dtms

annotate src/main.c @ 3:bf6dda0e9daf

added GPL License text
author Eleni Maria Stea <eleni@mutantstargoat.com>
date Fri, 13 May 2016 23:02:26 +0300
parents 50af08b83a1f
children db4bb4b5905a
rev   line source
eleni@3 1 /*
eleni@3 2 * DTMS Copyright (C) 2016 Eleni Maria Stea <elene.mst@gmail.com>
eleni@3 3 *
eleni@3 4 * This program is free software: you can redistribute it and/or modify
eleni@3 5 * it under the terms of the GNU General Public License as published by
eleni@3 6 * the Free Software Foundation, either version 3 of the License, or
eleni@3 7 * (at your option) any later version.
eleni@3 8 *
eleni@3 9 * This program is distributed in the hope that it will be useful,
eleni@3 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
eleni@3 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
eleni@3 12 * GNU General Public License for more details.
eleni@3 13
eleni@3 14 * You should have received a copy of the GNU General Public License
eleni@3 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
eleni@3 16 * */
eleni@3 17
eleni@0 18 #include <errno.h>
eleni@0 19 #include <fcntl.h>
eleni@0 20 #include <pwd.h>
eleni@0 21 #include <stdio.h>
eleni@0 22 #include <stdlib.h>
eleni@0 23 #include <string.h>
eleni@0 24 #include <sys/select.h>
eleni@0 25 #include <sys/stat.h>
eleni@0 26 #include <sys/types.h>
eleni@0 27 #include <time.h>
eleni@0 28 #include <unistd.h>
eleni@0 29
eleni@0 30 static int parse_args(int argc, char **argv);
eleni@0 31 static void print_help();
eleni@0 32 static void check_device(char *device_path);
eleni@0 33 static char* concatenate(char *mp_path, char *data_path);
eleni@0 34
eleni@0 35 static int uid;
eleni@0 36 static char *path;
eleni@0 37 static char *dev_path;
eleni@0 38
eleni@0 39 int main(int argc, char **argv)
eleni@0 40 {
eleni@0 41 time_t last_touch_time = 0;
eleni@0 42 int fd;
eleni@0 43
eleni@0 44 if(parse_args(argc, argv))
eleni@0 45 return 1;
eleni@0 46
eleni@0 47 check_device(dev_path);
eleni@0 48
eleni@0 49 if((fd = open(dev_path, O_RDONLY | O_NONBLOCK)) == -1) {
eleni@0 50 fprintf(stderr, "Failed to open device: %s, error: %s\n", dev_path, strerror(errno));
eleni@0 51 return 1;
eleni@0 52 }
eleni@0 53
eleni@0 54 if(seteuid(uid) == -1) {
eleni@0 55 perror("Set uid failed");
eleni@0 56 uid = 0;
eleni@0 57 }
eleni@0 58
eleni@0 59 if(!uid) {
eleni@0 60 const char *st = "/";
eleni@0 61 if(strncmp(path, st, 1) != 0) {
eleni@0 62 fprintf(stderr, "If you run this program as root you should pass the absolute path to a valid mp3 player.\n");
eleni@0 63 return 1;
eleni@0 64 }
eleni@0 65 }
eleni@0 66
eleni@0 67 while(1) {
eleni@0 68 fd_set read_set;
eleni@0 69 FD_ZERO(&read_set);
eleni@0 70 FD_SET(fd, &read_set);
eleni@0 71
eleni@0 72 int res;
eleni@0 73 while((res = select(fd + 1, &read_set, 0, 0, 0)) == -1 && errno == EINTR);
eleni@0 74 if(res < 0) {
eleni@0 75 perror("Select failed");
eleni@0 76 break;
eleni@0 77 }
eleni@0 78 if(res == 0) //nothing to read
eleni@0 79 continue;
eleni@0 80
eleni@0 81 if(FD_ISSET(fd, &read_set)) {
eleni@0 82 char buf[1024];
eleni@0 83 time_t now = time(0);
eleni@0 84 while(read(fd, buf, sizeof buf) > 0);
eleni@0 85 if (now - last_touch_time > 2) {
eleni@0 86 char *cmd = concatenate(path, "data/dtms.mp3");
eleni@0 87 system(cmd);
eleni@0 88 last_touch_time = now;
eleni@0 89 }
eleni@0 90 }
eleni@0 91 }
eleni@0 92 close(fd);
eleni@0 93 }
eleni@0 94
eleni@0 95 static int parse_args(int argc, char **argv)
eleni@0 96 {
eleni@0 97 for(int i=1; i<argc; i++) {
eleni@0 98 if((strcmp(argv[i], "-h") == 0)) {
eleni@0 99 print_help();
eleni@0 100 exit(0);
eleni@0 101 }
eleni@0 102 if((strcmp(argv[i], "-p") == 0)) {
eleni@0 103 if(argv[i+1]) {
eleni@0 104 path = argv[i+1];
eleni@0 105 }
eleni@0 106 else {
eleni@0 107 fprintf(stderr, "Invalid path. Please give the absolute path to an mp3 player.\n");
eleni@0 108 exit(1);
eleni@0 109 }
eleni@0 110 }
eleni@0 111
eleni@0 112 if((strcmp(argv[i], "-u") == 0)) {
eleni@0 113 if(argv[i+1]) {
eleni@0 114 struct passwd *passwd = getpwnam(argv[i+1]);
eleni@0 115 if(!passwd) {
eleni@0 116 fprintf(stderr, "Failed to get uid for: %s : %s.\n", argv[i+1], strerror(errno));
eleni@0 117 exit(1);
eleni@0 118 }
eleni@0 119 uid = passwd->pw_uid;
eleni@0 120 }
eleni@0 121 else {
eleni@0 122 fprintf(stderr, "Invalid username. Type -u `whoami`.\n");
eleni@0 123 exit(1);
eleni@0 124 }
eleni@0 125 }
eleni@0 126 if((strcmp(argv[i], "-d") == 0)) {
eleni@0 127 if(argv[i+1]) {
eleni@0 128 dev_path = argv[i+1];
eleni@0 129 }
eleni@0 130 else {
eleni@0 131 fprintf(stderr, "Invalid device file.\n");
eleni@0 132 exit(1);
eleni@0 133 }
eleni@0 134 }
eleni@0 135 }
eleni@0 136 return 0;
eleni@0 137 }
eleni@0 138
eleni@0 139 static void print_help()
eleni@0 140 {
eleni@0 141 printf("Options:\n");
eleni@0 142 printf("-h, prints this help\n");
eleni@0 143 printf("-d, path to the device\n");
eleni@0 144 printf("-p, path to the mp3 player\n");
eleni@0 145 printf("-u. username of the user that runs the program\n");
eleni@0 146 printf("--------\n");
eleni@0 147 printf("Examples:\n");
eleni@0 148 printf("--------\n");
eleni@0 149 printf("./dtms -d /dev/usb/hiddev0 -u eleni -p /usr/bin/mpv\n");
eleni@0 150 }
eleni@0 151
eleni@0 152 static void check_device(char *device_path)
eleni@0 153 {
eleni@0 154 struct stat sb;
eleni@0 155 if(stat(dev_path, &sb) == -1) {
eleni@0 156 perror("stat");
eleni@0 157 exit(0);
eleni@0 158 }
eleni@0 159 if(((sb.st_mode & S_IFMT) != S_IFBLK) && ((sb.st_mode & S_IFMT) != S_IFCHR)) {
eleni@0 160 fprintf(stderr, "Invalid device file.\n");
eleni@0 161 exit(0);
eleni@0 162 }
eleni@0 163 }
eleni@0 164
eleni@0 165 static char *concatenate(char *mp_path, char *data_path)
eleni@0 166 {
eleni@0 167 char *res = malloc(strlen(mp_path) + 1 + strlen(data_path) + 1);
eleni@0 168 strcpy(res, mp_path);
eleni@0 169 strcat(res, " ");
eleni@0 170 strcat(res, data_path);
eleni@0 171
eleni@0 172 return res;
eleni@0 173 }