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>
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)) > 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,
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 sprintf(number, "%d", firstId);
408 (*dialogArray)[i] = _DtGetResourceDialogData(dialogId, dataBase, nameList);
416 _DtSaveSubdialogArray (
419 DialogData ** dialogArray,
428 nameList[nameCount] = number;
429 nameList[nameCount + 1] = NULL;
431 for (i = 0; i < dialogCount; i++)
433 sprintf(number, "%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);
794 if (iconGadget->icon.pixmap == 0 ||
795 iconGadget->icon.pixmap_width == 0 ||
796 iconGadget->icon.pixmap_height == 0 ||
797 (Dimension)iconGadget->icon.pixmap_width > (Dimension)instanceWidth ||
798 (Dimension)iconGadget->icon.pixmap_height > (Dimension)instanceHeight)
801 pixmapData->iconName = DtDtsDataTypeToAttributeValue(
803 DtDTS_DA_ICON, NULL);
805 /* retrieve icon file name */
806 if (pixmapData->iconFileName != NULL)
808 XtFree(pixmapData->iconFileName);
809 pixmapData->iconFileName = NULL;
812 if (pixmapData->size == LARGE)
813 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
814 pixmapData->instanceIconName,
815 pixmapData->iconName,
816 pixmapData->hostPrefix,
819 pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
820 pixmapData->instanceIconName,
821 pixmapData->iconName,
822 pixmapData->hostPrefix,
827 XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
828 XtSetValues((Widget) iconGadget, args, 1);
830 DtDtsFreeAttributeValue(pixmapData->iconName);
835 DtDtsFreeAttributeValue(pixmapData->iconName);
838 DtDtsFreeAttributeValue(pixmapData->hostPrefix);
839 if (pixmapData->iconFileName)
840 XtFree(pixmapData->iconFileName);
842 XtFree((char *) pixmapData);
847 * This is a function for checking for a datatype property.
851 _DtCheckForDataTypeProperty(
859 Boolean found = False;
862 properties = DtDtsDataTypeToAttributeValue(dataType,
870 while (props = DtStrchr(props, ','))
873 if (strcmp(prop, property) == 0)
885 if (strcmp(prop, property) == 0)
889 DtDtsFreeAttributeValue(properties);
897 * This is a function for compiling a vectorized action list for a data type.
901 _DtCompileActionVector(
906 char **vector = NULL;
908 actions = DtDtsDataTypeToAttributeValue(dataType,
909 DtDTS_DA_ACTION_LIST,
912 vector = (char **) _DtVectorizeInPlace(actions, ',');
919 * This is a generic function for retrieving the default action for a data
924 _DtRetrieveDefaultAction(
930 char *default_action = NULL;
932 actions = DtDtsDataTypeToAttributeValue(dataType,
933 DtDTS_DA_ACTION_LIST,
937 if (acts = DtStrchr(actions, ','))
939 default_action = XtNewString(actions);
941 DtDtsFreeAttributeValue(actions);
944 return(default_action);
949 * This is a function for building a title for a File Manager view.
954 FileMgrData *file_mgr_data )
957 char *title, *ptr, *fileLabel, *fileName;
959 if (fileLabel = DtDtsFileToAttributeValue(file_mgr_data->current_directory,
962 else if (fileName = strrchr(file_mgr_data->current_directory, '/'))
967 if (file_mgr_data->title)
969 if (file_mgr_data->toolbox &&
970 strcmp(file_mgr_data->current_directory,
971 file_mgr_data->restricted_directory) != 0)
973 title = (char *)XtMalloc(strlen(file_mgr_data->title) +
975 4); /* Need for blank dash blank NULL */
976 sprintf(title, "%s - %s", file_mgr_data->title, ptr);
980 title = XtNewString(file_mgr_data->title);
985 if (strcmp(file_mgr_data->current_directory, "/") == 0 && !fileLabel)
987 title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
988 strlen(file_mgr_data->host) +
990 5); /* Need for blank dash blank colon NULL */
991 sprintf( title, "%s - %s:%s", (GETMESSAGE(12, 7, "File Manager")),
997 title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
999 4); /* Need for blank dash blank NULL */
1000 sprintf( title, "%s - %s", (GETMESSAGE(12, 7, "File Manager")), ptr);
1004 DtDtsFreeAttributeValue(fileLabel);
1010 * This is a function for building a path from the directory name
1011 * and file name pieces of a FileViewData structure.
1015 _DtGetSelectedFilePath(
1016 FileViewData *selected_file )
1023 directory = ((DirectorySet *)selected_file->directory_set)->name;
1024 file = selected_file->file_data->file_name;
1026 if (strcmp(directory, "/") == 0)
1028 path = XtMalloc(strlen(directory) + strlen(file) + 1);
1029 sprintf(path, "%s%s", directory, file);
1033 path = XtMalloc(strlen(directory) + strlen(file) + 2);
1034 sprintf(path, "%s/%s", directory, file);
1042 * This is a generic function for building action parameters from an array of
1043 * file view data structures.
1047 _DtBuildActionArgsWithSelectedFiles(
1048 FileViewData **selection_list,
1050 DtActionArg **action_args,
1056 *action_args = (DtActionArg *)
1057 XtCalloc(1, sizeof(DtActionArg) * selected_count);
1063 for(i = 0; i < selected_count; i++)
1065 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1066 ((*action_args)[(*arg_count)++]).u.file.name =
1067 _DtGetSelectedFilePath(selection_list[i]);
1074 _DtBuildActionArgsWithDTSelectedFiles(
1075 DesktopRec **selection_list,
1077 DtActionArg **action_args,
1083 *action_args = (DtActionArg *)
1084 XtCalloc(1, sizeof(DtActionArg) * selected_count);
1090 for(i = 0; i < selected_count; i++)
1092 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1093 ((*action_args)[(*arg_count)++]).u.file.name =
1094 _DtGetSelectedFilePath(selection_list[i]->file_view_data);
1101 * This is a generic function for building action parameters from drag and drop
1106 _DtBuildActionArgsWithDroppedFiles(
1107 FileViewData *dropped_on_obj,
1108 DtDndDropCallbackStruct *drop_parameters,
1109 DtActionArg **action_args,
1116 *action_args = (DtActionArg *) XtCalloc
1117 (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
1119 *action_args = (DtActionArg *) XtCalloc
1120 (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
1128 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1129 ((*action_args)[(*arg_count)++]).u.file.name =
1130 _DtGetSelectedFilePath(dropped_on_obj);
1133 for(i = 0; i < drop_parameters->dropData->numItems; i++)
1135 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1136 ((*action_args)[(*arg_count)++]).u.file.name =
1137 XtNewString(drop_parameters->dropData->data.files[i]);
1144 * This is a generic function for building action parameters from drag and drop
1145 * buffer information.
1150 _DtBuildActionArgsWithDroppedBuffers(
1151 FileViewData *dropped_on_obj,
1152 DtDndDropCallbackStruct *drop_parameters,
1153 DtActionArg **action_args,
1160 *action_args = (DtActionArg *) XtCalloc
1161 (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
1163 *action_args = (DtActionArg *) XtCalloc
1164 (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
1169 DtActionBuffer buffer_arg = {NULL, 0, NULL, NULL, False};
1173 ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
1174 ((*action_args)[(*arg_count)++]).u.file.name =
1175 _DtGetSelectedFilePath(dropped_on_obj);
1178 for(i = 0; i < drop_parameters->dropData->numItems; i++)
1180 buffer_arg.bp = drop_parameters->dropData->data.buffers[i].bp;
1181 buffer_arg.size = drop_parameters->dropData->data.buffers[i].size;
1182 buffer_arg.name = drop_parameters->dropData->data.buffers[i].name;
1184 ((*action_args)[(*arg_count)]).argClass = DtACTION_BUFFER;
1185 ((*action_args)[(*arg_count)++]).u.buffer = buffer_arg;
1192 * This is a generic function for freeing action parameters.
1197 DtActionArg *action_args,
1203 for (i = 0; i < arg_count; i++)
1205 if (action_args[i].argClass == DtACTION_FILE)
1207 XtFree(action_args[i].u.file.name);
1208 action_args[i].u.file.name = NULL;
1212 XtFree((char *) action_args);
1216 /************************************************************************
1217 * The following functions deal with Buffer Manipulation and Naming
1218 ************************************************************************/
1221 * This is a generic function for extracting buffer information from
1226 _DtSetDroppedBufferInfo(char **file_set,
1227 BufferInfo *buffer_set,
1229 DtDndDropCallbackStruct *drop_parameters)
1233 int num_of_buffers = drop_parameters->dropData->numItems;
1235 DtDndBuffer *buffers = drop_parameters->dropData->data.buffers;
1238 DPRINTF (("Executing..._DtSetDroppedBufferInfo\n"));
1240 /* Initialize file_set and ensure of unique file names for unamed buffers*/
1241 SetBufferFileNames(file_set, buffers, num_of_buffers);
1243 for (i= 0; i < num_of_buffers; i++)
1246 (buffer_set[i]).buf_ptr = buffers[i].bp;
1247 (buffer_set[i]).size = buffers[i].size;
1249 host_set[i] = XtNewString(home_host_name);
1251 DPRINTF(("_DtSetDroppedBufferInfo:\n host_set[%d]=%s,\
1252 buffer_set[%d].buf_ptr=%p, buffer_set[%d].size=%d\n",
1253 i, host_set[i], i, buffer_set[i].buf_ptr, i, buffer_set[i].size));
1259 * This is a function for creating file names for a set of buffers.
1263 SetBufferFileNames (char **file_set,
1264 DtDndBuffer *buffers,
1267 int null_filenames_count = 0;
1269 int first_nullfile_index = 0;
1270 Boolean NULL_FILENAMES=FALSE;
1272 DPRINTF (("Executing...SetBufferFileNames\n"));
1274 for (i = 0; i < num_of_buffers; i++)
1276 if (buffers[i].name == NULL)
1278 /* generate buffer name using Untitled as a base name */
1279 file_set[i]=BuildBufferFileName(DEFAULT_BUFFER_FILENAME,
1286 /* file name is supplied by the drag initiator */
1287 file_set[i] = XtNewString(buffers[i].name);
1290 DPRINTF(("file_set[%d]=%s\n", i, file_set[i]));
1292 } /* end for loop */
1295 /* Rename any collisions to unique names */
1296 RenameCollisions(file_set, num_of_buffers);
1303 * This is a generic function for generating a name for an untitled buffer.
1304 * A default name (Untitled) is used in conjunction with the name template
1305 * information from the types database.
1309 BuildBufferFileName (char *file_name,
1314 const char delim = '_';
1315 char *new_file_name;
1318 DPRINTF (("Executing....BuildBufferFileName\n"));
1320 /* Malloc memory and contruct the new file name */
1321 new_file_name = (char *) XtMalloc (strlen(file_name) + 1 +
1322 MAX_POSTFIX_LENGTH + 1);
1324 DPRINTF (("BuildBufferFileName: Old file name is %s\n", file_name));
1326 /* determine whether to append post fix name */
1327 if (postfix_index == -1)
1328 strcpy(new_file_name, file_name);
1330 sprintf(new_file_name,"%s%c%d", file_name, delim, postfix_index);
1332 /* Retrieve the name template if it exists and use it in the filename */
1333 new_file_name = RetrieveAndUseNameTemplateInfo(buffer,
1337 DPRINTF(("BuildBufferFileName: Returning new_file_name=%s\n", new_file_name));
1339 /* return new file name */
1340 return (new_file_name);
1346 * This is a function for building a buffer name using predfined input
1347 * and name template information from the types database.
1348 * WARNING: template_input will be freed. It must point to a char *.
1352 RetrieveAndUseNameTemplateInfo(
1355 char *template_input)
1358 char *name_template;
1359 char *buffer_name = NULL;
1361 name_template = DtDtsBufferToAttributeValue(buffer,
1363 DtDTS_DA_NAME_TEMPLATE,
1366 buffer_name = (char *) XtMalloc(strlen(name_template) +
1367 strlen(template_input) +
1371 sprintf(buffer_name, name_template, template_input);
1372 DtDtsFreeAttributeValue(name_template);
1373 XtFree(template_input);
1374 return(buffer_name);
1378 return(template_input);
1384 * This is a function for resolving collisions in a list of buffer names.
1388 RenameCollisions( char ** list, int count )
1390 register int i, j, k, l;
1391 char flg = 0, flg2 = 0;
1393 for( i = 0; i < count; ++i )
1395 unsigned int addIndex = 1;
1397 if( *(list[i]) == 0x0 )
1403 for( j = i+1; j < count; ++j )
1405 if( strcmp( list[i], list[j] ) == 0 )
1407 RenameEntry( &(list[j]), ++addIndex );
1415 RenameEntry( &(list[l]), 1 );
1421 list[k] = (char *)malloc( strlen( DEFAULT_BUFFER_FILENAME ) + 1 );
1422 sprintf( list[k], "%s", DEFAULT_BUFFER_FILENAME );
1428 * This is a function for adding an index to a buffer name which has
1433 RenameEntry( char ** name, unsigned int addIndex )
1436 #define MAX_INT_SIZE 15
1438 char * tmpPtr, * newName;
1442 else if( **name == 0x0 )
1444 newName = (char *)XtCalloc(1,strlen(DEFAULT_BUFFER_FILENAME)+ MAX_INT_SIZE);
1445 sprintf( newName, "%s_%d", DEFAULT_BUFFER_FILENAME, addIndex );
1449 tmpPtr = strrchr( *name, '.' );
1451 newName = (char *)XtCalloc( 1, strlen( *name ) + MAX_INT_SIZE );
1453 if( tmpPtr == NULL )
1454 sprintf( newName, "%s_%d", *name, addIndex );
1455 else if( tmpPtr == *name )
1456 sprintf( newName, "%d%s", addIndex, *name );
1460 sprintf( newName, "%s_%d.%s", *name, addIndex, ++tmpPtr);
1469 * This is a generic function for freeing buffer information extracted from
1474 _DtFreeDroppedBufferInfo(char **file_set,
1475 BufferInfo *buffer_set,
1481 DPRINTF (("Executing..._DtFreeDroppedBufferInfo\n"));
1483 /* Check for Null pointers */
1484 if (file_set && buffer_set && host_set )
1486 for (i=0; i< num_of_buffers; i++ )
1488 XtFree(file_set[i]);
1489 XtFree(host_set[i]);
1492 XtFree((char *)file_set);
1493 XtFree((char *)host_set);
1494 XtFree((char *)buffer_set);
1500 * This is a generic function for determining if a buffer is executable.
1504 _DtIsBufferExecutable(
1509 char *exe_attribute;
1510 Boolean is_exe = False;
1512 exe_attribute = DtDtsBufferToAttributeValue(buffer,
1518 if (DtDtsIsTrue(exe_attribute))
1521 DtDtsFreeAttributeValue(exe_attribute);
1529 * This is a generic function for extracting file information from drop input.
1533 _DtSetDroppedFileInfo(
1534 DtDndDropCallbackStruct *drop_parameters,
1540 numFiles = drop_parameters->dropData->numItems;
1542 *file_set = (char **)XtMalloc(sizeof(char *) * numFiles);
1543 *host_set = (char **)XtMalloc(sizeof(char *) * numFiles);
1544 for(i = 0; i < numFiles; i++)
1546 (*file_set)[i] = XtNewString(drop_parameters->dropData->data.files[i]);
1547 (*host_set)[i] = home_host_name;
1549 DPRINTF(("ProcessMoveCopyLink:\n host_set[%d]=%s, file_set[%d]=%s\n",
1550 i, (*host_set)[i], i, (*file_set)[i]));
1556 * This is a generic function for copying file info extracted from drop input.
1560 _DtCopyDroppedFileInfo(
1562 char **orig_file_set,
1563 char **orig_host_set,
1564 char ***new_file_set,
1565 char ***new_host_set)
1569 *new_file_set = (char **)XtMalloc(sizeof(char *) * num_files);
1570 *new_host_set = (char **)XtMalloc(sizeof(char *) * num_files);
1571 for(i = 0; i < num_files; i++)
1573 (*new_file_set)[i] = XtNewString(orig_file_set[i]);
1574 (*new_host_set)[i] = XtNewString(orig_host_set[i]);
1580 * This is a generic function for freeing file info extracted from drop input.
1584 _DtFreeDroppedFileInfo(
1591 for(i = 0; i < num_files; i++)
1592 XtFree(file_set[i]);
1594 XtFree((char *)file_set);
1595 XtFree((char *)host_set);
1600 * This is a generic function for resolving a cannonical path from user input.
1612 char *tmp_path = NULL;
1613 char *true_path = NULL;
1614 Tt_status tt_status;
1618 *host = XtNewString(home_host_name);
1620 /* find relative path */
1621 tmp_path = path = XtNewString(input_string);
1623 /* Strip any spaces from name -- input is overwritten */
1624 path = (char *) _DtStripSpaces(path);
1626 /* Resolve, if there're any, environment variables */
1629 char command[MAXPATHLEN];
1631 sprintf(command,"echo %s",path);
1633 if((pfp=popen(command,"r")) != NULL)
1637 if (NULL == (fgets(command,MAXPATHLEN,pfp)))
1640 * Try a few more reads and if the read still fails,
1641 * just use the path as is.
1644 for (i=0; i < 5; i++)
1647 if (NULL != (fgets(command,MAXPATHLEN,pfp)))
1656 command[strlen(command)-1] = '\0';
1658 path = XtNewString(command);
1664 /* Resolve '~' -- new memory is allocated, old memory is freed */
1666 path = _DtChangeTildeToHome(path);
1668 /* If current dir provided, check for relative path */
1669 if (path && current_dir)
1673 /* file is relative path i.e. xyz/abc */
1674 if (strcmp(current_dir, "/") == 0)
1676 tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 1);
1677 sprintf(tmp_path, "%s%s", current_dir, path);
1681 tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 2);
1682 sprintf(tmp_path, "%s/%s", current_dir, path);
1697 /* Resolve '.' or '..' -- input is overwritten, output may be NULL! */
1698 /* Save pointer to path to free if output is NULL. */
1700 path = (char *) DtEliminateDots(path);
1704 /* Resolve to local pathname */
1705 true_path = ResolveLocalPathName(*host,
1712 /* Strip off trailing '/' */
1713 dir_len = strlen(true_path);
1714 if (dir_len > 1 && *(true_path + dir_len - 1) == '/')
1715 *(true_path + dir_len - 1) = '\0';
1723 *rel_path = true_path;
1728 * This function takes a path name, and resolves any leading '~' to refer
1729 * to one of the following:
1731 * 1) if ~ or ~/path, then it resolves to the user's home directory on
1734 * 2) if ~user or ~user/path, then it resolves to the specified user's
1735 * home directory on the home host.
1737 * This function never resolves to any host but the home host, since we
1738 * have no way of determining a user's home directory on any system other
1739 * than the home system.
1743 _DtChangeTildeToHome (
1748 struct passwd * pwInfo;
1750 if ((input_string[1] != '\0') && (input_string[1] != '/'))
1754 /* ~user or ~user/path format */
1756 /* is there a path? */
1757 path = DtStrchr(input_string, '/');
1762 if ((pwInfo = getpwnam(input_string + 1)) == NULL)
1764 /* user doesn't exist */
1772 /* ~user/path format */
1776 if (strcmp(pwInfo->pw_dir, "/") == 0)
1778 /* We don't want to end up with double '/' in the path */
1779 full_path = (char *) XtMalloc(strlen(path) + 1);
1780 strcpy(full_path, path);
1784 full_path = (char *) XtMalloc(strlen(pwInfo->pw_dir) +
1786 sprintf(full_path, "%s%s", pwInfo->pw_dir, path);
1793 full_path = XtMalloc(strlen(pwInfo->pw_dir) + 1);
1794 strcpy(full_path, pwInfo->pw_dir);
1797 else if (input_string[1])
1801 /* NOTE: users_home_dir has trailing '/' */
1802 full_path = XtMalloc(strlen(users_home_dir) + strlen(input_string+2) + 1);
1803 sprintf(full_path, "%s%s", users_home_dir, (input_string + 2));
1809 full_path = XtMalloc(strlen(users_home_dir) + 1);
1810 strcpy(full_path, users_home_dir);
1813 XtFree(input_string);
1819 * This function checks for spaces in filenames.
1821 #ifdef _CHECK_FOR_SPACES
1824 _DtSpacesInFileNames(
1830 for (i = 0; i < fileCount; i++)
1832 fileNames[i] = (char *) _DtStripSpaces(fileNames[i]);
1834 if (DtStrchr (fileNames[i], ' ') != NULL ||
1835 DtStrchr (fileNames[i], '\t') != NULL)
1845 * This resolves the path for an appmanager object to its true path.
1849 _DtResolveAppManPath(
1851 char *restricted_dir )
1853 if (strlen(path) > strlen(restricted_dir))
1855 char *linkDir, *ptr, *tmpPath;
1857 linkDir = path + strlen(restricted_dir) + 1;
1858 ptr = DtStrchr(linkDir, '/');
1862 linkDir = _DtFollowLink(path);
1864 tmpPath = XtMalloc(strlen(linkDir) + strlen(ptr) + 1);
1865 sprintf(tmpPath, "%s%s", linkDir, ptr);
1871 linkDir = _DtFollowLink(path);
1873 path = XtNewString(linkDir);