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