home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name HLOPEN -- Open a help database and construct its index
- * in memory.
- *
- * Synopsis result = hlopen(pdatabase_path);
- *
- * int result Error code indicating success or
- * failure of the operation.
- * const char The name of the help database to
- * *pdatabase_path open.
- *
- * Description This function accepts a pointer to a string which
- * contains the name of a help database constructed with
- * BUILDHLP, copies that string into the global variable
- * b_help_path, constructs an in memory index of the help
- * records contained in the file, and places a pointer to
- * the root of the index in the global variable
- * b_phelp_index.
- *
- * If pdatabase path is NIL or points to the NUL string
- * ("\0") then the pathname of the previously opened
- * database is used (if there was one). If no database
- * was previously open, HL_NO_PATH is returned.
- *
- * If b_phelp_index already points to a database index,
- * the entire index is freed before the new index is built.
- *
- * An error occurs if the given pathname does not exist, if
- * there are not enough file handles to open the database,
- * if the path does not point to a valid help database, or
- * if there is not enough memory to construct the index.
- *
- * Returns result Error code. Possible values are:
- * HL_NO_ERROR Operation successful.
- * HL_NO_PATH Pathname does not exist.
- * HL_NO_HANDLES Not enough file handles.
- * HL_BAD_DATABASE Specified file is not
- * a valid help file.
- * HL_NO_MEMORY Insufficient memory.
- * HL_VER_MISMATCH Database version is
- * incorrect.
- * HL_SYSTEM Internal error.
- *
- * b_phelp_index Pointer to newly constructed help index,
- * or NIL if failure.
- *
- * b_help_path Pathname of database whose index is
- * currently constructed.
- *
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
-
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
- #include <errno.h>
- #include <bhelp.h>
- #include <bfiles.h>
-
-
- HL_INDEX_NODE *b_phelp_index = NIL;
- char b_help_path[MAX_FLEN] = {'\0'};
-
- #define close_error(error) \
- { \
- close(help_fd); \
- b_help_path[0] = '\0'; \
- hlfrindx(b_phelp_index); \
- hlerror(error); \
- return(b_wnerr); \
- }
-
- static void cdecl insert_index(HL_INDEX_NODE **, HL_INDEX_NODE *);
-
-
- int hlopen(pdatabase_path)
- const char *pdatabase_path;
- {
- int help_fd;
- int name_index = 0;
- int bytes_read;
- unsigned long file_size;
- HL_FILE_HEADER file_header;
- HL_INDEX_NODE *pnew_node;
-
- errno = 0;
-
- if ((pdatabase_path == NIL) || (*pdatabase_path == '\0'))
- pdatabase_path = b_help_path;
-
- /* Try to open and read the help database. */
- help_fd = open(pdatabase_path, O_RDONLY | O_BINARY);
- if (help_fd == -1)
- {
- switch (errno)
- {
- case EACCES:
- hlerror(HL_BAD_DATABASE);
-
- case EMFILE:
- hlerror(HL_NO_HANDLES);
-
- case ENOENT:
- hlerror(HL_NO_PATH);
-
- default:
- hlerror(HL_SYSTEM);
- }
-
- return(b_wnerr);
- }
-
- /* Now that the database has been opened, copy the */
- /* pathname into b_help_path. */
- if (pdatabase_path != b_help_path)
- if (flnorm(pdatabase_path, b_help_path, &name_index) != 0)
- {
- strncpy(b_help_path, pdatabase_path, sizeof(b_help_path));
- b_help_path[sizeof(b_help_path) - 1] = '\0';
- }
-
- if (b_phelp_index != NIL)
- {
- hlfrindx(b_phelp_index);
- b_phelp_index = NIL;
- }
-
- file_size = lseek(help_fd, 0, SEEK_END);
- lseek(help_fd, 0, SEEK_SET);
-
- if ((read(help_fd, &file_header,
- sizeof(file_header)) != sizeof(file_header)) ||
- (file_size < file_header.file_size) ||
- (file_header.index_offset > file_size) ||
- ((file_header.index_offset != 0) &&
- (file_header.index_offset < sizeof(file_header))) ||
- (strncmp(file_header.file_sign, HL_FILE_SIGN,
- strlen(HL_FILE_SIGN)) != 0))
- {
- close_error(HL_BAD_DATABASE);
- }
-
- if (file_header.version != HL_VERSION)
- {
- close_error(HL_VER_MISMATCH);
- }
-
- if (lseek(help_fd, file_header.index_offset, SEEK_SET) == 0)
- {
- close(help_fd);
- return(HL_NO_ERROR);
- }
-
- /* Now begin reading the database index. */
- do
- {
- pnew_node = calloc(sizeof(HL_INDEX_NODE), 1);
- if (pnew_node == NIL)
- {
- close_error(HL_NO_MEMORY);
- }
-
- bytes_read = read(help_fd, &(pnew_node->index_data),
- sizeof(pnew_node->index_data));
-
- if (pnew_node->index_data.description_len != 0)
- {
- pnew_node->pdescription =
- malloc(pnew_node->index_data.description_len + 1);
-
- if (pnew_node->pdescription == NIL)
- {
- close_error(HL_NO_MEMORY);
- }
-
- bytes_read += read(help_fd, pnew_node->pdescription,
- pnew_node->index_data.description_len);
- }
- else
- pnew_node->pdescription = NIL;
-
- if (bytes_read != 0)
- {
- if (bytes_read != (sizeof(pnew_node->index_data) +
- pnew_node->index_data.description_len))
- {
- close_error(HL_BAD_DATABASE);
- }
- else
- {
- hlpas2c(pnew_node->index_data.id_string,
- pnew_node->index_data.id_string,
- sizeof(pnew_node->index_data.id_string));
-
- pnew_node->pdescription[
- pnew_node->index_data.description_len] = '\0';
- insert_index(&b_phelp_index, pnew_node);
- }
- lseek(help_fd, pnew_node->index_data.next_index,
- SEEK_SET);
- }
- }
- while ((pnew_node->index_data.next_index != 0) &&
- (bytes_read != 0));
-
- close(help_fd);
-
- return(HL_NO_ERROR);
- }
-
-
- /**
- *
- * Name INSERT_INDEX Insert a help index node into the given
- * help index subtree.
- *
- * Synopsis insert_index(ppindex_node, pnew_node);
- *
- * HL_INDEX_NODE *ppindex_node Pointer to pointer to
- * subtree into which the new
- * node is to be inserted.
- * HL_INDEX_NODE *pnew_node Pointer to the new help
- * index node to insert.
- *
- * Description This function accepts a pointer to a pointer to a help
- * index subtree and a pointer to a new help index node
- * and inserts the given node into the subtree. If
- * *ppindex_node is NIL, *ppindex node is set to pnew_node.
- *
- * Returns *ppindex_node If NIL, it is set to pnew_node.
- *
- **/
-
- void insert_index(ppindex_node, pnew_node)
- HL_INDEX_NODE **ppindex_node;
- HL_INDEX_NODE *pnew_node;
- {
- if (*ppindex_node == NIL)
- {
- *ppindex_node = pnew_node;
- return;
- }
-
- if (strcmp(pnew_node->index_data.id_string,
- (*ppindex_node)->index_data.id_string) <= 0)
- insert_index(&((*ppindex_node)->pleft), pnew_node);
- else
- insert_index(&((*ppindex_node)->pright), pnew_node);
-
- return;
- }