void database_getfile(struct request *r) { struct file_entry *entry = 0; char *err = 0; unsigned long long id = strtoull(r->filename, &err, 16); if ((!id && errno == EINVAL) || (err && *err)){ errno = 0; r->data = 0; return; } struct lnode *n = database_get(id); if (n){ entry = n->data; database_read(entry); // For some reason we couldn't load the file from disk. // Unlink node from list and return. if (!entry->data){ wkb_log(LOG_DB, "File %llx not found on disk, unlinking", entry->id); r->data = 0; database_pop(n); return; } r->data = entry->data; r->len = entry->len; r->id = id; strcpy(r->ext, entry->ext); return; } r->data = 0; }
int database_init() { if (!config->db_persist) return 0; // Backup DB file before we f**k anything up. cp(DATA_DIR "/database.txt", DATA_DIR "/database.txt.bak"); FILE *fp = fopen(DATA_DIR "/database.txt", "r"); if (!fp) return 0; while(!feof(fp)){ struct lnode *n = calloc(sizeof(struct lnode), 1); struct file_entry *fe = calloc(sizeof(struct file_entry), 1); fscanf(fp, "%llx %zu %s %s\n", &fe->id, &fe->len, fe->ext, fe->hash); if (fe->len == 0 || !isonfs(fe->id)){ //Not a valid entry. wkb_log(LOG_DB, "%llx: Invalid entry, ignoring", fe->id); free(n); free(fe); continue; } if (!strcmp(fe->ext, "NULL")){ // File has no extension. fe->ext[0] = 0; } if (!strcmp(fe->hash, "0")){ //File has no hash, generate one. database_read(fe); hash(fe->data, fe->len, fe->hash); free(fe->data); } if (exists(fe->hash, 0)){ //Check if file is already in DB. wkb_log(LOG_DB, "%llx: Duplicate detected, removing and continuing", fe->id); char buf[512]; snprintf(buf, 512, DATA_DIR "/database/%llx", fe->id); remove(buf); free(n); free(fe); continue; } n->data = fe; file_list = lnode_push(file_list, n); if (fe->id >= next_id) next_id = fe->id + 1; } fclose(fp); return 0; }
size_t database_getfile(char *name, char **datap) { struct file_entry *entry = 0; char *err = 0; unsigned long long id = strtoull(name, &err, 16); if ((!id && errno == EINVAL) || (err && isalpha(*err))){ errno = 0; return 0; } //Check the cache first. struct cache_entry *ce = cache_get(id); if (ce){ if (datap) *datap = ce->data; return ce->len; } struct lnode *n = database_get(id); if (n){ entry = n->data; char *data = database_read(entry); if (!data) return 0; if (datap) *datap = data; //Put back in cache. if (!ce) cache_push(data, entry->len, entry->id); return entry->len; } return 0; }
void * database_read_simple(void *database) { database_read(database); return NULL; }