/*
 * cgi-wrap.c:
 *
 * Copyright (c) 2002 James McKenzie <james@fishsoup.dhs.org>,
 * All rights reserved.
 *
 */

static char rcsid[] =
  "$Id: globe.c,v 1.3 2002/08/26 09:41:06 root Exp root $";

/*
 * $Log: globe.c,v $
 * Revision 1.3  2002/08/26 09:41:06  root
 * #
 *
 * Revision 1.2  2002/08/24 13:45:45  root
 * #
 *
 * Revision 1.1  2002/08/24 13:38:11  root
 * #
 *
 * Revision 1.1  2002/08/24 08:08:48  root
 * #
 *
 */

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

unsigned char uribuf[1024];

#define invalid() do_invalid(__LINE__)

static void
do_invalid (int line)
{
  printf ("Content-Type: text/plain\n\nInvalid request at line %d\n", line);
  exit (0);
}

static int
xdigittoi (unsigned char c)
{
  switch (c)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      return c - '0';

    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
    case 'A':
    case 'B':
    case 'C':
    case 'D':
    case 'E':
    case 'F':
      return 10 + ((c | 32) - 'a');
    }
  return 0;
}




static void
uridecode (unsigned char *uri)
{
  unsigned char *ptr;
  int len = sizeof (uribuf) - 2;

  if (!uri)
    invalid ();

  ptr = uribuf;

  while (len)
    {
      switch (*uri)
        {
        case 0:
          *ptr = 0;
          return;
        case '%':
          if ((!uri[1]) || (!uri[2]))
            invalid ();
          *(ptr++) = (xdigittoi (uri[1]) << 4) + xdigittoi (uri[2]);
          uri += 3;
          break;
        default:
          *(ptr++) = *(uri++);
          len--;
        }
    }
  *ptr = 0;
}

int
main (int argc, char *argv[])
{
  pid_t pid;
  char *envp[] =
    {
"PATH=/software/bin:/usr/openwin/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin",
    "LD_LIBRARY_PATH=/software/lib:/usr/openwin/lib:/usr/lib:/lib", (char *) 0
  };
  char mbuf[1024];
  char buf[1024];
  char *argvp[] = { "make", mbuf, (char *) 0 };
  //char *argvp[] = { "bash","-c","set", (char *) 0 };
  double lat = 0.0, lon = 0.0, dist = 4000.0;
  unsigned char *ptr;
  unsigned char *uri = getenv ("REQUEST_URI");
  int fd;
  int status;

  signal (SIGTERM, SIG_IGN);
  signal (SIGINT, SIG_IGN);
  signal (SIGPIPE, SIG_IGN);

  if (chdir ("/root/projects/earthview/images"))
    invalid ();

  seteuid (0);
  setuid (0);
  seteuid (0);
  setuid (0);
  setegid (0);
  setgid (0);
  setegid (0);
  setgid (0);

  if (!uri)
    invalid ();

  uridecode (uri);


  ptr = strpbrk (uribuf, "?");

  if (!ptr || (!strlen (ptr + 1)))
    {
      sprintf (buf, "hemispheres.asis");
    }
  else
    {
      ptr++;

      switch (*ptr)
        {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case '+':
        case '-':
        case '.':
          lat = atof (ptr);
          break;
        default:
#define DELIMITERS ", :;latondis="
          ptr = strpbrk (ptr, DELIMITERS);
          if (ptr)
            ptr += strspn (ptr, DELIMITERS);
          if ((!ptr) || (!(*ptr)))
            invalid ();
          lat = atof (ptr);
          break;
        }

      ptr = strpbrk (ptr + 1, DELIMITERS);
      if (ptr)
        ptr += strspn (ptr, DELIMITERS);
      if ((!ptr) || (!(*ptr)))
        invalid ();
      lon = atof (ptr);
      ptr = strpbrk (ptr + 1, DELIMITERS);
      if (ptr)
        ptr += strspn (ptr, DELIMITERS);
      if (ptr)
        {
          dist = atof (ptr);
        }
      else
        {
          dist = 1000.0;
        }
      sprintf (buf, "globe;%.1f_%.1f_%.1f;asis", lat, lon, dist);
      ptr = buf;
      while (*ptr)
        {
          if (*ptr == '.')
            *ptr = ',';
          if (*ptr == ';')
            *ptr = '.';
          ptr++;
        }

    }

  strcpy (mbuf, "NOBACKUP/");
  strcat (mbuf, buf);

  puts ("Content-type: text/html");
  puts ("expires: Tuesday, 13-Jan-94 12:12:12 GMT");
  puts ("pragma: no-cache");
  puts ("");

  puts ("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
  puts ("<html>");
  puts ("<head></head>");
  puts
    ("<body text=\"#FFFFFF\" bgcolor=\"#000000\" link=\"#0000FF\" vlink=\"#9400D3\" alink=\"#FF0000\">");
  puts
    ("<center><font size=+2>Your images are rendering... please wait</font><br>");
  puts ("once loaded they will refresh every 4 mins...<br>");
  printf ("Lat=%f Lon=%f Dist=%f\n", lat, lon, dist);
  puts ("</center>");
  puts ("<pre>");

  fflush (stdout);

  while ((fd =
          open ("/tmp/globelock", O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0)
    {
      puts ("Waiting for lock...");
      fflush (stdout);
      sleep (5);
    }

  if ((pid = fork ()) == 0)
    {
      dup2 (1, 2);
      execve ("/usr/bin/make", argvp, envp);
      exit (1);
    }
  waitpid (pid, &status, 0);
  fflush (stdout);
  puts ("</pre>\n");


  sleep (1);
  if (!WEXITSTATUS (status))
    {
      puts ("<script language=\"JavaScript\">\n<!--\n");
      printf ("window.location.href = \"/globe/%s\";\n", buf);
      puts ("// -->\n</script>\n");
    }
  else
    {
      puts ("<font color=\"#ff3f3f\">An error occured - sorry</font>");
    }

  puts ("</body>\n</html>\n");

  fflush (stdout);

  unlink ("/tmp/globelock");
}
