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 {"session-upload", 1, 0, 500}, //SU0
70 {"session-download", 1, 0, 501}, //SD0
71 {"month-upload", 1, 0, 502}, //MU0
72 {"month-download", 1, 0, 503}, //MD0
74 {"user-data", 1, 0, 700}, //UserData0
76 {"prepaid", 0, 0, 'e'}, //prepaid traff
77 {"create", 0, 0, 'n'}, //create
78 {"delete", 0, 0, 'l'}, //delete
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
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
112 {"user-data", 1, 0, 700}, //UserData
114 {"prepaid", 1, 0, 'e'}, //prepaid traff
115 {"create", 1, 0, 'n'}, //create
116 {"delete", 1, 0, 'l'}, //delete
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
128 //-----------------------------------------------------------------------------
129 double ParseCash(const char * c, string * message)
131 //-c 123.45:log message
135 str = new char[strlen(c) + 1];
137 strncpy(str, c, strlen(c));
140 msg = strchr(str, ':');
150 if (strtodouble2(str, cash) != 0)
152 printf("Incorrect cash value %s\n", c);
153 exit(PARAMETER_PARSING_ERR_CODE);
159 //-----------------------------------------------------------------------------
160 double ParseCredit(const char * c)
163 if (strtodouble2(c, credit) != 0)
165 printf("Incorrect credit value %s\n", c);
166 exit(PARAMETER_PARSING_ERR_CODE);
171 //-----------------------------------------------------------------------------
172 double ParsePrepaidTraffic(const char * c)
175 if (strtodouble2(c, credit) != 0)
177 printf("Incorrect prepaid traffic value %s\n", c);
178 exit(PARAMETER_PARSING_ERR_CODE);
183 //-----------------------------------------------------------------------------
184 int64_t ParseTraff(const char * c)
187 if (str2x(c, traff) != 0)
189 printf("Incorrect credit value %s\n", c);
190 exit(PARAMETER_PARSING_ERR_CODE);
195 //-----------------------------------------------------------------------------
196 bool ParseDownPassive(const char * dp)
198 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
200 printf("Incorrect value %s\n", dp);
201 exit(PARAMETER_PARSING_ERR_CODE);
206 //-----------------------------------------------------------------------------
207 string ParseTariff(const char * t, int &chgType)
219 if (strlen(s1) >= TARIFF_NAME_LEN)
221 printf("Tariff name too big %s\n", s1);
222 exit(PARAMETER_PARSING_ERR_CODE);
229 printf("Incorrect tariff value %s\n", t);
230 exit(PARAMETER_PARSING_ERR_CODE);
233 s2 = strtok(NULL, ":");
239 chgType = TARIFF_NOW;
246 if (strcmp(s2, "now") == 0)
247 chgType = TARIFF_NOW;
249 if (strcmp(s2, "delayed") == 0)
250 chgType = TARIFF_DEL;
252 if (strcmp(s2, "recalc") == 0)
253 chgType = TARIFF_REC;
257 printf("Incorrect tariff value %s\n", t);
258 exit(PARAMETER_PARSING_ERR_CODE);
265 //-----------------------------------------------------------------------------
266 time_t ParseCreditExpire(const char * str)
268 struct tm brokenTime;
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;
277 stg_strptime(str, "%Y-%m-%d", &brokenTime);
279 return stg_timegm(&brokenTime);
281 //-----------------------------------------------------------------------------
282 void ParseAnyString(const char * c, string * msg, const char * enc)
285 char * ob = new char[strlen(c) + 1];
286 char * ib = new char[strlen(c) + 1];
293 setlocale(LC_ALL, "");
296 strncpy(charsetF, nl_langinfo(CODESET), 255);
298 const char * charsetT = enc;
302 size_t insize = strlen(ib);
303 size_t outsize = strlen(ib);
307 cd = iconv_open(charsetT, charsetF);
308 if (cd == (iconv_t) -1)
312 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
317 printf("error iconv_open\n");
319 exit(ICONV_ERR_CODE);
322 #if defined(FREE_BSD) || defined(FREE_BSD5)
323 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
325 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
327 //printf("nconv=%d outsize=%d\n", nconv, outsize);
328 if (nconv == (size_t) -1)
332 printf("iconv error\n");
333 exit(ICONV_ERR_CODE);
345 //-----------------------------------------------------------------------------
346 void CreateRequestSet(REQUEST * req, char * r)
348 const int strLen = 10024;
350 memset(str, 0, strLen);
354 if (!req->usrMsg.res_empty())
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);
366 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
374 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
380 strcat(r, "<SetUser>\n");
381 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
383 if (!req->credit.res_empty())
385 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
389 if (!req->creditExpire.res_empty())
391 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
395 if (!req->prepaidTraff.res_empty())
397 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
401 if (!req->cash.res_empty())
404 Encode12str(msg, req->message);
405 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
409 if (!req->setCash.res_empty())
412 Encode12str(msg, req->message);
413 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
417 if (!req->usrPasswd.res_empty())
419 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
423 if (!req->down.res_empty())
425 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
429 if (!req->passive.res_empty())
431 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
435 if (!req->disableDetailStat.res_empty())
437 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
441 if (!req->alwaysOnline.res_empty())
443 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
447 // IP-address of user
448 if (!req->ips.res_empty())
450 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
454 int uPresent = false;
455 int dPresent = false;
456 for (int i = 0; i < DIR_NUM; i++)
458 if (!req->u[i].res_empty())
460 if (!uPresent && !dPresent)
462 sprintf(str, "<traff ");
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());
473 if (!req->d[i].res_empty())
475 if (!uPresent && !dPresent)
477 sprintf(str, "<traff ");
483 ss << req->d[i].const_data();
484 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
488 if (uPresent || dPresent)
495 if (!req->tariff.res_empty())
497 switch (req->chgTariff)
500 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
504 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
508 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
515 if (!req->note.res_empty())
518 Encode12str(note, req->note);
519 sprintf(str, "<note value=\"%s\"/>", note.c_str());
523 if (!req->name.res_empty())
526 Encode12str(name, req->name);
527 sprintf(str, "<name value=\"%s\"/>", name.c_str());
531 if (!req->address.res_empty())
534 Encode12str(address, req->address);
535 sprintf(str, "<address value=\"%s\"/>", address.c_str());
539 if (!req->email.res_empty())
542 Encode12str(email, req->email);
543 sprintf(str, "<email value=\"%s\"/>", email.c_str());
547 if (!req->phone.res_empty())
550 Encode12str(phone, req->phone);
551 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
555 if (!req->group.res_empty())
558 Encode12str(group, req->group);
559 sprintf(str, "<group value=\"%s\"/>", group.c_str());
563 for (int i = 0; i < USERDATA_NUM; i++)
565 if (!req->ud[i].res_empty())
568 Encode12str(ud, req->ud[i]);
569 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
574 strcat(r, "</SetUser>\n");
576 //-----------------------------------------------------------------------------
577 int CheckParameters(REQUEST * req)
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();
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()
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
608 for (int i = 0; i < DIR_NUM; i++)
610 if (req->u[i].res_empty())
617 for (int i = 0; i < DIR_NUM; i++)
619 if (req->d[i].res_empty())
626 for (int i = 0; i < DIR_NUM; i++)
628 if (req->ud[i].res_empty())
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);
639 //-----------------------------------------------------------------------------
640 int CheckParametersGet(REQUEST * req)
642 return CheckParameters(req);
644 //-----------------------------------------------------------------------------
645 int CheckParametersSet(REQUEST * req)
647 return CheckParameters(req);
649 //-----------------------------------------------------------------------------
650 int mainGet(int argc, char **argv)
654 RESETABLE<string> t1;
655 int missedOptionArg = false;
657 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
658 int option_index = -1;
663 c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
674 req.port = ParseServerPort(optarg);
679 req.admLogin = ParseAdminLogin(optarg);
682 case 'w': //admin password
683 req.admPasswd = ParsePassword(optarg);
686 case 'o': //change user password
691 req.login = ParseUser(optarg);
702 case 'E': //credit expire
703 req.creditExpire = 1;
718 case 'e': //Prepaid Traffic
719 req.prepaidTraff = 1;
746 case 'I': //IP-address of user
750 case 'S': //Detail stat status
751 req.disableDetailStat = " ";
754 case 'O': //Always online status
755 req.alwaysOnline = " ";
759 //printf("U%d\n", c - 500);
760 req.sessionUpload[optarg] = 1;
763 //printf("U%d\n", c - 500);
764 req.sessionDownload[optarg] = 1;
767 //printf("U%d\n", c - 500);
768 req.monthUpload[optarg] = 1;
771 //printf("U%d\n", c - 500);
772 req.monthDownload[optarg] = 1;
776 //printf("UD%d\n", c - 700);
777 req.ud[optarg] = " ";
786 //printf ("Unknown option \n");
787 missedOptionArg = true;
791 printf ("?? getopt returned character code 0%o ??\n", c);
797 printf ("non-option ARGV-elements: ");
798 while (optind < argc)
799 printf ("%s ", argv[optind++]);
801 exit(PARAMETER_PARSING_ERR_CODE);
804 if (missedOptionArg || !CheckParametersGet(&req))
806 //printf("Parameter needed\n");
808 exit(PARAMETER_PARSING_ERR_CODE);
812 return ProcessAuthBy(req.server, req.port, req.admLogin, req.admPasswd, req.login, req);
814 return ProcessGetUser(req.server, req.port, req.admLogin, req.admPasswd, req.login, req);
816 //-----------------------------------------------------------------------------
817 int mainSet(int argc, char **argv)
822 bool isMessage = false;
825 RESETABLE<string> t1;
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:";
829 int missedOptionArg = false;
833 int option_index = -1;
835 c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
847 req.port = ParseServerPort(optarg);
852 req.admLogin = ParseAdminLogin(optarg);
855 case 'w': //admin password
856 req.admPasswd = ParsePassword(optarg);
859 case 'o': //change user password
860 req.usrPasswd = ParsePassword(optarg);
864 req.login = ParseUser(optarg);
868 req.cash = ParseCash(optarg, &req.message);
872 req.setCash = ParseCash(optarg, &req.message);
876 req.credit = ParseCredit(optarg);
879 case 'E': //credit expire
880 req.creditExpire = ParseCreditExpire(optarg);
884 req.down = ParseDownPassive(optarg);
888 req.passive = ParseDownPassive(optarg);
892 req.tariff = ParseTariff(optarg, req.chgTariff);
896 ParseAnyString(optarg, &str);
901 case 'e': //Prepaid Traffic
902 req.prepaidTraff = ParsePrepaidTraffic(optarg);
905 case 'n': //Create User
906 req.createUser = true;
909 case 'l': //Delete User
910 req.deleteUser = true;
914 ParseAnyString(optarg, &str, "koi8-ru");
919 ParseAnyString(optarg, &str, "koi8-ru");
924 ParseAnyString(optarg, &str, "koi8-ru");
929 ParseAnyString(optarg, &str, "koi8-ru");
931 //printf("EMAIL=%s\n", optarg);
935 ParseAnyString(optarg, &str);
940 ParseAnyString(optarg, &str, "koi8-ru");
944 case 'I': //IP-address of user
945 ParseAnyString(optarg, &str);
950 req.disableDetailStat = ParseDownPassive(optarg);
954 req.alwaysOnline = ParseDownPassive(optarg);
958 //printf("U%d\n", c - 500);
959 req.sesionUpload[optarg] = ParseTraff(argv[optind++]);
962 //printf("U%d\n", c - 500);
963 req.sessionDownload[optarg] = ParseTraff(argv[optind++]);
966 //printf("U%d\n", c - 500);
967 req.monthUpload[optarg] = ParseTraff(argv[optind++]);
970 //printf("U%d\n", c - 500);
971 req.monthDownload[optarg] = ParseTraff(argv[optind++]);
975 ParseAnyString(argv[optind++], &str);
976 //printf("UD%d\n", c - 700);
977 req.userData[optarg] = str;
981 //printf("Missing option argument\n");
982 missedOptionArg = true;
986 //printf("Missing option argument\n");
987 missedOptionArg = true;
991 printf("?? getopt returned character code 0%o ??\n", c);
997 printf ("non-option ARGV-elements: ");
998 while (optind < argc)
999 printf ("%s ", argv[optind++]);
1001 exit(PARAMETER_PARSING_ERR_CODE);
1004 if (missedOptionArg || !CheckParametersSet(&req))
1006 //printf("Parameter needed\n");
1008 exit(PARAMETER_PARSING_ERR_CODE);
1011 const int rLen = 20000;
1013 memset(rstr, 0, rLen);
1015 CreateRequestSet(&req, rstr);
1016 return ProcessSetUser(req.server, req.port, req.admLogin, req.admPasswd, rstr, NULL, isMessage);
1018 //-----------------------------------------------------------------------------
1019 int main(int argc, char **argv)
1024 exit(PARAMETER_PARSING_ERR_CODE);
1027 if (strcmp(argv[1], "get") == 0)
1030 return mainGet(argc - 1, argv + 1);
1032 else if (strcmp(argv[1], "set") == 0)
1035 return mainSet(argc - 1, argv + 1);
1040 exit(PARAMETER_PARSING_ERR_CODE);
1042 return UNKNOWN_ERR_CODE;
1044 //-----------------------------------------------------------------------------