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.