While working on a semi complex redirection script I came accross a library that allows you to write C programs to cgi scripts.

I only know of a *nix version.
The library is called libcgicg1 and libcgicg1-dev

Only negetive I have been able to find is that it uses a shared library. Which means that if the server you are running the script on doesn't have the shared library you have to use the -static parameter for GCC which greatly increases the file size.

This post was purely informational. The script as it stands now is below.

Happy coding
#include <cgic.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <fcntl.h>

typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;

int ping_host (char *);

int cgiMain()
  FILE *fp;
  int ping_return;
  char addy[20];


  fprintf(cgiOut, "<HTML><HEAD><TITLE>Redirection Test</TITLE>");
  if ( (fp=fopen("ip.dat", "r")) == NULL)
    fprintf(cgiOut, "</HEAD>Could not open the file\n");
    return 1;

  fgets(addy, sizeof addy, fp);
  if ( addy [ strlen(addy)-1] == '\n')

  if ( (ping_return = ping_host(addy)) <= 0)
    if (ping_return == 0)
      fprintf(cgiOut, "Sorry but the server is not reachable at the moment");
    if (ping_return == -1)
      fprintf(cgiOut, "Unable to acquire a socket so unable to tell if the server is reachable or not");
    fprintf(cgiOut, "</BODY></HTML>");
    return 1;

  fprintf(cgiOut, "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=http://%s/\"></HEAD>", addy);
  fprintf(cgiOut, "<BODY>Redirecting you to the server.<BR><BR><BR>");
  fprintf(cgiOut, "This script was created with help from CGIC libraries\n");
  fprintf(cgiOut, "<BR>%s...\n", addy);
  fprintf(cgiOut, "</BODY></HTML>");
  return 0;

int ping_host(char *addy)
  sockaddr_in addr;
  int sock, ret;
  fd_set set;
  struct timeval timeout = {10, 0};

  if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    return -1;

  addr.sin_family = AF_INET;
  addr.sin_port = htons(80);
  addr.sin_addr.s_addr = inet_addr(addy);
  memset(&(addr.sin_zero), '\0', 8);

  FD_SET(sock, &set);

  fcntl(sock, F_SETFL, O_NONBLOCK);

  if ( (ret = connect (sock, (sockaddr *)&addr, sizeof (sockaddr))) == -1)
    if ( errno != EINPROGRESS )
      return 0;

  ret = select(sock+1, NULL, &set, NULL, &timeout);


  if ( FD_ISSET(sock, &set) )
    return 1;

  return 0;