]> diplodocus.org Git - nmh/blob - uip/forwsbr.c
decode_rfc2047(): Stop unused-variable warning if HAVE_ICONV false.
[nmh] / uip / forwsbr.c
1 /* forwsbr.c -- subroutine to build a draft from a component file
2 *
3 * This code is Copyright (c) 2012, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include "h/mh.h"
9 #include "sbr/fmt_new.h"
10 #include "sbr/dtime.h"
11 #include "sbr/m_getfld.h"
12 #include "sbr/getcpy.h"
13 #include "sbr/error.h"
14 #include <fcntl.h>
15 #include "h/fmt_scan.h"
16 #include "h/tws.h"
17 #include "h/utils.h"
18 #include "sbr/m_mktemp.h"
19 #include "forwsbr.h"
20
21 /*
22 * Take from replsbr.c - a buffer big enough to read in data header lines
23 * in reasonable chunks but not enough to slurp in the whole message
24 */
25
26 static char msgbuf[NMH_BUFSIZ];
27 #define COMPFREE(c) free(c->c_text)
28
29 /*
30 * A list of components we treat as addresses
31 */
32
33 static char *addrcomps[] = {
34 "from",
35 "sender",
36 "reply-to",
37 "to",
38 "cc",
39 "bcc",
40 "resent-from",
41 "resent-sender",
42 "resent-reply-to",
43 "resent-to",
44 "resent-cc",
45 "resent-bcc",
46 NULL
47 };
48
49 int
50 build_form (char *form, char *digest, int *dat, char *from, char *to,
51 char *cc, char *fcc, char *subject, char *inputfile)
52 {
53 int in;
54 int fmtsize, state;
55 int i;
56 char *nfs;
57 char tmpfil[BUFSIZ], name[NAMESZ], **ap;
58 charstring_t line;
59 FILE *tmp;
60 struct comp *cptr;
61 struct format *fmt;
62 char *cp = NULL;
63 m_getfld_state_t gstate;
64
65 /*
66 * Open the message we'll be scanning for components
67 */
68
69 if ((tmp = fopen(inputfile, "r")) == NULL)
70 adios (inputfile, "Unable to open");
71
72 /* Get new format string */
73 nfs = new_fs (form, NULL, NULL);
74 fmtsize = strlen (nfs) + 256;
75
76 /* Compile format string */
77 (void) fmt_compile (nfs, &fmt, 1);
78
79 /*
80 * Mark any components tagged as address components
81 */
82
83 for (ap = addrcomps; *ap; ap++) {
84 cptr = fmt_findcomp (*ap);
85 if (cptr)
86 cptr->c_type |= CT_ADDR;
87 }
88
89 /*
90 * Process our message and save all relevant components
91 *
92 * A lot of this is taken from replsbr.c; should we try to merge
93 * these routines?
94 */
95
96 gstate = m_getfld_state_init(tmp);
97 for (;;) {
98 int msg_count = sizeof msgbuf;
99 state = m_getfld2(&gstate, name, msgbuf, &msg_count);
100 switch (state) {
101 case FLD:
102 case FLDPLUS:
103 /*
104 * If we find a component that we're interested in, save
105 * a copy. We don't do all of that weird buffer switching
106 * that replout does.
107 */
108
109 i = fmt_addcomptext(name, msgbuf);
110 if (i != -1) {
111 while (state == FLDPLUS) {
112 msg_count = sizeof msgbuf;
113 state = m_getfld2(&gstate, name, msgbuf, &msg_count);
114 fmt_appendcomp(i, name, msgbuf);
115 }
116 }
117 while (state == FLDPLUS) {
118 msg_count = sizeof msgbuf;
119 state = m_getfld2(&gstate, name, msgbuf, &msg_count);
120 }
121 break;
122
123 case LENERR:
124 case FMTERR:
125 case BODY:
126 case FILEEOF:
127 goto finished;
128
129 default:
130 die("m_getfld2() returned %d", state);
131 }
132 }
133
134 /*
135 * Override any components just in case they were included in the
136 * input message. Also include command-line components given here
137 *
138 * With the memory rework I've changed things so we always get copies
139 * of these strings; I don't like the idea that the caller of this
140 * function has to know to pass in already-allocated memory (and that
141 * it will be free()'d by us).
142 */
143
144 finished:
145 m_getfld_state_destroy (&gstate);
146
147 cptr = fmt_findcomp ("digest");
148 if (cptr) {
149 COMPFREE(cptr);
150 cptr->c_text = getcpy(digest);
151 }
152 cptr = fmt_findcomp ("nmh-date");
153 if (cptr) {
154 COMPFREE(cptr);
155 cptr->c_text = getcpy(dtimenow (0));
156 }
157 cptr = fmt_findcomp ("nmh-from");
158 if (cptr) {
159 COMPFREE(cptr);
160 cptr->c_text = getcpy(from);
161 }
162 cptr = fmt_findcomp ("nmh-to");
163 if (cptr) {
164 COMPFREE(cptr);
165 cptr->c_text = getcpy(to);
166 }
167 cptr = fmt_findcomp ("nmh-cc");
168 if (cptr) {
169 COMPFREE(cptr);
170 cptr->c_text = getcpy(cc);
171 }
172 cptr = fmt_findcomp ("nmh-subject");
173 if (cptr) {
174 COMPFREE(cptr);
175 cptr->c_text = getcpy(subject);
176 }
177 cptr = fmt_findcomp ("fcc");
178 if (cptr) {
179 COMPFREE(cptr);
180 cptr->c_text = getcpy(fcc);
181 }
182
183 cp = m_mktemp2(NULL, invo_name, NULL, &tmp);
184 if (cp == NULL) {
185 die("unable to create temporary file in %s", get_temp_dir());
186 }
187 strncpy (tmpfil, cp, sizeof(tmpfil));
188 (void) m_unlink (tmpfil);
189 if ((in = dup (fileno (tmp))) == NOTOK)
190 adios ("dup", "unable to");
191
192 line = charstring_create (fmtsize);
193 fmt_scan (fmt, line, fmtsize, dat, NULL);
194 fputs (charstring_buffer (line), tmp);
195 charstring_free (line);
196 if (fclose (tmp))
197 adios (tmpfil, "error writing");
198
199 lseek(in, 0, SEEK_SET);
200
201 /*
202 * Free any component buffers that we allocated
203 */
204
205 fmt_free(fmt, 1);
206
207 return in;
208 }