#include #include #include #include #include #include #include #include typeof(gdbm_open) *lfs_gdbm_open; typeof(gdbm_close) *lfs_gdbm_close; typeof(gdbm_store) *lfs_gdbm_store; void lfs_init(void) { void *h = dlopen("libgdbm.so.3", RTLD_LAZY|RTLD_LOCAL); assert(h != NULL); lfs_gdbm_open = dlsym(h, "gdbm_open"); lfs_gdbm_close = dlsym(h, "gdbm_close"); lfs_gdbm_store = dlsym(h, "gdbm_store"); } int main(int argc, char *argv[]) { datum key, val; struct stat st; char *srcf, *dstf; GDBM_FILE srcdb, dstdb; assert(argc == 2); lfs_init(); srcf = argv[1]; dstf = malloc(strlen(srcf) + 30); sprintf(dstf, "%s.upgrade.tmp", srcf); unlink(dstf); srcdb = gdbm_open(srcf, 1024, GDBM_NOLOCK | GDBM_READER, 0644, NULL); assert(srcdb != NULL); stat(srcf, &st); dstdb = lfs_gdbm_open(dstf, 1024, GDBM_NOLOCK | GDBM_WRCREAT, st.st_mode, NULL); assert(dstdb != NULL); key = gdbm_firstkey(srcdb); while (key.dptr) { val = gdbm_fetch(srcdb, key); lfs_gdbm_store(dstdb, key, val, GDBM_INSERT); key = gdbm_nextkey(srcdb, key); } gdbm_close(srcdb); lfs_gdbm_close(dstdb); chown(dstf, st.st_uid, st.st_gid); return 0; }