aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog49
-rw-r--r--configure.ac4
-rw-r--r--doc/gdbm.texinfo43
-rw-r--r--export/.cvsignore2
-rw-r--r--export/export.c5
-rw-r--r--src/.cvsignore2
-rw-r--r--src/Makefile.am35
-rw-r--r--src/base64.c127
-rw-r--r--src/flatfile.c246
-rw-r--r--src/gdbm.h.in23
-rw-r--r--src/gdbm_dump.c124
-rw-r--r--src/gdbm_load.c140
-rw-r--r--src/gdbmapp.h52
-rw-r--r--src/gdbmdefs.h2
-rw-r--r--src/gdbmdump.c193
-rw-r--r--src/gdbmerrno.c1
-rw-r--r--src/gdbmexp.c125
-rw-r--r--src/gdbmimp.c157
-rw-r--r--src/gdbmload.c502
-rw-r--r--src/mem.c74
-rw-r--r--src/parseopt.c585
-rw-r--r--src/progname.c35
-rw-r--r--src/proto.h12
-rw-r--r--src/systems.h16
-rw-r--r--src/testgdbm.c142
25 files changed, 2322 insertions, 374 deletions
diff --git a/ChangeLog b/ChangeLog
index f90b8a4..8072ea2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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/