// // dod -- show most recent files in current directory. // // - optional -N argument (default 10) to set the number of files displayed // - optional filename wildcard expression to limit types of files // - dod is short for "dir /od | tail" // // 20-Jan-2006 Tom Van Baak (tvb) www.LeapSecond.com/tools // #include #include #include #include #include #include // Sort files by modification time. int fd_cmp (const struct _finddata_t **ap, const struct _finddata_t **bp) { time_t a = (*ap)->time_write; time_t b = (*bp)->time_write; return a < b ? -1 : a > b ? 1 : 0; } void main (int argc, char *argv[]) { long fh, files, files_max, i, tail, start; struct _finddata_t **list, fd; char *pattern; // Get optional file count. tail = 10; if (argc > 1 && argv[1][0] == '-') { tail = atoi(&argv[1][1]); argc -= 1; argv += 1; } // Get optional filename pattern. pattern = (argc > 1) ? argv[1] : "*"; // Read all file names in directory and sort by mod time. if ((fh = _findfirst(pattern, &fd)) == -1) { fprintf(stderr, "no files matching \"%s\"\n", pattern); exit(1); } files_max = 100; if (NULL == (list = malloc(files_max * sizeof list[0]))) { fprintf(stderr, "malloc failed\n"); exit(1); } files = 0; do { if ((fd.attrib & _A_SUBDIR) == 0) { if (files == files_max) { files_max *= 2; if (NULL == (list = realloc(list, files_max * sizeof list[0]))) { fprintf(stderr, "malloc failed\n"); exit(1); } } if (NULL == (list[files] = malloc(sizeof fd))) { fprintf(stderr, "malloc failed\n"); exit(1); } memcpy(list[files], &fd, sizeof fd); files += 1; } } while (_findnext(fh, &fd) != -1); _findclose(fh); qsort(list, files, sizeof list[0], fd_cmp); // Display most recent files in directory. start = (tail <= 0 || tail > files) ? 0 : (files - tail); for (i = start; i < files; i += 1) { char *decimal (unsigned long n); struct tm *tm; if (NULL == (tm = localtime(&list[i]->time_write))) { static struct tm tm0 = { 0, 0, 0, 0, -1, -1900 }; tm = &tm0; } printf("%.4d-%.2d-%.2d %.2d:%.2d:%.2d %13s %s\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, decimal(list[i]->size), list[i]->name); } } // Format decimal numbers with thousands separators. char *decimal (unsigned long n) { unsigned long base, E3 = 1000; static char s[100]; for (base = E3 * E3 * E3; n < base && base > 1; base /= E3) {} sprintf(s, "%ld", n / base); while (base > 1) { n %= base; base /= E3; sprintf(s + strlen(s), ",%.3ld", n / base); } return s; // WARNING: static }