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