SharedProcs.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  23. /* $XConsortium: SharedProcs.c /main/7 1996/10/03 14:01:42 drk $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. *
  27. * FILE: SharedProcs.c
  28. *
  29. * COMPONENT_NAME: Desktop File Manager (dtfile)
  30. *
  31. * Description: Contains the set of functions which are of general
  32. * use to all DT clients.
  33. *
  34. * FUNCTIONS: BuildBufferFileName
  35. * RenameCollisions
  36. * RenameEntry
  37. * RetrieveAndUseNameTemplateInfo
  38. * SetBufferFileNames
  39. * _DtAddOneSubdialog
  40. * _DtBuildActionArgsWithDroppedBuffers
  41. * _DtBuildActionArgsWithDroppedFiles
  42. * _DtBuildActionArgsWithSelectedFiles
  43. * _DtBuildActionArgsWithDTSelectedFiles
  44. * _DtBuildFMTitle
  45. * _DtBuildPath
  46. * _DtChangeTildeToHome
  47. * _DtCheckAndFreePixmapData
  48. * _DtCheckForDataTypeProperty
  49. * _DtCompileActionVector
  50. * _DtCopyDroppedFileInfo
  51. * _DtDestroySubdialog
  52. * _DtDestroySubdialogArray
  53. * _DtDuplicateDialogNameList
  54. * _DtFollowLink
  55. * _DtFreeActionArgs
  56. * _DtFreeDroppedBufferInfo
  57. * _DtFreeDroppedFileInfo
  58. * _DtGenericDestroy
  59. * _DtGenericMapWindow
  60. * _DtGenericUpdateWindowPosition
  61. * _DtGetSelectedFilePath
  62. * _DtHideOneSubdialog
  63. * _DtIsBufferExecutable
  64. * _DtLoadSubdialogArray
  65. * _DtMappedCB
  66. * _DtPName
  67. * _DtPathFromInput
  68. * _DtResolveAppManPath
  69. * _DtRetrieveDefaultAction
  70. * _DtRetrievePixmapData
  71. * _DtSaveSubdialogArray
  72. * _DtSetDroppedBufferInfo
  73. * _DtSetDroppedFileInfo
  74. * _DtSpacesInFileNames
  75. * _DtStringsAreEquivalent
  76. *
  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.
  81. *
  82. ****************************************************************************
  83. ************************************<+>*************************************/
  84. #include <sys/types.h>
  85. #include <sys/stat.h>
  86. #include <errno.h>
  87. #include <fcntl.h>
  88. #include <limits.h>
  89. #include <stdio.h>
  90. #include <time.h>
  91. #include <pwd.h>
  92. #include <ctype.h>
  93. #include <Xm/Xm.h>
  94. #include <Xm/XmP.h>
  95. #include <Xm/VendorSEP.h>
  96. #include <Xm/MessageB.h>
  97. #include <Xm/RowColumn.h>
  98. #include <Xm/MwmUtil.h>
  99. #include <Xm/Protocols.h>
  100. #include <X11/ShellP.h>
  101. #include <X11/Shell.h>
  102. #include <X11/Xatom.h>
  103. /* Copied from Xm/BaseClassI.h */
  104. extern XmWidgetExtData _XmGetWidgetExtData(
  105. Widget widget,
  106. #if NeedWidePrototypes
  107. unsigned int extType) ;
  108. #else
  109. unsigned char extType) ;
  110. #endif /* NeedWidePrototypes */
  111. #include <Dt/DtP.h>
  112. #include <Dt/Connect.h>
  113. #include <Dt/DtNlUtils.h>
  114. #include <Dt/Dts.h>
  115. #include <Dt/Icon.h>
  116. #include <Dt/IconP.h>
  117. #include <Dt/IconFile.h>
  118. #include <Dt/Action.h>
  119. #include <Dt/Dnd.h>
  120. #include <Dt/Utility.h>
  121. #include <Dt/SharedProcs.h>
  122. #include <Tt/tttk.h>
  123. #include "Encaps.h"
  124. #include "FileMgr.h"
  125. #include "Desktop.h"
  126. #include "Common.h"
  127. #include "Main.h"
  128. #include "SharedProcs.h"
  129. extern char *pathcollapse();
  130. /* Defines */
  131. #define RW_ALL S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
  132. /* Global controlling whether auto-positioning is enabled */
  133. Boolean disableDialogAutoPlacement = False;
  134. /******** Static Function Declarations ********/
  135. static void SetBufferFileNames (
  136. char **file_set,
  137. DtDndBuffer *buffers,
  138. int num_of_buffers) ;
  139. static char * BuildBufferFileName (
  140. char *file_name,
  141. int postfix_index,
  142. void *buffer,
  143. int buffer_size) ;
  144. static char * RetrieveAndUseNameTemplateInfo(
  145. void *buffer,
  146. int buffer_size,
  147. char *template_input) ;
  148. static void RenameEntry(
  149. char **name,
  150. unsigned int addIndex) ;
  151. static void RenameCollisions(
  152. char **list,
  153. int count) ;
  154. /******** End Static Function Declarations ********/
  155. /************************************************************************
  156. *
  157. * _DtPName
  158. * Returns the parent directory of its argument.
  159. * Does this by looking for the last "/" in the name, and
  160. * NULL'ing it out.
  161. *
  162. ************************************************************************/
  163. char *
  164. _DtPName(
  165. char *name )
  166. {
  167. char * q;
  168. static char pnam[MAXPATHLEN];
  169. static char dot[] = ".";
  170. strcpy(pnam, name);
  171. q = strrchr(pnam, '/');
  172. if (q == NULL)
  173. q = pnam;
  174. else if ((q == pnam) &&
  175. #ifdef NLS16
  176. (mblen(q, MB_CUR_MAX) == 1) &&
  177. #endif
  178. (*q == '/'))
  179. {
  180. q++;
  181. }
  182. *q = '\0';
  183. return(pnam[0] ? pnam : dot);
  184. }
  185. /*
  186. * Given a filename, follow it to the end of its link. Returns NULL if
  187. * a recursive symbolic link is found.
  188. *
  189. * Note, the path returned is a static buffer, and should not be freed by
  190. * the calling function.
  191. */
  192. char *
  193. _DtFollowLink (
  194. char * path)
  195. {
  196. char link_path[MAXPATHLEN];
  197. static char file[MAXPATHLEN];
  198. int link_len;
  199. char * end;
  200. int history_count;
  201. int history_size;
  202. char ** history;
  203. int i;
  204. /* Used to check for symbolic link loops */
  205. history_count = 0;
  206. history_size = 100;
  207. history = (char **)XtMalloc(sizeof(char *) * history_size);
  208. strcpy(file, path);
  209. while ((link_len = readlink(file, link_path, MAXPATHLEN - 1)) > 0)
  210. {
  211. link_path[link_len] = 0;
  212. /* Force the link to be an absolute path, if necessary */
  213. if (link_path[0] != '/')
  214. {
  215. /* Relative paths are relative to the current directory */
  216. end = strrchr(file, '/') + 1;
  217. *end = '\0';
  218. strcat(file, link_path);
  219. }
  220. else
  221. strcpy(file, link_path);
  222. /* Check for a recursive loop; abort if found */
  223. for (i = 0; i < history_count; i++)
  224. {
  225. if (strcmp(file, history[i]) == 0)
  226. {
  227. for (i = 0; i < history_count; i++)
  228. XtFree(history[i]);
  229. XtFree((char *)history);
  230. history = NULL;
  231. return(NULL);
  232. }
  233. }
  234. /* Add to the history list */
  235. if (history_count >= history_size)
  236. {
  237. history_size += 100;
  238. history = (char **)XtRealloc((char *)history,
  239. sizeof(char *) * history_size);
  240. }
  241. history[history_count++] = XtNewString(file);
  242. }
  243. /* Free up the history list */
  244. for (i = 0; i < history_count; i++)
  245. XtFree(history[i]);
  246. XtFree((char *)history);
  247. history = NULL;
  248. return(file);
  249. }
  250. /************************************************************************
  251. *
  252. * _DtStringsAreEquivalent
  253. * Compare two strings and return true if equal.
  254. * The comparison is on lower cased strings. It is the callers
  255. * responsibility to ensure that test_str is already lower cased.
  256. *
  257. ************************************************************************/
  258. Boolean
  259. _DtStringsAreEquivalent(
  260. char *in_str,
  261. char *test_str )
  262. {
  263. #ifdef NLS16
  264. wchar_t c1;
  265. wchar_t c2;
  266. int c1size, c2size;
  267. #endif
  268. int i;
  269. int j;
  270. #ifdef NLS16
  271. if (is_multibyte)
  272. {
  273. for (;;)
  274. {
  275. /* Convert each character from multibyte to wide format */
  276. c1size = mbtowc(&c1, in_str, MB_CUR_MAX);
  277. c2size = mbtowc(&c2, test_str, MB_CUR_MAX);
  278. /* No match, if the two characters have different byte counts */
  279. if (c1size != c2size)
  280. return(False);
  281. /* Do case conversion only for single byte characters */
  282. if (c1size == 1)
  283. {
  284. if (isupper((int) c1))
  285. c1 = tolower((int) c1);
  286. }
  287. /* See if the two wide characters match */
  288. if (c1 != c2)
  289. return(False);
  290. /* Are we at the end of the string? */
  291. if (c1 == '\0')
  292. return(True);
  293. /* Keep comparing */
  294. in_str += c1size;
  295. test_str += c2size;
  296. }
  297. }
  298. else
  299. #endif
  300. {
  301. for (;;)
  302. {
  303. i = *in_str;
  304. j = *test_str;
  305. if (isupper (i)) i = tolower (i);
  306. if (i != j) return (False);
  307. if (i == 0) return (True);
  308. in_str++;
  309. test_str++;
  310. }
  311. }
  312. }
  313. void
  314. _DtDuplicateDialogNameList (
  315. char ** nameList,
  316. char ** newNameList,
  317. int newNameListSize,
  318. int * nameCount )
  319. {
  320. int i;
  321. /* Get a copy of the name list to be used to build new name lists. */
  322. *nameCount = 0;
  323. while (nameList[*nameCount] != NULL)
  324. {
  325. newNameList[*nameCount] = nameList[*nameCount];
  326. (*nameCount)++;
  327. }
  328. /* NULL out any remaining array entries */
  329. for (i = (*nameCount); i < newNameListSize; i++)
  330. newNameList[i] = NULL;
  331. }
  332. void
  333. _DtLoadSubdialogArray (
  334. char ** nameList,
  335. int nameCount,
  336. DialogData *** dialogArray,
  337. int dialogCount,
  338. int dialogId,
  339. XrmDatabase dataBase,
  340. int firstId )
  341. {
  342. int i;
  343. static char number[10];
  344. /* Load sub-dialogs */
  345. nameList[nameCount] = number;
  346. nameList[nameCount + 1] = NULL;
  347. /* Get text annotation dialogs */
  348. *dialogArray = (DialogData **) XtMalloc(sizeof(DialogData *) * dialogCount);
  349. for (i = 0; i < dialogCount; i++)
  350. {
  351. snprintf(number, 10, "%d", firstId);
  352. (*dialogArray)[i] = _DtGetResourceDialogData(dialogId, dataBase, nameList);
  353. firstId++;
  354. }
  355. }
  356. void
  357. _DtSaveSubdialogArray (
  358. char ** nameList,
  359. int nameCount,
  360. DialogData ** dialogArray,
  361. int dialogCount,
  362. int fd,
  363. int firstId )
  364. {
  365. int i;
  366. static char number[10];
  367. nameList[nameCount] = number;
  368. nameList[nameCount + 1] = NULL;
  369. for (i = 0; i < dialogCount; i++)
  370. {
  371. snprintf(number, 10, "%d", firstId);
  372. _DtWriteDialogData(dialogArray[i], fd, nameList);
  373. firstId++;
  374. }
  375. }
  376. void
  377. _DtDestroySubdialogArray (
  378. DialogData ** dialogArray,
  379. int dialogCount )
  380. {
  381. int i;
  382. for (i = 0; i < dialogCount; i++)
  383. {
  384. if (_DtIsDialogShowing(dialogArray[i]))
  385. _DtHideDialog(dialogArray[i], False);
  386. _DtFreeDialogData(dialogArray[i]);
  387. }
  388. XtFree((char *)dialogArray);
  389. }
  390. void
  391. _DtDestroySubdialog (
  392. DialogData * dialogData )
  393. {
  394. if (dialogData)
  395. {
  396. if (_DtIsDialogShowing(dialogData))
  397. _DtHideDialog(dialogData, False);
  398. _DtFreeDialogData(dialogData);
  399. }
  400. }
  401. void
  402. _DtHideOneSubdialog (
  403. DialogData * dialogData,
  404. DialogData *** dialogArray,
  405. int * dialogCountPtr )
  406. {
  407. int i, j;
  408. for (i = 0; i < *dialogCountPtr; i++)
  409. {
  410. if (dialogData == (*dialogArray)[i])
  411. {
  412. for (j = i; j < (*dialogCountPtr) - 1; j++)
  413. (*dialogArray)[j] = (*dialogArray)[j + 1];
  414. break;
  415. }
  416. }
  417. /* Free or decrease the size of the dialog data list */
  418. (*dialogCountPtr)--;
  419. if (*dialogCountPtr == 0)
  420. {
  421. XtFree((char *)*dialogArray);
  422. *dialogArray = NULL;
  423. }
  424. else
  425. {
  426. *dialogArray = (DialogData **)
  427. XtRealloc((char *)*dialogArray,
  428. sizeof(DialogData *) * (*dialogCountPtr));
  429. }
  430. }
  431. void
  432. _DtAddOneSubdialog (
  433. DialogData * dialogData,
  434. DialogData *** dialogArray,
  435. int * dialogCountPtr )
  436. {
  437. int count;
  438. count = *dialogCountPtr;
  439. (*dialogCountPtr)++;
  440. (*dialogArray) = (DialogData **) XtRealloc((char *)(*dialogArray),
  441. sizeof(DialogData *) * (*dialogCountPtr));
  442. (*dialogArray)[count] = dialogData;
  443. }
  444. /*
  445. * This function acts as a frontend to the encapsulator's map callback
  446. * function. If we are in the middle of a restore session, then we don't
  447. * want the map callback to alter the placement of the dialog, so we will
  448. * not call the encapsulator's function.
  449. */
  450. void
  451. _DtMappedCB(
  452. Widget w,
  453. XtPointer client_data,
  454. XtPointer call_data )
  455. {
  456. if (!disableDialogAutoPlacement)
  457. _DtmapCB(w,client_data,call_data);
  458. XtRemoveCallback(w, XmNpopupCallback, (XtCallbackProc)_DtMappedCB, client_data);
  459. }
  460. /*
  461. * This is the generic function for registering the map callback.
  462. */
  463. void
  464. _DtGenericMapWindow (
  465. Widget parent,
  466. XtPointer recordPtr)
  467. {
  468. GenericRecord * genericRecord = (GenericRecord *) recordPtr;
  469. XtAddCallback (genericRecord->shell, XmNpopupCallback,
  470. (XtCallbackProc)_DtMappedCB, (XtPointer) parent);
  471. }
  472. /*
  473. * This is the generic function for destroying a dialog widget hierarchy.
  474. */
  475. void
  476. _DtGenericDestroy(
  477. XtPointer recordPtr )
  478. {
  479. GenericRecord * genericRecord = (GenericRecord *) recordPtr;
  480. XtDestroyWidget(genericRecord->shell);
  481. XtFree((char *) genericRecord);
  482. }
  483. /*
  484. * This is the generic function for updating the shell's x and y, to
  485. * take the window manager border into consideration.
  486. */
  487. void
  488. _DtGenericUpdateWindowPosition(
  489. DialogData * dataPtr )
  490. {
  491. DialogInstanceData * genericData = (DialogInstanceData *) dataPtr->data;
  492. GenericRecord * genericRecord;
  493. /* Do nothing, if the dialog is not displayed */
  494. if (genericData->displayed == True)
  495. {
  496. XmVendorShellExtObject vendorExt;
  497. XmWidgetExtData extData;
  498. Window junkWindow;
  499. int t_x, t_y;
  500. Arg args[5];
  501. genericRecord = (GenericRecord *)_DtGetDialogInstance(dataPtr);
  502. XtSetArg(args[0], XmNwidth, &genericData->width);
  503. XtSetArg(args[1], XmNheight, &genericData->height);
  504. XtGetValues(genericRecord->shell, args, 2);
  505. XTranslateCoordinates(XtDisplay(genericRecord->shell),
  506. XtWindow(genericRecord->shell),
  507. RootWindowOfScreen(XtScreen(genericRecord->shell)),
  508. 0, 0, &t_x, &t_y,
  509. &junkWindow);
  510. genericData->x = (Position) t_x;
  511. genericData->y = (Position) t_y;
  512. /* Modify x & y to take into account window mgr frames */
  513. extData=_XmGetWidgetExtData(genericRecord->shell, XmSHELL_EXTENSION);
  514. vendorExt = (XmVendorShellExtObject)extData->widget;
  515. genericData->x -= vendorExt->vendor.xOffset;
  516. genericData->y -= vendorExt->vendor.yOffset;
  517. }
  518. }
  519. /*
  520. * This is a function for building a path from directory and filename
  521. * parameters.
  522. */
  523. void
  524. _DtBuildPath(
  525. char *path,
  526. char *directory,
  527. char *fileName)
  528. {
  529. if (directory)
  530. {
  531. if (fileName)
  532. sprintf(path, "%s/%s", directory, fileName);
  533. else
  534. sprintf(path, "%s", directory);
  535. }
  536. else
  537. {
  538. if (fileName)
  539. sprintf(path, "%s", fileName);
  540. else
  541. sprintf(path, "%s", "");
  542. }
  543. }
  544. /*
  545. * This is a function for retrieving the pixmap data for a data type.
  546. */
  547. PixmapData *
  548. _DtRetrievePixmapData(
  549. char *dataType,
  550. char *fileName,
  551. char *directory,
  552. Widget shell,
  553. int size)
  554. {
  555. PixmapData *pixmapData;
  556. char path[MAXPATHLEN];
  557. char *iconName;
  558. pixmapData = (PixmapData *) XtMalloc(sizeof(PixmapData));
  559. if (!pixmapData)
  560. return NULL;
  561. path[0] = 0x0;
  562. _DtBuildPath(path, directory, fileName);
  563. pixmapData->size = size;
  564. /* retrieve host name */
  565. pixmapData->hostPrefix = DtDtsDataTypeToAttributeValue(dataType,
  566. DtDTS_DA_DATA_HOST,
  567. NULL);
  568. /*
  569. retrieve instance icon name if one exists; otherwise, retrieve class
  570. icon name
  571. */
  572. if (path[0] != 0x0)
  573. {
  574. pixmapData->instanceIconName = DtDtsDataTypeToAttributeValue(dataType,
  575. DtDTS_DA_INSTANCE_ICON,
  576. path);
  577. }
  578. else
  579. pixmapData->instanceIconName = NULL;
  580. if (pixmapData->instanceIconName == NULL)
  581. {
  582. pixmapData->iconName = DtDtsDataTypeToAttributeValue( dataType,
  583. DtDTS_DA_ICON, NULL);
  584. if( pixmapData->iconName == NULL )
  585. {
  586. if( strcmp( dataType, LT_DIRECTORY ) == 0 )
  587. pixmapData->iconName = XtNewString( "DtdirB" );
  588. else
  589. pixmapData->iconName = XtNewString( "Dtdeflt" );
  590. }
  591. }
  592. else
  593. {
  594. pixmapData->iconName = NULL;
  595. }
  596. /* retrieve icon file name */
  597. if (pixmapData->size == LARGE)
  598. pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
  599. pixmapData->instanceIconName,
  600. pixmapData->iconName,
  601. pixmapData->hostPrefix,
  602. DtMEDIUM);
  603. else
  604. pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
  605. pixmapData->instanceIconName,
  606. pixmapData->iconName,
  607. pixmapData->hostPrefix,
  608. DtTINY);
  609. /* return pixmap data */
  610. return(pixmapData);
  611. }
  612. /*
  613. * This is a function for checking the size, etc of an icon pixmap and
  614. * freeing the pixmap data for an icon.
  615. */
  616. void
  617. _DtCheckAndFreePixmapData(
  618. char *dataType,
  619. Widget shell,
  620. DtIconGadget iconGadget,
  621. PixmapData *pixmapData)
  622. {
  623. Arg args[1];
  624. if (!pixmapData)
  625. return;
  626. /*
  627. if there was an instance icon name; verify that the pixmap parameters
  628. do not exceed system limits; if system limits are exceeded, retrieve
  629. class icon name and set icon gadget image resource to this value
  630. */
  631. if (pixmapData->instanceIconName)
  632. {
  633. if(! pixmapData->iconFileName && iconGadget->icon.pixmap == 0)
  634. { /* Try to get pixmap name
  635. */
  636. char * tmp, * ptr;
  637. tmp = XtNewString( pixmapData->instanceIconName );
  638. if( ptr = strrchr( tmp,'/' ) )
  639. *(ptr) = 0;
  640. XmeFlushIconFileCache( tmp );
  641. if (pixmapData->iconFileName != NULL)
  642. XtFree(pixmapData->iconFileName);
  643. if (pixmapData->size == LARGE)
  644. pixmapData->iconFileName = _DtGetIconFileName( XtScreen(shell),
  645. pixmapData->instanceIconName,
  646. NULL,
  647. pixmapData->hostPrefix,
  648. DtMEDIUM );
  649. else
  650. pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
  651. pixmapData->instanceIconName,
  652. NULL,
  653. pixmapData->hostPrefix,
  654. DtTINY);
  655. XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
  656. XtSetValues((Widget) iconGadget, args, 1);
  657. XtFree( tmp );
  658. }
  659. DtDtsFreeAttributeValue(pixmapData->instanceIconName);
  660. pixmapData->instanceIconName = NULL;
  661. if (iconGadget->icon.pixmap == 0 ||
  662. iconGadget->icon.pixmap_width == 0 ||
  663. iconGadget->icon.pixmap_height == 0 ||
  664. (Dimension)iconGadget->icon.pixmap_width > (Dimension)instanceWidth ||
  665. (Dimension)iconGadget->icon.pixmap_height > (Dimension)instanceHeight)
  666. {
  667. pixmapData->iconName = DtDtsDataTypeToAttributeValue(
  668. dataType,
  669. DtDTS_DA_ICON, NULL);
  670. /* retrieve icon file name */
  671. if (pixmapData->iconFileName != NULL)
  672. {
  673. XtFree(pixmapData->iconFileName);
  674. pixmapData->iconFileName = NULL;
  675. }
  676. if (pixmapData->size == LARGE)
  677. pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
  678. pixmapData->instanceIconName,
  679. pixmapData->iconName,
  680. pixmapData->hostPrefix,
  681. DtMEDIUM);
  682. else
  683. pixmapData->iconFileName = _DtGetIconFileName(XtScreen(shell),
  684. pixmapData->instanceIconName,
  685. pixmapData->iconName,
  686. pixmapData->hostPrefix,
  687. DtTINY);
  688. XtSetArg(args[0], XmNimageName, pixmapData->iconFileName);
  689. XtSetValues((Widget) iconGadget, args, 1);
  690. DtDtsFreeAttributeValue(pixmapData->iconName);
  691. pixmapData->iconName = NULL;
  692. }
  693. }
  694. else
  695. {
  696. DtDtsFreeAttributeValue(pixmapData->iconName);
  697. pixmapData->iconName = NULL;
  698. }
  699. DtDtsFreeAttributeValue(pixmapData->hostPrefix);
  700. if (pixmapData->iconFileName)
  701. XtFree(pixmapData->iconFileName);
  702. XtFree((char *) pixmapData);
  703. }
  704. /*
  705. * This is a function for checking for a datatype property.
  706. */
  707. Boolean
  708. _DtCheckForDataTypeProperty(
  709. char *dataType,
  710. char *property)
  711. {
  712. char *properties;
  713. char *prop;
  714. char *props;
  715. Boolean found = False;
  716. properties = DtDtsDataTypeToAttributeValue(dataType,
  717. DtDTS_DA_PROPERTIES,
  718. NULL);
  719. if (properties)
  720. {
  721. props = properties;
  722. prop = props;
  723. while (props = DtStrchr(props, ','))
  724. {
  725. *props = '\0';
  726. if (strcmp(prop, property) == 0)
  727. {
  728. found = True;
  729. break;
  730. }
  731. *props = ',';
  732. props++;
  733. prop = props;
  734. }
  735. if (!props)
  736. {
  737. if (strcmp(prop, property) == 0)
  738. found = True;
  739. }
  740. DtDtsFreeAttributeValue(properties);
  741. }
  742. return found;
  743. }
  744. /*
  745. * This is a function for compiling a vectorized action list for a data type.
  746. */
  747. char **
  748. _DtCompileActionVector(
  749. char *dataType)
  750. {
  751. char *actions;
  752. char **vector = NULL;
  753. actions = DtDtsDataTypeToAttributeValue(dataType,
  754. DtDTS_DA_ACTION_LIST,
  755. NULL);
  756. if (actions)
  757. vector = (char **) _DtVectorizeInPlace(actions, ',');
  758. return(vector);
  759. }
  760. /*
  761. * This is a generic function for retrieving the default action for a data
  762. * type.
  763. */
  764. char *
  765. _DtRetrieveDefaultAction(
  766. char *dataType)
  767. {
  768. char *actions;
  769. char *acts;
  770. char *default_action = NULL;
  771. actions = DtDtsDataTypeToAttributeValue(dataType,
  772. DtDTS_DA_ACTION_LIST,
  773. NULL);
  774. if (actions)
  775. {
  776. if (acts = DtStrchr(actions, ','))
  777. *acts = '\0';
  778. default_action = XtNewString(actions);
  779. DtDtsFreeAttributeValue(actions);
  780. }
  781. return(default_action);
  782. }
  783. /*
  784. * This is a function for building a title for a File Manager view.
  785. */
  786. char *
  787. _DtBuildFMTitle(
  788. FileMgrData *file_mgr_data )
  789. {
  790. char *title, *ptr, *fileLabel, *fileName;
  791. if (fileLabel = DtDtsFileToAttributeValue(file_mgr_data->current_directory,
  792. DtDTS_DA_LABEL))
  793. ptr = fileLabel;
  794. else if (fileName = strrchr(file_mgr_data->current_directory, '/'))
  795. ptr = fileName + 1;
  796. else
  797. ptr = "";
  798. if (file_mgr_data->title)
  799. {
  800. if (file_mgr_data->toolbox &&
  801. strcmp(file_mgr_data->current_directory,
  802. file_mgr_data->restricted_directory) != 0)
  803. {
  804. title = (char *)XtMalloc(strlen(file_mgr_data->title) +
  805. strlen(ptr) +
  806. 4); /* Need for blank dash blank NULL */
  807. sprintf(title, "%s - %s", file_mgr_data->title, ptr);
  808. }
  809. else
  810. {
  811. title = XtNewString(file_mgr_data->title);
  812. }
  813. }
  814. else
  815. {
  816. if (strcmp(file_mgr_data->current_directory, "/") == 0 && !fileLabel)
  817. {
  818. title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
  819. strlen(file_mgr_data->host) +
  820. strlen(root_title) +
  821. 5); /* Need for blank dash blank colon NULL */
  822. sprintf( title, "%s - %s:%s", (GETMESSAGE(12, 7, "File Manager")),
  823. file_mgr_data->host,
  824. root_title );
  825. }
  826. else
  827. {
  828. title = (char *)XtMalloc(strlen((GETMESSAGE(12, 7, "File Manager"))) +
  829. strlen(ptr) +
  830. 4); /* Need for blank dash blank NULL */
  831. sprintf( title, "%s - %s", (GETMESSAGE(12, 7, "File Manager")), ptr);
  832. }
  833. }
  834. DtDtsFreeAttributeValue(fileLabel);
  835. return(title);
  836. }
  837. /*
  838. * This is a function for building a path from the directory name
  839. * and file name pieces of a FileViewData structure.
  840. */
  841. char *
  842. _DtGetSelectedFilePath(
  843. FileViewData *selected_file )
  844. {
  845. char *directory;
  846. char *file;
  847. char *path;
  848. directory = ((DirectorySet *)selected_file->directory_set)->name;
  849. file = selected_file->file_data->file_name;
  850. if (strcmp(directory, "/") == 0)
  851. {
  852. path = XtMalloc(strlen(directory) + strlen(file) + 1);
  853. sprintf(path, "%s%s", directory, file);
  854. }
  855. else
  856. {
  857. path = XtMalloc(strlen(directory) + strlen(file) + 2);
  858. sprintf(path, "%s/%s", directory, file);
  859. }
  860. return(path);
  861. }
  862. /*
  863. * This is a generic function for building action parameters from an array of
  864. * file view data structures.
  865. */
  866. void
  867. _DtBuildActionArgsWithSelectedFiles(
  868. FileViewData **selection_list,
  869. int selected_count,
  870. DtActionArg **action_args,
  871. int *arg_count )
  872. {
  873. *arg_count = 0;
  874. *action_args = (DtActionArg *)
  875. XtCalloc(1, sizeof(DtActionArg) * selected_count);
  876. if (*action_args)
  877. {
  878. int i;
  879. for(i = 0; i < selected_count; i++)
  880. {
  881. ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
  882. ((*action_args)[(*arg_count)++]).u.file.name =
  883. _DtGetSelectedFilePath(selection_list[i]);
  884. }
  885. }
  886. }
  887. void
  888. _DtBuildActionArgsWithDTSelectedFiles(
  889. DesktopRec **selection_list,
  890. int selected_count,
  891. DtActionArg **action_args,
  892. int *arg_count )
  893. {
  894. *arg_count = 0;
  895. *action_args = (DtActionArg *)
  896. XtCalloc(1, sizeof(DtActionArg) * selected_count);
  897. if (*action_args)
  898. {
  899. int i;
  900. for(i = 0; i < selected_count; i++)
  901. {
  902. ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
  903. ((*action_args)[(*arg_count)++]).u.file.name =
  904. _DtGetSelectedFilePath(selection_list[i]->file_view_data);
  905. }
  906. }
  907. }
  908. /*
  909. * This is a generic function for building action parameters from drag and drop
  910. * file information.
  911. */
  912. void
  913. _DtBuildActionArgsWithDroppedFiles(
  914. FileViewData *dropped_on_obj,
  915. DtDndDropCallbackStruct *drop_parameters,
  916. DtActionArg **action_args,
  917. int *arg_count )
  918. {
  919. *arg_count = 0;
  920. if (dropped_on_obj)
  921. *action_args = (DtActionArg *) XtCalloc
  922. (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
  923. else
  924. *action_args = (DtActionArg *) XtCalloc
  925. (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
  926. if (*action_args)
  927. {
  928. int i;
  929. if (dropped_on_obj)
  930. {
  931. ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
  932. ((*action_args)[(*arg_count)++]).u.file.name =
  933. _DtGetSelectedFilePath(dropped_on_obj);
  934. }
  935. for(i = 0; i < drop_parameters->dropData->numItems; i++)
  936. {
  937. ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
  938. ((*action_args)[(*arg_count)++]).u.file.name =
  939. XtNewString(drop_parameters->dropData->data.files[i]);
  940. }
  941. }
  942. }
  943. /*
  944. * This is a generic function for building action parameters from drag and drop
  945. * buffer information.
  946. */
  947. void
  948. _DtBuildActionArgsWithDroppedBuffers(
  949. FileViewData *dropped_on_obj,
  950. DtDndDropCallbackStruct *drop_parameters,
  951. DtActionArg **action_args,
  952. int *arg_count )
  953. {
  954. *arg_count = 0;
  955. if (dropped_on_obj)
  956. *action_args = (DtActionArg *) XtCalloc
  957. (1, sizeof(DtActionArg) * (drop_parameters->dropData->numItems + 1));
  958. else
  959. *action_args = (DtActionArg *) XtCalloc
  960. (1, sizeof(DtActionArg) * drop_parameters->dropData->numItems);
  961. if (*action_args)
  962. {
  963. int i;
  964. DtActionBuffer buffer_arg = {NULL, 0, NULL, NULL, False};
  965. if (dropped_on_obj)
  966. {
  967. ((*action_args)[(*arg_count)]).argClass = DtACTION_FILE;
  968. ((*action_args)[(*arg_count)++]).u.file.name =
  969. _DtGetSelectedFilePath(dropped_on_obj);
  970. }
  971. for(i = 0; i < drop_parameters->dropData->numItems; i++)
  972. {
  973. buffer_arg.bp = drop_parameters->dropData->data.buffers[i].bp;
  974. buffer_arg.size = drop_parameters->dropData->data.buffers[i].size;
  975. buffer_arg.name = drop_parameters->dropData->data.buffers[i].name;
  976. ((*action_args)[(*arg_count)]).argClass = DtACTION_BUFFER;
  977. ((*action_args)[(*arg_count)++]).u.buffer = buffer_arg;
  978. }
  979. }
  980. }
  981. /*
  982. * This is a generic function for freeing action parameters.
  983. */
  984. void
  985. _DtFreeActionArgs(
  986. DtActionArg *action_args,
  987. int arg_count )
  988. {
  989. int i;
  990. for (i = 0; i < arg_count; i++)
  991. {
  992. if (action_args[i].argClass == DtACTION_FILE)
  993. {
  994. XtFree(action_args[i].u.file.name);
  995. action_args[i].u.file.name = NULL;
  996. }
  997. }
  998. XtFree((char *) action_args);
  999. }
  1000. /************************************************************************
  1001. * The following functions deal with Buffer Manipulation and Naming
  1002. ************************************************************************/
  1003. /*
  1004. * This is a generic function for extracting buffer information from
  1005. * drop input.
  1006. */
  1007. void
  1008. _DtSetDroppedBufferInfo(char **file_set,
  1009. BufferInfo *buffer_set,
  1010. char **host_set,
  1011. DtDndDropCallbackStruct *drop_parameters)
  1012. {
  1013. int num_of_buffers = drop_parameters->dropData->numItems;
  1014. int i;
  1015. DtDndBuffer *buffers = drop_parameters->dropData->data.buffers;
  1016. DPRINTF (("Executing..._DtSetDroppedBufferInfo\n"));
  1017. /* Initialize file_set and ensure of unique file names for unamed buffers*/
  1018. SetBufferFileNames(file_set, buffers, num_of_buffers);
  1019. for (i= 0; i < num_of_buffers; i++)
  1020. {
  1021. (buffer_set[i]).buf_ptr = buffers[i].bp;
  1022. (buffer_set[i]).size = buffers[i].size;
  1023. host_set[i] = XtNewString(home_host_name);
  1024. DPRINTF(("_DtSetDroppedBufferInfo:\n host_set[%d]=%s,\
  1025. buffer_set[%d].buf_ptr=%p, buffer_set[%d].size=%d\n",
  1026. i, host_set[i], i, buffer_set[i].buf_ptr, i, buffer_set[i].size));
  1027. }
  1028. }
  1029. /*
  1030. * This is a function for creating file names for a set of buffers.
  1031. */
  1032. static void
  1033. SetBufferFileNames (char **file_set,
  1034. DtDndBuffer *buffers,
  1035. int num_of_buffers)
  1036. {
  1037. int null_filenames_count = 0;
  1038. int i;
  1039. int first_nullfile_index = 0;
  1040. Boolean NULL_FILENAMES=FALSE;
  1041. DPRINTF (("Executing...SetBufferFileNames\n"));
  1042. for (i = 0; i < num_of_buffers; i++)
  1043. {
  1044. if (buffers[i].name == NULL)
  1045. {
  1046. /* generate buffer name using Untitled as a base name */
  1047. file_set[i]=BuildBufferFileName(DEFAULT_BUFFER_FILENAME,
  1048. -1,
  1049. buffers[i].bp,
  1050. buffers[i].size);
  1051. }
  1052. else
  1053. {
  1054. /* file name is supplied by the drag initiator */
  1055. file_set[i] = XtNewString(buffers[i].name);
  1056. }
  1057. DPRINTF(("file_set[%d]=%s\n", i, file_set[i]));
  1058. } /* end for loop */
  1059. /* Rename any collisions to unique names */
  1060. RenameCollisions(file_set, num_of_buffers);
  1061. return;
  1062. }
  1063. /*
  1064. * This is a generic function for generating a name for an untitled buffer.
  1065. * A default name (Untitled) is used in conjunction with the name template
  1066. * information from the types database.
  1067. */
  1068. static char *
  1069. BuildBufferFileName (char *file_name,
  1070. int postfix_index,
  1071. void *buffer,
  1072. int buffer_size)
  1073. {
  1074. const char delim = '_';
  1075. char *new_file_name;
  1076. DPRINTF (("Executing....BuildBufferFileName\n"));
  1077. /* Malloc memory and contruct the new file name */
  1078. new_file_name = (char *) XtMalloc (strlen(file_name) + 1 +
  1079. MAX_POSTFIX_LENGTH + 1);
  1080. DPRINTF (("BuildBufferFileName: Old file name is %s\n", file_name));
  1081. /* determine whether to append post fix name */
  1082. if (postfix_index == -1)
  1083. strcpy(new_file_name, file_name);
  1084. else
  1085. sprintf(new_file_name,"%s%c%d", file_name, delim, postfix_index);
  1086. /* Retrieve the name template if it exists and use it in the filename */
  1087. new_file_name = RetrieveAndUseNameTemplateInfo(buffer,
  1088. buffer_size,
  1089. new_file_name);
  1090. DPRINTF(("BuildBufferFileName: Returning new_file_name=%s\n", new_file_name));
  1091. /* return new file name */
  1092. return (new_file_name);
  1093. }
  1094. /*
  1095. * This is a function for building a buffer name using predfined input
  1096. * and name template information from the types database.
  1097. * WARNING: template_input MAY be freed. It must point to a char *.
  1098. */
  1099. static char *
  1100. RetrieveAndUseNameTemplateInfo(
  1101. void *buffer,
  1102. int buffer_size,
  1103. char *template_input)
  1104. {
  1105. char *name_template;
  1106. char *buffer_name = NULL;
  1107. name_template = DtDtsBufferToAttributeValue(buffer,
  1108. buffer_size,
  1109. DtDTS_DA_NAME_TEMPLATE,
  1110. NULL);
  1111. if (name_template)
  1112. buffer_name = (char *) XtMalloc(strlen(name_template) +
  1113. strlen(template_input) +
  1114. 1);
  1115. if (buffer_name)
  1116. {
  1117. sprintf(buffer_name, name_template, template_input);
  1118. DtDtsFreeAttributeValue(name_template);
  1119. XtFree(template_input);
  1120. return(buffer_name);
  1121. }
  1122. else
  1123. {
  1124. DtDtsFreeAttributeValue(name_template);
  1125. return(template_input);
  1126. }
  1127. }
  1128. /*
  1129. * This is a function for resolving collisions in a list of buffer names.
  1130. */
  1131. static void
  1132. RenameCollisions( char ** list, int count )
  1133. {
  1134. int i, j, k, l;
  1135. char flg = 0, flg2 = 0;
  1136. for( i = 0; i < count; ++i )
  1137. {
  1138. unsigned int addIndex = 1;
  1139. if( *(list[i]) == 0x0 )
  1140. {
  1141. k = i;
  1142. flg = 1;
  1143. }
  1144. for( j = i+1; j < count; ++j )
  1145. {
  1146. if( strcmp( list[i], list[j] ) == 0 )
  1147. {
  1148. RenameEntry( &(list[j]), ++addIndex );
  1149. l = i;
  1150. flg2 = 1;
  1151. }
  1152. }
  1153. if( flg2 )
  1154. {
  1155. flg2 = 0;
  1156. RenameEntry( &(list[l]), 1 );
  1157. }
  1158. }
  1159. if( flg )
  1160. {
  1161. free( list[k] );
  1162. list[k] = (char *)malloc( strlen( DEFAULT_BUFFER_FILENAME ) + 1 );
  1163. sprintf( list[k], "%s", DEFAULT_BUFFER_FILENAME );
  1164. }
  1165. }
  1166. /*
  1167. * This is a function for adding an index to a buffer name which has
  1168. * collided.
  1169. */
  1170. static void
  1171. RenameEntry( char ** name, unsigned int addIndex )
  1172. {
  1173. #define MAX_INT_SIZE 15
  1174. char * tmpPtr, * newName;
  1175. if( *name == 0x0 )
  1176. return;
  1177. else if( **name == 0x0 )
  1178. {
  1179. newName = (char *)XtCalloc(1,strlen(DEFAULT_BUFFER_FILENAME)+ MAX_INT_SIZE);
  1180. sprintf( newName, "%s_%d", DEFAULT_BUFFER_FILENAME, addIndex );
  1181. }
  1182. else
  1183. {
  1184. tmpPtr = strrchr( *name, '.' );
  1185. newName = (char *)XtCalloc( 1, strlen( *name ) + MAX_INT_SIZE );
  1186. if( tmpPtr == NULL )
  1187. sprintf( newName, "%s_%d", *name, addIndex );
  1188. else if( tmpPtr == *name )
  1189. sprintf( newName, "%d%s", addIndex, *name );
  1190. else
  1191. {
  1192. *tmpPtr = 0x0;
  1193. sprintf( newName, "%s_%d.%s", *name, addIndex, ++tmpPtr);
  1194. }
  1195. }
  1196. free( *name );
  1197. *name = newName;
  1198. }
  1199. /*
  1200. * This is a generic function for freeing buffer information extracted from
  1201. * drop input.
  1202. */
  1203. void
  1204. _DtFreeDroppedBufferInfo(char **file_set,
  1205. BufferInfo *buffer_set,
  1206. char **host_set,
  1207. int num_of_buffers)
  1208. {
  1209. int i;
  1210. DPRINTF (("Executing..._DtFreeDroppedBufferInfo\n"));
  1211. /* Check for Null pointers */
  1212. if (file_set && buffer_set && host_set )
  1213. {
  1214. for (i=0; i< num_of_buffers; i++ )
  1215. {
  1216. XtFree(file_set[i]);
  1217. XtFree(host_set[i]);
  1218. }
  1219. XtFree((char *)file_set);
  1220. XtFree((char *)host_set);
  1221. XtFree((char *)buffer_set);
  1222. }
  1223. }
  1224. /*
  1225. * This is a generic function for determining if a buffer is executable.
  1226. */
  1227. Boolean
  1228. _DtIsBufferExecutable(
  1229. void *buffer,
  1230. int buffer_size)
  1231. {
  1232. char *exe_attribute;
  1233. Boolean is_exe = False;
  1234. exe_attribute = DtDtsBufferToAttributeValue(buffer,
  1235. buffer_size,
  1236. "IS_EXECUTABLE",
  1237. NULL);
  1238. if (exe_attribute)
  1239. {
  1240. if (DtDtsIsTrue(exe_attribute))
  1241. is_exe = True;
  1242. DtDtsFreeAttributeValue(exe_attribute);
  1243. }
  1244. return(is_exe);
  1245. }
  1246. /*
  1247. * This is a generic function for extracting file information from drop input.
  1248. */
  1249. void
  1250. _DtSetDroppedFileInfo(
  1251. DtDndDropCallbackStruct *drop_parameters,
  1252. char ***file_set,
  1253. char ***host_set)
  1254. {
  1255. int numFiles, i;
  1256. numFiles = drop_parameters->dropData->numItems;
  1257. *file_set = (char **)XtMalloc(sizeof(char *) * numFiles);
  1258. *host_set = (char **)XtMalloc(sizeof(char *) * numFiles);
  1259. for(i = 0; i < numFiles; i++)
  1260. {
  1261. (*file_set)[i] = XtNewString(drop_parameters->dropData->data.files[i]);
  1262. (*host_set)[i] = home_host_name;
  1263. DPRINTF(("ProcessMoveCopyLink:\n host_set[%d]=%s, file_set[%d]=%s\n",
  1264. i, (*host_set)[i], i, (*file_set)[i]));
  1265. }
  1266. }
  1267. /*
  1268. * This is a generic function for copying file info extracted from drop input.
  1269. */
  1270. void
  1271. _DtCopyDroppedFileInfo(
  1272. int num_files,
  1273. char **orig_file_set,
  1274. char **orig_host_set,
  1275. char ***new_file_set,
  1276. char ***new_host_set)
  1277. {
  1278. int i;
  1279. *new_file_set = (char **)XtMalloc(sizeof(char *) * num_files);
  1280. *new_host_set = (char **)XtMalloc(sizeof(char *) * num_files);
  1281. for(i = 0; i < num_files; i++)
  1282. {
  1283. (*new_file_set)[i] = XtNewString(orig_file_set[i]);
  1284. (*new_host_set)[i] = XtNewString(orig_host_set[i]);
  1285. }
  1286. }
  1287. /*
  1288. * This is a generic function for freeing file info extracted from drop input.
  1289. */
  1290. void
  1291. _DtFreeDroppedFileInfo(
  1292. int num_files,
  1293. char **file_set,
  1294. char **host_set)
  1295. {
  1296. int i;
  1297. for(i = 0; i < num_files; i++)
  1298. XtFree(file_set[i]);
  1299. XtFree((char *)file_set);
  1300. XtFree((char *)host_set);
  1301. }
  1302. /*
  1303. * This is a generic function for resolving a cannonical path from user input.
  1304. */
  1305. void
  1306. _DtPathFromInput(
  1307. char *input_string,
  1308. char *current_dir,
  1309. char **host,
  1310. char **rel_path)
  1311. {
  1312. char *path;
  1313. char *tmp_path = NULL;
  1314. char *true_path = NULL;
  1315. Tt_status tt_status;
  1316. int dir_len;
  1317. /* find host */
  1318. *host = XtNewString(home_host_name);
  1319. /* find relative path */
  1320. tmp_path = path = XtNewString(input_string);
  1321. /* Strip any spaces from name -- input is overwritten */
  1322. path = (char *) _DtStripSpaces(path);
  1323. /* Resolve, if there're any, environment variables */
  1324. {
  1325. FILE *pfp = NULL;
  1326. char command[MAXPATHLEN];
  1327. memset(command, 0, sizeof(command));
  1328. sprintf(command,"echo %s",path);
  1329. if((pfp=popen(command,"r")) != NULL)
  1330. {
  1331. int read_ok = 1;
  1332. if (NULL == (fgets(command,MAXPATHLEN,pfp)))
  1333. {
  1334. /*
  1335. * Try a few more reads and if the read still fails,
  1336. * just use the path as is.
  1337. */
  1338. int i;
  1339. for (i=0; i < 5; i++)
  1340. {
  1341. sleep (1);
  1342. if (NULL != (fgets(command,MAXPATHLEN,pfp)))
  1343. break;
  1344. }
  1345. if (i >= 5)
  1346. read_ok = 0;
  1347. }
  1348. if (read_ok)
  1349. {
  1350. int slen = strlen(command);
  1351. /* need to remove the trailing newline safely*/
  1352. if (slen >= 1)
  1353. command[slen-1] = '\0';
  1354. XtFree(path);
  1355. path = XtNewString(command);
  1356. pclose(pfp);
  1357. pfp = NULL;
  1358. }
  1359. }
  1360. if (pfp)
  1361. {
  1362. pclose(pfp);
  1363. pfp = NULL;
  1364. }
  1365. }
  1366. /* Resolve '~' -- new memory is allocated, old memory is freed */
  1367. if (*path == '~')
  1368. path = _DtChangeTildeToHome(path);
  1369. /* If current dir provided, check for relative path */
  1370. if (path && current_dir)
  1371. {
  1372. if (*path != '/')
  1373. {
  1374. /* file is relative path i.e. xyz/abc */
  1375. if (strcmp(current_dir, "/") == 0)
  1376. {
  1377. tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 1);
  1378. sprintf(tmp_path, "%s%s", current_dir, path);
  1379. }
  1380. else
  1381. {
  1382. tmp_path = (char *)XtMalloc(strlen(current_dir) + strlen(path) + 2);
  1383. sprintf(tmp_path, "%s/%s", current_dir, path);
  1384. }
  1385. XtFree(path);
  1386. path = tmp_path;
  1387. tmp_path = NULL;
  1388. }
  1389. }
  1390. else if (!path)
  1391. {
  1392. *rel_path = NULL;
  1393. XtFree(tmp_path);
  1394. return;
  1395. }
  1396. /* Resolve '.' or '..' -- input is overwritten, output may be NULL! */
  1397. /* Save pointer to path to free if output is NULL. */
  1398. tmp_path = path;
  1399. path = (char *) DtEliminateDots(path);
  1400. if (path)
  1401. {
  1402. /* Resolve to local pathname */
  1403. true_path = ResolveLocalPathName(*host,
  1404. path,
  1405. NULL,
  1406. home_host_name,
  1407. &tt_status);
  1408. XtFree(path);
  1409. /* Strip off trailing '/' */
  1410. dir_len = strlen(true_path);
  1411. if (dir_len > 1 && *(true_path + dir_len - 1) == '/')
  1412. *(true_path + dir_len - 1) = '\0';
  1413. }
  1414. else
  1415. {
  1416. true_path = NULL;
  1417. XtFree(tmp_path);
  1418. }
  1419. *rel_path = true_path;
  1420. }
  1421. /*
  1422. * This function takes a path name, and resolves any leading '~' to refer
  1423. * to one of the following:
  1424. *
  1425. * 1) if ~ or ~/path, then it resolves to the user's home directory on
  1426. * their home host.
  1427. *
  1428. * 2) if ~user or ~user/path, then it resolves to the specified user's
  1429. * home directory on the home host.
  1430. *
  1431. * This function never resolves to any host but the home host, since we
  1432. * have no way of determining a user's home directory on any system other
  1433. * than the home system.
  1434. */
  1435. char *
  1436. _DtChangeTildeToHome (
  1437. char *input_string)
  1438. {
  1439. char *path;
  1440. char *full_path;
  1441. struct passwd * pwInfo;
  1442. if ((input_string[1] != '\0') && (input_string[1] != '/'))
  1443. {
  1444. char *path;
  1445. /* ~user or ~user/path format */
  1446. /* is there a path? */
  1447. path = DtStrchr(input_string, '/');
  1448. /* find user */
  1449. if (path)
  1450. *path = '\0';
  1451. if ((pwInfo = getpwnam(input_string + 1)) == NULL)
  1452. {
  1453. /* user doesn't exist */
  1454. if (path)
  1455. *path = '/';
  1456. return NULL;
  1457. }
  1458. if (path)
  1459. {
  1460. /* ~user/path format */
  1461. *path = '/';
  1462. if (strcmp(pwInfo->pw_dir, "/") == 0)
  1463. {
  1464. /* We don't want to end up with double '/' in the path */
  1465. full_path = (char *) XtMalloc(strlen(path) + 1);
  1466. strcpy(full_path, path);
  1467. }
  1468. else
  1469. {
  1470. full_path = (char *) XtMalloc(strlen(pwInfo->pw_dir) +
  1471. strlen(path) + 1);
  1472. sprintf(full_path, "%s%s", pwInfo->pw_dir, path);
  1473. }
  1474. }
  1475. else
  1476. {
  1477. /* ~user format */
  1478. full_path = XtMalloc(strlen(pwInfo->pw_dir) + 1);
  1479. strcpy(full_path, pwInfo->pw_dir);
  1480. }
  1481. }
  1482. else if (input_string[1])
  1483. {
  1484. /* ~/path format */
  1485. /* NOTE: users_home_dir has trailing '/' */
  1486. full_path = XtMalloc(strlen(users_home_dir) + strlen(input_string+2) + 1);
  1487. sprintf(full_path, "%s%s", users_home_dir, (input_string + 2));
  1488. }
  1489. else
  1490. {
  1491. /* ~ format */
  1492. full_path = XtMalloc(strlen(users_home_dir) + 1);
  1493. strcpy(full_path, users_home_dir);
  1494. }
  1495. XtFree(input_string);
  1496. return(full_path);
  1497. }
  1498. /*
  1499. * This function checks for spaces in filenames.
  1500. */
  1501. #ifdef _CHECK_FOR_SPACES
  1502. Boolean
  1503. _DtSpacesInFileNames(
  1504. char **fileNames,
  1505. int fileCount )
  1506. {
  1507. int i;
  1508. for (i = 0; i < fileCount; i++)
  1509. {
  1510. fileNames[i] = (char *) _DtStripSpaces(fileNames[i]);
  1511. if (DtStrchr (fileNames[i], ' ') != NULL ||
  1512. DtStrchr (fileNames[i], '\t') != NULL)
  1513. return(TRUE);
  1514. }
  1515. return(FALSE);
  1516. }
  1517. #endif
  1518. /*
  1519. * This resolves the path for an appmanager object to its true path.
  1520. */
  1521. char *
  1522. _DtResolveAppManPath(
  1523. char *path,
  1524. char *restricted_dir )
  1525. {
  1526. if (strlen(path) > strlen(restricted_dir))
  1527. {
  1528. char *linkDir, *ptr, *tmpPath;
  1529. linkDir = path + strlen(restricted_dir) + 1;
  1530. ptr = DtStrchr(linkDir, '/');
  1531. if (ptr)
  1532. {
  1533. *ptr = '\0';
  1534. linkDir = _DtFollowLink(path);
  1535. *ptr = '/';
  1536. tmpPath = XtMalloc(strlen(linkDir) + strlen(ptr) + 1);
  1537. sprintf(tmpPath, "%s%s", linkDir, ptr);
  1538. XtFree(path);
  1539. path = tmpPath;
  1540. }
  1541. else
  1542. {
  1543. linkDir = _DtFollowLink(path);
  1544. XtFree(path);
  1545. path = XtNewString(linkDir);
  1546. }
  1547. }
  1548. return(path);
  1549. }