annotate dpid/main.c @ 0:6ee11bf9e3ea

Initial revision
author jcid
date Sun, 07 Oct 2007 00:36:34 +0200
parents
children ec671a7ea6e2
rev   line source
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
2 Copyright (C) 2003 Ferdi Franceschini <ferdif@optusnet.com.au>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
3
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
4 This program is free software; you can redistribute it and/or modify
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
7 (at your option) any later version.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
8
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
12 GNU General Public License for more details.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
13
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
15 along with this program; if not, write to the Free Software
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
17 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
18
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
19 #include <errno.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
20 #include <unistd.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
21 #include <limits.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
22 #include <sys/stat.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
23 #include <sys/time.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
24 #include <assert.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
25 #include "dpid_common.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
26 #include "dpid.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
27 #include "dpi.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
28 #include "dpi_socket_dir.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
29 #include "misc_new.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
30 #include "../dpip/dpip.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
31
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
32 sigset_t mask_sigchld;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
33
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
34
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
35 /* Start a dpi filter plugin after accepting the pending connection
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
36 * \Return
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
37 * \li Child process ID on success
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
38 * \li 0 on failure
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
39 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
40 static int start_filter_plugin(struct dp dpi_attr)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
41 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
42 int newsock, old_stdout=-1, old_stdin=-1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
43 socklen_t csz;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
44 struct sockaddr_un clnt_addr;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
45 pid_t pid;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
46
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
47 csz = (socklen_t) sizeof(clnt_addr);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
48
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
49 newsock = accept(dpi_attr.socket, (struct sockaddr *) &clnt_addr, &csz);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
50 if (newsock == -1)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
51 ERRMSG("start_plugin", "accept", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
52
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
53 dup2(STDIN_FILENO, old_stdin);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
54 if (dup2(newsock, STDIN_FILENO) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
55 ERRMSG("start_plugin", "dup2", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
56 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
57 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
58 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
59
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
60 dup2(STDOUT_FILENO, old_stdout);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
61 if (dup2(newsock, STDOUT_FILENO) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
62 ERRMSG("start_plugin", "dup2", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
63 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
64 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
65 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
66 if ((pid = fork()) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
67 ERRMSG("main", "fork", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
68 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
69 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
70 if (pid == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
71 /* Child, start plugin */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
72 if (execl(dpi_attr.path, dpi_attr.path, NULL) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
73 ERRMSG("start_plugin", "execl", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
74 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
75 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
76 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
77 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
78
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
79 /* Parent, Close sockets fix stdio and return pid */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
80 if (a_Misc_close_fd(newsock) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
81 ERRMSG("start_plugin", "close", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
82 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
83 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
84 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
85 a_Misc_close_fd(STDIN_FILENO);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
86 a_Misc_close_fd(STDOUT_FILENO);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
87 dup2(old_stdin, STDIN_FILENO);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
88 dup2(old_stdout, STDOUT_FILENO);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
89 return pid;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
90 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
91
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
92 static void start_server_plugin(struct dp dpi_attr)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
93 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
94 if (dup2(dpi_attr.socket, STDIN_FILENO) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
95 ERRMSG("start_plugin", "dup2", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
96 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
97 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
98 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
99 if (a_Misc_close_fd(dpi_attr.socket) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
100 ERRMSG("start_plugin", "close", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
101 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
102 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
103 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
104 if (execl(dpi_attr.path, dpi_attr.path, NULL) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
105 ERRMSG("start_plugin", "execl", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
106 MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
107 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
108 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
109 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
110
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
111 /*!
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
112 * Read service request from sock
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
113 * \Return
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
114 * pointer to dynamically allocated request tag
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
115 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
116 static char *get_request(int sock)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
117 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
118 char *req, buf[10];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
119 size_t buflen;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
120 size_t rqsz;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
121 ssize_t rdln;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
122
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
123 req = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
124 buf[0] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
125 buflen = sizeof(buf) / sizeof(buf[0]);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
126
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
127 (void) sigprocmask(SIG_BLOCK, &mask_sigchld, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
128 for (rqsz = 0; (rdln = read(sock, buf, buflen)) != 0; rqsz += rdln) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
129 if (rdln == -1)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
130 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
131 req = (char *) realloc(req, rqsz + rdln + 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
132 if (rqsz == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
133 req[0] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
134 strncat(req, buf, (size_t) rdln);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
135 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
136 (void) sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
137 if (rdln == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
138 ERRMSG("get_request", "read", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
139 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
140
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
141 return (req);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
142 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
143
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
144 /*!
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
145 * Get value of cmd field in dpi_tag
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
146 * \Return
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
147 * command code on success, -1 on failure
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
148 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
149 static int get_command(int sock, char *dpi_tag, struct dp *dpi_attr_list)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
150 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
151 char *cmd, *d_cmd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
152 int COMMAND;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
153
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
154 if (dpi_tag == NULL) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
155 _ERRMSG("get_command", "dpid tag is NULL", 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
156 return (-1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
157 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
158
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
159 cmd = a_Dpip_get_attr(dpi_tag, strlen(dpi_tag), "cmd");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
160
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
161 if (cmd == NULL) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
162 ERRMSG("get_command", "a_Dpip_get_attr", 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
163 MSG_ERR(": dpid failed to parse cmd in %s\n", dpi_tag);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
164 d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
165 "DpiError", "Failed to parse request");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
166 (void) CKD_WRITE(sock, d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
167 dFree(d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
168 COMMAND = -1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
169 } else if (strcmp("DpiBye", cmd) == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
170 COMMAND = BYE_CMD;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
171 } else if (strcmp("check_server", cmd) == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
172 COMMAND = CHECK_SERVER_CMD;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
173 } else if (strcmp("register_all", cmd) == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
174 COMMAND = REGISTER_ALL_CMD;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
175 } else if (strcmp("register_service", cmd) == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
176 COMMAND = REGISTER_SERVICE_CMD;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
177 } else { /* Error unknown command */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
178 COMMAND = UNKNOWN_CMD;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
179 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
180
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
181 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
182 return (COMMAND);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
183 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
184
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
185 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
186 * Check whether a dpi server is running
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
187 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
188 int server_is_running(char *server_id)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
189 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
190 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
191
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
192 /* Search in the set of running servers */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
193 for (i = 0; i < numdpis; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
194 if (!dpi_attr_list[i].filter && dpi_attr_list[i].pid > 1 &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
195 strcmp(dpi_attr_list[i].id, server_id) == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
196 return 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
197 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
198 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
199 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
200
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
201
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
202 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
203 * Get MAX open FD limit (yes, it's tricky --Jcid).
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
204 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
205 static int get_open_max(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
206 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
207 #ifdef OPEN_MAX
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
208 return OPEN_MAX;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
209 #else
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
210 int ret = sysconf(_SC_OPEN_MAX);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
211 if (ret < 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
212 ret = 256;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
213 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
214 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
215 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
216
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
217 /*! \todo
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
218 * \li Add a dpid_idle_timeout variable to dpidrc
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
219 * \bug Infinite loop if plugin crashes before it accepts a connection
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
220 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
221 int main(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
222 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
223 int i, n = 0, open_max;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
224 char *dirname = NULL, *sockdir = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
225 int dpid_idle_timeout = 60 * 60; /* default, in seconds */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
226 struct timeval select_timeout;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
227 sigset_t mask_none;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
228 fd_set selected_set;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
229
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
230 dpi_attr_list = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
231 //daemon(0,0); /* Use 0,1 for feedback */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
232 /* todo: call setsid() ?? */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
233
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
234 /* Allow read and write access, but only for the user.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
235 * todo: can this cause trouble with umount? */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
236 umask(0077);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
237 /* todo: make dpid work on any directory. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
238 // chdir("/");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
239
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
240 /* close inherited file descriptors */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
241 open_max = get_open_max();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
242 for (i = 3; i < open_max; i++)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
243 a_Misc_close_fd(i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
244
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
245 /* this sleep used to unmask a race condition */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
246 // sleep(2);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
247
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
248 dpi_errno = no_errors;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
249
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
250 /* Get list of available dpis */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
251 numdpis = register_all(&dpi_attr_list);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
252
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
253 /* Get name of socket directory */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
254 dirname = a_Dpi_sockdir_file();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
255 if ((sockdir = init_sockdir(dirname)) == NULL) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
256 ERRMSG("main", "init_sockdir", 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
257 MSG_ERR("Failed to create socket directory\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
258 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
259 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
260
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
261 /* Remove any sockets that may have been leftover from a crash */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
262 cleanup(sockdir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
263 /* Initialise sockets */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
264 if ((numsocks = init_srs_socket(sockdir)) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
265 switch (dpi_errno) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
266 case dpid_srs_addrinuse:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
267 MSG_ERR("dpid refuses to start, possibly because:\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
268 MSG_ERR("\t1) An instance of dpid is already running.\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
269 MSG_ERR("\t2) A previous dpid didn't clean up on exit.\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
270 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
271 default:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
272 ERRMSG("main", "init_srs_sockets failed", 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
273 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
274 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
275 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
276 numsocks = init_all_dpi_sockets(dpi_attr_list, sockdir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
277 //est_terminator(); /* Do we still want to clean up on an abnormal exit? */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
278 est_dpi_sigchld();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
279
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
280 (void) sigemptyset(&mask_sigchld);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
281 (void) sigaddset(&mask_sigchld, SIGCHLD);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
282 (void) sigemptyset(&mask_none);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
283 (void) sigprocmask(SIG_SETMASK, &mask_none, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
284
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
285 printf("dpid started\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
286 /* Start main loop */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
287 while (1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
288 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
289 (void) sigprocmask(SIG_BLOCK, &mask_sigchld, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
290 if (caught_sigchld) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
291 handle_sigchld();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
292 caught_sigchld = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
293 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
294 (void) sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
295 select_timeout.tv_sec = dpid_idle_timeout;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
296 select_timeout.tv_usec = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
297 selected_set = sock_set;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
298 n = select(FD_SETSIZE, &selected_set, NULL, NULL, &select_timeout);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
299 if (n == 0) { /* select timed out, try to exit */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
300 /* BUG: This is a workaround for dpid not to exit when the
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
301 * downloads server is active. The proper way to handle it is with
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
302 * a dpip command that asks the server whether it's busy.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
303 * Note: the cookies server may lose session info too. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
304 if (server_is_running("downloads"))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
305 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
306
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
307 stop_active_dpis(dpi_attr_list, numdpis);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
308 cleanup(sockdir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
309 exit(0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
310 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
311 } while (n == -1 && errno == EINTR);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
312
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
313 if (n == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
314 ERRMSG("main", "select", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
315 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
316 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
317 /* If the service req socket is selected then service the req. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
318 if (FD_ISSET(srs, &selected_set)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
319 int sock;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
320 socklen_t csz;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
321 struct sockaddr_un clnt_addr;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
322 char *req = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
323
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
324 --n;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
325 assert(n >= 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
326 csz = (socklen_t) sizeof(clnt_addr);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
327 sock = accept(srs, (struct sockaddr *) &clnt_addr, &csz);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
328 if (sock == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
329 ERRMSG("main", "accept", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
330 MSG_ERR("accept on srs socket failed\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
331 MSG_ERR("service pending connections, and continue\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
332 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
333 int command;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
334
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
335 req = get_request(sock);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
336 command = get_command(sock, req, dpi_attr_list);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
337 switch (command) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
338 case BYE_CMD:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
339 stop_active_dpis(dpi_attr_list, numdpis);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
340 cleanup(sockdir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
341 exit(0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
342 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
343 case CHECK_SERVER_CMD:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
344 send_sockpath(sock, req, dpi_attr_list);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
345 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
346 case REGISTER_ALL_CMD:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
347 register_all_cmd(sockdir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
348 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
349 case UNKNOWN_CMD:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
350 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
351 char *d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
352 "DpiError", "Unknown command");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
353 (void) CKD_WRITE(sock, d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
354 dFree(d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
355 ERRMSG("main", "Unknown command", 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
356 MSG_ERR(" for request: %s\n", req);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
357 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
358 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
359 case -1:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
360 _ERRMSG("main", "get_command failed", 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
361 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
362 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
363 if (req)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
364 free(req);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
365 a_Misc_close_fd(sock);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
366 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
367 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
368
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
369 /* While there's a request on one of the plugin sockets
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
370 * find the matching plugin and start it. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
371 for (i = 0; n > 0 && i < numdpis; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
372 if (FD_ISSET(dpi_attr_list[i].socket, &selected_set)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
373 --n;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
374 assert(n >= 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
375
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
376 if (dpi_attr_list[i].filter) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
377 /* start a dpi filter plugin and continue watching its socket
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
378 * for new connections */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
379 (void) sigprocmask(SIG_SETMASK, &mask_none, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
380 start_filter_plugin(dpi_attr_list[i]);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
381 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
382 /* start a dpi server plugin but don't wait for new connections
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
383 * on its socket */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
384 numsocks--;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
385 assert(numsocks >= 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
386 FD_CLR(dpi_attr_list[i].socket, &sock_set);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
387 if ((dpi_attr_list[i].pid = fork()) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
388 ERRMSG("main", "fork", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
389 /* exit(1); */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
390 } else if (dpi_attr_list[i].pid == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
391 (void) sigprocmask(SIG_SETMASK, &mask_none, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
392 start_server_plugin(dpi_attr_list[i]);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
393 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
394 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
395 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
396 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
397 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
398 }