From: Maxim Mamontov Date: Mon, 8 Nov 2010 10:30:53 +0000 (+0200) Subject: Добавляем XML-конфигуратор (уж много желающих, пусть будет, мне не жалко) X-Git-Tag: 2.407-rc3~379 X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/afb00c045e0ea58e39c0d7a7921bedbf26d1860d Добавляем XML-конфигуратор (уж много желающих, пусть будет, мне не жалко) --- diff --git a/projects/sgconf_xml/CHANGES b/projects/sgconf_xml/CHANGES new file mode 100644 index 00000000..e69de29b diff --git a/projects/sgconf_xml/Makefile b/projects/sgconf_xml/Makefile new file mode 100644 index 00000000..168bf9f4 --- /dev/null +++ b/projects/sgconf_xml/Makefile @@ -0,0 +1,102 @@ +############################################################################### +# $Id: Makefile,v 1.3 2008/05/11 09:30:43 nobunaga Exp $ +############################################################################### + +include ../../Makefile.conf + +PROG = sgconf + +SRCS = ./main.cpp \ + ./parser.cpp + +LIBS = -lconffiles \ + -lstg_crypto \ + -lstg_common \ + -lsrvconf + +ifeq ($(OS),linux) +LIBS += -lexpat \ + -lpthread \ + -ldl +endif + +ifeq ($(OS),bsd) +LIBS += -lexpat \ + -lc_r \ + -lc +endif + +ifeq ($(OS),bsd5) +LIBS += -lexpat \ + -lc_r \ + -lc +endif + +SEARCH_DIRS = -I $(DIR_INCLUDE) + +OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS)))) + +CC = g++ + +CFLAGS += -Wall +LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg + +vpath %.so $(DIR_LIB) + +.PHONY: all clean distclean libs install uninstall install-bin install-data uninstall-bin uninstall-data +all: libs $(PROG) ../../Makefile.conf + +libs: + $(MAKE) -C $(DIR_LIBSRC) + +$(PROG): $(OBJS) $(LIBS) + $(CC) $^ $(LDFLAGS) -o $(PROG) + +clean: + rm -f deps $(PROG) *.o tags *.*~ .OS + rm -f .OS + rm -f .store + rm -f .db.sql + rm -f core* + $(MAKE) -C $(DIR_LIBSRC) clean + +distclean: clean + rm -f ../../Makefile.conf + +install: install-bin install-data + +install-bin: + install -m $(BIN_MODE) -o $(OWNER) -s $(PROG) $(PREFIX)/usr/sbin/$(PROG) + $(MAKE) -C $(DIR_LIBSRC) install + +install-data: + # Install etc + install -m $(DATA_MODE) -o $(OWNER) -D $(ETC_DIR)/sgconf.conf $(PREFIX)/etc/stargazer/sgconf.conf + +uninstall: uninstall-bin uninstall-data + +uninstall-bin: + rm -f $(PREFIX)/usr/sbin/$(PROG) + +uninstall-data: + # Uninstall etc + rm -f $(PREFIX)/etc/stargazer/sgconf.conf + + +ifneq ($(MAKECMDGOALS),distclean) +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(MAKECMDGOALS),uninstall) +include deps +endif +endif +endif + +deps: $(SRCS) ../../Makefile.conf + $(MAKE) -C $(DIR_LIBSRC) includes + @>deps ;\ + for file in $(SRCS); do\ + echo "`$(CC) $(CFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\ + echo -e '\t$$(CC) -c $$< $(CFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\ + done + + diff --git a/projects/sgconf_xml/README.txt b/projects/sgconf_xml/README.txt new file mode 100644 index 00000000..cbdf9aca --- /dev/null +++ b/projects/sgconf_xml/README.txt @@ -0,0 +1,3 @@ +Compiling: +> ./build + diff --git a/projects/sgconf_xml/build b/projects/sgconf_xml/build new file mode 100755 index 00000000..cdd7e72a --- /dev/null +++ b/projects/sgconf_xml/build @@ -0,0 +1,128 @@ +#!/bin/sh + +# $Author: nobunaga $ +# $Revision: 1.2 $ +# $Date: 2008/01/05 12:11:02 $ +###################################################### + +OS=unknown +sys=`uname -s` +release=`uname -r | cut -b1` +BUILD_DIR=`pwd` +CONFFILE="../../Makefile.conf" +PREFIX="/" +BIN_MODE=0755 +DATA_MODE=0644 +OWNER=root + +if [ -z $1 ] +then + MAKEOPTS="-j1" + CFLAGS="-O2" +else + if [ "$1" = "debug" ] + then + DEFS="-DDEBUG" + MAKEOPTS="-j1" + CFLAGS="-g3" + else + MAKEOPTS="-j1" + CFLAGS="-O2" + fi +fi + +if [ "$sys" = "Linux" ] +then + OS=linux + release="" + ETC_DIR="./inst/linux/etc/stargazer" +fi + +if [ "$sys" = "FreeBSD" ] +then + case $release in + 4) OS=bsd;; + 5) OS=bsd5;; + 6) OS=bsd5;; + *) OS=unknown;; + esac + ETC_DIR="./inst/freebsd/etc/stargazer" +fi + +if [ "$OS" = "unknown" ] +then + echo "#############################################################################" + echo "# Sorry, but sgconf currently supported by Linux, FreeBSD 4.x, 5.x, 6.x #" + echo "#############################################################################" + exit 1 +fi + +echo "#############################################################################" +echo " Building sgconf for $sys $release" +echo "#############################################################################" + +STG_LIBS="conffiles.lib + crypto.lib + common.lib + srvconf.lib" + +if [ "$OS" = "linux" ] +then + DEFS="$DEFS -DLINUX" + LIB_THREAD=-lpthread + SHELL="/bin/bash" +else + if [ "$OS" = "bsd" ] + then + DEFS="$DEFS -DFREE_BSD" + else + DEFS="$DEFS -DFREE_BSD5" + fi + SHELL="/usr/local/bin/bash" + LIB_THREAD=-lc_r +fi + +echo -n "Checking for -lexpat... " +echo "int main() { return 0; }" > build_check.c +gcc build_check.c -lexpat -o fake > /dev/null 2> /dev/null +if [ $? != 0 ] +then + CHECK_EXPAT=no + echo "no" +else + CHECK_EXPAT=yes + echo "yes" +fi +rm -f fake +rm -f build_check.c + +if [ "$CHECK_EXPAT" != "yes" ] +then + echo "-lexpat not found!" + exit 1 +fi + +echo "OS=$OS" > $CONFFILE +echo "STG_TIME=no" >> $CONFFILE +echo "DIR_BUILD=$BUILD_DIR" >> $CONFFILE +echo "DIR_LIB=\$(DIR_BUILD)/../../lib" >> $CONFFILE +echo "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs" >> $CONFFILE +echo "DIR_INCLUDE=\$(DIR_BUILD)/../../include" >> $CONFFILE +echo "CHECK_EXPAT=$CHECK_EXPAT" >> $CONFFILE +echo "DEFS=$DEFS" >> $CONFFILE +echo -n "STG_LIBS=" >> $CONFFILE +for lib in $STG_LIBS +do + echo -n "$lib " >> $CONFFILE +done +echo "" >> $CONFFILE +echo "SHELL=$SHELL" >> $CONFFILE +echo "CFLAGS=$CFLAGS" >> $CONFFILE +echo "PREFIX=$PREFIX" >> $CONFFILE +echo "BIN_MODE=$BIN_MODE" >> $CONFFILE +echo "DATA_MODE=$DATA_MODE" >> $CONFFILE +echo "OWNER=$OWNER" >> $CONFFILE +echo "ETC_DIR=$ETC_DIR" >> $CONFFILE + +gmake $MAKEOPTS + diff --git a/projects/sgconf_xml/main.cpp b/projects/sgconf_xml/main.cpp new file mode 100644 index 00000000..751a7537 --- /dev/null +++ b/projects/sgconf_xml/main.cpp @@ -0,0 +1,326 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Boris Mikhailenko + */ + +/* +$Revision: 1.2 $ +$Author: nobunaga $ +$Date: 2008/01/05 12:11:34 $ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "request.h" +#include "common.h" +#include "netunit.h" + +#define FN_LEN (512) +#define REQ_STR_LEN (300) +char fileName[FN_LEN]; +char strReq[2048]; + +//int ParseReply(void * data, SLIST * ans); +int ParseReply(void * data, list * ans); + +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 +{"strreq", 1, 0, 'r'}, //String request +{0, 0, 0, 0}}; + +//----------------------------------------------------------------------------- +int CheckLogin(const char * login) +{ +for (int i = 0; i < (int)strlen(login); i++) + { + if (!(( login[i] >= 'a' && login[i] <= 'z') + || (login[i] >= 'A' && login[i] <= 'Z') + || (login[i] >= '0' && login[i] <= '9') + || login[i] == '_' + || login[i] == '-')) + { + return 1; + } + } +return 0; +} +//----------------------------------------------------------------------------- +short int ParseServerPort(const char * p) +{ +int port; +if (str2x(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("Incorrect admin login %s\n", adm); + exit(PARAMETER_PARSING_ERR_CODE); + } +return adm; +} +//----------------------------------------------------------------------------- +char * ParsePassword(char * pass) +{ +if (strlen(pass) >= ADM_PASSWD_LEN) + { + printf("Password too big %s\n", pass); + exit(PARAMETER_PARSING_ERR_CODE); + } + +return pass; +} +//----------------------------------------------------------------------------- +void CreateRequest(REQUEST * req, char * r) +{ +char str[10024]; +r[0] = 0; + +if (!req->strReq.res_empty()) + { + sprintf(str, "%s", req->strReq.const_data().c_str()); + strcat(r, str); + return; + } else + { + FILE *f; + 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 errorMsg[MAX_ERR_STR_LEN]; +int ret; +char str[2048]; + +NETTRANSACT nt; +nt.SetServer(r->server.const_data().c_str()); +nt.SetServerPort(r->port); +nt.SetLogin(r->admLogin.const_data().c_str()); +nt.SetPassword(r->admPasswd.const_data().c_str()); +nt.SetRxCallback(NULL, ParseReply); + +CreateRequest(r, str); + +if ((ret = nt.Connect()) != st_ok) + { + strncpy(errorMsg, nt.GetError(), MAX_ERR_STR_LEN); + printf("%s", errorMsg); + return ret; + } +if ((ret = nt.Transact(str)) != st_ok) + { + strncpy(errorMsg, nt.GetError(), MAX_ERR_STR_LEN); + printf("%s", errorMsg); + return ret; + } +if ((ret = nt.Disconnect()) != st_ok) + { + strncpy(errorMsg, nt.GetError(), MAX_ERR_STR_LEN); + printf("%s", errorMsg); + return ret; + } + +printf("\n"); +return 0; +} +//----------------------------------------------------------------------------- +int CheckParameters(REQUEST * req) +{ +int a = !req->admLogin.res_empty() + && !req->admPasswd.res_empty() + && !req->server.res_empty() + && !req->port.res_empty(); + +int b = !req->fileReq.res_empty() + || !req->strReq.res_empty(); + +return a && b; +} +//----------------------------------------------------------------------------- +void Usage() +{ +printf("Sgconf version: 1.05.9_XML\n\n"); + +printf("Use: sgconf -s -p -a -w -r \n"); +printf("Use: sgconf -s -p -a -w -f \n\n"); + +printf("Request file or string content:\n\n"); + +printf(" \n\n"); + +printf(" \n"); +printf(" \n"); +printf(" \n\n"); + +printf(" \n"); +printf(" Day-Night time for each DIR\n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" New TraffType value: [up|down|up+down|max]\n"); +printf(" \n\n"); + +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n\n"); + +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" Checking login and password in database. Return Ok or Err.\n\n"); + +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" delayed - change tariff from 1st day of new month; now - change tariff NOW.\n"); +printf(" Encode12() -> value\n"); +printf(" Encode12() -> value\n"); +printf("
Encode12() -> value\n"); +printf(" Encode12() -> value\n"); +printf(" Encode12() -> value\n"); +printf(" Encode12() -> value\n"); +printf(" Encode12() -> value\n"); +printf(" add - add money on account; set - set money on account; Message - message for log\n"); +printf(" \n"); +printf(" \n"); +printf(" \n"); +printf(" 1 - turn ON AlwaysOnline; 0 - turn OFF AlwaysOnline\n"); +printf(" 1 - turn ON Down; 0 - turn OFF Down\n"); +printf(" 1 - turn ON Passive; 0 - turn OFF Passive\n"); +printf(" MU[0...9] - Set upload traffic value; MU[0...9] - Set download traffic value; \n"); +printf(" \n\n"); + +printf(" \n"); +} +//--------------------------------------------------------------------------- +int main (int argc, char **argv) +{ +int c; +//int digit_optind = 0; +REQUEST req; + +while (1) + { + //int this_option_optind = optind ? optind : 1; + int option_index = -1; + + c = getopt_long(argc, argv, "s:p:a:w:f:r:", long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 's': //server + req.server = optarg; + break; + + case 'p': //port + req.port = ParseServerPort(optarg); + //req.portReq = 1; + break; + + case 'a': //admin + req.admLogin = ParseAdminLogin(optarg); + break; + + case 'w': //admin password + req.admPasswd = ParsePassword(optarg); + break; + + case 'f': //file + strcpy(fileName,optarg); + req.fileReq = 1; + break; + + case 'r': //string request + req.strReq = 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; +} +//----------------------------------------------------------------------------- + diff --git a/projects/sgconf_xml/parser.cpp b/projects/sgconf_xml/parser.cpp new file mode 100644 index 00000000..12a1c7a2 --- /dev/null +++ b/projects/sgconf_xml/parser.cpp @@ -0,0 +1,181 @@ +#include +#include +#include +#include + +#include "common.h" +#include "netunit.h" +#include "request.h" + +int parse_depth = 0; +XML_Parser parser; +//--------------------------------------------------------------------------- +int ParseAns(void * data, const char *el, const char **attr) +{ +if (strcasecmp(el, "ServerInfo") == 0 || strcasecmp(el, "Tariffs") == 0 || strcasecmp(el, "Admins") == 0 || strcasecmp(el, "Users") == 0 || strcasecmp(el, "user") == 0) + { + return 0; + } +if (strcasecmp(attr[1], "ok") == 0) + { + return 0; + } +if (strcasecmp(attr[1], "error") == 0) + { + return 1; + } +if (strcasecmp(attr[1], "err") == 0) + { + return 1; + } +return -1; +} +//--------------------------------------------------------------------------- +void StartElement(void *data, const char *el, const char **attr) +{ +if (strcasecmp(el, "ServerInfo") == 0 || strcasecmp(el, "Tariffs") == 0 || strcasecmp(el, "Admins") == 0 || strcasecmp(el, "Users") == 0) + { + printf ("<%s>\n", el); + return; + } + +if (strcasecmp(el, "tariff") == 0) + { + if (strcasecmp(attr[0], "name") == 0) + { + printf ("<%s %s=\"%s\">\n", el, attr[0], attr[1]); + printf ("<%s>%s\n", attr[0], attr[1], attr[0]); + } + else + { + printf ("<%s>%s", el, attr[1]); + } + return; + } + +if (strcasecmp(el, "admin") == 0) + { + printf ("<%s %s=\"%s\">\n", el, attr[0], attr[1]); + int i = 0; + while (attr[i]) + { + printf ("<%s>%s\n", attr[i], attr[i+1], attr[i]); + i+=2; + } + printf ("\n"); + return; + } + +if (strcasecmp(el, "user") == 0) + { + if (strcasecmp(attr[0], "login") == 0) + { + printf ("<%s %s=\"%s\">\n", el, attr[0], attr[1]); + printf ("<%s>%s\n", attr[0], attr[1], attr[0]); + } + else + { + printf ("<%s>\n", el); + } + return; + } + +if (strncasecmp(el, "dir_name_", 9) == 0 || strcasecmp(el, "address") == 0 || strcasecmp(el, "email") == 0 || strcasecmp(el, "group") == 0 || strcasecmp(el, "note") == 0 || strcasecmp(el, "phone") == 0 || strcasecmp(el, "name") == 0 || strncasecmp(el, "UserData", 8) == 0) + { + char * str_tmp; + str_tmp = new char[strlen(attr[1]) + 1]; + Decode21(str_tmp, attr[1]); + printf ("<%s>%s\n", el, str_tmp, el); + delete[] str_tmp; + return; + } + +if (strcasecmp(el, "traff") == 0) + { +// printf ("\n"); + int j = 0; + uint64_t t; + while (attr[j]) + { + str2x(attr[j+1], t); + printf ("<%s>%lld\n", attr[j], t, attr[j]); + j+=2; + } +// printf ("\n"); + return; + } +else + { + printf ("<%s>%s\n", el, attr[1], el); + return; + } +// } +parse_depth++; +if (parse_depth == 1) + { + if (ParseAns(data, el, attr) < 0) + { + printf("Unexpected token\n"); + exit(UNKNOWN_ERR_CODE); + } + if (ParseAns(data, el, attr) == 1) + { + printf("User not found\n"); + exit(USER_NOT_FOUND_ERR_CODE); + } + return; + } +} +//----------------------------------------------------------------------------- +void EndElement(void *data, const char *el) +{ +parse_depth--; +if (strcasecmp(el, "ServerInfo") == 0 || strcasecmp(el, "Tariffs") == 0 || strcasecmp(el, "Admins") == 0 || strcasecmp(el, "Users") == 0 || strcasecmp(el, "tariff") == 0 || strcasecmp(el, "user") == 0) + { + printf ("\n", el); + } +} +//--------------------------------------------------------------------------- +int ParseReply(void * data, list * ans) +//int ParseReply(void * data, SLIST * ans) +{ +//char answ[ENC_MSG_LEN + 1]; +int len; +int done = 0; + +parse_depth = 0; +parser = XML_ParserCreate(NULL); + +if (!parser) + { + printf("Couldn't allocate memory for parser\n"); + exit(UNKNOWN_ERR_CODE); + } + +XML_ParserReset(parser, NULL); +XML_SetElementHandler(parser, StartElement, EndElement); + +list::iterator n = ans->begin(); +while (n != ans->end()) + { + len = strlen(n->c_str()); + + if (++n == ans->end()) + done = 1; + n--; + + if (XML_Parse(parser, n->c_str(), len, done) == XML_STATUS_ERROR) + { + char s[128]; + printf(s, "Parse error at line %d: %s", + XML_GetCurrentLineNumber(parser), + XML_ErrorString(XML_GetErrorCode(parser))); + return st_xml_parse_error; + } + + ++n; + } +XML_ParserFree(parser); +return 0; +} +//----------------------------------------------------------------------------- diff --git a/projects/sgconf_xml/request.h b/projects/sgconf_xml/request.h new file mode 100644 index 00000000..17db9277 --- /dev/null +++ b/projects/sgconf_xml/request.h @@ -0,0 +1,78 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + + /* + $Revision: 1.1 $ + $Date: 2007/12/29 17:24:07 $ + */ + +#ifndef request_h +#define request_h + +#include +#include "resetable.h" + +#ifdef LINUX +#include +#endif + +#ifdef FREE_BSD5 +#include +#endif + +#ifdef FREE_BSD +#include +#endif + +#include "stg_const.h" + +#ifndef ENODATA +#define ENODATA 61 +#endif + +#ifndef EBADMSG +#define EBADMSG 74 +#endif + +#define NETWORK_ERR_CODE (1) +#define LOGIN_OR_PASS_ERR_CODE (2) +#define USER_NOT_FOUND_ERR_CODE (3) +#define TARIFF_NOT_FOUND_ERR_CODE (4) +#define PARAMETER_PARSING_ERR_CODE (5) +#define UNKNOWN_ERR_CODE (6) + +using namespace std; +//----------------------------------------------------------------------------- +struct REQUEST +{ +RESETABLE server; +RESETABLE port; +RESETABLE admLogin; +RESETABLE admPasswd; +RESETABLE fileReq; +RESETABLE strReq; +}; +//----------------------------------------------------------------------------- + +#endif diff --git a/projects/sgconf_xml/stg_req b/projects/sgconf_xml/stg_req new file mode 100644 index 00000000..8c1f8ae7 --- /dev/null +++ b/projects/sgconf_xml/stg_req @@ -0,0 +1 @@ + \ No newline at end of file