/*- * Copyright (c) 1996 * David Parsons. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by David Parsons * (orc@pell.chi.il.us) * 4. My name may not be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ static char rcsid[] = "$Header: /home/orc/src/CVS/listmgr/admin.c,v 1.8 1996/04/23 03:32:23 orc Exp $"; /* * admin: do operations on a gdbm database * * usage: admin add "address" "name" * admin drop "address" * admin list * admin nomail "address" [y|n] */ #include #include #include #include #include #include #include #include "mailer.h" #include "server.h" typedef int (*ftn)(int, char**); extern int add(int argc, char **argv); extern int drop(int argc, char **argv); extern int list(int argc, char **argv); extern int nomail(int argc, char **argv); extern int alter(int argc, char **argv); extern int help(int argc, char **argv); struct ctab { char *cmd; int nrargs; ftn function; char *usage; char *comment; } commands[] = { { "add", 3, add, "add 'address' 'name'", "Add someone to the list" }, { "alter", 3, alter, "alter 'address' 'name'", "Alter someone's name" }, { "drop", 2, drop, "drop 'address'", "Drop someone from the list" }, { "list", -1, list, "list", "Display current subscribers" }, { "nomail", 3, nomail,"nomail 'address' [Y|N]", "Set nomail for someone" }, { "help", -1, help, "help", "get help on commands" }, }; #define NR(x) (sizeof (x)/ sizeof (x)[0]) GDBM_FILE fd; /* database access handle */ char *pgm; /* the program name, normalised */ char *db; /* the database name, extracted from the program name */ /* * list server administration */ int main(int argc, char **argv) { int x; int rc; char *p; char *tmp; /* get normalized program name */ if ((pgm = strrchr(argv[0], '/')) != 0) pgm++; else pgm = argv[0]; /* the database name for a given list is listname-users, * and the admin name is listname-admin. */ #define USERS LISTMGR_DIR "/%s-users" if ((tmp = malloc(strlen(pgm)+8)) == 0) { perror(pgm); exit(1); } strcpy(tmp, pgm); if ((p=strrchr(tmp, '-')) != 0 && strcasecmp(p, "-admin") == 0) *p = 0; db = Filename(USERS, tmp); while ((rc=getopt(argc, argv, "?F:f:")) != EOF) switch (rc) { case '?': exit (help(0, (char**)0)); case 'F': case 'f': db = optarg; break; default: fprintf(stderr, "usage: %s [-f database] {command args}\n", pgm); exit(1); } argc -= optind; argv += optind; if (argc < 1) exit (help(0, (char**)0)); for (x=0; x < NR(commands); x++) if (strcasecmp(argv[0], commands[x].cmd) == 0) { if (commands[x].nrargs < 0 || argc == commands[x].nrargs) exit ((*commands[x].function)(argc, argv)); else { fprintf(stderr, "usage: %s %s\n", pgm, commands[x].usage); exit(1); } } fprintf(stderr, "%s: can't execute %s\n", pgm, argv[0]); exit(1); } /* admin */ /* * help: gives a help message for all the commands or a single named * command. */ int help(int argc, char **argv) { int x; if (argc <= 1) { for (x=0; x < NR(commands); x++) fprintf(stderr, "%s\t%s\n", commands[x].cmd, commands[x].comment); return 0; } for (x=0; x < NR(commands); x++) if (strcasecmp(argv[1], commands[x].cmd) == 0) { fprintf(stderr, "%s\t%s\n", commands[x].cmd, commands[x].comment); fprintf(stderr, " usage: %s\n", commands[x].usage); return 0; } fprintf(stderr, "%s is not a valid command\n", argv[1]); return 1; } /* help */ /* * add: adds a user to the mailing list */ int add(int argc, char **argv) { datum key, value; if ((fd = gdbm_open(db, 0, GDBM_WRITER, GDBM_WRCREAT, 0)) != 0) { key.dptr = argv[1]; strlwr(key.dptr); key.dsize = strlen(key.dptr); /* value is nomail flag + name */ value.dsize = strlen(argv[2])+1; if ((value.dptr = malloc(value.dsize)) == 0) { perror(pgm); return 1; } strncpy(value.dptr+1, argv[2], value.dsize-1); value.dptr[0] = 'N'; if (gdbm_store(fd, key, value, GDBM_REPLACE) != 0) { gdbm_perror(argv[1]); return 1; } puts("Ok"); return 0; } gdbm_perror(argv[0]); return 1; } /* add */ /* * display_user_info shows the name, address, and nomail status of a * given user */ int display_user_info(datum key) { datum value; value = gdbm_fetch(fd, key); if ((value.dsize > 0) && value.dptr) { printf("%.*s", key.dsize, key.dptr); printf("%*s", 30-key.dsize, ""); printf(" %.*s", value.dsize-1, value.dptr+1); if (value.dptr[0] == 'Y') { if (value.dsize < 40) printf("%*s", 40-value.dsize, ""); printf(" (nomail)"); } putchar('\n'); return 0; } return EOF; } /* display_user_info */ /* * list: show who's subscribing to this list */ int list(int argc, char **argv) { datum key; int i; int errcount = 0; if ((fd = gdbm_open(db, 0, GDBM_READER, 0, 0)) != 0) { if (argc <= 1) { /* list all subscribers if no argument is given */ for (key = gdbm_firstkey(fd); key.dptr; key = gdbm_nextkey(fd, key)) display_user_info(key); } else { /* List info on named subscribers */ for (i=1; i < argc; i++) { key.dptr = argv[i]; strlwr(key.dptr); key.dsize = strlen(key.dptr); if (display_user_info(key) == EOF) { fprintf(stderr, "%s: no such person\n", argv[i]); errcount++; } } } return errcount ? 1 : 0; } gdbm_perror(argv[0]); return 1; } /* list */ /* * drop: drop a user from the list */ int drop(int argc, char **argv) { datum key; if ((fd = gdbm_open(db, 0, GDBM_WRITER, GDBM_WRCREAT, 0)) != 0) { key.dptr = argv[1]; strlwr(key.dptr); key.dsize = strlen(key.dptr); if (gdbm_delete(fd, key) != 0) { gdbm_perror(argv[1]); gdbm_close(fd); return 1; } gdbm_close(fd); puts("Ok"); return 0; } gdbm_perror(argv[0]); return 1; } /* drop */ /* * nomail: set a user's nomail status */ int nomail(int argc, char **argv) { datum key, value; char status = toupper(argv[2][0]); if (status != 'Y' && status != 'N') { fprintf(stderr, "%s: nomail status must be Y or N\n", pgm); return 1; } if ((fd = gdbm_open(db, 0, GDBM_WRITER, GDBM_WRCREAT, 0)) != 0) { key.dptr = argv[1]; strlwr(key.dptr); key.dsize = strlen(key.dptr); value = gdbm_fetch(fd, key); if ((value.dsize > 0) && value.dptr) { value.dptr[0] = status; if (gdbm_store(fd, key, value, GDBM_REPLACE) != 0) { gdbm_perror(argv[1]); gdbm_close(fd); return 1; } gdbm_close(fd); printf("%s: nomail is %s\n", argv[1], (status=='Y')?"ON":"OFF"); return 0; } fprintf(stderr, "%s: no such person\n", argv[1]); gdbm_close(fd); return 1; } gdbm_perror(argv[0]); return 1; } /* nomail */ /* * alter: set a user's name */ int alter(int argc, char **argv) { datum key, value, new; if ((fd = gdbm_open(db, 0, GDBM_WRITER, GDBM_WRCREAT, 0)) != 0) { key.dptr = argv[1]; strlwr(key.dptr); key.dsize = strlen(key.dptr); value = gdbm_fetch(fd, key); if ((value.dsize > 0) && value.dptr) { new.dsize = strlen(argv[2])+1; if ((new.dptr = malloc(new.dsize)) == (char*)0) { perror(pgm); return 1; } new.dptr[0] = value.dptr[0]; memcpy(new.dptr+1, argv[2], new.dsize-1); if (gdbm_store(fd, key, new, GDBM_REPLACE) != 0) { gdbm_perror(argv[1]); gdbm_close(fd); return 1; } gdbm_close(fd); puts("Ok"); return 0; } fprintf(stderr, "%s: no such person\n", argv[1]); gdbm_close(fd); return 1; } gdbm_perror(argv[0]); return 1; } /* nomail */