]>
diplodocus.org Git - nmh/blob - uip/dropsbr.c
1 /* dropsbr.c -- create/read/manipulate mail drops
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.
10 #include "sbr/dtime.h"
11 #include "sbr/strindex.h"
12 #include "sbr/error.h"
14 #include "h/dropsbr.h"
17 #include "sbr/lock_file.h"
18 #include "sbr/m_mktemp.h"
24 static int mbx_chk_mbox (int);
25 static int mbx_chk_mmdf (int);
29 * Main entry point to open/create and lock
34 mbx_open (char *file
, int mbx_style
, uid_t uid
, gid_t gid
, mode_t mode
)
36 int j
, count
, fd
= NOTOK
;
41 /* attempt to open and lock file */
42 for (count
= 4; count
> 0; count
--) {
43 int failed_to_lock
= 0;
45 if ((fd
= lkopenspool (file
, O_RDWR
| O_CREAT
| O_NONBLOCK
,
46 mode
, &failed_to_lock
)) != NOTOK
)
59 * Return if we still failed after 4 attempts,
60 * or we just want to skip the sanity checks.
62 if (fd
== NOTOK
|| mbx_style
== OTHER_FORMAT
)
66 * Do sanity checks on maildrop.
68 if (fstat (fd
, &st
) == NOTOK
) {
70 * The stat failed. So we make sure file
71 * has right ownership/modes
73 if (chown (file
, uid
, gid
) < 0) {
74 advise (file
, "chown");
76 if (chmod (file
, mode
) < 0) {
77 advise (file
, "chmod");
79 } else if (st
.st_size
> 0) {
82 /* check the maildrop */
86 status
= mbx_chk_mmdf (fd
);
90 status
= mbx_chk_mbox (fd
);
94 /* if error, attempt to close it */
95 if (status
== NOTOK
) {
106 * Check/prepare MBOX style maildrop for appending.
110 mbx_chk_mbox (int fd
)
112 /* just seek to the end */
113 if (lseek(fd
, 0, SEEK_END
) == (off_t
) NOTOK
)
121 * Check/prepare MMDF style maildrop for appending.
125 mbx_chk_mmdf (int fd
)
130 count
= LEN(MMDF_DELIM
);
132 if (lseek (fd
, -count
, SEEK_END
) == (off_t
) NOTOK
)
134 if (read (fd
, ldelim
, count
) != count
)
139 if (strcmp (ldelim
, MMDF_DELIM
)
140 && write (fd
, "\n", 1) != 1
141 && write (fd
, MMDF_DELIM
, count
) != count
)
149 * Append message to end of file or maildrop.
153 mbx_copy (char *mailbox
, int mbx_style
, int md
, int fd
,
157 char *cp
, buffer
[BUFSIZ
+ 1]; /* Space for NUL. */
166 if (write (md
, MMDF_DELIM
, j
) != j
)
171 if (write (md
, text
, i
) != i
)
173 for (cp
= text
; *cp
++; size
++)
178 while ((i
= read (fd
, buffer
, sizeof buffer
- 1)) > 0) {
179 buffer
[i
] = '\0'; /* Terminate for stringdex(). */
181 for ( ; (j
= stringdex (MMDF_DELIM
, buffer
)) >= 0; buffer
[j
]++)
183 for ( ; (j
= stringdex (MMDF_DELIM
, buffer
)) >= 0; buffer
[j
]++)
185 if (write (md
, buffer
, i
) != i
)
190 if (write (md
, MMDF_DELIM
, j
) != j
)
193 return i
== NOTOK
? NOTOK
: OK
;
196 if ((j
= dup (fd
)) == NOTOK
)
198 if ((fp
= fdopen (j
, "r")) == NULL
) {
203 /* If text is given, we add it to top of message */
206 if (write (md
, text
, i
) != i
)
208 for (cp
= text
; *cp
++; size
++)
213 for (j
= 0; fgets (buffer
, sizeof(buffer
), fp
) != NULL
; j
++) {
216 * Check the first line, and make some changes.
218 if (j
== 0 && !text
) {
220 * Change the "Return-Path:" field (if in first line)
223 if (has_prefix(buffer
, "Return-Path:")) {
224 char tmpbuffer
[sizeof buffer
];
227 strncpy(tmpbuffer
, buffer
, sizeof(tmpbuffer
));
229 if (!(fp
= strchr(ep
+ 1, ' ')))
230 fp
= strchr(ep
+ 1, '\n');
231 tp
= dctime(dlocaltimenow());
232 snprintf (buffer
, sizeof(buffer
), "From %.*s %s",
233 (int)(fp
- ep
), ep
, tp
);
234 } else if (has_prefix(buffer
, "X-Envelope-From:")) {
236 * Change the "X-Envelope-From:" field
237 * (if first line) back to "From ".
239 char tmpbuffer
[sizeof buffer
];
242 strncpy(tmpbuffer
, buffer
, sizeof(tmpbuffer
));
244 snprintf (buffer
, sizeof(buffer
), "From %s", ep
);
245 } else if (!has_prefix(buffer
, "From ")) {
247 * If there is already a "From " line,
248 * then leave it alone. Else we add one.
250 char tmpbuffer
[sizeof buffer
];
253 strncpy(tmpbuffer
, buffer
, sizeof(tmpbuffer
));
254 ep
= "nobody@nowhere";
255 tp
= dctime(dlocaltimenow());
256 snprintf (buffer
, sizeof(buffer
), "From %s %s%s", ep
, tp
, tmpbuffer
);
261 * If this is not first line, and begins with
262 * "From ", then prepend line with ">".
264 if (j
!= 0 && has_prefix(buffer
, "From ")) {
265 if (write (md
, ">", 1) < 0) {
266 advise (mailbox
, "write");
271 if (write (md
, buffer
, i
) != i
) {
276 if (write (md
, "\n", 1) != 1) {
282 lseek(fd
, 0, SEEK_END
);
290 * Close and unlock file/maildrop.
294 mbx_close (char *mailbox
, int md
)
296 if (lkclosespool (md
, mailbox
) == 0)