copymt.c revision 23a1ccea6aac035f084a7a4cdc968687d1b02daf
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27/*	  All Rights Reserved  	*/
28
29/*
30    NAME
31	copymt - copy mail (f1) to temp (f2)
32
33    SYNOPSIS
34	void copymt(FILE *f1, FILE *f2)
35
36    DESCRIPTION
37	The mail messages in /var/mail are copied into
38	the temp file. The file pointers f1 and f2 point
39	to the files, respectively.
40*/
41#include "mail.h"
42
43void copymt(f1, f2)
44register FILE *f1, *f2;
45{
46	static char pn[] = "copymt";
47	long nextadr;
48	int n, newline = 1;
49	int StartNewMsg = TRUE;
50	int ToldUser = FALSE;
51	int mesg = 0;
52	int ctf = FALSE; 		/* header continuation flag */
53	long clen = (long)0;
54	int hdr = 0;
55	int cflg = 0;			/* found Content-length in header */
56
57	Dout(pn, 0,"entered\n");
58	if (!let[1].adr) {
59		nlet = nextadr = 0;
60		let[0].adr = 0;
61		let[0].text = TRUE;	/* until proven otherwise.... */
62		let[0].change = ' ';
63	} else {
64		nextadr = let[nlet].adr;
65	}
66
67	while ((n = getaline(line, sizeof line, f1)) > 0) {
68		if (!newline) {
69			goto putout;
70		} else if ((hdr = isheader (line, &ctf)) == FALSE) {
71			ctf = FALSE;	/* next line can't be cont. */
72		}
73		if (!hdr && cflg) {	/* nonheader, Content-length seen */
74			if (clen < n) {	/* read too much */
75				/* NB: this only can happen if the content-length
76				 * says a smaller number than what's seen on the
77				 * first non-header line.
78				 */
79				if (let[nlet-1].text == TRUE) {
80					let[nlet-1].text = istext((unsigned char*)line,clen);
81				    Dout(pn, 0, "1, let[%d].text = %s\n",
82					   nlet-1,
83					   (let[nlet-1].text ? "TRUE":"FALSE"));
84				}
85				if (fwrite(line,1,(int)clen,f2) != clen) {
86					fclose(f1); fclose(f2);
87					errmsg(E_FILE,
88						"Write error in copymt()");
89					done(0);
90				}
91				nextadr += clen;
92				n -= clen;
93				strmove (line, line+clen);
94				cflg = 0;
95				ctf = FALSE;
96				hdr = isheader(line, &ctf);
97				goto dohdr;
98			}
99			/* here, clen >= n */
100			if (n == 1 && line[0] == '\n'){	/* leading empty line */
101				clen++;		/* cheat */
102			}
103			nextadr += clen;
104			for (;;) {
105				if (let[nlet-1].text == TRUE) {
106					let[nlet-1].text = istext((unsigned char*)line,n);
107				  Dout(pn, 0, "2, let[%d].text = %s\n",
108					nlet-1,
109					(let[nlet-1].text ? "TRUE" : "FALSE"));
110				}
111				if (fwrite(line,1,n,f2) != n) {
112					fclose(f1); fclose(f2);
113					errmsg(E_FILE,
114						"Write error in copymt()");
115					done(0);
116				}
117				clen -= n;
118				if (clen <= 0) {
119					break;
120				}
121				n = clen < sizeof line ? clen : sizeof line;
122				if ((n = fread (line, 1, n, f1)) <= 0) {
123				    fprintf(stderr,
124		"%c%s:\tYour mailfile was found to be corrupted.\n",
125						BELL, program);
126				    fprintf(stderr,
127					"\t(Unexpected end-of-file).\n");
128				    fprintf(stderr,
129					"\tMessage #%d may be truncated.%c\n\n",
130						nlet, BELL);
131					nextadr -= clen;
132					clen = 0; /* stop the loop */
133				}
134			}
135			/* All done, go to top for next message */
136			cflg = 0;
137			StartNewMsg = TRUE;
138			continue;
139		}
140
141dohdr:
142		switch (hdr) {
143		case H_FROM:
144			if(nlet >= (MAXLET-2)) {
145				if (!mesg) {
146					fprintf(stderr,"%s: Too many letters, overflowing letters concatenated\n\n",program);
147					mesg++;
148				}
149			} else {
150				let[nlet++].adr = nextadr;
151				let[nlet].text = TRUE;
152				let[nlet].change = ' ';
153			}
154			Dout(pn, 5, "setting StartNewMsg to FALSE\n");
155			StartNewMsg = FALSE;
156			ToldUser = FALSE;
157			break;
158		case H_CLEN:
159			if (cflg) {
160				break;
161			}
162			cflg = TRUE;	/* mark for clen processing */
163			clen = atol (strpbrk (line, ":")+1);
164			break;
165		default:
166			break;
167		}
168
169putout:
170		if (nlet == 0) {
171			fclose(f1);
172			fclose(f2);
173			errmsg(E_FILE,"mailfile does not begin with a 'From' line");
174			done(0);
175		}
176		nextadr += n;
177		if (let[nlet-1].text == TRUE) {
178			let[nlet-1].text = istext((unsigned char*)line,n);
179		        Dout(pn, 5,"3, let[%d].text = %s\n",
180				nlet-1, (let[nlet-1].text ? "TRUE" : "FALSE"));
181		}
182		if (fwrite(line,1,n,f2) != n) {
183			fclose(f1);
184			fclose(f2);
185			errmsg(E_FILE,"Write error in copymt()");
186			done(0);
187		}
188		if (line[n-1] == '\n') {
189			newline = 1;
190			if (n == 1) { /* Blank line. Skip StartNewMsg */
191				      /* check below                  */
192				continue;
193			}
194		} else {
195			newline = 0;
196		}
197		if (StartNewMsg == TRUE && ToldUser == FALSE) {
198			fprintf(stderr,
199			     "%c%s:\tYour mailfile was found to be corrupted\n",
200			     BELL, program);
201			fprintf(stderr, "\t(Content-length mismatch).\n");
202			fprintf(stderr,"\tMessage #%d may be truncated,\n",
203			     nlet);
204			fprintf(stderr,
205			    "\twith another message concatenated to it.%c\n\n",
206			    BELL);
207			ToldUser = TRUE;
208		}
209	}
210
211	/*
212		last plus 1
213	*/
214	let[nlet].adr = nextadr;
215	let[nlet].change = ' ';
216	let[nlet].text = TRUE;
217}
218