]> diplodocus.org Git - nmh/blob - uip/distsbr.c
getpass.c: Move interface to own file.
[nmh] / uip / distsbr.c
1 /* distsbr.c -- routines to do additional "dist-style" processing
2 *
3 * This code is Copyright (c) 2002, 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/cpydata.h"
10 #include "sbr/uprf.h"
11 #include "sbr/m_backup.h"
12 #include "sbr/error.h"
13 #include <fcntl.h>
14 #include "h/utils.h"
15 #include "sbr/m_mktemp.h"
16
17 static int hdrfd = NOTOK;
18 static int txtfd = NOTOK;
19
20 #define BADHDR "please re-edit %s to remove the ``%s'' header!"
21 #define BADTXT "please re-edit %s to consist of headers only!"
22 #define BADMSG "please re-edit %s to include a ``Resent-To:''!"
23 #define BADRFT "please re-edit %s and fix that header!"
24
25 /*
26 * static prototypes
27 */
28 static void ready_msg(char *);
29
30 int
31 distout (char *drft, char *msgnam, char *backup)
32 {
33 int state;
34 char *dp, *resent;
35 char name[NAMESZ], buffer[NMH_BUFSIZ];
36 FILE *ifp, *ofp;
37 m_getfld_state_t gstate;
38
39 if (rename (drft, strcpy (backup, m_backup (drft))) == NOTOK)
40 adios (backup, "unable to rename %s to",drft);
41 if ((ifp = fopen (backup, "r")) == NULL)
42 adios (backup, "unable to read");
43
44 if ((ofp = fopen (drft, "w")) == NULL)
45 adios (drft, "unable to create temporary file");
46 chmod (drft, m_gmprot ());
47
48 ready_msg (msgnam);
49 lseek(hdrfd, 0, SEEK_SET); /* msgnam not accurate */
50 cpydata (hdrfd, fileno (ofp), msgnam, drft);
51
52 gstate = m_getfld_state_init(ifp);
53 for (resent = NULL;;) {
54 int buffersz = sizeof buffer;
55 switch (state = m_getfld2(&gstate, name, buffer, &buffersz)) {
56 case FLD:
57 case FLDPLUS:
58 if (uprf (name, "distribute-"))
59 snprintf (name, sizeof(name), "%s%s", "Resent", &name[10]);
60 if (uprf (name, "distribution-"))
61 snprintf (name, sizeof(name), "%s%s", "Resent", &name[12]);
62 if (!uprf (name, "resent")) {
63 inform(BADHDR, "draft", name);
64 goto leave_bad;
65 }
66 if (state == FLD)
67 resent = add (":", add (name, resent));
68 resent = add (buffer, resent);
69 fprintf (ofp, "%s: %s", name, buffer);
70 while (state == FLDPLUS) {
71 buffersz = sizeof buffer;
72 state = m_getfld2(&gstate, name, buffer, &buffersz);
73 resent = add (buffer, resent);
74 fputs (buffer, ofp);
75 }
76 break;
77
78 case BODY:
79 for (dp = buffer; *dp; dp++)
80 if (!isspace ((unsigned char) *dp)) {
81 inform(BADTXT, "draft");
82 goto leave_bad;
83 }
84
85 case FILEEOF:
86 goto process;
87
88 case LENERR:
89 case FMTERR:
90 inform(BADRFT, "draft");
91 leave_bad: ;
92 fclose (ifp);
93 fclose (ofp);
94 (void) m_unlink (drft);
95 if (rename (backup, drft) == NOTOK)
96 adios (drft, "unable to rename %s to", backup);
97 return NOTOK;
98
99 default:
100 die("getfld() returned %d", state);
101 }
102 }
103 process: ;
104 m_getfld_state_destroy (&gstate);
105 fclose (ifp);
106 fflush (ofp);
107
108 if (!resent) {
109 inform(BADMSG, "draft");
110 fclose (ofp);
111 (void) m_unlink (drft);
112 if (rename (backup, drft) == NOTOK)
113 adios (drft, "unable to rename %s to", backup);
114 return NOTOK;
115 }
116 free (resent);
117
118 if (txtfd != NOTOK) {
119 lseek(txtfd, 0, SEEK_SET); /* msgnam not accurate */
120 cpydata (txtfd, fileno (ofp), msgnam, drft);
121 }
122
123 fclose (ofp);
124
125 return OK;
126 }
127
128
129 static void
130 ready_msg (char *msgnam)
131 {
132 int state, out;
133 char name[NAMESZ], buffer[NMH_BUFSIZ], tmpfil[BUFSIZ];
134 FILE *ifp, *ofp;
135 char *cp = NULL;
136 m_getfld_state_t gstate;
137
138 if (hdrfd != NOTOK) {
139 close (hdrfd);
140 hdrfd = NOTOK;
141 }
142 if (txtfd != NOTOK) {
143 close (txtfd);
144 txtfd = NOTOK;
145 }
146
147 if ((ifp = fopen (msgnam, "r")) == NULL)
148 adios (msgnam, "unable to open message");
149
150 cp = m_mktemp2(NULL, "dist", &hdrfd, NULL);
151 if (cp == NULL) {
152 die("unable to create temporary file in %s", get_temp_dir());
153 }
154 strncpy(tmpfil, cp, sizeof(tmpfil));
155 if ((out = dup (hdrfd)) == NOTOK
156 || (ofp = fdopen (out, "w")) == NULL)
157 die("no file descriptors -- you lose big");
158 (void) m_unlink (tmpfil);
159
160 gstate = m_getfld_state_init(ifp);
161 for (;;) {
162 int buffersz = sizeof buffer;
163 switch (state = m_getfld2(&gstate, name, buffer, &buffersz)) {
164 case FLD:
165 case FLDPLUS:
166 if (uprf (name, "resent"))
167 fprintf (ofp, "Prev-");
168 fprintf (ofp, "%s: %s", name, buffer);
169 while (state == FLDPLUS) {
170 buffersz = sizeof buffer;
171 state = m_getfld2(&gstate, name, buffer, &buffersz);
172 fputs (buffer, ofp);
173 }
174 break;
175
176 case BODY:
177 fclose (ofp);
178
179 cp = m_mktemp2(NULL, "dist", &txtfd, NULL);
180 if (cp == NULL) {
181 die("unable to create temporary file in %s",
182 get_temp_dir());
183 }
184 fchmod(txtfd, 0600);
185 strncpy (tmpfil, cp, sizeof(tmpfil));
186 if ((out = dup (txtfd)) == NOTOK
187 || (ofp = fdopen (out, "w")) == NULL)
188 die("no file descriptors -- you lose big");
189 (void) m_unlink (tmpfil);
190 fprintf (ofp, "\n%s", buffer);
191 while (state == BODY) {
192 buffersz = sizeof buffer;
193 state = m_getfld2(&gstate, name, buffer, &buffersz);
194 fputs (buffer, ofp);
195 }
196 case FILEEOF:
197 goto process;
198
199 case LENERR:
200 case FMTERR:
201 die("format error in message %s", msgnam);
202
203 default:
204 die("getfld() returned %d", state);
205 }
206 }
207 process: ;
208 m_getfld_state_destroy (&gstate);
209 fclose (ifp);
210 fclose (ofp);
211 }