Stranix 0 Posted 2006-04-07 19:04:50 Share Posted 2006-04-07 19:04:50 Нужно было реализовать перенос неистраченного бесплатного траффика на следующий месяц, а возможности установить freemb в КК не было... Поэтому решил немного модифицировать КК для того чтобы можно было менять скриптами любые параметры пользователя без перезагрузки сервера. Изменения заключаются в том, что выкинут код, формирующий запрос к серверу (его проще сформировать в скрипте) и запрос читается из файлика, кодируется и отсылается серверу. Изменился только файл main.cpp : #include <stdio.h> /* for printf */ #include <stdlib.h> /* for exit */ #include <getopt.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include "common.h" #include "netunit.h" #define FN_LEN 512 #define REQ_STR_LEN 300 char fileName[FN_LEN]; char * ParseServerAddress(char * a); short int ParseServerPort(const char * p); char * ParseAdminLogin(char * adm); char * ParseAdminPassword(char * pass); char * ParseUser(char * usr); int CheckLogin(const char * login); int Process(REQUEST * r); int CheckParameters(REQUEST * req); void ParseReply(const char * ans); void Usage(); void Encode12(char * dst, const char * src, int srcLen); struct option long_options[] = { {"server", 1, 0, 's'}, //Server {"port", 1, 0, 'p'}, //Port {"admin", 1, 0, 'a'}, //Admin {"admin_pass", 1, 0, 'w'}, //passWord {"file", 1, 0, 'f'}, //File {0, 0, 0, 0}}; int main (int argc, char **argv) { int c; int digit_optind = 0; REQUEST req; memset(&req, 0, sizeof(req)); while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; c = getopt_long(argc, argv, "s:p:a:w:f:", long_options, &option_index); if (c == -1) break; switch © { case 's': //server strcpy(req.server, ParseServerAddress(optarg)); req.serverReq = 1; break; case 'p': //port req.port = ParseServerPort(optarg); req.portReq = 1; break; case 'a': //admin strcpy(req.admLogin, ParseAdminLogin(optarg)); req.admLoginReq = 1; break; case 'w': //admon password strcpy(req.admPasswd, ParseAdminPassword(optarg)); req.admPasswdReq = 1; break; case 'f': //file strcpy(fileName,optarg); break; case '?': //printf ("Unknown option \n"); break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); exit(PARAMETER_PARSING_ERR_CODE); } if (CheckParameters(&req) == 0) { //printf("Parameter needed\n"); Usage(); exit(PARAMETER_PARSING_ERR_CODE); } Process(&req); return 0; } //----------------------------------------------------------------------------- char * ParseServerAddress(char * a) { /*long int addr = inet_addr(a); if(INADDR_NONE == addr) { printf("Incorrect server address %s\n", a); exit(NETWORK_ERR_CODE); }*/ if (strlen(a) >= SERVER_NAME_LEN) { printf("Server name too long %s\n", a); exit(PARAMETER_PARSING_ERR_CODE); } return a; } //----------------------------------------------------------------------------- short int ParseServerPort(const char * p) { int port; if (strtoi2(p, port) != 0) { printf("Incorresct server port %s\n", p); exit(NETWORK_ERR_CODE); } return (short)port; } //----------------------------------------------------------------------------- char * ParseAdminLogin(char * adm) { if (CheckLogin(adm)) { printf("Incorresct admin login %s\n", adm); exit(PARAMETER_PARSING_ERR_CODE); } return adm; } //----------------------------------------------------------------------------- char * ParseAdminPassword(char * pass) { if (strlen(pass) >= ADM_PASSWD_LEN) { printf("Password too big %s\n", pass); exit(PARAMETER_PARSING_ERR_CODE); } return pass; } //----------------------------------------------------------------------------- int CheckLogin(const char * login) { for (int i = 0; i < strlen(login); i++) { if (!(( login[i] >= 'a' && login[i] <= 'z') || (login[i] >= 'A' && login[i] <= 'Z') || (login[i] >= '0' && login[i] <= '9') || login[i] == '_')) { return 1; } } return 0; } //----------------------------------------------------------------------------- void FileRequest(char * r) { char str[1024]; FILE *f; r[0] = 0; f = NULL; f = fopen(fileName, "rt"); if (!f) { printf("Can't open request file\n"); exit(PARAMETER_PARSING_ERR_CODE); } char ts[REQ_STR_LEN]; while (fgets(ts, REQ_STR_LEN, f)) { strncat(r, ts, REQ_STR_LEN);} fclose(f); } int Process(REQUEST * r) { char str[2048]; NETTRANSACT nt; nt.SetServer(r->server); nt.SetServerPort(r->port); nt.SetLogin(r->admLogin); nt.SetPassword(r->admPasswd); nt.SetRxCallback(ParseReply); FileRequest(str); if (nt.Connect()) { printf("Connect failed.\n"); exit(NETWORK_ERR_CODE); } if (nt.Transact(str)) { printf("Login or password failed.\n"); exit(LOGIN_OR_PASS_ERR_CODE); } nt.Disconnect(); printf("Ok\n"); return 0; } //----------------------------------------------------------------------------- int CheckParameters(REQUEST * req) { int a = req->admLoginReq && req->admPasswdReq && req->serverReq && req->portReq; return a; } //----------------------------------------------------------------------------- void Usage() { printf("Use:\n"); printf("sgconf -s <server> -p <port> -a <admin> -w <admin_pass> -f <request_file>\n"); } Теперь для того чтобы, например установить счет пользователя, достаточно создать файл <SetUser> <login value="test"/> <cash set="10.0"/> </SetUser> и передать его в качесте параметра конфигуратору Link to post Share on other sites
p0int 0 Posted 2006-04-07 22:52:04 Share Posted 2006-04-07 22:52:04 хе прикольно а можешь еще примеры дать допустим изменение не денег а режима заморозить Link to post Share on other sites
Stranix 0 Posted 2006-04-07 23:02:51 Author Share Posted 2006-04-07 23:02:51 Про заморозку, немного непонятно как ее перевели... Вероятно: <SetUser> <login value="test"/> <passive value="1"/> </SetUser> А вообще хорошо бы на практике проверить все параметры, отрабатывают ли. Смотрю я их в файле parser.cpp в исходниках сервера. Link to post Share on other sites
XoRe 0 Posted 2006-04-09 11:45:11 Share Posted 2006-04-09 11:45:11 А есть идеи, как пользователя создавать? Link to post Share on other sites
Max 0 Posted 2006-04-09 12:16:49 Share Posted 2006-04-09 12:16:49 а что скажет автор? может включит данную фитчу в последующие релизы. Link to post Share on other sites
p0int 0 Posted 2006-04-10 14:25:26 Share Posted 2006-04-10 14:25:26 login NewLogin ip password address aonline cash CashExpire CreditExpire credit freemb down email userdata0 userdata1 group iface note passive phone Name traff tariff Это то что доступно, однако работать со строковымы параметрами у меня не вышло <SetUser> <login value="test"/> <address value="test"/> <iface value="eth0"/> </SetUser> в поле адреса вместо тест появляеться SB деньги интерфейс установка пасива и замарозки работает на ура и еще я как понял если вместо параметра логин отправлять параметр NewLorin по идеи должен регистрировать нового пользователя Link to post Share on other sites
Stranix 0 Posted 2006-04-10 20:07:06 Author Share Posted 2006-04-10 20:07:06 А со строковыми параметрами не так все просто. Для их кодирования применяется функция void Encode12(char * dst, const char * src, int srcLen) { char c1, c2; int i; for (i = 0; i <= srcLen; i++) { c1 = src[i] & 0x0f; c2 = (src[i] & 0xf0) >> 4; c1 += 'a'; c2 += 'a'; dst[i*2] = c1; dst[i*2 + 1] = c2; } dst[i*2] = 0; Вот ёё то и придется повторить в скрипте, чтобы иметь возможность отсылать серверу строковые параметры. А суть ее заключается в том что каждый байт кодируется в 2 буквы от 'a' до 'p' А для создания юзера, похоже, надо просто указать все параметры и заключить их в теги <AddUser> </AddUser> Link to post Share on other sites
karyon 48 Posted 2006-06-01 19:45:49 Share Posted 2006-06-01 19:45:49 <AddUser> <login value="login_name"/> <ip value=""/> <password value="123456"/> <phone value=""/> <email value=""/> <tariff value="ehbgchjggggg"/> <address value=""/> <note value=""/> <name value=""/> <userdata0 value=""/> <userdata1 value=""/> <cash value="0.0"/> <credit value="0.0"/> <iface value="eth0"/> <group value=""/> <passive value="0"/> <down value="0"/> <aonline value="0"/> </AddUser> Вот так работает добавление пользователя. В данном примере тариф=encode12("tariff") если послать <GetUser> <login value="login_name"/></GetUser> должно вернуть параметры пользователя Link to post Share on other sites
karyon 48 Posted 2006-06-02 20:09:13 Share Posted 2006-06-02 20:09:13 Для получения данных желательно подправить функцию в файле netunit.cpp: int NETTRANSACT::RxDataAnswer() { int n = 0; int ret; char bufferS[ENC_MSG_LEN]; char buffer[ENC_MSG_LEN]; BLOWFISH_CTX ctx; EnDecryptInit(password, PASSWD_LEN, &ctx); FILE *f=fopen("output.xml","w"); while (1) { ret = recv(outerSocket, &bufferS[n++], 1, 0); if (ret <= 0) { fclose(f); close(outerSocket); strcpy(errorMsg, RECV_DATA_ANSWER_ERROR); return 0; } if (n == 8) { n = 0; Decrypt(buffer, bufferS, &ctx); for (int j = 0; j < 8; j++) { if (buffer[j] == 0) { fwrite(buffer,j,1,f); if (RxCallBack) RxCallBack(answer); return st_ok; } } fwrite(buffer,8,1,f); } } } Полученные данные будут записаны в файл output.xml. <GetUser login="test"/> Вернет данные пользователя. Другие варианты запросов: GetServerInfo GetUsers GetTariffs GetTariff и тд Link to post Share on other sites
Колян 2 Posted 2007-05-07 18:28:58 Share Posted 2007-05-07 18:28:58 А кто опишет для СТГ 2.4 все хмл запросы? Буду благодарен Link to post Share on other sites
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now