11392Seric # include <stdio.h> 21392Seric # include <ctype.h> 31439Seric # include <errno.h> 41392Seric # include "dlvrmail.h" 51392Seric 6*1587Seric static char SccsId[] = "@(#)collect.c 1.5 10/21/80"; 71392Seric 81392Seric /* 91392Seric ** MAKETEMP -- read & parse message header & make temp file. 101392Seric ** 111392Seric ** Creates a temporary file name and copies the standard 121392Seric ** input to that file. While it is doing it, it looks for 131392Seric ** "From:" and "Sender:" fields to use as the from-person 141392Seric ** (but only if the -a flag is specified). It prefers to 151392Seric ** to use the "Sender:" field. 161392Seric ** 171392Seric ** MIT seems to like to produce "Sent-By:" fields instead 181392Seric ** of "Sender:" fields. We used to catch this, but it turns 191392Seric ** out that the "Sent-By:" field doesn't always correspond 201392Seric ** to someone real ("___057", for instance), as required by 211392Seric ** the protocol. So we limp by..... 221392Seric ** 231392Seric ** Parameters: 241392Seric ** none 251392Seric ** 261392Seric ** Returns: 271392Seric ** Name of temp file. 281392Seric ** 291392Seric ** Side Effects: 301392Seric ** Temp file is created and filled. 311392Seric ** 321392Seric ** Called By: 331392Seric ** main 341392Seric ** 351392Seric ** Notes: 361392Seric ** This is broken off from main largely so that the 371392Seric ** temp buffer can be deallocated. 381392Seric */ 391392Seric 401397Seric char MsgId[MAXNAME]; 411397Seric 421392Seric char * 431392Seric maketemp() 441392Seric { 451392Seric register FILE *tf; 461392Seric char buf[MAXFIELD+1]; 471392Seric static char fbuf[sizeof buf]; 481392Seric extern char *prescan(); 491392Seric extern char *matchhdr(); 501392Seric register char *p; 511392Seric register bool inheader; 521392Seric bool firstline; 531392Seric char c; 541439Seric extern int errno; 551392Seric 561392Seric /* 571392Seric ** Create the temp file name and create the file. 581392Seric */ 591392Seric 601392Seric mktemp(InFileName); 611392Seric close(creat(InFileName, 0600)); 621392Seric if ((tf = fopen(InFileName, "w")) == NULL) 631392Seric { 641392Seric syserr("Cannot create %s", InFileName); 651392Seric return (NULL); 661392Seric } 671392Seric 681392Seric /* 691392Seric ** Copy stdin to temp file & do message editting. 701392Seric ** From person gets copied into fbuf. At the end of 711392Seric ** this loop, if fbuf[0] == '\0' then there was no 721392Seric ** recognized from person in the message. We also 731392Seric ** save the message id in MsgId. The 741392Seric ** flag 'inheader' keeps track of whether we are 751392Seric ** in the header or in the body of the message. 761392Seric ** The flag 'firstline' is only true on the first 771392Seric ** line of a message. 781392Seric ** To keep certain mailers from getting confused, 791392Seric ** and to keep the output clean, lines that look 801392Seric ** like UNIX "From" lines are deleted in the header, 811392Seric ** and prepended with ">" in the body. 821392Seric */ 831392Seric 841392Seric inheader = TRUE; 851392Seric firstline = TRUE; 861392Seric fbuf[0] = '\0'; 871392Seric while (fgets(buf, sizeof buf, stdin) != NULL) 881392Seric { 891392Seric if (inheader && isalnum(buf[0])) 901392Seric { 911392Seric /* get the rest of this field */ 921392Seric while ((c = getc(stdin)) == ' ' || c == '\t') 931392Seric { 941392Seric p = &buf[strlen(buf)]; 951392Seric *p++ = c; 961392Seric if (fgets(p, sizeof buf - (p - buf), stdin) == NULL) 971392Seric break; 981392Seric } 99*1587Seric if (c != EOF) 100*1587Seric ungetc(c, stdin); 1011392Seric } 1021392Seric 1031392Seric if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0')) 1041392Seric break; 1051392Seric 1061392Seric /* are we still in the header? */ 1071392Seric if ((buf[0] == '\n' || buf[0] == '\0') && inheader) 1081392Seric { 1091392Seric inheader = FALSE; 1101392Seric if (MsgId[0] == '\0') 1111392Seric { 1121392Seric makemsgid(); 1131392Seric if (UseMsgId) 1141392Seric fprintf(tf, "Message-Id: <%s>\n", MsgId); 1151392Seric } 1161392Seric # ifdef DEBUG 1171392Seric if (Debug) 1181392Seric printf("EOH\n"); 1191392Seric # endif DEBUG 1201392Seric } 1211392Seric 1221392Seric /* Hide UNIX-like From lines */ 1231392Seric if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' && 1241392Seric buf[3] == 'm' && buf[4] == ' ') 1251392Seric { 1261392Seric if (firstline && !SaveFrom) 1271392Seric continue; 1281392Seric fputs(">", tf); 1291392Seric } 1301392Seric 1311392Seric if (inheader && !isspace(buf[0])) 1321392Seric { 1331392Seric /* find out if this is really a header */ 1341392Seric for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++) 1351392Seric continue; 1361392Seric while (*p != ':' && isspace(*p)) 1371392Seric p++; 1381392Seric if (*p != ':') 1391392Seric { 1401392Seric inheader = FALSE; 1411392Seric # ifdef DEBUG 1421392Seric if (Debug) 1431392Seric printf("EOH?\n"); 1441392Seric # endif DEBUG 1451392Seric } 1461392Seric } 1471392Seric 1481392Seric if (inheader) 1491392Seric { 1501392Seric /* find the sender */ 1511392Seric p = matchhdr(buf, "sender"); 1521392Seric if (p == NULL && fbuf[0] == '\0') 1531392Seric p = matchhdr(buf, "from"); 1541392Seric if (p != NULL) 1551392Seric prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0'); 1561392Seric 1571392Seric /* find the message id */ 1581392Seric p = matchhdr(buf, "message-id"); 1591392Seric if (p != NULL && MsgId[0] == '\0') 1601392Seric prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0'); 1611392Seric } 1621392Seric fputs(buf, tf); 1631392Seric firstline = FALSE; 1641392Seric if (ferror(tf)) 1651392Seric { 1661439Seric if (errno == ENOSPC) 1671439Seric { 1681439Seric freopen(InFileName, "w", tf); 1691439Seric fputs("\nMAIL DELETED BECAUSE OF LACK OF DISK SPACE\n\n", tf); 1701439Seric syserr("Out of disk space for temp file"); 1711439Seric } 1721439Seric else 1731439Seric syserr("Cannot write %s", InFileName); 1741439Seric freopen("/dev/null", "w", tf); 1751392Seric } 1761392Seric } 1771392Seric fclose(tf); 1781392Seric if (MsgId[0] == '\0') 1791392Seric makemsgid(); 1801392Seric if (freopen(InFileName, "r", stdin) == NULL) 1811392Seric syserr("Cannot reopen %s", InFileName); 1821392Seric return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL); 1831392Seric } 1841392Seric /* 1851392Seric ** MAKEMSGID -- Compute a message id for this process. 1861392Seric ** 1871392Seric ** This routine creates a message id for a message if 1881392Seric ** it did not have one already. If the MESSAGEID compile 1891392Seric ** flag is set, the messageid will be added to any message 1901392Seric ** that does not already have one. Currently it is more 1911392Seric ** of an artifact, but I suggest that if you are hacking, 1921392Seric ** you leave it in -- I may want to use it someday if 1931392Seric ** duplicate messages turn out to be a problem. 1941392Seric ** 1951392Seric ** Parameters: 1961392Seric ** none. 1971392Seric ** 1981392Seric ** Returns: 1991392Seric ** none. 2001392Seric ** 2011392Seric ** Side Effects: 2021392Seric ** Stores a message-id into MsgId. 2031392Seric ** 2041392Seric ** Called By: 2051392Seric ** maketemp 2061392Seric */ 2071392Seric 2081392Seric makemsgid() 2091392Seric { 2101392Seric auto long t; 2111392Seric extern char *MyLocName; 2121392Seric extern char *ArpaHost; 2131392Seric 2141392Seric time(&t); 2151392Seric sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost); 2161392Seric } 217