src/signals.c: reformat termination blurb
[vlock.git] / modules / nosysrq.c
blob08ea39b8b3dfed3d2fb3c1d8880e93dabf76e881
1 /* nosysrq.c -- SysRq protection plugin 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
10 * the author.
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <errno.h>
20 #include "vlock_plugin.h"
22 const char *preceeds[] = { "new", "all", NULL };
23 const char *depends[] = { "all", NULL };
25 #define SYSRQ_PATH "/proc/sys/kernel/sysrq"
26 #define SYSRQ_DISABLE_VALUE "0\n"
28 struct sysrq_context {
29 FILE *file;
30 char value[32];
33 /* Disable SysRq and save old value in context. */
34 bool vlock_start(void **ctx_ptr)
36 struct sysrq_context *ctx;
38 /* Allocate the context. */
39 if ((ctx = malloc(sizeof *ctx)) == NULL)
40 return false;
42 /* XXX: add optional PAM check here */
44 /* Open the SysRq sysctl file for reading and writing. */
45 if ((ctx->file = fopen(SYSRQ_PATH, "r+")) == NULL) {
46 perror("vlock-nosysrq: could not open '" SYSRQ_PATH "'");
47 if (errno == ENOENT)
48 goto nothing_to_do;
49 else
50 goto err;
53 /* Read the old value. */
54 if (fgets(ctx->value, sizeof ctx->value, ctx->file) == NULL) {
55 perror("vlock-nosysrq: could not read from '" SYSRQ_PATH "'");
56 goto err;
59 /* Check whether all data was read. */
60 if (feof(ctx->file) != 0) {
61 fprintf(stderr, "vlock-nosysrq: sysrq buffer to small: %zu\n",
62 sizeof ctx->value);
63 goto err;
66 /* Check if SysRq was already disabled. */
67 if (strcmp(SYSRQ_DISABLE_VALUE, ctx->value) == 0)
68 goto nothing_to_do;
70 /* Disable SysRq. */
71 if (fseek(ctx->file, 0, SEEK_SET) < 0
72 || ftruncate(fileno(ctx->file), 0) < 0
73 || fputs(SYSRQ_DISABLE_VALUE, ctx->file) < 0
74 || fflush(ctx->file) < 0) {
75 perror("vlock-nosysrq: could not write disable value to '" SYSRQ_PATH "'");
76 goto err;
79 *ctx_ptr = ctx;
80 return true;
82 nothing_to_do:
83 free(ctx);
84 *ctx_ptr = NULL;
85 return true;
87 err:
88 errno = 0;
89 free(ctx);
90 return false;
94 /* Restore old SysRq value. */
95 bool vlock_end(void **ctx_ptr)
97 struct sysrq_context *ctx = *ctx_ptr;
99 if (ctx == NULL)
100 return true;
102 /* Restore SysRq. */
103 if (fseek(ctx->file, 0, SEEK_SET) < 0
104 || ftruncate(fileno(ctx->file), 0) < 0
105 || fputs(ctx->value, ctx->file) < 0 || fflush(ctx->file) < 0)
106 perror("vlock-nosysrq: could not write old value to '" SYSRQ_PATH "'");
108 free(ctx);
109 return true;