chndlr.c (1596B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <stdlib.h> 3 #include <string.h> 4 #include <stdio.h> 5 #include <regex.h> 6 #include <unistd.h> 7 8 typedef struct { 9 const char *regex; 10 const char **action; 11 } Pair; 12 13 #include "config.h" 14 15 int i; 16 char cmd[BUFSIZ], *cmdv[BUFSIZ/16]; 17 regmatch_t match[9]; 18 19 int 20 reexec(char *uri, const char **args) { 21 const char *arg; 22 char *p = cmd; 23 int len; 24 25 while (*args) { 26 arg = *args; 27 cmdv[args - pairs[i].action] = p; 28 29 while (*arg) { 30 if (*arg == '%') { 31 unsigned char nc = *(arg + 1); 32 /* check if N in %N is between 0 and 9 */ 33 int group = nc - '0'; 34 if (group <= 9) { 35 len = match[group].rm_eo - match[group].rm_so; 36 snprintf(p, len + 1, "%.*s", len, uri + match[group].rm_so); 37 } else /* if (nc == 's') */ { 38 len = sprintf(p, "%s", uri); 39 } 40 arg += 2; 41 p += len; 42 } else { 43 *p++ = *arg++; 44 } 45 } 46 47 *p++ = '\0'; 48 args++; 49 } 50 51 return execvp(*cmdv, cmdv); 52 } 53 54 55 int 56 main(int argc, char *argv[]){ 57 regex_t regex; 58 59 /* we only take one argument */ 60 if (argc != 2) 61 return EXIT_FAILURE; 62 63 /* check regex and launch action if it matches argv[1] */ 64 for (i=0; i < sizeof(pairs)/sizeof(*pairs); ++i) { 65 if (regcomp(®ex, pairs[i].regex, REG_EXTENDED)) 66 fprintf(stderr, "invalid regex: %s\n", pairs[i].regex); 67 68 if (regexec(®ex, argv[1], 9, match, 0) == 0) { 69 regfree(®ex); 70 return reexec(argv[1], pairs[i].action); 71 } 72 } 73 74 regfree(®ex); 75 76 /* alternatively, fall back to chndlr_fallback_cmd */ 77 sprintf(cmd, "%s%s", chndlr_fallback_cmd, argv[1]); 78 system(cmd); 79 return EXIT_SUCCESS; 80 }