/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: ChangeDir.c /main/7 1996/10/30 11:09:35 drk $ */ /************************************<+>************************************* **************************************************************************** * * FILE: ChangeDir.c * * COMPONENT_NAME: Desktop File Manager (dtfile) * * DESCRIPTION: Source file for the change directory dialog. * * FUNCTIONS: ChangeToNewDir * CheckRestrictedDir * Create * Destroy * DropOnChangeView * FreeValues * GetDefaultValues * GetResourceValues * GetValues * GoToNewDir * InstallChange * InstallClose * OkCallback * SetFocus * SetValues * TextChange * TryToChangeDir * WriteResourceValues * * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company * (c) Copyright 1993, 1994, 1995 International Business Machines Corp. * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc. * (c) Copyright 1993, 1994, 1995 Novell, Inc. * **************************************************************************** ************************************<+>*************************************/ #include #include #include #include #ifdef __hpux #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
#include
#include
#include
#include #include #include #include #include /* _XmStringUngenerate */ #include
#include "Encaps.h" #include "SharedProcs.h" #include "FileMgr.h" #include "Desktop.h" #include "Main.h" #include "ChangeDir.h" #include "Help.h" #include "SharedMsgs.h" #define MAX_PATH PATH_MAX static char * CHANGEDIRECTORY = "ChangeDirectory"; static DialogResource resources[] = { { "string_path", XmRXmString, sizeof(XmString), XtOffset(ChangeDirDataPtr, string_path), NULL, _DtXmStringToString }, { "historyList", XmRXmStringTable, sizeof(XmStringTable), XtOffset(ChangeDirDataPtr, history_list), NULL, _DtXmStringTableToString }, { "visibleCount", XmRInt, sizeof(int), XtOffset(ChangeDirDataPtr, visible_count), (XtPointer) 8, _DtIntToString }, { "listCount", XmRInt, sizeof(int), XtOffset(ChangeDirDataPtr, list_count), NULL, _DtIntToString }, }; /******** Static Function Declarations ********/ static void Create( Display *display, Widget parent, Widget *shell, XtPointer *dialog) ; static void InstallChange( ChangeDirRec *change_dir_rec, XtCallbackProc callback, XtPointer client_data) ; static void InstallClose( ChangeDirRec *change_dir_rec, XtCallbackProc callback, XtPointer client_data) ; static void Destroy( ChangeDirRec *change_dir_rec) ; static XtPointer GetValues( ChangeDirRec *change_dir_rec) ; static XtPointer GetDefaultValues( void ) ; static XtPointer GetResourceValues( XrmDatabase data_base, char **name_list) ; static void SetValues( ChangeDirRec *change_dir_rec, ChangeDirData *change_dir_data) ; static void WriteResourceValues( DialogData *values, int fd, char **name_list) ; static void FreeValues( ChangeDirData *change_dir_data) ; static Boolean TryToChangeDir( Boolean isFromDialog, char * incoming_string, FileMgrData * file_mgr_data, FileMgrRec * file_mgr_rec, ChangeDirData * change_dir_data, Widget selection_box, ChangeDirApply * apply_data, XmSelectionBoxCallbackStruct * callback_data, void (*callback)()) ; static void OkCallback( Widget selection_box, ChangeDirApply *apply_data, XmSelectionBoxCallbackStruct *callback_data) ; static int CheckRestrictedDir ( FileMgrRec * file_mgr_rec, FileMgrData * file_mgr_data, char ** value, Boolean relative_name); static void GoToNewDir ( FileMgrData * file_mgr_data, char * dir_name) ; static void SetFocus( ChangeDirRec *change_dir_rec, ChangeDirData *change_dir_data) ; /******** End Static Function Declarations ********/ extern char *getwd(char *); /* * The Dialog Class structure. */ static DialogClass changeDirClassRec = { resources, XtNumber(resources), Create, (DialogInstallChangeProc) InstallChange, (DialogInstallCloseProc) InstallClose, (DialogDestroyProc) Destroy, (DialogGetValuesProc) GetValues, GetDefaultValues, GetResourceValues, (DialogSetValuesProc) SetValues, WriteResourceValues, (DialogFreeValuesProc) FreeValues, (DialogMapWindowProc) _DtGenericMapWindow, (DialogSetFocusProc) SetFocus, }; DialogClass * changeDirClass = (DialogClass *) &changeDirClassRec; /************************************************************************ * * Create * ************************************************************************/ static void Create( Display *display, Widget parent, Widget *shell, XtPointer *dialog ) { ChangeDirRec * change_dir_rec; XmString prompt; Widget w; Arg args[8]; int n; XtTranslations trans_table; Widget change_dir; /* Allocate the change directory dialog instance record. */ change_dir_rec = (ChangeDirRec *) XtMalloc (sizeof (ChangeDirRec)); prompt = XmStringCreateLocalized (((char *)GETMESSAGE(2,14, "Destination Folder:"))); trans_table = XtParseTranslationTable(translations_space); n = 0; XtSetArg (args[n], XmNselectionLabelString, prompt); n++; XtSetArg (args[n], XmNokLabelString, okXmString); n++; XtSetArg (args[n], XmNcancelLabelString, cancelXmString); n++; XtSetArg (args[n], XmNhelpLabelString, helpXmString); n++; XtSetArg (args[n], XmNautoUnmanage, False); n++; XtSetArg (args[n], XmNtextTranslations, trans_table); n++; change_dir = change_dir_rec->change_dir = XmCreateSelectionDialog (parent, "change_directory", args, n); change_dir_rec->shell = XtParent(change_dir); XmStringFree (prompt); /* Add the help callback to each of the important sub-components */ XtAddCallback(change_dir, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_APPLY_BUTTON); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_CANCEL_BUTTON); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_HELP_BUTTON); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); XtAddCallback(w, XmNactivateCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_OK_BUTTON); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_LIST); XtAddCallback(XtParent(w), XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_LIST_LABEL); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_SELECTION_LABEL); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); w = XmSelectionBoxGetChild(change_dir, XmDIALOG_TEXT); XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB, HELP_CHANGEDIR_DIALOG_STR); /* Adjust the margin widths and heights of each of the buttons */ XtSetArg (args[0], XmNmarginWidth, 6); XtSetArg (args[1], XmNmarginHeight, 2); w = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_OK_BUTTON); XtSetValues (w, args, 2); w = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_HELP_BUTTON); XtSetValues (w, args, 2); w = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_CANCEL_BUTTON); XtSetValues (w, args, 2); XtUnmanageChild(XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_APPLY_BUTTON)); /* Adjust the decorations for the dialog shell of the dialog */ XtSetArg(args[0], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE); XtSetArg(args[1], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE); XtSetValues (change_dir_rec->shell, args, 2); XtSetArg(args[0], XmNcancelButton, w); XtSetValues (change_dir_rec->change_dir, args, 1); /* Set the return values for the dialog widget and dialog instance. */ *shell = change_dir_rec->change_dir; *dialog = (XtPointer) change_dir_rec; } /************************************************************************ * * InstallChange * ************************************************************************/ static void InstallChange( ChangeDirRec *change_dir_rec, XtCallbackProc callback, XtPointer client_data ) { Widget selection_box = change_dir_rec->change_dir; ChangeDirApply * apply_data; /* Setup the callback data to be sent to the Ok callback. */ /* This contains the encapsulation callback to invoke upon */ /* the data within the dialog being changed. */ apply_data = (ChangeDirApply *) XtMalloc (sizeof (ChangeDirApply)); apply_data->callback = callback; apply_data->client_data = client_data; apply_data->change_dir_rec = (XtPointer) change_dir_rec; change_dir_rec->apply_data = apply_data; /* Add the callbacks for list item insertion and help. */ XtAddCallback (selection_box, XmNokCallback, (XtCallbackProc) OkCallback, (XtPointer) apply_data); } /************************************************************************ * * InstallClose * ************************************************************************/ static void InstallClose( ChangeDirRec *change_dir_rec, XtCallbackProc callback, XtPointer client_data ) { Widget close_widget; Atom delete_window_atom; close_widget = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_CANCEL_BUTTON); XtAddCallback (close_widget, XmNactivateCallback, callback, client_data); delete_window_atom = XmInternAtom (XtDisplay(change_dir_rec->shell), "WM_DELETE_WINDOW", True); XmRemoveWMProtocols( change_dir_rec->shell, &delete_window_atom, 1 ); XmAddWMProtocolCallback( change_dir_rec->shell, delete_window_atom, callback, (XtPointer)client_data ); } /************************************************************************ * * Destroy * ************************************************************************/ static void Destroy( ChangeDirRec *change_dir_rec ) { XtDestroyWidget (change_dir_rec->change_dir); XtFree ((char *) change_dir_rec->apply_data); XtFree ((char *) change_dir_rec); } /************************************************************************ * * GetValues * ************************************************************************/ static XtPointer GetValues( ChangeDirRec *change_dir_rec ) { ChangeDirData * change_dir_data; Arg args[8]; int n; XmStringTable history_list; XmString string_path; /* Allocate and initialize the change dir dialog data. */ change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData)); change_dir_data->displayed = True; change_dir_data->host_name = NULL; change_dir_data->file_mgr_rec = NULL; n = 0; XtSetArg (args[n], XmNx, &change_dir_data->x); n++; XtSetArg (args[n], XmNy, &change_dir_data->y); n++; XtSetArg (args[n], XmNwidth, &change_dir_data->width); n++; XtSetArg (args[n], XmNheight, &change_dir_data->height); n++; XtSetArg (args[n], XmNlistItemCount, &change_dir_data->list_count); n++; XtSetArg (args[n], XmNlistVisibleItemCount, &change_dir_data->visible_count); n++; XtSetArg (args[n], XmNtextString, &string_path); n++; XtSetArg (args[n], XmNlistItems, &history_list); n++; XtGetValues (change_dir_rec->change_dir, args, n); /* Extract and make local copies of the XmString data. */ change_dir_data->history_list = (XmStringTable) XtMalloc (sizeof(XmStringTable) * (change_dir_data->list_count + 1)); for (n = 0; n < change_dir_data->list_count; n++) change_dir_data->history_list[n] = XmStringCopy (history_list[n]); change_dir_data->history_list[n] = NULL; if(change_dir_data->string_path) XmStringFree (change_dir_data->string_path); change_dir_data->string_path = XmStringCopy (string_path); return ((XtPointer) change_dir_data); } /************************************************************************ * * GetDefaultValues * ************************************************************************/ static XtPointer GetDefaultValues( void ) { ChangeDirData * change_dir_data; /* Allocate and initialize the default change dir dialog data. */ change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData)); change_dir_data->displayed = False; change_dir_data->x = 0; change_dir_data->y = 0; change_dir_data->height = 0; change_dir_data->width = 0; change_dir_data->string_path = NULL; /* This will cause users_home_dir to be displayed in Application Manager go to dialog. if(restrictMode) change_dir_data->string_path = XmStringCreateLocalized(users_home_dir, XmFONTLIST_DEFAULT_TAG); else change_dir_data->string_path = NULL; */ change_dir_data->history_list = NULL; change_dir_data->visible_count = 8; change_dir_data->list_count = 0; change_dir_data->host_name = NULL; change_dir_data->file_mgr_rec = NULL; return ((XtPointer) change_dir_data); } /************************************************************************ * * GetResourceValues * ************************************************************************/ static XtPointer GetResourceValues( XrmDatabase data_base, char **name_list ) { ChangeDirData * change_dir_data; XmStringTable new_table; int i; /* Allocate and get the resources for change dir dialog data. */ change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData)); _DtDialogGetResources (data_base, name_list, CHANGEDIRECTORY, (char *) change_dir_data, resources, changeDirClass->resource_count); change_dir_data->host_name = NULL; /* If the history list is Non-Null, realloc the pointer array */ /* one element larger and NULL out the new last element */ if (change_dir_data->list_count != 0) { new_table = (XmStringTable) XtMalloc (sizeof (XmStringTable) * (change_dir_data->list_count + 1)); for (i = 0; i < change_dir_data->list_count; i++) new_table[i] = change_dir_data->history_list[i]; new_table[change_dir_data->list_count] = NULL; /****************** THIS WILL BE A MEMORY HOLE WHEN MOTIF FIXES THE XMSTRINGTABLE CONVERTER. EITHER REALLOC THE RETURNED TABLE OR COPY AND FREE IT. ******************/ change_dir_data->history_list = new_table; } return ((XtPointer) change_dir_data); } /************************************************************************ * * SetValues * ************************************************************************/ static void SetValues( ChangeDirRec *change_dir_rec, ChangeDirData *change_dir_data ) { Arg args[4]; char *tmp_str, *host_name; XmString host_string; DialogData * dialog_data; FileMgrData * file_mgr_data; dialog_data = _DtGetInstanceData (change_dir_data->file_mgr_rec); file_mgr_data = (FileMgrData *) dialog_data->data; if(change_dir_data->string_path) XmStringFree (change_dir_data->string_path); if( restrictMode && file_mgr_data->toolbox == False ) change_dir_data->string_path = XmStringCreateLocalized( users_home_dir); else if( file_mgr_data->restricted_directory ) change_dir_data->string_path = XmStringCreateLocalized( file_mgr_data->current_directory); else change_dir_data->string_path = NULL; XtSetArg (args[0], XmNlistItemCount, change_dir_data->list_count); XtSetArg (args[1], XmNlistVisibleItemCount, change_dir_data->visible_count); XtSetArg (args[2], XmNtextString, change_dir_data->string_path); XtSetArg (args[3], XmNlistItems, change_dir_data->history_list); XtSetValues (change_dir_rec->change_dir, args, 4); if( change_dir_data->string_path ) { Widget text; text = XmSelectionBoxGetChild(change_dir_rec->change_dir, XmDIALOG_TEXT); XtAddCallback (text, XmNmodifyVerifyCallback, (XtCallbackProc)TextChange, (XtPointer)file_mgr_data ); XtAddCallback (text, XmNmotionVerifyCallback, (XtCallbackProc)TextChange, (XtPointer)file_mgr_data ); XtAddCallback (text, XmNvalueChangedCallback, (XtCallbackProc)TextChange, (XtPointer)file_mgr_data ); } tmp_str = GETMESSAGE(2, 16, "System Name: "); host_name = XtMalloc(strlen(tmp_str) + strlen(change_dir_data->host_name)+1); sprintf(host_name, "%s%s", tmp_str, change_dir_data->host_name); host_string = XmStringCreateLocalized (host_name); XtSetArg (args[0], XmNlabelString, host_string); XtSetValues (XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_LIST_LABEL), args, 1); XtFree(host_name); XmStringFree(host_string); } /************************************************************************ * * WriteResourceValues * ************************************************************************/ static void WriteResourceValues( DialogData *values, int fd, char **name_list ) { ChangeDirData * change_dir_data = (ChangeDirData *) values->data; ChangeDirRec * change_dir_rec; /* If the dialog is currently displayed, update the geometry */ /* fields to their current values. */ if (change_dir_data->displayed == True) { _DtGenericUpdateWindowPosition(values); change_dir_rec = (ChangeDirRec *) _DtGetDialogInstance (values); } _DtDialogPutResources (fd, name_list, CHANGEDIRECTORY, values->data, resources, changeDirClass->resource_count); } /************************************************************************ * * FreeValues * ************************************************************************/ static void FreeValues( ChangeDirData *change_dir_data ) { int i; for (i = 0; i < change_dir_data->list_count; i++) XmStringFree (change_dir_data->history_list[i]); XtFree ((char *) change_dir_data->history_list); XmStringFree (change_dir_data->string_path); XtFree ((char *) change_dir_data->host_name); XtFree ((char *) change_dir_data); } /************************************************************************ ************************************************************************ * * Internal functions used by the ChangeDir dialog * ************************************************************************ ************************************************************************/ /***************************************************************************** TryToChangeDir INPUT: OUTPUT: DESCRIPTION: This function is used both by the ChangeDir dialog, and the FileMgr dialog's text field; it attempts to verify the incoming string, and then change to the indicated directory. NOTE: *****************************************************************************/ static Boolean TryToChangeDir( Boolean isFromDialog, char * incoming_string, FileMgrData * file_mgr_data, FileMgrRec * file_mgr_rec, ChangeDirData * change_dir_data, Widget selection_box, ChangeDirApply * apply_data, XmSelectionBoxCallbackStruct * callback_data, void (*callback)()) { char * new_directory; char * host; char * path; struct stat stat_buf; Widget list; XmString path_string; XmString host_string; Arg args[1]; char * message_buf; char * tmpStr; char * title; char * msg; Boolean rc = True; char *restricted = NULL; new_directory = XtNewString(incoming_string); if ((new_directory) && (strcmp(new_directory, "") != 0)) { _DtPathFromInput(new_directory, file_mgr_data->current_directory, &host, &path); } else { tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE); title = XtNewString(tmpStr); tmpStr = GETMESSAGE(2,18, "Destination Folder name is missing.\nType in a folder name or select a folder from the list."); msg = XtNewString(tmpStr); if(isFromDialog) _DtMessage(selection_box, title, msg, NULL, HelpRequestCB); else _DtMessage(file_mgr_rec->current_directory_text, title, msg, NULL, HelpRequestCB); XtFree(title); XtFree(msg); return False; } /* Don't allow access to the desktop directory */ if (path) { char *ttpath = (char *) GetTTPath(path); char *dtpath = (char *) GetTTPath(desktop_dir); if( ttpath && strcmp(ttpath, dtpath) == 0) { restricted = ttpath; XtFree(path); path = NULL; } } /* Stat the file and see if it is a valid directory. (If the current view is restricted, make sure that the new directory doesn't violate the directory restrictions. If so, refilter the displayed file set to show the files in this directory. */ if ((path) &&(stat(path, &stat_buf) == 0) &&((stat_buf.st_mode & S_IFMT) == S_IFDIR) &&(CheckRestrictedDir(file_mgr_rec, file_mgr_data, &path, False) == 0)) { /* Check for read/xcute permission */ if (CheckAccess(path, R_OK | X_OK)) { tmpStr = GETMESSAGE(9, 6, "Action Error"); title = XtNewString(tmpStr); msg = (char *)XtMalloc(strlen(GETMESSAGE(30, 1, "Cannot read from %s")) + strlen(new_directory) + 1); sprintf(msg, GETMESSAGE(30, 1, "Cannot read from %s"), new_directory); if(isFromDialog) _DtMessage(selection_box, title, msg, NULL, HelpRequestCB); else _DtMessage(file_mgr_rec->current_directory_text, title, msg, NULL, HelpRequestCB); XtFree(title); XtFree(msg); return False; } else { if (selection_box) { /* Adjust the selection box elements to add the text item into the list. */ list = XmSelectionBoxGetChild(selection_box, XmDIALOG_LIST); path_string = XmStringCreateLocalized(path); if (XmListItemExists(list, path_string)) XmListDeselectAllItems(list); else XmListAddItem(list, path_string, 0); XmListSelectItem(list, path_string, False); XmListSetBottomPos(list, 0); XmStringFree(path_string); } /* Clear out the text string */ if (isFromDialog) { if(restrictMode) XtSetArg(args[0], XmNtextString, XmStringCreateLocalized(users_home_dir)); else XtSetArg(args[0], XmNtextString, NULL); XtSetValues(selection_box, args, 1); } else { if(!file_mgr_data || !file_mgr_data->restricted_directory) XmTextFieldSetString(file_mgr_rec->current_directory_text, incoming_string); } /* Update the change directory host name field and the host name indicator widget in the dialog. */ XtFree((char *) change_dir_data->host_name); change_dir_data->host_name = XtNewString(host); if (selection_box) { tmpStr = GETMESSAGE(2, 16, "System Name: "); message_buf = XtMalloc(strlen(tmpStr) + strlen(change_dir_data->host_name) + 1); sprintf(message_buf, "%s%s", tmpStr, change_dir_data->host_name); host_string = XmStringCreateLocalized(message_buf); XtSetArg(args[0], XmNlabelString, host_string); XtSetValues(XmSelectionBoxGetChild(selection_box,XmDIALOG_LIST_LABEL), args, 1); XtFree(message_buf); XmStringFree(host_string); XmUpdateDisplay (selection_box); } /* Call the encapsulation change data callback */ if (isFromDialog) (*callback)(selection_box, apply_data->client_data, path); else (*callback)(file_mgr_data, path); } } else { tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE); title = XtNewString(tmpStr); if(restricted) { tmpStr = GETMESSAGE(2,20,"You cannot switch to folder:\n\n%s\n\nYou are not allowed to view this folder\nbecause it is a restricted folder."); path = restricted; } else tmpStr = GETMESSAGE(2,19,"The following folder name is invalid.\n\n%s"); if(path) { message_buf = XtMalloc(strlen(tmpStr) + strlen(path) + 1); sprintf(message_buf, tmpStr, path); } else { message_buf = XtMalloc(strlen(tmpStr) + strlen(new_directory) + 1); sprintf(message_buf, tmpStr, new_directory); } if (isFromDialog) _DtMessage(selection_box, title, message_buf, NULL, HelpRequestCB); else _DtMessage(file_mgr_rec->current_directory_text, title, message_buf, NULL, HelpRequestCB); XtFree(title); XtFree(message_buf); rc = False; } if (path) XtFree((char *) path); XtFree((char *) host); XtFree((char *) new_directory); return rc; } /************************************************************************ * * OkCallback * This is a callback function called when the Ok button (Apply) * is pressed. It adds the string contained within the call data * into the selection boxes list. * ************************************************************************/ static void OkCallback( Widget selection_box, ChangeDirApply *apply_data, XmSelectionBoxCallbackStruct *callback_data ) { DialogData * dialog_data; ChangeDirData * change_dir_data; FileMgrRec * file_mgr_rec; FileMgrData * file_mgr_data; char *strValue; char *value = NULL; int result; char message_buf[MAX_PATH + 100]; char * tmpStr; char * title; char * msg; /* Get the change dir data record */ dialog_data = _DtGetInstanceData (apply_data->change_dir_rec); change_dir_data = (ChangeDirData *) dialog_data->data; file_mgr_rec = (FileMgrRec *) change_dir_data->file_mgr_rec; dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec); file_mgr_data = (FileMgrData *) dialog_data->data; value = (char *) _XmStringUngenerate((XmString)callback_data->value, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, XmCHARSET_TEXT); if ( value == NULL) { tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE); title = XtNewString(tmpStr); tmpStr = (char *) GETMESSAGE(2, 11, "Cannot get the new folder name."); msg = XtNewString(tmpStr); _DtMessage(selection_box, title, message_buf, NULL, HelpRequestCB); XtFree(title); XtFree(msg); return; } strValue = XtNewString(value); if(file_mgr_data->toolbox && strValue[0] != '/') result = CheckRestrictedDir(file_mgr_rec, file_mgr_data, &strValue, True); else result = CheckRestrictedDir(file_mgr_rec, file_mgr_data, &strValue,False); /* Process the string representing a directory to verify */ /* that it is a valid path. */ if (result == 0) { TryToChangeDir(True, (char *)strValue, file_mgr_data, file_mgr_rec, change_dir_data, selection_box, apply_data, callback_data, apply_data->callback); } XtFree(value); XtFree(strValue); } /************************************************************************ * * CheckRestrictedDir: * Make sure we stay inside a restricted directory * ************************************************************************/ static int CheckRestrictedDir ( FileMgrRec * file_mgr_rec, FileMgrData * file_mgr_data, char ** value, Boolean relative_name) { char *tmpStr, directory[MAXPATHLEN]; int len; char *tmpBuffer, *title, *msg; /* If not in restricte mode, everything is ok. */ if (file_mgr_data->restricted_directory == NULL && !restrictMode) return 0; /* get real file name */ if (relative_name) { tmpStr = (char *)XtMalloc(strlen(*value) + strlen(file_mgr_data->restricted_directory) + 3); strcpy(tmpStr, file_mgr_data->restricted_directory); if(*value[0] != '/') strcat(tmpStr, "/"); strcat(tmpStr, *value); XtFree(*value); *value = tmpStr; } *value = (char *) DtEliminateDots (*value); if( restrictMode && file_mgr_data->toolbox == False ) { if( strcmp( users_home_dir, "/" ) == 0 ) return 0; strcpy( directory, users_home_dir ); } else strcpy( directory, file_mgr_data->restricted_directory ); len = strlen(directory); if( len > 1 && directory[len-1] == '/' ) { directory[len - 1] = 0x0; --len; } /* check if value is inside the restricted subdir */ len = strlen(directory); if (strncmp(*value, directory, len) != 0 || (*value)[len] != '/' && (*value)[len] != '\0') { tmpBuffer = GetSharedMessage(CHANGE_DIR_ERROR_TITLE); title = XtNewString(tmpBuffer); if(restrictMode) tmpBuffer = GETMESSAGE(2,8, "You cannot switch to this folder. You are\nallowed to view only folders beneath your\ncurrent folder. You cannot specify an absolute\npath to the new folder."); else tmpBuffer = GETMESSAGE(2,9, "This view is in restricted mode. You cannot go\nto the specified folder because it is not in the\nrelative path of the restricted folder.\n"); msg = XtNewString(tmpBuffer); _DtMessage(file_mgr_rec->current_directory_text, title, msg, NULL, HelpRequestCB); XtFree(title); XtFree(msg); return -1; } return 0; } /************************************************************************ * * ChangeToNewDir * This is the activate callback for the FileMgr text field provided * for quickly changing the current directory being viewed. * ************************************************************************/ void ChangeToNewDir ( Widget text_field, XtPointer client_data, XmAnyCallbackStruct * callback_data ) { DialogData * dialog_data; ChangeDirData * change_dir_data; ChangeDirRec * change_dir_rec; FileMgrRec * file_mgr_rec; FileMgrData * file_mgr_data; char * value; Widget selection_box; Arg args[1]; char * tmpStr; int rc; /* Get the change dir data record */ file_mgr_rec = (FileMgrRec *) client_data; dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec); file_mgr_data = (FileMgrData *) dialog_data->data; change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data; change_dir_rec =(ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir); if (change_dir_rec) selection_box = change_dir_rec->change_dir; else selection_box = NULL; value = (char *)XmTextFieldGetString(text_field); /* check if user attempts to go outside restricted directory */ rc = CheckRestrictedDir (file_mgr_rec, file_mgr_data, &value, True); /* This code will de-activate the text widget. HCI requests that if the switch is not successful, don't de-activate it so user has a change to go back and correct it without having to pop it up again. XmProcessTraversal(file_mgr_rec->file_window, XmTRAVERSE_CURRENT); XtSetArg (args[0], XmNallowShellResize, False); XtSetValues (file_mgr_rec->shell, args, 1); XtUnmanageChild(file_mgr_rec->current_directory_text); XtSetArg (args[0], XmNallowShellResize, True); XtSetValues (file_mgr_rec->shell, args, 1); file_mgr_data->fast_cd_enabled = False; */ /* Process the string representing a directory to verify */ /* that it is a valid path. */ if (rc == 0) { if( TryToChangeDir(False, value, file_mgr_data, file_mgr_rec, change_dir_data, selection_box, NULL, NULL, GoToNewDir) ) /* de-activate the text widget */ UnpostTextPath( file_mgr_data ); } XtFree(value); } /************************************************************************ * * DropOnChangeView * This is the drop callback for the change-view icon provided * for quickly changing the current directory being viewed. * ************************************************************************/ void DropOnChangeView ( Widget w, XtPointer client_data, XtPointer call_data) { DtDndDropCallbackStruct *fileList = (DtDndDropCallbackStruct *)call_data; FileMgrRec *file_mgr_rec; DialogData * dialog_data; ChangeDirData * change_dir_data; ChangeDirRec * change_dir_rec; FileMgrData * file_mgr_data; Widget selection_box; char *full_path_name; int numFiles; numFiles = fileList->dropData->numItems; /* if multiple selection, ignore all but the last one */ if (numFiles > 0 && fileList->reason == DtCR_DND_DROP_ANIMATE) { file_mgr_rec = (FileMgrRec *) client_data; dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec); file_mgr_data = (FileMgrData *) dialog_data->data; full_path_name = XtNewString(fileList->dropData->data.files[numFiles-1]); if (CheckRestrictedDir(file_mgr_rec, file_mgr_data, &full_path_name, False) == 0) { change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data; change_dir_rec = (ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir); if (change_dir_rec) selection_box = change_dir_rec->change_dir; else selection_box = NULL; TryToChangeDir(False, full_path_name, file_mgr_data, file_mgr_rec, change_dir_data, selection_box, NULL, NULL, GoToNewDir); } XtFree(full_path_name); } fileList->status = DtDND_FAILURE; } static void GoToNewDir( FileMgrData * file_mgr_data, char * dir_name ) { ChangeDirData * change_dir_data; int i; Boolean found; XmString xm_dir_name; /* Clear out any selected portion of the old CWD string */ if (file_mgr_data->cd_select != NULL) { XtFree(file_mgr_data->cd_select); file_mgr_data->cd_select = NULL; } /* Update the internal copy of the dialog history list */ if (file_mgr_data->change_dir) { change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data; xm_dir_name = XmStringCreateLocalized(dir_name); /* Add the directory only if not already in the list */ for (i = 0, found = False; i < change_dir_data->list_count; i++) { if (XmStringCompare(xm_dir_name, change_dir_data->history_list[i])) { found = True; XmStringFree(xm_dir_name); break; } } if (!found) { change_dir_data->list_count++; change_dir_data->history_list = (XmStringTable) XtRealloc((char *)change_dir_data->history_list, sizeof(XmStringTable) * (change_dir_data->list_count + 1)); change_dir_data->history_list[change_dir_data->list_count - 1] = xm_dir_name; change_dir_data->history_list[change_dir_data->list_count] = NULL; } /* Update view to display the new directory */ ShowNewDirectory(file_mgr_data, change_dir_data->host_name, dir_name); } } /* * Class function for forcing the focus to the text field, each time * the Change Dir dialog is posted. */ static void SetFocus( ChangeDirRec *change_dir_rec, ChangeDirData *change_dir_data ) { Widget text; /* Force the focus to the text field */ text = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_TEXT); XmProcessTraversal(text, XmTRAVERSE_CURRENT); } /*************************************************************************** * * TextChange() - callback from editable text widgets when something is * typed in the text widget. Only used when in restricted mode. * Used to make sure the users are not going out of their * "restricted" space. * ****************************************************************************/ void TextChange( Widget text, XtPointer client_data, XmTextVerifyCallbackStruct * callback_data ) { char *homeDir, *homeDirBackup; char *selection; if (callback_data->reason == XmCR_MODIFYING_TEXT_VALUE || callback_data->reason == XmCR_MOVING_INSERT_CURSOR ) { FileMgrData * file_mgr_data; file_mgr_data = (FileMgrData *) client_data; selection = XmTextFieldGetSelection(text); /* get whats in the text widget */ homeDir = homeDirBackup = XmTextFieldGetString(text); if(selection != NULL) { if(callback_data->event == NULL) XmTextFieldClearSelection(text, CurrentTime); else XmTextFieldClearSelection(text, callback_data->event->xkey.time); callback_data->doit = False; } else if(callback_data->reason == XmCR_MODIFYING_TEXT_VALUE) { /* see if the user is trying to back over the 'restricted' * text, in this case users_home_dir */ if( strcmp( homeDir, "" ) != 0 && strcmp( homeDir, file_mgr_data->restricted_directory ) <= 0 ) { if( callback_data->text->length != 0 ) { if( strncmp( file_mgr_data->restricted_directory, callback_data->text->ptr, strlen(file_mgr_data->restricted_directory)) != 0) { callback_data->doit = True; } } else { callback_data->doit = False; } } } else { int maxlength; maxlength = strlen( file_mgr_data->restricted_directory ); if(callback_data->newInsert < maxlength) { if(callback_data->event == NULL) _XmTextFieldSetDestination((Widget)text, (Position)callback_data->currInsert, CurrentTime); else { _XmTextFieldSetDestination((Widget)text, (Position)callback_data->currInsert, callback_data->event->xkey.time); callback_data->doit = False; } } } XtFree(homeDirBackup); XtFree(selection); } } void ChangeDirectoryToParent( FileMgrRec * file_mgr_rec, char *directory) { DialogData * dialog_data; ChangeDirData * change_dir_data; ChangeDirRec * change_dir_rec; FileMgrData * file_mgr_data; Widget selection_box; char * tmpStr; int rc; /* Get the change dir data record */ dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec); file_mgr_data = (FileMgrData *) dialog_data->data; change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data; change_dir_rec =(ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir); if (change_dir_rec) selection_box = change_dir_rec->change_dir; else selection_box = NULL; /* check if user attempts to go outside restricted directory */ rc = CheckRestrictedDir (file_mgr_rec, file_mgr_data, &directory, True); /* Process the string representing a directory to verify */ /* that it is a valid path. */ if (rc == 0) { TryToChangeDir(False, directory, file_mgr_data, file_mgr_rec, change_dir_data, selection_box, NULL, NULL, GoToNewDir); } }