~ubuntu-branches/ubuntu/trusty/vlock/trusty

« back to all changes in this revision

Viewing changes to src/vlock-nosysrq.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Wirt
  • Date: 2007-09-12 07:21:51 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070912072151-vfempzszy91mtnux
Tags: 2.1-2
* Fix copyright file 
* Change maintainer

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* vlock-nosysrq.c -- sysrq protection routine for vlock,
 
2
 *                   the VT locking program for linux
 
3
 *
 
4
 * This program is copyright (C) 2007 Frank Benkstein, and is free
 
5
 * software which is freely distributable under the terms of the
 
6
 * GNU General Public License version 2, included as the file COPYING in this
 
7
 * distribution.  It is NOT public domain software, and any
 
8
 * redistribution not permitted by the GNU General Public License is
 
9
 * expressly forbidden without prior written permission from
 
10
 * the author.
 
11
 *
 
12
 */
 
13
 
 
14
#include <stdio.h>
 
15
#include <stdlib.h>
 
16
#include <unistd.h>
 
17
#include <sys/wait.h>
 
18
 
 
19
#include "vlock.h"
 
20
 
 
21
#define SYSRQ_PATH "/proc/sys/kernel/sysrq"
 
22
#define SYSRQ_DISABLE_VALUE "0\n"
 
23
 
 
24
/* Run vlock-new or vlock-all while SysRQ keys are disabled. */
 
25
int main(void) {
 
26
  char sysrq[32];
 
27
  int pid;
 
28
  int status;
 
29
  FILE *f;
 
30
 
 
31
  /* XXX: add optional PAM check here */
 
32
 
 
33
  /* open the sysrq sysctl file for reading and writing */
 
34
  if ((f = fopen(SYSRQ_PATH, "r+")) == NULL) {
 
35
    perror("vlock-nosysrq: could not open '" SYSRQ_PATH "'");
 
36
    exit (111);
 
37
  }
 
38
 
 
39
  /* read the old value */
 
40
  if (fgets(sysrq, sizeof sysrq, f) == NULL) {
 
41
    perror("vlock-nosysrq: could not read from '" SYSRQ_PATH "'");
 
42
    exit (111);
 
43
  }
 
44
 
 
45
  /* check whether all was read */
 
46
  if (fgetc(f) != EOF) {
 
47
    fprintf(stderr, "vlock-nosysrq: sysrq buffer to small: %d\n", sizeof sysrq);
 
48
    exit (111);
 
49
  }
 
50
 
 
51
  /* disable sysrq */
 
52
  if (fseek(f, 0, SEEK_SET) < 0
 
53
      || ftruncate(fileno(f), 0) < 0
 
54
      || fputs(SYSRQ_DISABLE_VALUE, f) < 0
 
55
      || fflush(f) < 0) {
 
56
    perror("vlock-nosysrq: could not write disable value to '" SYSRQ_PATH "'");
 
57
    exit (111);
 
58
  }
 
59
 
 
60
  pid = fork();
 
61
 
 
62
  if (pid == 0) {
 
63
    /* child */
 
64
 
 
65
    /* close sysrq file */
 
66
    (void) fclose(f);
 
67
 
 
68
    /* drop privleges */
 
69
    (void) setuid(getuid());
 
70
 
 
71
    /* run child */
 
72
    if (getenv("VLOCK_NEW") != NULL) {
 
73
      execl(VLOCK_NEW, VLOCK_NEW, (char *) NULL);
 
74
      perror("vlock-nosysrq: exec of vlock-new failed");
 
75
    } else {
 
76
      execl(VLOCK_ALL, VLOCK_ALL, (char *) NULL);
 
77
      perror("vlock-nosysrq: exec of vlock-all failed");
 
78
    }
 
79
    _exit(127);
 
80
  } else if (pid < 0) {
 
81
    perror("vlock-nosysrq: could not create child process");
 
82
  }
 
83
 
 
84
  if (pid > 0 && waitpid(pid, &status, 0) < 0) {
 
85
    perror("vlock-nosysrq: child process missing");
 
86
    pid = -1;
 
87
  }
 
88
 
 
89
  if (fseek(f, 0, SEEK_SET) < 0
 
90
      || ftruncate(fileno(f), 0) < 0
 
91
      || fputs(sysrq, f) < 0
 
92
      || fflush(f) < 0
 
93
      )
 
94
    perror("vlock-nosysrq: could not restore old value to '" SYSRQ_PATH "'");
 
95
 
 
96
  /* exit with the exit status of the child or 128+signal if it was killed */
 
97
  if (pid > 0) {
 
98
    if (WIFEXITED(status))
 
99
      exit (WEXITSTATUS(status));
 
100
    else if (WIFSIGNALED(status))
 
101
      exit (128+WTERMSIG(status));
 
102
  }
 
103
 
 
104
  return 0;
 
105
}