Mercurial > hg > toybox
annotate lib/dirtree.c @ 629:225262d6e6c7
Only add / in dirtree_path if it hasn't already got one, spotted by Ashwini Sharma.
author  Rob Landley <rob@landley.net> 

date  Wed, 18 Jul 2012 00:19:08 0500 
parents  8bee9c27c219 
children  786841fdb1e0 
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 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

13 struct dirtree *dirtree_add_node(int dirfd, char *name, int symfollow) 
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) { 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

21 if (fstatat(dirfd, name, &st, symfollow ? 0 : AT_SYMLINK_NOFOLLOW)) 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

22 goto error; 
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

23 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

24 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

25 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

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

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

30 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

31 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

32 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

33 
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

34 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

35 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

36 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

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 } 
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset

39 
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

40 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

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

43 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

44 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

45 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

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

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

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

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

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

53 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

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

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

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

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

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

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

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

61 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

62 path = dirtree_path(node>parent, &len); 
629
225262d6e6c7
Only add / in dirtree_path if it hasn't already got one, spotted by Ashwini Sharma.
Rob Landley <rob@landley.net>
parents:
607
diff
changeset

63 if (len && path[len1] != '/') path[len++]='/'; 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

64 len = (stpcpy(path+len, node>name)  path); 
576
4058eacd4fbc
Whitespace (tabs vs spaces) cleanup.
Rob Landley <rob@landley.net>
parents:
569
diff
changeset

65 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

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

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

71 
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

72 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

73 { 
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 // 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

75 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

76 (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

77 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

78 
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

79 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

80 } 
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset

81 
601  82 int dirtree_parentfd(struct dirtree *node) 
83 {  
84 return node>parent ? node>parent>data : AT_FDCWD;  
85 }  
86  
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

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

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

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

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

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

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

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

94 
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

95 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

96 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

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

98 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

99 
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

100 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

101 
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

102 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

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

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

105 if (flags & (DIRTREE_RECURSEDIRTREE_COMEAGAIN)) { 
607
8bee9c27c219
Unify chown and chgrp, add support for hHLP flags.
Rob Landley <rob@landley.net>
parents:
601
diff
changeset

106 new>data = openat(dirtree_parentfd(new), new>name, 0); 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

107 dirtree_recurse(new, callback, flags & DIRTREE_SYMFOLLOW); 
582
b88bc7dcdb48
Update chgrp so R works, tweaking DIRTREE_COMEAGAIN design along the way.
Rob Landley <rob@landley.net>
parents:
580
diff
changeset

108 if (flags & DIRTREE_COMEAGAIN) flags = callback(new); 
607
8bee9c27c219
Unify chown and chgrp, add support for hHLP flags.
Rob Landley <rob@landley.net>
parents:
601
diff
changeset

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

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

111 
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

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

113 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

114 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

115 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

116 } 
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset

117 
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

118 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

119 } 
9cbb323f297f
Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff
changeset

120 
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

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

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

123 
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 void dirtree_recurse(struct dirtree *node, 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

125 int (*callback)(struct dirtree *node), int symfollow) 
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 { 
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 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

128 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

129 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

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

132 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

133 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

134 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

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

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

137 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

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

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

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

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

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

144 while ((entry = readdir(dir))) { 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

145 if (!(new = dirtree_add_node(node>data, entry>d_name, symfollow))) 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

146 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

147 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

148 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

149 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

150 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

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

152 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

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

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

157 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

158 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

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

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

163 // pointer to root node. 
607
8bee9c27c219
Unify chown and chgrp, add support for hHLP flags.
Rob Landley <rob@landley.net>
parents:
601
diff
changeset

164 // symfollow is just for the top of tree, callback return code controls children 
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

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

167 { 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
589
diff
changeset

168 struct dirtree *root = dirtree_add_node(AT_FDCWD, path, 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

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

170 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

171 } 