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