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.
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.
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
18 * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
24 $Date: 2010/03/25 14:37:43 $
27 #include "stg/common.h"
28 #include "stg/netunit.h"
30 #include "common_sg.h"
31 #include "sg_error_codes.h"
50 int ParseReplyGet(void * data, list<string> * ans);
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
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
99 {"prepaid", 0, 0, 'e'}, //prepaid traff
100 {"create", 0, 0, 'n'}, //create
101 {"delete", 0, 0, 'l'}, //delete
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
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
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
162 {"prepaid", 1, 0, 'e'}, //prepaid traff
163 {"create", 1, 0, 'n'}, //create
164 {"delete", 1, 0, 'l'}, //delete
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
176 //-----------------------------------------------------------------------------
177 double ParseCash(const char * c, string * message)
179 //-c 123.45:log message
183 str = new char[strlen(c) + 1];
185 strncpy(str, c, strlen(c));
188 msg = strchr(str, ':');
198 if (strtodouble2(str, cash) != 0)
200 printf("Incorrect cash value %s\n", c);
201 exit(PARAMETER_PARSING_ERR_CODE);
207 //-----------------------------------------------------------------------------
208 double ParseCredit(const char * c)
211 if (strtodouble2(c, credit) != 0)
213 printf("Incorrect credit value %s\n", c);
214 exit(PARAMETER_PARSING_ERR_CODE);
219 //-----------------------------------------------------------------------------
220 double ParsePrepaidTraffic(const char * c)
223 if (strtodouble2(c, credit) != 0)
225 printf("Incorrect prepaid traffic value %s\n", c);
226 exit(PARAMETER_PARSING_ERR_CODE);
231 //-----------------------------------------------------------------------------
232 int64_t ParseTraff(const char * c)
235 if (str2x(c, traff) != 0)
237 printf("Incorrect credit value %s\n", c);
238 exit(PARAMETER_PARSING_ERR_CODE);
243 //-----------------------------------------------------------------------------
244 bool ParseDownPassive(const char * dp)
246 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
248 printf("Incorrect value %s\n", dp);
249 exit(PARAMETER_PARSING_ERR_CODE);
254 //-----------------------------------------------------------------------------
255 string ParseTariff(const char * t, int &chgType)
267 if (strlen(s1) >= TARIFF_NAME_LEN)
269 printf("Tariff name too big %s\n", s1);
270 exit(PARAMETER_PARSING_ERR_CODE);
275 printf("Incorrect tariff value %s\n", t);
276 exit(PARAMETER_PARSING_ERR_CODE);
279 s2 = strtok(NULL, ":");
285 chgType = TARIFF_NOW;
292 if (strcmp(s2, "now") == 0)
293 chgType = TARIFF_NOW;
295 if (strcmp(s2, "delayed") == 0)
296 chgType = TARIFF_DEL;
298 if (strcmp(s2, "recalc") == 0)
299 chgType = TARIFF_REC;
303 printf("Incorrect tariff value %s\n", t);
304 exit(PARAMETER_PARSING_ERR_CODE);
311 //-----------------------------------------------------------------------------
312 time_t ParseCreditExpire(const char * str)
314 struct tm brokenTime;
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;
323 stg_strptime(str, "%Y-%m-%d", &brokenTime);
325 return stg_timegm(&brokenTime);
327 //-----------------------------------------------------------------------------
328 void ParseAnyString(const char * c, string * msg, const char * enc)
332 setlocale(LC_ALL, "");
335 strncpy(charsetF, nl_langinfo(CODESET), 255);
337 const char * charsetT = enc;
341 cd = iconv_open(charsetT, charsetF);
342 if (cd == (iconv_t) -1)
346 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
351 printf("error iconv_open\n");
353 exit(ICONV_ERR_CODE);
356 char * ob = new char[strlen(c) + 1];
357 char * ib = new char[strlen(c) + 1];
364 size_t insize = strlen(c);
365 size_t outsize = strlen(ib);
367 #if defined(CONST_ICONV)
368 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
370 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
372 if (nconv == (size_t) -1)
376 printf("iconv error\n");
377 exit(ICONV_ERR_CODE);
389 //-----------------------------------------------------------------------------
390 void CreateRequestSet(REQUEST * req, char * r)
392 const int strLen = 10024;
394 memset(str, 0, strLen);
398 if (!req->usrMsg.empty())
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());
409 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
416 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
421 strcat(r, "<SetUser>\n");
422 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
424 if (!req->credit.empty())
426 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
430 if (!req->creditExpire.empty())
432 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
436 if (!req->prepaidTraff.empty())
438 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
442 if (!req->cash.empty())
445 Encode12str(msg, req->message.c_str());
446 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
450 if (!req->setCash.empty())
453 Encode12str(msg, req->message.c_str());
454 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
458 if (!req->usrPasswd.empty())
460 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
464 if (!req->down.empty())
466 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
470 if (!req->passive.empty())
472 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
476 if (!req->disableDetailStat.empty())
478 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
482 if (!req->alwaysOnline.empty())
484 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
488 // IP-address of user
489 if (!req->ips.empty())
491 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
495 int uPresent = false;
496 int dPresent = false;
497 for (int i = 0; i < DIR_NUM; i++)
499 if (!req->u[i].empty())
501 if (!uPresent && !dPresent)
503 sprintf(str, "<traff ");
509 ss << req->u[i].const_data();
510 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
513 if (!req->d[i].empty())
515 if (!uPresent && !dPresent)
517 sprintf(str, "<traff ");
523 ss << req->d[i].const_data();
524 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
528 if (uPresent || dPresent)
533 if (!req->tariff.empty())
535 switch (req->chgTariff)
538 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
542 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
546 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
553 if (!req->note.empty())
556 Encode12str(note, req->note.const_data());
557 sprintf(str, "<note value=\"%s\"/>", note.c_str());
561 if (!req->name.empty())
564 Encode12str(name, req->name.const_data());
565 sprintf(str, "<name value=\"%s\"/>", name.c_str());
569 if (!req->address.empty())
572 Encode12str(address, req->address.const_data());
573 sprintf(str, "<address value=\"%s\"/>", address.c_str());
577 if (!req->email.empty())
580 Encode12str(email, req->email.const_data());
581 sprintf(str, "<email value=\"%s\"/>", email.c_str());
585 if (!req->phone.empty())
588 Encode12str(phone, req->phone.const_data());
589 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
593 if (!req->group.empty())
596 Encode12str(group, req->group.const_data());
597 sprintf(str, "<group value=\"%s\"/>", group.c_str());
601 for (int i = 0; i < USERDATA_NUM; i++)
603 if (!req->ud[i].empty())
606 Encode12str(ud, req->ud[i].const_data());
607 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
612 strcat(r, "</SetUser>\n");
614 //-----------------------------------------------------------------------------
615 int CheckParameters(REQUEST * req)
620 int a = !req->admLogin.empty()
621 && !req->admPasswd.empty()
622 && !req->server.empty()
623 && !req->port.empty()
624 && !req->login.empty();
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()
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
646 for (int i = 0; i < DIR_NUM; i++)
648 if (req->u[i].empty())
655 for (int i = 0; i < DIR_NUM; i++)
657 if (req->d[i].empty())
664 for (int i = 0; i < DIR_NUM; i++)
666 if (req->ud[i].empty())
673 return a && (b || u || d || ud);
675 //-----------------------------------------------------------------------------
676 int mainGet(int argc, char **argv)
679 RESETABLE<string> t1;
680 int missedOptionArg = false;
682 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
683 int option_index = -1;
688 int c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
699 req.port = ParseServerPort(optarg);
703 req.admLogin = ParseAdminLogin(optarg);
706 case 'w': //admin password
707 req.admPasswd = ParsePassword(optarg);
710 case 'o': //change user password
715 req.login = ParseUser(optarg);
726 case 'E': //credit expire
727 req.creditExpire = 1;
742 case 'e': //Prepaid Traffic
743 req.prepaidTraff = 1;
770 case 'I': //IP-address of user
774 case 'S': //Detail stat status
775 req.disableDetailStat = " ";
778 case 'O': //Always online status
779 req.alwaysOnline = " ";
818 req.ud[c - 700] = " ";
827 missedOptionArg = true;
831 printf ("?? getopt returned character code 0%o ??\n", c);
837 printf ("non-option ARGV-elements: ");
838 while (optind < argc)
839 printf ("%s ", argv[optind++]);
841 exit(PARAMETER_PARSING_ERR_CODE);
844 if (missedOptionArg || !CheckParameters(&req))
847 exit(PARAMETER_PARSING_ERR_CODE);
851 return ProcessAuthBy(req.server.const_data(), req.port.const_data(), req.admLogin.const_data(), req.admPasswd.const_data(), req.login.const_data(), &req);
853 return ProcessGetUser(req.server.const_data(), req.port.const_data(), req.admLogin.const_data(), req.admPasswd.const_data(), req.login.const_data(), &req);
855 //-----------------------------------------------------------------------------
856 int mainSet(int argc, char **argv)
860 bool isMessage = false;
863 RESETABLE<string> t1;
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:";
867 int missedOptionArg = false;
871 int option_index = -1;
873 int c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
885 req.port = ParseServerPort(optarg);
889 req.admLogin = ParseAdminLogin(optarg);
892 case 'w': //admin password
893 req.admPasswd = ParsePassword(optarg);
896 case 'o': //change user password
897 req.usrPasswd = ParsePassword(optarg);
901 req.login = ParseUser(optarg);
905 req.cash = ParseCash(optarg, &req.message);
909 req.setCash = ParseCash(optarg, &req.message);
913 req.credit = ParseCredit(optarg);
916 case 'E': //credit expire
917 req.creditExpire = ParseCreditExpire(optarg);
921 req.down = ParseDownPassive(optarg);
925 req.passive = ParseDownPassive(optarg);
929 req.tariff = ParseTariff(optarg, req.chgTariff);
933 ParseAnyString(optarg, &str);
938 case 'e': //Prepaid Traffic
939 req.prepaidTraff = ParsePrepaidTraffic(optarg);
942 case 'n': //Create User
943 req.createUser = true;
946 case 'l': //Delete User
947 req.deleteUser = true;
951 ParseAnyString(optarg, &str, "koi8-ru");
956 ParseAnyString(optarg, &str, "koi8-ru");
961 ParseAnyString(optarg, &str, "koi8-ru");
966 ParseAnyString(optarg, &str, "koi8-ru");
971 ParseAnyString(optarg, &str, "koi8-ru");
976 ParseAnyString(optarg, &str, "koi8-ru");
980 case 'I': //IP-address of user
981 ParseAnyString(optarg, &str);
986 req.disableDetailStat = ParseDownPassive(optarg);
990 req.alwaysOnline = ParseDownPassive(optarg);
1003 req.u[c - 500] = ParseTraff(optarg);
1016 req.d[c - 600] = ParseTraff(optarg);
1019 case 700: //UserData
1029 ParseAnyString(optarg, &str, "koi8-ru");
1030 req.ud[c - 700] = str;
1034 missedOptionArg = true;
1038 missedOptionArg = true;
1042 printf("?? getopt returned character code 0%o ??\n", c);
1048 printf ("non-option ARGV-elements: ");
1049 while (optind < argc)
1050 printf ("%s ", argv[optind++]);
1052 exit(PARAMETER_PARSING_ERR_CODE);
1055 if (missedOptionArg || !CheckParameters(&req))
1058 exit(PARAMETER_PARSING_ERR_CODE);
1061 const int rLen = 20000;
1063 memset(rstr, 0, rLen);
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);
1068 //-----------------------------------------------------------------------------
1069 int main(int argc, char **argv)
1074 exit(PARAMETER_PARSING_ERR_CODE);
1077 if (strcmp(argv[1], "get") == 0)
1079 return mainGet(argc - 1, argv + 1);
1081 else if (strcmp(argv[1], "set") == 0)
1084 return mainSet(argc - 1, argv + 1);
1089 exit(PARAMETER_PARSING_ERR_CODE);
1091 return UNKNOWN_ERR_CODE;
1093 //-----------------------------------------------------------------------------