The sql code is integrated with the conf file, socket code, and initilization portions so far.
its not yet setup to export any of NeoStats structs, but you can test with this release with the built in tables: to test: ./configure --enable-sqlsrv add a line to neostats.cfg: SQLSRV_AUTH Fish!blah@127.0.0.* (username Fish, pass blah, host 127.0.0.* (IP only, can use wildcards) compile and start up NeoStats Check for any errors about unable to bind to ports etc.... (if you need to run on a diff port, add SQLSRV_PORT <portnum> to the neostats.cfg now that its running, from php/command line, connect to the BINDTO ip address (if using BINDTO) or 127.0.0.1 port 8888 eg: command line: psql -U Fish -h localhost -p 8888 it should prompt with a password. once connected, you can view available tables with: "select * from rta_tables;" some examples are: "select * from pg_user;" "select * from pg_conn;" "select * from rta_stat;" "select * from rta_dbg;" "select * from rta_columns;" Remember, only very basic SQL is supported
This commit is contained in:
parent
80349bd9be
commit
4d556d1714
17 changed files with 555 additions and 17 deletions
|
@ -38,6 +38,7 @@ NeoStats ChangeLog - Anything we add/remove/fix/change is in here (even our rant
|
|||
- AddUser changes to fix bug 94 (M)
|
||||
- New function UmodeMaskToString as a helper for Umode handling (M)
|
||||
- Import new SQL Server emulation library, Real Time Access. (F)
|
||||
- new configure option --enable-sqlsrv to enable sql server emulation
|
||||
|
||||
* NeoStats * Fish (F) * Version 2.5.10
|
||||
- Fix a problem with Umode +T being reintroduced on Unreal Beta19 as a normal usermode.
|
||||
|
|
|
@ -9,7 +9,7 @@ CURL_LDFLAGS = `curl/mycurl-config --libs`
|
|||
OBJS = dns.o chans.o dotconf.o services.o main.o sock.o conf.o ircd.o timer.o \
|
||||
users.o ns_help.o dl.o list.o hash.o server.o keeper.o log.o misc.o \
|
||||
support.o ircstring.o commands.o transfer.o\
|
||||
@IRCD_FILES_OBJS@
|
||||
@IRCD_FILES_OBJS@ @sqlsrvbuild@
|
||||
SRCS = dns.c chans.c dotconf.c services.c main.c sock.c conf.c ircd.c timer.c \
|
||||
users.c ns_help.c dl.c list.c hash.c server.c keeper.c log.c misc.c \
|
||||
support.c ircstring.c commands.c transfer.c\
|
||||
|
@ -51,7 +51,7 @@ DISTMOD = cs extauth hostserv loveserv ms statserv template
|
|||
$(CC) $(NEOINCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
|
||||
all: libadns.a libkeeper.a libpcre libcurl.a neostats modules utils
|
||||
all: @buildsqlsrv@ libadns.a libkeeper.a libpcre libcurl.a neostats modules utils
|
||||
|
||||
modules:
|
||||
(cd dl; $(MAKE) $@)
|
||||
|
@ -68,6 +68,9 @@ libpcre:
|
|||
libcurl.a:
|
||||
(cd curl; $(MAKE))
|
||||
|
||||
sqlsrvlib:
|
||||
(cd sqlsrv; $(MAKE))
|
||||
|
||||
utils:
|
||||
(cd tools; $(MAKE) $@)
|
||||
|
||||
|
@ -79,6 +82,7 @@ clean:
|
|||
(cd tools; $(MAKE) $@)
|
||||
(cd pcre; $(MAKE) $@)
|
||||
(cd curl; $(MAKE) $@)
|
||||
(cd sqlsrv; $(MAKE) $@)
|
||||
/bin/rm -rf *.o neostats *.cache Makefile config.h Makefile.inc *.log *.a
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ LD=ld
|
|||
LDFLAGS= -rdynamic @LIBS@
|
||||
MODLDFLAGS = -shared
|
||||
INSTALL = @INSTALL@
|
||||
NEOINCLUDES=-Iadns -Ikeeper -Icurl
|
||||
NEOINCLUDES=-I. -Iadns -Ikeeper -Icurl
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
MODULES=@MODULES@
|
||||
|
|
52
conf.c
52
conf.c
|
@ -29,9 +29,14 @@
|
|||
#include "dl.h"
|
||||
#include "log.h"
|
||||
#include "services.h"
|
||||
#ifdef SQLSRV
|
||||
#include "sqlsrv/rta.h"
|
||||
#endif
|
||||
|
||||
static void cb_Server (char *, int);
|
||||
static void cb_Module (char *, int);
|
||||
static void cb_SqlConf (char *, int);
|
||||
|
||||
/** @brief The list of modules to load
|
||||
*/
|
||||
static void *load_mods[NUM_MODULES];
|
||||
|
@ -58,6 +63,10 @@ static config_option options[] = {
|
|||
{"BINDTO", ARG_STR, cb_Server, 13},
|
||||
{"LOGFILENAMEFORMAT", ARG_STR, cb_Server, 14},
|
||||
{"SERVER_NUMERIC", ARG_STR, cb_Server, 15},
|
||||
#ifdef SQLSRV
|
||||
{"SQLSRV_AUTH", ARG_STR, cb_SqlConf, 0},
|
||||
{"SQLSRV_PORT", ARG_STR, cb_SqlConf, 1},
|
||||
#endif
|
||||
};
|
||||
|
||||
/** @brief initialize the configuration parser
|
||||
|
@ -116,7 +125,6 @@ ConfLoad ()
|
|||
* @param configtype an index of what config item is currently being processed. Ignored
|
||||
* @returns Nothing
|
||||
*/
|
||||
|
||||
void
|
||||
cb_Module (char *arg, int configtype)
|
||||
{
|
||||
|
@ -134,6 +142,48 @@ cb_Module (char *arg, int configtype)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLSRV
|
||||
/** @brief prepare SqlAuthentication defined in the config file
|
||||
*
|
||||
* load the Sql UserName/Password and Host if we are using SQL Server option
|
||||
*
|
||||
* @param arg the module name in this case
|
||||
* @param configtype an index of what config item is currently being processed. Ignored
|
||||
* @returns Nothing
|
||||
*/
|
||||
|
||||
void
|
||||
cb_SqlConf (char *arg, int configtype)
|
||||
{
|
||||
char *uname, *pass, *host;
|
||||
SET_SEGV_LOCATION();
|
||||
if (configtype == 0) {
|
||||
if ((uname = strtok(arg, "!")) == NULL) {
|
||||
nlog(LOG_WARNING, LOG_CORE, "Invalid SQLSRV_AUTH syntax in config file (Username)");
|
||||
return;
|
||||
}
|
||||
if ((pass = strtok(NULL, "@")) == NULL) {
|
||||
nlog(LOG_WARNING, LOG_CORE, "Invalid SQLSRV_AUTH syntax in config file (Pass)");
|
||||
return;
|
||||
}
|
||||
if ((host = strtok(NULL, "")) == NULL) {
|
||||
nlog(LOG_WARNING, LOG_CORE, "Invalid SQLSRV_AUTH syntax in config file (Host)");
|
||||
return;
|
||||
}
|
||||
nlog(LOG_DEBUG1, LOG_CORE, "SqlSrv Uname %s Pass %s Host %s", uname, pass, host);
|
||||
rta_change_auth(uname, pass);
|
||||
strncpy(me.sqlhost, host, MAXHOST);
|
||||
} else if (configtype == 1) {
|
||||
me.sqlport = atoi(arg);
|
||||
if (me.sqlport == 0) {
|
||||
nlog(LOG_WARNING, LOG_CORE, "Invalid Port Specified for SQLSRV_PORT, Using Default");
|
||||
me.sqlport = 8888;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
/** @brief Load the modules
|
||||
*
|
||||
* Actually load the modules that were found in the config file
|
||||
|
|
|
@ -176,3 +176,6 @@
|
|||
|
||||
/* have fgets_unlocked and friends? */
|
||||
#undef HAVE_UNLOCKED
|
||||
|
||||
/* if we are compiling with SQL support */
|
||||
#undef SQLSRV
|
||||
|
|
37
configure
vendored
37
configure
vendored
|
@ -309,7 +309,7 @@ ac_includes_default="\
|
|||
# include <unistd.h>
|
||||
#endif"
|
||||
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP RANLIB ac_ct_RANLIB EGREP GTK_CONFIG build_configtool DIRINST LINK_SIZE MATCH_LIMIT NEWLINE PCRE_MAJOR PCRE_MINOR PCRE_DATE PCRE_VERSION PCRE_LIB_VERSION PCRE_POSIXLIB_VERSION POSIX_MALLOC_THRESHOLD UTF8 IRCD_FILES_SRC IRCD_FILES_OBJS MODULES EXTAUTH_SRC EXTAUTH_OBJS PACKAGE VERSION LIBOBJS LTLIBOBJS'
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP RANLIB ac_ct_RANLIB EGREP sqlsrvbuild buildsqlsrv GTK_CONFIG build_configtool DIRINST LINK_SIZE MATCH_LIMIT NEWLINE PCRE_MAJOR PCRE_MINOR PCRE_DATE PCRE_VERSION PCRE_LIB_VERSION PCRE_POSIXLIB_VERSION POSIX_MALLOC_THRESHOLD UTF8 IRCD_FILES_SRC IRCD_FILES_OBJS MODULES EXTAUTH_SRC EXTAUTH_OBJS PACKAGE VERSION LIBOBJS LTLIBOBJS'
|
||||
ac_subst_files=''
|
||||
|
||||
# Initialize some variables set by options.
|
||||
|
@ -854,6 +854,7 @@ Optional Features:
|
|||
--enable-liquid - enable Liquid IRCD Support
|
||||
--enable-auth=TYPE - what type of Authentication to use. See Readme File
|
||||
--enable-raw - Enable Raw command
|
||||
--enable-sqlsrv - Enable Sql Server Emulation
|
||||
--enable-modules="MODULES" - space seperated list of modules to compile
|
||||
--enable-configtool - Enable building of the configtool program (Needs X windows)
|
||||
|
||||
|
@ -5559,6 +5560,38 @@ echo "${ECHO_T}no" >&6
|
|||
|
||||
fi;
|
||||
|
||||
|
||||
echo "$as_me:$LINENO: checking To Enable Sql Server Emulation?" >&5
|
||||
echo $ECHO_N "checking To Enable Sql Server Emulation?... $ECHO_C" >&6
|
||||
# Check whether --enable-sqlsrv or --disable-sqlsrv was given.
|
||||
if test "${enable_sqlsrv+set}" = set; then
|
||||
enableval="$enable_sqlsrv"
|
||||
case "$enableval" in
|
||||
yes)
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define SQLSRV 1
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: yes" >&5
|
||||
echo "${ECHO_T}yes" >&6
|
||||
sqlsrvbuild=sqlsrv/librtadb.a
|
||||
|
||||
buildsqlsrv=sqlsrvlib
|
||||
|
||||
;;
|
||||
*)
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
echo "$as_me:$LINENO: checking Any other modules to compile?" >&5
|
||||
echo $ECHO_N "checking Any other modules to compile?... $ECHO_C" >&6
|
||||
# Check whether --enable-modules or --disable-modules was given.
|
||||
|
@ -6330,6 +6363,8 @@ s,@CPP@,$CPP,;t t
|
|||
s,@RANLIB@,$RANLIB,;t t
|
||||
s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
|
||||
s,@EGREP@,$EGREP,;t t
|
||||
s,@sqlsrvbuild@,$sqlsrvbuild,;t t
|
||||
s,@buildsqlsrv@,$buildsqlsrv,;t t
|
||||
s,@GTK_CONFIG@,$GTK_CONFIG,;t t
|
||||
s,@build_configtool@,$build_configtool,;t t
|
||||
s,@DIRINST@,$DIRINST,;t t
|
||||
|
|
20
configure.in
20
configure.in
|
@ -377,6 +377,26 @@ esac],
|
|||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
|
||||
AC_MSG_CHECKING(To Enable Sql Server Emulation?)
|
||||
AC_ARG_ENABLE(sqlsrv, [ --enable-sqlsrv - Enable Sql Server Emulation],
|
||||
[ case "$enableval" in
|
||||
yes)
|
||||
AC_DEFINE(SQLSRV, 1, 'Use Sql Server Emulation')
|
||||
AC_MSG_RESULT(yes)
|
||||
sqlsrvbuild=sqlsrv/librtadb.a
|
||||
AC_SUBST(sqlsrvbuild)
|
||||
buildsqlsrv=sqlsrvlib
|
||||
AC_SUBST(buildsqlsrv)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac],
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
|
||||
dnl Lets see what Modules to Compile
|
||||
AC_MSG_CHECKING(Any other modules to compile?)
|
||||
AC_ARG_ENABLE(modules, [ --enable-modules="MODULES" - space seperated list of modules to compile],
|
||||
|
|
7
log.c
7
log.c
|
@ -230,3 +230,10 @@ nassert_fail (const char *expr, const char *file, const int line, const char *in
|
|||
nlog (LOG_CRITICAL, LOG_CORE, "Shutting Down!");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if SQLSRV
|
||||
/* this is for sqlserver logging callback */
|
||||
void sqlsrvlog(char *logline) {
|
||||
nlog(LOG_DEBUG1, LOG_CORE, "SqlSrv: %s", logline);
|
||||
}
|
||||
#endif
|
||||
|
|
4
log.h
4
log.h
|
@ -98,4 +98,8 @@ void reset_logs ();
|
|||
/* Configurable log filename format string */
|
||||
extern char LogFileNameFormat[MAX_LOGFILENAME];
|
||||
|
||||
#if SQLSRV
|
||||
void sqlsrvlog(char *logline);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
18
main.c
18
main.c
|
@ -1,4 +1,4 @@
|
|||
/* NeoStats - IRC Statistical Services
|
||||
/* NeoStats - IRC Statistical Services k
|
||||
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond
|
||||
** http://www.neostats.net/
|
||||
**
|
||||
|
@ -43,6 +43,11 @@
|
|||
#include "chans.h"
|
||||
#include "dns.h"
|
||||
#include "transfer.h"
|
||||
#ifdef SQLSRV
|
||||
#include "sqlsrv/rta.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* this is the name of the services bot */
|
||||
char s_Services[MAXNICK] = "NeoStats";
|
||||
/*! Date when we were compiled */
|
||||
|
@ -120,7 +125,9 @@ main (int argc, char *argv[])
|
|||
#ifdef ULTIMATE3
|
||||
me.client = 0;
|
||||
#endif
|
||||
|
||||
#ifdef SQLSRV
|
||||
me.sqlport = 8888;
|
||||
#endif
|
||||
/* if we are doing recv.log, remove the previous version */
|
||||
if (config.recvlog)
|
||||
remove (RECV_LOG);
|
||||
|
@ -133,6 +140,11 @@ main (int argc, char *argv[])
|
|||
/* prepare to catch errors */
|
||||
setup_signals ();
|
||||
|
||||
/* init the sql subsystem if used */
|
||||
#ifdef SQLSRV
|
||||
rta_init(sqlsrvlog);
|
||||
#endif
|
||||
|
||||
/* load the config files */
|
||||
if(ConfLoad () != NS_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
|
@ -376,7 +388,7 @@ void do_backtrace(void)
|
|||
int i;
|
||||
|
||||
nlog (LOG_CRITICAL, LOG_CORE, "Backtrace:");
|
||||
chanalert (s_Services, "Backtrace:", segv_location);
|
||||
chanalert (s_Services, "Backtrace: %s", segv_location);
|
||||
size = backtrace (array, 10);
|
||||
strings = backtrace_symbols (array, size);
|
||||
for (i = 1; i < size; i++) {
|
||||
|
|
358
sock.c
358
sock.c
|
@ -27,6 +27,10 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "stats.h"
|
||||
#include "dl.h"
|
||||
#include <adns.h>
|
||||
|
@ -36,6 +40,10 @@
|
|||
#include "dns.h"
|
||||
#include "transfer.h"
|
||||
#include "curl.h"
|
||||
#ifdef SQLSRV
|
||||
#include <fnmatch.h>
|
||||
#include "sqlsrv/rta.h"
|
||||
#endif
|
||||
|
||||
static void recvlog (char *line);
|
||||
|
||||
|
@ -45,7 +53,41 @@ static int dobind;
|
|||
int servsock;
|
||||
char recbuf[BUFSIZE];
|
||||
|
||||
|
||||
#ifdef SQLSRV
|
||||
|
||||
#define MAXSQLCON 5
|
||||
|
||||
/* sqlsrv struct for tracking connections */
|
||||
typedef struct Sql_Conn {
|
||||
struct sockaddr_in cliskt;
|
||||
int fd;
|
||||
long long nbytein;
|
||||
long long nbyteout;
|
||||
char response[50000];
|
||||
int responsefree;
|
||||
int cmdpos;
|
||||
int cmd[1000];
|
||||
int connid;
|
||||
} Sql_Conn;
|
||||
|
||||
int sqlListenSock;
|
||||
|
||||
list_t *sqlconnections;
|
||||
|
||||
|
||||
static void sql_accept_conn(int srvfd);
|
||||
static int sqllisten_on_port(int port);
|
||||
static int sql_handle_ui_request(lnode_t *sqlnode);
|
||||
static int sql_handle_ui_output(lnode_t *sqlnode);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/** @brief Connect to a server
|
||||
*
|
||||
* also setups the SQL listen socket if defined
|
||||
*
|
||||
* @param host to connect to
|
||||
* @param port on remote host to connect to
|
||||
|
@ -97,7 +139,16 @@ ConnectTo (char *host, int port)
|
|||
close (s);
|
||||
return NS_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef SQLSRV
|
||||
/* init the sql Listen Socket now as well */
|
||||
sqlconnections = list_create(MAXSQLCON);
|
||||
|
||||
sqlListenSock = sqllisten_on_port(me.sqlport);
|
||||
if (sqlListenSock == -1) {
|
||||
nlog(LOG_CRITICAL, LOG_CORE, "Failed to Setup Sql Port. SQL not available");
|
||||
}
|
||||
#endif
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -121,6 +172,10 @@ read_loop ()
|
|||
int pollsize, pollflag;
|
||||
hscan_t ss;
|
||||
hnode_t *sn;
|
||||
#ifdef SQLSRV
|
||||
lnode_t *sqlnode;
|
||||
Sql_Conn *sqldata;
|
||||
#endif
|
||||
|
||||
TimeOut = malloc (sizeof (struct timeval));
|
||||
ufds = malloc((sizeof *ufds) * me.maxsocks);
|
||||
|
@ -185,6 +240,25 @@ read_loop ()
|
|||
/* XXX Should this be a pollsize or maxfdsunused... not sure yet */
|
||||
curl_multi_fdset(curlmultihandle, &readfds, &writefds, &errfds, &maxfdsunused);
|
||||
|
||||
#ifdef SQLSRV
|
||||
/* if we have sql support, add the Listen Socket to the fds */
|
||||
if (sqlListenSock > 0)
|
||||
FD_SET(sqlListenSock, &readfds);
|
||||
|
||||
/* if we have any existing connections, add them of course */
|
||||
if (list_count(sqlconnections) > 0) {
|
||||
sqlnode = list_first(sqlconnections);
|
||||
while (sqlnode != NULL) {
|
||||
sqldata = lnode_get(sqlnode);
|
||||
if (sqldata->responsefree < 50000) {
|
||||
FD_SET(sqldata->fd, &writefds);
|
||||
} else {
|
||||
FD_SET(sqldata->fd, &readfds);
|
||||
}
|
||||
sqlnode = list_next(sqlconnections, sqlnode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SelectResult = select (FD_SETSIZE, &readfds, &writefds, &errfds, TimeOut);
|
||||
me.now = time(NULL);
|
||||
if (SelectResult > 0) {
|
||||
|
@ -198,7 +272,29 @@ read_loop ()
|
|||
while(CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlmultihandle, &maxfdsunused)) {
|
||||
}
|
||||
transfer_status();
|
||||
|
||||
#ifdef SQLSRV
|
||||
/* did we get a connection to the SQL listen sock */
|
||||
if ((sqlListenSock > 0) && (FD_ISSET(sqlListenSock, &readfds)))
|
||||
sql_accept_conn(sqlListenSock);
|
||||
restartsql:
|
||||
/* don't bother checking the sql connections if we dont have any active connections! */
|
||||
if (list_count(sqlconnections) > 0) {
|
||||
sqlnode = list_first(sqlconnections);
|
||||
while (sqlnode != NULL) {
|
||||
sqldata = lnode_get(sqlnode);
|
||||
if (FD_ISSET(sqldata->fd, &readfds)) {
|
||||
if (sql_handle_ui_request(sqlnode) == NS_FAILURE) {
|
||||
goto restartsql;
|
||||
}
|
||||
} else if (FD_ISSET(sqldata->fd, &writefds)) {
|
||||
if (sql_handle_ui_output(sqlnode) == NS_FAILURE) {
|
||||
goto restartsql;
|
||||
}
|
||||
}
|
||||
sqlnode = list_next(sqlconnections, sqlnode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (FD_ISSET (servsock, &readfds)) {
|
||||
for (j = 0; j < BUFSIZE; j++) {
|
||||
i = read (servsock, &c, 1);
|
||||
|
@ -456,3 +552,261 @@ sts (char *fmt, ...)
|
|||
me.SendM++;
|
||||
me.SendBytes = me.SendBytes + sent;
|
||||
}
|
||||
|
||||
#if SQLSRV
|
||||
/* the following functions are taken from the RTA example app shipped with the library,
|
||||
* and modified to work with NeoStats.
|
||||
* Credit for these apps should be given to the respective authors of the RTA library.
|
||||
* more info can be found at http://www.linuxappliancedesign.com for more
|
||||
* information
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* listen_on_port(int port): - Open a socket to listen for
|
||||
* incoming TCP connections on the port given. Return the file
|
||||
* descriptor if OK, and -1 on any error. The calling routine
|
||||
* can handle any error condition.
|
||||
*
|
||||
* Input: The interger value of the port number to bind to
|
||||
* Output: The file descriptor of the socket
|
||||
* Effects: none
|
||||
***************************************************************/
|
||||
int
|
||||
sqllisten_on_port(int port)
|
||||
{
|
||||
int srvfd; /* FD for our listen server socket */
|
||||
struct sockaddr_in srvskt;
|
||||
int adrlen;
|
||||
int flags;
|
||||
|
||||
adrlen = sizeof(struct sockaddr_in);
|
||||
(void) memset((void *) &srvskt, 0, (size_t) adrlen);
|
||||
srvskt.sin_family = AF_INET;
|
||||
/* bind to the local IP */
|
||||
if (dobind) {
|
||||
srvskt.sin_addr = lsa.sin_addr;
|
||||
} else {
|
||||
srvskt.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
srvskt.sin_port = htons(me.sqlport);
|
||||
if ((srvfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
nlog(LOG_CRITICAL,LOG_CORE, "SqlSrv: Unable to get socket for port %d.", port);
|
||||
return -1;
|
||||
}
|
||||
flags = fcntl(srvfd, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
(void) fcntl(srvfd, F_SETFL, flags);
|
||||
if (bind(srvfd, (struct sockaddr *) &srvskt, adrlen) < 0)
|
||||
{
|
||||
nlog(LOG_CRITICAL, LOG_CORE, "Unable to bind to port %d\n", port);
|
||||
return -1;
|
||||
}
|
||||
if (listen(srvfd, 1) < 0)
|
||||
{
|
||||
nlog(LOG_CRITICAL, LOG_CORE, "Unable to listen on port %d\n", port);
|
||||
return -1;
|
||||
}
|
||||
return (srvfd);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* accept_ui_session(): - Accept a new UI/DB/manager session.
|
||||
* This routine is called when a user interface program such
|
||||
* as Apache (for the web interface), the SNMP manager, or one
|
||||
* of the console interface programs tries to connect to the
|
||||
* data base interface socket to do DB like get's and set's.
|
||||
* The connection is actually established by the PostgreSQL
|
||||
* library attached to the UI program by an XXXXXX call.
|
||||
*
|
||||
* Input: The file descriptor of the DB server socket
|
||||
* Output: none
|
||||
* Effects: manager connection table (ui)
|
||||
***************************************************************/
|
||||
void
|
||||
sql_accept_conn(int srvfd)
|
||||
{
|
||||
int adrlen; /* length of an inet socket address */
|
||||
int flags; /* helps set non-blocking IO */
|
||||
lnode_t *newuinode;
|
||||
Sql_Conn *newui;
|
||||
char tmp[16];
|
||||
|
||||
/* if we reached our max connection, just exit */
|
||||
if (list_count(sqlconnections) > 5) {
|
||||
nlog(LOG_NOTICE, LOG_CORE, "Can not accept new SQL connection. Full");
|
||||
close (srvfd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We have a new UI/DB/manager connection request. So make a free
|
||||
slot and allocate it */
|
||||
newui = malloc(sizeof(Sql_Conn));
|
||||
|
||||
|
||||
/* OK, we've got the ui slot, now accept the conn */
|
||||
adrlen = sizeof(struct sockaddr_in);
|
||||
newui->fd = accept(srvfd, (struct sockaddr *) &newui->cliskt, &adrlen);
|
||||
|
||||
if (newui->fd < 0)
|
||||
{
|
||||
nlog(LOG_NOTICE, LOG_CORE, "SqlSrv: Manager accept() error (%s). \n", strerror(errno));
|
||||
free(newui);
|
||||
close(srvfd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
inet_ntop(AF_INET, &newui->cliskt.sin_addr.s_addr, tmp, 16);
|
||||
if (fnmatch(me.sqlhost, tmp, 0)) {
|
||||
/* we didnt get a match, bye bye */
|
||||
nlog(LOG_NOTICE, LOG_CORE, "SqlSrv: Rejecting SQL Connection from %s", tmp);
|
||||
close(newui->fd);
|
||||
free(newui);
|
||||
return;
|
||||
}
|
||||
/* inc number ui, then init new ui */
|
||||
flags = fcntl(newui->fd, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
(void) fcntl(newui->fd, F_SETFL, flags);
|
||||
newui->cmdpos = 0;
|
||||
newui->responsefree = 50000; /* max response packetsize if 50000 */
|
||||
newui->nbytein = 0;
|
||||
newui->nbyteout = 0;
|
||||
newui->connid = 0;
|
||||
newuinode = lnode_create(newui);
|
||||
list_append(sqlconnections, newuinode);
|
||||
inet_ntop(AF_INET, &newui->cliskt.sin_addr.s_addr, tmp, 16);
|
||||
nlog(LOG_NOTICE, LOG_CORE, "New SqlConnection from %s", tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* handle_ui_request(): - This routine is called to read data
|
||||
* from the TCP connection to the UI programs such as the web
|
||||
* UI and consoles. The protocol used is that of Postgres and
|
||||
* the data is an encoded SQL request to select or update a
|
||||
* system variable. Note that the use of callbacks on reading
|
||||
* or writing means a lot of the operation of the program
|
||||
* starts from this execution path. The input is an index into
|
||||
* the ui table for the manager with data ready.
|
||||
*
|
||||
* Input: index of the relevant entry in the ui table
|
||||
* Output: none
|
||||
* Effects: many, many side effects via table callbacks
|
||||
***************************************************************/
|
||||
int
|
||||
sql_handle_ui_request(lnode_t *sqlnode)
|
||||
{
|
||||
int ret; /* a return value */
|
||||
int dbstat; /* a return value */
|
||||
int t; /* a temp int */
|
||||
Sql_Conn *sqlconn;
|
||||
|
||||
if ((sqlconn = lnode_get(sqlnode)) == NULL) {
|
||||
nlog(LOG_WARNING, LOG_CORE, "Got a Sql Handle without a valid node");
|
||||
return NS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* We read data from the connection into the buffer in the ui struct.
|
||||
Once we've read all of the data we can, we call the DB routine to
|
||||
parse out the SQL command and to execute it. */
|
||||
ret = read(sqlconn->fd,
|
||||
&(sqlconn->cmd[sqlconn->cmdpos]), (1000 - sqlconn->cmdpos));
|
||||
|
||||
/* shutdown manager conn on error or on zero bytes read */
|
||||
if (ret <= 0)
|
||||
{
|
||||
/* log this since a normal close is with an 'X' command from the
|
||||
client program? */
|
||||
nlog(LOG_DEBUG1, LOG_CORE, "Disconnecting SqlClient for failed read");
|
||||
deldbconnection(sqlconn->connid);
|
||||
close(sqlconn->fd);
|
||||
list_delete(sqlconnections, sqlnode);
|
||||
lnode_destroy(sqlnode);
|
||||
free(sqlconn);
|
||||
return NS_FAILURE;
|
||||
}
|
||||
sqlconn->cmdpos += ret;
|
||||
sqlconn->nbytein += ret;
|
||||
|
||||
/* The commands are in the buffer. Call the DB to parse and execute
|
||||
them */
|
||||
do
|
||||
{
|
||||
t = sqlconn->cmdpos, /* packet in length */
|
||||
dbstat = dbcommand(sqlconn->cmd, /* packet in */
|
||||
&sqlconn->cmdpos, /* packet in length */
|
||||
&sqlconn->response[50000 - sqlconn->responsefree], &sqlconn->responsefree, &sqlconn->connid);
|
||||
t -= sqlconn->cmdpos, /* t = # bytes consumed */
|
||||
/* move any trailing SQL cmd text up in the buffer */
|
||||
(void) memmove(sqlconn->cmd, &sqlconn->cmd[t], t);
|
||||
} while (dbstat == RTA_SUCCESS);
|
||||
if (dbstat == RTA_ERROR) {
|
||||
deldbconnection(sqlconn->connid);
|
||||
}
|
||||
/* the command is done (including side effects). Send any reply back
|
||||
to the UI */
|
||||
sql_handle_ui_output(sqlnode);
|
||||
return NS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* handle_ui_output() - This routine is called to write data
|
||||
* to the TCP connection to the UI programs. It is useful for
|
||||
* slow clients which can not accept the output in one big gulp.
|
||||
*
|
||||
* Input: index of the relevant entry in the ui table
|
||||
* Output: none
|
||||
* Effects: none
|
||||
***************************************************************/
|
||||
int
|
||||
sql_handle_ui_output(lnode_t *sqlnode)
|
||||
{
|
||||
int ret; /* write() return value */
|
||||
Sql_Conn *sqlconn;
|
||||
|
||||
if ((sqlconn = lnode_get(sqlnode)) == NULL) {
|
||||
nlog(LOG_WARNING, LOG_CORE, "Got a Sql write Handle without a valid node");
|
||||
return NS_SUCCESS;
|
||||
}
|
||||
|
||||
if (sqlconn->responsefree < 50000)
|
||||
{
|
||||
ret = write(sqlconn->fd, sqlconn->response, (50000 - sqlconn->responsefree));
|
||||
if (ret < 0)
|
||||
{
|
||||
nlog(LOG_WARNING, LOG_CORE, "Got a write error when attempting to return data to the SQL Server");
|
||||
deldbconnection(sqlconn->connid);
|
||||
close(sqlconn->fd);
|
||||
list_delete(sqlconnections, sqlnode);
|
||||
lnode_destroy(sqlnode);
|
||||
free(sqlconn);
|
||||
return NS_FAILURE;
|
||||
}
|
||||
else if (ret == (50000 - sqlconn->responsefree))
|
||||
{
|
||||
sqlconn->responsefree = 50000;
|
||||
sqlconn->nbyteout += ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we had a partial write. Adjust the buffer */
|
||||
(void) memmove(sqlconn->response, &sqlconn->response[ret],
|
||||
(50000 - sqlconn->responsefree - ret));
|
||||
sqlconn->responsefree += ret;
|
||||
sqlconn->nbyteout += ret; /* # bytes sent on conn */
|
||||
}
|
||||
}
|
||||
return NS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
13
sqlsrv/api.c
13
sqlsrv/api.c
|
@ -17,7 +17,9 @@
|
|||
#include <libgen.h> /* for dirname() */
|
||||
#include <string.h> /* for strlen() */
|
||||
#include <limits.h> /* for PATH_MAX */
|
||||
#ifdef SYSLOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include "rta.h" /* for various constants */
|
||||
#include "do_sql.h" /* for LOC */
|
||||
|
@ -53,7 +55,7 @@ getconndata(int id)
|
|||
* Output: None.
|
||||
**************************************************************/
|
||||
void
|
||||
rta_init()
|
||||
rta_init(logcb logfunc)
|
||||
{
|
||||
int i; /* loop index */
|
||||
extern TBLDEF pg_userTable;
|
||||
|
@ -62,7 +64,11 @@ rta_init()
|
|||
extern TBLDEF rta_dbgTable;
|
||||
extern TBLDEF rta_statTable;
|
||||
extern TBLDEF pg_connTable;
|
||||
#ifdef SYSLOG
|
||||
extern void restart_syslog();
|
||||
#else
|
||||
RTA_Conf.loggingfunc = logfunc;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MX_TBL; i++)
|
||||
{
|
||||
|
@ -81,10 +87,13 @@ rta_init()
|
|||
(void) rta_add_table(&pg_connTable);
|
||||
(void) rta_add_table(&rta_dbgTable);
|
||||
(void) rta_add_table(&rta_statTable);
|
||||
|
||||
#ifdef SYSLOG
|
||||
restart_syslog((char *) 0, (char *) 0, (char *) 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* rta_add_table(): - Add one table to the list of
|
||||
* tables in the system. If the table has an associated
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h> /* for va_arg */
|
||||
#include <string.h>
|
||||
#if 0
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#include "log.h"
|
||||
#include "do_sql.h"
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
|
@ -106,7 +109,7 @@ do_sql(char *buf, int *nbuf)
|
|||
break;
|
||||
|
||||
default:
|
||||
syslog(LOG_ERR, "DB error: no SQL cmd\n");
|
||||
nlog(LOG_CORE, LOG_NOTICE, "SQLSRC error: no SQL cmd\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1266,6 +1269,7 @@ rtalog(char *fname, /* error detected in file... */
|
|||
char *s1; /* first optional argument */
|
||||
char *s2; /* second optional argument */
|
||||
char *sptr; /* used to look for %s */
|
||||
char final[1024];
|
||||
|
||||
s1 = (char *) 0;
|
||||
s2 = (char *) 0;
|
||||
|
@ -1282,5 +1286,6 @@ rtalog(char *fname, /* error detected in file... */
|
|||
s2 = va_arg(ap, char *);
|
||||
}
|
||||
va_end(ap);
|
||||
fprintf(stderr, format, fname, linen, s1, s2);
|
||||
snprintf(final, 1024, format, fname, linen, s1, s2);
|
||||
RTA_Conf.loggingfunc(final);
|
||||
}
|
||||
|
|
|
@ -144,6 +144,16 @@ typedef struct
|
|||
/* the connections list */
|
||||
hash_t *pgconn;
|
||||
|
||||
|
||||
/* this is a struct that stores the RTA runtime config */
|
||||
struct RTA_Conf
|
||||
{
|
||||
logcb loggingfunc; /* logging callback */
|
||||
} RTA_Conf;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Forward references */
|
||||
void do_sql(char *, int *);
|
||||
void send_error(char *, int, char *, char *);
|
||||
|
|
10
sqlsrv/rta.h
10
sqlsrv/rta.h
|
@ -419,6 +419,11 @@ void deldbconnection(int connid);
|
|||
**************************************************************/
|
||||
int rta_add_table(TBLDEF *);
|
||||
|
||||
/*
|
||||
* Logging function callback
|
||||
*/
|
||||
typedef void (*logcb) (char *logmsg);
|
||||
|
||||
/** ************************************************************
|
||||
* rta_init(): - Initialize all internal variables and tables
|
||||
* This may be called more than once.
|
||||
|
@ -426,7 +431,10 @@ int rta_add_table(TBLDEF *);
|
|||
* Input: None
|
||||
* Return: None
|
||||
**************************************************************/
|
||||
void rta_init();
|
||||
void rta_init(logcb);
|
||||
|
||||
/* change the uname/password for authentication */
|
||||
void rta_change_auth(char *uname, char *pass);
|
||||
|
||||
/** ************************************************************
|
||||
* SQL_string(): - Execute single SQL command
|
||||
|
|
|
@ -64,17 +64,24 @@ struct Pg_User
|
|||
/* Allocate and initialize the table */
|
||||
struct Pg_User pg_user[] = {
|
||||
{
|
||||
"Fish", /* user name */
|
||||
"master", /* user name */
|
||||
100, /* user ID */
|
||||
"f", /* creat DB */
|
||||
"f", /* trace execution */
|
||||
"f", /* super user */
|
||||
"f",
|
||||
"blah", /* the password */
|
||||
"password", /* the password */
|
||||
"" /* valid until .... */
|
||||
}
|
||||
};
|
||||
|
||||
void rta_change_auth(char *uname, char *pass) {
|
||||
strncpy(pg_user[0].usename, uname, MX_PGNAMELEN);
|
||||
strncpy(pg_user[0].passwd, pass, MX_PGNAMELEN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the table columns */
|
||||
COLDEF pg_userCols[] = {
|
||||
{
|
||||
|
@ -865,3 +872,5 @@ TBLDEF rta_statTable = {
|
|||
"", /* save file name */
|
||||
"Usage and error counts for the rta package."
|
||||
};
|
||||
|
||||
|
||||
|
|
7
stats.h
7
stats.h
|
@ -303,6 +303,10 @@ struct me {
|
|||
time_t lastmsg;
|
||||
int pingtime;
|
||||
time_t now;
|
||||
#ifdef SQLSRV
|
||||
char sqlhost[MAXHOST];
|
||||
int sqlport;
|
||||
#endif
|
||||
} me;
|
||||
|
||||
/** @brief User structure
|
||||
|
@ -361,6 +365,9 @@ struct ping {
|
|||
int ulag;
|
||||
} ping;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Comand list handling */
|
||||
/** @brief flags for command list
|
||||
* flags to provide more information on a command to the core
|
||||
|
|
Reference in a new issue