1 /* dropsbr.c - write to a mailbox */
3 static char Id[] = "@(#)$Id: dropsbr.c,v 1.3 1993/08/25 17:43:26 jromine Exp $";
9 #include "../h/dropsbr.h"
10 #include "../zotnet/mts.h"
17 #include <sys/types.h>
26 static int mbx_style = MMDF;
36 int style = mbx_style;
44 int style = mbx_style;
52 int mbx_open (file, uid, gid, mode)
61 if ((fd = mbx_Xopen (file, uid, gid, mode, &clear)) == NOTOK)
68 if (mbx_chk (fd) == NOTOK) {
75 if (lseek (fd, (off_t)0, 2) == (off_t) NOTOK) {
87 int mbx_Xopen (file, uid, gid, mode, clear)
99 for (*clear = 0, count = 4, j = 0; count > 0; count--)
100 if ((fd = lkopen (file, 6)) == NOTOK)
103 if (mbx_create (file, uid, gid, mode) == NOTOK)
120 *clear = fstat (fd, &st) != NOTOK && st.st_size == 0L;
130 static int mbx_create (file, uid, gid, mode)
138 if ((fd = creat (file, 0600)) == NOTOK)
142 (void) chown (file, uid, gid);
143 (void) chmod (file, mode);
149 static int mbx_chk (fd)
155 count = strlen (mmdlm2);
157 if (lseek (fd, (off_t) (-count), 2) == (off_t) NOTOK
158 || read (fd, ldelim, count) != count)
160 ldelim[count] = NULL;
162 if (strcmp (ldelim, mmdlm2)
163 && write (fd, "\n", 1) != 1
164 && write (fd, mmdlm2, count) != count)
172 int mbx_read (fp, pos, drops, noisy)
184 register struct drop *cp,
189 pp = (struct drop *) calloc ((unsigned) (len = MAXFOLDER), sizeof *dp);
192 admonish (NULLCP, "unable to allocate drop storage");
196 ld1 = (long) strlen (mmdlm1);
197 ld2 = (long) strlen (mmdlm2);
199 (void) fseek (fp, pos, 0);
200 for (ep = (dp = pp) + len - 1; fgets (buffer, sizeof buffer, fp);) {
202 if (strcmp (buffer, mmdlm1) == 0)
203 pos += ld1, dp -> d_start = pos;
205 dp -> d_start = pos, pos += (long) strlen (buffer);
206 for (bp = buffer; *bp; bp++, size++)
211 while (fgets (buffer, sizeof buffer, fp) != NULL)
212 if (strcmp (buffer, mmdlm2) == 0)
215 pos += (long) strlen (buffer);
216 for (bp = buffer; *bp; bp++, size++)
221 if (dp -> d_start != pos) {
230 register int curlen = dp - pp;
232 cp = (struct drop *) realloc ((char *) pp,
233 (unsigned) (len += MAXFOLDER) * sizeof *pp);
236 admonish (NULLCP, "unable to allocate drop storage");
240 dp = cp + curlen, ep = (pp = cp) + len - 1;
253 int mbx_write (mailbox, md, fp, id, last, pos, stop, mapping, noisy)
272 off = (long) lseek (md, (off_t)0, 1);
274 if (write (md, mmdlm1, j) != j)
276 start = (long) lseek (md, (off_t)0, 1);
279 (void) fseek (fp, pos, 0);
280 while (fgets (buffer, sizeof buffer, fp) != NULL && pos < stop) {
282 for (j = 0; (j = stringdex (mmdlm1, buffer)) >= 0; buffer[j]++)
284 for (j = 0; (j = stringdex (mmdlm2, buffer)) >= 0; buffer[j]++)
286 if (write (md, buffer, i) != i)
290 for (cp = buffer; i-- > 0; size++)
295 stop = (long) lseek (md, (off_t)0, 1);
297 if (write (md, mmdlm2, j) != j)
300 (void) map_write (mailbox, md, id, last, start, stop, off, size, noisy);
307 int mbx_copy (mailbox, md, fd, mapping, text, noisy)
325 pos = (long) lseek (md, (off_t)0, 1);
332 if (write (md, mmdlm1, j) != j)
334 start = (long) lseek (md, (off_t)0, 1);
338 if (write (md, text, i) != i)
340 for (cp = text; *cp++; size++)
345 while ((i = read (fd, buffer, sizeof buffer)) > 0) {
347 (j = stringdex (mmdlm1, buffer)) >= 0;
351 (j = stringdex (mmdlm2, buffer)) >= 0;
354 if (write (md, buffer, i) != i)
357 for (cp = buffer; i-- > 0; size++)
362 stop = (long) lseek (md, (off_t)0, 1);
364 if (write (md, mmdlm2, j) != j)
367 (void) map_write (mailbox, md, 0, 0L, start, stop, pos, size,
370 return (i != NOTOK ? OK : NOTOK);
372 case UUCP: /* I hate this... */
373 if ((j = dup (fd)) == NOTOK)
375 if ((fp = fdopen (j, "r")) == NULL) {
379 start = (long) lseek (md, (off_t)0, 1);
383 if (write (md, text, i) != i)
385 for (cp = text; *cp++; size++)
390 for (j = 0; fgets (buffer, sizeof buffer, fp) != NULL; j++) {
391 if (j != 0 && strncmp (buffer, "From ", 5) == 0) {
392 (void) write (fd, ">", 1);
396 if (write (md, buffer, i) != i) {
401 for (cp = buffer; i-- > 0; size++)
407 (void) lseek (fd, (off_t)0, 2);
408 stop = (long) lseek (md, (off_t)0, 1);
410 (void) map_write (mailbox, md, 0, 0L, start, stop, pos, size,
419 int mbx_size (md, start, stop)
429 if ((fd = dup (md)) == NOTOK || (fp = fdopen (fd, "r")) == NULL) {
435 (void) fseek (fp, start, 0);
436 for (i = 0, pos = stop - start; pos-- > 0; i++)
437 if (fgetc (fp) == '\n')
447 int mbx_close (mailbox, md)
451 (void) lkclose (md, mailbox);
458 /* This function is performed implicitly by getbbent.c:
460 bb -> bb_map = map_name (bb -> bb_file);
463 char *map_name (file)
468 static char buffer[BUFSIZ];
470 if ((dp = index (cp = r1bindex (file, '/'), '.')) == NULL)
471 dp = cp + strlen (cp);
473 (void) sprintf (buffer, ".%.*s%s", dp - cp, cp, ".map");
475 (void) sprintf (buffer, "%.*s.%.*s%s", cp - file, file, dp - cp,
483 int map_read (file, pos, drops, noisy)
494 register struct drop *mp,
497 if ((md = open (cp = map_name (file), 0)) == NOTOK
498 || map_chk (cp, md, mp = &d, pos, noisy)) {
505 dp = (struct drop *) calloc ((unsigned) (msgp + 1), sizeof *dp);
511 bcopy ((char *) mp, (char *) dp, sizeof *dp);
513 (void) lseek (md, (off_t) sizeof *mp, 0);
514 if ((i = read (md, (char *) (dp + 1), msgp * sizeof *dp)) < sizeof *dp) {
523 return (i / sizeof *dp);
528 int map_write (mailbox, md, id, last, start, stop, pos, size, noisy)
529 register char *mailbox;
544 register struct drop *dp;
550 if ((fd = map_open (file = map_name (mailbox), &clear, md)) == NOTOK)
553 if (!clear && map_chk (file, fd, &d1, pos, noisy)) {
554 (void) unlink (file);
555 (void) mbx_close (file, fd);
556 if ((fd = map_open (file, &clear, md)) == NOTOK)
562 if ((td = dup (md)) == NOTOK || (fp = fdopen (td, "r")) == NULL) {
564 admonish (file, "unable to %s", td != NOTOK ? "fdopen" : "dup");
567 (void) mbx_close (file, fd);
571 switch (i = mbx_read (fp, 0L, &rp, noisy)) {
574 (void) mbx_close (file, fd);
582 for (dp = rp; i-- >0; dp++) {
583 if (dp -> d_start == start)
585 (void) lseek (fd, (off_t) (++d1.d_id * sizeof *dp), 0);
586 if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
588 admonish (file, "write error");
589 (void) mbx_close (file, fd);
603 dp -> d_size = size ? size : mbx_size (fd, start, stop);
604 dp -> d_start = start;
606 (void) lseek (fd, (off_t) (++d1.d_id * sizeof *dp), 0);
607 if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
609 admonish (file, "write error");
610 (void) mbx_close (file, fd);
616 dp -> d_size = DRVRSN;
617 dp -> d_start = last;
618 dp -> d_stop = (long) lseek (md, (off_t)0, 1);
620 (void) lseek (fd, (off_t)0, 0);
621 if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
623 admonish (file, "write error");
624 (void) mbx_close (file, fd);
628 (void) mbx_close (file, fd);
635 static int map_open (file, clear, md)
643 mode = fstat (md, &st) != NOTOK ? (int) (st.st_mode & 0777) : m_gmprot ();
644 return mbx_Xopen (file, st.st_uid, st.st_gid, mode, clear);
649 int map_chk (file, fd, dp, pos, noisy)
653 register struct drop *dp;
658 register struct drop *dl;
660 if (read (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
662 admonish (NULLCP, "%s: missing or partial index", file);
667 if (dp -> d_size != DRVRSN) {
669 admonish (NULLCP, "%s: version mismatch", file);
673 if (dp -> d_stop != pos) {
674 if (noisy && pos != 0L)
676 "%s: pointer mismatch or incomplete index (%ld!=%ld)",
677 file, dp -> d_stop, pos);
681 if ((long) ((dp -> d_id + 1) * sizeof *dp) != (long) lseek (fd, (off_t)0, 2)) {
683 admonish (NULLCP, "%s: corrupt index(1)", file);
688 count = (long) strlen (mmdlm2);
689 (void) lseek (fd, (off_t) (dp -> d_id * sizeof *dp), 0);
690 if (read (fd, (char *) dl, sizeof *dl) != sizeof *dl
691 || (dl -> d_stop != dp -> d_stop
692 && dl -> d_stop + count != dp -> d_stop)) {
694 admonish (NULLCP, "%s: corrupt index(2)", file);