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