timer

Wake up alarm system
git clone git://git.vgx.fr/timer
Log | Files | Refs

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:
A.gitignore | 1+
AMakefile | 5+++++
Areveil | 3+++
Atimer.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atimerat | 32++++++++++++++++++++++++++++++++
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"