Mercurial > hg > toybox
annotate lib/dirtree.c @ 588:9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 01 Jun 2012 20:04:39 -0500 |
parents | b88bc7dcdb48 |
children | 7013fd450ff4 |
rev | line source |
---|---|
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1 /* vi: set sw=4 ts=4 :*/ |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
2 /* dirtree.c - Functions for dealing with directory trees. |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
3 * |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
4 * Copyright 2007 Rob Landley <rob@landley.net> |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
5 */ |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
6 |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
7 #include "toys.h" |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
8 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
9 // Create a dirtree node from a path, with stat and symlink info. |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
10 // (This doesn't open directory filehandles yet so as not to exhaust the |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
11 // filehandle space on large trees. handle_callback() does that instead.) |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
12 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
13 struct dirtree *dirtree_add_node(int dirfd, char *name) |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
14 { |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
15 struct dirtree *dt = NULL; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
16 struct stat st; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
17 char buf[4096]; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
18 int len = 0, linklen = 0; |
156
1e8f4b05cb65
Remove trailing whitespace (thanks to Charlie Shepherd), and a couple comment
Rob Landley <rob@landley.net>
parents:
143
diff
changeset
|
19 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
20 if (name) { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
21 if (fstatat(dirfd, name, &st, AT_SYMLINK_NOFOLLOW)) goto error; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
22 if (S_ISLNK(st.st_mode)) { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
23 if (0>(linklen = readlinkat(dirfd, name, buf, 4095))) goto error; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
24 buf[linklen++]=0; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
25 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
26 len = strlen(name); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
27 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
28 dt = xzalloc((len = sizeof(struct dirtree)+len+1)+linklen); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
29 if (name) { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
30 memcpy(&(dt->st), &st, sizeof(struct stat)); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
31 strcpy(dt->name, name); |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
32 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
33 if (linklen) { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
34 dt->symlink = memcpy(len+(char *)dt, buf, linklen); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
35 dt->data = --linklen; |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
36 } |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
37 } |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
38 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
39 return dt; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
40 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
41 error: |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
42 perror_msg("%s",name); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
43 free(dt); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
44 return 0; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
45 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
46 |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
47 // Return path to this node, assembled recursively. |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
48 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
49 char *dirtree_path(struct dirtree *node, int *plen) |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
50 { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
51 char *path; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
52 int len; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
53 |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
54 if (!node || !node->name) { |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
55 path = xmalloc(*plen); |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
56 *plen = 0; |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
57 return path; |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
58 } |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
59 |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
60 len = (plen ? *plen : 0)+strlen(node->name)+1; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
61 path = dirtree_path(node->parent, &len); |
576
4058eacd4fbc
Whitespace (tabs vs spaces) cleanup.
Rob Landley <rob@landley.net>
parents:
569
diff
changeset
|
62 if (len) path[len++]='/'; |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
63 len = (stpcpy(path+len, node->name) - path); |
576
4058eacd4fbc
Whitespace (tabs vs spaces) cleanup.
Rob Landley <rob@landley.net>
parents:
569
diff
changeset
|
64 if (plen) *plen = len; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
65 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
66 return path; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
67 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
68 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
69 // Default callback, filters out "." and "..". |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
70 |
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
576
diff
changeset
|
71 int dirtree_notdotdot(struct dirtree *catch) |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
72 { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
73 // Should we skip "." and ".."? |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
74 if (catch->name[0]=='.' && (!catch->name[1] || |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
75 (catch->name[1]=='.' && !catch->name[2]))) |
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
576
diff
changeset
|
76 return 0; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
77 |
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
576
diff
changeset
|
78 return DIRTREE_SAVE|DIRTREE_RECURSE; |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
79 } |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
80 |
588
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
81 // depth first recursion |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
82 int dirtree_comeagain(struct dirtree *try, int recurse) |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
83 { |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
84 int ret = dirtree_notdotdot(try); |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
85 if (ret) { |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
86 if (S_ISDIR(try->st.st_mode)) { |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
87 if (!try->extra) { |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
88 try->extra = xdup(try->data); |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
89 if (recurse) return DIRTREE_COMEAGAIN; |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
90 } |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
91 } else try->extra = openat(try->parent ? try->parent->data : AT_FDCWD, |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
92 try->name, 0); |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
93 } |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
94 |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
95 return ret; |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
96 } |
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depth-first search with open filehandle in node->extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset
|
97 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
98 // Handle callback for a node in the tree. Returns saved node(s) or NULL. |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
99 // |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
100 // By default, allocates a tree of struct dirtree, not following symlinks |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
101 // If callback==NULL, or callback always returns 0, allocate tree of struct |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
102 // dirtree and return root of tree. Otherwise call callback(node) on each |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
103 // hit, free structures after use, and return NULL. |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
104 // |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
105 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
106 struct dirtree *handle_callback(struct dirtree *new, |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
107 int (*callback)(struct dirtree *node)) |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
108 { |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
109 int flags, dir = S_ISDIR(new->st.st_mode); |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
110 |
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
576
diff
changeset
|
111 if (!callback) callback = dirtree_notdotdot; |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
112 |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
113 // Directory always has filehandle for examining contents. Whether or |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
114 // not we'll recurse into it gets decided later. |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
115 |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
116 if (dir) |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
117 new->data = openat(new->parent ? new->parent->data : AT_FDCWD, |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
118 new->name, 0); |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
119 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
120 flags = callback(new); |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
121 |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
122 if (dir) { |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
123 if (flags & (DIRTREE_RECURSE|DIRTREE_COMEAGAIN)) { |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
124 dirtree_recurse(new, callback); |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
125 if (flags & DIRTREE_COMEAGAIN) flags = callback(new); |
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
126 } else close(new->data); |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
127 } |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
128 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
129 // If this had children, it was callback's job to free them already. |
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
576
diff
changeset
|
130 if (!(flags & DIRTREE_SAVE)) { |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
131 free(new); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
132 new = NULL; |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
133 } |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
134 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
135 return (flags & DIRTREE_ABORT)==DIRTREE_ABORT ? DIRTREE_ABORTVAL : new; |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
136 } |
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
137 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
138 // Recursively read/process children of directory node (with dirfd in data), |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
139 // filtering through callback(). |
143
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
140 |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
141 void dirtree_recurse(struct dirtree *node, |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
142 int (*callback)(struct dirtree *node)) |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
143 { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
144 struct dirtree *new, **ddt = &(node->child); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
145 struct dirent *entry; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
146 DIR *dir; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
147 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
148 if (!(dir = fdopendir(node->data))) { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
149 char *path = dirtree_path(node, 0); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
150 perror_msg("No %s", path); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
151 free(path); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
152 close(node->data); |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
153 |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
154 return; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
155 } |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
156 |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
157 // according to the fddir() man page, the filehandle in the DIR * can still |
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
158 // be externally used by things that don't lseek() it. |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
159 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
160 // The extra parentheses are to shut the stupid compiler up. |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
161 while ((entry = readdir(dir))) { |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
162 if (!(new = dirtree_add_node(node->data, entry->d_name))) continue; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
163 new->parent = node; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
164 new = handle_callback(new, callback); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
165 if (new == DIRTREE_ABORTVAL) break; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
166 if (new) { |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
167 *ddt = new; |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
168 ddt = &((*ddt)->next); |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
169 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
170 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
171 |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
172 // This closes filehandle as well, so note it |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
173 closedir(dir); |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
174 node->data = -1; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
175 } |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
176 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
177 // Create dirtree from path, using callback to filter nodes. |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
178 // If callback == NULL allocate a tree of struct dirtree nodes and return |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
179 // pointer to root node. |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
180 |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
181 struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node)) |
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
182 { |
569
2e0367cb9585
More work on ls. Now ls -lR sort of works-ish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset
|
183 struct dirtree *root = dirtree_add_node(AT_FDCWD, path); |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
184 |
582
b88bc7dcdb48
Update chgrp so -R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset
|
185 return root ? handle_callback(root, callback) : DIRTREE_ABORTVAL; |
565
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
320
diff
changeset
|
186 } |