diff options
Diffstat (limited to 'C/final-project-z2h')
| -rw-r--r-- | C/final-project-z2h/Makefile | 22 | ||||
| -rw-r--r-- | C/final-project-z2h/README.md | 1 | ||||
| -rw-r--r-- | C/final-project-z2h/fdb | bin | 0 -> 1044 bytes | |||
| -rw-r--r-- | C/final-project-z2h/include/common.h | 8 | ||||
| -rw-r--r-- | C/final-project-z2h/include/file.h | 7 | ||||
| -rw-r--r-- | C/final-project-z2h/include/parse.h | 26 | ||||
| -rw-r--r-- | C/final-project-z2h/src/file.c | 39 | ||||
| -rw-r--r-- | C/final-project-z2h/src/main.c | 108 | ||||
| -rw-r--r-- | C/final-project-z2h/src/parse.c | 162 |
9 files changed, 373 insertions, 0 deletions
diff --git a/C/final-project-z2h/Makefile b/C/final-project-z2h/Makefile new file mode 100644 index 0000000..be3cefa --- /dev/null +++ b/C/final-project-z2h/Makefile @@ -0,0 +1,22 @@ +TARGET = bin/dbview +SRC = $(wildcard src/*.c) +OBJ = $(patsubst src/%.c, obj/%.o, $(SRC)) + +run: clean default + ./$(TARGET) -f ./mynewdb.db -n + ./$(TARGET) -f ./mynewdb.db -a "Timmy H.,123 Sheshire Ln.,120" + +default: $(TARGET) + +clean: + rm -f obj/*.o + rm -f bin/* + rm -f *.db + +$(TARGET): $(OBJ) + gcc -o $@ $? + +obj/%.o : src/%.c + gcc -c $< -o $@ -Iinclude + + diff --git a/C/final-project-z2h/README.md b/C/final-project-z2h/README.md new file mode 100644 index 0000000..560d92e --- /dev/null +++ b/C/final-project-z2h/README.md @@ -0,0 +1 @@ +# This is a readme file diff --git a/C/final-project-z2h/fdb b/C/final-project-z2h/fdb Binary files differnew file mode 100644 index 0000000..394b7fb --- /dev/null +++ b/C/final-project-z2h/fdb diff --git a/C/final-project-z2h/include/common.h b/C/final-project-z2h/include/common.h new file mode 100644 index 0000000..839cc6f --- /dev/null +++ b/C/final-project-z2h/include/common.h @@ -0,0 +1,8 @@ +#ifndef COMMON_H +#define COMMON_H + +#define STATUS_ERROR -1 +#define STATUS_SUCCESS 0 + + +#endif diff --git a/C/final-project-z2h/include/file.h b/C/final-project-z2h/include/file.h new file mode 100644 index 0000000..73fd2a7 --- /dev/null +++ b/C/final-project-z2h/include/file.h @@ -0,0 +1,7 @@ +#ifndef FILE_H +#define FILE_H + +int create_db_file(char *filename); +int open_db_file(char *filename); + +#endif diff --git a/C/final-project-z2h/include/parse.h b/C/final-project-z2h/include/parse.h new file mode 100644 index 0000000..edcda9b --- /dev/null +++ b/C/final-project-z2h/include/parse.h @@ -0,0 +1,26 @@ +#ifndef PARSE_H +#define PARSE_H + +#define HEADER_MAGIC 0x4c4c4144 + +struct dbheader_t { + unsigned int magic; + unsigned short version; + unsigned short count; + unsigned int filesize; +}; + +struct employee_t { + char name[256]; + char address[256]; + unsigned int hours; +}; + +int create_db_header(int fd, struct dbheader_t **headerOut); +int validate_db_header(int fd, struct dbheader_t **headerOut); +int read_employees(int fd, struct dbheader_t *, struct employee_t **employeesOut); +int output_file(int fd, struct dbheader_t *, struct employee_t *employees); +void list_employees(struct dbheader_t *dbhdr, struct employee_t *employees); +int add_employee(struct dbheader_t *dbhdr, struct employee_t *employees, char *addstring); + +#endif 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; +} + + |
