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