Browse Source

* imdb_open()/imdb_close() now works with allocated data

master
Alex 'AdUser' Z 8 years ago
parent
commit
86b84abb23
  1. 81
      src/database.c
  2. 22
      src/database.h

81
src/database.c

@ -61,53 +61,63 @@ imdb_create(const char *path) {
return result;
}
int imdb_open(imdb_db_t *db, const char *path, int write)
{
imdb_db_t *
imdb_open(const char *path, int mode, int *error) {
imdb_db_t *db = NULL;
ssize_t bytes = 0;
struct stat st;
char buf[IMDB_REC_LEN] = "\0";
int flags = 0, fd = -1;
char *p;
assert(db != NULL);
assert(path != NULL);
memset(db, 0x0, sizeof(imdb_db_t));
assert(path != NULL);
assert(error != NULL);
errno = 0;
if (stat(path, &st) < 0) {
strncpy(db->error, strerror(errno), sizeof(db->error));
return -1;
*error = -1;
return NULL;
}
errno = 0;
if ((fd = open(path, write ? O_RDWR : O_RDONLY)) < 0) {
strncpy(db->error, strerror(errno), sizeof(db->error));
return -1;
if ((fd = open(path, (mode & IMDB_FLAG_WRITE) ? O_RDWR : O_RDONLY)) < 0) {
*error = -1;
return NULL;
}
DB_READ(db, buf, IMDB_REC_LEN, 0);
if (bytes != IMDB_REC_LEN) {
strncpy(db->error, "Empty or damaged database file", sizeof(db->error));
return -1;
errno = 0;
bytes = pread(fd, buf, IMDB_REC_LEN, 0);
if (bytes < IMDB_REC_LEN) {
*error = errno ? -1 : -3; /* empty file, damaged database or IO error */
return NULL;
}
if (memcmp("IMDB", buf, 4) != 0) {
strncpy(db->error, "Not a database file", sizeof(db->error));
return -1;
p = buf + 0;
if (memcmp("IMDB", p, 4) != 0) {
*error = -3; /* Not a database file */
return NULL;
}
if (atoi(buf + 6) != IMDB_VERSION) {
strncpy(db->error, "Database version mismatch", sizeof(db->error));
return -1;
p = buf + 6;
if (atoi(p) != IMDB_VERSION) {
*error = -4; /* Database version mismatch */
return NULL;
}
if (memcmp("CAPS", buf + 10, 4) != 0) {
strncpy(db->error, "Can't read database capabilities", sizeof(db->error));
return -1;
p = buf + 10;
if (memcmp("CAPS", p, 4) != 0) {
*error = -3; /* Can't read database capabilities */
return NULL;
}
if (write)
if (mode & IMDB_FLAG_WRITE)
flags |= IMDB_FLAG_WRITE;
/* all seems to be ok */
if ((db = calloc(1, sizeof(imdb_db_t))) == NULL) {
*error = -2; /* out of memory */
return NULL;
}
p = buf + 16;
for (size_t i = 0; i < 8 && *p != '\0'; p++) {
switch (*p) {
@ -124,21 +134,16 @@ int imdb_open(imdb_db_t *db, const char *path, int write)
strncpy(db->path, path, sizeof(db->path));
return 0;
return db;
}
int imdb_close(imdb_db_t *db)
void
imdb_close(imdb_db_t *db)
{
assert(db != NULL);
errno = 0;
if (close(db->fd) != 0) {
strncpy(db->error, strerror(errno), sizeof(db->error));
return -1;
}
db->fd = -1;
return 0;
if (db->fd >= 0)
close(db->fd);
}
int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec)

22
src/database.h

@ -103,15 +103,31 @@ int imdb_write_blk(imdb_db_t *db, imdb_block_t *blk);
/**
* @brief Creates empty database at given path
* @param path Where to create database
* @param path Path to database
* @returns true on success, and false on error
* @note See errno value for details
* @todo 2nd arg: caps
*/
bool imdb_create(const char *path);
int imdb_open (imdb_db_t *db, const char *path, int write);
int imdb_close (imdb_db_t *db);
/**
* @brief Open database at given path
* @param path Path to database
* @param mode Database open modes. See IMDB_FLAG_* defines above
* @param error Pointer to error code storage
* @returns Pointer to database handle on success, NULL on error
* -1 -- system error, see @a errno for details
* -2 -- malloc() failed
* -3 -- damaged database
* -4 -- database version mismatch
*/
imdb_db_t * imdb_open(const char *path, int mode, int *error);
/**
* @brief Close database and free associated resources
* @param db Database handle
*/
void imdb_close(imdb_db_t *db);
float
ratio_from_rec_data(unsigned char * const data);

Loading…
Cancel
Save