Always bothered me that otaa didn't differentiate between regular files and symlinks, so I wrote a patch. This is the only function I changed:
- Code: Select all
void extractFile (char *File, char *Name, uint32_t Size, uint16_t Perms, char *ExtractCriteria)
{
// MAYBE extract file (depending if matches Criteria, or "*").
// You can modify this to include regexps, case sensitivity, what not.
// presently, it's just strstr()
if(!ExtractCriteria)
return;
if((ExtractCriteria[0] != '*') && !strstr(Name, ExtractCriteria))
return;
// Ok. Extract . This is simple - just dump the file contents to its directory.
// What we need to do here is parse the '/' and mkdir(2), etc.
uint16_t type = Perms & S_IFMT;
Perms &= ~S_IFMT;
if(type != S_IFREG && type != S_IFLNK)
{
fprintf(stderr, "Unknown file type: %o\n", type);
return;
}
char *dirSep = strchr (Name, '/');
while(dirSep)
{
*dirSep = '\0';
mkdir(Name, 0755);
*dirSep = '/';
dirSep += 1;
dirSep = strchr (dirSep, '/');
}
if(type == S_IFLNK)
{
char *target = strndup(File, Size);
if(g_verbose)
{
fprintf(stderr, "Symlinking %s to %s\n", Name, target);
}
symlink(target, Name);
fchmodat(AT_FDCWD, Name, Perms, AT_SYMLINK_NOFOLLOW);
free(target);
}
else
{
// at this point we're out of '/'s
// go back to the last /, if any
if(g_verbose)
{
fprintf(stderr, "Dumping %d bytes to %s\n", Size, Name);
}
int fd = open (Name, O_WRONLY | O_CREAT);
fchmod (fd, Perms);
write (fd, File, Size);
close (fd);
}
} // end extractFile