95e9718709993572ff6e85bc7a751e1baa89c26a
braney
  Mon Nov 20 14:47:56 2023 -0800
add a utility to count up how many sessions are missing their custom
tracks

diff --git src/lib/osunix.c src/lib/osunix.c
index ce81386..fdf25b4 100644
--- src/lib/osunix.c
+++ src/lib/osunix.c
@@ -153,39 +153,40 @@
 	{
 	if (!regexec(&re, fileName, 0, NULL, 0))
 	    {
 	    name = newSlName(fileName);
 	    slAddHead(&list, name);
 	    }
 	}
     }
 closedir(d);
 regfree(&re);
 slNameSort(&list);
 return list;
 }
 
 struct fileInfo *newFileInfo(char *name, off_t size, bool isDir, int statErrno, 
-	time_t lastAccess)
+	time_t lastAccess, time_t creationTime)
 /* Return a new fileInfo. */
 {
 int len = strlen(name);
 struct fileInfo *fi = needMem(sizeof(*fi) + len);
 fi->size = size;
 fi->isDir = isDir;
 fi->statErrno = statErrno;
 fi->lastAccess = lastAccess;
+fi->creationTime = creationTime;
 strcpy(fi->name, name);
 return fi;
 }
 
 int cmpFileInfo(const void *va, const void *vb)
 /* Compare two fileInfo. */
 {
 const struct fileInfo *a = *((struct fileInfo **)va);
 const struct fileInfo *b = *((struct fileInfo **)vb);
 return strcmp(a->name, b->name);
 }
 
 boolean makeDir(char *dirName)
 /* Make dir.  Returns TRUE on success.  Returns FALSE
  * if failed because directory exists.  Prints error
@@ -232,31 +233,31 @@
 	    struct stat st;
 	    bool isDir = FALSE;
 	    int statErrno = 0;
 	    strcpy(pathName+fileNameOffset, fileName);
 	    if (stat(pathName, &st) < 0)
 		{
 		if (ignoreStatFailures)
 		    statErrno = errno;
 		else
     		    errnoAbort("stat failed in listDirX: %s", pathName);
 		}
 	    if (S_ISDIR(st.st_mode))
 		isDir = TRUE;
 	    if (fullPath)
 		fileName = pathName;
-	    el = newFileInfo(fileName, st.st_size, isDir, statErrno, st.st_atime);
+	    el = newFileInfo(fileName, st.st_size, isDir, statErrno, st.st_atime, st.st_ctime);
 	    slAddHead(&list, el);
 	    }
 	}
     }
 closedir(d);
 slSort(&list, cmpFileInfo);
 return list;
 }
 
 struct fileInfo *listDirX(char *dir, char *pattern, boolean fullPath)
 /* Return list of files matching wildcard pattern with
  * extra info. If full path is true then the path will be
  * included in the name of each file. */
 {
 return listDirXExt(dir, pattern, fullPath, FALSE);