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