diff options
| author | Carlos Maiolino <[email protected]> | 2025-07-10 22:55:07 +0200 |
|---|---|---|
| committer | Carlos Maiolino <[email protected]> | 2025-07-10 22:56:55 +0200 |
| commit | d98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch) | |
| tree | 267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /C/final-project-z2h/src | |
| parent | 869e68986aa8f69af6e7842260a68d1e5c6f796f (diff) | |
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'C/final-project-z2h/src')
| -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 |
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; +} + + |
