AccessSDL.c 38 KB

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