summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorepoch <epoch@enzo.thebackupbox.net>2021-10-25 06:34:39 +0000
committerepoch <epoch@enzo.thebackupbox.net>2021-10-25 06:34:39 +0000
commit6bc244ea4584b97a7ba514d4110f43ee30be0515 (patch)
tree31ce2ba4f54c94c8f6467788460f736280736016
parent80050281a53813021abe6ee7f6d12535d1337774 (diff)
downloaduritools-6bc244ea4584b97a7ba514d4110f43ee30be0515.tar.gz
uritools-6bc244ea4584b97a7ba514d4110f43ee30be0515.zip
added reverse match, used defines for match modes, fixed a argument parsing bug that would break on the second line of input if using non-simple matching
-rw-r--r--urimatch.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/urimatch.c b/urimatch.c
index a90fb68..91177f2 100644
--- a/urimatch.c
+++ b/urimatch.c
@@ -6,29 +6,43 @@
#define LINE_LENGTH 1024
-int match(char negate,char *part,char *arg) {
- if(negate) {
- if(part == 0) return 1;//we found that the part isn't here!
- } else {
- if(part) {
- if(!fnmatch(arg,part,FNM_NOESCAPE)) return 1;
- }
+#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;
+ int i,j;;
int ret=1;
struct uri u;
- char negate=0;
+ char rule=MATCH_PATTERN;
char *line=malloc(LINE_LENGTH);
char copy[LINE_LENGTH];
if(argc < 2) {
- printf("usage: urimatch [-][n][s|u|k|d|D|P|p|q|f] [string]\n");
+ 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("The D flag is special. it matches its argument against the last bytes of the input url's domain.\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;
@@ -40,30 +54,31 @@ int main(int argc,char *argv[]) {
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) {
- if(negate) {i--;}//we didn't really need to go that far.
- negate=0;
- if(argv[i][0] == '-') argv[i]++;
- if(argv[i][0] == 'n') {argv[i]++; negate=1; }//heh.
+ 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 's': if(match(negate,u.scheme,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'u': if(match(negate,u.username,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'k': if(match(negate,u.password,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'd': if(match(negate,u.domain,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'P': if(match(negate,u.port,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'p': if(match(negate,u.path,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'q': if(match(negate,u.query_string,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'f': if(match(negate,u.fragment_id,argv[i+1])) { printf("%s\n",copy); ret=0;} break;
- case 'D': //not sure how to look for a missing one of these. it'd be like d.
- if(u.domain && argv[i+1] && strlen(u.domain) >= strlen(argv[i+1]) && !strncmp(u.domain+strlen(u.domain)-strlen(argv[i+1]),argv[i+1],strlen(argv[i+1]))) {
- printf("%s\n",copy);
- ret=0;
- }
- break;
+ 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
+ }
+ 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;