Created
February 5, 2010 01:58
-
-
Save atr000/295406 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <CoreServices/CoreServices.h> | |
#import <unistd.h> | |
#import <sys/stat.h> | |
#import <time.h> | |
#define manager [NSFileManager defaultManager] | |
char *returnString=NULL; | |
char *returnSize(long theSize) | |
{ | |
float mySize=theSize; | |
if (returnString != NULL) { | |
free(returnString); | |
returnString=NULL; | |
} | |
returnString=malloc(10); | |
//KB | |
mySize=(mySize / (float)1024); | |
if (mySize > 1024) { | |
//MB | |
mySize=(mySize / (float)1024); | |
if (mySize > 1024) { | |
//GB | |
mySize=(mySize / (float)1024); | |
sprintf(returnString, "%.2f GB", mySize); | |
} else { | |
sprintf(returnString, "%.2f MB", mySize); | |
} | |
} else { | |
sprintf(returnString, "%.2f KB", mySize); | |
} | |
if (mySize < 1) { | |
mySize=theSize; | |
sprintf(returnString, "%.2f Bytes", mySize); | |
} | |
return returnString; | |
} | |
void xstat(NSString *theFile, BOOL hfs) | |
{ | |
NSDictionary *attrs; | |
NSNumber *fileSize, *identifier, *devIdentifier, *permissions, *hfsExtension, *creator, *type, *links, *ownerID, *groupID; | |
NSString *owner, *group, *fileType, *fileName, *permString, *filePrint; | |
NSDate *createDate, *modifyDate; | |
char access[10]; | |
char linkName[256]; | |
char theFileName[PATH_MAX]; | |
long int tfirst,tsecond,tthird,cfirst,csecond,cthird; | |
struct stat stats; | |
FSRef theRef; | |
FSCatalogInfo catInfo; | |
FSSpec theSpec; | |
Boolean isDir, isAlias, dirFlag=0; | |
FInfo *finderInfo=NULL; | |
long physDataSize, realDataSize, physRsrcSize, realRsrcSize; | |
OSErr theErr=0; | |
OSStatus theStatus=0; | |
int i; | |
fileName=theFile; | |
if ([fileName characterAtIndex:0] == '~') { | |
fileName=[fileName stringByExpandingTildeInPath]; | |
} | |
strcpy(theFileName,[fileName fileSystemRepresentation]); | |
i=lstat(theFileName,&stats); | |
if (i == -1) { | |
printf("%s: No such file or directory\n",theFileName); | |
return; | |
} | |
attrs=[manager fileAttributesAtPath:fileName traverseLink:NO]; | |
fileSize=[attrs objectForKey:NSFileSize]; | |
owner=[attrs objectForKey:NSFileOwnerAccountName]; | |
ownerID=[attrs objectForKey:NSFileOwnerAccountID]; | |
group=[attrs objectForKey:NSFileGroupOwnerAccountName]; | |
groupID=[attrs objectForKey:NSFileGroupOwnerAccountID]; | |
links=[attrs objectForKey:NSFileReferenceCount]; | |
identifier=[attrs objectForKey:NSFileSystemFileNumber]; | |
devIdentifier=[attrs objectForKey:NSFileSystemNumber]; | |
permissions=[attrs objectForKey:NSFilePosixPermissions]; | |
permString=[NSString stringWithFormat:@"%04o",[permissions intValue]]; | |
fileType=[attrs objectForKey:NSFileType]; | |
hfsExtension=[attrs objectForKey:NSFileExtensionHidden]; | |
creator=[attrs objectForKey:NSFileHFSCreatorCode]; | |
type=[attrs objectForKey:NSFileHFSTypeCode]; | |
createDate=[attrs objectForKey:NSFileCreationDate]; | |
modifyDate=[attrs objectForKey:NSFileModificationDate]; | |
access[10]='\0'; | |
access[9] = (stats.st_mode & S_IXOTH) ? ((stats.st_mode & S_ISVTX) ? 't' : 'x') : ((stats.st_mode & S_ISVTX) ? 'T' : '-'); | |
access[8] = (stats.st_mode & S_IWOTH) ? 'w' : '-'; | |
access[7] = (stats.st_mode & S_IROTH) ? 'r' : '-'; | |
access[6] = (stats.st_mode & S_IXGRP) ? ((stats.st_mode & S_ISGID) ? 's' : 'x') : ((stats.st_mode & S_ISGID) ? 'S' : '-'); | |
access[5] = (stats.st_mode & S_IWGRP) ? 'w' : '-'; | |
access[4] = (stats.st_mode & S_IRGRP) ? 'r' : '-'; | |
access[3] = (stats.st_mode & S_IXUSR) ? ((stats.st_mode & S_ISUID) ? 's' : 'x') : ((stats.st_mode & S_ISUID) ? 'S' : '-'); | |
access[2] = (stats.st_mode & S_IWUSR) ? 'w' : '-'; | |
access[1] = (stats.st_mode & S_IRUSR) ? 'r' : '-'; | |
switch (stats.st_mode & S_IFMT) { | |
case S_IFDIR: | |
access[0] = 'd'; | |
filePrint=@"Directory"; | |
break; | |
case S_IFCHR: | |
access[0] = 'c'; | |
filePrint=@"Character Device"; | |
break; | |
case S_IFBLK: | |
access[0] = 'b'; | |
filePrint=@"Block Device"; | |
break; | |
case S_IFREG: | |
access[0] = '-'; | |
filePrint=@"Regular File"; | |
break; | |
case S_IFLNK: | |
access[0] = 'l'; | |
filePrint=@"Symbolic Link"; | |
break; | |
case S_IFSOCK: | |
access[0] = 's'; | |
filePrint=@"Socket"; | |
break; | |
case S_IFIFO: | |
access[0] = 'p'; | |
filePrint=@"FIFO File"; | |
break; | |
default: | |
access[0] = '?'; | |
filePrint=@"Unknown Type"; | |
break; | |
} | |
theStatus=FSPathMakeRef(theFileName,&theRef,NULL); | |
if (theStatus != 0) { | |
goto UnixEnd; | |
} | |
theErr=FSGetCatalogInfo(&theRef, kFSCatInfoDataSizes | kFSCatInfoRsrcSizes | kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catInfo, NULL, &theSpec, NULL); | |
if (theErr != 0) { | |
goto UnixEnd; | |
} | |
isDir=((catInfo.nodeFlags & kFSNodeIsDirectoryMask) != 0); | |
physDataSize=(catInfo.dataPhysicalSize); | |
realDataSize=(catInfo.dataLogicalSize); | |
physRsrcSize=(catInfo.rsrcPhysicalSize); | |
realRsrcSize=(catInfo.rsrcLogicalSize); | |
finderInfo=(FInfo *)catInfo.finderInfo; | |
FSIsAliasFile(&theRef,&isAlias,&dirFlag); | |
if ((stats.st_mode & S_IFMT) == S_IFLNK) { | |
int i; | |
if ((i=readlink(theFileName,linkName, 256)) == -1) { | |
printf("Error reading file\n"); | |
return; | |
} | |
linkName[(i >= 256) ? 255 : i]='\0'; | |
printf("File: \"%s\" -> \"%s\"\n",theFileName,linkName); | |
} else if (isAlias) { | |
short refNum=0; | |
AliasHandle theAlias=NULL; | |
ResType aliasRes='alis'; | |
Boolean wasChanged; | |
FSRef targetRef; | |
char returnedPath[PATH_MAX + 1]; | |
OSErr aliasErr=0; | |
OSStatus aliasStatus=0; | |
filePrint=@"Alias"; | |
refNum=FSpOpenResFile(&theSpec, fsRdWrShPerm); | |
if (refNum <= 0) { goto SafeEnd; } | |
theAlias = (AliasHandle)Get1Resource(aliasRes,0); | |
if (theAlias == NULL) { goto SafeEnd; } | |
aliasErr=FSFollowFinderAlias(&theRef, theAlias, false, &targetRef, &wasChanged); | |
if (aliasErr != 0) { | |
printf("File: \"%s\" -> (Error reading alias: %d)\n",theFileName,aliasErr); | |
CloseResFile(refNum); | |
goto SafeEnd; | |
} | |
aliasStatus=FSRefMakePath(&targetRef, (UInt8 *)&returnedPath, PATH_MAX); | |
if (aliasStatus != 0) { | |
printf("File: \"%s\" -> (Could not locate original)\n",theFileName); | |
CloseResFile(refNum); | |
goto SafeEnd; | |
} | |
printf("File: \"%s\" -> \"%s\"\n",theFileName, returnedPath); | |
CloseResFile(refNum); | |
} else { | |
printf("File: \"%s\"\n",theFileName); | |
} | |
SafeEnd: | |
printf("IO Block : %d Blocks: %u ", (int)stats.st_blksize, (unsigned int)stats.st_blocks); | |
printf("Device: %d,%d Inode: %d Links: %d\n", major([devIdentifier intValue]), minor([devIdentifier intValue]), [identifier intValue], [links intValue]); | |
printf("File Type : %s\n", [filePrint UTF8String]); | |
if (!isDir) { | |
printf("Disk Size : %s ",returnSize((physDataSize + physRsrcSize))); | |
if ((physRsrcSize > 0) && (physDataSize > 0)) { | |
printf("(Rsrc Fork: %s ", returnSize(physRsrcSize)); | |
printf("/ Data Fork: %s)\n", returnSize(physDataSize)); | |
} else if (physRsrcSize > 0) { | |
printf("(Rsrc Fork)\n"); | |
} else { | |
printf ("(Data Fork)\n"); | |
} | |
printf("Real Size : %s ",returnSize((realDataSize + realRsrcSize))); | |
if ((realRsrcSize > 0) && (realDataSize > 0)) { | |
printf("(Rsrc Fork: %s ", returnSize(realRsrcSize)); | |
printf("/ Data Fork: %s)\n", returnSize(realDataSize)); | |
} else if (realRsrcSize > 0) { | |
printf("(Rsrc Fork)\n"); | |
} else { | |
printf("(Data Fork)\n"); | |
} | |
free(returnString); | |
returnString=NULL; | |
} | |
printf("Permissions : (%s/%10.10s)\n", [permString UTF8String], access); | |
printf("Owner : (%i / %s)\nGroup : (%i / %s)\n", [ownerID intValue], [owner UTF8String], [groupID intValue], [group UTF8String]); | |
printf("Attributes : "); | |
printf("%s",isAlias ? "A" : "a"); | |
printf("%s",((finderInfo->fdFlags & kIsInvisible) != 0) ? "V" : "v"); | |
printf("%s",(((finderInfo->fdFlags & kHasBundle) != 0) && !isDir) ? "B" : "b"); | |
printf("%s",(((finderInfo->fdFlags & kIsStationery) != 0) && !isDir) ? "T" : "t"); | |
printf("%s",((finderInfo->fdFlags & kHasCustomIcon) != 0) ? "C" : "c"); | |
printf("%s",((finderInfo->fdFlags & kNameLocked) != 0) ? "L" : "l"); | |
printf("%s",((finderInfo->fdFlags & kHasBeenInited) !=0) ? "I" : "i"); | |
printf("%s",((finderInfo->fdFlags & kHasNoINITs) != 0) ? "N" : "n"); | |
printf("%s",((finderInfo->fdFlags & kIsShared) != 0) ? "M" : "m"); | |
printf("%s",[hfsExtension boolValue] ? "E" : "e"); | |
printf("%s",((finderInfo->fdFlags & kIsOnDesk) != 0) ? "D" : "d"); | |
printf("\n"); | |
// printf("Extension Hidden: %s\n",[hfsExtension boolValue] ? "Yes" : "No"); | |
printf("Creation Date : %s\n",[[createDate descriptionWithCalendarFormat:@"%a %b %e %H:%M:%S %Y" timeZone:nil locale:nil]UTF8String]); | |
printf("Last Modified : %s\n",[[modifyDate descriptionWithCalendarFormat:@"%a %b %e %H:%M:%S %Y" timeZone:nil locale:nil]UTF8String]); | |
printf("Last accessed : %s\n", [[[NSDate dateWithTimeIntervalSince1970:stats.st_atime] descriptionWithCalendarFormat:@"%a %b %e %H:%M:%S %Y" timeZone:nil locale:nil]UTF8String]); | |
printf("Last changed : %s\n", [[[NSDate dateWithTimeIntervalSince1970:stats.st_ctime] descriptionWithCalendarFormat:@"%a %b %e %H:%M:%S %Y" timeZone:nil locale:nil]UTF8String]); | |
if ([creator unsignedLongValue] > 0) { | |
tthird = [type unsignedLongValue] >> 8; | |
tsecond = tthird >> 8; | |
tfirst = tsecond >> 8; | |
cthird = [creator unsignedLongValue] >> 8; | |
csecond = cthird >> 8; | |
cfirst = csecond >> 8; | |
printf("Type : %c%c%c%c\nCreator : %c%c%c%c\n", (int)tfirst, (int)tsecond, (int)tthird, [type intValue], (int)cfirst, (int)csecond, (int)cthird, [creator intValue]); | |
} | |
return; | |
UnixEnd: | |
if ((stats.st_mode & S_IFMT) == S_IFLNK) { | |
int i; | |
if ((i=readlink(theFileName,linkName, 256)) == -1) { | |
printf("Error reading file\n"); | |
return; | |
} | |
linkName[(i >= 256) ? 255 : i]='\0'; | |
printf("File: \"%s\" -> \"%s\"\n",theFileName,linkName); | |
} else { | |
printf("File: \"%s\"\n", theFileName); | |
} | |
printf("IO Block : %d Blocks: %u Device: %d,%d Inode: %d Links: %d\n", (unsigned int)stats.st_blocks, (int)stats.st_blksize, major([devIdentifier intValue]), minor([devIdentifier intValue]), [identifier intValue], [links intValue]); | |
printf("File Type : %s\n", [filePrint UTF8String]); | |
if (!((stats.st_mode & S_IFMT) == S_IFDIR)) { | |
printf("Real Size : %s\n", returnSize([fileSize longValue])); | |
} | |
printf("Permissions : (%s/%s)\n", [permString UTF8String], access); | |
printf("Owner : (%i / %s)\n", [ownerID intValue], [owner UTF8String]); | |
printf("Group : (%i / %s)\n", [groupID intValue], [group UTF8String]); | |
printf("Ext Hidden : %s\n", [hfsExtension boolValue] ? "Yes" : "No"); | |
printf("Creation Date : %s\n", [[createDate descriptionWithCalendarFormat:@"%a %b %d %H:%M:%S %Y" timeZone:nil locale:nil]UTF8String]); | |
printf("Last Modified : %s\n", [[modifyDate descriptionWithCalendarFormat:@"%a %b %d %H:%M:%S %Y" timeZone:nil locale:nil]UTF8String]); | |
printf("Last accessed : %s\n", [[[NSDate dateWithTimeIntervalSince1970:stats.st_atime] descriptionWithCalendarFormat:@"%a %b %d %H:%M:%S %Z %Y" timeZone:nil locale:nil]UTF8String]); | |
printf("Last changed : %s", ctime(&stats.st_ctime)); | |
if ([creator unsignedLongValue] > 0) { | |
tthird = [type unsignedLongValue] >> 8; | |
tsecond = tthird >> 8; | |
tfirst = tsecond >> 8; | |
cthird = [creator unsignedLongValue] >> 8; | |
csecond = cthird >> 8; | |
cfirst = csecond >> 8; | |
printf("Type : %c%c%c%c\nCreator : %c%c%c%c\n", (int)tfirst, (int)tsecond, (int)tthird, [type intValue], (int)cfirst, (int)csecond, (int)cthird, [creator intValue]); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init]; | |
NSString *file; | |
int c,i; | |
BOOL hfs=NO; | |
if (argc == 1) { | |
printf("USAGE: %s [-v] [-h] FILENAME\n\n",argv[0]); | |
[pool release]; | |
return 1; | |
} | |
while ((c=getopt(argc, argv, "vh?")) != EOF) { | |
switch (c) { | |
case 'v': | |
printf("%s version 0.1.2\n\tCopyright 2003 - 2004 Night Productions\n\n",argv[0]); | |
return 0; | |
break; | |
case 'h': | |
printf("USAGE: %s [-h] [-v] FILENAME\n\n",argv[0]); | |
printf("\t-h:\tThis help screen.\n"); | |
printf("\t-v:\tPrints out version information about xstat.\n\n"); | |
printf("\t(Attributes:)\n"); | |
printf("\t\ta - alias file\n"); | |
printf("\t\tv - invisible\n"); | |
printf("\t\tb - bundle\n"); | |
printf("\t\tt - stationary\n"); | |
printf("\t\tc - custom icon\n"); | |
printf("\t\tl - locked\n"); | |
printf("\t\ti - inited\n"); | |
printf("\t\tn - has no INITs\n"); | |
printf("\t\tm - shared file\n"); | |
printf("\t\te - extension hidden\n"); | |
printf("\t\td - desktop\n"); | |
printf("\t(lowercase means 'off/no', uppercase means 'on/yes')\n"); | |
printf("\n"); | |
[pool release]; | |
return 0; | |
break; | |
default: | |
printf("USAGE: %s [-h] [-v] FILENAME\n\n",argv[0]); | |
[pool release]; | |
return 1; | |
break; | |
} | |
} | |
for (i= optind; i < argc; i++) { | |
file=[NSString stringWithUTF8String:argv[i]]; | |
xstat(file,hfs); | |
file=nil; | |
} | |
[pool release]; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment