You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by ms...@apache.org on 2004/05/28 00:24:44 UTC

svn commit: rev 20519 - incubator/spamassassin/trunk/spamc

Author: mss
Date: Thu May 27 15:24:43 2004
New Revision: 20519

Modified:
   incubator/spamassassin/trunk/spamc/spamc.c
Log:
* Refactored the username determination into its own subroutine. This actually fixed a bug on Windows as WSACleanup() is now called on failure.
* Made the memory for username allocated dynamically. Why always use 255 bytes with some weird buffer handling when often a few bytes are enough?
* Got rid of an ifdef-bug on Windows I introduced before.


Modified: incubator/spamassassin/trunk/spamc/spamc.c
==============================================================================
--- incubator/spamassassin/trunk/spamc/spamc.c	(original)
+++ incubator/spamassassin/trunk/spamc/spamc.c	Thu May 27 15:24:43 2004
@@ -166,7 +166,7 @@
 
 int
 read_args(int argc, char **argv,
-          int *max_size, const char **username,
+          int *max_size, char **username,
           struct transport *ptrn)
 {
 #ifndef _WIN32
@@ -336,11 +336,8 @@
 	*fd = STDOUT_FILENO;
 	return;
     }
-#ifdef _WIN32
-    libspamc_log(flags, LOG_CRIT, "THIS MUST NOT HAPPEN AS -e IS NOT SUPPORTED UNDER WINDOWS.");
-    exit(EX_OSERR);
-#endif
     
+#ifndef _WIN32
     /* Create a pipe for communication between child and parent. */
     if (pipe(pipe_fds)) {
 	libspamc_log(flags, LOG_ERR, "pipe creation failed: %m");
@@ -378,15 +375,73 @@
     
     /* Whoa, something failed... */
     libspamc_log(flags, LOG_ERR, "exec failed: %m");
+#else
+    libspamc_log(flags, LOG_CRIT, "THIS MUST NOT HAPPEN AS -e IS NOT SUPPORTED UNDER WINDOWS.");
+#endif
     exit(EX_OSERR);
 }
 
 
+/**
+ * Determines the username of the uid spamc is running under.
+ *
+ * If the program's caller didn't identify the user to run as, use the
+ * current user for this. Note that we're not talking about UNIX perm-
+ * issions, but giving SpamAssassin a username so it can do per-user
+ * configuration (whitelists & the like).
+ *
+ * Allocates memory for the username, returns EX_OK if successful.
+ */
+int
+get_current_user(char **username)
+{
+#ifdef _WIN32
+
+    return EX_OK;
+    
+#else
+    struct passwd *curr_user;
+    
+    /* Get the passwd information for the effective uid spamc is running
+     * under. Setting errno to zero is recommended in the manpage.
+     */
+    errno = 0;
+    curr_user = getpwuid(geteuid());
+    if (curr_user == NULL) {
+        perror("getpwuid() failed");
+        goto fail;
+    }
+    
+    /* Since "curr_user" points to static library data, we don't wish to
+     * risk some other part of the system overwriting it, so we copy the 
+     * username to our own buffer -- then this won't arise as a problem.
+     */
+    *username = strdup(curr_user->pw_name);
+    if (*username == NULL) {
+        goto fail;
+    }
+
+    return EX_OK;
+    
+fail:
+    /* FIXME: The handling of SPAMC_CHECK_ONLY should probably be moved to 
+     *        the end of main()
+     */
+    if (flags & SPAMC_CHECK_ONLY) {
+        printf("0/0\n");
+        return EX_NOTSPAM;
+    }
+    return EX_OSERR;
+    
+#endif
+}
+
+
 int
 main(int argc, char *argv[])
 {
     int max_size;
-    const char *username;
+    char *username;
     struct transport trans;
     struct message m;
     int out_fd = -1;
@@ -411,41 +466,13 @@
    if ((ret = read_args(argc, argv, &max_size, &username, &trans)) != EX_OK)
        return ret;
 
-#ifndef _WIN32
-    /**********************************************************************
-     * DETERMINE USER
-     *
-     * If the program's caller didn't identify the user to run as, use the
-     * current user for this. Note that we're not talking about UNIX perm-
-     * issions, but giving SpamAssassin a username so it can do per-user
-     * configuration (whitelists & the like).
-     *
-     * Since "curr_user" points to static library data, we don't wish to
-     * risk some other part of the system overwriting it, so we copy the 
-     * username to our own buffer -- then this won't arise as a problem.
-     */
-    if (username == NULL) {
-	static char userbuf[256];
-	struct passwd *curr_user;
-
-	curr_user = getpwuid(geteuid());
-	if (curr_user == NULL) {
-	    perror("getpwuid failed");
-	    if (flags & SPAMC_CHECK_ONLY) {
-		printf("0/0\n");
-		return EX_NOTSPAM;
-	    }
-	    return EX_OSERR;
-	}
-        
-	memset(userbuf, 0, sizeof userbuf);
-	strncpy(userbuf, curr_user->pw_name, sizeof userbuf - 1);
-	userbuf[sizeof userbuf - 1] = '\0';
-	username = userbuf;
-    }
-#endif
-
-    if ((flags & SPAMC_RANDOMIZE_HOSTS) != 0) {
+   if (username == NULL) {
+       ret = get_current_user(&username);
+       if ( ret != EX_OK )
+           goto finish;
+   }
+       
+   if ((flags & SPAMC_RANDOMIZE_HOSTS) != 0) {
 	/* we don't need strong randomness; this is just so we pick
 	 * a random host for loadbalancing.
 	 */
@@ -472,9 +499,14 @@
 #endif
     ret = transport_setup(&trans, flags);
     if (ret == EX_OK) {
+	
 	ret = message_read(STDIN_FILENO, flags, &m);
+	
 	if (ret == EX_OK) {
+	    
 	    ret = message_filter(&trans, username, flags, &m);
+	    free(username); username = NULL;
+	    
 	    if (ret == EX_OK) {
 		get_output_fd(&out_fd);
 
@@ -496,6 +528,7 @@
 	    }
 	}
     }
+    free(username);
 
 /* FAIL: */
     get_output_fd(&out_fd);