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"
53 struct ARRAY_TYPE<T[]>
58 template <typename T, size_t N>
59 struct ARRAY_TYPE<T[N]>
65 bool SetArrayItem(T & array, const char * index, const typename ARRAY_TYPE<T>::type & value)
68 if (str2x(index, pos))
74 } // namespace anonymous
78 int ParseReplyGet(void * data, list<string> * ans);
79 //int ParseReplySet(void * data, list<string> * ans);
81 struct option long_options_get[] = {
82 {"server", 1, 0, 's'}, //Server
83 {"port", 1, 0, 'p'}, //Port
84 {"admin", 1, 0, 'a'}, //Admin
85 {"admin_pass", 1, 0, 'w'}, //passWord
86 {"user", 1, 0, 'u'}, //User
87 {"addcash", 0, 0, 'c'}, //Add Cash
88 //{"setcash", 0, 0, 'v'}, //Set Cash
89 {"credit", 0, 0, 'r'}, //cRedit
90 {"tariff", 0, 0, 't'}, //Tariff
91 {"message", 0, 0, 'm'}, //message
92 {"password", 0, 0, 'o'}, //password
93 {"down", 0, 0, 'd'}, //down
94 {"passive", 0, 0, 'i'}, //passive
95 {"disable-stat",0, 0, 'S'}, //disable detail stat
96 {"always-online",0, 0, 'O'}, //always online
97 {"session-upload", 1, 0, 500}, //SU0
98 {"session-download", 1, 0, 501}, //SD0
99 {"month-upload", 1, 0, 502}, //MU0
100 {"month-download", 1, 0, 503}, //MD0
102 {"user-data", 1, 0, 700}, //UserData0
104 {"prepaid", 0, 0, 'e'}, //prepaid traff
105 {"create", 0, 0, 'n'}, //create
106 {"delete", 0, 0, 'l'}, //delete
108 {"note", 0, 0, 'N'}, //Note
109 {"name", 0, 0, 'A'}, //nAme
110 {"address", 0, 0, 'D'}, //aDdress
111 {"email", 0, 0, 'L'}, //emaiL
112 {"phone", 0, 0, 'P'}, //phone
113 {"group", 0, 0, 'G'}, //Group
114 {"ip", 0, 0, 'I'}, //IP-address of user
115 {"authorized-by",0, 0, 800}, //always online
119 struct option long_options_set[] = {
120 {"server", 1, 0, 's'}, //Server
121 {"port", 1, 0, 'p'}, //Port
122 {"admin", 1, 0, 'a'}, //Admin
123 {"admin_pass", 1, 0, 'w'}, //passWord
124 {"user", 1, 0, 'u'}, //User
125 {"addcash", 1, 0, 'c'}, //Add Cash
126 {"setcash", 1, 0, 'v'}, //Set Cash
127 {"credit", 1, 0, 'r'}, //cRedit
128 {"tariff", 1, 0, 't'}, //Tariff
129 {"message", 1, 0, 'm'}, //message
130 {"password", 1, 0, 'o'}, //password
131 {"down", 1, 0, 'd'}, //down
132 {"passive", 1, 0, 'i'}, //passive
133 {"disable-stat",1, 0, 'S'}, //disable detail stat
134 {"always-online",1, 0, 'O'}, //always online
135 {"session-upload", 1, 0, 500}, //U0
136 {"session-download", 1, 0, 501}, //U1
137 {"month-upload", 1, 0, 502}, //U2
138 {"month-download", 1, 0, 503}, //U3
140 {"user-data", 1, 0, 700}, //UserData
142 {"prepaid", 1, 0, 'e'}, //prepaid traff
143 {"create", 1, 0, 'n'}, //create
144 {"delete", 1, 0, 'l'}, //delete
146 {"note", 1, 0, 'N'}, //Note
147 {"name", 1, 0, 'A'}, //nAme
148 {"address", 1, 0, 'D'}, //aDdress
149 {"email", 1, 0, 'L'}, //emaiL
150 {"phone", 1, 0, 'P'}, //phone
151 {"group", 1, 0, 'G'}, //Group
152 {"ip", 0, 0, 'I'}, //IP-address of user
156 //-----------------------------------------------------------------------------
157 double ParseCash(const char * c, string * message)
159 //-c 123.45:log message
163 str = new char[strlen(c) + 1];
165 strncpy(str, c, strlen(c));
168 msg = strchr(str, ':');
178 if (strtodouble2(str, cash) != 0)
180 printf("Incorrect cash value %s\n", c);
181 exit(PARAMETER_PARSING_ERR_CODE);
187 //-----------------------------------------------------------------------------
188 double ParseCredit(const char * c)
191 if (strtodouble2(c, credit) != 0)
193 printf("Incorrect credit value %s\n", c);
194 exit(PARAMETER_PARSING_ERR_CODE);
199 //-----------------------------------------------------------------------------
200 double ParsePrepaidTraffic(const char * c)
203 if (strtodouble2(c, credit) != 0)
205 printf("Incorrect prepaid traffic value %s\n", c);
206 exit(PARAMETER_PARSING_ERR_CODE);
211 //-----------------------------------------------------------------------------
212 int64_t ParseTraff(const char * c)
215 if (str2x(c, traff) != 0)
217 printf("Incorrect credit value %s\n", c);
218 exit(PARAMETER_PARSING_ERR_CODE);
223 //-----------------------------------------------------------------------------
224 bool ParseDownPassive(const char * dp)
226 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
228 printf("Incorrect value %s\n", dp);
229 exit(PARAMETER_PARSING_ERR_CODE);
234 //-----------------------------------------------------------------------------
235 string ParseTariff(const char * t, int &chgType)
247 if (strlen(s1) >= TARIFF_NAME_LEN)
249 printf("Tariff name too big %s\n", s1);
250 exit(PARAMETER_PARSING_ERR_CODE);
257 printf("Incorrect tariff value %s\n", t);
258 exit(PARAMETER_PARSING_ERR_CODE);
261 s2 = strtok(NULL, ":");
267 chgType = TARIFF_NOW;
274 if (strcmp(s2, "now") == 0)
275 chgType = TARIFF_NOW;
277 if (strcmp(s2, "delayed") == 0)
278 chgType = TARIFF_DEL;
280 if (strcmp(s2, "recalc") == 0)
281 chgType = TARIFF_REC;
285 printf("Incorrect tariff value %s\n", t);
286 exit(PARAMETER_PARSING_ERR_CODE);
293 //-----------------------------------------------------------------------------
294 time_t ParseCreditExpire(const char * str)
296 struct tm brokenTime;
298 brokenTime.tm_wday = 0;
299 brokenTime.tm_yday = 0;
300 brokenTime.tm_isdst = 0;
301 brokenTime.tm_hour = 0;
302 brokenTime.tm_min = 0;
303 brokenTime.tm_sec = 0;
305 stg_strptime(str, "%Y-%m-%d", &brokenTime);
307 return stg_timegm(&brokenTime);
309 //-----------------------------------------------------------------------------
310 void ParseAnyString(const char * c, string * msg, const char * enc)
313 char * ob = new char[strlen(c) + 1];
314 char * ib = new char[strlen(c) + 1];
321 setlocale(LC_ALL, "");
324 strncpy(charsetF, nl_langinfo(CODESET), 255);
326 const char * charsetT = enc;
330 size_t insize = strlen(ib);
331 size_t outsize = strlen(ib);
335 cd = iconv_open(charsetT, charsetF);
336 if (cd == (iconv_t) -1)
340 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
345 printf("error iconv_open\n");
347 exit(ICONV_ERR_CODE);
350 #if defined(FREE_BSD) || defined(FREE_BSD5)
351 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
353 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
355 //printf("nconv=%d outsize=%d\n", nconv, outsize);
356 if (nconv == (size_t) -1)
360 printf("iconv error\n");
361 exit(ICONV_ERR_CODE);
373 //-----------------------------------------------------------------------------
374 void CreateRequestSet(REQUEST * req, char * r)
376 const int strLen = 10024;
378 memset(str, 0, strLen);
382 if (!req->usrMsg.res_empty())
385 Encode12str(msg, req->usrMsg);
386 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());
387 //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
394 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
402 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
408 strcat(r, "<SetUser>\n");
409 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
411 if (!req->credit.res_empty())
413 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
417 if (!req->creditExpire.res_empty())
419 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
423 if (!req->prepaidTraff.res_empty())
425 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
429 if (!req->cash.res_empty())
432 Encode12str(msg, req->message);
433 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
437 if (!req->setCash.res_empty())
440 Encode12str(msg, req->message);
441 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
445 if (!req->usrPasswd.res_empty())
447 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
451 if (!req->down.res_empty())
453 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
457 if (!req->passive.res_empty())
459 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
463 if (!req->disableDetailStat.res_empty())
465 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
469 if (!req->alwaysOnline.res_empty())
471 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
475 // IP-address of user
476 if (!req->ips.res_empty())
478 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
482 int uPresent = false;
483 int dPresent = false;
484 for (int i = 0; i < DIR_NUM; i++)
486 if (!req->monthUpload[i].res_empty())
488 if (!uPresent && !dPresent)
490 sprintf(str, "<traff ");
496 ss << req->monthUpload[i].const_data();
497 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
498 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
501 if (!req->monthDownload[i].res_empty())
503 if (!uPresent && !dPresent)
505 sprintf(str, "<traff ");
511 ss << req->monthDownload[i].const_data();
512 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
515 if (!req->sessionUpload[i].res_empty())
517 if (!uPresent && !dPresent)
519 sprintf(str, "<traff ");
525 ss << req->sessionUpload[i].const_data();
526 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
527 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
530 if (!req->sessionDownload[i].res_empty())
532 if (!uPresent && !dPresent)
534 sprintf(str, "<traff ");
540 ss << req->sessionDownload[i].const_data();
541 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
545 if (uPresent || dPresent)
552 if (!req->tariff.res_empty())
554 switch (req->chgTariff)
557 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
561 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
565 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
572 if (!req->note.res_empty())
575 Encode12str(note, req->note);
576 sprintf(str, "<note value=\"%s\"/>", note.c_str());
580 if (!req->name.res_empty())
583 Encode12str(name, req->name);
584 sprintf(str, "<name value=\"%s\"/>", name.c_str());
588 if (!req->address.res_empty())
591 Encode12str(address, req->address);
592 sprintf(str, "<address value=\"%s\"/>", address.c_str());
596 if (!req->email.res_empty())
599 Encode12str(email, req->email);
600 sprintf(str, "<email value=\"%s\"/>", email.c_str());
604 if (!req->phone.res_empty())
607 Encode12str(phone, req->phone);
608 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
612 if (!req->group.res_empty())
615 Encode12str(group, req->group);
616 sprintf(str, "<group value=\"%s\"/>", group.c_str());
620 for (int i = 0; i < USERDATA_NUM; i++)
622 if (!req->userData[i].res_empty())
625 Encode12str(ud, req->userData[i]);
626 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
631 strcat(r, "</SetUser>\n");
633 //-----------------------------------------------------------------------------
634 int CheckParameters(REQUEST * req)
641 bool a = !req->admLogin.res_empty()
642 && !req->admPasswd.res_empty()
643 && !req->server.res_empty()
644 && !req->port.res_empty()
645 && !req->login.res_empty();
647 bool b = !req->cash.res_empty()
648 || !req->setCash.res_empty()
649 || !req->credit.res_empty()
650 || !req->prepaidTraff.res_empty()
651 || !req->tariff.res_empty()
652 || !req->usrMsg.res_empty()
653 || !req->usrPasswd.res_empty()
655 || !req->note.res_empty()
656 || !req->name.res_empty()
657 || !req->address.res_empty()
658 || !req->email.res_empty()
659 || !req->phone.res_empty()
660 || !req->group.res_empty()
661 || !req->ips.res_empty() // IP-address of user
667 for (int i = 0; i < DIR_NUM; i++)
669 if (req->sessionUpload[i].res_empty())
676 for (int i = 0; i < DIR_NUM; i++)
678 if (req->sessionDownload[i].res_empty())
685 for (int i = 0; i < DIR_NUM; i++)
687 if (req->monthUpload[i].res_empty())
694 for (int i = 0; i < DIR_NUM; i++)
696 if (req->monthDownload[i].res_empty())
703 for (int i = 0; i < DIR_NUM; i++)
705 if (req->userData[i].res_empty())
713 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
714 return a && (b || su || sd || mu || md || ud);
716 //-----------------------------------------------------------------------------
717 int CheckParametersGet(REQUEST * req)
719 return CheckParameters(req);
721 //-----------------------------------------------------------------------------
722 int CheckParametersSet(REQUEST * req)
724 return CheckParameters(req);
726 //-----------------------------------------------------------------------------
727 int mainGet(int argc, char **argv)
731 RESETABLE<string> t1;
732 int missedOptionArg = false;
734 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
735 int option_index = -1;
740 c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
751 req.port = ParseServerPort(optarg);
756 req.admLogin = ParseAdminLogin(optarg);
759 case 'w': //admin password
760 req.admPasswd = ParsePassword(optarg);
763 case 'o': //change user password
768 req.login = ParseUser(optarg);
779 case 'E': //credit expire
780 req.creditExpire = 1;
795 case 'e': //Prepaid Traffic
796 req.prepaidTraff = 1;
823 case 'I': //IP-address of user
827 case 'S': //Detail stat status
828 req.disableDetailStat = " ";
831 case 'O': //Always online status
832 req.alwaysOnline = " ";
836 SetArrayItem(req.sessionUpload, optarg, 1);
837 //req.sessionUpload[optarg] = 1;
840 SetArrayItem(req.sessionDownload, optarg, 1);
841 //req.sessionDownload[optarg] = 1;
844 SetArrayItem(req.monthUpload, optarg, 1);
845 //req.monthUpload[optarg] = 1;
848 SetArrayItem(req.monthDownload, optarg, 1);
849 //req.monthDownload[optarg] = 1;
853 SetArrayItem(req.userData, optarg, std::string(" "));
854 //req.userData[optarg] = " ";
863 missedOptionArg = true;
867 printf ("?? getopt returned character code 0%o ??\n", c);
873 printf ("non-option ARGV-elements: ");
874 while (optind < argc)
875 printf ("%s ", argv[optind++]);
877 exit(PARAMETER_PARSING_ERR_CODE);
880 if (missedOptionArg || !CheckParametersGet(&req))
882 //printf("Parameter needed\n");
884 exit(PARAMETER_PARSING_ERR_CODE);
888 return ProcessAuthBy(req.server, req.port, req.admLogin, req.admPasswd, req.login);
890 return ProcessGetUser(req.server, req.port, req.admLogin, req.admPasswd, req.login, req);
892 //-----------------------------------------------------------------------------
893 int mainSet(int argc, char **argv)
898 bool isMessage = false;
901 RESETABLE<string> t1;
903 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:";
905 int missedOptionArg = false;
909 int option_index = -1;
911 c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
923 req.port = ParseServerPort(optarg);
928 req.admLogin = ParseAdminLogin(optarg);
931 case 'w': //admin password
932 req.admPasswd = ParsePassword(optarg);
935 case 'o': //change user password
936 req.usrPasswd = ParsePassword(optarg);
940 req.login = ParseUser(optarg);
944 req.cash = ParseCash(optarg, &req.message);
948 req.setCash = ParseCash(optarg, &req.message);
952 req.credit = ParseCredit(optarg);
955 case 'E': //credit expire
956 req.creditExpire = ParseCreditExpire(optarg);
960 req.down = ParseDownPassive(optarg);
964 req.passive = ParseDownPassive(optarg);
968 req.tariff = ParseTariff(optarg, req.chgTariff);
972 ParseAnyString(optarg, &str);
977 case 'e': //Prepaid Traffic
978 req.prepaidTraff = ParsePrepaidTraffic(optarg);
981 case 'n': //Create User
982 req.createUser = true;
985 case 'l': //Delete User
986 req.deleteUser = true;
990 ParseAnyString(optarg, &str, "koi8-ru");
995 ParseAnyString(optarg, &str, "koi8-ru");
1000 ParseAnyString(optarg, &str, "koi8-ru");
1005 ParseAnyString(optarg, &str, "koi8-ru");
1007 //printf("EMAIL=%s\n", optarg);
1011 ParseAnyString(optarg, &str);
1016 ParseAnyString(optarg, &str, "koi8-ru");
1020 case 'I': //IP-address of user
1021 ParseAnyString(optarg, &str);
1026 req.disableDetailStat = ParseDownPassive(optarg);
1030 req.alwaysOnline = ParseDownPassive(optarg);
1034 SetArrayItem(req.sessionUpload, optarg, ParseTraff(argv[optind++]));
1035 //req.sessionUpload[optarg] = ParseTraff(argv[optind++]);
1038 SetArrayItem(req.sessionDownload, optarg, ParseTraff(argv[optind++]));
1039 //req.sessionDownload[optarg] = ParseTraff(argv[optind++]);
1042 SetArrayItem(req.monthUpload, optarg, ParseTraff(argv[optind++]));
1043 //req.monthUpload[optarg] = ParseTraff(argv[optind++]);
1046 SetArrayItem(req.monthDownload, optarg, ParseTraff(argv[optind++]));
1047 //req.monthDownload[optarg] = ParseTraff(argv[optind++]);
1050 case 700: //UserData
1051 ParseAnyString(argv[optind++], &str);
1052 SetArrayItem(req.userData, optarg, str);
1053 //req.userData[optarg] = str;
1057 missedOptionArg = true;
1061 missedOptionArg = true;
1065 printf("?? getopt returned character code 0%o ??\n", c);
1071 printf ("non-option ARGV-elements: ");
1072 while (optind < argc)
1073 printf ("%s ", argv[optind++]);
1075 exit(PARAMETER_PARSING_ERR_CODE);
1078 if (missedOptionArg || !CheckParametersSet(&req))
1080 //printf("Parameter needed\n");
1082 exit(PARAMETER_PARSING_ERR_CODE);
1085 const int rLen = 20000;
1087 memset(rstr, 0, rLen);
1089 CreateRequestSet(&req, rstr);
1090 return ProcessSetUser(req.server, req.port, req.admLogin, req.admPasswd, rstr, isMessage);
1092 //-----------------------------------------------------------------------------
1093 int main(int argc, char **argv)
1098 exit(PARAMETER_PARSING_ERR_CODE);
1101 if (strcmp(argv[1], "get") == 0)
1104 return mainGet(argc - 1, argv + 1);
1106 else if (strcmp(argv[1], "set") == 0)
1109 return mainSet(argc - 1, argv + 1);
1114 exit(PARAMETER_PARSING_ERR_CODE);
1116 return UNKNOWN_ERR_CODE;
1118 //-----------------------------------------------------------------------------