if (ctx->usemtime || (ctx->fakeatimes && S_ISDIR(st->st_mode)))
file.atime = st->st_mtime;
else
- file.atime = st->st_atime;
+ file.atime = max(st->st_mtime, st->st_atime);
/*
* Filter based on wildcards.
HELPOPT("[--scan,--load] fake atimes on directories") \
NOVAL(MTIME) LONG(mtime) \
HELPOPT("[--scan] use mtime instead of atime") \
- NOVAL(FULL) LONG(full_index) \
- HELPOPT("[--scan] index every file individually") \
VAL(AGERANGE) SHORT(r) LONG(age_range) LONG(range) LONG(ages) \
HELPARG("age[-age]") HELPOPT("[--web,--html] set limits of colour coding") \
VAL(SERVERADDR) LONG(address) LONG(addr) LONG(server_address) \
int tqdepth = 1;
int fakediratimes = 1;
int mtime = 0;
- int fullindex = 0;
#ifdef DEBUG_MAD_OPTION_PARSING_MACROS
{
case OPT_MTIME:
mtime = 1;
break;
- case OPT_FULL:
- fullindex = 1;
- break;
case OPT_DATAFILE:
filename = optval;
break;
ctx->progress = progress;
{
struct winsize ws;
- if (progress && ioctl(2, TIOCGWINSZ, &ws) == 0)
+ if (progress &&
+ ioctl(2, TIOCGWINSZ, &ws) == 0 &&
+ ws.ws_col > 0)
ctx->progwidth = ws.ws_col - 1;
else
ctx->progwidth = 79;
}
if (mode != SCANDUMP) {
size_t maxpathlen;
+ size_t delta;
char *buf, *prevbuf;
count = triebuild_finish(ctx->tb);
return 1;
}
- printf("Built pathname index, %d entries, %llu bytes\n", count,
+ printf("Built pathname index, %d entries,"
+ " %llu bytes of index\n", count,
(unsigned long long)st.st_size);
- totalsize = index_compute_size(st.st_size, count);
+ totalsize = index_initial_size(st.st_size, count);
+ totalsize += totalsize / 10;
if (lseek(fd, totalsize-1, SEEK_SET) < 0) {
perror(PNAME ": lseek");
return 1;
}
- printf("Upper bound on index file size = %llu bytes\n",
- (unsigned long long)totalsize);
-
mappedfile = mmap(NULL, totalsize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
if (!mappedfile) {
perror(PNAME ": mmap");
}
printf("Building index\n");
- ib = indexbuild_new(mappedfile, st.st_size, count);
+ ib = indexbuild_new(mappedfile, st.st_size, count, &delta);
maxpathlen = trie_maxpathlen(mappedfile);
buf = snewn(maxpathlen, char);
prevbuf = snewn(maxpathlen, char);
while (1) {
int i;
+ if (totalsize - indexbuild_realsize(ib) < delta) {
+ const void *oldfile = mappedfile;
+ ptrdiff_t diff;
+
+ /*
+ * Unmap the file, grow it, and remap it.
+ */
+ munmap(mappedfile, totalsize);
+
+ totalsize += delta;
+ totalsize += totalsize / 10;
+
+ if (lseek(fd, totalsize-1, SEEK_SET) < 0) {
+ perror(PNAME ": lseek");
+ return 1;
+ }
+ if (write(fd, "\0", 1) < 1) {
+ perror(PNAME ": write");
+ return 1;
+ }
+
+ mappedfile = mmap(NULL, totalsize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
+ if (!mappedfile) {
+ perror(PNAME ": mmap");
+ return 1;
+ }
+
+ indexbuild_rebase(ib, mappedfile);
+ 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);
+ }
+
/*
* Get the next file from the index. So we are
* currently holding, and have not yet
indexbuild_tag(ib);
break;
}
-
- /*
- * In full-index mode, index everything.
- */
- if (fullindex)
- indexbuild_tag(ib);
/*
* If prevbuf was a filename inside some
munmap(mappedfile, totalsize);
ftruncate(fd, realsize);
close(fd);
- printf("Actual index file size = %llu bytes\n",
+ printf("Final index file size = %llu bytes\n",
(unsigned long long)realsize);
}
} else if (mode == TEXT) {
munmap(mappedfile, totalsize);
} else if (mode == HTML) {
char *querydir = actions[action].arg;
- size_t pathlen;
+ size_t pathlen, maxpathlen;
+ char *pathbuf;
struct html_config cfg;
unsigned long xi;
char *html;
}
pathsep = trie_pathsep(mappedfile);
+ maxpathlen = trie_maxpathlen(mappedfile);
+ pathbuf = snewn(maxpathlen, char);
+
/*
* Trim trailing slash, just in case.
*/
querydir[--pathlen] = '\0';
xi = trie_before(mappedfile, querydir);
- cfg.format = NULL;
- cfg.autoage = htmlautoagerange;
- cfg.oldest = htmloldest;
- cfg.newest = htmlnewest;
- html = html_query(mappedfile, xi, &cfg);
- fputs(html, stdout);
+ 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)), "");
+ } else if (!index_has_root(mappedfile, xi)) {
+ fprintf(stderr, "%s: pathname '%s' is"
+ " a file, not a directory\n", PNAME, querydir);
+ } else {
+ cfg.format = NULL;
+ cfg.autoage = htmlautoagerange;
+ cfg.oldest = htmloldest;
+ cfg.newest = htmlnewest;
+ html = html_query(mappedfile, xi, &cfg);
+ fputs(html, stdout);
+ }
munmap(mappedfile, totalsize);
+ sfree(pathbuf);
} else if (mode == DUMP) {
size_t maxpathlen;
char *buf;