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