1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: Access.c /main/11 1996/11/01 10:09:29 drk $ */
- /************************************<+>*************************************
- ****************************************************************************
- **
- ** File: Access.c
- **
- ** Project: Run Time Project File Access
- **
- ** Description: This body of code handles the access routines for the
- ** Display Area.
- **
- **
- ** (c) Copyright 1987-1994, 1996 Hewlett-Packard Company
- ** (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
- ** (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
- ** (c) Copyright 1993, 1994, 1996 Novell, Inc.
- ** (c) Copyright 1996 Digital Equipment Corporation.
- ** (c) Copyright 1996 FUJITSU LIMITED.
- ** (c) Copyright 1996 Hitachi.
- **
- **
- ****************************************************************************
- ************************************<+>*************************************/
- /*
- * system includes
- */
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <X11/Xlib.h>
- #include <X11/Xresource.h>
- #ifdef X_NOT_STDC_ENV
- extern int errno;
- #endif
- /*
- * Canvas Engine includes
- */
- #include "CanvasP.h"
- #include "CanvasSegP.h"
- /*
- * private includes
- */
- #include "CanvasError.h"
- #include "Access.h"
- #include "bufioI.h"
- #include "FontAttrI.h"
- #include "AccessP.h"
- #include "AccessI.h"
- #include "AccessSDLP.h"
- #include "AccessSDLI.h"
- #include "AccessCCDFI.h"
- #include "FormatUtilI.h"
- #include "SDLI.h"
- #include "FormatSDLI.h"
- #include "CCDFUtilI.h"
- #include "StringFuncsI.h"
- #include "Lock.h" /* Process and App Lock macros */
- #ifdef NLS16
- #endif
- /******** Private Defines ********/
- #define LIST_INCREMENT 10
- #define BUFF_SIZE 256
- /******** End Private Defines ********/
- /******** Private Function Declarations ********/
- static int GetVolumeKeywords (
- _DtHelpVolume vol,
- char ***retKeywords);
- static int VolumeLoad (
- char *volFile,
- _DtHelpVolume *retVol);
- static int VolumeUnload (
- _DtHelpVolume vol);
- /******** End Private Function Declarations ********/
- /******** Private Macro Declarations ********/
- /******** End Private Macro Declarations ********/
- /******************************************************************************
- *
- * Private variables used within this file.
- *
- *******************************************************************************/
- static _DtHelpVolume volChain = NULL; /* Pointer to the head of the chain */
- /* of all the open volumes. */
- static const char *Slash = "/";
- static const char *Period = ".";
- /******************************************************************************
- * Private Functions
- ******************************************************************************/
- /******************************************************************************
- * Function: CheckVolList (_DtHelpVolume vol, _DtHelpVolume *ret_prev)
- *
- * Parameters: vol Specifies the volume to search for.
- * ret_prev Returns the volume whose nextVol element
- * points to 'vol' if non NULL.
- *
- * Returns: 0 if successful, -1 if failure.
- *
- * errno Values:
- *
- * Purpose: To check for the existence of a volume.
- *
- ******************************************************************************/
- static int
- CheckVolList (
- _DtHelpVolume vol,
- _DtHelpVolume *ret_prev )
- {
- _DtHelpVolume myVol;
- _DtHelpVolume prevVol = NULL;
- _DtHelpProcessLock();
- myVol = volChain;
- while (myVol != NULL && myVol != vol)
- {
- prevVol = myVol;
- myVol = myVol->nextVol;
- }
- if (ret_prev)
- *ret_prev = prevVol;
- if (myVol != vol)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- _DtHelpProcessUnlock();
- return 0;
- }
- /******************************************************************************
- * Function: int VolumeLoad (char *volFile, _DtHelpVolume *retVol);
- *
- * Parameters: volFile Specifies the name of the Help Volume file
- * to load.
- *
- * retVol Returns the handle to the loaded volume.
- *
- * Return Value: Returns 0 if successful,
- * -1 if an error occurred.
- *
- * errno Values: CEErrorMalloc
- * CEErrorIllegalDatabaseFile
- *
- * Purpose: This function must be called to load a Help Volume file
- * before any of the information in the volume can be
- * accessed.
- *
- ******************************************************************************/
- static int
- VolumeLoad (
- char *volFile,
- _DtHelpVolume *retVol)
- {
- /* Allocate the volume structure and initialize it. */
- *retVol = (_DtHelpVolume) malloc (sizeof (struct _DtHelpVolumeRec));
- if (*retVol)
- {
- (*retVol)->sdl_flag = False;
- (*retVol)->volFile = volFile;
- (*retVol)->keywords = NULL;
- (*retVol)->keywordTopics = NULL;
- (*retVol)->openCount = 1;
- (*retVol)->nextVol = NULL;
- (*retVol)->vols.ccdf_vol = NULL;
- if (_DtHelpCeOpenSdlVolume ((*retVol)) == 0)
- return 0;
- else if (_DtHelpCeOpenCcdfVolume(*retVol) == 0)
- return 0;
- /*
- * Set the global error
- */
- errno = CEErrorIllegalDatabaseFile;
- /*
- * error on loading the database.
- */
- free ((char *) ((*retVol)->volFile));
- free ((char *) (*retVol));
- *retVol = NULL;
- }
- else
- errno = CEErrorMalloc;
- return -1;
- } /* End VolumeLoad */
- /*******************************************************************************
- * Function: int VolumeUnload (_DtHelpVolume vol);
- *
- * Parameters: vol Specifies the loaded volume.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * errno Values: None
- *
- * Purpose: When the volume is no longer needed, it should be unloaded
- * with this call. Unloading it frees the memory (which means
- * any handles on the volume become invalid.)
- *
- ******************************************************************************/
- static int
- VolumeUnload (
- _DtHelpVolume vol)
- {
- char ***topicList;
-
- if (vol != NULL)
- {
- if (vol->sdl_flag == True)
- _DtHelpCeCloseSdlVolume((_DtHelpVolumeHdl) vol);
- else
- _DtHelpCeCloseCcdfVolume(vol);
- if (vol->volFile != NULL)
- free (vol->volFile);
- if (vol->keywords != NULL)
- _DtHelpCeFreeStringArray (vol->keywords);
- if (vol->keywordTopics != NULL)
- {
- for (topicList = vol->keywordTopics;
- *topicList != NULL; topicList++)
- _DtHelpCeFreeStringArray (*topicList);
- free (vol->keywordTopics);
- }
- free (vol);
- }
- return (0);
- }
- /*******************************************************************************
- * Function: int RereadVolume (_DtHelpVolume vol);
- *
- * Parameters: vol Specifies the loaded volume.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * errno Values: None
- *
- * Purpose: When the volume is no longer needed, it should be unloaded
- * with this call. Unloading it frees the memory (which means
- * any handles on the volume become invalid.)
- *
- ******************************************************************************/
- static int
- RereadVolume (
- _DtHelpVolume vol)
- {
- int result;
- char ***topicList;
-
- if (vol->keywords != NULL)
- {
- _DtHelpCeFreeStringArray (vol->keywords);
- vol->keywords = NULL;
- }
- if (vol->keywordTopics != NULL)
- {
- for (topicList = vol->keywordTopics; *topicList != NULL; topicList++)
- _DtHelpCeFreeStringArray (*topicList);
- free (vol->keywordTopics);
- vol->keywordTopics = NULL;
- }
- if (vol->sdl_flag == False)
- result = _DtHelpCeRereadCcdfVolume(vol);
- else
- result = _DtHelpCeRereadSdlVolume(vol);
- return (result);
- }
- /******************************************************************************
- * Function: static int GetKeywordTopics (_DtHelpVolume vol, char *keyword,
- * char ***topics);
- *
- * Parameters: vol Specifies the loaded volume
- * keyword Specifies the keyword whose location is desired.
- * topics Returns a NULL-terminated string array of the
- * list of topics which contain the keyword.
- * This array is NOT owned by the caller and
- * should only be read or copied.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * errno Values: CEErrorNoKeywordList
- * Specifies that the volume does not
- * have a keyword list.
- * CEErrorIllegalKeyword
- * Specifies that 'keyword' was not
- * found.
- * CEErrorMalloc
- * CEErrorIllegalDatabaseFile
- * Specifies that the keyword file is
- * invalid or corrupt.
- * CEErrorMissingKeywordsRes
- * Specifies that the keyword file does
- * not contain the 'Keywords/keywords'
- * resource or the resource is NULL
- *
- *
- * Purpose: Find which topic contains a specified locationId.
- *
- ******************************************************************************/
- static int
- GetKeywordTopics (
- _DtHelpVolume vol,
- char *keyword,
- char ***retTopics)
- {
- char **keywords;
- char **nextKey;
- int index;
- _DtHelpProcessLock();
- *retTopics = NULL;
- /* Get the list of keywords. */
- if (GetVolumeKeywords (vol, &keywords) != 0)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- if (keywords == NULL || vol->keywordTopics == NULL)
- {
- errno = CEErrorNoKeywordList;
- _DtHelpProcessUnlock();
- return -1;
- }
- /* Search the list of keywords for the current one. */
- nextKey = keywords;
- while (*nextKey != NULL && strcmp (*nextKey, keyword))
- nextKey++;
- if (*nextKey == NULL)
- {
- errno = CEErrorIllegalKeyword;
- _DtHelpProcessUnlock();
- return -1;
- }
- index = nextKey - keywords;
- *retTopics = *(vol->keywordTopics + index);
- _DtHelpProcessUnlock();
- return (0);
- }
- /******************************************************************************
- * Function: static int GetVolumeKeywords(_DtHelpVolume vol,char ***keywords);
- *
- * Parameters: vol Specifies the volume.
- * keywords Returns a NULL-terminated string array
- * containing the sorted list of keywords in the
- * volume. This array is NOT owned by the caller
- * and should only be read or copied.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * errno Values: CEErrorMalloc
- * CEErrorIllegalDatabaseFile
- * Specifies that the keyword file is
- * invalid or corrupt.
- * CEErrorMissingKeywordsRes
- * Specifies that the keyword file does
- * not contain the 'Keywords/keywords'
- * resource or the resource is NULL
- *
- * Purpose: Get the list of keywords defined in a volume.
- *
- ******************************************************************************/
- static int
- GetVolumeKeywords (
- _DtHelpVolume vol,
- char ***retKeywords)
- {
- int result;
- _DtHelpCeLockInfo lockInfo;
- _DtHelpProcessLock();
- /* Keywords aren't loaded until they are needed, so see if they have
- been loaded yet. */
- if (vol->keywords == NULL)
- {
- /*
- * What type of volume is it?
- */
- if (_DtHelpCeLockVolume(vol, &lockInfo) != 0)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- if (vol->sdl_flag == False)
- result = _DtHelpCeGetCcdfKeywordList(vol);
- else
- result = _DtHelpCeGetSdlKeywordList(vol);
- _DtHelpCeUnlockVolume(lockInfo);
- if (result != 0)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- }
- /* All of the keyword processing is done when they are loaded. */
- *retKeywords = vol->keywords;
- if (*retKeywords == NULL)
- {
- _DtHelpProcessUnlock();
- return (-1);
- }
- _DtHelpProcessUnlock();
- return (0);
- }
- /*****************************************************************************
- * Function: GetTopicTitleAndAbbrev (
- *
- * Parameters:
- *
- * Memory own by caller:
- * ret_name
- * ret_abrrev
- *
- * Returns: 0 if successful, -2 if didn't find the id,
- * -3 if couldn't format the topic,
- * otherwise -1.
- *
- * Purpose: Find the title and abbreviated title of a topic.
- *
- *****************************************************************************/
- static int
- GetTopicTitleAndAbbrev (
- _DtHelpVolume volume,
- char *id,
- char **ret_name,
- char **ret_abbrev )
- {
- int result = 0;
- int offset;
- char buffer[BUFF_SIZE];
- char *bufPtr;
- char *filename = NULL;
- BufFilePtr file;
- _DtHelpCeLockInfo lockInfo;
- if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
- return -1;
- if (_DtHelpCeFindId(volume, id, lockInfo.fd, &filename, &offset) != True)
- result = -2;
- /*
- * What type of volume is it?
- */
- if (result == 0)
- {
- if (0 == _DtHelpCeGetVolumeFlag(volume))
- {
- result = _DtHelpCeFileOpenAndSeek(filename,offset,-1,&file,NULL);
- if (result == 0)
- {
- result = -1;
- if (_DtHelpCeReadBuf (file, buffer, BUFF_SIZE) != -1)
- {
- result = 0;
- bufPtr = buffer;
- if (_DtHelpCeGetCcdfTopicAbbrev (NULL, file,
- buffer, &bufPtr, BUFF_SIZE, MB_CUR_MAX,
- ret_name, NULL, ret_abbrev) != 0)
- result = -3;
- }
- _DtHelpCeBufFileClose(file, True);
- }
- }
- else
- {
- _DtHelpProcessLock();
- if (_DtHelpCeFrmtSDLTitleToAscii(volume, offset,
- ret_name, ret_abbrev) != 0)
- result = -3;
- _DtHelpProcessUnlock();
- }
- }
- if (filename != NULL)
- free(filename);
- _DtHelpCeUnlockVolume(lockInfo);
- return result;
- }
- /*****************************************************************************
- * Function: static int FileOpenRtnFd (char *name, int *ret_fd)
- *
- * Parameters: name Specifies the file to open.
- * ret_fd Returns the fd of the opened file.
- *
- * Returns: 0 if required uncompress.
- * file descriptor to remove the file from the system.
- * 1 if no uncompression required.
- * -1 if a failure occurs
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorFileSeek
- * Specifies the seek offset was invalid.
- *
- * Purpose: Find out if a file is compressed and uncompress it if it is.
- *
- *****************************************************************************/
- static int
- FileOpenRtnFd (
- char *name,
- int *ret_fd )
- {
- char *inFile = NULL;
- char tmpName[MAXPATHLEN + 1];
- int result = 1;
- /*
- * check to see if the file exists in uncompressed form
- */
- *ret_fd = open(name, O_RDONLY);
- if (*ret_fd == -1)
- {
- /*
- * get a temporary name
- */
- (void) tmpnam (tmpName);
- /*
- * malloc memory for the dot Z file name.
- */
- inFile = (char *) malloc (strlen (name) + 3);
- if (inFile != NULL)
- {
- /*
- * make the dot Z file
- */
- strcpy (inFile, name);
- strcat (inFile, ".Z");
- /*
- * do the uncompress
- */
- result = _DtHelpCeUncompressFile (inFile, tmpName);
- free (inFile);
- if (result != 0)
- {
- errno = ENOENT;
- return -1;
- }
- /*
- * now open the uncompressed file
- */
- *ret_fd = open(tmpName, O_RDONLY);
- if (*ret_fd == -1)
- result = -1;
- else
- unlink(tmpName);
- }
- else
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- return result;
- } /* End FileOpenRtnFd */
- /******************************************************************************
- * Semi-Public Functions
- ******************************************************************************/
- /*****************************************************************************
- * Function: char *_DtHelpCeExpandPathname (char *spec, char *filename, char *type,
- * char *suffix, char *lang, _DtSubstitutionRec *subs, int num)
- *
- * Parameters:
- * spec Specifies a string with substitution
- * characters.
- * containing the character set if found.
- * filename Specifies the string to substitute for %N.
- * type Specifies the string to substitute for %T.
- * suffix Specifies the string to substitute for %S.
- * lang Specifies the string to substitute for %L.
- * subs Specifies the application own specific
- * substitutions.
- * num Specifies the number of substitution pairs
- * in 'subs'.
- *
- * Memory own by caller:
- * returned pointer
- *
- * Returns: The expanded filename if successful. NULL if errors.
- *
- * Purpose: Expand a string with %<char> substitution values.
- * Default substitutions are:
- * %N replaced with 'filename'.
- * %T replaced with 'type'
- * %S replaced with 'suffix'
- * %L replaced with 'lang'
- *
- * %l replaced with the language sub part of 'lang'.
- * %t replaced with the territory sub part of 'lang'.
- * %c replaced with the code set sub part of 'lang'.
- * Other substitutions can be done via the 'subs' parameter.
- *
- *****************************************************************************/
- char *
- _DtHelpCeExpandPathname (
- char *spec,
- char *filename,
- char *type,
- char *suffix,
- char *lang,
- _DtSubstitutionRec *subs,
- int num )
- {
- int i;
- int len = 1;
- char *ptr;
- char *subString;
- char *partLang;
- char *partTer;
- char *partCodeSet;
- char pathName [MAXPATHLEN + 5];
- Boolean previousSlash = False;
- #define MY_NUM 7
- _DtSubstitutionRec mySubs [MY_NUM];
- if (spec == NULL || *spec == '\0')
- {
- errno = EINVAL;
- return NULL;
- }
- /*
- * fill in the language sub parts
- */
- if (_DtHelpCeGetLangSubParts (lang, &partLang, &partTer, &partCodeSet))
- return NULL;
- mySubs[0].match = 'N';
- mySubs[0].substitution = filename;
- mySubs[1].match = 'T';
- mySubs[1].substitution = type;
- mySubs[2].match = 'S';
- mySubs[2].substitution = suffix;
- mySubs[3].match = 'L';
- mySubs[3].substitution = lang;
- mySubs[4].match = 'l';
- mySubs[4].substitution = partLang;
- mySubs[5].match = 't';
- mySubs[5].substitution = partTer;
- mySubs[6].match = 's';
- mySubs[6].substitution = partCodeSet;
- ptr = pathName;
- while (*spec)
- {
- len = 1;
- if (MB_CUR_MAX != 1)
- len = mblen (spec, MB_CUR_MAX);
- if (len == 1 && *spec == '/')
- {
- if (previousSlash)
- spec++;
- else
- {
- previousSlash = True;
- *ptr++ = *spec++;
- }
- }
- else if (len == 1 && *spec == '%')
- {
- spec++;
- switch (*spec)
- {
- case '\0':
- *ptr++ = '%';
- break;
- case '/':
- if (!previousSlash)
- {
- previousSlash = True;
- *ptr++ = *spec;
- }
- spec++;
- break;
- default:
- i = 0;
- while (i < MY_NUM && mySubs && mySubs[i].match != *spec)
- i++;
- if (i < MY_NUM)
- {
- if (mySubs[i].substitution != NULL)
- {
- subString = mySubs[i].substitution;
- if (((int)(ptr - pathName + strlen(subString)))
- > MAXPATHLEN)
- {
- errno = CEErrorExceedMaxSize;
- return NULL;
- }
- while (subString && *subString)
- *ptr++ = *subString++;
- }
- }
- else
- {
- i = 0;
- while (i < num && subs && subs[i].match != *spec)
- i++;
- /*
- * If the substitution character is not found
- * include the character onto the final string.
- */
- if (i >= num)
- *ptr++ = *spec;
- else if (subs[i].substitution != NULL)
- {
- subString = subs[i].substitution;
- if (((int)(ptr - pathName + strlen(subString)))
- > MAXPATHLEN)
- {
- errno = CEErrorExceedMaxSize;
- return NULL;
- }
- while (subString && *subString)
- *ptr++ = *subString++;
- }
- }
- spec++;
- previousSlash = False;
- break;
- }
- }
- else
- {
- previousSlash = False;
- do
- {
- *ptr++ = *spec++;
- len--;
- } while (len > 0);
- }
- if (ptr - pathName > MAXPATHLEN)
- {
- errno = CEErrorExceedMaxSize;
- return NULL;
- }
- }
- if (partLang)
- free (partLang);
- if (partTer)
- free (partTer);
- if (partCodeSet)
- free (partCodeSet);
- *ptr = '\0';
- ptr = strdup (pathName);
- if (ptr == NULL)
- errno = CEErrorMalloc;
- return ptr;
- }
- /*****************************************************************************
- * Function: char *_DtHelpCeGetLangSubParts (char *lang, char **subLang,
- * char **subTer, char **subCodeSet)
- *
- * Parameters:
- * lang Specifies the language string.
- * subLang Returns the language sub part of 'lang'
- * or NULL.
- * subTer Returns the territory sub part of 'lang'
- * or NULL.
- * subCodeSet Returns the code set sub part of 'lang'
- * or NULL.
- *
- * Memory own by caller:
- * subLang
- * subTer
- * subCodeSet
- *
- * errno Values:
- * EINVAL
- * CEErrorMalloc
- *
- * Returns: 0 if successful, -1 if errors.
- *
- * Purpose: Break a %l_%t.%c language specification into its sub parts.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetLangSubParts (
- char *lang,
- char **subLang,
- char **subTer,
- char **subCodeSet )
- {
- int len;
- char *ptr;
- char *sLang = NULL;
- char *sTer = NULL;
- char *sCode = NULL;
- if (subLang == NULL || subTer == NULL || subCodeSet == NULL)
- {
- errno = EINVAL;
- return -1;
- }
- if (lang != NULL && *lang != '\0')
- {
- /*
- * look for lang_ter
- */
- _DtHelpCeStrchr (lang, "_", MB_CUR_MAX, &ptr);
- if (ptr)
- {
- /*
- * do we want this string?
- */
- if (subLang != NULL)
- {
- len = ptr - lang;
- sLang = (char *) malloc (len + 1);
- if (sLang != NULL)
- {
- strncpy (sLang, lang, len);
- sLang[len] = '\0';
- }
- else
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- /*
- * just mark that the lang part was found
- */
- else
- sLang = lang;
-
- lang = ptr + 1;
- }
-
- /*
- * look for lang.codeset
- */
- _DtHelpCeStrchr (lang, Period, MB_CUR_MAX, &ptr);
- if (ptr)
- {
- len = ptr - lang;
-
- /*
- * if it was in the form lang_ter.codeset, sLang will non-null
- */
- if (sLang != NULL)
- {
- /*
- * do we want to save the territory?
- */
- if (subTer != NULL)
- {
- sTer = (char *) malloc (len + 1);
- if (sTer != NULL)
- {
- strncpy (sTer, lang, len);
- sTer[len] = '\0';
- }
- else
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- /*
- * don't wan to save, but make sure we mark the territory
- * as being found (non-null).
- */
- else
- sTer = lang;
- }
- /*
- * the lang was in the form lang.codeset.
- * now check to see if want to save the lang portion.
- */
- else if (subLang != NULL)
- {
- sLang = (char *) malloc (len + 1);
- if (sLang != NULL)
- {
- strncpy (sLang, lang, len);
- sLang[len] = '\0';
- }
- else
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- /*
- * didn't want to save the lang portion, but mark as found.
- */
- else
- sLang = lang;
- }
-
- /*
- * currently pointing at the dot?
- */
- if (ptr && *ptr == '.')
- {
- /*
- * yes save the code set
- */
- ptr++;
- if (subCodeSet != NULL)
- {
- sCode = strdup (ptr);
- if (sCode == NULL)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- /*
- * don't save the code set, but make sure we mark as found
- */
- else
- sCode = ptr;
- }
- /*
- * didn't find a code set, so save the current info.
- * If we haven't already processed a lang portion, save as the
- * lang.
- */
- else if (sLang == NULL)
- {
- if (subLang != NULL)
- {
- sLang = strdup (lang);
- if (sLang == NULL)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- else
- sLang = lang;
- }
- /*
- * otherwise this is the territory of the language. Save if desired
- */
- else if (subTer != NULL)
- {
- sTer = strdup (lang);
- if (sTer == NULL)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- }
- if (subLang)
- *subLang = sLang;
- if (subTer)
- *subTer = sTer;
- if (subCodeSet)
- *subCodeSet = sCode;
- return 0;
- }
- /*****************************************************************************
- * Function: int _DtHelpCeGetUncompressedFileName (char *name, char **ret_name)
- *
- * Parameters: name Specifies the file to open.
- * ret_name Returns the name of the uncompressed file.
- * This memory must be freed by the caller.
- *
- * Returns: 0 if required uncompress. ret_name will contain the
- * name of the uncompressed file. The caller is required
- * to free the memory.
- * 1 if no uncompression required. ret_name points to name.
- * -1 if a failure occurs
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorFileSeek
- * Specifies the seek offset was invalid.
- *
- * Purpose: Find out if a file is compressed and uncompress it if it is.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetUncompressedFileName (
- char *name,
- char **ret_name )
- {
- char *inFile = NULL;
- char tmpName[MAXPATHLEN + 1];
- int result = 1;
- /*
- * check to see if the file exists in uncompressed form
- */
- *ret_name = name;
- if (access (name, F_OK) == -1)
- {
- /*
- * get a temporary name
- */
- (void) tmpnam (tmpName);
- /*
- * malloc memory for the dot Z file name.
- */
- inFile = (char *) malloc (strlen (name) + 3);
- if (inFile != NULL)
- {
- /*
- * make the dot Z file
- */
- strcpy (inFile, name);
- strcat (inFile, ".Z");
- /*
- * do the uncompress
- */
- result = _DtHelpCeUncompressFile (inFile, tmpName);
- free (inFile);
- if (result != 0)
- {
- errno = ENOENT;
- return -1;
- }
- *ret_name = strdup (tmpName);
- if (*ret_name == NULL)
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- else
- {
- errno = CEErrorMalloc;
- return -1;
- }
- }
- return result;
- }
- /******************************************************************************
- * Function: int _DtHelpCeCompressPathname (char *basePath)
- *
- * Parameters: basePath Specifies the path for the file possibily
- * containing /./, //, and /../.
- *
- * Return Value: 0 for success, -1 for failure.
- * The number of bytes in basePath will be less than or
- * equal to the number of bytes in basePath when passed
- * in.
- *
- * errno Values: EINVAL
- *
- * Purpose: This function compresses directory changes found
- * in a file name path.
- *
- ******************************************************************************/
- int
- _DtHelpCeCompressPathname ( char *basePath )
- {
- int len;
- int result;
- short char1;
- short char2;
- short char3;
- char *ptr = basePath;
- char *prevPtr = NULL;
- if (basePath == NULL || *basePath != '/')
- {
- errno = EINVAL;
- return -1;
- }
- do
- {
- /*
- * for multi-byte environments, check how far single bytes extend.
- */
- char1 = False;
- char2 = False;
- char3 = False;
- if (MB_CUR_MAX == 1 || mblen (&ptr[1], MB_CUR_MAX) == 1)
- {
- char1 = True;
- if (MB_CUR_MAX == 1 || mblen (&ptr[2], MB_CUR_MAX) == 1)
- {
- char2 = True;
- if (MB_CUR_MAX == 1 || mblen (&ptr[3], MB_CUR_MAX) == 1)
- char3 = True;
- }
- }
- /*
- * check for //
- */
- if (char1 == True && ptr[1] == '/')
- strcpy (ptr, (ptr + 1));
- /*
- * check for /./
- */
- else if (char2 == True && ptr[1] == '.' && ptr[2] == '/')
- strcpy (ptr, (ptr + 2));
- /*
- * check for /../
- */
- else if (char3 == True && strncmp (&ptr[1], "../", 3) == 0)
- {
- /*
- * if at the top of the path, just ignore the extra
- * directory change.
- */
- if (prevPtr == NULL)
- strcpy (ptr, (ptr + 3));
- else
- {
- /*
- * compress the /../
- */
- strcpy (prevPtr, (ptr + 3));
- /*
- * reset the current pointer
- */
- ptr = prevPtr;
- /*
- * find the previous slash
- */
- *ptr = '\0';
- result = _DtHelpCeStrrchr(basePath,Slash,MB_CUR_MAX,&prevPtr);
- if (result == -1)
- return -1;
- /*
- * if there is no previous slash, set the pointer to
- * indicate that we're at the top of the path (NULL).
- */
- if (result != 0)
- prevPtr = NULL;
- /*
- * restore the slash (or null byte)
- */
- *ptr = '/';
- }
- }
- else
- {
- /*
- * remember this slash for /../ directory changes
- */
- prevPtr = ptr;
- /*
- * skip this slash, and find the next one.
- */
- ptr++;
- result = _DtHelpCeStrcspn (ptr, "/", MB_CUR_MAX, &len);
- /*
- * if we run into invalid data, error
- */
- if (result == -1)
- return -1;
- ptr += len;
- }
- } while (*ptr != '\0');
- return (0);
- }
- /******************************************************************************
- * Function: char *_DtHelpCeTracePathName (char *path)
- *
- * Parameters:
- * path Specifies the a path to trace and compress
- *
- * Return Value: The new string if successful, NULL otherwise.
- * The new string is owned by the caller and contains
- * an absolute pathname.
- *
- * errno Values: EINVAL Illegal parameter specified.
- * getcwd(2) errno set via a getcwd call.
- * readlink(2) errno set via a readlink call.
- * DtErrorMalloc
- * DtErrorExceedMaxSize The new path will exceed
- * max_size.
- * DtErrorIllegalPath The compression will required
- * the path to change to a parent
- * directory beyond the beginning
- * of basePath.
- *
- * Purpose: This function is called to trace the path of a file.
- * It can contain symbolic links, //, /./, and /../.
- *
- ******************************************************************************/
- char *
- _DtHelpCeTracePathName (char *path)
- {
- int result;
- int len;
- char c;
- char *ptr;
- char *prev;
- char newPath [2 * MAXPATHLEN + 2];
- char linkPath [MAXPATHLEN + 2];
- char tempPath [MAXPATHLEN + 2];
- if (path == NULL || *path == '\0')
- {
- errno = EINVAL;
- return NULL;
- }
- /*
- * initialize the new path
- */
- newPath[0] = '\0';
- /*
- * if the path passed in does not start with a slash,
- * get the current working directory and append the path to it.
- */
- if ((MB_CUR_MAX == 1 || mblen(path, MB_CUR_MAX) == 1) && *path != '/')
- {
- if (getcwd (newPath, MAXPATHLEN) == NULL)
- return NULL;
- strcat (newPath, "/");
- }
- /*
- * put the path in the working path buffer (or append it to
- * the current working directory).
- */
- strcat (newPath, path);
- /*
- * Compress out the slashes and directory changes.
- */
- if (_DtHelpCeCompressPathname (newPath) != 0)
- return NULL;
- ptr = newPath;
- do
- {
- /*
- * point to the first character of the next directory
- */
- prev = ptr + 1;
- /*
- * get the next slash after that
- */
- result = _DtHelpCeStrcspn (prev, "/", MB_CUR_MAX, &len);
- if (result == -1)
- return NULL;
- /*
- * Found either a slash or a null byte.
- * place the string terminator at this point
- */
- ptr = prev + len;
- c = *ptr;
- *ptr = '\0';
- /*
- * find out if this path is a symbolic link
- */
- result = readlink (newPath, linkPath, MAXPATHLEN);
- /*
- * replace the slash (or null byte).
- */
- *ptr = c;
- /*
- * check for the result of the readlink call
- */
- if (result == -1)
- {
- /*
- * if this was NOT a symbolic link, errno should be EINVAL
- */
- if (errno != EINVAL)
- return NULL;
- }
- else
- {
- /*
- * put the null byte on the end of the symbolic link string.
- */
- linkPath [result] = '\0';
- /*
- * Save the rest of the string that we haven't processed
- * for tacking on after the new link path has been
- * dropped into the path.
- */
- snprintf(tempPath, sizeof(tempPath), "%s", ptr);
- /*
- * is it an absolute path? Simply replace the path
- * being search with the new link path.
- */
- if (*linkPath == '/')
- strcpy (newPath, linkPath);
- else
- {
- /*
- * this is a relative link.
- * prev is looking at the first character of this directory.
- * replace with the link.
- */
- strcpy (prev, linkPath);
- }
- /*
- * now tack on the rest of the name
- */
- strcat (newPath, tempPath);
- /*
- * compress out the directory changes.
- */
- if (_DtHelpCeCompressPathname (newPath) != 0)
- return NULL;
- /*
- * start again from the top, until we have a clean path
- */
- ptr = newPath;
- }
- } while (*ptr != '\0');
- return (strdup (newPath));
- }
- /******************************************************************************
- * Function: char *_DtHelpCeTraceFilenamePath (char *file_path)
- *
- * Parameters:
- * file_path Specifies the a path to trace and compress
- *
- * Return Value: The new string if successful, NULL otherwise.
- * The new string is owned by the caller and
- * contains an absolute filename path.
- *
- * errno Values: EINVAL Illegal parameter specified.
- * getcwd(2) errno set via a getcwd call.
- * readlink(2) errno set via a readlink call.
- * DtErrorMalloc
- * DtErrorExceedMaxSize The new path will exceed
- * max_size.
- * DtErrorIllegalPath The compression will required
- * the path to change to a parent
- * directory beyond the beginning
- * of basePath.
- *
- * Purpose: This function is called to trace a filename path.
- * It can contain symbolic links, //, /./, and /../.
- *
- ******************************************************************************/
- char *
- _DtHelpCeTraceFilenamePath (char *file_path)
- {
- int result;
- int done = False;
- char *newPath;
- char *oldName;
- char *namePlace;
- char workName [MAXPATHLEN + 2];
- char newName [MAXPATHLEN + 2];
- char linkName [MAXPATHLEN + 2];
- if (file_path == NULL || *file_path == '\0')
- {
- errno = EINVAL;
- return NULL;
- }
- workName[0] = '\0';
- if ((MB_CUR_MAX == 1 || mblen(file_path, MB_CUR_MAX) == 1)
- && *file_path != '/')
- {
- if (getcwd(workName, MAXPATHLEN) == NULL)
- return NULL;
- strcat(workName, "/");
- }
- strcat (workName, file_path);
- do
- {
- /*
- * find and save the old filename
- */
- result = _DtHelpCeStrrchr(workName, Slash, MB_CUR_MAX, &oldName);
- if (result == -1)
- return NULL;
- /*
- * terminate the path
- */
- *oldName = '\0';
- /*
- * trace the path, resolving the symbolic links
- * and directory changes. If /filename given,
- * skip the path tracing.
- */
- newName[0] = '\0';
- if (workName[0] != '\0')
- {
- newPath = _DtHelpCeTracePathName(workName);
- if (newPath == NULL)
- return NULL;
- /*
- * copy the new path and free the allocated copy
- */
- snprintf(newName, sizeof(newName), "%s", newPath);
- free (newPath);
- }
- /*
- * replace the slash
- */
- *oldName = '/';
- /*
- * now append the slash and filename (pointed to by oldName)
- * onto the end of the new path.
- */
- namePlace = newName + strlen (newName);
- strcpy (namePlace, oldName);
- /*
- * See if the absolute path/filename is a symbolic link.
- */
- result = readlink (newName, linkName, MAXPATHLEN);
- if (result == -1)
- {
- if (errno != EINVAL)
- return NULL;
- done = True;
- }
- else
- {
- /*
- * put the null byte on the end of the symbolic
- * link string.
- */
- linkName [result] = '\0';
- if (*linkName == '/')
- strcpy (newName, linkName);
- else
- {
- /*
- * overwrite the filename with the link
- * but don't overwrite the slash.
- */
- strcpy ((namePlace + 1), linkName);
- }
- /*
- * make a copy of the new name to work on
- */
- strcpy (workName, newName);
- }
- } while (!done);
- return (strdup (newName));
- }
- /******************************************************************************
- * Core Engine Semi-Public Functions
- ******************************************************************************/
- /*****************************************************************************
- * Function: char *_DtHelpCeGetVolumeName (_DtHelpVolumeHdl volume)
- *
- * Parameters:
- *
- * Returns: ptr to the name of the volume, NULL otherwise.
- *
- * Purpose: Get the fully qualified volume name.
- *
- *****************************************************************************/
- char *
- _DtHelpCeGetVolumeName (
- _DtHelpVolumeHdl volume_handle)
- {
- char *volFile;
- _DtHelpProcessLock();
- volFile = ((_DtHelpVolume)volume_handle)->volFile;
- _DtHelpProcessUnlock();
- return volFile;
- } /* End __DtHelpCeGetVolumeName */
- /*****************************************************************************
- * Function: int _DtHelpCeFileOpenAndSeek (char *name, int offset, int fildes,
- * BufFilePtr *ret_file)
- *
- * Parameters: name Specifies the file to open.
- * offset Specifies location within the file to seek to.
- *
- * Returns: 0 if successful, -1 if a failure occurs
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorFileSeek
- * Specifies the seek offset was invalid.
- *
- * Purpose: Open a file and seek to a specific place.
- *
- *****************************************************************************/
- int
- _DtHelpCeFileOpenAndSeek (
- char *name,
- int offset,
- int fd,
- BufFilePtr *ret_file,
- time_t *ret_time)
- {
- unsigned char fileMagic[4];
- int bytesRead;
- int result = 0;
- int tmpFd;
- struct stat buf;
- /*
- * Get the file descriptor of the uncompressed file
- */
- tmpFd = fd;
- if (fd == -1)
- {
- result = FileOpenRtnFd (name, &tmpFd);
- if (result == -1)
- return -1;
- }
- if (ret_time != NULL)
- {
- (void) fstat(tmpFd, &buf);
- *ret_time = buf.st_mtime;
- }
- /*
- * make sure we don't go past the end of the file
- */
- result = lseek (tmpFd, 0, SEEK_END);
- if (result != -1)
- {
- if (result > offset)
- result = lseek (tmpFd, offset, SEEK_SET);
- else
- {
- result = -1;
- errno = CEErrorFileSeek;
- }
- }
- if (result == -1)
- {
- if (fd == -1)
- close (tmpFd);
- return -1;
- }
- bytesRead = read(tmpFd, fileMagic, 4);
- if (bytesRead != 4)
- { /* something's wrong in reading the file */
- if (fd == -1)
- close (tmpFd);
- return -1;
- }
- if (!*fileMagic)
- { /* started with compressed file magic number */
- CECompressInfoPtr myInfo;
- BufFilePtr inputRaw;
- /*
- * allocate the private information
- */
- myInfo = (CECompressInfoPtr) malloc(sizeof(CECompressInfo));
- if (myInfo == NULL)
- {
- if (fd == -1)
- close (tmpFd);
- errno = CEErrorMalloc;
- return -1;
- }
- /*
- * set the information
- * set the size to the maximum number of bytes we
- * want to read.
- */
- myInfo->fd = tmpFd;
- myInfo->size =
- (((fileMagic[1] * 256) + fileMagic[2]) * 256) + fileMagic[3];
- /*
- * start with raw functionality
- */
- inputRaw = _DtHelpCeBufFileRdRawZ(myInfo);
- if (inputRaw == NULL)
- {
- if (fd == -1)
- close (tmpFd);
- return -1;
- }
- *ret_file = _DtHelpCeBufFilePushZ(inputRaw);
- if (*ret_file == NULL)
- {
- _DtHelpCeBufFileClose(inputRaw, (fd == -1 ? True : False));
- return -1;
- }
- }
- else
- {
- /*
- * not a compressed file, back up the four bytes we read
- */
- result = lseek (tmpFd, offset, SEEK_SET);
- if (result == -1)
- {
- if (fd == -1)
- close (tmpFd);
- return -1;
- }
- /*
- * read with raw functionality
- */
- *ret_file = _DtHelpCeBufFileRdWithFd(tmpFd);
- if (*ret_file == NULL)
- {
- if (fd == -1)
- close (tmpFd);
- return -1;
- }
- }
- return 0;
- } /* End of _DtHelpCeFileOpenAndSeek */
- /******************************************************************************
- * Core Engine Public Functions
- ******************************************************************************/
- /******************************************************************************
- * Function: int _DtHelpOpenVolume (char *volFile, _DtHelpVolume *retVol);
- *
- * Parameters: volFile Specifies the name of the Help Volume file
- * to load.
- *
- * retVol Returns the handle to the loaded volume.
- * If a volume is opened several times, the
- * same handle will be returned each time.
- *
- * Return Value: 0 if successful, -1 if a failure occurred.
- *
- * errno Values: EINVAL Illegal parameter specified.
- * getcwd(2) errno set via a getcwd call.
- * readlink(2) errno set via a readlink call.
- * CEErrorMalloc
- * CEErrorExceedMaxSize The new path will exceed
- * max_size.
- * CEErrorIllegalPath The compression will required
- * the path to change to a parent
- * directory beyond the beginning
- * of basePath.
- * CEErrorIllegalDatabaseFile
- * Specifies that 'volFile' is
- * an illegal database file.
- *
- *
- * Purpose: This function must be called to open a Help Volume file
- * before any of the information in the volume can be
- * accessed.
- *
- ******************************************************************************/
- int
- _DtHelpOpenVolume (
- char *volFile,
- _DtHelpVolumeHdl *retVol)
- {
- int result = 0;
- _DtHelpVolume vol, prevVol;
- _DtHelpProcessLock();
- if (volFile == NULL || retVol == NULL)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return -1;
- }
- /*
- * follow all the symbolic links and get the absolute path and filename.
- */
- volFile = _DtHelpCeTraceFilenamePath(volFile);
- if (volFile == NULL)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- /* Search the volume chain to see if it is already open. */
- prevVol = NULL;
- vol = volChain;
- while (vol != NULL && strcmp (vol->volFile, volFile))
- {
- prevVol = vol;
- vol = vol->nextVol;
- }
- if (vol)
- {
- vol->openCount++;
- free(volFile);
- }
- else /* if (vol == NULL) */
- {
- /* If it isn't open, open it and insert it in the chain. */
- result = VolumeLoad (volFile, &vol);
- if (result == 0)
- {
- if (prevVol == NULL)
- volChain = vol;
- else
- prevVol->nextVol = vol;
- }
- }
- /* Return the volume handle and a status indicating success/failure. */
- *retVol = (_DtHelpVolumeHdl) vol;
- _DtHelpProcessUnlock();
- return result;
- }
- /******************************************************************************
- * Function: int _DtHelpCeUpVolumeOpenCnt (_DtHelpVolumeHdl vol);
- *
- * Parameters: vol Specifies the loaded volume.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * errno Values: EINVAL 'vol' was NULL, no volumes open or
- * 'vol' does not exist.
- *
- * Purpose: When the volume is no longer needed, it should be
- * closed with this call. If the volume has been opened
- * several times, closing it will just decrement the
- * reference count. When it has been closed as many times
- * as it was opened, the memory it is using will be freed
- * and any handles to the volume will be invalid.
- *
- ******************************************************************************/
- int
- _DtHelpCeUpVolumeOpenCnt (
- _DtHelpVolumeHdl volume)
- {
- _DtHelpVolume prevVol;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- _DtHelpProcessLock();
- if (vol == NULL || volChain == NULL)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return (-1);
- }
- /*
- * check to see if this volume is in our chain
- */
- if (vol != volChain)
- {
- if (CheckVolList (vol, &prevVol) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return (-1);
- }
- }
- /*
- * increment it's usage count.
- */
- vol->openCount++;
- _DtHelpProcessUnlock();
- return (0);
- }
- /******************************************************************************
- * Function: int _DtHelpCloseVolume (_DtHelpVolumeHdl vol);
- *
- * Parameters: vol Specifies the loaded volume.
- *
- * Return Value: 0 if successful, -1 if a failure occurs
- *
- * errno Values: EINVAL 'vol' was NULL, no volumes open or
- * 'vol' does not exist.
- *
- * Purpose: When the volume is no longer needed, it should be
- * closed with this call. If the volume has been opened
- * several times, closing it will just decrement the
- * reference count. When it has been closed as many times
- * as it was opened, the memory it is using will be freed
- * and any handles to the volume will be invalid.
- *
- ******************************************************************************/
- int
- _DtHelpCloseVolume (
- _DtHelpVolumeHdl volume)
- {
- _DtHelpVolume prevVol;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- _DtHelpProcessLock();
- if (vol == NULL || volChain == NULL)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return (-1);
- }
- /*
- * check to see if this volume is in our chain
- */
- if (vol != volChain)
- {
- if (CheckVolList (vol, &prevVol) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return (-1);
- }
- }
- /*
- * decrement it's usage count.
- */
- vol->openCount--;
- if (vol->openCount == 0)
- {
- /* The volume is no longer needed. Unlink it from the chain
- and free it. */
- if (vol == volChain)
- volChain = volChain->nextVol;
- else
- prevVol->nextVol = vol->nextVol;
- VolumeUnload (vol);
- }
- _DtHelpProcessUnlock();
- return (0);
- }
- /*****************************************************************************
- * Function: int _DtHelpCeGetTopTopicId (_DtHelpVolume vol,
- * char **ret_idString)
- *
- * Parameters: vol Specifies the loaded volume
- * ret_idString Returns the location ID of the
- * the top level topic.
- *
- * Memory own by caller:
- * ret_idString
- *
- * Returns: True for success, False if a failure occurs.
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorMissingTopTopicRes
- * Specifies that the 'TopTopic/topTopic'
- * resource is missing from the database.
- * CEErrorMalloc
- *
- * Purpose: Get the information to access the top level topic.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetTopTopicId (
- _DtHelpVolumeHdl volume,
- char **ret_idString )
- {
- int found = False;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- _DtHelpProcessLock();
- if (vol == NULL || ret_idString == NULL || CheckVolList(vol, NULL) == -1)
- errno = EINVAL;
- else
- {
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- (void) _DtHelpCeGetCcdfTopTopic(vol, ret_idString);
- else
- *ret_idString = _DtHelpCeGetSdlHomeTopicId((_DtHelpVolumeHdl) vol);
- if (*ret_idString != NULL)
- *ret_idString = strdup(*ret_idString);
- if (*ret_idString != NULL)
- found = True;
- }
- _DtHelpProcessUnlock();
- return found;
- } /* End _DtHelpCeGetTopTopicId */
- /*****************************************************************************
- * Function: int _DtHelpCeFindId (_DtHelpVolume vol, char *target_id,
- * int fd,
- * char *ret_name, int *ret_offset)
- *
- * Parameters: vol Specifies the loaded volume
- * target_id Specifies target location ID
- * fd Specifies the locked file descriptor.
- * ret_name Returns a null terminated string
- * containing a fully qualified path to
- * the file that contains 'target_id'.
- * ret_offset Returns the offset into 'ret_name'
- * to the topic that contains 'target_id'.
- *
- * Memory own by caller:
- * ret_name
- *
- * Returns: True if successful, False if a failure occurs
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorMalloc
- * CEErrorMissingFilenameRes
- * Specifies that the 'Filename/filename'
- * resource for 'topic' does not exist.
- * CEErrorMissingFileposRes
- * If the resource is not in the
- * database or if the resource NULL.
- * CEErrorLocIdNotFound
- * Specifies that 'locId' was not
- * found.
- *
- * Purpose: Find which topic contains a specified locationID.
- *
- *****************************************************************************/
- int
- _DtHelpCeFindId (
- _DtHelpVolumeHdl volume,
- char *target_id,
- int fd,
- char **ret_name,
- int *ret_offset )
- {
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- int result;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || target_id == NULL || ret_name == NULL ||
- ret_offset == NULL || CheckVolList (vol, NULL) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return False;
- }
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- {
- result = _DtHelpCeFindCcdfId(vol, target_id, ret_name, ret_offset);
- }
- else
- {
- result = _DtHelpCeFindSdlId(vol, target_id, fd, ret_name, ret_offset);
- }
- _DtHelpProcessUnlock();
- return result;
- } /* End _DtHelpCeFindId */
- /*****************************************************************************
- * Function: int _DtHelpCeGetKeywordList (_DtHelpVolume vol, char ***ret_keywords)
- *
- * Parameters: vol Specifies the loaded volume
- * ret_keywords Returns a NULL-terminated string array
- * containing the sorted list of keywords in the
- * volume. This array is NOT owned by the caller
- * and should only be read or copied.
- *
- * Returns: The count of keywords associated with the volume if successful.
- * -1 if a failure occurs;
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorMalloc
- * CEErrorIllegalDatabaseFile
- * Specifies that the keyword file is
- * invalid or corrupt.
- * CEErrorMissingKeywordsRes
- * Specifies that the keyword file does
- * not contain the 'Keywords/keywords'
- * resource or the resource is NULL
- *
- * Purpose: Get the list of keywords contained in a volume.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetKeywordList (
- _DtHelpVolumeHdl volume,
- char ***ret_keywords )
- {
- int nameCount = -1;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- if (vol == NULL || ret_keywords == NULL || CheckVolList (vol, NULL) == -1)
- errno = EINVAL;
- else if (GetVolumeKeywords (vol, ret_keywords) == 0)
- {
- nameCount = 0;
- while (*ret_keywords && (*ret_keywords)[nameCount])
- nameCount++;
- }
- return nameCount;
- } /* End _DtHelpCeGetKeywordList */
- /*****************************************************************************
- * Function: int _DtHelpCeFindKeyword (_DtHelpVolume vol, char *target, char ***ret_ids)
- *
- * Parameters: vol Specifies the loaded volume
- * target The target keyword.
- * ret_ids Returns a null terminated list of location
- * ids associated with the target keyword.
- *
- * Returns: The count of ids associated with the keyword if successful.
- * -1 if a failure occurs;
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- * CEErrorNoKeywordList
- * Specifies that the volume does not
- * have a keyword list.
- * CEErrorIllegalKeyword
- * Specifies that 'target' was not
- * found.
- * CEErrorMalloc
- * CEErrorIllegalDatabaseFile
- * Specifies that the keyword file is
- * invalid or corrupt.
- * CEErrorMissingKeywordsRes
- * Specifies that the keyword file does
- * not contain the 'Keywords/keywords'
- * resource or the resource is NULL
- *
- * Purpose: Get the list of location ids associated with a keyword
- *
- *****************************************************************************/
- int
- _DtHelpCeFindKeyword (
- _DtHelpVolumeHdl volume,
- char *target,
- char ***ret_ids )
- {
- int nameCount = -1;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- if (vol == NULL || target == NULL || ret_ids == NULL ||
- CheckVolList (vol, NULL) == -1)
- errno = EINVAL;
- else if (GetKeywordTopics (vol, target, ret_ids) == 0)
- {
- nameCount = 0;
- while (*ret_ids && (*ret_ids)[nameCount])
- nameCount++;
- }
- return nameCount;
- } /* End _DtHelpCeFindKeyword */
- /*****************************************************************************
- * Function: int _DtHelpGetTopicTitle (
- * _DtHelpVolumeHdl volume,
- * char *id, char **ret_title)
- *
- * Parameters: volume Specifies the volume containing the id.
- * id Specifies the id for the topic desired.
- * ret_title Returns a null terminated string containing
- * the title.
- *
- * Memory own by caller:
- * ret_title
- *
- * Returns: 0 if successful, -2 if didn't find the id,
- * otherwise -1.
- *
- * errno Values: EINVAL Specifies an invalid parameter was
- * used.
- *
- * Purpose: Get the title of a topic.
- *
- *****************************************************************************/
- int
- _DtHelpGetTopicTitle (
- _DtHelpVolumeHdl volume,
- char *id,
- char **ret_title)
- {
- int result;
- char *abbrevTitle;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- if (volume == NULL || id == NULL ||
- CheckVolList (vol, NULL) == -1 || ret_title == NULL)
- {
- errno = EINVAL;
- return -1;
- }
- /*
- * Try to get the title via the <TOPIC> and <ABBREV> tags.
- */
- result = GetTopicTitleAndAbbrev(vol, id, ret_title, &abbrevTitle);
- if (result == 0)
- {
- /*
- * If we have a abbreviated title, return it instead.
- */
- if (abbrevTitle)
- {
- if (*ret_title)
- free ((char *) *ret_title);
- *ret_title = abbrevTitle;
- }
- }
- return result;
- } /* End _DtHelpGetTopicTitle */
- /*****************************************************************************
- * Function: int _DtHelpCeMapTargetToId (_DtHelpVolume vol,
- * char *target_id,
- * char *ret_id)
- *
- * Parameters: vol Specifies the loaded volume
- * target_id Specifies target location ID
- * ret_id Returns the id containing the target_id.
- * This memory *IS NOT* owned by the caller.
- *
- * Returns: 0 if successful, -1 if a failure occurs
- *
- * Purpose: Find which topic contains a specified locationID.
- *
- *****************************************************************************/
- int
- _DtHelpCeMapTargetToId (
- _DtHelpVolumeHdl volume,
- char *target_id,
- char **ret_id)
- {
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- int result;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || target_id == NULL || ret_id == NULL ||
- CheckVolList (vol, NULL) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return -1;
- }
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- {
- result = _DtHelpCeMapCcdfTargetToId(vol, target_id, ret_id);
- }
- else
- {
- result = _DtHelpCeMapIdToSdlTopicId(vol, target_id, ret_id);
- }
- _DtHelpProcessUnlock();
- return result;
- } /* End _DtHelpCeMapTargetToId */
- /*****************************************************************************
- * Function: char * _DtHelpGetVolumeLocale (_DtHelpVolume vol)
- *
- * Parameters: vol Specifies the loaded volume
- *
- * Returns: The pointer to the locale string if successful. Otherwise
- * NULL.
- *
- * Purpose: Get the locale of the specified volume.
- * Returns the locale in a unix specific format
- * - locale[_ter][.charset] - This memory is owned by
- * the caller.
- *
- *****************************************************************************/
- char *
- _DtHelpGetVolumeLocale (
- _DtHelpVolumeHdl volume)
- {
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- char *result;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return NULL;
- }
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- {
- result = _DtHelpCeGetCcdfVolLocale(vol);
- }
- else
- {
- result = _DtHelpCeGetSdlVolumeLocale(vol);
- }
- _DtHelpProcessUnlock();
- return result;
- } /* End _DtHelpGetVolumeLocale */
- /*****************************************************************************
- * Function: int _DtHelpCeGetDocStamp (_DtHelpVolumeHdl volume, char **ret_doc,
- * char **ret_time)
- *
- * Parameters: volume Specifies the loaded volume
- * ret_doc Returns the doc id.
- * ret_time Returns the time stamp.
- *
- * Memory: Caller owns the string in ret_doc and ret_time.
- *
- * Returns: 0 if successful, -2 if the volume does not contain
- * one or the other, -1 if any other failure.
- *
- * Purpose: Get doc id and time stamp of a volume.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetDocStamp (
- _DtHelpVolumeHdl volume,
- char **ret_doc,
- char **ret_time)
- {
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- int result;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return 0;
- }
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- {
- result = _DtHelpCeGetCcdfDocStamp (vol, ret_doc, ret_time);
- }
- else
- {
- result = _DtHelpCeGetSdlDocStamp(vol, ret_doc, ret_time);
- }
- _DtHelpProcessUnlock();
- return result;
- } /* End _DtHelpCeGetDocStamp */
- /*****************************************************************************
- * Function: char * _DtHelpCeGetTopicChilren (_DtHelpVolumeHdl vol)
- *
- * Parameters: vol Specifies the loaded volume
- * topic_id Speicifes the topic id of which the
- * children are to be found.
- * retTopics Returns the null terminated array of
- * ids. This memory is owned by the caller
- * and must be freed.
- *
- * Returns: > 0 if successful, -1 if failures.
- *
- * Purpose: Get the children of a topic.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetTopicChildren (
- _DtHelpVolumeHdl volume,
- char *topic_id,
- char ***retTopics)
- {
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- int result;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- errno = EINVAL;
- _DtHelpProcessUnlock();
- return -1;
- }
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- {
- result = _DtHelpCeGetCcdfTopicChildren(volume, topic_id, retTopics);
- }
- else
- {
- result = _DtHelpCeGetSdlTopicChildren(volume, topic_id, retTopics);
- }
- _DtHelpProcessUnlock();
- return result;
- } /* End _DtHelpCeGetTopicChildren */
- /*****************************************************************************
- * Function: int _DtHelpCeGetVolumeFlag (_DtHelpVolumeHdl vol)
- *
- * Parameters: vol Specifies the loaded volume
- *
- * Returns: 0 if CCDF volume, 1 if SDL, -1 if failures.
- *
- * Purpose: Determine the type of volume.
- *
- *****************************************************************************/
- int
- _DtHelpCeGetVolumeFlag (
- _DtHelpVolumeHdl volume)
- {
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- errno = EINVAL;
- return -1;
- }
- /*
- * What type of volume is it?
- */
- return((int) vol->sdl_flag);
- } /* End _DtHelpCeGetVolumeFlag */
- /*****************************************************************************
- * Function: int _DtHelpCeLockVolume (_DtHelpVolumeHdl vol)
- *
- * Parameters: vol Specifies the loaded volume
- *
- * Returns: > 0 if successful, -1 if failures.
- *
- * Purpose: Lock the volume so that it can't get change out from
- * under the caller.
- *
- *****************************************************************************/
- int
- _DtHelpCeLockVolume (
- _DtHelpVolumeHdl volume,
- _DtHelpCeLockInfo *lock_info)
- {
- struct stat buf;
- _DtHelpVolume vol = (_DtHelpVolume)volume;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- /*
- * lock it by opening it.
- */
- lock_info->fd = open(vol->volFile, O_RDONLY);
- if (lock_info->fd == -1)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- (void) fstat(lock_info->fd, &buf);
- if (buf.st_mtime != vol->check_time)
- {
- if (RereadVolume(vol) != 0)
- {
- close(lock_info->fd);
- _DtHelpProcessUnlock();
- return -1;
- }
- vol->check_time = buf.st_mtime;
- }
- /*
- * Synthetic open
- */
- vol->openCount++;
- lock_info->volume = volume;
- _DtHelpProcessUnlock();
- return 0;
- } /* End _DtHelpCeLockVolume */
- /*****************************************************************************
- * Function: int _DtHelpCeUnlockVolume (_DtHelpVolumeHdl vol)
- *
- * Parameters: vol Specifies the loaded volume
- *
- * Returns: > 0 if successful, -1 if failures.
- *
- * Purpose: Unlock the volume.
- *
- *****************************************************************************/
- int
- _DtHelpCeUnlockVolume (
- _DtHelpCeLockInfo lock_info)
- {
- _DtHelpVolume vol = (_DtHelpVolume)(lock_info.volume);
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- /*
- * check to see if it needs to be unlocked.
- */
- if (lock_info.fd != -1)
- close(lock_info.fd);
- /*
- * Synthetic close
- */
- vol->openCount--;
- _DtHelpProcessUnlock();
- return 0;
- } /* End _DtHelpCeUnlockVolume */
- /*****************************************************************************
- * Function: int _DtHelpCeIsTopTopic (_DtHelpVolumeHdl volume, const char *id)
- *
- * Parameters: vol Specifies the loaded volume
- * id Specifies a location id.
- *
- * Returns: = 0 if successful, != 0 if failures.
- *
- * Purpose: Tests to see if the location id is in the top topic of
- * the volume.
- *
- *****************************************************************************/
- int
- _DtHelpCeIsTopTopic (
- _DtHelpVolumeHdl volume,
- const char *id)
- {
- int result = -1;
- char *topicId = NULL;
- char *topId = NULL;
- _DtHelpVolume vol = (_DtHelpVolume) volume;
- _DtHelpProcessLock();
- /*
- * check the parameters
- */
- if (vol == NULL || CheckVolList (vol, NULL) == -1)
- {
- _DtHelpProcessUnlock();
- return -1;
- }
- /*
- * What type of volume is it?
- */
- if (vol->sdl_flag == False)
- {
- if (_DtHelpCeMapCcdfTargetToId(vol, id, &topicId) == 0 &&
- _DtHelpCeGetCcdfTopTopic(vol, &topId) == 0)
- result = _DtHelpCeStrCaseCmpLatin1(topId, topicId);
- }
- else if (_DtHelpCeMapIdToSdlTopicId(vol, id, &topicId) == 0)
- {
- topId = _DtHelpCeGetSdlHomeTopicId(volume);
- if (topId != NULL)
- result = _DtHelpCeStrCaseCmpLatin1(topId, topicId);
- }
- _DtHelpProcessUnlock();
- return result;
- } /* End _DtHelpCeIsTopTopic */
|