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