+void print_sorted(struct entry_node *root, int width, int height) {
+ char line[BUFFER_SIZE];
+ struct entry_node *node;
+ struct entry_node **nodes;
+ int nb_nodes, n, first, last;
+
+ nb_nodes = 0;
+ for(node = root; node; node = node->next) {
+ if(size_min < 0 || node->size >= size_min) {
+ nb_nodes++;
+ }
+ }
+
+ nodes = safe_malloc(nb_nodes * sizeof(struct entry_node *));
+
+ n = 0;
+ for(node = root; node; node = node->next) {
+ if(size_min < 0 || node->size >= size_min) {
+ nodes[n++] = node;
+ }
+ }
+
+ qsort(nodes, nb_nodes, sizeof(struct entry_node *), compare_files);
+
+ first = 0;
+ last = nb_nodes;
+
+ if(forced_height) {
+ height = forced_height;
+ }
+
+ if(forced_width) {
+ width = forced_width;
+ }
+
+ if(height >= 0 && nb_nodes > height && !show_top && !forced_height) {
+ printf("...\n");
+ }
+
+ if(height > 0 && height < nb_nodes) {
+ first = nb_nodes - height;
+ }
+
+ if(show_top) {
+ n = last;
+ last = nb_nodes - first;
+ first = nb_nodes - n;
+ }
+
+ /* I do not like valgrind to complain about uninitialized data */
+ if(width < BUFFER_SIZE) {
+ line[width] = '\0';
+ }
+
+ for(n = first; n < last; n++) {
+ if(fancy_size_display) {
+ fancy_print(line, BUFFER_SIZE, nodes[n]->name, nodes[n]->size);
+ } else {
+ raw_print(line, BUFFER_SIZE, nodes[n]->name, nodes[n]->size);
+ }
+ if(width >= 1 && width + 1 < BUFFER_SIZE && line[width]) {
+ line[width] = '\n';
+ line[width + 1] = '\0';
+ }
+ printf("%s", line);
+ }
+
+ if(height >= 0 && nb_nodes > height && show_top && !forced_height) {
+ printf("...\n");
+ }
+
+ free(nodes);
+}
+
+/**********************************************************************/
+
+void usage(FILE *out) {
+ fprintf(out, "Usage: dus [OPTION]... [FILE]...\n");
+ fprintf(out, "Version %s (%s)\n", VERSION_NUMBER, UNAME);
+ fprintf(out, "Lists files and directories according to their size. The sizes are computed by summing recursively exact file sizes through directories. If a given directory has its name appended with '/', it is not listed, but the elements it contains are. If no files or directories are provided as arguments, the current directory is used as default.\n");
+ fprintf(out, "\n");
+ /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789*/
+ fprintf(out, " -h, --help show this help.\n");
+ fprintf(out, " -v, --version prints the version number and exit\n");
+ fprintf(out, " -d, --ignore-dots ignore files and directories starting with a '.'\n");
+ fprintf(out, " -i, --ignore-protected do not exit when visiting files and directories\n");
+ fprintf(out, " for which we do not have permission\n");
+ fprintf(out, " -f, --fancy display size with float values and K, M and G\n");
+ fprintf(out, " units.\n");
+ fprintf(out, " -r, --reverse-order reverse the sorting order.\n");
+ fprintf(out, " -t, --show-top show the top of the list.\n");
+ fprintf(out, " -c <cols>, --nb-columns <cols>\n");
+ fprintf(out, " specificy the number of columns to display. The\n");
+ fprintf(out, " value -1 corresponds to no constraint. By default\n");
+ fprintf(out, " the command uses the tty width, or no constraint\n");
+ fprintf(out, " if the stdout is not a tty.\n");
+ fprintf(out, " -l <lines>, --nb-lines <lines>\n");
+ fprintf(out, " same as -c for number of lines.\n");
+ fprintf(out, " -m <size>, --size-min <size>\n");
+ fprintf(out, " set the listed entries minimum size. The size\n");
+ fprintf(out, " can be specified using the G, M, K, and B units.\n");
+ fprintf(out, "\n");
+ fprintf(out, "Report bugs and comments to <francois@fleuret.org>.\n");
+}
+
+/**********************************************************************/
+
+static struct option long_options[] = {
+ { "version", no_argument, 0, 'v' },
+ { "ignore-dots", no_argument, 0, 'd' },
+ { "ignore-protected", no_argument, 0, 'i' },
+ { "reverse-order", no_argument, 0, 'r' },
+ { "show-top", no_argument, 0, 't' },
+ { "help", no_argument, 0, 'h' },
+ { "fancy", no_argument, 0, 'f' },
+ { "nb-columns", 1, 0, 'c' },
+ { "nb-lines", 1, 0, 'l' },
+ { "size-min", 1, 0, 'm' },
+ { 0, 0, 0, 0 }
+};
+