0
|
1 /* bbexp.c - expunge the BBoards area */
|
|
2 #ifndef lint
|
12
|
3 static char ident[] = "@(#)$Id: bbexp.c,v 1.1.1.1 2005/04/18 14:46:06 kono Exp $";
|
0
|
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 static TYPESIG pipeser ();
|
|
25
|
|
26
|
|
27 #ifndef __STDC__
|
|
28 #ifdef SYS5
|
|
29 struct passwd *getpwnam ();
|
|
30 #endif
|
|
31 #endif
|
|
32
|
|
33 /* */
|
|
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 /* */
|
|
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 /* */
|
|
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 /* */
|
|
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 execlp ("/usr/bin/chgrp", chgrp, group, file, NULLCP);
|
|
217 fprintf (stderr, "unable to exec ");
|
|
218 perror ("chgrp");
|
|
219 _exit (1);
|
|
220
|
|
221 default:
|
|
222 (void) pidwait (child_id, OK);
|
|
223 break;
|
|
224 }
|
|
225 }
|
|
226
|
|
227 /* */
|
|
228
|
|
229 /* ARGSUSED */
|
|
230
|
|
231 static TYPESIG pipeser (i)
|
|
232 int i;
|
|
233 {
|
|
234 #ifndef BSD42
|
|
235 (void) signal (SIGPIPE, pipeser);
|
|
236 #endif /* not BSD42 */
|
|
237
|
|
238 if (!broken_pipe++)
|
|
239 advise (NULLCP, "broken pipe");
|
|
240 }
|