diff options
-rw-r--r-- | ChangeLog | 49 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | doc/gdbm.texinfo | 43 | ||||
-rw-r--r-- | export/.cvsignore | 2 | ||||
-rw-r--r-- | export/export.c | 5 | ||||
-rw-r--r-- | src/.cvsignore | 2 | ||||
-rw-r--r-- | src/Makefile.am | 35 | ||||
-rw-r--r-- | src/base64.c | 127 | ||||
-rw-r--r-- | src/flatfile.c | 246 | ||||
-rw-r--r-- | src/gdbm.h.in | 23 | ||||
-rw-r--r-- | src/gdbm_dump.c | 124 | ||||
-rw-r--r-- | src/gdbm_load.c | 140 | ||||
-rw-r--r-- | src/gdbmapp.h | 52 | ||||
-rw-r--r-- | src/gdbmdefs.h | 2 | ||||
-rw-r--r-- | src/gdbmdump.c | 193 | ||||
-rw-r--r-- | src/gdbmerrno.c | 1 | ||||
-rw-r--r-- | src/gdbmexp.c | 125 | ||||
-rw-r--r-- | src/gdbmimp.c | 157 | ||||
-rw-r--r-- | src/gdbmload.c | 502 | ||||
-rw-r--r-- | src/mem.c | 74 | ||||
-rw-r--r-- | src/parseopt.c | 585 | ||||
-rw-r--r-- | src/progname.c | 35 | ||||
-rw-r--r-- | src/proto.h | 12 | ||||
-rw-r--r-- | src/systems.h | 16 | ||||
-rw-r--r-- | src/testgdbm.c | 142 |
25 files changed, 2322 insertions, 374 deletions
@@ -1,5 +1,54 @@ 2011-11-13 Sergey Poznyakoff <gray@gnu.org.ua> + Implement new dump format. Add new utilities: gdbm_dump and gdbm_load. + + * configure.ac (AC_CHECK_HEADERS): Don't check for files that must + always be present. Check for getopt.h. + (AC_CHECK_FUNCS): Add getopt_long + * src/systems.h: Include useless #if's. + + * src/flatfile.c: Split into two files: + * src/gdbmexp.c: ... this and ... + * src/gdbmimp.c: .., this + + * src/mem.c: New file. + * src/base64.c: New file. + * src/gdbm_dump.c: New file. + * src/gdbm_load.c: New file. + * src/gdbmapp.h: New file. + * src/gdbmdump.c: New file. + * src/gdbmload.c: New file. + * src/parseopt.c: New file. + * src/progname.c: New file. + * src/.cvsignore: Update. + * src/Makefile.am (libgdbm_la_SOURCES): Add new files. + (noinst_LIBRARIES): New variable. Build libgdbmapp.a. + (libgdbmapp_a_SOURCES): New variable. + (bin_PROGRAMS): Add gdbm_load and gdbm_dump + (testgdbm_LDADD, gdbm_load_LDADD) + (gdbm_dump_LDADD): Add ./libgdbmapp.a + + * src/gdbm.h.in: Include <stdio.h> + (gdbm_export_to_file) + (gdbm_import_from_file): New prototypes. + (GDBM_DUMP_FMT_BINARY,GDBM_DUMP_FMT_ASCII): New constants. + (gdbm_dump,gdbm_load) + (gdbm_dump_to_file,gdbm_load_from_file): New prototypes. + (GDBM_NO_DBNAME): New error code. + (_GDBM_MAX_ERRNO): Update. + * src/gdbmdefs.h (_GDBM_MAX_DUMP_LINE_LEN): New constant. + * src/gdbmerrno.c (gdbm_errlist): Add entry for GDBM_NO_DBNAME. + * src/proto.h (_gdbm_base64_encode,_gdbm_base64_decode) + (_gdbm_load,_gdbm_dump): New prototypes. + + * src/testgdbm.c: Use gdbmapp interface for option parsing. + + * export/export.c: Include gdbmexp.c + * export/.cvsignore: Update. + * doc/gdbm.texinfo: Update. + +2011-11-13 Sergey Poznyakoff <gray@gnu.org.ua> + Version 1.10 * NEWS: Raise version number. diff --git a/configure.ac b/configure.ac index 421e230..fec5d0d 100644 --- a/configure.ac +++ b/configure.ac @@ -91,11 +91,11 @@ dnl Internationalization macros. AM_GNU_GETTEXT([external], [need-ngettext]) AM_GNU_GETTEXT_VERSION(0.18) -AC_CHECK_HEADERS([stdlib.h string.h sys/file.h unistd.h fcntl.h sys/types.h memory.h sys/termios.h locale.h]) +AC_CHECK_HEADERS([sys/file.h sys/termios.h string.h locale.h getopt.h]) AC_CHECK_LIB(dbm, main) AC_CHECK_LIB(ndbm, main) -AC_CHECK_FUNCS([rename ftruncate flock lockf fsync setlocale]) +AC_CHECK_FUNCS([rename ftruncate flock lockf fsync setlocale getopt_long]) if test x$mapped_io = xyes then diff --git a/doc/gdbm.texinfo b/doc/gdbm.texinfo index efd8cb5..ff93a1a 100644 --- a/doc/gdbm.texinfo +++ b/doc/gdbm.texinfo @@ -951,27 +951,34 @@ existing @acronym{GDBM} database or to create a new one. @cindex default database, @command{testgdbm} @cindex @option{-g}, @command{testgdbm} option +@cindex @option{-f}, @command{testgdbm} option +@cindex @option{--file}, @command{testgdbm} option @flindex junk.gdbm When invoked without options, it tries to open a database file called @file{junk.gdbm}, located in the current working directory. You can -change this default using the @option{-g} command line option. This +change this default using the @option{--file} (@option{-f}) command +line option@footnote{For compatibility with earlier versions, the +@option{-g} option acts as an alias to @option{-f}}. This option takes a single argument, specifying the file name to open, e.g.: @example -$ testgdbm -g file.db +$ testgdbm -f file.db @end example @cindex read-only mode, @command{testgdbm} @cindex @option{-r}, @command{testgdbm} option -The database will be opened in read-write mode, unless the @option{-r} -option is specified, in which case it will be opened only for reading. +@cindex @option{--read-only}, @command{testgdbm} option +The database will be opened in read-write mode, unless the +@option{-r} (@option{--read-only}) option is specified, in which case +it will be opened only for reading. @cindex creating a database, @command{testgdbm} @cindex @option{-n}, @command{testgdbm} option +@cindex @option{--newdb}, @command{testgdbm} option If the database does not exist, @command{testgdbm} will create it. -There is a special option @option{-n}, which instructs the utility to -create a new database. If it is used and if the database already -exists, it will be deleted, so use it sparingly. +There is a special option @option{-n} (@option{--newdb}, which +instructs the utility to create a new database. If it is used and if +the database already exists, it will be deleted, so use it sparingly. @menu * invocation:: @@ -987,21 +994,39 @@ options: @table @option @item -b @var{size} +@itemx --block-size=@var{size} Set block size. @item -c @var{size} +@itemx --cache-size=@var{size} Set cache size. -@item -g @var{file} +@item -f @var{file} +@itemx -g @var{file} +@itemx --file=@var{file} Operate on @var{file} instead of the default @file{junk.gdbm}. @item -h +@itemx --help Print a concise help summary. @item -n +@itemx --newdb Create the database. +@item -l +@itemx --no-lock +Disable file locking. +@item -m +@itemx --no-mmap +Disable mmap. @item -r +@itemx --read-only Open the database in read-only mode. @item -s +@itemx --synchronize Synchronize to the disk after each write. -@item -v +@item -V +@itemx --version Print program version and licensing information and exit. +@item --usage +Print a terse invocation syntax summary along with a list of available +command line options. @end table @node shell diff --git a/export/.cvsignore b/export/.cvsignore index e995588..62e7a85 100644 --- a/export/.cvsignore +++ b/export/.cvsignore @@ -1,3 +1,5 @@ .deps +.libs Makefile Makefile.in +gdbmexport diff --git a/export/export.c b/export/export.c index d2a56a1..2ef4e6c 100644 --- a/export/export.c +++ b/export/export.c @@ -23,9 +23,8 @@ #include <gdbm.h> -/* Include flatfile.c to pull in gdbm_export() */ -#define _GDBMEXPORT_ -#include "flatfile.c" +/* Pull in gdbm_export() */ +#include "gdbmexp.c" void usage (char *s) diff --git a/src/.cvsignore b/src/.cvsignore index ee2dbd5..46838d7 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -7,3 +7,5 @@ gdbm.h *.lo libgdbm.la testgdbm +gdbm_dump +gdbm_load diff --git a/src/Makefile.am b/src/Makefile.am index 1c55a4e..2d7a81a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,22 +37,26 @@ lib_LTLIBRARIES = libgdbm.la libgdbm_la_LIBADD = @LTLIBINTL@ libgdbm_la_SOURCES = \ - gdbmopen.c\ - gdbmdelete.c\ - gdbmfetch.c\ - gdbmstore.c\ gdbmclose.c\ - gdbmreorg.c\ - gdbmseq.c\ - gdbmsync.c\ + gdbmdelete.c\ + gdbmdump.c\ gdbmerrno.c\ gdbmexists.c\ + gdbmexp.c\ gdbmfdesc.c\ + gdbmfetch.c\ + gdbmload.c\ + gdbmopen.c\ + gdbmimp.c\ + gdbmreorg.c\ + gdbmseq.c\ gdbmsetopt.c\ + gdbmstore.c\ + gdbmsync.c\ + base64.c\ bucket.c\ falloc.c\ findkey.c\ - flatfile.c\ fullio.c\ hash.c\ lock.c\ @@ -62,6 +66,17 @@ libgdbm_la_SOURCES = \ libgdbm_la_LDFLAGS = -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) +noinst_LIBRARIES = libgdbmapp.a + +libgdbmapp_a_SOURCES =\ + err.c\ + mem.c\ + gdbmapp.h\ + parseopt.c\ + progname.c + # Programs -bin_PROGRAMS = testgdbm -testgdbm_LDADD = ./libgdbm.la +bin_PROGRAMS = testgdbm gdbm_load gdbm_dump +testgdbm_LDADD = ./libgdbmapp.a ./libgdbm.la +gdbm_load_LDADD = ./libgdbmapp.a ./libgdbm.la +gdbm_dump_LDADD = ./libgdbmapp.a ./libgdbm.la diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 0000000..bf2bf6a --- /dev/null +++ b/src/base64.c @@ -0,0 +1,127 @@ +/* This file is part of GDBM, the GNU data base manager. + Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. */ + +# include "autoconf.h" +# include "gdbmdefs.h" +# include "gdbm.h" + +static char b64tab[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static int b64val[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 +}; + +int +_gdbm_base64_encode (const unsigned char *input, size_t input_len, + unsigned char **output, size_t *output_size, + size_t *nbytes) +{ + size_t olen = 4 * (input_len + 2) / 3 + 1; + unsigned char *out; + + if (olen > *output_size) + { + out = realloc (*output, olen); + if (!out) + return GDBM_MALLOC_ERROR; + *output = out; + *output_size = olen; + } + else + out = *output; + + while (input_len >= 3) + { + *out++ = b64tab[input[0] >> 2]; + *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)]; + *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)]; + *out++ = b64tab[input[2] & 0x3f]; + input_len -= 3; + input += 3; + } + + if (input_len > 0) + { + unsigned char c = (input[0] << 4) & 0x30; + *out++ = b64tab[input[0] >> 2]; + if (input_len > 1) + c |= input[1] >> 4; + *out++ = b64tab[c]; + *out++ = (input_len < 2) ? '=' : b64tab[(input[1] << 2) & 0x3c]; + *out++ = '='; + } + *out = 0; + *nbytes = out - *output; + return 0; +} + +int +_gdbm_base64_decode (const unsigned char *input, size_t input_len, + unsigned char **output, size_t *output_size, + size_t *inbytes, size_t *outbytes) +{ + int rc = 0; + int olen = input_len; + unsigned char *out; + size_t ins = 0; + + if (olen > *output_size) + { + out = realloc (*output, olen); + if (!out) + return GDBM_MALLOC_ERROR; + *output = out; + *output_size = olen; + } + else + out = *output; + + do + { + if (input_len < 4) + break; + if (input[0] > 127 || b64val[input[0]] == -1 + || input[1] > 127 || b64val[input[1]] == -1 + || input[2] > 127 || ((input[2] != '=') && (b64val[input[2]] == -1)) + || input[3] > 127 || ((input[3] != '=') + && (b64val[input[3]] == -1))) + { + rc = GDBM_ILLEGAL_DATA; + break; + } + *out++ = (b64val[input[0]] << 2) | (b64val[input[1]] >> 4); + if (input[2] != '=') + { + *out++ = ((b64val[input[1]] << 4) & 0xf0) | (b64val[input[2]] >> 2); + if (input[3] != '=') + *out++ = ((b64val[input[2]] << 6) & 0xc0) | b64val[input[3]]; + } + input += 4; + input_len -= 4; + ins += 4; + } + while (input_len > 0); + *inbytes = ins; + *outbytes = out - *output; + return rc; +} diff --git a/src/flatfile.c b/src/flatfile.c deleted file mode 100644 index c0f9422..0000000 --- a/src/flatfile.c +++ /dev/null @@ -1,246 +0,0 @@ -/* flatfile.c - Import/export a GDBM database. */ - -/* This file is part of GDBM, the GNU data base manager. - Copyright (C) 2007, 2011 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 <http://www.gnu.org/licenses/>. */ - -#ifndef _GDBMEXPORT_ - -/* Include system configuration before all else. */ -# include "autoconf.h" -# include <arpa/inet.h> - -# include "gdbmdefs.h" -# include "gdbm.h" - -#endif - -int -gdbm_export (GDBM_FILE dbf, const char *exportfile, int flags, int mode) -{ - int nfd, size; - datum key, nextkey, data; - const char *header1 = "!\r\n! GDBM FLAT FILE DUMP -- THIS IS NOT A TEXT FILE\r\n! "; - const char *header2 = "\r\n!\r\n"; - int count = 0; - - /* Only support GDBM_WCREAT or GDBM_NEWDB */ - switch (flags) - { - case GDBM_WRCREAT: - nfd = open (exportfile, O_WRONLY | O_CREAT | O_EXCL, mode); - if (nfd == -1) - { - gdbm_errno = GDBM_FILE_OPEN_ERROR; - return -1; - } - break; - case GDBM_NEWDB: - nfd = open (exportfile, O_WRONLY | O_CREAT | O_TRUNC, mode); - if (nfd == -1) - { - gdbm_errno = GDBM_FILE_OPEN_ERROR; - return -1; - } - break; - default: -#ifdef GDBM_BAD_OPEN_FLAGS - gdbm_errno = GDBM_BAD_OPEN_FLAGS; -#else - gdbm_errno = GDBM_FILE_OPEN_ERROR; -#endif - return -1; - } - - /* Write out the text header. */ - if (write (nfd, header1, strlen (header1)) != strlen (header1)) - goto write_fail; - if (write (nfd, gdbm_version, strlen (gdbm_version)) != strlen (gdbm_version)) - goto write_fail; - if (write (nfd, header2, strlen (header2)) != strlen (header2)) - goto write_fail; - - /* For each item in the database, write out a record to the file. */ - key = gdbm_firstkey (dbf); - - while (key.dptr != NULL) - { - data = gdbm_fetch (dbf, key); - if (data.dptr != NULL) - { - /* Add the data to the new file. */ - size = htonl (key.dsize); - if (write (nfd, &size, sizeof(int)) != sizeof (int)) - goto write_fail; - if (write (nfd, key.dptr, key.dsize) != key.dsize) - goto write_fail; - - size = htonl (data.dsize); - if (write (nfd, &size, sizeof(int)) != sizeof (int)) - goto write_fail; - if (write (nfd, data.dptr, data.dsize) != data.dsize) - goto write_fail; - } - nextkey = gdbm_nextkey (dbf, key); - free (key.dptr); - free (data.dptr); - key = nextkey; - - count++; - } - close (nfd); - - return count; - - write_fail: - - gdbm_errno = GDBM_FILE_WRITE_ERROR; - return -1; -} - -#ifndef _GDBMEXPORT_ - -int -gdbm_import (GDBM_FILE dbf, const char *importfile, int flag) -{ - int ifd, seenbang, seennewline, rsize, size, kbufsize, dbufsize, rret; - char c, *kbuffer, *dbuffer; - datum key, data; - int count = 0; - - ifd = open (importfile, O_RDONLY, 0); - if (ifd == -1) - { - gdbm_errno = GDBM_FILE_OPEN_ERROR; - return -1; - } - - seenbang = 0; - seennewline = 0; - kbuffer = NULL; - dbuffer = NULL; - - /* Read (and discard) four lines begining with ! and ending with \n. */ - while (1) - { - if (read (ifd, &c, 1) != 1) - goto read_fail; - - if (c == '!') - seenbang++; - if (c == '\n') - { - if (seenbang > 3 && seennewline > 2) - { - /* End of last line. */ - break; - } - seennewline++; - } - } - - /* Allocate buffers. */ - kbufsize = 512; - kbuffer = malloc (kbufsize); - if (kbuffer == NULL) - { - gdbm_errno = GDBM_MALLOC_ERROR; - close (ifd); - return -1; - } - dbufsize = 512; - dbuffer = malloc (dbufsize); - if (dbuffer == NULL) - { - gdbm_errno = GDBM_MALLOC_ERROR; - close (ifd); - return -1; - } - - /* Insert/replace records in the database until we run out of file. */ - while ((rret = read (ifd, &rsize, sizeof(rsize))) != 0) - { - if (rret != sizeof(rsize)) - goto read_fail; - - /* Read the key. */ - size = ntohl (rsize); - if (size > kbufsize) - { - kbufsize = (size + 512); - kbuffer = realloc (kbuffer, kbufsize); - if (kbuffer == NULL) - { - gdbm_errno = GDBM_MALLOC_ERROR; - close (ifd); - return -1; - } - } - if (read (ifd, kbuffer, size) != size) - goto read_fail; - - key.dptr = kbuffer; - key.dsize = size; - - /* Read the data. */ - if (read (ifd, &rsize, sizeof(rsize)) != sizeof(rsize)) - goto read_fail; - - size = ntohl (rsize); - if (size > dbufsize) - { - dbufsize = (size + 512); - dbuffer = realloc (dbuffer, dbufsize); - if (dbuffer == NULL) - { - gdbm_errno = GDBM_MALLOC_ERROR; - close (ifd); - return -1; - } - } - if (read (ifd, dbuffer, size) != size) - goto read_fail; - - data.dptr = dbuffer; - data.dsize = size; - - if (gdbm_store (dbf, key, data, flag) != 0) - { - /* Keep the existing errno. */ - free (kbuffer); - free (dbuffer); - close (ifd); - return -1; - } - - count++; - } - - close (ifd); - return count; - -read_fail: - - if (kbuffer != NULL) - free (kbuffer); - if (dbuffer != NULL) - free (dbuffer); - - close (ifd); - - gdbm_errno = GDBM_FILE_READ_ERROR; - return -1; -} -#endif diff --git a/src/gdbm.h.in b/src/gdbm.h.in index 21168de..81e9943 100644 --- a/src/gdbm.h.in +++ b/src/gdbm.h.in @@ -29,6 +29,8 @@ #ifndef _GDBM_H_ # define _GDBM_H_ +# include <stdio.h> + /* GDBM C++ support */ # if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -111,8 +113,24 @@ extern void gdbm_sync (GDBM_FILE); extern int gdbm_exists (GDBM_FILE, datum); extern int gdbm_setopt (GDBM_FILE, int, void *, int); extern int gdbm_fdesc (GDBM_FILE); + extern int gdbm_export (GDBM_FILE, const char *, int, int); +extern int gdbm_export_to_file (GDBM_FILE dbf, FILE *fp); + extern int gdbm_import (GDBM_FILE, const char *, int); +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 + +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, + unsigned long *line); +extern int gdbm_load_from_file (GDBM_FILE *, FILE *, int replace, + unsigned long *line); # define GDBM_NO_ERROR 0 # define GDBM_MALLOC_ERROR 1 @@ -140,9 +158,10 @@ extern int gdbm_import (GDBM_FILE, const char *, int); # define GDBM_BAD_OPEN_FLAGS 23 # define GDBM_FILE_STAT_ERROR 24 # define GDBM_FILE_EOF 25 - +# define GDBM_NO_DBNAME 26 + # define _GDBM_MIN_ERRNO 0 -# define _GDBM_MAX_ERRNO GDBM_FILE_EOF +# define _GDBM_MAX_ERRNO GDBM_NO_DBNAME typedef int gdbm_error; /* For compatibilities sake. */ extern gdbm_error gdbm_errno; extern const char * const gdbm_errlist[]; diff --git a/src/gdbm_dump.c b/src/gdbm_dump.c new file mode 100644 index 0000000..6ea94e6 --- /dev/null +++ b/src/gdbm_dump.c @@ -0,0 +1,124 @@ +/* This file is part of GDBM, the GNU data base manager. + Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. */ + +# include "autoconf.h" +# include "gdbm.h" +# include "gdbmapp.h" +# include "gdbmdefs.h" + +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 } +}; + +int format = GDBM_DUMP_FMT_ASCII; + +int +main (int argc, char **argv) +{ + GDBM_FILE dbf; + int rc, opt; + char *dbname, *filename; + FILE *fp; + + set_progname (argv[0]); + + for (opt = parseopt_first (argc, argv, optab); + opt != EOF; + opt = parseopt_next ()) + { + switch (opt) + { + case 'b': + format = GDBM_DUMP_FMT_BINARY; + break; + + case 'H': + format = atoi (optarg); + switch (format) + { + case GDBM_DUMP_FMT_BINARY: + case GDBM_DUMP_FMT_ASCII: + break; + default: + error (_("unknown dump format")); + exit (2); + } + break; + + default: + error (_("unknown option")); + exit (2); + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) + { + parseopt_print_help (); + exit (0); + } + + if (argc > 2) + { + error (_("too many arguments; try `%s -h' for more info"), progname); + exit (2); + } + + dbname = argv[0]; + if (argc == 2) + filename = argv[1]; + else + filename = NULL; + + if (!filename || strcmp (filename, "-") == 0) + { + filename = "<stdout>"; + fp = stdout; + } + else + { + fp = fopen (filename, "w"); + if (!fp) + { + sys_perror (errno, _("cannot open %s"), filename); + exit (1); + } + } + + dbf = gdbm_open (dbname, 0, GDBM_READER, 0600, NULL); + if (!dbf) + { + gdbm_perror (_("gdbm_open failed")); + exit (1); + } + + rc = gdbm_dump_to_file (dbf, fp, format); + if (rc) + { + gdbm_perror (_("dump error"), filename); + } + + gdbm_close (dbf); + + exit (!!rc); +} + diff --git a/src/gdbm_load.c b/src/gdbm_load.c new file mode 100644 index 0000000..4e14207 --- /dev/null +++ b/src/gdbm_load.c @@ -0,0 +1,140 @@ +/* This file is part of GDBM, the GNU data base manager. + Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. */ + +# include "autoconf.h" +# 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 +*/ + +int replace = 0; + +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") }, + { 0 } +}; + +int +main (int argc, char **argv) +{ + GDBM_FILE dbf = NULL; + int rc, opt; + char *dbname, *filename; + FILE *fp; + unsigned long err_line; + + set_progname (argv[0]); + + for (opt = parseopt_first (argc, argv, optab); + opt != EOF; + opt = parseopt_next ()) + { + switch (opt) + { + case 'r': + replace = 1; + break; + + default: + error (_("unknown option")); + exit (2); + } + } + + argc -= optind; + argv += optind; + + if (argc == 0) + { + parseopt_print_help (); + exit (0); + } + + if (argc > 2) + { + error (_("too many arguments; try `%s -h' for more info"), progname); + exit (2); + } + + filename = argv[0]; + if (argc == 2) + dbname = argv[1]; + else + dbname = NULL; + + if (strcmp (filename, "-") == 0) + { + filename = "<stdin>"; + fp = stdin; + } + else + { + fp = fopen (filename, "r"); + if (!fp) + { + sys_perror (errno, _("cannot open %s"), filename); + exit (1); + } + } + + if (dbname) + { + dbf = gdbm_open (dbname, 0, GDBM_NEWDB, 0600, NULL); + if (!dbf) + { + gdbm_perror (_("gdbm_open failed")); + exit (1); + } + } + + rc = gdbm_load_from_file (&dbf, fp, replace, &err_line); + if (rc) + { + if (err_line) + gdbm_perror ("%s:%lu", filename, err_line); + else + gdbm_perror ("cannot load from %s", filename); + } + + if (dbf) + { + if (!dbname) + { + if (gdbm_setopt (dbf, GDBM_GETDBNAME, &dbname, sizeof (dbname))) + gdbm_perror (_("gdbm_setopt failed")); + else + { + printf ("%s: created %s\n", progname, dbname); + free (dbname); + } + } + gdbm_close (dbf); + } + exit (!!rc); +} diff --git a/src/gdbmapp.h b/src/gdbmapp.h new file mode 100644 index 0000000..e7917f9 --- /dev/null +++ b/src/gdbmapp.h @@ -0,0 +1,52 @@ +/* This file is part of GDBM, the GNU data base manager. + Copyright (C) 2011 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 <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> +#include <stdarg.h> + +extern const char *progname; + +void set_progname (const char *arg); +void gdbm_perror (const char *fmt, ...); +void sys_perror (int code, const char *fmt, ...); +void error (const char *fmt, ...); +void verror (const char *fmt, va_list ap); + +void *emalloc (size_t size); +void *erealloc (void *ptr, size_t size); +void *ecalloc (size_t nmemb, size_t size); +void *ezalloc (size_t size); +char *estrdup (char *str); + +#define PARSEOPT_HIDDEN 0x01 +#define PARSEOPT_ALIAS 0x02 + +struct gdbm_option +{ + int opt_short; + char *opt_long; + char *opt_arg; + char *opt_descr; + int opt_flags; +}; + +int parseopt_first (int pc, char **pv, struct gdbm_option *options); +int parseopt_next (void); +void parseopt_print_help (void); + +extern char *parseopt_program_name; +extern char *parseopt_program_doc; +extern char *parseopt_program_args; diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h index 519d688..4ebb190 100644 --- a/src/gdbmdefs.h +++ b/src/gdbmdefs.h @@ -217,5 +217,7 @@ struct gdbm_file_info { } \ while (0) \ +#define _GDBM_MAX_DUMP_LINE_LEN 76 + /* Now define all the routines in use. */ #include "proto.h" diff --git a/src/ |