diff support/bboards/bbexp.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children 441a2190cfae
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/support/bboards/bbexp.c	Mon Apr 18 23:46:02 2005 +0900
@@ -0,0 +1,240 @@
+/* bbexp.c - expunge the BBoards area */
+#ifndef	lint
+static char ident[] = "@(#)$Id$";
+#endif	/* lint */
+
+#include "../h/mh.h"
+#include "../h/dropsbr.h"
+#include "../zotnet/bboards.h"
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+#define	FIRST	12
+#define	SECOND	20
+
+
+static int  broken_pipe;
+
+static	int	move();
+static		process(), chgrp();
+static TYPESIG	pipeser ();
+
+
+#ifndef	__STDC__
+#ifdef	SYS5
+struct passwd *getpwnam ();
+#endif
+#endif
+
+/*  */
+
+/* ARGSUSED */
+
+main (argc, argv)
+int	argc;
+char  **argv;
+{
+    int	    first = FIRST,
+	    second = SECOND;
+    char   *cp;
+    struct bboard  *bb;
+    struct passwd  *pw;
+
+    invo_name = r1bindex (*argv++, '/');
+    m_foil (NULLCP);
+
+    if ((pw = getpwnam (BBOARDS)) == NULL)
+	adios (NULLCP, "no entry for ~%s", BBOARDS);
+    if (pw -> pw_uid != geteuid ())
+	adios (NULLCP, "not running setuid to %s", BBOARDS);
+
+    if (*argv && **argv == '-') {
+	if ((first = atoi (*argv + 1)) < 1)
+	    first = FIRST;
+	argv++;
+    }
+    if (*argv && **argv == '-') {
+	if ((second = atoi (*argv + 1)) < 1)
+	    second = SECOND;
+	argv++;
+    }
+    
+    (void) setbbent (SB_STAY);
+    if (*argv == NULL)
+	while (bb = getbbent ()) {
+	    if ((bb -> bb_flags & BB_ARCH) & (BB_ASAV | BB_AREM))
+		process (bb, pw, first, second);
+	}
+    else
+	while (cp = *argv++)
+	    if ((bb = getbbnam (cp)) || (bb = getbbaka (cp))) {
+		if ((bb -> bb_flags & BB_ARCH) & (BB_ASAV | BB_AREM))
+		    process (bb, pw, first, second);
+	    }
+	    else
+		advise (NULLCP, "no such BBoard as %s", cp);
+    (void) endbbent ();
+
+    exit (0);
+}
+
+/*  */
+
+static process (bb, pw, first, second)
+struct bboard *bb;
+struct passwd *pw;
+int	first,
+	second;
+{
+    int     fd,
+            td;
+    char   *cp,
+            command[BUFSIZ],
+            tmpfil[BUFSIZ];
+    FILE   *pf;
+    struct stat st;
+
+    if ((fd = lkopen (bb -> bb_file, 6)) == NOTOK) {
+	advise (bb -> bb_file, "unable to lock and open");
+	return;
+    }
+
+    (void) sprintf (tmpfil, "%s/#bbexpXXXXXX", pw -> pw_dir);
+    (void) unlink (mktemp (tmpfil));
+    if ((td = creat (tmpfil, BBMODE)) == NOTOK) {
+	advise (tmpfil, "unable to create");
+	goto out1;
+    }
+    (void) close (td);
+    if ((td = creat (cp = map_name (tmpfil), BBMODE)) == NOTOK) {
+	advise (cp, "unable to create");
+	goto out2;
+    }
+    (void) close (td);
+
+    if ((bb -> bb_flags & BB_ARCH)
+	    && stat (bb -> bb_archive, &st) == NOTOK
+	    && stat (bb -> bb_file, &st) != NOTOK
+	    && (td = creat (bb -> bb_archive, (int) (st.st_mode & 0777))) != NOTOK)
+	(void) close (td);
+
+    (void) sprintf (command, "%s %s%s", mshproc, bb -> bb_file,
+	    isatty (fileno (stdout)) ? " 2>&1 | cat" : "");
+    printf ("%s  (%s old messages)\n", command,
+	    (bb -> bb_flags & BB_ARCH) == BB_ASAV ? "archive" : "remove");
+    (void) fflush (stdout);
+    if ((pf = popen (command, "w")) == NULL) {
+	advise (NULLCP, "unable to popen \"%s\" for writing", command);
+	goto out3;
+    }
+    (void) signal (SIGPIPE, pipeser);
+    broken_pipe = 0;
+
+    fprintf (pf, "pick %s -before -%d -sequence select -zero\n",
+	    "-datefield BB-Posted", first);
+    fprintf (pf, "pick -before -%d -sequence select -nozero\n", second);
+    fprintf (pf, "scan select\n");
+    if ((bb -> bb_flags & BB_ARCH) == BB_ASAV)
+	fprintf (pf, "pack select -file %s\n", bb -> bb_archive);
+    fprintf (pf, "rmm select\n");
+    fprintf (pf, "packf all -file %s\n", tmpfil);
+#ifdef	notdef			/* want real EOF to end it */
+    fprintf (pf, "quit\n");
+#endif	/* notdef */
+    if (td = pclose (pf))
+	advise (NULLCP, "msh returns %d", td);
+    (void) signal (SIGPIPE, SIG_DFL);
+
+    if (move (tmpfil, bb -> bb_file) != NOTOK)
+	(void) move (cp, bb -> bb_map);
+
+out3: ;
+    (void) unlink (cp);
+out2: ;
+    (void) unlink (tmpfil);
+out1: ;
+    (void) lkclose (fd, bb -> bb_file);
+}
+
+/*  */
+
+static  int move (input, output)
+char   *input,
+       *output;
+{
+    int     i,
+            in,
+            out;
+    struct stat st1,
+                st2;
+
+    if ((in = open (input, 0)) == NOTOK) {
+	advise (input, "unable to re-open");
+	return NOTOK;
+    }
+
+    i = stat (output, &st1);
+    if ((out = creat (output, BBMODE)) == NOTOK) {
+	advise (output, "unable to re-create");
+	return NOTOK;
+    }
+    if (i != NOTOK && chmod (output, (int) (st1.st_mode & 0777)) == NOTOK)
+	admonish (output, "unable to change mode of");
+    if (i != NOTOK && stat (output, &st2) != NOTOK && st2.st_gid != st1.st_gid)
+	chgrp (output, st1.st_gid);
+
+    cpydata (in, out, input, output);
+
+    (void) close (in);
+    (void) close (out);
+
+    return OK;
+}
+
+/*  */
+
+static  chgrp (file, gid)
+char   *file;
+short   gid;
+{
+    int     child_id;
+    char    group[BUFSIZ];
+
+    switch (child_id = fork ()) {
+	case NOTOK: 
+	    admonish ("fork", "unable to");
+	    return;
+
+	case OK: 
+	    (void) setuid (geteuid ());
+	    (void) sprintf (group, "%d", gid);
+	    execlp ("/bin/chgrp", chgrp, group, file, NULLCP);
+	    execlp ("/usr/bin/chgrp", chgrp, group, file, NULLCP);
+	    fprintf (stderr, "unable to exec ");
+	    perror ("chgrp");
+	    _exit (1);
+
+	default: 
+	    (void) pidwait (child_id, OK);
+	    break;
+    }
+}
+
+/*  */
+
+/* ARGSUSED */
+
+static TYPESIG pipeser (i)
+int     i;
+{
+#ifndef	BSD42
+    (void) signal (SIGPIPE, pipeser);
+#endif	/* not BSD42 */
+
+    if (!broken_pipe++)
+	advise (NULLCP, "broken pipe");
+}