]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/RCS/bbc.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / RCS / bbc.c,v
1 head 2.13;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 2.13
9 date 93.02.26.21.58.57; author jromine; state Exp;
10 branches;
11 next 2.12;
12
13 2.12
14 date 92.12.14.17.10.25; author jromine; state Exp;
15 branches;
16 next 2.11;
17
18 2.11
19 date 92.11.24.18.34.21; author jromine; state Exp;
20 branches;
21 next 2.10;
22
23 2.10
24 date 92.11.11.22.04.17; author jromine; state Exp;
25 branches;
26 next 2.9;
27
28 2.9
29 date 92.11.04.00.39.01; author jromine; state Exp;
30 branches;
31 next 2.8;
32
33 2.8
34 date 92.05.12.21.55.14; author jromine; state Exp;
35 branches;
36 next 2.7;
37
38 2.7
39 date 92.02.10.19.57.26; author jromine; state Exp;
40 branches;
41 next 2.6;
42
43 2.6
44 date 92.02.10.18.12.35; author jromine; state Exp;
45 branches;
46 next 2.5;
47
48 2.5
49 date 90.04.05.14.56.21; author sources; state Exp;
50 branches;
51 next 2.4;
52
53 2.4
54 date 90.03.12.14.01.42; author sources; state Exp;
55 branches;
56 next 2.3;
57
58 2.3
59 date 90.02.08.14.22.47; author sources; state Exp;
60 branches;
61 next 2.2;
62
63 2.2
64 date 90.02.05.14.23.59; author sources; state Exp;
65 branches;
66 next 2.1;
67
68 2.1
69 date 90.01.10.10.49.19; author sources; state Exp;
70 branches;
71 next 2.0;
72
73 2.0
74 date 89.11.17.16.02.21; author sources; state Exp;
75 branches;
76 next 1.5;
77
78 1.5
79 date 89.09.22.13.50.35; author sources; state Exp;
80 branches;
81 next 1.4;
82
83 1.4
84 date 89.09.22.13.48.40; author sources; state Exp;
85 branches;
86 next 1.3;
87
88 1.3
89 date 89.09.20.10.36.27; author sources; state Exp;
90 branches;
91 next 1.2;
92
93 1.2
94 date 89.06.02.12.56.11; author sources; state Exp;
95 branches;
96 next 1.1;
97
98 1.1
99 date 89.05.05.19.41.14; author sources; state Exp;
100 branches;
101 next ;
102
103
104 desc
105 @@
106
107
108 2.13
109 log
110 @TYPESIG
111 @
112 text
113 @/* bbc.c - ZOTnet BBoard checker */
114 #ifndef lint
115 static char ident[] = "@@(#)$Id: bbc.c,v 2.12 1992/12/14 17:10:25 jromine Exp jromine $";
116 #endif lint
117
118 #include "../h/mh.h"
119 #include "../zotnet/bboards.h"
120 #include <stdio.h>
121 #ifdef BPOP
122 #include "../zotnet/mts.h"
123 #endif BPOP
124 #include <errno.h>
125 #include <signal.h>
126 #ifndef sigmask
127 #define sigmask(s) (1 << ((s) - 1))
128 #endif not sigmask
129 #ifdef ridge
130 #undef SIGTSTP
131 #endif ridge
132 #include <sys/types.h>
133 #include <sys/stat.h>
134 #ifdef SIGTSTP
135 #include <sys/wait.h>
136 #include <sys/time.h>
137 #include <sys/resource.h>
138 #endif SIGTSTP
139 #ifdef LOCALE
140 #include <locale.h>
141 #endif
142
143 #define RCFILE ".bbrc"
144
145 #define NBB 100
146
147 /* \f */
148
149 static struct swit switches[] = {
150 #define TOPICSW 0
151 "topics", 6,
152 #define CHECKSW 1
153 "check", 5,
154 #define READSW 2
155 "read", 4,
156
157 #define QUIETSW 3
158 "quiet", 4,
159 #define VERBOSW 4
160 "verbose", 4,
161
162 #define ARCHSW 5
163 "archive", 4,
164 #define NOARCH 6
165 "noarchive", 3,
166
167 #define PROTSW 7
168 "protocol", 4,
169 #define NPROTSW 8
170 "noprotocol", 3,
171
172 #define PROGSW 9
173 "mshproc program", 4,
174
175 #define RCSW 10
176 "rcfile rcfile", 4,
177 #define NRCSW 11
178 "norcfile", 3,
179
180 #define FILESW 12
181 "file BBoardsfile", 4,
182 #define USERSW 13
183 "user BBoardsuser",
184 #ifndef NNTP
185 4,
186 #else NNTP
187 -4,
188 #endif NNTP
189
190 #define HOSTSW 14
191 "host host",
192 #ifndef BPOP
193 -4,
194 #else BPOP
195 4,
196 #endif BPOP
197 #define RPOPSW 15
198 "rpop",
199 #ifndef RPOP
200 -4,
201 #else RPOP
202 4,
203 #endif RPOP
204 #define NRPOPSW 16
205 "norpop",
206 #ifndef RPOP
207 -6,
208 #else RPOP
209 6,
210 #endif RPOP
211
212 #define HELPSW 17
213 "help", 4,
214
215 NULL, NULL
216 };
217
218 struct bbcount {
219 char *key;
220 int count;
221 struct bbcount *left;
222 struct bbcount *right;
223 };
224
225 /* \f */
226
227 extern int errno;
228
229 static int changed = 0;
230 static int oops = 0;
231 static int quitting = 0;
232
233 static int archivesw = 0;
234 static int checksw = 0;
235 static int protsw = 1;
236 static int quietsw = 0;
237 static int readsw = 0;
238 static int topicsw = 0;
239 static int verbosw = 0;
240
241 static int didpop = OK;
242 static int rpop = 1;
243 static char *user = BBOARDS;
244 static char *host = NULL;
245 #ifdef BPOP
246 extern char response[];
247
248 extern char *getusr ();
249 static char **getip ();
250 #endif BPOP
251
252 TYPESIG sigser (), hupser ();
253 int action ();
254 #ifdef SIGTSTP
255 int tstpid;
256 static TYPESIG tstpser ();
257 #endif SIGTSTP
258
259 static char *rcfile=NULL;
260
261
262 static struct bbcount *bbc = NULL;
263 static struct bboard *bbl = NULL;
264
265 struct bbcount *add_count (), *seek_count ();
266 struct bboard *getbbaux (), *getbbvis ();
267 static void bbreset();
268
269 #ifdef UCL
270 extern char *bbs[];
271 extern int called_bbc;
272 static int bbp;
273 #endif UCL
274 /* \f */
275
276 /* ARGSUSED */
277
278 main (argc, argv)
279 int argc;
280 char **argv;
281 {
282 #ifndef UCL
283 int bbp = 0,
284 vecp = 1;
285 #else UCL
286 int vecp = 1;
287 #endif UCL
288 char *cp,
289 *rc=NULL,
290 **ap,
291 **argp,
292 buffer[80],
293 *arguments[MAXARGS],
294 #ifndef UCL
295 *bbs[NBB + 1],
296 #endif UCL
297 *vec[MAXARGS];
298 #ifdef UCL
299 called_bbc = 1;
300 bbp = 0;
301 #endif UCL
302
303 #ifdef LOCALE
304 setlocale(LC_ALL, "");
305 #endif
306 invo_name = r1bindex (argv[0], '/');
307 #ifdef BPOP
308 mts_init (invo_name);
309 if (popbbhost && *popbbhost)
310 host = popbbhost;
311 if (popbbuser && *popbbuser)
312 user = popbbuser, rpop = 0;
313 #endif BPOP
314 if ((cp = m_find (invo_name)) != NULL) {
315 ap = brkstring (cp = getcpy (cp), " ", "\n");
316 ap = copyip (ap, arguments);
317 }
318 else
319 ap = arguments;
320 (void) copyip (argv + 1, ap);
321 argp = arguments;
322
323 (void) setbbent (SB_STAY);
324
325 /* \f */
326
327 while (cp = *argp++) {
328 if (*cp == '-')
329 switch (smatch (++cp, switches)) {
330 case AMBIGSW:
331 ambigsw (cp, switches);
332 done (1);
333 case UNKWNSW:
334 vec[vecp++] = --cp;
335 continue;
336 case HELPSW:
337 (void) sprintf (buffer,
338 "%s [bboards ...] [switches] [switches for mshproc]",
339 invo_name);
340 help (buffer, switches);
341 done (1);
342
343 case TOPICSW:
344 topicsw++;
345 checksw = readsw = 0;
346 continue;
347 case CHECKSW:
348 checksw++;
349 readsw = topicsw = 0;
350 continue;
351 case READSW:
352 readsw++;
353 checksw = topicsw = 0;
354 continue;
355
356 case ARCHSW:
357 archivesw++;
358 continue;
359 case NOARCH:
360 archivesw = 0;
361 continue;
362
363 case PROTSW:
364 protsw++;
365 continue;
366 case NPROTSW:
367 protsw = 0;
368 continue;
369
370 case QUIETSW:
371 quietsw++;
372 verbosw = 0;
373 continue;
374 case VERBOSW:
375 verbosw++;
376 quietsw = 0;
377 continue;
378
379 case PROGSW:
380 if (!(mshproc = *argp++) || *mshproc == '-')
381 adios (NULLCP, "missing argument to %s", argp[-2]);
382 continue;
383
384 case RCSW:
385 if (!(rc = *argp++) || *rc == '-')
386 adios (NULLCP, "missing argument to %s", argp[-2]);
387 continue;
388 case NRCSW:
389 rc = NULL;
390 continue;
391
392 case FILESW:
393 if (!(cp = *argp++) || *cp == '-')
394 adios (NULLCP, "missing argument to %s", argp[-2]);
395 if (!setbbinfo (user, cp, 1))
396 adios (NULLCP, "setbbinfo(%s, %s, 1) failed -- %s",
397 user, cp, getbberr ());
398 continue;
399 case USERSW:
400 if (!(user = *argp++) || *user == '-')
401 adios (NULLCP, "missing argument to %s", argp[-2]);
402 continue;
403
404 case HOSTSW:
405 if (!(host = *argp++) || *host == '-')
406 adios (NULLCP, "missing argument to %s", argp[-2]);
407 didpop = NOTOK;
408 continue;
409 case RPOPSW:
410 rpop++;
411 continue;
412 case NRPOPSW:
413 rpop = 0;
414 continue;
415 }
416 if (bbp < NBB)
417 bbs[bbp++] = cp;
418 else
419 adios (NULLCP, "too many bboards, starting with %s", cp);
420 }
421 bbs[bbp] = NULL;
422
423 /* \f */
424
425 #ifdef BPOP
426 if (host && !*host)
427 host = NULL, didpop = OK;
428 if (!host || !rpop)
429 (void) setuid (getuid ());
430 #endif BPOP
431
432 if (!m_find ("path"))
433 free (path ("./", TFOLDER));
434
435 rcinit (rc);
436
437 for (bbp = 0; cp = bbs[bbp]; bbp++)
438 add_bb (cp, NOTOK);
439
440 #ifdef UCL
441 if (topicsw) {
442 called_bbc = 0;
443 topics ();
444 }
445 #else
446 if (topicsw)
447 topics ();
448 #endif
449 else {
450 default_bboards ();
451 if (checksw)
452 check ();
453 else
454 process (vecp, vec);
455 }
456
457 #ifdef BPOP
458 if (didpop != OK && pop_quit () == NOTOK)
459 adios (NULLCP, "%s", response);
460 #endif BPOP
461
462 done (0);
463 }
464
465 /* \f */
466
467 topics () {
468 register char *cp,
469 **ap;
470 register struct bboard *bb;
471
472 printf ("%16s %s %s\n", "BBoard", "Items",
473 verbosw ? "Interesting Facts" : "Last Update");
474 printf ("%16s %s %s\n", "------", "-----",
475 verbosw ? "-----------------" : "-----------");
476
477 for (bb = bbl ? bbl : getbbvis ();
478 bb;
479 bb = bbl ? bb -> bb_link : getbbvis ()) {
480 printf ("%16s %5d %s\n",
481 bb -> bb_name, bb -> bb_maxima,
482 bb -> bb_date ? bb -> bb_date : "no deliveries");
483 if (verbosw) {
484 if (*bb -> bb_aka) {
485 cp = NULL;
486 for (ap = bb -> bb_aka; *ap; ap++)
487 cp = add (*ap, cp ? add (", ", cp) : cp);
488 printv ("AKA", cp);
489 free (cp);
490 }
491
492 printv ("Leaders", *bb -> bb_leader);
493 for (ap = bb -> bb_leader + 1; *ap; ap++)
494 printv (NULLCP, *ap);
495 printv ("File", bb -> bb_file);
496 printv ("Archive", bb -> bb_archive);
497 printv ("Info", bb -> bb_info);
498 printv ("Map", bb -> bb_map);
499 printv ("Password", bb -> bb_passwd);
500 if (strcmp (bb -> bb_name, bb -> bb_addr))
501 printv ("Address", bb -> bb_addr);
502 if (strcmp (*bb -> bb_leader, bb -> bb_request))
503 printv ("Request", bb -> bb_request);
504 if (*bb -> bb_relay)
505 printv ("Relay", bb -> bb_relay);
506 if (*bb -> bb_dist) {
507 changed = 0;
508 (void) getbbdist (bb, action);
509 if (!changed)
510 printv ("Dist", "");
511 if (cp = getbberr ())
512 printv ("Error", cp);
513 }
514 printb (bb -> bb_flags & ~BB_SEEN);
515 }
516 }
517 }
518
519 /* \f */
520
521 printv (key, value)
522 register char *key,
523 *value;
524 {
525 char buffer[BUFSIZ];
526
527 if (key)
528 (void) sprintf (buffer, "%s: ", key);
529 else
530 buffer[0] = '\0';
531 printf ("%*s%-*s", 25, "", 10, buffer);
532 if (value && *value)
533 printf ("%s", value);
534 (void) putchar ('\n');
535 }
536
537
538 int action (local, domain)
539 register char *local,
540 *domain;
541 {
542 char buffer[BUFSIZ];
543
544 (void) sprintf (buffer, "%s@@%s", local, domain);
545 printv (changed++ ? NULL : "Dist", buffer);
546 return 0;
547 }
548
549
550 printb (flags)
551 unsigned int flags;
552 {
553 char buffer[BUFSIZ];
554
555 printv ("Flags", sprintb (buffer, flags, BBITS));
556 }
557
558 /* \f */
559
560 check () {
561 #define grammar(a,b,c) (a == 1 ? b : c)
562 #define plural(d) grammar(d, "", "s")
563
564 int diff;
565 register struct bboard *bb;
566
567 for (bb = bbl; bb; bb = bb -> bb_link) {
568 diff = bb -> bb_maxima - bb -> bb_count;
569 if (quietsw) {
570 if (diff > 0)
571 printf ("%s -- %d item%s unseen\n",
572 bb -> bb_name, diff, plural (diff));
573 }
574 else
575 if (bb -> bb_maxima == 0)
576 printf ("%s -- empty\n", bb -> bb_name);
577 else
578 if (bb -> bb_count == 0)
579 printf ("%s -- %d item%sseen)\n",
580 bb -> bb_name, bb -> bb_maxima,
581 grammar (bb -> bb_maxima, " (un", "s (none "));
582 else
583 if (diff <= 0)
584 printf ("%s -- %d item%s (all seen)\n",
585 bb -> bb_name, bb -> bb_maxima,
586 plural (bb -> bb_maxima));
587 else
588 printf ("%s -- %d item%s unseen\n",
589 bb -> bb_name, diff, plural (diff));
590 }
591 }
592
593 /* \f */
594
595 process (vecp, vec)
596 int vecp;
597 char *vec[];
598 {
599 int diff;
600 #ifdef SIGTSTP
601 TYPESIG (*tstat) ();
602 #endif SIGTSTP
603 register struct bboard *bb;
604
605 vec[0] = r1bindex (mshproc, '/');
606 #ifdef SIGTSTP
607 tstat = signal (SIGTSTP, tstpser);
608 #endif SIGTSTP
609
610 for (bb = bbl; bb && !quitting; bb = bb -> bb_link) {
611 diff = bb -> bb_maxima - bb -> bb_count;
612 if (bb -> bb_maxima == 0) {
613 if (!quietsw)
614 printf ("%s -- empty\n", bb -> bb_name);
615 continue;
616 }
617 else {
618 if (diff < 0) {
619 printf (
620 "Oops! looks like someone reset %s -- assuming all unseen\n",
621 bb -> bb_name);
622 diff = bb -> bb_maxima;
623 bbreset (bb, 0);
624 }
625 if (verbosw || archivesw || diff > 0)
626 bbread (bb, vecp, vec);
627 else
628 if (!quietsw)
629 printf ("%s -- %d item%s (all seen)\n",
630 bb -> bb_name, bb -> bb_maxima,
631 plural (bb -> bb_maxima));
632 }
633 };
634
635 #ifdef SIGTSTP
636 (void) signal (SIGTSTP, tstat);
637 #endif SIGTSTP
638 rcend ();
639 }
640
641 /* \f */
642
643 #ifdef BPOP
644 /* ARGSUSED */
645
646 static int xtnd1 (s)
647 char *s;
648 {
649 return OK;
650 }
651 #endif BPOP
652
653 /* \f */
654
655 bbread (bb, vecp, vec)
656 register struct bboard *bb;
657 int vecp;
658 char *vec[];
659 {
660 int child_id,
661 pd[2];
662 char buf1[BUFSIZ],
663 buf2[BUFSIZ],
664 buf3[BUFSIZ];
665 #ifdef BPOP
666 int nmsgs,
667 nbytes;
668 char buf4[BUFSIZ],
669 buf5[BUFSIZ];
670 #endif BPOP
671 struct stat st;
672
673 #ifdef BPOP
674 if (bb -> bb_flags & BB_REMOTE) {
675 if (pop_xtnd (xtnd1, "%s %s", archivesw ? "archive" : "bboards",
676 bb -> bb_name) == NOTOK) {
677 advise (NULLCP, "%s", response);
678 return;
679 }
680 if (pop_stat (&nmsgs, &nbytes) == NOTOK)
681 adios (NULLCP, "%s", response);
682 if (nmsgs == 0) {
683 if (verbosw)
684 printf ("%s -- empty\n", bb -> bb_name);
685 return;
686 }
687 if (pop_fd (buf4, buf5) == NOTOK)
688 adios (NULLCP, "%s", response);
689 }
690 else
691 #endif BPOP
692 if (stat (archivesw ? bb -> bb_archive : bb -> bb_file, &st) != NOTOK
693 && st.st_size == 0)
694 return;
695
696 if (protsw) {
697 if (pipe (pd) == NOTOK)
698 adios ("pipe", "unable to");
699 (void) sprintf (buf3, "%d", getpid ());
700 }
701
702 switch (child_id = fork ()) {
703 case NOTOK:
704 adios ("fork", "unable to");
705
706 case OK:
707 if (protsw) {
708 (void) close (pd[0]);
709 (void) sprintf (buf1, "%d", bb -> bb_count + 1);
710 (void) sprintf (buf2, "%d", pd[1]);
711 vec[vecp++] = "-idname";
712 vec[vecp++] = bb -> bb_name;
713 vec[vecp++] = "-idstart";
714 vec[vecp++] = buf1;
715 vec[vecp++] = "-idstop";
716 vec[vecp++] = buf2;
717 vec[vecp++] = "-idquit";
718 vec[vecp++] = buf3;
719 }
720 #ifdef BPOP
721 if (bb -> bb_flags & BB_REMOTE) {
722 vec[vecp++] = "-popread";
723 vec[vecp++] = buf4;
724 vec[vecp++] = "-popwrite";
725 vec[vecp++] = buf5;
726 }
727 #endif BPOP
728 vec[vecp++] = archivesw ? bb -> bb_archive : bb -> bb_file;
729 vec[vecp] = NULL;
730 execvp (mshproc, vec);
731 fprintf (stderr, "unable to exec ");
732 perror (mshproc);
733 _exit (-1);
734
735 default:
736 #ifdef SIGTSTP
737 tstpid = child_id;
738 #endif SIGTSTP
739 if (protsw) {
740 (void) close (pd[1]);
741 pgmread (pd[0], child_id, bb);
742 }
743 else
744 (void) pidXwait (child_id, mshproc);
745 }
746 }
747
748 /* \f */
749
750 pgmread (pd, child_id, bb)
751 int pd,
752 child_id;
753 register struct bboard *bb;
754 {
755 int i,
756 j,
757 n;
758 TYPESIG (*estat) (), (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
759 char buffer[BUFSIZ];
760 struct bbcount *selected;
761
762 estat = signal (SIGEMT, sigser);
763 hstat = signal (SIGHUP, hupser);
764 istat = signal (SIGINT, SIG_IGN);
765 qstat = signal (SIGQUIT, SIG_IGN);
766 tstat = signal (SIGTERM, sigser);
767
768 while ((n = read (pd, buffer, sizeof buffer)) == NOTOK && errno == EINTR)
769 continue;
770 (void) close (pd);
771 (void) pidXwait (child_id, mshproc);
772
773 (void) signal (SIGEMT, estat);
774 (void) signal (SIGHUP, hstat);
775 (void) signal (SIGINT, istat);
776 (void) signal (SIGQUIT, qstat);
777 (void) signal (SIGTERM, tstat);
778
779 if (n <= 0)
780 return;
781 if (sscanf (buffer, "%d %d", &i, &j) != 2 || i <= 0 || j <= 0)
782 return;
783
784 if ((selected = seek_count (bbc, bb -> bb_name)) == NULL) {
785 bbc = add_count (bbc, bb -> bb_name, i);
786 changed++;
787 }
788 else
789 if (archivesw) {
790 if (i > selected -> count) {
791 selected -> count = i;
792 changed++;
793 }
794 }
795 else {
796 if (bb -> bb_maxima > j && i >= j)/* bbl... */
797 i = bb -> bb_maxima;
798 if (i != selected -> count) {
799 selected -> count = i;
800 changed++;
801 }
802 }
803 }
804
805
806 /* ARGSUSED */
807
808 TYPESIG sigser (i)
809 int i;
810 {
811 #ifndef BSD42
812 (void) signal (i, sigser);
813 #endif not BSD42
814 quitting++;
815 }
816
817
818 /* ARGSUSED */
819
820 TYPESIG hupser (i)
821 int i;
822 {
823 static int armed = 0;
824
825 #ifndef BSD42
826 (void) signal (i, hupser);
827 #endif
828
829 if (!armed++) /* tick tock... */
830 alarm ((unsigned int) 30);
831 }
832
833 /* \f */
834
835 rcinit (rc)
836 register char *rc;
837 {
838 int state;
839 register char *cp;
840 char key[NAMESZ],
841 value[BUFSIZ];
842 register FILE *bbrc;
843
844 if ((cp = rc ? rc : getenv ("MHBBRC")) && *cp) {
845 rcfile = path (cp, TFILE);
846 if (*cp != '/')
847 (void) m_putenv ("MHBBRC", rcfile);
848 }
849 else
850 rcfile = concat (mypath, "/", RCFILE, NULLCP);
851
852 if ((bbrc = fopen (rcfile, "r")) == NULL)
853 if (cp && *cp)
854 adios (rcfile, "unable to read");
855 else
856 return;
857
858 for (state = FLD;;) {
859 switch (state = m_getfld (state, key, value, sizeof value, bbrc)) {
860 case FLD:
861 case FLDEOF:
862 make_lower (key, key);
863 bbc = add_count (bbc, key, atoi (value));
864 if (state == FLDEOF)
865 break;
866 continue;
867
868 default:
869 admonish (NULLCP, "bad format: %s", rcfile);
870 case FILEEOF:
871 break;
872 }
873
874 break;
875 }
876
877 if (ferror (bbrc) && !feof (bbrc))
878 admonish (rcfile, "error reading");
879 (void) fclose (bbrc);
880 }
881
882 /* \f */
883
884 rcend () {
885 TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
886 register FILE *bbrc;
887
888 if (!changed)
889 return;
890
891 hstat = signal (SIGHUP, SIG_IGN);
892 istat = signal (SIGINT, SIG_IGN);
893 qstat = signal (SIGQUIT, SIG_IGN);
894 tstat = signal (SIGTERM, SIG_IGN);
895
896 if ((bbrc = fopen (rcfile, "w")) == NULL)
897 adios (rcfile, "unable to write");
898 rcput (bbrc, bbc);
899
900 if (ferror (bbrc))
901 adios (rcfile, "error writing");
902 (void) fclose (bbrc);
903
904 (void) signal (SIGHUP, hstat);
905 (void) signal (SIGINT, istat);
906 (void) signal (SIGQUIT, qstat);
907 (void) signal (SIGTERM, tstat);
908
909 changed = 0;
910 }
911
912
913 rcput (bbrc, p)
914 register FILE *bbrc;
915 register struct bbcount *p;
916 {
917 if (p == NULL)
918 return;
919
920 fprintf (bbrc, "%s: %d\n", p -> key, p -> count);
921 rcput (bbrc, p -> left);
922 rcput (bbrc, p -> right);
923 }
924
925 /* \f */
926
927 #ifdef SIGTSTP
928 static TYPESIG tstpser (sig)
929 int sig;
930 {
931 int pid;
932 #if defined(BSD42) && !defined(WAITINT)
933 union wait w;
934 #else
935 int w;
936 #endif
937
938 rcend ();
939
940 #ifdef SVR4
941 waitpid(tstpid, &w, WUNTRACED);
942 #else
943 while ((pid = wait3 (&w, WUNTRACED, (struct rusage *) 0)) != NOTOK
944 && pid != tstpid)
945 continue;
946 #endif
947
948 (void) signal (SIGTSTP, SIG_DFL);
949 #ifdef BSD42
950 (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
951 #endif BSD42
952
953 (void) kill (getpid (), sig);
954
955 #ifdef BSD42
956 (void) sigblock (sigmask (SIGTSTP));
957 #endif BSD42
958 (void) signal (SIGTSTP, tstpser);
959 }
960 #endif SIGTSTP
961
962 /* \f */
963 static void bbreset (bb, i)
964 register struct bboard *bb;
965 int i;
966 {
967 struct bbcount *selected;
968
969 bb -> bb_count = i;
970 if ((selected = seek_count (bbc, bb -> bb_name)) == NULL)
971 bbc = add_count (bbc, bb -> bb_name, i);
972 else
973 selected -> count = i;
974
975 changed++;
976 }
977
978 struct bbcount *add_count (p, w, i)
979 register struct bbcount *p;
980 register char *w;
981 int i;
982 {
983 int cond;
984
985 if (p == NULL) {
986 p = (struct bbcount *) malloc (sizeof *p);
987 if (p == NULL)
988 adios (NULLCP,"insufficient memory");
989 p -> key = getcpy (w);
990 p -> count = i;
991 p -> left = p -> right = NULL;
992 }
993 else
994 if ((cond = strcmp (w, p -> key)) < 0)
995 p -> left = add_count (p -> left, w, i);
996 else
997 if (cond > 0)
998 p -> right = add_count (p -> right, w, i);
999
1000 return p;
1001 }
1002
1003
1004 struct bbcount *seek_count (p, w)
1005 register struct bbcount *p;
1006 register char *w;
1007 {
1008 int cond;
1009
1010 if (p == NULL || (cond = strcmp (w, p -> key)) == 0)
1011 return p;
1012 else
1013 return seek_count (cond < 0 ? p -> left : p -> right, w);
1014 }
1015
1016 /* \f */
1017
1018 default_bboards () {
1019 register char *cp,
1020 **ap;
1021 #ifdef UCL
1022 register int i = bbp;
1023 #endif UCL
1024
1025 if (bbl != NULL)
1026 return;
1027
1028 if (!archivesw && ((cp = m_find ("bboards")) != NULL)) {
1029 #ifndef BPOP
1030 for (ap = brkstring (cp = getcpy (cp), " ", "\n"); *ap; ap++)
1031 #else BPOP
1032 for (ap = getip (cp); *ap; ap++)
1033 #endif BPOP
1034 #ifndef UCL
1035 add_bb (*ap, OK);
1036 #else UCL
1037 bbs[bbp++] = *ap;
1038 bbs[bbp] = NULL;
1039 while (i < bbp)
1040 add_bb (bbs[i++], OK);
1041 #endif UCL
1042 #ifndef BPOP
1043 free (cp);
1044 #endif not BPOP
1045 if (oops)
1046 advise (NULLCP, "please fix the %s: entry in your %s file",
1047 "bboards", mh_profile);
1048 }
1049 else {
1050 #ifdef UCL
1051 bbs[bbp++] = "system";
1052 bbs[bbp] = NULL;
1053 #endif UCL
1054 #ifndef NNTP
1055 add_bb ("system", NOTOK);
1056 #else NNTP
1057 add_bb ("general", NOTOK);
1058 #ifdef UCI
1059 add_bb ("ics.system", NOTOK);
1060 add_bb ("ics.general", NOTOK);
1061 #endif UCI
1062 #endif NNTP
1063 }
1064 #ifdef UCL
1065 bbs[bbp] = NULL;
1066 #endif UCL
1067
1068 if (bbl == NULL)
1069 done (1);
1070 }
1071
1072 /* \f */
1073
1074 add_bb (s, hush)
1075 register char *s;
1076 int hush;
1077 {
1078 register struct bboard *bb;
1079 static struct bboard *tail = NULL;
1080
1081 make_lower (s, s);
1082 if ((bb = getbbaux (s)) == NULL)
1083 if (hush == OK)
1084 return;
1085 else
1086 adios (NULLCP, "no such bboard as '%s'", s);
1087
1088 if (bb -> bb_flags & BB_SEEN) {
1089 if (hush == OK) {
1090 admonish (NULLCP, "duplicate bboard '%s'", s);
1091 oops++;
1092 }
1093 return;
1094 }
1095 bb -> bb_flags |= BB_SEEN;
1096
1097 if (tail != NULL)
1098 tail -> bb_link = bb;
1099 if (bbl == NULL)
1100 bbl = bb;
1101 tail = bb;
1102 }
1103
1104 /* \f */
1105
1106 #ifdef BPOP
1107 static struct bboard *Bhead = NULL;
1108 static struct bboard *Btail = NULL;
1109
1110 static int xtnd2 (s)
1111 char *s;
1112 {
1113 int maxima;
1114 char name[BUFSIZ];
1115 register struct bboard *bb;
1116
1117 if (sscanf (s, "%s %d", name, &maxima) != 2)
1118 adios (NULLCP, "XTND2 botch: %s", s);
1119
1120 if ((bb = (struct bboard *) calloc (1, sizeof *bb)) == NULL)
1121 adios (NULLCP, "insufficient memory");
1122 bb -> bb_name = getcpy (name);
1123 #ifdef NNTP
1124 if (index(name, '.')) {
1125 char *cp;
1126 bb -> bb_aka = getip (name);
1127 for (cp = *bb -> bb_aka; *cp; cp++)
1128 if (*cp == '.')
1129 *cp = '-';
1130 } else {
1131 #endif
1132 if ((bb -> bb_aka = (char **) calloc (1, sizeof *bb -> bb_aka)) == NULL)
1133 adios (NULLCP, "insufficient memory");
1134 *bb -> bb_aka = NULL;
1135 #ifdef NNTP
1136 }
1137 #endif NNTP
1138 bb -> bb_file = bb -> bb_archive = bb -> bb_info = bb -> bb_map = "";
1139 bb -> bb_passwd = "";
1140 #ifndef NNTP
1141 if ((bb -> bb_leader = (char **) calloc (1, sizeof *bb -> bb_leader))
1142 == NULL)
1143 adios (NULLCP, "insufficient memory");
1144 *bb -> bb_leader = NULL;
1145 #else NNTP
1146 bb -> bb_leader = getip ("usenet");
1147 #endif NNTP
1148 bb -> bb_addr = bb -> bb_request = bb -> bb_relay = "";
1149 if ((bb -> bb_dist = (char **) calloc (1, sizeof *bb -> bb_dist)) == NULL)
1150 adios (NULLCP, "insufficient memory");
1151 *bb -> bb_dist = NULL;
1152 bb -> bb_flags = BB_REMOTE;
1153 bb -> bb_count = 0;
1154 bb -> bb_maxima = maxima;
1155 bb -> bb_date = "";
1156 bb -> bb_next = bb -> bb_link = bb -> bb_chain = NULL;
1157
1158 if (Btail != NULL)
1159 Btail -> bb_chain = bb;
1160 if (Bhead == NULL)
1161 Bhead = bb;
1162 Btail = bb;
1163
1164 return OK;
1165 }
1166
1167 /* \f */
1168
1169 static int xtnd3 (s)
1170 char *s;
1171 {
1172 static int bbs_int = 0;
1173 static struct bboard *bb;
1174
1175 switch (bbs_int++) {
1176 case 0:
1177 for (bb = Bhead; bb; bb = bb -> bb_chain)
1178 if (strcmp (bb -> bb_name, s) == 0)
1179 break;
1180 if (bb == NULL)
1181 adios (NULLCP, "XTND3 botch");
1182
1183 free (bb -> bb_name);
1184 bb -> bb_name = getcpy (s);
1185 break;
1186 case 1:
1187 if (bb -> bb_aka)
1188 free ((char *) bb -> bb_aka);
1189 bb -> bb_aka = getip (s);
1190 break;
1191 case 2:
1192 bb -> bb_file = getcpy (s);
1193 break;
1194 case 3:
1195 bb -> bb_archive = getcpy (s);
1196 break;
1197 case 4:
1198 bb -> bb_info = getcpy (s);
1199 break;
1200 case 5:
1201 bb -> bb_map = getcpy (s);
1202 break;
1203 case 6:
1204 bb -> bb_passwd = getcpy (s);
1205 break;
1206 case 7:
1207 if (bb -> bb_leader)
1208 free ((char *) bb -> bb_leader);
1209 bb -> bb_leader = getip (s);
1210 break;
1211 case 8:
1212 bb -> bb_addr = getcpy (s);
1213 break;
1214 case 9:
1215 bb -> bb_request = getcpy (s);
1216 break;
1217 case 10:
1218 bb -> bb_relay = getcpy (s);
1219 break;
1220 case 11:
1221 if (bb -> bb_dist)
1222 free ((char *) bb -> bb_dist);
1223 bb -> bb_dist = getip (s);
1224 break;
1225 case 12:
1226 bb -> bb_flags = bb -> bb_maxima = 0;
1227 (void) sscanf (s, "%o %d", &bb -> bb_flags, &bb -> bb_maxima);
1228 bb -> bb_flags |= BB_REMOTE;
1229 break;
1230 case 13:
1231 bb -> bb_date = getcpy (s);
1232 bbs_int = 0;
1233 break;
1234 }
1235
1236 return OK;
1237 }
1238
1239
1240 static char **getip (s)
1241 char *s;
1242 {
1243 register char **ap,
1244 **p,
1245 **q;
1246
1247 for (p = ap = brkstring (getcpy (s), " ", "\n"); *p; p++)
1248 continue;
1249
1250 q = (char **) calloc ((unsigned) (p - ap + 1), sizeof *q);
1251 if (q == NULL)
1252 adios (NULLCP, "insufficient memory");
1253
1254 for (p = ap, ap = q; *p; *q++ = *p++)
1255 continue;
1256 *q = NULL;
1257
1258 return ap;
1259 }
1260
1261 /* \f */
1262
1263 static struct bboard *rover = NULL;
1264
1265 struct bboard *getbbpop () {
1266 int snoop;
1267 char *cp,
1268 *pass = NULL;
1269 register struct bboard *bb;
1270
1271 if (didpop != NOTOK && ((bb = getbbent ()) || !host))
1272 return bb;
1273
1274 if (Bhead == NULL) {
1275 snoop = (cp = getenv ("MHPOPDEBUG")) && *cp;
1276 if (rpop) {
1277 if (user == NULL)
1278 user = getusr ();
1279 pass = getusr ();
1280 }
1281 else
1282 if (strcmp (user, popbbuser) == 0)
1283 pass = user;
1284 else
1285 ruserpass (host, &user, &pass);
1286 if (didpop != NOTOK)
1287 didpop = DONE;
1288
1289 if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
1290 adios (NULLCP, "%s", response);
1291 if (rpop)
1292 (void) setuid (getuid ());
1293 if (pop_xtnd (xtnd2, "bboards") == NOTOK)
1294 adios (NULLCP, "%s", response);
1295 if (topicsw && verbosw) /* could optimize here */
1296 for (bb = Bhead; bb; bb = bb -> bb_chain)
1297 if (pop_xtnd (xtnd3, "x-bboards %s", bb -> bb_name) == NOTOK)
1298 adios (NULLCP, "%s", response);
1299 rover = Bhead;
1300 }
1301
1302 if (bb = rover)
1303 rover = rover -> bb_chain;
1304 return bb;
1305 }
1306
1307 #define getbbent getbbpop
1308 #endif BPOP
1309
1310 /* \f */
1311
1312 struct bboard *getbbaux (s)
1313 register char *s;
1314 {
1315 #ifdef BPOP
1316 int nlatch = host ? 1 : 0;
1317 #endif BPOP
1318 register char **ap;
1319 register struct bbcount *selected;
1320 register struct bboard *bb;
1321 static struct bboard *head = NULL,
1322 *tail = NULL;
1323
1324 for (bb = head; bb; bb = bb -> bb_next) {
1325 if (strcmp (bb -> bb_name, s) == 0)
1326 return bb;
1327 for (ap = bb -> bb_aka; *ap; ap++)
1328 if (strcmp (*ap, s) == 0)
1329 return bb;
1330 }
1331
1332 #ifdef BPOP
1333 one_more_time: ;
1334 #endif BPOP
1335 while (bb = getbbent ()) {
1336 if ((selected = seek_count (bbc, bb -> bb_name)) != NULL)
1337 bb -> bb_count = selected -> count;
1338
1339 #ifdef BPOP
1340 if (!(bb -> bb_flags & BB_REMOTE))
1341 #endif BPOP
1342 if ((bb = getbbcpy (bb)) == NULL)
1343 adios (NULLCP, "insufficient memory");
1344 if (tail != NULL)
1345 tail -> bb_next = bb;
1346 if (head == NULL)
1347 head = bb;
1348 tail = bb;
1349
1350 if (strcmp (bb -> bb_name, s) == 0) {
1351 found_it: ;
1352 bb -> bb_flags &= ~BB_SEEN;
1353 return bb;
1354 }
1355 for (ap = bb -> bb_aka; *ap; ap++)
1356 if (strcmp (*ap, s) == 0)
1357 goto found_it;
1358 }
1359
1360 #ifdef BPOP
1361 if (nlatch && pop_xtnd (xtnd2, "bboards %s", s) != NOTOK) {
1362 rover = Bhead;
1363 nlatch = 0;
1364 goto one_more_time;
1365 }
1366 #endif BPOP
1367
1368 return NULL;
1369 }
1370
1371
1372 struct bboard *getbbvis () {
1373 register struct bboard *bb;
1374
1375 while (bb = getbbent ())
1376 if (!(bb -> bb_flags & BB_INVIS)
1377 && (access (bb -> bb_file, 04) != NOTOK || errno != EACCES))
1378 break;
1379
1380 return bb;
1381 }
1382 @
1383
1384
1385 2.12
1386 log
1387 @WAITINT ifdefs
1388 @
1389 text
1390 @d3 1
1391 a3 1
1392 static char ident[] = "@@(#)$Id: bbc.c,v 2.11 1992/11/24 18:34:21 jromine Exp jromine $";
1393 d140 2
1394 a141 2
1395 int sigser (), action ();
1396 int hupser ();
1397 d144 1
1398 a144 1
1399 static int tstpser ();
1400 d696 1
1401 a696 1
1402 int sigser (i)
1403 d708 1
1404 a708 1
1405 int hupser (i)
1406 d816 1
1407 a816 1
1408 static int tstpser (sig)
1409 @
1410
1411
1412 2.11
1413 log
1414 @add decl
1415 @
1416 text
1417 @d3 1
1418 a3 1
1419 static char ident[] = "@@(#)$Id: bbc.c,v 2.10 1992/11/11 22:04:17 jromine Exp jromine $";
1420 d820 3
1421 a822 1
1422 #ifndef BSD42
1423 a823 2
1424 #else
1425 union wait w;
1426 @
1427
1428
1429 2.10
1430 log
1431 @use union wait under BSD42 only
1432 @
1433 text
1434 @d3 1
1435 a3 1
1436 static char ident[] = "@@(#)$Id: bbc.c,v 2.9 1992/11/04 00:39:01 jromine Exp jromine $";
1437 d136 2
1438 a137 1
1439 char *getusr (), **getip ();
1440 d144 1
1441 a144 1
1442 int tstpser ();
1443 @
1444
1445
1446 2.9
1447 log
1448 @putenv -> m_putenv
1449 LOCALE
1450 @
1451 text
1452 @d3 1
1453 a3 1
1454 static char ident[] = "@@(#)$Id: bbc.c,v 2.8 1992/05/12 21:55:14 jromine Exp jromine $";
1455 d819 1
1456 a819 1
1457 #ifdef SVR4
1458 @
1459
1460
1461 2.8
1462 log
1463 @move misplaced #endif
1464 @
1465 text
1466 @d3 1
1467 a3 1
1468 static char ident[] = "@@(#)$Id: bbc.c,v 2.7 1992/02/10 19:57:26 jromine Exp jromine $";
1469 d27 3
1470 a184 1
1471
1472 d189 4
1473 d734 1
1474 a734 1
1475 (void) putenv ("MHBBRC", rcfile);
1476 @
1477
1478
1479 2.7
1480 log
1481 @typo
1482 @
1483 text
1484 @d3 1
1485 a3 1
1486 static char ident[] = "@@(#)$Id: bbc.c,v 2.6 1992/02/10 18:12:35 jromine Exp $";
1487 d826 1
1488 a827 1
1489 continue;
1490 @
1491
1492
1493 2.6
1494 log
1495 @some SVR4 changes
1496 add "localdomain" tailor option
1497 @
1498 text
1499 @d3 1
1500 a3 1
1501 static char ident[] = "@@(#)$Id: bbc.c,v 2.5 1990/04/05 14:56:21 sources Exp jromine $";
1502 d823 1
1503 a823 1
1504 #endif
1505 @
1506
1507
1508 2.5
1509 log
1510 @add ID
1511 @
1512 text
1513 @d3 1
1514 a3 1
1515 static char ident[] = "@@(#)$Id:$";
1516 d813 3
1517 d817 1
1518 d821 3
1519 d826 1
1520 @
1521
1522
1523 2.4
1524 log
1525 @TYPESIG fix
1526 @
1527 text
1528 @d2 3
1529 @
1530
1531
1532 2.3
1533 log
1534 @UCL changes
1535 @
1536 text
1537 @d479 1
1538 a479 1
1539 int (*tstat) ();
1540 @
1541
1542
1543 2.2
1544 log
1545 @TYPESIG
1546 @
1547 text
1548 @d150 5
1549 d163 1
1550 d166 3
1551 d175 1
1552 d177 1
1553 d180 4
1554 d318 6
1555 d326 1
1556 d891 3
1557 d904 1
1558 d906 6
1559 d920 4
1560 d934 3
1561 d1042 1
1562 a1042 1
1563 static int bbs = 0;
1564 d1045 1
1565 a1045 1
1566 switch (bbs++) {
1567 d1102 1
1568 a1102 1
1569 bbs = 0;
1570 @
1571
1572
1573 2.1
1574 log
1575 @don't always add "general" to list of bbs.
1576 @
1577 text
1578 @d614 1
1579 a614 1
1580 int (*estat) (), (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
1581 d741 1
1582 a741 1
1583 int (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
1584 @
1585
1586
1587 2.0
1588 log
1589 @changes for SUN40 shared libraries and NNTP under bbc
1590 @
1591 text
1592 @d887 1
1593 a887 1
1594 else
1595 d897 1
1596 @
1597
1598
1599 1.5
1600 log
1601 @fix minor nntp bug
1602 @
1603 text
1604 @@
1605
1606
1607 1.4
1608 log
1609 @*** empty log message ***
1610 @
1611 text
1612 @a24 2
1613 static char *mshproc = "/usr/local/nmsh";
1614
1615 d148 1
1616 d473 8
1617 a480 1
1618 else
1619 d488 1
1620 a488 1
1621
1622 d538 3
1623 a540 1
1624 if (nmsgs == 0)
1625 d542 1
1626 d811 14
1627 @
1628
1629
1630 1.3
1631 log
1632 @*** empty log message ***
1633 @
1634 text
1635 @d869 4
1636 @
1637
1638
1639 1.2
1640 log
1641 @*** empty log message ***
1642 @
1643 text
1644 @d25 1
1645 d67 6
1646 a72 1
1647 "user BBoardsuser", 4,
1648 d865 1
1649 d867 3
1650 @
1651
1652
1653 1.1
1654 log
1655 @Initial revision
1656 @
1657 text
1658 @d916 9
1659 d928 3
1660 d933 1
1661 d938 3
1662 @