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