commit 0a07928444f3dc409aac70990012fdb41e5f3d27
Author: Léo Villeveygoux <l@vgx.fr>
Date: Tue, 22 Feb 2022 15:10:29 +0100
3 parts wake up alarm system
- timer: SUID timerfd+CLOCK_BOOTTIME_ALARM based alarm
- timerat: setup a wait time in sec from date(1) format
- reveil: actual wake up alarm for myself
Diffstat:
5 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+timer
diff --git a/Makefile b/Makefile
@@ -0,0 +1,5 @@
+suid: timer
+ chmod u+s timer
+ su -c "chown root timer"
+
+.PHONY: suid
diff --git a/reveil b/reveil
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+timerat "$1" "mpv ~/dl/sumomomo_momomo/*02.mp4"
diff --git a/timer.c b/timer.c
@@ -0,0 +1,58 @@
+#include <sys/timerfd.h> /* timerfd_create() timerfd_settime() */
+#include <unistd.h> /* read(), get/set(e)uid() execl()*/
+#include <stdlib.h> /* atol() */
+#include <stdint.h> /* uint64_t */
+#include <stdio.h> /* perror() */
+
+int main(int argc, char* argv[]) {
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s time cmd\n", argv[0]);
+ return 1;
+ }
+
+ int err = seteuid(0);
+
+ if (err == -1) {
+ perror("seteuid (get root rights)");
+ return 1;
+ }
+
+ int fd = timerfd_create(CLOCK_BOOTTIME_ALARM, TFD_CLOEXEC);
+
+ if (fd == -1) {
+ perror("timerfd creation");
+ return 1;
+ }
+
+ const struct itimerspec tspec = { .it_value.tv_sec = atol(argv[1])};
+
+ err = timerfd_settime(fd, 0, &tspec, NULL);
+
+ if (err == -1) {
+ perror("timerfd arming");
+ return 1;
+ }
+
+ err = seteuid(getuid());
+
+ if (err == -1) {
+ perror("seteuid (drop root right)");
+ return 1;
+ }
+
+ uint64_t res = 0;
+ ssize_t size = read(fd, &res, sizeof(res));
+
+ if (size == -1) {
+ perror("timerfd read");
+ return 1;
+ }
+
+ //printf("dring\n");
+
+ execl("/bin/sh", "sh", "-c", argv[2], (char*)NULL);
+
+ perror("exec");
+ return 1;
+}
+
diff --git a/timerat b/timerat
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Exec a command at a given date (date(1) format).
+#
+# Dependecies: date, expr, timer (with suid)
+
+if [ $# -ne 2 ] ; then
+ echo "Usage: timerat <target_date> <cmd>" >&2
+ exit 1
+fi
+
+diff_date () {
+ expr "$(date -d "$1" +%s)" - "$(date +%s)"
+}
+
+#if expr "$1" : '[0-9][0-9]*:[0-9]*$' > /dev/null ; then
+# DAT=$(date -d "tomorrow $1" +%s)
+#else
+# DAT=$(date -d "$1" +%s)
+#fi
+
+WAIT=$(diff_date "$1")
+if [ "$WAIT" -lt 0 ] ; then
+ WAIT=$(diff_date "tomorrow $1")
+elif [ "$WAIT" -le 0 ] ; then
+ echo "Can't wake up in the past! (wait: $WAIT sec)" >&2
+ exit 1
+else
+ echo "Waking up in $(date -ud "@$WAIT" +%T)"
+fi
+
+timer "$WAIT" "$2"