home *** CD-ROM | disk | FTP | other *** search
/ ftp.uv.es / 2014.11.ftp.uv.es.tar / ftp.uv.es / pub / unix / aix-rs6000 / elm2.3.11.AIX3.1.5.Z / elm2.3.11.AIX3.1.5 / utils / fastmail.c < prev    next >
C/C++ Source or Header  |  1990-12-06  |  9KB  |  328 lines

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