/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/usplash.c

  • Committer: Björn Påhlsson
  • Date: 2010-09-02 18:53:38 UTC
  • mto: (237.4.3 mandos-release)
  • mto: This revision was merged to the branch mainline in revision 421.
  • Revision ID: belorn@fukt.bsnet.se-20100902185338-d1022sv517txn3sb
early commit to ease todays coding

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <fcntl.h>              /* open(), O_WRONLY, O_RDONLY */
32
32
#include <iso646.h>             /* and, or, not*/
33
33
#include <errno.h>              /* errno, EINTR */
34
 
#include <error.h>
35
34
#include <sys/types.h>          /* size_t, ssize_t, pid_t, DIR, struct
36
35
                                   dirent */
37
36
#include <stddef.h>             /* NULL */
38
37
#include <string.h>             /* strlen(), memcmp() */
39
 
#include <stdio.h>              /* asprintf()*/
 
38
#include <stdio.h>              /* asprintf(), perror() */
40
39
#include <unistd.h>             /* close(), write(), readlink(),
41
40
                                   read(), STDOUT_FILENO, sleep(),
42
41
                                   fork(), setuid(), geteuid(),
154
153
  size_t cmdline_len = 0;
155
154
  DIR *proc_dir = opendir("/proc");
156
155
  if(proc_dir == NULL){
157
 
    error(0, errno, "opendir");
 
156
    perror("opendir");
158
157
    return -1;
159
158
  }
160
159
  errno = 0;
182
181
      char *exe_link;
183
182
      ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name);
184
183
      if(ret == -1){
185
 
        error(0, errno, "asprintf");
 
184
        perror("asprintf");
186
185
        goto fail_find_usplash;
187
186
      }
188
187
      
194
193
          free(exe_link);
195
194
          continue;
196
195
        }
197
 
        error(0, errno, "lstat");
 
196
        perror("lstat");
198
197
        free(exe_link);
199
198
        goto fail_find_usplash;
200
199
      }
225
224
        ret = asprintf(&cmdline_filename, "/proc/%s/cmdline",
226
225
                       proc_ent->d_name);
227
226
        if(ret == -1){
228
 
          error(0, errno, "asprintf");
 
227
          perror("asprintf");
229
228
          goto fail_find_usplash;
230
229
        }
231
230
        cl_fd = open(cmdline_filename, O_RDONLY);
232
231
        free(cmdline_filename);
233
232
        if(cl_fd == -1){
234
 
          error(0, errno, "open");
 
233
          perror("open");
235
234
          goto fail_find_usplash;
236
235
        }
237
236
      }
243
242
        if(cmdline_len + blocksize > cmdline_allocated){
244
243
          tmp = realloc(cmdline, cmdline_allocated + blocksize);
245
244
          if(tmp == NULL){
246
 
            error(0, errno, "realloc");
 
245
            perror("realloc");
247
246
            close(cl_fd);
248
247
            goto fail_find_usplash;
249
248
          }
254
253
        sret = read(cl_fd, cmdline + cmdline_len,
255
254
                    cmdline_allocated - cmdline_len);
256
255
        if(sret == -1){
257
 
          error(0, errno, "read");
 
256
          perror("read");
258
257
          close(cl_fd);
259
258
          goto fail_find_usplash;
260
259
        }
262
261
      } while(sret != 0);
263
262
      ret = close(cl_fd);
264
263
      if(ret == -1){
265
 
        error(0, errno, "close");
 
264
        perror("close");
266
265
        goto fail_find_usplash;
267
266
      }
268
267
    }
269
268
    /* Close directory */
270
269
    ret = closedir(proc_dir);
271
270
    if(ret == -1){
272
 
      error(0, errno, "closedir");
 
271
      perror("closedir");
273
272
      goto fail_find_usplash;
274
273
    }
275
274
    /* Success */
324
323
    sigemptyset(&new_action.sa_mask);
325
324
    ret = sigaddset(&new_action.sa_mask, SIGINT);
326
325
    if(ret == -1){
327
 
      error(0, errno, "sigaddset");
 
326
      perror("sigaddset");
328
327
      status = EX_OSERR;
329
328
      goto failure;
330
329
    }
331
330
    ret = sigaddset(&new_action.sa_mask, SIGHUP);
332
331
    if(ret == -1){
333
 
      error(0, errno, "sigaddset");
 
332
      perror("sigaddset");
334
333
      status = EX_OSERR;
335
334
      goto failure;
336
335
    }
337
336
    ret = sigaddset(&new_action.sa_mask, SIGTERM);
338
337
    if(ret == -1){
339
 
      error(0, errno, "sigaddset");
 
338
      perror("sigaddset");
340
339
      status = EX_OSERR;
341
340
      goto failure;
342
341
    }
343
342
    ret = sigaction(SIGINT, NULL, &old_action);
344
343
    if(ret == -1){
345
344
      if(errno != EINTR){
346
 
        error(0, errno, "sigaction");
 
345
        perror("sigaction");
347
346
        status = EX_OSERR;
348
347
      }
349
348
      goto failure;
352
351
      ret = sigaction(SIGINT, &new_action, NULL);
353
352
      if(ret == -1){
354
353
        if(errno != EINTR){
355
 
          error(0, errno, "sigaction");
 
354
          perror("sigaction");
356
355
          status = EX_OSERR;
357
356
        }
358
357
        goto failure;
361
360
    ret = sigaction(SIGHUP, NULL, &old_action);
362
361
    if(ret == -1){
363
362
      if(errno != EINTR){
364
 
        error(0, errno, "sigaction");
 
363
        perror("sigaction");
365
364
        status = EX_OSERR;
366
365
      }
367
366
      goto failure;
370
369
      ret = sigaction(SIGHUP, &new_action, NULL);
371
370
      if(ret == -1){
372
371
        if(errno != EINTR){
373
 
          error(0, errno, "sigaction");
 
372
          perror("sigaction");
374
373
          status = EX_OSERR;
375
374
        }
376
375
        goto failure;
379
378
    ret = sigaction(SIGTERM, NULL, &old_action);
380
379
    if(ret == -1){
381
380
      if(errno != EINTR){
382
 
        error(0, errno, "sigaction");
 
381
        perror("sigaction");
383
382
        status = EX_OSERR;
384
383
      }
385
384
      goto failure;
388
387
      ret = sigaction(SIGTERM, &new_action, NULL);
389
388
      if(ret == -1){
390
389
        if(errno != EINTR){
391
 
          error(0, errno, "sigaction");
 
390
          perror("sigaction");
392
391
          status = EX_OSERR;
393
392
        }
394
393
        goto failure;
400
399
  /* Write command to FIFO */
401
400
  if(not usplash_write(&fifo_fd, "TIMEOUT", "0")){
402
401
    if(errno != EINTR){
403
 
      error(0, errno, "usplash_write");
 
402
      perror("usplash_write");
404
403
      status = EX_OSERR;
405
404
    }
406
405
    goto failure;
412
411
  
413
412
  if(not usplash_write(&fifo_fd, "INPUTQUIET", prompt)){
414
413
    if(errno != EINTR){
415
 
      error(0, errno, "usplash_write");
 
414
      perror("usplash_write");
416
415
      status = EX_OSERR;
417
416
    }
418
417
    goto failure;
430
429
  outfifo_fd = open("/dev/.initramfs/usplash_outfifo", O_RDONLY);
431
430
  if(outfifo_fd == -1){
432
431
    if(errno != EINTR){
433
 
      error(0, errno, "open");
 
432
      perror("open");
434
433
      status = EX_OSERR;
435
434
    }
436
435
    goto failure;
449
448
      char *tmp = realloc(buf, buf_allocated + blocksize);
450
449
      if(tmp == NULL){
451
450
        if(errno != EINTR){
452
 
          error(0, errno, "realloc");
 
451
          perror("realloc");
453
452
          status = EX_OSERR;
454
453
        }
455
454
        goto failure;
461
460
                buf_allocated - buf_len);
462
461
    if(sret == -1){
463
462
      if(errno != EINTR){
464
 
        error(0, errno, "read");
 
463
        perror("read");
465
464
        status = EX_OSERR;
466
465
      }
467
466
      TEMP_FAILURE_RETRY(close(outfifo_fd));
476
475
  ret = close(outfifo_fd);
477
476
  if(ret == -1){
478
477
    if(errno != EINTR){
479
 
      error(0, errno, "close");
 
478
      perror("close");
480
479
      status = EX_OSERR;
481
480
    }
482
481
    goto failure;
489
488
  
490
489
  if(not usplash_write(&fifo_fd, "TIMEOUT", "15")){
491
490
    if(errno != EINTR){
492
 
      error(0, errno, "usplash_write");
 
491
      perror("usplash_write");
493
492
      status = EX_OSERR;
494
493
    }
495
494
    goto failure;
502
501
  ret = close(fifo_fd);
503
502
  if(ret == -1){
504
503
    if(errno != EINTR){
505
 
      error(0, errno, "close");
 
504
      perror("close");
506
505
      status = EX_OSERR;
507
506
    }
508
507
    goto failure;
516
515
      sret = write(STDOUT_FILENO, buf + written, buf_len - written);
517
516
      if(sret == -1){
518
517
        if(errno != EINTR){
519
 
          error(0, errno, "write");
 
518
          perror("write");
520
519
          status = EX_OSERR;
521
520
        }
522
521
        goto failure;
553
552
  if(fifo_fd != -1){
554
553
    ret = (int)TEMP_FAILURE_RETRY(close(fifo_fd));
555
554
    if(ret == -1 and errno != EINTR){
556
 
      error(0, errno, "close");
 
555
      perror("close");
557
556
    }
558
557
    fifo_fd = -1;
559
558
  }
562
561
  if(outfifo_fd != -1){
563
562
    ret = (int)TEMP_FAILURE_RETRY(close(outfifo_fd));
564
563
    if(ret == -1){
565
 
      error(0, errno, "close");
 
564
      perror("close");
566
565
    }
567
566
  }
568
567
  
576
575
                           (sizeof(char *)
577
576
                            * (size_t)(cmdline_argc + 2)));
578
577
      if(tmp == NULL){
579
 
        error(0, errno, "realloc");
 
578
        perror("realloc");
580
579
        free(cmdline_argv);
581
580
        return status;
582
581
      }
603
602
       the real user ID (_mandos) */
604
603
    ret = setuid(geteuid());
605
604
    if(ret == -1){
606
 
      error(0, errno, "setuid");
 
605
      perror("setuid");
607
606
    }
608
607
    
609
608
    setsid();
610
609
    ret = chdir("/");
611
610
    if(ret == -1){
612
 
      error(0, errno, "chdir");
 
611
      perror("chdir");
613
612
      _exit(EX_OSERR);
614
613
    }
615
614
/*     if(fork() != 0){ */
617
616
/*     } */
618
617
    ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */
619
618
    if(ret == -1){
620
 
      error(0, errno, "dup2");
 
619
      perror("dup2");
621
620
      _exit(EX_OSERR);
622
621
    }
623
622
    
624
623
    execv(usplash_name, cmdline_argv);
625
624
    if(not interrupted_by_signal){
626
 
      error(0, errno, "execv");
 
625
      perror("execv");
627
626
    }
628
627
    free(cmdline);
629
628
    free(cmdline_argv);
634
633
  sleep(2);
635
634
  if(not usplash_write(&fifo_fd, "PULSATE", NULL)){
636
635
    if(errno != EINTR){
637
 
      error(0, errno, "usplash_write");
 
636
      perror("usplash_write");
638
637
    }
639
638
  }
640
639
  
642
641
  if(fifo_fd != -1){
643
642
    ret = (int)TEMP_FAILURE_RETRY(close(fifo_fd));
644
643
    if(ret == -1 and errno != EINTR){
645
 
      error(0, errno, "close");
 
644
      perror("close");
646
645
    }
647
646
    fifo_fd = -1;
648
647
  }
653
652
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
654
653
                                            &signal_action, NULL));
655
654
    if(ret == -1){
656
 
      error(0, errno, "sigaction");
 
655
      perror("sigaction");
657
656
    }
658
657
    do {
659
658
      ret = raise(signal_received);
660
659
    } while(ret != 0 and errno == EINTR);
661
660
    if(ret != 0){
662
 
      error(0, errno, "raise");
 
661
      perror("raise");
663
662
      abort();
664
663
    }
665
664
    TEMP_FAILURE_RETRY(pause());