static int display_dir(char * p) { /* Open the directory */ DIR * dirp = opendir(p); if (dirp == NULL) { return 2; } if (print_dir) { printf("%s:\n", p); } /* Read the entries in the directory */ list_t * ents_list = list_create(); struct dirent * ent = readdir(dirp); while (ent != NULL) { if (show_hidden || (ent->d_name[0] != '.')) { struct tfile * f = malloc(sizeof(struct tfile)); f->name = strdup(ent->d_name); char tmp[strlen(p)+strlen(ent->d_name)+1]; sprintf(tmp, "%s/%s", p, ent->d_name); int t = stat(tmp, &f->statbuf); list_insert(ents_list, (void *)f); } ent = readdir(dirp); } closedir(dirp); /* Now, copy those entries into an array (for sorting) */ struct tfile ** file_arr = malloc(sizeof(struct tfile *) * ents_list->length); int index = 0; foreach(node, ents_list) { file_arr[index++] = (struct tfile *)node->value; } list_free(ents_list); qsort(file_arr, index, sizeof(struct tfile *), filecmp_notypesort); display_tfiles(file_arr, index); free(file_arr); return 0; }
int main (int argc, char * argv[]) { /* Parse arguments */ char * p = "."; if (argc > 1) { int c; while ((c = getopt(argc, argv, "ahl?")) != -1) { switch (c) { case 'a': show_hidden = 1; break; case 'h': human_readable = 1; break; case 'l': long_mode = 1; break; case '?': show_usage(argc, argv); return 0; } } if (optind < argc) { p = argv[optind]; } if (optind + 1 < argc) { print_dir = 1; } } stdout_is_tty = isatty(STDOUT_FILENO); if (long_mode) { struct tm * timeinfo; struct timeval now; gettimeofday(&now, NULL); //time(NULL); timeinfo = localtime((time_t *)&now.tv_sec); this_year = timeinfo->tm_year; } if (stdout_is_tty) { TRACE("getting display size"); struct winsize w; ioctl(1, TIOCGWINSZ, &w); term_width = w.ws_col; term_height = w.ws_row; term_width -= 1; /* And this just helps clean up our math */ } int out = 0; if (argc == 1 || optind == argc) { TRACE("no file to look up"); if (display_dir(p) == 2) { fprintf(stderr, "%s: %s: %s\n", argv[0], p, strerror(errno)); } } else { list_t * files = list_create(); while (p) { struct tfile * f = malloc(sizeof(struct tfile)); f->name = p; int t = lstat(p, &f->statbuf); if (t < 0) { fprintf(stderr, "%s: %s: %s\n", argv[0], p, strerror(errno)); free(f); out = 2; } else { if (S_ISLNK(f->statbuf.st_mode)) { stat(p, &f->statbufl); f->link = malloc(4096); readlink(p, f->link, 4096); } list_insert(files, f); } optind++; if (optind >= argc) p = NULL; else p = argv[optind]; } if (!files->length) { /* No valid entries */ return out; } struct tfile ** file_arr = malloc(sizeof(struct tfile *) * files->length); int index = 0; foreach(node, files) { file_arr[index++] = (struct tfile *)node->value; } list_free(files); qsort(file_arr, index, sizeof(struct tfile *), filecmp); int first_directory = index; for (int i = 0; i < index; ++i) { if (S_ISDIR(file_arr[i]->statbuf.st_mode)) { first_directory = i; break; } } if (first_directory) { display_tfiles(file_arr, first_directory); } for (int i = first_directory; i < index; ++i) { if (i != 0) { printf("\n"); } if (display_dir(file_arr[i]->name) == 2) { fprintf(stderr, "%s: %s: %s\n", argv[0], file_arr[i]->name, strerror(errno)); } } } return out; }