aboutsummaryrefslogblamecommitdiffstats
path: root/uricut.c
blob: df8136e1bddd450fb119fe7da43a8060be58deed (plain) (tree)
1
2
3
4
5
6
7
8
9

                         

                
                  


                   
 





















                                                                     
                        
 
                                                                                                               
                                                         

                                 
           
              
                                                                            
             
                                                                               
                     


                    
              

                                                          

                                                             



                                                            
                                                                                     






















































                                                                             
               






                                                             

                       



                                                                                        

                      







                                                                       
                                                

           
                                    







                                                                   
                                  
                   
    
                                          









                
#define _XOPEN_SOURCE 500
#include <string.h>
#include "uri.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

/*
 schemes are case sensitive but cononicals are lower case.
 domain is case insensitive. return it lowercased?
 port is optional and in decimal
 path
 scheme://username:password@domain:port/path?query_string#fragment_id
 mailto:username@domain

 optional stuff:
 scheme, username, password, port, path, query_string, fragment_id
*/

#define AorB(a,b) ((a)?(a):(b))

#define F_SCHEME 1<<0
#define F_USERNAME 1<<1
#define F_PASSWORD 1<<2
#define F_DOMAIN 1<<3
#define F_PORT 1<<4
#define F_PATH 1<<5
#define F_QUERY_STRING 1<<6
#define F_FRAGMENT_ID 1<<7
#define F_WHOLE_URI 1<<8

char *long_opts[]={"scheme","username","password","domain","port","path","query_string","fragment_id","URI",0};
char *short_opts[]={"s","u","k","d","P","p","q","f","U"};

int main(int argc,char *argv[]) {
 char *uri;
 char *line=0;
 short args[256];//this needs to be a short to make room for the F_WHOLE_URI
 int i,j,c=0;
 int size=8192;//use this to increase max length of URIs we can read from stdin
 char at_least_one=0;
 char fixme=0;
 char using_stdin=1;
 char malloced=0;
 struct uri u;
 if(argc > 1) {
  if(!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) {
   printf("usage: echo uris | uricut [options]\n");
   printf("usage: uricut [options] uri [options] [uri]\n\n");
   printf("options: \n");
   for(i=0;long_opts[i];i++) {
    printf("        -%s|--%s\n",short_opts[i],long_opts[i]);
   }
   printf("To set default values use environment variables like: CUTURI_[OPTION]\n");
   return 2;
  }
 }
 argv++;
 argc--;
 while(1) {
  u.scheme=0;
  u.username=0;
  u.password=0;
  u.domain=0;
  u.port=0;
  u.path=0;
  u.query_string=0;
  u.fragment_id=0;
  if(!using_stdin) c=0;
  if(argc >= 1) {
   for(;argc>0;argc--,argv++) {
    for(i=0;long_opts[i];i++) {
     if(!strncmp(*argv,"--",2)) {
      if(!strcmp(*argv+2,long_opts[i])) {
       args[c]=1<<i;
       c++;
       break;
      }
     }
    }
    fixme=0;
    if(**argv=='-' && argv[0][1] != '-') {
     for(j=1;argv[0][j];j++) {
      for(i=0;short_opts[i];i++) {
       if(argv[0][j]==*short_opts[i]) {
        args[c]=1<<i;
        c++;
        fixme=1;
       }
      }
     }
    }
    if(fixme) continue;
    if(long_opts[i]) continue;
    //if we get here we are at data instead of flags. work on it.
    line=*argv;
    using_stdin=0;
    argc--;
    argv++;
    break;
   }
  }
  if(!argc && !line) {//if we are out of arguments and it didn't include data
   using_stdin=1;
  }
  if(using_stdin) {
   line=malloc(size+1);
   malloced=1;
   if(!fgets(line,size,stdin)) {
    free(line);
    return 0;
   }
  }
  if(!line) return 0;
  for(i=0;line[i] && line[i] != '\n' && line[i] != '\r';i++);
  line[i]=0;

  uri=strdup(line);
  urifromline(&u,line);

  // printf("scheme://username:password@domain:port/path?query_string#fragment_id\n\n");
  //let's set them to what'll get printed now...

   if(c) {
    for(i=0;i<c;i++) {
     if(args[i]&F_SCHEME) printf("%s\n",AorB(u.scheme,""));
     if(args[i]&F_USERNAME) printf("%s\n",AorB(u.username,""));
     if(args[i]&F_PASSWORD) printf("%s\n",AorB(u.password,""));
     if(args[i]&F_DOMAIN) printf("%s\n",AorB(u.domain,""));
     if(args[i]&F_PORT) printf("%s\n",AorB(u.port,""));
     if(args[i]&F_PATH) printf("%s\n",AorB(u.path,""));
     if(args[i]&F_QUERY_STRING) printf("%s\n",AorB(u.query_string,""));
     if(args[i]&F_FRAGMENT_ID) printf("%s\n",AorB(u.fragment_id,""));
     if(args[i]&F_WHOLE_URI) printf("%s\n",uri);
    }
   } else {
    if(at_least_one)   printf("\n");
    if(u.scheme)       printf("scheme: %s\n",u.scheme);
    if(u.username)     printf("username: %s\n",u.username);
    if(u.password)     printf("password: %s\n",u.password);
    if(u.domain)       printf("domain: %s\n",u.domain);
    if(u.port)         printf("port: %s\n",u.port);
    if(u.path)         printf("path: %s\n",u.path);
    if(u.query_string) printf("query_string: %s\n",u.query_string);
    if(u.fragment_id)  printf("fragment_id: %s\n",u.fragment_id);
    printf("whole_uri: %s\n",uri);
    at_least_one=1;
   }
  free(uri);//this is definitely malloc()d
  if(malloced) {
   free(line);
   malloced=0;
   line=0;
  } else {
   line=0;//???
  }
 }
 return 0;
}