1
/* vlock-nosysrq.c -- sysrq protection routine for vlock,
2
* the VT locking program for linux
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
21
#define SYSRQ_PATH "/proc/sys/kernel/sysrq"
22
#define SYSRQ_DISABLE_VALUE "0\n"
24
/* Run vlock-new or vlock-all while SysRQ keys are disabled. */
31
/* XXX: add optional PAM check here */
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 "'");
39
/* read the old value */
40
if (fgets(sysrq, sizeof sysrq, f) == NULL) {
41
perror("vlock-nosysrq: could not read from '" SYSRQ_PATH "'");
45
/* check whether all was read */
46
if (fgetc(f) != EOF) {
47
fprintf(stderr, "vlock-nosysrq: sysrq buffer to small: %d\n", sizeof sysrq);
52
if (fseek(f, 0, SEEK_SET) < 0
53
|| ftruncate(fileno(f), 0) < 0
54
|| fputs(SYSRQ_DISABLE_VALUE, f) < 0
56
perror("vlock-nosysrq: could not write disable value to '" SYSRQ_PATH "'");
65
/* close sysrq file */
69
(void) setuid(getuid());
72
if (getenv("VLOCK_NEW") != NULL) {
73
execl(VLOCK_NEW, VLOCK_NEW, (char *) NULL);
74
perror("vlock-nosysrq: exec of vlock-new failed");
76
execl(VLOCK_ALL, VLOCK_ALL, (char *) NULL);
77
perror("vlock-nosysrq: exec of vlock-all failed");
81
perror("vlock-nosysrq: could not create child process");
84
if (pid > 0 && waitpid(pid, &status, 0) < 0) {
85
perror("vlock-nosysrq: child process missing");
89
if (fseek(f, 0, SEEK_SET) < 0
90
|| ftruncate(fileno(f), 0) < 0
91
|| fputs(sysrq, f) < 0
94
perror("vlock-nosysrq: could not restore old value to '" SYSRQ_PATH "'");
96
/* exit with the exit status of the child or 128+signal if it was killed */
98
if (WIFEXITED(status))
99
exit (WEXITSTATUS(status));
100
else if (WIFSIGNALED(status))
101
exit (128+WTERMSIG(status));