* Copyright (c) 1983 Eric P. Allman
* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)collect.c 5.4 (Berkeley) 6/30/88";
** COLLECT -- read & parse message header & make temp file.
** Creates a temporary file name and copies the standard
** input to that file. Leading UNIX-style "From" lines are
** stripped off (after important information is extracted).
** sayok -- if set, give an ARPANET style message
** to say we are ready to collect input.
** Temp file is created and filled.
** The from person may be set.
** Create the temp file name and create the file.
CurEnv
->e_df
= newstr(queuename(CurEnv
, 'd'));
if ((tf
= dfopen(CurEnv
->e_df
, "w")) == NULL
)
syserr("Cannot create %s", CurEnv
->e_df
);
(void) chmod(CurEnv
->e_df
, FileMode
);
** Tell ARPANET to go ahead.
message("354", "Enter mail, end with \".\" on a line by itself");
** Try to read a UNIX-style From line
(void) sfgets(buf
, sizeof buf
, InChannel
);
if (!SaveFrom
&& strncmp(buf
, "From ", 5) == 0)
(void) sfgets(buf
, sizeof buf
, InChannel
);
** Copy InChannel to temp file & do message editing.
** To keep certain mailers from getting confused,
** and to keep the output clean, lines that look
** like UNIX "From" lines are deleted in the header.
/* if the line is too long, throw the rest away */
if (index(buf
, '\n') == NULL
)
while ((c
= getc(InChannel
)) != '\n' && c
!= EOF
)
/* see if the header is over */
/* get the rest of this field */
while ((c
= getc(InChannel
)) == ' ' || c
== '\t')
if (sfgets(p
, MAXFIELD
- (p
- buf
), InChannel
) == NULL
)
if (!feof(InChannel
) && !ferror(InChannel
))
(void) ungetc(c
, InChannel
);
CurEnv
->e_msgsize
+= strlen(buf
);
if (bitset(H_EOH
, chompheader(buf
, FALSE
)))
} while (sfgets(buf
, MAXFIELD
, InChannel
) != NULL
);
/* throw away a blank line */
(void) sfgets(buf
, MAXFIELD
, InChannel
);
** Collect the body of the message.
/* check for end-of-message */
if (!IgnrDot
&& buf
[0] == '.' && (buf
[1] == '\n' || buf
[1] == '\0'))
/* check for transparent dot */
if (OpMode
== MD_SMTP
&& !IgnrDot
&& bp
[0] == '.' && bp
[1] == '.')
** Figure message length, output the line to the temp
** file, and insert a newline if missing.
CurEnv
->e_msgsize
+= strlen(bp
) + 1;
} while (sfgets(buf
, MAXFIELD
, InChannel
) != NULL
);
/* An EOF when running SMTP is an error */
if ((feof(InChannel
) || ferror(InChannel
)) && OpMode
== MD_SMTP
)
syserr("collect: unexpected close, from=%s", CurEnv
->e_from
.q_paddr
);
/* don't return an error indication */
CurEnv
->e_flags
&= ~EF_FATALERRS
;
/* and don't try to deliver the partial message either */
** Find out some information from the headers.
** Examples are who is the from person & the date.
** Add an Apparently-To: line if we have no recipient lines.
if (hvalue("to") == NULL
&& hvalue("cc") == NULL
&&
hvalue("bcc") == NULL
&& hvalue("apparently-to") == NULL
)
/* create an Apparently-To: field */
/* that or reject the message.... */
for (q
= CurEnv
->e_sendqueue
; q
!= NULL
; q
= q
->q_next
)
printf("Adding Apparently-To: %s\n", q
->q_paddr
);
addheader("apparently-to", q
->q_paddr
, CurEnv
);
if ((CurEnv
->e_dfp
= fopen(CurEnv
->e_df
, "r")) == NULL
)
syserr("Cannot reopen %s", CurEnv
->e_df
);
** TFERROR -- signal error on writing the temporary file.
** tf -- the file pointer for the temporary file.
** Gives an error message.
** Arranges for following output to go elsewhere.
(void) freopen(CurEnv
->e_df
, "w", tf
);
fputs("\nMAIL DELETED BECAUSE OF LACK OF DISK SPACE\n\n", tf
);
usrerr("452 Out of disk space for temp file");
syserr("collect: Cannot write %s", CurEnv
->e_df
);
(void) freopen("/dev/null", "w", tf
);
** EATFROM -- chew up a UNIX style from line and process
** This does indeed make some assumptions about the format
** extracts what information it can from the header,
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
printf("eatfrom(%s)\n", fm
);
while (*p
!= '\0' && *p
!= ' ')
if (!isupper(*p
) || p
[3] != ' ' || p
[13] != ':' || p
[16] != ':')
/* we have a possible date */
for (dt
= DowList
; *dt
!= NULL
; dt
++)
if (strncmp(*dt
, p
, 3) == 0)
for (dt
= MonthList
; *dt
!= NULL
; dt
++)
if (strncmp(*dt
, &p
[4], 3) == 0)
/* we have found a date */
(void) strncpy(q
, p
, 25);
define('a', newstr(q
), CurEnv
);