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