Expand Id keyword in man page.
[sgt/agedu] / agedu.c
diff --git a/agedu.c b/agedu.c
index 74d1971..c3ac6a7 100644 (file)
--- a/agedu.c
+++ b/agedu.c
@@ -24,7 +24,7 @@
 #include "du.h"
 #include "trie.h"
 #include "index.h"
-#include "malloc.h"
+#include "alloc.h"
 #include "html.h"
 #include "httpd.h"
 #include "fgetline.h"
@@ -82,7 +82,7 @@ static void dump_line(const char *pathname, const struct trie_file *tf)
     putchar('\n');
 }
 
-static int gotdata(void *vctx, const char *pathname, const struct stat64 *st)
+static int gotdata(void *vctx, const char *pathname, const STRUCT_STAT *st)
 {
     struct ctx *ctx = (struct ctx *)vctx;
     struct trie_file file;
@@ -262,6 +262,10 @@ static void text_query(const void *mappedfile, const char *querydir,
  * not bother defining logical identifiers for them at all - those
  * would be automatically generated, since I wouldn't have any
  * need to specify them manually in another part of the code.)
+ *
+ * One other helpful consequence of the enum-based structure here
+ * is that it causes a compiler error if I accidentally try to
+ * define the same option (short or long) twice.
  */
 
 #define OPTHELP(NOVAL, VAL, SHORT, LONG, HELPPFX, HELPARG, HELPLINE, HELPOPT) \
@@ -269,53 +273,51 @@ static void text_query(const void *mappedfile, const char *querydir,
     HELPPFX("actions") \
     VAL(SCAN) SHORT(s) LONG(scan) \
        HELPARG("directory") HELPOPT("scan and index a directory") \
-    NOVAL(DUMP) SHORT(d) LONG(dump) HELPOPT("dump the index file on stdout") \
-    VAL(SCANDUMP) SHORT(S) LONG(scan_dump) \
-       HELPARG("directory") HELPOPT("scan only, generating a dump") \
-    NOVAL(LOAD) SHORT(l) LONG(load) \
-       HELPOPT("load and index a dump file") \
+    NOVAL(HTTPD) SHORT(w) LONG(web) LONG(server) LONG(httpd) \
+        HELPOPT("serve HTML reports from a temporary web server") \
     VAL(TEXT) SHORT(t) LONG(text) \
        HELPARG("subdir") HELPOPT("print a plain text report on a subdirectory") \
+    NOVAL(REMOVE) SHORT(R) LONG(remove) LONG(delete) LONG(unlink) \
+        HELPOPT("remove the index file") \
+    NOVAL(DUMP) SHORT(D) LONG(dump) HELPOPT("dump the index file on stdout") \
+    NOVAL(LOAD) SHORT(L) LONG(load) \
+       HELPOPT("load and index a dump file") \
+    VAL(SCANDUMP) SHORT(S) LONG(scan_dump) \
+       HELPARG("directory") HELPOPT("scan only, generating a dump") \
     VAL(HTML) SHORT(H) LONG(html) \
        HELPARG("subdir") HELPOPT("print an HTML report on a subdirectory") \
-    NOVAL(HTTPD) SHORT(w) LONG(web) LONG(server) LONG(httpd) \
-        HELPOPT("serve HTML reports from a temporary web server") \
     HELPPFX("options") \
     VAL(DATAFILE) SHORT(f) LONG(file) \
-        HELPARG("filename") HELPOPT("[all modes] specify index file") \
-    NOVAL(PROGRESS) LONG(progress) LONG(scan_progress) \
-        HELPOPT("[--scan] report progress on stderr") \
-    NOVAL(NOPROGRESS) LONG(no_progress) LONG(no_scan_progress) \
-        HELPOPT("[--scan] do not report progress") \
-    NOVAL(TTYPROGRESS) LONG(tty_progress) LONG(tty_scan_progress) \
-                      LONG(progress_tty) LONG(scan_progress_tty) \
-        HELPOPT("[--scan] report progress if stderr is a tty") \
+        HELPARG("filename") HELPOPT("[most modes] specify index file") \
     NOVAL(CROSSFS) LONG(cross_fs) \
         HELPOPT("[--scan] cross filesystem boundaries") \
     NOVAL(NOCROSSFS) LONG(no_cross_fs) \
         HELPOPT("[--scan] stick to one filesystem") \
-    VAL(INCLUDE) LONG(include) \
-        HELPARG("wildcard") HELPOPT("[--scan] include files matching pattern") \
-    VAL(INCLUDEPATH) LONG(include_path) \
-        HELPARG("wildcard") HELPOPT("[--scan] include pathnames matching pattern") \
-    VAL(EXCLUDE) LONG(exclude) \
-        HELPARG("wildcard") HELPOPT("[--scan] exclude files matching pattern") \
-    VAL(EXCLUDEPATH) LONG(exclude_path) \
-        HELPARG("wildcard") HELPOPT("[--scan] exclude pathnames matching pattern") \
     VAL(PRUNE) LONG(prune) \
         HELPARG("wildcard") HELPOPT("[--scan] prune files matching pattern") \
     VAL(PRUNEPATH) LONG(prune_path) \
         HELPARG("wildcard") HELPOPT("[--scan] prune pathnames matching pattern") \
+    VAL(EXCLUDE) LONG(exclude) \
+        HELPARG("wildcard") HELPOPT("[--scan] exclude files matching pattern") \
+    VAL(EXCLUDEPATH) LONG(exclude_path) \
+        HELPARG("wildcard") HELPOPT("[--scan] exclude pathnames matching pattern") \
+    VAL(INCLUDE) LONG(include) \
+        HELPARG("wildcard") HELPOPT("[--scan] include files matching pattern") \
+    VAL(INCLUDEPATH) LONG(include_path) \
+        HELPARG("wildcard") HELPOPT("[--scan] include pathnames matching pattern") \
+    NOVAL(PROGRESS) LONG(progress) LONG(scan_progress) \
+        HELPOPT("[--scan] report progress on stderr") \
+    NOVAL(NOPROGRESS) LONG(no_progress) LONG(no_scan_progress) \
+        HELPOPT("[--scan] do not report progress") \
+    NOVAL(TTYPROGRESS) LONG(tty_progress) LONG(tty_scan_progress) \
+                      LONG(progress_tty) LONG(scan_progress_tty) \
+        HELPOPT("[--scan] report progress if stderr is a tty") \
     NOVAL(DIRATIME) LONG(dir_atime) LONG(dir_atimes) \
-        HELPOPT("[--scan] keep real atimes on directories") \
+        HELPOPT("[--scan,--load] keep real atimes on directories") \
     NOVAL(NODIRATIME) LONG(no_dir_atime) LONG(no_dir_atimes) \
-        HELPOPT("[--scan] fake atimes on directories") \
-    VAL(TQDEPTH) LONG(depth) LONG(max_depth) LONG(maximum_depth) \
-        HELPARG("levels") HELPOPT("[--text] recurse to this many levels") \
-    VAL(MINAGE) SHORT(a) LONG(age) LONG(min_age) LONG(minimum_age) \
-        HELPARG("age") HELPOPT("[--text] include only files older than this") \
+        HELPOPT("[--scan,--load] fake atimes on directories") \
     VAL(AGERANGE) SHORT(r) LONG(age_range) LONG(range) LONG(ages) \
-        HELPARG("age[-age]") HELPOPT("[--html,--web] set limits of colour coding") \
+        HELPARG("age[-age]") HELPOPT("[--web,--html] set limits of colour coding") \
     VAL(SERVERADDR) LONG(address) LONG(addr) LONG(server_address) \
               LONG(server_addr) \
         HELPARG("addr[:port]") HELPOPT("[--web] specify HTTP server address") \
@@ -326,6 +328,10 @@ 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(TQDEPTH) SHORT(d) LONG(depth) LONG(max_depth) LONG(maximum_depth) \
+        HELPARG("levels") HELPOPT("[--text] recurse to this many levels") \
+    VAL(MINAGE) SHORT(a) LONG(age) LONG(min_age) LONG(minimum_age) \
+        HELPARG("age") HELPOPT("[--text] include only files older than this") \
     HELPPFX("also") \
     NOVAL(HELP) SHORT(h) LONG(help) HELPOPT("display this help text") \
     NOVAL(VERSION) SHORT(V) LONG(version) HELPOPT("report version number") \
@@ -452,7 +458,7 @@ int main(int argc, char **argv)
     const struct trie_file *tf;
     char *filename = PNAME ".dat";
     int doing_opts = 1;
-    enum { TEXT, HTML, SCAN, DUMP, SCANDUMP, LOAD, HTTPD };
+    enum { TEXT, HTML, SCAN, DUMP, SCANDUMP, LOAD, HTTPD, REMOVE };
     struct action {
        int mode;
        char *arg;
@@ -610,7 +616,12 @@ int main(int argc, char **argv)
                    usage(stdout);
                    return 0;
                  case OPT_VERSION:
-                   printf("FIXME: version();\n");
+#ifdef PACKAGE_VERSION
+                   printf("%s, revision %s\n", PNAME, PACKAGE_VERSION);
+#else
+                   printf("%s: version number not available when not built"
+                          " via automake\n", PNAME);
+#endif
                    return 0;
                  case OPT_LICENCE:
                    {
@@ -686,6 +697,15 @@ int main(int argc, char **argv)
                    actions[nactions].arg = NULL;
                    nactions++;
                    break;
+                 case OPT_REMOVE:
+                   if (nactions >= actionsize) {
+                       actionsize = nactions * 3 / 2 + 16;
+                       actions = sresize(actions, actionsize, struct action);
+                   }
+                   actions[nactions].mode = REMOVE;
+                   actions[nactions].arg = NULL;
+                   nactions++;
+                   break;
                  case OPT_PROGRESS:
                    progress = 2;
                    break;
@@ -970,6 +990,7 @@ int main(int argc, char **argv)
                            p++;
                            c = 0;
                            for (i = 0; i < 2; i++) {
+                               c *= 16;
                                if (*p >= '0' && *p <= '9')
                                    c += *p - '0';
                                else if (*p >= 'A' && *p <= 'F')
@@ -989,6 +1010,7 @@ int main(int argc, char **argv)
                    *q = '\0';
                    triebuild_add(ctx->tb, buf, &tf);
                    sfree(buf);
+                   line++;
                }
            } else {
                du(scandir, gotdata, ctx);
@@ -1182,6 +1204,12 @@ int main(int argc, char **argv)
            pcfg.oldest = htmloldest;
            pcfg.newest = htmlnewest;
            run_httpd(mappedfile, auth, &dcfg, &pcfg);
+       } else if (mode == REMOVE) {
+           if (remove(filename) < 0) {
+               fprintf(stderr, "%s: %s: remove: %s\n", PNAME, filename,
+                       strerror(errno));
+               return 1;
+           }
        }
     }