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 $
39 #include "stg/common.h"
41 #include "common_sg.h"
42 #include "sg_error_codes.h"
51 struct ARRAY_TYPE<T[]>
56 template <typename T, size_t N>
57 struct ARRAY_TYPE<T[N]>
63 bool SetArrayItem(T & array, const char * index, const typename ARRAY_TYPE<T>::type & value)
66 if (str2x(index, pos))
72 } // namespace anonymous
76 struct option long_options_get[] = {
77 {"server", 1, 0, 's'}, //Server
78 {"port", 1, 0, 'p'}, //Port
79 {"admin", 1, 0, 'a'}, //Admin
80 {"admin_pass", 1, 0, 'w'}, //passWord
81 {"user", 1, 0, 'u'}, //User
82 {"addcash", 0, 0, 'c'}, //Add Cash
83 //{"setcash", 0, 0, 'v'}, //Set Cash
84 {"credit", 0, 0, 'r'}, //cRedit
85 {"tariff", 0, 0, 't'}, //Tariff
86 {"message", 0, 0, 'm'}, //message
87 {"password", 0, 0, 'o'}, //password
88 {"down", 0, 0, 'd'}, //down
89 {"passive", 0, 0, 'i'}, //passive
90 {"disable-stat",0, 0, 'S'}, //disable detail stat
91 {"always-online",0, 0, 'O'}, //always online
92 {"session-upload", 1, 0, 500}, //SU0
93 {"session-download", 1, 0, 501}, //SD0
94 {"month-upload", 1, 0, 502}, //MU0
95 {"month-download", 1, 0, 503}, //MD0
97 {"user-data", 1, 0, 700}, //UserData0
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 {"session-upload", 1, 0, 500}, //U0
131 {"session-download", 1, 0, 501}, //U1
132 {"month-upload", 1, 0, 502}, //U2
133 {"month-download", 1, 0, 503}, //U3
135 {"user-data", 1, 0, 700}, //UserData
137 {"prepaid", 1, 0, 'e'}, //prepaid traff
138 {"create", 1, 0, 'n'}, //create
139 {"delete", 1, 0, 'l'}, //delete
141 {"note", 1, 0, 'N'}, //Note
142 {"name", 1, 0, 'A'}, //nAme
143 {"address", 1, 0, 'D'}, //aDdress
144 {"email", 1, 0, 'L'}, //emaiL
145 {"phone", 1, 0, 'P'}, //phone
146 {"group", 1, 0, 'G'}, //Group
147 {"ip", 0, 0, 'I'}, //IP-address of user
151 //-----------------------------------------------------------------------------
152 double ParseCash(const char * c, string * message)
154 //-c 123.45:log message
158 str = new char[strlen(c) + 1];
160 strncpy(str, c, strlen(c));
163 msg = strchr(str, ':');
173 if (strtodouble2(str, cash) != 0)
175 printf("Incorrect cash value %s\n", c);
176 exit(PARAMETER_PARSING_ERR_CODE);
182 //-----------------------------------------------------------------------------
183 double ParseCredit(const char * c)
186 if (strtodouble2(c, credit) != 0)
188 printf("Incorrect credit value %s\n", c);
189 exit(PARAMETER_PARSING_ERR_CODE);
194 //-----------------------------------------------------------------------------
195 double ParsePrepaidTraffic(const char * c)
198 if (strtodouble2(c, credit) != 0)
200 printf("Incorrect prepaid traffic value %s\n", c);
201 exit(PARAMETER_PARSING_ERR_CODE);
206 //-----------------------------------------------------------------------------
207 int64_t ParseTraff(const char * c)
210 if (str2x(c, traff) != 0)
212 printf("Incorrect credit value %s\n", c);
213 exit(PARAMETER_PARSING_ERR_CODE);
218 //-----------------------------------------------------------------------------
219 bool ParseDownPassive(const char * dp)
221 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
223 printf("Incorrect value %s\n", dp);
224 exit(PARAMETER_PARSING_ERR_CODE);
229 //-----------------------------------------------------------------------------
230 string ParseTariff(const char * t, int &chgType)
242 if (strlen(s1) >= TARIFF_NAME_LEN)
244 printf("Tariff name too big %s\n", s1);
245 exit(PARAMETER_PARSING_ERR_CODE);
252 printf("Incorrect tariff value %s\n", t);
253 exit(PARAMETER_PARSING_ERR_CODE);
256 s2 = strtok(NULL, ":");
262 chgType = TARIFF_NOW;
269 if (strcmp(s2, "now") == 0)
270 chgType = TARIFF_NOW;
272 if (strcmp(s2, "delayed") == 0)
273 chgType = TARIFF_DEL;
275 if (strcmp(s2, "recalc") == 0)
276 chgType = TARIFF_REC;
280 printf("Incorrect tariff value %s\n", t);
281 exit(PARAMETER_PARSING_ERR_CODE);
288 //-----------------------------------------------------------------------------
289 time_t ParseCreditExpire(const char * str)
291 struct tm brokenTime;
293 brokenTime.tm_wday = 0;
294 brokenTime.tm_yday = 0;
295 brokenTime.tm_isdst = 0;
296 brokenTime.tm_hour = 0;
297 brokenTime.tm_min = 0;
298 brokenTime.tm_sec = 0;
300 stg_strptime(str, "%Y-%m-%d", &brokenTime);
302 return stg_timegm(&brokenTime);
304 //-----------------------------------------------------------------------------
305 void ParseAnyString(const char * c, string * msg, const char * enc)
308 char * ob = new char[strlen(c) + 1];
309 char * ib = new char[strlen(c) + 1];
316 setlocale(LC_ALL, "");
319 strncpy(charsetF, nl_langinfo(CODESET), 255);
321 const char * charsetT = enc;
325 size_t insize = strlen(ib);
326 size_t outsize = strlen(ib);
330 cd = iconv_open(charsetT, charsetF);
331 if (cd == (iconv_t) -1)
335 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
340 printf("error iconv_open\n");
342 exit(ICONV_ERR_CODE);
345 #if defined(FREE_BSD) || defined(FREE_BSD5)
346 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
348 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
350 //printf("nconv=%d outsize=%d\n", nconv, outsize);
351 if (nconv == (size_t) -1)
355 printf("iconv error\n");
356 exit(ICONV_ERR_CODE);
368 //-----------------------------------------------------------------------------
369 void CreateRequestSet(REQUEST * req, char * r)
371 const int strLen = 10024;
373 memset(str, 0, strLen);
377 if (!req->usrMsg.empty())
380 Encode12str(msg, req->usrMsg.data());
381 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());
382 //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
389 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
397 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
403 strcat(r, "<SetUser>\n");
404 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
406 if (!req->credit.empty())
408 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
412 if (!req->creditExpire.empty())
414 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
418 if (!req->prepaidTraff.empty())
420 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
424 if (!req->cash.empty())
427 Encode12str(msg, req->message);
428 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
432 if (!req->setCash.empty())
435 Encode12str(msg, req->message);
436 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
440 if (!req->usrPasswd.empty())
442 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
446 if (!req->down.empty())
448 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
452 if (!req->passive.empty())
454 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
458 if (!req->disableDetailStat.empty())
460 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
464 if (!req->alwaysOnline.empty())
466 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
470 // IP-address of user
471 if (!req->ips.empty())
473 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
477 int uPresent = false;
478 int dPresent = false;
479 for (int i = 0; i < DIR_NUM; i++)
481 if (!req->monthUpload[i].empty())
483 if (!uPresent && !dPresent)
485 sprintf(str, "<traff ");
491 ss << req->monthUpload[i].const_data();
492 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
493 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
496 if (!req->monthDownload[i].empty())
498 if (!uPresent && !dPresent)
500 sprintf(str, "<traff ");
506 ss << req->monthDownload[i].const_data();
507 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
510 if (!req->sessionUpload[i].empty())
512 if (!uPresent && !dPresent)
514 sprintf(str, "<traff ");
520 ss << req->sessionUpload[i].const_data();
521 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
522 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
525 if (!req->sessionDownload[i].empty())
527 if (!uPresent && !dPresent)
529 sprintf(str, "<traff ");
535 ss << req->sessionDownload[i].const_data();
536 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
540 if (uPresent || dPresent)
547 if (!req->tariff.empty())
549 switch (req->chgTariff)
552 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
556 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
560 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
567 if (!req->note.empty())
570 Encode12str(note, req->note.data());
571 sprintf(str, "<note value=\"%s\"/>", note.c_str());
575 if (!req->name.empty())
578 Encode12str(name, req->name.data());
579 sprintf(str, "<name value=\"%s\"/>", name.c_str());
583 if (!req->address.empty())
586 Encode12str(address, req->address.data());
587 sprintf(str, "<address value=\"%s\"/>", address.c_str());
591 if (!req->email.empty())
594 Encode12str(email, req->email.data());
595 sprintf(str, "<email value=\"%s\"/>", email.c_str());
599 if (!req->phone.empty())
602 Encode12str(phone, req->phone.data());
603 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
607 if (!req->group.empty())
610 Encode12str(group, req->group.data());
611 sprintf(str, "<group value=\"%s\"/>", group.c_str());
615 for (int i = 0; i < USERDATA_NUM; i++)
617 if (!req->userData[i].empty())
620 Encode12str(ud, req->userData[i].data());
621 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
626 strcat(r, "</SetUser>\n");
628 //-----------------------------------------------------------------------------
629 int CheckParameters(REQUEST * req)
636 bool a = !req->admLogin.empty()
637 && !req->admPasswd.empty()
638 && !req->server.empty()
639 && !req->port.empty()
640 && !req->login.empty();
642 bool b = !req->cash.empty()
643 || !req->setCash.empty()
644 || !req->credit.empty()
645 || !req->prepaidTraff.empty()
646 || !req->tariff.empty()
647 || !req->usrMsg.empty()
648 || !req->usrPasswd.empty()
650 || !req->note.empty()
651 || !req->name.empty()
652 || !req->address.empty()
653 || !req->email.empty()
654 || !req->phone.empty()
655 || !req->group.empty()
656 || !req->ips.empty() // IP-address of user
662 for (int i = 0; i < DIR_NUM; i++)
664 if (req->sessionUpload[i].empty())
671 for (int i = 0; i < DIR_NUM; i++)
673 if (req->sessionDownload[i].empty())
680 for (int i = 0; i < DIR_NUM; i++)
682 if (req->monthUpload[i].empty())
689 for (int i = 0; i < DIR_NUM; i++)
691 if (req->monthDownload[i].empty())
698 for (int i = 0; i < DIR_NUM; i++)
700 if (req->userData[i].empty())
708 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
709 return a && (b || su || sd || mu || md || ud);
711 //-----------------------------------------------------------------------------
712 int CheckParametersGet(REQUEST * req)
714 return CheckParameters(req);
716 //-----------------------------------------------------------------------------
717 int CheckParametersSet(REQUEST * req)
719 return CheckParameters(req);
721 //-----------------------------------------------------------------------------
722 bool mainGet(int argc, char **argv)
726 RESETABLE<string> t1;
727 int missedOptionArg = false;
729 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
730 int option_index = -1;
735 c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
746 req.port = ParseServerPort(optarg);
751 req.admLogin = ParseAdminLogin(optarg);
754 case 'w': //admin password
755 req.admPasswd = ParsePassword(optarg);
758 case 'o': //change user password
763 req.login = ParseUser(optarg);
774 case 'E': //credit expire
775 req.creditExpire = 1;
790 case 'e': //Prepaid Traffic
791 req.prepaidTraff = 1;
818 case 'I': //IP-address of user
822 case 'S': //Detail stat status
823 req.disableDetailStat = " ";
826 case 'O': //Always online status
827 req.alwaysOnline = " ";
831 SetArrayItem(req.sessionUpload, optarg, 1);
832 //req.sessionUpload[optarg] = 1;
835 SetArrayItem(req.sessionDownload, optarg, 1);
836 //req.sessionDownload[optarg] = 1;
839 SetArrayItem(req.monthUpload, optarg, 1);
840 //req.monthUpload[optarg] = 1;
843 SetArrayItem(req.monthDownload, optarg, 1);
844 //req.monthDownload[optarg] = 1;
848 SetArrayItem(req.userData, optarg, std::string(" "));
849 //req.userData[optarg] = " ";
858 missedOptionArg = true;
862 printf ("?? getopt returned character code 0%o ??\n", c);
868 printf ("non-option ARGV-elements: ");
869 while (optind < argc)
870 printf ("%s ", argv[optind++]);
872 exit(PARAMETER_PARSING_ERR_CODE);
875 if (missedOptionArg || !CheckParametersGet(&req))
877 //printf("Parameter needed\n");
879 exit(PARAMETER_PARSING_ERR_CODE);
883 return ProcessAuthBy(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data());
885 return ProcessGetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), req);
887 //-----------------------------------------------------------------------------
888 bool mainSet(int argc, char **argv)
893 bool isMessage = false;
896 RESETABLE<string> t1;
898 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:";
900 int missedOptionArg = false;
904 int option_index = -1;
906 c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
918 req.port = ParseServerPort(optarg);
923 req.admLogin = ParseAdminLogin(optarg);
926 case 'w': //admin password
927 req.admPasswd = ParsePassword(optarg);
930 case 'o': //change user password
931 req.usrPasswd = ParsePassword(optarg);
935 req.login = ParseUser(optarg);
939 req.cash = ParseCash(optarg, &req.message);
943 req.setCash = ParseCash(optarg, &req.message);
947 req.credit = ParseCredit(optarg);
950 case 'E': //credit expire
951 req.creditExpire = ParseCreditExpire(optarg);
955 req.down = ParseDownPassive(optarg);
959 req.passive = ParseDownPassive(optarg);
963 req.tariff = ParseTariff(optarg, req.chgTariff);
967 ParseAnyString(optarg, &str);
972 case 'e': //Prepaid Traffic
973 req.prepaidTraff = ParsePrepaidTraffic(optarg);
976 case 'n': //Create User
977 req.createUser = true;
980 case 'l': //Delete User
981 req.deleteUser = true;
985 ParseAnyString(optarg, &str, "koi8-ru");
990 ParseAnyString(optarg, &str, "koi8-ru");
995 ParseAnyString(optarg, &str, "koi8-ru");
1000 ParseAnyString(optarg, &str, "koi8-ru");
1002 //printf("EMAIL=%s\n", optarg);
1006 ParseAnyString(optarg, &str);
1011 ParseAnyString(optarg, &str, "koi8-ru");
1015 case 'I': //IP-address of user
1016 ParseAnyString(optarg, &str);
1021 req.disableDetailStat = ParseDownPassive(optarg);
1025 req.alwaysOnline = ParseDownPassive(optarg);
1029 SetArrayItem(req.sessionUpload, optarg, ParseTraff(argv[optind++]));
1030 //req.sessionUpload[optarg] = ParseTraff(argv[optind++]);
1033 SetArrayItem(req.sessionDownload, optarg, ParseTraff(argv[optind++]));
1034 //req.sessionDownload[optarg] = ParseTraff(argv[optind++]);
1037 SetArrayItem(req.monthUpload, optarg, ParseTraff(argv[optind++]));
1038 //req.monthUpload[optarg] = ParseTraff(argv[optind++]);
1041 SetArrayItem(req.monthDownload, optarg, ParseTraff(argv[optind++]));
1042 //req.monthDownload[optarg] = ParseTraff(argv[optind++]);
1045 case 700: //UserData
1046 ParseAnyString(argv[optind++], &str);
1047 SetArrayItem(req.userData, optarg, str);
1048 //req.userData[optarg] = str;
1052 missedOptionArg = true;
1056 missedOptionArg = true;
1060 printf("?? getopt returned character code 0%o ??\n", c);
1066 printf ("non-option ARGV-elements: ");
1067 while (optind < argc)
1068 printf ("%s ", argv[optind++]);
1070 exit(PARAMETER_PARSING_ERR_CODE);
1073 if (missedOptionArg || !CheckParametersSet(&req))
1075 //printf("Parameter needed\n");
1077 exit(PARAMETER_PARSING_ERR_CODE);
1080 const int rLen = 20000;
1082 memset(rstr, 0, rLen);
1084 CreateRequestSet(&req, rstr);
1086 return ProcessSendMessage(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), rstr);
1088 return ProcessSetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), rstr);
1090 //-----------------------------------------------------------------------------
1091 int main(int argc, char **argv)
1096 exit(PARAMETER_PARSING_ERR_CODE);
1099 if (strcmp(argv[1], "get") == 0)
1102 return mainGet(argc - 1, argv + 1);
1104 else if (strcmp(argv[1], "set") == 0)
1107 if (mainSet(argc - 1, argv + 1) )
1114 exit(PARAMETER_PARSING_ERR_CODE);
1116 return UNKNOWN_ERR_CODE;
1118 //-----------------------------------------------------------------------------