changeset 11086:260e190306b0 HEAD

Started using str_to_*() functions instead of libc's ones.
author Timo Sirainen <tss@iki.fi>
date Wed, 07 Apr 2010 01:49:00 +0300
parents b262aad23e59
children 01ab9b93f8bb
files src/anvil/anvil-connection.c src/auth/auth-client-connection.c src/auth/auth-master-connection.c src/auth/auth-request-handler.c src/auth/auth-request.c src/auth/auth-worker-client.c src/auth/auth-worker-server.c src/auth/mech-digest-md5.c src/auth/passdb-pam.c src/auth/userdb.c src/config/config-connection.c src/config/config-parser.c src/dict/dict-commands.c src/imap/cmd-fetch.c src/imap/cmd-select.c src/imap/cmd-store.c src/lib-auth/auth-master.c src/lib-auth/auth-server-connection.c src/lib-dict/dict-client.c src/lib-dict/dict-db.c src/lib-master/master-login-auth.c src/lib-master/master-service.c src/lib-settings/settings-parser.c src/lib-sql/sql-api.c src/lib-storage/index/dbox-multi/mdbox-map.c src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c src/lib-storage/index/dbox-multi/mdbox-sync.c src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c src/lib-storage/index/maildir/maildir-keywords.c src/lib-storage/index/maildir/maildir-mail.c src/lib-storage/mail-search-build.c src/lib-storage/mail-storage-service.c src/lib/file-dotlock.c src/lib/network.c src/lib/restrict-access.c src/plugins/acl/acl-backend-vfile.c src/plugins/expire/expire-env.c src/plugins/fts-squat/fts-backend-squat.c src/plugins/imap-quota/imap-quota-plugin.c src/plugins/imap-zlib/imap-zlib-plugin.c src/plugins/trash/trash-plugin.c src/plugins/zlib/zlib-plugin.c
diffstat 42 files changed, 238 insertions(+), 222 deletions(-) [+]
line wrap: on
line diff
--- a/src/anvil/anvil-connection.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/anvil/anvil-connection.c	Wed Apr 07 01:49:00 2010 +0300
@@ -104,21 +104,21 @@
 			*error_r = "PENALTY-INC: Not enough parameters";
 			return -1;
 		}
-		checksum = strtoul(args[1], NULL, 10);
-		value = strtoul(args[2], NULL, 10);
-		if (value > PENALTY_MAX_VALUE ||
+		if (str_to_uint(args[1], &checksum) < 0 ||
+		    str_to_uint(args[2], &value) < 0 ||
+		    value > PENALTY_MAX_VALUE ||
 		    (value == 0 && checksum != 0)) {
 			*error_r = "PENALTY-INC: Invalid parameters";
 			return -1;
 		}
 		penalty_inc(penalty, args[0], checksum, value);
 	} else if (strcmp(cmd, "PENALTY-SET-EXPIRE-SECS") == 0) {
-		if (args[0] == NULL) {
+		if (args[0] == NULL || str_to_uint(args[0], &value) < 0) {
 			*error_r = "PENALTY-SET-EXPIRE-SECS: "
-				"Not enough parameters";
+				"Invalid parameters";
 			return -1;
 		}
-		penalty_set_expire_secs(penalty, atoi(args[0]));
+		penalty_set_expire_secs(penalty, value);
 	} else if (strcmp(cmd, "PENALTY-DUMP") == 0) {
 		penalty_dump(penalty, conn->output);
 	} else {
@@ -150,7 +150,7 @@
 		if (str_array_length(args) < 4 ||
 		    strcmp(args[0], "VERSION") != 0 ||
 		    strcmp(args[1], "anvil") != 0 ||
-		    atoi(args[2]) != ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION) {
+		    !str_uint_equals(args[2], ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION)) {
 			i_error("Anvil client not compatible with this server "
 				"(mixed old and new binaries?)");
 			anvil_connection_destroy(conn);
--- a/src/auth/auth-client-connection.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/auth-client-connection.c	Wed Apr 07 01:49:00 2010 +0300
@@ -89,8 +89,7 @@
 
 	i_assert(conn->pid == 0);
 
-	pid = (unsigned int)strtoul(args, NULL, 10);
-	if (pid == 0) {
+	if (str_to_uint(args, &pid) < 0 || pid == 0) {
 		i_error("BUG: Authentication client said it's PID 0");
 		return FALSE;
 	}
@@ -221,8 +220,8 @@
 		if (!conn->version_received) {
 			/* make sure the major version matches */
 			if (strncmp(line, "VERSION\t", 8) != 0 ||
-			    atoi(t_strcut(line + 8, '\t')) !=
-			    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+			    !str_uint_equals(t_strcut(line + 8, '\t'),
+					     AUTH_CLIENT_PROTOCOL_MAJOR_VERSION)) {
 				i_error("Authentication client "
 					"not compatible with this server "
 					"(mixed old and new binaries?)");
--- a/src/auth/auth-master-connection.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/auth-master-connection.c	Wed Apr 07 01:49:00 2010 +0300
@@ -75,14 +75,14 @@
 
 	/* <id> <client-pid> <client-id> <cookie> */
 	list = t_strsplit(args, "\t");
-	if (str_array_length(list) < 4) {
+	if (str_array_length(list) < 4 ||
+	    str_to_uint(list[0], &id) < 0 ||
+	    str_to_uint(list[1], &client_pid) < 0 ||
+	    str_to_uint(list[2], &client_id) < 0) {
 		i_error("BUG: Master sent broken REQUEST");
 		return FALSE;
 	}
 
-	id = (unsigned int)strtoul(list[0], NULL, 10);
-	client_pid = (unsigned int)strtoul(list[1], NULL, 10);
-	client_id = (unsigned int)strtoul(list[2], NULL, 10);
 	buffer_create_data(&buf, cookie, sizeof(cookie));
 	if (hex_to_binary(list[3], &buf) < 0) {
 		i_error("BUG: Master sent broken REQUEST cookie");
@@ -114,16 +114,18 @@
 {
 	struct auth_request *auth_request;
 	const char *const *list, *name, *arg;
+	unsigned int id;
 
 	/* <id> <userid> [<parameters>] */
 	list = t_strsplit(args, "\t");
-	if (list[0] == NULL || list[1] == NULL) {
+	if (list[0] == NULL || list[1] == NULL ||
+	    str_to_uint(list[0], &id) < 0) {
 		i_error("BUG: Master sent broken %s", cmd);
 		return -1;
 	}
 
 	auth_request = auth_request_new_dummy();
-	auth_request->id = (unsigned int)strtoul(list[0], NULL, 10);
+	auth_request->id = id;
 	auth_request->context = conn;
 	auth_master_connection_ref(conn);
 
@@ -358,11 +360,10 @@
 	unsigned int id;
 
 	/* <id> */
-	if (*args == '\0') {
+	if (str_to_uint(args, &id) < 0) {
 		i_error("BUG: Master sent broken LIST");
 		return FALSE;
 	}
-	id = strtoul(args, NULL, 10);
 
 	while (userdb != NULL && userdb->userdb->iface->iterate_init == NULL)
 		userdb = userdb->next;
@@ -441,8 +442,8 @@
 
 		/* make sure the major version matches */
 		if (strncmp(line, "VERSION\t", 8) != 0 ||
-		    atoi(t_strcut(line + 8, '\t')) !=
-		    AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
+		    !str_uint_equals(t_strcut(line + 8, '\t'),
+				     AUTH_MASTER_PROTOCOL_MAJOR_VERSION)) {
 			i_error("Master not compatible with this server "
 				"(mixed old and new binaries?)");
 			auth_master_connection_destroy(&conn);
--- a/src/auth/auth-request-handler.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/auth-request-handler.c	Wed Apr 07 01:49:00 2010 +0300
@@ -314,14 +314,13 @@
 
 	/* <id> <mechanism> [...] */
 	list = t_strsplit(args, "\t");
-	if (list[0] == NULL || list[1] == NULL) {
+	if (list[0] == NULL || list[1] == NULL ||
+	    str_to_uint(list[0], &id) < 0) {
 		i_error("BUG: Authentication client %u "
 			"sent broken AUTH request", handler->client_pid);
 		return FALSE;
 	}
 
-	id = (unsigned int)strtoul(list[0], NULL, 10);
-
 	mech = mech_module_find(list[1]);
 	if (mech == NULL) {
 		/* unsupported mechanism */
@@ -427,14 +426,12 @@
 	unsigned int id;
 
 	data = strchr(args, '\t');
-	if (data == NULL) {
+	if (data == NULL || str_to_uint(args, &id) < 0) {
 		i_error("BUG: Authentication client sent broken CONT request");
 		return FALSE;
 	}
 	data++;
 
-	id = (unsigned int)strtoul(args, NULL, 10);
-
 	request = hash_table_lookup(handler->requests, POINTER_CAST(id));
 	if (request == NULL) {
 		struct auth_stream_reply *reply;
--- a/src/auth/auth-request.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/auth-request.c	Wed Apr 07 01:49:00 2010 +0300
@@ -1272,7 +1272,7 @@
 	if (!net_ip_compare(&ip, &request->local_ip))
 		return FALSE;
 
-	if (port != NULL && (unsigned int)atoi(port) != request->local_port)
+	if (port != NULL && !str_uint_equals(port, request->local_port))
 		return FALSE;
 	return destuser == NULL ||
 		strcmp(destuser, request->original_username) == 0;
--- a/src/auth/auth-worker-client.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/auth-worker-client.c	Wed Apr 07 01:49:00 2010 +0300
@@ -151,11 +151,10 @@
 	unsigned int passdb_id;
 
 	/* <passdb id> <password> [<args>] */
-	if (args[1] == NULL) {
+	if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
 		i_error("BUG: Auth worker server sent us invalid PASSV");
 		return FALSE;
 	}
-	passdb_id = atoi(args[0]);
 	password = args[1];
 
 	auth_request = worker_auth_request_new(client, id, args + 2);
@@ -256,11 +255,10 @@
 	unsigned int passdb_id;
 
 	/* <passdb id> <scheme> [<args>] */
-	if (args[1] == NULL) {
+	if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
 		i_error("BUG: Auth worker server sent us invalid PASSL");
 		return FALSE;
 	}
-	passdb_id = atoi(args[0]);
 	scheme = args[1];
 
 	auth_request = worker_auth_request_new(client, id, args + 2);
@@ -318,11 +316,10 @@
 	const char *creds;
 
 	/* <passdb id> <credentials> [<args>] */
-	if (args[1] == NULL) {
+	if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
 		i_error("BUG: Auth worker server sent us invalid SETCRED");
 		return FALSE;
 	}
-	passdb_id = atoi(args[0]);
 	creds = args[1];
 
 	auth_request = worker_auth_request_new(client, id, args + 2);
@@ -407,7 +404,10 @@
 	unsigned int userdb_id;
 
 	/* <userdb id> [<args>] */
-	userdb_id = atoi(args[0]);
+	if (str_to_uint(args[0], &userdb_id) < 0) {
+		i_error("BUG: Auth worker server sent us invalid USER");
+		return FALSE;
+	}
 
 	auth_request = worker_auth_request_new(client, id, args + 1);
 	if (auth_request->user == NULL || auth_request->service == NULL) {
@@ -504,8 +504,14 @@
 {
 	struct auth_worker_list_context *ctx;
 	struct auth_userdb *userdb;
+	unsigned int userdb_id;
 
-	userdb = auth_userdb_find_by_id(client->auth->userdbs, atoi(args[0]));
+	if (str_to_uint(args[0], &userdb_id) < 0) {
+		i_error("BUG: Auth worker server sent us invalid LIST");
+		return FALSE;
+	}
+
+	userdb = auth_userdb_find_by_id(client->auth->userdbs, userdb_id);
 	if (userdb == NULL) {
 		i_error("BUG: LIST had invalid userdb ID");
 		return FALSE;
@@ -534,12 +540,12 @@
 	bool ret = FALSE;
 
 	args = t_strsplit(line, "\t");
-	if (args[0] == NULL || args[1] == NULL || args[2] == NULL) {
+	if (args[0] == NULL || args[1] == NULL || args[2] == NULL ||
+	    str_to_uint(args[0], &id) < 0) {
 		i_error("BUG: Invalid input: %s", line);
 		return FALSE;
 	}
 
-	id = (unsigned int)strtoul(args[0], NULL, 10);
 	if (strcmp(args[1], "PASSV") == 0)
 		ret = auth_worker_handle_passv(client, id, args + 2);
 	else if (strcmp(args[1], "PASSL") == 0)
@@ -601,8 +607,8 @@
 			return;
 
 		if (strncmp(line, "VERSION\tauth-worker\t", 20) != 0 ||
-		    atoi(t_strcut(line + 20, '\t')) !=
-		    AUTH_WORKER_PROTOCOL_MAJOR_VERSION) {
+		    !str_uint_equals(t_strcut(line + 20, '\t'),
+				     AUTH_WORKER_PROTOCOL_MAJOR_VERSION)) {
 			i_error("Auth worker not compatible with this server "
 				"(mixed old and new binaries?)");
 			auth_worker_client_destroy(&client);
--- a/src/auth/auth-worker-server.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/auth-worker-server.c	Wed Apr 07 01:49:00 2010 +0300
@@ -277,11 +277,10 @@
 		}
 		id_str = line;
 		line = strchr(line, '\t');
-		if (line == NULL)
+		if (line == NULL ||
+		    str_to_uint(t_strdup_until(id_str, line), &id) < 0)
 			continue;
 
-		id = (unsigned int)strtoul(t_strcut(id_str, '\t'),
-					   NULL, 10);
 		if (conn->request != NULL && id == conn->request->id) {
 			auth_worker_request_handle(conn, conn->request,
 						   line + 1);
--- a/src/auth/mech-digest-md5.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/mech-digest-md5.c	Wed Apr 07 01:49:00 2010 +0300
@@ -384,8 +384,8 @@
 			return FALSE;
 		}
 
-		request->maxbuf = strtoul(value, NULL, 10);
-		if (request->maxbuf == 0) {
+		if (str_to_ulong(value, &request->maxbuf) < 0 ||
+		    request->maxbuf == 0) {
 			*error = "Invalid maxbuf value";
 			return FALSE;
 		}
--- a/src/auth/passdb-pam.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/passdb-pam.c	Wed Apr 07 01:49:00 2010 +0300
@@ -360,11 +360,15 @@
 			/* for backwards compatibility */
 			module->service_name = "%Ls";
 		} else if (strncmp(t_args[i], "max_requests=", 13) == 0) {
-			module->requests_left = atoi(t_args[i] + 13);
+			if (str_to_uint(t_args[i] + 13,
+					&module->requests_left) < 0) {
+				i_error("pam: Invalid requests_left value: %s",
+					t_args[i] + 13);
+			}
 		} else if (t_args[i+1] == NULL) {
 			module->service_name = p_strdup(pool, t_args[i]);
 		} else {
-			i_fatal("passdb pam: Unknown setting: %s", t_args[i]);
+			i_fatal("pam: Unknown setting: %s", t_args[i]);
 		}
 	}
 	return &module->module;
--- a/src/auth/userdb.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/auth/userdb.c	Wed Apr 07 01:49:00 2010 +0300
@@ -59,16 +59,12 @@
 {
 	struct passwd *pw;
 	uid_t uid;
-	char *p;
 
 	if (str == NULL)
 		return (uid_t)-1;
 
-	if (*str >= '0' && *str <= '9') {
-		uid = (uid_t)strtoul(str, &p, 10);
-		if (*p == '\0')
-			return uid;
-	}
+	if (str_to_uid(str, &uid) == 0)
+		return uid;
 
 	pw = getpwnam(str);
 	if (pw == NULL) {
@@ -85,16 +81,12 @@
 {
 	struct group *gr;
 	gid_t gid;
-	char *p;
 
 	if (str == NULL)
 		return (gid_t)-1;
 
-	if (*str >= '0' && *str <= '9') {
-		gid = (gid_t)strtoul(str, &p, 10);
-		if (*p == '\0')
-			return gid;
-	}
+	if (str_to_gid(str, &gid) == 0)
+		return gid;
 
 	gr = getgrnam(str);
 	if (gr == NULL) {
--- a/src/config/config-connection.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/config/config-connection.c	Wed Apr 07 01:49:00 2010 +0300
@@ -163,8 +163,8 @@
 			return;
 
 		if (strncmp(line, "VERSION\tconfig\t", 15) != 0 ||
-		    atoi(t_strcut(line + 15, '\t')) !=
-		    CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION) {
+		    !str_uint_equals(t_strcut(line + 15, '\t'),
+				     CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION)) {
 			i_error("Config client not compatible with this server "
 				"(mixed old and new binaries?)");
 			config_connection_destroy(conn);
--- a/src/config/config-parser.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/config/config-parser.c	Wed Apr 07 01:49:00 2010 +0300
@@ -189,7 +189,7 @@
 {
 	struct ip_addr *ips;
 	const char *p;
-	unsigned int ip_count;
+	unsigned int ip_count, bits, max_bits;
 	int ret;
 
 	if (net_parse_range(value, ip_r, bits_r) == 0)
@@ -209,10 +209,12 @@
 	}
 	*host_r = p_strdup(ctx->pool, value);
 	*ip_r = ips[0];
-	if (p != NULL && is_numeric(p, '\0'))
-		*bits_r = atoi(p);
+
+	max_bits = IPADDR_IS_V4(&ips[0]) ? 32 : 128;
+	if (p == NULL || str_to_uint(p, &bits) < 0 || bits > max_bits)
+		*bits_r = max_bits;
 	else
-		*bits_r = IPADDR_IS_V4(&ips[0]) ? 32 : 128;
+		*bits_r = bits;
 	return 0;
 }
 
--- a/src/dict/dict-commands.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/dict/dict-commands.c	Wed Apr 07 01:49:00 2010 +0300
@@ -83,6 +83,7 @@
 static int cmd_iterate(struct dict_connection *conn, const char *line)
 {
 	const char *const *args;
+	unsigned int flags;
 
 	if (conn->iter_ctx != NULL) {
 		i_error("dict client: ITERATE: Already iterating");
@@ -90,14 +91,14 @@
 	}
 
 	args = t_strsplit(line, "\t");
-	if (str_array_length(args) < 2) {
+	if (str_array_length(args) < 2 ||
+	    str_to_uint(args[0], &flags) < 0) {
 		i_error("dict client: ITERATE: broken input");
 		return -1;
 	}
 
 	/* <flags> <path> */
-	conn->iter_ctx = dict_iterate_init_multiple(conn->dict, args+1,
-						    atoi(args[0]));
+	conn->iter_ctx = dict_iterate_init_multiple(conn->dict, args+1, flags);
 
 	o_stream_set_flush_callback(conn->output, cmd_iterate_flush, conn);
 	cmd_iterate_flush(conn);
@@ -141,12 +142,10 @@
 	struct dict_connection_transaction *trans;
 	unsigned int id;
 
-	if (!is_numeric(line, '\0')) {
+	if (str_to_uint(line, &id) < 0) {
 		i_error("dict client: Invalid transaction ID %s", line);
 		return -1;
 	}
-
-	id = (unsigned int)strtoul(line, NULL, 10);
 	if (dict_connection_transaction_lookup(conn, id) != NULL) {
 		i_error("dict client: Transaction ID %u already exists", id);
 		return -1;
@@ -170,12 +169,10 @@
 {
 	unsigned int id;
 
-	if (!is_numeric(line, '\0')) {
+	if (str_to_uint(line, &id) < 0) {
 		i_error("dict client: Invalid transaction ID %s", line);
 		return -1;
 	}
-
-	id = (unsigned int)strtoul(line, NULL, 10);
 	*trans_r = dict_connection_transaction_lookup(conn, id);
 	if (*trans_r == NULL) {
 		i_error("dict client: Transaction ID %u doesn't exist", id);
@@ -311,11 +308,12 @@
 {
 	struct dict_connection_transaction *trans;
 	const char *const *args;
-	long long arg;
+	long long diff;
 
 	/* <id> <key> <diff> */
 	args = t_strsplit(line, "\t");
-	if (str_array_length(args) != 3) {
+	if (str_array_length(args) != 3 ||
+	    str_to_llong(args[2], &diff) < 0) {
 		i_error("dict client: ATOMIC_INC: broken input");
 		return -1;
 	}
@@ -323,11 +321,7 @@
 	if (dict_connection_transaction_lookup_parse(conn, args[0], &trans) < 0)
 		return -1;
 
-	if (*args[2] != '-')
-		arg = (long long)strtoull(args[2], NULL, 10);
-	else
-		arg = -(long long)strtoull(args[2]+1, NULL, 10);
-        dict_atomic_inc(trans->ctx, args[1], arg);
+        dict_atomic_inc(trans->ctx, args[1], diff);
 	return 0;
 }
 
--- a/src/imap/cmd-fetch.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/imap/cmd-fetch.c	Wed Apr 07 01:49:00 2010 +0300
@@ -77,17 +77,17 @@
 		     const char *name, const struct imap_arg **args)
 {
 	const char *str;
-	unsigned long long num;
+	uint64_t modseq;
 
 	if (strcmp(name, "CHANGEDSINCE") == 0) {
-		if (!imap_arg_get_atom(*args, &str)) {
+		if (!imap_arg_get_atom(*args, &str) ||
+		    str_to_uint64(str, &modseq) < 0) {
 			client_send_command_error(ctx->cmd,
 				"Invalid CHANGEDSINCE modseq.");
 			return FALSE;
 		}
-		num = strtoull(str, NULL, 10);
 		*args += 1;
-		return imap_fetch_add_changed_since(ctx, num);
+		return imap_fetch_add_changed_since(ctx, modseq);
 	}
 	if (strcmp(name, "VANISHED") == 0 && ctx->cmd->uid) {
 		if ((ctx->client->enabled_features &
--- a/src/imap/cmd-select.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/imap/cmd-select.c	Wed Apr 07 01:49:00 2010 +0300
@@ -106,7 +106,7 @@
 		     const struct imap_arg *args)
 {
 	const struct imap_arg *list_args;
-	const char *arg1, *arg2;
+	const char *str;
 	unsigned int count;
 
 	if ((ctx->cmd->client->enabled_features &
@@ -120,23 +120,23 @@
 		return FALSE;
 	}
 
-	if (!imap_arg_get_atom(&args[0], &arg1) ||
-	    !imap_arg_get_atom(&args[1], &arg2)) {
+	if (!imap_arg_get_atom(&args[0], &str) ||
+	    str_to_uint32(str, &ctx->qresync_uid_validity) < 0 ||
+	    !imap_arg_get_atom(&args[1], &str) ||
+	    str_to_uint64(str, &ctx->qresync_modseq) < 0) {
 		client_send_command_error(ctx->cmd,
 					  "Invalid QRESYNC parameters");
 		return FALSE;
 	}
 	args += 2;
-	ctx->qresync_uid_validity = strtoul(arg1, NULL, 10);
-	ctx->qresync_modseq = strtoull(arg2, NULL, 10);
 
-	if (!imap_arg_get_atom(args, &arg1)) {
+	if (!imap_arg_get_atom(args, &str)) {
 		i_array_init(&ctx->qresync_known_uids, 64);
 		seq_range_array_add_range(&ctx->qresync_known_uids,
 					  1, (uint32_t)-1);
 	} else {
 		i_array_init(&ctx->qresync_known_uids, 64);
-		if (imap_seq_set_parse(arg1, &ctx->qresync_known_uids) < 0) {
+		if (imap_seq_set_parse(str, &ctx->qresync_known_uids) < 0) {
 			client_send_command_error(ctx->cmd,
 						  "Invalid QRESYNC known-uids");
 			return FALSE;
--- a/src/imap/cmd-store.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/imap/cmd-store.c	Wed Apr 07 01:49:00 2010 +0300
@@ -57,7 +57,11 @@
 		}
 
 		if (strcasecmp(name, "UNCHANGEDSINCE") == 0) {
-			ctx->max_modseq = strtoull(value, NULL, 10);
+			if (str_to_uint64(value, &ctx->max_modseq) < 0) {
+				client_send_command_error(ctx->cmd,
+							  "Invalid modseq");
+				return FALSE;
+			}
 			client_enable(ctx->cmd->client,
 				      MAILBOX_FEATURE_CONDSTORE);
 		} else {
--- a/src/lib-auth/auth-master.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-auth/auth-master.c	Wed Apr 07 01:49:00 2010 +0300
@@ -464,11 +464,13 @@
 	p_array_init(&reply_r->extra_fields, pool, 64);
 
 	for (; *fields != NULL; fields++) {
-		if (strncmp(*fields, "uid=", 4) == 0)
-			reply_r->uid = strtoul(*fields + 4, NULL, 10);
-		else if (strncmp(*fields, "gid=", 4) == 0)
-			reply_r->gid = strtoul(*fields + 4, NULL, 10);
-		else if (strncmp(*fields, "home=", 5) == 0)
+		if (strncmp(*fields, "uid=", 4) == 0) {
+			if (str_to_uid(*fields + 4, &reply_r->uid) < 0)
+				i_error("Invalid uid in reply");
+		} else if (strncmp(*fields, "gid=", 4) == 0) {
+			if (str_to_gid(*fields + 4, &reply_r->gid) < 0)
+				i_error("Invalid gid in reply");
+		} else if (strncmp(*fields, "home=", 5) == 0)
 			reply_r->home = p_strdup(pool, *fields + 5);
 		else if (strncmp(*fields, "chroot=", 7) == 0)
 			reply_r->chroot = p_strdup(pool, *fields + 7);
--- a/src/lib-auth/auth-server-connection.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-auth/auth-server-connection.c	Wed Apr 07 01:49:00 2010 +0300
@@ -72,7 +72,10 @@
 		return -1;
 	}
 
-	conn->server_pid = (unsigned int)strtoul(args[0], NULL, 10);
+	if (str_to_uint(args[0], &conn->server_pid) < 0) {
+		i_error("BUG: Authentication server sent invalid PID");
+		return -1;
+	}
 	return 0;
 }
 
@@ -84,12 +87,11 @@
 		i_error("BUG: Authentication server already sent handshake");
 		return -1;
 	}
-	if (args[0] == NULL) {
+	if (args[0] == NULL ||
+	    str_to_uint(args[0], &conn->connect_uid) < 0) {
 		i_error("BUG: Authentication server sent broken CUID line");
 		return -1;
 	}
-
-	conn->connect_uid = (unsigned int)strtoul(args[0], NULL, 10);
 	return 0;
 }
 
@@ -135,11 +137,10 @@
 	struct auth_client_request *request;
 	unsigned int id;
 
-	if (id_arg == NULL) {
+	if (id_arg == NULL || str_to_uint(id_arg, &id) < 0) {
 		i_error("BUG: Authentication server input missing ID");
 		return -1;
 	}
-	id = (unsigned int)strtoul(id_arg, NULL, 10);
 
 	request = hash_table_lookup(conn->requests, POINTER_CAST(id));
 	if (request == NULL) {
@@ -255,8 +256,8 @@
 
 		/* make sure the major version matches */
 		if (strncmp(line, "VERSION\t", 8) != 0 ||
-		    atoi(t_strcut(line + 8, '\t')) !=
-		    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+		    !str_uint_equals(t_strcut(line + 8, '\t'),
+				     AUTH_CLIENT_PROTOCOL_MAJOR_VERSION)) {
 			i_error("Authentication server not compatible with "
 				"this client (mixed old and new binaries?)");
 			auth_server_connection_disconnect(conn);
--- a/src/lib-dict/dict-client.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-dict/dict-client.c	Wed Apr 07 01:49:00 2010 +0300
@@ -300,7 +300,10 @@
 				line);
 			return 0;
 		}
-		id = strtoul(line+2, NULL, 10);
+		if (str_to_uint(line+2, &id) < 0) {
+			i_error("dict-client: Invalid ID");
+			return 0;
+		}
 		client_dict_finish_transaction(dict, id, ret);
 		return 0;
 	}
--- a/src/lib-dict/dict-db.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-dict/dict-db.c	Wed Apr 07 01:49:00 2010 +0300
@@ -423,8 +423,12 @@
 	dkey.size = strlen(key);
 
 	if (dict->value_type == DICT_DATA_TYPE_UINT32) {
-		uint32_t ivalue = (uint32_t)strtoul(value, NULL, 10);
+		uint32_t ivalue;
 
+		if (str_to_uint32(value, &ivalue) < 0) {
+			i_error("db: Value not uint32: %s", value);
+			ivalue = 0;
+		}
 		ddata.data = &ivalue;
 		ddata.size = sizeof(ivalue);
 	} else {
--- a/src/lib-master/master-login-auth.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-master/master-login-auth.c	Wed Apr 07 01:49:00 2010 +0300
@@ -128,11 +128,11 @@
 	/* <id> <userid> [..] */
 
 	list = t_strsplit(args, "\t");
-	if (list[0] == NULL || list[1] == NULL) {
+	if (list[0] == NULL || list[1] == NULL ||
+	    str_to_uint(list[0], &id) < 0) {
 		i_error("Auth server sent corrupted USER line");
 		return FALSE;
 	}
-	id = (unsigned int)strtoul(list[0], NULL, 10);
 
 	request = master_login_auth_lookup_request(auth, id);
 	if (request != NULL) {
@@ -149,7 +149,11 @@
 	struct master_login_auth_request *request;
 	unsigned int id;
 
-	id = (unsigned int)strtoul(args, NULL, 10);
+	if (str_to_uint(args, &id) < 0) {
+		i_error("Auth server sent corrupted NOTFOUND line");
+		return FALSE;
+	}
+
 	request = master_login_auth_lookup_request(auth, id);
 	if (request != NULL) {
 		i_error("Authenticated user not found from userdb");
@@ -169,7 +173,7 @@
 	unsigned int i, id;
 
 	args = t_strsplit(args_line, "\t");
-	if (args[0] == NULL) {
+	if (args[0] == NULL || str_to_uint(args[0], &id) < 0) {
 		i_error("Auth server sent broken FAIL line");
 		return FALSE;
 	}
@@ -178,7 +182,6 @@
 			error = args[i] + 7;
 	}
 
-	id = (unsigned int)strtoul(args[0], NULL, 10);
 	request = master_login_auth_lookup_request(auth, id);
 	if (request != NULL) {
 		if (error != NULL)
@@ -217,8 +220,8 @@
 
 		/* make sure the major version matches */
 		if (strncmp(line, "VERSION\t", 8) != 0 ||
-		    atoi(t_strcut(line + 8, '\t')) !=
-		    AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
+		    !str_uint_equals(t_strcut(line + 8, '\t'),
+				     AUTH_MASTER_PROTOCOL_MAJOR_VERSION)) {
 			i_error("Authentication server not compatible with "
 				"master process (mixed old and new binaries?)");
 			master_login_auth_disconnect(auth);
--- a/src/lib-master/master-service.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-master/master-service.c	Wed Apr 07 01:49:00 2010 +0300
@@ -254,8 +254,6 @@
 bool master_service_parse_option(struct master_service *service,
 				 int opt, const char *arg)
 {
-	int i;
-
 	switch (opt) {
 	case 'c':
 		service->config_path = arg;
@@ -273,9 +271,8 @@
 		service->flags |= MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS;
 		break;
 	case 's':
-		if ((i = atoi(arg)) < 0)
+		if (str_to_uint(arg, &service->socket_count) < 0)
 			i_fatal("Invalid socket count: %s", arg);
-                service->socket_count = i;
 		break;
 	case 'L':
 		service->log_directly = TRUE;
@@ -343,25 +340,22 @@
 
 		/* initialize master_status structure */
 		value = getenv(MASTER_UID_ENV);
-		if (value == NULL)
-			i_fatal(MASTER_UID_ENV" not set");
+		if (value == NULL ||
+		    str_to_uint(value, &service->master_status.uid) < 0)
+			i_fatal(MASTER_UID_ENV" missing");
 		service->master_status.pid = getpid();
-		service->master_status.uid =
-			(unsigned int)strtoul(value, NULL, 10);
 
 		/* set the default limit */
 		value = getenv(MASTER_CLIENT_LIMIT_ENV);
-		count = value == NULL ? 0 :
-			(unsigned int)strtoul(value, NULL, 10);
-		if (count == 0)
-			i_fatal(MASTER_CLIENT_LIMIT_ENV" not set");
+		if (value == NULL || str_to_uint(value, &count) < 0 ||
+		    count == 0)
+			i_fatal(MASTER_CLIENT_LIMIT_ENV" missing");
 		master_service_set_client_limit(service, count);
 
 		/* set the default service count */
 		value = getenv(MASTER_SERVICE_COUNT_ENV);
-		count = value == NULL ? 0 :
-			(unsigned int)strtoul(value, NULL, 10);
-		if (count > 0)
+		if (value != NULL && str_to_uint(value, &count) == 0 &&
+		    count > 0)
 			master_service_set_service_count(service, count);
 
 		/* start listening errors for status fd, it means master died */
--- a/src/lib-settings/settings-parser.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-settings/settings-parser.c	Wed Apr 07 01:49:00 2010 +0300
@@ -310,15 +310,31 @@
 get_uint(struct setting_parser_context *ctx, const char *value,
 	 unsigned int *result_r)
 {
-	int num;
+	if (str_to_uint(value, result_r) < 0) {
+		ctx->error = p_strdup_printf(ctx->parser_pool,
+			"Invalid number %s: %s", value,
+			str_num_error(value));
+		return -1;
+	}
+	return 0;
+}
 
-	/* use %i so we can handle eg. 0600 as octal value with umasks */
-	if (!sscanf(value, "%i", &num) || num < 0) {
+static int
+get_octal(struct setting_parser_context *ctx, const char *value,
+	  unsigned int *result_r)
+{
+	unsigned long long octal;
+	char *p;
+
+	if (*value != '0')
+		return get_uint(ctx, value, result_r);
+
+	octal = strtoull(value + 1, &p, 4);
+	if (*p != '\0' || octal > UINT_MAX) {
 		ctx->error = p_strconcat(ctx->parser_pool, "Invalid number: ",
 					 value, NULL);
-		return -1;
 	}
-	*result_r = num;
+	*result_r = (unsigned int)octal;
 	return 0;
 }
 
@@ -573,8 +589,11 @@
 			return -1;
 		break;
 	case SET_UINT:
+		if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
+			return -1;
+		break;
 	case SET_UINT_OCT:
-		if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
+		if (get_octal(ctx, value, (unsigned int *)ptr) < 0)
 			return -1;
 		break;
 	case SET_TIME:
--- a/src/lib-sql/sql-api.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-sql/sql-api.c	Wed Apr 07 01:49:00 2010 +0300
@@ -195,17 +195,15 @@
 			break;
 		}
 		case SQL_TYPE_UINT: {
-			if (value != NULL) {
-				*((unsigned int *)ptr) =
-					strtoul(value, NULL, 10);
-			}
+			if (value != NULL &&
+			    str_to_uint(value, (unsigned int *)ptr) < 0)
+				i_error("sql: Value not uint: %s", value);
 			break;
 		}
 		case SQL_TYPE_ULLONG: {
-			if (value != NULL) {
-				*((unsigned long long *)ptr) =
-					strtoull(value, NULL, 10);
-			}
+			if (value != NULL &&
+			    str_to_ullong(value, (unsigned long long *)ptr) < 0)
+				i_error("sql: Value not ullong: %s", value);
 			break;
 		}
 		case SQL_TYPE_BOOL: {
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.c	Wed Apr 07 01:49:00 2010 +0300
@@ -699,9 +699,10 @@
 		if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX,
 			    strlen(MDBOX_MAIL_FILE_PREFIX)) != 0)
 			continue;
+		if (str_to_uint32(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
+				  &file_id) < 0)
+			continue;
 
-		file_id = strtoul(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
-				  NULL, 10);
 		if (min_file_id > file_id)
 			min_file_id = file_id;
 	}
--- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c	Wed Apr 07 01:49:00 2010 +0300
@@ -223,8 +223,7 @@
 	i_assert(fname != NULL);
 	fname += strlen(MDBOX_MAIL_FILE_PREFIX) + 1;
 
-	file_id = strtoul(fname, NULL, 10);
-	if (!is_numeric(fname, '\0') || file_id == 0) {
+	if (str_to_uint32(fname, &file_id) < 0 || file_id == 0) {
 		len = strlen(fname);
 		if (len > 7 && strcmp(fname + len - 7, ".broken") != 0) {
 			i_warning("dbox rebuild: File name is missing ID: %s",
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c	Wed Apr 07 01:49:00 2010 +0300
@@ -373,13 +373,13 @@
 		if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX,
 			    strlen(MDBOX_MAIL_FILE_PREFIX)) != 0)
 			continue;
+		if (str_to_uint32(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
+				  &file_id) < 0)
+			continue;
 
 		str_truncate(path, dir_len);
 		str_append(path, d->d_name);
 
-		file_id = strtoul(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
-				  NULL, 10);
-
 		if (stat(str_c(path), &st) < 0) {
 			mail_storage_set_critical(storage,
 				"stat(%s) failed: %m", str_c(path));
--- a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c	Wed Apr 07 01:49:00 2010 +0300
@@ -58,8 +58,7 @@
 {
 	struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)ctx->box;
 	struct dbox_file *file;
-	unsigned long uid;
-	char *p;
+	uint32_t uid;
 	int ret;
 
 	if (strncmp(fname, SDBOX_MAIL_FILE_PREFIX,
@@ -67,8 +66,7 @@
 		return 0;
 	fname += strlen(SDBOX_MAIL_FILE_PREFIX);
 
-	uid = strtoul(fname, &p, 10);
-	if (*p != '\0' || uid == 0 || uid >= (uint32_t)-1) {
+	if (str_to_uint32(fname, &uid) < 0 || uid == 0) {
 		i_warning("dbox %s: Ignoring invalid filename %s",
 			  ctx->box->path, fname);
 		return 0;
--- a/src/lib-storage/index/maildir/maildir-keywords.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/index/maildir/maildir-keywords.c	Wed Apr 07 01:49:00 2010 +0300
@@ -113,7 +113,8 @@
 	struct stat st;
 	char *line, *p, *new_name;
 	const char **strp;
-	int fd, idx;
+	unsigned int idx;
+	int fd;
 
         /* Remember that we rely on uidlist file locking in here. That's why
            we rely on stat()'s timestamp and don't bother handling ESTALE
@@ -166,8 +167,8 @@
 		}
 		*p++ = '\0';
 
-		idx = atoi(line);
-		if (idx < 0 || idx >= MAILDIR_MAX_KEYWORDS || *p == '\0') {
+		if (str_to_uint(line, &idx) < 0 ||
+		    idx >= MAILDIR_MAX_KEYWORDS || *p == '\0') {
 			/* shouldn't happen */
 			continue;
 		}
--- a/src/lib-storage/index/maildir/maildir-mail.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Wed Apr 07 01:49:00 2010 +0300
@@ -273,8 +273,6 @@
 	struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
 	enum maildir_uidlist_rec_ext_key key;
 	const char *path, *fname, *value;
-	uoff_t size;
-	char *p;
 
 	if (_mail->uid != 0) {
 		if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
@@ -299,13 +297,8 @@
 			MAILDIR_UIDLIST_REC_EXT_PSIZE;
 		value = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
 						   key);
-		if (value != NULL) {
-			size = strtoull(value, &p, 10);
-			if (*p == '\0') {
-				*size_r = size;
-				return 1;
-			}
-		}
+		if (value != NULL && str_to_uoff(value, size_r) == 0)
+			return 1;
 	}
 	return 0;
 }
--- a/src/lib-storage/mail-search-build.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/mail-search-build.c	Wed Apr 07 01:49:00 2010 +0300
@@ -93,14 +93,12 @@
 {
 	struct mail_search_arg *sarg;
 	const char *value;
-	char *p;
 
 	*next_sarg = sarg = search_arg_new(data->pool, type);
 	if (!arg_get_next(data, args, &value))
 		return FALSE;
 
-	sarg->value.size = strtoull(value, &p, 10);
-	if (*p != '\0') {
+	if (str_to_uoff(value, &sarg->value.size) < 0) {
 		data->error = "Invalid search size parameter";
 		return FALSE;
 	}
@@ -137,15 +135,13 @@
 {
 	struct mail_search_arg *sarg;
 	const char *value;
-	unsigned long interval;
-	char *p;
+	uint32_t interval;
 
 	*next_sarg = sarg = search_arg_new(data->pool, type);
 	if (!arg_get_next(data, args, &value))
 		return FALSE;
 
-	interval = strtoul(value, &p, 10);
-	if (interval == 0 || *p != '\0') {
+	if (str_to_uint32(value, &interval) < 0 || interval == 0) {
 		data->error = "Invalid search interval parameter";
 		return FALSE;
 	}
@@ -251,11 +247,10 @@
 		if (!arg_get_next(data, args, &value))
 			return FALSE;
 	}
-	if (!is_numeric(value, '\0')) {
+	if (str_to_uint64(value, &sarg->value.modseq->modseq) < 0) {
 		data->error = "Invalid MODSEQ value";
 		return FALSE;
 	}
-	sarg->value.modseq->modseq = strtoull(value, NULL, 10);
 	return TRUE;
 }
 
--- a/src/lib-storage/mail-storage-service.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib-storage/mail-storage-service.c	Wed Apr 07 01:49:00 2010 +0300
@@ -260,13 +260,9 @@
 static bool parse_uid(const char *str, uid_t *uid_r)
 {
 	struct passwd *pw;
-	char *p;
 
-	if (*str >= '0' && *str <= '9') {
-		*uid_r = (uid_t)strtoul(str, &p, 10);
-		if (*p == '\0')
-			return TRUE;
-	}
+	if (str_to_uid(str, uid_r) == 0)
+		return TRUE;
 
 	pw = getpwnam(str);
 	if (pw == NULL)
@@ -279,13 +275,9 @@
 static bool parse_gid(const char *str, gid_t *gid_r)
 {
 	struct group *gr;
-	char *p;
 
-	if (*str >= '0' && *str <= '9') {
-		*gid_r = (gid_t)strtoul(str, &p, 10);
-		if (*p == '\0')
-			return TRUE;
-	}
+	if (str_to_gid(str, gid_r) == 0)
+		return TRUE;
 
 	gr = getgrnam(str);
 	if (gr == NULL)
--- a/src/lib/file-dotlock.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib/file-dotlock.c	Wed Apr 07 01:49:00 2010 +0300
@@ -120,9 +120,8 @@
 	if (strcmp(host, my_hostname) != 0)
 		return -1;
 
-	if (!is_numeric(buf, '\0'))
+	if (str_to_pid(buf, &pid) < 0)
 		return -1;
-	pid = (pid_t)strtoul(buf, NULL, 0);
 	if (pid <= 0)
 		return -1;
 	return pid;
--- a/src/lib/network.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib/network.c	Wed Apr 07 01:49:00 2010 +0300
@@ -776,7 +776,7 @@
 		    unsigned int *bits_r)
 {
 	const char *p;
-	int bits, max_bits;
+	unsigned int bits, max_bits;
 
 	p = strchr(network, '/');
 	if (p != NULL)
@@ -791,8 +791,7 @@
 		bits = max_bits;
 	} else {
 		/* get the network mask */
-		bits = atoi(p);
-		if (bits < 0 || bits > max_bits)
+		if (str_to_uint(p, &bits) < 0 || bits > max_bits)
 			return -1;
 	}
 	*bits_r = bits;
--- a/src/lib/restrict-access.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/lib/restrict-access.c	Wed Apr 07 01:49:00 2010 +0300
@@ -151,9 +151,10 @@
 static gid_t get_group_id(const char *name)
 {
 	struct group *group;
+	gid_t gid;
 
-	if (is_numeric(name, '\0'))
-		return (gid_t)strtoul(name, NULL, 10);
+	if (str_to_gid(name, &gid) == 0)
+		return gid;
 
 	group = getgrnam(name);
 	if (group == NULL)
@@ -382,16 +383,26 @@
 
 	restrict_access_init(&set);
 
-	if ((value = getenv("RESTRICT_SETUID")) != NULL)
-		set.uid = (uid_t)strtol(value, NULL, 10);
-	if ((value = getenv("RESTRICT_SETGID")) != NULL)
-		set.gid = (gid_t)strtol(value, NULL, 10);
-	if ((value = getenv("RESTRICT_SETGID_PRIV")) != NULL)
-		set.privileged_gid = (gid_t)strtol(value, NULL, 10);
-	if ((value = getenv("RESTRICT_GID_FIRST")) != NULL)
-		set.first_valid_gid = (gid_t)strtol(value, NULL, 10);
-	if ((value = getenv("RESTRICT_GID_LAST")) != NULL)
-		set.last_valid_gid = (gid_t)strtol(value, NULL, 10);
+	if ((value = getenv("RESTRICT_SETUID")) != NULL) {
+		if (str_to_uid(value, &set.uid) < 0)
+			i_fatal("Invalid uid: %s", value);
+	}
+	if ((value = getenv("RESTRICT_SETGID")) != NULL) {
+		if (str_to_gid(value, &set.gid) < 0)
+			i_fatal("Invalid gid: %s", value);
+	}
+	if ((value = getenv("RESTRICT_SETGID_PRIV")) != NULL) {
+		if (str_to_gid(value, &set.privileged_gid) < 0)
+			i_fatal("Invalid privileged_gid: %s", value);
+	}
+	if ((value = getenv("RESTRICT_GID_FIRST")) != NULL) {
+		if (str_to_gid(value, &set.first_valid_gid) < 0)
+			i_fatal("Invalid first_valid_gid: %s", value);
+	}
+	if ((value = getenv("RESTRICT_GID_LAST")) != NULL) {
+		if (str_to_gid(value, &set.last_valid_gid) < 0)
+			i_fatal("Invalid last_value_gid: %s", value);
+	}
 
 	set.extra_groups = null_if_empty(getenv("RESTRICT_SETEXTRAGROUPS"));
 	set.system_groups_user = null_if_empty(getenv("RESTRICT_USER"));
--- a/src/plugins/acl/acl-backend-vfile.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/acl/acl-backend-vfile.c	Wed Apr 07 01:49:00 2010 +0300
@@ -89,9 +89,13 @@
 	if (*tmp != NULL)
 		tmp++;
 	for (; *tmp != NULL; tmp++) {
-		if (strncmp(*tmp, "cache_secs=", 11) == 0)
-			backend->cache_secs = atoi(*tmp + 11);
-		else {
+		if (strncmp(*tmp, "cache_secs=", 11) == 0) {
+			if (str_to_uint(*tmp + 11, &backend->cache_secs) < 0) {
+				i_error("acl vfile: Invalid cache_secs value: %s",
+					*tmp + 11);
+				return -1;
+			}
+		} else {
 			i_error("acl vfile: Unknown parameter: %s", *tmp);
 			return -1;
 		}
--- a/src/plugins/expire/expire-env.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/expire/expire-env.c	Wed Apr 07 01:49:00 2010 +0300
@@ -72,7 +72,7 @@
 		i_fatal("expire: Missing expire time for mailbox '%s'",
 			rule.pattern);
 	}
-	if (is_numeric(args[0], '\0')) {
+	if (str_is_numeric(args[0], '\0')) {
 		i_fatal("expire: Missing expire time specifier for mailbox "
 			"'%s': %s (add e.g. 'days')", rule.pattern, args[0]);
 	}
--- a/src/plugins/fts-squat/fts-backend-squat.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/fts-squat/fts-backend-squat.c	Wed Apr 07 01:49:00 2010 +0300
@@ -27,19 +27,17 @@
 fts_backend_squat_set(struct squat_fts_backend *backend, const char *str)
 {
 	const char *const *tmp;
-	int len;
+	unsigned int len;
 
 	for (tmp = t_strsplit_spaces(str, " "); *tmp != NULL; tmp++) {
 		if (strncmp(*tmp, "partial=", 8) == 0) {
-			len = atoi(*tmp + 8);
-			if (len <= 0) {
+			if (str_to_uint(*tmp + 8, &len) < 0 || len == 0) {
 				i_fatal("fts_squat: Invalid partial len: %s",
 					*tmp + 8);
 			}
 			squat_trie_set_partial_len(backend->trie, len);
 		} else if (strncmp(*tmp, "full=", 5) == 0) {
-			len = atoi(*tmp + 5);
-			if (len <= 0) {
+			if (str_to_uint(*tmp + 5, &len) < 0 || len == 0) {
 				i_fatal("fts_squat: Invalid full len: %s",
 					*tmp + 5);
 			}
--- a/src/plugins/imap-quota/imap-quota-plugin.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/imap-quota/imap-quota-plugin.c	Wed Apr 07 01:49:00 2010 +0300
@@ -181,12 +181,11 @@
 	for (; !IMAP_ARG_IS_EOL(list_args); list_args += 2) {
 		if (!imap_arg_get_atom(&list_args[0], &name) ||
 		    !imap_arg_get_atom(&list_args[1], &value_str) ||
-		    !is_numeric(value_str, '\0')) {
+		    str_to_uint64(value_str, &value) < 0) {
 			client_send_command_error(cmd, "Invalid arguments.");
 			return TRUE;
 		}
 
-                value = strtoull(value_str, NULL, 10);
 		if (quota_set_resource(root, name, value, &error) < 0) {
 			client_send_command_error(cmd, error);
 			return TRUE;
--- a/src/plugins/imap-zlib/imap-zlib-plugin.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/imap-zlib/imap-zlib-plugin.c	Wed Apr 07 01:49:00 2010 +0300
@@ -104,8 +104,8 @@
 
 	value = mail_user_plugin_getenv(client->user,
 					"imap_zlib_compress_level");
-	level = value == NULL ? 0 : atoi(value);
-	if (level <= 0 || level > 9)
+	if (str_to_uint(value, &level) < 0 ||
+	    level <= 0 || level > 9)
 		level = IMAP_COMPRESS_DEFAULT_LEVEL;
 
 	old_input = client->input;
--- a/src/plugins/trash/trash-plugin.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/trash/trash-plugin.c	Wed Apr 07 01:49:00 2010 +0300
@@ -271,7 +271,12 @@
 
 		trash = array_append_space(&tuser->trash_boxes);
 		trash->name = p_strdup(user->pool, name+1);
-		trash->priority = atoi(t_strdup_until(line, name));
+		if (str_to_int(t_strdup_until(line, name),
+			       &trash->priority) < 0) {
+			i_error("trash: Invalid priority for mailbox '%s'",
+				trash->name);
+			ret = -1;
+		}
 
 		if (!trash_find_storage(user, trash)) {
 			i_error("trash: Namespace not found for mailbox '%s'",
--- a/src/plugins/zlib/zlib-plugin.c	Wed Apr 07 01:48:03 2010 +0300
+++ b/src/plugins/zlib/zlib-plugin.c	Wed Apr 07 01:49:00 2010 +0300
@@ -44,7 +44,7 @@
 	union mail_user_module_context module_ctx;
 
 	const struct zlib_handler *save_handler;
-	int save_level;
+	unsigned int save_level;
 };
 
 const char *zlib_plugin_version = DOVECOT_VERSION;
@@ -394,8 +394,8 @@
 	}
 	name = mail_user_plugin_getenv(user, "zlib_save_level");
 	if (name != NULL) {
-		zuser->save_level = atoi(name);
-		if (zuser->save_level < 1 || zuser->save_level > 9) {
+		if (str_to_uint(name, &zuser->save_level) < 0 ||
+		    zuser->save_level < 1 || zuser->save_level > 9) {
 			i_error("zlib_save_level: Level must be between 1..9");
 			zuser->save_level = 0;
 		}