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