1 # include <stdio.h> 2 # include <ctype.h> 3 # include "dlvrmail.h" 4 5 static char SccsId[] = "@(#)collect.c 1.2 10/11/80"; 6 7 /* 8 ** MAKETEMP -- read & parse message header & make temp file. 9 ** 10 ** Creates a temporary file name and copies the standard 11 ** input to that file. While it is doing it, it looks for 12 ** "From:" and "Sender:" fields to use as the from-person 13 ** (but only if the -a flag is specified). It prefers to 14 ** to use the "Sender:" field. 15 ** 16 ** MIT seems to like to produce "Sent-By:" fields instead 17 ** of "Sender:" fields. We used to catch this, but it turns 18 ** out that the "Sent-By:" field doesn't always correspond 19 ** to someone real ("___057", for instance), as required by 20 ** the protocol. So we limp by..... 21 ** 22 ** Parameters: 23 ** none 24 ** 25 ** Returns: 26 ** Name of temp file. 27 ** 28 ** Side Effects: 29 ** Temp file is created and filled. 30 ** 31 ** Called By: 32 ** main 33 ** 34 ** Notes: 35 ** This is broken off from main largely so that the 36 ** temp buffer can be deallocated. 37 */ 38 39 char * 40 maketemp() 41 { 42 register FILE *tf; 43 char buf[MAXFIELD+1]; 44 static char fbuf[sizeof buf]; 45 extern char *prescan(); 46 extern char *matchhdr(); 47 register char *p; 48 register bool inheader; 49 bool firstline; 50 char c; 51 52 /* 53 ** Create the temp file name and create the file. 54 */ 55 56 mktemp(InFileName); 57 close(creat(InFileName, 0600)); 58 if ((tf = fopen(InFileName, "w")) == NULL) 59 { 60 syserr("Cannot create %s", InFileName); 61 return (NULL); 62 } 63 64 /* 65 ** Copy stdin to temp file & do message editting. 66 ** From person gets copied into fbuf. At the end of 67 ** this loop, if fbuf[0] == '\0' then there was no 68 ** recognized from person in the message. We also 69 ** save the message id in MsgId. The 70 ** flag 'inheader' keeps track of whether we are 71 ** in the header or in the body of the message. 72 ** The flag 'firstline' is only true on the first 73 ** line of a message. 74 ** To keep certain mailers from getting confused, 75 ** and to keep the output clean, lines that look 76 ** like UNIX "From" lines are deleted in the header, 77 ** and prepended with ">" in the body. 78 */ 79 80 inheader = TRUE; 81 firstline = TRUE; 82 fbuf[0] = '\0'; 83 while (fgets(buf, sizeof buf, stdin) != NULL) 84 { 85 if (inheader && isalnum(buf[0])) 86 { 87 /* get the rest of this field */ 88 while ((c = getc(stdin)) == ' ' || c == '\t') 89 { 90 p = &buf[strlen(buf)]; 91 *p++ = c; 92 if (fgets(p, sizeof buf - (p - buf), stdin) == NULL) 93 break; 94 } 95 ungetc(c, stdin); 96 } 97 98 if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0')) 99 break; 100 101 /* are we still in the header? */ 102 if ((buf[0] == '\n' || buf[0] == '\0') && inheader) 103 { 104 inheader = FALSE; 105 if (MsgId[0] == '\0') 106 { 107 makemsgid(); 108 if (UseMsgId) 109 fprintf(tf, "Message-Id: <%s>\n", MsgId); 110 } 111 # ifdef DEBUG 112 if (Debug) 113 printf("EOH\n"); 114 # endif DEBUG 115 } 116 117 /* Hide UNIX-like From lines */ 118 if (buf[0] == 'F' && buf[1] == 'r' && buf[2] == 'o' && 119 buf[3] == 'm' && buf[4] == ' ') 120 { 121 if (firstline && !SaveFrom) 122 continue; 123 fputs(">", tf); 124 } 125 126 if (inheader && !isspace(buf[0])) 127 { 128 /* find out if this is really a header */ 129 for (p = buf; *p != ':' && *p != '\0' && !isspace(*p); p++) 130 continue; 131 while (*p != ':' && isspace(*p)) 132 p++; 133 if (*p != ':') 134 { 135 inheader = FALSE; 136 # ifdef DEBUG 137 if (Debug) 138 printf("EOH?\n"); 139 # endif DEBUG 140 } 141 } 142 143 if (inheader) 144 { 145 /* find the sender */ 146 p = matchhdr(buf, "sender"); 147 if (p == NULL && fbuf[0] == '\0') 148 p = matchhdr(buf, "from"); 149 if (p != NULL) 150 prescan(p, fbuf, &fbuf[sizeof fbuf - 1], '\0'); 151 152 /* find the message id */ 153 p = matchhdr(buf, "message-id"); 154 if (p != NULL && MsgId[0] == '\0') 155 prescan(p, MsgId, &MsgId[sizeof MsgId - 1], '\0'); 156 } 157 fputs(buf, tf); 158 firstline = FALSE; 159 if (ferror(tf)) 160 { 161 syserr("Cannot write %s", InFileName); 162 clearerr(tf); 163 break; 164 } 165 } 166 fclose(tf); 167 if (MsgId[0] == '\0') 168 makemsgid(); 169 if (freopen(InFileName, "r", stdin) == NULL) 170 syserr("Cannot reopen %s", InFileName); 171 return (ArpaFmt && fbuf[0] != '\0' ? fbuf : NULL); 172 } 173 /* 174 ** MAKEMSGID -- Compute a message id for this process. 175 ** 176 ** This routine creates a message id for a message if 177 ** it did not have one already. If the MESSAGEID compile 178 ** flag is set, the messageid will be added to any message 179 ** that does not already have one. Currently it is more 180 ** of an artifact, but I suggest that if you are hacking, 181 ** you leave it in -- I may want to use it someday if 182 ** duplicate messages turn out to be a problem. 183 ** 184 ** Parameters: 185 ** none. 186 ** 187 ** Returns: 188 ** none. 189 ** 190 ** Side Effects: 191 ** Stores a message-id into MsgId. 192 ** 193 ** Called By: 194 ** maketemp 195 */ 196 197 makemsgid() 198 { 199 auto long t; 200 extern char *MyLocName; 201 extern char *ArpaHost; 202 203 time(&t); 204 sprintf(MsgId, "%ld.%d.%s@%s", t, getpid(), MyLocName, ArpaHost); 205 } 206