支持 -r --recursive 递归处理子目录,-a 显示隐藏文件,-l 显示属性,及这些参数的任意组合,可指定路径,默认为当前目录。
1
/**//*
2
作者
3
coreBugZJ
4
jinyang6655
5
6
命令名
7
ols
8
参数
9
递归
10
-r
11
--recursive
12
所有文件
13
-a
14
属性
15
-l
16
17
使用方式举例
18
ols
19
ols -r
20
ols dirnameA -ra
21
ols dirnameA dirnameB -l -a
22
*/
23
24
25
/**//*
26
几个定义
27
28
fullname /home/dir/name.c
29
dirname /home/dir
30
fullpath /home/dir/
31
filename name.c
32
*/
33
34
35
#include <stdio.h>
36
#include <sys/types.h>
37
#include <sys/stat.h>
38
#include <dirent.h>
39
#include <string.h>
40
#include <getopt.h>
41
#include <math.h>
42
#include <pwd.h>
43
#include <grp.h>
44
#include <time.h>
45
46
/**//* 文件名最大长度 */
47
#define NAME_LEN 257
48
49
50
/**//* 标志位,是否 -r */
51
#define FLAG_R 1
52
/**//* 标志位,是否 -a */
53
#define FLAG_A 2
54
/**//* 标志位,是否 -l */
55
#define FLAG_L 4
56
57
58
/**//* 定义函数类型,独立于文件遍历方式,处理被遍历到的文件或文件夹 */
59
typedef void (*DO_CMD_FILE)( const char *dirname, const char *filename, int flag );
60
61
62
/**//*
63
文件遍历,独立于对文件的处理方式,由参数 函数指针决定对遍历到的文件如何处理,
64
flag 中标志位 FLAG_R 是否为 1 决定是否遍历子目录
65
*/
66
#define QUE_LEN (1024*32)
67
char queDirName[ QUE_LEN ][ NAME_LEN ];
68
int queHead, queTail;
69
70
void do_cmd( const char *dirname, DO_CMD_FILE do_cmd_file, int flag )
{
71
DIR *dir_ptr;
72
struct dirent *dirent_ptr;
73
struct stat info;
74
char dirName[ NAME_LEN ] = "", fullPath[ NAME_LEN ] = "", fullName[ NAME_LEN ] = "";
75
76
queHead = 0;
77
queTail = 1;
78
strcpy( queDirName[ 0 ], dirname );
79
80
while ( queHead != queTail )
{
81
strcpy( dirName, queDirName[ queHead ] );
82
strcpy( fullPath, dirName );
83
strcat( fullPath, "/" );
84
dir_ptr = opendir( dirName );
85
queHead = ( queHead + 1 ) % QUE_LEN;
86
if ( NULL == dir_ptr )
{
87
continue;
88
}
89
printf( "%-32s ---------------------\n", fullPath );
90
while ( NULL != ( dirent_ptr = readdir(dir_ptr) ) )
{
91
strcpy( fullName, fullPath );
92
strcat( fullName, dirent_ptr->d_name );
93
if ( -1 == stat( fullName, &info ) )
{
94
continue;
95
}
96
do_cmd_file( dirName, dirent_ptr->d_name, flag );
97
if ( ! S_ISDIR(info.st_mode) )
{
98
continue;
99
}
100
if ( 0 == strcmp( ".", dirent_ptr->d_name ) )
{
101
continue;
102
}
103
if ( 0 == strcmp( "..", dirent_ptr->d_name ) )
{
104
continue;
105
}
106
strcpy( queDirName[ queTail ], fullName );
107
queTail = ( queTail + 1 ) % QUE_LEN;
108
if ( queTail == queHead )
{
109
fprintf( stderr, "error : buffer is full !\n" );
110
break;
111
}
112
}
113
closedir( dir_ptr );
114
printf( "\n" );
115
if ( 0 == (flag & FLAG_R) )
{
116
break;
117
}
118
}
119
}
120
121
122
/**//* 由模式得到字符串 */
123
char* mode2str( int mode );
124
/**//* 由 uid 得到名字 */
125
char* uid2name( uid_t uid );
126
/**//* 由 gid 得到名字 */
127
char* gid2name( gid_t gid );
128
129
130
/**//* 处理遍历到的文件或文件夹,由 flag 标志位决定处理方式 */
131
void do_ls_file( const char *dirname, const char *filename, int flag )
{
132
struct stat inf;
133
char fullName[ NAME_LEN ], modstr[ 13 ];
134
if ( ('.' == filename[ 0 ]) && (0 == (FLAG_A & flag)) )
{
135
return;
136
}
137
if ( 0 == (FLAG_L & flag) )
{
138
printf( "%s\n", filename );
139
return;
140
}
141
strcpy( fullName, dirname );
142
strcat( fullName, "/" );
143
strcat( fullName, filename );
144
if ( -1 == stat( fullName, &inf ) )
{
145
return;
146
}
147
printf( "%s ", mode2str(inf.st_mode) );
148
printf( "%5d ", (int)(inf.st_nlink) );
149
printf( "%-8s ", uid2name(inf.st_uid) );
150
printf( "%-8s ", gid2name(inf.st_gid) );
151
printf( "%8ld ", (long)(inf.st_size) );
152
printf( "%.12s ", ctime(&(inf.st_mtime)) );
153
printf( "%s\n", filename );
154
}
155
156
157
void do_ls( const char *dirname, int flag )
{
158
do_cmd( dirname, do_ls_file, flag );
159
}
160
161
162
/**//* 解析命令参数,设置 flag 标志位 */
163
int main( int argc, char *argv[] )
{
164
struct option longopts[] =
{
165
{ "recursive", 0, NULL, 'r' },
166
{ NULL, 0, NULL, 0 }
167
};
168
char *shortopts = "ral";
169
170
int ac = argc, opt, i, flag = 0, cur = 1;
171
char **av = argv;
172
for ( ; ; )
{
173
opt = getopt_long( ac, av, shortopts, longopts, NULL );
174
if ( -1 == opt )
{
175
break;
176
}
177
switch ( opt )
{
178
case 'r' :
179
flag |= FLAG_R;
180
break;
181
case 'a' :
182
flag |= FLAG_A;
183
break;
184
case 'l' :
185
flag |= FLAG_L;
186
break;
187
case ':' :
188
printf( "error !\n" );
189
break;
190
case '?' :
191
printf( "\nusage:\nols\nols -lar\nols /tmp\nols /tmp /usr --recursive\n" );
192
return 0;
193
}
194
}
195
196
for ( i = 1; i < argc; ++i )
{
197
if ( '-' != argv[ i ][ 0 ] )
{
198
do_ls( argv[ i ], flag );
199
cur = 0;
200
}
201
}
202
if ( cur )
{
203
do_ls( ".", flag );
204
}
205
206
return 0;
207
}
208
209
210
char* mode2str( int mode )
{
211
static char str[ 20 ];
212
213
strcpy( str, "----------" );
214
215
if ( S_ISDIR(mode) ) str[ 0 ] = 'd';
216
if ( S_ISCHR(mode) ) str[ 0 ] = 'c';
217
if ( S_ISBLK(mode) ) str[ 0 ] = 'b';
218
219
if ( mode & S_IRUSR ) str[ 1 ] = 'r';
220
if ( mode & S_IWUSR ) str[ 2 ] = 'w';
221
if ( mode & S_IXUSR ) str[ 3 ] = 'x';
222
223
if ( mode & S_IRGRP ) str[ 4 ] = 'r';
224
if ( mode & S_IWGRP ) str[ 5 ] = 'w';
225
if ( mode & S_IXGRP ) str[ 6 ] = 'x';
226
227
if ( mode & S_IROTH ) str[ 7 ] = 'r';
228
if ( mode & S_IWOTH ) str[ 8 ] = 'w';
229
if ( mode & S_IXOTH ) str[ 9 ] = 'x';
230
231
return str;
232
}
233
234
char* uid2name( uid_t uid )
{
235
static char numstr[ 32 ];
236
struct passwd *getpwuid(), *pw_ptr;
237
238
if ( NULL == (pw_ptr = getpwuid(uid)) )
{
239
sprintf( numstr, "%d", uid );
240
return numstr;
241
}
242
return pw_ptr->pw_name;
243
}
244
245
char* gid2name( gid_t gid )
{
246
static char numstr[ 32 ];
247
struct group *getgrgid(), *grp_ptr;
248
249
if ( NULL == (grp_ptr = getgrgid(gid)) )
{
250
sprintf( numstr, "%d", gid );
251
return numstr;
252
}
253
return grp_ptr->gr_name;
254
}
255
256