1 /*
2 * TEMPLATE.C
3 *
4 * Written on 10-Jul-94 by John Dennis and released to the public domain.
5 *
6 * Handles the creation of messages from a template.
7 */
8
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <time.h>
12 #include <string.h>
13 #include "addr.h"
14 #include "nedit.h"
15 #include "msged.h"
16 #include "quote.h"
17 #include "date.h"
18 #include "memextra.h"
19 #include "readmail.h" /* GetOrigin */
20 #include "template.h"
21 #include "version.h"
22
23 #if defined(UNIX)
24 #include <sys/utsname.h>
25 #define HAVE_UNAME
26 #endif
27
28
29 #define TEXTLEN 250
30
31 static LINE* addline(LINE* ln, char *l);
32
parse_words_to_array(char * string,int nmembers)33 static char **parse_words_to_array(char *string, int nmembers)
34 {
35 char *cp = strtok(string, " \t\r\n");
36 int n=0;
37 char **whereto = xmalloc(nmembers * sizeof(char **));
38
39 while (cp != NULL && n < nmembers )
40 {
41 whereto[n++] = cp;
42 cp = strtok(NULL, " \t\r\n");
43 }
44
45 if (n < nmembers)
46 {
47 free(whereto);
48 return NULL;
49 }
50 if (cp != NULL)
51 {
52 return whereto;
53 }
54 return whereto;
55 }
56
make_tearline(char * buf)57 void make_tearline(char *buf)
58 {
59 /* add the tearline */
60
61 if (SW->usepid)
62 {
63 sprintf(buf, "---");
64 }
65 else
66 #ifdef HAVE_UNAME
67 if (SW->xxltearline)
68 {
69 struct utsname uts;
70 uname(&uts);
71
72 sprintf(buf, "--- %s %s (%s/%s (%s))", PROG, VERNUM VERPATCH,
73 uts.sysname, uts.release, uts.machine);
74 }
75 else
76 #endif
77 {
78 sprintf(buf, "--- %s %s", PROG, VERNUM VERPATCH);
79 }
80 }
81
82
MakeTemplateMsg(msg * m,msg * oldmsg,int olda,int type)83 int MakeTemplateMsg(msg * m, msg * oldmsg, int olda, int type)
84 {
85 LINE *ln = NULL;
86 FILE *fp = NULL;
87 char buf[TEXTLEN], buf2[TEXTLEN];
88 char *wdaybuf=NULL, *monthbuf=NULL;
89 char **use_month = NULL;
90 char **use_day = NULL;
91 char *l;
92 int blankline;
93
94 if (ST->template)
95 {
96 fp = fopen(ST->template, "r");
97 }
98
99 if (!ST->template || fp == NULL)
100 {
101 if (m->text && (type & MT_QUO))
102 {
103 ln = m->text;
104 makequote(ln, oldmsg != NULL ? oldmsg->isfrom : m->isfrom);
105 }
106 return 0;
107 }
108
109 while (fgets(buf, TEXTLEN - 1, fp))
110 {
111 if (buf[0] == ';')
112 {
113 continue;
114 }
115
116 if (buf[0] == '@' && buf[1] && buf[1] != '@')
117 {
118 switch (tolower(buf[1]))
119 {
120 case 'w':
121 release(wdaybuf);
122 wdaybuf = xstrdup(buf+2);
123 use_day = parse_words_to_array(wdaybuf, 7);
124 continue;
125
126 case 'o':
127 release(monthbuf);
128 monthbuf = xstrdup(buf+2);
129 use_month = parse_words_to_array(monthbuf, 12);
130 continue;
131
132 case 'f':
133 if (!(type & MT_FOR))
134 {
135 continue;
136 }
137 break;
138
139 case 'l':
140 if (!(type & MT_FOL))
141 {
142 continue;
143 }
144 break;
145
146 case 'r':
147 if (!(type & MT_RED))
148 {
149 continue;
150 }
151 break;
152
153 case 'a':
154 if (!(type & MT_ARC))
155 {
156 continue;
157 }
158 break;
159
160 case 'q':
161 if (!(type & MT_QUO))
162 {
163 continue;
164 }
165 break;
166
167 case 'n':
168 if (!(type & MT_NEW))
169 {
170 continue;
171 }
172 break;
173
174 case 'm':
175 if (ln)
176 {
177 /* assign msg to follow */
178 ln->next = m->text;
179 if (ln->next)
180 {
181 ln->next->prev = ln;
182 ln = ln->next;
183 }
184 }
185 else
186 {
187 ln = m->text;
188 }
189 if (!(type & MT_QUO))
190 {
191 /* don't want a quote */
192 while (ln != NULL && ln->next != NULL)
193 {
194 ln = ln->next;
195 }
196 }
197 else
198 {
199 /* we do want a quote */
200 makequote(ln, oldmsg != NULL ? oldmsg->isfrom : m->isfrom);
201
202 /* just in case we didn't get the beginning */
203 ln = m->text;
204 while (ln != NULL && ln->next != NULL)
205 {
206 ln = ln->next;
207 }
208 }
209 continue;
210
211 default:
212 /* break on things we don't know */
213 break;
214 }
215
216 if (buf[2])
217 {
218 /* could be a blank line... */
219 l = attrib_line(m, oldmsg, olda, buf + 2, use_day, use_month);
220 }
221 else
222 {
223 l = xstrdup("\n");
224 }
225 }
226 else
227 {
228 l = attrib_line(m, oldmsg, olda, buf, use_day, use_month);
229 }
230
231 ln = addline(ln, l);
232
233 }
234
235 fclose(fp);
236
237 /* add tearline and origin if appropriate and wished */
238
239 if (CurArea.echomail && !(type & MT_RED))
240 {
241 if (ln != NULL)
242 {
243 blankline = ( *(ln->text) == '\n');
244 }
245 else
246 {
247 blankline = 0;
248 }
249
250 if (!(type & MT_FOR))
251 {
252 if (SW->usetearlines && SW->useoriginlines && !blankline &&
253 (SW->edittearlines || SW->editoriginlines))
254 {
255 strcpy(buf, "\n");
256 ln = addline(ln, xstrdup(buf));
257 }
258
259 if (SW->usetearlines && SW->edittearlines)
260 {
261 make_tearline(buf);
262 strcat(buf, "\n");
263 ln = addline(ln, xstrdup(buf));
264 }
265
266 if (SW->useoriginlines && SW->editoriginlines)
267 {
268 /* add the origin line */
269
270 GetOrigin(buf2);
271 sprintf(buf, " * Origin: %s (%s)\n", buf2,
272 SW->domainorigin ? show_address(&(m->from)) :
273 show_4d(&(m->from)));
274
275 ln = addline(ln, xstrdup(buf));
276 }
277 }
278 }
279
280
281 /* we've finished; assign it to the beginning of the msg */
282
283 if (m->text == NULL && ln != NULL)
284 {
285 /* find beginning of msg and assign it */
286
287 while (ln->prev)
288 {
289 ln = ln->prev;
290 }
291 m->text = ln;
292 }
293
294 ln = m->text;
295 while (ln && ln->prev)
296 {
297 ln = ln->prev;
298 }
299 m->text = ln;
300
301 release(monthbuf); release(wdaybuf);
302 release(use_month); release(use_day);
303
304 return 0;
305 }
306
addline(LINE * ln,char * l)307 static LINE* addline(LINE* ln, char *l)
308 {
309 LINE *n;
310
311 n = xcalloc(1, sizeof *n);
312
313 n->templt = 1; /* mark as a template line */
314
315 if (ln)
316 {
317 n->next = ln->next;
318 }
319
320 n->prev = ln;
321
322 if (ln)
323 {
324 ln->next = n;
325 }
326
327 if (n->next)
328 {
329 n->next->prev = n;
330 }
331
332 n->text = l;
333 ln = n;
334
335 return ln;
336 }
337
338