this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #1313 from darlinghq/add_removefile_submodule

Add removefile submodule

authored by

CuriousTommy and committed by
GitHub
0dfc8388 d50f6bee

+7 -2836
+3
.gitmodules
··· 441 441 [submodule "src/external/netcat"] 442 442 path = src/external/netcat 443 443 url = ../darling-netcat.git 444 + [submodule "src/external/removefile"] 445 + path = src/external/removefile 446 + url = ../darling-removefile.git
+1 -1
Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/checkint.h
··· 1 - ../../../../../../../../src/libremovefile/checkint.h 1 + ../../../../../../../../src/external/removefile/darling/include/checkint.h
+1 -1
Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/removefile.h
··· 1 - ../../../../../../../../src/libremovefile/removefile.h 1 + ../../../../../../../../src/external/removefile/darling/include/removefile.h
+1 -1
cmake/use_ld64.cmake
··· 20 20 -Wl,-dylib_file,/usr/lib/system/liblaunch.dylib:${CMAKE_BINARY_DIR}/src/launchd/liblaunch/liblaunch_firstpass.dylib \ 21 21 -Wl,-dylib_file,/usr/lib/system/libkeymgr.dylib:${CMAKE_BINARY_DIR}/src/external/keymgr/libkeymgr_firstpass.dylib \ 22 22 -Wl,-dylib_file,/usr/lib/system/libquarantine.dylib:${CMAKE_BINARY_DIR}/src/quarantine/libquarantine.dylib \ 23 - -Wl,-dylib_file,/usr/lib/system/libremovefile.dylib:${CMAKE_BINARY_DIR}/src/libremovefile/libremovefile.dylib \ 23 + -Wl,-dylib_file,/usr/lib/system/libremovefile.dylib:${CMAKE_BINARY_DIR}/src/external/removefile/libremovefile.dylib \ 24 24 -Wl,-dylib_file,/usr/lib/system/libcopyfile.dylib:${CMAKE_BINARY_DIR}/src/external/copyfile/libcopyfile.dylib \ 25 25 -Wl,-dylib_file,/usr/lib/system/libsystem_coreservices.dylib:${CMAKE_BINARY_DIR}/src/libsystem_coreservices/libsystem_coreservices.dylib \ 26 26 -Wl,-dylib_file,/usr/lib/system/libsystem_notify.dylib:${CMAKE_BINARY_DIR}/src/external/libnotify/libsystem_notify_firstpass.dylib \
+1 -1
src/CMakeLists.txt
··· 148 148 add_subdirectory(libsystem_coreservices) 149 149 add_subdirectory(external/libutil) 150 150 add_subdirectory(external/libnotify) 151 - add_subdirectory(libremovefile) 151 + add_subdirectory(external/removefile) 152 152 add_subdirectory(launchd) 153 153 add_subdirectory(external/keymgr) 154 154 add_subdirectory(libcache)
-26
src/libremovefile/CMakeLists.txt
··· 1 - project(libremovefile) 2 - 3 - cmake_minimum_required(VERSION 3.10) 4 - 5 - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 6 - 7 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks") 8 - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib") 9 - 10 - add_definitions(-w -nostdinc) 11 - 12 - set(removefile_sources 13 - removefile.c 14 - removefile_random.c 15 - removefile_rename_unlink.c 16 - removefile_sunlink.c 17 - removefile_tree_walker.c 18 - ) 19 - 20 - set(DYLIB_INSTALL_NAME "/usr/lib/system/libremovefile.dylib") 21 - add_darling_library(removefile SHARED ${removefile_sources}) 22 - target_link_libraries(removefile system_c system_kernel system_dyld system_malloc compiler_rt) 23 - make_fat(removefile) 24 - 25 - install(TARGETS removefile DESTINATION libexec/darling/usr/lib/system) 26 -
-26
src/libremovefile/LICENSE
··· 1 - Terms and Conditions 2 - 3 - Copyright � 2000 Matthew D. Gauthier 4 - 5 - Permission is hereby granted, free of charge, to any person obtaining 6 - a copy of this software and associated documentation files (the 7 - "Software"), to deal in the Software without restriction, including 8 - without limitation the rights to use, copy, modify, merge, publish, 9 - distribute, sublicense, and/or sell copies of the Software, and to 10 - permit persons to whom the Software is furnished to do so, subject to 11 - the following conditions: 12 - 13 - The above copyright notice and this permission notice shall be 14 - included in all copies or substantial portions of the Software. 15 - 16 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 - IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 - OTHER DEALINGS IN THE SOFTWARE. 23 - 24 - Except as contained in this notice, the name of the contributors shall 25 - not be used in advertising or otherwise to promote the sale, use or 26 - other dealings in this Software without prior written authorization.
-204
src/libremovefile/checkint.3
··· 1 - .Dd April 20, 2007 2 - .Dt CHECK_INT32_ADD 3 3 - .Os 4 - .Sh NAME 5 - .Nm check_int32_add , 6 - .Nm check_uint32_add , 7 - .Nm check_int64_add , 8 - .Nm check_uint64_add , 9 - .Nm check_int32_sub , 10 - .Nm check_uint32_sub , 11 - .Nm check_int64_sub , 12 - .Nm check_uint64_sub , 13 - .Nm check_int32_mul , 14 - .Nm check_uint32_mul , 15 - .Nm check_int64_mul , 16 - .Nm check_uint64_mul , 17 - .Nm check_int32_div , 18 - .Nm check_uint32_div , 19 - .Nm check_int64_div , 20 - .Nm check_uint64_div , 21 - .Nd detect overflow in arithmetic 22 - .Sh SYNOPSIS 23 - .In checkint.h 24 - .Ft int32_t 25 - .Fo check_int32_add 26 - .Fa "int x" 27 - .Fa "int y" 28 - .Fa "int *err" 29 - .Fc 30 - .Ft uint32_t 31 - .Fo check_uint32_add 32 - .Fa "int x" 33 - .Fa "int y" 34 - .Fa "int *err" 35 - .Fc 36 - .Ft int64_t 37 - .Fo check_int64_add 38 - .Fa "int x" 39 - .Fa "int y" 40 - .Fa "int *err" 41 - .Fc 42 - .Ft uint64_t 43 - .Fo check_uint64_add 44 - .Fa "int x" 45 - .Fa "int y" 46 - .Fa "int *err" 47 - .Fc 48 - .Ft int32_t 49 - .Fo check_int32_sub 50 - .Fa "int x" 51 - .Fa "int y" 52 - .Fa "int *err" 53 - .Fc 54 - .Ft uint32_t 55 - .Fo check_uint32_sub 56 - .Fa "int x" 57 - .Fa "int y" 58 - .Fa "int *err" 59 - .Fc 60 - .Ft int64_t 61 - .Fo check_int64_sub 62 - .Fa "int x" 63 - .Fa "int y" 64 - .Fa "int *err" 65 - .Fc 66 - .Ft uint64_t 67 - .Fo check_uint64_sub 68 - .Fa "int x" 69 - .Fa "int y" 70 - .Fa "int *err" 71 - .Fc 72 - .Ft int32_t 73 - .Fo check_int32_mul 74 - .Fa "int x" 75 - .Fa "int y" 76 - .Fa "int *err" 77 - .Fc 78 - .Ft uint32_t 79 - .Fo check_uint32_mul 80 - .Fa "int x" 81 - .Fa "int y" 82 - .Fa "int *err" 83 - .Fc 84 - .Ft int64_t 85 - .Fo check_int64_mul 86 - .Fa "int x" 87 - .Fa "int y" 88 - .Fa "int *err" 89 - .Fc 90 - .Ft uint64_t 91 - .Fo check_uint64_mul 92 - .Fa "int x" 93 - .Fa "int y" 94 - .Fa "int *err" 95 - .Fc 96 - .Ft int32_t 97 - .Fo check_int32_div 98 - .Fa "int x" 99 - .Fa "int y" 100 - .Fa "int *err" 101 - .Fc 102 - .Ft uint32_t 103 - .Fo check_uint32_div 104 - .Fa "int x" 105 - .Fa "int y" 106 - .Fa "int *err" 107 - .Fc 108 - .Ft int64_t 109 - .Fo check_int64_div 110 - .Fa "int x" 111 - .Fa "int y" 112 - .Fa "int *err" 113 - .Fc 114 - .Ft uint64_t 115 - .Fo check_uint64_div 116 - .Fa "int x" 117 - .Fa "int y" 118 - .Fa "int *err" 119 - .Fc 120 - .Sh DESCRIPTION 121 - The 122 - .Fn check_<type>_<operation> "x" "y" "err" 123 - family of functions perform the specified arithmetic operation (addition, subtraction, 124 - multiplication, or division) with the left operand of 125 - .Fa x 126 - and right operand of 127 - .Fa y 128 - and return the arithmetic result with the specified type. 129 - .Pp 130 - Either operand 131 - .Fa x 132 - or 133 - .Fa y 134 - (or both) can be of any type that is compatible to signed or unsigned 135 - 8-bit, 16-bit, 32-bit, or 64-bit integers. 136 - .Pp 137 - The 138 - .Fa err 139 - argument is 140 - .Em or Ns 'ed 141 - by flags in the function to indicate if an overflow has occurred. 142 - The possible flag values are: 143 - .Pp 144 - .Bd -literal -offset indent -compact 145 - CHECKINT_NO_ERROR no overflow has occurred 146 - CHECKINT_OVERFLOW_ERROR overflow has occurred 147 - CHECKINT_TYPE_ERROR operand is of an incompatible type 148 - .Ed 149 - .Pp 150 - The 151 - .Fa err 152 - argument is not cleared in calls to the 153 - .Fn check_<type>_<operation> "x" "y" "err" 154 - functions. Detected overflow persists in the 155 - .Fa err 156 - argument until 157 - .Fa err 158 - is reset to CHECKINT_NO_ERROR. 159 - .Sh RETURN VALUES 160 - If successful, the 161 - .Fn check_<type>_<operation> 162 - functions will return the arithmetic result of performing the operation with left operand 163 - .Fa x 164 - and right operand 165 - .Fa y 166 - (even when overflow error occurs). 167 - .Pp 168 - If any other error occurs, the return value is -1 169 - and the argument 170 - .Fa err 171 - will be set to indicate the error. 172 - .Sh EXAMPLES 173 - .Bd -literal -offset indent 174 - /* Create a variable to store overflow flag */ 175 - int32_t err = CHECKINT_NO_ERROR; 176 - /* Use checkint API to perform an arithmetic operation and 177 - * store result in variable. */ 178 - int32_t arithmetic_result = check_int32_add(UINT_MAX, 1, &err); 179 - /* Check status of overflow flag */ 180 - if (err & CHECKINT_OVERFLOW_ERROR) { 181 - /* Perform overflow resolution code */ 182 - fprintf(stderr, "Overflow detected!\\n"); 183 - } 184 - /* Check for type error */ 185 - else if (err & CHECKINT_TYPE_ERROR) { 186 - /* Deal with incompatible types error */ 187 - fprintf(stderr, "Incompatible types!\\n"); 188 - } 189 - /* Reset overflow flag for next operation */ 190 - err = CHECKINT_NO_ERROR; 191 - 192 - .Ed 193 - .Sh ERRORS 194 - The 195 - .Fn check_<type>_<operation> 196 - functions may fail if: 197 - .Pp 198 - .Bd -literal -offset indent -compact 199 - [CHECKINT_TYPE_ERROR] operand is of an incompatible type 200 - .Ed 201 - .Sh HISTORY 202 - The 203 - .Fn checkint 204 - API was introduced in Mac OS X 10.5.
-565
src/libremovefile/checkint.h
··· 1 - /* 2 - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. 3 - */ 4 - 5 - #ifndef __CHECKINT_H__ 6 - #define __CHECKINT_H__ 7 - 8 - /* ObjC++ Guard */ 9 - #if defined(__OBJC__) && defined(__cplusplus) 10 - #error "checkint.h does not support Objective C++" 11 - #elif defined(__cplusplus) 12 - #error "checkint.h does not support C++" 13 - #endif 14 - 15 - #include <stdint.h> 16 - #include <limits.h> 17 - 18 - __BEGIN_DECLS 19 - 20 - enum { 21 - CHECKINT_NO_ERROR = 0, 22 - CHECKINT_OVERFLOW_ERROR = (1 << 0), 23 - CHECKINT_TYPE_ERROR = (1 << 1) 24 - }; 25 - 26 - #define check_int32_add(x, y, err) __checkint_int32_add(x,y,err) 27 - #define check_uint32_add(x, y, err) __checkint_uint32_add(x,y,err) 28 - #define check_int64_add(x, y, err) __checkint_int64_add(x,y,err) 29 - #define check_uint64_add(x, y, err) __checkint_uint64_add(x,y,err) 30 - 31 - #define check_int32_sub(x, y, err) __checkint_int32_sub(x,y,err) 32 - #define check_uint32_sub(x, y, err) __checkint_uint32_sub(x,y,err) 33 - #define check_int64_sub(x, y, err) __checkint_int64_sub(x,y,err) 34 - #define check_uint64_sub(x, y, err) __checkint_uint64_sub(x,y,err) 35 - 36 - #define check_int32_mul(x, y, err) __checkint_int32_mul(x,y,err) 37 - #define check_uint32_mul(x, y, err) __checkint_uint32_mul(x,y,err) 38 - #define check_int64_mul(x, y, err) __checkint_int64_mul(x,y,err) 39 - #define check_uint64_mul(x, y, err) __checkint_uint64_mul(x,y,err) 40 - 41 - #define check_int32_div(x, y, err) __checkint_int32_div(x,y,err) 42 - #define check_uint32_div(x, y, err) __checkint_uint32_div(x,y,err) 43 - #define check_int64_div(x, y, err) __checkint_int64_div(x,y,err) 44 - #define check_uint64_div(x, y, err) __checkint_uint64_div(x,y,err) 45 - 46 - /*** 47 - * Private Interfaces 48 - * 49 - * Please do not directly use any interfaces below this point. They are 50 - * considered an implementation detail of the above, supported, interfaces 51 - * and are subject to change at any time without warning. 52 - ***/ 53 - 54 - #define __CHECKINT_INLINE static inline __attribute__((always_inline)) 55 - #define __CHECKINT_UNLIKELY(X) __builtin_expect((X),0) 56 - 57 - __CHECKINT_INLINE int32_t 58 - __checkint_is_mixed_sign32(int32_t x, int32_t y) {return ((x ^ y) < 0);} 59 - 60 - __CHECKINT_INLINE int32_t 61 - __checkint_is_mixed_sign64(int64_t x, int64_t y) {return ((x ^ y) < 0);} 62 - 63 - __CHECKINT_INLINE int32_t 64 - __checkint_int32_type_error(int32_t* err) {*err |= CHECKINT_TYPE_ERROR; return -1;} 65 - 66 - __CHECKINT_INLINE int32_t 67 - __checkint_uint32_type_error(int32_t* err) {*err |= CHECKINT_TYPE_ERROR; return -1;} 68 - 69 - __CHECKINT_INLINE int32_t 70 - __checkint_int64_type_error(int32_t* err) {*err |= CHECKINT_TYPE_ERROR; return -1;} 71 - 72 - __CHECKINT_INLINE int32_t 73 - __checkint_uint64_type_error(int32_t* err) {*err |= CHECKINT_TYPE_ERROR; return -1;} 74 - 75 - __CHECKINT_INLINE int32_t 76 - __checkint_int32_add(int64_t x, int64_t y, int32_t* err) { 77 - int64_t z = x + y; 78 - if (__CHECKINT_UNLIKELY(x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX)) { 79 - *err |= CHECKINT_OVERFLOW_ERROR; 80 - } 81 - if (z > INT32_MAX || z < INT32_MIN) *err |= CHECKINT_OVERFLOW_ERROR; 82 - return (int32_t)z; 83 - } 84 - 85 - __CHECKINT_INLINE uint32_t 86 - __checkint_uint32_add(int64_t x, int64_t y, int32_t* err) { 87 - int64_t z = x + y; 88 - if (__CHECKINT_UNLIKELY((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull))) *err |= CHECKINT_OVERFLOW_ERROR; 89 - if (__CHECKINT_UNLIKELY(z > UINT_MAX || z < 0)) *err |= CHECKINT_OVERFLOW_ERROR; 90 - return (uint32_t)z; 91 - } 92 - 93 - __CHECKINT_INLINE int64_t 94 - __checkint_int64_add_signed_signed(int64_t x, int64_t y, int32_t* err) { 95 - /* Mixed-sign additions cannot overflow */ 96 - if (__checkint_is_mixed_sign64(x,y)) { 97 - /* else, both arguments negative */ 98 - } else if (y < 0) { 99 - if (__CHECKINT_UNLIKELY(x < LLONG_MIN - y)) *err |= CHECKINT_OVERFLOW_ERROR; 100 - /* else, both arguments positive */ 101 - } else { 102 - if (__CHECKINT_UNLIKELY(LLONG_MAX - x < y)) *err |= CHECKINT_OVERFLOW_ERROR; 103 - } 104 - return x + y; 105 - } 106 - 107 - __CHECKINT_INLINE int64_t 108 - __checkint_int64_add_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 109 - if(__CHECKINT_UNLIKELY(((int64_t)(LLONG_MAX - y)) < x)) 110 - *err = *err | CHECKINT_OVERFLOW_ERROR; 111 - return x + y; 112 - } 113 - 114 - __CHECKINT_INLINE int64_t 115 - __checkint_int64_add_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 116 - return __checkint_int64_add_signed_unsigned(y, x, err); 117 - } 118 - 119 - __CHECKINT_INLINE int64_t 120 - __checkint_int64_add_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 121 - int64_t diff = LLONG_MAX - y; 122 - if(__CHECKINT_UNLIKELY(diff < 0 || ((uint64_t) diff) < x)) 123 - *err = *err | CHECKINT_OVERFLOW_ERROR; 124 - return x + y; 125 - } 126 - 127 - __CHECKINT_INLINE uint64_t 128 - __checkint_uint64_add_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 129 - if(__CHECKINT_UNLIKELY((ULLONG_MAX - y) < x)) 130 - *err = *err | CHECKINT_OVERFLOW_ERROR; 131 - return x + y; 132 - } 133 - 134 - __CHECKINT_INLINE uint64_t 135 - __checkint_uint64_add_signed_signed(int64_t x, int64_t y, int32_t* err) { 136 - if(__CHECKINT_UNLIKELY(((x < 0 && y >= 0) || (x >= 0 && y < 0)) && (x + y) < 0)) 137 - *err = *err | CHECKINT_OVERFLOW_ERROR; 138 - else if(__CHECKINT_UNLIKELY(x < 0 && y < 0)) 139 - *err = *err | CHECKINT_OVERFLOW_ERROR; 140 - return x + y; 141 - } 142 - 143 - __CHECKINT_INLINE uint64_t 144 - __checkint_uint64_add_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 145 - if(x > 0) 146 - return __checkint_uint64_add_unsigned_unsigned(x, y, err); 147 - if(__CHECKINT_UNLIKELY((y < ((uint64_t)LLONG_MAX + 1)) && (((int64_t) (x + y)) < 0))) 148 - *err = *err | CHECKINT_OVERFLOW_ERROR; 149 - return x + y; 150 - } 151 - 152 - __CHECKINT_INLINE uint64_t 153 - __checkint_uint64_add_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 154 - return __checkint_uint64_add_signed_unsigned(y, x, err); 155 - } 156 - 157 - __CHECKINT_INLINE int32_t 158 - __checkint_int32_sub(int64_t x, int64_t y, int32_t* err) { 159 - if (__CHECKINT_UNLIKELY(x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX)) { 160 - *err |= CHECKINT_OVERFLOW_ERROR; 161 - } 162 - int64_t z = x - y; 163 - if (__CHECKINT_UNLIKELY(z > INT_MAX || z < INT_MIN)) *err |= CHECKINT_OVERFLOW_ERROR; 164 - return (int32_t)z; 165 - } 166 - 167 - __CHECKINT_INLINE uint32_t 168 - __checkint_uint32_sub(int64_t x, int64_t y, int32_t* err) { 169 - int64_t z = x - y; 170 - if (__CHECKINT_UNLIKELY((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull))) *err |= CHECKINT_OVERFLOW_ERROR; 171 - if (__CHECKINT_UNLIKELY(z > UINT_MAX || z < 0)) *err |= CHECKINT_OVERFLOW_ERROR; 172 - return (uint32_t)z; 173 - } 174 - 175 - __CHECKINT_INLINE int64_t 176 - __checkint_int64_sub_signed_signed(int64_t x, int64_t y, int32_t* err) { 177 - if(__checkint_is_mixed_sign64(x, y)) 178 - { 179 - /* Positive x subtract a negative y */ 180 - if(x >= 0) 181 - { 182 - if(__CHECKINT_UNLIKELY(x > LLONG_MAX + y)) 183 - *err = *err | CHECKINT_OVERFLOW_ERROR; 184 - } 185 - /* Negative x subtract a positive y */ 186 - else 187 - { 188 - if(__CHECKINT_UNLIKELY(x < LLONG_MIN + y)) 189 - *err = *err | CHECKINT_OVERFLOW_ERROR; 190 - } 191 - } 192 - /* Both negative, or both positive, no possible overflow */ 193 - return x - y; 194 - } 195 - 196 - __CHECKINT_INLINE int64_t 197 - __checkint_int64_sub_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 198 - if(__CHECKINT_UNLIKELY(x < ((int64_t)(LLONG_MIN + y)))) 199 - *err = *err | CHECKINT_OVERFLOW_ERROR; 200 - return x - y; 201 - } 202 - 203 - __CHECKINT_INLINE int64_t 204 - __checkint_int64_sub_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 205 - if(__CHECKINT_UNLIKELY(x > ((uint64_t)(LLONG_MAX + y)) || y == LLONG_MIN)) 206 - *err = *err | CHECKINT_OVERFLOW_ERROR; 207 - return x - y; 208 - } 209 - 210 - __CHECKINT_INLINE int64_t 211 - __checkint_int64_sub_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 212 - if(__CHECKINT_UNLIKELY(x > y && ((x - y) > LLONG_MAX))) 213 - *err = *err | CHECKINT_OVERFLOW_ERROR; 214 - else if(__CHECKINT_UNLIKELY(x < y && ((y - x - 1) > LLONG_MAX))) 215 - *err = *err | CHECKINT_OVERFLOW_ERROR; 216 - return x - y; 217 - } 218 - 219 - __CHECKINT_INLINE uint64_t 220 - __checkint_uint64_sub_signed_signed(int64_t x, int64_t y, int32_t* err) { 221 - if(__CHECKINT_UNLIKELY(((x < 0 && y <= 0) || (x >= 0 && y > 0)) && (x - y) < 0)) 222 - *err = *err | CHECKINT_OVERFLOW_ERROR; 223 - else if(__CHECKINT_UNLIKELY(x < 0 && y > 0)) 224 - *err = *err | CHECKINT_OVERFLOW_ERROR; 225 - return x - y; 226 - } 227 - 228 - __CHECKINT_INLINE uint64_t 229 - __checkint_uint64_sub_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 230 - if(__CHECKINT_UNLIKELY(y > ((uint64_t) LLONG_MAX + 1) || ((int64_t) y) > x)) 231 - *err = *err | CHECKINT_OVERFLOW_ERROR; 232 - return x - y; 233 - } 234 - 235 - __CHECKINT_INLINE uint64_t 236 - __checkint_uint64_sub_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 237 - if(x <= LLONG_MAX) 238 - return __checkint_uint64_sub_signed_signed(x, y, err); 239 - else if (__CHECKINT_UNLIKELY(y == LLONG_MIN || -y > ULLONG_MAX - x)) 240 - *err = *err | CHECKINT_OVERFLOW_ERROR; 241 - return x - y; 242 - } 243 - 244 - __CHECKINT_INLINE uint64_t 245 - __checkint_uint64_sub_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 246 - if(__CHECKINT_UNLIKELY(x < y)) 247 - *err = *err | CHECKINT_OVERFLOW_ERROR; 248 - return x - y; 249 - } 250 - 251 - __CHECKINT_INLINE int32_t 252 - __checkint_int32_mul(int64_t x, int64_t y, int32_t* err) { 253 - int64_t z = x * y; 254 - if (__CHECKINT_UNLIKELY(x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX)) { 255 - *err |= CHECKINT_OVERFLOW_ERROR; 256 - } 257 - if (__CHECKINT_UNLIKELY(z > INT_MAX || z < INT_MIN)) *err |= CHECKINT_OVERFLOW_ERROR; 258 - return (int32_t)z; 259 - } 260 - 261 - __CHECKINT_INLINE uint32_t 262 - __checkint_uint32_mul(int64_t x, int64_t y, int32_t* err) { 263 - int64_t z = x * y; 264 - if (__CHECKINT_UNLIKELY((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull))) *err |= CHECKINT_OVERFLOW_ERROR; 265 - if (__CHECKINT_UNLIKELY(z > UINT_MAX || z < 0)) *err |= CHECKINT_OVERFLOW_ERROR; 266 - return (uint32_t)z; 267 - } 268 - 269 - __CHECKINT_INLINE int64_t 270 - __checkint_int64_mul_signed_signed(int64_t x, int64_t y, int32_t* err) { 271 - if(x == 0 || y == 0) return 0; 272 - 273 - if(!__checkint_is_mixed_sign64(x, y)) 274 - { 275 - if(x > 0) 276 - { 277 - if(__CHECKINT_UNLIKELY(LLONG_MAX/x < y)) 278 - *err = *err | CHECKINT_OVERFLOW_ERROR; 279 - } 280 - else 281 - { 282 - if(__CHECKINT_UNLIKELY(x == LLONG_MIN || y == LLONG_MIN)) 283 - *err = *err | CHECKINT_OVERFLOW_ERROR; 284 - if(__CHECKINT_UNLIKELY(LLONG_MAX/(-x) < (-y))) 285 - *err = *err | CHECKINT_OVERFLOW_ERROR; 286 - } 287 - } 288 - else 289 - { 290 - if(x < 0) 291 - { 292 - if(__CHECKINT_UNLIKELY(x < LLONG_MIN/y)) 293 - *err = *err | CHECKINT_OVERFLOW_ERROR; 294 - } 295 - else if(__CHECKINT_UNLIKELY(y < LLONG_MIN/x)) 296 - *err = *err | CHECKINT_OVERFLOW_ERROR; 297 - } 298 - return x * y; 299 - } 300 - 301 - __CHECKINT_INLINE uint64_t 302 - __checkint_uint64_mul_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 303 - if(x == 0) return 0; 304 - 305 - if(__CHECKINT_UNLIKELY(ULLONG_MAX/x < y)) 306 - *err = *err | CHECKINT_OVERFLOW_ERROR; 307 - return x * y; 308 - } 309 - 310 - 311 - __CHECKINT_INLINE int64_t 312 - __checkint_int64_mul_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 313 - if(x == 0) return 0; 314 - 315 - if(__CHECKINT_UNLIKELY(LLONG_MAX/x < y)) 316 - *err = *err | CHECKINT_OVERFLOW_ERROR; 317 - return x * y; 318 - } 319 - 320 - __CHECKINT_INLINE int64_t 321 - __checkint_int64_mul_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 322 - if(y == 0) return 0; 323 - 324 - if(x >= 0) 325 - return __checkint_int64_mul_unsigned_unsigned(x, y, err); 326 - else 327 - if(__CHECKINT_UNLIKELY(x < LLONG_MIN/y || x > LLONG_MAX/y)) 328 - *err = *err | CHECKINT_OVERFLOW_ERROR; 329 - return x * y; 330 - } 331 - 332 - __CHECKINT_INLINE int64_t 333 - __checkint_int64_mul_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 334 - return __checkint_int64_mul_signed_unsigned(y, x, err); 335 - } 336 - 337 - __CHECKINT_INLINE uint64_t 338 - __checkint_uint64_mul_signed_signed(int64_t x, int64_t y, int32_t* err) { 339 - if(__CHECKINT_UNLIKELY((x < 0 && y > 0) || (x > 0 && y < 0))) 340 - *err = *err | CHECKINT_OVERFLOW_ERROR; 341 - else if(x > 0 && y > 0) 342 - return __checkint_uint64_mul_unsigned_unsigned(x, y, err); 343 - else 344 - return __checkint_uint64_mul_unsigned_unsigned(-x, -y, err); 345 - return x * y; 346 - } 347 - 348 - __CHECKINT_INLINE uint64_t 349 - __checkint_uint64_mul_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 350 - if(x >= 0) 351 - return __checkint_uint64_mul_unsigned_unsigned(x, y, err); 352 - *err = *err | CHECKINT_OVERFLOW_ERROR; 353 - return (uint64_t) (x * y); 354 - } 355 - 356 - __CHECKINT_INLINE uint64_t 357 - __checkint_uint64_mul_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 358 - return __checkint_uint64_mul_signed_unsigned(y, x, err); 359 - } 360 - 361 - __CHECKINT_INLINE int32_t 362 - __checkint_int32_div_signed_signed(int32_t x, int32_t y, int32_t* err) { 363 - if(__CHECKINT_UNLIKELY((x == INT_MIN) && y == -1)) { 364 - *err = *err | CHECKINT_OVERFLOW_ERROR; 365 - return 0; 366 - } 367 - return x / y; 368 - } 369 - 370 - __CHECKINT_INLINE int32_t 371 - __checkint_int32_div_signed_unsigned(int32_t x, uint32_t y, int32_t* err) { 372 - if(y <= INT_MAX) 373 - return x / (int32_t) y; 374 - return 0; 375 - } 376 - 377 - __CHECKINT_INLINE int32_t 378 - __checkint_int32_div_unsigned_signed(uint32_t x, int32_t y, int32_t* err) { 379 - if(x == ((uint32_t) INT_MAX + 1) && y == -1) 380 - return INT_MIN; 381 - if(__CHECKINT_UNLIKELY(x > ((uint32_t) INT_MAX + 1) && y == -1)) 382 - *err = *err | CHECKINT_OVERFLOW_ERROR; 383 - else if(__CHECKINT_UNLIKELY(x > INT_MAX && y == 1)) 384 - *err = *err | CHECKINT_OVERFLOW_ERROR; 385 - if(x <= INT_MAX) 386 - return ((int32_t) x) / y; 387 - if(y > 0) 388 - return x / y; 389 - return -(x / (uint32_t) -y); 390 - } 391 - 392 - __CHECKINT_INLINE int32_t 393 - __checkint_int32_div_unsigned_unsigned(uint32_t x, uint32_t y, int32_t* err) { 394 - uint32_t result = x / y; 395 - if(__CHECKINT_UNLIKELY(result > INT_MAX)) 396 - *err = *err | CHECKINT_OVERFLOW_ERROR; 397 - return x / y; 398 - } 399 - 400 - __CHECKINT_INLINE uint32_t 401 - __checkint_uint32_div_signed_signed(int32_t x, int32_t y, int32_t* err) { 402 - int32_t result = x / y; 403 - if(x == INT_MIN && y == -1) 404 - return ((uint32_t) -x); 405 - if(__CHECKINT_UNLIKELY(result < 0)) 406 - *err = *err | CHECKINT_OVERFLOW_ERROR; 407 - if(x >= 0 && y > 0) 408 - return x / y; 409 - else if(x < 0 && y > 0) 410 - return -((uint32_t) -x / y); 411 - else if(x > 0 && y < 0) 412 - return -(x / (uint32_t) -y); 413 - else 414 - return ((uint32_t) -x / (uint32_t) -y); 415 - } 416 - 417 - __CHECKINT_INLINE uint32_t 418 - __checkint_uint32_div_signed_unsigned(int32_t x, uint32_t y, int32_t* err) { 419 - if(__CHECKINT_UNLIKELY(x < 0 && ((uint32_t) -x) >= y)) 420 - *err = *err | CHECKINT_OVERFLOW_ERROR; 421 - if(x >= 0) 422 - return x / y; 423 - return -(((uint32_t) -x) / y); 424 - } 425 - 426 - __CHECKINT_INLINE uint32_t 427 - __checkint_uint32_div_unsigned_signed(uint32_t x, int32_t y, int32_t* err) { 428 - if(__CHECKINT_UNLIKELY(y < 0 && ((uint32_t) -y) <= x)) 429 - *err = *err | CHECKINT_OVERFLOW_ERROR; 430 - if(y > 0) 431 - return x / y; 432 - return -(x / ((uint32_t) -y)); 433 - } 434 - 435 - __CHECKINT_INLINE uint32_t 436 - __checkint_uint32_div_unsigned_unsigned(uint32_t x, uint32_t y, int32_t* err) { 437 - return x / y; 438 - } 439 - 440 - __CHECKINT_INLINE int64_t 441 - __checkint_int64_div_signed_signed(int64_t x, int64_t y, int32_t* err) { 442 - if(__CHECKINT_UNLIKELY((x == LLONG_MIN) && y == -1)) { 443 - *err = *err | CHECKINT_OVERFLOW_ERROR; 444 - return 0; 445 - } 446 - return x / y; 447 - } 448 - 449 - __CHECKINT_INLINE int64_t 450 - __checkint_int64_div_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 451 - if(y <= LLONG_MAX) 452 - return x / (int64_t) y; 453 - return 0; 454 - } 455 - 456 - __CHECKINT_INLINE int64_t 457 - __checkint_int64_div_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 458 - if(x == ((uint64_t) LLONG_MAX + 1) && y == -1) 459 - return LLONG_MIN; 460 - if(__CHECKINT_UNLIKELY(x > ((uint64_t) LLONG_MAX + 1) && y == -1)) 461 - *err = *err | CHECKINT_OVERFLOW_ERROR; 462 - else if(__CHECKINT_UNLIKELY(x > LLONG_MAX && y == 1)) 463 - *err = *err | CHECKINT_OVERFLOW_ERROR; 464 - if(x <= LLONG_MAX) 465 - return ((int64_t) x) / y; 466 - if(y > 0) 467 - return x / y; 468 - return -(x / (uint64_t) -y); 469 - } 470 - 471 - __CHECKINT_INLINE int64_t 472 - __checkint_int64_div_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 473 - uint64_t result = x / y; 474 - if(__CHECKINT_UNLIKELY(result > LLONG_MAX)) 475 - *err = *err | CHECKINT_OVERFLOW_ERROR; 476 - return x / y; 477 - } 478 - 479 - __CHECKINT_INLINE uint64_t 480 - __checkint_uint64_div_signed_signed(int64_t x, int64_t y, int32_t* err) { 481 - int64_t result = x / y; 482 - if(x == LLONG_MIN && y == -1) 483 - return ((uint64_t)LLONG_MAX) + 1; 484 - if(__CHECKINT_UNLIKELY(result < 0)) 485 - *err = *err | CHECKINT_OVERFLOW_ERROR; 486 - if(x >= 0 && y > 0) 487 - return x / y; 488 - else if(x < 0 && y > 0) 489 - return -((uint64_t) -x / y); 490 - else if(x > 0 && y < 0) 491 - return -(x / (uint64_t) -y); 492 - else 493 - return ((uint64_t) -x / (uint64_t) -y); 494 - } 495 - 496 - __CHECKINT_INLINE uint64_t 497 - __checkint_uint64_div_signed_unsigned(int64_t x, uint64_t y, int32_t* err) { 498 - if(__CHECKINT_UNLIKELY(x < 0 && ((uint64_t) -x) >= y)) 499 - *err = *err | CHECKINT_OVERFLOW_ERROR; 500 - if(x >= 0) 501 - return x / y; 502 - return -(((uint64_t) -x) / y); 503 - } 504 - 505 - __CHECKINT_INLINE uint64_t 506 - __checkint_uint64_div_unsigned_signed(uint64_t x, int64_t y, int32_t* err) { 507 - if(__CHECKINT_UNLIKELY(y < 0 && ((uint64_t) -y) <= x)) 508 - *err = *err | CHECKINT_OVERFLOW_ERROR; 509 - if(y > 0) 510 - return x / y; 511 - return -(x / ((uint64_t) -y)); 512 - } 513 - 514 - __CHECKINT_INLINE uint64_t 515 - __checkint_uint64_div_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) { 516 - return x / y; 517 - } 518 - 519 - #undef __CHECKINT_INLINE 520 - 521 - /******/ 522 - 523 - #ifdef __GNUC__ 524 - #define __checkint_same_type(e1, e2) __builtin_types_compatible_p(__typeof__(e1), __typeof__(e2)) 525 - #define __checkint_cond_expr(c, e1, e2) __builtin_choose_expr(c, e1, e2) 526 - #else 527 - #error "need compiler support for __checkint_same_type() and __checkint_cond_expr()" 528 - #endif 529 - 530 - /******/ 531 - 532 - #define __checkint_is_signed(x) (__checkint_same_type(x, int8_t) || __checkint_same_type(x, int16_t) || __checkint_same_type(x, int32_t) || __checkint_same_type(x, int64_t) || __checkint_same_type(x, signed long)) 533 - #define __checkint_is_unsigned(x) (__checkint_same_type(x, uint8_t) || __checkint_same_type(x, uint16_t) || __checkint_same_type(x, uint32_t) || __checkint_same_type(x, uint64_t) || __checkint_same_type(x, uintptr_t) || __checkint_same_type(x, unsigned long)) 534 - 535 - #define __checkint_is_signed_signed(x, y) (__checkint_is_signed(x) && __checkint_is_signed(y)) 536 - #define __checkint_is_signed_unsigned(x, y) (__checkint_is_signed(x) && __checkint_is_unsigned(y)) 537 - #define __checkint_is_unsigned_signed(x, y) (__checkint_is_unsigned(x) && __checkint_is_signed(y)) 538 - #define __checkint_is_unsigned_unsigned(x, y) (__checkint_is_unsigned(x) && __checkint_is_unsigned(y)) 539 - 540 - /******/ 541 - 542 - #define __CHECKINT_SIGN_DEMUX(type,oper,x,y,err) \ 543 - (__checkint_cond_expr(__checkint_is_signed_signed(x, y), __checkint_ ## type ## _ ## oper ## _signed_signed(x, y, err), \ 544 - __checkint_cond_expr(__checkint_is_signed_unsigned(x, y), __checkint_ ## type ## _ ## oper ## _signed_unsigned(x, y, err), \ 545 - __checkint_cond_expr(__checkint_is_unsigned_signed(x, y), __checkint_ ## type ## _ ## oper ## _unsigned_signed(x, y, err), \ 546 - __checkint_cond_expr(__checkint_is_unsigned_unsigned(x, y), __checkint_ ## type ## _ ## oper ## _unsigned_unsigned(x, y, err), \ 547 - __checkint_ ## type ## _type_error(err)))))) 548 - 549 - #define __checkint_int64_add(x,y,err) __CHECKINT_SIGN_DEMUX(int64,add,x,y,err) 550 - #define __checkint_uint64_add(x,y,err) __CHECKINT_SIGN_DEMUX(uint64,add,x,y,err) 551 - 552 - #define __checkint_int64_sub(x,y,err) __CHECKINT_SIGN_DEMUX(int64,sub,x,y,err) 553 - #define __checkint_uint64_sub(x,y,err) __CHECKINT_SIGN_DEMUX(uint64,sub,x,y,err) 554 - 555 - #define __checkint_int64_mul(x,y,err) __CHECKINT_SIGN_DEMUX(int64,mul,x,y,err) 556 - #define __checkint_uint64_mul(x,y,err) __CHECKINT_SIGN_DEMUX(uint64,mul,x,y,err) 557 - 558 - #define __checkint_int32_div(x,y,err) __CHECKINT_SIGN_DEMUX(int32,div,x,y,err) 559 - #define __checkint_int64_div(x,y,err) __CHECKINT_SIGN_DEMUX(int64,div,x,y,err) 560 - #define __checkint_uint32_div(x,y,err) __CHECKINT_SIGN_DEMUX(uint32,div,x,y,err) 561 - #define __checkint_uint64_div(x,y,err) __CHECKINT_SIGN_DEMUX(uint64,div,x,y,err) 562 - 563 - __END_DECLS 564 - 565 - #endif /* __CHECKINT_H__ */
-288
src/libremovefile/removefile.3
··· 1 - .\" Copyright (c) 2015 Apple Inc. 2 - .\" All rights reserved. 3 - .\" 4 - .\" Redistribution and use in source and binary forms, with or without 5 - .\" modification, are permitted provided that the following conditions 6 - .\" are met: 7 - .\" 1. Redistributions of source code must retain the above copyright 8 - .\" notice, this list of conditions and the following disclaimer. 9 - .\" 2. Redistributions in binary form must reproduce the above copyright 10 - .\" notice, this list of conditions and the following disclaimer in the 11 - .\" documentation and/or other materials provided with the distribution. 12 - .\" 3. Neither the name of Apple Inc. ("Apple") nor the names of its 13 - .\" contributors may be used to endorse or promote products derived from 14 - .\" this software without specific prior written permission. 15 - .\" 16 - .\" THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 17 - .\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 - .\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 - .\" DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 20 - .\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 - .\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 - .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 - .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 - .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 - .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 - .\" 27 - .Dd Feb 26, 2015 28 - .Dt REMOVEFILE 3 29 - .Os 30 - .Sh NAME 31 - .Nm removefile , removefile_state_alloc , 32 - .Nm removefile_state_free , removefile_state_get , 33 - .Nm removefile_state_set 34 - .Nd remove files or directories 35 - .Sh SYNOPSIS 36 - .In removefile.h 37 - .Ft int 38 - .Fn removefile "const char *path" "removefile_state_t state" "removefile_flags_t flags" 39 - .Ft removefile_state_t 40 - .Fn removefile_state_alloc "void" 41 - .Ft int 42 - .Fn removefile_state_free "removefile_state_t state" 43 - .Ft int 44 - .Fn removefile_state_get "removefile_state_t state" "uint32_t key" "void * dst" 45 - .Ft int 46 - .Fn removefile_state_set "removefile_state_t state" "uint32_t key" "const void * value" 47 - .Ft int 48 - .Fn removefile_cancel "removefile_state_t state" 49 - .Sh DESCRIPTION 50 - .Pp 51 - These functions are used to remove a file or directory. Various levels 52 - of overwriting may be specified to prevent other people from recovering any 53 - information about the file. 54 - .Pp 55 - The 56 - .Fn removefile_state_alloc 57 - function initializes a 58 - .Vt removefile_state_t 59 - object (which is an opaque data type). 60 - This object can be passed to 61 - .Fn removefile . 62 - .Fn removefile_state_get 63 - and 64 - .Fn removefile_state_set 65 - can be used to manipulate the state (see below). 66 - The 67 - .Fn removefile_state_free 68 - function is used to deallocate the object and its contents. 69 - .Pp 70 - The 71 - .Fn removefile 72 - function removes files and directories located at the named 73 - .Va path 74 - filesystem location. The named 75 - .Va path 76 - location can be specified as either an absolute path or relative to the working directory 77 - of the calling process. 78 - If the 79 - .Va state 80 - parameter is the return value from 81 - .Fn removefile_state_alloc , 82 - then 83 - .Fn removefile 84 - will use the information from the state object; if it is 85 - .Dv NULL , 86 - then 87 - .Fn removefile 88 - will work normally, but less control will be available to the caller. 89 - The 90 - .Va flags 91 - parameter controls deletion options: 92 - .Bl -tag -width REMOVEFILE_SECURE_1_PASS_ZERO 93 - .It Dv REMOVEFILE_RECURSIVE 94 - If the 95 - .Va path 96 - location is a directory, then recursively delete the entire directory. 97 - .It Dv REMOVEFILE_KEEP_PARENT 98 - The file or directory at the 99 - .Va path 100 - location is not deleted. If specified in conjunction with REMOVEFILE_RECURSIVE, 101 - then all of the contents of the directory at 102 - .Va path 103 - location will be deleted, but not the directory itself. 104 - .It Dv REMOVEFILE_CROSS_MOUNT 105 - By default, recursive traversals do not cross mount points. This option allows 106 - .Fn removefile 107 - to descend into directories that have a different device number than the file from which 108 - the descent began. 109 - .It Dv REMOVEFILE_SECURE_7_PASS 110 - Overwrite the file with 7 US DoD compliant passes (0xF6, 0x00, 0xFF, random, 0x00, 0xFF, random). 111 - .It Dv REMOVEFILE_SECURE_35_PASS 112 - Overwrite the file using 35-pass Gutmann algorithm. 113 - .It Dv REMOVEFILE_SECURE_3_PASS 114 - Overwrite the file twice with random bytes, and then with 0xAA. 115 - .It Dv REMOVEFILE_SECURE_1_PASS 116 - Overwrite with a single pass of random data. 117 - .It Dv REMOVEFILE_SECURE_1_PASS_ZERO 118 - Overwrite with a single pass of zeroes. 119 - .El 120 - .Pp 121 - The 122 - .Fn removefile_state_get 123 - and 124 - .Fn removefile_state_set 125 - functions can be used to manipulate the 126 - .Ft removefile_state_t 127 - object returned by 128 - .Fn removefile_state_alloc . 129 - In both functions, the 130 - .Va dst 131 - or the 132 - .Va value 133 - parameter's type depends on the 134 - .Va key 135 - parameter that is passed in. 136 - .Bl -tag -width REMOVEFILE_STATE_CONFIRM_CALLBACK 137 - .It Dv REMOVEFILE_STATE_CONFIRM_CALLBACK 138 - Get or set the callback function of type 139 - .Va removefile_callback_t 140 - to be called prior to file deletion. 141 - .It Dv REMOVEFILE_STATE_CONFIRM_CONTEXT 142 - Get or set any parameters of type 143 - .Va void * 144 - that are needed for the confirm callback function. 145 - .It Dv REMOVEFILE_STATE_ERROR_CALLBACK 146 - Get or set the callback function of type 147 - .Va removefile_callback_t 148 - to be called when an error is detected. 149 - .It Dv REMOVEFILE_STATE_ERROR_CONTEXT 150 - Get or set any parameters of type 151 - .Va void * 152 - that are needed for the error callback function. 153 - .It Dv REMOVEFILE_STATE_ERRNO 154 - Get or set the current errno of type 155 - .Va int 156 - .It Dv REMOVEFILE_STATE_STATUS_CALLBACK 157 - Get or set the callback function of type 158 - .Va removefile_callback_t 159 - to be called subsequent to file deletion. 160 - .It Dv REMOVEFILE_STATE_STATUS_CONTEXT 161 - Get or set any parameters of type 162 - .Va void * 163 - that are needed for the status callback function. 164 - .El 165 - .Pp 166 - The 167 - .Va removefile_callback_t 168 - function pointer is defined as the following: 169 - .Pp 170 - .Ft int 171 - .Va (*removefile_callback_t) (removefile_state_t state, const char *path , void *context) 172 - .Pp 173 - The return value of the callback function is given as: 174 - .Bl -tag -width REMOVEFILE_PROCEED 175 - .It Dv REMOVEFILE_PROCEED 176 - File is deleted and 177 - .Fn removefile 178 - continues operation as normal. 179 - .It Dv REMOVEFILE_SKIP 180 - Current file is not deleted and 181 - .Fn removefile 182 - continues operation as normal. 183 - .It Dv REMOVEFILE_STOP 184 - Current file is not deleted and 185 - .Fn removefile 186 - exits without continuing further. 187 - .El 188 - .Pp 189 - The 190 - .Fn removefile_cancel 191 - function is used to cancel a remove that is in progress. 192 - .Sh RETURN VALUES 193 - The family of 194 - .Fn removefile 195 - functions returns less than 0 on error, and 0 on success. 196 - .Sh ERRORS 197 - .Fn removefile 198 - will fail if: 199 - .Bl -tag -width Er 200 - .It Bq Er EACCES 201 - The 202 - .Va path 203 - location specifies a file or directory for which the calling process does not 204 - have proper permissions. 205 - .It Bq Er EINVAL 206 - A callback returned an invalid return value (not REMOVEFILE_PROCEED, REMOVEFILE_SKIP, or REMOVEFILE_STOP) 207 - .It Bq Er EMLINK 208 - The 209 - .Va path 210 - location refers to a symbolic link. 211 - .It Bq Er ENAMETOOLONG 212 - The resource fork name of the file exceeds the maximum allowed length. 213 - .It Bq Er ENOMEM 214 - A memory allocation failed. 215 - .It Bq Er ENOTEMPTY 216 - The 217 - .Va path 218 - location specifies a directory that contains an immutable file which cannot be 219 - deleted. 220 - .It Bq Er EPERM 221 - The 222 - .Va path 223 - location specifies an immutable file that cannot be deleted. 224 - .El 225 - .Pp 226 - .Fn removefile_cancel 227 - will fail if: 228 - .Bl -tag -width Er 229 - .It Bq Er EINVAL 230 - A 231 - .Va NULL 232 - parameter was passed into 233 - .Fn removefile_cancel . 234 - .El 235 - .Pp 236 - In addition, all functions may return an error from an underlying library or 237 - system call. 238 - .Sh NOTES 239 - .Pp 240 - Write protected files owned by another user cannot be removed by 241 - .Fn removefile , 242 - regardless of the permissions on the directory containing the file. 243 - .Pp 244 - If multiple of the REMOVEFILE_SECURE_1_PASS, REMOVEFILE_SECURE_7_PASS, and REMOVEFILE_SECURE_35_PASS 245 - flags are specified, 246 - .Fn removefile 247 - will proceed using the flag that specifies the highest number of overwriting passes. 248 - .Pp 249 - .Fn removefile 250 - is pathname-based; this means that, when descending into a hierarchy, there are potential race conditions 251 - that may add risk when run with privileges. 252 - .Pp 253 - .Fn removefile 254 - operates on symbolic links, rather than the target of the link. 255 - .Sh EXAMPLES 256 - .Bd -literal -offset indent 257 - /* Initialize a state variable */ 258 - removefile_state_t s; 259 - s = removefile_state_alloc(); 260 - /* Recursively remove all files and directories while keeping parent tmp directory. */ 261 - removefile("/tmp", s, REMOVEFILE_RECURSIVE | REMOVEFILE_KEEP_PARENT); 262 - /* Release the state variable */ 263 - removefile_state_free(s); 264 - .Pp 265 - /* A more complex way to call removefile() -- define a callback function */ 266 - int removefile_status_callback(removefile_state_t state, const char * path, void * context) { 267 - fprintf(stderr, "File deleted: %s", path); 268 - return REMOVEFILE_PROCEED; 269 - } 270 - /* Initialize a state variable */ 271 - s = removefile_state_alloc(); 272 - /* Set callback function properties */ 273 - removefile_state_set(s, REMOVEFILE_STATE_CONFIRM_CALLBACK, removefile_confirm_callback); 274 - removefile_state_set(s, REMOVEFILE_STATE_CONFIRM_CONTEXT, NULL); 275 - /* Recursively remove all files and directories while keeping parent tmp directory, 276 - calling a confirm callback prior to each file deletion. */ 277 - removefile("/tmp", s, REMOVEFILE_RECURSIVE | REMOVEFILE_KEEP_PARENT); 278 - /* Release the state variable. */ 279 - removefile_state_free(s); 280 - .Ed 281 - .Sh "SEE ALSO" 282 - .Xr unlink 1 , 283 - .Xr sync 2 , 284 - .Xr sync_volume_np 3 285 - .Sh HISTORY 286 - The 287 - .Fn removefile 288 - API was introduced in Mac OS X 10.5.
-144
src/libremovefile/removefile.c
··· 1 - #include "removefile.h" 2 - #include "removefile_priv.h" 3 - 4 - #include <TargetConditionals.h> 5 - 6 - removefile_state_t 7 - removefile_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 - 14 - int 15 - removefile_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 - 30 - int 31 - removefile_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 - 61 - int 62 - removefile_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 - 92 - int 93 - removefile(const char* path, removefile_state_t state_param, removefile_flags_t flags) { 94 - int res = 0, error = 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 - error = state->error_num; 117 - free(paths[0]); 118 - } else { 119 - error = ENOMEM; 120 - res = -1; 121 - } 122 - 123 - // deallocate if allocated locally 124 - if (state_param == NULL) { 125 - removefile_state_free(state); 126 - } 127 - 128 - if (res) { 129 - errno = error; 130 - } 131 - 132 - return res; 133 - } 134 - 135 - int 136 - removefile_cancel(removefile_state_t state) { 137 - if (state == NULL) { 138 - errno = EINVAL; 139 - return -1; 140 - } else { 141 - state->cancelled = 1; 142 - return 0; 143 - } 144 - }
-71
src/libremovefile/removefile.h
··· 1 - /* 2 - * Copyright (c) 2015 Apple Computer, Inc. All rights reserved. 3 - */ 4 - 5 - #ifndef __REMOVEFILE_H__ 6 - #define __REMOVEFILE_H__ 7 - 8 - #include <stdint.h> 9 - 10 - #ifdef __cplusplus 11 - extern "C" { 12 - #endif 13 - 14 - /* 15 - * Flags 16 - */ 17 - typedef uint32_t removefile_flags_t; 18 - 19 - enum { 20 - REMOVEFILE_RECURSIVE = (1 << 0), // If path is a directory, recurse (depth first traversal) 21 - REMOVEFILE_KEEP_PARENT = (1 << 1), // Remove contents but not directory itself 22 - REMOVEFILE_SECURE_7_PASS = (1 << 2), // 7 pass DoD algorithm 23 - REMOVEFILE_SECURE_35_PASS = (1 << 3), // 35-pass Gutmann algorithm (overrides REMOVEFILE_SECURE_7_PASS) 24 - REMOVEFILE_SECURE_1_PASS = (1 << 4), // 1 pass single overwrite 25 - REMOVEFILE_SECURE_3_PASS = (1 << 5), // 3 pass overwrite 26 - REMOVEFILE_SECURE_1_PASS_ZERO = (1 << 6), // Single-pass overwrite, with 0 instead of random data 27 - REMOVEFILE_CROSS_MOUNT = (1 << 7), // Cross mountpoints when deleting recursively. 28 - }; 29 - 30 - /* 31 - * State object to pass in callback information 32 - */ 33 - typedef struct _removefile_state * removefile_state_t; 34 - 35 - removefile_state_t removefile_state_alloc(void); 36 - int removefile_state_free(removefile_state_t); 37 - 38 - int removefile_state_get(removefile_state_t state, uint32_t key, void * dst); 39 - int removefile_state_set(removefile_state_t state, uint32_t key, const void* value); 40 - 41 - enum { 42 - REMOVEFILE_STATE_CONFIRM_CALLBACK = 1, // removefile_callback_t 43 - REMOVEFILE_STATE_CONFIRM_CONTEXT = 2, // void* 44 - REMOVEFILE_STATE_ERROR_CALLBACK = 3, // removefile_callback_t 45 - REMOVEFILE_STATE_ERROR_CONTEXT = 4, // void* 46 - REMOVEFILE_STATE_ERRNO = 5, // int (read-only) 47 - REMOVEFILE_STATE_STATUS_CALLBACK = 6, // removefile_callback_t 48 - REMOVEFILE_STATE_STATUS_CONTEXT = 7, // void* 49 - }; 50 - 51 - typedef int (*removefile_callback_t)(removefile_state_t state, const char* path, void* context); 52 - 53 - /* 54 - * Callback return values 55 - */ 56 - enum { 57 - REMOVEFILE_PROCEED = 0, 58 - REMOVEFILE_SKIP = 1, 59 - REMOVEFILE_STOP = 2, 60 - }; 61 - 62 - 63 - int removefile(const char* path, removefile_state_t state, removefile_flags_t flags); 64 - 65 - int removefile_cancel(removefile_state_t state); 66 - 67 - #ifdef __cplusplus 68 - } 69 - #endif 70 - 71 - #endif /* __REMOVEFILE_H__ */
-22
src/libremovefile/removefile.plist
··· 1 - <?xml version="1.0" encoding="UTF-8"?> 2 - <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 - <plist version="1.0"> 4 - <dict> 5 - <key>OpenSourceImportDate</key> 6 - <string>2004-09-22</string> 7 - <key>OpenSourceLicense</key> 8 - <string>MIT</string> 9 - <key>OpenSourceLicenseFile</key> 10 - <string>removefile.txt</string> 11 - <key>OpenSourceProject</key> 12 - <string>srm</string> 13 - <key>OpenSourceSHA1</key> 14 - <string>8b7aafc95b3ef67e2c737030567222bf50082188</string> 15 - <key>OpenSourceURL</key> 16 - <string>http://prdownloads.sourceforge.net/srm/srm-1.2.8.tar.gz?download</string> 17 - <key>OpenSourceVersion</key> 18 - <string>1.2.8</string> 19 - <key>OpenSourceWebsiteURL</key> 20 - <string>http://sourceforge.net/projects/srm/</string> 21 - </dict> 22 - </plist>
-275
src/libremovefile/removefile.xcodeproj/project.pbxproj
··· 1 - // !$*UTF8*$! 2 - { 3 - archiveVersion = 1; 4 - classes = { 5 - }; 6 - objectVersion = 46; 7 - objects = { 8 - 9 - /* Begin PBXBuildFile section */ 10 - FCCE179913592780002CEE6D /* checkint.h in Headers */ = {isa = PBXBuildFile; fileRef = FCCE179013592780002CEE6D /* checkint.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 - FCCE179A13592780002CEE6D /* removefile_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = FCCE179113592780002CEE6D /* removefile_priv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 12 - FCCE179B13592780002CEE6D /* removefile_random.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179213592780002CEE6D /* removefile_random.c */; }; 13 - FCCE179C13592780002CEE6D /* removefile_rename_unlink.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179313592780002CEE6D /* removefile_rename_unlink.c */; }; 14 - FCCE179D13592780002CEE6D /* removefile_sunlink.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179413592780002CEE6D /* removefile_sunlink.c */; }; 15 - FCCE179E13592780002CEE6D /* removefile_tree_walker.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179513592780002CEE6D /* removefile_tree_walker.c */; }; 16 - FCCE179F13592780002CEE6D /* removefile.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179713592780002CEE6D /* removefile.c */; }; 17 - FCCE17A013592780002CEE6D /* removefile.h in Headers */ = {isa = PBXBuildFile; fileRef = FCCE179813592780002CEE6D /* removefile.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 - FCCE17DE135A69CD002CEE6D /* test-removefile.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE17DD135A69CD002CEE6D /* test-removefile.c */; }; 19 - /* End PBXBuildFile section */ 20 - 21 - /* Begin PBXFileReference section */ 22 - 3FE582A1185C51BD007B3FA6 /* removefile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = removefile.xcconfig; path = xcodescripts/removefile.xcconfig; sourceTree = "<group>"; }; 23 - FCCE1789135924FC002CEE6D /* libremovefile.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libremovefile.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 24 - FCCE178F13592780002CEE6D /* checkint.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = checkint.3; sourceTree = "<group>"; }; 25 - FCCE179013592780002CEE6D /* checkint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = checkint.h; sourceTree = "<group>"; }; 26 - FCCE179113592780002CEE6D /* removefile_priv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = removefile_priv.h; sourceTree = "<group>"; }; 27 - FCCE179213592780002CEE6D /* removefile_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = removefile_random.c; sourceTree = "<group>"; }; 28 - FCCE179313592780002CEE6D /* removefile_rename_unlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = removefile_rename_unlink.c; sourceTree = "<group>"; }; 29 - FCCE179413592780002CEE6D /* removefile_sunlink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = removefile_sunlink.c; sourceTree = "<group>"; }; 30 - FCCE179513592780002CEE6D /* removefile_tree_walker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = removefile_tree_walker.c; sourceTree = "<group>"; }; 31 - FCCE179613592780002CEE6D /* removefile.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = removefile.3; sourceTree = "<group>"; }; 32 - FCCE179713592780002CEE6D /* removefile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = removefile.c; sourceTree = "<group>"; }; 33 - FCCE179813592780002CEE6D /* removefile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = removefile.h; sourceTree = "<group>"; }; 34 - FCCE17A5135A3E9C002CEE6D /* install_files.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = install_files.sh; path = xcodescripts/install_files.sh; sourceTree = "<group>"; }; 35 - FCCE17D3135A6961002CEE6D /* test-removefile */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "test-removefile"; sourceTree = BUILT_PRODUCTS_DIR; }; 36 - FCCE17DD135A69CD002CEE6D /* test-removefile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "test-removefile.c"; path = "test/test-removefile.c"; sourceTree = "<group>"; }; 37 - /* End PBXFileReference section */ 38 - 39 - /* Begin PBXFrameworksBuildPhase section */ 40 - FCCE1786135924FC002CEE6D /* Frameworks */ = { 41 - isa = PBXFrameworksBuildPhase; 42 - buildActionMask = 2147483647; 43 - files = ( 44 - ); 45 - runOnlyForDeploymentPostprocessing = 0; 46 - }; 47 - FCCE17D0135A6961002CEE6D /* Frameworks */ = { 48 - isa = PBXFrameworksBuildPhase; 49 - buildActionMask = 2147483647; 50 - files = ( 51 - ); 52 - runOnlyForDeploymentPostprocessing = 0; 53 - }; 54 - /* End PBXFrameworksBuildPhase section */ 55 - 56 - /* Begin PBXGroup section */ 57 - FCCE1779135924CD002CEE6D = { 58 - isa = PBXGroup; 59 - children = ( 60 - 3FE582A1185C51BD007B3FA6 /* removefile.xcconfig */, 61 - FCCE179813592780002CEE6D /* removefile.h */, 62 - FCCE179113592780002CEE6D /* removefile_priv.h */, 63 - FCCE179613592780002CEE6D /* removefile.3 */, 64 - FCCE179713592780002CEE6D /* removefile.c */, 65 - FCCE179213592780002CEE6D /* removefile_random.c */, 66 - FCCE179313592780002CEE6D /* removefile_rename_unlink.c */, 67 - FCCE179413592780002CEE6D /* removefile_sunlink.c */, 68 - FCCE179513592780002CEE6D /* removefile_tree_walker.c */, 69 - FCCE17DD135A69CD002CEE6D /* test-removefile.c */, 70 - FCCE17A5135A3E9C002CEE6D /* install_files.sh */, 71 - FCCE179013592780002CEE6D /* checkint.h */, 72 - FCCE178F13592780002CEE6D /* checkint.3 */, 73 - FCCE178A135924FC002CEE6D /* Products */, 74 - ); 75 - sourceTree = "<group>"; 76 - }; 77 - FCCE178A135924FC002CEE6D /* Products */ = { 78 - isa = PBXGroup; 79 - children = ( 80 - FCCE1789135924FC002CEE6D /* libremovefile.dylib */, 81 - FCCE17D3135A6961002CEE6D /* test-removefile */, 82 - ); 83 - name = Products; 84 - sourceTree = "<group>"; 85 - }; 86 - /* End PBXGroup section */ 87 - 88 - /* Begin PBXHeadersBuildPhase section */ 89 - FCCE1787135924FC002CEE6D /* Headers */ = { 90 - isa = PBXHeadersBuildPhase; 91 - buildActionMask = 2147483647; 92 - files = ( 93 - FCCE179913592780002CEE6D /* checkint.h in Headers */, 94 - FCCE17A013592780002CEE6D /* removefile.h in Headers */, 95 - FCCE179A13592780002CEE6D /* removefile_priv.h in Headers */, 96 - ); 97 - runOnlyForDeploymentPostprocessing = 0; 98 - }; 99 - /* End PBXHeadersBuildPhase section */ 100 - 101 - /* Begin PBXNativeTarget section */ 102 - FCCE1788135924FC002CEE6D /* removefile */ = { 103 - isa = PBXNativeTarget; 104 - buildConfigurationList = FCCE178D135924FD002CEE6D /* Build configuration list for PBXNativeTarget "removefile" */; 105 - buildPhases = ( 106 - FCCE1785135924FC002CEE6D /* Sources */, 107 - FCCE1786135924FC002CEE6D /* Frameworks */, 108 - FCCE1787135924FC002CEE6D /* Headers */, 109 - FCCE17A4135A3E89002CEE6D /* Run Script */, 110 - ); 111 - buildRules = ( 112 - ); 113 - dependencies = ( 114 - ); 115 - name = removefile; 116 - productName = removefile; 117 - productReference = FCCE1789135924FC002CEE6D /* libremovefile.dylib */; 118 - productType = "com.apple.product-type.library.dynamic"; 119 - }; 120 - FCCE17D2135A6961002CEE6D /* test-removefile */ = { 121 - isa = PBXNativeTarget; 122 - buildConfigurationList = FCCE17DB135A6961002CEE6D /* Build configuration list for PBXNativeTarget "test-removefile" */; 123 - buildPhases = ( 124 - FCCE17CF135A6961002CEE6D /* Sources */, 125 - FCCE17D0135A6961002CEE6D /* Frameworks */, 126 - ); 127 - buildRules = ( 128 - ); 129 - dependencies = ( 130 - ); 131 - name = "test-removefile"; 132 - productName = "test-removefile"; 133 - productReference = FCCE17D3135A6961002CEE6D /* test-removefile */; 134 - productType = "com.apple.product-type.tool"; 135 - }; 136 - /* End PBXNativeTarget section */ 137 - 138 - /* Begin PBXProject section */ 139 - FCCE177B135924CD002CEE6D /* Project object */ = { 140 - isa = PBXProject; 141 - attributes = { 142 - ORGANIZATIONNAME = "Apple Inc."; 143 - }; 144 - buildConfigurationList = FCCE177E135924CD002CEE6D /* Build configuration list for PBXProject "removefile" */; 145 - compatibilityVersion = "Xcode 3.2"; 146 - developmentRegion = English; 147 - hasScannedForEncodings = 0; 148 - knownRegions = ( 149 - en, 150 - ); 151 - mainGroup = FCCE1779135924CD002CEE6D; 152 - productRefGroup = FCCE178A135924FC002CEE6D /* Products */; 153 - projectDirPath = ""; 154 - projectRoot = ""; 155 - targets = ( 156 - FCCE1788135924FC002CEE6D /* removefile */, 157 - FCCE17D2135A6961002CEE6D /* test-removefile */, 158 - ); 159 - }; 160 - /* End PBXProject section */ 161 - 162 - /* Begin PBXShellScriptBuildPhase section */ 163 - FCCE17A4135A3E89002CEE6D /* Run Script */ = { 164 - isa = PBXShellScriptBuildPhase; 165 - buildActionMask = 8; 166 - files = ( 167 - ); 168 - inputPaths = ( 169 - ); 170 - name = "Run Script"; 171 - outputPaths = ( 172 - ); 173 - runOnlyForDeploymentPostprocessing = 1; 174 - shellPath = /bin/sh; 175 - shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install_files.sh"; 176 - }; 177 - /* End PBXShellScriptBuildPhase section */ 178 - 179 - /* Begin PBXSourcesBuildPhase section */ 180 - FCCE1785135924FC002CEE6D /* Sources */ = { 181 - isa = PBXSourcesBuildPhase; 182 - buildActionMask = 2147483647; 183 - files = ( 184 - FCCE179B13592780002CEE6D /* removefile_random.c in Sources */, 185 - FCCE179C13592780002CEE6D /* removefile_rename_unlink.c in Sources */, 186 - FCCE179D13592780002CEE6D /* removefile_sunlink.c in Sources */, 187 - FCCE179E13592780002CEE6D /* removefile_tree_walker.c in Sources */, 188 - FCCE179F13592780002CEE6D /* removefile.c in Sources */, 189 - ); 190 - runOnlyForDeploymentPostprocessing = 0; 191 - }; 192 - FCCE17CF135A6961002CEE6D /* Sources */ = { 193 - isa = PBXSourcesBuildPhase; 194 - buildActionMask = 2147483647; 195 - files = ( 196 - FCCE17DE135A69CD002CEE6D /* test-removefile.c in Sources */, 197 - ); 198 - runOnlyForDeploymentPostprocessing = 0; 199 - }; 200 - /* End PBXSourcesBuildPhase section */ 201 - 202 - /* Begin XCBuildConfiguration section */ 203 - FCCE1781135924CD002CEE6D /* Release */ = { 204 - isa = XCBuildConfiguration; 205 - buildSettings = { 206 - SUPPORTS_TEXT_BASED_API = YES; 207 - TAPI_VERIFY_MODE = Pedantic; 208 - }; 209 - name = Release; 210 - }; 211 - FCCE178C135924FD002CEE6D /* Release */ = { 212 - isa = XCBuildConfiguration; 213 - baseConfigurationReference = 3FE582A1185C51BD007B3FA6 /* removefile.xcconfig */; 214 - buildSettings = { 215 - DYLIB_COMPATIBILITY_VERSION = 1; 216 - DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)"; 217 - EXECUTABLE_PREFIX = lib; 218 - GCC_PREPROCESSOR_DEFINITIONS = "__DARWIN_NON_CANCELABLE=1"; 219 - GCC_TREAT_WARNINGS_AS_ERRORS = YES; 220 - IS_ZIPPERED = YES; 221 - LINK_WITH_STANDARD_LIBRARIES = NO; 222 - OTHER_LDFLAGS = ( 223 - "-Wl,-umbrella,System", 224 - "-L/usr/lib/system", 225 - "-ldyld", 226 - "-lcompiler_rt", 227 - "-lsystem$(SIM_SUFFIX)_kernel", 228 - "-lsystem$(SIM_SUFFIX)_platform", 229 - "-lsystem_malloc", 230 - "-lsystem_c", 231 - ); 232 - "SIM_SUFFIX[sdk=iphonesimulator*]" = _sim; 233 - VERSION_INFO_PREFIX = "__attribute__((visibility(\"hidden\")))"; 234 - WARNING_CFLAGS = "-Wall"; 235 - }; 236 - name = Release; 237 - }; 238 - FCCE17DA135A6961002CEE6D /* Release */ = { 239 - isa = XCBuildConfiguration; 240 - buildSettings = { 241 - PRODUCT_NAME = "$(TARGET_NAME)"; 242 - }; 243 - name = Release; 244 - }; 245 - /* End XCBuildConfiguration section */ 246 - 247 - /* Begin XCConfigurationList section */ 248 - FCCE177E135924CD002CEE6D /* Build configuration list for PBXProject "removefile" */ = { 249 - isa = XCConfigurationList; 250 - buildConfigurations = ( 251 - FCCE1781135924CD002CEE6D /* Release */, 252 - ); 253 - defaultConfigurationIsVisible = 0; 254 - defaultConfigurationName = Release; 255 - }; 256 - FCCE178D135924FD002CEE6D /* Build configuration list for PBXNativeTarget "removefile" */ = { 257 - isa = XCConfigurationList; 258 - buildConfigurations = ( 259 - FCCE178C135924FD002CEE6D /* Release */, 260 - ); 261 - defaultConfigurationIsVisible = 0; 262 - defaultConfigurationName = Release; 263 - }; 264 - FCCE17DB135A6961002CEE6D /* Build configuration list for PBXNativeTarget "test-removefile" */ = { 265 - isa = XCConfigurationList; 266 - buildConfigurations = ( 267 - FCCE17DA135A6961002CEE6D /* Release */, 268 - ); 269 - defaultConfigurationIsVisible = 0; 270 - defaultConfigurationName = Release; 271 - }; 272 - /* End XCConfigurationList section */ 273 - }; 274 - rootObject = FCCE177B135924CD002CEE6D /* Project object */; 275 - }
-67
src/libremovefile/removefile_priv.h
··· 1 - #ifdef __cplusplus 2 - extern "C" { 3 - #endif 4 - 5 - #include "removefile.h" 6 - 7 - #include <sys/stat.h> 8 - #include <sys/param.h> 9 - #include <sys/mount.h> 10 - 11 - #include <err.h> 12 - #include <errno.h> 13 - #include <fcntl.h> 14 - #include <fts.h> 15 - #include <stdio.h> 16 - #include <stdlib.h> 17 - #include <string.h> 18 - #include <sysexits.h> 19 - #include <unistd.h> 20 - 21 - /* 22 - * This structure contains variables necessary to keep track of verification, 23 - * the flags set by the user, as well as associated buffers and file 24 - * attributes. These were defined previously by srm as global variables but a 25 - * structure is a much cleaner way of organizing the information and passing 26 - * it between functions. 27 - */ 28 - 29 - struct _removefile_state { 30 - removefile_callback_t confirm_callback; 31 - void * confirm_context; 32 - removefile_callback_t error_callback; 33 - void * error_context; 34 - int error_num; // clear on proceed 35 - removefile_callback_t status_callback; 36 - void * status_context; 37 - 38 - // globals for srm 39 - int urand_file; 40 - off_t random_bytes_read; 41 - int file; 42 - off_t file_size; 43 - unsigned char * buffer; 44 - uint32_t buffsize; 45 - uint32_t allocated_buffsize; 46 - int unlink_flags; 47 - int cancelled; 48 - }; 49 - 50 - int __removefile_rename_unlink(const char*path, removefile_state_t state); 51 - int __removefile_tree_walker(char ** trees, removefile_state_t state); 52 - int __removefile_sunlink(const char * path, removefile_state_t state); 53 - void __removefile_init_random(const unsigned int seed, removefile_state_t state); 54 - char __removefile_random_char(removefile_state_t state); 55 - void __removefile_randomize_buffer(unsigned char *buffer, size_t length, removefile_state_t state); 56 - 57 - #define __removefile_state_test_cancel(s) ((s)->cancelled != 0) 58 - 59 - #ifdef __cplusplus 60 - } 61 - #endif 62 - 63 - #if __APPLE__ 64 - #ifndef AT_REMOVEDIR_DATALESS 65 - #define AT_REMOVEDIR_DATALESS 0x0100 /* Remove a dataless directory without materializing first */ 66 - #endif 67 - #endif
-119
src/libremovefile/removefile_random.c
··· 1 - /* srm */ 2 - /* Copyright (c) 2000 Matthew D. Gauthier 3 - * Portions copyright (c) 2007 Apple Inc. All rights reserved. 4 - * 5 - * Permission is hereby granted, free of charge, to any person obtaining 6 - * a copy of this software and associated documentation files (the 7 - * "Software"), to deal in the Software without restriction, including 8 - * without limitation the rights to use, copy, modify, merge, publish, 9 - * distribute, sublicense, and/or sell copies of the Software, and to 10 - * permit persons to whom the Software is furnished to do so, subject to 11 - * the following conditions: 12 - * 13 - * The above copyright notice and this permission notice shall be 14 - * included in all copies or substantial portions of the Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 - * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 - * OTHER DEALINGS IN THE SOFTWARE. 23 - * 24 - * Except as contained in this notice, the name of the contributors shall 25 - * not be used in advertising or otherwise to promote the sale, use or 26 - * other dealings in this Software without prior written authorization. 27 - */ 28 - 29 - #include <fcntl.h> 30 - #include <stdlib.h> 31 - #include <sys/stat.h> 32 - #include <sys/types.h> 33 - #include <sys/time.h> 34 - #include <unistd.h> 35 - 36 - #include "removefile.h" 37 - #include "removefile_priv.h" 38 - 39 - static void 40 - seed_random(removefile_state_t state) { 41 - #ifdef USE_ARC4RANDOM 42 - arc4random_stir(); 43 - #else 44 - unsigned int rseed; 45 - struct timeval tv; 46 - struct timezone tz; 47 - 48 - if (state->urand_file != -1) { 49 - read(state->urand_file, &rseed, sizeof(rseed)); 50 - } else { 51 - rseed = rand(); 52 - } 53 - (void)gettimeofday(&tv, &tz); 54 - rseed ^= tv.tv_sec + tv.tv_usec + getpid(); 55 - srand(rseed); 56 - #endif 57 - } 58 - 59 - void 60 - __removefile_init_random(const unsigned int seed, removefile_state_t state) { 61 - #ifdef USE_ARC4RANDOM 62 - arc4random_addrandom((unsigned char *)&seed, sizeof(seed)); 63 - #else 64 - struct stat statbuf; 65 - 66 - if (stat("/dev/urandom", &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) { 67 - state->urand_file = open("/dev/urandom", O_RDONLY); 68 - } else { 69 - srand(seed); 70 - } 71 - seed_random(state); 72 - #endif 73 - } 74 - 75 - char 76 - __removefile_random_char(removefile_state_t state) { 77 - #ifdef USE_ARC4RANDOM 78 - random_bytes_read += 4; 79 - return arc4random(); 80 - #else 81 - char buf[4]; 82 - 83 - if (state->urand_file != -1) { 84 - read(state->urand_file, &buf, 1); 85 - return buf[0]; 86 - } 87 - return rand(); 88 - #endif 89 - } 90 - 91 - void 92 - __removefile_randomize_buffer(unsigned char *buffer, size_t length, removefile_state_t state) { 93 - size_t i; 94 - 95 - #ifdef USE_ARC4RANDOM 96 - u_int32_t *p = (u_int32_t *)buffer; 97 - u_int32_t mod4length = length - (length % 4); 98 - 99 - for (i = 0; i < mod4length; i += 4) { 100 - *p++ = arc4random(); 101 - } 102 - 103 - while (i < length) { 104 - buffer[i++] = arc4random(); 105 - } 106 - state->random_bytes_read += (mod4length + ((length - mod4length) * 4)); 107 - if (state->random_bytes_read > 512*1024*1024 /* RESEED_BYTES */) { 108 - state->random_bytes_read = 0; 109 - seed_random(state); 110 - } 111 - #else 112 - if (state->urand_file != -1) { 113 - read(state->urand_file, buffer, length); 114 - } else { 115 - for (i = 0; i < length; i++) 116 - buffer[i] = rand(); 117 - } 118 - #endif 119 - }
-121
src/libremovefile/removefile_rename_unlink.c
··· 1 - /* srm */ 2 - /* Copyright (c) 2000 Matthew D. Gauthier 3 - * Portions copyright (c) 2007 Apple Inc. All rights reserved. 4 - * 5 - * Permission is hereby granted, free of charge, to any person obtaining 6 - * a copy of this software and associated documentation files (the 7 - * "Software"), to deal in the Software without restriction, including 8 - * without limitation the rights to use, copy, modify, merge, publish, 9 - * distribute, sublicense, and/or sell copies of the Software, and to 10 - * permit persons to whom the Software is furnished to do so, subject to 11 - * the following conditions: 12 - * 13 - * The above copyright notice and this permission notice shall be 14 - * included in all copies or substantial portions of the Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 - * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 - * OTHER DEALINGS IN THE SOFTWARE. 23 - * 24 - * Except as contained in this notice, the name of the contributors shall 25 - * not be used in advertising or otherwise to promote the sale, use or 26 - * other dealings in this Software without prior written authorization. 27 - */ 28 - 29 - #include <ctype.h> 30 - #include <dirent.h> 31 - #include <errno.h> 32 - #include <stdlib.h> 33 - #include <stdio.h> 34 - #include <string.h> 35 - #include <sys/stat.h> 36 - #include <unistd.h> 37 - 38 - #include <TargetConditionals.h> 39 - 40 - #include "removefile.h" 41 - #include "removefile_priv.h" 42 - 43 - static int empty_directory(const char *path) { 44 - DIR *dp; 45 - struct dirent *de; 46 - 47 - dp = opendir(path); 48 - if (dp == NULL) { 49 - return -1; 50 - } 51 - while ((de = readdir(dp)) != NULL) { 52 - if (de->d_namlen < 3 && (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))) { 53 - continue; 54 - } 55 - (void)closedir(dp); 56 - return -1; 57 - } 58 - (void)closedir(dp); 59 - return 0; 60 - } 61 - 62 - int 63 - __removefile_rename_unlink(const char *path, removefile_state_t state) { 64 - char *p, c; 65 - struct stat statbuf; 66 - 67 - size_t new_name_size = strlen(path) + 15; 68 - char new_name[new_name_size]; 69 - int i = 0; 70 - 71 - strlcpy(new_name, path, new_name_size); 72 - 73 - if ( (p = strrchr(new_name, '/')) != NULL ) { 74 - p++; 75 - *p = '\0'; 76 - } else { 77 - p = new_name; 78 - } 79 - 80 - do { 81 - i = 0; 82 - 83 - while (i < 14) { 84 - c = __removefile_random_char(state); 85 - if (isalnum((int) c)) { 86 - p[i] = c; 87 - i++; 88 - } 89 - } 90 - p[i] = '\0'; 91 - } while (lstat(new_name, &statbuf) == 0); 92 - 93 - if (lstat(path, &statbuf) == -1) 94 - return -1; 95 - 96 - #if __APPLE__ 97 - if (S_ISDIR(statbuf.st_mode) && (statbuf.st_flags & SF_DATALESS) != 0) { 98 - return unlinkat(AT_FDCWD, path, AT_REMOVEDIR_DATALESS); 99 - } 100 - #endif 101 - 102 - if (S_ISDIR(statbuf.st_mode) && (empty_directory(path) == -1)) { 103 - /* Directory isn't empty (e.g. because it contains an immutable file). 104 - Attempting to remove it will fail, so avoid renaming it. */ 105 - errno = ENOTEMPTY; 106 - return -1; 107 - } 108 - 109 - if (rename(path, new_name) == -1) 110 - return -1; 111 - 112 - if (lstat(new_name, &statbuf) == -1) { 113 - errno = ENOENT; 114 - return -1; 115 - } 116 - 117 - if (S_ISDIR(statbuf.st_mode)) 118 - return rmdir(new_name); 119 - 120 - return unlink(new_name); 121 - }
-456
src/libremovefile/removefile_sunlink.c
··· 1 - /* srm */ 2 - /* Copyright (c) 2000 Matthew D. Gauthier 3 - * Portions copyright (c) 2007 Apple Inc. All rights reserved. 4 - * 5 - * Permission is hereby granted, free of charge, to any person obtaining 6 - * a copy of this software and associated documentation files (the 7 - * "Software"), to deal in the Software without restriction, including 8 - * without limitation the rights to use, copy, modify, merge, publish, 9 - * distribute, sublicense, and/or sell copies of the Software, and to 10 - * permit persons to whom the Software is furnished to do so, subject to 11 - * the following conditions: 12 - * 13 - * The above copyright notice and this permission notice shall be 14 - * included in all copies or substantial portions of the Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 - * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 - * OTHER DEALINGS IN THE SOFTWARE. 23 - * 24 - * Except as contained in this notice, the name of the contributors shall 25 - * not be used in advertising or otherwise to promote the sale, use or 26 - * other dealings in this Software without prior written authorization. 27 - */ 28 - 29 - #include <errno.h> 30 - #include <fcntl.h> 31 - #include <stdarg.h> 32 - #include <stdio.h> 33 - #include <stdlib.h> 34 - #include <string.h> 35 - #include <sys/ioctl.h> 36 - #include <sys/stat.h> 37 - #include <sys/types.h> 38 - #include <sys/mount.h> 39 - #include <time.h> 40 - #include <unistd.h> 41 - 42 - #if HAVE_LINUX_EXT2_FS_H 43 - #include <linux/ext2_fs.h> 44 - #endif 45 - 46 - #if HAVE_SYS_VFS_H 47 - #include <sys/vfs.h> 48 - #endif 49 - 50 - #if HAVE_SYS_PARAM_H && HAVE_SYS_MOUNT_H 51 - #include <sys/param.h> 52 - #include <sys/mount.h> 53 - #endif 54 - 55 - #if __APPLE__ 56 - #include <sys/disk.h> 57 - #endif 58 - 59 - #if HAVE_CHFLAGS 60 - /* define unsupported flags as 0 */ 61 - # if !defined UF_IMMUTABLE 62 - # define UF_IMMUTABLE 0 63 - # endif 64 - # if !defined UF_APPEND 65 - # define UF_APPEND 0 66 - # endif 67 - # if !defined UF_NOUNLINK 68 - # define UF_NOUNLINK 0 69 - # endif 70 - # if !defined SF_IMMUTABLE 71 - # define SF_IMMUTABLE 0 72 - # endif 73 - # if !defined SF_APPEND 74 - # define SF_APPEND 0 75 - # endif 76 - # if !defined SF_NOUNLINK 77 - # define SF_NOUNLINK 0 78 - # endif 79 - #endif 80 - 81 - #include "removefile.h" 82 - #include "removefile_priv.h" 83 - 84 - static int 85 - init_write_buffer(struct stat *statbuf, struct statfs *fs_stats, removefile_state_t state) { 86 - u_int32_t tmp_buffsize; 87 - 88 - state->file_size = statbuf->st_size; 89 - state->buffsize = statbuf->st_blksize; 90 - 91 - #if HAVE_SYS_PARAM_H 92 - /* try to determine an optimal write buffer size */ 93 - state->buffsize = (u_int32_t)(statbuf->st_size / statbuf->st_blksize) * statbuf->st_blksize; 94 - if ((statbuf->st_size % statbuf->st_blksize) != 0) { 95 - /* add full size of last block */ 96 - state->buffsize += statbuf->st_blksize; 97 - } else if (state->buffsize < statbuf->st_blksize) { 98 - /* no smaller than one device block */ 99 - state->buffsize = statbuf->st_blksize; 100 - } 101 - tmp_buffsize = MAXBSIZE; 102 - if (state->buffsize > tmp_buffsize) { 103 - /* no larger than the largest file system buffer size */ 104 - state->buffsize = tmp_buffsize; 105 - } 106 - #endif 107 - 108 - /* Allocated buffer must be at least 2 bytes larger than logical buffsize. 109 - This lets us align repeating 3-byte patterns across multiple buffer 110 - writes by using a variable offset (0..2) from the start of the buffer. */ 111 - 112 - tmp_buffsize = state->buffsize + 4; 113 - 114 - if (state->buffer) { 115 - if (tmp_buffsize > state->allocated_buffsize) { 116 - free(state->buffer); 117 - state->buffer = NULL; 118 - } else { 119 - return 0; /* use existing buffer */ 120 - } 121 - } 122 - if ((state->buffer = (unsigned char *)malloc(tmp_buffsize)) == NULL) { 123 - errno = ENOMEM; 124 - return -1; 125 - } 126 - state->allocated_buffsize = tmp_buffsize; 127 - return 0; 128 - } 129 - 130 - static void 131 - flush(int fd) { 132 - /* force buffered writes to be flushed to disk */ 133 - #if defined F_FULLFSYNC 134 - /* F_FULLFSYNC is equivalent to fsync plus device flush to media */ 135 - if (fcntl(fd, F_FULLFSYNC, NULL) != 0) { 136 - /* we're not on a fs that supports this; fall back to plain fsync */ 137 - fsync(fd); 138 - } 139 - #elif HAVE_FDATASYNC 140 - fdatasync(fd); 141 - #else 142 - fsync(fd); 143 - #endif 144 - } 145 - 146 - static unsigned char *align_buffer(unsigned char *buf, off_t pos) { 147 - /* return a pointer to the start of the buffer which should be written, 148 - offset from the given buffer by 0, 1, or 2 bytes, so that the 3-byte 149 - pattern which the buffer contains is aligned with the previous write. */ 150 - return (unsigned char *)((uintptr_t)buf + (unsigned int)(pos % 3)); 151 - } 152 - 153 - #if 0 /* UNUSED */ 154 - void verification_failure(off_t count) { 155 - if (sizeof(off_t) == 4) 156 - printf("warning: failed to verify write at offset %d\n", count); 157 - else if (sizeof(off_t) == 8) 158 - printf("warning: failed to verify write at offset %lld\n", count); 159 - else 160 - printf("warning: previous write failed to verify!\n"); 161 - fflush(stdout); 162 - } 163 - #endif /* UNUSED */ 164 - 165 - static void 166 - overwrite(int stage, removefile_state_t state) { 167 - ssize_t i; 168 - off_t count = 0; 169 - unsigned char *buffptr = state->buffer; 170 - 171 - // break out of the function early if cancel is detected 172 - if (__removefile_state_test_cancel(state)) return; 173 - 174 - lseek(state->file, 0, SEEK_SET); 175 - while (count < state->file_size - state->buffsize) { 176 - if (stage == 1 /* W_RANDOM */) { 177 - __removefile_randomize_buffer(state->buffer, state->buffsize, state); 178 - } else if (stage == 2 /* W_TRIPLE */) { 179 - buffptr = align_buffer(state->buffer, count); 180 - } 181 - i = write(state->file, buffptr, state->buffsize); 182 - if (i > 0) 183 - count += i; 184 - 185 - // break out of the loop early if cancel is detected 186 - if (__removefile_state_test_cancel(state)) return; 187 - } 188 - if (stage == 1 /* W_RANDOM */) { 189 - __removefile_randomize_buffer(state->buffer, (size_t)(state->file_size - count), state); 190 - } else if (stage == 2 /* W_TRIPLE */) { 191 - buffptr = align_buffer(state->buffer, count); 192 - } 193 - i = write(state->file, buffptr, (size_t)(state->file_size - count)); 194 - /* 195 - * Only flush the data if we're doing more than one pass of writes. 196 - */ 197 - if ((state->unlink_flags & (REMOVEFILE_SECURE_7_PASS | REMOVEFILE_SECURE_35_PASS | REMOVEFILE_SECURE_3_PASS)) != 0) 198 - flush(state->file); 199 - lseek(state->file, 0, SEEK_SET); 200 - } 201 - 202 - static void 203 - overwrite_random(int num_passes, removefile_state_t state) { 204 - int i; 205 - 206 - for (i = 0; i < num_passes; i++) { 207 - overwrite(1 /* W_RANDOM */, state); 208 - } 209 - } 210 - 211 - static void 212 - overwrite_byte(int byte, removefile_state_t state) { 213 - memset(state->buffer, byte, state->buffsize); 214 - overwrite(0 /* W_SINGLE */, state); 215 - } 216 - 217 - static void 218 - overwrite_bytes(unsigned int byte1, unsigned int byte2, unsigned int byte3, removefile_state_t state) { 219 - u_int32_t val[3], *p = (u_int32_t *)state->buffer; 220 - unsigned int i, mod12buffsize = state->allocated_buffsize - (state->allocated_buffsize % 12); 221 - 222 - val[0] = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte1; 223 - val[1] = (byte2 << 24) | (byte3 << 16) | (byte1 << 8) | byte2; 224 - val[2] = (byte3 << 24) | (byte1 << 16) | (byte2 << 8) | byte3; 225 - 226 - /* fill buffer 12 bytes at a time, optimized for 4-byte alignment */ 227 - for (i = 0; i < mod12buffsize; i += 12) { 228 - *p++ = val[0]; 229 - *p++ = val[1]; 230 - *p++ = val[2]; 231 - } 232 - while (i < state->allocated_buffsize) { 233 - state->buffer[i] = ((unsigned char *)&val[0])[i % 3]; 234 - i++; 235 - } 236 - overwrite(2 /* W_TRIPLE */, state); 237 - } 238 - 239 - static void 240 - overwrite_file(removefile_state_t state) { 241 - if (state->unlink_flags & REMOVEFILE_SECURE_35_PASS) { 242 - /* Gutmann 35-pass overwrite */ 243 - overwrite_random(4, state); 244 - overwrite_byte(0x55, state); 245 - overwrite_byte(0xAA, state); 246 - overwrite_bytes(0x92, 0x49, 0x24, state); 247 - overwrite_bytes(0x49, 0x24, 0x92, state); 248 - overwrite_bytes(0x24, 0x92, 0x49, state); 249 - overwrite_byte(0x00, state); 250 - overwrite_byte(0x11, state); 251 - overwrite_byte(0x22, state); 252 - overwrite_byte(0x33, state); 253 - overwrite_byte(0x44, state); 254 - overwrite_byte(0x55, state); 255 - overwrite_byte(0x66, state); 256 - overwrite_byte(0x77, state); 257 - overwrite_byte(0x88, state); 258 - overwrite_byte(0x99, state); 259 - overwrite_byte(0xAA, state); 260 - overwrite_byte(0xBB, state); 261 - overwrite_byte(0xCC, state); 262 - overwrite_byte(0xDD, state); 263 - overwrite_byte(0xEE, state); 264 - overwrite_byte(0xFF, state); 265 - overwrite_bytes(0x92, 0x49, 0x24, state); 266 - overwrite_bytes(0x49, 0x24, 0x92, state); 267 - overwrite_bytes(0x24, 0x92, 0x49, state); 268 - overwrite_bytes(0x6D, 0xB6, 0xDB, state); 269 - overwrite_bytes(0xB6, 0xDB, 0x6D, state); 270 - overwrite_bytes(0xDB, 0x6D, 0xB6, state); 271 - overwrite_random(4, state); 272 - } else if (state->unlink_flags & REMOVEFILE_SECURE_7_PASS) { 273 - /* DoD-compliant 7-pass overwrite */ 274 - overwrite_byte(0xF6, state); 275 - overwrite_byte(0x00, state); 276 - overwrite_byte(0xFF, state); 277 - overwrite_random(1, state); 278 - overwrite_byte(0x00, state); 279 - overwrite_byte(0xFF, state); 280 - overwrite_random(1, state); 281 - } else if (state->unlink_flags & REMOVEFILE_SECURE_3_PASS) { 282 - /* DOE M2051-2 or DOD 5220.22-M */ 283 - overwrite_random(2, state); 284 - overwrite_byte(0xAA, state); 285 - } else if (state->unlink_flags & REMOVEFILE_SECURE_1_PASS) { 286 - overwrite_random(1, state); 287 - } else if (state->unlink_flags & REMOVEFILE_SECURE_1_PASS_ZERO) { 288 - overwrite_byte(0, state); 289 - } 290 - } 291 - 292 - int 293 - __removefile_sunlink(const char *path, removefile_state_t state) { 294 - struct stat statbuf; 295 - struct statfs fs_stats; 296 - #if HAVE_LINUX_EXT2_FS_H 297 - int flags = 0; 298 - #endif 299 - int fmode = O_WRONLY; 300 - struct flock flock; 301 - 302 - if (lstat(path, &statbuf) == -1) 303 - return -1; 304 - if (!S_ISREG(statbuf.st_mode)) 305 - return __removefile_rename_unlink(path, state); 306 - if (statbuf.st_nlink > 1) { 307 - return __removefile_rename_unlink(path, state); 308 - } 309 - 310 - if ( (state->file = open(path, fmode)) == -1) /* BSD doesn't support O_SYNC */ 311 - return -1; 312 - if (fcntl(state->file, F_WRLCK, &flock) == -1) { 313 - close(state->file); 314 - state->file = -1; 315 - return -1; 316 - } 317 - 318 - if (fstatfs(state->file, &fs_stats) == -1 && errno != ENOSYS) { 319 - close(state->file); 320 - state->file = -1; 321 - return -1; 322 - } 323 - 324 - #if HAVE_LINUX_EXT2_FS_H 325 - if (fs_stats.f_type == EXT2_SUPER_MAGIC) 326 - if (ioctl(state->file, EXT2_IOC_GETFLAGS, &flags) == -1) { 327 - close(state->file); 328 - state->file = -1; 329 - return -1; 330 - } 331 - 332 - if ( (flags & EXT2_UNRM_FL) || (flags & EXT2_IMMUTABLE_FL) || 333 - (flags & EXT2_APPEND_FL) ) 334 - { 335 - close(state->file); 336 - state->file = -1; 337 - errno = EPERM; 338 - return -1; 339 - } 340 - 341 - #endif /* HAVE_LINUX_EXT2_FS_H */ 342 - 343 - /* chflags(2) turns out to be a different system call in every BSD 344 - derivative. The important thing is to make sure we'll be able to 345 - unlink it after we're through messing around. Unlinking it first 346 - would remove the need for any of these checks, but would leave the 347 - user with no way to overwrite the file if the process was 348 - interrupted during the overwriting. So, instead we assume that the 349 - open() above will fail on immutable and append-only files and try 350 - and catch only platforms supporting NOUNLINK here. 351 - 352 - FreeBSD - supports NOUNLINK (from 4.4 on?) 353 - MacOS X - doesn't support NOUNLINK (as of 10.3.5) 354 - OpenBSD - doesn't support NOUNLINK (as of 3.1) 355 - Tru64 - unknown 356 - 357 - Note: unsupported flags are defined as 0 at the top of this file, 358 - so a specific platform check is not required here. 359 - */ 360 - 361 - #if HAVE_CHFLAGS 362 - if ((statbuf.st_flags & UF_IMMUTABLE) || 363 - (statbuf.st_flags & UF_APPEND) || 364 - (statbuf.st_flags & UF_NOUNLINK) || 365 - (statbuf.st_flags & SF_IMMUTABLE) || 366 - (statbuf.st_flags & SF_APPEND) || 367 - (statbuf.st_flags & SF_NOUNLINK)) 368 - { 369 - close(state->file); 370 - state->file = -1; 371 - errno = EPERM; 372 - return -1; 373 - } 374 - #endif /* HAVE_CHFLAGS */ 375 - 376 - if (init_write_buffer(&statbuf, &fs_stats, state) == -1) { 377 - close(state->file); 378 - state->file = -1; 379 - return -1; 380 - } 381 - #if defined F_NOCACHE 382 - /* before performing file I/O, set F_NOCACHE to prevent caching */ 383 - (void)fcntl(state->file, F_NOCACHE, 1); 384 - #endif 385 - overwrite_file(state); 386 - #if HAVE_LINUX_EXT2_FS_H 387 - ioctl(state->file, EXT2_IOC_SETFLAGS, EXT2_SECRM_FL); 388 - #endif 389 - 390 - close(state->file); 391 - state->file = -1; 392 - #if __APPLE__ 393 - /* Also overwrite the file's resource fork, if present. */ 394 - { 395 - static const char *RSRCFORKSPEC = "/..namedfork/rsrc"; 396 - off_t rsrc_fork_size; 397 - size_t rsrc_path_size = strlen(path) + strlen(RSRCFORKSPEC) + 1; 398 - char *rsrc_path = (char *)alloca(rsrc_path_size); 399 - if (rsrc_path == NULL) { 400 - errno = ENOMEM; 401 - return -1; 402 - } 403 - if (snprintf(rsrc_path, MAXPATHLEN, 404 - "%s%s", path, RSRCFORKSPEC ) > MAXPATHLEN - 1) { 405 - errno = ENAMETOOLONG; 406 - return -1; 407 - } 408 - 409 - if (lstat(rsrc_path, &statbuf) != 0) { 410 - int err = errno; 411 - if (err == ENOENT || err == ENOTDIR) { 412 - rsrc_fork_size = 0; 413 - } else { 414 - return -1; 415 - } 416 - } else { 417 - rsrc_fork_size = statbuf.st_size; 418 - } 419 - 420 - if (rsrc_fork_size > 0) { 421 - 422 - if ((state->file = open(rsrc_path, O_WRONLY)) == -1) { 423 - return -1; 424 - } 425 - if (fcntl(state->file, F_WRLCK, &flock) == -1) { 426 - close(state->file); 427 - state->file = -1; 428 - return -1; 429 - } 430 - 431 - if (init_write_buffer(&statbuf, &fs_stats, state) == -1) { 432 - close(state->file); 433 - state->file = -1; 434 - return -1; 435 - } 436 - 437 - #if defined F_NOCACHE 438 - /* before performing file I/O, set F_NOCACHE to prevent caching */ 439 - (void)fcntl(state->file, F_NOCACHE, 1); 440 - #endif 441 - 442 - overwrite_file(state); 443 - 444 - close(state->file); 445 - state->file = -1; 446 - } 447 - } 448 - #endif /* __APPLE__ */ 449 - 450 - if (__removefile_state_test_cancel(state)) { 451 - errno = ECANCELED; 452 - return -1; 453 - } 454 - 455 - return __removefile_rename_unlink(path, state); 456 - }
-259
src/libremovefile/removefile_tree_walker.c
··· 1 - /* srm */ 2 - /* Copyright (c) 2000 Matthew D. Gauthier 3 - * Portions copyright (c) 2015 Apple Inc. All rights reserved. 4 - * 5 - * Permission is hereby granted, free of charge, to any person obtaining 6 - * a copy of this software and associated documentation files (the 7 - * "Software"), to deal in the Software without restriction, including 8 - * without limitation the rights to use, copy, modify, merge, publish, 9 - * distribute, sublicense, and/or sell copies of the Software, and to 10 - * permit persons to whom the Software is furnished to do so, subject to 11 - * the following conditions: 12 - * 13 - * The above copyright notice and this permission notice shall be 14 - * included in all copies or substantial portions of the Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 - * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 - * OTHER DEALINGS IN THE SOFTWARE. 23 - * 24 - * Except as contained in this notice, the name of the contributors shall 25 - * not be used in advertising or otherwise to promote the sale, use or 26 - * other dealings in this Software without prior written authorization. 27 - */ 28 - 29 - #include <errno.h> 30 - #include <fcntl.h> 31 - #include <stdlib.h> 32 - #include <stdio.h> 33 - #include <string.h> 34 - #include <sys/resource.h> 35 - #include <sys/stat.h> 36 - #include <sys/types.h> 37 - #include <unistd.h> 38 - #include <fts.h> 39 - 40 - #include "removefile.h" 41 - #include "removefile_priv.h" 42 - 43 - static int 44 - __removefile_process_file(FTS* stream, FTSENT* current_file, removefile_state_t state) { 45 - int res = 0; 46 - char* path = current_file->fts_path; 47 - 48 - int recursive = state->unlink_flags & REMOVEFILE_RECURSIVE; 49 - int keep_parent = state->unlink_flags & REMOVEFILE_KEEP_PARENT; 50 - int secure = state->unlink_flags & (REMOVEFILE_SECURE_7_PASS | REMOVEFILE_SECURE_35_PASS | REMOVEFILE_SECURE_1_PASS | REMOVEFILE_SECURE_3_PASS | REMOVEFILE_SECURE_1_PASS_ZERO); 51 - 52 - switch (current_file->fts_info) { 53 - // attempt to unlink the directory on pre-order in case it is 54 - // a directory hard-link. If we succeed, it was a hard-link 55 - // and we should not descend any further. 56 - case FTS_D: 57 - if (unlink(path) == 0) { 58 - fts_set(stream, current_file, FTS_SKIP); 59 - } 60 - break; 61 - case FTS_DC: 62 - state->error_num = ELOOP; 63 - res = -1; 64 - break; 65 - case FTS_DNR: 66 - case FTS_ERR: 67 - case FTS_NS: 68 - state->error_num = current_file->fts_errno; 69 - res = -1; 70 - break; 71 - case FTS_DP: 72 - if (recursive && 73 - (!keep_parent || 74 - current_file->fts_level != FTS_ROOTLEVEL)) { 75 - if (secure) { 76 - res = __removefile_rename_unlink(path, 77 - state); 78 - } else { 79 - if (geteuid() == 0 && 80 - (current_file->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && 81 - !(current_file->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && 82 - chflags(path, current_file->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) { 83 - errno = EACCES; 84 - res = -1; 85 - } else { 86 - #if __APPLE__ 87 - int is_dataless = (current_file->fts_statp->st_flags & SF_DATALESS) != 0; 88 - if (is_dataless) { 89 - int iopolicy = getiopolicy_np(IOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES, IOPOL_SCOPE_THREAD); 90 - int non_materializing = iopolicy == IOPOL_MATERIALIZE_DATALESS_FILES_OFF; 91 - if (non_materializing || state->confirm_callback == NULL) { 92 - res = unlinkat(AT_FDCWD, path, AT_REMOVEDIR_DATALESS); 93 - } else { 94 - res = rmdir(path); 95 - } 96 - } else { 97 - res = rmdir(path); 98 - } 99 - #else 100 - res = rmdir(path); 101 - #endif 102 - } 103 - } 104 - if (res == -1) state->error_num = errno; 105 - } 106 - break; 107 - case FTS_F: 108 - case FTS_SL: 109 - case FTS_SLNONE: 110 - case FTS_DEFAULT: 111 - if (secure) { 112 - res = __removefile_sunlink(path, state); 113 - } else if (geteuid() == 0 && 114 - (current_file->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && 115 - !(current_file->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && 116 - chflags(path, current_file->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) { 117 - errno = EACCES; 118 - res = -1; 119 - } else { 120 - res = unlink(path); 121 - } 122 - if (res == -1) state->error_num = errno; 123 - break; 124 - case FTS_DOT: 125 - default: 126 - break; 127 - } 128 - return res; 129 - } 130 - 131 - int 132 - __removefile_tree_walker(char **trees, removefile_state_t state) { 133 - FTSENT *current_file; 134 - FTS *stream; 135 - int rval = 0; 136 - int open_flags = 0; 137 - 138 - removefile_callback_t cb_confirm = NULL; 139 - removefile_callback_t cb_status = NULL; 140 - removefile_callback_t cb_error = NULL; 141 - 142 - cb_confirm = state->confirm_callback; 143 - cb_status = state->status_callback; 144 - cb_error = state->error_callback; 145 - 146 - open_flags = FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV; 147 - 148 - /* 149 - * Don't cross a mount point when deleting recursively by default. 150 - * This default was changed in 10.11, previous to which there was 151 - * no way to prevent removefile from crossing mount points. 152 - * see: rdar://problem/6799948 153 - */ 154 - if ((REMOVEFILE_CROSS_MOUNT & state->unlink_flags) != 0) 155 - open_flags &= ~FTS_XDEV; 156 - 157 - stream = fts_open(trees, open_flags, NULL); 158 - if (stream == NULL) { 159 - state->error_num = errno; 160 - return -1; 161 - } 162 - 163 - while ((current_file = fts_read(stream)) != NULL) { 164 - int res = REMOVEFILE_PROCEED; 165 - 166 - /* 167 - * fts_number is set to REMOVEFILE_SKIP for directories where 168 - * the confirmation callback has asked to skip it. We check 169 - * this on post-order, so we don't remove an empty directory that 170 - * the caller wanted preserved. 171 - */ 172 - if (current_file->fts_info == FTS_DP && 173 - current_file->fts_number == REMOVEFILE_SKIP) { 174 - current_file->fts_number = 0; 175 - continue; 176 - } 177 - 178 - /* Setting FTS_XDEV skips the mountpoint on pre-order traversal, 179 - * but you have to manually hop over it on post-order or 180 - * removefile will return an error. 181 - */ 182 - if (current_file->fts_info == FTS_DP && 183 - stream->fts_options & FTS_XDEV && 184 - stream->fts_dev != current_file->fts_dev) { 185 - continue; 186 - } 187 - 188 - // don't process the file if a cancel has been requested 189 - if (__removefile_state_test_cancel(state)) break; 190 - 191 - // confirm regular files and directories in pre-order 192 - if (cb_confirm && current_file->fts_info != FTS_DP) { 193 - res = cb_confirm(state, 194 - current_file->fts_path, state->confirm_context); 195 - } 196 - 197 - // don't process the file if a cancel has been requested 198 - // by the callback 199 - if (__removefile_state_test_cancel(state)) break; 200 - 201 - if (res == REMOVEFILE_PROCEED) { 202 - state->error_num = 0; 203 - rval = __removefile_process_file(stream, current_file, 204 - state); 205 - 206 - if (state->error_num != 0) { 207 - // Since removefile(3) is abstracting the 208 - // traversal of the directory tree, suppress 209 - // all ENOENT and ENOTDIR errors from the 210 - // calling process. 211 - // However, these errors should still be 212 - // reported for the ROOTLEVEL since those paths 213 - // were explicitly provided by the application. 214 - if ((state->error_num != ENOENT && 215 - state->error_num != ENOTDIR) || 216 - current_file->fts_level == FTS_ROOTLEVEL) { 217 - if (cb_error) { 218 - res = cb_error(state, 219 - current_file->fts_path, 220 - state->error_context); 221 - if (res == REMOVEFILE_PROCEED || 222 - res == REMOVEFILE_SKIP) { 223 - rval = 0; 224 - } else if (res == REMOVEFILE_STOP) { 225 - rval = -1; 226 - } 227 - } else { 228 - res = REMOVEFILE_STOP; 229 - } 230 - } 231 - // show status for regular files and directories 232 - // in post-order 233 - } else if (cb_status && 234 - current_file->fts_info != FTS_D) { 235 - res = cb_status(state, current_file->fts_path, 236 - state->status_context); 237 - } 238 - } 239 - 240 - if (current_file->fts_info == FTS_D && res == REMOVEFILE_SKIP) { 241 - current_file->fts_number = REMOVEFILE_SKIP; 242 - } 243 - 244 - if (res == REMOVEFILE_SKIP || 245 - !(state->unlink_flags & REMOVEFILE_RECURSIVE)) 246 - fts_set(stream, current_file, FTS_SKIP); 247 - if (res == REMOVEFILE_STOP || 248 - __removefile_state_test_cancel(state)) 249 - break; 250 - } 251 - 252 - if (__removefile_state_test_cancel(state)) { 253 - state->error_num = ECANCELED; 254 - rval = -1; 255 - } 256 - 257 - fts_close(stream); 258 - return rval; 259 - }
-136
src/libremovefile/test/test-removefile.c
··· 1 - #include "removefile.h" 2 - 3 - #include <assert.h> 4 - #include <errno.h> 5 - #include <fcntl.h> 6 - #include <pthread.h> 7 - #include <stdio.h> 8 - #include <string.h> 9 - #include <sys/stat.h> 10 - #include <sys/time.h> 11 - #include <unistd.h> 12 - 13 - 14 - static struct timeval tv; 15 - static void start_timer(const char* str) { 16 - fprintf(stderr, "%s... ", str); 17 - assert(gettimeofday(&tv, NULL) == 0); 18 - } 19 - 20 - static void stop_timer() { 21 - struct timeval tv2; 22 - assert(gettimeofday(&tv2, NULL) == 0); 23 - long sec = tv2.tv_sec - tv.tv_sec; 24 - long usec; 25 - if (sec == 0) { 26 - usec = tv2.tv_usec - tv.tv_usec; 27 - } else { 28 - usec = tv2.tv_usec + (1000000 - tv.tv_usec); 29 - } 30 - fprintf(stderr, "%ld.%03ld\n", sec, usec); 31 - } 32 - 33 - 34 - static int removefile_confirm_callback(removefile_state_t state, const char * path, void * context) { 35 - assert(context == (void*)1234); 36 - fprintf(stderr, "confirm callback: %s\n", path); 37 - return REMOVEFILE_PROCEED; 38 - } 39 - 40 - static int removefile_error_callback(removefile_state_t state, const char * path, void * context) { 41 - assert(context == (void*)4567); 42 - int err = 0; 43 - assert(removefile_state_get(state, REMOVEFILE_STATE_ERRNO, &err) == 0); 44 - fprintf(stderr, "error callback: %s: %s (%d)\n", path, strerror(err), err); 45 - return REMOVEFILE_PROCEED; 46 - } 47 - 48 - static int removefile_status_callback(removefile_state_t state, const char * path, void * context) { 49 - fprintf(stderr, "status callback: %s\n", path); 50 - return REMOVEFILE_PROCEED; 51 - } 52 - 53 - 54 - void mkdirs() { 55 - start_timer("Creating directory structure"); 56 - assert(mkdir("/tmp/removefile-test", 0755) == 0); 57 - assert(mkdir("/tmp/removefile-test/foo", 0755) == 0); 58 - assert(mkdir("/tmp/removefile-test/foo/bar", 0755) == 0); 59 - assert(mkdir("/tmp/removefile-test/foo/baz", 0755) == 0); 60 - int fd; 61 - assert((fd = open("/tmp/removefile-test/foo/baz/woot", O_CREAT | O_TRUNC | O_WRONLY, 0644)) != -1); 62 - write(fd, "Hello World\n", 12); 63 - close(fd); 64 - assert((fd = open("/tmp/removefile-test/foo/baz/wootage", O_CREAT | O_TRUNC | O_WRONLY, 0644)) != -1); 65 - write(fd, "Hello World\n", 12); 66 - assert(lseek(fd, 1024*1024*30, SEEK_SET) != -1); 67 - write(fd, "Goodbye Moon\n", 13); 68 - close(fd); 69 - stop_timer(); 70 - } 71 - 72 - void* threadproc(void* state) { 73 - sleep(1); 74 - fprintf(stderr, "cancelling...\n"); 75 - assert(removefile_cancel(state) == 0); 76 - return NULL; 77 - } 78 - 79 - int main(int argc, char *argv[]) { 80 - removefile_state_t state = NULL; 81 - removefile_callback_t callback = NULL; 82 - pthread_t thread = NULL; 83 - int err = 0; 84 - 85 - if (argc == 2) { 86 - /* pass in a directory with a mountpoint under it to test REMOVEFILE_CROSS_MOUNT */ 87 - state = removefile_state_alloc(); 88 - removefile_state_set(state, REMOVEFILE_STATE_ERROR_CALLBACK, removefile_error_callback); 89 - removefile_state_set(state, REMOVEFILE_STATE_ERROR_CONTEXT, (void*)4567); 90 - err = removefile(argv[1], state, REMOVEFILE_CROSS_MOUNT | REMOVEFILE_RECURSIVE); 91 - return err; 92 - } 93 - 94 - mkdirs(); 95 - start_timer("removefile(NULL)"); 96 - assert(removefile("/tmp/removefile-test", NULL, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0); 97 - stop_timer(); 98 - 99 - 100 - mkdirs(); 101 - assert((state = removefile_state_alloc()) != NULL); 102 - assert(pthread_create(&thread, NULL, threadproc, state) == 0); 103 - start_timer("removefile(state) with cancel"); 104 - assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CALLBACK, removefile_error_callback) == 0); 105 - assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CONTEXT, (void*)4567) == 0); 106 - assert(removefile("/tmp/removefile-test", state, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == -1 && errno == ECANCELED); 107 - stop_timer(); 108 - 109 - start_timer("removefile(NULL)"); 110 - assert(removefile("/tmp/removefile-test", NULL, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0); 111 - stop_timer(); 112 - 113 - mkdirs(); 114 - assert(removefile_state_set(state, 1234567, (void*)1234567) == -1 && errno == EINVAL); 115 - 116 - assert(removefile_state_set(state, REMOVEFILE_STATE_CONFIRM_CALLBACK, removefile_confirm_callback) == 0); 117 - assert(removefile_state_get(state, REMOVEFILE_STATE_CONFIRM_CALLBACK, &callback) == 0); 118 - assert(callback == removefile_confirm_callback); 119 - assert(removefile_state_set(state, REMOVEFILE_STATE_CONFIRM_CONTEXT, (void*)1234) == 0); 120 - 121 - assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CALLBACK, removefile_error_callback) == 0); 122 - assert(removefile_state_get(state, REMOVEFILE_STATE_ERROR_CALLBACK, &callback) == 0); 123 - assert(callback == removefile_error_callback); 124 - assert(removefile_state_set(state, REMOVEFILE_STATE_ERROR_CONTEXT, (void*)4567) == 0); 125 - 126 - assert(removefile_state_set(state, REMOVEFILE_STATE_STATUS_CALLBACK, removefile_status_callback) == 0); 127 - assert(removefile_state_get(state, REMOVEFILE_STATE_STATUS_CALLBACK, &callback) == 0); 128 - assert(callback == removefile_status_callback); 129 - assert(removefile_state_set(state, REMOVEFILE_STATE_STATUS_CONTEXT, (void*)5678) == 0); 130 - 131 - start_timer("removefile(state)"); 132 - assert(removefile("/tmp/removefile-test", state, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0); 133 - stop_timer(); 134 - 135 - return 0; 136 - }
-43
src/libremovefile/xcodescripts/install_files.sh
··· 1 - #!/bin/sh 2 - set -e -x 3 - 4 - # don't install man pages for installhdrs or iOS builds 5 - if [ "$ACTION" = installhdrs ]; then exit 0; fi 6 - if [ "${PLATFORM_NAME/iphone/}" != "${PLATFORM_NAME}" ]; then exit 0; fi 7 - 8 - # open source plist 9 - OSV="$DSTROOT"/usr/local/OpenSourceVersions 10 - OSL="$DSTROOT"/usr/local/OpenSourceLicenses 11 - mkdir -p -m 0755 "$OSV" "$OSL" 12 - install -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0444 removefile.plist "$OSV" 13 - install -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0444 LICENSE "$OSL"/removefile.txt 14 - 15 - function InstallManPages() { 16 - for MANPAGE in "$@"; do 17 - SECTION=`basename "${MANPAGE/*./}"` 18 - MANDIR="$DSTROOT"/usr/share/man/man"$SECTION" 19 - install -d -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0755 "$MANDIR" 20 - install -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0444 "$MANPAGE" "$MANDIR" 21 - done 22 - } 23 - 24 - function LinkManPages() { 25 - MANPAGE=`basename "$1"` 26 - SECTION=`basename "${MANPAGE/*./}"` 27 - MANDIR="$DSTROOT"/usr/share/man/man"$SECTION" 28 - shift 29 - for LINK in "$@"; do 30 - ln -hf "$MANDIR/$MANPAGE" "$MANDIR/$LINK" 31 - done 32 - } 33 - 34 - InstallManPages removefile.3 35 - LinkManPages removefile.3 \ 36 - removefile_state_alloc.3 \ 37 - removefile_state_free.3 \ 38 - removefile_state_get.3 \ 39 - removefile_state_set.3 40 - 41 - InstallManPages checkint.3 42 - LinkManPages checkint.3 \ 43 - check_{,u}int{32,64}_{add,sub,mul,div}.3
-10
src/libremovefile/xcodescripts/removefile.xcconfig
··· 1 - #include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig" 2 - 3 - INSTALL_PATH = /usr/lib/system 4 - 5 - PUBLIC_HEADERS_FOLDER_PATH = /usr/include 6 - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include 7 - 8 - BUILD_VARIANTS = normal debug 9 - 10 - PRODUCT_NAME = removefile