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; }
void database_delete(struct Connection *conn, int id) { struct Address addr = {.id=id, .set=0}; conn->db->rows[id] = addr; } void database_list(struct Connection *conn) { for(int i=0; i<MAX_ROWS; ++i) { struct Address *addr = &conn->db->rows[i]; if(addr->set) address_print(addr); } } int main(int argc, char *argv[]) { if(argc < 3) die("usage: a.out file action additional_params"); char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = database_open(filename, action); int id=0; if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("record id too high"); switch (action) { case 'c': database_create(conn); database_write(conn); break; case 'g': if(argc!=4) die("need an id for database_get()"); database_get(conn,id); break; case 's': if(argc!=6) die("need id, name, email for database_set()"); database_set(conn,id,argv[4],argv[5]); database_write(conn); break; case 'd': if(argc!=4) die("need id to delete"); database_delete(conn,id); database_write(conn); break; case 'l': database_list(conn); break; default: die("invalid action: c=create, g=get, s=set, d=delete, l=list"); } database_close(conn); return 0; }
int database_rm(char *name) { unsigned long long id = strtoull(name, 0, 16); struct lnode *node = database_get(id); if (!node) return 1; database_uncache(node->data); database_pop(node); char buf[512]; snprintf(buf, 512, DATA_DIR "/database/%llx", id); remove(buf); wkb_log(LOG_DB, "File %llx removed", id); return 0; }
int database_rm(char *name) { unsigned long long id = strtoull(name, 0, 16); struct lnode *node = database_get(id); if (!node) return 1; database_pop(node); cache_rm(id); char path[512]; snprintf(path, 512, DATA_DIR "/database/%llx", id); remove(path); char strtime[512]; time_t t = time(0); strftime(strtime, 512, TIME_FORMAT, localtime(&t)); printf("\033[1m%s, (database):\033[m File %llx removed\n", strtime, id); 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_create(struct Connection *conn) { int i = 0; for(i = 0; i < MAX_ROWS; i++) { // make a prototype to initialize the database struct Address addr = {.id = i, .set = 0}; // then assign it to conn conn->db->rows[i] = addr; } printf("got to bottom of database create"); } void database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Address *addr = &conn->db->rows[id]; if(addr->set) die("Already set, delete it first"); addr->set = 1; // WARNING FIX THIS char *res = strncpy(addr->name, name, MAX_DATA); // demonstrate that strncpy bug if(!res) die("Name copy failed"); res = strncpy(addr->email, email, MAX_DATA); if(!res) die("Email copy failed"); } void database_get(struct Connection *conn, int id) { struct Address *addr = &conn->db->rows[id]; if(addr->set) { address_print(addr); } else { die("ID is not set"); } } void database_delete(struct Connection *conn, int id) { struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; } void database_list(struct Connection *conn) { int i = 0; struct Database *db = conn->db; for(i = 0; i < MAX_ROWS; i++) { struct Address *cur = &db->rows[i]; if(cur->set) { address_print(cur); } } } int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]"); char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = database_open(filename, action); int id = 0; if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("There's not that many records."); switch(action) { case 'c': database_create(conn); database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get"); database_get(conn, id); break; case 's': if(argc != 6) die("Need id, name, email to set"); database_set(conn, id, argv[4], argv[5]); database_write(conn); break; case 'd': if(argc != 4) die("Need id to delete"); database_delete(conn, id); database_write(conn); break; case 'l': database_list(conn); break; default: die("Invalid action, only: c=create, g=get, s=set, d=del, l=list"); } database_close(conn); return 0; }