]> andersk Git - moira.git/blob - update/update_server.c
close child connections in parent process
[moira.git] / update / update_server.c
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
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17
18 #include <errno.h>
19 #include <pwd.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include <des.h>
26 #include "update.h"
27
28 RCSID("$Header$");
29
30 char *whoami, *hostname;
31
32 int have_authorization = 0;
33 des_cblock session;
34 int uid = 0;
35
36 struct _dt {
37   char *str;
38   void (*proc)(int, char *);
39 } dispatch_table[] = {
40   { "AUTH_002", auth_002 },
41   { "XFER_002", xfer_002 },
42   { "XFER_003", xfer_003 },
43   { "EXEC_002", exec_002 },
44   { "quit", quit },
45   { NULL, (void (*)(int, char *))abort }
46 };
47
48 int main(int argc, char **argv)
49 {
50   char *str, *p;
51   size_t len;
52   struct _dt *d;
53   struct utsname name;
54   int s, conn;
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     }
75
76   uname(&name);
77   hostname = name.nodename;
78
79   umask(0022);
80   mr_init();
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);
92           exit(1);
93         }
94       uid = pw->pw_uid;
95     }
96
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       close(conn);
130     }
131
132   /* If the config file contains a line "chroot /dir/name", the
133    * daemon will run chrooted to that directory.
134    */
135   if ((p = config_lookup("chroot")))
136     {
137       if (chroot(p) < 0)
138         {
139           com_err(whoami, errno, "unable to chroot to %s", p);
140           exit(1);
141         }
142     }
143
144   com_err(whoami, 0, "got connection");
145
146   while (1)
147     {
148       char *cp, *str;
149       size_t len;
150       int code;
151
152       code = recv_string(conn, &str, &len);
153       if (code)
154         {
155           com_err(whoami, code, "receiving command");
156           close(conn);
157           exit(1);
158         }
159
160       cp = strchr(str, ' ');
161       if (cp)
162         *cp = '\0';
163       for (d = dispatch_table; d->str; d++)
164         {
165           if (!strcmp(d->str, str))
166             {
167               if (cp)
168                 *cp = ' ';
169               (d->proc)(conn, str);
170               goto ok;
171             }
172         }
173       com_err(whoami, 0, "unknown request received: %s", str);
174       code = send_int(conn, MR_UNKNOWN_PROC);
175       if (code)
176         com_err(whoami, code, "sending UNKNOWN_PROC");
177     ok:
178       free(str);
179     }
180 }
181
182 int send_ok(int conn)
183 {
184   return send_int(conn, 0);
185 }
186
187 /*
188  * quit request:
189  *
190  * syntax:
191  * >>> quit
192  * <<< (int)0
193  * any arguments are ignored
194  *
195  * function:
196  *      closes connection from MR
197  */
198
199 void quit(int conn, char *str)
200 {
201   send_ok(conn);
202   close(conn);
203   com_err(whoami, 0, "Closing connection.");
204   exit(0);
205 }
206
207 void fail(int conn, int err, char *msg)
208 {
209   com_err(whoami, err, msg);
210   close(conn);
211   exit(1);
212 }
This page took 0.054643 seconds and 5 git commands to generate.