coreBugZJ

此 blog 已弃。

自己写的 LS 命令

        支持 -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
 28fullname        /home/dir/name.c
 29dirname         /home/dir
 30fullpath        /home/dir/
 31filename        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        /* 定义函数类型,独立于文件遍历方式,处理被遍历到的文件或文件夹 */
 59typedef  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)
 67char queDirName[ QUE_LEN ][ NAME_LEN ];
 68int  queHead, queTail;
 69
 70void 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        /* 由模式得到字符串 */
123char* mode2str( int mode );
124        /* 由 uid 得到名字 */
125char* uid2name( uid_t uid );
126        /* 由 gid 得到名字 */
127char* gid2name( gid_t gid );
128
129
130        /* 处理遍历到的文件或文件夹,由 flag 标志位决定处理方式 */
131void 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
157void do_ls( const char *dirname, int flag ) {
158        do_cmd( dirname, do_ls_file, flag );
159}

160
161
162        /* 解析命令参数,设置 flag 标志位 */
163int 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
210char* 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
234char* 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
245char* 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


posted on 2011-11-22 21:13 coreBugZJ 阅读(678) 评论(0)  编辑 收藏 引用 所属分类: LinuxOperatingSystem课内作业


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理