Exemplo n.º 1
0
/*
 * If given a '-p' flag, read encoded delta pieces from stdin or file
 * arguments, decode them and assemble any completed deltas.  If given
 * a '-b' flag, pass any completed deltas to 'ctm' for application to
 * the source tree.  The '-d' flag is mandatory, but either of '-p' or
 * '-b' can be omitted.  If given the '-l' flag, notes and errors will
 * be timestamped and written to the given file.
 *
 * Exit status is 0 for success or 1 for indigestible input.  That is,
 * 0 means the encode input pieces were decoded and stored, and 1 means
 * some input was discarded.  If a delta fails to apply, this won't be
 * reflected in the exit status.  In this case, the delta is left in
 * 'deltadir'.
 */
int
main(int argc, char **argv)
    {
    char *log_file = NULL;
    int status = 0;
    int fork_ctm = 0;

    mask = umask(0);
    umask(mask);

    err_prog_name(argv[0]);

    OPTIONS("[-Dfuv] [-p piecedir] [-d deltadir] [-b basedir] [-l log] [file ...]")
	FLAG('D', delete_after)
	FLAG('f', fork_ctm)
	FLAG('u', set_time)
	FLAG('v', apply_verbose)
	STRING('p', piece_dir)
	STRING('d', delta_dir)
	STRING('b', base_dir)
	STRING('l', log_file)
    ENDOPTS

    if (delta_dir == NULL)
	usage();

    if (piece_dir == NULL && (base_dir == NULL || argc > 1))
	usage();

    if (log_file != NULL)
	err_set_log(log_file);

    /*
     * Digest each file in turn, or just stdin if no files were given.
     */
    if (argc <= 1)
	{
	if (piece_dir != NULL)
	    status = read_piece(NULL);
	}
    else
	{
	while (*++argv != NULL)
	    status |= read_piece(*argv);
	}

    /*
     * Maybe it's time to look for and apply completed deltas with ctm.
     *
     * Shall we report back to sendmail immediately, and let a child do
     * the work?  Sendmail will be waiting for us to complete, delaying
     * other mail, and possibly some intermediate process (like MH slocal)
     * will terminate us if we take too long!
     *
     * If fork() fails, it's unlikely we'll be able to run ctm, so give up.
     * Also, the child exit status is unimportant.
     */
    if (base_dir != NULL)
	if (!fork_ctm || fork() == 0)
	    apply_complete();

    return status;
    }
Exemplo n.º 2
0
int
main(int argc, char **argv)
{
    char *log_file = NULL;
    char *queue_dir = NULL;
    char *list[2];
    int num_to_send = DEFAULT_NUM, chunk;
    int fd;
    FTS *fts;
    FTSENT *ftsent;
    int piece, npieces;
    char filename[PATH_MAX];

    err_prog_name(argv[0]);

    OPTIONS("[-l log] [-n num] queuedir")
	NUMBER('n', num_to_send)
	STRING('l', log_file)
    ENDOPTS

    if (argc != 2)
	usage();

    if (log_file)
	err_set_log(log_file);

    queue_dir = argv[1];
    list[0] = queue_dir;
    list[1] = NULL;

    fts = fts_open(list, FTS_PHYSICAL|FTS_COMFOLLOW, fts_sort);
    if (fts == NULL)
    {
	err("fts failed on `%s'", queue_dir);
	exit(1);
    }

    ftsent = fts_read(fts);
    if (ftsent == NULL || ftsent->fts_info != FTS_D)
    {
	err("not a directory: %s", queue_dir);
	exit(1);
    }

    ftsent = fts_children(fts, 0);
    if (ftsent == NULL && errno)
    {
	err("*ftschildren failed");
	exit(1);
    }

    for (chunk = 1; ftsent != NULL; ftsent = ftsent->fts_link)
    {
	/*
	 * Skip non-files and ctm_smail tmp files (ones starting with `.')
	 */
	if (ftsent->fts_info != FTS_F || ftsent->fts_name[0] == '.')
	    continue;

	sprintf(filename, "%s/%s", queue_dir, ftsent->fts_name);
	fd = open(filename, O_RDONLY);
	if (fd < 0)
	{
	    err("*open: %s", filename);
	    exit(1);
	}

	if (run_sendmail(fd))
	    exit(1);

	close(fd);
	
	if (unlink(filename) < 0)
	{
	    err("*unlink: %s", filename);
	    exit(1);
	}
	
	/*
	 * Deduce the delta, piece number, and number of pieces from
	 * the name of the file in the queue.  Ideally, we should be
	 * able to get the mail alias name too.
	 *
	 * NOTE: This depends intimately on the queue name used in ctm_smail.
	 */
	npieces = atoi(&ftsent->fts_name[ftsent->fts_namelen-3]);
	piece = atoi(&ftsent->fts_name[ftsent->fts_namelen-7]);
	err("%.*s %d/%d sent", ftsent->fts_namelen-8, ftsent->fts_name,
		piece, npieces);

	if (chunk++ == num_to_send)
	    break;
    }

    fts_close(fts);

    return(0);
}