Mail-SpamAssassin

 view release on metacpan or  search on metacpan

spamc/spamc.c  view on Meta::CPAN

	 * screw up an invoker waiting on the death of the parent. So instead,
	 * we fork a child to feed the data and have the parent exec the new
	 * program.
	 */
	close(pipe_fds[0]);
	*fd = pipe_fds[1];
	return;
    }
    
    /* This is the parent process (see above) */
    close(pipe_fds[1]);
    if (dup2(pipe_fds[0], STDIN_FILENO)) {
	libspamc_log(flags, LOG_ERR, "redirection of stdin failed: %m");
	exit(EX_OSERR);
    }
    /* No point in leaving extra fds lying around. */
    close(pipe_fds[0]);
    
    /* Now execute the command specified. */
    execv(exec_argv[0], exec_argv);
    
    /* 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 (welcomelists & the like).
 *
 * Allocates memory for the username, returns EX_OK if successful.
 */
int
get_current_user(char **username)
{
#ifndef _WIN32
    struct passwd *curr_user;
#endif

    if (*username != NULL) {
        *username = strdup(*username);
	if (username == NULL)
	    goto fail;
	goto pass;
    }

#ifndef _WIN32
    
    /* 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;
    }

#endif

pass:
    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;
}


int
main(int argc, char *argv[])
{
    int max_size;
    char *username;
    struct transport trans;
    struct message m;
    int out_fd = -1;
    int result = EX_SOFTWARE;
    int ret = EX_SOFTWARE;
    int ret_conf = EX_SOFTWARE;
    int extratype = 0;
    int islearned = 0;
    int isreported = 0;

    /* these are to hold CLI and config options combined, to be passed
     * to read_args() */
    char *combo_argv[COMBO_ARGV_SIZE];
    int combo_argc;

    int i;
    char *config_file = NULL;

    transport_init(&trans);

#ifdef LIBSPAMC_UNIT_TESTS
    /* unit test support; divert execution.  will not return */
    do_libspamc_unit_tests();
#endif

#ifndef _WIN32



( run in 2.128 seconds using v1.01-cache-2.11-cpan-98e64b0badf )