/* * 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; }
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); }