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