home *** CD-ROM | disk | FTP | other *** search
- #if ( !defined(lint) && !defined(Pete_copyright))
- #define Pete_copyright 1
- static char pete_copyright[] = "\
- Copyright 1986 by Peter Shipley All rights reserved\n\
- \n\
- Copy permission is hereby granted provided that this notice is\n\
- retained on all partial or complete copies.\n\
- \n\
- please mail questions and fixes to shipley@widow,berkeley.edu\n";
- #endif
-
-
- #include <stdio.h>
- #include <errno.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/param.h>
- #include <sys/dir.h>
- #include <signal.h>
-
- #include <X11/Xlib.h>
- #include <X11/IntrinsicP.h>
- /*
- #include <X11/Shell.h>
- #include <X11/Form.h>
- */
- #include <X11/cursorfont.h>
- /* #include <X11/Xlibint.h> */
- #include <X11/AsciiText.h>
- #include <X11/StringDefs.h>
- #include <X11/Xos.h>
- #include <X11/Xutil.h>
- #include <X11/Command.h>
- #include <X11/List.h>
- #include <X11/Viewport.h>
- #include <X11/Xmu.h>
-
-
- #include "BrowserP.h"
-
- /* Private Definitions */
-
- static int def_spacing = 10;
-
-
- /* {name, class, type, size, offset, default_type, default_addr}, */
- static XtResource resources[] = {
- {XtNvalue, XtCValue, XtRString, sizeof(String),
- XtOffset(BrowserWidget, browser.path), XtRString, NULL},
- {XtNdefaultDistance, XtCThickness, XtRInt, sizeof(int),
- XtOffset(BrowserWidget, browser.spacing), XtRInt,(caddr_t)&def_spacing},
- {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(caddr_t),
- XtOffset(BrowserWidget, browser.sel_callback), XtRCallback, NULL},
- {XtNopenCallback, XtCCallback, XtRCallback, sizeof(caddr_t),
- XtOffset(BrowserWidget, browser.can_callback), XtRCallback, NULL},
- {XtNfunction, XtCFunction, XtRFunction, sizeof (XtWorkProc),
- XtOffset(BrowserWidget, browser.testProc), XtRFunction, NULL},
- {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
- XtOffset(BrowserWidget, browser.reverse_video), XtRString, "FALSE"}
- };
-
- static Boolean SetValues(), ConstraintSetValues();
- static XtGeometryResult GeometryManager();
- static list_type *createFileList();
-
- extern int alphasort();
-
-
- static void CreateLabelWidget(), /* random Widget creation func. */
- CreateFileListWidget(),
- CreateErrorWidget(),
- CreateCommandButtons(),
-
- CreateCursors(),
-
- followdir(),
- Bdestroy(), /* callback to deallocate shit */
- /* toolkit failures */
-
- UpDateLabel(), /* Update the path label */
- LocalNotify(), /* generic callback */
- #ifdef DEBUG
- showList(), /* DEBUG func. (prints current list) */
- #endif DEBUG
-
- prev_callback(),
- next_callback(),
- path_completion(),
- kill_callback(),
-
- dummy(), /* a do nothing func. */
-
- _openCall(), /* callback for open button */
- _cancelCall(), /* callback for cancel button */
-
- ChangeManaged(),
- Initialize(),
- Resize(),
- Realize(),
- RefigureLocations(),
- ConstraintInitialize(),
-
- showError(),
- clearError(),
-
- SetWorkState(),
-
- deleteList(); /* de-allocate current list */
-
- #ifdef DEBUG
- #define printList(X) (void) fprintf(stderr, \
- "list->count = %d\tmin = '%s'\tmax = '%s'\n", \
- X->count, X->namelist[0], X->namelist[X->count -1]);
- #endif DEBUG
-
-
-
-
- BrowserClassRec browserClassRec = {
- { /* core_class fields */
- /* superclass */ (WidgetClass) &compositeClassRec,
- /* class_name */ "Browser",
- /* widget_size */ sizeof(BrowserRec),
- /* class_initialize */ NULL,
- /* class_part_init */ NULL,
- /* class_inited */ FALSE,
- /* initialize */ Initialize,
- /* initialize_hook */ NULL,
- /* realize */ Realize,
- /* 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 */ Bdestroy,
- /* resize */ Resize,
- /* expose */ XtInheritExpose,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ NULL,
- /* version */ XtVersion,
- /* callback_private */ NULL,
- /* tm_table */ NULL,
- /* query_geometry */ XtInheritQueryGeometry, /* %%% fix this! */
- /* display_accelerator*/ XtInheritDisplayAccelerator,
- /* extension */ NULL
- },
- { /* composite_class fields */
- /* geometry_manager */ GeometryManager,
- /* change_managed */ NULL, /* ChangeManaged, */
- /* insert_child */ XtInheritInsertChild,
- /* delete_child */ XtInheritDeleteChild,
- /* extension */ NULL
- },
- { /* browser_class fields */
- /* empty */ 0
- }
- };
-
- WidgetClass browserWidgetClass = (WidgetClass)&browserClassRec;
-
- /****************************************************************
- *
- * Private Procedures
- *
- ****************************************************************/
-
- static void CreateCursors(br)
- BrowserWidget br;
- {
-
- static XColor b = { 0, 0, 0, 0 }; /* black */
- static XColor f = { 0, 65535, 65535, 65535 }; /* white */
-
- #ifdef nodef
- XColor f, b;
-
- if (XtDisplay(br)->cursor_font == None) {
- XtDisplay(br)->cursor_font = XLoadFont (XtDisplay(br), CURSORFONT);
- if (XtDisplay(br)->cursor_font) {
- XtWarning("failed to open cursor_font");
- return;
- }
- }
-
- if(br->browser.reverse_video) {
- f = foreground;
- b = background;
- } else {
- b = foreground;
- f = background;
- }
-
- br->browser.ArrowCursor = XCreateGlyphCursor(XtDisplay(br),
- XtDisplay(br)->cursor_font, XtDisplay(br)->cursor_font,
- XC_left_ptr, XC_left_ptr +1, &f, &b);
-
- br->browser.CrossCursor = XCreateGlyphCursor(XtDisplay(br),
- XtDisplay(br)->cursor_font, XtDisplay(br)->cursor_font,
- XC_cross, XC_cross +1, &f, &b);
-
- br->browser.ClockCursor = XCreateGlyphCursor(XtDisplay(br),
- XtDisplay(br)->cursor_font, XtDisplay(br)->cursor_font,
- XC_watch, XC_watch +1, &f, &b);
- #endif nodef
-
- /* get the standard Cursors */
- br->browser.ArrowCursor = XCreateFontCursor(XtDisplay(br), XC_left_ptr);
- br->browser.CrossCursor = XCreateFontCursor(XtDisplay(br), XC_cross);
- br->browser.ClockCursor = XCreateFontCursor(XtDisplay(br), XC_watch);
-
- /* recolor cursor is we are displayed in reverse video. */
- if(br->browser.reverse_video) {
- XRecolorCursor(XtDisplay(br), br->browser.CrossCursor, &f, &b);
- XRecolorCursor(XtDisplay(br), br->browser.ClockCursor, &f, &b);
- }
-
- return;
- }
-
- /* ARGSUSED */
- static void Initialize(request, new)
- Widget request, new;
- {
- BrowserWidget br = (BrowserWidget)new;
-
-
- if(br->core.width == 0) br->core.width = 400;
- if(br->core.height == 0) br->core.height = 350;
-
- /* allocate room for path data */
- br->browser.labelpath = XtMalloc(MAXPATHLEN);
- br->browser.basepath = XtMalloc(MAXPATHLEN);
-
- /* labelpath NEEDS to be NULL */
- bzero(br->browser.labelpath, MAXPATHLEN);
-
- /* copy the base into an interal string */
- (void) strcpy(br->browser.basepath, br->browser.path);
-
- CreateCursors(br);
-
- /* get the dirt on the basepath */
- br->browser.list = (list_type *) createFileList(br, br->browser.path);
-
- #ifdef DEBUG
- showList(br->browser.list);
- #endif DEBUG
-
- /* Guess what these do ... */
- CreateLabelWidget(br);
-
- CreateErrorWidget(br);
-
- CreateFileListWidget(br);
-
- CreateCommandButtons(br);
-
- /* set the Keyboard Focus */
- XtSetKeyboardFocus(br, br->browser.b_label);
-
- /* display the current path */
- UpDateLabel(br, TRUE);
-
- return;
- }
-
-
- static void CreateLabelWidget(br)
- BrowserWidget br;
- {
- XtTranslations text_tran;
-
- static String newtextTranslations =
- "Ctrl<Key>W: prev_callback()\n\
- Ctrl<Key>M: next_callback()\n\
- Ctrl<Key>J: next_callback()\n\
- <Key>0xFF0D: next_callback()\n\
- <Key>0xFF0A: next_callback()\n\
- Meta<Key>I: dummy()\n\
- Ctrl<Key>C: kill_callback()\n\
- <Key>0xFF1B: path_completion()\n\
- Ctrl<Key>[: path_completion()\n";
-
- static XtActionsRec newtext_actions[] = {
- {"prev_callback", prev_callback},
- {"next_callback", next_callback},
- {"path_completion", path_completion},
- {"kill_callback", kill_callback},
- {"dummy", dummy}
- };
-
- static Arg label_arg[] = {
- {XtNstring, (XtArgVal) NULL},
- {XtNcursor, (XtArgVal) NULL},
- {XtNlength, (XtArgVal) MAXPATHLEN},
- {XtNtextOptions, (XtArgVal) editable},
- {XtNeditType, (XtArgVal) XttextEdit},
- {XtNjustify, (XtArgVal) XtJustifyLeft},
- {XtNborderWidth, (XtArgVal) 0},
- {XtNresize, (XtArgVal) FALSE}
- };
-
- label_arg[0].value = (XtArgVal) br->browser.labelpath;
- label_arg[1].value = (XtArgVal) br->browser.CrossCursor;
-
- br->browser.b_label = XtCreateManagedWidget("Browser_label",
- asciiStringWidgetClass, br, label_arg, XtNumber(label_arg));
-
- /* install the new actions record */
- XtAddActions(newtext_actions, XtNumber(newtext_actions));
-
- /* creat a Translation Table */
- text_tran = XtParseTranslationTable(newtextTranslations);
-
- /* install the new Translation Table */
- XtOverrideTranslations(br->browser.b_label, text_tran);
-
- return;
- }
-
-
- static void CreateFileListWidget(br)
- BrowserWidget br;
- {
- XtTranslations list_trans;
-
- static Arg view_args[] = {
- {XtNallowVert, (XtArgVal) TRUE},
- {XtNforceBars, (XtArgVal) TRUE},
- {XtNresize, (XtArgVal) FALSE},
- {XtNuseRight, (XtArgVal) TRUE}
- };
-
- static String newTranslations =
- "<Btn1Down>: Set()\n\
- <Btn1Down>(2+): Notify()\n";
-
- static XtCallbackRec list_call[] = {
- {(XtCallbackProc) _openCall, (caddr_t) NULL},
- {(XtCallbackProc) NULL, (caddr_t) NULL}
- };
-
- static Arg list_args[] = {
- {XtNlist, (XtArgVal) NULL},
- {XtNnumberStrings, (XtArgVal) NULL},
- {XtNcallback, (XtArgVal) list_call},
- {XtNverticalList, (XtArgVal) TRUE},
- {XtNforceColumns, (XtArgVal) 1},
- {XtNdefaultColumns, (XtArgVal) 1},
- {XtNcolumnSpacing, (XtArgVal) 1000}
- };
-
-
- list_call[0].closure = (caddr_t) br;
-
- list_args[0].value = (XtArgVal) br->browser.list->list;
- list_args[1].value = (XtArgVal) br->browser.list->count;
-
- /* create a viewport widget so the list widget will have scrollbars */
- br->browser.b_view = XtCreateManagedWidget( "view", viewportWidgetClass,
- br, view_args, XtNumber(view_args));
-
- /* Create the list widget at a child of the viewport widget */
- br->browser.b_list = XtCreateManagedWidget( "list", listWidgetClass,
- br->browser.b_view, list_args, XtNumber(list_args));
-
- /* Parse the replacement TranslationTable and install it */
- list_trans = XtParseTranslationTable(newTranslations);
- XtOverrideTranslations(br->browser.b_list, list_trans);
-
- return;
- }
-
- static void CreateErrorWidget(br)
- BrowserWidget br;
- {
- static Arg error_list[] = {
- {XtNjustify, (XtArgVal) XtJustifyLeft},
- {XtNborderWidth, (XtArgVal) 0},
- {XtNresize, (XtArgVal) FALSE},
- {XtNlabel, (XtArgVal) ">"}
- };
-
- br->browser.b_error = XtCreateManagedWidget("error", labelWidgetClass,
- br, error_list, XtNumber(error_list));
- return;
- }
-
-
- static void CreateCommandButtons(br)
- BrowserWidget br;
- {
- static XtCallbackRec cancel_call[] = {
- {(XtCallbackProc) _cancelCall, (caddr_t) NULL},
- {(XtCallbackProc) NULL, (caddr_t) NULL}
- };
-
- static XtCallbackRec open_call[] = {
- {(XtCallbackProc) _openCall, (caddr_t) NULL},
- {(XtCallbackProc) NULL, (caddr_t) NULL}
- };
-
- static Arg comm_args[] = {
- {XtNcursor, (XtArgVal) NULL},
- {XtNlabel, (XtArgVal) "Open"},
- {XtNcallback, (XtArgVal) open_call},
- {XtNresize, (XtArgVal) FALSE},
- {XtNresizable, (XtArgVal) FALSE},
- {XtNwidth, (XtArgVal) 70}
- };
-
- comm_args[0].value = (XtArgVal) br->browser.ArrowCursor;
-
- /* compleate the callback data arrays */
- open_call[0].closure = cancel_call[0].closure = (caddr_t) br;
-
- /* create the open button */
- br->browser.b_open = XtCreateManagedWidget( "open", commandWidgetClass,
- br, comm_args, XtNumber(comm_args) );
-
- /* reuses the arg array for the Cancel button */
- comm_args[1].value = (XtArgVal) "Cancel";
- comm_args[2].value = (XtArgVal) cancel_call;
-
- /* and now the Cancel command button */
- br->browser.b_cancel = XtCreateManagedWidget( "Cancel", commandWidgetClass,
- br, comm_args, XtNumber(comm_args));
-
- return;
- }
-
-
- static void RefigureLocations(wi)
- BrowserWidget wi;
- {
- BrowserWidget br = (BrowserWidget)wi;
-
- Position x, y, y1;
-
- #ifdef DEBUG
- (void) fputs("RefigureLocations called\n", stderr);
- #endif DEBUG
-
- /* first we do the label bar */
- XtConfigureWidget(br->browser.b_label,
- br->browser.spacing, br->browser.spacing, /* x & y*/
- br->core.width -(br->browser.spacing *2) /* width */
- -(br->browser.b_label->core.border_width *2),
- br->browser.b_label->core.height, /* height */
- br->browser.b_label->core.border_width); /* border */
-
- /* here we calc the Y Position for the selection list & buttons */
- y1 = br->browser.b_label->core.height
- +(br->browser.spacing *2)
- +(br->browser.b_label->core.border_width *2);
-
-
- /* calc the X Position for the buttons */
- x = br->core.width -br->browser.spacing -br->browser.b_cancel->core.width;
-
- /* Position the first button */
- XtMoveWidget(br->browser.b_open, x, y1);
-
- XtMoveWidget(br->browser.b_cancel, x,
- y1 +br->browser.spacing
- +br->browser.b_open->core.height
- +(br->browser.b_open->core.border_width *2));
-
-
- /* here we calc the Y Position error area */
- y = br->core.height -br->browser.spacing -br->browser.b_error->core.height
- -(br->browser.b_error->core.border_width *2);
-
- XtConfigureWidget(br->browser.b_error,
- br->browser.spacing, y, /* x & y */
- br->core.width -(br->browser.spacing *2) /* width */
- -(br->browser.b_error->core.border_width *2),
- br->browser.b_error->core.height, /* height */
- br->browser.b_error->core.border_width); /* border */
-
-
-
- XtConfigureWidget(br->browser.b_view,
- br->browser.spacing, y1, /* x & y */
- x -(br->browser.b_view->core.border_width *2) /* width */
- -(br->browser.spacing *2),
- y -(br->browser.b_view->core.border_width *2) /* height */
- -y1 -br->browser.spacing,
- br->browser.b_view->core.border_width); /* border */
-
- /* done */
- return;
- }
-
-
- static void Realize(wi, value_mask, attributes)
- Widget wi;
- Mask *value_mask;
- XSetWindowAttributes *attributes;
- {
-
- #ifdef DEBUG
- (void) fputs("Realize called\n", stderr);
- #endif DEBUG
-
- XtCreateWindow(wi, (unsigned int) InputOutput,
- (Visual *) CopyFromParent, *value_mask, attributes);
-
- RefigureLocations((BrowserWidget) wi);
-
- XDefineCursor(XtDisplay(wi), XtWindow(wi),
- ((BrowserWidget) wi)->browser.CrossCursor);
-
- return;
- }
-
-
- static void Resize(w)
- Widget w;
- {
-
- #ifdef DEBUG
- (void) fputs("Resize called\n", stderr);
- #endif DEBUG
-
- RefigureLocations((BrowserWidget) w);
-
- return;
- }
-
-
- /* ARGSUSED */
- static XtGeometryResult GeometryManager(w, request, reply)
- Widget w;
- XtWidgetGeometry *request;
- XtWidgetGeometry *reply; /* RETURN */
- {
- #ifdef DEBUG
- (void) fprintf(stderr, "GeometryManager called: %s\n", w->core.name);
- #endif DEBUG
-
- return XtGeometryNo;
- }
-
-
-
- /* ARGSUSED */
- static Boolean SetValues(current, request, new)
- Widget current, request, new;
- {
- BrowserWidget br = (BrowserWidget)new;
- BrowserWidget old = (BrowserWidget)current;
-
- #ifdef DEBUG
- (void) fputs("SetValues called\n", stderr);
- #endif DEBUG
-
- if(br->browser.path != old->browser.path
- || br->browser.path != NULL
- && (old->browser.path != NULL
- && strcmp(br->browser.path, old->browser.path)))
- {
- /* delete the old list */
- deleteList(old->browser.list);
-
- /* copy the new path into a safe area */
- (void) strcpy(br->browser.basepath, br->browser.path);
-
- /* create list of file to select from */
- br->browser.list = createFileList(br, br->browser.path);
-
- /* Update the displayed list */
- XtListChange(br->browser.b_list, br->browser.list->list,
- br->browser.list->count, 0, TRUE);
-
- /* update the displayed label */
- UpDateLabel(br, TRUE);
-
- }
-
- return( FALSE );
- }
-
- /* this is the util. for creating file listings */
- static list_type *createFileList(br, selection)
- BrowserWidget br;
- char *selection;
- {
- register Cardinal i;
- struct stat stat_buf;
- list_type *ret_list;
- extern errno;
-
- errno = 0;
-
- /* open requested directory */
- if (selection == (char *) NULL)
- selection = ".";
-
- /* malloc the return list */
- ret_list = (list_type *) XtMalloc(sizeof (list_type));
-
-
- /* report fuckups */
- if (ret_list == NULL) {
- return (list_type *) NULL;
- }
-
- ret_list->count =
- scandir(selection, &ret_list->namelist, br->browser.testProc,
- alphasort);
-
- /* test the scaning */
- if(ret_list->count == -1) {
- #ifdef DEBUG
- XtWarning("Fucked up in opening dir");
- #endif DEBUG
- XtFree((char *) ret_list);
- return (list_type *) NULL;
- }
-
- ret_list->list = (char **)XtCalloc(ret_list->count +1, sizeof(char *));
- ret_list->mode = (int *) XtCalloc(ret_list->count, sizeof(int));
-
- for(i=0; i < ret_list->count; i++) {
- int len;
- char tbuf[MAXNAMLEN +2];
-
- /* get the length of the file name for later use [and reuse] */
- len = strlen(ret_list->namelist[i]->d_name) + 2;
-
- /* copy file name into a new buffer */
- ret_list->list[i] =
- strcpy( XtMalloc(len), ret_list->namelist[i]->d_name);
-
- /* copy the current directory into a tempory space */
- (void) strcpy(tbuf, selection);
-
- /* add a "/" to the current directory path if it's not there already */
- if (tbuf[strlen(tbuf) -1] != '/')
- (void) strcat(tbuf, "/");
-
- /* tack on the current file name */
- (void) strcat(tbuf, ret_list->list[i]);
-
- /* get the status of our 'file', if we fail ignore the file */
- if ( stat(tbuf, &stat_buf) != 0 ) {
- #ifdef DEBUG
- (void) perror(ret_list->namelist[i]->d_name);
- XtWarning("Fucked up in stating file");
- #endif DEBUG
- showError(br, ret_list->list[i]);
- continue;
- }
-
- ret_list->mode[i] = stat_buf.st_mode;
-
- /* add the '/' to the end of the name to indicate directrices, etc..*/
- switch (ret_list->mode[i] & S_IFMT) {
- case S_IFDIR:
- (void) strcat(ret_list->list[i], "/");
- break;
- case S_IFSOCK:
- (void) strcat(ret_list->list[i], "=");
- break;
- default:
- if ( (stat_buf.st_mode & ~S_IFMT) & 0111)
- (void) strcat(ret_list->list[i], "*");
- break;
- }
- }
-
- /* null out the next slot [it should be null from calloc but..] */
- ret_list->list[i +1] = (char *) NULL;
-
- #ifdef DEBUG
- printList(ret_list);
- #endif DEBUG
-
- /* return with our work */
- return ret_list;
- }
-
-
- /* A clean up utility */
- static void deleteList(dead_list)
- list_type *dead_list;
- {
- register int i;
-
- /* Test to see it we have a list */
- if(dead_list == (list_type *) NULL)
- return;
-
- /* free the strings */
- for(i=0; i < dead_list->count; i++) {
- XtFree( (char *) dead_list->list[i]);
- }
-
- XtFree((char *) dead_list->namelist);
- XtFree((char *) dead_list->list);
- XtFree((char *) dead_list);
-
- return;
- }
-
-
-
- /*ARGUSED*/
- static void _cancelCall(wi, client_data, call_data)
- Widget wi;
- caddr_t client_data;
- caddr_t call_data;
- {
- BrowserWidget br = (BrowserWidget)client_data;
-
- /* Change the Cursors to a clock so the they think we're fuckup */
- SetWorkState(br, TRUE);
-
- /* Clear the error line*/
- clearError(br);
-
- XtCallCallbacks((Widget) br, XtNcancelCallback, (char *) NULL);
-
- /* Tell the user we are done */
- SetWorkState(br, FALSE);
-
- return;
- }
-
-
- /*ARGUSED*/
- static void _openCall(wi, client_data, call_data)
- Widget wi;
- caddr_t client_data;
- caddr_t call_data;
- {
- int i;
- XtListReturnStruct *ret_value;
- BrowserWidget br = (BrowserWidget)client_data;
-
- /* Clear the error line*/
- clearError(br);
-
- /* get the current selected list */
- ret_value = XtListShowCurrent(br->browser.b_list);
- i = ret_value->index;
-
- /* free as soon as we don't need */
- XtFree((char *)ret_value);
-
-
- /* test to see it there is a current seletion */
- if( i != XT_LIST_NONE ) {
-
- /* Change the Cursors to a clock so the they think we're fuckup */
- SetWorkState(br, TRUE);
-
- /* test if we are looking at a directory or not */
- if ( br->browser.list->mode[i] & (S_IFMT & S_IFDIR) )
- followdir(br, br->browser.list->namelist[i]->d_name);
- else
- XtCallCallbacks((Widget) br, XtNopenCallback,
- br->browser.list->namelist[i]->d_name);
-
- /* Tell the user we are done */
- SetWorkState(br, FALSE);
-
- }
-
- return;
- }
-
-
-
-
- static void followdir(br, new_path)
- BrowserWidget br;
- String new_path;
- {
- register u_int i;
- char *c;
- char t_path[MAXPATHLEN];
- list_type *t_list;
-
- /* reset the error index */
- clearError(br);
-
- #ifdef DEBUG
- (void) fputs("followdir\n", stderr);
- #endif DEBUG
-
- /* just in case save the old path and lists */
- (void) strcpy(t_path, br->browser.basepath);
- t_list = br->browser.list;
-
- /* see it we are just backing up one dir, there has to be a better way.. */
- if( strncmp(new_path, "..", 2) == 0 ) {
-
- /* get the last occurance of the char '/' in the string */
- c = rindex(br->browser.basepath, '/');
-
- /* report if it is not possible to back out */
- if(c == (char *)NULL) {
- showError(br, "Burp!: could not track '/'");
- return;
- }
-
- /* check if we index'ed to root's "/" */
- if ( c == br->browser.basepath ) {
- (void) strcpy(br->browser.basepath, "/");
- } else {
- /* Null out the rest of the string */
- while( *c != '\0') *c++ = '\0';
- }
-
- } else {
-
- i = strlen(br->browser.basepath) -1;
-
- if (br->browser.basepath[i] != '/')
- (void) strcat(br->browser.basepath, "/");
-
- (void) strcat(br->browser.basepath, new_path);
-
- i = strlen(br->browser.basepath) -1;
-
- if (br->browser.basepath[i] == '/')
- br->browser.basepath[i] = (char) NULL;
- }
-
- /* create a new list of files useing the new base path */
- br->browser.list = createFileList(br, br->browser.basepath);
-
- /* Test the new list, if error report it and restore old values */
- if (br->browser.list == (list_type *) NULL) {
- showError(br, br->browser.basepath);
- (void) strcpy(br->browser.basepath, t_path);
- br->browser.list = t_list;
- return;
- }
-
- /* free the storage used by the current list */
- deleteList(t_list);
-
- #ifdef DEBUG
- showList(br->browser.list);
- (void) fprintf(stderr, "basepath = `%s`\n", br->browser.basepath);
- #endif DEBUG
-
- /* Update the path label with the new path */
- UpDateLabel(br, TRUE);
-
- /* Update the listing with the new list */
- XtListChange(br->browser.b_list, br->browser.list->list, br->browser.list->count, 0, TRUE);
-
- return;
- }
-
- #ifdef DEBUG
- static void showList(ll)
- list_type *ll;
- {
- register int i;
-
- for (i=0; i < ll->count; i++)
- (void) fprintf(stderr,
- "%d:\tlist->list[i] = `%s`\tnamelist[i]->d_name= `%s`\tmode = %lo\n",
- i, ll->list[i], ll->namelist[i]->d_name, ll->mode[i]);
-
- printList(ll);
-
- return;
- }
- #endif DEBUG
-
- static void UpDateLabel(br, copy)
- BrowserWidget br;
- Boolean copy;
- {
- XtTextPosition len;
-
- /* Unset whatever maybe highlighted */
- XtTextUnsetSelection(br->browser.b_label);
-
- /* copy the real path in the shown path */
- if(copy)
- (void) strcpy(br->browser.labelpath, br->browser.basepath);
-
- /* get the length of the current path */
- len = (XtTextPosition) strlen(br->browser.labelpath);
-
- /* set the last position in the buffer */
- XtTextSetLastPos(br->browser.b_label, len);
-
- /* move the Cursor to the last position in the buffer */
- XtTextSetInsertionPoint(br->browser.b_label, len);
-
- return;
- }
-
- /* this is the callback for our widget when it it is destroyed */
- static void Bdestroy(wi)
- Widget wi;
- {
- BrowserWidget br = (BrowserWidget)wi;
-
- #ifdef DEBUG
- (void) fputs("Bdestroy called\n", stderr);
- #endif DEBUG
-
- deleteList(br->browser.list);
-
- XtFree(br->browser.basepath);
- XtFree(br->browser.labelpath);
-
- XFreeCursor(br->browser.ArrowCursor);
- XFreeCursor(br->browser.CrossCursor);
- XFreeCursor(br->browser.ClockCursor);
-
- return;
- }
-
- static void
- prev_callback(wi)
- Widget wi;
- {
- char *c;
- BrowserWidget br = (BrowserWidget)XtParent(wi);
-
- /* clear the error window */
- clearError(br);
-
- /* get the last occurance of the char '/' in the string */
- c = rindex(br->browser.labelpath, '/');
-
- /* report if it is not possible to back out */
- if(c == (char *)NULL) {
- showError(br, "Burp!: could not track '/'");
- XBell(XtDisplay(br), 0);
- return;
- }
-
- /* check if we index'ed to root's "/" */
- if ( c == br->browser.labelpath ) {
- (void) strcpy(br->browser.labelpath, "/");
- } else {
- /* Null out the rest of the string */
- while( *c != '\0') *c++ = '\0';
- }
-
- /* have the label reflect the change */
- UpDateLabel(br, FALSE);
-
- return;
- }
-
- static void next_callback(wi)
- Widget wi;
- {
- struct stat stat_buf;
- BrowserWidget br = (BrowserWidget)XtParent(wi);
-
- #ifdef DEBUG
- (void) fputs("next_callback called\n", stderr);
- #endif DEBUG
-
- /* turn off input and set the cursors to a clock */
- SetWorkState(br, TRUE);
-
- /* clear the error window */
- clearError(br);
-
- /* get the status of our 'file', if we fail ignore the file */
- if ( stat(br->browser.labelpath, &stat_buf) != 0 ) {
- showError(br, br->browser.labelpath);
- }
-
- if (stat_buf.st_mode & (S_IFMT & S_IFDIR) ) {
- list_type *t_list = br->browser.list;
-
- br->browser.list = createFileList(br, br->browser.labelpath);
-
- /* Test the new list */
- if (br->browser.list == (list_type *) NULL) {
-
- /* (void) strcpy(br->browser.basepath, t_path); */
- br->browser.list = t_list;
- showError(br, br->browser.labelpath);
- SetWorkState(br, FALSE);
- return;
- }
-
- /* Update the listing with the new list */
- XtListChange(br->browser.b_list, br->browser.list->list,
- br->browser.list->count, 0, TRUE);
-
- (void) strcpy(br->browser.basepath, br->browser.labelpath);
-
- /* this should not be needed */
- UpDateLabel(br, FALSE);
-
- } else
- XtCallCallbacks(br, XtNopenCallback, br->browser.labelpath);
-
- SetWorkState(br, FALSE);
-
- return;
- }
-
- static void path_completion(wi)
- Widget wi;
- {
- char *c;
- int len;
- int dir_count;
- u_int i;
- u_int hit=0;
- char selection[MAXPATHLEN];
- char name[MAXNAMLEN];
- struct direct **dir_list;
- Boolean free;
- BrowserWidget br = (BrowserWidget)XtParent(wi);
-
-
- #ifdef DEBUG
- (void) fputs("path_completion called\n", stderr);
- #endif DEBUG
-
- clearError(br);
-
- /* get the last occurance of the char '/' in the string */
- c = rindex(br->browser.labelpath, '/');
-
- /* report if it is not possible to back out */
- if(c == (char *)NULL) {
- c = br->browser.labelpath;
- /*
- showError(br, "Burp!: could not track '/'");
- return;
- */
- }
-
- /* move forward to skip the '/' */
- *c++;
-
- len = strlen(c);
-
- /* we will have trouble it these strings are not nulled */
- bzero(name, MAXNAMLEN);
- bzero(selection, MAXPATHLEN);
-
- (void) strncpy(selection, br->browser.labelpath,
- ((int)c -(int)br->browser.labelpath));
-
- if (strcmp(selection, br->browser.basepath) == 0) {
- dir_count = br->browser.list->count;
- dir_list = br->browser.list->namelist;
- free = FALSE;
- } else {
- dir_count = scandir(selection, &dir_list, br->browser.testProc,
- alphasort);
-
- if ( dir_count == -1) {
- showError(br, selection);
- return;
- }
-
- free = TRUE;
- }
-
- /* Enter Loop only if there is something to do */
- if (len > 0) {
- for(i=0; i < dir_count; i++)
- if ( strncmp(c, dir_list[i]->d_name, len) == 0) {
- /* if this is the first match copy if in full */
- hit++;
- if(hit == 1)
- (void) strcpy(name, dir_list[i]->d_name);
- else {
- register int j=0;
-
- for(; dir_list[i]->d_name[j] == name[j]; j++);
-
- name[j] = '\0';
-
- if(j == len)
- break;
- }
- }
-
-
- /* Ugly Ugly Ugly */
- if(hit == 0) {
-
- XBell(XtDisplay(br), 0);
- showError(br, "No matches found");
-
- } else {
-
- /* if we matched more then once ring bell */
- if(hit > 1) {
- char tbuf[MAXPATHLEN];
-
- (void) strcpy(tbuf, "\"");
- (void) strcat(tbuf, c);
- (void) strcat(tbuf, "\": ambiguous");
-
- XBell(XtDisplay(br), 0);
- showError(br, tbuf);
- }
-
- /* if we matched ANYTHING add the result to the current path*/
- if(hit) {
- (void) strcpy(c, name);
- UpDateLabel(br, FALSE);
- }
- }
-
-
- }
-
- if(free)
- XtFree((char *) dir_list);
-
- return;
- }
-
- static void dummy()
- {
- #ifdef DEBUG
- (void) fputs("dummy called\n", stderr);
- #endif DEBUG
- return;
- }
-
- /* this is call if the user types in a Cont-C */
- static void kill_callback(wi)
- Widget wi;
- {
- BrowserWidget br = (BrowserWidget)XtParent(wi);
-
- XtCallCallbacks(br, XtNcancelCallback, NULL);
-
- return;
- }
-
- static void clearError(br)
- BrowserWidget br;
- {
-
- static Arg update_arg[] = {
- {XtNlabel, (XtArgVal) ">"}
- };
-
- errno = 0;
-
- #ifdef DEBUG
- (void) fputs("clearError called\n", stderr);
- #endif DEBUG
-
- XtSetValues(br->browser.b_error, update_arg, XtNumber(update_arg));
-
- return;
- }
-
-
- /*
- * This func displays the current error in
- * a error window on the browser window
- */
- static void showError(br, string)
- BrowserWidget br;
- char *string;
- {
- char tbuf[MAXPATHLEN +80];
- extern char *sys_errlist[];
- extern int sys_nerr;
- extern int errno;
-
- static Arg update_arg[] = {
- {XtNlabel, (XtArgVal) NULL}
- };
-
- if (string != (char *) NULL)
- (void) strcpy(tbuf, string);
- else
- (void) strcpy(tbuf, "Error");
-
- #ifdef DEBUG
- (void) perror(tbuf);
- #endif DEBUG
-
- if (errno > 0 && errno < sys_nerr) {
- (void) strcat(tbuf, ": ");
- (void) strcat(tbuf, sys_errlist[errno]);
- }
-
- update_arg[0].value = (XtArgVal) tbuf;
-
- XBell(XtDisplay(br), 0);
-
- if(XtIsRealized(br))
- XtSetValues(br->browser.b_error, update_arg, XtNumber(update_arg));
-
- return;
- }
-
- static void SetWorkState(br, state)
- BrowserWidget br;
- Boolean state;
- {
-
- if (state) {
- XDefineCursor(XtDisplay(br), XtWindow(br), br->browser.ClockCursor);
- XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_list),
- br->browser.ClockCursor);
- XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_label),
- br->browser.ClockCursor);
-
-
- XtSetSensitive(br->browser.b_open, FALSE);
- XtSetSensitive(br->browser.b_label, FALSE);
- XtSetSensitive(br->browser.b_cancel, FALSE);
-
- } else {
-
- XDefineCursor(XtDisplay(br), XtWindow(br), br->browser.CrossCursor);
- XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_list),
- br->browser.ArrowCursor);
- XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_label),
- br->browser.CrossCursor);
-
- XtSetSensitive(br->browser.b_open, TRUE);
- XtSetSensitive(br->browser.b_label, TRUE);
- XtSetSensitive(br->browser.b_cancel, TRUE);
- }
-
- return;
- }
-
- /**********************************************************************
- *
- * Public routines
- *
- **********************************************************************/
-
- /* none */
-
-
- /* END OF TEXT */
-