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
81
82
83
84
85
86
87
88
89
90
91
92
|
#include "uri.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fnmatch.h>
#define LINE_LENGTH 1024
#define MATCH_UNEXIST 0
#define MATCH_PATTERN 1
#define MATCH_REVERSE -1
// return 1 if the match and rule should have the main function print this URL.
int match(char rule,char *part,char *arg) {
switch(rule) {
case MATCH_UNEXIST:
if(part == 0) return 1;
break;
case MATCH_REVERSE:
if(part) {
if(!fnmatch(arg,part,FNM_NOESCAPE)) return 0;
else return 1;
}
break;
case MATCH_PATTERN:
if(part) if(!fnmatch(arg,part,FNM_NOESCAPE)) return 1;
break;
default:
fprintf(stderr,"oh god. what the hell happened to get here?\n");
break;
}
return 0;
}
int main(int argc,char *argv[]) {
int i,j;;
int ret=1;
struct uri u;
char rule=MATCH_PATTERN;
char *line=malloc(LINE_LENGTH);
char copy[LINE_LENGTH];
if(argc < 2) {
printf("usage: urimatch [-][n][r][s|u|k|d|P|p|q|f] [string]\n");
printf("scheme://username:password@domain:port/path?query_string#fragment_id\n");
printf("s://u:k@d:P/p?q#f\n");
printf("This allows matching of subdomains, like `echo epoch.ano | urimatch -D ano` would match.\n");
printf("the 'n' flag can be put before any of the other flags to check for a missing.\n");
return 1;
}
while(fgets(line,LINE_LENGTH-1,stdin)) {
if(strchr(line,'\r')) *strchr(line,'\r')=0;
if(strchr(line,'\n')) *strchr(line,'\n')=0;
strcpy(copy,line);
memset(&u,0,sizeof(u));
urifromline(&u,line);
//use the character in argv[1] to match stdin against argv[2]. if match print whole line.
for(i=1;i<argc;i+=2) {//for each line, we're reparsing the arguments...
rule=MATCH_PATTERN;//default
j=0;
switch(argv[i][0]) {
case '-': j=1; rule=MATCH_PATTERN; break;//so we can't be modifying these! how the fuck?
case 'n': j=1; rule=MATCH_UNEXIST; break;
case 'r': j=1; rule=MATCH_REVERSE; break;
default: break;//handled by the next switch
}
if(rule != MATCH_UNEXIST) {
if(i+1 == argc) {
fprintf(stderr,"argument '%s' wants a value in the next argument and didn't get it. throwing a fit.\n",argv[i]);
// fprintf(stderr,"previous: '%s' current: '%s' next: '%s'\n",argv[i-1],argv[i],argv[i+1]);
return 2;
}
}
switch(argv[i][j]) {
case 's': if(match(rule,u.scheme,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'u': if(match(rule,u.username,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'k': if(match(rule,u.password,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'd': if(match(rule,u.domain,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'P': if(match(rule,u.port,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'p': if(match(rule,u.path,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'q': if(match(rule,u.query_string,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
case 'f': if(match(rule,u.fragment_id,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
// TODO: after a while, get rid of 'D' completely.
case 'D': fprintf(stderr,"the 'D' flag has been removed.\ninstead of: D 'host'\nuse: d '*host'\n");
default:
printf("unknown url part letter! '%c'\n",argv[i][0]);
return ret;
}
if(rule == MATCH_UNEXIST) {i--;}//UNEXIST doesn't consume the argument after it. so, go backwards 1. we're about to go ahead 2.
}
}
return ret;
}
|