Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / support / bboards / bbexp.c
1 /* bbexp.c - expunge the BBoards area */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: bbexp.c,v 1.6 1992/12/15 00:20:22 jromine Exp $";
4 #endif  /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/dropsbr.h"
8 #include "../zotnet/bboards.h"
9 #include <pwd.h>
10 #include <signal.h>
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14
15
16 #define FIRST   12
17 #define SECOND  20
18
19
20 static int  broken_pipe;
21
22 static  int     move();
23 static          process(), chgrp();
24 int     pipeser ();
25
26
27 #ifndef __STDC__
28 #ifdef  SYS5
29 struct passwd *getpwnam ();
30 #endif
31 #endif
32
33 /* \f */
34
35 /* ARGSUSED */
36
37 main (argc, argv)
38 int     argc;
39 char  **argv;
40 {
41     int     first = FIRST,
42             second = SECOND;
43     char   *cp;
44     struct bboard  *bb;
45     struct passwd  *pw;
46
47     invo_name = r1bindex (*argv++, '/');
48     m_foil (NULLCP);
49
50     if ((pw = getpwnam (BBOARDS)) == NULL)
51         adios (NULLCP, "no entry for ~%s", BBOARDS);
52     if (pw -> pw_uid != geteuid ())
53         adios (NULLCP, "not running setuid to %s", BBOARDS);
54
55     if (*argv && **argv == '-') {
56         if ((first = atoi (*argv + 1)) < 1)
57             first = FIRST;
58         argv++;
59     }
60     if (*argv && **argv == '-') {
61         if ((second = atoi (*argv + 1)) < 1)
62             second = SECOND;
63         argv++;
64     }
65     
66     (void) setbbent (SB_STAY);
67     if (*argv == NULL)
68         while (bb = getbbent ()) {
69             if ((bb -> bb_flags & BB_ARCH) & (BB_ASAV | BB_AREM))
70                 process (bb, pw, first, second);
71         }
72     else
73         while (cp = *argv++)
74             if ((bb = getbbnam (cp)) || (bb = getbbaka (cp))) {
75                 if ((bb -> bb_flags & BB_ARCH) & (BB_ASAV | BB_AREM))
76                     process (bb, pw, first, second);
77             }
78             else
79                 advise (NULLCP, "no such BBoard as %s", cp);
80     (void) endbbent ();
81
82     exit (0);
83 }
84
85 /* \f */
86
87 static process (bb, pw, first, second)
88 struct bboard *bb;
89 struct passwd *pw;
90 int     first,
91         second;
92 {
93     int     fd,
94             td;
95     char   *cp,
96             command[BUFSIZ],
97             tmpfil[BUFSIZ];
98     FILE   *pf;
99     struct stat st;
100
101     if ((fd = lkopen (bb -> bb_file, 6)) == NOTOK) {
102         advise (bb -> bb_file, "unable to lock and open");
103         return;
104     }
105
106     (void) sprintf (tmpfil, "%s/#bbexpXXXXXX", pw -> pw_dir);
107     (void) unlink (mktemp (tmpfil));
108     if ((td = creat (tmpfil, BBMODE)) == NOTOK) {
109         advise (tmpfil, "unable to create");
110         goto out1;
111     }
112     (void) close (td);
113     if ((td = creat (cp = map_name (tmpfil), BBMODE)) == NOTOK) {
114         advise (cp, "unable to create");
115         goto out2;
116     }
117     (void) close (td);
118
119     if ((bb -> bb_flags & BB_ARCH)
120             && stat (bb -> bb_archive, &st) == NOTOK
121             && stat (bb -> bb_file, &st) != NOTOK
122             && (td = creat (bb -> bb_archive, (int) (st.st_mode & 0777))) != NOTOK)
123         (void) close (td);
124
125     (void) sprintf (command, "%s %s%s", mshproc, bb -> bb_file,
126             isatty (fileno (stdout)) ? " 2>&1 | cat" : "");
127     printf ("%s  (%s old messages)\n", command,
128             (bb -> bb_flags & BB_ARCH) == BB_ASAV ? "archive" : "remove");
129     (void) fflush (stdout);
130     if ((pf = popen (command, "w")) == NULL) {
131         advise (NULLCP, "unable to popen \"%s\" for writing", command);
132         goto out3;
133     }
134     (void) signal (SIGPIPE, pipeser);
135     broken_pipe = 0;
136
137     fprintf (pf, "pick %s -before -%d -sequence select -zero\n",
138             "-datefield BB-Posted", first);
139     fprintf (pf, "pick -before -%d -sequence select -nozero\n", second);
140     fprintf (pf, "scan select\n");
141     if ((bb -> bb_flags & BB_ARCH) == BB_ASAV)
142         fprintf (pf, "pack select -file %s\n", bb -> bb_archive);
143     fprintf (pf, "rmm select\n");
144     fprintf (pf, "packf all -file %s\n", tmpfil);
145 #ifdef  notdef                  /* want real EOF to end it */
146     fprintf (pf, "quit\n");
147 #endif  /* notdef */
148     if (td = pclose (pf))
149         advise (NULLCP, "msh returns %d", td);
150     (void) signal (SIGPIPE, SIG_DFL);
151
152     if (move (tmpfil, bb -> bb_file) != NOTOK)
153         (void) move (cp, bb -> bb_map);
154
155 out3: ;
156     (void) unlink (cp);
157 out2: ;
158     (void) unlink (tmpfil);
159 out1: ;
160     (void) lkclose (fd, bb -> bb_file);
161 }
162
163 /* \f */
164
165 static  int move (input, output)
166 char   *input,
167        *output;
168 {
169     int     i,
170             in,
171             out;
172     struct stat st1,
173                 st2;
174
175     if ((in = open (input, 0)) == NOTOK) {
176         advise (input, "unable to re-open");
177         return NOTOK;
178     }
179
180     i = stat (output, &st1);
181     if ((out = creat (output, BBMODE)) == NOTOK) {
182         advise (output, "unable to re-create");
183         return NOTOK;
184     }
185     if (i != NOTOK && chmod (output, (int) (st1.st_mode & 0777)) == NOTOK)
186         admonish (output, "unable to change mode of");
187     if (i != NOTOK && stat (output, &st2) != NOTOK && st2.st_gid != st1.st_gid)
188         chgrp (output, st1.st_gid);
189
190     cpydata (in, out, input, output);
191
192     (void) close (in);
193     (void) close (out);
194
195     return OK;
196 }
197
198 /* \f */
199
200 static  chgrp (file, gid)
201 char   *file;
202 short   gid;
203 {
204     int     child_id;
205     char    group[BUFSIZ];
206
207     switch (child_id = fork ()) {
208         case NOTOK: 
209             admonish ("fork", "unable to");
210             return;
211
212         case OK: 
213             (void) setuid (geteuid ());
214             (void) sprintf (group, "%d", gid);
215             execlp ("/bin/chgrp", chgrp, group, file, NULLCP);
216             fprintf (stderr, "unable to exec ");
217             perror ("/bin/chgrp");
218             _exit (1);
219
220         default: 
221             (void) pidwait (child_id, OK);
222             break;
223     }
224 }
225
226 /* \f */
227
228 /* ARGSUSED */
229
230 static  int pipeser (i)
231 int     i;
232 {
233 #ifndef BSD42
234     (void) signal (SIGPIPE, pipeser);
235 #endif  /* not BSD42 */
236
237     if (!broken_pipe++)
238         advise (NULLCP, "broken pipe");
239 }