... | ... |
@@ -78,10 +78,12 @@ static pthread_mutex_t virusaction_lock = PTHREAD_MUTEX_INITIALIZER; |
78 | 78 |
static pthread_mutex_t detstats_lock = PTHREAD_MUTEX_INITIALIZER; |
79 | 79 |
|
80 | 80 |
#ifdef _WIN32 |
81 |
-void virusaction(const char *filename, const char *virname, const struct optstruct *opts) |
|
81 |
+void |
|
82 |
+virusaction (const char *filename, const char *virname, |
|
83 |
+ const struct optstruct *opts) |
|
82 | 84 |
{ |
83 |
- if(optget(opts, "VirusEvent")->enabled) |
|
84 |
- logg("^VirusEvent is not supported on this platform"); /* Yet */ |
|
85 |
+ if (optget (opts, "VirusEvent")->enabled) |
|
86 |
+ logg ("^VirusEvent is not supported on this platform"); /* Yet */ |
|
85 | 87 |
} |
86 | 88 |
|
87 | 89 |
#else |
... | ... |
@@ -89,244 +91,284 @@ void virusaction(const char *filename, const char *virname, const struct optstru |
89 | 89 |
#define VE_FILENAME "CLAM_VIRUSEVENT_FILENAME" |
90 | 90 |
#define VE_VIRUSNAME "CLAM_VIRUSEVENT_VIRUSNAME" |
91 | 91 |
|
92 |
-void virusaction(const char *filename, const char *virname, const struct optstruct *opts) |
|
92 |
+void |
|
93 |
+virusaction (const char *filename, const char *virname, |
|
94 |
+ const struct optstruct *opts) |
|
93 | 95 |
{ |
94 |
- pid_t pid; |
|
95 |
- const struct optstruct *opt; |
|
96 |
- char *buffer_file, *buffer_vir, *buffer_cmd; |
|
97 |
- const char *pt; |
|
98 |
- size_t i, j, v = 0, len; |
|
99 |
- char *env[4]; |
|
100 |
- |
|
101 |
- if(!(opt = optget(opts, "VirusEvent"))->enabled) |
|
102 |
- return; |
|
103 |
- |
|
104 |
- env[0] = getenv("PATH"); |
|
105 |
- j = env[0] ? 1 : 0; |
|
106 |
- /* Allocate env vars.. to be portable env vars should not be freed */ |
|
107 |
- buffer_file = (char *) malloc(strlen(VE_FILENAME) + strlen(filename) + 2); |
|
108 |
- if(buffer_file) { |
|
109 |
- sprintf(buffer_file, "%s=%s", VE_FILENAME, filename); |
|
110 |
- env[j++] = buffer_file; |
|
111 |
- } |
|
112 |
- |
|
113 |
- buffer_vir = (char *) malloc(strlen(VE_VIRUSNAME) + strlen(virname) + 2); |
|
114 |
- if(buffer_vir) { |
|
115 |
- sprintf(buffer_vir, "%s=%s", VE_VIRUSNAME, virname); |
|
116 |
- env[j++] = buffer_vir; |
|
117 |
- } |
|
118 |
- env[j++] = NULL; |
|
119 |
- |
|
120 |
- pt = opt->strarg; |
|
121 |
- while((pt = strstr(pt, "%v"))) { |
|
122 |
- pt += 2; |
|
123 |
- v++; |
|
124 |
- } |
|
125 |
- len = strlen(opt->strarg); |
|
126 |
- buffer_cmd = (char *) calloc(len + v * strlen(virname) + 1, sizeof(char)); |
|
127 |
- if(!buffer_cmd) { |
|
128 |
- free(buffer_file); |
|
129 |
- free(buffer_vir); |
|
130 |
- return; |
|
131 |
- } |
|
132 |
- for(i = 0, j = 0; i < len; i++) { |
|
133 |
- if(i + 1 < len && opt->strarg[i] == '%' && opt->strarg[i + 1] == 'v') { |
|
134 |
- strcat(buffer_cmd, virname); |
|
135 |
- j += strlen(virname); |
|
136 |
- i++; |
|
137 |
- } else { |
|
138 |
- buffer_cmd[j++] = opt->strarg[i]; |
|
139 |
- } |
|
140 |
- } |
|
141 |
- |
|
142 |
- pthread_mutex_lock(&virusaction_lock); |
|
143 |
- /* We can only call async-signal-safe functions after fork(). */ |
|
144 |
- pid = fork(); |
|
145 |
- if(!pid) { /* child */ |
|
146 |
- exit(execle("/bin/sh", "sh", "-c", buffer_cmd, NULL, env)); |
|
147 |
- } else if(pid > 0) { /* parent */ |
|
148 |
- pthread_mutex_unlock(&virusaction_lock); |
|
149 |
- while(waitpid(pid, NULL, 0) == -1 && errno == EINTR); |
|
150 |
- } else { |
|
151 |
- logg("!VirusEvent: fork failed.\n"); |
|
152 |
- } |
|
153 |
- free(buffer_cmd); |
|
154 |
- free(buffer_file); |
|
155 |
- free(buffer_vir); |
|
96 |
+ pid_t pid; |
|
97 |
+ const struct optstruct *opt; |
|
98 |
+ char *buffer_file, *buffer_vir, *buffer_cmd; |
|
99 |
+ const char *pt; |
|
100 |
+ size_t i, j, v = 0, len; |
|
101 |
+ char *env[4]; |
|
102 |
+ |
|
103 |
+ if (!(opt = optget (opts, "VirusEvent"))->enabled) |
|
104 |
+ return; |
|
105 |
+ |
|
106 |
+ env[0] = getenv ("PATH"); |
|
107 |
+ j = env[0] ? 1 : 0; |
|
108 |
+ /* Allocate env vars.. to be portable env vars should not be freed */ |
|
109 |
+ buffer_file = |
|
110 |
+ (char *) malloc (strlen (VE_FILENAME) + strlen (filename) + 2); |
|
111 |
+ if (buffer_file) |
|
112 |
+ { |
|
113 |
+ sprintf (buffer_file, "%s=%s", VE_FILENAME, filename); |
|
114 |
+ env[j++] = buffer_file; |
|
115 |
+ } |
|
116 |
+ |
|
117 |
+ buffer_vir = |
|
118 |
+ (char *) malloc (strlen (VE_VIRUSNAME) + strlen (virname) + 2); |
|
119 |
+ if (buffer_vir) |
|
120 |
+ { |
|
121 |
+ sprintf (buffer_vir, "%s=%s", VE_VIRUSNAME, virname); |
|
122 |
+ env[j++] = buffer_vir; |
|
123 |
+ } |
|
124 |
+ env[j++] = NULL; |
|
125 |
+ |
|
126 |
+ pt = opt->strarg; |
|
127 |
+ while ((pt = strstr (pt, "%v"))) |
|
128 |
+ { |
|
129 |
+ pt += 2; |
|
130 |
+ v++; |
|
131 |
+ } |
|
132 |
+ len = strlen (opt->strarg); |
|
133 |
+ buffer_cmd = |
|
134 |
+ (char *) calloc (len + v * strlen (virname) + 1, sizeof (char)); |
|
135 |
+ if (!buffer_cmd) |
|
136 |
+ { |
|
137 |
+ free (buffer_file); |
|
138 |
+ free (buffer_vir); |
|
139 |
+ return; |
|
140 |
+ } |
|
141 |
+ for (i = 0, j = 0; i < len; i++) |
|
142 |
+ { |
|
143 |
+ if (i + 1 < len && opt->strarg[i] == '%' && opt->strarg[i + 1] == 'v') |
|
144 |
+ { |
|
145 |
+ strcat (buffer_cmd, virname); |
|
146 |
+ j += strlen (virname); |
|
147 |
+ i++; |
|
148 |
+ } |
|
149 |
+ else |
|
150 |
+ { |
|
151 |
+ buffer_cmd[j++] = opt->strarg[i]; |
|
152 |
+ } |
|
153 |
+ } |
|
154 |
+ |
|
155 |
+ pthread_mutex_lock (&virusaction_lock); |
|
156 |
+ /* We can only call async-signal-safe functions after fork(). */ |
|
157 |
+ pid = fork (); |
|
158 |
+ if (!pid) |
|
159 |
+ { /* child */ |
|
160 |
+ exit (execle ("/bin/sh", "sh", "-c", buffer_cmd, NULL, env)); |
|
161 |
+ } |
|
162 |
+ else if (pid > 0) |
|
163 |
+ { /* parent */ |
|
164 |
+ pthread_mutex_unlock (&virusaction_lock); |
|
165 |
+ while (waitpid (pid, NULL, 0) == -1 && errno == EINTR); |
|
166 |
+ } |
|
167 |
+ else |
|
168 |
+ { |
|
169 |
+ logg ("!VirusEvent: fork failed.\n"); |
|
170 |
+ } |
|
171 |
+ free (buffer_cmd); |
|
172 |
+ free (buffer_file); |
|
173 |
+ free (buffer_vir); |
|
156 | 174 |
} |
157 | 175 |
#endif /* _WIN32 */ |
158 | 176 |
|
159 | 177 |
/* Function: writen |
160 | 178 |
Try hard to write the specified number of bytes |
161 | 179 |
*/ |
162 |
-int writen(int fd, void *buff, unsigned int count) |
|
180 |
+int |
|
181 |
+writen (int fd, void *buff, unsigned int count) |
|
163 | 182 |
{ |
164 |
- int retval; |
|
165 |
- unsigned int todo; |
|
166 |
- unsigned char *current; |
|
167 |
- |
|
183 |
+ int retval; |
|
184 |
+ unsigned int todo; |
|
185 |
+ unsigned char *current; |
|
186 |
+ |
|
168 | 187 |
todo = count; |
169 | 188 |
current = (unsigned char *) buff; |
170 |
- |
|
171 |
- do { |
|
172 |
- retval = write(fd, current, todo); |
|
173 |
- if (retval < 0) { |
|
174 |
- if (errno == EINTR) { |
|
175 |
- continue; |
|
176 |
- } |
|
177 |
- return -1; |
|
178 |
- } |
|
179 |
- todo -= retval; |
|
180 |
- current += retval; |
|
181 |
- } while (todo > 0); |
|
182 |
- |
|
189 |
+ |
|
190 |
+ do |
|
191 |
+ { |
|
192 |
+ retval = write (fd, current, todo); |
|
193 |
+ if (retval < 0) |
|
194 |
+ { |
|
195 |
+ if (errno == EINTR) |
|
196 |
+ { |
|
197 |
+ continue; |
|
198 |
+ } |
|
199 |
+ return -1; |
|
200 |
+ } |
|
201 |
+ todo -= retval; |
|
202 |
+ current += retval; |
|
203 |
+ } |
|
204 |
+ while (todo > 0); |
|
205 |
+ |
|
183 | 206 |
return count; |
184 | 207 |
} |
185 | 208 |
|
186 |
-static int realloc_polldata(struct fd_data *data) |
|
209 |
+static int |
|
210 |
+realloc_polldata (struct fd_data *data) |
|
187 | 211 |
{ |
188 | 212 |
#ifdef HAVE_POLL |
189 | 213 |
if (data->poll_data_nfds == data->nfds) |
190 |
- return 0; |
|
214 |
+ return 0; |
|
191 | 215 |
if (data->poll_data) |
192 |
- free(data->poll_data); |
|
193 |
- data->poll_data = malloc(data->nfds*sizeof(*data->poll_data)); |
|
194 |
- if (!data->poll_data) { |
|
195 |
- logg("!realloc_polldata: Memory allocation failed for poll_data\n"); |
|
196 |
- return -1; |
|
216 |
+ free (data->poll_data); |
|
217 |
+ data->poll_data = malloc (data->nfds * sizeof (*data->poll_data)); |
|
218 |
+ if (!data->poll_data) |
|
219 |
+ { |
|
220 |
+ logg ("!realloc_polldata: Memory allocation failed for poll_data\n"); |
|
221 |
+ return -1; |
|
197 | 222 |
} |
198 | 223 |
data->poll_data_nfds = data->nfds; |
199 | 224 |
#endif |
200 | 225 |
return 0; |
201 | 226 |
} |
202 | 227 |
|
203 |
-int poll_fd(int fd, int timeout_sec, int check_signals) |
|
228 |
+int |
|
229 |
+poll_fd (int fd, int timeout_sec, int check_signals) |
|
204 | 230 |
{ |
205 | 231 |
int ret; |
206 |
- struct fd_data fds = FDS_INIT(NULL); |
|
207 |
- |
|
208 |
- if (fds_add(&fds, fd, 1, timeout_sec) == -1) |
|
209 |
- return -1; |
|
210 |
- do { |
|
211 |
- ret = fds_poll_recv(&fds, timeout_sec, check_signals, NULL); |
|
212 |
- } while (ret == -1 && errno == EINTR); |
|
213 |
- fds_free(&fds); |
|
232 |
+ struct fd_data fds = FDS_INIT (NULL); |
|
233 |
+ |
|
234 |
+ if (fds_add (&fds, fd, 1, timeout_sec) == -1) |
|
235 |
+ return -1; |
|
236 |
+ do |
|
237 |
+ { |
|
238 |
+ ret = fds_poll_recv (&fds, timeout_sec, check_signals, NULL); |
|
239 |
+ } |
|
240 |
+ while (ret == -1 && errno == EINTR); |
|
241 |
+ fds_free (&fds); |
|
214 | 242 |
return ret; |
215 | 243 |
} |
216 | 244 |
|
217 |
-void fds_cleanup(struct fd_data *data) |
|
245 |
+void |
|
246 |
+fds_cleanup (struct fd_data *data) |
|
218 | 247 |
{ |
219 | 248 |
struct fd_buf *newbuf; |
220 |
- unsigned i,j; |
|
221 |
- |
|
222 |
- for (i=0,j=0;i < data->nfds; i++) { |
|
223 |
- if (data->buf[i].fd < 0) { |
|
224 |
- if (data->buf[i].buffer) |
|
225 |
- free(data->buf[i].buffer); |
|
226 |
- continue; |
|
227 |
- } |
|
228 |
- if (i != j) |
|
229 |
- data->buf[j] = data->buf[i]; |
|
230 |
- j++; |
|
249 |
+ unsigned i, j; |
|
250 |
+ |
|
251 |
+ for (i = 0, j = 0; i < data->nfds; i++) |
|
252 |
+ { |
|
253 |
+ if (data->buf[i].fd < 0) |
|
254 |
+ { |
|
255 |
+ if (data->buf[i].buffer) |
|
256 |
+ free (data->buf[i].buffer); |
|
257 |
+ continue; |
|
258 |
+ } |
|
259 |
+ if (i != j) |
|
260 |
+ data->buf[j] = data->buf[i]; |
|
261 |
+ j++; |
|
231 | 262 |
} |
232 | 263 |
if (j == data->nfds) |
233 |
- return; |
|
234 |
- for (i = j ; i < data->nfds; i++) |
|
235 |
- data->buf[i].fd = -1; |
|
264 |
+ return; |
|
265 |
+ for (i = j; i < data->nfds; i++) |
|
266 |
+ data->buf[i].fd = -1; |
|
236 | 267 |
data->nfds = j; |
237 |
- logg("$Number of file descriptors polled: %u fds\n", (unsigned) data->nfds); |
|
268 |
+ logg ("$Number of file descriptors polled: %u fds\n", |
|
269 |
+ (unsigned) data->nfds); |
|
238 | 270 |
/* Shrink buffer */ |
239 |
- newbuf = realloc(data->buf, j*sizeof(*newbuf)); |
|
240 |
- if(!j) |
|
241 |
- data->buf = NULL; |
|
271 |
+ newbuf = realloc (data->buf, j * sizeof (*newbuf)); |
|
272 |
+ if (!j) |
|
273 |
+ data->buf = NULL; |
|
242 | 274 |
else if (newbuf) |
243 |
- data->buf = newbuf;/* non-fatal if shrink fails */ |
|
275 |
+ data->buf = newbuf; /* non-fatal if shrink fails */ |
|
244 | 276 |
} |
245 | 277 |
|
246 |
-static int read_fd_data(struct fd_buf *buf) |
|
278 |
+static int |
|
279 |
+read_fd_data (struct fd_buf *buf) |
|
247 | 280 |
{ |
248 | 281 |
ssize_t n; |
249 | 282 |
|
250 |
- buf->got_newdata=1; |
|
251 |
- if (!buf->buffer) /* listen-only socket */ |
|
252 |
- return 1; |
|
283 |
+ buf->got_newdata = 1; |
|
284 |
+ if (!buf->buffer) /* listen-only socket */ |
|
285 |
+ return 1; |
|
253 | 286 |
|
254 | 287 |
if (buf->off >= buf->bufsize) |
255 |
- return -1; |
|
288 |
+ return -1; |
|
256 | 289 |
|
257 |
- /* Read the pending packet, it may contain more than one command, but |
|
258 |
- * that is to the cmdparser to handle. |
|
259 |
- * It will handle 1st command, and then move leftover to beginning of buffer |
|
260 |
- */ |
|
290 |
+ /* Read the pending packet, it may contain more than one command, but |
|
291 |
+ * that is to the cmdparser to handle. |
|
292 |
+ * It will handle 1st command, and then move leftover to beginning of buffer |
|
293 |
+ */ |
|
261 | 294 |
#ifdef HAVE_FD_PASSING |
262 |
- { |
|
263 |
- struct msghdr msg; |
|
264 |
- struct cmsghdr *cmsg; |
|
265 |
- union { |
|
266 |
- unsigned char buff[CMSG_SPACE(sizeof(int))]; |
|
267 |
- struct cmsghdr hdr; |
|
268 |
- } b; |
|
269 |
- struct iovec iov[1]; |
|
270 |
- |
|
271 |
- if (buf->recvfd != -1) { |
|
272 |
- logg("$Closing unclaimed FD: %d\n", buf->recvfd); |
|
273 |
- close(buf->recvfd); |
|
274 |
- buf->recvfd = -1; |
|
275 |
- } |
|
276 |
- memset(&msg, 0, sizeof(msg)); |
|
277 |
- iov[0].iov_base = buf->buffer + buf->off; |
|
278 |
- iov[0].iov_len = buf->bufsize - buf->off; |
|
279 |
- msg.msg_iov = iov; |
|
280 |
- msg.msg_iovlen = 1; |
|
281 |
- msg.msg_control = b.buff; |
|
282 |
- msg.msg_controllen = sizeof(b.buff); |
|
283 |
- |
|
284 |
- n = recvmsg(buf->fd, &msg, 0); |
|
285 |
- if (n < 0) |
|
286 |
- return -1; |
|
287 |
- if (msg.msg_flags & MSG_TRUNC) { |
|
288 |
- logg("^Message truncated at %d bytes\n", (int)n); |
|
289 |
- return -1; |
|
290 |
- } |
|
291 |
- if (msg.msg_flags & MSG_CTRUNC) { |
|
292 |
- if (msg.msg_controllen > 0) |
|
293 |
- logg("^Control message truncated at %d bytes, %d data read\n", |
|
294 |
- (int)msg.msg_controllen, (int)n); |
|
295 |
- else |
|
296 |
- logg("^Control message truncated, no control data received, %d bytes read" |
|
295 |
+ { |
|
296 |
+ struct msghdr msg; |
|
297 |
+ struct cmsghdr *cmsg; |
|
298 |
+ union |
|
299 |
+ { |
|
300 |
+ unsigned char buff[CMSG_SPACE (sizeof (int))]; |
|
301 |
+ struct cmsghdr hdr; |
|
302 |
+ } b; |
|
303 |
+ struct iovec iov[1]; |
|
304 |
+ |
|
305 |
+ if (buf->recvfd != -1) |
|
306 |
+ { |
|
307 |
+ logg ("$Closing unclaimed FD: %d\n", buf->recvfd); |
|
308 |
+ close (buf->recvfd); |
|
309 |
+ buf->recvfd = -1; |
|
310 |
+ } |
|
311 |
+ memset (&msg, 0, sizeof (msg)); |
|
312 |
+ iov[0].iov_base = buf->buffer + buf->off; |
|
313 |
+ iov[0].iov_len = buf->bufsize - buf->off; |
|
314 |
+ msg.msg_iov = iov; |
|
315 |
+ msg.msg_iovlen = 1; |
|
316 |
+ msg.msg_control = b.buff; |
|
317 |
+ msg.msg_controllen = sizeof (b.buff); |
|
318 |
+ |
|
319 |
+ n = recvmsg (buf->fd, &msg, 0); |
|
320 |
+ if (n < 0) |
|
321 |
+ return -1; |
|
322 |
+ if (msg.msg_flags & MSG_TRUNC) |
|
323 |
+ { |
|
324 |
+ logg ("^Message truncated at %d bytes\n", (int) n); |
|
325 |
+ return -1; |
|
326 |
+ } |
|
327 |
+ if (msg.msg_flags & MSG_CTRUNC) |
|
328 |
+ { |
|
329 |
+ if (msg.msg_controllen > 0) |
|
330 |
+ logg ("^Control message truncated at %d bytes, %d data read\n", (int) msg.msg_controllen, (int) n); |
|
331 |
+ else |
|
332 |
+ logg ("^Control message truncated, no control data received, %d bytes read" |
|
297 | 333 |
#ifdef C_LINUX |
298 |
- "(Is SELinux/AppArmor enabled, and blocking file descriptor passing?)" |
|
334 |
+ "(Is SELinux/AppArmor enabled, and blocking file descriptor passing?)" |
|
299 | 335 |
#endif |
300 |
- "\n", |
|
301 |
- (int)n); |
|
302 |
- return -1; |
|
303 |
- } |
|
304 |
- if (msg.msg_controllen) { |
|
305 |
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; |
|
306 |
- cmsg = CMSG_NXTHDR(&msg, cmsg)) { |
|
307 |
- if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && |
|
308 |
- cmsg->cmsg_level == SOL_SOCKET && |
|
309 |
- cmsg->cmsg_type == SCM_RIGHTS) { |
|
310 |
- if (buf->recvfd != -1) { |
|
311 |
- logg("$Unclaimed file descriptor received. closing: %d\n", buf->recvfd); |
|
312 |
- close(buf->recvfd); |
|
313 |
- } |
|
314 |
- buf->recvfd = *(int *)CMSG_DATA(cmsg); |
|
315 |
- logg("$Receveived a file descriptor: %d\n", buf->recvfd); |
|
316 |
- } |
|
317 |
- } |
|
318 |
- } |
|
319 |
- } |
|
336 |
+ "\n", (int) n); |
|
337 |
+ return -1; |
|
338 |
+ } |
|
339 |
+ if (msg.msg_controllen) |
|
340 |
+ { |
|
341 |
+ for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; |
|
342 |
+ cmsg = CMSG_NXTHDR (&msg, cmsg)) |
|
343 |
+ { |
|
344 |
+ if (cmsg->cmsg_len == CMSG_LEN (sizeof (int)) && |
|
345 |
+ cmsg->cmsg_level == SOL_SOCKET && |
|
346 |
+ cmsg->cmsg_type == SCM_RIGHTS) |
|
347 |
+ { |
|
348 |
+ if (buf->recvfd != -1) |
|
349 |
+ { |
|
350 |
+ logg ("$Unclaimed file descriptor received. closing: %d\n", buf->recvfd); |
|
351 |
+ close (buf->recvfd); |
|
352 |
+ } |
|
353 |
+ buf->recvfd = *(int *) CMSG_DATA (cmsg); |
|
354 |
+ logg ("$Receveived a file descriptor: %d\n", buf->recvfd); |
|
355 |
+ } |
|
356 |
+ } |
|
357 |
+ } |
|
358 |
+ } |
|
320 | 359 |
#else |
321 |
- n = recv(buf->fd, buf->buffer + buf->off, buf->bufsize - buf->off,0); |
|
322 |
- if (n < 0) |
|
323 |
- return -1; |
|
360 |
+ n = recv (buf->fd, buf->buffer + buf->off, buf->bufsize - buf->off, 0); |
|
361 |
+ if (n < 0) |
|
362 |
+ return -1; |
|
324 | 363 |
#endif |
325 |
- buf->off += n; |
|
326 |
- return n; |
|
364 |
+ buf->off += n; |
|
365 |
+ return n; |
|
327 | 366 |
} |
328 | 367 |
|
329 |
-static int buf_init(struct fd_buf *buf, int listen_only, int timeout) |
|
368 |
+static int |
|
369 |
+buf_init (struct fd_buf *buf, int listen_only, int timeout) |
|
330 | 370 |
{ |
331 | 371 |
buf->off = 0; |
332 | 372 |
buf->got_newdata = 0; |
... | ... |
@@ -339,89 +381,107 @@ static int buf_init(struct fd_buf *buf, int listen_only, int timeout) |
339 | 339 |
buf->dumpname = NULL; |
340 | 340 |
buf->group = NULL; |
341 | 341 |
buf->term = '\0'; |
342 |
- if (!listen_only) { |
|
343 |
- if (!buf->buffer) { |
|
344 |
- buf->bufsize = PATH_MAX+8; |
|
345 |
- /* plus extra space for a \0 so we can make sure every command is \0 |
|
346 |
- * terminated */ |
|
347 |
- if (!(buf->buffer = malloc(buf->bufsize + 1))) { |
|
348 |
- logg("!add_fd: Memory allocation failed for command buffer\n"); |
|
349 |
- return -1; |
|
350 |
- } |
|
351 |
- } |
|
352 |
- } else { |
|
353 |
- if (buf->buffer) |
|
354 |
- free(buf->buffer); |
|
355 |
- buf->bufsize = 0; |
|
356 |
- buf->buffer = NULL; |
|
342 |
+ if (!listen_only) |
|
343 |
+ { |
|
344 |
+ if (!buf->buffer) |
|
345 |
+ { |
|
346 |
+ buf->bufsize = PATH_MAX + 8; |
|
347 |
+ /* plus extra space for a \0 so we can make sure every command is \0 |
|
348 |
+ * terminated */ |
|
349 |
+ if (!(buf->buffer = malloc (buf->bufsize + 1))) |
|
350 |
+ { |
|
351 |
+ logg ("!add_fd: Memory allocation failed for command buffer\n"); |
|
352 |
+ return -1; |
|
353 |
+ } |
|
354 |
+ } |
|
355 |
+ } |
|
356 |
+ else |
|
357 |
+ { |
|
358 |
+ if (buf->buffer) |
|
359 |
+ free (buf->buffer); |
|
360 |
+ buf->bufsize = 0; |
|
361 |
+ buf->buffer = NULL; |
|
362 |
+ } |
|
363 |
+ if (timeout) |
|
364 |
+ { |
|
365 |
+ time (&buf->timeout_at); |
|
366 |
+ buf->timeout_at += timeout; |
|
357 | 367 |
} |
358 |
- if (timeout) { |
|
359 |
- time(&buf->timeout_at); |
|
360 |
- buf->timeout_at += timeout; |
|
361 |
- } else { |
|
362 |
- buf->timeout_at = 0; |
|
368 |
+ else |
|
369 |
+ { |
|
370 |
+ buf->timeout_at = 0; |
|
363 | 371 |
} |
364 | 372 |
return 0; |
365 | 373 |
} |
366 | 374 |
|
367 |
-int fds_add(struct fd_data *data, int fd, int listen_only, int timeout) |
|
375 |
+int |
|
376 |
+fds_add (struct fd_data *data, int fd, int listen_only, int timeout) |
|
368 | 377 |
{ |
369 | 378 |
struct fd_buf *buf; |
370 | 379 |
unsigned n; |
371 |
- if (fd < 0) { |
|
372 |
- logg("!add_fd: invalid fd passed to add_fd\n"); |
|
373 |
- return -1; |
|
380 |
+ if (fd < 0) |
|
381 |
+ { |
|
382 |
+ logg ("!add_fd: invalid fd passed to add_fd\n"); |
|
383 |
+ return -1; |
|
374 | 384 |
} |
375 | 385 |
/* we may already have this fd, if |
376 | 386 |
* the old FD got closed, and the kernel reused the FD */ |
377 | 387 |
for (n = 0; n < data->nfds; n++) |
378 |
- if (data->buf[n].fd == fd) { |
|
379 |
- /* clear stale data in buffer */ |
|
380 |
- if (buf_init(&data->buf[n], listen_only, timeout) < 0) |
|
381 |
- return -1; |
|
382 |
- return 0; |
|
383 |
- } |
|
388 |
+ if (data->buf[n].fd == fd) |
|
389 |
+ { |
|
390 |
+ /* clear stale data in buffer */ |
|
391 |
+ if (buf_init (&data->buf[n], listen_only, timeout) < 0) |
|
392 |
+ return -1; |
|
393 |
+ return 0; |
|
394 |
+ } |
|
384 | 395 |
|
385 | 396 |
n++; |
386 |
- buf = realloc(data->buf, n*sizeof(*buf)); |
|
387 |
- if (!buf) { |
|
388 |
- logg("!add_fd: Memory allocation failed for fd_buf\n"); |
|
389 |
- return -1; |
|
397 |
+ buf = realloc (data->buf, n * sizeof (*buf)); |
|
398 |
+ if (!buf) |
|
399 |
+ { |
|
400 |
+ logg ("!add_fd: Memory allocation failed for fd_buf\n"); |
|
401 |
+ return -1; |
|
390 | 402 |
} |
391 | 403 |
data->buf = buf; |
392 | 404 |
data->nfds = n; |
393 |
- data->buf[n-1].buffer = NULL; |
|
394 |
- if (buf_init(&data->buf[n-1], listen_only, timeout) < 0) |
|
395 |
- return -1; |
|
396 |
- data->buf[n-1].fd = fd; |
|
405 |
+ data->buf[n - 1].buffer = NULL; |
|
406 |
+ if (buf_init (&data->buf[n - 1], listen_only, timeout) < 0) |
|
407 |
+ return -1; |
|
408 |
+ data->buf[n - 1].fd = fd; |
|
397 | 409 |
return 0; |
398 | 410 |
} |
399 | 411 |
|
400 |
-static inline void fds_lock(struct fd_data *data) |
|
412 |
+static inline void |
|
413 |
+fds_lock (struct fd_data *data) |
|
401 | 414 |
{ |
402 | 415 |
if (data->buf_mutex) |
403 |
- pthread_mutex_lock(data->buf_mutex); |
|
416 |
+ pthread_mutex_lock (data->buf_mutex); |
|
404 | 417 |
} |
405 | 418 |
|
406 |
-static inline void fds_unlock(struct fd_data *data) |
|
419 |
+static inline void |
|
420 |
+fds_unlock (struct fd_data *data) |
|
407 | 421 |
{ |
408 | 422 |
if (data->buf_mutex) |
409 |
- pthread_mutex_unlock(data->buf_mutex); |
|
423 |
+ pthread_mutex_unlock (data->buf_mutex); |
|
410 | 424 |
} |
411 | 425 |
|
412 |
-void fds_remove(struct fd_data *data, int fd) |
|
426 |
+void |
|
427 |
+fds_remove (struct fd_data *data, int fd) |
|
413 | 428 |
{ |
414 | 429 |
size_t i; |
415 |
- fds_lock(data); |
|
416 |
- if (data->buf) { |
|
417 |
- for (i=0;i<data->nfds;i++) { |
|
418 |
- if (data->buf[i].fd == fd) { |
|
419 |
- data->buf[i].fd = -1; |
|
420 |
- break; |
|
421 |
- } |
|
422 |
- } |
|
430 |
+ fds_lock (data); |
|
431 |
+ if (data->buf) |
|
432 |
+ { |
|
433 |
+ for (i = 0; i < data->nfds; i++) |
|
434 |
+ { |
|
435 |
+ if (data->buf[i].fd == fd) |
|
436 |
+ { |
|
437 |
+ data->buf[i].fd = -1; |
|
438 |
+ break; |
|
439 |
+ } |
|
440 |
+ } |
|
423 | 441 |
} |
424 |
- fds_unlock(data); |
|
442 |
+ fds_unlock (data); |
|
425 | 443 |
} |
426 | 444 |
|
427 | 445 |
#define BUFFSIZE 1024 |
... | ... |
@@ -434,7 +494,9 @@ void fds_remove(struct fd_data *data, int fd) |
434 | 434 |
* Must be called with buf_mutex lock held. |
435 | 435 |
*/ |
436 | 436 |
/* TODO: handle ReadTimeout */ |
437 |
-int fds_poll_recv(struct fd_data *data, int timeout, int check_signals, void *event) |
|
437 |
+int |
|
438 |
+fds_poll_recv (struct fd_data *data, int timeout, int check_signals, |
|
439 |
+ void *event) |
|
438 | 440 |
{ |
439 | 441 |
unsigned fdsok = data->nfds; |
440 | 442 |
size_t i; |
... | ... |
@@ -442,40 +504,45 @@ int fds_poll_recv(struct fd_data *data, int timeout, int check_signals, void *ev |
442 | 442 |
time_t now, closest_timeout; |
443 | 443 |
|
444 | 444 |
/* we must have at least one fd, the control fd! */ |
445 |
- fds_cleanup(data); |
|
445 |
+ fds_cleanup (data); |
|
446 | 446 |
#ifndef _WIN32 |
447 | 447 |
if (!data->nfds) |
448 |
- return 0; |
|
448 |
+ return 0; |
|
449 | 449 |
#endif |
450 |
- for (i=0;i < data->nfds;i++) { |
|
451 |
- data->buf[i].got_newdata = 0; |
|
450 |
+ for (i = 0; i < data->nfds; i++) |
|
451 |
+ { |
|
452 |
+ data->buf[i].got_newdata = 0; |
|
452 | 453 |
} |
453 | 454 |
|
454 |
- time(&now); |
|
455 |
+ time (&now); |
|
455 | 456 |
if (timeout > 0) |
456 |
- closest_timeout = now + timeout; |
|
457 |
+ closest_timeout = now + timeout; |
|
457 | 458 |
else |
458 |
- closest_timeout = 0; |
|
459 |
- for (i=0;i < data->nfds; i++) { |
|
460 |
- time_t timeout_at = data->buf[i].timeout_at; |
|
461 |
- if (timeout_at && timeout_at < now) { |
|
462 |
- /* timed out */ |
|
463 |
- data->buf[i].got_newdata = -2; |
|
464 |
- /* we must return immediately from poll/select, we have a timeout! */ |
|
465 |
- closest_timeout = now; |
|
466 |
- } else { |
|
467 |
- if (!closest_timeout) |
|
468 |
- closest_timeout = timeout_at; |
|
469 |
- else if (timeout_at && timeout_at < closest_timeout) |
|
470 |
- closest_timeout = timeout_at; |
|
471 |
- } |
|
459 |
+ closest_timeout = 0; |
|
460 |
+ for (i = 0; i < data->nfds; i++) |
|
461 |
+ { |
|
462 |
+ time_t timeout_at = data->buf[i].timeout_at; |
|
463 |
+ if (timeout_at && timeout_at < now) |
|
464 |
+ { |
|
465 |
+ /* timed out */ |
|
466 |
+ data->buf[i].got_newdata = -2; |
|
467 |
+ /* we must return immediately from poll/select, we have a timeout! */ |
|
468 |
+ closest_timeout = now; |
|
469 |
+ } |
|
470 |
+ else |
|
471 |
+ { |
|
472 |
+ if (!closest_timeout) |
|
473 |
+ closest_timeout = timeout_at; |
|
474 |
+ else if (timeout_at && timeout_at < closest_timeout) |
|
475 |
+ closest_timeout = timeout_at; |
|
476 |
+ } |
|
472 | 477 |
} |
473 | 478 |
if (closest_timeout) |
474 |
- timeout = closest_timeout - now; |
|
479 |
+ timeout = closest_timeout - now; |
|
475 | 480 |
else |
476 |
- timeout = -1; |
|
481 |
+ timeout = -1; |
|
477 | 482 |
if (timeout > 0) |
478 |
- logg("$fds_poll_recv: timeout after %d seconds\n", timeout); |
|
483 |
+ logg ("$fds_poll_recv: timeout after %d seconds\n", timeout); |
|
479 | 484 |
#ifdef HAVE_POLL |
480 | 485 |
/* Use poll() if available, preferred because: |
481 | 486 |
* - can poll any number of FDs |
... | ... |
@@ -485,194 +552,240 @@ int fds_poll_recv(struct fd_data *data, int timeout, int check_signals, void *ev |
485 | 485 |
* recv() may still block according to the manpage |
486 | 486 |
*/ |
487 | 487 |
|
488 |
- if (realloc_polldata(data) == -1) |
|
489 |
- return -1; |
|
490 |
- if (timeout > 0) { |
|
491 |
- /* seconds to ms */ |
|
492 |
- timeout *= 1000; |
|
488 |
+ if (realloc_polldata (data) == -1) |
|
489 |
+ return -1; |
|
490 |
+ if (timeout > 0) |
|
491 |
+ { |
|
492 |
+ /* seconds to ms */ |
|
493 |
+ timeout *= 1000; |
|
493 | 494 |
} |
494 |
- for (i=0;i < data->nfds;i++) { |
|
495 |
- data->poll_data[i].fd = data->buf[i].fd; |
|
496 |
- data->poll_data[i].events = POLLIN; |
|
497 |
- data->poll_data[i].revents = 0; |
|
495 |
+ for (i = 0; i < data->nfds; i++) |
|
496 |
+ { |
|
497 |
+ data->poll_data[i].fd = data->buf[i].fd; |
|
498 |
+ data->poll_data[i].events = POLLIN; |
|
499 |
+ data->poll_data[i].revents = 0; |
|
498 | 500 |
} |
499 |
- do { |
|
500 |
- int n = data->nfds; |
|
501 |
+ do |
|
502 |
+ { |
|
503 |
+ int n = data->nfds; |
|
501 | 504 |
|
502 |
- fds_unlock(data); |
|
505 |
+ fds_unlock (data); |
|
503 | 506 |
#ifdef _WIN32 |
504 |
- retval = poll_with_event(data->poll_data, n, timeout, event); |
|
507 |
+ retval = poll_with_event (data->poll_data, n, timeout, event); |
|
505 | 508 |
#else |
506 |
- retval = poll(data->poll_data, n, timeout); |
|
509 |
+ retval = poll (data->poll_data, n, timeout); |
|
507 | 510 |
#endif |
508 |
- fds_lock(data); |
|
509 |
- |
|
510 |
- if (retval > 0) { |
|
511 |
- fdsok = 0; |
|
512 |
- /* nfds may change during poll, but not |
|
513 |
- * poll_data_nfds */ |
|
514 |
- for (i=0;i < data->poll_data_nfds; i++) { |
|
515 |
- short revents; |
|
516 |
- if (data->buf[i].fd < 0) |
|
517 |
- continue; |
|
518 |
- if (data->buf[i].fd != data->poll_data[i].fd) { |
|
519 |
- /* should never happen */ |
|
520 |
- logg("!poll_recv_fds FD mismatch\n"); |
|
521 |
- continue; |
|
522 |
- } |
|
523 |
- revents = data->poll_data[i].revents; |
|
524 |
- if (revents & (POLLIN|POLLHUP)) { |
|
525 |
- logg("$Received POLLIN|POLLHUP on fd %d\n",data->poll_data[i].fd); |
|
526 |
- } |
|
511 |
+ fds_lock (data); |
|
512 |
+ |
|
513 |
+ if (retval > 0) |
|
514 |
+ { |
|
515 |
+ fdsok = 0; |
|
516 |
+ /* nfds may change during poll, but not |
|
517 |
+ * poll_data_nfds */ |
|
518 |
+ for (i = 0; i < data->poll_data_nfds; i++) |
|
519 |
+ { |
|
520 |
+ short revents; |
|
521 |
+ if (data->buf[i].fd < 0) |
|
522 |
+ continue; |
|
523 |
+ if (data->buf[i].fd != data->poll_data[i].fd) |
|
524 |
+ { |
|
525 |
+ /* should never happen */ |
|
526 |
+ logg ("!poll_recv_fds FD mismatch\n"); |
|
527 |
+ continue; |
|
528 |
+ } |
|
529 |
+ revents = data->poll_data[i].revents; |
|
530 |
+ if (revents & (POLLIN | POLLHUP)) |
|
531 |
+ { |
|
532 |
+ logg ("$Received POLLIN|POLLHUP on fd %d\n", |
|
533 |
+ data->poll_data[i].fd); |
|
534 |
+ } |
|
527 | 535 |
#ifndef _WIN32 |
528 |
- if (revents & POLLHUP) { |
|
529 |
- /* avoid SHUT_WR problem on Mac OS X */ |
|
530 |
- int ret = send(data->poll_data[i].fd, &n, 0, 0); |
|
531 |
- if (!ret || (ret == -1 && errno == EINTR)) |
|
532 |
- revents &= ~POLLHUP; |
|
533 |
- } |
|
536 |
+ if (revents & POLLHUP) |
|
537 |
+ { |
|
538 |
+ /* avoid SHUT_WR problem on Mac OS X */ |
|
539 |
+ int ret = send (data->poll_data[i].fd, &n, 0, 0); |
|
540 |
+ if (!ret || (ret == -1 && errno == EINTR)) |
|
541 |
+ revents &= ~POLLHUP; |
|
542 |
+ } |
|
534 | 543 |
#endif |
535 |
- if (revents & POLLIN) { |
|
536 |
- int ret = read_fd_data(&data->buf[i]); |
|
537 |
- /* Data available to be read */ |
|
538 |
- if (ret == -1) |
|
539 |
- revents |= POLLERR; |
|
540 |
- else if (!ret) |
|
541 |
- revents = POLLHUP; |
|
542 |
- } |
|
543 |
- |
|
544 |
- if (revents & (POLLHUP | POLLERR | POLLNVAL)) { |
|
545 |
- if (revents & (POLLHUP| POLLNVAL)) { |
|
546 |
- /* remote disconnected */ |
|
547 |
- logg("*Client disconnected (FD %d)\n", |
|
548 |
- data->poll_data[i].fd); |
|
549 |
- } else { |
|
550 |
- /* error on file descriptor */ |
|
551 |
- logg("^Error condition on fd %d\n", |
|
552 |
- data->poll_data[i].fd); |
|
553 |
- } |
|
554 |
- data->buf[i].got_newdata = -1; |
|
555 |
- } else { |
|
556 |
- fdsok++; |
|
557 |
- } |
|
558 |
- } |
|
559 |
- } |
|
560 |
- } while (retval == -1 && !check_signals && errno == EINTR); |
|
544 |
+ if (revents & POLLIN) |
|
545 |
+ { |
|
546 |
+ int ret = read_fd_data (&data->buf[i]); |
|
547 |
+ /* Data available to be read */ |
|
548 |
+ if (ret == -1) |
|
549 |
+ revents |= POLLERR; |
|
550 |
+ else if (!ret) |
|
551 |
+ revents = POLLHUP; |
|
552 |
+ } |
|
553 |
+ |
|
554 |
+ if (revents & (POLLHUP | POLLERR | POLLNVAL)) |
|
555 |
+ { |
|
556 |
+ if (revents & (POLLHUP | POLLNVAL)) |
|
557 |
+ { |
|
558 |
+ /* remote disconnected */ |
|
559 |
+ logg ("*Client disconnected (FD %d)\n", |
|
560 |
+ data->poll_data[i].fd); |
|
561 |
+ } |
|
562 |
+ else |
|
563 |
+ { |
|
564 |
+ /* error on file descriptor */ |
|
565 |
+ logg ("^Error condition on fd %d\n", |
|
566 |
+ data->poll_data[i].fd); |
|
567 |
+ } |
|
568 |
+ data->buf[i].got_newdata = -1; |
|
569 |
+ } |
|
570 |
+ else |
|
571 |
+ { |
|
572 |
+ fdsok++; |
|
573 |
+ } |
|
574 |
+ } |
|
575 |
+ } |
|
576 |
+ } |
|
577 |
+ while (retval == -1 && !check_signals && errno == EINTR); |
|
561 | 578 |
#else |
562 | 579 |
{ |
563 |
- fd_set rfds; |
|
564 |
- struct timeval tv; |
|
565 |
- int maxfd = -1; |
|
566 |
- |
|
567 |
- for (i=0;i < data->nfds; i++) { |
|
568 |
- int fd = data->buf[i].fd; |
|
569 |
- if (fd >= FD_SETSIZE) { |
|
570 |
- logg ("!File descriptor is too high for FD_SET\n"); |
|
571 |
- return -1; |
|
572 |
- } |
|
573 |
- |
|
574 |
- maxfd = MAX(maxfd, fd); |
|
575 |
- } |
|
576 |
- |
|
577 |
- do { |
|
578 |
- FD_ZERO(&rfds); |
|
579 |
- for(i=0;i < data->nfds;i++) { |
|
580 |
- int fd = data->buf[i].fd; |
|
581 |
- if (fd >= 0) |
|
582 |
- FD_SET(fd, &rfds); |
|
583 |
- } |
|
584 |
- tv.tv_sec = timeout; |
|
585 |
- tv.tv_usec = 0; |
|
586 |
- |
|
587 |
- fds_unlock(data); |
|
588 |
- retval = select(maxfd+1, &rfds, NULL, NULL, timeout >= 0 ? &tv : NULL); |
|
589 |
- fds_lock(data); |
|
590 |
- if (retval > 0) { |
|
591 |
- fdsok = data->nfds; |
|
592 |
- for (i=0; i < data->nfds; i++) { |
|
593 |
- if (data->buf[i].fd < 0) { |
|
594 |
- fdsok--; |
|
595 |
- continue; |
|
596 |
- } |
|
597 |
- if (FD_ISSET(data->buf[i].fd, &rfds)) { |
|
598 |
- int ret = read_fd_data(&data->buf[i]); |
|
599 |
- if (ret == -1 || !ret) { |
|
600 |
- if (ret == -1) |
|
601 |
- logg("!Error condition on fd %d\n", |
|
602 |
- data->buf[i].fd); |
|
603 |
- else { |
|
604 |
- /* avoid SHUT_WR problem on Mac OS X */ |
|
605 |
- int ret = send(data->buf[i].fd, &i, 0, 0); |
|
606 |
- if (!ret || (ret == -1 && errno == EINTR)) |
|
607 |
- continue; |
|
608 |
- logg("*Client disconnected\n"); |
|
609 |
- } |
|
610 |
- data->buf[i].got_newdata = -1; |
|
611 |
- } |
|
612 |
- } |
|
613 |
- } |
|
614 |
- } |
|
615 |
- if (retval < 0 && errno == EBADF) { |
|
616 |
- /* unlike poll(), select() won't tell us which FD is bad, so |
|
617 |
- * we have to check them one by one. */ |
|
618 |
- tv.tv_sec = 0; |
|
619 |
- tv.tv_usec = 0; |
|
620 |
- /* with tv == 0 it doesn't check for EBADF */ |
|
621 |
- FD_ZERO(&rfds); |
|
622 |
- for (i=0; i< data->nfds; i++) { |
|
623 |
- if (data->buf[i].fd == -1) |
|
624 |
- continue; |
|
625 |
- FD_SET(data->buf[i].fd, &rfds); |
|
626 |
- do { |
|
627 |
- retval = select(data->buf[i].fd+1, &rfds, NULL, NULL, &tv); |
|
628 |
- } while (retval == -1 && errno == EINTR); |
|
629 |
- if (retval == -1) { |
|
630 |
- data->buf[i].fd = -1; |
|
631 |
- } else { |
|
632 |
- FD_CLR(data->buf[i].fd, &rfds); |
|
633 |
- } |
|
634 |
- } |
|
635 |
- retval = -1; |
|
636 |
- errno = EINTR; |
|
637 |
- continue; |
|
638 |
- } |
|
639 |
- } while (retval == -1 && !check_signals && errno == EINTR); |
|
580 |
+ fd_set rfds; |
|
581 |
+ struct timeval tv; |
|
582 |
+ int maxfd = -1; |
|
583 |
+ |
|
584 |
+ for (i = 0; i < data->nfds; i++) |
|
585 |
+ { |
|
586 |
+ int fd = data->buf[i].fd; |
|
587 |
+ if (fd >= FD_SETSIZE) |
|
588 |
+ { |
|
589 |
+ logg ("!File descriptor is too high for FD_SET\n"); |
|
590 |
+ return -1; |
|
591 |
+ } |
|
592 |
+ |
|
593 |
+ maxfd = MAX (maxfd, fd); |
|
594 |
+ } |
|
595 |
+ |
|
596 |
+ do |
|
597 |
+ { |
|
598 |
+ FD_ZERO (&rfds); |
|
599 |
+ for (i = 0; i < data->nfds; i++) |
|
600 |
+ { |
|
601 |
+ int fd = data->buf[i].fd; |
|
602 |
+ if (fd >= 0) |
|
603 |
+ FD_SET (fd, &rfds); |
|
604 |
+ } |
|
605 |
+ tv.tv_sec = timeout; |
|
606 |
+ tv.tv_usec = 0; |
|
607 |
+ |
|
608 |
+ fds_unlock (data); |
|
609 |
+ retval = |
|
610 |
+ select (maxfd + 1, &rfds, NULL, NULL, |
|
611 |
+ timeout >= 0 ? &tv : NULL); |
|
612 |
+ fds_lock (data); |
|
613 |
+ if (retval > 0) |
|
614 |
+ { |
|
615 |
+ fdsok = data->nfds; |
|
616 |
+ for (i = 0; i < data->nfds; i++) |
|
617 |
+ { |
|
618 |
+ if (data->buf[i].fd < 0) |
|
619 |
+ { |
|
620 |
+ fdsok--; |
|
621 |
+ continue; |
|
622 |
+ } |
|
623 |
+ if (FD_ISSET (data->buf[i].fd, &rfds)) |
|
624 |
+ { |
|
625 |
+ int ret = read_fd_data (&data->buf[i]); |
|
626 |
+ if (ret == -1 || !ret) |
|
627 |
+ { |
|
628 |
+ if (ret == -1) |
|
629 |
+ logg ("!Error condition on fd %d\n", |
|
630 |
+ data->buf[i].fd); |
|
631 |
+ else |
|
632 |
+ { |
|
633 |
+ /* avoid SHUT_WR problem on Mac OS X */ |
|
634 |
+ int ret = send (data->buf[i].fd, &i, 0, 0); |
|
635 |
+ if (!ret || (ret == -1 && errno == EINTR)) |
|
636 |
+ continue; |
|
637 |
+ logg ("*Client disconnected\n"); |
|
638 |
+ } |
|
639 |
+ data->buf[i].got_newdata = -1; |
|
640 |
+ } |
|
641 |
+ } |
|
642 |
+ } |
|
643 |
+ } |
|
644 |
+ if (retval < 0 && errno == EBADF) |
|
645 |
+ { |
|
646 |
+ /* unlike poll(), select() won't tell us which FD is bad, so |
|
647 |
+ * we have to check them one by one. */ |
|
648 |
+ tv.tv_sec = 0; |
|
649 |
+ tv.tv_usec = 0; |
|
650 |
+ /* with tv == 0 it doesn't check for EBADF */ |
|
651 |
+ FD_ZERO (&rfds); |
|
652 |
+ for (i = 0; i < data->nfds; i++) |
|
653 |
+ { |
|
654 |
+ if (data->buf[i].fd == -1) |
|
655 |
+ continue; |
|
656 |
+ FD_SET (data->buf[i].fd, &rfds); |
|
657 |
+ do |
|
658 |
+ { |
|
659 |
+ retval = |
|
660 |
+ select (data->buf[i].fd + 1, &rfds, NULL, NULL, |
|
661 |
+ &tv); |
|
662 |
+ } |
|
663 |
+ while (retval == -1 && errno == EINTR); |
|
664 |
+ if (retval == -1) |
|
665 |
+ { |
|
666 |
+ data->buf[i].fd = -1; |
|
667 |
+ } |
|
668 |
+ else |
|
669 |
+ { |
|
670 |
+ FD_CLR (data->buf[i].fd, &rfds); |
|
671 |
+ } |
|
672 |
+ } |
|
673 |
+ retval = -1; |
|
674 |
+ errno = EINTR; |
|
675 |
+ continue; |
|
676 |
+ } |
|
677 |
+ } |
|
678 |
+ while (retval == -1 && !check_signals && errno == EINTR); |
|
640 | 679 |
} |
641 | 680 |
#endif |
642 | 681 |
|
643 |
- if (retval == -1 && errno != EINTR) { |
|
644 |
- char err[128]; |
|
682 |
+ if (retval == -1 && errno != EINTR) |
|
683 |
+ { |
|
684 |
+ char err[128]; |
|
645 | 685 |
#ifdef HAVE_POLL |
646 |
- logg("!poll_recv_fds: poll failed: %s\n", cli_strerror(errno, err, sizeof(err))); |
|
686 |
+ logg ("!poll_recv_fds: poll failed: %s\n", |
|
687 |
+ cli_strerror (errno, err, sizeof (err))); |
|
647 | 688 |
#else |
648 |
- logg("!poll_recv_fds: select failed: %s\n", cli_strerror(errno, err, sizeof(err))); |
|
689 |
+ logg ("!poll_recv_fds: select failed: %s\n", |
|
690 |
+ cli_strerror (errno, err, sizeof (err))); |
|
649 | 691 |
#endif |
650 | 692 |
} |
651 | 693 |
|
652 | 694 |
return retval; |
653 | 695 |
} |
654 | 696 |
|
655 |
-void fds_free(struct fd_data *data) |
|
697 |
+void |
|
698 |
+fds_free (struct fd_data *data) |
|
656 | 699 |
{ |
657 | 700 |
unsigned i; |
658 |
- fds_lock(data); |
|
659 |
- for (i=0;i < data->nfds;i++) { |
|
660 |
- if (data->buf[i].buffer) { |
|
661 |
- free(data->buf[i].buffer); |
|
662 |
- } |
|
701 |
+ fds_lock (data); |
|
702 |
+ for (i = 0; i < data->nfds; i++) |
|
703 |
+ { |
|
704 |
+ if (data->buf[i].buffer) |
|
705 |
+ { |
|
706 |
+ free (data->buf[i].buffer); |
|
707 |
+ } |
|
663 | 708 |
} |
664 | 709 |
if (data->buf) |
665 |
- free(data->buf); |
|
710 |
+ free (data->buf); |
|
666 | 711 |
#ifdef HAVE_POLL |
667 | 712 |
if (data->poll_data) |
668 |
- free(data->poll_data); |
|
713 |
+ free (data->poll_data); |
|
669 | 714 |
#endif |
670 | 715 |
data->buf = NULL; |
671 | 716 |
data->nfds = 0; |
672 |
- fds_unlock(data); |
|
717 |
+ fds_unlock (data); |
|
673 | 718 |
} |
674 | 719 |
|
675 |
-struct detstats_s { |
|
720 |
+struct detstats_s |
|
721 |
+{ |
|
676 | 722 |
char virname[128]; |
677 | 723 |
char fname[128]; |
678 | 724 |
char md5[33]; |
... | ... |
@@ -683,63 +796,80 @@ struct detstats_s { |
683 | 683 |
static struct detstats_s detstats_data[DETSTATS_MAX]; |
684 | 684 |
static unsigned int detstats_idx = 0, detstats_total = 0; |
685 | 685 |
|
686 |
-void detstats_clear(void) |
|
686 |
+void |
|
687 |
+detstats_clear (void) |
|
687 | 688 |
{ |
688 |
- pthread_mutex_lock(&detstats_lock); |
|
689 |
+ pthread_mutex_lock (&detstats_lock); |
|
689 | 690 |
detstats_idx = detstats_total = 0; |
690 |
- pthread_mutex_unlock(&detstats_lock); |
|
691 |
+ pthread_mutex_unlock (&detstats_lock); |
|
691 | 692 |
} |
692 | 693 |
|
693 |
-void detstats_add(const char *virname, const char *fname, unsigned int fsize, const char *md5) |
|
694 |
+void |
|
695 |
+detstats_add (const char *virname, const char *fname, unsigned int fsize, |
|
696 |
+ const char *md5) |
|
694 | 697 |
{ |
695 |
- pthread_mutex_lock(&detstats_lock); |
|
696 |
- |
|
697 |
- strncpy(detstats_data[detstats_idx].virname, virname, sizeof(detstats_data[detstats_idx].virname)); |
|
698 |
- detstats_data[detstats_idx].virname[sizeof(detstats_data[detstats_idx].virname) - 1] = 0; |
|
699 |
- |
|
700 |
- if((fname = strrchr(fname, *PATHSEP))) |
|
701 |
- fname++; |
|
702 |
- strncpy(detstats_data[detstats_idx].fname, (!fname || !strlen(fname)) ? "NOFNAME" : fname, sizeof(detstats_data[detstats_idx].fname)); |
|
703 |
- detstats_data[detstats_idx].fname[sizeof(detstats_data[detstats_idx].fname) - 1] = 0; |
|
704 |
- |
|
705 |
- strncpy(detstats_data[detstats_idx].md5, md5, sizeof(detstats_data[detstats_idx].md5)); |
|
706 |
- detstats_data[detstats_idx].md5[sizeof(detstats_data[detstats_idx].md5) - 1] = 0; |
|
698 |
+ pthread_mutex_lock (&detstats_lock); |
|
699 |
+ |
|
700 |
+ strncpy (detstats_data[detstats_idx].virname, virname, |
|
701 |
+ sizeof (detstats_data[detstats_idx].virname)); |
|
702 |
+ detstats_data[detstats_idx]. |
|
703 |
+ virname[sizeof (detstats_data[detstats_idx].virname) - 1] = 0; |
|
704 |
+ |
|
705 |
+ if ((fname = strrchr (fname, *PATHSEP))) |
|
706 |
+ fname++; |
|
707 |
+ strncpy (detstats_data[detstats_idx].fname, |
|
708 |
+ (!fname |
|
709 |
+ || !strlen (fname)) ? "NOFNAME" : fname, |
|
710 |
+ sizeof (detstats_data[detstats_idx].fname)); |
|
711 |
+ detstats_data[detstats_idx]. |
|
712 |
+ fname[sizeof (detstats_data[detstats_idx].fname) - 1] = 0; |
|
713 |
+ |
|
714 |
+ strncpy (detstats_data[detstats_idx].md5, md5, |
|
715 |
+ sizeof (detstats_data[detstats_idx].md5)); |
|
716 |
+ detstats_data[detstats_idx].md5[sizeof (detstats_data[detstats_idx].md5) - |
|
717 |
+ 1] = 0; |
|
707 | 718 |
|
708 | 719 |
detstats_data[detstats_idx].fsize = fsize; |
709 |
- detstats_data[detstats_idx++].time = time(NULL); |
|
710 |
- if(detstats_idx == DETSTATS_MAX) |
|
711 |
- detstats_idx = 0; |
|
720 |
+ detstats_data[detstats_idx++].time = time (NULL); |
|
721 |
+ if (detstats_idx == DETSTATS_MAX) |
|
722 |
+ detstats_idx = 0; |
|
712 | 723 |
detstats_total++; |
713 |
- pthread_mutex_unlock(&detstats_lock); |
|
724 |
+ pthread_mutex_unlock (&detstats_lock); |
|
714 | 725 |
} |
715 | 726 |
|
716 |
-void detstats_print(int desc, char term) |
|
727 |
+void |
|
728 |
+detstats_print (int desc, char term) |
|
717 | 729 |
{ |
718 |
- unsigned int i; |
|
719 |
- |
|
720 |
- pthread_mutex_lock(&detstats_lock); |
|
721 |
- for(i = 0; i < DETSTATS_MAX && i < detstats_total; i++) |
|
722 |
- mdprintf(desc, "%u:%s:%u:%s:%s%c", detstats_data[i].time, detstats_data[i].md5, detstats_data[i].fsize, detstats_data[i].virname, detstats_data[i].fname, term); |
|
723 |
- pthread_mutex_unlock(&detstats_lock); |
|
730 |
+ unsigned int i; |
|
731 |
+ |
|
732 |
+ pthread_mutex_lock (&detstats_lock); |
|
733 |
+ for (i = 0; i < DETSTATS_MAX && i < detstats_total; i++) |
|
734 |
+ mdprintf (desc, "%u:%s:%u:%s:%s%c", detstats_data[i].time, |
|
735 |
+ detstats_data[i].md5, detstats_data[i].fsize, |
|
736 |
+ detstats_data[i].virname, detstats_data[i].fname, term); |
|
737 |
+ pthread_mutex_unlock (&detstats_lock); |
|
724 | 738 |
} |
725 | 739 |
|
726 | 740 |
#ifdef FANOTIFY |
727 |
-int fan_checkowner(int pid, const struct optstruct *opts) |
|
741 |
+int |
|
742 |
+fan_checkowner (int pid, const struct optstruct *opts) |
|
728 | 743 |
{ |
729 |
- char path[32]; |
|
730 |
- struct stat sb; |
|
731 |
- const struct optstruct *opt; |
|
732 |
- |
|
733 |
- if(!(opt = optget(opts, "OnAccessExcludeUID"))->enabled) |
|
734 |
- return 0; |
|
735 |
- |
|
736 |
- snprintf(path, sizeof(path), "/proc/%u", pid); |
|
737 |
- if(stat(path, &sb) == 0) { |
|
738 |
- while(opt) { |
|
739 |
- if(opt->numarg == (long long) sb.st_uid) |
|
740 |
- return 1; |
|
741 |
- opt = opt->nextarg; |
|
742 |
- } |
|
744 |
+ char path[32]; |
|
745 |
+ struct stat sb; |
|
746 |
+ const struct optstruct *opt; |
|
747 |
+ |
|
748 |
+ if (!(opt = optget (opts, "OnAccessExcludeUID"))->enabled) |
|
749 |
+ return 0; |
|
750 |
+ |
|
751 |
+ snprintf (path, sizeof (path), "/proc/%u", pid); |
|
752 |
+ if (stat (path, &sb) == 0) |
|
753 |
+ { |
|
754 |
+ while (opt) |
|
755 |
+ { |
|
756 |
+ if (opt->numarg == (long long) sb.st_uid) |
|
757 |
+ return 1; |
|
758 |
+ opt = opt->nextarg; |
|
759 |
+ } |
|
743 | 760 |
} |
744 | 761 |
return 0; |
745 | 762 |
} |