+ maxpathlen = trie_maxpathlen(mappedfile);
+ pathbuf = snewn(maxpathlen, char);
+
+ if (!querydir || !gotdepth) {
+ /*
+ * Single output file.
+ */
+ if (!querydir) {
+ cfg.uriformat = "/%|/%p/%|%|/%p";
+ } else {
+ cfg.uriformat = NULL;
+ }
+ cfg.autoage = htmlautoagerange;
+ cfg.oldest = htmloldest;
+ cfg.newest = htmlnewest;
+ cfg.showfiles = showfiles;
+ } else {
+ cfg.uriformat = "/index.html%|/%/p.html";
+ cfg.fileformat = "/index.html%|/%/p.html";
+ cfg.autoage = htmlautoagerange;
+ cfg.oldest = htmloldest;
+ cfg.newest = htmlnewest;
+ cfg.showfiles = showfiles;
+ }
+ cfg.html_title = html_title;
+
+ if (!querydir) {
+ /*
+ * If we're run in --cgi mode, read PATH_INFO to get
+ * a numeric pathname index.
+ */
+ char *path_info = getenv("PATH_INFO");
+
+ if (!path_info)
+ path_info = "";
+
+ /*
+ * Parse the path.
+ */
+ if (!html_parse_path(mappedfile, path_info, &cfg, &xi)) {
+ printf("Status: 404\nContent-type: text/html\n\n"
+ "<html><head>"
+ "<title>404 Not Found</title>"
+ "</head><body>"
+ "<h1>400 Not Found</h1>"
+ "<p>Invalid <code>agedu</code> pathname."
+ "</body></html>\n");
+ return 0;
+ }
+
+ /*
+ * If the path was parseable but not canonically
+ * expressed, return a redirect to the canonical
+ * version.
+ */
+ char *canonpath = html_format_path(mappedfile, &cfg, xi);
+ if (strcmp(canonpath, path_info)) {
+ char *servername = getenv("SERVER_NAME");
+ char *scriptname = getenv("SCRIPT_NAME");
+ if (!servername || !scriptname) {
+ if (servername)
+ fprintf(stderr, "%s: SCRIPT_NAME unset\n", PNAME);
+ else if (scriptname)
+ fprintf(stderr, "%s: SCRIPT_NAME unset\n", PNAME);
+ else
+ fprintf(stderr, "%s: SERVER_NAME and "
+ "SCRIPT_NAME both unset\n", PNAME);
+ printf("Status: 500\nContent-type: text/html\n\n"
+ "<html><head>"
+ "<title>500 Internal Server Error</title>"
+ "</head><body>"
+ "<h1>500 Internal Server Error</h1>"
+ "<p><code>agedu</code> suffered an internal "
+ "error."
+ "</body></html>\n");
+ return 0;
+ }
+ printf("Status: 301\n"
+ "Location: http://%s/%s%s\n"
+ "Content-type: text/html\n\n"
+ "<html><head>"
+ "<title>301 Moved</title>"
+ "</head><body>"
+ "<h1>301 Moved</h1>"
+ "<p>Moved."
+ "</body></html>\n",
+ servername, scriptname, canonpath);
+ return 0;
+ }
+
+ } else {
+ /*
+ * In ordinary --html mode, process a query
+ * directory passed in on the command line.
+ */
+
+ /*
+ * Trim trailing slash, just in case.
+ */
+ pathlen = strlen(querydir);
+ if (pathlen > 0 && querydir[pathlen-1] == pathsep)
+ querydir[--pathlen] = '\0';
+
+ xi = trie_before(mappedfile, querydir);
+ if (xi >= trie_count(mappedfile) ||
+ (trie_getpath(mappedfile, xi, pathbuf),
+ strcmp(pathbuf, querydir))) {
+ fprintf(stderr, "%s: pathname '%s' does not exist in index\n"
+ "%*s(check it is spelled exactly as it is in the "
+ "index, including\n%*sany leading './')\n",
+ PNAME, querydir,
+ (int)(1+sizeof(PNAME)), "",
+ (int)(1+sizeof(PNAME)), "");
+ return 1;
+ } else if (!index_has_root(mappedfile, xi)) {
+ fprintf(stderr, "%s: pathname '%s' is"
+ " a file, not a directory\n", PNAME, querydir);
+ return 1;
+ }
+ }