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 $
40 #include "stg/common.h"
41 #include "stg/netunit.h"
43 #include "common_sg.h"
44 #include "sg_error_codes.h"
50 int ParseReplyGet(void * data, list<string> * ans);
51 //int ParseReplySet(void * data, list<string> * ans);
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 {"u0", 0, 0, 500}, //U0
70 {"u1", 0, 0, 501}, //U1
71 {"u2", 0, 0, 502}, //U2
72 {"u3", 0, 0, 503}, //U3
73 {"u4", 0, 0, 504}, //U4
74 {"u5", 0, 0, 505}, //U5
75 {"u6", 0, 0, 506}, //U6
76 {"u7", 0, 0, 507}, //U7
77 {"u8", 0, 0, 508}, //U8
78 {"u9", 0, 0, 509}, //U9
79 {"d0", 0, 0, 600}, //D0
80 {"d1", 0, 0, 601}, //D1
81 {"d2", 0, 0, 602}, //D2
82 {"d3", 0, 0, 603}, //D3
83 {"d4", 0, 0, 604}, //D4
84 {"d5", 0, 0, 605}, //D5
85 {"d6", 0, 0, 606}, //D6
86 {"d7", 0, 0, 607}, //D7
87 {"d8", 0, 0, 608}, //D8
88 {"d9", 0, 0, 609}, //D9
90 {"ud0", 0, 0, 700}, //UserData0
91 {"ud1", 0, 0, 701}, //UserData1
92 {"ud2", 0, 0, 702}, //UserData2
93 {"ud3", 0, 0, 703}, //UserData3
94 {"ud4", 0, 0, 704}, //UserData4
95 {"ud5", 0, 0, 705}, //UserData5
96 {"ud6", 0, 0, 706}, //UserData6
97 {"ud7", 0, 0, 707}, //UserData7
98 {"ud8", 0, 0, 708}, //UserData8
99 {"ud9", 0, 0, 709}, //UserData9
101 {"prepaid", 0, 0, 'e'}, //prepaid traff
102 {"create", 0, 0, 'n'}, //create
103 {"delete", 0, 0, 'l'}, //delete
105 {"note", 0, 0, 'N'}, //Note
106 {"name", 0, 0, 'A'}, //nAme
107 {"address", 0, 0, 'D'}, //aDdress
108 {"email", 0, 0, 'L'}, //emaiL
109 {"phone", 0, 0, 'P'}, //phone
110 {"group", 0, 0, 'G'}, //Group
111 {"ip", 0, 0, 'I'}, //IP-address of user
112 {"authorized-by",0, 0, 800}, //always online
116 struct option long_options_set[] = {
117 {"server", 1, 0, 's'}, //Server
118 {"port", 1, 0, 'p'}, //Port
119 {"admin", 1, 0, 'a'}, //Admin
120 {"admin_pass", 1, 0, 'w'}, //passWord
121 {"user", 1, 0, 'u'}, //User
122 {"addcash", 1, 0, 'c'}, //Add Cash
123 {"setcash", 1, 0, 'v'}, //Set Cash
124 {"credit", 1, 0, 'r'}, //cRedit
125 {"tariff", 1, 0, 't'}, //Tariff
126 {"message", 1, 0, 'm'}, //message
127 {"password", 1, 0, 'o'}, //password
128 {"down", 1, 0, 'd'}, //down
129 {"passive", 1, 0, 'i'}, //passive
130 {"disable-stat",1, 0, 'S'}, //disable detail stat
131 {"always-online",1, 0, 'O'}, //always online
132 {"u0", 1, 0, 500}, //U0
133 {"u1", 1, 0, 501}, //U1
134 {"u2", 1, 0, 502}, //U2
135 {"u3", 1, 0, 503}, //U3
136 {"u4", 1, 0, 504}, //U4
137 {"u5", 1, 0, 505}, //U5
138 {"u6", 1, 0, 506}, //U6
139 {"u7", 1, 0, 507}, //U7
140 {"u8", 1, 0, 508}, //U8
141 {"u9", 1, 0, 509}, //U9
142 {"d0", 1, 0, 600}, //D0
143 {"d1", 1, 0, 601}, //D1
144 {"d2", 1, 0, 602}, //D2
145 {"d3", 1, 0, 603}, //D3
146 {"d4", 1, 0, 604}, //D4
147 {"d5", 1, 0, 605}, //D5
148 {"d6", 1, 0, 606}, //D6
149 {"d7", 1, 0, 607}, //D7
150 {"d8", 1, 0, 608}, //D8
151 {"d9", 1, 0, 609}, //D9
153 {"ud0", 1, 0, 700}, //UserData
154 {"ud1", 1, 0, 701}, //UserData1
155 {"ud2", 1, 0, 702}, //UserData2
156 {"ud3", 1, 0, 703}, //UserData3
157 {"ud4", 1, 0, 704}, //UserData4
158 {"ud5", 1, 0, 705}, //UserData5
159 {"ud6", 1, 0, 706}, //UserData6
160 {"ud7", 1, 0, 707}, //UserData7
161 {"ud8", 1, 0, 708}, //UserData8
162 {"ud9", 1, 0, 709}, //UserData9
164 {"prepaid", 1, 0, 'e'}, //prepaid traff
165 {"create", 1, 0, 'n'}, //create
166 {"delete", 1, 0, 'l'}, //delete
168 {"note", 1, 0, 'N'}, //Note
169 {"name", 1, 0, 'A'}, //nAme
170 {"address", 1, 0, 'D'}, //aDdress
171 {"email", 1, 0, 'L'}, //emaiL
172 {"phone", 1, 0, 'P'}, //phone
173 {"group", 1, 0, 'G'}, //Group
174 {"ip", 0, 0, 'I'}, //IP-address of user
178 //-----------------------------------------------------------------------------
179 double ParseCash(const char * c, string * message)
181 //-c 123.45:log message
185 str = new char[strlen(c) + 1];
187 strncpy(str, c, strlen(c));
190 msg = strchr(str, ':');
200 if (strtodouble2(str, cash) != 0)
202 printf("Incorrect cash value %s\n", c);
203 exit(PARAMETER_PARSING_ERR_CODE);
209 //-----------------------------------------------------------------------------
210 double ParseCredit(const char * c)
213 if (strtodouble2(c, credit) != 0)
215 printf("Incorrect credit value %s\n", c);
216 exit(PARAMETER_PARSING_ERR_CODE);
221 //-----------------------------------------------------------------------------
222 double ParsePrepaidTraffic(const char * c)
225 if (strtodouble2(c, credit) != 0)
227 printf("Incorrect prepaid traffic value %s\n", c);
228 exit(PARAMETER_PARSING_ERR_CODE);
233 //-----------------------------------------------------------------------------
234 int64_t ParseTraff(const char * c)
237 if (str2x(c, traff) != 0)
239 printf("Incorrect credit value %s\n", c);
240 exit(PARAMETER_PARSING_ERR_CODE);
245 //-----------------------------------------------------------------------------
246 bool ParseDownPassive(const char * dp)
248 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
250 printf("Incorrect value %s\n", dp);
251 exit(PARAMETER_PARSING_ERR_CODE);
256 //-----------------------------------------------------------------------------
257 string ParseTariff(const char * t, int &chgType)
269 if (strlen(s1) >= TARIFF_NAME_LEN)
271 printf("Tariff name too big %s\n", s1);
272 exit(PARAMETER_PARSING_ERR_CODE);
279 printf("Incorrect tariff value %s\n", t);
280 exit(PARAMETER_PARSING_ERR_CODE);
283 s2 = strtok(NULL, ":");
289 chgType = TARIFF_NOW;
296 if (strcmp(s2, "now") == 0)
297 chgType = TARIFF_NOW;
299 if (strcmp(s2, "delayed") == 0)
300 chgType = TARIFF_DEL;
302 if (strcmp(s2, "recalc") == 0)
303 chgType = TARIFF_REC;
307 printf("Incorrect tariff value %s\n", t);
308 exit(PARAMETER_PARSING_ERR_CODE);
315 //-----------------------------------------------------------------------------
316 time_t ParseCreditExpire(const char * str)
318 struct tm brokenTime;
320 brokenTime.tm_wday = 0;
321 brokenTime.tm_yday = 0;
322 brokenTime.tm_isdst = 0;
323 brokenTime.tm_hour = 0;
324 brokenTime.tm_min = 0;
325 brokenTime.tm_sec = 0;
327 stg_strptime(str, "%Y-%m-%d", &brokenTime);
329 return stg_timegm(&brokenTime);
331 //-----------------------------------------------------------------------------
332 void ParseAnyString(const char * c, string * msg, const char * enc)
336 setlocale(LC_ALL, "");
339 strncpy(charsetF, nl_langinfo(CODESET), 255);
341 const char * charsetT = enc;
345 cd = iconv_open(charsetT, charsetF);
346 if (cd == (iconv_t) -1)
350 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
355 printf("error iconv_open\n");
357 exit(ICONV_ERR_CODE);
360 char * ob = new char[strlen(c) + 1];
361 char * ib = new char[strlen(c) + 1];
368 size_t insize = strlen(c);
369 size_t outsize = strlen(ib);
371 #if defined(CONST_ICONV)
372 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
374 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
376 //printf("nconv=%d outsize=%d\n", nconv, outsize);
377 if (nconv == (size_t) -1)
381 printf("iconv error\n");
382 exit(ICONV_ERR_CODE);
394 //-----------------------------------------------------------------------------
395 void CreateRequestSet(REQUEST * req, char * r)
397 const int strLen = 10024;
399 memset(str, 0, strLen);
403 if (!req->usrMsg.empty())
406 Encode12str(msg, req->usrMsg.const_data());
407 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());
408 //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
415 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
423 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
429 strcat(r, "<SetUser>\n");
430 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
432 if (!req->credit.empty())
434 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
438 if (!req->creditExpire.empty())
440 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
444 if (!req->prepaidTraff.empty())
446 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
450 if (!req->cash.empty())
453 Encode12str(msg, req->message.c_str());
454 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
458 if (!req->setCash.empty())
461 Encode12str(msg, req->message.c_str());
462 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
466 if (!req->usrPasswd.empty())
468 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
472 if (!req->down.empty())
474 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
478 if (!req->passive.empty())
480 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
484 if (!req->disableDetailStat.empty())
486 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
490 if (!req->alwaysOnline.empty())
492 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
496 // IP-address of user
497 if (!req->ips.empty())
499 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
503 int uPresent = false;
504 int dPresent = false;
505 for (int i = 0; i < DIR_NUM; i++)
507 if (!req->u[i].empty())
509 if (!uPresent && !dPresent)
511 sprintf(str, "<traff ");
517 ss << req->u[i].const_data();
518 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
519 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
522 if (!req->d[i].empty())
524 if (!uPresent && !dPresent)
526 sprintf(str, "<traff ");
532 ss << req->d[i].const_data();
533 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
537 if (uPresent || dPresent)
544 if (!req->tariff.empty())
546 switch (req->chgTariff)
549 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
553 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
557 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
564 if (!req->note.empty())
567 Encode12str(note, req->note.const_data());
568 sprintf(str, "<note value=\"%s\"/>", note.c_str());
572 if (!req->name.empty())
575 Encode12str(name, req->name.const_data());
576 sprintf(str, "<name value=\"%s\"/>", name.c_str());
580 if (!req->address.empty())
583 Encode12str(address, req->address.const_data());
584 sprintf(str, "<address value=\"%s\"/>", address.c_str());
588 if (!req->email.empty())
591 Encode12str(email, req->email.const_data());
592 sprintf(str, "<email value=\"%s\"/>", email.c_str());
596 if (!req->phone.empty())
599 Encode12str(phone, req->phone.const_data());
600 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
604 if (!req->group.empty())
607 Encode12str(group, req->group.const_data());
608 sprintf(str, "<group value=\"%s\"/>", group.c_str());
612 for (int i = 0; i < USERDATA_NUM; i++)
614 if (!req->ud[i].empty())
617 Encode12str(ud, req->ud[i].const_data());
618 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
623 strcat(r, "</SetUser>\n");
625 //-----------------------------------------------------------------------------
626 int CheckParameters(REQUEST * req)
631 int a = !req->admLogin.empty()
632 && !req->admPasswd.empty()
633 && !req->server.empty()
634 && !req->port.empty()
635 && !req->login.empty();
637 int b = !req->cash.empty()
638 || !req->setCash.empty()
639 || !req->credit.empty()
640 || !req->prepaidTraff.empty()
641 || !req->tariff.empty()
642 || !req->usrMsg.empty()
643 || !req->usrPasswd.empty()
645 || !req->note.empty()
646 || !req->name.empty()
647 || !req->address.empty()
648 || !req->email.empty()
649 || !req->phone.empty()
650 || !req->group.empty()
651 || !req->ips.empty() // IP-address of user
657 for (int i = 0; i < DIR_NUM; i++)
659 if (req->u[i].empty())
666 for (int i = 0; i < DIR_NUM; i++)
668 if (req->d[i].empty())
675 for (int i = 0; i < DIR_NUM; i++)
677 if (req->ud[i].empty())
685 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
686 return a && (b || u || d || ud);
688 //-----------------------------------------------------------------------------
689 int CheckParametersGet(REQUEST * req)
691 return CheckParameters(req);
693 //-----------------------------------------------------------------------------
694 int CheckParametersSet(REQUEST * req)
696 return CheckParameters(req);
698 //-----------------------------------------------------------------------------
699 int mainGet(int argc, char **argv)
703 RESETABLE<string> t1;
704 int missedOptionArg = false;
706 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
707 int option_index = -1;
712 c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
723 req.port = ParseServerPort(optarg);
728 req.admLogin = ParseAdminLogin(optarg);
731 case 'w': //admin password
732 req.admPasswd = ParsePassword(optarg);
735 case 'o': //change user password
740 req.login = ParseUser(optarg);
751 case 'E': //credit expire
752 req.creditExpire = 1;
767 case 'e': //Prepaid Traffic
768 req.prepaidTraff = 1;
795 case 'I': //IP-address of user
799 case 'S': //Detail stat status
800 req.disableDetailStat = " ";
803 case 'O': //Always online status
804 req.alwaysOnline = " ";
817 //printf("U%d\n", c - 500);
831 //printf("D%d\n", c - 600);
845 //printf("UD%d\n", c - 700);
846 req.ud[c - 700] = " ";
855 //printf ("Unknown option \n");
856 missedOptionArg = true;
860 printf ("?? getopt returned character code 0%o ??\n", c);
866 printf ("non-option ARGV-elements: ");
867 while (optind < argc)
868 printf ("%s ", argv[optind++]);
870 exit(PARAMETER_PARSING_ERR_CODE);
873 if (missedOptionArg || !CheckParametersGet(&req))
875 //printf("Parameter needed\n");
877 exit(PARAMETER_PARSING_ERR_CODE);
881 return ProcessAuthBy(req.server.const_data(), req.port.const_data(), req.admLogin.const_data(), req.admPasswd.const_data(), req.login.const_data(), &req);
883 return ProcessGetUser(req.server.const_data(), req.port.const_data(), req.admLogin.const_data(), req.admPasswd.const_data(), req.login.const_data(), &req);
885 //-----------------------------------------------------------------------------
886 int mainSet(int argc, char **argv)
891 bool isMessage = false;
894 RESETABLE<string> t1;
896 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:";
898 int missedOptionArg = false;
902 int option_index = -1;
904 c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
916 req.port = ParseServerPort(optarg);
921 req.admLogin = ParseAdminLogin(optarg);
924 case 'w': //admin password
925 req.admPasswd = ParsePassword(optarg);
928 case 'o': //change user password
929 req.usrPasswd = ParsePassword(optarg);
933 req.login = ParseUser(optarg);
937 req.cash = ParseCash(optarg, &req.message);
941 req.setCash = ParseCash(optarg, &req.message);
945 req.credit = ParseCredit(optarg);
948 case 'E': //credit expire
949 req.creditExpire = ParseCreditExpire(optarg);
953 req.down = ParseDownPassive(optarg);
957 req.passive = ParseDownPassive(optarg);
961 req.tariff = ParseTariff(optarg, req.chgTariff);
965 ParseAnyString(optarg, &str);
970 case 'e': //Prepaid Traffic
971 req.prepaidTraff = ParsePrepaidTraffic(optarg);
974 case 'n': //Create User
975 req.createUser = true;
978 case 'l': //Delete User
979 req.deleteUser = true;
983 ParseAnyString(optarg, &str, "koi8-ru");
988 ParseAnyString(optarg, &str, "koi8-ru");
993 ParseAnyString(optarg, &str, "koi8-ru");
998 ParseAnyString(optarg, &str, "koi8-ru");
1000 //printf("EMAIL=%s\n", optarg);
1004 ParseAnyString(optarg, &str, "koi8-ru");
1009 ParseAnyString(optarg, &str, "koi8-ru");
1013 case 'I': //IP-address of user
1014 ParseAnyString(optarg, &str);
1019 req.disableDetailStat = ParseDownPassive(optarg);
1023 req.alwaysOnline = ParseDownPassive(optarg);
1036 //printf("U%d\n", c - 500);
1037 req.u[c - 500] = ParseTraff(optarg);
1050 //printf("D%d\n", c - 600);
1051 req.d[c - 600] = ParseTraff(optarg);
1054 case 700: //UserData
1064 ParseAnyString(optarg, &str, "koi8-ru");
1065 //printf("UD%d\n", c - 700);
1066 req.ud[c - 700] = str;
1070 //printf("Missing option argument\n");
1071 missedOptionArg = true;
1075 //printf("Missing option argument\n");
1076 missedOptionArg = true;
1080 printf("?? getopt returned character code 0%o ??\n", c);
1086 printf ("non-option ARGV-elements: ");
1087 while (optind < argc)
1088 printf ("%s ", argv[optind++]);
1090 exit(PARAMETER_PARSING_ERR_CODE);
1093 if (missedOptionArg || !CheckParametersSet(&req))
1095 //printf("Parameter needed\n");
1097 exit(PARAMETER_PARSING_ERR_CODE);
1100 const int rLen = 20000;
1102 memset(rstr, 0, rLen);
1104 CreateRequestSet(&req, rstr);
1105 return ProcessSetUser(req.server.const_data(), req.port.const_data(), req.admLogin.const_data(), req.admPasswd.const_data(), rstr, NULL, isMessage);
1107 //-----------------------------------------------------------------------------
1108 int main(int argc, char **argv)
1113 exit(PARAMETER_PARSING_ERR_CODE);
1116 if (strcmp(argv[1], "get") == 0)
1119 return mainGet(argc - 1, argv + 1);
1121 else if (strcmp(argv[1], "set") == 0)
1124 return mainSet(argc - 1, argv + 1);
1129 exit(PARAMETER_PARSING_ERR_CODE);
1131 return UNKNOWN_ERR_CODE;
1133 //-----------------------------------------------------------------------------