]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb_load.c
Happy New Year
[openldap] / libraries / liblmdb / mdb_load.c
index 326e8e78a7daee42277ecf50276aa6fbe6ae7ba4..cf1d42e93bc7d3b8c9271341dc8f270a257c1ba1 100644 (file)
@@ -1,6 +1,6 @@
 /* mdb_load.c - memory-mapped database load tool */
 /*
- * Copyright 2011-2014 Howard Chu, Symas Corp.
+ * Copyright 2011-2018 Howard Chu, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,10 +32,18 @@ static int flags;
 
 static char *prog;
 
-static int eof;
+static int Eof;
+
+static MDB_envinfo info;
 
 static MDB_val kbuf, dbuf;
 
+#ifdef _WIN32
+#define Z      "I"
+#else
+#define Z      "z"
+#endif
+
 #define STRLENOF(s)    (sizeof(s)-1)
 
 typedef struct flagbit {
@@ -56,28 +64,26 @@ flagbit dbflags[] = {
        { 0, NULL, 0 }
 };
 
-static const char hexc[] = "0123456789abcdef";
-
-static void readhdr()
+static void readhdr(void)
 {
        char *ptr;
 
        while (fgets(dbuf.mv_data, dbuf.mv_size, stdin) != NULL) {
                lineno++;
                if (!strncmp(dbuf.mv_data, "VERSION=", STRLENOF("VERSION="))) {
-                       version=atoi(dbuf.mv_data+STRLENOF("VERSION="));
+                       version=atoi((char *)dbuf.mv_data+STRLENOF("VERSION="));
                        if (version > 3) {
-                               fprintf(stderr, "%s: line %zd: unsupported VERSION %d\n",
+                               fprintf(stderr, "%s: line %" Z "d: unsupported VERSION %d\n",
                                        prog, lineno, version);
                                exit(EXIT_FAILURE);
                        }
                } else if (!strncmp(dbuf.mv_data, "HEADER=END", STRLENOF("HEADER=END"))) {
                        break;
                } else if (!strncmp(dbuf.mv_data, "format=", STRLENOF("format="))) {
-                       if (!strncmp(dbuf.mv_data+STRLENOF("FORMAT="), "print", STRLENOF("print")))
+                       if (!strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "print", STRLENOF("print")))
                                mode |= PRINT;
-                       else if (strncmp(dbuf.mv_data+STRLENOF("FORMAT="), "bytevalue", STRLENOF("bytevalue"))) {
-                               fprintf(stderr, "%s: line %zd: unsupported FORMAT %s\n",
+                       else if (strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "bytevalue", STRLENOF("bytevalue"))) {
+                               fprintf(stderr, "%s: line %" Z "d: unsupported FORMAT %s\n",
                                        prog, lineno, (char *)dbuf.mv_data+STRLENOF("FORMAT="));
                                exit(EXIT_FAILURE);
                        }
@@ -85,13 +91,43 @@ static void readhdr()
                        ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
                        if (ptr) *ptr = '\0';
                        if (subname) free(subname);
-                       subname = strdup(dbuf.mv_data+STRLENOF("database="));
+                       subname = strdup((char *)dbuf.mv_data+STRLENOF("database="));
                } else if (!strncmp(dbuf.mv_data, "type=", STRLENOF("type="))) {
-                       if (strncmp(dbuf.mv_data+STRLENOF("type="), "btree", STRLENOF("btree")))  {
-                               fprintf(stderr, "%s: line %zd: unsupported type %s\n",
+                       if (strncmp((char *)dbuf.mv_data+STRLENOF("type="), "btree", STRLENOF("btree")))  {
+                               fprintf(stderr, "%s: line %" Z "d: unsupported type %s\n",
                                        prog, lineno, (char *)dbuf.mv_data+STRLENOF("type="));
                                exit(EXIT_FAILURE);
                        }
+               } else if (!strncmp(dbuf.mv_data, "mapaddr=", STRLENOF("mapaddr="))) {
+                       int i;
+                       ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
+                       if (ptr) *ptr = '\0';
+                       i = sscanf((char *)dbuf.mv_data+STRLENOF("mapaddr="), "%p", &info.me_mapaddr);
+                       if (i != 1) {
+                               fprintf(stderr, "%s: line %" Z "d: invalid mapaddr %s\n",
+                                       prog, lineno, (char *)dbuf.mv_data+STRLENOF("mapaddr="));
+                               exit(EXIT_FAILURE);
+                       }
+               } else if (!strncmp(dbuf.mv_data, "mapsize=", STRLENOF("mapsize="))) {
+                       int i;
+                       ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
+                       if (ptr) *ptr = '\0';
+                       i = sscanf((char *)dbuf.mv_data+STRLENOF("mapsize="), "%" Z "u", &info.me_mapsize);
+                       if (i != 1) {
+                               fprintf(stderr, "%s: line %" Z "d: invalid mapsize %s\n",
+                                       prog, lineno, (char *)dbuf.mv_data+STRLENOF("mapsize="));
+                               exit(EXIT_FAILURE);
+                       }
+               } else if (!strncmp(dbuf.mv_data, "maxreaders=", STRLENOF("maxreaders="))) {
+                       int i;
+                       ptr = memchr(dbuf.mv_data, '\n', dbuf.mv_size);
+                       if (ptr) *ptr = '\0';
+                       i = sscanf((char *)dbuf.mv_data+STRLENOF("maxreaders="), "%u", &info.me_maxreaders);
+                       if (i != 1) {
+                               fprintf(stderr, "%s: line %" Z "d: invalid maxreaders %s\n",
+                                       prog, lineno, (char *)dbuf.mv_data+STRLENOF("maxreaders="));
+                               exit(EXIT_FAILURE);
+                       }
                } else {
                        int i;
                        for (i=0; dbflags[i].bit; i++) {
@@ -104,12 +140,12 @@ static void readhdr()
                        if (!dbflags[i].bit) {
                                ptr = memchr(dbuf.mv_data, '=', dbuf.mv_size);
                                if (!ptr) {
-                                       fprintf(stderr, "%s: line %zd: unexpected format\n",
+                                       fprintf(stderr, "%s: line %" Z "d: unexpected format\n",
                                                prog, lineno);
                                        exit(EXIT_FAILURE);
                                } else {
                                        *ptr = '\0';
-                                       fprintf(stderr, "%s: line %zd: unrecognized keyword ignored: %s\n",
+                                       fprintf(stderr, "%s: line %" Z "d: unrecognized keyword ignored: %s\n",
                                                prog, lineno, (char *)dbuf.mv_data);
                                }
                        }
@@ -117,9 +153,9 @@ static void readhdr()
        }
 }
 
-static void badend()
+static void badend(void)
 {
-       fprintf(stderr, "%s: line %zd: unexpected end of input\n",
+       fprintf(stderr, "%s: line %" Z "d: unexpected end of input\n",
                prog, lineno);
 }
 
@@ -140,19 +176,20 @@ static int unhex(unsigned char *c2)
 static int readline(MDB_val *out, MDB_val *buf)
 {
        unsigned char *c1, *c2, *end;
-       size_t len;
+       size_t len, l2;
        int c;
 
        if (!(mode & NOHDR)) {
                c = fgetc(stdin);
                if (c == EOF) {
-                       eof = 1;
+                       Eof = 1;
                        return EOF;
                }
                if (c != ' ') {
+                       lineno++;
                        if (fgets(buf->mv_data, buf->mv_size, stdin) == NULL) {
 badend:
-                               eof = 1;
+                               Eof = 1;
                                badend();
                                return EOF;
                        }
@@ -162,35 +199,37 @@ badend:
                }
        }
        if (fgets(buf->mv_data, buf->mv_size, stdin) == NULL) {
-               eof = 1;
+               Eof = 1;
                return EOF;
        }
        lineno++;
 
        c1 = buf->mv_data;
        len = strlen((char *)c1);
+       l2 = len;
 
        /* Is buffer too short? */
        while (c1[len-1] != '\n') {
                buf->mv_data = realloc(buf->mv_data, buf->mv_size*2);
                if (!buf->mv_data) {
-                       eof = 1;
-                       fprintf(stderr, "%s: line %zd: out of memory, line too long\n",
+                       Eof = 1;
+                       fprintf(stderr, "%s: line %" Z "d: out of memory, line too long\n",
                                prog, lineno);
                        return EOF;
                }
                c1 = buf->mv_data;
-               c1 += buf->mv_size;
-               if (fgets((char *)c1, buf->mv_size, stdin) == NULL) {
-                       eof = 1;
+               c1 += l2;
+               if (fgets((char *)c1, buf->mv_size+1, stdin) == NULL) {
+                       Eof = 1;
                        badend();
                        return EOF;
                }
                buf->mv_size *= 2;
                len = strlen((char *)c1);
+               l2 += len;
        }
        c1 = c2 = buf->mv_data;
-       len = strlen((char *)c1);
+       len = l2;
        c1[--len] = '\0';
        end = c1 + len;
 
@@ -200,8 +239,8 @@ badend:
                                if (c2[1] == '\\') {
                                        c1++; c2 += 2;
                                } else {
-                                       if (c2+3 >= end || !isxdigit(c2[1]) || !isxdigit(c2[2])) {
-                                               eof = 1;
+                                       if (c2+3 > end || !isxdigit(c2[1]) || !isxdigit(c2[2])) {
+                                               Eof = 1;
                                                badend();
                                                return EOF;
                                        }
@@ -209,19 +248,20 @@ badend:
                                        c2 += 2;
                                }
                        } else {
-                               c1++; c2++;
+                               /* copies are redundant when no escapes were used */
+                               *c1++ = *c2++;
                        }
                }
        } else {
                /* odd length not allowed */
                if (len & 1) {
-                       eof = 1;
+                       Eof = 1;
                        badend();
                        return EOF;
                }
                while (c2 < end) {
                        if (!isxdigit(*c2) || !isxdigit(c2[1])) {
-                               eof = 1;
+                               Eof = 1;
                                badend();
                                return EOF;
                        }
@@ -235,9 +275,9 @@ badend:
        return 0;
 }
 
-static void usage()
+static void usage(void)
 {
-       fprintf(stderr, "usage: %s dbpath [-V] [-f input] [-n] [-s name] [-N] [-T]\n", prog);
+       fprintf(stderr, "usage: %s [-V] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog);
        exit(EXIT_FAILURE);
 }
 
@@ -250,11 +290,12 @@ int main(int argc, char *argv[])
        MDB_dbi dbi;
        char *envname;
        int envflags = 0, putflags = 0;
+       int dohdr = 0;
 
        prog = argv[0];
 
        if (argc < 2) {
-               usage(prog);
+               usage();
        }
 
        /* -f: load file instead of stdin
@@ -287,90 +328,111 @@ int main(int argc, char *argv[])
                        putflags = MDB_NOOVERWRITE|MDB_NODUPDATA;
                        break;
                case 'T':
-                       mode |= NOHDR;
+                       mode |= NOHDR | PRINT;
                        break;
                default:
-                       usage(prog);
+                       usage();
                }
        }
 
        if (optind != argc - 1)
-               usage(prog);
+               usage();
+
+       dbuf.mv_size = 4096;
+       dbuf.mv_data = malloc(dbuf.mv_size);
+
+       if (!(mode & NOHDR))
+               readhdr();
 
        envname = argv[optind];
        rc = mdb_env_create(&env);
+       if (rc) {
+               fprintf(stderr, "mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc));
+               return EXIT_FAILURE;
+       }
 
        mdb_env_set_maxdbs(env, 2);
 
+       if (info.me_maxreaders)
+               mdb_env_set_maxreaders(env, info.me_maxreaders);
+
+       if (info.me_mapsize)
+               mdb_env_set_mapsize(env, info.me_mapsize);
+
+       if (info.me_mapaddr)
+               envflags |= MDB_FIXEDMAP;
+
        rc = mdb_env_open(env, envname, envflags, 0664);
        if (rc) {
-               printf("mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
+               fprintf(stderr, "mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
                goto env_close;
        }
 
        kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2;
        kbuf.mv_data = malloc(kbuf.mv_size);
-       dbuf.mv_size = 4096;
-       dbuf.mv_data = malloc(dbuf.mv_size);
 
-       while(!eof) {
+       while(!Eof) {
                MDB_val key, data;
                int batch = 0;
                flags = 0;
 
-               if (!(mode & NOHDR))
+               if (!dohdr) {
+                       dohdr = 1;
+               } else if (!(mode & NOHDR))
                        readhdr();
                
                rc = mdb_txn_begin(env, NULL, 0, &txn);
                if (rc) {
-                       printf("mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
+                       fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
                        goto env_close;
                }
 
                rc = mdb_open(txn, subname, flags|MDB_CREATE, &dbi);
                if (rc) {
-                       printf("mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
+                       fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
                        goto txn_abort;
                }
 
                rc = mdb_cursor_open(txn, dbi, &mc);
                if (rc) {
-                       printf("mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
+                       fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
                        goto txn_abort;
                }
 
                while(1) {
                        rc = readline(&key, &kbuf);
-                       if (rc == EOF)
+                       if (rc)  /* rc == EOF */
                                break;
-                       if (rc)
-                               goto txn_abort;
 
                        rc = readline(&data, &dbuf);
-                       if (rc)
+                       if (rc) {
+                               fprintf(stderr, "%s: line %" Z "d: failed to read key value\n", prog, lineno);
                                goto txn_abort;
-                       
+                       }
+
                        rc = mdb_cursor_put(mc, &key, &data, putflags);
                        if (rc == MDB_KEYEXIST && putflags)
                                continue;
-                       if (rc)
+                       if (rc) {
+                               fprintf(stderr, "mdb_cursor_put failed, error %d %s\n", rc, mdb_strerror(rc));
                                goto txn_abort;
+                       }
                        batch++;
                        if (batch == 100) {
                                rc = mdb_txn_commit(txn);
                                if (rc) {
-                                       fprintf(stderr, "%s: line %zd: txn_commit: %s\n",
+                                       fprintf(stderr, "%s: line %" Z "d: txn_commit: %s\n",
                                                prog, lineno, mdb_strerror(rc));
                                        goto env_close;
                                }
                                rc = mdb_txn_begin(env, NULL, 0, &txn);
                                if (rc) {
-                                       printf("mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
+                                       fprintf(stderr, "mdb_txn_begin failed, error %d %s\n", rc, mdb_strerror(rc));
                                        goto env_close;
                                }
                                rc = mdb_cursor_open(txn, dbi, &mc);
                                if (rc) {
-                                       printf("mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
+                                       fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
                                        goto txn_abort;
                                }
                                batch = 0;
@@ -379,7 +441,7 @@ int main(int argc, char *argv[])
                rc = mdb_txn_commit(txn);
                txn = NULL;
                if (rc) {
-                       fprintf(stderr, "%s: line %zd: txn_commit: %s\n",
+                       fprintf(stderr, "%s: line %" Z "d: txn_commit: %s\n",
                                prog, lineno, mdb_strerror(rc));
                        goto env_close;
                }