aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gdbm.h.in5
-rw-r--r--src/gdbm_dump.c40
-rw-r--r--src/gdbm_load.c164
-rw-r--r--src/gdbmapp.h7
-rw-r--r--src/gdbmload.c98
-rw-r--r--src/testgdbm.c24
6 files changed, 240 insertions, 98 deletions
diff --git a/src/gdbm.h.in b/src/gdbm.h.in
index b81516d..7789d7e 100644
--- a/src/gdbm.h.in
+++ b/src/gdbm.h.in
@@ -123,13 +123,18 @@ extern int gdbm_import_from_file (GDBM_FILE dbf, FILE *fp, int flag);
#define GDBM_DUMP_FMT_BINARY 0
#define GDBM_DUMP_FMT_ASCII 1
+#define GDBM_META_MASK_MODE 0x01
+#define GDBM_META_MASK_OWNER 0x02
+
extern int gdbm_dump (GDBM_FILE, const char *, int fmt, int open_flags,
int mode);
extern int gdbm_dump_to_file (GDBM_FILE, FILE *, int fmt);
extern int gdbm_load (GDBM_FILE *, const char *, int replace,
+ int meta_flags,
unsigned long *line);
extern int gdbm_load_from_file (GDBM_FILE *, FILE *, int replace,
+ int meta_flags,
unsigned long *line);
# define GDBM_NO_ERROR 0
diff --git a/src/gdbm_dump.c b/src/gdbm_dump.c
index 6ea94e6..9120f04 100644
--- a/src/gdbm_dump.c
+++ b/src/gdbm_dump.c
@@ -23,7 +23,6 @@ char *parseopt_program_doc = "dump a GDBM database to a file";
char *parseopt_program_args = "DB_FILE [FILE]";
struct gdbm_option optab[] = {
{ 'H', "format", N_("0|1"), N_("select dump format") },
- { 'b', "binary", NULL, N_("use binary output format") },
{ 0 }
};
@@ -45,26 +44,29 @@ main (int argc, char **argv)
{
switch (opt)
{
- case 'b':
- format = GDBM_DUMP_FMT_BINARY;
- break;
-
case 'H':
- format = atoi (optarg);
- switch (format)
+ if (strcmp (optarg, "binary") == 0)
+ format = GDBM_DUMP_FMT_BINARY;
+ else if (strcmp (optarg, "ascii") == 0)
+ format = GDBM_DUMP_FMT_ASCII;
+ else
{
- case GDBM_DUMP_FMT_BINARY:
- case GDBM_DUMP_FMT_ASCII:
- break;
- default:
- error (_("unknown dump format"));
- exit (2);
+ format = atoi (optarg);
+ switch (format)
+ {
+ case GDBM_DUMP_FMT_BINARY:
+ case GDBM_DUMP_FMT_ASCII:
+ break;
+ default:
+ error (_("unknown dump format"));
+ exit (EXIT_USAGE);
+ }
}
break;
default:
error (_("unknown option"));
- exit (2);
+ exit (EXIT_USAGE);
}
}
@@ -74,13 +76,13 @@ main (int argc, char **argv)
if (argc == 0)
{
parseopt_print_help ();
- exit (0);
+ exit (EXIT_OK);
}
if (argc > 2)
{
error (_("too many arguments; try `%s -h' for more info"), progname);
- exit (2);
+ exit (EXIT_USAGE);
}
dbname = argv[0];
@@ -100,7 +102,7 @@ main (int argc, char **argv)
if (!fp)
{
sys_perror (errno, _("cannot open %s"), filename);
- exit (1);
+ exit (EXIT_FATAL);
}
}
@@ -108,7 +110,7 @@ main (int argc, char **argv)
if (!dbf)
{
gdbm_perror (_("gdbm_open failed"));
- exit (1);
+ exit (EXIT_FATAL);
}
rc = gdbm_dump_to_file (dbf, fp, format);
@@ -119,6 +121,6 @@ main (int argc, char **argv)
gdbm_close (dbf);
- exit (!!rc);
+ exit (rc ? EXIT_OK : EXIT_FATAL);
}
diff --git a/src/gdbm_load.c b/src/gdbm_load.c
index cdc7302..deea9ca 100644
--- a/src/gdbm_load.c
+++ b/src/gdbm_load.c
@@ -18,28 +18,51 @@
# include "gdbm.h"
# include "gdbmapp.h"
# include "gdbmdefs.h"
-
-/* usage: gdbm_load [OPTIONS] FILE [DB_FILE]
- FILE is either "-" or a file name.
- OPTIONS are:
- -h, --help
- -u, --usage
- -v, --version
-
- -p, --permissions OOO
- -u, --user NAME-OR-UID
- -g, --group NAME-OR-GID
-*/
+# include <pwd.h>
+# include <grp.h>
int replace = 0;
+int meta_mask = 0;
+int no_meta_option;
+
+int mode;
+uid_t owner_uid;
+gid_t owner_gid;
char *parseopt_program_doc = "load a GDBM database from a file";
char *parseopt_program_args = "FILE [DB_FILE]";
struct gdbm_option optab[] = {
{ 'r', "replace", NULL, N_("replace records in the existing database") },
+ { 'm', "mode", N_("MODE"), N_("set file mode") },
+ { 'u', "user", N_("NAME|UID[:NAME|GID]"), N_("set file owner") },
+ { 'n', "no-meta", NULL, N_("do not attempt to set file meta-data") },
{ 0 }
};
+static int
+set_meta_info (GDBM_FILE dbf)
+{
+ if (meta_mask)
+ {
+ int fd = gdbm_fdesc (dbf);
+
+ if (meta_mask & GDBM_META_MASK_OWNER)
+ {
+ if (fchown (fd, owner_uid, owner_gid))
+ {
+ gdbm_errno = GDBM_ERR_FILE_OWNER;
+ return 1;
+ }
+ }
+ if ((meta_mask & GDBM_META_MASK_MODE) && fchmod (fd, mode))
+ {
+ gdbm_errno = GDBM_ERR_FILE_OWNER;
+ return 1;
+ }
+ }
+ return 0;
+}
+
int
main (int argc, char **argv)
{
@@ -47,8 +70,9 @@ main (int argc, char **argv)
int rc, opt;
char *dbname, *filename;
FILE *fp;
- unsigned long err_line;
-
+ unsigned long err_line, n;
+ char *end;
+
set_progname (argv[0]);
for (opt = parseopt_first (argc, argv, optab);
@@ -57,13 +81,94 @@ main (int argc, char **argv)
{
switch (opt)
{
+ case 'm':
+ {
+ errno = 0;
+ n = strtoul (optarg, &end, 8);
+ if (*end == 0 && errno == 0)
+ {
+ mode = n & 0777;
+ meta_mask |= GDBM_META_MASK_MODE;
+ }
+ else
+ {
+ error ("%s", _("invalid octal number"));
+ exit (EXIT_USAGE);
+ }
+ }
+ break;
+
+ case 'u':
+ {
+ size_t len;
+ struct passwd *pw;
+
+ len = strcspn (optarg, ".:");
+ if (optarg[len])
+ optarg[len++] = 0;
+ pw = getpwnam (optarg);
+ if (pw)
+ owner_uid = pw->pw_uid;
+ else
+ {
+ errno = 0;
+ n = strtoul (optarg, &end, 10);
+ if (*end == 0 && errno == 0)
+ owner_uid = n;
+ else
+ {
+ error (_("invalid user name: %s"), optarg);
+ exit (EXIT_USAGE);
+ }
+ }
+
+ if (optarg[len])
+ {
+ char *grname = optarg + len;
+ struct group *gr = getgrnam (grname);
+ if (gr)
+ owner_gid = gr->gr_gid;
+ else
+ {
+ errno = 0;
+ n = strtoul (grname, &end, 10);
+ if (*end == 0 && errno == 0)
+ owner_gid = n;
+ else
+ {
+ error (_("invalid group name: %s"), grname);
+ exit (EXIT_USAGE);
+ }
+ }
+ }
+ else
+ {
+ if (!pw)
+ {
+ pw = getpwuid (owner_uid);
+ if (!pw)
+ {
+ error (_("no such UID: %lu"), (unsigned long)owner_uid);
+ exit (EXIT_USAGE);
+ }
+ }
+ owner_gid = pw->pw_gid;
+ }
+ meta_mask |= GDBM_META_MASK_OWNER;
+ }
+ break;
+
case 'r':
replace = 1;
break;
+
+ case 'n':
+ no_meta_option = 1;
+ break;
default:
error (_("unknown option"));
- exit (2);
+ exit (EXIT_USAGE);
}
}
@@ -73,13 +178,13 @@ main (int argc, char **argv)
if (argc == 0)
{
parseopt_print_help ();
- exit (0);
+ exit (EXIT_OK);
}
if (argc > 2)
{
error (_("too many arguments; try `%s -h' for more info"), progname);
- exit (2);
+ exit (EXIT_USAGE);
}
filename = argv[0];
@@ -99,7 +204,7 @@ main (int argc, char **argv)
if (!fp)
{
sys_perror (errno, _("cannot open %s"), filename);
- exit (1);
+ exit (EXIT_FATAL);
}
}
@@ -109,19 +214,24 @@ main (int argc, char **argv)
if (!dbf)
{
gdbm_perror (_("gdbm_open failed"));
- exit (1);
+ exit (EXIT_FATAL);
}
}
- rc = gdbm_load_from_file (&dbf, fp, replace, &err_line);
+ rc = gdbm_load_from_file (&dbf, fp, replace,
+ no_meta_option ?
+ (GDBM_META_MASK_MODE | GDBM_META_MASK_OWNER) :
+ meta_mask,
+ &err_line);
if (rc)
{
switch (gdbm_errno)
{
case GDBM_ERR_FILE_OWNER:
case GDBM_ERR_FILE_MODE:
- error (_("error restoring metadata for %s: %s (%s)"),
- filename, gdbm_strerror (gdbm_errno), strerror (errno));
+ error (_("error restoring metadata: %s (%s)"),
+ gdbm_strerror (gdbm_errno), strerror (errno));
+ rc = EXIT_MILD;
break;
default:
@@ -129,11 +239,19 @@ main (int argc, char **argv)
gdbm_perror ("%s:%lu", filename, err_line);
else
gdbm_perror (_("cannot load from %s"), filename);
+ rc = EXIT_FATAL;
}
}
if (dbf)
{
+ if (!no_meta_option && set_meta_info (dbf))
+ {
+ error (_("error restoring metadata: %s (%s)"),
+ gdbm_strerror (gdbm_errno), strerror (errno));
+ rc = EXIT_MILD;
+ }
+
if (!dbname)
{
if (gdbm_setopt (dbf, GDBM_GETDBNAME, &dbname, sizeof (dbname)))
@@ -146,5 +264,5 @@ main (int argc, char **argv)
}
gdbm_close (dbf);
}
- exit (!!rc);
+ exit (rc);
}
diff --git a/src/gdbmapp.h b/src/gdbmapp.h
index e7917f9..0de0005 100644
--- a/src/gdbmapp.h
+++ b/src/gdbmapp.h
@@ -50,3 +50,10 @@ void parseopt_print_help (void);
extern char *parseopt_program_name;
extern char *parseopt_program_doc;
extern char *parseopt_program_args;
+
+/* Application exit codes */
+#define EXIT_OK 0
+#define EXIT_FATAL 1
+#define EXIT_MILD 2
+#define EXIT_USAGE 3
+
diff --git a/src/gdbmload.c b/src/gdbmload.c
index 1e9cb06..40a63b9 100644
--- a/src/gdbmload.c
+++ b/src/gdbmload.c
@@ -285,7 +285,7 @@ read_record (struct dump_file *file, char *param, int n, datum *dat)
#define META_MODE 0x04
static int
-_set_gdbm_meta_info (GDBM_FILE dbf, char *param)
+_set_gdbm_meta_info (GDBM_FILE dbf, char *param, int meta_mask)
{
unsigned long n;
uid_t owner_uid;
@@ -295,62 +295,68 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param)
const char *p;
char *end;
int rc = 0;
-
- p = getparm (param, "user");
- if (p)
+
+ if (!(meta_mask & GDBM_META_MASK_OWNER))
{
- struct passwd *pw = getpwnam (p);
- if (pw)
+ p = getparm (param, "user");
+ if (p)
{
- owner_uid = pw->pw_uid;
- meta_flags |= META_UID;
+ struct passwd *pw = getpwnam (p);
+ if (pw)
+ {
+ owner_uid = pw->pw_uid;
+ meta_flags |= META_UID;
+ }
}
- }
- if (!(meta_flags & META_UID) && (p = getparm (param, "uid")))
- {
- errno = 0;
- n = strtoul (p, &end, 10);
- if (*end == 0 && errno == 0)
+ if (!(meta_flags & META_UID) && (p = getparm (param, "uid")))
{
- owner_uid = n;
- meta_flags |= META_UID;
+ errno = 0;
+ n = strtoul (p, &end, 10);
+ if (*end == 0 && errno == 0)
+ {
+ owner_uid = n;
+ meta_flags |= META_UID;
+ }
}
- }
- p = getparm (param, "group");
- if (p)
- {
- struct group *gr = getgrnam (p);
- if (gr)
+ p = getparm (param, "group");
+ if (p)
{
- owner_gid = gr->gr_gid;
- meta_flags |= META_GID;
+ struct group *gr = getgrnam (p);
+ if (gr)
+ {
+ owner_gid = gr->gr_gid;
+ meta_flags |= META_GID;
+ }
}
- }
- if (!(meta_flags & META_GID) && (p = getparm (param, "gid")))
- {
- errno = 0;
- n = strtoul (p, &end, 10);
- if (*end == 0 && errno == 0)
+ if (!(meta_flags & META_GID) && (p = getparm (param, "gid")))
{
- owner_gid = n;
- meta_flags |= META_GID;
+ errno = 0;
+ n = strtoul (p, &end, 10);
+ if (*end == 0 && errno == 0)
+ {
+ owner_gid = n;
+ meta_flags |= META_GID;
+ }
}
}
-
- p = getparm (param, "mode");
- if (p)
+
+ if (!(meta_mask & GDBM_META_MASK_MODE))
{
- errno = 0;
- n = strtoul (p, &end, 8);
- if (*end == 0 && errno == 0)
+ p = getparm (param, "mode");
+ if (p)
{
- mode = n & 0777;
- meta_flags |= META_MODE;
+ errno = 0;
+ n = strtoul (p, &end, 8);
+ if (*end == 0 && errno == 0)
+ {
+ mode = n & 0777;
+ meta_flags |= META_MODE;
+ }
}
}
-
+
if (meta_flags)
{
int fd = gdbm_fdesc (dbf);
@@ -382,7 +388,7 @@ _set_gdbm_meta_info (GDBM_FILE dbf, char *param)
int
_gdbm_load_file (struct dump_file *file, GDBM_FILE dbf, GDBM_FILE *ofp,
- int replace)
+ int replace, int meta_mask)
{
char *param = NULL;
int rc;
@@ -439,7 +445,7 @@ _gdbm_load_file (struct dump_file *file, GDBM_FILE dbf, GDBM_FILE *ofp,
if (rc == 0)
{
- rc = _set_gdbm_meta_info (dbf, file->header);
+ rc = _set_gdbm_meta_info (dbf, file->header, meta_mask);
*ofp = dbf;
}
else if (tmp)
@@ -450,6 +456,7 @@ _gdbm_load_file (struct dump_file *file, GDBM_FILE dbf, GDBM_FILE *ofp,
int
gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace,
+ int meta_mask,
unsigned long *line)
{
struct dump_file df;
@@ -477,7 +484,7 @@ gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace,
memset (&df, 0, sizeof df);
df.fp = fp;
- rc = _gdbm_load_file (&df, *pdbf, pdbf, replace);
+ rc = _gdbm_load_file (&df, *pdbf, pdbf, replace, meta_mask);
dump_file_free (&df);
if (rc)
{
@@ -491,6 +498,7 @@ gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace,
int
gdbm_load (GDBM_FILE *pdbf, const char *filename, int replace,
+ int meta_mask,
unsigned long *line)
{
FILE *fp;
@@ -502,7 +510,7 @@ gdbm_load (GDBM_FILE *pdbf, const char *filename, int replace,
gdbm_errno = GDBM_FILE_OPEN_ERROR;
return -1;
}
- rc = gdbm_load_from_file (pdbf, fp, replace, line);
+ rc = gdbm_load_from_file (pdbf, fp, replace, meta_mask, line);
fclose (fp);
return rc;
}
diff --git a/src/testgdbm.c b/src/testgdbm.c
index cf5fc88..31a54d2 100644
--- a/src/testgdbm.c
+++ b/src/testgdbm.c
@@ -119,7 +119,7 @@ _gdbm_avail_list_size (GDBM_FILE dbf, size_t min_size)
+ sizeof (avail_block));
av_stk = (avail_block *) malloc (size);
if (av_stk == NULL)
- terror (2, _("Out of memory"));
+ terror (EXIT_FATAL, _("Out of memory"));
/* Traverse the stack. */
while (temp)
@@ -173,7 +173,7 @@ _gdbm_print_avail_list (FILE *fp, GDBM_FILE dbf)
+ sizeof (avail_block));
av_stk = (avail_block *) malloc (size);
if (av_stk == NULL)
- terror (2, _("Out of memory"));
+ terror (EXIT_FATAL, _("Out of memory"));
/* Print the stack. */
while (temp)
@@ -676,7 +676,7 @@ quit_handler (char *arg[NARGS] ARG_UNUSED, FILE *fp ARG_UNUSED,
if (gdbm_file != NULL)
gdbm_close (gdbm_file);
- exit (0);
+ exit (EXIT_OK);
}
/* e file [truncate] - export to a flat file format */
@@ -1025,21 +1025,21 @@ main (int argc, char *argv[])
case 's':
if (reader)
- terror (2, _("-s is incompatible with -r"));
+ terror (EXIT_USAGE, _("-s is incompatible with -r"));
flags = flags | GDBM_SYNC;
break;
case 'r':
if (newdb)
- terror (2, _("-r is incompatible with -n"));
+ terror (EXIT_USAGE, _("-r is incompatible with -n"));
reader = TRUE;
break;
case 'n':
if (reader)
- terror (2, _("-n is incompatible with -r"));
+ terror (EXIT_USAGE, _("-n is incompatible with -r"));
newdb = TRUE;
break;
@@ -1058,7 +1058,8 @@ main (int argc, char *argv[])
break;
default:
- terror (2, _("unknown option; try `%s -h' for more info\n"), progname);
+ terror (EXIT_USAGE,
+ _("unknown option; try `%s -h' for more info\n"), progname);
}
if (file_name == NULL)
@@ -1082,11 +1083,12 @@ main (int argc, char *argv[])
gdbm_open (file_name, block_size, GDBM_WRCREAT | flags, 00664, NULL);
}
if (gdbm_file == NULL)
- terror (2, _("gdbm_open failed: %s"), gdbm_strerror (gdbm_errno));
+ terror (EXIT_FATAL, _("gdbm_open failed: %s"), gdbm_strerror (gdbm_errno));
if (gdbm_setopt (gdbm_file, GDBM_CACHESIZE, &cache_size, sizeof (int)) ==
-1)
- terror (2, _("gdbm_setopt failed: %s"), gdbm_strerror (gdbm_errno));
+ terror (EXIT_FATAL, _("gdbm_setopt failed: %s"),
+ gdbm_strerror (gdbm_errno));
signal (SIGPIPE, SIG_IGN);
@@ -1141,12 +1143,12 @@ main (int argc, char *argv[])
/* Optional argument */
break;
if (!interactive)
- terror (1, _("%s: not enough arguments"), cmd->name);
+ terror (EXIT_USAGE, _("%s: not enough arguments"), cmd->name);
printf ("%s? ", arg);
if (fgets (argbuf[i], sizeof argbuf[i], stdin) == NULL)
- terror (1, _("unexpected eof"));
+ terror (EXIT_USAGE, _("unexpected eof"));
trimnl (argbuf[i]);
args[i] = argbuf[i];

Return to:

Send suggestions and report system problems to the System administrator.