Browse Source

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

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

79
src/database.c

@ -61,53 +61,63 @@ imdb_create(const char *path) {
return result; 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; ssize_t bytes = 0;
struct stat st; struct stat st;
char buf[IMDB_REC_LEN] = "\0"; char buf[IMDB_REC_LEN] = "\0";
int flags = 0, fd = -1; int flags = 0, fd = -1;
char *p; char *p;
assert(db != NULL);
assert(path != NULL); assert(path != NULL);
assert(error != NULL);
memset(db, 0x0, sizeof(imdb_db_t));
errno = 0;
if (stat(path, &st) < 0) { if (stat(path, &st) < 0) {
strncpy(db->error, strerror(errno), sizeof(db->error)); *error = -1;
return -1; return NULL;
} }
errno = 0; if ((fd = open(path, (mode & IMDB_FLAG_WRITE) ? O_RDWR : O_RDONLY)) < 0) {
if ((fd = open(path, write ? O_RDWR : O_RDONLY)) < 0) { *error = -1;
strncpy(db->error, strerror(errno), sizeof(db->error)); return NULL;
return -1;
} }
DB_READ(db, buf, IMDB_REC_LEN, 0); errno = 0;
bytes = pread(fd, buf, IMDB_REC_LEN, 0);
if (bytes != IMDB_REC_LEN) { if (bytes < IMDB_REC_LEN) {
strncpy(db->error, "Empty or damaged database file", sizeof(db->error)); *error = errno ? -1 : -3; /* empty file, damaged database or IO error */
return -1; return NULL;
} }
if (memcmp("IMDB", buf, 4) != 0) {
strncpy(db->error, "Not a database file", sizeof(db->error)); p = buf + 0;
return -1; 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)); p = buf + 6;
return -1; 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)); p = buf + 10;
return -1; 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; 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; p = buf + 16;
for (size_t i = 0; i < 8 && *p != '\0'; p++) { for (size_t i = 0; i < 8 && *p != '\0'; p++) {
switch (*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)); 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); assert(db != NULL);
errno = 0; if (db->fd >= 0)
if (close(db->fd) != 0) { close(db->fd);
strncpy(db->error, strerror(errno), sizeof(db->error));
return -1;
}
db->fd = -1;
return 0;
} }
int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec) 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 * @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 * @returns true on success, and false on error
* @note See errno value for details * @note See errno value for details
* @todo 2nd arg: caps * @todo 2nd arg: caps
*/ */
bool imdb_create(const char *path); 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 float
ratio_from_rec_data(unsigned char * const data); ratio_from_rec_data(unsigned char * const data);

Loading…
Cancel
Save