]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
f7faf1f5 | 2 | * "$Id$" |
ef416fc2 | 3 | * |
321d8d57 | 4 | * Online help CGI for CUPS. |
ef416fc2 | 5 | * |
321d8d57 | 6 | * Copyright 2007-2011 by Apple Inc. |
ef416fc2 | 7 | * Copyright 1997-2006 by Easy Software Products. |
8 | * | |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 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/". | |
ef416fc2 | 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 | ||
31 | int /* O - Exit status */ | |
32 | main(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 */ | |
ecdc0628 | 37 | help_node_t *n; /* Current help node */ |
38 | int i; /* Looping var */ | |
ef416fc2 | 39 | const char *query; /* Search query */ |
ecdc0628 | 40 | const char *cache_dir; /* CUPS_CACHEDIR environment variable */ |
ef416fc2 | 41 | const char *docroot; /* CUPS_DOCROOT environment variable */ |
82cc1f9a MS |
42 | const char *helpfile, /* Current help file */ |
43 | *helptitle = NULL; /* Current help title */ | |
ef416fc2 | 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 */ | |
4744bd90 | 51 | int printable; /* Show printable version? */ |
ef416fc2 | 52 | |
53 | ||
54 | /* | |
55 | * Get any form variables... | |
56 | */ | |
57 | ||
58 | cgiInitialize(); | |
59 | ||
4744bd90 | 60 | printable = cgiGetVariable("PRINTABLE") != NULL; |
61 | ||
ef416fc2 | 62 | /* |
63 | * Set the web interface section... | |
64 | */ | |
65 | ||
66 | cgiSetVariable("SECTION", "help"); | |
ef55b745 | 67 | cgiSetVariable("REFRESH_PAGE", ""); |
ef416fc2 | 68 | |
69 | /* | |
70 | * Load the help index... | |
71 | */ | |
72 | ||
ecdc0628 | 73 | if ((cache_dir = getenv("CUPS_CACHEDIR")) == NULL) |
74 | cache_dir = CUPS_CACHEDIR; | |
ef416fc2 | 75 | |
ecdc0628 | 76 | snprintf(filename, sizeof(filename), "%s/help.index", cache_dir); |
ef416fc2 | 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 | ||
2e4ff8af | 91 | cgiStartHTML(cgiText(_("Online Help"))); |
82cc1f9a | 92 | cgiSetVariable("ERROR", cgiText(_("Unable to load help index."))); |
ef416fc2 | 93 | cgiCopyTemplateLang("error.tmpl"); |
94 | cgiEndHTML(); | |
95 | ||
96 | return (1); | |
97 | } | |
98 | ||
ecdc0628 | 99 | fprintf(stderr, "DEBUG: %d nodes in help index...\n", |
100 | cupsArrayCount(hi->nodes)); | |
ef416fc2 | 101 | |
102 | /* | |
103 | * See if we are viewing a file... | |
104 | */ | |
105 | ||
106 | for (i = 0; i < argc; i ++) | |
ef55b745 | 107 | fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); |
ef416fc2 | 108 | |
109 | if ((helpfile = getenv("PATH_INFO")) != NULL) | |
b423cd4c | 110 | { |
ef416fc2 | 111 | helpfile ++; |
b423cd4c | 112 | |
113 | if (!*helpfile) | |
114 | helpfile = NULL; | |
115 | } | |
ef416fc2 | 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 | ||
2e4ff8af | 132 | cgiStartHTML(cgiText(_("Online Help"))); |
82cc1f9a | 133 | cgiSetVariable("ERROR", cgiText(_("Unable to access help file."))); |
ef416fc2 | 134 | cgiCopyTemplateLang("error.tmpl"); |
135 | cgiEndHTML(); | |
136 | ||
137 | return (1); | |
138 | } | |
139 | ||
140 | if ((n = helpFindNode(hi, helpfile, NULL)) == NULL) | |
141 | { | |
2e4ff8af | 142 | cgiStartHTML(cgiText(_("Online Help"))); |
82cc1f9a | 143 | cgiSetVariable("ERROR", cgiText(_("Help file not in index."))); |
ef416fc2 | 144 | cgiCopyTemplateLang("error.tmpl"); |
145 | cgiEndHTML(); | |
146 | ||
147 | return (1); | |
148 | } | |
149 | ||
150 | /* | |
82cc1f9a | 151 | * Save the page title and help file... |
ef416fc2 | 152 | */ |
153 | ||
82cc1f9a MS |
154 | helptitle = n->text; |
155 | topic = n->section; | |
ef416fc2 | 156 | |
157 | /* | |
158 | * Send a standard page header... | |
159 | */ | |
160 | ||
4744bd90 | 161 | if (printable) |
162 | puts("Content-Type: text/html;charset=utf-8\n"); | |
163 | else | |
164 | cgiStartHTML(n->text); | |
ef416fc2 | 165 | } |
166 | else | |
167 | { | |
168 | /* | |
169 | * Send a standard page header... | |
170 | */ | |
171 | ||
2e4ff8af | 172 | cgiStartHTML(cgiText(_("Online Help"))); |
82cc1f9a MS |
173 | |
174 | topic = cgiGetVariable("TOPIC"); | |
ef416fc2 | 175 | } |
176 | ||
177 | /* | |
178 | * Do a search as needed... | |
179 | */ | |
180 | ||
2e4ff8af MS |
181 | if (cgiGetVariable("CLEAR")) |
182 | cgiSetVariable("QUERY", ""); | |
183 | ||
ef416fc2 | 184 | query = cgiGetVariable("QUERY"); |
ef416fc2 | 185 | si = helpSearchIndex(hi, query, topic, helpfile); |
186 | ||
ef55b745 MS |
187 | cgiClearVariables(); |
188 | if (query) | |
189 | cgiSetVariable("QUERY", query); | |
190 | if (topic) | |
191 | cgiSetVariable("TOPIC", topic); | |
82cc1f9a MS |
192 | if (helpfile) |
193 | cgiSetVariable("HELPFILE", helpfile); | |
194 | if (helptitle) | |
195 | cgiSetVariable("HELPTITLE", helptitle); | |
ef55b745 | 196 | |
f301802f | 197 | fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n", |
198 | query ? query : "(null)", topic ? topic : "(null)"); | |
b423cd4c | 199 | |
ef416fc2 | 200 | if (si) |
201 | { | |
ecdc0628 | 202 | help_node_t *nn; /* Parent node */ |
ef416fc2 | 203 | |
204 | ||
ecdc0628 | 205 | fprintf(stderr, |
206 | "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si, | |
207 | si->sorted, cupsArrayCount(si->sorted)); | |
ef416fc2 | 208 | |
b423cd4c | 209 | for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted); |
ecdc0628 | 210 | n; |
b423cd4c | 211 | i ++, n = (help_node_t *)cupsArrayNext(si->sorted)) |
ef416fc2 | 212 | { |
ecdc0628 | 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); | |
ef416fc2 | 218 | else |
ecdc0628 | 219 | snprintf(line, sizeof(line), "/help/%s?QUERY=%s", n->filename, |
ef416fc2 | 220 | query ? query : ""); |
221 | ||
ecdc0628 | 222 | cgiSetArray("QTEXT", i, n->text); |
ef416fc2 | 223 | cgiSetArray("QLINK", i, line); |
224 | ||
ecdc0628 | 225 | if (!helpfile && n->anchor) |
ef416fc2 | 226 | { |
ecdc0628 | 227 | nn = helpFindNode(hi, n->filename, NULL); |
ef416fc2 | 228 | |
ecdc0628 | 229 | snprintf(line, sizeof(line), "/help/%s?QUERY=%s", nn->filename, |
ef416fc2 | 230 | query ? query : ""); |
231 | ||
ecdc0628 | 232 | cgiSetArray("QPTEXT", i, nn->text); |
ef416fc2 | 233 | cgiSetArray("QPLINK", i, line); |
234 | } | |
235 | else | |
236 | { | |
237 | cgiSetArray("QPTEXT", i, ""); | |
238 | cgiSetArray("QPLINK", i, ""); | |
239 | } | |
240 | ||
ecdc0628 | 241 | fprintf(stderr, "DEBUG: [%d] = \"%s\" @ \"%s\"\n", i, n->text, line); |
ef416fc2 | 242 | } |
243 | ||
244 | helpDeleteIndex(si); | |
245 | } | |
246 | ||
247 | /* | |
248 | * OK, now list the bookmarks within the index... | |
249 | */ | |
250 | ||
ecdc0628 | 251 | for (i = 0, section = NULL, n = (help_node_t *)cupsArrayFirst(hi->sorted); |
252 | n; | |
253 | n = (help_node_t *)cupsArrayNext(hi->sorted)) | |
ef416fc2 | 254 | { |
ecdc0628 | 255 | if (n->anchor) |
ef416fc2 | 256 | continue; |
257 | ||
258 | /* | |
259 | * Add a section link as needed... | |
260 | */ | |
261 | ||
ecdc0628 | 262 | if (n->section && |
263 | (!section || strcmp(n->section, section))) | |
ef416fc2 | 264 | { |
265 | /* | |
266 | * Add a link for this node... | |
267 | */ | |
268 | ||
269 | snprintf(line, sizeof(line), "/help/?TOPIC=%s&QUERY=%s", | |
ecdc0628 | 270 | cgiFormEncode(topic_data, n->section, sizeof(topic_data)), |
ef416fc2 | 271 | query ? query : ""); |
ecdc0628 | 272 | cgiSetArray("BMLINK", i, line); |
273 | cgiSetArray("BMTEXT", i, n->section); | |
274 | cgiSetArray("BMINDENT", i, "0"); | |
ef416fc2 | 275 | |
ecdc0628 | 276 | i ++; |
277 | section = n->section; | |
ef416fc2 | 278 | } |
279 | ||
ecdc0628 | 280 | if (!topic || strcmp(n->section, topic)) |
ef416fc2 | 281 | continue; |
282 | ||
283 | /* | |
284 | * Add a link for this node... | |
285 | */ | |
286 | ||
ecdc0628 | 287 | snprintf(line, sizeof(line), "/help/%s?TOPIC=%s&QUERY=%s", n->filename, |
288 | cgiFormEncode(topic_data, n->section, sizeof(topic_data)), | |
ef416fc2 | 289 | query ? query : ""); |
ecdc0628 | 290 | cgiSetArray("BMLINK", i, line); |
291 | cgiSetArray("BMTEXT", i, n->text); | |
292 | cgiSetArray("BMINDENT", i, "1"); | |
ef416fc2 | 293 | |
ecdc0628 | 294 | i ++; |
ef416fc2 | 295 | |
ecdc0628 | 296 | if (helpfile && !strcmp(helpfile, n->filename)) |
ef416fc2 | 297 | { |
ecdc0628 | 298 | help_node_t *nn; /* Pointer to sub-node */ |
ef416fc2 | 299 | |
300 | ||
ecdc0628 | 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)) | |
ef416fc2 | 307 | { |
308 | /* | |
309 | * Add a link for this node... | |
310 | */ | |
311 | ||
ecdc0628 | 312 | snprintf(line, sizeof(line), "#%s", nn->anchor); |
313 | cgiSetArray("BMLINK", i, line); | |
314 | cgiSetArray("BMTEXT", i, nn->text); | |
315 | cgiSetArray("BMINDENT", i, "2"); | |
ef416fc2 | 316 | |
ecdc0628 | 317 | i ++; |
ef416fc2 | 318 | } |
ecdc0628 | 319 | |
320 | cupsArrayRestore(hi->sorted); | |
ef416fc2 | 321 | } |
322 | } | |
323 | ||
324 | /* | |
325 | * Show the search and bookmark content... | |
326 | */ | |
327 | ||
4744bd90 | 328 | if (!helpfile || !printable) |
329 | cgiCopyTemplateLang("help-header.tmpl"); | |
330 | else | |
331 | cgiCopyTemplateLang("help-printable.tmpl"); | |
ef416fc2 | 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 | { | |
88f9aafc | 350 | if (!_cups_strncasecmp(line, "</BODY>", 7)) |
ef416fc2 | 351 | break; |
352 | ||
353 | printf("%s\n", line); | |
354 | } | |
88f9aafc | 355 | else if (!_cups_strncasecmp(line, "<BODY", 5)) |
ef416fc2 | 356 | inbody = 1; |
357 | } | |
358 | ||
359 | cupsFileClose(fp); | |
360 | } | |
361 | else | |
362 | { | |
363 | perror(filename); | |
82cc1f9a | 364 | cgiSetVariable("ERROR", cgiText(_("Unable to open help file."))); |
ef416fc2 | 365 | cgiCopyTemplateLang("error.tmpl"); |
366 | } | |
367 | } | |
368 | ||
369 | /* | |
370 | * Send a standard trailer... | |
371 | */ | |
372 | ||
4744bd90 | 373 | if (!printable) |
b19ccc9e MS |
374 | { |
375 | cgiCopyTemplateLang("help-trailer.tmpl"); | |
4744bd90 | 376 | cgiEndHTML(); |
b19ccc9e | 377 | } |
4744bd90 | 378 | else |
379 | puts("</BODY>\n</HTML>"); | |
ef416fc2 | 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 | /* | |
f7faf1f5 | 396 | * End of "$Id$". |
ef416fc2 | 397 | */ |