/* ------------------------------------------------------------------- */
/* D2Mcgi.c  : CGI program for DC -> MARC conversion                   */
/* Author    : Ole Husby                                               */
/* Updated   : 1998-09-30                                              */
/* ------------------------------------------------------------------- */

/* -------------------------------------------------------------------
D2MCgi() will take metadata input from a parameter, or fetch an
HTML file using HTTP.

DC metadata will be converted into MARC, and presented in one of
several formats.

The program will look for the following QUERY_STRING:

url=xxx&fmt=xxx&prs=xxx&txt=xxx&par=xxx 

where: 

  url
      xxx = the URL for the file containing the metadata
  fmt
      The MARC format. xxx =
      DANMARC | FINMARC | ISMARC | NORMARC (default) | SWEMARC | USMARC.
  prs
      The presentation format. xxx =
      plain (default) | html | 2709 | binary.

  txt
      If present, this field will be parsed for metadata, and the only 
      use of the URL (if entered) will be used to produce the 856 field 
      of the MARC record. 

  par
      If xxx = on, the program will additionally display the tags as
      they are recognized. Will only work together with the html format.
   ------------------------------------------------------------------- */


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#include <unistd.h>
#include "d2m.h"




/* ------------------------------------------------------------------- */
/* main() program                                                      */
/* ------------------------------------------------------------------- */

int main ()
{
  int rc, i, source, textarea, f2709, tracing, mformat, marcfile;
  int linel, llen, slen;
  int *meta;

  FILE *df, *of;
  char contype[64], dfilename[64], tfilename[64], line[50000];
  char *pq, *p, *q, pre[16], *l, *u;
  char marcformat[256], url[1000], method[32];
  char *buffer[50000];
  char syntax[64];

  char recstatus = 'n';
  char rectype   = 'm';
  char biblevel  = ' ';

/* Initializing  */

  of = stdout;
  *url = 0;
  marcfile = 0;

  strcpy(marcformat, D2M_DEFAULT_FORMAT);
  strcpy(syntax, D2M_DEFAULT_SYNTAX);
  sprintf(dfilename, "%s.%d", D2M_TEMPFILE, getpid());

  textarea = tracing = f2709 = 0;
  *line = 0;


/* Decide parameters for line format formating   */

  linel = D2M_LINELEN;
  if (!linel)
    linel = 80;

  if (linel > 200)
    linel = 200;

  llen = linel - 9;
  slen = linel - 30;
  if (slen < 10)
    slen = 10;


/* Check request method (POST or GET)  */

  strcpy(method, getenv("REQUEST_METHOD"));

  if (strcmp(method, "GET") == 0)
  {
    strcpy(line, getenv("QUERY_STRING"));
    pq = (char *) strdup(line);
  }
  
  else if (strcmp(method, "POST") == 0)
    pq = poq();

  else
    pq = (char *) NULL;           /* Error exit is missing here ! */


/* Parse parameters  */
  
  if (pq)
  {
    strcpy(line, pq);
    free(pq);

    l = (char *) line;

    u = strtok(l, "&");
    while (u)
    {
      unescape(u);
      if (strncasecmp(u, "url=", 4) == 0)
        strcpy(url, u + 4); 
      else if (strncasecmp(u, "fmt=", 4) == 0)
        strcpy(marcformat, u + 4); 
      else if (strncasecmp(u, "prs=", 4) == 0)
        strcpy(syntax, u + 4); 
      else if (strncasecmp(u, "par=", 4) == 0)
      {
        if (strcmp(u + 4, "on") == 0) 
          tracing = 1;
      }
      else if (strncasecmp(u, "txt=", 4) == 0)
      {
        if (strlen(u + 4))
        {
          if ( df = fopen(dfilename, "w"))
          {
            fprintf(df, "%s", u + 4);
            textarea = 1;
            fclose(df);
          }
        }
      }
      u = strtok(NULL, "&");
    }
  }



/* Check the syntax */

  if (strcmp(syntax, "2709") == 0)
  {
    strcpy(contype, "text/plain");
    tracing = 0;
    f2709 = 1;
  }

  else if (strcmp(syntax, "binary") == 0)
  {
    strcpy(contype, "application/marc");
    tracing = 0;
    f2709 = 1;
  }

  else if (strcmp(syntax, "html") == 0)
  {
    strcpy(contype, "text/html");
  }

  else if (strcmp(syntax, "plain") == 0)
  {
    strcpy(contype, "text/plain");
    tracing = 0;
  }


/* Write HTTP header and HTML <HEAD>: */

  printf("Content-type: %s\n\n", contype);
  if (strcmp(syntax, "html") == 0)
  {
    printf("<html><head><title>\n");
    printf("%s\n", HTML_TITLE);
    printf("</title></head>\n\n<body bgcolor=\"#ffffbb\">\n");
  }



/* Check if metadata in input (source = TEXTAREA) or in URL   */

  if (!textarea && !*url)
  {
    printf("1: ");
    printf("Error: Insufficient input\n");
    exit(0);
  }

  else if (textarea)
    source = TEXTAREA;

  else
    source = URL;

  if (!textarea && !*url)
  {
    printf("2: ");
    printf("Error: Insufficient input\n");
    exit(0);
  }


/* Check the marcformat   */

  if (strncasecmp(marcformat, "DAN", 3) == 0)
    mformat = DANMARC;
  else if (strncasecmp(marcformat, "FIN", 3) == 0)
    mformat = FINMARC;
  else if (strncasecmp(marcformat, "IS", 2) == 0)
    mformat = ISMARC;
  else if (strncasecmp(marcformat, "US", 2) == 0)
    mformat = USMARC;
  else if (strncasecmp(marcformat, "NOR", 3) == 0)
    mformat = NORMARC;
  else if (strncasecmp(marcformat, "SWE", 3) == 0)
    mformat = SWEMARC;
  else
  {
    printf("Error: This MARC format is not supported!\n");
    exit(0);
  }


/* Fetch URL if necessary    */

  if (source == URL)
  {
    if (strcmp(url, "test") == 0)
      strcpy(url, D2M_DEFAULT_URL);
    rc = wfetch(&url, &dfilename);
    if (!rc)
    {
      printf("Error %d: Unable to fetch file %s\n", rc, url);
      exit(0);
    }
    if (rc == 2)
      marcfile = 1;
  }

  if (*url && !textarea && ( strcmp(syntax, "html") == 0 ) )
  {
    printf("<h2><a href=\"%s\">%s</a></h2>\n", url, url);
    printf("<h3>%s record:</h3><hr>\n", marcformat);
  }

   if (strcmp(syntax, "html") == 0)
     printf("<pre>\n");

   if (tracing)
     strcpy(tfilename, D2M_TRACEFILE);
   else
     *tfilename = 0;

/* Convert to MARC                                                    */
/* NOTE: M2Mconv() will even convert from MARC 2709 to line format    */

   if (marcfile)
     rc = M2Mconv((char *) dfilename, (char *) buffer,
                 (char *) tfilename, mformat);
   else            
     rc = D2Mconv((char *) dfilename, (char *) buffer,
                 (char *) tfilename, (char *) url, mformat);

   remove(dfilename);


/* Produce output                                                      */

   if (!rc)
     printf("Error: Unable to parse data\n");

   else
   {
     if (f2709)
       printf("%s", 
         (char *) MARC2709(buffer, 0, 6, recstatus, rectype, biblevel));
     else
  
     {
       l = strtok((char *) buffer, "\n");
  
       while (l)
       {
         write_field(l, of, linel, llen, slen);
         l = strtok(NULL, "\n");
       }
     }
   }

   if (*url && !textarea && ( strcmp(syntax, "html") == 0 ) )
     printf("<hr>\n");

   if (tracing)
   {
     printf("</pre>\n");
     printf("<h3>Parsed DC metadata:</h3>\n");
     printf("<pre>\n");
     write_trace(tfilename, of);
   }

   if (strcmp(syntax, "html") == 0)
   {
     printf("</pre>\n");
     printf("</body></html>\n");
   }
}
