diff --git a/.gitignore b/.gitignore index 634b036..9970600 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ geticon/geticon seticon/seticon wsupdate/wsupdate -fileinfo/fileinfo +finfo/finfo getfcomment/getfcomment hfsdata/hfsdata lsmac/lsmac diff --git a/CHANGES.txt b/CHANGES.txt old mode 100755 new mode 100644 index d831778..2af7d41 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,23 @@ +This is a very incomplete list of changes. Some of the individual code +files contain more information. Git commit history and previous CVS +repository on SourceForge show the actual history of development. + +-- + +Version 1.8 by Dave Vasilevsky + +I have updated it to work on 64-bit systems and modern versions of Mac OS X. + +- Wrote Makefile, since xcodeproj files are fragile +- Replaced or rewrote deprecated functions +- Rewrote 'trash' so it properly renames files +- Getting OS 9 comments is not possible on OS X 10.5 and later +- wsupdate is probably useless on modern systems + +Tested on Mac OS X 10.7 Lion. I'd appreciate if anybody wants to test on other versions as well. + +-- + Version 1.7 Release notes Some new tools: diff --git a/Makefile b/Makefile index 7fda587..347d72e 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,15 @@ -OPT = -O0 -g +OPT = -w ARCH = MY_CFLAGS = -fpascal-strings -WARN = -w - -NAMES_CARBON = fileinfo getfcomment hfsdata lsmac mkalias setfcomment setfctypes setfflags setlabel setsuffix +NAMES_CARBON = finfo getfcomment hfsdata lsmac mkalias setfcomment setfctypes setfflags setlabel setsuffix NAMES_COCOA = geticon seticon wsupdate -NAMES_SCRIPT = cpath google osxutils rcmac getvolume setvolume trash wiki +NAMES_SCRIPT = cpath google osxutils rcmac getvolume setvolume mvtrash wikipedia NAMES = $(NAMES_CARBON) $(NAMES_COCOA) PROGRAMS = $(foreach name,$(NAMES),$(name)/$(name)) SCRIPTS = $(foreach name,$(NAMES_SCRIPT),$(name)/$(name)) MANPAGES = $(wildcard */*.1) - all: $(NAMES) clean: @@ -21,7 +18,6 @@ clean: .PHONY: all clean install install install-man install-bin $(NAMES) - PREFIX=$(DESTDIR)/usr/local BINDIR=$(PREFIX)/bin MANDIR=$(PREFIX)/share/man/man1 @@ -36,9 +32,8 @@ install-man: $(MANPAGES) install: install-bin install-man - ARCH_FLAG = $(if $(ARCH),-arch $(ARCH),) -COMPILER = $(CC) $(ARCH_FLAG) $(OPT) $(WARN) +COMPILER = $(CC) $(ARCH_FLAG) $(OPT) COMPILE = $(COMPILER) $(MY_CFLAGS) $(CFLAGS) %.o: %.c diff --git a/README b/README deleted file mode 100644 index fa88302..0000000 --- a/README +++ /dev/null @@ -1,17 +0,0 @@ -osxutils is a bundle of Mac OS X command line utilities that bring power over all sorts of Mac-specific information, settings and meta-data to the command line. - -Documentation: http://sveinbjorn.org/osxutils_docs -SourceForge: http://sourceforge.net/projects/osxutils/ - - -osxutils is written by Sveinbjorn Thordarson. I have updated it to work on 64-bit systems and modern versions of Mac OS X. Change notes: - -- Wrote Makefile, since xcodeproj files are fragile -- Replaced or rewrote deprecated functions -- Rewrote 'trash' so it properly renames files -- Getting OS 9 comments is not possible on OS X 10.5 and later -- wsupdate is probably useless on modern systems - -Tested on Mac OS X 10.7 Lion. I'd appreciate if anybody wants to test on other versions as well. - --Dave Vasilevsky diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7ccbbb --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# osxutils + +A collection of MacOS X command line utilities, based on the [original project](http://sveinbjorn.org/osxutils_docs) by [Sveinbjorn Thordarson](https://github.com/sveinbjornt). \ No newline at end of file diff --git a/cpath/cpath.1 b/cpath/cpath.1 index b81b262..17eace2 100755 --- a/cpath/cpath.1 +++ b/cpath/cpath.1 @@ -1,35 +1,24 @@ -.Dd Tue Apr 01 2003 +.Dd April 9, 2015 .Dt cpath 1 .Os Darwin .Sh NAME .Nm cpath -.Nd Copies current working directory path to the MacOS clipboard -.Sh SYNOPSIS +.Nd copy the current working directory path to the MacOS clipboard +.Sh SYNOPSIS .Nm -.Op Fl vh .Sh DESCRIPTION -cpath will copy the path returned by the getcwd() function into the MacOS clipboard. It +.Nm +will copy the path returned by the getcwd() function into the MacOS clipboard. It is more convenient than: -.Pp -# pwd | pbcopy +.Pp +.Dl pwd | pbcopy .Pp because it doesn't copy any newline character, which means you can paste the copied path into a terminal application without trying to execute it. -.Bl -tag -width indent -.It Fl v -Prints version and author. -.It Fl h -Prints help/usage. -.El -.Sh FILES +.Sh FILES .Bl -tag -width "/usr/local/bin/cpath" -compact .It Pa /usr/local/bin/cpath .El -.Sh SEE ALSO -.Xr lsmac 1 , -.Xr setfctypes 1 , -.Xr setfflags 1 , -.Xr mkalias 1 , -.Xr setsuffix 1 , -.Xr SetFile 1 , -.Xr setfcomment 1 +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . diff --git a/fileinfo/fileinfo.1 b/fileinfo/fileinfo.1 deleted file mode 100644 index 83e7d59..0000000 --- a/fileinfo/fileinfo.1 +++ /dev/null @@ -1,55 +0,0 @@ -.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. -.\"See Also: -.\"man mdoc.samples for a complete listing of options -.\"man mdoc for the short list of editing options -.\"/usr/share/misc/mdoc.template -.Dd Mon Jan 05 2004 \" DATE -.Dt fileinfo 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm fileinfo, -.\" The following lines are read in generating the apropos(man -k) database. Use only key -.\" words here as the database is built based on the words here and in the .ND line. . -.\" Use .Nm macro to designate other names for the documented program. -.Nd Print information about a file in a style similar to the Mac OS X Finder -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vh \" [-vh] -.Op Ar \" [file ...] -.Sh DESCRIPTION \" Section Header - required - don't modify -.Nm -is a program for printing all sorts of information about a file in a style similar to the -Mac OS X Finder Get Info window. It lists all sorts of Mac OS-specific metadata information. -.Pp -A list of flags accpeted by fileinfo and their descriptions: -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl v \"-a flag as a list item -Prints program version -.It Fl h -Prints a short usage help string -.El \" Ends the list -.Pp -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/fileinfo" -compact -.It Pa /usr/local/bin/fileinfo -.El -.\" .Sh DIAGNOSTICS \" May not be needed -.\" .Bl -diag -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr lsmac 1 , -.Xr setfflags 1 , -.Xr seticon 1 , -.Xr geticon 1 , -.Xr setfctypes 1 , -.Xr setfcomment 1 , -.Xr setlabel 1 -.\" .Sh BUGS \" Document known, unremedied bugs -.\" .Sh HISTORY \" Document history if command behaves in a unique manner - diff --git a/fileinfo/fileinfo.c b/fileinfo/fileinfo.c deleted file mode 100644 index da9e9b8..0000000 --- a/fileinfo/fileinfo.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - fileinfo - list info about files in MacOS X - Copyright (C) 2003 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/* - - ATTENTION! - - This code is very buggy and incomplete....my apologies :) -*/ - -/* - Version History - - Version 0.1 - fileinfo released despite bugs, flaws, shortcomings, etc -*/ - -/* Todo - - * Clean up the messy code - * Fix a lot of loose ends - * Serious error checking - * Finder comment retrieval - * Bugs, bugs, bugs - -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define PROGRAM_STRING "fileinfo" -#define VERSION_STRING "0.1" -#define AUTHOR_STRING "Sveinbjorn Thordarson " - -#define MAX_PATH_LENGTH 1024 -#define MAX_FILENAME_LENGTH 256 - -#define FILETYPE_FILE 0 -#define FILETYPE_FOLDER 1 -#define FILETYPE_ALIAS 2 -#define FILETYPE_SYMLINK 3 -#define FILETYPE_CHARDEV 4 -#define FILETYPE_BLOCKDEV 5 -#define FILETYPE_PIPE 6 -#define FILETYPE_SOCKET 7 -#define FILETYPE_WHITEOUT 8 -#define FILETYPE_UNKNOWN 9 - - -#define DISPLAY_FORK_BOTH 0 -#define DISPLAY_FORK_DATA 1 -#define DISPLAY_FORK_RSRC 2 - -#define SIZE_BYTES 0 -#define SIZE_HUMAN 1 -#define SIZE_HUMAN_SI 2 - -#define OPT_STRING "vh" - -const char fileTypeStrings[7][32] = { "File", "Folder", "Alias", "Symbolic Link", "Character Device", "Block Device", "Named Pipe (FIFO)", "UNIX Socket", "Whiteout", "Uknown File Type" }; -const char labelNames[8][8] = { "None", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray" }; -const char finderFlagNames[6][32] = { "Invisible", "CustomIcon", "NameLocked", "BundleBit", "Alias", "Stationery" }; - - -typedef struct -{ - char path[1024]; - - char name[256]; - char targetPath[1024]; - - short kind; - - FSSpec fsSpec; - FSRef fsRef; - FInfo finderInfo; - FXInfo finderXInfo; - - UInt64 rsrcPhysicalSize; - UInt64 dataPhysicalSize; - UInt64 rsrcLogicalSize; - UInt64 dataLogicalSize; - UInt64 totalLogicalSize; - UInt64 totalPhysicalSize; - - char fileType[5]; - char fileCreator[5]; - - Boolean finderFlags[6]; - short labelNum; - - char dateCreatedString[256]; - char dateModifiedString[256]; - char dateAccessedString[256]; - char dateAttrModString[256]; - - char ownerPermissions[3]; - char groupPermissions[3]; - char otherPermissions[3]; - -} FileInfoStruct; - - -static void PrintVersion (void); -static void PrintHelp (void); -void PrintFileInfo (char *path); -static int UnixIsFolder (char *path); -static OSErr GetForkSizes (const FSRef *fileRef, UInt64 *totalLogicalForkSize, UInt64 *totalPhysicalForkSize, short fork); - -OSErr RetrieveStatData (FileInfoStruct *file); -OSErr RetrieveFileInfo (FileInfoStruct *file); -OSErr ProcessFinderInfo (FileInfoStruct *file); -char* GetFileNameFromPath (char *name); -static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize); -static char* GetSizeString( UInt64 size, short sizeFormat); -OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTimeString); -static short GetLabelNumber (short flags); -void OSTypeToStr(OSType aType, char *aStr); - - -/*////////////////////////////////////// -// Main program function -/////////////////////////////////////*/ -int main (int argc, char *argv[]) -{ - int i; - int rc; - int optch; - static char optstring[] = OPT_STRING; - - while ( (optch = getopt(argc, argv, optstring)) != -1) - { - switch(optch) - { - case 'v': - PrintVersion(); - return 0; - break; - case 'h': - PrintHelp(); - return 0; - break; - default: /* '?' */ - rc = 1; - PrintHelp(); - return 0; - } - } - - - for (; optind < argc; ++optind) - PrintFileInfo( argv[optind] ); - - //PrintFileInfo("/Users/sveinbjorn/Desktop/Untitled.txt"); - return(0); -} - -#pragma mark - - - -/*////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////*/ - -static void PrintVersion (void) -{ - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); -} - -/*////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////*/ - -static void PrintHelp (void) -{ - printf("usage: %s [-%s] file ...\n", PROGRAM_STRING, OPT_STRING); -} - - -#pragma mark - - - - -void PrintFileInfo (char *path) -{ - short i = 0; - char buf[1024]; - char finderFlagsString[512] = "\0"; - FileInfoStruct file; - OSErr err = noErr; - - strcpy(file.path, path); - err = RetrieveStatData(&file); - if (err) - { - (void)fprintf(stderr, "\nfileinfo: %s: Error %d when retrieving stat data\n", &file.path, err); - return; - } - err = RetrieveFileInfo (&file); - if (err) - { - (void)fprintf(stderr, "\nfileinfo: %s: Error %d when retrieving file info\n", &file.path, err); - return; - } - - //Generate flag string - for (i = 0; i < 6; i++) - { - if (file.finderFlags[i] == 1) - strcat(&finderFlagsString, &finderFlagNames[i]); - strcat(&finderFlagsString, &" "); - } - if (!strlen(&finderFlagsString)) - strcpy(&finderFlagsString, &"None"); - - strcpy(&file.name, GetFileNameFromPath(file.path)); - - printf(" Name: \"%s\"\n", file.name); - printf(" Path: \"%s\"\n", file.path); - if (file.kind == FILETYPE_SYMLINK || file.kind == FILETYPE_ALIAS) - printf(" Kind: %s --> \"%s\"\n", &fileTypeStrings[file.kind], file.targetPath); - else - printf(" Kind: %s\n", &fileTypeStrings[file.kind]); - printf(" Size: %s (%llu bytes)\n", GetSizeString(file.totalPhysicalSize, SIZE_HUMAN), file.totalLogicalSize); - printf(" Forks: Data (%llu bytes), Resource (%llu bytes)\n\n", file.dataLogicalSize, file.rsrcLogicalSize); - - printf(" Type: \"%s\"\n", file.fileType); - printf(" Creator: \"%s\"\n", file.fileCreator); - printf(" Label: %s\n", &labelNames[file.labelNum]); - printf(" Flags: %s\n\n", &finderFlagsString); - - printf(" Created: %s\n", &file.dateCreatedString); - printf(" Modified: %s\n", &file.dateModifiedString); - printf(" Accessed: %s\n", &file.dateAccessedString); - printf("Attr. Mod: %s\n\n", &file.dateAttrModString); - - printf(" Read Write Exec\n"); - printf(" Owner: [%c] [%c] [%c]\n", file.ownerPermissions[0], file.ownerPermissions[1], file.ownerPermissions[2]); - printf(" Group: [%c] [%c] [%c]\n", file.groupPermissions[0], file.groupPermissions[1], file.groupPermissions[2]); - printf(" Others: [%c] [%c] [%c]\n", file.otherPermissions[0], file.otherPermissions[1], file.otherPermissions[2]); - //printf("\n%d\n", cinfo.permissions); - -} - - -OSErr RetrieveStatData (FileInfoStruct *file) -{ - struct stat filestat; - short err; - int lnklen; - char buf[20]; - - err = lstat(file->path, &filestat); - if (err == -1) - return err; - - strmode(filestat.st_mode, &buf); - - switch(buf[0]) - { - //regular file - case '-': - file->kind = FILETYPE_FILE; - break; - case 'b': - file->kind = FILETYPE_BLOCKDEV; - break; - case 'c': - file->kind = FILETYPE_CHARDEV; - break; - case 'd': - file->kind = FILETYPE_FOLDER; - break; - case 'l': - file->kind = FILETYPE_SYMLINK; - if ((lnklen = readlink(&file->path, file->targetPath, sizeof(file->targetPath) - 1)) == -1) - { - (void)fprintf(stderr, "\nfileinfo: %s: %s\n", &file->path, strerror(errno)); - return errno; - } - file->path[lnklen] = '\0'; - break; - case 'p': - file->kind = FILETYPE_PIPE; - break; - case 's': - file->kind = FILETYPE_SOCKET; - break; - case 'w': - file->kind = FILETYPE_WHITEOUT; - break; - case '?': - file->kind = FILETYPE_UNKNOWN; - break; - } - - file->ownerPermissions[0] = (buf[1] == 'r') ? '*' : ' '; - file->ownerPermissions[1] = (buf[2] == 'w') ? '*' : ' '; - file->ownerPermissions[2] = (buf[3] == 'x') ? '*' : ' '; - - file->groupPermissions[0] = (buf[4] == 'r') ? '*' : ' '; - file->groupPermissions[1] = (buf[5] == 'w') ? '*' : ' '; - file->groupPermissions[2] = (buf[6] == 'x') ? '*' : ' '; - - file->otherPermissions[0] = (buf[7] == 'r') ? '*' : ' '; - file->otherPermissions[1] = (buf[8] == 'w') ? '*' : ' '; - file->otherPermissions[2] = (buf[9] == 'x') ? '*' : ' '; - - return noErr; -} - - -OSErr RetrieveFileInfo (FileInfoStruct *file) -{ - FSRef fileRef; - FSSpec fileSpec; - OSErr err = noErr; - FSCatalogInfoBitmap cinfoMap = kFSCatInfoPermissions + kFSCatInfoFinderXInfo + kFSCatInfoCreateDate + kFSCatInfoContentMod - + kFSCatInfoAttrMod + kFSCatInfoAccessDate + kFSCatInfoDataSizes + kFSCatInfoRsrcSizes + kFSCatInfoFinderInfo; - FSCatalogInfo cinfo; - - /* Get file ref to the file or folder pointed to by the path */ - err = FSPathMakeRef(&file->path, &file->fsRef, NULL); - if (err != noErr) - { - printf("FSPathMakeRef(): Error %d returned when getting file reference from %s\n", err, file->path); - /* ExitToShell(); */ - return err; - } - - - //Retrieve File System Catalog information from an FSRef - err = FSGetCatalogInfo (&file->fsRef, cinfoMap, &cinfo, NULL, &file->fsSpec, NULL); - if (err != noErr) - { - printf("FSGetCatalogInfo(): Error %d returned when retrieving catalog information from %s\n", err, file->path); - /* ExitToShell(); */ - return err; - } - - //finder info - file->finderInfo = *(FInfo*)cinfo.finderInfo; - file->finderXInfo = *(FXInfo*)cinfo.extFinderInfo; - - //file size - file->rsrcPhysicalSize = cinfo.rsrcPhysicalSize; - file->dataPhysicalSize = cinfo.dataPhysicalSize; - file->rsrcLogicalSize = cinfo.rsrcLogicalSize; - file->dataLogicalSize = cinfo.dataLogicalSize; - file->totalLogicalSize = file->rsrcLogicalSize + file->dataLogicalSize; - file->totalPhysicalSize = file->rsrcPhysicalSize + file->dataPhysicalSize; - - //dates - GetDateTimeStringFromUTCDateTime(&cinfo.createDate, &file->dateCreatedString); - GetDateTimeStringFromUTCDateTime(&cinfo.contentModDate, &file->dateModifiedString); - GetDateTimeStringFromUTCDateTime(&cinfo.accessDate, &file->dateAccessedString); - GetDateTimeStringFromUTCDateTime(&cinfo.attributeModDate, &file->dateAttrModString); - - err = ProcessFinderInfo(file); - if (err) { return err; } - - - return noErr; - -} - -OSErr ProcessFinderInfo (FileInfoStruct *file) -{ - //get file label - file->labelNum = GetLabelNumber(file->finderInfo.fdFlags); - - /* get file type string */ - OSTypeToStr(file->finderInfo.fdType, file->fileType); - - /* get creator type string */ - OSTypeToStr(file->finderInfo.fdCreator, file->fileCreator); - - /* ///// Finder flags////// */ - - /* Is Invisible */ - file->finderFlags[0] = (file->finderInfo.fdFlags & kIsInvisible) ? 1 : 0; - - /* Has Custom Icon */ - file->finderFlags[1] = (file->finderInfo.fdFlags & kHasCustomIcon) ? 1 : 0; - - /* Is Locked */ - file->finderFlags[2] = (file->finderInfo.fdFlags & kNameLocked) ? 1 : 0; - - /* Has Bundle Bit Set */ - file->finderFlags[3] = (file->finderInfo.fdFlags & kHasBundle) ? 1 : 0; - - /* Is Alias */ - file->finderFlags[4] = (file->finderInfo.fdFlags & kIsAlias) ? 1 : 0; - - /* Is Stationery */ - file->finderFlags[5] = (file->finderInfo.fdFlags & kIsStationery) ? 1 : 0; - - return noErr; -} - - -#pragma mark - - -/*////////////////////////////////////// -// Check if file in designated path is folder -/////////////////////////////////////*/ -static int UnixIsFolder (char *path) -{ - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - return (S_ISREG(filestat.st_mode) != 1); -} - -static int UnixIsSymlink (char *path) -{ - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - return (S_ISLNK(filestat.st_mode) != 1); -} - -//////////////////////////////////////// -// Retrieves pointer to name of file from path -/////////////////////////////////////// - -char* GetFileNameFromPath (char *name) -{ - short i, len; - - len = strlen(name); - - for (i = len; i > 0; i--) - { - if (name[i] == '/') - { - return((char *)&name[i+1]); - } - } - return name; -} - - -/*////////////////////////////////////// -// On being passed the path to a MacOS alias, -// returns path to the original file to which -// it refers. Returns null if file not found. -/////////////////////////////////////*/ -static char* GetPathOfAliasSource (char *path) -{ - OSErr err = noErr; - static char srcPath[1024]; - FSRef fileRef; - Boolean isAlias, isFolder; - - //get file reference from path given - err = FSPathMakeRef (path, &fileRef, NULL); - if (err != noErr) - { - printf("Error getting file spec from path.\n"); - return 0; - } - - //make sure we're dealing with an alias - err = FSIsAliasFile (&fileRef, &isAlias, &isFolder); - if (err != noErr) - { - //printf("Error determining alias properties.\n"); - return NULL; - } - if (!isAlias) - { - //printf("%s: Not an alias.\n", argv[1]); - return NULL; - } - - //resolve alias --> get file reference to file - err = FSResolveAliasFile (&fileRef, TRUE, &isFolder, &isAlias); - if (err != noErr) - { - //printf("Error resolving alias.\n"); - return NULL; - } - - //get path to file that alias points to - err = FSMakePath(fileRef, (char *)&srcPath, strlen(srcPath)); - if (err != noErr) - { - return NULL; - } - - return ((char *)&srcPath); -} - - -/*////////////////////////////////////// -// Creates POSIX path string from FSRef -/////////////////////////////////////*/ -static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize) -{ - OSStatus result; - - result = FSRefMakePath(&fileRef, path, 1024); - - return ( result ); -} - -/* -////////////////////////////////////// -// Generate file size string -////////////////////////////////////// -*/ -static char* GetSizeString( UInt64 size, short sizeFormat) -{ - static char sizeStr[15]; - - switch( sizeFormat ) { - default: - case SIZE_BYTES: - snprintf( sizeStr, sizeof(sizeStr), "%14llu", size ); - break; - case SIZE_HUMAN: - if( size < 1024ULL ) { - /* bytes */ - snprintf( sizeStr, sizeof(sizeStr), "%6u B", (unsigned int)size ); - } else if( size < 1048576ULL) { - /* kbytes */ - snprintf( sizeStr, sizeof(sizeStr), "%5.1f KB", size / 1024.0 ); - } else if( size < 1073741824ULL ) { - /* megabytes */ - snprintf( sizeStr, sizeof(sizeStr), "%5.1f MB", size / 1048576.0 ); - } else { - /* gigabytes */ - snprintf( sizeStr, sizeof(sizeStr), "%5.1f GB", size / 1073741824.0 ); - } - break; - case SIZE_HUMAN_SI: - if( size < 1000ULL ) { - /* bytes */ - snprintf( sizeStr, sizeof(sizeStr), "%6u B", (unsigned int)size ); - } else if( size < 1000000ULL) { - /* kbytes */ - snprintf( sizeStr, sizeof(sizeStr), "%5.1f KB", size / 1000.0 ); - } else if( size < 1000000000ULL ) { - /* megabytes */ - snprintf( sizeStr, sizeof(sizeStr), "%5.1f MB", size / 1000000.0 ); - } else { - /* gigabytes */ - snprintf( sizeStr, sizeof(sizeStr), "%5.1f GB", size / 1000000000.0 ); - } - break; - } - - return( sizeStr ); -} - - -/*////////////////////////////////////// -// HFSUniStr255 converted to null-terminated C string -// For some inexplicable reason, there seems to be no -// convenient Carbon function to do this without -// first converting to a Core Foundation string -/////////////////////////////////////*/ -static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr) -{ - CFStringRef cfStr; - - cfStr = CFStringCreateWithCharacters(kCFAllocatorDefault,uniStr->unicode,uniStr->length); - - CFStringGetCString(cfStr, cstr, 255, kCFStringEncodingUTF8); -} - - -/*////////////////////////////////////// -// Transform OSType into a C string -// An OSType is just a 4 character string -// stored as a long integer -/////////////////////////////////////*/ -void OSTypeToStr(OSType aType, char *aStr) -{ - aStr[0] = (aType >> 24) & 0xFF; - aStr[1] = (aType >> 16) & 0xFF; - aStr[2] = (aType >> 8) & 0xFF; - aStr[3] = aType & 0xFF; - aStr[4] = 0; -} - - -OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTimeString) -{ - CFAbsoluteTime cfTime; - OSErr err = UCConvertUTCDateTimeToCFAbsoluteTime (utcDateTime, &cfTime); - - CFLocaleRef locale = CFLocaleCopyCurrent(); - CFDateRef date = CFDateCreate(NULL, cfTime); - CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, locale, - kCFDateFormatterLongStyle, kCFDateFormatterLongStyle); - CFRelease(locale); - CFStringRef dstr = CFDateFormatterCreateStringWithDate(NULL, formatter, date); - CFRelease(date); - CFRelease(formatter); - CFStringGetCString(dstr, dateTimeString, 256, kCFStringEncodingUTF8); - CFRelease(dstr); - - return err; -} - -/*////////////////////////////////////// -// Checks bits 1-3 of fdFlags and frFlags -// values in FInfo and DInfo structs -// and gets the relevant color/number -/////////////////////////////////////*/ -static short GetLabelNumber (short flags) -{ - /* Is Orange */ - if (flags & 2 && flags & 8 && flags & 4) - return 2; - - /* Is Red */ - if (flags & 8 && flags & 4) - return 1; - - /* Is Yellow */ - if (flags & 8 && flags & 2) - return 3; - - /* Is Blue */ - if (flags & 8) - return 5; - - /* Is Purple */ - if (flags & 2 && flags & 4) - return 6; - - /* Is Green */ - if (flags & 4) - return 4; - - /* Is Gray */ - if (flags & 2) - return 7; - - return 0; -} diff --git a/finfo/finfo.1 b/finfo/finfo.1 new file mode 100644 index 0000000..1b9dd13 --- /dev/null +++ b/finfo/finfo.1 @@ -0,0 +1,37 @@ +.Dd September 20, 2017 +.Dt finfo 1 +.Os Darwin +.Sh NAME +.Nm finfo +.Nd print information about a file in a style similar to the Mac OS X Finder +.Sh SYNOPSIS +.Nm +.Op Fl vh +.Op Ar +.Sh DESCRIPTION +.Nm +is a program for printing all sorts of information about a file in a style similar to the +Mac OS X Finder Get Info window. It lists all sorts of Mac OS-specific metadata information. +.Pp +A list of flags accepted by finfo and their descriptions: +.Bl -tag -width indent +.It Fl v +Print version and exit. +.It Fl h +Print usage and exit. +.El +.Pp +.Sh FILES +.Bl -tag -width "/usr/local/bin/finfo" -compact +.It Pa /usr/local/bin/finfo +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr setfflags 1 , +.Xr setfctypes 1 , +.Xr setfcomment 1 , +.Xr setlabel 1 , +.Xr GetFileInfo 1 , +.Xr hfsdata 1 diff --git a/finfo/finfo.c b/finfo/finfo.c new file mode 100644 index 0000000..0aa365f --- /dev/null +++ b/finfo/finfo.c @@ -0,0 +1,608 @@ +/* + finfo - list info about files in MacOS X + Copyright (C) 2003 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* TODO + + * Error checking + * Finder comment retrieval +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PROGRAM_STRING "finfo" +#define VERSION_STRING "0.1.1" +#define AUTHOR_STRING "Sveinbjorn Thordarson " + +#define MAX_PATH_LENGTH 1024 +#define MAX_FILENAME_LENGTH 256 + +#define FILETYPE_FILE 0 +#define FILETYPE_FOLDER 1 +#define FILETYPE_ALIAS 2 +#define FILETYPE_SYMLINK 3 +#define FILETYPE_CHARDEV 4 +#define FILETYPE_BLOCKDEV 5 +#define FILETYPE_PIPE 6 +#define FILETYPE_SOCKET 7 +#define FILETYPE_WHITEOUT 8 +#define FILETYPE_UNKNOWN 9 + +#define DISPLAY_FORK_BOTH 0 +#define DISPLAY_FORK_DATA 1 +#define DISPLAY_FORK_RSRC 2 + +#define SIZE_BYTES 0 +#define SIZE_HUMAN 1 +#define SIZE_HUMAN_SI 2 + +#define OPT_STRING "vh" + +const char fileTypeStrings[7][32] = { "File", "Folder", "Alias", "Symbolic Link", "Character Device", "Block Device", "Named Pipe (FIFO)", "UNIX Socket", "Whiteout", "Uknown File Type" }; +const char labelNames[8][8] = { "None", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray" }; +const char finderFlagNames[6][32] = { "Invisible", "CustomIcon", "NameLocked", "BundleBit", "Alias", "Stationery" }; + +typedef struct +{ + char path[1024]; + + char name[256]; + char targetPath[1024]; + + short kind; + + FSSpec fsSpec; + FSRef fsRef; + FInfo finderInfo; + FXInfo finderXInfo; + + UInt64 rsrcPhysicalSize; + UInt64 dataPhysicalSize; + UInt64 rsrcLogicalSize; + UInt64 dataLogicalSize; + UInt64 totalLogicalSize; + UInt64 totalPhysicalSize; + + char fileType[5]; + char fileCreator[5]; + + Boolean finderFlags[6]; + short labelNum; + + char dateCreatedString[256]; + char dateModifiedString[256]; + char dateAccessedString[256]; + char dateAttrModString[256]; + + char ownerPermissions[3]; + char groupPermissions[3]; + char otherPermissions[3]; + +} FileInfoStruct; + +static void PrintVersion (void); +static void PrintHelp (void); +void PrintFileInfo (char *path); +static int UnixIsFolder (char *path); +static OSErr GetForkSizes (const FSRef *fileRef, UInt64 *totalLogicalForkSize, UInt64 *totalPhysicalForkSize, short fork); + +OSErr RetrieveStatData (FileInfoStruct *file); +OSErr RetrieveFileInfo (FileInfoStruct *file); +OSErr ProcessFinderInfo (FileInfoStruct *file); +char* GetFileNameFromPath (char *name); +static OSStatus FSMakePath (FSRef fileRef, UInt8 *path, UInt32 maxPathSize); +static char* GetSizeString( UInt64 size, short sizeFormat); +OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTimeString); +static short GetLabelNumber (short flags); +void OSTypeToStr (OSType aType, char *aStr); + +int main (int argc, char *argv[]) +{ + int i; + int optch; + static char optstring[] = OPT_STRING; + + while ((optch = getopt(argc, argv, optstring)) != -1) + { + switch(optch) + { + case 'v': + PrintVersion(); + return 0; + case 'h': + PrintHelp(); + return 0; + } + } + + for (; optind < argc; ++optind) + PrintFileInfo( argv[optind] ); + + return 0; +} + +static void PrintVersion (void) +{ + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); +} + +static void PrintHelp (void) +{ + printf("usage: %s [-%s] [file ...]\n", PROGRAM_STRING, OPT_STRING); +} + +#pragma mark - + +void PrintFileInfo (char *path) +{ + short i = 0; + char buf[1024]; + char finderFlagsString[512] = "\0"; + FileInfoStruct file; + OSErr err = noErr; + + strcpy(file.path, path); + err = RetrieveStatData(&file); + if (err) + { + (void)fprintf(stderr, "\nfinfo: %s: Error %d when retrieving stat data\n", &file.path, err); + return; + } + err = RetrieveFileInfo (&file); + if (err) + { + (void)fprintf(stderr, "\nfinfo: %s: Error %d when retrieving file info\n", &file.path, err); + return; + } + + //Generate flag string + for (i = 0; i < 6; i++) + { + if (file.finderFlags[i] == 1) + strcat(&finderFlagsString, &finderFlagNames[i]); + + strcat(&finderFlagsString, &" "); + } + + if (!strlen(&finderFlagsString)) + strcpy(&finderFlagsString, &"None"); + + strcpy(&file.name, GetFileNameFromPath(file.path)); + + printf(" Name: \"%s\"\n", file.name); + printf(" Path: \"%s\"\n", file.path); + if (file.kind == FILETYPE_SYMLINK || file.kind == FILETYPE_ALIAS) + printf(" Kind: %s --> \"%s\"\n", &fileTypeStrings[file.kind], file.targetPath); + else + printf(" Kind: %s\n", &fileTypeStrings[file.kind]); + printf(" Size: %s (%llu bytes)\n", GetSizeString(file.totalPhysicalSize, SIZE_HUMAN), file.totalLogicalSize); + printf(" Forks: Data (%llu bytes), Resource (%llu bytes)\n\n", file.dataLogicalSize, file.rsrcLogicalSize); + + printf(" Type: \"%s\"\n", file.fileType); + printf(" Creator: \"%s\"\n", file.fileCreator); + printf(" Label: %s\n", &labelNames[file.labelNum]); + printf(" Flags: %s\n\n", &finderFlagsString); + + printf(" Created: %s\n", &file.dateCreatedString); + printf(" Modified: %s\n", &file.dateModifiedString); + printf(" Accessed: %s\n", &file.dateAccessedString); + printf("Attr. Mod: %s\n\n", &file.dateAttrModString); + + printf(" Read Write Exec\n"); + printf(" Owner: [%c] [%c] [%c]\n", file.ownerPermissions[0], file.ownerPermissions[1], file.ownerPermissions[2]); + printf(" Group: [%c] [%c] [%c]\n", file.groupPermissions[0], file.groupPermissions[1], file.groupPermissions[2]); + printf(" Others: [%c] [%c] [%c]\n", file.otherPermissions[0], file.otherPermissions[1], file.otherPermissions[2]); +} + +OSErr RetrieveStatData (FileInfoStruct *file) +{ + struct stat filestat; + short err; + int lnklen; + char buf[20]; + + err = lstat(file->path, &filestat); + if (err == -1) + return err; + + strmode(filestat.st_mode, &buf); + + switch(buf[0]) + { + //regular file + case '-': + file->kind = FILETYPE_FILE; + break; + case 'b': + file->kind = FILETYPE_BLOCKDEV; + break; + case 'c': + file->kind = FILETYPE_CHARDEV; + break; + case 'd': + file->kind = FILETYPE_FOLDER; + break; + case 'l': + file->kind = FILETYPE_SYMLINK; + if ((lnklen = readlink(&file->path, file->targetPath, sizeof(file->targetPath) - 1)) == -1) + { + (void)fprintf(stderr, "\nfinfo: %s: %s\n", &file->path, strerror(errno)); + return errno; + } + file->path[lnklen] = '\0'; + break; + case 'p': + file->kind = FILETYPE_PIPE; + break; + case 's': + file->kind = FILETYPE_SOCKET; + break; + case 'w': + file->kind = FILETYPE_WHITEOUT; + break; + case '?': + file->kind = FILETYPE_UNKNOWN; + break; + } + + file->ownerPermissions[0] = (buf[1] == 'r') ? '*' : ' '; + file->ownerPermissions[1] = (buf[2] == 'w') ? '*' : ' '; + file->ownerPermissions[2] = (buf[3] == 'x') ? '*' : ' '; + + file->groupPermissions[0] = (buf[4] == 'r') ? '*' : ' '; + file->groupPermissions[1] = (buf[5] == 'w') ? '*' : ' '; + file->groupPermissions[2] = (buf[6] == 'x') ? '*' : ' '; + + file->otherPermissions[0] = (buf[7] == 'r') ? '*' : ' '; + file->otherPermissions[1] = (buf[8] == 'w') ? '*' : ' '; + file->otherPermissions[2] = (buf[9] == 'x') ? '*' : ' '; + + return noErr; +} + +OSErr RetrieveFileInfo (FileInfoStruct *file) +{ + FSRef fileRef; + FSSpec fileSpec; + OSErr err = noErr; + FSCatalogInfoBitmap cinfoMap = kFSCatInfoPermissions + kFSCatInfoFinderXInfo + kFSCatInfoCreateDate + kFSCatInfoContentMod + + kFSCatInfoAttrMod + kFSCatInfoAccessDate + kFSCatInfoDataSizes + kFSCatInfoRsrcSizes + kFSCatInfoFinderInfo; + FSCatalogInfo cinfo; + + /* Get file ref to the file or folder pointed to by the path */ + err = FSPathMakeRef(&file->path, &file->fsRef, NULL); + if (err != noErr) + { + printf("FSPathMakeRef(): Error %d returned when getting file reference from %s\n", err, file->path); + return err; + } + + //Retrieve File System Catalog information from an FSRef + err = FSGetCatalogInfo (&file->fsRef, cinfoMap, &cinfo, NULL, &file->fsSpec, NULL); + if (err != noErr) + { + printf("FSGetCatalogInfo(): Error %d returned when retrieving catalog information from %s\n", err, file->path); + return err; + } + + //finder info + file->finderInfo = *(FInfo*)cinfo.finderInfo; + file->finderXInfo = *(FXInfo*)cinfo.extFinderInfo; + + //file size + file->rsrcPhysicalSize = cinfo.rsrcPhysicalSize; + file->dataPhysicalSize = cinfo.dataPhysicalSize; + file->rsrcLogicalSize = cinfo.rsrcLogicalSize; + file->dataLogicalSize = cinfo.dataLogicalSize; + file->totalLogicalSize = file->rsrcLogicalSize + file->dataLogicalSize; + file->totalPhysicalSize = file->rsrcPhysicalSize + file->dataPhysicalSize; + + //dates + GetDateTimeStringFromUTCDateTime(&cinfo.createDate, &file->dateCreatedString); + GetDateTimeStringFromUTCDateTime(&cinfo.contentModDate, &file->dateModifiedString); + GetDateTimeStringFromUTCDateTime(&cinfo.accessDate, &file->dateAccessedString); + GetDateTimeStringFromUTCDateTime(&cinfo.attributeModDate, &file->dateAttrModString); + + err = ProcessFinderInfo(file); + if (err) { return err; } + + return noErr; +} + +OSErr ProcessFinderInfo (FileInfoStruct *file) +{ + //get file label + file->labelNum = GetLabelNumber(file->finderInfo.fdFlags); + + /* get file type string */ + OSTypeToStr(file->finderInfo.fdType, file->fileType); + + /* get creator type string */ + OSTypeToStr(file->finderInfo.fdCreator, file->fileCreator); + + /* ///// Finder flags////// */ + + /* Is Invisible */ + file->finderFlags[0] = (file->finderInfo.fdFlags & kIsInvisible) ? 1 : 0; + + /* Has Custom Icon */ + file->finderFlags[1] = (file->finderInfo.fdFlags & kHasCustomIcon) ? 1 : 0; + + /* Is Locked */ + file->finderFlags[2] = (file->finderInfo.fdFlags & kNameLocked) ? 1 : 0; + + /* Has Bundle Bit Set */ + file->finderFlags[3] = (file->finderInfo.fdFlags & kHasBundle) ? 1 : 0; + + /* Is Alias */ + file->finderFlags[4] = (file->finderInfo.fdFlags & kIsAlias) ? 1 : 0; + + /* Is Stationery */ + file->finderFlags[5] = (file->finderInfo.fdFlags & kIsStationery) ? 1 : 0; + + return noErr; +} + +/*////////////////////////////////////// +// Check if file in designated path is folder +/////////////////////////////////////*/ +static int UnixIsFolder (char *path) +{ + struct stat filestat; + short err; + + err = stat(path, &filestat); + if (err == -1) + return err; + + return S_ISREG(filestat.st_mode) != 1; +} + +static int UnixIsSymlink (char *path) +{ + struct stat filestat; + short err; + + err = stat(path, &filestat); + if (err == -1) + return err; + + return (S_ISLNK(filestat.st_mode) != 1); +} + +//////////////////////////////////////// +// Retrieves pointer to name of file from path +/////////////////////////////////////// + +char* GetFileNameFromPath (char *name) +{ + short i, len; + + len = strlen(name); + + for (i = len; i > 0; i--) + { + if (name[i] == '/') + { + return((char *)&name[i+1]); + } + } + return name; +} + +/*////////////////////////////////////// +// On being passed the path to a MacOS alias, +// returns path to the original file to which +// it refers. Returns null if file not found. +/////////////////////////////////////*/ +static char* GetPathOfAliasSource (char *path) +{ + OSErr err = noErr; + static char srcPath[1024]; + FSRef fileRef; + Boolean isAlias, isFolder; + + //get file reference from path given + err = FSPathMakeRef (path, &fileRef, NULL); + if (err != noErr) + { + printf("Error getting file spec from path.\n"); + return 0; + } + + //make sure we're dealing with an alias + err = FSIsAliasFile (&fileRef, &isAlias, &isFolder); + if (err != noErr) + { + //printf("Error determining alias properties.\n"); + return NULL; + } + if (!isAlias) + { + //printf("%s: Not an alias.\n", argv[1]); + return NULL; + } + + //resolve alias --> get file reference to file + err = FSResolveAliasFile (&fileRef, TRUE, &isFolder, &isAlias); + if (err != noErr) + { + //printf("Error resolving alias.\n"); + return NULL; + } + + //get path to file that alias points to + err = FSMakePath(fileRef, (char *)&srcPath, strlen(srcPath)); + if (err != noErr) + { + return NULL; + } + + return (char *)&srcPath; +} + +/*////////////////////////////////////// +// Creates POSIX path string from FSRef +/////////////////////////////////////*/ +static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize) +{ + return FSRefMakePath(&fileRef, path, 1024); +} + +/* +////////////////////////////////////// +// Generate file size string +////////////////////////////////////// +*/ +static char* GetSizeString(UInt64 size, short sizeFormat) +{ + static char sizeStr[15]; + + switch( sizeFormat ) { + default: + case SIZE_BYTES: + snprintf( sizeStr, sizeof(sizeStr), "%14llu", size ); + break; + case SIZE_HUMAN: + if( size < 1024ULL ) { + /* bytes */ + snprintf( sizeStr, sizeof(sizeStr), "%6u B", (unsigned int)size ); + } else if( size < 1048576ULL) { + /* kbytes */ + snprintf( sizeStr, sizeof(sizeStr), "%5.1f KB", size / 1024.0 ); + } else if( size < 1073741824ULL ) { + /* megabytes */ + snprintf( sizeStr, sizeof(sizeStr), "%5.1f MB", size / 1048576.0 ); + } else { + /* gigabytes */ + snprintf( sizeStr, sizeof(sizeStr), "%5.1f GB", size / 1073741824.0 ); + } + break; + case SIZE_HUMAN_SI: + if( size < 1000ULL ) { + /* bytes */ + snprintf( sizeStr, sizeof(sizeStr), "%6u B", (unsigned int)size ); + } else if( size < 1000000ULL) { + /* kbytes */ + snprintf( sizeStr, sizeof(sizeStr), "%5.1f KB", size / 1000.0 ); + } else if( size < 1000000000ULL ) { + /* megabytes */ + snprintf( sizeStr, sizeof(sizeStr), "%5.1f MB", size / 1000000.0 ); + } else { + /* gigabytes */ + snprintf( sizeStr, sizeof(sizeStr), "%5.1f GB", size / 1000000000.0 ); + } + break; + } + + return sizeStr; +} + +/*////////////////////////////////////// +// HFSUniStr255 converted to null-terminated C string +// For some inexplicable reason, there seems to be no +// convenient Carbon function to do this without +// first converting to a Core Foundation string +/////////////////////////////////////*/ +static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr) +{ + CFStringRef cfStr; + + cfStr = CFStringCreateWithCharacters(kCFAllocatorDefault,uniStr->unicode,uniStr->length); + + CFStringGetCString(cfStr, cstr, 255, kCFStringEncodingUTF8); +} + +/*////////////////////////////////////// +// Transform OSType into a C string +// An OSType is just a 4 character string +// stored as a long integer +/////////////////////////////////////*/ +void OSTypeToStr(OSType aType, char *aStr) +{ + aStr[0] = (aType >> 24) & 0xFF; + aStr[1] = (aType >> 16) & 0xFF; + aStr[2] = (aType >> 8) & 0xFF; + aStr[3] = aType & 0xFF; + aStr[4] = 0; +} + +OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTimeString) +{ + CFAbsoluteTime cfTime; + OSErr err = UCConvertUTCDateTimeToCFAbsoluteTime (utcDateTime, &cfTime); + + CFLocaleRef locale = CFLocaleCopyCurrent(); + CFDateRef date = CFDateCreate(NULL, cfTime); + CFDateFormatterRef formatter = CFDateFormatterCreate( + NULL, locale, + kCFDateFormatterLongStyle, kCFDateFormatterLongStyle); + CFRelease(locale); + CFStringRef dstr = CFDateFormatterCreateStringWithDate(NULL, formatter, date); + CFRelease(date); + CFRelease(formatter); + CFStringGetCString(dstr, dateTimeString, 256, kCFStringEncodingUTF8); + CFRelease(dstr); + + return err; +} + +/*////////////////////////////////////// +// Checks bits 1-3 of fdFlags and frFlags +// values in FInfo and DInfo structs +// and gets the relevant color/number +/////////////////////////////////////*/ +static short GetLabelNumber (short flags) +{ + /* Is Orange */ + if (flags & 2 && flags & 8 && flags & 4) + return 2; + + /* Is Red */ + if (flags & 8 && flags & 4) + return 1; + + /* Is Yellow */ + if (flags & 8 && flags & 2) + return 3; + + /* Is Blue */ + if (flags & 8) + return 5; + + /* Is Purple */ + if (flags & 2 && flags & 4) + return 6; + + /* Is Green */ + if (flags & 4) + return 4; + + /* Is Gray */ + if (flags & 2) + return 7; + + return 0; +} diff --git a/getfcomment/getfcomment.1 b/getfcomment/getfcomment.1 index 7603321..b1f2665 100644 --- a/getfcomment/getfcomment.1 +++ b/getfcomment/getfcomment.1 @@ -1,39 +1,37 @@ -.Dd 11/27/05 \" DATE -.Dt getfcomment 1 \" Program name and manual section number +.Dd September 20, 2017 +.Dt getfcomment 1 .Os Darwin -.Sh NAME \" Section Header - required - don't modify +.Sh NAME .Nm getfcomment -.\" Use .Nm macro to designate other names for the documented program. -.Nd Print Mac OS comment for file -.Sh SYNOPSIS \" Section Header - required - don't modify +.Nd print Mac OS comment for file +.Sh SYNOPSIS .Nm -.Op Fl vhpc \" [-abcd] -.Ar file ... \" [file] -.Sh DESCRIPTION \" Section Header - required - don't modify +.Op Fl chpv +.Ar +.Sh DESCRIPTION .Nm -is a command line program which prints out the Mac OS comment on a file passed -as an argument. +is a command line program which prints out the Mac OS comment on a file passed as an argument. .Pp -.Nm -supports the following flags: -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl p \"-a flag as a list item -Name of file will be printed before each comment +The following options are available: +.Bl -tag -width indent .It Fl c -Output Mac OS Classic Desktop Database comment instead of Mac OS X Finder comment -.It Fl v -Print version and exit +Output Mac OS Classic Desktop Database comment instead of Mac OS X Finder comment. .It Fl h -Print help and exit -.El \" Ends the list +Print usage and exit. +.It Fl p +Print filename before each comment. +.It Fl v +Print version and exit. +.El .Pp -.Sh FILES \" File used or created by the topic of the man page +.Sh FILES .Bl -tag -width "/usr/local/bin/getfcomment" -compact .It Pa /usr/local/bin/getfcomment -.El \" Ends the list - -.\" .El -.Sh SEE ALSO -.Xr geticon 1 , -.Xr fileinfo 1 , -.Xr hfsdata 1 \ No newline at end of file +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr setfcomment 1 , +.Xr finfo 1 , +.Xr hfsdata 1 diff --git a/getfcomment/main.c b/getfcomment/main.c index e2aa899..9fd89be 100644 --- a/getfcomment/main.c +++ b/getfcomment/main.c @@ -18,29 +18,13 @@ */ - + /* CHANGES - + 0.3 - exit constants used from sysexits.h, manpage updated 0.2 - Apple Events querying Finder for comment -- now compatible with Mac OS X comments - 0.1 - First release of getfcomment. It only supports Mac OS 9 Desktop Database comments at the moment - -*/ - -/* TODO - - * Mac OS X comments - -*/ - - -/* - Command line options + 0.1 - First release of getfcomment. It only supports Mac OS 9 Desktop Database comments at the moment - v - version - h - help - usage - c - get Mac OS 9 Desktop Database comment instead of querying the Finder via Apple Events - */ #include @@ -53,8 +37,8 @@ // Some MoreAppleEvents stuff - #define MoreAssert(x) (true) - #define MoreAssertQ(x) +#define MoreAssert(x) (true) +#define MoreAssertQ(x) /////////////// Definitions ////////////// @@ -76,7 +60,7 @@ static const OSType gFinderSignature = 'MACS'; static void PrintFileComment (char *path); static void PrintVersion (void); static void PrintHelp (void); - + //AE functions from MoreAppleEvents.c, Apple's sample code pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr,Str255 pCommentStr,const AEIdleUPP pIdleProcUPP); pascal void MoreAEDisposeDesc(AEDesc* desc); @@ -92,9 +76,9 @@ static const OSType gFinderSignature = 'MACS'; -//main +//main -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { int rc; int optch; @@ -126,10 +110,10 @@ int main (int argc, const char * argv[]) return EX_USAGE; } } - + //all remaining arguments should be files for (; optind < argc; ++optind) - { + { if (os9comment) PrintFileComment((char *)argv[optind]); else @@ -155,7 +139,7 @@ static void PrintOSXComment (char *path) perror(path); return; } - + //get file reference from path err = FSPathMakeRef(path, &fileRef, NULL); if (err != noErr) @@ -163,7 +147,7 @@ static void PrintOSXComment (char *path) fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, path); return; } - + //retrieve filespec from file ref err = FSGetCatalogInfo (&fileRef, NULL, NULL, NULL, &fileSpec, NULL); if (err != noErr) @@ -171,8 +155,8 @@ static void PrintOSXComment (char *path) fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec for %s\n", err, path); return; } - - + + ///////////// oK, now we can go about getting the comment ///////////// // call the apple event routine. I'm not going to pretend I understand what's going on @@ -190,7 +174,7 @@ static void PrintOSXComment (char *path) //if there is no comment, we don't print out anything if (!strlen((char *)&cStrCmt)) return; - + //print out the comment if (!printFileName) printf("%s\n", (char *)&cStrCmt); @@ -216,7 +200,7 @@ static void PrintFileComment (char *path) perror(path); return; } - + //get file reference from path err = FSPathMakeRef(path, &fileRef, NULL); if (err != noErr) @@ -236,21 +220,21 @@ static void PrintFileComment (char *path) ///////////// oK, now we can go about getting the comment ///////////// dt.ioVRefNum = fileSpec.vRefNum; - + err = PBDTGetPath(&dt); if (err != noErr) { fprintf(stderr, "Can't get OS 9 comments for %s\n", path); return; } - + //fill in the relevant fields (using parameters) dt.ioNamePtr = fileSpec.name; dt.ioDirID = fileSpec.parID; dt.ioDTBuffer = (char *)&buf; - + PBDTGetCommentSync(&dt); - + if (dt.ioDTActCount != 0) //if zero, that means no comment { strncpy((char *)&comment, (char *)&buf, dt.ioDTActCount); @@ -263,34 +247,25 @@ static void PrintFileComment (char *path) #endif } - -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// - static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vhp] [file ...]\n", PROGRAM_STRING); +#if !__LP64__ + printf("usage: %s [-chpv] file ...\n", PROGRAM_STRING); +#else + printf("usage: %s [-hpv] file ...\n", PROGRAM_STRING); +#endif } - -#pragma mark - - Boolean MyAEIdleCallback ( EventRecord * theEvent, SInt32 * sleepTime, RgnHandle * mouseRgn) { - return 0; } @@ -326,7 +301,7 @@ pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr (void) MoreAEDisposeDesc(&tAEDesc); if (noErr == anErr) - { + { // Send the event. anErr = MoreAESendEventReturnPString(pIdleProcUPP,&tAppleEvent,pCommentStr); if (anErr) @@ -345,13 +320,13 @@ pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr } // end MoreFEGetComment /******************************************************************************** - Send an Apple event to the Finder to get the finder comment of the item + Send an Apple event to the Finder to get the finder comment of the item specified by the FSRefPtr. pFSRefPtr ==> The item to get the file kind of. pCommentStr ==> A string into which the finder comment will be returned. pIdleProcUPP ==> A UPP for an idle function (required) - + See note about idle functions above. */ #if TARGET_API_MAC_CARBON @@ -382,7 +357,7 @@ pascal OSErr MoreFEGetCommentCFString(const FSRefPtr pFSRefPtr, CFStringRef* pCo (void) MoreAEDisposeDesc(&tAEDesc); if (noErr == anErr) - { + { #if 0 // Set this true to printf the Apple Event before you send it. Handle strHdl; anErr = AEPrintDescToHandle(&tAppleEvent,&strHdl); @@ -418,7 +393,7 @@ pascal void MoreAEDisposeDesc(AEDesc* desc) OSStatus junk; MoreAssertQ(desc != nil); - + junk = AEDisposeDesc(desc); MoreAssertQ(junk == noErr); @@ -486,11 +461,11 @@ pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,A if ((anErr = MemError()) == noErr) { CFStringGetCharacters(tCFStringRef, CFRangeMake(0,bufSize/2), buf); - if (isDirectory) (buf)[(bufSize-1)/2] = (UniChar) 0x003A; + if (isDirectory) (buf)[(bufSize-1)/2] = (UniChar) 0x003A; } } else anErr = coreFoundationUnknownErr; - + if (anErr == noErr) anErr = AECreateDesc(typeUnicodeText, buf, GetPtrSize((Ptr) buf), &nameDesc); if (anErr == noErr) @@ -565,17 +540,17 @@ pascal OSStatus MoreAEGetHandlerError(const AppleEvent* pAEReply) { OSStatus anError = noErr; OSErr handlerErr; - + DescType actualType; long actualSize; - + if ( pAEReply->descriptorType != typeNull ) // there's a reply, so there may be an error { OSErr getErrErr = noErr; - + getErrErr = AEGetParamPtr( pAEReply, keyErrorNumber, typeSInt16, &actualType, &handlerErr, sizeof( OSErr ), &actualSize ); - + if ( getErrErr != errAEDescNotFound ) // found an errorNumber parameter { anError = handlerErr; // so return it's value diff --git a/geticon/NSString+CarbonFSSpecCreation.h b/geticon/NSString+CarbonFSSpecCreation.h deleted file mode 100644 index 13cd3b9..0000000 --- a/geticon/NSString+CarbonFSSpecCreation.h +++ /dev/null @@ -1,20 +0,0 @@ -#import -#import - -@interface NSString (CarbonFSSpecCreation) - -// Fills in the given FSRef struct so it specifies the file whose path is in this string. -// If the file doesn't exist, and "createFile" is YES, this method will attempt to create -// an empty file with the specified path. (The caller should insure that the directory -// the file is to be placed in already exists.) - -- (BOOL) getFSRef:(FSRef*)fsRef createFileIfNecessary:(BOOL)createFile; - -// Fills in the given FSSpec struct so it specifies the file whose path is in this string. -// If the file doesn't exist, and "createFile" is YES, this method will attempt to create -// an empty file with the specified path. (The caller should insure that the directory -// the file is to be placed in already exists.) - -- (BOOL) getFSSpec:(FSSpec*)fsSpec createFileIfNecessary:(BOOL)createFile; - -@end diff --git a/geticon/NSString+CarbonFSSpecCreation.h b/geticon/NSString+CarbonFSSpecCreation.h new file mode 120000 index 0000000..9f0bcb6 --- /dev/null +++ b/geticon/NSString+CarbonFSSpecCreation.h @@ -0,0 +1 @@ +../seticon/NSString+CarbonFSSpecCreation.h \ No newline at end of file diff --git a/geticon/NSString+CarbonFSSpecCreation.m b/geticon/NSString+CarbonFSSpecCreation.m deleted file mode 100644 index 711df94..0000000 --- a/geticon/NSString+CarbonFSSpecCreation.m +++ /dev/null @@ -1,66 +0,0 @@ -#import "NSString+CarbonFSSpecCreation.h" - -@implementation NSString (CarbonFSSpecCreation) - -- (BOOL) getFSRef:(FSRef*)fsRef createFileIfNecessary:(BOOL)createFile -{ - NSFileManager* fileManager = [NSFileManager defaultManager]; - CFURLRef urlRef; - Boolean gotFSRef; - - // Check whether the file exists already. If not, create an empty file if requested. - if (![fileManager fileExistsAtPath:self]) { - if (createFile) { - if (![@"" writeToFile:self atomically:YES]) { - return NO; - } - } else { - return NO; - } - } - - // Create a CFURL with the specified POSIX path. - urlRef = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, - (CFStringRef) self, - kCFURLPOSIXPathStyle, - FALSE /* isDirectory */ ); - if (urlRef == NULL) { -// printf( "** Couldn't make a CFURLRef for the file.\n" ); - return NO; - } - - // Try to create an FSRef from the URL. (If the specified file doesn't exist, this - // function will return false, but if we've reached this code we've already insured - // that the file exists.) - gotFSRef = CFURLGetFSRef( urlRef, fsRef ); - CFRelease( urlRef ); - - if (!gotFSRef) { -// printf( "** Couldn't get an FSRef for the file.\n" ); - return NO; - } - - return YES; -} - -- (BOOL) getFSSpec:(FSSpec*)fsSpec createFileIfNecessary:(BOOL)createFile -{ - FSRef fsRef; - - if (![self getFSRef:&fsRef createFileIfNecessary:createFile]) - return NO; - - if (FSGetCatalogInfo( &fsRef, - kFSCatInfoNone, - NULL, - NULL, - fsSpec, - NULL ) != noErr) { - // printf( "** Couldn't get an FSSpec for the file.\n" ); - return NO; - } - - return YES; -} - -@end diff --git a/geticon/NSString+CarbonFSSpecCreation.m b/geticon/NSString+CarbonFSSpecCreation.m new file mode 120000 index 0000000..39a7d9b --- /dev/null +++ b/geticon/NSString+CarbonFSSpecCreation.m @@ -0,0 +1 @@ +../seticon/NSString+CarbonFSSpecCreation.m \ No newline at end of file diff --git a/geticon/geticon.1 b/geticon/geticon.1 index 905061d..4185250 100644 --- a/geticon/geticon.1 +++ b/geticon/geticon.1 @@ -1,63 +1,36 @@ -.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. -.\"See Also: -.\"man mdoc.samples for a complete listing of options -.\"man mdoc for the short list of editing options -.\"/usr/share/misc/mdoc.template -.Dd Tue May 25 2004 \" DATE -.Dt geticon 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm geticon -.\" Use .Nm macro to designate other names for the documented program. -.Nd Get the icon of a Mac OS X file. -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vh \" [-abcd] -.Op Fl t Ar type \" [-a path] -.Op Fl o Ar outputfile \" [-a path] -.Ar file \" Underlined argument - use .Ar anywhere to underline -.Sh DESCRIPTION \" Section Header - required - don't modify -.Nm -is a command line utility for extracting the icon from a Mac OS X file or folder. -The default behaviour is to extract the icon to the current working directory in \.icns format. -This can be overridden using the -t and -o options described below. -.Pp -A list of flags and their descriptions: -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl o \"-a flag as a list item -Allows you to designate a path where the icon file will be created -.It Fl t -Allows you to specify what format you want to extract the icon to. Valid values are icns, png, gif, tiff and jpeg. -.It Fl v \"-a flag as a list item -Prints version and author -.It Fl h \"-a flag as a list item -Prints short help/usage string -.El \" Ends the list -.Pp -.\" .Sh ENVIRONMENT \" May not be needed -.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 -.\" .It Ev ENV_VAR_1 -.\" Description of ENV_VAR_1 -.\" .It Ev ENV_VAR_2 -.\" Description of ENV_VAR_2 -.\" .El -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact -.It Pa /usr/local/bin/geticon -.\" .Sh DIAGNOSTICS \" May not be needed -.\" .Bl -diag -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr seticon 1 , -.Xr GetFileInfo 1 , -.Xr lsmac 1 , -.Xr fileinfo 1 -.\" .Sh BUGS \" Document known, unremedied bugs -.\" .Sh HISTORY \" Document history if command behaves in a unique manner - +.Dd April 9, 2015 +.Dt geticon 1 +.Os Darwin +.Sh NAME +.Nm geticon +.Nd extract the icon from a Mac OS X file or folder +.Sh SYNOPSIS +.Nm +.Op Fl hv +.Op Fl o Ar outputfile +.Ar file +.Sh DESCRIPTION +.Nm +is a command line utility for extracting the icon from a Mac OS X file or folder. +The default behaviour is to extract the icon to the current working directory in \.icns format. +This can be overridden using the -t and -o options described below. +.Pp +A list of flags and their descriptions: +.Bl -tag -width indent +.It Fl h +Print usage and exit. +.It Fl o +Specify a path where the icon file will be written. +.It Fl v +Print version and exit. +.El +.Pp +.Sh FILES +.Bl -tag -width "/usr/local/bin/geticon" -compact +.It Pa /usr/local/bin/geticon +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr seticon 1 diff --git a/geticon/main.m b/geticon/main.m index 6ff760f..305c2be 100644 --- a/geticon/main.m +++ b/geticon/main.m @@ -1,43 +1,29 @@ /* - geticon - command line program to get icon from Mac OS X files - Copyright (C) 2004 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -/* - - Version History - - 0.2 - sysexits.h constants used as exit codes - 0.1 - geticon first released - + geticon - command line program to get icon from Mac OS X files + Copyright (C) 2004 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* + CHANGES - TO DO - - * Nothing I can think of. Must be something, though. - + 0.2 - sysexits.h constants used as exit codes + 0.1 - geticon first released */ -/////////////////// Includes ////////////////// - #import #import "IconFamily.h" #include @@ -49,112 +35,100 @@ #include #include -/////////////////// Prototypes ////////////////// - static int GenerateFileFromIcon (char *src, char *dst); -static int GetFileKindFromString (char *str); static char* CutSuffix (char *name); static char* GetFileNameFromPath (char *name); static void PrintHelp (void); static void PrintVersion (void); -/////////////////// Definitions ////////////////// - -#define PROGRAM_STRING "geticon" -#define VERSION_STRING "0.2" -#define AUTHOR_STRING "Sveinbjorn Thordarson" -#define OPT_STRING "vho:" +#define PROGRAM_STRING "geticon" +#define VERSION_STRING "0.2" +#define AUTHOR_STRING "Sveinbjorn Thordarson" +#define OPT_STRING "vho:" -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - - int rc, optch, result; - char *src = NULL, *dst = NULL; - int alloced = TRUE; - static char optstring[] = OPT_STRING; - - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) - { - switch(optch) - { - case 'v': - PrintVersion(); - return EX_OK; - break; - case 'h': - PrintHelp(); - return EX_OK; - break; - case 'o': - dst = optarg; - alloced = FALSE; - break; - default: // '?' - rc = 1; - PrintHelp(); - return EX_OK; - } - } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - src = (char *)argv[optind]; + int optch, result; + char *src = NULL, *dst = NULL; + int alloced = TRUE; + static char optstring[] = OPT_STRING; - //check if a correct number of arguments was submitted - if (argc < 2 || src == NULL) + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { - fprintf(stderr, "%s: Too few arguments.\n", PROGRAM_STRING); + case 'v': + PrintVersion(); + return EX_OK; + case 'h': PrintHelp(); - return EX_USAGE; - } - - - //make destination icon file path current working directory with filename plus icns suffix - if (dst == NULL) - { - dst = malloc(2048); - strcpy(dst, src); - char *name = GetFileNameFromPath(dst); - memmove(dst, name, strlen(name) + 1); - dst = CutSuffix(dst); - } - - result = GenerateFileFromIcon(src, dst); - - if (alloced == TRUE) - free(dst); - - [pool release]; - return result; + return EX_OK; + case 'o': + dst = optarg; + alloced = FALSE; + } + } + + src = (char *)argv[optind]; + + //check if a correct number of arguments was submitted + if (argc < 2 || src == NULL) + { + fprintf(stderr, "%s: Too few arguments.\n", PROGRAM_STRING); + PrintHelp(); + return EX_USAGE; + } + + //make destination icon file path current working directory with filename plus icns suffix + if (dst == NULL) + { + dst = malloc(2048); + strcpy(dst, src); + char *name = GetFileNameFromPath(dst); + memmove(dst, name, strlen(name) + 1); + dst = CutSuffix(dst); + } + + result = GenerateFileFromIcon(src, dst); + + if (alloced == TRUE) + free(dst); + + [pool release]; + return result; } static int GenerateFileFromIcon (char *src, char *dst) { - NSString *srcStr = [NSString stringWithCString: src]; - NSString *dstStr = [NSString stringWithCString: dst]; - NSData *data; - NSDictionary *dict; - - //make sure source file we grab icon from exists - if (![[NSFileManager defaultManager] fileExistsAtPath: srcStr]) - { - fprintf(stderr, "%s: %s: No such file or directory\n", PROGRAM_STRING, src); - return EX_NOINPUT; - } - - IconFamily *icon = [IconFamily iconFamilyWithIconOfFile: srcStr]; - - if (![dstStr hasSuffix: @".icns"]) - dstStr = [dstStr stringByAppendingString:@".icns"]; - [icon writeToFile: dstStr]; - - //see if file was created - if (![[NSFileManager defaultManager] fileExistsAtPath: dstStr]) - { - fprintf(stderr, "%s: %s: File could not be created\n", PROGRAM_STRING, dst); - return EX_CANTCREAT; - } - - return EX_OK; + NSString *srcStr = [NSString stringWithCString: src]; + NSString *dstStr = [NSString stringWithCString: dst]; + NSData *data; + NSDictionary *dict; + + //make sure source file we grab icon from exists + if (![[NSFileManager defaultManager] fileExistsAtPath: srcStr]) + { + fprintf(stderr, "%s: %s: No such file or directory\n", PROGRAM_STRING, src); + return EX_NOINPUT; + } + + IconFamily *icon = [IconFamily iconFamilyWithIconOfFile: srcStr]; + + if (![dstStr hasSuffix: @".icns"]) + dstStr = [dstStr stringByAppendingString:@".icns"]; + + [icon writeToFile: dstStr]; + + //see if file was created + if (![[NSFileManager defaultManager] fileExistsAtPath: dstStr]) + { + fprintf(stderr, "%s: %s: File could not be created\n", PROGRAM_STRING, dst); + return EX_CANTCREAT; + } + + return EX_OK; } //////////////////////////////////////// @@ -162,58 +136,41 @@ static int GenerateFileFromIcon (char *src, char *dst) /////////////////////////////////////// static char* CutSuffix (char *name) { - short i, len, suffixMaxLength = 11; - - len = strlen(name); - - for (i = 1; i < suffixMaxLength+2; i++) - { - if (name[len-i] == '.') - { - name[len-i] = NULL; - return name; - } - } - return name; -} - + short i, len, suffixMaxLength = 11; + len = strlen(name); + for (i = 1; i < suffixMaxLength+2; i++) + { + if (name[len-i] == '.') + { + name[len-i] = NULL; + return name; + } + } + return name; +} static char* GetFileNameFromPath (char *name) { - short i, len; - - len = strlen(name); - - for (i = len; i > 0; i--) - { - if (name[i] == '/') - { - return((char *)&name[i+1]); - } - } - return name; -} + short i, len; + len = strlen(name); -#pragma mark - + for (i = len; i > 0; i--) + if (name[i] == '/') + return (char *)&name[i+1]; -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// + return name; +} static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vh] [-t [icns|png|gif|tiff|jpeg]] [-o outputfile] [file]\n", PROGRAM_STRING); + printf("usage: %s [-hv] [-o outputfile] file\n", PROGRAM_STRING); } diff --git a/getvolume/getvolume b/getvolume/getvolume index 245b789..b652642 100755 --- a/getvolume/getvolume +++ b/getvolume/getvolume @@ -2,8 +2,8 @@ if ($ARGV[0] =~ m/-\w*h/) { - printf("Usage: getvolume\n"); - exit(64); + printf("Usage: getvolume\n"); + exit(64); } system("/usr/bin/osascript -e 'output volume of (get volume settings)'"); diff --git a/getvolume/getvolume.1 b/getvolume/getvolume.1 index 95a4be2..a9c752e 100755 --- a/getvolume/getvolume.1 +++ b/getvolume/getvolume.1 @@ -1,28 +1,20 @@ -.Dd Tue Apr 01 2003 +.Dd April 9, 2015 .Dt getvolume 1 .Os Darwin .Sh NAME .Nm getvolume -.Nd Gets global Mac OS X sound output volume -.Sh SYNOPSIS +.Nd print the global Mac OS X sound output volume setting +.Sh SYNOPSIS .Nm -[0-100] .Sh DESCRIPTION .Nm -is a command line tool for checking the global Mac OS X sound output volume. +is a command line tool for checking the global Mac OS X sound output volume. It prints an integer in the range [0-100]. .Sh FILES .Bl -tag -width "/usr/local/bin/getvolume" -compact .It Pa /usr/local/bin/getvolume .El -.Sh SEE ALSO -.Xr setvolume 1 , -.Xr lsmac 1 , -.Xr setfctypes 1 , -.Xr setfflags 1 , -.Xr mkalias 1 , -.Xr setsuffix 1 , -.Xr SetFile 1 , -.Xr setfcomment 1 , -.Xr wsupdate 1, -.Xr seticon 1, -.Xr geticon 1 \ No newline at end of file +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr setvolume 1 diff --git a/google/google b/google/google index c280955..afe5cb5 100755 --- a/google/google +++ b/google/google @@ -1,6 +1,7 @@ #!/usr/bin/perl # # © 2003 Sveinbjorn Thordarson +# # Search google with command line parameters # @@ -10,20 +11,18 @@ use warnings; my $google_url = "http://www.google.com/search?q="; my $google_img_url = "http://images.google.com/images?q="; -my $USAGE = <. -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/setlabel" -compact +.Sh FILES +.Bl -tag -width "/usr/local/bin/google" -compact .It Pa /usr/local/bin/google .El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr wikipedia 1 diff --git a/hfsdata/hfsdata.1 b/hfsdata/hfsdata.1 index b8c8328..69fc409 100644 --- a/hfsdata/hfsdata.1 +++ b/hfsdata/hfsdata.1 @@ -1,76 +1,77 @@ -.Dd 12/18/04 \" DATE -.Dt hfsdata 1 \" Program name and manual section number +.Dd September 20, 2017 +.Dt hfsdata 1 .Os Darwin -.Sh NAME \" Section Header - required - don't modify +.Sh NAME .Nm hfsdata .Nd retrieve Mac meta-data for a file or folder -.Sh SYNOPSIS \" Section Header - required - don't modify +.Sh SYNOPSIS .Nm -.Op Fl vhxAcmatrRsSdDTCklLoOe \" [-abcd] -.Ar file \" Underlined argument - use .Ar anywhere to underline -.Sh DESCRIPTION \" Section Header - required - don't modify +.Op Fl AaCcDdehkLlmOoRrSsTtvx +.Ar file +.Sh DESCRIPTION .Nm is a command line tool to get all sorts of miscellaneous HFS or Mac OS-specific -meta-data for a given file. You can specify the exact -meta-data you want to be printed as output by using one of these flags: -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl e -Prints the path of the file pointed to by a given alias -.It Fl x -Prints whether file's suffix is hidden by the Finder or not +meta-data for a given file. You can specify the exact meta-data you want to be +printed as output by using one of these flags: +.Bl -tag -width indent .It Fl A -Prints the name of the file's preferred application for opening -.It Fl c -Prints date created in standard format -.It Fl m -Prints date modified in standard format +Print the name of the preferred application for opening the file. .It Fl a -Prints date accessed in standard format -.It Fl t -Prints date attribute was modified in standard format -.It Fl r -Prints logical resource fork size in bytes -.It Fl R -Prints physical resource fork size in bytes -.It Fl s -Prints total logical size of all forks in bytes -.It Fl S -Prints total physical size of all forks in bytes -.It Fl d -Prints logical data fork size in bytes -.It Fl D -Prints physical data fork size in bytes -.It Fl T -Prints the file's 4-character type code +Print date accessed in standard format. .It Fl C -Prints the file's 4-character creator code +Print the file's 4-character creator code. +.It Fl c +Print date created in standard format. +.It Fl D +Print physical data fork size in bytes. +.It Fl d +Print logical data fork size in bytes. +.It Fl e +Print the path of the file pointed to by a given alias. +.It Fl h +Print usage and exit. .It Fl k -Prints the file's 'Kind', as it appears in the Finder -.It Fl l -Prints the file's label as a number (i.e. 0-8) +Print the file's 'Kind', as it appears in Finder. .It Fl L -Prints the file's label as a name (e.g. Green) -.It Fl o -Prints the file's Mac OS X Finder comment +Print the file's label as a name (e.g. Green). +.It Fl l +Print the file's label as a number (i.e. 0-8). .It Fl O -Prints the file's Mac OS 9 Desktop Database comment +Print the file's Mac OS 9 Desktop Database comment. +.It Fl o +Print the file's Mac OS X Finder comment. +.It Fl m +Print date modified in standard format. +.It Fl R +Print physical resource fork size in bytes. +.It Fl r +Print logical resource fork size in bytes. +.It Fl S +Print total physical size of all forks in bytes. +.It Fl s +Print total logical size of all forks in bytes. +.It Fl T +Print the file's 4-character type code. +.It Fl t +Print date attribute was modified in standard format. .It Fl v -Prints hfsdata program version and exits -.It Fl h -Prints help -.El \" Ends the list -.Pp -.Sh FILES \" File used or created by the topic of the man page +Print version and exit. +.It Fl x +Print whether file's suffix is hidden by Finder or not. +.El +.Pp +.Sh FILES .Bl -tag -width "/usr/local/bin/hfsdata" -compact .It Pa /usr/local/bin/hfsdata .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr geticon 1 , -.Xr fileinfo 1 , +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr finfo 1 , +.Xr GetFileInfo 1 , .Xr getfcomment 1 , -.Xr lsmac 1 , -.Xr setfflags 1 , +.Xr setfcomment 1 , .Xr setfctypes 1 , -.Xr GetFileInfo 1 +.Xr setfflags 1 , +.Xr setlabel 1 diff --git a/hfsdata/main.c b/hfsdata/main.c index 3fabb2e..d499019 100644 --- a/hfsdata/main.c +++ b/hfsdata/main.c @@ -1,69 +1,22 @@ /* - hfsdata - print out Mac OS HFS+ meta-data for a file - Copyright (C) 2003-2005 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/* CHANGES - - 0.1 - First release of hfsdata - + hfsdata - print out Mac OS HFS+ meta-data for a file + Copyright (C) 2003-2005 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - Command line options - - v - version - h - help - usage - - //hfsdata flags - - -x tells whether file suffix is hidden DONE - - -A tells what application is used to open file DONE - - -c date created DONE - -m date modified DONE - -a date accessed DONE - -t date of attribute modification DONE - - -r Resource fork size, logical DONE - -R Resource fork size, physical DONE - -s Total size of both forks, logical DONE - -S Total size of both forks, physical DONE - -d Data fork size, logical DONE - -D Data fork size, physical DONE - - -T file type code DONE - -C creator type code DONE - - -k file kind, as it appears in the Finder DONE - - -l label, numerically DONE - -L label, by name DONE - - -o Mac OS X Finder comment DONE - -O Mac OS 9 Finder comment DONE - - -e Show file pointed to by alias DONE - -*/ - - #define kSuffixHidden 0 #define kAppForFile 1 #define kDateCreated 2 @@ -85,8 +38,6 @@ #define kMacOS9Comment 18 #define kAliasOriginal 19 -/////////////// Includes ///////////////// - #include #include #include @@ -94,85 +45,77 @@ #include #include -////////////// Prototypes //////////////// - - static OSErr PrintIsExtensionHidden (FSRef *fileRef); - static OSErr PrintAliasSource (FSRef *fileRef); - static OSErr PrintResourceForkLogicalSize (FSRef *fileRef); - static OSErr PrintResourceForkPhysicalSize (FSRef *fileRef); - static OSErr PrintDataForkLogicalSize (FSRef *fileRef); - static OSErr PrintDataForkPhysicalSize (FSRef *fileRef); - static OSErr PrintBothForksLogicalSize (FSRef *fileRef); - static OSErr PrintBothForksPhysicalSize (FSRef *fileRef); - static OSErr PrintDateCreated (FSRef *fileRef); - static OSErr PrintDateContentModified (FSRef *fileRef); - static OSErr PrintDateLastAccessed (FSRef *fileRef); - static OSErr PrintDateAttributeModified (FSRef *fileRef); - static OSErr PrintFileType (FSRef *fileRef); - static OSErr PrintCreatorCode (FSRef *fileRef); - static OSErr PrintKind (FSRef *fileRef); - static OSErr PrintAppWhichOpensFile (FSRef *fileRef); - static OSErr PrintLabelName (FSRef *fileRef); - static OSErr PrintLabelNumber (FSRef *fileRef); - - static void OSTypeToStr(OSType aType, char *aStr); - static int UnixIsFolder (char *path); - static Boolean IsFolder (FSRef *fileRef); - static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr); - static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize); - static OSErr FSGetDInfo(const FSRef* ref, DInfo *dInfo); - static OSErr FSGetFInfo(const FSRef* ref, FInfo *fInfo); - static short GetLabelNumber (short flags); - static OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTimeString); - - static void PrintUsage (void); - static void PrintVersion (void); - static void PrintHelp (void); - - static OSErr PrintOSXComment (FSRef *fileRef); +static OSErr PrintIsExtensionHidden (FSRef *fileRef); +static OSErr PrintAliasSource (FSRef *fileRef); +static OSErr PrintResourceForkLogicalSize (FSRef *fileRef); +static OSErr PrintResourceForkPhysicalSize (FSRef *fileRef); +static OSErr PrintDataForkLogicalSize (FSRef *fileRef); +static OSErr PrintDataForkPhysicalSize (FSRef *fileRef); +static OSErr PrintBothForksLogicalSize (FSRef *fileRef); +static OSErr PrintBothForksPhysicalSize (FSRef *fileRef); +static OSErr PrintDateCreated (FSRef *fileRef); +static OSErr PrintDateContentModified (FSRef *fileRef); +static OSErr PrintDateLastAccessed (FSRef *fileRef); +static OSErr PrintDateAttributeModified (FSRef *fileRef); +static OSErr PrintFileType (FSRef *fileRef); +static OSErr PrintCreatorCode (FSRef *fileRef); +static OSErr PrintKind (FSRef *fileRef); +static OSErr PrintAppWhichOpensFile (FSRef *fileRef); +static OSErr PrintLabelName (FSRef *fileRef); +static OSErr PrintLabelNumber (FSRef *fileRef); + +static void OSTypeToStr(OSType aType, char *aStr); +static int UnixIsFolder (char *path); +static Boolean IsFolder (FSRef *fileRef); +static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr); +static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize); +static OSErr FSGetDInfo(const FSRef* ref, DInfo *dInfo); +static OSErr FSGetFInfo(const FSRef* ref, FInfo *fInfo); +static short GetLabelNumber (short flags); +static OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTimeString); + +static void PrintUsage (void); +static void PrintVersion (void); +static void PrintHelp (void); + +static OSErr PrintOSXComment (FSRef *fileRef); #if !__LP64__ - static OSErr PrintOS9Comment (FSRef *fileRef); +static OSErr PrintOS9Comment (FSRef *fileRef); #endif - //AE functions from MoreAppleEvents.c, Apple's sample code - pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr,Str255 pCommentStr,const AEIdleUPP pIdleProcUPP); - pascal void MoreAEDisposeDesc(AEDesc* desc); - pascal void MoreAENullDesc(AEDesc* desc); - pascal OSStatus MoreAEOCreateObjSpecifierFromFSRef(const FSRefPtr pFSRefPtr,AEDesc *pObjSpecifier); - pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,AEDesc *pObjSpecifier); - pascal OSStatus MoreAESendEventReturnAEDesc(const AEIdleUPP pIdleProcUPP, const AppleEvent *pAppleEvent,const DescType pDescType, AEDesc *pAEDesc); - pascal OSStatus MoreAESendEventReturnPString(const AEIdleUPP pIdleProcUPP,const AppleEvent* pAppleEvent,Str255 pStr255); - pascal OSStatus MoreAEGetHandlerError(const AppleEvent* pAEReply); - pascal OSStatus MoreAESendEventReturnData(const AEIdleUPP pIdleProcUPP,const AppleEvent *pAppleEvent,DescType pDesiredType,DescType* pActualType,void* pDataPtr,Size pMaximumSize,Size *pActualSize); - pascal OSErr MoreAEGetCFStringFromDescriptor(const AEDesc* pAEDesc, CFStringRef* pCFStringRef); - Boolean MyAEIdleCallback (EventRecord * theEvent,SInt32 * sleepTime,RgnHandle * mouseRgn); +//AE functions from MoreAppleEvents.c, Apple's sample code +pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr,Str255 pCommentStr,const AEIdleUPP pIdleProcUPP); +pascal void MoreAEDisposeDesc(AEDesc* desc); +pascal void MoreAENullDesc(AEDesc* desc); +pascal OSStatus MoreAEOCreateObjSpecifierFromFSRef(const FSRefPtr pFSRefPtr,AEDesc *pObjSpecifier); +pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,AEDesc *pObjSpecifier); +pascal OSStatus MoreAESendEventReturnAEDesc(const AEIdleUPP pIdleProcUPP, const AppleEvent *pAppleEvent,const DescType pDescType, AEDesc *pAEDesc); +pascal OSStatus MoreAESendEventReturnPString(const AEIdleUPP pIdleProcUPP,const AppleEvent* pAppleEvent,Str255 pStr255); +pascal OSStatus MoreAEGetHandlerError(const AppleEvent* pAEReply); +pascal OSStatus MoreAESendEventReturnData(const AEIdleUPP pIdleProcUPP,const AppleEvent *pAppleEvent,DescType pDesiredType,DescType* pActualType,void* pDataPtr,Size pMaximumSize,Size *pActualSize); +pascal OSErr MoreAEGetCFStringFromDescriptor(const AEDesc* pAEDesc, CFStringRef* pCFStringRef); +Boolean MyAEIdleCallback (EventRecord * theEvent,SInt32 * sleepTime,RgnHandle * mouseRgn); // Some MoreAppleEvents stuff I don't understand and don't want to - #define MoreAssert(x) (true) - #define MoreAssertQ(x) - - - - -/////////////// Definitions ////////////// +#define MoreAssert(x) (true) +#define MoreAssertQ(x) #define MAX_COMMENT_LENGTH 255 #define PROGRAM_STRING "hfsdata" #define VERSION_STRING "0.1" #define AUTHOR_STRING "Sveinbjorn Thordarson" #if __LP64__ -#define USAGE_STRING "hfsdata [-x|A|c|m|a|t|r|R|s|S|d|D|T|C|k|l|L|o|e] file\nor\nhfsdata [-hv]\n" +#define USAGE_STRING "hfsdata -AaCcDdehkLlmOoRrSsTtvx file\nor\nhfsdata [-hv]\n" #else -#define USAGE_STRING "hfsdata [-x|A|c|m|a|t|r|R|s|S|d|D|T|C|k|l|L|o|O|e] file\nor\nhfsdata [-hv]\n" +#define USAGE_STRING "hfsdata -AaCcDdehkLlmoRrSsTtvx file\nor\nhfsdata [-hv]\n" #endif // The Mac Four-Character Application Signature for the Finder static const OSType gFinderSignature = 'MACS'; -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { OSErr err = noErr; - int rc; int optch; char *path; FSRef fileRef; @@ -254,14 +197,13 @@ int main (int argc, const char * argv[]) type = kAliasOriginal; break; default: // '?' - rc = 1; PrintUsage(); return 0; } } - - - + + + //path to file passed as argument path = (char *)argv[optind]; if (path == NULL) @@ -269,21 +211,21 @@ int main (int argc, const char * argv[]) PrintHelp(); exit(0); } - + if (access(path, R_OK|F_OK) == -1) { perror(path); exit(1); } - + // Get file ref to the file or folder pointed to by the path err = FSPathMakeRef((unsigned char *)path, &fileRef, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSPathMakeRef(): Error %d returned when getting file reference for %s\n", err, path); exit(1); } - + switch(type) { case kSuffixHidden: @@ -349,7 +291,7 @@ int main (int argc, const char * argv[]) err = PrintAliasSource(&fileRef); break; } - + exit(err); return err; @@ -365,19 +307,19 @@ static OSErr PrintIsExtensionHidden (FSRef *fileRef) { LSItemInfoRecord infoRecord; OSErr err = noErr; - + err = LSCopyItemInfoForRef(fileRef, kLSRequestExtensionFlagsOnly, &infoRecord); if (err) - { + { fprintf(stderr, "Error %d in LSCopyItemInfoForRef()\n", err); return err; } - + if (infoRecord.flags & kLSItemInfoExtensionIsHidden) printf("Yes\n"); else printf("No\n"); - + return err; } @@ -392,7 +334,7 @@ static OSErr PrintAliasSource (FSRef *fileRef) static char srcPath[2048]; Boolean isAlias, isFolder; FSRef aliasRef; - + //make sure we're dealing with an alias err = FSIsAliasFile (fileRef, &isAlias, &isFolder); if (err != noErr) @@ -405,7 +347,7 @@ static OSErr PrintAliasSource (FSRef *fileRef) fprintf(stderr, "Argument is not an alias.\n"); return TRUE; } - + //resolve alias --> get file reference to file err = FSResolveAliasFile (fileRef, TRUE, &isFolder, &isAlias); if (err != noErr) @@ -413,7 +355,7 @@ static OSErr PrintAliasSource (FSRef *fileRef) fprintf(stderr, "Error resolving alias.\n"); return err; } - + //get path to file that alias points to err = FSMakePath(*fileRef, (char *)&srcPath, strlen(srcPath)); if (err != noErr) @@ -436,14 +378,14 @@ static OSErr PrintResourceForkLogicalSize (FSRef *fileRef) OSErr err = noErr; FSCatalogInfoBitmap cinfoMap = kFSCatInfoRsrcSizes; FSCatalogInfo cinfo; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + printf("%llu\n", cinfo.rsrcLogicalSize); return err; } @@ -453,14 +395,14 @@ static OSErr PrintResourceForkPhysicalSize (FSRef *fileRef) OSErr err = noErr; FSCatalogInfoBitmap cinfoMap = kFSCatInfoRsrcSizes; FSCatalogInfo cinfo; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + printf("%llu\n", cinfo.rsrcPhysicalSize); return err; } @@ -471,14 +413,14 @@ static OSErr PrintDataForkLogicalSize (FSRef *fileRef) OSErr err = noErr; FSCatalogInfoBitmap cinfoMap = kFSCatInfoDataSizes; FSCatalogInfo cinfo; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + printf("%llu\n", cinfo.dataLogicalSize); return err; } @@ -489,14 +431,14 @@ static OSErr PrintDataForkPhysicalSize (FSRef *fileRef) OSErr err = noErr; FSCatalogInfoBitmap cinfoMap = kFSCatInfoDataSizes; FSCatalogInfo cinfo; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + printf("%llu\n", cinfo.dataPhysicalSize); return err; } @@ -506,14 +448,14 @@ static OSErr PrintBothForksLogicalSize (FSRef *fileRef) OSErr err = noErr; FSCatalogInfoBitmap cinfoMap = kFSCatInfoDataSizes+kFSCatInfoRsrcSizes; FSCatalogInfo cinfo; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + printf("%llu\n", cinfo.rsrcLogicalSize + cinfo.dataLogicalSize); return err; } @@ -523,14 +465,14 @@ static OSErr PrintBothForksPhysicalSize (FSRef *fileRef) OSErr err = noErr; FSCatalogInfoBitmap cinfoMap = kFSCatInfoDataSizes+kFSCatInfoRsrcSizes; FSCatalogInfo cinfo; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + printf("%llu\n", cinfo.dataPhysicalSize + cinfo.rsrcPhysicalSize); return err; } @@ -543,14 +485,14 @@ static OSErr PrintDateCreated (FSRef *fileRef) FSCatalogInfoBitmap cinfoMap = kFSCatInfoCreateDate; FSCatalogInfo cinfo; char dateCreatedString[255]; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + err = GetDateTimeStringFromUTCDateTime(&cinfo.createDate, (char *)&dateCreatedString); if (err != noErr) { @@ -558,7 +500,7 @@ static OSErr PrintDateCreated (FSRef *fileRef) return err; } printf("%s\n", &dateCreatedString); - + return err; } @@ -568,14 +510,14 @@ static OSErr PrintDateContentModified (FSRef *fileRef) FSCatalogInfoBitmap cinfoMap = kFSCatInfoContentMod; FSCatalogInfo cinfo; char dateString[255]; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + err = GetDateTimeStringFromUTCDateTime(&cinfo.contentModDate, (char *)&dateString); if (err != noErr) { @@ -583,7 +525,7 @@ static OSErr PrintDateContentModified (FSRef *fileRef) return err; } printf("%s\n", &dateString); - + return err; } @@ -593,14 +535,14 @@ static OSErr PrintDateLastAccessed (FSRef *fileRef) FSCatalogInfoBitmap cinfoMap = kFSCatInfoAccessDate; FSCatalogInfo cinfo; char dateString[255]; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + err = GetDateTimeStringFromUTCDateTime(&cinfo.accessDate, (char *)&dateString); if (err != noErr) { @@ -608,7 +550,7 @@ static OSErr PrintDateLastAccessed (FSRef *fileRef) return err; } printf("%s\n", &dateString); - + return err; } @@ -618,14 +560,14 @@ static OSErr PrintDateAttributeModified (FSRef *fileRef) FSCatalogInfoBitmap cinfoMap = kFSCatInfoAttrMod; FSCatalogInfo cinfo; char dateString[255]; - + err = FSGetCatalogInfo (fileRef, cinfoMap, &cinfo, NULL, NULL, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d returned when retrieving catalog information\n", err); return err; } - + err = GetDateTimeStringFromUTCDateTime(&cinfo.attributeModDate, (char *)&dateString); if (err != noErr) { @@ -633,7 +575,7 @@ static OSErr PrintDateAttributeModified (FSRef *fileRef) return err; } printf("%s\n", &dateString); - + return err; } @@ -655,7 +597,7 @@ static OSErr PrintFileType (FSRef *fileRef) // retrieve filespec from file ref err = FSGetCatalogInfo (fileRef, NULL, NULL, NULL, &fileSpec, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec from file reference\n", err); return err; @@ -667,14 +609,14 @@ static OSErr PrintFileType (FSRef *fileRef) fprintf(stderr, "FSpGetFInfo(): Error %d getting file Finder File Info from file spec\n", err); return err; } - + /* get creator type string */ OSTypeToStr(finderInfo.fdType, fileType); - + //print it if (strlen(fileType) != 0) printf("%s\n", fileType); - + return 0; } @@ -685,7 +627,7 @@ static OSErr PrintCreatorCode (FSRef *fileRef) FInfo finderInfo; OSErr err = noErr; char creatorType[5] = "\0"; - + //if it's a folder if (IsFolder(fileRef)) { @@ -695,7 +637,7 @@ static OSErr PrintCreatorCode (FSRef *fileRef) // retrieve filespec from file ref err = FSGetCatalogInfo (fileRef, NULL, NULL, NULL, &fileSpec, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec from file reference\n", err); return err; @@ -707,10 +649,10 @@ static OSErr PrintCreatorCode (FSRef *fileRef) fprintf(stderr, "FSpGetFInfo(): Error %d getting file Finder File Info from file spec\n", err); return err; } - + /* get creator type string */ OSTypeToStr(finderInfo.fdCreator, creatorType); - + //print it if (strlen(creatorType) != 0) printf("%s\n", creatorType); @@ -725,13 +667,13 @@ static OSErr PrintKind (FSRef *fileRef) OSErr err = noErr; CFStringRef kindString; char cKindStr[1024]; - + err = LSCopyKindStringForRef(fileRef, &kindString); if (err) return err; - + CFStringGetCString(kindString, (char *)&cKindStr, 1024, CFStringGetSystemEncoding()); - + printf("%s\n", cKindStr); return 0; } @@ -789,12 +731,12 @@ static OSErr PrintLabelName (FSRef *fileRef) /* retrieve filespec from file ref */ err = FSGetCatalogInfo (fileRef, NULL, NULL, NULL, &fileSpec, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec from file reference\n", err); return err; } - + if (IsFolder(fileRef)) { err = FSGetDInfo (fileRef, &dInfo); @@ -815,9 +757,9 @@ static OSErr PrintLabelName (FSRef *fileRef) } labelNum = GetLabelNumber(finderInfo.fdFlags); } - + printf("%s\n", (char *)&labelNames[labelNum]); - + return noErr; } @@ -831,12 +773,12 @@ static OSErr PrintLabelNumber (FSRef *fileRef) /* retrieve filespec from file ref */ err = FSGetCatalogInfo (fileRef, NULL, NULL, NULL, &fileSpec, NULL); - if (err != noErr) + if (err != noErr) { fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec from file reference\n", err); return err; } - + if (IsFolder(fileRef)) { err = FSGetDInfo (fileRef, &dInfo); @@ -857,9 +799,9 @@ static OSErr PrintLabelNumber (FSRef *fileRef) } labelNum = GetLabelNumber(finderInfo.fdFlags); } - + printf("%d\n", labelNum); - + return noErr; } @@ -888,7 +830,7 @@ static int UnixIsFolder (char *path) { struct stat filestat; short err; - + err = stat(path, &filestat); if (err == -1) return err; @@ -922,7 +864,7 @@ static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr) CFStringRef cfStr; cfStr = CFStringCreateWithCharacters(kCFAllocatorDefault,uniStr->unicode,uniStr->length); - + CFStringGetCString(cfStr, cstr, 255, kCFStringEncodingUTF8); } @@ -932,14 +874,14 @@ static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr) static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize) { OSStatus result; - + result = FSRefMakePath(&fileRef, path, 2000); return ( result ); } /*////////////////////////////////////// -// Returns directory info structure of +// Returns directory info structure of // file spec /////////////////////////////////////*/ static OSErr FSGetDInfo(const FSRef* ref, DInfo *dInfo) @@ -979,19 +921,19 @@ static short GetLabelNumber (short flags) /* Is Yellow */ if (flags & 8 && flags & 2) return 3; - + /* Is Blue */ if (flags & 8) return 5; - + /* Is Purple */ if (flags & 2 && flags & 4) return 6; - + /* Is Green */ if (flags & 4) return 4; - + /* Is Gray */ if (flags & 2) return 7; @@ -1004,7 +946,7 @@ OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTime { CFAbsoluteTime cfTime; OSErr err = UCConvertUTCDateTimeToCFAbsoluteTime (utcDateTime, &cfTime); - + CFLocaleRef locale = CFLocaleCopyCurrent(); CFDateRef date = CFDateCreate(NULL, cfTime); CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, locale, @@ -1015,7 +957,7 @@ OSErr GetDateTimeStringFromUTCDateTime (UTCDateTime *utcDateTime, char *dateTime CFRelease(formatter); CFStringGetCString(dstr, dateTimeString, 256, kCFStringEncodingUTF8); CFRelease(dstr); - + return err; } @@ -1077,7 +1019,7 @@ static void PrintHelp (void) puts("\t-O Prints the file's Mac OS 9 Desktop Database comment"); #endif puts(""); - + } #pragma mark - @@ -1089,7 +1031,7 @@ static OSErr PrintOSXComment (FSRef *fileRef) Str255 comment = "\p"; char cStrCmt[255] = "\0"; AEIdleUPP inIdleProc = NewAEIdleUPP(&MyAEIdleCallback); - + //retrieve filespec from file ref err = FSGetCatalogInfo (fileRef, NULL, NULL, NULL, &fileSpec, NULL); if (err != noErr) @@ -1097,7 +1039,7 @@ static OSErr PrintOSXComment (FSRef *fileRef) fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec for %s\n", err); return err; } - + ///////////// oK, now we can go about getting the comment ///////////// // call the apple event routine. I'm not going to pretend I understand what's going on @@ -1112,11 +1054,11 @@ static OSErr PrintOSXComment (FSRef *fileRef) } //convert pascal string to c string strncpy((char *)&cStrCmt, (unsigned char *)&comment+1, comment[0]); - + //if there is a comment, we print it if (strlen((char *)&cStrCmt)) printf("%s\n", (char *)&cStrCmt); - + return noErr; } @@ -1141,21 +1083,21 @@ static OSErr PrintOS9Comment (FSRef *fileRef) ///////////// oK, now we can go about getting the comment ///////////// dt.ioVRefNum = fileSpec.vRefNum; - + err = PBDTGetPath(&dt); if (err != noErr) { fprintf(stderr, "Can't get OS 9 comments\n"); return err; } - + //fill in the relevant fields (using parameters) dt.ioNamePtr = fileSpec.name; dt.ioDirID = fileSpec.parID; dt.ioDTBuffer = (char *)&buf; - + PBDTGetCommentSync(&dt); - + if (dt.ioDTActCount != 0) //if zero, that means no comment { strncpy((char *)&comment, (char *)&buf, dt.ioDTActCount); @@ -1210,7 +1152,7 @@ pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr (void) MoreAEDisposeDesc(&tAEDesc); if (noErr == anErr) - { + { // Send the event. anErr = MoreAESendEventReturnPString(pIdleProcUPP,&tAppleEvent,pCommentStr); if (anErr) @@ -1229,13 +1171,13 @@ pascal OSErr MoreFEGetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr } // end MoreFEGetComment /******************************************************************************** - Send an Apple event to the Finder to get the finder comment of the item + Send an Apple event to the Finder to get the finder comment of the item specified by the FSRefPtr. pFSRefPtr ==> The item to get the file kind of. pCommentStr ==> A string into which the finder comment will be returned. pIdleProcUPP ==> A UPP for an idle function (required) - + See note about idle functions above. */ #if TARGET_API_MAC_CARBON @@ -1266,7 +1208,7 @@ pascal OSErr MoreFEGetCommentCFString(const FSRefPtr pFSRefPtr, CFStringRef* pCo (void) MoreAEDisposeDesc(&tAEDesc); if (noErr == anErr) - { + { #if 0 // Set this true to printf the Apple Event before you send it. Handle strHdl; anErr = AEPrintDescToHandle(&tAppleEvent,&strHdl); @@ -1302,7 +1244,7 @@ pascal void MoreAEDisposeDesc(AEDesc* desc) OSStatus junk; MoreAssertQ(desc != nil); - + junk = AEDisposeDesc(desc); MoreAssertQ(junk == noErr); @@ -1368,11 +1310,11 @@ pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,A if ((anErr = MemError()) == noErr) { CFStringGetCharacters(tCFStringRef, CFRangeMake(0,bufSize/2), buf); - if (isDirectory) (buf)[(bufSize-1)/2] = (UniChar) 0x003A; + if (isDirectory) (buf)[(bufSize-1)/2] = (UniChar) 0x003A; } } else anErr = coreFoundationUnknownErr; - + if (anErr == noErr) anErr = AECreateDesc(typeUnicodeText, buf, GetPtrSize((Ptr) buf), &nameDesc); if (anErr == noErr) @@ -1447,17 +1389,17 @@ pascal OSStatus MoreAEGetHandlerError(const AppleEvent* pAEReply) { OSStatus anError = noErr; OSErr handlerErr; - + DescType actualType; long actualSize; - + if ( pAEReply->descriptorType != typeNull ) // there's a reply, so there may be an error { OSErr getErrErr = noErr; - + getErrErr = AEGetParamPtr( pAEReply, keyErrorNumber, typeSInt16, &actualType, &handlerErr, sizeof( OSErr ), &actualSize ); - + if ( getErrErr != errAEDescNotFound ) // found an errorNumber parameter { anError = handlerErr; // so return it's value diff --git a/lsmac/lsmac.1 b/lsmac/lsmac.1 index 1e19d7e..08f91f7 100755 --- a/lsmac/lsmac.1 +++ b/lsmac/lsmac.1 @@ -1,25 +1,24 @@ -.Dd Wed Mar 31 2003 \" DATE -.Dt lsmac 1 +.Dd April 9, 2015 +.Dt lsmac 1 .Os Darwin -.Sh NAME +.Sh NAME .Nm lsmac .Nd list files in directory and associated Mac meta-data -.Sh SYNOPSIS +.Sh SYNOPSIS .Nm -.Op Fl vhsboapl -.Ar directory - -.Sh DESCRIPTION \" Section Header - required - don't modify +.Op Fl abFhLlopQsv +.Op Fl f Ar fork +.Op directory ... +.Sh DESCRIPTION .Ar lsmac is an ls-like utility for listing the files contained in a given directory on a HFS or HFS+ volume and the MacOS meta-data associated with them. The output is akin to that of the ls long view. Each line follows the format below: -.Bl -tag -width -indent -.It [Finder flags] [file type] [creator type] [size] [name or path] -.El \" Ends the list .Pp -The Finder flags of each file are displayed as a sequence of six characters. Each character indicates whether one +.Dl [Finder flags] [file type] [creator type] [size] [name or path] +.Pp +The Finder flags of each file are displayed as a sequence of six characters. Each character indicates whether one of the following flags are set: -.Bl -tag -width -indent \" Begins a tagged list +.Bl -tag -width indent .It I File has the Invisible flag set .It C @@ -32,60 +31,44 @@ File has the Bundle bit flag set File has the Alias flag set .It S File has the Stationery flag set -.El +.El .Pp -An '-' indicates that a flag is not set. For example, a file with none of the Finder flags set would be listed as '------' while +A '-' indicates that a flag is not set. For example, a file with none of the Finder flags set would be listed as '------' while a file with all the flags set would be listed as 'ICLBAS'. .Pp .Ar lsmac accepts the following options: .Pp -.Bl -tag -width indent \" Differs from above in tag removed -.It Fl v \"-a flag as a list item -Prints version and author and then exits +.Bl -tag -width indent +.It Fl a +Display all files, including files with the . prefix. +.It Fl b +Display file size in bytes (i.e. 12977128 bytes). +.It Fl F +Only list folders when listing directory contents. +.It Fl f Ar fork +Specify which forks to count when calculating file size. You can specify fork as 'rsrc', 'data' or 'both' (minus quote marks). .It Fl h -Prints help +Print usage and exit. .It Fl L -Prepends the MacOS Label name of the file in question to each output line -.It Fl f[fork] -Specify which forks to count when calculating file size. You can specify fork as 'rsrc', 'data' or 'both' (minus quote marks). -.It Fl b -Display file size in bytes (i.e. 12977128 bytes) +Prepend the MacOS Label name of the file to each output line. +.It Fl l +When listing file size, use physical size instead of logical size. .It Fl o -Omit folders when listing directory contents -.It Fl F -Only list folders when listing directory contents -.It Fl a -Display all files, including files with the . prefix. +Omit folders when listing directory contents. .It Fl p -Display full file paths instead of file names +Display full file paths instead of file names. .It Fl Q -Display file name or path within quotation marks ("). -.It Fl l -When listing file size, use physical size instead of logical size. -.El \" Ends the list -.Pp -Please direct queries to Sveinbjorn Thordarson . -.Pp -.Sh FILES \" File used or created by the topic of the man page +Display file name or path within quotation marks ("..."). +.It Fl v +Print version and exit. +.El +.Sh FILES .Bl -tag -width "/usr/local/bin/lsmac" -compact .It Pa /usr/local/bin/lsmac -.\" .Sh DIAGNOSTICS \" May not be needed -.\" .Bl -diag -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO .Xr ls 1 , -.Xr setfctypes 1 -.Xr GetFileInfo 1 -.Xr setsuffix 1 , -.Xr mkalias 1 -.Xr cpath 1 , -.Xr SetFile 1 , -.Xr setfflags 1 , - +.Xr rcmac 1 diff --git a/lsmac/lsmac.c b/lsmac/lsmac.c index da6e24a..cf7eae7 100644 --- a/lsmac/lsmac.c +++ b/lsmac/lsmac.c @@ -1,86 +1,89 @@ /* - lsmac - ls-like utility for viewing Mac OS file meta-data - Copyright (C) 2003-2005 Sveinbjorn Thordarson - Ingmar J. Stein - Jean-Luc Dubois - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + lsmac - ls-like utility for viewing Mac OS file meta-data + + Copyright (C) 2003-2005 + Sveinbjorn Thordarson + Ingmar J. Stein + Jean-Luc Dubois + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* -// I wrote this program because I found the Apple-supplied command line tools with the -// Developer Tools to be rather poor and needed a convenient way to view classic Mac file meta-data. -// I'd appreciate being notified of any changes/improvements made to the lsmac source code -// so I can add them to my own releases. Thanks and enjoy -- Sveinbjorn Thordarson +// I wrote this program because I found the Apple-supplied command line tools with the +// Developer Tools to be rather poor and needed a convenient way to view classic Mac file meta-data. +// I'd appreciate being notified of any changes/improvements made to the lsmac source code +// so I can add them to my own releases. Thanks and enjoy -- Sveinbjorn Thordarson */ -/* CHANGES - - 0.6 - * Now lists symlinks without error, thanks to Jean-Luc Dubois - * All errors go to stderr - * Exit values are constants from sysexits.h - - 0.5 - * Added support for labels now that they're back in the Mac OS as of version 10.3 "Panther" - * Label name is prepended to each output line with the -L option - * Finder flags for folders are now also retrieved and displayed - * Memory usage and performance improved ever so slightly by hardcoding max path length - * Removed deprecated code, slightly better commenting and help output - - - 0.4 - * made internal methods static (reduced file size by more than 50%) - * removed dynamic memory allocation and other performance enhancements - * Defined KB, MB and GB as 2^10, 2^20 and 2^30 bytes, respectively - * List multiple directories given as command line arguments - * Mac OS Finder Alias files now listed like symlinks with standard ls: *alias* --> *source* - - 0.3 - * lsmac can now be told whether to list the size of resource fork, data fork or both. Both is default - * -Q option: names/paths printed within quotation marks - * lsmac now displays file size in human readable format by default - * fixed error that occurred when listing root directory - * -F option: only folders are listed - * Num. of files within folders is now listed by default - * Some minor optimizations (f.e. stat used for determining directories, free & malloc instead of NewPtr & DisposePtr, etc.) - - 0.2 - Tons of stuff changed/improved - - * lsmac now accepts command line options via getopt - * can display file size in bytes or human readable format - * The size displayed is the size of ALL the file's forks, not just the data fork! - * Option to display the physical size of file instead of logical - * can display full pathname of files instead of just the names - * can be set to omit directories in listing directory contents - * lsmac now has a man page lsmac(1) - - 0.1 - First release of lsmac - +/* + CHANGES + + 0.6 + * Now lists symlinks without error, thanks to Jean-Luc Dubois + * All errors go to stderr + * Exit values are constants from sysexits.h + + 0.5 + * Added support for labels now that they're back in the Mac OS as of version 10.3 "Panther" + * Label name is prepended to each output line with the -L option + * Finder flags for folders are now also retrieved and displayed + * Memory usage and performance improved ever so slightly by hardcoding max path length + * Removed deprecated code, slightly better commenting and help output + + 0.4 + * made internal methods static (reduced file size by more than 50%) + * removed dynamic memory allocation and other performance enhancements + * Defined KB, MB and GB as 2^10, 2^20 and 2^30 bytes, respectively + * List multiple directories given as command line arguments + * Mac OS Finder Alias files now listed like symlinks with standard ls: *alias* --> *source* + + 0.3 + * lsmac can now be told whether to list the size of resource fork, data fork or both. Both is default + * -Q option: names/paths printed within quotation marks + * lsmac now displays file size in human readable format by default + * fixed error that occurred when listing root directory + * -F option: only folders are listed + * Num. of files within folders is now listed by default + * Some minor optimizations (f.e. stat used for determining directories, free & malloc instead of NewPtr & DisposePtr, etc.) + + 0.2 + * lsmac now accepts command line options via getopt + * can display file size in bytes or human readable format + * The size displayed is the size of ALL the file's forks, not just the data fork! + * Option to display the physical size of file instead of logical + * can display full pathname of files instead of just the names + * can be set to omit directories in listing directory contents + * lsmac now has a man page lsmac(1) + + 0.1 + * First release of lsmac */ +/* + TODO -/* TODO - - * Incorporate Ingmar J. Stein's improvements to lsmac, which should fix the following problems - - * Bug - errors may occur when listing folders containing more than 9999 files. - * Bug - Does not display size correctly for files larger than 4GB or so. 64bit int problem. - * Bug - When a directory parameter ends with a "/", the pathnames reported by the -p option have two slashes at the end - - * Implement calculation of folder sizes - recursively scan through hierarchy and add up total size - * There is other Mac file meta-data not available via FSpGetFInfo() which should also be listed - * -x option: list file suffixes in a seperate column, kind of like the DOS dir command - * List total size/number of all files listed on top, akin to ls + * Incorporate Ingmar J. Stein's improvements to lsmac, which should fix the following problems: + * Bug - errors may occur when listing folders containing more than 9999 files. + * Bug - Does not display size correctly for files larger than 4GB or so. 64bit int problem. + * Bug - When a directory parameter ends with a "/", the pathnames reported by the -p option have two slashes at the end + + * Implement calculation of folder sizes - recursively scan through hierarchy and add up total size + * There is other Mac file meta-data not available via FSpGetFInfo() which should also be listed + * -x option: list file suffixes in a seperate column, kind of like the DOS dir command + * List total size/number of all files listed on top, akin to ls */ #include @@ -93,8 +96,6 @@ #include #include -/*///////Prototypes///////////////////*/ - static void PrintVersion (void); static void PrintHelp (void); @@ -108,9 +109,7 @@ static long GetNumFilesInFolder (FSRef *fileRef); static short GetForkParameterFromString (char *str); -// static char* GetSizeString (long size); -static char* GetSizeString (UInt64 size); // up to 99 TBytes -// static char* GetHumanSizeString (long size); +static char* GetSizeString (UInt64 size); // up to 99 TBytes static char* GetHumanSizeString (UInt64 size); static OSErr GetForkSizes (const FSRef *fileRef, UInt64 *totalLogicalForkSize, UInt64 *totalPhysicalForkSize, short fork); @@ -127,427 +126,366 @@ static short GetLabelNumber (SInt16 flags); static OSErr MyFSPathMakeRef( const unsigned char *path, FSRef *ref ); // path to the link itself static OSErr ConvertCStringToHFSUniStr(const char* cStr, HFSUniStr255 *uniStr); -static UInt64 totalFolderSize; // total size of files in folder - -/*///////Definitions///////////////////*/ +static UInt64 totalFolderSize; // total size of files in folder -#define PROGRAM_STRING "lsmac" -#define VERSION_STRING "0.5" -#define AUTHOR_STRING "Sveinbjorn Thordarson " +#define PROGRAM_STRING "lsmac" +#define VERSION_STRING "0.5" +#define AUTHOR_STRING "Sveinbjorn Thordarson " /* Text for /usr/bin/what */ /*@unused@*/ static const char rcsid[] = "@(#)" PROGRAM_STRING " " VERSION_STRING " $Id: lsmac.c,v 1.5 2004/12/19 22:59:06 carstenklapp Exp $"; -#define USAGE_STRING "lsmac [-LvhFsboaplQ] [-f fork] directory ..." +#define USAGE_STRING "lsmac [-abFhLlopQsv] [-f fork] [directory ...]" -#define MAX_PATH_LENGTH 1024 -#define MAX_FILENAME_LENGTH 256 +#define MAX_PATH_LENGTH 1024 +#define MAX_FILENAME_LENGTH 256 -#define OPT_STRING "Lvhf:FsboaplQ" +#define OPT_STRING "Lvhf:FsboaplQ" -#define DISPLAY_FORK_BOTH 0 -#define DISPLAY_FORK_DATA 1 -#define DISPLAY_FORK_RSRC 2 +#define DISPLAY_FORK_BOTH 0 +#define DISPLAY_FORK_DATA 1 +#define DISPLAY_FORK_RSRC 2 -#define BOTH_FORK_PARAM_NAME "both" -#define DATA_FORK_PARAM_NAME "data" -#define RSRC_FORK_PARAM_NAME "rsrc" +#define BOTH_FORK_PARAM_NAME "both" +#define DATA_FORK_PARAM_NAME "data" +#define RSRC_FORK_PARAM_NAME "rsrc" -#define IS_SYMLINK 3 // to deal with symlinks -#define VOL_NOT_FOUND -35 // to suppress error with /.vol & /dev -#define kCouldNotCreateCFString 4 -#define kCouldNotGetStringData 5 +#define IS_SYMLINK 3 // to deal with symlinks +#define VOL_NOT_FOUND -35 // to suppress error with /.vol & /dev +#define kCouldNotCreateCFString 4 +#define kCouldNotGetStringData 5 +static int omitFolders = false; +static int displayAll = false; +static int printFullPath = false; +static int useBytesForSize = false; +static int physicalSize = false; +static int forkToDisplay = DISPLAY_FORK_BOTH; +static int useQuotes = false; +static int printLabelName = false; +static int foldersOnly = false; -/*///////Globals///////////////////*/ +static char labelNames[8][8] = { "None ", "Red ", "Orange ", "Yellow ", "Green ", "Blue ", "Purple ", "Gray " }; -static int omitFolders = false; -static int displayAll = false; -static int printFullPath = false; -static int useBytesForSize = false; -static int physicalSize = false; -static int forkToDisplay = DISPLAY_FORK_BOTH; -static int useQuotes = false; -static int printLabelName = false; -static int foldersOnly = false; +int main (int argc, char *argv[]) +{ + int i; + int optch; + static char optstring[] = OPT_STRING; + char buf[MAX_PATH_LENGTH]; + char *cwd; + + while ((optch = getopt(argc, argv, optstring)) != -1) + { + switch(optch) + { + case 'v': + PrintVersion(); + return EX_OK; + case 'h': + PrintHelp(); + return EX_OK; + case 'f': + forkToDisplay = GetForkParameterFromString(optarg); + break; + case 'F': + foldersOnly = true; + break; + case 'b': + useBytesForSize = true; + break; + case 'o': + omitFolders = true; + break; + case 'a': + displayAll = true; + break; + case 'p': + printFullPath = true; + break; + case 'l': + physicalSize = true; + break; + case 'L': + printLabelName = true; + break; + case 'Q': + useQuotes = true; + } + } -static char labelNames[8][8] = { "None ", "Red ", "Orange ", "Yellow ", "Green ", "Blue ", "Purple ", "Gray " }; + argc -= optind; + argv += optind; + if(argc) + { + for(i=0; i 1 ) + { + if( i > 0 ) + printf("\n"); -/* - Command line options - - v - version - h - help - B - display size as 10^X - b - display size in bytes - s - display size as 2^z - o - omit folders - will not omit folder aliases - a - display all (including hidden . files) - p - print full file path - l - when printing size, print physical size, not logical size - L - print label name - - [-f fork] - select which fork to print size of - - c - calculate folder sizes ** NOT IMPLEMENTED YET ** - i - calculate number of files within folders ** NOT IMPLEMENTED YET ** + printf("%s:\n", argv[i]); + } -*/ + ListDirectoryContents( argv[i] ); + } + } + else + { + /* If no path is specified as argument, we use the current working directory */ + cwd = getcwd( buf, sizeof(buf) ); -/*////////////////////////////////////// -// Main program function -/////////////////////////////////////*/ -int main (int argc, char *argv[]) -{ - int i; - int rc; - int optch; - static char optstring[] = OPT_STRING; - char buf[MAX_PATH_LENGTH]; - char *cwd; - - while ( (optch = getopt(argc, argv, optstring)) != -1) + if( !cwd ) { - switch(optch) - { - case 'v': - PrintVersion(); - return EX_OK; - break; - case 'h': - PrintHelp(); - return EX_OK; - break; - case 'f': - forkToDisplay = GetForkParameterFromString(optarg); - break; - case 'F': - foldersOnly = true; - break; - case 'b': - useBytesForSize = true; - break; - case 'o': - omitFolders = true; - break; - case 'a': - displayAll = true; - break; - case 'p': - printFullPath = true; - break; - case 'l': - physicalSize = true; - break; - case 'L': - printLabelName = true; - break; - case 'Q': - useQuotes = true; - break; - default: /* '?' */ - rc = 1; - PrintHelp(); - return EX_USAGE; - } + fprintf(stderr, "Error getting working directory.\n"); + return(EX_IOERR); } + ListDirectoryContents( cwd ); + } - argc -= optind; - argv += optind; - - if(argc) - { - for(i=0; i 1 ) - { - if( i > 0 ) - { - printf("\n"); - } - printf("%s:\n", argv[i]); - } - ListDirectoryContents( argv[i] ); - } - } - else - { - /* If no path is specified as argument, we use the current working directory */ - cwd = getcwd( buf, sizeof(buf) ); - - if( !cwd ) - { - fprintf(stderr, "Error getting working directory.\n"); - return(EX_IOERR); - } - ListDirectoryContents( cwd ); - } - - return(EX_OK); + return EX_OK; } -#pragma mark - - - -/*////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////*/ - static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -/*////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////*/ - static void PrintHelp (void) { - printf("usage: %s\n", USAGE_STRING); + printf("usage: %s\n", USAGE_STRING); } -#pragma mark - - /*////////////////////////////////////// // Iterate through directory and list its items /////////////////////////////////////*/ - static void ListDirectoryContents(char *pathPtr) { - char path[MAX_PATH_LENGTH + MAX_FILENAME_LENGTH + 1]; - DIR *directory; - struct dirent *dentry; - char *sizeStrTot; // total of files in folder others folders excluded - - if (!pathPtr[0]) - { - fprintf(stderr, "Invalid directory parameter.\n"); - exit(EX_USAGE); - } - - /* open directory */ - directory = opendir(pathPtr); - - /* if it's invalid, we return with an error */ - if (!directory) - { - perror(pathPtr); - exit(EX_USAGE); - } - - errno = 0; + char path[MAX_PATH_LENGTH + MAX_FILENAME_LENGTH + 1]; + DIR *directory; + struct dirent *dentry; + char *sizeStrTot; // total of files in folder others folders excluded + + if (!pathPtr[0]) + { + fprintf(stderr, "Invalid directory parameter.\n"); + exit(EX_USAGE); + } - /* iterate through the specified directory's contents */ - while( (dentry = readdir(directory)) ) - { - /* create the file's full path */ - strcpy(path, pathPtr); - strcat(path, "/"); - strcat(path, (char *)&dentry->d_name); + /* open directory */ + directory = opendir(pathPtr); - ListItem(path, (char *)&dentry->d_name); + /* if it's invalid, we return with an error */ + if (!directory) + { + perror(pathPtr); + exit(EX_USAGE); + } + + errno = 0; + + /* iterate through the specified directory's contents */ + while( (dentry = readdir(directory)) ) + { + /* create the file's full path */ + strcpy(path, pathPtr); + strcat(path, "/"); + strcat(path, (char *)&dentry->d_name); - errno = 0; - } + ListItem(path, (char *)&dentry->d_name); - // report total of all files in folder other folders size are not included - - sizeStrTot = useBytesForSize ? GetSizeString(totalFolderSize) : GetHumanSizeString(totalFolderSize); - - printf(" %s\n","----------------------------------------------" ); - printf(" %s %s\n", sizeStrTot, "Total Size of Files in Folder" ); + errno = 0; + } + // report total of all files in folder other folders size are not included + sizeStrTot = useBytesForSize ? GetSizeString(totalFolderSize) : GetHumanSizeString(totalFolderSize); - /* report errors and close dir */ - if (errno != 0) - perror("readdir(3)"); + printf(" %s\n","----------------------------------------------" ); + printf(" %s %s\n", sizeStrTot, "Total Size of Files in Folder" ); - if (closedir(directory) == -1) - perror("closedir(3)"); -} + /* report errors and close dir */ + if (errno != 0) + perror("readdir(3)"); + if (closedir(directory) == -1) + perror("closedir(3)"); +} /*////////////////////////////////////// // List some item in directory /////////////////////////////////////*/ - static void ListItem (char *path, char *name) { - FSRef fileRef; - OSErr err = noErr; - short isFldr; + FSRef fileRef; + OSErr err = noErr; + short isFldr; + + /* unless the -a paramter is passed, we don't list hidden .* files */ + if (name[0] == '.' && !displayAll) + return; + + /* Get file ref to the file or folder pointed to by the path */ + err = FSPathMakeRef((unsigned char *)path, &fileRef, NULL); + + if (err != noErr) + { + if (err != VOL_NOT_FOUND) // suppress error with files or folders like /.vol or /dev + fprintf(stderr, "FSPathMakeRef(): Error %d returned when getting file reference from %s\n", err, path); + return; + } - /* unless the -a paramter is passed, we don't list hidden .* files */ - if (name[0] == '.' && !displayAll) - return; + /* Check if we're dealing with a folder */ + isFldr = UnixIsFolder(path); - /* Get file ref to the file or folder pointed to by the path */ - err = FSPathMakeRef((unsigned char *)path, &fileRef, NULL); + if (isFldr == -1)/* an error occurred in stat */ + { + perror(path); + return; + } - if (err != noErr) - { - if (err != VOL_NOT_FOUND) // suppress error with files or folders like /.vol or /dev - fprintf(stderr, "FSPathMakeRef(): Error %d returned when getting file reference from %s\n", err, path); - return; - } - - /* Check if we're dealing with a folder */ - isFldr = UnixIsFolder(path); - // printf("isFldr : %d %s\n", isFldr, path); - - if (isFldr == -1)/* an error occurred in stat */ + /* if (isFldr) // it's a folder + { + if (!omitFolders) + ListFolder(name, path, fileRef); + } + else // regular file + { + if (!foldersOnly) + ListFile(name, path, fileRef); + } */ + + if (!isFldr) // it's a regular file + { + if (!foldersOnly) + ListFile(name, path, fileRef); + } + else + { + if (isFldr == IS_SYMLINK) { - perror(path); - return; + if (!foldersOnly) + { + err = MyFSPathMakeRef ((unsigned char *)path, &fileRef); + ListFile(name, path, fileRef); + } } - - /* if (isFldr) // it's a folder + else { - if (!omitFolders) - ListFolder(name, path, fileRef); + if (!omitFolders) + ListFolder(name, path, fileRef); } - else // regular file - { - if (!foldersOnly) - ListFile(name, path, fileRef); - } */ - - if (!isFldr) // it's a regular file - { - if (!foldersOnly) - ListFile(name, path, fileRef); - } - else - { - if (isFldr == IS_SYMLINK) - { - if (!foldersOnly) - { - err = MyFSPathMakeRef ((unsigned char *)path, &fileRef); - ListFile(name, path, fileRef); - } - } - else - { - if (!omitFolders) - ListFolder(name, path, fileRef); - } - } + } } - /*////////////////////////////////////// // Print directory item info for a file /////////////////////////////////////*/ - static void ListFile(char *name, char *path, FSRef fileRef) { - /* File manager structures */ - FInfo finderInfo; - - char fileType[5]; - char creatorType[5]; - char *sizeStr; - char quote; - char fflagstr[7]; - char *fileName; - char *aliasSrcPath; - - UInt64 totalPhysicalSize; - UInt64 totalLogicalSize; - // long size; - UInt64 size; - - short labelNum; - OSErr err = noErr; - - /* retrieve filespec from file ref */ - FSCatalogInfo cinfo; - err = FSGetCatalogInfo (&fileRef, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); - if (err != noErr) - { - fprintf(stderr, "FSGetCatalogInfo(): Error %d getting finder info from file reference", err); - exit(EX_IOERR); - } + /* File manager structures */ + FInfo finderInfo; + + char fileType[5]; + char creatorType[5]; + char *sizeStr; + char quote; + char fflagstr[7]; + char *fileName; + char *aliasSrcPath; + + UInt64 totalPhysicalSize; + UInt64 totalLogicalSize; + UInt64 size; + + short labelNum; + OSErr err = noErr; + + /* retrieve filespec from file ref */ + FSCatalogInfo cinfo; + err = FSGetCatalogInfo (&fileRef, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); + if (err != noErr) + { + fprintf(stderr, "FSGetCatalogInfo(): Error %d getting finder info from file reference", err); + exit(EX_IOERR); + } - /* get the finder info */ - finderInfo = *(FInfo*)cinfo.finderInfo; + /* get the finder info */ + finderInfo = *(FInfo*)cinfo.finderInfo; - /* ///// Finder flags////// */ - - /* Is Invisible */ - fflagstr[0] = (finderInfo.fdFlags & kIsInvisible) ? 'I' : '-'; + /* ///// Finder flags////// */ - /* Has Custom Icon */ - fflagstr[1] = (finderInfo.fdFlags & kHasCustomIcon) ? 'C' : '-'; + /* Is Invisible */ + fflagstr[0] = (finderInfo.fdFlags & kIsInvisible) ? 'I' : '-'; - /* Is Locked */ - fflagstr[2] = (finderInfo.fdFlags & kNameLocked) ? 'L' : '-'; + /* Has Custom Icon */ + fflagstr[1] = (finderInfo.fdFlags & kHasCustomIcon) ? 'C' : '-'; - /* Has Bundle Bit Set */ - fflagstr[3] = (finderInfo.fdFlags & kHasBundle) ? 'B' : '-'; + /* Is Locked */ + fflagstr[2] = (finderInfo.fdFlags & kNameLocked) ? 'L' : '-'; - /* Is Alias */ - fflagstr[4] = (finderInfo.fdFlags & kIsAlias) ? 'A' : '-'; + /* Has Bundle Bit Set */ + fflagstr[3] = (finderInfo.fdFlags & kHasBundle) ? 'B' : '-'; - /* Is Stationery */ - fflagstr[5] = (finderInfo.fdFlags & kIsStationery) ? 'S' : '-'; + /* Is Alias */ + fflagstr[4] = (finderInfo.fdFlags & kIsAlias) ? 'A' : '-'; - fflagstr[6] = '\0'; + /* Is Stationery */ + fflagstr[5] = (finderInfo.fdFlags & kIsStationery) ? 'S' : '-'; - /* ///// File/Creator types ///// */ + fflagstr[6] = '\0'; - /* get file type string */ - OSTypeToStr(finderInfo.fdType, fileType); + /* ///// File/Creator types ///// */ - /* get creator type string */ - OSTypeToStr(finderInfo.fdCreator, creatorType); + /* get file type string */ + OSTypeToStr(finderInfo.fdType, fileType); - /* ///// File Sizes ////// */ - err = GetForkSizes(&fileRef, &totalLogicalSize, &totalPhysicalSize, forkToDisplay); - if (err != noErr) - { - fprintf(stderr, "GetForkSizes(): Error %d getting size of file forks\n", err); - exit(EX_IOERR); - } + /* get creator type string */ + OSTypeToStr(finderInfo.fdCreator, creatorType); - /*//////////////////////////// - // This needs to be fixed in the future - // The size of files larger than 4GB is not displayed correctly due - // due the use of a long int to store file size - ////////////////////////////*/ - size = physicalSize ? totalPhysicalSize : totalLogicalSize; - - size = totalLogicalSize; - - totalFolderSize += size; // update the total with the current file - - sizeStr = useBytesForSize ? GetSizeString(size) : GetHumanSizeString(size); - - /* if the -Q option is specified */ - quote = useQuotes ? '"' : ' '; - - /* if the -p option is specified */ - fileName = printFullPath ? path : name; - - - // Print label - if (printLabelName) - { - labelNum = GetLabelNumber(finderInfo.fdFlags); - printf("%s ", (char *)&labelNames[labelNum]); - } - /* /////// Print output for this directory item //////// */ - if (finderInfo.fdFlags & kIsAlias) - { - aliasSrcPath = GetPathOfAliasSource(path); - printf("%s %4s %4s %s %c%s%c-->%c%s%c\n", fflagstr, fileType, creatorType, sizeStr, quote, fileName, quote, quote, aliasSrcPath, quote); - } - else - printf("%s %4s %4s %s %c%s%c\n", fflagstr, fileType, creatorType, sizeStr, quote, fileName, quote); + /* ///// File Sizes ////// */ + err = GetForkSizes(&fileRef, &totalLogicalSize, &totalPhysicalSize, forkToDisplay); + if (err != noErr) + { + fprintf(stderr, "GetForkSizes(): Error %d getting size of file forks\n", err); + exit(EX_IOERR); + } + + /*//////////////////////////// + // This needs to be fixed in the future + // The size of files larger than 4GB is not displayed correctly due + // due the use of a long int to store file size + ////////////////////////////*/ + size = physicalSize ? totalPhysicalSize : totalLogicalSize; + + size = totalLogicalSize; + + totalFolderSize += size; // update the total with the current file + + sizeStr = useBytesForSize ? GetSizeString(size) : GetHumanSizeString(size); + + /* if the -Q option is specified */ + quote = useQuotes ? '"' : ' '; + + /* if the -p option is specified */ + fileName = printFullPath ? path : name; + + // Print label + if (printLabelName) + { + labelNum = GetLabelNumber(finderInfo.fdFlags); + printf("%s ", (char *)&labelNames[labelNum]); + } + /* /////// Print output for this directory item //////// */ + if (finderInfo.fdFlags & kIsAlias) + { + aliasSrcPath = GetPathOfAliasSource(path); + printf("%s %4s %4s %s %c%s%c-->%c%s%c\n", fflagstr, fileType, creatorType, sizeStr, quote, fileName, quote, quote, aliasSrcPath, quote); + } + else + printf("%s %4s %4s %s %c%s%c\n", fflagstr, fileType, creatorType, sizeStr, quote, fileName, quote); } /*////////////////////////////////////// @@ -555,107 +493,98 @@ static void ListFile(char *name, char *path, FSRef fileRef) /////////////////////////////////////*/ static void ListFolder (char *name, char *path, FSRef fileRef) { - char quote; - long valence; - char *numFilesStr; - char *fileName; - char fflagstr[7]; - short labelNum; - const char *sizeStr; - const char *humanSizeStr = " - "; - const char *byteSizeStr = " - "; - DInfo dInfo;//directory information - - /* - * Retrieve number of files within folder from the - * FSCatalog record - */ - valence = GetNumFilesInFolder(&fileRef); - if (valence == -1)/* error */ - { - fprintf(stderr, "%s: Error getting number of files in folder\n", name); - return; - } + char quote; + long valence; + char *numFilesStr; + char *fileName; + char fflagstr[7]; + short labelNum; + const char *sizeStr; + const char *humanSizeStr = " - "; + const char *byteSizeStr = " - "; + DInfo dInfo;//directory information + + /* + * Retrieve number of files within folder from the + * FSCatalog record + */ + valence = GetNumFilesInFolder(&fileRef); + if (valence == -1)/* error */ + { + fprintf(stderr, "%s: Error getting number of files in folder\n", name); + return; + } - /* generate a suitable-length string from this number */ - numFilesStr = GetNumFilesString(valence); - if (!numFilesStr) - { - fprintf(stderr, "%s: Error getting number of files in folder\n", name); - return; - } - - /* modify according to the options specified */ - fileName = printFullPath ? path : name; + /* generate a suitable-length string from this number */ + numFilesStr = GetNumFilesString(valence); + if (!numFilesStr) + { + fprintf(stderr, "%s: Error getting number of files in folder\n", name); + return; + } - sizeStr = useBytesForSize ? byteSizeStr : humanSizeStr; + /* modify according to the options specified */ + fileName = printFullPath ? path : name; - quote = useQuotes ? '"' : ' '; + sizeStr = useBytesForSize ? byteSizeStr : humanSizeStr; - GetDInfo(&fileRef, &dInfo); + quote = useQuotes ? '"' : ' '; - - /* Is Invisible */ - fflagstr[0] = (dInfo.frFlags & kIsInvisible) ? 'I' : '-'; + GetDInfo(&fileRef, &dInfo); - /* Has Custom Icon */ - fflagstr[1] = (dInfo.frFlags & kHasCustomIcon) ? 'C' : '-'; + /* Is Invisible */ + fflagstr[0] = (dInfo.frFlags & kIsInvisible) ? 'I' : '-'; - /* Is Locked */ - fflagstr[2] = (dInfo.frFlags & kNameLocked) ? 'L' : '-'; + /* Has Custom Icon */ + fflagstr[1] = (dInfo.frFlags & kHasCustomIcon) ? 'C' : '-'; - /* Has Bundle Bit Set */ - fflagstr[3] = (dInfo.frFlags & kHasBundle) ? 'B' : '-'; + /* Is Locked */ + fflagstr[2] = (dInfo.frFlags & kNameLocked) ? 'L' : '-'; - /* Is Alias */ - fflagstr[4] = (dInfo.frFlags & kIsAlias) ? 'A' : '-'; + /* Has Bundle Bit Set */ + fflagstr[3] = (dInfo.frFlags & kHasBundle) ? 'B' : '-'; - /* Is Stationery */ - fflagstr[5] = (dInfo.frFlags & kIsStationery) ? 'S' : '-'; + /* Is Alias */ + fflagstr[4] = (dInfo.frFlags & kIsAlias) ? 'A' : '-'; - fflagstr[6] = '\0'; + /* Is Stationery */ + fflagstr[5] = (dInfo.frFlags & kIsStationery) ? 'S' : '-'; - - - // get label - if (printLabelName) - { - labelNum = GetLabelNumber(dInfo.frFlags); - printf("%s ", (char *)&labelNames[labelNum]); - } - - //print out line - printf("%s %s %s %c%s/%c\n", fflagstr, numFilesStr, sizeStr, quote, fileName, quote); - - return; - -} + fflagstr[6] = '\0'; + + // get label + if (printLabelName) + { + labelNum = GetLabelNumber(dInfo.frFlags); + printf("%s ", (char *)&labelNames[labelNum]); + } -#pragma mark - + printf("%s %s %s %c%s/%c\n", fflagstr, numFilesStr, sizeStr, quote, fileName, quote); + + return; +} /*////////////////////////////////////// // Generate a string for number of files within a folder /////////////////////////////////////*/ - static char* GetNumFilesString (long numFiles) { - static char numFilesStr[11]; - - /* there can't be less than 0 files in a folder...duh */ - if (numFiles < 0) - return NULL; - - /* we list a maximum of 9999 files within folder - this needs to be fixed at some point */ - if (numFiles > 9999) - numFiles = 9999; - - /* create a string that contains just the number */ - sprintf(numFilesStr, "%4d items", (int)numFiles); - - return numFilesStr; -} + static char numFilesStr[11]; + + /* there can't be less than 0 files in a folder...duh */ + if (numFiles < 0) + return NULL; + + /* we list a maximum of 9999 files within folder + this needs to be fixed at some point */ + if (numFiles > 9999) + numFiles = 9999; + /* create a string that contains just the number */ + sprintf(numFilesStr, "%4d items", (int)numFiles); + + return numFilesStr; +} /*////////////////////////////////////// // Get the number of files contained within @@ -663,17 +592,16 @@ static char* GetNumFilesString (long numFiles) /////////////////////////////////////*/ static long GetNumFilesInFolder (FSRef *fileRef) { - OSErr err; - FSCatalogInfo catInfo; - - /* access the FSCatalog record to get the number of files */ - err = FSGetCatalogInfo(fileRef, kFSCatInfoValence, &catInfo, NULL, NULL, NULL); + OSErr err; + FSCatalogInfo catInfo; - if (err) - return(-1); + /* access the FSCatalog record to get the number of files */ + err = FSGetCatalogInfo(fileRef, kFSCatInfoValence, &catInfo, NULL, NULL, NULL); - return (catInfo.valence); + if (err) + return -1; + return catInfo.valence; } /*////////////////////////////////////// @@ -683,193 +611,178 @@ static long GetNumFilesInFolder (FSRef *fileRef) /////////////////////////////////////*/ short GetForkParameterFromString (char *str) { - if (strlen(str) != 4) - { - fprintf(stderr, "Illegal parameter: %s\nYou must specify one of the following: rsrc, data, both", str); - exit(EX_USAGE); - } + if (strlen(str) != 4) + { + fprintf(stderr, "Illegal parameter: %s\nYou must specify one of the following: rsrc, data, both", str); + exit(EX_USAGE); + } - if (!strcmp((char *)&RSRC_FORK_PARAM_NAME, str)) - { - /* resource fork specified - 'rsrc' */ - return DISPLAY_FORK_RSRC; - } - else if (!strcmp((char *)&DATA_FORK_PARAM_NAME, str)) - { - /* data fork specified - 'data' */ - return DISPLAY_FORK_DATA; - } - else if (!strcmp((char *)&BOTH_FORK_PARAM_NAME, str)) - { - /* both forks specified - 'both' */ - return DISPLAY_FORK_BOTH; - } + if (!strcmp((char *)&RSRC_FORK_PARAM_NAME, str)) + { + /* resource fork specified - 'rsrc' */ + return DISPLAY_FORK_RSRC; + } + else if (!strcmp((char *)&DATA_FORK_PARAM_NAME, str)) + { + /* data fork specified - 'data' */ + return DISPLAY_FORK_DATA; + } + else if (!strcmp((char *)&BOTH_FORK_PARAM_NAME, str)) + { + /* both forks specified - 'both' */ + return DISPLAY_FORK_BOTH; + } - fprintf(stderr, "Illegal parameter: %s\nYou must specify one of the following: rsrc, data, both\n", str); - exit(EX_USAGE); + fprintf(stderr, "Illegal parameter: %s\nYou must specify one of the following: rsrc, data, both\n", str); + exit(EX_USAGE); - /* to appease the compiler */ - return 0; + /* to appease the compiler */ + return 0; } - /*////////////////////////////////////// // Generate file size string in bytes /////////////////////////////////////*/ - -// static char* GetSizeString (long size) static char* GetSizeString (UInt64 size) { - // static char sizeStr[15]; - static char sizeStr[17]; - - // sprintf(sizeStr, "%12d B", (int)size); - sprintf(sizeStr, "%15llu B",size ); - return sizeStr; + static char sizeStr[17]; + + sprintf(sizeStr, "%15llu B", size); + return sizeStr; } /*////////////////////////////////////// // Generate file size string in human readable format /////////////////////////////////////*/ - static char* GetHumanSizeString (UInt64 size) { - static char humanSizeStr[13]; + static char humanSizeStr[13]; - if (size < 1024) - { - /* bytes */ - sprintf(humanSizeStr, " %6d B", (int)size); - } - else if (size < 1048576) { - /* kbytes */ - sprintf(humanSizeStr, " %6.1f KB", size / 1024.0); - } - else if (size < 1073741824) - { - /* megabytes */ - sprintf(humanSizeStr, " %6.1f MB", size / 1048576.0); - } - else - { - /* gigabytes */ - sprintf(humanSizeStr, " %6.1f GB", size / 1073741824.0); - } + if (size < 1024) + { + /* bytes */ + sprintf(humanSizeStr, " %6d B", (int)size); + } + else if (size < 1048576) { + /* kbytes */ + sprintf(humanSizeStr, " %6.1f KB", size / 1024.0); + } + else if (size < 1073741824) + { + /* megabytes */ + sprintf(humanSizeStr, " %6.1f MB", size / 1048576.0); + } + else + { + /* gigabytes */ + sprintf(humanSizeStr, " %6.1f GB", size / 1073741824.0); + } - return (humanSizeStr); + return (humanSizeStr); } /*////////////////////////////////////////// -// Function to get size of file forks +// Get size of file forks //////////////////////////////////////////*/ - -static OSErr GetForkSizes (const FSRef *fileRef, UInt64 *totalLogicalForkSize, UInt64 *totalPhysicalForkSize, short fork) +static OSErr GetForkSizes (const FSRef *fileRef, UInt64 *totalLogicalForkSize, UInt64 *totalPhysicalForkSize, short fork) { - /* - the fork paramater can be one of three possible values - - 0 - Both forks - 1 - Data fork - 2 - Resource fork - - */ - - OSErr err; - CatPositionRec forkIterator; - - SInt64 forkLogicalSize = (SInt64)NULL; - SInt64 *forkLogicalSizePtr; - UInt64 forkPhysicalSize = (UInt64)NULL; - UInt64 *forkPhysicalSizePtr; - - HFSUniStr255 forkName; - char forkStr[255]; - - /* if logical fork size is needed */ - if (totalLogicalForkSize) - { - *totalLogicalForkSize = 0; - forkLogicalSizePtr = &forkLogicalSize; - } - else - { - forkLogicalSizePtr = NULL; - } - - /* if physical fork size is needed */ - if (totalPhysicalForkSize) - { - *totalPhysicalForkSize = 0; - forkPhysicalSizePtr = &forkPhysicalSize; - } - else - { - forkPhysicalSizePtr = NULL; - } - - /* Iterate through the file's forks and get their combined size */ - forkIterator.initialize = 0; + /* + the fork paramater can be one of three possible values + + 0 - Both forks + 1 - Data fork + 2 - Resource fork + */ + + OSErr err; + CatPositionRec forkIterator; + + SInt64 forkLogicalSize = (SInt64)NULL; + SInt64 *forkLogicalSizePtr; + UInt64 forkPhysicalSize = (UInt64)NULL; + UInt64 *forkPhysicalSizePtr; + + HFSUniStr255 forkName; + char forkStr[255]; + + /* if logical fork size is needed */ + if (totalLogicalForkSize) + { + *totalLogicalForkSize = 0; + forkLogicalSizePtr = &forkLogicalSize; + } + else + { + forkLogicalSizePtr = NULL; + } - do + /* if physical fork size is needed */ + if (totalPhysicalForkSize) + { + *totalPhysicalForkSize = 0; + forkPhysicalSizePtr = &forkPhysicalSize; + } + else + { + forkPhysicalSizePtr = NULL; + } + + /* Iterate through the file's forks and get their combined size */ + forkIterator.initialize = 0; + + do + { + err = FSIterateForks(fileRef, &forkIterator, &forkName, forkLogicalSizePtr, forkPhysicalSizePtr); + if (noErr == err) { - err = FSIterateForks(fileRef, &forkIterator, &forkName, forkLogicalSizePtr, forkPhysicalSizePtr); - if (noErr == err) + HFSUniPStrToCString(&forkName, (char *)&forkStr); + + /* if it's the resource fork we're doing now */ + if (!strcmp((char *)&"RESOURCE_FORK", (char *)&forkStr)) + { + /* if we're not just displaying the data fork */ + if (fork != DISPLAY_FORK_DATA) { - HFSUniPStrToCString(&forkName, (char *)&forkStr); - - /* if it's the resource fork we're doing now */ - if (!strcmp((char *)&"RESOURCE_FORK", (char *)&forkStr)) - { - /* if we're not just displaying the data fork */ - if (fork != DISPLAY_FORK_DATA) - { - if (totalLogicalForkSize) - { - *totalLogicalForkSize += forkLogicalSize; - } - if (totalPhysicalForkSize) - { - *totalPhysicalForkSize += forkPhysicalSize; - } - } - } - else/* must be the data fork, then */ - { - if (fork != DISPLAY_FORK_RSRC) - { - if (totalLogicalForkSize) - { - *totalLogicalForkSize += forkLogicalSize; - } - if (totalPhysicalForkSize) - { - *totalPhysicalForkSize += forkPhysicalSize; - } - } - } + if (totalLogicalForkSize) + { + *totalLogicalForkSize += forkLogicalSize; + } + if (totalPhysicalForkSize) + { + *totalPhysicalForkSize += forkPhysicalSize; + } } - - } while (err == noErr); - - /* errFSNoMoreItems is not serious, we report other errors */ - if (err && err != errFSNoMoreItems) - { - return err; - } - else - { - err = noErr; + } + else/* must be the data fork, then */ + { + if (fork != DISPLAY_FORK_RSRC) + { + if (totalLogicalForkSize) + { + *totalLogicalForkSize += forkLogicalSize; + } + if (totalPhysicalForkSize) + { + *totalPhysicalForkSize += forkPhysicalSize; + } + } + } } - - return(err); -} - + } while (err == noErr); + /* errFSNoMoreItems is not serious, we report other errors */ + if (err && err != errFSNoMoreItems) + { + return err; + } + else + { + err = noErr; + } - -#pragma mark - - + return(err); +} /*////////////////////////////////////// // Transform OSType into a C string @@ -878,11 +791,11 @@ static OSErr GetForkSizes (const FSRef *fileRef, UInt64 *totalLogicalForkSize, /////////////////////////////////////*/ void OSTypeToStr(OSType aType, char *aStr) { - aStr[0] = (aType >> 24) & 0xFF; - aStr[1] = (aType >> 16) & 0xFF; - aStr[2] = (aType >> 8) & 0xFF; - aStr[3] = aType & 0xFF; - aStr[4] = 0; + aStr[0] = (aType >> 24) & 0xFF; + aStr[1] = (aType >> 16) & 0xFF; + aStr[2] = (aType >> 8) & 0xFF; + aStr[3] = aType & 0xFF; + aStr[4] = 0; } /*////////////////////////////////////// @@ -892,88 +805,88 @@ void OSTypeToStr(OSType aType, char *aStr) /////////////////////////////////////*/ static int UnixIsFolder (char *path) { - struct stat filestat; - short err; - short i; // file type 0 = regular 1 = folder - - // err = stat(path, &filestat); - err = lstat(path, &filestat); // use lstat for symlinks - - if (err == -1) - return err; - - // return (S_ISREG(filestat.st_mode) != 1); - - i = (S_ISREG(filestat.st_mode) != 1); // only 0 for regular files - - if ( !i ) - return ( i ); - - i = (S_ISLNK(filestat.st_mode) != 1); // only 0 for symlinks - - if ( !i ) - { - return ( IS_SYMLINK ); - } - else - { - return ( i ); - } + struct stat filestat; + short err; + short i; // file type 0 = regular 1 = folder + + // err = stat(path, &filestat); + err = lstat(path, &filestat); // use lstat for symlinks + + if (err == -1) + return err; + + // return (S_ISREG(filestat.st_mode) != 1); + + i = (S_ISREG(filestat.st_mode) != 1); // only 0 for regular files + + if ( !i ) + return ( i ); + + i = (S_ISLNK(filestat.st_mode) != 1); // only 0 for symlinks + + if ( !i ) + { + return ( IS_SYMLINK ); + } + else + { + return ( i ); + } } /**************************************************************************************/ - /* Due to a bug in the X File Manager, 2489632, */ - /* FSPathMakeRef doesn't handle symlinks properly. It */ - /* automatically resolves it and returns an FSRef to the */ - /* symlinks target, not the symlink itself. So this is a */ - /* little workaround for it... */ - /* */ - /* We could call lstat() to find out if the object is a */ - /* symlink or not before jumping into the guts of the */ - /* routine, but its just as simple, and fast when working */ - /* on a single item like this, to send everything through */ - /* this routine */ - +/* Due to a bug in the X File Manager, 2489632, */ +/* FSPathMakeRef doesn't handle symlinks properly. It */ +/* automatically resolves it and returns an FSRef to the */ +/* symlinks target, not the symlink itself. So this is a */ +/* little workaround for it... */ +/* */ +/* We could call lstat() to find out if the object is a */ +/* symlink or not before jumping into the guts of the */ +/* routine, but its just as simple, and fast when working */ +/* on a single item like this, to send everything through */ +/* this routine */ + static OSErr MyFSPathMakeRef( const unsigned char *path, FSRef *ref ) { - FSRef tmpFSRef; - char tmpPath[ MAX_PATH_LENGTH ], - *tmpNamePtr; - OSErr err; - - /* Get local copy of incoming path */ + FSRef tmpFSRef; + char tmpPath[ MAX_PATH_LENGTH ], *tmpNamePtr; + OSErr err; + + /* Get local copy of incoming path */ strcpy( tmpPath, (char*)path ); - /* Get the name of the object from the given path */ - /* Find the last / and change it to a '\0' so */ - /* tmpPath is a path to the parent directory of the */ - /* object and tmpNamePtr is the name */ + /* Get the name of the object from the given path */ + /* Find the last / and change it to a '\0' so */ + /* tmpPath is a path to the parent directory of the */ + /* object and tmpNamePtr is the name */ tmpNamePtr = strrchr( tmpPath, '/' ); if( *(tmpNamePtr + 1) == '\0' ) - { /* in case the last character in the path is a / */ + { + /* in case the last character in the path is a / */ *tmpNamePtr = '\0'; tmpNamePtr = strrchr( tmpPath, '/' ); } *tmpNamePtr = '\0'; tmpNamePtr++; - - /* Get the FSRef to the parent directory */ + + /* Get the FSRef to the parent directory */ err = FSPathMakeRef( (unsigned char*)tmpPath, &tmpFSRef, NULL ); if( err == noErr ) - { - /* Convert the name to a Unicode string and pass it */ - /* to FSMakeFSRefUnicode to actually get the FSRef */ - /* to the object (symlink) */ + { + /* Convert the name to a Unicode string and pass it */ + /* to FSMakeFSRefUnicode to actually get the FSRef */ + /* to the object (symlink) */ HFSUniStr255 uniName; err = ConvertCStringToHFSUniStr( tmpNamePtr, &uniName ); if( err == noErr ) err = FSMakeFSRefUnicode( &tmpFSRef, uniName.length, uniName.unicode, kTextEncodingUnknown, &tmpFSRef ); } - + if( err == noErr ) *ref = tmpFSRef; - + return err; } @@ -981,21 +894,21 @@ static OSErr MyFSPathMakeRef( const unsigned char *path, FSRef *ref ) static OSErr ConvertCStringToHFSUniStr(const char* cStr, HFSUniStr255 *uniStr) { - OSErr err = noErr; - CFStringRef tmpStringRef = CFStringCreateWithCString( kCFAllocatorDefault, cStr, kCFStringEncodingMacRoman ); - if( tmpStringRef != NULL ) - { - if( CFStringGetCString( tmpStringRef, (char*)uniStr->unicode, sizeof(uniStr->unicode), kCFStringEncodingUnicode ) ) - uniStr->length = CFStringGetLength( tmpStringRef ); - else - err = kCouldNotGetStringData; - - CFRelease( tmpStringRef ); - } - else - err = kCouldNotCreateCFString; - - return err; + OSErr err = noErr; + CFStringRef tmpStringRef = CFStringCreateWithCString( kCFAllocatorDefault, cStr, kCFStringEncodingMacRoman ); + if( tmpStringRef != NULL ) + { + if( CFStringGetCString( tmpStringRef, (char*)uniStr->unicode, sizeof(uniStr->unicode), kCFStringEncodingUnicode ) ) + uniStr->length = CFStringGetLength( tmpStringRef ); + else + err = kCouldNotGetStringData; + + CFRelease( tmpStringRef ); + } + else + err = kCouldNotCreateCFString; + + return err; } /*////////////////////////////////////// @@ -1006,11 +919,11 @@ static OSErr ConvertCStringToHFSUniStr(const char* cStr, HFSUniStr255 *uniStr) /////////////////////////////////////*/ static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr) { - CFStringRef cfStr; + CFStringRef cfStr; + + cfStr = CFStringCreateWithCharacters(kCFAllocatorDefault,uniStr->unicode,uniStr->length); - cfStr = CFStringCreateWithCharacters(kCFAllocatorDefault,uniStr->unicode,uniStr->length); - - CFStringGetCString(cfStr, cstr, 255, kCFStringEncodingUTF8); + CFStringGetCString(cfStr, cstr, 255, kCFStringEncodingUTF8); } @@ -1021,77 +934,72 @@ static void HFSUniPStrToCString (HFSUniStr255 *uniStr, char *cstr) /////////////////////////////////////*/ static char* GetPathOfAliasSource (char *path) { - OSErr err = noErr; - static char srcPath[2000]; - FSRef fileRef; - Boolean isAlias, isFolder; - - //get file reference from path given - err = FSPathMakeRef (path, &fileRef, NULL); - if (err != noErr) - { - fprintf(stderr, "Error getting file spec from path.\n"); - return 0; - } - - //make sure we're dealing with an alias - err = FSIsAliasFile (&fileRef, &isAlias, &isFolder); - if (err != noErr) - { - //printf("Error determining alias properties.\n"); - return NULL; - } - if (!isAlias) - { - //printf("%s: Not an alias.\n", argv[1]); - return NULL; - } - - //resolve alias --> get file reference to file - err = FSResolveAliasFile (&fileRef, TRUE, &isFolder, &isAlias); - if (err != noErr) - { - //printf("Error resolving alias.\n"); - return NULL; - } - - //get path to file that alias points to - err = FSMakePath(fileRef, (char *)&srcPath, strlen(srcPath)); - if (err != noErr) - { - return NULL; - } - - return ((char *)&srcPath); -} + OSErr err = noErr; + static char srcPath[2000]; + FSRef fileRef; + Boolean isAlias, isFolder; + + //get file reference from path given + err = FSPathMakeRef (path, &fileRef, NULL); + if (err != noErr) + { + fprintf(stderr, "Error getting file spec from path.\n"); + return 0; + } + //make sure we're dealing with an alias + err = FSIsAliasFile (&fileRef, &isAlias, &isFolder); + if (err != noErr) + { + //printf("Error determining alias properties.\n"); + return NULL; + } + if (!isAlias) + { + //printf("%s: Not an alias.\n", argv[1]); + return NULL; + } + + //resolve alias --> get file reference to file + err = FSResolveAliasFile (&fileRef, TRUE, &isFolder, &isAlias); + if (err != noErr) + { + //printf("Error resolving alias.\n"); + return NULL; + } + + //get path to file that alias points to + err = FSMakePath(fileRef, (char *)&srcPath, strlen(srcPath)); + if (err != noErr) + { + return NULL; + } + + return ((char *)&srcPath); +} /*////////////////////////////////////// // Creates POSIX path string from FSRef /////////////////////////////////////*/ static OSStatus FSMakePath(FSRef fileRef, UInt8 *path, UInt32 maxPathSize) { - OSStatus result; - - result = FSRefMakePath(&fileRef, path, 2000); - - return ( result ); + return FSRefMakePath(&fileRef, path, 2000); } /*////////////////////////////////////// -// Returns directory info structure of +// Returns directory info structure of // file spec /////////////////////////////////////*/ static OSErr GetDInfo(const FSRef *ref, DInfo *dInfo) { - OSErr err = noErr; - - FSCatalogInfo cinfo; - err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); - if (err == noErr) { - *dInfo = *(DInfo*)cinfo.finderInfo; - } - return err; + OSErr err = noErr; + FSCatalogInfo cinfo; + + err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); + if (err == noErr) + *dInfo = *(DInfo*)cinfo.finderInfo; + + return err; } /*////////////////////////////////////// @@ -1101,33 +1009,33 @@ static OSErr GetDInfo(const FSRef *ref, DInfo *dInfo) /////////////////////////////////////*/ static short GetLabelNumber (short flags) { - /* Is Orange */ - if (flags & 2 && flags & 8 && flags & 4) - return 2; - - /* Is Red */ - if (flags & 8 && flags & 4) - return 1; - - /* Is Yellow */ - if (flags & 8 && flags & 2) - return 3; - - /* Is Blue */ - if (flags & 8) - return 5; - - /* Is Purple */ - if (flags & 2 && flags & 4) - return 6; - - /* Is Green */ - if (flags & 4) - return 4; - - /* Is Gray */ - if (flags & 2) - return 7; + /* Orange */ + if (flags & 2 && flags & 8 && flags & 4) + return 2; - return 0; -} \ No newline at end of file + /* Red */ + if (flags & 8 && flags & 4) + return 1; + + /* Yellow */ + if (flags & 8 && flags & 2) + return 3; + + /* Blue */ + if (flags & 8) + return 5; + + /* Purple */ + if (flags & 2 && flags & 4) + return 6; + + /* Green */ + if (flags & 4) + return 4; + + /* Gray */ + if (flags & 2) + return 7; + + return 0; +} diff --git a/mkalias/mkalias.1 b/mkalias/mkalias.1 index c996bec..7596639 100755 --- a/mkalias/mkalias.1 +++ b/mkalias/mkalias.1 @@ -1,46 +1,41 @@ -.\"/usr/share/misc/mdoc.template -.Dd Fri Apr 18 2003 -.Dt mkalias 1 -.Os Darwin -.Sh NAME -.Nm mkalias -.Nd Create MacOS Finder aliases -.Sh SYNOPSIS -.Nm -.Op Fl vhctr -.Op Ar source-file -.Op Ar target-alias -.Sh DESCRIPTION -.Ar mkalias -is similar to -.Ar ln -but creates MacOS Finder aliases instead of UNIX file system links. The alias created is identical to -aliases created manually using the Finder. The alias gets the source file's custom icon and -File and Creator type, and has the kIsAlias and kHasCustomIcon Finder flags set. -.Pp -The following options are accepted: -.Bl -tag -width -indent +.Dd April 9, 2015 +.Dt mkalias 1 +.Os Darwin +.Sh NAME +.Nm mkalias +.Nd create MacOS Finder aliases +.Sh SYNOPSIS +.Nm +.Op Fl chrtv +.Op Ar source-file +.Op Ar target-alias +.Sh DESCRIPTION +.Ar mkalias +is similar to +.Ar ln +but creates MacOS Finder aliases instead of UNIX file system links. The alias created is identical to +aliases created manually using the Finder. The alias gets the source file's custom icon and +File and Creator type, and has the kIsAlias and kHasCustomIcon Finder flags set. +.Pp +The following options are accepted: +.Bl -tag -width indent +.It Fl c +Do not copy source file's icon to target alias. +.It Fl h +Print usage and exit. .It Fl r -Make the alias relative instead of absolute. See http://developer.apple.com/technotes/tn/tn1188.html for why this is useful -.It Fl c -Omit copying source file's icon to target alias -.It Fl t -Source file's type and creator are not applied to the alias -.It Fl v -Print version and author -.It Fl h -Print help -.El -.Pp -.Sh FILES -.Bl -tag -width "/usr/local/bin/mkalias" -compact -.It Pa /usr/local/bin/mkalias -.El -.Sh SEE ALSO -.Xr ln 1 , -.Xr lsmac 1 , -.Xr setfctypes 1 , -.Xr setfflags 1 , -.Xr cpath 1 , -.Xr setsuffix 1 , -.Xr setfcomment 1 , \ No newline at end of file +Make the alias relative instead of absolute. +.It Fl t +Source file's type and creator are not applied to the alias +.It Fl v +Print version and exit. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/mkalias" -compact +.It Pa /usr/local/bin/mkalias +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr ln 1 diff --git a/mkalias/mkalias.c b/mkalias/mkalias.c index 68df517..10a4393 100755 --- a/mkalias/mkalias.c +++ b/mkalias/mkalias.c @@ -1,60 +1,52 @@ /* - mkalias - command line program to create MacOS aliases - Copyright (C) 2003 Sveinbjorn Thordarson + mkalias - command line program to create MacOS aliases - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + Copyright (C) 2003 Sveinbjorn Thordarson - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + CHANGES -/* CHANGES - - 0.5 - * Sysexits.h used for return values - - 0.4 - * Added support for creating relative aliases (see http://developer.apple.com/technotes/tn/tn1188.html for why this is useful) - * Fixed bug where mkalias would run without the required arguments and exit with major errors - - 0.3 - * Added setting of type and creator code for files (courtesy of Chris Bailey ) - * Can be switched off with the the -t flag - * Changed use of NewAliasMinimal (deprecated) to FSNewAliasMinimal (courtesy of Chris Bailey ) - * Fixed ill-formed usage string - * More informative error messages :) - - 0.2 - * Added custom icon copying and the -c flag option to turn it off. - * Internal methods made static. - - 0.1 - * Initial release of mkalias + 0.5 + * Sysexits.h used for return values -*/ + 0.4 + * Added support for creating relative aliases (see http://developer.apple.com/technotes/tn/tn1188.html for why this is useful) + * Fixed bug where mkalias would run without the required arguments and exit with major errors + 0.3 + * Added setting of type and creator code for files (courtesy of Chris Bailey ) + * Can be switched off with the the -t flag + * Changed use of NewAliasMinimal (deprecated) to FSNewAliasMinimal (courtesy of Chris Bailey ) + * Fixed ill-formed usage string + * More informative error messages :) -/* TODO - - * Ability to create symlink/alias combos -*/ + 0.2 + * Added custom icon copying and the -c flag option to turn it off. + * Internal methods made static. + 0.1 + * Initial release of mkalias +*/ /* - Command line options - - v - version - h - help - usage - c - don't copy custom icon - t - don't apply file and creator type of original - r - make it a relative alias - + TODO + + * Ability to create symlink/alias combos */ #include @@ -67,142 +59,129 @@ #include #include - -/////////////////// Definitions ////////////////// - -#define PROGRAM_STRING "mkalias" -#define VERSION_STRING "0.5" -#define AUTHOR_STRING "Sveinbjorn Thordarson" -#define OPT_STRING "vhctr" - - -/////////////////// Prototypes ////////////////// +#define PROGRAM_STRING "mkalias" +#define VERSION_STRING "0.5" +#define AUTHOR_STRING "Sveinbjorn Thordarson" +#define OPT_STRING "chrtv" static void CreateAlias (char *srcPath, char *destPath); static short UnixIsFolder (char *path); static void PrintVersion (void); static void PrintHelp (void); -///////////////// globals //////////////////// +short noCustomIconCopy = false; +short noCopyFileCreatorTypes = false; +short makeRelativeAlias = false; -short noCustomIconCopy = false; -short noCopyFileCreatorTypes = false; -short makeRelativeAlias = false; - -//////////////////////////////////////////// -// main program function -//////////////////////////////////////////// int main (int argc, const char * argv[]) { - int rc; - int optch; - static char optstring[] = OPT_STRING; + int optch; + static char optstring[] = OPT_STRING; - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) - { - switch(optch) - { - case 'v': - PrintVersion(); - return EX_OK; - break; - case 'h': - PrintHelp(); - return EX_OK; - break; - case 'c': - noCustomIconCopy = true; - break; - case 't': - noCopyFileCreatorTypes = true; - break; - case 'r': - makeRelativeAlias = true; - break; - default: // '?' - rc = 1; - PrintHelp(); - return EX_USAGE; - } - } - - //check if a correct number of arguments was submitted - if (argc - optind < 2) + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { - fprintf(stderr,"Too few arguments.\n"); + case 'v': + PrintVersion(); + return EX_OK; + case 'h': PrintHelp(); - return EX_USAGE; - } - - //check if file to be aliased exists - if (access(argv[optind], F_OK) == -1) - { - perror(argv[optind]); - return EX_NOINPUT; + return EX_OK; + case 'c': + noCustomIconCopy = true; + break; + case 't': + noCopyFileCreatorTypes = true; + break; + case 'r': + makeRelativeAlias = true; } - - //check if we can create alias in the specified location - if (access(argv[optind+1], F_OK) != -1) - { - fprintf(stderr, "%s: File exists\n", argv[optind+1]); - return EX_CANTCREAT; - } - - //create the alias - CreateAlias(/*source*/(char *)argv[optind], /*destination*/(char *)argv[optind+1]); - - return EX_OK; + } + + //check if a correct number of arguments was submitted + if (argc - optind < 2) + { + fprintf(stderr,"Too few arguments.\n"); + PrintHelp(); + return EX_USAGE; + } + + //check if file to be aliased exists + if (access(argv[optind], F_OK) == -1) + { + perror(argv[optind]); + return EX_NOINPUT; + } + + //check if we can create alias in the specified location + if (access(argv[optind+1], F_OK) != -1) + { + fprintf(stderr, "%s: File exists\n", argv[optind+1]); + return EX_CANTCREAT; + } + + CreateAlias(/*source*/(char *)argv[optind], /*destination*/(char *)argv[optind+1]); + + return EX_OK; } -#pragma mark - - static OSErr FSGetFInfo(const FSRef* ref, FInfo *fInfo) { - FSCatalogInfo cinfo; - OSErr err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); - if (err != noErr) - return err; - *fInfo = *(FInfo*)cinfo.finderInfo; - return err; + FSCatalogInfo cinfo; + OSErr err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); + + if (err != noErr) + return err; + + *fInfo = *(FInfo*)cinfo.finderInfo; + return err; } static OSErr FSSetFInfo(const FSRef* ref, FInfo *fInfo) { - FSCatalogInfo cinfo; - *(FInfo*)cinfo.finderInfo = *fInfo; - OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo); - return err; + FSCatalogInfo cinfo; + *(FInfo*)cinfo.finderInfo = *fInfo; + + OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo); + return err; } static OSErr myFSCreateResFile(const char *path, OSType creator, OSType fileType, FSRef *outRef) { - int fd = open(path, O_CREAT | O_WRONLY, 0666); - if (fd == -1) { - perror("opening destination:"); - return bdNamErr; - } - close(fd); - - FSRef ref; - OSErr err = FSPathMakeRef((const UInt8*)path, &ref, NULL); - if (err != noErr) - return err; - - HFSUniStr255 rname; - FSGetResourceForkName(&rname); - err = FSCreateResourceFork(&ref, rname.length, rname.unicode, 0); - if (err != noErr) - return err; - - FInfo finfo; - err = FSGetFInfo(&ref, &finfo); - if (err != noErr) - return err; - finfo.fdCreator = creator; - finfo.fdType = fileType; - err = FSSetFInfo(&ref, &finfo); - if (err != noErr) - return err; - - *outRef = ref; - return noErr; + int fd = open(path, O_CREAT | O_WRONLY, 0666); + if (fd == -1) { + perror("opening destination:"); + return bdNamErr; + } + close(fd); + + FSRef ref; + + OSErr err = FSPathMakeRef((const UInt8*)path, &ref, NULL); + if (err != noErr) + return err; + + HFSUniStr255 rname; + FSGetResourceForkName(&rname); + + err = FSCreateResourceFork(&ref, rname.length, rname.unicode, 0); + if (err != noErr) + return err; + + FInfo finfo; + + err = FSGetFInfo(&ref, &finfo); + if (err != noErr) + return err; + + finfo.fdCreator = creator; + finfo.fdType = fileType; + + err = FSSetFInfo(&ref, &finfo); + if (err != noErr) + return err; + + *outRef = ref; + + return noErr; } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -211,243 +190,225 @@ static OSErr myFSCreateResFile(const char *path, OSType creator, OSType fileType // in the destPath, complete with custom icon and all. Pretty neat. // ////////////////////////////////////////////////////////////////////////////////////////////////// - static void CreateAlias (char *srcPath, char *destPath) { - OSErr err; - - FSSpec sourceFSSpec; - FSRef srcRef, destRef; - OSType srcFileType = (OSType)NULL; - OSType srcCreatorType = (OSType)NULL; - FInfo srcFinderInfo, destFinderInfo; - - int fd; - SInt16 rsrcRefNum; - - IconRef srcIconRef; - IconFamilyHandle srcIconFamily; - SInt16 theLabel; - - AliasHandle alias; - short isSrcFolder; - - //find out if we're dealing with a folder alias - isSrcFolder = UnixIsFolder(srcPath); - if (isSrcFolder == -1)//error + OSErr err; + + FSSpec sourceFSSpec; + FSRef srcRef, destRef; + OSType srcFileType = (OSType)NULL; + OSType srcCreatorType = (OSType)NULL; + FInfo srcFinderInfo, destFinderInfo; + + int fd; + SInt16 rsrcRefNum; + + IconRef srcIconRef; + IconFamilyHandle srcIconFamily; + SInt16 theLabel; + + AliasHandle alias; + short isSrcFolder; + + //find out if we're dealing with a folder alias + isSrcFolder = UnixIsFolder(srcPath); + if (isSrcFolder == -1)//error + { + fprintf(stderr, "UnixIsFolder(): Error doing a stat on %s\n", srcPath); + exit(EX_IOERR); + } + + ///////////////////// Get the FSRef's and FSSpec's for source and dest /////////////////// + + //get file ref to src + err = FSPathMakeRef(srcPath, &srcRef, NULL); + if (err != noErr) + { + fprintf(stderr, "FSPathMakeRef: Error %d getting file ref for source \"%s\"\n", err, srcPath); + exit(EX_IOERR); + } + + //retrieve source filespec from source file ref + err = FSGetCatalogInfo (&srcRef, NULL, NULL, NULL, &sourceFSSpec, NULL); + if (err != noErr) + { + fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec from source FSRef\n", err); + exit(EX_IOERR); + } + + //get the finder info for the source if it's a folder + if (!isSrcFolder) + { + err = FSGetFInfo (&srcRef, &srcFinderInfo); + if (err != noErr) { - fprintf(stderr, "UnixIsFolder(): Error doing a stat on %s\n", srcPath); - exit(EX_IOERR); + fprintf(stderr, "FSpGetFInfo(): Error %d getting Finder info for source \"%s\"\n", err, srcPath); + exit(EX_IOERR); } - - - ///////////////////// Get the FSRef's and FSSpec's for source and dest /////////////////// - - - //get file ref to src - err = FSPathMakeRef(srcPath, &srcRef, NULL); - if (err != noErr) - { - fprintf(stderr, "FSPathMakeRef: Error %d getting file ref for source \"%s\"\n", err, srcPath); - exit(EX_IOERR); - } - - //retrieve source filespec from source file ref - err = FSGetCatalogInfo (&srcRef, NULL, NULL, NULL, &sourceFSSpec, NULL); - if (err != noErr) - { - fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec from source FSRef\n", err); - exit(EX_IOERR); - } - - //get the finder info for the source if it's a folder - if (!isSrcFolder) - { - err = FSGetFInfo (&srcRef, &srcFinderInfo); - if (err != noErr) - { - fprintf(stderr, "FSpGetFInfo(): Error %d getting Finder info for source \"%s\"\n", err, srcPath); - exit(EX_IOERR); - } - srcFileType = srcFinderInfo.fdType; - srcCreatorType = srcFinderInfo.fdCreator; - } - - //////////////// Get the source file's icon /////////////////////// - - if (!noCustomIconCopy) - { - err = GetIconRefFromFileInfo(&srcRef, 0, NULL, 0, NULL, - kIconServicesNormalUsageFlag, &srcIconRef, &theLabel); - if (err != noErr) - { - fprintf(stderr, "GetIconRefFromFile(): Error getting source file's icon.\n"); - } - IconRefToIconFamily (srcIconRef, kSelectorAllAvailableData, &srcIconFamily); - } - - ///////////////////// Create the relevant alias record /////////////////// - - if (makeRelativeAlias) - { - // The following code for making relative aliases was borrowed from Apple. See the following technote: - // - // http://developer.apple.com/technotes/tn/tn1188.html - // - - // create the new file - err = myFSCreateResFile(destPath, 'TEMP', 'TEMP', &destRef); - if (err != noErr) - { - fprintf(stderr, "FSpCreateResFile(): Error %d while creating file\n", err); - exit(EX_CANTCREAT); - } - - //create the alias record, relative to the new alias file - err = FSNewAlias(&destRef, &srcRef, &alias); - if (err != noErr) - { - fprintf(stderr, "NewAlias(): Error %d while creating relative alias\n", err); - exit(EX_CANTCREAT); - } - - // save the resource - rsrcRefNum = FSOpenResFile(&destRef, fsRdWrPerm); - if (rsrcRefNum == -1) - { - err = ResError(); - fprintf(stderr, "Error %d while opening resource fork for %s\n", err, (char *)&destPath); - exit(EX_IOERR); - } - UseResFile(rsrcRefNum); - Str255 rname; - AddResource((Handle) alias, rAliasType, 0, NULL); - if ((err = ResError()) != noErr) - { - fprintf(stderr, "Error %d while adding alias resource for %s", err, (char *)&destPath); - exit(EX_IOERR); - } - if (!noCustomIconCopy) - { - //write the custom icon data - AddResource( (Handle)srcIconFamily, kIconFamilyType, kCustomIconResource, "\p"); - } - - CloseResFile(rsrcRefNum); - } - else - { - //create alias record from source spec - FSNewAliasMinimal (&srcRef, &alias); - if (alias == NULL) - { - fprintf(stderr, "NewAliasMinimal(): Null handle Alias returned from FSRef for file %s\n", srcPath); - exit(EX_IOERR); - } - - // Create alias resource file - // If we're dealing with a folder, we use the Finder types for folder - // Otherwise, we use the same File/Creator as source file - - if (isSrcFolder) - err = myFSCreateResFile(destPath, 'MACS', 'fdrp', &destRef); - else - err = myFSCreateResFile(destPath, ' ', ' ', &destRef); - if (err != noErr) - { - fprintf(stderr, "Error %d while creating alias file\n", err); - exit(EX_CANTCREAT); - } - - //open resource file and write the relevant resources - rsrcRefNum = FSOpenResFile (&destRef, 3); - - //write the alias resource - AddResource ((Handle)alias, 'alis', 0, NULL); - - if (!noCustomIconCopy) - { - //write the custom icon data - AddResource( (Handle)srcIconFamily, kIconFamilyType, kCustomIconResource, "\p"); - } - - CloseResFile(rsrcRefNum); - } - - - ///////////////////// Set the relevant finder flags for alias /////////////////// - - - //get finder info on newly created alias - err = FSGetFInfo (&destRef, &destFinderInfo); - if (err != noErr) - { - printf("FSpGetFInfo(): Error %d getting Finder info for target alias \"%s\"\n", err, destPath); - exit(EX_IOERR); - } - - // set the flags in finder data - // we set both alias flag and custom icon flag - // - if (!noCustomIconCopy) - destFinderInfo.fdFlags = destFinderInfo.fdFlags | 0x8000 | kHasCustomIcon; - else - destFinderInfo.fdFlags = destFinderInfo.fdFlags | 0x8000; - - //if it's not a folder alias the alias gets the same creator/type as original - if (!isSrcFolder && !noCopyFileCreatorTypes) - { - destFinderInfo.fdType = srcFileType; - destFinderInfo.fdCreator = srcCreatorType; - } - - err = FSSetFInfo (&destRef, &destFinderInfo); - if (err != noErr) - { - printf("FSpSetFInfo(): Error %d setting Finder Alias flag (0x8000).\n", err); - exit(EX_IOERR); - } -} + srcFileType = srcFinderInfo.fdType; + srcCreatorType = srcFinderInfo.fdCreator; + } + + //////////////// Get the source file's icon /////////////////////// + + if (!noCustomIconCopy) + { + err = GetIconRefFromFileInfo( + &srcRef, 0, NULL, 0, NULL, + kIconServicesNormalUsageFlag, &srcIconRef, &theLabel + ); + + if (err != noErr) + fprintf(stderr, "GetIconRefFromFile(): Error getting source file's icon.\n"); -#pragma mark - + IconRefToIconFamily (srcIconRef, kSelectorAllAvailableData, &srcIconFamily); + } + ///////////////////// Create the relevant alias record /////////////////// + + if (makeRelativeAlias) + { + // The following code for making relative aliases was borrowed from Apple. See the following technote: + // + // http://developer.apple.com/technotes/tn/tn1188.html + // + + // create the new file + err = myFSCreateResFile(destPath, 'TEMP', 'TEMP', &destRef); + if (err != noErr) + { + fprintf(stderr, "FSpCreateResFile(): Error %d while creating file\n", err); + exit(EX_CANTCREAT); + } + + //create the alias record, relative to the new alias file + err = FSNewAlias(&destRef, &srcRef, &alias); + if (err != noErr) + { + fprintf(stderr, "NewAlias(): Error %d while creating relative alias\n", err); + exit(EX_CANTCREAT); + } + + // save the resource + rsrcRefNum = FSOpenResFile(&destRef, fsRdWrPerm); + if (rsrcRefNum == -1) + { + err = ResError(); + fprintf(stderr, "Error %d while opening resource fork for %s\n", err, (char *)&destPath); + exit(EX_IOERR); + } + + UseResFile(rsrcRefNum); + Str255 rname; + AddResource((Handle) alias, rAliasType, 0, NULL); + + if ((err = ResError()) != noErr) + { + fprintf(stderr, "Error %d while adding alias resource for %s", err, (char *)&destPath); + exit(EX_IOERR); + } + if (!noCustomIconCopy) + { + //write the custom icon data + AddResource( (Handle)srcIconFamily, kIconFamilyType, kCustomIconResource, "\p"); + } + + CloseResFile(rsrcRefNum); + } + else + { + //create alias record from source spec + FSNewAliasMinimal (&srcRef, &alias); + if (alias == NULL) + { + fprintf(stderr, "NewAliasMinimal(): Null handle Alias returned from FSRef for file %s\n", srcPath); + exit(EX_IOERR); + } + + // Create alias resource file + // If we're dealing with a folder, we use the Finder types for folder + // Otherwise, we use the same File/Creator as source file + + if (isSrcFolder) + err = myFSCreateResFile(destPath, 'MACS', 'fdrp', &destRef); + else + err = myFSCreateResFile(destPath, ' ', ' ', &destRef); + + if (err != noErr) + { + fprintf(stderr, "Error %d while creating alias file\n", err); + exit(EX_CANTCREAT); + } + + //open resource file and write the relevant resources + rsrcRefNum = FSOpenResFile (&destRef, 3); + + //write the alias resource + AddResource ((Handle)alias, 'alis', 0, NULL); + + if (!noCustomIconCopy) + { + //write the custom icon data + AddResource( (Handle)srcIconFamily, kIconFamilyType, kCustomIconResource, "\p"); + } + + CloseResFile(rsrcRefNum); + } + + ///////////////////// Set the relevant finder flags for alias /////////////////// + + //get finder info on newly created alias + err = FSGetFInfo (&destRef, &destFinderInfo); + if (err != noErr) + { + printf("FSpGetFInfo(): Error %d getting Finder info for target alias \"%s\"\n", err, destPath); + exit(EX_IOERR); + } + + // set the flags in finder data + // we set both alias flag and custom icon flag + // + if (!noCustomIconCopy) + destFinderInfo.fdFlags = destFinderInfo.fdFlags | 0x8000 | kHasCustomIcon; + else + destFinderInfo.fdFlags = destFinderInfo.fdFlags | 0x8000; + + //if it's not a folder alias the alias gets the same creator/type as original + if (!isSrcFolder && !noCopyFileCreatorTypes) + { + destFinderInfo.fdType = srcFileType; + destFinderInfo.fdCreator = srcCreatorType; + } + + err = FSSetFInfo (&destRef, &destFinderInfo); + if (err != noErr) + { + printf("FSpSetFInfo(): Error %d setting Finder Alias flag (0x8000).\n", err); + exit(EX_IOERR); + } +} //////////////////////////////////////// // Check if file in designated path is folder /////////////////////////////////////// static short UnixIsFolder (char *path) { - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - if(S_ISREG(filestat.st_mode) != 1) - return true; - else - return false; -} - + struct stat filestat; + short err; -#pragma mark - + err = stat(path, &filestat); + if (err == -1) + return err; -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// + return S_ISREG(filestat.st_mode) != 1; +} static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-%s] [source-file] [target-alias]\n", PROGRAM_STRING, OPT_STRING); + printf("usage: %s [-%s] [source-file] [target-alias]\n", PROGRAM_STRING, OPT_STRING); } - diff --git a/trash/trash b/mvtrash/mvtrash similarity index 50% rename from trash/trash rename to mvtrash/mvtrash index 339ac08..e6f7729 100755 --- a/trash/trash +++ b/mvtrash/mvtrash @@ -13,16 +13,17 @@ use File::Copy qw(move); my $exit = 0; my $trash = catfile($ENV{HOME}, '.Trash'); foreach my $arg (@ARGV) { - my $cnt = 1; - my $base = basename($arg); - my $tname = catfile($trash, $base); - while (-e $tname) { - $tname = catfile($trash, "$base copy $cnt"); - ++$cnt; - } - unless (move($arg, $tname)) { - print STDERR "Error trashing $arg: $!\n"; - $exit = 1; - } + my $cnt = 1; + my $base = basename($arg); + my $tname = catfile($trash, $base); + while (-e $tname) { + $tname = catfile($trash, "$base copy $cnt"); + ++$cnt; + } + unless (move($arg, $tname)) { + print STDERR "Error trashing $arg: $!\n"; + $exit = 1; + } } + exit $exit; diff --git a/mvtrash/mvtrash.1 b/mvtrash/mvtrash.1 new file mode 100755 index 0000000..9ba1fb3 --- /dev/null +++ b/mvtrash/mvtrash.1 @@ -0,0 +1,23 @@ +.Dd September 20, 2017 +.Dt mvtrash 1 +.Os Darwin +.Sh NAME +.Nm mvtrash +.Nd move files to the Trash +.Sh SYNOPSIS +.Nm +.Ar +.Sh DESCRIPTION +.Nm +is akin to the 'rm' command but instead of unlinking files it moves them into the MacOS Trash +in the user's home directory. It behaves in a similar way to Finder in this respect, since +files are renamed to 'File copy 1' and so forth if they already exist in the Trash. +.Sh FILES +.Bl -tag -width "/usr/local/bin/mvtrash" -compact +.It Pa /usr/local/bin/mvtrash +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr rm 1 diff --git a/osxutils/osxutils b/osxutils/osxutils index fd4f6f9..5232854 100755 --- a/osxutils/osxutils +++ b/osxutils/osxutils @@ -1,10 +1,12 @@ #!/usr/bin/perl -print "This is an overview of the 'osxutils' suite of Mac command line utilities. The programs included in the suite are listed in alphabetical order, followed by a short description of their function. For more detail on the functionality of individual tools, see the program man pages.\n\n"; +print "'osxutils' is a collection of MacOS command line utilities. The programs are listed in alphabetical order, followed by a short description of their function. For more detail on the functionality of individual tools, refer to their individual man pages.\n\n"; print "cpath copy the current working directory to the clipboard\n"; +print "finfo print information about a file in a style similar to the Mac OS X Finder\n"; print "getfcomment print a file's Spotlight comment\n"; print "geticon extract a file's icon as an image\n"; +print "getvolume show the global system volume setting\n"; print "google search Google in default browser\n"; print "hfsdata print a file's HFS- or Mac-specific metadata\n"; print "lsmac list directory contents with OS X metadata\n"; @@ -17,7 +19,7 @@ print "seticon set a file's OS X Icon\n"; print "setlabel set a file's Finder Label\n"; print "setsuffix batch modify file suffices\n"; print "setvolume set the global system volume\n"; -print "trash move a file to the Trash\n"; -print "wiki search Wikipedia in default browser\n"; +print "mvtrash move a file to the Trash\n"; +print "wikipedia search Wikipedia in default browser\n"; print "wsupdate update the Finder filesystem display\n"; print "\n"; diff --git a/rcmac/rcmac b/rcmac/rcmac index e091d78..faa663e 100755 --- a/rcmac/rcmac +++ b/rcmac/rcmac @@ -2,6 +2,5 @@ # # Uses find command to list every file using 'lsmac' # -# find "$1" -type d -exec lsmac -o '{}' \; diff --git a/rcmac/rcmac.1 b/rcmac/rcmac.1 index e650243..f0f5b12 100644 --- a/rcmac/rcmac.1 +++ b/rcmac/rcmac.1 @@ -1,24 +1,23 @@ -.Dd 11/11/04 \" DATE -.Dt rcmac 1 \" Program name and manual section number +.Dd April 9, 2015 +.Dt rcmac 1 .Os Darwin -.Sh NAME \" Section Header - required - don't modify +.Sh NAME .Nm rcmac -.Nd recursively lists all files in a hierarchy in the style of lsmac -.Sh SYNOPSIS +.Nd recursively list all files in a hierarchy in the style of lsmac +.Sh SYNOPSIS .Nm -[directory] -.Sh DESCRIPTION \" Section Header - required - don't modify +.Ar directory +.Sh DESCRIPTION .Nm -descends into directory structures and lists every single non-directory file within the structure in the style of 'lsmac'. See the lsmac(1) man page for details. The program accepts only one argument, which must be the path of a directory to descend into. -.Pp -.Pp -.Sh FILES \" File used or created by the topic of the man page +uses +.Xr lsmac 1 +to descend down a directory tree and list every single non-directory file within the structure. The program accepts only one argument, which should be the path of a directory to descend into. +.Sh FILES .Bl -tag -width "/usr/local/bin/rcmac" -compact .It Pa /usr/local/bin/rcmac .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr lsmac 1 , -.Xr fileinfo 1 , -.Xr GetFileInfo 1 , +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr lsmac 1 diff --git a/setfcomment/setfcomment.1 b/setfcomment/setfcomment.1 index 1e0a89d..4aa57ad 100755 --- a/setfcomment/setfcomment.1 +++ b/setfcomment/setfcomment.1 @@ -1,55 +1,50 @@ -.Dd Wed Mar 31 2003 \" DATE -.Dt setfcomment 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm setfcomment -.Nd set MacOS Finder comments of files and folders. -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vhns -.Op Fl c comment -.Ar file ... -.Sh DESCRIPTION \" Section Header - required - don't modify -.Ar setfcomment -is a utility for setting MacOS Finder comments of files and folders. This is done -by sending the MacOS X Finder the appropriate type of Apple Event, or if MacOS 9 -Finder comment setting is enabled, by modifying the Desktop Database file using -File Manager APIs. Typical would usage would be: -.Bl -tag -width -indent -.It setfcomment -c 'This is my comment' myfile.txt -.El \" Ends the list -.Pp -The following options are supported: -.Pp -.Bl -tag -width indent \" Differs from above in tag removed -.It Fl c [comment] -Specifies the string you wish to set as Finder comment. This parameter is required. -.It Fl n -Omit setting MacOS 9 Finder comment. If this flag is set, the comments set with -.Nm -will not be visible in the MacOS 9 Finder. -.It Fl s -Silent mode. +.Dd September 20, 2017 +.Dt setfcomment 1 +.Os Darwin +.Sh NAME +.Nm setfcomment +.Nd set MacOS Finder comments of files and folders +.Sh SYNOPSIS +.Nm +.Op Fl hnsv +.Fl c Ar comment +.Ar +.Sh DESCRIPTION +.Ar setfcomment +is a utility for setting MacOS Finder comments of files and folders. This is done +by sending Finder the appropriate type of Apple Event, or if MacOS 9 +Finder comment setting is enabled, by modifying the Desktop Database file using +File Manager APIs. Typical usage would be: +.Pp +.Dl setfcomment -c 'This is my comment' myfile.txt +.Pp +.Pp +The following options are supported: +.Pp +.Bl -tag -width indent +.It Fl c Ar comment +Specify the string you wish to set as Finder comment. This parameter is required. +.It Fl h +Print usage and exit. +.It Fl n +Omit setting MacOS 9 Finder comment. If this flag is set, the comments set with .Nm -sends no output to STDOUT confirming that the comment for each input file has been successfully set. -.It Fl v -Prints version and author and then exits -.It Fl h -Prints help -.El -.Pp -Please direct queries to Sveinbjorn Thordarson . -.Pp -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/setfcomment" -compact -.It Pa /usr/local/bin/setfcomment -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr SetFile 1 , -.Xr GetFileInfo 1 , -.Xr setlabel 1 , -.Xr seticon 1 , -.Xr setfflags 1 , -.Xr setsuffix 1 -.Xr lsmac 1 , \ No newline at end of file +will not be visible in the MacOS 9 Finder. +.It Fl s +Silent mode. Send no output to STDOUT confirming that the comment for each input file has been successfully set. +.It Fl v +Print version and exit. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/setfcomment" -compact +.It Pa /usr/local/bin/setfcomment +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr getfcomment 1 , +.Xr SetFile 1 , +.Xr setlabel 1 , +.Xr setfctypes 1 , +.Xr setfflags 1 , +.Xr finfo 1 diff --git a/setfcomment/setfcomment.c b/setfcomment/setfcomment.c index b4fb2dc..a92ec87 100755 --- a/setfcomment/setfcomment.c +++ b/setfcomment/setfcomment.c @@ -15,32 +15,17 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - /* CHANGES - + 0.2 - New "Silent Mode" flag, exit values from sysexit.h, errors go to stderr 0.1 - First release of setfcomment - */ /* TODO - - * Recursively scan directories option - -*/ - - -/* - Command line options - v - version - h - help - usage - c [str] - comment string passed as parameter - n - don't set MacOS 9 comment - + * Recursively scan directories option */ #include @@ -51,49 +36,40 @@ #include #include -/////////////// Definitions ////////////// - #define MAX_COMMENT_LENGTH 200 #define PROGRAM_STRING "setfcomment" #define VERSION_STRING "0.2" #define AUTHOR_STRING "Sveinbjorn Thordarson" - // Some MoreAppleEvents voodoo #define MoreAssert(x) (true) #define MoreAssertQ(x) +// my stuff -/////////////// Prototypes ///////////////// +static char *GetCommentParameter (char *arg); +static void SetFileComment (char *path, char *comment); +static OSErr OSX_SetComment (FSRef *fileRef, FSSpec *fileSpec, char *comment); +static OSErr OS9_SetComment (FSSpec *fileSpec, char *comment, bool *unsupported); +static void PrintVersion (void); +static void PrintHelp (void); - // my stuff +// the stuff I ripped from MoreAppleEvents sample code - static char *GetCommentParameter (char *arg); - static void SetFileComment (char *path, char *comment); - static OSErr OSX_SetComment (FSRef *fileRef, FSSpec *fileSpec, char *comment); - static OSErr OS9_SetComment (FSSpec *fileSpec, char *comment, bool *unsupported); - static void PrintVersion (void); - static void PrintHelp (void); - - // the stuff I ripped from MoreAppleEvents sample code - - pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr, const Str255 pCommentStr, const AEIdleUPP pIdleProcUPP); - //pascal OSErr MoreFEGetComment(const FSSpecPtr pFSSpecPtr,Str255 pCommentStr,const AEIdleUPP pIdleProcUPP); - pascal OSStatus MoreAEOCreateObjSpecifierFromFSRef(const FSRefPtr pFSRefPtr,AEDesc *pObjSpecifier); - pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,AEDesc *pObjSpecifier); - pascal OSErr MoreAESendEventNoReturnValue (const AEIdleUPP pIdleProcUPP, const AppleEvent* pAppleEvent ); - pascal OSErr MoreAEGetHandlerError(const AppleEvent* pAEReply); - pascal void MoreAEDisposeDesc(AEDesc* desc); - pascal void MoreAENullDesc(AEDesc* desc); - - -/////////////// Globals ///////////////// +pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr, const Str255 pCommentStr, const AEIdleUPP pIdleProcUPP); +//pascal OSErr MoreFEGetComment(const FSSpecPtr pFSSpecPtr,Str255 pCommentStr,const AEIdleUPP pIdleProcUPP); +pascal OSStatus MoreAEOCreateObjSpecifierFromFSRef(const FSRefPtr pFSRefPtr,AEDesc *pObjSpecifier); +pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,AEDesc *pObjSpecifier); +pascal OSErr MoreAESendEventNoReturnValue (const AEIdleUPP pIdleProcUPP, const AppleEvent* pAppleEvent ); +pascal OSErr MoreAEGetHandlerError(const AppleEvent* pAEReply); +pascal void MoreAEDisposeDesc(AEDesc* desc); +pascal void MoreAENullDesc(AEDesc* desc); static const OSType gFinderSignature = 'MACS'; static short setOS9comment = 1; static short silentMode = 0; -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { int rc; int optch; @@ -130,7 +106,7 @@ int main (int argc, const char * argv[]) #if __LP64__ setOS9comment = 0; #endif - + if (comment == NULL) { fprintf(stderr, "Invalid usage: You must specify the comment to set using the -c option.\n"); @@ -144,12 +120,6 @@ int main (int argc, const char * argv[]) return EX_OK; } - - - - -#pragma mark - - /////////////////////////////////////////////////////////////////// // Check out the string passed as parameter with the -c option // Make sure it's within reasonable bounds etc. @@ -157,7 +127,7 @@ int main (int argc, const char * argv[]) static char *GetCommentParameter (char *arg) { static char comment[200]; - + if (strlen(arg) > MAX_COMMENT_LENGTH) { fprintf(stderr, "Invalid parameter: %s\n", arg); @@ -169,7 +139,7 @@ static char *GetCommentParameter (char *arg) } /////////////////////////////////////////////////////////////////// -// Make sure file exists and we have privileges. Then set the +// Make sure file exists and we have privileges. Then set the // file Finder comment. /////////////////////////////////////////////////////////////////// static void SetFileComment (char *path, char *comment) @@ -186,7 +156,7 @@ static void SetFileComment (char *path, char *comment) perror(path); return; } - + //get file reference from path err = FSPathMakeRef(path, &fileRef, NULL); if (err != noErr) @@ -194,7 +164,7 @@ static void SetFileComment (char *path, char *comment) fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, path); return; } - + //retrieve filespec from file ref err = FSGetCatalogInfo (&fileRef, NULL, NULL, NULL, &fileSpec, NULL); if (err != noErr) @@ -202,11 +172,11 @@ static void SetFileComment (char *path, char *comment) fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec for %s\n", err, path); return; } - - + + ///////////// oK, now we can go about setting the comment ///////////// - - + + //being by setting MacOS X Finder Comment err = OSX_SetComment (&fileRef, &fileSpec, comment); if (err != noErr) @@ -218,11 +188,11 @@ static void SetFileComment (char *path, char *comment) { printf("Finder Comment set for %s\n", path); } - + //check if we're setting OS9 comment. If not, we bail out here if (!setOS9comment) return; - + //set MacOS 9 Comment bool unsupported = 0; err = OS9_SetComment (&fileSpec, comment, &unsupported); @@ -239,13 +209,6 @@ static void SetFileComment (char *path, char *comment) } } - - - -#pragma mark - - - - /////////////////////////////////////////////////////////////////// // We set the MacOS X Finder comment by sending an Apple Event to // the Finder. As far as I know, there is no other way. @@ -267,84 +230,56 @@ static OSErr OSX_SetComment (FSRef *fileRef, FSSpec *fileSpec, char *comment) pCommentStr[0] = len; err = MoreFESetComment(fileRef, fileSpec, pCommentStr, NULL); - + return(err); } - /////////////////////////////////////////////////////////////////// // We set the MacOS 9 Finder comment using the File Manager API's // Desktop Database functions. /////////////////////////////////////////////////////////////////// static OSErr OS9_SetComment (FSSpec *fileSpec, char *comment, bool *unsupported) { -#if !__LP64__ +#if !__LP64__ OSErr err = noErr; DTPBRec dt; - + dt.ioVRefNum = (*fileSpec).vRefNum; - + err = PBDTGetPath(&dt); if (err != noErr) { *unsupported = true; return err; } - + //fill in the relevant fields (using parameters) dt.ioNamePtr = (*fileSpec).name; dt.ioDirID = (*fileSpec).parID; dt.ioDTBuffer = comment; dt.ioDTReqCount = strlen(comment); - + if (PBDTSetCommentSync (&dt) != noErr) return (err); - + err = PBDTSetCommentSync(&dt); if (err != noErr) - return err; - + return err; + err = PBDTFlushSync (&dt); -#endif +#endif return (noErr); } - - - - -#pragma mark - - -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// - static void PrintVersion (void) { printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vhn] [-c comment] [file ...]\n", PROGRAM_STRING); + printf("usage: %s [-hnsv] [-c comment] file ...\n", PROGRAM_STRING); } - - - - - - - - - - - - -#pragma mark - /////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// The stuff I ripped from MoreAppleEvents sample code ////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -352,15 +287,14 @@ static void PrintHelp (void) // can be got by downloading the MoreAppleEvents sample code package from developer.apple.com /////////////////////////////////////////////////////////////////////////////////////////////////// - /******************************************************************************** - Send an Apple event to the Finder to set the finder comment of the item + Send an Apple event to the Finder to set the finder comment of the item specified by the FSSpecPtr. pFSSpecPtr ==> The item to set the file kind of. pCommentStr ==> A string to which the file comment will be set pIdleProcUPP ==> A UPP for an idle function, or nil. - + See note about idle functions above. */ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr, const Str255 pCommentStr, const AEIdleUPP pIdleProcUPP) @@ -375,6 +309,7 @@ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr { char* dataPtr = NewPtr(pCommentStr[0] + 1); strncpy(dataPtr, (char*)pCommentStr + 1, pCommentStr[0]); + dataPtr[pCommentStr[0]] = 0; anErr = AEBuildAppleEvent( kAECoreSuite,kAESetData, typeApplSignature,&gFinderSignature,sizeof(OSType), @@ -386,7 +321,7 @@ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr DisposePtr(dataPtr); if (noErr == anErr) - { + { // Send the event. In this case we don't care about the reply anErr = MoreAESendEventNoReturnValue(pIdleProcUPP,&tAppleEvent); (void) MoreAEDisposeDesc(&tAppleEvent); // always dispose of AEDescs when you are finished with them @@ -395,15 +330,14 @@ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr return anErr; } // end MoreFESetComment - /******************************************************************************** - Send an Apple event to the Finder to get the finder comment of the item + Send an Apple event to the Finder to get the finder comment of the item specified by the FSSpecPtr. pFSSpecPtr ==> The item to get the file kind of. pCommentStr ==> A string into which the finder comment will be returned. pIdleProcUPP ==> A UPP for an idle function (required) - + See note about idle functions above. */ /*pascal OSErr MoreFEGetComment(const FSSpecPtr pFSSpecPtr,Str255 pCommentStr,const AEIdleUPP pIdleProcUPP) @@ -416,7 +350,7 @@ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr return paramErr; anErr = MoreAEOCreateObjSpecifierFromFSSpec(pFSSpecPtr,&tAEDesc); - + if (noErr == anErr) { AEBuildError tAEBuildError; @@ -430,7 +364,7 @@ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr (void) MoreAEDisposeDesc(&tAEDesc); // always dispose of AEDescs when you are finished with them if (noErr == anErr) - { + { //Send the event. anErr = MoreAESendEventReturnPString(pIdleProcUPP,&tAppleEvent,pCommentStr); (void) MoreAEDisposeDesc(&tAppleEvent); // always dispose of AEDescs when you are finished with them @@ -440,8 +374,6 @@ pascal OSErr MoreFESetComment(const FSRef *pFSRefPtr, const FSSpecPtr pFSSpecPtr } // end MoreFEGetComment */ - - //******************************************************************************** // A simple wrapper around CreateObjSpecifier which creates // an object specifier from a FSRef and using formName. @@ -464,8 +396,6 @@ pascal OSStatus MoreAEOCreateObjSpecifierFromFSRef(const FSRefPtr pFSRefPtr,AEDe return anErr; } - - //******************************************************************************** // A simple wrapper around CreateObjSpecifier which creates // an object specifier from a CFURLRef and using formName. @@ -491,11 +421,11 @@ pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,A if ((anErr = MemError()) == noErr) { CFStringGetCharacters(tCFStringRef, CFRangeMake(0,bufSize/2), buf); - if (isDirectory) (buf)[(bufSize-1)/2] = (UniChar) 0x003A; + if (isDirectory) (buf)[(bufSize-1)/2] = (UniChar) 0x003A; } } else anErr = coreFoundationUnknownErr; - + if (anErr == noErr) anErr = AECreateDesc(typeUnicodeText, buf, GetPtrSize((Ptr) buf), &nameDesc); if (anErr == noErr) @@ -509,11 +439,6 @@ pascal OSStatus MoreAEOCreateObjSpecifierFromCFURLRef(const CFURLRef pCFURLRef,A return anErr; }//end MoreAEOCreateObjSpecifierFromCFURLRef - - - - - pascal OSErr MoreAESendEventNoReturnValue (const AEIdleUPP pIdleProcUPP, const AppleEvent* pAppleEvent ) { OSErr anErr = noErr; @@ -530,31 +455,25 @@ pascal OSErr MoreAESendEventNoReturnValue (const AEIdleUPP pIdleProcUPP, const A anErr = MoreAEGetHandlerError(&theReply); MoreAEDisposeDesc( &theReply ); - + return anErr; } - - - - - - /******************************************************************************** Takes a reply event checks it for any errors that may have been returned by the event handler. A simple function, in that it only returns the error number. You can often also extract an error string and three other error parameters from a reply event. - + Also see: IM:IAC for details about returned error strings. AppleScript developer release notes for info on the other error parameters. - + pAEReply ==> The reply event to be checked. RESULT CODES ____________ - noErr 0 No error + noErr 0 No error ???? ?? Pretty much any error, depending on what the event handler returns for it's errors. */ @@ -562,17 +481,17 @@ pascal OSErr MoreAEGetHandlerError(const AppleEvent* pAEReply) { OSErr anErr = noErr; OSErr handlerErr; - + DescType actualType; long actualSize; - + if ( pAEReply->descriptorType != typeNull ) // there's a reply, so there may be an error { OSErr getErrErr = noErr; - + getErrErr = AEGetParamPtr( pAEReply, keyErrorNumber, typeSInt16, &actualType, &handlerErr, sizeof( OSErr ), &actualSize ); - + if ( getErrErr != errAEDescNotFound ) // found an errorNumber parameter { anErr = handlerErr; // so return it's value @@ -581,9 +500,6 @@ pascal OSErr MoreAEGetHandlerError(const AppleEvent* pAEReply) return anErr; }//end MoreAEGetHandlerError - - - //******************************************************************************* // Disposes of desc and initialises it to the null descriptor. pascal void MoreAEDisposeDesc(AEDesc* desc) @@ -591,17 +507,13 @@ pascal void MoreAEDisposeDesc(AEDesc* desc) OSStatus junk; MoreAssertQ(desc != nil); - + junk = AEDisposeDesc(desc); MoreAssertQ(junk == noErr); MoreAENullDesc(desc); }//end MoreAEDisposeDesc - - - - //******************************************************************************* // Initialises desc to the null descriptor (typeNull, nil). pascal void MoreAENullDesc(AEDesc* desc) @@ -613,8 +525,6 @@ pascal void MoreAENullDesc(AEDesc* desc) }//end MoreAENullDesc /* - - pascal OSErr MoreAESendEventReturnPString( const AEIdleUPP pIdleProcUPP, const AppleEvent* pAppleEvent, @@ -639,9 +549,6 @@ pascal OSErr MoreAESendEventReturnPString( return anErr; } // MoreAESendEventReturnPString - - - pascal OSErr MoreAESendEventReturnData( const AEIdleUPP pIdleProcUPP, const AppleEvent *pAppleEvent, @@ -677,7 +584,4 @@ pascal OSErr MoreAESendEventReturnData( } return anErr; } // MoreAESendEventReturnData - - - -*/ \ No newline at end of file +*/ diff --git a/setfctypes/setfctypes.1 b/setfctypes/setfctypes.1 index ebbab91..452d8aa 100755 --- a/setfctypes/setfctypes.1 +++ b/setfctypes/setfctypes.1 @@ -1,60 +1,50 @@ -.Dd Wed Mar 31 2003 \" DATE -.Dt setfctypes 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm setfctypes -.\" The following lines are read in generating the apropos(man -k) database. Use only key -.\" words here as the database is built based on the words here and in the .ND line. -.\" Use .Nm macro to designate other names for the documented program. -.Nd set heritage MacOS File and Creator types. -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vhs -.Op Fl f filetype -.Op Fl c creator -.Ar file ... -.Sh DESCRIPTION \" Section Header - required - don't modify -.Ar setfctypes -is a utility for setting the heritage MacOS File Type and Creator Type of files. It's very simple to use and is about -twice as fast as Apple's SetFile(1) command. An example of typical usage would be: -.Bl -tag -width -indent -.It setfctypes -f TEXT -c ttxt myfile.txt -.El \" Ends the list -.Pp -It is not neccesary to specify both the -f and -c options. -.Pp -.Ar setfctypes -accepts the following options: -.Pp -.Bl -tag -width indent \" Differs from above in tag removed -.It Fl v \"-a flag as a list item -Prints version and author and then exits -.It Fl h -Prints help -.It Fl s -Silent mode. No errors or problems are reported. -.It Fl c -Followed by a four character string specifying Creator type. -.It Fl f -Followed by a four character string specifying File type. -.El \" Ends the list -.Pp -Please direct queries to Sveinbjorn Thordarson . -.Pp -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/setfctypes" -compact -.It Pa /usr/local/bin/setfctypes -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr lsmac 1 , -.Xr SetFile 1 , -.Xr GetFileInfo 1 , +.Dd September 20, 2017 +.Dt setfctypes 1 +.Os Darwin +.Sh NAME +.Nm setfctypes +.Nd set heritage MacOS File and Creator types +.Sh SYNOPSIS +.Nm +.Op Fl hsv +.Op Fl f Ar filetype +.Op Fl c Ar creator +.Ar +.Sh DESCRIPTION +.Nm +is a utility for setting the heritage MacOS File Type and Creator Type of files. It's very simple to use and is about +twice as fast as Apple's +.Xr SetFile 1 +command. An example of typical usage would be: +.Pp +.Dl setfctypes -f TEXT -c ttxt myfile.txt +.Pp +It is not neccesary to specify both the -f and -c options. +.Pp +.Nm +accepts the following options: +.Pp +.Bl -tag -width indent +.It Fl c Ar creator +Specify four character Creator type. +.It Fl f Ar filetype +Specify four character File type. +.It Fl h +Print usage and exit. +.It Fl s +Silent mode. No errors or problems are reported. +.It Fl v +Print version and exit. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/setfctypes" -compact +.It Pa /usr/local/bin/setfctypes +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr SetFile 1 , .Xr setlabel 1 , -.Xr seticon 1 , -.Xr setfcomment 1 , -.Xr setfflags 1 , -.Xr setsuffix 1 -.\" .Sh BUGS \" Document known, unremedied bugs -.\" .Sh HISTORY \" Document history if command behaves in a unique manner - +.Xr setfcomment 1 , +.Xr setfflags 1 , +.Xr finfo 1 diff --git a/setfctypes/setfctypes.c b/setfctypes/setfctypes.c index 5f30de0..7d0d2ff 100755 --- a/setfctypes/setfctypes.c +++ b/setfctypes/setfctypes.c @@ -1,49 +1,37 @@ /* - setfctypes - program to set heritage Mac file/creator types of files - Copyright (C) 2003-2005 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + setfctypes - program to set heritage Mac file/creator types of files + Copyright (C) 2003-2005 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + CHANGES -/* CHANGES - - 0.2 - Exit codes use sysexits.h constants, errors go to stderr - 0.1 - First release of setfctypes - -*/ + 0.2 + * Exit codes use sysexits.h constants, errors go to stderr -/* TODO - - * Recursively scan through folder hierarchies option (can currently be done by combining with 'find') - * Hmmm...suggestions are welcome + 0.1 + * First release of setfctypes */ - /* - Command line options - - v - version - h - help - usage - c - set creator type - f - set file type - s - silent mode - -*/ + TODO + * Recursively scan through folder hierarchies option (can currently be done by combining with 'find') +*/ #include #include @@ -53,190 +41,170 @@ #include #include -/////////////////// Definitions ////////////////// - -#define PROGRAM_STRING "setfctypes" -#define VERSION_STRING "0.2" -#define AUTHOR_STRING "Sveinbjorn Thordarson" - -#define OPT_STRING "svhf:c:" +#define PROGRAM_STRING "setfctypes" +#define VERSION_STRING "0.2" +#define AUTHOR_STRING "Sveinbjorn Thordarson" -/////////////////// Prototypes ////////////////// +#define OPT_STRING "svhf:c:" static void SetTypes (char *fileStr, OSType fileType, OSType creatorType); static OSType GetOSTypeFromString (char *str); static OSType CStrToType(char *s); -//Boolean IsFolder (FSRef *fileRef); static short UnixIsFolder (char *path); static void PrintVersion (void); static void PrintHelp (void); -/////////////////// Globals ////////////////// +short silentMode = false; -short silentMode = false; - - -//////////////////////////////////////////// -// main program function -//////////////////////////////////////////// int main (int argc, const char * argv[]) { - int rc; - int optch; - static char optstring[] = OPT_STRING; - - OSType fileType = (OSType)NULL; - OSType creatorType = (OSType)NULL; - - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) - { - switch(optch) - { - case 's': - silentMode = true; - break; - case 'v': - PrintVersion(); - return EX_OK; - break; - case 'h': - PrintHelp(); - return EX_OK; - break; - case 'f': - fileType = GetOSTypeFromString(optarg); - break; - case 'c': - creatorType = GetOSTypeFromString(optarg); - break; - default: // '?' - rc = 1; - PrintHelp(); - return EX_USAGE; - } - } - - //if there are no types specifed, print help and exit - if (fileType == (OSType)NULL && creatorType == (OSType)NULL) + int optch; + static char optstring[] = OPT_STRING; + + OSType fileType = (OSType)NULL; + OSType creatorType = (OSType)NULL; + + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { + case 's': + silentMode = true; + break; + case 'v': + PrintVersion(); + return EX_OK; + case 'h': PrintHelp(); - return EX_USAGE; + return EX_OK; + case 'f': + fileType = GetOSTypeFromString(optarg); + break; + case 'c': + creatorType = GetOSTypeFromString(optarg); } + } - //all remaining arguments should be files - for (; optind < argc; ++optind) - SetTypes((char *)argv[optind], fileType, creatorType); - - return EX_OK; -} + //if there are no types specifed, print help and exit + if (fileType == (OSType)NULL && creatorType == (OSType)NULL) + { + PrintHelp(); + return EX_USAGE; + } + //all remaining arguments should be files + for (; optind < argc; ++optind) + SetTypes((char *)argv[optind], fileType, creatorType); -#pragma mark - + return EX_OK; +} //////////////////////////////////////////// // Use Carbon functions to actually set the // File and Creator types //////////////////////////////////////////// - static void SetTypes (char *fileStr, OSType fileType, OSType creatorType) { - OSErr err = noErr; - FSRef fileRef; - FInfo finderInfo; - short c = 0; - - //see if the file in question exists and we can write it - if (access(fileStr, R_OK|W_OK|F_OK) == -1) - { - if (!silentMode) - perror(fileStr); - return; - } - - //get file reference from path - err = FSPathMakeRef(fileStr, &fileRef, NULL); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, fileStr); - return; - } - - //check if it's a folder - c = UnixIsFolder(fileStr); - - if (c == -1)//an error occurred in stat - { - if (!silentMode) - perror(fileStr); - return; - } - else if (c == 1)//it is a folder - { - if (!silentMode) - fprintf(stderr, "%s is a folder\n", fileStr); - return; - } - - //retrieve filespec from file ref - FSCatalogInfo cinfo; - err = FSGetCatalogInfo (&fileRef, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSGetCatalogInfo(): Error %d getting Finder info for %s", err, fileStr); - return; - } - finderInfo = *(FInfo*)cinfo.finderInfo; - - c = false; - - //now, change the creator/file types in FInfo structure as appropriate - if (fileType != (OSType)NULL && finderInfo.fdType != fileType) - { - finderInfo.fdType = fileType; - c = true; - } - if (creatorType != (OSType)NULL && finderInfo.fdCreator != (OSType)creatorType) - { - finderInfo.fdCreator = creatorType; - c = true; - } - - //if the file and creator types we're setting are the same as the file's - //then there's no need to set them. A little optimization never hurt... :) - if (!c) - return; - - *(FInfo*)cinfo.finderInfo = finderInfo; - err = FSSetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &cinfo); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSSetCatalogInfo(): Error %d setting Finder info for %s", err, fileStr); - return; - } + OSErr err = noErr; + FSRef fileRef; + FInfo finderInfo; + short c = 0; + + //see if the file in question exists and we can write it + if (access(fileStr, R_OK|W_OK|F_OK) == -1) + { + if (!silentMode) + perror(fileStr); + + return; + } + + //get file reference from path + err = FSPathMakeRef(fileStr, &fileRef, NULL); + if (err != noErr) + { + if (!silentMode) + fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, fileStr); + + return; + } + + //check if it's a folder + c = UnixIsFolder(fileStr); + + if (c == -1)//an error occurred in stat + { + if (!silentMode) + perror(fileStr); + + return; + } + else if (c == 1)//it is a folder + { + if (!silentMode) + fprintf(stderr, "%s is a folder\n", fileStr); + + return; + } + + //retrieve filespec from file ref + FSCatalogInfo cinfo; + err = FSGetCatalogInfo (&fileRef, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); + if (err != noErr) + { + if (!silentMode) + fprintf(stderr, "FSGetCatalogInfo(): Error %d getting Finder info for %s", err, fileStr); + + return; + } + finderInfo = *(FInfo*)cinfo.finderInfo; + + c = false; + + //now, change the creator/file types in FInfo structure as appropriate + if (fileType != (OSType)NULL && finderInfo.fdType != fileType) + { + finderInfo.fdType = fileType; + c = true; + } + if (creatorType != (OSType)NULL && finderInfo.fdCreator != (OSType)creatorType) + { + finderInfo.fdCreator = creatorType; + c = true; + } + + //if the file and creator types we're setting are the same as the file's + //then there's no need to set them. + if (!c) + return; + + *(FInfo*)cinfo.finderInfo = finderInfo; + err = FSSetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &cinfo); + if (err != noErr) + { + if (!silentMode) + fprintf(stderr, "FSSetCatalogInfo(): Error %d setting Finder info for %s", err, fileStr); + + return; + } } -#pragma mark - - //////////////////////////////////////////// // Create an Apple OSType from a C string //////////////////////////////////////////// - static OSType GetOSTypeFromString (char *str) { - OSType type; - - if (strlen(str) != 4) - { - fprintf(stderr, "Illegal parameter: %s\nYou must specify a string of exactly 4 characters\n", str); - exit(EX_DATAERR); - } - - type = CStrToType(str); - - return(type); + OSType type; + + if (strlen(str) != 4) + { + fprintf(stderr, "Illegal parameter: %s\nYou must specify a string of exactly 4 characters\n", str); + exit(EX_DATAERR); + } + + type = CStrToType(str); + + return type; } //////////////////////////////////////// @@ -244,56 +212,42 @@ static OSType GetOSTypeFromString (char *str) // // We could also just do: typeCode = (OSType)*s; // However, that would only work on big-endian machines -// We wouldn't want that now, would we? // // Thanks go to Ed Watkeys for this one /////////////////////////////////////// - static OSType CStrToType(char *s) { - OSType typeCode = (OSType)NULL; + OSType typeCode = (OSType)NULL; - typeCode = ((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]); + typeCode = ((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]); - return typeCode; + return typeCode; } -#pragma mark - - //////////////////////////////////////// // Check if file in designated path is folder /////////////////////////////////////// static short UnixIsFolder (char *path) { - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - if(S_ISREG(filestat.st_mode) != 1) - return true; - else - return false; -} + struct stat filestat; + short err; -#pragma mark - + err = stat(path, &filestat); + if (err == -1) + return err; -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// + if(S_ISREG(filestat.st_mode) != 1) + return true; + else + return false; +} static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vhs] [-f filetype] [-c creator] [file ...]\n", PROGRAM_STRING); + printf("usage: %s [-hsv] [-f filetype] [-c creator] file ...\n", PROGRAM_STRING); } diff --git a/setfflags/setfflags.1 b/setfflags/setfflags.1 index 7c37e48..2f26fbe 100755 --- a/setfflags/setfflags.1 +++ b/setfflags/setfflags.1 @@ -1,59 +1,70 @@ -.Dd Mon Apr 21 2003 \" DATE -.Dt setfflags 1 -.Os Darwin -.Sh NAME -.Nm setfflags -.Nd Set the MacOS Finder flags of files -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vhmp -.Op Fl c Ar bool -.Op Fl s Ar bool -.Op Fl l Ar bool -.Op Fl b Ar bool -.Op Fl i Ar bool -.Op Fl a Ar bool -.Ar file -.Ar ... -.Sh DESCRIPTION \" Section Header - required - don't modify +.Dd September 20, 2017 +.Dt setfflags 1 +.Os Darwin +.Sh NAME +.Nm setfflags +.Nd set the MacOS Finder flags of files +.Sh SYNOPSIS .Nm -is a command line program for altering the MacOS Finder flags of files and/or folders. You must specify at least one flag to be set or unset using the following options: -.Pp \" Inserts a space -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl c -Has Custom Icon -.It Fl s -Is Stationery -.It Fl l -Is Name Locked -.It Fl b -Has Bundle Bit -.It Fl i -Is Invisible -.It Fl a -Is Alias -.El \" Ends the list -.Pp -The specification of each of the above must be followed by a boolean value, i.e. "true"/"false" or 1/0. -Here's an example of typical usage. Let's say we want to set a file's Invisibility flag: -.Pp -# setfflags -i true /path/to/file -.Pp -Using numbers instead of string to specify the boolean value is also permitted. Here we set the -invisibility flag and unset the custom icon flag. -.Pp -# setfflags -i 1 -c 0 /path/to/file -.Pp -If you have any questions, please direct them to Sveinbjorn Thordarson . -.Pp -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/setfflags" -compact -.It Pa /usr/local/bin/setfflags -.Sh SEE ALSO -.Xr SetFile 1 , -.Xr GetFileInfo 1 , -.Xr setfcomment 1 , -.Xr setsuffix 1 , +.Op Fl hmpv +.Op Fl a Ar bool +.Op Fl b Ar bool +.Op Fl c Ar bool +.Op Fl i Ar bool +.Op Fl l Ar bool +.Op Fl s Ar bool +.Ar +.Sh DESCRIPTION +.Nm +is a command line program for altering the MacOS Finder flags of files and/or folders. You must specify at least one Finder flag to be set or unset using the following options, or alternatively use the +.Fl p +flag to see which Finder flags are currently set on the file: +.Bl -tag -width indent +.It Fl a +Is Alias +.It Fl b +Has Bundle Bit +.It Fl c +Has Custom Icon +.It Fl i +Is Invisible +.It Fl l +Is Name Locked +.It Fl s +Is Stationery +.El +.Pp +The specification of each of the above must be followed by a boolean value, i.e. "true"/"false" or 1/0. +Here's an example of typical usage. Let's say we want to set a file's Invisibility flag: +.Pp +.Dl setfflags -i true /path/to/file +.Pp +Using numbers instead of string to specify the boolean value is also permitted. Here we set the +invisibility flag and unset the custom icon flag. +.Pp +.Dl setfflags -i 1 -c 0 /path/to/file +.Pp +.Nm +accepts the following options: +.Bl -tag -width indent +.It Fl h +Print usage and exit. +.It Fl m +Silent mode. +.It Fl p +Print the file's current Finder flags. +.It Fl v +Print version and exit. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/setfflags" -compact +.It Pa /usr/local/bin/setfflags +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr SetFile 1 , .Xr setlabel 1 , -.Xr seticon 1 , -.Xr lsmac 1 \ No newline at end of file +.Xr setfcomment 1 , +.Xr setfctypes 1 , +.Xr finfo 1 diff --git a/setfflags/setfflags.c b/setfflags/setfflags.c index b3a3232..9f56554 100644 --- a/setfflags/setfflags.c +++ b/setfflags/setfflags.c @@ -1,50 +1,35 @@ /* - setfflags - program to set Mac Finder flags of files - Copyright (C) 2003-2005 Sveinbjorn Thordarson + setfflags - program to set Mac Finder flags of files - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + Copyright (C) 2003-2005 Sveinbjorn Thordarson - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* CHANGES - - 0.1 - First release of setfflags - 0.2 - Updated to support folders - 0.3 - Code cleaned, sysexits.h constants used for exit values, errors go to stderr +/* + CHANGES -*/ + 0.3 + * Code cleaned, sysexits.h constants used for exit values, errors go to stderr -/* - Command line options - - v - version - h - help - usage - m - silent mode - p - print flags - - // flag options - - c - has custom icon - s - stationery - l - name locked - b - has bundle - i - is invisible - a - is alias - -*/ + 0.2 + * Updated to support folders + 0.1 + * First release of setfflags +*/ #include #include @@ -54,15 +39,11 @@ #include #include -/////////////////// Definitions ////////////////// +#define PROGRAM_STRING "setfflags" +#define VERSION_STRING "0.3" +#define AUTHOR_STRING "Sveinbjorn Thordarson" -#define PROGRAM_STRING "setfflags" -#define VERSION_STRING "0.3" -#define AUTHOR_STRING "Sveinbjorn Thordarson" - -#define OPT_STRING "mpvhc:s:l:b:i:a:" - -/////////////////// Prototypes ////////////////// +#define OPT_STRING "mpvhc:s:l:b:i:a:" static int SetFlags(char *fileStr); static int PrintFlags(char *fileStr); @@ -71,385 +52,359 @@ static Boolean GetBooleanParameter(char *str); static void PrintVersion(void); static void PrintHelp(void); -/////////////////// Globals ////////////////// - -enum -{ - kDoCustomIcon = 0, - kDoStationery, - kDoNameLocked, - kDoHasBundle, - kDoIsInvisible, - kDoIsAlias, - kLastFinderFlag +enum { + kDoCustomIcon = 0, + kDoStationery, + kDoNameLocked, + kDoHasBundle, + kDoIsInvisible, + kDoIsAlias, + kLastFinderFlag }; -enum -{ - kDoCustomIconBit = 1 << kDoCustomIcon, - kDoStationeryBit = 1 << kDoStationery, - kDoNameLockedBit = 1 << kDoNameLocked, - kDoHasBundleBit = 1 << kDoHasBundle, - kDoIsInvisibleBit = 1 << kDoIsInvisible, - kDoIsAliasBit = 1 << kDoIsAlias +enum { + kDoCustomIconBit = 1 << kDoCustomIcon, + kDoStationeryBit = 1 << kDoStationery, + kDoNameLockedBit = 1 << kDoNameLocked, + kDoHasBundleBit = 1 << kDoHasBundle, + kDoIsInvisibleBit = 1 << kDoIsInvisible, + kDoIsAliasBit = 1 << kDoIsAlias }; -static const UInt16 kFinderFlags[] = -{ - kHasCustomIcon, - kIsStationery, - kNameLocked, - kHasBundle, - kIsInvisible, - kIsAlias +static const UInt16 kFinderFlags[] = { + kHasCustomIcon, + kIsStationery, + kNameLocked, + kHasBundle, + kIsInvisible, + kIsAlias }; -static const UInt16 kFolderOnlyFlags[] = -{ - kHasCustomIcon, - 0, - kNameLocked, - 0, - kIsInvisible, - 0 +static const UInt16 kFolderOnlyFlags[] = { + kHasCustomIcon, + 0, + kNameLocked, + 0, + kIsInvisible, + 0 }; -static const char *kFinderStrings[] = -{ - "kHasCustomIcon", - "kIsStationery", - "kNameLocked", - "kHasBundle", - "kIsInvisible", - "kIsAlias" +static const char *kFinderStrings[] = { + "kHasCustomIcon", + "kIsStationery", + "kNameLocked", + "kHasBundle", + "kIsInvisible", + "kIsAlias" }; -static short silentMode; -static short printFlags; -static UInt16 sCustomFlags; -static UInt16 sCustomMask; +static short silentMode; +static short printFlags; +static UInt16 sCustomFlags; +static UInt16 sCustomMask; -//////////////////////////////////////////// -// main program function -//////////////////////////////////////////// int main (int argc, const char * argv[]) { - int err = EX_OK; - int optch; - static char optstring[] = OPT_STRING; - - silentMode = false; - printFlags = false; - sCustomFlags = 0; - sCustomMask = 0; - - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) - { - switch (optch) - { - case 'm': - silentMode = true; - break; - case 'v': - PrintVersion(); - return 0; - break; - case 'h': - PrintHelp(); - return 0; - break; - case 'c': - if (GetBooleanParameter(optarg)) - sCustomFlags |= kDoCustomIconBit; - sCustomMask |= kDoCustomIconBit; - break; - case 's': - if (GetBooleanParameter(optarg)) - sCustomFlags |= kDoStationeryBit; - sCustomMask |= kDoStationeryBit; - break; - case 'l': - if (GetBooleanParameter(optarg)) - sCustomFlags |= kDoNameLockedBit; - sCustomMask |= kDoNameLockedBit; - break; - case 'b': - if (GetBooleanParameter(optarg)) - sCustomFlags |= kDoHasBundleBit; - sCustomMask |= kDoHasBundleBit; - break; - case 'i': - if (GetBooleanParameter(optarg)) - sCustomFlags |= kDoIsInvisibleBit; - sCustomMask |= kDoIsInvisibleBit; - break; - case 'a': - if (GetBooleanParameter(optarg)) - sCustomFlags |= kDoIsAliasBit; - sCustomMask |= kDoIsAliasBit; - break; - case 'p': - printFlags = true; - break; - default: // '?' - PrintHelp(); - return 0; - } - } - - // if there are no types specifed and we're not printing the flags, print help and exit - if (!sCustomMask && !printFlags) - { - PrintHelp(); - return EX_USAGE; - } - - if (sCustomMask && printFlags) - { - fprintf(stderr, "Incompatible options.\n"); + int err = EX_OK; + int optch; + static char optstring[] = OPT_STRING; + + silentMode = false; + printFlags = false; + sCustomFlags = 0; + sCustomMask = 0; + + while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch (optch) + { + case 'm': + silentMode = true; + break; + case 'v': + PrintVersion(); + return 0; + case 'h': PrintHelp(); - return EX_USAGE; - } - - // all remaining arguments should be files - for (; optind < argc && !err; ++optind) - { - if (printFlags) - err = PrintFlags((char *)argv[optind]); - else - err = SetFlags((char *)argv[optind]); + return 0; + case 'c': + if (GetBooleanParameter(optarg)) + sCustomFlags |= kDoCustomIconBit; + sCustomMask |= kDoCustomIconBit; + break; + case 's': + if (GetBooleanParameter(optarg)) + sCustomFlags |= kDoStationeryBit; + sCustomMask |= kDoStationeryBit; + break; + case 'l': + if (GetBooleanParameter(optarg)) + sCustomFlags |= kDoNameLockedBit; + sCustomMask |= kDoNameLockedBit; + break; + case 'b': + if (GetBooleanParameter(optarg)) + sCustomFlags |= kDoHasBundleBit; + sCustomMask |= kDoHasBundleBit; + break; + case 'i': + if (GetBooleanParameter(optarg)) + sCustomFlags |= kDoIsInvisibleBit; + sCustomMask |= kDoIsInvisibleBit; + break; + case 'a': + if (GetBooleanParameter(optarg)) + sCustomFlags |= kDoIsAliasBit; + sCustomMask |= kDoIsAliasBit; + break; + case 'p': + printFlags = true; } - - return err; + } + + // if there are no types specifed and we're not printing the flags, print help and exit + if (!sCustomMask && !printFlags) + { + PrintHelp(); + return EX_USAGE; + } + + if (sCustomMask && printFlags) + { + fprintf(stderr, "Incompatible options.\n"); + PrintHelp(); + return EX_USAGE; + } + + // all remaining arguments should be files + for (; optind < argc && !err; ++optind) + { + if (printFlags) + err = PrintFlags((char *)argv[optind]); + else + err = SetFlags((char *)argv[optind]); + } + + return err; } - - -#pragma mark - - //////////////////////////////////////////// // Use Carbon functions to actually set the // File and Creator types //////////////////////////////////////////// - static int SetFlags (char *fileStr) { - int i; - const UInt16 *pFlags; - OSErr err; - FSRef fileRef; - FSCatalogInfo catalogInfo; - FInfo *fInfo; - UInt16 finderFlags; - - // see if the file in question exists and we can write it - if (access(fileStr, R_OK|W_OK|F_OK) == -1) - { - if (!silentMode) - perror(fileStr); - return EX_NOPERM; - } - - // check if it's a folder - i = UnixIsFolder(fileStr); - if (i == -1) - { - if (!silentMode) - fprintf(stderr, "UnixIsFolder: Error %d for file %s\n", errno, fileStr); - return EX_NOINPUT; - } - - // enable folder-only or complete flags - pFlags = (i == 1) ? kFolderOnlyFlags : kFinderFlags; - - // get file reference from path - if ((err = FSPathMakeRef(fileStr, &fileRef, NULL)) != noErr) - { + int i; + const UInt16 *pFlags; + OSErr err; + FSRef fileRef; + FSCatalogInfo catalogInfo; + FInfo *fInfo; + UInt16 finderFlags; + + // see if the file in question exists and we can write it + if (access(fileStr, R_OK|W_OK|F_OK) == -1) + { + if (!silentMode) + perror(fileStr); + + return EX_NOPERM; + } + + // check if it's a folder + i = UnixIsFolder(fileStr); + if (i == -1) + { + if (!silentMode) + fprintf(stderr, "UnixIsFolder: Error %d for file %s\n", errno, fileStr); + + return EX_NOINPUT; + } + + // enable folder-only or complete flags + pFlags = (i == 1) ? kFolderOnlyFlags : kFinderFlags; + + // get file reference from path + if ((err = FSPathMakeRef(fileStr, &fileRef, NULL)) != noErr) + { + if (!silentMode) + fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, fileStr); + + return EX_NOINPUT; + } + + // retrieve finder info from file ref + if ((err = FSGetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL)) != noErr) + { + if (!silentMode) + fprintf(stderr, "FSGetCatalogInfo(): Error %d getting Finder info for %s\n", err, fileStr); + + return EX_NOINPUT; + } + + fInfo = (FInfo *)&catalogInfo.finderInfo; + finderFlags = fInfo->fdFlags; + + // Modify the finder flags structure + for (i = 0; i < kLastFinderFlag; ++i) + { + if ((sCustomMask & (1 << i))) + { + if (pFlags[i]) + { + if ((sCustomFlags & (1 << i))) + finderFlags |= pFlags[i]; + else + finderFlags &= ~pFlags[i]; + } + else + { if (!silentMode) - fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, fileStr); - return EX_NOINPUT; - } + fprintf(stderr, "Unsupported flag %s for %s\n", kFinderStrings[i], fileStr); - // retrieve finder info from file ref - if ((err = FSGetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL)) != noErr) - { - if (!silentMode) - fprintf(stderr, "FSGetCatalogInfo(): Error %d getting Finder info for %s\n", err, fileStr); - return EX_NOINPUT; + return EX_USAGE; + } } + } + + // If the finder flags we're supposed to set + // aren't the same as the ones already in place, we set them. + if (fInfo->fdFlags != finderFlags) + { + fInfo->fdFlags = finderFlags; + if ((err = FSSetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catalogInfo)) != noErr) + { + if (!silentMode) + fprintf(stderr, "FSSetCatalogInfo(): Error %d setting Finder info for %s\n", err, fileStr); - fInfo = (FInfo *)&catalogInfo.finderInfo; - finderFlags = fInfo->fdFlags; - - // Modify the finder flags structure - for (i = 0; i < kLastFinderFlag; ++i) - { - if ((sCustomMask & (1 << i))) - { - if (pFlags[i]) - { - if ((sCustomFlags & (1 << i))) - finderFlags |= pFlags[i]; - else - finderFlags &= ~pFlags[i]; - } - else - { - if (!silentMode) - fprintf(stderr, "Unsupported flag %s for %s\n", kFinderStrings[i], fileStr); - return EX_USAGE; - } - } + return EX_IOERR; } + } - // If the finder flags we're supposed to set - // aren't the same as the ones already in place, we set them. - if (fInfo->fdFlags != finderFlags) - { - fInfo->fdFlags = finderFlags; - if ((err = FSSetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catalogInfo)) != noErr) - { - if (!silentMode) - fprintf(stderr, "FSSetCatalogInfo(): Error %d setting Finder info for %s\n", err, fileStr); - return EX_IOERR; - } - } - return EX_OK; + return EX_OK; } static int PrintFlags (char *fileStr) { - int i; - const UInt16 *pFlags; - OSErr err; - FSRef fileRef; - FSCatalogInfo catalogInfo; - FInfo *fInfo; - - //see if the file in question exists and we can read it - if (access(fileStr, R_OK|F_OK) == -1) - { - if (!silentMode) - perror(fileStr); - return EX_NOPERM; - } - - //check if it's a folder - i = UnixIsFolder(fileStr); - if (i == -1) - { - if (!silentMode) - fprintf(stderr, "UnixIsFolder: Error %d for file %s\n", errno, fileStr); - return EX_IOERR; - } - - //enable folder-only or complete flags - pFlags = (i == 1) ? kFolderOnlyFlags : kFinderFlags; - - //get file reference from path - err = FSPathMakeRef(fileStr, &fileRef, NULL); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, fileStr); - return EX_IOERR; - } - - //retrieve finder info from file ref - err = FSGetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSGetCatalogInfo(): Error %d getting Finder info for %s\n", err, fileStr); - return EX_IOERR; - } - fInfo = (FInfo *)&catalogInfo.finderInfo; - - printf("File: %s\n", fileStr); - printf("Flags:\n"); - - // Display the finder flags structure - for (i = 0; i < kLastFinderFlag; ++i) - if ( pFlags[i] ) - printf("%22s - %s", kFinderStrings[i], (fInfo->fdFlags & pFlags[i]) != 0 ? "On\n" : "Off\n"); - - printf("\n"); - return EX_OK; + int i; + const UInt16 *pFlags; + OSErr err; + FSRef fileRef; + FSCatalogInfo catalogInfo; + FInfo *fInfo; + + //see if the file in question exists and we can read it + if (access(fileStr, R_OK|F_OK) == -1) + { + if (!silentMode) + perror(fileStr); + + return EX_NOPERM; + } + + //check if it's a folder + i = UnixIsFolder(fileStr); + if (i == -1) + { + if (!silentMode) + fprintf(stderr, "UnixIsFolder: Error %d for file %s\n", errno, fileStr); + + return EX_IOERR; + } + + //enable folder-only or complete flags + pFlags = (i == 1) ? kFolderOnlyFlags : kFinderFlags; + + //get file reference from path + err = FSPathMakeRef(fileStr, &fileRef, NULL); + if (err != noErr) + { + if (!silentMode) + fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, fileStr); + + return EX_IOERR; + } + + //retrieve finder info from file ref + err = FSGetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL); + if (err != noErr) + { + if (!silentMode) + fprintf(stderr, "FSGetCatalogInfo(): Error %d getting Finder info for %s\n", err, fileStr); + + return EX_IOERR; + } + + fInfo = (FInfo *)&catalogInfo.finderInfo; + + printf("File: %s\n", fileStr); + printf("Flags:\n"); + + // Display the finder flags structure + for (i = 0; i < kLastFinderFlag; ++i) + if ( pFlags[i] ) + printf("%22s - %s", kFinderStrings[i], (fInfo->fdFlags & pFlags[i]) != 0 ? "On\n" : "Off\n"); + + printf("\n"); + + return EX_OK; } - -#pragma mark - - //////////////////////////////////////// // Check if file in designated path is folder /////////////////////////////////////// static short UnixIsFolder (char *path) { - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - if(S_ISREG(filestat.st_mode) != 1) - return true; - else - return false; -} + struct stat filestat; + short err; -#pragma mark - + err = stat(path, &filestat); + if (err == -1) + return err; + + return S_ISREG(filestat.st_mode) != 1; +} //////////////////////////////////////////// // Get boolean value from string argument // Can be specified as 0, 1, false or true //////////////////////////////////////////// - static Boolean GetBooleanParameter (char *str) { - char numStr[2]; - short num; - - if (!strcmp(str, "true")) - return true; - if (!strcmp(str, "false")) - return false; - - if (strlen(str) != 1) - { - fprintf(stderr, "%s: Invalid parameter for option.\n", str); - exit(EX_USAGE); - } + char numStr[2]; + short num; - strcpy(numStr, str); - num = atoi(numStr); - - if (num != 0 && num != 1) - { - fprintf(stderr, "%d: Invalid parameter for option.\n", num); - exit(EX_USAGE); - } - - return num; -} + if (!strcmp(str, "true")) + return true; -#pragma mark - + if (!strcmp(str, "false")) + return false; -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// + if (strlen(str) != 1) + { + fprintf(stderr, "%s: Invalid parameter for option.\n", str); + exit(EX_USAGE); + } + + strcpy(numStr, str); + num = atoi(numStr); + + if (num != 0 && num != 1) + { + fprintf(stderr, "%d: Invalid parameter for option.\n", num); + exit(EX_USAGE); + } + + return num; +} static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-mvh] [-c bool] [-s bool] [-i bool] [-l bool] [-b bool] [-a bool] [file ...]\n", PROGRAM_STRING); - printf(" or: %s [-p] [file ...]\n", PROGRAM_STRING); + printf("usage: %s [-hmv] [-a bool] [-b bool] [-c bool] [-i bool] [-l bool] [-s bool] file ...\n", PROGRAM_STRING); + printf(" or: %s [-p] file ...\n", PROGRAM_STRING); } diff --git a/seticon/main.m b/seticon/main.m index 86300b2..2b6c033 100644 --- a/seticon/main.m +++ b/seticon/main.m @@ -1,26 +1,30 @@ /* - seticon - command line program to set icon of Mac OS X files - Copyright (C) 2003-2005 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + seticon - command line program to set icon of Mac OS X files + Copyright (C) 2003-2005 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - 0.2 - * sysexits.h constants used as exit values - 0.1 - * Initial release + CHANGES + + 0.2 + * sysexits.h constants used as exit values + + 0.1 + * Initial release */ #include @@ -36,113 +40,92 @@ #include #include -#define PROGRAM_STRING "seticon" -#define VERSION_STRING "0.2" -#define AUTHOR_STRING "Sveinbjorn Thordarson" -#define OPT_STRING "vhd" +#define PROGRAM_STRING "seticon" +#define VERSION_STRING "0.2" +#define AUTHOR_STRING "Sveinbjorn Thordarson" +#define OPT_STRING "dhv" static int UnixIsFolder (char *path); static void PrintVersion (void); static void PrintHelp (void); -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - int rc, optch, sourceIsIcns = 0; - char *src; - static char optstring[] = OPT_STRING; - IconFamily *icon; - //NSImage *image; - NSString *dstPath, *srcPath; + int optch, sourceIsIcns = 0; + char *src; + static char optstring[] = OPT_STRING; + IconFamily *icon; + NSString *dstPath, *srcPath; - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) - { - switch(optch) - { - case 'v': - PrintVersion(); - exit(EX_OK); - break; - case 'h': - PrintHelp(); - exit(EX_OK); - break; - case 'd': - sourceIsIcns = 1; - break; - default: // '?' - rc = 1; - PrintHelp(); - exit(EX_USAGE); - } - } - - //check if a correct number of arguments was submitted - if (argc < 3) + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { - fprintf(stderr, "%s: Too few arguments.\n", PROGRAM_STRING); + case 'v': + PrintVersion(); + return EX_OK; + case 'h': PrintHelp(); - exit(EX_USAGE); + return EX_OK; + case 'd': + sourceIsIcns = 1; } - - src = (char *)argv[optind]; - - //get the icon - srcPath = [NSString stringWithCString: src]; - if (sourceIsIcns) - icon = [IconFamily iconFamilyWithContentsOfFile: srcPath]; - else - icon = [IconFamily iconFamilyWithIconOfFile: srcPath]; - - //all remaining arguments should be files - for (; optind < argc; ++optind) - { - dstPath = [NSString stringWithCString: (char *)argv[optind]]; - if (UnixIsFolder((char *)argv[optind])) - [icon setAsCustomIconForDirectory: dstPath]; - else - [icon setAsCustomIconForFile: dstPath]; - } - - [pool release]; - return EX_OK; + } + + //check if a correct number of arguments was submitted + if (argc < 3) + { + fprintf(stderr, "%s: Too few arguments.\n", PROGRAM_STRING); + PrintHelp(); + exit(EX_USAGE); + } + + src = (char *)argv[optind]; + + //get the icon + srcPath = [NSString stringWithCString: src]; + if (sourceIsIcns) + icon = [IconFamily iconFamilyWithContentsOfFile: srcPath]; + else + icon = [IconFamily iconFamilyWithIconOfFile: srcPath]; + + //all remaining arguments should be files + for (; optind < argc; ++optind) + { + dstPath = [NSString stringWithCString: (char *)argv[optind]]; + if (UnixIsFolder((char *)argv[optind])) + [icon setAsCustomIconForDirectory: dstPath]; + else + [icon setAsCustomIconForFile: dstPath]; + } + + [pool release]; + return EX_OK; } - /*////////////////////////////////////// // Check if file in designated path is folder /////////////////////////////////////*/ static int UnixIsFolder (char *path) { - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - return (S_ISREG(filestat.st_mode) != 1); -} - + struct stat filestat; + short err; -#pragma mark - + err = stat(path, &filestat); + if (err == -1) + return err; -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// + return S_ISREG(filestat.st_mode) != 1; +} static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vhd] [source] [file ...]\n", PROGRAM_STRING); + printf("usage: %s [-vhd] source file ...\n", PROGRAM_STRING); } - diff --git a/seticon/seticon.1 b/seticon/seticon.1 index 9621856..6b80219 100644 --- a/seticon/seticon.1 +++ b/seticon/seticon.1 @@ -1,82 +1,53 @@ -.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. -.\"See Also: -.\"man mdoc.samples for a complete listing of options -.\"man mdoc for the short list of editing options -.\"/usr/share/misc/mdoc.template -.Dd Thu May 27 2004 \" DATE -.Dt seticon 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm seticon -.\" Use .Nm macro to designate other names for the documented program. -.Nd Set icon of Mac OS X files. -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vhd \" [-abcd] -.Op Ar source \" [file] -.Op Ar \" [file ...] -.Sh DESCRIPTION \" Section Header - required - don't modify -.Nm -is a utility for setting a custom icon on Mac OS X files and folders via the command line. -The first argument to seticon is the source file, i.e. the file with the icon you wish to -apply to other file(s). Any arguments after the first should be -files which you wish to give the custom icon to. -.Pp -Please note that this need not be an .icns file -- see the -d option for using -an .icns file as a source. -.Nm -defaults to retrieving the actual icon of the file in question. -.Pp \" Inserts a space -Typical usage would look like this: -.Pp \" Inserts a space -.Nm -sourcefile file1 file2 -.Pp \" Inserts a space -The example above would result in the icon of -.Ar sourcefile -being applied to the files -.Ar file1 -and -.Ar file2 -as custom icons. -.Pp \" Inserts a space -.Nm -supports the following options: -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl d \"-a flag as a list item -Use the data of the source file as icon instead of the source file's actual icon. -.It Fl v \"-a flag as a list item -Print version and author -.It Fl h -Print a short help text on program usage -.El \" Ends the list -.Pp -.\" .Sh ENVIRONMENT \" May not be needed -.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 -.\" .It Ev ENV_VAR_1 -.\" Description of ENV_VAR_1 -.\" .It Ev ENV_VAR_2 -.\" Description of ENV_VAR_2 -.\" .El -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/seticon" -compact -.It Pa /usr/local/bin/seticon -.\" .Sh DIAGNOSTICS \" May not be needed -.\" .Bl -diag -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report -.Xr geticon 1 , -.Xr lsmac 1 , -.Xr fileinfo 1 , -.Xr setfflags 1 , -.Xr setlabel 1 , -.Xr SetFile 1 , -.\" .Sh BUGS \" Document known, unremedied bugs -.\" .Sh HISTORY \" Document history if command behaves in a unique manner - +.Dd April 9, 2015 +.Dt seticon 1 +.Os Darwin +.Sh NAME +.Nm seticon +.Nd set icon of Mac OS X files +.Sh SYNOPSIS +.Nm +.Op Fl dhv +.Ar source +.Ar +.Sh DESCRIPTION +.Nm +is a utility for setting a custom icon on Mac OS X files and folders via the command line. +The first argument to seticon is the source file, i.e. the file with the icon you wish to +apply to other file(s). Any arguments after the first should be files which you wish to +give the custom icon to. +.Pp +Please note that this need not be an .icns file -- see the -d option for using +an .icns file as a source. +.Nm +defaults to retrieving the actual icon of the file in question. +.Pp +Typical usage would look like this: +.Pp +.Dl seticon sourcefile file1 file2 +.Pp +The example above would result in the icon of +.Ar sourcefile +being applied to the files +.Ar file1 +and +.Ar file2 +as custom icons. +.Pp +.Nm +supports the following options: +.Bl -tag -width indent +.It Fl d +Use the data of the source file as icon instead of the source file's actual icon. +.It Fl h +Print usage and exit. +.It Fl v +Print version and exit. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/seticon" -compact +.It Pa /usr/local/bin/seticon +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr geticon 1 diff --git a/setlabel/main.c b/setlabel/main.c index 41c4efd..159e448 100644 --- a/setlabel/main.c +++ b/setlabel/main.c @@ -1,43 +1,30 @@ /* - setlabel - Set the Finder color label of file - Copyright (C) 2003-2005 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + setlabel - Set the Finder color label of file + Copyright (C) 2003-2005 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* CHANGES - - 0.2 - Updated to use exit code constants from sysexits.h, errors go to stderr - 0.1 - First release of setlabel - -*/ - -/* TODO - -*/ - - /* - Command line options + CHANGES - v - version - h - help - usage - s - silent mode - + 0.2 + * Updated to use exit code constants from sysexits.h, errors go to stderr + + 0.1 + * First release of setlabel */ #include @@ -49,337 +36,320 @@ #include #include -/////////////// Definitions ////////////// - -#define PROGRAM_STRING "setlabel" -#define VERSION_STRING "0.2" -#define AUTHOR_STRING "Sveinbjorn Thordarson " - +#define PROGRAM_STRING "setlabel" +#define VERSION_STRING "0.2" +#define AUTHOR_STRING "Sveinbjorn Thordarson " -/////////////// Prototypes ///////////////// +static void SetFileLabel (char *path, short labelNum); +static short ParseLabelName (char *labelName); +static short GetLabelNumber (short flags); +static void PrintVersion (void); +static void PrintHelp (void); +static int UnixIsFolder (char *path); +static void SetLabelInFlags (short *flags, short labelNum); - // my stuff +const char labelNames[8][7] = { "None", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray" }; +short silentMode = 0; - static void SetFileLabel (char *path, short labelNum); - static short ParseLabelName (char *labelName); - static short GetLabelNumber (short flags); - static void PrintVersion (void); - static void PrintHelp (void); - static int UnixIsFolder (char *path); - static void SetLabelInFlags (short *flags, short labelNum); - -/////////////// Globals ///////////////// +static OSErr FSGetDInfo(const FSRef* ref, DInfo *dInfo) +{ + FSCatalogInfo cinfo; + OSErr err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); -const char labelNames[8][7] = { "None", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray" }; -short silentMode = 0; + if (err != noErr) + return err; + *dInfo = *(DInfo*)cinfo.finderInfo; -static OSErr FSGetDInfo(const FSRef* ref, DInfo *dInfo) -{ - FSCatalogInfo cinfo; - OSErr err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); - if (err != noErr) - return err; - *dInfo = *(DInfo*)cinfo.finderInfo; - return err; + return err; } + static OSErr FSGetFInfo(const FSRef* ref, FInfo *fInfo) { - FSCatalogInfo cinfo; - OSErr err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); - if (err != noErr) - return err; - *fInfo = *(FInfo*)cinfo.finderInfo; - return err; + FSCatalogInfo cinfo; + OSErr err = FSGetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo, NULL, NULL, NULL); + + if (err != noErr) + return err; + + *fInfo = *(FInfo*)cinfo.finderInfo; + + return err; } + static OSErr FSSetFInfo(const FSRef *ref, const FInfo *finfo) { - FSCatalogInfo cinfo; - *(FInfo*)cinfo.finderInfo = *finfo; - OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo); - return err; + FSCatalogInfo cinfo; + *(FInfo*)cinfo.finderInfo = *finfo; + + OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo); + return err; } + static OSErr FSSetDInfo(const FSRef *ref, const DInfo *dinfo) { - FSCatalogInfo cinfo; - *(DInfo*)cinfo.finderInfo = *dinfo; - OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo); - return err; + FSCatalogInfo cinfo; + *(DInfo*)cinfo.finderInfo = *dinfo; + + OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo); + return err; } -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { - int rc; - int optch; - static char optstring[] = "vhs"; - char *labelName; - short labelNum; - - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) + int optch; + static char optstring[] = "vhs"; + char *labelName; + short labelNum; + + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { - switch(optch) - { - case 'v': - PrintVersion(); - return EX_OK; - break; - case 'h': - PrintHelp(); - return EX_OK; - break; - case 's': - silentMode = 1; - break; - default: // '?' - rc = 1; - return EX_OK; - } - } - - if (argc < 2) - { - fprintf(stderr, "Missing parameters.\n"); + case 'v': + PrintVersion(); + return EX_OK; + case 'h': PrintHelp(); - return EX_USAGE; + return EX_OK; + case 's': + silentMode = 1; } - - // get label identifying number from name string - labelName = malloc(sizeof((char *)argv[optind])); - strcpy((char *)labelName, (char *)argv[optind]); - labelNum = ParseLabelName((char *)labelName); - - optind++; - - //all remaining arguments should be files - for (; optind < argc; ++optind) - SetFileLabel((char *)argv[optind], labelNum); - - return EX_OK; -} + } + if (argc < 2) + { + fprintf(stderr, "Missing parameters.\n"); + PrintHelp(); + return EX_USAGE; + } + // get label identifying number from name string + labelName = malloc(sizeof((char *)argv[optind])); + strcpy((char *)labelName, (char *)argv[optind]); + labelNum = ParseLabelName((char *)labelName); + optind++; + //all remaining arguments should be files + for (; optind < argc; ++optind) + SetFileLabel((char *)argv[optind], labelNum); -#pragma mark - - + return EX_OK; +} /////////////////////////////////////////////////////////////////// -// Make sure file exists and we have privileges. Then set the +// Make sure file exists and we have privileges. Then set the // file Finder comment. /////////////////////////////////////////////////////////////////// static void SetFileLabel (char *path, short labelNum) { - OSErr err = noErr; - FSRef fileRef; - FSSpec fileSpec; - short isFldr; - short currentLabel; - FInfo finderInfo; - - //see if the file in question exists and we can write it - if (access(path, R_OK|W_OK|F_OK) == -1) - { - perror(path); - return; - } - - //get file reference from path - err = FSPathMakeRef((char *)path, &fileRef, NULL); - if (err != noErr) - { - fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, path); - return; - } - - //retrieve filespec from file ref - err = FSGetCatalogInfo (&fileRef, NULL, NULL, NULL, &fileSpec, NULL); - if (err != noErr) - { - fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec for %s\n", err, path); - return; - } - - /* Check if we're dealing with a folder */ - isFldr = UnixIsFolder(path); - if (isFldr == -1)/* an error occurred in stat */ - { - perror(path); - return; + OSErr err = noErr; + FSRef fileRef; + FSSpec fileSpec; + short isFldr; + short currentLabel; + FInfo finderInfo; + + //see if the file in question exists and we can write it + if (access(path, R_OK|W_OK|F_OK) == -1) + { + perror(path); + return; + } + + //get file reference from path + err = FSPathMakeRef((char *)path, &fileRef, NULL); + if (err != noErr) + { + fprintf(stderr, "FSPathMakeRef: Error %d for file %s\n", err, path); + return; + } + + //retrieve filespec from file ref + err = FSGetCatalogInfo (&fileRef, NULL, NULL, NULL, &fileSpec, NULL); + if (err != noErr) + { + fprintf(stderr, "FSGetCatalogInfo(): Error %d getting file spec for %s\n", err, path); + return; + } + + /* Check if we're dealing with a folder */ + isFldr = UnixIsFolder(path); + if (isFldr == -1)/* an error occurred in stat */ + { + perror(path); + return; + } + + ///////////////////////// IF SPECIFIED FILE IS A FOLDER ///////////////////////// + + if (isFldr) + { + DInfo dInfo; + err = FSGetDInfo (&fileRef, &dInfo); + + if (err != noErr) { + fprintf(stderr, "Error %d getting file Finder Directory Info\n", err); + + return; } - - ///////////////////////// IF SPECIFIED FILE IS A FOLDER ///////////////////////// - - if (isFldr) - { - DInfo dInfo; - err = FSGetDInfo (&fileRef, &dInfo); - if (err != noErr) { - fprintf(stderr, "Error %d getting file Finder Directory Info\n", err); - return; - } - - //get current label - currentLabel = GetLabelNumber(dInfo.frFlags); - - //set new label into record - SetLabelInFlags(&dInfo.frFlags, labelNum); - - err = FSSetDInfo(&fileRef, &dInfo); - if (err != noErr) { - fprintf(stderr, "Error %d setting file Finder Directory Info\n", err); - return; - } + + //get current label + currentLabel = GetLabelNumber(dInfo.frFlags); + + //set new label into record + SetLabelInFlags(&dInfo.frFlags, labelNum); + + err = FSSetDInfo(&fileRef, &dInfo); + if (err != noErr) { + fprintf(stderr, "Error %d setting file Finder Directory Info\n", err); + return; } - - ///////////////////////// IF SPECIFIED FILE IS A REGULAR FILE ///////////////////////// - - else + } + + ///////////////////////// IF SPECIFIED FILE IS A REGULAR FILE ///////////////////////// + + else + { + /* get the finder info */ + err = FSGetFInfo (&fileRef, &finderInfo); + if (err != noErr) + if (!silentMode) + fprintf(stderr, "FSpGetFInfo(): Error %d getting file Finder info from file spec for file %s", err, path); + + //retrieve the label number of the file + currentLabel = GetLabelNumber(finderInfo.fdFlags); + + //if it's already set with the desired label we return + if (currentLabel == labelNum) + return; + + //set the appropriate value in the flags field + SetLabelInFlags(&finderInfo.fdFlags, labelNum); + + //apply the settings to the file + err = FSSetFInfo (&fileRef, &finderInfo); + if (err != noErr) { - /* get the finder info */ - err = FSGetFInfo (&fileRef, &finderInfo); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSpGetFInfo(): Error %d getting file Finder info from file spec for file %s", err, path); - } - - //retrieve the label number of the file - currentLabel = GetLabelNumber(finderInfo.fdFlags); - - //if it's already set with the desired label we return - if (currentLabel == labelNum) - return; - - //set the appropriate value in the flags field - SetLabelInFlags(&finderInfo.fdFlags, labelNum); - - //apply the settings to the file - err = FSSetFInfo (&fileRef, &finderInfo); - if (err != noErr) - { - if (!silentMode) - fprintf(stderr, "FSpSetFInfo(): Error %d setting Finder info for %s", err, path); - return; - } + if (!silentMode) + fprintf(stderr, "FSpSetFInfo(): Error %d setting Finder info for %s", err, path); + + return; } - - //print output reporting the changes made - if (!silentMode) - printf("%s:\n\t%s --> %s\n", path, (char *)&labelNames[currentLabel], (char *)&labelNames[labelNum]); - - return; -} + } + + //print output reporting the changes made + if (!silentMode) + printf("%s:\n\t%s --> %s\n", path, (char *)&labelNames[currentLabel], (char *)&labelNames[labelNum]); + return; +} static void SetLabelInFlags (short *flags, short labelNum) { - short myFlags = *flags; - - //nullify former label - /* Is Orange */ - if (myFlags & 2 && myFlags & 8 && myFlags & 4) - { - myFlags -= 2; - myFlags -= 8; - myFlags -= 4; - } - /* Is Red */ - if (myFlags & 8 && myFlags & 4) - { - myFlags -= 8; - myFlags -= 4; - } - /* Is Yellow */ - if (myFlags & 8 && myFlags & 2) - { - myFlags -= 8; - myFlags -= 2; - } - - /* Is Blue */ - if (myFlags & 8) - { - myFlags -= 8; - } - - /* Is Purple */ - if (myFlags & 2 && myFlags & 4) - { - myFlags -= 2; - myFlags -= 4; - } - - /* Is Green */ - if (myFlags & 4) - { - myFlags -= 4; - } - - /* Is Gray */ - if (myFlags & 2) - { - myFlags -= 2; - } - - //OK, now all the labels should be at off - //create flags with the desired label - switch(labelNum) - { - case 0://None - break; - case 2: - myFlags += 2; - myFlags += 8; - myFlags += 4; - break; - case 1: - myFlags += 8; - myFlags += 4; - break; - case 3: - myFlags += 2; - myFlags += 8; - break; - case 5: - myFlags += 8; - break; - case 6: - myFlags += 2; - myFlags += 4; - break; - case 4: - myFlags += 4; - break; - case 7: - myFlags += 2; - break; - } - - //now, to set the desired label - *flags = myFlags; + short myFlags = *flags; + + // + // nullify former label + // + + /* Orange */ + if (myFlags & 2 && myFlags & 8 && myFlags & 4) + { + myFlags -= 2; + myFlags -= 8; + myFlags -= 4; + } + + /* Red */ + if (myFlags & 8 && myFlags & 4) + { + myFlags -= 8; + myFlags -= 4; + } + + /* Yellow */ + if (myFlags & 8 && myFlags & 2) + { + myFlags -= 8; + myFlags -= 2; + } + + /* Blue */ + if (myFlags & 8) + { + myFlags -= 8; + } + + /* Purple */ + if (myFlags & 2 && myFlags & 4) + { + myFlags -= 2; + myFlags -= 4; + } + + /* Green */ + if (myFlags & 4) + { + myFlags -= 4; + } + + /* Gray */ + if (myFlags & 2) + { + myFlags -= 2; + } + + // + // Now all the labels should be at off + // Create flags with the desired label + // + + switch(labelNum) + { + case 0: + // None + break; + case 2: + myFlags += 2; + myFlags += 8; + myFlags += 4; + break; + case 1: + myFlags += 8; + myFlags += 4; + break; + case 3: + myFlags += 2; + myFlags += 8; + break; + case 5: + myFlags += 8; + break; + case 6: + myFlags += 2; + myFlags += 4; + break; + case 4: + myFlags += 4; + break; + case 7: + myFlags += 2; + } + + // Set the desired label + *flags = myFlags; } -#pragma mark - - -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// - static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vhs] [label] [file ...]\n", PROGRAM_STRING); + printf("usage: %s [-hsv] label file ...\n", PROGRAM_STRING); } - - /*////////////////////////////////////// // Checks bits 1-3 of fdFlags and frFlags // values in FInfo and DInfo structs @@ -387,90 +357,59 @@ static void PrintHelp (void) /////////////////////////////////////*/ static short GetLabelNumber (short flags) { - /* Is Orange */ - if (flags & 2 && flags & 8 && flags & 4) - return 2; - - /* Is Red */ - if (flags & 8 && flags & 4) - return 1; - - /* Is Yellow */ - if (flags & 8 && flags & 2) - return 3; - - /* Is Blue */ - if (flags & 8) - return 5; - - /* Is Purple */ - if (flags & 2 && flags & 4) - return 6; - - /* Is Green */ - if (flags & 4) - return 4; - - /* Is Gray */ - if (flags & 2) - return 7; - - return 0; -} + /* Orange */ + if (flags & 2 && flags & 8 && flags & 4) + return 2; + /* Red */ + if (flags & 8 && flags & 4) + return 1; + /* Yellow */ + if (flags & 8 && flags & 2) + return 3; -static short ParseLabelName (char *labelName) -{ - short labelNum, i; - - for (i = 0; i < 8; i++) - { - if (!strcmp(labelName, (char *)labelNames[i])) - labelNum = i; - } + /* Blue */ + if (flags & 8) + return 5; - return labelNum; -} + /* Purple */ + if (flags & 2 && flags & 4) + return 6; + /* Green */ + if (flags & 4) + return 4; + /* Gray */ + if (flags & 2) + return 7; -/*////////////////////////////////////// -// Check if file in designated path is folder -/////////////////////////////////////*/ -static int UnixIsFolder (char *path) -{ - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; - - return (S_ISREG(filestat.st_mode) != 1); + return 0; } +static short ParseLabelName (char *labelName) +{ + short labelNum, i; + + for (i = 0; i < 8; i++) + if (!strcmp(labelName, (char *)labelNames[i])) + labelNum = i; + + return labelNum; +} /*////////////////////////////////////// -// Returns directory info structure of -// file spec +// Check if file in designated path is folder /////////////////////////////////////*/ -/*static OSErr FSpSetDInfo(const FSSpec* fileSpec, DInfo *dInfo) +static int UnixIsFolder (char *path) { - CInfoPBRec infoRec = {0}; - OSErr err = noErr; - - PBSetCatInfoSync( + struct stat filestat; + short err; - infoRec.hFileInfo.ioNamePtr = (unsigned char *)fileSpec->name; - infoRec.hFileInfo.ioVRefNum = fileSpec->vRefNum; - infoRec.hFileInfo.ioDirID = fileSpec->parID; - err = PBGetCatInfoSync(&infoRec); - if (err == noErr) - { - *dInfo = infoRec.dirInfo.ioDrUsrWds; - } + err = stat(path, &filestat); + if (err == -1) + return err; - return err; + return S_ISREG(filestat.st_mode) != 1; } -*/ \ No newline at end of file diff --git a/setlabel/setlabel.1 b/setlabel/setlabel.1 index 9195200..e1b900f 100644 --- a/setlabel/setlabel.1 +++ b/setlabel/setlabel.1 @@ -1,66 +1,46 @@ -.Dd Wed Mar 31 2003 \" DATE -.Dt setlabel 1 \" Program name and manual section number +.Dd September 20, 2017 +.Dt setlabel 1 .Os Darwin -.Sh NAME \" Section Header - required - don't modify +.Sh NAME .Nm setlabel -.Nd set MacOS Finder label of files and folders. -.Sh SYNOPSIS \" Section Header - required - don't modify +.Nd set MacOS Finder label of files and folders +.Sh SYNOPSIS +.Nm +.Op Fl hsv +.Ar label +.Ar +.Sh DESCRIPTION .Nm -.Op Fl vhs -.Ar Label file ... -.Sh DESCRIPTION \" Section Header - required - don't modify -.Ar setlabel is a utility for setting the MacOS Finder label of files and folders. This is done by modifying the meta-data flag fields in the HFS file record. The available labels (case sensitive) are: .Pp -None -Red -Orange -Yellow -Green -Blue -Purple -Gray +.Dl None, Red, Orange, Yellow, Green, Blue, Purple, Gray .Pp An example of typical usage would be: -.Bl -tag -width -indent -.It setlabel Gray myfile.txt -.El \" Ends the list +.Pp +.Dl setlabel Gray myfile.txt .Pp The following options are supported: .Pp -.Bl -tag -width indent \" Differs from above in tag removed -.It Fl v \"-a flag as a list item -Prints version and author and then exits +.Bl -tag -width indent .It Fl h -Prints help +Print usage and exit. .It Fl s -Silent mode. No output list or error reports are printed. -.El \" Ends the list -.Pp -Please direct queries to Sveinbjorn Thordarson . -.Pp -.Sh FILES \" File used or created by the topic of the man page +Silent mode. +.It Fl v +Print version and exit. +.El +.Sh FILES .Bl -tag -width "/usr/local/bin/setlabel" -compact .It Pa /usr/local/bin/setlabel -.\" .Sh DIAGNOSTICS \" May not be needed -.\" .Bl -diag -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .It Diagnostic Tag -.\" Diagnostic informtion here. -.\" .El -.Sh SEE ALSO -.\" List links in ascending order by section, alphabetically within a section. -.\" Please do not reference files that do not exist without filing a bug report +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO .Xr SetFile 1 , -.Xr GetFileInfo 1 , -.Xr setfflags 1 , -.Xr setsuffix 1 -.Xr lsmac 1 , .Xr setfcomment 1 , -.Xr setfctypes 1 , -.\" .Sh BUGS \" Document known, unremedied bugs -.\" .Sh HISTORY \" Document history if command behaves in a unique manner - +.Xr setfctypes 1 , +.Xr setfflags 1 , +.Xr finfo 1 diff --git a/setsuffix/setsuffix.1 b/setsuffix/setsuffix.1 index f6f236e..2395524 100755 --- a/setsuffix/setsuffix.1 +++ b/setsuffix/setsuffix.1 @@ -1,48 +1,50 @@ -.Dd Sun Apr 20 2003 \" DATE -.Dt setsuffix 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm setsuffix -.\" Use .Nm macro to designate other names for the documented program. -.Nd Program to set, remove and replace filename suffices. -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Op Fl vhsefar \" [-vhsefar] -.Op Fl l Ar length \" [-l length] -.Op Fl x Ar suffix \" [-x suffix] -.Op Ar \" [file ...] -.Sh DESCRIPTION \" Section Header - required - don't modify -.Nm -can be used to set, change and remove filename suffices. Suffices are used by MacOS X to identify -files and determined what application to employ when opening them. -.Pp -.Nm -accepts the following options: -.Bl -tag -width -indent \" Differs from above in tag removed -.It Fl x [suffix] \"-a flag as a list item -Use the -x option to specify the suffix you want added, without the leading dot (".") -.It Fl l [length] -Sets the max number of characters that can constitute a valid suffix. -.Nm -defaults to 4, so without this specification it will ignore all suffices longer than 4 characters. -.It Fl s -Silent mode. Only critical errors or invalid usage errors are printed to stdout. -.It Fl e -Ignore files that already have a suffix. -.It Fl f -Ignore folders. -.It Fl a -Instead of replacing previous file suffix, add it. -.It Fl r -Remove file suffix. If this option is specified, all other options apart from -l are ignored. -.El \" Ends the list -.Pp -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/setsuffix" -compact -.It Pa /usr/local/bin/setsuffix -.Sh SEE ALSO -.Xr lsmac 1 , -.Xr setfctypes 1 , -.Xr mkalias 1 , -.Xr cpath 1 - +.Dd April 9, 2015 +.Dt setsuffix 1 +.Os Darwin +.Sh NAME +.Nm setsuffix +.Nd set, remove and replace filename suffixes +.Sh SYNOPSIS +.Nm +.Op Fl aefhrsv +.Op Fl l Ar length +.Fl x Ar suffix +.Ar +.Sh DESCRIPTION +.Nm +can be used to set, change and remove filename suffixes. Suffixes are used by MacOS X to identify +files and determine what application to employ when opening them. +.Pp +.Nm +accepts the following options: +.Bl -tag -width indent +.It Fl a +Append the new suffix instead of replacing the old one. +.It Fl e +Ignore files that already have a suffix. +.It Fl f +Ignore folders. +.It Fl h +Print usage and exit. +.It Fl l Ar length +Set the max number of characters that can constitute a valid suffix. +.Nm +defaults to 4, so without this specification it will ignore all suffixes longer than 4 characters. +.It Fl r +Remove file suffix. If this option is specified, all other options apart from -l are ignored. +.It Fl s +Silent mode. Only critical errors or invalid usage errors are printed to stdout. +.It Fl v +Print version and exit. +.It Fl x Ar suffix +Specify the suffix you want added, without the leading dot ("."). Specifying an empty string is the same as using the +.Fl r +option. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/setsuffix" -compact +.It Pa /usr/local/bin/setsuffix +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . diff --git a/setsuffix/setsuffix.c b/setsuffix/setsuffix.c index a652f9b..c24dfac 100755 --- a/setsuffix/setsuffix.c +++ b/setsuffix/setsuffix.c @@ -1,56 +1,39 @@ /* - setsuffix - set file suffices in batches - Copyright (C) 2003-2005 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + setsuffix - set file suffices in batches + Copyright (C) 2003-2005 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + CHANGES -/* CHANGES - - 0.2 - Fixed all compiler warnings, removed Carbon dependency, syexits.h for program exit codes - 0.1 - First release of setsuffix + 0.2 + * Fixed all compiler warnings, removed Carbon dependency, syexits.h for program exit codes + 0.1 + * First release of setsuffix */ -/* TODO - - * Find out how Apple stores the "Hide Extension" file meta-data set in Get info and enable setsuffix to modify it - * Add suffix matching specification (something like "all files with suffix a get suffix b") - * Recursively scan through folder hierarchies option (although this can, of course, be done by combining 'setsuffix' with 'find') - * Suggestions are welcome... -*/ - - /* - Command line options - - v - version - h - help - usage - s - silent mode - e - exclude files that already have a suffix - f - ignore folders - a - add the specified suffix to file names, regardless of any previous suffices - r - remove suffices - - l [length] - length of suffix to take into account - x [suffix] - the actual suffix string - -*/ + TODO + * Find out how Apple stores the "Hide Extension" file meta-data set in Get info and enable setsuffix to modify it + * Add suffix matching specification (something like "all files with suffix a get suffix b") + * Recursively scan through folder hierarchies option (although this can, of course, be done by combining 'setsuffix' with 'find') +*/ #include #include @@ -60,20 +43,14 @@ #include #include +#define PROGRAM_STRING "setsuffix" +#define VERSION_STRING "0.2" +#define AUTHOR_STRING "Sveinbjorn Thordarson" -/////////////////// Definitions ////////////////// - -#define PROGRAM_STRING "setsuffix" -#define VERSION_STRING "0.2" -#define AUTHOR_STRING "Sveinbjorn Thordarson" +#define OPT_STRING "vhl:x:sefar" -#define OPT_STRING "vhl:x:sefar" - -#define DEFAULT_SUFFIX_LEGNTH 4 -#define MAX_SUFFIX_LENGTH 10 - - -/////////////////// Prototypes ////////////////// +#define DEFAULT_SUFFIX_LEGNTH 4 +#define MAX_SUFFIX_LENGTH 10 static void SetSuffix (char *path, char *suffix); static short GetFileSuffix (char *name); @@ -83,209 +60,188 @@ static short UnixIsFolder (char *path); static void PrintVersion (void); static void PrintHelp (void); -/////////////////// Globals ////////////////// +short silentMode = 0; +short suffixMaxLength = DEFAULT_SUFFIX_LEGNTH; +short excludeFilesWithSuffix = 0; +short ignoreFolders = 1; +short justAddTheSuffix = 0; +short removeSuffix = 0; -short silentMode = 0; -short suffixMaxLength = DEFAULT_SUFFIX_LEGNTH; -short excludeFilesWithSuffix = 0; -short ignoreFolders = 1; -short justAddTheSuffix = 0; -short removeSuffix = 0; - -//////////////////////////////////////////// -// main program function -//////////////////////////////////////////// int main (int argc, const char * argv[]) { - int rc; - int optch; - static char optstring[] = OPT_STRING; - char *suffix = NULL; + int optch; + static char optstring[] = OPT_STRING; + char *suffix = NULL; - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) - { - switch(optch) - { - case 'v': - PrintVersion(); - return EX_OK; - break; - case 'h': - PrintHelp(); - return EX_OK; - break; - case 'l': - suffixMaxLength = GetSuffixMaxLength(optarg); - break; - case 'x': - suffix = GetSuffixStringFromArgument(optarg); - break; - case 's': - silentMode = 1; - break; - case 'e': - excludeFilesWithSuffix = 1; - break; - case 'f': - ignoreFolders = 0; - break; - break; - case 'a': - justAddTheSuffix = 1; - break; - case 'r': - removeSuffix = 1; - break; - default: // '?' - rc = 1; - PrintHelp(); - return EX_OK; - } - } - - if (!removeSuffix && suffix == NULL) + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { - fprintf(stderr, "You must specify the suffix to be set using the -x option.\n"); + case 'v': + PrintVersion(); + return EX_OK; + case 'h': PrintHelp(); - return EX_USAGE; + return EX_OK; + case 'l': + suffixMaxLength = GetSuffixMaxLength(optarg); + break; + case 'x': + suffix = GetSuffixStringFromArgument(optarg); + break; + case 's': + silentMode = 1; + break; + case 'e': + excludeFilesWithSuffix = 1; + break; + case 'f': + ignoreFolders = 0; + break; + case 'a': + justAddTheSuffix = 1; + break; + case 'r': + removeSuffix = 1; } - - - //all remaining arguments should be files - for (; optind < argc; ++optind) - SetSuffix((char *)argv[optind], suffix); + } - return EX_OK; -} + if (!removeSuffix && suffix == NULL) + { + fprintf(stderr, "Please specify the suffix you'd like to set using the -x flag.\n"); + PrintHelp(); + return EX_USAGE; + } + //all remaining arguments should be files + for (; optind < argc; ++optind) + SetSuffix((char *)argv[optind], suffix); -#pragma mark - + return EX_OK; +} //////////////////////////////////////// // Set the specified file's specified suffix /////////////////////////////////////// static void SetSuffix (char *path, char *suffix) { - char newName[256]; - int err; - short isFldr; - short nameEnd; - - isFldr = UnixIsFolder(path); - - if (isFldr && ignoreFolders) - return; - - nameEnd = GetFileSuffix(path); - - //file has no suffix - if (nameEnd == 0) - { - //if we're supposed to remove suffix and it doesn't have one...well - if (removeSuffix) - { - if (!silentMode) - { - fprintf(stderr, "%s: File has no suffix.\n", path); - } - return; - } - - //if we're setting suffixes.. - //we simply add the suffix to the unsuffixed file name - sprintf((char *)&newName, "%s.%s", path, suffix); - if (!silentMode) - { - printf("%s --> %s\n", path, (char *)&newName); - } - err = rename(path, (char *)&newName); - if (err == -1) - { - perror("rename()"); - } - return; - } - - if (excludeFilesWithSuffix) - { - return; - } - - //if we're removing suffix + char newName[256]; + int err; + short isFldr; + short nameEnd; + + isFldr = UnixIsFolder(path); + + if (isFldr && ignoreFolders) + return; + + nameEnd = GetFileSuffix(path); + + //file has no suffix + if (nameEnd == 0) + { + //if we're supposed to remove suffix and it doesn't have one...well if (removeSuffix) { - strcpy((char *)newName, path); - //terminate c string at the dot - newName[nameEnd] = (char)NULL; - //rename file - err = rename(path, (char *)&newName); - if (err == -1) - { - perror("rename(): "); - return; - } - if (!silentMode) - { - printf("%s --> %s\n", (char *)path, (char *)&newName); - } - return; - } - - //if file suffix matches the one we're setting - if (!strcmp(suffix, &path[nameEnd+1]) && !justAddTheSuffix)//increment nameEnd by one to get rid of the dot - { - //we do nothing - return; - } - - //ok, at this point we have a file with a suffix that we want to replace with another suffix - strcpy((char *)&newName, path); - if (!justAddTheSuffix) - { - newName[nameEnd+1] = (char)NULL;//terminate after dot - } - else - { - strcat((char *)&newName, (char *)"."); + if (!silentMode) + fprintf(stderr, "%s: File has no suffix.\n", path); + + return; } - strcat((char *)&newName, suffix); + + //if we're setting suffixes.. + //we simply add the suffix to the unsuffixed file name + sprintf((char *)&newName, "%s.%s", path, suffix); + if (!silentMode) + printf("%s --> %s\n", path, (char *)&newName); + + err = rename(path, (char *)&newName); + if (err == -1) + perror("rename()"); + + return; + } + + if (excludeFilesWithSuffix) + return; + + //if we're removing suffix + if (removeSuffix) + { + strcpy((char *)newName, path); + + //terminate c string at the dot + newName[nameEnd] = (char)NULL; + + //rename file err = rename(path, (char *)&newName); if (err == -1) { - perror("rename()"); - return; + perror("rename(): "); + return; } if (!silentMode) { - printf("%s --> %s\n", path, (char *)&newName); + printf("%s --> %s\n", (char *)path, (char *)&newName); } -} - -#pragma mark - + return; + } + + //if file suffix matches the one we're setting + if (!strcmp(suffix, &path[nameEnd+1]) && !justAddTheSuffix)//increment nameEnd by one to get rid of the dot + { + //we do nothing + return; + } + + //ok, at this point we have a file with a suffix that we want to replace with another suffix + strcpy((char *)&newName, path); + + if (!justAddTheSuffix) + { + newName[nameEnd+1] = (char)NULL;//terminate after dot + } + else + { + strcat((char *)&newName, (char *)"."); + } + + strcat((char *)&newName, suffix); + + err = rename(path, (char *)&newName); + if (err == -1) + { + perror("rename()"); + return; + } + if (!silentMode) + { + printf("%s --> %s\n", path, (char *)&newName); + } +} //////////////////////////////////////// // Returns the suffix of a file name, -// provided it is no longer than +// provided it is no longer than // the specified maximum suffix length /////////////////////////////////////// - static short GetFileSuffix (char *name) { - short i, len, nameEnd = 0; - - len = strlen(name); - - for (i = 1; i < suffixMaxLength+2; i++) + short i, len, nameEnd = 0; + + len = strlen(name); + + for (i = 1; i < suffixMaxLength+2; i++) + { + if (name[len-i] == '.') { - if (name[len-i] == '.') - { - nameEnd = (len - i); - break; - } + nameEnd = (len - i); + break; } - - return (nameEnd); + } + + return nameEnd; } //////////////////////////////////////// @@ -293,44 +249,37 @@ static short GetFileSuffix (char *name) // in the -x option, checks if it is // valid, copies it and returns it /////////////////////////////////////// - static char* GetSuffixStringFromArgument (char *arg) { - static char suffix[MAX_SUFFIX_LENGTH]; - short len = strlen(arg); - - // Check if suffix string specified is of valid length - if (len > MAX_SUFFIX_LENGTH) - { - fprintf(stderr,"Suffix \"%s\" is too long. setsuffix handles a max suffix length of 10 characters.\n", arg); - PrintHelp(); - return((char *)EX_DATAERR); - } - else if (len > suffixMaxLength) - { - - fprintf(stderr,"Suffix \"%s\" is too long. Specify a longer max suffix length with the -l option.\n", arg); - PrintHelp(); - return((char *)EX_DATAERR); - } - if (len <= 0) - { - fprintf(stderr,"Please specify a suffix of at least 1 character.\n"); - PrintHelp(); - return((char *)EX_USAGE); - } - - //check if use made the error of including the dot '.' - if (suffix[0] == '.') - { - fprintf(stderr,"You don't need to write the preceding dot when specifying suffix.\n"); - PrintHelp(); - return((char *)EX_USAGE); - } - - strcpy((char *)&suffix, arg); - - return((char*)&suffix); + static char suffix[MAX_SUFFIX_LENGTH]; + short len = strlen(arg); + + if (len == 0) + { + removeSuffix = 1; + } + else if (suffix[0] == '.') + { + fprintf(stderr,"You don't need to write the preceding dot when specifying suffix.\n"); + PrintHelp(); + exit(EX_USAGE); + } + else if (len > MAX_SUFFIX_LENGTH) + { + fprintf(stderr,"Suffix \"%s\" is too long. setsuffix handles a max suffix length of 10 characters.\n", arg); + PrintHelp(); + exit(EX_DATAERR); + } + else if (len > suffixMaxLength) + { + fprintf(stderr,"Suffix \"%s\" is too long. Specify a longer max suffix length with the -l option.\n", arg); + PrintHelp(); + exit(EX_DATAERR); + } + + strcpy((char *)&suffix, arg); + + return (char*)&suffix; } //////////////////////////////////////// @@ -338,71 +287,53 @@ static char* GetSuffixStringFromArgument (char *arg) // option, checks if it is valid and then // converts it to an integer. /////////////////////////////////////// - static short GetSuffixMaxLength (char *strArg) { - char str[MAX_SUFFIX_LENGTH+1]; - short num; - - strcpy(str, strArg); - - num = atoi(str); - - if (num < 1) - { - printf("%s: Invalid length specified\n", strArg); - PrintHelp(); - return(EX_USAGE); - } - - if (num > MAX_SUFFIX_LENGTH) - { - printf("%s: Length cannot exceed %d\n", strArg, MAX_SUFFIX_LENGTH); - PrintHelp(); - return(EX_USAGE); - } - - return num; -} + char str[MAX_SUFFIX_LENGTH+1]; + short num; -#pragma mark - + strcpy(str, strArg); + + num = atoi(str); + + if (num < 1) + { + printf("%s: Invalid length specified\n", strArg); + PrintHelp(); + exit(EX_USAGE); + } + + if (num > MAX_SUFFIX_LENGTH) + { + printf("%s: Length cannot exceed %d\n", strArg, MAX_SUFFIX_LENGTH); + PrintHelp(); + exit(EX_USAGE); + } + + return num; +} //////////////////////////////////////// // Check if file in designated path is folder /////////////////////////////////////// static short UnixIsFolder (char *path) { - struct stat filestat; - short err; - - err = stat(path, &filestat); - if (err == -1) - return err; + struct stat filestat; + short err; - if(S_ISREG(filestat.st_mode) != 1) - return 1; + err = stat(path, &filestat); + if (err == -1) + return err; - return 0; + return (S_ISREG(filestat.st_mode) != 1) ? 1 : 0; } -#pragma mark - - - -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// - static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vhsefar] [-l length] [-x suffix] [file ...]\n", PROGRAM_STRING); + printf("usage: %s [-aefhrsv] [-l length] -x suffix file ...\n", PROGRAM_STRING); } - diff --git a/setvolume/setvolume b/setvolume/setvolume index 6d8707f..967613d 100755 --- a/setvolume/setvolume +++ b/setvolume/setvolume @@ -2,8 +2,8 @@ if ($ARGV[0] =~ m/-\w*h/ or $ARGV[0] eq "") { - printf("Usage: setvolume [1-100]\n"); - exit(64); + printf("Usage: setvolume [0-100]\n"); + exit(64); } $vol = $ARGV[0]; diff --git a/setvolume/setvolume.1 b/setvolume/setvolume.1 index 8ae8d26..926ea6e 100755 --- a/setvolume/setvolume.1 +++ b/setvolume/setvolume.1 @@ -1,10 +1,10 @@ -.Dd Tue Apr 01 2003 +.Dd April 9, 2015 .Dt setvolume 1 .Os Darwin .Sh NAME .Nm setvolume -.Nd Sets global Mac OS X sound output volume -.Sh SYNOPSIS +.Nd set global Mac OS X sound output volume +.Sh SYNOPSIS .Nm [0-100] .Sh DESCRIPTION @@ -14,15 +14,8 @@ is a command line tool for controlling the global Mac OS X sound output volume. .Bl -tag -width "/usr/local/bin/setvolume" -compact .It Pa /usr/local/bin/setvolume .El -.Sh SEE ALSO -.Xr getvolume 1 , -.Xr lsmac 1 , -.Xr setfctypes 1 , -.Xr setfflags 1 , -.Xr mkalias 1 , -.Xr setsuffix 1 , -.Xr SetFile 1 , -.Xr setfcomment 1 , -.Xr wsupdate 1, -.Xr seticon 1, -.Xr geticon 1 \ No newline at end of file +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr getvolume 1 diff --git a/trash/trash.1 b/trash/trash.1 deleted file mode 100755 index 885b4ac..0000000 --- a/trash/trash.1 +++ /dev/null @@ -1,27 +0,0 @@ -.Dd Tue Apr 01 2003 -.Dt trash 1 -.Os Darwin -.Sh NAME -.Nm trash -.Nd Moves files to the Trash -.Sh SYNOPSIS -.Nm -[file] ... -.Sh DESCRIPTION -.Nm -is akin to the 'rm' command but instead of unlinking files it moves them into the MacOS Trash -in the user's home directory. It behaves in a similar way to the Finder in this respect, since -files are renamed to 'File copy 1' and so forth if they already exist in the Trash. -.Sh FILES -.Bl -tag -width "/usr/local/bin/trash" -compact -.It Pa /usr/local/bin/trash -.El -.Sh SEE ALSO -.Xr lsmac 1 , -.Xr setfctypes 1 , -.Xr setfflags 1 , -.Xr mkalias 1 , -.Xr setsuffix 1 , -.Xr SetFile 1 , -.Xr setfcomment 1 , -.Xr wsupdate 1 diff --git a/wiki/wiki.1 b/wiki/wiki.1 deleted file mode 100755 index 15f266c..0000000 --- a/wiki/wiki.1 +++ /dev/null @@ -1,18 +0,0 @@ -.Dd Tue Apr 01 2003 -.Dt wiki 1 -.Os Darwin -.Sh NAME -.Nm wiki -.Nd search Wikipedia from the command line -.Sh SYNOPSIS -.Nm -[search words] [...] -.Sh DESCRIPTION -.Nm -is a command line program to search the Wikipedia. All arguments following the command will be counted as search terms. A browser window will open with the relevant Wikipedia results. -.Sh FILES -.Bl -tag -width "/usr/local/bin/wiki" -compact -.It Pa /usr/local/bin/wiki -.El -.Sh SEE ALSO -.Xr google 1 \ No newline at end of file diff --git a/wiki/wiki b/wikipedia/wikipedia similarity index 100% rename from wiki/wiki rename to wikipedia/wikipedia diff --git a/wikipedia/wikipedia.1 b/wikipedia/wikipedia.1 new file mode 100755 index 0000000..d417aeb --- /dev/null +++ b/wikipedia/wikipedia.1 @@ -0,0 +1,21 @@ +.Dd September 20, 2017 +.Dt wikipedia 1 +.Os Darwin +.Sh NAME +.Nm wikipedia +.Nd search Wikipedia from the command line +.Sh SYNOPSIS +.Nm +.Op Ar search-words ... +.Sh DESCRIPTION +.Nm +is a command line program to search Wikipedia. All arguments following the command will be counted as search terms. A browser window will open with the relevant Wikipedia results. +.Sh FILES +.Bl -tag -width "/usr/local/bin/wikipedia" -compact +.It Pa /usr/local/bin/wikipedia +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . +.Sh SEE ALSO +.Xr google 1 diff --git a/wsupdate/wsupdate.1 b/wsupdate/wsupdate.1 index dca00b0..b3482a3 100644 --- a/wsupdate/wsupdate.1 +++ b/wsupdate/wsupdate.1 @@ -1,21 +1,29 @@ -.Dd Wed Mar 31 2003 \" DATE -.Dt wsupdate 1 \" Program name and manual section number -.Os Darwin -.Sh NAME \" Section Header - required - don't modify -.Nm wsupdate -.Nd report file system change to Mac OS X -.Sh SYNOPSIS \" Section Header - required - don't modify -.Nm -.Ar [-vh] -.Ar file ... - -.Sh DESCRIPTION \" Section Header - required - don't modify -.Ar wsupdate -is a simple command line tool to execute the NSWorkspace method 'noteFileSystemChanged'. This will make the Finder update its open windows. If no arguments are given, the system will receive a general notification. If files are specified, these particular locations will be updated. -.Pp -.Pp -Please direct queries to Sveinbjorn Thordarson . -.Pp -.Sh FILES \" File used or created by the topic of the man page -.Bl -tag -width "/usr/local/bin/wsupdate" -compact -.It Pa /usr/local/bin/wsupdate +.Dd April 9, 2015 +.Dt wsupdate 1 +.Os Darwin +.Sh NAME +.Nm wsupdate +.Nd report file system change to Mac OS X +.Sh SYNOPSIS +.Nm +.Op Fl hv +.Op Ar +.Sh DESCRIPTION +.Nm +is a simple command line tool to execute the NSWorkspace method 'noteFileSystemChanged'. This will make the Finder update its open windows. If no arguments are given, the system will receive a general notification. If files are specified, these particular locations will be updated. +.Pp +.Nm +accepts the following options: +.Bl -tag -width indent +.It Fl h +Print usage and exit. +.It Fl v +Print version and exit. +.El +.Sh FILES +.Bl -tag -width "/usr/local/bin/wsupdate" -compact +.It Pa /usr/local/bin/wsupdate +.El +.Sh AUTHOR +Originally written by +.An Sveinbjorn Thordarson Aq sveinbjornt@gmail.com . diff --git a/wsupdate/wsupdate.m b/wsupdate/wsupdate.m index 48f7924..0bcd390 100644 --- a/wsupdate/wsupdate.m +++ b/wsupdate/wsupdate.m @@ -1,41 +1,40 @@ /* - wsupdate - command line program which notifies the Mac OS X Workspace Manager of new files - Copyright (C) 2005 Sveinbjorn Thordarson - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + wsupdate - command line program which notifies the Mac OS X Workspace Manager of new files + Copyright (C) 2005 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - In versions of Mac OS X prior to 10.4 "Tiger", the Finder file manager - updated the files in windows via polling, i.e. by checking at certain - intervals whether new files had been created. This could result in a - considerable delay between the creation of a file by a command line - program and its subsequent display in Finder windows. - - wsupdate was created to circument this problem. A command line script - can call this program and pass the paths of newly created files to send - a message to the workspace manager notifying of their existence. This - will cause the Finder to display them instantly. Example: - - wsupdate ~/Desktop/MyNewFile.txt - - wsupdate uses the same API call to notify the workspace manager as regular - Mac OS X applications. If no files are passed as arguments, wsupdate - just sends a general "file system changed" notification, which should update - all Finder windows, regardless of contents. + In versions of Mac OS X prior to 10.4 "Tiger", the Finder file manager + updated the files in windows via polling, i.e. by checking at certain + intervals whether new files had been created. This could result in a + considerable delay between the creation of a file by a command line + program and its subsequent display in Finder windows. + + wsupdate was created to circument this problem. A command line script + can call this program and pass the paths of newly created files to send + a message to the workspace manager notifying of their existence. This + will cause the Finder to display them instantly. Example: + + wsupdate ~/Desktop/MyNewFile.txt + + wsupdate uses the same API call to notify the workspace manager as regular + Mac OS X applications. If no files are passed as arguments, wsupdate + just sends a general "file system changed" notification, which should update + all Finder windows, regardless of contents. */ #import @@ -49,103 +48,83 @@ #include #include -#define PROGRAM_STRING "wsupdate" -#define VERSION_STRING "0.2" -#define AUTHOR_STRING "Sveinbjorn Thordarson" -#define OPT_STRING "vh" +#define PROGRAM_STRING "wsupdate" +#define VERSION_STRING "0.2" +#define AUTHOR_STRING "Sveinbjorn Thordarson" +#define OPT_STRING "hv" /* - Version History - - 0.2 - * Updated to use BSD sysexits - * Now complains if a path does not exist - * Functionality moved to UpdateWorkspaceForFile function - - 0.1 - * Initial Release + Version History + + 0.2 + * Updated to use BSD sysexits + * Now complains if a path does not exist + * Functionality moved to UpdateWorkspaceForFile function + + 0.1 + * Initial Release */ static void UpdateWorkspaceForFile (char *path); static void PrintVersion (void); static void PrintHelp (void); -int main (int argc, const char * argv[]) +int main (int argc, const char * argv[]) { - int rc, optch; - static char optstring[] = OPT_STRING; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - + int optch; + static char optstring[] = OPT_STRING; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - while ( (optch = getopt(argc, (char * const *)argv, optstring)) != -1) + while ((optch = getopt(argc, (char * const *)argv, optstring)) != -1) + { + switch(optch) { - switch(optch) - { - case 'v': - PrintVersion(); - return(EX_OK); - break; - case 'h': - PrintHelp(); - return(EX_OK); - break; - default: // '?' - rc = 1; - PrintHelp(); - return(EX_OK); - } + case 'v': + PrintVersion(); + return EX_OK; + case 'h': + PrintHelp(); + return EX_OK; } - - // if no file or folder is submitted as argument, - // we just send a general file system changed notification - if (argc == 0) - { - [[NSWorkspace sharedWorkspace] noteFileSystemChanged]; - } - else - { - // otherwise, we send change notification for all the specified files/folders - for (; optind < argc; ++optind) - { - UpdateWorkspaceForFile((char *)argv[optind]); - } - } - - [pool release]; - return(EX_OK); + } + + // if no file or folder is submitted as argument, + // we just send a general file system changed notification + if (argc == 0) + { + [[NSWorkspace sharedWorkspace] noteFileSystemChanged]; + } + else + { + // otherwise, we send change notification for all the specified files/folders + for (; optind < argc; ++optind) + UpdateWorkspaceForFile((char *)argv[optind]); + } + + [pool release]; + return(EX_OK); } -#pragma mark - - ////////////////////////////////////////////// // Update workspace for a given c string path // and give error if no file exists at path ////////////////////////////////////////////// - static void UpdateWorkspaceForFile (char *path) { - NSString *pathStr = [NSString stringWithCString: path]; - - if ([[NSFileManager defaultManager] fileExistsAtPath: pathStr]) - [[NSWorkspace sharedWorkspace] noteFileSystemChanged: pathStr]; - else - fprintf(stderr, "No such file or directory: %s\n", path); -} + NSString *pathStr = [NSString stringWithCString: path]; -//////////////////////////////////////// -// Print version and author to stdout -/////////////////////////////////////// + if ([[NSFileManager defaultManager] fileExistsAtPath: pathStr]) + [[NSWorkspace sharedWorkspace] noteFileSystemChanged: pathStr]; + else + fprintf(stderr, "No such file or directory: %s\n", path); +} static void PrintVersion (void) { - printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); + printf("%s version %s by %s\n", PROGRAM_STRING, VERSION_STRING, AUTHOR_STRING); } -//////////////////////////////////////// -// Print help string to stdout -/////////////////////////////////////// - static void PrintHelp (void) { - printf("usage: %s [-vh] [directory ...]\n", PROGRAM_STRING); + printf("usage: %s [-%s] [file ...]\n", PROGRAM_STRING, OPT_STRING); } - -