/*- * 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/automod/admin.c,v 1.7 1996/10/27 17:29:46 orc Exp $"; /* * admin: do operations on a gdbm database * * usage: admin [-f database] add "item" "comment" * admin [-f database] drop "item" * admin [-f database] alter "item" "comment" * admin [-f database] list */ #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 alter(int argc, char **argv); extern int list(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 'item' 'comment'", "Add to the database" }, { "drop", 2, drop, "drop 'item'", "Delete item from the database" }, { "alter", 3, alter, "alter 'item' 'comment'", "Change the item comment" }, { "list", -1, list, "list", "Display contents of the database" }, { "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]; db = "database"; 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 an item to the database */ int add(int argc, char **argv) { datum key, value; if ((fd = gdbm_open(db, 0, GDBM_WRCREAT, 0600, 0)) != 0) { key.dptr = argv[1]; strlwr(key.dptr); key.dsize = strlen(key.dptr); if ((value.dptr = strdup(argv[2])) == 0) { perror(pgm); return 1; } value.dsize = strlen(value.dptr); if (gdbm_store(fd, key, value, GDBM_REPLACE) != 0) { gdbm_perror(db); return 1; } puts("Ok"); return 0; } gdbm_perror(db); return 1; } /* add */ /* * display_info shows a particular row. */ int display_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, value.dptr); putchar('\n'); return 0; } return EOF; } /* display_info */ /* * list: display the contents of the database */ int list(int argc, char **argv) { datum key; int i; int errcount = 0; if ((fd = gdbm_open(db, 0, GDBM_READER, 0600, 0)) != 0) { if (argc <= 1) { /* fetch the contents of the database. */ for (key = gdbm_firstkey(fd); key.dptr; key = gdbm_nextkey(fd, key)) display_info(key); } else { /* fetch specific rows */ for (i=1; i < argc; i++) { key.dptr = argv[i]; strlwr(key.dptr); key.dsize = strlen(key.dptr); if (display_info(key) == EOF) { fprintf(stderr, "%s: not in database\n", argv[i]); errcount++; } } } return errcount ? 1 : 0; } gdbm_perror(db); return 1; } /* list */ /* * drop: drop an entry from the database */ int drop(int argc, char **argv) { datum key; if ((fd = gdbm_open(db, 0, GDBM_WRCREAT, 0600, 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(db); return 1; } /* drop */ /* * alter: change a comment */ int alter(int argc, char **argv) { datum key, value, new; if ((fd = gdbm_open(db, 0, GDBM_WRCREAT, 0600, 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]); if ((new.dptr = strdup(argv[2])) == (char*)0) { perror(pgm); return 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 record\n", argv[1]); gdbm_close(fd); return 1; } gdbm_perror(argv[0]); return 1; } /* alter */