summaryrefslogtreecommitdiff
path: root/urimatch.c
blob: 641ed45dfecda69d61b9e2beb081848ec2146d6d (plain) (blame)
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;
}