Mercurial > hg > toybox
annotate lib/dirtree.c @ 589:7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
author  Rob Landley <rob@landley.net> 

date  Fri, 01 Jun 2012 20:27:51 0500 
parents  9c2277b92b86 
children  fb582378a36a 
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 worksish.
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 worksish.
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 worksish.
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 worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

54 if (!node  !node>name) { 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

55 path = xmalloc(*plen); 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

56 *plen = 0; 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

57 return path; 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
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 worksish.
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 worksish.
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_SAVEDIRTREE_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 
589
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

81 // get open filehandle for node in extra, giving caller the option of 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

82 // using DIRTREE_COMEAGAIN or not. 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

83 int dirtree_opennode(struct dirtree *try) 
588
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depthfirst search with open filehandle in node>extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset

84 { 
589
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

85 if (!dirtree_notdotdot(try)) return 0; 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

86 if (S_ISDIR(try>st.st_mode)) { 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

87 if (!try>extra) { 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

88 try>extra = xdup(try>data); 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

89 return DIRTREE_COMEAGAIN; 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

90 } 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

91 } else try>extra = openat(try>parent ? try>parent>data : AT_FDCWD, 
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

92 try>name, 0); 
588
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depthfirst search with open filehandle in node>extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset

93 
589
7013fd450ff4
Changed my mind about the design again, now callback is dirtree_opennode() and recursion choice is how caller interprets flags.
Rob Landley <rob@landley.net>
parents:
588
diff
changeset

94 return DIRTREE_SAVEDIRTREE_RECURSE; 
588
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depthfirst search with open filehandle in node>extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset

95 } 
9c2277b92b86
Factor out dirtree_comeagain() callback, setting up depthfirst search with open filehandle in node>extra.
Rob Landley <rob@landley.net>
parents:
582
diff
changeset

96 
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

97 // 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

98 // 
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

99 // 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

100 // 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

101 // 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

102 // 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

103 // 
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

104 
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

105 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

106 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

107 { 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

108 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

109 
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

110 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

111 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

112 // 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

113 // 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

114 
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

115 if (dir) 
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

116 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

117 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

118 
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

119 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

120 
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

121 if (dir) { 
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

122 if (flags & (DIRTREE_RECURSEDIRTREE_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

123 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

124 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

125 } 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

126 } 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

127 
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

128 // 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

129 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

130 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

131 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

132 } 
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 
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

134 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

135 } 
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 
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

137 // 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

138 // 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

139 
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

140 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

141 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

142 { 
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 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

144 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

145 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

146 
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 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

148 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

149 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

150 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

151 close(node>data); 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

152 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

153 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

154 } 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

155 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

156 // according to the fddir() man page, the filehandle in the DIR * can still 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

157 // 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

158 
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 // 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

160 while ((entry = readdir(dir))) { 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

161 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

162 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

163 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

164 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

165 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

166 *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

167 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

168 } 
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 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

171 // 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

172 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

173 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

174 } 
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 // 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

177 // 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

178 // 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

179 
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 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

181 { 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

182 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

183 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

184 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

185 } 