Mercurial > hg > toybox
annotate toys/ls.c @ 650:dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
author  Rob Landley <rob@landley.net> 

date  Sat, 18 Aug 2012 21:12:02 0500 
parents  92200901cfe1 
children 
rev  line source 

458  1 /* vi: set sw=4 ts=4: 
2 *  
3 * ls.c  list files  
4 *  
5 * Copyright 2012 Andre Renaud <andre@bluewatersys.com>  
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:
533
diff
changeset

6 * Copyright 2012 Rob Landley <rob@landley.net> 
458  7 * 
459
1dbe91079950
Second drop of ls from Andre, adds l.
Rob Landley <rob@landley.net>
parents:
458
diff
changeset

8 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html 
458  9 
584  10 // "[Cl]" 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

11 USE_LS(NEWTOY(ls, "goACFHLRSacdfiklmnpqrstux1", TOYFLAG_BIN)) 
458  12 
13 config LS  
14 bool "ls"  
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:
533
diff
changeset

15 default y 
458  16 help 
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:
533
diff
changeset

17 usage: ls [ACFHLRSacdfiklmnpqrstux1] [directory...] 
458  18 list files 
19  
584  20 what to show: 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

21 a all files including .hidden 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

22 c use ctime for timestamps 
584  23 d directory, not contents 
24 i inode number  
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

25 k block sizes in kilobytes 
584  26 p put a '/' after directory names 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

27 q unprintable chars as '?' 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

28 s size (in blocks) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

29 u use access time for timestamps 
514  30 A list all files except . and .. 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

31 H follow command line symlinks 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

32 L follow symlinks 
584  33 R recursively list files in subdirectories 
34 F append file type indicator (/=dir, *=exe, @=symlink, =FIFO)  
35  
36 output formats:  
37 1 list one file per line  
38 C columns (sorted vertically)  
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

39 g like l but no owner 
584  40 l long (show full details for each file) 
41 m comma separated  
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

42 n like l but numeric uid/gid 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

43 o like l but no group 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

44 x columns (sorted horizontally) 
584  45 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

46 sorting (default is alphabetical): 
584  47 f unsorted 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

48 r reverse 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

49 t timestamp 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

50 S size 
458  51 */ 
52  
53 #include "toys.h"  
54  
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:
533
diff
changeset

55 #define FLAG_1 (1<<0) 
584  56 #define FLAG_x (1<<1) 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

57 #define FLAG_u (1<<2) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

58 #define FLAG_t (1<<3) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

59 #define FLAG_s (1<<4) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

60 #define FLAG_r (1<<5) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

61 #define FLAG_q (1<<6) 
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:
533
diff
changeset

62 #define FLAG_p (1<<7) 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

63 #define FLAG_n (1<<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:
533
diff
changeset

64 #define FLAG_m (1<<9) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

65 #define FLAG_l (1<<10) 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

66 #define FLAG_k (1<<11) 
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:
533
diff
changeset

67 #define FLAG_i (1<<12) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

68 #define FLAG_f (1<<13) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

69 #define FLAG_d (1<<14) 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

70 #define FLAG_c (1<<15) 
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:
533
diff
changeset

71 #define FLAG_a (1<<16) 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

72 #define FLAG_S (1<<17) 
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:
533
diff
changeset

73 #define FLAG_R (1<<18) 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

74 #define FLAG_L (1<<19) 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

75 #define FLAG_H (1<<20) 
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:
533
diff
changeset

76 #define FLAG_F (1<<21) 
584  77 #define FLAG_C (1<<22) 
78 #define FLAG_A (1<<23)  
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

79 #define FLAG_o (1<<24) 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

80 #define FLAG_g (1<<25) 
459
1dbe91079950
Second drop of ls from Andre, adds l.
Rob Landley <rob@landley.net>
parents:
458
diff
changeset

81 
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:
533
diff
changeset

82 // test sst output (suid/sticky in ls flaglist) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

83 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

84 // ls lR starts .: then ./subdir: 
459
1dbe91079950
Second drop of ls from Andre, adds l.
Rob Landley <rob@landley.net>
parents:
458
diff
changeset

85 
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:
533
diff
changeset

86 DEFINE_GLOBALS( 
584  87 struct dirtree *files; 
459
1dbe91079950
Second drop of ls from Andre, adds l.
Rob Landley <rob@landley.net>
parents:
458
diff
changeset

88 
584  89 unsigned screen_width; 
90 int nl_title;  
650
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

91 
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

92 // group and user can make overlapping use of the utoa() buf, so move it 
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

93 char uid_buf[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:
533
diff
changeset

94 ) 
459
1dbe91079950
Second drop of ls from Andre, adds l.
Rob Landley <rob@landley.net>
parents:
458
diff
changeset

95 
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:
533
diff
changeset

96 #define TT this.ls 
459
1dbe91079950
Second drop of ls from Andre, adds l.
Rob Landley <rob@landley.net>
parents:
458
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:
533
diff
changeset

98 void dlist_to_dirtree(struct dirtree *parent) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

99 { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

100 // Turn double_list into dirtree 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

101 struct dirtree *dt = parent>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:
533
diff
changeset

102 if (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:
533
diff
changeset

103 dt>parent>next = 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:
533
diff
changeset

104 while (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:
533
diff
changeset

105 dt>parent = parent; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

106 dt = dt>next; 
476
d10b58563cff
More ls updates from Andre Renaud: Add R and initial support for listing files on the command line.
Rob Landley <rob@landley.net>
parents:
459
diff
changeset

107 } 
d10b58563cff
More ls updates from Andre Renaud: Add R and initial support for listing files on the command line.
Rob Landley <rob@landley.net>
parents:
459
diff
changeset

108 } 
458  109 } 
110  
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:
533
diff
changeset

111 static char endtype(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:
533
diff
changeset

112 { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

113 mode_t mode = 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:
533
diff
changeset

114 if ((toys.optflags&(FLAG_FFLAG_p)) && S_ISDIR(mode)) 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:
533
diff
changeset

115 if (toys.optflags & FLAG_F) { 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

116 if (S_ISLNK(mode)) 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:
533
diff
changeset

117 if (S_ISREG(mode) && (mode&0111)) 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:
533
diff
changeset

118 if (S_ISFIFO(mode)) 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:
533
diff
changeset

119 if (S_ISSOCK(mode)) 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:
533
diff
changeset

120 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

121 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:
533
diff
changeset

122 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

123 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

124 static char *getusername(uid_t uid) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

125 { 
584  126 struct passwd *pw = getpwuid(uid); 
650
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

127 utoa_to_buf(uid, TT.uid_buf, 12); 
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

128 return pw ? pw>pw_name : TT.uid_buf; 
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:
533
diff
changeset

129 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
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:
533
diff
changeset

131 static char *getgroupname(gid_t gid) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

132 { 
584  133 struct group *gr = getgrgid(gid); 
134 return gr ? gr>gr_name : utoa(gid);  
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:
533
diff
changeset

135 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

136 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

137 // Figure out size of printable entry fields for display indent/wrap 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

138 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

139 static void entrylen(struct dirtree *dt, unsigned *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:
533
diff
changeset

140 { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

141 struct stat *st = &(dt>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:
533
diff
changeset

142 unsigned flags = toys.optflags; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
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:
533
diff
changeset

144 *len = strlen(dt>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:
533
diff
changeset

145 if (endtype(st)) ++*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:
533
diff
changeset

146 if (flags & FLAG_m) ++*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:
533
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:
533
diff
changeset

148 if (flags & FLAG_i) *len += (len[1] = numlen(st>st_ino)); 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

149 if (flags & (FLAG_lFLAG_oFLAG_nFLAG_g)) { 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

150 unsigned fn = flags & FLAG_n; 
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:
533
diff
changeset

151 len[2] = numlen(st>st_nlink); 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

152 len[3] = strlen(fn ? utoa(st>st_uid) : getusername(st>st_uid)); 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

153 len[4] = strlen(fn ? utoa(st>st_gid) : getgroupname(st>st_gid)); 
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:
533
diff
changeset

154 len[5] = numlen(st>st_size); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

155 } 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

156 if (flags & FLAG_s) *len += (len[6] = numlen(st>st_blocks)); 
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:
533
diff
changeset

157 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
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:
533
diff
changeset

159 static int compare(void *a, void *b) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
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:
533
diff
changeset

161 struct dirtree *dta = *(struct dirtree **)a; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

162 struct dirtree *dtb = *(struct dirtree **)b; 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

163 int ret = 0, reverse = (toys.optflags & FLAG_r) ? 1 : 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:
533
diff
changeset

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

165 if (toys.optflags & FLAG_S) { 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

166 if (dta>st.st_size > dtb>st.st_size) ret = 1; 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

167 else if (dta>st.st_size < dtb>st.st_size) ret = 1; 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

168 } 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

169 if (toys.optflags & FLAG_t) { 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

170 if (dta>st.st_mtime > dtb>st.st_mtime) ret = 1; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

171 else if (dta>st.st_mtime < dtb>st.st_mtime) ret = 1; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

172 } 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

173 if (!ret) ret = strcmp(dta>name, dtb>name); 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

174 return ret * reverse; 
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:
533
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:
533
diff
changeset

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

177 // callback from dirtree_recurse() determining how to handle this entry. 
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

178 
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:
533
diff
changeset

179 static int filter(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:
533
diff
changeset

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

181 int flags = toys.optflags; 
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:
533
diff
changeset

182 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

183 // Special case to handle enormous dirs without running out of memory. 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

184 if (flags == (FLAG_1FLAG_f)) { 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

185 xprintf("%s\n", new>name); 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

186 return 0; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

187 } 
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:
533
diff
changeset

188 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

189 if (!(flags&FLAG_f)) { 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

190 if (flags & FLAG_a) return 0; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

191 if (!(flags & FLAG_A) && new>name[0]=='.') return 0; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

192 } 
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:
533
diff
changeset

193 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

194 if (flags & FLAG_u) new>st.st_mtime = new>st.st_atime; 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

195 if (flags & FLAG_c) new>st.st_mtime = new>st.st_ctime; 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

196 if (flags & FLAG_k) new>st.st_blocks = (new>st.st_blocks + 1) / 2; 
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
573
diff
changeset

197 return dirtree_notdotdot(new); 
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:
533
diff
changeset

198 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

199 
584  200 // For column view, calculate horizontal position (for padding) and return 
201 // index of next entry to display.  
202  
203 static unsigned long next_column(unsigned long ul, unsigned long dtlen,  
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

204 unsigned columns, unsigned *xpos) 
584  205 { 
206 unsigned long transition;  
207 unsigned height, widecols;  
208  
209 // Horizontal sort is easy  
210 if (!(toys.optflags & FLAG_C)) {  
211 *xpos = ul % columns;  
212 return ul;  
213 }  
214  
215 // vertical sort  
216  
217 // For x, calculate height of display, rounded up  
218 height = (dtlen+columns1)/columns;  
219  
220 // Sanity check: does wrapping render this column count impossible  
221 // due to the right edge wrapping eating a whole row?  
222 if (height*columns  dtlen >= height) {  
223 *xpos = columns;  
224 return 0;  
225 }  
226  
227 // Uneven rounding goes along right edge  
228 widecols = dtlen % height;  
229 if (!widecols) widecols = height;  
230 transition = widecols * columns;  
231 if (ul < transition) {  
232 *xpos = ul % columns;  
233 return (*xpos*height) + (ul/columns);  
234 }  
235  
236 ul = transition;  
237 *xpos = ul % (columns1);  
238  
239 return (*xpos*height) + widecols + (ul/(columns1));  
240 }  
241  
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:
533
diff
changeset

242 // Display a list of dirtree entries, according to current format 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

243 // Output types 1, l, C, or stream 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

244 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

245 static void listfiles(int dirfd, struct dirtree *indir) 
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:
533
diff
changeset

246 { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

247 struct dirtree *dt, **sort = 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:
533
diff
changeset

248 unsigned long dtlen = 0, ul = 0; 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

249 unsigned width, flags = toys.optflags, totals[7], len[7], 
584  250 *colsizes = (unsigned *)(toybuf+260), columns = (sizeof(toybuf)260)/4; 
251  
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

252 memset(totals, 0, sizeof(totals)); 
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:
533
diff
changeset

253 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

254 // Silently descend into single directory listed by itself on command line. 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

255 // In this case only show dirname/total header when given R. 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

256 if (!indir>parent) { 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

257 if (!(dt = indir>child)) return; 
584  258 if (S_ISDIR(dt>st.st_mode) && !dt>next && !(flags & FLAG_d)) { 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

259 dt>extra = 1; 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

260 listfiles(open(dt>name, 0), dt); 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

261 return; 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

262 } 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

263 } else { 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

264 // Read directory contents. We dup() the fd because this will close it. 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

265 indir>data = dup(dirfd); 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

266 dirtree_recurse(indir, filter, (flags&FLAG_L)); 
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:
533
diff
changeset

267 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

268 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

269 // Copy linked list to array and sort it. Directories go in array because 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

270 // we visit them in sorted order. 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

271 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

272 for (;;) { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

273 for (dt = indir>child; dt; dt = dt>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:
533
diff
changeset

274 if (sort) sort[dtlen] = 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:
533
diff
changeset

275 dtlen++; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

276 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

277 if (sort) 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:
533
diff
changeset

278 sort = xmalloc(dtlen * sizeof(void *)); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

279 dtlen = 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:
533
diff
changeset

280 continue; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

281 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

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

283 // Label directory if not top of tree, or if R 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

284 if (indir>parent && (!indir>extra  (flags & FLAG_R))) 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

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

286 char *path = dirtree_path(indir, 0); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

287 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

288 if (TT.nl_title++) xputc('\n'); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

289 xprintf("%s:\n", path); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

290 free(path); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

291 } 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

292 
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:
533
diff
changeset

293 if (!(flags & FLAG_f)) qsort(sort, dtlen, sizeof(void *), (void *)compare); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

294 
584  295 // Find largest entry in each field for display alignment 
296 if (flags & (FLAG_CFLAG_x)) {  
297  
298 // columns can't be more than toybuf can hold, or more than files,  
299 // or > 1/2 screen width (one char filename, one space).  
300 if (columns > TT.screen_width/2) columns = TT.screen_width/2;  
301 if (columns > dtlen) columns = dtlen;  
302  
303 // Try to fit as many columns as we can, dropping down by one each time  
304 for (;columns > 1; columns) {  
305 unsigned c, totlen = columns;  
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:
533
diff
changeset

306 
584  307 memset(colsizes, 0, columns*sizeof(unsigned)); 
308 for (ul=0; ul<dtlen; ul++) {  
309 entrylen(sort[next_column(ul, dtlen, columns, &c)], len);  
310 if (c == columns) break;  
311 // Does this put us over budget?  
312 if (*len > colsizes[c]) {  
313 totlen += *lencolsizes[c];  
314 colsizes[c] = *len;  
315 if (totlen > TT.screen_width) break;  
316 }  
317 }  
318 // If it fit, stop here  
319 if (ul == dtlen) break;  
320 }  
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

321 } else if (flags & (FLAG_lFLAG_oFLAG_nFLAG_gFLAG_s)) { 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

322 unsigned long blocks = 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:
533
diff
changeset

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

324 for (ul = 0; ul<dtlen; ul++) 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

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

326 entrylen(sort[ul], len); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

327 for (width=0; width<6; width++) 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

328 if (len[width] > totals[width]) totals[width] = len[width]; 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

329 blocks += sort[ul]>st.st_blocks; 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

330 } 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

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

332 if (indir>parent) xprintf("total %lu\n", blocks); 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

333 } 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

334 
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:
533
diff
changeset

335 // Loop through again to produce output. 
584  336 memset(toybuf, ' ', 256); 
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:
533
diff
changeset

337 width = 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:
533
diff
changeset

338 for (ul = 0; ul<dtlen; ul++) { 
584  339 unsigned curcol; 
340 unsigned long next = next_column(ul, dtlen, columns, &curcol);  
341 struct stat *st = &(sort[next]>st);  
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:
533
diff
changeset

342 mode_t mode = 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:
533
diff
changeset

343 char et = endtype(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:
533
diff
changeset

344 
571  345 // Skip directories at the top of the tree when d isn't set 
346 if (S_ISDIR(mode) && !indir>parent && !(flags & FLAG_d)) continue;  
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

347 TT.nl_title=1; 
571  348 
584  349 // Handle padding and wrapping for display purposes 
350 entrylen(sort[next], 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:
533
diff
changeset

351 if (ul) { 
584  352 if (flags & FLAG_m) xputc(','); 
353 if (flags & (FLAG_CFLAG_x)) {  
354 if (!curcol) xputc('\n');  
355 } else if ((flags & FLAG_1)  width+1+*len > TT.screen_width) {  
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:
533
diff
changeset

356 xputc('\n'); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

357 width = 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:
533
diff
changeset

358 } else { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

359 xputc(' '); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

360 width++; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

361 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

362 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

363 width += *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:
533
diff
changeset

364 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

365 if (flags & FLAG_i) 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

366 xprintf("% *lu ", len[1], (unsigned long)st>st_ino); 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

367 if (flags & FLAG_s) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

368 xprintf("% *lu ", len[6], (unsigned long)st>st_blocks); 
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:
533
diff
changeset

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

370 if (flags & (FLAG_lFLAG_oFLAG_nFLAG_g)) { 
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:
533
diff
changeset

371 struct tm *tm; 
650
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

372 char perm[11], thyme[64], c, d, *usr, *upad, *grp, *grpad; 
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:
533
diff
changeset

373 int i, bit; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

374 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

375 perm[10]=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:
533
diff
changeset

376 for (i=0; i<9; i++) { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

377 bit = mode & (1<<i); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

378 c = i%3; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

379 if (!c && (mode & (1<<((d=i/3)+9)))) { 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

380 c = "tss"[d]; 
638
92200901cfe1
Make chmod +w respect umask, implement +s and +t, fix ls to show suid/sgid/stid without x bit.
Rob Landley <rob@landley.net>
parents:
597
diff
changeset

381 if (!bit) c &= ~0x20; 
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:
533
diff
changeset

382 } else c = bit ? "xwr"[c] : ''; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

383 perm[9i] = c; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

384 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

385 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

386 if (S_ISDIR(mode)) c = 'd'; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

387 else if (S_ISBLK(mode)) c = 'b'; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

388 else if (S_ISCHR(mode)) c = 'c'; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

389 else if (S_ISLNK(mode)) c = 'l'; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

390 else if (S_ISFIFO(mode)) c = 'p'; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

391 else if (S_ISSOCK(mode)) c = 's'; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

392 else c = ''; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

393 *perm = c; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

394 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

395 tm = localtime(&(st>st_mtime)); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

396 strftime(thyme, sizeof(thyme), "%F %H:%M", tm); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

397 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

398 if (flags&FLAG_o) grp = grpad = toybuf+256; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

399 else { 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

400 grp = (flags&FLAG_n) ? utoa(st>st_gid) 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

401 : getgroupname(st>st_gid); 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

402 grpad = toybuf+256(totals[4]len[4]); 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

403 } 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

404 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

405 if (flags&FLAG_g) usr = upad = toybuf+256; 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

406 else { 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

407 upad = toybuf+255(totals[3]len[3]); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

408 if (flags&FLAG_n) { 
650
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

409 usr = TT.uid_buf; 
dd82e0b28eda
Fix bug spotted by Avery Pennarun: getusername() and getgroupname() can reuse the utoa buffer when neither is recognized, meaning uid would be shown again instead of gid.
Rob Landley <rob@landley.net>
parents:
638
diff
changeset

410 utoa_to_buf(st>st_uid, TT.uid_buf, 12); 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

411 } else usr = getusername(st>st_uid); 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

412 } 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

413 
597
b2d0e8e572ba
Fix an embarassing bug causing ls l to segfault on 32 bit targets.
Rob Landley <rob@landley.net>
parents:
593
diff
changeset

414 // Coerce the st types into something we know we can print. 
b2d0e8e572ba
Fix an embarassing bug causing ls l to segfault on 32 bit targets.
Rob Landley <rob@landley.net>
parents:
593
diff
changeset

415 xprintf("%s% *ld %s%s%s%s% *"PRId64" %s ", perm, totals[2]+1, 
b2d0e8e572ba
Fix an embarassing bug causing ls l to segfault on 32 bit targets.
Rob Landley <rob@landley.net>
parents:
593
diff
changeset

416 (long)st>st_nlink, usr, upad, grp, grpad, totals[5]+1, 
b2d0e8e572ba
Fix an embarassing bug causing ls l to segfault on 32 bit targets.
Rob Landley <rob@landley.net>
parents:
593
diff
changeset

417 (int64_t)st>st_size, thyme); 
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:
533
diff
changeset

418 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

419 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

420 if (flags & FLAG_q) { 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

421 char *p; 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

422 for (p=sort[next]>name; *p; p++) xputc(isprint(*p) ? *p : '?'); 
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

423 } else xprintf("%s", sort[next]>name); 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

424 if ((flags & (FLAG_lFLAG_oFLAG_nFLAG_g)) && S_ISLNK(mode)) 
584  425 xprintf(" > %s", sort[next]>symlink); 
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:
533
diff
changeset

426 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

427 if (et) xputc(et); 
584  428 
429 // Pad columns  
430 if (flags & (FLAG_CFLAG_x)) {  
431 curcol = colsizes[curcol]  *len;  
432 if (curcol >= 0) xprintf("%s", toybuf+255curcol);  
433 }  
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:
533
diff
changeset

434 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

435 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

436 if (width) xputc('\n'); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

437 
571  438 // Free directory entries, recursing first if necessary. 
439  
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:
533
diff
changeset

440 for (ul = 0; ul<dtlen; free(sort[ul++])) { 
571  441 if ((flags & FLAG_d)  !S_ISDIR(sort[ul]>st.st_mode) 
580
4877cff01b25
dirtree logic cleanup: switch DIRTREE_NORECURSE and DIRTREE_NOSAVE to DIRTREE_RECURSE and DIRTREE_SAVE.
Rob Landley <rob@landley.net>
parents:
573
diff
changeset

442  !dirtree_notdotdot(sort[ul])) continue; 
571  443 
444 // Recurse into dirs if at top of the tree or given R  
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

445 if (!indir>parent  (flags & FLAG_R)) 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

446 listfiles(openat(dirfd, sort[ul]>name, 0), sort[ul]); 
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:
533
diff
changeset

447 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

448 free(sort); 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

449 if (dirfd != AT_FDCWD) close(indir>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:
533
diff
changeset

450 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

451 
458  452 void ls_main(void) 
453 {  
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:
533
diff
changeset

454 char **s, *noargs[] = {".", 0}; 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

455 struct dirtree *dt; 
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:
533
diff
changeset

456 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

457 // Do we have an implied 1 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

458 if (!isatty(1)  (toys.optflags&(FLAG_lFLAG_oFLAG_nFLAG_g))) 
591
7c4ca3f0536b
Add ls kqsunort, and fix F @symlink.
Rob Landley <rob@landley.net>
parents:
584
diff
changeset

459 toys.optflags = FLAG_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:
533
diff
changeset

460 else { 
584  461 TT.screen_width = 80; 
462 terminal_size(&TT.screen_width, 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:
533
diff
changeset

463 } 
571  464 // The optflags parsing infrastructure should really do this for us, 
465 // but currently it has "switch off when this is set", so "dR" and "Rd"  
466 // behave differently  
467 if (toys.optflags & FLAG_d) toys.optflags &= ~FLAG_R;  
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:
533
diff
changeset

468 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

469 // Iterate through command line arguments, collecting directories and files. 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

470 // Nonabsolute paths are relative to current directory. 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

471 TT.files = dirtree_add_node(0, 0, 0); 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

472 for (s = *toys.optargs ? toys.optargs : noargs; *s; s++) { 
593
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

473 dt = dirtree_add_node(AT_FDCWD, *s, 
fb582378a36a
Implement DIRTREE_SYMFOLLOW and ls cSHL.
Rob Landley <rob@landley.net>
parents:
591
diff
changeset

474 (toys.optflags & (FLAG_LFLAG_HFLAG_l))^FLAG_l); 
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:
533
diff
changeset

475 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

476 if (!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:
533
diff
changeset

477 toys.exitval = 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:
533
diff
changeset

478 continue; 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

479 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

480 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

481 // Typecast means double_list>prev temporarirly goes in dirtree>parent 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

482 dlist_add_nomalloc((struct double_list **)&TT.files>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:
533
diff
changeset

483 (struct double_list *)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:
533
diff
changeset

484 } 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

485 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

486 // Turn double_list into dirtree 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

487 dlist_to_dirtree(TT.files); 
44abf4d901f3
Rewrite dirtree so we don't need readdir, scandir, and fts.h. Rewrite ls (from scratch) to use new dirtree infrastructure. (This breaks everything else that currently uses dirtree.)
Rob Landley <rob@landley.net>
parents:
533
diff
changeset

488 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

489 // Display the files we collected 
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

490 listfiles(AT_FDCWD, TT.files); 
569
2e0367cb9585
More work on ls. Now ls lR sort of worksish.
Rob Landley <rob@landley.net>
parents:
565
diff
changeset

491 
573
c42ed3601b35
Simplify/unify listfiles recursion: populate directory node (and detect top of tree) at start of function rather than end (and redundantly in main). Move title printing down next to total printing.
Rob Landley <rob@landley.net>
parents:
571
diff
changeset

492 if (CFG_TOYBOX_FREE) free(TT.files); 
458  493 } 