/** * mdb_clone_handle: * @mdb: Handle to open MDB database file * * Clones an existing database handle. Cloned handle shares the file descriptor * but has its own page buffer, page position, and similar internal variables. * * Return value: new handle to the database. */ MdbHandle *mdb_clone_handle(MdbHandle *mdb) { MdbHandle *newmdb; MdbCatalogEntry *entry, *data; unsigned int i; newmdb = (MdbHandle *) g_memdup(mdb, sizeof(MdbHandle)); newmdb->stats = NULL; newmdb->catalog = g_ptr_array_new(); for (i=0;i<mdb->num_catalog;i++) { entry = g_ptr_array_index(mdb->catalog,i); data = g_memdup(entry,sizeof(MdbCatalogEntry)); g_ptr_array_add(newmdb->catalog, data); } mdb->backend_name = NULL; if (mdb->f) { mdb->f->refs++; } mdb_iconv_init(mdb); return newmdb; }
/** * mdb_open: * @filename: path to MDB (database) file * @flags: MDB_NOFLAGS for read-only, MDB_WRITABLE for read/write * * Opens an MDB file and returns an MdbHandle to it. MDB File may be relative * to the current directory, a full path to the file, or relative to a * component of $MDBPATH. * * Return value: pointer to MdbHandle structure. **/ MdbHandle *mdb_open(const char *filename, MdbFileFlags flags) { MdbHandle *mdb; int key[] = {0x86, 0xfb, 0xec, 0x37, 0x5d, 0x44, 0x9c, 0xfa, 0xc6, 0x5e, 0x28, 0xe6, 0x13, 0xb6}; int j, pos; int open_flags; mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle)); mdb_set_default_backend(mdb, "access"); #ifdef HAVE_ICONV mdb->iconv_in = (iconv_t)-1; mdb->iconv_out = (iconv_t)-1; #endif /* need something to bootstrap with, reassign after page 0 is read */ mdb->fmt = &MdbJet3Constants; mdb->f = (MdbFile *) g_malloc0(sizeof(MdbFile)); mdb->f->refs = 1; mdb->f->fd = -1; mdb->f->filename = mdb_find_file(filename); if (!mdb->f->filename) { fprintf(stderr, "File not found\n"); mdb_close(mdb); return NULL; } if (flags & MDB_WRITABLE) { mdb->f->writable = TRUE; open_flags = O_RDWR; } else { open_flags = O_RDONLY; } #ifdef _WIN32 open_flags |= O_BINARY; #endif mdb->f->fd = open(mdb->f->filename, open_flags); if (mdb->f->fd==-1) { fprintf(stderr,"Couldn't open file %s\n",mdb->f->filename); mdb_close(mdb); return NULL; } if (!mdb_read_pg(mdb, 0)) { fprintf(stderr,"Couldn't read first page.\n"); mdb_close(mdb); return NULL; } if (mdb->pg_buf[0] != 0) { mdb_close(mdb); return NULL; } mdb->f->jet_version = mdb_get_int32(mdb->pg_buf, 0x14); switch(mdb->f->jet_version) { case MDB_VER_JET3: mdb->fmt = &MdbJet3Constants; break; case MDB_VER_JET4: case MDB_VER_ACCDB_2007: case MDB_VER_ACCDB_2010: mdb->fmt = &MdbJet4Constants; break; default: fprintf(stderr,"Unknown Jet version.\n"); mdb_close(mdb); return NULL; } mdb->f->db_key = mdb_get_int32(mdb->pg_buf, 0x3e); /* I don't know if this value is valid for some versions? * it doesn't seem to be valid for the databases I have * * f->db_key ^= 0xe15e01b9; */ mdb->f->db_key ^= 0x4ebc8afb; /* fprintf(stderr, "Encrypted file, RC4 key seed= %d\n", mdb->f->db_key); */ if (mdb->f->db_key) { /* write is not supported for encrypted files yet */ mdb->f->writable = FALSE; /* that should be enought, but reopen the file read only just to be * sure we don't write invalid data */ close(mdb->f->fd); open_flags = O_RDONLY; #ifdef _WIN32 open_flags |= O_BINARY; #endif mdb->f->fd = open(mdb->f->filename, open_flags); if (mdb->f->fd==-1) { fprintf(stderr, "Couldn't ropen file %s in read only\n", mdb->f->filename); mdb_close(mdb); return NULL; } } /* get the db password located at 0x42 bytes into the file */ for (pos=0;pos<14;pos++) { j = mdb_get_int32(mdb->pg_buf, 0x42+pos); j ^= key[pos]; if ( j != 0) mdb->f->db_passwd[pos] = j; else mdb->f->db_passwd[pos] = '\0'; } mdb_iconv_init(mdb); return mdb; }
/** * mdb_open: * @filename: path to MDB (database) file * @flags: MDB_NOFLAGS for read-only, MDB_WRITABLE for read/write * * Opens an MDB file and returns an MdbHandle to it. MDB File may be relative * to the current directory, a full path to the file, or relative to a * component of $MDBPATH. * * Return value: pointer to MdbHandle structure. **/ MdbHandle *mdb_open(const char *filename, MdbFileFlags flags) { MdbHandle *mdb; int open_flags; mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle)); mdb_set_default_backend(mdb, "access"); #ifdef HAVE_ICONV mdb->iconv_in = (iconv_t)-1; mdb->iconv_out = (iconv_t)-1; #endif /* need something to bootstrap with, reassign after page 0 is read */ mdb->fmt = &MdbJet3Constants; mdb->f = (MdbFile *) g_malloc0(sizeof(MdbFile)); mdb->f->refs = 1; mdb->f->fd = -1; mdb->f->filename = mdb_find_file(filename); if (!mdb->f->filename) { fprintf(stderr, "Can't alloc filename\n"); mdb_close(mdb); return NULL; } if (flags & MDB_WRITABLE) { mdb->f->writable = TRUE; open_flags = O_RDWR; } else { open_flags = O_RDONLY; } #ifdef _WIN32 open_flags |= O_BINARY; #endif mdb->f->fd = open(mdb->f->filename, open_flags); if (mdb->f->fd==-1) { fprintf(stderr,"Couldn't open file %s\n",mdb->f->filename); mdb_close(mdb); return NULL; } if (!mdb_read_pg(mdb, 0)) { fprintf(stderr,"Couldn't read first page.\n"); mdb_close(mdb); return NULL; } if (mdb->pg_buf[0] != 0) { mdb_close(mdb); return NULL; } mdb->f->jet_version = mdb_get_int32(mdb->pg_buf, 0x14); if (IS_JET4(mdb)) { mdb->fmt = &MdbJet4Constants; } else if (IS_JET3(mdb)) { mdb->fmt = &MdbJet3Constants; } else { fprintf(stderr,"Unknown Jet version.\n"); mdb_close(mdb); return NULL; } mdb_iconv_init(mdb); return mdb; }