diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-05-13 21:10:40 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-05-13 21:10:40 +0000 |
commit | 6d66bc4877a319d0f6400f5058be47f221e731da (patch) | |
tree | fa767d22262801297ffac0aedf25f4eec904751d | |
parent | f1a89bc4e380c1fd331f26baa1376233acbc7772 (diff) | |
download | gdbm-6d66bc4877a319d0f6400f5058be47f221e731da.tar.gz gdbm-6d66bc4877a319d0f6400f5058be47f221e731da.tar.bz2 |
Add support for Berkeley dump format version 3 (read-only).
* src/gdbmapp.h: Include gettext.h and locale.h.
* src/gdbmload.c: Support for Berkeley dump format,
version 3.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/datconv.c | 2 | ||||
-rw-r--r-- | src/gdbmapp.h | 4 | ||||
-rw-r--r-- | src/gdbmload.c | 115 | ||||
-rw-r--r-- | src/gdbmtool.h | 1 |
5 files changed, 127 insertions, 3 deletions
@@ -1,3 +1,11 @@ +2013-05-14 Sergey Poznyakoff <gray@gnu.org.ua> + + Add support for Berkeley dump format version 3 (read-only). + + * src/gdbmapp.h: Include gettext.h and locale.h. + * src/gdbmload.c: Support for Berkeley dump format, + version 3. + 2013-05-13 Sergey Poznyakoff <gray@gnu.org.ua> Remove the "read" command. Use "import" instead. diff --git a/src/datconv.c b/src/datconv.c index 19049aa..6f5e2f5 100644 --- a/src/datconv.c +++ b/src/datconv.c @@ -301,7 +301,7 @@ xd_store (struct xdatum *xd, void *val, size_t size) if (xd->off > xd->dsize) xd->dsize = xd->off; } - + int datum_scan_notag (datum *dat, struct dsegm *ds, struct kvpair *kv) { diff --git a/src/gdbmapp.h b/src/gdbmapp.h index 0de0005..d978cef 100644 --- a/src/gdbmapp.h +++ b/src/gdbmapp.h @@ -16,6 +16,10 @@ #include <stdlib.h> #include <stdarg.h> +#include "gettext.h" +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif extern const char *progname; diff --git a/src/gdbmload.c b/src/gdbmload.c index 40a63b9..4a0c2de 100644 --- a/src/gdbmload.c +++ b/src/gdbmload.c @@ -454,6 +454,113 @@ _gdbm_load_file (struct dump_file *file, GDBM_FILE dbf, GDBM_FILE *ofp, return rc; } +static int +read_bdb_header (struct dump_file *file) +{ + char buf[256]; + + file->line = 1; + if (!fgets (buf, sizeof (buf), file->fp)) + return -1; + if (strcmp (buf, "VERSION=3\n")) + return -1; + while (fgets (buf, sizeof (buf), file->fp)) + { + ++file->line; + if (strcmp (buf, "HEADER=END\n") == 0) + return 0; + } + return -1; +} + +static int +c2x (int c) +{ + static char xdig[] = "0123456789abcdef"; + char *p = strchr (xdig, c); + if (!p) + return -1; + return p - xdig; +} + +#define DINCR 128 + +static int +xdatum_read (FILE *fp, datum *d, size_t *pdmax) +{ + int c; + size_t dmax = *pdmax; + + d->dsize = 0; + while ((c = fgetc (fp)) != EOF && c != '\n') + { + int t, n; + + t = c2x (c); + if (t == -1) + return EOF; + t <<= 4; + + if ((c = fgetc (fp)) == EOF) + break; + + n = c2x (c); + if (n == -1) + return EOF; + t += n; + + if (d->dsize == dmax) + { + char *np = realloc (d->dptr, dmax + DINCR); + if (!np) + return GDBM_MALLOC_ERROR; + d->dptr = np; + dmax += DINCR; + } + d->dptr[d->dsize++] = t; + } + *pdmax = dmax; + if (c == '\n') + return 0; + return c; +} + +int +gdbm_load_bdb_dump (struct dump_file *file, GDBM_FILE dbf, int replace) +{ + datum xd[2]; + size_t xs[2]; + int rc, c; + int i; + + if (read_bdb_header (file)) + return -1; + memset (&xd, 0, sizeof (xd)); + xs[0] = xs[1] = 0; + i = 0; + while ((c = fgetc (file->fp)) == ' ') + { + rc = xdatum_read (file->fp, &xd[i], &xs[i]); + if (rc) + break; + ++file->line; + + if (i == 1) + { + if (gdbm_store (dbf, xd[0], xd[1], replace)) + return gdbm_errno; + } + i = !i; + } + //FIXME: Read "DATA=END" + free (xd[0].dptr); + free (xd[1].dptr); + if (rc == 0 && i) + rc = EOF; + + return rc; +} + int gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace, int meta_mask, @@ -481,10 +588,14 @@ gdbm_load_from_file (GDBM_FILE *pdbf, FILE *fp, int replace, return -1; return 0; } - + memset (&df, 0, sizeof df); df.fp = fp; - rc = _gdbm_load_file (&df, *pdbf, pdbf, replace, meta_mask); + + if (rc == 'V') + rc = gdbm_load_bdb_dump (&df, *pdbf, replace); + else + rc = _gdbm_load_file (&df, *pdbf, pdbf, replace, meta_mask); dump_file_free (&df); if (rc) { diff --git a/src/gdbmtool.h b/src/gdbmtool.h index a4df02a..4097629 100644 --- a/src/gdbmtool.h +++ b/src/gdbmtool.h @@ -173,6 +173,7 @@ int run_command (struct command *cmd, struct gdbmarglist *arglist); struct xdatum; void xd_expand (struct xdatum *xd, size_t size); void xd_store (struct xdatum *xd, void *val, size_t size); + struct datadef { |