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