#include #include #include #include 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; } }