]> andersk Git - moira.git/blame - update/update_server.c
First cut at support for winhomedir and winprofiledir support.
[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>
9d3d51ad 26#include <syslog.h>
de56407f 27
7ac48069 28#include <des.h>
7ac48069 29#include "update.h"
de56407f 30
7ac48069 31RCSID("$Header$");
de56407f 32
85330553 33char *whoami, *hostname;
de56407f 34
45c91bf7 35int have_authorization = 0;
85330553 36des_cblock session;
529a5b0d 37int uid = 0;
45c91bf7 38
cf0ec460 39void child_handler(int signal);
9d3d51ad 40static void syslog_com_err_proc(const char *progname, long code,
41 const char *fmt, va_list args);
cf0ec460 42
de56407f 43struct _dt {
5eaef520 44 char *str;
85330553 45 void (*proc)(int, char *);
de56407f 46} dispatch_table[] = {
5eaef520 47 { "AUTH_002", auth_002 },
48 { "XFER_002", xfer_002 },
49 { "XFER_003", xfer_003 },
50 { "EXEC_002", exec_002 },
51 { "quit", quit },
85330553 52 { NULL, (void (*)(int, char *))abort }
de56407f 53};
54
5eaef520 55int main(int argc, char **argv)
de56407f 56{
85330553 57 char *str, *p;
58 size_t len;
5eaef520 59 struct _dt *d;
85330553 60 struct utsname name;
61 int s, conn;
cf0ec460 62 struct sigaction sa;
5eaef520 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 }
5eaef520 83
85330553 84 uname(&name);
85 hostname = name.nodename;
5eaef520 86
85330553 87 umask(0022);
88 mr_init();
5eaef520 89
cf0ec460 90 sigemptyset(&sa.sa_mask);
91 sa.sa_flags = SA_RESTART;
92 sa.sa_handler = child_handler;
93 sigaction(SIGCHLD, &sa, NULL);
94
5eaef520 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);
de56407f 105 exit(1);
5eaef520 106 }
107 uid = pw->pw_uid;
108 }
de56407f 109
85330553 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
9d3d51ad 123 set_com_err_hook(syslog_com_err_proc);
124 openlog(whoami, LOG_PID, LOG_DAEMON);
125
85330553 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;
bcb7d888 144
145 close(conn);
85330553 146 }
147
5eaef520 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 }
45c91bf7 159
85330553 160 com_err(whoami, 0, "got connection");
5eaef520 161
5eaef520 162 while (1)
163 {
85330553 164 char *cp, *str;
165 size_t len;
166 int code;
167
168 code = recv_string(conn, &str, &len);
5eaef520 169 if (code)
170 {
85330553 171 com_err(whoami, code, "receiving command");
172 close(conn);
5eaef520 173 exit(1);
174 }
85330553 175
176 cp = strchr(str, ' ');
5eaef520 177 if (cp)
178 *cp = '\0';
179 for (d = dispatch_table; d->str; d++)
180 {
85330553 181 if (!strcmp(d->str, str))
5eaef520 182 {
183 if (cp)
184 *cp = ' ';
85330553 185 (d->proc)(conn, str);
5eaef520 186 goto ok;
187 }
188 }
85330553 189 com_err(whoami, 0, "unknown request received: %s", str);
190 code = send_int(conn, MR_UNKNOWN_PROC);
5eaef520 191 if (code)
85330553 192 com_err(whoami, code, "sending UNKNOWN_PROC");
5eaef520 193 ok:
85330553 194 free(str);
5eaef520 195 }
de56407f 196}
197
85330553 198int send_ok(int conn)
45c91bf7 199{
85330553 200 return send_int(conn, 0);
45c91bf7 201}
202
45c91bf7 203/*
204 * quit request:
205 *
206 * syntax:
207 * >>> quit
208 * <<< (int)0
209 * any arguments are ignored
210 *
211 * function:
2ad0a777 212 * closes connection from MR
45c91bf7 213 */
85330553 214
215void quit(int conn, char *str)
45c91bf7 216{
85330553 217 send_ok(conn);
218 close(conn);
219 com_err(whoami, 0, "Closing connection.");
5eaef520 220 exit(0);
45c91bf7 221}
222
85330553 223void fail(int conn, int err, char *msg)
45c91bf7 224{
85330553 225 com_err(whoami, err, msg);
226 close(conn);
5eaef520 227 exit(1);
45c91bf7 228}
cf0ec460 229
230void child_handler(int signal)
231{
232 int status;
233
234 while (waitpid(-1, &status, WNOHANG) > 0)
235 ;
236}
9d3d51ad 237
238static void syslog_com_err_proc(const char *progname, long code,
239 const char *fmt, va_list args)
240{
995c29c0 241 char buf[BUFSIZ + 1];
9d3d51ad 242
995c29c0 243 buf[BUFSIZ] = '\0';
9d3d51ad 244
995c29c0 245 vsnprintf(buf, BUFSIZ, fmt, args);
246 syslog(LOG_NOTICE, "%s: %s %s", progname, error_message(code), buf);
9d3d51ad 247}
This page took 0.136781 seconds and 5 git commands to generate.