/* * 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 */ /* * COMPONENT_NAME: austext * * FUNCTIONS: open_dblk * * ORIGINS: 27 * * (C) COPYRIGHT International Business Machines Corp. 1993,1995 * All Rights Reserved * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /*********************** OPENDBLK.C ************************ * $XConsortium: opendblk.c /main/5 1996/05/07 13:43:01 drk $ * October 1993. * Opens all vista and the d99 database files in a dblk list. * Most errors are handled by disconnecting the offending * dblk from the list. Of course loss of ALL dblks is fatal. * * The nonvista d99 files (words inverted index) are opened, * mostly to test if they can be found. If not, we can return * a complete error message for the single dblk and unlink it. * Vista can only open all databases at once. * * Does not use dmacros.h for vista calls so error msgs can be * constructed and added to global msglist (although hard vista * errors will still first send a msg to stdout via dberr.c). * * Open_dblk() should be used to replace all OPEN() calls * in systems using DBLK structures. * (1) It does not open dictionary files because they are not * always needed (in OE, these are opened in oeinit.c). * (2) It does not read dbrec system records because the caller may * want to initialize them (in OE, these are read and * validated by ve_initialize() in ve.c). * (3) It does not open the other d9x files because they * may not be present, depending on values in dbrec record. * * INPUT: * 'dblist' is linked list of dblks. * Each dblk must have valid 'name' field, * and 'path' field must be NULL or a valid path string. * 'numpages' is the number of vista cache pages to be opened. * Where speed is critical it should be 64-- * for normal operations it should be no less than 16. * 'debugging' is a boolean. It is usually set to (usrblk.debug & USRDBG_RARE) * and if TRUE, trace msgs are written to stdout. * * OUTPUT: * Sets correct vistano, iifile, and iimtime fields in each surviving dblk. * Places all err msgs on global msglist as they occur. * Sets austext_exit_dbms to d_close() on success (retncode > 0). * Returns TRUE if at least some of the databases were opened. * Bad dblks are unlinked from dblist and freed. * Returns FALSE if fatal errors. * * $Log$ * Revision 2.5 1996/02/01 19:19:41 miker * Minor change to err msg. * * Revision 2.4 1995/10/25 15:26:16 miker * Added prolog. * * Revision 2.3 1995/10/19 20:25:52 miker * Renaming database files no longer required. * Transaction logging disabled, no space needed for overflow files. * Open mode of non-vista database files also tracks new vista db_oflag. * * Revision 2.2 1995/10/03 21:45:26 miker * Cosmetic msg changes only. * * Revision 2.1 1995/09/22 21:38:03 miker * Freeze DtSearch 0.1, AusText 2.1.8 * * Revision 1.8 1995/09/05 19:04:40 miker * Name and msgs changes for DtSearch. Made ausapi_msglist universal. */ #include "SearchE.h" #include #include #include #include #include #include "vista.h" #define PROGNAME "OPENDBLK" #define MS_misc 1 #define MS_oeinit 9 #define MS_vista 13 /****************************************/ /* */ /* open_dblk */ /* */ /****************************************/ /* dblk.path may be NULL */ int open_dblk (DBLK ** dblist, int numpages, int debugging) { DBLK *db, *bad_db, **lastlink; int i; size_t totlen = 0L; char *allnames; int vistano = 0; char *srcptr, *targptr; char temp_file_name[1024]; char sprintbuf[1024]; struct stat statbuf; char open_mode [8]; if (debugging) fprintf (aa_stderr, PROGNAME"76 " "Entering open_dblks(). db_oflag==%d.\n", db_oflag); if (dblist == NULL || numpages < 8) { BAD_INPUT: sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 99, "%s Programming Error: Invalid input to open_dblk()."), PROGNAME "99"); DtSearchAddMessage (sprintbuf); return FALSE; } if (*dblist == NULL) /* empty list of dblks */ goto BAD_INPUT; if (debugging) { fprintf (aa_stderr, PROGNAME "96 Current list of dblks:\n"); for (db = *dblist; db != NULL; db = db->link) { targptr = sprintbuf; for (i = 0; i < db->ktcount; i++) { *targptr++ = db->keytypes[i].ktchar; } *targptr = 0; fprintf (aa_stderr, "--> DBLK at %p link=%p name='%s' maxhits=%d\n" " keytypes='%s', path='%s'\n", (void *) db, (void *) db->link, db->name, db->maxhits, sprintbuf, NULLORSTR (db->path)); } } /* By doing setpages first, we can trap previously opened databases. * Overflow and transaction locking files are not required. */ d_setpages (numpages, 0); if (db_status != S_OKAY) { DtSearchAddMessage (vista_msg (PROGNAME "389")); return FALSE; } /* ---- PASS #1 ------------------------------------------ * Open nonvista (d99) files. If error, unlink dblk from dblist. * Add up the total string length of surviving paths and database names. * This giant path/file string will be used in the single d_open() * below to find the .dbd files. * While we're at it, set vistano in each dblk. * The open mode depends on the current setting of db_oflag. */ if (db_oflag == O_RDONLY) strcpy (open_mode, "rb"); else strcpy (open_mode, "r+b"); db = *dblist; lastlink = dblist; while (db != NULL) { if (db->path == NULL) db->path = strdup (""); strcpy (temp_file_name, db->path); strcat (temp_file_name, db->name); strcat (temp_file_name, EXT_DTBS); if ((db->iifile = fopen (temp_file_name, open_mode)) == NULL) { if (debugging) fprintf (aa_stderr, PROGNAME "129 UNLINK: cant open '%s'.\n", temp_file_name); sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 317, "%s Cannot open database file '%s'.\n" " Errno %d = %s\n" " %s is removing '%s' from list of available databases."), PROGNAME "317", temp_file_name, errno, strerror (errno), OE_prodname, db->name); if (errno == ENOENT) strcat (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 318, "\n This can usually be corrected by specifying a valid\n" " database PATH in the site configuration file.")); DtSearchAddMessage (sprintbuf); goto DELETE_DB; } /* * Find and save the timestamp for when the d99 file was * last modified. An engine reinit is forced if it changes * while the engine is running. */ if (fstat (fileno (db->iifile), &statbuf) == -1) { if (debugging) fprintf (aa_stderr, PROGNAME "149 UNLINK: cant get status '%s'.\n", temp_file_name); sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 1404, "%s Removing database '%s' from list of " "available databases because status is " "unavailable for file %s: %s"), PROGNAME "1404", db->name, temp_file_name, strerror (errno)); DtSearchAddMessage (sprintbuf); goto DELETE_DB; } db->iimtime = statbuf.st_mtime; /* * This dblk is ok so far. Increment pointers and * continue. */ if (debugging) fprintf (aa_stderr, PROGNAME "163 opened '%s'.\n", temp_file_name); db->vistano = vistano++; totlen += strlen (db->path) + strlen (db->name) + 16; lastlink = &db->link; db = db->link; continue; DELETE_DB: /* * This dblk failed in one or more ways. Unlink it and * don't increment pointers. If all dblks unlinked, *dblist * will = NULL. */ bad_db = db; /* temp save */ *lastlink = db->link; db = db->link; free (bad_db); } /* end PASS #1 */ /* quit if no dblks remain */ if (vistano <= 0) { sprintf (sprintbuf, catgets (dtsearch_catd, MS_misc, 8, "%s No valid databases remain."), PROGNAME "265"); DtSearchAddMessage (sprintbuf); return FALSE; } allnames = austext_malloc (totlen + 512, PROGNAME "66", NULL); /* ---- PASS #2 ------------------------------------------ * Build string of accumulated path and database names. */ targptr = allnames; for (db = *dblist; db != NULL; db = db->link) { srcptr = db->path; while (*srcptr != 0) *targptr++ = *srcptr++; srcptr = db->name; while (*srcptr != 0) *targptr++ = *srcptr++; *targptr++ = ';'; } *(--targptr) = 0; /* terminate string */ if (debugging) fprintf (aa_stderr, PROGNAME "150 vista opening databases '%s'\n", allnames); d_open (allnames, "o"); /* replaces OPEN() call from dmacros.h */ if (db_status != S_OKAY) { targptr = austext_malloc (totlen + 128, PROGNAME"239", NULL); sprintf (targptr, catgets (dtsearch_catd, MS_vista, 378, "%s Could not open following database name string:\n '%s'"), PROGNAME"378", allnames); DtSearchAddMessage (targptr); DtSearchAddMessage (vista_msg (PROGNAME"379")); free (allnames); free (targptr); return FALSE; } else if (debugging) fprintf (aa_stderr, " --> vista open successful!\n"); /* From here on, emergency exits MUST close the databases */ austext_exit_dbms = (void (*) (int)) d_close; free (allnames); return TRUE; } /* open_dblk() */ /*********************** OPENDBLK.C ************************/