1#include "removefile.h" 2#include "removefile_priv.h" 3 4#include <TargetConditionals.h> 5 6removefile_state_t 7removefile_state_alloc() { 8 removefile_state_t state = (removefile_state_t)calloc(1, sizeof(struct _removefile_state)); 9 if (state != NULL) 10 state->urand_file = -1; 11 return state; 12} 13 14int 15removefile_state_free(removefile_state_t state) { 16 if (state != NULL) { 17 if (state->urand_file != -1) { 18 close(state->urand_file); 19 state->urand_file = -1; 20 } 21 if (state->buffer != NULL) { 22 free(state->buffer); 23 state->buffer = NULL; 24 } 25 free(state); 26 } 27 return 0; 28} 29 30int 31removefile_state_get(removefile_state_t state, uint32_t key, void* dst) { 32 switch(key) { 33 case REMOVEFILE_STATE_CONFIRM_CALLBACK: 34 *(removefile_callback_t*)dst = state->confirm_callback; 35 break; 36 case REMOVEFILE_STATE_CONFIRM_CONTEXT: 37 *(void**)dst = state->confirm_context; 38 break; 39 case REMOVEFILE_STATE_ERROR_CALLBACK: 40 *(removefile_callback_t*)dst = state->error_callback; 41 break; 42 case REMOVEFILE_STATE_ERROR_CONTEXT: 43 *(void**)dst = state->error_context; 44 break; 45 case REMOVEFILE_STATE_ERRNO: 46 *(int*)dst = state->error_num; 47 break; 48 case REMOVEFILE_STATE_STATUS_CALLBACK: 49 *(removefile_callback_t*)dst = state->status_callback; 50 break; 51 case REMOVEFILE_STATE_STATUS_CONTEXT: 52 *(void**)dst = state->status_context; 53 break; 54 default: 55 errno = EINVAL; 56 return -1; 57 } 58 return 0; 59} 60 61int 62removefile_state_set(removefile_state_t state, uint32_t key, const void* value) { 63 switch(key) { 64 case REMOVEFILE_STATE_CONFIRM_CALLBACK: 65 state->confirm_callback = value; 66 break; 67 case REMOVEFILE_STATE_CONFIRM_CONTEXT: 68 state->confirm_context = (void *) value; 69 break; 70 case REMOVEFILE_STATE_ERROR_CALLBACK: 71 state->error_callback = value; 72 break; 73 case REMOVEFILE_STATE_ERROR_CONTEXT: 74 state->error_context = (void *) value; 75 break; 76 case REMOVEFILE_STATE_ERRNO: 77 state->error_num = *(int*)value; 78 break; 79 case REMOVEFILE_STATE_STATUS_CALLBACK: 80 state->status_callback = value; 81 break; 82 case REMOVEFILE_STATE_STATUS_CONTEXT: 83 state->status_context = (void *) value; 84 break; 85 default: 86 errno = EINVAL; 87 return -1; 88 } 89 return 0; 90} 91 92int 93removefile(const char* path, removefile_state_t state_param, removefile_flags_t flags) { 94 int res = 0; 95 char* paths[] = { NULL, NULL }; 96 removefile_state_t state = state_param; 97 98 // allocate the state if it was not passed in 99 if (state_param == NULL) { 100 state = removefile_state_alloc(); 101 if (state == NULL) { 102 errno = ENOMEM; 103 return -1; 104 } 105 } 106 state->cancelled = 0; 107 state->unlink_flags = flags; 108 109 if (flags & (REMOVEFILE_SECURE_7_PASS | REMOVEFILE_SECURE_35_PASS | REMOVEFILE_SECURE_1_PASS | REMOVEFILE_SECURE_3_PASS)) { 110 __removefile_init_random(getpid(), state); 111 } 112 113 paths[0] = strdup(path); 114 if (paths[0]) { 115 res = __removefile_tree_walker(paths, state); 116 free(paths[0]); 117 } else { 118 errno = ENOMEM; 119 res = -1; 120 } 121 122 // deallocate if allocated locally 123 if (state_param == NULL) { 124 removefile_state_free(state); 125 } 126 127 return res; 128} 129 130int 131removefile_cancel(removefile_state_t state) { 132 if (state == NULL) { 133 errno = EINVAL; 134 return -1; 135 } else { 136 state->cancelled = 1; 137 return 0; 138 } 139} 140