/*
 * title:       head.c
 *
 * authors:     Craig E. Ward
 *              Kholoud Khateeb
 *              CMSI 698, Homework 3, Problem 3
 *              Spring 2003
 *
 * environment: ANSI C (GCC)
 *
 * description:
 *              This program accepts one command line argument that is assumed
 *              to be a URI with "http" as the protocol. It parses the URI and
 *              displays the minimum HTTP 1.1 headers that would result were
 *              the URI used with the GET method.
 *
 *              The minimum HTTP 1.1 headers for a GET method are:
 *
 *                  GET document HTTP/1.1
 *                  Host: hostname
 *
 * build:       cc -ansi -g -Wall -o head head.c
 *
 * usage:       head {uri}
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* definitions */
#define HEADER_BUFFER_MAX 1024
#define HOST_BUFFER_MAX 256
#define PATH_BUFFER_MAX 256

/* static function prototypes */
static char * build_http_get_header(char *);

/* uninitialized data */
char *progname;

int main(int argc, char *argv[])
{
  /* 
   * Strip path from command if there is one
   */
  progname = strrchr(argv[0], '/');
  if (progname != NULL) 
    progname++; 
  else
    progname = argv[0];

  /* 
   * Minimalist sanity check: see that this is just one argument
   */
  if (argc != 2) {
    printf("%s: usage %s {uri}\n\tExample: %s http://www.oasis-nss.org/calend"
           "ar.html\n", progname, progname, progname);
    exit(EXIT_FAILURE);
  }
  /*
   * Break it apart and display
   */
  printf("%s\n", build_http_get_header(argv[1]));

  exit(EXIT_SUCCESS);
}

/*
 * Break the URI string into tokens and assemble into a header
 */
static char *build_http_get_header(char *uri)
{
  static char header_buffer[HEADER_BUFFER_MAX];
  char hostname[HOST_BUFFER_MAX];
  char path[PATH_BUFFER_MAX];
  char *token = NULL;

  memset(hostname, '\0', sizeof hostname);
  memset(path, '\0', sizeof path);
  path[0] = '/';                /* default root file */

  /*
   * Get the hostname part
   */
  token = strtok(uri,"/");      /* eat http */
  token = strtok(NULL, "/");    /* find host part */
  strncpy(hostname, token, (sizeof hostname) - 1);
  /*
   * Check hostname for a port; cut it out if it is the default (:80)
   */
  char *portpart = strchr(hostname,':');
  if (portpart != NULL     &&
      *(portpart+1) == '8' &&
      *(portpart+2) == '0' &&
      *(portpart+3) == '\0') {
    *portpart = '\0';
  }
  
  /*
   * Get remain path data up to a posible fragment marker
   */
  token = strtok(NULL, "#");
  if (token != NULL)
    strncpy(path+1, token, (sizeof hostname) - 2);

  sprintf(header_buffer, "GET %s HTTP/1.1\nHost: %s\n",
          path, hostname);
  return header_buffer;
}
