mas01cr@392: #include "audioDB.h" mas01cr@392: extern "C" { mas01cr@392: #include "audioDB_API.h" mas01cr@402: #include "audioDB-internals.h" mas01cr@392: } mas01cr@392: mas01cr@402: static bool audiodb_check_header(adb_header_t *header) { mas01cr@392: /* FIXME: use syslog() or write to stderr or something to give the mas01cr@392: poor user some diagnostics. */ mas01cr@392: if(header->magic == O2_OLD_MAGIC) { mas01cr@392: return false; mas01cr@392: } mas01cr@392: if(header->magic != O2_MAGIC) { mas01cr@392: return false; mas01cr@392: } mas01cr@392: if(header->version != O2_FORMAT_VERSION) { mas01cr@392: return false; mas01cr@392: } mas01cr@392: if(header->headerSize != O2_HEADERSIZE) { mas01cr@392: return false; mas01cr@392: } mas01cr@392: return true; mas01cr@392: } mas01cr@392: mas01cr@402: static int audiodb_collect_keys(adb_t *adb) { mas01cr@402: char *key_table = 0; mas01cr@402: size_t key_table_length = 0; mas01cr@402: mas01cr@402: if(adb->header->length > 0) { mas01cr@402: unsigned nfiles = adb->header->numFiles; mas01cr@402: key_table_length = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE); mas01cr@402: mmap_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length); mas01cr@402: for (unsigned i = 0; i < nfiles; i++) { mas01cr@402: adb->keys->insert(key_table + i*O2_FILETABLE_ENTRY_SIZE); mas01cr@402: } mas01cr@402: munmap(key_table, key_table_length); mas01cr@402: } mas01cr@402: mas01cr@402: return 0; mas01cr@402: mas01cr@402: error: mas01cr@402: maybe_munmap(key_table, key_table_length); mas01cr@402: return 1; mas01cr@402: } mas01cr@402: mas01cr@392: adb_t *audiodb_open(const char *path, int flags) { mas01cr@392: adb_t *adb = 0; mas01cr@392: int fd = -1; mas01cr@392: mas01cr@392: flags &= (O_RDONLY|O_RDWR); mas01cr@392: fd = open(path, flags); mas01cr@392: if(fd == -1) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: if(acquire_lock(fd, flags == O_RDWR)) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: mas01cr@411: adb = (adb_t *) calloc(1, sizeof(adb_t)); mas01cr@392: if(!adb) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: adb->fd = fd; mas01cr@392: adb->flags = flags; mas01cr@392: adb->path = (char *) malloc(1+strlen(path)); mas01cr@392: if(!(adb->path)) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: strcpy(adb->path, path); mas01cr@392: mas01cr@392: adb->header = (adb_header_t *) malloc(sizeof(adb_header_t)); mas01cr@392: if(!(adb->header)) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: if(read(fd, (char *) adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: if(!audiodb_check_header(adb->header)) { mas01cr@392: goto error; mas01cr@392: } mas01cr@392: mas01cr@402: adb->keys = new std::set; mas01cr@402: if(!adb->keys) { mas01cr@402: goto error; mas01cr@402: } mas01cr@402: if(audiodb_collect_keys(adb)) { mas01cr@402: goto error; mas01cr@402: } mas01cr@392: return adb; mas01cr@392: mas01cr@392: error: mas01cr@392: if(adb) { mas01cr@392: if(adb->header) { mas01cr@392: free(adb->header); mas01cr@392: } mas01cr@392: if(adb->path) { mas01cr@392: free(adb->path); mas01cr@392: } mas01cr@402: if(adb->keys) { mas01cr@402: delete adb->keys; mas01cr@402: } mas01cr@392: free(adb); mas01cr@392: } mas01cr@392: if(fd != -1) { mas01cr@392: close(fd); mas01cr@392: } mas01cr@392: return NULL; mas01cr@392: }