First commit to this server

This commit is contained in:
Tim O\'Neil committed 2025-08-19 07:49:22 -07:00
1 parent ec05d3601a
commit cce6f6b9c6
44 files changed
+5529 -296

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
#pragma once
typedef enum
{
CMD_MISPARAM = -11, // inimissing paramt file
CMD_MEMERR = -10,
CMD_INITNF = -9, // initialization file not found
CMD_HELPERR = -8, // problem with help subsystem
CMD_QUOTES = -7, // argument not enclosed in quotes
CMD_IOERR = -6, // io error
CMD_BANNERPTH = -5, //
CMD_FILEEXST = -4, // file exists
CMD_FILENF = -3, // file not found
CMD_ARGS = -2, // error with command arguments
CMD_ERR = -1, // non-specific error
CMD_OK = 0, // command completed successfully
CMD_QUIT = 1, // exit application
CMD_NOOP = 2 // no operation
} RET_CODE;
// Hashmap of pointers to error text and codes whatever else.
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>
#ifndef _WIN32
#include "utils/filesys.h"
#endif
#include "simple_strlib.h"
#include "error_info.h"
#ifdef __cplusplus
extern "C"{
#endif
int dummy(const char*);
int aaa(const char*);
int alist(const char*);
int amp(const char*);
int app(const char*);
int arp(const char*);
int badl(const char*);
int batch(const char*);
int bert(const char*);
int date(const char*);
int list(const char*);
int time2(const char*);
int loglevel(const char*);
int filet(const char*);
#ifdef __cplusplus
}
#endif
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>
#include "utils/filesys.h"
#include "utils/huff.h"
#include "error_info.h"
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4090 )
#pragma warning( disable : 594 )
#pragma warning( disable : 542 )
#endif
extern const char dateout[16];
extern const char timeout[20];
extern const char* commands[];
extern const int noCmds;
#ifdef __cplusplus
extern "C" {
#endif
int help(const char*);
int find_help_section(const char*);
int motd(const char*);
int prompt(const char*);
int quit(const char*);
#ifdef _MSC_VER
#pragma warning ( pop )
#endif
#ifdef __cplusplus
}
#endif
+12
View File
@@ -0,0 +1,12 @@
#pragma once
/**
* Logging thread, complately alpha code- may completely change form in the near future.
*/
inline int
StartLogger(int nLevel)
{
return CMD_OK;
}
+141
View File
@@ -0,0 +1,141 @@
#pragma once
#include "foo1.h"
#ifdef _MSC_VER
#include <io.h>
#include "winunistd.h"
#define STRLWR _strlwr
extern size_t getline(char**, size_t*, FILE*);
#else
#include <unistd.h>
#include <libconfig.h>
extern char* strlwr(char*);
#define STRLWR strlwr
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4090 )
#pragma warning( disable : 542 )
#endif
extern const char* strstrip(char*);
// Just a simple jump table
const char* commands[] = {
"dummy",
"help",
"aaa",
"access-lists",
"amplifiers",
"app",
"arp",
"badl",
"batch",
"bert",
"motd",
"prompt",
"quit",
"date",
"lists",
"time2",
"loglevel",
"filet",
"?" };
int (*table[])() = {
dummy, help, aaa, alist, amp, app, arp, badl, batch, bert,
motd, prompt, quit, date, list, time2, loglevel, filet,
};
#ifdef _MSC_VER
int const noCmds = _countof(table);
#else
const int noCmds = *(&table + 1) - table;
#endif
bool
run_cmd(int nCmd, char* full_cmd)
{
int n = 0;
if(nCmd == CMD_ERR) {
printf("\nUnknown command.\n");
return true;
}
// If help is invoked with '?'
if (nCmd == noCmds) nCmd = 1;
if((nCmd == 1) && (strlen(full_cmd) < 5)) {
printf("\n");
while (strchr(*(commands + ++n), '?') == NULL)
printf("- %s\n", *(commands + n));
printf("\n");
}
int nStatus = CMD_ERR;
int (**p)(char*);
p = table;
// command found, execute it.
nStatus = (*p[nCmd])(strstrip(full_cmd));
// if its the 'special' quit command; bail.
if (nStatus == CMD_QUIT)
return false;
return true;
}
/**
* @brief Process the commands rejecting those that aren't on the list
* This needs to be moved to another translation unit (completed 11/2023)
*
* @param char** inp The string to process
* @param int size The number of command elements
* @return boolean returns the status of the run_cmd
* function, which is only false if we
* process a quit command.
*/
bool
proc_cmds(char** inp, int size)
{
int n = 0, nCmd = 0;
bool bFound = false;
char full_cmd[200], cmd[40];
memset(full_cmd, '\n', sizeof(full_cmd));
memset(cmd, '\n', sizeof(cmd));
for(n = 0; n <= noCmds; n++) {
if(strncmp(inp[0],
*(commands + n),
strlen(strstrip(STRLWR(inp[0])))) == 0) {
bFound = true;
}
if(bFound) {
nCmd = n;
strcpy(full_cmd, *(commands + n));
for(int m = 1; m < size; m++) {
strcat(full_cmd, " ");
strcat(full_cmd, inp[m]);
}
printf("\n");
return run_cmd(nCmd, full_cmd);
}
}
return run_cmd(CMD_ERR, NULL);
}
#ifdef _MSC_VER
#pragma warning ( pop )
#endif
#ifdef __cplusplus
}
#endif
+266
View File
@@ -0,0 +1,266 @@
#pragma once
#ifdef _MSVC_VER
#include <winunistd.h>
#endif
#include "support.h"
/**
* @file simple_strlib.h
* @brief Some additions that seem to be missing or
* are missing from the clib port.
*
* @details We've rolled our own string functions, they
* were either missing or I didn't like the way
* they worked. (I tend to favor in-place string
* manips for embedded work.) Needs to be tested
* for thread safety.
*
* @author t.o.
* @bug
*/
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <stdlib.h>
#ifndef _WIN32
#include <sys/param.h>
#endif
#ifdef __cplusplus
extern "C"{
#endif
/**
* @brief strlwr
*
* @details My own version of strlwr, becuase clib
* doesn't appear to have one.
*
* @param s The string to convert
* @return pointer to the modified string
*/
inline char*
strlwr(char* s)
{
char* p = s;
while(*p) {
*p = tolower((uint32_t)*p);
p++;
}
return s;
}
/**
* @brief countc
*
* @details Count the number of occurrences of c in s
*
* @param s The target string
* @param c The character to count
* @return the count
*/
static inline int
countc(const char* s, char c)
{
int n = 0;
while(*s++ != '\0') {
if(*s == c)
n++;
}
return n;
}
/**
* @brief Strip trailing whitespace from s inplace
*
* @param s The string to trim
* @return the modified string
*/
inline const char*
strstrip(char* s)
{
size_t size = strlen(s);
if (!size)
return s;
char* end;
end = s + size - 1;
while(end >= s && isspace(*end))
end--;
*(end + 1) = '\0';
while(*s && isspace(*s))
s++;
return s;
}
/**
* @brief Split the string at delimiters using a zero-copy in-place algorithm
*
* @param s The string to split (every delimiter will be replaced by NULL)
* @param delimiter The delimiter character to split at
* @param size The size of the return array w
* @return A list of char* (size stored in *size), pointing to all split results in order
* Don't forget to free the returned array in the caller
*/
static inline char**
split(char* s, char delimiter, int* size)
{
int numdelimiters = countc(s, delimiter);
char** splitresult = malloc((numdelimiters + 2) * sizeof(char*)); // +2 for the last substring and NULL terminator
if (splitresult == NULL) {
*size = 0;
return NULL; // Memory allocation failed
}
splitresult[0] = s;
int i = 1;
char* hit = s;
while ((hit = strchr(hit, delimiter)) != NULL) {
*hit++ = '\0';
splitresult[i++] = hit;
}
splitresult[i] = NULL; // Mark the end of the splitresult array with NULL
*size = numdelimiters + 1;
return splitresult;
}
/**
* @breif Remove the substring matched. Operates
* in-place.
*
* @param the string to operate on
* @param the character sequence to remove
*/
static inline void
remove_first(char* str, const char* str_remove)
{
size_t j;
size_t len;
size_t remove_len;
int found = 0;
len = strlen(str);
remove_len = strlen(str_remove);
for(size_t i = 0; i < len; i++) {
found = 1;
for(j = 0; j < remove_len; j++) {
if(*(str + i + j) != *(str_remove + j)) {
found = 0;
break;
}
}
// If word has been found then remove it by shifting characters
if(found == 1) {
for(j = i; j <= len - remove_len; j++)
*(str + j) = *(str + j + remove_len);
// Terminate from loop so only first occurrence is removed
break;
}
}
}
/**
* @brief find first index of character in string
*
* @param string string to operate on
* @param char char to find index of
* @return integer index of the first occurance of char
*/
static inline int
find_ch_index(const char* string, char ch)
{
int i = 0;
while(*(string + i) && *(string + i) != ch) i++;
return *(string + i) == ch ? -1 : i;
}
/**
* @brief pass a substring of the source string through an i/o parameter
*
* @param char pointer source string
* @param start index of starting character for subsctring in source
* @param length of source string
* @param char pointer to destination string buffer
* @param length of destination string buffer
*/
static inline void
mid(const char* src, size_t start, size_t length, char* dst, size_t dstlen)
{
size_t len = MIN(dstlen, length);
strncpy(dst, src + start, len);
// zero terminate because strncpy() didn't ?
if(len < length)
dst[dstlen - 1] = 0;
}
static char*
right(char* string, int size)
{
while(*string++);
return(string - size - 2);
}
static char*
replace_char(char* str, char find, char replace){
char *current_pos = strchr(str,find);
while (current_pos) {
*current_pos = replace;
current_pos = strchr(current_pos,find);
}
return str;
}
static void
substr(const char* inputString, char delimiter, char** resultBuffer) {
// Find the first occurrence of the delimiter
const char* firstOccurrence = strchr(inputString, delimiter);
if (firstOccurrence == NULL) {
// Delimiter not found
*resultBuffer = NULL;
return;
}
// Find the second occurrence of the delimiter
const char* secondOccurrence = strchr(firstOccurrence + 1, delimiter);
if (secondOccurrence == NULL) {
// Second occurrence not found
*resultBuffer = NULL;
return;
}
// Calculate the length of the substring
size_t substringLength = secondOccurrence - (firstOccurrence + 1);
// Allocate memory for the result buffer
*resultBuffer = (char*)malloc(substringLength + 1);
if (*resultBuffer == NULL) {
// Memory allocation failed
fprintf(stderr, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
// Copy the substring into the result buffer
strncpy(*resultBuffer, firstOccurrence + 1, substringLength);
(*resultBuffer)[substringLength] = '\0'; // Null-terminate the string
}
#ifdef __cplusplus
}
#endif
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 5945 )
#include <conio.h>
#else
#include <termios.h>
#endif
#include <string.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C"{
#endif
/**
* Internal objects ONLY
*/
#define MAXMOTD 512
#define MAXBUF 256
#ifndef SIZEARRAY
#define SIZEARRAY(a) (sizeof(a) / sizeof((a)[0]))
#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
typedef int (*command_object)(char*);
//typedef enum {false, true} bool;
struct uinfo {
struct passwd* info;
};
struct user_ctx
{
int loglevel;
bool admin;
char prompt[16];
};
#ifdef __cplusplus
}
#endif
#ifdef _MSC_VER
#pragma warning( pop )
#endif
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <threads.h>
#define DEFAULT_THREAD_POOL_SIZE 5
typedef struct ThreadPool ThreadPool;
typedef struct Task Task;
struct Task {
void (*function)(void* arg);
void* arg;
Task* next;
};
struct ThreadPool {
mtx_t lock;
cnd_t condition;
Task* task_queue;
thrd_t* threads;
size_t num_threads;
bool shutdown;
};
#ifdef __cplusplus
extern "C"{
#endif
// Function to initialize a thread pool
ThreadPool* thread_pool_init(size_t num_threads);
// Function to destroy a thread pool
void thread_pool_destroy(ThreadPool* pool);
// Function to add a task to the thread pool
bool thread_pool_enqueue(ThreadPool* pool, void (*function)(void*), void* arg);
// Function executed by each thread in the pool
int thread_function(void* arg);
#ifdef __cplusplus
}
#endif
+111
View File
@@ -0,0 +1,111 @@
#ifndef _TCONFIG_H_
#define _TCONFIG_H_
#include <stdbool.h>
typedef struct ini_entry_s {
char* key;
char* value;
} ini_entry_s;
typedef struct ini_section_s {
char* name;
ini_entry_s* entry;
int size;
} ini_section_s;
typedef struct ini_table_s {
ini_section_s* section;
int size;
} ini_table_s;
/**
* @brief Creates an empty ini_table_s struct for writing new entries to.
* @return ini_table_s*
*/
ini_table_s* ini_table_create();
/**
* @brief Free up all the allocated resources in the ini_table_s struct.
* @param table
*/
void ini_table_destroy(ini_table_s* table);
/**
* @brief Creates an ini_table_s struct filled with data from the specified
* `file'. Returns NULL if the file can not be read.
* @param table
* @param file
* @return ini_table_s*
*/
bool ini_table_read_from_file(ini_table_s* table, const char* file);
/**
* @brief Writes the specified ini_table_s struct to the specified `file'.
* Returns false if the file could not be opened for writing, otherwise
* true.
* @param table
* @param file
* @return bool
*/
bool ini_table_write_to_file(ini_table_s* table, const char* file);
/**
* @brief Creates a new entry in the `table' containing the `key' and `value'
* provided if it does not exist. Otherwise, modifies an exsiting `key'
* with the new `value'
* @param table
* @param section_name
* @param key
* @param value
*/
void ini_table_create_entry(ini_table_s* table, const char* section_name,
const char* key, const char* value);
/**
* @brief Checks for the existance of an entry in the specified `table'. Returns
* false if the entry does not exist, otherwise true.
* @param table
* @param section_name
* @param key
* @return bool
*/
bool ini_table_check_entry(ini_table_s* table, const char* section_name,
const char* key);
/**
* @brief Retrieves the unmodified value of the specified `key' in `section_name'.
* Returns NULL if the entry does not exist, otherwise a pointer to the
* entry value data.
* @param table
* @param section_name
* @param key
* @return const char*
*/
const char* ini_table_get_entry(ini_table_s* table, const char* section_name,
const char* key);
/**
* @brief Retrieves the value of the specified `key' in `section_name', converted
* to int. Returns false on failure, otherwise true.
* @param table
* @param section_name
* @param key
* @param [out]value
* @return int
*/
bool ini_table_get_entry_as_int(ini_table_s* table, const char* section_name,
const char* key, int* value);
/**
* @brief Retrieves the value of the specified `key' in `section_name', converted
* to bool. Returns false on failure, true otherwise.
* @param table
* @param section_name
* @param key
* @param [out]value
* @return bool
*/
bool ini_table_get_entry_as_bool(ini_table_s* table, const char* section_name,
const char* key, bool* value);
#endif//_TCONFIG_H_
+51
View File
@@ -0,0 +1,51 @@
#pragma once
#include <sys/types.h>
#include <stdlib.h>
#include <utils/filesys.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <stdio.h>
#ifndef _MSC_VER
#include <pwd.h>
#include <unistd.h>
#else
#include <io.h>
#include <Shlobj.h>
#endif
#include "support.h"
#include "simple_strlib.h"
#include "error_info.h"
#define MAXSIZE 256
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file filesys.h
* @author Tim O'Neil
* @date 3/9/2018
*
* @brief System-specific & near system-specific utilities
*
* @section DESCRIPTION
*
* Collection of functions that will be more system specific
* and non-portable (mostly file systems utils and such).
*/
int find_cfgfile(const char*, char*, bool);
int create_cfgfile(const char*);
void get_userdir(char*);
int write_motd(char*, const char*);
int read_motd(const char*);
const char* get_keyvalue(const char*, const char*);
int set_keyvalue(const char*, const char*);
bool file_exists(const char*);
#ifdef __cplusplus
}
#endif
+84
View File
@@ -0,0 +1,84 @@
/* A minimal POSIX getopt() implementation in ANSI C
*
* This is free and unencumbered software released into the public domain.
*
* This implementation supports the convention of resetting the option
* parser by assigning optind to 0. This resets the internal state
* appropriately.
*
* Ref: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html
*/
#ifndef GETOPT_H
#define GETOPT_H
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int optind;
int opterr = 1;
int optopt;
char *optarg;
int
getopt(int argc, char * const argv[], const char *optstring)
{
static int optpos = 1;
const char *arg;
/* Reset? */
if (optind == 0) {
optind = !!argc;
optpos = 1;
}
arg = argv[optind];
if (arg && strcmp(arg, "--") == 0) {
optind++;
return -1;
} else if (!arg || arg[0] != '-' || !isalnum(arg[1])) {
return -1;
} else {
const char *opt = strchr(optstring, arg[optpos]);
optopt = arg[optpos];
if (!opt) {
if (opterr && *optstring != ':')
fprintf(stderr, "%s: illegal option: %c\n", argv[0], optopt);
if (!arg[++optpos]) {
optind++;
optpos = 1;
}
return '?';
} else if (opt[1] == ':') {
if (arg[optpos + 1]) {
optarg = (char *)arg + optpos + 1;
optind++;
optpos = 1;
return optopt;
} else if (argv[optind + 1]) {
optarg = (char *)argv[optind + 1];
optind += 2;
optpos = 1;
return optopt;
} else {
if (opterr && *optstring != ':')
fprintf(stderr,
"%s: option requires an argument: %c\n",
argv[0], optopt);
if (!arg[++optpos]) {
optind++;
optpos = 1;
}
return *optstring == ':' ? ':' : '?';
}
} else {
if (!arg[++optpos]) {
optind++;
optpos = 1;
}
return optopt;
}
}
}
#endif
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/**
* @file huff.h
* @author Tim O'Neil
* @date 3/9/2018
*
* @brief Probably pretty portable Huffman coder
*
* @section DESCRIPTION
*
* Huffman ecoder to compress large blobs of text and anything
* meant to be read only through an application UI. This file
* defines some necessary structs and such. See the implementation
* file for more details.
*/
typedef struct node
{
char c;
int freq;
struct node *link;
struct node *rlink;
struct node *llink;
} node_t;
typedef struct List
{
node_t *head;
} List_t;
typedef struct
{
unsigned char c : 8;
} code_generated;
typedef struct
{
int freq;
unsigned char ch;
} info;
void decode(const char*);
void encode(const char*, char*);
void insert_in_list(List_t*, node_t*);
void init_list(List_t *ptr);
void disp_list(const List_t*);
void make_node(List_t*, int, char);
void make_list(List_t*, int*);
void find_freq(char*, int*);
void make_tree(List_t*, int*);
void find_code(node_t*, char*, char codes[256][40]);
void compress(char*, FILE*, char codes[256][40], int, info*, int*, int num);
unsigned char convert_string_char(char string[8]);
int find_no_of_chars(int*);
void strre(char*, int);
node_t* decode_char(FILE*, node_t*, int, int, node_t*, int*, int);
int create_header(int*, int, info*);