]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/sgconfig/parser.cpp
Optimized sending answers in sgconfig.
[stg.git] / projects / stargazer / plugins / configuration / sgconfig / parser.cpp
1 #include <stdio.h>
2 #include <sys/utsname.h>
3 #include <sys/types.h>
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 #include <arpa/inet.h>
7
8 #include <cstring>
9 #include <cerrno>
10 #include <sstream>
11
12 #include "stg/version.h"
13 #include "stg/tariffs.h"
14 #include "stg/user_property.h"
15 #include "stg/settings.h"
16 #include "stg/logger.h"
17 #include "parser.h"
18
19 #define  UNAME_LEN      (256)
20
21 namespace
22 {
23
24 std::string UserToXML(const USER & user, bool loginInStart, bool showPass, time_t lastTime = 0)
25 {
26 std::string answer;
27
28 if (loginInStart)
29     answer += "<User result=\"ok\">";
30 else
31     answer += "<User result=\"ok\" login=\"" + user.GetLogin() + "\">";
32
33 answer += "<Login value=\"" + user.GetLogin() + "\"/>";
34
35 if (user.GetProperty().password.ModificationTime() > lastTime)
36     {
37     if (showPass)
38         answer += "<Password value=\"" + user.GetProperty().password.Get() + "\" />";
39     else
40         answer += "<Password value=\"++++++\"/>";
41     }
42
43 if (user.GetProperty().cash.ModificationTime() > lastTime)
44     answer += "<Cash value=\"" + x2str(user.GetProperty().cash.Get()) + "\"/>";
45 if (user.GetProperty().freeMb.ModificationTime() > lastTime)
46     answer += "<FreeMb value=\"" + x2str(user.GetProperty().freeMb.Get()) + "\"/>";
47 if (user.GetProperty().credit.ModificationTime() > lastTime)
48     answer += "<Credit value=\"" + x2str(user.GetProperty().credit.Get()) + "\"/>";
49
50 if (user.GetProperty().nextTariff.Get() != "")
51     {
52     if (user.GetProperty().tariffName.ModificationTime() > lastTime ||
53         user.GetProperty().nextTariff.ModificationTime() > lastTime)
54         answer += "<Tariff value=\"" + user.GetProperty().tariffName.Get() + "/" + user.GetProperty().nextTariff.Get() + "\"/>";
55     }
56 else
57     {
58     if (user.GetProperty().tariffName.ModificationTime() > lastTime)
59         answer += "<Tariff value=\"" + user.GetProperty().tariffName.Get() + "\"/>";
60     }
61
62 if (user.GetProperty().note.ModificationTime() > lastTime)
63     answer += "<Note value=\"" + Encode12str(user.GetProperty().note) + "\"/>";
64 if (user.GetProperty().phone.ModificationTime() > lastTime)
65     answer += "<Phone value=\"" + Encode12str(user.GetProperty().phone) + "\"/>";
66 if (user.GetProperty().address.ModificationTime() > lastTime)
67     answer += "<Address value=\"" + Encode12str(user.GetProperty().address) + "\"/>";
68 if (user.GetProperty().email.ModificationTime() > lastTime)
69     answer += "<Email value=\"" + Encode12str(user.GetProperty().email) + "\"/>";
70
71 std::vector<const USER_PROPERTY_LOGGED<std::string> *> userdata;
72 userdata.push_back(user.GetProperty().userdata0.GetPointer());
73 userdata.push_back(user.GetProperty().userdata1.GetPointer());
74 userdata.push_back(user.GetProperty().userdata2.GetPointer());
75 userdata.push_back(user.GetProperty().userdata3.GetPointer());
76 userdata.push_back(user.GetProperty().userdata4.GetPointer());
77 userdata.push_back(user.GetProperty().userdata5.GetPointer());
78 userdata.push_back(user.GetProperty().userdata6.GetPointer());
79 userdata.push_back(user.GetProperty().userdata7.GetPointer());
80 userdata.push_back(user.GetProperty().userdata8.GetPointer());
81 userdata.push_back(user.GetProperty().userdata9.GetPointer());
82
83 for (size_t i = 0; i < userdata.size(); i++)
84     if (userdata[i]->ModificationTime() > lastTime)
85         answer += "<UserData" + x2str(i) + " value=\"" + Encode12str(userdata[i]->Get()) + "\" />";
86
87 if (user.GetProperty().realName.ModificationTime() > lastTime)
88     answer += "<Name value=\"" + Encode12str(user.GetProperty().realName) + "\"/>";
89 if (user.GetProperty().group.ModificationTime() > lastTime)
90     answer += "<Group value=\"" + Encode12str(user.GetProperty().group) + "\"/>";
91 if (user.GetConnectedModificationTime() > lastTime)
92     answer += std::string("<Status value=\"") + (user.GetConnected() ? "1" : "0") + "\"/>";
93 if (user.GetProperty().alwaysOnline.ModificationTime() > lastTime)
94     answer += std::string("<AOnline value=\"") + (user.GetProperty().alwaysOnline.Get() ? "1" : "0") + "\"/>";
95 if (user.GetCurrIPModificationTime() > lastTime)
96     answer += "<CurrIP value=\"" + inet_ntostring(user.GetCurrIP()) + "\"/>";
97 if (user.GetPingTime() > lastTime)
98     answer += "<PingTime value=\"" + x2str(user.GetPingTime()) + "\"/>";
99 if (user.GetProperty().ips.ModificationTime() > lastTime)
100     answer += "<IP value=\"" + user.GetProperty().ips.Get().GetIpStr() + "\"/>";
101
102 answer += "<Traff";
103 const DIR_TRAFF & upload(user.GetProperty().down.Get());
104 const DIR_TRAFF & download(user.GetProperty().up.Get());
105 if (user.GetProperty().up.ModificationTime() > lastTime)
106     for (size_t j = 0; j < DIR_NUM; j++)
107         answer += " MU" + x2str(j) + "=\"" + x2str(upload[j]) + "\"";
108 if (user.GetProperty().down.ModificationTime() > lastTime)
109     for (size_t j = 0; j < DIR_NUM; j++)
110         answer += " MD" + x2str(j) + "=\"" + x2str(download[j]) + "\"";
111 if (user.GetSessionUploadModificationTime() > lastTime)
112     for (size_t j = 0; j < DIR_NUM; j++)
113         answer += " SU" + x2str(j) + "=\"" + x2str(user.GetSessionUpload()[j]) + "\"";
114 if (user.GetSessionDownloadModificationTime() > lastTime)
115     for (size_t j = 0; j < DIR_NUM; j++)
116         answer += " SD" + x2str(j) + "=\"" + x2str(user.GetSessionDownload()[j]) + "\"";
117 answer += "/>";
118
119 if (user.GetProperty().disabled.ModificationTime() > lastTime)
120     answer += std::string("<Down value=\"") + (user.GetProperty().disabled.Get() ? "1" : "0") + "\"/>";
121 if (user.GetProperty().disabledDetailStat.ModificationTime() > lastTime)
122     answer += std::string("<DisableDetailStat value=\"") + (user.GetProperty().disabledDetailStat.Get() ? "1" : "0") + "\"/>";
123 if (user.GetProperty().passive.ModificationTime() > lastTime)
124     answer += std::string("<Passive value=\"") + (user.GetProperty().passive.Get() ? "1" : "0") + "\"/>";
125 if (user.GetProperty().lastCashAdd.ModificationTime() > lastTime)
126     answer += "<LastCash value=\"" + x2str(user.GetProperty().lastCashAdd.Get()) + "\"/>";
127 if (user.GetProperty().lastCashAddTime.ModificationTime() > lastTime)
128     answer += "<LastTimeCash value=\"" + x2str(user.GetProperty().lastCashAddTime.Get()) + "\"/>";
129 if (user.GetProperty().lastActivityTime.ModificationTime() > lastTime)
130     answer += "<LastActivityTime value=\"" + x2str(user.GetProperty().lastActivityTime.Get()) + "\"/>";
131 if (user.GetProperty().creditExpire.ModificationTime() > lastTime)
132     answer += "<CreditExpire value=\"" + x2str(user.GetProperty().creditExpire.Get()) + "\"/>";
133
134 if (lastTime == 0)
135     {
136     answer += "<AuthorizedBy>";
137     std::vector<std::string> list(user.GetAuthorizers());
138     for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
139         answer += "<Auth name=\"" + *it + "\"/>";
140     answer += "</AuthorizedBy>";
141     }
142
143 answer += "</User>";
144
145 return answer;
146 }
147
148 } // namespace anonymous
149
150 //-----------------------------------------------------------------------------
151 //  GET SERVER INFO
152 //-----------------------------------------------------------------------------
153 int PARSER_GET_SERVER_INFO::ParseStart(void *, const char *el, const char **)
154 {
155 answer.clear();
156 if (strcasecmp(el, "GetServerInfo") == 0)
157     {
158     return 0;
159     }
160 return -1;
161 }
162 //-----------------------------------------------------------------------------
163 int PARSER_GET_SERVER_INFO::ParseEnd(void *, const char *el)
164 {
165 if (strcasecmp(el, "GetServerInfo") == 0)
166     {
167     CreateAnswer();
168     return 0;
169     }
170 return -1;
171 }
172 //-----------------------------------------------------------------------------
173 void PARSER_GET_SERVER_INFO::CreateAnswer()
174 {
175 char un[UNAME_LEN];
176 struct utsname utsn;
177
178 uname(&utsn);
179 un[0] = 0;
180
181 strcat(un, utsn.sysname);
182 strcat(un, " ");
183 strcat(un, utsn.release);
184 strcat(un, " ");
185 strcat(un, utsn.machine);
186 strcat(un, " ");
187 strcat(un, utsn.nodename);
188
189 answer.clear();
190 answer += "<ServerInfo>";
191 answer += std::string("<version value=\"") + SERVER_VERSION + "\"/>";
192 answer += "<tariff_num value=\"" + x2str(tariffs->Count()) + "\"/>";
193 answer += "<tariff value=\"2\"/>";
194 answer += "<user_num value=\"" + x2str(users->Count()) + "\"/>";
195 answer += std::string("<uname value=\"") + un + "\"/>";
196 answer += "<dir_num value=\"" + x2str(DIR_NUM) + "\"/>";
197 answer += "<day_fee value=\"" + x2str(settings->GetDayFee()) + "\"/>";
198
199 for (size_t i = 0; i< DIR_NUM; i++)
200     answer += "<dir_name_" + x2str(i) + " value=\"" + Encode12str(settings->GetDirName(i)) + "\"/>";
201
202 answer += "</ServerInfo>";
203 }
204 //-----------------------------------------------------------------------------
205 //  GET USER
206 //-----------------------------------------------------------------------------
207 int PARSER_GET_USER::ParseStart(void *, const char *el, const char **attr)
208 {
209 if (strcasecmp(el, "GetUser") == 0)
210     {
211     if (attr[0] && attr[1])
212         login = attr[1];
213     else
214         {
215         //login.clear();
216         login.erase(login.begin(), login.end());
217         return -1;
218         }
219     return 0;
220     }
221 return -1;
222 }
223 //-----------------------------------------------------------------------------
224 int PARSER_GET_USER::ParseEnd(void *, const char *el)
225 {
226 if (strcasecmp(el, "GetUser") == 0)
227     {
228     CreateAnswer();
229     return 0;
230     }
231 return -1;
232 }
233 //-----------------------------------------------------------------------------
234 void PARSER_GET_USER::CreateAnswer()
235 {
236 USER_PTR u;
237
238 answer.clear();
239
240 if (users->FindByName(login, &u))
241     {
242     answer = "<User result=\"error\" reason=\"User not found.\"/>";
243     return;
244     }
245
246 answer = UserToXML(*u, false, currAdmin->GetPriv()->userConf || currAdmin->GetPriv()->userPasswd);
247 }
248 //-----------------------------------------------------------------------------
249 //  GET USERS
250 //-----------------------------------------------------------------------------
251 int PARSER_GET_USERS::ParseStart(void *, const char *el, const char ** attr)
252 {
253 /*if (attr && *attr && *(attr+1))
254     {
255     printfd(__FILE__, "attr=%s %s\n", *attr, *(attr+1));
256     }
257 else
258     {
259     printfd(__FILE__, "attr = NULL\n");
260     }*/
261
262 lastUpdateFound = false;
263 if (strcasecmp(el, "GetUsers") == 0)
264     {
265     while (attr && *attr && *(attr+1))
266         {
267         if (strcasecmp(*attr, "LastUpdate") == 0)
268             {
269             if (str2x(*(attr+1), lastUserUpdateTime) == 0)
270                 {
271                 //printfd(__FILE__, "lastUserUpdateTime=%d\n", lastUserUpdateTime);
272                 lastUpdateFound = true;
273                 }
274             else
275                 {
276                 //printfd(__FILE__, "NO lastUserUpdateTime\n");
277                 }
278             }
279         ++attr;
280         }
281
282     return 0;
283     }
284 return -1;
285 }
286 //-----------------------------------------------------------------------------
287 int PARSER_GET_USERS::ParseEnd(void *, const char *el)
288 {
289 if (strcasecmp(el, "GetUsers") == 0)
290     {
291     CreateAnswer();
292     return 0;
293     }
294 return -1;
295 }
296 //-----------------------------------------------------------------------------
297 void PARSER_GET_USERS::CreateAnswer()
298 {
299 answer.clear();
300
301 int h = users->OpenSearch();
302 if (!h)
303     {
304     printfd(__FILE__, "users->OpenSearch() error\n");
305     users->CloseSearch(h);
306     return;
307     }
308
309 if (lastUpdateFound)
310     answer += "<Users LastUpdate=\"" + x2str(time(NULL)) + "\">";
311 else
312     answer += "<Users>";
313
314 USER_PTR u;
315
316 while (users->SearchNext(h, &u) == 0)
317     answer += UserToXML(*u, true, currAdmin->GetPriv()->userConf || currAdmin->GetPriv()->userPasswd, lastUserUpdateTime);
318
319 users->CloseSearch(h);
320
321 answer += "</Users>";
322 }
323 //-----------------------------------------------------------------------------
324 //  ADD USER
325 //-----------------------------------------------------------------------------
326 int PARSER_ADD_USER::ParseStart(void *, const char *el, const char **attr)
327 {
328 depth++;
329
330 if (depth == 1)
331     {
332     if (strcasecmp(el, "AddUser") == 0)
333         {
334         return 0;
335         }
336     }
337 else
338     {
339     if (strcasecmp(el, "login") == 0)
340         {
341         login = attr[1];
342         return 0;
343         }
344     }
345 return -1;
346 }
347 //-----------------------------------------------------------------------------
348 int PARSER_ADD_USER::ParseEnd(void *, const char *el)
349 {
350 if (depth == 1)
351     {
352     if (strcasecmp(el, "AddUser") == 0)
353         {
354         CreateAnswer();
355         depth--;
356         return 0;
357         }
358     }
359
360 depth--;
361 return -1;
362 }
363 //-----------------------------------------------------------------------------
364 void PARSER_ADD_USER::Reset()
365 {
366 BASE_PARSER::Reset();
367 depth = 0;
368 }
369 //-----------------------------------------------------------------------------
370 void PARSER_ADD_USER::CreateAnswer()
371 {
372 if (CheckUserData() == 0)
373     answer = "<AddUser result=\"ok\"/>";
374 else
375     answer = "<AddUser result=\"error\" reason=\"Access denied\"/>";
376 }
377 //-----------------------------------------------------------------------------
378 int PARSER_ADD_USER::CheckUserData()
379 {
380 USER_PTR u;
381 if (users->FindByName(login, &u))
382     {
383     return users->Add(login, currAdmin);
384     }
385 return -1;
386 }
387 //-----------------------------------------------------------------------------
388 //  PARSER CHG USER
389 //-----------------------------------------------------------------------------
390 PARSER_CHG_USER::PARSER_CHG_USER()
391     : BASE_PARSER(),
392       usr(NULL),
393       ucr(NULL),
394       upr(NULL),
395       downr(NULL),
396       cashMsg(),
397       login(),
398       cashMustBeAdded(false),
399       res(0)
400 {
401 Reset();
402 }
403 //-----------------------------------------------------------------------------
404 PARSER_CHG_USER::~PARSER_CHG_USER()
405 {
406 delete usr;
407 delete ucr;
408 delete[] upr;
409 delete[] downr;
410 }
411 //-----------------------------------------------------------------------------
412 void PARSER_CHG_USER::Reset()
413 {
414 depth = 0;
415 delete usr;
416
417 delete ucr;
418
419 delete[] upr;
420
421 delete[] downr;
422
423 usr = new USER_STAT_RES;
424 ucr = new USER_CONF_RES;
425
426 upr = new RESETABLE<uint64_t>[DIR_NUM];
427 downr = new RESETABLE<uint64_t>[DIR_NUM];
428 }
429 //-----------------------------------------------------------------------------
430 std::string PARSER_CHG_USER::EncChar2String(const char * strEnc)
431 {
432 std::string str;
433 Decode21str(str, strEnc);
434 return str;
435 }
436 //-----------------------------------------------------------------------------
437 int PARSER_CHG_USER::ParseStart(void *, const char *el, const char **attr)
438 {
439 depth++;
440
441 if (depth == 1)
442     {
443     if (strcasecmp(el, "SetUser") == 0)
444         {
445         return 0;
446         }
447     }
448 else
449     {
450     //printfd(__FILE__, "el=%s\n", el);
451     if (strcasecmp(el, "login") == 0)
452         {
453         login = attr[1];
454         return 0;
455         }
456
457     if (strcasecmp(el, "ip") == 0)
458         {
459         try
460             {
461             ucr->ips = StrToIPS(attr[1]);
462             }
463         catch (...)
464             {
465             printfd(__FILE__, "StrToIPS Error!\n");
466             }
467         }
468
469     if (strcasecmp(el, "password") == 0)
470         {
471         ucr->password = attr[1];
472         return 0;
473         }
474
475     if (strcasecmp(el, "address") == 0)
476         {
477         ucr->address = EncChar2String(attr[1]);
478         return 0;
479         }
480
481     if (strcasecmp(el, "aonline") == 0)
482         {
483         ucr->alwaysOnline = (*(attr[1]) != '0');
484         return 0;
485         }
486
487     if (strcasecmp(el, "cash") == 0)
488         {
489         if (attr[2] && (strcasecmp(attr[2], "msg") == 0))
490             {
491             cashMsg = EncChar2String(attr[3]);
492             }
493
494         double cash;
495         if (strtodouble2(attr[1], cash) == 0)
496             usr->cash = cash;
497
498         if (strcasecmp(attr[0], "set") == 0)
499             cashMustBeAdded = false;
500
501         if (strcasecmp(attr[0], "add") == 0)
502             cashMustBeAdded = true;
503
504         return 0;
505         }
506
507     if (strcasecmp(el, "CreditExpire") == 0)
508         {
509         long int creditExpire = 0;
510         if (str2x(attr[1], creditExpire) == 0)
511             ucr->creditExpire = (time_t)creditExpire;
512
513         return 0;
514         }
515
516     if (strcasecmp(el, "credit") == 0)
517         {
518         double credit;
519         if (strtodouble2(attr[1], credit) == 0)
520             ucr->credit = credit;
521         return 0;
522         }
523
524     if (strcasecmp(el, "freemb") == 0)
525         {
526         double freeMb;
527         if (strtodouble2(attr[1], freeMb) == 0)
528             usr->freeMb = freeMb;
529         return 0;
530         }
531
532     if (strcasecmp(el, "down") == 0)
533         {
534         int down = 0;
535         if (str2x(attr[1], down) == 0)
536             ucr->disabled = down;
537         return 0;
538         }
539
540     if (strcasecmp(el, "DisableDetailStat") == 0)
541         {
542         int disabledDetailStat = 0;
543         if (str2x(attr[1], disabledDetailStat) == 0)
544             ucr->disabledDetailStat = disabledDetailStat;
545         return 0;
546         }
547
548     if (strcasecmp(el, "email") == 0)
549         {
550         ucr->email = EncChar2String(attr[1]);
551         return 0;
552         }
553
554     for (int i = 0; i < USERDATA_NUM; i++)
555         {
556         char name[15];
557         sprintf(name, "userdata%d", i);
558         if (strcasecmp(el, name) == 0)
559             {
560             ucr->userdata[i] = EncChar2String(attr[1]);
561             return 0;
562             }
563         }
564
565     if (strcasecmp(el, "group") == 0)
566         {
567         ucr->group = EncChar2String(attr[1]);
568         return 0;
569         }
570
571     if (strcasecmp(el, "note") == 0)
572         {
573         ucr->note = EncChar2String(attr[1]);
574         return 0;
575         }
576
577     if (strcasecmp(el, "passive") == 0)
578         {
579         int passive = 0;
580         if (str2x(attr[1], passive) == 0)
581             ucr->passive = passive;
582         return 0;
583         }
584
585     if (strcasecmp(el, "phone") == 0)
586         {
587         ucr->phone = EncChar2String(attr[1]);
588         return 0;
589         }
590
591     if (strcasecmp(el, "Name") == 0)
592         {
593         ucr->realName = EncChar2String(attr[1]);
594         return 0;
595         }
596
597     if (strcasecmp(el, "traff") == 0)
598         {
599         int j = 0;
600         DIR_TRAFF dtu;
601         DIR_TRAFF dtd;
602         uint64_t t = 0;
603         while (attr[j])
604             {
605             int dir = attr[j][2] - '0';
606
607             if (strncasecmp(attr[j], "md", 2) == 0)
608                 {
609                 str2x(attr[j+1], t);
610                 dtd[dir] = t;
611                 downr[dir] = t;
612                 }
613             if (strncasecmp(attr[j], "mu", 2) == 0)
614                 {
615                 str2x(attr[j+1], t);
616                 dtu[dir] = t;
617                 upr[dir] = t;
618                 }
619             j+=2;
620             }
621         return 0;
622         }
623
624     if (strcasecmp(el, "tariff") == 0)
625         {
626         if (strcasecmp(attr[0], "now") == 0)
627             ucr->tariffName = attr[1];
628
629         if (strcasecmp(attr[0], "delayed") == 0)
630             ucr->nextTariff = attr[1];
631
632         return 0;
633         }
634     }
635 return -1;
636 }
637 //-----------------------------------------------------------------------------
638 int PARSER_CHG_USER::ParseEnd(void *, const char *el)
639 {
640 if (depth == 1)
641     {
642     if (strcasecmp(el, "SetUser") == 0)
643         {
644         AplayChanges();
645         CreateAnswer();
646         depth--;
647         return 0;
648         }
649     }
650
651 depth--;
652 return -1;
653 }
654 //-----------------------------------------------------------------------------
655 void PARSER_CHG_USER::CreateAnswer()
656 {
657 switch (res)
658     {
659     case 0:
660         answer = "<SetUser result=\"ok\"/>";
661         break;
662     case -1:
663         answer = "<SetUser result=\"error\"/>";
664         break;
665     case -2:
666         answer = "<SetUser result=\"error\"/>";
667         break;
668     default:
669         answer = "<SetUser result=\"error\"/>";
670         break;
671     }
672
673 }
674 //-----------------------------------------------------------------------------
675 int PARSER_CHG_USER::AplayChanges()
676 {
677 printfd(__FILE__, "PARSER_CHG_USER::AplayChanges()\n");
678 USER_PTR u;
679
680 res = 0;
681 if (users->FindByName(login, &u))
682     {
683     res = -1;
684     return -1;
685     }
686
687 bool check = false;
688 bool alwaysOnline = u->GetProperty().alwaysOnline;
689 if (!ucr->alwaysOnline.empty())
690     {
691     check = true;
692     alwaysOnline = ucr->alwaysOnline.const_data();
693     }
694 bool onlyOneIP = u->GetProperty().ips.ConstData().OnlyOneIP();
695 if (!ucr->ips.empty())
696     {
697     check = true;
698     onlyOneIP = ucr->ips.const_data().OnlyOneIP();
699     }
700
701 if (check && alwaysOnline && !onlyOneIP)
702     {
703     printfd(__FILE__, "Requested change leads to a forbidden state: AlwaysOnline with multiple IP's\n");
704     GetStgLogger()("%s Requested change leads to a forbidden state: AlwaysOnline with multiple IP's", currAdmin->GetLogStr().c_str());
705     res = -1;
706     return -1;
707     }
708
709 for (size_t i = 0; i < ucr->ips.const_data().Count(); ++i)
710     {
711     CONST_USER_PTR user;
712     uint32_t ip = ucr->ips.const_data().operator[](i).ip;
713     if (users->IsIPInUse(ip, login, &user))
714         {
715         printfd(__FILE__, "Trying to assign an IP %s to '%s' that is already in use by '%s'\n", inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
716         GetStgLogger()("%s trying to assign an IP %s to '%s' that is currently in use by '%s'", currAdmin->GetLogStr().c_str(), inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
717         res = -1;
718         return -1;
719         }
720     }
721
722 if (!ucr->ips.empty())
723     if (!u->GetProperty().ips.Set(ucr->ips.const_data(), currAdmin, login, store))
724         res = -1;
725
726 if (!ucr->alwaysOnline.empty())
727     if (!u->GetProperty().alwaysOnline.Set(ucr->alwaysOnline.const_data(),
728                                       currAdmin, login, store))
729         res = -1;
730
731 if (!ucr->address.empty())
732     if (!u->GetProperty().address.Set(ucr->address.const_data(), currAdmin, login, store))
733         res = -1;
734
735 if (!ucr->creditExpire.empty())
736     if (!u->GetProperty().creditExpire.Set(ucr->creditExpire.const_data(),
737                                       currAdmin, login, store))
738         res = -1;
739
740 if (!ucr->credit.empty())
741     if (!u->GetProperty().credit.Set(ucr->credit.const_data(), currAdmin, login, store))
742         res = -1;
743
744 if (!usr->freeMb.empty())
745     if (!u->GetProperty().freeMb.Set(usr->freeMb.const_data(), currAdmin, login, store))
746         res = -1;
747
748 if (!ucr->disabled.empty())
749     if (!u->GetProperty().disabled.Set(ucr->disabled.const_data(), currAdmin, login, store))
750         res = -1;
751
752 if (!ucr->disabledDetailStat.empty())
753     if (!u->GetProperty().disabledDetailStat.Set(ucr->disabledDetailStat.const_data(), currAdmin, login, store))
754         res = -1;
755
756 if (!ucr->email.empty())
757     if (!u->GetProperty().email.Set(ucr->email.const_data(), currAdmin, login, store))
758         res = -1;
759
760 if (!ucr->group.empty())
761     if (!u->GetProperty().group.Set(ucr->group.const_data(), currAdmin, login, store))
762         res = -1;
763
764 if (!ucr->note.empty())
765     if (!u->GetProperty().note.Set(ucr->note.const_data(), currAdmin, login, store))
766         res = -1;
767
768 std::vector<USER_PROPERTY_LOGGED<std::string> *> userdata;
769 userdata.push_back(u->GetProperty().userdata0.GetPointer());
770 userdata.push_back(u->GetProperty().userdata1.GetPointer());
771 userdata.push_back(u->GetProperty().userdata2.GetPointer());
772 userdata.push_back(u->GetProperty().userdata3.GetPointer());
773 userdata.push_back(u->GetProperty().userdata4.GetPointer());
774 userdata.push_back(u->GetProperty().userdata5.GetPointer());
775 userdata.push_back(u->GetProperty().userdata6.GetPointer());
776 userdata.push_back(u->GetProperty().userdata7.GetPointer());
777 userdata.push_back(u->GetProperty().userdata8.GetPointer());
778 userdata.push_back(u->GetProperty().userdata9.GetPointer());
779
780 for (int i = 0; i < (int)userdata.size(); i++)
781     {
782     if (!ucr->userdata[i].empty())
783         {
784         if(!userdata[i]->Set(ucr->userdata[i].const_data(), currAdmin, login, store))
785             res = -1;
786         }
787     }
788
789 if (!ucr->passive.empty())
790     if (!u->GetProperty().passive.Set(ucr->passive.const_data(), currAdmin, login, store))
791         res = -1;
792
793 if (!ucr->password.empty())
794     if (!u->GetProperty().password.Set(ucr->password.const_data(), currAdmin, login, store))
795         res = -1;
796
797 if (!ucr->phone.empty())
798     if (!u->GetProperty().phone.Set(ucr->phone.const_data(), currAdmin, login, store))
799         res = -1;
800
801 if (!ucr->realName.empty())
802     if (!u->GetProperty().realName.Set(ucr->realName.const_data(), currAdmin, login, store))
803         res = -1;
804
805
806 if (!usr->cash.empty())
807     {
808     //if (*currAdmin->GetPriv()->userCash)
809         {
810         if (cashMustBeAdded)
811             {
812             if (!u->GetProperty().cash.Set(usr->cash.const_data() + u->GetProperty().cash,
813                                            currAdmin,
814                                            login,
815                                            store,
816                                            cashMsg))
817                 res = -1;
818             }
819         else
820             {
821             if (!u->GetProperty().cash.Set(usr->cash.const_data(), currAdmin, login, store, cashMsg))
822                 res = -1;
823             }
824         }
825     }
826
827
828 if (!ucr->tariffName.empty())
829     {
830     if (tariffs->FindByName(ucr->tariffName.const_data()))
831         {
832         if (!u->GetProperty().tariffName.Set(ucr->tariffName.const_data(), currAdmin, login, store))
833             res = -1;
834         u->ResetNextTariff();
835         }
836     else
837         {
838         //WriteServLog("SetUser: Tariff %s not found", ud.conf.tariffName.c_str());
839         res = -1;
840         }
841     }
842
843 if (!ucr->nextTariff.empty())
844     {
845     if (tariffs->FindByName(ucr->nextTariff.const_data()))
846         {
847         if (!u->GetProperty().nextTariff.Set(ucr->nextTariff.const_data(), currAdmin, login, store))
848             res = -1;
849         }
850     else
851         {
852         //WriteServLog("SetUser: Tariff %s not found", ud.conf.tariffName.c_str());
853         res = -1;
854         }
855     }
856
857 DIR_TRAFF up = u->GetProperty().up;
858 DIR_TRAFF down = u->GetProperty().down;
859 int upCount = 0;
860 int downCount = 0;
861 for (int i = 0; i < DIR_NUM; i++)
862     {
863     if (!upr[i].empty())
864         {
865         up[i] = upr[i].data();
866         upCount++;
867         }
868     if (!downr[i].empty())
869         {
870         down[i] = downr[i].data();
871         downCount++;
872         }
873     }
874
875 if (upCount)
876     if (!u->GetProperty().up.Set(up, currAdmin, login, store))
877         res = -1;
878
879 if (downCount)
880     if (!u->GetProperty().down.Set(down, currAdmin, login, store))
881         res = -1;
882
883 u->WriteConf();
884 u->WriteStat();
885
886 return 0;
887 }
888 //-----------------------------------------------------------------------------
889 //      SEND MESSAGE
890 //-----------------------------------------------------------------------------
891 int PARSER_SEND_MESSAGE::ParseStart(void *, const char *el, const char **attr)
892 {
893 if (strcasecmp(el, "Message") == 0)
894     {
895     for (int i = 0; i < 14; i++)
896         {
897         if (attr[i] == NULL)
898             {
899             result = res_params_error;
900             CreateAnswer();
901             printfd(__FILE__, "To few parameters\n");
902             return 0;
903             }
904         }
905
906     for (int i = 0; i < 14; i+=2)
907         {
908         if (strcasecmp(attr[i], "login") == 0)
909             {
910             ParseLogins(attr[i+1]);
911             /*if (users->FindByName(login, &u))
912                 {
913                 result = res_unknown;
914                 break;
915                 }*/
916             }
917
918         if (strcasecmp(attr[i], "MsgVer") == 0)
919             {
920             str2x(attr[i+1], msg.header.ver);
921             if (msg.header.ver != 1)
922                 result = res_params_error;
923             }
924
925         if (strcasecmp(attr[i], "MsgType") == 0)
926             {
927             str2x(attr[i+1], msg.header.type);
928             if (msg.header.type != 1)
929                 result = res_params_error;
930             }
931
932         if (strcasecmp(attr[i], "Repeat") == 0)
933             {
934             str2x(attr[i+1], msg.header.repeat);
935             if (msg.header.repeat < 0)
936                 result = res_params_error;
937             }
938
939         if (strcasecmp(attr[i], "RepeatPeriod") == 0)
940             {
941             str2x(attr[i+1], msg.header.repeatPeriod);
942             }
943
944         if (strcasecmp(attr[i], "ShowTime") == 0)
945             {
946             str2x(attr[i+1], msg.header.showTime);
947             }
948
949         if (strcasecmp(attr[i], "Text") == 0)
950             {
951             Decode21str(msg.text, attr[i+1]);
952             result = res_ok;
953             }
954         }
955     return 0;
956     }
957 return -1;
958 }
959 //-----------------------------------------------------------------------------
960 int PARSER_SEND_MESSAGE::ParseEnd(void *, const char *el)
961 {
962 //MSG msg;
963 if (strcasecmp(el, "Message") == 0)
964     {
965     result = res_unknown;
966     for (unsigned i = 0; i < logins.size(); i++)
967         {
968         if (users->FindByName(logins[i], &u))
969             {
970             printfd(__FILE__, "User not found. %s\n", logins[i].c_str());
971             continue;
972             }
973         msg.header.creationTime = static_cast<unsigned int>(stgTime);
974         u->AddMessage(&msg);
975         result = res_ok;
976         }
977     /*if (result == res_ok)
978         {
979         if (strcmp(login, "*") == 0)
980             {
981             msg.text = text;
982             msg.prio = pri;
983             printfd(__FILE__, "SendMsg text: %s\n", text);
984             users->GetAllUsers(SendMessageAllUsers, &msg);
985             }
986         else
987             {
988             u->AddMessage(pri, text);
989             }
990         }*/
991     CreateAnswer();
992     return 0;
993     }
994 return -1;
995 }
996 //-----------------------------------------------------------------------------
997 int PARSER_SEND_MESSAGE::ParseLogins(const char * login)
998 {
999 char * p;
1000 char * l = new char[strlen(login) + 1];
1001 strcpy(l, login);
1002 p = strtok(l, ":");
1003 logins.clear();
1004 while(p)
1005     {
1006     logins.push_back(p);
1007     p = strtok(NULL, ":");
1008     }
1009
1010 delete[] l;
1011 return 0;
1012 }
1013 //-----------------------------------------------------------------------------
1014 void PARSER_SEND_MESSAGE::CreateAnswer()
1015 {
1016 switch (result)
1017     {
1018     case res_ok:
1019         answer = "<SendMessageResult value=\"ok\"/>";
1020         break;
1021     case res_params_error:
1022         printfd(__FILE__, "res_params_error\n");
1023         answer = "<SendMessageResult value=\"Parameters error.\"/>";
1024         break;
1025     case res_unknown:
1026         printfd(__FILE__, "res_unknown\n");
1027         answer = "<SendMessageResult value=\"Unknown user.\"/>";
1028         break;
1029     default:
1030         printfd(__FILE__, "res_default\n");
1031     }
1032
1033 }
1034 //-----------------------------------------------------------------------------
1035 //      DEL USER
1036 //-----------------------------------------------------------------------------
1037 int PARSER_DEL_USER::ParseStart(void *, const char *el, const char **attr)
1038 {
1039 res = 0;
1040 if (strcasecmp(el, "DelUser") == 0)
1041     {
1042     if (attr[0] == NULL || attr[1] == NULL)
1043         {
1044         //CreateAnswer("Parameters error!");
1045         CreateAnswer();
1046         return 0;
1047         }
1048
1049     if (users->FindByName(attr[1], &u))
1050         {
1051         res = 1;
1052         CreateAnswer();
1053         return 0;
1054         }
1055     CreateAnswer();
1056     return 0;
1057     }
1058 return -1;
1059 }
1060 //-----------------------------------------------------------------------------
1061 int PARSER_DEL_USER::ParseEnd(void *, const char *el)
1062 {
1063 if (strcasecmp(el, "DelUser") == 0)
1064     {
1065     if (!res)
1066         users->Del(u->GetLogin(), currAdmin);
1067
1068     return 0;
1069     }
1070 return -1;
1071 }
1072 //-----------------------------------------------------------------------------
1073 void PARSER_DEL_USER::CreateAnswer()
1074 {
1075 if (res)
1076     answer = "<DelUser value=\"error\" reason=\"User not found\"/>";
1077 else
1078     answer = "<DelUser value=\"ok\"/>";
1079 }
1080 //-----------------------------------------------------------------------------
1081 //  CHECK USER
1082 // <checkuser login="vasya" password=\"123456\"/>
1083 //-----------------------------------------------------------------------------
1084 int PARSER_CHECK_USER::ParseStart(void *, const char *el, const char **attr)
1085 {
1086 if (strcasecmp(el, "CheckUser") == 0)
1087     {
1088     if (attr[0] == NULL || attr[1] == NULL
1089      || attr[2] == NULL || attr[3] == NULL)
1090         {
1091         CreateAnswer("Invalid parameters.");
1092         printfd(__FILE__, "PARSER_CHECK_USER - attr err\n");
1093         return 0;
1094         }
1095
1096     USER_PTR user;
1097     if (users->FindByName(attr[1], &user))
1098         {
1099         CreateAnswer("User not found.");
1100         printfd(__FILE__, "PARSER_CHECK_USER - login err\n");
1101         return 0;
1102         }
1103
1104     if (strcmp(user->GetProperty().password.Get().c_str(), attr[3]))
1105         {
1106         CreateAnswer("Wrong password.");
1107         printfd(__FILE__, "PARSER_CHECK_USER - passwd err\n");
1108         return 0;
1109         }
1110
1111     CreateAnswer(NULL);
1112     return 0;
1113     }
1114 return -1;
1115 }
1116 //-----------------------------------------------------------------------------
1117 int PARSER_CHECK_USER::ParseEnd(void *, const char *el)
1118 {
1119 if (strcasecmp(el, "CheckUser") == 0)
1120     {
1121     return 0;
1122     }
1123 return -1;
1124 }
1125 //-----------------------------------------------------------------------------
1126 void PARSER_CHECK_USER::CreateAnswer(const char * error)
1127 {
1128 if (error)
1129     answer = std::string("<CheckUser value=\"Err\" reason=\"") + error + "\"/>";
1130 else
1131     answer = "<CheckUser value=\"Ok\"/>";
1132 }
1133 //-----------------------------------------------------------------------------
1134 //-----------------------------------------------------------------------------
1135 //-----------------------------------------------------------------------------