#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define NUMHANDS (sizeof(handlers)/sizeof(handlers[0]))

static const char *handlers[][2] = {
       /* pattern, program */
       { "http",       "lynx" },
       { "https",      "lynx" },
       { "gopher",     "sacc" },
       { "magnet",     "aria2c" },
       { "ssh",        "ssh" },
       { "telnet",     "telnet" },
};

static int getpre(char[], int, char *);
static int gethand(char[], int);

/* recieve uri and parse for prefix. return prefix length */
static int
getpre(char p[], int lim, char *uri)
{
       int i;

       for (i = 0; *uri != '\0' && *uri != ':' && i < lim - 1;
           ++i && ++uri)
               p[i] = *uri;
       p[i] = '\0';
       return i;
}

/* compare prefix to avail. handlers, return index of match, -1 on err */
static int
gethand(char pre[], int len)
{
       int i;

       for (i = 0; i < NUMHANDS; ++i) {
               if (strncmp(pre, handlers[i][0], len) == 0)
                       break;
       }
       if (i == NUMHANDS)
               i = -1;
       return i;
}

/*
* The goal of plumber is that when given a string, run the appropriate
* tool for it. e.g. If the string is a url, run a browser; If it's
* a magnet link, open a torrent client. Plumber should also be
* easy to configure to define new handlers.
*/
int
main(int argc, char *argv[])
{
       char pre[10];
       int hi;
       int len;

       if (argc < 2)
               errx(1, "no uri");
       len = getpre(pre, 10, argv[1]);
       hi = gethand(pre, len);
       if (hi == -1)
               errx(1, "handler not defined");
       execlp(handlers[hi][1], handlers[hi][1], argv[1], NULL);
       return 0;
}