dtms

annotate src/main.c @ 1:49df14292d38

README.md edited online with Bitbucket
author Eleni Maria Stea <elene.mst@gmail.com>
date Fri, 13 May 2016 18:08:29 +0000
parents
children bf6dda0e9daf
rev   line source
eleni@0 1 #include <errno.h>
eleni@0 2 #include <fcntl.h>
eleni@0 3 #include <pwd.h>
eleni@0 4 #include <stdio.h>
eleni@0 5 #include <stdlib.h>
eleni@0 6 #include <string.h>
eleni@0 7 #include <sys/select.h>
eleni@0 8 #include <sys/stat.h>
eleni@0 9 #include <sys/types.h>
eleni@0 10 #include <time.h>
eleni@0 11 #include <unistd.h>
eleni@0 12
eleni@0 13 static int parse_args(int argc, char **argv);
eleni@0 14 static void print_help();
eleni@0 15 static void check_device(char *device_path);
eleni@0 16 static char* concatenate(char *mp_path, char *data_path);
eleni@0 17
eleni@0 18 static int uid;
eleni@0 19 static char *path;
eleni@0 20 static char *dev_path;
eleni@0 21
eleni@0 22 int main(int argc, char **argv)
eleni@0 23 {
eleni@0 24 time_t last_touch_time = 0;
eleni@0 25 int fd;
eleni@0 26
eleni@0 27 if(parse_args(argc, argv))
eleni@0 28 return 1;
eleni@0 29
eleni@0 30 check_device(dev_path);
eleni@0 31
eleni@0 32 if((fd = open(dev_path, O_RDONLY | O_NONBLOCK)) == -1) {
eleni@0 33 fprintf(stderr, "Failed to open device: %s, error: %s\n", dev_path, strerror(errno));
eleni@0 34 return 1;
eleni@0 35 }
eleni@0 36
eleni@0 37 if(seteuid(uid) == -1) {
eleni@0 38 perror("Set uid failed");
eleni@0 39 uid = 0;
eleni@0 40 }
eleni@0 41
eleni@0 42 if(!uid) {
eleni@0 43 const char *st = "/";
eleni@0 44 if(strncmp(path, st, 1) != 0) {
eleni@0 45 fprintf(stderr, "If you run this program as root you should pass the absolute path to a valid mp3 player.\n");
eleni@0 46 return 1;
eleni@0 47 }
eleni@0 48 }
eleni@0 49
eleni@0 50 while(1) {
eleni@0 51 fd_set read_set;
eleni@0 52 FD_ZERO(&read_set);
eleni@0 53 FD_SET(fd, &read_set);
eleni@0 54
eleni@0 55 int res;
eleni@0 56 while((res = select(fd + 1, &read_set, 0, 0, 0)) == -1 && errno == EINTR);
eleni@0 57 if(res < 0) {
eleni@0 58 perror("Select failed");
eleni@0 59 break;
eleni@0 60 }
eleni@0 61 if(res == 0) //nothing to read
eleni@0 62 continue;
eleni@0 63
eleni@0 64 if(FD_ISSET(fd, &read_set)) {
eleni@0 65 char buf[1024];
eleni@0 66 time_t now = time(0);
eleni@0 67 while(read(fd, buf, sizeof buf) > 0);
eleni@0 68 if (now - last_touch_time > 2) {
eleni@0 69 char *cmd = concatenate(path, "data/dtms.mp3");
eleni@0 70 system(cmd);
eleni@0 71 last_touch_time = now;
eleni@0 72 }
eleni@0 73 }
eleni@0 74 }
eleni@0 75 close(fd);
eleni@0 76 }
eleni@0 77
eleni@0 78 static int parse_args(int argc, char **argv)
eleni@0 79 {
eleni@0 80 for(int i=1; i<argc; i++) {
eleni@0 81 if((strcmp(argv[i], "-h") == 0)) {
eleni@0 82 print_help();
eleni@0 83 exit(0);
eleni@0 84 }
eleni@0 85 if((strcmp(argv[i], "-p") == 0)) {
eleni@0 86 if(argv[i+1]) {
eleni@0 87 path = argv[i+1];
eleni@0 88 }
eleni@0 89 else {
eleni@0 90 fprintf(stderr, "Invalid path. Please give the absolute path to an mp3 player.\n");
eleni@0 91 exit(1);
eleni@0 92 }
eleni@0 93 }
eleni@0 94
eleni@0 95 if((strcmp(argv[i], "-u") == 0)) {
eleni@0 96 if(argv[i+1]) {
eleni@0 97 struct passwd *passwd = getpwnam(argv[i+1]);
eleni@0 98 if(!passwd) {
eleni@0 99 fprintf(stderr, "Failed to get uid for: %s : %s.\n", argv[i+1], strerror(errno));
eleni@0 100 exit(1);
eleni@0 101 }
eleni@0 102 uid = passwd->pw_uid;
eleni@0 103 }
eleni@0 104 else {
eleni@0 105 fprintf(stderr, "Invalid username. Type -u `whoami`.\n");
eleni@0 106 exit(1);
eleni@0 107 }
eleni@0 108 }
eleni@0 109 if((strcmp(argv[i], "-d") == 0)) {
eleni@0 110 if(argv[i+1]) {
eleni@0 111 dev_path = argv[i+1];
eleni@0 112 }
eleni@0 113 else {
eleni@0 114 fprintf(stderr, "Invalid device file.\n");
eleni@0 115 exit(1);
eleni@0 116 }
eleni@0 117 }
eleni@0 118 }
eleni@0 119 return 0;
eleni@0 120 }
eleni@0 121
eleni@0 122 static void print_help()
eleni@0 123 {
eleni@0 124 printf("Options:\n");
eleni@0 125 printf("-h, prints this help\n");
eleni@0 126 printf("-d, path to the device\n");
eleni@0 127 printf("-p, path to the mp3 player\n");
eleni@0 128 printf("-u. username of the user that runs the program\n");
eleni@0 129 printf("--------\n");
eleni@0 130 printf("Examples:\n");
eleni@0 131 printf("--------\n");
eleni@0 132 printf("./dtms -d /dev/usb/hiddev0 -u eleni -p /usr/bin/mpv\n");
eleni@0 133 }
eleni@0 134
eleni@0 135 static void check_device(char *device_path)
eleni@0 136 {
eleni@0 137 struct stat sb;
eleni@0 138 if(stat(dev_path, &sb) == -1) {
eleni@0 139 perror("stat");
eleni@0 140 exit(0);
eleni@0 141 }
eleni@0 142 if(((sb.st_mode & S_IFMT) != S_IFBLK) && ((sb.st_mode & S_IFMT) != S_IFCHR)) {
eleni@0 143 fprintf(stderr, "Invalid device file.\n");
eleni@0 144 exit(0);
eleni@0 145 }
eleni@0 146 }
eleni@0 147
eleni@0 148 static char *concatenate(char *mp_path, char *data_path)
eleni@0 149 {
eleni@0 150 char *res = malloc(strlen(mp_path) + 1 + strlen(data_path) + 1);
eleni@0 151 strcpy(res, mp_path);
eleni@0 152 strcat(res, " ");
eleni@0 153 strcat(res, data_path);
eleni@0 154
eleni@0 155 return res;
eleni@0 156 }