2 * DTMS Copyright (C) 2016 Eleni Maria Stea <elene.mst@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/select.h>
26 #include <sys/types.h>
30 static int parse_args(int argc, char **argv);
31 static void print_help();
32 static int check_device(char *device_path);
35 static char *player_path;
36 static char *dev_path;
39 static const char* player_arg = PREFIX "/share/dtms/dtms.mp3";
41 static const char* player_arg = "data/dtms.mp3";
44 int main(int argc, char **argv)
46 time_t last_touch_time = 0;
49 if(parse_args(argc, argv) == -1)
52 if(getuid() == 0 && uid == -1) {
53 fprintf(stderr, "It's a bad idea to run this program as root, either make it setuid-root, or use the -u option to specify an unprivileged user.\n");
57 if(check_device(dev_path) == -1)
60 if((fd = open(dev_path, O_RDONLY | O_NONBLOCK)) == -1) {
61 fprintf(stderr, "Failed to open device: %s, error: %s\n", dev_path, strerror(errno));
69 if(seteuid(uid) == -1) {
70 perror("Set uid failed");
75 if(player_path[0] != '/') {
76 fprintf(stderr, "If you run this program as root you should pass the absolute path to a valid mp3 player.\n");
81 char *cmd = malloc(strlen(player_path) + 1 + strlen(player_arg) + 1);
82 sprintf(cmd, "%s %s", player_path, player_arg);
87 FD_SET(fd, &read_set);
90 while((res = select(fd + 1, &read_set, 0, 0, 0)) == -1 && errno == EINTR);
92 perror("Select failed");
95 if(res == 0) //nothing to read
98 if(FD_ISSET(fd, &read_set)) {
100 time_t now = time(0);
101 while(read(fd, buf, sizeof buf) > 0);
102 if (now - last_touch_time > 2) {
104 last_touch_time = now;
115 static int parse_args(int argc, char **argv)
117 for(int i=1; i<argc; i++) {
118 if((strcmp(argv[i], "-h") == 0)) {
123 else if((strcmp(argv[i], "-p") == 0)) {
125 player_path = argv[i];
128 fprintf(stderr, "Invalid path. Please give the absolute path to an mp3 player.\n");
133 else if((strcmp(argv[i], "-u") == 0)) {
135 struct passwd *passwd = getpwnam(argv[i]);
137 fprintf(stderr, "Failed to get uid for: %s : %s.\n", argv[i], strerror(errno));
140 uid = passwd->pw_uid;
142 fprintf(stderr, "You should pass an unprivileged username.\n");
147 fprintf(stderr, "Missing username.\n");
151 else if((strcmp(argv[i], "-d") == 0)) {
156 fprintf(stderr, "Invalid device file.\n");
161 fprintf(stderr, "Unknown argument: %s\n", argv[i]);
168 static void print_help()
170 printf("Options:\n");
171 printf("-h, prints this help\n");
172 printf("-d, path to the device\n");
173 printf("-p, path to the mp3 player\n");
174 printf("-u. username of the user that runs the program\n");
175 printf("--------\n");
176 printf("Examples:\n");
177 printf("--------\n");
178 printf("./dtms -d /dev/usb/hiddev0 -u eleni -p /usr/bin/mpv\n");
181 static int check_device(char *device_path)
184 if(stat(dev_path, &sb) == -1) {
188 if(((sb.st_mode & S_IFMT) != S_IFBLK) && ((sb.st_mode & S_IFMT) != S_IFCHR)) {
189 fprintf(stderr, "%s is not a device file.\n", device_path);