2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: ChangeDir.c /main/7 1996/10/30 11:09:35 drk $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 * COMPONENT_NAME: Desktop File Manager (dtfile)
31 * DESCRIPTION: Source file for the change directory dialog.
33 * FUNCTIONS: ChangeToNewDir
52 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
53 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
54 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
55 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
57 ****************************************************************************
58 ************************************<+>*************************************/
62 #include <sys/types.h>
66 #include <sys/inode.h>
74 #include <Xm/MessageB.h>
75 #include <Xm/SelectioB.h>
77 #include <Xm/VendorSEP.h>
79 #include <Xm/MwmUtil.h>
80 #include <Xm/Protocols.h>
82 #include <X11/ShellP.h>
83 #include <X11/Shell.h>
84 #include <X11/Xatom.h>
86 #include <Dt/Action.h>
87 #include <Dt/Connect.h>
88 #include <Dt/DtNlUtils.h>
89 #include <Dt/SharedProcs.h>
93 #include <Xm/DragIcon.h>
96 #include <Xm/XmPrivate.h> /* _XmStringUngenerate */
100 #include "SharedProcs.h"
104 #include "ChangeDir.h"
106 #include "SharedMsgs.h"
109 #define MAX_PATH PATH_MAX
111 static char * CHANGEDIRECTORY = "ChangeDirectory";
114 static DialogResource resources[] =
116 { "string_path", XmRXmString, sizeof(XmString),
117 XtOffset(ChangeDirDataPtr, string_path), NULL, _DtXmStringToString },
119 { "historyList", XmRXmStringTable, sizeof(XmStringTable),
120 XtOffset(ChangeDirDataPtr, history_list), NULL, _DtXmStringTableToString },
122 { "visibleCount", XmRInt, sizeof(int),
123 XtOffset(ChangeDirDataPtr, visible_count), (XtPointer) 8, _DtIntToString },
125 { "listCount", XmRInt, sizeof(int),
126 XtOffset(ChangeDirDataPtr, list_count), NULL, _DtIntToString },
130 /******** Static Function Declarations ********/
132 static void Create( Display *display,
136 static void InstallChange( ChangeDirRec *change_dir_rec,
137 XtCallbackProc callback,
138 XtPointer client_data) ;
139 static void InstallClose( ChangeDirRec *change_dir_rec,
140 XtCallbackProc callback,
141 XtPointer client_data) ;
142 static void Destroy( ChangeDirRec *change_dir_rec) ;
143 static XtPointer GetValues( ChangeDirRec *change_dir_rec) ;
144 static XtPointer GetDefaultValues( void ) ;
145 static XtPointer GetResourceValues( XrmDatabase data_base,
147 static void SetValues( ChangeDirRec *change_dir_rec,
148 ChangeDirData *change_dir_data) ;
149 static void WriteResourceValues( DialogData *values,
152 static void FreeValues( ChangeDirData *change_dir_data) ;
153 static Boolean TryToChangeDir( Boolean isFromDialog,
154 char * incoming_string,
155 FileMgrData * file_mgr_data,
156 FileMgrRec * file_mgr_rec,
157 ChangeDirData * change_dir_data,
158 Widget selection_box,
159 ChangeDirApply * apply_data,
160 XmSelectionBoxCallbackStruct * callback_data,
161 void (*callback)()) ;
162 static void OkCallback( Widget selection_box,
163 ChangeDirApply *apply_data,
164 XmSelectionBoxCallbackStruct *callback_data) ;
165 static int CheckRestrictedDir ( FileMgrRec * file_mgr_rec,
166 FileMgrData * file_mgr_data,
168 Boolean relative_name);
169 static void GoToNewDir ( FileMgrData * file_mgr_data,
171 static void SetFocus(
172 ChangeDirRec *change_dir_rec,
173 ChangeDirData *change_dir_data) ;
176 /******** End Static Function Declarations ********/
178 extern char *getwd(char *);
181 * The Dialog Class structure.
184 static DialogClass changeDirClassRec =
189 (DialogInstallChangeProc) InstallChange,
190 (DialogInstallCloseProc) InstallClose,
191 (DialogDestroyProc) Destroy,
192 (DialogGetValuesProc) GetValues,
195 (DialogSetValuesProc) SetValues,
197 (DialogFreeValuesProc) FreeValues,
198 (DialogMapWindowProc) _DtGenericMapWindow,
199 (DialogSetFocusProc) SetFocus,
202 DialogClass * changeDirClass = (DialogClass *) &changeDirClassRec;
207 /************************************************************************
211 ************************************************************************/
220 ChangeDirRec * change_dir_rec;
225 XtTranslations trans_table;
229 /* Allocate the change directory dialog instance record. */
231 change_dir_rec = (ChangeDirRec *) XtMalloc (sizeof (ChangeDirRec));
233 prompt = XmStringCreateLocalized (((char *)GETMESSAGE(2,14, "Destination Folder:")));
235 trans_table = XtParseTranslationTable(translations_space);
237 XtSetArg (args[n], XmNselectionLabelString, prompt); n++;
238 XtSetArg (args[n], XmNokLabelString, okXmString); n++;
239 XtSetArg (args[n], XmNcancelLabelString, cancelXmString); n++;
240 XtSetArg (args[n], XmNhelpLabelString, helpXmString); n++;
241 XtSetArg (args[n], XmNautoUnmanage, False); n++;
242 XtSetArg (args[n], XmNtextTranslations, trans_table); n++;
243 change_dir = change_dir_rec->change_dir =
244 XmCreateSelectionDialog (parent, "change_directory", args, n);
245 change_dir_rec->shell = XtParent(change_dir);
247 XmStringFree (prompt);
249 /* Add the help callback to each of the important sub-components */
250 XtAddCallback(change_dir, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
251 HELP_CHANGEDIR_DIALOG_STR);
252 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_APPLY_BUTTON);
253 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
254 HELP_CHANGEDIR_DIALOG_STR);
255 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_CANCEL_BUTTON);
256 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
257 HELP_CHANGEDIR_DIALOG_STR);
258 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_HELP_BUTTON);
259 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
260 HELP_CHANGEDIR_DIALOG_STR);
261 XtAddCallback(w, XmNactivateCallback, (XtCallbackProc)HelpRequestCB,
262 HELP_CHANGEDIR_DIALOG_STR);
263 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_OK_BUTTON);
264 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
265 HELP_CHANGEDIR_DIALOG_STR);
266 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_LIST);
267 XtAddCallback(XtParent(w), XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
268 HELP_CHANGEDIR_DIALOG_STR);
269 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_LIST_LABEL);
270 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
271 HELP_CHANGEDIR_DIALOG_STR);
272 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_SELECTION_LABEL);
273 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
274 HELP_CHANGEDIR_DIALOG_STR);
275 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_TEXT);
276 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
277 HELP_CHANGEDIR_DIALOG_STR);
280 /* Adjust the margin widths and heights of each of the buttons */
282 XtSetArg (args[0], XmNmarginWidth, 6);
283 XtSetArg (args[1], XmNmarginHeight, 2);
285 w = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_OK_BUTTON);
286 XtSetValues (w, args, 2);
288 w = XmSelectionBoxGetChild (change_dir_rec->change_dir,
289 XmDIALOG_HELP_BUTTON);
290 XtSetValues (w, args, 2);
292 w = XmSelectionBoxGetChild (change_dir_rec->change_dir,
293 XmDIALOG_CANCEL_BUTTON);
294 XtSetValues (w, args, 2);
296 XtUnmanageChild(XmSelectionBoxGetChild (change_dir_rec->change_dir,
297 XmDIALOG_APPLY_BUTTON));
300 /* Adjust the decorations for the dialog shell of the dialog */
302 XtSetArg(args[0], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE);
303 XtSetArg(args[1], XmNmwmDecorations,
304 MWM_DECOR_BORDER | MWM_DECOR_TITLE);
305 XtSetValues (change_dir_rec->shell, args, 2);
307 XtSetArg(args[0], XmNcancelButton, w);
308 XtSetValues (change_dir_rec->change_dir, args, 1);
310 /* Set the return values for the dialog widget and dialog instance. */
312 *shell = change_dir_rec->change_dir;
313 *dialog = (XtPointer) change_dir_rec;
320 /************************************************************************
324 ************************************************************************/
328 ChangeDirRec *change_dir_rec,
329 XtCallbackProc callback,
330 XtPointer client_data )
332 Widget selection_box = change_dir_rec->change_dir;
333 ChangeDirApply * apply_data;
335 /* Setup the callback data to be sent to the Ok callback. */
336 /* This contains the encapsulation callback to invoke upon */
337 /* the data within the dialog being changed. */
339 apply_data = (ChangeDirApply *) XtMalloc (sizeof (ChangeDirApply));
340 apply_data->callback = callback;
341 apply_data->client_data = client_data;
342 apply_data->change_dir_rec = (XtPointer) change_dir_rec;
343 change_dir_rec->apply_data = apply_data;
345 /* Add the callbacks for list item insertion and help. */
347 XtAddCallback (selection_box, XmNokCallback, (XtCallbackProc) OkCallback,
348 (XtPointer) apply_data);
354 /************************************************************************
358 ************************************************************************/
362 ChangeDirRec *change_dir_rec,
363 XtCallbackProc callback,
364 XtPointer client_data )
367 Atom delete_window_atom;
370 XmSelectionBoxGetChild (change_dir_rec->change_dir,
371 XmDIALOG_CANCEL_BUTTON);
373 XtAddCallback (close_widget, XmNactivateCallback, callback, client_data);
375 delete_window_atom = XmInternAtom (XtDisplay(change_dir_rec->shell),
376 "WM_DELETE_WINDOW", True);
377 XmRemoveWMProtocols( change_dir_rec->shell, &delete_window_atom, 1 );
378 XmAddWMProtocolCallback( change_dir_rec->shell, delete_window_atom, callback,
379 (XtPointer)client_data );
385 /************************************************************************
389 ************************************************************************/
393 ChangeDirRec *change_dir_rec )
395 XtDestroyWidget (change_dir_rec->change_dir);
396 XtFree ((char *) change_dir_rec->apply_data);
397 XtFree ((char *) change_dir_rec);
403 /************************************************************************
407 ************************************************************************/
411 ChangeDirRec *change_dir_rec )
413 ChangeDirData * change_dir_data;
416 XmStringTable history_list;
417 XmString string_path;
420 /* Allocate and initialize the change dir dialog data. */
422 change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData));
424 change_dir_data->displayed = True;
425 change_dir_data->host_name = NULL;
426 change_dir_data->file_mgr_rec = NULL;
429 XtSetArg (args[n], XmNx, &change_dir_data->x); n++;
430 XtSetArg (args[n], XmNy, &change_dir_data->y); n++;
431 XtSetArg (args[n], XmNwidth, &change_dir_data->width); n++;
432 XtSetArg (args[n], XmNheight, &change_dir_data->height); n++;
433 XtSetArg (args[n], XmNlistItemCount, &change_dir_data->list_count); n++;
434 XtSetArg (args[n], XmNlistVisibleItemCount, &change_dir_data->visible_count); n++;
435 XtSetArg (args[n], XmNtextString, &string_path); n++;
436 XtSetArg (args[n], XmNlistItems, &history_list); n++;
437 XtGetValues (change_dir_rec->change_dir, args, n);
440 /* Extract and make local copies of the XmString data. */
442 change_dir_data->history_list = (XmStringTable)
443 XtMalloc (sizeof(XmStringTable) * (change_dir_data->list_count + 1));
445 for (n = 0; n < change_dir_data->list_count; n++)
446 change_dir_data->history_list[n] = XmStringCopy (history_list[n]);
447 change_dir_data->history_list[n] = NULL;
449 if(change_dir_data->string_path)
450 XmStringFree (change_dir_data->string_path);
451 change_dir_data->string_path = XmStringCopy (string_path);
453 return ((XtPointer) change_dir_data);
459 /************************************************************************
463 ************************************************************************/
466 GetDefaultValues( void )
468 ChangeDirData * change_dir_data;
471 /* Allocate and initialize the default change dir dialog data. */
473 change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData));
475 change_dir_data->displayed = False;
476 change_dir_data->x = 0;
477 change_dir_data->y = 0;
478 change_dir_data->height = 0;
479 change_dir_data->width = 0;
480 change_dir_data->string_path = NULL;
483 This will cause users_home_dir to be displayed in
484 Application Manager go to dialog.
487 change_dir_data->string_path =
488 XmStringCreateLocalized(users_home_dir, XmFONTLIST_DEFAULT_TAG);
490 change_dir_data->string_path = NULL;
492 change_dir_data->history_list = NULL;
493 change_dir_data->visible_count = 8;
494 change_dir_data->list_count = 0;
495 change_dir_data->host_name = NULL;
496 change_dir_data->file_mgr_rec = NULL;
499 return ((XtPointer) change_dir_data);
505 /************************************************************************
509 ************************************************************************/
513 XrmDatabase data_base,
516 ChangeDirData * change_dir_data;
517 XmStringTable new_table;
521 /* Allocate and get the resources for change dir dialog data. */
523 change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData));
525 _DtDialogGetResources (data_base, name_list,
526 CHANGEDIRECTORY, (char *) change_dir_data,
527 resources, changeDirClass->resource_count);
529 change_dir_data->host_name = NULL;
532 /* If the history list is Non-Null, realloc the pointer array */
533 /* one element larger and NULL out the new last element */
535 if (change_dir_data->list_count != 0)
537 new_table = (XmStringTable) XtMalloc (sizeof (XmStringTable) *
538 (change_dir_data->list_count + 1));
540 for (i = 0; i < change_dir_data->list_count; i++)
541 new_table[i] = change_dir_data->history_list[i];
543 new_table[change_dir_data->list_count] = NULL;
546 THIS WILL BE A MEMORY HOLE WHEN MOTIF FIXES THE XMSTRINGTABLE
547 CONVERTER. EITHER REALLOC THE RETURNED TABLE OR COPY AND FREE IT.
549 change_dir_data->history_list = new_table;
552 return ((XtPointer) change_dir_data);
558 /************************************************************************
562 ************************************************************************/
566 ChangeDirRec *change_dir_rec,
567 ChangeDirData *change_dir_data )
570 char *tmp_str, *host_name;
571 XmString host_string;
572 DialogData * dialog_data;
573 FileMgrData * file_mgr_data;
575 dialog_data = _DtGetInstanceData (change_dir_data->file_mgr_rec);
576 file_mgr_data = (FileMgrData *) dialog_data->data;
578 if(change_dir_data->string_path)
579 XmStringFree (change_dir_data->string_path);
582 && file_mgr_data->toolbox == False )
583 change_dir_data->string_path =
584 XmStringCreateLocalized( users_home_dir);
585 else if( file_mgr_data->restricted_directory )
586 change_dir_data->string_path =
587 XmStringCreateLocalized( file_mgr_data->current_directory);
589 change_dir_data->string_path = NULL;
591 XtSetArg (args[0], XmNlistItemCount, change_dir_data->list_count);
592 XtSetArg (args[1], XmNlistVisibleItemCount, change_dir_data->visible_count);
593 XtSetArg (args[2], XmNtextString, change_dir_data->string_path);
594 XtSetArg (args[3], XmNlistItems, change_dir_data->history_list);
596 XtSetValues (change_dir_rec->change_dir, args, 4);
598 if( change_dir_data->string_path )
602 text = XmSelectionBoxGetChild(change_dir_rec->change_dir, XmDIALOG_TEXT);
603 XtAddCallback (text, XmNmodifyVerifyCallback,
604 (XtCallbackProc)TextChange, (XtPointer)file_mgr_data );
605 XtAddCallback (text, XmNmotionVerifyCallback,
606 (XtCallbackProc)TextChange, (XtPointer)file_mgr_data );
607 XtAddCallback (text, XmNvalueChangedCallback,
608 (XtCallbackProc)TextChange, (XtPointer)file_mgr_data );
611 tmp_str = GETMESSAGE(2, 16, "System Name: ");
612 host_name = XtMalloc(strlen(tmp_str) + strlen(change_dir_data->host_name)+1);
613 sprintf(host_name, "%s%s", tmp_str, change_dir_data->host_name);
614 host_string = XmStringCreateLocalized (host_name);
615 XtSetArg (args[0], XmNlabelString, host_string);
616 XtSetValues (XmSelectionBoxGetChild (change_dir_rec->change_dir,
617 XmDIALOG_LIST_LABEL), args, 1);
620 XmStringFree(host_string);
626 /************************************************************************
628 * WriteResourceValues
630 ************************************************************************/
638 ChangeDirData * change_dir_data = (ChangeDirData *) values->data;
639 ChangeDirRec * change_dir_rec;
641 /* If the dialog is currently displayed, update the geometry */
642 /* fields to their current values. */
644 if (change_dir_data->displayed == True)
646 _DtGenericUpdateWindowPosition(values);
647 change_dir_rec = (ChangeDirRec *) _DtGetDialogInstance (values);
650 _DtDialogPutResources (fd, name_list, CHANGEDIRECTORY, values->data,
651 resources, changeDirClass->resource_count);
657 /************************************************************************
661 ************************************************************************/
665 ChangeDirData *change_dir_data )
669 for (i = 0; i < change_dir_data->list_count; i++)
670 XmStringFree (change_dir_data->history_list[i]);
671 XtFree ((char *) change_dir_data->history_list);
673 XmStringFree (change_dir_data->string_path);
674 XtFree ((char *) change_dir_data->host_name);
676 XtFree ((char *) change_dir_data);
680 /************************************************************************
681 ************************************************************************
683 * Internal functions used by the ChangeDir dialog
685 ************************************************************************
686 ************************************************************************/
688 /*****************************************************************************
693 This function is used both by the ChangeDir dialog, and the FileMgr
694 dialog's text field; it attempts to verify the incoming string, and
695 then change to the indicated directory.
697 *****************************************************************************/
700 Boolean isFromDialog,
701 char * incoming_string,
702 FileMgrData * file_mgr_data,
703 FileMgrRec * file_mgr_rec,
704 ChangeDirData * change_dir_data,
705 Widget selection_box,
706 ChangeDirApply * apply_data,
707 XmSelectionBoxCallbackStruct * callback_data,
710 char * new_directory;
713 struct stat stat_buf;
715 XmString path_string;
716 XmString host_string;
723 char *restricted = NULL;
725 new_directory = XtNewString(incoming_string);
727 if ((new_directory) && (strcmp(new_directory, "") != 0))
729 _DtPathFromInput(new_directory, file_mgr_data->current_directory,
734 tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
735 title = XtNewString(tmpStr);
736 tmpStr = GETMESSAGE(2,18, "Destination Folder name is missing.\nType in a folder name or select a folder from the list.");
737 msg = XtNewString(tmpStr);
740 _DtMessage(selection_box, title, msg, NULL, HelpRequestCB);
742 _DtMessage(file_mgr_rec->current_directory_text, title, msg, NULL,
751 /* Don't allow access to the desktop directory */
754 char *ttpath = (char *) GetTTPath(path);
755 char *dtpath = (char *) GetTTPath(desktop_dir);
756 if( ttpath && strcmp(ttpath, dtpath) == 0)
764 /* Stat the file and see if it is a valid directory. (If the current view
765 is restricted, make sure that the new directory doesn't violate the
766 directory restrictions. If so, refilter the displayed file set to show
767 the files in this directory.
770 &&(stat(path, &stat_buf) == 0)
771 &&((stat_buf.st_mode & S_IFMT) == S_IFDIR)
772 &&(CheckRestrictedDir(file_mgr_rec, file_mgr_data, &path, False) == 0))
774 /* Check for read/xcute permission */
775 if (CheckAccess(path, R_OK | X_OK))
777 tmpStr = GETMESSAGE(9, 6, "Action Error");
778 title = XtNewString(tmpStr);
779 msg = (char *)XtMalloc(strlen(GETMESSAGE(30, 1, "Cannot read from %s"))
780 + strlen(new_directory)
782 sprintf(msg, GETMESSAGE(30, 1, "Cannot read from %s"), new_directory);
785 _DtMessage(selection_box, title, msg, NULL, HelpRequestCB);
787 _DtMessage(file_mgr_rec->current_directory_text, title,
788 msg, NULL, HelpRequestCB);
798 /* Adjust the selection box elements to add the text item
801 list = XmSelectionBoxGetChild(selection_box, XmDIALOG_LIST);
803 path_string = XmStringCreateLocalized(path);
805 if (XmListItemExists(list, path_string))
806 XmListDeselectAllItems(list);
808 XmListAddItem(list, path_string, 0);
810 XmListSelectItem(list, path_string, False);
811 XmListSetBottomPos(list, 0);
813 XmStringFree(path_string);
816 /* Clear out the text string */
822 XmStringCreateLocalized(users_home_dir));
824 XtSetArg(args[0], XmNtextString, NULL);
825 XtSetValues(selection_box, args, 1);
829 if(!file_mgr_data || !file_mgr_data->restricted_directory)
830 XmTextFieldSetString(file_mgr_rec->current_directory_text,
836 /* Update the change directory host name field
837 and the host name indicator widget in the dialog.
839 XtFree((char *) change_dir_data->host_name);
840 change_dir_data->host_name = XtNewString(host);
844 tmpStr = GETMESSAGE(2, 16, "System Name: ");
845 message_buf = XtMalloc(strlen(tmpStr) +
846 strlen(change_dir_data->host_name) + 1);
847 sprintf(message_buf, "%s%s", tmpStr, change_dir_data->host_name);
849 XmStringCreateLocalized(message_buf);
850 XtSetArg(args[0], XmNlabelString, host_string);
851 XtSetValues(XmSelectionBoxGetChild(selection_box,XmDIALOG_LIST_LABEL),
854 XmStringFree(host_string);
856 XmUpdateDisplay (selection_box);
859 /* Call the encapsulation change data callback */
861 (*callback)(selection_box, apply_data->client_data, path);
863 (*callback)(file_mgr_data, path);
868 tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
869 title = XtNewString(tmpStr);
872 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.");
876 tmpStr = GETMESSAGE(2,19,"The following folder name is invalid.\n\n%s");
879 message_buf = XtMalloc(strlen(tmpStr) + strlen(path) + 1);
880 sprintf(message_buf, tmpStr, path);
884 message_buf = XtMalloc(strlen(tmpStr) + strlen(new_directory) + 1);
885 sprintf(message_buf, tmpStr, new_directory);
889 _DtMessage(selection_box, title, message_buf, NULL, HelpRequestCB);
891 _DtMessage(file_mgr_rec->current_directory_text, title, message_buf,
892 NULL, HelpRequestCB);
900 XtFree((char *) path);
901 XtFree((char *) host);
902 XtFree((char *) new_directory);
909 /************************************************************************
912 * This is a callback function called when the Ok button (Apply)
913 * is pressed. It adds the string contained within the call data
914 * into the selection boxes list.
916 ************************************************************************/
920 Widget selection_box,
921 ChangeDirApply *apply_data,
922 XmSelectionBoxCallbackStruct *callback_data )
924 DialogData * dialog_data;
925 ChangeDirData * change_dir_data;
926 FileMgrRec * file_mgr_rec;
927 FileMgrData * file_mgr_data;
931 char message_buf[MAX_PATH + 100];
937 /* Get the change dir data record */
939 dialog_data = _DtGetInstanceData (apply_data->change_dir_rec);
940 change_dir_data = (ChangeDirData *) dialog_data->data;
942 file_mgr_rec = (FileMgrRec *) change_dir_data->file_mgr_rec;
943 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
944 file_mgr_data = (FileMgrData *) dialog_data->data;
946 value = (char *) _XmStringUngenerate((XmString)callback_data->value,
947 XmFONTLIST_DEFAULT_TAG,
948 XmCHARSET_TEXT, XmCHARSET_TEXT);
952 tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
953 title = XtNewString(tmpStr);
954 tmpStr = (char *) GETMESSAGE(2, 11, "Cannot get the new folder name.");
955 msg = XtNewString(tmpStr);
957 _DtMessage(selection_box, title, message_buf, NULL, HelpRequestCB);
964 strValue = XtNewString(value);
965 if(file_mgr_data->toolbox && strValue[0] != '/')
966 result = CheckRestrictedDir(file_mgr_rec, file_mgr_data, &strValue, True);
968 result = CheckRestrictedDir(file_mgr_rec, file_mgr_data, &strValue,False);
970 /* Process the string representing a directory to verify */
971 /* that it is a valid path. */
974 TryToChangeDir(True, (char *)strValue, file_mgr_data,
975 file_mgr_rec, change_dir_data, selection_box, apply_data,
976 callback_data, apply_data->callback);
984 /************************************************************************
986 * CheckRestrictedDir:
987 * Make sure we stay inside a restricted directory
989 ************************************************************************/
993 FileMgrRec * file_mgr_rec,
994 FileMgrData * file_mgr_data,
996 Boolean relative_name)
998 char *tmpStr, directory[MAXPATHLEN];
1000 char *tmpBuffer, *title, *msg;
1002 /* If not in restricte mode, everything is ok. */
1003 if (file_mgr_data->restricted_directory == NULL && !restrictMode)
1006 /* get real file name */
1009 tmpStr = (char *)XtMalloc(strlen(*value) +
1010 strlen(file_mgr_data->restricted_directory) + 3);
1011 strcpy(tmpStr, file_mgr_data->restricted_directory);
1012 if(*value[0] != '/')
1013 strcat(tmpStr, "/");
1014 strcat(tmpStr, *value);
1018 *value = (char *) DtEliminateDots (*value);
1021 && file_mgr_data->toolbox == False )
1023 if( strcmp( users_home_dir, "/" ) == 0 )
1025 strcpy( directory, users_home_dir );
1028 strcpy( directory, file_mgr_data->restricted_directory );
1030 len = strlen(directory);
1032 if( len > 1 && directory[len-1] == '/' )
1034 directory[len - 1] = 0x0;
1038 /* check if value is inside the restricted subdir */
1039 len = strlen(directory);
1040 if (strncmp(*value, directory, len) != 0 ||
1041 (*value)[len] != '/' && (*value)[len] != '\0')
1043 tmpBuffer = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
1044 title = XtNewString(tmpBuffer);
1046 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.");
1048 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");
1049 msg = XtNewString(tmpBuffer);
1051 _DtMessage(file_mgr_rec->current_directory_text, title, msg,
1052 NULL, HelpRequestCB);
1063 /************************************************************************
1066 * This is the activate callback for the FileMgr text field provided
1067 * for quickly changing the current directory being viewed.
1069 ************************************************************************/
1074 XtPointer client_data,
1075 XmAnyCallbackStruct * callback_data )
1077 DialogData * dialog_data;
1078 ChangeDirData * change_dir_data;
1079 ChangeDirRec * change_dir_rec;
1080 FileMgrRec * file_mgr_rec;
1081 FileMgrData * file_mgr_data;
1083 Widget selection_box;
1088 /* Get the change dir data record */
1090 file_mgr_rec = (FileMgrRec *) client_data;
1091 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1092 file_mgr_data = (FileMgrData *) dialog_data->data;
1093 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1094 change_dir_rec =(ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir);
1097 selection_box = change_dir_rec->change_dir;
1099 selection_box = NULL;
1101 value = (char *)XmTextFieldGetString(text_field);
1103 /* check if user attempts to go outside restricted directory */
1104 rc = CheckRestrictedDir (file_mgr_rec, file_mgr_data, &value, True);
1107 This code will de-activate the text widget.
1108 HCI requests that if the switch is not successful, don't de-activate it
1109 so user has a change to go back and correct it without having to pop it
1112 XmProcessTraversal(file_mgr_rec->file_window, XmTRAVERSE_CURRENT);
1113 XtSetArg (args[0], XmNallowShellResize, False);
1114 XtSetValues (file_mgr_rec->shell, args, 1);
1115 XtUnmanageChild(file_mgr_rec->current_directory_text);
1116 XtSetArg (args[0], XmNallowShellResize, True);
1117 XtSetValues (file_mgr_rec->shell, args, 1);
1118 file_mgr_data->fast_cd_enabled = False;
1121 /* Process the string representing a directory to verify */
1122 /* that it is a valid path. */
1125 if( TryToChangeDir(False, value, file_mgr_data, file_mgr_rec,
1126 change_dir_data, selection_box, NULL, NULL,
1128 /* de-activate the text widget */
1129 UnpostTextPath( file_mgr_data );
1136 /************************************************************************
1139 * This is the drop callback for the change-view icon provided
1140 * for quickly changing the current directory being viewed.
1142 ************************************************************************/
1147 XtPointer client_data,
1148 XtPointer call_data)
1150 DtDndDropCallbackStruct *fileList = (DtDndDropCallbackStruct *)call_data;
1151 FileMgrRec *file_mgr_rec;
1152 DialogData * dialog_data;
1153 ChangeDirData * change_dir_data;
1154 ChangeDirRec * change_dir_rec;
1155 FileMgrData * file_mgr_data;
1156 Widget selection_box;
1157 char *full_path_name;
1160 numFiles = fileList->dropData->numItems;
1162 /* if multiple selection, ignore all but the last one */
1164 if (numFiles > 0 && fileList->reason == DtCR_DND_DROP_ANIMATE)
1166 file_mgr_rec = (FileMgrRec *) client_data;
1167 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1168 file_mgr_data = (FileMgrData *) dialog_data->data;
1170 full_path_name = XtNewString(fileList->dropData->data.files[numFiles-1]);
1172 if (CheckRestrictedDir(file_mgr_rec, file_mgr_data,
1173 &full_path_name, False) == 0)
1175 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1177 (ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir);
1179 selection_box = change_dir_rec->change_dir;
1181 selection_box = NULL;
1183 TryToChangeDir(False, full_path_name, file_mgr_data, file_mgr_rec,
1184 change_dir_data, selection_box, NULL, NULL,
1187 XtFree(full_path_name);
1190 fileList->status = DtDND_FAILURE;
1196 FileMgrData * file_mgr_data,
1199 ChangeDirData * change_dir_data;
1202 XmString xm_dir_name;
1204 /* Clear out any selected portion of the old CWD string */
1205 if (file_mgr_data->cd_select != NULL)
1207 XtFree(file_mgr_data->cd_select);
1208 file_mgr_data->cd_select = NULL;
1211 /* Update the internal copy of the dialog history list */
1212 if (file_mgr_data->change_dir)
1214 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1215 xm_dir_name = XmStringCreateLocalized(dir_name);
1217 /* Add the directory only if not already in the list */
1218 for (i = 0, found = False; i < change_dir_data->list_count; i++)
1220 if (XmStringCompare(xm_dir_name, change_dir_data->history_list[i]))
1223 XmStringFree(xm_dir_name);
1230 change_dir_data->list_count++;
1231 change_dir_data->history_list = (XmStringTable)
1232 XtRealloc((char *)change_dir_data->history_list,
1233 sizeof(XmStringTable) * (change_dir_data->list_count + 1));
1234 change_dir_data->history_list[change_dir_data->list_count - 1] =
1236 change_dir_data->history_list[change_dir_data->list_count] = NULL;
1239 /* Update view to display the new directory */
1240 ShowNewDirectory(file_mgr_data, change_dir_data->host_name, dir_name);
1246 * Class function for forcing the focus to the text field, each time
1247 * the Change Dir dialog is posted.
1252 ChangeDirRec *change_dir_rec,
1253 ChangeDirData *change_dir_data )
1257 /* Force the focus to the text field */
1258 text = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_TEXT);
1259 XmProcessTraversal(text, XmTRAVERSE_CURRENT);
1263 /***************************************************************************
1265 * TextChange() - callback from editable text widgets when something is
1266 * typed in the text widget. Only used when in restricted mode.
1267 * Used to make sure the users are not going out of their
1268 * "restricted" space.
1270 ****************************************************************************/
1275 XtPointer client_data,
1276 XmTextVerifyCallbackStruct * callback_data )
1278 char *homeDir, *homeDirBackup;
1281 if (callback_data->reason == XmCR_MODIFYING_TEXT_VALUE ||
1282 callback_data->reason == XmCR_MOVING_INSERT_CURSOR )
1284 FileMgrData * file_mgr_data;
1286 file_mgr_data = (FileMgrData *) client_data;
1288 selection = XmTextFieldGetSelection(text);
1290 /* get whats in the text widget */
1291 homeDir = homeDirBackup = XmTextFieldGetString(text);
1293 if(selection != NULL)
1295 if(callback_data->event == NULL)
1296 XmTextFieldClearSelection(text, CurrentTime);
1298 XmTextFieldClearSelection(text, callback_data->event->xkey.time);
1299 callback_data->doit = False;
1301 else if(callback_data->reason == XmCR_MODIFYING_TEXT_VALUE)
1303 /* see if the user is trying to back over the 'restricted'
1304 * text, in this case users_home_dir
1306 if( strcmp( homeDir, "" ) != 0
1307 && strcmp( homeDir, file_mgr_data->restricted_directory ) <= 0 )
1309 if( callback_data->text->length != 0 )
1311 if( strncmp( file_mgr_data->restricted_directory,
1312 callback_data->text->ptr,
1313 strlen(file_mgr_data->restricted_directory)) != 0)
1315 callback_data->doit = True;
1320 callback_data->doit = False;
1328 maxlength = strlen( file_mgr_data->restricted_directory );
1330 if(callback_data->newInsert < maxlength)
1332 if(callback_data->event == NULL)
1333 _XmTextFieldSetDestination((Widget)text,
1334 (Position)callback_data->currInsert, CurrentTime);
1337 _XmTextFieldSetDestination((Widget)text,
1338 (Position)callback_data->currInsert,
1339 callback_data->event->xkey.time);
1340 callback_data->doit = False;
1345 XtFree(homeDirBackup);
1351 ChangeDirectoryToParent(
1352 FileMgrRec * file_mgr_rec,
1355 DialogData * dialog_data;
1356 ChangeDirData * change_dir_data;
1357 ChangeDirRec * change_dir_rec;
1358 FileMgrData * file_mgr_data;
1359 Widget selection_box;
1363 /* Get the change dir data record */
1365 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1366 file_mgr_data = (FileMgrData *) dialog_data->data;
1367 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1368 change_dir_rec =(ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir);
1371 selection_box = change_dir_rec->change_dir;
1373 selection_box = NULL;
1375 /* check if user attempts to go outside restricted directory */
1376 rc = CheckRestrictedDir (file_mgr_rec, file_mgr_data, &directory, True);
1378 /* Process the string representing a directory to verify */
1379 /* that it is a valid path. */
1382 TryToChangeDir(False, directory, file_mgr_data, file_mgr_rec,
1383 change_dir_data, selection_box, NULL, NULL,