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