[dovecot-cvs] dovecot/src/master login-process.c, 1.72, 1.73 mail-process.c, 1.90, 1.91 mail-process.h, 1.8, 1.9 main.c, 1.78, 1.79 master-settings.c, 1.123, 1.124 master-settings.h, 1.82, 1.83

cras at dovecot.org cras at dovecot.org
Fri Apr 14 21:21:03 EEST 2006


Update of /var/lib/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv5712/master

Modified Files:
	login-process.c mail-process.c mail-process.h main.c 
	master-settings.c master-settings.h 
Log Message:
If we have plugins set and imap_capability unset, figure out the IMAP
capabilities automatically by running imap binary at startup. The generated
capability list isn't updated until Dovecot is restarted completely, so if
you add or remove IMAP plugins you should restart.



Index: login-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/login-process.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- login-process.c	9 Apr 2006 14:36:03 -0000	1.72
+++ login-process.c	14 Apr 2006 18:20:57 -0000	1.73
@@ -88,9 +88,10 @@
 
 		t_push();
 		master_reply.success =
-			create_mail_process(group, request->fd,
-					    &request->local_ip,
-					    &request->remote_ip, user, args);
+			create_mail_process(group->process_type, group->set,
+					    request->fd, &request->local_ip,
+					    &request->remote_ip, user, args,
+					    FALSE);
 		t_pop();
 	}
 
@@ -455,6 +456,13 @@
 	env_put(t_strconcat("LOG_FORMAT=", set->login_log_format, NULL));
 	if (set->login_greeting_capability)
 		env_put("GREETING_CAPABILITY=1");
+
+	if (group->process_type == PROCESS_TYPE_IMAP) {
+		env_put(t_strconcat("CAPABILITY_STRING=",
+				    *set->imap_capability != '\0' ?
+				    set->imap_capability :
+				    set->imap_generated_capability, NULL));
+	}
 }
 
 static pid_t create_login_process(struct login_group *group)

Index: mail-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/mail-process.c,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- mail-process.c	14 Apr 2006 10:52:55 -0000	1.90
+++ mail-process.c	14 Apr 2006 18:20:57 -0000	1.91
@@ -209,8 +209,10 @@
 				set->mail_max_keyword_length));
 	env_put(t_strdup_printf("IMAP_MAX_LINE_LENGTH=%u",
 				set->imap_max_line_length));
-	env_put(t_strconcat("IMAP_CAPABILITY=",
-			    set->imap_capability, NULL));
+	if (*set->imap_capability != '\0') {
+		env_put(t_strconcat("IMAP_CAPABILITY=",
+				    set->imap_capability, NULL));
+	}
 	env_put(t_strconcat("IMAP_CLIENT_WORKAROUNDS=",
 			    set->imap_client_workarounds, NULL));
 	env_put(t_strconcat("POP3_UIDL_FORMAT=",
@@ -372,12 +374,12 @@
 		"If you're sure this check was wrong, set nfs_check=no.", path);
 }
 
-bool create_mail_process(struct login_group *group, int socket,
-			 const struct ip_addr *local_ip,
+bool create_mail_process(enum process_type process_type, struct settings *set,
+			 int socket, const struct ip_addr *local_ip,
 			 const struct ip_addr *remote_ip,
-			 const char *user, const char *const *args)
+			 const char *user, const char *const *args,
+			 bool dump_capability)
 {
-	struct settings *set = group->set;
 	const struct var_expand_table *var_expand_table;
 	const char *p, *addr, *mail, *chroot_dir, *home_dir, *full_home_dir;
 	const char *system_user;
@@ -448,7 +450,13 @@
 		return FALSE;
 	}
 
-	log_fd = log_create_pipe(&log, 10);
+	if (!dump_capability)
+		log_fd = log_create_pipe(&log, 10);
+	else {
+		log = NULL;
+		log_fd = dup(STDERR_FILENO);
+		fd_close_on_exec(log_fd, TRUE);
+	}
 
 	pid = fork();
 	if (pid < 0) {
@@ -458,7 +466,7 @@
 	}
 
 	var_expand_table =
-		get_var_expand_table(process_names[group->process_type],
+		get_var_expand_table(process_names[process_type],
 				     user, home_given ? home_dir : NULL,
 				     net_ip2addr(local_ip),
 				     net_ip2addr(remote_ip),
@@ -468,10 +476,12 @@
 	if (pid != 0) {
 		/* master */
 		var_expand(str, set->mail_log_prefix, var_expand_table);
-		log_set_prefix(log, str_c(str));
 
 		mail_process_count++;
-		PID_ADD_PROCESS_TYPE(pid, group->process_type);
+		if (!dump_capability) {
+			log_set_prefix(log, str_c(str));
+			PID_ADD_PROCESS_TYPE(pid, process_type);
+		}
 		(void)close(log_fd);
 		return TRUE;
 	}
@@ -483,14 +493,16 @@
 	}
 #endif
 
-	str_append(str, "master-");
-	var_expand(str, set->mail_log_prefix, var_expand_table);
-	log_set_prefix(log, str_c(str));
+	if (!dump_capability) {
+		str_append(str, "master-");
+		var_expand(str, set->mail_log_prefix, var_expand_table);
+		log_set_prefix(log, str_c(str));
+	}
 
 	child_process_init_env();
 
 	/* move the client socket into stdin and stdout fds, log to stderr */
-	if (dup2(socket, 0) < 0)
+	if (dup2(dump_capability ? null_fd : socket, 0) < 0)
 		i_fatal("dup2(stdin) failed: %m");
 	if (dup2(socket, 1) < 0)
 		i_fatal("dup2(stdout) failed: %m");
@@ -508,6 +520,9 @@
 
 	restrict_process_size(set->mail_process_size, (unsigned int)-1);
 
+	if (dump_capability)
+		env_put("DUMP_CAPABILITY=1");
+
 	if (*home_dir == '\0')
 		ret = -1;
 	else {
@@ -568,7 +583,7 @@
 		}
 	}
 
-	if (set->nfs_check && !set->mmap_disable) {
+	if (set->nfs_check && !set->mmap_disable && !dump_capability) {
 		/* do this only once */
 		nfs_warn_if_found(getenv("MAIL"), home_dir);
 		set->nfs_check = FALSE;

Index: mail-process.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/mail-process.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mail-process.h	13 Jan 2006 20:26:40 -0000	1.8
+++ mail-process.h	14 Apr 2006 18:20:57 -0000	1.9
@@ -6,10 +6,11 @@
 
 void mail_process_exec(const char *protocol, const char *section);
 
-bool create_mail_process(struct login_group *group, int socket,
-			 const struct ip_addr *local_ip,
+bool create_mail_process(enum process_type process_type, struct settings *set,
+			 int socket, const struct ip_addr *local_ip,
 			 const struct ip_addr *remote_ip,
-			 const char *user, const char *const *args);
+			 const char *user, const char *const *args,
+			 bool dump_capability);
 
 void mail_process_destroyed(pid_t pid);
 

Index: main.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/main.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- main.c	9 Apr 2006 11:07:36 -0000	1.78
+++ main.c	14 Apr 2006 18:20:57 -0000	1.79
@@ -77,7 +77,8 @@
 	if (env_tz != NULL)
 		env_put(t_strconcat("TZ=", env_tz, NULL));
 
-	if (!syslog_facility_find(settings_root->defaults->syslog_facility,
+	if (settings_root == NULL ||
+	    !syslog_facility_find(settings_root->defaults->syslog_facility,
 				  &facility))
 		facility = LOG_MAIL;
 	env_put(t_strdup_printf("SYSLOG_FACILITY=%d", facility));
@@ -545,6 +546,7 @@
         lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
         lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
         lib_signals_set_handler(SIGPIPE, FALSE, NULL, NULL);
+        lib_signals_set_handler(SIGALRM, FALSE, NULL, NULL);
         lib_signals_set_handler(SIGHUP, TRUE, sig_reload_settings, NULL);
         lib_signals_set_handler(SIGUSR1, TRUE, sig_reopen_logs, NULL);
 

Index: master-settings.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/master-settings.c,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -d -r1.123 -r1.124
--- master-settings.c	14 Apr 2006 10:52:55 -0000	1.123
+++ master-settings.c	14 Apr 2006 18:20:57 -0000	1.124
@@ -4,10 +4,12 @@
 #include "array.h"
 #include "str.h"
 #include "istream.h"
+#include "fd-close-on-exec.h"
 #include "safe-mkdir.h"
 #include "mkdir-parents.h"
 #include "unlink-directory.h"
 #include "syslog-util.h"
+#include "mail-process.h"
 #include "settings.h"
 
 #include <stdio.h>
@@ -16,6 +18,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <pwd.h>
 
 enum settings_type {
@@ -350,7 +353,7 @@
 
 	/* imap */
 	MEMBER(imap_max_line_length) 65536,
-	MEMBER(imap_capability) NULL,
+	MEMBER(imap_capability) "",
 	MEMBER(imap_client_workarounds) "outlook-idle",
 
 	/* pop3 */
@@ -572,6 +575,90 @@
 	(void)closedir(dirp);
 }
 
+#ifdef HAVE_MODULES
+static bool get_imap_capability(struct settings *set)
+{
+	/* FIXME: pretty ugly code just for getting the capability
+	   automatically */
+	static const char *generated_capability = NULL;
+	static const char *args[] = {
+		"uid=65534",
+		"gid=65534",
+		NULL
+	};
+	struct ip_addr ip;
+	char buf[4096];
+	int fd[2], status;
+	ssize_t ret;
+	unsigned int pos;
+
+	if (generated_capability != NULL) {
+		/* Reloading configuration. Don't try to execute the imap
+		   process again. Too risky and the wait() call below will
+		   break it anyway. Just use the previous capability list we
+		   already had generated. */
+		set->imap_generated_capability =
+			p_strdup(settings_pool, generated_capability);
+		return TRUE;
+	}
+
+	memset(&ip, 0, sizeof(ip));
+	if (pipe(fd) < 0) {
+		i_error("pipe() failed: %m");
+		return FALSE;
+	}
+	fd_close_on_exec(fd[0], TRUE);
+	fd_close_on_exec(fd[1], TRUE);
+	if (!create_mail_process(MAIL_PROTOCOL_IMAP, set, fd[1],
+				 &ip, &ip, "dump-capability", args, TRUE)) {
+		(void)close(fd[0]);
+		(void)close(fd[1]);
+		return FALSE;
+	}
+	(void)close(fd[1]);
+
+	alarm(5);
+	if (wait(&status) == -1)
+		i_fatal("imap dump-capability process got stuck");
+	alarm(0);
+
+	if (status != 0) {
+		(void)close(fd[0]);
+		if (WIFSIGNALED(status)) {
+			i_error("imap dump-capability process "
+				"killed with signal %d", WTERMSIG(status));
+		} else {
+			i_error("imap dump-capability process returned %d",
+				status);
+		}
+		return FALSE;
+	}
+
+	pos = 0;
+	while ((ret = read(fd[0], buf + pos, sizeof(buf) - pos)) > 0)
+		pos += ret;
+
+	if (ret < 0) {
+		i_error("read(imap dump-capability process) failed: %m");
+		(void)close(fd[0]);
+		return FALSE;
+	}
+	(void)close(fd[0]);
+
+	if (pos == 0 || buf[pos-1] != '\n') {
+		i_error("imap dump-capability: Couldn't read capability "
+			"(got %u bytes)", pos);
+		return FALSE;
+	}
+	buf[pos-1] = '\0';
+
+	generated_capability = i_strdup(buf);
+	set->imap_generated_capability =
+		p_strdup(settings_pool, generated_capability);
+	return TRUE;
+}
+#endif
+
 static bool settings_verify(struct settings *set)
 {
 	const char *dir;
@@ -594,6 +681,11 @@
 			set->mail_plugin_dir);
 		return FALSE;
 	}
+	if (*set->mail_plugins != '\0' && set->protocol == MAIL_PROTOCOL_IMAP &&
+	    *set->imap_capability == '\0') {
+		if (!get_imap_capability(set))
+			return FALSE;
+	}
 #else
 	if (*set->mail_plugins != '\0') {
 		i_error("Module support wasn't built into Dovecot, "

Index: master-settings.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/master-settings.h,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- master-settings.h	14 Apr 2006 10:52:55 -0000	1.82
+++ master-settings.h	14 Apr 2006 18:20:57 -0000	1.83
@@ -118,6 +118,8 @@
 	/* .. */
 	uid_t login_uid;
 
+	const char *imap_generated_capability;
+
 	int listen_fd, ssl_listen_fd;
 	struct ip_addr listen_ip, ssl_listen_ip;
 	unsigned int listen_port, ssl_listen_port;



More information about the dovecot-cvs mailing list