AccessSDL.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460
  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: AccessSDL.c /main/13 1996/09/30 11:22:14 cde-hp $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. **
  27. ** File: AccessSDL.c
  28. **
  29. ** Project: Run Time Project File Access
  30. **
  31. ** Description: This body of code handles the access routines for the
  32. ** SDL files.
  33. **
  34. **
  35. ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
  36. **
  37. ** (c) Copyright 1993, 1994 Hewlett-Packard Company
  38. ** (c) Copyright 1993, 1994 International Business Machines Corp.
  39. ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  40. ** (c) Copyright 1993, 1994 Novell, Inc.
  41. **
  42. **
  43. ****************************************************************************
  44. ************************************<+>*************************************/
  45. /*
  46. * system includes
  47. */
  48. #include <stdlib.h>
  49. #include <stdio.h>
  50. #include <string.h>
  51. #include <X11/Xlib.h>
  52. #include <X11/Xresource.h>
  53. /*
  54. * Canvas Engine includes
  55. */
  56. #include "CanvasP.h"
  57. #include "CanvasSegP.h"
  58. /*
  59. * private includes
  60. */
  61. #include "bufioI.h"
  62. #include "CleanUpI.h"
  63. #include "CvStringI.h"
  64. #include "FontAttrI.h"
  65. #include "Access.h"
  66. #include "AccessP.h"
  67. #include "AccessSDLP.h"
  68. #include "AccessSDLI.h"
  69. #include "FormatUtilI.h"
  70. #include "FormatSDLI.h"
  71. #include "StringFuncsI.h"
  72. #include "UtilSDLI.h"
  73. #ifdef NLS16
  74. #endif
  75. /******** Private Defines ********/
  76. /******** End Private Defines ********/
  77. /******** Private Function Declarations ********/
  78. static int ProcessEntry (
  79. _DtHelpVolume vol,
  80. _DtCvSegment *p_seg,
  81. char *parent_key);
  82. /******** End Private Function Declarations ********/
  83. /******** Private Variable Declarations ********/
  84. static const char *IsoString = "ISO-8859-1";
  85. static const CESDLVolume DefaultSdlVolume =
  86. {
  87. NULL, /* _DtCvSegment *sdl_info; */
  88. NULL, /* _DtCvSegment *toss; */
  89. NULL, /* _DtCvSegment *loids; */
  90. NULL, /* _DtCvSegment *index; */
  91. NULL, /* _DtCvSegment *title; */
  92. NULL, /* _DtCvSegment *snb; */
  93. 0, /* short minor_no; */
  94. False, /* short title_processed; */
  95. };
  96. /******** Private Macro Declarations ********/
  97. /******************************************************************************
  98. * Private Functions
  99. ******************************************************************************/
  100. /******************************************************************************
  101. * Function: void FreeIds (
  102. *
  103. * Parameters:
  104. *
  105. * Return Value:
  106. *
  107. * errno Values:
  108. *
  109. * Purpose:
  110. *
  111. ******************************************************************************/
  112. static void
  113. FreeIds (
  114. _DtCvSegment *loids)
  115. {
  116. _DtCvSegment *p_seg;
  117. if (NULL == loids)
  118. return;
  119. p_seg = _DtCvContainerListOfSeg(loids);
  120. while (NULL != p_seg)
  121. {
  122. if (NULL != _SdlSegToSdlIdInfoPtr(p_seg))
  123. {
  124. if (NULL != _SdlSegToSdlIdInfoRssi(p_seg))
  125. free(_SdlSegToSdlIdInfoRssi(p_seg));
  126. free(_SdlSegToSdlIdInfoPtr(p_seg));
  127. }
  128. p_seg = p_seg->next_seg;
  129. }
  130. }
  131. /******************************************************************************
  132. * Function: void FreeTossInfo (
  133. *
  134. * Parameters:
  135. *
  136. * Return Value:
  137. *
  138. * errno Values:
  139. *
  140. * Purpose:
  141. *
  142. ******************************************************************************/
  143. static void
  144. FreeTossInfo (
  145. _DtCvSegment *toss)
  146. {
  147. _DtCvSegment *p_seg;
  148. SDLTossInfo *info;
  149. if (NULL == toss)
  150. return;
  151. p_seg = _DtCvContainerListOfSeg(toss);
  152. while (NULL != p_seg)
  153. {
  154. info = (SDLTossInfo *) _SdlSegTossInfo(p_seg);
  155. /* free the ssi */
  156. if (NULL != _SdlTossInfoPtrSsi(info))
  157. free(_SdlTossInfoPtrSsi(info));
  158. /* free the colj,colw or the enter, exit data */
  159. if (NULL != _SdlTossInfoPtrStr1(info))
  160. free(_SdlTossInfoPtrStr1(info));
  161. if (NULL != _SdlTossInfoPtrStr2(info))
  162. free(_SdlTossInfoPtrStr2(info));
  163. /* free the font strings */
  164. if (NULL != _DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)))
  165. free(_DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)));
  166. if (NULL != _DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)))
  167. free(_DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)));
  168. if (NULL != _DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)))
  169. free(_DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)));
  170. if (NULL != _DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)))
  171. free(_DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)));
  172. if (NULL != _DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)))
  173. free(_DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)));
  174. if (NULL != _DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)))
  175. free(_DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)));
  176. if (NULL != _DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)))
  177. free(_DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)));
  178. if (NULL != _DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)))
  179. free(_DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)));
  180. if (NULL != _DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)))
  181. free(_DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)));
  182. free(info);
  183. p_seg = p_seg->next_seg;
  184. }
  185. }
  186. /******************************************************************************
  187. * Function: void FreeEntryInfo (
  188. *
  189. * Parameters:
  190. *
  191. * Return Value:
  192. *
  193. * errno Values:
  194. *
  195. * Purpose:
  196. *
  197. ******************************************************************************/
  198. static void
  199. FreeEntryInfo (
  200. _DtCvSegment *index)
  201. {
  202. _DtCvSegment *p_seg;
  203. SDLEntryInfo *info;
  204. if (NULL == index)
  205. return;
  206. p_seg = _DtCvContainerListOfSeg(index);
  207. while (NULL != p_seg)
  208. {
  209. info = _SdlSegToSdlEntryInfo(p_seg);
  210. if (NULL != info)
  211. {
  212. if (NULL != info->main)
  213. free(info->main);
  214. if (NULL != info->locs)
  215. free(info->locs);
  216. if (NULL != info->syns)
  217. free(info->syns);
  218. if (NULL != info->sort)
  219. free(info->sort);
  220. }
  221. if (_DtCvIsSegContainer(p_seg))
  222. FreeEntryInfo(p_seg);
  223. free(info);
  224. p_seg = p_seg->next_seg;
  225. }
  226. }
  227. /******************************************************************************
  228. * Function: int ProcessSubEntries (
  229. *
  230. * Parameters:
  231. *
  232. * Return Value:
  233. *
  234. * errno Values:
  235. *
  236. * Purpose:
  237. *
  238. ******************************************************************************/
  239. static int
  240. ProcessSubEntries (
  241. _DtHelpVolume vol,
  242. _DtCvSegment *p_seg,
  243. char *parent_key)
  244. {
  245. while (p_seg != NULL)
  246. {
  247. /*
  248. * the only sub containers of an entry that should have an non-null
  249. * internal pointer should be a sub <entry>.
  250. */
  251. if (_DtCvIsSegContainer(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
  252. && ProcessEntry(vol, _DtCvContainerListOfSeg(p_seg),
  253. parent_key) == -1)
  254. return -1;
  255. p_seg = p_seg->next_seg;
  256. }
  257. return 0;
  258. }
  259. /******************************************************************************
  260. * Function: int AsciiKeyword (
  261. *
  262. * Parameters:
  263. * p_list The segment list to process for strings.
  264. * parent_str The string to append information onto.
  265. * This may be NULL.
  266. * str_size The malloc'ed size of the parent string.
  267. * Includes room for the null byte. If zero
  268. * and parent_str is non-null, then memory
  269. * must be malloc'ed and parent_str copied
  270. * into it. Otherwise, goodStr can just
  271. * reuse parent_str.
  272. *
  273. * Return Value:
  274. *
  275. * errno Values:
  276. *
  277. * Purpose:
  278. *
  279. ******************************************************************************/
  280. static char *
  281. AsciiKeyword (
  282. _DtCvSegment *p_list,
  283. char *parent_str,
  284. int *str_size)
  285. {
  286. int len = 0;
  287. int newLen;
  288. char *goodStr;
  289. /*
  290. * if a starting string has been passed in, use it.
  291. */
  292. if (NULL != parent_str)
  293. {
  294. /*
  295. * get the actual byte count.
  296. */
  297. len = strlen(parent_str) + 1;
  298. /*
  299. * is the starting value zero? If so, we have to copy it.
  300. */
  301. if (0 == *str_size)
  302. {
  303. parent_str = strdup(parent_str);
  304. if (NULL == parent_str)
  305. return NULL;
  306. *str_size = len;
  307. }
  308. }
  309. /*
  310. * start with the parent_string
  311. */
  312. goodStr = parent_str;
  313. while (p_list != NULL)
  314. {
  315. if (_DtCvIsSegString(p_list))
  316. {
  317. /*
  318. * get the number of characters in the next string.
  319. */
  320. newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_list),
  321. _DtCvIsSegWideChar(p_list));
  322. /*
  323. * if this is wide char string, multiply the count by
  324. * MB_CUR_MAX to get the maximum number of bytes this
  325. * string would take.
  326. */
  327. if (_DtCvIsSegWideChar(p_list))
  328. newLen = newLen * MB_CUR_MAX;
  329. /*
  330. * now add it to our previous size.
  331. */
  332. len += newLen;
  333. /*
  334. * are we starting from scratch?
  335. */
  336. if (goodStr == NULL)
  337. {
  338. /*
  339. * include a byte for the end-of-string character.
  340. */
  341. len++;
  342. /*
  343. * malloc the memory
  344. */
  345. goodStr = (char *) malloc (len);
  346. }
  347. else if (*str_size < len) /* does this have to grow? */
  348. goodStr = (char *) realloc (goodStr, len);
  349. if (goodStr == NULL)
  350. return NULL;
  351. /*
  352. * remember the absolute size of the memory for the string
  353. */
  354. if (*str_size < len)
  355. *str_size = len;
  356. if (_DtCvIsSegWideChar(p_list))
  357. {
  358. /*
  359. * back up to the insertion point.
  360. */
  361. len -= newLen;
  362. /*
  363. * transfer
  364. */
  365. newLen = wcstombs(&goodStr[len - 1],
  366. (wchar_t *) _DtCvStringOfStringSeg(p_list),
  367. newLen + 1);
  368. if ((size_t) -1 == newLen)
  369. {
  370. free(goodStr);
  371. return NULL;
  372. }
  373. len += newLen;
  374. }
  375. else
  376. strcpy(&goodStr[len - newLen - 1],
  377. (char *) _DtCvStringOfStringSeg(p_list));
  378. }
  379. /*
  380. * the only containers in an <entry> that should have a non-null
  381. * internal pointer should be a sub <entry>. Therefore, if null,
  382. * process since it could be a <key>, <sphrase>, etc.
  383. */
  384. else if (_DtCvIsSegContainer(p_list) &&
  385. NULL == _SdlSegEntryInfo(p_list))
  386. {
  387. goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr,
  388. str_size);
  389. if (goodStr == NULL)
  390. return NULL;
  391. len = strlen(goodStr) + 1;
  392. }
  393. p_list = p_list->next_seg;
  394. }
  395. return goodStr;
  396. }
  397. /******************************************************************************
  398. * Function: int ProcessLocations (
  399. *
  400. * Parameters:
  401. *
  402. * Return Value:
  403. *
  404. * errno Values:
  405. *
  406. * Purpose:
  407. *
  408. ******************************************************************************/
  409. static int
  410. ProcessLocations (
  411. char *locs,
  412. char ***list)
  413. {
  414. char **myList = NULL;
  415. char *nextLoc;
  416. while (locs != NULL && *locs != '\0')
  417. {
  418. locs = _DtHelpGetNxtToken(locs, &nextLoc);
  419. if (nextLoc == NULL)
  420. return -1;
  421. if (*nextLoc != '\0')
  422. {
  423. myList = (char **) _DtHelpCeAddPtrToArray ((void **) myList,
  424. (void *) nextLoc);
  425. if (myList == NULL)
  426. return -1;
  427. }
  428. }
  429. *list = myList;
  430. return 0;
  431. }
  432. /******************************************************************************
  433. * Function: int ProcessEntry (_DtHelpVolume vol)
  434. *
  435. * Parameters: vol Specifies the volume whose keywords need to be
  436. * loaded from disk. Once loaded, they can be
  437. * accessed through the fields of the volume structure.
  438. *
  439. * Return Value: 0 if successful, -1 if a failure occurs
  440. *
  441. * errno Values: CEErrorMalloc
  442. * CEErrorIllegalDatabaseFile
  443. * Specifies that the keyword file is
  444. * invalid or corrupt.
  445. * CEErrorMissingKeywordsRes
  446. * Specifies that the keyword file does
  447. * not contain the 'Keywords/keywords'
  448. * resource or the resource is NULL
  449. *
  450. *
  451. * Purpose: Load the keywords associated with a volume.
  452. *
  453. ******************************************************************************/
  454. static int
  455. ProcessEntry (
  456. _DtHelpVolume vol,
  457. _DtCvSegment *p_seg,
  458. char *parent_key)
  459. {
  460. int strSize;
  461. char **topics;
  462. char *nextKey = NULL;
  463. /* Now parse the string into the appropriate arrays. The string has the
  464. following syntax:
  465. <!ELEMENT entry - - ((%simple; | #PCDATA)*, entry*) >
  466. <!ATTLIST entry id ID #IMPLIED
  467. main IDREFS #IMPLIED
  468. locs IDREFS #IMPLIED
  469. syns IDREFS #IMPLIED
  470. sort CDATA #IMPLIED >
  471. */
  472. #define MAIN_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->main
  473. #define LOCS_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->locs
  474. while (p_seg != NULL)
  475. {
  476. strSize = 0;
  477. nextKey = AsciiKeyword(_DtCvContainerListOfSeg(p_seg),
  478. parent_key, &strSize);
  479. if (nextKey == NULL)
  480. return -1;
  481. /* We have the next keyword. Hang onto it and add it to the list
  482. once we get the array of topics. We don't add it yet because if
  483. there are no topics we want to throw it away. (Silently ignoring
  484. keywords which specify no topics is an undocumented feature.) */
  485. /* Now get the list of topics. */
  486. topics = NULL;
  487. if (NULL != FrmtPrivInfoPtr(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
  488. && (ProcessLocations(MAIN_STRINGS, &topics) == -1 ||
  489. ProcessLocations(LOCS_STRINGS, &topics) == -1))
  490. {
  491. free(nextKey);
  492. return -1;
  493. }
  494. if (topics != NULL)
  495. {
  496. vol->keywords = (char **) _DtHelpCeAddPtrToArray (
  497. (void **) vol->keywords,
  498. (void *) nextKey);
  499. vol->keywordTopics = (char ***) _DtHelpCeAddPtrToArray (
  500. (void **) vol->keywordTopics,
  501. (void *) topics);
  502. /*
  503. * If we just malloc'ed ourselves out of existence...
  504. * stop here.
  505. */
  506. if (vol->keywords == 0 || vol->keywordTopics == 0)
  507. {
  508. if (vol->keywords != NULL)
  509. {
  510. free(nextKey);
  511. _DtHelpCeFreeStringArray (vol->keywords);
  512. _DtHelpCeFreeStringArray (topics);
  513. vol->keywords = NULL;
  514. }
  515. if (vol->keywordTopics)
  516. {
  517. char ***topicList;
  518. for (topicList = vol->keywordTopics; topicList; topicList++)
  519. _DtHelpCeFreeStringArray (*topicList);
  520. free (vol->keywordTopics);
  521. vol->keywordTopics = NULL;
  522. }
  523. return -1;
  524. }
  525. }
  526. if (_DtCvContainerListOfSeg(p_seg) != NULL &&
  527. ProcessSubEntries(vol,_DtCvContainerListOfSeg(p_seg),nextKey) == -1)
  528. return -1;
  529. if (topics == NULL)
  530. free (nextKey);
  531. p_seg = p_seg->next_seg;
  532. }
  533. return (0);
  534. }
  535. /******************************************************************************
  536. * Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids)
  537. *
  538. * Parameters:
  539. *
  540. * Return Value: 0 if successful, -1 if failure.
  541. *
  542. * Memory: The memory returned in ret_ids is owned by the caller.
  543. *
  544. * Purpose: To come up with a path from the top of the volume to the
  545. * target id.
  546. *
  547. ******************************************************************************/
  548. static int
  549. MapPath (
  550. _DtCvSegment **cur_id,
  551. _DtCvSegment *target_el,
  552. int stop_lev,
  553. int lev_cnt,
  554. int hidden_no,
  555. char ***ret_ids)
  556. {
  557. _DtCvSegment *mySeg = *cur_id;
  558. int count = -1;
  559. int myLev;
  560. SDLIdInfo *info;
  561. while (mySeg != NULL)
  562. {
  563. /*
  564. * Does this match the target id?
  565. * And, is the element a child of the current path?
  566. */
  567. info = _SdlSegToSdlIdInfoPtr(mySeg);
  568. myLev = _SdlIdInfoPtrRlevel(info);
  569. if (target_el == mySeg && (myLev == -1 || myLev > stop_lev))
  570. {
  571. /*
  572. * matched the target id.
  573. * allocate memory and return.
  574. */
  575. count = 0;
  576. if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
  577. {
  578. count++;
  579. lev_cnt++;
  580. }
  581. *ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1));
  582. if ((*ret_ids) == NULL)
  583. return -1;
  584. (*ret_ids)[lev_cnt] = NULL;
  585. if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
  586. (*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg));
  587. return count;
  588. }
  589. else if (myLev != -1 && myLev != hidden_no
  590. && _SdlIdInfoPtrType(info) == SdlIdVirpage)
  591. {
  592. char *myId = _DtCvContainerIdOfSeg(mySeg);
  593. /*
  594. * If we've hit a virpage that is a sibling or an aunt
  595. * set the search pointer to this segment (since this
  596. * is where we want to start searching again) and return
  597. * a negative on the successful search.
  598. */
  599. if (myLev <= stop_lev)
  600. {
  601. *cur_id = mySeg;
  602. return -1;
  603. }
  604. /*
  605. * this virpage is a child of mine, so look at it's children
  606. * for the target id.
  607. */
  608. mySeg = mySeg->next_seg;
  609. count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no,
  610. ret_ids);
  611. /*
  612. * successful response on finding the target id in the virpage's
  613. * children. Duplicate the virpage's id string and return to
  614. * my parent.
  615. */
  616. if (count != -1)
  617. {
  618. (*ret_ids)[lev_cnt] = strdup(myId);
  619. count++;
  620. return count;
  621. }
  622. }
  623. else /* did not match the target id and is not a virpage
  624. * or is a hidden virpage */
  625. mySeg = mySeg->next_seg;
  626. }
  627. *cur_id = mySeg;
  628. return -1;
  629. }
  630. /******************************************************************************
  631. * Semi-Private Functions
  632. ******************************************************************************/
  633. /*******************************************************************************
  634. * Function: CESDLVolume *_DtHelpCeGetSdlVolumePtr (_DtHelpVolumeHdl vol);
  635. *
  636. * Parameters: vol Specifies the loaded volume.
  637. *
  638. * Return Value: 0 if successful, -1 if a failure occurs
  639. *
  640. * errno Values: None
  641. *
  642. * Purpose: When the volume is no longer needed, it should be unloaded
  643. * with this call. Unloading it frees the memory (which means
  644. * any handles on the volume become invalid.)
  645. *
  646. ******************************************************************************/
  647. CESDLVolume *
  648. _DtHelpCeGetSdlVolumePtr (
  649. _DtHelpVolumeHdl volume)
  650. {
  651. _DtHelpVolume vol = (_DtHelpVolume) volume;
  652. if (vol != NULL)
  653. return ((CESDLVolume *) vol->vols.sdl_vol);
  654. return NULL;
  655. }
  656. /******************************************************************************
  657. * Semi-Public Functions
  658. ******************************************************************************/
  659. /*******************************************************************************
  660. * Function: void _DtHelpCeInitSdlVolume (_DtHelpVolume vol);
  661. *
  662. * Parameters: vol Specifies the loaded volume.
  663. *
  664. * Return Value: 0 if successful, -1 if a failure occurs
  665. *
  666. * errno Values: None
  667. *
  668. * Purpose: When the volume is no longer needed, it should be unloaded
  669. * with this call. Unloading it frees the memory (which means
  670. * any handles on the volume become invalid.)
  671. *
  672. ******************************************************************************/
  673. void
  674. _DtHelpCeInitSdlVolume (
  675. _DtHelpVolumeHdl volume)
  676. {
  677. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  678. if (sdlVol != NULL)
  679. *sdlVol = DefaultSdlVolume;
  680. }
  681. /*******************************************************************************
  682. * Function: void _DtHelpCeOpenSdlVolume (_DtHelpVolume vol);
  683. *
  684. * Parameters: vol Specifies the loaded volume.
  685. *
  686. * Return Value: 0 if successful, -1 if a failure occurs
  687. *
  688. * errno Values: None
  689. *
  690. * Purpose: When the volume is no longer needed, it should be unloaded
  691. * with this call. Unloading it frees the memory (which means
  692. * any handles on the volume become invalid.)
  693. *
  694. ******************************************************************************/
  695. int
  696. _DtHelpCeOpenSdlVolume (
  697. _DtHelpVolumeHdl volume)
  698. {
  699. CESDLVolume *sdlVol;
  700. _DtHelpVolume vol = (_DtHelpVolume) volume;
  701. sdlVol = (CESDLVolume *) calloc (1, sizeof(CESDLVolume));
  702. if (sdlVol != NULL)
  703. {
  704. vol->vols.sdl_vol = (SdlVolumeHandle) sdlVol;
  705. _DtHelpCeInitSdlVolume(volume);
  706. if (_DtHelpCeFrmtSdlVolumeInfo(vol->volFile,
  707. vol, &(vol->check_time)) == 0)
  708. {
  709. vol->sdl_flag = True;
  710. return 0;
  711. }
  712. vol->vols.sdl_vol = NULL;
  713. free(sdlVol);
  714. }
  715. return -1;
  716. }
  717. /*******************************************************************************
  718. * Function: void _DtHelpCeCleanSdlVolume (_DtHelpVolume vol);
  719. *
  720. * Parameters: vol Specifies the loaded volume.
  721. *
  722. * Return Value: 0 if successful, -1 if a failure occurs
  723. *
  724. * errno Values: None
  725. *
  726. * Purpose: When the volume is no longer needed, it should be unloaded
  727. * with this call. Unloading it frees the memory (which means
  728. * any handles on the volume become invalid.)
  729. *
  730. ******************************************************************************/
  731. void
  732. _DtHelpCeCleanSdlVolume (
  733. _DtHelpVolumeHdl volume)
  734. {
  735. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  736. if (sdlVol != NULL)
  737. {
  738. _DtHelpFreeSegments(sdlVol->snb , _DtCvFALSE, sdlVol->destroy_region,
  739. sdlVol->client_data);
  740. _DtHelpFreeSegments(sdlVol->title, _DtCvFALSE, sdlVol->destroy_region,
  741. sdlVol->client_data);
  742. /*
  743. * free the index information
  744. */
  745. FreeEntryInfo(sdlVol->index);
  746. _DtHelpFreeSegments(sdlVol->index, _DtCvFALSE, NULL, NULL);
  747. /*
  748. * free the toss information.
  749. */
  750. FreeTossInfo(sdlVol->toss);
  751. _DtHelpFreeSegments(sdlVol->toss , _DtCvFALSE, NULL, NULL);
  752. /*
  753. * free the ids
  754. */
  755. FreeIds(sdlVol->loids);
  756. _DtHelpFreeSegments(sdlVol->loids, _DtCvFALSE, NULL, NULL);
  757. /*
  758. * free the document information.
  759. */
  760. if (NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
  761. free(_SdlDocInfoPtrLanguage(sdlVol->sdl_info));
  762. if (NULL != _SdlDocInfoPtrCharSet(sdlVol->sdl_info))
  763. free(_SdlDocInfoPtrCharSet(sdlVol->sdl_info));
  764. if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
  765. free(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
  766. if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
  767. free(_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
  768. if (NULL != _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info))
  769. free(_SdlDocInfoPtrSdlDtd(sdlVol->sdl_info));
  770. if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
  771. free(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
  772. free(sdlVol->sdl_info);
  773. }
  774. }
  775. /*******************************************************************************
  776. * Function: int _DtHelpCeRereadSdlVolume (_DtHelpVolume vol);
  777. *
  778. * Parameters: vol Specifies the loaded volume.
  779. *
  780. * Return Value: 0 if successful, -1 if a failure occurs
  781. *
  782. * errno Values: None
  783. *
  784. * Purpose: When the volume is no longer needed, it should be unloaded
  785. * with this call. Unloading it frees the memory (which means
  786. * any handles on the volume become invalid.)
  787. *
  788. ******************************************************************************/
  789. int
  790. _DtHelpCeRereadSdlVolume (
  791. _DtHelpVolumeHdl volume)
  792. {
  793. _DtHelpCeCleanSdlVolume(volume);
  794. _DtHelpCeInitSdlVolume(volume);
  795. if (_DtHelpCeFrmtSdlVolumeInfo(_DtHelpCeGetVolumeName(volume),
  796. volume, NULL) == 0)
  797. return 0;
  798. return -1;
  799. }
  800. /*******************************************************************************
  801. * Function: void _DtHelpCeCloseSdlVolume (_DtHelpVolume vol);
  802. *
  803. * Parameters: vol Specifies the loaded volume.
  804. *
  805. * Return Value: 0 if successful, -1 if a failure occurs
  806. *
  807. * errno Values: None
  808. *
  809. * Purpose: When the volume is no longer needed, it should be unloaded
  810. * with this call. Unloading it frees the memory (which means
  811. * any handles on the volume become invalid.)
  812. *
  813. ******************************************************************************/
  814. void
  815. _DtHelpCeCloseSdlVolume (
  816. _DtHelpVolumeHdl volume)
  817. {
  818. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  819. if (sdlVol != NULL)
  820. {
  821. _DtHelpCeCleanSdlVolume(volume);
  822. free(sdlVol);
  823. }
  824. }
  825. /*****************************************************************************
  826. * Function: Boolean _DtHelpCeGetSdlHomeTopicId (_DtHelpVolume vol,
  827. * char *target_id,
  828. * char *ret_name, int *ret_offset)
  829. *
  830. * Parameters: vol Specifies the loaded volume
  831. * target_id Specifies target location ID
  832. * ret_name Returns a null terminated string
  833. * containing a fully qualified path to
  834. * the file that contains 'target_id'.
  835. * ret_offset Returns the offset into 'ret_name'
  836. * to the topic that contains 'target_id'.
  837. *
  838. * Memory own by caller:
  839. * ret_name
  840. *
  841. * Returns: True if successful, False if a failure occurs
  842. *
  843. * errno Values: EINVAL Specifies an invalid parameter was
  844. * used.
  845. * CEErrorMalloc
  846. * CEErrorLocIdNotFound
  847. * Specifies that 'locId' was not
  848. * found.
  849. *
  850. * Purpose: Find which topic contains a specified locationID.
  851. *
  852. *****************************************************************************/
  853. char *
  854. _DtHelpCeGetSdlHomeTopicId (
  855. _DtHelpVolumeHdl volume)
  856. {
  857. _DtCvSegment *idSegs;
  858. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  859. if (sdlVol->sdl_info != NULL)
  860. {
  861. /*
  862. * Was the first page topic declared in the header?
  863. */
  864. if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
  865. return (_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
  866. /*
  867. * have to search the list of ids for the home topic. This is a
  868. * bit of a kludge since we are looking for a specific string in
  869. * the rssi. But this is for backwards compatibility since the
  870. * Snapshot release of the help system were released with out
  871. * the first-page attribute and relied on _hometopic.
  872. *
  873. * Plus, first-page is #IMPLIED, which means that the parser
  874. * that generated this SDL document does not have to use this
  875. * attribute.
  876. */
  877. if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
  878. return NULL;
  879. while (idSegs != NULL)
  880. {
  881. if (SdlIdVirpage == _SdlSegToSdlIdInfoType(idSegs) &&
  882. _DtHelpCeStrCaseCmpLatin1(_SdlIdInfoPtrRssi(
  883. _SdlSegToSdlIdInfoPtr(idSegs)),
  884. "_hometopic") == 0)
  885. return _DtCvContainerIdOfSeg(idSegs);
  886. idSegs = idSegs->next_seg;
  887. }
  888. }
  889. return NULL;
  890. }
  891. /*****************************************************************************
  892. * Function: Boolean _DtHelpCeFindSdlId (_DtHelpVolume vol, char *target_id,
  893. * char *ret_name, int *ret_offset)
  894. *
  895. * Parameters: vol Specifies the loaded volume
  896. * target_id Specifies target location ID
  897. * ret_name Returns a null terminated string
  898. * containing a fully qualified path to
  899. * the file that contains 'target_id'.
  900. * ret_offset Returns the offset into 'ret_name'
  901. * to the topic that contains 'target_id'.
  902. *
  903. * Memory own by caller:
  904. * ret_name
  905. *
  906. * Returns: True if successful, False if a failure occurs
  907. *
  908. * errno Values: EINVAL Specifies an invalid parameter was
  909. * used.
  910. * CEErrorMalloc
  911. * CEErrorLocIdNotFound
  912. * Specifies that 'locId' was not
  913. * found.
  914. *
  915. * Purpose: Find which topic contains a specified locationID.
  916. *
  917. *****************************************************************************/
  918. int
  919. _DtHelpCeFindSdlId (
  920. _DtHelpVolumeHdl volume,
  921. char *target_id,
  922. int fd,
  923. char **ret_name,
  924. int *ret_offset )
  925. {
  926. _DtHelpVolume vol = (_DtHelpVolume) volume;
  927. _DtCvSegment *pEl;
  928. pEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, fd);
  929. if (pEl != NULL)
  930. {
  931. if (ret_name != NULL)
  932. *ret_name = strdup(vol->volFile);
  933. *ret_offset = _SdlIdInfoPtrOffset(_SdlSegToSdlIdInfoPtr(pEl));
  934. return True;
  935. }
  936. return False;
  937. }
  938. /*****************************************************************************
  939. * Function: int _DtHelpCeGetSdlKeywordList (
  940. *
  941. * Parameters:
  942. *
  943. * Returns: 0 if successful, -1 if not.
  944. *
  945. * errno Values:
  946. *
  947. * Purpose: Get the KeywordList for an SDL volume.
  948. *
  949. *****************************************************************************/
  950. int
  951. _DtHelpCeGetSdlKeywordList (
  952. _DtHelpVolumeHdl volume)
  953. {
  954. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  955. if (_DtHelpCeGetSdlVolIndex(volume) != 0 || NULL == sdlVol->index
  956. || NULL == _DtCvContainerListOfSeg(sdlVol->index))
  957. return -1;
  958. return(ProcessEntry(((_DtHelpVolume) volume),
  959. _DtCvContainerListOfSeg(sdlVol->index), NULL));
  960. }
  961. /*****************************************************************************
  962. * Function: int _DtHelpCeGetSdlVolumeAsciiAbstract(volume);
  963. *
  964. * Parameters:
  965. *
  966. * Returns: 0 if successful, -1 if not.
  967. *
  968. * errno Values:
  969. *
  970. * Purpose: Get the KeywordList for an SDL volume.
  971. *
  972. *****************************************************************************/
  973. char *
  974. _DtHelpCeGetSdlVolumeAsciiAbstract(
  975. _DtHelpVolumeHdl volume)
  976. {
  977. return(_DtHelpCeFrmtSdlVolumeAbstractToAscii(volume));
  978. }
  979. /*****************************************************************************
  980. * Function: int _DtHelpCeGetSdlIdPath(volume, target_id, ret_ids);
  981. *
  982. * Parameters:
  983. *
  984. * Returns: > 0 if successful, -1 if not.
  985. *
  986. * Memory: The memory returned is owned by the caller.
  987. *
  988. * Purpose: Get the list of location ids between the top and the
  989. * target_id.
  990. *
  991. *****************************************************************************/
  992. int
  993. _DtHelpCeGetSdlIdPath(
  994. _DtHelpVolumeHdl volume,
  995. char *target_id,
  996. char ***ret_ids)
  997. {
  998. _DtCvSegment *idSegs;
  999. _DtCvSegment *targetEl;
  1000. int hiddenNo = -1;
  1001. targetEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
  1002. if (targetEl == NULL)
  1003. return -1;
  1004. *ret_ids = NULL;
  1005. if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
  1006. return 0;
  1007. if (_SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)) >= SDL_DTD_1_1)
  1008. hiddenNo = 0;
  1009. return (MapPath(&idSegs, targetEl, -1, 0, hiddenNo, ret_ids));
  1010. }
  1011. /*****************************************************************************
  1012. * Function: _DtCvSegment *_DtHelpCeMapSdlIdToSegment(volume, target_id);
  1013. *
  1014. * Parameters:
  1015. *
  1016. * Returns: > 0 if successful, -1 if not.
  1017. *
  1018. * errno Values:
  1019. *
  1020. * Purpose: Get the list of location ids between the top and the
  1021. * target_id.
  1022. *
  1023. *****************************************************************************/
  1024. _DtCvSegment *
  1025. _DtHelpCeMapSdlIdToSegment(
  1026. _DtHelpVolumeHdl volume,
  1027. const char *target_id,
  1028. int fd)
  1029. {
  1030. int underScore = False;
  1031. short minorNo;
  1032. _DtCvSegment *idSegs;
  1033. char *idString;
  1034. char resStr[128] = "SDL-RESERVED-";
  1035. minorNo = _SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume));
  1036. if (*target_id == '_')
  1037. {
  1038. /*
  1039. * parsers generating SDL_DTD_1_0 and earlier put the special
  1040. * access points (_hometopic, _abstract, _copyright, etc.) in
  1041. * the SSI.
  1042. */
  1043. if (minorNo < SDL_DTD_1_1)
  1044. underScore = True;
  1045. else
  1046. {
  1047. target_id++;
  1048. strcat(resStr, target_id);
  1049. target_id = resStr;
  1050. }
  1051. }
  1052. if (_DtHelpCeGetSdlVolIds(volume, fd, &idSegs) != 0)
  1053. return NULL;
  1054. while (idSegs != NULL)
  1055. {
  1056. if (underScore == True)
  1057. idString = _SdlIdInfoPtrRssi(_SdlSegToSdlIdInfoPtr(idSegs));
  1058. else
  1059. idString = _DtCvContainerIdOfSeg(idSegs);
  1060. if (idString != NULL &&
  1061. _DtHelpCeStrCaseCmpLatin1(idString, target_id) == 0)
  1062. return idSegs;
  1063. idSegs = idSegs->next_seg;
  1064. }
  1065. return NULL;
  1066. }
  1067. /*****************************************************************************
  1068. * Function: int _DtHelpCeMapIdToSdlTopicId(volume, target_id);
  1069. *
  1070. * Parameters:
  1071. *
  1072. * Returns: > 0 if successful, -1 if not.
  1073. *
  1074. * errno Values:
  1075. *
  1076. * Purpose: Get the id of the virpage containing the target_id.
  1077. *
  1078. *****************************************************************************/
  1079. int
  1080. _DtHelpCeMapIdToSdlTopicId(
  1081. _DtHelpVolumeHdl volume,
  1082. const char *target_id,
  1083. char **ret_id)
  1084. {
  1085. int found = -1;
  1086. _DtCvSegment *idList;
  1087. _DtCvSegment *idSeg;
  1088. SDLIdInfo *idInfo;
  1089. if (_DtHelpCeGetSdlVolIds(volume, -1, &idList) == 0)
  1090. {
  1091. idSeg = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
  1092. if (idSeg != NULL)
  1093. {
  1094. while (found == -1 && idList != NULL)
  1095. {
  1096. idInfo = _SdlSegToSdlIdInfoPtr(idList);
  1097. if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
  1098. *ret_id = _DtCvContainerIdOfSeg(idList);
  1099. if (idList == idSeg)
  1100. found = 0;
  1101. else
  1102. idList = idList->next_seg;
  1103. }
  1104. }
  1105. }
  1106. return found;
  1107. }
  1108. /*****************************************************************************
  1109. * Function: char * _DtHelpCeGetSdlVolCharSet(volume);
  1110. *
  1111. * Parameters:
  1112. *
  1113. * Returns: the pointer to the locale string. Null otherwise.
  1114. *
  1115. * errno Values:
  1116. *
  1117. * Purpose: Get the locale of the volume.
  1118. *
  1119. *****************************************************************************/
  1120. const char *
  1121. _DtHelpCeGetSdlVolCharSet(
  1122. _DtHelpVolumeHdl volume)
  1123. {
  1124. const char *charSet = IsoString;
  1125. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  1126. if (sdlVol->sdl_info != NULL &&
  1127. NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
  1128. charSet = _SdlDocInfoPtrCharSet(sdlVol->sdl_info);
  1129. return charSet;
  1130. }
  1131. /*****************************************************************************
  1132. * Function: char * _DtHelpCeGetSdlVolLanguage(volume);
  1133. *
  1134. * Parameters:
  1135. *
  1136. * Returns: the pointer to the language used in the volume.
  1137. *
  1138. * errno Values:
  1139. *
  1140. * Purpose: Get the locale of the volume.
  1141. *
  1142. *****************************************************************************/
  1143. char *
  1144. _DtHelpCeGetSdlVolLanguage(
  1145. _DtHelpVolumeHdl volume)
  1146. {
  1147. char *language = "C";
  1148. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  1149. if (sdlVol->sdl_info != NULL &&
  1150. NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
  1151. language = _SdlDocInfoPtrLanguage(sdlVol->sdl_info);
  1152. return language;
  1153. }
  1154. /*****************************************************************************
  1155. * Function: char * _DtHelpCeGetSdlVolumeLocale(volume);
  1156. *
  1157. * Parameters:
  1158. *
  1159. * Returns: the pointer to the locale string. Null otherwise.
  1160. *
  1161. * errno Values:
  1162. *
  1163. * Purpose: Get the locale of the volume.
  1164. *
  1165. *****************************************************************************/
  1166. char *
  1167. _DtHelpCeGetSdlVolumeLocale(
  1168. _DtHelpVolumeHdl volume)
  1169. {
  1170. int langLen;
  1171. char *locale;
  1172. char *lang;
  1173. const char *charSet;
  1174. lang = _DtHelpCeGetSdlVolLanguage(volume);
  1175. charSet = _DtHelpCeGetSdlVolCharSet(volume);
  1176. langLen = strlen(lang);
  1177. locale = (char *) malloc (langLen + strlen(charSet) + 2);
  1178. if (locale != NULL)
  1179. {
  1180. strcpy(locale, lang);
  1181. if (langLen != 0 && *charSet != '\0')
  1182. {
  1183. locale[langLen++] = '.';
  1184. strcpy(&(locale[langLen]), charSet);
  1185. }
  1186. }
  1187. return locale;
  1188. }
  1189. /*****************************************************************************
  1190. * Function: int _DtHelpCeGetSdlDocStamp(volume, ret_doc, ret_time);
  1191. *
  1192. * Parameters:
  1193. *
  1194. * Returns: 0 if successful, -2 if the volume does not contain
  1195. * one or the other, -1 if any other failure.
  1196. *
  1197. * Memory: The Caller owns the memory returned in ret_doc and ret_time.
  1198. *
  1199. * Purpose: Get the doc id and time stamp of a volume.
  1200. *
  1201. *****************************************************************************/
  1202. int
  1203. _DtHelpCeGetSdlDocStamp(
  1204. _DtHelpVolumeHdl volume,
  1205. char **ret_doc,
  1206. char **ret_time)
  1207. {
  1208. int result = -1;
  1209. char *docId = NULL;
  1210. char *timestamp = NULL;
  1211. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  1212. if (sdlVol->sdl_info != NULL)
  1213. {
  1214. result = 0;
  1215. if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
  1216. docId = strdup(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
  1217. else
  1218. result = -2;
  1219. if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
  1220. timestamp = strdup(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
  1221. else
  1222. result = -2;
  1223. }
  1224. if (ret_doc != NULL)
  1225. *ret_doc = docId;
  1226. if (ret_time != NULL)
  1227. *ret_time = timestamp;
  1228. if (result == 0 && (docId == NULL || timestamp == NULL)) {
  1229. free(docId); /* Incase only one of them is NULL */
  1230. free(timestamp); /* " */
  1231. return -1;
  1232. }
  1233. return result;
  1234. }
  1235. /*****************************************************************************
  1236. * Function: int _DtHelpCeGetSdlTopicChildren(
  1237. *
  1238. * Parameters:
  1239. *
  1240. * Returns: pointer to the element, Null otherwise.
  1241. *
  1242. * errno Values:
  1243. *
  1244. * Purpose: Find the specified element.
  1245. *
  1246. *****************************************************************************/
  1247. int
  1248. _DtHelpCeGetSdlTopicChildren(
  1249. _DtHelpVolumeHdl volume,
  1250. char *target,
  1251. char ***ret_ids)
  1252. {
  1253. int done = False;
  1254. int count = 0;
  1255. int segLev;
  1256. _DtCvSegment *idSeg;
  1257. SDLIdInfo *idInfo;
  1258. /*
  1259. * Find the target id.
  1260. */
  1261. idSeg = _DtHelpCeMapSdlIdToSegment(volume, target, -1);
  1262. /*
  1263. * save this level and start looking for its children at the next seg.
  1264. */
  1265. *ret_ids = NULL;
  1266. if (idSeg != NULL)
  1267. {
  1268. idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
  1269. segLev = _SdlIdInfoPtrRlevel(idInfo) + 1;
  1270. idSeg = idSeg->next_seg;
  1271. }
  1272. /*
  1273. * process any virpage that has the correct level
  1274. */
  1275. while (idSeg != NULL && done == False)
  1276. {
  1277. idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
  1278. if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
  1279. {
  1280. /*
  1281. * If greater, we're at the next sibling.
  1282. */
  1283. if (segLev > _SdlIdInfoPtrRlevel(idInfo))
  1284. done = True;
  1285. else if (segLev == _SdlIdInfoPtrRlevel(idInfo))
  1286. {
  1287. *ret_ids = (char **) _DtHelpCeAddPtrToArray( (void **) *ret_ids,
  1288. (void *)(strdup(_DtCvContainerIdOfSeg(idSeg))));
  1289. if ((*ret_ids) == NULL)
  1290. return -1;
  1291. count++;
  1292. }
  1293. }
  1294. idSeg = idSeg->next_seg;
  1295. }
  1296. return count;
  1297. }