home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / utils / from.c < prev    next >
C/C++ Source or Header  |  1992-03-22  |  11KB  |  433 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: from.c,v 4.1 90/04/28 22:44:41 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.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:    from.c,v $
  17.  * Revision 4.1  90/04/28  22:44:41  syd
  18.  * checkin of Elm 2.3 as of Release PL0
  19.  *
  20.  *
  21.  ******************************************************************************/
  22.  
  23. /** print out whom each message is from in the pending folder or specified
  24.     one, including a subject line if available..
  25.  
  26. **/
  27.  
  28. #include <stdio.h>
  29. #include <pwd.h>
  30. #include "defs.h"
  31.  
  32. static char ident[] = { WHAT_STRING };
  33.  
  34. #ifdef MMDF
  35. char username[SLEN] = {0};
  36. #endif /* MMDF */
  37.  
  38. #define LINEFEED    (char) 10
  39.  
  40. #define metachar(c)    (c == '=' || c == '+' || c == '%')
  41.  
  42. FILE *mailfile;
  43.  
  44. int   number = 0,    /* should we number the messages?? */
  45.       verbose = 0;    /* and should we prepend a header? */
  46.  
  47. main(argc, argv)
  48. int argc;
  49. char *argv[];
  50. {
  51.     char infile[SLEN], *cp ;
  52.     int  multiple_files = 0, output_files = 0, c;
  53.     struct passwd *pass;
  54. #ifndef    _POSIX_SOURCE
  55.     struct passwd *getpwuid();
  56. #endif
  57.     extern int optind;
  58.  
  59.         initpaths();
  60.  
  61.     while ((c = getopt(argc, argv, "nv")) != EOF)
  62.       switch (c) {
  63.         case (int)'n': number++;        break;
  64.         case (int)'v': verbose++;    break;
  65.         case (int)'?': printf("Usage: %s [-n] [-v] {filename | username}\n",
  66.                  argv[0]);
  67.                        exit(1);
  68.       }
  69.  
  70.     if((pass = getpwuid(getuid())) == NULL) {
  71.       printf("You have no password entry!");
  72.       exit(1);
  73.     }
  74.     strcpy(username,pass->pw_name);
  75.  
  76.     infile[0] = '\0';
  77.     if (optind == argc) {
  78.     /*
  79.      *    determine mail file from environment variable if found,
  80.      *    else use password entry
  81.      */
  82.       optind -= 1;    /* ensure one pass through loop */
  83.       if ((cp = getenv("MAIL")) == NULL)
  84.         strcpy(infile, argv[optind] = username);
  85.       else
  86.         strcpy(infile, argv[optind] = cp);
  87.     }
  88.  
  89.     multiple_files = (argc - optind > 1);
  90.  
  91.     while (optind < argc) {
  92.  
  93.       if (multiple_files) {
  94.         strcpy(infile, argv[optind]);
  95.         printf("%s%s: \n", output_files++ > 0 ? "\n":"", infile);
  96.       }
  97.       else if (infile[0] == '\0')
  98.         strcpy(infile, argv[optind]);
  99.  
  100.       if (metachar(infile[0])) {
  101.         if (expand(infile) == 0) {
  102.            fprintf(stderr, "%s: couldn't expand filename %s!\n",
  103.                argv[0], infile);
  104.            exit(1);
  105.         }
  106.       }
  107.  
  108.       if ((mailfile = fopen(infile,"r")) == NULL) {
  109.           if (infile[0] == '/')
  110.             printf("Couldn't open folder \"%s\".\n", infile);
  111.           else {
  112.             sprintf(infile,"%s%s", mailhome, argv[optind]);
  113.             if ((mailfile = fopen(infile,"r")) == NULL)
  114.               printf("Couldn't open folders \"%s\" or \"%s\".\n",
  115.              argv[optind], infile);
  116.             else {
  117.           if (read_headers(1)==0)
  118.                 printf("No mail.\n");
  119.               fclose(mailfile);
  120.         }
  121.           }
  122.       } else {
  123.         if (read_headers(0)==0)
  124.           printf("No messages in that folder!\n");
  125.         fclose(mailfile);
  126.       }
  127.  
  128.       optind++;
  129.     }
  130.     exit(0);
  131. }
  132.  
  133. int
  134. read_headers(user_mailbox)
  135. int user_mailbox;
  136. {
  137.     /** Read the headers, output as found.  User-Mailbox is to guarantee
  138.         that we get a reasonably sensible message from the '-v' option
  139.      **/
  140.  
  141.     char buffer[SLEN], from_whom[SLEN], subject[SLEN];
  142.     register int in_header = 0, count = 0;
  143. #ifdef MMDF
  144.     int newheader = 0;
  145. #endif /* MMDF */
  146.  
  147.     while (fgets(buffer, SLEN, mailfile) != NULL) {
  148.       if (index(buffer, '\n') == NULL && !feof(mailfile)) {
  149.         int c;
  150.         while ((c = getc(mailfile)) != EOF && c != '\n')
  151.           ; /* keep reading */
  152.       }
  153.  
  154. #ifdef MMDF
  155.           if (strcmp(buffer, MSG_SEPERATOR) == 0 || !newheader &&
  156.             first_word(buffer,"From ") && real_from(buffer, from_whom)) {
  157.         newheader = 1;
  158.         subject[0] = '\0';
  159.         in_header = 1;
  160.       }
  161. #else
  162.       if (first_word(buffer,"From ")
  163.        && real_from(buffer, from_whom)) {
  164.         subject[0] = '\0';
  165.         in_header = 1;
  166.       }
  167. #endif /* MMDF */
  168.       else if (in_header) {
  169. #ifdef MMDF
  170.             newheader = 0;
  171.         if (first_word(buffer,"From "))
  172.           real_from(buffer, from_whom);
  173. #endif /* MMDF */
  174.         if (first_word(buffer,">From "))
  175.           forwarded(buffer, from_whom); /* return address */
  176.         else if (first_word(buffer,"Subject:") ||
  177.              first_word(buffer,"Re:")) {
  178.           if (subject[0] == '\0') {
  179.             remove_first_word(buffer);
  180.         strcpy(subject, buffer);
  181.           }
  182.         }
  183.         else if (first_word(buffer,"From:") ||
  184.             first_word(buffer, ">From:"))
  185.           parse_arpa_from(buffer, from_whom);
  186.         else if (buffer[0] == LINEFEED) {
  187.           if (verbose && count == 0)
  188.             printf("%s contains the following messages:\n\n",
  189.             user_mailbox?"Your mailbox" : "Folder");
  190. #ifdef MMDF
  191.           if (*from_whom == '\0')
  192.                 strcpy(from_whom,username);
  193. #endif /* MMDF */
  194.           ++count;
  195.           show_header(count, from_whom, subject);
  196.           in_header = 0;
  197.         }
  198.       }
  199.     }
  200.     return(count);
  201. }
  202.  
  203. int
  204. real_from(buffer, who)
  205. char *buffer, *who;
  206. {
  207.     /***** returns true iff 's' has the seven 'from' fields,
  208.            initializing the who to the sender *****/
  209.  
  210.     char junk[SLEN];
  211.  
  212.     junk[0] = '\0';
  213.     sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
  214.                 who, junk);
  215.     return(junk[0] != '\0');
  216. }
  217.  
  218. forwarded(buffer, who)
  219. char *buffer, *who;
  220. {
  221.     /** change 'from' and date fields to reflect the ORIGINATOR of
  222.         the message by iteratively parsing the >From fields... **/
  223.  
  224.     char machine[SLEN], buff[SLEN], holding_from[SLEN];
  225.  
  226.     machine[0] = '\0';
  227.     holding_from[0] = '\0';
  228.     sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %s",
  229.                 holding_from, machine);
  230.  
  231.     if(machine[0] == '\0')    /* try for address with timezone in date */
  232.     sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
  233.                 holding_from, machine);
  234.  
  235.     if (machine[0] == '\0') /* try for srm address */
  236.       sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
  237.                 holding_from, machine);
  238.  
  239.     if (machine[0] == '\0')
  240.       sprintf(buff, holding_from[0] ? holding_from : "anonymous");
  241.     else
  242.       sprintf(buff,"%s!%s", machine, holding_from);
  243.  
  244.     strncpy(who, buff, SLEN);
  245. }
  246.  
  247. remove_first_word(string)
  248. char *string;
  249. {    /** removes first word of string, ie up to first non-white space
  250.         following a white space! **/
  251.  
  252.     register int loc;
  253.  
  254.     for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
  255.         ;
  256.  
  257.     while (string[loc] == ' ' || string[loc] == '\t')
  258.       loc++;
  259.  
  260.     move_left(string, loc);
  261. }
  262.  
  263. move_left(string, chars)
  264. char string[];
  265. int  chars;
  266. {
  267.     /** moves string chars characters to the left DESTRUCTIVELY **/
  268.  
  269.     register int i;
  270.  
  271.     chars--; /* index starting at zero! */
  272.  
  273.     for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
  274.       string[i-chars] = string[i];
  275.  
  276.     string[i-chars] = '\0';
  277. }
  278.  
  279. show_header(count, from, subject)
  280. int  count;
  281. char *from, *subject;
  282. {
  283.     /** output header in clean format, including abbreviation
  284.         of return address if more than one machine name is
  285.         contained within it! **/
  286.  
  287.     char buffer[SLEN];
  288.     int  loc, i=0, exc=0, len;
  289.  
  290. #ifndef INTERNET
  291.     char *p;
  292.  
  293.     if (chloc(from,'!') != -1 && chloc(from,'@') > 0) {
  294.       for (p=from;*p != '@'; p++) ;
  295.       *p = '\0';
  296.     }
  297. #endif
  298.  
  299.     loc = strlen(from);
  300.  
  301.     while (exc < 2 && loc > 0)
  302.       if (from[--loc] == '!')
  303.         exc++;
  304.  
  305.     if (exc == 2) { /* lots of machine names!  Get last one */
  306.       loc++;
  307.       len = strlen(from);
  308.       while (loc < len && loc < SLEN)
  309.         buffer[i++] = from[loc++];
  310.       buffer[i] = '\0';
  311.       if (number)
  312.         printf("%3d: %-20s  %s\n", count, buffer, subject);
  313.       else
  314.         printf("%-20s  %s\n", buffer, subject);
  315.     }
  316.     else
  317.       if (number)
  318.         printf("%3d: %-20s  %s\n", count, from, subject);
  319.       else
  320.         printf("%-20s  %s\n", from, subject);
  321. }
  322.  
  323. parse_arpa_from(buffer, newfrom)
  324. char *buffer, *newfrom;
  325. {
  326.     /** try to parse the 'From:' line given... It can be in one of
  327.         two formats:
  328.         From: Dave Taylor <hpcnou!dat>
  329.         or  From: hpcnou!dat (Dave Taylor)
  330.         Change 'newfrom' ONLY if sucessfully parsed this entry and
  331.         the resulting name is non-null!
  332.     **/
  333.  
  334.     char temp_buffer[SLEN], *temp;
  335.     register int i, j = 0, in_parens;
  336.  
  337.     temp = (char *) temp_buffer;
  338.     temp[0] = '\0';
  339.  
  340.     no_ret(buffer);        /* blow away '\n' char! */
  341.  
  342.     if (lastch(buffer) == '>') {
  343.       for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
  344.            buffer[i] != '('; i++)
  345.         temp[j++] = buffer[i];
  346.       temp[j] = '\0';
  347.     }
  348.     else if (lastch(buffer) == ')') {
  349.       in_parens = 1;
  350.       for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '<'; i--) {
  351.         switch(buffer[i]) {
  352.         case ')':    in_parens++;
  353.             break;
  354.         case '(':    in_parens--;
  355.             break;
  356.         }
  357.         if(!in_parens) break;
  358.         temp[j++] = buffer[i];
  359.       }
  360.       temp[j] = '\0';
  361.       reverse(temp);
  362.     }
  363.  
  364. /* this stuff copied from src/addr_util.c */
  365. #ifdef USE_EMBEDDED_ADDRESSES
  366.  
  367.     /** if we have a null string at this point, we must just have a
  368.         From: line that contains an address only.  At this point we
  369.         can have one of a few possibilities...
  370.  
  371.         From: address
  372.         From: <address>
  373.         From: address ()
  374.     **/
  375.  
  376.     if (strlen(temp) == 0) {
  377.       if (lastch(buffer) != '>') {
  378.         for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++)
  379.           temp[j++] = buffer[i];
  380.         temp[j] = '\0';
  381.       }
  382.       else {    /* get outta '<>' pair, please! */
  383.         for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--)
  384.           temp[j++] = buffer[i];
  385.         temp[j] = '\0';
  386.         reverse(temp);
  387.       }
  388.     }
  389. #endif
  390.  
  391.     if (strlen(temp) > 0) {        /* mess with buffer... */
  392.  
  393.       /* remove leading spaces... */
  394.  
  395.       while (whitespace(temp[0]))
  396.         temp = (char *) (temp + 1);        /* increment address! */
  397.  
  398.       /* remove trailing spaces... */
  399.  
  400.       i = strlen(temp) - 1;
  401.  
  402.       while (whitespace(temp[i]))
  403.        temp[i--] = '\0';
  404.  
  405.       /* remove surrounding paired quotation marks */
  406.       if((temp[i] == '"') & (*temp == '"')) {
  407.         temp[i] = '\0';
  408.         temp++;
  409.       }
  410.  
  411.       /* if anything is left, let's change 'from' value! */
  412.  
  413.       if (strlen(temp) > 0)
  414.         strcpy(newfrom, temp);
  415.     }
  416. }
  417.  
  418. reverse(string)
  419. char *string;
  420. {
  421.     /** reverse string... pretty trivial routine, actually! **/
  422.  
  423.     char buffer[SLEN];
  424.     register int i, j = 0;
  425.  
  426.     for (i = strlen(string)-1; i >= 0; i--)
  427.       buffer[j++] = string[i];
  428.  
  429.     buffer[j] = '\0';
  430.  
  431.     strcpy(string, buffer);
  432. }
  433.