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 libraries 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>
123 #include <Dt/Utility.h>
124 #include <Dt/SharedProcs.h>
133 #include "SharedProcs.h"
135 extern char *pathcollapse();
139 #define RW_ALL S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
142 /* Global controlling whether auto-positioning is enabled */
143 Boolean disableDialogAutoPlacement = False;
146 /******** Static Function Declarations ********/
148 static void SetBufferFileNames (
150 DtDndBuffer *buffers,
151 int num_of_buffers) ;
152 static char * BuildBufferFileName (
157 static char * RetrieveAndUseNameTemplateInfo(
160 char *template_input) ;
161 static void RenameEntry(
163 unsigned int addIndex) ;
164 static void RenameCollisions(
168 /******** End Static Function Declarations ********/
171 /************************************************************************
174 * Returns the parent directory of its argument.
175 * Does this by looking for the last "/" in the name, and
178 ************************************************************************/
182 register char *name )
186 static char pnam[MAXPATHLEN];
187 static char dot[] = ".";
190 q = strrchr(pnam, '/');
194 else if ((q == pnam) &&
196 (mblen(q, MB_CUR_MAX) == 1) &&
205 return(pnam[0] ? pnam : dot);
210 * Given a filename, follow it to the end of its link. Returns NULL if
211 * a recursive symbolic link is found.
213 * Note, the path returned is a static buffer, and should not be freed by
214 * the calling function.
221 char link_path[MAXPATHLEN];
222 static char file[MAXPATHLEN];
230 /* Used to check for symbolic link loops */
233 history = (char **)XtMalloc(sizeof(char *) * history_size);
237 while ((link_len = readlink(file, link_path, MAXPATHLEN - 1)) > 0)
239 link_path[link_len] = 0;
241 /* Force the link to be an absolute path, if necessary */
242 if (link_path[0] != '/')
244 /* Relative paths are relative to the current directory */
245 end = strrchr(file, '/') + 1;
247 strcat(file, link_path);
250 strcpy(file, link_path);
252 /* Check for a recursive loop; abort if found */
253 for (i = 0; i < history_count; i++)
255 if (strcmp(file, history[i]) == 0)
257 for (i = 0; i < history_count; i++)
259 XtFree((char *)history);
265 /* Add to the history list */
266 if (history_count >= history_size)
269 history = (char **)XtRealloc((char *)history,
270 sizeof(char *) * history_size);
272 history[history_count++] = XtNewString(file);
275 /* Free up the history list */
276 for (i = 0; i < history_count; i++)
278 XtFree((char *)history);
285 /************************************************************************
287 * _DtStringsAreEquivalent
288 * Compare two strings and return true if equal.
289 * The comparison is on lower cased strings. It is the callers
290 * responsibility to ensure that test_str is already lower cased.
292 ************************************************************************/
295 _DtStringsAreEquivalent(
296 register char *in_str,
297 register char *test_str )
312 /* Convert each character from multibyte to wide format */
313 c1size = mbtowc(&c1, in_str, MB_CUR_MAX);
314 c2size = mbtowc(&c2, test_str, MB_CUR_MAX);
316 /* No match, if the two characters have different byte counts */
317 if (c1size != c2size)
320 /* Do case conversion only for single byte characters */
323 if (isupper((int) c1))
324 c1 = tolower((int) c1);
327 /* See if the two wide characters match */
331 /* Are we at the end of the string? */
348 if (isupper (i)) i = tolower (i);
349 if (i != j) return (False);
350 if (i == 0) return (True);
361 _DtDuplicateDialogNameList (
370 /* Get a copy of the name list to be used to build new name lists. */
372 while (nameList[*nameCount] != NULL)
374 newNameList[*nameCount] = nameList[*nameCount];
378 /* NULL out any remaining array entries */
379 for (i = (*nameCount); i < newNameListSize; i++)
380 newNameList[i] = NULL;
385 _DtLoadSubdialogArray (
388 DialogData *** dialogArray,
391 XrmDatabase dataBase,
396 static char number[10];
398 /* Load sub-dialogs */
399 nameList[nameCount] = number;
400 nameList[nameCount + 1] = NULL;
402 /* Get text annotation dialogs */
403 *dialogArray = (DialogData **) XtMalloc(sizeof(DialogData *) * dialogCount);
405 for (i = 0; i < dialogCount; i++)
407 snprintf(number, 10, "%d", firstId);
408 (*dialogArray)[i] = _DtGetResourceDialogData(dialogId, dataBase, nameList);
416 _DtSaveSubdialogArray (
419 DialogData ** dialogArray,
426 static char number[10];
428 nameList[nameCount] = number;
429 nameList[nameCount + 1] = NULL;
431 for (i = 0; i < dialogCount; i++)
433 snprintf(number, 10, "%d", firstId);
434 _DtWriteDialogData(dialogArray[i], fd, nameList);
441 _DtDestroySubdialogArray (
442 DialogData ** dialogArray,
448 for (i = 0; i < dialogCount; i++)
450 if (_DtIsDialogShowing(dialogArray[i]))
451 _DtHideDialog(dialogArray[i], False);
453 _DtFreeDialogData(dialogArray[i]);
455 XtFree((char *)dialogArray);
460 _DtDestroySubdialog (
461 DialogData * dialogData )
466 if (_DtIsDialogShowing(dialogData))
467 _DtHideDialog(dialogData, False);
468 _DtFreeDialogData(dialogData);
474 _DtHideOneSubdialog (
475 DialogData * dialogData,
476 DialogData *** dialogArray,
477 int * dialogCountPtr )
482 for (i = 0; i < *dialogCountPtr; i++)
484 if (dialogData == (*dialogArray)[i])
486 for (j = i; j < (*dialogCountPtr) - 1; j++)
487 (*dialogArray)[j] = (*dialogArray)[j + 1];
492 /* Free or decrease the size of the dialog data list */
494 if (*dialogCountPtr == 0)
496 XtFree((char *)*dialogArray);
501 *dialogArray = (DialogData **)
502 XtRealloc((char *)*dialogArray,
503 sizeof(DialogData *) * (*dialogCountPtr));
510 DialogData * dialogData,
511 DialogData *** dialogArray,
512 int * dialogCountPtr )
517 count = *dialogCountPtr;
519 (*dialogArray) = (DialogData **) XtRealloc((char *)(*dialogArray),
520 sizeof(DialogData *) * (*dialogCountPtr));
521 (*dialogArray)[count] = dialogData;
526 * This function acts as a frontend to the encapsulator's map callback
527 * function. If we are in the middle of a restore session, then we don't
528 * want the map callback to alter the placement of the dialog, so we will
529 * not call the encapsulator's function.
535 XtPointer client_data,
536 XtPointer call_data )
538 if (!disableDialogAutoPlacement)
539 _DtmapCB(w,client_data,call_data);
541 XtRemoveCallback(w, XmNpopupCallback, (XtCallbackProc)_DtMappedCB, client_data);
546 * This is the generic function for registering the map callback.
550 _DtGenericMapWindow (
554 GenericRecord * genericRecord = (GenericRecord *) recordPtr;
556 XtAddCallback (genericRecord->shell, XmNpopupCallback,
557 (XtCallbackProc)_DtMappedCB, (XtPointer) parent);
562 * This is the generic function for destroying a dialog widget hierarchy.
567 XtPointer recordPtr )
570 GenericRecord * genericRecord = (GenericRecord *) recordPtr;
572 XtDestroyWidget(genericRecord->shell);
573 XtFree((char *) genericRecord);
578 * This is the generic function for updating the shell's x and y, to
579 * take the window manager border into consideration.
583 _DtGenericUpdateWindowPosition(
584 DialogData * dataPtr )
587 DialogInstanceData * genericData = (DialogInstanceData *) dataPtr->data;
588 GenericRecord * genericRecord;
590 /* Do nothing, if the dialog is not displayed */
591 if (genericData->displayed == True)
593 XmVendorShellExtObject vendorExt;
594 XmWidgetExtData extData;
599 genericRecord = (GenericRecord *)_DtGetDialogInstance(dataPtr);
601 XtSetArg(args[0], XmNwidth, &genericData->width);
602 XtSetArg(args[1], XmNheight, &genericData->height);
603 XtGetValues(genericRecord->shell, args, 2);
605 XTranslateCoordinates(XtDisplay(genericRecord->shell),
606 XtWindow(genericRecord->shell),
607 RootWindowOfScreen(XtScreen(genericRecord->shell)),
610 genericData->x = (Position) t_x;
611 genericData->y = (Position) t_y;
613 /* Modify x & y to take into account window mgr frames */
614 extData=_XmGetWidgetExtData(genericRecord->shell, XmSHELL_EXTENSION);
615 vendorExt = (XmVendorShellExtObject)extData->widget;
616 genericData->x -= vendorExt->vendor.xOffset;
617 genericData->y -= vendorExt->vendor.yOffset;
623 * This is a function for building a path from directory and filename
637 sprintf(path, "%s/%s", directory, fileName);
639 sprintf(path, "%s", directory);
644 sprintf(path, "%s", fileName);
646 sprintf(path, "%s", "");
652 * This is a function for retrieving the pixmap data for a data type.
656 _DtRetrievePixmapData(
664 PixmapData *pixmapData;
665 char path[MAXPATHLEN];
668 pixmapData = (PixmapData *) XtMalloc(sizeof(PixmapData));
673 _DtBuildPath(path, directory, fileName);
675 pixmapData->size = size;
677 /* retrieve host name */
678 pixmapData->hostPrefix = DtDtsDataTypeToAttributeValue(dataType,
683 retrieve instance icon name if one exists; otherwise, retrieve class
688 pixmapData->instanceIconName = DtDtsDataTypeToAttributeValue(dataType,
689 DtDTS_DA_INSTANCE_ICON,
693 pixmapData->instanceIconName = NULL;
695 if (pixmapData->instanceIconName == NULL)
697 pixmapData->iconName = DtDtsDataTypeToAttributeValue( dataType,
698 DtDTS_DA_ICON, NULL);
699 if( pixmapData->iconName == NULL )
701 if( strcmp( dataType, LT_DIRECTORY ) == 0 )
702 pixmapData->iconName = XtNewString( "DtdirB" );
704 pixmapData->iconName = XtNewString( "Dtdeflt" );
709 pixmapData->iconName = NULL;
712 /* retrieve icon file name */
713 if (pixmapData->size == LARGE)
714 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
715 pixmapData->instanceIconName,
716 pixmapData->iconName,
717 pixmapData->hostPrefix,
720 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
721 pixmapData->instanceIconName,
722 pixmapData->iconName,
723 pixmapData->hostPrefix,
726 /* return pixmap data */
732 * This is a function for checking the size, etc of an icon pixmap and
733 * freeing the pixmap data for an icon.
737 _DtCheckAndFreePixmapData(
740 DtIconGadget iconGadget,
741 PixmapData *pixmapData)
750 if there was an instance icon name; verify that the pixmap parameters
751 do not exceed system limits; if system limits are exceeded, retrieve
752 class icon name and set icon gadget image resource to this value
754 if (pixmapData->instanceIconName)
757 if(! pixmapData->iconFileName && iconGadget->icon.pixmap == 0)
758 { /* Try to get pixmap name
762 tmp = XtNewString( pixmapData->instanceIconName );
763 if( ptr = strrchr( tmp,'/' ) )
765 XmeFlushIconFileCache( tmp );
767 if (pixmapData->iconFileName != NULL)
768 XtFree(pixmapData->iconFileName);
769 if (pixmapData->size == LARGE)
770 pixmapData->iconFileName = _DtGetIconFileName( XtScreen(shell),
771 pixmapData->instanceIconName,
773 pixmapData->hostPrefix,
776 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
777 pixmapData->instanceIconName,
779 pixmapData->hostPrefix,
784 XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
785 XtSetValues((Widget) iconGadget, args, 1);
792 DtDtsFreeAttributeValue(pixmapData->instanceIconName);
793 pixmapData->instanceIconName = NULL;
795 if (iconGadget->icon.pixmap == 0 ||
796 iconGadget->icon.pixmap_width == 0 ||
797 iconGadget->icon.pixmap_height == 0 ||
798 (Dimension)iconGadget->icon.pixmap_width > (Dimension)instanceWidth ||
799 (Dimension)iconGadget->icon.pixmap_height > (Dimension)instanceHeight)
802 pixmapData->iconName = DtDtsDataTypeToAttributeValue(
804 DtDTS_DA_ICON, NULL);
806 /* retrieve icon file name */
807 if (pixmapData->iconFileName != NULL)
809 XtFree(pixmapData->iconFileName);
810 pixmapData->iconFileName = NULL;
813 if (pixmapData->size == LARGE)
814 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
815 pixmapData->instanceIconName,
816 pixmapData->iconName,
817 pixmapData->hostPrefix,
820 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
821 pixmapData->instanceIconName,
822 pixmapData->iconName,
823 pixmapData->hostPrefix,
828 XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
829 XtSetValues((Widget) iconGadget, args, 1);
831 DtDtsFreeAttributeValue(pixmapData->iconName);
832 pixmapData->iconName = NULL;
837 DtDtsFreeAttributeValue(pixmapData->iconName);
838 pixmapData->iconName = NULL;
841 DtDtsFreeAttributeValue(pixmapData->hostPrefix);
842 if (pixmapData->iconFileName)
843 XtFree(pixmapData->iconFileName);
845 XtFree((char *) pixmapData);
850 * This is a function for checking for a datatype property.
854 _DtCheckForDataTypeProperty(
862 Boolean found = False;
865 properties = DtDtsDataTypeToAttributeValue(dataType,
873 while (props = DtStrchr(props, ','))
876 if (strcmp(prop, property) == 0)
888 if (strcmp(prop, property) == 0)
892 DtDtsFreeAttributeValue(properties);
900 * This is a function for compiling a vectorized action list for a data type.
904 _DtCompileActionVector(
909 char **vector = NULL;
911 actions = DtDtsDataTypeToAttributeValue(dataType,
912 DtDTS_DA_ACTION_LIST,
915 vector = (char **) _DtVectorizeInPlace(actions, ',');
922 * This is a generic function for retrieving the default action for a data
927 _DtRetrieveDefaultAction(
933 char *default_action = NULL;
935 actions = DtDtsDataTypeToAttributeValue(dataType,
936 DtDTS_DA_ACTION_LIST,
940 if (acts = DtStrchr(actions, ','))
942 default_action = XtNewString(actions);
944 DtDtsFreeAttributeValue(actions);
947 return(default_action);
952 * This is a function for building a title for a File Manager view.
957 FileMgrData *file_mgr_data )
960 char *title, *ptr, *fileLabel, *fileName;
962 if (fileLabel = DtDtsFileToAttributeValue(file_mgr_data->current_directory,
965 else if (fileName = strrchr(file_mgr_data->current_directory, '/'))
970 if (file_mgr_data->title)
972 if (file_mgr_data->toolbox &&
973 strcmp(file_mgr_data->current_directory,
974 file_mgr_data->restricted_directory) != 0)
976 title = (char *)XtMalloc(strlen(file_mgr_data->title) +
978 4); /* Need for blank dash blank NULL */
979 sprintf(title, "%s - %s", file_mgr_data->title, ptr);
983 title = XtNewString(file_mgr_data->title);
988 if (strcmp(file_mgr_data->current_directory, "/") == 0 && !fileLabel)
990 title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
991 strlen(file_mgr_data->host) +
993 5); /* Need for blank dash blank colon NULL */
994 sprintf( title, "%s - %s:%s", (GETMESSAGE(12, 7, "File Manager")),
1000 title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
1002 4); /* Need for blank dash blank NULL */
1003 sprintf( title, "%s - %s", (GETMESSAGE(12, 7, "File Manager")), ptr);
1007 DtDtsFreeAttributeValue(fileLabel);
1013 * This is a function for building a path from the directory name
1014 * and file name pieces of a FileViewData structure.
1018 _DtGetSelectedFilePath(
1019 FileViewData *selected_file )
1026 directory = ((DirectorySet *)selected_file->directory_set)->name;
1027 file = selected_file->file_data->file_name;
1029 if (strcmp(directory, "/") == 0)
1031 path = XtMalloc(strlen(directory) + strlen(file) + 1);
1032 sprintf(path, "%s%s", directory, file);
1036 path = XtMalloc(strlen(directory) + strlen(file) + 2);
1037 sprintf(path, "%s/%s", directory, file);
1045 * This is a generic function for building action parameters from an array of
1046 * file view data structures.
1050 _DtBuildActionArgsWithSelectedFiles(
1051 FileViewData **selection_list,
1053 DtActionArg **action_args,
1059 *action_args = (DtActionArg *)
1060 XtCalloc(1, sizeof(DtActionArg) * selected_count);
1066 for(i = 0; i < selected_count; i++)
1068 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1069 ((*action_args)[(*arg_count)++]).u.file.name =
1070 _DtGetSelectedFilePath(selection_list[i]);
1077 _DtBuildActionArgsWithDTSelectedFiles(
1078 DesktopRec **selection_list,
1080 DtActionArg **action_args,
1086 *action_args = (DtActionArg *)
1087 XtCalloc(1, sizeof(DtActionArg) * selected_count);
1093 for(i = 0; i < selected_count; i++)
1095 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1096 ((*action_args)[(*arg_count)++]).u.file.name =
1097 _DtGetSelectedFilePath(selection_list[i]->file_view_data);
1104 * This is a generic function for building action parameters from drag and drop
1109 _DtBuildActionArgsWithDroppedFiles(
1110 FileViewData *dropped_on_obj,
1111 DtDndDropCallbackStruct *drop_parameters,
1112 DtActionArg **action_args,
1119 *action_args = (DtActionArg *) XtCalloc
1120 (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
1122 *action_args = (DtActionArg *) XtCalloc
1123 (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
1131 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1132 ((*action_args)[(*arg_count)++]).u.file.name =
1133 _DtGetSelectedFilePath(dropped_on_obj);
1136 for(i = 0; i < drop_parameters->dropData->numItems; i++)
1138 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1139 ((*action_args)[(*arg_count)++]).u.file.name =
1140 XtNewString(drop_parameters->dropData->data.files[i]);
1147 * This is a generic function for building action parameters from drag and drop
1148 * buffer information.
1153 _DtBuildActionArgsWithDroppedBuffers(
1154 FileViewData *dropped_on_obj,
1155 DtDndDropCallbackStruct *drop_parameters,
1156 DtActionArg **action_args,
1163 *action_args = (DtActionArg *) XtCalloc
1164 (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
1166 *action_args = (DtActionArg *) XtCalloc
1167 (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
1172 DtActionBuffer buffer_arg = {NULL, 0, NULL, NULL, False};
1176 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1177 ((*action_args)[(*arg_count)++]).u.file.name =
1178 _DtGetSelectedFilePath(dropped_on_obj);
1181 for(i = 0; i < drop_parameters->dropData->numItems; i++)
1183 buffer_arg.bp = drop_parameters->dropData->data.buffers[i].bp;
1184 buffer_arg.size = drop_parameters->dropData->data.buffers[i].size;
1185 buffer_arg.name = drop_parameters->dropData->data.buffers[i].name;
1187 ((*action_args)[(*arg_count)]).argClass = DtACTION_BUFFER;
1188 ((*action_args)[(*arg_count)++]).u.buffer = buffer_arg;
1195 * This is a generic function for freeing action parameters.
1200 DtActionArg *action_args,
1206 for (i = 0; i < arg_count; i++)
1208 if (action_args[i].argClass == DtACTION_FILE)
1210 XtFree(action_args[i].u.file.name);
1211 action_args[i].u.file.name = NULL;
1215 XtFree((char *) action_args);
1219 /************************************************************************
1220 * The following functions deal with Buffer Manipulation and Naming
1221 ************************************************************************/
1224 * This is a generic function for extracting buffer information from
1229 _DtSetDroppedBufferInfo(char **file_set,
1230 BufferInfo *buffer_set,
1232 DtDndDropCallbackStruct *drop_parameters)
1236 int num_of_buffers = drop_parameters->dropData->numItems;
1238 DtDndBuffer *buffers = drop_parameters->dropData->data.buffers;
1241 DPRINTF (("Executing..._DtSetDroppedBufferInfo\n"));
1243 /* Initialize file_set and ensure of unique file names for unamed buffers*/
1244 SetBufferFileNames(file_set, buffers, num_of_buffers);
1246 for (i= 0; i < num_of_buffers; i++)
1249 (buffer_set[i]).buf_ptr = buffers[i].bp;
1250 (buffer_set[i]).size = buffers[i].size;
1252 host_set[i] = XtNewString(home_host_name);
1254 DPRINTF(("_DtSetDroppedBufferInfo:\n host_set[%d]=%s,\
1255 buffer_set[%d].buf_ptr=%p, buffer_set[%d].size=%d\n",
1256 i, host_set[i], i, buffer_set[i].buf_ptr, i, buffer_set[i].size));
1262 * This is a function for creating file names for a set of buffers.
1266 SetBufferFileNames (char **file_set,
1267 DtDndBuffer *buffers,
1270 int null_filenames_count = 0;
1272 int first_nullfile_index = 0;
1273 Boolean NULL_FILENAMES=FALSE;
1275 DPRINTF (("Executing...SetBufferFileNames\n"));
1277 for (i = 0; i < num_of_buffers; i++)
1279 if (buffers[i].name == NULL)
1281 /* generate buffer name using Untitled as a base name */
1282 file_set[i]=BuildBufferFileName(DEFAULT_BUFFER_FILENAME,
1289 /* file name is supplied by the drag initiator */
1290 file_set[i] = XtNewString(buffers[i].name);
1293 DPRINTF(("file_set[%d]=%s\n", i, file_set[i]));
1295 } /* end for loop */
1298 /* Rename any collisions to unique names */
1299 RenameCollisions(file_set, num_of_buffers);
1306 * This is a generic function for generating a name for an untitled buffer.
1307 * A default name (Untitled) is used in conjunction with the name template
1308 * information from the types database.
1312 BuildBufferFileName (char *file_name,
1317 const char delim = '_';
1318 char *new_file_name;
1321 DPRINTF (("Executing....BuildBufferFileName\n"));
1323 /* Malloc memory and contruct the new file name */
1324 new_file_name = (char *) XtMalloc (strlen(file_name) + 1 +
1325 MAX_POSTFIX_LENGTH + 1);
1327 DPRINTF (("BuildBufferFileName: Old file name is %s\n", file_name));
1329 /* determine whether to append post fix name */
1330 if (postfix_index == -1)
1331 strcpy(new_file_name, file_name);
1333 sprintf(new_file_name,"%s%c%d", file_name, delim, postfix_index);
1335 /* Retrieve the name template if it exists and use it in the filename */
1336 new_file_name = RetrieveAndUseNameTemplateInfo(buffer,
1340 DPRINTF(("BuildBufferFileName: Returning new_file_name=%s\n", new_file_name));
1342 /* return new file name */
1343 return (new_file_name);
1349 * This is a function for building a buffer name using predfined input
1350 * and name template information from the types database.
1351 * WARNING: template_input MAY be freed. It must point to a char *.
1355 RetrieveAndUseNameTemplateInfo(
1358 char *template_input)
1361 char *name_template;
1362 char *buffer_name = NULL;
1364 name_template = DtDtsBufferToAttributeValue(buffer,
1366 DtDTS_DA_NAME_TEMPLATE,
1369 buffer_name = (char *) XtMalloc(strlen(name_template) +
1370 strlen(template_input) +
1374 sprintf(buffer_name, name_template, template_input);
1375 DtDtsFreeAttributeValue(name_template);
1376 XtFree(template_input);
1377 return(buffer_name);
1381 DtDtsFreeAttributeValue(name_template);
1382 return(template_input);
1388 * This is a function for resolving collisions in a list of buffer names.
1392 RenameCollisions( char ** list, int count )
1394 register int i, j, k, l;
1395 char flg = 0, flg2 = 0;
1397 for( i = 0; i < count; ++i )
1399 unsigned int addIndex = 1;
1401 if( *(list[i]) == 0x0 )
1407 for( j = i+1; j < count; ++j )
1409 if( strcmp( list[i], list[j] ) == 0 )
1411 RenameEntry( &(list[j]), ++addIndex );
1419 RenameEntry( &(list[l]), 1 );
1425 list[k] = (char *)malloc( strlen( DEFAULT_BUFFER_FILENAME ) + 1 );
1426 sprintf( list[k], "%s", DEFAULT_BUFFER_FILENAME );
1432 * This is a function for adding an index to a buffer name which has
1437 RenameEntry( char ** name, unsigned int addIndex )
1440 #define MAX_INT_SIZE 15
1442 char * tmpPtr, * newName;
1446 else if( **name == 0x0 )
1448 newName = (char *)XtCalloc(1,strlen(DEFAULT_BUFFER_FILENAME)+ MAX_INT_SIZE);
1449 sprintf( newName, "%s_%d", DEFAULT_BUFFER_FILENAME, addIndex );
1453 tmpPtr = strrchr( *name, '.' );
1455 newName = (char *)XtCalloc( 1, strlen( *name ) + MAX_INT_SIZE );
1457 if( tmpPtr == NULL )
1458 sprintf( newName, "%s_%d", *name, addIndex );
1459 else if( tmpPtr == *name )
1460 sprintf( newName, "%d%s", addIndex, *name );
1464 sprintf( newName, "%s_%d.%s", *name, addIndex, ++tmpPtr);
1473 * This is a generic function for freeing buffer information extracted from
1478 _DtFreeDroppedBufferInfo(char **file_set,
1479 BufferInfo *buffer_set,
1485 DPRINTF (("Executing..._DtFreeDroppedBufferInfo\n"));
1487 /* Check for Null pointers */
1488 if (file_set && buffer_set && host_set )
1490 for (i=0; i< num_of_buffers; i++ )
1492 XtFree(file_set[i]);
1493 XtFree(host_set[i]);
1496 XtFree((char *)file_set);
1497 XtFree((char *)host_set);
1498 XtFree((char *)buffer_set);
1504 * This is a generic function for determining if a buffer is executable.
1508 _DtIsBufferExecutable(
1513 char *exe_attribute;
1514 Boolean is_exe = False;
1516 exe_attribute = DtDtsBufferToAttributeValue(buffer,
1522 if (DtDtsIsTrue(exe_attribute))
1525 DtDtsFreeAttributeValue(exe_attribute);
1533 * This is a generic function for extracting file information from drop input.
1537 _DtSetDroppedFileInfo(
1538 DtDndDropCallbackStruct *drop_parameters,
1544 numFiles = drop_parameters->dropData->numItems;
1546 *file_set = (char **)XtMalloc(sizeof(char *) * numFiles);
1547 *host_set = (char **)XtMalloc(sizeof(char *) * numFiles);
1548 for(i = 0; i < numFiles; i++)
1550 (*file_set)[i] = XtNewString(drop_parameters->dropData->data.files[i]);
1551 (*host_set)[i] = home_host_name;
1553 DPRINTF(("ProcessMoveCopyLink:\n host_set[%d]=%s, file_set[%d]=%s\n",
1554 i, (*host_set)[i], i, (*file_set)[i]));
1560 * This is a generic function for copying file info extracted from drop input.
1564 _DtCopyDroppedFileInfo(
1566 char **orig_file_set,
1567 char **orig_host_set,
1568 char ***new_file_set,
1569 char ***new_host_set)
1573 *new_file_set = (char **)XtMalloc(sizeof(char *) * num_files);
1574 *new_host_set = (char **)XtMalloc(sizeof(char *) * num_files);
1575 for(i = 0; i < num_files; i++)
1577 (*new_file_set)[i] = XtNewString(orig_file_set[i]);
1578 (*new_host_set)[i] = XtNewString(orig_host_set[i]);
1584 * This is a generic function for freeing file info extracted from drop input.
1588 _DtFreeDroppedFileInfo(
1595 for(i = 0; i < num_files; i++)
1596 XtFree(file_set[i]);
1598 XtFree((char *)file_set);
1599 XtFree((char *)host_set);
1604 * This is a generic function for resolving a cannonical path from user input.
1616 char *tmp_path = NULL;
1617 char *true_path = NULL;
1618 Tt_status tt_status;
1622 *host = XtNewString(home_host_name);
1624 /* find relative path */
1625 tmp_path = path = XtNewString(input_string);
1627 /* Strip any spaces from name -- input is overwritten */
1628 path = (char *) _DtStripSpaces(path);
1630 /* Resolve, if there're any, environment variables */
1633 char command[MAXPATHLEN];
1635 memset(command, 0, sizeof(command));
1636 sprintf(command,"echo %s",path);
1638 if((pfp=popen(command,"r")) != NULL)
1642 if (NULL == (fgets(command,MAXPATHLEN,pfp)))
1645 * Try a few more reads and if the read still fails,
1646 * just use the path as is.
1649 for (i=0; i < 5; i++)
1652 if (NULL != (fgets(command,MAXPATHLEN,pfp)))
1661 int slen = strlen(command);
1662 /* need to remove the trailing newline safely*/
1664 command[slen-1] = '\0';
1667 path = XtNewString(command);
1679 /* Resolve '~' -- new memory is allocated, old memory is freed */
1681 path = _DtChangeTildeToHome(path);
1683 /* If current dir provided, check for relative path */
1684 if (path && current_dir)
1688 /* file is relative path i.e. xyz/abc */
1689 if (strcmp(current_dir, "/") == 0)
1691 tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 1);
1692 sprintf(tmp_path, "%s%s", current_dir, path);
1696 tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 2);
1697 sprintf(tmp_path, "%s/%s", current_dir, path);
1712 /* Resolve '.' or '..' -- input is overwritten, output may be NULL! */
1713 /* Save pointer to path to free if output is NULL. */
1715 path = (char *) DtEliminateDots(path);
1719 /* Resolve to local pathname */
1720 true_path = ResolveLocalPathName(*host,
1727 /* Strip off trailing '/' */
1728 dir_len = strlen(true_path);
1729 if (dir_len > 1 && *(true_path + dir_len - 1) == '/')
1730 *(true_path + dir_len - 1) = '\0';
1738 *rel_path = true_path;
1743 * This function takes a path name, and resolves any leading '~' to refer
1744 * to one of the following:
1746 * 1) if ~ or ~/path, then it resolves to the user's home directory on
1749 * 2) if ~user or ~user/path, then it resolves to the specified user's
1750 * home directory on the home host.
1752 * This function never resolves to any host but the home host, since we
1753 * have no way of determining a user's home directory on any system other
1754 * than the home system.
1758 _DtChangeTildeToHome (
1763 struct passwd * pwInfo;
1765 if ((input_string[1] != '\0') && (input_string[1] != '/'))
1769 /* ~user or ~user/path format */
1771 /* is there a path? */
1772 path = DtStrchr(input_string, '/');
1777 if ((pwInfo = getpwnam(input_string + 1)) == NULL)
1779 /* user doesn't exist */
1787 /* ~user/path format */
1791 if (strcmp(pwInfo->pw_dir, "/") == 0)
1793 /* We don't want to end up with double '/' in the path */
1794 full_path = (char *) XtMalloc(strlen(path) + 1);
1795 strcpy(full_path, path);
1799 full_path = (char *) XtMalloc(strlen(pwInfo->pw_dir) +
1801 sprintf(full_path, "%s%s", pwInfo->pw_dir, path);
1808 full_path = XtMalloc(strlen(pwInfo->pw_dir) + 1);
1809 strcpy(full_path, pwInfo->pw_dir);
1812 else if (input_string[1])
1816 /* NOTE: users_home_dir has trailing '/' */
1817 full_path = XtMalloc(strlen(users_home_dir) + strlen(input_string+2) + 1);
1818 sprintf(full_path, "%s%s", users_home_dir, (input_string + 2));
1824 full_path = XtMalloc(strlen(users_home_dir) + 1);
1825 strcpy(full_path, users_home_dir);
1828 XtFree(input_string);
1834 * This function checks for spaces in filenames.
1836 #ifdef _CHECK_FOR_SPACES
1839 _DtSpacesInFileNames(
1845 for (i = 0; i < fileCount; i++)
1847 fileNames[i] = (char *) _DtStripSpaces(fileNames[i]);
1849 if (DtStrchr (fileNames[i], ' ') != NULL ||
1850 DtStrchr (fileNames[i], '\t') != NULL)
1860 * This resolves the path for an appmanager object to its true path.
1864 _DtResolveAppManPath(
1866 char *restricted_dir )
1868 if (strlen(path) > strlen(restricted_dir))
1870 char *linkDir, *ptr, *tmpPath;
1872 linkDir = path + strlen(restricted_dir) + 1;
1873 ptr = DtStrchr(linkDir, '/');
1877 linkDir = _DtFollowLink(path);
1879 tmpPath = XtMalloc(strlen(linkDir) + strlen(ptr) + 1);
1880 sprintf(tmpPath, "%s%s", linkDir, ptr);
1886 linkDir = _DtFollowLink(path);
1888 path = XtNewString(linkDir);