Minor changes.
[egate.git] / kernel / main.c
1 /* Gateway kernel
2  * Europagate, 1995
3  *
4  * main.c,v
5  * Revision 1.7  1995/02/22  15:22:33  adam
6  * Much more checking of run-time state. Show command never retrieves
7  * more records than indicated by the previous search request. Help
8  * command available. The maximum number of records retrieved can be
9  * controlled now.
10  *
11  * Revision 1.6  1995/02/22  08:51:34  adam
12  * Output function can be customized in fml, which is used to print
13  * the reply to reply_fd.
14  *
15  * Revision 1.5  1995/02/20  21:16:20  adam
16  * FML support. Bug fixes. Profile for drewdb.
17  *
18  * Revision 1.4  1995/02/17  17:06:16  adam
19  * Minor changes.
20  *
21  * Revision 1.3  1995/02/16  18:35:09  adam
22  * First use of Zdist library. Search requests are supported.
23  * Present requests are not supported yet.
24  *
25  * Revision 1.2  1995/02/16  13:21:00  adam
26  * Organization of resource files for targets and conversion
27  * language implemented.
28  *
29  * Revision 1.1  1995/02/15  17:45:29  adam
30  * First version of email gateway kernel. Email requests are read
31  * from stdin. The output is transferred to an MTA if 'From' is
32  * found in the header - or stdout if absent. No Z39.50 client is used.
33  *
34  */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40
41 #include "kernel.h"
42
43 FILE *reply_fd = stdout;
44
45 struct gw_kernel_info info;
46
47 int main (int argc, char **argv)
48 {
49     info.kernel_res = NULL;
50     info.default_res = "default.res";
51     info.override_res = NULL;
52     *info.target = 0;
53     info.lang = NULL;
54     info.bibset = NULL;
55     info.zass = NULL;
56     info.override_portno = NULL;
57     info.override_hostname = NULL;
58     info.databases = NULL;
59 #if USE_FML
60     info.fml = NULL;
61 #endif
62     info.sets = NULL;
63
64     gw_log_init (*argv);
65     info.kernel_res = gw_res_init ();
66     while (--argc > 0)
67     {
68         if (**++argv == '-')
69         {
70             switch (argv[0][1])
71             {
72             case 'd':
73                 gw_log_level (GW_LOG_ALL);
74                 break;
75             case 't':
76                 if (argv[0][2])
77                     strcpy (info.target, argv[0]+2);
78                 else if (argc > 0)
79                 {
80                     --argc;
81                     strcpy (info.target, *++argv);
82                 }
83                 else
84                 {
85                     gw_log (GW_LOG_FATAL, "main", "missing target name");
86                     exit (1);
87                 }
88                 break;
89             case 'l':
90                 if (argv[0][2])
91                     info.lang = argv[0]+2;
92                 else if (argc > 0)
93                 {
94                     --argc;
95                     info.lang = *++argv;
96                 }
97                 else
98                 {
99                     gw_log (GW_LOG_FATAL, "main", "missing language name");
100                     exit (1);
101                 }
102                 break;
103             case 'o':
104                 if (argv[0][2])
105                     info.override_res = argv[0]+2;
106                 else if (argc > 0)
107                 {
108                     --argc;
109                     info.override_res = *++argv;
110                 }
111                 else
112                 {
113                     gw_log (GW_LOG_FATAL, "main", "missing language name");
114                     exit (1);
115                 }
116                 break;
117             case 'p':
118                 if (argv[0][2])
119                     info.override_portno = argv[0]+2;
120                 else if (argc > 0)
121                 {
122                     --argc;
123                     info.override_portno = *++argv;
124                 }
125                 else
126                 {
127                     gw_log (GW_LOG_FATAL, "main", "missing portno");
128                     exit (1);
129                 }
130                 break;
131             case 'h':
132                 if (argv[0][2])
133                     info.override_hostname = argv[0]+2;
134                 else if (argc > 0)
135                 {
136                     --argc;
137                     info.override_hostname = *++argv;
138                 }
139                 else
140                 {
141                     gw_log (GW_LOG_FATAL, "main", "missing hostname");
142                     exit (1);
143                 }
144                 break;
145             case 'g':
146                 if (argv[0][2])
147                     gw_log_file (GW_LOG_ALL, argv[0]+2);
148                 else if (argc > 0)
149                 {
150                     --argc;
151                     gw_log_file (GW_LOG_ALL, *++argv);
152                 }
153                 else
154                 {
155                     gw_log (GW_LOG_FATAL, "main", "missing log filename");
156                     exit (1);
157                 }
158                 break;
159             default:
160                 gw_log (GW_LOG_FATAL, "main", "unknown option %s", *argv);
161                 exit (1);
162             }
163         }
164         else
165             info.default_res = *argv;
166     }
167     read_kernel_res ();
168     urp (stdin);
169     return 0;
170 }
171
172 struct gw_user_set *user_set_add (const char *name, int hits)
173 {
174     struct gw_user_set *s;
175
176     s = malloc (sizeof (*s));
177     assert (s);
178
179     s->name = gw_strdup (name);
180     s->hits = hits;
181     s->prev = info.sets;
182     info.sets = s;
183     return s;
184 }
185
186 void user_set_init (void)
187 {
188     struct gw_user_set *s, *s1;
189
190     for (s = info.sets; s; s = s1)
191     {
192         free (s->name);
193         s1 = s->prev;
194         free (s);
195     }
196     info.sets = NULL;
197 }
198
199 struct gw_user_set *user_set_search (const char *name)
200 {
201     struct gw_user_set *s;
202
203     if (!name)
204         return info.sets;
205     for (s = info.sets; s; s = s->prev)
206         if (!strcmp (s->name, name))
207             return s;
208     return NULL;
209 }
210
211 #if USE_FML
212 static void fml_inf_write (int ch)
213 {
214     putc (ch, reply_fd);
215 }
216 static FILE *fml_inf;
217
218 static int fml_inf_read (void)
219 {
220     return getc (fml_inf);
221 }
222 #endif
223
224 void read_kernel_res (void)
225 {
226     char path_prefix[128];
227     char fname[160];
228     const char *v;
229     char *cp;
230     char resource_name[256];
231
232     user_set_init ();
233
234     if (info.bibset)
235         ccl_qual_rm (&info.bibset);
236     info.bibset = ccl_qual_mk ();
237
238     if (info.kernel_res)
239         gw_res_close (info.kernel_res);
240     info.kernel_res = gw_res_init ();
241
242     gw_log (GW_LOG_DEBUG, "main", "reading kernel resource, default %s",
243             info.default_res);
244     if (*info.target)
245         gw_log (GW_LOG_DEBUG, "main", "reading kernel resource, target %s",
246                 info.target);
247     if (info.lang)
248         gw_log (GW_LOG_DEBUG, "main", "reading kernel resource, lang %s",
249                 info.lang);
250
251     if (gw_res_merge (info.kernel_res, info.default_res))
252     {
253         gw_log (GW_LOG_WARN, "main", "Couldn't read resource file %s",
254                 info.default_res);
255         return;
256     }
257     strcpy (path_prefix, gw_res_get (info.kernel_res, "gw.path", "."));
258     
259     if (*info.target)
260     {
261         sprintf (resource_name, "gw.target.%s", info.target);
262         v = gw_res_get (info.kernel_res, resource_name, NULL);
263         if (v)
264         {
265             sprintf (fname, "%s/%s", path_prefix, v);
266             gw_res_merge (info.kernel_res, fname);
267         }
268     }
269     if (info.lang)
270     {
271         sprintf (resource_name, "gw.lang.%s", info.lang);
272         v = gw_res_get (info.kernel_res, resource_name, NULL);
273         if (v)
274         {
275             sprintf (fname, "%s/%s", path_prefix, v);
276             gw_res_merge (info.kernel_res, fname);
277         }
278     }
279     if (info.override_res)
280     {
281         sprintf (fname, "%s/%s", path_prefix, info.override_res);
282         gw_res_merge (info.kernel_res, fname);        
283     }
284     v = gw_res_get (info.kernel_res, "gw.bibset", NULL);
285     if (v)
286     {
287         FILE *bib_inf;
288
289         sprintf (fname, "%s/%s", path_prefix, v);
290         bib_inf = fopen (fname, "r");
291         if (!bib_inf)
292             gw_log (GW_LOG_WARN, "main", "cannot open %s", fname);
293         else
294         {
295             gw_log (GW_LOG_DEBUG, "main", "reading bib file %s", fname);
296             ccl_qual_file (info.bibset, bib_inf);
297             fclose (bib_inf);
298         }
299     }
300     sprintf (resource_name, "gw.target.%s", info.target);
301     if (*info.target && ! gw_res_get (info.kernel_res, resource_name, NULL))
302     {
303         /* target is there, and there is no sub-resource for it... */
304         char *split;
305
306         if ((split = strchr (info.target, ':')))
307             *split++ = '\0';
308         strncpy (info.hostname, info.target, sizeof(info.hostname)-1);
309         if (split)
310             info.port = atoi (split);
311         else
312             info.port = atoi (gw_res_get
313                               (info.kernel_res, "gw.portno", "210"));
314     }
315     else
316     {
317         strncpy (info.hostname, gw_res_get (info.kernel_res,
318                                             "gw.hostname", "localhost"),
319                  sizeof(info.hostname)-1);
320         info.port = atoi (gw_res_get (info.kernel_res,
321                                       "gw.portno", "210"));
322     }
323     if (info.databases)
324         free (info.databases);
325     v = gw_res_get (info.kernel_res, "gw.databases", "");
326     info.databases = gw_strdup (v);
327     for (cp = info.databases; (cp = strchr (cp, ' ')); cp++)
328         *cp = ',';
329     if (info.override_portno)
330         info.port = atoi (info.override_portno);
331     if (info.override_hostname)
332         strncpy (info.hostname, info.override_hostname,
333                  sizeof(info.hostname)-1);
334 #if USE_FML
335     if (!info.fml)
336     {
337         v = gw_res_get (info.kernel_res, "gw.fml", "default.fml");    
338         sprintf (fname, "%s/%s", path_prefix, v);
339         fml_inf = fopen (fname, "r");
340         if (!fml_inf)
341             gw_log (GW_LOG_WARN, "main", "cannot open fml script %s", fname);
342         else
343         {
344             info.fml = fml_open ();
345             info.fml->read_func = fml_inf_read;
346             info.fml->write_func = fml_inf_write;
347             fml_preprocess (info.fml);
348             fml_exec (info.fml);
349             fclose (fml_inf);
350         }
351     }
352 #endif
353 }