2 * Display directory contents
14 static int rows
, cols
; /* Screen parameters */
16 #define DIR_CHUNK 1024
18 static const char *type_str(int type
)
43 static void free_dirents(struct dirent
**dex
, size_t n_de
)
47 for (i
= 0; i
< n_de
; i
++)
53 static int compare_dirent(const void *p_de1
, const void *p_de2
)
55 const struct dirent
*de1
= *(const struct dirent
**)p_de1
;
56 const struct dirent
*de2
= *(const struct dirent
**)p_de2
;
59 ndir1
= de1
->d_type
!= DT_DIR
;
60 ndir2
= de2
->d_type
!= DT_DIR
;
65 return strcmp(de1
->d_name
, de2
->d_name
);
68 static int display_directory(const char *dirname
)
72 struct dirent
**dex
= NULL
;
73 size_t n_dex
= 0, n_de
= 0;
75 size_t nrows
, ncols
, perpage
;
78 int pos
, tpos
, colwidth
;
80 dir
= opendir(dirname
);
82 printf("Unable to read directory: %s\n", dirname
);
86 while ((de
= readdir(dir
)) != NULL
) {
92 ndex
= realloc(dex
, (n_dex
+ DIR_CHUNK
) * sizeof *dex
);
100 nde
= malloc(de
->d_reclen
);
104 memcpy(nde
, de
, de
->d_reclen
);
107 maxlen
= max(maxlen
, de
->d_reclen
);
112 qsort(dex
, n_de
, sizeof *dex
, compare_dirent
);
114 maxlen
-= offsetof(struct dirent
, d_name
) + 1;
115 ncols
= (cols
+ 2)/(maxlen
+ 8);
116 ncols
= min(ncols
, n_de
);
117 ncols
= max(ncols
, 1U);
118 colwidth
= (cols
+ 2)/ncols
;
119 perpage
= ncols
* (rows
- 1);
121 for (i
= 0; i
< n_de
; i
+= perpage
) {
122 /* Rows on this page */
123 endpage
= min(i
+perpage
, n_de
);
124 nrows
= ((endpage
-i
) + ncols
- 1)/ncols
;
126 for (j
= 0; j
< nrows
; j
++) {
128 for (k
= i
+j
; k
< endpage
; k
+= nrows
) {
129 pos
+= printf("%*s%-5s %s",
131 type_str(dex
[k
]->d_type
),
144 free_dirents(dex
, n_de
);
149 printf("Out of memory error!\n");
150 free_dirents(dex
, n_de
);
154 int main(int argc
, char *argv
[])
158 if (getscreensize(1, &rows
, &cols
)) {
159 /* Unknown screen size? */
165 rv
= display_directory(".");
167 rv
= display_directory(argv
[1]);
169 printf("Usage: %s directory\n", argv
[0]);