This is Dir.c in view mode; [Download] [Up]
/* * Dir.c - Dir composite widget * */ #if ( !defined(lint) && !defined(SABER)) static char PCN_rcsid[] = "$Header: /ufs/comp/mei/PROJ_PCN/onprofile/IFModel/Xsw/RCS/Dir.c,v 1.1 1992/04/17 18:23:47 mei Exp $"; #endif /****************************************************************************** * * * Copyright (C) The Aerospace Corporation 1991 * * * * This software was developed by The Aerospace Corporation as a * * research endeavor for the United States Air Force * * Space Systems Division. The current version of the Gauge * * computer program is available for release to you for * * educational and research purposes only. It is not * * to be used for commercial purposes. * * * * In addition, the following conditions shall apply. * * * * 1) The computer software and documentation were designed to * * satisfy internal Aerospace requirements only. * * The software is provided ``as is,'' and The Aerospace Corporation * * makes no warranty, expressed or implied, as to it accuracy, * * functioning, or fitness for a particular purpose. * * * * 2) The Aerospace Corporation and its personnel are not * * responsible for providing technical support or general assistance * * with respect to the software. * * * * 3) Neither The Aerospace Corporation nor its personnel shall be * * liable for claims, losses, or damages arising out of or connected * * with the use of this software. * * Your sole and exclusive remedy shall be to request a replacement * * copy of the program. * * * ******************************************************************************/ #include <sys/types.h> /* Steve Tuecke, 11/9/92 -- changed to use dirent instead of direct */ #ifdef next040 #include <sys/dir.h> #else #include <dirent.h> #endif /* #include <sys/dir.h> */ #include <sys/param.h> #include <sys/stat.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <X11/IntrinsicP.h> #include <X11/Xresource.h> #include "Xsw.h" #include <X11/Xaw/Form.h> #include <X11/Xaw/Viewport.h> #include <X11/Xaw/Label.h> #include "MultiList.h" #include "FileObjects.h" #include "DirP.h" #define NENTRIES 20 #define TWIDDLE '~' /* Emacs backup file suffix. */ #define EOS 0 extern int sys_nerr; extern char* sys_errlist[]; /**************************************************************** * * dir Resources * ****************************************************************/ static XtResource resources[] = { #define offset(field) XtOffset(DirWidget, dir.field) { XtNdirectoryChange, XtCDirectoryChange, XtRCallback, sizeof(XtPointer), offset(directory_change), XtRImmediate, (XtPointer)NULL }, { XtNuserDirectory, XtCUserDirectory, XtRCallback, sizeof(XtPointer), offset(user_directory), XtRImmediate, (XtPointer)NULL }, { XtNcurrentDirectory, XtCCurrentDirectory, XtRString, sizeof(String), offset(current_dir), XtRString, NULL}, { XtNextensions, XtCExtensions, XtRSCPairList, sizeof(SCPairList), offset(extensions), XtRString, ""}, { XtNfullPath, XtCFullPath, XtRBoolean, sizeof(Boolean), offset(full_path), XtRString, "False"}, { XtNinterval, XtCInterval, XtRInt, sizeof(int), offset(interval), XtRString, "10"}, { XtNselectType, XtCSelectType, XtRSType, sizeof(SType), offset(select_type), XtRString, "Single"}, { XtNshowDirectories, XtCShowDirectories, XtRBoolean, sizeof(Boolean), offset(show_directories), XtRString, "True"}, { XtNshowDotFiles, XtCShowDotFiles, XtRBoolean, sizeof(Boolean), offset(show_dot_files), XtRString, "False"}, { XtNshowBackupFiles, XtCShowBackupFiles, XtRBoolean, sizeof(Boolean), offset(show_backup_files), XtRString, "False"}, }; /**************************************************************** * * Full class record constant * ****************************************************************/ static void Initialize(); static void Destroy(); static void ClassPartInitialize(); static StringList MakeFileList(); DirClassRec dirClassRec = { { /* core_class fields */ /* superclass */ (WidgetClass) &formClassRec, /* class_name */ "dir", /* widget_size */ sizeof(DirRec), /* class_initialize */ NULL, /* class_part_init */ ClassPartInitialize, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave*/ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ XtInheritResize, /* expose */ NULL, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* dir_geometry */ XtInheritQueryGeometry, /* display_accelerator*/ XtInheritDisplayAccelerator, /* extension */ NULL },{ /* composite_class fields */ /* geometry_manager */ XtInheritGeometryManager, /* change_managed */ XtInheritChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL },{ /* constraint class fields */ /* subresources */ NULL, /* subresource_count */ 0, /* constraint_size */ sizeof(DirConstraintsRec), /* initialize */ NULL, /* destroy */ NULL, /* set_values */ NULL, /* extension */ NULL },{ /* form_class fields */ /* layout */ XtInheritLayout } }; WidgetClass dirWidgetClass = (WidgetClass)&dirClassRec; #define IsFileExt(file,ext) (!strcmp(file+strlen(file)- strlen(ext),ext)) static void BackgroundDirectoryUpdate(w, id) DirWidget w; XtIntervalId *id; { struct stat stat_struct; int ret; ret = stat(w->dir.current_dir, &stat_struct); if(ret != 0 && ! w->dir.pending_error) { w->dir.pending_error = True; XtWarning((ret < sys_nerr) ? sys_errlist[ret] : "Stat failed"); } if (w->dir.mod_time != stat_struct.st_mtime) { XswDirUpdate(w); } w->dir.timer_proc_id = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget) w), (unsigned long)(w->dir.interval*100), BackgroundDirectoryUpdate, w); } static String FullName(dir, name) char *dir; char *name; { static char fullpath[MAXPATHLEN]; if (!strcmp(name, "..")) { char *cPtr; strcpy(fullpath, dir); cPtr = strrchr(fullpath, '/'); if (cPtr == NULL) strcpy(fullpath, "/"); /* hui 4/16 change assignment from NULL */ else *cPtr ='\0'; } else { sprintf(fullpath, "%s/%s", dir, name); } return fullpath; } static Boolean CheckMode(name, mode) char *name; u_short mode; { struct stat statbuf; if (stat(name, &statbuf)) { return False; } if (statbuf.st_mode & mode) return True; else return False; } static Boolean IsReadable(name) char *name; { FILE *file; if ((file = fopen(name, "r")) != NULL) { fclose(file); return True; } else { return False; } } static Boolean IsAccess(name) char *name; { return (IsReadable(name) && !CheckMode(name, (S_IFSOCK & S_IFIFO))); } /* Function: IsDirectory() tests to see if a pathname is a directory. * Arguments: path: Pathname of file to test. * Returns: True or False. * Notes: False is returned if the directory is not accessible. */ static Boolean IsDirectory(path) char *path; { return (CheckMode(path, S_IFDIR)); } /* Function: DoChangeDir() actually changes the directory and displays * the new listing. * Arguments: dir: Pathname of new directory. * Returns: Nothing. * Notes: *NULL for dir means to rebuild the file list for the current directory * (as in an update to the directory or change in filename filter). */ static void DoChangeDir(w, dir) DirWidget w; char * dir; { char *p; Arg args[10]; Cardinal arg_cnt; String newdir; struct stat stat_struct; int ret; UserDirStruct user_dir_struct; if (dir != NULL) { /* dir[strlen(dir)-1] = NULL; */ dir[strlen(dir)-1] = '\0'; newdir = FullName(w->dir.current_dir, dir); XtFree(w->dir.current_dir); w->dir.current_dir = XtNewString(newdir); XtCallCallbacks((Widget) w, XtNdirectoryChange, w->dir.current_dir); } if ( w->dir.user_directory ) { user_dir_struct.dir_name = &(w->dir.current_dir); user_dir_struct.file_list = &(w->dir.file_list); XtCallCallbacks((Widget) w, XtNuserDirectory, &(user_dir_struct) ); } else { ret = stat(w->dir.current_dir, &stat_struct); if(ret != 0 && ! w->dir.pending_error) { w->dir.pending_error = True; XtWarning((ret < sys_nerr) ? sys_errlist[ret] : "Stat failed"); return; } w->dir.file_list = MakeFileList(w); w->dir.mod_time = stat_struct.st_mtime; } if (w->dir.file_list == NULL && ! w->dir.pending_error) { w->dir.pending_error = True; XtWarning("Unable to list directory"); return; } arg_cnt = 0; XtSetArg(args[arg_cnt], XtNlabel, w->dir.current_dir); arg_cnt++; XtSetValues(w->dir.label_w, args, arg_cnt); (void)XswDirGetEntriesAndClear(w); XswMultiListChange(w->dir.list_w, w->dir.file_list, 0, 0, True); XtFree(w->dir.cur_selection); w->dir.cur_selection = XtNewString(""); w->dir.pending_error = False; } /*ARGSUSED*/ static void FileSelected(w, cw, ret_val) Widget w; DirWidget cw; XPointer ret_val; { XswMultiListReturnStruct *ret_struct; char * file_name; ret_struct = XswMultiListShowCurrent(w); if (cw->dir.full_path) { file_name = FullName(cw->dir.current_dir, ret_struct->string); } else { file_name = ret_struct->string; } if ((ret_struct->list_index != XSW_LIST_NONE) && (cw->dir.cur_selection[0] != 0) && !strcmp(cw->dir.cur_selection, file_name)) { if (IsDirectory(FullName(cw->dir.current_dir, ret_struct->string))) { DoChangeDir(cw, ret_struct->string); } else { XswSCPairListCall(cw->dir.extensions, XswGetExtension(cw->dir.extensions, cw->dir.cur_selection), cw, cw->dir.cur_selection); XswMultiListUnhighlight(w, ret_struct->list_index); XtFree(cw->dir.cur_selection); cw->dir.cur_selection = XtNewString(""); } } else { if (cw->dir.select_type != Multi) { XtFree(cw->dir.cur_selection); cw->dir.cur_selection = XtNewString(file_name); } else { if (IsDirectory(FullName(cw->dir.current_dir, ret_struct->string))) { DoChangeDir(cw, ret_struct->string); } } } XtFree((char *) ret_struct); } /* Function: SPComp() compares two string pointers for qsort(). * Arguments: s1, s2: strings to be compared. * Returns: Value of strcmp(). * Notes: */ static int SPComp(s1, s2) char **s1, **s2; { return(strcmp(*s1, *s2)); } static Boolean NoExt(file) String file; { int i; i = 0; while ((file[i] != 0) && (file[i] != '.')) i++; return (file[i] == 0); } static int valid_extension(filename,extensions) char *filename; char *extensions[]; { int i = 0; if (extensions[0] == NULL) return True; while (extensions[i] != NULL) if (XswStrCmp(extensions[i], XtNNO_EXTENSION)) { if (NoExt(filename)) return True; else i++; } else { if (IsFileExt(filename,extensions[i])) return(True); else i++; } return(False); } static StringList MakeFileList(w) DirWidget w; { DIR *dirp; /* Steve Tuecke, 11/9/92 -- changed to use dirent instead of direct */ #ifdef next040 struct direct *dp; #else struct dirent *dp; #endif char **filelist; char **cur_file; char **last_file; int entry_cnt; entry_cnt = NENTRIES; filelist = (char **) XtCalloc(entry_cnt, sizeof (char *)); cur_file = filelist; last_file = filelist + entry_cnt - 1; dirp = opendir(w->dir.current_dir); if (dirp == NULL) { return(NULL); } for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if ( !strcmp(dp->d_name, ".") ) continue; if ( (!w->dir.show_dot_files) && (dp->d_name[0] == '.') && strcmp(dp->d_name, "..")) continue; if (!((w->dir.show_directories) && IsDirectory(FullName(w->dir.current_dir, dp->d_name)))) { if (!valid_extension(dp->d_name,w->dir.legal_extensions)) continue; if ( (!w->dir.show_backup_files) && (dp->d_name[strlen(dp->d_name)-1] == TWIDDLE)) continue; } if (!IsAccess(FullName(w->dir.current_dir,dp->d_name))) continue; if (IsDirectory(FullName(w->dir.current_dir, dp->d_name))) { *cur_file = XtMalloc(sizeof(char)*(strlen(dp->d_name)+3)); sprintf(*cur_file, "%s%s", dp->d_name, "/"); cur_file++; } else { *cur_file++ = XtNewString(dp->d_name); } if (cur_file == last_file) { filelist = (char **) XtRealloc((char *) filelist, 2 * entry_cnt * sizeof (char *)); cur_file = filelist + entry_cnt - 1; entry_cnt = 2 * entry_cnt; last_file = filelist + entry_cnt - 1; } } *cur_file = NULL; qsort(filelist, cur_file - filelist, sizeof (char *), SPComp); return(filelist); } /* ARGSUSED */ Boolean CvtStringToSType(display, args, nargs, fromVal, toVal, converter_data) Display* display; XrmValuePtr args, fromVal, toVal; int *nargs; XtPointer* converter_data; { static int result; if (XswStrCmp((char *)fromVal->addr, "single")) result = Single; else if ((XswStrCmp((char *)fromVal->addr, "multi")) || (XswStrCmp((char *)fromVal->addr, "multiple"))) result = Multi; else XtStringConversionWarning((char *) fromVal->addr, "SType"); DONE(SType, result); } /* ARGSUSED */ static void ClassPartInitialize(class) WidgetClass class; { XtSetTypeConverter(XtRString, XtRSType, CvtStringToSType, NULL, 0, XtCacheAll, NULL); } static void Destroy(w) DirWidget w; { XswFreeStringList(w->dir.return_list); XswFreeStringList(w->dir.file_list); XtRemoveTimeOut(w->dir.timer_proc_id); } /* ARGSUSED */ static void Initialize(request, new) DirWidget request, new; { Widget previous_w, vert_w; Cardinal arg_cnt; Dimension width; String dir; Arg args[20]; int i; new->dir.return_list = NULL; new->dir.file_list = NULL; new->dir.pending_error = False; new->dir.label_w = XtVaCreateManagedWidget("dirLabel", labelWidgetClass, (Widget)new, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNright, XtChainRight, XtNleft, XtChainLeft, NULL); new->dir.viewer_w = XtVaCreateManagedWidget("dirVport", viewportWidgetClass, (Widget)new, XtNallowVert, True, XtNfromVert, new->dir.label_w, XtNtop, XtChainTop, XtNbottom, XtChainBottom, XtNright, XtChainRight, XtNleft, XtChainLeft, NULL); new->dir.legal_extensions = XswSCPairListGetStrings(new->dir.extensions); new->dir.cur_selection = XtNewString(""); new->dir.list_w = XtVaCreateManagedWidget("dirList", multiListWidgetClass, new->dir.viewer_w, XtNsingle, (new->dir.select_type == Single), NULL); XtAddCallback(new->dir.list_w, XtNcallback, FileSelected, new); if ( new->dir.interval ) new->dir.timer_proc_id = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget) new), (unsigned long)(new->dir.interval*100), BackgroundDirectoryUpdate, new); if (new->dir.current_dir == NULL) { new->dir.current_dir = XtMalloc(sizeof(char)*MAXPATHLEN); /* hui 4/16 add cast */ if ((char *)getwd(new->dir.current_dir) == NULL) XtError("Cannot find current directory!"); } XswDirUpdate(new); XtVaGetValues(new->dir.label_w, XtNwidth, &width, NULL); XtVaSetValues(new->dir.viewer_w, XtNwidth, width, NULL); XtCallCallbacks((Widget) new, XtNdirectoryChange, new->dir.current_dir); } StringList XswDirGetEntries(w) DirWidget w; { StringList list; XswMultiListReturnStruct *lptr; int i, num; lptr = XswMultiListShowCurrent(w->dir.list_w); num = 0; while (lptr[num].list_index != XSW_LIST_NONE) num++; XswFreeStringList(w->dir.return_list); w->dir.return_list = (StringList)XtMalloc(sizeof(String)*(num+1)); for(i=0; i < num; i++) { w->dir.return_list[i] = XtNewString(lptr[i].string); } w->dir.return_list[i] = NULL; return w->dir.return_list; } StringList XswDirGetEntriesAndClear(w) DirWidget w; { StringList list; XswMultiListReturnStruct *lptr; int i, num; lptr = XswMultiListShowCurrent(w->dir.list_w); w->dir.cur_selection[0] = 0; num = 0; while (lptr[num].list_index != XSW_LIST_NONE) { XswMultiListUnhighlight(w->dir.list_w, lptr[num].list_index); num++; } XswFreeStringList(w->dir.return_list); w->dir.return_list = (StringList)XtMalloc(sizeof(String)*(num+1)); for(i=0; i < num; i++) { w->dir.return_list[i] = XtNewString(lptr[i].string); } w->dir.return_list[i] = NULL; XtFree((char *) lptr); return w->dir.return_list; } void XswDirUpdate(w) DirWidget w; { DoChangeDir(w, NULL); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.