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: SharedProcs.c /main/7 1996/10/03 14:01:42 drk $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 * COMPONENT_NAME: Desktop File Manager (dtfile)
31 * Description: Contains the set of functions which are of general
32 * use to all DT clients.
34 * FUNCTIONS: BuildBufferFileName
37 * RetrieveAndUseNameTemplateInfo
40 * _DtBuildActionArgsWithDroppedBuffers
41 * _DtBuildActionArgsWithDroppedFiles
42 * _DtBuildActionArgsWithSelectedFiles
43 * _DtBuildActionArgsWithDTSelectedFiles
46 * _DtChangeTildeToHome
47 * _DtCheckAndFreePixmapData
48 * _DtCheckForDataTypeProperty
49 * _DtCompileActionVector
50 * _DtCopyDroppedFileInfo
52 * _DtDestroySubdialogArray
53 * _DtDuplicateDialogNameList
56 * _DtFreeDroppedBufferInfo
57 * _DtFreeDroppedFileInfo
60 * _DtGenericUpdateWindowPosition
61 * _DtGetSelectedFilePath
63 * _DtIsBufferExecutable
64 * _DtLoadSubdialogArray
68 * _DtResolveAppManPath
69 * _DtRetrieveDefaultAction
70 * _DtRetrievePixmapData
71 * _DtSaveSubdialogArray
72 * _DtSetDroppedBufferInfo
73 * _DtSetDroppedFileInfo
74 * _DtSpacesInFileNames
75 * _DtStringsAreEquivalent
77 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
78 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
79 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
80 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
82 ****************************************************************************
83 ************************************<+>*************************************/
85 #include <sys/types.h>
97 #include <Xm/VendorSEP.h>
98 #include <Xm/MessageB.h>
99 #include <Xm/RowColumn.h>
100 #include <Xm/MwmUtil.h>
101 #include <Xm/Protocols.h>
102 #include <X11/ShellP.h>
103 #include <X11/Shell.h>
104 #include <X11/Xatom.h>
105 /* Copied from Xm/BaseClassI.h */
106 extern XmWidgetExtData _XmGetWidgetExtData(
108 #if NeedWidePrototypes
109 unsigned int extType) ;
111 unsigned char extType) ;
112 #endif /* NeedWidePrototypes */
115 #include <Dt/Connect.h>
116 #include <Dt/DtNlUtils.h>
119 #include <Dt/IconP.h>
120 #include <Dt/IconFile.h>
121 #include <Dt/Action.h>
131 #include "SharedProcs.h"
135 #define RW_ALL S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
138 /* Global controlling whether auto-positioning is enabled */
139 Boolean disableDialogAutoPlacement = False;
142 /******** Static Function Declarations ********/
144 static void SetBufferFileNames (
146 DtDndBuffer *buffers,
147 int num_of_buffers) ;
148 static char * BuildBufferFileName (
153 static char * RetrieveAndUseNameTemplateInfo(
156 char *template_input) ;
157 static void RenameEntry(
159 unsigned int addIndex) ;
160 static void RenameCollisions(
164 /******** End Static Function Declarations ********/
167 /************************************************************************
170 * Returns the parent directory of its argument.
171 * Does this by looking for the last "/" in the name, and
174 ************************************************************************/
178 register char *name )
182 static char pnam[MAXPATHLEN];
183 static char dot[] = ".";
186 q = strrchr(pnam, '/');
190 else if ((q == pnam) &&
192 (mblen(q, MB_CUR_MAX) == 1) &&
201 return(pnam[0] ? pnam : dot);
206 * Given a filename, follow it to the end of its link. Returns NULL if
207 * a recursive symbolic link is found.
209 * Note, the path returned is a static buffer, and should not be freed by
210 * the calling function.
217 char link_path[MAXPATHLEN];
218 static char file[MAXPATHLEN];
226 /* Used to check for symbolic link loops */
229 history = (char **)XtMalloc(sizeof(char *) * history_size);
233 while ((link_len = readlink(file, link_path, MAXPATHLEN)) > 0)
235 link_path[link_len] = '\0';
237 /* Force the link to be an absolute path, if necessary */
238 if (link_path[0] != '/')
240 /* Relative paths are relative to the current directory */
241 end = strrchr(file, '/') + 1;
243 strcat(file, link_path);
246 strcpy(file, link_path);
248 /* Check for a recursive loop; abort if found */
249 for (i = 0; i < history_count; i++)
251 if (strcmp(file, history[i]) == 0)
253 for (i = 0; i < history_count; i++)
255 XtFree((char *)history);
261 /* Add to the history list */
262 if (history_count >= history_size)
265 history = (char **)XtRealloc((char *)history,
266 sizeof(char *) * history_size);
268 history[history_count++] = XtNewString(file);
271 /* Free up the history list */
272 for (i = 0; i < history_count; i++)
274 XtFree((char *)history);
281 /************************************************************************
283 * _DtStringsAreEquivalent
284 * Compare two strings and return true if equal.
285 * The comparison is on lower cased strings. It is the callers
286 * responsibility to ensure that test_str is already lower cased.
288 ************************************************************************/
291 _DtStringsAreEquivalent(
292 register char *in_str,
293 register char *test_str )
308 /* Convert each character from multibyte to wide format */
309 c1size = mbtowc(&c1, in_str, MB_CUR_MAX);
310 c2size = mbtowc(&c2, test_str, MB_CUR_MAX);
312 /* No match, if the two characters have different byte counts */
313 if (c1size != c2size)
316 /* Do case conversion only for single byte characters */
319 if (isupper((int) c1))
320 c1 = tolower((int) c1);
323 /* See if the two wide characters match */
327 /* Are we at the end of the string? */
344 if (isupper (i)) i = tolower (i);
345 if (i != j) return (False);
346 if (i == 0) return (True);
357 _DtDuplicateDialogNameList (
366 /* Get a copy of the name list to be used to build new name lists. */
368 while (nameList[*nameCount] != NULL)
370 newNameList[*nameCount] = nameList[*nameCount];
374 /* NULL out any remaining array entries */
375 for (i = (*nameCount); i < newNameListSize; i++)
376 newNameList[i] = NULL;
381 _DtLoadSubdialogArray (
384 DialogData *** dialogArray,
387 XrmDatabase dataBase,
394 /* Load sub-dialogs */
395 nameList[nameCount] = number;
396 nameList[nameCount + 1] = NULL;
398 /* Get text annotation dialogs */
399 *dialogArray = (DialogData **) XtMalloc(sizeof(DialogData *) * dialogCount);
401 for (i = 0; i < dialogCount; i++)
403 sprintf(number, "%d", firstId);
404 (*dialogArray)[i] = _DtGetResourceDialogData(dialogId, dataBase, nameList);
412 _DtSaveSubdialogArray (
415 DialogData ** dialogArray,
424 nameList[nameCount] = number;
425 nameList[nameCount + 1] = NULL;
427 for (i = 0; i < dialogCount; i++)
429 sprintf(number, "%d", firstId);
430 _DtWriteDialogData(dialogArray[i], fd, nameList);
437 _DtDestroySubdialogArray (
438 DialogData ** dialogArray,
444 for (i = 0; i < dialogCount; i++)
446 if (_DtIsDialogShowing(dialogArray[i]))
447 _DtHideDialog(dialogArray[i], False);
449 _DtFreeDialogData(dialogArray[i]);
451 XtFree((char *)dialogArray);
456 _DtDestroySubdialog (
457 DialogData * dialogData )
462 if (_DtIsDialogShowing(dialogData))
463 _DtHideDialog(dialogData, False);
464 _DtFreeDialogData(dialogData);
470 _DtHideOneSubdialog (
471 DialogData * dialogData,
472 DialogData *** dialogArray,
473 int * dialogCountPtr )
478 for (i = 0; i < *dialogCountPtr; i++)
480 if (dialogData == (*dialogArray)[i])
482 for (j = i; j < (*dialogCountPtr) - 1; j++)
483 (*dialogArray)[j] = (*dialogArray)[j + 1];
488 /* Free or decrease the size of the dialog data list */
490 if (*dialogCountPtr == 0)
492 XtFree((char *)*dialogArray);
497 *dialogArray = (DialogData **)
498 XtRealloc((char *)*dialogArray,
499 sizeof(DialogData *) * (*dialogCountPtr));
506 DialogData * dialogData,
507 DialogData *** dialogArray,
508 int * dialogCountPtr )
513 count = *dialogCountPtr;
515 (*dialogArray) = (DialogData **) XtRealloc((char *)(*dialogArray),
516 sizeof(DialogData *) * (*dialogCountPtr));
517 (*dialogArray)[count] = dialogData;
522 * This function acts as a frontend to the encapsulator's map callback
523 * function. If we are in the middle of a restore session, then we don't
524 * want the map callback to alter the placement of the dialog, so we will
525 * not call the encapsulator's function.
531 XtPointer client_data,
532 XtPointer call_data )
534 if (!disableDialogAutoPlacement)
535 _DtmapCB(w,client_data,call_data);
537 XtRemoveCallback(w, XmNpopupCallback, (XtCallbackProc)_DtMappedCB, client_data);
542 * This is the generic function for registering the map callback.
546 _DtGenericMapWindow (
550 GenericRecord * genericRecord = (GenericRecord *) recordPtr;
552 XtAddCallback (genericRecord->shell, XmNpopupCallback,
553 (XtCallbackProc)_DtMappedCB, (XtPointer) parent);
558 * This is the generic function for destroying a dialog widget hierarchy.
563 XtPointer recordPtr )
566 GenericRecord * genericRecord = (GenericRecord *) recordPtr;
568 XtDestroyWidget(genericRecord->shell);
569 XtFree((char *) genericRecord);
574 * This is the generic function for updating the shell's x and y, to
575 * take the window manager border into consideration.
579 _DtGenericUpdateWindowPosition(
580 DialogData * dataPtr )
583 DialogInstanceData * genericData = (DialogInstanceData *) dataPtr->data;
584 GenericRecord * genericRecord;
586 /* Do nothing, if the dialog is not displayed */
587 if (genericData->displayed == True)
589 XmVendorShellExtObject vendorExt;
590 XmWidgetExtData extData;
595 genericRecord = (GenericRecord *)_DtGetDialogInstance(dataPtr);
597 XtSetArg(args[0], XmNwidth, &genericData->width);
598 XtSetArg(args[1], XmNheight, &genericData->height);
599 XtGetValues(genericRecord->shell, args, 2);
601 XTranslateCoordinates(XtDisplay(genericRecord->shell),
602 XtWindow(genericRecord->shell),
603 RootWindowOfScreen(XtScreen(genericRecord->shell)),
606 genericData->x = (Position) t_x;
607 genericData->y = (Position) t_y;
609 /* Modify x & y to take into account window mgr frames */
610 extData=_XmGetWidgetExtData(genericRecord->shell, XmSHELL_EXTENSION);
611 vendorExt = (XmVendorShellExtObject)extData->widget;
612 genericData->x -= vendorExt->vendor.xOffset;
613 genericData->y -= vendorExt->vendor.yOffset;
619 * This is a function for building a path from directory and filename
633 sprintf(path, "%s/%s", directory, fileName);
635 sprintf(path, "%s", directory);
640 sprintf(path, "%s", fileName);
642 sprintf(path, "%s", "");
648 * This is a function for retrieving the pixmap data for a data type.
652 _DtRetrievePixmapData(
660 PixmapData *pixmapData;
661 char path[MAXPATHLEN];
664 pixmapData = (PixmapData *) XtMalloc(sizeof(PixmapData));
669 _DtBuildPath(path, directory, fileName);
671 pixmapData->size = size;
673 /* retrieve host name */
674 pixmapData->hostPrefix = DtDtsDataTypeToAttributeValue(dataType,
679 retrieve instance icon name if one exists; otherwise, retrieve class
684 pixmapData->instanceIconName = DtDtsDataTypeToAttributeValue(dataType,
685 DtDTS_DA_INSTANCE_ICON,
689 pixmapData->instanceIconName = NULL;
691 if (pixmapData->instanceIconName == NULL)
693 pixmapData->iconName = DtDtsDataTypeToAttributeValue( dataType,
694 DtDTS_DA_ICON, NULL);
695 if( pixmapData->iconName == NULL )
697 if( strcmp( dataType, LT_DIRECTORY ) == 0 )
698 pixmapData->iconName = XtNewString( "DtdirB" );
700 pixmapData->iconName = XtNewString( "Dtdeflt" );
705 pixmapData->iconName = NULL;
708 /* retrieve icon file name */
709 if (pixmapData->size == LARGE)
710 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
711 pixmapData->instanceIconName,
712 pixmapData->iconName,
713 pixmapData->hostPrefix,
716 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
717 pixmapData->instanceIconName,
718 pixmapData->iconName,
719 pixmapData->hostPrefix,
722 /* return pixmap data */
728 * This is a function for checking the size, etc of an icon pixmap and
729 * freeing the pixmap data for an icon.
733 _DtCheckAndFreePixmapData(
736 DtIconGadget iconGadget,
737 PixmapData *pixmapData)
746 if there was an instance icon name; verify that the pixmap parameters
747 do not exceed system limits; if system limits are exceeded, retrieve
748 class icon name and set icon gadget image resource to this value
750 if (pixmapData->instanceIconName)
753 if(! pixmapData->iconFileName && iconGadget->icon.pixmap == NULL)
754 { /* Try to get pixmap name
758 tmp = XtNewString( pixmapData->instanceIconName );
759 if( ptr = strrchr( tmp,'/' ) )
761 XmeFlushIconFileCache( tmp );
763 if (pixmapData->iconFileName != NULL)
764 XtFree(pixmapData->iconFileName);
765 if (pixmapData->size == LARGE)
766 pixmapData->iconFileName = _DtGetIconFileName( XtScreen(shell),
767 pixmapData->instanceIconName,
769 pixmapData->hostPrefix,
772 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
773 pixmapData->instanceIconName,
775 pixmapData->hostPrefix,
780 XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
781 XtSetValues((Widget) iconGadget, args, 1);
788 DtDtsFreeAttributeValue(pixmapData->instanceIconName);
790 if (iconGadget->icon.pixmap == NULL ||
791 iconGadget->icon.pixmap_width == NULL ||
792 iconGadget->icon.pixmap_height == NULL ||
793 (Dimension)iconGadget->icon.pixmap_width > (Dimension)instanceWidth ||
794 (Dimension)iconGadget->icon.pixmap_height > (Dimension)instanceHeight)
797 pixmapData->iconName = DtDtsDataTypeToAttributeValue(
799 DtDTS_DA_ICON, NULL);
801 /* retrieve icon file name */
802 if (pixmapData->iconFileName != NULL)
804 XtFree(pixmapData->iconFileName);
805 pixmapData->iconFileName = NULL;
808 if (pixmapData->size == LARGE)
809 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
810 pixmapData->instanceIconName,
811 pixmapData->iconName,
812 pixmapData->hostPrefix,
815 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
816 pixmapData->instanceIconName,
817 pixmapData->iconName,
818 pixmapData->hostPrefix,
823 XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
824 XtSetValues((Widget) iconGadget, args, 1);
826 DtDtsFreeAttributeValue(pixmapData->iconName);
831 DtDtsFreeAttributeValue(pixmapData->iconName);
834 DtDtsFreeAttributeValue(pixmapData->hostPrefix);
835 if (pixmapData->iconFileName)
836 XtFree(pixmapData->iconFileName);
838 XtFree((char *) pixmapData);
843 * This is a function for checking for a datatype property.
847 _DtCheckForDataTypeProperty(
855 Boolean found = False;
858 properties = DtDtsDataTypeToAttributeValue(dataType,
866 while (props = DtStrchr(props, ','))
869 if (strcmp(prop, property) == 0)
881 if (strcmp(prop, property) == 0)
885 DtDtsFreeAttributeValue(properties);
893 * This is a function for compiling a vectorized action list for a data type.
897 _DtCompileActionVector(
902 char **vector = NULL;
904 actions = DtDtsDataTypeToAttributeValue(dataType,
905 DtDTS_DA_ACTION_LIST,
908 vector = (char **) _DtVectorizeInPlace(actions, ',');
915 * This is a generic function for retrieving the default action for a data
920 _DtRetrieveDefaultAction(
926 char *default_action = NULL;
928 actions = DtDtsDataTypeToAttributeValue(dataType,
929 DtDTS_DA_ACTION_LIST,
933 if (acts = DtStrchr(actions, ','))
935 default_action = XtNewString(actions);
937 DtDtsFreeAttributeValue(actions);
940 return(default_action);
945 * This is a function for building a title for a File Manager view.
950 FileMgrData *file_mgr_data )
953 char *title, *ptr, *fileLabel, *fileName;
955 if (fileLabel = DtDtsFileToAttributeValue(file_mgr_data->current_directory,
958 else if (fileName = strrchr(file_mgr_data->current_directory, '/'))
963 if (file_mgr_data->title)
965 if (file_mgr_data->toolbox &&
966 strcmp(file_mgr_data->current_directory,
967 file_mgr_data->restricted_directory) != 0)
969 title = (char *)XtMalloc(strlen(file_mgr_data->title) +
971 4); /* Need for blank dash blank NULL */
972 sprintf(title, "%s - %s", file_mgr_data->title, ptr);
976 title = XtNewString(file_mgr_data->title);
981 if (strcmp(file_mgr_data->current_directory, "/") == 0 && !fileLabel)
983 title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
984 strlen(file_mgr_data->host) +
986 5); /* Need for blank dash blank colon NULL */
987 sprintf( title, "%s - %s:%s", (GETMESSAGE(12, 7, "File Manager")),
993 title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
995 4); /* Need for blank dash blank NULL */
996 sprintf( title, "%s - %s", (GETMESSAGE(12, 7, "File Manager")), ptr);
1000 DtDtsFreeAttributeValue(fileLabel);
1006 * This is a function for building a path from the directory name
1007 * and file name pieces of a FileViewData structure.
1011 _DtGetSelectedFilePath(
1012 FileViewData *selected_file )
1019 directory = ((DirectorySet *)selected_file->directory_set)->name;
1020 file = selected_file->file_data->file_name;
1022 if (strcmp(directory, "/") == 0)
1024 path = XtMalloc(strlen(directory) + strlen(file) + 1);
1025 sprintf(path, "%s%s", directory, file);
1029 path = XtMalloc(strlen(directory) + strlen(file) + 2);
1030 sprintf(path, "%s/%s", directory, file);
1038 * This is a generic function for building action parameters from an array of
1039 * file view data structures.
1043 _DtBuildActionArgsWithSelectedFiles(
1044 FileViewData **selection_list,
1046 DtActionArg **action_args,
1052 *action_args = (DtActionArg *)
1053 XtCalloc(1, sizeof(DtActionArg) * selected_count);
1059 for(i = 0; i < selected_count; i++)
1061 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1062 ((*action_args)[(*arg_count)++]).u.file.name =
1063 _DtGetSelectedFilePath(selection_list[i]);
1070 _DtBuildActionArgsWithDTSelectedFiles(
1071 DesktopRec **selection_list,
1073 DtActionArg **action_args,
1079 *action_args = (DtActionArg *)
1080 XtCalloc(1, sizeof(DtActionArg) * selected_count);
1086 for(i = 0; i < selected_count; i++)
1088 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1089 ((*action_args)[(*arg_count)++]).u.file.name =
1090 _DtGetSelectedFilePath(selection_list[i]->file_view_data);
1097 * This is a generic function for building action parameters from drag and drop
1102 _DtBuildActionArgsWithDroppedFiles(
1103 FileViewData *dropped_on_obj,
1104 DtDndDropCallbackStruct *drop_parameters,
1105 DtActionArg **action_args,
1112 *action_args = (DtActionArg *) XtCalloc
1113 (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
1115 *action_args = (DtActionArg *) XtCalloc
1116 (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
1124 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1125 ((*action_args)[(*arg_count)++]).u.file.name =
1126 _DtGetSelectedFilePath(dropped_on_obj);
1129 for(i = 0; i < drop_parameters->dropData->numItems; i++)
1131 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1132 ((*action_args)[(*arg_count)++]).u.file.name =
1133 XtNewString(drop_parameters->dropData->data.files[i]);
1140 * This is a generic function for building action parameters from drag and drop
1141 * buffer information.
1146 _DtBuildActionArgsWithDroppedBuffers(
1147 FileViewData *dropped_on_obj,
1148 DtDndDropCallbackStruct *drop_parameters,
1149 DtActionArg **action_args,
1156 *action_args = (DtActionArg *) XtCalloc
1157 (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
1159 *action_args = (DtActionArg *) XtCalloc
1160 (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
1165 DtActionBuffer buffer_arg = {NULL, 0, NULL, NULL, False};
1169 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1170 ((*action_args)[(*arg_count)++]).u.file.name =
1171 _DtGetSelectedFilePath(dropped_on_obj);
1174 for(i = 0; i < drop_parameters->dropData->numItems; i++)
1176 buffer_arg.bp = drop_parameters->dropData->data.buffers[i].bp;
1177 buffer_arg.size = drop_parameters->dropData->data.buffers[i].size;
1178 buffer_arg.name = drop_parameters->dropData->data.buffers[i].name;
1180 ((*action_args)[(*arg_count)]).argClass = DtACTION_BUFFER;
1181 ((*action_args)[(*arg_count)++]).u.buffer = buffer_arg;
1188 * This is a generic function for freeing action parameters.
1193 DtActionArg *action_args,
1199 for (i = 0; i < arg_count; i++)
1201 if (action_args[i].argClass == DtACTION_FILE)
1203 XtFree(action_args[i].u.file.name);
1204 action_args[i].u.file.name = NULL;
1208 XtFree((char *) action_args);
1212 /************************************************************************
1213 * The following functions deal with Buffer Manipulation and Naming
1214 ************************************************************************/
1217 * This is a generic function for extracting buffer information from
1222 _DtSetDroppedBufferInfo(char **file_set,
1223 BufferInfo *buffer_set,
1225 DtDndDropCallbackStruct *drop_parameters)
1229 int num_of_buffers = drop_parameters->dropData->numItems;
1231 DtDndBuffer *buffers = drop_parameters->dropData->data.buffers;
1234 DPRINTF (("Executing..._DtSetDroppedBufferInfo\n"));
1236 /* Initialize file_set and ensure of unique file names for unamed buffers*/
1237 SetBufferFileNames(file_set, buffers, num_of_buffers);
1239 for (i= 0; i < num_of_buffers; i++)
1242 (buffer_set[i]).buf_ptr = buffers[i].bp;
1243 (buffer_set[i]).size = buffers[i].size;
1245 host_set[i] = XtNewString(home_host_name);
1247 DPRINTF(("_DtSetDroppedBufferInfo:\n host_set[%d]=%s,\
1248 buffer_set[%d].buf_ptr=%p, buffer_set[%d].size=%d\n",
1249 i, host_set[i], i, buffer_set[i].buf_ptr, i, buffer_set[i].size));
1255 * This is a function for creating file names for a set of buffers.
1259 SetBufferFileNames (char **file_set,
1260 DtDndBuffer *buffers,
1263 int null_filenames_count = 0;
1265 int first_nullfile_index = 0;
1266 Boolean NULL_FILENAMES=FALSE;
1268 DPRINTF (("Executing...SetBufferFileNames\n"));
1270 for (i = 0; i < num_of_buffers; i++)
1272 if (buffers[i].name == NULL)
1274 /* generate buffer name using Untitled as a base name */
1275 file_set[i]=BuildBufferFileName(DEFAULT_BUFFER_FILENAME,
1282 /* file name is supplied by the drag initiator */
1283 file_set[i] = XtNewString(buffers[i].name);
1286 DPRINTF(("file_set[%d]=%s\n", i, file_set[i]));
1288 } /* end for loop */
1291 /* Rename any collisions to unique names */
1292 RenameCollisions(file_set, num_of_buffers);
1299 * This is a generic function for generating a name for an untitled buffer.
1300 * A default name (Untitled) is used in conjunction with the name template
1301 * information from the types database.
1305 BuildBufferFileName (char *file_name,
1310 const char delim = '_';
1311 char *new_file_name;
1314 DPRINTF (("Executing....BuildBufferFileName\n"));
1316 /* Malloc memory and contruct the new file name */
1317 new_file_name = (char *) XtMalloc (strlen(file_name) + 1 +
1318 MAX_POSTFIX_LENGTH + 1);
1320 DPRINTF (("BuildBufferFileName: Old file name is %s\n", file_name));
1322 /* determine whether to append post fix name */
1323 if (postfix_index == -1)
1324 strcpy(new_file_name, file_name);
1326 sprintf(new_file_name,"%s%c%d", file_name, delim, postfix_index);
1328 /* Retrieve the name template if it exists and use it in the filename */
1329 new_file_name = RetrieveAndUseNameTemplateInfo(buffer,
1333 DPRINTF(("BuildBufferFileName: Returning new_file_name=%s\n", new_file_name));
1335 /* return new file name */
1336 return (new_file_name);
1342 * This is a function for building a buffer name using predfined input
1343 * and name template information from the types database.
1344 * WARNING: template_input will be freed. It must point to a char *.
1348 RetrieveAndUseNameTemplateInfo(
1351 char *template_input)
1354 char *name_template;
1355 char *buffer_name = NULL;
1357 name_template = DtDtsBufferToAttributeValue(buffer,
1359 DtDTS_DA_NAME_TEMPLATE,
1362 buffer_name = (char *) XtMalloc(strlen(name_template) +
1363 strlen(template_input) +
1367 sprintf(buffer_name, name_template, template_input);
1368 DtDtsFreeAttributeValue(name_template);
1369 XtFree(template_input);
1370 return(buffer_name);
1374 return(template_input);
1380 * This is a function for resolving collisions in a list of buffer names.
1384 RenameCollisions( char ** list, int count )
1386 register int i, j, k, l;
1387 char flg = 0, flg2 = 0;
1389 for( i = 0; i < count; ++i )
1391 unsigned int addIndex = 1;
1393 if( *(list[i]) == 0x0 )
1399 for( j = i+1; j < count; ++j )
1401 if( strcmp( list[i], list[j] ) == 0 )
1403 RenameEntry( &(list[j]), ++addIndex );
1411 RenameEntry( &(list[l]), 1 );
1417 list[k] = (char *)malloc( strlen( DEFAULT_BUFFER_FILENAME ) + 1 );
1418 sprintf( list[k], "%s", DEFAULT_BUFFER_FILENAME );
1424 * This is a function for adding an index to a buffer name which has
1429 RenameEntry( char ** name, unsigned int addIndex )
1432 #define MAX_INT_SIZE 15
1434 char * tmpPtr, * newName;
1438 else if( **name == 0x0 )
1440 newName = (char *)XtCalloc(1,strlen(DEFAULT_BUFFER_FILENAME)+ MAX_INT_SIZE);
1441 sprintf( newName, "%s_%d", DEFAULT_BUFFER_FILENAME, addIndex );
1445 tmpPtr = strrchr( *name, '.' );
1447 newName = (char *)XtCalloc( 1, strlen( *name ) + MAX_INT_SIZE );
1449 if( tmpPtr == NULL )
1450 sprintf( newName, "%s_%d", *name, addIndex );
1451 else if( tmpPtr == *name )
1452 sprintf( newName, "%d%s", addIndex, *name );
1456 sprintf( newName, "%s_%d.%s", *name, addIndex, ++tmpPtr);
1465 * This is a generic function for freeing buffer information extracted from
1470 _DtFreeDroppedBufferInfo(char **file_set,
1471 BufferInfo *buffer_set,
1477 DPRINTF (("Executing..._DtFreeDroppedBufferInfo\n"));
1479 /* Check for Null pointers */
1480 if (file_set && buffer_set && host_set )
1482 for (i=0; i< num_of_buffers; i++ )
1484 XtFree(file_set[i]);
1485 XtFree(host_set[i]);
1488 XtFree((char *)file_set);
1489 XtFree((char *)host_set);
1490 XtFree((char *)buffer_set);
1496 * This is a generic function for determining if a buffer is executable.
1500 _DtIsBufferExecutable(
1505 char *exe_attribute;
1506 Boolean is_exe = False;
1508 exe_attribute = DtDtsBufferToAttributeValue(buffer,
1514 if (DtDtsIsTrue(exe_attribute))
1517 DtDtsFreeAttributeValue(exe_attribute);
1525 * This is a generic function for extracting file information from drop input.
1529 _DtSetDroppedFileInfo(
1530 DtDndDropCallbackStruct *drop_parameters,
1536 numFiles = drop_parameters->dropData->numItems;
1538 *file_set = (char **)XtMalloc(sizeof(char *) * numFiles);
1539 *host_set = (char **)XtMalloc(sizeof(char *) * numFiles);
1540 for(i = 0; i < numFiles; i++)
1542 (*file_set)[i] = XtNewString(drop_parameters->dropData->data.files[i]);
1543 (*host_set)[i] = home_host_name;
1545 DPRINTF(("ProcessMoveCopyLink:\n host_set[%d]=%s, file_set[%d]=%s\n",
1546 i, (*host_set)[i], i, (*file_set)[i]));
1552 * This is a generic function for copying file info extracted from drop input.
1556 _DtCopyDroppedFileInfo(
1558 char **orig_file_set,
1559 char **orig_host_set,
1560 char ***new_file_set,
1561 char ***new_host_set)
1565 *new_file_set = (char **)XtMalloc(sizeof(char *) * num_files);
1566 *new_host_set = (char **)XtMalloc(sizeof(char *) * num_files);
1567 for(i = 0; i < num_files; i++)
1569 (*new_file_set)[i] = XtNewString(orig_file_set[i]);
1570 (*new_host_set)[i] = XtNewString(orig_host_set[i]);
1576 * This is a generic function for freeing file info extracted from drop input.
1580 _DtFreeDroppedFileInfo(
1587 for(i = 0; i < num_files; i++)
1588 XtFree(file_set[i]);
1590 XtFree((char *)file_set);
1591 XtFree((char *)host_set);
1596 * This is a generic function for resolving a cannonical path from user input.
1608 char *tmp_path = NULL;
1609 char *true_path = NULL;
1610 Tt_status tt_status;
1614 *host = XtNewString(home_host_name);
1616 /* find relative path */
1617 tmp_path = path = XtNewString(input_string);
1619 /* Strip any spaces from name -- input is overwritten */
1620 path = (char *) _DtStripSpaces(path);
1622 /* Resolve, if there're any, environment variables */
1625 char command[MAXPATHLEN];
1627 sprintf(command,"echo %s",path);
1629 if((pfp=popen(command,"r")) != NULL)
1633 if (NULL == (fgets(command,MAXPATHLEN,pfp)))
1636 * Try a few more reads and if the read still fails,
1637 * just use the path as is.
1640 for (i=0; i < 5; i++)
1643 if (NULL != (fgets(command,MAXPATHLEN,pfp)))
1652 command[strlen(command)-1] = '\0';
1654 path = XtNewString(command);
1660 /* Resolve '~' -- new memory is allocated, old memory is freed */
1662 path = _DtChangeTildeToHome(path);
1664 /* If current dir provided, check for relative path */
1665 if (path && current_dir)
1669 /* file is relative path i.e. xyz/abc */
1670 if (strcmp(current_dir, "/") == 0)
1672 tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 1);
1673 sprintf(tmp_path, "%s%s", current_dir, path);
1677 tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 2);
1678 sprintf(tmp_path, "%s/%s", current_dir, path);
1693 /* Resolve '.' or '..' -- input is overwritten, output may be NULL! */
1694 /* Save pointer to path to free if output is NULL. */
1696 path = (char *) DtEliminateDots(path);
1700 /* Resolve to local pathname */
1701 true_path = ResolveLocalPathName(*host,
1708 /* Strip off trailing '/' */
1709 dir_len = strlen(true_path);
1710 if (dir_len > 1 && *(true_path + dir_len - 1) == '/')
1711 *(true_path + dir_len - 1) = NULL;
1719 *rel_path = true_path;
1724 * This function takes a path name, and resolves any leading '~' to refer
1725 * to one of the following:
1727 * 1) if ~ or ~/path, then it resolves to the user's home directory on
1730 * 2) if ~user or ~user/path, then it resolves to the specified user's
1731 * home directory on the home host.
1733 * This function never resolves to any host but the home host, since we
1734 * have no way of determining a user's home directory on any system other
1735 * than the home system.
1739 _DtChangeTildeToHome (
1744 struct passwd * pwInfo;
1746 if ((input_string[1] != '\0') && (input_string[1] != '/'))
1750 /* ~user or ~user/path format */
1752 /* is there a path? */
1753 path = DtStrchr(input_string, '/');
1758 if ((pwInfo = getpwnam(input_string + 1)) == NULL)
1760 /* user doesn't exist */
1768 /* ~user/path format */
1772 if (strcmp(pwInfo->pw_dir, "/") == 0)
1774 /* We don't want to end up with double '/' in the path */
1775 full_path = (char *) XtMalloc(strlen(path) + 1);
1776 strcpy(full_path, path);
1780 full_path = (char *) XtMalloc(strlen(pwInfo->pw_dir) +
1782 sprintf(full_path, "%s%s", pwInfo->pw_dir, path);
1789 full_path = XtMalloc(strlen(pwInfo->pw_dir) + 1);
1790 strcpy(full_path, pwInfo->pw_dir);
1793 else if (input_string[1])
1797 /* NOTE: users_home_dir has trailing '/' */
1798 full_path = XtMalloc(strlen(users_home_dir) + strlen(input_string+2) + 1);
1799 sprintf(full_path, "%s%s", users_home_dir, (input_string + 2));
1805 full_path = XtMalloc(strlen(users_home_dir) + 1);
1806 strcpy(full_path, users_home_dir);
1809 XtFree(input_string);
1815 * This function checks for spaces in filenames.
1817 #ifdef _CHECK_FOR_SPACES
1820 _DtSpacesInFileNames(
1826 for (i = 0; i < fileCount; i++)
1828 fileNames[i] = (char *) _DtStripSpaces(fileNames[i]);
1830 if (DtStrchr (fileNames[i], ' ') != NULL ||
1831 DtStrchr (fileNames[i], '\t') != NULL)
1841 * This resolves the path for an appmanager object to its true path.
1845 _DtResolveAppManPath(
1847 char *restricted_dir )
1849 if (strlen(path) > strlen(restricted_dir))
1851 char *linkDir, *ptr, *tmpPath;
1853 linkDir = path + strlen(restricted_dir) + 1;
1854 ptr = DtStrchr(linkDir, '/');
1858 linkDir = _DtFollowLink(path);
1860 tmpPath = XtMalloc(strlen(linkDir) + strlen(ptr) + 1);
1861 sprintf(tmpPath, "%s%s", linkDir, ptr);
1867 linkDir = _DtFollowLink(path);
1869 path = XtNewString(linkDir);