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