Changeset 52 for trunk/launch/launch/main.c
- Timestamp:
- 12/14/02 06:50:34 (21 years ago)
- Location:
- trunk/launch/launch
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/launch/launch
-
Property svn:ignore
set to
build
.*
-
Property svn:ignore
set to
-
trunk/launch/launch/main.c
r3 r52 23 23 - Does -X work at all? What does it return if it fails? 24 24 25 - Create blank document la my existing BBEdit alias? Use26 template/stationery?27 28 - Allow piping (like BBEdit, again?)29 30 25 - Launching as root: use authentication framework - doesn't work. 26 27 - launch URL with specified URL handler (done, except for IC) 31 28 32 29 - launch apps by IC protocol handler (esp. editor) … … 46 43 47 44 #include <unistd.h> 45 #include <sys/stat.h> 48 46 #include <Carbon/Carbon.h> 49 47 #include <CoreServices/CoreServices.h> … … 58 56 const char *APP_NAME; 59 57 60 #define VERSION "1.0 a9"58 #define VERSION "1.0b1" 61 59 62 60 #define STRBUF_LEN 1024 … … 78 76 79 77 LSLaunchURLSpec LSPEC = {NULL, NULL, NULL, DEFAULT_LAUNCH_FLAGS, NULL}; 78 79 char *TEMPFILE = NULL; 80 80 81 81 typedef struct { … … 107 107 108 108 void usage() { 109 fprintf(stderr, "usage: %s [-npswbmhCX] [-c creator] [-i bundleID] [-u URL] [-a name] [ document ...]\n"109 fprintf(stderr, "usage: %s [-npswbmhCX] [-c creator] [-i bundleID] [-u URL] [-a name] [item ...] [-]\n" 110 110 " or: %s [-npflswbmhCX] item ...\n", APP_NAME, APP_NAME); 111 111 fprintf(stderr, … … 140 140 errRec *rec; 141 141 const char *errDesc = "unknown error"; 142 c onst char *failedStr = "(unable to retrieve error message)";142 char * const failedStr = "(unable to retrieve error message)"; 143 143 static char *str = NULL; 144 144 size_t len; … … 152 152 str = (char *)malloc(len); 153 153 if (str != NULL) 154 snprintf(str, len, "%s (% d)", errDesc, (long)err);154 snprintf(str, len, "%s (%ld)", errDesc, err); 155 155 else 156 156 str = failedStr; … … 242 242 #endif 243 243 244 void getargs(int argc, const char *argv[]) { 244 CFURLRef normalizedURLFromString(CFStringRef str) { 245 CFURLRef url = CFURLCreateWithString(NULL, str, NULL); 246 if (url != NULL) { 247 CFURLRef absURL = CFURLCopyAbsoluteURL(url); 248 CFRelease(url); 249 url = NULL; 250 if (absURL != NULL) { 251 CFStringRef scheme = CFURLCopyScheme(absURL); 252 url = absURL; 253 if (scheme == NULL) { 254 CFRelease(url); 255 url = NULL; 256 } 257 } 258 } 259 return url; 260 } 261 262 CFURLRef normalizedURLFromPrefixSlack(CFStringRef prefix, CFStringRef slackStr) { 263 CFStringRef str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), 264 prefix, slackStr); 265 CFURLRef normalizedURL = normalizedURLFromString(str); 266 CFRelease(str); 267 return normalizedURL; 268 } 269 270 char *tempFile(int *fd) { 271 char *tmpDir = getenv("TMPDIR"); 272 const char * const tempTemplate = "/launch-stationery-XXXXXXXX"; 273 char *tempPath; 274 OSStatus err; 275 FSRef fsr; 276 FSCatalogInfo catalogInfo; 277 FileInfo *fInfo; 278 279 // create temporary file 280 if (tmpDir == NULL) tmpDir = "/tmp"; 281 tempPath = (char *)malloc(strlen(tmpDir) + strlen(tempTemplate) + 1); 282 if (tempPath == NULL) errexit("can't allocate memory"); 283 strcpy(tempPath, tmpDir); 284 strcat(tempPath, tempTemplate); 285 if ( (*fd = mkstemp(tempPath)) == -1) 286 errexit("can't create temporary file '%s'", tempPath); 287 // mark file as stationery 288 err = FSPathMakeRef(tempPath, &fsr, NULL); 289 if (err != noErr) osstatusexit(err, "can't find '%s'", tempPath); 290 err = FSGetCatalogInfo(&fsr, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL); 291 if (err != noErr) osstatusexit(err, "can't get information for '%s'", tempPath); 292 fInfo = (FileInfo *)&(catalogInfo.finderInfo); 293 fInfo->finderFlags |= kIsStationery; 294 err = FSSetCatalogInfo(&fsr, kFSCatInfoFinderInfo, &catalogInfo); 295 if (err != noErr) osstatusexit(err, "can't set information for '%s'", tempPath); 296 297 return tempPath; 298 } 299 300 char *stdinAsTempFile() { 301 unsigned char *buf; 302 int bufsize; 303 // Actual number of characters read, and therefore written. 304 ssize_t charCount; 305 int fd; 306 struct stat stat_buf; 307 char *tempFilePath; 308 309 tempFilePath = tempFile(&fd); 310 311 if (fstat(fd, &stat_buf) == -1) 312 errexit("can't fstat temporary file '%s'", tempFilePath); 313 314 bufsize = stat_buf.st_blksize; 315 if ( (buf = (unsigned char *)malloc(bufsize * sizeof(unsigned char))) == NULL) 316 errexit("can't allocate %ld bytes of buffer memory", 317 bufsize * sizeof(unsigned char)); 318 319 // Loop until the end of the file. 320 while (1) { 321 // Read a block of input. 322 charCount = read(STDIN_FILENO, buf, bufsize); 323 if (charCount < 0) { 324 errexit("can't read from standard input"); 325 } 326 // End of this file? 327 if (charCount == 0) 328 break; 329 // Write this block out. 330 if (write(fd, buf, charCount) != charCount) 331 errexit("error writing to file '%s'", tempFilePath); 332 } 333 free(buf); 334 return tempFilePath; 335 } 336 337 void getargs(int argc, char * const argv[]) { 245 338 extern char *optarg; 246 339 extern int optind; … … 311 404 break; 312 405 case 'u': 313 LSPEC.appURL = CFURLCreateWithString(NULL, 314 CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding()), NULL); 406 { CFStringRef str = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding()); 407 LSPEC.appURL = CFURLCreateWithString(NULL, str, NULL); 408 if (str != NULL) CFRelease(str); 409 } 315 410 if (LSPEC.appURL == NULL) { 316 411 errexit("invalid URL (argument of -u)"); … … 354 449 355 450 if (OPTS.action == ACTION_LAUNCH_URLS && appSpecified) 356 errexit("sorry, launching URLs with a given application is not yet supported"); // XXX 451 errexit("launching URLs with a given application is not supported; try without -l"); 357 452 358 453 if (OPTS.action == ACTION_INFO_ITEMS && appSpecified) … … 365 460 int i; 366 461 OSStatus err; 367 CFStringRef pathstr;462 CFStringRef argStr; 368 463 CFURLRef itemURL; 369 464 LSItemInfoRecord docInfo; … … 375 470 LSPEC.itemURLs = CFArrayCreateMutable(NULL, argc, NULL); 376 471 for (i = 0 ; i < argc ; i++) { 377 pathstr = CFStringCreateWithCString(NULL, argv[i], CFStringGetSystemEncoding()); 378 itemURL = NULL; 379 if (OPTS.action == ACTION_FIND_ITEMS || OPTS.action == ACTION_OPEN_ITEMS || 380 OPTS.action == ACTION_LAUNCH_URLS || OPTS.action == ACTION_INFO_ITEMS) { // check for URLs 381 itemURL = CFURLCreateWithString(NULL, pathstr, NULL); 382 if (itemURL != NULL) { 383 CFURLRef absURL = CFURLCopyAbsoluteURL(itemURL); 384 CFRelease(itemURL); 385 itemURL = NULL; 386 if (absURL != NULL) { 387 CFStringRef scheme = CFURLCopyScheme(absURL); 388 itemURL = absURL; 389 if (scheme == NULL) { 390 CFRelease(itemURL); 391 itemURL = NULL; 392 } 393 } 472 argStr = NULL; 473 if (strcmp(argv[i], "-") == 0) { 474 TEMPFILE = stdinAsTempFile(); 475 itemURL = CFURLCreateFromFileSystemRepresentation(NULL, TEMPFILE, strlen(TEMPFILE), false); 476 LSPEC.launchFlags ^= kLSLaunchAsync; 477 } else { 478 argStr = CFStringCreateWithCString(NULL, argv[i], CFStringGetSystemEncoding()); 479 // check for URLs 480 itemURL = normalizedURLFromString(argStr); 481 if (itemURL == NULL && OPTS.action == ACTION_LAUNCH_URLS) { 482 // check for email addresses 483 if (strchr(argv[i], '@') != NULL && strchr(argv[i], '/') == NULL) 484 itemURL = normalizedURLFromPrefixSlack(CFSTR("mailto:"), argStr); 485 // check for "slack" URLs 486 if (itemURL == NULL && strchr(argv[i], '.') != NULL && strchr(argv[i], '/') != argv[i]) 487 itemURL = normalizedURLFromPrefixSlack(CFSTR("http://"), argStr); 488 } 489 if (itemURL == NULL) { 490 // check for file paths 491 itemURL = CFURLCreateWithFileSystemPath(NULL, argStr, kCFURLPOSIXPathStyle, false); 492 err = LSCopyItemInfoForURL(itemURL, kLSRequestExtensionFlagsOnly, &docInfo); 493 if (err != noErr) osstatusexit(err, "unable to locate '%s'", argv[i]); 394 494 } 395 495 } 396 if (itemURL == NULL) {397 itemURL = CFURLCreateWithFileSystemPath(NULL, pathstr, kCFURLPOSIXPathStyle, false);398 err = LSCopyItemInfoForURL(itemURL, kLSRequestExtensionFlagsOnly, &docInfo);399 if (err != noErr) osstatusexit(err, "unable to locate '%s'", argv[i]);400 }401 496 CFArrayAppendValue((CFMutableArrayRef)LSPEC.itemURLs, itemURL); 402 CFRelease(pathstr); 497 // don't CFRelease the itemURL because CFArray doesn't retain it by default 498 if (argStr != NULL) CFRelease(argStr); 403 499 } 404 500 } … … 616 712 } 617 713 618 int main (int argc, c onst char *argv[]) {714 int main (int argc, char * const argv[]) { 619 715 OSStatus err; 620 716 … … 670 766 } 671 767 768 if (TEMPFILE != NULL) { 769 // the application may take a while to finish opening the temporary file 770 daemon(0, 0); 771 sleep(60); 772 unlink(TEMPFILE); 773 } 774 672 775 return 0; 673 776 }
Note:
See TracChangeset
for help on using the changeset viewer.