diff --git a/ChangeLog b/ChangeLog index 17c39e86c..3df093da6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Feb 2 12:56:21 EET 2009 (edwin) +------------------------------------ + * clamd/others.c, clamd/server-th.c, clamd/server.h, + clamd/session.c, clamd/session.h: temp commit + Thu Jan 29 11:47:16 EET 2009 (edwin) ------------------------------------ * libclamav/others.h, libclamav/others_common.c: s/msg/path/ diff --git a/clamd/others.c b/clamd/others.c index d1876de58..5b52a782f 100644 --- a/clamd/others.c +++ b/clamd/others.c @@ -389,7 +389,9 @@ int fds_add(struct fd_data *data, int fd, int listen_only) data->buf[n-1].recvfd = -1; if (!listen_only) { data->buf[n-1].bufsize = PATH_MAX+8; - if (!(data->buf[n-1].buffer = malloc(data->buf[n-1].bufsize))) { + /* plus extra space for a \0 so we can make sure every command is \0 + * terminated */ + if (!(data->buf[n-1].buffer = malloc(data->buf[n-1].bufsize + 1))) { logg("!add_fd: Memory allocation failed for command buffer\n"); return -1; } diff --git a/clamd/scanner.c b/clamd/scanner.c index cae0e74da..b85ac0ab5 100644 --- a/clamd/scanner.c +++ b/clamd/scanner.c @@ -383,9 +383,8 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw client_conn->scanfd = -1; client_conn->sd = scandata->odesc; client_conn->fds = NULL; - client_conn->cmdlen = 0; - client_conn->cmd = "MULTISCANFILE"; client_conn->filename = filename; + client_conn->cmdtype = COMMAND_MULTISCANFILE; client_conn->term = scandata->term; client_conn->options = scandata->options; client_conn->opts = scandata->opts; diff --git a/clamd/server-th.c b/clamd/server-th.c index 1c1fbf994..8c014d1da 100644 --- a/clamd/server-th.c +++ b/clamd/server-th.c @@ -102,86 +102,15 @@ static void scanner_thread(void *arg) timeout = optget(conn->opts, "ReadTimeout")->numarg; if(!timeout) - timeout = -1; - - if (conn->filename) { - /* TODO: this is the bad place for this */ - ret = 0; - if (access(conn->filename, R_OK)) { - mdprintf(conn->sd, "%s: Access denied. ERROR%c", - conn->filename, conn->term); - errors++; - } else { - const char *virname; - thrmgr_setactivetask(conn->filename, - "MULTISCANFILE"); - ret = cl_scanfile(conn->filename, &virname, NULL, conn->engine, conn->options); - thrmgr_setactivetask(NULL, NULL); - if (ret == CL_EMEM) { - if(optget(conn->opts, "ExitOnOOM")->enabled) - ret = COMMAND_SHUTDOWN; - errors++; - } else { - if(ret == CL_VIRUS) { - mdprintf(conn->sd, "%s: %s FOUND%c", conn->filename, virname, conn->term); - logg("~%s: %s FOUND\n", conn->filename, virname); - virusaction(conn->filename, virname, conn->opts); - virus++; - } else if(ret != CL_CLEAN) { - errors++; - mdprintf(conn->sd, "%s: %s ERROR%c", conn->filename, cl_strerror(ret), conn->term); - logg("~%s: %s ERROR\n", conn->filename, cl_strerror(ret)); - } else if(logok) { - logg("~%s: OK\n", conn->filename); - } - ret = 0; - } - } + timeout = -1; + command(conn); + if (ret == COMMAND_SHUTDOWN) { + pthread_mutex_lock(&exit_mutex); + progexit = 1; + pthread_mutex_unlock(&exit_mutex); } - do { - if (!conn->filename) /* TODO: */ - ret = command(conn, timeout); - if (ret < 0) { - break; - } - - switch(ret) { - case COMMAND_SHUTDOWN: - pthread_mutex_lock(&exit_mutex); - progexit = 1; - pthread_mutex_unlock(&exit_mutex); - break; - - case COMMAND_RELOAD: - pthread_mutex_lock(&reload_mutex); - reload = 1; - pthread_mutex_unlock(&reload_mutex); - break; - - case COMMAND_SESSION: - session = TRUE; - break; - - case COMMAND_END: - session = FALSE; - break; - } - if (session) { - pthread_mutex_lock(&exit_mutex); - if(progexit) { - session = FALSE; - } - pthread_mutex_unlock(&exit_mutex); - pthread_mutex_lock(&reload_mutex); - if (conn->engine_timestamp != reloaded_time) { - session = FALSE; - } - pthread_mutex_unlock(&reload_mutex); - } - } while (session); - if (conn->scanfd != -1) close(conn->scanfd); thrmgr_setactiveengine(NULL); @@ -195,8 +124,6 @@ static void scanner_thread(void *arg) if (conn->group) thrmgr_group_finished(conn->group, virus ? EXIT_OTHER : errors ? EXIT_ERROR : EXIT_OK); cl_engine_free(conn->engine); - if (conn->cmdlen) - free(conn->cmd); free(conn); return; } @@ -336,12 +263,18 @@ static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *te return NULL; } *pos = '\0'; - *len = pos - buf->buffer; - return buf->buffer + 1; + if (*term) { + *len = cli_chomp(buf->buffer + off); + } else { + *len = pos - buf->buffer - off; + } + return buf->buffer + off + 1; default: /* one packet = one command */ - *len = buf->off; - return buf->buffer; + *len = buf->off - off; + buf->buffer[buf->off] = '\0'; + cli_chomp(buf->buffer + off); + return buf->buffer + off; } } @@ -842,6 +775,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi } if (buf->fd != -1 && buf->buffer) { + client_conn_t conn; const unsigned char *cmd; size_t cmdlen = 0; size_t pos = 0; @@ -849,12 +783,21 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi char term; /* New data available to read on socket. */ + memset(&conn, 0, sizeof(conn)); + conn.scanfd = buf->recvfd; + buf->recvfd = -1; + conn.sd = buf->fd; + conn.options = options; + conn.opts = opts; + conn.thrpool = thr_pool; + conn.engine = engine; /* Parse & dispatch commands */ while ((cmd = get_cmd(buf, pos, &cmdlen, &term)) != NULL) { + int rc; + const char *argument; + enum commands command = parse_command(cmd, &argument); - /* TODO: when we'll parse commands here, move this out into another - * function */ - if (!strncmp(cmd, CMD14, strlen(CMD14))) {/* FILDES */ + if (command = COMMAND_FILDES) { if ((buf->buffer + buf->off) - (cmd + cmdlen) < 1) { /* we need the extra byte from recvmsg */ cmdlen = 0; @@ -863,51 +806,18 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi /* eat extra \0 for controlmsg */ cmdlen++; } - client_conn_t *client_conn = (client_conn_t *) malloc(sizeof(struct client_conn_tag)); - if(client_conn) { - client_conn->scanfd = buf->recvfd; - buf->recvfd = -1; - client_conn->filename = NULL; - client_conn->group = NULL; - client_conn->sd = buf->fd; - client_conn->fds = fds; - client_conn->cmdlen = cmdlen; - client_conn->cmd = malloc(cmdlen+1); - client_conn->term = term; - if (!client_conn->cmd) { - logg("!acceptloop_th: failed to allocate memory for command\n"); - error = 1; - break; - } - memcpy(client_conn->cmd, cmd, cmdlen); - client_conn->cmd[cmdlen] = '\0'; - client_conn->options = options; - client_conn->opts = opts; - client_conn->thrpool = thr_pool; - if(cl_engine_addref(engine)) { - logg("!cl_engine_addref() failed\n"); - error = 1; - pthread_mutex_lock(&exit_mutex); - progexit = 1; - pthread_mutex_unlock(&exit_mutex); - } else { - client_conn->engine = engine; - client_conn->engine_timestamp = reloaded_time; - if(!thrmgr_dispatch(thr_pool, client_conn)) { - logg("!thread dispatch failed\n"); - error = 1; - } - } - } else { - logg("!Can't allocate memory for client_conn\n"); - if(optget(opts, "ExitOnOOM")->enabled) { + + conn.term = term; + + if ((rc = execute_or_dispatch_command(&conn, command, argument)) < 0) { + if(rc == -1 && optget(opts, "ExitOnOOM")->enabled) { pthread_mutex_lock(&exit_mutex); progexit = 1; pthread_mutex_unlock(&exit_mutex); } error = 1; - break; } + conn.scanfd = -1; pos += cmdlen+1; } diff --git a/clamd/server.h b/clamd/server.h index 65238df7e..d6974a583 100644 --- a/clamd/server.h +++ b/clamd/server.h @@ -26,23 +26,7 @@ #include "libclamav/clamav.h" #include "shared/optparser.h" #include "thrmgr.h" - -/* TODO: these don't belong here */ -enum commands { - COMMAND_SHUTDOWN = 1, - COMMAND_RELOAD, - COMMAND_END, - COMMAND_SESSION, - COMMAND_SCAN, - COMMAND_PING, - COMMAND_CONTSCAN, - COMMAND_VERSION, - COMMAND_STREAM, - COMMAND_MULTISCAN, - COMMAND_FILDES, - COMMAND_STATS, - COMMAND_MULTISCANFILE /* internal */ -}; +#include "session.h" struct thrarg { int sid; int options; @@ -60,26 +44,12 @@ struct thrwarg { unsigned int options; }; -typedef struct client_conn_tag { - char *cmd; - size_t cmdlen; - enum commands cmdtype; - char *filename; - int scanfd; - int sd; - struct fd_data *fds; - unsigned int options; - const struct optstruct *opts; - struct cl_engine *engine; - time_t engine_timestamp; - char term; - threadpool_t *thrpool; - jobgroup_t *group; -} client_conn_t; - int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts); void sighandler(int sig); void sighandler_th(int sig); void sigsegv(int sig); +extern pthread_mutex_t exit_mutex, reload_mutex; +extern int progexit, reload; + #endif diff --git a/clamd/session.c b/clamd/session.c index 723fa9080..a817cda63 100644 --- a/clamd/session.c +++ b/clamd/session.c @@ -114,132 +114,250 @@ static int recvfd_and_scan(int desc, const struct cl_engine *engine, unsigned in } #endif -int command(client_conn_t *conn, int timeout) +enum commands parse_command(const char *cmd, const char **argument) { + *argument = NULL; + if (!strncmp(cmd, CMD1, strlen(CMD1))) { /* SCAN */ + *argument = cmd + strlen(CMD1) + 1; + return COMMAND_SCAN; + } else if (!strncmp(cmd, CMD3, strlen(CMD3))) { /* QUIT */ + return COMMAND_SHUTDOWN; + } else if (!strncmp(cmd, CMD4, strlen(CMD4))) { /* RELOAD */ + return COMMAND_RELOAD; + } else if (!strncmp(cmd, CMD5, strlen(CMD5))) { /* PING */ + return COMMAND_PING; + } else if (!strncmp(cmd, CMD6, strlen(CMD6))) { /* CONTSCAN */ + *argument = cmd + strlen(CMD6) + 1; + return COMMAND_CONTSCAN; + } else if (!strncmp(cmd, CMD7, strlen(CMD7))) { /* VERSION */ + return COMMAND_VERSION; + } else if (!strncmp(cmd, CMD8, strlen(CMD8))) { /* STREAM */ + return COMMAND_STREAM; +#if 0 + } else if (!strncmp(cmd, CMD9, strlen(CMD9))) { /* SESSION */ + return COMMAND_SESSION; +#endif + } else if (!strncmp(cmd, CMD10, strlen(CMD10))) { /* END */ + return COMMAND_END; + } else if (!strncmp(cmd, CMD11, strlen(CMD11))) { /* SHUTDOWN */ + return COMMAND_SHUTDOWN; + } else if (!strncmp(cmd, CMD13, strlen(CMD13))) { /* MULTISCAN */ + *argument = cmd + strlen(CMD13) + 1; + return COMMAND_MULTISCAN; + } else if (!strncmp(cmd, CMD14, strlen(CMD14))) { /* FILDES */ + return COMMAND_FILDES; + } else if (!strncmp(cmd, CMD15, strlen(CMD15))) { /* STATS */ + return COMMAND_STATS; + } else if (!strncmp(cmd, CMD16, strlen(CMD16))) { /* IDSESSION */ + return COMMAND_IDSESSION; + } + return COMMAND_UNKNOWN; +} +int command(client_conn_t *conn) +{ int desc = conn->sd; - char *buff = conn->cmd; - size_t cmdlen = conn->cmdlen; struct cl_engine *engine = conn->engine; unsigned int options = conn->options; const struct optstruct *opts = conn->opts; const char term = conn->term; + int type; /* TODO: make this enum */ - if (conn->term) - cli_chomp(buff); - thrmgr_setactiveengine(engine); - - if(!strncmp(buff, CMD1, strlen(CMD1))) { /* SCAN */ - thrmgr_setactivetask(NULL, CMD1); - if(scan(buff + strlen(CMD1) + 1, term, NULL, engine, options, opts, desc, TYPE_SCAN) == -2) - if(optget(opts, "ExitOnOOM")->enabled) - return COMMAND_SHUTDOWN; - - } else if(!strncmp(buff, CMD3, strlen(CMD3))) { /* QUIT */ - thrmgr_setactivetask(NULL, CMD3); - return COMMAND_SHUTDOWN; - - } else if(!strncmp(buff, CMD4, strlen(CMD4))) { /* RELOAD */ - thrmgr_setactivetask(NULL, CMD4); - /* we'll reload, hide the engine, if we are the last - * holding a ref to the engine it'll be freed, - * we don't want STATS command to access it */ - thrmgr_setactiveengine(NULL); - mdprintf(desc, "RELOADING%c", conn->term); - return COMMAND_RELOAD; - - } else if(!strncmp(buff, CMD5, strlen(CMD5))) { /* PING */ - thrmgr_setactivetask(NULL, CMD5); - mdprintf(desc, "PONG%c", conn->term); - - } else if(!strncmp(buff, CMD6, strlen(CMD6))) { /* CONTSCAN */ - thrmgr_setactivetask(NULL, CMD6); - if(scan(buff + strlen(CMD6) + 1, term, NULL, engine, options, opts, desc, TYPE_CONTSCAN) == -2) - if(optget(opts, "ExitOnOOM")->enabled) - return COMMAND_SHUTDOWN; - - } else if(!strncmp(buff, CMD7, strlen(CMD7))) { /* VERSION */ - uint32_t ver; - - thrmgr_setactivetask(NULL, CMD7); - cl_engine_get(engine, CL_ENGINE_DB_VERSION, &ver); - if(ver) { - char timestr[32]; - const char *tstr; - time_t t; - cl_engine_get(engine, CL_ENGINE_DB_TIME, &t); - tstr = cli_ctime(&t, timestr, sizeof(timestr)); - /* cut trailing \n */ - timestr[strlen(tstr)-1] = '\0'; - mdprintf(desc, "ClamAV %s/%u/%s%c", get_version(), (unsigned int) ver, tstr, conn->term); - } else { - mdprintf(desc, "ClamAV %s%c", get_version(), conn->term); - } - - } else if(!strncmp(buff, CMD8, strlen(CMD8))) { /* STREAM */ - thrmgr_setactivetask(NULL, CMD8); - if(scanstream(desc, NULL, engine, options, opts, conn->term) == CL_EMEM) - if(optget(opts, "ExitOnOOM")->enabled) - return COMMAND_SHUTDOWN; - - } else if(!strncmp(buff, CMD9, strlen(CMD9))) { /* SESSION */ - thrmgr_setactivetask(NULL, CMD9); - return COMMAND_SESSION; - - } else if(!strncmp(buff, CMD10, strlen(CMD10))) { /* END */ - thrmgr_setactivetask(NULL, CMD10); - return COMMAND_END; - - } else if(!strncmp(buff, CMD11, strlen(CMD11))) { /* SHUTDOWN */ - thrmgr_setactivetask(NULL, CMD11); - return COMMAND_SHUTDOWN; + struct scan_cb_data scandata; + struct cli_ftw_cbdata data; + unsigned ok, error, total; + jobgroup_t group = JOBGROUP_INITIALIZER; - } else if(!strncmp(buff, CMD13, strlen(CMD13))) { /* MULTISCAN */ - struct scan_cb_data scandata; - struct cli_ftw_cbdata data; - unsigned ok, error, total; - const char *path = buff + strlen(CMD13) + 1; - jobgroup_t group = JOBGROUP_INITIALIZER; - data.data = &scandata; - - memset(&scandata, 0, sizeof(scandata)); - scandata.type = TYPE_MULTISCAN; - scandata.odesc = desc; - scandata.term = term; - scandata.options = options; - scandata.engine = engine; - scandata.opts = opts; - scandata.thr_pool = conn->thrpool; - scandata.group = &group; - thrmgr_setactivetask(buff+strlen(CMD13)+1, CMD13); - int maxdirrec = optget(opts, "MaxDirectoryRecursion")->numarg; - - if (cli_ftw(path, CLI_FTW_STD, maxdirrec ? maxdirrec : INT_MAX, scan_callback, &data) == CL_EMEM) - if(optget(opts, "ExitOnOOM")->enabled) - return COMMAND_SHUTDOWN; - thrmgr_group_waitforall(&group, &ok, &error, &total); - if (ok + error == total) { - mdprintf(desc, "%s: OK%c", path, conn->term); - } + thrmgr_setactiveengine(engine); - } else if(!strncmp(buff, CMD14, strlen(CMD14))) { /* FILDES */ - thrmgr_setactivetask(NULL, CMD14); + data.data = &scandata; + memset(&scandata, 0, sizeof(scandata)); + scandata.group = conn->group; + scandata.type = type; + scandata.odesc = desc; + scandata.term = term; + scandata.options = options; + scandata.engine = engine; + scandata.opts = opts; + scandata.thr_pool = conn->thrpool; + + switch (conn->cmdtype) { + case COMMAND_SCAN: + thrmgr_setactivetask(NULL, "SCAN"); + type = TYPE_SCAN; + break; + case COMMAND_CONTSCAN: + thrmgr_setactivetask(NULL, "CONTSCAN"); + type = TYPE_CONTSCAN; + break; + case COMMAND_MULTISCAN: + thrmgr_setactivetask(NULL, "MULTISCAN"); + type = TYPE_MULTISCAN; + scandata.group = &group; + break; + case COMMAND_MULTISCANFILE: + thrmgr_setactivetask(NULL, "MULTISCANFILE"); + scandata.group = NULL; + /* TODO: check ret value */ + scan_callback(NULL, conn->filename, conn->filename, visit_file, &data); + break; + case COMMAND_FILDES: + thrmgr_setactivetask(NULL, "FILDES"); #ifdef HAVE_FD_PASSING - if (conn->scanfd == -1) - mdprintf(desc, "FILDES: didn't receive file descriptor %c", conn->term); - else if (scanfd(conn->scanfd, conn->term, NULL, engine, options, opts, desc) == -2) - if(optget(opts, "ExitOnOOM")->enabled) - return COMMAND_SHUTDOWN; + if (conn->scanfd == -1) + mdprintf(desc, "FILDES: didn't receive file descriptor %c", conn->term); + else if (scanfd(conn->scanfd, conn->term, NULL, engine, options, opts, desc) == -2) + if(optget(opts, "ExitOnOOM")->enabled) + return COMMAND_SHUTDOWN; + return 0; #else - mdprintf(desc, "FILDES support not compiled inERROR%c",conn->term); - return -1; + mdprintf(desc, "FILDES support not compiled inERROR%c",conn->term); + return -1; #endif - } else if(!strncmp(buff, CMD15, strlen(CMD15))) { /* STATS */ - thrmgr_setactivetask(NULL, CMD15); + case COMMAND_STATS: + thrmgr_setactivetask(NULL, "STATS"); thrmgr_printstats(desc); - } else { - mdprintf(desc, "UNKNOWN COMMAND%c", conn->term); + return 0; + case COMMAND_STREAM: + thrmgr_setactivetask(NULL, "STREAM"); + if(scanstream(desc, NULL, engine, options, opts, conn->term) == CL_EMEM) + if(optget(opts, "ExitOnOOM")->enabled) + return COMMAND_SHUTDOWN; + return 0; } + int maxdirrec = optget(opts, "MaxDirectoryRecursion")->numarg; + // TODO: flags symlink from opt + if (cli_ftw(conn->filename, CLI_FTW_STD, maxdirrec ? maxdirrec : INT_MAX, scan_callback, &data) == CL_EMEM) + if(optget(opts, "ExitOnOOM")->enabled) + return COMMAND_SHUTDOWN; + if (scandata.group) + thrmgr_group_waitforall(&group, &ok, &error, &total); + if (ok + error == total) { + mdprintf(desc, "%s: OK%c", conn->filename, conn->term); + } return 0; /* no error and no 'special' command executed */ } + +static int dispatch_command(const client_conn_t *conn, enum commands command, const char *argument) +{ + client_conn_t *dup_conn = (client_conn_t *) malloc(sizeof(struct client_conn_tag)); + if(!dup_conn) { + logg("!Can't allocate memory for client_conn\n"); + return -1; + } + memcpy(dup_conn, conn, sizeof(*conn)); + dup_conn->cmdtype = command; + if(cl_engine_addref(dup_conn->engine)) { + logg("!cl_engine_addref() failed\n"); + return -1; + } + dup_conn->scanfd = -1; + switch (command) { + case COMMAND_FILDES: + dup_conn->scanfd = conn->scanfd; + break; + case COMMAND_SCAN: + case COMMAND_CONTSCAN: + case COMMAND_MULTISCAN: + dup_conn->filename = strdup(argument); + if (!dup_conn->filename) { + logg("!Failed to allocate memory for filename\n"); + return -1; + } + break; + case COMMAND_STREAM: + case COMMAND_STATS: + /* just dispatch the command */ + break; + } + if(!thrmgr_dispatch(dup_conn->thrpool, dup_conn)) { + logg("!thread dispatch failed\n"); + return -2; + } + return 0; +} + +/* returns: + * <0 for error + * -1 out of memory + * -2 other + * 0 for async dispatched + * 1 for command completed (connection can be closed) + */ +int execute_or_dispatch_command(client_conn_t *conn, enum commands command, const char *argument) +{ + int desc = conn->sd; + char term = conn->term; + const struct cl_engine *engine = conn->engine; + /* execute commands that can be executed quickly on the recvloop thread, + * these must: + * - not involve any operation that can block for a long time, such as disk + * I/O + * - send of atomic message is allowed. + * Dispatch other commands */ + switch (command) { + case COMMAND_SHUTDOWN: + pthread_mutex_lock(&exit_mutex); + progexit = 1; + pthread_mutex_unlock(&exit_mutex); + return 1; + case COMMAND_RELOAD: + pthread_mutex_lock(&reload_mutex); + reload = 1; + pthread_mutex_unlock(&reload_mutex); + mdprintf(desc, "RELOADING%c", term); + /* we set reload flag, and we'll reload before closing the + * connection */ + return 1; + case COMMAND_PING: + mdprintf(desc, "PONG%c", term); + return 1; + case COMMAND_VERSION: + { + uint32_t ver; + cl_engine_get(engine, CL_ENGINE_DB_VERSION, &ver); + if(ver) { + char timestr[32]; + const char *tstr; + time_t t; + cl_engine_get(engine, CL_ENGINE_DB_TIME, &t); + tstr = cli_ctime(&t, timestr, sizeof(timestr)); + /* cut trailing \n */ + timestr[strlen(tstr)-1] = '\0'; + mdprintf(desc, "ClamAV %s/%u/%s%c", get_version(), (unsigned int) ver, tstr, term); + } else { + mdprintf(desc, "ClamAV %s%c", get_version(), conn->term); + } + return 1; + } + case COMMAND_FILDES: + case COMMAND_SCAN: + case COMMAND_CONTSCAN: + case COMMAND_STREAM: + case COMMAND_MULTISCAN: + case COMMAND_STATS: + return dispatch_command(conn, command, argument); + case COMMAND_IDSESSION: + if (conn->group) { + /* we are already inside an idsession/multiscan */ + mdprintf(desc, "UNKNOWN COMMAND%c", term); + return 1; + } + conn->group = calloc(1, sizeof(*conn->group)); + if (!conn->group) + return CL_EMEM; + return 0; + case COMMAND_END: + if (!conn->group) { + /* end without idsession? */ + mdprintf(desc, "UNKNOWN COMMAND%c", term); + return 1; + } + return 1; + /*case COMMAND_UNKNOWN:*/ + default: + mdprintf(desc, "UNKNOWN COMMAND%c", term); + return 1; + } +} diff --git a/clamd/session.h b/clamd/session.h index a6a2e4e0f..70365d47f 100644 --- a/clamd/session.h +++ b/clamd/session.h @@ -28,18 +28,57 @@ #define CMD6 "CONTSCAN" #define CMD7 "VERSION" #define CMD8 "STREAM" -#define CMD9 "SESSION" +/*#define CMD9 "SESSION"*/ #define CMD10 "END" #define CMD11 "SHUTDOWN" /* #define CMD12 "FD" */ #define CMD13 "MULTISCAN" #define CMD14 "FILDES" #define CMD15 "STATS" +#define CMD16 "IDSESSION" #include "libclamav/clamav.h" #include "shared/optparser.h" #include "server.h" -int command(client_conn_t *conn, int timeout); +enum commands { + COMMAND_UNKNOWN = 0, + COMMAND_SHUTDOWN = 1, + COMMAND_RELOAD, + COMMAND_END, + COMMAND_SESSION, + COMMAND_SCAN, + COMMAND_PING, + COMMAND_CONTSCAN, + COMMAND_VERSION, + COMMAND_STREAM, + COMMAND_MULTISCAN, + COMMAND_FILDES, + COMMAND_STATS, + /* new proto commands */ + COMMAND_IDSESSION, + COMMAND_INSTREAM, + /* internal commands */ + COMMAND_MULTISCANFILE +}; + +typedef struct client_conn_tag { + enum commands cmdtype; + char *filename; + int scanfd; + int sd; + struct fd_data *fds; + unsigned int options; + const struct optstruct *opts; + struct cl_engine *engine; + time_t engine_timestamp; + char term; + threadpool_t *thrpool; + jobgroup_t *group; +} client_conn_t; + +int command(client_conn_t *conn); +enum commands parse_command(const char *cmd, const char **argument); +int execute_or_dispatch_command(client_conn_t *conn, enum commands command, const char *argument); #endif