diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-10-02 17:09:38 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-10-02 17:09:38 +0400 |
commit | f3ad9c6f1e91c9912dbe730fdec350b5fc908672 (patch) | |
tree | 005e5568431db09becaa9b67a33dfc11f80bba7f | |
parent | e6a1d22de250c10992b484635fd95a03f197f779 (diff) | |
download | rspamd-f3ad9c6f1e91c9912dbe730fdec350b5fc908672.tar.gz rspamd-f3ad9c6f1e91c9912dbe730fdec350b5fc908672.zip |
* Retab, no functional changes
50 files changed, 6906 insertions, 7033 deletions
diff --git a/src/bloom.c b/src/bloom.c index eebaac009..154296e16 100644 --- a/src/bloom.c +++ b/src/bloom.c @@ -36,7 +36,7 @@ \ a[n * SIZE_BIT / CHAR_BIT] &= (0xF << (4 - (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT))); \ a[n * SIZE_BIT / CHAR_BIT] |= (acc << (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT)); \ -} while (0); +} while (0); #define DECBIT(a, n, acc) do { \ acc = a[n * SIZE_BIT / CHAR_BIT] & (0xF << (n % (CHAR_BIT / SIZE_BIT) * SIZE_BIT)); \ @@ -50,22 +50,24 @@ #define GETBIT(a, n) (a[n * SIZE_BIT / CHAR_BIT] & (0xF << (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT))) /* Common hash functions */ -unsigned int -bloom_sax_hash(const char *key) +unsigned int +bloom_sax_hash (const char *key) { - unsigned int h = 0; + unsigned int h = 0; - while(*key) h ^= (h<<5) + (h>>2) + (unsigned char)*key++; + while (*key) + h ^= (h << 5) + (h >> 2) + (unsigned char)*key++; return h; } -unsigned int -bloom_sdbm_hash(const char *key) +unsigned int +bloom_sdbm_hash (const char *key) { - unsigned int h = 0; + unsigned int h = 0; - while(*key) h = (unsigned char)*key++ + (h<<6) + (h<<16) - h; + while (*key) + h = (unsigned char)*key++ + (h << 6) + (h << 16) - h; return h; } @@ -73,22 +75,22 @@ bloom_sdbm_hash(const char *key) unsigned int bloom_fnv_hash (const char *key) { - unsigned int h = 0; - + unsigned int h = 0; + while (*key) { h ^= (unsigned char)*key++; - h += (h<<1) + (h<<4) + (h<<7) + (h<<8) + (h<<24); + h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24); } return h; } -unsigned int +unsigned int bloom_rs_hash (const char *key) { - unsigned int b = 378551; - unsigned int a = 63689; - unsigned int hash = 0; + unsigned int b = 378551; + unsigned int a = 63689; + unsigned int hash = 0; while (*key) { hash = hash * a + (unsigned char)*key++; @@ -98,10 +100,10 @@ bloom_rs_hash (const char *key) return hash; } -unsigned int +unsigned int bloom_js_hash (const char *key) { - unsigned int hash = 1315423911; + unsigned int hash = 1315423911; while (*key) { hash ^= ((hash << 5) + (unsigned char)*key++ + (hash >> 2)); @@ -111,15 +113,15 @@ bloom_js_hash (const char *key) } -unsigned int +unsigned int bloom_elf_hash (const char *key) { - unsigned int hash = 0; - unsigned int x = 0; + unsigned int hash = 0; + unsigned int x = 0; while (*key) { hash = (hash << 4) + (unsigned char)*key++; - if((x = hash & 0xF0000000L) != 0) { + if ((x = hash & 0xF0000000L) != 0) { hash ^= (x >> 24); } hash &= ~x; @@ -129,46 +131,45 @@ bloom_elf_hash (const char *key) } -unsigned int +unsigned int bloom_bkdr_hash (const char *key) { - unsigned int seed = 131; /* 31 131 1313 13131 131313 etc.. */ - unsigned int hash = 0; + unsigned int seed = 131; /* 31 131 1313 13131 131313 etc.. */ + unsigned int hash = 0; while (*key) { - hash = (hash * seed) + (unsigned char)*key ++; + hash = (hash * seed) + (unsigned char)*key++; } return hash; } -unsigned int +unsigned int bloom_ap_hash (const char *key) { - unsigned int hash = 0xAAAAAAAA; - unsigned int i = 0; + unsigned int hash = 0xAAAAAAAA; + unsigned int i = 0; while (*key) { - hash ^= ((i & 1) == 0) ? ((hash << 7) ^ ((unsigned char)*key) * (hash >> 3)) : - (~((hash << 11) + (((unsigned char)*key) ^ (hash >> 5)))); + hash ^= ((i & 1) == 0) ? ((hash << 7) ^ ((unsigned char)*key) * (hash >> 3)) : (~((hash << 11) + (((unsigned char)*key) ^ (hash >> 5)))); key++; } return hash; } -bloom_filter_t * +bloom_filter_t * bloom_create (size_t size, size_t nfuncs, ...) { - bloom_filter_t *bloom; - va_list l; - int n; + bloom_filter_t *bloom; + va_list l; + int n; if (!(bloom = g_malloc (sizeof (bloom_filter_t)))) { return NULL; } - if (!(bloom->a = g_new0 (char, (size + CHAR_BIT - 1) / CHAR_BIT * SIZE_BIT))) { + if (!(bloom->a = g_new0 (char, (size + CHAR_BIT - 1) / CHAR_BIT * SIZE_BIT))) { g_free (bloom); return NULL; } @@ -191,7 +192,7 @@ bloom_create (size_t size, size_t nfuncs, ...) } void -bloom_destroy (bloom_filter_t *bloom) +bloom_destroy (bloom_filter_t * bloom) { g_free (bloom->a); g_free (bloom->funcs); @@ -199,10 +200,10 @@ bloom_destroy (bloom_filter_t *bloom) } gboolean -bloom_add (bloom_filter_t *bloom, const char *s) +bloom_add (bloom_filter_t * bloom, const char *s) { - size_t n; - u_char t; + size_t n; + u_char t; for (n = 0; n < bloom->nfuncs; ++n) { INCBIT (bloom->a, bloom->funcs[n] (s) % bloom->asize, t); @@ -212,23 +213,23 @@ bloom_add (bloom_filter_t *bloom, const char *s) } gboolean -bloom_del (bloom_filter_t *bloom, const char *s) +bloom_del (bloom_filter_t * bloom, const char *s) { - size_t n; - u_char t; + size_t n; + u_char t; for (n = 0; n < bloom->nfuncs; ++n) { DECBIT (bloom->a, bloom->funcs[n] (s) % bloom->asize, t); } return TRUE; - + } gboolean bloom_check (bloom_filter_t * bloom, const char *s) { - size_t n; + size_t n; for (n = 0; n < bloom->nfuncs; ++n) { if (!(GETBIT (bloom->a, bloom->funcs[n] (s) % bloom->asize))) diff --git a/src/buffer.c b/src/buffer.c index 125c11686..6e862664a 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -28,23 +28,23 @@ #define G_DISPATCHER_ERROR dispatcher_error_quark() -static void dispatcher_cb (int fd, short what, void *arg); +static void dispatcher_cb (int fd, short what, void *arg); -static inline GQuark +static inline GQuark dispatcher_error_quark (void) { - return g_quark_from_static_string ("g-dispatcher-error-quark"); + return g_quark_from_static_string ("g-dispatcher-error-quark"); } #define BUFREMAIN(x) (x)->data->size - ((x)->pos - (x)->data->begin) -static gboolean -write_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean is_delayed) +static gboolean +write_buffers (int fd, rspamd_io_dispatcher_t * d, gboolean is_delayed) { - GList *cur; - GError *err; - rspamd_buffer_t *buf; - ssize_t r; + GList *cur; + GError *err; + rspamd_buffer_t *buf; + ssize_t r; /* Fix order */ if (d->out_buffers) { @@ -52,7 +52,7 @@ write_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean is_delayed) } cur = g_list_first (d->out_buffers); while (cur) { - buf = (rspamd_buffer_t *)cur->data; + buf = (rspamd_buffer_t *) cur->data; if (BUFREMAIN (buf) == 0) { /* Skip empty buffers */ cur = g_list_next (cur); @@ -106,7 +106,7 @@ write_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean is_delayed) return FALSE; } } - + event_del (d->ev); event_set (d->ev, fd, EV_READ | EV_PERSIST, dispatcher_cb, (void *)d); event_add (d->ev, d->tv); @@ -122,16 +122,16 @@ write_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean is_delayed) } static void -read_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean skip_read) +read_buffers (int fd, rspamd_io_dispatcher_t * d, gboolean skip_read) { - ssize_t r; - GError *err; - f_str_t res; - char *c, *b; - char **pos; - size_t *len; - enum io_policy saved_policy; - + ssize_t r; + GError *err; + f_str_t res; + char *c, *b; + char **pos; + size_t *len; + enum io_policy saved_policy; + if (d->wanna_die) { rspamd_remove_dispatcher (d); return; @@ -150,7 +150,7 @@ read_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean skip_read) pos = &d->in_buf->pos; len = &d->in_buf->data->len; - + if (BUFREMAIN (d->in_buf) == 0) { /* Buffer is full, try to call callback with overflow error */ if (d->err_callback) { @@ -185,63 +185,34 @@ read_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean skip_read) *pos += r; *len += r; } - msg_debug ("read_buffers: read %ld characters, policy is %s, watermark is: %ld", - (long int)r, d->policy == BUFFER_LINE ? "LINE" : "CHARACTER", - (long int)d->nchars); + msg_debug ("read_buffers: read %ld characters, policy is %s, watermark is: %ld", (long int)r, d->policy == BUFFER_LINE ? "LINE" : "CHARACTER", (long int)d->nchars); } - + saved_policy = d->policy; c = d->in_buf->data->begin; b = c; r = 0; switch (d->policy) { - case BUFFER_LINE: - while (r < *len) { - if (*c == '\n') { - res.begin = b; - res.len = r; - if (r != 0 && *(c - 1) == '\r') { - res.len --; - } - if (d->read_callback) { - if (!d->read_callback (&res, d->user_data)) { - return; - } - /* Move remaining string to begin of buffer (draining) */ - memmove (d->in_buf->data->begin, c + 1, *len - r - 1); - b = d->in_buf->data->begin; - c = b; - *len -= r + 1; - *pos = b + *len; - r = 0; - if (d->policy != saved_policy) { - msg_debug ("read_buffers: policy changed during callback, restart buffer's processing"); - read_buffers (fd, d, TRUE); - return; - } - } - } - r ++; - c ++; - } - break; - case BUFFER_CHARACTER: - r = d->nchars; - if (*len >= r) { + case BUFFER_LINE: + while (r < *len) { + if (*c == '\n') { res.begin = b; res.len = r; - c = b + r; + if (r != 0 && *(c - 1) == '\r') { + res.len--; + } if (d->read_callback) { if (!d->read_callback (&res, d->user_data)) { return; } /* Move remaining string to begin of buffer (draining) */ - memmove (d->in_buf->data->begin, c, *len - r); + memmove (d->in_buf->data->begin, c + 1, *len - r - 1); b = d->in_buf->data->begin; c = b; - *len -= r; + *len -= r + 1; *pos = b + *len; + r = 0; if (d->policy != saved_policy) { msg_debug ("read_buffers: policy changed during callback, restart buffer's processing"); read_buffers (fd, d, TRUE); @@ -249,7 +220,34 @@ read_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean skip_read) } } } - break; + r++; + c++; + } + break; + case BUFFER_CHARACTER: + r = d->nchars; + if (*len >= r) { + res.begin = b; + res.len = r; + c = b + r; + if (d->read_callback) { + if (!d->read_callback (&res, d->user_data)) { + return; + } + /* Move remaining string to begin of buffer (draining) */ + memmove (d->in_buf->data->begin, c, *len - r); + b = d->in_buf->data->begin; + c = b; + *len -= r; + *pos = b + *len; + if (d->policy != saved_policy) { + msg_debug ("read_buffers: policy changed during callback, restart buffer's processing"); + read_buffers (fd, d, TRUE); + return; + } + } + } + break; } } @@ -258,50 +256,47 @@ read_buffers (int fd, rspamd_io_dispatcher_t *d, gboolean skip_read) static void dispatcher_cb (int fd, short what, void *arg) { - rspamd_io_dispatcher_t *d = (rspamd_io_dispatcher_t *)arg; - GError *err; + rspamd_io_dispatcher_t *d = (rspamd_io_dispatcher_t *) arg; + GError *err; msg_debug ("dispatcher_cb: in dispatcher callback, what: %d, fd: %d", (int)what, fd); switch (what) { - case EV_TIMEOUT: - if (d->err_callback) { - err = g_error_new (G_DISPATCHER_ERROR, ETIMEDOUT, "IO timeout"); - d->err_callback (err, d->user_data); - } - break; - case EV_WRITE: - /* No data to write, disable further EV_WRITE to this fd */ - if (d->out_buffers == NULL) { - event_del (d->ev); - event_set (d->ev, fd, EV_READ | EV_PERSIST, dispatcher_cb, (void *)d); - event_add (d->ev, d->tv); - } - else { - /* Delayed write */ - write_buffers (fd, d, TRUE); - } - break; - case EV_READ: - read_buffers (fd, d, FALSE); - break; + case EV_TIMEOUT: + if (d->err_callback) { + err = g_error_new (G_DISPATCHER_ERROR, ETIMEDOUT, "IO timeout"); + d->err_callback (err, d->user_data); + } + break; + case EV_WRITE: + /* No data to write, disable further EV_WRITE to this fd */ + if (d->out_buffers == NULL) { + event_del (d->ev); + event_set (d->ev, fd, EV_READ | EV_PERSIST, dispatcher_cb, (void *)d); + event_add (d->ev, d->tv); + } + else { + /* Delayed write */ + write_buffers (fd, d, TRUE); + } + break; + case EV_READ: + read_buffers (fd, d, FALSE); + break; } } -rspamd_io_dispatcher_t* +rspamd_io_dispatcher_t * rspamd_create_dispatcher (int fd, enum io_policy policy, - dispatcher_read_callback_t read_cb, - dispatcher_write_callback_t write_cb, - dispatcher_err_callback_t err_cb, - struct timeval *tv, void *user_data) + dispatcher_read_callback_t read_cb, dispatcher_write_callback_t write_cb, dispatcher_err_callback_t err_cb, struct timeval *tv, void *user_data) { - rspamd_io_dispatcher_t *new; + rspamd_io_dispatcher_t *new; if (fd == -1) { return NULL; } - + new = g_malloc (sizeof (rspamd_io_dispatcher_t)); bzero (new, sizeof (rspamd_io_dispatcher_t)); @@ -329,8 +324,8 @@ rspamd_create_dispatcher (int fd, enum io_policy policy, return new; } -void -rspamd_remove_dispatcher (rspamd_io_dispatcher_t *dispatcher) +void +rspamd_remove_dispatcher (rspamd_io_dispatcher_t * dispatcher) { if (dispatcher != NULL) { event_del (dispatcher->ev); @@ -342,13 +337,11 @@ rspamd_remove_dispatcher (rspamd_io_dispatcher_t *dispatcher) } } -void -rspamd_set_dispatcher_policy (rspamd_io_dispatcher_t *d, - enum io_policy policy, - size_t nchars) +void +rspamd_set_dispatcher_policy (rspamd_io_dispatcher_t * d, enum io_policy policy, size_t nchars) { - f_str_t *tmp; - int t; + f_str_t *tmp; + int t; if (d->policy != policy) { d->policy = policy; @@ -379,17 +372,15 @@ rspamd_set_dispatcher_policy (rspamd_io_dispatcher_t *d, msg_debug ("rspamd_set_dispatcher_policy: new input length watermark is %ld", (long int)d->nchars); } -gboolean -rspamd_dispatcher_write (rspamd_io_dispatcher_t *d, - void *data, - size_t len, gboolean delayed, gboolean allocated) +gboolean +rspamd_dispatcher_write (rspamd_io_dispatcher_t * d, void *data, size_t len, gboolean delayed, gboolean allocated) { - rspamd_buffer_t *newbuf; + rspamd_buffer_t *newbuf; newbuf = memory_pool_alloc (d->pool, sizeof (rspamd_buffer_t)); if (!allocated) { newbuf->data = fstralloc (d->pool, len); - + /* We need to copy data to temporary internal buffer to avoid using of stack variables */ memcpy (newbuf->data->begin, data, len); } @@ -401,7 +392,7 @@ rspamd_dispatcher_write (rspamd_io_dispatcher_t *d, newbuf->pos = newbuf->data->begin; newbuf->data->len = len; - + d->out_buffers = g_list_prepend (d->out_buffers, newbuf); if (!delayed) { @@ -411,8 +402,8 @@ rspamd_dispatcher_write (rspamd_io_dispatcher_t *d, return TRUE; } -void -rspamd_dispatcher_pause (rspamd_io_dispatcher_t *d) +void +rspamd_dispatcher_pause (rspamd_io_dispatcher_t * d) { event_del (d->ev); } diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 0acd50be8..9387ca36f 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -34,35 +34,38 @@ #define DEFAULT_SCORE 10.0 -extern int yylineno; -extern char *yytext; +extern int yylineno; +extern char *yytext; int add_memcached_server (struct config_file *cf, char *str) { - char *cur_tok, *err_str; - struct memcached_server *mc; - struct hostent *hent; - uint16_t port; + char *cur_tok, *err_str; + struct memcached_server *mc; + struct hostent *hent; + uint16_t port; - if (str == NULL) return 0; + if (str == NULL) + return 0; cur_tok = strsep (&str, ":"); - if (cur_tok == NULL || *cur_tok == '\0') return 0; + if (cur_tok == NULL || *cur_tok == '\0') + return 0; - if(cf->memcached_servers_num == MAX_MEMCACHED_SERVERS) { + if (cf->memcached_servers_num == MAX_MEMCACHED_SERVERS) { yywarn ("yyparse: maximum number of memcached servers is reached %d", MAX_MEMCACHED_SERVERS); } - + mc = &cf->memcached_servers[cf->memcached_servers_num]; - if (mc == NULL) return 0; + if (mc == NULL) + return 0; /* cur_tok - server name, str - server port */ if (str == NULL) { port = DEFAULT_MEMCACHED_PORT; } else { - port = (uint16_t)strtoul (str, &err_str, 10); + port = (uint16_t) strtoul (str, &err_str, 10); if (*err_str != '\0') { return 0; } @@ -75,7 +78,7 @@ add_memcached_server (struct config_file *cf, char *str) return 0; } else { - memcpy((char *)&mc->addr, hent->h_addr, sizeof(struct in_addr)); + memcpy ((char *)&mc->addr, hent->h_addr, sizeof (struct in_addr)); } } mc->port = port; @@ -86,14 +89,15 @@ add_memcached_server (struct config_file *cf, char *str) int parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) { - char *cur_tok, *err_str; - struct hostent *hent; - size_t s; - char **host; - int16_t *family, *port; - struct in_addr *addr; - - if (str == NULL) return 0; + char *cur_tok, *err_str; + struct hostent *hent; + size_t s; + char **host; + int16_t *family, *port; + struct in_addr *addr; + + if (str == NULL) + return 0; cur_tok = strsep (&str, ":"); host = &cf->bind_host; @@ -101,13 +105,13 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) *port = DEFAULT_BIND_PORT; family = &cf->bind_family; addr = &cf->bind_addr; - + if (cur_tok[0] == '/' || cur_tok[0] == '.') { #ifdef HAVE_DIRNAME /* Try to check path of bind credit */ - struct stat st; - int fd; - char *copy = memory_pool_strdup (cfg->cfg_pool, cur_tok); + struct stat st; + int fd; + char *copy = memory_pool_strdup (cfg->cfg_pool, cur_tok); if (stat (copy, &st) == -1) { if (errno == ENOENT) { if ((fd = open (cur_tok, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1) { @@ -135,9 +139,10 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) *family = AF_UNIX; return 1; - } else { + } + else { if (*str != '\0') { - *port = (uint16_t)strtoul (str, &err_str, 10); + *port = (uint16_t) strtoul (str, &err_str, 10); if (*err_str != '\0') { yyerror ("parse_bind_line: cannot read numeric value: %s", err_str); return 0; @@ -146,7 +151,8 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) if (strcmp (cur_tok, "*") == 0) { *host = memory_pool_strdup (cfg->cfg_pool, cur_tok); addr->s_addr = htonl (INADDR_ANY); - } else if (!inet_aton (cur_tok, addr)) { + } + else if (!inet_aton (cur_tok, addr)) { /* Try to call gethostbyname */ hent = gethostbyname (cur_tok); if (hent == NULL) { @@ -154,7 +160,7 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) } else { *host = memory_pool_strdup (cfg->cfg_pool, cur_tok); - memcpy((char *)addr, hent->h_addr, sizeof(struct in_addr)); + memcpy ((char *)addr, hent->h_addr, sizeof (struct in_addr)); s = strlen (cur_tok) + 1; } } @@ -215,17 +221,17 @@ free_config (struct config_file *cfg) memory_pool_delete (cfg->cfg_pool); } -char* +char * get_module_opt (struct config_file *cfg, char *module_name, char *opt_name) { - GList *cur_opt; - struct module_opt *cur; - + GList *cur_opt; + struct module_opt *cur; + cur_opt = g_hash_table_lookup (cfg->modules_opts, module_name); if (cur_opt == NULL) { return NULL; } - + while (cur_opt) { cur = cur_opt->data; if (strcmp (cur->param, opt_name) == 0) { @@ -240,10 +246,11 @@ get_module_opt (struct config_file *cfg, char *module_name, char *opt_name) size_t parse_limit (const char *limit) { - size_t result = 0; - char *err_str; + size_t result = 0; + char *err_str; - if (!limit || *limit == '\0') return 0; + if (!limit || *limit == '\0') + return 0; result = strtoul (limit, &err_str, 10); @@ -268,10 +275,11 @@ parse_limit (const char *limit) unsigned int parse_seconds (const char *t) { - unsigned int result = 0; - char *err_str; + unsigned int result = 0; + char *err_str; - if (!t || *t == '\0') return 0; + if (!t || *t == '\0') + return 0; result = strtoul (t, &err_str, 10); @@ -280,21 +288,21 @@ parse_seconds (const char *t) if (*err_str == 's' || *err_str == 'S') { result *= 1000; } - /* Minutes */ - else if (*err_str == 'm' || *err_str == 'M') { - /* Handle ms correctly */ - if (*(err_str + 1) == 's' || *(err_str + 1) == 'S') { - result *= 60 * 1000; - } - } - /* Hours */ - else if (*err_str == 'h' || *err_str == 'H') { - result *= 60 * 60 * 1000; - } - /* Days */ - else if (*err_str == 'd' || *err_str == 'D') { - result *= 24 * 60 * 60 * 1000; - } + /* Minutes */ + else if (*err_str == 'm' || *err_str == 'M') { + /* Handle ms correctly */ + if (*(err_str + 1) == 's' || *(err_str + 1) == 'S') { + result *= 60 * 1000; + } + } + /* Hours */ + else if (*err_str == 'h' || *err_str == 'H') { + result *= 60 * 60 * 1000; + } + /* Days */ + else if (*err_str == 'd' || *err_str == 'D') { + result *= 24 * 60 * 60 * 1000; + } } return result; @@ -303,27 +311,23 @@ parse_seconds (const char *t) char parse_flag (const char *str) { - if (!str || !*str) return -1; + if (!str || !*str) + return -1; if ((*str == 'Y' || *str == 'y') && *(str + 1) == '\0') { return 1; } - if ((*str == 'Y' || *str == 'y') && - (*(str + 1) == 'E' || *(str + 1) == 'e') && - (*(str + 2) == 'S' || *(str + 2) == 's') && - *(str + 3) == '\0') { - return 1; + if ((*str == 'Y' || *str == 'y') && (*(str + 1) == 'E' || *(str + 1) == 'e') && (*(str + 2) == 'S' || *(str + 2) == 's') && *(str + 3) == '\0') { + return 1; } if ((*str == 'N' || *str == 'n') && *(str + 1) == '\0') { return 0; } - if ((*str == 'N' || *str == 'n') && - (*(str + 1) == 'O' || *(str + 1) == 'o') && - *(str + 2) == '\0') { - return 0; + if ((*str == 'N' || *str == 'n') && (*(str + 1) == 'O' || *(str + 1) == 'o') && *(str + 2) == '\0') { + return 0; } return -1; @@ -333,18 +337,18 @@ parse_flag (const char *str) * Try to substitute all variables in given string * Return: newly allocated string with substituted variables (original string may be freed if variables are found) */ -char * +char * substitute_variable (struct config_file *cfg, char *name, char *str, u_char recursive) { - char *var, *new, *v_begin, *v_end, *p, t; - size_t len; - gboolean changed = FALSE; + char *var, *new, *v_begin, *v_end, *p, t; + size_t len; + gboolean changed = FALSE; if (str == NULL) { yywarn ("substitute_variable: trying to substitute variable in NULL string"); return NULL; } - + p = str; while ((v_begin = strstr (p, "${")) != NULL) { len = strlen (str); @@ -370,13 +374,12 @@ substitute_variable (struct config_file *cfg, char *name, char *str, u_char recu /* Allocate new string */ new = memory_pool_alloc (cfg->cfg_pool, len - strlen (v_begin) + strlen (var) + 3); - snprintf (new, len - strlen (v_begin) + strlen (var) + 3, "%s(%s)%s", - str, var, v_end + 1); + snprintf (new, len - strlen (v_begin) + strlen (var) + 3, "%s(%s)%s", str, var, v_end + 1); p = new; str = new; changed = TRUE; } - + if (changed && name != NULL) { g_hash_table_insert (cfg->variables, name, str); } @@ -387,9 +390,9 @@ substitute_variable (struct config_file *cfg, char *name, char *str, u_char recu static void substitute_module_variables (gpointer key, gpointer value, gpointer data) { - struct config_file *cfg = (struct config_file *)data; - GList *cur_opt = (GList *)value; - struct module_opt *cur; + struct config_file *cfg = (struct config_file *)data; + GList *cur_opt = (GList *) value; + struct module_opt *cur; while (cur_opt) { cur = cur_opt->data; @@ -403,7 +406,7 @@ substitute_module_variables (gpointer key, gpointer value, gpointer data) static void substitute_all_variables (gpointer key, gpointer value, gpointer data) { - struct config_file *cfg = (struct config_file *)data; + struct config_file *cfg = (struct config_file *)data; /* Do recursive substitution */ (void)substitute_variable (cfg, (char *)key, (char *)value, 1); @@ -412,12 +415,12 @@ substitute_all_variables (gpointer key, gpointer value, gpointer data) static void parse_filters_str (struct config_file *cfg, const char *str) { - gchar **strvec, **p; - struct filter *cur; - int i; - + gchar **strvec, **p; + struct filter *cur; + int i; + if (str == NULL) { - return; + return; } strvec = g_strsplit (str, ",", 0); @@ -430,17 +433,17 @@ parse_filters_str (struct config_file *cfg, const char *str) cur = NULL; /* Search modules from known C modules */ for (i = 0; i < MODULES_NUM; i++) { - g_strstrip (*p); + g_strstrip (*p); if (strcasecmp (modules[i].name, *p) == 0) { cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct filter)); cur->type = C_FILTER; msg_debug ("parse_filters_str: found C filter %s", *p); cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); - cur->module = &modules[i]; + cur->module = &modules[i]; cfg->filters = g_list_prepend (cfg->filters, cur); break; - } + } } if (cur != NULL) { /* Go to next iteration */ @@ -451,7 +454,7 @@ parse_filters_str (struct config_file *cfg, const char *str) cur->type = PERL_FILTER; cur->func_name = memory_pool_strdup (cfg->cfg_pool, *p); cfg->filters = g_list_prepend (cfg->filters, cur); - p ++; + p++; } g_strfreev (strvec); @@ -463,22 +466,22 @@ parse_filters_str (struct config_file *cfg, const char *str) static void fill_cfg_params (struct config_file *cfg) { - struct config_scalar *scalars; - - scalars = memory_pool_alloc (cfg->cfg_pool, 10 * sizeof (struct config_scalar)); - - scalars[0].type = SCALAR_TYPE_STR; - scalars[0].pointer = &cfg->cfg_name; - g_hash_table_insert (cfg->cfg_params, "cfg_name", &scalars[0]); - scalars[1].type = SCALAR_TYPE_STR; - scalars[1].pointer = &cfg->pid_file; - g_hash_table_insert (cfg->cfg_params, "pid_file", &scalars[1]); - scalars[2].type = SCALAR_TYPE_STR; - scalars[2].pointer = &cfg->temp_dir; - g_hash_table_insert (cfg->cfg_params, "temp_dir", &scalars[2]); - scalars[3].type = SCALAR_TYPE_SIZE; - scalars[3].pointer = &cfg->max_statfile_size; - g_hash_table_insert (cfg->cfg_params, "max_statfile_size", &scalars[3]); + struct config_scalar *scalars; + + scalars = memory_pool_alloc (cfg->cfg_pool, 10 * sizeof (struct config_scalar)); + + scalars[0].type = SCALAR_TYPE_STR; + scalars[0].pointer = &cfg->cfg_name; + g_hash_table_insert (cfg->cfg_params, "cfg_name", &scalars[0]); + scalars[1].type = SCALAR_TYPE_STR; + scalars[1].pointer = &cfg->pid_file; + g_hash_table_insert (cfg->cfg_params, "pid_file", &scalars[1]); + scalars[2].type = SCALAR_TYPE_STR; + scalars[2].pointer = &cfg->temp_dir; + g_hash_table_insert (cfg->cfg_params, "temp_dir", &scalars[2]); + scalars[3].type = SCALAR_TYPE_SIZE; + scalars[3].pointer = &cfg->max_statfile_size; + g_hash_table_insert (cfg->cfg_params, "max_statfile_size", &scalars[3]); } @@ -488,13 +491,13 @@ fill_cfg_params (struct config_file *cfg) void post_load_config (struct config_file *cfg) { - struct timespec ts; - struct metric *def_metric; + struct timespec ts; + struct metric *def_metric; g_hash_table_foreach (cfg->variables, substitute_all_variables, cfg); g_hash_table_foreach (cfg->modules_opts, substitute_module_variables, cfg); parse_filters_str (cfg, cfg->filters_str); - fill_cfg_params (cfg); + fill_cfg_params (cfg); #ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID clock_getres (CLOCK_PROCESS_CPUTIME_ID, &ts); @@ -528,10 +531,10 @@ post_load_config (struct config_file *cfg) void parse_err (const char *fmt, ...) { - va_list aq; - char logbuf[BUFSIZ], readbuf[32]; - int r; - + va_list aq; + char logbuf[BUFSIZ], readbuf[32]; + int r; + va_start (aq, fmt); g_strlcpy (readbuf, yytext, sizeof (readbuf)); @@ -545,10 +548,10 @@ parse_err (const char *fmt, ...) void parse_warn (const char *fmt, ...) { - va_list aq; - char logbuf[BUFSIZ], readbuf[32]; - int r; - + va_list aq; + char logbuf[BUFSIZ], readbuf[32]; + int r; + va_start (aq, fmt); g_strlcpy (readbuf, yytext, sizeof (readbuf)); @@ -562,26 +565,26 @@ parse_warn (const char *fmt, ...) void unescape_quotes (char *line) { - char *c = line, *t; + char *c = line, *t; while (*c) { if (*c == '\\' && *(c + 1) == '"') { t = c; while (*t) { *t = *(t + 1); - t ++; + t++; } } - c ++; + c++; } } -GList * -parse_comma_list (memory_pool_t *pool, char *line) +GList * +parse_comma_list (memory_pool_t * pool, char *line) { - GList *res = NULL; - char *c, *p, *str; - + GList *res = NULL; + char *c, *p, *str; + c = line; p = c; @@ -595,16 +598,16 @@ parse_comma_list (memory_pool_t *pool, char *line) c = p; continue; } - p ++; + p++; } if (res != NULL) { - memory_pool_add_destructor (pool, (pool_destruct_func)g_list_free, res); + memory_pool_add_destructor (pool, (pool_destruct_func) g_list_free, res); } return res; } -struct classifier_config * +struct classifier_config * check_classifier_cfg (struct config_file *cfg, struct classifier_config *c) { if (c == NULL) { @@ -612,7 +615,7 @@ check_classifier_cfg (struct config_file *cfg, struct classifier_config *c) } if (c->opts == NULL) { c->opts = g_hash_table_new (g_str_hash, g_str_equal); - memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)g_hash_table_destroy, c->opts); + memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->opts); } return c; diff --git a/src/classifiers/classifiers.c b/src/classifiers/classifiers.c index 482d111b0..566cf2b75 100644 --- a/src/classifiers/classifiers.c +++ b/src/classifiers/classifiers.c @@ -29,21 +29,21 @@ #include <sys/types.h> #include "classifiers.h" -struct classifier classifiers[] = { +struct classifier classifiers[] = { { - .name = "winnow", - .init_func = winnow_init, - .classify_func = winnow_classify, - .learn_func = winnow_learn, - }, + .name = "winnow", + .init_func = winnow_init, + .classify_func = winnow_classify, + .learn_func = winnow_learn, + }, }; -struct classifier* +struct classifier * get_classifier (char *name) { - int i; + int i; - for (i = 0; i < sizeof (classifiers) / sizeof (classifiers[0]); i ++) { + for (i = 0; i < sizeof (classifiers) / sizeof (classifiers[0]); i++) { if (strcmp (classifiers[i].name, name) == 0) { return &classifiers[i]; } diff --git a/src/classifiers/winnow.c b/src/classifiers/winnow.c index 0b156176e..9404644ac 100644 --- a/src/classifiers/winnow.c +++ b/src/classifiers/winnow.c @@ -35,42 +35,42 @@ #define WINNOW_DEMOTION 0.83 struct winnow_callback_data { - statfile_pool_t *pool; - struct classifier_ctx *ctx; - stat_file_t *file; - double sum; - int count; - int in_class; - time_t now; + statfile_pool_t *pool; + struct classifier_ctx *ctx; + stat_file_t *file; + double sum; + int count; + int in_class; + time_t now; }; -static gboolean -classify_callback (gpointer key, gpointer value, gpointer data) +static gboolean +classify_callback (gpointer key, gpointer value, gpointer data) { - token_node_t *node = key; - struct winnow_callback_data *cd = data; - float v; - + token_node_t *node = key; + struct winnow_callback_data *cd = data; + float v; + /* Consider that not found blocks have value 1 */ if ((v = statfile_pool_get_block (cd->pool, cd->file, node->h1, node->h2, cd->now)) < 0.00001) { cd->sum += 1; } else { cd->sum += v; - cd->in_class ++; + cd->in_class++; } - cd->count ++; + cd->count++; return FALSE; } -static gboolean -learn_callback (gpointer key, gpointer value, gpointer data) +static gboolean +learn_callback (gpointer key, gpointer value, gpointer data) { - token_node_t *node = key; - struct winnow_callback_data *cd = data; - float v, c; + token_node_t *node = key; + struct winnow_callback_data *cd = data; + float v, c; c = (cd->in_class) ? WINNOW_PROMOTION : WINNOW_DEMOTION; @@ -82,29 +82,30 @@ learn_callback (gpointer key, gpointer value, gpointer data) statfile_pool_set_block (cd->pool, cd->file, node->h1, node->h2, cd->now, v * c); } - cd->count ++; - + cd->count++; + return FALSE; } -struct classifier_ctx* -winnow_init (memory_pool_t *pool, struct classifier_config *cfg) +struct classifier_ctx * +winnow_init (memory_pool_t * pool, struct classifier_config *cfg) { - struct classifier_ctx *ctx = memory_pool_alloc (pool, sizeof (struct classifier_ctx)); + struct classifier_ctx *ctx = memory_pool_alloc (pool, sizeof (struct classifier_ctx)); ctx->pool = pool; ctx->cfg = cfg; return ctx; } -void -winnow_classify (struct classifier_ctx *ctx, statfile_pool_t *pool, GTree *input, struct worker_task *task) + +void +winnow_classify (struct classifier_ctx *ctx, statfile_pool_t * pool, GTree * input, struct worker_task *task) { - struct winnow_callback_data data; - double *res = memory_pool_alloc (ctx->pool, sizeof (double)); - double max = 0; - GList *cur; - struct statfile *st, *sel = NULL; + struct winnow_callback_data data; + double *res = memory_pool_alloc (ctx->pool, sizeof (double)); + double max = 0; + GList *cur; + struct statfile *st, *sel = NULL; g_assert (pool != NULL); g_assert (ctx != NULL); @@ -114,7 +115,7 @@ winnow_classify (struct classifier_ctx *ctx, statfile_pool_t *pool, GTree *input data.count = 0; data.now = time (NULL); data.ctx = ctx; - + cur = ctx->cfg->statfiles; while (cur) { st = cur->data; @@ -131,7 +132,7 @@ winnow_classify (struct classifier_ctx *ctx, statfile_pool_t *pool, GTree *input g_tree_foreach (input, classify_callback, &data); statfile_pool_unlock_file (pool, data.file); } - + if (data.count != 0) { *res = (data.sum / data.count); } @@ -144,23 +145,23 @@ winnow_classify (struct classifier_ctx *ctx, statfile_pool_t *pool, GTree *input } cur = g_list_next (cur); } - + if (sel != NULL) { insert_result (task, ctx->cfg->metric, sel->symbol, 1, NULL); } } void -winnow_learn (struct classifier_ctx *ctx, statfile_pool_t *pool, char *symbol, GTree *input, int in_class) +winnow_learn (struct classifier_ctx *ctx, statfile_pool_t * pool, char *symbol, GTree * input, int in_class) { - struct winnow_callback_data data = { - .file = NULL, + struct winnow_callback_data data = { + .file = NULL, .sum = 0, .count = 0, }; - GList *cur; - struct statfile *st; - + GList *cur; + struct statfile *st; + g_assert (pool != NULL); g_assert (ctx != NULL); @@ -168,15 +169,14 @@ winnow_learn (struct classifier_ctx *ctx, statfile_pool_t *pool, char *symbol, G data.in_class = in_class; data.now = time (NULL); data.ctx = ctx; - + cur = g_list_first (ctx->cfg->statfiles); while (cur) { st = cur->data; if (strcmp (symbol, st->symbol) == 0) { if ((data.file = statfile_pool_open (pool, st->path)) == NULL) { /* Try to create statfile */ - if (statfile_pool_create (pool, - st->path, st->size / sizeof (struct stat_file_block)) == -1) { + if (statfile_pool_create (pool, st->path, st->size / sizeof (struct stat_file_block)) == -1) { msg_err ("winnow_learn: cannot create statfile %s", st->path); return; } diff --git a/src/controller.c b/src/controller.c index c88994b9f..21df8d511 100644 --- a/src/controller.c +++ b/src/controller.c @@ -52,16 +52,16 @@ enum command_type { }; struct controller_command { - char *command; - gboolean privilleged; - enum command_type type; + char *command; + gboolean privilleged; + enum command_type type; }; struct custom_controller_command { - const char *command; - gboolean privilleged; - gboolean require_message; - controller_func_t handler; + const char *command; + gboolean privilleged; + gboolean require_message; + controller_func_t handler; }; static struct controller_command commands[] = { @@ -76,33 +76,34 @@ static struct controller_command commands[] = { {"counters", FALSE, COMMAND_COUNTERS}, }; -static GList *custom_commands = NULL; +static GList *custom_commands = NULL; -static GCompletion *comp; -static time_t start_time; +static GCompletion *comp; +static time_t start_time; -static char greetingbuf[1024]; -extern rspamd_hash_t *counters; +static char greetingbuf[1024]; +extern rspamd_hash_t *counters; -static gboolean controller_write_socket (void *arg); +static gboolean controller_write_socket (void *arg); -static -void sig_handler (int signo) +static + void +sig_handler (int signo) { switch (signo) { - case SIGINT: - case SIGTERM: - _exit (1); - break; + case SIGINT: + case SIGTERM: + _exit (1); + break; } } static void sigusr_handler (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct rspamd_worker *worker = (struct rspamd_worker *)arg; /* Do not accept new connections, preparing to end worker's process */ - struct timeval tv; + struct timeval tv; tv.tv_sec = 2; tv.tv_usec = 0; event_del (&worker->sig_ev); @@ -112,10 +113,10 @@ sigusr_handler (int fd, short what, void *arg) return; } -static gchar* +static gchar * completion_func (gpointer elem) { - struct controller_command *cmd = (struct controller_command *)elem; + struct controller_command *cmd = (struct controller_command *)elem; return cmd->command; } @@ -123,12 +124,12 @@ completion_func (gpointer elem) static void free_session (void *ud) { - GList *part; - struct mime_part *p; - struct controller_session *session = ud; - + GList *part; + struct mime_part *p; + struct controller_session *session = ud; + msg_debug ("free_session: freeing session %p", session); - + while ((part = g_list_first (session->parts))) { session->parts = g_list_remove_link (session->parts, part); p = (struct mime_part *)part->data; @@ -144,10 +145,10 @@ free_session (void *ud) } static int -check_auth (struct controller_command *cmd, struct controller_session *session) +check_auth (struct controller_command *cmd, struct controller_session *session) { - char out_buf[128]; - int r; + char out_buf[128]; + int r; if (cmd->privilleged && !session->authorized) { r = snprintf (out_buf, sizeof (out_buf), "not authorized" CRLF); @@ -161,11 +162,11 @@ check_auth (struct controller_command *cmd, struct controller_session *session) static void counter_write_callback (gpointer key, gpointer value, void *data) { - struct controller_session *session = data; - struct counter_data *cd = value; - char *name = key; - char out_buf[128]; - int r; + struct controller_session *session = data; + struct counter_data *cd = value; + char *name = key; + char out_buf[128]; + int r; r = snprintf (out_buf, sizeof (out_buf), "%s: %llu" CRLF, name, (unsigned long long int)cd->value); rspamd_dispatcher_write (session->dispatcher, out_buf, r, TRUE, FALSE); @@ -174,210 +175,190 @@ counter_write_callback (gpointer key, gpointer value, void *data) static void process_command (struct controller_command *cmd, char **cmd_args, struct controller_session *session) { - char out_buf[BUFSIZ], *arg, *err_str; - int r = 0, days, hours, minutes; - time_t uptime; - unsigned long size = 0; - struct classifier_config *cl; - memory_pool_stat_t mem_st; - char *password = g_hash_table_lookup (session->worker->cf->params, "password"); + char out_buf[BUFSIZ], *arg, *err_str; + int r = 0, days, hours, minutes; + time_t uptime; + unsigned long size = 0; + struct classifier_config *cl; + memory_pool_stat_t mem_st; + char *password = g_hash_table_lookup (session->worker->cf->params, "password"); switch (cmd->type) { - case COMMAND_PASSWORD: - arg = *cmd_args; - if (!arg || *arg == '\0') { - msg_debug ("process_command: empty password passed"); - r = snprintf (out_buf, sizeof (out_buf), "password command requires one argument" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; + case COMMAND_PASSWORD: + arg = *cmd_args; + if (!arg || *arg == '\0') { + msg_debug ("process_command: empty password passed"); + r = snprintf (out_buf, sizeof (out_buf), "password command requires one argument" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return; + } + if (password == NULL) { + r = snprintf (out_buf, sizeof (out_buf), "password command disabled in config, authorized access unallowed" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return; + } + if (strncmp (arg, password, strlen (arg)) == 0) { + session->authorized = 1; + r = snprintf (out_buf, sizeof (out_buf), "password accepted" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + } + else { + session->authorized = 0; + r = snprintf (out_buf, sizeof (out_buf), "password NOT accepted" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + } + break; + case COMMAND_QUIT: + session->state = STATE_QUIT; + break; + case COMMAND_RELOAD: + if (check_auth (cmd, session)) { + r = snprintf (out_buf, sizeof (out_buf), "reload request sent" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + kill (getppid (), SIGHUP); + } + break; + case COMMAND_STAT: + if (check_auth (cmd, session)) { + memory_pool_stat (&mem_st); + r = snprintf (out_buf, sizeof (out_buf), "Messages scanned: %u" CRLF, session->worker->srv->stat->messages_scanned); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Messages learned: %u" CRLF, session->worker->srv->stat->messages_learned); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Connections count: %u" CRLF, session->worker->srv->stat->connections_count); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Control connections count: %u" CRLF, session->worker->srv->stat->control_connections_count); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Pools allocated: %ld" CRLF, (long int)mem_st.pools_allocated); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Pools freed: %ld" CRLF, (long int)mem_st.pools_freed); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Bytes allocated: %ld" CRLF, (long int)mem_st.bytes_allocated); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Memory chunks allocated: %ld" CRLF, (long int)mem_st.chunks_allocated); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Shared chunks allocated: %ld" CRLF, (long int)mem_st.shared_chunks_allocated); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Chunks freed: %ld" CRLF, (long int)mem_st.chunks_freed); + r += snprintf (out_buf + r, sizeof (out_buf) - r, "Oversized chunks: %ld" CRLF, (long int)mem_st.oversized_chunks); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + } + break; + case COMMAND_SHUTDOWN: + if (check_auth (cmd, session)) { + r = snprintf (out_buf, sizeof (out_buf), "shutdown request sent" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + kill (getppid (), SIGTERM); + } + break; + case COMMAND_UPTIME: + if (check_auth (cmd, session)) { + uptime = time (NULL) - start_time; + /* If uptime more than 2 hours, print as a number of days. */ + if (uptime >= 2 * 3600) { + days = uptime / 86400; + hours = uptime / 3600 - days * 3600; + minutes = uptime / 60 - hours * 60 - days * 3600; + r = snprintf (out_buf, sizeof (out_buf), "%d day%s %d hour%s %d minute%s" CRLF, days, days > 1 ? "s" : " ", hours, hours > 1 ? "s" : " ", minutes, minutes > 1 ? "s" : " "); } - if (password == NULL) { - r = snprintf (out_buf, sizeof (out_buf), "password command disabled in config, authorized access unallowed" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; - } - if (strncmp (arg, password, strlen (arg)) == 0) { - session->authorized = 1; - r = snprintf (out_buf, sizeof (out_buf), "password accepted" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + /* If uptime is less than 1 minute print only seconds */ + else if (uptime / 60 == 0) { + r = snprintf (out_buf, sizeof (out_buf), "%d second%s" CRLF, (int)uptime, (int)uptime > 1 ? "s" : " "); } + /* Else print the minutes and seconds. */ else { - session->authorized = 0; - r = snprintf (out_buf, sizeof (out_buf), "password NOT accepted" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + hours = uptime / 3600; + minutes = uptime / 60 - hours * 3600; + uptime -= hours * 3600 + minutes * 60; + r = snprintf (out_buf, sizeof (out_buf), "%d hour%s %d minite%s %d second%s" CRLF, hours, hours > 1 ? "s" : " ", minutes, minutes > 1 ? "s" : " ", (int)uptime, uptime > 1 ? "s" : " "); } - break; - case COMMAND_QUIT: - session->state = STATE_QUIT; - break; - case COMMAND_RELOAD: - if (check_auth (cmd, session)) { - r = snprintf (out_buf, sizeof (out_buf), "reload request sent" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + } + break; + case COMMAND_LEARN: + if (check_auth (cmd, session)) { + arg = *cmd_args; + if (!arg || *arg == '\0') { + msg_debug ("process_command: no statfile specified in learn command"); + r = snprintf (out_buf, sizeof (out_buf), "learn command requires at least two arguments: stat filename and its size" CRLF); rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - kill (getppid (), SIGHUP); + return; } - break; - case COMMAND_STAT: - if (check_auth (cmd, session)) { - memory_pool_stat (&mem_st); - r = snprintf (out_buf, sizeof (out_buf), "Messages scanned: %u" CRLF, - session->worker->srv->stat->messages_scanned); - r += snprintf (out_buf + r, sizeof (out_buf) - r , "Messages learned: %u" CRLF, - session->worker->srv->stat->messages_learned); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Connections count: %u" CRLF, - session->worker->srv->stat->connections_count); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Control connections count: %u" CRLF, - session->worker->srv->stat->control_connections_count); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Pools allocated: %ld" CRLF, - (long int)mem_st.pools_allocated); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Pools freed: %ld" CRLF, - (long int)mem_st.pools_freed); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Bytes allocated: %ld" CRLF, - (long int)mem_st.bytes_allocated); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Memory chunks allocated: %ld" CRLF, - (long int)mem_st.chunks_allocated); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Shared chunks allocated: %ld" CRLF, - (long int)mem_st.shared_chunks_allocated); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Chunks freed: %ld" CRLF, - (long int)mem_st.chunks_freed); - r += snprintf (out_buf + r, sizeof (out_buf) - r, "Oversized chunks: %ld" CRLF, - (long int)mem_st.oversized_chunks); + arg = *(cmd_args + 1); + if (arg == NULL || *arg == '\0') { + msg_debug ("process_command: no statfile size specified in learn command"); + r = snprintf (out_buf, sizeof (out_buf), "learn command requires at least two arguments: stat filename and its size" CRLF); rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return; } - break; - case COMMAND_SHUTDOWN: - if (check_auth (cmd, session)) { - r = snprintf (out_buf, sizeof (out_buf), "shutdown request sent" CRLF); + size = strtoul (arg, &err_str, 10); + if (err_str && *err_str != '\0') { + msg_debug ("process_command: statfile size is invalid: %s", arg); + r = snprintf (out_buf, sizeof (out_buf), "learn size is invalid" CRLF); rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - kill (getppid (), SIGTERM); + return; } - break; - case COMMAND_UPTIME: - if (check_auth (cmd, session)) { - uptime = time (NULL) - start_time; - /* If uptime more than 2 hours, print as a number of days. */ - if (uptime >= 2 * 3600) { - days = uptime / 86400; - hours = uptime / 3600 - days * 3600; - minutes = uptime / 60 - hours * 60 - days * 3600; - r = snprintf (out_buf, sizeof (out_buf), "%d day%s %d hour%s %d minute%s" CRLF, - days, days > 1 ? "s" : " ", - hours, hours > 1 ? "s" : " ", - minutes, minutes > 1 ? "s" : " "); - } - /* If uptime is less than 1 minute print only seconds */ - else if (uptime / 60 == 0) { - r = snprintf (out_buf, sizeof (out_buf), "%d second%s" CRLF, (int)uptime, (int)uptime > 1 ? "s" : " "); - } - /* Else print the minutes and seconds. */ - else { - hours = uptime / 3600; - minutes = uptime / 60 - hours * 3600; - uptime -= hours * 3600 + minutes * 60; - r = snprintf (out_buf, sizeof (out_buf), "%d hour%s %d minite%s %d second%s" CRLF, - hours, hours > 1 ? "s" : " ", - minutes, minutes > 1 ? "s" : " ", - (int)uptime, uptime > 1 ? "s" : " "); - } + + session->learn_symbol = memory_pool_strdup (session->session_pool, *cmd_args); + cl = g_hash_table_lookup (session->cfg->classifiers_symbols, *cmd_args); + if (cl == NULL) { + r = snprintf (out_buf, sizeof (out_buf), "statfile %s is not defined" CRLF, *cmd_args); rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - } - break; - case COMMAND_LEARN: - if (check_auth (cmd, session)) { - arg = *cmd_args; - if (!arg || *arg == '\0') { - msg_debug ("process_command: no statfile specified in learn command"); - r = snprintf (out_buf, sizeof (out_buf), "learn command requires at least two arguments: stat filename and its size" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; - } - arg = *(cmd_args + 1); - if (arg == NULL || *arg == '\0') { - msg_debug ("process_command: no statfile size specified in learn command"); - r = snprintf (out_buf, sizeof (out_buf), "learn command requires at least two arguments: stat filename and its size" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; - } - size = strtoul (arg, &err_str, 10); - if (err_str && *err_str != '\0') { - msg_debug ("process_command: statfile size is invalid: %s", arg); - r = snprintf (out_buf, sizeof (out_buf), "learn size is invalid" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; - } + return; - session->learn_symbol = memory_pool_strdup (session->session_pool, *cmd_args); - cl = g_hash_table_lookup (session->cfg->classifiers_symbols, *cmd_args); - if (cl == NULL) { - r = snprintf (out_buf, sizeof (out_buf), "statfile %s is not defined" CRLF, *cmd_args); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; + } + session->learn_classifier = cl; - } - session->learn_classifier = cl; - - /* By default learn positive */ - session->in_class = 1; - /* Get all arguments */ - while (*cmd_args++) { - arg = *cmd_args; - if (arg && *arg == '-') { - switch (*(arg + 1)) { - case 'r': - arg = *(cmd_args + 1); - if (!arg || *arg == '\0') { - r = snprintf (out_buf, sizeof (out_buf), "recipient is not defined" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; - } - session->learn_rcpt = memory_pool_strdup (session->session_pool, arg); - break; - case 'f': - arg = *(cmd_args + 1); - if (!arg || *arg == '\0') { - r = snprintf (out_buf, sizeof (out_buf), "from is not defined" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; - } - session->learn_from = memory_pool_strdup (session->session_pool, arg); - break; - case 'n': - session->in_class = 0; - break; - default: - r = snprintf (out_buf, sizeof (out_buf), "tokenizer is not defined" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return; + /* By default learn positive */ + session->in_class = 1; + /* Get all arguments */ + while (*cmd_args++) { + arg = *cmd_args; + if (arg && *arg == '-') { + switch (*(arg + 1)) { + case 'r': + arg = *(cmd_args + 1); + if (!arg || *arg == '\0') { + r = snprintf (out_buf, sizeof (out_buf), "recipient is not defined" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return; } + session->learn_rcpt = memory_pool_strdup (session->session_pool, arg); + break; + case 'f': + arg = *(cmd_args + 1); + if (!arg || *arg == '\0') { + r = snprintf (out_buf, sizeof (out_buf), "from is not defined" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return; + } + session->learn_from = memory_pool_strdup (session->session_pool, arg); + break; + case 'n': + session->in_class = 0; + break; + default: + r = snprintf (out_buf, sizeof (out_buf), "tokenizer is not defined" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return; } } - rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_CHARACTER, size); - session->state = STATE_LEARN; } - break; - case COMMAND_HELP: - r = snprintf (out_buf, sizeof (out_buf), - "Rspamd CLI commands (* - privilleged command):" CRLF - " help - this help message" CRLF - "(*) learn <statfile> <size> [-r recipient], [-f from] [-n] - learn message to specified statfile" CRLF - " quit - quit CLI session" CRLF - "(*) reload - reload rspamd" CRLF - "(*) shutdown - shutdown rspamd" CRLF - " stat - show different rspamd stat" CRLF - " counters - show rspamd counters" CRLF - " uptime - rspamd uptime" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - break; - case COMMAND_COUNTERS: - rspamd_hash_foreach (counters, counter_write_callback, session); - break; + rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_CHARACTER, size); + session->state = STATE_LEARN; + } + break; + case COMMAND_HELP: + r = snprintf (out_buf, sizeof (out_buf), + "Rspamd CLI commands (* - privilleged command):" CRLF + " help - this help message" CRLF + "(*) learn <statfile> <size> [-r recipient], [-f from] [-n] - learn message to specified statfile" CRLF + " quit - quit CLI session" CRLF + "(*) reload - reload rspamd" CRLF + "(*) shutdown - shutdown rspamd" CRLF " stat - show different rspamd stat" CRLF " counters - show rspamd counters" CRLF " uptime - rspamd uptime" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + break; + case COMMAND_COUNTERS: + rspamd_hash_foreach (counters, counter_write_callback, session); + break; } } -static gboolean +static gboolean process_custom_command (char *line, char **cmd_args, struct controller_session *session) { - GList *cur; + GList *cur; struct custom_controller_command *cmd; cur = custom_commands; @@ -394,175 +375,173 @@ process_custom_command (char *line, char **cmd_args, struct controller_session * return FALSE; } -static gboolean -controller_read_socket (f_str_t *in, void *arg) +static gboolean +controller_read_socket (f_str_t * in, void *arg) { - struct controller_session *session = (struct controller_session *)arg; - struct classifier_ctx *cls_ctx; - int len, i, r; - char *s, **params, *cmd, out_buf[128]; - struct worker_task *task; - struct mime_text_part *part; - GList *comp_list, *cur = NULL; - GTree *tokens = NULL; - f_str_t c; + struct controller_session *session = (struct controller_session *)arg; + struct classifier_ctx *cls_ctx; + int len, i, r; + char *s, **params, *cmd, out_buf[128]; + struct worker_task *task; + struct mime_text_part *part; + GList *comp_list, *cur = NULL; + GTree *tokens = NULL; + f_str_t c; switch (session->state) { - case STATE_COMMAND: - s = fstrcstr (in, session->session_pool); - params = g_strsplit (s, " ", -1); - - memory_pool_add_destructor (session->session_pool, (pool_destruct_func)g_strfreev, params); - - len = g_strv_length (params); - if (len > 0) { - cmd = g_strstrip (params[0]); - comp_list = g_completion_complete (comp, cmd, NULL); - switch (g_list_length (comp_list)) { - case 1: - process_command ((struct controller_command *)comp_list->data, ¶ms[1], session); - break; - case 0: - if (!process_custom_command (cmd, ¶ms[1], session)) { - msg_debug ("Unknown command: '%s'", cmd); - i = snprintf (out_buf, sizeof (out_buf), "Unknown command" CRLF); - if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { - return FALSE; - } - } - break; - default: - msg_debug ("Ambigious command: '%s'", cmd); - i = snprintf (out_buf, sizeof (out_buf), "Ambigious command" CRLF); - if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { - return FALSE; - } - break; + case STATE_COMMAND: + s = fstrcstr (in, session->session_pool); + params = g_strsplit (s, " ", -1); + + memory_pool_add_destructor (session->session_pool, (pool_destruct_func) g_strfreev, params); + + len = g_strv_length (params); + if (len > 0) { + cmd = g_strstrip (params[0]); + comp_list = g_completion_complete (comp, cmd, NULL); + switch (g_list_length (comp_list)) { + case 1: + process_command ((struct controller_command *)comp_list->data, ¶ms[1], session); + break; + case 0: + if (!process_custom_command (cmd, ¶ms[1], session)) { + msg_debug ("Unknown command: '%s'", cmd); + i = snprintf (out_buf, sizeof (out_buf), "Unknown command" CRLF); + if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { + return FALSE; + } } + break; + default: + msg_debug ("Ambigious command: '%s'", cmd); + i = snprintf (out_buf, sizeof (out_buf), "Ambigious command" CRLF); + if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { + return FALSE; + } + break; } - if (session->state == STATE_COMMAND) { - session->state = STATE_REPLY; - } - if (session->state != STATE_LEARN && session->state != STATE_OTHER) { - if (!rspamd_dispatcher_write (session->dispatcher, END, sizeof (END) - 1, FALSE, TRUE)) { - return FALSE; - } + } + if (session->state == STATE_COMMAND) { + session->state = STATE_REPLY; + } + if (session->state != STATE_LEARN && session->state != STATE_OTHER) { + if (!rspamd_dispatcher_write (session->dispatcher, END, sizeof (END) - 1, FALSE, TRUE)) { + return FALSE; } + } - break; - case STATE_LEARN: - session->learn_buf = in; - task = construct_task (session->worker); - - task->msg = memory_pool_alloc (task->task_pool, sizeof (f_str_t)); - task->msg->begin = in->begin; - task->msg->len = in->len; - - r = process_message (task); - if (r == -1) { - msg_warn ("read_socket: processing of message failed"); - free_task (task, FALSE); - session->state = STATE_REPLY; - r = snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF); - rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); - return FALSE; - } - cur = g_list_first (task->text_parts); - while (cur) { - part = cur->data; - if (part->is_empty) { - cur = g_list_next (cur); - continue; - } - c.begin = part->content->data; - c.len = part->content->len; + break; + case STATE_LEARN: + session->learn_buf = in; + task = construct_task (session->worker); - if (!session->learn_classifier->tokenizer->tokenize_func (session->learn_classifier->tokenizer, - session->session_pool, &c, &tokens)) { - i = snprintf (out_buf, sizeof (out_buf), "learn fail, tokenizer error" CRLF); - free_task (task, FALSE); - if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { - return FALSE; - } - session->state = STATE_REPLY; - return TRUE; - } + task->msg = memory_pool_alloc (task->task_pool, sizeof (f_str_t)); + task->msg->begin = in->begin; + task->msg->len = in->len; + + r = process_message (task); + if (r == -1) { + msg_warn ("read_socket: processing of message failed"); + free_task (task, FALSE); + session->state = STATE_REPLY; + r = snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF); + rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); + return FALSE; + } + cur = g_list_first (task->text_parts); + while (cur) { + part = cur->data; + if (part->is_empty) { cur = g_list_next (cur); + continue; } - cls_ctx = session->learn_classifier->classifier->init_func (session->session_pool, session->learn_classifier); - session->learn_classifier->classifier->learn_func (cls_ctx, session->worker->srv->statfile_pool, - session->learn_symbol, tokens, session->in_class); - session->worker->srv->stat->messages_learned ++; + c.begin = part->content->data; + c.len = part->content->len; + + if (!session->learn_classifier->tokenizer->tokenize_func (session->learn_classifier->tokenizer, session->session_pool, &c, &tokens)) { + i = snprintf (out_buf, sizeof (out_buf), "learn fail, tokenizer error" CRLF); + free_task (task, FALSE); + if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { + return FALSE; + } + session->state = STATE_REPLY; + return TRUE; + } + cur = g_list_next (cur); + } + cls_ctx = session->learn_classifier->classifier->init_func (session->session_pool, session->learn_classifier); + session->learn_classifier->classifier->learn_func (cls_ctx, session->worker->srv->statfile_pool, session->learn_symbol, tokens, session->in_class); + session->worker->srv->stat->messages_learned++; - free_task (task, FALSE); - i = snprintf (out_buf, sizeof (out_buf), "learn ok" CRLF); - if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { - return FALSE; - } + free_task (task, FALSE); + i = snprintf (out_buf, sizeof (out_buf), "learn ok" CRLF); + if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { + return FALSE; + } - session->state = STATE_REPLY; - break; - case STATE_OTHER: - if (session->other_handler) { - session->other_handler (session, in); - } - session->state = STATE_REPLY; - break; - case STATE_WAIT: - rspamd_dispatcher_pause (session->dispatcher); - break; - default: - msg_debug ("controller_read_socket: unknown state while reading %d", session->state); - break; + session->state = STATE_REPLY; + break; + case STATE_OTHER: + if (session->other_handler) { + session->other_handler (session, in); + } + session->state = STATE_REPLY; + break; + case STATE_WAIT: + rspamd_dispatcher_pause (session->dispatcher); + break; + default: + msg_debug ("controller_read_socket: unknown state while reading %d", session->state); + break; } - if (session->state == STATE_REPLY || session->state == STATE_QUIT) { - (void)controller_write_socket (session); - } + if (session->state == STATE_REPLY || session->state == STATE_QUIT) { + (void)controller_write_socket (session); + } - return TRUE; + return TRUE; } -static gboolean +static gboolean controller_write_socket (void *arg) { - struct controller_session *session = (struct controller_session *)arg; - + struct controller_session *session = (struct controller_session *)arg; + if (session->state == STATE_QUIT) { /* Free buffers */ - destroy_session (session->s); - return FALSE; + destroy_session (session->s); + return FALSE; } else if (session->state == STATE_REPLY) { session->state = STATE_COMMAND; rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, BUFSIZ); } - return TRUE; + return TRUE; } static void -controller_err_socket (GError *err, void *arg) +controller_err_socket (GError * err, void *arg) { - struct controller_session *session = (struct controller_session *)arg; + struct controller_session *session = (struct controller_session *)arg; if (err->code != EOF) { msg_info ("controller_err_socket: abnormally closing control connection, error: %s", err->message); } /* Free buffers */ - destroy_session (session->s); + destroy_session (session->s); } static void accept_socket (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; - struct sockaddr_storage ss; - struct controller_session *new_session; - struct timeval *io_tv; - socklen_t addrlen = sizeof(ss); - int nfd; + struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct sockaddr_storage ss; + struct controller_session *new_session; + struct timeval *io_tv; + socklen_t addrlen = sizeof (ss); + int nfd; if ((nfd = accept_from_socket (fd, (struct sockaddr *)&ss, &addrlen)) == -1) { msg_warn ("accept_socket: accept failed: %s", strerror (errno)); @@ -580,29 +559,27 @@ accept_socket (int fd, short what, void *arg) new_session->cfg = worker->srv->cfg; new_session->state = STATE_COMMAND; new_session->session_pool = memory_pool_new (memory_pool_get_size () - 1); - worker->srv->stat->control_connections_count ++; + worker->srv->stat->control_connections_count++; /* Set up dispatcher */ - io_tv = memory_pool_alloc (new_session->session_pool, sizeof (struct timeval)); + io_tv = memory_pool_alloc (new_session->session_pool, sizeof (struct timeval)); io_tv->tv_sec = CONTROLLER_IO_TIMEOUT; io_tv->tv_usec = 0; - new_session->s = new_async_session (new_session->session_pool, free_session, new_session); + new_session->s = new_async_session (new_session->session_pool, free_session, new_session); - new_session->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, controller_read_socket, - controller_write_socket, controller_err_socket, io_tv, - (void *)new_session); + new_session->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, controller_read_socket, controller_write_socket, controller_err_socket, io_tv, (void *)new_session); rspamd_dispatcher_write (new_session->dispatcher, greetingbuf, strlen (greetingbuf), FALSE, FALSE); } void start_controller (struct rspamd_worker *worker) { - struct sigaction signals; - int i; - GList *comp_list = NULL; - char *hostbuf; - long int hostmax; + struct sigaction signals; + int i; + GList *comp_list = NULL; + char *hostbuf; + long int hostmax; worker->srv->pid = getpid (); event_init (); @@ -612,14 +589,14 @@ start_controller (struct rspamd_worker *worker) sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL); /* SIGUSR2 handler */ - signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *) worker); + signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *)worker); signal_add (&worker->sig_ev, NULL); - + start_time = time (NULL); /* Init command completion */ - for (i = 0; i < G_N_ELEMENTS (commands); i ++) { + for (i = 0; i < G_N_ELEMENTS (commands); i++) { comp_list = g_list_prepend (comp_list, &commands[i]); } comp = g_completion_new (completion_func); @@ -631,24 +608,24 @@ start_controller (struct rspamd_worker *worker) hostbuf[hostmax - 1] = '\0'; snprintf (greetingbuf, sizeof (greetingbuf), "Rspamd version %s is running on %s" CRLF, RVERSION, hostbuf); /* Accept event */ - event_set(&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); - event_add(&worker->bind_ev, NULL); + event_set (&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); + event_add (&worker->bind_ev, NULL); /* Send SIGUSR2 to parent */ kill (getppid (), SIGUSR2); gperf_profiler_init (worker->srv->cfg, "controller"); - + event_loop (0); exit (EXIT_SUCCESS); } -void +void register_custom_controller_command (const char *name, controller_func_t handler, gboolean privilleged, gboolean require_message) { struct custom_controller_command *cmd; - + cmd = g_malloc (sizeof (struct custom_controller_command)); cmd->command = name; cmd->handler = handler; diff --git a/src/events.c b/src/events.c index 9092e85c9..1299980e1 100644 --- a/src/events.c +++ b/src/events.c @@ -27,10 +27,10 @@ #include "events.h" -struct rspamd_async_session* -new_async_session (memory_pool_t *pool, event_finalizer_t fin, void *user_data) +struct rspamd_async_session * +new_async_session (memory_pool_t * pool, event_finalizer_t fin, void *user_data) { - struct rspamd_async_session *new; + struct rspamd_async_session *new; new = memory_pool_alloc (pool, sizeof (struct rspamd_async_session)); new->pool = pool; @@ -39,29 +39,29 @@ new_async_session (memory_pool_t *pool, event_finalizer_t fin, void *user_data) new->wanna_die = FALSE; new->events = g_queue_new (); - memory_pool_add_destructor (pool, (pool_destruct_func)g_queue_free, new->events); + memory_pool_add_destructor (pool, (pool_destruct_func) g_queue_free, new->events); return new; } -void +void register_async_event (struct rspamd_async_session *session, event_finalizer_t fin, void *user_data, gboolean forced) { - struct rspamd_async_event *new, *ev; - GList *cur; + struct rspamd_async_event *new, *ev; + GList *cur; if (session == NULL) { msg_info ("register_async_event: session is NULL"); return; } - + if (forced) { /* For forced events try first to increase its reference */ cur = session->events->head; while (cur) { ev = cur->data; if (ev->forced && ev->fin == fin) { - ev->ref ++; + ev->ref++; return; } cur = g_list_next (cur); @@ -76,22 +76,22 @@ register_async_event (struct rspamd_async_session *session, event_finalizer_t fi g_queue_push_head (session->events, new); } -void +void remove_forced_event (struct rspamd_async_session *session, event_finalizer_t fin) { - struct rspamd_async_event *ev; - GList *cur; + struct rspamd_async_event *ev; + GList *cur; if (session == NULL) { msg_info ("remove_forced_event: session is NULL"); return; } - + cur = session->events->head; while (cur) { ev = cur->data; if (ev->forced && ev->fin == fin) { - ev->ref --; + ev->ref--; if (ev->ref == 0) { g_queue_delete_link (session->events, cur); } @@ -106,17 +106,17 @@ remove_forced_event (struct rspamd_async_session *session, event_finalizer_t fin } } -void -remove_normal_event (struct rspamd_async_session *session, event_finalizer_t fin, void *ud) +void +remove_normal_event (struct rspamd_async_session *session, event_finalizer_t fin, void *ud) { - struct rspamd_async_event *ev; - GList *cur; + struct rspamd_async_event *ev; + GList *cur; if (session == NULL) { msg_info ("remove_forced_event: session is NULL"); return; } - + cur = session->events->head; while (cur) { ev = cur->data; @@ -134,16 +134,16 @@ remove_normal_event (struct rspamd_async_session *session, event_finalizer_t fin gboolean destroy_session (struct rspamd_async_session *session) { - struct rspamd_async_event *ev; - GList *cur, *tmp; + struct rspamd_async_event *ev; + GList *cur, *tmp; if (session == NULL) { msg_info ("destroy_session: session is NULL"); return FALSE; } - + session->wanna_die = TRUE; - + cur = session->events->head; while (cur) { diff --git a/src/expressions.c b/src/expressions.c index 8ea4ebc50..02dc6e190 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -31,66 +31,66 @@ #include "expressions.h" #include "html.h" -gboolean rspamd_compare_encoding (struct worker_task *task, GList *args); -gboolean rspamd_header_exists (struct worker_task *task, GList *args); -gboolean rspamd_content_type_compare_param (struct worker_task *task, GList *args); -gboolean rspamd_content_type_has_param (struct worker_task *task, GList *args); -gboolean rspamd_content_type_is_subtype (struct worker_task *task, GList *args); -gboolean rspamd_content_type_is_type (struct worker_task *task, GList *args); -gboolean rspamd_parts_distance (struct worker_task *task, GList *args); -gboolean rspamd_recipients_distance (struct worker_task *task, GList *args); -gboolean rspamd_has_content_part (struct worker_task *task, GList *args); -gboolean rspamd_has_content_part_len (struct worker_task *task, GList *args); -gboolean rspamd_has_only_html_part (struct worker_task *task, GList *args); -gboolean rspamd_is_recipients_sorted (struct worker_task *task, GList *args); -gboolean rspamd_compare_transfer_encoding (struct worker_task *task, GList *args); -gboolean rspamd_is_html_balanced (struct worker_task *task, GList *args); -gboolean rspamd_has_html_tag (struct worker_task *task, GList *args); -gboolean rspamd_has_fake_html (struct worker_task *task, GList *args); +gboolean rspamd_compare_encoding (struct worker_task *task, GList * args); +gboolean rspamd_header_exists (struct worker_task *task, GList * args); +gboolean rspamd_content_type_compare_param (struct worker_task *task, GList * args); +gboolean rspamd_content_type_has_param (struct worker_task *task, GList * args); +gboolean rspamd_content_type_is_subtype (struct worker_task *task, GList * args); +gboolean rspamd_content_type_is_type (struct worker_task *task, GList * args); +gboolean rspamd_parts_distance (struct worker_task *task, GList * args); +gboolean rspamd_recipients_distance (struct worker_task *task, GList * args); +gboolean rspamd_has_content_part (struct worker_task *task, GList * args); +gboolean rspamd_has_content_part_len (struct worker_task *task, GList * args); +gboolean rspamd_has_only_html_part (struct worker_task *task, GList * args); +gboolean rspamd_is_recipients_sorted (struct worker_task *task, GList * args); +gboolean rspamd_compare_transfer_encoding (struct worker_task *task, GList * args); +gboolean rspamd_is_html_balanced (struct worker_task *task, GList * args); +gboolean rspamd_has_html_tag (struct worker_task *task, GList * args); +gboolean rspamd_has_fake_html (struct worker_task *task, GList * args); /* * List of internal functions of rspamd * Sorted by name to use bsearch */ static struct _fl { - const char *name; - rspamd_internal_func_t func; + const char *name; + rspamd_internal_func_t func; } rspamd_functions_list[] = { - { "compare_encoding", rspamd_compare_encoding }, - { "compare_parts_distance", rspamd_parts_distance }, - { "compare_recipients_distance", rspamd_recipients_distance }, - { "compare_transfer_encoding", rspamd_compare_transfer_encoding }, - { "content_type_compare_param", rspamd_content_type_compare_param }, - { "content_type_has_param", rspamd_content_type_has_param }, - { "content_type_is_subtype", rspamd_content_type_is_subtype }, - { "content_type_is_type", rspamd_content_type_is_type }, - { "has_content_part", rspamd_has_content_part }, - { "has_content_part_len", rspamd_has_content_part_len }, - { "has_fake_html", rspamd_has_fake_html }, - { "has_html_tag", rspamd_has_html_tag }, - { "has_only_html_part", rspamd_has_only_html_part }, - { "header_exists", rspamd_header_exists }, - { "is_html_balanced", rspamd_is_html_balanced }, - { "is_recipients_sorted", rspamd_is_recipients_sorted }, -}; - -static struct _fl *list_ptr = &rspamd_functions_list[0]; -static uint32_t functions_number = sizeof (rspamd_functions_list) / sizeof (struct _fl); -static gboolean list_allocated = FALSE; + { + "compare_encoding", rspamd_compare_encoding}, { + "compare_parts_distance", rspamd_parts_distance}, { + "compare_recipients_distance", rspamd_recipients_distance}, { + "compare_transfer_encoding", rspamd_compare_transfer_encoding}, { + "content_type_compare_param", rspamd_content_type_compare_param}, { + "content_type_has_param", rspamd_content_type_has_param}, { + "content_type_is_subtype", rspamd_content_type_is_subtype}, { + "content_type_is_type", rspamd_content_type_is_type}, { + "has_content_part", rspamd_has_content_part}, { + "has_content_part_len", rspamd_has_content_part_len}, { + "has_fake_html", rspamd_has_fake_html}, { + "has_html_tag", rspamd_has_html_tag}, { + "has_only_html_part", rspamd_has_only_html_part}, { + "header_exists", rspamd_header_exists}, { + "is_html_balanced", rspamd_is_html_balanced}, { +"is_recipients_sorted", rspamd_is_recipients_sorted},}; + +static struct _fl *list_ptr = &rspamd_functions_list[0]; +static uint32_t functions_number = sizeof (rspamd_functions_list) / sizeof (struct _fl); +static gboolean list_allocated = FALSE; /* Bsearch routine */ static int fl_cmp (const void *s1, const void *s2) { - struct _fl *fl1 = (struct _fl *)s1; - struct _fl *fl2 = (struct _fl *)s2; + struct _fl *fl1 = (struct _fl *)s1; + struct _fl *fl2 = (struct _fl *)s2; return strcmp (fl1->name, fl2->name); } /* Cache for regular expressions that are used in functions */ -static GHashTable *re_cache = NULL; +static GHashTable *re_cache = NULL; -void * +void * re_cache_check (const char *line) { if (re_cache == NULL) { @@ -106,17 +106,17 @@ re_cache_add (char *line, void *pointer) if (re_cache == NULL) { re_cache = g_hash_table_new (g_str_hash, g_str_equal); } - + g_hash_table_insert (re_cache, line, pointer); } /* Task cache functions */ -void +void task_cache_add (struct worker_task *task, struct rspamd_regexp *re, int32_t result) { - if (result == 0) { - result = -1; - } + if (result == 0) { + result = -1; + } g_hash_table_insert (task->re_cache, re->regexp_text, GINT_TO_POINTER (result)); } @@ -124,15 +124,15 @@ task_cache_add (struct worker_task *task, struct rspamd_regexp *re, int32_t resu int32_t task_cache_check (struct worker_task *task, struct rspamd_regexp *re) { - gpointer res; - int32_t r; + gpointer res; + int32_t r; if ((res = g_hash_table_lookup (task->re_cache, re->regexp_text)) != NULL) { - r = GPOINTER_TO_INT (res); - if (r == -1) { - return 0; - } - return 1; + r = GPOINTER_TO_INT (res); + if (r == -1) { + return 0; + } + return 1; } return -1; } @@ -141,21 +141,21 @@ task_cache_check (struct worker_task *task, struct rspamd_regexp *re) * Functions for parsing expressions */ struct expression_stack { - char op; - struct expression_stack *next; + char op; + struct expression_stack *next; }; /* * Push operand or operator to stack */ -static struct expression_stack* -push_expression_stack (memory_pool_t *pool, struct expression_stack *head, char op) +static struct expression_stack * +push_expression_stack (memory_pool_t * pool, struct expression_stack *head, char op) { - struct expression_stack *new; + struct expression_stack *new; new = memory_pool_alloc (pool, sizeof (struct expression_stack)); new->op = op; - new->next = head; - return new; + new->next = head; + return new; } /* @@ -164,14 +164,15 @@ push_expression_stack (memory_pool_t *pool, struct expression_stack *head, char static char delete_expression_stack (struct expression_stack **head) { - struct expression_stack *cur; - char res; + struct expression_stack *cur; + char res; - if(*head == NULL) return 0; + if (*head == NULL) + return 0; cur = *head; res = cur->op; - + *head = cur->next; return res; } @@ -183,15 +184,15 @@ static int logic_priority (char a) { switch (a) { - case '!': - return 3; - case '|': - case '&': - return 2; - case '(': - return 1; - default: - return 0; + case '!': + return 3; + case '|': + case '&': + return 2; + case '(': + return 1; + default: + return 0; } } @@ -199,51 +200,51 @@ logic_priority (char a) * Return FALSE if symbol is not operation symbol (operand) * Return TRUE if symbol is operation symbol */ -static gboolean +static gboolean is_operation_symbol (char a) { switch (a) { - case '!': - case '&': - case '|': - case '(': - case ')': - return TRUE; - default: - return FALSE; + case '!': + case '&': + case '|': + case '(': + case ')': + return TRUE; + default: + return FALSE; } } /* * Return TRUE if symbol can be regexp flag */ -static gboolean +static gboolean is_regexp_flag (char a) { switch (a) { - case 'i': - case 'm': - case 'x': - case 's': - case 'u': - case 'o': - case 'r': - case 'H': - case 'M': - case 'P': - case 'U': - case 'X': - return TRUE; - default: - return FALSE; + case 'i': + case 'm': + case 'x': + case 's': + case 'u': + case 'o': + case 'r': + case 'H': + case 'M': + case 'P': + case 'U': + case 'X': + return TRUE; + default: + return FALSE; } } static void -insert_expression (memory_pool_t *pool, struct expression **head, int type, char op, void *operand) +insert_expression (memory_pool_t * pool, struct expression **head, int type, char op, void *operand) { - struct expression *new, *cur; - + struct expression *new, *cur; + new = memory_pool_alloc (pool, sizeof (struct expression)); new->type = type; if (new->type != EXPR_OPERATION) { @@ -266,17 +267,17 @@ insert_expression (memory_pool_t *pool, struct expression **head, int type, char } } -static struct expression* -maybe_parse_expression (memory_pool_t *pool, char *line) +static struct expression * +maybe_parse_expression (memory_pool_t * pool, char *line) { - struct expression *expr; - char *p = line; + struct expression *expr; + char *p = line; while (*p) { if (is_operation_symbol (*p)) { return parse_expression (pool, line); } - p ++; + p++; } expr = memory_pool_alloc (pool, sizeof (struct expression)); @@ -291,17 +292,17 @@ maybe_parse_expression (memory_pool_t *pool, char *line) * Make inverse polish record for specified expression * Memory is allocated from given pool */ -struct expression* -parse_expression (memory_pool_t *pool, char *line) +struct expression * +parse_expression (memory_pool_t * pool, char *line) { - struct expression *expr = NULL; - struct expression_stack *stack = NULL; - struct expression_function *func = NULL, *old; - struct expression *arg; - GQueue *function_stack; - char *p, *c, *str, op; - gboolean in_regexp = FALSE; - int brackets = 0; + struct expression *expr = NULL; + struct expression_stack *stack = NULL; + struct expression_function *func = NULL, *old; + struct expression *arg; + GQueue *function_stack; + char *p, *c, *str, op; + gboolean in_regexp = FALSE; + int brackets = 0; enum { SKIP_SPACES, @@ -314,194 +315,198 @@ parse_expression (memory_pool_t *pool, char *line) if (line == NULL || pool == NULL) { return NULL; - } + } msg_debug ("parse_expression: parsing expression {{ %s }}", line); - + function_stack = g_queue_new (); p = line; c = p; while (*p) { switch (state) { - case SKIP_SPACES: - if (!g_ascii_isspace (*p)) { - if (is_operation_symbol (*p)) { - state = READ_OPERATOR; - } else if (*p == '/') { - c = ++p; - state = READ_REGEXP; - } else { - c = p; - state = READ_FUNCTION; - } + case SKIP_SPACES: + if (!g_ascii_isspace (*p)) { + if (is_operation_symbol (*p)) { + state = READ_OPERATOR; + } + else if (*p == '/') { + c = ++p; + state = READ_REGEXP; } else { - p ++; + c = p; + state = READ_FUNCTION; } - break; - case READ_OPERATOR: - if (*p == ')') { - if (stack == NULL) { - return NULL; - } - /* Pop all operators from stack to nearest '(' or to head */ - while (stack && stack->op != '(') { - op = delete_expression_stack (&stack); - if (op != '(') { - insert_expression (pool, &expr, EXPR_OPERATION, op, NULL); - } - } - if (stack) { - op = delete_expression_stack (&stack); + } + else { + p++; + } + break; + case READ_OPERATOR: + if (*p == ')') { + if (stack == NULL) { + return NULL; + } + /* Pop all operators from stack to nearest '(' or to head */ + while (stack && stack->op != '(') { + op = delete_expression_stack (&stack); + if (op != '(') { + insert_expression (pool, &expr, EXPR_OPERATION, op, NULL); } } - else if (*p == '(') { - /* Push it to stack */ + if (stack) { + op = delete_expression_stack (&stack); + } + } + else if (*p == '(') { + /* Push it to stack */ + stack = push_expression_stack (pool, stack, *p); + } + else { + if (stack == NULL) { stack = push_expression_stack (pool, stack, *p); } + /* Check priority of logic operation */ else { - if (stack == NULL) { + if (logic_priority (stack->op) < logic_priority (*p)) { stack = push_expression_stack (pool, stack, *p); } - /* Check priority of logic operation */ else { - if (logic_priority (stack->op) < logic_priority (*p)) { - stack = push_expression_stack (pool, stack, *p); - } - else { - /* Pop all operations that have higher priority than this one */ - while((stack != NULL) && (logic_priority (stack->op) >= logic_priority (*p))) { - op = delete_expression_stack (&stack); - if (op != '(') { - insert_expression (pool, &expr, EXPR_OPERATION, op, NULL); - } + /* Pop all operations that have higher priority than this one */ + while ((stack != NULL) && (logic_priority (stack->op) >= logic_priority (*p))) { + op = delete_expression_stack (&stack); + if (op != '(') { + insert_expression (pool, &expr, EXPR_OPERATION, op, NULL); } - stack = push_expression_stack (pool, stack, *p); } + stack = push_expression_stack (pool, stack, *p); } } - p ++; - state = SKIP_SPACES; - break; + } + p++; + state = SKIP_SPACES; + break; - case READ_REGEXP: - if (*p == '/' && *(p - 1) != '\\') { - if (*(p + 1)) { - p ++; - } - state = READ_REGEXP_FLAGS; + case READ_REGEXP: + if (*p == '/' && *(p - 1) != '\\') { + if (*(p + 1)) { + p++; } - else { - p ++; - } - break; + state = READ_REGEXP_FLAGS; + } + else { + p++; + } + break; - case READ_REGEXP_FLAGS: - if (!is_regexp_flag (*p) || *(p + 1) == '\0') { - if (c != p) { - if ((is_regexp_flag (*p) || *p == '/') && *(p + 1) == '\0') { - p ++; - } - str = memory_pool_alloc (pool, p - c + 2); - g_strlcpy (str, c - 1, (p - c + 2)); - g_strstrip (str); - msg_debug ("parse_expression: found regexp: %s", str); - if (strlen (str) > 0) { - insert_expression (pool, &expr, EXPR_REGEXP, 0, str); - } + case READ_REGEXP_FLAGS: + if (!is_regexp_flag (*p) || *(p + 1) == '\0') { + if (c != p) { + if ((is_regexp_flag (*p) || *p == '/') && *(p + 1) == '\0') { + p++; + } + str = memory_pool_alloc (pool, p - c + 2); + g_strlcpy (str, c - 1, (p - c + 2)); + g_strstrip (str); + msg_debug ("parse_expression: found regexp: %s", str); + if (strlen (str) > 0) { + insert_expression (pool, &expr, EXPR_REGEXP, 0, str); } - c = p; - state = SKIP_SPACES; - } - else { - p ++; } - break; + c = p; + state = SKIP_SPACES; + } + else { + p++; + } + break; - case READ_FUNCTION: - if (*p == '/') { - /* In fact it is regexp */ - state = READ_REGEXP; - c ++; - p ++; - } else if (*p == '(') { - func = memory_pool_alloc (pool, sizeof (struct expression_function)); - func->name = memory_pool_alloc (pool, p - c + 1); - func->args = NULL; - g_strlcpy (func->name, c, (p - c + 1)); - g_strstrip (func->name); - state = READ_FUNCTION_ARGUMENT; - g_queue_push_tail (function_stack, func); - insert_expression (pool, &expr, EXPR_FUNCTION, 0, func); - c = ++p; - } else if (is_operation_symbol (*p)) { - /* In fact it is not function, but symbol */ - if (c != p) { - str = memory_pool_alloc (pool, p - c + 1); - g_strlcpy (str, c, (p - c + 1)); - g_strstrip (str); - if (strlen (str) > 0) { - insert_expression (pool, &expr, EXPR_STR, 0, str); - } + case READ_FUNCTION: + if (*p == '/') { + /* In fact it is regexp */ + state = READ_REGEXP; + c++; + p++; + } + else if (*p == '(') { + func = memory_pool_alloc (pool, sizeof (struct expression_function)); + func->name = memory_pool_alloc (pool, p - c + 1); + func->args = NULL; + g_strlcpy (func->name, c, (p - c + 1)); + g_strstrip (func->name); + state = READ_FUNCTION_ARGUMENT; + g_queue_push_tail (function_stack, func); + insert_expression (pool, &expr, EXPR_FUNCTION, 0, func); + c = ++p; + } + else if (is_operation_symbol (*p)) { + /* In fact it is not function, but symbol */ + if (c != p) { + str = memory_pool_alloc (pool, p - c + 1); + g_strlcpy (str, c, (p - c + 1)); + g_strstrip (str); + if (strlen (str) > 0) { + insert_expression (pool, &expr, EXPR_STR, 0, str); } - state = READ_OPERATOR; } - else if (*(p + 1) == '\0') { - /* In fact it is not function, but symbol */ - p ++; - if (c != p) { - str = memory_pool_alloc (pool, p - c + 1); - g_strlcpy (str, c, (p - c + 1)); - g_strstrip (str); - if (strlen (str) > 0) { - insert_expression (pool, &expr, EXPR_STR, 0, str); - } + state = READ_OPERATOR; + } + else if (*(p + 1) == '\0') { + /* In fact it is not function, but symbol */ + p++; + if (c != p) { + str = memory_pool_alloc (pool, p - c + 1); + g_strlcpy (str, c, (p - c + 1)); + g_strstrip (str); + if (strlen (str) > 0) { + insert_expression (pool, &expr, EXPR_STR, 0, str); } - state = SKIP_SPACES; - } - else { - p ++; } - break; - - case READ_FUNCTION_ARGUMENT: - if (*p == '/' && !in_regexp) { - in_regexp = TRUE; - p ++; - } - if (!in_regexp) { - /* Append argument to list */ - if (*p == ',' || (*p == ')' && brackets == 0)) { - arg = memory_pool_alloc (pool, sizeof (struct expression)); - str = memory_pool_alloc (pool, p - c + 1); - g_strlcpy (str, c, (p - c + 1)); - g_strstrip (str); - /* Recursive call */ - arg = maybe_parse_expression (pool, str); - func->args = g_list_append (func->args, arg); - /* Pop function */ - if (*p == ')') { - /* Last function in chain, goto skipping spaces state */ - old = func; - func = g_queue_pop_tail (function_stack); - if (g_queue_get_length (function_stack) == 0) { - state = SKIP_SPACES; - } + state = SKIP_SPACES; + } + else { + p++; + } + break; + + case READ_FUNCTION_ARGUMENT: + if (*p == '/' && !in_regexp) { + in_regexp = TRUE; + p++; + } + if (!in_regexp) { + /* Append argument to list */ + if (*p == ',' || (*p == ')' && brackets == 0)) { + arg = memory_pool_alloc (pool, sizeof (struct expression)); + str = memory_pool_alloc (pool, p - c + 1); + g_strlcpy (str, c, (p - c + 1)); + g_strstrip (str); + /* Recursive call */ + arg = maybe_parse_expression (pool, str); + func->args = g_list_append (func->args, arg); + /* Pop function */ + if (*p == ')') { + /* Last function in chain, goto skipping spaces state */ + old = func; + func = g_queue_pop_tail (function_stack); + if (g_queue_get_length (function_stack) == 0) { + state = SKIP_SPACES; } - c = p + 1; - } - else if (*p == '(') { - brackets ++; - } - else if (*p == ')') { - brackets --; } + c = p + 1; } - else if (*p == '/' && *(p - 1) != '\\') { - in_regexp = FALSE; + else if (*p == '(') { + brackets++; } - p ++; - break; + else if (*p == ')') { + brackets--; + } + } + else if (*p == '/' && *(p - 1) != '\\') { + in_regexp = FALSE; + } + p++; + break; } } @@ -512,7 +517,7 @@ parse_expression (memory_pool_t *pool, char *line) return NULL; } /* Pop everything from stack */ - while(stack != NULL) { + while (stack != NULL) { op = delete_expression_stack (&stack); if (op != '(') { insert_expression (pool, &expr, EXPR_OPERATION, op, NULL); @@ -525,19 +530,19 @@ parse_expression (memory_pool_t *pool, char *line) /* * Rspamd regexp utility functions */ -struct rspamd_regexp* -parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) +struct rspamd_regexp * +parse_regexp (memory_pool_t * pool, char *line, gboolean raw_mode) { - char *begin, *end, *p, *src; - struct rspamd_regexp *result, *check; - int regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE; - GError *err = NULL; - + char *begin, *end, *p, *src; + struct rspamd_regexp *result, *check; + int regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE; + GError *err = NULL; + src = line; result = memory_pool_alloc0 (pool, sizeof (struct rspamd_regexp)); /* Skip whitespaces */ while (g_ascii_isspace (*line)) { - line ++; + line++; } if (line == '\0') { msg_warn ("parse_regexp: got empty regexp"); @@ -566,7 +571,7 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) } /* Find begin of regexp */ while (*line && *line != '/') { - line ++; + line++; } if (*line != '\0') { begin = line + 1; @@ -585,7 +590,7 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) /* Find end */ end = begin; while (*end && (*end != '/' || *(end - 1) == '\\')) { - end ++; + end++; } if (end == begin || *end != '/') { msg_warn ("parse_regexp: no trailing / in regexp %s", src); @@ -595,69 +600,69 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) p = end + 1; while (p != NULL) { switch (*p) { - case 'i': - regexp_flags |= G_REGEX_CASELESS; - p ++; - break; - case 'm': - regexp_flags |= G_REGEX_MULTILINE; - p ++; - break; - case 's': - regexp_flags |= G_REGEX_DOTALL; - p ++; - break; - case 'x': - regexp_flags |= G_REGEX_EXTENDED; - p ++; - break; - case 'u': - regexp_flags |= G_REGEX_UNGREEDY; - p ++; - break; - case 'o': - regexp_flags |= G_REGEX_OPTIMIZE; - p ++; - break; - case 'r': - regexp_flags |= G_REGEX_RAW; - p ++; - break; + case 'i': + regexp_flags |= G_REGEX_CASELESS; + p++; + break; + case 'm': + regexp_flags |= G_REGEX_MULTILINE; + p++; + break; + case 's': + regexp_flags |= G_REGEX_DOTALL; + p++; + break; + case 'x': + regexp_flags |= G_REGEX_EXTENDED; + p++; + break; + case 'u': + regexp_flags |= G_REGEX_UNGREEDY; + p++; + break; + case 'o': + regexp_flags |= G_REGEX_OPTIMIZE; + p++; + break; + case 'r': + regexp_flags |= G_REGEX_RAW; + p++; + break; /* Type flags */ - case 'H': - if (result->type == REGEXP_NONE) { - result->type = REGEXP_HEADER; - } - p ++; - break; - case 'M': - if (result->type == REGEXP_NONE) { - result->type = REGEXP_MESSAGE; - } - p ++; - break; - case 'P': - if (result->type == REGEXP_NONE) { - result->type = REGEXP_MIME; - } - p ++; - break; - case 'U': - if (result->type == REGEXP_NONE) { - result->type = REGEXP_URL; - } - p ++; - break; - case 'X': - if (result->type == REGEXP_NONE || result->type == REGEXP_HEADER) { - result->type = REGEXP_RAW_HEADER; - } - p ++; - break; + case 'H': + if (result->type == REGEXP_NONE) { + result->type = REGEXP_HEADER; + } + p++; + break; + case 'M': + if (result->type == REGEXP_NONE) { + result->type = REGEXP_MESSAGE; + } + p++; + break; + case 'P': + if (result->type == REGEXP_NONE) { + result->type = REGEXP_MIME; + } + p++; + break; + case 'U': + if (result->type == REGEXP_NONE) { + result->type = REGEXP_URL; + } + p++; + break; + case 'X': + if (result->type == REGEXP_NONE || result->type == REGEXP_HEADER) { + result->type = REGEXP_RAW_HEADER; + } + p++; + break; /* Stop flags parsing */ - default: - p = NULL; - break; + default: + p = NULL; + break; } } @@ -683,7 +688,7 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) } result->regexp = g_regex_new (begin, regexp_flags, 0, &err); result->regexp_text = memory_pool_strdup (pool, begin); - memory_pool_add_destructor (pool, (pool_destruct_func)g_regex_unref, (void *)result->regexp); + memory_pool_add_destructor (pool, (pool_destruct_func) g_regex_unref, (void *)result->regexp); if (result->regexp == NULL || err != NULL) { *end = '/'; @@ -695,7 +700,7 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) } else { result->raw_regexp = g_regex_new (begin, regexp_flags | G_REGEX_RAW, 0, &err); - memory_pool_add_destructor (pool, (pool_destruct_func)g_regex_unref, (void *)result->raw_regexp); + memory_pool_add_destructor (pool, (pool_destruct_func) g_regex_unref, (void *)result->raw_regexp); } *end = '/'; @@ -703,36 +708,35 @@ parse_regexp (memory_pool_t *pool, char *line, gboolean raw_mode) msg_warn ("parse_regexp: could not read raw regexp: %s while reading regexp %s", err->message, src); return NULL; } - + /* Add to cache for further usage */ re_cache_add (result->regexp_text, result); return result; } -gboolean -call_expression_function (struct expression_function *func, struct worker_task *task) +gboolean +call_expression_function (struct expression_function * func, struct worker_task * task) { - struct _fl *selected, key; + struct _fl *selected, key; key.name = func->name; - selected = bsearch (&key, list_ptr, functions_number, - sizeof (struct _fl), fl_cmp); + selected = bsearch (&key, list_ptr, functions_number, sizeof (struct _fl), fl_cmp); if (selected == NULL) { msg_warn ("call_expression_function: call to undefined function %s", key.name); return FALSE; } - + return selected->func (task, func->args); } -struct expression_argument * +struct expression_argument * get_function_arg (struct expression *expr, struct worker_task *task, gboolean want_string) { - GQueue *stack; - gsize cur, op1, op2; - struct expression_argument *res; - struct expression *it; + GQueue *stack; + gsize cur, op1, op2; + struct expression_argument *res; + struct expression *it; if (expr == NULL) { msg_warn ("get_function_arg: NULL expression passed"); @@ -767,11 +771,12 @@ get_function_arg (struct expression *expr, struct worker_task *task, gboolean wa res->type = EXPRESSION_ARGUMENT_EXPR; res->data = expr; return res; - } else if (it->type == EXPR_FUNCTION) { - cur = (gsize)call_expression_function ((struct expression_function *)it->content.operand, task); - msg_debug ("get_function_arg: function %s returned %s", ((struct expression_function *)it->content.operand)->name, - cur ? "true" : "false"); - } else if (it->type == EXPR_OPERATION) { + } + else if (it->type == EXPR_FUNCTION) { + cur = (gsize) call_expression_function ((struct expression_function *)it->content.operand, task); + msg_debug ("get_function_arg: function %s returned %s", ((struct expression_function *)it->content.operand)->name, cur ? "true" : "false"); + } + else if (it->type == EXPR_OPERATION) { if (g_queue_is_empty (stack)) { /* Queue has no operands for operation, exiting */ msg_debug ("get_function_arg: invalid expression"); @@ -779,22 +784,22 @@ get_function_arg (struct expression *expr, struct worker_task *task, gboolean wa return NULL; } switch (it->content.operation) { - case '!': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op1 = !op1; - g_queue_push_head (stack, GSIZE_TO_POINTER (op1)); - break; - case '&': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - g_queue_push_head (stack, GSIZE_TO_POINTER (op1 && op2)); - case '|': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - g_queue_push_head (stack, GSIZE_TO_POINTER (op1 || op2)); - default: - it = it->next; - continue; + case '!': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op1 = !op1; + g_queue_push_head (stack, GSIZE_TO_POINTER (op1)); + break; + case '&': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + g_queue_push_head (stack, GSIZE_TO_POINTER (op1 && op2)); + case '|': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + g_queue_push_head (stack, GSIZE_TO_POINTER (op1 || op2)); + default: + it = it->next; + continue; } } if (it) { @@ -819,10 +824,10 @@ get_function_arg (struct expression *expr, struct worker_task *task, gboolean wa void register_expression_function (const char *name, rspamd_internal_func_t func) { - static struct _fl *new; + static struct _fl *new; + + functions_number++; - functions_number ++; - new = g_new (struct _fl, functions_number); memcpy (new, list_ptr, (functions_number - 1) * sizeof (struct _fl)); if (list_allocated) { @@ -837,9 +842,9 @@ register_expression_function (const char *name, rspamd_internal_func_t func) } gboolean -rspamd_compare_encoding (struct worker_task *task, GList *args) +rspamd_compare_encoding (struct worker_task *task, GList * args) { - struct expression_argument *arg; + struct expression_argument *arg; if (args == NULL || task == NULL) { return FALSE; @@ -855,11 +860,11 @@ rspamd_compare_encoding (struct worker_task *task, GList *args) return TRUE; } -gboolean -rspamd_header_exists (struct worker_task *task, GList *args) +gboolean +rspamd_header_exists (struct worker_task * task, GList * args) { - struct expression_argument *arg; - GList *headerlist; + struct expression_argument *arg; + GList *headerlist; if (args == NULL || task == NULL) { return FALSE; @@ -885,14 +890,14 @@ rspamd_header_exists (struct worker_task *task, GList *args) * its hashes and check for threshold, if value is greater than threshold, return TRUE * and return FALSE otherwise. */ -gboolean -rspamd_parts_distance (struct worker_task *task, GList *args) -{ - int threshold; - struct mime_text_part *p1, *p2; - GList *cur; - struct expression_argument *arg; - +gboolean +rspamd_parts_distance (struct worker_task * task, GList * args) +{ + int threshold; + struct mime_text_part *p1, *p2; + GList *cur; + struct expression_argument *arg; + if (args == NULL) { msg_debug ("rspamd_parts_distance: no threshold is specified, assume it 100"); threshold = 100; @@ -928,17 +933,17 @@ rspamd_parts_distance (struct worker_task *task, GList *args) return FALSE; } -gboolean -rspamd_content_type_compare_param (struct worker_task *task, GList *args) +gboolean +rspamd_content_type_compare_param (struct worker_task * task, GList * args) { - char *param_name, *param_pattern; - const char *param_data; - struct rspamd_regexp *re; - struct expression_argument *arg; - GMimeObject *part; - const GMimeContentType *ct; - int r; - + char *param_name, *param_pattern; + const char *param_data; + struct rspamd_regexp *re; + struct expression_argument *arg; + GMimeObject *part; + const GMimeContentType *ct; + int r; + if (args == NULL) { msg_warn ("rspamd_content_type_compare_param: no parameters to function"); return FALSE; @@ -952,7 +957,7 @@ rspamd_content_type_compare_param (struct worker_task *task, GList *args) } arg = get_function_arg (args->data, task, TRUE); param_pattern = arg->data; - + part = g_mime_message_get_mime_part (task->message); if (part) { ct = g_mime_object_get_content_type (part); @@ -989,20 +994,20 @@ rspamd_content_type_compare_param (struct worker_task *task, GList *args) } } } - + return FALSE; -} +} -gboolean -rspamd_content_type_has_param (struct worker_task *task, GList *args) +gboolean +rspamd_content_type_has_param (struct worker_task * task, GList * args) { - char *param_name; - const char *param_data; - struct expression_argument *arg; - GMimeObject *part; - const GMimeContentType *ct; - + char *param_name; + const char *param_data; + struct expression_argument *arg; + GMimeObject *part; + const GMimeContentType *ct; + if (args == NULL) { msg_warn ("rspamd_content_type_compare_param: no parameters to function"); return FALSE; @@ -1020,34 +1025,34 @@ rspamd_content_type_has_param (struct worker_task *task, GList *args) return FALSE; } } - + return TRUE; } /* In gmime24 this function is opaque, so define it here to avoid errors when compiling with gmime24 */ typedef struct { - char *type; - char *subtype; - - GMimeParam *params; - GHashTable *param_hash; + char *type; + char *subtype; + + GMimeParam *params; + GHashTable *param_hash; } localContentType; -gboolean -rspamd_content_type_is_subtype (struct worker_task *task, GList *args) +gboolean +rspamd_content_type_is_subtype (struct worker_task *task, GList * args) { - char *param_pattern; - struct rspamd_regexp *re; - struct expression_argument *arg; - GMimeObject *part; - const localContentType *ct; - int r; - + char *param_pattern; + struct rspamd_regexp *re; + struct expression_argument *arg; + GMimeObject *part; + const localContentType *ct; + int r; + if (args == NULL) { msg_warn ("rspamd_content_type_compare_param: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); param_pattern = arg->data; part = g_mime_message_get_mime_part (task->message); @@ -1058,7 +1063,7 @@ rspamd_content_type_is_subtype (struct worker_task *task, GList *args) if (ct == NULL) { return FALSE; } - + if (*param_pattern == '/') { /* This is regexp, so compile and create g_regexp object */ if ((re = re_cache_check (param_pattern)) == NULL) { @@ -1091,21 +1096,21 @@ rspamd_content_type_is_subtype (struct worker_task *task, GList *args) return FALSE; } -gboolean -rspamd_content_type_is_type (struct worker_task *task, GList *args) +gboolean +rspamd_content_type_is_type (struct worker_task * task, GList * args) { - char *param_pattern; - struct rspamd_regexp *re; - GMimeObject *part; - const localContentType *ct; - struct expression_argument *arg; - int r; - + char *param_pattern; + struct rspamd_regexp *re; + GMimeObject *part; + const localContentType *ct; + struct expression_argument *arg; + int r; + if (args == NULL) { msg_warn ("rspamd_content_type_compare_param: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); param_pattern = arg->data; @@ -1117,7 +1122,7 @@ rspamd_content_type_is_type (struct worker_task *task, GList *args) if (ct == NULL) { return FALSE; } - + if (*param_pattern == '/') { /* This is regexp, so compile and create g_regexp object */ if ((re = re_cache_check (param_pattern)) == NULL) { @@ -1151,29 +1156,29 @@ rspamd_content_type_is_type (struct worker_task *task, GList *args) } struct addr_list { - const char *name; - const char *addr; + const char *name; + const char *addr; }; #define COMPARE_RCPT_LEN 3 #define MIN_RCPT_TO_COMPARE 5 -gboolean -rspamd_recipients_distance (struct worker_task *task, GList *args) +gboolean +rspamd_recipients_distance (struct worker_task *task, GList * args) { - struct expression_argument *arg; - InternetAddressList *cur; - InternetAddress *addr; - double threshold; - struct addr_list *ar; - char *c; - int num, i, j, hits = 0, total = 0; - + struct expression_argument *arg; + InternetAddressList *cur; + InternetAddress *addr; + double threshold; + struct addr_list *ar; + char *c; + int num, i, j, hits = 0, total = 0; + if (args == NULL) { msg_warn ("rspamd_content_type_compare_param: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); errno = 0; threshold = strtod ((char *)arg->data, NULL); @@ -1199,21 +1204,21 @@ rspamd_recipients_distance (struct worker_task *task, GList *args) ar[i].addr = c + 1; } cur = internet_address_list_next (cur); - i ++; + i++; } /* Cycle all elements in array */ - for (i = 0; i < num; i ++) { - for (j = i + 1; j < num; j ++) { + for (i = 0; i < num; i++) { + for (j = i + 1; j < num; j++) { if (ar[i].name && ar[j].name && g_ascii_strncasecmp (ar[i].name, ar[j].name, COMPARE_RCPT_LEN) == 0) { /* Common name part */ - hits ++; + hits++; } else if (ar[i].addr && ar[j].addr && g_ascii_strcasecmp (ar[i].addr, ar[j].addr) == 0) { /* Common address part, but different name */ - hits ++; + hits++; } - total ++; + total++; } } @@ -1224,12 +1229,12 @@ rspamd_recipients_distance (struct worker_task *task, GList *args) return FALSE; } -gboolean -rspamd_has_only_html_part (struct worker_task *task, GList *args) +gboolean +rspamd_has_only_html_part (struct worker_task * task, GList * args) { - struct mime_text_part *p; - GList *cur; - gboolean res = FALSE; + struct mime_text_part *p; + GList *cur; + gboolean res = FALSE; cur = g_list_first (task->text_parts); while (cur) { @@ -1247,14 +1252,15 @@ rspamd_has_only_html_part (struct worker_task *task, GList *args) return res; } -static gboolean -is_recipient_list_sorted (const InternetAddressList *ia) +static gboolean +is_recipient_list_sorted (const InternetAddressList * ia) { - const InternetAddressList *cur; - InternetAddress *addr; - gboolean res = TRUE; - struct addr_list current = {NULL, NULL}, previous = {NULL, NULL}; - + const InternetAddressList *cur; + InternetAddress *addr; + gboolean res = TRUE; + struct addr_list current = { NULL, NULL }, previous = { + NULL, NULL}; + /* Do not check to short address lists */ if (internet_address_list_length (ia) < MIN_RCPT_TO_COMPARE) { return FALSE; @@ -1278,7 +1284,7 @@ is_recipient_list_sorted (const InternetAddressList *ia) } gboolean -rspamd_is_recipients_sorted (struct worker_task *task, GList *args) +rspamd_is_recipients_sorted (struct worker_task * task, GList * args) { /* Check all types of addresses */ if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_TO)) == TRUE) { @@ -1294,11 +1300,11 @@ rspamd_is_recipients_sorted (struct worker_task *task, GList *args) return FALSE; } -static inline gboolean -compare_subtype (struct worker_task *task, const localContentType *ct, char *subtype) +static inline gboolean +compare_subtype (struct worker_task *task, const localContentType * ct, char *subtype) { - struct rspamd_regexp *re; - int r; + struct rspamd_regexp *re; + int r; if (*subtype == '/') { /* This is regexp, so compile and create g_regexp object */ @@ -1331,7 +1337,7 @@ compare_subtype (struct worker_task *task, const localContentType *ct, char *sub return FALSE; } -static inline gboolean +static inline gboolean compare_len (struct mime_part *part, int min, int max) { if (min == 0 && max == 0) { @@ -1349,24 +1355,24 @@ compare_len (struct mime_part *part, int min, int max) } } -gboolean -common_has_content_part (struct worker_task *task, char *param_type, char *param_subtype, int min_len, int max_len) +gboolean +common_has_content_part (struct worker_task * task, char *param_type, char *param_subtype, int min_len, int max_len) { - struct rspamd_regexp *re; - struct mime_part *part; - GList *cur; - const localContentType *ct; - int r; - + struct rspamd_regexp *re; + struct mime_part *part; + GList *cur; + const localContentType *ct; + int r; + cur = g_list_first (task->parts); while (cur) { part = cur->data; - ct = (localContentType *)part->type; + ct = (localContentType *) part->type; if (ct == NULL) { cur = g_list_next (cur); continue; } - + if (*param_type == '/') { /* This is regexp, so compile and create g_regexp object */ if ((re = re_cache_check (param_type)) == NULL) { @@ -1432,16 +1438,16 @@ common_has_content_part (struct worker_task *task, char *param_type, char *param } gboolean -rspamd_has_content_part (struct worker_task *task, GList *args) +rspamd_has_content_part (struct worker_task * task, GList * args) { - char *param_type = NULL, *param_subtype = NULL; - struct expression_argument *arg; + char *param_type = NULL, *param_subtype = NULL; + struct expression_argument *arg; if (args == NULL) { msg_warn ("rspamd_has_content_part: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); param_type = arg->data; args = args->next; @@ -1454,17 +1460,17 @@ rspamd_has_content_part (struct worker_task *task, GList *args) } gboolean -rspamd_has_content_part_len (struct worker_task *task, GList *args) +rspamd_has_content_part_len (struct worker_task * task, GList * args) { - char *param_type = NULL, *param_subtype = NULL; - int min = 0, max = 0; - struct expression_argument *arg; + char *param_type = NULL, *param_subtype = NULL; + int min = 0, max = 0; + struct expression_argument *arg; if (args == NULL) { msg_warn ("rspamd_has_content_part_len: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); param_type = arg->data; args = args->next; @@ -1495,18 +1501,18 @@ rspamd_has_content_part_len (struct worker_task *task, GList *args) return common_has_content_part (task, param_type, param_subtype, min, max); } -gboolean -rspamd_compare_transfer_encoding (struct worker_task *task, GList *args) +gboolean +rspamd_compare_transfer_encoding (struct worker_task * task, GList * args) { - GMimeObject *part; - GMimePartEncodingType enc_req, part_enc; - struct expression_argument *arg; - + GMimeObject *part; + GMimePartEncodingType enc_req, part_enc; + struct expression_argument *arg; + if (args == NULL) { msg_warn ("rspamd_compare_transfer_encoding: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); enc_req = g_mime_part_encoding_from_string (arg->data); #ifndef GMIME24 @@ -1522,9 +1528,8 @@ rspamd_compare_transfer_encoding (struct worker_task *task, GList *args) if (part) { if (GMIME_IS_PART (part)) { part_enc = g_mime_part_get_encoding (GMIME_PART (part)); - - msg_debug ("rspamd_compare_transfer_encoding: got encoding in part: %d and compare with %d", - (int)part_enc, (int)enc_req); + + msg_debug ("rspamd_compare_transfer_encoding: got encoding in part: %d and compare with %d", (int)part_enc, (int)enc_req); g_object_unref (part); return part_enc == enc_req; @@ -1535,12 +1540,12 @@ rspamd_compare_transfer_encoding (struct worker_task *task, GList *args) return FALSE; } -gboolean -rspamd_is_html_balanced (struct worker_task *task, GList *args) +gboolean +rspamd_is_html_balanced (struct worker_task * task, GList * args) { - struct mime_text_part *p; - GList *cur; - gboolean res = TRUE; + struct mime_text_part *p; + GList *cur; + gboolean res = TRUE; cur = g_list_first (task->text_parts); while (cur) { @@ -1562,16 +1567,16 @@ rspamd_is_html_balanced (struct worker_task *task, GList *args) } struct html_callback_data { - struct html_tag *tag; - gboolean *res; + struct html_tag *tag; + gboolean *res; }; -static gboolean -search_html_node_callback (GNode *node, gpointer data) +static gboolean +search_html_node_callback (GNode * node, gpointer data) { - struct html_callback_data *cd = data; - struct html_node *nd; - + struct html_callback_data *cd = data; + struct html_node *nd; + nd = node->data; if (nd) { if (nd->tag == cd->tag) { @@ -1583,21 +1588,21 @@ search_html_node_callback (GNode *node, gpointer data) return FALSE; } -gboolean -rspamd_has_html_tag (struct worker_task *task, GList *args) +gboolean +rspamd_has_html_tag (struct worker_task * task, GList * args) { - struct mime_text_part *p; - GList *cur; - struct expression_argument *arg; - struct html_tag *tag; - gboolean res = FALSE; - struct html_callback_data cd; - + struct mime_text_part *p; + GList *cur; + struct expression_argument *arg; + struct html_tag *tag; + gboolean res = FALSE; + struct html_callback_data cd; + if (args == NULL) { msg_warn ("rspamd_has_html_tag: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); tag = get_tag_by_name (arg->data); if (tag == NULL) { @@ -1621,13 +1626,13 @@ rspamd_has_html_tag (struct worker_task *task, GList *args) } -gboolean -rspamd_has_fake_html (struct worker_task *task, GList *args) +gboolean +rspamd_has_fake_html (struct worker_task * task, GList * args) { - struct mime_text_part *p; - GList *cur; - gboolean res = FALSE; - + struct mime_text_part *p; + GList *cur; + gboolean res = FALSE; + cur = g_list_first (task->text_parts); while (cur && res == FALSE) { diff --git a/src/filter.c b/src/filter.c index 86df617df..0ffec02d5 100644 --- a/src/filter.c +++ b/src/filter.c @@ -39,20 +39,20 @@ #include "tokenizers/tokenizers.h" #ifndef WITHOUT_PERL -#include "perl.h" +# include "perl.h" #endif #ifdef WITH_LUA -#include "lua/lua_common.h" +# include "lua/lua_common.h" #endif void -insert_result (struct worker_task *task, const char *metric_name, const char *symbol, double flag, GList *opts) +insert_result (struct worker_task *task, const char *metric_name, const char *symbol, double flag, GList * opts) { - struct metric *metric; - struct metric_result *metric_res; - struct symbol *s; - struct cache_item *item; - int i; + struct metric *metric; + struct metric_result *metric_res; + struct symbol *s; + struct cache_item *item; + int i; metric = g_hash_table_lookup (task->worker->srv->cfg->metrics, metric_name); if (metric == NULL) { @@ -66,11 +66,11 @@ insert_result (struct worker_task *task, const char *metric_name, const char *sy metric_res = memory_pool_alloc (task->task_pool, sizeof (struct metric_result)); metric_res->symbols = g_hash_table_new (g_str_hash, g_str_equal); metric_res->checked = FALSE; - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_hash_table_destroy, metric_res->symbols); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_hash_table_destroy, metric_res->symbols); metric_res->metric = metric; - g_hash_table_insert (task->results, (gpointer)metric_name, metric_res); + g_hash_table_insert (task->results, (gpointer) metric_name, metric_res); } - + if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) { if (s->options && opts) { /* Append new options */ @@ -82,7 +82,7 @@ insert_result (struct worker_task *task, const char *metric_name, const char *sy } else if (opts) { s->options = opts; - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, s->options); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_list_free, s->options); } s->score = flag; @@ -93,19 +93,19 @@ insert_result (struct worker_task *task, const char *metric_name, const char *sy s->options = opts; if (opts) { - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, s->options); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_list_free, s->options); } - g_hash_table_insert (metric_res->symbols, (gpointer)symbol, s); + g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s); } /* Process cache item */ if (metric->cache) { - for (i = 0; i < metric->cache->used_items; i ++) { + for (i = 0; i < metric->cache->used_items; i++) { item = &metric->cache->items[i]; if (flag > 0 && strcmp (item->s->symbol, symbol) == 0) { - item->s->frequency ++; + item->s->frequency++; } } } @@ -115,15 +115,15 @@ insert_result (struct worker_task *task, const char *metric_name, const char *sy * Default consolidation function based on factors in config file */ struct consolidation_callback_data { - struct worker_task *task; - double score; + struct worker_task *task; + double score; }; static void consolidation_callback (gpointer key, gpointer value, gpointer arg) { - double *factor, fs; - struct symbol *s = (struct symbol *)value; + double *factor, fs; + struct symbol *s = (struct symbol *)value; struct consolidation_callback_data *data = (struct consolidation_callback_data *)arg; if (check_factor_settings (data->task, key, &fs)) { @@ -145,15 +145,15 @@ consolidation_callback (gpointer key, gpointer value, gpointer arg) double factor_consolidation_func (struct worker_task *task, const char *metric_name, const char *unused) { - struct metric_result *metric_res; - double res = 0.; + struct metric_result *metric_res; + double res = 0.; struct consolidation_callback_data data = { task, 0 }; metric_res = g_hash_table_lookup (task->results, metric_name); if (metric_res == NULL) { return res; } - + g_hash_table_foreach (metric_res->symbols, consolidation_callback, &data); return data.score; @@ -165,30 +165,30 @@ factor_consolidation_func (struct worker_task *task, const char *metric_name, co static void call_filter_by_name (struct worker_task *task, const char *name, enum filter_type filt_type) { - struct module_ctx *c_module; - int res = 0; - + struct module_ctx *c_module; + int res = 0; + switch (filt_type) { - case C_FILTER: - c_module = g_hash_table_lookup (task->worker->srv->cfg->c_modules, name); - if (c_module) { - res = 1; - c_module->filter (task); - } - else { - msg_debug ("call_filter_by_name: %s is not a C module", name); - } - break; - case PERL_FILTER: + case C_FILTER: + c_module = g_hash_table_lookup (task->worker->srv->cfg->c_modules, name); + if (c_module) { res = 1; + c_module->filter (task); + } + else { + msg_debug ("call_filter_by_name: %s is not a C module", name); + } + break; + case PERL_FILTER: + res = 1; #ifndef WITHOUT_PERL - perl_call_filter (name, task); + perl_call_filter (name, task); #elif defined(WITH_LUA) - lua_call_filter (name, task); + lua_call_filter (name, task); #else - msg_err ("call_filter_by_name: trying to call perl function while perl support is disabled %s", name); + msg_err ("call_filter_by_name: trying to call perl function while perl support is disabled %s", name); #endif - break; + break; } msg_debug ("call_filter_by_name: filter name: %s, result: %d", name, (int)res); @@ -197,14 +197,14 @@ call_filter_by_name (struct worker_task *task, const char *name, enum filter_typ static void metric_process_callback_common (gpointer key, gpointer value, void *data, gboolean is_forced) { - struct worker_task *task = (struct worker_task *)data; - struct metric_result *metric_res = (struct metric_result *)value; - + struct worker_task *task = (struct worker_task *)data; + struct metric_result *metric_res = (struct metric_result *)value; + if (metric_res->checked && !is_forced) { /* Already checked */ return; } - + /* Set flag */ metric_res->checked = TRUE; @@ -214,8 +214,7 @@ metric_process_callback_common (gpointer key, gpointer value, void *data, gboole else { metric_res->score = factor_consolidation_func (task, metric_res->metric->name, NULL); } - msg_debug ("process_metric_callback: got result %.2f from consolidation function for metric %s", - metric_res->score, metric_res->metric->name); + msg_debug ("process_metric_callback: got result %.2f from consolidation function for metric %s", metric_res->score, metric_res->metric->name); } static void @@ -231,11 +230,11 @@ metric_process_callback_forced (gpointer key, gpointer value, void *data) } /* Return true if metric has score that is more than spam score for it */ -static gboolean +static gboolean check_metric_is_spam (struct worker_task *task, struct metric *metric) { - struct metric_result *res; - double ms; + struct metric_result *res; + double ms; res = g_hash_table_lookup (task->results, metric->name); if (res) { @@ -252,11 +251,11 @@ check_metric_is_spam (struct worker_task *task, struct metric *metric) static int continue_process_filters (struct worker_task *task) { - GList *cur = task->save.entry; - struct cache_item *item = task->save.item; + GList *cur = task->save.entry; + struct cache_item *item = task->save.item; + + struct metric *metric = cur->data; - struct metric *metric = cur->data; - while (cur) { metric = cur->data; while (call_symbol_callback (task, metric->cache, &item)) { @@ -280,12 +279,12 @@ continue_process_filters (struct worker_task *task) return 1; } -int +int process_filters (struct worker_task *task) { - GList *cur; - struct metric *metric; - struct cache_item *item = NULL; + GList *cur; + struct metric *metric; + struct cache_item *item = NULL; if (task->save.saved) { task->save.saved = 0; @@ -321,20 +320,20 @@ process_filters (struct worker_task *task) } struct composites_data { - struct worker_task *task; - struct metric_result *metric_res; + struct worker_task *task; + struct metric_result *metric_res; }; static void composites_foreach_callback (gpointer key, gpointer value, void *data) { - struct composites_data *cd = (struct composites_data *)data; - struct expression *expr = (struct expression *)value; - GQueue *stack; - GList *symbols = NULL, *s; - gsize cur, op1, op2; - struct symbol *res; - + struct composites_data *cd = (struct composites_data *)data; + struct expression *expr = (struct expression *)value; + GQueue *stack; + GList *symbols = NULL, *s; + gsize cur, op1, op2; + struct symbol *res; + stack = g_queue_new (); while (expr) { @@ -357,22 +356,22 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) return; } switch (expr->content.operation) { - case '!': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op1 = !op1; - g_queue_push_head (stack, GSIZE_TO_POINTER (op1)); - break; - case '&': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - g_queue_push_head (stack, GSIZE_TO_POINTER (op1 && op2)); - case '|': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - g_queue_push_head (stack, GSIZE_TO_POINTER (op1 || op2)); - default: - expr = expr->next; - continue; + case '!': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op1 = !op1; + g_queue_push_head (stack, GSIZE_TO_POINTER (op1)); + break; + case '&': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + g_queue_push_head (stack, GSIZE_TO_POINTER (op1 && op2)); + case '|': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + g_queue_push_head (stack, GSIZE_TO_POINTER (op1 || op2)); + default: + expr = expr->next; + continue; } } expr = expr->next; @@ -400,12 +399,12 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) return; } -static gboolean +static gboolean check_autolearn (struct statfile_autolearn_params *params, struct worker_task *task) -{ - char *metric_name = DEFAULT_METRIC; - struct metric_result *metric_res; - GList *cur; +{ + char *metric_name = DEFAULT_METRIC; + struct metric_result *metric_res; + GList *cur; if (params->metric != NULL) { metric_name = (char *)params->metric; @@ -424,8 +423,7 @@ check_autolearn (struct statfile_autolearn_params *params, struct worker_task *t else { /* Process score of metric */ metric_process_callback_normal ((void *)metric_name, metric_res, task); - if ((params->threshold_min != 0 && metric_res->score > params->threshold_min) || - (params->threshold_max != 0 && metric_res->score < params->threshold_max)) { + if ((params->threshold_min != 0 && metric_res->score > params->threshold_min) || (params->threshold_max != 0 && metric_res->score < params->threshold_max)) { /* Now check for specific symbols */ if (params->symbols) { cur = params->symbols; @@ -445,19 +443,17 @@ check_autolearn (struct statfile_autolearn_params *params, struct worker_task *t } void -process_autolearn (struct statfile *st, struct worker_task *task, GTree *tokens, - struct classifier *classifier, char *filename, struct classifier_ctx* ctx) +process_autolearn (struct statfile *st, struct worker_task *task, GTree * tokens, struct classifier *classifier, char *filename, struct classifier_ctx *ctx) { if (check_autolearn (st->autolearn, task)) { if (tokens) { msg_info ("process_autolearn: message with id <%s> autolearned statfile '%s'", task->message_id, filename); /* Check opened */ - if (! statfile_pool_is_open (task->worker->srv->statfile_pool, filename)) { + if (!statfile_pool_is_open (task->worker->srv->statfile_pool, filename)) { /* Try open */ if (statfile_pool_open (task->worker->srv->statfile_pool, filename) == NULL) { /* Try create */ - if (statfile_pool_create (task->worker->srv->statfile_pool, - filename, st->size / sizeof (struct stat_file_block)) == -1) { + if (statfile_pool_create (task->worker->srv->statfile_pool, filename, st->size / sizeof (struct stat_file_block)) == -1) { msg_info ("process_autolearn: error while creating statfile %s", filename); return; } @@ -470,11 +466,11 @@ process_autolearn (struct statfile *st, struct worker_task *task, GTree *tokens, } static void -composites_metric_callback (gpointer key, gpointer value, void *data) +composites_metric_callback (gpointer key, gpointer value, void *data) { - struct worker_task *task = (struct worker_task *)data; - struct composites_data *cd = memory_pool_alloc (task->task_pool, sizeof (struct composites_data)); - struct metric_result *metric_res = (struct metric_result *)value; + struct worker_task *task = (struct worker_task *)data; + struct composites_data *cd = memory_pool_alloc (task->task_pool, sizeof (struct composites_data)); + struct metric_result *metric_res = (struct metric_result *)value; cd->task = task; cd->metric_res = (struct metric_result *)metric_res; @@ -482,7 +478,7 @@ composites_metric_callback (gpointer key, gpointer value, void *data) g_hash_table_foreach (task->cfg->composite_symbols, composites_foreach_callback, cd); } -void +void make_composites (struct worker_task *task) { g_hash_table_foreach (task->results, composites_metric_callback, task); @@ -492,23 +488,23 @@ make_composites (struct worker_task *task) struct statfile_callback_data { - GHashTable *tokens; - struct worker_task *task; + GHashTable *tokens; + struct worker_task *task; }; static void classifiers_callback (gpointer value, void *arg) { - struct statfile_callback_data *data= (struct statfile_callback_data *)arg; - struct worker_task *task = data->task; - struct classifier_config *cl = value; - struct classifier_ctx *ctx; - struct mime_text_part *text_part; - struct statfile *st; - GTree *tokens = NULL; - GList *cur; - f_str_t c; - + struct statfile_callback_data *data = (struct statfile_callback_data *)arg; + struct worker_task *task = data->task; + struct classifier_config *cl = value; + struct classifier_ctx *ctx; + struct mime_text_part *text_part; + struct statfile *st; + GTree *tokens = NULL; + GList *cur; + f_str_t c; + cur = g_list_first (task->text_parts); if ((tokens = g_hash_table_lookup (data->tokens, cl->tokenizer)) == NULL) { while (cur != NULL) { @@ -532,10 +528,10 @@ classifiers_callback (gpointer value, void *arg) if (tokens == NULL) { return; } - + ctx = cl->classifier->init_func (task->task_pool, cl); cl->classifier->classify_func (ctx, task->worker->srv->statfile_pool, tokens, task); - + /* Autolearning */ cur = g_list_first (cl->statfiles); while (cur) { @@ -554,8 +550,8 @@ classifiers_callback (gpointer value, void *arg) void process_statfiles (struct worker_task *task) { - struct statfile_callback_data cd; - + struct statfile_callback_data cd; + cd.task = task; cd.tokens = g_hash_table_new (g_direct_hash, g_direct_equal); @@ -570,14 +566,14 @@ process_statfiles (struct worker_task *task) static void insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data) { - struct worker_task *task = (struct worker_task *)data; - int r = 0; + struct worker_task *task = (struct worker_task *)data; + int r = 0; /* Try to be rfc2822 compatible and avoid long headers with folding */ - char header_name[128], outbuf[1000]; - GList *symbols = NULL, *cur; - struct metric_result *metric_res = (struct metric_result *)metric_value; - double ms; - + char header_name[128], outbuf[1000]; + GList *symbols = NULL, *cur; + struct metric_result *metric_res = (struct metric_result *)metric_value; + double ms; + snprintf (header_name, sizeof (header_name), "X-Spam-%s", metric_res->metric->name); if (!check_metric_settings (task, metric_res->metric, &ms)) { diff --git a/src/fstring.c b/src/fstring.c index 00ca4ed12..d325aa421 100644 --- a/src/fstring.c +++ b/src/fstring.c @@ -28,15 +28,15 @@ * Search first occurence of character in string */ ssize_t -fstrchr (f_str_t *src, char c) +fstrchr (f_str_t * src, char c) { - register ssize_t cur = 0; + register ssize_t cur = 0; while (cur < src->len) { if (*(src->begin + cur) == c) { return cur; } - cur ++; + cur++; } return -1; @@ -46,15 +46,15 @@ fstrchr (f_str_t *src, char c) * Search last occurence of character in string */ ssize_t -fstrrchr (f_str_t *src, char c) +fstrrchr (f_str_t * src, char c) { - register ssize_t cur = src->len; + register ssize_t cur = src->len; while (cur > 0) { if (*(src->begin + cur) == c) { return cur; } - cur --; + cur--; } return -1; @@ -64,9 +64,9 @@ fstrrchr (f_str_t *src, char c) * Search for pattern in orig */ ssize_t -fstrstr (f_str_t *orig, f_str_t *pattern) +fstrstr (f_str_t * orig, f_str_t * pattern) { - register ssize_t cur = 0, pcur = 0; + register ssize_t cur = 0, pcur = 0; if (pattern->len > orig->len) { return -1; @@ -79,12 +79,12 @@ fstrstr (f_str_t *orig, f_str_t *pattern) pcur = 0; break; } - cur ++; - pcur ++; + cur++; + pcur++; } return cur - pattern->len; } - cur ++; + cur++; } return -1; @@ -95,9 +95,9 @@ fstrstr (f_str_t *orig, f_str_t *pattern) * Search for pattern in orig ignoring case */ ssize_t -fstrstri (f_str_t *orig, f_str_t *pattern) +fstrstri (f_str_t * orig, f_str_t * pattern) { - register ssize_t cur = 0, pcur = 0; + register ssize_t cur = 0, pcur = 0; if (pattern->len > orig->len) { return -1; @@ -110,12 +110,12 @@ fstrstri (f_str_t *orig, f_str_t *pattern) pcur = 0; break; } - cur ++; - pcur ++; + cur++; + pcur++; } return cur - pattern->len; } - cur ++; + cur++; } return -1; @@ -131,10 +131,10 @@ fstrstri (f_str_t *orig, f_str_t *pattern) * 0 - last word extracted */ int -fstrtok (f_str_t *text, const char *sep, f_tok_t *state) +fstrtok (f_str_t * text, const char *sep, f_tok_t * state) { - register size_t cur; - const char *csep = sep; + register size_t cur; + const char *csep = sep; if (state->pos >= text->len) { return -1; @@ -150,12 +150,12 @@ fstrtok (f_str_t *text, const char *sep, f_tok_t *state) state->pos = cur + 1; return 1; } - csep ++; + csep++; } csep = sep; - cur ++; + cur++; } - + /* Last word */ state->word.begin = (text->begin + state->pos); state->word.len = cur - state->pos; @@ -168,9 +168,9 @@ fstrtok (f_str_t *text, const char *sep, f_tok_t *state) * Copy one string into other */ size_t -fstrcpy (f_str_t *dest, f_str_t *src) +fstrcpy (f_str_t * dest, f_str_t * src) { - register size_t cur = 0; + register size_t cur = 0; if (dest->size < src->len) { return 0; @@ -178,7 +178,7 @@ fstrcpy (f_str_t *dest, f_str_t *src) while (cur < src->len && cur < dest->size) { *(dest->begin + cur) = *(src->begin + cur); - cur ++; + cur++; } return cur; @@ -188,10 +188,10 @@ fstrcpy (f_str_t *dest, f_str_t *src) * Concatenate two strings */ size_t -fstrcat (f_str_t *dest, f_str_t *src) +fstrcat (f_str_t * dest, f_str_t * src) { - register size_t cur = 0; - char *p = dest->begin + dest->len; + register size_t cur = 0; + char *p = dest->begin + dest->len; if (dest->size < src->len + dest->len) { return 0; @@ -199,8 +199,8 @@ fstrcat (f_str_t *dest, f_str_t *src) while (cur < src->len) { *p = *(src->begin + cur); - p ++; - cur ++; + p++; + cur++; } dest->len += src->len; @@ -212,10 +212,10 @@ fstrcat (f_str_t *dest, f_str_t *src) /* * Make copy of string to 0-terminated string */ -char* -fstrcstr (f_str_t *str, memory_pool_t *pool) +char * +fstrcstr (f_str_t * str, memory_pool_t * pool) { - char *res; + char *res; res = memory_pool_alloc (pool, str->len + 1); memcpy (res, str->begin, str->len); @@ -228,7 +228,7 @@ fstrcstr (f_str_t *str, memory_pool_t *pool) * Push one character to fstr */ int -fstrpush (f_str_t *dest, char c) +fstrpush (f_str_t * dest, char c) { if (dest->size < dest->len) { /* Need to reallocate string */ @@ -236,32 +236,32 @@ fstrpush (f_str_t *dest, char c) } *(dest->begin + dest->len) = c; - dest->len ++; + dest->len++; return 1; } /* * Allocate memory for f_str_t */ -f_str_t* -fstralloc (memory_pool_t *pool, size_t len) +f_str_t * +fstralloc (memory_pool_t * pool, size_t len) { - f_str_t *res = memory_pool_alloc (pool, sizeof (f_str_t)); + f_str_t *res = memory_pool_alloc (pool, sizeof (f_str_t)); res->begin = memory_pool_alloc (pool, len); res->size = len; - res->len = 0; + res->len = 0; return res; } /* * Truncate string to its len */ -f_str_t* -fstrtruncate (memory_pool_t *pool, f_str_t *orig) +f_str_t * +fstrtruncate (memory_pool_t * pool, f_str_t * orig) { - f_str_t *res; + f_str_t *res; if (orig == NULL || orig->len == 0 || orig->size <= orig->len) { return orig; @@ -279,10 +279,10 @@ fstrtruncate (memory_pool_t *pool, f_str_t *orig) /* * Enlarge string to new size */ -f_str_t* -fstrgrow (memory_pool_t *pool, f_str_t *orig, size_t newlen) +f_str_t * +fstrgrow (memory_pool_t * pool, f_str_t * orig, size_t newlen) { - f_str_t *res; + f_str_t *res; if (orig == NULL || orig->len == 0 || orig->size >= newlen) { return orig; @@ -301,19 +301,19 @@ fstrgrow (memory_pool_t *pool, f_str_t *orig, size_t newlen) * Return hash value for a string */ uint32_t -fstrhash (f_str_t *str) +fstrhash (f_str_t * str) { - size_t i; - uint32_t hval; - uint32_t tmp; - char *c = str->begin; + size_t i; + uint32_t hval; + uint32_t tmp; + char *c = str->begin; if (str == NULL) { return 0; } hval = str->len; - for (i = 0; i < str->len; i++, c++) { + for (i = 0; i < str->len; i++, c++) { /* * xor in the current byte against each byte of hval * (which alone gaurantees that every bit of input will have @@ -324,7 +324,7 @@ fstrhash (f_str_t *str) hval ^= tmp; /* add some bits out of the middle as low order bits */ - hval = hval + ((hval >> 12) & 0x0000ffff) ; + hval = hval + ((hval >> 12) & 0x0000ffff); /* swap most and min significative bytes */ tmp = (hval << 24) | ((hval >> 24) & 0xff); @@ -341,21 +341,21 @@ fstrhash (f_str_t *str) } void -fstrstrip (f_str_t *str) +fstrstrip (f_str_t * str) { - char *p = str->begin; - int r = 0; + char *p = str->begin; + int r = 0; while (r < str->len) { if (g_ascii_isspace (*p)) { - p ++; - r ++; + p++; + r++; } else { break; } } - + if (r > 0) { memmove (str->begin, p, str->len - r); str->len -= r; @@ -365,8 +365,8 @@ fstrstrip (f_str_t *str) p = str->begin + str->len; while (r > 0) { if (g_ascii_isspace (*p)) { - p --; - r --; + p--; + r--; } else { break; diff --git a/src/fuzzy.c b/src/fuzzy.c index cb595a9ab..b71fcb650 100644 --- a/src/fuzzy.c +++ b/src/fuzzy.c @@ -33,16 +33,16 @@ #define HASH_INIT 0x28021967 struct roll_state { - uint32_t h[3]; - char window[ROLL_WINDOW_SIZE]; - int n; + uint32_t h[3]; + char window[ROLL_WINDOW_SIZE]; + int n; }; -static struct roll_state rs; +static struct roll_state rs; /* Rolling hash function based on Adler-32 checksum */ -static uint32_t +static uint32_t fuzzy_roll_hash (char c) { /* Check window position */ @@ -52,34 +52,34 @@ fuzzy_roll_hash (char c) rs.h[1] -= rs.h[0]; rs.h[1] += ROLL_WINDOW_SIZE * c; - + rs.h[0] += c; rs.h[0] -= rs.window[rs.n]; - + /* Save current symbol */ rs.window[rs.n] = c; - rs.n ++; - + rs.n++; + rs.h[2] <<= 5; rs.h[2] ^= c; - + return rs.h[0] + rs.h[1] + rs.h[2]; } /* A simple non-rolling hash, based on the FNV hash */ -static uint32_t +static uint32_t fuzzy_fnv_hash (char c, uint32_t hval) { hval ^= c; - hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); + hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); return hval; } /* Calculate blocksize depending on length of input */ -static uint32_t -fuzzy_blocksize (uint32_t len) +static uint32_t +fuzzy_blocksize (uint32_t len) { - + if (len < MIN_FUZZY_BLOCK_SIZE) { return MIN_FUZZY_BLOCK_SIZE; } @@ -88,16 +88,16 @@ fuzzy_blocksize (uint32_t len) /* Update hash with new symbol */ void -fuzzy_update (fuzzy_hash_t *h, char c) +fuzzy_update (fuzzy_hash_t * h, char c) { h->rh = fuzzy_roll_hash (c); - h->h = fuzzy_fnv_hash(c, h->h); - + h->h = fuzzy_fnv_hash (c, h->h); + if (h->rh % h->block_size == (h->block_size - 1)) { h->hash_pipe[h->hi] = h->h; if (h->hi < FUZZY_HASHLEN - 2) { h->h = HASH_INIT; - h->hi ++; + h->hi++; } } } @@ -109,24 +109,24 @@ fuzzy_update (fuzzy_hash_t *h, char c) */ uint32_t lev_distance (char *s1, int len1, char *s2, int len2) -{ - int i; - int *row; /* we only need to keep one row of costs */ - int *end; - int half, nx; - char *sx, *char2p, char1; - int *p, D, x, offset, c3; +{ + int i; + int *row; /* we only need to keep one row of costs */ + int *end; + int half, nx; + char *sx, *char2p, char1; + int *p, D, x, offset, c3; /* strip common prefix */ while (len1 > 0 && len2 > 0 && *s1 == *s2) { - len1 --; - len2 --; - s1 ++; - s2 ++; + len1--; + len2--; + s1++; + s2++; } /* strip common suffix */ - while (len1 > 0 && len2 > 0 && s1[len1-1] == s2[len2-1]) { + while (len1 > 0 && len2 > 0 && s1[len1 - 1] == s2[len2 - 1]) { len1--; len2--; } @@ -154,12 +154,12 @@ lev_distance (char *s1, int len1, char *s2, int len2) return len2 - (memchr (s2, *s1, len2) != NULL); } - len1 ++; - len2 ++; + len1++; + len2++; half = len1 >> 1; /* initalize first row */ - row = g_malloc (len2 * sizeof(int)); + row = g_malloc (len2 * sizeof (int)); end = row + len2 - 1; for (i = 0; i < len2; i++) { row[i] = i; @@ -221,20 +221,20 @@ lev_distance (char *s1, int len1, char *s2, int len2) } /* Calculate fuzzy hash for specified string */ -fuzzy_hash_t * -fuzzy_init (f_str_t *in, memory_pool_t *pool) +fuzzy_hash_t * +fuzzy_init (f_str_t * in, memory_pool_t * pool) { - fuzzy_hash_t *new; - int i, repeats = 0; - char *c = in->begin, last = '\0'; + fuzzy_hash_t *new; + int i, repeats = 0; + char *c = in->begin, last = '\0'; new = memory_pool_alloc0 (pool, sizeof (fuzzy_hash_t)); bzero (&rs, sizeof (rs)); new->block_size = fuzzy_blocksize (in->len); - - for (i = 0; i < in->len; i ++) { + + for (i = 0; i < in->len; i++) { if (*c == last) { - repeats ++; + repeats++; } else { repeats = 0; @@ -243,16 +243,16 @@ fuzzy_init (f_str_t *in, memory_pool_t *pool) fuzzy_update (new, *c); } last = *c; - c ++; + c++; } return new; } -fuzzy_hash_t * -fuzzy_init_byte_array (GByteArray *in, memory_pool_t *pool) +fuzzy_hash_t * +fuzzy_init_byte_array (GByteArray * in, memory_pool_t * pool) { - f_str_t f; + f_str_t f; f.begin = in->data; f.len = in->len; @@ -262,15 +262,15 @@ fuzzy_init_byte_array (GByteArray *in, memory_pool_t *pool) /* Compare score of difference between two hashes 0 - different hashes, 100 - identical hashes */ int -fuzzy_compare_hashes (fuzzy_hash_t *h1, fuzzy_hash_t *h2) +fuzzy_compare_hashes (fuzzy_hash_t * h1, fuzzy_hash_t * h2) { - int res, l1, l2; + int res, l1, l2; /* If we have hashes of different size, input strings are too different */ if (h1->block_size != h2->block_size) { return 0; } - + l1 = strlen (h1->hash_pipe); l2 = strlen (h2->hash_pipe); diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 3393dfdab..702c5b7c5 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -52,51 +52,51 @@ /* Number of insuccessfull bind retries */ #define MAX_RETRIES 40 -static GQueue *hashes[BUCKETS]; -static bloom_filter_t *bf; +static GQueue *hashes[BUCKETS]; +static bloom_filter_t *bf; /* Number of cache modifications */ -static uint32_t mods = 0; +static uint32_t mods = 0; /* For evtimer */ -static struct timeval tmv; -static struct event tev; +static struct timeval tmv; +static struct event tev; struct rspamd_fuzzy_node { - fuzzy_hash_t h; - uint64_t time; + fuzzy_hash_t h; + uint64_t time; }; -static void +static void sig_handler (int signo) -{ +{ switch (signo) { - case SIGINT: - /* Ignore SIGINT as we should got SIGTERM after it anyway */ - return; - case SIGTERM: + case SIGINT: + /* Ignore SIGINT as we should got SIGTERM after it anyway */ + return; + case SIGTERM: #ifdef WITH_PROFILER - exit (0); + exit (0); #else - _exit (1); + _exit (1); #endif - break; + break; } } static void sync_cache (struct rspamd_worker *wrk) { - int fd, i; - char *filename, *exp_str; - GList *cur, *tmp; - struct rspamd_fuzzy_node *node; - uint64_t expire, now; - + int fd, i; + char *filename, *exp_str; + GList *cur, *tmp; + struct rspamd_fuzzy_node *node; + uint64_t expire, now; + /* Check for modifications */ if (mods < MOD_LIMIT) { return; } - + msg_info ("sync_cache: syncing fuzzy hash storage"); filename = g_hash_table_lookup (wrk->cf->params, "hashfile"); if (filename == NULL) { @@ -114,9 +114,9 @@ sync_cache (struct rspamd_worker *wrk) msg_err ("sync_cache: cannot create hash file %s: %s", filename, strerror (errno)); return; } - - now = (uint64_t)time (NULL); - for (i = 0; i < BUCKETS; i ++) { + + now = (uint64_t) time (NULL); + for (i = 0; i < BUCKETS; i++) { cur = hashes[i]->head; while (cur) { node = cur->data; @@ -139,15 +139,15 @@ sync_cache (struct rspamd_worker *wrk) close (fd); } -static void +static void sigterm_handler (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; - static struct timeval tv = { + struct rspamd_worker *worker = (struct rspamd_worker *)arg; + static struct timeval tv = { .tv_sec = 0, .tv_usec = 0, }; - + mods = MOD_LIMIT + 1; sync_cache (worker); close (worker->cf->listen_sock); @@ -160,9 +160,9 @@ sigterm_handler (int fd, short what, void *arg) static void sigusr_handler (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct rspamd_worker *worker = (struct rspamd_worker *)arg; /* Do not accept new connections, preparing to end worker's process */ - struct timeval tv; + struct timeval tv; tv.tv_sec = SOFT_SHUTDOWN_TIME; tv.tv_usec = 0; event_del (&worker->sig_ev); @@ -174,15 +174,15 @@ sigusr_handler (int fd, short what, void *arg) return; } -static gboolean +static gboolean read_hashes_file (struct rspamd_worker *wrk) { - int r, fd, i; - struct stat st; - char *filename; - struct rspamd_fuzzy_node *node; + int r, fd, i; + struct stat st; + char *filename; + struct rspamd_fuzzy_node *node; - for (i = 0; i < BUCKETS; i ++) { + for (i = 0; i < BUCKETS; i++) { hashes[i] = g_queue_new (); } @@ -195,14 +195,14 @@ read_hashes_file (struct rspamd_worker *wrk) msg_err ("read_hashes_file: cannot open hash file %s: %s", filename, strerror (errno)); return FALSE; } - + fstat (fd, &st); - + for (;;) { node = g_malloc (sizeof (struct rspamd_fuzzy_node)); r = read (fd, node, sizeof (struct rspamd_fuzzy_node)); if (r != sizeof (struct rspamd_fuzzy_node)) { - break; + break; } g_queue_push_head (hashes[node->h.block_size % BUCKETS], node); bloom_add (bf, node->h.hash_pipe); @@ -219,16 +219,16 @@ read_hashes_file (struct rspamd_worker *wrk) return TRUE; } -static gboolean +static gboolean process_check_command (struct fuzzy_cmd *cmd) { - GList *cur; - struct rspamd_fuzzy_node *h; - fuzzy_hash_t s; - int prob = 0; - + GList *cur; + struct rspamd_fuzzy_node *h; + fuzzy_hash_t s; + int prob = 0; + if (!bloom_check (bf, cmd->hash)) { - return FALSE; + return FALSE; } memcpy (s.hash_pipe, cmd->hash, sizeof (s.hash_pipe)); @@ -249,39 +249,39 @@ process_check_command (struct fuzzy_cmd *cmd) return FALSE; } -static gboolean +static gboolean process_write_command (struct fuzzy_cmd *cmd) { - struct rspamd_fuzzy_node *h; + struct rspamd_fuzzy_node *h; if (bloom_check (bf, cmd->hash)) { - return FALSE; + return FALSE; } h = g_malloc (sizeof (struct rspamd_fuzzy_node)); memcpy (&h->h.hash_pipe, &cmd->hash, sizeof (cmd->hash)); h->h.block_size = cmd->blocksize; - h->time = (uint64_t)time (NULL); + h->time = (uint64_t) time (NULL); g_queue_push_head (hashes[cmd->blocksize % BUCKETS], h); bloom_add (bf, cmd->hash); - mods ++; + mods++; msg_info ("process_write_command: fuzzy hash was successfully added"); - + return TRUE; } -static gboolean +static gboolean process_delete_command (struct fuzzy_cmd *cmd) { - GList *cur, *tmp; - struct rspamd_fuzzy_node *h; - fuzzy_hash_t s; - gboolean res = FALSE; + GList *cur, *tmp; + struct rspamd_fuzzy_node *h; + fuzzy_hash_t s; + gboolean res = FALSE; if (!bloom_check (bf, cmd->hash)) { - return FALSE; + return FALSE; } - + memcpy (s.hash_pipe, cmd->hash, sizeof (s.hash_pipe)); s.block_size = cmd->blocksize; cur = hashes[cmd->blocksize % BUCKETS]->head; @@ -297,7 +297,7 @@ process_delete_command (struct fuzzy_cmd *cmd) bloom_del (bf, cmd->hash); msg_info ("process_delete_command: fuzzy hash was successfully deleted"); res = TRUE; - mods ++; + mods++; continue; } cur = g_list_next (cur); @@ -324,20 +324,20 @@ static void process_fuzzy_command (struct fuzzy_session *session) { switch (session->cmd.cmd) { - case FUZZY_CHECK: - CMD_PROCESS(check); - break; - case FUZZY_WRITE: - CMD_PROCESS(write); - break; - case FUZZY_DEL: - CMD_PROCESS(delete); - break; - default: - if (sendto (session->fd, "ERR" CRLF, sizeof ("ERR" CRLF) - 1, 0, (struct sockaddr *)&session->sa, session->salen) == -1) { - msg_err ("process_fuzzy_command: error while writing reply: %s", strerror (errno)); - } - break; + case FUZZY_CHECK: + CMD_PROCESS (check); + break; + case FUZZY_WRITE: + CMD_PROCESS (write); + break; + case FUZZY_DEL: + CMD_PROCESS (delete); + break; + default: + if (sendto (session->fd, "ERR" CRLF, sizeof ("ERR" CRLF) - 1, 0, (struct sockaddr *)&session->sa, session->salen) == -1) { + msg_err ("process_fuzzy_command: error while writing reply: %s", strerror (errno)); + } + break; } } @@ -350,14 +350,14 @@ process_fuzzy_command (struct fuzzy_session *session) static void accept_fuzzy_socket (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; - struct fuzzy_session session; - ssize_t r; - + struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct fuzzy_session session; + ssize_t r; + session.worker = worker; session.fd = fd; - session.pos = (u_char *)&session.cmd; + session.pos = (u_char *) & session.cmd; session.salen = sizeof (session.sa); /* Got some data */ @@ -375,13 +375,13 @@ accept_fuzzy_socket (int fd, short what, void *arg) return; } } -} +} static void sync_callback (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; - /* Timer event */ + struct rspamd_worker *worker = (struct rspamd_worker *)arg; + /* Timer event */ evtimer_set (&tev, sync_callback, worker); /* Plan event with jitter */ tmv.tv_sec = SYNC_TIMEOUT + SYNC_TIMEOUT * g_random_double (); @@ -397,9 +397,9 @@ sync_callback (int fd, short what, void *arg) void start_fuzzy_storage (struct rspamd_worker *worker) { - struct sigaction signals; - struct event sev; - int retries = 0; + struct sigaction signals; + struct event sev; + int retries = 0; worker->srv->pid = getpid (); worker->srv->type = TYPE_FUZZY; @@ -410,9 +410,9 @@ start_fuzzy_storage (struct rspamd_worker *worker) sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL); /* SIGUSR2 handler */ - signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *) worker); + signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *)worker); signal_add (&worker->sig_ev, NULL); - signal_set (&sev, SIGTERM, sigterm_handler, (void *) worker); + signal_set (&sev, SIGTERM, sigterm_handler, (void *)worker); signal_add (&sev, NULL); /* Send SIGUSR2 to parent */ @@ -424,7 +424,7 @@ start_fuzzy_storage (struct rspamd_worker *worker) if (!read_hashes_file (worker)) { msg_err ("read_hashes_file: cannot read hashes file, it can be created after save procedure"); } - /* Timer event */ + /* Timer event */ evtimer_set (&tev, sync_callback, worker); /* Plan event with jitter */ tmv.tv_sec = SYNC_TIMEOUT + SYNC_TIMEOUT * g_random_double (); @@ -439,12 +439,11 @@ start_fuzzy_storage (struct rspamd_worker *worker) exit (0); } } - event_set(&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_fuzzy_socket, (void *)worker); - event_add(&worker->bind_ev, NULL); + event_set (&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_fuzzy_socket, (void *)worker); + event_add (&worker->bind_ev, NULL); gperf_profiler_init (worker->srv->cfg, "fuzzy"); event_loop (0); exit (EXIT_SUCCESS); } - diff --git a/src/hash.c b/src/hash.c index ab9830d2d..a023bcbf4 100644 --- a/src/hash.c +++ b/src/hash.c @@ -33,11 +33,11 @@ * will use this function internally. */ static inline struct rspamd_hash_node ** -rspamd_hash_lookup_node (rspamd_hash_t *hash, gconstpointer key, guint *hash_return) +rspamd_hash_lookup_node (rspamd_hash_t * hash, gconstpointer key, guint * hash_return) { - struct rspamd_hash_node **node_ptr, *node; - guint hash_value; - hash_value = (* hash->hash_func) (key); + struct rspamd_hash_node **node_ptr, *node; + guint hash_value; + hash_value = (*hash->hash_func) (key); if (hash->shared) { memory_pool_rlock_rwlock (hash->lock); @@ -48,22 +48,23 @@ rspamd_hash_lookup_node (rspamd_hash_t *hash, gconstpointer key, guint *hash_re *hash_return = hash_value; /* Hash table lookup needs to be fast. - * We therefore remove the extra conditional of testing - * whether to call the key_equal_func or not from - * the inner loop. - * - * Additional optimisation: first check if our full hash - * values are equal so we can avoid calling the full-blown - * key equality function in most cases. - */ + * We therefore remove the extra conditional of testing + * whether to call the key_equal_func or not from + * the inner loop. + * + * Additional optimisation: first check if our full hash + * values are equal so we can avoid calling the full-blown + * key equality function in most cases. + */ if (hash->key_equal_func) { while ((node = *node_ptr)) { if (node->key_hash == hash_value && hash->key_equal_func (node->key, key)) { - break; + break; } node_ptr = &(*node_ptr)->next; } - } else { + } + else { while ((node = *node_ptr)) { if (node->key == key) { break; @@ -82,18 +83,18 @@ rspamd_hash_lookup_node (rspamd_hash_t *hash, gconstpointer key, guint *hash_re * No table resize is performed. */ static void -rspamd_hash_remove_node (rspamd_hash_t *hash, struct rspamd_hash_node ***node_ptr_ptr) +rspamd_hash_remove_node (rspamd_hash_t * hash, struct rspamd_hash_node ***node_ptr_ptr) { - struct rspamd_hash_node **node_ptr, *node; + struct rspamd_hash_node **node_ptr, *node; if (hash->shared) { memory_pool_wlock_rwlock (hash->lock); } node_ptr = *node_ptr_ptr; node = *node_ptr; - + *node_ptr = node->next; - + hash->nnodes--; if (hash->shared) { memory_pool_wunlock_rwlock (hash->lock); @@ -105,19 +106,20 @@ rspamd_hash_remove_node (rspamd_hash_t *hash, struct rspamd_hash_node ***node_pt * nodes currently held. */ static void -rspamd_hash_resize (rspamd_hash_t *hash) +rspamd_hash_resize (rspamd_hash_t * hash) { - struct rspamd_hash_node **new_nodes; - struct rspamd_hash_node *node, *next; - guint hash_val; - gint new_size, i; + struct rspamd_hash_node **new_nodes; + struct rspamd_hash_node *node, *next; + guint hash_val; + gint new_size, i; new_size = g_spaced_primes_closest (hash->nnodes); new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE); - + if (hash->shared) { new_nodes = memory_pool_alloc_shared (hash->pool, sizeof (struct rspamd_hash_node *) * new_size); - } else { + } + else { new_nodes = memory_pool_alloc (hash->pool, sizeof (struct rspamd_hash_node *) * new_size); } @@ -146,68 +148,67 @@ rspamd_hash_resize (rspamd_hash_t *hash) * Resizes the hash table, if needed. */ static inline void -rspamd_hash_maybe_resize (rspamd_hash_t *hash) +rspamd_hash_maybe_resize (rspamd_hash_t * hash) { - gint nnodes = hash->nnodes; - gint size = hash->size; - - if ((size >= 3 * nnodes && size > HASH_TABLE_MIN_SIZE) || - (3 * size <= nnodes && size < HASH_TABLE_MAX_SIZE)) { + gint nnodes = hash->nnodes; + gint size = hash->size; + + if ((size >= 3 * nnodes && size > HASH_TABLE_MIN_SIZE) || (3 * size <= nnodes && size < HASH_TABLE_MAX_SIZE)) { rspamd_hash_resize (hash); } } /* Create new hash in specified pool */ -rspamd_hash_t* -rspamd_hash_new (memory_pool_t *pool, GHashFunc hash_func, GEqualFunc key_equal_func) +rspamd_hash_t * +rspamd_hash_new (memory_pool_t * pool, GHashFunc hash_func, GEqualFunc key_equal_func) { - rspamd_hash_t* hash; + rspamd_hash_t *hash; hash = memory_pool_alloc (pool, sizeof (rspamd_hash_t)); - hash->size = HASH_TABLE_MIN_SIZE; - hash->nnodes = 0; - hash->hash_func = hash_func ? hash_func : g_direct_hash; - hash->key_equal_func = key_equal_func; - hash->nodes = memory_pool_alloc0 (pool, sizeof (struct rspamd_hash_node*) * hash->size); - hash->shared = 0; - hash->pool = pool; - + hash->size = HASH_TABLE_MIN_SIZE; + hash->nnodes = 0; + hash->hash_func = hash_func ? hash_func : g_direct_hash; + hash->key_equal_func = key_equal_func; + hash->nodes = memory_pool_alloc0 (pool, sizeof (struct rspamd_hash_node *) * hash->size); + hash->shared = 0; + hash->pool = pool; + return hash; } /* * Create new hash in specified pool using shared memory */ -rspamd_hash_t* -rspamd_hash_new_shared (memory_pool_t *pool, GHashFunc hash_func, GEqualFunc key_equal_func, gint size) +rspamd_hash_t * +rspamd_hash_new_shared (memory_pool_t * pool, GHashFunc hash_func, GEqualFunc key_equal_func, gint size) { - rspamd_hash_t* hash; + rspamd_hash_t *hash; hash = memory_pool_alloc_shared (pool, sizeof (rspamd_hash_t)); - hash->size = size; - hash->nnodes = 0; - hash->hash_func = hash_func ? hash_func : g_direct_hash; - hash->key_equal_func = key_equal_func; - hash->nodes = memory_pool_alloc0_shared (pool, sizeof (struct rspamd_hash_node*) * hash->size); - hash->shared = 1; + hash->size = size; + hash->nnodes = 0; + hash->hash_func = hash_func ? hash_func : g_direct_hash; + hash->key_equal_func = key_equal_func; + hash->nodes = memory_pool_alloc0_shared (pool, sizeof (struct rspamd_hash_node *) * hash->size); + hash->shared = 1; /* Get mutex from pool for locking on insert/remove operations */ - hash->lock = memory_pool_get_rwlock (pool); - hash->pool = pool; - + hash->lock = memory_pool_get_rwlock (pool); + hash->pool = pool; + return hash; } /* * Insert item in hash */ -void -rspamd_hash_insert (rspamd_hash_t *hash, gpointer key, gpointer value) +void +rspamd_hash_insert (rspamd_hash_t * hash, gpointer key, gpointer value) { - struct rspamd_hash_node **node_ptr, *node; - guint key_hash; + struct rspamd_hash_node **node_ptr, *node; + guint key_hash; g_return_if_fail (hash != NULL); - node_ptr = rspamd_hash_lookup_node (hash, key, &key_hash); + node_ptr = rspamd_hash_lookup_node (hash, key, &key_hash); if (hash->shared) { memory_pool_wlock_rwlock (hash->lock); @@ -223,19 +224,19 @@ rspamd_hash_insert (rspamd_hash_t *hash, gpointer key, gpointer value) else { node = memory_pool_alloc (hash->pool, sizeof (struct rspamd_hash_node)); } - + node->key = key; node->value = value; node->key_hash = key_hash; node->next = NULL; - + *node_ptr = node; - hash->nnodes ++; - } + hash->nnodes++; + } if (hash->shared) { memory_pool_wunlock_rwlock (hash->lock); } - + if (!hash->shared) { rspamd_hash_maybe_resize (hash); } @@ -244,10 +245,10 @@ rspamd_hash_insert (rspamd_hash_t *hash, gpointer key, gpointer value) /* * Remove item from hash */ -gboolean -rspamd_hash_remove (rspamd_hash_t *hash, gpointer key) +gboolean +rspamd_hash_remove (rspamd_hash_t * hash, gpointer key) { - struct rspamd_hash_node **node_ptr; + struct rspamd_hash_node **node_ptr; g_return_val_if_fail (hash != NULL, FALSE); @@ -264,26 +265,26 @@ rspamd_hash_remove (rspamd_hash_t *hash, gpointer key) /* * Lookup item from hash */ -gpointer -rspamd_hash_lookup (rspamd_hash_t *hash, gpointer key) +gpointer +rspamd_hash_lookup (rspamd_hash_t * hash, gpointer key) { - struct rspamd_hash_node *node; + struct rspamd_hash_node *node; g_return_val_if_fail (hash != NULL, NULL); - + node = *rspamd_hash_lookup_node (hash, key, NULL); - + return node ? node->value : NULL; } /* * Iterate throught hash */ -void -rspamd_hash_foreach (rspamd_hash_t *hash, GHFunc func, gpointer user_data) +void +rspamd_hash_foreach (rspamd_hash_t * hash, GHFunc func, gpointer user_data) { - struct rspamd_hash_node *node; - gint i; - + struct rspamd_hash_node *node; + gint i; + g_return_if_fail (hash != NULL); g_return_if_fail (func != NULL); @@ -292,7 +293,7 @@ rspamd_hash_foreach (rspamd_hash_t *hash, GHFunc func, gpointer user_data) } for (i = 0; i < hash->size; i++) { for (node = hash->nodes[i]; node; node = node->next) { - (* func) (node->key, node->value, user_data); + (*func) (node->key, node->value, user_data); } } if (hash->shared) { diff --git a/src/html.c b/src/html.c index d216b751a..b77e21bf1 100644 --- a/src/html.c +++ b/src/html.c @@ -29,423 +29,420 @@ #include "html.h" #include "url.h" -sig_atomic_t tags_sorted = 0; - -static struct html_tag tag_defs[] = -{ - /* W3C defined elements */ - { Tag_A, "a", (CM_INLINE)}, - { Tag_ABBR, "abbr", (CM_INLINE)}, - { Tag_ACRONYM, "acronym", (CM_INLINE)}, - { Tag_ADDRESS, "address", (CM_BLOCK)}, - { Tag_APPLET, "applet", (CM_OBJECT|CM_IMG|CM_INLINE|CM_PARAM)}, - { Tag_AREA, "area", (CM_BLOCK|CM_EMPTY)}, - { Tag_B, "b", (CM_INLINE)}, - { Tag_BASE, "base", (CM_HEAD|CM_EMPTY)}, - { Tag_BASEFONT, "basefont", (CM_INLINE|CM_EMPTY)}, - { Tag_BDO, "bdo", (CM_INLINE)}, - { Tag_BIG, "big", (CM_INLINE)}, - { Tag_BLOCKQUOTE, "blockquote", (CM_BLOCK)}, - { Tag_BODY, "body", (CM_HTML|CM_OPT|CM_OMITST)}, - { Tag_BR, "br", (CM_INLINE|CM_EMPTY)}, - { Tag_BUTTON, "button", (CM_INLINE)}, - { Tag_CAPTION, "caption", (CM_TABLE)}, - { Tag_CENTER, "center", (CM_BLOCK)}, - { Tag_CITE, "cite", (CM_INLINE)}, - { Tag_CODE, "code", (CM_INLINE)}, - { Tag_COL, "col", (CM_TABLE|CM_EMPTY)}, - { Tag_COLGROUP, "colgroup", (CM_TABLE|CM_OPT)}, - { Tag_DD, "dd", (CM_DEFLIST|CM_OPT|CM_NO_INDENT)}, - { Tag_DEL, "del", (CM_INLINE|CM_BLOCK|CM_MIXED)}, - { Tag_DFN, "dfn", (CM_INLINE)}, - { Tag_DIR, "dir", (CM_BLOCK|CM_OBSOLETE)}, - { Tag_DIV, "div", (CM_BLOCK)}, - { Tag_DL, "dl", (CM_BLOCK)}, - { Tag_DT, "dt", (CM_DEFLIST|CM_OPT|CM_NO_INDENT)}, - { Tag_EM, "em", (CM_INLINE)}, - { Tag_FIELDSET, "fieldset", (CM_BLOCK)}, - { Tag_FONT, "font", (CM_INLINE)}, - { Tag_FORM, "form", (CM_BLOCK)}, - { Tag_FRAME, "frame", (CM_FRAMES|CM_EMPTY)}, - { Tag_FRAMESET, "frameset", (CM_HTML|CM_FRAMES)}, - { Tag_H1, "h1", (CM_BLOCK|CM_HEADING)}, - { Tag_H2, "h2", (CM_BLOCK|CM_HEADING)}, - { Tag_H3, "h3", (CM_BLOCK|CM_HEADING)}, - { Tag_H4, "h4", (CM_BLOCK|CM_HEADING)}, - { Tag_H5, "h5", (CM_BLOCK|CM_HEADING)}, - { Tag_H6, "h6", (CM_BLOCK|CM_HEADING)}, - { Tag_HEAD, "head", (CM_HTML|CM_OPT|CM_OMITST)}, - { Tag_HR, "hr", (CM_BLOCK|CM_EMPTY)}, - { Tag_HTML, "html", (CM_HTML|CM_OPT|CM_OMITST)}, - { Tag_I, "i", (CM_INLINE)}, - { Tag_IFRAME, "iframe", (CM_INLINE)}, - { Tag_IMG, "img", (CM_INLINE|CM_IMG|CM_EMPTY)}, - { Tag_INPUT, "input", (CM_INLINE|CM_IMG|CM_EMPTY)}, - { Tag_INS, "ins", (CM_INLINE|CM_BLOCK|CM_MIXED)}, - { Tag_ISINDEX, "isindex", (CM_BLOCK|CM_EMPTY)}, - { Tag_KBD, "kbd", (CM_INLINE)}, - { Tag_LABEL, "label", (CM_INLINE)}, - { Tag_LEGEND, "legend", (CM_INLINE)}, - { Tag_LI, "li", (CM_LIST|CM_OPT|CM_NO_INDENT)}, - { Tag_LINK, "link", (CM_HEAD|CM_EMPTY)}, - { Tag_LISTING, "listing", (CM_BLOCK|CM_OBSOLETE)}, - { Tag_MAP, "map", (CM_INLINE)}, - { Tag_MENU, "menu", (CM_BLOCK|CM_OBSOLETE)}, - { Tag_META, "meta", (CM_HEAD|CM_EMPTY)}, - { Tag_NOFRAMES, "noframes", (CM_BLOCK|CM_FRAMES)}, - { Tag_NOSCRIPT, "noscript", (CM_BLOCK|CM_INLINE|CM_MIXED)}, - { Tag_OBJECT, "object", (CM_OBJECT|CM_HEAD|CM_IMG|CM_INLINE|CM_PARAM)}, - { Tag_OL, "ol", (CM_BLOCK)}, - { Tag_OPTGROUP, "optgroup", (CM_FIELD|CM_OPT)}, - { Tag_OPTION, "option", (CM_FIELD|CM_OPT)}, - { Tag_P, "p", (CM_BLOCK|CM_OPT)}, - { Tag_PARAM, "param", (CM_INLINE|CM_EMPTY)}, - { Tag_PLAINTEXT, "plaintext", (CM_BLOCK|CM_OBSOLETE)}, - { Tag_PRE, "pre", (CM_BLOCK)}, - { Tag_Q, "q", (CM_INLINE)}, - { Tag_RB, "rb", (CM_INLINE)}, - { Tag_RBC, "rbc", (CM_INLINE)}, - { Tag_RP, "rp", (CM_INLINE)}, - { Tag_RT, "rt", (CM_INLINE)}, - { Tag_RTC, "rtc", (CM_INLINE)}, - { Tag_RUBY, "ruby", (CM_INLINE)}, - { Tag_S, "s", (CM_INLINE)}, - { Tag_SAMP, "samp", (CM_INLINE)}, - { Tag_SCRIPT, "script", (CM_HEAD|CM_MIXED|CM_BLOCK|CM_INLINE)}, - { Tag_SELECT, "select", (CM_INLINE|CM_FIELD)}, - { Tag_SMALL, "small", (CM_INLINE)}, - { Tag_SPAN, "span", (CM_INLINE)}, - { Tag_STRIKE, "strike", (CM_INLINE)}, - { Tag_STRONG, "strong", (CM_INLINE)}, - { Tag_STYLE, "style", (CM_HEAD)}, - { Tag_SUB, "sub", (CM_INLINE)}, - { Tag_SUP, "sup", (CM_INLINE)}, - { Tag_TABLE, "table", (CM_BLOCK)}, - { Tag_TBODY, "tbody", (CM_TABLE|CM_ROWGRP|CM_OPT)}, - { Tag_TD, "td", (CM_ROW|CM_OPT|CM_NO_INDENT)}, - { Tag_TEXTAREA, "textarea", (CM_INLINE|CM_FIELD)}, - { Tag_TFOOT, "tfoot", (CM_TABLE|CM_ROWGRP|CM_OPT)}, - { Tag_TH, "th", (CM_ROW|CM_OPT|CM_NO_INDENT)}, - { Tag_THEAD, "thead", (CM_TABLE|CM_ROWGRP|CM_OPT)}, - { Tag_TITLE, "title", (CM_HEAD)}, - { Tag_TR, "tr", (CM_TABLE|CM_OPT)}, - { Tag_TT, "tt", (CM_INLINE)}, - { Tag_U, "u", (CM_INLINE)}, - { Tag_UL, "ul", (CM_BLOCK)}, - { Tag_VAR, "var", (CM_INLINE)}, - { Tag_XMP, "xmp", (CM_BLOCK|CM_OBSOLETE)}, - { Tag_NEXTID, "nextid", (CM_HEAD|CM_EMPTY)}, - - /* proprietary elements */ - { Tag_ALIGN, "align", (CM_BLOCK)}, - { Tag_BGSOUND, "bgsound", (CM_HEAD|CM_EMPTY)}, - { Tag_BLINK, "blink", (CM_INLINE)}, - { Tag_COMMENT, "comment", (CM_INLINE)}, - { Tag_EMBED, "embed", (CM_INLINE|CM_IMG|CM_EMPTY)}, - { Tag_ILAYER, "ilayer", (CM_INLINE)}, - { Tag_KEYGEN, "keygen", (CM_INLINE|CM_EMPTY)}, - { Tag_LAYER, "layer", (CM_BLOCK)}, - { Tag_MARQUEE, "marquee", (CM_INLINE|CM_OPT)}, - { Tag_MULTICOL, "multicol", (CM_BLOCK)}, - { Tag_NOBR, "nobr", (CM_INLINE)}, - { Tag_NOEMBED, "noembed", (CM_INLINE)}, - { Tag_NOLAYER, "nolayer", (CM_BLOCK|CM_INLINE|CM_MIXED)}, - { Tag_NOSAVE, "nosave", (CM_BLOCK)}, - { Tag_SERVER, "server", (CM_HEAD|CM_MIXED|CM_BLOCK|CM_INLINE)}, - { Tag_SERVLET, "servlet", (CM_OBJECT|CM_IMG|CM_INLINE|CM_PARAM)}, - { Tag_SPACER, "spacer", (CM_INLINE|CM_EMPTY)}, - { Tag_WBR, "wbr", (CM_INLINE|CM_EMPTY)}, +sig_atomic_t tags_sorted = 0; + +static struct html_tag tag_defs[] = { + /* W3C defined elements */ + {Tag_A, "a", (CM_INLINE)}, + {Tag_ABBR, "abbr", (CM_INLINE)}, + {Tag_ACRONYM, "acronym", (CM_INLINE)}, + {Tag_ADDRESS, "address", (CM_BLOCK)}, + {Tag_APPLET, "applet", (CM_OBJECT | CM_IMG | CM_INLINE | CM_PARAM)}, + {Tag_AREA, "area", (CM_BLOCK | CM_EMPTY)}, + {Tag_B, "b", (CM_INLINE)}, + {Tag_BASE, "base", (CM_HEAD | CM_EMPTY)}, + {Tag_BASEFONT, "basefont", (CM_INLINE | CM_EMPTY)}, + {Tag_BDO, "bdo", (CM_INLINE)}, + {Tag_BIG, "big", (CM_INLINE)}, + {Tag_BLOCKQUOTE, "blockquote", (CM_BLOCK)}, + {Tag_BODY, "body", (CM_HTML | CM_OPT | CM_OMITST)}, + {Tag_BR, "br", (CM_INLINE | CM_EMPTY)}, + {Tag_BUTTON, "button", (CM_INLINE)}, + {Tag_CAPTION, "caption", (CM_TABLE)}, + {Tag_CENTER, "center", (CM_BLOCK)}, + {Tag_CITE, "cite", (CM_INLINE)}, + {Tag_CODE, "code", (CM_INLINE)}, + {Tag_COL, "col", (CM_TABLE | CM_EMPTY)}, + {Tag_COLGROUP, "colgroup", (CM_TABLE | CM_OPT)}, + {Tag_DD, "dd", (CM_DEFLIST | CM_OPT | CM_NO_INDENT)}, + {Tag_DEL, "del", (CM_INLINE | CM_BLOCK | CM_MIXED)}, + {Tag_DFN, "dfn", (CM_INLINE)}, + {Tag_DIR, "dir", (CM_BLOCK | CM_OBSOLETE)}, + {Tag_DIV, "div", (CM_BLOCK)}, + {Tag_DL, "dl", (CM_BLOCK)}, + {Tag_DT, "dt", (CM_DEFLIST | CM_OPT | CM_NO_INDENT)}, + {Tag_EM, "em", (CM_INLINE)}, + {Tag_FIELDSET, "fieldset", (CM_BLOCK)}, + {Tag_FONT, "font", (CM_INLINE)}, + {Tag_FORM, "form", (CM_BLOCK)}, + {Tag_FRAME, "frame", (CM_FRAMES | CM_EMPTY)}, + {Tag_FRAMESET, "frameset", (CM_HTML | CM_FRAMES)}, + {Tag_H1, "h1", (CM_BLOCK | CM_HEADING)}, + {Tag_H2, "h2", (CM_BLOCK | CM_HEADING)}, + {Tag_H3, "h3", (CM_BLOCK | CM_HEADING)}, + {Tag_H4, "h4", (CM_BLOCK | CM_HEADING)}, + {Tag_H5, "h5", (CM_BLOCK | CM_HEADING)}, + {Tag_H6, "h6", (CM_BLOCK | CM_HEADING)}, + {Tag_HEAD, "head", (CM_HTML | CM_OPT | CM_OMITST)}, + {Tag_HR, "hr", (CM_BLOCK | CM_EMPTY)}, + {Tag_HTML, "html", (CM_HTML | CM_OPT | CM_OMITST)}, + {Tag_I, "i", (CM_INLINE)}, + {Tag_IFRAME, "iframe", (CM_INLINE)}, + {Tag_IMG, "img", (CM_INLINE | CM_IMG | CM_EMPTY)}, + {Tag_INPUT, "input", (CM_INLINE | CM_IMG | CM_EMPTY)}, + {Tag_INS, "ins", (CM_INLINE | CM_BLOCK | CM_MIXED)}, + {Tag_ISINDEX, "isindex", (CM_BLOCK | CM_EMPTY)}, + {Tag_KBD, "kbd", (CM_INLINE)}, + {Tag_LABEL, "label", (CM_INLINE)}, + {Tag_LEGEND, "legend", (CM_INLINE)}, + {Tag_LI, "li", (CM_LIST | CM_OPT | CM_NO_INDENT)}, + {Tag_LINK, "link", (CM_HEAD | CM_EMPTY)}, + {Tag_LISTING, "listing", (CM_BLOCK | CM_OBSOLETE)}, + {Tag_MAP, "map", (CM_INLINE)}, + {Tag_MENU, "menu", (CM_BLOCK | CM_OBSOLETE)}, + {Tag_META, "meta", (CM_HEAD | CM_EMPTY)}, + {Tag_NOFRAMES, "noframes", (CM_BLOCK | CM_FRAMES)}, + {Tag_NOSCRIPT, "noscript", (CM_BLOCK | CM_INLINE | CM_MIXED)}, + {Tag_OBJECT, "object", (CM_OBJECT | CM_HEAD | CM_IMG | CM_INLINE | CM_PARAM)}, + {Tag_OL, "ol", (CM_BLOCK)}, + {Tag_OPTGROUP, "optgroup", (CM_FIELD | CM_OPT)}, + {Tag_OPTION, "option", (CM_FIELD | CM_OPT)}, + {Tag_P, "p", (CM_BLOCK | CM_OPT)}, + {Tag_PARAM, "param", (CM_INLINE | CM_EMPTY)}, + {Tag_PLAINTEXT, "plaintext", (CM_BLOCK | CM_OBSOLETE)}, + {Tag_PRE, "pre", (CM_BLOCK)}, + {Tag_Q, "q", (CM_INLINE)}, + {Tag_RB, "rb", (CM_INLINE)}, + {Tag_RBC, "rbc", (CM_INLINE)}, + {Tag_RP, "rp", (CM_INLINE)}, + {Tag_RT, "rt", (CM_INLINE)}, + {Tag_RTC, "rtc", (CM_INLINE)}, + {Tag_RUBY, "ruby", (CM_INLINE)}, + {Tag_S, "s", (CM_INLINE)}, + {Tag_SAMP, "samp", (CM_INLINE)}, + {Tag_SCRIPT, "script", (CM_HEAD | CM_MIXED | CM_BLOCK | CM_INLINE)}, + {Tag_SELECT, "select", (CM_INLINE | CM_FIELD)}, + {Tag_SMALL, "small", (CM_INLINE)}, + {Tag_SPAN, "span", (CM_INLINE)}, + {Tag_STRIKE, "strike", (CM_INLINE)}, + {Tag_STRONG, "strong", (CM_INLINE)}, + {Tag_STYLE, "style", (CM_HEAD)}, + {Tag_SUB, "sub", (CM_INLINE)}, + {Tag_SUP, "sup", (CM_INLINE)}, + {Tag_TABLE, "table", (CM_BLOCK)}, + {Tag_TBODY, "tbody", (CM_TABLE | CM_ROWGRP | CM_OPT)}, + {Tag_TD, "td", (CM_ROW | CM_OPT | CM_NO_INDENT)}, + {Tag_TEXTAREA, "textarea", (CM_INLINE | CM_FIELD)}, + {Tag_TFOOT, "tfoot", (CM_TABLE | CM_ROWGRP | CM_OPT)}, + {Tag_TH, "th", (CM_ROW | CM_OPT | CM_NO_INDENT)}, + {Tag_THEAD, "thead", (CM_TABLE | CM_ROWGRP | CM_OPT)}, + {Tag_TITLE, "title", (CM_HEAD)}, + {Tag_TR, "tr", (CM_TABLE | CM_OPT)}, + {Tag_TT, "tt", (CM_INLINE)}, + {Tag_U, "u", (CM_INLINE)}, + {Tag_UL, "ul", (CM_BLOCK)}, + {Tag_VAR, "var", (CM_INLINE)}, + {Tag_XMP, "xmp", (CM_BLOCK | CM_OBSOLETE)}, + {Tag_NEXTID, "nextid", (CM_HEAD | CM_EMPTY)}, + + /* proprietary elements */ + {Tag_ALIGN, "align", (CM_BLOCK)}, + {Tag_BGSOUND, "bgsound", (CM_HEAD | CM_EMPTY)}, + {Tag_BLINK, "blink", (CM_INLINE)}, + {Tag_COMMENT, "comment", (CM_INLINE)}, + {Tag_EMBED, "embed", (CM_INLINE | CM_IMG | CM_EMPTY)}, + {Tag_ILAYER, "ilayer", (CM_INLINE)}, + {Tag_KEYGEN, "keygen", (CM_INLINE | CM_EMPTY)}, + {Tag_LAYER, "layer", (CM_BLOCK)}, + {Tag_MARQUEE, "marquee", (CM_INLINE | CM_OPT)}, + {Tag_MULTICOL, "multicol", (CM_BLOCK)}, + {Tag_NOBR, "nobr", (CM_INLINE)}, + {Tag_NOEMBED, "noembed", (CM_INLINE)}, + {Tag_NOLAYER, "nolayer", (CM_BLOCK | CM_INLINE | CM_MIXED)}, + {Tag_NOSAVE, "nosave", (CM_BLOCK)}, + {Tag_SERVER, "server", (CM_HEAD | CM_MIXED | CM_BLOCK | CM_INLINE)}, + {Tag_SERVLET, "servlet", (CM_OBJECT | CM_IMG | CM_INLINE | CM_PARAM)}, + {Tag_SPACER, "spacer", (CM_INLINE | CM_EMPTY)}, + {Tag_WBR, "wbr", (CM_INLINE | CM_EMPTY)}, }; -sig_atomic_t entities_sorted = 0; +sig_atomic_t entities_sorted = 0; struct _entity; -typedef struct _entity entity; +typedef struct _entity entity; -struct _entity -{ - char *name; - uint code; +struct _entity { + char *name; + uint code; }; -static entity entities_defs[] = -{ - /* - ** Markup pre-defined character entities - */ - { "quot", 34 }, - { "amp", 38 }, - { "apos", 39 }, - { "lt", 60 }, - { "gt", 62 }, - - /* - ** Latin-1 character entities - */ - { "nbsp", 160 }, - { "iexcl", 161 }, - { "cent", 162 }, - { "pound", 163 }, - { "curren", 164 }, - { "yen", 165 }, - { "brvbar", 166 }, - { "sect", 167 }, - { "uml", 168 }, - { "copy", 169 }, - { "ordf", 170 }, - { "laquo", 171 }, - { "not", 172 }, - { "shy", 173 }, - { "reg", 174 }, - { "macr", 175 }, - { "deg", 176 }, - { "plusmn", 177 }, - { "sup2", 178 }, - { "sup3", 179 }, - { "acute", 180 }, - { "micro", 181 }, - { "para", 182 }, - { "middot", 183 }, - { "cedil", 184 }, - { "sup1", 185 }, - { "ordm", 186 }, - { "raquo", 187 }, - { "frac14", 188 }, - { "frac12", 189 }, - { "frac34", 190 }, - { "iquest", 191 }, - { "Agrave", 192 }, - { "Aacute", 193 }, - { "Acirc", 194 }, - { "Atilde", 195 }, - { "Auml", 196 }, - { "Aring", 197 }, - { "AElig", 198 }, - { "Ccedil", 199 }, - { "Egrave", 200 }, - { "Eacute", 201 }, - { "Ecirc", 202 }, - { "Euml", 203 }, - { "Igrave", 204 }, - { "Iacute", 205 }, - { "Icirc", 206 }, - { "Iuml", 207 }, - { "ETH", 208 }, - { "Ntilde", 209 }, - { "Ograve", 210 }, - { "Oacute", 211 }, - { "Ocirc", 212 }, - { "Otilde", 213 }, - { "Ouml", 214 }, - { "times", 215 }, - { "Oslash", 216 }, - { "Ugrave", 217 }, - { "Uacute", 218 }, - { "Ucirc", 219 }, - { "Uuml", 220 }, - { "Yacute", 221 }, - { "THORN", 222 }, - { "szlig", 223 }, - { "agrave", 224 }, - { "aacute", 225 }, - { "acirc", 226 }, - { "atilde", 227 }, - { "auml", 228 }, - { "aring", 229 }, - { "aelig", 230 }, - { "ccedil", 231 }, - { "egrave", 232 }, - { "eacute", 233 }, - { "ecirc", 234 }, - { "euml", 235 }, - { "igrave", 236 }, - { "iacute", 237 }, - { "icirc", 238 }, - { "iuml", 239 }, - { "eth", 240 }, - { "ntilde", 241 }, - { "ograve", 242 }, - { "oacute", 243 }, - { "ocirc", 244 }, - { "otilde", 245 }, - { "ouml", 246 }, - { "divide", 247 }, - { "oslash", 248 }, - { "ugrave", 249 }, - { "uacute", 250 }, - { "ucirc", 251 }, - { "uuml", 252 }, - { "yacute", 253 }, - { "thorn", 254 }, - { "yuml", 255 }, - - /* - ** Extended Entities defined in HTML 4: Symbols - */ - { "fnof", 402 }, - { "Alpha", 913 }, - { "Beta", 914 }, - { "Gamma", 915 }, - { "Delta", 916 }, - { "Epsilon", 917 }, - { "Zeta", 918 }, - { "Eta", 919 }, - { "Theta", 920 }, - { "Iota", 921 }, - { "Kappa", 922 }, - { "Lambda", 923 }, - { "Mu", 924 }, - { "Nu", 925 }, - { "Xi", 926 }, - { "Omicron", 927 }, - { "Pi", 928 }, - { "Rho", 929 }, - { "Sigma", 931 }, - { "Tau", 932 }, - { "Upsilon", 933 }, - { "Phi", 934 }, - { "Chi", 935 }, - { "Psi", 936 }, - { "Omega", 937 }, - { "alpha", 945 }, - { "beta", 946 }, - { "gamma", 947 }, - { "delta", 948 }, - { "epsilon", 949 }, - { "zeta", 950 }, - { "eta", 951 }, - { "theta", 952 }, - { "iota", 953 }, - { "kappa", 954 }, - { "lambda", 955 }, - { "mu", 956 }, - { "nu", 957 }, - { "xi", 958 }, - { "omicron", 959 }, - { "pi", 960 }, - { "rho", 961 }, - { "sigmaf", 962 }, - { "sigma", 963 }, - { "tau", 964 }, - { "upsilon", 965 }, - { "phi", 966 }, - { "chi", 967 }, - { "psi", 968 }, - { "omega", 969 }, - { "thetasym", 977 }, - { "upsih", 978 }, - { "piv", 982 }, - { "bull", 8226 }, - { "hellip", 8230 }, - { "prime", 8242 }, - { "Prime", 8243 }, - { "oline", 8254 }, - { "frasl", 8260 }, - { "weierp", 8472 }, - { "image", 8465 }, - { "real", 8476 }, - { "trade", 8482 }, - { "alefsym", 8501 }, - { "larr", 8592 }, - { "uarr", 8593 }, - { "rarr", 8594 }, - { "darr", 8595 }, - { "harr", 8596 }, - { "crarr", 8629 }, - { "lArr", 8656 }, - { "uArr", 8657 }, - { "rArr", 8658 }, - { "dArr", 8659 }, - { "hArr", 8660 }, - { "forall", 8704 }, - { "part", 8706 }, - { "exist", 8707 }, - { "empty", 8709 }, - { "nabla", 8711 }, - { "isin", 8712 }, - { "notin", 8713 }, - { "ni", 8715 }, - { "prod", 8719 }, - { "sum", 8721 }, - { "minus", 8722 }, - { "lowast", 8727 }, - { "radic", 8730 }, - { "prop", 8733 }, - { "infin", 8734 }, - { "ang", 8736 }, - { "and", 8743 }, - { "or", 8744 }, - { "cap", 8745 }, - { "cup", 8746 }, - { "int", 8747 }, - { "there4", 8756 }, - { "sim", 8764 }, - { "cong", 8773 }, - { "asymp", 8776 }, - { "ne", 8800 }, - { "equiv", 8801 }, - { "le", 8804 }, - { "ge", 8805 }, - { "sub", 8834 }, - { "sup", 8835 }, - { "nsub", 8836 }, - { "sube", 8838 }, - { "supe", 8839 }, - { "oplus", 8853 }, - { "otimes", 8855 }, - { "perp", 8869 }, - { "sdot", 8901 }, - { "lceil", 8968 }, - { "rceil", 8969 }, - { "lfloor", 8970 }, - { "rfloor", 8971 }, - { "lang", 9001 }, - { "rang", 9002 }, - { "loz", 9674 }, - { "spades", 9824 }, - { "clubs", 9827 }, - { "hearts", 9829 }, - { "diams", 9830 }, - - /* - ** Extended Entities defined in HTML 4: Special (less Markup at top) - */ - { "OElig", 338 }, - { "oelig", 339 }, - { "Scaron", 352 }, - { "scaron", 353 }, - { "Yuml", 376 }, - { "circ", 710 }, - { "tilde", 732 }, - { "ensp", 8194 }, - { "emsp", 8195 }, - { "thinsp", 8201 }, - { "zwnj", 8204 }, - { "zwj", 8205 }, - { "lrm", 8206 }, - { "rlm", 8207 }, - { "ndash", 8211 }, - { "mdash", 8212 }, - { "lsquo", 8216 }, - { "rsquo", 8217 }, - { "sbquo", 8218 }, - { "ldquo", 8220 }, - { "rdquo", 8221 }, - { "bdquo", 8222 }, - { "dagger", 8224 }, - { "Dagger", 8225 }, - { "permil", 8240 }, - { "lsaquo", 8249 }, - { "rsaquo", 8250 }, - { "euro", 8364 }, +static entity entities_defs[] = { + /* + ** Markup pre-defined character entities + */ + {"quot", 34}, + {"amp", 38}, + {"apos", 39}, + {"lt", 60}, + {"gt", 62}, + + /* + ** Latin-1 character entities + */ + {"nbsp", 160}, + {"iexcl", 161}, + {"cent", 162}, + {"pound", 163}, + {"curren", 164}, + {"yen", 165}, + {"brvbar", 166}, + {"sect", 167}, + {"uml", 168}, + {"copy", 169}, + {"ordf", 170}, + {"laquo", 171}, + {"not", 172}, + {"shy", 173}, + {"reg", 174}, + {"macr", 175}, + {"deg", 176}, + {"plusmn", 177}, + {"sup2", 178}, + {"sup3", 179}, + {"acute", 180}, + {"micro", 181}, + {"para", 182}, + {"middot", 183}, + {"cedil", 184}, + {"sup1", 185}, + {"ordm", 186}, + {"raquo", 187}, + {"frac14", 188}, + {"frac12", 189}, + {"frac34", 190}, + {"iquest", 191}, + {"Agrave", 192}, + {"Aacute", 193}, + {"Acirc", 194}, + {"Atilde", 195}, + {"Auml", 196}, + {"Aring", 197}, + {"AElig", 198}, + {"Ccedil", 199}, + {"Egrave", 200}, + {"Eacute", 201}, + {"Ecirc", 202}, + {"Euml", 203}, + {"Igrave", 204}, + {"Iacute", 205}, + {"Icirc", 206}, + {"Iuml", 207}, + {"ETH", 208}, + {"Ntilde", 209}, + {"Ograve", 210}, + {"Oacute", 211}, + {"Ocirc", 212}, + {"Otilde", 213}, + {"Ouml", 214}, + {"times", 215}, + {"Oslash", 216}, + {"Ugrave", 217}, + {"Uacute", 218}, + {"Ucirc", 219}, + {"Uuml", 220}, + {"Yacute", 221}, + {"THORN", 222}, + {"szlig", 223}, + {"agrave", 224}, + {"aacute", 225}, + {"acirc", 226}, + {"atilde", 227}, + {"auml", 228}, + {"aring", 229}, + {"aelig", 230}, + {"ccedil", 231}, + {"egrave", 232}, + {"eacute", 233}, + {"ecirc", 234}, + {"euml", 235}, + {"igrave", 236}, + {"iacute", 237}, + {"icirc", 238}, + {"iuml", 239}, + {"eth", 240}, + {"ntilde", 241}, + {"ograve", 242}, + {"oacute", 243}, + {"ocirc", 244}, + {"otilde", 245}, + {"ouml", 246}, + {"divide", 247}, + {"oslash", 248}, + {"ugrave", 249}, + {"uacute", 250}, + {"ucirc", 251}, + {"uuml", 252}, + {"yacute", 253}, + {"thorn", 254}, + {"yuml", 255}, + + /* + ** Extended Entities defined in HTML 4: Symbols + */ + {"fnof", 402}, + {"Alpha", 913}, + {"Beta", 914}, + {"Gamma", 915}, + {"Delta", 916}, + {"Epsilon", 917}, + {"Zeta", 918}, + {"Eta", 919}, + {"Theta", 920}, + {"Iota", 921}, + {"Kappa", 922}, + {"Lambda", 923}, + {"Mu", 924}, + {"Nu", 925}, + {"Xi", 926}, + {"Omicron", 927}, + {"Pi", 928}, + {"Rho", 929}, + {"Sigma", 931}, + {"Tau", 932}, + {"Upsilon", 933}, + {"Phi", 934}, + {"Chi", 935}, + {"Psi", 936}, + {"Omega", 937}, + {"alpha", 945}, + {"beta", 946}, + {"gamma", 947}, + {"delta", 948}, + {"epsilon", 949}, + {"zeta", 950}, + {"eta", 951}, + {"theta", 952}, + {"iota", 953}, + {"kappa", 954}, + {"lambda", 955}, + {"mu", 956}, + {"nu", 957}, + {"xi", 958}, + {"omicron", 959}, + {"pi", 960}, + {"rho", 961}, + {"sigmaf", 962}, + {"sigma", 963}, + {"tau", 964}, + {"upsilon", 965}, + {"phi", 966}, + {"chi", 967}, + {"psi", 968}, + {"omega", 969}, + {"thetasym", 977}, + {"upsih", 978}, + {"piv", 982}, + {"bull", 8226}, + {"hellip", 8230}, + {"prime", 8242}, + {"Prime", 8243}, + {"oline", 8254}, + {"frasl", 8260}, + {"weierp", 8472}, + {"image", 8465}, + {"real", 8476}, + {"trade", 8482}, + {"alefsym", 8501}, + {"larr", 8592}, + {"uarr", 8593}, + {"rarr", 8594}, + {"darr", 8595}, + {"harr", 8596}, + {"crarr", 8629}, + {"lArr", 8656}, + {"uArr", 8657}, + {"rArr", 8658}, + {"dArr", 8659}, + {"hArr", 8660}, + {"forall", 8704}, + {"part", 8706}, + {"exist", 8707}, + {"empty", 8709}, + {"nabla", 8711}, + {"isin", 8712}, + {"notin", 8713}, + {"ni", 8715}, + {"prod", 8719}, + {"sum", 8721}, + {"minus", 8722}, + {"lowast", 8727}, + {"radic", 8730}, + {"prop", 8733}, + {"infin", 8734}, + {"ang", 8736}, + {"and", 8743}, + {"or", 8744}, + {"cap", 8745}, + {"cup", 8746}, + {"int", 8747}, + {"there4", 8756}, + {"sim", 8764}, + {"cong", 8773}, + {"asymp", 8776}, + {"ne", 8800}, + {"equiv", 8801}, + {"le", 8804}, + {"ge", 8805}, + {"sub", 8834}, + {"sup", 8835}, + {"nsub", 8836}, + {"sube", 8838}, + {"supe", 8839}, + {"oplus", 8853}, + {"otimes", 8855}, + {"perp", 8869}, + {"sdot", 8901}, + {"lceil", 8968}, + {"rceil", 8969}, + {"lfloor", 8970}, + {"rfloor", 8971}, + {"lang", 9001}, + {"rang", 9002}, + {"loz", 9674}, + {"spades", 9824}, + {"clubs", 9827}, + {"hearts", 9829}, + {"diams", 9830}, + + /* + ** Extended Entities defined in HTML 4: Special (less Markup at top) + */ + {"OElig", 338}, + {"oelig", 339}, + {"Scaron", 352}, + {"scaron", 353}, + {"Yuml", 376}, + {"circ", 710}, + {"tilde", 732}, + {"ensp", 8194}, + {"emsp", 8195}, + {"thinsp", 8201}, + {"zwnj", 8204}, + {"zwj", 8205}, + {"lrm", 8206}, + {"rlm", 8207}, + {"ndash", 8211}, + {"mdash", 8212}, + {"lsquo", 8216}, + {"rsquo", 8217}, + {"sbquo", 8218}, + {"ldquo", 8220}, + {"rdquo", 8221}, + {"bdquo", 8222}, + {"dagger", 8224}, + {"Dagger", 8225}, + {"permil", 8240}, + {"lsaquo", 8249}, + {"rsaquo", 8250}, + {"euro", 8364}, }; static int tag_cmp (const void *m1, const void *m2) { - const struct html_tag *p1 = m1; - const struct html_tag *p2 = m2; + const struct html_tag *p1 = m1; + const struct html_tag *p2 = m2; return g_ascii_strcasecmp (p1->name, p2->name); } @@ -453,25 +450,25 @@ tag_cmp (const void *m1, const void *m2) static int entity_cmp (const void *m1, const void *m2) { - const entity *p1 = m1; - const entity *p2 = m2; + const entity *p1 = m1; + const entity *p2 = m2; return g_ascii_strcasecmp (p1->name, p2->name); } -static GNode* -construct_html_node (memory_pool_t *pool, char *text) +static GNode * +construct_html_node (memory_pool_t * pool, char *text) { - struct html_node *html; - GNode *n = NULL; - struct html_tag key, *found; - char t; - int taglen = strlen (text); + struct html_node *html; + GNode *n = NULL; + struct html_tag key, *found; + char t; + int taglen = strlen (text); if (text == NULL || *text == '\0') { return NULL; } - + html = memory_pool_alloc0 (pool, sizeof (struct html_node)); /* Check whether this tag is fully closed */ @@ -481,13 +478,13 @@ construct_html_node (memory_pool_t *pool, char *text) /* Check xml tag */ if (*text == '?' && g_ascii_strncasecmp (text + 1, "xml", sizeof ("xml") - 1) == 0) { - html->flags |= FL_XML; - html->tag = NULL; + html->flags |= FL_XML; + html->tag = NULL; } else { if (*text == '/') { html->flags |= FL_CLOSING; - text ++; + text++; } /* Find end of tag name */ @@ -513,12 +510,12 @@ construct_html_node (memory_pool_t *pool, char *text) return n; } -static gboolean -check_balance (GNode *node, GNode **cur_level) +static gboolean +check_balance (GNode * node, GNode ** cur_level) { - struct html_node *arg = node->data, *tmp; - GNode *cur; - + struct html_node *arg = node->data, *tmp; + GNode *cur; + if (arg->flags & FL_CLOSING) { /* First of all check whether this tag is closing tag for parent node */ cur = node->parent; @@ -538,14 +535,14 @@ check_balance (GNode *node, GNode **cur_level) else { return TRUE; } - + return FALSE; } -struct html_tag * +struct html_tag * get_tag_by_name (const char *name) { - struct html_tag key; + struct html_tag key; key.name = name; @@ -554,90 +551,89 @@ get_tag_by_name (const char *name) /* Decode HTML entitles in text */ void -decode_entitles (char *s, guint *len) +decode_entitles (char *s, guint * len) { - guint l; - char *t = s; /* t - tortoise */ - char *h = s; /* h - hare */ - char *e = s; - char *end_ptr; - int state = 0, val, base; - entity *found, key; + guint l; + char *t = s; /* t - tortoise */ + char *h = s; /* h - hare */ + char *e = s; + char *end_ptr; + int state = 0, val, base; + entity *found, key; if (len == NULL || *len == 0) { - l = strlen (s); + l = strlen (s); } else { - l = *len; + l = *len; } - + while (h - s < l) { switch (state) { /* Out of entitle */ - case 0: - if (*h == '&') { - state = 1; - e = h; - h ++; - continue; + case 0: + if (*h == '&') { + state = 1; + e = h; + h++; + continue; + } + else { + *t = *h; + h++; + t++; + } + break; + case 1: + if (*h == ';') { + /* Determine base */ + /* First find in entities table */ + + key.name = e + 1; + *h = '\0'; + if (*(e + 1) != '#' && (found = bsearch (&key, entities_defs, G_N_ELEMENTS (entities_defs), sizeof (entity), entity_cmp)) != NULL) { + if (found->code > 0 || found->code < 127) { + *t = (char)found->code; + } + else { + /* Skip undecoded */ + t = h; + } } else { - *t = *h; - h ++; - t ++; - } - break; - case 1: - if (*h == ';') { - /* Determine base */ - /* First find in entities table */ - - key.name = e + 1; - *h = '\0'; - if (*(e + 1) != '#' && - (found = bsearch (&key, entities_defs, G_N_ELEMENTS (entities_defs), sizeof ( entity), entity_cmp)) != NULL) { - if (found->code > 0 || found->code < 127) { - *t = (char)found->code; - } - else { - /* Skip undecoded */ - t = h; - } + if (*(e + 2) == 'x' || *(e + 2) == 'X') { + base = 16; + } + else if (*(e + 2) == 'o' || *(e + 2) == 'O') { + base = 8; + } + else { + base = 10; + } + if (base == 10) { + val = strtoul ((e + 2), &end_ptr, base); } else { - if (*(e + 2) == 'x' || *(e + 2) == 'X') { - base = 16; - } - else if (*(e + 2) == 'o' || *(e + 2) == 'O') { - base = 8; - } - else { - base = 10; - } - if (base == 10) { - val = strtoul ((e + 2), &end_ptr, base); - } - else { - val = strtoul ((e + 3), &end_ptr, base); - } - if ((end_ptr != NULL && *end_ptr != '\0') || (val == 0 || val > 127)) { - /* Skip undecoded */ - t = h; - } - else { - *t = (char)val; - } + val = strtoul ((e + 3), &end_ptr, base); + } + if ((end_ptr != NULL && *end_ptr != '\0') || (val == 0 || val > 127)) { + /* Skip undecoded */ + t = h; + } + else { + *t = (char)val; } - *h = ';'; - state = 0; - t ++; } - h ++; - break; + *h = ';'; + state = 0; + t++; + } + h++; + break; } } *t = '\0'; - + if (len != NULL) { *len = t - s; } @@ -646,11 +642,11 @@ decode_entitles (char *s, guint *len) static void parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t id, char *tag_text) { - char *c = NULL, *p; - int len, rc; - char *url_text; - struct uri *url; - gboolean got_single_quote = FALSE, got_double_quote = FALSE; + char *c = NULL, *p; + int len, rc; + char *url_text; + struct uri *url; + gboolean got_single_quote = FALSE, got_double_quote = FALSE; /* For A tags search for href= and for IMG tags search for src= */ if (id == Tag_A) { @@ -667,7 +663,7 @@ parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t i c += len; /* Skip spaces after eqsign */ while (g_ascii_isspace (*c)) { - c ++; + c++; } len = 0; p = c; @@ -677,7 +673,7 @@ parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t i break; } else { - len ++; + len++; } } else if (got_single_quote) { @@ -685,10 +681,10 @@ parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t i break; } else { - len ++; + len++; } } - else if (g_ascii_isspace(*p) || *p == '>' || (*p == '/' && *(p + 1) == '>') || *p == '\r' || *p == '\n') { + else if (g_ascii_isspace (*p) || *p == '>' || (*p == '/' && *(p + 1) == '>') || *p == '\r' || *p == '\n') { break; } else { @@ -699,10 +695,10 @@ parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t i got_single_quote = !got_single_quote; } else { - len ++; + len++; } } - p ++; + p++; } if (got_single_quote || got_double_quote) { @@ -712,14 +708,14 @@ parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t i if (len == 0) { return; } - + url_text = memory_pool_alloc (task->task_pool, len + 1); g_strlcpy (url_text, c, len + 1); decode_entitles (url_text, NULL); - if (g_ascii_strncasecmp (url_text, "http://", sizeof ("http://") - 1) != 0) { - return; - } + if (g_ascii_strncasecmp (url_text, "http://", sizeof ("http://") - 1) != 0) { + return; + } url = memory_pool_alloc (task->task_pool, sizeof (struct uri)); rc = parse_uri (url, url_text, task->task_pool); @@ -730,14 +726,14 @@ parse_tag_url (struct worker_task *task, struct mime_text_part *part, tag_id_t i task->urls = g_list_prepend (task->urls, url); } } - } + } } gboolean -add_html_node (struct worker_task *task, memory_pool_t *pool, struct mime_text_part *part, char *tag_text, GNode **cur_level) +add_html_node (struct worker_task *task, memory_pool_t * pool, struct mime_text_part *part, char *tag_text, GNode ** cur_level) { - GNode *new; - struct html_node *data; + GNode *new; + struct html_node *data; if (!tags_sorted) { qsort (tag_defs, G_N_ELEMENTS (tag_defs), sizeof (struct html_tag), tag_cmp); @@ -754,7 +750,7 @@ add_html_node (struct worker_task *task, memory_pool_t *pool, struct mime_text_p new = g_node_new (NULL); *cur_level = new; part->html_nodes = new; - memory_pool_add_destructor (pool, (pool_destruct_func)g_node_destroy, part->html_nodes); + memory_pool_add_destructor (pool, (pool_destruct_func) g_node_destroy, part->html_nodes); /* Call once again with root node */ return add_html_node (task, pool, part, tag_text, cur_level); } @@ -769,7 +765,7 @@ add_html_node (struct worker_task *task, memory_pool_t *pool, struct mime_text_p parse_tag_url (task, part, data->tag->id, tag_text); } if (data->flags & FL_CLOSING) { - if (! *cur_level) { + if (!*cur_level) { msg_debug ("add_html_node: bad parent node"); return FALSE; } diff --git a/src/json/dump.c b/src/json/dump.c index 31ad41586..f384760c5 100644 --- a/src/json/dump.c +++ b/src/json/dump.c @@ -8,12 +8,12 @@ #include "jansson.h" #include "strbuffer.h" -typedef int (*dump_func) (const char *buffer, int size, void *data); +typedef int (*dump_func) (const char *buffer, int size, void *data); struct string { - char *buffer; - int length; - int size; + char *buffer; + int length; + int size; }; static int @@ -25,21 +25,21 @@ dump_to_strbuffer (const char *buffer, int size, void *data) static int dump_to_file (const char *buffer, int size, void *data) { - FILE *dest = (FILE *) data; + FILE *dest = (FILE *) data; if (fwrite (buffer, size, 1, dest) != 1) return -1; return 0; } /* 256 spaces (the maximum indentation size) */ -static char whitespace[] = +static char whitespace[] = " "; static int dump_indent (uint32_t flags, int depth, dump_func dump, void *data) { if (JSON_INDENT (flags) > 0) { - int i, ws_count = JSON_INDENT (flags); + int i, ws_count = JSON_INDENT (flags); if (dump ("\n", 1, data)) return -1; @@ -55,16 +55,16 @@ dump_indent (uint32_t flags, int depth, dump_func dump, void *data) static int dump_string (const char *str, dump_func dump, void *data) { - const char *end; + const char *end; if (dump ("\"", 1, data)) return -1; end = str; while (1) { - const char *text; - char seq[7]; - int length; + const char *text; + char seq[7]; + int length; while (*end && *end != '\\' && *end != '"' && (*end < 0 || *end > 0x1F)) end++; @@ -121,8 +121,7 @@ dump_string (const char *str, dump_func dump, void *data) } static int -do_dump (const json_t * json, uint32_t flags, int depth, - dump_func dump, void *data) +do_dump (const json_t * json, uint32_t flags, int depth, dump_func dump, void *data) { switch (json_typeof (json)) { case JSON_NULL: @@ -136,8 +135,8 @@ do_dump (const json_t * json, uint32_t flags, int depth, case JSON_INTEGER: { - char *buffer; - int size, ret; + char *buffer; + int size, ret; size = asprintf (&buffer, "%d", json_integer_value (json)); if (size == -1) @@ -150,8 +149,8 @@ do_dump (const json_t * json, uint32_t flags, int depth, case JSON_REAL: { - char *buffer; - int size, ret; + char *buffer; + int size, ret; size = asprintf (&buffer, "%.17f", json_real_value (json)); if (size == -1) @@ -167,8 +166,8 @@ do_dump (const json_t * json, uint32_t flags, int depth, case JSON_ARRAY: { - int i; - int n = json_array_size (json); + int i; + int n = json_array_size (json); if (dump ("[", 1, data)) return -1; @@ -178,13 +177,11 @@ do_dump (const json_t * json, uint32_t flags, int depth, return -1; for (i = 0; i < n; ++i) { - if (do_dump (json_array_get (json, i), flags, depth + 1, - dump, data)) + if (do_dump (json_array_get (json, i), flags, depth + 1, dump, data)) return -1; if (i < n - 1) { - if (dump (",", 1, data) || - dump_indent (flags, depth + 1, dump, data)) + if (dump (",", 1, data) || dump_indent (flags, depth + 1, dump, data)) return -1; } else { @@ -197,7 +194,7 @@ do_dump (const json_t * json, uint32_t flags, int depth, case JSON_OBJECT: { - void *iter = json_object_iter ((json_t *) json); + void *iter = json_object_iter ((json_t *) json); if (dump ("{", 1, data)) return -1; @@ -207,18 +204,14 @@ do_dump (const json_t * json, uint32_t flags, int depth, return -1; while (iter) { - void *next = - json_object_iter_next ((json_t *) json, iter); + void *next = json_object_iter_next ((json_t *) json, iter); dump_string (json_object_iter_key (iter), dump, data); - if (dump (": ", 2, data) || - do_dump (json_object_iter_value (iter), flags, depth + 1, - dump, data)) + if (dump (": ", 2, data) || do_dump (json_object_iter_value (iter), flags, depth + 1, dump, data)) return -1; if (next) { - if (dump (",", 1, data) || - dump_indent (flags, depth + 1, dump, data)) + if (dump (",", 1, data) || dump_indent (flags, depth + 1, dump, data)) return -1; } else { @@ -238,11 +231,11 @@ do_dump (const json_t * json, uint32_t flags, int depth, } -char * +char * json_dumps (const json_t * json, uint32_t flags) { - strbuffer_t strbuff; - char *result; + strbuffer_t strbuff; + char *result; if (!json_is_array (json) && !json_is_object (json)) return NULL; @@ -276,9 +269,9 @@ json_dumpf (const json_t * json, FILE * output, uint32_t flags) int json_dump_file (const json_t * json, const char *path, uint32_t flags) { - int result; + int result; - FILE *output = fopen (path, "w"); + FILE *output = fopen (path, "w"); if (!output) return -1; diff --git a/src/json/hashtable.c b/src/json/hashtable.c index 43e851382..14a59aff1 100644 --- a/src/json/hashtable.c +++ b/src/json/hashtable.c @@ -8,8 +8,8 @@ #include "../config.h" #include "hashtable.h" -typedef struct hashtable_list list_t; -typedef struct hashtable_pair pair_t; +typedef struct hashtable_list list_t; +typedef struct hashtable_pair pair_t; typedef struct hashtable_bucket bucket_t; #define container_of(ptr_, type_, member_) \ @@ -59,14 +59,14 @@ insert_to_bucket (hashtable_t * hashtable, bucket_t * bucket, list_t * list) } } -static unsigned int primes[] = { +static unsigned int primes[] = { 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741 }; -static const unsigned int num_primes = sizeof (primes) / sizeof (unsigned int); +static const unsigned int num_primes = sizeof (primes) / sizeof (unsigned int); static inline unsigned int num_buckets (hashtable_t * hashtable) @@ -75,12 +75,11 @@ num_buckets (hashtable_t * hashtable) } -static pair_t * -hashtable_find_pair (hashtable_t * hashtable, bucket_t * bucket, - const void *key, unsigned int hash) +static pair_t * +hashtable_find_pair (hashtable_t * hashtable, bucket_t * bucket, const void *key, unsigned int hash) { - list_t *list; - pair_t *pair; + list_t *list; + pair_t *pair; if (bucket_is_empty (hashtable, bucket)) return NULL; @@ -104,9 +103,9 @@ hashtable_find_pair (hashtable_t * hashtable, bucket_t * bucket, static int hashtable_do_del (hashtable_t * hashtable, const void *key, unsigned int hash) { - pair_t *pair; - bucket_t *bucket; - unsigned int index; + pair_t *pair; + bucket_t *bucket; + unsigned int index; index = hash % num_buckets (hashtable); bucket = &hashtable->buckets[index]; @@ -140,9 +139,9 @@ hashtable_do_del (hashtable_t * hashtable, const void *key, unsigned int hash) static int hashtable_do_rehash (hashtable_t * hashtable) { - list_t *list, *next; - pair_t *pair; - unsigned int i, index, new_size; + list_t *list, *next; + pair_t *pair; + unsigned int i, index, new_size; g_free (hashtable->buckets); @@ -154,8 +153,7 @@ hashtable_do_rehash (hashtable_t * hashtable) return -1; for (i = 0; i < num_buckets (hashtable); i++) { - hashtable->buckets[i].first = hashtable->buckets[i].last = - &hashtable->list; + hashtable->buckets[i].first = hashtable->buckets[i].last = &hashtable->list; } list = hashtable->list.next; @@ -172,11 +170,10 @@ hashtable_do_rehash (hashtable_t * hashtable) } -hashtable_t * -hashtable_create (key_hash_fn hash_key, key_cmp_fn cmp_keys, - free_fn free_key, free_fn free_value) +hashtable_t * +hashtable_create (key_hash_fn hash_key, key_cmp_fn cmp_keys, free_fn free_key, free_fn free_value) { - hashtable_t *hashtable = g_malloc (sizeof (hashtable_t)); + hashtable_t *hashtable = g_malloc (sizeof (hashtable_t)); if (!hashtable) return NULL; @@ -196,11 +193,9 @@ hashtable_destroy (hashtable_t * hashtable) } int -hashtable_init (hashtable_t * hashtable, - key_hash_fn hash_key, key_cmp_fn cmp_keys, - free_fn free_key, free_fn free_value) +hashtable_init (hashtable_t * hashtable, key_hash_fn hash_key, key_cmp_fn cmp_keys, free_fn free_key, free_fn free_value) { - unsigned int i; + unsigned int i; hashtable->size = 0; hashtable->num_buckets = 0; /* index to primes[] */ @@ -216,8 +211,7 @@ hashtable_init (hashtable_t * hashtable, hashtable->free_value = free_value; for (i = 0; i < num_buckets (hashtable); i++) { - hashtable->buckets[i].first = hashtable->buckets[i].last = - &hashtable->list; + hashtable->buckets[i].first = hashtable->buckets[i].last = &hashtable->list; } return 0; @@ -226,8 +220,8 @@ hashtable_init (hashtable_t * hashtable, void hashtable_close (hashtable_t * hashtable) { - list_t *list, *next; - pair_t *pair; + list_t *list, *next; + pair_t *pair; for (list = hashtable->list.next; list != &hashtable->list; list = next) { next = list->next; pair = list_to_pair (list); @@ -235,7 +229,7 @@ hashtable_close (hashtable_t * hashtable) hashtable->free_key (pair->key); if (hashtable->free_value) hashtable->free_value (pair->value); - g_free (pair); + g_free (pair); } g_free (hashtable->buckets); @@ -244,9 +238,9 @@ hashtable_close (hashtable_t * hashtable) int hashtable_set (hashtable_t * hashtable, void *key, void *value) { - pair_t *pair; - bucket_t *bucket; - unsigned int hash, index; + pair_t *pair; + bucket_t *bucket; + unsigned int hash, index; hash = hashtable->hash_key (key); @@ -276,12 +270,12 @@ hashtable_set (hashtable_t * hashtable, void *key, void *value) return 0; } -void * +void * hashtable_get (hashtable_t * hashtable, const void *key) { - pair_t *pair; - unsigned int hash; - bucket_t *bucket; + pair_t *pair; + unsigned int hash; + bucket_t *bucket; hash = hashtable->hash_key (key); bucket = &hashtable->buckets[hash % num_buckets (hashtable)]; @@ -296,35 +290,35 @@ hashtable_get (hashtable_t * hashtable, const void *key) int hashtable_del (hashtable_t * hashtable, const void *key) { - unsigned int hash = hashtable->hash_key (key); + unsigned int hash = hashtable->hash_key (key); return hashtable_do_del (hashtable, key, hash); } -void * +void * hashtable_iter (hashtable_t * hashtable) { return hashtable_iter_next (hashtable, &hashtable->list); } -void * +void * hashtable_iter_next (hashtable_t * hashtable, void *iter) { - list_t *list = (list_t *) iter; + list_t *list = (list_t *) iter; if (list->next == &hashtable->list) return NULL; return list->next; } -void * +void * hashtable_iter_key (void *iter) { - pair_t *pair = list_to_pair ((list_t *) iter); + pair_t *pair = list_to_pair ((list_t *) iter); return pair->key; } -void * +void * hashtable_iter_value (void *iter) { - pair_t *pair = list_to_pair ((list_t *) iter); + pair_t *pair = list_to_pair ((list_t *) iter); return pair->value; } diff --git a/src/json/load.c b/src/json/load.c index 6c6cda59e..07d0b9f8b 100644 --- a/src/json/load.c +++ b/src/json/load.c @@ -20,30 +20,30 @@ #define TOKEN_NULL 261 /* read one byte from stream, return EOF on end of file */ -typedef int (*get_func) (void *data); +typedef int (*get_func) (void *data); /* return non-zero if end of file has been reached */ -typedef int (*eof_func) (void *data); +typedef int (*eof_func) (void *data); typedef struct { - get_func get; - eof_func eof; - void *data; - int stream_pos; - char buffer[5]; - int buffer_pos; + get_func get; + eof_func eof; + void *data; + int stream_pos; + char buffer[5]; + int buffer_pos; } stream_t; typedef struct { - stream_t stream; - strbuffer_t saved_text; - int token; - int line, column; + stream_t stream; + strbuffer_t saved_text; + int token; + int line, column; union { - char *string; - int integer; - double real; + char *string; + int integer; + double real; } value; } lex_t; @@ -62,8 +62,8 @@ error_init (json_error_t * error) static void error_set (json_error_t * error, const lex_t * lex, const char *msg, ...) { - va_list ap; - char text[JSON_ERROR_TEXT_LENGTH]; + va_list ap; + char text[JSON_ERROR_TEXT_LENGTH]; if (!error || error->text[0] != '\0') { /* error already set */ @@ -75,19 +75,17 @@ error_set (json_error_t * error, const lex_t * lex, const char *msg, ...) va_end (ap); if (lex) { - const char *saved_text = strbuffer_value (&lex->saved_text); + const char *saved_text = strbuffer_value (&lex->saved_text); error->line = lex->line; if (saved_text && saved_text[0]) { if (lex->saved_text.length <= 20) { - snprintf (error->text, JSON_ERROR_TEXT_LENGTH, - "%s near '%s'", text, saved_text); + snprintf (error->text, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", text, saved_text); } else snprintf (error->text, JSON_ERROR_TEXT_LENGTH, "%s", text); } else { - snprintf (error->text, JSON_ERROR_TEXT_LENGTH, - "%s near end of file", text); + snprintf (error->text, JSON_ERROR_TEXT_LENGTH, "%s near end of file", text); } } else { @@ -113,7 +111,7 @@ stream_init (stream_t * stream, get_func get, eof_func eof, void *data) static char stream_get (stream_t * stream, json_error_t * error) { - char c; + char c; if (!stream->buffer[stream->buffer_pos]) { stream->buffer[0] = stream->get (stream->data); @@ -126,7 +124,7 @@ stream_get (stream_t * stream, json_error_t * error) if (c < 0) { /* multi-byte UTF-8 sequence */ - int i, count; + int i, count; count = utf8_check_first (c); if (!count) @@ -152,8 +150,7 @@ stream_get (stream_t * stream, json_error_t * error) return stream->buffer[stream->buffer_pos++]; out: - error_set (error, NULL, "unable to decode byte 0x%x at position %d", - (unsigned char)c, stream->stream_pos); + error_set (error, NULL, "unable to decode byte 0x%x at position %d", (unsigned char)c, stream->stream_pos); stream->buffer[0] = EOF; stream->buffer[1] = '\0'; @@ -192,7 +189,7 @@ lex_save (lex_t * lex, char c) static int lex_get_save (lex_t * lex, json_error_t * error) { - char c = stream_get (&lex->stream, error); + char c = stream_get (&lex->stream, error); lex_save (lex, c); return c; } @@ -200,7 +197,7 @@ lex_get_save (lex_t * lex, json_error_t * error) static void lex_unget_unsave (lex_t * lex, char c) { - char d; + char d; stream_unget (&lex->stream, c); d = strbuffer_pop (&lex->saved_text); g_assert (c == d); @@ -219,13 +216,13 @@ lex_save_cached (lex_t * lex) static int decode_unicode_escape (const char *str) { - int i; - int value = 0; + int i; + int value = 0; g_assert (str[0] == 'u'); for (i = 1; i <= 4; i++) { - char c = str[i]; + char c = str[i]; value <<= 4; if (g_ascii_isdigit (c)) value += c - '0'; @@ -243,10 +240,10 @@ decode_unicode_escape (const char *str) static void lex_scan_string (lex_t * lex, json_error_t * error) { - char c; - const char *p; - char *t; - int i; + char c; + const char *p; + char *t; + int i; lex->value.string = NULL; lex->token = TOKEN_INVALID; @@ -284,8 +281,7 @@ lex_scan_string (lex_t * lex, json_error_t * error) c = lex_get_save (lex, error); } } - else if (c == '"' || c == '\\' || c == '/' || c == 'b' || - c == 'f' || c == 'n' || c == 'r' || c == 't') + else if (c == '"' || c == '\\' || c == '/' || c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't') c = lex_get_save (lex, error); else { lex_unget_unsave (lex, c); @@ -320,9 +316,9 @@ lex_scan_string (lex_t * lex, json_error_t * error) if (*p == '\\') { p++; if (*p == 'u') { - char buffer[4]; - int length; - int value; + char buffer[4]; + int length; + int value; value = decode_unicode_escape (p); p += 5; @@ -330,26 +326,22 @@ lex_scan_string (lex_t * lex, json_error_t * error) if (0xD800 <= value && value <= 0xDBFF) { /* surrogate pair */ if (*p == '\\' && *(p + 1) == 'u') { - int value2 = decode_unicode_escape (++p); + int value2 = decode_unicode_escape (++p); p += 5; if (0xDC00 <= value2 && value2 <= 0xDFFF) { /* valid second surrogate */ - value = ((value - 0xD800) << 10) + - (value2 - 0xDC00) + 0x10000; + value = ((value - 0xD800) << 10) + (value2 - 0xDC00) + 0x10000; } else { /* invalid second surrogate */ - error_set (error, lex, - "invalid Unicode '\\u%04X\\u%04X'", - value, value2); + error_set (error, lex, "invalid Unicode '\\u%04X\\u%04X'", value, value2); goto out; } } else { /* no second surrogate */ - error_set (error, lex, "invalid Unicode '\\u%04X'", - value); + error_set (error, lex, "invalid Unicode '\\u%04X'", value); goto out; } } @@ -411,8 +403,8 @@ lex_scan_string (lex_t * lex, json_error_t * error) static void lex_scan_number (lex_t * lex, char c, json_error_t * error) { - const char *saved_text; - char *end; + const char *saved_text; + char *end; lex->token = TOKEN_INVALID; @@ -484,7 +476,7 @@ lex_scan_number (lex_t * lex, char c, json_error_t * error) static int lex_scan (lex_t * lex, json_error_t * error) { - char c; + char c; strbuffer_clear (&lex->saved_text); @@ -522,7 +514,7 @@ lex_scan (lex_t * lex, json_error_t * error) else if (g_ascii_isupper (c) || g_ascii_islower (c)) { /* eat up the whole identifier for clearer error messages */ - const char *saved_text; + const char *saved_text; c = lex_get_save (lex, error); while (g_ascii_isupper (c) || g_ascii_islower (c)) @@ -552,10 +544,10 @@ lex_scan (lex_t * lex, json_error_t * error) return lex->token; } -static char * +static char * lex_steal_string (lex_t * lex) { - char *result = NULL; + char *result = NULL; if (lex->token == TOKEN_STRING) { result = lex->value.string; lex->value.string = NULL; @@ -587,12 +579,12 @@ lex_close (lex_t * lex) /*** parser ***/ -static json_t *parse_value (lex_t * lex, json_error_t * error); +static json_t *parse_value (lex_t * lex, json_error_t * error); -static json_t * +static json_t * parse_object (lex_t * lex, json_error_t * error) { - json_t *object = json_object (); + json_t *object = json_object (); if (!object) return NULL; @@ -601,8 +593,8 @@ parse_object (lex_t * lex, json_error_t * error) return object; while (1) { - char *key; - json_t *value; + char *key; + json_t *value; if (lex->token != TOKEN_STRING) { error_set (error, lex, "string or '}' expected"); @@ -655,10 +647,10 @@ parse_object (lex_t * lex, json_error_t * error) return NULL; } -static json_t * +static json_t * parse_array (lex_t * lex, json_error_t * error) { - json_t *array = json_array (); + json_t *array = json_array (); if (!array) return NULL; @@ -667,7 +659,7 @@ parse_array (lex_t * lex, json_error_t * error) return array; while (lex->token) { - json_t *elem = parse_value (lex, error); + json_t *elem = parse_value (lex, error); if (!elem) goto error; @@ -696,10 +688,10 @@ parse_array (lex_t * lex, json_error_t * error) return NULL; } -static json_t * +static json_t * parse_value (lex_t * lex, json_error_t * error) { - json_t *json; + json_t *json; switch (lex->token) { case TOKEN_STRING:{ @@ -752,7 +744,7 @@ parse_value (lex_t * lex, json_error_t * error) return json; } -json_t * +json_t * parse_json (lex_t * lex, json_error_t * error) { error_init (error); @@ -767,15 +759,15 @@ parse_json (lex_t * lex, json_error_t * error) } typedef struct { - const char *data; - int pos; + const char *data; + int pos; } string_data_t; static int string_get (void *data) { - char c; - string_data_t *stream = (string_data_t *) data; + char c; + string_data_t *stream = (string_data_t *) data; c = stream->data[stream->pos]; if (c == '\0') return EOF; @@ -788,17 +780,17 @@ string_get (void *data) static int string_eof (void *data) { - string_data_t *stream = (string_data_t *) data; + string_data_t *stream = (string_data_t *) data; return (stream->data[stream->pos] == '\0'); } -json_t * +json_t * json_loads (const char *string, json_error_t * error) { - lex_t lex; - json_t *result; + lex_t lex; + json_t *result; - string_data_t stream_data = { + string_data_t stream_data = { .data = string, .pos = 0 }; @@ -822,11 +814,11 @@ json_loads (const char *string, json_error_t * error) return result; } -json_t * +json_t * json_loadf (FILE * input, json_error_t * error) { - lex_t lex; - json_t *result; + lex_t lex; + json_t *result; if (lex_init (&lex, (get_func) fgetc, (eof_func) feof, input)) return NULL; @@ -847,16 +839,15 @@ json_loadf (FILE * input, json_error_t * error) return result; } -json_t * +json_t * json_load_file (const char *path, json_error_t * error) { - json_t *result; - FILE *fp; + json_t *result; + FILE *fp; fp = fopen (path, "r"); if (!fp) { - error_set (error, NULL, "unable to open %s: %s", - path, strerror (errno)); + error_set (error, NULL, "unable to open %s: %s", path, strerror (errno)); return NULL; } diff --git a/src/json/strbuffer.c b/src/json/strbuffer.c index 8ba7faa9a..b6afcc248 100644 --- a/src/json/strbuffer.c +++ b/src/json/strbuffer.c @@ -43,16 +43,16 @@ strbuffer_clear (strbuffer_t * strbuff) strbuff->value[0] = '\0'; } -const char * +const char * strbuffer_value (const strbuffer_t * strbuff) { return strbuff->value; } -char * +char * strbuffer_steal_value (strbuffer_t * strbuff) { - char *result = strbuff->value; + char *result = strbuff->value; strbuffer_init (strbuff); return result; } @@ -73,8 +73,7 @@ int strbuffer_append_bytes (strbuffer_t * strbuff, const char *data, int size) { if (strbuff->length + size >= strbuff->size) { - strbuff->size = max (strbuff->size * STRBUFFER_FACTOR, - strbuff->length + size + 1); + strbuff->size = max (strbuff->size * STRBUFFER_FACTOR, strbuff->length + size + 1); strbuff->value = realloc (strbuff->value, strbuff->size); if (!strbuff->value) @@ -92,7 +91,7 @@ char strbuffer_pop (strbuffer_t * strbuff) { if (strbuff->length > 0) { - char c = strbuff->value[--strbuff->length]; + char c = strbuff->value[--strbuff->length]; strbuff->value[strbuff->length] = '\0'; return c; } diff --git a/src/json/utf.c b/src/json/utf.c index c9cfeaaef..b02630812 100644 --- a/src/json/utf.c +++ b/src/json/utf.c @@ -43,7 +43,7 @@ utf8_encode (int codepoint, char *buffer, int *size) int utf8_check_first (char byte) { - unsigned char u = (unsigned char)byte; + unsigned char u = (unsigned char)byte; if (u < 0x80) return 1; @@ -80,8 +80,8 @@ utf8_check_first (char byte) int utf8_check_full (const char *buffer, int size) { - int i, value = 0; - unsigned char u = (unsigned char)buffer[0]; + int i, value = 0; + unsigned char u = (unsigned char)buffer[0]; if (size == 2) { value = u & 0x1F; @@ -116,8 +116,7 @@ utf8_check_full (const char *buffer, int size) return 0; } - else if ((size == 2 && value < 0x80) || - (size == 3 && value < 0x800) || (size == 4 && value < 0x10000)) { + else if ((size == 2 && value < 0x80) || (size == 3 && value < 0x800) || (size == 4 && value < 0x10000)) { /* overlong encoding */ return 0; } @@ -128,13 +127,13 @@ utf8_check_full (const char *buffer, int size) int utf8_check_string (const char *string, int length) { - int i; + int i; if (length == -1) length = strlen (string); for (i = 0; i < length; i++) { - int count = utf8_check_first (string[i]); + int count = utf8_check_first (string[i]); if (count == 0) return 0; else if (count > 1) { diff --git a/src/json/value.c b/src/json/value.c index 9270f1f76..bb1bb9631 100644 --- a/src/json/value.c +++ b/src/json/value.c @@ -16,30 +16,30 @@ ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_)) typedef struct { - json_t json; - hashtable_t hashtable; + json_t json; + hashtable_t hashtable; } json_object_t; typedef struct { - json_t json; - unsigned int size; - unsigned int entries; - json_t **table; + json_t json; + unsigned int size; + unsigned int entries; + json_t **table; } json_array_t; typedef struct { - json_t json; - char *value; + json_t json; + char *value; } json_string_t; typedef struct { - json_t json; - double value; + json_t json; + double value; } json_real_t; typedef struct { - json_t json; - int value; + json_t json; + int value; } json_integer_t; #define json_to_object(json_) container_of(json_, json_object_t, json) @@ -61,9 +61,9 @@ json_init (json_t * json, json_type type) static unsigned int hash_string (const void *key) { - const char *str = (const char *)key; - unsigned int hash = 5381; - unsigned int c; + const char *str = (const char *)key; + unsigned int hash = 5381; + unsigned int c; while ((c = (unsigned int)*str)) { hash = ((hash << 5) + hash) + c; @@ -85,16 +85,15 @@ value_decref (void *value) json_decref ((json_t *) value); } -json_t * +json_t * json_object (void) { - json_object_t *object = g_malloc (sizeof (json_object_t)); + json_object_t *object = g_malloc (sizeof (json_object_t)); if (!object) return NULL; json_init (&object->json, JSON_OBJECT); - if (hashtable_init (&object->hashtable, hash_string, string_equal, - g_free, value_decref)) { + if (hashtable_init (&object->hashtable, hash_string, string_equal, g_free, value_decref)) { g_free (object); return NULL; } @@ -108,10 +107,10 @@ json_delete_object (json_object_t * object) g_free (object); } -json_t * +json_t * json_object_get (const json_t * json, const char *key) { - json_object_t *object; + json_object_t *object; if (!json_is_object (json)) return NULL; @@ -123,7 +122,7 @@ json_object_get (const json_t * json, const char *key) int json_object_set_new_nocheck (json_t * json, const char *key, json_t * value) { - json_object_t *object; + json_object_t *object; if (!key || !value) return -1; @@ -162,7 +161,7 @@ json_object_set_new (json_t * json, const char *key, json_t * value) int json_object_del (json_t * json, const char *key) { - json_object_t *object; + json_object_t *object; if (!json_is_object (json)) return -1; @@ -171,10 +170,10 @@ json_object_del (json_t * json, const char *key) return hashtable_del (&object->hashtable, key); } -void * +void * json_object_iter (json_t * json) { - json_object_t *object; + json_object_t *object; if (!json_is_object (json)) return NULL; @@ -183,10 +182,10 @@ json_object_iter (json_t * json) return hashtable_iter (&object->hashtable); } -void * +void * json_object_iter_next (json_t * json, void *iter) { - json_object_t *object; + json_object_t *object; if (!json_is_object (json) || iter == NULL) return NULL; @@ -195,7 +194,7 @@ json_object_iter_next (json_t * json, void *iter) return hashtable_iter_next (&object->hashtable, iter); } -const char * +const char * json_object_iter_key (void *iter) { if (!iter) @@ -204,7 +203,7 @@ json_object_iter_key (void *iter) return (const char *)hashtable_iter_key (iter); } -json_t * +json_t * json_object_iter_value (void *iter) { if (!iter) @@ -216,10 +215,10 @@ json_object_iter_value (void *iter) /*** array ***/ -json_t * +json_t * json_array (void) { - json_array_t *array = g_malloc (sizeof (json_array_t)); + json_array_t *array = g_malloc (sizeof (json_array_t)); if (!array) return NULL; json_init (&array->json, JSON_ARRAY); @@ -234,7 +233,7 @@ json_array (void) static void json_delete_array (json_array_t * array) { - unsigned int i; + unsigned int i; for (i = 0; i < array->entries; i++) json_decref (array->table[i]); @@ -252,10 +251,10 @@ json_array_size (const json_t * json) return json_to_array (json)->entries; } -json_t * +json_t * json_array_get (const json_t * json, unsigned int index) { - json_array_t *array; + json_array_t *array; if (!json_is_array (json)) return NULL; array = json_to_array (json); @@ -269,7 +268,7 @@ json_array_get (const json_t * json, unsigned int index) int json_array_set_new (json_t * json, unsigned int index, json_t * value) { - json_array_t *array; + json_array_t *array; if (!value) return -1; @@ -294,7 +293,7 @@ json_array_set_new (json_t * json, unsigned int index, json_t * value) int json_array_append_new (json_t * json, json_t * value) { - json_array_t *array; + json_array_t *array; if (!value) return -1; @@ -323,10 +322,10 @@ json_array_append_new (json_t * json, json_t * value) /*** string ***/ -json_t * +json_t * json_string_nocheck (const char *value) { - json_string_t *string; + json_string_t *string; if (!value) return NULL; @@ -345,7 +344,7 @@ json_string_nocheck (const char *value) return &string->json; } -json_t * +json_t * json_string (const char *value) { if (!value || !utf8_check_string (value, -1)) @@ -354,7 +353,7 @@ json_string (const char *value) return json_string_nocheck (value); } -const char * +const char * json_string_value (const json_t * json) { if (!json_is_string (json)) @@ -373,10 +372,10 @@ json_delete_string (json_string_t * string) /*** integer ***/ -json_t * +json_t * json_integer (int value) { - json_integer_t *integer = g_malloc (sizeof (json_integer_t)); + json_integer_t *integer = g_malloc (sizeof (json_integer_t)); if (!integer) return NULL; json_init (&integer->json, JSON_INTEGER); @@ -403,10 +402,10 @@ json_delete_integer (json_integer_t * integer) /*** real ***/ -json_t * +json_t * json_real (double value) { - json_real_t *real = g_malloc (sizeof (json_real_t)); + json_real_t *real = g_malloc (sizeof (json_real_t)); if (!real) return NULL; json_init (&real->json, JSON_REAL); @@ -447,10 +446,10 @@ json_number_value (const json_t * json) /*** simple values ***/ -json_t * +json_t * json_true (void) { - static json_t the_true = { + static json_t the_true = { .type = JSON_TRUE, .refcount = 1 }; @@ -458,10 +457,10 @@ json_true (void) } -json_t * +json_t * json_false (void) { - static json_t the_false = { + static json_t the_false = { .type = JSON_FALSE, .refcount = 1 }; @@ -469,10 +468,10 @@ json_false (void) } -json_t * +json_t * json_null (void) { - static json_t the_null = { + static json_t the_null = { .type = JSON_NULL, .refcount = 1 }; diff --git a/src/lmtp.c b/src/lmtp.c index 3becb1dfe..087be2e1a 100644 --- a/src/lmtp.c +++ b/src/lmtp.c @@ -33,19 +33,20 @@ #include "modules.h" #include "message.h" -static char greetingbuf[1024]; -static struct timeval io_tv; +static char greetingbuf[1024]; +static struct timeval io_tv; -static gboolean lmtp_write_socket (void *arg); +static gboolean lmtp_write_socket (void *arg); -static -void sig_handler (int signo) +static + void +sig_handler (int signo) { switch (signo) { - case SIGINT: - case SIGTERM: - _exit (1); - break; + case SIGINT: + case SIGTERM: + _exit (1); + break; } } @@ -55,9 +56,9 @@ void sig_handler (int signo) static void sigusr_handler (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct rspamd_worker *worker = (struct rspamd_worker *)arg; /* Do not accept new connections, preparing to end worker's process */ - struct timeval tv; + struct timeval tv; tv.tv_sec = SOFT_SHUTDOWN_TIME; tv.tv_usec = 0; event_del (&worker->sig_ev); @@ -74,7 +75,7 @@ sigusr_handler (int fd, short what, void *arg) static void rcpt_destruct (void *pointer) { - struct worker_task *task = (struct worker_task *)pointer; + struct worker_task *task = (struct worker_task *)pointer; if (task->rcpt) { g_list_free (task->rcpt); @@ -87,8 +88,8 @@ rcpt_destruct (void *pointer) static void free_lmtp_task (struct rspamd_lmtp_proto *lmtp, gboolean is_soft) { - GList *part; - struct mime_part *p; + GList *part; + struct mime_part *p; if (lmtp) { msg_debug ("free_lmtp_task: free pointer %p", lmtp->task); @@ -121,47 +122,47 @@ free_lmtp_task (struct rspamd_lmtp_proto *lmtp, gboolean is_soft) /* * Callback that is called when there is data to read in buffer */ -static gboolean -lmtp_read_socket (f_str_t *in, void *arg) +static gboolean +lmtp_read_socket (f_str_t * in, void *arg) { - struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg; - struct worker_task *task = lmtp->task; - ssize_t r; + struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg; + struct worker_task *task = lmtp->task; + ssize_t r; switch (task->state) { - case READ_COMMAND: - case READ_HEADER: - if (read_lmtp_input_line (lmtp, in) != 0) { - msg_info ("read_lmtp_socket: closing lmtp connection due to protocol error"); - lmtp->task->state = CLOSING_CONNECTION; - } - /* Task was read, recall read handler once more with new state to process message and write reply */ - if (task->state == READ_MESSAGE) { - lmtp_read_socket (in, arg); - } - break; - case READ_MESSAGE: - r = process_message (lmtp->task); - r = process_filters (lmtp->task); - if (r == -1) { - task->last_error = "Filter processing error"; - task->error_code = LMTP_FAILURE; - task->state = WRITE_ERROR; - lmtp_write_socket (lmtp); - } - else if (r == 0) { - task->state = WAIT_FILTER; - rspamd_dispatcher_pause (lmtp->task->dispatcher); - } - else { - process_statfiles (lmtp->task); - task->state = WRITE_REPLY; - lmtp_write_socket (lmtp); - } - break; - default: - msg_debug ("lmtp_read_socket: invalid state while reading from socket %d", lmtp->task->state); - break; + case READ_COMMAND: + case READ_HEADER: + if (read_lmtp_input_line (lmtp, in) != 0) { + msg_info ("read_lmtp_socket: closing lmtp connection due to protocol error"); + lmtp->task->state = CLOSING_CONNECTION; + } + /* Task was read, recall read handler once more with new state to process message and write reply */ + if (task->state == READ_MESSAGE) { + lmtp_read_socket (in, arg); + } + break; + case READ_MESSAGE: + r = process_message (lmtp->task); + r = process_filters (lmtp->task); + if (r == -1) { + task->last_error = "Filter processing error"; + task->error_code = LMTP_FAILURE; + task->state = WRITE_ERROR; + lmtp_write_socket (lmtp); + } + else if (r == 0) { + task->state = WAIT_FILTER; + rspamd_dispatcher_pause (lmtp->task->dispatcher); + } + else { + process_statfiles (lmtp->task); + task->state = WRITE_REPLY; + lmtp_write_socket (lmtp); + } + break; + default: + msg_debug ("lmtp_read_socket: invalid state while reading from socket %d", lmtp->task->state); + break; } return TRUE; @@ -170,32 +171,32 @@ lmtp_read_socket (f_str_t *in, void *arg) /* * Callback for socket writing */ -static gboolean +static gboolean lmtp_write_socket (void *arg) { - struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg; - + struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg; + switch (lmtp->task->state) { - case WRITE_REPLY: - if (write_lmtp_reply (lmtp) == 1) { - lmtp->task->state = WAIT_FILTER; - } - else { - lmtp->task->state = CLOSING_CONNECTION; - } - break; - case WRITE_ERROR: - write_lmtp_reply (lmtp); + case WRITE_REPLY: + if (write_lmtp_reply (lmtp) == 1) { + lmtp->task->state = WAIT_FILTER; + } + else { lmtp->task->state = CLOSING_CONNECTION; - break; - case CLOSING_CONNECTION: - msg_debug ("lmtp_write_socket: normally closing connection"); - free_lmtp_task (lmtp, TRUE); - return FALSE; - break; - default: - msg_debug ("lmtp_write_socket: invalid state while writing to socket %d", lmtp->task->state); - break; + } + break; + case WRITE_ERROR: + write_lmtp_reply (lmtp); + lmtp->task->state = CLOSING_CONNECTION; + break; + case CLOSING_CONNECTION: + msg_debug ("lmtp_write_socket: normally closing connection"); + free_lmtp_task (lmtp, TRUE); + return FALSE; + break; + default: + msg_debug ("lmtp_write_socket: invalid state while writing to socket %d", lmtp->task->state); + break; } return TRUE; @@ -205,9 +206,9 @@ lmtp_write_socket (void *arg) * Called if something goes wrong */ static void -lmtp_err_socket (GError *err, void *arg) +lmtp_err_socket (GError * err, void *arg) { - struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg; + struct rspamd_lmtp_proto *lmtp = (struct rspamd_lmtp_proto *)arg; msg_info ("lmtp_err_socket: abnormally closing connection, error: %s", err->message); /* Free buffers */ free_lmtp_task (lmtp, FALSE); @@ -219,12 +220,12 @@ lmtp_err_socket (GError *err, void *arg) static void accept_socket (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; - struct sockaddr_storage ss; - struct worker_task *new_task; - struct rspamd_lmtp_proto *lmtp; - socklen_t addrlen = sizeof(ss); - int nfd; + struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct sockaddr_storage ss; + struct worker_task *new_task; + struct rspamd_lmtp_proto *lmtp; + socklen_t addrlen = sizeof (ss); + int nfd; if ((nfd = accept_from_socket (fd, (struct sockaddr *)&ss, &addrlen)) == -1) { msg_warn ("accept_socket: accept failed: %s", strerror (errno)); @@ -240,17 +241,15 @@ accept_socket (int fd, short what, void *arg) new_task->cfg = worker->srv->cfg; new_task->task_pool = memory_pool_new (memory_pool_get_size ()); /* Add destructor for recipients list (it would be better to use anonymous function here */ - memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)rcpt_destruct, new_task); + memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func) rcpt_destruct, new_task); new_task->results = g_hash_table_new (g_str_hash, g_str_equal); - memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)g_hash_table_destroy, new_task->results); - worker->srv->stat->connections_count ++; + memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func) g_hash_table_destroy, new_task->results); + worker->srv->stat->connections_count++; lmtp->task = new_task; lmtp->state = LMTP_READ_LHLO; /* Set up dispatcher */ - new_task->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, lmtp_read_socket, - lmtp_write_socket, lmtp_err_socket, &io_tv, - (void *)lmtp); + new_task->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, lmtp_read_socket, lmtp_write_socket, lmtp_err_socket, &io_tv, (void *)lmtp); rspamd_dispatcher_write (lmtp->task->dispatcher, greetingbuf, strlen (greetingbuf), FALSE, FALSE); } @@ -260,10 +259,10 @@ accept_socket (int fd, short what, void *arg) void start_lmtp_worker (struct rspamd_worker *worker) { - struct sigaction signals; - int i; - char *hostbuf; - long int hostmax; + struct sigaction signals; + int i; + char *hostbuf; + long int hostmax; worker->srv->pid = getpid (); worker->srv->type = TYPE_LMTP; @@ -274,15 +273,15 @@ start_lmtp_worker (struct rspamd_worker *worker) sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL); /* SIGUSR2 handler */ - signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *) worker); + signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *)worker); signal_add (&worker->sig_ev, NULL); - + /* Accept event */ - event_set(&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); - event_add(&worker->bind_ev, NULL); + event_set (&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); + event_add (&worker->bind_ev, NULL); /* Perform modules configuring */ - for (i = 0; i < MODULES_NUM; i ++) { + for (i = 0; i < MODULES_NUM; i++) { modules[i].module_config_func (worker->srv->cfg); } diff --git a/src/lmtp_proto.c b/src/lmtp_proto.c index 7fbc38684..2c0ffa9d4 100644 --- a/src/lmtp_proto.c +++ b/src/lmtp_proto.c @@ -33,40 +33,44 @@ #define OUTBUFSIZ 1000 /* LMTP commands */ -static f_str_t lhlo_command = { +static f_str_t lhlo_command = { .begin = "LHLO", .len = sizeof ("LHLO") - 1 }; -static f_str_t mail_command = { + +static f_str_t mail_command = { .begin = "MAIL FROM:", .len = sizeof ("MAIL FROM:") - 1 }; -static f_str_t rcpt_command = { + +static f_str_t rcpt_command = { .begin = "RCPT TO:", .len = sizeof ("RCPT TO:") - 1 }; -static f_str_t data_command = { + +static f_str_t data_command = { .begin = "DATA", .len = sizeof ("DATA") - 1 }; -static f_str_t data_dot = { + +static f_str_t data_dot = { .begin = ".\r\n", .len = sizeof (".\r\n") - 1 }; -static const char *mail_regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"; -static GRegex *mail_re = NULL; +static const char *mail_regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"; +static GRegex *mail_re = NULL; /* * Extract e-mail from read line * return <> if no valid address detected */ -static char * -extract_mail (memory_pool_t *pool, f_str_t *line) +static char * +extract_mail (memory_pool_t * pool, f_str_t * line) { - GError *err = NULL; - char *match; - GMatchInfo *info; + GError *err = NULL; + char *match; + GMatchInfo *info; if (mail_re == NULL) { /* Compile regexp */ @@ -87,9 +91,9 @@ extract_mail (memory_pool_t *pool, f_str_t *line) static void out_lmtp_reply (struct worker_task *task, int code, char *rcode, char *msg) { - char outbuf[OUTBUFSIZ]; - int r; - + char outbuf[OUTBUFSIZ]; + int r; + if (*rcode == '\0') { r = snprintf (outbuf, OUTBUFSIZ, "%d %s\r\n", code, msg); } @@ -99,144 +103,144 @@ out_lmtp_reply (struct worker_task *task, int code, char *rcode, char *msg) rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); } -int -read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t *line) +int +read_lmtp_input_line (struct rspamd_lmtp_proto *lmtp, f_str_t * line) { - char *c, *rcpt; - f_str_t fstr; - unsigned int i = 0, l = 0, size; + char *c, *rcpt; + f_str_t fstr; + unsigned int i = 0, l = 0, size; switch (lmtp->state) { - case LMTP_READ_LHLO: - /* Search LHLO line */ - if ((i = fstrstri (line, &lhlo_command)) == -1) { - msg_info ("read_lmtp_input_line: LHLO expected but not found"); - out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need LHLO here"); - return -1; - } - else { - i += lhlo_command.len; - c = line->begin + i; - /* Skip spaces */ - while (g_ascii_isspace (*c) && i < line->len) { - i ++; - c ++; - } - lmtp->task->helo = memory_pool_alloc (lmtp->task->task_pool, line->len - i + 1); - /* Strlcpy makes string null terminated by design */ - g_strlcpy (lmtp->task->helo, c, line->len - i + 1); - lmtp->state = LMTP_READ_FROM; - out_lmtp_reply (lmtp->task, LMTP_OK, "", "Ok"); - return 0; + case LMTP_READ_LHLO: + /* Search LHLO line */ + if ((i = fstrstri (line, &lhlo_command)) == -1) { + msg_info ("read_lmtp_input_line: LHLO expected but not found"); + out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need LHLO here"); + return -1; + } + else { + i += lhlo_command.len; + c = line->begin + i; + /* Skip spaces */ + while (g_ascii_isspace (*c) && i < line->len) { + i++; + c++; } - break; - case LMTP_READ_FROM: - /* Search MAIL FROM: line */ - if ((i = fstrstri (line, &mail_command)) == -1) { - msg_info ("read_lmtp_input_line: MAIL expected but not found"); - out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need MAIL here"); + lmtp->task->helo = memory_pool_alloc (lmtp->task->task_pool, line->len - i + 1); + /* Strlcpy makes string null terminated by design */ + g_strlcpy (lmtp->task->helo, c, line->len - i + 1); + lmtp->state = LMTP_READ_FROM; + out_lmtp_reply (lmtp->task, LMTP_OK, "", "Ok"); + return 0; + } + break; + case LMTP_READ_FROM: + /* Search MAIL FROM: line */ + if ((i = fstrstri (line, &mail_command)) == -1) { + msg_info ("read_lmtp_input_line: MAIL expected but not found"); + out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need MAIL here"); + return -1; + } + else { + i += mail_command.len; + c = line->begin + i; + fstr.begin = line->begin + i; + fstr.len = line->len - i; + lmtp->task->from = extract_mail (lmtp->task->task_pool, &fstr); + lmtp->state = LMTP_READ_RCPT; + out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Sender ok"); + return 0; + } + break; + case LMTP_READ_RCPT: + /* Search RCPT_TO: line */ + if ((i = fstrstri (line, &rcpt_command)) == -1) { + msg_info ("read_lmtp_input_line: RCPT expected but not found"); + out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Need RCPT here"); + return -1; + } + else { + i += rcpt_command.len; + c = line->begin + i; + fstr.begin = line->begin + i; + fstr.len = line->len - i; + rcpt = extract_mail (lmtp->task->task_pool, &fstr); + if (*rcpt == '<' && *(rcpt + 1) == '>') { + /* Invalid or empty rcpt not allowed */ + msg_info ("read_lmtp_input_line: bad recipient"); + out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Bad recipient"); return -1; } - else { - i += mail_command.len; - c = line->begin + i; - fstr.begin = line->begin + i; - fstr.len = line->len - i; - lmtp->task->from = extract_mail (lmtp->task->task_pool, &fstr); - lmtp->state = LMTP_READ_RCPT; - out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Sender ok"); - return 0; - } - break; - case LMTP_READ_RCPT: - /* Search RCPT_TO: line */ - if ((i = fstrstri (line, &rcpt_command)) == -1) { - msg_info ("read_lmtp_input_line: RCPT expected but not found"); - out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Need RCPT here"); - return -1; + /* Strlcpy makes string null terminated by design */ + lmtp->task->rcpt = g_list_prepend (lmtp->task->rcpt, rcpt); + lmtp->state = LMTP_READ_DATA; + out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Recipient ok"); + return 0; + } + break; + case LMTP_READ_DATA: + /* Search DATA line */ + if ((i = fstrstri (line, &data_command)) == -1) { + msg_info ("read_lmtp_input_line: DATA expected but not found"); + out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need DATA here"); + return -1; + } + else { + i += data_command.len; + c = line->begin + i; + /* Skip spaces */ + while (g_ascii_isspace (*c++)) { + i++; } - else { - i += rcpt_command.len; - c = line->begin + i; - fstr.begin = line->begin + i; - fstr.len = line->len - i; - rcpt = extract_mail (lmtp->task->task_pool, &fstr); - if (*rcpt == '<' && *(rcpt + 1) == '>') { - /* Invalid or empty rcpt not allowed */ - msg_info ("read_lmtp_input_line: bad recipient"); - out_lmtp_reply (lmtp->task, LMTP_NO_RCPT, "5.5.4", "Bad recipient"); - return -1; + rcpt = memory_pool_alloc (lmtp->task->task_pool, line->len - i + 1); + /* Strlcpy makes string null terminated by design */ + g_strlcpy (rcpt, c, line->len - i + 1); + lmtp->task->rcpt = g_list_prepend (lmtp->task->rcpt, rcpt); + lmtp->state = LMTP_READ_MESSAGE; + out_lmtp_reply (lmtp->task, LMTP_DATA, "", "Enter message, ending with \".\" on a line by itself"); + lmtp->task->msg = fstralloc (lmtp->task->task_pool, BUFSIZ); + return 0; + } + break; + case LMTP_READ_MESSAGE: + if (strncmp (line->begin, data_dot.begin, line->len) == 0) { + lmtp->state = LMTP_READ_DOT; + lmtp->task->state = READ_MESSAGE; + return 0; + } + else { + l = lmtp->task->msg->len; + size = lmtp->task->msg->size; + if (l + line->len > size) { + /* Grow buffer */ + if (line->len > size) { + size += line->len << 1; } - /* Strlcpy makes string null terminated by design */ - lmtp->task->rcpt = g_list_prepend (lmtp->task->rcpt, rcpt); - lmtp->state = LMTP_READ_DATA; - out_lmtp_reply (lmtp->task, LMTP_OK, "2.1.0", "Recipient ok"); - return 0; - } - break; - case LMTP_READ_DATA: - /* Search DATA line */ - if ((i = fstrstri (line, &data_command)) == -1) { - msg_info ("read_lmtp_input_line: DATA expected but not found"); - out_lmtp_reply (lmtp->task, LMTP_BAD_CMD, "5.0.0", "Need DATA here"); - return -1; - } - else { - i += data_command.len; - c = line->begin + i; - /* Skip spaces */ - while (g_ascii_isspace (*c++)) { - i ++; + else { + /* size *= 2 */ + size <<= 1; } - rcpt = memory_pool_alloc (lmtp->task->task_pool, line->len - i + 1); - /* Strlcpy makes string null terminated by design */ - g_strlcpy (rcpt, c, line->len - i + 1); - lmtp->task->rcpt = g_list_prepend (lmtp->task->rcpt, rcpt); - lmtp->state = LMTP_READ_MESSAGE; - out_lmtp_reply (lmtp->task, LMTP_DATA, "", "Enter message, ending with \".\" on a line by itself"); - lmtp->task->msg = fstralloc (lmtp->task->task_pool, BUFSIZ); - return 0; + lmtp->task->msg = fstrgrow (lmtp->task->task_pool, lmtp->task->msg, size); } - break; - case LMTP_READ_MESSAGE: - if (strncmp (line->begin, data_dot.begin, line->len) == 0) { - lmtp->state = LMTP_READ_DOT; - lmtp->task->state = READ_MESSAGE; - return 0; - } - else { - l = lmtp->task->msg->len; - size = lmtp->task->msg->size; - if (l + line->len > size) { - /* Grow buffer */ - if (line->len > size) { - size += line->len << 1; - } - else { - /* size *= 2 */ - size <<= 1; - } - lmtp->task->msg = fstrgrow (lmtp->task->task_pool, lmtp->task->msg, size); - } - fstrcat (lmtp->task->msg, line); - return 0; - } - break; - case LMTP_READ_DOT: - /* We have some input after reading dot, close connection as we have no currently support of multiply - * messages per session - */ - out_lmtp_reply (lmtp->task, LMTP_QUIT, "", "Bye"); + fstrcat (lmtp->task->msg, line); return 0; - break; - } + } + break; + case LMTP_READ_DOT: + /* We have some input after reading dot, close connection as we have no currently support of multiply + * messages per session + */ + out_lmtp_reply (lmtp->task, LMTP_QUIT, "", "Bye"); + return 0; + break; + } return 0; } struct mta_callback_data { - struct worker_task *task; - rspamd_io_dispatcher_t *dispatcher; + struct worker_task *task; + rspamd_io_dispatcher_t *dispatcher; enum { LMTP_WANT_GREETING, LMTP_WANT_MAIL, @@ -247,37 +251,33 @@ struct mta_callback_data { } state; }; -static gboolean -parse_mta_str (f_str_t *in, struct mta_callback_data *cd) +static gboolean +parse_mta_str (f_str_t * in, struct mta_callback_data *cd) { - int r; - static f_str_t okres1 = { + int r; + static f_str_t okres1 = { .begin = "250 ", .len = sizeof ("250 ") - 1, - }, - okres2 = { - .begin = "220 ", - .len = sizeof ("220 ") - 1, - }, - datares = { - .begin = "354 ", - .len = sizeof ("354 ") - 1, - }; + } + , okres2 = { + .begin = "220 ",.len = sizeof ("220 ") - 1,} + , datares = { + .begin = "354 ",.len = sizeof ("354 ") - 1,}; switch (cd->state) { - case LMTP_WANT_GREETING: - case LMTP_WANT_MAIL: - case LMTP_WANT_RCPT: - case LMTP_WANT_DATA: - case LMTP_WANT_CLOSING: - r = fstrstr (in, &okres1); - if (r == -1) { - r = fstrstr (in, &okres2); - } - break; - case LMTP_WANT_DOT: - r = fstrstr (in, &datares); - break; + case LMTP_WANT_GREETING: + case LMTP_WANT_MAIL: + case LMTP_WANT_RCPT: + case LMTP_WANT_DATA: + case LMTP_WANT_CLOSING: + r = fstrstr (in, &okres1); + if (r == -1) { + r = fstrstr (in, &okres2); + } + break; + case LMTP_WANT_DOT: + r = fstrstr (in, &datares); + break; } return r != -1; @@ -299,104 +299,102 @@ close_mta_connection (struct mta_callback_data *cd, gboolean is_success) /* * Callback that is called when there is data to read in buffer */ -static gboolean -mta_read_socket (f_str_t *in, void *arg) +static gboolean +mta_read_socket (f_str_t * in, void *arg) { - struct mta_callback_data *cd = (struct mta_callback_data *)arg; - char outbuf[1024], *hostbuf, *c; - int hostmax, r; - GList *cur; - static f_str_t contres1 = { + struct mta_callback_data *cd = (struct mta_callback_data *)arg; + char outbuf[1024], *hostbuf, *c; + int hostmax, r; + GList *cur; + static f_str_t contres1 = { .begin = "250-", .len = sizeof ("250-") - 1, - }, - contres2 = { - .begin = "220-", - .len = sizeof ("220-") - 1, - }; - + } + , contres2 = { + .begin = "220-",.len = sizeof ("220-") - 1,}; + if (fstrstr (in, &contres1) != -1 || fstrstr (in, &contres2) != -1) { /* Skip such lines */ return TRUE; } switch (cd->state) { - case LMTP_WANT_GREETING: - if (!parse_mta_str (in, cd)) { - msg_warn ("mta_read_socket: got bad greeting"); - close_mta_connection (cd, FALSE); - return FALSE; - } - hostmax = sysconf (_SC_HOST_NAME_MAX) + 1; - hostbuf = alloca (hostmax); - gethostname (hostbuf, hostmax); - hostbuf[hostmax - 1] = '\0'; - if (cd->task->cfg->deliver_lmtp) { - r = snprintf (outbuf, sizeof (outbuf), "LHLO %s" CRLF, hostbuf); - } - else { - r = snprintf (outbuf, sizeof (outbuf), "HELO %s" CRLF, hostbuf); - } - rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); - cd->state = LMTP_WANT_MAIL; - break; - case LMTP_WANT_MAIL: - if (!parse_mta_str (in, cd)) { - msg_warn ("mta_read_socket: got bad helo"); - close_mta_connection (cd, FALSE); - return FALSE; - } - r = snprintf (outbuf, sizeof (outbuf), "MAIL FROM: <%s>" CRLF, cd->task->from); - rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); - cd->state = LMTP_WANT_RCPT; - break; - case LMTP_WANT_RCPT: - if (!parse_mta_str (in, cd)) { - msg_warn ("mta_read_socket: got bad mail from"); - close_mta_connection (cd, FALSE); - return FALSE; - } - cur = g_list_first (cd->task->rcpt); - r = 0; - while (cur) { - r += snprintf (outbuf + r, sizeof (outbuf) -r, "RCPT TO: <%s>" CRLF, (char *)cur->data); - cur = g_list_next (cur); - } + case LMTP_WANT_GREETING: + if (!parse_mta_str (in, cd)) { + msg_warn ("mta_read_socket: got bad greeting"); + close_mta_connection (cd, FALSE); + return FALSE; + } + hostmax = sysconf (_SC_HOST_NAME_MAX) + 1; + hostbuf = alloca (hostmax); + gethostname (hostbuf, hostmax); + hostbuf[hostmax - 1] = '\0'; + if (cd->task->cfg->deliver_lmtp) { + r = snprintf (outbuf, sizeof (outbuf), "LHLO %s" CRLF, hostbuf); + } + else { + r = snprintf (outbuf, sizeof (outbuf), "HELO %s" CRLF, hostbuf); + } + rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); + cd->state = LMTP_WANT_MAIL; + break; + case LMTP_WANT_MAIL: + if (!parse_mta_str (in, cd)) { + msg_warn ("mta_read_socket: got bad helo"); + close_mta_connection (cd, FALSE); + return FALSE; + } + r = snprintf (outbuf, sizeof (outbuf), "MAIL FROM: <%s>" CRLF, cd->task->from); + rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); + cd->state = LMTP_WANT_RCPT; + break; + case LMTP_WANT_RCPT: + if (!parse_mta_str (in, cd)) { + msg_warn ("mta_read_socket: got bad mail from"); + close_mta_connection (cd, FALSE); + return FALSE; + } + cur = g_list_first (cd->task->rcpt); + r = 0; + while (cur) { + r += snprintf (outbuf + r, sizeof (outbuf) - r, "RCPT TO: <%s>" CRLF, (char *)cur->data); + cur = g_list_next (cur); + } - rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); - cd->state = LMTP_WANT_DATA; - break; - case LMTP_WANT_DATA: - if (!parse_mta_str (in, cd)) { - msg_warn ("mta_read_socket: got bad rcpt"); - close_mta_connection (cd, FALSE); - return FALSE; - } - r = snprintf (outbuf, sizeof (outbuf), "DATA" CRLF); - rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); - cd->state = LMTP_WANT_DOT; - break; - case LMTP_WANT_DOT: - if (!parse_mta_str (in, cd)) { - msg_warn ("mta_read_socket: got bad data"); - close_mta_connection (cd, FALSE); - return FALSE; - } - c = g_mime_object_to_string ((GMimeObject *)cd->task->message); - r = strlen (c); - rspamd_dispatcher_write (cd->task->dispatcher, c, r, TRUE, TRUE); - memory_pool_add_destructor (cd->task->task_pool, (pool_destruct_func)g_free, c); - r = snprintf (outbuf, sizeof (outbuf), CRLF "." CRLF); - rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); - cd->state = LMTP_WANT_CLOSING; - case LMTP_WANT_CLOSING: - if (!parse_mta_str (in, cd)) { - msg_warn ("mta_read_socket: message not delivered"); - close_mta_connection (cd, FALSE); - return FALSE; - } - close_mta_connection (cd, TRUE); - break; + rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); + cd->state = LMTP_WANT_DATA; + break; + case LMTP_WANT_DATA: + if (!parse_mta_str (in, cd)) { + msg_warn ("mta_read_socket: got bad rcpt"); + close_mta_connection (cd, FALSE); + return FALSE; + } + r = snprintf (outbuf, sizeof (outbuf), "DATA" CRLF); + rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); + cd->state = LMTP_WANT_DOT; + break; + case LMTP_WANT_DOT: + if (!parse_mta_str (in, cd)) { + msg_warn ("mta_read_socket: got bad data"); + close_mta_connection (cd, FALSE); + return FALSE; + } + c = g_mime_object_to_string ((GMimeObject *) cd->task->message); + r = strlen (c); + rspamd_dispatcher_write (cd->task->dispatcher, c, r, TRUE, TRUE); + memory_pool_add_destructor (cd->task->task_pool, (pool_destruct_func) g_free, c); + r = snprintf (outbuf, sizeof (outbuf), CRLF "." CRLF); + rspamd_dispatcher_write (cd->task->dispatcher, outbuf, r, FALSE, FALSE); + cd->state = LMTP_WANT_CLOSING; + case LMTP_WANT_CLOSING: + if (!parse_mta_str (in, cd)) { + msg_warn ("mta_read_socket: message not delivered"); + close_mta_connection (cd, FALSE); + return FALSE; + } + close_mta_connection (cd, TRUE); + break; } return TRUE; @@ -406,9 +404,9 @@ mta_read_socket (f_str_t *in, void *arg) * Called if something goes wrong */ static void -mta_err_socket (GError *err, void *arg) +mta_err_socket (GError * err, void *arg) { - struct mta_callback_data *cd = (struct mta_callback_data *)arg; + struct mta_callback_data *cd = (struct mta_callback_data *)arg; msg_info ("mta_err_socket: abnormaly terminating connection with MTA"); close_mta_connection (cd, FALSE); } @@ -419,10 +417,10 @@ mta_err_socket (GError *err, void *arg) static int lmtp_deliver_mta (struct worker_task *task) { - int sock; - struct sockaddr_un *un; - struct mta_callback_data *cd; - + int sock; + struct sockaddr_un *un; + struct mta_callback_data *cd; + if (task->cfg->deliver_family == AF_UNIX) { un = alloca (sizeof (struct sockaddr_un)); sock = make_unix_socket (task->cfg->deliver_host, un, FALSE); @@ -433,94 +431,92 @@ lmtp_deliver_mta (struct worker_task *task) if (sock == -1) { msg_warn ("lmtp_deliver_mta: cannot create socket for %s, %s", task->cfg->deliver_host, strerror (errno)); } - + cd = memory_pool_alloc (task->task_pool, sizeof (struct mta_callback_data)); cd->task = task; cd->state = LMTP_WANT_GREETING; - cd->dispatcher = rspamd_create_dispatcher (sock, BUFFER_LINE, mta_read_socket, - NULL, mta_err_socket, NULL, - (void *)cd); + cd->dispatcher = rspamd_create_dispatcher (sock, BUFFER_LINE, mta_read_socket, NULL, mta_err_socket, NULL, (void *)cd); return 0; } -static char* +static char * format_lda_args (struct worker_task *task) { - char *res, *c, *r; - size_t len; - GList *rcpt; - gboolean got_args = FALSE; + char *res, *c, *r; + size_t len; + GList *rcpt; + gboolean got_args = FALSE; c = task->cfg->deliver_agent_path; /* Find first arg */ if ((c = strchr (c, ' ')) == NULL) { return task->cfg->deliver_agent_path; } - + /* Calculate length of result string */ len = strlen (task->cfg->deliver_agent_path); while (*c) { if (*c == '%') { c++; switch (*c) { - case 'f': - /* Insert from */ - len += strlen (task->from) - 2; - break; - case 'r': - /* Insert list of recipients */ - rcpt = g_list_first (task->rcpt); - len -= 2; - while (rcpt) { - len += strlen ((char *)rcpt->data) + 1; - rcpt = g_list_next (rcpt); - } - break; + case 'f': + /* Insert from */ + len += strlen (task->from) - 2; + break; + case 'r': + /* Insert list of recipients */ + rcpt = g_list_first (task->rcpt); + len -= 2; + while (rcpt) { + len += strlen ((char *)rcpt->data) + 1; + rcpt = g_list_next (rcpt); + } + break; } } - c ++; - len ++; + c++; + len++; } res = memory_pool_alloc (task->task_pool, len + 1); r = res; c = task->cfg->deliver_agent_path; - + while (*c) { if (*c == ' ') { got_args = TRUE; } if (got_args && *c == '%') { switch (*(c + 1)) { - case 'f': - /* Insert from */ - c += 2; - len = strlen (task->from); - memcpy (r, task->from, len); + case 'f': + /* Insert from */ + c += 2; + len = strlen (task->from); + memcpy (r, task->from, len); + r += len; + break; + case 'r': + /* Insert list of recipients */ + c += 2; + rcpt = g_list_first (task->rcpt); + while (rcpt) { + len = strlen ((char *)rcpt->data) + 1; + memcpy (r, rcpt->data, len); r += len; - break; - case 'r': - /* Insert list of recipients */ - c += 2; - rcpt = g_list_first (task->rcpt); - while (rcpt) { - len = strlen ((char *)rcpt->data) + 1; - memcpy (r, rcpt->data, len); - r += len; - *r++ = ' '; - rcpt = g_list_next (rcpt); - } - break; - default: - *r = *c; - r ++; - c ++; - break; + *r++ = ' '; + rcpt = g_list_next (rcpt); + } + break; + default: + *r = *c; + r++; + c++; + break; } } else { *r = *c; - r ++; - c ++; + r++; + c++; } } @@ -530,15 +526,15 @@ format_lda_args (struct worker_task *task) static int lmtp_deliver_lda (struct worker_task *task) { - char *args, **argv; - GMimeStream *stream; - int rc, ecode, p[2], argc; - pid_t cpid, pid; + char *args, **argv; + GMimeStream *stream; + int rc, ecode, p[2], argc; + pid_t cpid, pid; if ((args = format_lda_args (task)) == NULL) { return -1; } - + /* Format arguments in shell style */ if (!g_shell_parse_argv (args, &argc, &argv, NULL)) { msg_info ("lmtp_deliver_lda: cannot parse arguments"); @@ -550,7 +546,7 @@ lmtp_deliver_lda (struct worker_task *task) msg_info ("lmtp_deliver_lda: cannot open pipe: %s", strerror (errno)); return -1; } - + /* Fork to exec LDA */ #ifdef HAVE_VFORK if ((cpid = vfork ()) == -1) { @@ -558,7 +554,7 @@ lmtp_deliver_lda (struct worker_task *task) msg_info ("lmtp_deliver_lda: cannot fork: %s", strerror (errno)); return -1; } -#else +#else if ((cpid = fork ()) == -1) { g_strfreev (argv); msg_info ("lmtp_deliver_lda: cannot fork: %s", strerror (errno)); @@ -571,18 +567,18 @@ lmtp_deliver_lda (struct worker_task *task) close (p[1]); /* Set standart IO descriptors */ if (p[0] != STDIN_FILENO) { - (void)dup2(p[0], STDIN_FILENO); - (void)close(p[0]); + (void)dup2 (p[0], STDIN_FILENO); + (void)close (p[0]); } execv (argv[0], argv); _exit (127); } - + close (p[0]); stream = g_mime_stream_fs_new (p[1]); - if (g_mime_object_write_to_stream ((GMimeObject *)task->message, stream) == -1) { + if (g_mime_object_write_to_stream ((GMimeObject *) task->message, stream) == -1) { g_strfreev (argv); msg_info ("lmtp_deliver_lda: cannot write stream to lda"); return -1; @@ -593,14 +589,14 @@ lmtp_deliver_lda (struct worker_task *task) #if defined(HAVE_WAIT4) do { - pid = wait4(cpid, &rc, 0, NULL); + pid = wait4 (cpid, &rc, 0, NULL); } while (pid == -1 && errno == EINTR); #elif defined(HAVE_WAITPID) do { - pid = waitpid(cpid, &rc, 0); + pid = waitpid (cpid, &rc, 0); } while (pid == -1 && errno == EINTR); #else -#error wait mechanisms are undefined +# error wait mechanisms are undefined #endif if (rc == -1) { g_strfreev (argv); @@ -640,7 +636,7 @@ lmtp_deliver_message (struct worker_task *task) int write_lmtp_reply (struct rspamd_lmtp_proto *lmtp) { - int r; + int r; msg_debug ("write_lmtp_reply: writing reply to client"); if (lmtp->task->error_code != 0) { diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index b52e88df2..05829db97 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -27,79 +27,79 @@ /* Lua module init function */ #define MODULE_INIT_FUNC "module_init" -lua_State *L = NULL; -const luaL_reg null_reg[] = { +lua_State *L = NULL; +const luaL_reg null_reg[] = { {"__tostring", lua_class_tostring}, - {NULL, NULL} + {NULL, NULL} }; /* Logger methods */ -LUA_FUNCTION_DEF(logger, err); -LUA_FUNCTION_DEF(logger, warn); -LUA_FUNCTION_DEF(logger, info); -LUA_FUNCTION_DEF(logger, debug); - -static const struct luaL_reg loggerlib_m[] = { - LUA_INTERFACE_DEF(logger, err), - LUA_INTERFACE_DEF(logger, warn), - LUA_INTERFACE_DEF(logger, info), - LUA_INTERFACE_DEF(logger, debug), +LUA_FUNCTION_DEF (logger, err); +LUA_FUNCTION_DEF (logger, warn); +LUA_FUNCTION_DEF (logger, info); +LUA_FUNCTION_DEF (logger, debug); + +static const struct luaL_reg loggerlib_m[] = { + LUA_INTERFACE_DEF (logger, err), + LUA_INTERFACE_DEF (logger, warn), + LUA_INTERFACE_DEF (logger, info), + LUA_INTERFACE_DEF (logger, debug), {"__tostring", lua_class_tostring}, - {NULL, NULL} + {NULL, NULL} }; /* Util functions */ -void -lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func) +void +lua_newclass (lua_State * L, const char *classname, const struct luaL_reg *func) { - luaL_newmetatable (L, classname); /* mt */ - lua_pushstring(L, "__index"); - lua_pushvalue(L, -2); /* pushes the metatable */ - lua_settable(L, -3); /* metatable.__index = metatable */ - - lua_pushstring (L, "class"); /* mt,"__index",it,"class" */ - lua_pushstring (L, classname); /* mt,"__index",it,"class",classname */ - lua_rawset (L, -3); /* mt,"__index",it */ - - luaL_openlib(L, NULL, func, 0); + luaL_newmetatable (L, classname); /* mt */ + lua_pushstring (L, "__index"); + lua_pushvalue (L, -2); /* pushes the metatable */ + lua_settable (L, -3); /* metatable.__index = metatable */ + + lua_pushstring (L, "class"); /* mt,"__index",it,"class" */ + lua_pushstring (L, classname); /* mt,"__index",it,"class",classname */ + lua_rawset (L, -3); /* mt,"__index",it */ + + luaL_openlib (L, NULL, func, 0); } -int -lua_class_tostring (lua_State *L) +int +lua_class_tostring (lua_State * L) { - char buf[32]; + char buf[32]; if (!lua_getmetatable (L, 1)) { goto error; } - lua_pushstring (L, "__index"); - lua_gettable (L, -2); + lua_pushstring (L, "__index"); + lua_gettable (L, -2); - if (!lua_istable (L, -1)) { - goto error; + if (!lua_istable (L, -1)) { + goto error; } - lua_pushstring (L, "class"); - lua_gettable (L, -2); + lua_pushstring (L, "class"); + lua_gettable (L, -2); - if (!lua_isstring (L, -1)) { + if (!lua_isstring (L, -1)) { goto error; } - snprintf (buf, sizeof (buf), "%p", lua_touserdata (L, 1)); + snprintf (buf, sizeof (buf), "%p", lua_touserdata (L, 1)); - lua_pushfstring (L, "%s: %s", lua_tostring (L, -1), buf); + lua_pushfstring (L, "%s: %s", lua_tostring (L, -1), buf); - return 1; + return 1; -error: - lua_pushstring (L, "invalid object passed to 'lua_common.c:__tostring'"); - lua_error (L); - return 1; + error: + lua_pushstring (L, "invalid object passed to 'lua_common.c:__tostring'"); + lua_error (L); + return 1; } -void -lua_setclass (lua_State *L, const char *classname, int objidx) +void +lua_setclass (lua_State * L, const char *classname, int objidx) { luaL_getmetatable (L, classname); if (objidx < 0) { @@ -109,75 +109,75 @@ lua_setclass (lua_State *L, const char *classname, int objidx) } /* assume that table is at the top */ -void -lua_set_table_index (lua_State *L, const char *index, const char *value) +void +lua_set_table_index (lua_State * L, const char *index, const char *value) { lua_pushstring (L, index); lua_pushstring (L, value); - lua_settable(L, -3); + lua_settable (L, -3); } /*** Logger interface ***/ static int -lua_logger_err (lua_State *L) +lua_logger_err (lua_State * L) { - const char *msg; - msg = luaL_checkstring (L, 1); - msg_err (msg); - return 1; + const char *msg; + msg = luaL_checkstring (L, 1); + msg_err (msg); + return 1; } static int -lua_logger_warn (lua_State *L) +lua_logger_warn (lua_State * L) { - const char *msg; - msg = luaL_checkstring (L, 1); - msg_warn (msg); - return 1; + const char *msg; + msg = luaL_checkstring (L, 1); + msg_warn (msg); + return 1; } static int -lua_logger_info (lua_State *L) +lua_logger_info (lua_State * L) { - const char *msg; - msg = luaL_checkstring (L, 1); - msg_info (msg); - return 1; + const char *msg; + msg = luaL_checkstring (L, 1); + msg_info (msg); + return 1; } static int -lua_logger_debug (lua_State *L) +lua_logger_debug (lua_State * L) { - const char *msg; - msg = luaL_checkstring (L, 1); - msg_debug (msg); - return 1; + const char *msg; + msg = luaL_checkstring (L, 1); + msg_debug (msg); + return 1; } /*** Init functions ***/ int -luaopen_rspamd (lua_State *L) +luaopen_rspamd (lua_State * L) { - luaL_openlib(L, "rspamd", null_reg, 0); - /* make version string available to scripts */ - lua_pushstring(L, "_VERSION"); - lua_pushstring(L, RVERSION); - lua_rawset(L, -3); - + luaL_openlib (L, "rspamd", null_reg, 0); + /* make version string available to scripts */ + lua_pushstring (L, "_VERSION"); + lua_pushstring (L, RVERSION); + lua_rawset (L, -3); + return 1; } int -luaopen_logger (lua_State *L) +luaopen_logger (lua_State * L) { luaL_openlib (L, "rspamd_logger", loggerlib_m, 0); - return 1; + return 1; } static void @@ -186,13 +186,13 @@ init_lua () if (L == NULL) { L = lua_open (); luaL_openlibs (L); - - (void)luaopen_rspamd (L); - (void)luaopen_logger (L); - (void)luaopen_config (L); - (void)luaopen_metric (L); + + (void)luaopen_rspamd (L); + (void)luaopen_logger (L); + (void)luaopen_config (L); + (void)luaopen_metric (L); (void)luaopen_task (L); - (void)luaopen_textpart (L); + (void)luaopen_textpart (L); (void)luaopen_message (L); } } @@ -200,10 +200,10 @@ init_lua () void init_lua_filters (struct config_file *cfg) { - struct config_file **pcfg; - GList *cur; - struct script_module *module; - + struct config_file **pcfg; + GList *cur; + struct script_module *module; + init_lua (); cur = g_list_first (cfg->script_modules); while (cur) { @@ -211,17 +211,17 @@ init_lua_filters (struct config_file *cfg) if (module->path) { if (luaL_loadfile (L, module->path) != 0) { msg_info ("lua_init_filters: load of %s failed: %s", module->path, lua_tostring (L, -1)); - cur = g_list_next (cur); - continue; - } + cur = g_list_next (cur); + continue; + } /* Call module init function */ pcfg = lua_newuserdata (L, sizeof (struct config_file *)); lua_setclass (L, "rspamd{config}", -1); *pcfg = cfg; - lua_setglobal (L, "rspamd_config"); + lua_setglobal (L, "rspamd_config"); /* do the call (1 arguments, 1 result) */ - if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0) { + if (lua_pcall (L, 0, LUA_MULTRET, 0) != 0) { msg_info ("lua_init_filters: init of %s failed: %s", module->path, lua_tostring (L, -1)); } } @@ -234,14 +234,14 @@ init_lua_filters (struct config_file *cfg) int lua_call_filter (const char *function, struct worker_task *task) { - int result; - struct worker_task **ptask; + int result; + struct worker_task **ptask; lua_getglobal (L, function); ptask = lua_newuserdata (L, sizeof (struct worker_task *)); lua_setclass (L, "rspamd{task}", -1); *ptask = task; - + if (lua_pcall (L, 1, 1, 0) != 0) { msg_info ("lua_call_filter: call to %s failed", function); } @@ -251,18 +251,18 @@ lua_call_filter (const char *function, struct worker_task *task) msg_info ("lua_call_filter: function %s must return a number", function); } result = lua_tonumber (L, -1); - lua_pop (L, 1); /* pop returned value */ + lua_pop (L, 1); /* pop returned value */ return result; } int lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number) { - int result, i; + int result, i; lua_getglobal (L, function); - for (i = 0; i < number; i ++) { + for (i = 0; i < number; i++) { lua_pushnumber (L, marks[i]); } if (lua_pcall (L, number, 1, 0) != 0) { @@ -274,7 +274,7 @@ lua_call_chain_filter (const char *function, struct worker_task *task, int *mark msg_info ("lua_call_header_filter: function %s must return a number", function); } result = lua_tonumber (L, -1); - lua_pop (L, 1); /* pop returned value */ + lua_pop (L, 1); /* pop returned value */ return result; } @@ -282,16 +282,16 @@ lua_call_chain_filter (const char *function, struct worker_task *task, int *mark * LUA custom consolidation function */ struct consolidation_callback_data { - struct worker_task *task; - double score; - const char *func; + struct worker_task *task; + double score; + const char *func; }; static void lua_consolidation_callback (gpointer key, gpointer value, gpointer arg) { - double res; - struct symbol *s = (struct symbol *)value; + double res; + struct symbol *s = (struct symbol *)value; struct consolidation_callback_data *data = (struct consolidation_callback_data *)arg; lua_getglobal (L, data->func); @@ -307,15 +307,15 @@ lua_consolidation_callback (gpointer key, gpointer value, gpointer arg) msg_info ("lua_consolidation_callback: function %s must return a number", data->func); } res = lua_tonumber (L, -1); - lua_pop (L, 1); /* pop returned value */ + lua_pop (L, 1); /* pop returned value */ data->score += res; } double lua_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name) { - struct metric_result *metric_res; - double res = 0.; + struct metric_result *metric_res; + double res = 0.; struct consolidation_callback_data data = { task, 0, function_name }; if (function_name == NULL) { @@ -335,13 +335,12 @@ lua_consolidation_func (struct worker_task *task, const char *metric_name, const void add_luabuf (const char *line) { - int error; + int error; init_lua (); - error = luaL_loadbuffer(L, line, strlen(line), "config") || - lua_pcall(L, 0, 0, 0); + error = luaL_loadbuffer (L, line, strlen (line), "config") || lua_pcall (L, 0, 0, 0); if (error) { - yyerror ("lua error: %s", lua_tostring(L, -1)); - lua_pop(L, 1); /* pop error message from the stack */ + yyerror ("lua error: %s", lua_tostring (L, -1)); + lua_pop (L, 1); /* pop error message from the stack */ } } diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index f62f45bef..8ddf8cd1d 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -26,84 +26,84 @@ #include "lua_common.h" /* Config file methods */ -LUA_FUNCTION_DEF(config, get_module_opt); -LUA_FUNCTION_DEF(config, get_metric); -LUA_FUNCTION_DEF(config, get_all_opt); - -static const struct luaL_reg configlib_m[] = { - LUA_INTERFACE_DEF(config, get_module_opt), - LUA_INTERFACE_DEF(config, get_metric), - LUA_INTERFACE_DEF(config, get_all_opt), +LUA_FUNCTION_DEF (config, get_module_opt); +LUA_FUNCTION_DEF (config, get_metric); +LUA_FUNCTION_DEF (config, get_all_opt); + +static const struct luaL_reg configlib_m[] = { + LUA_INTERFACE_DEF (config, get_module_opt), + LUA_INTERFACE_DEF (config, get_metric), + LUA_INTERFACE_DEF (config, get_all_opt), {"__tostring", lua_class_tostring}, - {NULL, NULL} + {NULL, NULL} }; /* Metric methods */ -LUA_FUNCTION_DEF(metric, register_symbol); +LUA_FUNCTION_DEF (metric, register_symbol); -static const struct luaL_reg metriclib_m[] = { - LUA_INTERFACE_DEF(metric, register_symbol), +static const struct luaL_reg metriclib_m[] = { + LUA_INTERFACE_DEF (metric, register_symbol), {"__tostring", lua_class_tostring}, {NULL, NULL} }; -static struct config_file * -lua_check_config (lua_State *L) +static struct config_file * +lua_check_config (lua_State * L) { - void *ud = luaL_checkudata (L, 1, "rspamd{config}"); + void *ud = luaL_checkudata (L, 1, "rspamd{config}"); luaL_argcheck (L, ud != NULL, 1, "'config' expected"); return *((struct config_file **)ud); } -static struct metric * -lua_check_metric (lua_State *L) +static struct metric * +lua_check_metric (lua_State * L) { - void *ud = luaL_checkudata (L, 1, "rspamd{metric}"); + void *ud = luaL_checkudata (L, 1, "rspamd{metric}"); luaL_argcheck (L, ud != NULL, 1, "'metric' expected"); return *((struct metric **)ud); } /*** Config functions ***/ static int -lua_config_get_module_opt (lua_State *L) +lua_config_get_module_opt (lua_State * L) { - struct config_file *cfg = lua_check_config (L); - const char *mname, *optname, *val; - - if (cfg) { - mname = luaL_checkstring (L, 2); - optname = luaL_checkstring (L, 3); - - if (mname && optname) { - val = get_module_opt (cfg, (char *)mname, (char *)optname); - if (val) { - lua_pushstring (L, val); - return 1; - } - } - } - lua_pushnil (L); - return 1; + struct config_file *cfg = lua_check_config (L); + const char *mname, *optname, *val; + + if (cfg) { + mname = luaL_checkstring (L, 2); + optname = luaL_checkstring (L, 3); + + if (mname && optname) { + val = get_module_opt (cfg, (char *)mname, (char *)optname); + if (val) { + lua_pushstring (L, val); + return 1; + } + } + } + lua_pushnil (L); + return 1; } static int -lua_config_get_all_opt (lua_State *L) +lua_config_get_all_opt (lua_State * L) { - struct config_file *cfg = lua_check_config (L); - const char *mname; - GList *cur_opt; - struct module_opt *cur; + struct config_file *cfg = lua_check_config (L); + const char *mname; + GList *cur_opt; + struct module_opt *cur; - if (cfg) { - mname = luaL_checkstring (L, 2); + if (cfg) { + mname = luaL_checkstring (L, 2); - if (mname) { + if (mname) { cur_opt = g_hash_table_lookup (cfg->modules_opts, mname); if (cur_opt == NULL) { lua_pushnil (L); return 1; } - + lua_newtable (L); while (cur_opt) { cur = cur_opt->data; @@ -111,67 +111,66 @@ lua_config_get_all_opt (lua_State *L) cur_opt = g_list_next (cur_opt); } return 1; - } - } - lua_pushnil (L); - return 1; + } + } + lua_pushnil (L); + return 1; } static int -lua_config_get_metric (lua_State *L) +lua_config_get_metric (lua_State * L) { - struct config_file *cfg = lua_check_config (L); - struct metric *metric, **pmetric; - const char *name; - - if (cfg) { - name = luaL_checkstring (L, 2); - metric = g_hash_table_lookup (cfg->metrics, name); - if (metric) { - pmetric = lua_newuserdata (L, sizeof (struct metric *)); - lua_setclass (L, "rspamd{metric}", -1); - *pmetric = metric; + struct config_file *cfg = lua_check_config (L); + struct metric *metric, **pmetric; + const char *name; + + if (cfg) { + name = luaL_checkstring (L, 2); + metric = g_hash_table_lookup (cfg->metrics, name); + if (metric) { + pmetric = lua_newuserdata (L, sizeof (struct metric *)); + lua_setclass (L, "rspamd{metric}", -1); + *pmetric = metric; return 1; - } - } + } + } + + lua_pushnil (L); + return 1; - lua_pushnil (L); - return 1; - } /*** Metric functions ***/ struct lua_callback_data { - const char *name; - lua_State *L; + const char *name; + lua_State *L; }; static void lua_metric_symbol_callback (struct worker_task *task, gpointer ud) { - struct lua_callback_data *cd = ud; - struct worker_task **ptask; + struct lua_callback_data *cd = ud; + struct worker_task **ptask; lua_getglobal (cd->L, cd->name); ptask = lua_newuserdata (cd->L, sizeof (struct worker_task *)); lua_setclass (cd->L, "rspamd{task}", -1); *ptask = task; - if (lua_pcall(cd->L, 1, 1, 0) != 0) { - msg_warn ("lua_metric_symbol_callback: error running function %s: %s", - cd->name, lua_tostring(cd->L, -1)); + if (lua_pcall (cd->L, 1, 1, 0) != 0) { + msg_warn ("lua_metric_symbol_callback: error running function %s: %s", cd->name, lua_tostring (cd->L, -1)); } } static int -lua_metric_register_symbol (lua_State *L) +lua_metric_register_symbol (lua_State * L) { - struct metric *metric = lua_check_metric (L); - const char *name, *callback; - double weight; - struct lua_callback_data *cd; + struct metric *metric = lua_check_metric (L); + const char *name, *callback; + double weight; + struct lua_callback_data *cd; if (metric) { name = g_strdup (luaL_checkstring (L, 2)); @@ -180,7 +179,7 @@ lua_metric_register_symbol (lua_State *L) if (name) { cd = g_malloc (sizeof (struct lua_callback_data)); cd->name = g_strdup (callback); - cd->L = L; + cd->L = L; register_symbol (&metric->cache, name, weight, lua_metric_symbol_callback, cd); } } @@ -188,19 +187,19 @@ lua_metric_register_symbol (lua_State *L) } int -luaopen_config (lua_State *L) +luaopen_config (lua_State * L) { - lua_newclass (L, "rspamd{config}", configlib_m); + lua_newclass (L, "rspamd{config}", configlib_m); luaL_openlib (L, "rspamd_config", null_reg, 0); - return 1; + return 1; } int -luaopen_metric (lua_State *L) +luaopen_metric (lua_State * L) { - lua_newclass (L, "rspamd{metric}", metriclib_m); + lua_newclass (L, "rspamd{metric}", metriclib_m); luaL_openlib (L, "rspamd_metric", null_reg, 0); - return 1; + return 1; } diff --git a/src/lua/lua_message.c b/src/lua/lua_message.c index 12d3c05cb..a6a12213a 100644 --- a/src/lua/lua_message.c +++ b/src/lua/lua_message.c @@ -38,7 +38,7 @@ lua_##class##_##name(lua_State *L) \ lua_pushnil (L); \ } \ return 1; \ -} +} #define LUA_GMIME_BRIDGE_SET(class, name, mime_class) \ static int \ @@ -54,64 +54,64 @@ lua_##class##_##name(lua_State *L) \ lua_pushnil (L); \ } \ return 1; \ -} +} /* Message methods */ -LUA_FUNCTION_DEF(message, get_subject); -LUA_FUNCTION_DEF(message, set_subject); -LUA_FUNCTION_DEF(message, get_message_id); -LUA_FUNCTION_DEF(message, set_message_id); -LUA_FUNCTION_DEF(message, get_sender); -LUA_FUNCTION_DEF(message, set_sender); -LUA_FUNCTION_DEF(message, get_reply_to); -LUA_FUNCTION_DEF(message, set_reply_to); -LUA_FUNCTION_DEF(message, get_header); -LUA_FUNCTION_DEF(message, set_header); - -static const struct luaL_reg msglib_m[] = { - LUA_INTERFACE_DEF(message, get_subject), - LUA_INTERFACE_DEF(message, set_subject), - LUA_INTERFACE_DEF(message, get_message_id), - LUA_INTERFACE_DEF(message, set_message_id), - LUA_INTERFACE_DEF(message, get_sender), - LUA_INTERFACE_DEF(message, set_sender), - LUA_INTERFACE_DEF(message, get_reply_to), - LUA_INTERFACE_DEF(message, set_reply_to), - LUA_INTERFACE_DEF(message, get_header), - LUA_INTERFACE_DEF(message, set_header), +LUA_FUNCTION_DEF (message, get_subject); +LUA_FUNCTION_DEF (message, set_subject); +LUA_FUNCTION_DEF (message, get_message_id); +LUA_FUNCTION_DEF (message, set_message_id); +LUA_FUNCTION_DEF (message, get_sender); +LUA_FUNCTION_DEF (message, set_sender); +LUA_FUNCTION_DEF (message, get_reply_to); +LUA_FUNCTION_DEF (message, set_reply_to); +LUA_FUNCTION_DEF (message, get_header); +LUA_FUNCTION_DEF (message, set_header); + +static const struct luaL_reg msglib_m[] = { + LUA_INTERFACE_DEF (message, get_subject), + LUA_INTERFACE_DEF (message, set_subject), + LUA_INTERFACE_DEF (message, get_message_id), + LUA_INTERFACE_DEF (message, set_message_id), + LUA_INTERFACE_DEF (message, get_sender), + LUA_INTERFACE_DEF (message, set_sender), + LUA_INTERFACE_DEF (message, get_reply_to), + LUA_INTERFACE_DEF (message, set_reply_to), + LUA_INTERFACE_DEF (message, get_header), + LUA_INTERFACE_DEF (message, set_header), {"__tostring", lua_class_tostring}, {NULL, NULL} }; -static GMimeMessage * -lua_check_message (lua_State *L) +static GMimeMessage * +lua_check_message (lua_State * L) { - void *ud = luaL_checkudata (L, 1, "rspamd{message}"); + void *ud = luaL_checkudata (L, 1, "rspamd{message}"); luaL_argcheck (L, ud != NULL, 1, "'message' expected"); - return *((GMimeMessage **)ud); + return *((GMimeMessage **) ud); } /*** Message interface ***/ -LUA_GMIME_BRIDGE_GET(message, get_subject, Message) -LUA_GMIME_BRIDGE_SET(message, set_subject, Message) -LUA_GMIME_BRIDGE_GET(message, get_message_id, Message) -LUA_GMIME_BRIDGE_SET(message, set_message_id, Message) -LUA_GMIME_BRIDGE_GET(message, get_sender, Message) -LUA_GMIME_BRIDGE_SET(message, set_sender, Message) -LUA_GMIME_BRIDGE_GET(message, get_reply_to, Message) -LUA_GMIME_BRIDGE_SET(message, set_reply_to, Message) - -static int -lua_message_get_header (lua_State *L) +LUA_GMIME_BRIDGE_GET (message, get_subject, Message) + LUA_GMIME_BRIDGE_SET (message, set_subject, Message) + LUA_GMIME_BRIDGE_GET (message, get_message_id, Message) + LUA_GMIME_BRIDGE_SET (message, set_message_id, Message) + LUA_GMIME_BRIDGE_GET (message, get_sender, Message) + LUA_GMIME_BRIDGE_SET (message, set_sender, Message) + LUA_GMIME_BRIDGE_GET (message, get_reply_to, Message) + LUA_GMIME_BRIDGE_SET (message, set_reply_to, Message) + + static int + lua_message_get_header (lua_State * L) { - const char *headern; - GMimeMessage *obj = lua_check_message (L); - GList *res = NULL, *cur; - int i = 1; + const char *headern; + GMimeMessage *obj = lua_check_message (L); + GList *res = NULL, *cur; + int i = 1; if (obj != NULL) { headern = luaL_checkstring (L, 2); @@ -119,10 +119,10 @@ lua_message_get_header (lua_State *L) res = message_get_header (NULL, obj, headern); if (res) { cur = res; - lua_newtable (L); + lua_newtable (L); while (cur) { lua_pushstring (L, (const char *)cur->data); - lua_rawseti(L, -2, i++); + lua_rawseti (L, -2, i++); g_free (cur->data); cur = g_list_next (cur); } @@ -145,10 +145,10 @@ lua_message_get_header (lua_State *L) static int -lua_message_set_header (lua_State *L) +lua_message_set_header (lua_State * L) { - const char *headern, *headerv; - GMimeMessage *obj = lua_check_message (L); + const char *headern, *headerv; + GMimeMessage *obj = lua_check_message (L); if (obj != NULL) { headern = luaL_checkstring (L, 2); @@ -163,17 +163,16 @@ lua_message_set_header (lua_State *L) else { lua_pushnil (L); } - + return 1; } int -luaopen_message (lua_State *L) +luaopen_message (lua_State * L) { lua_newclass (L, "rspamd{message}", msglib_m); luaL_openlib (L, "rspamd_message", null_reg, 0); - + return 1; } - diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 71e7f6224..a762cb660 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -29,68 +29,68 @@ #include <evdns.h> /* Task methods */ -LUA_FUNCTION_DEF(task, get_message); -LUA_FUNCTION_DEF(task, insert_result); -LUA_FUNCTION_DEF(task, get_urls); -LUA_FUNCTION_DEF(task, get_text_parts); -LUA_FUNCTION_DEF(task, get_raw_headers); -LUA_FUNCTION_DEF(task, get_received_headers); -LUA_FUNCTION_DEF(task, resolve_dns_a); -LUA_FUNCTION_DEF(task, resolve_dns_ptr); -LUA_FUNCTION_DEF(task, call_rspamd_function); - -static const struct luaL_reg tasklib_m[] = { - LUA_INTERFACE_DEF(task, get_message), - LUA_INTERFACE_DEF(task, insert_result), - LUA_INTERFACE_DEF(task, get_urls), - LUA_INTERFACE_DEF(task, get_text_parts), - LUA_INTERFACE_DEF(task, get_raw_headers), - LUA_INTERFACE_DEF(task, get_received_headers), - LUA_INTERFACE_DEF(task, resolve_dns_a), - LUA_INTERFACE_DEF(task, resolve_dns_ptr), - LUA_INTERFACE_DEF(task, call_rspamd_function), +LUA_FUNCTION_DEF (task, get_message); +LUA_FUNCTION_DEF (task, insert_result); +LUA_FUNCTION_DEF (task, get_urls); +LUA_FUNCTION_DEF (task, get_text_parts); +LUA_FUNCTION_DEF (task, get_raw_headers); +LUA_FUNCTION_DEF (task, get_received_headers); +LUA_FUNCTION_DEF (task, resolve_dns_a); +LUA_FUNCTION_DEF (task, resolve_dns_ptr); +LUA_FUNCTION_DEF (task, call_rspamd_function); + +static const struct luaL_reg tasklib_m[] = { + LUA_INTERFACE_DEF (task, get_message), + LUA_INTERFACE_DEF (task, insert_result), + LUA_INTERFACE_DEF (task, get_urls), + LUA_INTERFACE_DEF (task, get_text_parts), + LUA_INTERFACE_DEF (task, get_raw_headers), + LUA_INTERFACE_DEF (task, get_received_headers), + LUA_INTERFACE_DEF (task, resolve_dns_a), + LUA_INTERFACE_DEF (task, resolve_dns_ptr), + LUA_INTERFACE_DEF (task, call_rspamd_function), {"__tostring", lua_class_tostring}, {NULL, NULL} }; /* Textpart methods */ -LUA_FUNCTION_DEF(textpart, get_content); -LUA_FUNCTION_DEF(textpart, is_empty); -LUA_FUNCTION_DEF(textpart, is_html); -LUA_FUNCTION_DEF(textpart, get_fuzzy); - -static const struct luaL_reg textpartlib_m[] = { - LUA_INTERFACE_DEF(textpart, get_content), - LUA_INTERFACE_DEF(textpart, is_empty), - LUA_INTERFACE_DEF(textpart, is_html), - LUA_INTERFACE_DEF(textpart, get_fuzzy), +LUA_FUNCTION_DEF (textpart, get_content); +LUA_FUNCTION_DEF (textpart, is_empty); +LUA_FUNCTION_DEF (textpart, is_html); +LUA_FUNCTION_DEF (textpart, get_fuzzy); + +static const struct luaL_reg textpartlib_m[] = { + LUA_INTERFACE_DEF (textpart, get_content), + LUA_INTERFACE_DEF (textpart, is_empty), + LUA_INTERFACE_DEF (textpart, is_html), + LUA_INTERFACE_DEF (textpart, get_fuzzy), {"__tostring", lua_class_tostring}, {NULL, NULL} }; /* Utility functions */ -static struct worker_task * -lua_check_task (lua_State *L) +static struct worker_task * +lua_check_task (lua_State * L) { - void *ud = luaL_checkudata (L, 1, "rspamd{task}"); + void *ud = luaL_checkudata (L, 1, "rspamd{task}"); luaL_argcheck (L, ud != NULL, 1, "'task' expected"); return *((struct worker_task **)ud); } -static struct mime_text_part * -lua_check_textpart (lua_State *L) +static struct mime_text_part * +lua_check_textpart (lua_State * L) { - void *ud = luaL_checkudata (L, 1, "rspamd{textpart}"); + void *ud = luaL_checkudata (L, 1, "rspamd{textpart}"); luaL_argcheck (L, ud != NULL, 1, "'textpart' expected"); return *((struct mime_text_part **)ud); } /*** Task interface ***/ static int -lua_task_get_message (lua_State *L) +lua_task_get_message (lua_State * L) { - GMimeMessage **pmsg; - struct worker_task *task = lua_check_task (L); + GMimeMessage **pmsg; + struct worker_task *task = lua_check_task (L); if (task != NULL) { /* XXX write handler for message object */ @@ -101,14 +101,14 @@ lua_task_get_message (lua_State *L) return 1; } -static int -lua_task_insert_result (lua_State *L) +static int +lua_task_insert_result (lua_State * L) { - struct worker_task *task = lua_check_task (L); - const char *metric_name, *symbol_name, *param; - double flag; - GList *params = NULL; - int i, top; + struct worker_task *task = lua_check_task (L); + const char *metric_name, *symbol_name, *param; + double flag; + GList *params = NULL; + int i, top; if (task != NULL) { metric_name = memory_pool_strdup (task->task_pool, luaL_checkstring (L, 2)); @@ -116,7 +116,7 @@ lua_task_insert_result (lua_State *L) flag = luaL_checknumber (L, 4); top = lua_gettop (L); /* Get additional options */ - for (i = 5; i <= top; i ++) { + for (i = 5; i <= top; i++) { param = luaL_checkstring (L, i); params = g_list_prepend (params, memory_pool_strdup (task->task_pool, param)); } @@ -126,21 +126,21 @@ lua_task_insert_result (lua_State *L) return 1; } -static int -lua_task_get_urls (lua_State *L) +static int +lua_task_get_urls (lua_State * L) { - int i = 1; - struct worker_task *task = lua_check_task (L); - GList *cur; - struct uri *url; + int i = 1; + struct worker_task *task = lua_check_task (L); + GList *cur; + struct uri *url; if (task != NULL) { - lua_newtable (L); + lua_newtable (L); cur = g_list_first (task->urls); while (cur) { url = cur->data; lua_pushstring (L, struri (url)); - lua_rawseti(L, -2, i++); + lua_rawseti (L, -2, i++); cur = g_list_next (cur); } } @@ -149,55 +149,55 @@ lua_task_get_urls (lua_State *L) } static int -lua_task_get_text_parts (lua_State *L) +lua_task_get_text_parts (lua_State * L) { - int i = 1; - struct worker_task *task = lua_check_task (L); - GList *cur; - struct mime_text_part *part, **ppart; + int i = 1; + struct worker_task *task = lua_check_task (L); + GList *cur; + struct mime_text_part *part, **ppart; if (task != NULL) { - lua_newtable (L); + lua_newtable (L); cur = task->text_parts; while (cur) { part = cur->data; ppart = lua_newuserdata (L, sizeof (struct mime_text_part *)); *ppart = part; lua_setclass (L, "rspamd{textpart}", -1); - /* Make it array */ - lua_rawseti(L, -2, i++); + /* Make it array */ + lua_rawseti (L, -2, i++); cur = g_list_next (cur); } - return 1; + return 1; } lua_pushnil (L); return 1; } static int -lua_task_get_raw_headers (lua_State *L) +lua_task_get_raw_headers (lua_State * L) { - struct worker_task *task = lua_check_task (L); + struct worker_task *task = lua_check_task (L); - if (task) { + if (task) { lua_pushstring (L, task->raw_headers); - } + } else { lua_pushnil (L); } - return 1; + return 1; } static int -lua_task_get_received_headers (lua_State *L) +lua_task_get_received_headers (lua_State * L) { - struct worker_task *task = lua_check_task (L); - GList *cur; - struct received_header *rh; - int i = 1; + struct worker_task *task = lua_check_task (L); + GList *cur; + struct received_header *rh; + int i = 1; - if (task) { + if (task) { lua_newtable (L); cur = g_list_first (task->received); while (cur) { @@ -208,31 +208,31 @@ lua_task_get_received_headers (lua_State *L) lua_set_table_index (L, "real_hostname", rh->real_hostname); lua_set_table_index (L, "real_ip", rh->real_ip); lua_set_table_index (L, "by_hostname", rh->by_hostname); - lua_rawseti(L, -2, i++); + lua_rawseti (L, -2, i++); cur = g_list_next (cur); } - } + } else { lua_pushnil (L); } - + return 1; } struct lua_dns_callback_data { - lua_State *L; - struct worker_task *task; - const char *callback; - const char *to_resolve; + lua_State *L; + struct worker_task *task; + const char *callback; + const char *to_resolve; }; -static void +static void lua_dns_callback (int result, char type, int count, int ttl, void *addresses, void *arg) { - struct lua_dns_callback_data *cd = arg; - int i; - struct in_addr ina; - struct worker_task **ptask; + struct lua_dns_callback_data *cd = arg; + int i; + struct in_addr ina; + struct worker_task **ptask; lua_getglobal (cd->L, cd->callback); ptask = lua_newuserdata (cd->L, sizeof (struct worker_task *)); @@ -245,8 +245,8 @@ lua_dns_callback (int result, char type, int count, int ttl, void *addresses, vo if (type == DNS_IPv4_A) { lua_newtable (cd->L); - for (i = 1; i <= count; i ++) { - memcpy (&ina.s_addr, ((in_addr_t *)addresses) + i - 1, sizeof (in_addr_t)); + for (i = 1; i <= count; i++) { + memcpy (&ina.s_addr, ((in_addr_t *) addresses) + i - 1, sizeof (in_addr_t)); /* Actually this copy memory, so using of inet_ntoa is valid */ lua_pushstring (cd->L, inet_ntoa (ina)); lua_rawseti (cd->L, -2, i); @@ -255,7 +255,7 @@ lua_dns_callback (int result, char type, int count, int ttl, void *addresses, vo } else if (type == DNS_PTR) { lua_newtable (cd->L); - for (i = 1; i <= count; i ++) { + for (i = 1; i <= count; i++) { lua_pushstring (cd->L, ((char **)addresses)[i - 1]); lua_rawseti (cd->L, -2, i); } @@ -275,21 +275,21 @@ lua_dns_callback (int result, char type, int count, int ttl, void *addresses, vo msg_info ("lua_dns_callback: call to %s failed: %s", cd->callback, lua_tostring (cd->L, -1)); } - cd->task->save.saved --; + cd->task->save.saved--; if (cd->task->save.saved == 0) { /* Call other filters */ cd->task->save.saved = 1; process_filters (cd->task); } - remove_forced_event (cd->task->s, (event_finalizer_t)lua_dns_callback); + remove_forced_event (cd->task->s, (event_finalizer_t) lua_dns_callback); } static int -lua_task_resolve_dns_a (lua_State *L) +lua_task_resolve_dns_a (lua_State * L) { - struct worker_task *task = lua_check_task (L); - struct lua_dns_callback_data *cd; + struct worker_task *task = lua_check_task (L); + struct lua_dns_callback_data *cd; if (task) { cd = memory_pool_alloc (task->task_pool, sizeof (struct lua_dns_callback_data)); @@ -302,19 +302,19 @@ lua_task_resolve_dns_a (lua_State *L) return 0; } if (evdns_resolve_ipv4 (cd->to_resolve, DNS_QUERY_NO_SEARCH, lua_dns_callback, (void *)cd) == 0) { - task->save.saved ++; - register_async_event (task->s, (event_finalizer_t)lua_dns_callback, NULL, TRUE); - } + task->save.saved++; + register_async_event (task->s, (event_finalizer_t) lua_dns_callback, NULL, TRUE); + } } return 0; } static int -lua_task_resolve_dns_ptr (lua_State *L) +lua_task_resolve_dns_ptr (lua_State * L) { - struct worker_task *task = lua_check_task (L); - struct lua_dns_callback_data *cd; - struct in_addr *ina; + struct worker_task *task = lua_check_task (L); + struct lua_dns_callback_data *cd; + struct in_addr *ina; if (task) { cd = memory_pool_alloc (task->task_pool, sizeof (struct lua_dns_callback_data)); @@ -328,21 +328,21 @@ lua_task_resolve_dns_ptr (lua_State *L) return 0; } if (evdns_resolve_reverse (ina, DNS_QUERY_NO_SEARCH, lua_dns_callback, (void *)cd) == 0) { - task->save.saved ++; - register_async_event (task->s, (event_finalizer_t)lua_dns_callback, NULL, TRUE); - } + task->save.saved++; + register_async_event (task->s, (event_finalizer_t) lua_dns_callback, NULL, TRUE); + } } return 0; } static int -lua_task_call_rspamd_function (lua_State *L) +lua_task_call_rspamd_function (lua_State * L) { - struct worker_task *task = lua_check_task (L); - struct expression_function f; - int i, top; - gboolean res; - char *arg; + struct worker_task *task = lua_check_task (L); + struct expression_function f; + int i, top; + gboolean res; + char *arg; if (task) { f.name = (char *)luaL_checkstring (L, 2); @@ -350,7 +350,7 @@ lua_task_call_rspamd_function (lua_State *L) f.args = NULL; top = lua_gettop (L); /* Get arguments after function name */ - for (i = 3; i <= top; i ++) { + for (i = 3; i <= top; i++) { arg = (char *)luaL_checkstring (L, i); if (arg != NULL) { f.args = g_list_prepend (f.args, arg); @@ -376,24 +376,24 @@ lua_task_call_rspamd_function (lua_State *L) /**** Textpart implementation *****/ static int -lua_textpart_get_content (lua_State *L) +lua_textpart_get_content (lua_State * L) { - struct mime_text_part *part = lua_check_textpart (L); + struct mime_text_part *part = lua_check_textpart (L); if (part == NULL || part->is_empty) { lua_pushnil (L); return 1; } - + lua_pushlstring (L, part->content->data, part->content->len); return 1; } static int -lua_textpart_is_empty (lua_State *L) +lua_textpart_is_empty (lua_State * L) { - struct mime_text_part *part = lua_check_textpart (L); + struct mime_text_part *part = lua_check_textpart (L); if (part == NULL) { lua_pushnil (L); @@ -406,9 +406,9 @@ lua_textpart_is_empty (lua_State *L) } static int -lua_textpart_is_html (lua_State *L) +lua_textpart_is_html (lua_State * L) { - struct mime_text_part *part = lua_check_textpart (L); + struct mime_text_part *part = lua_check_textpart (L); if (part == NULL) { lua_pushnil (L); @@ -421,15 +421,15 @@ lua_textpart_is_html (lua_State *L) } static int -lua_textpart_get_fuzzy (lua_State *L) +lua_textpart_get_fuzzy (lua_State * L) { - struct mime_text_part *part = lua_check_textpart (L); + struct mime_text_part *part = lua_check_textpart (L); if (part == NULL || part->is_empty) { lua_pushnil (L); return 1; } - + lua_pushlstring (L, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); return 1; } @@ -437,20 +437,19 @@ lua_textpart_get_fuzzy (lua_State *L) /* Init part */ int -luaopen_task (lua_State *L) +luaopen_task (lua_State * L) { lua_newclass (L, "rspamd{task}", tasklib_m); luaL_openlib (L, "rspamd_task", null_reg, 0); - + return 1; } int -luaopen_textpart (lua_State *L) +luaopen_textpart (lua_State * L) { lua_newclass (L, "rspamd{textpart}", textpartlib_m); luaL_openlib (L, "rspamd_textpart", null_reg, 0); - + return 1; } - diff --git a/src/main.c b/src/main.c index 1c89efd5a..e600251b1 100644 --- a/src/main.c +++ b/src/main.c @@ -31,133 +31,132 @@ #ifndef WITHOUT_PERL -#include <EXTERN.h> /* from the Perl distribution */ -#include <perl.h> /* from the Perl distribution */ +# include <EXTERN.h> /* from the Perl distribution */ +# include <perl.h> /* from the Perl distribution */ -# ifndef PERL_IMPLICIT_CONTEXT -# undef dTHXa -# define dTHXa(a) -# endif -#include "perl.h" +# ifndef PERL_IMPLICIT_CONTEXT +# undef dTHXa +# define dTHXa(a) +# endif +# include "perl.h" #elif defined(WITH_LUA) -#include "lua/lua_common.h" +# include "lua/lua_common.h" #endif /* 2 seconds to fork new process in place of dead one */ #define SOFT_FORK_TIME 2 -struct config_file *cfg; +struct config_file *cfg; -rspamd_hash_t *counters; +rspamd_hash_t *counters; -static void sig_handler (int ); -static struct rspamd_worker * fork_worker (struct rspamd_main *, struct worker_conf *); - -sig_atomic_t do_restart; -sig_atomic_t do_terminate; -sig_atomic_t child_dead; -sig_atomic_t child_ready; -sig_atomic_t got_alarm; +static void sig_handler (int); +static struct rspamd_worker *fork_worker (struct rspamd_main *, struct worker_conf *); -extern int yynerrs; -extern FILE *yyin; +sig_atomic_t do_restart; +sig_atomic_t do_terminate; +sig_atomic_t child_dead; +sig_atomic_t child_ready; +sig_atomic_t got_alarm; -static int dump_vars = 0; -static int dump_cache = 0; +extern int yynerrs; +extern FILE *yyin; + +static int dump_vars = 0; +static int dump_cache = 0; #ifndef WITHOUT_PERL -extern void xs_init(pTHX); -extern PerlInterpreter *perl_interpreter; +extern void xs_init (pTHX); +extern PerlInterpreter *perl_interpreter; #endif /* Active workers */ -static GList *active_workers = NULL; +static GList *active_workers = NULL; /* List of workers that are pending to start */ -static GList *workers_pending = NULL; +static GList *workers_pending = NULL; -static -void sig_handler (int signo) +static + void +sig_handler (int signo) { switch (signo) { - case SIGHUP: - do_restart = 1; - do_reopen_log = 1; - break; - case SIGINT: - case SIGTERM: - do_terminate = 1; - break; - case SIGCHLD: - child_dead = 1; - break; - case SIGUSR2: - child_ready = 1; - break; - case SIGALRM: - got_alarm = 1; - break; + case SIGHUP: + do_restart = 1; + do_reopen_log = 1; + break; + case SIGINT: + case SIGTERM: + do_terminate = 1; + break; + case SIGCHLD: + child_dead = 1; + break; + case SIGUSR2: + child_ready = 1; + break; + case SIGALRM: + got_alarm = 1; + break; } } -static void +static void read_cmd_line (int argc, char **argv, struct config_file *cfg) { - int ch; - while ((ch = getopt(argc, argv, "tVChfc:u:g:")) != -1) { + int ch; + while ((ch = getopt (argc, argv, "tVChfc:u:g:")) != -1) { switch (ch) { - case 'f': - cfg->no_fork = 1; - break; - case 'c': - if (optarg && cfg->cfg_name) { - cfg->cfg_name = memory_pool_strdup (cfg->cfg_pool, optarg); - } - break; - case 't': - cfg->config_test = 1; - break; - case 'V': - dump_vars = 1; - break; - case 'C': - dump_cache = 1; - break; - case 'u': - if (optarg) { - cfg->rspamd_user = memory_pool_strdup (cfg->cfg_pool, optarg); - } - break; - case 'g': - if (optarg) { - cfg->rspamd_group = memory_pool_strdup (cfg->cfg_pool, optarg); - } - break; - case 'h': - case '?': - default: - /* Show help message and exit */ - printf ("Rspamd version " RVERSION "\n" - "Usage: rspamd [-t] [-h] [-n] [-f] [-c config_file]\n" - "-h: This help message\n" - "-t: Do config test and exit\n" - "-C: Dump symbols cache stats and exit\n" - "-V Print all rspamd variables and exit\n" - "-f: Do not daemonize main process\n" - "-c: Specify config file (./rspamd.conf is used by default)\n" - "-u: User to run rspamd as\n" - "-g: Group to run rspamd as\n"); - exit (0); - break; + case 'f': + cfg->no_fork = 1; + break; + case 'c': + if (optarg && cfg->cfg_name) { + cfg->cfg_name = memory_pool_strdup (cfg->cfg_pool, optarg); + } + break; + case 't': + cfg->config_test = 1; + break; + case 'V': + dump_vars = 1; + break; + case 'C': + dump_cache = 1; + break; + case 'u': + if (optarg) { + cfg->rspamd_user = memory_pool_strdup (cfg->cfg_pool, optarg); + } + break; + case 'g': + if (optarg) { + cfg->rspamd_group = memory_pool_strdup (cfg->cfg_pool, optarg); + } + break; + case 'h': + case '?': + default: + /* Show help message and exit */ + printf ("Rspamd version " RVERSION "\n" + "Usage: rspamd [-t] [-h] [-n] [-f] [-c config_file]\n" + "-h: This help message\n" + "-t: Do config test and exit\n" + "-C: Dump symbols cache stats and exit\n" + "-V Print all rspamd variables and exit\n" + "-f: Do not daemonize main process\n" + "-c: Specify config file (./rspamd.conf is used by default)\n" "-u: User to run rspamd as\n" "-g: Group to run rspamd as\n"); + exit (0); + break; } } } static void -drop_priv (struct config_file *cfg) +drop_priv (struct config_file *cfg) { - struct passwd *pwd; - struct group *grp; + struct passwd *pwd; + struct group *grp; if (geteuid () == 0 && cfg->rspamd_user) { pwd = getpwnam (cfg->rspamd_user); @@ -175,7 +174,7 @@ drop_priv (struct config_file *cfg) msg_err ("drop_priv: cannot setgid to %d (%s), aborting", (int)grp->gr_gid, strerror (errno)); exit (-errno); } - if (initgroups(cfg->rspamd_user, grp->gr_gid) == -1) { + if (initgroups (cfg->rspamd_user, grp->gr_gid) == -1) { msg_err ("drop_priv: initgroups failed (%s), aborting", strerror (errno)); exit (-errno); } @@ -191,76 +190,76 @@ static void config_logger (struct rspamd_main *rspamd, gboolean is_fatal) { switch (rspamd->cfg->log_type) { - case RSPAMD_LOG_CONSOLE: - if (!rspamd->cfg->no_fork) { - if (is_fatal) { - fprintf (stderr, "Cannot log to console while daemonized, disable logging\n"); - } - rspamd->cfg->log_fd = -1; - rspamd->cfg->logf = NULL; + case RSPAMD_LOG_CONSOLE: + if (!rspamd->cfg->no_fork) { + if (is_fatal) { + fprintf (stderr, "Cannot log to console while daemonized, disable logging\n"); } - else { - rspamd->cfg->logf = stderr; - rspamd->cfg->log_fd = STDERR_FILENO; - } - rspamd_set_logger (file_log_function, rspamd->cfg); - g_log_set_default_handler (file_log_function, rspamd->cfg); - break; - case RSPAMD_LOG_FILE: - if (rspamd->cfg->log_file == NULL || open_log (rspamd->cfg) == -1) { - if (is_fatal) { - fprintf (stderr, "Fatal error, cannot open logfile, exiting\n"); - exit (EXIT_FAILURE); - } - else { - msg_err ("config_logger: cannot log to file, logfile unaccessable"); - } + rspamd->cfg->log_fd = -1; + rspamd->cfg->logf = NULL; + } + else { + rspamd->cfg->logf = stderr; + rspamd->cfg->log_fd = STDERR_FILENO; + } + rspamd_set_logger (file_log_function, rspamd->cfg); + g_log_set_default_handler (file_log_function, rspamd->cfg); + break; + case RSPAMD_LOG_FILE: + if (rspamd->cfg->log_file == NULL || open_log (rspamd->cfg) == -1) { + if (is_fatal) { + fprintf (stderr, "Fatal error, cannot open logfile, exiting\n"); + exit (EXIT_FAILURE); } else { - rspamd_set_logger (file_log_function, rspamd->cfg); - g_log_set_default_handler (file_log_function, rspamd->cfg); + msg_err ("config_logger: cannot log to file, logfile unaccessable"); } - break; - case RSPAMD_LOG_SYSLOG: - if (open_log (rspamd->cfg) == -1) { - if (is_fatal) { - fprintf (stderr, "Fatal error, cannot open syslog facility, exiting\n"); - exit (EXIT_FAILURE); - } - else { - msg_err ("config_logger: cannot log to syslog"); - } + } + else { + rspamd_set_logger (file_log_function, rspamd->cfg); + g_log_set_default_handler (file_log_function, rspamd->cfg); + } + break; + case RSPAMD_LOG_SYSLOG: + if (open_log (rspamd->cfg) == -1) { + if (is_fatal) { + fprintf (stderr, "Fatal error, cannot open syslog facility, exiting\n"); + exit (EXIT_FAILURE); } else { - rspamd_set_logger (syslog_log_function, rspamd->cfg); - g_log_set_default_handler (syslog_log_function, rspamd->cfg); + msg_err ("config_logger: cannot log to syslog"); } - break; + } + else { + rspamd_set_logger (syslog_log_function, rspamd->cfg); + g_log_set_default_handler (syslog_log_function, rspamd->cfg); + } + break; } } static void reread_config (struct rspamd_main *rspamd) { - struct config_file *tmp_cfg; - char *cfg_file; - FILE *f; + struct config_file *tmp_cfg; + char *cfg_file; + FILE *f; - tmp_cfg = (struct config_file *) g_malloc (sizeof (struct config_file)); + tmp_cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); if (tmp_cfg) { bzero (tmp_cfg, sizeof (struct config_file)); tmp_cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); init_defaults (tmp_cfg); cfg_file = memory_pool_strdup (tmp_cfg->cfg_pool, rspamd->cfg->cfg_name); - f = fopen (rspamd->cfg->cfg_name , "r"); + f = fopen (rspamd->cfg->cfg_name, "r"); if (f == NULL) { - msg_warn ("reread_config: cannot open file: %s", rspamd->cfg->cfg_name ); + msg_warn ("reread_config: cannot open file: %s", rspamd->cfg->cfg_name); } else { yyin = f; yyrestart (yyin); - if (yyparse() != 0 || yynerrs > 0) { + if (yyparse () != 0 || yynerrs > 0) { msg_warn ("reread_config: yyparse: cannot parse config file, %d errors", yynerrs); fclose (f); } @@ -278,57 +277,57 @@ reread_config (struct rspamd_main *rspamd) } } -static struct rspamd_worker * -fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) +static struct rspamd_worker * +fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) { - struct rspamd_worker *cur; + struct rspamd_worker *cur; /* Starting worker process */ cur = (struct rspamd_worker *)g_malloc (sizeof (struct rspamd_worker)); if (cur) { bzero (cur, sizeof (struct rspamd_worker)); - active_workers = g_list_prepend (active_workers, cur); + active_workers = g_list_prepend (active_workers, cur); cur->srv = rspamd; cur->type = cf->type; - cur->pid = fork(); + cur->pid = fork (); cur->cf = cf; cur->pending = FALSE; switch (cur->pid) { - case 0: - /* Drop privilleges */ - drop_priv (cfg); - switch (cf->type) { - case TYPE_CONTROLLER: - setproctitle ("controller process"); - pidfile_close (rspamd->pfh); - msg_info ("fork_worker: starting controller process %d", getpid ()); - start_controller (cur); - break; - case TYPE_LMTP: - setproctitle ("lmtp process"); - pidfile_close (rspamd->pfh); - msg_info ("fork_worker: starting lmtp process %d", getpid ()); - start_lmtp_worker (cur); - break; - case TYPE_FUZZY: - setproctitle ("fuzzy storage"); - pidfile_close (rspamd->pfh); - msg_info ("fork_worker: starting fuzzy storage process %d", getpid ()); - start_fuzzy_storage (cur); - break; - case TYPE_WORKER: - default: - setproctitle ("worker process"); - pidfile_close (rspamd->pfh); - msg_info ("fork_worker: starting worker process %d", getpid ()); - start_worker (cur); - break; - } + case 0: + /* Drop privilleges */ + drop_priv (cfg); + switch (cf->type) { + case TYPE_CONTROLLER: + setproctitle ("controller process"); + pidfile_close (rspamd->pfh); + msg_info ("fork_worker: starting controller process %d", getpid ()); + start_controller (cur); break; - case -1: - msg_err ("fork_worker: cannot fork main process. %s", strerror (errno)); - pidfile_remove (rspamd->pfh); - exit (-errno); + case TYPE_LMTP: + setproctitle ("lmtp process"); + pidfile_close (rspamd->pfh); + msg_info ("fork_worker: starting lmtp process %d", getpid ()); + start_lmtp_worker (cur); + break; + case TYPE_FUZZY: + setproctitle ("fuzzy storage"); + pidfile_close (rspamd->pfh); + msg_info ("fork_worker: starting fuzzy storage process %d", getpid ()); + start_fuzzy_storage (cur); break; + case TYPE_WORKER: + default: + setproctitle ("worker process"); + pidfile_close (rspamd->pfh); + msg_info ("fork_worker: starting worker process %d", getpid ()); + start_worker (cur); + break; + } + break; + case -1: + msg_err ("fork_worker: cannot fork main process. %s", strerror (errno)); + pidfile_remove (rspamd->pfh); + exit (-errno); + break; } } @@ -345,11 +344,11 @@ delay_fork (struct worker_conf *cf) static void dump_module_variables (gpointer key, gpointer value, gpointer data) -{ - GList *cur_opt; - struct module_opt *cur; - - cur_opt = (GList *)value; +{ + GList *cur_opt; + struct module_opt *cur; + + cur_opt = (GList *) value; while (cur_opt) { cur = cur_opt->data; @@ -376,8 +375,8 @@ dump_cfg_vars () static int create_listen_socket (struct in_addr *addr, int port, int family, char *path) { - int listen_sock = -1; - struct sockaddr_un *un_addr; + int listen_sock = -1; + struct sockaddr_un *un_addr; /* Create listen socket */ if (family == AF_INET) { if ((listen_sock = make_tcp_socket (addr, port, TRUE, TRUE)) == -1) { @@ -385,12 +384,12 @@ create_listen_socket (struct in_addr *addr, int port, int family, char *path) } } else { - un_addr = (struct sockaddr_un *) alloca (sizeof (struct sockaddr_un)); + un_addr = (struct sockaddr_un *)alloca (sizeof (struct sockaddr_un)); if (!un_addr || (listen_sock = make_unix_socket (path, un_addr, TRUE)) == -1) { msg_err ("create_listen_socket: cannot create unix listen socket. %s", strerror (errno)); } } - + if (listen_sock != -1) { if (listen (listen_sock, -1) == -1) { msg_err ("start_lmtp: cannot listen on socket. %s", strerror (errno)); @@ -403,8 +402,8 @@ create_listen_socket (struct in_addr *addr, int port, int family, char *path) static void fork_delayed (struct rspamd_main *rspamd) { - GList *cur; - struct worker_conf *cf; + GList *cur; + struct worker_conf *cf; while (workers_pending != NULL) { cur = workers_pending; @@ -419,9 +418,9 @@ fork_delayed (struct rspamd_main *rspamd) static void spawn_workers (struct rspamd_main *rspamd) { - GList *cur; - struct worker_conf *cf; - int i, listen_sock; + GList *cur; + struct worker_conf *cf; + int i, listen_sock; cur = cfg->workers; @@ -430,10 +429,9 @@ spawn_workers (struct rspamd_main *rspamd) /* Create listen socket */ if (cf->type != TYPE_FUZZY) { - listen_sock = create_listen_socket (&cf->bind_addr, cf->bind_port, - cf->bind_family, cf->bind_host); + listen_sock = create_listen_socket (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host); if (listen_sock == -1) { - exit(-errno); + exit (-errno); } cf->listen_sock = listen_sock; } @@ -446,42 +444,42 @@ spawn_workers (struct rspamd_main *rspamd) } } -static const char * +static const char * get_process_type (enum process_type type) { switch (type) { - case TYPE_MAIN: - return "main"; - case TYPE_WORKER: - return "worker"; - case TYPE_FUZZY: - return "fuzzy"; - case TYPE_CONTROLLER: - return "controller"; - case TYPE_LMTP: - return "lmtp"; + case TYPE_MAIN: + return "main"; + case TYPE_WORKER: + return "worker"; + case TYPE_FUZZY: + return "fuzzy"; + case TYPE_CONTROLLER: + return "controller"; + case TYPE_LMTP: + return "lmtp"; } return NULL; } -int +int main (int argc, char **argv, char **env) { - struct rspamd_main *rspamd; - struct module_ctx *cur_module = NULL; - int res = 0, i; - struct sigaction signals; - struct rspamd_worker *cur, *active_worker; - struct rlimit rlim; - struct metric *metric; - struct cache_item *item; - struct filter *filt; - FILE *f; - pid_t wrk; - GList *l; + struct rspamd_main *rspamd; + struct module_ctx *cur_module = NULL; + int res = 0, i; + struct sigaction signals; + struct rspamd_worker *cur, *active_worker; + struct rlimit rlim; + struct metric *metric; + struct cache_item *item; + struct filter *filt; + FILE *f; + pid_t wrk; + GList *l; #ifndef WITHOUT_PERL - char *args[] = { "", "-e", "0", NULL }; + char *args[] = { "", "-e", "0", NULL }; #endif rspamd = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); @@ -490,10 +488,10 @@ main (int argc, char **argv, char **env) cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); rspamd->cfg = cfg; if (!rspamd || !rspamd->cfg) { - fprintf(stderr, "Cannot allocate memory\n"); - exit(-errno); + fprintf (stderr, "Cannot allocate memory\n"); + exit (-errno); } - + do_terminate = 0; do_restart = 0; child_dead = 0; @@ -537,15 +535,15 @@ main (int argc, char **argv, char **env) #ifndef HAVE_SETPROCTITLE init_title (argc, argv, environ); #endif - - f = fopen (rspamd->cfg->cfg_name , "r"); + + f = fopen (rspamd->cfg->cfg_name, "r"); if (f == NULL) { - msg_err ("main: cannot open file: %s", rspamd->cfg->cfg_name ); + msg_err ("main: cannot open file: %s", rspamd->cfg->cfg_name); return EBADF; } yyin = f; - if (yyparse() != 0 || yynerrs > 0) { + if (yyparse () != 0 || yynerrs > 0) { msg_err ("main: cannot parse config file, %d errors", yynerrs); return EBADF; } @@ -555,14 +553,14 @@ main (int argc, char **argv, char **env) counters = rspamd_hash_new_shared (rspamd->server_pool, g_str_hash, g_str_equal, 64); /* Init C modules */ - l = g_list_first (rspamd->cfg->filters); + l = g_list_first (rspamd->cfg->filters); while (l) { filt = l->data; if (filt->module) { cur_module = memory_pool_alloc (rspamd->cfg->cfg_pool, sizeof (struct module_ctx)); - if (filt->module->module_init_func(cfg, &cur_module) == 0) { - g_hash_table_insert (cfg->c_modules, (gpointer)filt->module->name, cur_module); + if (filt->module->module_init_func (cfg, &cur_module) == 0) { + g_hash_table_insert (cfg->c_modules, (gpointer) filt->module->name, cur_module); } } l = g_list_next (l); @@ -584,9 +582,9 @@ main (int argc, char **argv, char **env) } l = g_list_next (l); } - #if defined(WITH_LUA) +#if defined(WITH_LUA) init_lua_filters (cfg); - #endif +#endif if (dump_vars) { dump_cfg_vars (); } @@ -601,12 +599,10 @@ main (int argc, char **argv, char **env) printf ("Cache for metric: %s\n", metric->name); printf ("-----------------------------------------------------------------\n"); printf ("| Pri | Symbol | Weight | Frequency | Avg. time |\n"); - for (i = 0; i < metric->cache->used_items; i ++) { + for (i = 0; i < metric->cache->used_items; i++) { item = &metric->cache->items[i]; printf ("-----------------------------------------------------------------\n"); - printf ("| %3d | %22s | %6.1f | %9d | %9.3f |\n", i, item->s->symbol, - item->s->weight, item->s->frequency, - item->s->avg_time); + printf ("| %3d | %22s | %6.1f | %9d | %9.3f |\n", i, item->s->symbol, item->s->weight, item->s->frequency, item->s->avg_time); } printf ("-----------------------------------------------------------------\n"); @@ -620,14 +616,14 @@ main (int argc, char **argv, char **env) } /* Set stack size for pcre */ - getrlimit(RLIMIT_STACK, &rlim); + getrlimit (RLIMIT_STACK, &rlim); rlim.rlim_cur = 100 * 1024 * 1024; - setrlimit(RLIMIT_STACK, &rlim); - + setrlimit (RLIMIT_STACK, &rlim); + config_logger (rspamd, TRUE); - msg_info ("main: rspamd "RVERSION " is starting"); - rspamd->cfg->cfg_name = memory_pool_strdup (rspamd->cfg->cfg_pool, rspamd->cfg->cfg_name ); + msg_info ("main: rspamd " RVERSION " is starting"); + rspamd->cfg->cfg_name = memory_pool_strdup (rspamd->cfg->cfg_pool, rspamd->cfg->cfg_name); /* Strictly set temp dir */ if (!rspamd->cfg->temp_dir) { @@ -645,9 +641,9 @@ main (int argc, char **argv, char **env) exit (-errno); } - rspamd->pid = getpid(); + rspamd->pid = getpid (); rspamd->type = TYPE_MAIN; - + init_signals (&signals, sig_handler); @@ -675,7 +671,7 @@ main (int argc, char **argv, char **env) #endif /* Block signals to use sigsuspend in future */ - sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL); + sigprocmask (SIG_BLOCK, &signals.sa_mask, NULL); setproctitle ("main process"); @@ -708,7 +704,7 @@ main (int argc, char **argv, char **env) l = g_list_next (l); } - + spawn_workers (rspamd); /* Signal processing cycle */ @@ -726,54 +722,50 @@ main (int argc, char **argv, char **env) msg_debug ("main: catch SIGCHLD signal, finding terminated worker"); /* Remove dead child form childs list */ wrk = waitpid (0, &res, 0); - l = g_list_first (active_workers); - while (l) { - cur = l->data; + l = g_list_first (active_workers); + while (l) { + cur = l->data; if (wrk == cur->pid) { /* Catch situations if active worker is abnormally terminated */ if (cur == active_worker) { active_worker = NULL; } - active_workers = g_list_remove_link (active_workers, l); + active_workers = g_list_remove_link (active_workers, l); if (WIFEXITED (res) && WEXITSTATUS (res) == 0) { /* Normal worker termination, do not fork one more */ - msg_info ("main: %s process %d terminated normally", - get_process_type (cur->type), cur->pid); + msg_info ("main: %s process %d terminated normally", get_process_type (cur->type), cur->pid); } else { if (WIFSIGNALED (res)) { - msg_warn ("main: %s process %d terminated abnormally by signal: %d", - get_process_type (cur->type), - cur->pid, WTERMSIG(res)); + msg_warn ("main: %s process %d terminated abnormally by signal: %d", get_process_type (cur->type), cur->pid, WTERMSIG (res)); } else { - msg_warn ("main: %s process %d terminated abnormally", - get_process_type (cur->type), cur->pid); + msg_warn ("main: %s process %d terminated abnormally", get_process_type (cur->type), cur->pid); } /* Fork another worker in replace of dead one */ delay_fork (cur->cf); } - g_list_free_1 (l); + g_list_free_1 (l); g_free (cur); } l = g_list_next (l); } } - if (do_restart) { + if (do_restart) { do_restart = 0; do_reopen_log = 1; msg_info ("main: rspamd " RVERSION " is restarting"); - l = g_list_first (active_workers); - while (l) { - cur = l->data; - /* Start new workers that would reread configuration */ + l = g_list_first (active_workers); + while (l) { + cur = l->data; + /* Start new workers that would reread configuration */ cur->pending = FALSE; active_worker = fork_worker (rspamd, cur->cf); - active_worker->pending = TRUE; + active_worker->pending = TRUE; l = g_list_next (l); - } + } } if (child_ready) { child_ready = 0; @@ -788,8 +780,7 @@ main (int argc, char **argv, char **env) cur->is_dying = 1; } else { - msg_info ("main: %s process %d has been successfully started", - get_process_type (cur->type), cur->pid); + msg_info ("main: %s process %d has been successfully started", get_process_type (cur->type), cur->pid); } l = g_list_next (l); } @@ -813,9 +804,9 @@ main (int argc, char **argv, char **env) } g_list_free (active_workers); - + msg_info ("main: terminating..."); - + free_config (rspamd->cfg); g_free (rspamd->cfg); g_free (rspamd); @@ -31,30 +31,30 @@ #include "util.h" #include "mem_pool.h" -static memory_pool_t *map_pool = NULL; +static memory_pool_t *map_pool = NULL; -static GList *maps = NULL; -static char *hash_fill = "1"; +static GList *maps = NULL; +static char *hash_fill = "1"; /* Http reply */ struct http_reply { - int code; - GHashTable *headers; - char *cur_header; + int code; + GHashTable *headers; + char *cur_header; - int parser_state; + int parser_state; }; struct http_callback_data { - struct event ev; - struct timeval tv; - struct rspamd_map *map; - struct http_map_data *data; - struct http_reply *reply; - struct map_cb_data cbdata; - - int state; - int fd; + struct event ev; + struct timeval tv; + struct rspamd_map *map; + struct http_map_data *data; + struct http_reply *reply; + struct map_cb_data cbdata; + + int state; + int fd; }; /* Value in seconds after whitch we would try to do stat on list file */ @@ -66,7 +66,7 @@ struct http_callback_data { static int connect_http (struct rspamd_map *map, struct http_map_data *data, gboolean is_async) { - int sock; + int sock; if ((sock = make_tcp_socket (&data->addr, data->port, FALSE, is_async)) == -1) { msg_info ("connect_http: cannot connect to http server %s: %d, %s", data->host, errno, strerror (errno)); @@ -79,13 +79,10 @@ connect_http (struct rspamd_map *map, struct http_map_data *data, gboolean is_as static void write_http_request (struct rspamd_map *map, struct http_map_data *data, int sock) { - char outbuf[BUFSIZ]; - int r; + char outbuf[BUFSIZ]; + int r; - r = snprintf (outbuf, sizeof (outbuf), "GET %s%s HTTP/1.1" CRLF - "Connection: close" CRLF - "Host: %s" CRLF, (*data->path == '/') ? "" : "/", - data->path, data->host); + r = snprintf (outbuf, sizeof (outbuf), "GET %s%s HTTP/1.1" CRLF "Connection: close" CRLF "Host: %s" CRLF, (*data->path == '/') ? "" : "/", data->path, data->host); if (data->last_checked != 0) { r += snprintf (outbuf + r, sizeof (outbuf) - r, "If-Modified-Since: %s" CRLF, asctime (gmtime (&data->last_checked))); } @@ -97,88 +94,88 @@ write_http_request (struct rspamd_map *map, struct http_map_data *data, int sock } } -static u_char * -parse_http_reply (u_char *chunk, size_t len, struct http_reply *reply) +static u_char * +parse_http_reply (u_char * chunk, size_t len, struct http_reply *reply) { - u_char *s, *p, *err_str, *tmp; + u_char *s, *p, *err_str, *tmp; p = chunk; s = chunk; while (p - chunk < len) { switch (reply->parser_state) { /* Search status code */ - case 0: - /* Search for status code */ - if (*p != ' ') { - p ++; - } - else { - /* Try to parse HTTP reply code */ - reply->code = strtoul (++p, (char **)&err_str, 10); - if (*err_str != ' ') { - msg_info ("parse_http_reply: error while reading HTTP status code: %s", p); - return NULL; - } - /* Now skip to end of status string */ - reply->parser_state = 1; - continue; + case 0: + /* Search for status code */ + if (*p != ' ') { + p++; + } + else { + /* Try to parse HTTP reply code */ + reply->code = strtoul (++p, (char **)&err_str, 10); + if (*err_str != ' ') { + msg_info ("parse_http_reply: error while reading HTTP status code: %s", p); + return NULL; } - break; + /* Now skip to end of status string */ + reply->parser_state = 1; + continue; + } + break; /* Skip to end of line */ - case 1: - if (*p == '\n') { - /* Switch to read header state */ - reply->parser_state = 2; - } - /* Each skipped symbol is proceeded */ - s = ++p; - break; + case 1: + if (*p == '\n') { + /* Switch to read header state */ + reply->parser_state = 2; + } + /* Each skipped symbol is proceeded */ + s = ++p; + break; /* Read header value */ - case 2: - if (*p == ':') { - reply->cur_header = g_malloc (p - s + 1); - g_strlcpy (reply->cur_header, s, p - s + 1); - reply->parser_state = 3; - } - else if (*p == '\r' && *(p + 1) == '\n') { - /* Last empty line */ - reply->parser_state = 5; - } - p ++; - break; + case 2: + if (*p == ':') { + reply->cur_header = g_malloc (p - s + 1); + g_strlcpy (reply->cur_header, s, p - s + 1); + reply->parser_state = 3; + } + else if (*p == '\r' && *(p + 1) == '\n') { + /* Last empty line */ + reply->parser_state = 5; + } + p++; + break; /* Skip spaces after header name */ - case 3: - if (*p != ' ') { - s = p; - reply->parser_state = 4; - } - else { - p ++; - } - break; + case 3: + if (*p != ' ') { + s = p; + reply->parser_state = 4; + } + else { + p++; + } + break; /* Read header value */ - case 4: - if (*p == '\r') { - if (reply->cur_header != NULL) { - tmp = g_malloc (p - s + 1); - g_strlcpy (tmp, s, p - s + 1); - g_hash_table_insert (reply->headers, reply->cur_header, tmp); - reply->cur_header = NULL; - } - reply->parser_state = 1; + case 4: + if (*p == '\r') { + if (reply->cur_header != NULL) { + tmp = g_malloc (p - s + 1); + g_strlcpy (tmp, s, p - s + 1); + g_hash_table_insert (reply->headers, reply->cur_header, tmp); + reply->cur_header = NULL; } - p ++; - break; - case 5: - /* Set pointer to begining of HTTP body */ - p ++; - s = p; - reply->parser_state = 6; - break; - case 6: - /* Headers parsed, just return */ - return p; - break; + reply->parser_state = 1; + } + p++; + break; + case 5: + /* Set pointer to begining of HTTP body */ + p++; + s = p; + reply->parser_state = 6; + break; + case 6: + /* Headers parsed, just return */ + return p; + break; } } @@ -186,39 +183,39 @@ parse_http_reply (u_char *chunk, size_t len, struct http_reply *reply) } static int -read_chunk_header (u_char *buf, size_t len, struct http_map_data *data) +read_chunk_header (u_char * buf, size_t len, struct http_map_data *data) { - u_char chunkbuf[32], *p, *c; - int skip = 0; + u_char chunkbuf[32], *p, *c; + int skip = 0; p = chunkbuf; c = buf; while (g_ascii_isxdigit (*c) && p - chunkbuf < sizeof (chunkbuf) - 1) { *p++ = *c++; - skip ++; + skip++; } *p = '\0'; data->chunk = strtoul (chunkbuf, NULL, 16); /* Now skip to CRLF */ while (*c != '\n' && c - buf < len) { - c ++; - skip ++; + c++; + skip++; } if (*c == '\n') { - skip ++; - c ++; + skip++; + c++; } data->chunk_read = 0; - + return skip; } -static gboolean -read_http_chunked (u_char *buf, size_t len, struct rspamd_map *map, struct http_map_data *data, struct map_cb_data *cbdata) +static gboolean +read_http_chunked (u_char * buf, size_t len, struct rspamd_map *map, struct http_map_data *data, struct map_cb_data *cbdata) { - u_char *p = buf, *remain; - uint32_t skip = 0, rlen; - + u_char *p = buf, *remain; + uint32_t skip = 0, rlen; + if (data->chunk == 0) { /* Read first chunk data */ skip = read_chunk_header (buf, len, data); @@ -261,17 +258,17 @@ read_http_chunked (u_char *buf, size_t len, struct rspamd_map *map, struct http_ return TRUE; } -static gboolean +static gboolean read_http_common (struct rspamd_map *map, struct http_map_data *data, struct http_reply *reply, struct map_cb_data *cbdata, int fd) { - u_char buf[BUFSIZ], *remain, *pos; - int rlen; - ssize_t r; - char *te; + u_char buf[BUFSIZ], *remain, *pos; + int rlen; + ssize_t r; + char *te; rlen = 0; if ((r = read (fd, buf + rlen, sizeof (buf) - rlen - 1)) > 0) { - buf[r ++] = '\0'; + buf[r++] = '\0'; remain = parse_http_reply (buf, r - 1, reply); if (remain != NULL && remain != buf) { /* copy remaining buffer to start of buffer */ @@ -318,9 +315,9 @@ read_http_common (struct rspamd_map *map, struct http_map_data *data, struct htt static void read_http_sync (struct rspamd_map *map, struct http_map_data *data) { - struct map_cb_data cbdata; - int fd; - struct http_reply *repl; + struct map_cb_data cbdata; + int fd; + struct http_reply *repl; if (map->read_callback == NULL || map->fin_callback == NULL) { msg_err ("read_map_file: bad callback for reading map file"); @@ -332,7 +329,7 @@ read_http_sync (struct rspamd_map *map, struct http_map_data *data) return; } write_http_request (map, data, fd); - + cbdata.state = 0; cbdata.prev_data = *map->user_data; cbdata.cur_data = NULL; @@ -341,7 +338,7 @@ read_http_sync (struct rspamd_map *map, struct http_map_data *data) repl->parser_state = 0; repl->code = 404; repl->headers = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, g_free); - + while (read_http_common (map, data, repl, &cbdata, fd)); close (fd); @@ -357,11 +354,11 @@ read_http_sync (struct rspamd_map *map, struct http_map_data *data) static void read_map_file (struct rspamd_map *map, struct file_map_data *data) { - struct map_cb_data cbdata; - u_char buf[BUFSIZ], *remain; - ssize_t r; - int fd, rlen; - + struct map_cb_data cbdata; + u_char buf[BUFSIZ], *remain; + ssize_t r; + int fd, rlen; + if (map->read_callback == NULL || map->fin_callback == NULL) { msg_err ("read_map_file: bad callback for reading map file"); return; @@ -375,10 +372,10 @@ read_map_file (struct rspamd_map *map, struct file_map_data *data) cbdata.state = 0; cbdata.prev_data = *map->user_data; cbdata.cur_data = NULL; - + rlen = 0; while ((r = read (fd, buf + rlen, sizeof (buf) - rlen - 1)) > 0) { - buf[r ++] = '\0'; + buf[r++] = '\0'; remain = map->read_callback (map->pool, buf, r - 1, &cbdata); if (remain != NULL) { /* copy remaining buffer to start of buffer */ @@ -386,24 +383,24 @@ read_map_file (struct rspamd_map *map, struct file_map_data *data) memmove (buf, remain, rlen); } } - + close (fd); map->fin_callback (map->pool, &cbdata); *map->user_data = cbdata.cur_data; } -gboolean +gboolean add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback, void **user_data) { - struct rspamd_map *new_map; - enum fetch_proto proto; - const char *def, *p, *hostend; - struct file_map_data *fdata; - struct http_map_data *hdata; - char portbuf[6]; - int i, s, fd; - struct hostent *hent; + struct rspamd_map *new_map; + enum fetch_proto proto; + const char *def, *p, *hostend; + struct file_map_data *fdata; + struct http_map_data *hdata; + char portbuf[6]; + int i, s, fd; + struct hostent *hent; /* First of all detect protocol line */ if (strncmp (map_line, "http://", sizeof ("http://") - 1) == 0) { @@ -427,7 +424,7 @@ add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback new_map->fin_callback = fin_callback; new_map->user_data = user_data; new_map->protocol = proto; - + /* Now check for each proto separately */ if (proto == PROTO_FILE) { if ((fd = open (def, O_RDONLY)) == -1) { @@ -445,9 +442,9 @@ add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback if ((p = strchr (def, ':')) != NULL) { hostend = p; i = 0; - p ++; + p++; while (g_ascii_isdigit (*p) && i < sizeof (portbuf) - 1) { - portbuf[i ++] = *p ++; + portbuf[i++] = *p++; } if (*p != '/') { msg_info ("add_map: bad http map definition: %s", def); @@ -478,7 +475,7 @@ add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback return FALSE; } else { - memcpy (&hdata->addr, hent->h_addr, sizeof(struct in_addr)); + memcpy (&hdata->addr, hent->h_addr, sizeof (struct in_addr)); } } /* Now try to connect */ @@ -497,12 +494,12 @@ add_map (const char *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback return TRUE; } -typedef void (*insert_func)(gpointer st, gconstpointer key, gpointer value); +typedef void (*insert_func) (gpointer st, gconstpointer key, gpointer value); -static u_char* -abstract_parse_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data, insert_func func) +static u_char * +abstract_parse_list (memory_pool_t * pool, u_char * chunk, size_t len, struct map_cb_data *data, insert_func func) { - u_char *s, *p, *str, *start; + u_char *s, *p, *str, *start; p = chunk; start = p; @@ -513,53 +510,53 @@ abstract_parse_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_ while (p - chunk < len) { switch (data->state) { /* READ_SYMBOL */ - case 0: - if (*p == '#') { - if (s != str) { - *s = '\0'; - s = memory_pool_strdup (pool, g_strstrip (str)); - if (strlen (s) > 0) { - func (data->cur_data, s, hash_fill); - } - s = str; - start = p; - } - data->state = 1; - } - else if (*p == '\r' || *p == '\n') { - if (s != str) { - *s = '\0'; - s = memory_pool_strdup (pool, g_strstrip (str)); - if (strlen (s) > 0) { - func (data->cur_data, s, hash_fill); - } - s = str; - start = p; + case 0: + if (*p == '#') { + if (s != str) { + *s = '\0'; + s = memory_pool_strdup (pool, g_strstrip (str)); + if (strlen (s) > 0) { + func (data->cur_data, s, hash_fill); } - while (*p == '\r' || *p == '\n') { - p ++; - } - } - else { - *s = *p; - s ++; - p ++; + s = str; + start = p; } - break; - /* SKIP_COMMENT */ - case 1: - if (*p == '\r' || *p == '\n') { - while (*p == '\r' || *p == '\n') { - p ++; + data->state = 1; + } + else if (*p == '\r' || *p == '\n') { + if (s != str) { + *s = '\0'; + s = memory_pool_strdup (pool, g_strstrip (str)); + if (strlen (s) > 0) { + func (data->cur_data, s, hash_fill); } s = str; start = p; - data->state = 0; } - else { - p ++; + while (*p == '\r' || *p == '\n') { + p++; } - break; + } + else { + *s = *p; + s++; + p++; + } + break; + /* SKIP_COMMENT */ + case 1: + if (*p == '\r' || *p == '\n') { + while (*p == '\r' || *p == '\n') { + p++; + } + s = str; + start = p; + data->state = 0; + } + else { + p++; + } + break; } } @@ -571,19 +568,19 @@ abstract_parse_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_ static void radix_tree_insert_helper (gpointer st, gconstpointer key, gpointer value) { - radix_tree_t *tree = st; - - uint32_t mask = 0xFFFFFFFF; - uint32_t ip; - char *token, *ipnet, *err_str, **strv, **cur; - struct in_addr ina; - int k; - - strv = g_strsplit_set ((char *)key, " ,;", 0); + radix_tree_t *tree = st; + + uint32_t mask = 0xFFFFFFFF; + uint32_t ip; + char *token, *ipnet, *err_str, **strv, **cur; + struct in_addr ina; + int k; + + strv = g_strsplit_set ((char *)key, " ,;", 0); cur = strv; - while (*cur) { + while (*cur) { if (**cur == '\0') { - cur ++; + cur++; continue; } ipnet = *cur; @@ -609,7 +606,7 @@ radix_tree_insert_helper (gpointer st, gconstpointer key, gpointer value) return; } - ip = ntohl ((uint32_t)ina.s_addr); + ip = ntohl ((uint32_t) ina.s_addr); k = radix32tree_insert (tree, ip, mask, 1); if (k == -1) { msg_warn ("radix_tree_insert_helper: cannot insert ip to tree: %s, mask %X", inet_ntoa (ina), mask); @@ -617,40 +614,40 @@ radix_tree_insert_helper (gpointer st, gconstpointer key, gpointer value) else if (k == 1) { msg_warn ("add_ip_radix: ip %s, mask %X, value already exists", inet_ntoa (ina), mask); } - cur ++; + cur++; } g_strfreev (strv); } -u_char * -read_host_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data) -{ +u_char * +read_host_list (memory_pool_t * pool, u_char * chunk, size_t len, struct map_cb_data *data) +{ if (data->cur_data == NULL) { data->cur_data = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); } - return abstract_parse_list (pool, chunk, len, data, (insert_func)g_hash_table_insert); + return abstract_parse_list (pool, chunk, len, data, (insert_func) g_hash_table_insert); } -void -fin_host_list (memory_pool_t *pool, struct map_cb_data *data) +void +fin_host_list (memory_pool_t * pool, struct map_cb_data *data) { if (data->prev_data) { g_hash_table_destroy (data->prev_data); } } -u_char * -read_radix_list (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data) +u_char * +read_radix_list (memory_pool_t * pool, u_char * chunk, size_t len, struct map_cb_data *data) { if (data->cur_data == NULL) { data->cur_data = radix_tree_create (); } - return abstract_parse_list (pool, chunk, len, data, (insert_func)radix_tree_insert_helper); + return abstract_parse_list (pool, chunk, len, data, (insert_func) radix_tree_insert_helper); } -void -fin_radix_list (memory_pool_t *pool, struct map_cb_data *data) +void +fin_radix_list (memory_pool_t * pool, struct map_cb_data *data) { if (data->prev_data) { radix_tree_free (data->prev_data); @@ -660,9 +657,9 @@ fin_radix_list (memory_pool_t *pool, struct map_cb_data *data) static void file_callback (int fd, short what, void *ud) { - struct rspamd_map *map = ud; - struct file_map_data *data = map->map_data; - struct stat st; + struct rspamd_map *map = ud; + struct file_map_data *data = map->map_data; + struct stat st; /* Plan event again with jitter */ evtimer_del (&map->ev); @@ -676,7 +673,7 @@ file_callback (int fd, short what, void *ud) else { return; } - + msg_info ("rereading map file %s", data->filename); read_map_file (map, data); } @@ -696,8 +693,8 @@ free_http_cbdata (struct http_callback_data *cbd) static void http_async_callback (int fd, short what, void *ud) { - struct http_callback_data *cbd = ud; - + struct http_callback_data *cbd = ud; + /* Begin of connection */ if (what == EV_WRITE) { if (cbd->state == 0) { @@ -745,7 +742,7 @@ http_async_callback (int fd, short what, void *ud) free_http_cbdata (cbd); return; - } + } else if (cbd->state == 1) { /* Write to log that data is modified */ msg_info ("http_async_callback: rereading map data from %s", cbd->data->host); @@ -763,10 +760,10 @@ http_async_callback (int fd, short what, void *ud) static void http_callback (int fd, short what, void *ud) { - struct rspamd_map *map = ud; - struct http_map_data *data = map->map_data; - int sock; - struct http_callback_data *cbd; + struct rspamd_map *map = ud; + struct http_map_data *data = map->map_data; + int sock; + struct http_callback_data *cbd; /* Plan event again with jitter */ evtimer_del (&map->ev); @@ -794,12 +791,12 @@ http_callback (int fd, short what, void *ud) } /* Start watching event for all maps */ -void +void start_map_watch (void) { - GList *cur = maps; - struct rspamd_map *map; - + GList *cur = maps; + struct rspamd_map *map; + /* First of all do synced read of data */ while (cur) { map = cur->data; diff --git a/src/mem_pool.c b/src/mem_pool.c index ce6eab86e..23907d260 100644 --- a/src/mem_pool.c +++ b/src/mem_pool.c @@ -31,12 +31,12 @@ #define MUTEX_SPIN_COUNT 100 #ifdef _THREAD_SAFE -pthread_mutex_t stat_mtx = PTHREAD_MUTEX_INITIALIZER; -#define STAT_LOCK() do { pthread_mutex_lock (&stat_mtx); } while (0) -#define STAT_UNLOCK() do { pthread_mutex_unlock (&stat_mtx); } while (0) +pthread_mutex_t stat_mtx = PTHREAD_MUTEX_INITIALIZER; +# define STAT_LOCK() do { pthread_mutex_lock (&stat_mtx); } while (0) +# define STAT_UNLOCK() do { pthread_mutex_unlock (&stat_mtx); } while (0) #else -#define STAT_LOCK() do {} while (0) -#define STAT_UNLOCK() do {} while (0) +# define STAT_LOCK() do {} while (0) +# define STAT_UNLOCK() do {} while (0) #endif /* @@ -50,65 +50,65 @@ pthread_mutex_t stat_mtx = PTHREAD_MUTEX_INITIALIZER; #undef MEMORY_GREEDY /* Internal statistic */ -static memory_pool_stat_t *mem_pool_stat = NULL; +static memory_pool_stat_t *mem_pool_stat = NULL; -static struct _pool_chain * -pool_chain_new (memory_pool_ssize_t size) +static struct _pool_chain * +pool_chain_new (memory_pool_ssize_t size) { - struct _pool_chain *chain; + struct _pool_chain *chain; g_assert (size > 0); chain = g_slice_alloc (sizeof (struct _pool_chain)); - g_assert (chain != NULL); + g_assert (chain != NULL); chain->begin = g_slice_alloc (size); - g_assert (chain->begin != NULL); + g_assert (chain->begin != NULL); chain->len = size; chain->pos = chain->begin; chain->next = NULL; STAT_LOCK (); - mem_pool_stat->chunks_allocated ++; + mem_pool_stat->chunks_allocated++; STAT_UNLOCK (); - + return chain; } static struct _pool_chain_shared * -pool_chain_new_shared (memory_pool_ssize_t size) +pool_chain_new_shared (memory_pool_ssize_t size) { - struct _pool_chain_shared *chain; + struct _pool_chain_shared *chain; #if defined(HAVE_MMAP_ANON) - chain = mmap (NULL, size + sizeof (struct _pool_chain_shared), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); + chain = mmap (NULL, size + sizeof (struct _pool_chain_shared), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); g_assert (chain != MAP_FAILED); - chain->begin = ((u_char *)chain) + sizeof (struct _pool_chain_shared); + chain->begin = ((u_char *) chain) + sizeof (struct _pool_chain_shared); g_assert (chain->begin != MAP_FAILED); #elif defined(HAVE_MMAP_ZERO) - int fd; + int fd; fd = open ("/dev/zero", O_RDWR); if (fd == -1) { return NULL; } - chain = mmap (NULL, size + sizeof (struct _pool_chain_shared), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + chain = mmap (NULL, size + sizeof (struct _pool_chain_shared), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); g_assert (chain != MAP_FAILED); - chain->begin = ((u_char *)chain) + sizeof (struct _pool_chain_shared); + chain->begin = ((u_char *) chain) + sizeof (struct _pool_chain_shared); g_assert (chain->begin != MAP_FAILED); #else -# error No mmap methods are defined +# error No mmap methods are defined #endif chain->len = size; chain->pos = chain->begin; chain->lock = 0; chain->next = NULL; STAT_LOCK (); - mem_pool_stat->shared_chunks_allocated ++; + mem_pool_stat->shared_chunks_allocated++; STAT_UNLOCK (); - + return chain; } @@ -118,47 +118,47 @@ pool_chain_new_shared (memory_pool_ssize_t size) * @param size size of pool's page * @return new memory pool object */ -memory_pool_t* +memory_pool_t * memory_pool_new (memory_pool_ssize_t size) { - memory_pool_t *new; - + memory_pool_t *new; + g_assert (size > 0); /* Allocate statistic structure if it is not allocated before */ if (mem_pool_stat == NULL) { #if defined(HAVE_MMAP_ANON) - mem_pool_stat = mmap (NULL, sizeof (memory_pool_stat_t), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); + mem_pool_stat = mmap (NULL, sizeof (memory_pool_stat_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); g_assert (stat != MAP_FAILED); #elif defined(HAVE_MMAP_ZERO) - int fd; + int fd; fd = open ("/dev/zero", O_RDWR); g_assert (fd != -1); - mem_pool_stat = mmap (NULL, sizeof (memory_pool_stat_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + mem_pool_stat = mmap (NULL, sizeof (memory_pool_stat_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); g_assert (chain != MAP_FAILED); #else -# error No mmap methods are defined +# error No mmap methods are defined #endif } new = g_slice_alloc (sizeof (memory_pool_t)); - g_assert (new != NULL); + g_assert (new != NULL); new->cur_pool = pool_chain_new (size); new->shared_pool = NULL; new->first_pool = new->cur_pool; new->destructors = NULL; - mem_pool_stat->pools_allocated ++; + mem_pool_stat->pools_allocated++; return new; } -void * -memory_pool_alloc (memory_pool_t *pool, memory_pool_ssize_t size) +void * +memory_pool_alloc (memory_pool_t * pool, memory_pool_ssize_t size) { - u_char *tmp; - struct _pool_chain *new, *cur; + u_char *tmp; + struct _pool_chain *new, *cur; if (pool) { #ifdef MEMORY_GREEDY @@ -176,7 +176,7 @@ memory_pool_alloc (memory_pool_t *pool, memory_pool_ssize_t size) new = pool_chain_new (cur->len); } else { - mem_pool_stat->oversized_chunks ++; + mem_pool_stat->oversized_chunks++; new = pool_chain_new (size + cur->len); } /* Attach new pool to chain */ @@ -187,7 +187,7 @@ memory_pool_alloc (memory_pool_t *pool, memory_pool_ssize_t size) mem_pool_stat->bytes_allocated += size; STAT_UNLOCK (); return new->begin; - } + } tmp = cur->pos; cur->pos += size; STAT_LOCK (); @@ -198,31 +198,31 @@ memory_pool_alloc (memory_pool_t *pool, memory_pool_ssize_t size) return NULL; } -void * -memory_pool_alloc0 (memory_pool_t *pool, memory_pool_ssize_t size) +void * +memory_pool_alloc0 (memory_pool_t * pool, memory_pool_ssize_t size) { - void *pointer = memory_pool_alloc (pool, size); + void *pointer = memory_pool_alloc (pool, size); if (pointer) { bzero (pointer, size); } return pointer; } -void * -memory_pool_alloc0_shared (memory_pool_t *pool, memory_pool_ssize_t size) +void * +memory_pool_alloc0_shared (memory_pool_t * pool, memory_pool_ssize_t size) { - void *pointer = memory_pool_alloc_shared (pool, size); + void *pointer = memory_pool_alloc_shared (pool, size); if (pointer) { bzero (pointer, size); } return pointer; } -char * -memory_pool_strdup (memory_pool_t *pool, const char *src) +char * +memory_pool_strdup (memory_pool_t * pool, const char *src) { - memory_pool_ssize_t len; - char *newstr; + memory_pool_ssize_t len; + char *newstr; if (src == NULL) { return NULL; @@ -235,10 +235,10 @@ memory_pool_strdup (memory_pool_t *pool, const char *src) return newstr; } -char * -memory_pool_fstrdup (memory_pool_t *pool, const struct f_str_s *src) +char * +memory_pool_fstrdup (memory_pool_t * pool, const struct f_str_s *src) { - char *newstr; + char *newstr; if (src == NULL) { return NULL; @@ -251,11 +251,11 @@ memory_pool_fstrdup (memory_pool_t *pool, const struct f_str_s *src) } -char * -memory_pool_strdup_shared (memory_pool_t *pool, const char *src) +char * +memory_pool_strdup_shared (memory_pool_t * pool, const char *src) { - memory_pool_ssize_t len; - char *newstr; + memory_pool_ssize_t len; + char *newstr; if (src == NULL) { return NULL; @@ -269,11 +269,11 @@ memory_pool_strdup_shared (memory_pool_t *pool, const char *src) } -void * -memory_pool_alloc_shared (memory_pool_t *pool, memory_pool_ssize_t size) +void * +memory_pool_alloc_shared (memory_pool_t * pool, memory_pool_ssize_t size) { - u_char *tmp; - struct _pool_chain_shared *new, *cur; + u_char *tmp; + struct _pool_chain_shared *new, *cur; if (pool) { g_assert (size > 0); @@ -293,7 +293,7 @@ memory_pool_alloc_shared (memory_pool_t *pool, memory_pool_ssize_t size) new = pool_chain_new_shared (cur->len); } else { - mem_pool_stat->oversized_chunks ++; + mem_pool_stat->oversized_chunks++; new = pool_chain_new_shared (size + cur->len); } /* Attach new pool to chain */ @@ -316,12 +316,12 @@ memory_pool_alloc_shared (memory_pool_t *pool, memory_pool_ssize_t size) /* Find pool for a pointer, returns NULL if pointer is not in pool */ static struct _pool_chain_shared * -memory_pool_find_pool (memory_pool_t *pool, void *pointer) +memory_pool_find_pool (memory_pool_t * pool, void *pointer) { - struct _pool_chain_shared *cur = pool->shared_pool; + struct _pool_chain_shared *cur = pool->shared_pool; while (cur) { - if ((u_char *)pointer >= cur->begin && (u_char *)pointer <= (cur->begin + cur->len)) { + if ((u_char *) pointer >= cur->begin && (u_char *) pointer <= (cur->begin + cur->len)) { return cur; } cur = cur->next; @@ -331,7 +331,7 @@ memory_pool_find_pool (memory_pool_t *pool, void *pointer) } static inline int -__mutex_spin (memory_pool_mutex_t *mutex) +__mutex_spin (memory_pool_mutex_t * mutex) { /* check spin count */ if (g_atomic_int_dec_and_test (&mutex->spin)) { @@ -350,23 +350,23 @@ __mutex_spin (memory_pool_mutex_t *mutex) g_atomic_int_set (&mutex->spin, MUTEX_SPIN_COUNT); } #ifdef HAVE_ASM_PAUSE - __asm __volatile("pause"); + __asm __volatile ("pause"); #elif defined(HAVE_SCHED_YIELD) (void)sched_yield (); #elif defined(HAVE_NANOSLEEP) - struct timespec ts; + struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = MUTEX_SLEEP_TIME; /* Spin */ while (nanosleep (&ts, &ts) == -1 && errno == EINTR); #else -# error No methods to spin are defined +# error No methods to spin are defined #endif return 1; } static void -memory_pool_mutex_spin (memory_pool_mutex_t *mutex) +memory_pool_mutex_spin (memory_pool_mutex_t * mutex) { while (!g_atomic_int_compare_and_exchange (&mutex->lock, 0, 1)) { if (!__mutex_spin (mutex)) { @@ -377,34 +377,35 @@ memory_pool_mutex_spin (memory_pool_mutex_t *mutex) /* Simple implementation of spinlock */ void -memory_pool_lock_shared (memory_pool_t *pool, void *pointer) +memory_pool_lock_shared (memory_pool_t * pool, void *pointer) { - struct _pool_chain_shared *chain; + struct _pool_chain_shared *chain; chain = memory_pool_find_pool (pool, pointer); if (chain == NULL) { return; } - + memory_pool_lock_mutex (chain->lock); } -void memory_pool_unlock_shared (memory_pool_t *pool, void *pointer) +void +memory_pool_unlock_shared (memory_pool_t * pool, void *pointer) { - struct _pool_chain_shared *chain; + struct _pool_chain_shared *chain; chain = memory_pool_find_pool (pool, pointer); if (chain == NULL) { return; } - + memory_pool_unlock_mutex (chain->lock); } void -memory_pool_add_destructor (memory_pool_t *pool, pool_destruct_func func, void *data) +memory_pool_add_destructor (memory_pool_t * pool, pool_destruct_func func, void *data) { - struct _pool_destructors *cur, *tmp; + struct _pool_destructors *cur, *tmp; cur = memory_pool_alloc (pool, sizeof (struct _pool_destructors)); if (cur) { @@ -426,16 +427,16 @@ memory_pool_add_destructor (memory_pool_t *pool, pool_destruct_func func, void * } void -memory_pool_delete (memory_pool_t *pool) +memory_pool_delete (memory_pool_t * pool) { - struct _pool_chain *cur = pool->first_pool, *tmp; - struct _pool_chain_shared *cur_shared = pool->shared_pool, *tmp_shared; - struct _pool_destructors *destructor = pool->destructors; - + struct _pool_chain *cur = pool->first_pool, *tmp; + struct _pool_chain_shared *cur_shared = pool->shared_pool, *tmp_shared; + struct _pool_destructors *destructor = pool->destructors; + /* Call all pool destructors */ while (destructor) { /* Avoid calling destructors for NULL pointers */ - if (destructor->data != NULL) { + if (destructor->data != NULL) { destructor->func (destructor->data); } destructor = destructor->prev; @@ -447,7 +448,7 @@ memory_pool_delete (memory_pool_t *pool) g_slice_free1 (tmp->len, tmp->begin); g_slice_free (struct _pool_chain, tmp); STAT_LOCK (); - mem_pool_stat->chunks_freed ++; + mem_pool_stat->chunks_freed++; STAT_UNLOCK (); } /* Unmap shared memory */ @@ -456,16 +457,16 @@ memory_pool_delete (memory_pool_t *pool) cur_shared = cur_shared->next; munmap (tmp_shared, tmp_shared->len + sizeof (struct _pool_chain_shared)); STAT_LOCK (); - mem_pool_stat->chunks_freed ++; + mem_pool_stat->chunks_freed++; STAT_UNLOCK (); } - mem_pool_stat->pools_freed ++; + mem_pool_stat->pools_freed++; g_slice_free (memory_pool_t, pool); } void -memory_pool_stat (memory_pool_stat_t *st) +memory_pool_stat (memory_pool_stat_t * st) { st->pools_allocated = mem_pool_stat->pools_allocated; st->pools_freed = mem_pool_stat->pools_freed; @@ -483,16 +484,16 @@ memory_pool_ssize_t memory_pool_get_size () { #ifdef HAVE_GETPAGESIZE - return MAX (getpagesize (), FIXED_POOL_SIZE); + return MAX (getpagesize (), FIXED_POOL_SIZE); #else return MAX (sysconf (_SC_PAGESIZE), FIXED_POOL_SIZE); #endif } -memory_pool_mutex_t* -memory_pool_get_mutex (memory_pool_t *pool) +memory_pool_mutex_t * +memory_pool_get_mutex (memory_pool_t * pool) { - memory_pool_mutex_t *res; + memory_pool_mutex_t *res; if (pool != NULL) { res = memory_pool_alloc_shared (pool, sizeof (memory_pool_mutex_t)); res->lock = 0; @@ -503,24 +504,24 @@ memory_pool_get_mutex (memory_pool_t *pool) return NULL; } -void -memory_pool_lock_mutex (memory_pool_mutex_t *mutex) +void +memory_pool_lock_mutex (memory_pool_mutex_t * mutex) { memory_pool_mutex_spin (mutex); mutex->owner = getpid (); } -void -memory_pool_unlock_mutex (memory_pool_mutex_t *mutex) +void +memory_pool_unlock_mutex (memory_pool_mutex_t * mutex) { mutex->owner = 0; (void)g_atomic_int_compare_and_exchange (&mutex->lock, 1, 0); } -memory_pool_rwlock_t* -memory_pool_get_rwlock (memory_pool_t *pool) +memory_pool_rwlock_t * +memory_pool_get_rwlock (memory_pool_t * pool) { - memory_pool_rwlock_t *lock; + memory_pool_rwlock_t *lock; lock = memory_pool_alloc_shared (pool, sizeof (memory_pool_rwlock_t)); lock->__r_lock = memory_pool_get_mutex (pool); @@ -529,8 +530,8 @@ memory_pool_get_rwlock (memory_pool_t *pool) return lock; } -void -memory_pool_rlock_rwlock (memory_pool_rwlock_t *lock) +void +memory_pool_rlock_rwlock (memory_pool_rwlock_t * lock) { /* Spin on write lock */ while (g_atomic_int_get (&lock->__w_lock->lock)) { @@ -538,13 +539,13 @@ memory_pool_rlock_rwlock (memory_pool_rwlock_t *lock) break; } } - + g_atomic_int_inc (&lock->__r_lock->lock); lock->__r_lock->owner = getpid (); } -void -memory_pool_wlock_rwlock (memory_pool_rwlock_t *lock) +void +memory_pool_wlock_rwlock (memory_pool_rwlock_t * lock) { /* Spin on write lock first */ memory_pool_lock_mutex (lock->__w_lock); @@ -555,16 +556,16 @@ memory_pool_wlock_rwlock (memory_pool_rwlock_t *lock) } } -void -memory_pool_runlock_rwlock (memory_pool_rwlock_t *lock) +void +memory_pool_runlock_rwlock (memory_pool_rwlock_t * lock) { if (g_atomic_int_get (&lock->__r_lock->lock)) { (void)g_atomic_int_dec_and_test (&lock->__r_lock->lock); } } -void -memory_pool_wunlock_rwlock (memory_pool_rwlock_t *lock) +void +memory_pool_wunlock_rwlock (memory_pool_rwlock_t * lock) { memory_pool_unlock_mutex (lock->__w_lock); } diff --git a/src/memcached-test.c b/src/memcached-test.c index ef81cf73c..5e5557337 100644 --- a/src/memcached-test.c +++ b/src/memcached-test.c @@ -37,14 +37,14 @@ #define HOST "127.0.0.1" #define PORT 11211 -memcached_param_t cur_param; +memcached_param_t cur_param; static void -test_memc_callback (memcached_ctx_t *ctx, memc_error_t error, void *data) -{ - int s; - int r; - int *num = ((int *)data); +test_memc_callback (memcached_ctx_t * ctx, memc_error_t error, void *data) +{ + int s; + int r; + int *num = ((int *)data); printf ("result of memc command '%s' is '%s'\n", ctx->cmd, memc_strerror (error)); /* Connect */ if (*num == 0) { @@ -66,13 +66,13 @@ test_memc_callback (memcached_ctx_t *ctx, memc_error_t error, void *data) } -int +int main (int argc, char **argv) { - memcached_ctx_t mctx; - char *addr, buf[512]; - int num = 0; - + memcached_ctx_t mctx; + char *addr, buf[512]; + int num = 0; + event_init (); strcpy (cur_param.key, "testkey"); strcpy (buf, "test_value"); @@ -85,7 +85,7 @@ main (int argc, char **argv) else { addr = HOST; } - + mctx.protocol = TCP_TEXT; mctx.timeout.tv_sec = 1; mctx.timeout.tv_usec = 0; @@ -97,7 +97,7 @@ main (int argc, char **argv) inet_aton (addr, &mctx.addr); memc_init_ctx (&mctx); - + event_loop (0); return 0; } diff --git a/src/memcached.c b/src/memcached.c index 2d369c87c..fc7152940 100644 --- a/src/memcached.c +++ b/src/memcached.c @@ -23,7 +23,7 @@ */ #ifdef _THREAD_SAFE -#include <pthread.h> +# include <pthread.h> #endif #include <stdarg.h> @@ -64,24 +64,23 @@ #define MAX_RETRIES 3 /* Header for udp protocol */ -struct memc_udp_header -{ - uint16_t req_id; - uint16_t seq_num; - uint16_t dg_sent; - uint16_t unused; +struct memc_udp_header { + uint16_t req_id; + uint16_t seq_num; + uint16_t dg_sent; + uint16_t unused; }; -static void socket_callback (int fd, short what, void *arg); -static int memc_parse_header (char *buf, size_t *len, char **end); +static void socket_callback (int fd, short what, void *arg); +static int memc_parse_header (char *buf, size_t * len, char **end); /* * Write to syslog if OPT_DEBUG is specified */ static void -memc_log (const memcached_ctx_t *ctx, int line, const char *fmt, ...) +memc_log (const memcached_ctx_t * ctx, int line, const char *fmt, ...) { - va_list args; + va_list args; if (ctx->options & MEMC_OPT_DEBUG) { va_start (args, fmt); g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "memc_debug(%d): host: %s, port: %d", line, inet_ntoa (ctx->addr), ntohs (ctx->port)); @@ -94,13 +93,13 @@ memc_log (const memcached_ctx_t *ctx, int line, const char *fmt, ...) * Callback for write command */ static void -write_handler (int fd, short what, memcached_ctx_t *ctx) +write_handler (int fd, short what, memcached_ctx_t * ctx) { - char read_buf[READ_BUFSIZ]; - int retries; - ssize_t r; - struct memc_udp_header header; - struct iovec iov[4]; + char read_buf[READ_BUFSIZ]; + int retries; + ssize_t r; + struct memc_udp_header header; + struct iovec iov[4]; /* Write something to memcached */ if (what == EV_WRITE) { @@ -159,7 +158,7 @@ write_handler (int fd, short what, memcached_ctx_t *ctx) ctx->callback (ctx, SERVER_ERROR, ctx->callback_data); } if (header.req_id != ctx->count && retries < MAX_RETRIES) { - retries ++; + retries++; /* Not our reply packet */ continue; } @@ -195,16 +194,16 @@ write_handler (int fd, short what, memcached_ctx_t *ctx) * Callback for read command */ static void -read_handler (int fd, short what, memcached_ctx_t *ctx) +read_handler (int fd, short what, memcached_ctx_t * ctx) { - char read_buf[READ_BUFSIZ]; - char *p; - ssize_t r; - size_t datalen; - struct memc_udp_header header; - struct iovec iov[2]; - int retries = 0, t; - + char read_buf[READ_BUFSIZ]; + char *p; + ssize_t r; + size_t datalen; + struct memc_udp_header header; + struct iovec iov[2]; + int retries = 0, t; + if (what == EV_WRITE) { /* Send command to memcached */ if (ctx->protocol == UDP_TEXT) { @@ -297,9 +296,8 @@ read_handler (int fd, short what, memcached_ctx_t *ctx) else { p = read_buf; } - - if (strncmp (ctx->param->buf + ctx->param->bufpos + r - sizeof (END_TRAILER) - sizeof (CRLF) + 2, - END_TRAILER, sizeof (END_TRAILER) - 1) == 0) { + + if (strncmp (ctx->param->buf + ctx->param->bufpos + r - sizeof (END_TRAILER) - sizeof (CRLF) + 2, END_TRAILER, sizeof (END_TRAILER) - 1) == 0) { r -= sizeof (END_TRAILER) - sizeof (CRLF) - 2; memcpy (ctx->param->buf + ctx->param->bufpos, p, r); event_del (&ctx->mem_ev); @@ -323,20 +321,20 @@ read_handler (int fd, short what, memcached_ctx_t *ctx) event_del (&ctx->mem_ev); ctx->callback (ctx, SERVER_TIMEOUT, ctx->callback_data); } - + } /* * Callback for delete command */ static void -delete_handler (int fd, short what, memcached_ctx_t *ctx) +delete_handler (int fd, short what, memcached_ctx_t * ctx) { - char read_buf[READ_BUFSIZ]; - int retries; - ssize_t r; - struct memc_udp_header header; - struct iovec iov[2]; + char read_buf[READ_BUFSIZ]; + int retries; + ssize_t r; + struct memc_udp_header header; + struct iovec iov[2]; /* Write something to memcached */ if (what == EV_WRITE) { @@ -382,7 +380,7 @@ delete_handler (int fd, short what, memcached_ctx_t *ctx) return; } if (header.req_id != ctx->count && retries < MAX_RETRIES) { - retries ++; + retries++; /* Not our reply packet */ continue; } @@ -416,36 +414,36 @@ delete_handler (int fd, short what, memcached_ctx_t *ctx) static void socket_callback (int fd, short what, void *arg) { - memcached_ctx_t *ctx = (memcached_ctx_t *)arg; + memcached_ctx_t *ctx = (memcached_ctx_t *) arg; switch (ctx->op) { - case CMD_NULL: - /* Do nothing here */ - break; - case CMD_CONNECT: - /* We have write readiness after connect call, so reinit event */ - ctx->cmd = "connect"; - if (what == EV_WRITE) { - event_del (&ctx->mem_ev); - event_set (&ctx->mem_ev, ctx->sock, EV_READ | EV_PERSIST | EV_TIMEOUT, socket_callback, (void *)ctx); - event_add (&ctx->mem_ev, NULL); - ctx->callback (ctx, OK, ctx->callback_data); - ctx->alive = 1; - } - else { - ctx->callback (ctx, SERVER_TIMEOUT, ctx->callback_data); - ctx->alive = 0; - } - break; - case CMD_WRITE: - write_handler (fd, what, ctx); - break; - case CMD_READ: - read_handler (fd, what, ctx); - break; - case CMD_DELETE: - delete_handler (fd, what, ctx); - break; + case CMD_NULL: + /* Do nothing here */ + break; + case CMD_CONNECT: + /* We have write readiness after connect call, so reinit event */ + ctx->cmd = "connect"; + if (what == EV_WRITE) { + event_del (&ctx->mem_ev); + event_set (&ctx->mem_ev, ctx->sock, EV_READ | EV_PERSIST | EV_TIMEOUT, socket_callback, (void *)ctx); + event_add (&ctx->mem_ev, NULL); + ctx->callback (ctx, OK, ctx->callback_data); + ctx->alive = 1; + } + else { + ctx->callback (ctx, SERVER_TIMEOUT, ctx->callback_data); + ctx->alive = 0; + } + break; + case CMD_WRITE: + write_handler (fd, what, ctx); + break; + case CMD_READ: + read_handler (fd, what, ctx); + break; + case CMD_DELETE: + delete_handler (fd, what, ctx); + break; } } @@ -453,7 +451,7 @@ socket_callback (int fd, short what, void *arg) * Common callback function for memcached operations if no user's callback is specified */ static void -common_memc_callback (memcached_ctx_t *ctx, memc_error_t error, void *data) +common_memc_callback (memcached_ctx_t * ctx, memc_error_t error, void *data) { memc_log (ctx, __LINE__, "common_memc_callback: result of memc command '%s' is '%s'", ctx->cmd, memc_strerror (error)); } @@ -462,10 +460,10 @@ common_memc_callback (memcached_ctx_t *ctx, memc_error_t error, void *data) * Make socket for udp connection */ static int -memc_make_udp_sock (memcached_ctx_t *ctx) +memc_make_udp_sock (memcached_ctx_t * ctx) { - struct sockaddr_in sc; - int ofl; + struct sockaddr_in sc; + int ofl; bzero (&sc, sizeof (struct sockaddr_in *)); sc.sin_family = AF_INET; @@ -480,8 +478,8 @@ memc_make_udp_sock (memcached_ctx_t *ctx) } /* set nonblocking */ - ofl = fcntl(ctx->sock, F_GETFL, 0); - fcntl(ctx->sock, F_SETFL, ofl | O_NONBLOCK); + ofl = fcntl (ctx->sock, F_GETFL, 0); + fcntl (ctx->sock, F_SETFL, ofl | O_NONBLOCK); /* * Call connect to set default destination for datagrams @@ -490,17 +488,17 @@ memc_make_udp_sock (memcached_ctx_t *ctx) ctx->op = CMD_CONNECT; event_set (&ctx->mem_ev, ctx->sock, EV_WRITE | EV_TIMEOUT, socket_callback, (void *)ctx); event_add (&ctx->mem_ev, NULL); - return connect (ctx->sock, (struct sockaddr*)&sc, sizeof (struct sockaddr_in)); + return connect (ctx->sock, (struct sockaddr *)&sc, sizeof (struct sockaddr_in)); } /* * Make socket for tcp connection */ static int -memc_make_tcp_sock (memcached_ctx_t *ctx) +memc_make_tcp_sock (memcached_ctx_t * ctx) { - struct sockaddr_in sc; - int ofl, r; + struct sockaddr_in sc; + int ofl, r; bzero (&sc, sizeof (struct sockaddr_in *)); sc.sin_family = AF_INET; @@ -515,10 +513,10 @@ memc_make_tcp_sock (memcached_ctx_t *ctx) } /* set nonblocking */ - ofl = fcntl(ctx->sock, F_GETFL, 0); - fcntl(ctx->sock, F_SETFL, ofl | O_NONBLOCK); - - if ((r = connect (ctx->sock, (struct sockaddr*)&sc, sizeof (struct sockaddr_in))) == -1) { + ofl = fcntl (ctx->sock, F_GETFL, 0); + fcntl (ctx->sock, F_SETFL, ofl | O_NONBLOCK); + + if ((r = connect (ctx->sock, (struct sockaddr *)&sc, sizeof (struct sockaddr_in))) == -1) { if (errno != EINPROGRESS) { close (ctx->sock); ctx->sock = -1; @@ -536,10 +534,10 @@ memc_make_tcp_sock (memcached_ctx_t *ctx) * Parse VALUE reply from server and set len argument to value returned by memcached */ static int -memc_parse_header (char *buf, size_t *len, char **end) +memc_parse_header (char *buf, size_t * len, char **end) { - char *p, *c; - int i; + char *p, *c; + int i; /* VALUE <key> <flags> <bytes> [<cas unique>]\r\n */ c = strstr (buf, CRLF); @@ -547,10 +545,10 @@ memc_parse_header (char *buf, size_t *len, char **end) return -1; } *end = c + sizeof (CRLF) - 1; - + if (strncmp (buf, "VALUE ", sizeof ("VALUE ") - 1) == 0) { p = buf + sizeof ("VALUE ") - 1; - + /* Read bytes value and ignore all other fields, such as flags and key */ for (i = 0; i < 2; i++) { while (p++ < c && *p != ' '); @@ -575,7 +573,7 @@ memc_parse_header (char *buf, size_t *len, char **end) * Common read command handler for memcached */ memc_error_t -memc_read (memcached_ctx_t *ctx, const char *cmd, memcached_param_t *param) +memc_read (memcached_ctx_t * ctx, const char *cmd, memcached_param_t * param) { ctx->cmd = cmd; ctx->op = CMD_READ; @@ -590,7 +588,7 @@ memc_read (memcached_ctx_t *ctx, const char *cmd, memcached_param_t *param) * Common write command handler for memcached */ memc_error_t -memc_write (memcached_ctx_t *ctx, const char *cmd, memcached_param_t *param, int expire) +memc_write (memcached_ctx_t * ctx, const char *cmd, memcached_param_t * param, int expire) { ctx->cmd = cmd; ctx->op = CMD_WRITE; @@ -601,11 +599,12 @@ memc_write (memcached_ctx_t *ctx, const char *cmd, memcached_param_t *param, int return OK; } + /* * Delete command handler */ memc_error_t -memc_delete (memcached_ctx_t *ctx, memcached_param_t *param) +memc_delete (memcached_ctx_t * ctx, memcached_param_t * param) { ctx->cmd = "delete"; ctx->op = CMD_DELETE; @@ -621,11 +620,11 @@ memc_delete (memcached_ctx_t *ctx, memcached_param_t *param) * writing is done to each memcached server */ memc_error_t -memc_write_mirror (memcached_ctx_t *ctx, size_t memcached_num, const char *cmd, memcached_param_t *param, int expire) +memc_write_mirror (memcached_ctx_t * ctx, size_t memcached_num, const char *cmd, memcached_param_t * param, int expire) { - memc_error_t r, result = OK; + memc_error_t r, result = OK; - while (memcached_num --) { + while (memcached_num--) { if (ctx[memcached_num].alive == 1) { r = memc_write (&ctx[memcached_num], cmd, param, expire); if (r != OK) { @@ -644,11 +643,11 @@ memc_write_mirror (memcached_ctx_t *ctx, size_t memcached_num, const char *cmd, * reading is done from first active memcached server */ memc_error_t -memc_read_mirror (memcached_ctx_t *ctx, size_t memcached_num, const char *cmd, memcached_param_t *param) +memc_read_mirror (memcached_ctx_t * ctx, size_t memcached_num, const char *cmd, memcached_param_t * param) { - memc_error_t r, result = OK; + memc_error_t r, result = OK; - while (memcached_num --) { + while (memcached_num--) { if (ctx[memcached_num].alive == 1) { r = memc_read (&ctx[memcached_num], cmd, param); if (r != OK) { @@ -675,11 +674,11 @@ memc_read_mirror (memcached_ctx_t *ctx, size_t memcached_num, const char *cmd, m * deleting is done for each active memcached server */ memc_error_t -memc_delete_mirror (memcached_ctx_t *ctx, size_t memcached_num, const char *cmd, memcached_param_t *param) +memc_delete_mirror (memcached_ctx_t * ctx, size_t memcached_num, const char *cmd, memcached_param_t * param) { - memc_error_t r, result = OK; + memc_error_t r, result = OK; - while (memcached_num --) { + while (memcached_num--) { if (ctx[memcached_num].alive == 1) { r = memc_delete (&ctx[memcached_num], param); if (r != OK) { @@ -699,8 +698,8 @@ memc_delete_mirror (memcached_ctx_t *ctx, size_t memcached_num, const char *cmd, /* * Initialize memcached context for specified protocol */ -int -memc_init_ctx (memcached_ctx_t *ctx) +int +memc_init_ctx (memcached_ctx_t * ctx) { if (ctx == NULL) { return -1; @@ -715,26 +714,27 @@ memc_init_ctx (memcached_ctx_t *ctx) } switch (ctx->protocol) { - case UDP_TEXT: - return memc_make_udp_sock (ctx); - break; - case TCP_TEXT: - return memc_make_tcp_sock (ctx); - break; + case UDP_TEXT: + return memc_make_udp_sock (ctx); + break; + case TCP_TEXT: + return memc_make_tcp_sock (ctx); + break; /* Not implemented */ - case UDP_BIN: - case TCP_BIN: - default: - return -1; + case UDP_BIN: + case TCP_BIN: + default: + return -1; } } + /* * Mirror init */ -int -memc_init_ctx_mirror (memcached_ctx_t *ctx, size_t memcached_num) +int +memc_init_ctx_mirror (memcached_ctx_t * ctx, size_t memcached_num) { - int r, result = -1; + int r, result = -1; while (memcached_num--) { if (ctx[memcached_num].alive == 1) { r = memc_init_ctx (&ctx[memcached_num]); @@ -755,7 +755,7 @@ memc_init_ctx_mirror (memcached_ctx_t *ctx, size_t memcached_num) * Close context connection */ int -memc_close_ctx (memcached_ctx_t *ctx) +memc_close_ctx (memcached_ctx_t * ctx) { if (ctx != NULL && ctx->sock != -1) { event_del (&ctx->mem_ev); @@ -764,13 +764,14 @@ memc_close_ctx (memcached_ctx_t *ctx) return -1; } + /* * Mirror close */ -int -memc_close_ctx_mirror (memcached_ctx_t *ctx, size_t memcached_num) +int +memc_close_ctx_mirror (memcached_ctx_t * ctx, size_t memcached_num) { - int r = 0; + int r = 0; while (memcached_num--) { if (ctx[memcached_num].alive == 1) { r = memc_close_ctx (&ctx[memcached_num]); @@ -785,38 +786,39 @@ memc_close_ctx_mirror (memcached_ctx_t *ctx, size_t memcached_num) } -const char * memc_strerror (memc_error_t err) +const char * +memc_strerror (memc_error_t err) { - const char *p; + const char *p; switch (err) { - case OK: - p = "Ok"; - break; - case BAD_COMMAND: - p = "Bad command"; - break; - case CLIENT_ERROR: - p = "Client error"; - break; - case SERVER_ERROR: - p = "Server error"; - break; - case SERVER_TIMEOUT: - p = "Server timeout"; - break; - case NOT_EXISTS: - p = "Key not found"; - break; - case EXISTS: - p = "Key already exists"; - break; - case WRONG_LENGTH: - p = "Wrong result length"; - break; - default: - p = "Unknown error"; - break; + case OK: + p = "Ok"; + break; + case BAD_COMMAND: + p = "Bad command"; + break; + case CLIENT_ERROR: + p = "Client error"; + break; + case SERVER_ERROR: + p = "Server error"; + break; + case SERVER_TIMEOUT: + p = "Server timeout"; + break; + case NOT_EXISTS: + p = "Key not found"; + break; + case EXISTS: + p = "Key already exists"; + break; + case WRONG_LENGTH: + p = "Wrong result length"; + break; + default: + p = "Unknown error"; + break; } return p; diff --git a/src/message.c b/src/message.c index f1886e687..4bfaf093a 100644 --- a/src/message.c +++ b/src/message.c @@ -32,18 +32,18 @@ #define RECURSION_LIMIT 30 -GByteArray* -strip_html_tags (struct worker_task *task, memory_pool_t *pool, struct mime_text_part *part, GByteArray *src, int *stateptr) +GByteArray * +strip_html_tags (struct worker_task *task, memory_pool_t * pool, struct mime_text_part *part, GByteArray * src, int *stateptr) { - uint8_t *tbuf = NULL, *p, *tp = NULL, *rp, *tbegin = NULL, c, lc; - int br, i = 0, depth = 0, in_q = 0; - int state = 0; - GByteArray *buf; - GNode *level_ptr = NULL; + uint8_t *tbuf = NULL, *p, *tp = NULL, *rp, *tbegin = NULL, c, lc; + int br, i = 0, depth = 0, in_q = 0; + int state = 0; + GByteArray *buf; + GNode *level_ptr = NULL; if (stateptr) state = *stateptr; - + buf = g_byte_array_sized_new (src->len); g_byte_array_append (buf, src->data, src->len); @@ -55,182 +55,187 @@ strip_html_tags (struct worker_task *task, memory_pool_t *pool, struct mime_text while (i < src->len) { switch (c) { - case '\0': - break; - case '<': - if (g_ascii_isspace(*(p + 1))) { - goto reg_char; - } - if (state == 0) { - lc = '<'; - tbegin = p + 1; - state = 1; - } else if (state == 1) { - depth++; - } - break; + case '\0': + break; + case '<': + if (g_ascii_isspace (*(p + 1))) { + goto reg_char; + } + if (state == 0) { + lc = '<'; + tbegin = p + 1; + state = 1; + } + else if (state == 1) { + depth++; + } + break; - case '(': - if (state == 2) { - if (lc != '"' && lc != '\'') { - lc = '('; - br++; - } - } else if (state == 0) { - *(rp++) = c; + case '(': + if (state == 2) { + if (lc != '"' && lc != '\'') { + lc = '('; + br++; } - break; + } + else if (state == 0) { + *(rp++) = c; + } + break; - case ')': - if (state == 2) { - if (lc != '"' && lc != '\'') { - lc = ')'; - br--; - } - } else if (state == 0) { - *(rp++) = c; + case ')': + if (state == 2) { + if (lc != '"' && lc != '\'') { + lc = ')'; + br--; } - break; + } + else if (state == 0) { + *(rp++) = c; + } + break; - case '>': - if (depth) { - depth--; - break; - } + case '>': + if (depth) { + depth--; + break; + } - if (in_q) { - break; - } + if (in_q) { + break; + } - switch (state) { - case 1: /* HTML/XML */ - lc = '>'; - in_q = state = 0; - *p = '\0'; - add_html_node (task, pool, part, tbegin, &level_ptr); - *p = '>'; - break; - - case 2: /* PHP */ - if (!br && lc != '\"' && *(p-1) == '?') { - in_q = state = 0; - tp = tbuf; - } - break; - - case 3: - in_q = state = 0; - tp = tbuf; - break; - - case 4: /* JavaScript/CSS/etc... */ - if (p >= src->data + 2 && *(p-1) == '-' && *(p-2) == '-') { - in_q = state = 0; - tp = tbuf; - } - break; - - default: - *(rp++) = c; - break; - } + switch (state) { + case 1: /* HTML/XML */ + lc = '>'; + in_q = state = 0; + *p = '\0'; + add_html_node (task, pool, part, tbegin, &level_ptr); + *p = '>'; break; - case '"': - case '\'': - if (state == 2 && *(p-1) != '\\') { - if (lc == c) { - lc = '\0'; - } else if (lc != '\\') { - lc = c; - } - } else if (state == 0) { - *(rp++) = c; - } - if (state && p != src->data && *(p-1) != '\\' && (!in_q || *p == in_q)) { - if (in_q) { - in_q = 0; - } else { - in_q = *p; - } + case 2: /* PHP */ + if (!br && lc != '\"' && *(p - 1) == '?') { + in_q = state = 0; + tp = tbuf; } break; - - case '!': - /* JavaScript & Other HTML scripting languages */ - if (state == 1 && *(p-1) == '<') { - state = 3; - lc = c; - } else { - if (state == 0) { - *(rp++) = c; - } - } + + case 3: + in_q = state = 0; + tp = tbuf; break; - case '-': - if (state == 3 && p >= src->data + 2 && *(p-1) == '-' && *(p-2) == '!') { - state = 4; - } else { - goto reg_char; + case 4: /* JavaScript/CSS/etc... */ + if (p >= src->data + 2 && *(p - 1) == '-' && *(p - 2) == '-') { + in_q = state = 0; + tp = tbuf; } break; - case '?': + default: + *(rp++) = c; + break; + } + break; - if (state == 1 && *(p-1) == '<') { - br = 0; - state = 2; - break; + case '"': + case '\'': + if (state == 2 && *(p - 1) != '\\') { + if (lc == c) { + lc = '\0'; } + else if (lc != '\\') { + lc = c; + } + } + else if (state == 0) { + *(rp++) = c; + } + if (state && p != src->data && *(p - 1) != '\\' && (!in_q || *p == in_q)) { + if (in_q) { + in_q = 0; + } + else { + in_q = *p; + } + } + break; - case 'E': - case 'e': - /* !DOCTYPE exception */ - if (state == 3 && p > src->data + 6 - && g_ascii_tolower(*(p-1)) == 'p' - && g_ascii_tolower(*(p-2)) == 'y' - && g_ascii_tolower(*(p-3)) == 't' - && g_ascii_tolower(*(p-4)) == 'c' - && g_ascii_tolower(*(p-5)) == 'o' - && g_ascii_tolower(*(p-6)) == 'd') { - state = 1; - break; + case '!': + /* JavaScript & Other HTML scripting languages */ + if (state == 1 && *(p - 1) == '<') { + state = 3; + lc = c; + } + else { + if (state == 0) { + *(rp++) = c; } - /* fall-through */ + } + break; - case 'l': + case '-': + if (state == 3 && p >= src->data + 2 && *(p - 1) == '-' && *(p - 2) == '!') { + state = 4; + } + else { + goto reg_char; + } + break; - /* swm: If we encounter '<?xml' then we shouldn't be in - * state == 2 (PHP). Switch back to HTML. - */ + case '?': - if (state == 2 && p > src->data + 2 && *(p-1) == 'm' && *(p-2) == 'x') { - state = 1; - break; - } + if (state == 1 && *(p - 1) == '<') { + br = 0; + state = 2; + break; + } - /* fall-through */ - default: -reg_char: - if (state == 0) { - *(rp++) = c; - } + case 'E': + case 'e': + /* !DOCTYPE exception */ + if (state == 3 && p > src->data + 6 + && g_ascii_tolower (*(p - 1)) == 'p' + && g_ascii_tolower (*(p - 2)) == 'y' + && g_ascii_tolower (*(p - 3)) == 't' && g_ascii_tolower (*(p - 4)) == 'c' && g_ascii_tolower (*(p - 5)) == 'o' && g_ascii_tolower (*(p - 6)) == 'd') { + state = 1; + break; + } + /* fall-through */ + + case 'l': + + /* swm: If we encounter '<?xml' then we shouldn't be in + * state == 2 (PHP). Switch back to HTML. + */ + + if (state == 2 && p > src->data + 2 && *(p - 1) == 'm' && *(p - 2) == 'x') { + state = 1; break; + } + + /* fall-through */ + default: + reg_char: + if (state == 0) { + *(rp++) = c; + } + break; } i++; if (i < src->len) { c = *(++p); } - } + } if (rp < buf->data + src->len) { *rp = '\0'; g_byte_array_set_size (buf, rp - buf->data); } - + /* Check tag balancing */ if (level_ptr && level_ptr->data != NULL) { - part->is_balanced = FALSE; + part->is_balanced = FALSE; } if (stateptr) { @@ -241,19 +246,19 @@ reg_char: } static void -parse_qmail_recv (memory_pool_t *pool, char *line, struct received_header *r) +parse_qmail_recv (memory_pool_t * pool, char *line, struct received_header *r) { - char *s, *p, t; - + char *s, *p, t; + /* We are intersted only with received from network headers */ if ((p = strstr (line, "from network")) == NULL) { r->is_error = 2; return; } - + p += sizeof ("from network") - 1; while (g_ascii_isspace (*p) || *p == '[') { - p ++; + p++; } /* format is ip/host */ s = p; @@ -270,7 +275,7 @@ parse_qmail_recv (memory_pool_t *pool, char *line, struct received_header *r) /* Now try to parse hostname */ s = ++p; while (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { - p ++; + p++; } t = *p; *p = '\0'; @@ -281,11 +286,11 @@ parse_qmail_recv (memory_pool_t *pool, char *line, struct received_header *r) } static void -parse_recv_header (memory_pool_t *pool, char *line, struct received_header *r) +parse_recv_header (memory_pool_t * pool, char *line, struct received_header *r) { - char *p, *s, t, **res = NULL; - int state = 0, next_state = 0; - + char *p, *s, t, **res = NULL; + int state = 0, next_state = 0; + g_strstrip (line); p = line; s = line; @@ -293,160 +298,158 @@ parse_recv_header (memory_pool_t *pool, char *line, struct received_header *r) while (*p) { switch (state) { /* Initial state, search for from */ - case 0: - if (*p == 'f' || *p == 'F') { - if (g_ascii_tolower (*++p) == 'r' && - g_ascii_tolower (*++p) == 'o' && - g_ascii_tolower (*++p) == 'm') { - p ++; - state = 99; - next_state = 1; - } - } - else { - /* This can be qmail header, parse it separately */ - parse_qmail_recv (pool, line, r); - return; - } - break; - /* Read hostname */ - case 1: - if (*p == '[') { - /* This should be IP address */ - res = &r->from_ip; - state = 98; - next_state = 3; - s = ++p; - } - else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { - p ++; - } - else { - t = *p; - *p = '\0'; - r->from_hostname = memory_pool_strdup (pool, s); - *p = t; + case 0: + if (*p == 'f' || *p == 'F') { + if (g_ascii_tolower (*++p) == 'r' && g_ascii_tolower (*++p) == 'o' && g_ascii_tolower (*++p) == 'm') { + p++; state = 99; - next_state = 3; + next_state = 1; } - break; + } + else { + /* This can be qmail header, parse it separately */ + parse_qmail_recv (pool, line, r); + return; + } + break; + /* Read hostname */ + case 1: + if (*p == '[') { + /* This should be IP address */ + res = &r->from_ip; + state = 98; + next_state = 3; + s = ++p; + } + else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { + p++; + } + else { + t = *p; + *p = '\0'; + r->from_hostname = memory_pool_strdup (pool, s); + *p = t; + state = 99; + next_state = 3; + } + break; /* Try to extract additional info */ - case 3: - /* Try to extract ip or () info or by */ - if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == 'y') { - p += 2; - /* Skip spaces after by */ - state = 99; - next_state = 5; - } - else if (*p == '(') { - state = 99; - next_state = 4; - p ++; - } - else if (*p == '[') { - /* Got ip before '(' so extract it */ - s = ++p; - res = &r->from_ip; - state = 98; - next_state = 3; - } - else { - p ++; - } - break; + case 3: + /* Try to extract ip or () info or by */ + if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == 'y') { + p += 2; + /* Skip spaces after by */ + state = 99; + next_state = 5; + } + else if (*p == '(') { + state = 99; + next_state = 4; + p++; + } + else if (*p == '[') { + /* Got ip before '(' so extract it */ + s = ++p; + res = &r->from_ip; + state = 98; + next_state = 3; + } + else { + p++; + } + break; /* We are in () block. Here can be found real hostname and real ip, this is written by some MTA */ - case 4: - /* End of block */ - if (*p == ')') { - p ++; - state = 3; - } - else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { - p ++; - } - else if (*p == '[') { - s = ++p; - state = 98; - res = &r->real_ip; - next_state = 3; - } - else { - if (s != p) { - /* Got some real hostname */ - /* check whether it is helo or p is not space symbol*/ - if (!g_ascii_isspace (*p) || *(p + 1) != '[') { - /* skip all */ - while (*p++ != ')' && *p != '\0'); - state = 3; - } - else { - t = *p; - *p = '\0'; - r->real_hostname = memory_pool_strdup (pool, s); - *p = t; - /* Now parse ip */ - p += 2; - s = p; - res = &r->real_ip; - state = 98; - next_state = 4; - } + case 4: + /* End of block */ + if (*p == ')') { + p++; + state = 3; + } + else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { + p++; + } + else if (*p == '[') { + s = ++p; + state = 98; + res = &r->real_ip; + next_state = 3; + } + else { + if (s != p) { + /* Got some real hostname */ + /* check whether it is helo or p is not space symbol */ + if (!g_ascii_isspace (*p) || *(p + 1) != '[') { + /* skip all */ + while (*p++ != ')' && *p != '\0'); + state = 3; } else { - r->is_error = 1; - return; + t = *p; + *p = '\0'; + r->real_hostname = memory_pool_strdup (pool, s); + *p = t; + /* Now parse ip */ + p += 2; + s = p; + res = &r->real_ip; + state = 98; + next_state = 4; } } - break; - /* Got by word */ - case 5: - /* Here can be only hostname */ - if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { - p ++; - } else { - /* We got something like hostname */ - t = *p; - *p = '\0'; - r->by_hostname = memory_pool_strdup (pool, s); - *p = t; - /* Now end of parsing */ + r->is_error = 1; return; } - break; + } + break; + /* Got by word */ + case 5: + /* Here can be only hostname */ + if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { + p++; + } + else { + /* We got something like hostname */ + t = *p; + *p = '\0'; + r->by_hostname = memory_pool_strdup (pool, s); + *p = t; + /* Now end of parsing */ + return; + } + break; /* Extract ip */ - case 98: - while (g_ascii_isdigit (*++p) || *p == '.'); - if (*p != ']') { - /* Not an ip in fact */ - state = next_state; - p ++; - } - else { - *p = '\0'; - *res = memory_pool_strdup (pool, s); - *p = ']'; - p ++; - state = next_state; - } - break; + case 98: + while (g_ascii_isdigit (*++p) || *p == '.'); + if (*p != ']') { + /* Not an ip in fact */ + state = next_state; + p++; + } + else { + *p = '\0'; + *res = memory_pool_strdup (pool, s); + *p = ']'; + p++; + state = next_state; + } + break; /* Skip spaces */ - case 99: - if (!g_ascii_isspace (*p)) { - state = next_state; - s = p; - } - else { - p ++; - } - break; - case 100: - r->is_error = 1; - return; - break; + case 99: + if (!g_ascii_isspace (*p)) { + state = next_state; + s = p; + } + else { + p++; + } + break; + case 100: + r->is_error = 1; + return; + break; } } @@ -457,18 +460,18 @@ parse_recv_header (memory_pool_t *pool, char *line, struct received_header *r) static void free_byte_array_callback (void *pointer) { - GByteArray *arr = (GByteArray *)pointer; + GByteArray *arr = (GByteArray *) pointer; g_byte_array_free (arr, TRUE); } -static GByteArray * -convert_text_to_utf (struct worker_task *task, GByteArray *part_content, GMimeContentType *type, struct mime_text_part *text_part) +static GByteArray * +convert_text_to_utf (struct worker_task *task, GByteArray * part_content, GMimeContentType * type, struct mime_text_part *text_part) { - GError *err = NULL; - gsize read_bytes, write_bytes; - const char *charset; - gchar *res_str; - GByteArray *result_array; + GError *err = NULL; + gsize read_bytes, write_bytes; + const char *charset; + gchar *res_str; + GByteArray *result_array; if (task->cfg->raw_mode) { text_part->is_raw = TRUE; @@ -479,15 +482,13 @@ convert_text_to_utf (struct worker_task *task, GByteArray *part_content, GMimeCo text_part->is_raw = TRUE; return part_content; } - + if (g_ascii_strcasecmp (charset, "utf-8") == 0 || g_ascii_strcasecmp (charset, "utf8") == 0) { text_part->is_raw = TRUE; return part_content; } - - res_str = g_convert_with_fallback (part_content->data, part_content->len, - "UTF-8", charset, NULL, - &read_bytes, &write_bytes, &err); + + res_str = g_convert_with_fallback (part_content->data, part_content->len, "UTF-8", charset, NULL, &read_bytes, &write_bytes, &err); if (res_str == NULL) { msg_warn ("convert_text_to_utf: cannot convert from %s to utf8: %s", charset, err ? err->message : "unknown problem"); text_part->is_raw = TRUE; @@ -497,16 +498,16 @@ convert_text_to_utf (struct worker_task *task, GByteArray *part_content, GMimeCo result_array = memory_pool_alloc (task->task_pool, sizeof (GByteArray)); result_array->data = res_str; result_array->len = write_bytes + 1; - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, res_str); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, res_str); text_part->is_raw = FALSE; return result_array; } static void -process_text_part (struct worker_task *task, GByteArray *part_content, GMimeContentType *type, gboolean is_empty) +process_text_part (struct worker_task *task, GByteArray * part_content, GMimeContentType * type, gboolean is_empty) { - struct mime_text_part *text_part; + struct mime_text_part *text_part; if (g_mime_content_type_is_type (type, "text", "html") || g_mime_content_type_is_type (type, "text", "xhtml")) { msg_debug ("mime_foreach_callback: got urls from text/html part"); @@ -524,8 +525,8 @@ process_text_part (struct worker_task *task, GByteArray *part_content, GMimeCont text_part->is_balanced = TRUE; text_part->html_nodes = NULL; - text_part->html_urls = g_tree_new ( (GCompareFunc)g_ascii_strcasecmp); - text_part->urls = g_tree_new ( (GCompareFunc)g_ascii_strcasecmp); + text_part->html_urls = g_tree_new ((GCompareFunc) g_ascii_strcasecmp); + text_part->urls = g_tree_new ((GCompareFunc) g_ascii_strcasecmp); text_part->content = strip_html_tags (task, task->task_pool, text_part, part_content, NULL); @@ -541,11 +542,11 @@ process_text_part (struct worker_task *task, GByteArray *part_content, GMimeCont } text_part->fuzzy = fuzzy_init_byte_array (text_part->content, task->task_pool); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)free_byte_array_callback, text_part->content); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_tree_destroy, text_part->html_urls); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_tree_destroy, text_part->urls); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) free_byte_array_callback, text_part->content); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_tree_destroy, text_part->html_urls); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_tree_destroy, text_part->urls); task->text_parts = g_list_prepend (task->text_parts, text_part); - } + } else if (g_mime_content_type_is_type (type, "text", "plain")) { msg_debug ("mime_foreach_callback: got urls from text/plain part"); @@ -562,42 +563,42 @@ process_text_part (struct worker_task *task, GByteArray *part_content, GMimeCont text_part->content = text_part->orig; text_part->fuzzy = fuzzy_init_byte_array (text_part->content, task->task_pool); text_part->html_urls = NULL; - text_part->urls = g_tree_new ( (GCompareFunc)g_ascii_strcasecmp); + text_part->urls = g_tree_new ((GCompareFunc) g_ascii_strcasecmp); url_parse_text (task->task_pool, task, text_part, FALSE); task->text_parts = g_list_prepend (task->text_parts, text_part); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_tree_destroy, text_part->urls); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_tree_destroy, text_part->urls); } } #ifdef GMIME24 static void -mime_foreach_callback (GMimeObject *parent, GMimeObject *part, gpointer user_data) +mime_foreach_callback (GMimeObject * parent, GMimeObject * part, gpointer user_data) #else static void -mime_foreach_callback (GMimeObject *part, gpointer user_data) +mime_foreach_callback (GMimeObject * part, gpointer user_data) #endif { - struct worker_task *task = (struct worker_task *)user_data; - struct mime_part *mime_part; - GMimeContentType *type; - GMimeDataWrapper *wrapper; - GMimeStream *part_stream; - GByteArray *part_content; - - task->parts_count ++; - + struct worker_task *task = (struct worker_task *)user_data; + struct mime_part *mime_part; + GMimeContentType *type; + GMimeDataWrapper *wrapper; + GMimeStream *part_stream; + GByteArray *part_content; + + task->parts_count++; + /* 'part' points to the current part node that g_mime_message_foreach_part() is iterating over */ - + /* find out what class 'part' is... */ if (GMIME_IS_MESSAGE_PART (part)) { /* message/rfc822 or message/news */ - GMimeMessage *message; - + GMimeMessage *message; + /* g_mime_message_foreach_part() won't descend into - child message parts, so if we want to count any - subparts of this child message, we'll have to call - g_mime_message_foreach_part() again here. */ - + child message parts, so if we want to count any + subparts of this child message, we'll have to call + g_mime_message_foreach_part() again here. */ + message = g_mime_message_part_get_message ((GMimeMessagePart *) part); if (task->parser_recursion++ < RECURSION_LIMIT) { #ifdef GMIME24 @@ -611,18 +612,20 @@ mime_foreach_callback (GMimeObject *part, gpointer user_data) return; } g_object_unref (message); - } else if (GMIME_IS_MESSAGE_PARTIAL (part)) { + } + else if (GMIME_IS_MESSAGE_PARTIAL (part)) { /* message/partial */ - + /* this is an incomplete message part, probably a - large message that the sender has broken into - smaller parts and is sending us bit by bit. we - could save some info about it so that we could - piece this back together again once we get all the - parts? */ - } else if (GMIME_IS_MULTIPART (part)) { + large message that the sender has broken into + smaller parts and is sending us bit by bit. we + could save some info about it so that we could + piece this back together again once we get all the + parts? */ + } + else if (GMIME_IS_MULTIPART (part)) { /* multipart/mixed, multipart/alternative, multipart/related, multipart/signed, multipart/encrypted, etc... */ - + /* we'll get to finding out if this is a signed/encrypted multipart later... */ if (task->parser_recursion++ < RECURSION_LIMIT) { g_mime_multipart_foreach ((GMimeMultipart *) part, mime_foreach_callback, task); @@ -631,17 +634,18 @@ mime_foreach_callback (GMimeObject *part, gpointer user_data) msg_err ("mime_foreach_callback: endless recursion detected: %d", task->parser_recursion); return; } - } else if (GMIME_IS_PART (part)) { + } + else if (GMIME_IS_PART (part)) { /* a normal leaf part, could be text/plain or image/jpeg etc */ #ifdef GMIME24 - type = (GMimeContentType *)g_mime_object_get_content_type (GMIME_OBJECT (part)); + type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT (part)); #else - type = (GMimeContentType *)g_mime_part_get_content_type (GMIME_PART (part)); + type = (GMimeContentType *) g_mime_part_get_content_type (GMIME_PART (part)); #endif if (type == NULL) { msg_warn ("mime_foreach_callback: type of part is unknown, assume text/plain"); type = g_mime_content_type_new ("text", "plain"); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_mime_content_type_destroy, type); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_mime_content_type_destroy, type); } wrapper = g_mime_part_get_content_object (GMIME_PART (part)); if (wrapper != NULL) { @@ -666,7 +670,8 @@ mime_foreach_callback (GMimeObject *part, gpointer user_data) else { msg_warn ("mime_foreach_callback: cannot get wrapper for mime part, type of part: %s/%s", type->type, type->subtype); } - } else { + } + else { g_assert_not_reached (); } } @@ -674,7 +679,7 @@ mime_foreach_callback (GMimeObject *part, gpointer user_data) static void destroy_message (void *pointer) { - GMimeMessage *msg = pointer; + GMimeMessage *msg = pointer; msg_debug ("destroy_message: freeing pointer %p", msg); g_object_unref (msg); @@ -683,13 +688,13 @@ destroy_message (void *pointer) int process_message (struct worker_task *task) { - GMimeMessage *message; - GMimeParser *parser; - GMimeStream *stream; - GByteArray *tmp; - GList *first, *cur; - struct received_header *recv; - + GMimeMessage *message; + GMimeParser *parser; + GMimeStream *stream; + GByteArray *tmp; + GList *first, *cur; + struct received_header *recv; + tmp = memory_pool_alloc (task->task_pool, sizeof (GByteArray)); tmp->data = task->msg->begin; tmp->len = task->msg->len; @@ -712,17 +717,17 @@ process_message (struct worker_task *task) msg_warn ("process_message: cannot construct mime from stream"); return -1; } - + task->message = message; - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)destroy_message, task->message); - + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) destroy_message, task->message); + task->parser_recursion = 0; #ifdef GMIME24 g_mime_message_foreach (message, mime_foreach_callback, task); #else g_mime_message_foreach_part (message, mime_foreach_callback, task); #endif - + msg_debug ("process_message: found %d parts in message", task->parts_count); if (task->queue_id == NULL) { task->queue_id = (char *)g_mime_message_get_message_id (task->message); @@ -739,7 +744,7 @@ process_message (struct worker_task *task) #endif /* Parse received headers */ - first = message_get_header (task->task_pool, message, "Received"); + first = message_get_header (task->task_pool, message, "Received"); cur = first; while (cur) { recv = memory_pool_alloc0 (task->task_pool, sizeof (struct received_header)); @@ -752,16 +757,16 @@ process_message (struct worker_task *task) } if (task->raw_headers) { - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, task->raw_headers); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, task->raw_headers); } task->rcpts = g_mime_message_get_all_recipients (message); if (task->rcpts) { - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)internet_address_list_destroy, task->rcpts); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) internet_address_list_destroy, task->rcpts); } - + if (task->worker) { - task->worker->srv->stat->messages_scanned ++; + task->worker->srv->stat->messages_scanned++; } /* free the parser (and the stream) */ @@ -771,15 +776,15 @@ process_message (struct worker_task *task) } struct raw_header { - struct raw_header *next; - char *name; - char *value; -}; + struct raw_header *next; + char *name; + char *value; +}; typedef struct _GMimeHeader { - GHashTable *hash; - GHashTable *writers; - struct raw_header *headers; + GHashTable *hash; + GHashTable *writers; + struct raw_header *headers; } local_GMimeHeader; @@ -799,7 +804,7 @@ enum { #ifndef GMIME24 static void -header_iterate (memory_pool_t *pool, struct raw_header *h, GList **ret, const char *field) +header_iterate (memory_pool_t * pool, struct raw_header *h, GList ** ret, const char *field) { while (h) { if (h->value && !g_strncasecmp (field, h->name, strlen (field))) { @@ -815,10 +820,10 @@ header_iterate (memory_pool_t *pool, struct raw_header *h, GList **ret, const ch } #else static void -header_iterate (memory_pool_t *pool, GMimeHeaderList *ls, GList **ret, const char field) +header_iterate (memory_pool_t * pool, GMimeHeaderList * ls, GList ** ret, const char field) { - GMimeHeaderIter *iter; - const char *name; + GMimeHeaderIter *iter; + const char *name; if (g_mime_header_list_get_iter (ls, iter)) { while (g_mime_header_iter_is_valid (iter)) { @@ -841,31 +846,31 @@ header_iterate (memory_pool_t *pool, GMimeHeaderList *ls, GList **ret, const cha struct multipart_cb_data { - GList *ret; - memory_pool_t *pool; - const char *field; - gboolean try_search; - int rec; + GList *ret; + memory_pool_t *pool; + const char *field; + gboolean try_search; + int rec; }; #define MAX_REC 10 static void #ifdef GMIME24 -multipart_iterate (GMimeObject *parent, GMimeObject *part, gpointer user_data) +multipart_iterate (GMimeObject * parent, GMimeObject * part, gpointer user_data) #else -multipart_iterate (GMimeObject *part, gpointer user_data) +multipart_iterate (GMimeObject * part, gpointer user_data) #endif { - struct multipart_cb_data *data = user_data; - struct raw_header *h; - GList *l = NULL; - - if (data->try_search && GMIME_IS_PART (part)) { + struct multipart_cb_data *data = user_data; + struct raw_header *h; + GList *l = NULL; + + if (data->try_search && GMIME_IS_PART (part)) { #ifdef GMIME24 - GMimeHeaderList *ls; + GMimeHeaderList *ls; - ls = GMIME_OBJECT(message)->headers; + ls = GMIME_OBJECT (message)->headers; header_iterate (data->pool, ls, &l, data->field); #else h = part->headers->headers; @@ -881,10 +886,10 @@ multipart_iterate (GMimeObject *part, gpointer user_data) data->ret = g_list_concat (l, data->ret); } } - else if (data->try_search && GMIME_IS_MULTIPART (part)) { + else if (data->try_search && GMIME_IS_MULTIPART (part)) { /* Maybe endless recursion here ? */ if (data->rec++ < MAX_REC) { - g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, data); + g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, data); } else { msg_info ("multipart_iterate: maximum recurse limit is over, stop recursing, %d", data->rec); @@ -893,12 +898,12 @@ multipart_iterate (GMimeObject *part, gpointer user_data) } } -static GList * -local_message_get_header(memory_pool_t *pool, GMimeMessage *message, const char *field) +static GList * +local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const char *field) { - GList *gret = NULL; - GMimeObject *part; - struct multipart_cb_data cb = { + GList *gret = NULL; + GMimeObject *part; + struct multipart_cb_data cb = { .try_search = TRUE, .rec = 0, .ret = NULL, @@ -907,15 +912,15 @@ local_message_get_header(memory_pool_t *pool, GMimeMessage *message, const char cb.field = field; #ifndef GMIME24 - struct raw_header *h; + struct raw_header *h; if (field == NULL) { return NULL; } - h = GMIME_OBJECT(message)->headers->headers; + h = GMIME_OBJECT (message)->headers->headers; header_iterate (pool, h, &gret, field); - + if (gret == NULL) { /* Try to iterate with mime part headers */ part = g_mime_message_get_mime_part (message); @@ -934,9 +939,9 @@ local_message_get_header(memory_pool_t *pool, GMimeMessage *message, const char return gret; #else - GMimeHeaderList *ls; + GMimeHeaderList *ls; - ls = GMIME_OBJECT(message)->headers; + ls = GMIME_OBJECT (message)->headers; header_iterate (pool, ls, &gret, field); if (gret == NULL) { /* Try to iterate with mime part headers */ @@ -945,7 +950,7 @@ local_message_get_header(memory_pool_t *pool, GMimeMessage *message, const char ls = part->headers; header_iterate (pool, ls, &gret, field); if (gret == NULL && GMIME_IS_MULTIPART (part)) { - g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb); + g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb); if (cb.ret != NULL) { gret = cb.ret; } @@ -965,27 +970,27 @@ local_message_get_header(memory_pool_t *pool, GMimeMessage *message, const char * @string: A string of date * * Set the sent-date on a MIME Message. -**/ +**/ void -local_mime_message_set_date_from_string (GMimeMessage *message, const gchar *string) +local_mime_message_set_date_from_string (GMimeMessage * message, const gchar * string) { - time_t date; - int offset = 0; + time_t date; + int offset = 0; date = g_mime_utils_header_decode_date (string, &offset); - g_mime_message_set_date (message, date, offset); + g_mime_message_set_date (message, date, offset); } /* * Replacements for standart gmime functions but converting adresses to IA */ -static const char* -local_message_get_sender (GMimeMessage *message) +static const char * +local_message_get_sender (GMimeMessage * message) { - char *res; - const char *from = g_mime_message_get_sender (message); - InternetAddressList *ia; - + char *res; + const char *from = g_mime_message_get_sender (message); + InternetAddressList *ia; + #ifndef GMIME24 ia = internet_address_parse_string (from); #else @@ -996,16 +1001,16 @@ local_message_get_sender (GMimeMessage *message) } res = internet_address_list_to_string (ia, FALSE); internet_address_list_destroy (ia); - + return res; } -static const char* -local_message_get_reply_to (GMimeMessage *message) +static const char * +local_message_get_reply_to (GMimeMessage * message) { - char *res; - const char *from = g_mime_message_get_reply_to (message); - InternetAddressList *ia; + char *res; + const char *from = g_mime_message_get_reply_to (message); + InternetAddressList *ia; #ifndef GMIME24 ia = internet_address_parse_string (from); @@ -1017,13 +1022,13 @@ local_message_get_reply_to (GMimeMessage *message) } res = internet_address_list_to_string (ia, FALSE); internet_address_list_destroy (ia); - + return res; } #ifdef GMIME24 -#define ADD_RECIPIENT_TEMPLATE(type,def) \ +# define ADD_RECIPIENT_TEMPLATE(type,def) \ static void \ local_message_add_recipients_from_string_##type (GMimeMessage *message, const gchar *string, const gchar *value) \ { \ @@ -1034,30 +1039,25 @@ local_message_add_recipients_from_string_##type (GMimeMessage *message, const gc internet_address_list_append (il, new); \ } \ -ADD_RECIPIENT_TEMPLATE(to, GMIME_RECIPIENT_TYPE_TO) -ADD_RECIPIENT_TEMPLATE(cc, GMIME_RECIPIENT_TYPE_CC) -ADD_RECIPIENT_TEMPLATE(bcc, GMIME_RECIPIENT_TYPE_BCC) - -#define GET_RECIPIENT_TEMPLATE(type,def) \ +ADD_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO) + ADD_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC) + ADD_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC) +# define GET_RECIPIENT_TEMPLATE(type,def) \ static InternetAddressList* \ local_message_get_recipients_##type (GMimeMessage *message, const char *unused) \ { \ return g_mime_message_get_recipients (message, (def)); \ } - -GET_RECIPIENT_TEMPLATE(to, GMIME_RECIPIENT_TYPE_TO) -GET_RECIPIENT_TEMPLATE(cc, GMIME_RECIPIENT_TYPE_CC) -GET_RECIPIENT_TEMPLATE(bcc, GMIME_RECIPIENT_TYPE_BCC) - + GET_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO) + GET_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC) + GET_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC) #endif - - /* different declarations for different types of set and get functions */ -typedef const char *(*GetFunc) (GMimeMessage *message); -typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage *message, const char *type ); -typedef GList *(*GetListFunc) (memory_pool_t *pool, GMimeMessage *message, const char *type ); -typedef void (*SetFunc) (GMimeMessage *message, const char *value); -typedef void (*SetListFunc) (GMimeMessage *message, const char *field, const char *value); + typedef const char *(*GetFunc) (GMimeMessage * message); + typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage * message, const char *type); + typedef GList *(*GetListFunc) (memory_pool_t * pool, GMimeMessage * message, const char *type); + typedef void (*SetFunc) (GMimeMessage * message, const char *value); + typedef void (*SetListFunc) (GMimeMessage * message, const char *field, const char *value); /** different types of functions * @@ -1073,73 +1073,81 @@ typedef void (*SetListFunc) (GMimeMessage *message, const char *field, const ch * - function with additional "field" argument (given arbitrary header field name) * - get returns Glist* **/ -enum { - FUNC_CHARPTR = 0, - FUNC_CHARFREEPTR, - FUNC_IA, - FUNC_LIST -}; + enum { + FUNC_CHARPTR = 0, + FUNC_CHARFREEPTR, + FUNC_IA, + FUNC_LIST + }; /** * fieldfunc struct: structure of MIME fields and corresponding get and set * functions. **/ -static struct { - char * name; - GetFunc func; - GetRcptFunc rcptfunc; - GetListFunc getlistfunc; - SetFunc setfunc; - SetListFunc setlfunc; - gint functype; -} fieldfunc[] = { - { "From", local_message_get_sender, NULL, NULL, g_mime_message_set_sender, NULL, FUNC_CHARFREEPTR }, - { "Reply-To", local_message_get_reply_to, NULL, NULL, g_mime_message_set_reply_to, NULL, FUNC_CHARFREEPTR }, + static struct { + char *name; + GetFunc func; + GetRcptFunc rcptfunc; + GetListFunc getlistfunc; + SetFunc setfunc; + SetListFunc setlfunc; + gint functype; + } fieldfunc[] = +{ + { + "From", local_message_get_sender, NULL, NULL, g_mime_message_set_sender, NULL, FUNC_CHARFREEPTR}, { + "Reply-To", local_message_get_reply_to, NULL, NULL, g_mime_message_set_reply_to, NULL, FUNC_CHARFREEPTR}, #ifndef GMIME24 - { "To", NULL, (GetRcptFunc)g_mime_message_get_recipients, NULL, NULL, (SetListFunc)g_mime_message_add_recipients_from_string, FUNC_IA }, - { "Cc", NULL, (GetRcptFunc)g_mime_message_get_recipients, NULL, NULL, (SetListFunc)g_mime_message_add_recipients_from_string, FUNC_IA }, - { "Bcc",NULL, (GetRcptFunc)g_mime_message_get_recipients, NULL, NULL, (SetListFunc)g_mime_message_add_recipients_from_string, FUNC_IA }, - { "Date", (GetFunc)g_mime_message_get_date_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR }, + { + "To", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, { + "Cc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, { + "Bcc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, { + "Date", (GetFunc) g_mime_message_get_date_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR}, #else - { "To", NULL, local_message_get_recipients_to, NULL, NULL, local_message_add_recipients_from_string_to, FUNC_IA }, - { "Cc", NULL, local_message_get_recipients_cc, NULL, NULL, local_message_add_recipients_from_string_cc, FUNC_IA }, - { "Bcc", NULL, local_message_get_recipients_bcc, NULL, NULL, local_message_add_recipients_from_string_bcc, FUNC_IA }, - { "Date", g_mime_message_get_date_as_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR }, + { + "To", NULL, local_message_get_recipients_to, NULL, NULL, local_message_add_recipients_from_string_to, FUNC_IA}, { + "Cc", NULL, local_message_get_recipients_cc, NULL, NULL, local_message_add_recipients_from_string_cc, FUNC_IA}, { + "Bcc", NULL, local_message_get_recipients_bcc, NULL, NULL, local_message_add_recipients_from_string_bcc, FUNC_IA}, { + "Date", g_mime_message_get_date_as_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR}, #endif - { "Subject", g_mime_message_get_subject, NULL, NULL, g_mime_message_set_subject, NULL, FUNC_CHARPTR }, - { "Message-Id", g_mime_message_get_message_id, NULL, NULL, g_mime_message_set_message_id, NULL, FUNC_CHARPTR }, + { + "Subject", g_mime_message_get_subject, NULL, NULL, g_mime_message_set_subject, NULL, FUNC_CHARPTR}, { + "Message-Id", g_mime_message_get_message_id, NULL, NULL, g_mime_message_set_message_id, NULL, FUNC_CHARPTR}, #ifndef GMIME24 - { NULL, NULL, NULL, local_message_get_header, NULL, g_mime_message_add_header, FUNC_LIST } + { + NULL, NULL, NULL, local_message_get_header, NULL, g_mime_message_add_header, FUNC_LIST} #else - { NULL, NULL, NULL, local_message_get_header, NULL, g_mime_object_append_header, FUNC_LIST } + { + NULL, NULL, NULL, local_message_get_header, NULL, g_mime_object_append_header, FUNC_LIST} #endif }; + /** * message_set_header: set header of any type excluding special (Content- and MIME-Version:) **/ void -message_set_header (GMimeMessage *message, const char *field, const char *value) +message_set_header (GMimeMessage * message, const char *field, const char *value) { - gint i; + gint i; if (!g_strcasecmp (field, "MIME-Version:") || !g_strncasecmp (field, "Content-", 8)) { return; } - for (i=0; i<=HEADER_UNKNOWN; ++i) { - if (!fieldfunc[i].name || !g_strncasecmp(field, fieldfunc[i].name, strlen(fieldfunc[i].name))) { + for (i = 0; i <= HEADER_UNKNOWN; ++i) { + if (!fieldfunc[i].name || !g_strncasecmp (field, fieldfunc[i].name, strlen (fieldfunc[i].name))) { switch (fieldfunc[i].functype) { - case FUNC_CHARPTR: - (*(fieldfunc[i].setfunc))(message, value); - break; - case FUNC_IA: - (*(fieldfunc[i].setlfunc))(message, fieldfunc[i].name, value); - break; - case FUNC_LIST: - (*(fieldfunc[i].setlfunc))(message, field, value); - break; + case FUNC_CHARPTR: + (*(fieldfunc[i].setfunc)) (message, value); + break; + case FUNC_IA: + (*(fieldfunc[i].setlfunc)) (message, fieldfunc[i].name, value); + break; + case FUNC_LIST: + (*(fieldfunc[i].setlfunc)) (message, field, value); + break; } break; - } + } } } @@ -1150,51 +1158,51 @@ message_set_header (GMimeMessage *message, const char *field, const char *value) * * You should free the GList list by yourself. **/ -GList * -message_get_header (memory_pool_t *pool, GMimeMessage *message, const char *field) +GList * +message_get_header (memory_pool_t * pool, GMimeMessage * message, const char *field) { - gint i; - char * ret = NULL, *ia_string; - GList * gret = NULL; - InternetAddressList *ia_list = NULL, *ia; + gint i; + char *ret = NULL, *ia_string; + GList *gret = NULL; + InternetAddressList *ia_list = NULL, *ia; for (i = 0; i <= HEADER_UNKNOWN; ++i) { - if (!fieldfunc[i].name || !g_strncasecmp(field, fieldfunc[i].name, strlen(fieldfunc[i].name))) { + if (!fieldfunc[i].name || !g_strncasecmp (field, fieldfunc[i].name, strlen (fieldfunc[i].name))) { switch (fieldfunc[i].functype) { - case FUNC_CHARFREEPTR: - ret = (char *)(*(fieldfunc[i].func))(message); - break; - case FUNC_CHARPTR: - ret = (char *)(*(fieldfunc[i].func))(message); - break; - case FUNC_IA: - ia_list = (*(fieldfunc[i].rcptfunc))(message, field); - gret = g_list_alloc(); - ia = ia_list; + case FUNC_CHARFREEPTR: + ret = (char *)(*(fieldfunc[i].func)) (message); + break; + case FUNC_CHARPTR: + ret = (char *)(*(fieldfunc[i].func)) (message); + break; + case FUNC_IA: + ia_list = (*(fieldfunc[i].rcptfunc)) (message, field); + gret = g_list_alloc (); + ia = ia_list; #ifndef GMIME24 - while (ia && ia->address) { + while (ia && ia->address) { - ia_string = internet_address_to_string ((InternetAddress *)ia->address, FALSE); - memory_pool_add_destructor (pool, (pool_destruct_func)g_free, ia_string); - gret = g_list_prepend (gret, ia_string); - ia = ia->next; - } + ia_string = internet_address_to_string ((InternetAddress *) ia->address, FALSE); + memory_pool_add_destructor (pool, (pool_destruct_func) g_free, ia_string); + gret = g_list_prepend (gret, ia_string); + ia = ia->next; + } #else - i = internet_address_list_length (ia); - while (i > 0) { - ia_string = internet_address_to_string (internet_address_list_get_address (ia, i), FALSE); - memory_pool_add_destructor (pool, (pool_destruct_func)g_free, ia_string); - gret = g_list_prepend (gret, ia_string); - -- i; - } + i = internet_address_list_length (ia); + while (i > 0) { + ia_string = internet_address_to_string (internet_address_list_get_address (ia, i), FALSE); + memory_pool_add_destructor (pool, (pool_destruct_func) g_free, ia_string); + gret = g_list_prepend (gret, ia_string); + --i; + } #endif - break; - case FUNC_LIST: - gret = (*(fieldfunc[i].getlistfunc))(pool, message, field); - break; + break; + case FUNC_LIST: + gret = (*(fieldfunc[i].getlistfunc)) (pool, message, field); + break; } break; - } + } } if (gret == NULL && ret != NULL) { if (pool != NULL) { diff --git a/src/perl.c b/src/perl.c index eab3a424d..2849289b6 100644 --- a/src/perl.c +++ b/src/perl.c @@ -28,44 +28,44 @@ #include "perl.h" #include "cfg_file.h" -#include <EXTERN.h> /* from the Perl distribution */ -#include <perl.h> /* from the Perl distribution */ +#include <EXTERN.h> /* from the Perl distribution */ +#include <perl.h> /* from the Perl distribution */ #ifndef PERL_IMPLICIT_CONTEXT -#undef dTHXa -#define dTHXa(a) +# undef dTHXa +# define dTHXa(a) #endif /* Perl module init function */ #define MODULE_INIT_FUNC "module_init" -PerlInterpreter *perl_interpreter; +PerlInterpreter *perl_interpreter; -static HV *rspamd_task_stash; -static HV *rspamd_cfg_stash; +static HV *rspamd_task_stash; +static HV *rspamd_cfg_stash; -extern void boot_DynaLoader (pTHX_ CV* cv); -extern void boot_Socket (pTHX_ CV* cv); +extern void boot_DynaLoader (pTHX_ CV * cv); +extern void boot_Socket (pTHX_ CV * cv); void -xs_init(pTHX) +xs_init (pTHX) { dXSUB_SYS; /* DynaLoader is a special case */ newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); - rspamd_task_stash = gv_stashpv("rspamd_task", TRUE); - rspamd_cfg_stash = gv_stashpv("rspamd_config", TRUE); + rspamd_task_stash = gv_stashpv ("rspamd_task", TRUE); + rspamd_cfg_stash = gv_stashpv ("rspamd_config", TRUE); } void init_perl_filters (struct config_file *cfg) { - struct perl_module *module; - char *init_func; - size_t funclen; - SV* sv; - + struct perl_module *module; + char *init_func; + size_t funclen; + SV *sv; + dTHXa (perl_interpreter); PERL_SET_CONTEXT (perl_interpreter); @@ -77,7 +77,7 @@ init_perl_filters (struct config_file *cfg) SAVETMPS; PUSHMARK (SP); - sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV(cfg))), rspamd_cfg_stash)); + sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV (cfg))), rspamd_cfg_stash)); XPUSHs (sv); PUTBACK; /* Call module init function */ @@ -96,8 +96,8 @@ init_perl_filters (struct config_file *cfg) int perl_call_header_filter (const char *function, struct worker_task *task) { - int result; - SV* sv; + int result; + SV *sv; dTHXa (perl_interpreter); PERL_SET_CONTEXT (perl_interpreter); @@ -107,10 +107,10 @@ perl_call_header_filter (const char *function, struct worker_task *task) SAVETMPS; PUSHMARK (SP); - sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV(task))), rspamd_task_stash)); + sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV (task))), rspamd_task_stash)); XPUSHs (sv); PUTBACK; - + call_pv (function, G_SCALAR); SPAGAIN; @@ -128,28 +128,28 @@ perl_call_header_filter (const char *function, struct worker_task *task) int perl_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number) { - int result, i; - AV *av; - SV *sv; + int result, i; + AV *av; + SV *sv; dTHXa (perl_interpreter); PERL_SET_CONTEXT (perl_interpreter); dSP; - + ENTER; SAVETMPS; - av = newAV(); + av = newAV (); av_extend (av, number); - for (i = 0; i < number; i ++) { + for (i = 0; i < number; i++) { av_push (av, sv_2mortal (newSViv (marks[i]))); } PUSHMARK (SP); - sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV(task))), rspamd_task_stash)); + sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV (task))), rspamd_task_stash)); XPUSHs (sv); - XPUSHs (sv_2mortal ((SV *)AvARRAY (av))); + XPUSHs (sv_2mortal ((SV *) AvARRAY (av))); PUTBACK; - + call_pv (function, G_SCALAR); SPAGAIN; @@ -166,15 +166,15 @@ perl_call_chain_filter (const char *function, struct worker_task *task, int *mar return result; } -void -perl_call_memcached_callback (memcached_ctx_t *ctx, memc_error_t error, void *data) +void +perl_call_memcached_callback (memcached_ctx_t * ctx, memc_error_t error, void *data) { struct { - SV *callback; - struct worker_task *task; - } *callback_data = data; - SV *sv; - + SV *callback; + struct worker_task *task; + } *callback_data = data; + SV *sv; + dTHXa (perl_interpreter); PERL_SET_CONTEXT (perl_interpreter); @@ -183,14 +183,14 @@ perl_call_memcached_callback (memcached_ctx_t *ctx, memc_error_t error, void *da ENTER; SAVETMPS; PUSHMARK (SP); - sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV(callback_data->task))), rspamd_task_stash)); + sv = sv_2mortal (sv_bless (newRV_noinc (newSViv (PTR2IV (callback_data->task))), rspamd_task_stash)); XPUSHs (sv); XPUSHs (sv_2mortal (newSViv (error))); XPUSHs (sv_2mortal (newSVpv (ctx->param->buf, ctx->param->bufsize))); PUTBACK; call_sv (callback_data->callback, G_SCALAR); - + /* Set save point */ callback_data->task->save.saved = 0; process_filters (callback_data->task); @@ -205,18 +205,18 @@ perl_call_memcached_callback (memcached_ctx_t *ctx, memc_error_t error, void *da * Perl custom consolidation function */ struct consolidation_callback_data { - struct worker_task *task; - double score; - const char *func; + struct worker_task *task; + double score; + const char *func; }; static void perl_consolidation_callback (gpointer key, gpointer value, gpointer arg) { - double res; - struct symbol *s = (struct symbol *)value; + double res; + struct symbol *s = (struct symbol *)value; struct consolidation_callback_data *data = (struct consolidation_callback_data *)arg; - + dTHXa (perl_interpreter); PERL_SET_CONTEXT (perl_interpreter); @@ -225,11 +225,11 @@ perl_consolidation_callback (gpointer key, gpointer value, gpointer arg) SAVETMPS; PUSHMARK (SP); - + XPUSHs (sv_2mortal (newSVpv ((const char *)key, 0))); XPUSHs (sv_2mortal (newSVnv (s->score))); PUTBACK; - + call_pv (data->func, G_SCALAR); SPAGAIN; @@ -242,8 +242,8 @@ perl_consolidation_callback (gpointer key, gpointer value, gpointer arg) double perl_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name) { - struct metric_result *metric_res; - double res = 0.; + struct metric_result *metric_res; + double res = 0.; struct consolidation_callback_data data = { task, 0, function_name }; if (function_name == NULL) { diff --git a/src/plugins/chartable.c b/src/plugins/chartable.c index 721dab452..d311da740 100644 --- a/src/plugins/chartable.c +++ b/src/plugins/chartable.c @@ -38,18 +38,18 @@ #define DEFAULT_THRESHOLD 0.1 struct chartable_ctx { - int (*filter)(struct worker_task *task); - char *metric; - char *symbol; - double threshold; + int (*filter) (struct worker_task * task); + char *metric; + char *symbol; + double threshold; - memory_pool_t *chartable_pool; + memory_pool_t *chartable_pool; }; -static struct chartable_ctx *chartable_module_ctx = NULL; +static struct chartable_ctx *chartable_module_ctx = NULL; -static int chartable_mime_filter (struct worker_task *task); -static void chartable_symbol_callback (struct worker_task *task, void *unused); +static int chartable_mime_filter (struct worker_task *task); +static void chartable_symbol_callback (struct worker_task *task, void *unused); int chartable_module_init (struct config_file *cfg, struct module_ctx **ctx) @@ -60,7 +60,7 @@ chartable_module_init (struct config_file *cfg, struct module_ctx **ctx) chartable_module_ctx->chartable_pool = memory_pool_new (memory_pool_get_size ()); *ctx = (struct module_ctx *)chartable_module_ctx; - + return 0; } @@ -68,10 +68,10 @@ chartable_module_init (struct config_file *cfg, struct module_ctx **ctx) int chartable_module_config (struct config_file *cfg) { - char *value; - int res = TRUE; - struct metric *metric; - double *w; + char *value; + int res = TRUE; + struct metric *metric; + double *w; if ((value = get_module_opt (cfg, "chartable", "metric")) != NULL) { chartable_module_ctx->metric = memory_pool_strdup (chartable_module_ctx->chartable_pool, value); @@ -126,38 +126,36 @@ chartable_module_reconfig (struct config_file *cfg) return chartable_module_config (cfg); } -static gboolean +static gboolean check_part (struct mime_text_part *part, gboolean raw_mode) { - unsigned char *p, *p1; - gunichar c, t; - GUnicodeScript scc, sct; - uint32_t mark = 0, total = 0; - uint32_t remain = part->content->len; - + unsigned char *p, *p1; + gunichar c, t; + GUnicodeScript scc, sct; + uint32_t mark = 0, total = 0; + uint32_t remain = part->content->len; + p = part->content->data; if (part->is_raw || raw_mode) { while (remain > 1) { - if ((g_ascii_isalpha (*p) && (*(p + 1) & 0x80)) || - ((*p & 0x80) && g_ascii_isalpha (*(p + 1)))) { - mark ++; - total ++; + if ((g_ascii_isalpha (*p) && (*(p + 1) & 0x80)) || ((*p & 0x80) && g_ascii_isalpha (*(p + 1)))) { + mark++; + total++; } /* Current and next symbols are of one class */ - else if (((*p & 0x80) && (*(p + 1) & 0x80)) || - (g_ascii_isalpha (*p) && g_ascii_isalpha (*(p + 1)))) { - total ++; + else if (((*p & 0x80) && (*(p + 1) & 0x80)) || (g_ascii_isalpha (*p) && g_ascii_isalpha (*(p + 1)))) { + total++; } - p ++; - remain --; + p++; + remain--; } } else { while (remain > 0) { c = g_utf8_get_char_validated (p, remain); - if (c == (gunichar)-2 || c == (gunichar)-1) { - /* Invalid characters detected, stop processing*/ + if (c == (gunichar) - 2 || c == (gunichar) - 1) { + /* Invalid characters detected, stop processing */ return FALSE; } @@ -165,20 +163,20 @@ check_part (struct mime_text_part *part, gboolean raw_mode) p1 = g_utf8_next_char (p); remain -= p1 - p; p = p1; - + if (remain > 0) { t = g_utf8_get_char_validated (p, remain); - if (c == (gunichar)-2 || c == (gunichar)-1) { - /* Invalid characters detected, stop processing*/ + if (c == (gunichar) - 2 || c == (gunichar) - 1) { + /* Invalid characters detected, stop processing */ return FALSE; } sct = g_unichar_get_script (t); if (g_unichar_isalnum (c) && g_unichar_isalnum (t)) { /* We have two unicode alphanumeric characters, so we can check its script */ if (sct != scc) { - mark ++; + mark++; } - total ++; + total++; } p1 = g_utf8_next_char (p); remain -= p1 - p; @@ -190,18 +188,18 @@ check_part (struct mime_text_part *part, gboolean raw_mode) return ((double)mark / (double)total) > chartable_module_ctx->threshold; } -static void +static void chartable_symbol_callback (struct worker_task *task, void *unused) -{ - GList *cur; - struct mime_text_part *part; +{ + GList *cur; + struct mime_text_part *part; if (check_view (task->cfg->views, chartable_module_ctx->symbol, task)) { cur = g_list_first (task->text_parts); while (cur) { part = cur->data; if (!part->is_empty && check_part (part, task->cfg->raw_mode)) { - insert_result (task, chartable_module_ctx->metric, chartable_module_ctx->symbol, 1, NULL); + insert_result (task, chartable_module_ctx->metric, chartable_module_ctx->symbol, 1, NULL); } cur = g_list_next (cur); } @@ -209,7 +207,7 @@ chartable_symbol_callback (struct worker_task *task, void *unused) } -static int +static int chartable_mime_filter (struct worker_task *task) { /* XXX: remove it */ diff --git a/src/plugins/emails.c b/src/plugins/emails.c index 39415f0c8..a58e8d7c6 100644 --- a/src/plugins/emails.c +++ b/src/plugins/emails.c @@ -38,30 +38,31 @@ #define DEFAULT_SYMBOL "R_BAD_EMAIL" -static const char *email_re_text = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\\b"; +static const char *email_re_text = + "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\\b"; struct email_ctx { - int (*filter)(struct worker_task *task); - char *metric; - char *symbol; - GRegex *email_re; + int (*filter) (struct worker_task * task); + char *metric; + char *symbol; + GRegex *email_re; - GHashTable *blacklist; - char *blacklist_file; + GHashTable *blacklist; + char *blacklist_file; - memory_pool_t *email_pool; + memory_pool_t *email_pool; }; -static struct email_ctx *email_module_ctx = NULL; +static struct email_ctx *email_module_ctx = NULL; -static int emails_mime_filter (struct worker_task *task); -static void emails_symbol_callback (struct worker_task *task, void *unused); -static int emails_command_handler (struct worker_task *task); +static int emails_mime_filter (struct worker_task *task); +static void emails_symbol_callback (struct worker_task *task, void *unused); +static int emails_command_handler (struct worker_task *task); int emails_module_init (struct config_file *cfg, struct module_ctx **ctx) { - GError *err = NULL; + GError *err = NULL; email_module_ctx = g_malloc (sizeof (struct email_ctx)); @@ -69,9 +70,9 @@ emails_module_init (struct config_file *cfg, struct module_ctx **ctx) email_module_ctx->email_pool = memory_pool_new (memory_pool_get_size ()); email_module_ctx->email_re = g_regex_new (email_re_text, G_REGEX_RAW | G_REGEX_OPTIMIZE | G_REGEX_CASELESS, 0, &err); email_module_ctx->blacklist = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); - + *ctx = (struct module_ctx *)email_module_ctx; - + register_protocol_command ("emails", emails_command_handler); return 0; @@ -81,10 +82,10 @@ emails_module_init (struct config_file *cfg, struct module_ctx **ctx) int emails_module_config (struct config_file *cfg) { - char *value; - int res = TRUE; - struct metric *metric; - double *w; + char *value; + int res = TRUE; + struct metric *metric; + double *w; if ((value = get_module_opt (cfg, "emails", "metric")) != NULL) { email_module_ctx->metric = memory_pool_strdup (email_module_ctx->email_pool, value); @@ -104,7 +105,7 @@ emails_module_config (struct config_file *cfg) if (add_map (value, read_host_list, fin_host_list, (void **)&email_module_ctx->blacklist)) { email_module_ctx->blacklist_file = memory_pool_strdup (email_module_ctx->email_pool, value + sizeof ("file://") - 1); } - } + } metric = g_hash_table_lookup (cfg->metrics, email_module_ctx->metric); if (metric == NULL) { @@ -133,15 +134,15 @@ emails_module_reconfig (struct config_file *cfg) return emails_module_config (cfg); } -static GList * +static GList * extract_emails (struct worker_task *task) { - GList *res = NULL, *cur; - GMatchInfo *info; - GError *err = NULL; - struct mime_text_part *part; - char *email_str; - int rc; + GList *res = NULL, *cur; + GMatchInfo *info; + GError *err = NULL; + struct mime_text_part *part; + char *email_str; + int rc; cur = g_list_first (task->text_parts); while (cur) { @@ -158,7 +159,7 @@ extract_emails (struct worker_task *task) email_str = g_match_info_fetch (info, 0); if (email_str != NULL) { res = g_list_prepend (res, email_str); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, email_str); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, email_str); } /* Get next match */ g_match_info_next (info, &err); @@ -175,29 +176,29 @@ extract_emails (struct worker_task *task) cur = g_list_next (cur); } if (res != NULL) { - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, res); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_list_free, res); } - + return res; } -static int +static int emails_command_handler (struct worker_task *task) { - GList *emails, *cur; - char outbuf[BUFSIZ]; - int r, num = 0; + GList *emails, *cur; + char outbuf[BUFSIZ]; + int r, num = 0; emails = extract_emails (task); r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK"); - + r += snprintf (outbuf + r, sizeof (outbuf) - r - 2, "Emails: "); - + cur = g_list_first (emails); while (cur) { - num ++; + num++; if (g_list_next (cur) != NULL) { r += snprintf (outbuf + r, sizeof (outbuf) - r - 2, "%s, ", (char *)cur->data); } @@ -206,8 +207,9 @@ emails_command_handler (struct worker_task *task) } cur = g_list_next (cur); } - - outbuf[r++] = '\r'; outbuf[r++] = '\n'; + + outbuf[r++] = '\r'; + outbuf[r++] = '\n'; rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); msg_info ("process_message: msg ok, id: <%s>, %d emails extracted", task->message_id, num); @@ -215,10 +217,10 @@ emails_command_handler (struct worker_task *task) return 0; } -static void +static void emails_symbol_callback (struct worker_task *task, void *unused) -{ - GList *emails, *cur; +{ + GList *emails, *cur; if (check_view (task->cfg->views, email_module_ctx->symbol, task)) { @@ -228,9 +230,8 @@ emails_symbol_callback (struct worker_task *task, void *unused) while (cur) { if (g_hash_table_lookup (email_module_ctx->blacklist, cur->data) != NULL) { - insert_result (task, email_module_ctx->metric, email_module_ctx->symbol, 1, - g_list_prepend (NULL, memory_pool_strdup (task->task_pool, (char *)cur->data))); - + insert_result (task, email_module_ctx->metric, email_module_ctx->symbol, 1, g_list_prepend (NULL, memory_pool_strdup (task->task_pool, (char *)cur->data))); + } cur = g_list_next (cur); } @@ -239,7 +240,7 @@ emails_symbol_callback (struct worker_task *task, void *unused) } -static int +static int emails_mime_filter (struct worker_task *task) { /* XXX: remove this */ diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index 258a41505..ef139b3a1 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -46,70 +46,70 @@ #define DEFAULT_PORT 11335 struct storage_server { - struct upstream up; - char *name; - struct in_addr addr; - uint16_t port; + struct upstream up; + char *name; + struct in_addr addr; + uint16_t port; }; struct fuzzy_ctx { - int (*filter)(struct worker_task *task); - char *metric; - char *symbol; - struct storage_server *servers; - int servers_num; - memory_pool_t *fuzzy_pool; + int (*filter) (struct worker_task * task); + char *metric; + char *symbol; + struct storage_server *servers; + int servers_num; + memory_pool_t *fuzzy_pool; }; struct fuzzy_client_session { - int state; - fuzzy_hash_t *h; - struct event ev; - struct timeval tv; - struct worker_task *task; - struct storage_server *server; + int state; + fuzzy_hash_t *h; + struct event ev; + struct timeval tv; + struct worker_task *task; + struct storage_server *server; }; struct fuzzy_learn_session { - struct event ev; - fuzzy_hash_t *h; - int cmd; - int *saved; - struct timeval tv; - struct controller_session *session; - struct storage_server *server; - struct worker_task *task; + struct event ev; + fuzzy_hash_t *h; + int cmd; + int *saved; + struct timeval tv; + struct controller_session *session; + struct storage_server *server; + struct worker_task *task; }; -static struct fuzzy_ctx *fuzzy_module_ctx = NULL; +static struct fuzzy_ctx *fuzzy_module_ctx = NULL; -static int fuzzy_mime_filter (struct worker_task *task); -static void fuzzy_symbol_callback (struct worker_task *task, void *unused); -static void fuzzy_add_handler (char **args, struct controller_session *session); -static void fuzzy_delete_handler (char **args, struct controller_session *session); +static int fuzzy_mime_filter (struct worker_task *task); +static void fuzzy_symbol_callback (struct worker_task *task, void *unused); +static void fuzzy_add_handler (char **args, struct controller_session *session); +static void fuzzy_delete_handler (char **args, struct controller_session *session); static void parse_servers_string (char *str) { - char **strvec, *p, portbuf[6], *name; - int num, i, j, port; - struct hostent *hent; - struct in_addr addr; + char **strvec, *p, portbuf[6], *name; + int num, i, j, port; + struct hostent *hent; + struct in_addr addr; strvec = g_strsplit (str, ",", 0); num = g_strv_length (strvec); fuzzy_module_ctx->servers = memory_pool_alloc0 (fuzzy_module_ctx->fuzzy_pool, sizeof (struct storage_server) * num); - for (i = 0; i < num; i ++) { + for (i = 0; i < num; i++) { g_strstrip (strvec[i]); if ((p = strchr (strvec[i], ':')) != NULL) { j = 0; - p ++; + p++; while (g_ascii_isdigit (*(p + j)) && j < sizeof (portbuf) - 1) { portbuf[j] = *(p + j); - j ++; + j++; } portbuf[j] = '\0'; port = atoi (portbuf); @@ -128,17 +128,17 @@ parse_servers_string (char *str) continue; } else { - fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].port = port; - fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].name = name; - memcpy (&fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].addr, hent->h_addr, sizeof(struct in_addr)); - fuzzy_module_ctx->servers_num ++; + fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].port = port; + fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].name = name; + memcpy (&fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].addr, hent->h_addr, sizeof (struct in_addr)); + fuzzy_module_ctx->servers_num++; } } else { - fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].port = port; - fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].name = name; - memcpy (&fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].addr, hent->h_addr, sizeof(struct in_addr)); - fuzzy_module_ctx->servers_num ++; + fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].port = port; + fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].name = name; + memcpy (&fuzzy_module_ctx->servers[fuzzy_module_ctx->servers_num].addr, hent->h_addr, sizeof (struct in_addr)); + fuzzy_module_ctx->servers_num++; } } @@ -156,7 +156,7 @@ fuzzy_check_module_init (struct config_file *cfg, struct module_ctx **ctx) fuzzy_module_ctx->fuzzy_pool = memory_pool_new (memory_pool_get_size ()); fuzzy_module_ctx->servers = NULL; fuzzy_module_ctx->servers_num = 0; - + *ctx = (struct module_ctx *)fuzzy_module_ctx; return 0; @@ -165,10 +165,10 @@ fuzzy_check_module_init (struct config_file *cfg, struct module_ctx **ctx) int fuzzy_check_module_config (struct config_file *cfg) { - char *value; - int res = TRUE; - struct metric *metric; - double *w; + char *value; + int res = TRUE; + struct metric *metric; + double *w; if ((value = get_module_opt (cfg, "fuzzy_check", "metric")) != NULL) { fuzzy_module_ctx->metric = memory_pool_strdup (fuzzy_module_ctx->fuzzy_pool, value); @@ -186,7 +186,7 @@ fuzzy_check_module_config (struct config_file *cfg) } if ((value = get_module_opt (cfg, "fuzzy_check", "servers")) != NULL) { parse_servers_string (value); - } + } metric = g_hash_table_lookup (cfg->metrics, fuzzy_module_ctx->metric); if (metric == NULL) { @@ -205,7 +205,7 @@ fuzzy_check_module_config (struct config_file *cfg) register_custom_controller_command ("fuzzy_add", fuzzy_add_handler, TRUE, TRUE); register_custom_controller_command ("fuzzy_del", fuzzy_delete_handler, TRUE, TRUE); - + return res; } @@ -221,10 +221,10 @@ fuzzy_check_module_reconfig (struct config_file *cfg) static void fuzzy_io_fin (void *ud) { - struct fuzzy_client_session *session = ud; + struct fuzzy_client_session *session = ud; event_del (&session->ev); - session->task->save.saved --; + session->task->save.saved--; if (session->task->save.saved == 0) { /* Call other filters */ session->task->save.saved = 1; @@ -235,9 +235,9 @@ fuzzy_io_fin (void *ud) static void fuzzy_io_callback (int fd, short what, void *arg) { - struct fuzzy_client_session *session = arg; - struct fuzzy_cmd cmd; - char buf[sizeof ("ERR")]; + struct fuzzy_client_session *session = arg; + struct fuzzy_cmd cmd; + char buf[sizeof ("ERR")]; if (what == EV_WRITE) { /* Send command to storage */ @@ -261,25 +261,24 @@ fuzzy_io_callback (int fd, short what, void *arg) } goto ok; } - + return; - err: - msg_err ("fuzzy_io_callback: got error on IO with server %s:%d, %d, %s", session->server->name, session->server->port, - errno, strerror (errno)); - ok: - close (fd); - remove_normal_event (session->task->s, fuzzy_io_fin, session); + err: + msg_err ("fuzzy_io_callback: got error on IO with server %s:%d, %d, %s", session->server->name, session->server->port, errno, strerror (errno)); + ok: + close (fd); + remove_normal_event (session->task->s, fuzzy_io_fin, session); } static void fuzzy_learn_fin (void *arg) { - struct fuzzy_learn_session *session = arg; + struct fuzzy_learn_session *session = arg; event_del (&session->ev); - (*session->saved) --; + (*session->saved)--; if (*session->saved == 0) { session->session->state = STATE_REPLY; } @@ -288,9 +287,9 @@ fuzzy_learn_fin (void *arg) static void fuzzy_learn_callback (int fd, short what, void *arg) { - struct fuzzy_learn_session *session = arg; - struct fuzzy_cmd cmd; - char buf[sizeof ("ERR" CRLF)]; + struct fuzzy_learn_session *session = arg; + struct fuzzy_cmd cmd; + char buf[sizeof ("ERR" CRLF)]; if (what == EV_WRITE) { /* Send command to storage */ @@ -311,25 +310,24 @@ fuzzy_learn_callback (int fd, short what, void *arg) } goto ok; } - + return; - err: - msg_err ("fuzzy_learn_callback: got error in IO with server %s:%d, %d, %s", session->server->name, - session->server->port, errno, strerror (errno)); - ok: - close (fd); - remove_normal_event (session->session->s, fuzzy_learn_fin, session); + err: + msg_err ("fuzzy_learn_callback: got error in IO with server %s:%d, %d, %s", session->server->name, session->server->port, errno, strerror (errno)); + ok: + close (fd); + remove_normal_event (session->session->s, fuzzy_learn_fin, session); } -static void +static void fuzzy_symbol_callback (struct worker_task *task, void *unused) { - struct mime_text_part *part; - struct fuzzy_client_session *session; - struct storage_server *selected; - GList *cur; - int sock; + struct mime_text_part *part; + struct fuzzy_client_session *session; + struct storage_server *selected; + GList *cur; + int sock; cur = task->text_parts; @@ -340,14 +338,12 @@ fuzzy_symbol_callback (struct worker_task *task, void *unused) continue; } selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num, - sizeof (struct storage_server), task->ts.tv_sec, - DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, - DEFAULT_UPSTREAM_MAXERRORS, - part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); + sizeof (struct storage_server), task->ts.tv_sec, + DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); if (selected) { if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) { msg_warn ("fuzzy_symbol_callback: cannot connect to %s, %d, %s", selected->name, errno, strerror (errno)); - } + } else { session = memory_pool_alloc (task->task_pool, sizeof (struct fuzzy_client_session)); event_set (&session->ev, sock, EV_WRITE, fuzzy_io_callback, session); @@ -359,7 +355,7 @@ fuzzy_symbol_callback (struct worker_task *task, void *unused) session->server = selected; event_add (&session->ev, &session->tv); register_async_event (task->s, fuzzy_io_fin, session, FALSE); - task->save.saved ++; + task->save.saved++; } } cur = g_list_next (cur); @@ -367,23 +363,23 @@ fuzzy_symbol_callback (struct worker_task *task, void *unused) } static void -fuzzy_process_handler (struct controller_session *session, f_str_t *in) +fuzzy_process_handler (struct controller_session *session, f_str_t * in) { - struct worker_task *task; - struct fuzzy_learn_session *s; - struct mime_text_part *part; - struct storage_server *selected; - GList *cur; - int sock, r, cmd = 0, *saved; - char out_buf[BUFSIZ]; - + struct worker_task *task; + struct fuzzy_learn_session *s; + struct mime_text_part *part; + struct storage_server *selected; + GList *cur; + int sock, r, cmd = 0, *saved; + char out_buf[BUFSIZ]; + if (session->other_data) { cmd = GPOINTER_TO_SIZE (session->other_data); } task = construct_task (session->worker); session->other_data = task; session->state = STATE_WAIT; - + task->msg = memory_pool_alloc (task->task_pool, sizeof (f_str_t)); task->msg->begin = in->begin; task->msg->len = in->len; @@ -409,10 +405,8 @@ fuzzy_process_handler (struct controller_session *session, f_str_t *in) continue; } selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num, - sizeof (struct storage_server), task->ts.tv_sec, - DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, - DEFAULT_UPSTREAM_MAXERRORS, - part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); + sizeof (struct storage_server), task->ts.tv_sec, + DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); if (selected) { if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) { msg_warn ("fuzzy_symbol_callback: cannot connect to %s, %d, %s", selected->name, errno, strerror (errno)); @@ -421,7 +415,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t *in) rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE); free_task (task, FALSE); return; - } + } else { s = memory_pool_alloc (session->session_pool, sizeof (struct fuzzy_learn_session)); event_set (&s->ev, sock, EV_WRITE, fuzzy_learn_callback, s); @@ -435,7 +429,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t *in) s->cmd = cmd; s->saved = saved; event_add (&s->ev, &s->tv); - (*saved) ++; + (*saved)++; register_async_event (session->s, fuzzy_learn_fin, s, FALSE); } } @@ -461,9 +455,9 @@ fuzzy_process_handler (struct controller_session *session, f_str_t *in) static void fuzzy_controller_handler (char **args, struct controller_session *session, int cmd) { - char *arg, out_buf[BUFSIZ], *err_str; - uint32_t size; - int r; + char *arg, out_buf[BUFSIZ], *err_str; + uint32_t size; + int r; arg = *args; if (!arg || *arg == '\0') { @@ -500,7 +494,7 @@ fuzzy_delete_handler (char **args, struct controller_session *session) fuzzy_controller_handler (args, session, FUZZY_DEL); } -static int +static int fuzzy_mime_filter (struct worker_task *task) { /* XXX: remove this */ diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index ec07bc0ad..a2bc1574f 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -41,32 +41,32 @@ #define DEFAULT_STATFILE_PREFIX "./" struct regexp_module_item { - struct expression *expr; - char *symbol; - long int avg_time; + struct expression *expr; + char *symbol; + long int avg_time; }; struct autolearn_data { - char *statfile_name; - char *symbol; - float weight; + char *statfile_name; + char *symbol; + float weight; }; struct regexp_ctx { - int (*filter)(struct worker_task *task); - GHashTable *autolearn_symbols; - char *metric; - char *statfile_prefix; + int (*filter) (struct worker_task * task); + GHashTable *autolearn_symbols; + char *metric; + char *statfile_prefix; - memory_pool_t *regexp_pool; + memory_pool_t *regexp_pool; }; -static struct regexp_ctx *regexp_module_ctx = NULL; +static struct regexp_ctx *regexp_module_ctx = NULL; -static int regexp_common_filter (struct worker_task *task); -static gboolean rspamd_regexp_match_number (struct worker_task *task, GList *args); -static gboolean rspamd_raw_header_exists (struct worker_task *task, GList *args); -static void process_regexp_item (struct worker_task *task, void *user_data); +static int regexp_common_filter (struct worker_task *task); +static gboolean rspamd_regexp_match_number (struct worker_task *task, GList * args); +static gboolean rspamd_raw_header_exists (struct worker_task *task, GList * args); +static void process_regexp_item (struct worker_task *task, void *user_data); int @@ -81,14 +81,14 @@ regexp_module_init (struct config_file *cfg, struct module_ctx **ctx) *ctx = (struct module_ctx *)regexp_module_ctx; register_expression_function ("regexp_match_number", rspamd_regexp_match_number); register_expression_function ("raw_header_exists", rspamd_raw_header_exists); - + return 0; } -static gboolean -read_regexp_expression (memory_pool_t *pool, struct regexp_module_item *chain, char *symbol, char *line, struct config_file *cfg) -{ - struct expression *e, *cur; +static gboolean +read_regexp_expression (memory_pool_t * pool, struct regexp_module_item *chain, char *symbol, char *line, struct config_file *cfg) +{ + struct expression *e, *cur; e = parse_expression (regexp_module_ctx->regexp_pool, line); if (e == NULL) { @@ -119,8 +119,8 @@ read_regexp_expression (memory_pool_t *pool, struct regexp_module_item *chain, c void parse_autolearn_param (const char *param, const char *value, struct config_file *cfg) { - struct autolearn_data *d; - char *p; + struct autolearn_data *d; + char *p; p = memory_pool_strdup (regexp_module_ctx->regexp_pool, value); d = memory_pool_alloc (regexp_module_ctx->regexp_pool, sizeof (struct autolearn_data)); @@ -146,13 +146,13 @@ parse_autolearn_param (const char *param, const char *value, struct config_file int regexp_module_config (struct config_file *cfg) { - GList *cur_opt = NULL; - struct module_opt *cur; - struct regexp_module_item *cur_item; - struct metric *metric; - char *value; - int res = TRUE; - double *w; + GList *cur_opt = NULL; + struct module_opt *cur; + struct regexp_module_item *cur_item; + struct metric *metric; + char *value; + int res = TRUE; + double *w; if ((value = get_module_opt (cfg, "regexp", "metric")) != NULL) { regexp_module_ctx->metric = memory_pool_strdup (regexp_module_ctx->regexp_pool, value); @@ -168,7 +168,7 @@ regexp_module_config (struct config_file *cfg) else { regexp_module_ctx->statfile_prefix = DEFAULT_STATFILE_PREFIX; } - + metric = g_hash_table_lookup (cfg->metrics, regexp_module_ctx->metric); if (metric == NULL) { msg_err ("regexp_module_config: cannot find metric definition %s", regexp_module_ctx->metric); @@ -199,10 +199,10 @@ regexp_module_config (struct config_file *cfg) else { register_symbol (&metric->cache, cur->param, *w, process_regexp_item, cur_item); } - + cur_opt = g_list_next (cur_opt); } - + return res; } @@ -215,11 +215,11 @@ regexp_module_reconfig (struct config_file *cfg) return regexp_module_config (cfg); } -static const char * +static const char * find_raw_header_pos (const char *headers, const char *headerv) { - const char *p = headers; - gsize headerlen = strlen (headerv); + const char *p = headers; + gsize headerlen = strlen (headerv); if (headers == NULL) { return NULL; @@ -229,7 +229,7 @@ find_raw_header_pos (const char *headers, const char *headerv) /* Try to find headers only at the begin of line */ if (*p == '\r' || *p == '\n') { if (*(p + 1) == '\n' && *p == '\r') { - p ++; + p++; } if (g_ascii_isspace (*(++p))) { /* Folding */ @@ -245,7 +245,7 @@ find_raw_header_pos (const char *headers, const char *headerv) } } if (*p != '\0') { - p ++; + p++; } } @@ -253,17 +253,17 @@ find_raw_header_pos (const char *headers, const char *headerv) } struct url_regexp_param { - struct worker_task *task; - GRegex *regexp; - struct rspamd_regexp *re; - gboolean found; + struct worker_task *task; + GRegex *regexp; + struct rspamd_regexp *re; + gboolean found; }; -static gboolean +static gboolean tree_url_callback (gpointer key, gpointer value, void *data) { - struct url_regexp_param *param = data; - struct uri *url = value; + struct url_regexp_param *param = data; + struct uri *url = value; if (g_regex_match (param->regexp, struri (url), 0, NULL) == TRUE) { task_cache_add (param->task, param->re, 1); @@ -274,80 +274,54 @@ tree_url_callback (gpointer key, gpointer value, void *data) return FALSE; } -static gsize +static gsize process_regexp (struct rspamd_regexp *re, struct worker_task *task) { - char *headerv, *c, t; - struct mime_text_part *part; - GList *cur, *headerlist; - GRegex *regexp; - struct url_regexp_param callback_param; - int r; - + char *headerv, *c, t; + struct mime_text_part *part; + GList *cur, *headerlist; + GRegex *regexp; + struct url_regexp_param callback_param; + int r; + if (re == NULL) { msg_info ("process_regexp: invalid regexp passed"); return 0; } - + if ((r = task_cache_check (task, re)) != -1) { msg_debug ("process_regexp: regexp /%s/ is found in cache, result: %d", re->regexp_text, r); return r == 1; } switch (re->type) { - case REGEXP_NONE: - msg_warn ("process_regexp: bad error detected: /%s/ has invalid regexp type", re->regexp_text); + case REGEXP_NONE: + msg_warn ("process_regexp: bad error detected: /%s/ has invalid regexp type", re->regexp_text); + return 0; + case REGEXP_HEADER: + if (re->header == NULL) { + msg_info ("process_regexp: header regexp without header name: '%s'", re->regexp_text); + task_cache_add (task, re, 0); return 0; - case REGEXP_HEADER: - if (re->header == NULL) { - msg_info ("process_regexp: header regexp without header name: '%s'", re->regexp_text); - task_cache_add (task, re, 0); - return 0; - } - msg_debug ("process_regexp: checking header regexp: %s = /%s/", re->header, re->regexp_text); - headerlist = message_get_header (task->task_pool, task->message, re->header); - if (headerlist == NULL) { - task_cache_add (task, re, 0); - return 0; - } - else { - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, headerlist); - if (re->regexp == NULL) { - msg_debug ("process_regexp: regexp contains only header and it is found %s", re->header); - task_cache_add (task, re, 1); - return 1; - } - cur = headerlist; - while (cur) { - msg_debug ("process_regexp: found header \"%s\" with value \"%s\"", re->header, (char *)cur->data); - if (cur->data && g_regex_match (re->regexp, cur->data, 0, NULL) == TRUE) { - task_cache_add (task, re, 1); - return 1; - } - cur = g_list_next (cur); - } - task_cache_add (task, re, 0); - return 0; + } + msg_debug ("process_regexp: checking header regexp: %s = /%s/", re->header, re->regexp_text); + headerlist = message_get_header (task->task_pool, task->message, re->header); + if (headerlist == NULL) { + task_cache_add (task, re, 0); + return 0; + } + else { + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_list_free, headerlist); + if (re->regexp == NULL) { + msg_debug ("process_regexp: regexp contains only header and it is found %s", re->header); + task_cache_add (task, re, 1); + return 1; } - break; - case REGEXP_MIME: - msg_debug ("process_regexp: checking mime regexp: /%s/", re->regexp_text); - cur = g_list_first (task->text_parts); + cur = headerlist; while (cur) { - part = (struct mime_text_part *)cur->data; - /* Skip empty parts */ - if (part->is_empty) { - cur = g_list_next (cur); - continue; - } - if (part->is_raw) { - regexp = re->raw_regexp; - } - else { - regexp = re->regexp; - } - if (g_regex_match_full (regexp, part->orig->data, part->orig->len, 0, 0, NULL, NULL) == TRUE) { + msg_debug ("process_regexp: found header \"%s\" with value \"%s\"", re->header, (char *)cur->data); + if (cur->data && g_regex_match (re->regexp, cur->data, 0, NULL) == TRUE) { task_cache_add (task, re, 1); return 1; } @@ -355,105 +329,131 @@ process_regexp (struct rspamd_regexp *re, struct worker_task *task) } task_cache_add (task, re, 0); return 0; - case REGEXP_MESSAGE: - msg_debug ("process_regexp: checking message regexp: /%s/", re->regexp_text); - if (g_regex_match_full (re->raw_regexp, task->msg->begin, task->msg->len, 0, 0, NULL, NULL) == TRUE) { + } + break; + case REGEXP_MIME: + msg_debug ("process_regexp: checking mime regexp: /%s/", re->regexp_text); + cur = g_list_first (task->text_parts); + while (cur) { + part = (struct mime_text_part *)cur->data; + /* Skip empty parts */ + if (part->is_empty) { + cur = g_list_next (cur); + continue; + } + if (part->is_raw) { + regexp = re->raw_regexp; + } + else { + regexp = re->regexp; + } + if (g_regex_match_full (regexp, part->orig->data, part->orig->len, 0, 0, NULL, NULL) == TRUE) { task_cache_add (task, re, 1); return 1; } - task_cache_add (task, re, 0); - return 0; - case REGEXP_URL: - msg_debug ("process_regexp: checking url regexp: /%s/", re->regexp_text); - cur = g_list_first (task->text_parts); - while (cur) { - part = (struct mime_text_part *)cur->data; - /* Skip empty parts */ - if (part->is_empty) { - cur = g_list_next (cur); - continue; - } - if (part->is_raw) { - regexp = re->raw_regexp; - } - else { - regexp = re->regexp; - } - callback_param.task = task; - callback_param.regexp = regexp; - callback_param.re = re; - callback_param.found = FALSE; - if (part->urls) { - g_tree_foreach (part->urls, tree_url_callback, &callback_param); - } - if (part->html_urls && callback_param.found == FALSE) { - g_tree_foreach (part->html_urls, tree_url_callback, &callback_param); - } + cur = g_list_next (cur); + } + task_cache_add (task, re, 0); + return 0; + case REGEXP_MESSAGE: + msg_debug ("process_regexp: checking message regexp: /%s/", re->regexp_text); + if (g_regex_match_full (re->raw_regexp, task->msg->begin, task->msg->len, 0, 0, NULL, NULL) == TRUE) { + task_cache_add (task, re, 1); + return 1; + } + task_cache_add (task, re, 0); + return 0; + case REGEXP_URL: + msg_debug ("process_regexp: checking url regexp: /%s/", re->regexp_text); + cur = g_list_first (task->text_parts); + while (cur) { + part = (struct mime_text_part *)cur->data; + /* Skip empty parts */ + if (part->is_empty) { cur = g_list_next (cur); + continue; } - if (callback_param.found == FALSE) { - task_cache_add (task, re, 0); + if (part->is_raw) { + regexp = re->raw_regexp; } + else { + regexp = re->regexp; + } + callback_param.task = task; + callback_param.regexp = regexp; + callback_param.re = re; + callback_param.found = FALSE; + if (part->urls) { + g_tree_foreach (part->urls, tree_url_callback, &callback_param); + } + if (part->html_urls && callback_param.found == FALSE) { + g_tree_foreach (part->html_urls, tree_url_callback, &callback_param); + } + cur = g_list_next (cur); + } + if (callback_param.found == FALSE) { + task_cache_add (task, re, 0); + } + return 0; + case REGEXP_RAW_HEADER: + msg_debug ("process_regexp: checking for raw header: %s with regexp: /%s/", re->header, re->regexp_text); + if (task->raw_headers == NULL) { + msg_debug ("process_regexp: cannot check for raw header in message, no headers found"); + task_cache_add (task, re, 0); + return 0; + } + if ((headerv = (char *)find_raw_header_pos (task->raw_headers, re->header)) == NULL) { + /* No header was found */ + task_cache_add (task, re, 0); return 0; - case REGEXP_RAW_HEADER: - msg_debug ("process_regexp: checking for raw header: %s with regexp: /%s/", re->header, re->regexp_text); - if (task->raw_headers == NULL) { - msg_debug ("process_regexp: cannot check for raw header in message, no headers found"); - task_cache_add (task, re, 0); - return 0; - } - if ((headerv = (char *)find_raw_header_pos (task->raw_headers, re->header)) == NULL) { - /* No header was found */ - task_cache_add (task, re, 0); - return 0; - } - /* Now the main problem is to find position of end of raw header */ - c = headerv; - while (*c) { - /* We need to handle all types of line end */ - if ((*c == '\r' && *(c + 1) == '\n')) { - c ++; - /* Check for folding */ - if (!g_ascii_isspace (*(c + 1))) { - c ++; - break; - } - } - else if (*c == '\r' || *c == '\n') { - if (!g_ascii_isspace (*(c + 1))) { - c ++; - break; - } + } + /* Now the main problem is to find position of end of raw header */ + c = headerv; + while (*c) { + /* We need to handle all types of line end */ + if ((*c == '\r' && *(c + 1) == '\n')) { + c++; + /* Check for folding */ + if (!g_ascii_isspace (*(c + 1))) { + c++; + break; } - c ++; - } - /* Temporary null terminate this part of string */ - t = *c; - *c = '\0'; - msg_debug ("process_regexp: found raw header \"%s\" with value \"%s\"", re->header, headerv); - if (g_regex_match (re->raw_regexp, headerv, 0, NULL) == TRUE) { - *c = t; - task_cache_add (task, re, 1); - return 1; } + else if (*c == '\r' || *c == '\n') { + if (!g_ascii_isspace (*(c + 1))) { + c++; + break; + } + } + c++; + } + /* Temporary null terminate this part of string */ + t = *c; + *c = '\0'; + msg_debug ("process_regexp: found raw header \"%s\" with value \"%s\"", re->header, headerv); + if (g_regex_match (re->raw_regexp, headerv, 0, NULL) == TRUE) { *c = t; - task_cache_add (task, re, 0); - return 0; - default: - msg_warn ("process_regexp: bad error detected: %p is not a valid regexp object", re); + task_cache_add (task, re, 1); + return 1; + } + *c = t; + task_cache_add (task, re, 0); + return 0; + default: + msg_warn ("process_regexp: bad error detected: %p is not a valid regexp object", re); } /* Not reached */ return 0; } -static gboolean -optimize_regexp_expression (struct expression **e, GQueue *stack, gboolean res) +static gboolean +optimize_regexp_expression (struct expression **e, GQueue * stack, gboolean res) { - struct expression *it = (*e)->next; - gboolean ret = FALSE, is_nearest = TRUE; - int skip_level = 0; - + struct expression *it = (*e)->next; + gboolean ret = FALSE, is_nearest = TRUE; + int skip_level = 0; + /* Skip nearest logical operators from optimization */ if (!it || (it->type == EXPR_OPERATION && it->content.operation != '!')) { g_queue_push_head (stack, GSIZE_TO_POINTER (res)); @@ -474,7 +474,7 @@ optimize_regexp_expression (struct expression **e, GQueue *stack, gboolean res) continue; } else { - skip_level --; + skip_level--; } /* Check whether we found corresponding operator for this operand */ if (skip_level <= 0) { @@ -493,7 +493,7 @@ optimize_regexp_expression (struct expression **e, GQueue *stack, gboolean res) } else { is_nearest = FALSE; - skip_level ++; + skip_level++; } it = it->next; } @@ -503,15 +503,15 @@ optimize_regexp_expression (struct expression **e, GQueue *stack, gboolean res) return ret; } -static gboolean +static gboolean process_regexp_expression (struct expression *expr, char *symbol, struct worker_task *task) { - GQueue *stack; - gsize cur, op1, op2; - struct expression *it = expr; - struct rspamd_regexp *re; - gboolean try_optimize = TRUE; - + GQueue *stack; + gsize cur, op1, op2; + struct expression *it = expr; + struct rspamd_regexp *re; + gboolean try_optimize = TRUE; + stack = g_queue_new (); while (it) { @@ -525,17 +525,18 @@ process_regexp_expression (struct expression *expr, char *symbol, struct worker_ else { g_queue_push_head (stack, GSIZE_TO_POINTER (cur)); } - } else if (it->type == EXPR_FUNCTION) { - cur = (gsize)call_expression_function ((struct expression_function *)it->content.operand, task); - msg_debug ("process_regexp_expression: function %s returned %s", ((struct expression_function *)it->content.operand)->name, - cur ? "true" : "false"); + } + else if (it->type == EXPR_FUNCTION) { + cur = (gsize) call_expression_function ((struct expression_function *)it->content.operand, task); + msg_debug ("process_regexp_expression: function %s returned %s", ((struct expression_function *)it->content.operand)->name, cur ? "true" : "false"); if (try_optimize) { try_optimize = optimize_regexp_expression (&it, stack, cur); } else { g_queue_push_head (stack, GSIZE_TO_POINTER (cur)); } - } else if (it->type == EXPR_REGEXP) { + } + else if (it->type == EXPR_REGEXP) { /* Compile regexp if it is not parsed */ if (it->content.operand == NULL) { it = it->next; @@ -544,14 +545,15 @@ process_regexp_expression (struct expression *expr, char *symbol, struct worker_ re = parse_regexp (task->cfg->cfg_pool, it->content.operand, task->cfg->raw_mode); if (re == NULL) { msg_warn ("process_regexp_expression: cannot parse regexp, skip expression"); - g_queue_free (stack); + g_queue_free (stack); return FALSE; } it->content.operand = re; it->type = EXPR_REGEXP_PARSED; /* Continue with this regexp once again */ continue; - } else if (it->type == EXPR_OPERATION) { + } + else if (it->type == EXPR_OPERATION) { if (g_queue_is_empty (stack)) { /* Queue has no operands for operation, exiting */ msg_warn ("process_regexp_expression: regexp expression seems to be invalid: empty stack while reading operation"); @@ -560,24 +562,24 @@ process_regexp_expression (struct expression *expr, char *symbol, struct worker_ } msg_debug ("process_regexp_expression: got operation %c", it->content.operation); switch (it->content.operation) { - case '!': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op1 = !op1; - try_optimize = optimize_regexp_expression (&it, stack, op1); - break; - case '&': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - try_optimize = optimize_regexp_expression (&it, stack, op1 && op2); - break; - case '|': - op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); - try_optimize = optimize_regexp_expression (&it, stack, op1 || op2); - break; - default: - it = it->next; - continue; + case '!': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op1 = !op1; + try_optimize = optimize_regexp_expression (&it, stack, op1); + break; + case '&': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + try_optimize = optimize_regexp_expression (&it, stack, op1 && op2); + break; + case '|': + op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack)); + try_optimize = optimize_regexp_expression (&it, stack, op1 || op2); + break; + default: + it = it->next; + continue; } } if (it) { @@ -594,7 +596,7 @@ process_regexp_expression (struct expression *expr, char *symbol, struct worker_ else { msg_warn ("process_regexp_expression: regexp expression seems to be invalid: empty stack at the end of expression, symbol %s", symbol); } - + g_queue_free (stack); return FALSE; @@ -602,47 +604,47 @@ process_regexp_expression (struct expression *expr, char *symbol, struct worker_ static void process_regexp_item (struct worker_task *task, void *user_data) -{ - struct regexp_module_item *item = user_data; +{ + struct regexp_module_item *item = user_data; if (process_regexp_expression (item->expr, item->symbol, task)) { insert_result (task, regexp_module_ctx->metric, item->symbol, 1, NULL); } } -static int +static int regexp_common_filter (struct worker_task *task) { /* XXX: remove this shit too */ - return 0; + return 0; } -static gboolean -rspamd_regexp_match_number (struct worker_task *task, GList *args) +static gboolean +rspamd_regexp_match_number (struct worker_task *task, GList * args) { - int param_count, res = 0; - struct expression_argument *arg; - GList *cur; - + int param_count, res = 0; + struct expression_argument *arg; + GList *cur; + if (args == NULL) { msg_warn ("rspamd_regexp_match_number: no parameters to function"); return FALSE; } - + arg = get_function_arg (args->data, task, TRUE); param_count = strtoul (arg->data, NULL, 10); - + cur = args->next; while (cur) { arg = get_function_arg (cur->data, task, FALSE); if (arg && arg->type == EXPRESSION_ARGUMENT_BOOL) { - if ((gboolean)GPOINTER_TO_SIZE (arg->data)) { - res ++; + if ((gboolean) GPOINTER_TO_SIZE (arg->data)) { + res++; } } else { if (process_regexp_expression (cur->data, "regexp_match_number", task)) { - res ++; + res++; } if (res >= param_count) { return TRUE; @@ -654,10 +656,10 @@ rspamd_regexp_match_number (struct worker_task *task, GList *args) return res >= param_count; } -static gboolean -rspamd_raw_header_exists (struct worker_task *task, GList *args) +static gboolean +rspamd_raw_header_exists (struct worker_task *task, GList * args) { - struct expression_argument *arg; + struct expression_argument *arg; if (args == NULL || task == NULL) { return FALSE; diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c index 61f70586e..2557e6e2e 100644 --- a/src/plugins/surbl.c +++ b/src/plugins/surbl.c @@ -35,13 +35,13 @@ #include "surbl.h" -static struct surbl_ctx *surbl_module_ctx = NULL; +static struct surbl_ctx *surbl_module_ctx = NULL; -static int surbl_filter (struct worker_task *task); -static void surbl_test_url (struct worker_task *task, void *user_data); -static void dns_callback (int result, char type, int count, int ttl, void *addresses, void *data); -static void process_dns_results (struct worker_task *task, struct suffix_item *suffix, char *url, uint32_t addr); -static int urls_command_handler (struct worker_task *task); +static int surbl_filter (struct worker_task *task); +static void surbl_test_url (struct worker_task *task, void *user_data); +static void dns_callback (int result, char type, int count, int ttl, void *addresses, void *data); +static void process_dns_results (struct worker_task *task, struct suffix_item *suffix, char *url, uint32_t addr); +static int urls_command_handler (struct worker_task *task); #define SURBL_ERROR surbl_error_quark () #define WHITELIST_ERROR 0 @@ -49,855 +49,835 @@ static int urls_command_handler (struct worker_task *task); GQuark surbl_error_quark (void) { - return g_quark_from_static_string ("surbl-error-quark"); + return g_quark_from_static_string ("surbl-error-quark"); } int surbl_module_init (struct config_file *cfg, struct module_ctx **ctx) { - GError *err = NULL; - - surbl_module_ctx = g_malloc (sizeof (struct surbl_ctx)); - - surbl_module_ctx->filter = surbl_filter; - surbl_module_ctx->use_redirector = 0; - surbl_module_ctx->suffixes = NULL; - surbl_module_ctx->bits = NULL; - surbl_module_ctx->surbl_pool = memory_pool_new (memory_pool_get_size ()); - - surbl_module_ctx->tld2_file = NULL; - surbl_module_ctx->whitelist_file = NULL; - - surbl_module_ctx->tld2 = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); - surbl_module_ctx->redirector_hosts = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); - surbl_module_ctx->whitelist = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); - /* Register destructors */ - memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_hash_table_destroy, surbl_module_ctx->tld2); - memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_hash_table_destroy, surbl_module_ctx->whitelist); - memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_hash_table_destroy, surbl_module_ctx->redirector_hosts); - - memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_list_free, surbl_module_ctx->suffixes); - memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func)g_list_free, surbl_module_ctx->bits); - - /* Init matching regexps */ - surbl_module_ctx->extract_hoster_regexp = g_regex_new ("([^.]+)\\.([^.]+)\\.([^.]+)$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); - surbl_module_ctx->extract_normal_regexp = g_regex_new ("([^.]+)\\.([^.]+)$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); - surbl_module_ctx->extract_ip_regexp = g_regex_new ("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); - surbl_module_ctx->extract_numeric_regexp = g_regex_new ("(\\d{5,20})$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); - - *ctx = (struct module_ctx *)surbl_module_ctx; - - register_protocol_command ("urls", urls_command_handler); - - return 0; + GError *err = NULL; + + surbl_module_ctx = g_malloc (sizeof (struct surbl_ctx)); + + surbl_module_ctx->filter = surbl_filter; + surbl_module_ctx->use_redirector = 0; + surbl_module_ctx->suffixes = NULL; + surbl_module_ctx->bits = NULL; + surbl_module_ctx->surbl_pool = memory_pool_new (memory_pool_get_size ()); + + surbl_module_ctx->tld2_file = NULL; + surbl_module_ctx->whitelist_file = NULL; + + surbl_module_ctx->tld2 = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); + surbl_module_ctx->redirector_hosts = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); + surbl_module_ctx->whitelist = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); + /* Register destructors */ + memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func) g_hash_table_destroy, surbl_module_ctx->tld2); + memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func) g_hash_table_destroy, surbl_module_ctx->whitelist); + memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func) g_hash_table_destroy, surbl_module_ctx->redirector_hosts); + + memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func) g_list_free, surbl_module_ctx->suffixes); + memory_pool_add_destructor (surbl_module_ctx->surbl_pool, (pool_destruct_func) g_list_free, surbl_module_ctx->bits); + + /* Init matching regexps */ + surbl_module_ctx->extract_hoster_regexp = g_regex_new ("([^.]+)\\.([^.]+)\\.([^.]+)$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); + surbl_module_ctx->extract_normal_regexp = g_regex_new ("([^.]+)\\.([^.]+)$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); + surbl_module_ctx->extract_ip_regexp = g_regex_new ("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); + surbl_module_ctx->extract_numeric_regexp = g_regex_new ("(\\d{5,20})$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &err); + + *ctx = (struct module_ctx *)surbl_module_ctx; + + register_protocol_command ("urls", urls_command_handler); + + return 0; } int surbl_module_config (struct config_file *cfg) { - struct hostent *hent; - GList *cur_opt; - struct module_opt *cur; - struct suffix_item *new_suffix; - struct surbl_bit_item *new_bit; - struct metric *metric; - double *w; - - char *value, *cur_tok, *str; - uint32_t bit; - - - if ((value = get_module_opt (cfg, "surbl", "redirector")) != NULL) { - str = memory_pool_strdup (surbl_module_ctx->surbl_pool, value); - cur_tok = strsep (&str, ":"); - if (!inet_aton (cur_tok, &surbl_module_ctx->redirector_addr)) { - /* Try to call gethostbyname */ - hent = gethostbyname (cur_tok); - if (hent != NULL) { - memcpy((char *)&surbl_module_ctx->redirector_addr, hent->h_addr, sizeof(struct in_addr)); - if (str != NULL) { - surbl_module_ctx->redirector_port = (uint16_t)strtoul (str, NULL, 10); - } - else { - surbl_module_ctx->redirector_port = DEFAULT_REDIRECTOR_PORT; - } - surbl_module_ctx->use_redirector = 1; - } - } - } - if ((value = get_module_opt (cfg, "surbl", "weight")) != NULL) { - surbl_module_ctx->weight = atoi (value); - } - else { - surbl_module_ctx->weight = DEFAULT_SURBL_WEIGHT; - } - if ((value = get_module_opt (cfg, "surbl", "url_expire")) != NULL) { - surbl_module_ctx->url_expire = atoi (value); - } - else { - surbl_module_ctx->url_expire = DEFAULT_SURBL_URL_EXPIRE; - } - if ((value = get_module_opt (cfg, "surbl", "redirector_connect_timeout")) != NULL) { - surbl_module_ctx->connect_timeout = parse_seconds (value); - } - else { - surbl_module_ctx->connect_timeout = DEFAULT_REDIRECTOR_CONNECT_TIMEOUT; - } - if ((value = get_module_opt (cfg, "surbl", "redirector_read_timeout")) != NULL) { - surbl_module_ctx->read_timeout = parse_seconds (value); - } - else { - surbl_module_ctx->read_timeout = DEFAULT_REDIRECTOR_READ_TIMEOUT; - } - if ((value = get_module_opt (cfg, "surbl", "redirector_hosts_map")) != NULL) { - add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->redirector_hosts); - } - else { - surbl_module_ctx->read_timeout = DEFAULT_REDIRECTOR_READ_TIMEOUT; - } - if ((value = get_module_opt (cfg, "surbl", "max_urls")) != NULL) { - surbl_module_ctx->max_urls = atoi (value); - } - else { - surbl_module_ctx->max_urls = DEFAULT_SURBL_MAX_URLS; - } - if ((value = get_module_opt (cfg, "surbl", "metric")) != NULL) { - surbl_module_ctx->metric = memory_pool_strdup (surbl_module_ctx->surbl_pool, value); - } - else { - surbl_module_ctx->metric = DEFAULT_METRIC; - } - if ((value = get_module_opt (cfg, "surbl", "2tld")) != NULL) { - if (add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->tld2)) { - surbl_module_ctx->tld2_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); - } - } - if ((value = get_module_opt (cfg, "surbl", "whitelist")) != NULL) { - if (add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->whitelist)) { - surbl_module_ctx->whitelist_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); - } - } - - metric = g_hash_table_lookup (cfg->metrics, surbl_module_ctx->metric); - if (metric == NULL) { - msg_err ("surbl_module_config: cannot find metric definition %s", surbl_module_ctx->metric); - return FALSE; - } - - - cur_opt = g_hash_table_lookup (cfg->modules_opts, "surbl"); - while (cur_opt) { - cur = cur_opt->data; - if (!g_strncasecmp (cur->param, "suffix", sizeof ("suffix") - 1)) { - if ((str = strchr (cur->param, '_')) != NULL) { - new_suffix = memory_pool_alloc (surbl_module_ctx->surbl_pool, sizeof (struct suffix_item)); - *str = '\0'; - new_suffix->symbol = memory_pool_strdup (surbl_module_ctx->surbl_pool, str + 1); - new_suffix->suffix = memory_pool_strdup (surbl_module_ctx->surbl_pool, cur->value); - msg_debug ("surbl_module_config: add new surbl suffix: %s with symbol: %s", - new_suffix->suffix, new_suffix->symbol); - *str = '_'; - surbl_module_ctx->suffixes = g_list_prepend (surbl_module_ctx->suffixes, new_suffix); - /* Search in factors hash table */ - w = g_hash_table_lookup (cfg->factors, new_suffix->symbol); - if (w == NULL) { - register_symbol (&metric->cache, new_suffix->symbol, 1, surbl_test_url, new_suffix); - } - else { - register_symbol (&metric->cache, new_suffix->symbol, *w, surbl_test_url, new_suffix); - } - } - } - if (!g_strncasecmp (cur->param, "bit", sizeof ("bit") - 1)) { - if ((str = strchr (cur->param, '_')) != NULL) { - bit = strtoul (str + 1, NULL, 10); - if (bit != 0) { - new_bit = memory_pool_alloc (surbl_module_ctx->surbl_pool, sizeof (struct surbl_bit_item)); - new_bit->bit = bit; - new_bit->symbol = memory_pool_strdup (surbl_module_ctx->surbl_pool, cur->value); - msg_debug ("surbl_module_config: add new bit suffix: %d with symbol: %s", - (int)new_bit->bit, new_bit->symbol); - surbl_module_ctx->bits = g_list_prepend (surbl_module_ctx->bits, new_bit); - } - } - } - cur_opt = g_list_next (cur_opt); - } - /* Add default suffix */ - if (surbl_module_ctx->suffixes == NULL) { - new_suffix = memory_pool_alloc (surbl_module_ctx->surbl_pool, sizeof (struct suffix_item)); - new_suffix->suffix = memory_pool_strdup (surbl_module_ctx->surbl_pool, DEFAULT_SURBL_SUFFIX); - new_suffix->symbol = memory_pool_strdup (surbl_module_ctx->surbl_pool, DEFAULT_SURBL_SYMBOL); - msg_debug ("surbl_module_config: add default surbl suffix: %s with symbol: %s", - new_suffix->suffix, new_suffix->symbol); - surbl_module_ctx->suffixes = g_list_prepend (surbl_module_ctx->suffixes, new_suffix); - w = g_hash_table_lookup (cfg->factors, new_suffix->symbol); - if (w == NULL) { - register_symbol (&metric->cache, new_suffix->symbol, 1, surbl_test_url, new_suffix); - } - else { - register_symbol (&metric->cache, new_suffix->symbol, *w, surbl_test_url, new_suffix); - } - } - - return TRUE; + struct hostent *hent; + GList *cur_opt; + struct module_opt *cur; + struct suffix_item *new_suffix; + struct surbl_bit_item *new_bit; + struct metric *metric; + double *w; + + char *value, *cur_tok, *str; + uint32_t bit; + + + if ((value = get_module_opt (cfg, "surbl", "redirector")) != NULL) { + str = memory_pool_strdup (surbl_module_ctx->surbl_pool, value); + cur_tok = strsep (&str, ":"); + if (!inet_aton (cur_tok, &surbl_module_ctx->redirector_addr)) { + /* Try to call gethostbyname */ + hent = gethostbyname (cur_tok); + if (hent != NULL) { + memcpy ((char *)&surbl_module_ctx->redirector_addr, hent->h_addr, sizeof (struct in_addr)); + if (str != NULL) { + surbl_module_ctx->redirector_port = (uint16_t) strtoul (str, NULL, 10); + } + else { + surbl_module_ctx->redirector_port = DEFAULT_REDIRECTOR_PORT; + } + surbl_module_ctx->use_redirector = 1; + } + } + } + if ((value = get_module_opt (cfg, "surbl", "weight")) != NULL) { + surbl_module_ctx->weight = atoi (value); + } + else { + surbl_module_ctx->weight = DEFAULT_SURBL_WEIGHT; + } + if ((value = get_module_opt (cfg, "surbl", "url_expire")) != NULL) { + surbl_module_ctx->url_expire = atoi (value); + } + else { + surbl_module_ctx->url_expire = DEFAULT_SURBL_URL_EXPIRE; + } + if ((value = get_module_opt (cfg, "surbl", "redirector_connect_timeout")) != NULL) { + surbl_module_ctx->connect_timeout = parse_seconds (value); + } + else { + surbl_module_ctx->connect_timeout = DEFAULT_REDIRECTOR_CONNECT_TIMEOUT; + } + if ((value = get_module_opt (cfg, "surbl", "redirector_read_timeout")) != NULL) { + surbl_module_ctx->read_timeout = parse_seconds (value); + } + else { + surbl_module_ctx->read_timeout = DEFAULT_REDIRECTOR_READ_TIMEOUT; + } + if ((value = get_module_opt (cfg, "surbl", "redirector_hosts_map")) != NULL) { + add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->redirector_hosts); + } + else { + surbl_module_ctx->read_timeout = DEFAULT_REDIRECTOR_READ_TIMEOUT; + } + if ((value = get_module_opt (cfg, "surbl", "max_urls")) != NULL) { + surbl_module_ctx->max_urls = atoi (value); + } + else { + surbl_module_ctx->max_urls = DEFAULT_SURBL_MAX_URLS; + } + if ((value = get_module_opt (cfg, "surbl", "metric")) != NULL) { + surbl_module_ctx->metric = memory_pool_strdup (surbl_module_ctx->surbl_pool, value); + } + else { + surbl_module_ctx->metric = DEFAULT_METRIC; + } + if ((value = get_module_opt (cfg, "surbl", "2tld")) != NULL) { + if (add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->tld2)) { + surbl_module_ctx->tld2_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); + } + } + if ((value = get_module_opt (cfg, "surbl", "whitelist")) != NULL) { + if (add_map (value, read_host_list, fin_host_list, (void **)&surbl_module_ctx->whitelist)) { + surbl_module_ctx->whitelist_file = memory_pool_strdup (surbl_module_ctx->surbl_pool, value + sizeof ("file://") - 1); + } + } + + metric = g_hash_table_lookup (cfg->metrics, surbl_module_ctx->metric); + if (metric == NULL) { + msg_err ("surbl_module_config: cannot find metric definition %s", surbl_module_ctx->metric); + return FALSE; + } + + + cur_opt = g_hash_table_lookup (cfg->modules_opts, "surbl"); + while (cur_opt) { + cur = cur_opt->data; + if (!g_strncasecmp (cur->param, "suffix", sizeof ("suffix") - 1)) { + if ((str = strchr (cur->param, '_')) != NULL) { + new_suffix = memory_pool_alloc (surbl_module_ctx->surbl_pool, sizeof (struct suffix_item)); + *str = '\0'; + new_suffix->symbol = memory_pool_strdup (surbl_module_ctx->surbl_pool, str + 1); + new_suffix->suffix = memory_pool_strdup (surbl_module_ctx->surbl_pool, cur->value); + msg_debug ("surbl_module_config: add new surbl suffix: %s with symbol: %s", new_suffix->suffix, new_suffix->symbol); + *str = '_'; + surbl_module_ctx->suffixes = g_list_prepend (surbl_module_ctx->suffixes, new_suffix); + /* Search in factors hash table */ + w = g_hash_table_lookup (cfg->factors, new_suffix->symbol); + if (w == NULL) { + register_symbol (&metric->cache, new_suffix->symbol, 1, surbl_test_url, new_suffix); + } + else { + register_symbol (&metric->cache, new_suffix->symbol, *w, surbl_test_url, new_suffix); + } + } + } + if (!g_strncasecmp (cur->param, "bit", sizeof ("bit") - 1)) { + if ((str = strchr (cur->param, '_')) != NULL) { + bit = strtoul (str + 1, NULL, 10); + if (bit != 0) { + new_bit = memory_pool_alloc (surbl_module_ctx->surbl_pool, sizeof (struct surbl_bit_item)); + new_bit->bit = bit; + new_bit->symbol = memory_pool_strdup (surbl_module_ctx->surbl_pool, cur->value); + msg_debug ("surbl_module_config: add new bit suffix: %d with symbol: %s", (int)new_bit->bit, new_bit->symbol); + surbl_module_ctx->bits = g_list_prepend (surbl_module_ctx->bits, new_bit); + } + } + } + cur_opt = g_list_next (cur_opt); + } + /* Add default suffix */ + if (surbl_module_ctx->suffixes == NULL) { + new_suffix = memory_pool_alloc (surbl_module_ctx->surbl_pool, sizeof (struct suffix_item)); + new_suffix->suffix = memory_pool_strdup (surbl_module_ctx->surbl_pool, DEFAULT_SURBL_SUFFIX); + new_suffix->symbol = memory_pool_strdup (surbl_module_ctx->surbl_pool, DEFAULT_SURBL_SYMBOL); + msg_debug ("surbl_module_config: add default surbl suffix: %s with symbol: %s", new_suffix->suffix, new_suffix->symbol); + surbl_module_ctx->suffixes = g_list_prepend (surbl_module_ctx->suffixes, new_suffix); + w = g_hash_table_lookup (cfg->factors, new_suffix->symbol); + if (w == NULL) { + register_symbol (&metric->cache, new_suffix->symbol, 1, surbl_test_url, new_suffix); + } + else { + register_symbol (&metric->cache, new_suffix->symbol, *w, surbl_test_url, new_suffix); + } + } + + return TRUE; } int surbl_module_reconfig (struct config_file *cfg) { - memory_pool_delete (surbl_module_ctx->surbl_pool); - surbl_module_ctx->surbl_pool = memory_pool_new (1024); + memory_pool_delete (surbl_module_ctx->surbl_pool); + surbl_module_ctx->surbl_pool = memory_pool_new (1024); - return surbl_module_config (cfg); + return surbl_module_config (cfg); } -static char * -format_surbl_request (memory_pool_t *pool, f_str_t *hostname, struct suffix_item *suffix, char **host_end, gboolean append_suffix, GError **err) +static char * +format_surbl_request (memory_pool_t * pool, f_str_t * hostname, struct suffix_item *suffix, char **host_end, gboolean append_suffix, GError ** err) { - GMatchInfo *info; - char *result = NULL; - int len, slen, r; - - if (suffix != NULL) { - slen = strlen (suffix->suffix); - } - else if (!append_suffix) { - slen = 0; - } - else { - g_assert_not_reached (); - } - len = hostname->len + slen + 2; - - /* First try to match numeric expression */ - if (g_ascii_isdigit (*hostname->begin)) { - if (g_regex_match_full (surbl_module_ctx->extract_ip_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { - gchar *octet1, *octet2, *octet3, *octet4; - octet1 = g_match_info_fetch (info, 1); - octet2 = g_match_info_fetch (info, 2); - octet3 = g_match_info_fetch (info, 3); - octet4 = g_match_info_fetch (info, 4); - result = memory_pool_alloc (pool, len); - msg_debug ("format_surbl_request: got numeric host for check: %s.%s.%s.%s", octet1, octet2, octet3, octet4); - r = snprintf (result, len, "%s.%s.%s.%s", octet4, octet3, octet2, octet1); - if (g_hash_table_lookup (surbl_module_ctx->whitelist, result) != NULL) { - g_free (octet1); - g_free (octet2); - g_free (octet3); - g_free (octet4); - g_match_info_free (info); - msg_debug ("format_surbl_request: url %s is whitelisted", result); - g_set_error (err, - SURBL_ERROR, /* error domain */ - WHITELIST_ERROR, /* error code */ - "URL is whitelisted: %s", /* error message format string */ - result); - - return NULL; - } - if (append_suffix) { - r += snprintf (result + r, len - r, ".%s", suffix->suffix); - } - *host_end = result + r - slen - 1; - g_free (octet1); - g_free (octet2); - g_free (octet3); - g_free (octet4); - g_match_info_free (info); - return result; - } - g_match_info_free (info); - if (g_regex_match_full (surbl_module_ctx->extract_numeric_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { - gchar *ip = g_match_info_fetch (info, 1); - uint64_t ip_num; - - errno = 0; - ip_num = strtoull (ip, NULL, 10); - if (errno != 0) { - g_match_info_free (info); - msg_info ("format_surbl_request: cannot convert ip to number '%s': %s", ip, strerror (errno)); - g_set_error (err, - SURBL_ERROR, /* error domain */ - CONVERSION_ERROR, /* error code */ - "URL cannot be decoded"); - g_free (ip); - - return NULL; - } - - len = sizeof ("255.255.255.255") + slen; - result = memory_pool_alloc (pool, len); - /* Hack for bugged windows resolver */ - ip_num &= 0xFFFFFFFF; - /* Get octets */ - r = snprintf (result, len, "%u.%u.%u.%u", - (uint32_t)ip_num & 0x000000FF, - (uint32_t)(ip_num & 0x0000FF00) >> 8, - (uint32_t)(ip_num & 0x00FF0000) >> 16, - (uint32_t)(ip_num & 0xFF000000) >> 24); - if (append_suffix) { - r += snprintf (result + r, len - r, ".%s", suffix->suffix); - } - *host_end = result + r - slen - 1; - g_free (ip); - g_match_info_free (info); - return result; - } - g_match_info_free (info); - } - /* Try to match normal domain */ - if (g_regex_match_full (surbl_module_ctx->extract_normal_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { - gchar *part1, *part2; - part1 = g_match_info_fetch (info, 1); - part2 = g_match_info_fetch (info, 2); - g_match_info_free (info); - result = memory_pool_alloc (pool, len); - r = snprintf (result, len, "%s.%s", part1, part2); - if (g_hash_table_lookup (surbl_module_ctx->tld2, result) != NULL) { - /* Match additional part for hosters */ - g_free (part1); - g_free (part2); - if (g_regex_match_full (surbl_module_ctx->extract_hoster_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { - gchar *hpart1, *hpart2, *hpart3; - hpart1 = g_match_info_fetch (info, 1); - hpart2 = g_match_info_fetch (info, 2); - hpart3 = g_match_info_fetch (info, 3); - msg_debug ("format_surbl_request: got hoster 3-d level domain %s.%s.%s", hpart1, hpart2, hpart3); - r = snprintf (result, len, "%s.%s.%s", hpart1, hpart2, hpart3); - if (g_hash_table_lookup (surbl_module_ctx->whitelist, result) != NULL) { - g_free (hpart1); - g_free (hpart2); - g_free (hpart3); - g_match_info_free (info); - msg_debug ("format_surbl_request: url %s is whitelisted", result); - g_set_error (err, - SURBL_ERROR, /* error domain */ - WHITELIST_ERROR, /* error code */ - "URL is whitelisted: %s", /* error message format string */ - result); - return NULL; - } - if (append_suffix) { - r += snprintf (result + r, len - r, ".%s", suffix->suffix); - } - *host_end = result + r - slen - 1; - g_free (hpart1); - g_free (hpart2); - g_free (hpart3); - g_match_info_free (info); - return result; - } - g_match_info_free (info); - *host_end = NULL; - return NULL; - } - else { - if (g_hash_table_lookup (surbl_module_ctx->whitelist, result) != NULL) { - g_free (part1); - g_free (part2); - msg_debug ("format_surbl_request: url %s is whitelisted", result); - g_set_error (err, - SURBL_ERROR, /* error domain */ - WHITELIST_ERROR, /* error code */ - "URL is whitelisted: %s", /* error message format string */ - result); - return NULL; - } - if (append_suffix) { - r += snprintf (result + r, len - r, ".%s", suffix->suffix); - } - *host_end = result + r - slen - 1; - msg_debug ("format_surbl_request: got normal 2-d level domain %s.%s", part1, part2); - } - g_free (part1); - g_free (part2); - return result; - } - - g_match_info_free (info); - *host_end = NULL; - return NULL; + GMatchInfo *info; + char *result = NULL; + int len, slen, r; + + if (suffix != NULL) { + slen = strlen (suffix->suffix); + } + else if (!append_suffix) { + slen = 0; + } + else { + g_assert_not_reached (); + } + len = hostname->len + slen + 2; + + /* First try to match numeric expression */ + if (g_ascii_isdigit (*hostname->begin)) { + if (g_regex_match_full (surbl_module_ctx->extract_ip_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { + gchar *octet1, *octet2, *octet3, *octet4; + octet1 = g_match_info_fetch (info, 1); + octet2 = g_match_info_fetch (info, 2); + octet3 = g_match_info_fetch (info, 3); + octet4 = g_match_info_fetch (info, 4); + result = memory_pool_alloc (pool, len); + msg_debug ("format_surbl_request: got numeric host for check: %s.%s.%s.%s", octet1, octet2, octet3, octet4); + r = snprintf (result, len, "%s.%s.%s.%s", octet4, octet3, octet2, octet1); + if (g_hash_table_lookup (surbl_module_ctx->whitelist, result) != NULL) { + g_free (octet1); + g_free (octet2); + g_free (octet3); + g_free (octet4); + g_match_info_free (info); + msg_debug ("format_surbl_request: url %s is whitelisted", result); + g_set_error (err, SURBL_ERROR, /* error domain */ + WHITELIST_ERROR, /* error code */ + "URL is whitelisted: %s", /* error message format string */ + result); + + return NULL; + } + if (append_suffix) { + r += snprintf (result + r, len - r, ".%s", suffix->suffix); + } + *host_end = result + r - slen - 1; + g_free (octet1); + g_free (octet2); + g_free (octet3); + g_free (octet4); + g_match_info_free (info); + return result; + } + g_match_info_free (info); + if (g_regex_match_full (surbl_module_ctx->extract_numeric_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { + gchar *ip = g_match_info_fetch (info, 1); + uint64_t ip_num; + + errno = 0; + ip_num = strtoull (ip, NULL, 10); + if (errno != 0) { + g_match_info_free (info); + msg_info ("format_surbl_request: cannot convert ip to number '%s': %s", ip, strerror (errno)); + g_set_error (err, SURBL_ERROR, /* error domain */ + CONVERSION_ERROR, /* error code */ + "URL cannot be decoded"); + g_free (ip); + + return NULL; + } + + len = sizeof ("255.255.255.255") + slen; + result = memory_pool_alloc (pool, len); + /* Hack for bugged windows resolver */ + ip_num &= 0xFFFFFFFF; + /* Get octets */ + r = snprintf (result, len, "%u.%u.%u.%u", + (uint32_t) ip_num & 0x000000FF, (uint32_t) (ip_num & 0x0000FF00) >> 8, (uint32_t) (ip_num & 0x00FF0000) >> 16, (uint32_t) (ip_num & 0xFF000000) >> 24); + if (append_suffix) { + r += snprintf (result + r, len - r, ".%s", suffix->suffix); + } + *host_end = result + r - slen - 1; + g_free (ip); + g_match_info_free (info); + return result; + } + g_match_info_free (info); + } + /* Try to match normal domain */ + if (g_regex_match_full (surbl_module_ctx->extract_normal_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { + gchar *part1, *part2; + part1 = g_match_info_fetch (info, 1); + part2 = g_match_info_fetch (info, 2); + g_match_info_free (info); + result = memory_pool_alloc (pool, len); + r = snprintf (result, len, "%s.%s", part1, part2); + if (g_hash_table_lookup (surbl_module_ctx->tld2, result) != NULL) { + /* Match additional part for hosters */ + g_free (part1); + g_free (part2); + if (g_regex_match_full (surbl_module_ctx->extract_hoster_regexp, hostname->begin, hostname->len, 0, 0, &info, NULL) == TRUE) { + gchar *hpart1, *hpart2, *hpart3; + hpart1 = g_match_info_fetch (info, 1); + hpart2 = g_match_info_fetch (info, 2); + hpart3 = g_match_info_fetch (info, 3); + msg_debug ("format_surbl_request: got hoster 3-d level domain %s.%s.%s", hpart1, hpart2, hpart3); + r = snprintf (result, len, "%s.%s.%s", hpart1, hpart2, hpart3); + if (g_hash_table_lookup (surbl_module_ctx->whitelist, result) != NULL) { + g_free (hpart1); + g_free (hpart2); + g_free (hpart3); + g_match_info_free (info); + msg_debug ("format_surbl_request: url %s is whitelisted", result); + g_set_error (err, SURBL_ERROR, /* error domain */ + WHITELIST_ERROR, /* error code */ + "URL is whitelisted: %s", /* error message format string */ + result); + return NULL; + } + if (append_suffix) { + r += snprintf (result + r, len - r, ".%s", suffix->suffix); + } + *host_end = result + r - slen - 1; + g_free (hpart1); + g_free (hpart2); + g_free (hpart3); + g_match_info_free (info); + return result; + } + g_match_info_free (info); + *host_end = NULL; + return NULL; + } + else { + if (g_hash_table_lookup (surbl_module_ctx->whitelist, result) != NULL) { + g_free (part1); + g_free (part2); + msg_debug ("format_surbl_request: url %s is whitelisted", result); + g_set_error (err, SURBL_ERROR, /* error domain */ + WHITELIST_ERROR, /* error code */ + "URL is whitelisted: %s", /* error message format string */ + result); + return NULL; + } + if (append_suffix) { + r += snprintf (result + r, len - r, ".%s", suffix->suffix); + } + *host_end = result + r - slen - 1; + msg_debug ("format_surbl_request: got normal 2-d level domain %s.%s", part1, part2); + } + g_free (part1); + g_free (part2); + return result; + } + + g_match_info_free (info); + *host_end = NULL; + return NULL; } -static void -make_surbl_requests (struct uri* url, struct worker_task *task, GTree *tree, struct suffix_item *suffix) -{ - char *surbl_req; - f_str_t f; - GError *err = NULL; - struct dns_param *param; - char *host_end; - - f.begin = url->host; - f.len = url->hostlen; - - if (check_view (task->cfg->views, suffix->symbol, task)) { - if ((surbl_req = format_surbl_request (task->task_pool, &f, suffix, &host_end, TRUE, &err)) != NULL) { - if (g_tree_lookup (tree, surbl_req) == NULL) { - g_tree_insert (tree, surbl_req, surbl_req); - param = memory_pool_alloc (task->task_pool, sizeof (struct dns_param)); - param->url = url; - param->task = task; - param->suffix = suffix; - *host_end = '\0'; - param->host_resolve = memory_pool_strdup (task->task_pool, surbl_req); - *host_end = '.'; - msg_debug ("surbl_test_url: send surbl dns request %s", surbl_req); - if (evdns_resolve_ipv4 (surbl_req, DNS_QUERY_NO_SEARCH, dns_callback, (void *)param) == 0) { - param->task->save.saved ++; - register_async_event (task->s, (event_finalizer_t)dns_callback, NULL, TRUE); - } - } - else { - msg_debug ("make_surbl_requests: request %s is already sent", surbl_req); - } - } - else if (err != NULL && err->code != WHITELIST_ERROR) { - msg_info ("surbl_test_url: cannot format url string for surbl %s, %s", struri (url), err->message); - g_error_free (err); - return; - } - else if (err != NULL) { - g_error_free (err); - } - } - else { - msg_debug ("make_surbl_requests: skipping symbol that is not in view: %s", suffix->symbol); - } +static void +make_surbl_requests (struct uri *url, struct worker_task *task, GTree * tree, struct suffix_item *suffix) +{ + char *surbl_req; + f_str_t f; + GError *err = NULL; + struct dns_param *param; + char *host_end; + + f.begin = url->host; + f.len = url->hostlen; + + if (check_view (task->cfg->views, suffix->symbol, task)) { + if ((surbl_req = format_surbl_request (task->task_pool, &f, suffix, &host_end, TRUE, &err)) != NULL) { + if (g_tree_lookup (tree, surbl_req) == NULL) { + g_tree_insert (tree, surbl_req, surbl_req); + param = memory_pool_alloc (task->task_pool, sizeof (struct dns_param)); + param->url = url; + param->task = task; + param->suffix = suffix; + *host_end = '\0'; + param->host_resolve = memory_pool_strdup (task->task_pool, surbl_req); + *host_end = '.'; + msg_debug ("surbl_test_url: send surbl dns request %s", surbl_req); + if (evdns_resolve_ipv4 (surbl_req, DNS_QUERY_NO_SEARCH, dns_callback, (void *)param) == 0) { + param->task->save.saved++; + register_async_event (task->s, (event_finalizer_t) dns_callback, NULL, TRUE); + } + } + else { + msg_debug ("make_surbl_requests: request %s is already sent", surbl_req); + } + } + else if (err != NULL && err->code != WHITELIST_ERROR) { + msg_info ("surbl_test_url: cannot format url string for surbl %s, %s", struri (url), err->message); + g_error_free (err); + return; + } + else if (err != NULL) { + g_error_free (err); + } + } + else { + msg_debug ("make_surbl_requests: skipping symbol that is not in view: %s", suffix->symbol); + } } static void process_dns_results (struct worker_task *task, struct suffix_item *suffix, char *url, uint32_t addr) { - char *c, *symbol; - GList *cur; - struct surbl_bit_item *bit; - int len, found = 0; - - if ((c = strchr (suffix->symbol, '%')) != NULL && *(c + 1) == 'b') { - cur = g_list_first (surbl_module_ctx->bits); - - while (cur) { - bit = (struct surbl_bit_item *)cur->data; - msg_debug ("process_dns_results: got result(%d) AND bit(%d): %d", (int)addr, (int)ntohl(bit->bit), - (int)bit->bit & (int)ntohl (addr)); - if (((int)bit->bit & (int)ntohl (addr)) != 0) { - len = strlen (suffix->symbol) - 2 + strlen (bit->symbol) + 1; - *c = '\0'; - symbol = memory_pool_alloc (task->task_pool, len); - snprintf (symbol, len, "%s%s%s", suffix->symbol, bit->symbol, c + 2); - *c = '%'; - insert_result (task, surbl_module_ctx->metric, symbol, 1, - g_list_prepend (NULL, memory_pool_strdup (task->task_pool, url))); - found = 1; - } - cur = g_list_next (cur); - } - - if (!found) { - insert_result (task, surbl_module_ctx->metric, suffix->symbol, 1, - g_list_prepend (NULL, memory_pool_strdup (task->task_pool, url))); - } - } - else { - insert_result (task, surbl_module_ctx->metric, suffix->symbol, 1, - g_list_prepend (NULL, memory_pool_strdup (task->task_pool, url))); - } + char *c, *symbol; + GList *cur; + struct surbl_bit_item *bit; + int len, found = 0; + + if ((c = strchr (suffix->symbol, '%')) != NULL && *(c + 1) == 'b') { + cur = g_list_first (surbl_module_ctx->bits); + + while (cur) { + bit = (struct surbl_bit_item *)cur->data; + msg_debug ("process_dns_results: got result(%d) AND bit(%d): %d", (int)addr, (int)ntohl (bit->bit), (int)bit->bit & (int)ntohl (addr)); + if (((int)bit->bit & (int)ntohl (addr)) != 0) { + len = strlen (suffix->symbol) - 2 + strlen (bit->symbol) + 1; + *c = '\0'; + symbol = memory_pool_alloc (task->task_pool, len); + snprintf (symbol, len, "%s%s%s", suffix->symbol, bit->symbol, c + 2); + *c = '%'; + insert_result (task, surbl_module_ctx->metric, symbol, 1, g_list_prepend (NULL, memory_pool_strdup (task->task_pool, url))); + found = 1; + } + cur = g_list_next (cur); + } + + if (!found) { + insert_result (task, surbl_module_ctx->metric, suffix->symbol, 1, g_list_prepend (NULL, memory_pool_strdup (task->task_pool, url))); + } + } + else { + insert_result (task, surbl_module_ctx->metric, suffix->symbol, 1, g_list_prepend (NULL, memory_pool_strdup (task->task_pool, url))); + } } -static void +static void dns_callback (int result, char type, int count, int ttl, void *addresses, void *data) { - struct dns_param *param = (struct dns_param *)data; - - msg_debug ("dns_callback: in surbl request callback"); - /* If we have result from DNS server, this url exists in SURBL, so increase score */ - if (result == DNS_ERR_NONE && type == DNS_IPv4_A) { - msg_info ("surbl_check: <%s> domain [%s] is in surbl %s", - param->task->message_id, param->host_resolve, param->suffix->suffix); - process_dns_results (param->task, param->suffix, param->host_resolve, (uint32_t)(((in_addr_t *)addresses)[0])); - } - else { - msg_debug ("surbl_check: <%s> domain [%s] is not in surbl %s", - param->task->message_id, param->host_resolve, param->suffix->suffix); - } - - param->task->save.saved --; - if (param->task->save.saved == 0) { - /* Call other filters */ - param->task->save.saved = 1; - process_filters (param->task); - } - remove_forced_event (param->task->s, (event_finalizer_t)dns_callback); + struct dns_param *param = (struct dns_param *)data; + + msg_debug ("dns_callback: in surbl request callback"); + /* If we have result from DNS server, this url exists in SURBL, so increase score */ + if (result == DNS_ERR_NONE && type == DNS_IPv4_A) { + msg_info ("surbl_check: <%s> domain [%s] is in surbl %s", param->task->message_id, param->host_resolve, param->suffix->suffix); + process_dns_results (param->task, param->suffix, param->host_resolve, (uint32_t) (((in_addr_t *) addresses)[0])); + } + else { + msg_debug ("surbl_check: <%s> domain [%s] is not in surbl %s", param->task->message_id, param->host_resolve, param->suffix->suffix); + } + + param->task->save.saved--; + if (param->task->save.saved == 0) { + /* Call other filters */ + param->task->save.saved = 1; + process_filters (param->task); + } + remove_forced_event (param->task->s, (event_finalizer_t) dns_callback); } -static void -memcached_callback (memcached_ctx_t *ctx, memc_error_t error, void *data) +static void +memcached_callback (memcached_ctx_t * ctx, memc_error_t error, void *data) { - struct memcached_param *param = (struct memcached_param *)data; - int *url_count; - - switch (ctx->op) { - case CMD_CONNECT: - if (error != OK) { - msg_info ("memcached_callback: memcached returned error %s on CONNECT stage", memc_strerror (error)); - memc_close_ctx (param->ctx); - param->task->save.saved --; - if (param->task->save.saved == 0) { - /* Call other filters */ - param->task->save.saved = 1; - process_filters (param->task); - } - } - else { - memc_get (param->ctx, param->ctx->param); - } - break; - case CMD_READ: - if (error != OK) { - msg_info ("memcached_callback: memcached returned error %s on READ stage", memc_strerror (error)); - memc_close_ctx (param->ctx); - param->task->save.saved --; - if (param->task->save.saved == 0) { - /* Call other filters */ - param->task->save.saved = 1; - process_filters (param->task); - } - } - else { - url_count = (int *)param->ctx->param->buf; - /* Do not check DNS for urls that have count more than max_urls */ - if (*url_count > surbl_module_ctx->max_urls) { - msg_info ("memcached_callback: url '%s' has count %d, max: %d", struri (param->url), *url_count, surbl_module_ctx->max_urls); - /* - * XXX: try to understand why we should use memcached here - * insert_result (param->task, surbl_module_ctx->metric, surbl_module_ctx->symbol, 1); - */ - } - (*url_count) ++; - memc_set (param->ctx, param->ctx->param, surbl_module_ctx->url_expire); - } - break; - case CMD_WRITE: - if (error != OK) { - msg_info ("memcached_callback: memcached returned error %s on WRITE stage", memc_strerror (error)); - } - memc_close_ctx (param->ctx); - param->task->save.saved --; - if (param->task->save.saved == 0) { - /* Call other filters */ - param->task->save.saved = 1; - process_filters (param->task); - } - make_surbl_requests (param->url, param->task, param->tree, param->suffix); - break; - default: - return; - } + struct memcached_param *param = (struct memcached_param *)data; + int *url_count; + + switch (ctx->op) { + case CMD_CONNECT: + if (error != OK) { + msg_info ("memcached_callback: memcached returned error %s on CONNECT stage", memc_strerror (error)); + memc_close_ctx (param->ctx); + param->task->save.saved--; + if (param->task->save.saved == 0) { + /* Call other filters */ + param->task->save.saved = 1; + process_filters (param->task); + } + } + else { + memc_get (param->ctx, param->ctx->param); + } + break; + case CMD_READ: + if (error != OK) { + msg_info ("memcached_callback: memcached returned error %s on READ stage", memc_strerror (error)); + memc_close_ctx (param->ctx); + param->task->save.saved--; + if (param->task->save.saved == 0) { + /* Call other filters */ + param->task->save.saved = 1; + process_filters (param->task); + } + } + else { + url_count = (int *)param->ctx->param->buf; + /* Do not check DNS for urls that have count more than max_urls */ + if (*url_count > surbl_module_ctx->max_urls) { + msg_info ("memcached_callback: url '%s' has count %d, max: %d", struri (param->url), *url_count, surbl_module_ctx->max_urls); + /* + * XXX: try to understand why we should use memcached here + * insert_result (param->task, surbl_module_ctx->metric, surbl_module_ctx->symbol, 1); + */ + } + (*url_count)++; + memc_set (param->ctx, param->ctx->param, surbl_module_ctx->url_expire); + } + break; + case CMD_WRITE: + if (error != OK) { + msg_info ("memcached_callback: memcached returned error %s on WRITE stage", memc_strerror (error)); + } + memc_close_ctx (param->ctx); + param->task->save.saved--; + if (param->task->save.saved == 0) { + /* Call other filters */ + param->task->save.saved = 1; + process_filters (param->task); + } + make_surbl_requests (param->url, param->task, param->tree, param->suffix); + break; + default: + return; + } } static void -register_memcached_call (struct uri *url, struct worker_task *task, GTree *url_tree, struct suffix_item *suffix) +register_memcached_call (struct uri *url, struct worker_task *task, GTree * url_tree, struct suffix_item *suffix) { - struct memcached_param *param; - struct memcached_server *selected; - memcached_param_t *cur_param; - gchar *sum_str; - int *url_count; - - param = memory_pool_alloc (task->task_pool, sizeof (struct memcached_param)); - cur_param = memory_pool_alloc0 (task->task_pool, sizeof (memcached_param_t)); - url_count = memory_pool_alloc (task->task_pool, sizeof (int)); - - param->url = url; - param->task = task; - param->tree = url_tree; - param->suffix = suffix; - - param->ctx = memory_pool_alloc0 (task->task_pool, sizeof (memcached_ctx_t)); - - cur_param->buf = (u_char *)url_count; - cur_param->bufsize = sizeof (int); - - sum_str = g_compute_checksum_for_string (G_CHECKSUM_MD5, struri (url), -1); - g_strlcpy (cur_param->key, sum_str, sizeof (cur_param->key)); - g_free (sum_str); - - selected = (struct memcached_server *) get_upstream_by_hash ((void *)task->cfg->memcached_servers, - task->cfg->memcached_servers_num, sizeof (struct memcached_server), - time (NULL), task->cfg->memcached_error_time, task->cfg->memcached_dead_time, task->cfg->memcached_maxerrors, - cur_param->key, strlen(cur_param->key)); - if (selected == NULL) { - msg_err ("surbl_register_memcached_call: no memcached servers can be selected"); - return; - } - param->ctx->callback = memcached_callback; - param->ctx->callback_data = (void *)param; - param->ctx->protocol = task->cfg->memcached_protocol; - memcpy(¶m->ctx->addr, &selected->addr, sizeof (struct in_addr)); - param->ctx->port = selected->port; - param->ctx->timeout.tv_sec = task->cfg->memcached_connect_timeout / 1000; - param->ctx->timeout.tv_sec = task->cfg->memcached_connect_timeout - param->ctx->timeout.tv_sec * 1000; - param->ctx->sock = -1; + struct memcached_param *param; + struct memcached_server *selected; + memcached_param_t *cur_param; + gchar *sum_str; + int *url_count; + + param = memory_pool_alloc (task->task_pool, sizeof (struct memcached_param)); + cur_param = memory_pool_alloc0 (task->task_pool, sizeof (memcached_param_t)); + url_count = memory_pool_alloc (task->task_pool, sizeof (int)); + + param->url = url; + param->task = task; + param->tree = url_tree; + param->suffix = suffix; + + param->ctx = memory_pool_alloc0 (task->task_pool, sizeof (memcached_ctx_t)); + + cur_param->buf = (u_char *) url_count; + cur_param->bufsize = sizeof (int); + + sum_str = g_compute_checksum_for_string (G_CHECKSUM_MD5, struri (url), -1); + g_strlcpy (cur_param->key, sum_str, sizeof (cur_param->key)); + g_free (sum_str); + + selected = (struct memcached_server *)get_upstream_by_hash ((void *)task->cfg->memcached_servers, + task->cfg->memcached_servers_num, sizeof (struct memcached_server), + time (NULL), task->cfg->memcached_error_time, task->cfg->memcached_dead_time, task->cfg->memcached_maxerrors, cur_param->key, strlen (cur_param->key)); + if (selected == NULL) { + msg_err ("surbl_register_memcached_call: no memcached servers can be selected"); + return; + } + param->ctx->callback = memcached_callback; + param->ctx->callback_data = (void *)param; + param->ctx->protocol = task->cfg->memcached_protocol; + memcpy (¶m->ctx->addr, &selected->addr, sizeof (struct in_addr)); + param->ctx->port = selected->port; + param->ctx->timeout.tv_sec = task->cfg->memcached_connect_timeout / 1000; + param->ctx->timeout.tv_sec = task->cfg->memcached_connect_timeout - param->ctx->timeout.tv_sec * 1000; + param->ctx->sock = -1; #ifdef WITH_DEBUG - param->ctx->options = MEMC_OPT_DEBUG; + param->ctx->options = MEMC_OPT_DEBUG; #else - param->ctx->options = 0; + param->ctx->options = 0; #endif - param->ctx->param = cur_param; - memc_init_ctx (param->ctx); + param->ctx->param = cur_param; + memc_init_ctx (param->ctx); } static void free_redirector_session (void *ud) { - struct redirector_param *param = (struct redirector_param *)ud; + struct redirector_param *param = (struct redirector_param *)ud; event_del (¶m->ev); close (param->sock); - param->task->save.saved --; + param->task->save.saved--; make_surbl_requests (param->url, param->task, param->tree, param->suffix); if (param->task->save.saved == 0) { /* Call other filters */ param->task->save.saved = 1; process_filters (param->task); } - + } static void redirector_callback (int fd, short what, void *arg) { - struct redirector_param *param = (struct redirector_param *)arg; - char url_buf[1024]; - int r; - struct timeval *timeout; - char *p, *c; - - switch (param->state) { - case STATE_CONNECT: - /* We have write readiness after connect call, so reinit event */ - if (what == EV_WRITE) { - timeout = memory_pool_alloc (param->task->task_pool, sizeof (struct timeval)); - timeout->tv_sec = surbl_module_ctx->read_timeout / 1000; - timeout->tv_usec = surbl_module_ctx->read_timeout - timeout->tv_sec * 1000; - event_del (¶m->ev); - event_set (¶m->ev, param->sock, EV_READ | EV_PERSIST, redirector_callback, (void *)param); - event_add (¶m->ev, timeout); - r = snprintf (url_buf, sizeof (url_buf), "GET %s HTTP/1.0\r\n\r\n", struri (param->url)); - if (write (param->sock, url_buf, r) == -1) { - msg_err ("redirector_callback: write failed %s", strerror (errno)); - remove_normal_event (param->task->s, free_redirector_session, param); - return; - } - param->state = STATE_READ; - } - else { - msg_info ("redirector_callback: <%s> connection to redirector timed out while waiting for write", - param->task->message_id); + struct redirector_param *param = (struct redirector_param *)arg; + char url_buf[1024]; + int r; + struct timeval *timeout; + char *p, *c; + + switch (param->state) { + case STATE_CONNECT: + /* We have write readiness after connect call, so reinit event */ + if (what == EV_WRITE) { + timeout = memory_pool_alloc (param->task->task_pool, sizeof (struct timeval)); + timeout->tv_sec = surbl_module_ctx->read_timeout / 1000; + timeout->tv_usec = surbl_module_ctx->read_timeout - timeout->tv_sec * 1000; + event_del (¶m->ev); + event_set (¶m->ev, param->sock, EV_READ | EV_PERSIST, redirector_callback, (void *)param); + event_add (¶m->ev, timeout); + r = snprintf (url_buf, sizeof (url_buf), "GET %s HTTP/1.0\r\n\r\n", struri (param->url)); + if (write (param->sock, url_buf, r) == -1) { + msg_err ("redirector_callback: write failed %s", strerror (errno)); remove_normal_event (param->task->s, free_redirector_session, param); return; - } - break; - case STATE_READ: - if (what == EV_READ) { - r = read (param->sock, url_buf, sizeof (url_buf)); - if ((p = strstr (url_buf, "Uri: ")) != NULL) { - p += sizeof ("Uri: ") - 1; - c = p; - while (p++ < url_buf + sizeof (url_buf) - 1) { - if (*p == '\r' || *p == '\n') { - *p = '\0'; - break; - } - } - if (*p == '\0') { - msg_debug ("redirector_callback: <%s> got reply from redirector: '%s' -> '%s'", - param->task->message_id, struri (param->url), c); - parse_uri (param->url, memory_pool_strdup (param->task->task_pool, c), param->task->task_pool); - } - } - remove_normal_event (param->task->s, free_redirector_session, param); - } - else { - msg_info ("redirector_callback: <%s> reading redirector timed out, while waiting for read", - param->task->message_id); - remove_normal_event (param->task->s, free_redirector_session, param); - } - break; - } + } + param->state = STATE_READ; + } + else { + msg_info ("redirector_callback: <%s> connection to redirector timed out while waiting for write", param->task->message_id); + remove_normal_event (param->task->s, free_redirector_session, param); + return; + } + break; + case STATE_READ: + if (what == EV_READ) { + r = read (param->sock, url_buf, sizeof (url_buf)); + if ((p = strstr (url_buf, "Uri: ")) != NULL) { + p += sizeof ("Uri: ") - 1; + c = p; + while (p++ < url_buf + sizeof (url_buf) - 1) { + if (*p == '\r' || *p == '\n') { + *p = '\0'; + break; + } + } + if (*p == '\0') { + msg_debug ("redirector_callback: <%s> got reply from redirector: '%s' -> '%s'", param->task->message_id, struri (param->url), c); + parse_uri (param->url, memory_pool_strdup (param->task->task_pool, c), param->task->task_pool); + } + } + remove_normal_event (param->task->s, free_redirector_session, param); + } + else { + msg_info ("redirector_callback: <%s> reading redirector timed out, while waiting for read", param->task->message_id); + remove_normal_event (param->task->s, free_redirector_session, param); + } + break; + } } static void -register_redirector_call (struct uri *url, struct worker_task *task, GTree *url_tree, struct suffix_item *suffix) +register_redirector_call (struct uri *url, struct worker_task *task, GTree * url_tree, struct suffix_item *suffix) { - int s; - struct redirector_param *param; - struct timeval *timeout; - - s = make_tcp_socket (&surbl_module_ctx->redirector_addr, surbl_module_ctx->redirector_port, FALSE, TRUE); - - if (s == -1) { - msg_info ("register_redirector_call: <%s> cannot create tcp socket failed: %s", - task->message_id, strerror (errno)); - task->save.saved --; - make_surbl_requests (url, task, url_tree, suffix); - return; - } - - param = memory_pool_alloc (task->task_pool, sizeof (struct redirector_param)); - param->url = url; - param->task = task; - param->state = STATE_CONNECT; - param->sock = s; - param->tree = url_tree; - param->suffix = suffix; - timeout = memory_pool_alloc (task->task_pool, sizeof (struct timeval)); - timeout->tv_sec = surbl_module_ctx->connect_timeout / 1000; - timeout->tv_usec = surbl_module_ctx->connect_timeout - timeout->tv_sec * 1000; - event_set (¶m->ev, s, EV_WRITE, redirector_callback, (void *)param); - event_add (¶m->ev, timeout); + int s; + struct redirector_param *param; + struct timeval *timeout; + + s = make_tcp_socket (&surbl_module_ctx->redirector_addr, surbl_module_ctx->redirector_port, FALSE, TRUE); + + if (s == -1) { + msg_info ("register_redirector_call: <%s> cannot create tcp socket failed: %s", task->message_id, strerror (errno)); + task->save.saved--; + make_surbl_requests (url, task, url_tree, suffix); + return; + } + + param = memory_pool_alloc (task->task_pool, sizeof (struct redirector_param)); + param->url = url; + param->task = task; + param->state = STATE_CONNECT; + param->sock = s; + param->tree = url_tree; + param->suffix = suffix; + timeout = memory_pool_alloc (task->task_pool, sizeof (struct timeval)); + timeout->tv_sec = surbl_module_ctx->connect_timeout / 1000; + timeout->tv_usec = surbl_module_ctx->connect_timeout - timeout->tv_sec * 1000; + event_set (¶m->ev, s, EV_WRITE, redirector_callback, (void *)param); + event_add (¶m->ev, timeout); register_async_event (task->s, free_redirector_session, param, FALSE); } -static gboolean +static gboolean tree_url_callback (gpointer key, gpointer value, void *data) { - struct redirector_param *param = data; - struct uri *url = value; - f_str_t f; - char *urlstr, *host_end; - GError *err = NULL; - - msg_debug ("surbl_test_url: check url %s", struri (url)); - - - if (surbl_module_ctx->use_redirector) { - f.begin = url->host; - f.len = url->hostlen; - if ((urlstr = format_surbl_request (param->task->task_pool, &f, NULL, &host_end, FALSE, &err)) != NULL) { - if (g_hash_table_lookup (surbl_module_ctx->redirector_hosts, urlstr) != NULL) { - register_redirector_call (url, param->task, param->tree, param->suffix); - param->task->save.saved++; - return FALSE; - } - } - make_surbl_requests (url, param->task, param->tree, param->suffix); - } - else { - if (param->task->worker->srv->cfg->memcached_servers_num > 0) { - register_memcached_call (url, param->task, param->tree, param->suffix); - param->task->save.saved++; - } - else { - make_surbl_requests (url, param->task, param->tree, param->suffix); - } - } - - return FALSE; + struct redirector_param *param = data; + struct uri *url = value; + f_str_t f; + char *urlstr, *host_end; + GError *err = NULL; + + msg_debug ("surbl_test_url: check url %s", struri (url)); + + + if (surbl_module_ctx->use_redirector) { + f.begin = url->host; + f.len = url->hostlen; + if ((urlstr = format_surbl_request (param->task->task_pool, &f, NULL, &host_end, FALSE, &err)) != NULL) { + if (g_hash_table_lookup (surbl_module_ctx->redirector_hosts, urlstr) != NULL) { + register_redirector_call (url, param->task, param->tree, param->suffix); + param->task->save.saved++; + return FALSE; + } + } + make_surbl_requests (url, param->task, param->tree, param->suffix); + } + else { + if (param->task->worker->srv->cfg->memcached_servers_num > 0) { + register_memcached_call (url, param->task, param->tree, param->suffix); + param->task->save.saved++; + } + else { + make_surbl_requests (url, param->task, param->tree, param->suffix); + } + } + + return FALSE; } static void surbl_test_url (struct worker_task *task, void *user_data) { - GTree *url_tree; - GList *cur; - struct mime_text_part *part; - struct redirector_param param; - struct suffix_item *suffix = user_data; - - url_tree = g_tree_new ((GCompareFunc)g_ascii_strcasecmp); - - param.tree = url_tree; - param.task = task; - param.suffix = suffix; - cur = task->text_parts; - while (cur) { - part = cur->data; - if (part->urls) { - g_tree_foreach (part->urls, tree_url_callback, ¶m); - } - if (part->html_urls) { - g_tree_foreach (part->html_urls, tree_url_callback, ¶m); - } - - cur = g_list_next (cur); - } - - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_tree_destroy, url_tree); + GTree *url_tree; + GList *cur; + struct mime_text_part *part; + struct redirector_param param; + struct suffix_item *suffix = user_data; + + url_tree = g_tree_new ((GCompareFunc) g_ascii_strcasecmp); + + param.tree = url_tree; + param.task = task; + param.suffix = suffix; + cur = task->text_parts; + while (cur) { + part = cur->data; + if (part->urls) { + g_tree_foreach (part->urls, tree_url_callback, ¶m); + } + if (part->html_urls) { + g_tree_foreach (part->html_urls, tree_url_callback, ¶m); + } + + cur = g_list_next (cur); + } + + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_tree_destroy, url_tree); } static int surbl_filter (struct worker_task *task) { - /* XXX: remove this shit */ - return 0; + /* XXX: remove this shit */ + return 0; } -static int +static int urls_command_handler (struct worker_task *task) { - GList *cur; - char *outbuf, *urlstr; - int r, num = 0, buflen; - struct uri *url; - GError *err = NULL; - GTree *url_tree; - f_str_t f; - char *host_end; - - url_tree = g_tree_new ((GCompareFunc)g_ascii_strcasecmp); - - /* First calculate buffer length */ - cur = g_list_first (task->urls); - buflen = 0; - while (cur) { - url = cur->data; - buflen += strlen (struri (url)) + url->hostlen + sizeof (" <\"\">, ") - 1; - cur = g_list_next (cur); - } - - buflen += sizeof (RSPAMD_REPLY_BANNER " 0 OK" CRLF CRLF "URLs: "); - - outbuf = memory_pool_alloc (task->task_pool, buflen * sizeof (char)); - - r = snprintf (outbuf, buflen, "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK"); - - r += snprintf (outbuf + r, buflen - r - 2, "URLs: "); - - cur = g_list_first (task->urls); - - while (cur) { - num ++; - url = cur->data; - if (g_tree_lookup (url_tree, struri (url)) == NULL) { - g_tree_insert (url_tree, struri (url), url); - f.begin = url->host; - f.len = url->hostlen; - if ((urlstr = format_surbl_request (task->task_pool, &f, NULL, &host_end, FALSE, &err)) != NULL) { - if (g_list_next (cur) != NULL) { - r += snprintf (outbuf + r, buflen - r - 2, "%s <\"%s\">, ", (char *)urlstr, struri (url)); - } - else { - r += snprintf (outbuf + r, buflen - r - 2, "%s <\"%s\">", (char *)urlstr, struri (url)); - } - } - } - cur = g_list_next (cur); - } - - outbuf[r++] = '\r'; outbuf[r++] = '\n'; - - rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, TRUE); - msg_info ("process_message: msg ok, id: <%s>, %d urls extracted", task->message_id, num); - g_tree_destroy (url_tree); - - return 0; + GList *cur; + char *outbuf, *urlstr; + int r, num = 0, buflen; + struct uri *url; + GError *err = NULL; + GTree *url_tree; + f_str_t f; + char *host_end; + + url_tree = g_tree_new ((GCompareFunc) g_ascii_strcasecmp); + + /* First calculate buffer length */ + cur = g_list_first (task->urls); + buflen = 0; + while (cur) { + url = cur->data; + buflen += strlen (struri (url)) + url->hostlen + sizeof (" <\"\">, ") - 1; + cur = g_list_next (cur); + } + + buflen += sizeof (RSPAMD_REPLY_BANNER " 0 OK" CRLF CRLF "URLs: "); + + outbuf = memory_pool_alloc (task->task_pool, buflen * sizeof (char)); + + r = snprintf (outbuf, buflen, "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK"); + + r += snprintf (outbuf + r, buflen - r - 2, "URLs: "); + + cur = g_list_first (task->urls); + + while (cur) { + num++; + url = cur->data; + if (g_tree_lookup (url_tree, struri (url)) == NULL) { + g_tree_insert (url_tree, struri (url), url); + f.begin = url->host; + f.len = url->hostlen; + if ((urlstr = format_surbl_request (task->task_pool, &f, NULL, &host_end, FALSE, &err)) != NULL) { + if (g_list_next (cur) != NULL) { + r += snprintf (outbuf + r, buflen - r - 2, "%s <\"%s\">, ", (char *)urlstr, struri (url)); + } + else { + r += snprintf (outbuf + r, buflen - r - 2, "%s <\"%s\">", (char *)urlstr, struri (url)); + } + } + } + cur = g_list_next (cur); + } + + outbuf[r++] = '\r'; + outbuf[r++] = '\n'; + + rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, TRUE); + msg_info ("process_message: msg ok, id: <%s>, %d urls extracted", task->message_id, num); + g_tree_destroy (url_tree); + + return 0; } diff --git a/src/protocol.c b/src/protocol.c index d6fe07cca..a902cb505 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -55,7 +55,7 @@ #define MSG_CMD_SKIP "skip" /* * Return a confirmation that spamd is alive - */ + */ #define MSG_CMD_PING "ping" /* * Process this message as described above and return modified message @@ -84,13 +84,13 @@ #define USER_HEADER "User" #define DELIVER_TO_HEADER "Deliver-To" -static GList *custom_commands = NULL; +static GList *custom_commands = NULL; -static char * -separate_command (f_str_t *in, char c) +static char * +separate_command (f_str_t * in, char c) { - int r = 0; - char *p = in->begin, *b; + int r = 0; + char *p = in->begin, *b; b = p; while (r < in->len) { @@ -100,19 +100,19 @@ separate_command (f_str_t *in, char c) in->len -= r + 1; return b; } - p ++; - r ++; + p++; + r++; } return NULL; } static int -parse_command (struct worker_task *task, f_str_t *line) +parse_command (struct worker_task *task, f_str_t * line) { - char *token; - struct custom_command *cmd; - GList *cur; + char *token; + struct custom_command *cmd; + GList *cur; token = separate_command (line, ' '); if (line == NULL || token == NULL) { @@ -121,82 +121,82 @@ parse_command (struct worker_task *task, f_str_t *line) } switch (token[0]) { - case 'c': - case 'C': - /* check */ - if (g_ascii_strcasecmp (token + 1, MSG_CMD_CHECK + 1) == 0) { - task->cmd = CMD_CHECK; - } - else { - msg_debug ("parse_command: bad command: %s", token); - return -1; - } - break; - case 's': - case 'S': - /* symbols, skip */ - if (g_ascii_strcasecmp (token + 1, MSG_CMD_SYMBOLS + 1) == 0) { - task->cmd = CMD_SYMBOLS; - } - else if (g_ascii_strcasecmp (token + 1, MSG_CMD_SKIP + 1) == 0) { - task->cmd = CMD_SKIP; - } - else { - msg_debug ("parse_command: bad command: %s", token); - return -1; - } - break; - case 'p': - case 'P': - /* ping, process */ - if (g_ascii_strcasecmp (token + 1, MSG_CMD_PING + 1) == 0) { - task->cmd = CMD_PING; - } - else if (g_ascii_strcasecmp (token + 1, MSG_CMD_PROCESS + 1) == 0) { - task->cmd = CMD_PROCESS; - } - else { - msg_debug ("parse_command: bad command: %s", token); - return -1; - } - break; - case 'r': - case 'R': - /* report, report_ifspam */ - if (g_ascii_strcasecmp (token + 1, MSG_CMD_REPORT + 1) == 0) { - task->cmd = CMD_REPORT; - } - else if (g_ascii_strcasecmp (token + 1, MSG_CMD_REPORT_IFSPAM + 1) == 0) { - task->cmd = CMD_REPORT_IFSPAM; - } - else { - msg_debug ("parse_command: bad command: %s", token); - return -1; - } - break; - default: - cur = custom_commands; - while (cur) { - cmd = cur->data; - if (g_ascii_strcasecmp (token, cmd->name) == 0) { - task->cmd = CMD_OTHER; - task->custom_cmd = cmd; - break; - } - cur = g_list_next (cur); + case 'c': + case 'C': + /* check */ + if (g_ascii_strcasecmp (token + 1, MSG_CMD_CHECK + 1) == 0) { + task->cmd = CMD_CHECK; + } + else { + msg_debug ("parse_command: bad command: %s", token); + return -1; + } + break; + case 's': + case 'S': + /* symbols, skip */ + if (g_ascii_strcasecmp (token + 1, MSG_CMD_SYMBOLS + 1) == 0) { + task->cmd = CMD_SYMBOLS; + } + else if (g_ascii_strcasecmp (token + 1, MSG_CMD_SKIP + 1) == 0) { + task->cmd = CMD_SKIP; + } + else { + msg_debug ("parse_command: bad command: %s", token); + return -1; + } + break; + case 'p': + case 'P': + /* ping, process */ + if (g_ascii_strcasecmp (token + 1, MSG_CMD_PING + 1) == 0) { + task->cmd = CMD_PING; + } + else if (g_ascii_strcasecmp (token + 1, MSG_CMD_PROCESS + 1) == 0) { + task->cmd = CMD_PROCESS; + } + else { + msg_debug ("parse_command: bad command: %s", token); + return -1; + } + break; + case 'r': + case 'R': + /* report, report_ifspam */ + if (g_ascii_strcasecmp (token + 1, MSG_CMD_REPORT + 1) == 0) { + task->cmd = CMD_REPORT; + } + else if (g_ascii_strcasecmp (token + 1, MSG_CMD_REPORT_IFSPAM + 1) == 0) { + task->cmd = CMD_REPORT_IFSPAM; + } + else { + msg_debug ("parse_command: bad command: %s", token); + return -1; + } + break; + default: + cur = custom_commands; + while (cur) { + cmd = cur->data; + if (g_ascii_strcasecmp (token, cmd->name) == 0) { + task->cmd = CMD_OTHER; + task->custom_cmd = cmd; + break; } + cur = g_list_next (cur); + } - if (cur == NULL) { - msg_debug ("parse_command: bad command: %s", token); - return -1; - } - break; + if (cur == NULL) { + msg_debug ("parse_command: bad command: %s", token); + return -1; + } + break; } if (strncasecmp (line->begin, RSPAMC_GREETING, sizeof (RSPAMC_GREETING) - 1) == 0) { task->proto = RSPAMC_PROTO; } - else if (strncasecmp (line->begin, SPAMC_GREETING, sizeof (SPAMC_GREETING) -1) == 0) { + else if (strncasecmp (line->begin, SPAMC_GREETING, sizeof (SPAMC_GREETING) - 1) == 0) { task->proto = SPAMC_PROTO; } else { @@ -207,10 +207,10 @@ parse_command (struct worker_task *task, f_str_t *line) } static int -parse_header (struct worker_task *task, f_str_t *line) +parse_header (struct worker_task *task, f_str_t * line) { - char *headern, *err, *tmp; - + char *headern, *err, *tmp; + /* Check end of headers */ if (line->len == 0) { msg_debug ("parse_header: got empty line, assume it as end of headers"); @@ -219,7 +219,7 @@ parse_header (struct worker_task *task, f_str_t *line) } else { if (task->content_length > 0) { - rspamd_set_dispatcher_policy (task->dispatcher, BUFFER_CHARACTER, task->content_length); + rspamd_set_dispatcher_policy (task->dispatcher, BUFFER_CHARACTER, task->content_length); task->state = READ_MESSAGE; } else { @@ -242,152 +242,152 @@ parse_header (struct worker_task *task, f_str_t *line) fstrstrip (line); switch (headern[0]) { - case 'c': - case 'C': - /* content-length */ - if (strncasecmp (headern, CONTENT_LENGTH_HEADER, sizeof (CONTENT_LENGTH_HEADER) - 1) == 0) { - if (task->content_length == 0) { - tmp = memory_pool_fstrdup (task->task_pool, line); - task->content_length = strtoul (tmp, &err, 10); - msg_debug ("parse_header: read Content-Length header, value: %lu", (unsigned long int)task->content_length); - } - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'd': - case 'D': - /* Deliver-To */ - if (strncasecmp (headern, DELIVER_TO_HEADER, sizeof (DELIVER_TO_HEADER) - 1) == 0) { - task->deliver_to = memory_pool_fstrdup (task->task_pool, line); - msg_debug ("parse_header: read deliver-to header, value: %s", task->deliver_to); - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'h': - case 'H': - /* helo */ - if (strncasecmp (headern, HELO_HEADER, sizeof (HELO_HEADER) - 1) == 0) { - task->helo = memory_pool_fstrdup (task->task_pool, line); - msg_debug ("parse_header: read helo header, value: %s", task->helo); - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'f': - case 'F': - /* from */ - if (strncasecmp (headern, FROM_HEADER, sizeof (FROM_HEADER) - 1) == 0) { - task->from = memory_pool_fstrdup (task->task_pool, line); - msg_debug ("parse_header: read from header, value: %s", task->from); - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'q': - case 'Q': - /* Queue id */ - if (strncasecmp (headern, QUEUE_ID_HEADER, sizeof (QUEUE_ID_HEADER) - 1) == 0) { - task->queue_id = memory_pool_fstrdup (task->task_pool, line); - msg_debug ("parse_header: read queue_id header, value: %s", task->queue_id); - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'r': - case 'R': - /* rcpt */ - if (strncasecmp (headern, RCPT_HEADER, sizeof (RCPT_HEADER) - 1) == 0) { - tmp = memory_pool_fstrdup (task->task_pool, line); - task->rcpt = g_list_prepend (task->rcpt, tmp); - msg_debug ("parse_header: read rcpt header, value: %s", tmp); - } - else if (strncasecmp (headern, NRCPT_HEADER, sizeof (NRCPT_HEADER) - 1) == 0) { - tmp = memory_pool_fstrdup (task->task_pool, line); - task->nrcpt = strtoul (tmp, &err, 10); - msg_debug ("parse_header: read rcpt header, value: %d", (int)task->nrcpt); - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'i': - case 'I': - /* ip_addr */ - if (strncasecmp (headern, IP_ADDR_HEADER, sizeof (IP_ADDR_HEADER) - 1) == 0) { + case 'c': + case 'C': + /* content-length */ + if (strncasecmp (headern, CONTENT_LENGTH_HEADER, sizeof (CONTENT_LENGTH_HEADER) - 1) == 0) { + if (task->content_length == 0) { tmp = memory_pool_fstrdup (task->task_pool, line); - if (!inet_aton (tmp, &task->from_addr)) { - msg_info ("parse_header: bad ip header: '%s'", tmp); - return -1; - } - msg_debug ("parse_header: read IP header, value: %s", tmp); - } - else { - msg_info ("parse_header: wrong header: %s", headern); - return -1; - } - break; - case 'u': - case 'U': - if (strncasecmp (headern, USER_HEADER, sizeof (USER_HEADER) - 1) == 0) { - /* XXX: use this header somehow */ - task->user = memory_pool_fstrdup (task->task_pool, line); + task->content_length = strtoul (tmp, &err, 10); + msg_debug ("parse_header: read Content-Length header, value: %lu", (unsigned long int)task->content_length); } - else { + } + else { + msg_info ("parse_header: wrong header: %s", headern); + return -1; + } + break; + case 'd': + case 'D': + /* Deliver-To */ + if (strncasecmp (headern, DELIVER_TO_HEADER, sizeof (DELIVER_TO_HEADER) - 1) == 0) { + task->deliver_to = memory_pool_fstrdup (task->task_pool, line); + msg_debug ("parse_header: read deliver-to header, value: %s", task->deliver_to); + } + else { + msg_info ("parse_header: wrong header: %s", headern); + return -1; + } + break; + case 'h': + case 'H': + /* helo */ + if (strncasecmp (headern, HELO_HEADER, sizeof (HELO_HEADER) - 1) == 0) { + task->helo = memory_pool_fstrdup (task->task_pool, line); + msg_debug ("parse_header: read helo header, value: %s", task->helo); + } + else { + msg_info ("parse_header: wrong header: %s", headern); + return -1; + } + break; + case 'f': + case 'F': + /* from */ + if (strncasecmp (headern, FROM_HEADER, sizeof (FROM_HEADER) - 1) == 0) { + task->from = memory_pool_fstrdup (task->task_pool, line); + msg_debug ("parse_header: read from header, value: %s", task->from); + } + else { + msg_info ("parse_header: wrong header: %s", headern); + return -1; + } + break; + case 'q': + case 'Q': + /* Queue id */ + if (strncasecmp (headern, QUEUE_ID_HEADER, sizeof (QUEUE_ID_HEADER) - 1) == 0) { + task->queue_id = memory_pool_fstrdup (task->task_pool, line); + msg_debug ("parse_header: read queue_id header, value: %s", task->queue_id); + } + else { + msg_info ("parse_header: wrong header: %s", headern); + return -1; + } + break; + case 'r': + case 'R': + /* rcpt */ + if (strncasecmp (headern, RCPT_HEADER, sizeof (RCPT_HEADER) - 1) == 0) { + tmp = memory_pool_fstrdup (task->task_pool, line); + task->rcpt = g_list_prepend (task->rcpt, tmp); + msg_debug ("parse_header: read rcpt header, value: %s", tmp); + } + else if (strncasecmp (headern, NRCPT_HEADER, sizeof (NRCPT_HEADER) - 1) == 0) { + tmp = memory_pool_fstrdup (task->task_pool, line); + task->nrcpt = strtoul (tmp, &err, 10); + msg_debug ("parse_header: read rcpt header, value: %d", (int)task->nrcpt); + } + else { + msg_info ("parse_header: wrong header: %s", headern); + return -1; + } + break; + case 'i': + case 'I': + /* ip_addr */ + if (strncasecmp (headern, IP_ADDR_HEADER, sizeof (IP_ADDR_HEADER) - 1) == 0) { + tmp = memory_pool_fstrdup (task->task_pool, line); + if (!inet_aton (tmp, &task->from_addr)) { + msg_info ("parse_header: bad ip header: '%s'", tmp); return -1; } - break; - default: + msg_debug ("parse_header: read IP header, value: %s", tmp); + } + else { msg_info ("parse_header: wrong header: %s", headern); return -1; + } + break; + case 'u': + case 'U': + if (strncasecmp (headern, USER_HEADER, sizeof (USER_HEADER) - 1) == 0) { + /* XXX: use this header somehow */ + task->user = memory_pool_fstrdup (task->task_pool, line); + } + else { + return -1; + } + break; + default: + msg_info ("parse_header: wrong header: %s", headern); + return -1; } return 0; } int -read_rspamd_input_line (struct worker_task *task, f_str_t *line) +read_rspamd_input_line (struct worker_task *task, f_str_t * line) { switch (task->state) { - case READ_COMMAND: - return parse_command (task, line); - break; - case READ_HEADER: - return parse_header (task, line); - break; - default: - return -1; + case READ_COMMAND: + return parse_command (task, line); + break; + case READ_HEADER: + return parse_header (task, line); + break; + default: + return -1; } return -1; } struct metric_callback_data { - struct worker_task *task; - char *log_buf; - int log_offset; - int log_size; + struct worker_task *task; + char *log_buf; + int log_offset; + int log_size; }; static void show_url_header (struct worker_task *task) { - int r = 0; - char outbuf[OUTBUFSIZ], c; - struct uri *url; - GList *cur; - f_str_t host; + int r = 0; + char outbuf[OUTBUFSIZ], c; + struct uri *url; + GList *cur; + f_str_t host; r = snprintf (outbuf, sizeof (outbuf), "Urls: "); cur = task->urls; @@ -402,7 +402,9 @@ show_url_header (struct worker_task *task) } /* Do header folding */ if (host.len + r >= OUTBUFSIZ - 3) { - outbuf[r ++] = '\r'; outbuf[r ++] = '\n'; outbuf[r] = ' '; + outbuf[r++] = '\r'; + outbuf[r++] = '\n'; + outbuf[r] = ' '; rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE); r = 0; } @@ -429,12 +431,12 @@ show_url_header (struct worker_task *task) static void metric_symbols_callback (gpointer key, gpointer value, void *user_data) { - struct metric_callback_data *cd = (struct metric_callback_data *)user_data; - struct worker_task *task = cd->task; - int r = 0; - char outbuf[OUTBUFSIZ]; - struct symbol *s = (struct symbol *)value; - GList *cur; + struct metric_callback_data *cd = (struct metric_callback_data *)user_data; + struct worker_task *task = cd->task; + int r = 0; + char outbuf[OUTBUFSIZ]; + struct symbol *s = (struct symbol *)value; + GList *cur; if (s->options) { r = snprintf (outbuf, OUTBUFSIZ, "Symbol: %s; ", (char *)key); @@ -457,8 +459,7 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) else { r = snprintf (outbuf, OUTBUFSIZ, "Symbol: %s" CRLF, (char *)key); } - cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, - "%s,", (char *)key); + cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "%s,", (char *)key); rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); } @@ -466,9 +467,9 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) static void show_metric_symbols (struct metric_result *metric_res, struct metric_callback_data *cd) { - int r = 0; - GList *symbols, *cur; - char outbuf[OUTBUFSIZ]; + int r = 0; + GList *symbols, *cur; + char outbuf[OUTBUFSIZ]; if (cd->task->proto == SPAMC_PROTO) { symbols = g_hash_table_get_keys (metric_res->symbols); @@ -497,15 +498,15 @@ show_metric_symbols (struct metric_result *metric_res, struct metric_callback_da static void show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data) { - struct metric_callback_data *cd = (struct metric_callback_data *)user_data; - struct worker_task *task = cd->task; - int r; - char outbuf[OUTBUFSIZ]; - struct metric_result *metric_res = (struct metric_result *)metric_value; - struct metric *m; - int is_spam = 0; - double ms; - + struct metric_callback_data *cd = (struct metric_callback_data *)user_data; + struct worker_task *task = cd->task; + int r; + char outbuf[OUTBUFSIZ]; + struct metric_result *metric_res = (struct metric_result *)metric_value; + struct metric *m; + int is_spam = 0; + double ms; + if (metric_name == NULL || metric_value == NULL) { m = g_hash_table_lookup (task->cfg->metrics, "default"); @@ -513,15 +514,12 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data ms = m->required_score; } if (task->proto == SPAMC_PROTO) { - r = snprintf (outbuf, sizeof (outbuf), "Spam: False ; 0 / %.2f" CRLF, - m != NULL ? ms : 0); + r = snprintf (outbuf, sizeof (outbuf), "Spam: False ; 0 / %.2f" CRLF, m != NULL ? ms : 0); } else { - r = snprintf (outbuf, sizeof (outbuf), "Metric: default; False; 0 / %.2f" CRLF, - m != NULL ? ms : 0); + r = snprintf (outbuf, sizeof (outbuf), "Metric: default; False; 0 / %.2f" CRLF, m != NULL ? ms : 0); } - cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, - "(%s: F: [0/%.2f] [", "default", m != NULL ? ms : 0); + cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "(%s: F: [0/%.2f] [", "default", m != NULL ? ms : 0); } else { if (!check_metric_settings (task, metric_res->metric, &ms)) { @@ -531,16 +529,12 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data is_spam = 1; } if (task->proto == SPAMC_PROTO) { - r = snprintf (outbuf, sizeof (outbuf), "Spam: %s ; %.2f / %.2f" CRLF, - (is_spam) ? "True" : "False", metric_res->score, ms); + r = snprintf (outbuf, sizeof (outbuf), "Spam: %s ; %.2f / %.2f" CRLF, (is_spam) ? "True" : "False", metric_res->score, ms); } else { - r = snprintf (outbuf, sizeof (outbuf), "Metric: %s; %s; %.2f / %.2f" CRLF, (char *)metric_name, - (is_spam) ? "True" : "False", metric_res->score, ms); + r = snprintf (outbuf, sizeof (outbuf), "Metric: %s; %s; %.2f / %.2f" CRLF, (char *)metric_name, (is_spam) ? "True" : "False", metric_res->score, ms); } - cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, - "(%s: %s: [%.2f/%.2f] [", (char *)metric_name, is_spam ? "T" : "F", - metric_res->score, ms); + cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "(%s: %s: [%.2f/%.2f] [", (char *)metric_name, is_spam ? "T" : "F", metric_res->score, ms); } if (task->cmd == CMD_PROCESS) { #ifndef GMIME24 @@ -557,16 +551,16 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data } } cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %ld, time: %sms", - (long int)task->msg->len, calculate_check_time (&task->ts, task->cfg->clock_res)); + (long int)task->msg->len, calculate_check_time (&task->ts, task->cfg->clock_res)); } static int write_check_reply (struct worker_task *task) { - int r; - char outbuf[OUTBUFSIZ], logbuf[OUTBUFSIZ]; - struct metric_result *metric_res; - struct metric_callback_data cd; + int r; + char outbuf[OUTBUFSIZ], logbuf[OUTBUFSIZ]; + struct metric_result *metric_res; + struct metric_callback_data cd; r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK"); rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE); @@ -584,7 +578,7 @@ write_check_reply (struct worker_task *task) show_metric_result (NULL, NULL, (void *)&cd); } else { - show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)&cd); + show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd); } } else { @@ -595,7 +589,7 @@ write_check_reply (struct worker_task *task) show_metric_result (NULL, NULL, (void *)&cd); } else { - show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)&cd); + show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd); } g_hash_table_remove (task->results, "default"); @@ -613,14 +607,13 @@ write_check_reply (struct worker_task *task) static int write_process_reply (struct worker_task *task) { - int r; - char *outmsg; - char outbuf[OUTBUFSIZ], logbuf[OUTBUFSIZ]; - struct metric_result *metric_res; - struct metric_callback_data cd; + int r; + char *outmsg; + char outbuf[OUTBUFSIZ], logbuf[OUTBUFSIZ]; + struct metric_result *metric_res; + struct metric_callback_data cd; - r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF "Content-Length: %zd" CRLF CRLF, - (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK", task->msg->len); + r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF "Content-Length: %zd" CRLF CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK", task->msg->len); cd.task = task; cd.log_buf = logbuf; @@ -635,7 +628,7 @@ write_process_reply (struct worker_task *task) show_metric_result (NULL, NULL, (void *)&cd); } else { - show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)&cd); + show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd); } } else { @@ -646,7 +639,7 @@ write_process_reply (struct worker_task *task) show_metric_result (NULL, NULL, (void *)&cd); } else { - show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)&cd); + show_metric_result ((gpointer) "default", (gpointer) metric_res, (void *)&cd); } g_hash_table_remove (task->results, "default"); @@ -661,7 +654,7 @@ write_process_reply (struct worker_task *task) rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE); rspamd_dispatcher_write (task->dispatcher, outmsg, strlen (outmsg), FALSE, TRUE); - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, outmsg); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, outmsg); return 0; } @@ -669,8 +662,8 @@ write_process_reply (struct worker_task *task) int write_reply (struct worker_task *task) { - int r; - char outbuf[OUTBUFSIZ]; + int r; + char outbuf[OUTBUFSIZ]; msg_debug ("write_reply: writing reply to client"); if (task->error_code != 0) { @@ -680,8 +673,7 @@ write_reply (struct worker_task *task) msg_debug ("write_reply: writing error: %s", outbuf); } else { - r = snprintf (outbuf, sizeof (outbuf), "%s %d %s" CRLF "%s: %s" CRLF CRLF, RSPAMD_REPLY_BANNER, task->error_code, - SPAMD_ERROR, ERROR_HEADER, task->last_error); + r = snprintf (outbuf, sizeof (outbuf), "%s %d %s" CRLF "%s: %s" CRLF CRLF, RSPAMD_REPLY_BANNER, task->error_code, SPAMD_ERROR, ERROR_HEADER, task->last_error); msg_debug ("write_reply: writing error: %s", outbuf); } /* Write to bufferevent error message */ @@ -689,36 +681,35 @@ write_reply (struct worker_task *task) } else { switch (task->cmd) { - case CMD_REPORT_IFSPAM: - case CMD_REPORT: - case CMD_CHECK: - case CMD_SYMBOLS: - return write_check_reply (task); - break; - case CMD_PROCESS: - return write_process_reply (task); - break; - case CMD_SKIP: - r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, - SPAMD_OK); - rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); - break; - case CMD_PING: - r = snprintf (outbuf, sizeof (outbuf), "%s 0 PONG" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER); - rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); - break; - case CMD_OTHER: - return task->custom_cmd->func (task); + case CMD_REPORT_IFSPAM: + case CMD_REPORT: + case CMD_CHECK: + case CMD_SYMBOLS: + return write_check_reply (task); + break; + case CMD_PROCESS: + return write_process_reply (task); + break; + case CMD_SKIP: + r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, SPAMD_OK); + rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); + break; + case CMD_PING: + r = snprintf (outbuf, sizeof (outbuf), "%s 0 PONG" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER); + rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); + break; + case CMD_OTHER: + return task->custom_cmd->func (task); } } return 0; } -void +void register_protocol_command (const char *name, protocol_reply_func func) { - struct custom_command *cmd; + struct custom_command *cmd; cmd = g_malloc (sizeof (struct custom_command)); cmd->name = name; diff --git a/src/radix.c b/src/radix.c index e55e9e5ba..b31e8f0d9 100644 --- a/src/radix.c +++ b/src/radix.c @@ -27,19 +27,19 @@ #include "radix.h" #include "mem_pool.h" -static void *radix_alloc (radix_tree_t *tree); +static void *radix_alloc (radix_tree_t * tree); -radix_tree_t * +radix_tree_t * radix_tree_create () { - radix_tree_t *tree; + radix_tree_t *tree; - tree = g_malloc (sizeof(radix_tree_t)); + tree = g_malloc (sizeof (radix_tree_t)); if (tree == NULL) { return NULL; } - - tree->pool = memory_pool_new (memory_pool_get_size ()); + + tree->pool = memory_pool_new (memory_pool_get_size ()); tree->size = 0; tree->root = radix_alloc (tree); @@ -51,17 +51,16 @@ radix_tree_create () tree->root->left = NULL; tree->root->parent = NULL; tree->root->value = RADIX_NO_VALUE; - + return tree; } int -radix32tree_insert (radix_tree_t *tree, uint32_t key, uint32_t mask, - unsigned char value) +radix32tree_insert (radix_tree_t * tree, uint32_t key, uint32_t mask, unsigned char value) { - uint32_t bit; - radix_node_t *node, *next; + uint32_t bit; + radix_node_t *node, *next; bit = 0x80000000; @@ -72,7 +71,8 @@ radix32tree_insert (radix_tree_t *tree, uint32_t key, uint32_t mask, if (key & bit) { next = node->right; - } else { + } + else { next = node->left; } @@ -94,7 +94,7 @@ radix32tree_insert (radix_tree_t *tree, uint32_t key, uint32_t mask, } /* Inserting value in trie creating all path components */ while (bit & mask) { - next = radix_alloc(tree); + next = radix_alloc (tree); if (next == NULL) { return -1; } @@ -107,7 +107,8 @@ radix32tree_insert (radix_tree_t *tree, uint32_t key, uint32_t mask, if (key & bit) { node->right = next; - } else { + } + else { node->left = next; } @@ -122,11 +123,11 @@ radix32tree_insert (radix_tree_t *tree, uint32_t key, uint32_t mask, int -radix32tree_delete (radix_tree_t *tree, uint32_t key, uint32_t mask) +radix32tree_delete (radix_tree_t * tree, uint32_t key, uint32_t mask) { - uint32_t bit; - radix_node_t *node; - radix_node_t *tmp; + uint32_t bit; + radix_node_t *node; + radix_node_t *tmp; bit = 0x80000000; node = tree->root; @@ -135,7 +136,8 @@ radix32tree_delete (radix_tree_t *tree, uint32_t key, uint32_t mask) if (key & bit) { node = node->right; - } else { + } + else { node = node->left; } @@ -155,11 +157,12 @@ radix32tree_delete (radix_tree_t *tree, uint32_t key, uint32_t mask) return -1; } - for ( ;; ) { + for (;;) { if (node->parent->right == node) { node->parent->right = NULL; - } else { + } + else { node->parent->left = NULL; } @@ -184,11 +187,11 @@ radix32tree_delete (radix_tree_t *tree, uint32_t key, uint32_t mask) unsigned char -radix32tree_find (radix_tree_t *tree, uint32_t key) +radix32tree_find (radix_tree_t * tree, uint32_t key) { - uint32_t bit; - uintptr_t value; - radix_node_t *node; + uint32_t bit; + uintptr_t value; + radix_node_t *node; bit = 0x80000000; value = RADIX_NO_VALUE; @@ -202,7 +205,8 @@ radix32tree_find (radix_tree_t *tree, uint32_t key) if (key & bit) { node = node->right; - } else { + } + else { node = node->left; } @@ -213,12 +217,12 @@ radix32tree_find (radix_tree_t *tree, uint32_t key) } -static void * -radix_alloc (radix_tree_t *tree) +static void * +radix_alloc (radix_tree_t * tree) { - char *p; + char *p; - p = memory_pool_alloc (tree->pool, sizeof(radix_node_t)); + p = memory_pool_alloc (tree->pool, sizeof (radix_node_t)); tree->size += sizeof (radix_node_t); @@ -226,9 +230,9 @@ radix_alloc (radix_tree_t *tree) } void -radix_tree_free (radix_tree_t *tree) +radix_tree_free (radix_tree_t * tree) { - + g_return_if_fail (tree != NULL); memory_pool_delete (tree->pool); g_free (tree); diff --git a/src/settings.c b/src/settings.c index 5ee37d4ed..a4dca10dd 100644 --- a/src/settings.c +++ b/src/settings.c @@ -30,16 +30,16 @@ #include "json/jansson.h" struct json_buf { - GHashTable *table; - u_char *buf; - u_char *pos; - size_t buflen; + GHashTable *table; + u_char *buf; + u_char *pos; + size_t buflen; }; static void settings_free (gpointer data) { - struct rspamd_settings *s = data; + struct rspamd_settings *s = data; if (s->statfile_alias) { g_free (s->statfile_alias); @@ -54,11 +54,11 @@ settings_free (gpointer data) } -u_char* -json_read_cb (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data *data) +u_char * +json_read_cb (memory_pool_t * pool, u_char * chunk, size_t len, struct map_cb_data *data) { - struct json_buf *jb; - size_t free, off; + struct json_buf *jb; + size_t free, off; if (data->cur_data == NULL) { jb = g_malloc (sizeof (struct json_buf)); @@ -89,22 +89,22 @@ json_read_cb (memory_pool_t *pool, u_char *chunk, size_t len, struct map_cb_data memcpy (jb->pos, chunk, len); jb->pos += len; - + /* Say not to copy any part of this buffer */ return NULL; } void -json_fin_cb (memory_pool_t *pool, struct map_cb_data *data) -{ - struct json_buf *jb; - int nelts, i; - json_t *js, *cur_elt, *cur_nm, *it_val; - json_error_t je; - struct rspamd_settings *cur_settings; - char *cur_name; - void *json_it; - double *score; +json_fin_cb (memory_pool_t * pool, struct map_cb_data *data) +{ + struct json_buf *jb; + int nelts, i; + json_t *js, *cur_elt, *cur_nm, *it_val; + json_error_t je; + struct rspamd_settings *cur_settings; + char *cur_name; + void *json_it; + double *score; if (data->prev_data) { jb = data->prev_data; @@ -146,7 +146,7 @@ json_fin_cb (memory_pool_t *pool, struct map_cb_data *data) } nelts = json_array_size (js); - for (i = 0; i < nelts; i ++) { + for (i = 0; i < nelts; i++) { cur_settings = g_malloc (sizeof (struct rspamd_settings)); cur_settings->metric_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); cur_settings->factors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -179,10 +179,9 @@ json_fin_cb (memory_pool_t *pool, struct map_cb_data *data) while (json_it) { it_val = json_object_iter_value (json_it); if (it_val && json_is_string (it_val)) { - g_hash_table_insert (cur_settings->factors, g_strdup (json_object_iter_key (json_it)), - g_strdup (json_string_value (it_val))); + g_hash_table_insert (cur_settings->factors, g_strdup (json_object_iter_key (json_it)), g_strdup (json_string_value (it_val))); } - json_it = json_object_iter_next(cur_nm, json_it); + json_it = json_object_iter_next (cur_nm, json_it); } } /* Metrics object */ @@ -194,10 +193,9 @@ json_fin_cb (memory_pool_t *pool, struct map_cb_data *data) if (it_val && json_is_number (it_val)) { score = g_malloc (sizeof (double)); *score = json_number_value (it_val); - g_hash_table_insert (cur_settings->metric_scores, g_strdup (json_object_iter_key (json_it)), - score); + g_hash_table_insert (cur_settings->metric_scores, g_strdup (json_object_iter_key (json_it)), score); } - json_it = json_object_iter_next(cur_nm, json_it); + json_it = json_object_iter_next (cur_nm, json_it); } } /* Want spam */ @@ -207,18 +205,18 @@ json_fin_cb (memory_pool_t *pool, struct map_cb_data *data) cur_settings->want_spam = TRUE; } } - g_hash_table_insert (((struct json_buf*)data->cur_data)->table, cur_name, cur_settings); + g_hash_table_insert (((struct json_buf *)data->cur_data)->table, cur_name, cur_settings); } json_decref (js); } gboolean -read_settings (const char *path, struct config_file *cfg, GHashTable *table) +read_settings (const char *path, struct config_file *cfg, GHashTable * table) { - struct json_buf *jb = g_malloc (sizeof (struct json_buf)), **pjb; + struct json_buf *jb = g_malloc (sizeof (struct json_buf)), **pjb; pjb = g_malloc (sizeof (struct json_buf *)); - + jb->table = table; jb->buf = NULL; *pjb = jb; @@ -227,7 +225,7 @@ read_settings (const char *path, struct config_file *cfg, GHashTable *table) msg_err ("read_settings: cannot add map %s", path); return FALSE; } - + return TRUE; } @@ -238,10 +236,10 @@ init_settings (struct config_file *cfg) cfg->user_settings = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, settings_free); } -static gboolean +static gboolean check_setting (struct worker_task *task, struct rspamd_settings **user_settings, struct rspamd_settings **domain_settings) { - char *field = NULL, *domain = NULL; + char *field = NULL, *domain = NULL; if (task->deliver_to != NULL) { /* First try to use deliver-to field */ @@ -267,9 +265,9 @@ check_setting (struct worker_task *task, struct rspamd_settings **user_settings, } } if (domain != NULL) { - domain ++; + domain++; } - + /* First try to search per-user settings */ if (field != NULL) { *user_settings = g_hash_table_lookup (task->cfg->user_settings, field); @@ -285,11 +283,11 @@ check_setting (struct worker_task *task, struct rspamd_settings **user_settings, return FALSE; } -gboolean -check_metric_settings (struct worker_task *task, struct metric *metric, double *score) +gboolean +check_metric_settings (struct worker_task * task, struct metric * metric, double *score) { - struct rspamd_settings *us, *ds; - double *sc; + struct rspamd_settings *us, *ds; + double *sc; if (check_setting (task, &us, &ds)) { if (us != NULL) { @@ -311,15 +309,15 @@ check_metric_settings (struct worker_task *task, struct metric *metric, double * } } } - + return FALSE; } -gboolean -check_factor_settings (struct worker_task *task, const char *symbol, double *factor) +gboolean +check_factor_settings (struct worker_task * task, const char *symbol, double *factor) { - struct rspamd_settings *us, *ds; - double *fc; + struct rspamd_settings *us, *ds; + double *fc; if (check_setting (task, &us, &ds)) { if (us != NULL) { @@ -341,16 +339,16 @@ check_factor_settings (struct worker_task *task, const char *symbol, double *fac } } } - + return FALSE; } -gboolean -check_want_spam (struct worker_task *task) +gboolean +check_want_spam (struct worker_task * task) { - struct rspamd_settings *us, *ds; + struct rspamd_settings *us, *ds; if (check_setting (task, &us, &ds)) { if (us != NULL) { @@ -369,7 +367,7 @@ check_want_spam (struct worker_task *task) } } } - + return FALSE; } diff --git a/src/statfile.c b/src/statfile.c index 29368ae6d..697f54e4c 100644 --- a/src/statfile.c +++ b/src/statfile.c @@ -33,17 +33,17 @@ static int cmpstatfile (const void *a, const void *b) { - const stat_file_t *s1 = a, *s2 = b; + const stat_file_t *s1 = a, *s2 = b; return g_ascii_strcasecmp (s1->filename, s2->filename); } /* Check whether specified file is statistic file and calculate its len in blocks */ static int -statfile_pool_check (stat_file_t *file) +statfile_pool_check (stat_file_t * file) { - struct stat_file *f; - char *c; + struct stat_file *f; + char *c; if (!file || !file->map) { return -1; @@ -66,30 +66,29 @@ statfile_pool_check (stat_file_t *file) /* Check first section and set new offset */ file->cur_section.code = f->section.code; file->cur_section.length = f->section.length; - if (file->cur_section.length * sizeof (struct stat_file_block) > file->len) { - msg_info ("statfile_pool_check: file %s is truncated: %zd, must be %zd", file->filename, - file->len, file->cur_section.length * sizeof (struct stat_file_block)); + if (file->cur_section.length * sizeof (struct stat_file_block) > file->len) { + msg_info ("statfile_pool_check: file %s is truncated: %zd, must be %zd", file->filename, file->len, file->cur_section.length * sizeof (struct stat_file_block)); return -1; - } + } file->seek_pos = sizeof (struct stat_file) - sizeof (struct stat_file_block); - + return 0; } struct expiration_data { - statfile_pool_t *pool; - uint64_t oldest; - char *filename; + statfile_pool_t *pool; + uint64_t oldest; + char *filename; }; static int -statfile_pool_expire (statfile_pool_t *pool) +statfile_pool_expire (statfile_pool_t * pool) { - struct expiration_data exp; - stat_file_t *file; - int i; + struct expiration_data exp; + stat_file_t *file; + int i; if (pool->opened == 0) { return -1; @@ -101,7 +100,7 @@ statfile_pool_expire (statfile_pool_t *pool) for (i = 0; i < pool->opened; i++) { file = &pool->files[i]; - if ((uint64_t)file->access_time < exp.oldest) { + if ((uint64_t) file->access_time < exp.oldest) { exp.oldest = file->access_time; exp.filename = file->filename; } @@ -114,33 +113,33 @@ statfile_pool_expire (statfile_pool_t *pool) return 0; } -statfile_pool_t* +statfile_pool_t * statfile_pool_new (size_t max_size) { - statfile_pool_t *new; + statfile_pool_t *new; new = g_malloc (sizeof (statfile_pool_t)); bzero (new, sizeof (statfile_pool_t)); new->pool = memory_pool_new (memory_pool_get_size ()); new->max = max_size; new->files = memory_pool_alloc_shared (new->pool, STATFILES_MAX * sizeof (stat_file_t)); - new->lock = memory_pool_get_mutex (new->pool); + new->lock = memory_pool_get_mutex (new->pool); return new; } -stat_file_t * -statfile_pool_open (statfile_pool_t *pool, char *filename) +stat_file_t * +statfile_pool_open (statfile_pool_t * pool, char *filename) { - struct stat st; - stat_file_t *new_file; - + struct stat st; + stat_file_t *new_file; + if ((new_file = statfile_pool_is_open (pool, filename)) != NULL) { return new_file; } if (pool->opened >= STATFILES_MAX - 1) { - msg_err ("sttafile_pool_open: reached hard coded limit of statfiles opened: %d", STATFILES_MAX); + msg_err ("sttafile_pool_open: reached hard coded limit of statfiles opened: %d", STATFILES_MAX); return NULL; } @@ -148,9 +147,9 @@ statfile_pool_open (statfile_pool_t *pool, char *filename) msg_info ("statfile_pool_open: cannot stat file %s, error %s, %d", filename, strerror (errno), errno); return NULL; } - + if (st.st_size > pool->max) { - msg_info ("statfile_pool_open: cannot attach file to pool, too large: %zd", (size_t)st.st_size); + msg_info ("statfile_pool_open: cannot attach file to pool, too large: %zd", (size_t) st.st_size); return NULL; } @@ -161,31 +160,31 @@ statfile_pool_open (statfile_pool_t *pool, char *filename) return NULL; } } - - memory_pool_lock_mutex (pool->lock); - new_file = &pool->files[pool->opened ++]; - bzero (new_file, sizeof (stat_file_t)); - if ((new_file->fd = open (filename, O_RDWR)) == -1 ) { + + memory_pool_lock_mutex (pool->lock); + new_file = &pool->files[pool->opened++]; + bzero (new_file, sizeof (stat_file_t)); + if ((new_file->fd = open (filename, O_RDWR)) == -1) { msg_info ("statfile_pool_open: cannot open file %s, error %d, %s", filename, errno, strerror (errno)); - memory_pool_unlock_mutex (pool->lock); - pool->opened --; + memory_pool_unlock_mutex (pool->lock); + pool->opened--; return NULL; } - + if ((new_file->map = mmap (NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, new_file->fd, 0)) == MAP_FAILED) { close (new_file->fd); - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); msg_info ("statfile_pool_open: cannot mmap file %s, error %d, %s", filename, errno, strerror (errno)); - pool->opened --; + pool->opened--; return NULL; - + } - + g_strlcpy (new_file->filename, filename, sizeof (new_file->filename)); new_file->len = st.st_size; if (statfile_pool_check (new_file) == -1) { - pool->opened --; - memory_pool_unlock_mutex (pool->lock); + pool->opened--; + memory_pool_unlock_mutex (pool->lock); return NULL; } @@ -193,25 +192,25 @@ statfile_pool_open (statfile_pool_t *pool, char *filename) new_file->open_time = time (NULL); new_file->access_time = new_file->open_time; new_file->lock = memory_pool_get_mutex (pool->pool); - + /* Keep sorted */ qsort (pool->files, pool->opened, sizeof (stat_file_t), cmpstatfile); - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); return new_file; } int -statfile_pool_close (statfile_pool_t *pool, stat_file_t *file, gboolean keep_sorted) +statfile_pool_close (statfile_pool_t * pool, stat_file_t * file, gboolean keep_sorted) { - stat_file_t *pos; + stat_file_t *pos; if ((pos = statfile_pool_is_open (pool, file->filename)) == NULL) { msg_info ("statfile_pool_open: file %s is not opened", file->filename); return -1; } - - memory_pool_lock_mutex (pool->lock); + + memory_pool_lock_mutex (pool->lock); if (file->lock) { memory_pool_lock_mutex (file->lock); } @@ -223,82 +222,82 @@ statfile_pool_close (statfile_pool_t *pool, stat_file_t *file, gboolean keep_sor close (file->fd); } pool->occupied -= file->len; - pool->opened --; + pool->opened--; if (keep_sorted) { memmove (pos, &pool->files[pool->opened], sizeof (stat_file_t)); /* Keep sorted */ qsort (pool->files, pool->opened, sizeof (stat_file_t), cmpstatfile); } - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); return 0; } int -statfile_pool_create (statfile_pool_t *pool, char *filename, size_t blocks) +statfile_pool_create (statfile_pool_t * pool, char *filename, size_t blocks) { - struct stat_file_header header = { + struct stat_file_header header = { .magic = {'r', 's', 'd'}, .version = {1, 0}, .padding = {0, 0, 0}, }; - struct stat_file_section section = { + struct stat_file_section section = { .code = STATFILE_SECTION_COMMON, }; - struct stat_file_block block = {0, 0, 0, 0}; - int fd; - + struct stat_file_block block = { 0, 0, 0, 0 }; + int fd; + if (statfile_pool_is_open (pool, filename) != NULL) { msg_info ("statfile_pool_open: file %s is already opened", filename); return 0; } - memory_pool_lock_mutex (pool->lock); + memory_pool_lock_mutex (pool->lock); - if ((fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1 ) { + if ((fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1) { msg_info ("statfile_pool_create: cannot create file %s, error %d, %s", filename, errno, strerror (errno)); - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); return -1; } - header.create_time = (uint64_t)time (NULL); + header.create_time = (uint64_t) time (NULL); if (write (fd, &header, sizeof (header)) == -1) { msg_info ("statfile_pool_create: cannot write header to file %s, error %d, %s", filename, errno, strerror (errno)); close (fd); - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); return -1; } - - section.length = (uint64_t)blocks; + + section.length = (uint64_t) blocks; if (write (fd, §ion, sizeof (section)) == -1) { msg_info ("statfile_pool_create: cannot write section header to file %s, error %d, %s", filename, errno, strerror (errno)); close (fd); - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); return -1; } - - while (blocks --) { + + while (blocks--) { if (write (fd, &block, sizeof (block)) == -1) { msg_info ("statfile_pool_create: cannot write block to file %s, error %d, %s", filename, errno, strerror (errno)); close (fd); - memory_pool_unlock_mutex (pool->lock); + memory_pool_unlock_mutex (pool->lock); return -1; } } close (fd); - memory_pool_unlock_mutex (pool->lock); - + memory_pool_unlock_mutex (pool->lock); + return 0; } void -statfile_pool_delete (statfile_pool_t *pool) +statfile_pool_delete (statfile_pool_t * pool) { - int i; + int i; - for (i = 0; i < pool->opened; i ++) { + for (i = 0; i < pool->opened; i++) { statfile_pool_close (pool, &pool->files[i], FALSE); } memory_pool_delete (pool->pool); @@ -306,44 +305,44 @@ statfile_pool_delete (statfile_pool_t *pool) } void -statfile_pool_lock_file (statfile_pool_t *pool, stat_file_t *file) +statfile_pool_lock_file (statfile_pool_t * pool, stat_file_t * file) { memory_pool_lock_mutex (file->lock); } void -statfile_pool_unlock_file (statfile_pool_t *pool, stat_file_t *file) +statfile_pool_unlock_file (statfile_pool_t * pool, stat_file_t * file) { memory_pool_unlock_mutex (file->lock); } float -statfile_pool_get_block (statfile_pool_t *pool, stat_file_t *file, uint32_t h1, uint32_t h2, time_t now) +statfile_pool_get_block (statfile_pool_t * pool, stat_file_t * file, uint32_t h1, uint32_t h2, time_t now) { - struct stat_file_block *block; - struct stat_file_header *header; - unsigned int i, blocknum; - u_char *c; - - + struct stat_file_block *block; + struct stat_file_header *header; + unsigned int i, blocknum; + u_char *c; + + file->access_time = now; if (!file->map) { return 0; } - + blocknum = h1 % file->cur_section.length; header = (struct stat_file_header *)file->map; - c = (u_char *)file->map + file->seek_pos + blocknum * sizeof (struct stat_file_block); + c = (u_char *) file->map + file->seek_pos + blocknum * sizeof (struct stat_file_block); block = (struct stat_file_block *)c; - for (i = 0; i < CHAIN_LENGTH; i ++) { + for (i = 0; i < CHAIN_LENGTH; i++) { if (i + blocknum > file->cur_section.length) { break; } if (block->hash1 == h1 && block->hash2 == h2) { - block->last_access = now - (time_t)header->create_time; + block->last_access = now - (time_t) header->create_time; return block->value; } c += sizeof (struct stat_file_block); @@ -355,25 +354,25 @@ statfile_pool_get_block (statfile_pool_t *pool, stat_file_t *file, uint32_t h1, } void -statfile_pool_set_block (statfile_pool_t *pool, stat_file_t *file, uint32_t h1, uint32_t h2, time_t now, float value) +statfile_pool_set_block (statfile_pool_t * pool, stat_file_t * file, uint32_t h1, uint32_t h2, time_t now, float value) { - struct stat_file_block *block, *to_expire = NULL; - struct stat_file_header *header; - unsigned int i, blocknum, oldest = 0; - u_char *c; - - + struct stat_file_block *block, *to_expire = NULL; + struct stat_file_header *header; + unsigned int i, blocknum, oldest = 0; + u_char *c; + + file->access_time = now; if (!file->map) { return; } - + blocknum = h1 % file->cur_section.length; header = (struct stat_file_header *)file->map; - c = (u_char *)file->map + file->seek_pos + blocknum * sizeof (struct stat_file_block); + c = (u_char *) file->map + file->seek_pos + blocknum * sizeof (struct stat_file_block); block = (struct stat_file_block *)c; - for (i = 0; i < CHAIN_LENGTH; i ++) { + for (i = 0; i < CHAIN_LENGTH; i++) { if (i + blocknum > file->cur_section.length) { /* Need to expire some block in chain */ msg_debug ("statfile_pool_set_block: chain %u is full, starting expire", blocknum); @@ -381,7 +380,7 @@ statfile_pool_set_block (statfile_pool_t *pool, stat_file_t *file, uint32_t h1, } /* First try to find block in chain */ if (block->hash1 == h1 && block->hash2 == h2) { - block->last_access = now - (time_t)header->create_time; + block->last_access = now - (time_t) header->create_time; block->value = value; return; } @@ -392,7 +391,7 @@ statfile_pool_set_block (statfile_pool_t *pool, stat_file_t *file, uint32_t h1, block->hash1 = h1; block->hash2 = h2; block->value = value; - block->last_access = now - (time_t)header->create_time; + block->last_access = now - (time_t) header->create_time; return; } if (block->last_access > oldest) { @@ -408,38 +407,38 @@ statfile_pool_set_block (statfile_pool_t *pool, stat_file_t *file, uint32_t h1, } else { /* Expire first block in chain */ - c = (u_char *)file->map + file->seek_pos + blocknum * sizeof (struct stat_file_block); + c = (u_char *) file->map + file->seek_pos + blocknum * sizeof (struct stat_file_block); block = (struct stat_file_block *)c; } - block->last_access = now - (time_t)header->create_time; + block->last_access = now - (time_t) header->create_time; block->hash1 = h1; block->hash2 = h2; block->value = value; } -stat_file_t * -statfile_pool_is_open (statfile_pool_t *pool, char *filename) +stat_file_t * +statfile_pool_is_open (statfile_pool_t * pool, char *filename) { - static stat_file_t f, *ret; + static stat_file_t f, *ret; g_strlcpy (f.filename, filename, sizeof (f.filename)); ret = bsearch (&f, pool->files, pool->opened, sizeof (stat_file_t), cmpstatfile); return ret; } uint32_t -statfile_pool_get_section (statfile_pool_t *pool, stat_file_t *file) +statfile_pool_get_section (statfile_pool_t * pool, stat_file_t * file) { return file->cur_section.code; } -gboolean -statfile_pool_set_section (statfile_pool_t *pool, stat_file_t *file, uint32_t code, gboolean from_begin) +gboolean +statfile_pool_set_section (statfile_pool_t * pool, stat_file_t * file, uint32_t code, gboolean from_begin) { - struct stat_file_section *sec; - off_t cur_offset; + struct stat_file_section *sec; + off_t cur_offset; + - /* Try to find section */ if (from_begin) { cur_offset = sizeof (struct stat_file_header); @@ -461,17 +460,17 @@ statfile_pool_set_section (statfile_pool_t *pool, stat_file_t *file, uint32_t co return FALSE; } -gboolean -statfile_pool_add_section (statfile_pool_t *pool, stat_file_t *file, uint32_t code, uint64_t length) +gboolean +statfile_pool_add_section (statfile_pool_t * pool, stat_file_t * file, uint32_t code, uint64_t length) { - struct stat_file_section sect; - struct stat_file_block block = {0, 0, 0, 0}; - + struct stat_file_section sect; + struct stat_file_block block = { 0, 0, 0, 0 }; + if (lseek (file->fd, 0, SEEK_END) == -1) { msg_info ("statfile_pool_add_section: cannot lseek file %s, error %d, %s", file->filename, errno, strerror (errno)); return FALSE; } - + sect.code = code; sect.length = length; @@ -480,19 +479,19 @@ statfile_pool_add_section (statfile_pool_t *pool, stat_file_t *file, uint32_t co return FALSE; } - while (length --) { + while (length--) { if (write (file->fd, &block, sizeof (block)) == -1) { msg_info ("statfile_pool_add_section: cannot write block to file %s, error %d, %s", file->filename, errno, strerror (errno)); return FALSE; } } - + /* Lock statfile to remap memory */ statfile_pool_lock_file (pool, file); munmap (file->map, file->len); fsync (file->fd); file->len += length; - + if (file->len > pool->max) { msg_info ("statfile_pool_open: cannot attach file to pool, too large: %lu", (long int)file->len); return FALSE; @@ -515,7 +514,7 @@ statfile_pool_add_section (statfile_pool_t *pool, stat_file_t *file, uint32_t co } -uint32_t +uint32_t statfile_get_section_by_name (const char *name) { if (g_ascii_strcasecmp (name, "common") == 0) { diff --git a/src/symbols_cache.c b/src/symbols_cache.c index cc7e8a1b1..8ecae4513 100644 --- a/src/symbols_cache.c +++ b/src/symbols_cache.c @@ -42,43 +42,39 @@ #define MIN_CACHE 17 -static uint64_t total_frequency; -static uint32_t nsymbols; +static uint64_t total_frequency; +static uint32_t nsymbols; int cache_cmp (const void *p1, const void *p2) { - const struct cache_item *i1 = p1, *i2 = p2; - + const struct cache_item *i1 = p1, *i2 = p2; + return strcmp (i1->s->symbol, i2->s->symbol); } int cache_logic_cmp (const void *p1, const void *p2) { - const struct cache_item *i1 = p1, *i2 = p2; - double w1, w2; - double f1 = 0, f2 = 0; - + const struct cache_item *i1 = p1, *i2 = p2; + double w1, w2; + double f1 = 0, f2 = 0; + if (total_frequency > 0) { f1 = ((double)i1->s->frequency * nsymbols) / (double)total_frequency; f2 = ((double)i2->s->frequency * nsymbols) / (double)total_frequency; } - w1 = abs (i1->s->weight) * WEIGHT_MULT + - f1 * FREQUENCY_MULT + - i1->s->avg_time * TIME_MULT; - w2 = abs (i2->s->weight) * WEIGHT_MULT + - f2 * FREQUENCY_MULT + - i2->s->avg_time * TIME_MULT; - + w1 = abs (i1->s->weight) * WEIGHT_MULT + f1 * FREQUENCY_MULT + i1->s->avg_time * TIME_MULT; + w2 = abs (i2->s->weight) * WEIGHT_MULT + f2 * FREQUENCY_MULT + i2->s->avg_time * TIME_MULT; + return (int)w2 - w1; } static void grow_cache (struct symbols_cache *cache) { - guint old = cache->cur_items, i; - void *new; + guint old = cache->cur_items, i; + void *new; cache->cur_items = cache->cur_items * 2; new = g_new0 (struct cache_item, cache->cur_items); @@ -87,20 +83,20 @@ grow_cache (struct symbols_cache *cache) cache->items = new; /* Create new saved_cache_items */ - for (i = old; i < cache->cur_items; i ++) { + for (i = old; i < cache->cur_items; i++) { cache->items[i].s = g_new0 (struct saved_cache_item, 1); } } -static GChecksum * +static GChecksum * get_mem_cksum (struct symbols_cache *cache) { - int i; - GChecksum *result; - + int i; + GChecksum *result; + result = g_checksum_new (G_CHECKSUM_SHA1); - for (i = 0; i < cache->used_items; i ++) { + for (i = 0; i < cache->used_items; i++) { if (cache->items[i].s->symbol[0] != '\0') { g_checksum_update (result, cache->items[i].s->symbol, strlen (cache->items[i].s->symbol)); } @@ -113,22 +109,22 @@ get_mem_cksum (struct symbols_cache *cache) static void post_cache_init (struct symbols_cache *cache) { - int i; - + int i; + total_frequency = 0; nsymbols = cache->used_items; - for (i = 0; i < cache->used_items; i ++) { + for (i = 0; i < cache->used_items; i++) { total_frequency += cache->items[i].s->frequency; } qsort (cache->items, cache->used_items, sizeof (struct cache_item), cache_logic_cmp); } -static gboolean +static gboolean mmap_cache_file (struct symbols_cache *cache, int fd) { - void *map; - int i; + void *map; + int i; map = mmap (NULL, cache->used_items * sizeof (struct saved_cache_item), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { @@ -139,7 +135,7 @@ mmap_cache_file (struct symbols_cache *cache, int fd) /* Close descriptor as it would never be used */ close (fd); /* Now free old values for saved cache items and fill them with mmapped ones */ - for (i = 0; i < cache->used_items; i ++) { + for (i = 0; i < cache->used_items; i++) { g_free (cache->items[i].s); cache->items[i].s = ((struct saved_cache_item *)map) + i; } @@ -149,13 +145,13 @@ mmap_cache_file (struct symbols_cache *cache, int fd) } /* Fd must be opened for writing, after creating file is mmapped */ -static gboolean +static gboolean create_cache_file (struct symbols_cache *cache, const char *filename, int fd) { - int i; - GChecksum *cksum; - u_char *digest; - gsize cklen; + int i; + GChecksum *cksum; + u_char *digest; + gsize cklen; /* Calculate checksum */ cksum = get_mem_cksum (cache); @@ -170,7 +166,7 @@ create_cache_file (struct symbols_cache *cache, const char *filename, int fd) g_checksum_get_digest (cksum, digest, &cklen); /* Now write data to file */ - for (i = 0; i < cache->used_items; i ++) { + for (i = 0; i < cache->used_items; i++) { if (write (fd, cache->items[i].s, sizeof (struct saved_cache_item)) == -1) { msg_err ("create_cache_file: cannot write to file %d, %s", errno, strerror (errno)); close (fd); @@ -200,12 +196,12 @@ create_cache_file (struct symbols_cache *cache, const char *filename, int fd) return mmap_cache_file (cache, fd); } -void +void register_symbol (struct symbols_cache **cache, const char *name, double weight, symbol_func_t func, gpointer user_data) { - struct cache_item *item = NULL; - int i; - + struct cache_item *item = NULL; + int i; + if (*cache == NULL) { *cache = g_new0 (struct symbols_cache, 1); } @@ -213,11 +209,11 @@ register_symbol (struct symbols_cache **cache, const char *name, double weight, (*cache)->cur_items = MIN_CACHE; (*cache)->used_items = 0; (*cache)->items = g_new0 (struct cache_item, (*cache)->cur_items); - for (i = 0; i < (*cache)->cur_items; i ++) { + for (i = 0; i < (*cache)->cur_items; i++) { (*cache)->items[i].s = g_new0 (struct saved_cache_item, 1); } } - + if ((*cache)->used_items >= (*cache)->cur_items) { grow_cache (*cache); /* Call once more */ @@ -226,34 +222,34 @@ register_symbol (struct symbols_cache **cache, const char *name, double weight, } item = &(*cache)->items[(*cache)->used_items]; - + g_strlcpy (item->s->symbol, name, sizeof (item->s->symbol)); item->func = func; item->user_data = user_data; item->s->weight = weight; - (*cache)->used_items ++; + (*cache)->used_items++; set_counter (item->s->symbol, 0); } -gboolean -init_symbols_cache (memory_pool_t *pool, struct symbols_cache *cache, const char *filename) +gboolean +init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const char *filename) { - struct stat st; - int fd; - GChecksum *cksum; - u_char *mem_sum, *file_sum; - gsize cklen; + struct stat st; + int fd; + GChecksum *cksum; + u_char *mem_sum, *file_sum; + gsize cklen; if (cache == NULL || cache->items == NULL) { return FALSE; } - + /* Sort items in cache */ qsort (cache->items, cache->used_items, sizeof (struct cache_item), cache_cmp); /* Init locking */ cache->lock = memory_pool_get_rwlock (pool); - + /* Just in-memory cache */ if (filename == NULL) { post_cache_init (cache); @@ -265,7 +261,7 @@ init_symbols_cache (memory_pool_t *pool, struct symbols_cache *cache, const char /* Check errno */ if (errno == ENOENT) { /* Try to create file */ - if ((fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1 ) { + if ((fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1) { msg_info ("load_symbols_cache: cannot create file %s, error %d, %s", filename, errno, strerror (errno)); return FALSE; } @@ -322,7 +318,7 @@ init_symbols_cache (memory_pool_t *pool, struct symbols_cache *cache, const char g_checksum_free (cksum); msg_info ("load_symbols_cache: checksum mismatch, recreating file"); /* Reopen with rw permissions */ - if ((fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1 ) { + if ((fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1) { msg_info ("load_symbols_cache: cannot create file %s, error %d, %s", filename, errno, strerror (errno)); return FALSE; } @@ -339,17 +335,17 @@ init_symbols_cache (memory_pool_t *pool, struct symbols_cache *cache, const char } gboolean -call_symbol_callback (struct worker_task *task, struct symbols_cache *cache, struct cache_item **saved_item) +call_symbol_callback (struct worker_task * task, struct symbols_cache * cache, struct cache_item ** saved_item) { - struct timespec ts1, ts2; - uint64_t diff; - struct cache_item *item; + struct timespec ts1, ts2; + uint64_t diff; + struct cache_item *item; if (*saved_item == NULL) { if (cache == NULL) { return FALSE; } - if (cache->uses ++ >= MAX_USES) { + if (cache->uses++ >= MAX_USES) { msg_info ("call_symbols_callback: resort symbols cache"); memory_pool_wlock_rwlock (cache->lock); cache->uses = 0; diff --git a/src/tokenizers/osb.c b/src/tokenizers/osb.c index d2a1fe22f..8bbf30d7f 100644 --- a/src/tokenizers/osb.c +++ b/src/tokenizers/osb.c @@ -32,24 +32,24 @@ /* Minimum length of token */ #define MIN_LEN 4 -extern const int primes[]; +extern const int primes[]; int -osb_tokenize_text (struct tokenizer *tokenizer, memory_pool_t *pool, f_str_t *input, GTree **tree) +osb_tokenize_text (struct tokenizer *tokenizer, memory_pool_t * pool, f_str_t * input, GTree ** tree) { - token_node_t *new = NULL; - f_str_t token = { NULL, 0, 0 }, *res; - uint32_t hashpipe[FEATURE_WINDOW_SIZE], h1, h2; - int i; + token_node_t *new = NULL; + f_str_t token = { NULL, 0, 0 }, *res; + uint32_t hashpipe[FEATURE_WINDOW_SIZE], h1, h2; + int i; /* First set all bytes of hashpipe to some common value */ - for (i = 0; i < FEATURE_WINDOW_SIZE; i ++) { + for (i = 0; i < FEATURE_WINDOW_SIZE; i++) { hashpipe[i] = 0xABCDEF; } - + if (*tree == NULL) { *tree = g_tree_new (token_node_compare_func); - memory_pool_add_destructor (pool, (pool_destruct_func)g_tree_destroy, *tree); + memory_pool_add_destructor (pool, (pool_destruct_func) g_tree_destroy, *tree); } msg_debug ("osb_tokenize_text: got input length: %zd", input->len); @@ -60,14 +60,14 @@ osb_tokenize_text (struct tokenizer *tokenizer, memory_pool_t *pool, f_str_t *in continue; } /* Shift hashpipe */ - for (i = FEATURE_WINDOW_SIZE - 1; i > 0; i --) { + for (i = FEATURE_WINDOW_SIZE - 1; i > 0; i--) { hashpipe[i] = hashpipe[i - 1]; } hashpipe[0] = fstrhash (&token); - - for (i = 1; i < FEATURE_WINDOW_SIZE; i ++) { - h1 = hashpipe[0]* primes[0] + hashpipe[i] * primes[i<<1]; - h2 = hashpipe[0] * primes[1] + hashpipe[i] * primes[(i<<1)-1]; + + for (i = 1; i < FEATURE_WINDOW_SIZE; i++) { + h1 = hashpipe[0] * primes[0] + hashpipe[i] * primes[i << 1]; + h2 = hashpipe[0] * primes[1] + hashpipe[i] * primes[(i << 1) - 1]; new = memory_pool_alloc (pool, sizeof (token_node_t)); new->h1 = h1; new->h2 = h2; diff --git a/src/tokenizers/tokenizers.c b/src/tokenizers/tokenizers.c index 7db1af12c..2bb478aaa 100644 --- a/src/tokenizers/tokenizers.c +++ b/src/tokenizers/tokenizers.c @@ -30,11 +30,11 @@ #include "../main.h" #include "tokenizers.h" -struct tokenizer tokenizers[] = { - {"osb-text", osb_tokenize_text, get_next_word }, +struct tokenizer tokenizers[] = { + {"osb-text", osb_tokenize_text, get_next_word}, }; -const int primes[] = { +const int primes[] = { 1, 7, 3, 13, 5, 29, @@ -47,12 +47,12 @@ const int primes[] = { 797, 3277, }; -struct tokenizer* +struct tokenizer * get_tokenizer (char *name) { - int i; + int i; - for (i = 0; i < sizeof (tokenizers) / sizeof (tokenizers[0]); i ++) { + for (i = 0; i < sizeof (tokenizers) / sizeof (tokenizers[0]); i++) { if (strcmp (tokenizers[i].name, name) == 0) { return &tokenizers[i]; } @@ -61,11 +61,11 @@ get_tokenizer (char *name) return NULL; } -int +int token_node_compare_func (gconstpointer a, gconstpointer b) { - const token_node_t *aa = a, *bb = b; - + const token_node_t *aa = a, *bb = b; + if (aa->h1 == bb->h1) { return aa->h2 - bb->h2; } @@ -74,12 +74,12 @@ token_node_compare_func (gconstpointer a, gconstpointer b) } /* Get next word from specified f_str_t buf */ -f_str_t * -get_next_word (f_str_t *buf, f_str_t *token) +f_str_t * +get_next_word (f_str_t * buf, f_str_t * token) { - size_t remain; - unsigned char *pos; - + size_t remain; + unsigned char *pos; + if (buf == NULL) { return NULL; } @@ -89,7 +89,7 @@ get_next_word (f_str_t *buf, f_str_t *token) token->begin = token->begin + token->len; token->len = 0; - + remain = buf->len - (token->begin - buf->begin); if (remain <= 0) { return NULL; @@ -97,37 +97,37 @@ get_next_word (f_str_t *buf, f_str_t *token) pos = token->begin; /* Skip non graph symbols */ while (remain > 0 && (!g_ascii_isgraph (*pos) && *pos < 127)) { - token->begin ++; - pos ++; - remain --; + token->begin++; + pos++; + remain--; } while (remain > 0 && (g_ascii_isgraph (*pos) || *pos > 127)) { - token->len ++; - pos ++; - remain --; + token->len++; + pos++; + remain--; } if (token->len == 0) { return NULL; } - + return token; } int -tokenize_urls (memory_pool_t *pool, struct worker_task *task, GTree **tree) +tokenize_urls (memory_pool_t * pool, struct worker_task *task, GTree ** tree) { - token_node_t *new = NULL; - f_str_t url_domain; - struct uri *url; - GList *cur; - uint32_t h; + token_node_t *new = NULL; + f_str_t url_domain; + struct uri *url; + GList *cur; + uint32_t h; if (*tree == NULL) { *tree = g_tree_new (token_node_compare_func); - memory_pool_add_destructor (pool, (pool_destruct_func)g_tree_destroy, *tree); + memory_pool_add_destructor (pool, (pool_destruct_func) g_tree_destroy, *tree); } - + cur = task->urls; while (cur) { url = cur->data; @@ -148,32 +148,32 @@ tokenize_urls (memory_pool_t *pool, struct worker_task *task, GTree **tree) /* Struct to access gmime headers */ struct raw_header { - struct raw_header *next; - char *name; - char *value; + struct raw_header *next; + char *name; + char *value; }; typedef struct _GMimeHeader { - GHashTable *hash; - GHashTable *writers; - struct raw_header *headers; + GHashTable *hash; + GHashTable *writers; + struct raw_header *headers; } local_GMimeHeader; int -tokenize_headers (memory_pool_t *pool, struct worker_task *task, GTree **tree) +tokenize_headers (memory_pool_t * pool, struct worker_task *task, GTree ** tree) { - token_node_t *new = NULL; - f_str_t headername; - f_str_t headervalue; + token_node_t *new = NULL; + f_str_t headername; + f_str_t headervalue; if (*tree == NULL) { *tree = g_tree_new (token_node_compare_func); - memory_pool_add_destructor (pool, (pool_destruct_func)g_tree_destroy, *tree); + memory_pool_add_destructor (pool, (pool_destruct_func) g_tree_destroy, *tree); } #ifndef GMIME24 - struct raw_header *h; + struct raw_header *h; - h = GMIME_OBJECT(task->message)->headers->headers; + h = GMIME_OBJECT (task->message)->headers->headers; while (h) { if (h->name && h->value) { new = memory_pool_alloc (pool, sizeof (token_node_t)); @@ -190,12 +190,12 @@ tokenize_headers (memory_pool_t *pool, struct worker_task *task, GTree **tree) h = h->next; } #else - GMimeHeaderList *ls; - GMimeHeaderIter *iter; - const char *name; - const char *value; + GMimeHeaderList *ls; + GMimeHeaderIter *iter; + const char *name; + const char *value; - ls = GMIME_OBJECT(task->message)->headers; + ls = GMIME_OBJECT (task->message)->headers; if (g_mime_header_list_get_iter (ls, iter)) { while (g_mime_header_iter_is_valid (iter)) { diff --git a/src/upstream.c b/src/upstream.c index 8bc636377..fac7d3381 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -23,7 +23,7 @@ */ #ifdef _THREAD_SAFE -#include <pthread.h> +# include <pthread.h> #endif #include <sys/types.h> @@ -31,32 +31,32 @@ #include <stdlib.h> #include <stdio.h> #ifdef HAVE_STDINT_H -#include <stdint.h> +# include <stdint.h> #endif #ifdef HAVE_INTTYPES_H -#include <inttypes.h> +# include <inttypes.h> #endif #include <limits.h> #ifdef WITH_DEBUG -#include <syslog.h> +# include <syslog.h> #endif #include "upstream.h" #ifdef WITH_DEBUG -#define msg_debug(args...) syslog(LOG_DEBUG, ##args) +# define msg_debug(args...) syslog(LOG_DEBUG, ##args) #else -#define msg_debug(args...) do {} while(0) +# define msg_debug(args...) do {} while(0) #endif #ifdef _THREAD_SAFE -pthread_rwlock_t upstream_mtx = PTHREAD_RWLOCK_INITIALIZER; -#define U_RLOCK() do { pthread_rwlock_rdlock (&upstream_mtx); } while (0) -#define U_WLOCK() do { pthread_rwlock_wrlock (&upstream_mtx); } while (0) -#define U_UNLOCK() do { pthread_rwlock_unlock (&upstream_mtx); } while (0) +pthread_rwlock_t upstream_mtx = PTHREAD_RWLOCK_INITIALIZER; +# define U_RLOCK() do { pthread_rwlock_rdlock (&upstream_mtx); } while (0) +# define U_WLOCK() do { pthread_rwlock_wrlock (&upstream_mtx); } while (0) +# define U_UNLOCK() do { pthread_rwlock_unlock (&upstream_mtx); } while (0) #else -#define U_RLOCK() do {} while (0) -#define U_WLOCK() do {} while (0) -#define U_UNLOCK() do {} while (0) +# define U_RLOCK() do {} while (0) +# define U_WLOCK() do {} while (0) +# define U_UNLOCK() do {} while (0) #endif #define MAX_TRIES 20 @@ -66,50 +66,50 @@ pthread_rwlock_t upstream_mtx = PTHREAD_RWLOCK_INITIALIZER; * Init: 0x0 */ -static const uint32_t crc32lookup[256] = { - 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, 0x706af48fU, - 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, - 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, - 0xf3b97148U, 0x84be41deU, 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, - 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, - 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U, - 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 0x35b5a8faU, 0x42b2986cU, - 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, - 0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, - 0xcfba9599U, 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, - 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, 0x01db7106U, - 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U, - 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, - 0x91646c97U, 0xe6635c01U, 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, - 0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, - 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, - 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, 0x4adfa541U, 0x3dd895d7U, - 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, - 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, - 0xbe0b1010U, 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, - 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, 0x2eb40d81U, - 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU, - 0xead54739U, 0x9dd277afU, 0x04db2615U, 0x73dc1683U, 0xe3630b12U, 0x94643b84U, - 0x0d6d6a3eU, 0x7a6a5aa8U, 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, - 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, - 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU, - 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 0xd6d6a3e8U, 0xa1d1937eU, - 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, - 0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, - 0x316e8eefU, 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, - 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, 0xb2bd0b28U, - 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, - 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, - 0x72076785U, 0x05005713U, 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, - 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, - 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, - 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 0x8f659effU, 0xf862ae69U, - 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, - 0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, - 0x40df0b66U, 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, - 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, 0xcdd70693U, - 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U, - 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU +static const uint32_t crc32lookup[256] = { + 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, 0x706af48fU, + 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, + 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, + 0xf3b97148U, 0x84be41deU, 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, + 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, + 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U, + 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 0x35b5a8faU, 0x42b2986cU, + 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, + 0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, + 0xcfba9599U, 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, + 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, 0x01db7106U, + 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U, + 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, + 0x91646c97U, 0xe6635c01U, 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, + 0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, + 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, + 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, 0x4adfa541U, 0x3dd895d7U, + 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, + 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, + 0xbe0b1010U, 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, + 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, 0x2eb40d81U, + 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU, + 0xead54739U, 0x9dd277afU, 0x04db2615U, 0x73dc1683U, 0xe3630b12U, 0x94643b84U, + 0x0d6d6a3eU, 0x7a6a5aa8U, 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, + 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, + 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU, + 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 0xd6d6a3e8U, 0xa1d1937eU, + 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, + 0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, + 0x316e8eefU, 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, + 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, 0xb2bd0b28U, + 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, + 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, + 0x72076785U, 0x05005713U, 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, + 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, + 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, + 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 0x8f659effU, 0xf862ae69U, + 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, + 0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, + 0x40df0b66U, 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, + 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, 0xcdd70693U, + 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U, + 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; /* @@ -120,7 +120,7 @@ check_upstream (struct upstream *up, time_t now, time_t error_timeout, time_t re { if (up->dead) { if (now - up->time >= revive_timeout) { - msg_debug ("check_upstream: reviving upstream after %ld seconds", (long int) now - up->time); + msg_debug ("check_upstream: reviving upstream after %ld seconds", (long int)now - up->time); U_WLOCK (); up->dead = 0; up->errors = 0; @@ -131,7 +131,7 @@ check_upstream (struct upstream *up, time_t now, time_t error_timeout, time_t re } else { if (now - up->time >= error_timeout && up->errors >= max_errors) { - msg_debug ("check_upstream: marking upstreams as dead after %ld errors", (long int) up->errors); + msg_debug ("check_upstream: marking upstreams as dead after %ld errors", (long int)up->errors); U_WLOCK (); up->dead = 1; up->time = now; @@ -148,15 +148,16 @@ void upstream_fail (struct upstream *up, time_t now) { if (up->time != 0) { - up->errors ++; + up->errors++; } else { U_WLOCK (); up->time = now; - up->errors ++; + up->errors++; U_UNLOCK (); } } + /* * Call this function after successfull upstream request */ @@ -170,17 +171,18 @@ upstream_ok (struct upstream *up, time_t now) U_UNLOCK (); } - up->weight --; + up->weight--; } + /* * Mark all upstreams as active. This function is used when all upstreams are marked as inactive */ void -revive_all_upstreams (void *ups, size_t members, size_t msize) +revive_all_upstreams (void *ups, size_t members, size_t msize) { - int i; - struct upstream *cur; - u_char *p; + int i; + struct upstream *cur; + u_char *p; U_WLOCK (); msg_debug ("revive_all_upstreams: starting reviving all upstreams"); @@ -202,11 +204,11 @@ revive_all_upstreams (void *ups, size_t members, size_t msize) */ static int rescan_upstreams (void *ups, size_t members, size_t msize, time_t now, time_t error_timeout, time_t revive_timeout, size_t max_errors) -{ - int i, alive; - struct upstream *cur; - u_char *p; - +{ + int i, alive; + struct upstream *cur; + u_char *p; + /* Recheck all upstreams */ p = ups; alive = members; @@ -216,7 +218,7 @@ rescan_upstreams (void *ups, size_t members, size_t msize, time_t now, time_t er alive -= cur->dead; p += msize; } - + /* All upstreams are dead */ if (alive == 0) { revive_all_upstreams (ups, members, msize); @@ -224,18 +226,18 @@ rescan_upstreams (void *ups, size_t members, size_t msize, time_t now, time_t er } msg_debug ("rescan_upstreams: %d upstreams alive", alive); - + return alive; } /* Return alive upstream by its number */ -static struct upstream * +static struct upstream * get_upstream_by_number (void *ups, size_t members, size_t msize, int selected) { - int i; - u_char *p, *c; - struct upstream *cur; + int i; + u_char *p, *c; + struct upstream *cur; i = 0; p = ups; @@ -271,16 +273,16 @@ get_upstream_by_number (void *ups, size_t members, size_t msize, int selected) /* * Get hash key for specified key (perl hash) */ -static uint32_t +static uint32_t get_hash_for_key (uint32_t hash, char *key, size_t keylen) { - uint32_t h, index; - const char *end = key + keylen; + uint32_t h, index; + const char *end = key + keylen; h = ~hash; while (key < end) { - index = (h ^ (u_char) *key) & 0x000000ffU; + index = (h ^ (u_char) * key) & 0x000000ffU; h = (h >> 8) ^ crc32lookup[index]; ++key; } @@ -291,31 +293,29 @@ get_hash_for_key (uint32_t hash, char *key, size_t keylen) /* * Recheck all upstreams and return random active upstream */ -struct upstream * +struct upstream * get_random_upstream (void *ups, size_t members, size_t msize, time_t now, time_t error_timeout, time_t revive_timeout, size_t max_errors) { - int alive, selected; - + int alive, selected; + alive = rescan_upstreams (ups, members, msize, now, error_timeout, revive_timeout, max_errors); selected = rand () % alive; msg_debug ("get_random_upstream: return upstream with number %d of %d", selected, alive); - - return get_upstream_by_number (ups, members, msize, selected); + + return get_upstream_by_number (ups, members, msize, selected); } /* * Return upstream by hash, that is calculated from active upstreams number */ -struct upstream * -get_upstream_by_hash (void *ups, size_t members, size_t msize, time_t now, - time_t error_timeout, time_t revive_timeout, size_t max_errors, - char *key, size_t keylen) +struct upstream * +get_upstream_by_hash (void *ups, size_t members, size_t msize, time_t now, time_t error_timeout, time_t revive_timeout, size_t max_errors, char *key, size_t keylen) { - int alive, tries = 0, r; - uint32_t h = 0, ht; - char *p, numbuf[4]; - struct upstream *cur; - + int alive, tries = 0, r; + uint32_t h = 0, ht; + char *p, numbuf[4]; + struct upstream *cur; + alive = rescan_upstreams (ups, members, msize, now, error_timeout, revive_timeout, max_errors); if (alive == 0) { @@ -345,13 +345,13 @@ get_upstream_by_hash (void *ups, size_t members, size_t msize, time_t now, #endif h %= members; msg_debug ("get_upstream_by_hash: try to select upstream number %d of %zd, tries: %d", h, members, tries); - tries ++; + tries++; if (tries > MAX_TRIES) { msg_debug ("get_upstream_by_hash: max tries exceed, returning NULL"); return NULL; } } - + U_RLOCK (); p = ups; U_UNLOCK (); @@ -361,13 +361,13 @@ get_upstream_by_hash (void *ups, size_t members, size_t msize, time_t now, /* * Recheck all upstreams and return upstream in round-robin order according to weight and priority */ -struct upstream * +struct upstream * get_upstream_round_robin (void *ups, size_t members, size_t msize, time_t now, time_t error_timeout, time_t revive_timeout, size_t max_errors) { - int alive, max_weight, i; - struct upstream *cur, *selected = NULL; - u_char *p; - + int alive, max_weight, i; + struct upstream *cur, *selected = NULL; + u_char *p; + /* Recheck all upstreams */ alive = rescan_upstreams (ups, members, msize, now, error_timeout, revive_timeout, max_errors); @@ -391,7 +391,7 @@ get_upstream_round_robin (void *ups, size_t members, size_t msize, time_t now, t p = ups; U_WLOCK (); for (i = 0; i < members; i++) { - cur = (struct upstream *)p; + cur = (struct upstream *)p; cur->weight = cur->priority; if (!cur->dead) { if (max_weight < cur->priority) { @@ -411,13 +411,13 @@ get_upstream_round_robin (void *ups, size_t members, size_t msize, time_t now, t /* * Recheck all upstreams and return upstream in round-robin order according to only priority (master-slaves) */ -struct upstream * +struct upstream * get_upstream_master_slave (void *ups, size_t members, size_t msize, time_t now, time_t error_timeout, time_t revive_timeout, size_t max_errors) { - int alive, max_weight, i; - struct upstream *cur, *selected = NULL; - u_char *p; - + int alive, max_weight, i; + struct upstream *cur, *selected = NULL; + u_char *p; + /* Recheck all upstreams */ alive = rescan_upstreams (ups, members, msize, now, error_timeout, revive_timeout, max_errors); @@ -448,7 +448,7 @@ get_upstream_master_slave (void *ups, size_t members, size_t msize, time_t now, static int ketama_sort_cmp (const void *a1, const void *a2) { - return *((uint32_t *)a1) - *((uint32_t *)a2); + return *((uint32_t *) a1) - *((uint32_t *) a2); } /* @@ -457,9 +457,9 @@ ketama_sort_cmp (const void *a1, const void *a2) int upstream_ketama_add (struct upstream *up, char *up_key, size_t keylen, size_t keypoints) { - uint32_t h = 0; - char tmp[4]; - int i; + uint32_t h = 0; + char tmp[4]; + int i; /* Allocate ketama points array */ if (up->ketama_points == NULL) { @@ -477,7 +477,7 @@ upstream_ketama_add (struct upstream *up, char *up_key, size_t keylen, size_t ke tmp[1] = (i >> 8) & 0xff; tmp[2] = (i >> 16) & 0xff; tmp[3] = (i >> 24) & 0xff; - + h = get_hash_for_key (h, tmp, sizeof (tmp) * sizeof (char)); up->ketama_points[i] = h; } @@ -490,16 +490,14 @@ upstream_ketama_add (struct upstream *up, char *up_key, size_t keylen, size_t ke /* * Return upstream by hash and find nearest ketama point in some server */ -struct upstream * -get_upstream_by_hash_ketama (void *ups, size_t members, size_t msize, time_t now, - time_t error_timeout, time_t revive_timeout, size_t max_errors, - char *key, size_t keylen) +struct upstream * +get_upstream_by_hash_ketama (void *ups, size_t members, size_t msize, time_t now, time_t error_timeout, time_t revive_timeout, size_t max_errors, char *key, size_t keylen) { - int alive, i; - uint32_t h = 0, step, middle, d, min_diff = UINT_MAX; - char *p; - struct upstream *cur = NULL, *nearest = NULL; - + int alive, i; + uint32_t h = 0, step, middle, d, min_diff = UINT_MAX; + char *p; + struct upstream *cur = NULL, *nearest = NULL; + alive = rescan_upstreams (ups, members, msize, now, error_timeout, revive_timeout, max_errors); if (alive == 0) { @@ -507,7 +505,7 @@ get_upstream_by_hash_ketama (void *ups, size_t members, size_t msize, time_t now } h = get_hash_for_key (h, key, keylen); - + U_RLOCK (); p = ups; nearest = (struct upstream *)p; @@ -40,61 +40,37 @@ (LOWEST_PORT <= (port) && (port) <= HIGHEST_PORT) struct _proto { - unsigned char *name; - int port; - uintptr_t *unused; - unsigned int need_slashes:1; - unsigned int need_slash_after_host:1; - unsigned int free_syntax:1; - unsigned int need_ssl:1; + unsigned char *name; + int port; + uintptr_t *unused; + unsigned int need_slashes:1; + unsigned int need_slash_after_host:1; + unsigned int free_syntax:1; + unsigned int need_ssl:1; }; -static const char *text_url = "((https?|ftp)://)?" -"(\\b(?<![.\\@A-Za-z0-9-])" -"(?: [A-Za-z0-9][A-Za-z0-9-]*(?:\\.[A-Za-z0-9-]+)*\\." -"(?i:com|net|org|biz|edu|gov|info|name|int|mil|aero|coop|jobs|mobi|museum|pro|travel" -"|cc|[rs]u|uk|ua|by|de|jp|fr|fi|no|no|ca|it|ro|cn|nl|at|nu|se" -"|[a-z]{2}" -"(?(1)|(?=/)))" -"(?!\\w)" -"|(?:\\d{1,3}\\.){3}\\d{1,3}(?(1)|(?=[/:]))" /* ip in dotted view */ -"|\\d{5,20}(?(1)|(?=[/:]))" /* ip in numeric view */ -")" -"(?::\\d{1,5})?" /* port */ -"(?!\\.\\w)" /* host part ended, no more of this further on */ -"(?:[/?][;/?:@&=+\\$,[\\]\\-_.!~*'()A-Za-z0-9#%]*)?" /* path (&query) */ -"(?<![\\s>?!),.'\"\\]:])" -"(?!@)" -")"; -static const char *html_url = "(?: src|href)=\"?(" -"((https?|ftp)://)?" -"(\\b(?<![.\\@A-Za-z0-9-])" -"(?: [A-Za-z0-9][A-Za-z0-9-]*(?:\\.[A-Za-z0-9-]+)*\\." -"(?i:com|net|org|biz|edu|gov|info|name|int|mil|aero|coop|jobs|mobi|museum|pro|travel" -"|[rs]u|uk|ua|by|de|jp|fr|fi|no|no|ca|it|ro|cn|nl|at|nu|se" -"|[a-z]{2}" -"(?(1)|(?=/)))" -"(?!\\w)" -"|(?:\\d{1,3}\\.){3}\\d{1,3}(?(1)|(?=[/:]))" -")" -"(?::\\d{1,5})?" /* port */ -"(?!\\.\\w)" /* host part ended, no more of this further on */ -"(?:[/?][;/?:@&=+\\$,[\\]\\-_.!~*'()A-Za-z0-9#%]*)?" /* path (&query) */ -"(?<![\\s>?!),.'\"\\]:])" -"(?!@)" -"))\"?"; - -static short url_initialized = 0; -GRegex *text_re, *html_re; - -static const struct _proto protocol_backends[] = { - { "file", 0, NULL, 1, 0, 0, 0 }, - { "ftp", 21, NULL, 1, 1, 0, 0 }, - { "http", 80, NULL, 1, 1, 0, 0 }, - { "https", 443, NULL, 1, 1, 0, 1 }, +static const char *text_url = "((https?|ftp)://)?" "(\\b(?<![.\\@A-Za-z0-9-])" "(?: [A-Za-z0-9][A-Za-z0-9-]*(?:\\.[A-Za-z0-9-]+)*\\." "(?i:com|net|org|biz|edu|gov|info|name|int|mil|aero|coop|jobs|mobi|museum|pro|travel" "|cc|[rs]u|uk|ua|by|de|jp|fr|fi|no|no|ca|it|ro|cn|nl|at|nu|se" "|[a-z]{2}" "(?(1)|(?=/)))" "(?!\\w)" "|(?:\\d{1,3}\\.){3}\\d{1,3}(?(1)|(?=[/:]))" /* ip in dotted view */ + "|\\d{5,20}(?(1)|(?=[/:]))" /* ip in numeric view */ + ")" "(?::\\d{1,5})?" /* port */ + "(?!\\.\\w)" /* host part ended, no more of this further on */ + "(?:[/?][;/?:@&=+\\$,[\\]\\-_.!~*'()A-Za-z0-9#%]*)?" /* path (&query) */ + "(?<![\\s>?!),.'\"\\]:])" "(?!@)" ")"; +static const char *html_url = "(?: src|href)=\"?(" "((https?|ftp)://)?" "(\\b(?<![.\\@A-Za-z0-9-])" "(?: [A-Za-z0-9][A-Za-z0-9-]*(?:\\.[A-Za-z0-9-]+)*\\." "(?i:com|net|org|biz|edu|gov|info|name|int|mil|aero|coop|jobs|mobi|museum|pro|travel" "|[rs]u|uk|ua|by|de|jp|fr|fi|no|no|ca|it|ro|cn|nl|at|nu|se" "|[a-z]{2}" "(?(1)|(?=/)))" "(?!\\w)" "|(?:\\d{1,3}\\.){3}\\d{1,3}(?(1)|(?=[/:]))" ")" "(?::\\d{1,5})?" /* port */ + "(?!\\.\\w)" /* host part ended, no more of this further on */ + "(?:[/?][;/?:@&=+\\$,[\\]\\-_.!~*'()A-Za-z0-9#%]*)?" /* path (&query) */ + "(?<![\\s>?!),.'\"\\]:])" "(?!@)" "))\"?"; + +static short url_initialized = 0; +GRegex *text_re, *html_re; + +static const struct _proto protocol_backends[] = { + {"file", 0, NULL, 1, 0, 0, 0}, + {"ftp", 21, NULL, 1, 1, 0, 0}, + {"http", 80, NULL, 1, 1, 0, 0}, + {"https", 443, NULL, 1, 1, 0, 1}, /* Keep these last! */ - { NULL, 0, NULL, 0, 0, 1, 0 }, + {NULL, 0, NULL, 0, 0, 1, 0}, }; /* @@ -121,11 +97,11 @@ static const struct _proto protocol_backends[] = { lookup. This code assumes ASCII character set and 8-bit chars. */ enum { - /* rfc1738 reserved chars + "$" and ",". */ - urlchr_reserved = 1, + /* rfc1738 reserved chars + "$" and ",". */ + urlchr_reserved = 1, - /* rfc1738 unsafe chars, plus non-printables. */ - urlchr_unsafe = 2 + /* rfc1738 unsafe chars, plus non-printables. */ + urlchr_unsafe = 2 }; #define urlchr_test(c, mask) (urlchr_table[(unsigned char)(c)] & (mask)) @@ -147,97 +123,97 @@ enum { #define U urlchr_unsafe #define RU R|U -static const unsigned char urlchr_table[256] = -{ - U, U, U, U, U, U, U, U, /* NUL SOH STX ETX EOT ENQ ACK BEL */ - U, U, U, U, U, U, U, U, /* BS HT LF VT FF CR SO SI */ - U, U, U, U, U, U, U, U, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ - U, U, U, U, U, U, U, U, /* CAN EM SUB ESC FS GS RS US */ - U, 0, U, RU, R, U, R, 0, /* SP ! " # $ % & ' */ - 0, 0, 0, R, R, 0, 0, R, /* ( ) * + , - . / */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */ - 0, 0, RU, R, U, R, U, R, /* 8 9 : ; < = > ? */ - RU, 0, 0, 0, 0, 0, 0, 0, /* @ A B C D E F G */ - 0, 0, 0, 0, 0, 0, 0, 0, /* H I J K L M N O */ - 0, 0, 0, 0, 0, 0, 0, 0, /* P Q R S T U V W */ - 0, 0, 0, RU, U, RU, U, 0, /* X Y Z [ \ ] ^ _ */ - U, 0, 0, 0, 0, 0, 0, 0, /* ` a b c d e f g */ - 0, 0, 0, 0, 0, 0, 0, 0, /* h i j k l m n o */ - 0, 0, 0, 0, 0, 0, 0, 0, /* p q r s t u v w */ - 0, 0, 0, U, U, U, 0, U, /* x y z { | } ~ DEL */ - - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, - U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, +static const unsigned char urlchr_table[256] = { + U, U, U, U, U, U, U, U, /* NUL SOH STX ETX EOT ENQ ACK BEL */ + U, U, U, U, U, U, U, U, /* BS HT LF VT FF CR SO SI */ + U, U, U, U, U, U, U, U, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ + U, U, U, U, U, U, U, U, /* CAN EM SUB ESC FS GS RS US */ + U, 0, U, RU, R, U, R, 0, /* SP ! " # $ % & ' */ + 0, 0, 0, R, R, 0, 0, R, /* ( ) * + , - . / */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */ + 0, 0, RU, R, U, R, U, R, /* 8 9 : ; < = > ? */ + RU, 0, 0, 0, 0, 0, 0, 0, /* @ A B C D E F G */ + 0, 0, 0, 0, 0, 0, 0, 0, /* H I J K L M N O */ + 0, 0, 0, 0, 0, 0, 0, 0, /* P Q R S T U V W */ + 0, 0, 0, RU, U, RU, U, 0, /* X Y Z [ \ ] ^ _ */ + U, 0, 0, 0, 0, 0, 0, 0, /* ` a b c d e f g */ + 0, 0, 0, 0, 0, 0, 0, 0, /* h i j k l m n o */ + 0, 0, 0, 0, 0, 0, 0, 0, /* p q r s t u v w */ + 0, 0, 0, U, U, U, 0, U, /* x y z { | } ~ DEL */ + + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, }; + #undef R #undef U #undef RU -static const char * +static const char * url_strerror (enum uri_errno err) { switch (err) { - case URI_ERRNO_OK: - return "Parsing went well"; - case URI_ERRNO_EMPTY: - return "The URI string was empty"; - case URI_ERRNO_INVALID_PROTOCOL: - return "No protocol was found"; - case URI_ERRNO_NO_SLASHES: - return "Slashes after protocol missing"; - case URI_ERRNO_TOO_MANY_SLASHES: - return "Too many slashes after protocol"; - case URI_ERRNO_TRAILING_DOTS: - return "'.' after host"; - case URI_ERRNO_NO_HOST: - return "Host part is missing"; - case URI_ERRNO_NO_PORT_COLON: - return "':' after host without port"; - case URI_ERRNO_NO_HOST_SLASH: - return "Slash after host missing"; - case URI_ERRNO_IPV6_SECURITY: - return "IPv6 security bug detected"; - case URI_ERRNO_INVALID_PORT: - return "Port number is bad"; - case URI_ERRNO_INVALID_PORT_RANGE: - return "Port number is not within 0-65535"; + case URI_ERRNO_OK: + return "Parsing went well"; + case URI_ERRNO_EMPTY: + return "The URI string was empty"; + case URI_ERRNO_INVALID_PROTOCOL: + return "No protocol was found"; + case URI_ERRNO_NO_SLASHES: + return "Slashes after protocol missing"; + case URI_ERRNO_TOO_MANY_SLASHES: + return "Too many slashes after protocol"; + case URI_ERRNO_TRAILING_DOTS: + return "'.' after host"; + case URI_ERRNO_NO_HOST: + return "Host part is missing"; + case URI_ERRNO_NO_PORT_COLON: + return "':' after host without port"; + case URI_ERRNO_NO_HOST_SLASH: + return "Slash after host missing"; + case URI_ERRNO_IPV6_SECURITY: + return "IPv6 security bug detected"; + case URI_ERRNO_INVALID_PORT: + return "Port number is bad"; + case URI_ERRNO_INVALID_PORT_RANGE: + return "Port number is not within 0-65535"; } return NULL; } static inline int -end_of_dir(unsigned char c) +end_of_dir (unsigned char c) { return c == POST_CHAR || c == '#' || c == ';' || c == '?'; } static inline int -is_uri_dir_sep(struct uri *uri, unsigned char pos) +is_uri_dir_sep (struct uri *uri, unsigned char pos) { return (pos == '/'); } static int -check_uri_file(unsigned char *name) +check_uri_file (unsigned char *name) { - static const unsigned char chars[] = POST_CHAR_S "#?"; + static const unsigned char chars[] = POST_CHAR_S "#?"; - return strcspn(name, chars); + return strcspn (name, chars); } static int url_init (void) { - GError *err = NULL; + GError *err = NULL; if (url_initialized == 0) { - text_re = g_regex_new (text_url, G_REGEX_CASELESS | G_REGEX_MULTILINE | G_REGEX_OPTIMIZE | G_REGEX_EXTENDED, 0, &err); + text_re = g_regex_new (text_url, G_REGEX_CASELESS | G_REGEX_MULTILINE | G_REGEX_OPTIMIZE | G_REGEX_EXTENDED, 0, &err); if (err != NULL) { msg_info ("url_init: cannot init text url parsing regexp: %s", err->message); g_error_free (err); @@ -256,22 +232,22 @@ url_init (void) } enum protocol -get_protocol(unsigned char *name, int namelen) +get_protocol (unsigned char *name, int namelen) { /* These are really enum protocol values but can take on negative * values and since 0 <= -1 for enum values it's better to use clean * integer type. */ - int start, end; - enum protocol protocol; - unsigned char *pname; - int pnamelen, minlen, compare; + int start, end; + enum protocol protocol; + unsigned char *pname; + int pnamelen, minlen, compare; /* Almost dichotomic search is used here */ /* Starting at the HTTP entry which is the most common that will make * file and NNTP the next entries checked and amongst the third checks * are proxy and FTP. */ - start = 0; - end = PROTOCOL_UNKNOWN - 1; + start = 0; + end = PROTOCOL_UNKNOWN - 1; protocol = PROTOCOL_HTTP; while (start <= end) { @@ -303,33 +279,33 @@ get_protocol(unsigned char *name, int namelen) int -get_protocol_port(enum protocol protocol) +get_protocol_port (enum protocol protocol) { return protocol_backends[protocol].port; } int -get_protocol_need_slashes(enum protocol protocol) +get_protocol_need_slashes (enum protocol protocol) { return protocol_backends[protocol].need_slashes; } int -get_protocol_need_slash_after_host(enum protocol protocol) +get_protocol_need_slash_after_host (enum protocol protocol) { return protocol_backends[protocol].need_slash_after_host; } int -get_protocol_free_syntax(enum protocol protocol) +get_protocol_free_syntax (enum protocol protocol) { return protocol_backends[protocol].free_syntax; } static int -get_protocol_length(const unsigned char *url) +get_protocol_length (const unsigned char *url) { - unsigned char *end = (unsigned char *) url; + unsigned char *end = (unsigned char *)url; /* Seek the end of the protocol name if any. */ /* RFC1738: @@ -349,10 +325,10 @@ get_protocol_length(const unsigned char *url) static unsigned int url_calculate_escaped_hostlen (char *host, unsigned int hostlen) { - unsigned int i, result = hostlen; - char *p = host, c; + unsigned int i, result = hostlen; + char *p = host, c; - for (i = 0; i < hostlen; i ++, p ++) { + for (i = 0; i < hostlen; i++, p++) { if (*p == '%' && g_ascii_isxdigit (*(p + 1)) && g_ascii_isxdigit (*(p + 2)) && i < hostlen - 2) { c = X2DIGITS_TO_NUM (*(p + 1), *(p + 2)); if (c != '\0') { @@ -376,16 +352,16 @@ url_calculate_escaped_hostlen (char *host, unsigned int hostlen) static void url_unescape (char *s) { - char *t = s; /* t - tortoise */ - char *h = s; /* h - hare */ - + char *t = s; /* t - tortoise */ + char *h = s; /* h - hare */ + for (; *h; h++, t++) { if (*h != '%') { - copychar: + copychar: *t = *h; } - else { - char c; + else { + char c; /* Do nothing if '%' is not followed by two hex digits. */ if (!h[1] || !h[2] || !(g_ascii_isxdigit (h[1]) && g_ascii_isxdigit (h[2]))) goto copychar; @@ -404,17 +380,17 @@ url_unescape (char *s) static void url_strip (char *s) { - char *t = s; /* t - tortoise */ - char *h = s; /* h - hare */ - - while (*h) { - if (g_ascii_isgraph (*h)) { - *t = *h; - t ++; - } - h++; - } - *t = '\0'; + char *t = s; /* t - tortoise */ + char *h = s; /* h - hare */ + + while (*h) { + if (g_ascii_isgraph (*h)) { + *t = *h; + t++; + } + h++; + } + *t = '\0'; } /* The core of url_escape_* functions. Escapes the characters that @@ -424,13 +400,13 @@ url_strip (char *s) will be returned unchanged. If ALLOW_PASSTHROUGH is zero, a freshly allocated string will be returned in all cases. */ -static char * -url_escape_1 (const char *s, unsigned char mask, int allow_passthrough, memory_pool_t *pool) +static char * +url_escape_1 (const char *s, unsigned char mask, int allow_passthrough, memory_pool_t * pool) { - const char *p1; - char *p2, *newstr; - int newlen; - int addition = 0; + const char *p1; + char *p2, *newstr; + int newlen; + int addition = 0; for (p1 = s; *p1; p1++) if (urlchr_test (*p1, mask)) @@ -446,14 +422,14 @@ url_escape_1 (const char *s, unsigned char mask, int allow_passthrough, memory_p } newlen = (p1 - s) + addition; - newstr = (char *) memory_pool_alloc (pool, newlen + 1); + newstr = (char *)memory_pool_alloc (pool, newlen + 1); p1 = s; p2 = newstr; while (*p1) { /* Quote the characters that match the test mask. */ if (urlchr_test (*p1, mask)) { - unsigned char c = *p1++; + unsigned char c = *p1++; *p2++ = '%'; *p2++ = XNUM_TO_DIGIT (c >> 4); *p2++ = XNUM_TO_DIGIT (c & 0xf); @@ -469,8 +445,8 @@ url_escape_1 (const char *s, unsigned char mask, int allow_passthrough, memory_p /* URL-escape the unsafe characters (see urlchr_table) in a given string, returning a freshly allocated string. */ -char * -url_escape (const char *s, memory_pool_t *pool) +char * +url_escape (const char *s, memory_pool_t * pool) { return url_escape_1 (s, urlchr_unsafe, 0, pool); } @@ -478,8 +454,8 @@ url_escape (const char *s, memory_pool_t *pool) /* URL-escape the unsafe characters (see urlchr_table) in a given string. If no characters are unsafe, S is returned. */ -static char * -url_escape_allow_passthrough (const char *s, memory_pool_t *pool) +static char * +url_escape_allow_passthrough (const char *s, memory_pool_t * pool) { return url_escape_1 (s, urlchr_unsafe, 1, pool); } @@ -518,14 +494,14 @@ char_needs_escaping (const char *p) further transformations of the result yield the same output. */ -static char * -reencode_escapes (char *s, memory_pool_t *pool) +static char * +reencode_escapes (char *s, memory_pool_t * pool) { - const char *p1; - char *newstr, *p2; - int oldlen, newlen; + const char *p1; + char *newstr, *p2; + int oldlen, newlen; - int encode_count = 0; + int encode_count = 0; /* First pass: inspect the string to see if there's anything to do, and to calculate the new length. */ @@ -549,19 +525,20 @@ reencode_escapes (char *s, memory_pool_t *pool) p2 = newstr; while (*p1) - if (char_needs_escaping (p1)) { - unsigned char c = *p1++; - *p2++ = '%'; - *p2++ = XNUM_TO_DIGIT (c >> 4); - *p2++ = XNUM_TO_DIGIT (c & 0xf); - } - else { - *p2++ = *p1++; - } + if (char_needs_escaping (p1)) { + unsigned char c = *p1++; + *p2++ = '%'; + *p2++ = XNUM_TO_DIGIT (c >> 4); + *p2++ = XNUM_TO_DIGIT (c & 0xf); + } + else { + *p2++ = *p1++; + } *p2 = '\0'; return newstr; } + /* Unescape CHR in an otherwise escaped STR. Used to selectively escaping of certain characters, such as "/" and ":". Returns a count of unescaped chars. */ @@ -569,17 +546,17 @@ reencode_escapes (char *s, memory_pool_t *pool) static void unescape_single_char (char *str, char chr) { - const char c1 = XNUM_TO_DIGIT (chr >> 4); - const char c2 = XNUM_TO_DIGIT (chr & 0xf); - char *h = str; /* hare */ - char *t = str; /* tortoise */ + const char c1 = XNUM_TO_DIGIT (chr >> 4); + const char c2 = XNUM_TO_DIGIT (chr & 0xf); + char *h = str; /* hare */ + char *t = str; /* tortoise */ for (; *h; h++, t++) { if (h[0] == '%' && h[1] == c1 && h[2] == c2) { *t = chr; h += 2; } - else { + else { *t = *h; } } @@ -589,10 +566,10 @@ unescape_single_char (char *str, char chr) /* Escape unsafe and reserved characters, except for the slash characters. */ -static char * -url_escape_dir (const char *dir, memory_pool_t *pool) +static char * +url_escape_dir (const char *dir, memory_pool_t * pool) { - char *newdir = url_escape_1 (dir, urlchr_unsafe | urlchr_reserved, 1, pool); + char *newdir = url_escape_1 (dir, urlchr_unsafe | urlchr_reserved, 1, pool); if (newdir == dir) return (char *)dir; @@ -617,53 +594,53 @@ url_escape_dir (const char *dir, memory_pool_t *pool) static int path_simplify (char *path) { - char *h = path; /* hare */ - char *t = path; /* tortoise */ - char *beg = path; /* boundary for backing the tortoise */ - char *end = path + strlen (path); + char *h = path; /* hare */ + char *t = path; /* tortoise */ + char *beg = path; /* boundary for backing the tortoise */ + char *end = path + strlen (path); while (h < end) { /* Hare should be at the beginning of a path element. */ if (h[0] == '.' && (h[1] == '/' || h[1] == '\0')) { - /* Ignore "./". */ - h += 2; + /* Ignore "./". */ + h += 2; } else if (h[0] == '.' && h[1] == '.' && (h[2] == '/' || h[2] == '\0')) { - /* Handle "../" by retreating the tortoise by one path - element -- but not past beggining. */ + /* Handle "../" by retreating the tortoise by one path + element -- but not past beggining. */ if (t > beg) { - /* Move backwards until T hits the beginning of the - previous path element or the beginning of path. */ + /* Move backwards until T hits the beginning of the + previous path element or the beginning of path. */ for (--t; t > beg && t[-1] != '/'; t--); - } - else { - /* If we're at the beginning, copy the "../" literally - move the beginning so a later ".." doesn't remove - it. */ + } + else { + /* If we're at the beginning, copy the "../" literally + move the beginning so a later ".." doesn't remove + it. */ beg = t + 3; goto regular; } h += 3; } else { - regular: + regular: /* A regular path element. If H hasn't advanced past T, - simply skip to the next path element. Otherwise, copy - the path element until the next slash. */ + simply skip to the next path element. Otherwise, copy + the path element until the next slash. */ if (t == h) { - /* Skip the path element, including the slash. */ + /* Skip the path element, including the slash. */ while (h < end && *h != '/') t++, h++; if (h < end) t++, h++; - } - else { - /* Copy the path element, including the final slash. */ - while (h < end && *h != '/') + } + else { + /* Copy the path element, including the final slash. */ + while (h < end && *h != '/') *t++ = *h++; - if (h < end) + if (h < end) *t++ = *h++; - } + } } } @@ -674,24 +651,25 @@ path_simplify (char *path) } enum uri_errno -parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) +parse_uri (struct uri *uri, unsigned char *uristring, memory_pool_t * pool) { - unsigned char *prefix_end, *host_end, *p; - unsigned char *lbracket, *rbracket; - int datalen, n, addrlen; - unsigned char *frag_or_post, *user_end, *port_end; + unsigned char *prefix_end, *host_end, *p; + unsigned char *lbracket, *rbracket; + int datalen, n, addrlen; + unsigned char *frag_or_post, *user_end, *port_end; memset (uri, 0, sizeof (*uri)); /* Nothing to do for an empty url. */ - if (!*uristring) return URI_ERRNO_EMPTY; - + if (!*uristring) + return URI_ERRNO_EMPTY; + uri->string = reencode_escapes (uristring, pool); msg_debug ("parse_uri: reencoding escapes in original url: '%s'", struri (uri)); uri->protocollen = get_protocol_length (struri (uri)); /* Assume http as default protocol */ - if (!uri->protocollen || (uri->protocol = get_protocol (struri(uri), uri->protocollen)) == PROTOCOL_UNKNOWN) { + if (!uri->protocollen || (uri->protocol = get_protocol (struri (uri), uri->protocollen)) == PROTOCOL_UNKNOWN) { p = g_strconcat ("http://", uri->string, NULL); uri->string = memory_pool_strdup (pool, p); g_free (p); @@ -702,7 +680,7 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) /* Figure out whether the protocol is known */ msg_debug ("parse_uri: getting protocol from url: %d", uri->protocol); - prefix_end = struri (uri) + uri->protocollen; /* ':' */ + prefix_end = struri (uri) + uri->protocollen; /* ':' */ /* Check if there's a digit after the protocol name. */ if (g_ascii_isdigit (*prefix_end)) { @@ -726,7 +704,8 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) prefix_end += 2; - } else { + } + else { msg_debug ("parse_uri: no '/' in uri"); return URI_ERRNO_NO_SLASHES; } @@ -737,7 +716,8 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) uri->datalen = strlen (prefix_end); return URI_ERRNO_OK; - } else if (uri->protocol == PROTOCOL_FILE) { + } + else if (uri->protocol == PROTOCOL_FILE) { datalen = check_uri_file (prefix_end); frag_or_post = prefix_end + datalen; @@ -745,14 +725,15 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) if (datalen >= 0) { if (*frag_or_post == '#') { uri->fragment = frag_or_post + 1; - uri->fragmentlen = strcspn(uri->fragment, POST_CHAR_S); + uri->fragmentlen = strcspn (uri->fragment, POST_CHAR_S); frag_or_post = uri->fragment + uri->fragmentlen; } if (*frag_or_post == POST_CHAR) { uri->post = frag_or_post + 1; } - } else { - datalen = strlen(prefix_end); + } + else { + datalen = strlen (prefix_end); } uri->data = prefix_end; @@ -772,15 +753,15 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) uri->ipv6 = 1; else lbracket = rbracket = NULL; - } else { + } + else { rbracket = NULL; } /* Possibly skip auth part */ host_end = prefix_end + strcspn (prefix_end, "@"); - if (prefix_end + strcspn (prefix_end, "/") > host_end - && *host_end) { /* we have auth info here */ + if (prefix_end + strcspn (prefix_end, "/") > host_end && *host_end) { /* we have auth info here */ /* Allow '@' in the password component */ while (strcspn (host_end + 1, "@") < strcspn (host_end + 1, "/?")) @@ -791,7 +772,8 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) if (!user_end || user_end > host_end) { uri->user = prefix_end; uri->userlen = host_end - prefix_end; - } else { + } + else { uri->user = prefix_end; uri->userlen = user_end - prefix_end; uri->password = user_end + 1; @@ -811,7 +793,8 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) uri->host = lbracket + 1; uri->hostlen = addrlen; - } else { + } + else { uri->host = prefix_end; uri->hostlen = host_end - prefix_end; @@ -820,7 +803,7 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) return URI_ERRNO_TRAILING_DOTS; } - if (*host_end == ':') { /* we have port here */ + if (*host_end == ':') { /* we have port here */ port_end = host_end + 1 + strcspn (host_end + 1, "/"); host_end++; @@ -854,7 +837,8 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) if (*host_end == '/') { host_end++; - } else if (get_protocol_need_slash_after_host (uri->protocol) && *host_end != '?') { + } + else if (get_protocol_need_slash_after_host (uri->protocol) && *host_end != '?') { /* The need for slash after the host component depends on the * need for a host component. -- The dangerous mind of Jonah */ if (!uri->hostlen) @@ -877,13 +861,13 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) if (*prefix_end == POST_CHAR) { uri->post = prefix_end + 1; } - + convert_to_lowercase (uri->string, uri->protocollen); convert_to_lowercase (uri->host, uri->hostlen); /* Decode %HH sequences in host name. This is important not so much - to support %HH sequences in host names (which other browser - don't), but to support binary characters (which will have been - converted to %HH by reencode_escapes). */ + to support %HH sequences in host names (which other browser + don't), but to support binary characters (which will have been + converted to %HH by reencode_escapes). */ if (strchr (uri->host, '%')) { uri->hostlen = url_calculate_escaped_hostlen (uri->host, uri->hostlen); } @@ -896,15 +880,15 @@ parse_uri(struct uri *uri, unsigned char *uristring, memory_pool_t *pool) return URI_ERRNO_OK; } -void -url_parse_text (memory_pool_t *pool, struct worker_task *task, struct mime_text_part *part, gboolean is_html) +void +url_parse_text (memory_pool_t * pool, struct worker_task *task, struct mime_text_part *part, gboolean is_html) { - GMatchInfo *info; - GError *err = NULL; - int rc; - char *url_str = NULL; - struct uri *new; - + GMatchInfo *info; + GError *err = NULL; + int rc; + char *url_str = NULL; + struct uri *new; + if (!part->orig->data || part->orig->len == 0) { msg_warn ("url_parse_text: got empty text part"); return; @@ -916,7 +900,7 @@ url_parse_text (memory_pool_t *pool, struct worker_task *task, struct mime_text_ } else { rc = g_regex_match_full (text_re, (const char *)part->content->data, part->content->len, 0, 0, &info, &err); - + } if (rc) { while (g_match_info_matches (info)) { @@ -937,7 +921,7 @@ url_parse_text (memory_pool_t *pool, struct worker_task *task, struct mime_text_ } } } - memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, url_str); + memory_pool_add_destructor (task->task_pool, (pool_destruct_func) g_free, url_str); /* Get next match */ g_match_info_next (info, &err); } diff --git a/src/util.c b/src/util.c index 26e9dbd32..59de138aa 100644 --- a/src/util.c +++ b/src/util.c @@ -36,27 +36,27 @@ #define CONNECT_TIMEOUT 3 #ifdef RSPAMD_MAIN -sig_atomic_t do_reopen_log = 0; -extern rspamd_hash_t *counters; +sig_atomic_t do_reopen_log = 0; +extern rspamd_hash_t *counters; #endif struct logger_params { - GLogFunc log_func; - struct config_file *cfg; + GLogFunc log_func; + struct config_file *cfg; }; -static struct logger_params log_params; +static struct logger_params log_params; /* Here would be put log messages intensity */ -static uint32_t log_written; -static time_t last_check; -static char *io_buf = NULL; -static gboolean log_buffered = FALSE; +static uint32_t log_written; +static time_t last_check; +static char *io_buf = NULL; +static gboolean log_buffered = FALSE; int make_socket_nonblocking (int fd) { - int ofl; + int ofl; ofl = fcntl (fd, F_GETFL, 0); @@ -69,8 +69,8 @@ make_socket_nonblocking (int fd) int make_socket_blocking (int fd) -{ - int ofl; +{ + int ofl; ofl = fcntl (fd, F_GETFL, 0); @@ -81,11 +81,11 @@ make_socket_blocking (int fd) return 0; } -int +int poll_sync_socket (int fd, int timeout, short events) { - int r; - struct pollfd fds[1]; + int r; + struct pollfd fds[1]; fds->fd = fd; fds->events = events; @@ -102,10 +102,10 @@ poll_sync_socket (int fd, int timeout, short events) static int make_inet_socket (int family, struct in_addr *addr, u_short port, gboolean is_server, gboolean async) { - int fd, r, optlen, on = 1, s_error; - int serrno; - struct sockaddr_in sin; - + int fd, r, optlen, on = 1, s_error; + int serrno; + struct sockaddr_in sin; + /* Create socket */ fd = socket (AF_INET, family, 0); if (fd == -1) { @@ -116,20 +116,20 @@ make_inet_socket (int family, struct in_addr *addr, u_short port, gboolean is_se if (make_socket_nonblocking (fd) < 0) { goto out; } - + /* Set close on exec */ if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) { msg_warn ("make_tcp_socket: fcntl failed: %d, '%s'", errno, strerror (errno)); goto out; } - + /* Bind options */ sin.sin_family = AF_INET; sin.sin_port = htons (port); sin.sin_addr.s_addr = addr->s_addr; - + if (is_server) { - setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(int)); + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (int)); r = bind (fd, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); } else { @@ -158,8 +158,8 @@ make_inet_socket (int family, struct in_addr *addr, u_short port, gboolean is_se } else { /* Still need to check SO_ERROR on socket */ - optlen = sizeof(s_error); - getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&s_error, &optlen); + optlen = sizeof (s_error); + getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *)&s_error, &optlen); if (s_error) { errno = s_error; goto out; @@ -169,7 +169,7 @@ make_inet_socket (int family, struct in_addr *addr, u_short port, gboolean is_se return (fd); - out: + out: serrno = errno; close (fd); errno = serrno; @@ -179,32 +179,32 @@ make_inet_socket (int family, struct in_addr *addr, u_short port, gboolean is_se int make_tcp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) { - return make_inet_socket (SOCK_STREAM, addr, port, is_server, async); + return make_inet_socket (SOCK_STREAM, addr, port, is_server, async); } int make_udp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) { - return make_inet_socket (SOCK_DGRAM, addr, port, is_server, async); + return make_inet_socket (SOCK_DGRAM, addr, port, is_server, async); } int -accept_from_socket (int listen_sock, struct sockaddr *addr, socklen_t *len) +accept_from_socket (int listen_sock, struct sockaddr *addr, socklen_t * len) { - int nfd; - int serrno; + int nfd; + int serrno; if ((nfd = accept (listen_sock, addr, len)) == -1) { if (errno == EAGAIN) { - return 0; + return 0; } msg_warn ("accept_from_socket: accept failed: %d, '%s'", errno, strerror (errno)); return -1; } - if (make_socket_nonblocking(nfd) < 0) { + if (make_socket_nonblocking (nfd) < 0) { goto out; } - + /* Set close on exec */ if (fcntl (nfd, F_SETFD, FD_CLOEXEC) == -1) { msg_warn ("accept_from_socket: fcntl failed: %d, '%s'", errno, strerror (errno)); @@ -215,7 +215,7 @@ accept_from_socket (int listen_sock, struct sockaddr *addr, socklen_t *len) return (nfd); - out: + out: serrno = errno; close (nfd); errno = serrno; @@ -226,37 +226,38 @@ accept_from_socket (int listen_sock, struct sockaddr *addr, socklen_t *len) int make_unix_socket (const char *path, struct sockaddr_un *addr, gboolean is_server) { - size_t len = strlen (path); - int fd, s_error, r, optlen, serrno, on = 1; + size_t len = strlen (path); + int fd, s_error, r, optlen, serrno, on = 1; - if (len > sizeof (addr->sun_path) - 1 || path == NULL) return -1; - - #ifdef FREEBSD + if (len > sizeof (addr->sun_path) - 1 || path == NULL) + return -1; + +#ifdef FREEBSD addr->sun_len = sizeof (struct sockaddr_un); - #endif +#endif addr->sun_family = AF_UNIX; - + strncpy (addr->sun_path, path, len); - + fd = socket (PF_LOCAL, SOCK_STREAM, 0); - + if (fd == -1) { msg_warn ("make_unix_socket: socket failed: %d, '%s'", errno, strerror (errno)); return -1; } - if (make_socket_nonblocking(fd) < 0) { + if (make_socket_nonblocking (fd) < 0) { goto out; } - + /* Set close on exec */ if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) { msg_warn ("make_unix_socket: fcntl failed: %d, '%s'", errno, strerror (errno)); goto out; } if (is_server) { - setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(int)); + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (int)); r = bind (fd, (struct sockaddr *)addr, sizeof (struct sockaddr_in)); } else { @@ -271,7 +272,7 @@ make_unix_socket (const char *path, struct sockaddr_un *addr, gboolean is_server } else { /* Still need to check SO_ERROR on socket */ - optlen = sizeof(s_error); + optlen = sizeof (s_error); getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *)&s_error, &optlen); if (s_error) { errno = s_error; @@ -282,7 +283,7 @@ make_unix_socket (const char *path, struct sockaddr_un *addr, gboolean is_server return (fd); - out: + out: serrno = errno; close (fd); errno = serrno; @@ -292,7 +293,7 @@ make_unix_socket (const char *path, struct sockaddr_un *addr, gboolean is_server int write_pid (struct rspamd_main *main) { - pid_t pid; + pid_t pid; main->pfh = pidfile_open (main->cfg->pid_file, 0644, &pid); if (main->pfh == NULL) { @@ -307,7 +308,7 @@ write_pid (struct rspamd_main *main) void init_signals (struct sigaction *signals, sig_t sig_handler) { - struct sigaction sigpipe_act; + struct sigaction sigpipe_act; /* Setting up signal handlers */ /* SIGUSR1 - reopen config file */ /* SIGUSR2 - worker is ready for accept */ @@ -330,7 +331,7 @@ init_signals (struct sigaction *signals, sig_t sig_handler) sigaction (SIGUSR1, signals, NULL); sigaction (SIGUSR2, signals, NULL); sigaction (SIGALRM, signals, NULL); - + /* Ignore SIGPIPE as we handle write errors manually */ sigemptyset (&sigpipe_act.sa_mask); sigaddset (&sigpipe_act.sa_mask, SIGPIPE); @@ -340,10 +341,10 @@ init_signals (struct sigaction *signals, sig_t sig_handler) } void -pass_signal_worker (GList *workers, int signo) +pass_signal_worker (GList * workers, int signo) { - struct rspamd_worker *cur; - GList *l; + struct rspamd_worker *cur; + GList *l; l = workers; while (l) { @@ -353,19 +354,20 @@ pass_signal_worker (GList *workers, int signo) } } -void convert_to_lowercase (char *str, unsigned int size) +void +convert_to_lowercase (char *str, unsigned int size) { while (size--) { *str = g_ascii_tolower (*str); - str ++; + str++; } } #ifndef HAVE_SETPROCTITLE -static char *title_buffer = 0; -static size_t title_buffer_size = 0; -static char *title_progname, *title_progname_full; +static char *title_buffer = 0; +static size_t title_buffer_size = 0; +static char *title_progname, *title_progname_full; int setproctitle (const char *fmt, ...) @@ -377,28 +379,24 @@ setproctitle (const char *fmt, ...) memset (title_buffer, '\0', title_buffer_size); - ssize_t written; + ssize_t written; if (fmt) { - ssize_t written2; - va_list ap; + ssize_t written2; + va_list ap; written = snprintf (title_buffer, title_buffer_size, "%s: ", title_progname); if (written < 0 || (size_t) written >= title_buffer_size) return -1; va_start (ap, fmt); - written2 = - vsnprintf (title_buffer + written, - title_buffer_size - written, fmt, ap); + written2 = vsnprintf (title_buffer + written, title_buffer_size - written, fmt, ap); va_end (ap); - if (written2 < 0 - || (size_t) written2 >= title_buffer_size - written) + if (written2 < 0 || (size_t) written2 >= title_buffer_size - written) return -1; - } else { - written = - snprintf (title_buffer, title_buffer_size, "%s", - title_progname); + } + else { + written = snprintf (title_buffer, title_buffer_size, "%s", title_progname); if (written < 0 || (size_t) written >= title_buffer_size) return -1; } @@ -417,8 +415,8 @@ setproctitle (const char *fmt, ...) int init_title (int argc, char *argv[], char *envp[]) { - char *begin_of_buffer = 0, *end_of_buffer = 0; - int i; + char *begin_of_buffer = 0, *end_of_buffer = 0; + int i; for (i = 0; i < argc; ++i) { if (!begin_of_buffer) @@ -431,13 +429,13 @@ init_title (int argc, char *argv[], char *envp[]) if (!begin_of_buffer) begin_of_buffer = envp[i]; if (!end_of_buffer || end_of_buffer + 1 == envp[i]) - end_of_buffer = envp[i] + strlen(envp[i]); + end_of_buffer = envp[i] + strlen (envp[i]); } if (!end_of_buffer) return 0; - char **new_environ = g_malloc ((i + 1) * sizeof (envp[0])); + char **new_environ = g_malloc ((i + 1) * sizeof (envp[0])); if (!new_environ) return 0; @@ -454,7 +452,7 @@ init_title (int argc, char *argv[], char *envp[]) if (!title_progname_full) goto cleanup_enomem; - char *p = strrchr (title_progname_full, '/'); + char *p = strrchr (title_progname_full, '/'); if (p) title_progname = p + 1; @@ -471,7 +469,7 @@ init_title (int argc, char *argv[], char *envp[]) return 0; - cleanup_enomem: + cleanup_enomem: for (--i; i >= 0; --i) { g_free (new_environ[i]); } @@ -481,13 +479,13 @@ init_title (int argc, char *argv[], char *envp[]) #endif #ifndef HAVE_PIDFILE -extern char * __progname; -static int _pidfile_remove (struct pidfh *pfh, int freeit); +extern char *__progname; +static int _pidfile_remove (struct pidfh *pfh, int freeit); static int pidfile_verify (struct pidfh *pfh) { - struct stat sb; + struct stat sb; if (pfh == NULL || pfh->pf_fd == -1) return (-1); @@ -502,17 +500,17 @@ pidfile_verify (struct pidfh *pfh) } static int -pidfile_read (const char *path, pid_t *pidptr) +pidfile_read (const char *path, pid_t * pidptr) { - char buf[16], *endptr; - int error, fd, i; + char buf[16], *endptr; + int error, fd, i; fd = open (path, O_RDONLY); if (fd == -1) return (errno); - i = read (fd, buf, sizeof(buf) - 1); - error = errno; /* Remember errno in case close() wants to change it. */ + i = read (fd, buf, sizeof (buf) - 1); + error = errno; /* Remember errno in case close() wants to change it. */ close (fd); if (i == -1) return error; @@ -527,24 +525,22 @@ pidfile_read (const char *path, pid_t *pidptr) return 0; } -struct pidfh * -pidfile_open (const char *path, mode_t mode, pid_t *pidptr) +struct pidfh * +pidfile_open (const char *path, mode_t mode, pid_t * pidptr) { - struct pidfh *pfh; - struct stat sb; - int error, fd, len, count; - struct timespec rqtp; + struct pidfh *pfh; + struct stat sb; + int error, fd, len, count; + struct timespec rqtp; - pfh = g_malloc (sizeof(*pfh)); + pfh = g_malloc (sizeof (*pfh)); if (pfh == NULL) return NULL; if (path == NULL) - len = snprintf (pfh->pf_path, sizeof(pfh->pf_path), - "/var/run/%s.pid", __progname); + len = snprintf (pfh->pf_path, sizeof (pfh->pf_path), "/var/run/%s.pid", __progname); else - len = snprintf (pfh->pf_path, sizeof(pfh->pf_path), - "%s", path); + len = snprintf (pfh->pf_path, sizeof (pfh->pf_path), "%s", path); if (len >= (int)sizeof (pfh->pf_path)) { g_free (pfh); errno = ENAMETOOLONG; @@ -557,15 +553,14 @@ pidfile_open (const char *path, mode_t mode, pid_t *pidptr) * PID file will be truncated again in pidfile_write(), so * pidfile_write() can be called multiple times. */ - fd = open (pfh->pf_path, - O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode); + fd = open (pfh->pf_path, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, mode); flock (fd, LOCK_EX | LOCK_NB); if (fd == -1) { count = 0; rqtp.tv_sec = 0; rqtp.tv_nsec = 5000000; if (errno == EWOULDBLOCK && pidptr != NULL) { - again: + again: errno = pidfile_read (pfh->pf_path, pidptr); if (errno == 0) errno = EEXIST; @@ -602,8 +597,8 @@ pidfile_open (const char *path, mode_t mode, pid_t *pidptr) int pidfile_write (struct pidfh *pfh) { - char pidstr[16]; - int error, fd; + char pidstr[16]; + int error, fd; /* * Check remembered descriptor, so we don't overwrite some other @@ -628,8 +623,8 @@ pidfile_write (struct pidfh *pfh) return -1; } - snprintf (pidstr, sizeof(pidstr), "%u", getpid ()); - if (pwrite (fd, pidstr, strlen (pidstr), 0) != (ssize_t)strlen (pidstr)) { + snprintf (pidstr, sizeof (pidstr), "%u", getpid ()); + if (pwrite (fd, pidstr, strlen (pidstr), 0) != (ssize_t) strlen (pidstr)) { error = errno; _pidfile_remove (pfh, 0); errno = error; @@ -642,7 +637,7 @@ pidfile_write (struct pidfh *pfh) int pidfile_close (struct pidfh *pfh) { - int error; + int error; error = pidfile_verify (pfh); if (error != 0) { @@ -663,7 +658,7 @@ pidfile_close (struct pidfh *pfh) static int _pidfile_remove (struct pidfh *pfh, int freeit) { - int error; + int error; error = pidfile_verify (pfh); if (error != 0) { @@ -706,46 +701,46 @@ int open_log (struct config_file *cfg) { switch (cfg->log_type) { - case RSPAMD_LOG_CONSOLE: - /* Do nothing with console */ - return 0; - case RSPAMD_LOG_SYSLOG: - openlog ("rspamd", LOG_NDELAY | LOG_PID, cfg->log_facility); - return 0; - case RSPAMD_LOG_FILE: - cfg->log_fd = open (cfg->log_file, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); - if (cfg->log_fd == -1) { - fprintf (stderr, "open_log: cannot open desired log file: %s, %s", cfg->log_file, strerror (errno)); - return -1; - } - cfg->logf = fdopen (cfg->log_fd, "w"); - /* Set line buffering */ - setvbuf (cfg->logf, (char *) NULL, _IOLBF, 0); - return 0; + case RSPAMD_LOG_CONSOLE: + /* Do nothing with console */ + return 0; + case RSPAMD_LOG_SYSLOG: + openlog ("rspamd", LOG_NDELAY | LOG_PID, cfg->log_facility); + return 0; + case RSPAMD_LOG_FILE: + cfg->log_fd = open (cfg->log_file, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); + if (cfg->log_fd == -1) { + fprintf (stderr, "open_log: cannot open desired log file: %s, %s", cfg->log_file, strerror (errno)); + return -1; + } + cfg->logf = fdopen (cfg->log_fd, "w"); + /* Set line buffering */ + setvbuf (cfg->logf, (char *)NULL, _IOLBF, 0); + return 0; } return -1; } -void +void close_log (struct config_file *cfg) { switch (cfg->log_type) { - case RSPAMD_LOG_CONSOLE: - /* Do nothing with console */ - break; - case RSPAMD_LOG_SYSLOG: - closelog (); - break; - case RSPAMD_LOG_FILE: - if (cfg->logf != NULL) { - if (fsync (cfg->log_fd) == -1) { - msg_err ("close_log: error syncing log file: %s", strerror (errno)); - } - fclose (cfg->logf); - /* XXX: I think this is not needed */ - close (cfg->log_fd); + case RSPAMD_LOG_CONSOLE: + /* Do nothing with console */ + break; + case RSPAMD_LOG_SYSLOG: + closelog (); + break; + case RSPAMD_LOG_FILE: + if (cfg->logf != NULL) { + if (fsync (cfg->log_fd) == -1) { + msg_err ("close_log: error syncing log file: %s", strerror (errno)); } - break; + fclose (cfg->logf); + /* XXX: I think this is not needed */ + close (cfg->log_fd); + } + break; } } @@ -770,8 +765,8 @@ reopen_log (struct config_file *cfg) void rspamd_log_function (GLogLevelFlags log_level, const char *fmt, ...) { - static char logbuf[BUFSIZ]; - va_list vp; + static char logbuf[BUFSIZ]; + va_list vp; if (log_level <= log_params.cfg->log_level) { va_start (vp, fmt); @@ -782,9 +777,9 @@ rspamd_log_function (GLogLevelFlags log_level, const char *fmt, ...) } void -syslog_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer arg) +syslog_log_function (const gchar * log_domain, GLogLevelFlags log_level, const gchar * message, gpointer arg) { - struct config_file *cfg = (struct config_file *)arg; + struct config_file *cfg = (struct config_file *)arg; #ifdef RSPAMD_MAIN if (do_reopen_log) { reopen_log (cfg); @@ -808,13 +803,13 @@ syslog_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gc } void -file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer arg) +file_log_function (const gchar * log_domain, GLogLevelFlags log_level, const gchar * message, gpointer arg) { - struct config_file *cfg = (struct config_file *)arg; - char tmpbuf[128], timebuf[32]; - time_t now; - struct tm *tms; - + struct config_file *cfg = (struct config_file *)arg; + char tmpbuf[128], timebuf[32]; + time_t now; + struct tm *tms; + if (cfg->log_fd == -1 || cfg->logf == NULL) { return; } @@ -852,18 +847,18 @@ file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gcha strftime (timebuf, sizeof (timebuf), "%b %d %H:%M:%S", tms); snprintf (tmpbuf, sizeof (tmpbuf), "#%d: %s rspamd ", (int)getpid (), timebuf); fprintf (cfg->logf, "%s%s" CRLF, tmpbuf, message); - log_written ++; + log_written++; } } /* Replace %r with rcpt value and %f with from value, new string is allocated in pool */ -char * -resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from) +char * +resolve_stat_filename (memory_pool_t * pool, char *pattern, char *rcpt, char *from) { - int need_to_format = 0, len = 0; - int rcptlen, fromlen; - char *c = pattern, *new, *s; - + int need_to_format = 0, len = 0; + int rcptlen, fromlen; + char *c = pattern, *new, *s; + if (rcpt) { rcptlen = strlen (rcpt); } @@ -892,21 +887,21 @@ resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *fro need_to_format = 1; continue; } - len ++; + len++; } - + /* Do not allocate extra memory if we do not need to format string */ if (!need_to_format) { return pattern; } - + /* Allocate new string */ new = memory_pool_alloc (pool, len); c = pattern; s = new; - + /* Format string */ - while (*c ++) { + while (*c++) { if (*c == '%' && *(c + 1) == 'r') { c += 2; memcpy (s, rcpt, rcptlen); @@ -919,22 +914,22 @@ resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *fro s += fromlen; continue; } - *s ++ = *c; + *s++ = *c; } - + *s = '\0'; return new; } -const char * +const char * calculate_check_time (struct timespec *begin, int resolution) { - struct timespec ts; - double diff; - static char res[sizeof("100000.000")]; - static char fmt[sizeof("%.10f")]; - + struct timespec ts; + double diff; + static char res[sizeof ("100000.000")]; + static char fmt[sizeof ("%.10f")]; + #ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts); #elif defined(HAVE_CLOCK_VIRTUAL) @@ -943,8 +938,8 @@ calculate_check_time (struct timespec *begin, int resolution) clock_gettime (CLOCK_REALTIME, &ts); #endif - diff = (ts.tv_sec - begin->tv_sec) * 1000. + /* Seconds */ - (ts.tv_nsec - begin->tv_nsec) / 1000000.; /* Nanoseconds */ + diff = (ts.tv_sec - begin->tv_sec) * 1000. + /* Seconds */ + (ts.tv_nsec - begin->tv_nsec) / 1000000.; /* Nanoseconds */ sprintf (fmt, "%%.%df", resolution); snprintf (res, sizeof (res), fmt, diff); @@ -955,18 +950,18 @@ double set_counter (const char *name, long int value) { #ifdef RSPAMD_MAIN - struct counter_data *cd; - double alpha; - char *key; - - cd = rspamd_hash_lookup (counters, (gpointer)name); + struct counter_data *cd; + double alpha; + char *key; + + cd = rspamd_hash_lookup (counters, (gpointer) name); if (cd == NULL) { cd = memory_pool_alloc_shared (counters->pool, sizeof (struct counter_data)); cd->value = value; cd->number = 0; key = memory_pool_strdup_shared (counters->pool, name); - rspamd_hash_insert (counters, (gpointer)key, (gpointer)cd); + rspamd_hash_insert (counters, (gpointer) key, (gpointer) cd); } else { /* Calculate new value */ @@ -985,13 +980,13 @@ set_counter (const char *name, long int value) } #ifndef g_tolower -#define g_tolower(x) (((x) >= 'A' && (x) <= 'Z') ? (x) - 'A' + 'a' : (x)) +# define g_tolower(x) (((x) >= 'A' && (x) <= 'Z') ? (x) - 'A' + 'a' : (x)) #endif gboolean rspamd_strcase_equal (gconstpointer v, gconstpointer v2) { - if (g_ascii_strcasecmp ((const char *) v, (const char *) v2) == 0) { + if (g_ascii_strcasecmp ((const char *)v, (const char *)v2) == 0) { return TRUE; } @@ -1002,24 +997,24 @@ rspamd_strcase_equal (gconstpointer v, gconstpointer v2) guint rspamd_strcase_hash (gconstpointer key) { - const char *p = key; - guint h = 0; - + const char *p = key; + guint h = 0; + while (*p != '\0') { h = (h << 5) - h + g_tolower (*p); p++; } - + return h; } -void +void gperf_profiler_init (struct config_file *cfg, const char *descr) { #if defined(WITH_GPERF_TOOLS) && defined(RSPAMD_MAIN) - char prof_path[PATH_MAX]; + char prof_path[PATH_MAX]; - if (getenv("CPUPROFILE")) { + if (getenv ("CPUPROFILE")) { /* disable inherited Profiler enabled in master process */ ProfilerStop (); @@ -1032,7 +1027,7 @@ gperf_profiler_init (struct config_file *cfg, const char *descr) snprintf (prof_path, sizeof (prof_path), "%s-%s.%d", cfg->profile_path, descr, (int)getpid ()); if (ProfilerStart (prof_path)) { /* start ITIMER_PROF timer */ - ProfilerRegisterThread(); + ProfilerRegisterThread (); } else { msg_warn ("gperf_frofiler_init: cannot start google perftools profiler"); diff --git a/src/view.c b/src/view.c index efad70666..3acd165ed 100644 --- a/src/view.c +++ b/src/view.c @@ -30,10 +30,10 @@ #include "cfg_file.h" #include "map.h" -struct rspamd_view* -init_view (memory_pool_t *pool) +struct rspamd_view * +init_view (memory_pool_t * pool) { - struct rspamd_view *new; + struct rspamd_view *new; new = memory_pool_alloc0 (pool, sizeof (struct rspamd_view)); @@ -41,16 +41,16 @@ init_view (memory_pool_t *pool) new->from_hash = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); new->symbols_hash = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); - memory_pool_add_destructor (new->pool, (pool_destruct_func)g_hash_table_destroy, new->from_hash); - memory_pool_add_destructor (new->pool, (pool_destruct_func)g_hash_table_destroy, new->symbols_hash); + memory_pool_add_destructor (new->pool, (pool_destruct_func) g_hash_table_destroy, new->from_hash); + memory_pool_add_destructor (new->pool, (pool_destruct_func) g_hash_table_destroy, new->symbols_hash); return new; } -gboolean -add_view_from (struct rspamd_view *view, char *line) +gboolean +add_view_from (struct rspamd_view * view, char *line) { - struct rspamd_regexp *re = NULL; + struct rspamd_regexp *re = NULL; if (add_map (line, read_host_list, fin_host_list, (void **)&view->from_hash)) { return TRUE; @@ -63,11 +63,11 @@ add_view_from (struct rspamd_view *view, char *line) return FALSE; } -gboolean -add_view_symbols (struct rspamd_view *view, char *line) +gboolean +add_view_symbols (struct rspamd_view * view, char *line) { - struct rspamd_regexp *re = NULL; - GList *symbols; + struct rspamd_regexp *re = NULL; + GList *symbols; if (add_map (line, read_host_list, fin_host_list, (void **)&view->symbols_hash)) { return TRUE; @@ -90,8 +90,8 @@ add_view_symbols (struct rspamd_view *view, char *line) } -gboolean -add_view_ip (struct rspamd_view *view, char *line) +gboolean +add_view_ip (struct rspamd_view * view, char *line) { if (add_map (line, read_radix_list, fin_radix_list, (void **)&view->ip_tree)) { return TRUE; @@ -101,16 +101,16 @@ add_view_ip (struct rspamd_view *view, char *line) } -struct rspamd_view * -find_view_by_ip (GList *views, struct worker_task *task) +struct rspamd_view * +find_view_by_ip (GList * views, struct worker_task *task) { - GList *cur; - struct rspamd_view *v; + GList *cur; + struct rspamd_view *v; if (task->from_addr.s_addr == INADDR_NONE) { return NULL; } - + cur = views; while (cur) { v = cur->data; @@ -123,17 +123,17 @@ find_view_by_ip (GList *views, struct worker_task *task) return NULL; } -struct rspamd_view * -find_view_by_from (GList *views, struct worker_task *task) +struct rspamd_view * +find_view_by_from (GList * views, struct worker_task *task) { - GList *cur, *cur_re; - struct rspamd_view *v; - struct rspamd_regexp *re; + GList *cur, *cur_re; + struct rspamd_view *v; + struct rspamd_regexp *re; if (task->from == NULL) { return NULL; } - + cur = views; while (cur) { v = cur->data; @@ -157,11 +157,11 @@ find_view_by_from (GList *views, struct worker_task *task) return NULL; } -static gboolean +static gboolean match_view_symbol (struct rspamd_view *v, const char *symbol) { - GList *cur; - struct rspamd_regexp *re; + GList *cur; + struct rspamd_regexp *re; /* First try to lookup in hashtable */ if (g_hash_table_lookup (v->symbols_hash, symbol) != NULL) { @@ -181,17 +181,17 @@ match_view_symbol (struct rspamd_view *v, const char *symbol) return FALSE; } -gboolean -check_view (GList *views, const char *symbol, struct worker_task *task) +gboolean +check_view (GList * views, const char *symbol, struct worker_task * task) { - struct rspamd_view *selected = NULL; + struct rspamd_view *selected = NULL; if (views == NULL || (task->view == NULL && task->view_checked == TRUE)) { /* If now views defined just return TRUE to check each symbol */ return TRUE; } - + if (task->view != NULL) { goto check_symbol; } @@ -203,11 +203,11 @@ check_view (GList *views, const char *symbol, struct worker_task *task) return TRUE; } } - + task->view_checked = TRUE; task->view = selected; -check_symbol: + check_symbol: /* selected is now not NULL */ if (match_view_symbol (task->view, symbol)) { return TRUE; diff --git a/src/worker.c b/src/worker.c index 49324031c..880da71ab 100644 --- a/src/worker.c +++ b/src/worker.c @@ -40,35 +40,36 @@ #include <evdns.h> #ifndef WITHOUT_PERL -#include <EXTERN.h> /* from the Perl distribution */ -#include <perl.h> /* from the Perl distribution */ +# include <EXTERN.h> /* from the Perl distribution */ +# include <perl.h> /* from the Perl distribution */ -extern PerlInterpreter *perl_interpreter; +extern PerlInterpreter *perl_interpreter; #endif #ifdef WITH_GPERF_TOOLS -#include <glib/gprintf.h> +# include <glib/gprintf.h> #endif -static struct timeval io_tv; +static struct timeval io_tv; -static gboolean write_socket (void *arg); +static gboolean write_socket (void *arg); -static -void sig_handler (int signo) +static + void +sig_handler (int signo) { switch (signo) { - case SIGINT: - case SIGTERM: + case SIGINT: + case SIGTERM: #ifdef WITH_GPERF_TOOLS - ProfilerStop (); + ProfilerStop (); #endif #ifdef WITH_PROFILER - exit (0); + exit (0); #else - _exit (1); + _exit (1); #endif - break; + break; } } @@ -78,9 +79,9 @@ void sig_handler (int signo) static void sigusr_handler (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct rspamd_worker *worker = (struct rspamd_worker *)arg; /* Do not accept new connections, preparing to end worker's process */ - struct timeval tv; + struct timeval tv; tv.tv_sec = SOFT_SHUTDOWN_TIME; tv.tv_usec = 0; event_del (&worker->sig_ev); @@ -97,7 +98,7 @@ sigusr_handler (int fd, short what, void *arg) static void rcpt_destruct (void *pointer) { - struct worker_task *task = (struct worker_task *)pointer; + struct worker_task *task = (struct worker_task *)pointer; if (task->rcpt) { g_list_free (task->rcpt); @@ -110,8 +111,8 @@ rcpt_destruct (void *pointer) void free_task (struct worker_task *task, gboolean is_soft) { - GList *part; - struct mime_part *p; + GList *part; + struct mime_part *p; if (task) { msg_debug ("free_task: free pointer %p", task); @@ -147,10 +148,10 @@ free_task (struct worker_task *task, gboolean is_soft) } } -static void +static void free_task_hard (void *ud) { - struct worker_task *task = ud; + struct worker_task *task = ud; free_task (task, FALSE); } @@ -158,62 +159,62 @@ free_task_hard (void *ud) /* * Callback that is called when there is data to read in buffer */ -static gboolean -read_socket (f_str_t *in, void *arg) +static gboolean +read_socket (f_str_t * in, void *arg) { - struct worker_task *task = (struct worker_task *)arg; - ssize_t r; + struct worker_task *task = (struct worker_task *)arg; + ssize_t r; switch (task->state) { - case READ_COMMAND: - case READ_HEADER: - if (read_rspamd_input_line (task, in) != 0) { - task->last_error = "Read error"; - task->error_code = RSPAMD_NETWORK_ERROR; - task->state = WRITE_ERROR; - } - if (task->state == WRITE_REPLY || task->state == WRITE_ERROR) { - write_socket (task); - } - break; - case READ_MESSAGE: - task->msg = memory_pool_alloc (task->task_pool, sizeof (f_str_t)); - task->msg->begin = in->begin; - task->msg->len = in->len; - msg_debug ("read_socket: got string of length %ld", (long int)task->msg->len); - r = process_message (task); - if (r == -1) { - msg_warn ("read_socket: processing of message failed"); - task->last_error = "MIME processing error"; - task->error_code = RSPAMD_FILTER_ERROR; - task->state = WRITE_ERROR; - write_socket (task); - } - if (task->cmd == CMD_OTHER) { - /* Skip filters */ - task->state = WRITE_REPLY; - write_socket (task); - return TRUE; - } - r = process_filters (task); - if (r == -1) { - task->last_error = "Filter processing error"; - task->error_code = RSPAMD_FILTER_ERROR; - task->state = WRITE_ERROR; - write_socket (task); - } - else if (r == 0) { - task->state = WAIT_FILTER; - rspamd_dispatcher_pause (task->dispatcher); - } - else { - process_statfiles (task); - write_socket (task); - } - break; - default: - msg_debug ("read_socket: invalid state on reading stage"); - break; + case READ_COMMAND: + case READ_HEADER: + if (read_rspamd_input_line (task, in) != 0) { + task->last_error = "Read error"; + task->error_code = RSPAMD_NETWORK_ERROR; + task->state = WRITE_ERROR; + } + if (task->state == WRITE_REPLY || task->state == WRITE_ERROR) { + write_socket (task); + } + break; + case READ_MESSAGE: + task->msg = memory_pool_alloc (task->task_pool, sizeof (f_str_t)); + task->msg->begin = in->begin; + task->msg->len = in->len; + msg_debug ("read_socket: got string of length %ld", (long int)task->msg->len); + r = process_message (task); + if (r == -1) { + msg_warn ("read_socket: processing of message failed"); + task->last_error = "MIME processing error"; + task->error_code = RSPAMD_FILTER_ERROR; + task->state = WRITE_ERROR; + write_socket (task); + } + if (task->cmd == CMD_OTHER) { + /* Skip filters */ + task->state = WRITE_REPLY; + write_socket (task); + return TRUE; + } + r = process_filters (task); + if (r == -1) { + task->last_error = "Filter processing error"; + task->error_code = RSPAMD_FILTER_ERROR; + task->state = WRITE_ERROR; + write_socket (task); + } + else if (r == 0) { + task->state = WAIT_FILTER; + rspamd_dispatcher_pause (task->dispatcher); + } + else { + process_statfiles (task); + write_socket (task); + } + break; + default: + msg_debug ("read_socket: invalid state on reading stage"); + break; } return TRUE; @@ -222,32 +223,32 @@ read_socket (f_str_t *in, void *arg) /* * Callback for socket writing */ -static gboolean +static gboolean write_socket (void *arg) { - struct worker_task *task = (struct worker_task *)arg; - + struct worker_task *task = (struct worker_task *)arg; + switch (task->state) { - case WRITE_REPLY: - write_reply (task); - destroy_session (task->s); - return FALSE; - break; - case WRITE_ERROR: - write_reply (task); - destroy_session (task->s); - return FALSE; - break; - case CLOSING_CONNECTION: - msg_debug ("write_socket: normally closing connection"); - destroy_session (task->s); - return FALSE; - break; - default: - msg_info ("write_socket: abnormally closing connection"); - destroy_session (task->s); - return FALSE; - break; + case WRITE_REPLY: + write_reply (task); + destroy_session (task->s); + return FALSE; + break; + case WRITE_ERROR: + write_reply (task); + destroy_session (task->s); + return FALSE; + break; + case CLOSING_CONNECTION: + msg_debug ("write_socket: normally closing connection"); + destroy_session (task->s); + return FALSE; + break; + default: + msg_info ("write_socket: abnormally closing connection"); + destroy_session (task->s); + return FALSE; + break; } return TRUE; } @@ -256,19 +257,19 @@ write_socket (void *arg) * Called if something goes wrong */ static void -err_socket (GError *err, void *arg) +err_socket (GError * err, void *arg) { - struct worker_task *task = (struct worker_task *)arg; + struct worker_task *task = (struct worker_task *)arg; msg_info ("err_socket: abnormally closing connection, error: %s", err->message); /* Free buffers */ destroy_session (task->s); } -struct worker_task * +struct worker_task * construct_task (struct rspamd_worker *worker) { - struct worker_task *new_task; - + struct worker_task *new_task; + new_task = g_malloc (sizeof (struct worker_task)); msg_debug ("accept_socket: new task allocated: %p", new_task); @@ -289,11 +290,11 @@ construct_task (struct rspamd_worker *worker) io_tv.tv_usec = 0; new_task->task_pool = memory_pool_new (memory_pool_get_size ()); /* Add destructor for recipients list (it would be better to use anonymous function here */ - memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)rcpt_destruct, new_task); + memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func) rcpt_destruct, new_task); new_task->results = g_hash_table_new (g_str_hash, g_str_equal); - memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)g_hash_table_destroy, new_task->results); + memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func) g_hash_table_destroy, new_task->results); new_task->re_cache = g_hash_table_new (g_str_hash, g_str_equal); - memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func)g_hash_table_destroy, new_task->re_cache); + memory_pool_add_destructor (new_task->task_pool, (pool_destruct_func) g_hash_table_destroy, new_task->re_cache); new_task->s = new_async_session (new_task->task_pool, free_task_hard, new_task); new_task->sock = -1; @@ -306,13 +307,13 @@ construct_task (struct rspamd_worker *worker) static void accept_socket (int fd, short what, void *arg) { - struct rspamd_worker *worker = (struct rspamd_worker *)arg; - struct sockaddr_storage ss; - struct sockaddr_in *sin; - struct worker_task *new_task; - socklen_t addrlen = sizeof(ss); - int nfd; - + struct rspamd_worker *worker = (struct rspamd_worker *)arg; + struct sockaddr_storage ss; + struct sockaddr_in *sin; + struct worker_task *new_task; + socklen_t addrlen = sizeof (ss); + int nfd; + if ((nfd = accept_from_socket (fd, (struct sockaddr *)&ss, &addrlen)) == -1) { msg_warn ("accept_socket: accept failed: %s", strerror (errno)); return; @@ -327,19 +328,17 @@ accept_socket (int fd, short what, void *arg) msg_info ("accept_socket: accepted connection from unix socket"); } else if (ss.ss_family == AF_INET) { - sin = (struct sockaddr_in *) &ss; + sin = (struct sockaddr_in *)&ss; msg_info ("accept_socket: accepted connection from %s port %d", inet_ntoa (sin->sin_addr), ntohs (sin->sin_port)); } new_task = construct_task (worker); - new_task->sock = nfd; - worker->srv->stat->connections_count ++; + new_task->sock = nfd; + worker->srv->stat->connections_count++; /* Set up dispatcher */ - new_task->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, read_socket, - write_socket, err_socket, &io_tv, - (void *)new_task); + new_task->dispatcher = rspamd_create_dispatcher (nfd, BUFFER_LINE, read_socket, write_socket, err_socket, &io_tv, (void *)new_task); } @@ -349,11 +348,11 @@ accept_socket (int fd, short what, void *arg) void start_worker (struct rspamd_worker *worker) { - struct sigaction signals; + struct sigaction signals; #ifdef WITH_PROFILER - extern void _start (void), etext (void); - monstartup ((u_long) &_start, (u_long) &etext); + extern void _start (void), etext (void); + monstartup ((u_long) & _start, (u_long) & etext); #endif gperf_profiler_init (worker->srv->cfg, "worker"); @@ -367,12 +366,12 @@ start_worker (struct rspamd_worker *worker) sigprocmask (SIG_UNBLOCK, &signals.sa_mask, NULL); /* SIGUSR2 handler */ - signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *) worker); + signal_set (&worker->sig_ev, SIGUSR2, sigusr_handler, (void *)worker); signal_add (&worker->sig_ev, NULL); /* Accept event */ - event_set(&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); - event_add(&worker->bind_ev, NULL); + event_set (&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_socket, (void *)worker); + event_add (&worker->bind_ev, NULL); /* Maps events */ start_map_watch (); |