diff options
| author | @syxhe <https://t.me/syxhe> | 2025-11-10 16:09:10 -0600 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2025-11-10 16:09:10 -0600 |
| commit | c8ab26e9f5aa398a208fcac3d8d11335f6c72632 (patch) | |
| tree | 2dc2c0f18e98b71c02991ea5511cdcb0039e346b /src | |
| parent | 0c541f74d346625618dc3ea8974bfb2cf042c000 (diff) | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/encryption.c | 67 | ||||
| -rw-r--r-- | src/shared.c | 11 | ||||
| -rw-r--r-- | src/threadpool.c | 34 |
3 files changed, 53 insertions, 59 deletions
diff --git a/src/encryption.c b/src/encryption.c index 2d48e4e..9b264dc 100644 --- a/src/encryption.c +++ b/src/encryption.c | |||
| @@ -138,6 +138,7 @@ CLEANUP_linkto: | |||
| 138 | * @param dst Destination to write encrypted file | 138 | * @param dst Destination to write encrypted file |
| 139 | * @param key Key for encryption | 139 | * @param key Key for encryption |
| 140 | * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error | 140 | * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error |
| 141 | * @todo Rewrite this into being one of my own functions instead of copying from libsodium | ||
| 141 | */ | 142 | */ |
| 142 | int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 143 | int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 143 | if(!src || !dst || !key) ERRRET(EINVAL, -1); | 144 | if(!src || !dst || !key) ERRRET(EINVAL, -1); |
| @@ -187,6 +188,7 @@ int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 187 | * @param dst Destination to write decrypted file | 188 | * @param dst Destination to write decrypted file |
| 188 | * @param key Key used to encrypt | 189 | * @param key Key used to encrypt |
| 189 | * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error | 190 | * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error |
| 191 | * @todo Rewrite this into being one of my own functions instead of copying from libsodium | ||
| 190 | */ | 192 | */ |
| 191 | int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 193 | int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 192 | if(!src || !dst || !key) ERRRET(EINVAL, -1); | 194 | if(!src || !dst || !key) ERRRET(EINVAL, -1); |
| @@ -250,42 +252,55 @@ int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 250 | * @param output | 252 | * @param output |
| 251 | * @param key | 253 | * @param key |
| 252 | * @retval (int)[,] | 254 | * @retval (int)[,] |
| 255 | * @todo Fill out warning messages & documentation | ||
| 253 | */ | 256 | */ |
| 254 | int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 257 | int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 255 | if(!target || !output || !key) ERRRET(EINVAL, -1); | 258 | if(!target || !output || !key) ERRRET(EINVAL, -1); |
| 256 | 259 | ||
| 257 | int fd = -1, tfd = -1, res = -1; | 260 | int fd = -1, tfd = -1, res = -1, eflag = 0; |
| 258 | FILE *src, *dst; | 261 | FILE *src, *dst; |
| 259 | char *targetdir; | 262 | char *targetdir; |
| 260 | 263 | ||
| 261 | // Open the target file | 264 | // Open the target file |
| 262 | if((fd = open(target, O_RDONLY)) < 0) return -1; | 265 | if((fd = open(target, O_RDONLY)) < 0) {eflag = 1; goto CLEANUP_encryptviatmp;} |
| 263 | 266 | ||
| 264 | // Create a temp file for writing | 267 | // Create a temp file for writing |
| 265 | targetdir = vxdirname(output); | 268 | targetdir = vxdirname(output); |
| 266 | if(!targetdir) goto CLEANUP_encryptviatmp; | 269 | if(!targetdir) {eflag = 2; goto CLEANUP_encryptviatmp;} |
| 267 | 270 | ||
| 268 | // Actually get the file descriptor for the temp file | 271 | // Actually get the file descriptor for the temp file |
| 269 | tfd = maketmp(targetdir); | 272 | tfd = maketmp(targetdir); |
| 270 | if(tfd < 0) goto CLEANUP_encryptviatmp; | 273 | if(tfd < 0) {eflag = 3; goto CLEANUP_encryptviatmp;} |
| 271 | 274 | ||
| 272 | // Create a FILE* version of the source fd | 275 | // Create a FILE* version of the source fd |
| 273 | if(!(src = fdopen(fd, "rb"))) goto CLEANUP_encryptviatmp; | 276 | if(!(src = fdopen(fd, "rb"))) {eflag = 4; goto CLEANUP_encryptviatmp;} |
| 274 | 277 | ||
| 275 | // Create a FILE* version of the target fd | 278 | // Create a FILE* version of the target fd |
| 276 | if(!(dst = fdopen(tfd, "wb"))) goto CLEANUP_encryptviatmp; | 279 | if(!(dst = fdopen(tfd, "wb"))) {eflag = 5; goto CLEANUP_encryptviatmp;} |
| 277 | 280 | ||
| 278 | // Do the encryption now that everything has been set up | 281 | // Do the encryption now that everything has been set up |
| 279 | if(encrypttofile(src, dst, key) < 0) // Not going to bother changing this, it probably is catastrophic if an error happens when it shouldn't | 282 | if(encrypttofile(src, dst, key) < 0) {eflag = 6; goto CLEANUP_encryptviatmp;} |
| 280 | ERROR(1, ENOTRECOVERABLE, "<encryptviatmp> I don't even have a way to cause an error here. How did you do it?",); | ||
| 281 | 283 | ||
| 282 | // Link the temp file into the system | 284 | // Link the temp file into the system |
| 283 | if(linkto(output, tfd) < 0) | 285 | if(linkto(output, tfd) < 0) {eflag = 7; goto CLEANUP_encryptviatmp;} |
| 284 | WARN(errno, "<encryptviatmp> Could not link \"%s\" into system after encryption", , output); | ||
| 285 | 286 | ||
| 286 | res = 0; | 287 | res = 0; |
| 287 | 288 | ||
| 288 | CLEANUP_encryptviatmp: | 289 | CLEANUP_encryptviatmp: |
| 290 | // TODO: Add warning messages for verbose errors | ||
| 291 | if(___VXGG___VERBOSE_ERRORS___) { | ||
| 292 | switch (eflag) { | ||
| 293 | case 1: WARN(errno, "<encryptviatmp> Warning: Could not open target fd \"%s\"",, target); | ||
| 294 | case 2: WARN(errno, "<encryptviatmp> Warning: Could not get real dirname for \"%s\"",, output); | ||
| 295 | case 3: WARN(errno, "<encryptviatmp> Warning: Could not make temp file in target dir \"%s\"",, targetdir); | ||
| 296 | case 4: WARN(errno, "<encryptviatmp> Warning: Could not get FILE* handle for source file \"%s\"",, target); | ||
| 297 | case 5: WARN(errno, "<encryptviatmp> Warning: Could not get FILE* handle for output file",); | ||
| 298 | case 6: ERROR(1, ENOTRECOVERABLE, "<encryptviatmp> ERROR: I don't even have a way to cause an error here. How did you do it?",); | ||
| 299 | case 7: WARN(errno, "<encryptviatmp> Warning: Could not link \"%s\" into system after encryption",, output); | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | |||
| 289 | free(targetdir); | 304 | free(targetdir); |
| 290 | fclose(src); | 305 | fclose(src); |
| 291 | fclose(dst); | 306 | fclose(dst); |
| @@ -302,6 +317,7 @@ CLEANUP_encryptviatmp: | |||
| 302 | * @param target | 317 | * @param target |
| 303 | * @param key | 318 | * @param key |
| 304 | * @retval (int)[,] | 319 | * @retval (int)[,] |
| 320 | * @todo Fill out documentation | ||
| 305 | */ | 321 | */ |
| 306 | int decryptto(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 322 | int decryptto(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 307 | if(!target || !output || !key) ERRRET(EINVAL, -1); | 323 | if(!target || !output || !key) ERRRET(EINVAL, -1); |
| @@ -333,12 +349,12 @@ CLEANUP_decryptto: | |||
| 333 | 349 | ||
| 334 | if(___VXGG___VERBOSE_ERRORS___) { | 350 | if(___VXGG___VERBOSE_ERRORS___) { |
| 335 | switch (eflag) { | 351 | switch (eflag) { |
| 336 | case 0: WARN(errno, "<decryptto> Could not open \"%s\" for decryption", , target); break; | 352 | case 0: WARN(errno, "<decryptto> Could not open \"%s\" for decryption",, target); break; |
| 337 | case 1: WARN(errno, "<decryptto> Could not get temp file for decryption", ); break; | 353 | case 1: WARN(errno, "<decryptto> Could not get temp file for decryption",); break; |
| 338 | case 2: WARN(errno, "<decryptto> Could not open \"%s\" for writing decrypted data", , output); break; | 354 | case 2: WARN(errno, "<decryptto> Could not open \"%s\" for writing decrypted data",, output); break; |
| 339 | case 3: ERROR(1, errno, "<decryptto> How did you even cause an error?",); break; | 355 | case 3: ERROR(1, errno, "<decryptto> How did you even cause an error?",); break; |
| 340 | case 4: WARN(errno, "<decryptto> Could not link \"%s\" into system", , output); break; | 356 | case 4: WARN(errno, "<decryptto> Could not link \"%s\" into system",, output); break; |
| 341 | default: WARN(errno, "<decryptto> Ran into an error", ); break; | 357 | default: WARN(errno, "<decryptto> Ran into an error",); break; |
| 342 | } | 358 | } |
| 343 | } | 359 | } |
| 344 | 360 | ||
| @@ -353,7 +369,6 @@ CLEANUP_decryptto: | |||
| 353 | * @retval (int)[-1, words] On success, returns the number of words requested. On error, returns -1 and sets errno | 369 | * @retval (int)[-1, words] On success, returns the number of words requested. On error, returns -1 and sets errno |
| 354 | */ | 370 | */ |
| 355 | int genpassword(char **str, unsigned int words) { | 371 | int genpassword(char **str, unsigned int words) { |
| 356 | // Early returns | ||
| 357 | if(words < 1) return 0; | 372 | if(words < 1) return 0; |
| 358 | if(!str) ERRRET(EINVAL, -1); | 373 | if(!str) ERRRET(EINVAL, -1); |
| 359 | 374 | ||
| @@ -378,24 +393,6 @@ int genpassword(char **str, unsigned int words) { | |||
| 378 | return words; | 393 | return words; |
| 379 | } | 394 | } |
| 380 | 395 | ||
| 381 | /** | ||
| 382 | * @brief sodium_malloc wrapper. | ||
| 383 | * | ||
| 384 | * Calls `error()` or `abort()` depnding on the value of `___VXGG___VXALLOC_EXIT_ON_ERROR___`. Will make sure libsodium is initialized if `___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0` | ||
| 385 | * | ||
| 386 | * @param size | ||
| 387 | * @retval (void*) A pointer to some data allocated via `sodium_malloc()` | ||
| 388 | */ | ||
| 389 | void* xsodium_malloc(size_t size) { | ||
| 390 | void *mem = sodium_malloc(size); | ||
| 391 | if(mem == NULL) | ||
| 392 | XALLOC_EXIT("<xsodium_malloc> could not allocate memory... Quitting", ); | ||
| 393 | |||
| 394 | return mem; | ||
| 395 | } | ||
| 396 | |||
| 397 | |||
| 398 | |||
| 399 | // TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task | 396 | // TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task |
| 400 | 397 | ||
| 401 | // #include <dirent.h> | 398 | // #include <dirent.h> |
diff --git a/src/shared.c b/src/shared.c index 2397bd6..b6d27e4 100644 --- a/src/shared.c +++ b/src/shared.c | |||
| @@ -28,13 +28,10 @@ | |||
| 28 | #define ___VXGG___VERBOSE_ERRORS___ 1 | 28 | #define ___VXGG___VERBOSE_ERRORS___ 1 |
| 29 | 29 | ||
| 30 | //! Macro to exit on an alloc error instead of doing the terrible nested if statement that was being used previously | 30 | //! Macro to exit on an alloc error instead of doing the terrible nested if statement that was being used previously |
| 31 | #define XALLOC_EXIT(msg, ...) do {\ | 31 | #define XALLOC_EXIT(msg, ...) do { \ |
| 32 | if(!___VXGG___VXALLOC_EXIT_ON_ERROR___)\ | 32 | if(___VXGG___VERBOSE_ERRORS___) error(EXIT_FAILURE, errno, (msg)__VA_ARGS__); \ |
| 33 | abort();\ | 33 | if(___VXGG___VXALLOC_EXIT_ON_ERROR___) exit(EXIT_FAILURE); \ |
| 34 | if(!___VXGG___VERBOSE_ERRORS___)\ | 34 | abort(); \ |
| 35 | exit(EXIT_FAILURE);\ | ||
| 36 | error(EXIT_FAILURE, errno, (msg)__VA_ARGS__);\ | ||
| 37 | exit(EXIT_FAILURE); /* Makes gcc happy */\ | ||
| 38 | } while (0) | 35 | } while (0) |
| 39 | 36 | ||
| 40 | //! Error macro that gcc will not complain about | 37 | //! Error macro that gcc will not complain about |
diff --git a/src/threadpool.c b/src/threadpool.c index 959c060..7a2f93a 100644 --- a/src/threadpool.c +++ b/src/threadpool.c | |||
| @@ -182,14 +182,15 @@ taskqueue * taskqueue_new(void) { | |||
| 182 | * @param tq A taskqueue to be freed. May be null | 182 | * @param tq A taskqueue to be freed. May be null |
| 183 | */ | 183 | */ |
| 184 | void taskqueue_free(void *tq) { | 184 | void taskqueue_free(void *tq) { |
| 185 | if(!tq) return; | 185 | taskqueue *real = tq; |
| 186 | if(!real) return; | ||
| 186 | 187 | ||
| 187 | for(tqnode *p = ((taskqueue*)tq)->start, *n; p != NULL;) { | 188 | for(tqnode *p = real->start, *n; p != NULL;) { |
| 188 | n = p->next; | 189 | n = p->next; |
| 189 | tqnode_free(p); | 190 | tqnode_free(p); |
| 190 | p = n; | 191 | p = n; |
| 191 | } | 192 | } |
| 192 | free(tq); | 193 | free(real); |
| 193 | 194 | ||
| 194 | return; | 195 | return; |
| 195 | } | 196 | } |
| @@ -221,7 +222,8 @@ int taskqueue_push(taskqueue *tq, task *tsk) { | |||
| 221 | int hf; | 222 | int hf; |
| 222 | if((hf = taskqueue_handlefirst(tq, tsk))) return (hf >= 0) ? 0 : -1; | 223 | if((hf = taskqueue_handlefirst(tq, tsk))) return (hf >= 0) ? 0 : -1; |
| 223 | 224 | ||
| 224 | tqnode *curstart = tq->start, *newstart = tqnode_new(tq->start, NULL, tsk); | 225 | tqnode *curstart = tq->start; |
| 226 | tqnode *newstart = tqnode_new(curstart, NULL, tsk); | ||
| 225 | if(!newstart) return -1; | 227 | if(!newstart) return -1; |
| 226 | 228 | ||
| 227 | curstart->prev = newstart; | 229 | curstart->prev = newstart; |
| @@ -241,18 +243,18 @@ task * taskqueue_pop(taskqueue *tq) { | |||
| 241 | if(!tq) ERRRET(EINVAL, NULL); | 243 | if(!tq) ERRRET(EINVAL, NULL); |
| 242 | if(tq->size <= 0) ERRRET(ENODATA, NULL); | 244 | if(tq->size <= 0) ERRRET(ENODATA, NULL); |
| 243 | 245 | ||
| 244 | tqnode *end = tq->end; | 246 | tqnode *curend = tq->end; |
| 245 | task *ret = end->task; | 247 | task *ret = curend->task; |
| 246 | 248 | ||
| 247 | if(tq->size == 1) { | 249 | if(tq->size == 1) { |
| 248 | tq->end = NULL; | 250 | tq->end = NULL; |
| 249 | tq->start = NULL; | 251 | tq->start = NULL; |
| 250 | } else { | 252 | } else { |
| 251 | tq->end = end->prev; | 253 | tq->end = curend->prev; |
| 252 | tq->end->next = NULL; | 254 | tq->end->next = NULL; |
| 253 | } | 255 | } |
| 254 | 256 | ||
| 255 | free(end); | 257 | free(curend); |
| 256 | tq->size--; | 258 | tq->size--; |
| 257 | return ret; | 259 | return ret; |
| 258 | } | 260 | } |
| @@ -270,7 +272,8 @@ int taskqueue_pushfront(taskqueue *tq, task *tsk) { | |||
| 270 | int hf; | 272 | int hf; |
| 271 | if((hf = taskqueue_handlefirst(tq, tsk))) return (hf >= 0) ? 0 : -1; | 273 | if((hf = taskqueue_handlefirst(tq, tsk))) return (hf >= 0) ? 0 : -1; |
| 272 | 274 | ||
| 273 | tqnode *end =tq->end, *newend = tqnode_new(NULL, tq->end, tsk); | 275 | tqnode *end = tq->end; |
| 276 | tqnode *newend = tqnode_new(NULL, end, tsk); | ||
| 274 | if(!newend) return -1; | 277 | if(!newend) return -1; |
| 275 | 278 | ||
| 276 | end->next = newend; | 279 | end->next = newend; |
| @@ -290,18 +293,18 @@ task * taskqueue_popback(taskqueue *tq) { | |||
| 290 | if(!tq) ERRRET(EINVAL, NULL); | 293 | if(!tq) ERRRET(EINVAL, NULL); |
| 291 | if(tq->size <= 0) ERRRET(ENODATA, NULL); | 294 | if(tq->size <= 0) ERRRET(ENODATA, NULL); |
| 292 | 295 | ||
| 293 | tqnode *start = tq->start; | 296 | tqnode *curstart = tq->start; |
| 294 | task *ret = start->task; | 297 | task *ret = curstart->task; |
| 295 | 298 | ||
| 296 | if(tq->size == 1) { | 299 | if(tq->size == 1) { |
| 297 | tq->start = NULL; | 300 | tq->start = NULL; |
| 298 | tq->end = NULL; | 301 | tq->end = NULL; |
| 299 | } else { | 302 | } else { |
| 300 | tq->start = start->next; | 303 | tq->start = curstart->next; |
| 301 | tq->start->prev = NULL; | 304 | tq->start->prev = NULL; |
| 302 | } | 305 | } |
| 303 | 306 | ||
| 304 | free(start); | 307 | free(curstart); |
| 305 | tq->size--; | 308 | tq->size--; |
| 306 | return ret; | 309 | return ret; |
| 307 | } | 310 | } |
| @@ -321,7 +324,6 @@ int taskqueue_size(taskqueue *tq) { | |||
| 321 | mtx_unlock(&(ctq)->mutex); \ | 324 | mtx_unlock(&(ctq)->mutex); \ |
| 322 | return (retval); \ | 325 | return (retval); \ |
| 323 | } \ | 326 | } \ |
| 324 | \ | ||
| 325 | code \ | 327 | code \ |
| 326 | mtx_unlock(&(ctq)->mutex); \ | 328 | mtx_unlock(&(ctq)->mutex); \ |
| 327 | } while (0) | 329 | } while (0) |
| @@ -413,8 +415,6 @@ void ctqueue_free(void *ctq) { | |||
| 413 | free(real->thrdarr); | 415 | free(real->thrdarr); |
| 414 | free(real); | 416 | free(real); |
| 415 | 417 | ||
| 416 | // TODO: figure out if it's necessary / a good idea to do error handling on these functions | ||
| 417 | |||
| 418 | return; | 418 | return; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| @@ -424,7 +424,7 @@ void ctqueue_free(void *ctq) { | |||
| 424 | * | 424 | * |
| 425 | * @param ctq The concurrent taskqueue to modify. Must be non-null | 425 | * @param ctq The concurrent taskqueue to modify. Must be non-null |
| 426 | * @param tsk The task to push. Must be non-null | 426 | * @param tsk The task to push. Must be non-null |
| 427 | * @retval (int) Returns `thrd_success` on success, returns `thrd_error` or `thrd_nomem` on error | 427 | * @retval (int)[`thrd_error` | `thrd_nomem`, `thrd_success`] |
| 428 | */ | 428 | */ |
| 429 | int ctqueue_waitpush(ctqueue *ctq, task *tsk) { | 429 | int ctqueue_waitpush(ctqueue *ctq, task *tsk) { |
| 430 | if(!ctq || !tsk) ERRRET(EINVAL, -1); | 430 | if(!ctq || !tsk) ERRRET(EINVAL, -1); |
