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