home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / gmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  6.3 KB  |  259 lines

  1. /*++
  2. /* NAME
  3. /*      gmail 1
  4. /* SUMMARY
  5. /*      deliver unsent mail via gnuucp
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      gnu
  10. /* SYNOPSIS
  11. /*      gmail [-d debuglevel]
  12. /* DESCRIPTION
  13. /*    This program replaces the sending function of the pc-mail "cico"
  14. /*    program, on systems that use GNUUCP for message transport.
  15. /*
  16. /*      gmail searches the pc-mail message data base for unsent mail
  17. /*    (with the "Out" status) and queues it for transmission via GNUUCP.
  18. /*    When a message has been queued it is renamed to reflect
  19. /*    the "Sent" status.
  20. /*
  21. /*    This program is intended to be called via the MAILCMD environment
  22. /*    variable, so that it is invoked upon exit from the mail user
  23. /*    interface program.
  24. /*
  25. /*      In order to avoid corruption of the message data base, control-c
  26. /*    interrupts are disabled while this program executes.
  27. /* ENVIRONMENT
  28. /*    MAILDIR, path to pc-mail message data base
  29. /* COMMANDS
  30. /*    rmail, the gnuucp mailer
  31. /* FILES
  32. /*      In the spool directory:
  33. /*    d<seqno>    unsent mail, message body
  34. /*    x<seqno>    unsent mail, destination and subject
  35. /*    q<seqno>    sent mail, message body
  36. /*    r<seqno>    sent mail, destination and subject
  37. /* SEE ALSO
  38. /*      path(5)         spool directory, file name formats
  39. /* DIAGNOSTICS
  40. /*      Problems are reported on the standard error output, and cause the
  41. /*    program to terminate with a nonzero exit status.
  42. /* BUGS
  43. /*    It is left up to GNUUCP to determine what to do with undeliverable mail.
  44. /* AUTHOR(S)
  45. /*      W.Z. Venema
  46. /*      Eindhoven University of Technology
  47. /*      Department of Mathematics and Computer Science
  48. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  49. /* CREATION DATE
  50. /*    Wed Jan  3 22:16:28 MET 1990
  51. /* LAST MODIFICATION
  52. /*    90/01/22 13:01:40
  53. /* VERSION/RELEASE
  54. /*    2.1
  55. /*--*/
  56.  
  57. #include <stdio.h>
  58. #include <signal.h>
  59. #include <time.h>
  60. #include <varargs.h>
  61.  
  62. #include "defs.h"
  63. #include "ndir.h"
  64. #include "path.h"
  65.  
  66. #ifndef    RMAIL
  67. #define    RMAIL    "rmail"
  68. #endif
  69.  
  70. /* Forward declarations */
  71.  
  72. hidden char *get_dest();
  73. hidden int uuqueue();
  74. hidden void error();
  75. hidden void frename();
  76. hidden void parse_args();
  77. hidden void scanmail();
  78. hidden void usage();
  79.  
  80. #define debug    if (dflag) (void) printf
  81.  
  82. hidden int dflag = 0;            /* debugging option */
  83.  
  84. public char *progname = "gmail";    /* for diagnostics */
  85.  
  86. /* .. */
  87.  
  88. main(argc, argv)
  89. int     argc;
  90. char  **argv;
  91. {
  92.     (void) signal(SIGINT, SIG_IGN);        /* disable ctrl-c */
  93.     if (pathinit())                /* get path info */
  94.     error("no mail directory or MAILDIR environment variable not set");
  95.     parse_args(argc, argv);            /* parse command args */
  96.     scanmail();                    /* search for unsent mail */
  97.     exit(0);
  98.     /* NOTREACHED */
  99. }
  100.  
  101. /* parse_args - process command-line arguments */
  102.  
  103. hidden void parse_args(argc, argv)
  104. int     argc;
  105. char  **argv;
  106. {
  107.     while (--argc && *++argv && **argv == '-') {/* process options */
  108.     switch (*++*argv) {
  109.     case 'd':                /* turn debugging on */
  110.         dflag++;
  111.         break;
  112.     default:                /* unknown option */
  113.         usage("invalid option: -%c", **argv);
  114.         break;
  115.     }
  116.     }
  117.  
  118.     /* check for extraneous arguments */
  119.  
  120.     if (argc > 0)
  121.     usage("unexpected argument: %s", *argv);
  122. }
  123.  
  124. /* scan for unsent mail */
  125.  
  126. hidden void scanmail()
  127. {
  128.     unsigned msgno;            /* message sequence number */
  129.     register DIR *dp;
  130.     struct direct *de;
  131.     char   *dest;
  132.  
  133.     debug("directory: \"%s\"\n", maildir);
  134.  
  135.     /*
  136.      * Scan the spool directory for unsent mail. After the message has been
  137.      * piped through rmail, rename it to reflect the "Sent" status. Do not give
  138.      * up if a file cannot be opened; just proceed with the next message.
  139.      */
  140.  
  141.     if ((dp = opendir(maildir)) == 0)
  142.     error("cannot read the mail directory: %s", maildir);
  143.  
  144.     while (de = readdir(dp)) {
  145.     debug("file: \"%s\"\n", de->d_name);
  146.     if (de->d_name[0] == OUT_META && (msgno = seqno(de->d_name))
  147.     && (dest = get_dest(msgno)) && uuqueue(msgno, dest)) {
  148.         frename(out_mesg(msgno), sent_mesg(msgno));
  149.         frename(out_meta(msgno), sent_meta(msgno));
  150.     }
  151.     }
  152.     closedir(dp);
  153. }
  154.  
  155. /* uuqueue - queue one message */
  156.  
  157. hidden int uuqueue(msgno, dest)
  158. unsigned msgno;
  159. char   *dest;
  160. {
  161.     char    cmd[BUFSIZ];
  162.     char   *path;
  163.     char   *rcpt;
  164.     static char sep[] = " \t\r\n";
  165.  
  166.     if (access(path = out_mesg(msgno), 04)) {
  167.     debug("%s: cannot read message file: %s\n", path, sys_errlist[errno]);
  168.     return (0);
  169.     } else {
  170.  
  171.     /*
  172.      * The GNUUCP rmail program has to invoked for each recipient. rmail
  173.      * will have to deal with undeliverable mail anyway, so we ignore
  174.      * that class of errors.
  175.      */
  176.  
  177.     for (rcpt = strtok(dest, sep); rcpt; rcpt = strtok((char *) 0, sep)) {
  178.         (void) sprintf(cmd, "%s %s <%s", RMAIL, rcpt, path);
  179.         debug("command: %s\n", cmd);
  180.         if (system(cmd) == 127)
  181.         error("could not invoke the shell");
  182.     }
  183.     return (1);
  184.     }
  185. }
  186.  
  187. /* get_dest - extract recipients */
  188.  
  189. hidden char *get_dest(msgno)
  190. unsigned msgno;
  191. {
  192.     static char buf[MAXLINE];
  193.     FILE   *fp;
  194.     char   *ret;
  195.     char   *path;
  196.  
  197.     if ((fp = fopen(path = out_meta(msgno), "r")) == 0) {
  198.     debug("%s: cannot open: %s\n", path, sys_errlist[errno]);
  199.     return (0);
  200.     } else {
  201.     if ((ret = fgets(buf, sizeof(buf), fp)) == 0)
  202.         debug("%s: no recipients found\n", path);
  203.     (void) fclose(fp);
  204.     return (ret);
  205.     }
  206. }
  207.  
  208. /* frename - forcibly change the name of a file */
  209.  
  210. hidden void frename(from, to)
  211. char   *from;
  212. char   *to;
  213. {
  214.     debug("rename: %s -> %s\n", from, to);
  215.  
  216.     if (chmod(to, 0600) == 0)
  217.     (void) unlink(to);
  218.     if (rename(from, to))
  219.     error("cannot rename %s to %s: %s", from, to, sys_errlist[errno]);
  220. }
  221.  
  222. /* error - complain */
  223.  
  224. /* VARARGS */
  225.  
  226. hidden void error(va_alist) 
  227. va_dcl
  228. {
  229.     va_list ap;
  230.     char   *fmt;
  231.  
  232.     (void) fprintf(stderr, "%s: ", progname);
  233.     va_start(ap);
  234.     fmt = va_arg(ap, char *);
  235.     (void) vfprintf(stderr, fmt, ap);
  236.     va_end(ap);
  237.     (void) putc('\n', stderr);
  238.     exit(2);
  239. }
  240.  
  241. /* usage - explain what is wrong */
  242.  
  243. /* VARARGS */
  244.  
  245. hidden void usage(va_alist) 
  246. va_dcl
  247. {
  248.     va_list ap;
  249.     char   *fmt;
  250.  
  251.     (void) fprintf(stderr, "%s: ", progname);
  252.     va_start(ap);
  253.     fmt = va_arg(ap, char *);
  254.     (void) vfprintf(stderr, fmt, ap);
  255.     va_end(ap);
  256.     (void) fprintf(stderr, "\nusage: gmail [-d]\n");
  257.     exit(2);
  258. }
  259.