home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / elm.lzh / ELM / UTILS / FASTMAIL.C < prev    next >
C/C++ Source or Header  |  1993-03-18  |  9KB  |  315 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: fastmail.c,v 4.1.1.1 90/06/26 20:30:22 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.1 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    fastmail.c,v $
  17.  * Revision 4.1.1.1  90/06/26  20:30:22  syd
  18.  * Fix boundary check on argument count
  19.  * From: Syd
  20.  * 
  21.  * Revision 4.1  90/04/28  22:44:39  syd
  22.  * checkin of Elm 2.3 as of Release PL0
  23.  * 
  24.  *
  25.  ******************************************************************************/
  26.  
  27. /** This program is specifically written for group mailing lists and
  28.     such batch type mail processing.  It does NOT use aliases at all,
  29.     it does NOT read the /etc/password file to find the From: name
  30.     of the user and does NOT expand any addresses.  It is meant 
  31.     purely as a front-end for either /bin/mail or /usr/lib/sendmail
  32.     (according to what is available on the current system).
  33.  
  34.          **** This program should be used with CAUTION *****
  35.  
  36. **/
  37.  
  38. /** The calling sequence for this program is:
  39.  
  40.     fastmail {args}  filename full-email-address 
  41.  
  42.    where args could be any (or all) of;
  43.  
  44.        -b bcc-list        (Blind carbon copies to)
  45.        -c cc-list        (carbon copies to)
  46.        -d            (debug on)
  47.        -f from         (from name)
  48.        -F from-addr        (the actual address to be put in the From: line)
  49.        -r reply-to-address     (Reply-To:)
  50.        -s subject         (subject of message)
  51. **/
  52.  
  53. #include <stdio.h>
  54. #include "defs.h"
  55. #include "patchlevel.h"
  56.  
  57. #ifdef I_TIME
  58. #  include <time.h>
  59. #endif
  60. #ifdef I_SYSTIME
  61. #  include <sys/time.h>
  62. #endif
  63. #ifdef BSD
  64. #  include <sys/types.h>
  65. /*
  66. #  include <sys/timeb.h>
  67. */
  68. #endif
  69.  
  70. static char ident[] = { WHAT_STRING };
  71.  
  72. #define  binrmail    "/bin/rmail"
  73. #define  temphome    "/tmp/fastmail."
  74.  
  75.  
  76. char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
  77.           "Fri", "Sat", "" };
  78.  
  79. char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  80.           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
  81.  
  82. char *get_arpa_date();
  83.  
  84. #if defined(BSD) && !defined(_POSIX_SOURCE)
  85.   char *timezone();
  86. #else
  87.   extern char *tzname[];
  88. #endif
  89.  
  90. main(argc, argv)
  91. int argc;
  92. char *argv[];
  93. {
  94.  
  95.     extern char *optarg;
  96.     extern int optind;
  97.     FILE *tempfile;
  98.     char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN];
  99.     char filename[SLEN], tempfilename[SLEN], command_buffer[256];
  100.     char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN];
  101.     char from_addr[SLEN];
  102.     int  c, sendmail_available, debug = 0;
  103.  
  104.     from_string[0] = '\0';
  105.     subject[0] = '\0';
  106.     replyto[0] = '\0';
  107.     cc_list[0] = '\0';
  108.     bcc_list[0] = '\0';
  109.     to_list[0] = '\0';
  110.     from_addr[0] = '\0';
  111.  
  112.     while ((c = getopt(argc, argv, "b:c:df:F:r:s:")) != EOF) {
  113.       switch (c) {
  114.         case 'b' : strcpy(bcc_list, optarg);        break;
  115.         case 'c' : strcpy(cc_list, optarg);        break;
  116.         case 'd' : debug++;                    break;    
  117.         case 'f' : strcpy(from_string, optarg);    break;
  118.         case 'F' : strcpy(from_addr, optarg);        break;
  119.         case 'r' : strcpy(replyto, optarg);        break;
  120.         case 's' : strcpy(subject, optarg);        break;
  121.         case '?' :
  122.           fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
  123.           fprintf(stderr, "   where {args} can be;\n");
  124.           fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n");
  125.           fprintf(stderr,"\t-f from-name\n\t-F from-addr\n");
  126.           fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
  127.           exit(1);
  128.        }
  129.     }    
  130.  
  131.     if (optind >= argc) {
  132.       fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
  133.       fprintf(stderr, "   where {args} can be;\n");
  134.       fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
  135.       fprintf(stderr,"\t-F from-addr\n");
  136.       fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
  137.       exit(1);
  138.     }
  139.  
  140.     strcpy(filename, argv[optind++]);
  141.  
  142.     if (optind >= argc) {
  143.       fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
  144.       fprintf(stderr, "   where {args} can be;\n");
  145.       fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
  146.       fprintf(stderr,"\t-F from-addr\n");
  147.       fprintf(stderr,"\t-r reply-to\n\t-s subject\n\n");
  148.       exit(1);
  149.     }
  150.  
  151. #ifdef HOSTCOMPILED
  152.     strncpy(hostname, HOSTNAME, sizeof(hostname));
  153. #else
  154.     gethostname(hostname, sizeof(hostname));
  155. #endif
  156.  
  157.     strcpy(username, getlogin());
  158.  
  159.     if (strlen(username) == 0)
  160.       cuserid(username);
  161.  
  162.     if (access(filename, READ_ACCESS) == -1) {
  163.       fprintf(stderr, "Error: can't find file %s!\n", filename);
  164.       exit(1);
  165.     }
  166.  
  167.     sprintf(tempfilename, "%s%d", temphome, getpid());
  168.  
  169.     if ((tempfile = fopen(tempfilename, "w")) == NULL) {
  170.       fprintf(stderr, "Couldn't open temp file %s\n", tempfilename);
  171.       exit(1);
  172.     }
  173.  
  174.     /** Subject must appear even if "null" and must be first
  175.         at top of headers for mail because the
  176.         pure System V.3 mailer, in its infinite wisdom, now
  177.         assumes that anything the user sends is part of the 
  178.         message body unless either:
  179.         1. the "-s" flag is used (although it doesn't seem
  180.            to be supported on all implementations??)
  181.         2. the first line is "Subject:".  If so, then it'll
  182.            read until a blank line and assume all are meant
  183.            to be headers.
  184.         So the gory solution here is to move the Subject: line
  185.         up to the top.  I assume it won't break anyone elses program
  186.         or anything anyway (besides, RFC-822 specifies that the *order*
  187.         of headers is irrelevant).  Gahhhhh....
  188.     **/
  189.     fprintf(tempfile, "Subject: %s\n", subject);
  190.  
  191.     if (strlen(from_string) > 0)
  192.       if (strlen(from_addr) > 0)
  193.           fprintf(tempfile, "From: %s (%s)\n", from_addr, from_string);
  194.       else
  195.           fprintf(tempfile, "From: %s!%s (%s)\n", hostname, username, 
  196.               from_string);
  197.     else
  198.       if (strlen(from_addr) > 0)
  199.         fprintf(tempfile, "From: %s\n", from_addr);
  200.       else
  201.         fprintf(tempfile, "From: %s!%s\n", hostname, username);
  202.  
  203.     fprintf(tempfile, "Date: %s\n", get_arpa_date());
  204.  
  205.     if (strlen(replyto) > 0)
  206.       fprintf(tempfile, "Reply-To: %s\n", replyto);
  207.  
  208.     while (optind < argc) 
  209.           sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? " ":""), 
  210.           argv[optind++]);
  211.     
  212.     fprintf(tempfile, "To: %s\n", to_list);
  213.  
  214.     if (strlen(cc_list) > 0)
  215.       fprintf(tempfile, "Cc: %s\n", cc_list);
  216.  
  217.     fprintf(tempfile, "X-Mailer: fastmail [version %s PL%d]\n",
  218.       VERSION, PATCHLEVEL);
  219.     fprintf(tempfile, "\n");
  220.  
  221.     fclose(tempfile);
  222.  
  223.     /** now we'll cat both files to /bin/rmail or sendmail... **/
  224.  
  225.     sendmail_available = (access(sendmail, EXECUTE_ACCESS) != -1);
  226.  
  227.     if (debug)
  228.         printf("Mailing to %s%s%s%s%s [via %s]\n", to_list,
  229.             (strlen(cc_list) > 0 ? " ":""), cc_list,
  230.             (strlen(bcc_list) > 0 ? " ":""), bcc_list,
  231.             sendmail_available? "sendmail" : "rmail");
  232.  
  233.     sprintf(command_buffer, "cat %s %s | %s %s %s %s", 
  234.         tempfilename, filename, 
  235.             sendmail_available? sendmail : mailer,
  236.         to_list, cc_list, bcc_list);
  237.  
  238.     if (debug)
  239.       printf("%s\n", command_buffer);
  240.  
  241.     c = system(command_buffer);
  242.  
  243.     unlink(tempfilename);
  244.  
  245.     exit(c != 0);
  246. }
  247.  
  248.  
  249. char *get_arpa_date()
  250. {
  251.     /** returns an ARPA standard date.  The format for the date
  252.         according to DARPA document RFC-822 is exemplified by;
  253.  
  254.                      Mon, 12 Aug 85 6:29:08 MST
  255.  
  256.     **/
  257.  
  258.     static char buffer[SLEN];    /* static character buffer       */
  259.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  260.     long       junk;        /* time in seconds....         */
  261. #ifndef    _POSIX_SOURCE
  262.     struct tm *localtime();
  263. #endif
  264. #ifdef BSD
  265. #  ifndef TZ_MINUTESWEST
  266.     struct timeb loc_time;    /* of course this is different! */
  267. #    ifndef _POSIX_SOURCE
  268.     long time();
  269. #    endif
  270. #  else
  271.     struct  timeval  time_val;        
  272.     struct  timezone time_zone;
  273. #  endif
  274. #else
  275.     long time();
  276. #endif
  277.  
  278. #ifdef BSD
  279. #  ifndef TZ_MINUTESWEST
  280.     junk = (long) time((long *) 0);
  281.     ftime(&loc_time);
  282. #  else
  283.     gettimeofday(&time_val, &time_zone);
  284.     junk = time_val.tv_sec;
  285. #  endif
  286. #else
  287.     junk = time(0);    /* this must be here for it to work! */
  288. #endif
  289.     the_time = localtime(&junk);
  290.  
  291.     sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
  292.       arpa_dayname[the_time->tm_wday],
  293.       the_time->tm_mday % 32,
  294.       arpa_monname[the_time->tm_mon],
  295.       the_time->tm_year % 100,
  296.       the_time->tm_hour % 24,
  297.       the_time->tm_min  % 61,
  298.       the_time->tm_sec  % 61,
  299. #if defined(BSD) && !defined(_POSIX_SOURCE)
  300. #  ifndef TZ_MINUTESWEST
  301.       timezone(loc_time.time_zone, the_time->tz_isdst));
  302. #  else
  303. #   ifdef GOULD_NP1
  304.       the_time->tm_zone);
  305. #   else
  306.       timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime));
  307. #   endif
  308. #  endif
  309. #else
  310.       tzname[the_time->tm_isdst]);
  311. #endif
  312.     
  313.     return( (char *) buffer);
  314. }
  315.