]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/sgconfig/parser.cpp
Improved handling errors got from server.
[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 //  GET SERVER INFO
22 //-----------------------------------------------------------------------------
23 int PARSER_GET_SERVER_INFO::ParseStart(void *, const char *el, const char **)
24 {
25 answerList->erase(answerList->begin(), answerList->end());
26 if (strcasecmp(el, "GetServerInfo") == 0)
27     {
28     return 0;
29     }
30 return -1;
31 }
32 //-----------------------------------------------------------------------------
33 int PARSER_GET_SERVER_INFO::ParseEnd(void *, const char *el)
34 {
35 if (strcasecmp(el, "GetServerInfo") == 0)
36     {
37     CreateAnswer();
38     return 0;
39     }
40 return -1;
41 }
42 //-----------------------------------------------------------------------------
43 void PARSER_GET_SERVER_INFO::CreateAnswer()
44 {
45 char s[UNAME_LEN + 128];
46 char un[UNAME_LEN];
47 struct utsname utsn;
48
49 uname(&utsn);
50 un[0] = 0;
51
52 strcat(un, utsn.sysname);
53 strcat(un, " ");
54 strcat(un, utsn.release);
55 strcat(un, " ");
56 strcat(un, utsn.machine);
57 strcat(un, " ");
58 strcat(un, utsn.nodename);
59
60 //answerList->clear();
61 answerList->erase(answerList->begin(), answerList->end());
62 answerList->push_back("<ServerInfo>");
63
64 sprintf(s, "<version value=\"%s\"/>", SERVER_VERSION);
65 answerList->push_back(s);
66
67 sprintf(s, "<tariff_num value=\"%llu\"/>", static_cast<unsigned long long>(tariffs->Count()));
68 answerList->push_back(s);
69
70 sprintf(s, "<tariff value=\"%d\"/>", 2);
71 answerList->push_back(s);
72
73 sprintf(s, "<users_num value=\"%llu\"/>", static_cast<unsigned long long>(users->Count()));
74 answerList->push_back(s);
75
76 sprintf(s, "<uname value=\"%s\"/>", un);
77 answerList->push_back(s);
78
79 sprintf(s, "<dir_num value=\"%d\"/>", DIR_NUM);
80 answerList->push_back(s);
81
82 sprintf(s, "<day_fee value=\"%d\"/>", settings->GetDayFee());
83 answerList->push_back(s);
84
85 for (int i = 0; i< DIR_NUM; i++)
86     {
87     std::string dn2e;
88     Encode12str(dn2e, settings->GetDirName(i));
89     sprintf(s, "<dir_name_%d value=\"%s\"/>", i, dn2e.c_str());
90     answerList->push_back(s);
91     }
92
93 answerList->push_back("</ServerInfo>");
94 }
95 //-----------------------------------------------------------------------------
96 //  GET USER
97 //-----------------------------------------------------------------------------
98 int PARSER_GET_USER::ParseStart(void *, const char *el, const char **attr)
99 {
100 if (strcasecmp(el, "GetUser") == 0)
101     {
102     if (attr[0] && attr[1])
103         login = attr[1];
104     else
105         {
106         //login.clear();
107         login.erase(login.begin(), login.end());
108         return -1;
109         }
110     return 0;
111     }
112 return -1;
113 }
114 //-----------------------------------------------------------------------------
115 int PARSER_GET_USER::ParseEnd(void *, const char *el)
116 {
117 if (strcasecmp(el, "GetUser") == 0)
118     {
119     CreateAnswer();
120     return 0;
121     }
122 return -1;
123 }
124 //-----------------------------------------------------------------------------
125 void PARSER_GET_USER::CreateAnswer()
126 {
127 std::string s;
128 std::string enc;
129
130 USER_PTR u;
131
132 answerList->erase(answerList->begin(), answerList->end());
133
134 if (users->FindByName(login, &u))
135     {
136     answerList->push_back("<user result=\"error\" reason=\"User not found.\"/>");
137     return;
138     }
139
140 s = "<user result=\"ok\">";
141 answerList->push_back(s);
142
143 s = "<login value=\"" + u->GetLogin() + "\"/>";
144 answerList->push_back(s);
145
146 if (currAdmin->GetPriv()->userConf || currAdmin->GetPriv()->userPasswd)
147     s = "<password value=\"" + u->GetProperty().password.Get() + "\" />";
148 else
149     s = "<password value=\"++++++\"/>";
150 answerList->push_back(s);
151
152 strprintf(&s, "<cash value=\"%f\" />", u->GetProperty().cash.Get());
153 answerList->push_back(s);
154
155 strprintf(&s, "<freemb value=\"%f\" />", u->GetProperty().freeMb.Get());
156 answerList->push_back(s);
157
158 strprintf(&s, "<credit value=\"%f\" />", u->GetProperty().credit.Get());
159 answerList->push_back(s);
160
161 if (u->GetProperty().nextTariff.Get() != "")
162     {
163     strprintf(&s, "<tariff value=\"%s/%s\" />",
164               u->GetProperty().tariffName.Get().c_str(),
165               u->GetProperty().nextTariff.Get().c_str());
166     }
167 else
168     {
169     strprintf(&s, "<tariff value=\"%s\" />",
170               u->GetProperty().tariffName.Get().c_str());
171     }
172
173 answerList->push_back(s);
174
175 Encode12str(enc, u->GetProperty().note);
176 s = "<note value=\"" + enc + "\" />";
177 answerList->push_back(s);
178
179 Encode12str(enc, u->GetProperty().phone);
180 s = "<phone value=\"" + enc + "\" />";
181 answerList->push_back(s);
182
183 Encode12str(enc, u->GetProperty().address);
184 s = "<address value=\"" + enc + "\" />";
185 answerList->push_back(s);
186
187 Encode12str(enc, u->GetProperty().email);
188 s = "<email value=\"" + enc + "\" />";
189 answerList->push_back(s);
190
191
192 std::vector<USER_PROPERTY_LOGGED<std::string> *> userdata;
193 userdata.push_back(u->GetProperty().userdata0.GetPointer());
194 userdata.push_back(u->GetProperty().userdata1.GetPointer());
195 userdata.push_back(u->GetProperty().userdata2.GetPointer());
196 userdata.push_back(u->GetProperty().userdata3.GetPointer());
197 userdata.push_back(u->GetProperty().userdata4.GetPointer());
198 userdata.push_back(u->GetProperty().userdata5.GetPointer());
199 userdata.push_back(u->GetProperty().userdata6.GetPointer());
200 userdata.push_back(u->GetProperty().userdata7.GetPointer());
201 userdata.push_back(u->GetProperty().userdata8.GetPointer());
202 userdata.push_back(u->GetProperty().userdata9.GetPointer());
203
204 std::string tmpI;
205 for (unsigned i = 0; i < userdata.size(); i++)
206     {
207     Encode12str(enc, userdata[i]->Get());
208     s = "<UserData" + x2str(i, tmpI) + " value=\"" + enc + "\" />";
209     answerList->push_back(s);
210     }
211
212 Encode12str(enc, u->GetProperty().realName);
213 s = "<name value=\"" + enc + "\" />";
214 answerList->push_back(s);
215
216 Encode12str(enc, u->GetProperty().group);
217 s = "<GROUP value=\"" + enc + "\" />";
218 answerList->push_back(s);
219
220 strprintf(&s, "<status value=\"%d\" />", u->GetConnected());
221 answerList->push_back(s);
222
223 strprintf(&s, "<aonline value=\"%d\" />", u->GetProperty().alwaysOnline.Get());
224 answerList->push_back(s);
225
226 strprintf(&s, "<currip value=\"%s\" />", inet_ntostring(u->GetCurrIP()).c_str());
227 answerList->push_back(s);
228
229 strprintf(&s, "<PingTime value=\"%lu\" />", u->GetPingTime());
230 answerList->push_back(s);
231
232 std::ostringstream sstr;
233 sstr << u->GetProperty().ips.Get();
234 strprintf(&s, "<ip value=\"%s\" />", sstr.str().c_str());
235 answerList->push_back(s);
236
237 char * ss;
238 ss = new char[DIR_NUM*25*4 + 50];
239 char st[50];
240 sprintf(ss, "<traff");
241 DIR_TRAFF upload;
242 DIR_TRAFF download;
243 download = u->GetProperty().down.Get();
244 upload = u->GetProperty().up.Get();
245
246 for (int j = 0; j < DIR_NUM; j++)
247     {
248     std::string s;
249     x2str(upload[j], s);
250     sprintf(st, " MU%d=\"%s\"", j, s.c_str());
251     strcat(ss, st);
252
253     x2str(download[j], s);
254     sprintf(st, " MD%d=\"%s\"", j, s.c_str());
255     strcat(ss, st);
256
257     sprintf(st, " SU%d=\"0\"", j);
258     strcat(ss, st);
259
260     sprintf(st, " SD%d=\"0\"", j);
261     strcat(ss, st);
262     }
263 strcat(ss, " />");
264 answerList->push_back(ss);
265 delete[] ss;
266
267 strprintf(&s, "<down value=\"%d\" />", u->GetProperty().disabled.Get());
268 answerList->push_back(s);
269
270 strprintf(&s, "<DisableDetailStat value=\"%d\" />", u->GetProperty().disabledDetailStat.Get());
271 answerList->push_back(s);
272
273 strprintf(&s, "<passive value=\"%d\" />", u->GetProperty().passive.Get());
274 answerList->push_back(s);
275
276 strprintf(&s, "<LastCash value=\"%f\" />", u->GetProperty().lastCashAdd.Get());
277 answerList->push_back(s);
278
279 strprintf(&s, "<LastTimeCash value=\"%ld\" />", u->GetProperty().lastCashAddTime.Get());
280 answerList->push_back(s);
281
282 strprintf(&s, "<LastActivityTime value=\"%ld\" />", u->GetProperty().lastActivityTime.Get());
283 answerList->push_back(s);
284
285 strprintf(&s, "<CreditExpire value=\"%ld\" />", u->GetProperty().creditExpire.Get());
286 answerList->push_back(s);
287
288 s = "<AuthorizedBy>";
289 std::vector<std::string> list(u->GetAuthorizers());
290 for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
291     s += "<Auth name=\"" + *it + "\"/>";
292 s += "</AuthorizedBy>";
293 answerList->push_back(s);
294
295 strprintf(&s, "</user>");
296 answerList->push_back(s);
297 }
298 //-----------------------------------------------------------------------------
299 //  GET USERS
300 //-----------------------------------------------------------------------------
301 int PARSER_GET_USERS::ParseStart(void *, const char *el, const char ** attr)
302 {
303 /*if (attr && *attr && *(attr+1))
304     {
305     printfd(__FILE__, "attr=%s %s\n", *attr, *(attr+1));
306     }
307 else
308     {
309     printfd(__FILE__, "attr = NULL\n");
310     }*/
311
312 lastUpdateFound = false;
313 if (strcasecmp(el, "GetUsers") == 0)
314     {
315     while (attr && *attr && *(attr+1))
316         {
317         if (strcasecmp(*attr, "LastUpdate") == 0)
318             {
319             if (str2x(*(attr+1), lastUserUpdateTime) == 0)
320                 {
321                 //printfd(__FILE__, "lastUserUpdateTime=%d\n", lastUserUpdateTime);
322                 lastUpdateFound = true;
323                 }
324             else
325                 {
326                 //printfd(__FILE__, "NO lastUserUpdateTime\n");
327                 }
328             }
329         ++attr;
330         }
331
332     return 0;
333     }
334 return -1;
335 }
336 //-----------------------------------------------------------------------------
337 int PARSER_GET_USERS::ParseEnd(void *, const char *el)
338 {
339 if (strcasecmp(el, "GetUsers") == 0)
340     {
341     CreateAnswer();
342     return 0;
343     }
344 return -1;
345 }
346 //-----------------------------------------------------------------------------
347 void PARSER_GET_USERS::CreateAnswer()
348 {
349 answerList->erase(answerList->begin(), answerList->end());
350
351 std::string s;
352 std::string userStart;
353 std::string traffStart;
354 std::string traffMiddle;
355 std::string traffFinish;
356 std::string middle;
357 std::string userFinish;
358
359
360 std::string enc;
361
362 USER_PTR u;
363
364 int h = users->OpenSearch();
365 if (!h)
366     {
367     printfd(__FILE__, "users->OpenSearch() error\n");
368     users->CloseSearch(h);
369     return;
370     }
371 std::string updateTime;
372 x2str(time(NULL), updateTime);
373
374 if (lastUpdateFound)
375     answerList->push_back("<Users LastUpdate=\"" + updateTime + "\">");
376 else
377     answerList->push_back("<Users>");
378
379 while (1)
380     {
381     if (users->SearchNext(h, &u))
382         {
383         break;
384         }
385     userStart = "<user login=\"" + u->GetLogin() + "\">";
386     middle = "";
387
388     if (u->GetProperty().password.ModificationTime() > lastUserUpdateTime)
389         {
390         if (currAdmin->GetPriv()->userConf || currAdmin->GetPriv()->userPasswd)
391             s = "<password value=\"" + u->GetProperty().password.Get() + "\" />";
392         else
393             s = "<password value=\"++++++\"/>";
394         middle += s;
395         }
396
397
398     if (u->GetProperty().cash.ModificationTime() > lastUserUpdateTime)
399         {
400         strprintf(&s, "<cash value=\"%f\" />", u->GetProperty().cash.Get());
401         middle += s;
402         //printfd(__FILE__, "cash value=\"%f\"\n", u->GetProperty().cash.Get());
403         }
404
405
406     if (u->GetProperty().freeMb.ModificationTime() > lastUserUpdateTime)
407         {
408         strprintf(&s, "<freemb value=\"%f\" />", u->GetProperty().freeMb.Get());
409         middle += s;
410         }
411
412     if (u->GetProperty().credit.ModificationTime() > lastUserUpdateTime)
413         {
414         strprintf(&s, "<credit value=\"%f\" />", u->GetProperty().credit.Get());
415         middle += s;
416         }
417
418     if (u->GetProperty().nextTariff.Get() != "")
419         {
420         if (u->GetProperty().tariffName.ModificationTime() > lastUserUpdateTime
421             || u->GetProperty().nextTariff.ModificationTime() > lastUserUpdateTime)
422             {
423             strprintf(&s, "<tariff value=\"%s/%s\" />",
424                       u->GetProperty().tariffName.Get().c_str(),
425                       u->GetProperty().nextTariff.Get().c_str());
426             middle += s;
427             }
428         }
429     else
430         {
431         if (u->GetProperty().tariffName.ModificationTime() > lastUserUpdateTime)
432             {
433             strprintf(&s, "<tariff value=\"%s\" />",
434                       u->GetProperty().tariffName.Get().c_str());
435             middle += s;
436             }
437         }
438
439     if (u->GetProperty().note.ModificationTime() > lastUserUpdateTime)
440         {
441         Encode12str(enc, u->GetProperty().note);
442         strprintf(&s, "<note value=\"%s\" />", enc.c_str());
443         middle += s;
444         }
445
446     if (u->GetProperty().phone.ModificationTime() > lastUserUpdateTime)
447         {
448         Encode12str(enc, u->GetProperty().phone);
449         strprintf(&s, "<phone value=\"%s\" />", enc.c_str());
450         middle += s;
451         }
452
453     if (u->GetProperty().address.ModificationTime() > lastUserUpdateTime)
454         {
455         Encode12str(enc, u->GetProperty().address);
456         strprintf(&s, "<address value=\"%s\" />", enc.c_str());
457         middle += s;
458         }
459
460     if (u->GetProperty().email.ModificationTime() > lastUserUpdateTime)
461         {
462         Encode12str(enc, u->GetProperty().email);
463         strprintf(&s, "<email value=\"%s\" />", enc.c_str());
464         middle += s;
465         }
466
467     std::vector<USER_PROPERTY_LOGGED<std::string> *> userdata;
468     userdata.push_back(u->GetProperty().userdata0.GetPointer());
469     userdata.push_back(u->GetProperty().userdata1.GetPointer());
470     userdata.push_back(u->GetProperty().userdata2.GetPointer());
471     userdata.push_back(u->GetProperty().userdata3.GetPointer());
472     userdata.push_back(u->GetProperty().userdata4.GetPointer());
473     userdata.push_back(u->GetProperty().userdata5.GetPointer());
474     userdata.push_back(u->GetProperty().userdata6.GetPointer());
475     userdata.push_back(u->GetProperty().userdata7.GetPointer());
476     userdata.push_back(u->GetProperty().userdata8.GetPointer());
477     userdata.push_back(u->GetProperty().userdata9.GetPointer());
478
479     std::string tmpI;
480     for (unsigned i = 0; i < userdata.size(); i++)
481         {
482         if (userdata[i]->ModificationTime() > lastUserUpdateTime)
483             {
484             Encode12str(enc, userdata[i]->Get());
485             s = "<UserData" + x2str(i, tmpI) + " value=\"" + enc + "\" />";
486             middle += s;
487             }
488         }
489
490     if (u->GetProperty().realName.ModificationTime() > lastUserUpdateTime)
491         {
492         Encode12str(enc, u->GetProperty().realName);
493         strprintf(&s, "<name value=\"%s\" />", enc.c_str());
494         middle += s;
495         }
496
497     if (u->GetProperty().group.ModificationTime() > lastUserUpdateTime)
498         {
499         Encode12str(enc, u->GetProperty().group);
500         strprintf(&s, "<GROUP value=\"%s\" />", enc.c_str());
501         middle += s;
502         }
503
504     if (u->GetProperty().alwaysOnline.ModificationTime() > lastUserUpdateTime)
505         {
506         strprintf(&s, "<aonline value=\"%d\" />", u->GetProperty().alwaysOnline.Get());
507         middle += s;
508         }
509
510     if (u->GetCurrIPModificationTime() > lastUserUpdateTime)
511         {
512         strprintf(&s, "<currip value=\"%s\" />", inet_ntostring(u->GetCurrIP()).c_str());
513         middle += s;
514         }
515
516
517     if (u->GetConnectedModificationTime() > lastUserUpdateTime)
518         {
519         strprintf(&s, "<status value=\"%d\" />", u->GetConnected());
520         middle += s;
521         }
522
523     if (u->GetPingTime() > lastUserUpdateTime)
524         {
525         strprintf(&s, "<PingTime value=\"%lu\" />", u->GetPingTime());
526         middle += s;
527         }
528
529     if (u->GetProperty().ips.ModificationTime() > lastUserUpdateTime)
530         {
531         std::ostringstream sstr;
532         sstr << u->GetProperty().ips.Get();
533         strprintf(&s, "<ip value=\"%s\" />", sstr.str().c_str());
534         middle += s;
535         }
536
537     char st[50];
538     traffStart = "<traff";
539     DIR_TRAFF upload;
540     DIR_TRAFF download;
541     download = u->GetProperty().down.Get();
542     upload = u->GetProperty().up.Get();
543     traffMiddle = "";
544
545     if (u->GetProperty().up.ModificationTime() > lastUserUpdateTime)
546         {
547         for (int j = 0; j < DIR_NUM; j++)
548             {
549             std::string s;
550             x2str(upload[j], s);
551             sprintf(st, " MU%d=\"%s\" ", j, s.c_str());
552             traffMiddle += st;
553             }
554         }
555
556     if (u->GetProperty().down.ModificationTime() > lastUserUpdateTime)
557         {
558         for (int j = 0; j < DIR_NUM; j++)
559             {
560             x2str(download[j], s);
561             sprintf(st, " MD%d=\"%s\" ", j, s.c_str());
562             traffMiddle += st;
563             }
564         }
565
566     traffFinish = " />";
567     if (traffMiddle.length() > 0)
568         {
569         middle += traffStart;
570         middle += traffMiddle;
571         middle += traffFinish;
572         }
573
574     if (u->GetProperty().disabled.ModificationTime() > lastUserUpdateTime)
575         {
576         strprintf(&s, "<down value=\"%d\" />", u->GetProperty().disabled.Get());
577         middle += s;
578         }
579
580     if (u->GetProperty().disabledDetailStat.ModificationTime() > lastUserUpdateTime)
581         {
582         strprintf(&s, "<DisableDetailStat value=\"%d\" />", u->GetProperty().disabledDetailStat.Get());
583         middle += s;
584         }
585
586     //printfd(__FILE__, ">>>>> %s\n", s.c_str());
587
588     if (u->GetProperty().passive.ModificationTime() > lastUserUpdateTime)
589         {
590         strprintf(&s, "<passive value=\"%d\" />", u->GetProperty().passive.Get());
591         middle += s;
592         }
593
594     if (u->GetProperty().lastCashAdd.ModificationTime() > lastUserUpdateTime)
595         {
596         strprintf(&s, "<LastCash value=\"%f\" />", u->GetProperty().lastCashAdd.Get());
597         middle += s;
598         }
599
600     if (u->GetProperty().lastCashAddTime.ModificationTime() > lastUserUpdateTime)
601         {
602         strprintf(&s, "<LastTimeCash value=\"%ld\" />", u->GetProperty().lastCashAddTime.Get());
603         middle += s;
604         }
605
606
607     if (u->GetProperty().lastActivityTime.ModificationTime() > lastUserUpdateTime)
608         {
609         strprintf(&s, "<LastActivityTime value=\"%ld\" />", u->GetProperty().lastActivityTime.Get());
610         middle += s;
611         }
612
613     if (u->GetProperty().creditExpire.ModificationTime() > lastUserUpdateTime)
614         {
615         strprintf(&s, "<CreditExpire value=\"%ld\" />", u->GetProperty().creditExpire.Get());
616         middle += s;
617         }
618
619
620     userFinish = "</user>";
621
622     if (middle.length() > 0)
623         {
624         /*printfd(__FILE__, "login: %s\n", u->GetLogin().c_str());
625         printfd(__FILE__, "middle: %s\n", middle.c_str());*/
626
627         answerList->push_back(userStart);
628         answerList->push_back(middle);
629         answerList->push_back(userFinish);
630         }
631     }
632
633 users->CloseSearch(h);
634
635 //answerList->push_back("</Users>");
636
637 answerList->push_back("</Users>");
638 }
639 //-----------------------------------------------------------------------------
640 //  ADD USER
641 //-----------------------------------------------------------------------------
642 int PARSER_ADD_USER::ParseStart(void *, const char *el, const char **attr)
643 {
644 depth++;
645
646 if (depth == 1)
647     {
648     if (strcasecmp(el, "AddUser") == 0)
649         {
650         return 0;
651         }
652     }
653 else
654     {
655     if (strcasecmp(el, "login") == 0)
656         {
657         login = attr[1];
658         return 0;
659         }
660     }
661 return -1;
662 }
663 //-----------------------------------------------------------------------------
664 int PARSER_ADD_USER::ParseEnd(void *, const char *el)
665 {
666 if (depth == 1)
667     {
668     if (strcasecmp(el, "AddUser") == 0)
669         {
670         CreateAnswer();
671         depth--;
672         return 0;
673         }
674     }
675
676 depth--;
677 return -1;
678 }
679 //-----------------------------------------------------------------------------
680 void PARSER_ADD_USER::Reset()
681 {
682 BASE_PARSER::Reset();
683 depth = 0;
684 }
685 //-----------------------------------------------------------------------------
686 void PARSER_ADD_USER::CreateAnswer()
687 {
688 //answerList->clear();
689 answerList->erase(answerList->begin(), answerList->end());
690
691 if (CheckUserData() == 0)
692     {
693     answerList->push_back("<AddUser result=\"ok\"/>");
694     }
695 else
696     {
697     answerList->push_back("<AddUser result=\"error\" reason=\"Access denied\"/>");
698     }
699 }
700 //-----------------------------------------------------------------------------
701 int PARSER_ADD_USER::CheckUserData()
702 {
703 USER_PTR u;
704 if (users->FindByName(login, &u))
705     {
706     return users->Add(login, currAdmin);
707     }
708 return -1;
709 }
710 //-----------------------------------------------------------------------------
711 //  PARSER CHG USER
712 //-----------------------------------------------------------------------------
713 PARSER_CHG_USER::PARSER_CHG_USER()
714     : BASE_PARSER(),
715       usr(NULL),
716       ucr(NULL),
717       upr(NULL),
718       downr(NULL),
719       cashMsg(),
720       login(),
721       cashMustBeAdded(false),
722       res(0)
723 {
724 Reset();
725 }
726 //-----------------------------------------------------------------------------
727 PARSER_CHG_USER::~PARSER_CHG_USER()
728 {
729 delete usr;
730 delete ucr;
731 delete[] upr;
732 delete[] downr;
733 }
734 //-----------------------------------------------------------------------------
735 void PARSER_CHG_USER::Reset()
736 {
737 depth = 0;
738 delete usr;
739
740 delete ucr;
741
742 delete[] upr;
743
744 delete[] downr;
745
746 usr = new USER_STAT_RES;
747 ucr = new USER_CONF_RES;
748
749 upr = new RESETABLE<uint64_t>[DIR_NUM];
750 downr = new RESETABLE<uint64_t>[DIR_NUM];
751 }
752 //-----------------------------------------------------------------------------
753 std::string PARSER_CHG_USER::EncChar2String(const char * strEnc)
754 {
755 std::string str;
756 Decode21str(str, strEnc);
757 return str;
758 }
759 //-----------------------------------------------------------------------------
760 int PARSER_CHG_USER::ParseStart(void *, const char *el, const char **attr)
761 {
762 depth++;
763
764 if (depth == 1)
765     {
766     if (strcasecmp(el, "SetUser") == 0)
767         {
768         return 0;
769         }
770     }
771 else
772     {
773     //printfd(__FILE__, "el=%s\n", el);
774     if (strcasecmp(el, "login") == 0)
775         {
776         login = attr[1];
777         return 0;
778         }
779
780     if (strcasecmp(el, "ip") == 0)
781         {
782         try
783             {
784             ucr->ips = StrToIPS(attr[1]);
785             }
786         catch (...)
787             {
788             printfd(__FILE__, "StrToIPS Error!\n");
789             }
790         }
791
792     if (strcasecmp(el, "password") == 0)
793         {
794         ucr->password = attr[1];
795         return 0;
796         }
797
798     if (strcasecmp(el, "address") == 0)
799         {
800         ucr->address = EncChar2String(attr[1]);
801         return 0;
802         }
803
804     if (strcasecmp(el, "aonline") == 0)
805         {
806         ucr->alwaysOnline = (*(attr[1]) != '0');
807         return 0;
808         }
809
810     if (strcasecmp(el, "cash") == 0)
811         {
812         if (attr[2] && (strcasecmp(attr[2], "msg") == 0))
813             {
814             cashMsg = EncChar2String(attr[3]);
815             }
816
817         double cash;
818         if (strtodouble2(attr[1], cash) == 0)
819             usr->cash = cash;
820
821         if (strcasecmp(attr[0], "set") == 0)
822             cashMustBeAdded = false;
823
824         if (strcasecmp(attr[0], "add") == 0)
825             cashMustBeAdded = true;
826
827         return 0;
828         }
829
830     if (strcasecmp(el, "CreditExpire") == 0)
831         {
832         long int creditExpire = 0;
833         if (str2x(attr[1], creditExpire) == 0)
834             ucr->creditExpire = (time_t)creditExpire;
835
836         return 0;
837         }
838
839     if (strcasecmp(el, "credit") == 0)
840         {
841         double credit;
842         if (strtodouble2(attr[1], credit) == 0)
843             ucr->credit = credit;
844         return 0;
845         }
846
847     if (strcasecmp(el, "freemb") == 0)
848         {
849         double freeMb;
850         if (strtodouble2(attr[1], freeMb) == 0)
851             usr->freeMb = freeMb;
852         return 0;
853         }
854
855     if (strcasecmp(el, "down") == 0)
856         {
857         int down = 0;
858         if (str2x(attr[1], down) == 0)
859             ucr->disabled = down;
860         return 0;
861         }
862
863     if (strcasecmp(el, "DisableDetailStat") == 0)
864         {
865         int disabledDetailStat = 0;
866         if (str2x(attr[1], disabledDetailStat) == 0)
867             ucr->disabledDetailStat = disabledDetailStat;
868         return 0;
869         }
870
871     if (strcasecmp(el, "email") == 0)
872         {
873         ucr->email = EncChar2String(attr[1]);
874         return 0;
875         }
876
877     for (int i = 0; i < USERDATA_NUM; i++)
878         {
879         char name[15];
880         sprintf(name, "userdata%d", i);
881         if (strcasecmp(el, name) == 0)
882             {
883             ucr->userdata[i] = EncChar2String(attr[1]);
884             return 0;
885             }
886         }
887
888     if (strcasecmp(el, "group") == 0)
889         {
890         ucr->group = EncChar2String(attr[1]);
891         return 0;
892         }
893
894     if (strcasecmp(el, "note") == 0)
895         {
896         ucr->note = EncChar2String(attr[1]);
897         return 0;
898         }
899
900     if (strcasecmp(el, "passive") == 0)
901         {
902         int passive = 0;
903         if (str2x(attr[1], passive) == 0)
904             ucr->passive = passive;
905         return 0;
906         }
907
908     if (strcasecmp(el, "phone") == 0)
909         {
910         ucr->phone = EncChar2String(attr[1]);
911         return 0;
912         }
913
914     if (strcasecmp(el, "Name") == 0)
915         {
916         ucr->realName = EncChar2String(attr[1]);
917         return 0;
918         }
919
920     if (strcasecmp(el, "traff") == 0)
921         {
922         int j = 0;
923         int dir;
924         DIR_TRAFF dtu;
925         DIR_TRAFF dtd;
926         uint64_t t = 0;
927         while (attr[j])
928             {
929             dir = attr[j][2] - '0';
930
931             if (strncasecmp(attr[j], "md", 2) == 0)
932                 {
933                 str2x(attr[j+1], t);
934                 dtd[dir] = t;
935                 downr[dir] = t;
936                 }
937             if (strncasecmp(attr[j], "mu", 2) == 0)
938                 {
939                 str2x(attr[j+1], t);
940                 dtu[dir] = t;
941                 upr[dir] = t;
942                 }
943             j+=2;
944             }
945         usr->down = dtd;
946         usr->up = dtu;
947         return 0;
948         }
949
950     if (strcasecmp(el, "tariff") == 0)
951         {
952         if (strcasecmp(attr[0], "now") == 0)
953             ucr->tariffName = attr[1];
954
955         if (strcasecmp(attr[0], "delayed") == 0)
956             ucr->nextTariff = attr[1];
957
958         return 0;
959         }
960     }
961 return -1;
962 }
963 //-----------------------------------------------------------------------------
964 int PARSER_CHG_USER::ParseEnd(void *, const char *el)
965 {
966 if (depth == 1)
967     {
968     if (strcasecmp(el, "SetUser") == 0)
969         {
970         AplayChanges();
971         CreateAnswer();
972         depth--;
973         return 0;
974         }
975     }
976
977 depth--;
978 return -1;
979 }
980 //-----------------------------------------------------------------------------
981 void PARSER_CHG_USER::CreateAnswer()
982 {
983 //answerList->clear();
984 answerList->erase(answerList->begin(), answerList->end());
985
986 switch (res)
987     {
988     case 0:
989         answerList->push_back("<SetUser result=\"ok\"/>");
990         break;
991     case -1:
992         answerList->push_back("<SetUser result=\"error\"/>");
993         break;
994     case -2:
995         answerList->push_back("<SetUser result=\"error\"/>");
996         break;
997     default:
998         answerList->push_back("<SetUser result=\"error\"/>");
999         break;
1000     }
1001
1002 }
1003 //-----------------------------------------------------------------------------
1004 int PARSER_CHG_USER::AplayChanges()
1005 {
1006 printfd(__FILE__, "PARSER_CHG_USER::AplayChanges()\n");
1007 USER_PTR u;
1008
1009 res = 0;
1010 if (users->FindByName(login, &u))
1011     {
1012     res = -1;
1013     return -1;
1014     }
1015
1016 bool check = false;
1017 bool alwaysOnline = u->GetProperty().alwaysOnline;
1018 if (!ucr->alwaysOnline.res_empty())
1019     {
1020     check = true;
1021     alwaysOnline = ucr->alwaysOnline.const_data();
1022     }
1023 bool onlyOneIP = u->GetProperty().ips.ConstData().OnlyOneIP();
1024 if (!ucr->ips.res_empty())
1025     {
1026     check = true;
1027     onlyOneIP = ucr->ips.const_data().OnlyOneIP();
1028     }
1029
1030 if (check && alwaysOnline && !onlyOneIP)
1031     {
1032     printfd(__FILE__, "Requested change leads to a forbidden state: AlwaysOnline with multiple IP's\n");
1033     GetStgLogger()("%s Requested change leads to a forbidden state: AlwaysOnline with multiple IP's", currAdmin->GetLogStr().c_str());
1034     res = -1;
1035     return -1;
1036     }
1037
1038 for (size_t i = 0; i < ucr->ips.const_data().Count(); ++i)
1039     {
1040     CONST_USER_PTR user;
1041     uint32_t ip = ucr->ips.const_data().operator[](i).ip;
1042     if (users->IsIPInUse(ip, login, &user))
1043         {
1044         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());
1045         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());
1046         res = -1;
1047         return -1;
1048         }
1049     }
1050
1051 if (!ucr->ips.res_empty())
1052     if (!u->GetProperty().ips.Set(ucr->ips.const_data(), currAdmin, login, store))
1053         res = -1;
1054
1055 if (!ucr->alwaysOnline.res_empty())
1056     if (!u->GetProperty().alwaysOnline.Set(ucr->alwaysOnline.const_data(),
1057                                       currAdmin, login, store))
1058         res = -1;
1059
1060 if (!ucr->address.res_empty())
1061     if (!u->GetProperty().address.Set(ucr->address.const_data(), currAdmin, login, store))
1062         res = -1;
1063
1064 if (!ucr->creditExpire.res_empty())
1065     if (!u->GetProperty().creditExpire.Set(ucr->creditExpire.const_data(),
1066                                       currAdmin, login, store))
1067         res = -1;
1068
1069 if (!ucr->credit.res_empty())
1070     if (!u->GetProperty().credit.Set(ucr->credit.const_data(), currAdmin, login, store))
1071         res = -1;
1072
1073 if (!usr->freeMb.res_empty())
1074     if (!u->GetProperty().freeMb.Set(usr->freeMb.const_data(), currAdmin, login, store))
1075         res = -1;
1076
1077 if (!ucr->disabled.res_empty())
1078     if (!u->GetProperty().disabled.Set(ucr->disabled.const_data(), currAdmin, login, store))
1079         res = -1;
1080
1081 if (!ucr->disabledDetailStat.res_empty())
1082     if (!u->GetProperty().disabledDetailStat.Set(ucr->disabledDetailStat.const_data(), currAdmin, login, store))
1083         res = -1;
1084
1085 if (!ucr->email.res_empty())
1086     if (!u->GetProperty().email.Set(ucr->email.const_data(), currAdmin, login, store))
1087         res = -1;
1088
1089 if (!ucr->group.res_empty())
1090     if (!u->GetProperty().group.Set(ucr->group.const_data(), currAdmin, login, store))
1091         res = -1;
1092
1093 if (!ucr->note.res_empty())
1094     if (!u->GetProperty().note.Set(ucr->note.const_data(), currAdmin, login, store))
1095         res = -1;
1096
1097 std::vector<USER_PROPERTY_LOGGED<std::string> *> userdata;
1098 userdata.push_back(u->GetProperty().userdata0.GetPointer());
1099 userdata.push_back(u->GetProperty().userdata1.GetPointer());
1100 userdata.push_back(u->GetProperty().userdata2.GetPointer());
1101 userdata.push_back(u->GetProperty().userdata3.GetPointer());
1102 userdata.push_back(u->GetProperty().userdata4.GetPointer());
1103 userdata.push_back(u->GetProperty().userdata5.GetPointer());
1104 userdata.push_back(u->GetProperty().userdata6.GetPointer());
1105 userdata.push_back(u->GetProperty().userdata7.GetPointer());
1106 userdata.push_back(u->GetProperty().userdata8.GetPointer());
1107 userdata.push_back(u->GetProperty().userdata9.GetPointer());
1108
1109 for (int i = 0; i < (int)userdata.size(); i++)
1110     {
1111     if (!ucr->userdata[i].res_empty())
1112         {
1113         if(!userdata[i]->Set(ucr->userdata[i].const_data(), currAdmin, login, store))
1114             res = -1;
1115         }
1116     }
1117
1118 if (!ucr->passive.res_empty())
1119     if (!u->GetProperty().passive.Set(ucr->passive.const_data(), currAdmin, login, store))
1120         res = -1;
1121
1122 if (!ucr->password.res_empty())
1123     if (!u->GetProperty().password.Set(ucr->password.const_data(), currAdmin, login, store))
1124         res = -1;
1125
1126 if (!ucr->phone.res_empty())
1127     if (!u->GetProperty().phone.Set(ucr->phone.const_data(), currAdmin, login, store))
1128         res = -1;
1129
1130 if (!ucr->realName.res_empty())
1131     if (!u->GetProperty().realName.Set(ucr->realName.const_data(), currAdmin, login, store))
1132         res = -1;
1133
1134
1135 if (!usr->cash.res_empty())
1136     {
1137     //if (*currAdmin->GetPriv()->userCash)
1138         {
1139         if (cashMustBeAdded)
1140             {
1141             if (!u->GetProperty().cash.Set(usr->cash.const_data() + u->GetProperty().cash,
1142                                            currAdmin,
1143                                            login,
1144                                            store,
1145                                            cashMsg))
1146                 res = -1;
1147             }
1148         else
1149             {
1150             if (!u->GetProperty().cash.Set(usr->cash.const_data(), currAdmin, login, store, cashMsg))
1151                 res = -1;
1152             }
1153         }
1154     }
1155
1156
1157 if (!ucr->tariffName.res_empty())
1158     {
1159     if (tariffs->FindByName(ucr->tariffName.const_data()))
1160         {
1161         if (!u->GetProperty().tariffName.Set(ucr->tariffName.const_data(), currAdmin, login, store))
1162             res = -1;
1163         u->ResetNextTariff();
1164         }
1165     else
1166         {
1167         //WriteServLog("SetUser: Tariff %s not found", ud.conf.tariffName.c_str());
1168         res = -1;
1169         }
1170     }
1171
1172 if (!ucr->nextTariff.res_empty())
1173     {
1174     if (tariffs->FindByName(ucr->nextTariff.const_data()))
1175         {
1176         if (!u->GetProperty().nextTariff.Set(ucr->nextTariff.const_data(), currAdmin, login, store))
1177             res = -1;
1178         }
1179     else
1180         {
1181         //WriteServLog("SetUser: Tariff %s not found", ud.conf.tariffName.c_str());
1182         res = -1;
1183         }
1184     }
1185
1186 DIR_TRAFF up = u->GetProperty().up;
1187 DIR_TRAFF down = u->GetProperty().down;
1188 int upCount = 0;
1189 int downCount = 0;
1190 for (int i = 0; i < DIR_NUM; i++)
1191     {
1192     if (!upr[i].res_empty())
1193         {
1194         up[i] = upr[i];
1195         upCount++;
1196         }
1197     if (!downr[i].res_empty())
1198         {
1199         down[i] = downr[i];
1200         downCount++;
1201         }
1202     }
1203
1204 if (upCount)
1205     if (!u->GetProperty().up.Set(up, currAdmin, login, store))
1206         res = -1;
1207
1208 if (downCount)
1209     if (!u->GetProperty().down.Set(down, currAdmin, login, store))
1210         res = -1;
1211
1212 /*if (!usr->down.res_empty())
1213     {
1214     u->GetProperty().down.Set(usr->down.const_data(), currAdmin, login, store);
1215     }
1216 if (!usr->up.res_empty())
1217     {
1218     u->GetProperty().up.Set(usr->up.const_data(), currAdmin, login, store);
1219     }*/
1220
1221 u->WriteConf();
1222 u->WriteStat();
1223
1224 return 0;
1225 }
1226 //-----------------------------------------------------------------------------
1227 //      SEND MESSAGE
1228 //-----------------------------------------------------------------------------
1229 int PARSER_SEND_MESSAGE::ParseStart(void *, const char *el, const char **attr)
1230 {
1231 if (strcasecmp(el, "Message") == 0)
1232     {
1233     for (int i = 0; i < 14; i++)
1234         {
1235         if (attr[i] == NULL)
1236             {
1237             result = res_params_error;
1238             CreateAnswer();
1239             printfd(__FILE__, "To few parameters\n");
1240             return 0;
1241             }
1242         }
1243
1244     for (int i = 0; i < 14; i+=2)
1245         {
1246         if (strcasecmp(attr[i], "login") == 0)
1247             {
1248             ParseLogins(attr[i+1]);
1249             /*if (users->FindByName(login, &u))
1250                 {
1251                 result = res_unknown;
1252                 break;
1253                 }*/
1254             }
1255
1256         if (strcasecmp(attr[i], "MsgVer") == 0)
1257             {
1258             str2x(attr[i+1], msg.header.ver);
1259             if (msg.header.ver != 1)
1260                 result = res_params_error;
1261             }
1262
1263         if (strcasecmp(attr[i], "MsgType") == 0)
1264             {
1265             str2x(attr[i+1], msg.header.type);
1266             if (msg.header.type != 1)
1267                 result = res_params_error;
1268             }
1269
1270         if (strcasecmp(attr[i], "Repeat") == 0)
1271             {
1272             str2x(attr[i+1], msg.header.repeat);
1273             if (msg.header.repeat < 0)
1274                 result = res_params_error;
1275             }
1276
1277         if (strcasecmp(attr[i], "RepeatPeriod") == 0)
1278             {
1279             str2x(attr[i+1], msg.header.repeatPeriod);
1280             }
1281
1282         if (strcasecmp(attr[i], "ShowTime") == 0)
1283             {
1284             str2x(attr[i+1], msg.header.showTime);
1285             }
1286
1287         if (strcasecmp(attr[i], "Text") == 0)
1288             {
1289             Decode21str(msg.text, attr[i+1]);
1290             result = res_ok;
1291             }
1292         }
1293     return 0;
1294     }
1295 return -1;
1296 }
1297 //-----------------------------------------------------------------------------
1298 int PARSER_SEND_MESSAGE::ParseEnd(void *, const char *el)
1299 {
1300 //MSG msg;
1301 if (strcasecmp(el, "Message") == 0)
1302     {
1303     result = res_unknown;
1304     for (unsigned i = 0; i < logins.size(); i++)
1305         {
1306         if (users->FindByName(logins[i], &u))
1307             {
1308             printfd(__FILE__, "User not found. %s\n", logins[i].c_str());
1309             continue;
1310             }
1311         msg.header.creationTime = static_cast<unsigned int>(stgTime);
1312         u->AddMessage(&msg);
1313         result = res_ok;
1314         }
1315     /*if (result == res_ok)
1316         {
1317         if (strcmp(login, "*") == 0)
1318             {
1319             msg.text = text;
1320             msg.prio = pri;
1321             printfd(__FILE__, "SendMsg text: %s\n", text);
1322             users->GetAllUsers(SendMessageAllUsers, &msg);
1323             }
1324         else
1325             {
1326             u->AddMessage(pri, text);
1327             }
1328         }*/
1329     CreateAnswer();
1330     return 0;
1331     }
1332 return -1;
1333 }
1334 //-----------------------------------------------------------------------------
1335 int PARSER_SEND_MESSAGE::ParseLogins(const char * login)
1336 {
1337 char * p;
1338 char * l = new char[strlen(login) + 1];
1339 strcpy(l, login);
1340 p = strtok(l, ":");
1341 logins.clear();
1342 while(p)
1343     {
1344     logins.push_back(p);
1345     p = strtok(NULL, ":");
1346     }
1347
1348 delete[] l;
1349 return 0;
1350 }
1351 //-----------------------------------------------------------------------------
1352 void PARSER_SEND_MESSAGE::CreateAnswer()
1353 {
1354 //answerList->clear();
1355 answerList->erase(answerList->begin(), answerList->end());
1356 //answerList->push_back("<SendMessageResult value=\"ok\"/>");
1357 //
1358 switch (result)
1359     {
1360     case res_ok:
1361         answerList->push_back("<SendMessageResult value=\"ok\"/>");
1362         break;
1363     case res_params_error:
1364         printfd(__FILE__, "res_params_error\n");
1365         answerList->push_back("<SendMessageResult value=\"Parameters error.\"/>");
1366         break;
1367     case res_unknown:
1368         printfd(__FILE__, "res_unknown\n");
1369         answerList->push_back("<SendMessageResult value=\"Unknown user.\"/>");
1370         break;
1371     default:
1372         printfd(__FILE__, "res_default\n");
1373     }
1374
1375 }
1376 //-----------------------------------------------------------------------------
1377 //      DEL USER
1378 //-----------------------------------------------------------------------------
1379 int PARSER_DEL_USER::ParseStart(void *, const char *el, const char **attr)
1380 {
1381 res = 0;
1382 if (strcasecmp(el, "DelUser") == 0)
1383     {
1384     if (attr[0] == NULL || attr[1] == NULL)
1385         {
1386         //CreateAnswer("Parameters error!");
1387         CreateAnswer();
1388         return 0;
1389         }
1390
1391     if (users->FindByName(attr[1], &u))
1392         {
1393         res = 1;
1394         CreateAnswer();
1395         return 0;
1396         }
1397     CreateAnswer();
1398     return 0;
1399     }
1400 return -1;
1401 }
1402 //-----------------------------------------------------------------------------
1403 int PARSER_DEL_USER::ParseEnd(void *, const char *el)
1404 {
1405 if (strcasecmp(el, "DelUser") == 0)
1406     {
1407     if (!res)
1408         users->Del(u->GetLogin(), currAdmin);
1409
1410     return 0;
1411     }
1412 return -1;
1413 }
1414 //-----------------------------------------------------------------------------
1415 void PARSER_DEL_USER::CreateAnswer()
1416 {
1417 if (res)
1418     answerList->push_back("<DelUser value=\"error\" reason=\"User not found\"/>");
1419 else
1420     answerList->push_back("<DelUser value=\"ok\"/>");
1421 }
1422 //-----------------------------------------------------------------------------
1423 //  CHECK USER
1424 // <checkuser login="vasya" password=\"123456\"/>
1425 //-----------------------------------------------------------------------------
1426 int PARSER_CHECK_USER::ParseStart(void *, const char *el, const char **attr)
1427 {
1428 if (strcasecmp(el, "CheckUser") == 0)
1429     {
1430     if (attr[0] == NULL || attr[1] == NULL
1431      || attr[2] == NULL || attr[3] == NULL)
1432         {
1433         CreateAnswer("Invalid parameters.");
1434         printfd(__FILE__, "PARSER_CHECK_USER - attr err\n");
1435         return 0;
1436         }
1437
1438     USER_PTR user;
1439     if (users->FindByName(attr[1], &user))
1440         {
1441         CreateAnswer("User not found.");
1442         printfd(__FILE__, "PARSER_CHECK_USER - login err\n");
1443         return 0;
1444         }
1445
1446     if (strcmp(user->GetProperty().password.Get().c_str(), attr[3]))
1447         {
1448         CreateAnswer("Wrong password.");
1449         printfd(__FILE__, "PARSER_CHECK_USER - passwd err\n");
1450         return 0;
1451         }
1452
1453     CreateAnswer(NULL);
1454     return 0;
1455     }
1456 return -1;
1457 }
1458 //-----------------------------------------------------------------------------
1459 int PARSER_CHECK_USER::ParseEnd(void *, const char *el)
1460 {
1461 if (strcasecmp(el, "CheckUser") == 0)
1462     {
1463     return 0;
1464     }
1465 return -1;
1466 }
1467 //-----------------------------------------------------------------------------
1468 void PARSER_CHECK_USER::CreateAnswer(const char * error)
1469 {
1470 if (error)
1471     answerList->push_back(std::string("<CheckUser value=\"Err\" reason=\"") + error + "\"/>");
1472 else
1473     answerList->push_back("<CheckUser value=\"Ok\"/>");
1474 }
1475 //-----------------------------------------------------------------------------
1476 //-----------------------------------------------------------------------------
1477 //-----------------------------------------------------------------------------