Changeset 166
- Timestamp:
- 04/04/05 00:22:09 (20 years ago)
- Location:
- trunk/launch
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/launch/launch/README
r146 r166 1 launch 1.0 [23 October 2003]2 ========== 1 launch 1.0.1 [3 April 2005] 2 ============ 3 3 4 4 A command-line launcher for Mac OS X in the spirit of open(1). … … 56 56 Uninstallation: 57 57 58 % sudo rm -f /usr/local/bin/launch /usr/local/man/man1/ appswitch.158 % sudo rm -f /usr/local/bin/launch /usr/local/man/man1/launch.1 59 59 60 60 COMPILATION … … 63 63 An Xcode/Project Builder project, 'launch.pbproj', is included. A 64 64 precompiled binary is also provided. 'launch' was developed and 65 tested under Mac OS 10.3 with the October 2003 Developer Tools, and66 does not require anyadditional software to build.65 tested under Mac OS 10.3.8 with Xcode 1.5, and does not require any 66 additional software to build. 67 67 68 68 USAGE … … 202 202 various system services owned by the currently logged-on user. If you 203 203 aren't using 'launch' from a terminal currently logged into the Mac OS 204 X GUI, certain operations may not work. Try opening Terminal .app,205 creating a new terminal, and trying again.204 X GUI, certain operations may not work. Try opening Terminal, creating 205 a new terminal window, and trying again. 206 206 207 207 Another possibility is to create your own interprocess messaging. … … 237 237 --------------- 238 238 239 1.0.1 - 3 April 2005 240 - prefer files to URLs; added -U for old behavior 241 - don't display extraneous leading './' on file paths 242 - display 'zero items', not '0 items', for consistency 243 - display versions of non-applications 244 - read Info.plists embedded in unbundled Mach-O applications 245 - non-ASCII arguments are now handled with the filesystem, rather 246 than the system encoding [Derrick Bass] 247 - explicitly use UTF-8 everywhere else to properly interpret and 248 display non-ASCII filenames and URLs 249 - reading OSTypes and 'vers' resources, and opening URLs with 250 Internet Config still uses the system encoding, converting as 251 necessary for display 252 - should be buildable on 10.2 again 239 253 1.0 - 23 October 2003 240 254 - work around CFBundle bug to report bundle identifiers and versions -
trunk/launch/launch/VERSION
r146 r166 1 1.0 1 1.0.1 -
trunk/launch/launch/launch.1
r146 r166 1 .Dd Wed Oct 22 2003\" DATE1 .Dd Sun Apr 3 2005 \" DATE 2 2 .Dt LAUNCH 1 LOCAL \" Program name and manual section number 3 .Os launch 1.0 3 .Os launch 1.0.1 4 4 .Sh NAME 5 5 .Nm launch … … 7 7 .Sh SYNOPSIS 8 8 .Nm launch 9 .Op Fl npswbmhCX \" [-npswbmhCX]9 .Op Fl npswbmhCXU \" [-npswbmhCXU] 10 10 .Op Fl c Ar creator \" [-c creator] 11 11 .Op Fl i Ar bundleID \" [-i bundleID] … … 15 15 .Op Ar - \" [-] 16 16 .Nm 17 .Op Fl npflswbmhCX 17 .Op Fl npflswbmhCXU 18 18 .Ar item ... 19 19 .Sh DESCRIPTION … … 99 99 Don't start the Classic environment for this Classic application if 100 100 Classic isn't running. 101 .It Fl U 102 Interpret items as URLs, even if files with the same names as the URLs 103 exist. (This was the default behavior in 104 .Nm 105 1.0.) 101 106 .El 102 107 .Sh SEE ALSO -
trunk/launch/launch/launch.pbproj/nicholas.pbxuser
r148 r166 47 47 PBXFileTableDataSourceColumnWidthsKey = ( 48 48 20, 49 341,49 236, 50 50 20, 51 65,51 47, 52 52 43, 53 53 43, … … 76 76 ); 77 77 }; 78 PBXPerProjectTemplateStateSaveDate = 88649579; 78 PBXPerProjectTemplateStateSaveDate = 134264568; 79 PBXPrepackagedSmartGroups_v2 = ( 80 { 81 PBXTransientLocationAtTop = bottom; 82 absolutePathToBundle = ""; 83 activationKey = OldTargetSmartGroup; 84 clz = PBXTargetSmartGroup; 85 description = "Displays all targets of the project."; 86 globalID = 1C37FABC04509CD000000102; 87 name = Targets; 88 preferences = { 89 image = Targets; 90 }; 91 }, 92 { 93 PBXTransientLocationAtTop = bottom; 94 absolutePathToBundle = ""; 95 clz = PBXTargetSmartGroup2; 96 description = "Displays all targets of the project as well as nested build phases."; 97 globalID = 1C37FBAC04509CD000000102; 98 name = Targets; 99 preferences = { 100 image = Targets; 101 }; 102 }, 103 { 104 PBXTransientLocationAtTop = bottom; 105 absolutePathToBundle = ""; 106 clz = PBXExecutablesSmartGroup; 107 description = "Displays all executables of the project."; 108 globalID = 1C37FAAC04509CD000000102; 109 name = Executables; 110 preferences = { 111 image = Executable; 112 }; 113 }, 114 { 115 " PBXTransientLocationAtTop " = bottom; 116 absolutePathToBundle = ""; 117 clz = PBXErrorsWarningsSmartGroup; 118 description = "Displays files with errors or warnings."; 119 globalID = 1C08E77C0454961000C914BD; 120 name = "Errors and Warnings"; 121 preferences = { 122 fnmatch = ""; 123 image = WarningsErrors; 124 recursive = 1; 125 regex = ""; 126 root = "<PROJECT>"; 127 }; 128 }, 129 { 130 PBXTransientLocationAtTop = bottom; 131 absolutePathToBundle = ""; 132 clz = PBXFilenameSmartGroup; 133 description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; 134 globalID = 1CC0EA4004350EF90044410B; 135 name = "Implementation Files"; 136 preferences = { 137 canSave = 1; 138 fnmatch = ""; 139 image = SmartFolder; 140 isLeaf = 0; 141 recursive = 1; 142 regex = "?*\\.[mcMC]"; 143 root = "<PROJECT>"; 144 }; 145 }, 146 { 147 PBXTransientLocationAtTop = bottom; 148 absolutePathToBundle = ""; 149 clz = PBXFilenameSmartGroup; 150 description = "This group displays Interface Builder NIB Files."; 151 globalID = 1CC0EA4004350EF90041110B; 152 name = "NIB Files"; 153 preferences = { 154 canSave = 1; 155 fnmatch = "*.nib"; 156 image = SmartFolder; 157 isLeaf = 0; 158 recursive = 1; 159 regex = ""; 160 root = "<PROJECT>"; 161 }; 162 }, 163 { 164 PBXTransientLocationAtTop = no; 165 absolutePathToBundle = ""; 166 clz = PBXFindSmartGroup; 167 description = "Displays Find Results."; 168 globalID = 1C37FABC05509CD000000102; 169 name = "Find Results"; 170 preferences = { 171 image = spyglass; 172 }; 173 }, 174 { 175 PBXTransientLocationAtTop = no; 176 absolutePathToBundle = ""; 177 clz = PBXBookmarksSmartGroup; 178 description = "Displays Project Bookmarks."; 179 globalID = 1C37FABC05539CD112110102; 180 name = Bookmarks; 181 preferences = { 182 image = Bookmarks; 183 }; 184 }, 185 { 186 PBXTransientLocationAtTop = bottom; 187 absolutePathToBundle = ""; 188 clz = XCSCMSmartGroup; 189 description = "Displays files with interesting SCM status."; 190 globalID = E2644B35053B69B200211256; 191 name = SCM; 192 preferences = { 193 image = PBXRepository; 194 isLeaf = 0; 195 }; 196 }, 197 { 198 PBXTransientLocationAtTop = bottom; 199 absolutePathToBundle = ""; 200 clz = PBXSymbolsSmartGroup; 201 description = "Displays all symbols for the project."; 202 globalID = 1C37FABC04509CD000100104; 203 name = "Project Symbols"; 204 preferences = { 205 image = ProjectSymbols; 206 isLeaf = 1; 207 }; 208 }, 209 { 210 PBXTransientLocationAtTop = bottom; 211 absolutePathToBundle = ""; 212 clz = PBXFilenameSmartGroup; 213 description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; 214 globalID = PBXTemplateMarker; 215 name = "Simple Filter SmartGroup"; 216 preferences = { 217 canSave = 1; 218 fnmatch = "*.nib"; 219 image = SmartFolder; 220 isLeaf = 0; 221 recursive = 1; 222 regex = ""; 223 root = "<PROJECT>"; 224 }; 225 }, 226 { 227 PBXTransientLocationAtTop = bottom; 228 absolutePathToBundle = ""; 229 clz = PBXFilenameSmartGroup; 230 description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; 231 globalID = PBXTemplateMarker; 232 name = "Simple Regular Expression SmartGroup"; 233 preferences = { 234 canSave = 1; 235 fnmatch = ""; 236 image = SmartFolder; 237 isLeaf = 0; 238 recursive = 1; 239 regex = "?*\\.[mcMC]"; 240 root = "<PROJECT>"; 241 }; 242 }, 243 { 244 PBXTransientLocationAtTop = bottom; 245 clz = XDDesignSmartGroup; 246 description = "Displays Xdesign models"; 247 globalID = 2E4A936305E6979E00701470; 248 name = Design; 249 preferences = { 250 image = Design; 251 isLeaf = 0; 252 }; 253 }, 254 ); 79 255 PBXWorkspaceContents = ( 80 256 { … … 83 259 PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { 84 260 Split0 = { 85 bookmark = E1 A087D20548746200594651;261 bookmark = E12B212E0548BF6E00CFF4E9; 86 262 history = ( 87 263 E1375C530530898300FE8BF8, 88 E103506B05355596002A18D1,89 264 E11E9B8E0544EE7900045D4F, 90 265 E11E9B8F0544EE7900045D4F, … … 92 267 E1A087CE0548746200594651, 93 268 E1A087CF0548746200594651, 94 E1A087D00548746200594651, 95 ); 96 nextStack = ( 97 E1A087D10548746200594651, 269 E103506C05355596002A18D1, 98 270 ); 99 271 prevStack = ( 100 272 E1375C560530898300FE8BF8, 101 E103506C05355596002A18D1,102 273 ); 103 274 }; … … 124 295 }; 125 296 }, 126 {127 PBXProjectWorkspaceModule_StateKey_Rev36 = {128 PBXProjectWorkspaceModule_EditorOpen = true;129 PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {130 Split0 = {131 bookmark = E1A087D40548746200594651;132 history = (133 E1A087D30548746200594651,134 );135 };136 SplitCount = 1;137 };138 PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {600, 115}}";139 PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 115}, {600, 186}}";140 PBXProjectWorkspaceModule_OldSuperviewFrame = "{{0, 0}, {600, 301}}";141 PBXProjectWorkspaceModule_SGTM = {142 PBXBottomSmartGroupGIDs = (143 );144 PBXTopSmartGroupGIDs = (145 );146 };147 };148 },149 297 ); 150 298 "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { … … 208 356 WindowFrame = "{{8, 70}, {775, 753}}"; 209 357 }, 210 {211 Frame = "{{0, 0}, {600, 321}}";212 PBXProjectWorkspaceModule_GeometryKey_Rev11 = {213 GroupTreeCollapsed = yes;214 PBXProjectWorkspaceModule_SGTM_Geometry = {215 _collapsingFrameDimension = 182;216 _indexOfCollapsedView = 0;217 _percentageOfCollapsedView = 0.3033333;218 sizes = (219 "{{0, 0}, {600, 301}}",220 );221 };222 };223 WindowFrame = "{{523, 63}, {600, 383}}";224 },225 358 ); 226 359 "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { … … 277 410 WindowFrame = "{{723, 149}, {517, 249}}"; 278 411 }; 279 PBXWorkspaceStateSaveDate = 88649579; 280 }; 281 perUserProjectItems = { 282 E103506B05355596002A18D1 = E103506B05355596002A18D1; 283 E103506C05355596002A18D1 = E103506C05355596002A18D1; 284 E11E9B8E0544EE7900045D4F = E11E9B8E0544EE7900045D4F; 285 E11E9B8F0544EE7900045D4F = E11E9B8F0544EE7900045D4F; 286 E1375C530530898300FE8BF8 = E1375C530530898300FE8BF8; 287 E1375C560530898300FE8BF8 = E1375C560530898300FE8BF8; 288 E1A087BB0548731500594651 = E1A087BB0548731500594651; 289 E1A087CE0548746200594651 = E1A087CE0548746200594651; 290 E1A087CF0548746200594651 = E1A087CF0548746200594651; 291 E1A087D00548746200594651 = E1A087D00548746200594651; 292 E1A087D10548746200594651 = E1A087D10548746200594651; 293 E1A087D20548746200594651 = E1A087D20548746200594651; 294 E1A087D30548746200594651 = E1A087D30548746200594651; 295 E1A087D40548746200594651 = E1A087D40548746200594651; 412 PBXWorkspaceStateSaveDate = 134264568; 296 413 }; 297 414 sourceControlManager = E14C945E052A896100142529; … … 302 419 08FB7796FE84155DC02AAC07 = { 303 420 uiCtxt = { 304 sepNavIntBoundsRect = "{{0, 0}, { 578, 13369}}";305 sepNavSelRange = "{ 3507, 26}";306 sepNavVisRect = "{{0, 996}, {578, 654}}";307 sepNavWindowFrame = "{{ 265, 76}, {725, 703}}";421 sepNavIntBoundsRect = "{{0, 0}, {740, 11507}}"; 422 sepNavSelRange = "{29214, 0}"; 423 sepNavVisRect = "{{0, 8530}, {740, 660}}"; 424 sepNavWindowFrame = "{{15, 43}, {755, 698}}"; 308 425 }; 309 426 }; … … 314 431 ); 315 432 }; 316 E103506B05355596002A18D1 = {317 fRef = E1375C5D0530898300FE8BF8;318 isa = PBXTextBookmark;319 name = "LSOpen.h: 241";320 rLen = 0;321 rLoc = 8490;322 rType = 0;323 vrLen = 1029;324 vrLoc = 7546;325 };326 E103506C05355596002A18D1 = {327 fRef = E1375C5D0530898300FE8BF8;328 isa = PBXTextBookmark;329 name = "LSOpen.h: 241";330 rLen = 0;331 rLoc = 8490;332 rType = 0;333 vrLen = 1029;334 vrLoc = 7546;335 };336 E103508E0535B52C002A18D1 = {337 isa = PBXFileReference;338 name = CFString.h;339 path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFString.h;340 refType = 0;341 sourceTree = "<absolute>";342 };343 E11E9B8E0544EE7900045D4F = {344 fRef = E11E9B950544EE9700045D4F;345 isa = PBXTextBookmark;346 name = "(null): 158";347 rLen = 0;348 rLoc = 8234;349 rType = 0;350 vrLen = 1977;351 vrLoc = 6660;352 };353 E11E9B8F0544EE7900045D4F = {354 fRef = E103508E0535B52C002A18D1;355 isa = PBXTextBookmark;356 name = "CFString.h: CFStringCreateWithCString";357 rLen = 16;358 rLoc = 6861;359 rType = 0;360 vrLen = 2215;361 vrLoc = 5649;362 };363 E11E9B940544EE9700045D4F = {364 expectedFileType = sourcecode.c.h;365 isa = PBXFileReference;366 name = CFURL.h;367 path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFURL.h;368 refType = 0;369 sourceTree = "<absolute>";370 };371 E11E9B950544EE9700045D4F = {372 isa = PBXFileReference;373 name = CFStringEncodingExt.h;374 path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFStringEncodingExt.h;375 refType = 0;376 sourceTree = "<absolute>";377 };378 E11E9B960544EE9700045D4F = {379 expectedFileType = sourcecode.c.h;380 isa = PBXFileReference;381 name = LSOpen.h;382 path = /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LSOpen.h;383 refType = 0;384 sourceTree = "<absolute>";385 };386 E1375C530530898300FE8BF8 = {387 fRef = E1375C5C0530898300FE8BF8;388 isa = PBXTextBookmark;389 name = "(null): 1";390 rLen = 0;391 rLoc = 0;392 rType = 0;393 vrLen = 688;394 vrLoc = 0;395 };396 E1375C560530898300FE8BF8 = {397 fRef = E1375C5B0530898300FE8BF8;398 isa = PBXTextBookmark;399 name = "(null): 1";400 rLen = 0;401 rLoc = 0;402 rType = 0;403 vrLen = 688;404 vrLoc = 0;405 };406 E1375C5B0530898300FE8BF8 = {407 isa = PBXFileReference;408 name = LaunchServices.h;409 path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LaunchServices.h;410 refType = 0;411 sourceTree = "<absolute>";412 };413 E1375C5C0530898300FE8BF8 = {414 isa = PBXFileReference;415 name = LaunchServices.h;416 path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LaunchServices.h;417 refType = 0;418 sourceTree = "<absolute>";419 };420 E1375C5D0530898300FE8BF8 = {421 isa = PBXFileReference;422 name = LSOpen.h;423 path = /Developer/SDKs/MacOSX10.3.0.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LSOpen.h;424 refType = 0;425 sourceTree = "<absolute>";426 };427 433 E14C945E052A896100142529 = { 434 fallbackIsa = XCSourceControlManager; 435 isSCMEnabled = 1; 428 436 isa = PBXSourceControlManager; 429 437 scmConfiguration = { 430 438 }; 431 scmType = scm. cvs;439 scmType = scm.subversion; 432 440 }; 433 441 E14C945F052A896100142529 = { 434 442 indexTemplatePath = ""; 435 443 isa = PBXCodeSenseManager; 436 usesDefaults = 1;444 usesDefaults = 0; 437 445 wantsCodeCompletion = 1; 438 wantsCodeCompletionAutoPopup = 0;439 446 wantsCodeCompletionAutoSuggestions = 0; 440 447 wantsCodeCompletionCaseSensitivity = 1; 448 wantsCodeCompletionListAlways = 1; 441 449 wantsCodeCompletionOnlyMatchingItems = 1; 442 450 wantsCodeCompletionParametersIncluded = 1; … … 448 456 fileReference = 08FB7796FE84155DC02AAC07; 449 457 isa = PBXFileBreakpoint; 450 lineNumber = 674;458 lineNumber = 708; 451 459 state = 1; 452 460 }; … … 463 471 name = "handle URL/file arguments"; 464 472 rLen = 0; 465 rLoc = 1 7962;473 rLoc = 18094; 466 474 rType = 0; 467 475 vrLen = 1773; 468 476 vrLoc = 14523; 469 };470 E1A087BB0548731500594651 = {471 fRef = E11E9B960544EE9700045D4F;472 isa = PBXTextBookmark;473 name = "LSOpen.h: LSLaunchFSRefSpec";474 rLen = 27;475 rLoc = 2548;476 rType = 0;477 vrLen = 2176;478 vrLoc = 1426;479 };480 E1A087C80548731D00594651 = {481 expectedFileType = sourcecode.c.c;482 isa = PBXFileReference;483 name = main.c;484 path = /Volumes/Ti/Users/nicholas/Documents/Development/launch/launch/main.c;485 refType = 0;486 sourceTree = "<absolute>";487 };488 E1A087CE0548746200594651 = {489 fRef = E11E9B940544EE9700045D4F;490 isa = PBXTextBookmark;491 name = "CFURL.h: CFURLGetFSRef";492 rLen = 58;493 rLoc = 18538;494 rType = 0;495 vrLen = 1812;496 vrLoc = 16881;497 };498 E1A087CF0548746200594651 = {499 fRef = E1A087D50548746200594651;500 isa = PBXTextBookmark;501 name = "(null): 5155";502 rLen = 0;503 rLoc = 175675;504 rType = 0;505 vrLen = 2070;506 vrLoc = 174398;507 };508 E1A087D00548746200594651 = {509 fRef = 08FB7796FE84155DC02AAC07;510 isa = PBXTextBookmark;511 name = "main.c: 805";512 rLen = 5;513 rLoc = 33144;514 rType = 0;515 vrLen = 1438;516 vrLoc = 31911;517 };518 E1A087D10548746200594651 = {519 fRef = E1A087D60548746200594651;520 isa = PBXTextBookmark;521 name = "(null): 5155";522 rLen = 0;523 rLoc = 175675;524 rType = 0;525 vrLen = 2070;526 vrLoc = 174398;527 };528 E1A087D20548746200594651 = {529 fRef = 08FB7796FE84155DC02AAC07;530 isa = PBXTextBookmark;531 name = "main.c: 805";532 rLen = 0;533 rLoc = 33157;534 rType = 0;535 vrLen = 1436;536 vrLoc = 31909;537 };538 E1A087D30548746200594651 = {539 fRef = E1A087C80548731D00594651;540 isa = PBXTextBookmark;541 rLen = 1;542 rLoc = 808;543 rType = 1;544 };545 E1A087D40548746200594651 = {546 fRef = 08FB7796FE84155DC02AAC07;547 isa = PBXTextBookmark;548 name = "main.c: 809";549 rLen = 0;550 rLoc = 33280;551 rType = 0;552 vrLen = 325;553 vrLoc = 33020;554 };555 E1A087D50548746200594651 = {556 isa = PBXFileReference;557 name = Files.h;558 path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/Files.h;559 refType = 0;560 sourceTree = "<absolute>";561 };562 E1A087D60548746200594651 = {563 isa = PBXFileReference;564 name = Files.h;565 path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/Files.h;566 refType = 0;567 sourceTree = "<absolute>";568 477 }; 569 478 F561F49E0139D79101AEEDB1 = { … … 581 490 configStateDict = { 582 491 }; 492 cppStopOnCatchEnabled = 0; 493 cppStopOnThrowEnabled = 0; 494 customDataFormattersEnabled = 1; 583 495 debuggerPlugin = GDBDebugging; 496 disassemblyDisplayState = 0; 584 497 dylibVariantSuffix = ""; 585 498 enableDebugStr = 1; … … 587 500 ); 588 501 isa = PBXExecutable; 502 libgmallocEnabled = 0; 589 503 name = launch; 590 504 shlibInfoDictList = ( … … 595 509 F5C0CA9501B5740C01AEEDB1 = { 596 510 uiCtxt = { 597 sepNavIntBoundsRect = "{{0, 0}, {7 09, 3779}}";598 sepNavSelRange = "{ 7907, 0}";599 sepNavVisRect = "{{0, 3118}, {709, 443}}";600 sepNavWindowFrame = "{{ 38, 304}, {750, 502}}";511 sepNavIntBoundsRect = "{{0, 0}, {735, 3479}}"; 512 sepNavSelRange = "{8123, 0}"; 513 sepNavVisRect = "{{0, 2798}, {735, 464}}"; 514 sepNavWindowFrame = "{{130, 134}, {750, 502}}"; 601 515 }; 602 516 }; -
trunk/launch/launch/launch.pbproj/project.pbxproj
r146 r166 7 7 objects = { 8 8 014CEA490018CE3211CA2923 = { 9 buildRules = (10 );11 9 buildSettings = { 12 10 COPY_PHASE_STRIP = NO; … … 22 20 }; 23 21 014CEA4A0018CE3211CA2923 = { 24 buildRules = (25 );26 22 buildSettings = { 27 23 COPY_PHASE_STRIP = YES; … … 43 39 //034 44 40 034768E2FF38A6DC11DB9C8B = { 45 expectedFileType = "compiled.mach-o.executable"; 46 fallbackIsa = PBXFileReference; 47 isa = PBXExecutableFileReference; 41 explicitFileType = "compiled.mach-o.executable"; 42 isa = PBXFileReference; 48 43 path = launch; 49 44 refType = 3; … … 62 57 08FB7793FE84155DC02AAC07 = { 63 58 buildSettings = { 59 MACOSX_DEPLOYMENT_TARGET = 10.2; 60 SDKROOT = /Developer/SDKs/MacOSX10.2.8.sdk; 64 61 }; 65 62 buildStyles = ( … … 98 95 }; 99 96 08FB7796FE84155DC02AAC07 = { 100 expectedFileType = sourcecode.c.c;101 97 fileEncoding = 30; 102 98 isa = PBXFileReference; 99 lastKnownFileType = sourcecode.c.c; 103 100 path = main.c; 104 101 refType = 4; 105 102 sourceTree = "<group>"; 103 tabWidth = 8; 106 104 }; 107 105 08FB779DFE84155DC02AAC07 = { … … 197 195 //094 198 196 09AB6884FE841BABC02AAC07 = { 199 expectedFileType = wrapper.framework; 200 fallbackIsa = PBXFileReference; 201 isa = PBXFrameworkReference; 197 isa = PBXFileReference; 198 lastKnownFileType = wrapper.framework; 202 199 name = CoreFoundation.framework; 203 200 path = /System/Library/Frameworks/CoreFoundation.framework; … … 241 238 //F54 242 239 F561F49F0139D7DD01AEEDB1 = { 243 expectedFileType = wrapper.framework; 244 fallbackIsa = PBXFileReference; 245 isa = PBXFrameworkReference; 240 isa = PBXFileReference; 241 lastKnownFileType = wrapper.framework; 246 242 name = ApplicationServices.framework; 247 243 path = /System/Library/Frameworks/ApplicationServices.framework; … … 256 252 }; 257 253 F574340B01B8A47B01AEEDB1 = { 258 expectedFileType = text;259 254 fileEncoding = 30; 260 255 isa = PBXFileReference; 256 lastKnownFileType = text; 261 257 path = VERSION; 262 258 refType = 4; … … 264 260 }; 265 261 F579CF4B019A1C6D01AEEDB1 = { 266 expectedFileType = wrapper.framework; 267 fallbackIsa = PBXFileReference; 268 isa = PBXFrameworkReference; 262 isa = PBXFileReference; 263 lastKnownFileType = wrapper.framework; 269 264 name = Security.framework; 270 265 path = /System/Library/Frameworks/Security.framework; … … 279 274 }; 280 275 F5C0CA9501B5740C01AEEDB1 = { 281 expectedFileType = text;282 276 fileEncoding = 30; 283 277 isa = PBXFileReference; 278 lastKnownFileType = text; 284 279 path = README; 285 280 refType = 4; … … 287 282 }; 288 283 F5E819BF0198DFF701AEEDB1 = { 289 expectedFileType = wrapper.framework; 290 fallbackIsa = PBXFileReference; 291 isa = PBXFrameworkReference; 284 isa = PBXFileReference; 285 lastKnownFileType = wrapper.framework; 292 286 name = Carbon.framework; 293 287 path = /System/Library/Frameworks/Carbon.framework; -
trunk/launch/launch/main.c
r148 r166 3 3 Nicholas Riley <launchsw@sabi.net> 4 4 5 Copyright (c) 2001-0 3, Nicholas Riley5 Copyright (c) 2001-05, Nicholas Riley 6 6 All rights reserved. 7 7 … … 51 51 const char *APP_NAME; 52 52 53 #define VERSION "1.0 "53 #define VERSION "1.0.1" 54 54 55 55 #define STRBUF_LEN 1024 … … 59 59 OSType creator; 60 60 CFStringRef bundleID, name; 61 Boolean forceURLs; 61 62 enum { ACTION_FIND, ACTION_FIND_ITEMS, 62 63 ACTION_OPEN, ACTION_OPEN_ITEMS, … … 64 65 } OPTS = 65 66 { 66 kLSUnknownCreator, NULL, NULL, 67 kLSUnknownCreator, NULL, NULL, false, 67 68 ACTION_DEFAULT 68 69 }; … … 87 88 { -10827, "application package contains no executable, or an unusable executable" }, /* kLSNoExecutableErr, not defined in 10.2 */ 88 89 { -10828, "Classic environment required but not available" }, /* kLSNoClassicEnvironmentErr, not defined in 10.2 */ 90 { -10829, "unable to launch multiple instances of application" }, /* kLSMultipleSessionsNotSupportedErr, not defined in 10.2 */ 89 91 #ifndef BROKEN_AUTHORIZATION 90 92 // Security framework errors … … 97 99 { icInternalErr, "internal Internet Config error" }, 98 100 // Misc. errors 101 { nsvErr, "the volume cannot be found (buggy filesystem?)" }, 99 102 { procNotFound, "unable to connect to system service.\nAre you logged in?" }, 100 103 { kCGErrorIllegalArgument, "window server error.\nAre you logged in?" }, … … 105 108 106 109 void usage() { 107 fprintf(stderr, "usage: %s [-npswbmhCX ] [-c creator] [-i bundleID] [-u URL] [-a name] [item ...] [-]\n"108 " or: %s [-npflswbmhCX ] item ...\n", APP_NAME, APP_NAME);110 fprintf(stderr, "usage: %s [-npswbmhCXU] [-c creator] [-i bundleID] [-u URL] [-a name] [item ...] [-]\n" 111 " or: %s [-npflswbmhCXU] item ...\n", APP_NAME, APP_NAME); 109 112 fprintf(stderr, 110 113 " -n print matching paths/URLs instead of opening them\n" … … 121 124 " -C force CFM/PEF Carbon application to launch in Classic\n" 122 125 " -X don't start Classic for this app if Classic isn't running\n" 126 " -U interpret items as URLs, even if same-named files exist\n" 123 127 " -c creator match application by four-character creator code ('ToyS')\n" 124 128 " -i bundle ID match application by bundle identifier (com.apple.scripteditor)\n" … … 127 131 "'document' may be a file, folder, or disk - whatever the application can open.\n" 128 132 "'item' may be a file, folder, disk, or URL.\n\n"); 129 fprintf(stderr, "launch "VERSION" (c) 2001-0 3Nicholas Riley <http://web.sabi.net/nriley/software/>.\n"133 fprintf(stderr, "launch "VERSION" (c) 2001-05 Nicholas Riley <http://web.sabi.net/nriley/software/>.\n" 130 134 "Please send bugs, suggestions, etc. to <launchsw@sabi.net>.\n"); 131 135 … … 341 345 if (argc == 1) usage(); 342 346 343 while ( (ch = getopt(argc, argv, "npflswbmhCX c:i:u:a:")) != -1) {347 while ( (ch = getopt(argc, argv, "npflswbmhCXUc:i:u:a:")) != -1) { 344 348 switch (ch) { 345 349 case 'n': … … 384 388 case 'C': LSPEC.launchFlags |= kLSLaunchInClassic; break; // force Classic 385 389 case 'X': LSPEC.launchFlags ^= kLSLaunchStartClassic; break;// don't start Classic for app 390 case 'U': OPTS.forceURLs = true; break; 386 391 case 'c': 387 392 if (strlen(optarg) != 4) errexit("creator (argument of -c) must be four characters long"); … … 390 395 break; 391 396 case 'i': 392 OPTS.bundleID = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding());397 OPTS.bundleID = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); 393 398 appSpecified = true; 394 399 break; 395 400 case 'a': 396 OPTS.name = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding());401 OPTS.name = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); 397 402 appSpecified = true; 398 403 break; 399 404 case 'u': 400 { CFStringRef str = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding());405 { CFStringRef str = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingUTF8); 401 406 LSPEC.appURL = CFURLCreateWithString(NULL, str, NULL); 402 407 if (str != NULL) CFRelease(str); … … 471 476 LSPEC.launchFlags ^= kLSLaunchAsync; 472 477 } else { 473 argStr = CFStringCreateWithCString(NULL, argv[i], CFStringGetSystemEncoding()); 474 // check for URLs 475 itemURL = normalizedURLFromString(argStr); 476 if (itemURL == NULL && OPTS.action == ACTION_LAUNCH_URLS) { 477 // check for email addresses 478 if (strchr(argv[i], '@') != NULL && strchr(argv[i], '/') == NULL) 479 itemURL = normalizedURLFromPrefixSlack(CFSTR("mailto:"), argStr); 480 // check for "slack" URLs 481 if (itemURL == NULL && strchr(argv[i], '.') != NULL && strchr(argv[i], '/') != argv[i]) 482 itemURL = normalizedURLFromPrefixSlack(CFSTR("http://"), argStr); 483 } 478 struct stat stat_buf; 479 if (!OPTS.forceURLs && stat(argv[i], &stat_buf) == 0) { 480 itemURL = NULL; 481 } else { 482 argStr = CFStringCreateWithCString(NULL, argv[i], kCFStringEncodingUTF8); 483 // check for URLs 484 itemURL = normalizedURLFromString(argStr); 485 if (itemURL == NULL && OPTS.action == ACTION_LAUNCH_URLS) { 486 // check for email addresses 487 if (strchr(argv[i], '@') != NULL && strchr(argv[i], '/') == NULL) 488 itemURL = normalizedURLFromPrefixSlack(CFSTR("mailto:"), argStr); 489 // check for "slack" URLs 490 if (itemURL == NULL && strchr(argv[i], '.') != NULL && strchr(argv[i], '/') != argv[i]) 491 itemURL = normalizedURLFromPrefixSlack(CFSTR("http://"), argStr); 492 } 493 } 484 494 if (itemURL == NULL) { 485 495 // check for file paths 486 itemURL = CFURLCreate WithFileSystemPath(NULL, argStr, kCFURLPOSIXPathStyle, false);496 itemURL = CFURLCreateFromFileSystemRepresentation(NULL, argv[i], strlen(argv[i]), false); 487 497 err = LSCopyItemInfoForURL(itemURL, kLSRequestExtensionFlagsOnly, &docInfo); 488 498 if (err != noErr) osstatusexit(err, "unable to locate '%s'", argv[i]); … … 496 506 } 497 507 508 Boolean stringFromURLIsRemote(CFURLRef url, char *strBuffer) { 509 CFStringRef scheme = CFURLCopyScheme(url); 510 Boolean isRemote = !CFEqual(scheme, CFSTR("file")); 511 CFRelease(scheme); 512 513 strBuffer[0] = '\0'; 514 if (isRemote) { 515 CFStringRef urlString = CFURLGetString(url); 516 CFStringGetCString(urlString, strBuffer, STRBUF_LEN, kCFStringEncodingUTF8); 517 CFRelease(urlString); 518 } else { 519 if (CFURLGetFileSystemRepresentation(url, false, strBuffer, STRBUF_LEN)) { 520 if (strBuffer[0] == '.' && strBuffer[1] == '/') { 521 // remove the leading "./" 522 char *fromBufPtr = strBuffer + 2; 523 while (true) { 524 *strBuffer = *fromBufPtr; 525 if (*fromBufPtr == '\0') break; 526 strBuffer++; 527 fromBufPtr++; 528 } 529 } 530 } else { 531 strcpy(strBuffer, "[can't get path: CFURLGetFileSystemRepresentation failed]"); 532 } 533 } 534 return isRemote; 535 } 536 498 537 void printPathFromURL(CFURLRef url, FILE *stream) { 499 CFStringRef scheme, pathOrURL;500 538 static char strBuffer[STRBUF_LEN]; 501 502 539 check(url != NULL && stream != NULL); 503 504 scheme = CFURLCopyScheme(url); 505 506 if (CFEqual(scheme, CFSTR("file"))) 507 pathOrURL = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); 508 else 509 pathOrURL = CFURLGetString(url); 510 511 strBuffer[0] = '\0'; 512 CFStringGetCString(pathOrURL, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX buffer size issues? 540 stringFromURLIsRemote(url, strBuffer); 513 541 fprintf(stream, "%s\n", strBuffer); 514 CFRelease(scheme);515 CFRelease(pathOrURL);516 542 } 517 543 … … 582 608 583 609 if (fscInfo.nodeFlags & kFSNodeIsDirectoryMask) { 584 printf("\tcontents: %lu item%s\n", fscInfo.valence, fscInfo.valence != 1 ? "s" : ""); 610 printf("\tcontents: "); 611 switch (fscInfo.valence) { 612 case 0: printf("zero items\n"); break; 613 case 1: printf("1 item\n"); break; 614 default: printf("%lu items\n", fscInfo.valence); 615 } 585 616 } else { 586 617 printSizes("data fork size", fscInfo.dataLogicalSize, fscInfo.dataPhysicalSize, true); … … 605 636 } 606 637 638 const char *utf8StringFromCFStringRef(CFStringRef cfStr) { 639 static char tmpBuffer[STRBUF_LEN]; 640 CFStringGetCString(cfStr, tmpBuffer, STRBUF_LEN, kCFStringEncodingUTF8); 641 return tmpBuffer; 642 } 643 644 const char *utf8StringFromOSType(OSType osType) { 645 CFStringRef typeStr = CFStringCreateWithBytes(NULL, (const char *)&osType, 4, CFStringGetSystemEncoding(), false); 646 if (typeStr == NULL) { 647 // punt to displaying verbatim 648 static char tmpBuffer[4]; 649 tmpBuffer[4] = '\0'; 650 strncpy(tmpBuffer, (const char *)&osType, 4); 651 return tmpBuffer; 652 } 653 const char *buffer = utf8StringFromCFStringRef(typeStr); 654 CFRelease(typeStr); 655 return buffer; 656 } 657 607 658 // 'context' is to match prototype for CFArrayApplierFunction, it's unused 608 659 void printInfoFromURL(CFURLRef url, void *context) { 609 CFStringRef scheme, pathOrURL, kind; 610 Boolean isRemote; 611 static char strBuffer[STRBUF_LEN], tmpBuffer[STRBUF_LEN]; 660 CFStringRef kind; 661 static char strBuffer[STRBUF_LEN]; 612 662 613 663 check(url != NULL && context == NULL); 614 664 615 scheme = CFURLCopyScheme(url); 616 617 isRemote = !CFEqual(scheme, CFSTR("file")); 618 if (isRemote) 619 pathOrURL = CFURLGetString(url); 620 else 621 pathOrURL = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); 622 623 strBuffer[0] = '\0'; 624 CFStringGetCString(pathOrURL, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX buffer size issues? 625 if (isRemote) 665 if (stringFromURLIsRemote(url, strBuffer)) 626 666 printf("<%s>: URL\n", strBuffer); 627 667 else { 628 668 static LSItemInfoRecord info; 669 CFStringRef version = NULL; 670 UInt32 intVersion = 0; 629 671 OSStatus err = LSCopyItemInfoForURL(url, kLSRequestAllInfo, &info); 630 672 if (err != noErr) osstatusexit(err, "unable to get information about '%s'", strBuffer); … … 655 697 printf("\n"); 656 698 if (!(info.flags & kLSItemInfoIsContainer) || info.flags & kLSItemInfoIsPackage) { 657 tmpBuffer[4] = '\0'; 658 strncpy(tmpBuffer, (char *)&info.filetype, 4); printf("\ttype: '%s'", tmpBuffer); 659 strncpy(tmpBuffer, (char *)&info.creator, 4); printf("\tcreator: '%s'\n", tmpBuffer); 699 printf("\ttype: '%s'", utf8StringFromOSType(info.filetype)); 700 printf("\tcreator: '%s'\n", utf8StringFromOSType(info.creator)); 660 701 } 661 702 if (info.flags & kLSItemInfoIsPackage || info.flags & kLSItemInfoIsApplication) { … … 663 704 CFBundleRef bundle = CFBundleCreate(NULL, url); 664 705 CFStringRef bundleID = NULL; 665 CFStringRef appVersion = NULL;666 UInt32 intVersion = 0;667 706 if (bundle == NULL && (info.flags & kLSItemInfoIsApplication)) { 668 707 FSRef fsr; … … 683 722 CFPropertyListRef infoPlist = CFPropertyListCreateFromXMLData(NULL, plstData, kCFPropertyListImmutable, &error); 684 723 if (plstData != NULL) { 685 CFRelease(plstData); 686 plstData = NULL; 724 CFRelease(plstData); 725 plstData = NULL; 726 } else { 727 // this function should handle the 'plst' 0 case too, but it doesn't provide error messages; however, it handles the case of an unbundled Mach-O binary, so it is useful as a fallback 728 infoPlist = CFBundleCopyInfoDictionaryForURL(url); 687 729 } 688 730 if (infoPlist == NULL) { 689 CFStringGetCString(error, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); 690 printf("\t['plst' 0 resource invalid: %s]\n", tmpBuffer); 731 printf("\t['plst' 0 resource invalid: %s]\n", utf8StringFromCFStringRef(error)); 691 732 CFRelease(error); 692 733 } else { … … 694 735 bundleID = CFDictionaryGetValue(infoPlist, kCFBundleIdentifierKey); 695 736 if (bundleID != NULL) CFRetain(bundleID); 696 appVersion = CFDictionaryGetValue(infoPlist, CFSTR("CFBundleShortVersionString"));697 if ( appVersion == NULL)698 appVersion = CFDictionaryGetValue(infoPlist, kCFBundleVersionKey);699 if ( appVersion != NULL) CFRetain(appVersion);737 version = CFDictionaryGetValue(infoPlist, CFSTR("CFBundleShortVersionString")); 738 if (version == NULL) 739 version = CFDictionaryGetValue(infoPlist, kCFBundleVersionKey); 740 if (version != NULL) CFRetain(version); 700 741 CFRelease(infoPlist); 701 742 } … … 705 746 if (err != noErr && err != resNotFound) osstatusexit(err, "unable to read 'vers' 1 resource"); 706 747 } else { 707 if ( appVersion == NULL) { // prefer 'plst' version708 appVersion = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead?748 if (version == NULL) { // prefer 'plst' version 749 version = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead? 709 750 } 710 751 intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole; … … 717 758 if (bundleID != NULL) CFRetain(bundleID); 718 759 // prefer a short version string, e.g. "1.0 Beta" instead of "51" for Safari 719 appVersion = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));720 if ( appVersion == NULL)721 appVersion = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);722 if ( appVersion != NULL) {723 CFRetain( appVersion);760 version = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")); 761 if (version == NULL) 762 version = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey); 763 if (version != NULL) { 764 CFRetain(version); 724 765 intVersion = CFBundleGetVersionNumber(bundle); 725 766 } … … 727 768 } 728 769 if (bundleID != NULL) { 729 CFStringGetCString(bundleID, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); 730 printf("\tbundle ID: %s\n", tmpBuffer); 770 printf("\tbundle ID: %s\n", utf8StringFromCFStringRef(bundleID)); 731 771 CFRelease(bundleID); 732 772 } 733 if (appVersion != NULL) { 734 CFStringGetCString(appVersion, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); 735 printf("\tversion: %s", tmpBuffer); 736 if (intVersion != 0) printf(" [0x%lx = %lu]", intVersion, intVersion); 737 putchar('\n'); 738 CFRelease(appVersion); 739 } 740 } 741 773 } else { 774 // try to get a version if we can, but don't complain if we can't 775 FSRef fsr; 776 if (CFURLGetFSRef(url, &fsr)) { 777 SInt16 resFork = FSOpenResFile(&fsr, fsRdPerm); 778 if (ResError() == noErr) { 779 VersRecHndl vers = (VersRecHndl)Get1Resource('vers', 1); 780 if (ResError() == noErr && vers != NULL) { 781 version = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead? 782 intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole; 783 } 784 } 785 CloseResFile(resFork); 786 } 787 } 788 789 if (version != NULL) { 790 printf("\tversion: %s", utf8StringFromCFStringRef(version)); 791 if (intVersion != 0) printf(" [0x%lx = %lu]", intVersion, intVersion); 792 putchar('\n'); 793 CFRelease(version); 794 } 795 742 796 // kind string 743 797 err = LSCopyKindStringForURL(url, &kind); 744 798 if (err != noErr) osstatusexit(err, "unable to get kind of '%s'", strBuffer); 745 CFStringGetCString(kind, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); 746 printf("\tkind: %s\n", tmpBuffer); 799 printf("\tkind: %s\n", utf8StringFromCFStringRef(kind)); 747 800 CFRelease(kind); 748 801 printMoreInfoFromURL(url); 749 802 } 750 CFRelease(scheme);751 CFRelease(pathOrURL);752 803 } 753 804 … … 760 811 761 812 strBuffer[0] = '\0'; 762 CFStringGetCString(urlStr, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX buffer size issues?813 CFStringGetCString(urlStr, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX no idea what encoding ICLaunchURL is supposed to take; leave as is for now 763 814 strStart = 0; 764 815 strEnd = strlen(strBuffer); -
trunk/launch/package-launch.sh
r149 r166 1 #!/bin/ sh1 #!/bin/zsh 2 2 3 3 set -x -v … … 5 5 cd launch && \ 6 6 find . -name \*~ -exec rm '{}' \; && \ 7 xcodebuild && \7 xcodebuild -buildstyle Deployment && \ 8 8 SetFile -c 'R*ch' -t 'TEXT' README VERSION launch.1 && \ 9 9 strip build/launch && \ 10 10 sudo /usr/bin/install -c build/launch /usr/local/bin && \ 11 11 sudo /usr/bin/install -c launch.1 /usr/local/man/man1 && \ 12 chmod 755 build/launch && \ 13 chmod 644 launch.1 && \ 12 14 rm -rf build/launch.build build/intermediates build/.gdb_history && \ 13 15 VERSION=`cat VERSION` TARBALL="launch-$VERSION.tar.gz" && \ … … 16 18 rm -f launch-$VERSION $TARBALL $DMG && \ 17 19 ln -s launch launch-$VERSION && \ 18 tar -- exclude=.DS_Store --exclude=.svn --exclude=.gdb_history -zchf launch-$VERSION.tar.gz launch-$VERSION && \20 tar --owner=root --group=wheel --exclude=.DS_Store --exclude=.svn --exclude=.gdb_history -zchf launch-$VERSION.tar.gz launch-$VERSION && \ 19 21 #hdiutil create $DMG -megabytes 5 -ov -type UDIF && \ 20 22 #DISK=`hdid $DMG | sed -ne ' /Apple_partition_scheme/ s|^/dev/\([^ ]*\).*$|\1|p'` && \
Note:
See TracChangeset
for help on using the changeset viewer.