1/*
2 * "$Id: help.c 11093 2013-07-03 20:48:42Z msweet $"
3 *
4 *   Online help CGI for CUPS.
5 *
6 *   Copyright 2007-2011 by Apple Inc.
7 *   Copyright 1997-2006 by Easy Software Products.
8 *
9 *   These coded instructions, statements, and computer programs are the
10 *   property of Apple Inc. and are protected by Federal copyright
11 *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
12 *   which should have been included with this file.  If this file is
13 *   file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * Contents:
16 *
17 *   main() - Main entry for CGI.
18 */
19
20/*
21 * Include necessary headers...
22 */
23
24#include "cgi-private.h"
25
26
27/*
28 * 'main()' - Main entry for CGI.
29 */
30
31int					/* O - Exit status */
32main(int  argc,				/* I - Number of command-line arguments */
33     char *argv[])			/* I - Command-line arguments */
34{
35  help_index_t	*hi,			/* Help index */
36		*si;			/* Search index */
37  help_node_t	*n;			/* Current help node */
38  int		i;			/* Looping var */
39  const char	*query;			/* Search query */
40  const char	*cache_dir;		/* CUPS_CACHEDIR environment variable */
41  const char	*docroot;		/* CUPS_DOCROOT environment variable */
42  const char	*helpfile,		/* Current help file */
43		*helptitle = NULL;	/* Current help title */
44  const char	*topic;			/* Current topic */
45  char		topic_data[1024];	/* Topic form data */
46  const char	*section;		/* Current section */
47  char		filename[1024],		/* Filename */
48		directory[1024];	/* Directory */
49  cups_file_t	*fp;			/* Help file */
50  char		line[1024];		/* Line from file */
51  int		printable;		/* Show printable version? */
52
53
54 /*
55  * Get any form variables...
56  */
57
58  cgiInitialize();
59
60  printable = cgiGetVariable("PRINTABLE") != NULL;
61
62 /*
63  * Set the web interface section...
64  */
65
66  cgiSetVariable("SECTION", "help");
67  cgiSetVariable("REFRESH_PAGE", "");
68
69 /*
70  * Load the help index...
71  */
72
73  if ((cache_dir = getenv("CUPS_CACHEDIR")) == NULL)
74    cache_dir = CUPS_CACHEDIR;
75
76  snprintf(filename, sizeof(filename), "%s/help.index", cache_dir);
77
78  if ((docroot = getenv("CUPS_DOCROOT")) == NULL)
79    docroot = CUPS_DOCROOT;
80
81  snprintf(directory, sizeof(directory), "%s/help", docroot);
82
83  fprintf(stderr, "DEBUG: helpLoadIndex(filename=\"%s\", directory=\"%s\")\n",
84          filename, directory);
85
86  hi = helpLoadIndex(filename, directory);
87  if (!hi)
88  {
89    perror(filename);
90
91    cgiStartHTML(cgiText(_("Online Help")));
92    cgiSetVariable("ERROR", cgiText(_("Unable to load help index.")));
93    cgiCopyTemplateLang("error.tmpl");
94    cgiEndHTML();
95
96    return (1);
97  }
98
99  fprintf(stderr, "DEBUG: %d nodes in help index...\n",
100          cupsArrayCount(hi->nodes));
101
102 /*
103  * See if we are viewing a file...
104  */
105
106  for (i = 0; i < argc; i ++)
107    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
108
109  if ((helpfile = getenv("PATH_INFO")) != NULL)
110  {
111    helpfile ++;
112
113    if (!*helpfile)
114      helpfile = NULL;
115  }
116
117  if (helpfile)
118  {
119   /*
120    * Verify that the help file exists and is part of the index...
121    */
122
123    snprintf(filename, sizeof(filename), "%s/help/%s", docroot, helpfile);
124
125    fprintf(stderr, "DEBUG: helpfile=\"%s\", filename=\"%s\"\n",
126            helpfile, filename);
127
128    if (access(filename, R_OK))
129    {
130      perror(filename);
131
132      cgiStartHTML(cgiText(_("Online Help")));
133      cgiSetVariable("ERROR", cgiText(_("Unable to access help file.")));
134      cgiCopyTemplateLang("error.tmpl");
135      cgiEndHTML();
136
137      return (1);
138    }
139
140    if ((n = helpFindNode(hi, helpfile, NULL)) == NULL)
141    {
142      cgiStartHTML(cgiText(_("Online Help")));
143      cgiSetVariable("ERROR", cgiText(_("Help file not in index.")));
144      cgiCopyTemplateLang("error.tmpl");
145      cgiEndHTML();
146
147      return (1);
148    }
149
150   /*
151    * Save the page title and help file...
152    */
153
154    helptitle = n->text;
155    topic     = n->section;
156
157   /*
158    * Send a standard page header...
159    */
160
161    if (printable)
162      puts("Content-Type: text/html;charset=utf-8\n");
163    else
164      cgiStartHTML(n->text);
165  }
166  else
167  {
168   /*
169    * Send a standard page header...
170    */
171
172    cgiStartHTML(cgiText(_("Online Help")));
173
174    topic = cgiGetVariable("TOPIC");
175  }
176
177 /*
178  * Do a search as needed...
179  */
180
181  if (cgiGetVariable("CLEAR"))
182    cgiSetVariable("QUERY", "");
183
184  query = cgiGetVariable("QUERY");
185  si    = helpSearchIndex(hi, query, topic, helpfile);
186
187  cgiClearVariables();
188  if (query)
189    cgiSetVariable("QUERY", query);
190  if (topic)
191    cgiSetVariable("TOPIC", topic);
192  if (helpfile)
193    cgiSetVariable("HELPFILE", helpfile);
194  if (helptitle)
195    cgiSetVariable("HELPTITLE", helptitle);
196
197  fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n",
198          query ? query : "(null)", topic ? topic : "(null)");
199
200  if (si)
201  {
202    help_node_t	*nn;			/* Parent node */
203
204
205    fprintf(stderr,
206            "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si,
207            si->sorted, cupsArrayCount(si->sorted));
208
209    for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted);
210         n;
211	 i ++, n = (help_node_t *)cupsArrayNext(si->sorted))
212    {
213      if (helpfile && n->anchor)
214        snprintf(line, sizeof(line), "#%s", n->anchor);
215      else if (n->anchor)
216        snprintf(line, sizeof(line), "/help/%s?QUERY=%s#%s", n->filename,
217	         query ? query : "", n->anchor);
218      else
219        snprintf(line, sizeof(line), "/help/%s?QUERY=%s", n->filename,
220	         query ? query : "");
221
222      cgiSetArray("QTEXT", i, n->text);
223      cgiSetArray("QLINK", i, line);
224
225      if (!helpfile && n->anchor)
226      {
227        nn = helpFindNode(hi, n->filename, NULL);
228
229        snprintf(line, sizeof(line), "/help/%s?QUERY=%s", nn->filename,
230	         query ? query : "");
231
232        cgiSetArray("QPTEXT", i, nn->text);
233	cgiSetArray("QPLINK", i, line);
234      }
235      else
236      {
237        cgiSetArray("QPTEXT", i, "");
238	cgiSetArray("QPLINK", i, "");
239      }
240
241      fprintf(stderr, "DEBUG: [%d] = \"%s\" @ \"%s\"\n", i, n->text, line);
242    }
243
244    helpDeleteIndex(si);
245  }
246
247 /*
248  * OK, now list the bookmarks within the index...
249  */
250
251  for (i = 0, section = NULL, n = (help_node_t *)cupsArrayFirst(hi->sorted);
252       n;
253       n = (help_node_t *)cupsArrayNext(hi->sorted))
254  {
255    if (n->anchor)
256      continue;
257
258   /*
259    * Add a section link as needed...
260    */
261
262    if (n->section &&
263        (!section || strcmp(n->section, section)))
264    {
265     /*
266      * Add a link for this node...
267      */
268
269      snprintf(line, sizeof(line), "/help/?TOPIC=%s&QUERY=%s",
270               cgiFormEncode(topic_data, n->section, sizeof(topic_data)),
271	       query ? query : "");
272      cgiSetArray("BMLINK", i, line);
273      cgiSetArray("BMTEXT", i, n->section);
274      cgiSetArray("BMINDENT", i, "0");
275
276      i ++;
277      section = n->section;
278    }
279
280    if (!topic || strcmp(n->section, topic))
281      continue;
282
283   /*
284    * Add a link for this node...
285    */
286
287    snprintf(line, sizeof(line), "/help/%s?TOPIC=%s&QUERY=%s", n->filename,
288             cgiFormEncode(topic_data, n->section, sizeof(topic_data)),
289	     query ? query : "");
290    cgiSetArray("BMLINK", i, line);
291    cgiSetArray("BMTEXT", i, n->text);
292    cgiSetArray("BMINDENT", i, "1");
293
294    i ++;
295
296    if (helpfile && !strcmp(helpfile, n->filename))
297    {
298      help_node_t	*nn;		/* Pointer to sub-node */
299
300
301      cupsArraySave(hi->sorted);
302
303      for (nn = (help_node_t *)cupsArrayFirst(hi->sorted);
304           nn;
305	   nn = (help_node_t *)cupsArrayNext(hi->sorted))
306        if (nn->anchor && !strcmp(helpfile, nn->filename))
307	{
308	 /*
309	  * Add a link for this node...
310	  */
311
312	  snprintf(line, sizeof(line), "#%s", nn->anchor);
313	  cgiSetArray("BMLINK", i, line);
314	  cgiSetArray("BMTEXT", i, nn->text);
315	  cgiSetArray("BMINDENT", i, "2");
316
317	  i ++;
318	}
319
320      cupsArrayRestore(hi->sorted);
321    }
322  }
323
324 /*
325  * Show the search and bookmark content...
326  */
327
328  if (!helpfile || !printable)
329    cgiCopyTemplateLang("help-header.tmpl");
330  else
331    cgiCopyTemplateLang("help-printable.tmpl");
332
333 /*
334  * If we are viewing a file, copy it in now...
335  */
336
337  if (helpfile)
338  {
339    if ((fp = cupsFileOpen(filename, "r")) != NULL)
340    {
341      int	inbody;			/* Are we inside the body? */
342
343
344      inbody = 0;
345
346      while (cupsFileGets(fp, line, sizeof(line)))
347      {
348        if (inbody)
349	{
350	  if (!_cups_strncasecmp(line, "</BODY>", 7))
351	    break;
352
353	  printf("%s\n", line);
354        }
355	else if (!_cups_strncasecmp(line, "<BODY", 5))
356	  inbody = 1;
357      }
358
359      cupsFileClose(fp);
360    }
361    else
362    {
363      perror(filename);
364      cgiSetVariable("ERROR", cgiText(_("Unable to open help file.")));
365      cgiCopyTemplateLang("error.tmpl");
366    }
367  }
368
369 /*
370  * Send a standard trailer...
371  */
372
373  if (!printable)
374  {
375    cgiCopyTemplateLang("help-trailer.tmpl");
376    cgiEndHTML();
377  }
378  else
379    puts("</BODY>\n</HTML>");
380
381 /*
382  * Delete the index...
383  */
384
385  helpDeleteIndex(hi);
386
387 /*
388  * Return with no errors...
389  */
390
391  return (0);
392}
393
394
395/*
396 * End of "$Id: help.c 11093 2013-07-03 20:48:42Z msweet $".
397 */
398