2 ** dropsbr.c -- create/read/manipulate mail drops
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.
13 #include <h/dropsbr.h>
25 ** Main entry point to open/create and lock
26 ** a file or maildrop.
29 mbx_open(char *file, uid_t uid, gid_t gid, mode_t mode)
36 /* attempt to open and lock file */
37 for (count = 4; count > 0; count--) {
38 if ((fd = lkopen(file, O_RDWR | O_CREAT | O_NONBLOCK, mode))
41 #if defined(FCNTL_LOCKING) || defined(LOCKF_LOCKING)
55 /* just return error */
60 /* good file descriptor */
67 ** Return if we still failed after 4 attempts,
68 ** or we just want to skip the sanity checks.
73 /* Do sanity checks on maildrop. */
74 if (fstat(fd, &st) == NOTOK) {
76 ** The stat failed. So we make sure file
77 ** has right ownership/modes
79 chown(file, uid, gid);
81 } else if (st.st_size > (off_t) 0) {
84 /* Check/prepare MBOX style maildrop for appending. */
85 if (lseek(fd, (off_t) 0, SEEK_END) == (off_t) NOTOK) {
91 /* if error, attempt to close it */
92 if (status == NOTOK) {
104 ** Append message to end of file or maildrop.
107 mbx_copy(char *mailbox, int md, int fd, char *text, int noisy)
115 pos = (long) lseek(md, (off_t) 0, SEEK_CUR);
117 if ((j = dup(fd)) == NOTOK)
119 if ((fp = fdopen(j, "r")) == NULL) {
123 start = lseek(md, (off_t) 0, SEEK_CUR);
125 /* If text is given, we add it to top of message */
128 if (write(md, text, i) != i)
132 for (j = 0; fgets(buffer, sizeof(buffer), fp) != NULL; j++) {
134 ** Check the first line, and make some changes.
136 if (j == 0 && !text) {
138 ** Change the "Return-Path:" field
139 ** (if in first line) back to "From ".
141 if (strncmp(buffer, "Return-Path:", 12)==0) {
142 char tmpbuffer[BUFSIZ];
145 strncpy(tmpbuffer, buffer, sizeof(tmpbuffer));
147 if (!(fp = strchr(ep + 1, ' ')))
148 fp = strchr(ep + 1, '\n');
149 tp = dctime(dlocaltimenow());
150 snprintf(buffer, sizeof(buffer),
152 (int)(fp-ep), ep, tp);
153 } else if (strncmp(buffer, "X-Envelope-From:",
156 ** Change the "X-Envelope-From:" field
157 ** (if first line) back to "From ".
159 char tmpbuffer[BUFSIZ];
162 strncpy(tmpbuffer, buffer, sizeof(tmpbuffer));
164 snprintf(buffer, sizeof(buffer), "From %s",
166 } else if (strncmp(buffer, "From ", 5)!=0) {
168 ** If there is already a "From " line,
169 ** then leave it alone. Else we add one.
171 char tmpbuffer[BUFSIZ];
174 strncpy(tmpbuffer, buffer, sizeof(tmpbuffer));
175 ep = "nobody@nowhere";
176 tp = dctime(dlocaltimenow());
177 snprintf(buffer, sizeof(buffer),
178 "From %s %s%s", ep, tp,
184 ** If this is not first line, and begins with "From ",
185 ** then prepend line with ">".
187 if (j != 0 && strncmp(buffer, "From ", 5) == 0) {
191 if (write(md, buffer, i) != i) {
197 if (write(md, "\n", 1) != 1) {
202 lseek(fd, (off_t) 0, SEEK_END);
203 stop = lseek(md, (off_t) 0, SEEK_CUR);
210 ** Close and unlock file/maildrop.
213 mbx_close(char *mailbox, int md)
215 if (lkclose(md, mailbox) == 0)