diff options
Diffstat (limited to 'bin/zzz.c')
| -rw-r--r-- | bin/zzz.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/bin/zzz.c b/bin/zzz.c new file mode 100644 index 0000000..2170c78 --- /dev/null +++ b/bin/zzz.c @@ -0,0 +1,86 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> + +#define POWER_STATE_F "/sys/power/state" + +void +die(const char *msg) +{ + puts(msg); + exit(1); +} + +void +err(const char *msg) +{ + perror(msg); + exit(1); +} + +void +suspend() +{ + int fh = open(POWER_STATE_F, O_WRONLY); + int n; + const char *cmd = "mem"; + + if (fh == -1) + err("Opening "POWER_STATE_F); + + n = write(fh, cmd, 3); + if (n == -1) + err("Writing to "POWER_STATE_F); + + exit(0); +} + +int +main(int argc, char **argv) +{ + uid_t uid = getuid(); + gid_t gid = getgid(); + uid_t euid = geteuid(); + char **a = argv+1; + char *lockProg = "slock"; + pid_t pid; + int ret; + + if (euid != 0) + die("Program must be run as root/setuid"); + + for (;*a;a++) { + if (strcmp("-l", *a) == 0) { + a++; + if (*a) + lockProg = *a; + else + die("-l must have an argument"); + } else { + printf("Unknown argument: '%s'\n", *a); + exit(1); + } + } + + + pid = fork(); + switch (pid) { + case -1: + err("fork"); + case 0: + ret = setuid(uid); + if (ret == -1) + err("setuid"); + ret = setgid(gid); + if (ret == -1) + err("setgid"); + + ret = execlp(lockProg, lockProg); + err("execlp"); + default: + suspend(); + } + +} |
