Light-Untar-for-iOS
Light-Untar-for-iOS copied to clipboard
Tar file with two files decompresses into four files
The two bogus files have the same names but start with "._"
So listing the directory what I see is:
._FirstFile.ext
._SecondFile.ext
FirstFile.ext
SecondFile.ext
Oddly it didn't happen with a tar with 32 files in it. The only thing that is different is that this file had French names (which shouldn't have mattered).
Stepping through your code I can see it breaking and creating the files with ._
I just decompressed the tar file and there are only two files. I'm at my wits end.
Okay, I've discovered the issue. It appears your code does not handle extended attributes. As such, they end up appearing as separate files when you untar.
Another solution is to use the following when creating the tar file:
COPYFILE_DISABLE=1 tar -cf MyTarFile.tar files*
However this assumes that the user will remember to do this every time. Perhaps a better solution (not great, but better) is to discard files that start with "._" as it appears it is impossible to put such a file in a tar (interesting).
How To Duplicate My Results
-
In the terminal type the following: mkdir MyTar
-
cd to MyTar
-
Create two dummy files (FirstFile.ext and SecondFile.ext).
-
Add attributes using the following line: xattr -w com.apple.metadata:MyAttribute FirstFile.ext
xattr -w com.apple.metadata:MyAttribute SecondFile.ext
-
cd ..
-
tar -cf MyTar.tar MyTar
You now have a tar file that has four items in it, two of which are extended attributes.
Here is my solution. I don't guarantee it being a great solution, but it appears to solve my immediate problem.
Okay, in createFilesAndDirectoriesAtPath:withTarObject:size:error: I modified the code by adding:
if (![[name lastPathComponent] hasPrefix: @"._"])
See below:
case '0': // It's a File
{
NSString *name = [NSFileManager nameForObject:object atOffset:location];
#ifdef TAR_VERBOSE_LOG_MODE
NSLog(@"UNTAR - file - %@", name);
#endif
NSString *filePath = [path stringByAppendingPathComponent:name]; // Create a full path from the name
unsigned long long size = [NSFileManager sizeForObject:object atOffset:location];
if (size == 0) {
#ifdef TAR_VERBOSE_LOG_MODE
NSLog(@"UNTAR - empty_file - %@", filePath);
#endif
[@"" writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:error];
break;
}
blockCount += (size - 1) / TAR_BLOCK_SIZE + 1; // size/TAR_BLOCK_SIZE rounded up
// [self writeFileDataForObject:object inRange:NSMakeRange(location+TAR_BLOCK_SIZE, size) atPath:filePath];
if (![[name lastPathComponent] hasPrefix: @"._"]) //// **ADDED THIS LINE**
[self writeFileDataForObject:object atLocation:(location + TAR_BLOCK_SIZE) withLength:size atPath:filePath];
break;
}
Note that it appears ONLY bsdtar allows extended attributes. So if you were using gnutar you probably didn't see this problem.