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 struct option long_options_get[] = {
78 {"server", 1, 0, 's'}, //Server
79 {"port", 1, 0, 'p'}, //Port
80 {"admin", 1, 0, 'a'}, //Admin
81 {"admin_pass", 1, 0, 'w'}, //passWord
82 {"user", 1, 0, 'u'}, //User
83 {"addcash", 0, 0, 'c'}, //Add Cash
84 //{"setcash", 0, 0, 'v'}, //Set Cash
85 {"credit", 0, 0, 'r'}, //cRedit
86 {"tariff", 0, 0, 't'}, //Tariff
87 {"message", 0, 0, 'm'}, //message
88 {"password", 0, 0, 'o'}, //password
89 {"down", 0, 0, 'd'}, //down
90 {"passive", 0, 0, 'i'}, //passive
91 {"disable-stat",0, 0, 'S'}, //disable detail stat
92 {"always-online",0, 0, 'O'}, //always online
93 {"session-upload", 1, 0, 500}, //SU0
94 {"session-download", 1, 0, 501}, //SD0
95 {"month-upload", 1, 0, 502}, //MU0
96 {"month-download", 1, 0, 503}, //MD0
98 {"user-data", 1, 0, 700}, //UserData0
100 {"prepaid", 0, 0, 'e'}, //prepaid traff
101 {"create", 0, 0, 'n'}, //create
102 {"delete", 0, 0, 'l'}, //delete
104 {"note", 0, 0, 'N'}, //Note
105 {"name", 0, 0, 'A'}, //nAme
106 {"address", 0, 0, 'D'}, //aDdress
107 {"email", 0, 0, 'L'}, //emaiL
108 {"phone", 0, 0, 'P'}, //phone
109 {"group", 0, 0, 'G'}, //Group
110 {"ip", 0, 0, 'I'}, //IP-address of user
111 {"authorized-by",0, 0, 800}, //always online
115 struct option long_options_set[] = {
116 {"server", 1, 0, 's'}, //Server
117 {"port", 1, 0, 'p'}, //Port
118 {"admin", 1, 0, 'a'}, //Admin
119 {"admin_pass", 1, 0, 'w'}, //passWord
120 {"user", 1, 0, 'u'}, //User
121 {"addcash", 1, 0, 'c'}, //Add Cash
122 {"setcash", 1, 0, 'v'}, //Set Cash
123 {"credit", 1, 0, 'r'}, //cRedit
124 {"tariff", 1, 0, 't'}, //Tariff
125 {"message", 1, 0, 'm'}, //message
126 {"password", 1, 0, 'o'}, //password
127 {"down", 1, 0, 'd'}, //down
128 {"passive", 1, 0, 'i'}, //passive
129 {"disable-stat",1, 0, 'S'}, //disable detail stat
130 {"always-online",1, 0, 'O'}, //always online
131 {"session-upload", 1, 0, 500}, //U0
132 {"session-download", 1, 0, 501}, //U1
133 {"month-upload", 1, 0, 502}, //U2
134 {"month-download", 1, 0, 503}, //U3
136 {"user-data", 1, 0, 700}, //UserData
138 {"prepaid", 1, 0, 'e'}, //prepaid traff
139 {"create", 1, 0, 'n'}, //create
140 {"delete", 1, 0, 'l'}, //delete
142 {"note", 1, 0, 'N'}, //Note
143 {"name", 1, 0, 'A'}, //nAme
144 {"address", 1, 0, 'D'}, //aDdress
145 {"email", 1, 0, 'L'}, //emaiL
146 {"phone", 1, 0, 'P'}, //phone
147 {"group", 1, 0, 'G'}, //Group
148 {"ip", 0, 0, 'I'}, //IP-address of user
152 //-----------------------------------------------------------------------------
153 double ParseCash(const char * c, string * message)
155 //-c 123.45:log message
159 str = new char[strlen(c) + 1];
161 strncpy(str, c, strlen(c));
164 msg = strchr(str, ':');
174 if (strtodouble2(str, cash) != 0)
176 printf("Incorrect cash value %s\n", c);
177 exit(PARAMETER_PARSING_ERR_CODE);
183 //-----------------------------------------------------------------------------
184 double ParseCredit(const char * c)
187 if (strtodouble2(c, credit) != 0)
189 printf("Incorrect credit value %s\n", c);
190 exit(PARAMETER_PARSING_ERR_CODE);
195 //-----------------------------------------------------------------------------
196 double ParsePrepaidTraffic(const char * c)
199 if (strtodouble2(c, credit) != 0)
201 printf("Incorrect prepaid traffic value %s\n", c);
202 exit(PARAMETER_PARSING_ERR_CODE);
207 //-----------------------------------------------------------------------------
208 int64_t ParseTraff(const char * c)
211 if (str2x(c, traff) != 0)
213 printf("Incorrect credit value %s\n", c);
214 exit(PARAMETER_PARSING_ERR_CODE);
219 //-----------------------------------------------------------------------------
220 bool ParseDownPassive(const char * dp)
222 if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
224 printf("Incorrect value %s\n", dp);
225 exit(PARAMETER_PARSING_ERR_CODE);
230 //-----------------------------------------------------------------------------
231 string ParseTariff(const char * t, int &chgType)
243 if (strlen(s1) >= TARIFF_NAME_LEN)
245 printf("Tariff name too big %s\n", s1);
246 exit(PARAMETER_PARSING_ERR_CODE);
253 printf("Incorrect tariff value %s\n", t);
254 exit(PARAMETER_PARSING_ERR_CODE);
257 s2 = strtok(NULL, ":");
263 chgType = TARIFF_NOW;
270 if (strcmp(s2, "now") == 0)
271 chgType = TARIFF_NOW;
273 if (strcmp(s2, "delayed") == 0)
274 chgType = TARIFF_DEL;
276 if (strcmp(s2, "recalc") == 0)
277 chgType = TARIFF_REC;
281 printf("Incorrect tariff value %s\n", t);
282 exit(PARAMETER_PARSING_ERR_CODE);
289 //-----------------------------------------------------------------------------
290 time_t ParseCreditExpire(const char * str)
292 struct tm brokenTime;
294 brokenTime.tm_wday = 0;
295 brokenTime.tm_yday = 0;
296 brokenTime.tm_isdst = 0;
297 brokenTime.tm_hour = 0;
298 brokenTime.tm_min = 0;
299 brokenTime.tm_sec = 0;
301 stg_strptime(str, "%Y-%m-%d", &brokenTime);
303 return stg_timegm(&brokenTime);
305 //-----------------------------------------------------------------------------
306 void ParseAnyString(const char * c, string * msg, const char * enc)
309 char * ob = new char[strlen(c) + 1];
310 char * ib = new char[strlen(c) + 1];
317 setlocale(LC_ALL, "");
320 strncpy(charsetF, nl_langinfo(CODESET), 255);
322 const char * charsetT = enc;
326 size_t insize = strlen(ib);
327 size_t outsize = strlen(ib);
331 cd = iconv_open(charsetT, charsetF);
332 if (cd == (iconv_t) -1)
336 printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
341 printf("error iconv_open\n");
343 exit(ICONV_ERR_CODE);
346 #if defined(FREE_BSD) || defined(FREE_BSD5)
347 nconv = iconv (cd, (const char**)&inbuf, &insize, &outbuf, &outsize);
349 nconv = iconv (cd, &inbuf, &insize, &outbuf, &outsize);
351 //printf("nconv=%d outsize=%d\n", nconv, outsize);
352 if (nconv == (size_t) -1)
356 printf("iconv error\n");
357 exit(ICONV_ERR_CODE);
369 //-----------------------------------------------------------------------------
370 void CreateRequestSet(REQUEST * req, char * r)
372 const int strLen = 10024;
374 memset(str, 0, strLen);
378 if (!req->usrMsg.empty())
381 Encode12str(msg, req->usrMsg.data());
382 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());
383 //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
390 sprintf(str, "<DelUser login=\"%s\"/>", req->login.const_data().c_str());
398 sprintf(str, "<AddUser> <login value=\"%s\"/> </AddUser>", req->login.const_data().c_str());
404 strcat(r, "<SetUser>\n");
405 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
407 if (!req->credit.empty())
409 sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
413 if (!req->creditExpire.empty())
415 sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
419 if (!req->prepaidTraff.empty())
421 sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
425 if (!req->cash.empty())
428 Encode12str(msg, req->message);
429 sprintf(str, "<cash add=\"%f\" msg=\"%s\"/>\n", req->cash.const_data(), msg.c_str());
433 if (!req->setCash.empty())
436 Encode12str(msg, req->message);
437 sprintf(str, "<cash set=\"%f\" msg=\"%s\"/>\n", req->setCash.const_data(), msg.c_str());
441 if (!req->usrPasswd.empty())
443 sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
447 if (!req->down.empty())
449 sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
453 if (!req->passive.empty())
455 sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
459 if (!req->disableDetailStat.empty())
461 sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
465 if (!req->alwaysOnline.empty())
467 sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
471 // IP-address of user
472 if (!req->ips.empty())
474 sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
478 int uPresent = false;
479 int dPresent = false;
480 for (int i = 0; i < DIR_NUM; i++)
482 if (!req->monthUpload[i].empty())
484 if (!uPresent && !dPresent)
486 sprintf(str, "<traff ");
492 ss << req->monthUpload[i].const_data();
493 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
494 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
497 if (!req->monthDownload[i].empty())
499 if (!uPresent && !dPresent)
501 sprintf(str, "<traff ");
507 ss << req->monthDownload[i].const_data();
508 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
511 if (!req->sessionUpload[i].empty())
513 if (!uPresent && !dPresent)
515 sprintf(str, "<traff ");
521 ss << req->sessionUpload[i].const_data();
522 //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
523 sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
526 if (!req->sessionDownload[i].empty())
528 if (!uPresent && !dPresent)
530 sprintf(str, "<traff ");
536 ss << req->sessionDownload[i].const_data();
537 sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
541 if (uPresent || dPresent)
548 if (!req->tariff.empty())
550 switch (req->chgTariff)
553 sprintf(str, "<tariff now=\"%s\"/>\n", req->tariff.const_data().c_str());
557 sprintf(str, "<tariff recalc=\"%s\"/>\n", req->tariff.const_data().c_str());
561 sprintf(str, "<tariff delayed=\"%s\"/>\n", req->tariff.const_data().c_str());
568 if (!req->note.empty())
571 Encode12str(note, req->note.data());
572 sprintf(str, "<note value=\"%s\"/>", note.c_str());
576 if (!req->name.empty())
579 Encode12str(name, req->name.data());
580 sprintf(str, "<name value=\"%s\"/>", name.c_str());
584 if (!req->address.empty())
587 Encode12str(address, req->address.data());
588 sprintf(str, "<address value=\"%s\"/>", address.c_str());
592 if (!req->email.empty())
595 Encode12str(email, req->email.data());
596 sprintf(str, "<email value=\"%s\"/>", email.c_str());
600 if (!req->phone.empty())
603 Encode12str(phone, req->phone.data());
604 sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
608 if (!req->group.empty())
611 Encode12str(group, req->group.data());
612 sprintf(str, "<group value=\"%s\"/>", group.c_str());
616 for (int i = 0; i < USERDATA_NUM; i++)
618 if (!req->userData[i].empty())
621 Encode12str(ud, req->userData[i].data());
622 sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
627 strcat(r, "</SetUser>\n");
629 //-----------------------------------------------------------------------------
630 int CheckParameters(REQUEST * req)
637 bool a = !req->admLogin.empty()
638 && !req->admPasswd.empty()
639 && !req->server.empty()
640 && !req->port.empty()
641 && !req->login.empty();
643 bool b = !req->cash.empty()
644 || !req->setCash.empty()
645 || !req->credit.empty()
646 || !req->prepaidTraff.empty()
647 || !req->tariff.empty()
648 || !req->usrMsg.empty()
649 || !req->usrPasswd.empty()
651 || !req->note.empty()
652 || !req->name.empty()
653 || !req->address.empty()
654 || !req->email.empty()
655 || !req->phone.empty()
656 || !req->group.empty()
657 || !req->ips.empty() // IP-address of user
663 for (int i = 0; i < DIR_NUM; i++)
665 if (req->sessionUpload[i].empty())
672 for (int i = 0; i < DIR_NUM; i++)
674 if (req->sessionDownload[i].empty())
681 for (int i = 0; i < DIR_NUM; i++)
683 if (req->monthUpload[i].empty())
690 for (int i = 0; i < DIR_NUM; i++)
692 if (req->monthDownload[i].empty())
699 for (int i = 0; i < DIR_NUM; i++)
701 if (req->userData[i].empty())
709 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
710 return a && (b || su || sd || mu || md || ud);
712 //-----------------------------------------------------------------------------
713 int CheckParametersGet(REQUEST * req)
715 return CheckParameters(req);
717 //-----------------------------------------------------------------------------
718 int CheckParametersSet(REQUEST * req)
720 return CheckParameters(req);
722 //-----------------------------------------------------------------------------
723 bool mainGet(int argc, char **argv)
727 RESETABLE<string> t1;
728 int missedOptionArg = false;
730 const char * short_options_get = "s:p:a:w:u:crtmodieNADLPGISOE";
731 int option_index = -1;
736 c = getopt_long(argc, argv, short_options_get, long_options_get, &option_index);
747 req.port = ParseServerPort(optarg);
752 req.admLogin = ParseAdminLogin(optarg);
755 case 'w': //admin password
756 req.admPasswd = ParsePassword(optarg);
759 case 'o': //change user password
764 req.login = ParseUser(optarg);
775 case 'E': //credit expire
776 req.creditExpire = 1;
791 case 'e': //Prepaid Traffic
792 req.prepaidTraff = 1;
819 case 'I': //IP-address of user
823 case 'S': //Detail stat status
824 req.disableDetailStat = " ";
827 case 'O': //Always online status
828 req.alwaysOnline = " ";
832 SetArrayItem(req.sessionUpload, optarg, 1);
833 //req.sessionUpload[optarg] = 1;
836 SetArrayItem(req.sessionDownload, optarg, 1);
837 //req.sessionDownload[optarg] = 1;
840 SetArrayItem(req.monthUpload, optarg, 1);
841 //req.monthUpload[optarg] = 1;
844 SetArrayItem(req.monthDownload, optarg, 1);
845 //req.monthDownload[optarg] = 1;
849 SetArrayItem(req.userData, optarg, std::string(" "));
850 //req.userData[optarg] = " ";
859 missedOptionArg = true;
863 printf ("?? getopt returned character code 0%o ??\n", c);
869 printf ("non-option ARGV-elements: ");
870 while (optind < argc)
871 printf ("%s ", argv[optind++]);
873 exit(PARAMETER_PARSING_ERR_CODE);
876 if (missedOptionArg || !CheckParametersGet(&req))
878 //printf("Parameter needed\n");
880 exit(PARAMETER_PARSING_ERR_CODE);
884 return ProcessAuthBy(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data());
886 return ProcessGetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), req);
888 //-----------------------------------------------------------------------------
889 bool mainSet(int argc, char **argv)
894 bool isMessage = false;
897 RESETABLE<string> t1;
899 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:";
901 int missedOptionArg = false;
905 int option_index = -1;
907 c = getopt_long(argc, argv, short_options_set, long_options_set, &option_index);
919 req.port = ParseServerPort(optarg);
924 req.admLogin = ParseAdminLogin(optarg);
927 case 'w': //admin password
928 req.admPasswd = ParsePassword(optarg);
931 case 'o': //change user password
932 req.usrPasswd = ParsePassword(optarg);
936 req.login = ParseUser(optarg);
940 req.cash = ParseCash(optarg, &req.message);
944 req.setCash = ParseCash(optarg, &req.message);
948 req.credit = ParseCredit(optarg);
951 case 'E': //credit expire
952 req.creditExpire = ParseCreditExpire(optarg);
956 req.down = ParseDownPassive(optarg);
960 req.passive = ParseDownPassive(optarg);
964 req.tariff = ParseTariff(optarg, req.chgTariff);
968 ParseAnyString(optarg, &str);
973 case 'e': //Prepaid Traffic
974 req.prepaidTraff = ParsePrepaidTraffic(optarg);
977 case 'n': //Create User
978 req.createUser = true;
981 case 'l': //Delete User
982 req.deleteUser = true;
986 ParseAnyString(optarg, &str, "koi8-ru");
991 ParseAnyString(optarg, &str, "koi8-ru");
996 ParseAnyString(optarg, &str, "koi8-ru");
1001 ParseAnyString(optarg, &str, "koi8-ru");
1003 //printf("EMAIL=%s\n", optarg);
1007 ParseAnyString(optarg, &str);
1012 ParseAnyString(optarg, &str, "koi8-ru");
1016 case 'I': //IP-address of user
1017 ParseAnyString(optarg, &str);
1022 req.disableDetailStat = ParseDownPassive(optarg);
1026 req.alwaysOnline = ParseDownPassive(optarg);
1030 SetArrayItem(req.sessionUpload, optarg, ParseTraff(argv[optind++]));
1031 //req.sessionUpload[optarg] = ParseTraff(argv[optind++]);
1034 SetArrayItem(req.sessionDownload, optarg, ParseTraff(argv[optind++]));
1035 //req.sessionDownload[optarg] = ParseTraff(argv[optind++]);
1038 SetArrayItem(req.monthUpload, optarg, ParseTraff(argv[optind++]));
1039 //req.monthUpload[optarg] = ParseTraff(argv[optind++]);
1042 SetArrayItem(req.monthDownload, optarg, ParseTraff(argv[optind++]));
1043 //req.monthDownload[optarg] = ParseTraff(argv[optind++]);
1046 case 700: //UserData
1047 ParseAnyString(argv[optind++], &str);
1048 SetArrayItem(req.userData, optarg, str);
1049 //req.userData[optarg] = str;
1053 missedOptionArg = true;
1057 missedOptionArg = true;
1061 printf("?? getopt returned character code 0%o ??\n", c);
1067 printf ("non-option ARGV-elements: ");
1068 while (optind < argc)
1069 printf ("%s ", argv[optind++]);
1071 exit(PARAMETER_PARSING_ERR_CODE);
1074 if (missedOptionArg || !CheckParametersSet(&req))
1076 //printf("Parameter needed\n");
1078 exit(PARAMETER_PARSING_ERR_CODE);
1081 const int rLen = 20000;
1083 memset(rstr, 0, rLen);
1085 CreateRequestSet(&req, rstr);
1087 return ProcessSendMessage(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), rstr);
1089 return ProcessSetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), rstr);
1091 //-----------------------------------------------------------------------------
1092 int main(int argc, char **argv)
1097 exit(PARAMETER_PARSING_ERR_CODE);
1100 if (strcmp(argv[1], "get") == 0)
1103 return mainGet(argc - 1, argv + 1);
1105 else if (strcmp(argv[1], "set") == 0)
1108 if (mainSet(argc - 1, argv + 1) )
1115 exit(PARAMETER_PARSING_ERR_CODE);
1117 return UNKNOWN_ERR_CODE;
1119 //-----------------------------------------------------------------------------