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