]> andersk Git - moira.git/blame_incremental - update/update_server.c
Make Moira Java Object thread safe (provide mutex locking of a sorts)
[moira.git] / update / update_server.c
... / ...
CommitLineData
1/* $Id$
2 *
3 * Copyright 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
5 * <mit-copyright.h>.
6 */
7
8#include <mit-copyright.h>
9#include <moira.h>
10#include "update_server.h"
11
12#include <sys/stat.h>
13#include <sys/utsname.h>
14#include <sys/wait.h>
15
16#include <netinet/in.h>
17#include <arpa/inet.h>
18
19#include <errno.h>
20#include <pwd.h>
21#include <signal.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <syslog.h>
27
28#include <des.h>
29#include "update.h"
30
31RCSID("$Header$");
32
33char *whoami, *hostname;
34
35int have_authorization = 0;
36des_cblock session;
37int uid = 0;
38
39void child_handler(int signal);
40static void syslog_com_err_proc(const char *progname, long code,
41 const char *fmt, va_list args);
42
43struct _dt {
44 char *str;
45 void (*proc)(int, char *);
46} dispatch_table[] = {
47 { "AUTH_002", auth_002 },
48 { "XFER_002", xfer_002 },
49 { "XFER_003", xfer_003 },
50 { "EXEC_002", exec_002 },
51 { "quit", quit },
52 { NULL, (void (*)(int, char *))abort }
53};
54
55int main(int argc, char **argv)
56{
57 char *str, *p;
58 size_t len;
59 struct _dt *d;
60 struct utsname name;
61 int s, conn;
62 struct sigaction sa;
63
64 whoami = strrchr(argv[0], '/');
65 if (whoami)
66 whoami++;
67 else
68 whoami = argv[0];
69
70 /* interpret arguments here */
71 if (argc != 1)
72 {
73 fprintf(stderr, "Usage: %s\n", whoami);
74 exit(1);
75 }
76
77 if (!config_lookup("nofork"))
78 {
79 if (fork())
80 exit(0);
81 setsid();
82 }
83
84 uname(&name);
85 hostname = name.nodename;
86
87 umask(0022);
88 mr_init();
89
90 sigemptyset(&sa.sa_mask);
91 sa.sa_flags = SA_RESTART;
92 sa.sa_handler = child_handler;
93 sigaction(SIGCHLD, &sa, NULL);
94
95 /* If the config file contains a line "user username", the
96 * daemon will run with that user's UID.
97 */
98 if ((p = config_lookup("user")))
99 {
100 struct passwd *pw;
101 pw = getpwnam(p);
102 if (!pw)
103 {
104 com_err(whoami, errno, "Unable to find user %s\n", p);
105 exit(1);
106 }
107 uid = pw->pw_uid;
108 }
109
110 /* If the config file contains a line "port portname", the daemon
111 * will listen on the named port rather than SERVICE_NAME ("moira_update")
112 */
113 if (!(p = config_lookup("port")))
114 p = SERVICE_NAME;
115
116 s = mr_listen(p);
117 if (s == -1)
118 {
119 com_err(whoami, errno, "creating listening socket");
120 exit(1);
121 }
122
123 set_com_err_hook(syslog_com_err_proc);
124 openlog(whoami, LOG_PID, LOG_DAEMON);
125
126 /* now loop waiting for connections */
127 while (1)
128 {
129 struct sockaddr_in client;
130 long len;
131 char *buf;
132
133 conn = mr_accept(s, &client);
134 if (conn == -1)
135 {
136 com_err(whoami, errno, "accepting on listening socket");
137 exit(1);
138 }
139 else if (conn == 0)
140 continue;
141
142 if (config_lookup("nofork") || (fork() <= 0))
143 break;
144
145 close(conn);
146 }
147
148 /* If the config file contains a line "chroot /dir/name", the
149 * daemon will run chrooted to that directory.
150 */
151 if ((p = config_lookup("chroot")))
152 {
153 if (chroot(p) < 0)
154 {
155 com_err(whoami, errno, "unable to chroot to %s", p);
156 exit(1);
157 }
158 }
159
160 com_err(whoami, 0, "got connection");
161
162 while (1)
163 {
164 char *cp, *str;
165 size_t len;
166 int code;
167
168 code = recv_string(conn, &str, &len);
169 if (code)
170 {
171 com_err(whoami, code, "receiving command");
172 close(conn);
173 exit(1);
174 }
175
176 cp = strchr(str, ' ');
177 if (cp)
178 *cp = '\0';
179 for (d = dispatch_table; d->str; d++)
180 {
181 if (!strcmp(d->str, str))
182 {
183 if (cp)
184 *cp = ' ';
185 (d->proc)(conn, str);
186 goto ok;
187 }
188 }
189 com_err(whoami, 0, "unknown request received: %s", str);
190 code = send_int(conn, MR_UNKNOWN_PROC);
191 if (code)
192 com_err(whoami, code, "sending UNKNOWN_PROC");
193 ok:
194 free(str);
195 }
196}
197
198int send_ok(int conn)
199{
200 return send_int(conn, 0);
201}
202
203/*
204 * quit request:
205 *
206 * syntax:
207 * >>> quit
208 * <<< (int)0
209 * any arguments are ignored
210 *
211 * function:
212 * closes connection from MR
213 */
214
215void quit(int conn, char *str)
216{
217 send_ok(conn);
218 close(conn);
219 com_err(whoami, 0, "Closing connection.");
220 exit(0);
221}
222
223void fail(int conn, int err, char *msg)
224{
225 com_err(whoami, err, msg);
226 close(conn);
227 exit(1);
228}
229
230void child_handler(int signal)
231{
232 int status;
233
234 while (waitpid(-1, &status, WNOHANG) > 0)
235 ;
236}
237
238static void syslog_com_err_proc(const char *progname, long code,
239 const char *fmt, va_list args)
240{
241 char *buf;
242 int bufsiz = 1024;
243
244 buf = malloc(bufsiz + 1);
245 buf[bufsiz] = '\0';
246
247 vsnprintf(buf, bufsiz, fmt, args);
248 syslog(LOG_NOTICE, "%s", buf);
249}
This page took 0.048409 seconds and 5 git commands to generate.