- if (S_ISLNK(f->mode)) perms[0] = 'l';
- if (S_ISDIR(f->mode)) perms[0] = 'd';
- if (S_ISBLK(f->mode)) perms[0] = 'b';
- if (S_ISCHR(f->mode)) perms[0] = 'c';
- if (S_ISSOCK(f->mode)) perms[0] = 's';
- if (S_ISFIFO(f->mode)) perms[0] = 'p';
-
+}
+
+static char *string_area_malloc(struct string_area **ap, int size)
+{
+ char *p;
+ struct string_area *a;
+
+ /* does the request fit into the current space? */
+ a = *ap;
+ if (a->current + size >= a->end) {
+ /* no; get space, move new string_area to front of the list */
+ a = string_area_new(size > ARENA_SIZE ? size : ARENA_SIZE);
+ a->next = *ap;
+ *ap = a;
+ }
+
+ /* have space; do the "allocation." */
+ p = a->current;
+ a->current += size;
+ return p;
+}
+
+static char *string_area_strdup(struct string_area **ap, const char *src)
+{
+ char* dest = string_area_malloc(ap, strlen(src) + 1);
+ return strcpy(dest, src);
+}
+
+static void list_file_entry(struct file_struct *f)
+{
+ char perms[11];
+
+ if (!f->basename)
+ /* this can happen if duplicate names were removed */
+ return;
+
+ permstring(perms, f->mode);
+