diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-15 15:23:56 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-15 15:23:56 +0000 |
commit | 5e3403fbd39b2cafdaa662768a61d8fb0f45e244 (patch) | |
tree | 2d9f7bbe099046ad5c369eb225bbde3ab94e0bdf /src/gdbm_load.c | |
parent | af116bb7d7d5a53310e48d196ebe577b9a63f799 (diff) | |
download | gdbm-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.c | 164 |
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); } |