This is open.m in view mode; [Download] [Up]
/* -*-ObjC-*- ****************************************************************************** * * File: open.m * RCS: /usr/local/lib/cvs/open/open.m,v 1.14 1995/05/08 18:37:59 chris Exp * Description: replacement for /usr/bin/open * Author: Christian Limpach <chris@nice.ch> * Created: Wed Mar 20 23:48:35 1994 * Modified: Mon May 8 20:28:24 1995 (Christian Limpach) chris@nice.ch * Language: ObjC * Package: open * Status: Released * * (C) Copyright 1994, Christian Limpach, all rights reserved. * ****************************************************************************** */ /* * open.m,v * Revision 1.14 1995/05/08 18:37:59 chris * made -as option sticky, it will now remain in effect until an * application is explicitely selected via the -a option. * this is version 1.3 now * * Revision 1.13 1995/05/08 17:50:08 chris * made -as symlink generation reuse existing symlinks if possible * and use the basename of the file instead of openfiletmp as the * symlink template [suggested by Peter Langston <psl@acm.org>] * * Revision 1.12 1995/05/08 15:44:11 chris * fixed double tempfile when -as and stdin * [reported by Peter Langston <psl@acm.org>] * * Revision 1.11 1995/05/02 22:28:07 chris * changed version number to 1.2 * * Revision 1.10 1995/05/02 22:18:15 chris * added -as option to define extensions of files without or with * incorrect extensions [suggested by Peter Langston <psl@acm.org>] * * Revision 1.9 1995/04/05 01:10:22 chris * fixed problem with uninitialized stat parameter * [reported by Daniel G. Kluge <daniel@vis.inf.ethz.ch>] * * Revision 1.8 1995/03/30 17:37:02 chris * fixed bug with openfiletmpXXXXXX.ext where NXGetTempFilename replaced * XX.ext insted of XXXXXX. added documentation for -pause and -connectp. * increased version number to 1.1. * * Revision 1.7 1994/09/01 14:58:24 chris * added -connectp (check if we can connect to a Windowserver) and * -pause n to make open pause n seconds before exiting * * Revision 1.6 1994/06/20 22:19:32 chris * added -tmpdir option to choose directory used for temporary files * * Revision 1.5 1994/05/30 22:02:55 chris * added -help and -version * * Revision 1.4 1994/05/26 12:47:39 chris * added `Foo.client somefile' = `open -a Foo -wait somefile' * [suggested by Carl Edman <cedman@princeton.edu>] * * Revision 1.3 1994/05/23 18:00:17 chris * fixed bug which broke 'open -p *.txt' (only the first file was * printed) [reported by Paul van der Zwan <paulzn@olivetti.nl>] * fixed bug which broke -NXHost (no more Application object) * [reported by Bill Bumgarner <bbum@friday.com>] * * Revision 1.2 1994/05/09 21:37:42 chris * fixed NXHost which was broken because of [Application new] * * Revision 1.1 1994/05/05 22:32:05 chris * replaces /usr/bin/open and adds some nice features * */ #ifdef RCSID static char rcsid[] = "open.m,v 1.14 1995/05/08 18:37:59 chris Exp"; #endif #define VERSION_STRING "open v1.3\n" #import "open.h" @implementation AppInfo - initFor:(const char *)openApp onHost:(const char *)hostName { [super init]; if((Port=NXPortFromName(openApp, hostName)) != PORT_NULL) { Name=str_copy(openApp); Host=str_copy(hostName); } return self; } - (port_t)port { return Port; } - (BOOL)isEntryFor:(const char *)openApp:(const char *)hostName { if(!strcmp(Name, openApp) && (Host==hostName || (Host!=NULL && hostName!=NULL && !strcmp(Host, hostName)))) return YES; else return NO; } @end @implementation AppList - (port_t)getPortFor:(const char *)anApp onHost:(const char *)aHost { int index; for(index=0; index<[self count]; index++) if([[self objectAt:index] isEntryFor:anApp:aHost]) break; if(index!=[self count]) return [[self objectAt:index] port]; else { id info; info=[[AppInfo alloc] initFor:anApp onHost:aHost]; if ([info port]!=PORT_NULL) [self addObject:info]; return [info port]; } } @end void version() { fprintf(stderr, VERSION_STRING); } int check_help(int argc, char *argv[], const char *appName, int flag) { if(argc>1 && !strcmp(argv[1], "-help")) { if(flag==HELP_UNHIDE) fprintf(stderr, "%s [app] ", appName); else if(flag==HELP_APPOPEN) fprintf(stderr, "%s app ", appName); else if(flag==HELP_OPENAS) fprintf(stderr, "%s extension ", appName); else fprintf(stderr, "%s ", appName); fprintf(stderr, "[-a app] [-o file] [-p] " "[-NXHost hostname] [-unhide] [-nostat] [-wait] " "[-temp] [-tmpdir directory] [-connectp] [-pause n] " "[-as extension] [+linenum] [filename] ...\n"); return 1; } else if(argc>1 && !strcmp(argv[1], "-version")) { version(); return 1; } else return 0; } void main(int argc, char *argv[]) { port_t appPort; int ok, arg=1; char *host=NULL; const char *openApp=WORKSPACE, *appName, *tmpDir="/tmp", *asExt=""; id appSpeaker = [[Speaker alloc] init]; id appList = [[AppList alloc] init]; int openMode=OPEN, fileMode=DISK, openedAFile=0; int oline=0, waitForFileChange=0, noStat=0, openAs=0; if(appName=strrchr(argv[0], '/')) appName++; else appName=argv[0]; if(strcmp(appName, "open")) if(!strcmp(appName, "appopen") || !strcmp(appName, "run")) { if(check_help(argc, argv, appName, HELP_APPOPEN)) { arg++; openedAFile++; } else if(argc<(arg+1)) { printf("Usage: %s Application file...\n", appName); exit(1); } openApp=argv[arg++]; } else if(!strcmp(appName, "unhide")) { if(check_help(argc, argv, appName, HELP_UNHIDE)) { arg++; openedAFile++; } if(argc>arg) openApp=argv[arg++]; openMode=UNHIDE; } else if(strlen(appName)>CLIENTEXTLEN && !strcmp(&appName[strlen(appName)-CLIENTEXTLEN], CLIENTEXT)) { register char *name; waitForFileChange++; name=str_copy(appName); name[strlen(name)-CLIENTEXTLEN]='\000'; openApp=name; if(check_help(argc, argv, appName, HELP_OPEN)) { arg++; openedAFile++; } } else if(!strcmp(appName, "openAs")) { if(check_help(argc, argv, appName, HELP_OPENAS)) { arg++; openedAFile++; } else if(argc<(arg+1)) { printf("Usage: %s extension file...\n", appName); exit(1); } asExt=argv[arg++]; openAs++; } else { openApp=appName; if(check_help(argc, argv, appName, HELP_OPEN)) { arg++; openedAFile++; } } else if(check_help(argc, argv, appName, HELP_OPEN)) { arg++; openedAFile++; } while(1) { int argIsFile=0; if(arg>=argc) /* auto detect stdin */ if(openedAFile) break; else { if((openApp!=WORKSPACE && openMode==OPEN) || openMode==UNHIDE) { if(openMode==OPEN) openMode=APP; fileMode=NONE; } else fileMode=STDIN; argIsFile++; } else if(argv[arg][0]=='-') { if(!strcmp(&argv[arg][1], "NXHost")) { if(arg!=(argc-1)) host=argv[++arg]; else argIsFile++; } else if(!strcmp(&argv[arg][1], "wait")) { waitForFileChange++; } else if(!strcmp(&argv[arg][1], "nostat")) { noStat++; } else if(!strcmp(&argv[arg][1], "unhide") || !strcmp(&argv[arg][1], "activate") || !strcmp(&argv[arg][1], "makeKey")) { openMode=UNHIDE; fileMode=NONE; argIsFile++; } else if(!strcmp(&argv[arg][1], "temp")) { fileMode=TEMP; } else if(!strcmp(&argv[arg][1], "version")) { version(); } else if(!strcmp(&argv[arg][1], "tmpdir")) { if(arg!=(argc-1)) tmpDir=argv[++arg]; else argIsFile++; } else if(!strcmp(&argv[arg][1], "connectp")) { if(NXPortFromName(WORKSPACE, host) != PORT_NULL) exit(0); else exit(1); } else if(!strcmp(&argv[arg][1], "pause")) { if(arg!=(argc-1)) sleep(atoi(argv[++arg])); else argIsFile++; } else if(!strcmp(&argv[arg][1], "as")) { if(arg!=(argc-1)) { openAs++; asExt=argv[++arg]; } else argIsFile++; } else if(argv[arg][1]=='\000') { if(arg==(argc-1) && !openedAFile) fileMode=STDIN; argIsFile++; } else if(argv[arg][2]=='\000') { switch(argv[arg][1]) { case 'a': /* next arg is new application to open with */ if(arg!=(argc-1)) { openApp=argv[++arg]; openAs=0; } else argIsFile++; break; case 'o': /* open next arg without checking switches */ openMode=OPEN; if(arg!=(argc-1)) arg++; argIsFile++; break; case 'p': /* go printmode */ openMode=PRINT; break; default: /* not a switch -> open it */ argIsFile++; break; } } else argIsFile++; /* not a longopt -> open it */ } else if(argv[arg][0]=='+') { int i=0; oline=0; while(argv[arg][++i]!='\0') if(isdigit(argv[arg][i])) oline=10*oline+(argv[arg][i]-48); else { argIsFile++; break; } if(!argIsFile) { if(arg!=(argc-1)) { openMode=OPENLINE; arg++; } argIsFile++; } } else argIsFile++; /* not an opt at all -> open it */ if(argIsFile) { char fname[MAXPATHLEN+1+(arg>=argc?0:strlen(argv[arg]))+ (openAs?strlen(asExt):0)+1]; struct stat buf; switch(fileMode) { case STDIN: { char buffer[STDINBUFSIZE+1]; int len, xxpos; FILE *file; if((len=fread(buffer, 1, STDINBUFSIZE, stdin))>=0) { if(tmpDir[0]=='/') strcpy(fname, tmpDir); else { getwd(fname); strcat(fname, "/"); strcat(fname, tmpDir); } if(fname[strlen(fname)-1]!='/') strcat(fname, "/"); strcat(fname, "openfiletmpXXXXXX"); xxpos=strlen(fname)-6; buffer[len]='\0'; if (!openAs) { if(len>=5 && !strncmp(buffer, "{\\rtf", 5)) strcat(fname, ".rtf"); else if(len>=11 && !strncmp(buffer, "%!PS-Adobe-", 11)) if(strstr(buffer, "EPSF-")<strchr(buffer, '\012')) strcat(fname, ".eps"); else strcat(fname, ".ps"); } else { strcat(fname, "."); strcat(fname, asExt); } NXGetTempFilename(fname, xxpos); if(!(file=fopen(fname, "wb"))) { printf("%s: couldn't create temp file\n", appName); exit(1); } while(len==STDINBUFSIZE) { fwrite(buffer, STDINBUFSIZE, 1, file); len=fread(buffer, 1, STDINBUFSIZE, stdin); } fwrite(buffer, 1, len, file); fclose(file); } break; } case NONE: break; case DISK: case TEMP: default: if(argv[arg][0]=='/') strcpy(fname, argv[arg]); else { getwd(fname); strcat(fname, "/"); strcat(fname, argv[arg]); } if(fname[strlen(fname)-1]=='/') strcat(fname, "."); break; } if(openAs && fileMode!=STDIN) { char *tmp, fname2[MAXPATHLEN+1+(arg>=argc?0:strlen(argv[arg]))+ strlen(asExt)+1], fname3[MAXPATHLEN]; int count=1, cc; if(tmpDir[0]=='/') strcpy(fname2, tmpDir); else { getwd(fname2); strcat(fname2, "/"); strcat(fname2, tmpDir); } if(fname2[strlen(fname2)-1]!='/') strcat(fname2, "/"); tmp=fname2+strlen(fname2); if(strrchr(fname, '/')) { strcat(fname2, strrchr(fname, '/')+1); if(tmp=strrchr(tmp, '.')) *tmp='\0'; } else strcat(fname2, "openfiletmp"); tmp=fname2+strlen(fname2); sprintf(tmp, "%06d.%s", count++, asExt); while(!stat(fname2, &buf)) { if(buf.st_mode & S_IFLNK) { cc=readlink(fname2, fname3, MAXPATHLEN); if(!strncmp(fname, fname3, cc)) { tmp=NULL; break; } } sprintf(tmp, "%06d.%s", count++, asExt); } if(tmp) { symlink(fname, fname2); } strcpy(fname, fname2); } if(!noStat && openMode!=APP && openMode!=UNHIDE && stat(fname, &buf)) printf("%s: can't stat file: %s\n", appName, fname); else { char *connName; NXAtom type; if((openMode==PRINT || openMode==OPENLINE) && !strcmp(openApp, WORKSPACE)) [[Application workspace] getInfoForFile:fname application:&connName type:&type]; else connName=str_copy(openApp); if((appPort=[appList getPortFor:connName onHost:host]) != PORT_NULL) { [appSpeaker setSendPort:appPort]; switch(openMode) { case UNHIDE: [appSpeaker performRemoteMethod:"unhide"]; break; case APP: break; case OPENLINE: [appSpeaker selectorRPC:"openFile:onHost:atTrueLine:" paramTypes:"cci", fname, host?host:"localhost", oline]; break; case PRINT: if([appSpeaker msgPrint:fname ok:&ok] || !ok) printf("%s: unable to print file: %s\n", appName, fname); break; case OPEN: default: if(fileMode==STDIN || fileMode==TEMP || openAs) { if([appSpeaker openTempFile:fname ok:&ok] || !ok) printf("%s: unable to open temp file: %s\n", appName, fname); } else { if([appSpeaker openFile:fname ok:&ok] || !ok) printf("%s: unable to open file: %s\n", appName, fname); } break; } if(!noStat && waitForFileChange) { time_t last=buf.st_mtime; while(buf.st_mtime==last && !sleep(1)) stat(fname, &buf); } } else { printf("%s: can't open connection to %s on %s.\n", appName , openApp, host?host:"local host"); } str_free(connName); } waitForFileChange=0; noStat=0; fileMode=DISK; if(openMode!=PRINT) openMode=OPEN; openedAFile++; } arg++; } [appSpeaker free]; exit(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.