eleni@3: /* eleni@3: * DTMS Copyright (C) 2016 Eleni Maria Stea eleni@3: * eleni@3: * This program is free software: you can redistribute it and/or modify eleni@3: * it under the terms of the GNU General Public License as published by eleni@3: * the Free Software Foundation, either version 3 of the License, or eleni@3: * (at your option) any later version. eleni@3: * eleni@3: * This program is distributed in the hope that it will be useful, eleni@3: * but WITHOUT ANY WARRANTY; without even the implied warranty of eleni@3: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the eleni@3: * GNU General Public License for more details. eleni@3: eleni@3: * You should have received a copy of the GNU General Public License eleni@3: * along with this program. If not, see . eleni@3: * */ eleni@3: eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: #include eleni@0: eleni@0: static int parse_args(int argc, char **argv); eleni@0: static void print_help(); eleni@0: static void check_device(char *device_path); eleni@0: static char* concatenate(char *mp_path, char *data_path); eleni@0: eleni@0: static int uid; eleni@0: static char *path; eleni@0: static char *dev_path; eleni@0: eleni@0: int main(int argc, char **argv) eleni@0: { eleni@0: time_t last_touch_time = 0; eleni@0: int fd; eleni@0: eleni@0: if(parse_args(argc, argv)) eleni@0: return 1; eleni@0: eleni@0: check_device(dev_path); eleni@0: eleni@0: if((fd = open(dev_path, O_RDONLY | O_NONBLOCK)) == -1) { eleni@0: fprintf(stderr, "Failed to open device: %s, error: %s\n", dev_path, strerror(errno)); eleni@0: return 1; eleni@0: } eleni@0: eleni@0: if(seteuid(uid) == -1) { eleni@0: perror("Set uid failed"); eleni@0: uid = 0; eleni@0: } eleni@0: eleni@0: if(!uid) { eleni@0: const char *st = "/"; eleni@0: if(strncmp(path, st, 1) != 0) { eleni@0: fprintf(stderr, "If you run this program as root you should pass the absolute path to a valid mp3 player.\n"); eleni@0: return 1; eleni@0: } eleni@0: } eleni@0: eleni@0: while(1) { eleni@0: fd_set read_set; eleni@0: FD_ZERO(&read_set); eleni@0: FD_SET(fd, &read_set); eleni@0: eleni@0: int res; eleni@0: while((res = select(fd + 1, &read_set, 0, 0, 0)) == -1 && errno == EINTR); eleni@0: if(res < 0) { eleni@0: perror("Select failed"); eleni@0: break; eleni@0: } eleni@0: if(res == 0) //nothing to read eleni@0: continue; eleni@0: eleni@0: if(FD_ISSET(fd, &read_set)) { eleni@0: char buf[1024]; eleni@0: time_t now = time(0); eleni@0: while(read(fd, buf, sizeof buf) > 0); eleni@0: if (now - last_touch_time > 2) { eleni@0: char *cmd = concatenate(path, "data/dtms.mp3"); eleni@0: system(cmd); eleni@0: last_touch_time = now; eleni@0: } eleni@0: } eleni@0: } eleni@0: close(fd); eleni@0: } eleni@0: eleni@0: static int parse_args(int argc, char **argv) eleni@0: { eleni@0: for(int i=1; ipw_uid; eleni@0: } eleni@0: else { eleni@0: fprintf(stderr, "Invalid username. Type -u `whoami`.\n"); eleni@0: exit(1); eleni@0: } eleni@0: } eleni@0: if((strcmp(argv[i], "-d") == 0)) { eleni@0: if(argv[i+1]) { eleni@0: dev_path = argv[i+1]; eleni@0: } eleni@0: else { eleni@0: fprintf(stderr, "Invalid device file.\n"); eleni@0: exit(1); eleni@0: } eleni@0: } eleni@0: } eleni@0: return 0; eleni@0: } eleni@0: eleni@0: static void print_help() eleni@0: { eleni@0: printf("Options:\n"); eleni@0: printf("-h, prints this help\n"); eleni@0: printf("-d, path to the device\n"); eleni@0: printf("-p, path to the mp3 player\n"); eleni@0: printf("-u. username of the user that runs the program\n"); eleni@0: printf("--------\n"); eleni@0: printf("Examples:\n"); eleni@0: printf("--------\n"); eleni@0: printf("./dtms -d /dev/usb/hiddev0 -u eleni -p /usr/bin/mpv\n"); eleni@0: } eleni@0: eleni@0: static void check_device(char *device_path) eleni@0: { eleni@0: struct stat sb; eleni@0: if(stat(dev_path, &sb) == -1) { eleni@0: perror("stat"); eleni@0: exit(0); eleni@0: } eleni@0: if(((sb.st_mode & S_IFMT) != S_IFBLK) && ((sb.st_mode & S_IFMT) != S_IFCHR)) { eleni@0: fprintf(stderr, "Invalid device file.\n"); eleni@0: exit(0); eleni@0: } eleni@0: } eleni@0: eleni@0: static char *concatenate(char *mp_path, char *data_path) eleni@0: { eleni@0: char *res = malloc(strlen(mp_path) + 1 + strlen(data_path) + 1); eleni@0: strcpy(res, mp_path); eleni@0: strcat(res, " "); eleni@0: strcat(res, data_path); eleni@0: eleni@0: return res; eleni@0: }