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