diff --git a/pgworker/pgworker/pg_worker.c b/pgworker/pgworker/pg_worker.c index 09cd6b0..bebe65c 100644 --- a/pgworker/pgworker/pg_worker.c +++ b/pgworker/pgworker/pg_worker.c @@ -28,6 +28,7 @@ #include #include "htmalloc.h" +#include "htbuffer.h" #include "smmapd.h" @@ -35,7 +36,7 @@ int pg_worker_init(cfgl_t *cfg, void **handle); int pg_worker_destroy(void *handle); int pg_worker_work_setup(void *handle, void **work_handle); int pg_worker_work_destroy(void *handle, void *work_handle); -int pg_worker_work(void *handle, void *work_handle, char *input, char *output); +int pg_worker_work(void *handle, void *work_handle, char *input, htbuffer_t *output); class_descriptor_t pgworker = { "pgworker", @@ -54,6 +55,10 @@ typedef struct pg_container_handle_s { int param_cnt; char *input_delimiter; char *output_format_string; + char *dbhost; + char *dbname; + char *dbuser; + char *dbpass; } pg_container_handle_t; typedef struct pg_worker_handle_s { @@ -63,6 +68,11 @@ typedef struct pg_worker_handle_s { PGconn *dbconn; } pg_worker_handle_t; +static int process(pg_worker_handle_t *pwh, char *input, htbuffer_t *output); +static int count_params(const char *stmt); +static int break_input(pg_worker_handle_t *pwh, char *input); + + int debug = 0; @@ -97,6 +107,10 @@ static int count_params(const char *stmt) { syslog(LOG_ERR, "pgworker count_params: failure, x=0"); break; } + if (x >= MAX_PARAM_COUNT) { + syslog(LOG_ERR, "pgworker count_params: failure, x > MAX_PARAM_COUNT"); + break; + } checkArray[x-1] = 1; cnt++; done = 1; @@ -148,6 +162,29 @@ int pg_worker_init(cfgl_t *cfg, void **handle) { return -1; } pch->output_format_string = findcfgl(pch->cfg, "output_format_string"); + pch->dbhost = findcfgl(pch->cfg, "dbhost"); + if (pch->dbhost == NULL) { + syslog(LOG_ERR, "pgworker pg_worker_init: missing dbhost"); + return -1; + } + pch->dbname = findcfgl(pch->cfg, "dbname"); + if (pch->dbname == NULL) { + syslog(LOG_ERR, "pgworker pg_worker_init: missing dbname"); + return -1; + } + pch->dbuser = findcfgl(pch->cfg, "dbuser"); + if (pch->dbuser == NULL) { + syslog(LOG_ERR, "pgworker pg_worker_init: missing dbuser"); + return -1; + } + pch->dbpass = findcfgl(pch->cfg, "dbpass"); + if (pch->dbpass == NULL) { + syslog(LOG_ERR, "pgworker pg_worker_init: missing dbpass"); + return -1; + } + + + *handle = pch; return 0; } @@ -167,13 +204,13 @@ int pg_worker_work_setup(void *handle, void **work_handle) { pwh->param_array = (char **) htmalloc(sizeof(char*) * pwh->pch->param_cnt); syslog(LOG_DEBUG, "pgworker c=%p w=%p", pwh->pch, pwh); - pwh->dbconn = PQsetdbLogin("confdb.hottis.de", + pwh->dbconn = PQsetdbLogin(pwh->pch->dbhost, NULL, NULL, NULL, - "config", - "lurker", - "lurker123"); + pwh->pch->dbname, + pwh->pch->dbuser, + pwh->pch->dbpass); syslog(LOG_DEBUG, "pgworker (%p) pg_worker_work_setup: dbconn=%p", pwh, pwh->dbconn); @@ -189,16 +226,12 @@ int pg_worker_work_destroy(void *handle, void *work_handle) { free(pwh); } -int pg_worker_work(void *handle, void *work_handle, char *input, char *output) { +int pg_worker_work(void *handle, void *work_handle, char *input, htbuffer_t *output) { int res; - pg_container_handle_t *pch = (pg_container_handle_t*) handle; pg_worker_handle_t *pwh = (pg_worker_handle_t*) work_handle; syslog(LOG_DEBUG, "pgworker (%p) pg_worker_work entered", pwh); - sprintf(output, "pg-worker receives %s (pch %p, pwh %p) (called %d)\n", - input, pch, pwh, pwh->counter++); - res = process(pwh, input, output); return SMM_OK; @@ -251,17 +284,17 @@ static int break_input(pg_worker_handle_t *pwh, char *input) { #define MAX_RESULT_DIGIT_NUM 2 static int populate_output_format(pg_worker_handle_t *pwh, PGresult *pgr, - char *output, int tuple_num) { + htbuffer_t *output, int tuple_num) { const char *formatPtr = pwh->pch->output_format_string; const char *tmpPtr = formatPtr; char numBuf[MAX_PARAM_DIGIT_NUM + 1]; char *s; int i, x, cnt=0, done, res=0; - output[0] = '\0'; + htbuffer_strcpy(output, ""); while ((formatPtr = strchr(formatPtr, '$')) && (res == 0)) { - strncat(output, tmpPtr, formatPtr - tmpPtr); + htbuffer_strncat(output, tmpPtr, formatPtr - tmpPtr); syslog(LOG_DEBUG, "pgworker (%p) populate_output_format OUTPUT: %s", pwh, output); formatPtr++; @@ -281,14 +314,14 @@ static int populate_output_format(pg_worker_handle_t *pwh, PGresult *pgr, s = PQgetvalue(pgr, tuple_num, x); syslog(LOG_DEBUG, "pgworker (%p) populate_output_format OUTPUT PARAM: %s", pwh, s); - strcat(output, s); + htbuffer_strcat(output, s); done = 1; } } if (!done) { syslog(LOG_ERR, "pgworker (%p) populate_outputformat, not done, failure", pwh); - output[0] = '\0'; + htbuffer_strcpy(output, ""); res = -1; break; } @@ -296,31 +329,26 @@ static int populate_output_format(pg_worker_handle_t *pwh, PGresult *pgr, if (done == 1) { /* reminds */ - strncat(output, tmpPtr, formatPtr - tmpPtr); - syslog(LOG_DEBUG, "OUTPUT: %s", output); + htbuffer_strncat(output, tmpPtr, formatPtr - tmpPtr); + syslog(LOG_DEBUG, "OUTPUT: %s", output->buf); } return res; } -static int process(pg_worker_handle_t *pwh, char *input, char *output) { +static int process(pg_worker_handle_t *pwh, char *input, htbuffer_t *output) { int i, j, t, f, res; char *s; PGresult *pgr; if (0 == (res = break_input(pwh, input))) { - for (i = 0; i < pwh->pch->param_cnt; i++) { - syslog(LOG_DEBUG, "pgworker (%p) process: param %d --> %s", - pwh, i+1, pwh->param_array[i]); - } - pgr = PQexecParams(pwh->dbconn, pwh->pch->sql_statement, pwh->pch->param_cnt, NULL, - pwh->param_array, + (const char * const *) pwh->param_array, NULL, NULL, 0); @@ -333,24 +361,16 @@ static int process(pg_worker_handle_t *pwh, char *input, char *output) { syslog(LOG_DEBUG, "pgworker (%p) process PQnfields=%d", pwh, f); if (t > 0) { - for (i = 0; i < t; i++) { - for (j = 0; j < f; j++) { - s = PQgetvalue(pgr, i, j); - syslog(LOG_DEBUG, "pgworker (%p) process result (%d, %d) = {%s}", - pwh, i, j, s); - } - } - if (NULL == pwh->pch->output_format_string) { if (f > 1) syslog(LOG_WARNING, "pgworker (%p) process: more than one result fields (%d) but no format string", pwh, f); - strcpy(output, PQgetvalue(pgr, 0, 0)); + htbuffer_strcpy(output, PQgetvalue(pgr, 0, 0)); res = 0; } else { if (0 == (res = populate_output_format(pwh, pgr, output, 0))) { - syslog(LOG_DEBUG, "pgworker (%p) process: output %s", pwh, output); + syslog(LOG_DEBUG, "pgworker (%p) process: output %s", pwh, output->buf); } else { syslog(LOG_ERR, "pgworker (%p) process failure in population of output", pwh); } @@ -358,9 +378,10 @@ static int process(pg_worker_handle_t *pwh, char *input, char *output) { } else { syslog(LOG_DEBUG, "pgworker (%p) process: no output", pwh); } + + PQclear(pgr); } - PQclear(pgr); return res; } diff --git a/smmapdfw/cyrus_worker/cyrus_worker.c b/smmapdfw/cyrus_worker/cyrus_worker.c index 127977e..a9b758b 100644 --- a/smmapdfw/cyrus_worker/cyrus_worker.c +++ b/smmapdfw/cyrus_worker/cyrus_worker.c @@ -28,6 +28,7 @@ #include "smtp.h" #include "htdns.h" #include "htmalloc.h" +#include "htbuffer.h" #include "stats.h" #define SMM_LOCAL_PERM_NOK 101 @@ -60,7 +61,7 @@ typedef struct cyrus_work_handle_s cyrus_work_handle_t; int cyrus_init(cfgl_t *cfg, void **handle); int cyrus_destroy(void *handle); /* int cyrus_work_setup(void *handle, void **work_handle); */ -int cyrus_work(void *handle, void *work_handle, char *input, char *output); +int cyrus_work(void *handle, void *work_handle, char *input, htbuffer_t *output); /* int cyrus_work_destroy(void *handle, void *work_handle); */ @@ -99,7 +100,7 @@ int cyrus_destroy(void *handle) { -int cyrus_work(void *handle, void *work_handle, char *input, char *output) { +int cyrus_work(void *handle, void *work_handle, char *input, htbuffer_t *output) { static const char *DEFAULT_ANSWER = "default answer"; static const char *ILLEGAL_INPUT = "illegal input (must be 'depot_uid depot_host')"; static const char *UNEXPECTED_ERROR = "unexpected error in lmtp dialog"; @@ -130,7 +131,8 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) { depot_uid = input; if (NULL == (depot_host = strchr(depot_uid, ' '))) { - snprintf(output, ANSWER_BUFSIZE, ILLEGAL_INPUT); + // snprintf(output, ANSWER_BUFSIZE, ILLEGAL_INPUT); + htbuffer_strcpy(output, ILLEGAL_INPUT); incStatCounter(STAT_CNT_CYRUS_ILLEGAL_INPUT); return SMM_PERM_NOK; } @@ -143,7 +145,8 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) { if (NULL == a_rdata) { syslog(LOG_DEBUG, "cyrus_work: (%04x) depot_host %s could not be found in dns", log_id, depot_host); - snprintf(output, ANSWER_BUFSIZE, DEPOT_DNS_ERROR); + // snprintf(output, ANSWER_BUFSIZE, DEPOT_DNS_ERROR); + htbuffer_strcpy(output, DEPOT_DNS_ERROR); incStatCounter(STAT_CNT_CYRUS_DEPOT_DNS_FAILURE); return SMM_TEMP_NOK; } @@ -240,29 +243,39 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) { switch (result) { case SMM_LOCAL_TEMP_NOK: - snprintf(output, ANSWER_BUFSIZE, "<%s>", response_text); + htbuffer_strcat(output, "<"); + htbuffer_strcat(output, response_text); + htbuffer_strcat(output, ">"); + //snprintf(output, ANSWER_BUFSIZE, "<%s>", response_text); result = SMM_OK; incStatCounter(STAT_CNT_CYRUS_RETURNED_TNOK); break; case SMM_LOCAL_PERM_NOK: - snprintf(output, ANSWER_BUFSIZE, "<%s>", response_text); + htbuffer_strcat(output, "<"); + htbuffer_strcat(output, response_text); + htbuffer_strcat(output, ">"); + //snprintf(output, ANSWER_BUFSIZE, "<%s>", response_text); result = SMM_OK; incStatCounter(STAT_CNT_CYRUS_RETURNED_NOK); break; case SMM_LOCAL_OK: - snprintf(output, ANSWER_BUFSIZE, "<%s>", response_text); + htbuffer_strcat(output, "<"); + htbuffer_strcat(output, response_text); + htbuffer_strcat(output, ">"); + //snprintf(output, ANSWER_BUFSIZE, "<%s>", response_text); result = SMM_OK; incStatCounter(STAT_CNT_CYRUS_RETURNED_OK); break; default: - snprintf(output, ANSWER_BUFSIZE, response_text); + htbuffer_strcpy(output, response_text); + //snprintf(output, ANSWER_BUFSIZE, response_text); break; } smtp_destroy(lmtp); syslog(LOG_DEBUG, "cyrus_work: (%04x) result %d, %s", log_id, - result, output); + result, output->buf); return result; } diff --git a/smmapdfw/libsmmapdfw/Makefile.am b/smmapdfw/libsmmapdfw/Makefile.am index 7072904..b540147 100644 --- a/smmapdfw/libsmmapdfw/Makefile.am +++ b/smmapdfw/libsmmapdfw/Makefile.am @@ -1,7 +1,9 @@ -include_HEADERS=containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h htdns.h smmapd.h htmalloc.h stats.h htcache.h +include_HEADERS=containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h htdns.h smmapd.h htmalloc.h stats.h htcache.h htbuffer.h lib_LTLIBRARIES = libsmmapdfw.la -libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c htdns.c smtp.c htmalloc.c stats.c htcache.c +libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c htdns.c smtp.c htmalloc.c stats.c htcache.c htbuffer.c libsmmapdfw_la_LIBADD = @BDB_LIBS@ -bin_PROGRAMS = htcachetest +bin_PROGRAMS = htcachetest htbuffertest htcachetest_SOURCES = htcachetest.c htcachetest_LDADD = libsmmapdfw.la +htbuffertest_SOURCES = htbuffertest.c +htbuffertest_LDADD = libsmmapdfw.la diff --git a/smmapdfw/libsmmapdfw/Makefile.in b/smmapdfw/libsmmapdfw/Makefile.in index 9fd1047..9bde0e7 100644 --- a/smmapdfw/libsmmapdfw/Makefile.in +++ b/smmapdfw/libsmmapdfw/Makefile.in @@ -87,13 +87,15 @@ RC = @RC@ STRIP = @STRIP@ VERSION = @VERSION@ -include_HEADERS = containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h htdns.h smmapd.h htmalloc.h stats.h htcache.h +include_HEADERS = containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h htdns.h smmapd.h htmalloc.h stats.h htcache.h htbuffer.h lib_LTLIBRARIES = libsmmapdfw.la -libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c htdns.c smtp.c htmalloc.c stats.c htcache.c +libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c htdns.c smtp.c htmalloc.c stats.c htcache.c htbuffer.c libsmmapdfw_la_LIBADD = @BDB_LIBS@ -bin_PROGRAMS = htcachetest +bin_PROGRAMS = htcachetest htbuffertest htcachetest_SOURCES = htcachetest.c htcachetest_LDADD = libsmmapdfw.la +htbuffertest_SOURCES = htbuffertest.c +htbuffertest_LDADD = libsmmapdfw.la mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -107,13 +109,17 @@ LIBS = @LIBS@ libsmmapdfw_la_LDFLAGS = libsmmapdfw_la_DEPENDENCIES = libsmmapdfw_la_OBJECTS = cfg.lo queue.lo count.lo safe_write.lo \ -config_public.lo htdns.lo smtp.lo htmalloc.lo stats.lo htcache.lo -bin_PROGRAMS = htcachetest$(EXEEXT) +config_public.lo htdns.lo smtp.lo htmalloc.lo stats.lo htcache.lo \ +htbuffer.lo +bin_PROGRAMS = htcachetest$(EXEEXT) htbuffertest$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) htcachetest_OBJECTS = htcachetest.$(OBJEXT) htcachetest_DEPENDENCIES = libsmmapdfw.la htcachetest_LDFLAGS = +htbuffertest_OBJECTS = htbuffertest.$(OBJEXT) +htbuffertest_DEPENDENCIES = libsmmapdfw.la +htbuffertest_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -129,10 +135,11 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best DEP_FILES = .deps/cfg.P .deps/config_public.P .deps/count.P \ -.deps/htcache.P .deps/htcachetest.P .deps/htdns.P .deps/htmalloc.P \ -.deps/queue.P .deps/safe_write.P .deps/smtp.P .deps/stats.P -SOURCES = $(libsmmapdfw_la_SOURCES) $(htcachetest_SOURCES) -OBJECTS = $(libsmmapdfw_la_OBJECTS) $(htcachetest_OBJECTS) +.deps/htbuffer.P .deps/htbuffertest.P .deps/htcache.P \ +.deps/htcachetest.P .deps/htdns.P .deps/htmalloc.P .deps/queue.P \ +.deps/safe_write.P .deps/smtp.P .deps/stats.P +SOURCES = $(libsmmapdfw_la_SOURCES) $(htcachetest_SOURCES) $(htbuffertest_SOURCES) +OBJECTS = $(libsmmapdfw_la_OBJECTS) $(htcachetest_OBJECTS) $(htbuffertest_OBJECTS) all: all-redirect .SUFFIXES: @@ -240,6 +247,10 @@ htcachetest$(EXEEXT): $(htcachetest_OBJECTS) $(htcachetest_DEPENDENCIES) @rm -f htcachetest$(EXEEXT) $(LINK) $(htcachetest_LDFLAGS) $(htcachetest_OBJECTS) $(htcachetest_LDADD) $(LIBS) +htbuffertest$(EXEEXT): $(htbuffertest_OBJECTS) $(htbuffertest_DEPENDENCIES) + @rm -f htbuffertest$(EXEEXT) + $(LINK) $(htbuffertest_LDFLAGS) $(htbuffertest_OBJECTS) $(htbuffertest_LDADD) $(LIBS) + install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(includedir) diff --git a/smmapdfw/libsmmapdfw/containers_public.h b/smmapdfw/libsmmapdfw/containers_public.h index 10df8b2..600b967 100644 --- a/smmapdfw/libsmmapdfw/containers_public.h +++ b/smmapdfw/libsmmapdfw/containers_public.h @@ -23,13 +23,14 @@ #define _CONTAINERS_PUBLIC_H_ #include "cfg.h" +#include "htbuffer.h" struct class_descriptor_s { char *name; int (*init_function)(cfgl_t *cfg, void **handle); int (*destroy_function)(void *handle); int (*work_setup_function)(void *handle, void **work_handle); - int (*work_function)(void *handle, void *work_handle, char *input, char *output); + int (*work_function)(void *handle, void *work_handle, char *input, htbuffer_t *output); int (*work_destroy_function)(void *handle, void *work_handle); }; diff --git a/smmapdfw/libsmmapdfw/htbuffer.c b/smmapdfw/libsmmapdfw/htbuffer.c new file mode 100644 index 0000000..94d8a2f --- /dev/null +++ b/smmapdfw/libsmmapdfw/htbuffer.c @@ -0,0 +1,138 @@ +/* + Copyright (C) 2005 Wolfgang Hottgenroth + + This file is part of smmapdfw. + + smmapdfw 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. + + smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "htmalloc.h" +#include "htbuffer.h" + + + +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) + +htbuffer_t *htbuffer_init(unsigned int start_size) { + htbuffer_t *b; + + b = (htbuffer_t*) htmalloc(sizeof(htbuffer_t)); + + b->current_buf_size = (start_size % DEFAULT_CHUNK_SIZE) + ? (start_size + (DEFAULT_CHUNK_SIZE - start_size % DEFAULT_CHUNK_SIZE)) + : start_size; + + b->current_fill_size = 0; + b->max_size = DEFAULT_MAX_SIZE; + + b->buf = (char*) htmalloc(sizeof(char) * b->current_buf_size); + memset(b->buf, 0, start_size); + + return b; +} + +void htbuffer_set_max_size(htbuffer_t *b, unsigned int s) { + b->max_size = s; +} + +void htbuffer_free(htbuffer_t *b) { + free(b->buf); + free(b); +} + + +unsigned int htbuffer_strlen(htbuffer_t *b) { + /* 1 because of the terminating \0 */ + assert((b->current_fill_size + 1) == strlen(b->buf)); + return b->current_fill_size - 1; +} + +htbuffer_t *htbuffer_memcpy_w_offset(htbuffer_t *dest, unsigned int offset, const char *src, unsigned int src_size) { + int new_buf_size; + +/* printf("src_size=%d, offset=%d, cbs=%d\n", src_size, offset, dest->current_buf_size); */ + if (src_size + offset > dest->current_buf_size) { + /* grow buffer */ + int pos = src_size + offset; + new_buf_size = (pos % DEFAULT_CHUNK_SIZE) + ? (pos + (DEFAULT_CHUNK_SIZE - (pos % DEFAULT_CHUNK_SIZE))) + : pos; + + if (new_buf_size > dest->max_size) { + syslog(LOG_ERR, "htbuffer (%p) htbuffer_strcpy: new size too large %d (max=%d)", + dest, new_buf_size, dest->max_size); + exit(154); + } + + dest->buf = (char*) htrealloc(dest->buf, sizeof(char) * new_buf_size); + dest->current_buf_size = new_buf_size; + } + + dest->current_fill_size = src_size + offset; + + memcpy(dest->buf + offset, src, src_size); + + return dest; +} + +htbuffer_t *htbuffer_memcpy(htbuffer_t *dest, const char *src, unsigned int src_size) { + return htbuffer_memcpy_w_offset(dest, 0, src, src_size); +} + +htbuffer_t *htbuffer_strcpy_w_offset(htbuffer_t *dest, unsigned int offset, const char *src) { + return htbuffer_memcpy_w_offset(dest, offset, src, strlen(src)+1); +} + +htbuffer_t *htbuffer_strcpy(htbuffer_t *dest, const char *src) { + return htbuffer_strcpy_w_offset(dest, 0, src); +} + +htbuffer_t *htbuffer_strncpy_w_offset(htbuffer_t *dest, unsigned int offset, const char *src, unsigned int n) { + return htbuffer_memcpy_w_offset(dest, offset, src, MIN(strlen(src)+1, n)); +} + +htbuffer_t *htbuffer_strncpy(htbuffer_t *dest, const char *src, unsigned int n) { + return htbuffer_strncpy_w_offset(dest, 0, src, n); +} + +htbuffer_t *htbuffer_strcat(htbuffer_t *dest, const char *src) { + return htbuffer_strcpy_w_offset(dest, strlen(dest->buf), src); +} + +htbuffer_t *htbuffer_strncat(htbuffer_t *dest, const char *src, unsigned int n) { + return htbuffer_strncpy_w_offset(dest, strlen(dest->buf), src, n); +} + + + + + + + + + + + diff --git a/smmapdfw/libsmmapdfw/htbuffer.h b/smmapdfw/libsmmapdfw/htbuffer.h new file mode 100644 index 0000000..c454069 --- /dev/null +++ b/smmapdfw/libsmmapdfw/htbuffer.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2005, Wolfgang Hottgenroth + + This file is part of smmapdfw. + + smmapdfw 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. + + smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + + +#ifndef _HTBUFFER_H_ +#define _HTBUFFER_H_ + +#define DEFAULT_MAX_SIZE 16*1024*1024 +#define DEFAULT_CHUNK_SIZE 1024 + +typedef struct htbuffer_s { + char *buf; + unsigned int current_buf_size; + unsigned int current_fill_size; + unsigned int max_size; +} htbuffer_t; + + +void htbuffer_set_max_size(htbuffer_t *b, unsigned int s); +htbuffer_t *htbuffer_init(unsigned int start_size); +void htbuffer_free(htbuffer_t *b); + +unsigned int htbuffer_strlen(htbuffer_t *b); + +htbuffer_t *htbuffer_memcpy_w_offset(htbuffer_t *dest, unsigned int offset, const char *src, unsigned int src_size); +htbuffer_t *htbuffer_memcpy(htbuffer_t *dest, const char *src, unsigned int src_size); + + +htbuffer_t *htbuffer_strcpy_w_offset(htbuffer_t *dest, unsigned int offset, const char *src); +htbuffer_t *htbuffer_strcpy(htbuffer_t *dest, const char *src); + +htbuffer_t *htbuffer_strncpy_w_offset(htbuffer_t *dest, unsigned int offset, const char *src, unsigned int n); +htbuffer_t *htbuffer_strncpy(htbuffer_t *dest, const char *src, unsigned int n); + +htbuffer_t *htbuffer_strncat(htbuffer_t *dest, const char *src, unsigned int n); +htbuffer_t *htbuffer_strcat(htbuffer_t *dest, const char *src); + + + + + +#endif /* _HTBUFFER_H_ */ + + diff --git a/smmapdfw/libsmmapdfw/htbuffertest.c b/smmapdfw/libsmmapdfw/htbuffertest.c new file mode 100644 index 0000000..b382259 --- /dev/null +++ b/smmapdfw/libsmmapdfw/htbuffertest.c @@ -0,0 +1,177 @@ +/* + Copyright (C) 2005 Wolfgang Hottgenroth + + This file is part of smmapdfw. + + smmapdfw 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. + + smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "htbuffer.h" + + + + +int main(int argc, char **args) { + htbuffer_t *b; + char* output; + int size; + int res; + + + /* ------------------------------------------------------------------------------------------- */ + b = htbuffer_init(512); + if (b->current_buf_size != 1024) + printf("1. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else + printf("1. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + b = htbuffer_init(519); + if (b->current_buf_size != 1024) + printf("2. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else + printf("2. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + b = htbuffer_init(2500); + if (b->current_buf_size != 3072) + printf("3. FAILURE: wrong current_buf_size (%d), expected 3072\n", b->current_buf_size); + else + printf("3. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + b = htbuffer_init(1024); + if (b->current_buf_size != 1024) + printf("4. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else + printf("4. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + b = htbuffer_init(10240); + if (b->current_buf_size != 10240) + printf("5. FAILURE: wrong current_buf_size (%d), expected 10240\n", b->current_buf_size); + else + printf("5. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + #define TEXT1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123" + b = htbuffer_init(512); + htbuffer_strcpy(b, TEXT1); + if (b->current_buf_size != 1024) + printf("6. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else if (strcmp(TEXT1, b->buf)) + printf("6. FAILURE: unexpected content\n"); + else + printf("6. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + #define TEXT2 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123" + b = htbuffer_init(512); + htbuffer_strcpy(b, TEXT2); + if (b->current_buf_size != 2048) + printf("7. FAILURE: wrong current_buf_size (%d), expected 2048\n", b->current_buf_size); + else if (strcmp(TEXT2, b->buf)) + printf("7. FAILURE: unexpected content\n"); + else + printf("7. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + #define TEXT3 "abcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa123" + #define TEXT4 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123" + #define TEXT3_4 "abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123" + b = htbuffer_init(512); + htbuffer_strcpy(b, TEXT3); + htbuffer_strcpy_w_offset(b, 3, TEXT4); + if (b->current_buf_size != 1024) + printf("8. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else if (strcmp(TEXT3_4, b->buf)) + printf("8. FAILURE: unexpected content {%s}\n", b->buf); + else + printf("8. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + #define TEXT5 "abc" + #define TEXT6 "xxxxxxyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxx123" + #define TEXT5_6 "abcxxxxxxyyy" + b = htbuffer_init(512); + htbuffer_strcpy(b, TEXT5); + htbuffer_strncpy_w_offset(b, 3, TEXT6, 9); + if (b->current_buf_size != 1024) + printf("9. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else if (strcmp(TEXT5_6, b->buf)) + printf("9. FAILURE: unexpected content {%s}\n", b->buf); + else + printf("9. OK\n"); + htbuffer_free(b); + + /* ------------------------------------------------------------------------------------------- */ + #define TEXT7 "---------XXX" + #define TEXT8 "xxxxxxyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxx123" + #define TEXT9 "xxxxxxyyyXXX" + b = htbuffer_init(512); + htbuffer_strcpy(b, TEXT7); + htbuffer_strncpy(b, TEXT8, 9); + if (b->current_buf_size != 1024) + printf("10. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else if (strcmp(TEXT9, b->buf)) + printf("10. FAILURE: unexpected content {%s}\n", b->buf); + else + printf("10. OK\n"); + htbuffer_free(b); + +/* ------------------------------------------------------------------------------------------- */ + #define TEXT10 "aaa" + #define TEXT11 "bbb" + #define TEXT10_11 "aaabbb" + b = htbuffer_init(512); + htbuffer_strcpy(b, TEXT10); + htbuffer_strcat(b, TEXT11); + if (b->current_buf_size != 1024) + printf("11. FAILURE: wrong current_buf_size (%d), expected 1024\n", b->current_buf_size); + else if (strcmp(TEXT10_11, b->buf)) + printf("11. FAILURE: unexpected content {%s}\n", b->buf); + else + printf("11. OK\n"); + htbuffer_free(b); + + + + + + +} + + + + + + diff --git a/smmapdfw/smmapd/containers.c b/smmapdfw/smmapd/containers.c index 0b45171..432a77f 100644 --- a/smmapdfw/smmapd/containers.c +++ b/smmapdfw/smmapd/containers.c @@ -44,6 +44,7 @@ #include "cfg.h" #include "smmapd.h" #include "htmalloc.h" +#include "htbuffer.h" #define CFG_SECTION_GLOBAL "global" @@ -93,7 +94,7 @@ int containers_destroy(container_handle_t *ch) { } -int containers_dispatcher(container_handle_t *ch, char *input, char *output) { +int containers_dispatcher(container_handle_t *ch, char *input, htbuffer_t *output) { char *class; char *data; classes_t *classes; @@ -144,7 +145,7 @@ int containers_dispatcher(container_handle_t *ch, char *input, char *output) { result = (*classes->descr->work_function)(classes->handle, wh2->handle, data, output); - syslog(LOG_DEBUG, "dispatcher: worker output: (%d, %s)", result, output); + syslog(LOG_DEBUG, "dispatcher: worker output: (%d, %s)", result, output->buf); break; } } diff --git a/smmapdfw/smmapd/containers.h b/smmapdfw/smmapd/containers.h index d8d8ed5..4d8179f 100644 --- a/smmapdfw/smmapd/containers.h +++ b/smmapdfw/smmapd/containers.h @@ -25,6 +25,7 @@ #define _SMMAPD_ #include "containers_public.h" +#include "htbuffer.h" struct classes_s { class_descriptor_t *descr; @@ -51,7 +52,7 @@ typedef struct container_handle_s container_handle_t; int containers_setup(container_handle_t **ch); int containers_destroy(container_handle_t *ch); -int containers_dispatcher(container_handle_t *ch, char *input, char *output); +int containers_dispatcher(container_handle_t *ch, char *input, htbuffer_t *output); int register_all(); diff --git a/smmapdfw/smmapd/smmapd.c b/smmapdfw/smmapd/smmapd.c index 6eadae0..9f8a7c6 100644 --- a/smmapdfw/smmapd/smmapd.c +++ b/smmapdfw/smmapd/smmapd.c @@ -63,6 +63,7 @@ #include "cfg.h" #include "safe_write.h" #include "htmalloc.h" +#include "htbuffer.h" #define _SMMAPD_C_ #include "smmapd.h" @@ -163,7 +164,8 @@ void * networker(void * arg) { char buffer[BUFSIZE+1]; char *input; - char answer[ANSWER_BUFSIZE+1]; + // char answer[ANSWER_BUFSIZE+1]; + htbuffer_t *answer; char output[OUTPUT_BUFSIZE+1]; const char *answer_ptr; const char *result_text; @@ -182,6 +184,8 @@ void * networker(void * arg) { thread->clientSock, inet_ntoa(thread->clientAddr.sin_addr), ntohs(thread->clientAddr.sin_port)); + answer = htbuffer_init(ANSWER_BUFSIZE); + containers_setup(&container_handle); syslog(LOG_DEBUG, "networker: got a container handle"); @@ -216,9 +220,10 @@ void * networker(void * arg) { } if (!dispatcher_result) { - answer[0] = '\0'; + // answer[0] = '\0'; + answer->buf[0] = '\0'; dispatcher_result = containers_dispatcher(container_handle, input, answer); - syslog(LOG_DEBUG, "networker: dispatcher result: %d, answer: %s", dispatcher_result, answer); + syslog(LOG_DEBUG, "networker: dispatcher result: %d, answer: %s", dispatcher_result, answer->buf); } incStatCounter(dispatcher_result + STAT_CNT_OFFSET); @@ -232,7 +237,7 @@ void * networker(void * arg) { T_SMM_RESULT_INFOS[dispatcher_result]; if (NULL == answer_ptr) - answer_ptr = answer; + answer_ptr = answer->buf; if (netstring_disabled) { snprintf(output, OUTPUT_BUFSIZE, "%s\n", answer_ptr); @@ -252,6 +257,8 @@ void * networker(void * arg) { containers_destroy(container_handle); syslog(LOG_DEBUG, "networker: destroyed the container handle"); + htbuffer_free(answer); + thread->result = 1; queue_put(&terminated_networker_queue, thread); diff --git a/smmapdfw/test_worker/test_workers.c b/smmapdfw/test_worker/test_workers.c index ff42fd7..128daf0 100644 --- a/smmapdfw/test_worker/test_workers.c +++ b/smmapdfw/test_worker/test_workers.c @@ -22,13 +22,14 @@ #include #include "containers_public.h" #include "htmalloc.h" +#include "htbuffer.h" int test_worker1_init(cfgl_t *cfg, void **handle); int test_worker1_setup(void *handle, void **work_handle); int test_worker1_destroy(void *handle, void *work_handle); -int test_worker1_work(void *handle, void *work_handle, char *input, char *output); -int test_worker2_work(void *handle, void *work_handle, char *input, char *output); +int test_worker1_work(void *handle, void *work_handle, char *input, htbuffer_t *output); +int test_worker2_work(void *handle, void *work_handle, char *input, htbuffer_t *output); class_descriptor_t test_worker1 = { "test_worker1", @@ -76,14 +77,18 @@ int test_worker1_destroy(void *handle, void *work_handle) { free(work_handle); } -int test_worker1_work(void *handle, void *work_handle, char *input, char *output) { - sprintf(output, "Test-Worker 1 receives %s (handle %s) (called %d)\n", +int test_worker1_work(void *handle, void *work_handle, char *input, htbuffer_t *output) { + char o[1024]; + sprintf(o, "Test-Worker 1 receives %s (handle %s) (called %d)\n", input, (char*)handle, (((test_worker1_handle_t*)work_handle)->counter)++); + htbuffer_strcpy(output, o); return 0; } -int test_worker2_work(void *handle, void *work_handle, char *input, char *output) { - sprintf(output, "Test-Worker 2 receives %s\n", input); +int test_worker2_work(void *handle, void *work_handle, char *input, htbuffer_t *output) { + htbuffer_strcpy(output, "Test-Worker 2 receives"); + htbuffer_strcat(output, input); + htbuffer_strcat(output, "\n"); return 0; } diff --git a/smmapdfw/verify_worker/verify_worker.c b/smmapdfw/verify_worker/verify_worker.c index 3e6bc85..2a58410 100644 --- a/smmapdfw/verify_worker/verify_worker.c +++ b/smmapdfw/verify_worker/verify_worker.c @@ -46,6 +46,7 @@ #include "queue.h" #include "smtp.h" #include "htmalloc.h" +#include "htbuffer.h" #include "stats.h" @@ -134,7 +135,7 @@ typedef struct mydata_s mydata_t; int verify_init(cfgl_t *cfg, void **handle); int verify_destroy(void *handle); int verify_work_setup(void *handle, void **work_handle); -int verify_work(void *handle, void *work_handle, char *input, char *output); +int verify_work(void *handle, void *work_handle, char *input, htbuffer_t *output); int verify_work_destroy(void *handle, void *work_handle); static void *worker_thread(void *arg); @@ -355,7 +356,7 @@ int cache_lookup(verify_work_handle_t *vwh, const char* address, int *result, ch snprintf(output, ANSWER_BUFSIZE, "verify_work: %s", msg); \ return SMM_TEMP_NOK; -int verify_work(void *handle, void *work_handle, char *input, char *output) { +int verify_work(void *handle, void *work_handle, char *input, htbuffer_t *output) { int err; pthread_t tid; worker_thread_t *wt; @@ -405,7 +406,8 @@ int verify_work(void *handle, void *work_handle, char *input, char *output) { TEMP_NOK_RETURN("worker thread timed out"); } - snprintf(output, ANSWER_BUFSIZE, vwh->result->output); + // snprintf(output, ANSWER_BUFSIZE, vwh->result->output); + htbuffer_strcpy(output, vwh->result->output); free(vwh->result->output); return vwh->result->result; }