]> git.stg.codes - stg.git/blob - projects/sgconf/main.cpp
Added DIR_TRAFF_RES, refactored DIR_TRAFF.
[stg.git] / projects / sgconf / main.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21  /*
22  $Author: faust $
23  $Revision: 1.25 $
24  $Date: 2010/03/25 14:37:43 $
25  */
26
27 #include <unistd.h>
28 #include <getopt.h>
29 #include <iconv.h>
30 #include <langinfo.h>
31
32 #include <cerrno>
33 #include <clocale>
34 #include <cstdio>
35 #include <cstdlib>
36 #include <cstring>
37 #include <string>
38 #include <sstream>
39
40 #include "stg/common.h"
41 #include "request.h"
42 #include "common_sg.h"
43 #include "sg_error_codes.h"
44
45 namespace
46 {
47
48 template <typename T>
49 struct ARRAY_TYPE;
50
51 template <typename T>
52 struct ARRAY_TYPE<T[]>
53 {
54 typedef T type;
55 };
56
57 template <typename T, size_t N>
58 struct ARRAY_TYPE<T[N]>
59 {
60 typedef T type;
61 };
62
63 template <typename T>
64 bool SetArrayItem(T & array, const char * index, const typename ARRAY_TYPE<T>::type & value)
65 {
66 size_t pos = 0;
67 if (str2x(index, pos))
68     return false;
69 array[pos] = value;
70 return true;
71 }
72
73 } // namespace anonymous
74
75 time_t stgTime;
76
77 struct option long_options_get[] = {
78 {"server",      1, 0, 's'},  //Server
79 {"port",        1, 0, 'p'},  //Port
80 {"admin",       1, 0, 'a'},  //Admin
81 {"admin_pass",  1, 0, 'w'},  //passWord
82 {"user",        1, 0, 'u'},  //User
83 {"addcash",     0, 0, 'c'},  //Add Cash
84 //{"setcash",     0, 0, 'v'},  //Set Cash
85 {"credit",      0, 0, 'r'},  //cRedit
86 {"tariff",      0, 0, 't'},  //Tariff
87 {"message",     0, 0, 'm'},  //message
88 {"password",    0, 0, 'o'},  //password
89 {"down",        0, 0, 'd'},  //down
90 {"passive",     0, 0, 'i'},  //passive
91 {"disable-stat",0, 0, 'S'},  //disable detail stat
92 {"always-online",0, 0, 'O'}, //always online
93 {"session-upload",   1, 0, 500},  //SU0
94 {"session-download", 1, 0, 501},  //SD0
95 {"month-upload",     1, 0, 502},  //MU0
96 {"month-download",   1, 0, 503},  //MD0
97
98 {"user-data",   1, 0, 700},  //UserData0
99
100 {"prepaid",     0, 0, 'e'},  //prepaid traff
101 {"create",      0, 0, 'n'},  //create
102 {"delete",      0, 0, 'l'},  //delete
103
104 {"note",        0, 0, 'N'},  //Note
105 {"name",        0, 0, 'A'},  //nAme
106 {"address",     0, 0, 'D'},  //aDdress
107 {"email",       0, 0, 'L'},  //emaiL
108 {"phone",       0, 0, 'P'},  //phone
109 {"group",       0, 0, 'G'},  //Group
110 {"ip",          0, 0, 'I'},  //IP-address of user
111 {"authorized-by",0, 0, 800}, //always online
112
113 {0, 0, 0, 0}};
114
115 struct option long_options_set[] = {
116 {"server",      1, 0, 's'},  //Server
117 {"port",        1, 0, 'p'},  //Port
118 {"admin",       1, 0, 'a'},  //Admin
119 {"admin_pass",  1, 0, 'w'},  //passWord
120 {"user",        1, 0, 'u'},  //User
121 {"addcash",     1, 0, 'c'},  //Add Cash
122 {"setcash",     1, 0, 'v'},  //Set Cash
123 {"credit",      1, 0, 'r'},  //cRedit
124 {"tariff",      1, 0, 't'},  //Tariff
125 {"message",     1, 0, 'm'},  //message
126 {"password",    1, 0, 'o'},  //password
127 {"down",        1, 0, 'd'},  //down
128 {"passive",     1, 0, 'i'},  //passive
129 {"disable-stat",1, 0, 'S'},  //disable detail stat
130 {"always-online",1, 0, 'O'},  //always online
131 {"session-upload",   1, 0, 500},  //U0
132 {"session-download", 1, 0, 501},  //U1
133 {"month-upload",     1, 0, 502},  //U2
134 {"month-download",   1, 0, 503},  //U3
135
136 {"user-data",        1, 0, 700},  //UserData
137
138 {"prepaid",     1, 0, 'e'},  //prepaid traff
139 {"create",      1, 0, 'n'},  //create
140 {"delete",      1, 0, 'l'},  //delete
141
142 {"note",        1, 0, 'N'},  //Note
143 {"name",        1, 0, 'A'},  //nAme
144 {"address",     1, 0, 'D'},  //aDdress
145 {"email",       1, 0, 'L'},  //emaiL
146 {"phone",       1, 0, 'P'},  //phone
147 {"group",       1, 0, 'G'},  //Group
148 {"ip",          0, 0, 'I'},  //IP-address of user
149
150 {0, 0, 0, 0}};
151
152 //-----------------------------------------------------------------------------
153 double ParseCash(const char * c, string * message)
154 {
155 //-c 123.45:log message
156 double cash;
157 char * msg;
158 char * str;
159 str = new char[strlen(c) + 1];
160
161 strncpy(str, c, strlen(c));
162 str[strlen(c)] = 0;
163
164 msg = strchr(str, ':');
165
166 if (msg)
167     {
168     *message =  msg + 1;
169     str[msg - str] = 0;
170     }
171 else
172     *message = "";
173
174 if (strtodouble2(str, cash) != 0)
175     {
176     printf("Incorrect cash value %s\n", c);
177     exit(PARAMETER_PARSING_ERR_CODE);
178     }
179
180 delete[] str;
181 return cash;
182 }
183 //-----------------------------------------------------------------------------
184 double ParseCredit(const char * c)
185 {
186 double credit;
187 if (strtodouble2(c, credit) != 0)
188     {
189     printf("Incorrect credit value %s\n", c);
190     exit(PARAMETER_PARSING_ERR_CODE);
191     }
192
193 return credit;
194 }
195 //-----------------------------------------------------------------------------
196 double ParsePrepaidTraffic(const char * c)
197 {
198 double credit;
199 if (strtodouble2(c, credit) != 0)
200     {
201     printf("Incorrect prepaid traffic value %s\n", c);
202     exit(PARAMETER_PARSING_ERR_CODE);
203     }
204
205 return credit;
206 }
207 //-----------------------------------------------------------------------------
208 int64_t ParseTraff(const char * c)
209 {
210 int64_t traff;
211 if (str2x(c, traff) != 0)
212     {
213     printf("Incorrect credit value %s\n", c);
214     exit(PARAMETER_PARSING_ERR_CODE);
215     }
216
217 return traff;
218 }
219 //-----------------------------------------------------------------------------
220 bool ParseDownPassive(const char * dp)
221 {
222 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
223     {
224     printf("Incorrect value %s\n", dp);
225     exit(PARAMETER_PARSING_ERR_CODE);
226     }
227
228 return dp[0] - '0';
229 }
230 //-----------------------------------------------------------------------------
231 string ParseTariff(const char * t, int &chgType)
232 {
233 int l = strlen(t);
234 char * s;
235 s = new char[l];
236 char * s1, * s2;
237 string ss;
238
239 strcpy(s, t);
240
241 s1 = strtok(s, ":");
242
243 if (strlen(s1) >= TARIFF_NAME_LEN)
244     {
245     printf("Tariff name too big %s\n", s1);
246     exit(PARAMETER_PARSING_ERR_CODE);
247     }
248
249 //*tariff = s;
250
251 if (CheckLogin(s1))
252     {
253     printf("Incorrect tariff value %s\n", t);
254     exit(PARAMETER_PARSING_ERR_CODE);
255     }
256
257 s2 = strtok(NULL, ":");
258
259 chgType = -1;
260
261 if (s2 == NULL)
262     {
263     chgType = TARIFF_NOW;
264     ss = s;
265     delete[] s;
266     return ss;
267     }
268
269
270 if (strcmp(s2, "now") == 0)
271     chgType = TARIFF_NOW;
272
273 if (strcmp(s2, "delayed") == 0)
274     chgType = TARIFF_DEL;
275
276 if (strcmp(s2, "recalc") == 0)
277     chgType = TARIFF_REC;
278
279 if (chgType < 0)
280     {
281     printf("Incorrect tariff value %s\n", t);
282     exit(PARAMETER_PARSING_ERR_CODE);
283     }
284
285 ss = s;
286 delete[] s;
287 return ss;
288 }
289 //-----------------------------------------------------------------------------
290 time_t ParseCreditExpire(const char * str)
291 {
292 struct tm brokenTime;
293
294 brokenTime.tm_wday = 0;
295 brokenTime.tm_yday = 0;
296 brokenTime.tm_isdst = 0;
297 brokenTime.tm_hour = 0;
298 brokenTime.tm_min = 0;
299 brokenTime.tm_sec = 0;
300
301 stg_strptime(str, "%Y-%m-%d", &brokenTime);
302
303 return stg_timegm(&brokenTime);
304 }
305 //-----------------------------------------------------------------------------
306 void ParseAnyString(const char * c, string * msg, const char * enc)
307 {
308 iconv_t cd;
309 char * ob = new char[strlen(c) + 1];
310 char * ib = new char[strlen(c) + 1];
311
312 strcpy(ib, c);
313
314 char * outbuf = ob;
315 char * inbuf = ib;
316
317 setlocale(LC_ALL, "");
318
319 char charsetF[255];
320 strncpy(charsetF, nl_langinfo(CODESET), 255);
321
322 const char * charsetT = enc;
323
324 size_t nconv = 1;
325
326 size_t insize = strlen(ib);
327 size_t outsize = strlen(ib);
328
329 insize = strlen(c);
330
331 cd = iconv_open(charsetT, charsetF);
332 if (cd == (iconv_t) -1)
333     {
334     if (errno == EINVAL)
335         {
336         printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
337         *msg = c;
338         return;
339         }
340     else
341         printf("error iconv_open\n");
342
343     exit(ICONV_ERR_CODE);
344     }
345
346 #if defined(FREE_BSD) || defined(FREE_BSD5)
347 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
348 #else
349 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
350 #endif
351 //printf("nconv=%d outsize=%d\n", nconv, outsize);
352 if (nconv == (size_t) -1)
353     {
354     if (errno != EINVAL)
355         {
356         printf("iconv error\n");
357         exit(ICONV_ERR_CODE);
358         }
359     }
360
361 *outbuf = L'\0';
362
363 iconv_close(cd);
364 *msg = ob;
365
366 delete[] ob;
367 delete[] ib;
368 }
369 //-----------------------------------------------------------------------------
370 void CreateRequestSet(REQUEST * req, char * r)
371 {
372 const int strLen = 10024;
373 char str[strLen];
374 memset(str, 0, strLen);
375
376 r[0] = 0;
377
378 if (!req->usrMsg.empty())
379     {
380     string msg;
381     Encode12str(msg, req->usrMsg.data());
382     sprintf(str, "<Message login=\"%s\" msgver=\"1\" msgtype=\"1\" repeat=\"0\" repeatperiod=\"0\" showtime=\"0\" text=\"%s\"/>", req->login.const_data().c_str(), msg.c_str());
383     //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
384     strcat(r, str);
385     return;
386     }
387
388 if (req->deleteUser)
389     {
390     sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
391     strcat(r, str);
392     //printf("%s\n", r);
393     return;
394     }
395
396 if (req->createUser)
397     {
398     sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
399     strcat(r, str);
400     //printf("%s\n", r);
401     return;
402     }
403
404 strcat(r, "<SetUser>\n");
405 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
406 strcat(r, str);
407 if (!req->credit.empty())
408     {
409     sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
410     strcat(r, str);
411     }
412
413 if (!req->creditExpire.empty())
414     {
415     sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
416     strcat(r, str);
417     }
418
419 if (!req->prepaidTraff.empty())
420     {
421     sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
422     strcat(r, str);
423     }
424
425 if (!req->cash.empty())
426     {
427     string msg;
428     Encode12str(msg, req->message);
429     sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
430     strcat(r, str);
431     }
432
433 if (!req->setCash.empty())
434     {
435     string msg;
436     Encode12str(msg, req->message);
437     sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
438     strcat(r, str);
439     }
440
441 if (!req->usrPasswd.empty())
442     {
443     sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
444     strcat(r, str);
445     }
446
447 if (!req->down.empty())
448     {
449     sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
450     strcat(r, str);
451     }
452
453 if (!req->passive.empty())
454     {
455     sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
456     strcat(r, str);
457     }
458
459 if (!req->disableDetailStat.empty())
460     {
461     sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
462     strcat(r, str);
463     }
464
465 if (!req->alwaysOnline.empty())
466     {
467     sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
468     strcat(r, str);
469     }
470
471 // IP-address of user
472 if (!req->ips.empty())
473     {
474     sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
475     strcat(r, str);
476     }
477
478 int uPresent = false;
479 int dPresent = false;
480 for (int i = 0; i < DIR_NUM; i++)
481     {
482     if (!req->monthUpload[i].empty())
483         {
484         if (!uPresent && !dPresent)
485             {
486             sprintf(str, "<traff ");
487             strcat(r, str);
488             uPresent = true;
489             }
490
491         stringstream ss;
492         ss << req->monthUpload[i].const_data();
493         //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
494         sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
495         strcat(r, str);
496         }
497     if (!req->monthDownload[i].empty())
498         {
499         if (!uPresent && !dPresent)
500             {
501             sprintf(str, "<traff ");
502             strcat(r, str);
503             dPresent = true;
504             }
505
506         stringstream ss;
507         ss << req->monthDownload[i].const_data();
508         sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
509         strcat(r, str);
510         }
511     if (!req->sessionUpload[i].empty())
512         {
513         if (!uPresent && !dPresent)
514             {
515             sprintf(str, "<traff ");
516             strcat(r, str);
517             uPresent = true;
518             }
519
520         stringstream ss;
521         ss << req->sessionUpload[i].const_data();
522         //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
523         sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
524         strcat(r, str);
525         }
526     if (!req->sessionDownload[i].empty())
527         {
528         if (!uPresent && !dPresent)
529             {
530             sprintf(str, "<traff ");
531             strcat(r, str);
532             dPresent = true;
533             }
534
535         stringstream ss;
536         ss << req->sessionDownload[i].const_data();
537         sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
538         strcat(r, str);
539         }
540     }
541 if (uPresent || dPresent)
542     {
543     strcat(r, "/>");
544     }
545
546 //printf("%s\n", r);
547
548 if (!req->tariff.empty())
549     {
550     switch (req->chgTariff)
551         {
552         case TARIFF_NOW:
553             sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
554             strcat(r, str);
555             break;
556         case TARIFF_REC:
557             sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
558             strcat(r, str);
559             break;
560         case TARIFF_DEL:
561             sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
562             strcat(r, str);
563             break;
564         }
565
566     }
567
568 if (!req->note.empty())
569     {
570     string note;
571     Encode12str(note, req->note.data());
572     sprintf(str, "<note value=\"%s\"/>", note.c_str());
573     strcat(r, str);
574     }
575
576 if (!req->name.empty())
577     {
578     string name;
579     Encode12str(name, req->name.data());
580     sprintf(str, "<name value=\"%s\"/>", name.c_str());
581     strcat(r, str);
582     }
583
584 if (!req->address.empty())
585     {
586     string address;
587     Encode12str(address, req->address.data());
588     sprintf(str, "<address value=\"%s\"/>", address.c_str());
589     strcat(r, str);
590     }
591
592 if (!req->email.empty())
593     {
594     string email;
595     Encode12str(email, req->email.data());
596     sprintf(str, "<email value=\"%s\"/>", email.c_str());
597     strcat(r, str);
598     }
599
600 if (!req->phone.empty())
601     {
602     string phone;
603     Encode12str(phone, req->phone.data());
604     sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
605     strcat(r, str);
606     }
607
608 if (!req->group.empty())
609     {
610     string group;
611     Encode12str(group, req->group.data());
612     sprintf(str, "<group value=\"%s\"/>", group.c_str());
613     strcat(r, str);
614     }
615
616 for (int i = 0; i < USERDATA_NUM; i++)
617     {
618     if (!req->userData[i].empty())
619         {
620         string ud;
621         Encode12str(ud, req->userData[i].data());
622         sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
623         strcat(r, str);
624         }
625     }
626
627 strcat(r, "</SetUser>\n");
628 }
629 //-----------------------------------------------------------------------------
630 int CheckParameters(REQUEST * req)
631 {
632 bool su = false;
633 bool sd = false;
634 bool mu = false;
635 bool md = false;
636 bool ud = false;
637 bool a = !req->admLogin.empty()
638     && !req->admPasswd.empty()
639     && !req->server.empty()
640     && !req->port.empty()
641     && !req->login.empty();
642
643 bool b = !req->cash.empty()
644     || !req->setCash.empty()
645     || !req->credit.empty()
646     || !req->prepaidTraff.empty()
647     || !req->tariff.empty()
648     || !req->usrMsg.empty()
649     || !req->usrPasswd.empty()
650
651     || !req->note.empty()
652     || !req->name.empty()
653     || !req->address.empty()
654     || !req->email.empty()
655     || !req->phone.empty()
656     || !req->group.empty()
657     || !req->ips.empty() // IP-address of user
658
659     || !req->createUser
660     || !req->deleteUser;
661
662
663 for (int i = 0; i < DIR_NUM; i++)
664     {
665     if (req->sessionUpload[i].empty())
666         {
667         su = true;
668         break;
669         }
670     }
671
672 for (int i = 0; i < DIR_NUM; i++)
673     {
674     if (req->sessionDownload[i].empty())
675         {
676         sd = true;
677         break;
678         }
679     }
680
681 for (int i = 0; i < DIR_NUM; i++)
682     {
683     if (req->monthUpload[i].empty())
684         {
685         mu = true;
686         break;
687         }
688     }
689
690 for (int i = 0; i < DIR_NUM; i++)
691     {
692     if (req->monthDownload[i].empty())
693         {
694         md = true;
695         break;
696         }
697     }
698
699 for (int i = 0; i < DIR_NUM; i++)
700     {
701     if (req->userData[i].empty())
702         {
703         ud = true;
704         break;
705         }
706     }
707
708
709 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
710 return a && (b || su || sd || mu || md || ud);
711 }
712 //-----------------------------------------------------------------------------
713 int CheckParametersGet(REQUEST * req)
714 {
715 return CheckParameters(req);
716 }
717 //-----------------------------------------------------------------------------
718 int CheckParametersSet(REQUEST * req)
719 {
720 return CheckParameters(req);
721 }
722 //-----------------------------------------------------------------------------
723 bool mainGet(int argc, char **argv)
724 {
725 int c;
726 REQUEST req;
727 RESETABLE<string>   t1;
728 int missedOptionArg = false;
729
730 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
731 int option_index = -1;
732
733 while (1)
734     {
735     option_index = -1;
736     c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
737     if (c == -1)
738         break;
739
740     switch (c)
741         {
742         case 's': //server
743             req.server = optarg;
744             break;
745
746         case 'p': //port
747             req.port = ParseServerPort(optarg);
748             //req.portReq = 1;
749             break;
750
751         case 'a': //admin
752             req.admLogin = ParseAdminLogin(optarg);
753             break;
754
755         case 'w': //admin password
756             req.admPasswd = ParsePassword(optarg);
757             break;
758
759         case 'o': //change user password
760             req.usrPasswd = " ";
761             break;
762
763         case 'u': //user
764             req.login = ParseUser(optarg);
765             break;
766
767         case 'c': //get cash
768             req.cash = 1;
769             break;
770
771         case 'r': //credit
772             req.credit = 1;
773             break;
774
775         case 'E': //credit expire
776             req.creditExpire = 1;
777             break;
778
779         case 'd': //down
780             req.down = 1;
781             break;
782
783         case 'i': //passive
784             req.passive = 1;
785             break;
786
787         case 't': //tariff
788             req.tariff = " ";
789             break;
790
791         case 'e': //Prepaid Traffic
792             req.prepaidTraff = 1;
793             break;
794
795         case 'N': //Note
796             req.note = " ";
797             break;
798
799         case 'A': //nAme
800             req.name = " ";
801             break;
802
803         case 'D': //aDdress
804             req.address =" ";
805             break;
806
807         case 'L': //emaiL
808             req.email = " ";
809             break;
810
811         case 'P': //phone
812             req.phone = " ";
813             break;
814
815         case 'G': //Group
816             req.group = " ";
817             break;
818
819         case 'I': //IP-address of user
820             req.ips = " ";
821             break;
822
823         case 'S': //Detail stat status
824             req.disableDetailStat = " ";
825             break;
826
827         case 'O': //Always online status
828             req.alwaysOnline = " ";
829             break;
830
831         case 500: //U
832             SetArrayItem(req.sessionUpload, optarg, 1);
833             //req.sessionUpload[optarg] = 1;
834             break;
835         case 501:
836             SetArrayItem(req.sessionDownload, optarg, 1);
837             //req.sessionDownload[optarg] = 1;
838             break;
839         case 502:
840             SetArrayItem(req.monthUpload, optarg, 1);
841             //req.monthUpload[optarg] = 1;
842             break;
843         case 503:
844             SetArrayItem(req.monthDownload, optarg, 1);
845             //req.monthDownload[optarg] = 1;
846             break;
847
848         case 700: //UserData
849             SetArrayItem(req.userData, optarg, std::string(" "));
850             //req.userData[optarg] = " ";
851             break;
852
853         case 800:
854             req.authBy = true;
855             break;
856
857         case '?':
858         case ':':
859             missedOptionArg = true;
860             break;
861
862         default:
863             printf ("?? getopt returned character code 0%o ??\n", c);
864         }
865     }
866
867 if (optind < argc)
868     {
869     printf ("non-option ARGV-elements: ");
870     while (optind < argc)
871         printf ("%s ", argv[optind++]);
872     UsageInfo();
873     exit(PARAMETER_PARSING_ERR_CODE);
874     }
875
876 if (missedOptionArg || !CheckParametersGet(&req))
877     {
878     //printf("Parameter needed\n");
879     UsageInfo();
880     exit(PARAMETER_PARSING_ERR_CODE);
881     }
882
883 if (req.authBy)
884     return ProcessAuthBy(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data());
885 else
886     return ProcessGetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), req);
887 }
888 //-----------------------------------------------------------------------------
889 bool mainSet(int argc, char **argv)
890 {
891 string str;
892
893 int c;
894 bool isMessage = false;
895 REQUEST req;
896
897 RESETABLE<string>   t1;
898
899 const char * short_options_set = "s:p:a:w:u:c:r:t:m:o:d:i:e:v:nlN:A:D:L:P:G:I:S:O:E:";
900
901 int missedOptionArg = false;
902
903 while (1)
904     {
905     int option_index = -1;
906
907     c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
908
909     if (c == -1)
910         break;
911
912     switch (c)
913         {
914         case 's': //server
915             req.server = optarg;
916             break;
917
918         case 'p': //port
919             req.port = ParseServerPort(optarg);
920             //req.portReq = 1;
921             break;
922
923         case 'a': //admin
924             req.admLogin = ParseAdminLogin(optarg);
925             break;
926
927         case 'w': //admin password
928             req.admPasswd = ParsePassword(optarg);
929             break;
930
931         case 'o': //change user password
932             req.usrPasswd = ParsePassword(optarg);
933             break;
934
935         case 'u': //user
936             req.login = ParseUser(optarg);
937             break;
938
939         case 'c': //add cash
940             req.cash = ParseCash(optarg, &req.message);
941             break;
942
943         case 'v': //set cash
944             req.setCash = ParseCash(optarg, &req.message);
945             break;
946
947         case 'r': //credit
948             req.credit = ParseCredit(optarg);
949             break;
950
951         case 'E': //credit expire
952             req.creditExpire = ParseCreditExpire(optarg);
953             break;
954
955         case 'd': //down
956             req.down = ParseDownPassive(optarg);
957             break;
958
959         case 'i': //passive
960             req.passive = ParseDownPassive(optarg);
961             break;
962
963         case 't': //tariff
964             req.tariff = ParseTariff(optarg, req.chgTariff);
965             break;
966
967         case 'm': //message
968             ParseAnyString(optarg, &str);
969             req.usrMsg = str;
970             isMessage = true;
971             break;
972
973         case 'e': //Prepaid Traffic
974             req.prepaidTraff = ParsePrepaidTraffic(optarg);
975             break;
976
977         case 'n': //Create User
978             req.createUser = true;
979             break;
980
981         case 'l': //Delete User
982             req.deleteUser = true;
983             break;
984
985         case 'N': //Note
986             ParseAnyString(optarg, &str, "koi8-ru");
987             req.note = str;
988             break;
989
990         case 'A': //nAme
991             ParseAnyString(optarg, &str, "koi8-ru");
992             req.name = str;
993             break;
994
995         case 'D': //aDdress
996             ParseAnyString(optarg, &str, "koi8-ru");
997             req.address = str;
998             break;
999
1000         case 'L': //emaiL
1001             ParseAnyString(optarg, &str, "koi8-ru");
1002             req.email = str;
1003             //printf("EMAIL=%s\n", optarg);
1004             break;
1005
1006         case 'P': //phone
1007             ParseAnyString(optarg, &str);
1008             req.phone = str;
1009             break;
1010
1011         case 'G': //Group
1012             ParseAnyString(optarg, &str, "koi8-ru");
1013             req.group = str;
1014             break;
1015
1016         case 'I': //IP-address of user
1017             ParseAnyString(optarg, &str);
1018             req.ips = str;
1019             break;
1020
1021         case 'S':
1022             req.disableDetailStat = ParseDownPassive(optarg);
1023             break;
1024
1025         case 'O':
1026             req.alwaysOnline = ParseDownPassive(optarg);
1027             break;
1028
1029         case 500: //U
1030             SetArrayItem(req.sessionUpload, optarg, ParseTraff(argv[optind++]));
1031             //req.sessionUpload[optarg] = ParseTraff(argv[optind++]);
1032             break;
1033         case 501:
1034             SetArrayItem(req.sessionDownload, optarg, ParseTraff(argv[optind++]));
1035             //req.sessionDownload[optarg] = ParseTraff(argv[optind++]);
1036             break;
1037         case 502:
1038             SetArrayItem(req.monthUpload, optarg, ParseTraff(argv[optind++]));
1039             //req.monthUpload[optarg] = ParseTraff(argv[optind++]);
1040             break;
1041         case 503:
1042             SetArrayItem(req.monthDownload, optarg, ParseTraff(argv[optind++]));
1043             //req.monthDownload[optarg] = ParseTraff(argv[optind++]);
1044             break;
1045
1046         case 700: //UserData
1047             ParseAnyString(argv[optind++], &str);
1048             SetArrayItem(req.userData, optarg, str);
1049             //req.userData[optarg] = str;
1050             break;
1051
1052         case '?':
1053             missedOptionArg = true;
1054             break;
1055
1056         case ':':
1057             missedOptionArg = true;
1058             break;
1059
1060         default:
1061             printf("?? getopt returned character code 0%o ??\n", c);
1062         }
1063     }
1064
1065 if (optind < argc)
1066     {
1067     printf ("non-option ARGV-elements: ");
1068     while (optind < argc)
1069         printf ("%s ", argv[optind++]);
1070     UsageConf();
1071     exit(PARAMETER_PARSING_ERR_CODE);
1072     }
1073
1074 if (missedOptionArg || !CheckParametersSet(&req))
1075     {
1076     //printf("Parameter needed\n");
1077     UsageConf();
1078     exit(PARAMETER_PARSING_ERR_CODE);
1079     }
1080
1081 const int rLen = 20000;
1082 char rstr[rLen];
1083 memset(rstr, 0, rLen);
1084
1085 CreateRequestSet(&req, rstr);
1086 if (isMessage)
1087     return ProcessSendMessage(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), rstr);
1088
1089 return ProcessSetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), rstr);
1090 }
1091 //-----------------------------------------------------------------------------
1092 int main(int argc, char **argv)
1093 {
1094 if (argc <= 2)
1095     {
1096     UsageConf();
1097     exit(PARAMETER_PARSING_ERR_CODE);
1098     }
1099
1100 if (strcmp(argv[1], "get") == 0)
1101     {
1102     //printf("get\n");
1103     return mainGet(argc - 1, argv + 1);
1104     }
1105 else if (strcmp(argv[1], "set") == 0)
1106     {
1107     //printf("set\n");
1108     if (mainSet(argc - 1, argv + 1) )
1109         return 0;
1110     return -1;
1111     }
1112 else
1113     {
1114     UsageConf();
1115     exit(PARAMETER_PARSING_ERR_CODE);
1116     }
1117 return UNKNOWN_ERR_CODE;
1118 }
1119 //-----------------------------------------------------------------------------
1120