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