int main(int argc, char *argv[]) { char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = Database_open(filename, action); int id = 0; if (argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]", conn); if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("There's not that many records.", conn); switch(action) { case 'c': if(argc == 5) Database_create(conn, atoi(argv[3]), atoi(argv[4])); else Database_create(conn, 0, 0); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get", conn); Database_get(conn, id); break; case 's': if(argc != 6) die("Need id, name, email to set.", conn); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc != 4) die("Need id to delete", conn); 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, r=resize", conn); } Database_close(conn); return 0; }
// Declare the Database_load function void Database_load() { rewind(conn->file); // Read conn->file into conn->db // Each block is the sizeof(struct Database) // Read 1 block int rc = fread(&conn->db->max_rows, sizeof(int), 1, conn->file); if (rc != 1) die("Failed to load database."); rc = fread(&conn->db->max_data, sizeof(int), 1, conn->file); if (rc != 1) die("Failed to load database."); if (conn->db->rows == NULL) { Database_create(conn->db->max_rows, conn->db->max_data); } int i = 0; for (i = 0; i < conn->db->max_rows; i++) { struct Address *row = &conn->db->rows[i]; fread(&row->id, sizeof(int), 1, conn->file); fread(&row->set, sizeof(int), 1, conn->file); fread(row->name, sizeof(char) * conn->db->max_data, 1, conn->file); fread(row->email, sizeof(char) * conn->db->max_data, 1, conn->file); fread(row->location, sizeof(char) * conn->db->max_data, 1, conn->file); } }
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; char *name = "\0"; if(strcmp(argv[2],"f")==0){ name = argv[3]; } else 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 'd': if(argc != 4) die("Need id to delete"); Database_delete(conn, id); Database_write(conn); 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 'l': Database_list(conn); break; case 'f': Database_find(conn, name); break; default: die("Invalid action, only: c=create, g=get, s=set, d=del, l=list"); } Database_close(conn); return 0; }
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]; Database_open(filename, action); int id = 0; if (action != 'c' && action != 'f' && argc > 3) { id = atoi(argv[3]); if (id >= conn->db->max_rows) die("There are not that many records."); } switch (action) { // Create case 'c': if (argc != 5) die("MAX_DATA and MAX_ROWS required."); conn->db->max_data = atoi(argv[3]); conn->db->max_rows = atoi(argv[4]); Database_create(); Database_write(); break; // Get case 'g': if (argc != 4) die("Need an ID to get."); Database_get(id); break; // Set case 's': if (argc != 6) die("Need ID, name, and email to set."); Database_set(id, argv[4], argv[5]); Database_write(); break; // Find case 'f': if (argc != 4) die("Need a name or email to search for."); Database_find(argv[3]); break; // Delete case 'd': if (argc != 4) die("Need ID to delete."); Database_delete(id); Database_write(); break; // List case 'l': Database_list(); break; default: die("Invalid action, only: c=create, g=get, s=set, d=delete, l=list"); } Database_close(); return 0; }
int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]", NULL); int max_data = MAX_DATA; int max_rows = MAX_ROWS; 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.", conn); switch(action) { case 'f': if(argc != 4) die("Need a name to find", conn); Database_find(conn, argv[3]); break; case 'c': max_data = argv[3] ? atoi(argv[3]) : MAX_DATA; max_rows = argv[4] ? atoi(argv[4]) : MAX_ROWS; Database_create(conn, max_data, max_rows); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get", conn); Database_get(conn,id); break; case 's': if(argc != 6) die("Need id, name, email to set", conn); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc != 4) die("Need id to delete", conn); 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", conn); } Database_close(conn); return 0; }
int main(int argc, char *argv[]) { char usage[64]; sprintf(usage, "USAGE: %s <dbfile> <action> [action params]", basename(argv[0])); if(argc < 3) die(usage, NULL); 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.", conn); switch(action) { case 'c': Database_create(conn); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get", conn); Database_get(conn, id); break; case 's': if(argc != 7) die("Need id, name, email, and street to set", conn); Database_set(conn, id, argv[4], argv[5], argv[6]); Database_write(conn); break; case 'd': if(argc != 4) die("Need id to delete", conn); Database_delete(conn, id); Database_write(conn); break; case 'f': if(argc != 4) die("Need something to find", conn); Database_find(conn, argv[3]); break; case 'l': Database_list(conn); break; default: die("Invalid action, only: c=create, g=get, s=set, d=del, l=list, f=find", conn); } Database_close(conn); return 0; }
int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]", NULL); char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = Database_open(filename, action); int id = 0; if((argc > 3) && (action != 'c') && (action != 'f')) id = atoi(argv[3]); //if(id >= conn->db->MAX_ROWS) die("There's not that many records.", conn); switch(action) { case 'c': Database_create(conn, atoi(argv[3]), atoi(argv[4])); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get", conn); Database_get(conn, id); break; case 's': if(argc != 7) die("Need id, name, email and age to set", conn); Database_set(conn, id, argv[4], argv[5], atoi(argv[6])); Database_write(conn); break; case 'd': if(argc != 4) die("Need an id to delete", conn); Database_delete(conn, id); Database_write(conn); break; case 'l': Database_list(conn); break; case 'f': Database_find(conn, argv[3], argv[4]); break; default: die("Invalid action, only: c=create, g=get, s=set, d=delete, l=list", conn); } Database_close(conn); return 0; }
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]; 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(); Database_write(); break; case 'g': if(argc != 4) die("Need an id to get"); Database_get(id); break; case 's': if(argc != 6) die("Need id, name, email to set"); Database_set(id, argv[4], argv[5]); Database_write(); break; case 'd': if(argc != 4) die("Need an id to delete)"); Database_delete(id); Database_write(); break; case 'l': Database_list(); break; case 'f': Database_find(argv[3]); break; default: die("Invalid action, only c=create, g=get, s=set, d=del, l=list"); } Database_close(); return 0; }
int ui(int argc, char *argv[]) { struct Connection *conn = NULL; char action = 'r'; char *filename; char *name = "the dude"; char *email = "*****@*****.**"; int id = 0; while (1) { fputs("$ ", stdout); char cmd = getchar(); switch (cmd) { case 'c': Database_create(conn); Database_write(conn); break; case 'd': Database_delete(conn, id); Database_write(conn); break; case 'g': Database_get(conn, id); break; case 'h': help(); break; case 'l': Database_list(conn); break; case 'o': conn = Database_open(filename, action); break; case 's': Database_set(conn, id, name, email); Database_write(conn); break; case 'q': goto exit; default: break; } } exit: return 0; }
int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: mydb <dbfile> <action> [action params]"); char *filename=argv[1]; char action = argv[2][0]; // will open file. Only creates file if action is 'c' 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 '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; }
/* * === FUNCTION ====================================================================== * Name: Database_create * Description: * ===================================================================================== */ void Database_create ( struct Connection*conn ) { int i=0; for(i=0;i<MAX_ROWS;i++){ struct Address addr = { .id=i, .set=0 }; conn->db->rows[i] = addr; } } /* ----- end of function Database_create ----- */ /* * === FUNCTION ====================================================================== * Name: Database_set * Description: * ===================================================================================== */ 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; char *res = strncpy(addr->name, name, MAX_DATA); if(strlen(addr->name) >= MAX_DATA) printf("WARNING:length_error\n"); res[MAX_DATA-1] = '\0'; if(!res) die("Name copy failed"); printf("name is %s\n", addr->name); char* eres = strncpy(addr->email, email, MAX_DATA); if(!eres) die("Email copy failed"); if(strlen(addr->email) >= MAX_DATA) printf("WARNING:length_error\n"); eres[MAX_DATA-1] ='\0'; printf("email is %s\n", addr->email); } /* ----- end of function Database_set ----- */ /* * === FUNCTION ====================================================================== * Name: Database_get * Description: * ===================================================================================== */ 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"); } } /* ----- end of function Database_get ----- */ /* * === FUNCTION ====================================================================== * Name: Database_delete * Description: * ===================================================================================== */ void Database_delete ( struct Connection *conn, int id ) { struct Address addr = {.id = id, .set=0}; conn->db->rows[id] = addr; } /* ----- end of function Database_delete ----- */ /* * === FUNCTION ====================================================================== * Name: Database_list * Description: * ===================================================================================== */ 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); } } } /* ----- end of function Database_list ----- */ #include <stdlib.h> /* * === FUNCTION ====================================================================== * Name: main * Description: * ===================================================================================== */ 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]; // printf("mode is %c" ,action);// // printf("filename is %s", filename);// struct Connection *conn = Database_open(filename,action); int id=0; if(argc > 3)id=atoi(argv[3]); if(id >= MAX_ROWS) die("this is not that many record"); 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 EXIT_SUCCESS; } /* ---------- end of function main ---------- */
void Database_create(struct Connection *conn) { int i = 0; for (i = 0; i < MAX_ROWS; i++) { struct Address addr = { .id = i, .set = 0}; conn->db->rows[i] = addr; } } 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("Record already set - delete first", conn); } addr->set = 1; char *res = strncpy(addr->name, name, MAX_DATA); if (!res) { die("name copy failed", conn); } res = strncpy(addr->email, email, MAX_DATA); if (!res) { die("email copy failed", conn); } } 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", conn); } } 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 *addr = &db->rows[i]; if (addr->set) { Address_print(addr); printf("\n"); } } } void die(const char *message, struct Connection *conn) { if (errno) { perror(message); } else { printf("ERROR %s\n", message); } Database_close(conn); exit(1); } int main(int argc, char *argv[]) { if (argc < 3) { die("USAGE: simple-database <dbfile> <action> [action params]", NULL); } 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("ID exceeds maximum database capacity", conn); } switch(action) { case 'c': Database_create(conn); Database_write(conn); break; case 'g': if (argc != 4) { die("An ID is required for the get operation", conn); } Database_get(conn, id); break; case 's': if (argc != 6) { die("Need an ID, name, and email for the set operation", conn); } Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if (argc != 4) { die("Need an ID to delete", conn); } 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", conn); } Database_close(conn); return 0; }
//Database handler. UI int main(int argc, char* argv[]){ if(argc<3){ die("USAGE: ex17 <dbfile> <action> [action params]", NULL); } char* filename = argv[1]; char action = argv[2][0]; struct Connection* conn = Database_open(filename, action); int id = 0; if(argc>3 && action != 'f'){ id = atoi(argv[3]); } if(id > MAX_ROWS){ die("There's not that many records.", conn); } switch(action){ case 'c': Database_create(conn); Database_write(conn); break; case 'g': if(argc!=4){ die("Need an id to get.", conn); } Database_get(conn, id); break; case 's': if(argc != 6){ die("Need id, name, email to set.", conn); } Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc < 4){ die("Need id to delete.", conn); } Database_delete(conn, id); Database_write(conn); break; case 'l': Database_list(conn); break; case 'f': if(argc!=4) die("Need name to look for.", conn); Database_find(conn, argv[3]); break; default: die("Invalid action. Only c=create, g=get, s=set, d=delete and l=list are valid actions.", conn); } Database_close(conn); return 0; }
void Database_create(struct Connection *conn) { int i = 0; for(i = 0; i < MAX_ROWS; i++){ //Make a prototype struct Address addr = {.id = i, .set = 0}; conn->db->rows[i] = addr; } } 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!"); addr->set = 1; char *res = strncpy(addr->name, name, MAX_DATA); 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 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 *curr = &db->rows[i]; if(curr->set){ Address_print(curr); } } } int main(int argc, char *argv[]){ if(argc < 3) die("USAGE: heapstack <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("Not enough records"); switch(action) { case 'c': Database_create(conn); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id"); Database_get(conn, id); break; case 's': if(argc != 6) die("Need id, name and email"); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc != 4) die("Need an id"); Database_delete(conn,id); Database_write(conn); break; case 'l': Database_list(conn); break; default: die("Invalid action"); break; } Database_close(conn); return 0; }
void Database_create(struct Connection *conn) { int i = 0; for(i = 0; i < MAX_ROWS; i++) { // make a prototype to initialize it struct Address addr = {.id = i, .set = 0}; // then just assign it conn->db->rows[i] = addr; } } 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"); /* &conn->db->rows[i] reads "get the i element of rows, which is in db, which is in conn, then get the address of (&) it */ addr->set = 1; // WARNING: bug, read the "How To Break It" and fix this char *res = strncpy(addr->name, name, MAX_DATA); // demonstrate the 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; // This trick makes sure that all fields but set and id are initialized to 0s // and is actually easier to write. // The dot before the fieldname is for giving initial values to struct members at declaration } 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; // The atoi is to take the string for the id on the command line and convert it to the int id variable 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; }
void Database_create(struct Connection *conn) { for(int i = 0; i < MAX_ROWS; i++) { struct Address addr = { .id = i, .set = 0 }; conn->db->rows[i] = addr; } } 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; //This copies at most MAX_DATA bytes from name to addr->name. //If the length of name is less than MAX_DATA, the remaining //chars are nulled out until MAX_DATA is reached. //Note that if name is greater than or equal to MAX_DATA, //only MAX_DATA bytes are copied, but no room is left for a null terminator. //Therefore, some memory disclosure may occur after the allocated //memory for addr->name, depending on the next null byte. //This applies equally for the email copying below. char *res = strncpy(addr->name, name, MAX_DATA); 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 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) { struct Database *db = conn->db; for(int i = 0; i < MAX_ROWS; i++) { struct Address *addr = &db->rows[i]; if(addr->set) Address_print(addr); } } int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action parameters]."); 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 are 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 an ID, Name, and Email to set."); } Database_set(conn, id, argv[4], argv[5]); Database_write_record(conn, id); break; case 'd': if(argc != 4) { die("Need an ID to delete."); } Database_delete(conn, id); Database_write_record(conn, id); 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 main(int argc, char *argv[]) { if (argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]", NULL); 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.", NULL); switch (action) { case 'c': Database_create(conn); Database_write(conn); break; case 'g': if (argc !=4) die("Need an id to get.", NULL); Database_get(conn, id); break; case 's': if (argc != 6) die("Need id, name, email to set.", NULL); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if (argc != 4) die("Need id to delete.", NULL); Database_delete(conn, id); Database_write(conn); break; case 'f': if (argc != 5) die("Need attribute, value to find", NULL); char attribute = argv[3][0]; char *value = argv[4]; if (attribute == 'e') { Database_find_email(conn, value); } else { Database_find_name(conn, value); } break; case 'l': Database_list(conn); break; default: die("Invalid action, only: c=create, g=get, f=find, s=set, d=del, l=list.", NULL); } Database_close(conn); return 0; }
void Database_create(struct Connection *conn) { int i = 0; for(i=0; i < MAX_ROWS; i++) { struct Contact c = { .id = i, .set = 0 }; conn->db->rows[i] = c; } } void Database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Contact *c = &conn->db->rows[id]; // TODO: what does the & do to a struct pointer? if(c->set) die("Contact already set, delete it first"); c->set = 1; // WARNING: bug, read the "How To Break It" and fix this char *res = strncpy(c->name, name, MAX_DATA); if(!res) die("Name copy failed"); res = strncpy(c->email, email, MAX_DATA); if(!res) die("Email copy failed"); } void Database_get(struct Connection *conn, int id) { struct Contact *c = &conn->db->rows[id]; if(c->set) { Contact_print(c); } else { die("ID not set"); } } void Database_delete(struct Connection *conn, int id) { struct Contact c = { .id = id, .set = 0 }; conn->db->rows[id] = c; } void Database_list(struct Connection *conn) { int i = 0; struct Database *db = conn->db; for(i = 0; i < MAX_ROWS; i++) { struct Contact *cursor = &db->rows[i]; if(cursor->set) { Contact_print(cursor); } } } 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; }
void Database_create(struct Connection *conn) { int i = 0; for (i = 0; i < MAX_ROWS; i++) { // make a prototype to initialize it struct Address addr = {.id = i, .is_set = false}; // then just assign it conn->db->rows[i] = addr; } } void Database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Address *addr = &conn->db->rows[id]; if (addr->is_set) { die(conn, "Already set, delete it first"); } addr->is_set = true; // WARNING: bug, read the "How To Break It" and fix this // demonstrate the strncpy bug (Not an undocumented 'bug', but maybe poor design) // if name is as long or longer than MAX_DATA, strncpy won't set the last character null. // http://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/ // http://stackoverflow.com/questions/14950241/pointer-to-one-struct-in-another-writing-and-reading-it-from-file-gives-segfaul char *res = strncpy(addr->name, name, MAX_DATA); // Ensure last character is null. addr->name[sizeof(addr->name) - 1] = '\0'; if (!res) { die(conn, "Name copy failed"); } res = strncpy(addr->email, email, MAX_DATA); // Ensure last character is null. addr->email[sizeof(addr->email) - 1] = '\0'; if (!res) { die(conn, "Email copy failed"); } } void Database_get(struct Connection *conn, int id) { struct Address *addr = &conn->db->rows[id]; if (addr->is_set) { Address_print(addr); } else { die(conn, "ID is not set"); } } void Database_delete(struct Connection *conn, int id) { // set id and is_set // don't set name or email, this initializes them to zero. struct Address addr = {.id = id, .is_set = false}; 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->is_set) { Address_print(cur); } } } int main(int argc, char *argv[]) { if (argc < 3) { die(NULL, "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) { // atoi converts string to integer id = atoi(argv[3]); } if (id >= MAX_ROWS) { die(conn, "There's not that many records."); } switch (action) { case 'c': Database_create(conn); Database_write(conn); break; case 'g': if (argc != 4) { die(conn, "Need an id to get"); } Database_get(conn, id); break; case 's': if (argc != 6) { die(conn, "Need id, name, email to get"); } Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if (argc != 4) { die(conn, "Need id to delete"); } Database_delete(conn, id); Database_write(conn); break; case 'l': Database_list(conn); break; default: die(conn, "Invalid action, only: c=create, g=get, s=set, d=delete, l=list"); } Database_close(conn); return 0; }
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; int id; switch(action) { case 'c': conn = Database_open(filename, action); Database_create(conn); Database_write(conn); break; case 'f': if(argc != 4) die("Need a name to find"); conn = Database_open(filename, action); Database_find_name(conn, argv[3]); Database_close(conn); break; case 'g': if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("The are already too many records."); if(argc != 4) die("Need an ID to get"); conn = Database_open(filename, action); Database_get(conn, id); Database_close(conn); break; case 'a': if(argc > 3) id = atoi(argv[3]); //if(argc != 5) die("Need name, and email to set."); conn = Database_open(filename, action); Database_add(conn, argv[4], argv[5]); Database_write(conn); Database_close(conn); break; case 's': if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("The are already too many records."); if(argc != 6) die("Need id, name, and email to set."); conn = Database_open(filename, action); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); Database_close(conn); break; case 'd': if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("The are already too many records."); if(argc != 4) die("Need an ID to delete"); conn = Database_open(filename, action); Database_delete(conn, id); Database_write(conn); Database_close(conn); break; case 'l': conn = Database_open(filename, action); Database_list(conn); Database_close(conn); break; case 'u': if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("The are already too many records."); if(argc != 6) die("Need id, name, and email to set."); conn = Database_open(filename, action); Database_update(conn, id, argv[4], argv[5]); Database_write(conn); Database_close(conn); break; case 'z': conn = Database_open(filename, action); printf("%d\n", Database_nrows(conn)); Database_close(conn); break; default: die("Invalid action, only: c=create, a=add, g=get, f=find, s=set, d=delete, l=list, u=update, z=size"); break; } return 0; }
int main(int argc, char *argv[]) { struct Connection *conn = NULL; if (argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]", conn); char *filename = argv[1]; char action = argv[2][0]; conn = Database_open(filename, action); int id = 0; if (argc > 3) id = atoi(argv[3]); if (action != 'c') { if (id >= MAX_ROWS) die("There's not that many records.", conn); } switch (action) { case 'c': Database_create(conn); Database_write(conn); break; case 'g': if (argc != 4) die("Need an id to get", conn); Database_get(conn, id); break; case 's': if (argc != 6) die("Need id, name, email to set", conn); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if (argc != 4) die("Need id to delete", conn); Database_delete(conn, id); Database_write(conn); break; case 'l': Database_list(conn); break; case 'f': if (argc != 4) die("Need to provide a string to search matches.", conn); Database_find(conn, argv[3]); break; default: die("Invalid action: c=create, g=get, s=set, d=del, l=list", conn); } Database_close(conn); return 0; }
void Database_create(struct Connection *conn, int max_data, int max_rows) { conn->db->max_data = max_data; conn->db->max_rows = max_rows; conn->db->rows = malloc(sizeof(struct Address[max_rows])); if(!conn->db->rows) die("Memory error", conn); int i = 0; for(i = 0; i < max_rows; i++) { // make a prototype to initialize it struct Address addr = { .id = i, .set = 0, .name = malloc(sizeof(char [max_data])), .email = malloc(sizeof(char [max_data])), }; // then just assign it conn->db->rows[i] = addr; } } 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", conn); addr->set = 1; // WARNING: bug, read the "How To Break It" and fix this char *res = strncpy(addr->name, name, conn->db->max_data); // demonstrate the strncpy bug if(!res) die("Name copy failed", conn); res = strncpy(addr->email, email, conn->db->max_data); if(!res) die("Email copy failed", conn); } 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", conn); } } 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 < conn->db->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]", NULL); char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = Database_open(filename, action); int id = 0; switch(action) { case 'c': if(argc != 5) die("Need to specify max data and max rows", conn); int max_data = atoi(argv[3]); int max_rows = atoi(argv[4]); Database_create(conn, max_data, max_rows); Database_write(conn); break; case 'g': if(argc > 3) id = atoi(argv[3]); if(id >= conn->db->max_rows) die("There's not that many records.", conn); if(argc != 4) die("Need an id to get", conn); Database_get(conn, id); break; case 's': if(argc > 3) id = atoi(argv[3]); if(id >= conn->db->max_rows) die("There's not that many records.", conn); if(argc != 6) die("Need id, name, email to set", conn); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc > 3) id = atoi(argv[3]); if(id >= conn->db->max_rows) die("There's not that many records.", conn); if(argc != 4) die("Need id to delete", conn); 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", conn); } Database_close(conn); return 0; }
void Database_create(struct Connection *conn) //create database { int i = 0; for (i = 0; i < MAX_ROWS; i++) { //for the maximum number of rows // make a prototype to initialize it struct Address addr = {.id = i, .set = 0}; // then just assign it conn->db->rows[i] = addr; } } void Database_set(struct Connection *conn, int id, const char *name, const char *email) { struct Address *addr = &conn->db->rows[id]; //get the i element of rows, which is in db, which is in conn, then get the address of the above if(addr->set) die("Already set, delete it first."); addr->set = 1; char *res = strncpy(addr->name, name, MAX_DATA); // just fix prinf in address call, far easier 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) //fetch the database with a certain id { struct Address *addr = &conn->db->rows[id]; if(addr->set){ Address_print(addr); //print address } else { die("ID is not set."); } } void Database_delete(struct Connection *conn, int id) //this function deletes the database { struct Address addr = {.id = id, .set = 0}; //set temporary local address tonull conn->db->rows[id] = addr; } void Database_list(struct Connection *conn) //list the databases { int i = 0; struct Database *db = conn->db; //new pointer for(i = 0; i < MAX_ROWS; i++) { struct Address *cur = &db->rows[i]; //set the rows to the address of db 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]; //our filename char action = argv[2][0]; struct Connection *conn = Database_open(filename, action); //open a database 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; }
void Database_create(struct Connection *conn, int max_rows, int max_data) { conn->db->max_rows = max_rows; conn->db->max_data = max_data; Database_alloc_rows(conn); int i = 0; for(i = 0; i < max_rows; i++) { struct Address addr = { .id = i, .set = 0}; addr.email = malloc(sizeof(char) * conn->db->max_data); addr.name = malloc(sizeof(char) * conn->db->max_data); conn->db->rows[i] = addr; } } struct Connection *Database_open(const char *filename, char mode) { struct Connection *conn = malloc(sizeof(struct Connection)); if(!conn) die("Memory error", conn); conn->db = malloc(sizeof(struct Database)); if(!conn->db) die("Memory error", conn); if(mode == 'c') { conn->file = fopen(filename, "w"); } else { conn->file = fopen(filename, "r+"); if(conn->file) { Database_load(conn); } } if(!conn->file) die("Failed to open the file", conn); return conn; } void Database_close(struct Connection *conn) { if(conn) { if(conn->file) fclose(conn->file); if(conn->db->rows) free(conn->db->rows); if(conn->db) free(conn->db); free(conn); } } 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", conn); addr->set = 1; //WARNING: bug, read the "How to break it" and fix this char *res = strncpy(addr->name, name, conn->db->max_data); //demonstrate the strncpy bug if(!res) die("Name copy failed", conn); res = strncpy(addr->email, email, conn->db->max_data); if(!res) die("Email copy failed", conn); } void Database_get(struct Connection *conn, int id) { if(id > conn->db->max_rows) { die("There's not that many rows", conn); } struct Address *addr = &conn->db->rows[id]; if(addr->set) { Address_print(addr); } else { die("ID not set", conn); } } void Database_delete(struct Connection *conn, int id) { struct Address addr = {.id = id, .set = 0}; addr.email = malloc(sizeof(char) * conn->db->max_data); addr.name = malloc(sizeof(char) * conn->db->max_data); conn->db->rows[id] = addr; } void Database_list(struct Connection *conn) { int i = 0; for(i=0; i< conn->db->max_rows; i++) { struct Address *cur = &(conn->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]", NULL); char *filename = argv[1]; char action = argv[2][0]; struct Connection *conn = Database_open(filename, action); int param1 = 0; int param2 = 0; int max_rows = 100; int max_data = 512; if(argc > 3) { param1 = atoi(argv[3]); } if(argc > 4) { param2 = atoi(argv[4]); } switch(action) { case 'c': if(argc > 3) { max_rows = param1; } if(argc > 4) { max_data = param2; } Database_create(conn, max_rows, max_data); Database_write(conn); break; case 'g': if(argc != 4) die("Need an id to get", conn); Database_get(conn, param1); break; case 's': if(argc != 6) die("Need id, name, email to set", conn); Database_set(conn, param1, argv[4], argv[5]); Database_write(conn); break; case 'd': if(argc != 4) die("Need an id to delete", conn); Database_delete(conn, param1); 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", conn); } Database_close(conn); return 0; }
void Database_create(struct Connection *conn) { int i = 0; for (i = 0; i < MAX_ROWS; i++) { struct Address addr = {.id = i, .set = 0}; conn->db->rows[i] = addr; }; }; void Database_delete(struct Connection *conn, int id) { struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; }; void Database_set(struct Connection *conn, int id, const char *restrict name, const char *restrict email) { struct Address *restrict addr = &conn->db->rows[id]; if(addr->set) { die("Already set, delete it first"); }; addr->set = 1; char *res = strncpy(addr->name, name, MAX_DATA); addr->name[ sizeof(name) - 1 ] = '\0'; if(!res) { die("Name copy failed."); }; char *res1 = strncopy(addr->email, email, MAX_DATA); addr->email[ sizeof(email) - 1 ] = '\0'; if(!res1) { die("Email copy failed"); }; }; void Database_get(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); 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; };
void Database_create(struct Connection *conn) { int i = 0; for(i = 0; i < MAX_ROWS; i++) { //Initizalize Database struct Users user = {.id = i, .set = 0}; // Assign database conn->db->rows[i] = user; } } void Database_set(struct Connection *conn, int id, const char *username, const char *password) { struct Users *user = &conn->db->rows[id]; if(user->set) die("Already set, delete it first"); user->set = 1; //we have to find a better way to do this rather than strncpy char *res = strncpy(user->username, username, MAX_DATA); if(!res) die("Username copy failed"); res = strncpy(user->password, password, MAX_DATA); if(!res) die("Password copy failed"); } void Database_get(struct Connection *conn, int id) { struct Users *user = &conn->db->rows[id]; if(user->set) { Users_print(user); } else { die("ID is not set"); } } void Database_delete(struct Connection *conn, int id) { struct Users user = {.id = id, .set = 0}; conn->db->rows[id] = user; } void Database_list(struct Connection *conn) { int i = 0; struct Database *db = conn->db; for(i = 0; i < MAX_ROWS; i++) { struct Users *cur = &db->rows[i]; if(cur->set) { Users_print(cur); } } } int main(int argc, char *argv[]) { if(argc < 3) die("USAGE: Database <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, username, password 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; }
void Database_create(struct Connection *conn) { int i = 0; for (i = 0; i <= MAX_ROWS; i++){ //make a prototype to initialize data to address struct Address addr = {.id = i, .set = 0}; //assign address rows to the db conn->db->rows[i] = addr; } } 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 row first"); addr->set = 1; // Warning: bug, read the how to break and fix this char *res = strncpy(addr->name, name, MAX_DATA); 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 *addr = &db->rows[i]; if (addr->set){ Address_print(addr); } } } int main (int argc, char *argv[]) { if (argc < 3) die ("Too less argument for setting up db: 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("Too many records to open. There are 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 open the record"); Database_get(conn, id); break; case 's': if (argc != 6) die ("Need id email and name 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=Delete, l=List commands are available"); } Database_close(conn); return 0; }
void Database_create(struct Connection * connection) { int i = 0; for(i = 0; i < MAX_ROWS; i++) { struct Address addr = { .id = i, .set = 0 }; connection->db->rows[i] = addr; } } void Database_set(struct Connection * connection, int id, const char * name, const char * email) { struct Address *address = &connection->db->rows[id]; if(address->set) die("Already set. Delete it first."); address->set = 1; // Warning BUG char * res = strncpy(address->name, name, MAX_DATA); // Demonstrate strncpy bug if(!res) die("Name copy failed"); res = strncpy(address->email, email, MAX_DATA); if(!res) die("Email copy failed"); } void Database_get(struct Connection * connection, int id) { struct Address * address = &connection->db->rows[id]; if(address->set) { Address_print(address); } else { die("ID is not set"); } } void Database_delete(struct Connection * connection, int id) { struct Address address = { .id = id, .set = 0 }; connection->db->rows[id] = address; } void Database_list(struct Connection * connection) { int i = 0; struct Database * db = connection->db; for(i = 0; i < MAX_ROWS; i++) { struct Address * current = &db->rows[i]; if(current->set) Address_print(current); } } int main(int argc, char * argv[]) { if(argc < 3) die("USAGE: ex17 <db_file> <action> [action params]"); char * filename = argv[1]; char action = argv[2][0]; struct Connection * connection = 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(connection); Database_write(connection); break; case 'g': if(argc != 4) die("Need an id to get"); Database_get(connection, id); break; case 's': if(argc != 6) die("Need id, name, and email to set"); Database_set(connection, id, argv[4], argv[5]); Database_write(connection); break; case 'd': if(argc != 4) die("Need id to delete"); Database_delete(connection, id); Database_write(connection); break; case 'l': Database_list(connection); break; default: die("Invalid action. Only: c=create, g=get, s=save, d=delete, l=list"); } Database_close(connection); return 0; }
void Database_create(struct Connection *conn) { int i = 0; for (i = 0; i < MAX_ROWS; i++) { // make a prototype to initialize it struct Address addr = {.id = i, .set = 0}; // then just assign it conn->db->rows[i] = addr; } } 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: bug, read the "How To Break It" and fix it char *res = strncpy(addr->name, name, MAX_DATA); // demonstrate the 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"); 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; }
void Database_create(struct Connection *conn, int max_rows, int max_data) { printf("Creating database...\n"); int i = 0; for(i = 0; i < max_rows; i++) { // Make a prototype to initialize it: struct Address addr = {.id = i, .set = 0}; // ...then set it: conn->db->rows[i] = addr; } printf("Database created.\n"); } void Database_set(struct Connection *conn, int id, const char *name, const char *email) { //printf("Setting DB entry...\n"); struct Address *addr = &conn->db->rows[id]; if(addr->set) die(conn, "DB Address already set, delete it first."); // WARNING: This a bug: char *res = strncpy(addr->name, name, conn->db->max_data); // Demonstrate the strncopy bug: if(!res) die(conn, "Name copy failed."); res = strncpy(addr->email, email, conn->db->max_data); if(!res) die(conn, "Email copy failed."); addr->set = 1; //printf("DB entry set\n"); } void Database_get(struct Connection *conn, int id) { struct Address *addr = &conn->db->rows[id]; if(addr->set) { Address_print(addr); } else { die(conn, "DB Address is not set"); } printf("DB entry got\n"); } void Database_delete(struct Connection *conn, int id) { struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; printf("DB entry deleted\n"); } void Database_list(struct Connection *conn) { printf("Printing Database...\n"); int i = 0; struct Database *db = conn->db; for(i = 0; i < db->max_rows; i++) { struct Address *cur = &db->rows[i]; if(cur->set) { //printf("Is set!"); Address_print(cur); } //printf("Is not set!"); } printf("...Database printed.\n"); } void Database_find(struct Connection *conn, char *target) { struct Database *db = conn->db; struct Address *addr; int i; printf("Finding %s...\n", target); for(i = 0; i < db->max_rows; i++) { addr = &db->rows[i]; if(addr->set == 1) { if(strstr(addr->name, target) || strstr(addr->email, target)) Address_print(addr); } } printf("All results found.\n"); } int main(int argc, char* argv[]) { if(argc < 3) die(NULL, "USAGE: ex17 <dbfile> <action> [action params]"); char* filename = argv[1]; char action = argv[2][0]; struct Connection* conn; if(action == 'c') conn = Database_open(filename, action, atoi(argv[3]), atoi(argv[4])); else conn = Database_open(filename, action, 0, 0); int id = 0; switch(action) { case 'c': if(argc != 5) die(conn, "Incorrect params."); Database_create(conn, atoi(argv[3]), atoi(argv[4])); Database_write(conn); break; case 'g': id = atoi(argv[3]); if(id > conn->db->max_rows) die(conn, "ID is greater than number of records."); if(argc != 4) die(conn, "Need ID to get."); Database_get(conn, id); break; case 's': id = atoi(argv[3]); if(id > conn->db->max_rows) die(conn, "ID is greater than number of records."); if(argc != 6) die(conn, "Need ID, name and email to set."); Database_set(conn, id, argv[4], argv[5]); Database_write(conn); break; case 'd': id = atoi(argv[3]); if(id > conn->db->max_rows) die(conn, "ID is greater than number of records."); if(argc != 4) die(conn, "Need ID to delete."); Database_delete(conn, id); Database_write(conn); break; case 'l': Database_list(conn); break; case 'f': Database_find(conn, argv[3]); break; default: die(conn, "Invalid action. c=create, g=get, s=set, d=delete, s=set, f=find."); } Database_close(conn); return 0; }