Any better way to determine if file is executable?
Any better way to determine if file is executable?
- Subject: Any better way to determine if file is executable?
- From: Devon Ferns <email@hidden>
- Date: Tue, 30 Oct 2007 08:04:06 -0400
I've searched the list archives and no one seems to have a good way to
do this.
As discussed before, NSFileManager's isExecutableAtPath: returns YES
for directories and any other file with the execute bit set.
This isn't what I want so I've had to fudge together a solution.
Basically, I'm using NSTask and executing /usr/bin/file on all
suspected executable files and parsing the output for Mach-O.
BTW, can anyone tell me what the program "file" will output for CFM
binaries? I don't know of any that I can test it on to see.
The reason I'm doing this:
This is my first real Cocoa application and it's for a university
assignment. We can use any language we want
so I figured, why not use Cocoa and learn something, which I have
learned quite a lot of already.
The assignment is, take any input directories, parse them recursively
for executables, either applications, dylibs, frameworks, and
do a hash on them. Store this all in an encrypted file.
Change a binary somehow and recompute all the hashes. Determine if
any binary has changed.
My method of using NSTask works just fine, but I'm wondering if
there's a faster method, because launching hundreds
of processes can't be very fast.
It is "fast enough" but takes a few minutes when run against a few
Adobe folders because they have a zillion folders and files
with literally hundreds of executables like frameworks and plugins in
the application bundles.
Here's my code, which I'm running in an NSOperation. I'm using GC, so
forgive if my code doesn't use good non-GC memory
management, however some things I put in just to get the hang of best
practice memory management, even though
I know it won't do anything with GC turned on.
NSFileManager* fileManager = [NSFileManager defaultManager];
NSMutableArray* executables = [[NSMutableArray alloc] init];
NSDirectoryEnumerator* enumerator = [fileManager
enumeratorAtPath:rootPath];
BOOL isEx = NO;
BOOL isDir = NO;
BOOL isSymbolicLink = NO;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
for(NSString* file in enumerator)
{
NSString* fullPath = [NSString stringWithFormat:@"%@/%@", rootPath,
file];
isEx = [fileManager isExecutableFileAtPath:fullPath];
NSDictionary* attributes = [fileManager
fileAttributesAtPath:fullPath traverseLink:NO];
NSString* fileType = [attributes valueForKey:NSFileType];
isDir = [fileType isEqualToString:NSFileTypeDirectory];
isSymbolicLink = [fileType isEqualToString:NSFileTypeSymbolicLink];
//preliminary checks to rule out some files
//directories have the execute bit set so
//some files may be executable but not actually an executable binary
if(isEx && !isDir && !isSymbolicLink)
{
//this will execute the "file" command which will output
//to the command line what the file type is
//can use this to get information about if it's an executable or not
NSTask* theProcess = [[NSTask alloc] init];
[theProcess setLaunchPath:@"/usr/bin/file"];
[theProcess setArguments:[NSArray arrayWithObject:fullPath]];
[theProcess setStandardOutput:[NSPipe pipe]];
[theProcess setStandardError:[theProcess standardOutput]];
[theProcess launch];
[theProcess waitUntilExit];
if([theProcess terminationStatus] == 0)
{
NSData* result = [[[theProcess standardOutput]
fileHandleForReading] readDataToEndOfFile];
NSMutableString* resultText = [[NSMutableString alloc]
initWithData:result encoding:NSUTF8StringEncoding];
NSRange loc = [resultText rangeOfString:@"Mach-O"];
if(loc.length > 0)
{
[executables addObject:fullPath];
//NSLog(fullPath);
NSDictionary* info = [NSDictionary
dictionaryWithObjectsAndKeys:fullPath, @"executable", nil];
if(![self isCancelled])
{
[[NSNotificationCenter defaultCenter]
postNotificationName:FileFound object:nil userInfo:info];
}
}
}
else
NSLog(@"failed to execute shell command");
[theProcess release];
}
}
[pool release];
Hopefully someone has read this far, and knows any better way.
Thanks,
Devon.
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden