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