diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gdbm.h.in | 5 | ||||
-rw-r--r-- | src/gdbm_dump.c | 40 | ||||
-rw-r--r-- | src/gdbm_load.c | 164 | ||||
-rw-r--r-- | src/gdbmapp.h | 7 | ||||
-rw-r--r-- | src/gdbmload.c | 98 | ||||
-rw-r--r-- | src/testgdbm.c | 24 |
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]; |