]>
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/strindex.h"
11 #include "sbr/error.h"
13 #include "h/dropsbr.h"
16 #include "sbr/lock_file.h"
17 #include "sbr/m_mktemp.h"
23 static int mbx_chk_mbox (int);
24 static int mbx_chk_mmdf (int);
28 * Main entry point to open/create and lock
33 mbx_open (char *file
, int mbx_style
, uid_t uid
, gid_t gid
, mode_t mode
)
35 int j
, count
, fd
= NOTOK
;
40 /* attempt to open and lock file */
41 for (count
= 4; count
> 0; count
--) {
42 int failed_to_lock
= 0;
44 if ((fd
= lkopenspool (file
, O_RDWR
| O_CREAT
| O_NONBLOCK
,
45 mode
, &failed_to_lock
)) != NOTOK
)
58 * Return if we still failed after 4 attempts,
59 * or we just want to skip the sanity checks.
61 if (fd
== NOTOK
|| mbx_style
== OTHER_FORMAT
)
65 * Do sanity checks on maildrop.
67 if (fstat (fd
, &st
) == NOTOK
) {
69 * The stat failed. So we make sure file
70 * has right ownership/modes
72 if (chown (file
, uid
, gid
) < 0) {
73 advise (file
, "chown");
75 if (chmod (file
, mode
) < 0) {
76 advise (file
, "chmod");
78 } else if (st
.st_size
> 0) {
81 /* check the maildrop */
85 status
= mbx_chk_mmdf (fd
);
89 status
= mbx_chk_mbox (fd
);
93 /* if error, attempt to close it */
94 if (status
== NOTOK
) {
105 * Check/prepare MBOX style maildrop for appending.
109 mbx_chk_mbox (int fd
)
111 /* just seek to the end */
112 if (lseek(fd
, 0, SEEK_END
) == (off_t
) NOTOK
)
120 * Check/prepare MMDF style maildrop for appending.
124 mbx_chk_mmdf (int fd
)
129 count
= LEN(MMDF_DELIM
);
131 if (lseek (fd
, -count
, SEEK_END
) == (off_t
) NOTOK
)
133 if (read (fd
, ldelim
, count
) != count
)
138 if (strcmp (ldelim
, MMDF_DELIM
)
139 && write (fd
, "\n", 1) != 1
140 && write (fd
, MMDF_DELIM
, count
) != count
)
148 * Append message to end of file or maildrop.
152 mbx_copy (char *mailbox
, int mbx_style
, int md
, int fd
,
156 char *cp
, buffer
[BUFSIZ
+ 1]; /* Space for NUL. */
165 if (write (md
, MMDF_DELIM
, j
) != j
)
170 if (write (md
, text
, i
) != i
)
172 for (cp
= text
; *cp
++; size
++)
177 while ((i
= read (fd
, buffer
, sizeof buffer
- 1)) > 0) {
178 buffer
[i
] = '\0'; /* Terminate for stringdex(). */
180 for ( ; (j
= stringdex (MMDF_DELIM
, buffer
)) >= 0; buffer
[j
]++)
182 for ( ; (j
= stringdex (MMDF_DELIM
, buffer
)) >= 0; buffer
[j
]++)
184 if (write (md
, buffer
, i
) != i
)
189 if (write (md
, MMDF_DELIM
, j
) != j
)
192 return i
== NOTOK
? NOTOK
: OK
;
195 if ((j
= dup (fd
)) == NOTOK
)
197 if ((fp
= fdopen (j
, "r")) == NULL
) {
202 /* If text is given, we add it to top of message */
205 if (write (md
, text
, i
) != i
)
207 for (cp
= text
; *cp
++; size
++)
212 for (j
= 0; fgets (buffer
, sizeof(buffer
), fp
) != NULL
; j
++) {
215 * Check the first line, and make some changes.
217 if (j
== 0 && !text
) {
219 * Change the "Return-Path:" field (if in first line)
222 if (has_prefix(buffer
, "Return-Path:")) {
223 char tmpbuffer
[sizeof buffer
];
226 strncpy(tmpbuffer
, buffer
, sizeof(tmpbuffer
));
228 if (!(fp
= strchr(ep
+ 1, ' ')))
229 fp
= strchr(ep
+ 1, '\n');
230 tp
= dctime(dlocaltimenow());
231 snprintf (buffer
, sizeof(buffer
), "From %.*s %s",
232 (int)(fp
- ep
), ep
, tp
);
233 } else if (has_prefix(buffer
, "X-Envelope-From:")) {
235 * Change the "X-Envelope-From:" field
236 * (if first line) back to "From ".
238 char tmpbuffer
[sizeof buffer
];
241 strncpy(tmpbuffer
, buffer
, sizeof(tmpbuffer
));
243 snprintf (buffer
, sizeof(buffer
), "From %s", ep
);
244 } else if (!has_prefix(buffer
, "From ")) {
246 * If there is already a "From " line,
247 * then leave it alone. Else we add one.
249 char tmpbuffer
[sizeof buffer
];
252 strncpy(tmpbuffer
, buffer
, sizeof(tmpbuffer
));
253 ep
= "nobody@nowhere";
254 tp
= dctime(dlocaltimenow());
255 snprintf (buffer
, sizeof(buffer
), "From %s %s%s", ep
, tp
, tmpbuffer
);
260 * If this is not first line, and begins with
261 * "From ", then prepend line with ">".
263 if (j
!= 0 && has_prefix(buffer
, "From ")) {
264 if (write (md
, ">", 1) < 0) {
265 advise (mailbox
, "write");
270 if (write (md
, buffer
, i
) != i
) {
275 if (write (md
, "\n", 1) != 1) {
281 lseek(fd
, 0, SEEK_END
);
289 * Close and unlock file/maildrop.
293 mbx_close (char *mailbox
, int md
)
295 if (lkclosespool (md
, mailbox
) == 0)