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