this repo has no description
1
fork

Configure Feed

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

Incomplete PKSignedContainer code, used even by some non-Apple utilities

+318 -4
+9
src/private-frameworks/PackageKit/CMakeLists.txt
··· 1 1 project(PackageKit) 2 2 3 + include_directories( 4 + ${CMAKE_SOURCE_DIR}/src/external/libarchive/libarchive 5 + ) 6 + 7 + add_definitions(-fobjc-arc) 8 + 3 9 set(pk_sources 4 10 src/functions.c 5 11 src/PKAddExtendedAttributesInstallOperation.m ··· 135 141 DEPENDENCIES 136 142 system 137 143 Foundation 144 + xar 145 + archive 146 + lzma 138 147 ) 139 148
+31
src/private-frameworks/PackageKit/include/PackageKit/PKSignedContainer.h
··· 17 17 along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 18 */ 19 19 20 + #import <Foundation/NSString.h> 21 + #import <Foundation/NSURL.h> 22 + #import <Foundation/NSError.h> 23 + #import <dispatch/dispatch.h> 24 + #import <xar/xar.h> 25 + #import <libarchive/archive.h> 26 + #import <lzma.h> 27 + #import <pthread.h> 28 + 20 29 @interface PKSignedContainer : NSObject 30 + { 31 + xar_t _xar; 32 + xar_file_t _xar_file; 33 + xar_stream _xar_stream; 34 + struct archive* _archive; 35 + lzma_stream _zs; 36 + uint64_t _blockLength, _flags; 37 + 38 + char _inbuf[4096]; 39 + char _outbuf[4096 * 1024]; 40 + BOOL _abort; 41 + } 42 + 43 + - (instancetype)initForReadingFromContainerAtURL:(NSURL *)url 44 + error:(NSError **)error; 45 + 46 + - (void)startUnarchivingAtPath:(NSString *)path 47 + notifyOnQueue:(dispatch_queue_t)queue 48 + progress:(void (^)(double, NSString *))progressBlock 49 + finish:(void (^)(BOOL))finishBlock; 50 + 51 + - (xar_stream*)_xarStream; 21 52 22 53 @end
+278 -4
src/private-frameworks/PackageKit/src/PKSignedContainer.m
··· 18 18 */ 19 19 20 20 #import <PackageKit/PackageKit.h> 21 + #include <stdlib.h> 22 + #include <string.h> 23 + #include <unistd.h> 24 + #include <fcntl.h> 25 + #include <pthread/private.h> 26 + 27 + static int open_cb(struct archive *a, void *_client_data) 28 + { 29 + return ARCHIVE_OK; 30 + } 31 + 32 + static int close_cb(struct archive *a, void *_client_data) 33 + { 34 + return ARCHIVE_OK; 35 + } 36 + 37 + struct ReadContext 38 + { 39 + xar_stream* xs; 40 + uint64_t blockLength; 41 + 42 + char inbuf[4096]; 43 + char outbuf[4096 * 1024]; 44 + }; 45 + 46 + static ssize_t read_cb(struct archive *a, void *_client_data, const void **_buffer) 47 + { 48 + struct ReadContext* rc = (struct ReadContext*) _client_data; 49 + 50 + if (!rc->blockLength) 51 + { 52 + // TODO 53 + } 54 + } 55 + 56 + static NSError* makeError(NSURL* url, NSString* errorString) 57 + { 58 + NSDictionary* userInfo = @{ 59 + NSLocalizedDescriptionKey: errorString, 60 + NSFilePathErrorKey: [url absoluteString] 61 + }; 62 + return [[NSError alloc] initWithDomain:@"PackageKit" 63 + code: 0 64 + userInfo: userInfo]; 65 + } 66 + 67 + static inline BOOL xar_read(char *buffer, uint32_t size, xar_stream *stream) { 68 + stream->next_out = buffer; 69 + stream->avail_out = size; 70 + while (stream->avail_out) 71 + { 72 + if (xar_extract_tostream(stream) != XAR_STREAM_OK) 73 + return NO; 74 + } 75 + return YES; 76 + } 77 + 78 + static inline uint64_t xar_read_64(xar_stream *stream) { 79 + char t[8]; 80 + xar_read(t, 8, stream); 81 + return __builtin_bswap64(*(uint64_t *)t); 82 + } 83 + 84 + static int copy_data(struct archive *ar, struct archive *aw) 85 + { 86 + int r; 87 + const void *buff; 88 + size_t size; 89 + off_t offset; 90 + 91 + for (;;) 92 + { 93 + r = archive_read_data_block(ar, &buff, &size, &offset); 94 + if (r == ARCHIVE_EOF) 95 + return (ARCHIVE_OK); 96 + if (r != ARCHIVE_OK) 97 + return (r); 98 + r = archive_write_data_block(aw, buff, size, offset); 99 + if (r != ARCHIVE_OK) 100 + { 101 + NSLog(@"archive_write_data_block error\n"); 102 + return (r); 103 + } 104 + } 105 + } 21 106 22 107 @implementation PKSignedContainer 23 108 24 - - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 25 - return [NSMethodSignature signatureWithObjCTypes: "v@:"]; 109 + - (instancetype)initForReadingFromContainerAtURL:(NSURL *)url 110 + error:(NSError **)error 111 + { 112 + const char* path = [url fileSystemRepresentation]; 113 + 114 + _xar = xar_open(path, READ); 115 + 116 + if (!_xar) 117 + { 118 + *error = makeError(url, @"Cannot open input XIP (XAR error)"); 119 + return nil; 120 + } 121 + 122 + xar_iter_t i = xar_iter_new(); 123 + _xar_file = xar_file_first(_xar, i); 124 + char *xarPath; 125 + 126 + while (strncmp((xarPath = xar_get_path(_xar_file)), "Content", 7) && (_xar_file = xar_file_next(i))) 127 + free(xarPath); 128 + 129 + free(xarPath); 130 + xar_iter_free(i); 131 + 132 + if (!_xar_file) 133 + { 134 + *error = makeError(url, @"Not a XIP, 'Content' not found"); 135 + return nil; 136 + } 137 + 138 + if (xar_verify(_xar, _xar_file) != XAR_STREAM_OK) 139 + { 140 + *error = makeError(url, @"xar_verify failed"); 141 + return nil; 142 + } 143 + 144 + if (xar_extract_tostream_init(_xar, _xar_file, &_xar_stream) != XAR_STREAM_OK) 145 + { 146 + *error = makeError(url, @"XAR init failed"); 147 + return nil; 148 + } 149 + 150 + char header[4]; 151 + xar_read(header, sizeof(header), &_xar_stream); 152 + 153 + if (strncmp(header, "pbzx", 4) != 0) 154 + { 155 + *error = makeError(url, @"Not a pbzx stream"); 156 + return nil; 157 + } 158 + 159 + xar_extract_tostream_end(&_xar_stream); 160 + 161 + return self; 26 162 } 27 163 28 - - (void)forwardInvocation:(NSInvocation *)anInvocation { 29 - NSLog(@"Stub called: %@ in %@", NSStringFromSelector([anInvocation selector]), [self class]); 164 + - (void)dealloc 165 + { 166 + lzma_end(&_zs); 167 + 168 + if (_xar) 169 + xar_close(_xar); 170 + if (_archive) 171 + archive_read_finish(_archive); 172 + } 173 + 174 + - (void)cancelOperation:(id)arg1 175 + { 176 + _abort = YES; 177 + } 178 + 179 + - (void)startUnarchivingAtPath:(NSString *)path 180 + notifyOnQueue:(dispatch_queue_t)queue 181 + progress:(void (^)(double, NSString *))progressBlock 182 + finish:(void (^)(BOOL))finishBlock 183 + { 184 + if (_archive) 185 + { 186 + NSLog(@"PackageKit: Unarchiving already in progress\n"); 187 + dispatch_async(queue, ^{ 188 + finishBlock(NO); 189 + }); 190 + return; 191 + } 192 + 193 + int dfd = open([path UTF8String], O_RDONLY | O_DIRECTORY); 194 + if (dfd == -1) 195 + { 196 + NSLog(@"PackageKit: target directory cannot be opened\n"); 197 + dispatch_async(queue, ^{ 198 + finishBlock(NO); 199 + }); 200 + return; 201 + } 202 + 203 + if (lzma_stream_decoder(&_zs, UINT64_MAX, LZMA_CONCATENATED) != LZMA_OK) 204 + { 205 + close(dfd); 206 + NSLog(@"PackageKit: LZMA init failed\n"); 207 + dispatch_async(queue, ^{ 208 + finishBlock(NO); 209 + }); 210 + return; 211 + } 212 + 213 + char header[4]; 214 + xar_read(header, sizeof(header), &_xar_stream); 215 + _flags = xar_read_64(&_xar_stream); 216 + 217 + _archive = archive_read_new(); 218 + 219 + archive_read_support_format_cpio(_archive); 220 + 221 + dispatch_queue_t q = dispatch_queue_create("org.darlinghq.PackageKit", NULL); 222 + 223 + _abort = NO; 224 + dispatch_async(q, ^{ 225 + BOOL result = YES; 226 + struct ReadContext* rc = (struct ReadContext*) malloc(sizeof(struct ReadContext)); 227 + 228 + rc->xs = &_xar_stream; 229 + rc->blockLength = 0; 230 + 231 + pthread_fchdir_np(dfd); 232 + close(dfd); 233 + 234 + int err = archive_read_open(_archive, (__bridge void*) self, open_cb, read_cb, close_cb); 235 + if (err != ARCHIVE_OK) 236 + { 237 + NSLog(@"archive_read_open error\n"); 238 + result = NO; 239 + goto out; 240 + } 241 + 242 + struct archive* ext = archive_write_disk_new(); 243 + 244 + while (!_abort) 245 + { 246 + struct archive_entry *entry; 247 + int r = archive_read_next_header(_archive, &entry); 248 + 249 + if (r == ARCHIVE_EOF) 250 + break; 251 + 252 + if (r != ARCHIVE_OK) 253 + { 254 + NSLog(@"archive_read_next_header failed\n"); 255 + result = NO; 256 + break; 257 + } 258 + 259 + r = archive_write_header(ext, entry); 260 + if (r != ARCHIVE_OK) 261 + { 262 + NSLog(@"archive_write_header failed\n"); 263 + result = NO; 264 + break; 265 + } 266 + r = copy_data(_archive, ext); 267 + if (r != ARCHIVE_OK) 268 + { 269 + NSLog(@"failed to write data\n"); 270 + result = NO; 271 + break; 272 + } 273 + 274 + r = archive_write_finish_entry(ext); 275 + if (r != ARCHIVE_OK) 276 + { 277 + NSLog(@"archive_write_finish_entry failed\n"); 278 + result = NO; 279 + break; 280 + } 281 + 282 + // TODO: report progress 283 + } 284 + 285 + out: 286 + archive_write_finish(ext); 287 + archive_read_close(_archive); 288 + archive_read_finish(_archive); 289 + _archive = NULL; 290 + free(rc); 291 + pthread_fchdir_np(-1); 292 + 293 + dispatch_async(queue, ^{ 294 + finishBlock(result); 295 + }); 296 + }); 297 + 298 + dispatch_release(q); 299 + } 300 + 301 + - (xar_stream*)_xarStream 302 + { 303 + return &_xar_stream; 30 304 } 31 305 32 306 @end