## Authentication processes
##
-# Authentication cache size in kilobytes. 0 means it's disabled.
-# Note that bsdauth, PAM and vpopmail require cache_key to be set for caching
-# to be used.
+# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
+# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
#auth_cache_size = 0
# Time to live in seconds for cached data. After this many seconds the cached
# record is no longer used, *except* if the main database lookup returns
##
protocol imap {
- # Maximum IMAP command line length in bytes. Some clients generate very long
- # command lines with huge mailboxes, so you may need to raise this if you get
+ # Maximum IMAP command line length. Some clients generate very long command
+ # lines with huge mailboxes, so you may need to raise this if you get
# "Too long argument" or "IMAP command line too large" errors often.
- #imap_max_line_length = 65536
+ #imap_max_line_length = 64k
# Maximum number of IMAP connections allowed for a user from each IP address.
# NOTE: The username is compared case-sensitively.
# aren't immediately visible to other MUAs.
#mbox_lazy_writes = yes
-# If mbox size is smaller than this (in kilobytes), don't write index files.
+# If mbox size is smaller than this (e.g. 100k), don't write index files.
# If an index file already exists it's still read, just not updated.
#mbox_min_index_size = 0
## mdbox-specific settings
##
-# Maximum dbox file size in kilobytes until it's rotated.
-#mdbox_rotate_size = 2048
+# Maximum dbox file size until it's rotated.
+#mdbox_rotate_size = 2M
-# Minimum dbox file size in kilobytes before it's rotated
-# (overrides mdbox_rotate_days)
-#mdbox_rotate_min_size = 16
+# Minimum dbox file size before it's rotated (overrides mdbox_rotate_days)
+#mdbox_rotate_min_size = 16k
# Maximum dbox file age in days until it's rotated. Day always begins from
# midnight, so 1 = today, 2 = yesterday, etc. 0 = check disabled.
#default_process_limit = 100
#default_client_limit = 1000
-#default_vsz_limit = 256
+#default_vsz_limit = 256M
service imap-login {
inet_listener {
#service_count = 1
# If you set service_count=0, you probably need to grow this.
- #vsz_limit = 64
+ #vsz_limit = 64M
}
service pop3-login {
service imap {
# Most of the memory goes to mmap()ing files. You may need to increase this
# limit if you have huge mailboxes.
- #vsz_limit = 256
+ #vsz_limit = 256M
}
service auth {
DEF(SET_STR, mechanisms),
DEF(SET_STR, realms),
DEF(SET_STR, default_realm),
- DEF(SET_UINT, cache_size),
+ DEF(SET_SIZE, cache_size),
DEF(SET_UINT, cache_ttl),
DEF(SET_UINT, cache_negative_ttl),
DEF(SET_STR, username_chars),
const char *mechanisms;
const char *realms;
const char *default_realm;
- unsigned int cache_size;
+ uoff_t cache_size;
unsigned int cache_ttl;
unsigned int cache_negative_ttl;
const char *username_chars;
if (set->cache_size == 0 || set->cache_ttl == 0)
return;
- passdb_cache = auth_cache_new(set->cache_size * 1024UL, set->cache_ttl,
+ passdb_cache = auth_cache_new(set->cache_size, set->cache_ttl,
set->cache_negative_ttl);
}
}
break;
}
+ case SET_SIZE: {
+ const uoff_t *val = value, *dval = default_value;
+ if (dump_default || dval == NULL || *val != *dval) {
+ str_printfa(ctx->value, "%llu",
+ (unsigned long long)*val);
+ }
+ break;
+ }
case SET_UINT: {
const unsigned int *val = value, *dval = default_value;
if (dump_default || dval == NULL || *val != *dval)
DEF(SET_BOOL, mail_debug),
DEF(SET_BOOL, verbose_proctitle),
- DEF(SET_UINT, imap_max_line_length),
+ DEF(SET_SIZE, imap_max_line_length),
DEF(SET_UINT, imap_idle_notify_interval),
DEF(SET_STR, imap_capability),
DEF(SET_STR, imap_client_workarounds),
/* RFC-2683 recommends at least 8000 bytes. Some clients however don't
break large message sets to multiple commands, so we're pretty
liberal by default. */
- MEMBER(imap_max_line_length) 65536,
+ MEMBER(imap_max_line_length) 64*1024,
MEMBER(imap_idle_notify_interval) 120,
MEMBER(imap_capability) "",
MEMBER(imap_client_workarounds) "outlook-idle",
bool verbose_proctitle;
/* imap: */
- unsigned int imap_max_line_length;
+ uoff_t imap_max_line_length;
unsigned int imap_idle_notify_interval;
const char *imap_capability;
const char *imap_client_workarounds;
unsigned int process_limit;
unsigned int client_limit;
unsigned int service_count;
- unsigned int vsz_limit;
+ uoff_t vsz_limit;
ARRAY_TYPE(file_listener_settings) unix_listeners;
ARRAY_TYPE(file_listener_settings) fifo_listeners;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
return 0;
}
+static int
+get_size(struct setting_parser_context *ctx, const char *value,
+ uoff_t *result_r)
+{
+ unsigned long long num, multiply;
+ char *p;
+
+ num = strtoull(value, &p, 10);
+ switch (i_toupper(*p)) {
+ case '\0':
+ multiply = 1;
+ break;
+ case 'B':
+ multiply = 1;
+ p += 1;
+ break;
+ case 'K':
+ multiply = 1024;
+ p += 1;
+ break;
+ case 'M':
+ multiply = 1024*1024;
+ p += 1;
+ break;
+ case 'G':
+ multiply = 1024*1024*1024;
+ p += 1;
+ break;
+ case 'T':
+ multiply = 1024ULL*1024*1024*1024;
+ p += 1;
+ break;
+ }
+
+ if (multiply > 1) {
+ /* Allow: k, ki, kiB */
+ if (i_toupper(*p) == 'I')
+ p++;
+ if (i_toupper(*p) == 'B')
+ p++;
+ }
+ if (*p != '\0') {
+ ctx->error = p_strconcat(ctx->parser_pool, "Invalid size: ",
+ value, NULL);
+ return -1;
+ }
+ if (num > -1ULL / multiply) {
+ ctx->error = p_strconcat(ctx->parser_pool,
+ "Size is too large: ", value, NULL);
+ return -1;
+ }
+ *result_r = num * multiply;
+ return 0;
+}
+
static int get_enum(struct setting_parser_context *ctx, const char *value,
char **result_r, const char *allowed_values)
{
if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
return -1;
break;
+ case SET_SIZE:
+ if (get_size(ctx, value, (uoff_t *)ptr) < 0)
+ return -1;
+ break;
case SET_STR:
*((char **)ptr) = p_strdup(ctx->set_pool, value);
break;
switch (def->type) {
case SET_BOOL:
case SET_UINT:
+ case SET_SIZE:
case SET_STR:
case SET_ENUM:
case SET_STRLIST:
switch (def->type) {
case SET_BOOL:
case SET_UINT:
+ case SET_SIZE:
case SET_STR:
case SET_ENUM:
case SET_STRLIST:
*dest_uint = *src_uint;
break;
}
+ case SET_SIZE: {
+ const uoff_t *src_size = src;
+ uoff_t *dest_size = dest;
+
+ *dest_size = *src_size;
+ break;
+ }
case SET_STR_VARS:
case SET_STR:
case SET_ENUM: {
switch (def->type) {
case SET_BOOL:
case SET_UINT:
+ case SET_SIZE:
case SET_STR_VARS:
case SET_STR:
case SET_ENUM:
enum setting_type {
SET_BOOL,
SET_UINT,
+ SET_SIZE,
SET_STR,
SET_STR_VARS, /* string with %variables */
SET_ENUM,
{ SET_UINT + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
((struct struct_name *)0)->name, unsigned int), \
#name, offsetof(struct struct_name, name), NULL }
+#define SETTING_DEFINE_STRUCT_SIZE(name, struct_name) \
+ { SET_SIZE + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
+ ((struct struct_name *)0)->name, uoff_t), \
+ #name, offsetof(struct struct_name, name), NULL }
#define SETTING_DEFINE_STRUCT_STR(name, struct_name) \
{ SET_STR + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
((struct struct_name *)0)->name, const char *), \
/* Return section name escaped */
const char *settings_section_escape(const char *name);
+/* Parse a size string to actual size. */
+int settings_parse_size(const char *str, uoff_t *size_r, const char **error_r);
#endif
const char **error_r);
static const struct setting_define mdbox_setting_defines[] = {
- DEF(SET_UINT, mdbox_rotate_size),
- DEF(SET_UINT, mdbox_rotate_min_size),
+ DEF(SET_SIZE, mdbox_rotate_size),
+ DEF(SET_SIZE, mdbox_rotate_min_size),
DEF(SET_UINT, mdbox_rotate_days),
DEF(SET_UINT, mdbox_max_open_files),
DEF(SET_UINT, mdbox_purge_min_percentage),
};
static const struct mdbox_settings mdbox_default_settings = {
- MEMBER(mdbox_rotate_size) 2048*1024,
+ MEMBER(mdbox_rotate_size) 2*1024*1024,
MEMBER(mdbox_rotate_min_size) 16*1024,
MEMBER(mdbox_rotate_days) 0,
MEMBER(mdbox_max_open_files) 64,
#define MDBOX_SETTINGS_H
struct mdbox_settings {
- unsigned int mdbox_rotate_size;
- unsigned int mdbox_rotate_min_size;
+ uoff_t mdbox_rotate_size;
+ uoff_t mdbox_rotate_min_size;
unsigned int mdbox_rotate_days;
unsigned int mdbox_max_open_files;
unsigned int mdbox_purge_min_percentage;
DEF(SET_STR, mbox_write_locks),
DEF(SET_UINT, mbox_lock_timeout),
DEF(SET_UINT, mbox_dotlock_change_timeout),
- DEF(SET_UINT, mbox_min_index_size),
+ DEF(SET_SIZE, mbox_min_index_size),
DEF(SET_BOOL, mbox_dirty_syncs),
DEF(SET_BOOL, mbox_very_dirty_syncs),
DEF(SET_BOOL, mbox_lazy_writes),
const char *mbox_write_locks;
unsigned int mbox_lock_timeout;
unsigned int mbox_dotlock_change_timeout;
- unsigned int mbox_min_index_size;
+ uoff_t mbox_min_index_size;
bool mbox_dirty_syncs;
bool mbox_very_dirty_syncs;
bool mbox_lazy_writes;
return FALSE;
}
}
- return st.st_size / 1024 < storage->set->mbox_min_index_size;
+ return (uoff_t)st.st_size < storage->set->mbox_min_index_size;
}
static struct mailbox *
DEF(SET_UINT, process_limit),
DEF(SET_UINT, client_limit),
DEF(SET_UINT, service_count),
- DEF(SET_UINT, vsz_limit),
+ DEF(SET_SIZE, vsz_limit),
DEFLIST_UNIQUE(unix_listeners, "unix_listener",
&file_listener_setting_parser_info),
MEMBER(process_limit) -1U,
MEMBER(client_limit) 0,
MEMBER(service_count) 0,
- MEMBER(vsz_limit) -1U,
+ MEMBER(vsz_limit) (uoff_t)-1,
MEMBER(unix_listeners) ARRAY_INIT,
MEMBER(fifo_listeners) ARRAY_INIT,
DEF(SET_ENUM, ssl),
DEF(SET_UINT, default_process_limit),
DEF(SET_UINT, default_client_limit),
- DEF(SET_UINT, default_vsz_limit),
+ DEF(SET_SIZE, default_vsz_limit),
DEF(SET_BOOL, version_ignore),
DEF(SET_BOOL, mail_debug),
MEMBER(ssl) "yes:no:required",
MEMBER(default_process_limit) 100,
MEMBER(default_client_limit) 1000,
- MEMBER(default_vsz_limit) 256,
+ MEMBER(default_vsz_limit) 256*1024*1024,
MEMBER(version_ignore) FALSE,
MEMBER(mail_debug) FALSE,
const char *ssl;
unsigned int default_process_limit;
unsigned int default_client_limit;
- unsigned int default_vsz_limit;
+ uoff_t default_vsz_limit;
bool version_ignore;
bool mail_debug;
unsigned int len;
if (service->vsz_limit != 0)
- restrict_process_size(service->vsz_limit, -1U);
+ restrict_process_size(service->vsz_limit/1024, -1U);
restrict_access_init(&rset);
rset.uid = service->uid;
if (service->vsz_limit == 0)
return "Out of memory";
return t_strdup_printf("Out of memory (vsz_limit=%u MB, "
- "you may need to increase it)",
- service->vsz_limit);
+ "you may need to increase it)",
+ (unsigned int)(service->vsz_limit/1024/1024));
case FATAL_EXEC:
return "exec() failed";
service->client_limit < set->service_count)
service->client_limit = set->service_count;
- service->vsz_limit = set->vsz_limit != -1U ? set->vsz_limit :
+ service->vsz_limit = set->vsz_limit != (uoff_t)-1 ? set->vsz_limit :
set->master_set->default_vsz_limit;
service->type = service->set->parsed_type;
/* Maximum number of client connections a process can handle. */
unsigned int client_limit;
/* set->vsz_limit or set->master_set->default_client_limit */
- unsigned int vsz_limit;
+ uoff_t vsz_limit;
/* log process pipe file descriptors. */
int log_fd[2];