自己写的 LS 命令

自己写的 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          /**/ /* 定义函数类型,独立于文件遍历方式,处理被遍历到的文件或文件夹 */
 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


你可能感兴趣的:(自己写的 LS 命令)