aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-05-13 21:10:40 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2013-05-13 21:10:40 +0000
commit6d66bc4877a319d0f6400f5058be47f221e731da (patch)
treefa767d22262801297ffac0aedf25f4eec904751d
parentf1a89bc4e380c1fd331f26baa1376233acbc7772 (diff)
downloadgdbm-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--ChangeLog8
-rw-r--r--src/datconv.c2
-rw-r--r--src/gdbmapp.h4
-rw-r--r--src/gdbmload.c115
-rw-r--r--src/gdbmtool.h1
5 files changed, 127 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 7e8b390..3dd14f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
{

Return to:

Send suggestions and report system problems to the System administrator.