Пример #1
0
    int
env_is_old( struct envelope *env, int dfile_fd )
{
    struct timeval              tv_now;
    struct stat			sb;

    if ( env->e_age == ENV_AGE_UNKNOWN ) {
	if ( fstat( dfile_fd, &sb ) != 0 ) {
	    syslog( LOG_ERR, "Syserror: env_is_old fstat %s/D%s: %m",
		    env->e_dir, env->e_id );
	    return( 0 );
	}

	if ( simta_gettimeofday( &tv_now ) != 0 ) {
	    return( 0 );
	}

	if ( simta_bounce_seconds > 0 ) {
	    if (( tv_now.tv_sec - sb.st_mtime ) > ( simta_bounce_seconds )) {
		env->e_age = ENV_AGE_OLD;
	    } else {
		env->e_age = ENV_AGE_NOT_OLD;
	    }

	}
    }

    if ( env->e_age == ENV_AGE_OLD ) {
	return( 1 );
    }

    return( 0 );
}
Пример #2
0
    int
env_fsync( const char *path )
{
    int		fd;
    int		ret = 0;

    if (( fd = open( path, O_RDONLY )) < 0 ) {
	syslog( LOG_ERR, "Syserror: env_fsync open %s: %m", path );
	return( 1 );
    }

    /* fdatasync() "does not flush modified metadata unless that metadata is
     * needed in order to allow a subsequent data retrieval to be correctly
     * handled." We don't require that all metadata be synced to disk, so if
     * fdatasync() is available it's preferred.
     */
#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
    if ( fdatasync( fd ) < 0 ) {
#else
    if ( fsync( fd ) < 0 ) {
#endif
	syslog( LOG_ERR, "Syserror: env_fsync fsync %s: %m", path );
	ret = 1;
    }
    close( fd );

    return( ret );
}

    /* calling this function updates the attempt time */

    int
env_touch( struct envelope *env )
{
    char			fname[ MAXPATHLEN ];
    struct timeval		tv_now;

    sprintf( fname, "%s/E%s", env->e_dir, env->e_id );

    if ( utime( fname, NULL ) != 0 ) {
	syslog( LOG_ERR, "Syserror: env_touch utime %s: %m", fname );
	return( -1 );
    }

    if ( simta_gettimeofday( &tv_now ) != 0 ) {
	return( -1 );
    }

    env->e_etime.tv_sec = tv_now.tv_sec;

    return( 0 );
}
Пример #3
0
    struct envelope *
env_create( const char *dir, const char *id, const char *e_mail,
	const struct envelope *parent )
{
    struct envelope	*env;
    struct timeval		tv_now;
    int				pid;
    /* way bigger than we should ever need */
    char			buf[ 1024 ];

    env = calloc( 1, sizeof( struct envelope ));

    if (( id == NULL ) || ( *id == '\0' )) {
	if ( simta_gettimeofday( &tv_now ) != 0 ) {
	    env_free( env );
	    return( NULL );
	}

	if (( pid = getpid()) < 0 ) {
	    syslog( LOG_ERR, "Syserror: env_set_id getpid: %m" );
	    env_free( env );
	    return( NULL );
	}

	snprintf( buf, 1023, "%lX.%lX.%d", (unsigned long)tv_now.tv_sec,
		(unsigned long)tv_now.tv_usec, pid );

	id = buf;
    }

    env->e_id = strdup( id );

    if ( e_mail != NULL ) {
	if ( env_sender( env, e_mail ) != 0 ) {
	    env_free( env );
	    return( NULL );
	}
    }

    if ( parent ) {
	env->e_dinode = parent->e_dinode;
	env->e_n_exp_level = parent->e_n_exp_level + 1;
	env_jail_set( env, parent->e_jail );
    } else if ( simta_rqueue_policy == RQUEUE_POLICY_JAIL ) {
	env_jail_set( env, ENV_JAIL_PRISONER );
    }

    env->e_dir = dir;

    return( env );
}
Пример #4
0
    int
env_efile( struct envelope *e )
{
    char		tf[ MAXPATHLEN + 1 ];
    char		ef[ MAXPATHLEN + 1 ];
    char		df[ MAXPATHLEN + 1 ];
    struct timeval	tv_now;
    struct dll_entry	*e_dll;

    sprintf( tf, "%s/t%s", e->e_dir, e->e_id );
    sprintf( ef, "%s/E%s", e->e_dir, e->e_id );
    sprintf( df, "%s/D%s", e->e_dir, e->e_id );

    if ( rename( tf, ef ) < 0 ) {
	syslog( LOG_ERR, "Syserror: env_efile rename %s %s: %m", tf, ef );
	unlink( tf );
	return( -1 );
    }

    if ( e->e_dir == simta_dir_fast ) {
	simta_fast_files++;
	simta_debuglog( 2, "Envelope env <%s> fast_files increment %d",
		e->e_id, simta_fast_files );
    }

    simta_debuglog( 3, "env_efile %s %s %s", e->e_dir, e->e_id,
	    e->e_hostname ? e->e_hostname : "" );

    e->e_flags = ( e->e_flags & ( ~ENV_FLAG_TFILE ));
    e->e_flags |= ENV_FLAG_EFILE;

    if ( simta_gettimeofday( &tv_now ) != 0 ) {
	return( -1 );
    }

    e->e_etime.tv_sec = tv_now.tv_sec;

    if ( simta_sync ) {
	env_fsync( ef );
	env_fsync( df );
	/* fsync() does not ensure that the directory entries for the files
	 * have been synced, so we must explicitly sync the directory.
	 */
	env_fsync( e->e_dir );
    }

    if ( simta_mid_list_enable != 0 ) {
	if (( e_dll = dll_lookup_or_create( &simta_env_list,
		e->e_id, 0 )) == NULL ) {
	    return( 1 );
	}

	if ( e_dll->dll_data == NULL ) {
	    e_dll->dll_data = e;
	    e->e_env_list_entry = e_dll;
	}
    }

    if ( simta_sender_list_enable != 0 ) {
	if ( sender_list_add( e ) != 0 ) {
	    return( 1 );
	}
    }

    return( 0 );
}
Пример #5
0
    int
main( int argc, char *argv[] )
{
    SNET		*in;
    SNET		*out;
    char		*line;
    int			x;
    struct timeval	tv;
    char		path[ MAXPATHLEN ];
    int			c;

    if ( simta_gettimeofday( &tv ) != 0 ) {
	perror( "gettimeofday" );
	return( 1 );
    }

    /* XXX hard path */
    sprintf( path, "%s/%ld.%ld", "/var/simta/log", tv.tv_sec, tv.tv_usec );

    if (( in = snet_attach( 0, 1024 * 1024 )) == NULL ) {
	perror( "snet_attach" );
	exit( 1 );
    }

    if (( out = snet_open( path, O_CREAT | O_WRONLY,
	    S_IRUSR | S_IRGRP | S_IROTH, 1024 * 1024 )) == NULL ) {
	perror( "snet_open" );
	exit( 1 );
    }

    snet_writef( out, "%s", argv[ 0 ] );

    for ( x = 1; x < argc; x++ ) {
	snet_writef( out, " %s", argv[ x ] );
    }
    snet_writef( out, "\n\n" );

    opterr = 0;

    while (( c = getopt( argc, argv, "b:" )) != -1 ) {
	switch ( c ) {
	case 'b':
	    if ( strlen( optarg ) == 1 ) {
		switch ( *optarg ) {
		case 'a':
		    /* -ba ARPANET mode */
		case 'd':
		    /* -bd Daemon mode, background */
		case 's':
		    /* 501 Permission denied */
		    printf( "501 Mode not supported\r\n" );
		    exit( 1 );
		}
	    }
	    break;

	default:
	    break;
	}
    }

    while (( line = snet_getline( in, NULL )) != NULL ) {
	snet_writef( out, "%s\n", line );
    }

    if ( snet_close( in ) != 0 ) {
	perror( "snet_close" );
	exit( 1 );
    }

    if ( snet_close( out ) != 0 ) {
	perror( "snet_close" );
	exit( 1 );
    }

    return( 0 );
}