* uip/mhlistsbr.c, uip/mhlsbr.c, uip/picksbr.c: cast
[mmh] / uip / distsbr.c
1
2 /*
3  * distsbr.c -- routines to do additional "dist-style" processing
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13 #include <fcntl.h>
14 #include <h/utils.h>
15
16 static int  hdrfd = NOTOK;
17 static int  txtfd = NOTOK;
18
19 #define BADHDR  "please re-edit %s to remove the ``%s'' header!"
20 #define BADTXT  "please re-edit %s to consist of headers only!"
21 #define BADMSG  "please re-edit %s to include a ``Resent-To:''!"
22 #define BADRFT  "please re-edit %s and fix that header!"
23
24 /*
25  * static prototypes
26  */
27 static void ready_msg(char *);
28
29 int
30 distout (char *drft, char *msgnam, char *backup)
31 {
32     int state;
33     register unsigned char *dp;
34     register char *resent;
35     char name[NAMESZ], buffer[BUFSIZ];
36     register FILE *ifp, *ofp;
37
38     if (rename (drft, strcpy (backup, m_backup (drft))) == NOTOK)
39         adios (backup, "unable to rename %s to",drft);
40     if ((ifp = fopen (backup, "r")) == NULL)
41         adios (backup, "unable to read");
42
43     if ((ofp = fopen (drft, "w")) == NULL)
44         adios (drft, "unable to create temporary file");
45     chmod (drft, m_gmprot ());
46
47     ready_msg (msgnam);
48     lseek (hdrfd, (off_t) 0, SEEK_SET); /* msgnam not accurate */
49     cpydata (hdrfd, fileno (ofp), msgnam, drft);
50
51     for (state = FLD, resent = NULL;;)
52         switch (state =
53                 m_getfld (state, name, buffer, sizeof buffer, ifp)) {
54             case FLD: 
55             case FLDPLUS: 
56             case FLDEOF: 
57                 if (uprf (name, "distribute-"))
58                     snprintf (name, sizeof(name), "%s%s", "Resent", &name[10]);
59                 if (uprf (name, "distribution-"))
60                     snprintf (name, sizeof(name), "%s%s", "Resent", &name[12]);
61                 if (!uprf (name, "resent")) {
62                     advise (NULL, BADHDR, "draft", name);
63                     goto leave_bad;
64                 }
65                 if (state == FLD)
66                     resent = add (":", add (name, resent));
67                 resent = add (buffer, resent);
68                 fprintf (ofp, "%s: %s", name, buffer);
69                 while (state == FLDPLUS) {
70                     state = m_getfld (state, name,
71                             buffer, sizeof buffer, ifp);
72                     resent = add (buffer, resent);
73                     fputs (buffer, ofp);
74                 }
75                 if (state == FLDEOF)
76                     goto process;
77                 break;
78
79             case BODY: 
80             case BODYEOF: 
81                 for (dp = buffer; *dp; dp++)
82                     if (!isspace (*dp)) {
83                         advise (NULL, BADTXT, "draft");
84                         goto leave_bad;
85                     }
86
87             case FILEEOF: 
88                 goto process;
89
90             case LENERR: 
91             case FMTERR: 
92                 advise (NULL, BADRFT, "draft");
93         leave_bad: ;
94                 fclose (ifp);
95                 fclose (ofp);
96                 unlink (drft);
97                 if (rename (backup, drft) == NOTOK)
98                     adios (drft, "unable to rename %s to", backup);
99                 return NOTOK;
100
101             default: 
102                 adios (NULL, "getfld() returned %d", state);
103         }
104 process: ;
105     fclose (ifp);
106     fflush (ofp);
107
108     if (!resent) {
109         advise (NULL, BADMSG, "draft");
110         fclose (ofp);
111         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, (off_t) 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[BUFSIZ], tmpfil[BUFSIZ];
134     register FILE *ifp, *ofp;
135
136     if (hdrfd != NOTOK)
137         close (hdrfd), hdrfd = NOTOK;
138     if (txtfd != NOTOK)
139         close (txtfd), txtfd = NOTOK;
140
141     if ((ifp = fopen (msgnam, "r")) == NULL)
142         adios (msgnam, "unable to open message");
143
144     strncpy (tmpfil, m_tmpfil ("dist"), sizeof(tmpfil));
145     if ((hdrfd = open (tmpfil, O_RDWR | O_CREAT | O_TRUNC, 0600)) == NOTOK)
146         adios (tmpfil, "unable to re-open temporary file");
147     if ((out = dup (hdrfd)) == NOTOK
148             || (ofp = fdopen (out, "w")) == NULL)
149         adios (NULL, "no file descriptors -- you lose big");
150     unlink (tmpfil);
151
152     for (state = FLD;;)
153         switch (state =
154                 m_getfld (state, name, buffer, sizeof buffer, ifp)) {
155             case FLD: 
156             case FLDPLUS: 
157             case FLDEOF: 
158                 if (uprf (name, "resent"))
159                     fprintf (ofp, "Prev-");
160                 fprintf (ofp, "%s: %s", name, buffer);
161                 while (state == FLDPLUS) {
162                     state = m_getfld (state, name,
163                             buffer, sizeof buffer, ifp);
164                     fputs (buffer, ofp);
165                 }
166                 if (state == FLDEOF)
167                     goto process;
168                 break;
169
170             case BODY: 
171             case BODYEOF: 
172                 fclose (ofp);
173
174                 strncpy (tmpfil, m_tmpfil ("dist"), sizeof(tmpfil));
175                 if ((txtfd = open (tmpfil, O_RDWR | O_CREAT | O_TRUNC, 0600)) == NOTOK)
176                     adios (tmpfil, "unable to open temporary file");
177                 if ((out = dup (txtfd)) == NOTOK
178                         || (ofp = fdopen (out, "w")) == NULL)
179                     adios (NULL, "no file descriptors -- you lose big");
180                 unlink (tmpfil);
181                 fprintf (ofp, "\n%s", buffer);
182                 while (state == BODY) {
183                     state = m_getfld (state, name,
184                             buffer, sizeof buffer, ifp);
185                     fputs (buffer, ofp);
186                 }
187             case FILEEOF: 
188                 goto process;
189
190             case LENERR: 
191             case FMTERR: 
192                 adios (NULL, "format error in message %s", msgnam);
193
194             default: 
195                 adios (NULL, "getfld() returned %d", state);
196         }
197 process: ;
198     fclose (ifp);
199     fclose (ofp);
200 }