aboutsummaryrefslogtreecommitdiff
path: root/src/main/extractor_ipc_gnu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/extractor_ipc_gnu.c')
-rw-r--r--src/main/extractor_ipc_gnu.c389
1 files changed, 195 insertions, 194 deletions
diff --git a/src/main/extractor_ipc_gnu.c b/src/main/extractor_ipc_gnu.c
index 7bb8914..5400636 100644
--- a/src/main/extractor_ipc_gnu.c
+++ b/src/main/extractor_ipc_gnu.c
@@ -138,10 +138,10 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size)
138 const char *tpath; 138 const char *tpath;
139 139
140 if (NULL == (shm = malloc (sizeof (struct EXTRACTOR_SharedMemory)))) 140 if (NULL == (shm = malloc (sizeof (struct EXTRACTOR_SharedMemory))))
141 { 141 {
142 LOG_STRERROR ("malloc"); 142 LOG_STRERROR ("malloc");
143 return NULL; 143 return NULL;
144 } 144 }
145#if SOMEBSD 145#if SOMEBSD
146 /* this works on FreeBSD, not sure about others... */ 146 /* this works on FreeBSD, not sure about others... */
147 tpath = getenv ("TMPDIR"); 147 tpath = getenv ("TMPDIR");
@@ -151,24 +151,24 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size)
151 tpath = "/"; /* Linux */ 151 tpath = "/"; /* Linux */
152#endif 152#endif
153 snprintf (shm->shm_name, 153 snprintf (shm->shm_name,
154 MAX_SHM_NAME, 154 MAX_SHM_NAME,
155 "%sLE-%u-%u", 155 "%sLE-%u-%u",
156 tpath, getpid (), 156 tpath, getpid (),
157 (unsigned int) RANDOM()); 157 (unsigned int) RANDOM ());
158 if (-1 == (shm->shm_id = shm_open (shm->shm_name, 158 if (-1 == (shm->shm_id = shm_open (shm->shm_name,
159 O_RDWR | O_CREAT, S_IRUSR | S_IWUSR))) 159 O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)))
160 { 160 {
161 LOG_STRERROR_FILE ("shm_open", 161 LOG_STRERROR_FILE ("shm_open",
162 shm->shm_name); 162 shm->shm_name);
163 free (shm); 163 free (shm);
164 return NULL; 164 return NULL;
165 } 165 }
166 if ( (0 != ftruncate (shm->shm_id, size)) || 166 if ( (0 != ftruncate (shm->shm_id, size)) ||
167 (NULL == (shm->shm_ptr = mmap (NULL, 167 (NULL == (shm->shm_ptr = mmap (NULL,
168 size, 168 size,
169 PROT_WRITE, 169 PROT_WRITE,
170 MAP_SHARED, 170 MAP_SHARED,
171 shm->shm_id, 171 shm->shm_id,
172 0))) || 172 0))) ||
173 (((void*) -1) == shm->shm_ptr) ) 173 (((void*) -1) == shm->shm_ptr) )
174 { 174 {
@@ -193,7 +193,7 @@ EXTRACTOR_IPC_shared_memory_create_ (size_t size)
193 */ 193 */
194unsigned int 194unsigned int
195EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm, 195EXTRACTOR_IPC_shared_memory_change_rc_ (struct EXTRACTOR_SharedMemory *shm,
196 int delta) 196 int delta)
197{ 197{
198 shm->rc += delta; 198 shm->rc += delta;
199 return shm->rc; 199 return shm->rc;
@@ -228,23 +228,23 @@ EXTRACTOR_IPC_shared_memory_destroy_ (struct EXTRACTOR_SharedMemory *shm)
228 */ 228 */
229ssize_t 229ssize_t
230EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm, 230EXTRACTOR_IPC_shared_memory_set_ (struct EXTRACTOR_SharedMemory *shm,
231 struct EXTRACTOR_Datasource *ds, 231 struct EXTRACTOR_Datasource *ds,
232 uint64_t off, 232 uint64_t off,
233 size_t size) 233 size_t size)
234{ 234{
235 if (-1 == 235 if (-1 ==
236 EXTRACTOR_datasource_seek_ (ds, 236 EXTRACTOR_datasource_seek_ (ds,
237 off, 237 off,
238 SEEK_SET)) 238 SEEK_SET))
239 { 239 {
240 LOG ("Failed to set IPC memory due to seek error\n"); 240 LOG ("Failed to set IPC memory due to seek error\n");
241 return -1; 241 return -1;
242 } 242 }
243 if (size > shm->shm_size) 243 if (size > shm->shm_size)
244 size = shm->shm_size; 244 size = shm->shm_size;
245 return EXTRACTOR_datasource_read_ (ds, 245 return EXTRACTOR_datasource_read_ (ds,
246 shm->shm_ptr, 246 shm->shm_ptr,
247 size); 247 size);
248} 248}
249 249
250 250
@@ -277,7 +277,7 @@ EXTRACTOR_datasource_get_pos_ (struct EXTRACTOR_Datasource *ds)
277 */ 277 */
278struct EXTRACTOR_Channel * 278struct EXTRACTOR_Channel *
279EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin, 279EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin,
280 struct EXTRACTOR_SharedMemory *shm) 280 struct EXTRACTOR_SharedMemory *shm)
281{ 281{
282 struct EXTRACTOR_Channel *channel; 282 struct EXTRACTOR_Channel *channel;
283 int p1[2]; 283 int p1[2];
@@ -287,74 +287,74 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin,
287 size_t slen; 287 size_t slen;
288 288
289 if (NULL == (channel = malloc (sizeof (struct EXTRACTOR_Channel)))) 289 if (NULL == (channel = malloc (sizeof (struct EXTRACTOR_Channel))))
290 { 290 {
291 LOG_STRERROR ("malloc"); 291 LOG_STRERROR ("malloc");
292 return NULL; 292 return NULL;
293 } 293 }
294 channel->mdata_size = 1024; 294 channel->mdata_size = 1024;
295 if (NULL == (channel->mdata = malloc (channel->mdata_size))) 295 if (NULL == (channel->mdata = malloc (channel->mdata_size)))
296 { 296 {
297 LOG_STRERROR ("malloc"); 297 LOG_STRERROR ("malloc");
298 free (channel); 298 free (channel);
299 return NULL; 299 return NULL;
300 } 300 }
301 channel->shm = shm; 301 channel->shm = shm;
302 channel->plugin = plugin; 302 channel->plugin = plugin;
303 channel->size = 0; 303 channel->size = 0;
304 if (0 != pipe (p1)) 304 if (0 != pipe (p1))
305 { 305 {
306 LOG_STRERROR ("pipe"); 306 LOG_STRERROR ("pipe");
307 free (channel->mdata); 307 free (channel->mdata);
308 free (channel); 308 free (channel);
309 return NULL; 309 return NULL;
310 } 310 }
311 if (0 != pipe (p2)) 311 if (0 != pipe (p2))
312 { 312 {
313 LOG_STRERROR ("pipe"); 313 LOG_STRERROR ("pipe");
314 (void) close (p1[0]); 314 (void) close (p1[0]);
315 (void) close (p1[1]); 315 (void) close (p1[1]);
316 free (channel->mdata); 316 free (channel->mdata);
317 free (channel); 317 free (channel);
318 return NULL; 318 return NULL;
319 } 319 }
320 pid = fork (); 320 pid = fork ();
321 if (pid == -1) 321 if (pid == -1)
322 { 322 {
323 LOG_STRERROR ("fork"); 323 LOG_STRERROR ("fork");
324 (void) close (p1[0]); 324 (void) close (p1[0]);
325 (void) close (p1[1]); 325 (void) close (p1[1]);
326 (void) close (p2[0]); 326 (void) close (p2[0]);
327 (void) close (p2[1]); 327 (void) close (p2[1]);
328 free (channel->mdata); 328 free (channel->mdata);
329 free (channel); 329 free (channel);
330 return NULL; 330 return NULL;
331 } 331 }
332 if (0 == pid) 332 if (0 == pid)
333 { 333 {
334 (void) close (p1[1]); 334 (void) close (p1[1]);
335 (void) close (p2[0]); 335 (void) close (p2[0]);
336 free (channel->mdata); 336 free (channel->mdata);
337 free (channel); 337 free (channel);
338#if HAVE_SYS_APPARMOR_H 338#if HAVE_SYS_APPARMOR_H
339#if HAVE_APPARMOR 339#if HAVE_APPARMOR
340 if (0 > aa_change_profile("libextractor")) 340 if (0 > aa_change_profile ("libextractor"))
341 {
342 int eno = errno;
343
344 if ( (EINVAL != eno) &&
345 (ENOENT != eno) )
341 { 346 {
342 int eno = errno; 347 fprintf (stderr,
343 348 "Failure changing AppArmor profile: %s\n",
344 if ( (EINVAL != eno) && 349 strerror (errno));
345 (ENOENT != eno) ) 350 _exit (1);
346 {
347 fprintf (stderr,
348 "Failure changing AppArmor profile: %s\n",
349 strerror (errno));
350 _exit(1);
351 }
352 } 351 }
352 }
353#endif 353#endif
354#endif 354#endif
355 EXTRACTOR_plugin_main_ (plugin, p1[0], p2[1]); 355 EXTRACTOR_plugin_main_ (plugin, p1[0], p2[1]);
356 _exit (0); 356 _exit (0);
357 } 357 }
358 (void) close (p1[0]); 358 (void) close (p1[0]);
359 (void) close (p2[1]); 359 (void) close (p2[1]);
360 channel->cpipe_in = p1[1]; 360 channel->cpipe_in = p1[1];
@@ -362,11 +362,11 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin,
362 channel->cpid = pid; 362 channel->cpid = pid;
363 slen = strlen (shm->shm_name) + 1; 363 slen = strlen (shm->shm_name) + 1;
364 if (NULL == (init = malloc (sizeof (struct InitMessage) + slen))) 364 if (NULL == (init = malloc (sizeof (struct InitMessage) + slen)))
365 { 365 {
366 LOG_STRERROR ("malloc"); 366 LOG_STRERROR ("malloc");
367 EXTRACTOR_IPC_channel_destroy_ (channel); 367 EXTRACTOR_IPC_channel_destroy_ (channel);
368 return NULL; 368 return NULL;
369 } 369 }
370 init->opcode = MESSAGE_INIT_STATE; 370 init->opcode = MESSAGE_INIT_STATE;
371 init->reserved = 0; 371 init->reserved = 0;
372 init->reserved2 = 0; 372 init->reserved2 = 0;
@@ -375,14 +375,14 @@ EXTRACTOR_IPC_channel_create_ (struct EXTRACTOR_PluginList *plugin,
375 memcpy (&init[1], shm->shm_name, slen); 375 memcpy (&init[1], shm->shm_name, slen);
376 if (sizeof (struct InitMessage) + slen != 376 if (sizeof (struct InitMessage) + slen !=
377 EXTRACTOR_IPC_channel_send_ (channel, 377 EXTRACTOR_IPC_channel_send_ (channel,
378 init, 378 init,
379 sizeof (struct InitMessage) + slen) ) 379 sizeof (struct InitMessage) + slen) )
380 { 380 {
381 LOG ("Failed to send INIT_STATE message to plugin\n"); 381 LOG ("Failed to send INIT_STATE message to plugin\n");
382 EXTRACTOR_IPC_channel_destroy_ (channel); 382 EXTRACTOR_IPC_channel_destroy_ (channel);
383 free (init); 383 free (init);
384 return NULL; 384 return NULL;
385 } 385 }
386 free (init); 386 free (init);
387 return channel; 387 return channel;
388} 388}
@@ -425,24 +425,24 @@ EXTRACTOR_IPC_channel_destroy_ (struct EXTRACTOR_Channel *channel)
425 */ 425 */
426ssize_t 426ssize_t
427EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel, 427EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel,
428 const void *data, 428 const void *data,
429 size_t size) 429 size_t size)
430{ 430{
431 const char *cdata = data; 431 const char *cdata = data;
432 size_t off = 0; 432 size_t off = 0;
433 ssize_t ret; 433 ssize_t ret;
434 434
435 while (off < size) 435 while (off < size)
436 {
437 ret = write (channel->cpipe_in, &cdata[off], size - off);
438 if (ret <= 0)
436 { 439 {
437 ret = write (channel->cpipe_in, &cdata[off], size - off); 440 if (-1 == ret)
438 if (ret <= 0) 441 LOG_STRERROR ("write");
439 { 442 return -1;
440 if (-1 == ret)
441 LOG_STRERROR ("write");
442 return -1;
443 }
444 off += ret;
445 } 443 }
444 off += ret;
445 }
446 return size; 446 return size;
447} 447}
448 448
@@ -464,9 +464,9 @@ EXTRACTOR_IPC_channel_send_ (struct EXTRACTOR_Channel *channel,
464 */ 464 */
465int 465int
466EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels, 466EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels,
467 unsigned int num_channels, 467 unsigned int num_channels,
468 EXTRACTOR_ChannelMessageProcessor proc, 468 EXTRACTOR_ChannelMessageProcessor proc,
469 void *proc_cls) 469 void *proc_cls)
470{ 470{
471 struct timeval tv; 471 struct timeval tv;
472 fd_set to_check; 472 fd_set to_check;
@@ -480,105 +480,106 @@ EXTRACTOR_IPC_channel_recv_ (struct EXTRACTOR_Channel **channels,
480 480
481 FD_ZERO (&to_check); 481 FD_ZERO (&to_check);
482 max = -1; 482 max = -1;
483 for (i=0;i<num_channels;i++) 483 for (i = 0; i<num_channels; i++)
484 {
485 channel = channels[i];
486 if (NULL == channel)
487 continue;
488 FD_SET (channel->cpipe_out, &to_check);
489 if (max < channel->cpipe_out)
490 max = channel->cpipe_out;
491 }
492 if (-1 == max)
493 {
494 return 1; /* nothing left to do! */
495 }
496 tv.tv_sec = 0;
497 tv.tv_usec = 500000; /* 500 ms */
498 if (0 >= select (max + 1, &to_check, NULL, NULL, &tv))
499 {
500 /* an error or timeout -> something's wrong or all plugins hung up */
501 closed_channel = 0;
502 for (i = 0; i<num_channels; i++)
484 { 503 {
485 channel = channels[i]; 504 channel = channels[i];
486 if (NULL == channel) 505 if (NULL == channel)
487 continue; 506 continue;
488 FD_SET (channel->cpipe_out, &to_check); 507 if (-1 == channel->plugin->seek_request)
489 if (max < channel->cpipe_out) 508 {
490 max = channel->cpipe_out; 509 /* plugin blocked for too long, kill channel */
510 LOG ("Channel blocked, closing channel to %s\n",
511 channel->plugin->libname);
512 channel->plugin->channel = NULL;
513 channel->plugin->round_finished = 1;
514 EXTRACTOR_IPC_channel_destroy_ (channel);
515 channels[i] = NULL;
516 closed_channel = 1;
517 }
491 } 518 }
492 if (-1 == max) 519 if (1 == closed_channel)
520 return 1;
521 /* strange, no channel is to blame, let's die just to be safe */
522 if ((EINTR != errno) && (0 != errno))
523 LOG_STRERROR ("select");
524 return -1;
525 }
526 for (i = 0; i<num_channels; i++)
527 {
528 channel = channels[i];
529 if (NULL == channel)
530 continue;
531 if (! FD_ISSET (channel->cpipe_out, &to_check))
532 continue;
533 if (channel->mdata_size == channel->size)
493 { 534 {
494 return 1; /* nothing left to do! */ 535 /* not enough space, need to grow allocation (if allowed) */
536 if (MAX_META_DATA == channel->mdata_size)
537 {
538 LOG ("Inbound message from channel too large, aborting\n");
539 EXTRACTOR_IPC_channel_destroy_ (channel);
540 channels[i] = NULL;
541 continue;
542 }
543 channel->mdata_size *= 2;
544 if (channel->mdata_size > MAX_META_DATA)
545 channel->mdata_size = MAX_META_DATA;
546 if (NULL == (ndata = realloc (channel->mdata,
547 channel->mdata_size)))
548 {
549 LOG_STRERROR ("realloc");
550 EXTRACTOR_IPC_channel_destroy_ (channel);
551 channels[i] = NULL;
552 continue;
553 }
554 channel->mdata = ndata;
495 } 555 }
496 tv.tv_sec = 0; 556 if ( (-1 == (iret = read (channel->cpipe_out,
497 tv.tv_usec = 500000; /* 500 ms */ 557 &channel->mdata[channel->size],
498 if (0 >= select (max + 1, &to_check, NULL, NULL, &tv)) 558 channel->mdata_size - channel->size)) ) ||
559 (0 == iret) ||
560 (-1 == (ret = EXTRACTOR_IPC_process_reply_ (channel->plugin,
561 channel->mdata,
562 channel->size + iret,
563 proc, proc_cls)) ) )
499 { 564 {
500 /* an error or timeout -> something's wrong or all plugins hung up */ 565 if (-1 == iret)
501 closed_channel = 0; 566 LOG_STRERROR ("read");
502 for (i=0;i<num_channels;i++) 567 LOG ("Read error from channel, closing channel %s\n",
503 { 568 channel->plugin->libname);
504 channel = channels[i]; 569 EXTRACTOR_IPC_channel_destroy_ (channel);
505 if (NULL == channel) 570 channels[i] = NULL;
506 continue; 571 continue;
507 if (-1 == channel->plugin->seek_request)
508 {
509 /* plugin blocked for too long, kill channel */
510 LOG ("Channel blocked, closing channel to %s\n",
511 channel->plugin->libname);
512 channel->plugin->channel = NULL;
513 channel->plugin->round_finished = 1;
514 EXTRACTOR_IPC_channel_destroy_ (channel);
515 channels[i] = NULL;
516 closed_channel = 1;
517 }
518 }
519 if (1 == closed_channel)
520 return 1;
521 /* strange, no channel is to blame, let's die just to be safe */
522 if ((EINTR != errno) && (0 != errno))
523 LOG_STRERROR ("select");
524 return -1;
525 } 572 }
526 for (i=0;i<num_channels;i++) 573 else
527 { 574 {
528 channel = channels[i]; 575 channel->size = channel->size + iret - ret;
529 if (NULL == channel) 576 memmove (channel->mdata,
530 continue; 577 &channel->mdata[ret],
531 if (! FD_ISSET (channel->cpipe_out, &to_check)) 578 channel->size);
532 continue;
533 if (channel->mdata_size == channel->size)
534 {
535 /* not enough space, need to grow allocation (if allowed) */
536 if (MAX_META_DATA == channel->mdata_size)
537 {
538 LOG ("Inbound message from channel too large, aborting\n");
539 EXTRACTOR_IPC_channel_destroy_ (channel);
540 channels[i] = NULL;
541 continue;
542 }
543 channel->mdata_size *= 2;
544 if (channel->mdata_size > MAX_META_DATA)
545 channel->mdata_size = MAX_META_DATA;
546 if (NULL == (ndata = realloc (channel->mdata,
547 channel->mdata_size)))
548 {
549 LOG_STRERROR ("realloc");
550 EXTRACTOR_IPC_channel_destroy_ (channel);
551 channels[i] = NULL;
552 continue;
553 }
554 channel->mdata = ndata;
555 }
556 if ( (-1 == (iret = read (channel->cpipe_out,
557 &channel->mdata[channel->size],
558 channel->mdata_size - channel->size)) ) ||
559 (0 == iret) ||
560 (-1 == (ret = EXTRACTOR_IPC_process_reply_ (channel->plugin,
561 channel->mdata,
562 channel->size + iret,
563 proc, proc_cls)) ) )
564 {
565 if (-1 == iret)
566 LOG_STRERROR ("read");
567 LOG ("Read error from channel, closing channel %s\n",
568 channel->plugin->libname);
569 EXTRACTOR_IPC_channel_destroy_ (channel);
570 channels[i] = NULL;
571 continue;
572 }
573 else
574 {
575 channel->size = channel->size + iret - ret;
576 memmove (channel->mdata,
577 &channel->mdata[ret],
578 channel->size);
579 }
580 } 579 }
580 }
581 return 1; 581 return 1;
582} 582}
583 583
584
584/* end of extractor_ipc_gnu.c */ 585/* end of extractor_ipc_gnu.c */