mplay.c (1452B)
1#include <unistd.h> 2#include <dirent.h> 3 4#include <stdarg.h> 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8 9void 10die(const char *fmt, ...) 11{ 12 va_list ap; 13 14 fputs("mplay: ", stderr); 15 va_start(ap, fmt); 16 vfprintf(stderr, fmt, ap); 17 va_end(ap); 18 if (*fmt && fmt[strlen(fmt)-1] == ':') { 19 perror(NULL); 20 } else { 21 fputc('\n', stderr); 22 } 23 exit(1); 24} 25 26int 27main(int argc, char **argv) 28{ 29 char *path, *bin; 30 char *tok, *sep, *end; 31 char **arg, *fmt; 32 struct dirent *ent; 33 DIR *dir; 34 35 if (argc < 2) die("mplay [-d] [-f FMT] ... FILE[.FMT]"); 36 37 path = strdup(getenv("PATH")); 38 if (!path) die("PATH not set"); 39 40 fmt = NULL; 41 for (arg = argv; arg[1]; arg++) { 42 if (!strcmp(arg[1], "-f")) { 43 fmt = arg[2]; 44 arg++; 45 } else { 46 break; 47 } 48 } 49 arg[0] = argv[0]; 50 51 if (fmt == NULL) { 52 fmt = strrchr(argv[argc - 1], '.'); 53 if (!fmt) die("no file extension"); 54 fmt += 1; 55 } 56 57 tok = path; 58 do { 59 sep = strchr(tok, ':'); 60 end = sep ? sep : tok + strlen(tok); 61 *end = '\0'; 62 dir = opendir(tok); 63 if (!dir) continue; 64 while ((ent = readdir(dir))) { 65 if (!strncmp(ent->d_name, "mplay.", 6) 66 && !strcmp(ent->d_name + 6, fmt)) { 67 bin = malloc(strlen(tok) + strlen(ent->d_name) + 2); 68 if (!bin) die("malloc:"); 69 strcpy(bin, tok); 70 strcat(bin, "/"); 71 strcat(bin, ent->d_name); 72 closedir(dir); 73 execv(bin, arg); 74 die("execv %s:", bin); 75 } 76 } 77 closedir(dir); 78 tok = sep + 1; 79 } while (sep); 80 81 die("no handler"); 82}