Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/bin/ls/ls.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main
  2. printtype
  3. printmode
  4. printentry
  5. do_ls

   1 /*
   2  * Copyright (c) 2005-2009, Kohsuke Ohtani
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the author nor the names of any co-contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 #include <sys/stat.h>
  31 
  32 #include <unistd.h>
  33 #include <termios.h>
  34 #include <err.h>
  35 #include <string.h>
  36 #include <stdlib.h>
  37 #include <dirent.h>
  38 #include <limits.h>
  39 #include <stdio.h>
  40 #include <errno.h>
  41 
  42 #ifdef CMDBOX
  43 #define main(argc, argv)        ls_main(argc, argv)
  44 #endif
  45 
  46 static void printentry(char *name, struct stat *sp);
  47 static int do_ls(char *path);
  48 
  49 /* Flags */
  50 #define LSF_DOT         0x01    /* List files begining with . */
  51 #define LSF_LONG        0x02    /* Long format */
  52 #define LSF_SINGLE      0x04    /* Single column */
  53 #define LSF_TYPE        0x08    /* Add /(dir) and @(symlink) with file name */
  54 #define LSF_ALL         0x10    /* List hidden files */
  55 
  56 #define LSF_RECURSIVE   0x20    /* List Subdirectory */
  57 #define LSF_TIMESORT    0x40    /* Sort by time */
  58 
  59 #define DEFAULT_WIDTH   80
  60 
  61 static unsigned int ls_flags;
  62 static int termwidth;
  63 static int cols;
  64 
  65 int
  66 main(int argc, char *argv[])
  67 {
  68         struct winsize ws;
  69         int ch, rc;
  70 
  71         ls_flags = 0;
  72 
  73         while ((ch = getopt(argc, argv, "1ClFaA")) != -1) {
  74                 switch(ch) {
  75                 case '1':
  76                         ls_flags |= LSF_SINGLE;
  77                         ls_flags &= ~LSF_LONG;
  78                         break;
  79                 case 'C':
  80                         ls_flags &= ~LSF_SINGLE;
  81                         ls_flags &= ~LSF_LONG;
  82                         break;
  83                 case 'l':
  84                         ls_flags |= LSF_LONG;
  85                         ls_flags &= ~LSF_SINGLE;
  86                         break;
  87                 case 'F':
  88                         ls_flags |= LSF_TYPE;
  89                         break;
  90                 case 'a':
  91                         ls_flags |= LSF_DOT;
  92                         /* FALLTHROUGH */
  93                 case 'A':
  94                         ls_flags |= LSF_ALL;
  95                         break;
  96                 default:
  97                 case '?':
  98                         fprintf(stderr, "usage: ls [-1CFAal] [file ...]\n");
  99                         exit(1);
 100                 }
 101         }
 102         argc -= optind;
 103         argv += optind;
 104 
 105         if (isatty(STDOUT_FILENO)) {
 106                 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 &&
 107                     ws.ws_col != 0) {
 108                         termwidth = ws.ws_col;
 109                 } else {
 110                         termwidth = DEFAULT_WIDTH;
 111                 }
 112         }
 113 
 114         if (argc == 0)
 115                 rc = do_ls(".");
 116         else {
 117                 do {
 118                         rc = do_ls(*argv);
 119                         ++argv;
 120                 } while (*argv);
 121         }
 122         if (rc)
 123                 err(1, NULL);
 124         return 0;
 125 }
 126 
 127 static void
 128 printtype(u_int mode)
 129 {
 130         char type;
 131 
 132         switch (mode & S_IFMT) {
 133         case S_IFIFO:
 134                 type = 'p';
 135                 break;
 136         case S_IFCHR:
 137                 type = 'c';
 138                         break;
 139         case S_IFDIR:
 140                 type = 'd';
 141                 break;
 142         case S_IFBLK:
 143                 type = 'b';
 144                 break;
 145         case S_IFLNK:
 146                 type = 'l';
 147                 break;
 148         case S_IFSOCK:
 149                 type = 's';
 150                 break;
 151         case S_IFREG:
 152         default:
 153                 type = '-';
 154                 break;
 155         }
 156         putchar(type);
 157 }
 158 
 159 /* We don't use strmode() to save code. */
 160 static void
 161 printmode(u_int mode)
 162 {
 163 
 164         if (mode & S_IRUSR)
 165                 putchar('r');
 166         else
 167                 putchar('-');
 168         if (mode & S_IWUSR)
 169                 putchar('w');
 170         else
 171                 putchar('-');
 172         if (mode & S_IXUSR)
 173                 putchar('x');
 174         else
 175                 putchar('-');
 176 }
 177 
 178 static void
 179 printentry(char *name, struct stat *sp)
 180 {
 181         int color;
 182         int dot = 0;
 183         int len;
 184 
 185         if (name[0] == '.') {
 186                 if ((ls_flags & LSF_DOT) == 0)
 187                         return;
 188                 dot = 1;
 189         }
 190 
 191         /* set color */
 192         color = 0;
 193         if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
 194                 color = 35;  /* magenta */
 195         else if (S_ISDIR(sp->st_mode))
 196                 color = 36;  /* cyan */
 197         else if (S_ISFIFO(sp->st_mode))
 198                 color = 34;
 199         else if (S_ISLNK(sp->st_mode))
 200                 color = 33;  /* yellow */
 201 
 202         if (ls_flags & LSF_LONG) {
 203                 printtype(sp->st_mode);
 204                 printmode(sp->st_mode);
 205 
 206                 printf("------");
 207 
 208                 /* print link */
 209                 printf("  1 ");
 210 
 211                 /* print owner */
 212                 printf("prex   ");
 213 
 214                 /* print date/time */
 215                 printf("%s 12:00 ", __DATE__);
 216 
 217                 /* print size */
 218                 printf("%7d ", (int)sp->st_size);
 219         }
 220 
 221         /* print name */
 222         printf("\033[%dm", color);
 223         printf("%s", name);
 224 
 225         /* print type */
 226         if (!dot && (ls_flags & LSF_TYPE)) {
 227                 printtype(sp->st_mode);
 228                 if (sp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
 229                         putchar('*');
 230         }
 231         printf("\033[0m");
 232         if (ls_flags & LSF_LONG || ls_flags & LSF_SINGLE) {
 233                 putchar('\n');
 234         } else {
 235                 len = strlen(name);
 236                 cols += len;
 237                 if (cols > termwidth / 2 + 8) {
 238                         printf("\n");
 239                         cols = 0;
 240                 } else {
 241                         if (len > 8) {
 242                                 putchar(' ');
 243                                 cols++;
 244                         } else {
 245                                 for (; len <= 9; len++) {
 246                                         putchar(' ');
 247                                         cols++;
 248                                 }
 249                         }
 250                 }
 251         }
 252 }
 253 
 254 static int
 255 do_ls(char *path)
 256 {
 257         struct stat st;
 258         int nr_file = 0;
 259         char buf[PATH_MAX];
 260         DIR *dir;
 261         struct dirent *entry;
 262 
 263         if (stat(path, &st) == -1)
 264                 return ENOTDIR;
 265 
 266         if (S_ISDIR(st.st_mode)) {
 267 
 268                 dir = opendir(path);
 269                 if (dir == NULL)
 270                         return ENOTDIR;
 271 
 272                 cols = 0;
 273                 for (;;) {
 274 
 275                         entry = readdir(dir);
 276                         if (entry == NULL)
 277                                 break;
 278 
 279                         buf[0] = 0;
 280                         strlcpy(buf, path, sizeof(buf));
 281                         buf[sizeof(buf) - 1] = '\0';
 282                         if (!strcmp(entry->d_name, "."))
 283                                 ;       /* Do nothing */
 284                         else if (!strcmp(entry->d_name, ".."))
 285                                 ;       /* Do nothing */
 286                         else {
 287                                 strlcat(buf, "/", sizeof(buf));
 288                                 strlcat(buf, entry->d_name, sizeof(buf));
 289                         }
 290                         if (stat(buf, &st) == -1 && errno != EACCES)
 291                                 break;
 292                         printentry(entry->d_name, &st);
 293                         nr_file++;
 294                 }
 295                 closedir(dir);
 296                 if (ls_flags & LSF_LONG)
 297                         printf("total %d\n", nr_file);
 298                 else
 299                         putchar('\n');
 300         } else {
 301 
 302                 printentry(path, &st);
 303                 putchar('\n');
 304         }
 305         return 0;
 306 }

/* [<][>][^][v][top][bottom][index][help] */