X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/a8d1009fa71020a958786761e08945db33e94010..HEAD:/agedu.c diff --git a/agedu.c b/agedu.c index 08286a5..1847e2c 100644 --- a/agedu.c +++ b/agedu.c @@ -341,6 +341,8 @@ static void text_query(const void *mappedfile, const char *querydir, HELPOPT("[--scan,--load] keep real atimes on directories") \ NOVAL(NODIRATIME) LONG(no_dir_atime) LONG(no_dir_atimes) \ HELPOPT("[--scan,--load] fake atimes on directories") \ + NOVAL(NOEOF) LONG(no_eof) LONG(noeof) \ + HELPOPT("[--web] do not close web server on EOF") \ NOVAL(MTIME) LONG(mtime) \ HELPOPT("[--scan] use mtime instead of atime") \ NOVAL(SHOWFILES) LONG(files) \ @@ -359,6 +361,8 @@ static void text_query(const void *mappedfile, const char *querydir, HELPARG("filename") HELPOPT("[--web] read HTTP Basic user/pass from file") \ VAL(AUTHFD) LONG(auth_fd) \ HELPARG("fd") HELPOPT("[--web] read HTTP Basic user/pass from fd") \ + VAL(HTMLTITLE) LONG(title) \ + HELPARG("title") HELPOPT("[--web,--html] title prefix for web pages") \ VAL(DEPTH) SHORT(d) LONG(depth) LONG(max_depth) LONG(maximum_depth) \ HELPARG("levels") HELPOPT("[--text,--html] recurse to this many levels") \ VAL(MINAGE) SHORT(a) LONG(age) LONG(min_age) LONG(minimum_age) \ @@ -498,10 +502,11 @@ int main(int argc, char **argv) time_t now = time(NULL); time_t textcutoff = now, htmlnewest = now, htmloldest = now; int htmlautoagerange = 1; - const char *httpserveraddr = NULL; - int httpserverport = 0; + const char *httpserveraddr = "localhost"; + const char *httpserverport = NULL; const char *httpauthdata = NULL; const char *outfile = NULL; + const char *html_title = PNAME; int auth = HTTPD_AUTH_MAGIC | HTTPD_AUTH_BASIC; int progress = 1; struct inclusion_exclusion *inex = NULL; @@ -510,6 +515,7 @@ int main(int argc, char **argv) int depth = -1, gotdepth = 0; int fakediratimes = 1; int mtime = 0; + int closeoneof = 1; int showfiles = 0; #ifdef DEBUG_MAD_OPTION_PARSING_MACROS @@ -767,6 +773,9 @@ int main(int argc, char **argv) case OPT_MTIME: mtime = 1; break; + case OPT_NOEOF: + closeoneof = 0; + break; case OPT_DATAFILE: filename = optval; break; @@ -785,6 +794,9 @@ int main(int argc, char **argv) case OPT_OUTFILE: outfile = optval; break; + case OPT_HTMLTITLE: + html_title = optval; + break; case OPT_MINAGE: textcutoff = parse_age(now, optval); break; @@ -809,10 +821,13 @@ int main(int argc, char **argv) else port = optval; port += strcspn(port, ":"); - if (port) + if (port && *port) *port++ = '\0'; - httpserveraddr = optval; - httpserverport = atoi(port); + if (!strcmp(optval, "ANY")) + httpserveraddr = NULL; + else + httpserveraddr = optval; + httpserverport = port; } break; case OPT_AUTH: @@ -1131,7 +1146,6 @@ int main(int argc, char **argv) prevbuf[0] = '\0'; tf = triewalk_next(tw, buf); assert(tf); - prevtf = NULL; /* placate lint */ while (1) { int i; @@ -1166,9 +1180,6 @@ int main(int argc, char **argv) triewalk_rebase(tw, mappedfile); diff = (const unsigned char *)mappedfile - (const unsigned char *)oldfile; - if (prevtf) - prevtf = (const struct trie_file *) - (((const unsigned char *)prevtf) + diff); if (tf) tf = (const struct trie_file *) (((const unsigned char *)tf) + diff); @@ -1235,7 +1246,8 @@ int main(int argc, char **argv) indexbuild_free(ib); munmap(mappedfile, totalsize); - ftruncate(fd, realsize); + if (ftruncate(fd, realsize) < 0) + fatal("%s: truncate: %s\n", filename, strerror(errno)); close(fd); printf("Final index file size = %llu bytes\n", (unsigned long long)realsize); @@ -1260,6 +1272,11 @@ int main(int argc, char **argv) perror(PNAME ": mmap"); return 1; } + if (!trie_check_magic(mappedfile)) { + fprintf(stderr, "%s: %s: magic numbers did not match\n" + "%s: check that the index was built by this version of agedu on this platform\n", PNAME, filename, PNAME); + return 1; + } pathsep = trie_pathsep(mappedfile); /* @@ -1343,11 +1360,49 @@ int main(int argc, char **argv) } return 1; } + if (!trie_check_magic(mappedfile)) { + fprintf(stderr, "%s: %s: magic numbers did not match\n" + "%s: check that the index was built by this version of agedu on this platform\n", PNAME, filename, PNAME); + if (!querydir) { + printf("Status: 500\nContent-type: text/html\n\n" + "" + "500 Internal Server Error" + "" + "

500 Internal Server Error

" + "

agedu suffered an internal error." + "\n"); + return 0; + } + return 1; + } pathsep = trie_pathsep(mappedfile); 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 @@ -1358,13 +1413,27 @@ int main(int argc, char **argv) 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" + "" + "404 Not Found" + "" + "

400 Not Found

" + "

Invalid agedu pathname." + "\n"); + return 0; + } + /* - * Because we need relative links to go to the - * right place, it's important that our - * PATH_INFO should contain a slash right at the - * start, and no slashes anywhere else. + * If the path was parseable but not canonically + * expressed, return a redirect to the canonical + * version. */ - if (path_info[0] != '/') { + 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) { @@ -1386,7 +1455,7 @@ int main(int argc, char **argv) return 0; } printf("Status: 301\n" - "Location: http://%s/%s/\n" + "Location: http://%s/%s%s\n" "Content-type: text/html\n\n" "" "301 Moved" @@ -1394,39 +1463,10 @@ int main(int argc, char **argv) "

301 Moved

" "

Moved." "\n", - servername, scriptname); - return 0; - } else if (strchr(path_info+1, '/')) { - printf("Status: 404\nContent-type: text/html\n\n" - "" - "404 Not Found" - "" - "

400 Not Found

" - "

Invalid agedu pathname." - "\n"); + servername, scriptname, canonpath); return 0; } - xi = atoi(path_info + 1); - if (xi >= trie_count(mappedfile)) { - printf("Status: 404\nContent-type: text/html\n\n" - "" - "404 Not Found" - "" - "

404 Not Found

" - "

This is not a valid pathname index." - "\n"); - return 0; - } else if (!index_has_root(mappedfile, xi)) { - printf("Status: 404\nContent-type: text/html\n\n" - "" - "404 Not Found" - "" - "

404 Not Found

" - "

Pathname index out of range." - "\n"); - return 0; - } } else { /* * In ordinary --html mode, process a query @@ -1462,16 +1502,6 @@ int main(int argc, char **argv) /* * Single output file. */ - if (!querydir) { - cfg.format = "%.0lu"; /* use crosslinks in --cgi mode */ - } else { - cfg.format = NULL; - } - cfg.rootpage = NULL; - cfg.autoage = htmlautoagerange; - cfg.oldest = htmloldest; - cfg.newest = htmlnewest; - cfg.showfiles = showfiles; html = html_query(mappedfile, xi, &cfg, 1); if (querydir && outfile != NULL) { FILE *fp = fopen(outfile, "w"); @@ -1521,12 +1551,6 @@ int main(int argc, char **argv) make_successor(pathbuf); xi2 = trie_before(mappedfile, pathbuf); - cfg.format = "%lu.html"; - cfg.rootpage = "index.html"; - cfg.autoage = htmlautoagerange; - cfg.oldest = htmloldest; - cfg.newest = htmlnewest; - cfg.showfiles = showfiles; if (html_dump(mappedfile, xi, xi2, depth, &cfg, prefix)) return 1; } @@ -1553,6 +1577,11 @@ int main(int argc, char **argv) perror(PNAME ": mmap"); return 1; } + if (!trie_check_magic(mappedfile)) { + fprintf(stderr, "%s: %s: magic numbers did not match\n" + "%s: check that the index was built by this version of agedu on this platform\n", PNAME, filename, PNAME); + return 1; + } pathsep = trie_pathsep(mappedfile); maxpathlen = trie_maxpathlen(mappedfile); @@ -1585,17 +1614,23 @@ int main(int argc, char **argv) perror(PNAME ": mmap"); return 1; } + if (!trie_check_magic(mappedfile)) { + fprintf(stderr, "%s: %s: magic numbers did not match\n" + "%s: check that the index was built by this version of agedu on this platform\n", PNAME, filename, PNAME); + return 1; + } pathsep = trie_pathsep(mappedfile); dcfg.address = httpserveraddr; dcfg.port = httpserverport; + dcfg.closeoneof = closeoneof; dcfg.basicauthdata = httpauthdata; - pcfg.format = NULL; - pcfg.rootpage = NULL; + pcfg.uriformat = "/%|/%p/%|%|/%p"; pcfg.autoage = htmlautoagerange; pcfg.oldest = htmloldest; pcfg.newest = htmlnewest; pcfg.showfiles = showfiles; + pcfg.html_title = html_title; run_httpd(mappedfile, auth, &dcfg, &pcfg); munmap(mappedfile, totalsize); } else if (mode == REMOVE) {