#include "uri.h" #include #include #include #include #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(signed 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[]) {//argument needs to be the URI int j; int ret=1; struct uri *u = malloc(sizeof(struct uri)); char matches; signed char rule=MATCH_PATTERN; char *line=malloc(LINE_LENGTH); char *a,*b,*c; char *command; char all=0; int verbose=0; if(argc > 1) { if(!strcmp(argv[1],"-a")) { all=1; argv++; argc--; } if(!strcmp(argv[1],"-v")) { verbose++; argv++; argc--; } } if(argc < 2) { fprintf(stderr,"usage: urigetline [-a] uri < uristart.conf\n"); free(u); return 1; } urifromline(u,argv[1]);//only argv[1] is a URI? for(;fgets(line,LINE_LENGTH-1,stdin);) {//each line comes from the config. we need to split it on spaces. if(strchr(line,'\r')) *strchr(line,'\r')=0; if(strchr(line,'\n')) *strchr(line,'\n')=0; if(*line == '#') continue; //skip this line too. comment. if(strlen(line) == 0) continue; //skip empty lines. if((command=strstr(line,":\t"))) {//this is the "real" separator between match pattern and command *command=0; command++; while(*command == '\t') command++;//and command may have leading tabs that are ignored. if(verbose) fprintf(stderr,"loading config line: '%s'\n",line); } else { fprintf(stderr,"invalid line: '%s'\n",line); continue;//skip this line. needs at least one ":\t" to work. } a=line; matches=1; for(;a && *a;) { rule=MATCH_PATTERN; j=0; switch(a[0]) { case '-': j=1; rule=MATCH_PATTERN; break; case 'n': j=1; rule=MATCH_UNEXIST; break; case 'r': j=1; rule=MATCH_REVERSE; break; default: break; } b=0; c=0; if(rule != MATCH_UNEXIST) { if(!(b=strchr(a,' '))) { fprintf(stderr,"argument '%s' wants a value in the next argument and didn't get it. throwing a fit. (pass -v to urigetline to help debug)\n",a); free(u); return 2; } *b=0; b++; if((c=strchr(b,' '))) {//not required *c=0; c++; } } else { if((c=strchr(a,' '))) { *c=0; c++; } } switch(a[j]) { case 's': if(!match(rule,u->scheme,b)) { matches=0;} break; case 'u': if(!match(rule,u->username,b)) { matches=0;} break; case 'k': if(!match(rule,u->password,b)) { matches=0;} break; case 'd': if(!match(rule,u->domain,b)) { matches=0;} break; case 'P': if(!match(rule,u->port,b)) { matches=0;} break; case 'p': if(!match(rule,u->path,b)) { matches=0;} break; case 'q': if(!match(rule,u->query_string,b)) { matches=0;} break; case 'f': if(!match(rule,u->fragment_id,b)) { matches=0;} break; break; default: fprintf(stderr,"unknown url part letter! %s\n",a); free(u); return 3; } //if(b) printf("two: %s %s\n",a,b); //else printf("one: %s\n",a); a=c; } if(matches) { //printf("comm: %s\n",command); printf("%s\n",command); if(!all) { free(u); return ret;//bail early if we only need first match } } } free(u); return ret; }