diff --git a/Makefile b/Makefile index 8296cda..b7d3026 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,10 @@ test: cp etc/example.cfg ./glacier.cfg lib: - mkdir lib - $(CC) libglacier.c -c $(LIBFLAGS) -o lib/libglacier.o - $(AR) -rc lib/libglacier.a lib/libglacier.o + mkdir build + mkdir build/lib + $(CC) libglacier.c -c $(LIBFLAGS) -o build/lib/libglacier.o + $(AR) -rc build/lib/libglacier.a build/lib/libglacier.o install: install lib/libglacier.a $(PREFIX)/lib @@ -28,4 +29,4 @@ install: install include/glacier_runtime.h $(PREFIX)/include clean: - rm libglacier.test libglacier.a glacier.cfg + rm -rf build diff --git a/include/glacier_config.h b/include/glacier_config.h index 45ad128..59a25bb 100644 --- a/include/glacier_config.h +++ b/include/glacier_config.h @@ -22,16 +22,25 @@ * init_config * DESCRIPTION: Init_config initializes the libconfig library, so it can read the required runtime files * PARAMETERS: - * None. + * None. (void) * RETURN VAUES: - * 0 on success, 1 on failure + * 0 on success, EXIT_FAILURE on failure * CAVEATS: * None. * EXAMPLE: - * init_config(); + * // It is best practice to check for ALL non-zero return values, rather than specific ones, + * // as init_config() returns EXIT_FAILURE + * + * if (init_config() != 0) { + * errlog("Failed to initialize libconfig"); + * return(EXIT_FAILURE); // fatal error requiring termination of program execution + * } + * else { + * successlog("Initialized libconfig"); // output automatically if LG_VERBOSE = 1 + * } */ -int init_config(); +int init_config(void); /**************************************************************************************************************/ @@ -39,16 +48,19 @@ int init_config(); * die_config * DESCRPTION: Die_config destroys the loaded libconfig library. * PARAMETERS: - * None. + * None. (void) * RETURN VALUES: - * 0 on success, 1 on failure + * EXIT_SUCCESS on success * CAVEATS: * None. * EXAMPLE: + * // die_config() is unlikely to fail unless you tried to destroy an invalid object, + * // so checking for non-zero return values is unnecessary + * * die_config(); */ -int die_config(); +int die_config(void); /**************************************************************************************************************/ @@ -56,7 +68,7 @@ int die_config(); * load_all_from_config * DESCRIPTION: Initialize all settings from glacier.cfg. * PARAMETERS: - * None. + * None. (void) * RETURN VALUES: * 0 on success, 1 on file does not exist, 2 on library error * CAVEATS: diff --git a/include/glacier_data.h b/include/glacier_data.h index aa83a23..bec5c25 100644 --- a/include/glacier_data.h +++ b/include/glacier_data.h @@ -72,4 +72,85 @@ void add_child(struct node *parent, struct node *child); void print_tree(struct node *root, int level); +/**************************************************************************************************************/ + +/* + * init_queue + * + * DESCRIPTION: Init_queue initializes a queue data structue. + * PARAMETERS: + * queue *q -> The name of the queue to initialize + * RETURN VALUES: + * None. + * CAVEATS: + * None. + * EXAMPLE: + * init_queue("operation_queue"); + */ + +void init_queue(queue *q); + +/**************************************************************************************************************/ + +/* + * queue_is_empty + * + * DESCRIPTION: Queue_is_empty checks if queue *q is empty + * PARAMETERS: + * queue *q -> The queue to check + * RETURN VALUES: + * true on empty, false on not empty + * CAVEATS: + * None. + * EXAMPLE: + * if (queue_is_empty(q)) { + * printf("Queue is empty\n"); + * return; + * } + */ + +bool queue_is_empty(queue *q); + +/**************************************************************************************************************/ + +/* + * queue_is_full + * + * DESCRIPTION: Queue_is_full checks if queue *q is full + * PARAMETERS: + * queue *q -> The queue to check + * RETURN VALUES: + * true on full, false on not full + * CAVEATS: + * None. + * EXAMPLE: + * if (queue_is_full(q)) { + * printf("Queue is full\n"); + * return; + * } + */ + +bool queue_is_full(queue *q); + +/**************************************************************************************************************/ + +/* + * enqueue + * + * DESCRIPTION: Enqueue enqueues an element at the back of the queue + * PARAMETERS: + * queue *q -> The queue to enqueue to + * int value -> + * RETURN VALUES: + * true on full, false on not full + * CAVEATS: + * None. + * EXAMPLE: + * if (queue_is_full(q)) { + * printf("Queue is full\n"); + * return; + * } + */ + + #endif diff --git a/include/glacier_runtime.h b/include/glacier_runtime.h index 1133f52..716b820 100644 --- a/include/glacier_runtime.h +++ b/include/glacier_runtime.h @@ -23,31 +23,47 @@ * * DESCRIPTION: runtime_exists checks if all necessary runtime files exist. * PARAMETERS: - * None. + * None. (void) * RETURN VALUES: - * None. + * 0 on one or more runtime files missing, 1 on all runtime files exist * CAVEATS: * None. * EXAMPLE: - * runtime_exists(); + * if (runtime_exists() == 0) { + * errlog("One or more runtime files missing"); + * return 1; + * } + * else { + * successlog("All runtime files present"); + * return 0; + * } */ -void runtime_exists(); +int runtime_exists(void); /* * is_process_root * * DESCRIPTION: is_process_root checks if the process is running with root privileges. * PARAMETERS: - * None. + * None. (void) * RETURN VALUES: - * 0 on root, 1 on non-root + * 0 on process is not running as root, 1 on process is running as root * CAVEATS: * None. * EXAMPLE: - * is_process_root(); + * // Assuming block is running within main(), no values will be returned. + * // If you wish to exit the program if it is not running as root, it would + * // be appropriate to add return values to this block + * + * if (is_process_root() == 0) { + * errlog("Process is not running as root"); + * } + * else { + * successlog("Process is running as root"); + * } */ -int is_process_root(); +int is_process_root(void); #endif diff --git a/include/glacier_security.h b/include/glacier_security.h new file mode 100644 index 0000000..27ce1c7 --- /dev/null +++ b/include/glacier_security.h @@ -0,0 +1,38 @@ +/* + * glacier_runtime.h - Runtime function declarations for libglacier + * + * This file is part of Glacier. + * + * Glacier is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * Glacier is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Glacier. If + * not, see . + */ + +#ifndef GLACIERSECURITY_H_ +#define GLACIERSECURITY_H_ + +/* + * compare_file_hash + * + * DESCRIPTION: compare_file_hash compares the SHA256 hashes of a file and its original hash + * PARAMETERS: + * char ORIG_HASH[] -> The file containing the expected hash result + * char FILE[] -> The file to compare against ORIG_HASH[] + * RETURN VALUES: + * 0 on hashes match, 1 on hashes do not match, -1 on library error + * CAVEATS: + * None. + * EXAMPLE: + * compare_file_hash("pkg.sha256sum", "pkg.tar.xz"); + */ + +int compare_file_hash(char ORIG_HASH[], char FILE[]); + +#endif diff --git a/libglacier.c b/libglacier.c index df4f1d0..cee9748 100644 --- a/libglacier.c +++ b/libglacier.c @@ -31,7 +31,9 @@ #include "config.h" +#define BUFFER_SIZE 1024 #define MAX_CHILDREN 64 +#define MAX_SIZE 256 /* Global variables */ @@ -62,6 +64,9 @@ struct node { int numChildren; }; +FILE *expected_hash; +FILE *pkg; + /* * infolog * @@ -152,21 +157,22 @@ successlog(char MSG[]) */ int -runtime_exists() +runtime_exists(void) { int f; - for (f = 0; f < 3; f++) { + for (f = 0; f < sizeof(runtime_files); f++) { if (access(runtime_files[f], F_OK) == 0) { continue; } else { - errlog("Runtime files are missing, cannot continue with operation."); + /* might keep this message, might not, idk */ + /* errlog("Runtime files are missing, cannot continue with operation."); printf(COL_RED "[x]" COL_RESET " The following files are missing:\n"); - printf(COL_RED "[x]" COL_RESET " \t%s\n", runtime_files[f]); - return 1; + printf(COL_RED "[x]" COL_RESET " \t%s\n", runtime_files[f]); */ + return 0; } } - return 0; + return 1; } /* @@ -179,11 +185,13 @@ runtime_exists() */ int -is_process_root(char MSG[]) +is_process_root(void) { if (getuid() != 0) { - fprintf(stderr, COL_RED "[x] " COL_RESET "%s\n", MSG); - exit(1); + return 0; /* process is not running as root */ + } + else { + return 1; /* process is running as root */ } } @@ -197,7 +205,7 @@ is_process_root(char MSG[]) */ int -init_config() +init_config(void) { config_init(&cfg); @@ -225,7 +233,7 @@ init_config() */ int -die_config() +die_config(void) { config_destroy(&cfg); @@ -246,7 +254,7 @@ die_config() */ int -load_all_from_config() +load_all_from_config(void) { config_lookup_bool(&cfg, "GLACIER_DO_INT_CHECK", &GLACIER_DO_INT_CHECK); config_lookup_bool(&cfg, "GLACIER_VERBOSE", &GLACIER_VERBOSE); @@ -310,13 +318,13 @@ struct node } /* -* add_child -* -* DESCRIPTION: Add a child node to a parent node. -* PARAMETERS: struct node *parent, struct node *child -* DEFINED IN: glacier_data.h -* -*/ + * add_child + * + * DESCRIPTION: Add a child node to a parent node. + * PARAMETERS: struct node *parent, struct node *child + * DEFINED IN: glacier_data.h + * + */ void add_child(struct node *parent, struct node *child) @@ -356,6 +364,137 @@ print_tree(struct node *root, int level) } } +/* Definition of queue data type */ +typedef struct { + int items[MAX_SIZE]; + int front; + int rear; +} queue; + +/* +* init_queue +* +* DESCRIPTION: Initialize a queue. +* PARAMETERS: queue *q +* DEFINED IN: glacier_data.h +* +*/ + +void +init_queue(queue *q) +{ + q -> front = -1; + q -> rear = 0; +} + +/* +* queue_is_empty +* +* DESCRIPTION: Check if queue is empty. +* PARAMETERS: struct node *root, int level +* DEFINED IN: glacier_data.h +* +*/ + +bool queue_is_empty(queue *q) { return (q -> front == q -> rear -1); } + +/* +* queue_is_full +* +* DESCRIPTION: Check if queue is full. +* PARAMETERS: queue *q +* DEFINED IN: glacier_data.h +* +*/ + +bool queue_is_full(queue *q) { return (q -> rear == MAX_SIZE); } + +/* +* enqueue +* +* DESCRIPTION: Enqueue an element at the back of the queue. +* PARAMETERS: queue *q, int value +* DEFINED IN: glacier_data.h +* +*/ + +void +enqueue (queue *q, int value) +{ + if (queue_is_full(q)) { + printf("Queue is full\n"); + return; + } + + q -> items[q -> rear] = value; + q -> rear++; +} + +/* +* dequeue +* +* DESCRIPTION: Dequeue the element at the front of the queue. +* PARAMETERS: queue *q, int value +* DEFINED IN: glacier_data.h +* +*/ + +void +dequeue(queue *q) +{ + if (queue_is_empty(q)) { + printf("Queue is empty\n"); + return; + } + + q -> front++; +} + +/* +* peek +* +* DESCRIPTION: View the element at the front of the queue. +* PARAMETERS: struct node *root, int level +* DEFINED IN: glacier_data.h +* +*/ + +int +peek(queue *q) +{ + if (queue_is_empty(q)) { + printf("Queue is empty\n"); + return -1; + } + + return q -> items[q -> front + 1]; +} + +/* +* print_queue +* +* DESCRIPTION: Print the queue. +* PARAMETERS: queue *q +* DEFINED IN: glacier_data.h +* +*/ + +void +print_queue(queue *q) +{ + if (queue_is_empty(q)) { + printf("Queue is empty\n"); + return; + } + + printf("Current Queue: "); + + for (int i = q -> front + 1; i < q -> rear; i++) { + printf("%d ", q -> items[i]); + } + printf("\n"); +} + /* * mkworkspace * @@ -366,17 +505,22 @@ print_tree(struct node *root, int level) */ int -mkworkspace() +mkworkspace(void) { DIR* workspace = opendir("/tmp/glacier-workspace"); if (workspace) { - infolog("Not creating new workspace, valid workspace already exists."); + /* infolog("Not creating new workspace, valid workspace already exists."); */ + return 0; } else if (ENOENT == errno) { - infolog("Creating new Glacier workspace..."); + /* infolog("Creating new Glacier workspace..."); */ mkdir("/tmp/glacier-workspace", 0777); + return 1; } else { - printf("LIBRARY ERROR: opendir() failed\n"); - return 2; + if (LG_VERBOSE == 1) { + errlog("in mkworkspace()"); + errlog("mkdir() failed to run"); + } + return -1; } } @@ -492,3 +636,17 @@ run_make_task(char TASK[]) } } +/* + * compare_file_hash + * + * DESCRIPTION: Compare two file hashes + * PARAMETERS: char ORIG_HASH[], char FILE[] + * DEFINED IN: glacier_security.h + * + */ + +int +compare_file_hash(char ORIG_HASH[], char FILE[]) +{ + +}