If rcvpack missed file argument, it prints to stdout; Removed unused code.
[mmh] / uip / dropsbr.c
1 /*
2 ** dropsbr.c -- append to mbox files
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/nmh.h>
10 #include <h/utils.h>
11
12 #include <h/mh.h>
13 #include <h/dropsbr.h>
14 #include <h/tws.h>
15
16 #ifdef HAVE_ERRNO_H
17 # include <errno.h>
18 #endif
19
20 #include <fcntl.h>
21
22
23 /*
24 ** Main entry point to open/create and lock
25 ** a file or maildrop.
26 */
27 int
28 mbx_open(char *file, uid_t uid, gid_t gid, mode_t mode)
29 {
30         int i, count, fd;
31         struct stat st;
32
33         i = 0;
34
35         /* attempt to open and lock file */
36         for (count = 4; count > 0; count--) {
37                 if ((fd = lkopen(file, O_RDWR | O_CREAT | O_NONBLOCK, mode))
38                                 == NOTOK) {
39                         switch (errno) {
40 #if defined(FCNTL_LOCKING) || defined(LOCKF_LOCKING)
41                         case EACCES:
42                         case EAGAIN:
43 #endif
44
45 #ifdef FLOCK_LOCKING
46                         case EWOULDBLOCK:
47 #endif
48                         case ETXTBSY:
49                                 i = errno;
50                                 sleep(5);
51                                 break;
52
53                         default:
54                                 /* just return error */
55                                 return NOTOK;
56                         }
57                 }
58
59                 /* good file descriptor */
60                 break;
61         }
62
63         errno = i;
64
65         /*
66         ** Return if we still failed after 4 attempts,
67         ** or we just want to skip the sanity checks.
68         */
69         if (fd == NOTOK)
70                 return fd;
71
72         /* Do sanity checks on maildrop. */
73         if (fstat(fd, &st) == NOTOK) {
74                 /*
75                 ** The stat failed.  So we make sure file
76                 ** has right ownership/modes
77                 */
78                 chown(file, uid, gid);
79                 chmod(file, mode);
80         } else if (st.st_size > (off_t) 0) {
81                 int status;
82
83                 /* Check/prepare MBOX style maildrop for appending. */
84                 if (lseek(fd, (off_t) 0, SEEK_END) == (off_t) NOTOK) {
85                         status = NOTOK;
86                 } else {
87                         status = OK;
88                 }
89
90                 /* if error, attempt to close it */
91                 if (status == NOTOK) {
92                         close(fd);
93                         return NOTOK;
94                 }
95         }
96
97         return fd;
98 }
99
100
101 /*
102 ** Append message to end of mbox.
103 */
104 int
105 mbx_copy(int to, int from)
106 {
107         int i;
108         char buffer[BUFSIZ];
109         FILE *fp;
110
111         if ((i = dup(from)) == NOTOK)
112                 return NOTOK;
113         if ((fp = fdopen(i, "r")) == NULL) {
114                 close(i);
115                 return NOTOK;
116         }
117
118         for (i = 0; fgets(buffer, sizeof(buffer), fp) != NULL; i++) {
119                 /*
120                 ** Check the first line, and make some changes.
121                 */
122                 if (i == 0) {
123                         /*
124                         ** Change the "Return-Path:" field
125                         ** (if in first line) back to "From ".
126                         */
127                         if (strncmp(buffer, "Return-Path:", 12)==0) {
128                                 char tmpbuffer[BUFSIZ];
129                                 char *tp, *ep, *fp;
130
131                                 strncpy(tmpbuffer, buffer, sizeof(tmpbuffer));
132                                 ep = tmpbuffer + 13;
133                                 if (!(fp = strchr(ep + 1, ' ')))
134                                         fp = strchr(ep + 1, '\n');
135                                 tp = dctime(dlocaltimenow());
136                                         snprintf(buffer, sizeof(buffer),
137                                                         "From %.*s  %s",
138                                                         (int)(fp-ep), ep, tp);
139                         } else if (strncmp(buffer, "X-Envelope-From:",
140                                         16)==0) {
141                                 /*
142                                 ** Change the "X-Envelope-From:" field
143                                 ** (if first line) back to "From ".
144                                 */
145                                 char tmpbuffer[BUFSIZ];
146                                 char *ep;
147
148                                 strncpy(tmpbuffer, buffer, sizeof(tmpbuffer));
149                                 ep = tmpbuffer + 17;
150                                 snprintf(buffer, sizeof(buffer), "From %s",
151                                                 ep);
152                         } else if (strncmp(buffer, "From ", 5)!=0) {
153                                 /*
154                                 ** If there is already a "From " line,
155                                 ** then leave it alone.  Else we add one.
156                                 */
157                                 char tmpbuffer[BUFSIZ];
158                                 char *tp, *ep;
159
160                                 strncpy(tmpbuffer, buffer, sizeof(tmpbuffer));
161                                 ep = "nobody@nowhere";
162                                 tp = dctime(dlocaltimenow());
163                                 snprintf(buffer, sizeof(buffer),
164                                                 "From %s  %s%s", ep, tp,
165                                                 tmpbuffer);
166                         }
167                 }
168
169                 /*
170                 ** If this is not first line, and begins with "From ",
171                 ** then prepend line with ">". (`mboxo' format is used.)
172                 */
173                 if (i != 0 && strncmp(buffer, "From ", 5) == 0) {
174                         write(to, ">", 1);
175                 }
176                 if (write(to, buffer, strlen(buffer)) != strlen(buffer)) {
177                         fclose(fp);
178                         return NOTOK;
179                 }
180         }
181
182         if (write(to, "\n", 1) != 1) {
183                 fclose(fp);
184                 return NOTOK;
185         }
186         fclose(fp);
187         lseek(from, (off_t) 0, SEEK_END);
188
189         return OK;
190 }
191
192
193 /*
194 ** Close and unlock file/maildrop.
195 */
196 int
197 mbx_close(char *mailbox, int md)
198 {
199         if (lkclose(md, mailbox) == 0)
200                 return OK;
201         return NOTOK;
202 }