Mercurial > hg > xemacs-beta
comparison lib-src/b2m.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 84b14dcb0985 |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* | |
2 * b2m - a filter for Babyl -> Unix mail files | |
3 * | |
4 * usage: b2m < babyl > mailbox | |
5 * | |
6 * I find this useful whenever I have to use a | |
7 * system which - shock horror! - doesn't run | |
8 * Gnu emacs. At least now I can read all my | |
9 * Gnumacs Babyl format mail files! | |
10 * | |
11 * it's not much but it's free! | |
12 * | |
13 * Ed Wilkinson | |
14 * E.Wilkinson@massey.ac.nz | |
15 * Mon Nov 7 15:54:06 PDT 1988 | |
16 */ | |
17 | |
18 /* Made conformant to the GNU coding standards January, 1995 | |
19 by Francesco Potorti` <pot@cnuce.cnr.it>. */ | |
20 | |
21 #ifdef HAVE_CONFIG_H | |
22 #include <../src/config.h> | |
23 /* On some systems, Emacs defines static as nothing for the sake | |
24 of unexec. We don't want that here since we don't use unexec. */ | |
25 #undef static | |
26 #endif | |
27 | |
28 #include <stdio.h> | |
29 #include <stdlib.h> | |
30 #include <string.h> | |
31 #include <time.h> | |
32 #include <sys/types.h> | |
33 #ifdef MSDOS | |
34 #include <fcntl.h> | |
35 #endif | |
36 | |
37 #undef TRUE | |
38 #define TRUE 1 | |
39 #undef FALSE | |
40 #define FALSE 0 | |
41 | |
42 /* Exit codes for success and failure. */ | |
43 #ifdef VMS | |
44 #define GOOD 1 | |
45 #define BAD 0 | |
46 #else | |
47 #define GOOD 0 | |
48 #define BAD 1 | |
49 #endif | |
50 | |
51 #define streq(s,t) (strcmp (s, t) == 0) | |
52 #define strneq(s,t,n) (strncmp (s, t, n) == 0) | |
53 | |
54 typedef int logical; | |
55 | |
56 /* | |
57 * A `struct linebuffer' is a structure which holds a line of text. | |
58 * `readline' reads a line from a stream into a linebuffer and works | |
59 * regardless of the length of the line. | |
60 */ | |
61 struct linebuffer | |
62 { | |
63 long size; | |
64 char *buffer; | |
65 }; | |
66 | |
67 | |
68 static long *xmalloc (unsigned int); | |
69 static long *xrealloc (void *, unsigned int); | |
70 static char *concat (char *s1, char *s2, char *s3); | |
71 static long readline (struct linebuffer *, FILE *); | |
72 static void fatal (char *); | |
73 | |
74 /* | |
75 * xnew -- allocate storage. SYNOPSIS: Type *xnew (int n, Type); | |
76 */ | |
77 #define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type))) | |
78 | |
79 | |
80 | |
81 char *progname; | |
82 | |
83 int | |
84 main (int argc, char *argv[]) | |
85 { | |
86 logical labels_saved, printing, header; | |
87 time_t ltoday; | |
88 char *labels = NULL, *p, *today; | |
89 struct linebuffer data; | |
90 | |
91 #ifdef MSDOS | |
92 _fmode = O_BINARY; /* all of files are treated as binary files */ | |
93 #if __DJGPP__ > 1 | |
94 if (!isatty (fileno (stdout))) | |
95 setmode (fileno (stdout), O_BINARY); | |
96 if (!isatty (fileno (stdin))) | |
97 setmode (fileno (stdin), O_BINARY); | |
98 #else /* not __DJGPP__ > 1 */ | |
99 (stdout)->_flag &= ~_IOTEXT; | |
100 (stdin)->_flag &= ~_IOTEXT; | |
101 #endif /* not __DJGPP__ > 1 */ | |
102 #endif | |
103 progname = argv[0]; | |
104 | |
105 if (argc != 1) | |
106 { | |
107 fprintf (stderr, "Usage: %s <babylmailbox >unixmailbox\n", progname); | |
108 exit (GOOD); | |
109 } | |
110 labels_saved = printing = header = FALSE; | |
111 ltoday = time (0); | |
112 today = ctime (<oday); | |
113 data.size = 200; | |
114 data.buffer = xnew (200, char); | |
115 | |
116 if (readline (&data, stdin) == 0 | |
117 || !strneq (data.buffer, "BABYL OPTIONS:", 14)) | |
118 fatal ("standard input is not a Babyl mailfile."); | |
119 | |
120 while (readline (&data, stdin) > 0) | |
121 { | |
122 if (streq (data.buffer, "*** EOOH ***") && !printing) | |
123 { | |
124 printing = header = TRUE; | |
125 printf ("From \"Babyl to mail by %s\" %s", progname, today); | |
126 continue; | |
127 } | |
128 | |
129 if (data.buffer[0] == '\037') | |
130 { | |
131 if (data.buffer[1] == '\0') | |
132 continue; | |
133 else if (data.buffer[1] == '\f') | |
134 { | |
135 /* Save labels. */ | |
136 readline (&data, stdin); | |
137 p = strtok (data.buffer, " ,\r\n\t"); | |
138 labels = "X-Babyl-Labels: "; | |
139 | |
140 while ((p = strtok (NULL, " ,\r\n\t"))) | |
141 labels = concat (labels, p, ", "); | |
142 | |
143 p = &labels[strlen (labels) - 2]; | |
144 if (*p == ',') | |
145 *p = '\0'; | |
146 printing = header = FALSE; | |
147 labels_saved = TRUE; | |
148 continue; | |
149 } | |
150 } | |
151 | |
152 if ((data.buffer[0] == '\0') && header) | |
153 { | |
154 header = FALSE; | |
155 if (labels_saved) | |
156 puts (labels); | |
157 } | |
158 | |
159 if (printing) | |
160 puts (data.buffer); | |
161 } | |
162 return 0; | |
163 } | |
164 | |
165 | |
166 | |
167 /* | |
168 * Return a newly-allocated string whose contents | |
169 * concatenate those of s1, s2, s3. | |
170 */ | |
171 static char * | |
172 concat (char *s1, char *s2, char *s3) | |
173 { | |
174 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); | |
175 char *result = xnew (len1 + len2 + len3 + 1, char); | |
176 | |
177 strcpy (result, s1); | |
178 strcpy (result + len1, s2); | |
179 strcpy (result + len1 + len2, s3); | |
180 result[len1 + len2 + len3] = '\0'; | |
181 | |
182 return result; | |
183 } | |
184 | |
185 /* | |
186 * Read a line of text from `stream' into `linebuffer'. | |
187 * Return the number of characters read from `stream', | |
188 * which is the length of the line including the newline, if any. | |
189 */ | |
190 static long | |
191 readline (struct linebuffer *linebuffer, FILE *stream) | |
192 { | |
193 char *buffer = linebuffer->buffer; | |
194 register char *p = linebuffer->buffer; | |
195 register char *pend; | |
196 int chars_deleted; | |
197 | |
198 pend = p + linebuffer->size; /* Separate to avoid 386/IX compiler bug. */ | |
199 | |
200 while (1) | |
201 { | |
202 register int c = getc (stream); | |
203 if (p == pend) | |
204 { | |
205 linebuffer->size *= 2; | |
206 buffer = (char *) xrealloc (buffer, linebuffer->size); | |
207 p += buffer - linebuffer->buffer; | |
208 pend = buffer + linebuffer->size; | |
209 linebuffer->buffer = buffer; | |
210 } | |
211 if (c == EOF) | |
212 { | |
213 chars_deleted = 0; | |
214 break; | |
215 } | |
216 if (c == '\n') | |
217 { | |
218 if (p[-1] == '\r' && p > buffer) | |
219 { | |
220 *--p = '\0'; | |
221 chars_deleted = 2; | |
222 } | |
223 else | |
224 { | |
225 *p = '\0'; | |
226 chars_deleted = 1; | |
227 } | |
228 break; | |
229 } | |
230 *p++ = c; | |
231 } | |
232 | |
233 return (p - buffer + chars_deleted); | |
234 } | |
235 | |
236 /* | |
237 * Like malloc but get fatal error if memory is exhausted. | |
238 */ | |
239 static long * | |
240 xmalloc (unsigned int size) | |
241 { | |
242 long *result = (long *) malloc (size); | |
243 if (result == NULL) | |
244 fatal ("virtual memory exhausted"); | |
245 return result; | |
246 } | |
247 | |
248 static long * | |
249 xrealloc (void *ptr, unsigned int size) | |
250 { | |
251 long *result = (long *) realloc (ptr, size); | |
252 if (result == NULL) | |
253 fatal ("virtual memory exhausted"); | |
254 return result; | |
255 } | |
256 | |
257 static void | |
258 fatal (char *message) | |
259 { | |
260 fprintf (stderr, "%s: %s\n", progname, message); | |
261 exit (BAD); | |
262 } | |
263 |