This is Controller.m in view mode; [Download] [Up]
/***************************************************************************** * Controller.m * * Authors: * Denise Howard * howardd@swissbank.com * * Michael Hawley * mike@media.mit.edu * * Copyright (c) MIT Media Laboratory, 1991-1995. * * Description: * This is the app delegate for Opener. * * Revisions: * See Revision_History.rtfd in project directory HelpOpener. * * To add new filetypes: * See Modifying.rtfd in project directory HelpOpener. * * Modified by Tsutomu_Eguchi@ns.saga-med.ac.jp April 1998 * Add bzip2, bunzip2, binhex support * See Modifying.rtfd in project directory HelpOpener. * *****************************************************************************/ #import "Controller.h" #import "Help.h" #import "ComposeSuggestion.h" @interface Speaker(ObsoleteMethods) - (int)registerWindow:(int)windowNum toPort:(port_t)aPort; - (int)unregisterWindow:(int)windowNum; @end @implementation Controller static NXDefaultsVector OpenerDefaults = { {"TmpDir", "/tmp"}, {"ArchiveFormat", ".tar.Z"}, {"FirstUsed", ""}, {NULL} }; #define MaxLen 256 #define MaxSuf 64 #define MaxTab 64 #define MaxPend 512 #define LS_MSG_YES NXLocalizedString("Yes", NULL, "LS_MSG_YES") //TE #define LS_MSG_NO NXLocalizedString("No", NULL, "LS_MSG_NO") //TE #define LS_MSG_COULDNT_OPEN \ NXLocalizedString("Couldn't open file: %s",NULL,"LS_MSG_COULDNT_OPEN") //TE char TmpDir[1024] = "/tmp"; char *iconPathList = (char *)0; char MoreFiles[8192] = ""; int Reset = 1; char Suffix[MaxTab][MaxSuf], Command[MaxTab][MaxLen]; int NT = 0; char PSuffix[MaxTab][MaxSuf], PCommand[MaxTab][MaxLen]; int PNT = 0; char *Pending[MaxPend]; int NP = 0; static id me, pb2; static char Files[8192]; /*****************************************************************************/ /* Functions start here */ /*****************************************************************************/ int err(a,b,c,d) char *a,*b,*c,*d; { char t[1024]; extern id NXApp; sprintf(t,a,b,c,d); return NXRunAlertPanel([NXApp appName],t,0,0,0)==1; } char * tmp(char *s, char *suffix, int isDir) { /* * return a path for a temporary file * named "/tmp/O_[n_]file", where 'file' is 's'; * e.g., /a/b/foo.bar, .bar => /tmp/O_foo * if 'isDir', map a "." in the suffix to "_" to ensure that * the directory wrapper will open properly. */ static char t[1024]; char *p, u[1024]; int k = 1; strcpy(u,s); if (*suffix) u[strlen(u) - strlen(suffix)] = '\0'; if (p = rindex(u,'/')) p++; else p = s; if (isDir) { char *x = rindex(p,'.'); if (x) *x = '_'; } sprintf(t,"%s/O_%s", TmpDir, p); while (access(t,0)==0) sprintf(t, "%s/O_%d_%s", TmpDir, k++, p); return t; } char * path(char *s) /* * if 's' is in [NXArgv[0]], return [NXArgv[0]]/s. * (for looking up internal commands and files in .../Opener.app/...). */ { char t[1024], *q, *r; static char p[1024]; extern char **NXArgv; *t = '\0'; sscanf(s,"%s",t); if (!*t || *t=='(') return s; r = s + strlen(t); strcpy(p,*NXArgv); if (q=rindex(p,'/')) strcpy(q+1,t); else strcpy(p,t); if (access(p,0)==0){ strcpy(p+strlen(p),r); return p; } return s; } char * skipsp(char *s) { while (*s==' ' || *s=='\t' || *s == '\n') ++s; return s; } int blank(char *s) { /* true if 's' is blank */ while (*s == ' ' || *s=='\t' || *s == '\n') ++s; return !*s; } char * save(char *s) { char *p = (char *)malloc(strlen(s)+1); if (p) strcpy(p,s); return p; } void stripcomment(char *s) { /* truncate 's' at a comment character ('#') */ char *p = index(s,'#'); if (p && (p==s || p[-1] != '\\')) *p = '\0'; } char * strindex(char *s, char *t) { /* return ptr to first match of 't' in 's' */ int n = strlen(t); if (s) while (*s) if (!strncmp(s, t, n)) return s; else s++; return (char *)0; } // Case-insensitive version of equal(). // Commented out by Denise Howard 08/93 Opener 3.1.1. // int // equal(char *s, char *t) // { /* true if 's' & 't' are equal (case-insens.) */ // char a, b; // while (*s && *t){ // a = isupper(*s)? tolower(*s) : *s; // b = isupper(*t)? tolower(*t) : *t; // s++, t++; // if (a != b) return 0; // } // return (*s || *t)? 0 : 1; // } /* Case-sensitive version of equal(). */ /* Added by Howard 08/93 Opener 3.1.1. */ int equal(char *s, char *t) { /* true if 's' & 't' are equal (case-sens.) */ char a, b; while (*s && *t){ a = *s; b = *t; s++, t++; if (a != b) return 0; } return (*s || *t)? 0 : 1; } int tailmatch(char *s, char *t) { /* true if t appears at end of s */ int tn = strlen(t), sn = strlen(s); if (tn > sn) return 0; return equal(s+(sn-tn), t); } char * shstrcat(char *s, char *t) { // strcat, but quote shell metachars register char *p; while (*s) s++; p=t; if (*p=='~') *s++='\\'; // csh "feature" while (*p) { if (*p<=' '||*p>'~'||index(";&()|<>\\'\"$*?[]^!", *p)) *s++='\\'; *s++=*p++; } *s='\0'; return t; } void subfname(char *s, char *a, char *b) { /* like 'substr', but assumes the "b" string is a filename that may need special-to-shell characters quoted */ char q[8192], quoted_b[2048]; char *p = s; int n = strlen(a); quoted_b[0] = '\0'; shstrcat(quoted_b, b); for (;*p;p++){ if (*p == *a && strncmp(p,a,n)==0){ strcpy(q,p+n); strcpy(p,quoted_b); strcpy(p+strlen(quoted_b),q); p += strlen(quoted_b)-1; } } } int fdTime(int f) { /* return size of file 'f' */ struct stat b; fstat(f, &b); return b.st_mtime; } void clearPackItems() { int i, n = [[pb2 target] count]; for (i=0;i<n;i++){ [[pb2 target] removeItemAt:i]; } } void addPackItem(char *s) { // What this function does: add a cell to the pb2 matrix with title 's', // and assign it a selector so that when someone selects it the title // becomes the new default pack suffix. id c; c = [[pb2 target] addItem:s]; [c setTarget:me]; [c setAction:@selector(setPackSuffix:)]; } void resetPackItems() { int i; clearPackItems(); for (i=0;i<PNT;i++) addPackItem(PSuffix[i]); } void addUnpackItem(char *s) { id c; c = [[pb2 target] addItem:s]; [c setTarget:me]; [c setAction:@selector(setUnpackSuffix:)]; } void loadTable() { /* * Unpacking files is table-driven. * The file "Opener.table" is of the form * suffix command * like * .Z uncompress < $f > $t * When opening files, the table is checked to * find a matching command for the given suffix. */ char s[1024]; FILE *f; static int first = 1; static int t = 0; int pack = 0; strcpy(s,path("Opener.table")); if (!first){ if (f=fopen(s,"r")){ int tt = fdTime(fileno(f)); fclose(f); if (tt == t) return; t = tt; // table has changed -- reread it NT=PNT=0; clearPackItems(); printf("rereading table\n"); } else return; } first = 0; if (f = fopen(s,"r")){ char *p, *q; t = fdTime(fileno(f)); while (fgets(s,sizeof s,f)){ stripcomment(s); if (blank(s)) continue; if (strncmp(s,"Unpack:",7)==0) continue; if (strncmp(s,"Pack:",5)==0){ pack++; continue; } if (pack){ for (p=skipsp(s), q=PSuffix[PNT]; *p && *p != ' ' && *p != '\t' && (q-PSuffix[PNT])<(MaxSuf-1); *q++ = *p++) ; *q = '\0'; for (p = skipsp(p), q=PCommand[PNT]; *p && (*p != '\n') && (q-PCommand[PNT])<(MaxLen-1); *q++ = *p++) ; *q='\0'; addPackItem(PSuffix[PNT]); // printf("[%s]: %s\n",PSuffix[PNT],PCommand[PNT]); if (!blank(PSuffix[PNT])&& !blank(PCommand[PNT]) && PNT < MaxTab) ++PNT; } else { for (p=skipsp(s), q=Suffix[NT]; *p && *p != ' ' && *p != '\t' && (q-Suffix[NT])<(MaxSuf-1); *q++ = *p++) ; *q = '\0'; for (p = skipsp(p), q=Command[NT]; *p && (*p != '\n') && (q-Command[NT])<(MaxLen-1); *q++ = *p++) ; *q='\0'; // printf("[%s]: %s\n",Suffix[NT],Command[NT]); if (!blank(Suffix[NT]) && !blank(Command[NT]) && NT < MaxTab) ++NT; } } fclose(f); } } int findSuffix(char *s) { char *p = s + strlen(s); int i; loadTable(); for (i=0;i<NT;i++) if (equal(Suffix[i],p-strlen(Suffix[i]))) return i; return -1; } int findPSuffix(char *s) { char *p = s + strlen(s); int i; loadTable(); for (i=0;i<PNT;i++) if (equal(PSuffix[i],p-strlen(PSuffix[i]))) return i; return -1; } void ex_unpack(char *s) { char t[1024]; if (strncmp(s,"unpack: ",8)) return; strcpy(t,skipsp(s+8)); strcpy(s,"mkdir $t; cd $t; "); strcat(s,t); } void substr(char *s, char *a, char *b) { /* like 'sub', but with strings */ char q[8192]; char *p = s; int n = strlen(a); for (;*p;p++){ if (*p == *a && strncmp(p,a,n)==0){ strcpy(q,p+n); strcpy(p,b); strcpy(p+strlen(b),q); p += strlen(b)-1; } } } void expand(char *s, int i, char *c) { /* * 's' is the current filename. * 'i' is the index in the Suffix/Command table. * 'c' is the command to fill; * Replace "unpack: ..." with the standard unpack command * $f with the filename, * $g => $f without the path * $r => $f without any extensions * $R => $f without any extensions and without the path * $e => all the extensions (including the dot) * $t with the temp */ char *T, *p, S[MaxSuf], q[1024], *r; int isDir = 0; strcpy(c,Command[i]); strcpy(S,s+strlen(s)-strlen(Suffix[i])); if (strindex(c,"mkdir $t") || strindex(c,"unpack: ")) isDir = 1; T = tmp(s,Suffix[i],isDir); ex_unpack(c); /* rewrite "unpack: ..." */ p = c; /* prepend the $p/... paths */ while (p = strindex(p,"$p/")){ sscanf(p,"%s",q); r = path(q+3); substr(p,q,r); } if (!strindex(c,"open ")){ if (isDir) strcat(c,"; (cd $t; open . )"); // make sure directory opens else strcat(c,"; open $t"); } subfname(c,"$f",s); /* expand the abbreviations */ subfname(c,"$t",T); subfname(c,"$s",S); /*******************************************************/ /* The following chunk handles the $r abbreviation */ /*******************************************************/ { char root[1024]; int index=0; while(s[index]!='\0' && index<1024 && s[index]!='.'){ root[index] = s[index]; index++; } root[index]='\0'; subfname(c,"$r",root); } /*******************************************************/ /* The following chunk handles the $e abbreviation */ /*******************************************************/ { char ext[1024]; int index=0,ptr=0; ext[0]='\0'; while(s[index]!='\0' && index<1024 && s[index]!='.'){ index++; } if(s[index]=='.'){ ptr = index; while(s[index]!='\0' && index<1024){ ext[index-ptr]=s[index]; index++; } ext[index-ptr]='\0'; } subfname(c,"$e",ext); } /*******************************************************/ /* The following chunk handles the $R abbreviation */ /*******************************************************/ { char rroot[1024]; int index=0; rroot[0]='\0'; while(s[index]!='\0'){index++;} while(index>-1 && s[index]!='/'){index--;} if(s[index]=='/'){ index++; while(s[index]!='\0' && index<1024 && s[index]!='.'){ rroot[index] = s[index]; index++; } } subfname(c,"$R",rroot); } /*******************************************************/ /* The following chunk handles the $g abbreviation */ /*******************************************************/ { char sroot[1024]; int index=0; sroot[0]='\0'; while(s[index]!='\0'){index++;} while(index>-1 && s[index]!='/'){index--;} if(s[index]=='/'){ index++; while(s[index]!='\0' && index<1024){ sroot[index] = s[index]; index++; } } subfname(c,"$g",sroot); } } void getTmpName(char *s, char *t) { /* * Copy a /tmp name for the comp.sources archive into 't'. * if 's' is ...comp.sources/.../foo/part00.Z ==> /tmp/O_foo * ...comp.sources/.../foo.Z ==> /tmp/O_foo */ char *p = rindex(s,'/'), q[1024], c; int n; if (!p) return (void)strcpy(t,s); strcpy(q,p+1); c = q[4]; q[4]='\0'; if (equal(q,"part") && isdigit(c)){ /* skip to previous */ *p='\0'; p = rindex(s,'/'); if (!p) p=s; else p++; } else p++; strcpy(t,p); n = findSuffix(t); p = (n== -1)? ".Z" : Suffix[n]; if (t[strlen(t)-strlen(p)]=='.') t[strlen(t)-strlen(p)] = '\0'; strcpy(t,tmp(t,p,0)); } int System(fmt, a,b,c,d,e,f,g) char *fmt,*a,*b,*c,*d,*e,*f,*g; { char t[8192]; sprintf(t,fmt,a,b,c,d,e,f,g); printf("! %s\n",t); return system(t); } void openFile(char *s) { /* open 's' in workspace */ int ok = 0; id p = [NXApp appSpeaker]; [p setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)]; [p openTempFile:s ok:&ok]; if (!ok) err(LS_MSG_COULDNT_OPEN,s); } void previewFile(char *s) { /* open 's' in the default PostScript previewer */ /* This function worked over for 3.1.1 by Howard; it never worked before * but it does now. */ char *a = (char *)0; char *index; char head[1024]; int ok = 0; id p = [NXApp appSpeaker]; /* get handle on the user's favorite Preview application */ if (!a) a = "Preview"; [p setSendPort:NXPortFromName(a, NULL)]; getTmpName(s, head); index = rindex(&head[0], '.'); if (tailmatch(s, ".PS")) strcpy(index+1, "ps"); else strcpy(index+1, "eps"); System("cp %s %s", s, head); [p openFile: head ok:&ok]; if (!ok) err(LS_MSG_COULDNT_OPEN,s); } int confirm(a,b,c,d) char *a,*b,*c,*d; { char t[1024]; extern id NXApp; sprintf(t,a,b,c,d); return NXRunAlertPanel([NXApp appName],t,LS_MSG_YES,LS_MSG_NO,NULL)==1; //TE } int unpackFile(char *s) { int i; char c[2048]; i = findSuffix(s); if (i != -1){ /* we found a suffix and command in the table */ expand(s,i,c); [me system:c]; // System("(%s)&",c); } else if (tailmatch(s,".PS" ) || tailmatch(s,".EPS")) /* catch some PS files */ previewFile(s); else err("Couldn't open '%s'",s); return 1; } int isCompSourceArchive(char *s) { return ((strindex(s,"comp.sources") || strindex(s,"mod.sources") || strindex(s,"net.sources")) && equal(s+strlen(s)-2,".z") && !strindex(s,"index") && !strindex(s,"Index") && !strindex(s,"INDEX") && !strindex(s,"files") && !strindex(s,"Files") && !strindex(s,"FILES")); } void reap(DPSTimedEntry n, double now, char *userData) { int i, np; char x[1024], head[1024], c[8192], *p, q[1024], *r; DPSRemoveTimedEntry(n); np = NP; if (!NP) return; NP = 0; if (confirm("Try to build %s...?",Pending[0])){ strcpy(x,Pending[0]); getTmpName(x,head); sprintf(c,"(mkdir $t; cp "); for (i=0; i<np; i++) strcat(c,Pending[i]), strcat(c," "); sprintf(c+strlen(c)," $t; $p/builder $t; open $t $t/errors)&"); p = c; /* prepend the $p/... paths */ while (p = strindex(p,"$p/")){ sscanf(p,"%s",q); r = path(q+3); substr(p,q,r); } substr(c,"$t",head); System("%s",c); } else { for (i=0;i<np;i++) unpackFile(Pending[i]); } for (i=0;i<np;i++) free(Pending[i]); } void pending(char *s) { /* * One or more files from a comp.sources archive are being selected. * Put them on a queue -- reap() will unpack them specially. */ if (NP == MaxPend) return (void)err("Too many pending files! Try quitting."); Pending[NP++] = save(s); DPSAddTimedEntry(4.0, (DPSTimedEntryProc)reap, 0, 10); } void stot(char *s, char **t, char c) { /* split 's' into a table 't' */ char *p; while (p = index(s,c)){ *p++ = '\0'; *t++ = s; s = p; } *t++ = s; *t = (char *)0; } void trimdir(char *d, char **t) { /* put longest leading directory of t into d */ int i, n; char *p,*q; *d = '\0'; p = rindex(t[0],'/'); if (p){ *p='\0'; strcpy(d,t[0]); strcat(d,"/"); *p='/'; } else return ; if (t[1]){ for (i=0;t[i];i++){ for (p=d,q=t[i]; *p && *q && *p == *q; p++, q++); if (!*p) continue; *p = '\0'; } } n = strlen(d); for (i=0;t[i];i++) t[i] += n; } void pexpand(i,c,d,f,F,t) char *c, *d, *f, *F, *t; int i; /* * like expand, but for packing: * 'i' is the index in the Suffix/Command table. * 'c' is the command to fill; * 'd' is the prefix directory * 'F' is the files without 'd' removed * 'f' is the files with 'd' removed * 't' is the files with 'd' removed */ { char *p, q[1024], *r; strcpy(c,PCommand[i]); p = c; /* prepend the $p/... paths */ while (p = strindex(p,"$p/")){ sscanf(p,"%s",q); r = path(q+3); substr(p,q,r); } substr(c,"$F",F); substr(c,"$f",f); substr(c,"$d",d); substr(c,"$t",t); } void expand_files(char *s, char *p, char *dir) { char *t[1024], x[8192]; int i; strcpy(x,s); stot(x,t,'\t'); if (dir) trimdir(dir,t); *p = '\0'; for (i=0;t[i];i++){ if (i > 0) strcat(p," "); shstrcat(p,t[i]); p += strlen(p); } } char * getText(id t, char *s) { id d = [t docView]; int n = [d textLength]; char *p; *s = '\0'; [d getSubstring:s start:0 length:[d textLength]]; s[n] = '\0'; for (p=s; *p; p++) if (*p == '\n') *p = ' '; return s; } void setText(id t, char *s) { id w = [t window], d = [t docView]; static NXPoint origin = {0.0,0.0}; [w disableFlushWindow]; [d setMonoFont:YES]; [d setText:s]; [d setSel:0:999999]; [d setSelGray:0.0]; [d selectNull]; [d scrollPoint:&origin]; [t display]; [[w reenableFlushWindow] flushWindow]; NXPing(); } int setSuffixes(char *s) { char *p = s + strlen(s); int i, r = -1; loadTable(); clearPackItems(); for (i=0;i<NT;i++) if (equal(Suffix[i],p-strlen(Suffix[i]))){ if (r == -1) r = i; addUnpackItem(Suffix[i]); } if (r >= 0) [[pb2 selectedCell] setTitle:Suffix[r]]; return r; } /*****************************************************************************/ /* Action methods start here */ /*****************************************************************************/ - appWillInit:sender { me = self; return self; } - appDidInit:sender { // char subj[512] = "Opener-"; unsigned int wn; id s = [NXApp appSpeaker]; NXRegisterDefaults("Opener", OpenerDefaults); strcpy(TmpDir, ((char *)NXGetDefaultValue("Opener", "TmpDir"))); [tmpDirTF setStringValue:TmpDir]; [versionTF setStringValue:[self version]]; // This new-user monitoring feature now obsolete (2/95) DJH // strcat(subj, [self version]); // strcat(subj, "-newuser"); // OpenerMonitor(subj); NXConvertWinNumToGlobal([[NXApp appIcon] windowNum], &wn); [s setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)]; [s registerWindow:wn toPort:[[NXApp appListener] listenPort]]; pb2 = packButton2; return self; } - appWillTerminate:sender { unsigned int wn; NXConvertWinNumToGlobal([[NXApp appIcon] windowNum], &wn); [self removeTmpFiles:sender]; [[NXApp appSpeaker] unregisterWindow:wn]; [helpObject free]; return self; } - (BOOL)appAcceptsAnotherFile:sender { return YES; } #define LS_MSG_REMOVE_SCRATCH_FILE \ NXLocalizedString("Remove the scratch files in %s?",NULL,"LS_MSG_REMOVE_SCRATCH_FILE") //TE - removeTmpFiles:sender { if ([self scratchFiles] && confirm(LS_MSG_REMOVE_SCRATCH_FILE, TmpDir)) { //TE if (strcmp(TmpDir,"/tmp")) System("rm -rf /tmp/O_* %s/O_* &", TmpDir); else System("rm -rf /tmp/O_* &"); } return self; } - setTmp:sender { char *s = (char *)[sender stringValueAt:0]; if (!s || !*s || access(s,0)){ if (s && *s) err("Couldn't access '%s'",s); s = (char *)[sender stringValueAt:0]; NXWriteDefault("Opener", "TmpDir", s); strcpy(TmpDir, s); [tmpDirTF setStringValue:s]; } return self; } #define LS_MSG_UNPACK_FILES_IN \ NXLocalizedString("Unpack files in:", NULL, "LS_MSG_UNPACK_FILES_IN") //TE - setDirectory:sender { id p = [SavePanel new]; char *s; [[[p contentView] findViewWithTag:NX_OPTITLEFIELD] setStringValue:LS_MSG_UNPACK_FILES_IN]; //TE if ([p dirPanelRunModal] && (s = (char *)[p directory])){ NXWriteDefault("Opener", "TmpDir", s); strcpy(TmpDir,s); [tmpDirTF setStringValue:s]; } return self; } - (int)appOpenFile:(const char *)filename type:(const char *)aType { if (isCompSourceArchive((char *)filename)) pending((char *)filename); else unpackFile((char *)filename); return 1; } - openRequest:sender { const char *directory, *const *files; static const char *const types[] = { "tar", "TAR", "tar.z", "tar.Z", "TAR.Z", "tar-z", "tar-Z", "TAR-Z", "taz", "TAZ", "tar.gz", "tar.GZ", "TAR.GZ", "tar-gz", "tar-GZ", "TAR-GZ", "tgz", "TGZ", "shar","SHAR","shar.z","shar.Z","SHAR.Z","shar-z","shar-Z","SHAR-Z", "shar.gz", "shar.GZ", "SHAR.GZ", "shar-gz", "shar-GZ", "SHAR-GZ", "PS", "EPS", "PS-Z", "ps-Z", "ps-z", "EPS-Z", "eps-Z", "eps-z", "PS-GZ", "ps-GZ", "ps-gz", "EPS-GZ", "eps-GZ", "eps-gz", "tar.bz2", "tar.BZ2","TAR.BZ2","bz2","BZ2", //TE "uu", "UU", "lha", "Lha", "LHA", "lzh", "Lzh", "LZH", "arc", "Arc", "ARC", "arj", "Arj", "ARJ", "sit", "Sit", "SIT", "cpt", "Cpt", "CPT", "bin", "Bin", "BIN", "hqx", "Hqx", "HQX", "zip", "Zip", "ZIP", "zoo", "Zoo", "ZOO", "mime", "Mime", "MIME", "gz", "Gz", "GZ", "z", "Z", "compressed", "Compressed", "COMPRESSED", "gsm", "Gsm", "GSM", "au", "Au", "AU", NULL}; id p = [[OpenPanel new] allowMultipleFiles:YES]; char name[512]; if ([p runModalForTypes:types]){ files = [p filenames]; // list of multiple files directory = [p directory]; while (files && *files) { strcpy(name, directory ); strcat(name, "/" ); strcat(name, *files ); files++; unpackFile(name); } } return self; } - (BOOL)scratchFiles { char t[1024]; FILE *p; char s[1024]; BOOL b = NO; if (strcmp(TmpDir,"/tmp")) sprintf(t,"ls /tmp/O_* %s/O_*", TmpDir); else sprintf(t,"ls /tmp/O_*"); p = popen(t,"r"); if (p){ if (fgets(s,sizeof s,p) && strncmp(s,"No match",8)) b = YES; pclose(p); } return b; } - (int)iconEntered:(int)windowNum at:(double)x :(double)y iconWindow:(int)iconWindowNum iconX:(double)iconX iconY:(double)iconY iconWidth:(double)iconWidth iconHeight:(double)iconHeight pathList:(char *)pathList { if (!iconPathList || strcmp(iconPathList, pathList)) { free(iconPathList); iconPathList = save(pathList); } return 0; } - processOutput:(char *)s { err("%s",s); return self; } - system:(char *)s { // exec 's' and processOutput pops up a panel with output [Process new:s delegate:self]; return self; } - setPackCommand { char t[1024], f[4096], F[4096], dir[1024], *p, files[8192]; char c[8192], *curSuffix, *curCmd; int i; Again: curSuffix = (char *)[[packButton2 selectedCell] title]; curCmd = (char *)[[packButton selectedCell] title]; strcpy(files,Files); if (strcmp(curCmd,"create")==0){ // curCmd == "unpack" if (Reset) resetPackItems(); Reset = 1; curSuffix = (char *)[[packButton2 selectedCell] title]; i = findPSuffix(curSuffix); if (i == -1){ [packPanel orderOut:self]; err("Unknown archive format: %s",curSuffix); return 0; } expand_files(files,f,dir); expand_files(files,F,0); sscanf(f,"%s",t); stripnl(t); if (p = rindex(t,'/')) strcpy(t,p+1); strcat(t,curSuffix); p = tmp(t,"",0); strcpy(t,p); pexpand(i,c,dir,f,F,t); setText(packCmdText,c); } else { // curCmd = "create" rather than "unpack" if (index(files,'\t')){ char *p; p = index(files,'\t'); *p = '\0'; strcpy(MoreFiles,p+1); stripnl(files); } else { *MoreFiles = '\0'; } expand_files(files,f,0); i = setSuffixes(files); if (i == -1){ extern void NXBeep(); [[packButton selectedCell] setTitle:"create"]; NXBeep(); resetPackItems(); NXPing(); goto Again; } expand(f,i,c); setText(packCmdText,c); } return self; } #define LS_TITLE_MAKE_NEW_ARCHIVE \ NXLocalizedString("Make new archive", NULL, "LS_TITLE_MAKE_NEW_ARCHIVE") //TE #define LS_TITLE_UNPACK_ARCHIVE \ NXLocalizedString("Unpack archive", NULL, "LS_TITLE_UNPACK_ARCHIVE") //TE - setPackOrUnpack:sender { char *s = (char *)[[sender selectedCell] title]; [[packButton selectedCell] setTitle:s]; if (strcmp(s,"create")==0) [packPanel setTitle:LS_TITLE_MAKE_NEW_ARCHIVE]; //TE else [packPanel setTitle:LS_TITLE_UNPACK_ARCHIVE]; //TE NXPing(); resetPackItems(); [self setPackCommand]; return self; } - setUnpackSuffix:sender { char *s = (char *)[[sender selectedCell] title]; [[packButton2 selectedCell] setTitle:s]; NXPing(); resetPackItems(); [self setPackCommand]; return self; } - setPackSuffix:sender { // Change the default pack suffix in the Opener defaults to match the title // on the selected cell. Then use the title to build a pack command. char *s = (char *)[[sender selectedCell] title]; NXWriteDefault("Opener", "ArchiveFormat", s); [[packButton2 selectedCell] setTitle:s]; Reset = 0; // bandaid NXPing(); [self setPackCommand]; return self; } - packFiles:(char *)files { strcpy(Files,files); if (!*MoreFiles){ if (index(Files,'\t') || findSuffix(Files) == -1){ [packPanel setTitle:LS_TITLE_MAKE_NEW_ARCHIVE]; //TE [[packButton selectedCell] setTitle:"create"]; } else { [packPanel setTitle:LS_TITLE_UNPACK_ARCHIVE]; //TE [[packButton selectedCell] setTitle:"unpack"]; } } [packPanel makeKeyAndOrderFront:self]; [[packButton2 selectedCell] setTitle:((char *)NXGetDefaultValue("Opener", "ArchiveFormat"))]; NXPing(); resetPackItems(); [self setPackCommand]; return self; } - cancelPack:sender { [packPanel orderOut:sender]; *MoreFiles = '\0'; return self; } - pack:sender { char c[8192]; getText(packCmdText,c); if (!blank(c)) [self system:c]; [packPanel orderOut:sender]; if (*MoreFiles) [self packFiles:MoreFiles]; return self; } - (int)iconReleasedAt:(double)x :(double)y ok:(int *)flag { [self packFiles:iconPathList]; *flag = YES; return 0; } - help:sender { if (!helpObject) helpObject = [Help new]; [helpObject generalHelp:sender]; return self; } #define LS_MSG_CONFIRM_EDIT_TABLE \ NXLocalizedString("Edit the command table that controls Opener?\n(Unix experts only)", NULL, "LS_MSG_CONFIRM_EDIT_TABLE") //TE - editTable:sender { char s[1024]; strcpy(s,path("open")); if (confirm(LS_MSG_CONFIRM_EDIT_TABLE)) //TE // System("open -a Edit %s",path("Opener.table")); System("%s -a Edit %s", s, path("Opener.table")); //TE return self; } - suggestion:sender { ComposeSuggestion(); return self; } /*****************************************************************************/ /* Access methods start here */ /*****************************************************************************/ - (char *)version { return "Version 3.4b Jun 1998"; //TE } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.