12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586 |
- /*
- * 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
- */
- /* $TOG: helpgen.c /main/8 1998/04/20 12:52:36 mgreess $ */
- #include <dirent.h>
- #include <errno.h>
- #include <locale.h>
- #include <Dt/MsgCatP.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <X11/Xlib.h>
- #include <X11/Xresource.h>
- #include <X11/Intrinsic.h>
- #include <Dt/Help.h>
- #include <Dt/EnvControlP.h>
- #include "Dt/HelpP.h" /* in DtHelp library */
- #include "GenUtilsP.h" /* in DtHelp library */
- #include "ObsoleteP.h" /* in DtHelp library */
- #include "DtI/bufioI.h" /* for AccessI.h */
- #include "DtI/Access.h" /* in DtHelp library */
- #include "DtI/AccessP.h" /* in DtHelp library */
- #include "DtI/AccessI.h" /* in DtHelp library */
- #include "AccessCCDFI.h" /* in DtHelp library */
- #include "StringFuncsI.h" /* in DtHelp library */
- #ifdef _AIX
- #include <LocaleXlate.h>
- #endif
- #ifndef NL_CAT_LOCALE
- static const int NL_CAT_LOCALE = 0;
- #endif
- #ifndef CDE_INSTALLATION_TOP
- #define CDE_INSTALLATION_TOP "/usr/dt"
- #endif
- #ifndef CDE_CONFIGURATION_TOP
- #define CDE_CONFIGURATION_TOP "/etc/dt"
- #endif
- #ifndef DtSYS_FILE_SEARCH_ENV
- #define DtSYS_FILE_SEARCH_ENV "DTHELPSEARCHPATH"
- #endif
- #ifndef DtUSER_FILE_SEARCH_ENV
- #define DtUSER_FILE_SEARCH_ENV "DTHELPUSERSEARCHPATH"
- #endif
- /*****************************************************************************
- * defines
- *****************************************************************************/
- #define VOLUME_EXT ".hv"
- #define FAMILY_EXT ".hf"
- /*****************************************************************************
- * static strings.
- *****************************************************************************/
- static const char *ShellCmd = "sh";
- static const char *UsageStr =
- "%s -dir <directory> [-generate] [-file <name>] [-lang <language>]\n";
- static const char *TopLocId = "_hometopic";
- static const char *SlashString = "/";
- static const char *C_String = "C";
- static const char *DefCharSet = "C.ISO-8859-1";
- static const char *Family_ext = FAMILY_EXT;
- static const char *Ext_Hv = ".hv";
- static const char *Ext_Sdl = ".sdl";
- static const char *SuperMsg =
- "%s: Access denied for directory %s\nTry running as super user?\n";
- static const char *GeneralAccess =
- "%s: Unable to access %s - error status number %d\n";
- static const char *NotDirectory = "%s: Element of %s is not a directory\n";
- static const char *WriteInvalid = "%s: Write to %s invalid\n";
- static const char *defaultTopic = "<TOPIC charset %s>\n";
- static const char *defaultTitle12 =
- "<TYPE serif><WEIGHT bold><SIZE 12><ANGLE italic>\n%s\n</ANGLE></SIZE></WEIGHT></TYPE>\n";
- static const char *defaultTitle14 =
- "<TITLE><TYPE serif><WEIGHT bold><SIZE 14>\n%s\n</SIZE></WEIGHT></TYPE></TITLE>\n";
- static const char *defaultTextBody =
- "<ABBREV>Welcome to the Help Manager</ABBREV> \n\
- <PARAGRAPH>Each of the titles listed below represents a <ANGLE italic> \n\
- product family</> that has installed and registered its online help. Each \n\
- title (and icon) is a hyperlink that lists the help within the family.</> \n\
- <PARAGRAPH after 0 first 1 left 3 label \"<CHAR C.DT-SYMBOL-1><0xB7></>\">To \n\
- display a list of the help available for a product family, choose its \n\
- title (underlined text) or icon.</PARAGRAPH> \n\
- <PARAGRAPH after 0 first 1 left 3 label \"<CHAR C.DT-SYMBOL-1><0xB7></>\">\n\
- Within a product \n\
- family, find the help you want to view, then choose its title.</PARAGRAPH> \n\
- <PARAGRAPH first 1 left 3 label \"<CHAR C.DT-SYMBOL-1><0xB7></>\"> \n\
- If you need help while using help windows, press F1.</PARAGRAPH>";
- static const char *defaultAlternate =
- "<ABBREV>Welcome to the Help Manager</ABBREV> \n\
- <LINK 0 \"Help4Help How-To-Register-Help\"> \n\
- <TYPE serif><WEIGHT bold><SIZE 12><ANGLE italic> \n\
- Note:\\ \\ \\ No Help Registered</SIZE></WEIGHT></TYPE></></LINK> \n\
- <PARAGRAPH leftindent 3 firstindent 3> \n\
- <WEIGHT bold>No product families have registered their online help \n\
- files for browsing.</> Help may be available for some applications by \n\
- choosing Help commands directly within the applications.</>";
- /*****************************************************************************
- * global variables.
- *****************************************************************************/
- char *myName;
- char *Lang = NULL;
- char *ParentName = "_HOMETOPIC";
- char **TopicList = NULL;
- /* The family search list */
- char **FUserList = NULL;
- char **FSysList = NULL;
- /* The volume search list */
- char **VUserList = NULL;
- char **VSysList = NULL;
- char **FamilyList = NULL; /* the names of the unique families */
- char **FullFamilyName = NULL; /* the fully qualified family names */
- char **VolumeList = NULL; /* the names (only) of volume */
- char **FullVolName = NULL; /* the fully qualified volume names */
- char TopicName [MAXPATHLEN + 2];
- int FamilyNum = 0;
- /* Global Message Catalog file names */
- /*****************************************************************************
- * Private Function Declarations
- *****************************************************************************/
- extern char *FindFile (char *filename);
- /*****************************************************************************
- * options and resources
- *****************************************************************************/
- typedef struct
- {
- char *dir;
- char *file;
- char *lang;
- } ApplicationArgs, *ApplicationArgsPtr;
- static ApplicationArgs App_args =
- {
- NULL,
- "browser",
- NULL,
- };
- /*****************************************************************************
- * void MyExit(exit_val, pid)
- *****************************************************************************/
- void
- MyExit (
- int exit_val,
- pid_t pid)
- {
- if (pid != ((pid_t) -1))
- (void) kill(pid, SIGKILL);
- exit (exit_val);
- }
- /*****************************************************************************
- * char *GetMessage(set, n, s)
- *****************************************************************************/
- char *
- GetMessage (
- int set,
- int n,
- char *s)
- {
- char *msg;
- char *lang;
- char *catFileName=NULL;
- static nl_catd nlmsg_fd;
- static int first = 1;
- if ( first )
- {
- /* Setup our default message catalog names if none have been set! */
- /* Setup the short and long versions */
- catFileName = "dthelpgen";
- first = 0;
- if (strcmp (Lang, "C") == 0)
- /*
- * If LANG is not set or if LANG=C, then there
- * is no need to open the message catalog - just
- * return the built-in string "s".
- */
- nlmsg_fd = (nl_catd) -1;
- else
- nlmsg_fd = CATOPEN(catFileName, NL_CAT_LOCALE);
- }
- msg=CATGETS(nlmsg_fd,set,n,s);
- return (msg);
- }
- /*****************************************************************************
- * Boolean *GetPath(filename)
- *****************************************************************************/
- Boolean
- GetPath (char *filename, short strip, char ***list )
- {
- char *ptr;
- char **next = *list;
- if (strip)
- {
- ptr = strrchr (filename, '/');
- if (ptr)
- *ptr = '\0';
- else
- filename = "./";
- }
- while (next != NULL && *next != NULL && strcmp (*next, filename))
- next++;
- if (next == NULL || *next == NULL)
- *list = (char **) _DtHelpCeAddPtrToArray ((void **) (*list),
- strdup(filename));
- return False;
- }
- /*****************************************************************************
- * char *GetExtension(filename)
- * char *filename - name of file to get the extension from.
- * return a pointer to the extension of the file name
- *****************************************************************************/
- char *
- GetExtension(char *filename )
- {
- char *ext;
- /*
- * WARNING...
- * need multi-byte functionality here
- */
- ext = strrchr(filename, '.');
- if (ext)
- return(ext); /* safe because ext not in middle of character */
- return(""); /* never returns NULL */
- }
- /*****************************************************************************
- * Function: CreateVolumeLink
- *
- * outTopic the output stream.
- * volume_name Searches for a volume by this name.
- *
- * Reads a volume database and creates a label paragraph entry.
- *
- *****************************************************************************/
- int
- CreateVolumeLink (
- CanvasHandle canvas,
- FILE *outTopic,
- char *volume_name )
- {
- int result = -1;
- char *title = NULL;
- char *charSet = (char *) DefCharSet;
- char *abstract = NULL;
- char *pathName = NULL;
- VolumeHandle volume = NULL;
- pathName = FindFile (volume_name);
- if (pathName != NULL && _DtHelpCeOpenVolume(canvas,pathName,&volume) == 0)
- {
- if (_DtHelpCeGetVolumeTitle (canvas, volume, &title) == 0)
- result = 0;
- else if (_DtHelpCeGetTopicTitle(canvas,volume,(char*)TopLocId,&title)
- == True)
- result = 0;
- if (result == 0)
- {
- if (_DtHelpCeGetAsciiVolumeAbstract(canvas,volume,&abstract) == -1)
- abstract = NULL;
- charSet = _DtHelpCeGetVolumeLocale(volume);
- if (charSet == NULL)
- charSet = (char *) DefCharSet;
- }
- _DtHelpCeCloseVolume (canvas, volume);
- }
- if (result == 0)
- {
- fprintf (outTopic, (GetMessage(3, 4, "<CHARACTERSET %s>\n")), charSet);
- fprintf (outTopic,"<LINK 0 \"%s %s\">\n", volume_name, (char*)TopLocId);
- fprintf (outTopic, (GetMessage(3, 5, (char*)defaultTitle12)), title);
- fprintf (outTopic, "</LINK>\n");
- /*
- * put the abstract information about this
- * family in the header file
- */
- fprintf (outTopic, "%s", GetMessage (3, 3, "<P before 1 first 1 left 1>\n"));
- if (abstract != NULL)
- {
- fprintf (outTopic, (GetMessage (3, 4, "<CHARACTERSET %s>\n")),
- charSet);
- fprintf (outTopic, "%s\n", abstract);
- fprintf (outTopic, "</CHARACTERSET>\n");
- free (abstract);
- }
- fprintf (outTopic, "</P>\n</CHARACTERSET>\n");
- }
- if (charSet != DefCharSet)
- free(charSet);
- if (title)
- free ((void *) title);
- return result;
- }
- /*****************************************************************************
- * Function: CreateFamily
- *
- *****************************************************************************/
- int
- CreateFamily (
- CanvasHandle canvas,
- char *family_name,
- FILE *out_volume,
- FILE *out_header,
- FILE *out_topic )
- {
- int result = -1;
- int count = 0;
- long filepos;
- char *charSet = NULL;
- char *title = NULL;
- char *abstract = NULL;
- char *list = NULL;
- char *token = NULL;
- char *ptr;
- char *bitmap = NULL;
- char familyName [20]; /* FAMILY%d */
- char bitmapName [MAXPATHLEN + 2];
- char bitmapNameTemp [sizeof(bitmapName)];
- XrmDatabase db;
- char *resType;
- XrmValue resValue;
- db = XrmGetFileDatabase (family_name);
- if (db)
- {
- /*
- * get the title
- */
- if (XrmGetResource (db, "Family.Title", "family.title",
- &resType, &resValue))
- {
- title = (char *) resValue.addr;
- /*
- * get the abstract
- */
- if (XrmGetResource (db, "Family.Abstract", "family.abstract",
- &resType, &resValue))
- {
- abstract = (char *) resValue.addr;
- /*
- * get the volumes list
- */
- if (XrmGetResource (db, "Family.Volumes", "family.volumes",
- &resType, &resValue))
- {
- list = (char *) resValue.addr;
- /*
- * get the character set
- */
- if (XrmGetResource (db, "Family.CharSet", "family.charSet",
- &resType, &resValue))
- {
- charSet = (char *) resValue.addr;
- /*
- * get the bitmap (optional)
- */
- if (XrmGetResource (db,
- "Family.Bitmap", "family.bitmap",
- &resType, &resValue))
- bitmap = (char *) resValue.addr;
- }
- else
- {
- fprintf (stderr,
- (GetMessage (1, 14,
- "%s: character set resource missing\n")),
- family_name);
- return -1;
- }
- }
- else
- {
- fprintf (stderr,
- (GetMessage (1, 13,
- "%s: volumes resource missing\n")),
- family_name);
- return -1;
- }
- }
- else
- {
- fprintf (stderr,
- (GetMessage (1, 12, "%s: abstract resource missing\n")),
- family_name);
- return -1;
- }
- }
- else
- {
- fprintf (stderr,
- (GetMessage (1, 11, "%s: title resource missing\n")),
- family_name);
- return -1;
- }
-
- if (title && abstract && list && charSet)
- {
- /*
- * find out the position of the file pointer
- */
- filepos = ftell (out_topic);
- /*
- * write out the <TOPIC>
- */
- fprintf (out_topic, (GetMessage (3, 1, (char*)defaultTopic)),
- charSet, title);
- /*
- * write out the <TITLE>
- */
- fprintf (out_topic, (GetMessage (3, 2, (char*)defaultTitle14)),
- title);
- fprintf (out_topic, "%s", (GetMessage (3, 3, "<P before 1 first 1 left 1>\n")));
- fprintf (out_topic, "%s\n", abstract);
- fprintf (out_topic, "</P>\n");
- do
- {
- token = NULL;
- list = _DtHelpCeGetNxtToken(list, &token);
- if (token && *token != '\0' && *token != '\n' &&
- CreateVolumeLink (canvas,out_topic, token) == 0)
- count++;
- if (token)
- {
- free ((void *) token);
- token = NULL;
- }
- } while (list && *list != '\0');
- if (count)
- {
- result = 0;
- sprintf (familyName, "FAMILY%d", FamilyNum);
- fprintf (out_topic, "</PARAGRAPH>\n</TOPIC>\n");
- /*
- * Put the link information in the header file
- */
- fprintf (out_header,
- (GetMessage (3, 4, "<CHARACTERSET %s>\n")), charSet);
- fprintf (out_header, "<LINK 0 %s>\n", familyName);
- fprintf (out_header, (GetMessage (3, 5, (char*)defaultTitle12)),
- title);
- fprintf (out_header, "</LINK>\n");
- /*
- * put the abstract information about this
- * family in the header file
- */
- if (NULL != bitmap && *bitmap != '/')
- {
- snprintf(bitmapName, sizeof(bitmapName), "%s", family_name);
- ptr = strrchr (bitmapName, '/');
- if (ptr)
- {
- ptr++;
- *ptr = '\0';
- snprintf(bitmapNameTemp, sizeof(bitmapNameTemp), "%s%s", bitmapName, bitmap);
- strcpy(bitmapName, bitmapNameTemp);
- bitmap = bitmapName;
- }
- else
- bitmap = NULL;
- }
- if (NULL != bitmap)
- {
- fprintf (out_header,
- (GetMessage (3, 6,
- "<P before 1 first 1 left 1 graphic %s glink %s gtypelink 0>\n")),
- bitmap, familyName);
- }
- else
- fprintf (out_header, "%s", GetMessage (3, 3, "<P before 1 first 1 left 1>\n"));
- fprintf (out_header, "%s\n", abstract);
- fprintf (out_header, "</P></CHARACTERSET>\n");
- /*
- * put the information in the volume file.
- */
- fprintf (out_volume, "*.%s.filepos: %ld\n",
- familyName, filepos);
- fprintf (out_volume, "*.%s.filename: %s\n",
- familyName, TopicName);
- TopicList = (char **) _DtHelpCeAddPtrToArray (
- (void **) TopicList,
- strdup (familyName));
- }
- else
- {
- /*
- * rewind back to the original starting position
- */
- fseek (out_topic, filepos, 0);
- /*
- * didn't find any volumes for this family.
- */
- result = -2;
- }
- }
- XrmDestroyDatabase (db);
- }
- return result;
- }
- /*****************************************************************************
- * Function: CheckFamilyList (name)
- *
- * See if this family has been seen
- *
- *****************************************************************************/
- int
- CheckFamilyList (char *name )
- {
- char **listPtr = FamilyList;
- while (listPtr != NULL && *listPtr != NULL)
- {
- if (strcmp (*listPtr, name) == 0)
- return True;
- listPtr++;
- }
- return False;
- }
- /*****************************************************************************
- * Function: AddFamilyToList (name)
- *
- * add the name to the family list
- *
- *****************************************************************************/
- char **
- AddFamilyToList (char *name )
- {
- FamilyList = (char **) _DtHelpCeAddPtrToArray ((void **) FamilyList,
- strdup(name));
- return FamilyList;
- }
- /*****************************************************************************
- * Function: ScanDirectory
- *
- * scan a directory looking for family files.
- *
- *****************************************************************************/
- void
- ScanDirectory (
- char *directory,
- long *ret_time)
- {
- DIR *pDir;
- struct stat buf;
- char fullName [MAXPATHLEN + 2];
- char *ptr;
- char *ext;
- struct dirent *pDirent;
- *ret_time = 0;
- if (stat(directory, &buf) == -1)
- return;
- *ret_time = buf.st_mtime;
- pDir = opendir (directory);
- if (pDir == NULL)
- return;
- snprintf(fullName, sizeof(fullName), "%s%s", directory, SlashString);
- ptr = fullName + strlen (fullName);
- /*
- * skip over the "." and ".." entries.
- */
- (void) readdir (pDir);
- (void) readdir (pDir);
- pDirent = readdir (pDir);
- while (pDirent)
- {
- ext = GetExtension (pDirent->d_name);
- if (strcmp (ext, Family_ext) == 0)
- {
- if (CheckFamilyList (pDirent->d_name) == False)
- {
- AddFamilyToList (pDirent->d_name);
- strcpy (ptr, pDirent->d_name);
- FullFamilyName = (char **) _DtHelpCeAddPtrToArray(
- (void **)FullFamilyName,
- strdup(fullName));
- }
- }
- else if (strcmp(ext, Ext_Hv) == 0 || strcmp(ext, Ext_Sdl) == 0)
- {
- strcpy (ptr, pDirent->d_name);
- VolumeList = (char **) _DtHelpCeAddPtrToArray((void **)VolumeList,
- strdup(pDirent->d_name));
- FullVolName = (char **) _DtHelpCeAddPtrToArray((void **)FullVolName,
- strdup(fullName));
- }
- pDirent = readdir (pDir);
- }
- closedir(pDir);
- return;
- }
- /*****************************************************************************
- * Function: FindFile
- *
- * Resolves the environment variable for all possible paths.
- *
- *****************************************************************************/
- char *
- FindFile (
- char *filename)
- {
- int i;
- int trimExt = 0;
- int different;
- char *fileExt;
- char *ext;
- struct stat status;
- fileExt = GetExtension(filename);
- if (*fileExt == '\0')
- trimExt = 1;
- i = 0;
- while (VolumeList != NULL && VolumeList[i] != NULL)
- {
- if (trimExt)
- {
- ext = GetExtension(VolumeList[i]);
- *ext = '\0';
- }
- different = strcmp(filename, VolumeList[i]);
- if (trimExt)
- *ext = '.';
- if (!different && access(FullVolName[i], R_OK) == 0
- && stat(FullVolName[i], &status) == 0
- && S_ISDIR(status.st_mode) == 0)
- return (FullVolName[i]);
- i++;
- }
- return NULL;
- }
- /*****************************************************************************
- * Function: ExpandPaths
- *
- * Resolves the environment variable for all possible paths.
- *
- *****************************************************************************/
- void
- ExpandPaths (
- char *lang,
- char *type,
- char *env_var,
- char *default_str,
- char ***list)
- {
- short strip;
- char *ptr;
- char *hPtr;
- char *src;
- char *pathName;
- char *searchPath;
- searchPath = getenv (env_var);
- if (searchPath == NULL || *searchPath == '\0')
- {
- if (default_str == NULL)
- return;
- searchPath = default_str;
- }
- searchPath = strdup (searchPath);
- *list = NULL;
- src = searchPath;
- do
- {
- ptr = strchr (src, ':');
- if (ptr)
- *ptr = '\0';
- /*
- * check to see if %H is declared. If so, we're going
- * to have to trim it before saving as the directory path.
- */
- strip = False;
- hPtr = strrchr (src, '%');
- if (hPtr != NULL)
- {
- hPtr++;
- if (*hPtr == 'H')
- strip = True;
- }
- /*
- * check to see if the path needs expanding
- */
- if (NULL != strchr (src, '%'))
- pathName = _DtHelpCeExpandPathname (src, NULL, type, NULL, lang,
- (_DtSubstitutionRec *) NULL, 0);
- else
- pathName = strdup(src);
- if (pathName)
- {
- GetPath (pathName, strip, list);
- free (pathName);
- }
- if (ptr)
- {
- *ptr = ':';
- ptr++;
- }
- src = ptr;
- } while (src && *src);
- free(searchPath);
- }
- /*****************************************************************************
- * Function: CheckTimeStamps
- *
- * Check the time stamps on the volume dir to determine if
- * it needs regenerating.
- *
- *****************************************************************************/
- int
- CheckTimeStamps (
- XrmDatabase db,
- char **dir_list)
- {
- long timeVal;
- char *value;
- struct stat buf;
- while (*dir_list != NULL)
- {
- if (stat(*dir_list, &buf) == -1)
- buf.st_mtime = 0;
- value = _DtHelpCeGetResourceString(db, *dir_list,
- "TimeStamp", "timeStamp");
- timeVal = atol(value);
- if (timeVal != buf.st_mtime)
- return 1;
- dir_list++;
- }
- return 0;
- }
- /*****************************************************************************
- * Function: CheckInfo
- *
- * Check the information in the volume to determine if it needs regenerating.
- *
- *****************************************************************************/
- int
- CheckInfo (
- char *file)
- {
- int result = 1;
- char **list1, **list2;
- char **volDirList;
- XrmDatabase db;
- db = XrmGetFileDatabase (file);
- if (db != NULL)
- {
- volDirList = _DtHelpCeGetResourceStringArray(db, NULL,
- "DirList", "dirList");
- if (volDirList != NULL)
- {
- result = 0;
- list1 = volDirList;
- list2 = FUserList;
- while (result == 0 && *list1 != NULL
- && list2 != NULL && *list2 != NULL)
- {
- result = strcmp(*list1, *list2);
- list1++;
- list2++;
- }
- if (list2 != NULL && *list2 != NULL)
- result = 1;
- list2 = FSysList;
- while (result == 0 && *list1 != NULL
- && list2 != NULL && *list2 != NULL)
- {
- result = strcmp(*list1, *list2);
- list1++;
- list2++;
- }
- if (list2 != NULL && *list2 != NULL)
- result = 1;
- list2 = VUserList;
- while (result == 0 && *list1 != NULL
- && list2 != NULL && *list2 != NULL)
- {
- result = strcmp(*list1, *list2);
- list1++;
- list2++;
- }
- if (list2 != NULL && *list2 != NULL)
- result = 1;
- list2 = VSysList;
- while (result == 0 && *list1 != NULL
- && list2 != NULL && *list2 != NULL)
- {
- result = strcmp(*list1, *list2);
- list1++;
- list2++;
- }
- if (*list1 != NULL || (list2 != NULL && *list2 != NULL))
- result = 1;
- if (result == 0)
- result = CheckTimeStamps(db, volDirList);
- _DtHelpCeFreeStringArray(volDirList);
- }
- XrmDestroyDatabase(db);
- }
- return result;
- }
- /*****************************************************************************
- * Main routine
- *****************************************************************************/
- int
- main(
- int argc,
- char *argv[] )
- {
- int i;
- int result;
- int foundFamily;
- int foundVolumes;
- int usedUser = 0;
- int doGen = 0;
- char tmpVolume [MAXPATHLEN + 2];
- char tmpVolumeTemp[sizeof(tmpVolume)];
- char tmpVolume2 [MAXPATHLEN + 2];
- char tmpTopic [MAXPATHLEN + 2];
- char tmpHeader [MAXPATHLEN + 2];
- char headerName [MAXPATHLEN + 2];
- char baseName [MAXPATHLEN + 2];
- char baseNameTemp[sizeof(baseName)];
- char tempName [MAXPATHLEN + 2];
- char **next;
- char *charSet;
- char *topicTitle;
- char *ptr;
- char *endDir;
- long preamble;
- long modTime;
- FILE *outVolume;
- FILE *outTopic;
- FILE *outHeader;
- pid_t childPid = (pid_t) -1;
- CanvasHandle canvasHandle;
- myName = strrchr (argv[0], '/');
- if (myName)
- myName++;
- else
- myName = argv[0];
- /*
- * have to do a setlocale here, so that the usage message is in the
- * correct language.
- */
- Lang = getenv ("LANG");
- /*
- * use the default if no lang is specified.
- */
- if (Lang == NULL || *Lang == '\0')
- Lang = (char*)C_String;
- setlocale(LC_ALL, "");
- _DtEnvControl(DT_ENV_SET);
- /*
- * now process the arguments
- */
- for (i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-')
- {
- if (argv[i][1] == 'd' && i + 1 < argc)
- App_args.dir = argv[++i];
- else if (argv[i][1] == 'f' && i + 1 < argc)
- App_args.file = argv[++i];
- else if (argv[i][1] == 'g')
- doGen = 1;
- else if (argv[i][1] == 'l' && i + 1 < argc)
- App_args.lang = argv[++i];
- else
- {
- fprintf (stderr, (GetMessage(1,1, ((char*)UsageStr))), myName);
- exit (1);
- }
- }
- else
- {
- fprintf (stderr, (GetMessage(1,1, ((char*)UsageStr))), myName);
- exit (1);
- }
- }
- /*
- * get the language we are working with.
- */
- if (App_args.lang != NULL)
- {
- /*
- * Set the locale! Since the user has specified a (likely)
- * different language to do the processing in, we need to
- * do a setlocale to work with the new language.
- */
- Lang = App_args.lang;
- if (setlocale(LC_ALL, Lang) == NULL)
- {
- fprintf (stderr, (GetMessage(1, 20,
- "%s: Invalid system language specified - %s\n")),
- myName, Lang);
- exit (1);
- }
- _DtEnvControl(DT_ENV_SET);
- }
- Lang = strdup(Lang);
- /*
- * get the directory to work in
- */
- if (NULL == App_args.dir)
- {
- fprintf (stderr, (GetMessage(1,1, ((char*)UsageStr))), myName);
- exit (1);
- }
- if (App_args.dir[0] != '/')
- {
- if (getcwd (baseName, MAXPATHLEN) == NULL)
- {
- fprintf (stderr, (GetMessage (1, 18,
- "%s: Unable to access current working directory - error status number %d\n")),
- myName, errno);
- exit (1);
- }
- snprintf(baseNameTemp, sizeof(baseNameTemp), "%s/%s", baseName, App_args.dir);
- strcpy(baseName, baseNameTemp);
- }
- else
- snprintf(baseName, sizeof(baseName), "%s", App_args.dir);
- /*
- * make sure the directory exists
- */
- ptr = _DtHelpCeExpandPathname (baseName, NULL, "help", NULL, Lang,
- (_DtSubstitutionRec *) NULL, 0);
- if (ptr == NULL || *ptr == '\0')
- {
- fprintf (stderr,
- (GetMessage (1, 15, "%s: Destination directory missing\n")),
- myName);
- exit (1);
- }
- snprintf(tmpVolume, sizeof(tmpVolume), "%s", ptr);
- if (tmpVolume[strlen (tmpVolume) - 1] != '/') {
- snprintf(tmpVolumeTemp, sizeof(tmpVolumeTemp), "%s%s", tmpVolume, SlashString);
- strcpy(tmpVolume, tmpVolumeTemp);
- }
- free (ptr);
- /*
- * march down the path, checking that
- * 1) it exists
- * 2) the caller has access permission.
- * 3) resolve all symbolic links
- */
- endDir = strchr (tmpVolume, '/');
- if (endDir != NULL)
- {
- endDir++;
- endDir = strchr (endDir, '/');
- }
- while (endDir && *endDir != '\0')
- {
- /*
- * remember the rest of the string (including the slash)
- * and strip the trailing slash from the directory path.
- */
- snprintf(tmpVolume2, sizeof(tmpVolume2), "%s", endDir);
- *endDir = '\0';
- /*
- * trace the path and copy the new string into the old buffer.
- */
- ptr = _DtHelpCeTracePathName(tmpVolume);
- if (ptr != NULL)
- {
- snprintf(tmpVolume, sizeof(tmpVolume), "%s", ptr);
- free (ptr);
- }
- if (access (tmpVolume, F_OK) == -1)
- {
- switch (errno)
- {
- case ENOTDIR:
- ptr = GetMessage (1, 2, (char*)NotDirectory);
- fprintf (stderr, ptr, myName, tmpVolume);
- exit (1);
- case EACCES:
- ptr = GetMessage (1, 3, (char*)SuperMsg);
- fprintf (stderr, ptr, myName, tmpVolume);
- exit (1);
- case ENOENT:
- if (mkdir(tmpVolume,
- (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) == -1
- && errno != EEXIST && errno != EROFS)
- {
- switch (errno)
- {
- case ENOTDIR:
- ptr = GetMessage(1,2,
- (char*)NotDirectory);
- break;
- case EACCES:
- ptr = GetMessage(1, 3,
- (char*)SuperMsg);
- break;
- case ENOENT:
- ptr = GetMessage(1, 4,
- "%s: Element of %s does not exist\n");
- break;
- case ENOSPC:
- ptr = GetMessage (1, 5,
- "%s: File system containing %s is full\n");
- break;
- default:
- ptr = GetMessage(1,6,
- (char*)GeneralAccess);
- break;
- }
- fprintf (stderr, ptr, myName, tmpVolume, errno);
- exit (1);
- }
- break;
- default:
- ptr = GetMessage (1, 6, (char*)GeneralAccess);
- fprintf (stderr, ptr, myName, tmpVolume, errno);
- exit (1);
- }
- }
- /*
- * point to the end of the string (past where the slash will go)
- */
- endDir = tmpVolume + strlen(tmpVolume) + 2;
- /*
- * append the rest of the directory spec that hasn't been checked.
- */
- strcat (tmpVolume, tmpVolume2);
- endDir = strchr (endDir, '/');
- }
- /*
- * get temporary files for the volume and topic file.
- */
- snprintf(tmpVolumeTemp, sizeof(tmpVolumeTemp), "%s%s", tmpVolume, App_args.file);
- strcpy(tmpVolume, tmpVolumeTemp);
- (void) strcpy (tmpHeader, tmpVolume);
- (void) strcpy (tmpTopic, tmpVolume);
- snprintf(tmpVolumeTemp, sizeof(tmpVolumeTemp), "%s%s", tmpVolume, Ext_Hv);
- strcpy(tmpVolume, tmpVolumeTemp);
- (void) strcat (tmpHeader, "00.ht");
- (void) strcat (tmpTopic , "01.ht");
- result = access (tmpVolume, F_OK);
- /*
- * If it exists, make sure the invoker can write to it.
- */
- if (result == 0)
- {
- if (access (tmpVolume, W_OK) == -1)
- {
- if (errno == EROFS)
- ptr = GetMessage (1, 7,
- "%s: File system containing %s is read only\n");
- else if (errno == EACCES)
- ptr = GetMessage (1, 8,
- "%s: Requires root permission to write to %s\n");
- else
- ptr = GetMessage (1, 9, (char*)WriteInvalid);
- fprintf (stderr, ptr, myName, tmpVolume, errno);
- exit (1);
- }
- }
- else if (result == -1 && errno != ENOENT)
- {
- ptr = GetMessage (1, 6, (char*)GeneralAccess);
- fprintf (stderr, ptr, myName, tmpVolume, errno);
- exit (1);
- }
- else /* file does not exist */
- doGen = 1;
- /*
- * Find out if we have any paths to check.
- */
- ExpandPaths(Lang, "families", DtUSER_FILE_SEARCH_ENV, NULL, &FUserList);
- ExpandPaths(Lang, "volumes", DtUSER_FILE_SEARCH_ENV, NULL, &VUserList);
- ExpandPaths(Lang, "families", DtSYS_FILE_SEARCH_ENV ,
- DtDEFAULT_SYSTEM_PATH, &FSysList);
- ExpandPaths(Lang, "volumes", DtSYS_FILE_SEARCH_ENV ,
- DtDEFAULT_SYSTEM_PATH, &VSysList);
- if (((FUserList == NULL || *FUserList == NULL) &&
- (FSysList == NULL || *FSysList == NULL)) ||
- ((VUserList == NULL || *VUserList == NULL) &&
- (VSysList == NULL || *VSysList == NULL)))
- {
- ptr = GetMessage (1, 10, "%s: Search Path empty\n");
- fprintf (stderr, ptr, myName);
- exit (1);
- }
- /*
- * If we already haven't determined that the volume needs (re)generating
- * check the info squirreled away in the old volume.
- */
- if (doGen == 0)
- doGen = CheckInfo(tmpVolume);
- /*
- * the volume doesn't need (re)generating.
- * exit now.
- */
- if (doGen == 0)
- exit(0);
- /*
- * create a canvas for the functions.
- */
- canvasHandle = _DtHelpCeCreateDefCanvas();
- if (canvasHandle == NULL)
- {
- fprintf (stderr, GetMessage(1, 19,"%s: Unable to allocate memory\n"),
- myName);
- MyExit (1, -1);
- }
- /*
- * open the individual files that will hold the browser information.
- * <file>.hv
- */
- outVolume = fopen (tmpVolume, "w");
- if (outVolume == NULL)
- {
- ptr = GetMessage (1, 9, (char*)WriteInvalid);
- fprintf (stderr, ptr, myName, tmpVolume, errno);
- _DtHelpCeDestroyCanvas(canvasHandle);
- MyExit (1, -1);
- }
- /*
- * <file>00.ht
- */
- outTopic = fopen (tmpTopic, "w");
- if (outTopic == NULL)
- {
- ptr = GetMessage (1, 9, (char*)WriteInvalid);
- fprintf (stderr, ptr, myName, tmpTopic, errno);
- (void) unlink (tmpVolume);
- _DtHelpCeDestroyCanvas(canvasHandle);
- MyExit (1, -1);
- }
- /*
- * <file>01.ht
- */
- outHeader = fopen (tmpHeader, "w");
- if (outHeader == NULL)
- {
- ptr = GetMessage (1, 9, (char*)WriteInvalid);
- fprintf (stderr, ptr, myName, tmpHeader, errno);
- (void) unlink (tmpVolume);
- (void) unlink (tmpTopic);
- _DtHelpCeDestroyCanvas(canvasHandle);
- MyExit (1, -1);
- }
- /*
- * fork off the dtksh script that will put up a dialog
- * telling the user that we're building help browser
- * information.
- */
- childPid = fork();
- /*
- * if this is the child, exec the dthelpgen.ds script.
- */
- if (childPid == 0)
- {
- execlp("dthelpgen.ds", "dthelpgen.ds",
- ((char *) 0), ((char *) 0), ((char *) 0));
- _exit(1);
- }
- /*
- * initialize the main topic
- */
- strcpy (TopicName, App_args.file);
- strcat (TopicName, "01.ht");
- strcpy (headerName, App_args.file);
- strcat (headerName, "00.ht");
- /*
- * The original dthelpgen extracts the CDE Standard name from
- * its message catalogue( set 2/msg 1 ).
- * But on IBM ODE, this is a problem. For example,
- * fr_FR's dthelpgen.cat has
- * fr_FR.ISO-8859-1 in set 2/msg 1.
- * Correct Fr_FR's message catalogue must have,
- * fr_FR.IBM-850
- * there. But current IBM ode's Makefile cannot do this. Instead put
- * fr_FR.ISO-8859-1. ( That is "do nothing" ).
- * To fix this, dthelpgen converts the current IBM LANG to CDE
- * standard name with _DtLcx*() function provided by libDtHelp.a as
- * internal API.
- */
- #ifdef _AIX
- {
- _DtXlateDb db = NULL;
- int ret;
- char plat[_DtPLATFORM_MAX_LEN];
- int execver;
- int compver;
- char *ret_stdLocale;
- char *ret_stdLangTerr;
- char *ret_stdCodeset;
- char *ret_stdModifier;
- ret = _DtLcxOpenAllDbs( &db );
- if ( !ret ) {
- ret = _DtXlateGetXlateEnv( db, plat, &execver, &compver );
- if ( !ret ) {
- ret = _DtLcxXlateOpToStd( db, plat, execver,
- DtLCX_OPER_SETLOCALE,
- setlocale( LC_MESSAGES, NULL ),
- &ret_stdLocale, &ret_stdLangTerr,
- &ret_stdCodeset, &ret_stdModifier );
- if ( !ret ) {
- charSet = strdup( ret_stdLocale );
- } else {
- charSet = "C.ISO-8859-1";
- }
- } else {
- charSet = "C.ISO-8859-1";
- }
- ret = _DtLcxCloseDb( &db );
- } else {
- charSet = "C.ISO-8859-1";
- }
- }
- #else /* _AIX */
- charSet = strdup (GetMessage (2, 1, "C.ISO-8859-1"));
- #endif /* _AIX */
- topicTitle = strdup (GetMessage (2, 2, "Welcome to Help Manager"));
- fprintf (outHeader, (GetMessage (3, 1, (char*)defaultTopic)),
- charSet, topicTitle);
- fprintf (outHeader, (GetMessage (3, 2, (char*)defaultTitle14)), topicTitle);
- free(topicTitle);
- preamble = ftell (outHeader);
- fprintf (outHeader, "%s\n", GetMessage (2, 3, (char*)defaultTextBody));
- /*
- * loop through the directories looking for all the unique families
- * and -all- the volumes.
- */
- fprintf (outVolume, "!# Last modification time stamp per directory\n");
- next = FUserList;
- while (next != NULL && *next != NULL)
- {
- ScanDirectory(*next, &modTime);
- fprintf (outVolume, "*.%s.timeStamp: %ld\n" , *next, modTime);
- next++;
- }
- next = FSysList;
- while (next != NULL && *next != NULL)
- {
- ScanDirectory(*next, &modTime);
- fprintf (outVolume, "*.%s.timeStamp: %ld\n" , *next, modTime);
- next++;
- }
- next = VUserList;
- while (next != NULL && *next != NULL)
- {
- ScanDirectory(*next, &modTime);
- fprintf (outVolume, "*.%s.timeStamp: %ld\n" , *next, modTime);
- next++;
- }
- next = VSysList;
- while (next != NULL && *next != NULL)
- {
- ScanDirectory(*next, &modTime);
- fprintf (outVolume, "*.%s.timeStamp: %ld\n" , *next, modTime);
- next++;
- }
- fprintf (outVolume, "*.charSet: %s\n", charSet);
- free(charSet);
- fprintf (outVolume, "\n!# Topic filenames and offsets\n");
- /*
- * Now create families.
- */
- foundVolumes = 0;
- foundFamily = 0;
- for (next = FullFamilyName; next != NULL && *next != NULL; next++)
- {
- result = CreateFamily(canvasHandle,*next,outVolume,outHeader,outTopic);
- if (result == 0)
- {
- FamilyNum++;
- foundVolumes = 1;
- foundFamily = 1;
- }
- else if (result == -2)
- foundFamily = 1;
- }
- if (foundFamily == 0)
- fprintf(stderr,
- GetMessage(1, 16, "%s: Zero Family files found\n"), myName);
- else if (foundVolumes == 0)
- fprintf (stderr,
- GetMessage (1, 17, "%s: Zero Volume files found\n"), myName);
- /*
- * Clean up
- */
- if (FamilyList != NULL)
- _DtHelpCeFreeStringArray(FamilyList);
- if (FullFamilyName != NULL)
- _DtHelpCeFreeStringArray(FullFamilyName);
- if (VolumeList != NULL)
- _DtHelpCeFreeStringArray(VolumeList);
- if (FullVolName != NULL)
- _DtHelpCeFreeStringArray(FullVolName);
- /*
- * If no family or volume files were found,
- * write out the alternative preamble
- */
- if (foundFamily == 0 || foundVolumes == 0)
- {
- fseek (outHeader, preamble, 0);
- fprintf (outHeader, "%s\n", GetMessage (2, 5, (char*)defaultAlternate));
- }
- /*
- * write the ending message and finish the topic.
- */
- fprintf (outHeader, "</TOPIC>\n");
- /*
- * write out the volume resouces
- */
- fprintf (outVolume, "\n\n!# Top (or home) topic filename and offset\n");
- fprintf (outVolume, "*.%s.filepos: 0\n" , ParentName);
- fprintf (outVolume, "*.%s.filename: %s\n", ParentName, headerName);
- fprintf (outVolume, "\n\n!# Volume Title\n");
- fprintf (outVolume, "*.title: %s\n",
- GetMessage (2, 4, "Help - Top Level"));
- /*
- * top topic
- */
- fprintf (outVolume, "\n\n!# Topic Home Location\n");
- fprintf (outVolume, "*.topTopic: %s\n", ParentName);
- /*
- * topic hierarchy
- */
- fprintf (outVolume, "\n\n!# Topic Hierarchy\n");
- fprintf (outVolume, "*.%s.parent: \n", ParentName);
- for (next = TopicList; next && *next; next++)
- fprintf (outVolume, "*.%s.parent: %s\n", *next, ParentName);
- /*
- * topic list
- */
- fprintf (outVolume, "\n\n!# Topic List\n");
- fprintf (outVolume, "*.topicList: %s", ParentName);
- next = TopicList;
- while (next && *next)
- {
- fprintf (outVolume, " \\\n %s", *next);
- next++;
- }
- fprintf (outVolume, "\n");
- /*
- * The paths used to create this information.
- */
- fprintf (outVolume, "\n\n!# Paths Searched\n");
- fprintf (outVolume, "*.dirList: ");
- next = FUserList;
- while (next != NULL && *next != NULL)
- {
- fprintf (outVolume, " \\\n %s", *next);
- next++;
- }
- next = FSysList;
- while (next != NULL && *next != NULL)
- {
- fprintf (outVolume, " \\\n %s", *next);
- next++;
- }
- next = VUserList;
- while (next != NULL && *next != NULL)
- {
- fprintf (outVolume, " \\\n %s", *next);
- next++;
- }
- next = VSysList;
- while (next != NULL && *next != NULL)
- {
- fprintf (outVolume, " \\\n %s", *next);
- next++;
- }
- fprintf (outVolume, "\n");
- /*
- * close the volumes.
- */
- fclose (outVolume);
- fclose (outHeader);
- fclose (outTopic);
- if (TopicList != NULL)
- _DtHelpCeFreeStringArray(TopicList);
- if (FUserList != NULL)
- _DtHelpCeFreeStringArray(FUserList);
- if (FSysList != NULL)
- _DtHelpCeFreeStringArray(FSysList);
- if (VUserList != NULL)
- _DtHelpCeFreeStringArray(VUserList);
- if (VSysList != NULL)
- _DtHelpCeFreeStringArray(VSysList);
- _DtHelpCeDestroyCanvas(canvasHandle);
- MyExit (0, childPid);
- }
|