home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* gmail 1
- /* SUMMARY
- /* deliver unsent mail via gnuucp
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* gnu
- /* SYNOPSIS
- /* gmail [-d debuglevel]
- /* DESCRIPTION
- /* This program replaces the sending function of the pc-mail "cico"
- /* program, on systems that use GNUUCP for message transport.
- /*
- /* gmail searches the pc-mail message data base for unsent mail
- /* (with the "Out" status) and queues it for transmission via GNUUCP.
- /* When a message has been queued it is renamed to reflect
- /* the "Sent" status.
- /*
- /* This program is intended to be called via the MAILCMD environment
- /* variable, so that it is invoked upon exit from the mail user
- /* interface program.
- /*
- /* In order to avoid corruption of the message data base, control-c
- /* interrupts are disabled while this program executes.
- /* ENVIRONMENT
- /* MAILDIR, path to pc-mail message data base
- /* COMMANDS
- /* rmail, the gnuucp mailer
- /* FILES
- /* In the spool directory:
- /* d<seqno> unsent mail, message body
- /* x<seqno> unsent mail, destination and subject
- /* q<seqno> sent mail, message body
- /* r<seqno> sent mail, destination and subject
- /* SEE ALSO
- /* path(5) spool directory, file name formats
- /* DIAGNOSTICS
- /* Problems are reported on the standard error output, and cause the
- /* program to terminate with a nonzero exit status.
- /* BUGS
- /* It is left up to GNUUCP to determine what to do with undeliverable mail.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Wed Jan 3 22:16:28 MET 1990
- /* LAST MODIFICATION
- /* 90/01/22 13:01:40
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <signal.h>
- #include <time.h>
- #include <varargs.h>
-
- #include "defs.h"
- #include "ndir.h"
- #include "path.h"
-
- #ifndef RMAIL
- #define RMAIL "rmail"
- #endif
-
- /* Forward declarations */
-
- hidden char *get_dest();
- hidden int uuqueue();
- hidden void error();
- hidden void frename();
- hidden void parse_args();
- hidden void scanmail();
- hidden void usage();
-
- #define debug if (dflag) (void) printf
-
- hidden int dflag = 0; /* debugging option */
-
- public char *progname = "gmail"; /* for diagnostics */
-
- /* .. */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- (void) signal(SIGINT, SIG_IGN); /* disable ctrl-c */
- if (pathinit()) /* get path info */
- error("no mail directory or MAILDIR environment variable not set");
- parse_args(argc, argv); /* parse command args */
- scanmail(); /* search for unsent mail */
- exit(0);
- /* NOTREACHED */
- }
-
- /* parse_args - process command-line arguments */
-
- hidden void parse_args(argc, argv)
- int argc;
- char **argv;
- {
- while (--argc && *++argv && **argv == '-') {/* process options */
- switch (*++*argv) {
- case 'd': /* turn debugging on */
- dflag++;
- break;
- default: /* unknown option */
- usage("invalid option: -%c", **argv);
- break;
- }
- }
-
- /* check for extraneous arguments */
-
- if (argc > 0)
- usage("unexpected argument: %s", *argv);
- }
-
- /* scan for unsent mail */
-
- hidden void scanmail()
- {
- unsigned msgno; /* message sequence number */
- register DIR *dp;
- struct direct *de;
- char *dest;
-
- debug("directory: \"%s\"\n", maildir);
-
- /*
- * Scan the spool directory for unsent mail. After the message has been
- * piped through rmail, rename it to reflect the "Sent" status. Do not give
- * up if a file cannot be opened; just proceed with the next message.
- */
-
- if ((dp = opendir(maildir)) == 0)
- error("cannot read the mail directory: %s", maildir);
-
- while (de = readdir(dp)) {
- debug("file: \"%s\"\n", de->d_name);
- if (de->d_name[0] == OUT_META && (msgno = seqno(de->d_name))
- && (dest = get_dest(msgno)) && uuqueue(msgno, dest)) {
- frename(out_mesg(msgno), sent_mesg(msgno));
- frename(out_meta(msgno), sent_meta(msgno));
- }
- }
- closedir(dp);
- }
-
- /* uuqueue - queue one message */
-
- hidden int uuqueue(msgno, dest)
- unsigned msgno;
- char *dest;
- {
- char cmd[BUFSIZ];
- char *path;
- char *rcpt;
- static char sep[] = " \t\r\n";
-
- if (access(path = out_mesg(msgno), 04)) {
- debug("%s: cannot read message file: %s\n", path, sys_errlist[errno]);
- return (0);
- } else {
-
- /*
- * The GNUUCP rmail program has to invoked for each recipient. rmail
- * will have to deal with undeliverable mail anyway, so we ignore
- * that class of errors.
- */
-
- for (rcpt = strtok(dest, sep); rcpt; rcpt = strtok((char *) 0, sep)) {
- (void) sprintf(cmd, "%s %s <%s", RMAIL, rcpt, path);
- debug("command: %s\n", cmd);
- if (system(cmd) == 127)
- error("could not invoke the shell");
- }
- return (1);
- }
- }
-
- /* get_dest - extract recipients */
-
- hidden char *get_dest(msgno)
- unsigned msgno;
- {
- static char buf[MAXLINE];
- FILE *fp;
- char *ret;
- char *path;
-
- if ((fp = fopen(path = out_meta(msgno), "r")) == 0) {
- debug("%s: cannot open: %s\n", path, sys_errlist[errno]);
- return (0);
- } else {
- if ((ret = fgets(buf, sizeof(buf), fp)) == 0)
- debug("%s: no recipients found\n", path);
- (void) fclose(fp);
- return (ret);
- }
- }
-
- /* frename - forcibly change the name of a file */
-
- hidden void frename(from, to)
- char *from;
- char *to;
- {
- debug("rename: %s -> %s\n", from, to);
-
- if (chmod(to, 0600) == 0)
- (void) unlink(to);
- if (rename(from, to))
- error("cannot rename %s to %s: %s", from, to, sys_errlist[errno]);
- }
-
- /* error - complain */
-
- /* VARARGS */
-
- hidden void error(va_alist)
- va_dcl
- {
- va_list ap;
- char *fmt;
-
- (void) fprintf(stderr, "%s: ", progname);
- va_start(ap);
- fmt = va_arg(ap, char *);
- (void) vfprintf(stderr, fmt, ap);
- va_end(ap);
- (void) putc('\n', stderr);
- exit(2);
- }
-
- /* usage - explain what is wrong */
-
- /* VARARGS */
-
- hidden void usage(va_alist)
- va_dcl
- {
- va_list ap;
- char *fmt;
-
- (void) fprintf(stderr, "%s: ", progname);
- va_start(ap);
- fmt = va_arg(ap, char *);
- (void) vfprintf(stderr, fmt, ap);
- va_end(ap);
- (void) fprintf(stderr, "\nusage: gmail [-d]\n");
- exit(2);
- }
-