summaryrefslogtreecommitdiff
path: root/tools/gdbmtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gdbmtool.c')
-rw-r--r--tools/gdbmtool.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/tools/gdbmtool.c b/tools/gdbmtool.c
new file mode 100644
index 0000000..dfe7094
--- /dev/null
+++ b/tools/gdbmtool.c
@@ -0,0 +1,293 @@
+/* This file is part of GDBM, the GNU data base manager.
+ Copyright (C) 1990-2021 Free Software Foundation, Inc.
+
+ GDBM is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GDBM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GDBM. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "gdbmtool.h"
+#include <errno.h>
+#include <ctype.h>
+#include <signal.h>
+#include <pwd.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <stdarg.h>
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+static void
+source_rcfile (void)
+{
+ instream_t istr = NULL;
+
+ if (access (GDBMTOOLRC, R_OK) == 0)
+ {
+ istr = instream_file_create (GDBMTOOLRC);
+ }
+ else
+ {
+ char *fname;
+ char *p = getenv ("HOME");
+ if (!p)
+ {
+ struct passwd *pw = getpwuid (getuid ());
+ if (!pw)
+ {
+ terror (_("cannot find home directory"));
+ return;
+ }
+ p = pw->pw_dir;
+ }
+ fname = mkfilename (p, GDBMTOOLRC, NULL);
+ if (access (fname, R_OK) == 0)
+ {
+ istr = instream_file_create (GDBMTOOLRC);
+ }
+ free (fname);
+ }
+
+ if (istr)
+ {
+ if (input_context_push (istr))
+ exit (EXIT_FATAL);
+ yyparse ();
+ }
+}
+
+#if GDBM_DEBUG_ENABLE
+void
+debug_printer (char const *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+}
+#endif
+
+
+char *parseopt_program_doc = N_("examine and/or modify a GDBM database");
+char *parseopt_program_args = N_("DBFILE [COMMAND [ARG ...]]");
+
+enum {
+ OPT_LEX_TRACE = 256,
+ OPT_GRAM_TRACE
+};
+
+struct gdbm_option optab[] = {
+ { 'b', "block-size", N_("SIZE"), N_("set block size") },
+ { 'c', "cache-size", N_("SIZE"), N_("set cache size") },
+ { 'f', "file", N_("FILE"), N_("read commands from FILE") },
+ { 'g', NULL, "FILE", NULL, PARSEOPT_HIDDEN },
+ { 'l', "no-lock", NULL, N_("disable file locking") },
+ { 'm', "no-mmap", NULL, N_("do not use mmap") },
+ { 'n', "newdb", NULL, N_("create database") },
+ { 'N', "norc", NULL, N_("do not read .gdbmtoolrc file") },
+ { 'r', "read-only", NULL, N_("open database in read-only mode") },
+ { 's', "synchronize", NULL, N_("synchronize to disk after each write") },
+ { 'q', "quiet", NULL, N_("don't print initial banner") },
+ { 'd', "db-descriptor",
+ /* TRANSLATORS: File Descriptor. */
+ N_("FD"),
+ N_("open database at the given file descriptor") },
+ { 'x', "extended", NULL, N_("extended format (numsync)") },
+ { 0, "numsync", NULL, NULL, PARSEOPT_ALIAS },
+ { 't', "trace", NULL, N_("enable trace mode") },
+ { 'T', "timing", NULL, N_("print timing after each command") },
+#if GDBMTOOL_DEBUG
+ { OPT_LEX_TRACE, "lex-trace", NULL, N_("enable lexical analyzer traces") },
+ { OPT_GRAM_TRACE, "gram-trace", NULL, N_("enable grammar traces") },
+#endif
+ { 0 }
+};
+
+#ifdef WITH_READLINE
+# define instream_default_create instream_readline_create
+#else
+# define instream_default_create instream_stdin_create
+#endif
+
+struct gdbmtool_closure
+{
+ int argc;
+ char **argv;
+};
+
+static int
+gdbmtool_init (void *data, instream_t *pinstr)
+{
+ struct gdbmtool_closure *clos = data;
+ int argc = clos->argc;
+ char **argv = clos->argv;
+ int opt;
+ int bv;
+ int norc = 0;
+ char *source = NULL;
+ instream_t input = NULL;
+
+ for (opt = parseopt_first (argc, argv, optab);
+ opt != EOF;
+ opt = parseopt_next ())
+ switch (opt)
+ {
+ case 'd':
+ if (variable_set ("fd", VART_STRING, optarg) != VAR_OK)
+ {
+ terror (_("invalid file descriptor: %s"), optarg);
+ exit (EXIT_USAGE);
+ }
+ break;
+
+ case 'f':
+ source = optarg;
+ break;
+
+ case 'l':
+ bv = 0;
+ variable_set ("lock", VART_BOOL, &bv);
+ break;
+
+ case 'm':
+ bv = 0;
+ variable_set ("mmap", VART_BOOL, &bv);
+ break;
+
+ case 's':
+ bv = 1;
+ variable_set ("sync", VART_BOOL, &bv);
+ break;
+
+ case 'r':
+ variable_set ("open", VART_STRING, "readonly");
+ break;
+
+ case 'n':
+ variable_set ("open", VART_STRING, "newdb");
+ break;
+
+ case 'N':
+ norc = 1;
+ break;
+
+ case 'c':
+ variable_set ("cachesize", VART_STRING, optarg);
+ break;
+
+ case 'b':
+ variable_set ("blocksize", VART_STRING, optarg);
+ break;
+
+ case 'g':
+ variable_set ("filename", VART_STRING, optarg);
+ break;
+
+ case 't':
+ bv = 1;
+ variable_set ("trace", VART_BOOL, &bv);
+ break;
+
+ case 'T':
+ bv = 1;
+ variable_set ("timing", VART_BOOL, &bv);
+ break;
+
+ case 'q':
+ bv = 1;
+ variable_set ("quiet", VART_BOOL, &bv);
+ break;
+
+ case 'x':
+ variable_set ("format", VART_STRING, "numsync");
+ break;
+
+ case OPT_LEX_TRACE:
+ lex_trace (1);
+ break;
+
+ case OPT_GRAM_TRACE:
+ gram_trace (1);
+ break;
+
+ default:
+ if (optopt == 0)
+ terror (_("unknown option %s; try `%s -h' for more info"),
+ argv[optind-1], progname);
+ else
+ terror (_("unknown option %c; try `%s -h' for more info"),
+ optopt, progname);
+ exit (EXIT_USAGE);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (source && strcmp (source, "-"))
+ {
+ input = instream_file_create (source);
+ if (!input)
+ exit (1);
+ }
+
+ if (argc >= 1)
+ {
+ variable_set ("filename", VART_STRING, argv[0]);
+ argc--;
+ argv++;
+ if (argc)
+ {
+ if (input)
+ {
+ terror (_("--file and command cannot be used together"));
+ exit (EXIT_USAGE);
+ }
+ input = instream_argv_create (argc, argv);
+ if (!input)
+ exit (1);
+ }
+ }
+
+ if (!norc)
+ source_rcfile ();
+
+ if (!input)
+ input = instream_default_create ();
+
+ *pinstr = input;
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct gdbmtool_closure closure;
+
+ set_progname (argv[0]);
+#if GDBM_DEBUG_ENABLE
+ gdbm_debug_printer = debug_printer;
+#endif
+
+#ifdef HAVE_SETLOCALE
+ setlocale (LC_ALL, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ closure.argc = argc;
+ closure.argv = argv;
+
+ return gdbmshell_run (gdbmtool_init, &closure);
+}