xref: /illumos-gate/usr/src/cmd/mail/copymt.c (revision 6a634c9d)
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 
copymt(f1,f2)43 void copymt(f1, f2)
44 register 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 
141 dohdr:
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 
169 putout:
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