]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/support/bboards/bbexp.c
Always check that mktemp()/mktemp2() succeeds before trying to
[nmh] / 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 }