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" + "
" + "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"
+ "
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"
"
Moved." "\n", - servername, scriptname); - return 0; - } else if (strchr(path_info+1, '/')) { - printf("Status: 404\nContent-type: text/html\n\n" - "
" - "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"
- "
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" - "
" - "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) {