aboutsummaryrefslogtreecommitdiff
path: root/src/gdbm_load.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-11-15 15:23:56 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2011-11-15 15:23:56 +0000
commit5e3403fbd39b2cafdaa662768a61d8fb0f45e244 (patch)
tree2d9f7bbe099046ad5c369eb225bbde3ab94e0bdf /src/gdbm_load.c
parentaf116bb7d7d5a53310e48d196ebe577b9a63f799 (diff)
downloadgdbm-5e3403fbd39b2cafdaa662768a61d8fb0f45e244.tar.gz
gdbm-5e3403fbd39b2cafdaa662768a61d8fb0f45e244.tar.bz2
Update the docs. Improve dump/load utilities.
* doc/gdbm.texinfo: Reorganize the material. Document gdbm_load and gdbm_dump utilities. * src/gdbm.h.in (GDBM_META_MASK_MODE) (GDBM_META_MASK_OWNER): New constant. (gdbm_load,gdbm_load_from_file): Take an additional argument: meta_flags, which masks out restoring certain meta-data. * src/gdbm_dump.c: Remove -b option. The -H option takes symbolic format names. Use the standard exit codes. * src/gdbm_load.c: New options: --mode, --user and --no-meta. Use the standard exit codes. * src/gdbmapp.h (EXIT_OK, EXIT_FATAL, EXIT_MILD) (EXIT_USAGE): New constants. * src/gdbmload.c (gdbm_load,gdbm_load_from_file): Take an additional argument, which masks out restoring certain meta-data.
Diffstat (limited to 'src/gdbm_load.c')
-rw-r--r--src/gdbm_load.c164
1 files changed, 141 insertions, 23 deletions
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);
}

Return to:

Send suggestions and report system problems to the System administrator.