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 }
|