-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: uritools
action: blob
revision:
path_from: urigetline.c
revision_from: refs/heads/master:
path_to:
revision_to:

git.thebackupbox.net

uritools

git://git.thebackupbox.net/uritools

blob of:

uritools

/ urigetline.c

refs/heads/master:/urigetline.c
 #define _XOPEN_SOURCE 500
 #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(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,strdup(argv[1]));
   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;
 }

-- Response ended

-- Page fetched on Sun Jun 2 16:52:49 2024