/* 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 . */
#include "gdbmtool.h"
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef HAVE_LOCALE_H
# include
#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 },
#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 '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:
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);
}