home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / utils / fastmail.c < prev    next >
C/C++ Source or Header  |  1994-08-16  |  10KB  |  351 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. char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
  79.           "Fri", "Sat", "" };
  80.  
  81. char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  82.           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
  83.  
  84. char *get_arpa_date();
  85.  
  86. #if defined(BSD) && !defined(_POSIX_SOURCE)
  87.   char *timezone();
  88. #else
  89. #ifndef OS2
  90.   extern char *tzname[];
  91. #endif
  92. #endif
  93.  
  94. main(argc, argv)
  95. int argc;
  96. char *argv[];
  97. {
  98.  
  99.     extern char *optarg;
  100.     extern int optind;
  101.     FILE *tempfile, *mailpipe;
  102.     char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN];
  103.     char filename[SLEN], tempfilename[SLEN], command_buffer[256];
  104.     char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN];
  105.     char from_addr[SLEN], buffer[SLEN], hostfromname[SLEN];
  106.     char *tmplogname;
  107.     int  c, sendmail_available, debug = 0;
  108.  
  109.         initpaths();
  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.           usage();
  130.        }
  131.     }
  132.  
  133.     if (optind >= argc)
  134.       usage();
  135.  
  136.     strcpy(filename, argv[optind++]);
  137.  
  138.     if (optind >= argc)
  139.           usage();
  140.  
  141. #ifdef HOSTCOMPILED
  142.     strncpy(hostname, HOSTNAME, sizeof(hostname));
  143. #else
  144.     gethostname(hostname, sizeof(hostname));
  145. #endif
  146.  
  147. #ifdef OS2
  148.     getfromdomain(hostfromname, sizeof(hostfromname));
  149. #else
  150.     strcpy(hostfromname, hostname);
  151. #endif
  152.  
  153.     tmplogname = getenv("LOGNAME");
  154.     if (tmplogname != NULL)
  155.       strcpy(username, tmplogname);
  156.     else
  157.       username[0] = '\0';
  158.  
  159. #ifndef OS2
  160.     if (strlen(username) == 0)
  161.       cuserid(username);
  162. #endif
  163.  
  164.     if (access(filename, READ_ACCESS) == -1) {
  165.       fprintf(stderr, "Error: can't find file %s!\n", filename);
  166.       exit(1);
  167.     }
  168.  
  169.     sprintf(tempfilename, "%s%d.fm", tempdir, getpid());
  170.  
  171.     if ((tempfile = fopen(tempfilename, "w")) == NULL) {
  172.       fprintf(stderr, "Couldn't open temp file %s\n", tempfilename);
  173.       exit(1);
  174.     }
  175.  
  176.     /** Subject must appear even if "null" and must be first
  177.         at top of headers for mail because the
  178.         pure System V.3 mailer, in its infinite wisdom, now
  179.         assumes that anything the user sends is part of the
  180.         message body unless either:
  181.         1. the "-s" flag is used (although it doesn't seem
  182.            to be supported on all implementations??)
  183.         2. the first line is "Subject:".  If so, then it'll
  184.            read until a blank line and assume all are meant
  185.            to be headers.
  186.         So the gory solution here is to move the Subject: line
  187.         up to the top.  I assume it won't break anyone elses program
  188.         or anything anyway (besides, RFC-822 specifies that the *order*
  189.         of headers is irrelevant).  Gahhhhh....
  190.     **/
  191.     fprintf(tempfile, "Subject: %s\n", subject);
  192.  
  193.     if (strlen(from_addr) == 0)
  194.       sprintf(from_addr, "%s@%s", username, hostfromname);
  195.  
  196.     if (strlen(from_string) > 0)
  197.       fprintf(tempfile, "From: %s (%s)\n", from_addr, from_string);
  198.     else
  199.       fprintf(tempfile, "From: %s\n", from_addr);
  200.  
  201.     fprintf(tempfile, "Date: %s\n", get_arpa_date());
  202.  
  203.     if (strlen(replyto) > 0)
  204.       fprintf(tempfile, "Reply-To: %s\n", replyto);
  205.  
  206.     while (optind < argc)
  207.           sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? " ":""),
  208.           argv[optind++]);
  209.  
  210.     fprintf(tempfile, "To: %s\n", to_list);
  211.  
  212.     if (strlen(cc_list) > 0)
  213.       fprintf(tempfile, "Cc: %s\n", cc_list);
  214.  
  215. #ifndef NO_XHEADER
  216.     fprintf(tempfile, "X-Mailer: fastmail [version %s PL%d]\n",
  217.       VERSION, PATCHLEVEL);
  218. #endif /* !NO_XHEADER */
  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" : mailer);
  232.  
  233. #ifdef OS2
  234.     if (strcmp(sendmail, mailer) == 0)
  235.       sprintf(command_buffer, "%s -f %s %s %s %s", mailer, 
  236.           from_addr, to_list, cc_list, bcc_list);
  237.     else
  238.       sprintf(command_buffer, "%s -t", mailer);
  239. #else
  240.     sprintf(command_buffer, "cat %s %s | %s %s %s %s",
  241.         tempfilename, filename,
  242.             sendmail_available? sendmail : mailer,
  243.         to_list, cc_list, bcc_list);
  244. #endif
  245.  
  246.     if (debug)
  247.       printf("%s\n", command_buffer);
  248.  
  249. #ifdef OS2
  250.         mailpipe = popen(command_buffer, "w");
  251.     tempfile = fopen(tempfilename, "r");
  252.         while ( fgets(buffer, sizeof(buffer), tempfile) != NULL )
  253.           fputs(buffer, mailpipe);
  254.         fclose(tempfile);
  255.     tempfile = fopen(filename, "r");
  256.         while ( fgets(buffer, sizeof(buffer), tempfile) != NULL )
  257.           fputs(buffer, mailpipe);
  258.         fclose(tempfile);
  259.         pclose(mailpipe);
  260. #else
  261.     c = system(command_buffer);
  262. #endif
  263.  
  264.     unlink(tempfilename);
  265.  
  266.     exit(c != 0);
  267. }
  268.  
  269.  
  270. usage()
  271. {
  272.   printf("\nUsage: fastmail {args} filename address(es)\n");
  273.   printf( "\nwhere {args} can be:\n\n");
  274.   printf("\t-b bcc-list       addresses to send blind-carbon copies to\n");
  275.   printf("\t-c cc-list        addresses to send carbon copies to\n");
  276.   printf("\t-d                debug\n");
  277.   printf("\t-f from-name      sender's full name\n");
  278.   printf("\t-F from-addr      sender's mail address\n");
  279.   printf("\t-r reply-to       reply-to mail address\n");
  280.   printf("\t-s subject        subject of the message\n");
  281.   exit(1);
  282. }
  283.  
  284.  
  285. char *get_arpa_date()
  286. {
  287.     /** returns an ARPA standard date.  The format for the date
  288.         according to DARPA document RFC-822 is exemplified by;
  289.  
  290.                      Mon, 12 Aug 85 6:29:08 MST
  291.  
  292.     **/
  293.  
  294.     static char buffer[SLEN];    /* static character buffer       */
  295.     struct tm *the_time;        /* Time structure, see CTIME(3C) */
  296.     long       junk;        /* time in seconds....         */
  297. #ifndef    _POSIX_SOURCE
  298.     struct tm *localtime();
  299. #endif
  300. #ifdef BSD
  301. #  ifndef TZ_MINUTESWEST
  302.     struct timeb loc_time;    /* of course this is different! */
  303. #    ifndef _POSIX_SOURCE
  304.     long time();
  305. #    endif
  306. #  else
  307.     struct  timeval  time_val;
  308.     struct  timezone time_zone;
  309. #  endif
  310. #else
  311.     time_t time();
  312. #endif
  313.  
  314. #ifdef BSD
  315. #  ifndef TZ_MINUTESWEST
  316.     junk = (long) time((long *) 0);
  317.     ftime(&loc_time);
  318. #  else
  319.     gettimeofday(&time_val, &time_zone);
  320.     junk = time_val.tv_sec;
  321. #  endif
  322. #else
  323.     junk = time(0);    /* this must be here for it to work! */
  324. #endif
  325.     the_time = localtime(&junk);
  326.  
  327.     sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
  328.       arpa_dayname[the_time->tm_wday],
  329.       the_time->tm_mday % 32,
  330.       arpa_monname[the_time->tm_mon],
  331.       the_time->tm_year % 100,
  332.       the_time->tm_hour % 24,
  333.       the_time->tm_min  % 61,
  334.       the_time->tm_sec  % 61,
  335. #if defined(BSD) && !defined(_POSIX_SOURCE)
  336. #  ifndef TZ_MINUTESWEST
  337.       timezone(loc_time.time_zone, the_time->tz_isdst));
  338. #  else
  339. #   ifdef GOULD_NP1
  340.       the_time->tm_zone);
  341. #   else
  342.       timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime));
  343. #   endif
  344. #  endif
  345. #else
  346.       tzname[the_time->tm_isdst]);
  347. #endif
  348.  
  349.     return( (char *) buffer);
  350. }
  351.