Mercurial > emacs
annotate lib-src/fakemail.c @ 72863:526dc1f36b09
(produce_image_glyph): Automatically crop wide images at
right window edge so we can draw the cursor on the same row to
avoid confusing redisplay by placing the cursor outside the visible
window area.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Thu, 14 Sep 2006 09:37:44 +0000 |
parents | ca1a855f01ae |
children | 6d19c76d81c5 858cb33ae39d |
rev | line source |
---|---|
18 | 1 /* sendmail-like interface to /bin/mail for system V, |
64769
6358e3c6075c
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64083
diff
changeset
|
2 Copyright (C) 1985, 1994, 1999, 2002, 2003, 2004, |
68647
3661e9b3c48f
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64769
diff
changeset
|
3 2005, 2006 Free Software Foundation, Inc. |
18 | 4 |
5 This file is part of GNU Emacs. | |
6 | |
37 | 7 GNU Emacs is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | |
6109 | 9 the Free Software Foundation; either version 2, or (at your option) |
37 | 10 any later version. |
18 | 11 |
37 | 12 GNU Emacs is distributed in the hope that it will be useful, |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GNU Emacs; see the file COPYING. If not, write to | |
64083 | 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 Boston, MA 02110-1301, USA. */ | |
18 | 21 |
22 #define NO_SHORTNAMES | |
42134
de525d9743c9
Include "config.h", not <../src/config.h>.
Dave Love <fx@gnu.org>
parents:
34951
diff
changeset
|
23 #define _XOPEN_SOURCE 500 /* for cuserid */ |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
24 |
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
25 #ifdef HAVE_CONFIG_H |
42469 | 26 #include <config.h> |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
27 #endif |
18 | 28 |
16218
32f82ca8b41f
Replaced all BSD with BSD_SYSTEM.
Karl Heuer <kwzh@gnu.org>
parents:
16121
diff
changeset
|
29 #if defined (BSD_SYSTEM) && !defined (BSD4_1) && !defined (USE_FAKEMAIL) |
18 | 30 /* This program isnot used in BSD, so just avoid loader complaints. */ |
15683 | 31 int |
18 | 32 main () |
33 { | |
16121 | 34 return 0; |
18 | 35 } |
36 #else /* not BSD 4.2 (or newer) */ | |
5447
6f0905b05218
(main) [MSDOS]: Dummy stub just to make the file compile.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
37 #ifdef MSDOS |
15683 | 38 int |
5447
6f0905b05218
(main) [MSDOS]: Dummy stub just to make the file compile.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
39 main () |
6f0905b05218
(main) [MSDOS]: Dummy stub just to make the file compile.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
40 { |
16121 | 41 return 0; |
5447
6f0905b05218
(main) [MSDOS]: Dummy stub just to make the file compile.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
42 } |
6f0905b05218
(main) [MSDOS]: Dummy stub just to make the file compile.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
43 #else /* not MSDOS */ |
18 | 44 /* This conditional contains all the rest of the file. */ |
45 | |
46 /* These are defined in config in some versions. */ | |
47 | |
48 #ifdef static | |
49 #undef static | |
50 #endif | |
51 | |
15099
857388330750
[WINDOWSNT]: Include ntlib.h.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
52 #ifdef WINDOWSNT |
857388330750
[WINDOWSNT]: Include ntlib.h.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
53 #include "ntlib.h" |
857388330750
[WINDOWSNT]: Include ntlib.h.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
54 #endif |
857388330750
[WINDOWSNT]: Include ntlib.h.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
55 |
18 | 56 #include <stdio.h> |
57 #include <string.h> | |
58 #include <ctype.h> | |
59 #include <time.h> | |
60 #include <pwd.h> | |
18841
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
61 |
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
62 /* This is to declare cuserid. */ |
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
63 #ifdef HAVE_UNISTD_H |
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
64 #include <unistd.h> |
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
65 #endif |
18 | 66 |
67 /* Type definitions */ | |
68 | |
69 #define boolean int | |
70 #define true 1 | |
71 #define false 0 | |
72 | |
69790
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
73 #define TM_YEAR_BASE 1900 |
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
74 |
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
75 /* Nonzero if TM_YEAR is a struct tm's tm_year value that causes |
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
76 asctime to have well-defined behavior. */ |
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
77 #ifndef TM_YEAR_IN_ASCTIME_RANGE |
69697
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
78 # define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \ |
69790
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
79 (1000 - TM_YEAR_BASE <= (tm_year) && (tm_year) <= 9999 - TM_YEAR_BASE) |
69697
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
80 #endif |
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
81 |
18 | 82 /* Various lists */ |
83 | |
84 struct line_record | |
85 { | |
86 char *string; | |
87 struct line_record *continuation; | |
88 }; | |
89 typedef struct line_record *line_list; | |
90 | |
91 struct header_record | |
92 { | |
93 line_list text; | |
94 struct header_record *next; | |
95 struct header_record *previous; | |
96 }; | |
97 typedef struct header_record *header; | |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
98 |
18 | 99 struct stream_record |
100 { | |
101 FILE *handle; | |
102 int (*action)(); | |
103 struct stream_record *rest_streams; | |
104 }; | |
105 typedef struct stream_record *stream_list; | |
106 | |
107 /* A `struct linebuffer' is a structure which holds a line of text. | |
108 * `readline' reads a line from a stream into a linebuffer | |
109 * and works regardless of the length of the line. | |
110 */ | |
111 | |
112 struct linebuffer | |
113 { | |
114 long size; | |
115 char *buffer; | |
116 }; | |
117 | |
118 struct linebuffer lb; | |
119 | |
120 #define new_list() \ | |
121 ((line_list) xmalloc (sizeof (struct line_record))) | |
122 #define new_header() \ | |
123 ((header) xmalloc (sizeof (struct header_record))) | |
124 #define new_stream() \ | |
125 ((stream_list) xmalloc (sizeof (struct stream_record))) | |
126 #define alloc_string(nchars) \ | |
127 ((char *) xmalloc ((nchars) + 1)) | |
128 | |
129 /* Global declarations */ | |
130 | |
131 #define BUFLEN 1024 | |
132 #define KEYWORD_SIZE 256 | |
133 #define FROM_PREFIX "From" | |
134 #define MY_NAME "fakemail" | |
135 #define NIL ((line_list) NULL) | |
136 #define INITIAL_LINE_SIZE 200 | |
137 | |
138 #ifndef MAIL_PROGRAM_NAME | |
139 #define MAIL_PROGRAM_NAME "/bin/mail" | |
140 #endif | |
141 | |
142 static char *my_name; | |
143 static char *the_date; | |
144 static char *the_user; | |
145 static line_list file_preface; | |
146 static stream_list the_streams; | |
147 static boolean no_problems = true; | |
148 | |
149 extern FILE *popen (); | |
150 extern int fclose (), pclose (); | |
151 | |
152 #ifdef CURRENT_USER | |
153 extern struct passwd *getpwuid (); | |
154 extern unsigned short geteuid (); | |
155 static struct passwd *my_entry; | |
156 #define cuserid(s) \ | |
157 (my_entry = getpwuid (((int) geteuid ())), \ | |
158 my_entry->pw_name) | |
159 #endif | |
160 | |
161 /* Utilities */ | |
162 | |
163 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | |
164 | |
165 static void | |
166 error (s1, s2) | |
167 char *s1, *s2; | |
168 { | |
169 printf ("%s: ", my_name); | |
170 printf (s1, s2); | |
171 printf ("\n"); | |
172 no_problems = false; | |
173 } | |
174 | |
175 /* Print error message and exit. */ | |
176 | |
177 static void | |
72034
ca1a855f01ae
(fatal): Drop second parameter and treat first
Andreas Schwab <schwab@suse.de>
parents:
70278
diff
changeset
|
178 fatal (s1) |
ca1a855f01ae
(fatal): Drop second parameter and treat first
Andreas Schwab <schwab@suse.de>
parents:
70278
diff
changeset
|
179 char *s1; |
18 | 180 { |
72034
ca1a855f01ae
(fatal): Drop second parameter and treat first
Andreas Schwab <schwab@suse.de>
parents:
70278
diff
changeset
|
181 error ("%s", s1); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
182 exit (EXIT_FAILURE); |
18 | 183 } |
184 | |
185 /* Like malloc but get fatal error if memory is exhausted. */ | |
186 | |
12833
25464bf61eb1
(xmalloc, xrealloc): Use return-type long *.
Richard M. Stallman <rms@gnu.org>
parents:
10265
diff
changeset
|
187 static long * |
18 | 188 xmalloc (size) |
189 int size; | |
190 { | |
12833
25464bf61eb1
(xmalloc, xrealloc): Use return-type long *.
Richard M. Stallman <rms@gnu.org>
parents:
10265
diff
changeset
|
191 long *result = (long *) malloc (((unsigned) size)); |
25464bf61eb1
(xmalloc, xrealloc): Use return-type long *.
Richard M. Stallman <rms@gnu.org>
parents:
10265
diff
changeset
|
192 if (result == ((long *) NULL)) |
72034
ca1a855f01ae
(fatal): Drop second parameter and treat first
Andreas Schwab <schwab@suse.de>
parents:
70278
diff
changeset
|
193 fatal ("virtual memory exhausted"); |
18 | 194 return result; |
195 } | |
196 | |
12833
25464bf61eb1
(xmalloc, xrealloc): Use return-type long *.
Richard M. Stallman <rms@gnu.org>
parents:
10265
diff
changeset
|
197 static long * |
18 | 198 xrealloc (ptr, size) |
12833
25464bf61eb1
(xmalloc, xrealloc): Use return-type long *.
Richard M. Stallman <rms@gnu.org>
parents:
10265
diff
changeset
|
199 long *ptr; |
18 | 200 int size; |
201 { | |
12833
25464bf61eb1
(xmalloc, xrealloc): Use return-type long *.
Richard M. Stallman <rms@gnu.org>
parents:
10265
diff
changeset
|
202 long *result = (long *) realloc (ptr, ((unsigned) size)); |
12840
4e9a14304b8b
(xrealloc): Change cast to match return type.
Karl Heuer <kwzh@gnu.org>
parents:
12833
diff
changeset
|
203 if (result == ((long *) NULL)) |
18 | 204 fatal ("virtual memory exhausted"); |
205 return result; | |
206 } | |
207 | |
208 /* Initialize a linebuffer for use */ | |
209 | |
210 void | |
211 init_linebuffer (linebuffer) | |
212 struct linebuffer *linebuffer; | |
213 { | |
214 linebuffer->size = INITIAL_LINE_SIZE; | |
215 linebuffer->buffer = ((char *) xmalloc (INITIAL_LINE_SIZE)); | |
216 } | |
217 | |
218 /* Read a line of text from `stream' into `linebuffer'. | |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
219 Return the length of the line. */ |
18 | 220 |
221 long | |
222 readline (linebuffer, stream) | |
223 struct linebuffer *linebuffer; | |
224 FILE *stream; | |
225 { | |
226 char *buffer = linebuffer->buffer; | |
227 char *p = linebuffer->buffer; | |
228 char *end = p + linebuffer->size; | |
229 | |
230 while (true) | |
231 { | |
232 int c = getc (stream); | |
233 if (p == end) | |
234 { | |
235 linebuffer->size *= 2; | |
34951
1efc40541908
(readline): Cast buffer to "long *" to pacify
Eli Zaretskii <eliz@gnu.org>
parents:
34609
diff
changeset
|
236 buffer = ((char *) xrealloc ((long *)buffer, linebuffer->size)); |
6992
ed57331fb222
(readline): Fix updating of p when buffer grows.
Richard M. Stallman <rms@gnu.org>
parents:
6954
diff
changeset
|
237 p = buffer + (p - linebuffer->buffer); |
6954
774fdc20d115
(readline): When extending the buffer,
Richard M. Stallman <rms@gnu.org>
parents:
6109
diff
changeset
|
238 end = buffer + linebuffer->size; |
18 | 239 linebuffer->buffer = buffer; |
240 } | |
241 if (c < 0 || c == '\n') | |
242 { | |
243 *p = 0; | |
244 break; | |
245 } | |
246 *p++ = c; | |
247 } | |
248 | |
249 return p - buffer; | |
250 } | |
251 | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
252 /* Extract a colon-terminated keyword from the string FIELD. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
253 Return that keyword as a string stored in a static buffer. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
254 Store the address of the rest of the string into *REST. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
255 |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
256 If there is no keyword, return NULL and don't alter *REST. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
257 |
18 | 258 char * |
259 get_keyword (field, rest) | |
260 register char *field; | |
261 char **rest; | |
262 { | |
263 static char keyword[KEYWORD_SIZE]; | |
264 register char *ptr; | |
34609
cb2667416fa5
(get_keyword): Make sure that isspace and
Gerd Moellmann <gerd@gnu.org>
parents:
26083
diff
changeset
|
265 register int c; |
18 | 266 |
267 ptr = &keyword[0]; | |
34609
cb2667416fa5
(get_keyword): Make sure that isspace and
Gerd Moellmann <gerd@gnu.org>
parents:
26083
diff
changeset
|
268 c = (unsigned char) *field++; |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
269 if (isspace (c) || c == ':') |
18 | 270 return ((char *) NULL); |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
271 *ptr++ = (islower (c) ? toupper (c) : c); |
34609
cb2667416fa5
(get_keyword): Make sure that isspace and
Gerd Moellmann <gerd@gnu.org>
parents:
26083
diff
changeset
|
272 while (((c = (unsigned char) *field++) != ':') && ! isspace (c)) |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
273 *ptr++ = (islower (c) ? toupper (c) : c); |
18 | 274 *ptr++ = '\0'; |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
275 while (isspace (c)) |
34609
cb2667416fa5
(get_keyword): Make sure that isspace and
Gerd Moellmann <gerd@gnu.org>
parents:
26083
diff
changeset
|
276 c = (unsigned char) *field++; |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
277 if (c != ':') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
278 return ((char *) NULL); |
18 | 279 *rest = field; |
280 return &keyword[0]; | |
281 } | |
282 | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
283 /* Nonzero if the string FIELD starts with a colon-terminated keyword. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
284 |
18 | 285 boolean |
286 has_keyword (field) | |
287 char *field; | |
288 { | |
289 char *ignored; | |
290 return (get_keyword (field, &ignored) != ((char *) NULL)); | |
291 } | |
292 | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
293 /* Store the string FIELD, followed by any lines in THE_LIST, |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
294 into the buffer WHERE. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
295 Concatenate lines, putting just a space between them. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
296 Delete everything contained in parentheses. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
297 When a recipient name contains <...>, we discard |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
298 everything except what is inside the <...>. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
299 |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
300 We don't pay attention to overflowing WHERE; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
301 the caller has to make it big enough. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
302 |
18 | 303 char * |
304 add_field (the_list, field, where) | |
305 line_list the_list; | |
306 register char *field, *where; | |
307 { | |
308 register char c; | |
309 while (true) | |
310 { | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
311 char *this_recipient_where; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
312 int in_quotes = 0; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
313 |
18 | 314 *where++ = ' '; |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
315 this_recipient_where = where; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
316 |
18 | 317 while ((c = *field++) != '\0') |
318 { | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
319 if (c == '\\') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
320 *where++ = c; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
321 else if (c == '"') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
322 { |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
323 in_quotes = ! in_quotes; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
324 *where++ = c; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
325 } |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
326 else if (in_quotes) |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
327 *where++ = c; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
328 else if (c == '(') |
18 | 329 { |
330 while (*field && *field != ')') ++field; | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
331 if (! (*field++)) break; /* no close */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
332 continue; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
333 } |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
334 else if (c == ',') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
335 { |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
336 *where++ = ' '; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
337 /* When we get to the end of one recipient, |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
338 don't discard it if the next one has <...>. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
339 this_recipient_where = where; |
18 | 340 } |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
341 else if (c == '<') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
342 /* Discard everything we got before the `<'. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
343 where = this_recipient_where; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
344 else if (c == '>') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
345 /* Discard the rest of this name that follows the `>'. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
346 { |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
347 while (*field && *field != ',') ++field; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
348 if (! (*field++)) break; /* no comma */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
349 continue; |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
350 } |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
351 else |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
352 *where++ = c; |
18 | 353 } |
354 if (the_list == NIL) break; | |
355 field = the_list->string; | |
356 the_list = the_list->continuation; | |
357 } | |
358 return where; | |
359 } | |
360 | |
361 line_list | |
362 make_file_preface () | |
363 { | |
364 char *the_string, *temp; | |
365 long idiotic_interface; | |
69697
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
366 struct tm *tm; |
18 | 367 long prefix_length; |
368 long user_length; | |
369 long date_length; | |
370 line_list result; | |
371 | |
372 prefix_length = strlen (FROM_PREFIX); | |
373 time (&idiotic_interface); | |
69697
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
374 /* Convert to a string, checking for out-of-range time stamps. |
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
375 Don't use 'ctime', as that might dump core if the hardware clock |
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
376 is set to a bizarre value. */ |
e112ec9aa49b
* b2m.c: Include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
68647
diff
changeset
|
377 tm = localtime (&idiotic_interface); |
69790
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
378 if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year) |
1e68e7f3b824
* lib-src/b2m.c (main): Don't include <limits.h>.
Paul Eggert <eggert@twinsun.com>
parents:
69697
diff
changeset
|
379 && (the_date = asctime (tm)))) |
72034
ca1a855f01ae
(fatal): Drop second parameter and treat first
Andreas Schwab <schwab@suse.de>
parents:
70278
diff
changeset
|
380 fatal ("current time is out of range"); |
18 | 381 /* the_date has an unwanted newline at the end */ |
382 date_length = strlen (the_date) - 1; | |
383 the_date[date_length] = '\0'; | |
384 temp = cuserid ((char *) NULL); | |
385 user_length = strlen (temp); | |
386 the_user = alloc_string (user_length + 1); | |
387 strcpy (the_user, temp); | |
18841
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
388 the_string = alloc_string (3 + prefix_length |
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
389 + user_length |
36704f455f32
[HAVE_UNISTD_H]: Include unistd.h.
Richard M. Stallman <rms@gnu.org>
parents:
16218
diff
changeset
|
390 + date_length); |
18 | 391 temp = the_string; |
392 strcpy (temp, FROM_PREFIX); | |
393 temp = &temp[prefix_length]; | |
394 *temp++ = ' '; | |
395 strcpy (temp, the_user); | |
396 temp = &temp[user_length]; | |
397 *temp++ = ' '; | |
398 strcpy (temp, the_date); | |
399 result = new_list (); | |
400 result->string = the_string; | |
401 result->continuation = ((line_list) NULL); | |
402 return result; | |
403 } | |
404 | |
405 void | |
406 write_line_list (the_list, the_stream) | |
407 register line_list the_list; | |
408 FILE *the_stream; | |
409 { | |
410 for ( ; | |
411 the_list != ((line_list) NULL) ; | |
412 the_list = the_list->continuation) | |
413 { | |
414 fputs (the_list->string, the_stream); | |
415 putc ('\n', the_stream); | |
416 } | |
417 return; | |
418 } | |
419 | |
420 int | |
421 close_the_streams () | |
422 { | |
423 register stream_list rem; | |
424 for (rem = the_streams; | |
425 rem != ((stream_list) NULL); | |
426 rem = rem->rest_streams) | |
427 no_problems = (no_problems && | |
428 ((*rem->action) (rem->handle) == 0)); | |
429 the_streams = ((stream_list) NULL); | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
430 return (no_problems ? EXIT_SUCCESS : EXIT_FAILURE); |
18 | 431 } |
432 | |
433 void | |
434 add_a_stream (the_stream, closing_action) | |
435 FILE *the_stream; | |
436 int (*closing_action)(); | |
437 { | |
438 stream_list old = the_streams; | |
439 the_streams = new_stream (); | |
440 the_streams->handle = the_stream; | |
441 the_streams->action = closing_action; | |
442 the_streams->rest_streams = old; | |
443 return; | |
444 } | |
445 | |
446 int | |
447 my_fclose (the_file) | |
448 FILE *the_file; | |
449 { | |
450 putc ('\n', the_file); | |
451 fflush (the_file); | |
452 return fclose (the_file); | |
453 } | |
454 | |
455 boolean | |
456 open_a_file (name) | |
457 char *name; | |
458 { | |
459 FILE *the_stream = fopen (name, "a"); | |
460 if (the_stream != ((FILE *) NULL)) | |
461 { | |
462 add_a_stream (the_stream, my_fclose); | |
463 if (the_user == ((char *) NULL)) | |
464 file_preface = make_file_preface (); | |
465 write_line_list (file_preface, the_stream); | |
466 return true; | |
467 } | |
468 return false; | |
469 } | |
470 | |
471 void | |
472 put_string (s) | |
473 char *s; | |
474 { | |
475 register stream_list rem; | |
476 for (rem = the_streams; | |
477 rem != ((stream_list) NULL); | |
478 rem = rem->rest_streams) | |
479 fputs (s, rem->handle); | |
480 return; | |
481 } | |
482 | |
483 void | |
20 | 484 put_line (string) |
485 char *string; | |
18 | 486 { |
487 register stream_list rem; | |
488 for (rem = the_streams; | |
489 rem != ((stream_list) NULL); | |
490 rem = rem->rest_streams) | |
491 { | |
20 | 492 char *s = string; |
493 int column = 0; | |
494 | |
495 /* Divide STRING into lines. */ | |
496 while (*s != 0) | |
497 { | |
498 char *breakpos; | |
499 | |
5959
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
500 /* Find the last char that fits. */ |
20 | 501 for (breakpos = s; *breakpos && column < 78; ++breakpos) |
502 { | |
503 if (*breakpos == '\t') | |
504 column += 8; | |
505 else | |
506 column++; | |
507 } | |
5959
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
508 /* If we didn't reach end of line, break the line. */ |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
509 if (*breakpos) |
20 | 510 { |
5959
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
511 /* Back up to just after the last comma that fits. */ |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
512 while (breakpos != s && breakpos[-1] != ',') --breakpos; |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
513 |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
514 if (breakpos == s) |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
515 { |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
516 /* If no comma fits, move past the first address anyway. */ |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
517 while (*breakpos != 0 && *breakpos != ',') ++breakpos; |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
518 if (*breakpos != 0) |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
519 /* Include the comma after it. */ |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
520 ++breakpos; |
e4337a7bbe32
(put_line): Don't break the line if it all fits.
Richard M. Stallman <rms@gnu.org>
parents:
5447
diff
changeset
|
521 } |
20 | 522 } |
523 /* Output that much, then break the line. */ | |
524 fwrite (s, 1, breakpos - s, rem->handle); | |
525 column = 8; | |
526 | |
527 /* Skip whitespace and prepare to print more addresses. */ | |
528 s = breakpos; | |
529 while (*s == ' ' || *s == '\t') ++s; | |
3219
1aa8fa0a569e
(put_line): Don't output \n\t unless more text follows.
Richard M. Stallman <rms@gnu.org>
parents:
37
diff
changeset
|
530 if (*s != 0) |
1aa8fa0a569e
(put_line): Don't output \n\t unless more text follows.
Richard M. Stallman <rms@gnu.org>
parents:
37
diff
changeset
|
531 fputs ("\n\t", rem->handle); |
20 | 532 } |
18 | 533 putc ('\n', rem->handle); |
534 } | |
535 return; | |
536 } | |
537 | |
538 #define mail_error error | |
539 | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
540 /* Handle an FCC field. FIELD is the text of the first line (after |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
541 the header name), and THE_LIST holds the continuation lines if any. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
542 Call open_a_file for each file. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
543 |
18 | 544 void |
545 setup_files (the_list, field) | |
546 register line_list the_list; | |
547 register char *field; | |
548 { | |
549 register char *start; | |
550 register char c; | |
551 while (true) | |
552 { | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
553 while (((c = *field) != '\0') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
554 && (c == ' ' |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
555 || c == '\t' |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
556 || c == ',')) |
18 | 557 field += 1; |
558 if (c != '\0') | |
559 { | |
560 start = field; | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
561 while (((c = *field) != '\0') |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
562 && c != ' ' |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
563 && c != '\t' |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
564 && c != ',') |
18 | 565 field += 1; |
566 *field = '\0'; | |
567 if (!open_a_file (start)) | |
568 mail_error ("Could not open file %s", start); | |
569 *field = c; | |
570 if (c != '\0') continue; | |
571 } | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
572 if (the_list == ((line_list) NULL)) |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
573 return; |
18 | 574 field = the_list->string; |
575 the_list = the_list->continuation; | |
576 } | |
577 } | |
578 | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
579 /* Compute the total size of all recipient names stored in THE_HEADER. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
580 The result says how big to make the buffer to pass to parse_header. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
581 |
18 | 582 int |
583 args_size (the_header) | |
584 header the_header; | |
585 { | |
586 register header old = the_header; | |
587 register line_list rem; | |
588 register int size = 0; | |
589 do | |
590 { | |
591 char *field; | |
592 register char *keyword = get_keyword (the_header->text->string, &field); | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
593 if ((strcmp (keyword, "TO") == 0) |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
594 || (strcmp (keyword, "CC") == 0) |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
595 || (strcmp (keyword, "BCC") == 0)) |
18 | 596 { |
597 size += 1 + strlen (field); | |
598 for (rem = the_header->text->continuation; | |
599 rem != NIL; | |
600 rem = rem->continuation) | |
601 size += 1 + strlen (rem->string); | |
602 } | |
603 the_header = the_header->next; | |
604 } while (the_header != old); | |
605 return size; | |
606 } | |
607 | |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
608 /* Scan the header described by the lists THE_HEADER, |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
609 and put all recipient names into the buffer WHERE. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
610 Precede each recipient name with a space. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
611 |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
612 Also, if the header has any FCC fields, call setup_files for each one. */ |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
613 |
21389
48690fd8d40a
(_XOPEN_SOURCE): Define for declaration of cuserid.
Andreas Schwab <schwab@suse.de>
parents:
18841
diff
changeset
|
614 void |
18 | 615 parse_header (the_header, where) |
616 header the_header; | |
617 register char *where; | |
618 { | |
619 register header old = the_header; | |
620 do | |
621 { | |
622 char *field; | |
623 register char *keyword = get_keyword (the_header->text->string, &field); | |
624 if (strcmp (keyword, "TO") == 0) | |
625 where = add_field (the_header->text->continuation, field, where); | |
626 else if (strcmp (keyword, "CC") == 0) | |
627 where = add_field (the_header->text->continuation, field, where); | |
628 else if (strcmp (keyword, "BCC") == 0) | |
629 { | |
630 where = add_field (the_header->text->continuation, field, where); | |
631 the_header->previous->next = the_header->next; | |
632 the_header->next->previous = the_header->previous; | |
633 } | |
634 else if (strcmp (keyword, "FCC") == 0) | |
635 setup_files (the_header->text->continuation, field); | |
636 the_header = the_header->next; | |
637 } while (the_header != old); | |
638 *where = '\0'; | |
639 return; | |
640 } | |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
641 |
10265
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
642 /* Read lines from the input until we get a blank line. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
643 Create a list of `header' objects, one for each header field, |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
644 each of which points to a list of `line_list' objects, |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
645 one for each line in that field. |
c53a70ec8d85
(xmalloc, xrealloc): Add casts.
Richard M. Stallman <rms@gnu.org>
parents:
9621
diff
changeset
|
646 Continuation lines are grouped in the headers they continue. */ |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
647 |
18 | 648 header |
649 read_header () | |
650 { | |
651 register header the_header = ((header) NULL); | |
652 register line_list *next_line = ((line_list *) NULL); | |
653 | |
654 init_linebuffer (&lb); | |
655 | |
656 do | |
657 { | |
658 long length; | |
659 register char *line; | |
660 | |
661 readline (&lb, stdin); | |
662 line = lb.buffer; | |
663 length = strlen (line); | |
664 if (length == 0) break; | |
665 | |
666 if (has_keyword (line)) | |
667 { | |
668 register header old = the_header; | |
669 the_header = new_header (); | |
670 if (old == ((header) NULL)) | |
671 { | |
672 the_header->next = the_header; | |
673 the_header->previous = the_header; | |
674 } | |
675 else | |
676 { | |
677 the_header->previous = old; | |
678 the_header->next = old->next; | |
679 old->next = the_header; | |
680 } | |
681 next_line = &(the_header->text); | |
682 } | |
683 | |
684 if (next_line == ((line_list *) NULL)) | |
685 { | |
686 /* Not a valid header */ | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
687 exit (EXIT_FAILURE); |
18 | 688 } |
689 *next_line = new_list (); | |
690 (*next_line)->string = alloc_string (length); | |
691 strcpy (((*next_line)->string), line); | |
692 next_line = &((*next_line)->continuation); | |
693 *next_line = NIL; | |
694 | |
695 } while (true); | |
696 | |
70278
8e7233f487a3
(read_header): Give fatal error if input has no header.
Richard M. Stallman <rms@gnu.org>
parents:
69790
diff
changeset
|
697 if (! the_header) |
8e7233f487a3
(read_header): Give fatal error if input has no header.
Richard M. Stallman <rms@gnu.org>
parents:
69790
diff
changeset
|
698 fatal ("input message has no header"); |
18 | 699 return the_header->next; |
700 } | |
701 | |
702 void | |
703 write_header (the_header) | |
704 header the_header; | |
705 { | |
706 register header old = the_header; | |
707 do | |
708 { | |
709 register line_list the_list; | |
710 for (the_list = the_header->text; | |
711 the_list != NIL; | |
712 the_list = the_list->continuation) | |
713 put_line (the_list->string); | |
714 the_header = the_header->next; | |
715 } while (the_header != old); | |
716 put_line (""); | |
717 return; | |
718 } | |
719 | |
15683 | 720 int |
18 | 721 main (argc, argv) |
722 int argc; | |
723 char **argv; | |
724 { | |
725 char *command_line; | |
726 header the_header; | |
727 long name_length; | |
728 char *mail_program_name; | |
729 char buf[BUFLEN + 1]; | |
730 register int size; | |
731 FILE *the_pipe; | |
732 | |
733 extern char *getenv (); | |
734 | |
735 mail_program_name = getenv ("FAKEMAILER"); | |
736 if (!(mail_program_name && *mail_program_name)) | |
737 mail_program_name = MAIL_PROGRAM_NAME; | |
738 name_length = strlen (mail_program_name); | |
739 | |
740 my_name = MY_NAME; | |
741 the_streams = ((stream_list) NULL); | |
742 the_date = ((char *) NULL); | |
743 the_user = ((char *) NULL); | |
744 | |
745 the_header = read_header (); | |
746 command_line = alloc_string (name_length + args_size (the_header)); | |
747 strcpy (command_line, mail_program_name); | |
748 parse_header (the_header, &command_line[name_length]); | |
42181
358035cb58d9
Conditionally include config.h.
Pavel Janík <Pavel@Janik.cz>
parents:
42134
diff
changeset
|
749 |
18 | 750 the_pipe = popen (command_line, "w"); |
751 if (the_pipe == ((FILE *) NULL)) | |
752 fatal ("cannot open pipe to real mailer"); | |
753 | |
754 add_a_stream (the_pipe, pclose); | |
755 | |
756 write_header (the_header); | |
757 | |
758 /* Dump the message itself */ | |
759 | |
760 while (!feof (stdin)) | |
761 { | |
762 size = fread (buf, 1, BUFLEN, stdin); | |
763 buf[size] = '\0'; | |
764 put_string (buf); | |
765 } | |
766 | |
767 exit (close_the_streams ()); | |
768 } | |
769 | |
5447
6f0905b05218
(main) [MSDOS]: Dummy stub just to make the file compile.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
770 #endif /* not MSDOS */ |
18 | 771 #endif /* not BSD 4.2 (or newer) */ |
52401 | 772 |
773 /* arch-tag: acb0afa6-315a-4c5b-b9e3-def5725c8783 | |
774 (do not change this comment) */ | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
775 |
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
776 /* fakemail.c ends here */ |