]> git.stg.codes - stg.git/blob - projects/sgconf/common_sg.cpp
Better handling of errors from server. Refactoring.
[stg.git] / projects / sgconf / common_sg.cpp
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21  /*
22  $Author: faust $
23  $Revision: 1.12 $
24  $Date: 2009/06/08 10:02:28 $
25  */
26
27
28 #include "sg_error_codes.h"
29 #include "common_sg.h"
30 #include "version_sg.h"
31
32 #include "stg/common.h"
33
34 #include <iostream>
35 #include <vector>
36
37 #include <cstdio>
38 #include <cstring>
39 #include <cstdlib>
40 #include <cerrno>
41 #include <clocale>
42
43 #include <langinfo.h>
44 #include <iconv.h>
45
46 const int usageConf = 0;
47 const int usageInfo = 1;
48
49 const int TO_KOI8 = 0;
50 const int FROM_KOI8 = 1;
51 //-----------------------------------------------------------------------------
52 struct GetUserData
53 {
54     GetUserData(REQUEST & req, bool res) : request(req), result(res) {}
55     REQUEST & request;
56     bool result;
57 };
58 //---------------------------------------------------------------------------
59 struct HelpParams
60 {
61     std::string setActionName;
62     std::string getActionName;
63     std::string valueName;
64     std::string valueParam;
65 };
66 //---------------------------------------------------------------------------
67 void Usage(int usageType)
68 {
69 printf("Sgconf version: %s\n\n", VERSION_SG);
70
71 char action[4];
72 if (usageType == usageConf)
73     strcpy(action, "set");
74 else
75     strcpy(action, "get");
76
77 printf("To add or to set cash use:\n");
78 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -c <add_cash[:log message]>\n");
79 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -v <set_cash[:log message]>\n");
80 printf("To get cash use:\n");
81 printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -c\n\n");
82
83 HelpParams hp[] =
84 {
85     {"set tariff",              "get tariff",           "-t",   "<tariff:now|delayed>"},
86     {"set credit",              "get credit",           "-r",   "<credit>"},
87     {"set credit expire",       "get credit expire",    "-E",   "<credit_expire_date>"},
88     {"set password",            "get password",         "-o",   "<new_password>"},
89     {"set prepaid traffic",     "get prepaid traffic",  "-e",   "<prepaid>"},
90     {"set IP-addresses",        "get IP-addresses",     "-I",   "<*|ip_addr[,ip_addr...]>"},
91     {"set name",                "get name",             "-A",   "<name>"},
92     {"set note",                "get note",             "-N",   "<note>"},
93     {"set street address",      "get street address",   "-D",   "<address>"},
94     {"set email",               "get email",            "-L",   "<email>"},
95     {"set phone",               "get phone",            "-P",   "<phone>"},
96     {"set group",               "get group",            "-G",   "<group>"},
97     {"set/unset down",          "get down",             "-d",   "<0/1>"},
98     {"set/unset \'passive\'",   "get \'passive\'",      "-i",   "<0/1>"},
99     {"set/unset \'disableDetailStat\'",   "get \'disableDetailStat\'",      "--disable-stat",   "<0/1>"},
100     {"set/unset \'alwaysOnline\'",   "get \'alwaysOnline\'",      "--always-online",   "<0/1>"},
101 };
102
103 for (unsigned i = 0; i < sizeof(hp) / sizeof(HelpParams); i++)
104     {
105     printf("To %s use:\n", hp[i].setActionName.c_str());
106     printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> %s %s\n",
107            hp[i].valueName.c_str(), hp[i].valueParam.c_str());
108     printf("To %s use:\n", hp[i].getActionName.c_str());
109     printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> %s\n\n",
110            hp[i].valueName.c_str());
111     }
112
113 printf("To set user\'s upload traffic value use:\n");
114 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --u0 <traff> [--u1<traff> ...]\n");
115 printf("To get user\'s upload traffic value use:\n");
116 printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --u0 [--u1 ...]\n\n");
117
118 printf("To set user\'s download traffic value use:\n");
119 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --d0 <traff> [--d1<traff> ...]\n");
120 printf("To get user\'s download traffic value use:\n");
121 printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --d0 [--d1 ...]\n\n");
122
123 printf("To set userdata<0...9> use:\n");
124 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --ud0 <userdata> [--ud1<userdata> ...]\n");
125 printf("To get userdata<0...9> use:\n");
126 printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --ud0 [--ud1 ...]\n\n");
127
128 printf("To get user's authorizers list use:\n");
129 printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --authorized-by\n\n");
130
131 printf("To send message use:\n");
132 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -m <message>\n\n");
133
134 printf("To create user use:\n");
135 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -n\n\n");
136
137 printf("To delete user use:\n");
138 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -l\n\n");
139 }
140 //---------------------------------------------------------------------------
141 void UsageConf()
142 {
143 Usage(usageConf);
144 }
145 //---------------------------------------------------------------------------
146 void UsageInfo()
147 {
148 Usage(usageInfo);
149 }
150 //---------------------------------------------------------------------------
151 int CheckLogin(const char * login)
152 {
153 for (int i = 0; i < (int)strlen(login); i++)
154     {
155     if (!(( login[i] >= 'a' && login[i] <= 'z')
156         || (login[i] >= 'A' && login[i] <= 'Z')
157         || (login[i] >= '0' && login[i] <= '9')
158         ||  login[i] == '.'
159         ||  login[i] == '_'
160         ||  login[i] == '-'))
161         {
162         return 1;
163         }
164     }
165 return 0;
166 }
167 //-----------------------------------------------------------------------------
168 short int ParseServerPort(const char * p)
169 {
170 int port;
171 if (str2x(p, port) != 0)
172     {
173     printf("Incorrect server port %s\n", p);
174     exit(NETWORK_ERR_CODE);
175     }
176 return (short)port;
177 }
178 //-----------------------------------------------------------------------------
179 char * ParseAdminLogin(char * adm)
180 {
181 if (CheckLogin(adm))
182     {
183     printf("Incorrect admin login %s\n", adm);
184     exit(PARAMETER_PARSING_ERR_CODE);
185     }
186 return adm;
187 }
188 //-----------------------------------------------------------------------------
189 char * ParsePassword(char * pass)
190 {
191 if (strlen(pass) >= ADM_PASSWD_LEN)
192     {
193     printf("Password too big %s\n", pass);
194     exit(PARAMETER_PARSING_ERR_CODE);
195     }
196
197 return pass;
198 }
199 //-----------------------------------------------------------------------------
200 char * ParseUser(char * usr)
201 {
202 if (CheckLogin(usr))
203     {
204     printf("Incorrect user login %s\n", usr);
205     exit(PARAMETER_PARSING_ERR_CODE);
206     }
207 return usr;
208 }
209 //-----------------------------------------------------------------------------
210 void ConvertKOI8(const std::string & src, std::string * dst, int encType)
211 {
212 iconv_t cd;
213 char * ob = new char[src.size() * 2 + 1];
214 char * ib = new char[src.size() + 1];
215
216 strcpy(ib, src.c_str());
217
218 char * outbuf = ob;
219 char * inbuf = ib;
220
221 setlocale(LC_ALL, "");
222
223 char charsetF[100];
224 char charsetT[100];
225
226 if (encType == TO_KOI8)
227     {
228     strcpy(charsetF, nl_langinfo(CODESET));
229     strcpy(charsetT, "koi8-ru");
230     }
231 else
232     {
233     strcpy(charsetT, nl_langinfo(CODESET));
234     strcpy(charsetF, "koi8-ru");
235     }
236
237 size_t nconv = 1;
238
239 size_t insize = strlen(ib);
240 size_t outsize = insize * 2 + 1;
241
242 insize = src.size();
243
244 cd = iconv_open(charsetT, charsetF);
245 if (cd == (iconv_t) -1)
246     {
247     if (errno != EINVAL)
248         printf("error iconv_open\n");
249     else
250         {
251         printf("Warning: iconv from %s to %s failed\n", charsetF, charsetT);
252         *dst = src;
253         return;
254         }
255
256     exit(ICONV_ERR_CODE);
257     }
258
259 #if defined(FREE_BSD) || defined(FREE_BSD5)
260 nconv = iconv(cd, (const char **)&inbuf, &insize, &outbuf, &outsize);
261 #else
262 nconv = iconv(cd, &inbuf, &insize, &outbuf, &outsize);
263 #endif
264 //printf("charsetT=%s charsetF=%s\n", charsetT, charsetF);
265 //printf("ib=%s ob=%s\n", ib, ob);
266 //printf("nconv=%d outsize=%d\n", nconv, outsize);
267 if (nconv == (size_t) -1)
268     {
269     if (errno != EINVAL)
270         {
271         printf("iconv error\n");
272         exit(ICONV_ERR_CODE);
273         }
274     }
275
276 *outbuf = L'\0';
277
278 iconv_close(cd);
279 *dst = ob;
280
281 delete[] ob;
282 delete[] ib;
283 }
284 //-----------------------------------------------------------------------------
285 void ConvertFromKOI8(const std::string & src, std::string * dst)
286 {
287 ConvertKOI8(src, dst, FROM_KOI8);
288 }
289 //-----------------------------------------------------------------------------
290 int RecvSetUserAnswer(const char * ans, void * d)
291 {
292 GetUserData * data = static_cast<GetUserData *>(d);
293
294 std::cout << ans << std::endl;
295
296 data->result = (strcasecmp("Ok", ans) == 0);
297
298 return 0;
299 }
300 //-----------------------------------------------------------------------------
301 struct StringReqParams
302 {
303     std::string name;
304     RESETABLE<std::string> reqParam;
305     const std::string * value;
306 };
307 //-----------------------------------------------------------------------------
308 void GetUserCallback(const PARSER_GET_USER::INFO & info, void * d)
309 {
310 GetUserData * data = static_cast<GetUserData *>(d);
311
312 if (info.login == "")
313     {
314     data->result = false;
315     return;
316     }
317
318 if (!data->request.cash.res_empty())
319     cout << "cash = " << info.cash << endl;
320
321 if (!data->request.credit.res_empty())
322     cout << "credit = " << info.credit << endl;
323
324 if (!data->request.creditExpire.res_empty())
325     {
326     char buf[32];
327     struct tm brokenTime;
328     time_t tt = info.creditExpire;
329
330     brokenTime.tm_wday = 0;
331     brokenTime.tm_yday = 0;
332     brokenTime.tm_isdst = 0;
333     brokenTime.tm_hour = 0;
334     brokenTime.tm_min = 0;
335     brokenTime.tm_sec = 0;
336
337     gmtime_r(&tt, &brokenTime);
338
339     strftime(buf, 32, "%Y-%m-%d", &brokenTime);
340
341     cout << "creditExpire = " << buf << endl;
342     }
343
344 if (!data->request.down.res_empty())
345     cout << "down = " << info.down << endl;
346
347 if (!data->request.passive.res_empty())
348     cout << "passive = " << info.passive << endl;
349
350 if (!data->request.disableDetailStat.res_empty())
351     cout << "disableDetailStat = " << info.disableDetailStat << endl;
352
353 if (!data->request.alwaysOnline.res_empty())
354     cout << "alwaysOnline = " << info.alwaysOnline << endl;
355
356 if (!data->request.prepaidTraff.res_empty())
357     cout << "prepaidTraff = " << info.prepaidTraff << endl;
358
359 for (int i = 0; i < DIR_NUM; i++)
360     {
361     if (!data->request.sessionUpload[i].res_empty())
362         cout << "session upload for dir " << i << " = " << info.stat.su[i] << endl;
363     if (!data->request.sessionDownload[i].res_empty())
364         cout << "session download for dir " << i << "=" << info.stat.sd[i] << endl;
365     }
366
367 for (int i = 0; i < DIR_NUM; i++)
368     {
369     if (!data->request.monthUpload[i].res_empty())
370         cout << "month upload for dir " << i << " = " << info.stat.mu[i] << endl;
371     if (!data->request.monthDownload[i].res_empty())
372         cout << "month download for dir " << i << " = " << info.stat.md[i] << endl;
373     }
374
375 for (int i = 0; i < USERDATA_NUM; i++)
376     {
377     if (!data->request.userData[i].res_empty())
378         {
379         std::string str;
380         ConvertFromKOI8(info.userData[i], &str);
381         cout << "user data " << i << " = " << str << endl;
382         }
383     }
384
385 StringReqParams strReqParams[] =
386 {
387     {"note",     data->request.note,        &info.note},
388     {"name",     data->request.name,        &info.name},
389     {"address",  data->request.address,     &info.address},
390     {"email",    data->request.email,       &info.email},
391     {"phone",    data->request.phone,       &info.phone},
392     {"group",    data->request.group,       &info.group},
393     {"tariff",   data->request.tariff,      &info.tariff},
394     {"password", data->request.usrPasswd,   &info.password},
395     {"ip",       data->request.ips,         &info.ips} // IP-address of user
396 };
397 for (unsigned i = 0; i < sizeof(strReqParams) / sizeof(StringReqParams); i++)
398     {
399     if (!strReqParams[i].reqParam.res_empty())
400         {
401         string str;
402         ConvertFromKOI8(*strReqParams[i].value, &str);
403         cout << strReqParams[i].name << " = " << str << endl;
404         }
405     }
406 data->result = true;
407 }
408 //-----------------------------------------------------------------------------
409 void RecvAuthByData(const PARSER_AUTH_BY::INFO & list, void *)
410 {
411 for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
412     cout << *it << "\n";
413 cout << endl;
414 }
415 //-----------------------------------------------------------------------------
416 int ProcessSetUser(const std::string &server,
417                    int port,
418                    const std::string &admLogin,
419                    const std::string &admPasswd,
420                    const std::string &str,
421                    bool isMessage)
422 {
423 SERVCONF sc;
424
425 sc.SetServer(server.c_str());
426 sc.SetPort(port);
427 sc.SetAdmLogin(admLogin.c_str());
428 sc.SetAdmPassword(admPasswd.c_str());
429
430 REQUEST request;
431 GetUserData cbdata(request, false);
432
433 int res = 0;
434 if (isMessage)
435     {
436     sc.SetSendMessageCallback(RecvSetUserAnswer, &cbdata);
437     res = sc.SendMessage(str.c_str());
438     }
439 else
440     {
441     sc.SetChgUserCallback(RecvSetUserAnswer, &cbdata);
442     res = sc.ChgUser(str.c_str());
443     }
444
445 if (res == st_ok && cbdata.result)
446     {
447     printf("Ok\n");
448     return 0;
449     }
450 else
451     {
452     printf("Error\n");
453     if (res != st_ok)
454         printf("%s\n", sc.GetStrError().c_str());
455     return -1;
456     }
457
458 return 0;
459 }
460 //-----------------------------------------------------------------------------
461 int ProcessGetUser(const std::string &server,
462                    int port,
463                    const std::string &admLogin,
464                    const std::string &admPasswd,
465                    const std::string &login,
466                    REQUEST & request)
467 {
468 SERVCONF sc;
469
470 sc.SetServer(server.c_str());
471 sc.SetPort(port);
472 sc.SetAdmLogin(admLogin.c_str());
473 sc.SetAdmPassword(admPasswd.c_str());
474
475 GetUserData data(request, false);
476
477 sc.SetGetUserCallback(GetUserCallback, &data);
478 bool res = (sc.GetUser(login.c_str()) == st_ok);
479
480 if (res && data.result)
481     {
482     printf("Ok\n");
483     return 0;
484     }
485 else
486     {
487     printf("Error\n");
488     return -1;
489     }
490
491 return 0;
492 }
493 //-----------------------------------------------------------------------------
494 int ProcessAuthBy(const std::string &server,
495                   int port,
496                   const std::string &admLogin,
497                   const std::string &admPasswd,
498                   const std::string &login)
499 {
500 SERVCONF sc;
501
502 sc.SetServer(server.c_str());
503 sc.SetPort(port);
504 sc.SetAdmLogin(admLogin.c_str());
505 sc.SetAdmPassword(admPasswd.c_str());
506
507 sc.SetAuthByCallback(RecvAuthByData, NULL);
508 bool res = (sc.AuthBy(login.c_str()) == st_ok);
509
510 if (!res)
511     {
512     printf("Error\n");
513     return -1;
514     }
515
516 printf("Ok\n");
517 return 0;
518 }
519 //-----------------------------------------------------------------------------