1: /* dropsbr.c - write to a mailbox */
   2: 
   3: #include <stdio.h>
   4: #ifndef MMDFONLY
   5: #include "../h/mh.h"
   6: #include "../h/dropsbr.h"
   7: #include "../zotnet/mts.h"
   8: #else   MMDFONLY
   9: #include "dropsbr.h"
  10: #include "strings.h"
  11: #include "mmdfonly.h"
  12: #endif	MMDFONLY
  13: #include <errno.h>
  14: #include <sys/types.h>
  15: #include <sys/stat.h>
  16: 
  17: 
  18: #define MMDF    1
  19: #define UUCP    2
  20: 
  21: /*  */
  22: 
  23: static  int mbx_style = MMDF;
  24: 
  25: 
  26: extern int  errno;
  27: 
  28: 
  29: long   lseek ();
  30: 
  31: /*  */
  32: 
  33: int     mbx_mmdf () {
  34:     int     style = mbx_style;
  35: 
  36:     mbx_style = MMDF;
  37:     return style;
  38: }
  39: 
  40: 
  41: int     mbx_uucp () {
  42:     int     style = mbx_style;
  43: 
  44:     mbx_style = UUCP;
  45:     return style;
  46: }
  47: 
  48: /*  */
  49: 
  50: int     mbx_open (file, uid, gid, mode)
  51: char   *file;
  52: int     uid,
  53:         gid,
  54:     mode;
  55: {
  56:     int     clear,
  57:             fd;
  58: 
  59:     if ((fd = mbx_Xopen (file, uid, gid, mode, &clear)) == NOTOK)
  60:     return fd;
  61: 
  62:     if (!clear)
  63:     switch (mbx_style) {
  64:         case MMDF:
  65:         default:
  66:         if (mbx_chk (fd) == NOTOK) {
  67:             (void) close (fd);
  68:             return NOTOK;
  69:         }
  70:         break;
  71: 
  72:         case UUCP:
  73:         if (lseek (fd, 0L, 2) == (long) NOTOK) {
  74:             (void) close (fd);
  75:             return NOTOK;
  76:         }
  77:         break;
  78:     }
  79: 
  80:     return fd;
  81: }
  82: 
  83: /*  */
  84: 
  85: int mbx_Xopen (file, uid, gid, mode, clear)
  86: char   *file;
  87: int uid,
  88:     gid,
  89:     mode,
  90:        *clear;
  91: {
  92:     register int j;
  93:     int     count,
  94:             fd;
  95:     struct stat st;
  96: 
  97:     for (*clear = 0, count = 4, j = 0; count > 0; count--)
  98:     if ((fd = lkopen (file, 6)) == NOTOK)
  99:         switch (errno) {
 100:         case ENOENT:
 101:             if (mbx_create (file, uid, gid, mode) == NOTOK)
 102:             return NOTOK;
 103:             (*clear)++;
 104:             break;
 105: 
 106: #ifdef  BSD42
 107:         case EWOULDBLOCK:
 108: #endif	BSD42
 109:         case ETXTBSY:
 110:             j = errno;
 111:             sleep (5);
 112:             break;
 113: 
 114:         default:
 115:             return NOTOK;
 116:         }
 117:     else {
 118:         *clear = fstat (fd, &st) != NOTOK && st.st_size == 0L;
 119:         break;
 120:     }
 121: 
 122:     errno = j;
 123:     return fd;
 124: }
 125: 
 126: /*  */
 127: 
 128: static int  mbx_create (file, uid, gid, mode)
 129: char   *file;
 130: int     uid,
 131:         gid,
 132:     mode;
 133: {
 134:     int     fd;
 135: 
 136:     if ((fd = creat (file, 0600)) == NOTOK)
 137:     return NOTOK;
 138: 
 139:     (void) close (fd);
 140:     (void) chown (file, uid, gid);
 141:     (void) chmod (file, mode);
 142: 
 143:     return OK;
 144: }
 145: 
 146: 
 147: static int  mbx_chk (fd)
 148: int     fd;
 149: {
 150:     int     count;
 151:     char    ldelim[BUFSIZ];
 152: 
 153:     count = strlen (mmdlm2);
 154: 
 155:     if (lseek (fd, (long) (-count), 2) == (long) NOTOK
 156:         || read (fd, ldelim, count) != count)
 157:     return NOTOK;
 158:     ldelim[count] = NULL;
 159: 
 160:     if (strcmp (ldelim, mmdlm2)
 161:         && write (fd, "\n", 1) != 1
 162:         && write (fd, mmdlm2, count) != count)
 163:     return NOTOK;
 164: 
 165:     return OK;
 166: }
 167: 
 168: /*  */
 169: 
 170: int mbx_read (fp, pos, drops, noisy)
 171: register FILE  *fp;
 172: register long   pos;
 173: struct drop **drops;
 174: int noisy;
 175: {
 176:     register int    len,
 177:                     size;
 178:     long    ld1,
 179:             ld2;
 180:     register char  *bp;
 181:     char    buffer[BUFSIZ];
 182:     register struct drop   *cp,
 183:                            *dp,
 184:                            *ep,
 185:                            *pp;
 186: 
 187:     pp = (struct drop  *) calloc ((unsigned) (len = MAXFOLDER), sizeof *dp);
 188:     if (pp == NULL) {
 189:     if (noisy)
 190:         admonish (NULLCP, "unable to allocate drop storage");
 191:     return NOTOK;
 192:     }
 193: 
 194:     ld1 = (long) strlen (mmdlm1);
 195:     ld2 = (long) strlen (mmdlm2);
 196: 
 197:     (void) fseek (fp, pos, 0);
 198:     for (ep = (dp = pp) + len - 1; fgets (buffer, sizeof buffer, fp);) {
 199:     size = 0;
 200:     if (strcmp (buffer, mmdlm1) == 0)
 201:         pos += ld1, dp -> d_start = pos;
 202:     else {
 203:         dp -> d_start = pos, pos += (long) strlen (buffer);
 204:         for (bp = buffer; *bp; bp++, size++)
 205:         if (*bp == '\n')
 206:             size++;
 207:     }
 208: 
 209:     while (fgets (buffer, sizeof buffer, fp) != NULL)
 210:         if (strcmp (buffer, mmdlm2) == 0)
 211:         break;
 212:         else {
 213:         pos += (long) strlen (buffer);
 214:         for (bp = buffer; *bp; bp++, size++)
 215:             if (*bp == '\n')
 216:             size++;
 217:         }
 218: 
 219:     if (dp -> d_start != pos) {
 220:         dp -> d_id = 0;
 221:         dp -> d_size = size;
 222:         dp -> d_stop = pos;
 223:         dp++;
 224:     }
 225:     pos += ld2;
 226: 
 227:     if (dp >= ep) {
 228:         register int    curlen = dp - pp;
 229: 
 230:         cp = (struct drop  *) realloc ((char *) pp,
 231:                             (unsigned) (len += MAXFOLDER) * sizeof *pp);
 232:         if (cp == NULL) {
 233:         if (noisy)
 234:             admonish (NULLCP, "unable to allocate drop storage");
 235:         free ((char *) pp);
 236:         return 0;
 237:         }
 238:         dp = cp + curlen, ep = (pp = cp) + len - 1;
 239:     }
 240:     }
 241: 
 242:     if (dp == pp)
 243:     free ((char *) pp);
 244:     else
 245:     *drops = pp;
 246:     return (dp - pp);
 247: }
 248: 
 249: /*  */
 250: 
 251: int mbx_write (mailbox, md, fp, id, pos, stop, mapping, noisy)
 252: char   *mailbox;
 253: register FILE *fp;
 254: int     md,
 255:     id,
 256:     mapping,
 257:     noisy;
 258: register long   pos,
 259:         stop;
 260: {
 261:     register int    i,
 262:                     j,
 263:                     size;
 264:     register long   start,
 265:                     off;
 266:     register char  *cp;
 267:     char    buffer[BUFSIZ];
 268: 
 269:     off = lseek (md, 0L, 1);
 270:     j = strlen (mmdlm1);
 271:     if (write (md, mmdlm1, j) != j)
 272:     return NOTOK;
 273:     start = lseek (md, 0L, 1);
 274:     size = 0;
 275: 
 276:     (void) fseek (fp, pos, 0);
 277:     while (fgets (buffer, sizeof buffer, fp) != NULL && pos < stop) {
 278:     i = strlen (buffer);
 279:     for (j = 0; (j = stringdex (mmdlm1, buffer)) >= 0; buffer[j]++)
 280:         continue;
 281:     for (j = 0; (j = stringdex (mmdlm2, buffer)) >= 0; buffer[j]++)
 282:         continue;
 283:     if (write (md, buffer, i) != i)
 284:         return NOTOK;
 285:     pos += (long) i;
 286:     if (mapping)
 287:         for (cp = buffer; i-- > 0; size++)
 288:         if (*cp++ == '\n')
 289:             size++;
 290:     }
 291: 
 292:     stop = lseek (md, 0L, 1);
 293:     j = strlen (mmdlm2);
 294:     if (write (md, mmdlm2, j) != j)
 295:     return NOTOK;
 296:     if (mapping)
 297:     (void) map_write (mailbox, md, id, start, stop, off, size, noisy);
 298: 
 299:     return OK;
 300: }
 301: 
 302: /*  */
 303: 
 304: int     mbx_copy (mailbox, md, fd, mapping, text, noisy)
 305: char   *mailbox;
 306: int     md,
 307:         fd,
 308:     mapping,
 309:     noisy;
 310: char   *text;
 311: {
 312:     register int    i,
 313:                     j,
 314:                     size;
 315:     register long   start,
 316:                     stop,
 317:                     pos;
 318:     register char  *cp;
 319:     char    buffer[BUFSIZ];
 320:     register FILE  *fp;
 321: 
 322:     pos = lseek (md, 0L, 1);
 323:     size = 0;
 324: 
 325:     switch (mbx_style) {
 326:     case MMDF:
 327:     default:
 328:         j = strlen (mmdlm1);
 329:         if (write (md, mmdlm1, j) != j)
 330:         return NOTOK;
 331:         start = lseek (md, 0L, 1);
 332: 
 333:         if (text) {
 334:         i = strlen (text);
 335:         if (write (md, text, i) != i)
 336:             return NOTOK;
 337:         for (cp = buffer; *cp++; size++)
 338:             if (*cp == '\n')
 339:             size++;
 340:         }
 341: 
 342:         while ((i = read (fd, buffer, sizeof buffer)) > 0) {
 343:         for (j = 0;
 344:             (j = stringdex (mmdlm1, buffer)) >= 0;
 345:             buffer[j]++)
 346:             continue;
 347:         for (j = 0;
 348:             (j = stringdex (mmdlm2, buffer)) >= 0;
 349:             buffer[j]++)
 350:             continue;
 351:         if (write (md, buffer, i) != i)
 352:             return NOTOK;
 353:         if (mapping)
 354:             for (cp = buffer; i-- > 0; size++)
 355:             if (*cp++ == '\n')
 356:                 size++;
 357:         }
 358: 
 359:         stop = lseek (md, 0L, 1);
 360:         j = strlen (mmdlm2);
 361:         if (write (md, mmdlm2, j) != j)
 362:         return NOTOK;
 363:         if (mapping)
 364:         (void) map_write (mailbox, md, 0, start, stop, pos, size, noisy);
 365: 
 366:         return (i != NOTOK ? OK : NOTOK);
 367: 
 368:     case UUCP:      /* I hate this... */
 369:         if ((j = dup (fd)) == NOTOK)
 370:         return NOTOK;
 371:         if ((fp = fdopen (j, "r")) == NULL) {
 372:         (void) close (j);
 373:         return NOTOK;
 374:         }
 375:         start = lseek (md, 0L, 1);
 376: 
 377:         if (text) {
 378:         i = strlen (text);
 379:         if (write (md, text, i) != i)
 380:             return NOTOK;
 381:         for (cp = buffer; *cp++; size++)
 382:             if (*cp == '\n')
 383:             size++;
 384:         }
 385: 
 386:         for (j = 0; fgets (buffer, sizeof buffer, fp) != NULL; j++) {
 387:         if (j != 0 && strncmp (buffer, "From ", 5) == 0) {
 388:             (void) write (fd, ">", 1);
 389:             size++;
 390:         }
 391:         i = strlen (buffer);
 392:         if (write (md, buffer, i) != i) {
 393:             (void) fclose (fp);
 394:             return NOTOK;
 395:         }
 396:         if (mapping)
 397:             for (cp = buffer; i-- > 0; size++)
 398:             if (*cp++ == '\n')
 399:                 size++;
 400:         }
 401: 
 402:         (void) fclose (fp);
 403:         (void) lseek (fd, 0L, 2);
 404:         stop = lseek (md, 0L, 1);
 405:         if (mapping)
 406:         (void) map_write (mailbox, md, 0, start, stop, pos, size,
 407:                 noisy);
 408: 
 409:         return OK;
 410:     }
 411: }
 412: 
 413: /*  */
 414: 
 415: int mbx_size (md, start, stop)
 416: int md;
 417: long    start,
 418:     stop;
 419: {
 420:     register int    i,
 421:                     fd;
 422:     register long   pos;
 423:     register FILE  *fp;
 424: 
 425:     if ((fd = dup (md)) == NOTOK || (fp = fdopen (fd, "r")) == NULL) {
 426:     if (fd != NOTOK)
 427:         (void) close (fd);
 428:     return NOTOK;
 429:     }
 430: 
 431:     (void) fseek (fp, start, 0);
 432:     for (i = 0, pos = stop - start; pos-- > 0; i++)
 433:     if (fgetc (fp) == '\n')
 434:         i++;
 435: 
 436:     (void) fclose (fp);
 437: 
 438:     return i;
 439: }
 440: 
 441: /*  */
 442: 
 443: int     mbx_close (mailbox, md)
 444: char   *mailbox;
 445: int     md;
 446: {
 447:     (void) lkclose (md, mailbox);
 448: 
 449:     return OK;
 450: }
 451: 
 452: /*  */
 453: 
 454: /* This function is performed implicitly by getbbent.c:
 455: 
 456: 		bb -> bb_map = map_name (bb -> bb_file);
 457: */
 458: 
 459: char    *map_name (file)
 460: register char   *file;
 461: {
 462:     register char  *cp,
 463:                    *dp;
 464:     static char buffer[BUFSIZ];
 465: 
 466:     if ((dp = index (cp = r1bindex (file, '/'), '.')) == NULL)
 467:     dp = cp + strlen (cp);
 468:     if (cp == file)
 469:     (void) sprintf (buffer, ".%.*s%s", dp - cp, cp, ".map");
 470:     else
 471:     (void) sprintf (buffer, "%.*s.%.*s%s", cp - file, file, dp - cp,
 472:         cp, ".map");
 473: 
 474:     return buffer;
 475: }
 476: 
 477: /*  */
 478: 
 479: int map_read (file, pos, drops, noisy)
 480: char   *file;
 481: long    pos;
 482: struct drop **drops;
 483: int noisy;
 484: {
 485:     register int    i,
 486:                     md,
 487:                     msgp;
 488:     register char  *cp;
 489:     struct drop d;
 490:     register struct drop   *mp,
 491:                            *dp;
 492: 
 493:     if ((md = open (cp = map_name (file), 0)) == NOTOK
 494:         || map_chk (cp, md, mp = &d, pos, noisy)) {
 495:     if (md != NOTOK)
 496:         (void) close (md);
 497:     return 0;
 498:     }
 499: 
 500:     msgp = mp -> d_id;
 501:     dp = (struct drop  *) calloc ((unsigned) msgp, sizeof *dp);
 502:     if (dp == NULL) {
 503:     (void) close (md);
 504:     return 0;
 505:     }
 506: 
 507:     (void) lseek (md, (long) sizeof *mp, 0);
 508:     if ((i = read (md, (char *) dp, msgp * sizeof *dp)) < sizeof *dp) {
 509:     i = 0;
 510:     free ((char *) dp);
 511:     }
 512:     else
 513:     *drops = dp;
 514: 
 515:     (void) close (md);
 516: 
 517:     return (i / sizeof *dp);
 518: }
 519: 
 520: /*  */
 521: 
 522: int     map_write (mailbox, md, id, start, stop, pos, size, noisy)
 523: register char   *mailbox;
 524: int     md,
 525:         id,
 526:     size,
 527:     noisy;
 528: long    start,
 529:         stop,
 530:         pos;
 531: {
 532:     register int    i;
 533:     int     clear,
 534:             fd,
 535:             td;
 536:     char   *file;
 537:     register struct drop   *dp;
 538:     struct drop    d1,
 539:            d2,
 540:                   *rp;
 541:     register FILE *fp;
 542: 
 543:     if ((fd = map_open (file = map_name (mailbox), &clear, md)) == NOTOK)
 544:     return NOTOK;
 545: 
 546:     if (!clear && map_chk (file, fd, &d1, pos, noisy)) {
 547:     (void) unlink (file);
 548:     (void) mbx_close (file, fd);
 549:     if ((fd = map_open (file, &clear, md)) == NOTOK)
 550:         return NOTOK;
 551:     clear++;
 552:     }
 553: 
 554:     if (clear) {
 555:     if ((td = dup (md)) == NOTOK || (fp = fdopen (td, "r")) == NULL) {
 556:         if (noisy)
 557:         admonish (file, "unable to %s", td != NOTOK ? "fdopen" : "dup");
 558:         if (td != NOTOK)
 559:         (void) close (td);
 560:         (void) mbx_close (file, fd);
 561:         return NOTOK;
 562:     }
 563: 
 564:     switch (i = mbx_read (fp, 0L, &rp, noisy)) {
 565:         case NOTOK:
 566:         (void) fclose (fp);
 567:         (void) mbx_close (file, fd);
 568:         return NOTOK;
 569: 
 570:         case OK:
 571:         break;
 572: 
 573:         default:
 574:         d1.d_id = 0;
 575:         for (dp = rp; i-- >0; dp++) {
 576:             if (dp -> d_start == start)
 577:             dp -> d_id = id;
 578:             (void) lseek (fd, (long) (++d1.d_id * sizeof *dp), 0);
 579:             if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
 580:             if (noisy)
 581:                 admonish (file, "write error");
 582:             (void) mbx_close (file, fd);
 583:             (void) fclose (fp);
 584:             return NOTOK;
 585:             }
 586:         }
 587:         free ((char *) rp);
 588:         break;
 589:     }
 590:     }
 591:     else {
 592:     dp = &d2;
 593:     dp -> d_id = id;
 594:     dp -> d_size = size ? size : mbx_size (fd, start, stop);
 595:     dp -> d_start = start;
 596:     dp -> d_stop = stop;
 597:     (void) lseek (fd, (long) (++d1.d_id * sizeof *dp), 0);
 598:     if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
 599:         if (noisy)
 600:         admonish (file, "write error");
 601:         (void) mbx_close (file, fd);
 602:         return NOTOK;
 603:     }
 604:     }
 605: 
 606:     dp = &d1;
 607:     dp -> d_size = DRVRSN;
 608:     dp -> d_start = DRMAGIC;
 609:     dp -> d_stop = lseek (md, 0L, 1);
 610:     (void) lseek (fd, 0L, 0);
 611:     if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
 612:     if (noisy)
 613:         admonish (file, "write error");
 614:     (void) mbx_close (file, fd);
 615:     return NOTOK;
 616:     }
 617: 
 618:     (void) mbx_close (file, fd);
 619: 
 620:     return OK;
 621: }
 622: 
 623: /*  */
 624: 
 625: static int  map_open (file, clear, md)
 626: char   *file;
 627: int    *clear,
 628:     md;
 629: {
 630:     int     mode;
 631:     struct  stat st;
 632: 
 633:     mode = fstat (md, &st) != NOTOK ? (int) (st.st_mode & 0777) : m_gmprot ();
 634:     return mbx_Xopen (file, st.st_uid, st.st_gid, mode, clear);
 635: }
 636: 
 637: /*  */
 638: 
 639: int  map_chk (file, fd, dp, pos, noisy)
 640: char   *file;
 641: int     fd,
 642:     noisy;
 643: register struct drop *dp;
 644: long    pos;
 645: {
 646:     long    count;
 647:     struct drop d;
 648:     register struct drop    *dl;
 649: 
 650:     if (read (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
 651: #ifdef  notdef
 652:     admonish (NULLCP, "%s: missing or partial index", file);
 653: #endif	notdef
 654:     return NOTOK;
 655:     }
 656:     if (dp -> d_size != DRVRSN) {
 657:     if (noisy)
 658:         admonish (NULLCP, "%s: version mismatch", file);
 659:     return NOTOK;
 660:     }
 661:     if (dp -> d_start != DRMAGIC) {
 662:     if (noisy)
 663:         admonish (NULLCP, "%s: bad magic number", file);
 664:     return NOTOK;
 665:     }
 666:     if (dp -> d_stop != pos) {
 667:     if (noisy && pos != 0L)
 668:         admonish (NULLCP,
 669:             "%s: pointer mismatch or incomplete index (%ld!=%ld)",
 670:             file, dp -> d_stop, pos);
 671:     return NOTOK;
 672:     }
 673: 
 674:     if ((long) ((dp -> d_id + 1) * sizeof *dp) != lseek (fd, 0L, 2)) {
 675:     if (noisy)
 676:         admonish (NULLCP, "%s: corrupt index(1)", file);
 677:     return NOTOK;
 678:     }
 679: 
 680:     dl = &d;
 681:     count = (long) strlen (mmdlm2);
 682:     (void) lseek (fd, (long) (dp -> d_id * sizeof *dp), 0);
 683:     if (read (fd, (char *) dl, sizeof *dl) != sizeof *dl
 684:         || (dl -> d_stop != dp -> d_stop
 685:         && dl -> d_stop + count != dp -> d_stop)) {
 686:     if (noisy)
 687:         admonish (NULLCP, "%s: corrupt index(2)", file);
 688:     return NOTOK;
 689:     }
 690: 
 691:     return OK;
 692: }

Defined functions

map_chk defined in line 639; used 3 times
map_name defined in line 459; used 8 times
map_open defined in line 625; used 2 times
map_read defined in line 479; used 1 times
map_write defined in line 522; used 4 times
mbx_Xopen defined in line 85; used 4 times
mbx_chk defined in line 147; used 1 times
  • in line 66
mbx_create defined in line 128; used 1 times
mbx_mmdf defined in line 33; never used
mbx_read defined in line 170; used 2 times
mbx_size defined in line 415; used 1 times
mbx_uucp defined in line 41; used 1 times
mbx_write defined in line 251; used 1 times

Defined variables

mbx_style defined in line 23; used 6 times

Defined macros

MMDF defined in line 18; used 2 times
UUCP defined in line 19; used 1 times
  • in line 44
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1976
Valid CSS Valid XHTML 1.0 Strict