From: Eleni Maria Stea Date: Wed, 28 Oct 2020 09:52:31 +0000 (+0200) Subject: Don't touch my screen! X-Git-Url: https://eleni.mutantstargoat.com/git/?a=commitdiff_plain;ds=sidebyside;p=dtms Don't touch my screen! --- 52973a3b876dfa4c72dd6ef1ac474f13f4c882de diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..279de6f --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +# change the following line to install to a different prefix +PREFIX = /usr/local + +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +dep = $(obj:.o=.d) +bin = dtms + +dbg = -g +opt = -O0 + +CFLAGS = -pedantic -Wall -std=gnu99 -DPREFIX=\"$(PREFIX)\" $(dbg) + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) $(dep) + +.PHONY: install +install: $(bin) + mkdir -p $(PREFIX)/bin $(PREFIX)/share/dtms + cp $(bin) $(PREFIX)/bin/$(bin) + chown root $(PREFIX)/bin/$(bin) + chmod +s $(PREFIX)/bin/$(bin) + cp data/dtms.mp3 $(PREFIX)/share/dtms/dtms.mp3 + +.PHONY: uninstall +uninstall: + rm -f $(PREFIX)/bin/$(bin) + rm -f $(PREFIX)/share/dtms/dtms.mp3 + rmdir $(PREFIX)/share/dtms + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..d8e9ce6 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +------------- +Options: +------------- +-h, for help +-d, path to the device file +-p, path to the mp3 player +-u. username of the user that runs the program +-------------- +Example usage: +-------------- +./dtms -d /dev/usb/hiddev0 -u eleni -p /usr/bin/mpv diff --git a/data/dtms.mp3 b/data/dtms.mp3 new file mode 100644 index 0000000..2450789 Binary files /dev/null and b/data/dtms.mp3 differ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..6f8f719 --- /dev/null +++ b/src/main.c @@ -0,0 +1,193 @@ +/* + * DTMS Copyright (C) 2016 Eleni Maria Stea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int parse_args(int argc, char **argv); +static void print_help(); +static int check_device(char *device_path); + +static int uid = -1; +static char *player_path; +static char *dev_path; + +#ifdef PREFIX +static const char* player_arg = PREFIX "/share/dtms/dtms.mp3"; +#else +static const char* player_arg = "data/dtms.mp3"; +#endif + +int main(int argc, char **argv) +{ + time_t last_touch_time = 0; + int fd; + + if(parse_args(argc, argv) == -1) + return 1; + + if(getuid() == 0 && uid == -1) { + fprintf(stderr, "It's a bad idea to run this program as root, either make it setuid-root, or use the -u option to specify an unprivileged user.\n"); + return 1; + } + + if(check_device(dev_path) == -1) + return 1; + + if((fd = open(dev_path, O_RDONLY | O_NONBLOCK)) == -1) { + fprintf(stderr, "Failed to open device: %s, error: %s\n", dev_path, strerror(errno)); + return 1; + } + + if(uid == -1) { + uid = getuid(); + } + + if(seteuid(uid) == -1) { + perror("Set uid failed"); + return 1; + } + + if(!uid) { + if(player_path[0] != '/') { + fprintf(stderr, "If you run this program as root you should pass the absolute path to a valid mp3 player.\n"); + return 1; + } + } + + char *cmd = malloc(strlen(player_path) + 1 + strlen(player_arg) + 1); + sprintf(cmd, "%s %s", player_path, player_arg); + + while(1) { + fd_set read_set; + FD_ZERO(&read_set); + FD_SET(fd, &read_set); + + int res; + while((res = select(fd + 1, &read_set, 0, 0, 0)) == -1 && errno == EINTR); + if(res < 0) { + perror("Select failed"); + break; + } + if(res == 0) //nothing to read + continue; + + if(FD_ISSET(fd, &read_set)) { + char buf[1024]; + time_t now = time(0); + while(read(fd, buf, sizeof buf) > 0); + if (now - last_touch_time > 2) { + system(cmd); + last_touch_time = now; + } + } + } + + free(cmd); + close(fd); + + return 0; +} + +static int parse_args(int argc, char **argv) +{ + for(int i=1; ipw_uid; + if(uid == 0) { + fprintf(stderr, "You should pass an unprivileged username.\n"); + return -1; + } + } + else { + fprintf(stderr, "Missing username.\n"); + return -1; + } + } + else if((strcmp(argv[i], "-d") == 0)) { + if(argv[++i]) { + dev_path = argv[i]; + } + else { + fprintf(stderr, "Invalid device file.\n"); + return -1; + } + } + else { + fprintf(stderr, "Unknown argument: %s\n", argv[i]); + return -1; + } + } + return 0; +} + +static void print_help() +{ + printf("Options:\n"); + printf("-h, prints this help\n"); + printf("-d, path to the device\n"); + printf("-p, path to the mp3 player\n"); + printf("-u. username of the user that runs the program\n"); + printf("--------\n"); + printf("Examples:\n"); + printf("--------\n"); + printf("./dtms -d /dev/usb/hiddev0 -u eleni -p /usr/bin/mpv\n"); +} + +static int check_device(char *device_path) +{ + struct stat sb; + if(stat(dev_path, &sb) == -1) { + perror("stat"); + return -1; + } + if(((sb.st_mode & S_IFMT) != S_IFBLK) && ((sb.st_mode & S_IFMT) != S_IFCHR)) { + fprintf(stderr, "%s is not a device file.\n", device_path); + return -1; + } + return 0; +}