This is BrowserDelegate.m in view mode; [Download] [Up]
#include "BrowserDelegate.h" #include <stdlib.h> #include <string.h> #include <dirent.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> #include "appkit/Matrix.h" #include "appkit/MList.h" #include "appkit/NXBrowser.h" #include "appkit/NXBrowserCell.h" #include "appkit/ScrollView.h" #include "appkit/stdmacros.h" #include <objc/List.h> #include <ctype.h> @implementation BrowserDelegate :Object static void exec(char **argv) { int p[2]; int pid; if (pipe(p) == -1) { perror("error creating pipe"); exit(1); } pid = fork(); if (pid == -1) { perror("bad pid number\n"); exit(1); } if (pid == 0) { close(p[0]); dup2(p[1], 1); close(p[1]); printf("%s %s %s\n", argv[0], argv[1], argv[2]); if (argv[1] == NULL) { execl(argv[0], argv[0], (char *)0); } else { execl(argv[0], argv[0], argv[1], (char *)0); } perror("error in exec call\n"); exit(1); } else { close(p[1]); dup2(p[0], 0); close(p[0]); } } int findexec(const char *filename, char *pathptr) { char *path, *patho, *cur; struct stat buf; patho = getenv("PATH"); path = alloca(strlen(patho)+1); strcpy(path, patho); if (path == 0) return -1; cur = strtok(path, "=:"); while(1) { if (cur == 0) break; strcpy(pathptr, cur); strcat(pathptr, "/"); strcat(pathptr, filename); stat(pathptr, &buf); if (S_ISREG(buf.st_mode)) { uid_t uid, euid; gid_t gid, egid; mode_t mask = S_IXOTH; uid = getuid(); euid = geteuid(); gid = getgid(); egid = getegid(); if (uid == buf.st_uid || euid == buf.st_uid) mask = S_IXUSR; else if (gid == buf.st_gid || egid == buf.st_gid) mask = S_IXGRP; if (buf.st_mode | mask) return 0; } cur = strtok(0, ":"); } return -1; } static BOOL isExec(char *dirpath) { struct stat stbuf; if (stat(dirpath, &stbuf) == -1) { fprintf(stderr, "can't access %s\n", dirpath); } return (stbuf.st_mode & 0111); } static int is_lower( NXBrowserCell **cellOne, NXBrowserCell **cellTwo ) { int i = 0; const char *wordOne, *wordTwo; char one, two; BOOL isLetterOne, isLetterTwo; wordOne = [*cellOne stringValue]; wordTwo = [*cellTwo stringValue]; while ((wordOne[i] != '\0') && (wordTwo[i] != '\0')) { one = tolower(wordOne[i]); isLetterOne = ((one >= 'a') && (one <= 'z')); two = tolower(wordTwo[i]); isLetterTwo = ((two >= 'a') && (two <= 'z')); if ((isLetterOne) && (!isLetterTwo)) return -1; if ((!isLetterOne) && (isLetterTwo)) return +1; if (one < two) return -1; if (one > two) return +1; i++; } if (wordOne[i] == '\0') return +1; return -1; } /* the browser passes an empty matrix for this delegate to fill in */ - (int)browser:sender fillMatrix:matrix inColumn:(int)column { List *list; NXBrowserCell *aCell; NXBrowserCell **listPtr; DIR *dirp; struct dirent *entry; struct stat statbuf; char dir_path[MAXPATHLEN]; char file_path[MAXPATHLEN]; char cell_entry[MAXPATHLEN]; char *p; int numRows = 0; int i = 0;; if (column == 0) { strcpy( dir_path, "/" ); } else { [sender getPath:dir_path toColumn:column-1]; } if ( (dirp = opendir(dir_path) ) == NULL ) { return 0; } strcpy( file_path, dir_path ); if ( column != 0 ) strcat( file_path, "/" ); p = file_path + strlen(file_path); while( (entry = readdir(dirp) ) != NULL ) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; /* skip self and parent */ } [matrix addRow]; aCell = [matrix cellAt:i :0]; strcpy(cell_entry, entry->d_name); *p = '\0'; strcat( p, entry->d_name ); stat( file_path, &statbuf ); if ( (statbuf.st_mode & S_IFMT) == S_IFDIR ) { strcat(cell_entry, "/"); [aCell setStringValue:cell_entry]; [aCell setLeaf:NO]; } else { [aCell setStringValue:cell_entry]; [aCell setLeaf:YES]; } [aCell setLoaded:YES]; i++; } numRows = i; list = [matrix cellList]; listPtr = NX_ADDRESS(list); qsort(listPtr, numRows, sizeof(id), is_lower ); return numRows; } - execute:sender { char filename[MAXPATHLEN]; char *editor; char **argv; int column; column = [sender selectedColumn]; [sender getPath:filename toColumn:column]; if ( isExec(filename) ) { printf("this is a exectutable\n"); argv = alloca(2 * sizeof argv[0]); argv[0] = filename; argv[1] = NULL; } else { argv = alloca(3 * sizeof argv[0]); editor = getenv("EDITOR"); if ( !editor ) return self; argv[0] = malloc(MAXPATHLEN); if (findexec(editor, argv[0])) { fprintf(stderr, "%s not in path\n", editor); return self; } argv[1] = filename; argv[2] = NULL; } exec(argv); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.