]> diplodocus.org Git - nmh/blob - uip/distsbr.c
sbr/dtime.c: Remove struct-assigning twscopy().
[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[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[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), hdrfd = NOTOK;
134 if (txtfd != NOTOK)
135 close (txtfd), txtfd = NOTOK;
136
137 if ((ifp = fopen (msgnam, "r")) == NULL)
138 adios (msgnam, "unable to open message");
139
140 cp = m_mktemp2(NULL, "dist", &hdrfd, NULL);
141 if (cp == NULL) {
142 adios(NULL, "unable to create temporary file in %s", get_temp_dir());
143 }
144 strncpy(tmpfil, cp, sizeof(tmpfil));
145 if ((out = dup (hdrfd)) == NOTOK
146 || (ofp = fdopen (out, "w")) == NULL)
147 adios (NULL, "no file descriptors -- you lose big");
148 (void) m_unlink (tmpfil);
149
150 for (;;) {
151 int buffersz = sizeof buffer;
152 switch (state = m_getfld (&gstate, name, buffer, &buffersz, ifp)) {
153 case FLD:
154 case FLDPLUS:
155 if (uprf (name, "resent"))
156 fprintf (ofp, "Prev-");
157 fprintf (ofp, "%s: %s", name, buffer);
158 while (state == FLDPLUS) {
159 buffersz = sizeof buffer;
160 state = m_getfld (&gstate, name, buffer, &buffersz, ifp);
161 fputs (buffer, ofp);
162 }
163 break;
164
165 case BODY:
166 fclose (ofp);
167
168 cp = m_mktemp2(NULL, "dist", &txtfd, NULL);
169 if (cp == NULL) {
170 adios(NULL, "unable to create temporary file in %s",
171 get_temp_dir());
172 }
173 fchmod(txtfd, 0600);
174 strncpy (tmpfil, cp, sizeof(tmpfil));
175 if ((out = dup (txtfd)) == NOTOK
176 || (ofp = fdopen (out, "w")) == NULL)
177 adios (NULL, "no file descriptors -- you lose big");
178 (void) m_unlink (tmpfil);
179 fprintf (ofp, "\n%s", buffer);
180 while (state == BODY) {
181 buffersz = sizeof buffer;
182 state = m_getfld (&gstate, name, buffer, &buffersz, ifp);
183 fputs (buffer, ofp);
184 }
185 case FILEEOF:
186 goto process;
187
188 case LENERR:
189 case FMTERR:
190 adios (NULL, "format error in message %s", msgnam);
191
192 default:
193 adios (NULL, "getfld() returned %d", state);
194 }
195 }
196 process: ;
197 m_getfld_state_destroy (&gstate);
198 fclose (ifp);
199 fclose (ofp);
200 }