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"
42 #include "common_sg.h"
43 #include "sg_error_codes.h"
52 struct ARRAY_TYPE<T[]>
57 template <typename T, size_t N>
58 struct ARRAY_TYPE<T[N]>
64 bool SetArrayItem(T & array, const char * index, const typename ARRAY_TYPE<T>::type & value)
67 if (str2x(index, pos))
73 } // namespace anonymous
77 int ParseReplyGet(void * data, list<string> * ans);
78 //int ParseReplySet(void * data, list<string> * ans);
80 struct option long_options_get[] = {
81 {"server", 1, 0, 's'}, //Server
82 {"port", 1, 0, 'p'}, //Port
83 {"admin", 1, 0, 'a'}, //Admin
84 {"admin_pass", 1, 0, 'w'}, //passWord
85 {"user", 1, 0, 'u'}, //User
86 {"addcash", 0, 0, 'c'}, //Add Cash
87 //{"setcash", 0, 0, 'v'}, //Set Cash
88 {"credit", 0, 0, 'r'}, //cRedit
89 {"tariff", 0, 0, 't'}, //Tariff
90 {"message", 0, 0, 'm'}, //message
91 {"password", 0, 0, 'o'}, //password
92 {"down", 0, 0, 'd'}, //down
93 {"passive", 0, 0, 'i'}, //passive
94 {"disable-stat",0, 0, 'S'}, //disable detail stat
95 {"always-online",0, 0, 'O'}, //always online
96 {"session-upload", 1, 0, 500}, //SU0
97 {"session-download", 1, 0, 501}, //SD0
98 {"month-upload", 1, 0, 502}, //MU0
99 {"month-download", 1, 0, 503}, //MD0
101 {"user-data", 1, 0, 700}, //UserData0
103 {"prepaid", 0, 0, 'e'}, //prepaid traff
104 {"create", 0, 0, 'n'}, //create
105 {"delete", 0, 0, 'l'}, //delete
107 {"note", 0, 0, 'N'}, //Note
108 {"name", 0, 0, 'A'}, //nAme
109 {"address", 0, 0, 'D'}, //aDdress
110 {"email", 0, 0, 'L'}, //emaiL
111 {"phone", 0, 0, 'P'}, //phone
112 {"group", 0, 0, 'G'}, //Group
113 {"ip", 0, 0, 'I'}, //IP-address of user
114 {"authorized-by",0, 0, 800}, //always online
118 struct option long_options_set[] = {
119 {"server", 1, 0, 's'}, //Server
120 {"port", 1, 0, 'p'}, //Port
121 {"admin", 1, 0, 'a'}, //Admin
122 {"admin_pass", 1, 0, 'w'}, //passWord
123 {"user", 1, 0, 'u'}, //User
124 {"addcash", 1, 0, 'c'}, //Add Cash
125 {"setcash", 1, 0, 'v'}, //Set Cash
126 {"credit", 1, 0, 'r'}, //cRedit
127 {"tariff", 1, 0, 't'}, //Tariff
128 {"message", 1, 0, 'm'}, //message
129 {"password", 1, 0, 'o'}, //password
130 {"down", 1, 0, 'd'}, //down
131 {"passive", 1, 0, 'i'}, //passive
132 {"disable-stat",1, 0, 'S'}, //disable detail stat
133 {"always-online",1, 0, 'O'}, //always online
134 {"session-upload", 1, 0, 500}, //U0
135 {"session-download", 1, 0, 501}, //U1
136 {"month-upload", 1, 0, 502}, //U2
137 {"month-download", 1, 0, 503}, //U3
139 {"user-data", 1, 0, 700}, //UserData
141 {"prepaid", 1, 0, 'e'}, //prepaid traff
142 {"create", 1, 0, 'n'}, //create
143 {"delete", 1, 0, 'l'}, //delete
145 {"note", 1, 0, 'N'}, //Note
146 {"name", 1, 0, 'A'}, //nAme
147 {"address", 1, 0, 'D'}, //aDdress
148 {"email", 1, 0, 'L'}, //emaiL
149 {"phone", 1, 0, 'P'}, //phone
150 {"group", 1, 0, 'G'}, //Group
151 {"ip", 0, 0, 'I'}, //IP-address of user
155 //-----------------------------------------------------------------------------
156 double ParseCash(const char * c, string * message)
158 //-c 123.45:log message
162 str = new char[strlen(c) + 1];
164 strncpy(str, c, strlen(c));
167 msg = strchr(str, ':');
177 if (strtodouble2(str, cash) != 0)
179 printf("Incorrect cash value %s\n", c);
180 exit(PARAMETER_PARSING_ERR_CODE);
186 //-----------------------------------------------------------------------------
187 double ParseCredit(const char * c)
190 if (strtodouble2(c, credit) != 0)
192 printf("Incorrect credit value %s\n", c);
193 exit(PARAMETER_PARSING_ERR_CODE);
198 //-----------------------------------------------------------------------------
199 double ParsePrepaidTraffic(const char * c)
202 if (strtodouble2(c, credit) != 0)
204 printf("Incorrect prepaid traffic value %s\n", c);
205 exit(PARAMETER_PARSING_ERR_CODE);
210 //-----------------------------------------------------------------------------
211 int64_t ParseTraff(const char * c)
214 if (str2x(c, traff) != 0)
216 printf("Incorrect credit value %s\n", c);
217 exit(PARAMETER_PARSING_ERR_CODE);
222 //-----------------------------------------------------------------------------
223 bool ParseDownPassive(const char * dp)
225 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
227 printf("Incorrect value %s\n", dp);
228 exit(PARAMETER_PARSING_ERR_CODE);
233 //-----------------------------------------------------------------------------
234 string ParseTariff(const char * t, int &chgType)
246 if (strlen(s1) >= TARIFF_NAME_LEN)
248 printf("Tariff name too big %s\n", s1);
249 exit(PARAMETER_PARSING_ERR_CODE);
256 printf("Incorrect tariff value %s\n", t);
257 exit(PARAMETER_PARSING_ERR_CODE);
260 s2 = strtok(NULL, ":");
266 chgType = TARIFF_NOW;
273 if (strcmp(s2, "now") == 0)
274 chgType = TARIFF_NOW;
276 if (strcmp(s2, "delayed") == 0)
277 chgType = TARIFF_DEL;
279 if (strcmp(s2, "recalc") == 0)
280 chgType = TARIFF_REC;
284 printf("Incorrect tariff value %s\n", t);
285 exit(PARAMETER_PARSING_ERR_CODE);
292 //-----------------------------------------------------------------------------
293 time_t ParseCreditExpire(const char * str)
295 struct tm brokenTime;
297 brokenTime.tm_wday = 0;
298 brokenTime.tm_yday = 0;
299 brokenTime.tm_isdst = 0;
300 brokenTime.tm_hour = 0;
301 brokenTime.tm_min = 0;
302 brokenTime.tm_sec = 0;
304 stg_strptime(str, "%Y-%m-%d", &brokenTime);
306 return stg_timegm(&brokenTime);
308 //-----------------------------------------------------------------------------
309 void ParseAnyString(const char * c, string * msg, const char * enc)
312 char * ob = new char[strlen(c) + 1];
313 char * ib = new char[strlen(c) + 1];
320 setlocale(LC_ALL, "");
323 strncpy(charsetF, nl_langinfo(CODESET), 255);
325 const char * charsetT = enc;
329 size_t insize = strlen(ib);
330 size_t outsize = strlen(ib);
334 cd = iconv_open(charsetT, charsetF);
335 if (cd == (iconv_t) -1)
339 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
344 printf("error iconv_open\n");
346 exit(ICONV_ERR_CODE);
349 #if defined(FREE_BSD) || defined(FREE_BSD5)
350 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
352 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
354 //printf("nconv=%d outsize=%d\n", nconv, outsize);
355 if (nconv == (size_t) -1)
359 printf("iconv error\n");
360 exit(ICONV_ERR_CODE);
372 //-----------------------------------------------------------------------------
373 void CreateRequestSet(REQUEST * req, char * r)
375 const int strLen = 10024;
377 memset(str, 0, strLen);
381 if (!req->usrMsg.res_empty())
384 Encode12str(msg, req->usrMsg);
385 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());
386 //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
393 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
401 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
407 strcat(r, "<SetUser>\n");
408 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
410 if (!req->credit.res_empty())
412 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
416 if (!req->creditExpire.res_empty())
418 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
422 if (!req->prepaidTraff.res_empty())
424 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
428 if (!req->cash.res_empty())
431 Encode12str(msg, req->message);
432 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
436 if (!req->setCash.res_empty())
439 Encode12str(msg, req->message);
440 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
444 if (!req->usrPasswd.res_empty())
446 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
450 if (!req->down.res_empty())
452 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
456 if (!req->passive.res_empty())
458 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
462 if (!req->disableDetailStat.res_empty())
464 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
468 if (!req->alwaysOnline.res_empty())
470 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
474 // IP-address of user
475 if (!req->ips.res_empty())
477 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
481 int uPresent = false;
482 int dPresent = false;
483 for (int i = 0; i < DIR_NUM; i++)
485 if (!req->monthUpload[i].res_empty())
487 if (!uPresent && !dPresent)
489 sprintf(str, "<traff ");
495 ss << req->monthUpload[i].const_data();
496 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
497 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
500 if (!req->monthDownload[i].res_empty())
502 if (!uPresent && !dPresent)
504 sprintf(str, "<traff ");
510 ss << req->monthDownload[i].const_data();
511 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
514 if (!req->sessionUpload[i].res_empty())
516 if (!uPresent && !dPresent)
518 sprintf(str, "<traff ");
524 ss << req->sessionUpload[i].const_data();
525 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
526 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
529 if (!req->sessionDownload[i].res_empty())
531 if (!uPresent && !dPresent)
533 sprintf(str, "<traff ");
539 ss << req->sessionDownload[i].const_data();
540 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
544 if (uPresent || dPresent)
551 if (!req->tariff.res_empty())
553 switch (req->chgTariff)
556 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
560 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
564 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
571 if (!req->note.res_empty())
574 Encode12str(note, req->note);
575 sprintf(str, "<note value=\"%s\"/>", note.c_str());
579 if (!req->name.res_empty())
582 Encode12str(name, req->name);
583 sprintf(str, "<name value=\"%s\"/>", name.c_str());
587 if (!req->address.res_empty())
590 Encode12str(address, req->address);
591 sprintf(str, "<address value=\"%s\"/>", address.c_str());
595 if (!req->email.res_empty())
598 Encode12str(email, req->email);
599 sprintf(str, "<email value=\"%s\"/>", email.c_str());
603 if (!req->phone.res_empty())
606 Encode12str(phone, req->phone);
607 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
611 if (!req->group.res_empty())
614 Encode12str(group, req->group);
615 sprintf(str, "<group value=\"%s\"/>", group.c_str());
619 for (int i = 0; i < USERDATA_NUM; i++)
621 if (!req->userData[i].res_empty())
624 Encode12str(ud, req->userData[i]);
625 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
630 strcat(r, "</SetUser>\n");
632 //-----------------------------------------------------------------------------
633 int CheckParameters(REQUEST * req)
640 bool a = !req->admLogin.res_empty()
641 && !req->admPasswd.res_empty()
642 && !req->server.res_empty()
643 && !req->port.res_empty()
644 && !req->login.res_empty();
646 bool b = !req->cash.res_empty()
647 || !req->setCash.res_empty()
648 || !req->credit.res_empty()
649 || !req->prepaidTraff.res_empty()
650 || !req->tariff.res_empty()
651 || !req->usrMsg.res_empty()
652 || !req->usrPasswd.res_empty()
654 || !req->note.res_empty()
655 || !req->name.res_empty()
656 || !req->address.res_empty()
657 || !req->email.res_empty()
658 || !req->phone.res_empty()
659 || !req->group.res_empty()
660 || !req->ips.res_empty() // IP-address of user
666 for (int i = 0; i < DIR_NUM; i++)
668 if (req->sessionUpload[i].res_empty())
675 for (int i = 0; i < DIR_NUM; i++)
677 if (req->sessionDownload[i].res_empty())
684 for (int i = 0; i < DIR_NUM; i++)
686 if (req->monthUpload[i].res_empty())
693 for (int i = 0; i < DIR_NUM; i++)
695 if (req->monthDownload[i].res_empty())
702 for (int i = 0; i < DIR_NUM; i++)
704 if (req->userData[i].res_empty())
712 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
713 return a && (b || su || sd || mu || md || ud);
715 //-----------------------------------------------------------------------------
716 int CheckParametersGet(REQUEST * req)
718 return CheckParameters(req);
720 //-----------------------------------------------------------------------------
721 int CheckParametersSet(REQUEST * req)
723 return CheckParameters(req);
725 //-----------------------------------------------------------------------------
726 bool mainGet(int argc, char **argv)
730 RESETABLE<string> t1;
731 int missedOptionArg = false;
733 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
734 int option_index = -1;
739 c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
750 req.port = ParseServerPort(optarg);
755 req.admLogin = ParseAdminLogin(optarg);
758 case 'w': //admin password
759 req.admPasswd = ParsePassword(optarg);
762 case 'o': //change user password
767 req.login = ParseUser(optarg);
778 case 'E': //credit expire
779 req.creditExpire = 1;
794 case 'e': //Prepaid Traffic
795 req.prepaidTraff = 1;
822 case 'I': //IP-address of user
826 case 'S': //Detail stat status
827 req.disableDetailStat = " ";
830 case 'O': //Always online status
831 req.alwaysOnline = " ";
835 SetArrayItem(req.sessionUpload, optarg, 1);
836 //req.sessionUpload[optarg] = 1;
839 SetArrayItem(req.sessionDownload, optarg, 1);
840 //req.sessionDownload[optarg] = 1;
843 SetArrayItem(req.monthUpload, optarg, 1);
844 //req.monthUpload[optarg] = 1;
847 SetArrayItem(req.monthDownload, optarg, 1);
848 //req.monthDownload[optarg] = 1;
852 SetArrayItem(req.userData, optarg, std::string(" "));
853 //req.userData[optarg] = " ";
862 missedOptionArg = true;
866 printf ("?? getopt returned character code 0%o ??\n", c);
872 printf ("non-option ARGV-elements: ");
873 while (optind < argc)
874 printf ("%s ", argv[optind++]);
876 exit(PARAMETER_PARSING_ERR_CODE);
879 if (missedOptionArg || !CheckParametersGet(&req))
881 //printf("Parameter needed\n");
883 exit(PARAMETER_PARSING_ERR_CODE);
887 return ProcessAuthBy(req.server, req.port, req.admLogin, req.admPasswd, req.login);
889 return ProcessGetUser(req.server, req.port, req.admLogin, req.admPasswd, req.login, req);
891 //-----------------------------------------------------------------------------
892 bool mainSet(int argc, char **argv)
897 bool isMessage = false;
900 RESETABLE<string> t1;
902 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:";
904 int missedOptionArg = false;
908 int option_index = -1;
910 c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
922 req.port = ParseServerPort(optarg);
927 req.admLogin = ParseAdminLogin(optarg);
930 case 'w': //admin password
931 req.admPasswd = ParsePassword(optarg);
934 case 'o': //change user password
935 req.usrPasswd = ParsePassword(optarg);
939 req.login = ParseUser(optarg);
943 req.cash = ParseCash(optarg, &req.message);
947 req.setCash = ParseCash(optarg, &req.message);
951 req.credit = ParseCredit(optarg);
954 case 'E': //credit expire
955 req.creditExpire = ParseCreditExpire(optarg);
959 req.down = ParseDownPassive(optarg);
963 req.passive = ParseDownPassive(optarg);
967 req.tariff = ParseTariff(optarg, req.chgTariff);
971 ParseAnyString(optarg, &str);
976 case 'e': //Prepaid Traffic
977 req.prepaidTraff = ParsePrepaidTraffic(optarg);
980 case 'n': //Create User
981 req.createUser = true;
984 case 'l': //Delete User
985 req.deleteUser = true;
989 ParseAnyString(optarg, &str, "koi8-ru");
994 ParseAnyString(optarg, &str, "koi8-ru");
999 ParseAnyString(optarg, &str, "koi8-ru");
1004 ParseAnyString(optarg, &str, "koi8-ru");
1006 //printf("EMAIL=%s\n", optarg);
1010 ParseAnyString(optarg, &str);
1015 ParseAnyString(optarg, &str, "koi8-ru");
1019 case 'I': //IP-address of user
1020 ParseAnyString(optarg, &str);
1025 req.disableDetailStat = ParseDownPassive(optarg);
1029 req.alwaysOnline = ParseDownPassive(optarg);
1033 SetArrayItem(req.sessionUpload, optarg, ParseTraff(argv[optind++]));
1034 //req.sessionUpload[optarg] = ParseTraff(argv[optind++]);
1037 SetArrayItem(req.sessionDownload, optarg, ParseTraff(argv[optind++]));
1038 //req.sessionDownload[optarg] = ParseTraff(argv[optind++]);
1041 SetArrayItem(req.monthUpload, optarg, ParseTraff(argv[optind++]));
1042 //req.monthUpload[optarg] = ParseTraff(argv[optind++]);
1045 SetArrayItem(req.monthDownload, optarg, ParseTraff(argv[optind++]));
1046 //req.monthDownload[optarg] = ParseTraff(argv[optind++]);
1049 case 700: //UserData
1050 ParseAnyString(argv[optind++], &str);
1051 SetArrayItem(req.userData, optarg, str);
1052 //req.userData[optarg] = str;
1056 missedOptionArg = true;
1060 missedOptionArg = true;
1064 printf("?? getopt returned character code 0%o ??\n", c);
1070 printf ("non-option ARGV-elements: ");
1071 while (optind < argc)
1072 printf ("%s ", argv[optind++]);
1074 exit(PARAMETER_PARSING_ERR_CODE);
1077 if (missedOptionArg || !CheckParametersSet(&req))
1079 //printf("Parameter needed\n");
1081 exit(PARAMETER_PARSING_ERR_CODE);
1084 const int rLen = 20000;
1086 memset(rstr, 0, rLen);
1088 CreateRequestSet(&req, rstr);
1090 return ProcessSendMessage(req.server, req.port, req.admLogin, req.admPasswd, rstr);
1092 return ProcessSetUser(req.server, req.port, req.admLogin, req.admPasswd, rstr);
1094 //-----------------------------------------------------------------------------
1095 int main(int argc, char **argv)
1100 exit(PARAMETER_PARSING_ERR_CODE);
1103 if (strcmp(argv[1], "get") == 0)
1106 return mainGet(argc - 1, argv + 1);
1108 else if (strcmp(argv[1], "set") == 0)
1111 if (mainSet(argc - 1, argv + 1) )
1118 exit(PARAMETER_PARSING_ERR_CODE);
1120 return UNKNOWN_ERR_CODE;
1122 //-----------------------------------------------------------------------------