00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <stdio.h>
00033 #include <unistd.h>
00034 #include <string.h>
00035 #include <errno.h>
00036 #include <err.h>
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 static int aopt=0;
00050 static int dopt=0;
00051 static int lopt=0;
00052 static int Ropt=0;
00053 static int sopt=0;
00054
00055
00056 static
00057 void
00058 option(int ch)
00059 {
00060 switch (ch) {
00061 case 'a': aopt=1; break;
00062 case 'd': dopt=1; break;
00063 case 'l': lopt=1; break;
00064 case 'R': Ropt=1; break;
00065 case 's': sopt=1; break;
00066 default:
00067 errx(1, "Unknown option -%c", ch);
00068 }
00069 }
00070
00071
00072
00073
00074 static
00075 const char *
00076 basename(const char *path)
00077 {
00078 const char *s;
00079
00080 s = strrchr(path, '/');
00081 if (s) {
00082 return s+1;
00083 }
00084 return path;
00085 }
00086
00087
00088
00089
00090 static
00091 int
00092 isdir(const char *path)
00093 {
00094 struct stat buf;
00095 int fd;
00096
00097
00098 fd = open(path, O_RDONLY);
00099 if (fd<0) {
00100 err(1, "%s", path);
00101 }
00102 if (fstat(fd, &buf)<0) {
00103 err(1, "%s: fstat", path);
00104 }
00105 close(fd);
00106
00107 return S_ISDIR(buf.st_mode);
00108 }
00109
00110
00111
00112
00113
00114 static
00115 void
00116 printheader(const char *file)
00117 {
00118
00119 static int first=1;
00120 if (first) {
00121 first = 0;
00122 }
00123 else {
00124 printf("\n");
00125 }
00126 printf("%s:\n", file);
00127 }
00128
00129
00130
00131
00132
00133 static
00134 void
00135 print(const char *path)
00136 {
00137 struct stat statbuf;
00138 const char *file;
00139 int typech;
00140
00141 if (lopt || sopt) {
00142 int fd;
00143
00144 fd = open(path, O_RDONLY);
00145 if (fd<0) {
00146 err(1, "%s", path);
00147 }
00148 if (fstat(fd, &statbuf)<0) {
00149 err(1, "%s: fstat", path);
00150 }
00151 close(fd);
00152 }
00153
00154 file = basename(path);
00155
00156 if (sopt) {
00157 printf("%3d ", statbuf.st_blocks);
00158 }
00159
00160 if (lopt) {
00161 if (S_ISREG(statbuf.st_mode)) {
00162 typech = '-';
00163 }
00164 else if (S_ISDIR(statbuf.st_mode)) {
00165 typech = 'd';
00166 }
00167 else if (S_ISLNK(statbuf.st_mode)) {
00168 typech = 'l';
00169 }
00170 else if (S_ISCHR(statbuf.st_mode)) {
00171 typech = 'c';
00172 }
00173 else if (S_ISBLK(statbuf.st_mode)) {
00174 typech = 'b';
00175 }
00176 else {
00177 typech = '?';
00178 }
00179
00180 printf("%crwx------ %2d root %-8llu",
00181 typech,
00182 statbuf.st_nlink,
00183 statbuf.st_size);
00184 }
00185 printf("%s\n", file);
00186 }
00187
00188
00189
00190
00191 static
00192 void
00193 listdir(const char *path, int showheader)
00194 {
00195 int fd;
00196 char buf[1024];
00197 char newpath[1024];
00198 int len;
00199
00200 if (showheader) {
00201 printheader(path);
00202 }
00203
00204
00205
00206
00207 fd = open(path, O_RDONLY);
00208 if (fd<0) {
00209 err(1, "%s", path);
00210 }
00211
00212
00213
00214
00215 while ((len = getdirentry(fd, buf, sizeof(buf)-1)) > 0) {
00216 buf[len] = 0;
00217
00218
00219 snprintf(newpath, sizeof(newpath), "%s/%s", path, buf);
00220
00221 if (aopt || buf[0]!='.') {
00222
00223 print(newpath);
00224 }
00225 }
00226 if (len<0) {
00227 err(1, "%s: getdirentry", path);
00228 }
00229
00230
00231 close(fd);
00232 }
00233
00234 static
00235 void
00236 recursedir(const char *path)
00237 {
00238 int fd;
00239 char buf[1024];
00240 char newpath[1024];
00241 int len;
00242
00243
00244
00245
00246 fd = open(path, O_RDONLY);
00247 if (fd<0) {
00248 err(1, "%s", path);
00249 }
00250
00251
00252
00253
00254 while ((len = getdirentry(fd, buf, sizeof(buf)-1)) > 0) {
00255 buf[len] = 0;
00256
00257
00258 snprintf(newpath, sizeof(newpath), "%s/%s", path, buf);
00259
00260 if (!aopt && buf[0]=='.') {
00261
00262 continue;
00263 }
00264
00265 if (!strcmp(buf, ".") || !strcmp(buf, "..")) {
00266
00267 continue;
00268 }
00269
00270 if (!isdir(newpath)) {
00271 continue;
00272 }
00273
00274 listdir(newpath, 1 );
00275 if (Ropt) {
00276 recursedir(newpath);
00277 }
00278 }
00279 if (len<0) {
00280 err(1, "%s", path);
00281 }
00282
00283 close(fd);
00284 }
00285
00286 static
00287 void
00288 listitem(const char *path, int showheader)
00289 {
00290 if (!dopt && isdir(path)) {
00291 listdir(path, showheader || Ropt);
00292 if (Ropt) {
00293 recursedir(path);
00294 }
00295 }
00296 else {
00297 print(path);
00298 }
00299 }
00300
00301 int
00302 main(int argc, char *argv[])
00303 {
00304 int i,j, items=0;
00305
00306
00307
00308
00309 for (i=1; i<argc; i++) {
00310 if (argv[i][0]!='-') {
00311 items++;
00312 }
00313 }
00314
00315
00316
00317
00318 for (i=1; i<argc; i++) {
00319 if (argv[i][0]=='-') {
00320
00321
00322
00323
00324 for (j=1; argv[i][j]; j++) {
00325 option(argv[i][j]);
00326 }
00327 }
00328 else {
00329
00330
00331
00332 listitem(argv[i], items>1);
00333 }
00334 }
00335
00336
00337
00338
00339
00340 if (items==0) {
00341 listitem(".", 0);
00342 }
00343
00344 return 0;
00345 }