Implement option to change UID (-u)
[yazpp-moved-to-github.git] / src / yaz-proxy-main.cpp
1 /*
2  * Copyright (c) 1998-2003, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-proxy-main.cpp,v 1.22 2003-10-23 11:45:08 adam Exp $
6  */
7
8 #include <signal.h>
9 #include <unistd.h>
10 #include <pwd.h>
11 #include <sys/types.h>
12
13 #include <yaz/log.h>
14 #include <yaz/options.h>
15
16 #include <yaz++/socket-manager.h>
17 #include <yaz++/pdu-assoc.h>
18 #include <yaz++/proxy.h>
19
20 void usage(char *prog)
21 {
22     fprintf (stderr, "%s: [-c config] [-a log] [-m num] [-v level] [-t target] [-i sec] "
23              "[-u uid] [-p pidfile] [-o optlevel] @:port\n", prog);
24     exit (1);
25 }
26
27 static char *pid_fname = 0;
28 static char *uid = 0;
29
30 int args(Yaz_Proxy *proxy, int argc, char **argv)
31 {
32     char *addr = 0;
33     char *arg;
34     char *prog = argv[0];
35     int ret;
36
37     while ((ret = options("o:a:t:v:c:u:i:m:l:T:p:U:", argv, argc, &arg)) != -2)
38     {
39         int err;
40         switch (ret)
41         {
42         case 0:
43             if (addr)
44             {
45                 usage(prog);
46                 return 1;
47             }
48             addr = arg;
49             break;
50         case 'c':
51             err = proxy->set_config(arg);
52             if (err == -2)
53             {
54                 fprintf(stderr, "Config file support not enabled (proxy not compiled with libxml2 support)\n");
55                 exit(1);
56             }
57             else if (err == -1)
58             {
59                 fprintf(stderr, "Bad or missing file %s\n", arg);
60                 exit(1);
61             }
62             break;
63         case 'a':
64             proxy->set_APDU_log(arg);
65             break;
66         case 't':
67             proxy->set_default_target(arg);
68             break;
69         case 'U':
70             proxy->set_proxy_authentication(arg);
71             break;
72         case 'o':
73             proxy->option("optimize", arg);
74             break;
75         case 'v':
76             yaz_log_init_level (yaz_log_mask_str(arg));
77             break;
78         case 'l':
79             yaz_log_init_file (arg);
80             break;
81         case 'm':
82             proxy->set_max_clients(atoi(arg));
83             break;
84         case 'i':
85             proxy->set_client_idletime(atoi(arg));
86             break;
87         case 'T':
88             proxy->set_target_idletime(atoi(arg));
89             break;
90         case 'p':
91             if (!pid_fname)
92                 pid_fname = xstrdup(arg);
93             break;
94         case 'u':
95             if (!uid)
96                 uid = xstrdup(arg);
97             break;
98         default:
99             usage(prog);
100             return 1;
101         }
102     }
103     if (addr)
104     {
105         if (proxy->server(addr))
106         {
107             yaz_log(LOG_FATAL|LOG_ERRNO, "listen %s", addr);
108             exit(1);
109         }
110     }
111     else
112     {
113         usage(prog);
114         return 1;
115     }
116     return 0;
117 }
118
119 static Yaz_Proxy *static_yaz_proxy = 0;
120 static void sighup_handler(int num)
121 {
122     if (static_yaz_proxy)
123         static_yaz_proxy->reconfig();
124 }
125
126 int main(int argc, char **argv)
127 {
128     static int mk_pid = 0;
129     Yaz_SocketManager mySocketManager;
130     Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager));
131
132     static_yaz_proxy = &proxy;
133
134     signal(SIGHUP, sighup_handler);
135
136     args(&proxy, argc, argv);
137
138     if (pid_fname)
139     {
140         FILE *f = fopen(pid_fname, "w");
141         if (!f)
142         {
143             yaz_log(LOG_ERRNO|LOG_FATAL, "Couldn't create %s", pid_fname);
144             exit(0);
145         }
146         fprintf(f, "%ld", (long) getpid());
147         fclose(f);
148         xfree(pid_fname);
149     }
150     if (uid)
151     {
152         struct passwd *pw;
153         
154         if (!(pw = getpwnam(uid)))
155         {
156             yaz_log(LOG_FATAL, "%s: Unknown user", uid);
157             exit(3);
158         }
159         if (setuid(pw->pw_uid) < 0)
160         {
161             yaz_log(LOG_FATAL|LOG_ERRNO, "setuid");
162             exit(4);
163         }
164         xfree(uid);
165     }
166
167     while (mySocketManager.processEvent() > 0)
168         ;
169
170     exit (0);
171     return 0;
172 }