summaryrefslogtreecommitdiff
path: root/C/final-project-z2h/src
diff options
context:
space:
mode:
Diffstat (limited to 'C/final-project-z2h/src')
-rw-r--r--C/final-project-z2h/src/file.c39
-rw-r--r--C/final-project-z2h/src/main.c108
-rw-r--r--C/final-project-z2h/src/parse.c162
3 files changed, 309 insertions, 0 deletions
diff --git a/C/final-project-z2h/src/file.c b/C/final-project-z2h/src/file.c
new file mode 100644
index 0000000..fcdb036
--- /dev/null
+++ b/C/final-project-z2h/src/file.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "file.h"
+#include "common.h"
+
+
+int create_db_file(char *filename) {
+ int fd = open(filename, O_RDWR);
+ if (fd != -1) {
+ close(fd);
+ printf("File already exists\n");
+ return STATUS_ERROR;
+ }
+
+ fd = open(filename, O_RDWR | O_CREAT, 0644);
+ if (fd == -1) {
+ perror("open");
+ return STATUS_ERROR;
+ }
+
+ return fd;
+}
+
+int open_db_file(char *filename) {
+ int fd = open(filename, O_RDWR, 0644);
+ if (fd == -1) {
+ perror("open");
+ return STATUS_ERROR;
+ }
+
+ return fd;
+}
+
+
diff --git a/C/final-project-z2h/src/main.c b/C/final-project-z2h/src/main.c
new file mode 100644
index 0000000..09cbde1
--- /dev/null
+++ b/C/final-project-z2h/src/main.c
@@ -0,0 +1,108 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <getopt.h>
+#include <stdlib.h>
+
+#include "common.h"
+#include "file.h"
+#include "parse.h"
+
+void print_usage(char *argv[]) {
+ printf("Usage: %s -n -f <database file>\n", argv[0]);
+ printf("\t -n - create new database file\n");
+ printf("\t -f - (required) path to database file\n");
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ char *filepath = NULL;
+ char *portarg = NULL;
+ unsigned short port = 0;
+ bool newfile = false;
+ bool list = false;
+ char *addstring = NULL;
+ int c;
+
+ int dbfd = -1;
+ struct dbheader_t *dbhdr = NULL;
+ struct employee_t *employees = NULL;
+
+ while ((c = getopt(argc, argv, "nf:a:l")) != -1) {
+ switch (c) {
+ case 'n':
+ newfile = true;
+ break;
+ case 'f':
+ filepath = optarg;
+ break;
+ case 'p':
+ portarg = optarg;
+ break;
+ case 'a':
+ addstring = optarg;
+ break;
+ case 'l':
+ list = true;
+ break;
+ case '?':
+ printf("Unknown option -%c\n", c);
+ break;
+ default:
+ return -1;
+
+ }
+ }
+
+ if (filepath == NULL) {
+ printf("Filepath is a required argument\n");
+ print_usage(argv);
+
+ return 0;
+ }
+
+
+ if (newfile) {
+ dbfd = create_db_file(filepath);
+ if (dbfd == STATUS_ERROR) {
+ printf("Unable to create database file\n");
+ return -1;
+ }
+
+ if (create_db_header(dbfd, &dbhdr) == STATUS_ERROR) {
+ printf("Failed to create database header\n");
+ return -1;
+ }
+ } else {
+ dbfd = open_db_file(filepath);
+ if (dbfd == STATUS_ERROR) {
+ printf("Unable to open database file\n");
+ return -1;
+ }
+
+ if (validate_db_header(dbfd, &dbhdr) == STATUS_ERROR) {
+ printf("Failed to validate database header\n");
+ return -1;
+ }
+ }
+
+ if (read_employees(dbfd, dbhdr, &employees) != STATUS_SUCCESS) {
+ printf("Failed to read employees");
+ return 0;
+ }
+
+ if (addstring) {
+ dbhdr->count++;
+ employees = realloc(employees, dbhdr->count*(sizeof(struct employee_t)));
+ add_employee(dbhdr, employees, addstring);
+ }
+
+ if (list) {
+ list_employees(dbhdr, employees);
+ }
+
+
+ output_file(dbfd, dbhdr, employees);
+
+
+ return 0;
+}
diff --git a/C/final-project-z2h/src/parse.c b/C/final-project-z2h/src/parse.c
new file mode 100644
index 0000000..0f9b8e7
--- /dev/null
+++ b/C/final-project-z2h/src/parse.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "common.h"
+#include "parse.h"
+
+void list_employees(struct dbheader_t *dbhdr, struct employee_t *employees) {
+ int i = 0;
+ for (; i < dbhdr->count; i++) {
+ printf("Employee %d\n", i);
+ printf("\tName: %s\n", employees[i].name);
+ printf("\tAddress: %s\n", employees[i].address);
+ printf("\tHours: %d\n", employees[i].hours);
+ }
+}
+
+int add_employee(struct dbheader_t *dbhdr, struct employee_t *employees, char *addstring) {
+ printf("%s\n", addstring);
+
+ char *name = strtok(addstring, ",");
+
+ char *addr = strtok(NULL, ",");
+
+ char *hours = strtok(NULL, ",");
+
+ printf("%s %s %s\n", name, addr, hours);
+
+
+ strncpy(employees[dbhdr->count-1].name, name, sizeof(employees[dbhdr->count-1].name));
+ strncpy(employees[dbhdr->count-1].address, addr, sizeof(employees[dbhdr->count-1].address));
+
+ employees[dbhdr->count-1].hours = atoi(hours);
+
+
+ return STATUS_SUCCESS;
+}
+
+int read_employees(int fd, struct dbheader_t *dbhdr, struct employee_t **employeesOut) {
+ if (fd < 0) {
+ printf("Got a bad FD from the user\n");
+ return STATUS_ERROR;
+ }
+
+
+ int count = dbhdr->count;
+
+ struct employee_t *employees = calloc(count, sizeof(struct employee_t));
+ if (employees == (void*)-1) {
+ printf("Malloc failed\n");
+ return STATUS_ERROR;
+ }
+
+ read(fd, employees, count*sizeof(struct employee_t));
+
+ int i = 0;
+ for (; i < count; i++) {
+ employees[i].hours = ntohl(employees[i].hours);
+ }
+
+ *employeesOut = employees;
+ return STATUS_SUCCESS;
+
+}
+
+int output_file(int fd, struct dbheader_t *dbhdr, struct employee_t *employees) {
+ if (fd < 0) {
+ printf("Got a bad FD from the user\n");
+ return STATUS_ERROR;
+ }
+
+ int realcount = dbhdr->count;
+
+ dbhdr->magic = htonl(dbhdr->magic);
+ dbhdr->filesize = htonl(sizeof(struct dbheader_t) + (sizeof(struct employee_t) * realcount));
+ dbhdr->count = htons(dbhdr->count);
+ dbhdr->version = htons(dbhdr->version);
+
+ lseek(fd, 0, SEEK_SET);
+
+ write(fd, dbhdr, sizeof(struct dbheader_t));
+
+ int i = 0;
+ for (; i < realcount; i++) {
+ employees[i].hours = htonl(employees[i].hours);
+ write(fd, &employees[i], sizeof(struct employee_t));
+ }
+
+ return STATUS_SUCCESS;
+
+}
+
+int validate_db_header(int fd, struct dbheader_t **headerOut) {
+ if (fd < 0) {
+ printf("Got a bad FD from the user\n");
+ return STATUS_ERROR;
+ }
+
+ struct dbheader_t *header = calloc(1, sizeof(struct dbheader_t));
+ if (header == (void*)-1) {
+ printf("Malloc failed create a db header\n");
+ return STATUS_ERROR;
+ }
+
+ if (read(fd, header, sizeof(struct dbheader_t)) != sizeof(struct dbheader_t)) {
+ perror("read");
+ free(header);
+ return STATUS_ERROR;
+ }
+
+ header->version = ntohs(header->version);
+ header->count = ntohs(header->count);
+ header->magic = ntohl(header->magic);
+ header->filesize = ntohl(header->filesize);
+
+ if (header->magic != HEADER_MAGIC) {
+ printf("Impromper header magic\n");
+ free(header);
+ return -1;
+ }
+
+
+ if (header->version != 1) {
+ printf("Impromper header version\n");
+ free(header);
+ return -1;
+ }
+
+ struct stat dbstat = {0};
+ fstat(fd, &dbstat);
+ if (header->filesize != dbstat.st_size) {
+ printf("Corrupted database\n");
+ free(header);
+ return -1;
+ }
+
+ *headerOut = header;
+}
+
+int create_db_header(int fd, struct dbheader_t **headerOut) {
+ struct dbheader_t *header = calloc(1, sizeof(struct dbheader_t));
+ if (header == (void*)-1) {
+ printf("Malloc failed to create db header\n");
+ return STATUS_ERROR;
+ }
+
+ header->version = 0x1;
+ header->count = 0;
+ header->magic = HEADER_MAGIC;
+ header->filesize = sizeof(struct dbheader_t);
+
+ *headerOut = header;
+
+ return STATUS_SUCCESS;
+}
+
+