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