2 * Copyright (c) 1998-2004, Index Data.
3 * See the file LICENSE for details.
5 * $Id: yaz-proxy-main.cpp,v 1.35 2004-03-17 10:49:58 adam Exp $
11 #include <sys/types.h>
16 #include <sys/resource.h>
20 #include <yaz/options.h>
22 #include <yaz++/socket-manager.h>
23 #include <yaz++/pdu-assoc.h>
24 #include <yaz++/proxy.h>
26 void usage(char *prog)
28 fprintf (stderr, "%s: [-c config] [-l log] [-a log] [-v level] [-t target] "
29 "[-u uid] [-p pidfile] @:port\n", prog);
33 static char *pid_fname = 0;
35 static char *log_file = 0;
37 static int no_limit_files = 0;
39 int args(Yaz_Proxy *proxy, int argc, char **argv)
46 while ((ret = options("o:a:t:v:c:u:i:m:l:T:p:U:n:X",
47 argv, argc, &arg)) != -2)
61 err = proxy->set_config(arg);
64 fprintf(stderr, "Config file support not enabled (proxy not compiled with libxml2 support)\n");
69 fprintf(stderr, "Bad or missing file %s\n", arg);
74 proxy->set_APDU_log(arg);
77 proxy->set_default_target(arg);
80 proxy->set_proxy_authentication(arg);
83 proxy->option("optimize", arg);
86 yaz_log_init_level (yaz_log_mask_str(arg));
89 yaz_log_init_file (arg);
90 log_file = xstrdup(arg);
93 proxy->set_max_clients(atoi(arg));
96 proxy->set_client_idletime(atoi(arg));
99 proxy->set_target_idletime(atoi(arg));
102 no_limit_files = atoi(arg);
109 pid_fname = xstrdup(arg);
122 if (proxy->server(addr))
124 yaz_log(LOG_FATAL|LOG_ERRNO, "listen %s", addr);
136 static Yaz_Proxy *static_yaz_proxy = 0;
137 static void sighup_handler(int num)
139 signal(SIGHUP, sighup_handler);
140 if (static_yaz_proxy)
141 static_yaz_proxy->reconfig();
145 static void proxy_xml_error_handler(void *ctx, const char *fmt, ...)
152 vsnprintf(buf, sizeof(buf), fmt, ap);
154 yaz_log(LOG_WARN, "%s: %s", (char*) ctx, buf);
160 static void child_run(Yaz_SocketManager *m, int run)
162 signal(SIGHUP, sighup_handler);
165 xmlSetGenericErrorFunc((void *) "XML", proxy_xml_error_handler);
166 xsltSetGenericErrorFunc((void *) "XSLT", proxy_xml_error_handler);
168 yaz_log(LOG_LOG, "0 proxy run=%d pid=%ld", run, (long) getpid());
173 struct rlimit limit_data;
174 limit_data.rlim_cur = no_limit_files;
175 limit_data.rlim_max = no_limit_files;
177 yaz_log(LOG_LOG, "0 setrlimit NOFILE cur=%d max=%d",
178 limit_data.rlim_cur, limit_data.rlim_max);
179 if (setrlimit(RLIMIT_NOFILE, &limit_data))
180 yaz_log(LOG_ERRNO|LOG_WARN, "setrlimit");
182 yaz_log(LOG_WARN, "setrlimit unavablable. Option -n ignored");
187 FILE *f = fopen(pid_fname, "w");
190 yaz_log(LOG_ERRNO|LOG_FATAL, "Couldn't create %s", pid_fname);
193 fprintf(f, "%ld", (long) getpid());
201 if (!(pw = getpwnam(uid)))
203 yaz_log(LOG_FATAL, "%s: Unknown user", uid);
208 chown(log_file, pw->pw_uid, pw->pw_gid);
211 if (setuid(pw->pw_uid) < 0)
213 yaz_log(LOG_FATAL|LOG_ERRNO, "setuid");
219 struct rlimit limit_data;
220 getrlimit(RLIMIT_NOFILE, &limit_data);
221 yaz_log(LOG_LOG, "0 getrlimit NOFILE cur=%d max=%d",
222 limit_data.rlim_cur, limit_data.rlim_max);
225 while (m->processEvent() > 0)
231 int main(int argc, char **argv)
240 Yaz_SocketManager mySocketManager;
241 Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager));
243 static_yaz_proxy = &proxy;
245 args(&proxy, argc, argv);
249 child_run(&mySocketManager, run);
257 yaz_log(LOG_FATAL|LOG_ERRNO, "fork");
262 child_run(&mySocketManager, run);
272 yaz_log(LOG_FATAL, "p1=%d != p=%d", p1, p);
275 if (WIFSIGNALED(status))
277 switch(WTERMSIG(status)) {
279 yaz_log(LOG_WARN, "Received SIGILL from child %ld", (long) p);
283 yaz_log(LOG_WARN, "Received SIGABRT from child %ld", (long) p);
287 yaz_log(LOG_WARN, "Received SIGSEGV from child %ld", (long) p);
291 yaz_log(LOG_WARN, "Received SIGBUS from child %ld", (long) p);
295 yaz_log(LOG_LOG, "Received SIGTERM from child %ld",
300 yaz_log(LOG_WARN, "Received SIG %d from child %ld",
301 WTERMSIG(status), (long) p);
305 else if (status == 0)
309 yaz_log(LOG_LOG, "Exit %d from child %ld", status, (long) p);