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