Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / bbl.c,v
1 head    2.4;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 2.4
9 date    92.11.04.00.39.25;      author jromine; state Exp;
10 branches;
11 next    2.3;
12
13 2.3
14 date    92.02.04.00.02.03;      author jromine; state Exp;
15 branches;
16 next    2.2;
17
18 2.2
19 date    92.02.03.16.46.28;      author jromine; state Exp;
20 branches;
21 next    2.1;
22
23 2.1
24 date    90.04.05.14.56.46;      author sources; state Exp;
25 branches;
26 next    2.0;
27
28 2.0
29 date    89.11.17.15.57.51;      author sources; state Exp;
30 branches;
31 next    1.1;
32
33 1.1
34 date    89.06.26.14.36.36;      author sources; state Exp;
35 branches;
36 next    ;
37
38
39 desc
40 @@
41
42
43 2.4
44 log
45 @LOCALE
46 @
47 text
48 @/* bbl.c - ease the tasks of a BBleader */
49 #ifndef lint
50 static char ident[] = "@@(#)$Id: bbl.c,v 2.3 1992/02/04 00:02:03 jromine Exp jromine $";
51 #endif  lint
52
53 #include "../h/mh.h"
54 #include "../h/local.h"
55 #include "../zotnet/bboards.h"
56 #include <ctype.h>
57 #include <pwd.h>
58 #include <stdio.h>
59 #ifdef LOCALE
60 #include        <locale.h>
61 #endif
62
63 /* \f */
64
65 static struct swit switches[] = {
66 #define SHELLSW 0
67     "shell program", 0,
68
69 #define VERBSW  1
70     "verbose", 0,
71 #define NVERBSW 2
72     "noverbose", 0,
73
74 #define HELPSW  3
75     "help", 4,
76
77     NULL, NULL
78 };
79
80 /* \f */
81
82 static  int     verbosw = 0;
83
84 static  int     sub_ok = 0;
85
86 static  char   *bboards = BBOARDS;
87
88 static  char   *cwd = NULL;
89
90 static  char   *current_folder = NULL;
91
92 static  char   *bbfolder = NULL;
93 static  char    subfolder[BUFSIZ];
94
95 static  struct stat bbstat;
96 static  struct stat substat;
97
98 static  char   *shell = "/bin/sh";
99
100 static  struct bboard  *bb = NULL;
101
102
103 #ifndef __STDC__
104 #ifdef  SYS5
105 struct  passwd  *getpwnam (), *getpwuid ();
106 #endif  /* SYS5 */
107 #endif
108
109 /* \f */
110
111 /* ARGSUSED */
112
113 main (argc, argv)
114 int     argc;
115 char  **argv;
116 {
117     char   *cp,
118           **ap,
119           **argp,
120             buffer[80],
121            *arguments[MAXARGS];
122     struct passwd  *pw;
123
124 #ifdef LOCALE
125         setlocale(LC_ALL, "");
126 #endif
127     invo_name = r1bindex (argv[0], '/');
128     if ((cp = m_find (invo_name)) != NULL) {
129         ap = brkstring (cp = getcpy (cp), " ", "\n");
130         ap = copyip (ap, arguments);
131     }
132     else
133         ap = arguments;
134     (void) copyip (argv + 1, ap);
135     argp = arguments;
136
137     if ((shell = getenv ("SHELL")) == NULL)
138         if ((pw = getpwuid (getuid ())) != NULL
139                 && pw -> pw_shell
140                 && *pw -> pw_shell)
141             shell = getcpy (pw -> pw_shell);
142
143     if ((pw = getpwnam (bboards)) == NULL)
144         adios (NULLCP, "no entry for ~%s", bboards);
145     if (pw -> pw_uid != geteuid ())
146         adios (NULLCP, "not running setuid to %s", bboards);
147
148     current_folder = ((cp = m_find (pfolder)) || (cp = m_find (inbox)))
149             ? getcpy (cp) : defalt;
150
151 /* \f */
152
153     while (cp = *argp++) {
154         if (*cp == '-')
155             switch (smatch (++cp, switches)) {
156                 case AMBIGSW: 
157                     ambigsw (cp, switches);
158                     done (1);
159                 case UNKWNSW: 
160                     adios (NULLCP, "-%s unknown", cp);
161                 case HELPSW: 
162                     (void) sprintf (buffer, "%s [+folder] [switches] bboard",
163                             invo_name);
164                     help (buffer, switches);
165                     done (1);
166
167                 case SHELLSW: 
168                     if (!(shell = *argp++) || *shell == '-')
169                         adios (NULLCP, "missing argument to %s", argp[-2]);
170                     continue;
171
172                 case VERBSW: 
173                     verbosw++;
174                     continue;
175                 case NVERBSW: 
176                     verbosw = 0;
177                     continue;
178             }
179         if (*cp == '+')
180             if (bbfolder)
181                 adios (NULLCP, "only one folder at a time!");
182             else
183                 bbfolder = cp;
184         else
185             if (bb != NULL)
186                 adios (NULLCP, "only one BBoard a time!");
187             else
188                 if ((bb = getbbnam (cp)) == NULL
189                         && (bb = getbbaka (cp)) == NULL)
190                     adios (NULLCP, "no such BBoard as '%s'", cp);
191     }
192
193 /* \f */
194
195     if (!bb)
196         adios (NULLCP, "no BBoard specified");
197     if (!bbfolder)
198         bbfolder = "+bbl";
199     (void) sprintf (subfolder, "%s/arc", bbfolder);
200
201     if (!m_find ("path"))
202         free (path ("./", TFOLDER));
203     cwd = getcpy (pwd ());
204
205     process ();
206
207     m_replace (pfolder, current_folder);
208     m_update ();
209
210     done (0);
211 }
212
213 /* \f */
214
215 process () {
216     int     child_id;
217     char    buffer[BUFSIZ];
218
219     if (!ldrbb (bb) && !ldrchk (bb))
220         return;
221
222     if (stat (bb -> bb_file, &bbstat) == NOTOK)
223         adios (NULLCP, "no such file as %s", bb -> bb_file);
224
225     if (stat (bb -> bb_archive, &substat) != NOTOK
226             && substat.st_size > 0)
227         sub_ok++;
228 /*  else */
229     substat.st_mode = bbstat.st_mode;/* archive should always match */
230     substat.st_gid = bbstat.st_gid;/* actual bboard mode & gid */
231
232 /* do subfolder first, since you will lose otherwise... */
233     (void) sprintf (buffer, "Remove messages currently in %s? ", subfolder);
234     if (check_folder (subfolder) && getanswer (buffer))
235         rmf (subfolder);
236
237     (void) sprintf (buffer, "Remove messages currently in %s? ", bbfolder);
238     if (check_folder (bbfolder) && getanswer (buffer))
239         rmf (bbfolder);
240
241     switch (child_id = fork ()) {
242         case NOTOK: 
243             adios ("fork", "unable to");
244
245         case OK: 
246             do_child ();        /* NOTREACHED */
247
248         default: 
249             do_parent (child_id);
250             break;
251     }
252 }
253
254 /* \f */
255
256 int     check_folder (folder)
257 char   *folder;
258 {
259     char   *maildir;
260     struct stat st;
261     struct msgs *mp;
262
263     maildir = m_maildir (folder + 1);
264
265     if (stat (maildir, &st) == NOTOK)
266         return 0;
267
268     if ((st.st_mode & S_IFMT) != S_IFDIR)
269         adios (NULLCP, "not a directory '%s'", maildir);
270     check_mode (maildir, (st.st_mode | 0555) & 0777);
271
272     if (chdir (maildir) == NOTOK)
273         adios (maildir, "unable to change to");
274     if (!(mp = m_gmsg (folder + 1)))
275         adios (NULLCP, "unable to read %s", folder);
276
277     if (chdir (cwd) == NOTOK)
278         admonish (cwd, "could not change back to");
279     return (mp -> hghmsg != 0);
280 }
281
282 /* \f */
283
284 do_parent (child_id)
285 int     child_id;
286 {
287     int     zap = 0;
288     char    buffer[BUFSIZ];
289
290     if (pidwait (child_id, NOTOK) == NOTOK)
291         done (1);
292
293     (void) putchar ('\n');
294
295     (void) check_folder (bbfolder);
296     if (getanswer ("Incorporate changes? "))
297         update (&bbstat, bb -> bb_file, bbfolder, bb -> bb_info, bb -> bb_map);
298     (void) sprintf (buffer, "Remove %s? ", bbfolder);
299     if (getanswer (buffer))
300         zap++;
301
302     if (check_folder (subfolder)) {
303         if (getanswer ("Update archives? "))
304             update (&substat, bb -> bb_archive, subfolder, NULLCP, NULLCP);
305     (void) sprintf (buffer, "Remove %s? ", subfolder);
306     if (getanswer (buffer))
307         rmf (subfolder);
308     }
309     else
310         if (sub_ok
311                 && getanswer ("Remove archives? ")
312                 && getanswer ("Are you sure? "))
313             if (unlink (bb -> bb_archive) == NOTOK)
314                 admonish (bb -> bb_archive, "unable to remove %s");
315     if (zap)
316         rmf (bbfolder);
317 }
318
319 /* \f */
320
321 check_mode (dir, mode)
322 char   *dir;
323 unsigned int    mode;
324 {
325     int     child_id;
326     struct stat st;
327 #ifdef SYS5DIR
328     struct dirent  *dp;
329 #else  SYS5DIR
330     struct direct  *dp;
331 #endif SYS5DIR
332     DIR * dd;
333
334     if (verbosw)
335         fprintf (stderr, "chmod %o %s\n", mode, dir);
336
337     switch (child_id = fork ()) {
338         case NOTOK: 
339             adios ("fork", "unable to");
340
341         case OK: 
342             (void) setgid (getgid ());
343             (void) setuid (getuid ());
344
345             if (chmod (dir, (int) mode) == NOTOK)
346                 adios (dir, "unable to change mode of");
347             if (chdir (dir) == NOTOK)
348                 adios (dir, "unable to change to");
349             if ((dd = opendir (dir)) == NULL)
350                 adios (dir, "unable to read");
351             while (dp = readdir (dd))
352                 if (dp -> d_name[0] != '.') {
353                     if (stat (dp -> d_name, &st) == NOTOK) {
354                         admonish (dp -> d_name, "unable to stat");
355                         continue;
356                     }
357                     if (chmod (dp -> d_name, (int) ((st.st_mode | 0444) & 0777))
358                             == NOTOK)
359                         admonish (dp -> d_name, "unable to change mode of");
360                 }
361             closedir (dd);
362             done (0);
363
364         default: 
365             if (pidwait (child_id, OK))
366                 done (1);
367             break;
368     }
369 }
370
371 /* \f */
372
373 /* ARGSUSED */
374
375 update (stp, file, folder, info, map)
376 struct stat *stp;
377 char   *file,
378        *folder,
379        *info,
380        *map;
381 {
382     int     fd;
383     struct stat st;
384
385     if (stat (file, &st) != NOTOK
386             && st.st_mtime != stp -> st_mtime) {
387         printf ("File '%s' has changed...\n", file);
388         if (getanswer ("Append to it instead? "))
389             goto work;
390         else
391             if (!getanswer ("Still update it? "))
392                 return;
393     }
394     if ((fd = creat (file, BBMODE)) == NOTOK)
395         adios (file, "unable to re-create");
396     else {
397         (void) close (fd);
398         if (map)
399             (void) unlink (map);
400     }
401 #ifdef  notdef
402     if (info)
403         check_info (folder, info);
404 #endif  notdef
405
406 work: ;
407     pack (folder, file);
408     if (chmod (file, (int) (stp -> st_mode & 0777)) == NOTOK)
409         admonish (file, "unable to change mode of");
410     if (stat (file, &st) != NOTOK && st.st_gid != stp -> st_gid)
411         chgrp (file, stp -> st_gid);
412 }
413
414 /* \f */
415
416 #ifdef  notdef
417 check_info (folder, info)
418 char   *folder,
419        *info;
420 {
421     int     id,
422             state;
423     char   *hdrptr,
424            *maildir,
425            *msgnam,
426             posted[BUFSIZ],
427             name[NAMESZ],
428             buf[BUFSIZ];
429     struct msgs *mp;
430     FILE * fp;
431
432     if (chdir (maildir = m_maildir (folder + 1)) == NOTOK)
433         adios (maildir, "unable to change to");
434
435     if (!(mp = m_gmsg (folder + 1)))
436         adios (NULL, "unable to read %s", folder);
437     if (mp -> hghmsg) {
438         if ((fp = fopen (msgnam = m_name (mp -> hghmsg), "r")) == NULL)
439             adios (NULL, "unable to read message %s in %s",
440                     msgnam, folder);
441         id = 0;
442         posted[0] = NULL;
443         for (state = FLD;;) {
444             switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
445                 case FLD: 
446                 case FLDEOF: 
447                 case FLDPLUS: 
448                     hdrptr = add (buf, NULL);
449                     while (state == FLDPLUS) {
450                         state = m_getfld (state, name, buf, sizeof buf, fp);
451                         hdrptr = add (buf, hdrptr);
452                     }
453                     if (uleq (name, "BBoard-ID")) {
454                         id = atoi (buf);
455                         if (id > 0 && posted[0])
456                             break;
457                     }
458                     if (uleq (name, "BB-Posted")) {
459                         strncpy (posted, buf, sizeof posted - 2);
460                         if (posted[strlen (posted) - 1] == '\n')
461                             posted[strlen (posted) - 1] = NULL;
462                         if (id > 0 && posted[0])
463                             break;
464                     }
465                     continue;
466
467                 default: 
468                     admonish (NULL, "unable to find BBoard-info in message %s",
469                             msgnam);
470                     (void) fclose (fp);
471                     goto no_risk;
472             }
473             break;
474         }
475         (void) fclose (fp);
476
477         if (verbosw)
478             fprintf (stderr,
479                     "[ Highest message has %s%d and\n\t\t      %s%s ]\n",
480                     "BBoard-ID: ", id, "BB-Posted: ", posted);
481
482         if ((fp = lkfopen (info, "w")) == NULL)
483             adios (info, "unable to lock and fopen");
484         fprintf (fp, "%d\n%s\n", id, posted);
485         (void) lkfclose (fp, info);
486     }
487
488 no_risk: ;
489     if (chdir (cwd) == NOTOK)
490         admonish (cwd, "could not change back to");
491 }
492 #endif  notdef
493
494 /* \f */
495
496 pack (folder, file)
497 char   *folder,
498        *file;
499 {
500     int     child_id;
501
502     switch (child_id = fork ()) {
503         case NOTOK: 
504             admonish ("fork", "unable to");
505             return;
506
507         case OK: 
508             if (verbosw)
509                 fprintf (stderr, "pack %s -file %s\n", folder, file);
510
511             execlp (packproc, r1bindex (packproc, '/'),
512                     folder, "-file", file, NULLCP);
513             fprintf (stderr, "unable to exec ");
514             perror (packproc);
515             _exit (-1);
516
517         default: 
518             (void) pidXwait (child_id, packproc);
519             break;
520     }
521 }
522
523 /* \f */
524
525 chgrp (file, gid)
526 char   *file;
527 short   gid;
528 {
529     int     child_id;
530     char    group[BUFSIZ];
531
532     switch (child_id = fork ()) {
533         case NOTOK: 
534             admonish ("fork", "unable to");
535             return;
536
537         case OK: 
538             (void) setuid (geteuid ());/* make sure chgrp works */
539             (void) sprintf (group, "%d", gid);
540             if (verbosw)
541                 fprintf (stderr, "chgrp %s %s\n", group, file);
542
543             execlp ("/bin/chgrp", "chgrp", group, file, NULLCP);
544             fprintf (stderr, "unable to exec ");
545             perror ("/bin/chgrp");
546             _exit (-1);
547
548         default: 
549             (void) pidXwait (child_id, "chgrp");
550             break;
551     }
552 }
553
554 /* \f */
555
556 rmf (folder)
557 char   *folder;
558 {
559     int     child_id;
560
561     switch (child_id = fork ()) {
562         case NOTOK: 
563             admonish ("fork", "unable to");
564             return;
565
566         case OK: 
567             (void) setgid (getgid ());
568             (void) setuid (getuid ());
569             if (verbosw)
570                 fprintf (stderr, "rmf %s\n", folder);
571
572             execlp (rmfproc, r1bindex (rmfproc, '/'), folder, NULLCP);
573             fprintf (stderr, "unable to exec ");
574             perror (rmfproc);
575             _exit (-1);
576
577         default: 
578             (void) pidXwait (child_id, rmfproc);
579             break;
580     }
581 }
582
583 /* \f */
584
585 do_child () {
586     char    buffer[BUFSIZ];
587
588     (void) setgid (getgid ());          /* become the user, not bboards */
589     (void) setuid (getuid ());
590
591     inc (bb -> bb_file, bbfolder);
592     if (sub_ok)
593         inc (bb -> bb_archive, subfolder);
594 /*  else
595         create the folder */
596
597     if (verbosw)
598         (void) putchar ('\n');
599     printf ("[ Working folder is %s, Archive folder is %s ]\n",
600             bbfolder, subfolder);
601     printf ("[ Type CTRL-D to finish ]\n");
602
603     m_replace (pfolder, bbfolder + 1);
604     m_update ();
605
606     (void) sprintf (buffer, "=> %s: %s", invo_name, bb -> bb_name);
607     execlp (shell, buffer, NULLCP);
608     fprintf (stderr, "unable to exec ");
609     perror (shell);
610     _exit (-1);
611 }
612
613 /* \f */
614
615 inc (file, folder)
616 char   *file,
617        *folder;
618 {
619     int     child_id;
620
621     switch (child_id = fork ()) {
622         case NOTOK: 
623             adios ("fork", "unable to");
624
625         case OK: 
626             if (verbosw)
627                 fprintf (stderr, "inc %s -file %s -silent\n", folder, file);
628             execlp (incproc, r1bindex (incproc, '/'),
629                     folder, "-file", file, "-silent", NULLCP);
630             fprintf (stderr, "unable to exec ");
631             perror (incproc);
632             _exit (-1);
633
634         default: 
635             if (pidXwait (child_id, incproc))
636                 done (1);
637             break;
638     }
639 }
640 @
641
642
643 2.3
644 log
645 @contributed patch
646 @
647 text
648 @d3 1
649 a3 1
650 static char ident[] = "@@(#)$Id: bbl.c,v 2.2 1992/02/03 16:46:28 jromine Exp jromine $";
651 d12 3
652 d77 3
653 @
654
655
656 2.2
657 log
658 @getpwuid decl
659 @
660 text
661 @d3 1
662 a3 1
663 static char ident[] = "@@(#)$Id: bbl.c,v 2.1 90/04/05 14:56:46 sources Exp $";
664 d95 2
665 a96 1
666     current_folder = (cp = m_find (pfolder)) ? getcpy (cp) : defalt;
667 @
668
669
670 2.1
671 log
672 @add ID
673 @
674 text
675 @d3 1
676 a3 1
677 static char ident[] = "@@(#)$Id:$";
678 d53 1
679 d56 2
680 a57 1
681 #endif  SYS5
682 @
683
684
685 2.0
686 log
687 @changes for SUN40 shared libraries and NNTP under bbc
688 @
689 text
690 @d2 3
691 @
692
693
694 1.1
695 log
696 @Initial revision
697 @
698 text
699 @d268 3
700 d272 1
701 @