opendblk.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*
  24. * COMPONENT_NAME: austext
  25. *
  26. * FUNCTIONS: open_dblk
  27. *
  28. * ORIGINS: 27
  29. *
  30. * (C) COPYRIGHT International Business Machines Corp. 1993,1995
  31. * All Rights Reserved
  32. * US Government Users Restricted Rights - Use, duplication or
  33. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  34. */
  35. /*********************** OPENDBLK.C ************************
  36. * $XConsortium: opendblk.c /main/5 1996/05/07 13:43:01 drk $
  37. * October 1993.
  38. * Opens all vista and the d99 database files in a dblk list.
  39. * Most errors are handled by disconnecting the offending
  40. * dblk from the list. Of course loss of ALL dblks is fatal.
  41. *
  42. * The nonvista d99 files (words inverted index) are opened,
  43. * mostly to test if they can be found. If not, we can return
  44. * a complete error message for the single dblk and unlink it.
  45. * Vista can only open all databases at once.
  46. *
  47. * Does not use dmacros.h for vista calls so error msgs can be
  48. * constructed and added to global msglist (although hard vista
  49. * errors will still first send a msg to stdout via dberr.c).
  50. *
  51. * Open_dblk() should be used to replace all OPEN() calls
  52. * in systems using DBLK structures.
  53. * (1) It does not open dictionary files because they are not
  54. * always needed (in OE, these are opened in oeinit.c).
  55. * (2) It does not read dbrec system records because the caller may
  56. * want to initialize them (in OE, these are read and
  57. * validated by ve_initialize() in ve.c).
  58. * (3) It does not open the other d9x files because they
  59. * may not be present, depending on values in dbrec record.
  60. *
  61. * INPUT:
  62. * 'dblist' is linked list of dblks.
  63. * Each dblk must have valid 'name' field,
  64. * and 'path' field must be NULL or a valid path string.
  65. * 'numpages' is the number of vista cache pages to be opened.
  66. * Where speed is critical it should be 64--
  67. * for normal operations it should be no less than 16.
  68. * 'debugging' is a boolean. It is usually set to (usrblk.debug & USRDBG_RARE)
  69. * and if TRUE, trace msgs are written to stdout.
  70. *
  71. * OUTPUT:
  72. * Sets correct vistano, iifile, and iimtime fields in each surviving dblk.
  73. * Places all err msgs on global msglist as they occur.
  74. * Sets austext_exit_dbms to d_close() on success (retncode > 0).
  75. * Returns TRUE if at least some of the databases were opened.
  76. * Bad dblks are unlinked from dblist and freed.
  77. * Returns FALSE if fatal errors.
  78. *
  79. * $Log$
  80. * Revision 2.5 1996/02/01 19:19:41 miker
  81. * Minor change to err msg.
  82. *
  83. * Revision 2.4 1995/10/25 15:26:16 miker
  84. * Added prolog.
  85. *
  86. * Revision 2.3 1995/10/19 20:25:52 miker
  87. * Renaming database files no longer required.
  88. * Transaction logging disabled, no space needed for overflow files.
  89. * Open mode of non-vista database files also tracks new vista db_oflag.
  90. *
  91. * Revision 2.2 1995/10/03 21:45:26 miker
  92. * Cosmetic msg changes only.
  93. *
  94. * Revision 2.1 1995/09/22 21:38:03 miker
  95. * Freeze DtSearch 0.1, AusText 2.1.8
  96. *
  97. * Revision 1.8 1995/09/05 19:04:40 miker
  98. * Name and msgs changes for DtSearch. Made ausapi_msglist universal.
  99. */
  100. #include "SearchE.h"
  101. #include <string.h>
  102. #include <stdlib.h>
  103. #include <errno.h>
  104. #include <fcntl.h>
  105. #include <sys/stat.h>
  106. #include "vista.h"
  107. #define PROGNAME "OPENDBLK"
  108. #define MS_misc 1
  109. #define MS_oeinit 9
  110. #define MS_vista 13
  111. /****************************************/
  112. /* */
  113. /* open_dblk */
  114. /* */
  115. /****************************************/
  116. /* dblk.path may be NULL */
  117. int open_dblk (DBLK ** dblist, int numpages, int debugging)
  118. {
  119. DBLK *db, *bad_db, **lastlink;
  120. int i;
  121. size_t totlen = 0L;
  122. char *allnames;
  123. int vistano = 0;
  124. char *srcptr, *targptr;
  125. char temp_file_name[1024];
  126. char sprintbuf[1024];
  127. struct stat statbuf;
  128. char open_mode [8];
  129. if (debugging)
  130. fprintf (aa_stderr, PROGNAME"76 "
  131. "Entering open_dblks(). db_oflag==%d.\n",
  132. db_oflag);
  133. if (dblist == NULL || numpages < 8) {
  134. BAD_INPUT:
  135. sprintf (sprintbuf, CATGETS(dtsearch_catd, MS_oeinit, 99,
  136. "%s Programming Error: Invalid input to open_dblk()."),
  137. PROGNAME "99");
  138. DtSearchAddMessage (sprintbuf);
  139. return FALSE;
  140. }
  141. if (*dblist == NULL) /* empty list of dblks */
  142. goto BAD_INPUT;
  143. if (debugging) {
  144. fprintf (aa_stderr, PROGNAME "96 Current list of dblks:\n");
  145. for (db = *dblist; db != NULL; db = db->link) {
  146. targptr = sprintbuf;
  147. for (i = 0; i < db->ktcount; i++) {
  148. *targptr++ = db->keytypes[i].ktchar;
  149. }
  150. *targptr = 0;
  151. fprintf (aa_stderr, "--> DBLK at %p link=%p name='%s' maxhits=%d\n"
  152. " keytypes='%s', path='%s'\n",
  153. (void *) db, (void *) db->link, db->name, db->maxhits,
  154. sprintbuf, NULLORSTR (db->path));
  155. }
  156. }
  157. /* By doing setpages first, we can trap previously opened databases.
  158. * Overflow and transaction locking files are not required.
  159. */
  160. d_setpages (numpages, 0);
  161. if (db_status != S_OKAY) {
  162. DtSearchAddMessage (vista_msg (PROGNAME "389"));
  163. return FALSE;
  164. }
  165. /* ---- PASS #1 ------------------------------------------
  166. * Open nonvista (d99) files. If error, unlink dblk from dblist.
  167. * Add up the total string length of surviving paths and database names.
  168. * This giant path/file string will be used in the single d_open()
  169. * below to find the .dbd files.
  170. * While we're at it, set vistano in each dblk.
  171. * The open mode depends on the current setting of db_oflag.
  172. */
  173. if (db_oflag == O_RDONLY)
  174. strcpy (open_mode, "rb");
  175. else
  176. strcpy (open_mode, "r+b");
  177. db = *dblist;
  178. lastlink = dblist;
  179. while (db != NULL) {
  180. if (db->path == NULL)
  181. db->path = strdup ("");
  182. strcpy (temp_file_name, db->path);
  183. strcat (temp_file_name, db->name);
  184. strcat (temp_file_name, EXT_DTBS);
  185. if ((db->iifile = fopen (temp_file_name, open_mode)) == NULL) {
  186. if (debugging)
  187. fprintf (aa_stderr, PROGNAME "129 UNLINK: cant open '%s'.\n",
  188. temp_file_name);
  189. sprintf (sprintbuf, CATGETS(dtsearch_catd, MS_oeinit, 317,
  190. "%s Cannot open database file '%s'.\n"
  191. " Errno %d = %s\n"
  192. " %s is removing '%s' from list of available databases."),
  193. PROGNAME "317", temp_file_name, errno, strerror (errno),
  194. OE_prodname, db->name);
  195. if (errno == ENOENT)
  196. strcat (sprintbuf, CATGETS(dtsearch_catd, MS_oeinit, 318,
  197. "\n This can usually be corrected by specifying a valid\n"
  198. " database PATH in the site configuration file."));
  199. DtSearchAddMessage (sprintbuf);
  200. goto DELETE_DB;
  201. }
  202. /*
  203. * Find and save the timestamp for when the d99 file was
  204. * last modified. An engine reinit is forced if it changes
  205. * while the engine is running.
  206. */
  207. if (fstat (fileno (db->iifile), &statbuf) == -1) {
  208. if (debugging)
  209. fprintf (aa_stderr,
  210. PROGNAME "149 UNLINK: cant get status '%s'.\n",
  211. temp_file_name);
  212. sprintf (sprintbuf, CATGETS(dtsearch_catd, MS_oeinit, 1404,
  213. "%s Removing database '%s' from list of "
  214. "available databases because status is "
  215. "unavailable for file %s: %s"),
  216. PROGNAME "1404", db->name, temp_file_name, strerror (errno));
  217. DtSearchAddMessage (sprintbuf);
  218. goto DELETE_DB;
  219. }
  220. db->iimtime = statbuf.st_mtime;
  221. /*
  222. * This dblk is ok so far. Increment pointers and
  223. * continue.
  224. */
  225. if (debugging)
  226. fprintf (aa_stderr, PROGNAME "163 opened '%s'.\n", temp_file_name);
  227. db->vistano = vistano++;
  228. totlen += strlen (db->path) + strlen (db->name) + 16;
  229. lastlink = &db->link;
  230. db = db->link;
  231. continue;
  232. DELETE_DB:
  233. /*
  234. * This dblk failed in one or more ways. Unlink it and
  235. * don't increment pointers. If all dblks unlinked, *dblist
  236. * will = NULL.
  237. */
  238. bad_db = db; /* temp save */
  239. *lastlink = db->link;
  240. db = db->link;
  241. free (bad_db);
  242. } /* end PASS #1 */
  243. /* quit if no dblks remain */
  244. if (vistano <= 0) {
  245. sprintf (sprintbuf, CATGETS(dtsearch_catd, MS_misc, 8,
  246. "%s No valid databases remain."), PROGNAME "265");
  247. DtSearchAddMessage (sprintbuf);
  248. return FALSE;
  249. }
  250. allnames = austext_malloc (totlen + 512, PROGNAME "66", NULL);
  251. /* ---- PASS #2 ------------------------------------------
  252. * Build string of accumulated path and database names.
  253. */
  254. targptr = allnames;
  255. for (db = *dblist; db != NULL; db = db->link) {
  256. srcptr = db->path;
  257. while (*srcptr != 0)
  258. *targptr++ = *srcptr++;
  259. srcptr = db->name;
  260. while (*srcptr != 0)
  261. *targptr++ = *srcptr++;
  262. *targptr++ = ';';
  263. }
  264. *(--targptr) = 0; /* terminate string */
  265. if (debugging)
  266. fprintf (aa_stderr,
  267. PROGNAME "150 vista opening databases '%s'\n", allnames);
  268. d_open (allnames, "o"); /* replaces OPEN() call from dmacros.h */
  269. if (db_status != S_OKAY) {
  270. targptr = austext_malloc (totlen + 128, PROGNAME"239", NULL);
  271. sprintf (targptr, CATGETS(dtsearch_catd, MS_vista, 378,
  272. "%s Could not open following database name string:\n '%s'"),
  273. PROGNAME"378", allnames);
  274. DtSearchAddMessage (targptr);
  275. DtSearchAddMessage (vista_msg (PROGNAME"379"));
  276. free (allnames);
  277. free (targptr);
  278. return FALSE;
  279. }
  280. else if (debugging)
  281. fprintf (aa_stderr, " --> vista open successful!\n");
  282. /* From here on, emergency exits MUST close the databases */
  283. austext_exit_dbms = (void (*) (int)) d_close;
  284. free (allnames);
  285. return TRUE;
  286. } /* open_dblk() */
  287. /*********************** OPENDBLK.C ************************/