Changeset 308
- Timestamp:
- 10/30/06 10:36:56 (18 years ago)
- Location:
- trunk/launch/launch
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/launch/launch/README
r304 r308 61 61 ----------- 62 62 63 An Xcode project, 'launch.xcodeproj', is included. A precompiled Universal64 binary is also provided. 'launch' was developed and tested under Mac OS X 65 10.4.7 with Xcode 2.3, and does not require any additional software to 66 build.63 An Xcode project, 'launch.xcodeproj', is included. A precompiled 64 Universal binary is also provided. 'launch' was developed and tested 65 under Mac OS X 10.4.8 with Xcode 2.4, and does not require any 66 additional software to build. 67 67 68 68 USAGE … … 89 89 90 90 % launch -f /Applications/Preview.app 91 /Applications/Preview.app: Mac OS X application package 91 /Applications/Preview.app: Mac OS X application package 92 92 type: 'APPL' creator: 'prvw' 93 architecture: Intel 80x86, PowerPC 93 94 bundle ID: com.apple.Preview 94 version: 2.1.095 version: 3.0.8 95 96 kind: Application 97 content type ID: com.apple.application-bundle 96 98 contents: 1 item 97 99 [...] … … 120 122 121 123 % launch -f /Applications/Internet/OmniWeb.app 122 /Applications/Internet/OmniWeb.app: Mac OS X application package124 /Applications/Internet/OmniWeb.app: scriptable Mac OS X application package 123 125 type: 'APPL' creator: 'OWEB' 124 bundle ID: com.omnigroup.OmniWeb 125 version: 4.5 126 kind: Application 126 architecture: PowerPC, Intel 80x86 127 bundle ID: com.omnigroup.OmniWeb5 127 128 128 129 Note that bundle IDs are not case-sensitive: com.barebones.BBEdit is … … 227 228 - -o: pass command-line arguments (broken, r. 4474993) 228 229 - display content type ID (UTI) 230 - display architecture of Mach-O files 229 231 - switched to new LSOpen APIs (now requires Mac OS X 10.4 or later) 230 232 - switched to new date formatting APIs (the old ones are deprecated) -
trunk/launch/launch/launch.xcodeproj/project.pbxproj
r305 r308 134 134 i386, 135 135 ); 136 GCC_C_LANGUAGE_STANDARD = c99; 136 137 MACOSX_DEPLOYMENT_TARGET = 10.4; 137 138 PREBINDING = NO; … … 147 148 i386, 148 149 ); 150 GCC_C_LANGUAGE_STANDARD = c99; 149 151 MACOSX_DEPLOYMENT_TARGET = 10.4; 150 152 PREBINDING = NO; -
trunk/launch/launch/main.c
r305 r308 21 21 #include <unistd.h> 22 22 #include <sys/stat.h> 23 #include <mach-o/fat.h> 24 #include <mach-o/arch.h> 25 #include <mach-o/loader.h> 23 26 #include <Carbon/Carbon.h> 24 27 #include <CoreServices/CoreServices.h> … … 648 651 CFRelease(typeStr); 649 652 return buffer; 653 } 654 655 // based on Apple's "CheckExecutableArchitecture" sample code 656 657 #define MAX_HEADER_BYTES 512 658 659 void swapHeader(uint8_t *bytes, ssize_t length) { 660 for (ssize_t i = 0 ; i < length ; i += 4) 661 *(uint32_t *)(bytes + i) = OSSwapInt32(*(uint32_t *)(bytes + i)); 662 } 663 664 void printExecutableArchitectures(CFURLRef url, bool printOnFailure) { 665 uint8_t path[PATH_MAX]; 666 if (printOnFailure) 667 printf("\tarchitecture: "); 668 669 if (!CFURLGetFileSystemRepresentation(url, true, path, PATH_MAX)) { 670 if (printOnFailure) printf("(can't get executable)\n"); 671 return; 672 } 673 674 int fd = open((const char *)path, O_RDONLY, 0777); 675 if (fd <= 0) { 676 if (printOnFailure) printf("(can't read)\n"); 677 return; 678 } 679 680 uint8_t bytes[MAX_HEADER_BYTES]; 681 ssize_t length = read(fd, bytes, MAX_HEADER_BYTES); 682 close(fd); 683 684 if (length < sizeof(struct mach_header_64)) { 685 if (printOnFailure) printf("(can't read Mach-O header)\n"); 686 return; 687 } 688 689 // Look for any of the six magic numbers relevant to Mach-O executables, and swap the header if necessary. 690 uint32_t num_fat = 0, magic = *((uint32_t *)bytes); 691 uint32_t max_fat = (length - sizeof(struct fat_header)) / sizeof(struct fat_arch); 692 struct fat_arch one_fat = {0}, *fat; 693 if (MH_MAGIC == magic || MH_CIGAM == magic) { 694 struct mach_header *mh = (struct mach_header *)bytes; 695 if (MH_CIGAM == magic) swapHeader(bytes, length); 696 one_fat.cputype = mh->cputype; 697 one_fat.cpusubtype = mh->cpusubtype; 698 fat = &one_fat; 699 num_fat = 1; 700 } else if (MH_MAGIC_64 == magic || MH_CIGAM_64 == magic) { 701 struct mach_header_64 *mh = (struct mach_header_64 *)bytes; 702 if (MH_CIGAM_64 == magic) swapHeader(bytes, length); 703 one_fat.cputype = mh->cputype; 704 one_fat.cpusubtype = mh->cpusubtype; 705 fat = &one_fat; 706 num_fat = 1; 707 } else if (FAT_MAGIC == magic || FAT_CIGAM == magic) { 708 fat = (struct fat_arch *)(bytes + sizeof(struct fat_header)); 709 if (FAT_CIGAM == magic) swapHeader(bytes, length); 710 num_fat = ((struct fat_header *)bytes)->nfat_arch; 711 if (num_fat > max_fat) num_fat = max_fat; 712 } 713 714 if (num_fat == 0) { 715 if (printOnFailure) printf("(none found)\n"); 716 return; 717 } 718 719 if (!printOnFailure) 720 printf("\tarchitecture: "); 721 722 for (int i = 0 ; i < num_fat ; i++) { 723 if (i != 0) printf(", "); 724 const NXArchInfo *arch = NXGetArchInfoFromCpuType(fat[i].cputype, fat[i].cpusubtype); 725 if (arch == NULL) { 726 printf("unknown (cputype %d, subtype %d)", fat[i].cputype, fat[i].cpusubtype); 727 continue; 728 } 729 printf(arch->description); 730 } 731 printf("\n"); 650 732 } 651 733 … … 761 843 intVersion = CFBundleGetVersionNumber(bundle); 762 844 } 845 CFURLRef executable = CFBundleCopyExecutableURL(bundle); 846 if (executable != NULL) { 847 printExecutableArchitectures(executable, true); 848 CFRelease(executable); 849 } 763 850 CFRelease(bundle); 764 851 } … … 767 854 CFRelease(bundleID); 768 855 } 769 } else if (haveFSRef) { 770 // try to get a version if we can, but don't complain if we can't 771 SInt16 resFork = FSOpenResFile(&fsr, fsRdPerm); 772 if (ResError() == noErr) { 773 VersRecHndl vers = (VersRecHndl)Get1Resource('vers', 1); 774 if (ResError() == noErr && vers != NULL) { 775 version = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead? 776 intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole; 856 } else { 857 printExecutableArchitectures(url, false); 858 if (haveFSRef) { 859 // try to get a version if we can, but don't complain if we can't 860 SInt16 resFork = FSOpenResFile(&fsr, fsRdPerm); 861 if (ResError() == noErr) { 862 VersRecHndl vers = (VersRecHndl)Get1Resource('vers', 1); 863 if (ResError() == noErr && vers != NULL) { 864 version = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead? 865 intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole; 866 } 777 867 } 868 CloseResFile(resFork); 778 869 } 779 CloseResFile(resFork);780 870 } 781 871 782 872 if (version != NULL) { 783 873 printf("\tversion: %s", utf8StringFromCFStringRef(version));
Note:
See TracChangeset
for help on using the changeset viewer.