mirror of
https://gitlab.com/niansa/simpsh-httpd.git
synced 2025-03-06 20:53:36 +01:00
167 lines
4.2 KiB
C
167 lines
4.2 KiB
C
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/mman.h>
|
|
|
|
struct databuffer {
|
|
size_t len;
|
|
char *data;
|
|
};
|
|
|
|
void db_init(struct databuffer *db) { // Initialises the db
|
|
db->len = 0;
|
|
db->data = malloc(1);
|
|
db->data[0] = 0x00;
|
|
}
|
|
|
|
void db_deinit(struct databuffer *db) { // Deinitialises the db (TODO)
|
|
//free(db->data);
|
|
}
|
|
|
|
const char *db_raw(struct databuffer *db) { // Append temporary null-terminator and returns data
|
|
db->data = realloc(db->data, db->len + 1);
|
|
db->data[db->len] = 0x00;
|
|
return db->data;
|
|
}
|
|
|
|
void db_clear(struct databuffer *db) { // Reinitialises ("clears") the db
|
|
db_deinit(db);
|
|
db_init(db);
|
|
}
|
|
|
|
void db_append(struct databuffer *db, const struct databuffer *db_src) { // Appends db_src to db
|
|
if (db_src->len == 0) {
|
|
return;
|
|
}
|
|
db->len += db_src->len;
|
|
db->data = realloc(db->data, db->len);
|
|
memcpy(db->data + db->len - db_src->len, db_src->data, db_src->len);
|
|
}
|
|
|
|
void db_set(struct databuffer *db, const struct databuffer *db_src) { // Resets db to db_src
|
|
db_clear(db);
|
|
db_append(db, db_src);
|
|
}
|
|
|
|
const struct databuffer sized_db(const char *buffer, size_t len) { // Generates sized-size uninitialised (!!!) db
|
|
struct databuffer thisdb;
|
|
thisdb.data = buffer;
|
|
thisdb.len = len;
|
|
return thisdb;
|
|
}
|
|
|
|
const struct databuffer auto_db(const char *buffer) { // Same as above but autodetects size
|
|
return sized_db(buffer, strlen(buffer));
|
|
}
|
|
|
|
bool db_compare(const struct databuffer *db1, const struct databuffer *db2) { // Compares two dbs
|
|
if (db1->len != db2->len) {
|
|
return true;
|
|
} else {
|
|
for (size_t it = 0; it != db1->len; it++) {
|
|
if (db1->data[it] != db2->data[it]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
ssize_t db_find(const struct databuffer *db, const struct databuffer *db_src) { // Finds db_src in db, returns position or -1
|
|
if (db->len < db_src->len) {
|
|
return -1;
|
|
}
|
|
struct databuffer thisdb;
|
|
thisdb.len = db_src->len;
|
|
for (char *byte = db->data; byte != db->data + db->len - db_src->len + 1; byte++) {
|
|
thisdb.data = byte;
|
|
if (db_compare(&thisdb, db_src)) {
|
|
return byte - db->data;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool db_contains(const struct databuffer *db, const struct databuffer *db_src) { // Checks if db contains db_src
|
|
return db_find(db, db_src) != -1;
|
|
}
|
|
bool db_startswith(const struct databuffer *db, const struct databuffer *db_src) { // Checks if db starts with db_src
|
|
return db_find(db, db_src) == 0;
|
|
}
|
|
bool db_endswith(const struct databuffer *db, const struct databuffer *db_src) { // Checks if db ends with db_src
|
|
if (db->len < db_src->len) {
|
|
return false;
|
|
}
|
|
struct databuffer db_aligned;
|
|
db_aligned = sized_db(db->data + db->len - db_src->len, db_src->len);
|
|
return db_compare(&db_aligned, db_src);
|
|
}
|
|
|
|
bool db_fcheck(FILE *stream) {
|
|
if (stream == NULL) {
|
|
perror("Couldn't handle file");
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void db_fwrite(const struct databuffer *db, FILE *output) { // writes data from db to output
|
|
db_fcheck(output);
|
|
fwrite(db->data, db->len, 1, output);
|
|
}
|
|
|
|
void db_fread(struct databuffer *db, FILE *input) { // Reads data from input to db
|
|
size_t readbytes;
|
|
struct databuffer readdb;
|
|
char outb[16];
|
|
db_fcheck(input);
|
|
while (feof(input) == 0) {
|
|
readbytes = fread(outb, 1, sizeof(outb), input);
|
|
readdb = sized_db(outb, readbytes);
|
|
db_append(db, &readdb);
|
|
}
|
|
}
|
|
|
|
|
|
void db_readline(struct databuffer *db, FILE *input) { // Appends one line from input to db
|
|
struct databuffer thisdb;
|
|
char *buffer = NULL;
|
|
ssize_t size = 0;
|
|
db_fcheck(input);
|
|
size = getline(&buffer, &size, input);
|
|
assert(size != -1);
|
|
thisdb = sized_db(buffer, size);
|
|
db_append(db, &thisdb);
|
|
}
|
|
|
|
int runcmd(const char **command, bool wait_exit) { // Dumbly runs command
|
|
fflush(stdout);
|
|
if (fork() == 0) {
|
|
execvp(command[0], command);
|
|
perror(command[0]);
|
|
}
|
|
if (wait_exit) {
|
|
int status;
|
|
wait(&status);
|
|
return status;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void db_cmdread(struct databuffer *db, const char **command) { // Appends output (stdout) of command to db
|
|
struct databuffer thisdb;
|
|
int stdout_backup = dup(1);
|
|
dup2(memfd_create("pipe", 0), 1);
|
|
runcmd(command, true);
|
|
FILE *proc_out = fdopen(1, "r");
|
|
fseek(proc_out, 0, SEEK_SET);
|
|
db_fread(db, proc_out);
|
|
close(1);
|
|
dup2(stdout_backup, 1);
|
|
thisdb = auto_db("\n");
|
|
if (db_endswith(db, &thisdb)) {
|
|
db->data[db->len - 1] = 0x00;
|
|
}
|
|
}
|