1 /* dropsbr.c - write to a mailbox */
3 static char ident[] = "@(#)$Id: dropsbr.c,v 1.19 1995/12/07 18:59:08 jromine Exp $";
9 #include "../h/dropsbr.h"
10 #include "../zotnet/mts.h"
17 #include <sys/types.h>
19 #if (defined(BSD42) || defined(SOCKETS)) && defined(NTOHLSWAP)
20 #include <netinet/in.h>
31 static int mbx_style = MMDF;
33 static int mbx_create(), mbx_chk(), map_open();
42 int style = mbx_style;
50 int style = mbx_style;
58 int mbx_open (file, uid, gid, mode)
67 if ((fd = mbx_Xopen (file, uid, gid, mode, &clear)) == NOTOK)
74 if (mbx_chk (fd) == NOTOK) {
81 if (lseek (fd, (off_t)0, 2) == (off_t) NOTOK) {
93 int mbx_Xopen (file, uid, gid, mode, clear)
105 for (*clear = 0, count = 4, j = 0; count > 0; count--)
106 if ((fd = lkopen (file, 6)) == NOTOK)
109 if (mbx_create (file, uid, gid, mode) == NOTOK)
126 *clear = fstat (fd, &st) != NOTOK && st.st_size == (off_t)0;
136 static int mbx_create (file, uid, gid, mode)
144 if ((fd = creat (file, 0600)) == NOTOK)
148 (void) chown (file, uid, gid);
149 (void) chmod (file, mode);
155 static int mbx_chk (fd)
161 count = strlen (mmdlm2);
163 if (lseek (fd, (off_t) (-count), 2) == (off_t) NOTOK
164 || read (fd, ldelim, count) != count)
168 if (strcmp (ldelim, mmdlm2)
169 && write (fd, "\n", 1) != 1
170 && write (fd, mmdlm2, count) != count)
178 int mbx_read (fp, pos, drops, noisy)
190 register struct drop *cp,
195 pp = (struct drop *) calloc ((unsigned) (len = MAXFOLDER), sizeof *dp);
198 admonish (NULLCP, "unable to allocate drop storage");
202 ld1 = (long) strlen (mmdlm1);
203 ld2 = (long) strlen (mmdlm2);
205 (void) fseek (fp, pos, 0);
206 for (ep = (dp = pp) + len - 1; fgets (buffer, sizeof buffer, fp);) {
208 if (strcmp (buffer, mmdlm1) == 0)
209 pos += ld1, dp -> d_start = (long) pos;
211 dp -> d_start = (long)pos , pos += (long) strlen (buffer);
212 for (bp = buffer; *bp; bp++, size++)
217 while (fgets (buffer, sizeof buffer, fp) != NULL)
218 if (strcmp (buffer, mmdlm2) == 0)
221 pos += (long) strlen (buffer);
222 for (bp = buffer; *bp; bp++, size++)
227 if (dp -> d_start != (long) pos) {
229 dp -> d_size = (long) size;
230 dp -> d_stop = (long) pos;
236 register int curlen = dp - pp;
238 cp = (struct drop *) realloc ((char *) pp,
239 (unsigned) (len += MAXFOLDER) * sizeof *pp);
242 admonish (NULLCP, "unable to allocate drop storage");
246 dp = cp + curlen, ep = (pp = cp) + len - 1;
259 int mbx_write (mailbox, md, fp, id, last, pos, stop, mapping, noisy)
278 off = (long) lseek (md, (off_t)0, 1);
280 if (write (md, mmdlm1, j) != j)
282 start = (long) lseek (md, (off_t)0, 1);
285 (void) fseek (fp, pos, 0);
286 while (fgets (buffer, sizeof buffer, fp) != NULL && pos < stop) {
288 for (j = 0; (j = stringdex (mmdlm1, buffer)) >= 0; buffer[j]++)
290 for (j = 0; (j = stringdex (mmdlm2, buffer)) >= 0; buffer[j]++)
292 if (write (md, buffer, i) != i)
296 for (cp = buffer; i-- > 0; size++)
301 stop = (long) lseek (md, (off_t)0, 1);
303 if (write (md, mmdlm2, j) != j)
306 (void) map_write (mailbox, md, id, last, start, stop, off, size, noisy);
313 int mbx_copy (mailbox, md, fd, mapping, text, noisy)
331 pos = (long) lseek (md, (off_t)0, 1);
338 if (write (md, mmdlm1, j) != j)
340 start = (long) lseek (md, (off_t)0, 1);
344 if (write (md, text, i) != i)
346 for (cp = text; *cp++; size++)
351 while ((i = read (fd, buffer, sizeof buffer)) > 0) {
353 (j = stringdex (mmdlm1, buffer)) >= 0;
357 (j = stringdex (mmdlm2, buffer)) >= 0;
360 if (write (md, buffer, i) != i)
363 for (cp = buffer; i-- > 0; size++)
368 stop = (long) lseek (md, (off_t)0, 1);
370 if (write (md, mmdlm2, j) != j)
373 (void) map_write (mailbox, md, 0, (long)0, start, stop, pos, size,
376 return (i != NOTOK ? OK : NOTOK);
378 case UUCP: /* I hate this... */
379 if ((j = dup (fd)) == NOTOK)
381 if ((fp = fdopen (j, "r")) == NULL) {
385 start = (long) lseek (md, (off_t)0, 1);
389 if (write (md, text, i) != i)
391 for (cp = text; *cp++; size++)
396 for (j = 0; fgets (buffer, sizeof buffer, fp) != NULL; j++) {
397 if (j != 0 && strncmp (buffer, "From ", 5) == 0) {
398 (void) write (md, ">", 1);
402 if (write (md, buffer, i) != i) {
407 for (cp = buffer; i-- > 0; size++)
411 if (write (md, "\n", 1) != 1) {
415 if (mapping) size += 2;
418 (void) (long) lseek (fd, (off_t)0, 2);
419 stop = (long) lseek (md, (off_t)0, 1);
421 (void) map_write (mailbox, md, 0, (long)0, start, stop, pos, size,
430 int mbx_size (md, start, stop)
440 if ((fd = dup (md)) == NOTOK || (fp = fdopen (fd, "r")) == NULL) {
446 (void) fseek (fp, start, 0);
447 for (i = 0, pos = stop - start; pos-- > 0; i++)
448 if (fgetc (fp) == '\n')
458 int mbx_close (mailbox, md)
462 (void) lkclose (md, mailbox);
469 /* This function is performed implicitly by getbbent.c:
471 bb -> bb_map = map_name (bb -> bb_file);
474 char *map_name (file)
478 static char buffer[BUFSIZ];
480 if ((cp = r1bindex (file, '/')) == file)
481 (void) sprintf (buffer, ".%s.map", cp);
483 (void) sprintf (buffer, "%.*s.%s.map", cp - file, file, cp);
490 int map_read (file, pos, drops, noisy)
501 register struct drop *mp,
504 if ((md = open (cp = map_name (file), 0)) == NOTOK
505 || map_chk (cp, md, mp = &d, pos, noisy)) {
512 dp = (struct drop *) calloc ((unsigned) (msgp + 1), sizeof *dp);
518 bcopy ((char *) mp, (char *) dp, sizeof *dp);
520 (void) lseek (md, (off_t) sizeof *mp, 0);
521 if ((i = read (md, (char *) (dp + 1), msgp * sizeof *dp)) < sizeof *dp) {
527 register struct drop *tdp;
528 for (j = 0, tdp = dp; j < i / sizeof(*dp); j++, tdp++) {
529 tdp->d_id = ntohl(tdp->d_id);
530 tdp->d_size = ntohl(tdp->d_size);
531 tdp->d_start = ntohl(tdp->d_start);
532 tdp->d_stop = ntohl(tdp->d_stop);
540 return (i / sizeof *dp);
545 int map_write (mailbox, md, id, last, start, stop, pos, size, noisy)
546 register char *mailbox;
561 register struct drop *dp;
567 if ((fd = map_open (file = map_name (mailbox), &clear, md)) == NOTOK)
570 if (!clear && map_chk (file, fd, &d1, pos, noisy)) {
571 (void) unlink (file);
572 (void) mbx_close (file, fd);
573 if ((fd = map_open (file, &clear, md)) == NOTOK)
579 if ((td = dup (md)) == NOTOK || (fp = fdopen (td, "r")) == NULL) {
581 admonish (file, "unable to %s", td != NOTOK ? "fdopen" : "dup");
584 (void) mbx_close (file, fd);
588 switch (i = mbx_read (fp, 0L, &rp, noisy)) {
591 (void) mbx_close (file, fd);
599 for (dp = rp; i-- >0; dp++) {
600 if (dp -> d_start == start)
602 (void) lseek (fd, (off_t) (++d1.d_id * sizeof *dp), 0);
603 if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
605 admonish (file, "write error");
606 (void) mbx_close (file, fd);
620 dp -> d_size = (long) (size ? size : mbx_size (fd, start, stop));
621 dp -> d_start = (long) start;
622 dp -> d_stop = (long) stop;
623 (void) lseek (fd, (off_t) (++d1.d_id * sizeof *dp), 0);
624 if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
626 admonish (file, "write error");
627 (void) mbx_close (file, fd);
633 dp -> d_size = DRVRSN;
634 dp -> d_start = (long) last;
635 dp -> d_stop = (long) lseek (md, (off_t)0, 1);
637 (void) lseek (fd, (off_t)0, 0);
638 if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
640 admonish (file, "write error");
641 (void) mbx_close (file, fd);
645 (void) mbx_close (file, fd);
652 static int map_open (file, clear, md)
660 mode = fstat (md, &st) != NOTOK ? (int) (st.st_mode & 0777) : m_gmprot ();
661 return mbx_Xopen (file, st.st_uid, st.st_gid, mode, clear);
666 int map_chk (file, fd, dp, pos, noisy)
670 register struct drop *dp;
675 register struct drop *dl;
677 if (read (fd, (char *) &tmpd, sizeof *dp) != sizeof *dp) {
679 admonish (NULLCP, "%s: missing or partial index", file);
684 *dp = tmpd; /* if ntohl(n)=(n), can use struct assign */
686 dp->d_id = ntohl(tmpd.d_id);
687 dp->d_size = ntohl(tmpd.d_size);
688 dp->d_start = ntohl(tmpd.d_start);
689 dp->d_stop = ntohl(tmpd.d_stop);
692 if (dp -> d_size != DRVRSN) {
694 admonish (NULLCP, "%s: version mismatch (%d != %d)", file,
699 if (dp -> d_stop != (long) pos) {
700 if (noisy && pos != (long)0)
702 "%s: pointer mismatch or incomplete index (%ld!=%ld)",
703 file, dp -> d_stop, (long) pos);
707 if ((long) ((dp -> d_id + 1) * sizeof *dp) != (long) lseek (fd, (off_t)0, 2)) {
709 admonish (NULLCP, "%s: corrupt index(1)", file);
714 count = (long) strlen (mmdlm2);
715 (void) lseek (fd, (off_t) (dp -> d_id * sizeof *dp), 0);
716 if (read (fd, (char *) dl, sizeof *dl) != sizeof *dl
717 || (ntohl(dl -> d_stop) != dp -> d_stop
718 && ntohl(dl -> d_stop) + count != dp -> d_stop)) {
720 admonish (NULLCP, "%s: corrupt index(2)", file);