Blame cgi-bin/help.c

Packit 2fc92b
/*
Packit 2fc92b
 * Online help CGI for CUPS.
Packit 2fc92b
 *
Packit 2fc92b
 * Copyright 2007-2011 by Apple Inc.
Packit 2fc92b
 * Copyright 1997-2006 by Easy Software Products.
Packit 2fc92b
 *
Packit 2fc92b
 * These coded instructions, statements, and computer programs are the
Packit 2fc92b
 * property of Apple Inc. and are protected by Federal copyright
Packit 2fc92b
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
Packit 2fc92b
 * which should have been included with this file.  If this file is
Packit 2fc92b
 * missing or damaged, see the license at "http://www.cups.org/".
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * Include necessary headers...
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
#include "cgi-private.h"
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'main()' - Main entry for CGI.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
int					/* O - Exit status */
Packit 2fc92b
main(int  argc,				/* I - Number of command-line arguments */
Packit 2fc92b
     char *argv[])			/* I - Command-line arguments */
Packit 2fc92b
{
Packit 2fc92b
  help_index_t	*hi,			/* Help index */
Packit 2fc92b
		*si;			/* Search index */
Packit 2fc92b
  help_node_t	*n;			/* Current help node */
Packit 2fc92b
  int		i;			/* Looping var */
Packit 2fc92b
  const char	*query;			/* Search query */
Packit 2fc92b
  const char	*cache_dir;		/* CUPS_CACHEDIR environment variable */
Packit 2fc92b
  const char	*docroot;		/* CUPS_DOCROOT environment variable */
Packit 2fc92b
  const char	*helpfile,		/* Current help file */
Packit 2fc92b
		*helptitle = NULL;	/* Current help title */
Packit 2fc92b
  const char	*topic;			/* Current topic */
Packit 2fc92b
  char		topic_data[1024];	/* Topic form data */
Packit 2fc92b
  const char	*section;		/* Current section */
Packit 2fc92b
  char		filename[1024],		/* Filename */
Packit 2fc92b
		directory[1024];	/* Directory */
Packit 2fc92b
  cups_file_t	*fp;			/* Help file */
Packit 2fc92b
  char		line[1024];		/* Line from file */
Packit 2fc92b
  int		printable;		/* Show printable version? */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Get any form variables...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  cgiInitialize();
Packit 2fc92b
Packit 2fc92b
  printable = cgiGetVariable("PRINTABLE") != NULL;
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Set the web interface section...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  cgiSetVariable("SECTION", "help");
Packit 2fc92b
  cgiSetVariable("REFRESH_PAGE", "");
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Load the help index...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  if ((cache_dir = getenv("CUPS_CACHEDIR")) == NULL)
Packit 2fc92b
    cache_dir = CUPS_CACHEDIR;
Packit 2fc92b
Packit 2fc92b
  snprintf(filename, sizeof(filename), "%s/help.index", cache_dir);
Packit 2fc92b
Packit 2fc92b
  if ((docroot = getenv("CUPS_DOCROOT")) == NULL)
Packit 2fc92b
    docroot = CUPS_DOCROOT;
Packit 2fc92b
Packit 2fc92b
  snprintf(directory, sizeof(directory), "%s/help", docroot);
Packit 2fc92b
Packit 2fc92b
  fprintf(stderr, "DEBUG: helpLoadIndex(filename=\"%s\", directory=\"%s\")\n",
Packit 2fc92b
          filename, directory);
Packit 2fc92b
Packit 2fc92b
  hi = helpLoadIndex(filename, directory);
Packit 2fc92b
  if (!hi)
Packit 2fc92b
  {
Packit 2fc92b
    perror(filename);
Packit 2fc92b
Packit 2fc92b
    cgiStartHTML(cgiText(_("Online Help")));
Packit 2fc92b
    cgiSetVariable("ERROR", cgiText(_("Unable to load help index.")));
Packit 2fc92b
    cgiCopyTemplateLang("error.tmpl");
Packit 2fc92b
    cgiEndHTML();
Packit 2fc92b
Packit 2fc92b
    return (1);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  fprintf(stderr, "DEBUG: %d nodes in help index...\n",
Packit 2fc92b
          cupsArrayCount(hi->nodes));
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * See if we are viewing a file...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  for (i = 0; i < argc; i ++)
Packit 2fc92b
    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
Packit 2fc92b
Packit 2fc92b
  if ((helpfile = getenv("PATH_INFO")) != NULL)
Packit 2fc92b
  {
Packit 2fc92b
    helpfile ++;
Packit 2fc92b
Packit 2fc92b
    if (!*helpfile)
Packit 2fc92b
      helpfile = NULL;
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  if (helpfile)
Packit 2fc92b
  {
Packit 2fc92b
   /*
Packit 2fc92b
    * Verify that the help file exists and is part of the index...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    snprintf(filename, sizeof(filename), "%s/help/%s", docroot, helpfile);
Packit 2fc92b
Packit 2fc92b
    fprintf(stderr, "DEBUG: helpfile=\"%s\", filename=\"%s\"\n",
Packit 2fc92b
            helpfile, filename);
Packit 2fc92b
Packit 2fc92b
    if (access(filename, R_OK))
Packit 2fc92b
    {
Packit 2fc92b
      perror(filename);
Packit 2fc92b
Packit 2fc92b
      cgiStartHTML(cgiText(_("Online Help")));
Packit 2fc92b
      cgiSetVariable("ERROR", cgiText(_("Unable to access help file.")));
Packit 2fc92b
      cgiCopyTemplateLang("error.tmpl");
Packit 2fc92b
      cgiEndHTML();
Packit 2fc92b
Packit 2fc92b
      return (1);
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    if ((n = helpFindNode(hi, helpfile, NULL)) == NULL)
Packit 2fc92b
    {
Packit 2fc92b
      cgiStartHTML(cgiText(_("Online Help")));
Packit 2fc92b
      cgiSetVariable("ERROR", cgiText(_("Help file not in index.")));
Packit 2fc92b
      cgiCopyTemplateLang("error.tmpl");
Packit 2fc92b
      cgiEndHTML();
Packit 2fc92b
Packit 2fc92b
      return (1);
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
   /*
Packit 2fc92b
    * Save the page title and help file...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    helptitle = n->text;
Packit 2fc92b
    topic     = n->section;
Packit 2fc92b
Packit 2fc92b
   /*
Packit 2fc92b
    * Send a standard page header...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    if (printable)
Packit 2fc92b
      puts("Content-Type: text/html;charset=utf-8\n");
Packit 2fc92b
    else
Packit 2fc92b
      cgiStartHTML(n->text);
Packit 2fc92b
  }
Packit 2fc92b
  else
Packit 2fc92b
  {
Packit 2fc92b
   /*
Packit 2fc92b
    * Send a standard page header...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    cgiStartHTML(cgiText(_("Online Help")));
Packit 2fc92b
Packit 2fc92b
    topic = cgiGetVariable("TOPIC");
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Do a search as needed...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  if (cgiGetVariable("CLEAR"))
Packit 2fc92b
    cgiSetVariable("QUERY", "");
Packit 2fc92b
Packit 2fc92b
  query = cgiGetVariable("QUERY");
Packit 2fc92b
  si    = helpSearchIndex(hi, query, topic, helpfile);
Packit 2fc92b
Packit 2fc92b
  cgiClearVariables();
Packit 2fc92b
  if (query)
Packit 2fc92b
    cgiSetVariable("QUERY", query);
Packit 2fc92b
  if (topic)
Packit 2fc92b
    cgiSetVariable("TOPIC", topic);
Packit 2fc92b
  if (helpfile)
Packit 2fc92b
    cgiSetVariable("HELPFILE", helpfile);
Packit 2fc92b
  if (helptitle)
Packit 2fc92b
    cgiSetVariable("HELPTITLE", helptitle);
Packit 2fc92b
Packit 2fc92b
  fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n",
Packit 2fc92b
          query ? query : "(null)", topic ? topic : "(null)");
Packit 2fc92b
Packit 2fc92b
  if (si)
Packit 2fc92b
  {
Packit 2fc92b
    help_node_t	*nn;			/* Parent node */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
    fprintf(stderr,
Packit 2fc92b
            "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si,
Packit 2fc92b
            si->sorted, cupsArrayCount(si->sorted));
Packit 2fc92b
Packit 2fc92b
    for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted);
Packit 2fc92b
         n;
Packit 2fc92b
	 i ++, n = (help_node_t *)cupsArrayNext(si->sorted))
Packit 2fc92b
    {
Packit 2fc92b
      if (helpfile && n->anchor)
Packit 2fc92b
        snprintf(line, sizeof(line), "#%s", n->anchor);
Packit 2fc92b
      else if (n->anchor)
Packit 2fc92b
        snprintf(line, sizeof(line), "/help/%s?QUERY=%s#%s", n->filename,
Packit 2fc92b
	         query ? query : "", n->anchor);
Packit 2fc92b
      else
Packit 2fc92b
        snprintf(line, sizeof(line), "/help/%s?QUERY=%s", n->filename,
Packit 2fc92b
	         query ? query : "");
Packit 2fc92b
Packit 2fc92b
      cgiSetArray("QTEXT", i, n->text);
Packit 2fc92b
      cgiSetArray("QLINK", i, line);
Packit 2fc92b
Packit 2fc92b
      if (!helpfile && n->anchor)
Packit 2fc92b
      {
Packit 2fc92b
        nn = helpFindNode(hi, n->filename, NULL);
Packit 2fc92b
Packit 2fc92b
        snprintf(line, sizeof(line), "/help/%s?QUERY=%s", nn->filename,
Packit 2fc92b
	         query ? query : "");
Packit 2fc92b
Packit 2fc92b
        cgiSetArray("QPTEXT", i, nn->text);
Packit 2fc92b
	cgiSetArray("QPLINK", i, line);
Packit 2fc92b
      }
Packit 2fc92b
      else
Packit 2fc92b
      {
Packit 2fc92b
        cgiSetArray("QPTEXT", i, "");
Packit 2fc92b
	cgiSetArray("QPLINK", i, "");
Packit 2fc92b
      }
Packit 2fc92b
Packit 2fc92b
      fprintf(stderr, "DEBUG: [%d] = \"%s\" @ \"%s\"\n", i, n->text, line);
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    helpDeleteIndex(si);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * OK, now list the bookmarks within the index...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  for (i = 0, section = NULL, n = (help_node_t *)cupsArrayFirst(hi->sorted);
Packit 2fc92b
       n;
Packit 2fc92b
       n = (help_node_t *)cupsArrayNext(hi->sorted))
Packit 2fc92b
  {
Packit 2fc92b
    if (n->anchor)
Packit 2fc92b
      continue;
Packit 2fc92b
Packit 2fc92b
   /*
Packit 2fc92b
    * Add a section link as needed...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    if (n->section &&
Packit 2fc92b
        (!section || strcmp(n->section, section)))
Packit 2fc92b
    {
Packit 2fc92b
     /*
Packit 2fc92b
      * Add a link for this node...
Packit 2fc92b
      */
Packit 2fc92b
Packit 2fc92b
      snprintf(line, sizeof(line), "/help/?TOPIC=%s&QUERY=%s",
Packit 2fc92b
               cgiFormEncode(topic_data, n->section, sizeof(topic_data)),
Packit 2fc92b
	       query ? query : "");
Packit 2fc92b
      cgiSetArray("BMLINK", i, line);
Packit 2fc92b
      cgiSetArray("BMTEXT", i, n->section);
Packit 2fc92b
      cgiSetArray("BMINDENT", i, "0");
Packit 2fc92b
Packit 2fc92b
      i ++;
Packit 2fc92b
      section = n->section;
Packit 2fc92b
    }
Packit 2fc92b
Packit 2fc92b
    if (!topic || !n->section || strcmp(n->section, topic))
Packit 2fc92b
      continue;
Packit 2fc92b
Packit 2fc92b
   /*
Packit 2fc92b
    * Add a link for this node...
Packit 2fc92b
    */
Packit 2fc92b
Packit 2fc92b
    snprintf(line, sizeof(line), "/help/%s?TOPIC=%s&QUERY=%s", n->filename,
Packit 2fc92b
             cgiFormEncode(topic_data, n->section, sizeof(topic_data)),
Packit 2fc92b
	     query ? query : "");
Packit 2fc92b
    cgiSetArray("BMLINK", i, line);
Packit 2fc92b
    cgiSetArray("BMTEXT", i, n->text);
Packit 2fc92b
    cgiSetArray("BMINDENT", i, "1");
Packit 2fc92b
Packit 2fc92b
    i ++;
Packit 2fc92b
Packit 2fc92b
    if (helpfile && !strcmp(helpfile, n->filename))
Packit 2fc92b
    {
Packit 2fc92b
      help_node_t	*nn;		/* Pointer to sub-node */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
      cupsArraySave(hi->sorted);
Packit 2fc92b
Packit 2fc92b
      for (nn = (help_node_t *)cupsArrayFirst(hi->sorted);
Packit 2fc92b
           nn;
Packit 2fc92b
	   nn = (help_node_t *)cupsArrayNext(hi->sorted))
Packit 2fc92b
        if (nn->anchor && !strcmp(helpfile, nn->filename))
Packit 2fc92b
	{
Packit 2fc92b
	 /*
Packit 2fc92b
	  * Add a link for this node...
Packit 2fc92b
	  */
Packit 2fc92b
Packit 2fc92b
	  snprintf(line, sizeof(line), "#%s", nn->anchor);
Packit 2fc92b
	  cgiSetArray("BMLINK", i, line);
Packit 2fc92b
	  cgiSetArray("BMTEXT", i, nn->text);
Packit 2fc92b
	  cgiSetArray("BMINDENT", i, "2");
Packit 2fc92b
Packit 2fc92b
	  i ++;
Packit 2fc92b
	}
Packit 2fc92b
Packit 2fc92b
      cupsArrayRestore(hi->sorted);
Packit 2fc92b
    }
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Show the search and bookmark content...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  if (!helpfile || !printable)
Packit 2fc92b
    cgiCopyTemplateLang("help-header.tmpl");
Packit 2fc92b
  else
Packit 2fc92b
    cgiCopyTemplateLang("help-printable.tmpl");
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * If we are viewing a file, copy it in now...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  if (helpfile)
Packit 2fc92b
  {
Packit 2fc92b
    if ((fp = cupsFileOpen(filename, "r")) != NULL)
Packit 2fc92b
    {
Packit 2fc92b
      int	inbody;			/* Are we inside the body? */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
      inbody = 0;
Packit 2fc92b
Packit 2fc92b
      while (cupsFileGets(fp, line, sizeof(line)))
Packit 2fc92b
      {
Packit 2fc92b
        if (inbody)
Packit 2fc92b
	{
Packit 2fc92b
	  if (!_cups_strncasecmp(line, "</BODY>", 7))
Packit 2fc92b
	    break;
Packit 2fc92b
Packit 2fc92b
	  printf("%s\n", line);
Packit 2fc92b
        }
Packit 2fc92b
	else if (!_cups_strncasecmp(line, "
Packit 2fc92b
	  inbody = 1;
Packit 2fc92b
      }
Packit 2fc92b
Packit 2fc92b
      cupsFileClose(fp);
Packit 2fc92b
    }
Packit 2fc92b
    else
Packit 2fc92b
    {
Packit 2fc92b
      perror(filename);
Packit 2fc92b
      cgiSetVariable("ERROR", cgiText(_("Unable to open help file.")));
Packit 2fc92b
      cgiCopyTemplateLang("error.tmpl");
Packit 2fc92b
    }
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Send a standard trailer...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  if (!printable)
Packit 2fc92b
  {
Packit 2fc92b
    cgiCopyTemplateLang("help-trailer.tmpl");
Packit 2fc92b
    cgiEndHTML();
Packit 2fc92b
  }
Packit 2fc92b
  else
Packit 2fc92b
    puts("</BODY>\n</HTML>");
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Delete the index...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  helpDeleteIndex(hi);
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Return with no errors...
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  return (0);
Packit 2fc92b
}