Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / DtSearch / dtoeinit.c
1 /*
2  *   COMPONENT_NAME: austext
3  *
4  *   FUNCTIONS: UNMALLOC
5  *              dump_dblk
6  *              oe_initialize
7  *              oe_uninitialize
8  *
9  *   ORIGINS: 27
10  *
11  *
12  *   (C) COPYRIGHT International Business Machines Corp. 1991,1995
13  *   All Rights Reserved
14  *   Licensed Materials - Property of IBM
15  *   US Government Users Restricted Rights - Use, duplication or
16  *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
17  */
18 /******************************* DTOEINIT.C ********************************
19  * $XConsortium: dtoeinit.c /main/6 1996/11/21 19:49:29 drk $
20  * Sept 1991.
21  * Contains oe_initialize() function from universal "Opera Engine" code.
22  * Has been separated out because it is the largest function and
23  * needs to be tested separately.
24  *
25  * $Log$
26  * Revision 2.4  1996/03/13  22:52:04  miker
27  * Enabled several language loading debug requests from API.
28  *
29  * Revision 2.3  1995/10/25  21:59:27  miker
30  * Renamed from oeinit.c.  Added prolog.
31  *
32  * Log: oeinit.c,v
33  * Revision 2.2  1995/10/02  20:39:22  miker
34  * Added zbflags arg to load_semantic().
35  *
36  * Revision 2.1  1995/09/22  21:38:53  miker
37  * Freeze DtSearch 0.1, AusText 2.1.8
38  *
39  * Revision 1.14  1995/09/05  18:58:01  miker
40  * Changed all socblk refs to universal, global usrblk (no more merges).
41  * Deleted numerous globals.  Added DTSEARCH define.
42  * Conflated all msglists to one ausapi_msglist.  All for DtSearch...
43  */
44 #include "SearchE.h"
45 #include <string.h>
46 #include <sys/stat.h>
47
48 #define XOS_USE_NO_LOCKING
49 #define X_INCLUDE_TIME_H
50 #include <X11/Xos_r.h>
51
52 #define PROGNAME        "DTOEINIT"
53 #define MS_misc         1
54 #define MS_oeinit       9
55
56 extern int      debugging_loadlang;
57
58 /************************************************/
59 /*                                              */
60 /*                   UNMALLOC                   */
61 /*                                              */
62 /************************************************/
63 /* macro to test and free any malloc'ed pointer */
64 #define UNMALLOC(ptr)  if(ptr){free(ptr);ptr=NULL;}
65
66
67 /********************************/
68 /*                              */
69 /*         dump_dblk            */
70 /*                              */
71 /********************************/
72 /* Dumps values from passed dblk.
73  * Used only for debugging initialization.
74  */
75 static void     dump_dblk (char *msgprefix, DBLK *d)
76 {
77     int         i;
78     fprintf (aa_stderr, "%s: DBLK v#%d name='%s' label='%s', path='%s'\n",
79         NULLORSTR (msgprefix), d->vistano, NULLORSTR (d->name),
80         NULLORSTR (d->label), NULLORSTR (d->path));
81     fprintf (aa_stderr, " mx=%d kt=", d->maxhits);
82     for (i = 0; i < d->ktcount; i++) {
83         fputc (' ', aa_stderr);
84         if (d->keytypes[i].is_selected)
85             fputc ('*', aa_stderr);
86         fputc (d->keytypes[i].ktchar, aa_stderr);
87     }
88     fputc ('\n', aa_stderr);
89     return;
90 }  /* dump_dblk() */
91
92
93 /************************************************/
94 /*                                              */
95 /*                oe_initialize                 */
96 /*                                              */
97 /************************************************/
98 /* - verify version number compatibilities.
99  * - initialize socblk and OE_... globals.
100  * - load site defaults ocf file and create database list.
101  * - load dictionaries.
102  * - merge site defaults into usrblk.
103  * - open database(s).
104  */
105 void            oe_initialize (void)
106 {
107     char        *ptr;
108     int         good_dblk_count = 0;
109     DBLK        *db, *bad_db, **lastlink;
110     char        sprintbuf[1024];
111     FILE        *stream;
112     OEFTAB      *oef;
113
114     if (usrblk.debug & USRDBG_RARE)
115         fprintf (aa_stderr, PROGNAME "555  Entered Engine Initialization.\n");
116     debugging_loadlang = (usrblk.debug & USRDBG_RARE);
117
118     /* Initialize most of the engine's globals.
119      * OE_bit_vector_size is set in ve_initialize().
120      * OE_bmhtab... are set by boyer-moore string searches only.
121      * OE_prodname is initialized by compiler and maybe changed by main().
122      * OE_expiration is initialized by compiler and never reset.
123      * OE_sitecnfg_fname is initialized by ausapi or loadocf and never reset.
124      * OE_sitecnfg_mtime is initialized by oe_initialize() and never reset.
125      */
126     global_memory_ptr =         NULL;
127     austext_exit_mem =          (void (*) (int)) release_shm_mem;
128
129     OE_flags =                  0L;
130     OE_objsize =                0L;
131     OE_search_type =            'P';    /* default is statistical searches */
132     OE_words_hitlimit =         WORDS_HITLIMIT;
133     OE_enable_markdel =         FALSE;  /* former lvl2 default: TRUE */
134     OE_enable_usernotes =       FALSE;  /* former lvl2 default: TRUE */
135     OE_fastdecode =             FALSE;  /* former lvl2 default: TRUE */
136     OE_fileio =                 "-OFF"; /* former lvl2 default: "-ON" */
137     OE_uppercase_keys =         FALSE;  /* former lvl2 default: TRUE */
138
139     OEF_audit =                 FNAME_AUDIT;
140     OEF_discard =               FNAME_DISCARD_DATA;
141     OEF_news =                  FNAME_SITENEWS;
142     OEF_notesnot =              FNAME_NOTES_BAC;
143     OEF_notessem =              FNAME_NOTES_SEM;
144     OEF_readme =                FNAME_README;
145
146     for (oef = oef_table; oef->id != NULL; oef++)
147         oef->previously_specified = FALSE;
148
149
150     /* Verify version number compatibility between engine and UI.
151      * Only checked if request is OE_INITIALIZE, not on reinits.
152      */
153     if (usrblk.request == OE_INITIALIZE) {
154         if (!is_compatible_version (usrblk.query, SCHEMA_VERSION) ||
155             !is_compatible_version (usrblk.query, PROTOCOL_VERSION)) {
156             if (usrblk.query != NULL)
157                 ptr = usrblk.query;
158             else
159                 ptr = catgets (dtsearch_catd, MS_misc, 6, "<unknown>");
160             sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 137,
161                     "%s User Interface version %s and Engine "
162                     "version %s are incompatible."),
163                 PROGNAME"137", ptr, AUSAPI_VERSION);
164             DtSearchAddMessage (sprintbuf);
165             usrblk.retncode = OE_NOTAVAIL;
166             return;
167         }
168     }
169
170     /* Load site configuration (ocf) file and create dblks list */
171     if (!load_ocf()) {
172         sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 202,
173             "%s Initialization failed due to errors in configuration file."),
174             PROGNAME"202");
175         DtSearchAddMessage (sprintbuf);
176         usrblk.retncode = OE_NOTAVAIL;
177         return;
178     }
179
180     /* Had to wait to write audit file till after site config set the flags */
181     if (OE_flags & OE_AUDIT || usrblk.debug & USRDBG_RARE) {
182         sprintf (sprintbuf,
183             "ENGINEINIT='%s' UVER='%s' " AUDIT_WHOWHEN "\n",
184             AUSAPI_VERSION, usrblk.query, usrblk.userid,
185             nowstring (NULL));
186         if (usrblk.debug & USRDBG_RARE)
187             fprintf (aa_stderr, PROGNAME "362 %s", sprintbuf);
188         if (OE_flags & OE_AUDIT) {
189             if ((stream = fopen (OEF_audit, "a ")) != NULL)
190                 /* the blank in "a " works around old aix bug */
191             {
192                 fputs (sprintbuf, stream);
193                 fclose (stream);
194             }
195         }
196     }   /* endif to write to audit file */
197
198
199     /* ---- DATABASES PASSES #1 - #3 ------------------------------------
200      * Call vista to open databases and load system (dbrec) records.
201      * Where possible, this call will forgive errors by just
202      * unlinking the offending dblk from the dblist.
203      * However loss of all dblks equals a fatal error.
204      */
205     if (!ve_initialize()) {
206 INIT_FAILED:
207         sprintf (sprintbuf, catgets (dtsearch_catd, MS_oeinit, 266,
208                 "%s Initialization failed due to errors in database,\n"
209                 "  language, or related files."),
210             PROGNAME "266");
211         DtSearchAddMessage (sprintbuf);
212         usrblk.retncode = OE_NOTAVAIL;
213         return;
214     }
215
216     /* ---- DATABASES PASS #4 ------------------------------------
217      * Load each database's language and semantic files.
218      * If an error is discovered in any one dblk,
219      * it is unlinked from dblist.
220      * However loss of all dblks on dblist is fatal.
221      */
222     good_dblk_count = 0;
223     db = usrblk.dblist; /* could already = NULL after ve_initialize() */
224     lastlink = &usrblk.dblist;
225     while (db != NULL) {
226         if (!load_language (db, usrblk.dblist))
227             goto DELETE_DB;
228         /*
229          * This dblk successfully loaded its language and and semantic
230          * files.  If no gui label was provided, set it to the
231          * database name.  Then increment pointers and continue. 
232          */
233         if (db->label == NULL)
234             db->label = strdup (db->name);
235         else if (db->label[0] == 0)
236             db->label = strdup (db->name);
237
238         good_dblk_count++;
239         lastlink = &db->link;
240         db = db->link;
241         continue;
242
243 DELETE_DB:
244         /*
245          * One or more language or semantic files could not be loaded for
246          * this dblk.  Unlink it and don't increment pointers. 
247          */
248         bad_db = db;    /* temp save */
249         *lastlink = db->link;
250         db = db->link;
251         free (bad_db);
252     }   /* end loop that loads all database files */
253
254     /* Abort if fatal dictionary load errors */
255     if (good_dblk_count <= 0) {
256         sprintf (sprintbuf, catgets (dtsearch_catd, MS_misc, 8,
257             "%s No valid databases remain."),
258             PROGNAME"265");
259         DtSearchAddMessage (sprintbuf);
260         goto INIT_FAILED;
261     }
262
263     memset (&saveusr, 0, sizeof (SAVEUSR));
264
265     OE_flags |= OE_INITOK;
266     if (usrblk.debug & USRDBG_RARE) {
267         struct tm       *time_ptr;
268         _Xltimeparams   localtime_buf;
269
270         if (*OE_expiration != 0)
271           {
272             time_ptr = _XLocaltime(OE_expiration, localtime_buf);
273             strftime (sprintbuf, 100, "%x", time_ptr);
274           }
275         else
276             strcpy (sprintbuf, "0");
277         if (OE_sitecnfg_mtime != 0)
278           {
279             time_ptr = _XLocaltime(&OE_sitecnfg_mtime, localtime_buf);
280             strftime (sprintbuf + 100, 100, "%x,%X", time_ptr);
281           }
282         else
283             strcpy (sprintbuf + 100, "0");
284         fprintf (aa_stderr, PROGNAME "666  Engine Initialization Completed.\n"
285             "  usrblk.flags=%ld(x%04lx), usrblk.debug=%ld(x%04lx).\n"
286             "  OE_flags=%ld(x%04lx), expiration=%s, sitecnfg=%s.\n"
287             ,usrblk.flags, usrblk.flags, usrblk.debug, usrblk.debug
288             ,OE_flags, OE_flags, sprintbuf, sprintbuf + 100
289             );
290     }
291
292     usrblk.retncode = OE_OK;
293     return;
294 }  /* oe_initialize() */
295
296
297 /************************************************/
298 /*                                              */
299 /*                oe_uninitialize               */
300 /*                                              */
301 /************************************************/
302 /* Called by Opera_Engine() whenever the site config file
303  * has been altered.  Closes databases, frees all allocated storage,
304  * and resets everything so oe_initialize() can be re-called. 
305  * Allows administrator to swap to newer, updated databases
306  * without forcing users to shutdown by changing PATH value
307  * in site config file.
308  */
309 void            oe_uninitialize (void)
310 {
311     DBLK           *db, *nextdb;
312     OEFTAB         *oef;
313
314     ve_shutdown ();     /* close all databases */
315     UNMALLOC (usrblk.abstrbuf);
316
317     /* release shared memory, suffixes array, etc, if any */
318     release_shm_mem ();
319
320     /* Free allocated storage in oef table and reset the default filenames. */
321     for (oef = oef_table; oef->id != NULL; oef++) {
322         if (oef->previously_specified) {
323             oef->previously_specified = FALSE;
324             free (*(oef->OEFptr));
325         }
326     }
327
328     db = usrblk.dblist;
329     while (db != NULL) {
330
331         /* Save next dblk so we'll know where to go after freeing this one */
332         nextdb = db->link;
333
334         UNMALLOC (db->path);
335         UNMALLOC (db->keytypes);
336
337         if (db->iifile != NULL) {
338             fclose (db->iifile);
339             db->iifile = NULL;
340         }
341         if (db->syofile != NULL) {
342             fclose (db->syofile);
343             db->syofile = NULL;
344         }
345         if (db->syifile != NULL) {
346             fclose (db->syifile);
347             db->syifile = NULL;
348         }
349
350         unload_language (db);
351
352         free (db);
353         db = nextdb;
354     }
355     usrblk.dblist = NULL;
356     usrblk.dblk = NULL;
357     return;
358 }  /* oe_uninitialize() */
359
360 /******************************* DTOEINIT.C ********************************/