diff -r 52f1d54d37cf src/deliver/duplicate.c --- a/src/deliver/duplicate.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/deliver/duplicate.c Fri Jun 27 20:43:11 2008 +0300 @@ -58,7 +58,7 @@ strcasecmp(d1->user, d2->user) == 0) ? 0 : 1; } -static unsigned int duplicate_hash(const void *p) +static unsigned int duplicate_hash(const void *p, unsigned int rnd) { /* a char* hash function from ASU -- from glib */ const struct duplicate *d = p; @@ -74,7 +74,7 @@ s++; } - return h ^ strcase_hash(d->user); + return h ^ strcase_hash(d->user, rnd); } static int duplicate_read(struct duplicate_file *file) diff -r 52f1d54d37cf src/dict/dict-server.c --- a/src/dict/dict-server.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/dict/dict-server.c Fri Jun 27 20:43:11 2008 +0300 @@ -455,7 +455,7 @@ server->fd = fd; while (server->fd == -1) { - server->fd = net_listen_unix(path, 64); + server->fd = net_listen_unix(path, 1024); if (server->fd != -1) break; diff -r 52f1d54d37cf src/lib-imap/imap-date.c --- a/src/lib-imap/imap-date.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-imap/imap-date.c Fri Jun 27 20:43:11 2008 +0300 @@ -160,24 +160,24 @@ const char *imap_to_datetime(time_t time) { char *buf; - struct tm *tm; + struct tm tm; int timezone_offset, year; - tm = localtime(&time); - timezone_offset = utc_offset(tm, time); + localtime_r(&time, &tm); + timezone_offset = utc_offset(&tm, time); /* @UNSAFE: but faster than t_strdup_printf() call.. */ buf = t_malloc(27); /* dd-mon- */ - buf[0] = (tm->tm_mday / 10) + '0'; - buf[1] = (tm->tm_mday % 10) + '0'; + buf[0] = (tm.tm_mday / 10) + '0'; + buf[1] = (tm.tm_mday % 10) + '0'; buf[2] = '-'; - memcpy(buf+3, month_names[tm->tm_mon], 3); + memcpy(buf+3, month_names[tm.tm_mon], 3); buf[6] = '-'; /* yyyy */ - year = tm->tm_year + 1900; + year = tm.tm_year + 1900; buf[7] = (year / 1000) + '0'; buf[8] = ((year / 100) % 10) + '0'; buf[9] = ((year / 10) % 10) + '0'; @@ -185,14 +185,14 @@ buf[11] = ' '; /* hh:mi:ss */ - buf[12] = (tm->tm_hour / 10) + '0'; - buf[13] = (tm->tm_hour % 10) + '0'; + buf[12] = (tm.tm_hour / 10) + '0'; + buf[13] = (tm.tm_hour % 10) + '0'; buf[14] = ':'; - buf[15] = (tm->tm_min / 10) + '0'; - buf[16] = (tm->tm_min % 10) + '0'; + buf[15] = (tm.tm_min / 10) + '0'; + buf[16] = (tm.tm_min % 10) + '0'; buf[17] = ':'; - buf[18] = (tm->tm_sec / 10) + '0'; - buf[19] = (tm->tm_sec % 10) + '0'; + buf[18] = (tm.tm_sec / 10) + '0'; + buf[19] = (tm.tm_sec % 10) + '0'; buf[20] = ' '; /* timezone */ diff -r 52f1d54d37cf src/lib-index/mail-index-sync-update.c --- a/src/lib-index/mail-index-sync-update.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-index/mail-index-sync-update.c Fri Jun 27 20:43:11 2008 +0300 @@ -565,7 +565,7 @@ int i, days; /* get beginning of today */ - tm = *localtime(&ioloop_time); + localtime_r(&ioloop_time, &tm); tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; diff -r 52f1d54d37cf src/lib-mail/message-date.c --- a/src/lib-mail/message-date.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-mail/message-date.c Fri Jun 27 20:43:11 2008 +0300 @@ -245,12 +245,12 @@ const char *message_date_create(time_t time) { - struct tm *tm; + struct tm tm; int offset; bool negative; - tm = localtime(&time); - offset = utc_offset(tm, time); + localtime_r(&time, &tm); + offset = utc_offset(&tm, time); if (offset >= 0) negative = FALSE; else { @@ -259,10 +259,10 @@ } return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %c%02d%02d", - weekday_names[tm->tm_wday], - tm->tm_mday, - month_names[tm->tm_mon], - tm->tm_year+1900, - tm->tm_hour, tm->tm_min, tm->tm_sec, + weekday_names[tm.tm_wday], + tm.tm_mday, + month_names[tm.tm_mon], + tm.tm_year+1900, + tm.tm_hour, tm.tm_min, tm.tm_sec, negative ? '-' : '+', offset / 60, offset % 60); } diff -r 52f1d54d37cf src/lib-storage/index/dbox/dbox-uidlist.c --- a/src/lib-storage/index/dbox/dbox-uidlist.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-storage/index/dbox/dbox-uidlist.c Fri Jun 27 20:43:11 2008 +0300 @@ -517,7 +517,7 @@ return 0; /* get beginning of today */ - tm = *localtime(&ioloop_time); + localtime_r(&ioloop_time, &tm); tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; diff -r 52f1d54d37cf src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-storage/index/index-search.c Fri Jun 27 20:43:11 2008 +0300 @@ -183,7 +183,7 @@ enum mail_search_arg_type type, const char *value) { - struct tm *tm; + struct tm tm; time_t date, search_time; uoff_t virtual_size, search_size; int timezone_offset; @@ -197,8 +197,8 @@ if (date == (time_t)-1) return -1; - tm = localtime(&date); - date += utc_offset(tm, date)*60; + localtime_r(&date, &tm); + date += utc_offset(&tm, date)*60; if (!imap_parse_date(value, &search_time)) return 0; diff -r 52f1d54d37cf src/lib-storage/index/maildir/maildir-storage.h --- a/src/lib-storage/index/maildir/maildir-storage.h Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.h Fri Jun 27 20:43:11 2008 +0300 @@ -174,7 +174,7 @@ const char *fname, enum mail_flags flags, array_t *keywords); -unsigned int maildir_hash(const void *p); +unsigned int maildir_hash(const void *p, unsigned int rnd); int maildir_cmp(const void *p1, const void *p2); #endif diff -r 52f1d54d37cf src/lib-storage/index/maildir/maildir-util.c --- a/src/lib-storage/index/maildir/maildir-util.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-storage/index/maildir/maildir-util.c Fri Jun 27 20:43:11 2008 +0300 @@ -7,6 +7,7 @@ #include "maildir-storage.h" #include "maildir-uidlist.h" #include "maildir-keywords.h" +#include "jhash.h" #include #include @@ -266,23 +267,13 @@ } /* a char* hash function from ASU -- from glib */ -unsigned int maildir_hash(const void *p) +unsigned int maildir_hash(const void *p, unsigned int rnd) { const unsigned char *s = p; - unsigned int g, h = 0; + unsigned int len = 0; - while (*s != MAILDIR_INFO_SEP && *s != '\0') { - i_assert(*s != '/'); - h = (h << 4) + *s; - if ((g = h & 0xf0000000UL)) { - h = h ^ (g >> 24); - h = h ^ g; - } - - s++; - } - - return h; + while (*s != MAILDIR_INFO_SEP && *s != '\0' && *s != '/') { s++; len++; } + return jhash (p, len, rnd); } int maildir_cmp(const void *p1, const void *p2) diff -r 52f1d54d37cf src/lib-storage/index/mbox/mbox-from.c --- a/src/lib-storage/index/mbox/mbox-from.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-storage/index/mbox/mbox-from.c Fri Jun 27 20:43:11 2008 +0300 @@ -241,7 +241,7 @@ const char *mbox_from_create(const char *sender, time_t time) { string_t *str; - struct tm *tm; + struct tm tm; int year; str = t_str_new(256); @@ -251,38 +251,38 @@ /* we could use simply asctime(), but i18n etc. may break it. Example: "Thu Nov 29 22:33:52 2001" */ - tm = localtime(&time); + localtime_r(&time, &tm); /* week day */ - str_append(str, weekdays[tm->tm_wday]); + str_append(str, weekdays[tm.tm_wday]); str_append_c(str, ' '); /* month */ - str_append(str, months[tm->tm_mon]); + str_append(str, months[tm.tm_mon]); str_append_c(str, ' '); /* day */ - str_append_c(str, (tm->tm_mday / 10) + '0'); - str_append_c(str, (tm->tm_mday % 10) + '0'); + str_append_c(str, (tm.tm_mday / 10) + '0'); + str_append_c(str, (tm.tm_mday % 10) + '0'); str_append_c(str, ' '); /* hour */ - str_append_c(str, (tm->tm_hour / 10) + '0'); - str_append_c(str, (tm->tm_hour % 10) + '0'); + str_append_c(str, (tm.tm_hour / 10) + '0'); + str_append_c(str, (tm.tm_hour % 10) + '0'); str_append_c(str, ':'); /* minute */ - str_append_c(str, (tm->tm_min / 10) + '0'); - str_append_c(str, (tm->tm_min % 10) + '0'); + str_append_c(str, (tm.tm_min / 10) + '0'); + str_append_c(str, (tm.tm_min % 10) + '0'); str_append_c(str, ':'); /* second */ - str_append_c(str, (tm->tm_sec / 10) + '0'); - str_append_c(str, (tm->tm_sec % 10) + '0'); + str_append_c(str, (tm.tm_sec / 10) + '0'); + str_append_c(str, (tm.tm_sec % 10) + '0'); str_append_c(str, ' '); /* year */ - year = tm->tm_year + 1900; + year = tm.tm_year + 1900; str_append_c(str, (year / 1000) + '0'); str_append_c(str, ((year / 100) % 10) + '0'); str_append_c(str, ((year / 10) % 10) + '0'); diff -r 52f1d54d37cf src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib-storage/mail-storage.c Fri Jun 27 20:43:11 2008 +0300 @@ -243,14 +243,14 @@ void mail_storage_set_internal_error(struct mail_storage *storage) { - struct tm *tm; + struct tm tm; char str[256]; - tm = localtime(&ioloop_time); + localtime_r(&ioloop_time, &tm); i_free(storage->error); storage->error = - strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ? + strftime(str, sizeof(str), CRITICAL_MSG_STAMP, &tm) > 0 ? i_strdup(str) : i_strdup(CRITICAL_MSG); storage->syntax_error = FALSE; storage->temporary_error = TRUE; diff -r 52f1d54d37cf src/lib/failures.c --- a/src/lib/failures.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/failures.c Fri Jun 27 20:43:11 2008 +0300 @@ -57,7 +57,7 @@ static void write_prefix(FILE *f) { - struct tm *tm; + struct tm tm; char str[256]; time_t now; @@ -66,10 +66,10 @@ if (log_stamp_format != NULL) { now = time(NULL); - tm = localtime(&now); + localtime_r(&now, &tm); if (strftime(str, sizeof(str), - get_log_stamp_format("unused"), tm) > 0) + get_log_stamp_format("unused"), &tm) > 0) fputs(str, f); } } diff -r 52f1d54d37cf src/lib/hash.c --- a/src/lib/hash.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/hash.c Fri Jun 27 20:43:11 2008 +0300 @@ -5,6 +5,8 @@ #include "lib.h" #include "hash.h" #include "primes.h" +#include "randgen.h" +#include "jhash.h" #include @@ -23,6 +25,7 @@ unsigned int initial_size, nodes_count, removed_count; unsigned int size; + unsigned int rnd; struct hash_node *nodes; struct hash_node *free_nodes; @@ -43,10 +46,11 @@ return p1 == p2 ? 0 : 1; } -static unsigned int direct_hash(const void *p) +static unsigned int direct_hash(const void *p, unsigned int __unused) { /* NOTE: may truncate the value, but that doesn't matter. */ return POINTER_CAST_TO(p, unsigned int); + (void)__unused; } struct hash_table * @@ -61,7 +65,14 @@ table->initial_size = I_MAX(primes_closest(initial_size), HASH_TABLE_MIN_SIZE); - table->hash_cb = hash_cb != NULL ? hash_cb : direct_hash; + if (hash_cb) { + table->hash_cb = hash_cb; + random_init(); + random_fill(&table->rnd, sizeof(table->rnd)); + } else { + table->hash_cb = direct_hash; + table->rnd = 0; + } table->key_compare_cb = key_compare_cb == NULL ? direct_cmp : key_compare_cb; @@ -156,7 +167,7 @@ { struct hash_node *node; - node = hash_lookup_node(table, key, table->hash_cb(key)); + node = hash_lookup_node(table, key, table->hash_cb(key, table->rnd)); return node != NULL ? node->value : NULL; } @@ -166,7 +177,7 @@ struct hash_node *node; node = hash_lookup_node(table, lookup_key, - table->hash_cb(lookup_key)); + table->hash_cb(lookup_key, table->rnd)); if (node == NULL) return FALSE; @@ -186,7 +197,7 @@ i_assert(key != NULL); - hash = table->hash_cb(key); + hash = table->hash_cb(key, table->rnd); if (check_existing && table->removed_count > 0) { /* there may be holes, have to check everything */ @@ -308,7 +319,7 @@ struct hash_node *node; unsigned int hash; - hash = table->hash_cb(key); + hash = table->hash_cb(key, table->rnd); node = hash_lookup_node(table, key, hash); if (node == NULL) @@ -468,38 +479,13 @@ hash_thaw(dest); } -/* a char* hash function from ASU -- from glib */ -unsigned int str_hash(const void *p) +unsigned int str_hash(const void *p, unsigned int rnd) { - const unsigned char *s = p; - unsigned int g, h = 0; - - while (*s != '\0') { - h = (h << 4) + *s; - if ((g = h & 0xf0000000UL)) { - h = h ^ (g >> 24); - h = h ^ g; - } - s++; - } - - return h; + return jhash(p, strlen(p), rnd); } -/* a char* hash function from ASU -- from glib */ -unsigned int strcase_hash(const void *p) +unsigned int strcase_hash(const void *p, unsigned int rnd) { - const unsigned char *s = p; - unsigned int g, h = 0; + return jhash_case(p, strlen(p), rnd); +} - while (*s != '\0') { - h = (h << 4) + i_toupper(*s); - if ((g = h & 0xf0000000UL)) { - h = h ^ (g >> 24); - h = h ^ g; - } - s++; - } - - return h; -} diff -r 52f1d54d37cf src/lib/hash.h --- a/src/lib/hash.h Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/hash.h Fri Jun 27 20:43:11 2008 +0300 @@ -2,7 +2,7 @@ #define __HASH_H /* Returns hash code. */ -typedef unsigned int hash_callback_t(const void *p); +typedef unsigned int hash_callback_t(const void *p, unsigned int); /* Returns 0 if the pointers are equal. */ typedef int hash_cmp_callback_t(const void *p1, const void *p2); @@ -51,7 +51,7 @@ void hash_copy(struct hash_table *dest, struct hash_table *src); /* hash function for strings */ -unsigned int str_hash(const void *p); -unsigned int strcase_hash(const void *p); +unsigned int str_hash(const void *p, unsigned int rnd); +unsigned int strcase_hash(const void *p, unsigned int rnd); #endif diff -r 52f1d54d37cf src/lib/jhash.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/jhash.h Fri Jun 27 20:43:11 2008 +0300 @@ -0,0 +1,235 @@ +/* +vim:tw=76:ts=2:sw=2:cindent:expandtab +*/ + +#ifndef _JHASH_H +#define _JHASH_H + +#include +#include + +/* jhash.h: Jenkins hash support. + * + * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) + * + * http://burtleburtle.net/bob/hash/ + * + * These are the credits from Bob's sources: + * + * lookup2.c, by Bob Jenkins, December 1996, Public Domain. + * hash(), hash2(), hash3, and mix() are externally useful functions. + * Routines to test the hash are included if SELF_TEST is defined. + * You can use this free for any purpose. It has no warranty. + * + * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * + * I've modified Bob's hash to be useful in the Linux kernel, and + * any bugs present are surely my fault. -DaveM + * + * __jhash_mix4 added, and __jhash_mix modified to use rotations by Sami Farin + * + */ + +#define ROTATE(v,n) (((v) << (n)) | ((v) >> (32 - (n)))) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (((v) + (w))) + +#define __jhash_mix4(a, b, c, d) \ +{ \ + a = XOR(a,ROTATE(PLUS(b, c), 7)); \ + b = XOR(b,ROTATE(PLUS(a, c), 9)); \ + c = XOR(c,ROTATE(PLUS(a, b), 13)); \ + d = XOR(d,ROTATE(PLUS(a, b), 18)); \ + \ + a = XOR(a,ROTATE(PLUS(b, d), 25)); \ + b = XOR(b,ROTATE(PLUS(a, d), 5)); \ + c = XOR(c,ROTATE(PLUS(a, d), 11)); \ + d = XOR(d,ROTATE(PLUS(a, c), 19)); \ + \ + a = XOR(a,ROTATE(PLUS(c, d), 23)); \ + b = XOR(b,ROTATE(PLUS(a, c), 3)); \ + c = XOR(c,ROTATE(PLUS(a, b), 15)); \ + d = XOR(d,ROTATE(PLUS(b, c), 21)); \ +} + +#define __jhash_mix(a, b, c) \ +{ \ + a = XOR(a,ROTATE(PLUS(b, c), 7)); \ + b = XOR(b,ROTATE(PLUS(a, c), 9)); \ + c = XOR(c,ROTATE(PLUS(a, b), 13)); \ + \ + a = XOR(a,ROTATE(PLUS(b, c), 18)); \ + b = XOR(b,ROTATE(PLUS(a, c), 1)); \ + c = XOR(c,ROTATE(PLUS(a, b), 11)); \ + \ + a = XOR(a,ROTATE(PLUS(b, c), 17)); \ + b = XOR(b,ROTATE(PLUS(a, c), 19)); \ + c = XOR(c,ROTATE(PLUS(a, b), 23)); \ +} + +/* The golden ration: an arbitrary value */ +#define JHASH_GOLDEN_RATIO 0x9e3779b9 + +/* The most generic version, hashes an arbitrary sequence + * of bytes. No alignment or length assumptions are made about + * the input key. + */ +static inline uint32_t jhash(const void *key, uint32_t length, uint32_t initval) +{ + uint32_t a, b, c, len; + const uint8_t *k = key; + + len = length; + a = b = JHASH_GOLDEN_RATIO; + c = initval; + + while (len >= 12) { + a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24)); + b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24)); + c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24)); + + __jhash_mix(a,b,c); + + k += 12; + len -= 12; + } + + c += length; + switch (len) { + case 11: c += ((uint32_t)k[10]<<24); + case 10: c += ((uint32_t)k[9]<<16); + case 9 : c += ((uint32_t)k[8]<<8); + case 8 : b += ((uint32_t)k[7]<<24); + case 7 : b += ((uint32_t)k[6]<<16); + case 6 : b += ((uint32_t)k[5]<<8); + case 5 : b += k[4]; + case 4 : a += ((uint32_t)k[3]<<24); + case 3 : a += ((uint32_t)k[2]<<16); + case 2 : a += ((uint32_t)k[1]<<8); + case 1 : a += k[0]; + }; + + __jhash_mix(a,b,c); + + return c; +} + +static int toup_init; +static uint8_t toup[256]; + +static inline uint32_t jhash_case(const void *key, uint32_t length, uint32_t initval) +{ + uint32_t a, b, c, len; + const uint8_t *k = key; + + if (!toup_init) { + for (a = 0; a < 256; a++) toup[a] = toupper(a); + toup_init = 1; + } + + len = length; + a = b = JHASH_GOLDEN_RATIO; + c = initval; + + while (len >= 12) { + a += (toup[k[0]] +((uint32_t)toup[k[1]]<<8) +((uint32_t)toup[k[2]]<<16) +((uint32_t)toup[k[3]]<<24)); + b += (toup[k[4]] +((uint32_t)toup[k[5]]<<8) +((uint32_t)toup[k[6]]<<16) +((uint32_t)toup[k[7]]<<24)); + c += (toup[k[8]] +((uint32_t)toup[k[9]]<<8) +((uint32_t)toup[k[10]]<<16)+((uint32_t)toup[k[11]]<<24)); + + __jhash_mix(a,b,c); + + k += 12; + len -= 12; + } + + c += length; + switch (len) { + case 11: c += ((uint32_t)toup[k[10]]<<24); + case 10: c += ((uint32_t)toup[k[9]]<<16); + case 9 : c += ((uint32_t)toup[k[8]]<<8); + case 8 : b += ((uint32_t)toup[k[7]]<<24); + case 7 : b += ((uint32_t)toup[k[6]]<<16); + case 6 : b += ((uint32_t)toup[k[5]]<<8); + case 5 : b += toup[k[4]]; + case 4 : a += ((uint32_t)toup[k[3]]<<24); + case 3 : a += ((uint32_t)toup[k[2]]<<16); + case 2 : a += ((uint32_t)toup[k[1]]<<8); + case 1 : a += toup[k[0]]; + }; + + __jhash_mix(a,b,c); + + return c; +} + +/* A special optimized version that handles 1 or more of uint32_ts. + * The length parameter here is the number of uint32_ts in the key. + */ +static inline uint32_t jhash2(uint32_t *k, uint32_t length, uint32_t initval) +{ + uint32_t a, b, c, len; + + a = b = JHASH_GOLDEN_RATIO; + c = initval; + len = length; + + while (len >= 3) { + a += k[0]; + b += k[1]; + c += k[2]; + __jhash_mix(a, b, c); + k += 3; len -= 3; + } + + c += length * 4; + + switch (len) { + case 2 : b += k[1]; + case 1 : a += k[0]; + }; + + __jhash_mix(a,b,c); + + return c; +} + +/* A special ultra-optimized versions that knows they are hashing exactly + * 4, 3, 2 or 1 word(s). + * + * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally + * done at the end is not done here. + */ + +static inline uint32_t jhash_4words(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t initval) +{ + a += JHASH_GOLDEN_RATIO; + b += JHASH_GOLDEN_RATIO; + c += JHASH_GOLDEN_RATIO; + d += initval; + + __jhash_mix4(a, b, c, d); + + return d; +} +static inline uint32_t jhash_3words(uint32_t a, uint32_t b, uint32_t c, uint32_t initval) +{ + a += JHASH_GOLDEN_RATIO; + b += JHASH_GOLDEN_RATIO; + c += initval; + + __jhash_mix(a, b, c); + + return c; +} + +static inline uint32_t jhash_2words(uint32_t a, uint32_t b, uint32_t initval) +{ + return jhash_3words(a, b, 0, initval); +} + +static inline uint32_t jhash_1word(uint32_t a, uint32_t initval) +{ + return jhash_3words(a, 0, 0, initval); +} + +#endif /* _LINUX_JHASH_H */ diff -r 52f1d54d37cf src/lib/network.c --- a/src/lib/network.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/network.c Fri Jun 27 20:43:11 2008 +0300 @@ -316,10 +316,17 @@ ret = getsockname(fd, &so.sa, &len); if (ret >= 0) { *port = sin_get_port(&so); + int retlisten; + int defer = 30; /* start listening */ - if (listen(fd, backlog) >= 0) + retlisten = listen(fd, backlog); + if (retlisten >= 0) { +#ifdef TCP_DEFER_ACCEPT + setsockopt(fd, SOL_TCP, TCP_DEFER_ACCEPT, &defer, sizeof(defer)); +#endif return fd; + } if (errno != EADDRINUSE) i_error("listen() failed: %m"); diff -r 52f1d54d37cf src/lib/utc-mktime.c --- a/src/lib/utc-mktime.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/utc-mktime.c Fri Jun 27 20:43:11 2008 +0300 @@ -107,7 +107,7 @@ register int bits; register int saved_seconds; time_t t; - struct tm yourtm, *mytm; + struct tm yourtm, mytm; yourtm = *tm; saved_seconds = yourtm.tm_sec; @@ -129,8 +129,9 @@ */ t = (t < 0) ? 0 : ((time_t) 1 << bits); for ( ; ; ) { - mytm = gmtime(&t); - dir = tmcomp(mytm, &yourtm); + if (gmtime_r(&t, &mytm) == NULL) + break; + dir = tmcomp(&mytm, &yourtm); if (dir != 0) { if (bits-- < 0) return (time_t)-1; diff -r 52f1d54d37cf src/lib/utc-offset.c --- a/src/lib/utc-offset.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/utc-offset.c Fri Jun 27 20:43:11 2008 +0300 @@ -10,27 +10,22 @@ #ifdef HAVE_TM_GMTOFF return (int) (tm->tm_gmtoff/60); #else - struct tm ltm, gtm; + struct tm gtm; int offset; - /* gmtime() overwrites tm, so we need to copy it elsewhere */ - ltm = *tm; - tm = gmtime(&t); - gtm = *tm; + gmtime_r(&t, >m); /* max offset of 24 hours */ - if (ltm.tm_yday < gtm.tm_yday) + if (lt->tm_yday < gtm.tm_yday) offset = -24 * 60; - else if (ltm.tm_yday > gtm.tm_yday) + else if (tm->tm_yday > gtm.tm_yday) offset = 24 * 60; else offset = 0; - offset += (ltm.tm_hour - gtm.tm_hour) * 60; - offset += (ltm.tm_min - gtm.tm_min); + offset += (tm->tm_hour - gtm.tm_hour) * 60; + offset += (tm->tm_min - gtm.tm_min); - /* restore overwritten tm */ - *tm = ltm; return offset; #endif } diff -r 52f1d54d37cf src/lib/var-expand.c --- a/src/lib/var-expand.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/lib/var-expand.c Fri Jun 27 20:43:11 2008 +0300 @@ -64,7 +64,7 @@ static const char *m_str_hash(const char *str, struct var_expand_context *ctx) { - unsigned int value = str_hash(str); + unsigned int value = str_hash(str, 0); string_t *hash = t_str_new(20); if (ctx->width != 0) { diff -r 52f1d54d37cf src/login-common/master.c --- a/src/login-common/master.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/login-common/master.c Fri Jun 27 20:43:11 2008 +0300 @@ -199,7 +199,7 @@ } /* need to create it */ - fd = net_listen_unix(path, 16); + fd = net_listen_unix(path, 1024); if (fd != -1) { master_exec(fd); fd = -1; diff -r 52f1d54d37cf src/master/dict-process.c --- a/src/master/dict-process.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/master/dict-process.c Fri Jun 27 20:43:11 2008 +0300 @@ -111,7 +111,7 @@ for (;;) { old_umask = umask(0); - process->fd = net_listen_unix(process->path, 64); + process->fd = net_listen_unix(process->path, 1024); umask(old_umask); if (process->fd != -1) diff -r 52f1d54d37cf src/master/main.c --- a/src/master/main.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/master/main.c Fri Jun 27 20:43:11 2008 +0300 @@ -427,7 +427,7 @@ *fd = null_fd; else { for (i = 0; i < 10; i++) { - *fd = net_listen(ip, &port, 8); + *fd = net_listen(ip, &port, 1024); if (*fd != -1) break; if (errno == EADDRINUSE) { diff -r 52f1d54d37cf src/plugins/lazy-expunge/lazy-expunge-plugin.c --- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c Fri Jun 27 20:43:11 2008 +0300 @@ -411,7 +411,7 @@ struct mail_storage *dest_storage; enum mailbox_name_status status; const char *destname; - struct tm *tm; + struct tm tm; char timestamp[256]; int ret; @@ -434,8 +434,8 @@ } /* destination mailbox name needs to contain a timestamp */ - tm = localtime(&ioloop_time); - if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", tm) == 0) + localtime_r(&ioloop_time, &tm); + if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", &tm) == 0) strocpy(timestamp, dec2str(ioloop_time), sizeof(timestamp)); destname = t_strconcat(name, "-", timestamp, NULL); diff -r 52f1d54d37cf src/util/rawlog.c --- a/src/util/rawlog.c Sat Jun 21 16:23:40 2008 +0300 +++ b/src/util/rawlog.c Fri Jun 27 20:43:11 2008 +0300 @@ -90,7 +90,7 @@ static void proxy_write_out(struct rawlog_proxy *proxy, const void *data, size_t size) { - struct tm *tm; + struct tm tm; char buf[256]; if (proxy->fd_out == -1 || size == 0) @@ -99,9 +99,9 @@ if (proxy->last_out_lf && (proxy->flags & RAWLOG_FLAG_LOG_TIMESTAMPS) != 0 && ioloop_time - proxy->last_write >= TIMESTAMP_WAIT_TIME) { - tm = localtime(&ioloop_time); + localtime_r(&ioloop_time, &tm); - if (strftime(buf, sizeof(buf), TIMESTAMP_FORMAT, tm) <= 0) + if (strftime(buf, sizeof(buf), TIMESTAMP_FORMAT, &tm) <= 0) i_fatal("strftime() failed"); if (write_full(proxy->fd_out, buf, strlen(buf)) < 0) i_fatal("Can't write to log file: %m"); @@ -205,13 +205,13 @@ static void proxy_open_logs(struct rawlog_proxy *proxy, const char *path) { time_t now; - struct tm *tm; + struct tm tm; const char *fname; char timestamp[50]; now = time(NULL); - tm = localtime(&now); - if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", tm) <= 0) + localtime_r(&now, &tm); + if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", &tm) <= 0) i_fatal("strftime() failed"); if ((proxy->flags & RAWLOG_FLAG_LOG_INPUT) != 0) {