| 193 | | - (BOOL)_extractArchivePath:archivePath toDestination:(NSString *)destination pipingDataToCommand:(NSString *)command |
|---|
| 194 | | { |
|---|
| 195 | | // Get the file size. |
|---|
| 196 | | NSNumber *fs = [[[NSFileManager defaultManager] fileAttributesAtPath:archivePath traverseLink:NO] objectForKey:NSFileSize]; |
|---|
| 197 | | if (fs == nil) { return NO; } |
|---|
| 198 | | |
|---|
| 199 | | // Thank you, Allan Odgaard! |
|---|
| 200 | | // (who wrote the following extraction alg.) |
|---|
| 201 | | |
|---|
| 202 | | long current = 0; |
|---|
| 203 | | FILE *fp, *cmdFP; |
|---|
| 204 | | sig_t oldSigPipeHandler = signal(SIGPIPE, SIG_IGN); |
|---|
| 205 | | if ((fp = fopen([archivePath UTF8String], "r"))) |
|---|
| 206 | | { |
|---|
| 207 | | setenv("DESTINATION", [destination fileSystemRepresentation], 1); |
|---|
| 208 | | if ((cmdFP = popen([command cString], "w"))) |
|---|
| 209 | | { |
|---|
| 210 | | char buf[32*1024]; |
|---|
| 211 | | long len; |
|---|
| 212 | | while((len = fread(buf, 1, 32 * 1024, fp))) |
|---|
| 213 | | { |
|---|
| 214 | | current += len; |
|---|
| 215 | | |
|---|
| 216 | | fwrite(buf, 1, len, cmdFP); |
|---|
| 217 | | |
|---|
| 218 | | } |
|---|
| 219 | | pclose(cmdFP); |
|---|
| 220 | | } |
|---|
| 221 | | unsetenv("DESTINATION"); |
|---|
| 222 | | fclose(fp); |
|---|
| 223 | | } |
|---|
| 224 | | signal(SIGPIPE, oldSigPipeHandler); |
|---|
| 225 | | return YES; |
|---|
| | 193 | - (BOOL)_extractArchivePath:archivePath toDestination:(NSString *)destination |
|---|
| | 194 | { |
|---|
| | 195 | BOOL ret = NO; |
|---|
| | 196 | struct stat sb; |
|---|
| | 197 | if(stat([destination fileSystemRepresentation], &sb) != 0) |
|---|
| | 198 | return FALSE; |
|---|
| | 199 | |
|---|
| | 200 | char *buf = NULL; |
|---|
| | 201 | asprintf(&buf, |
|---|
| | 202 | "ditto -x -k --rsrc \"$SRC_ARCHIVE\" \"$DST_PATH\""); |
|---|
| | 203 | if(!buf) |
|---|
| | 204 | return FALSE; |
|---|
| | 205 | |
|---|
| | 206 | setenv("SRC_ARCHIVE", [archivePath fileSystemRepresentation], 1); |
|---|
| | 207 | setenv("DST_PATH", [destination fileSystemRepresentation], 1); |
|---|
| | 208 | |
|---|
| | 209 | int status = system(buf); |
|---|
| | 210 | if(WIFEXITED(status) && WEXITSTATUS(status) == 0) |
|---|
| | 211 | ret = YES; |
|---|
| | 212 | |
|---|
| | 213 | free(buf); |
|---|
| | 214 | unsetenv("SRC_ARCHIVE"); |
|---|
| | 215 | unsetenv("DST_PATH"); |
|---|
| | 216 | return ret; |
|---|