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