X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblmdb%2Fmdb_load.c;h=cf1d42e93bc7d3b8c9271341dc8f270a257c1ba1;hb=385193cd520c3b238fe9048d47e8abf8383386bc;hp=0cf02ada5e640c15dc223f7a3cd2019ead46811b;hpb=cf331ccb3dc482769d6ac8d75cc66249b0086d29;p=openldap diff --git a/libraries/liblmdb/mdb_load.c b/libraries/liblmdb/mdb_load.c index 0cf02ada5e..cf1d42e93b 100644 --- a/libraries/liblmdb/mdb_load.c +++ b/libraries/liblmdb/mdb_load.c @@ -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,9 +64,7 @@ flagbit dbflags[] = { { 0, NULL, 0 } }; -static const char hexc[] = "0123456789abcdef"; - -static void readhdr() +static void readhdr(void) { char *ptr; @@ -67,7 +73,7 @@ static void readhdr() if (!strncmp(dbuf.mv_data, "VERSION=", 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); } @@ -77,7 +83,7 @@ static void readhdr() if (!strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "print", STRLENOF("print"))) mode |= PRINT; else if (strncmp((char *)dbuf.mv_data+STRLENOF("FORMAT="), "bytevalue", STRLENOF("bytevalue"))) { - fprintf(stderr, "%s: line %zd: unsupported FORMAT %s\n", + fprintf(stderr, "%s: line %" Z "d: unsupported FORMAT %s\n", prog, lineno, (char *)dbuf.mv_data+STRLENOF("FORMAT=")); exit(EXIT_FAILURE); } @@ -88,10 +94,40 @@ static void readhdr() subname = strdup((char *)dbuf.mv_data+STRLENOF("database=")); } else if (!strncmp(dbuf.mv_data, "type=", STRLENOF("type="))) { if (strncmp((char *)dbuf.mv_data+STRLENOF("type="), "btree", STRLENOF("btree"))) { - fprintf(stderr, "%s: line %zd: unsupported type %s\n", + 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,20 +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; } @@ -163,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; @@ -201,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; } @@ -210,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; } @@ -236,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); } @@ -251,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 @@ -288,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; @@ -380,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; }