Annotation of prex/usr/bin/ls/ls.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * Copyright (c) 2005-2006, 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 <err.h>
! 34: #include <string.h>
! 35: #include <stdlib.h>
! 36: #include <dirent.h>
! 37: #include <limits.h>
! 38: #include <stdio.h>
! 39: #include <errno.h>
! 40:
! 41: #ifdef CMDBOX
! 42: #define main(argc, argv) ls_main(argc, argv)
! 43: #endif
! 44:
! 45: static void print_entry(char *name, struct stat *sp);
! 46: static int do_ls(char *path);
! 47:
! 48: /* Flags */
! 49: #define LSF_DOT 0x01 /* List files begining with . */
! 50: #define LSF_LONG 0x02 /* Long format */
! 51: #define LSF_SINGLE 0x04 /* Single column */
! 52: #define LSF_TYPE 0x08 /* Add /(dir) and @(symlink) with file name */
! 53: #define LSF_ALL 0x10 /* List hidden files */
! 54:
! 55: #define LSF_RECURSIVE 0x20 /* List Subdirectory */
! 56: #define LSF_TIMESORT 0x40 /* Sort by time */
! 57:
! 58: static unsigned int ls_flags;
! 59:
! 60: int
! 61: main(int argc, char *argv[])
! 62: {
! 63: int ch, rc;
! 64:
! 65: ls_flags = 0;
! 66:
! 67: while ((ch = getopt(argc, argv, "1ClFaA")) != -1) {
! 68: switch(ch) {
! 69: case '1':
! 70: ls_flags |= LSF_SINGLE;
! 71: ls_flags &= ~LSF_LONG;
! 72: break;
! 73: case 'C':
! 74: ls_flags &= ~LSF_SINGLE;
! 75: ls_flags &= ~LSF_LONG;
! 76: break;
! 77: case 'l':
! 78: ls_flags |= LSF_LONG;
! 79: ls_flags &= ~LSF_SINGLE;
! 80: break;
! 81: case 'F':
! 82: ls_flags |= LSF_TYPE;
! 83: break;
! 84: case 'a':
! 85: ls_flags |= LSF_DOT;
! 86: /* FALLTHROUGH */
! 87: case 'A':
! 88: ls_flags |= LSF_ALL;
! 89: break;
! 90: default:
! 91: case '?':
! 92: fprintf(stderr, "usage: ls [-1CFAal] [file ...]\n");
! 93: exit(1);
! 94: }
! 95: }
! 96: argc -= optind;
! 97: argv += optind;
! 98:
! 99: if (argc == 0)
! 100: rc = do_ls(".");
! 101: else {
! 102: do {
! 103: rc = do_ls(*argv);
! 104: ++argv;
! 105: } while (*argv);
! 106: }
! 107: if (rc)
! 108: err(1, NULL);
! 109: return 0;
! 110: }
! 111:
! 112: static void
! 113: print_entry(char *name, struct stat *sp)
! 114: {
! 115: int color;
! 116: int dot = 0;
! 117:
! 118: if (name[0] == '.') {
! 119: if ((ls_flags & LSF_DOT) == 0)
! 120: return;
! 121: dot = 1;
! 122: }
! 123:
! 124: /* set color */
! 125: color = 0;
! 126: if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
! 127: color = 35; /* magenta */
! 128: else if (S_ISDIR(sp->st_mode))
! 129: color = 36; /* cyan */
! 130: else if (S_ISFIFO(sp->st_mode))
! 131: color = 34;
! 132: else if (S_ISLNK(sp->st_mode))
! 133: color = 33; /* yellow */
! 134:
! 135: if (ls_flags & LSF_LONG) {
! 136: /* print mode */
! 137: if (S_ISDIR(sp->st_mode))
! 138: putchar('d');
! 139: else if (S_ISLNK(sp->st_mode))
! 140: putchar('@');
! 141: else if (S_ISFIFO(sp->st_mode))
! 142: putchar('|');
! 143: else
! 144: putchar('-');
! 145:
! 146: printf("rw");
! 147: if (sp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
! 148: putchar('x');
! 149: else
! 150: putchar('-');
! 151: printf("------");
! 152:
! 153: /* print link */
! 154: printf(" 1 ");
! 155:
! 156: /* print owner */
! 157: printf("prex ");
! 158:
! 159: /* print date/time */
! 160: printf("%s 12:00 ", __DATE__);
! 161:
! 162: /* print size */
! 163: printf("%7d ", (int)sp->st_size);
! 164: }
! 165:
! 166: /* print name */
! 167: printf("\033[%dm", color);
! 168: printf("%s", name);
! 169:
! 170: /* print type */
! 171: if (!dot && (ls_flags & LSF_TYPE)) {
! 172: switch (sp->st_mode & S_IFMT) {
! 173: case S_IFDIR:
! 174: putchar('/');
! 175: break;
! 176: case S_IFIFO:
! 177: putchar('|');
! 178: break;
! 179: case S_IFLNK:
! 180: putchar('@');
! 181: break;
! 182: case S_IFSOCK:
! 183: putchar('=');
! 184: break;
! 185: case S_IFWHT:
! 186: putchar('%');
! 187: break;
! 188: }
! 189: if (sp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
! 190: putchar('*');
! 191: }
! 192: printf("\033[0m");
! 193: if (ls_flags & LSF_LONG || ls_flags & LSF_SINGLE) {
! 194: putchar('\n');
! 195: } else {
! 196: putchar(' ');
! 197: }
! 198: }
! 199:
! 200: static int
! 201: do_ls(char *path)
! 202: {
! 203: struct stat st;
! 204: int nr_file = 0;
! 205: char buf[PATH_MAX];
! 206: DIR *dir;
! 207: struct dirent *entry;
! 208:
! 209: if (stat(path, &st) == -1)
! 210: return ENOTDIR;
! 211:
! 212: if (S_ISDIR(st.st_mode)) {
! 213:
! 214: dir = opendir(path);
! 215: if (dir == NULL)
! 216: return ENOTDIR;
! 217:
! 218: for (;;) {
! 219: entry = readdir(dir);
! 220: if (entry == NULL)
! 221: break;
! 222: buf[0] = 0;
! 223: strlcpy(buf, path, sizeof(buf));
! 224: buf[sizeof(buf) - 1] = '\0';
! 225: if (!strcmp(entry->d_name, "."))
! 226: ; /* Do nothing */
! 227: else if (!strcmp(entry->d_name, ".."))
! 228: ; /* Do nothing */
! 229: else {
! 230: strlcat(buf, "/", sizeof(buf));
! 231: strlcat(buf, entry->d_name, sizeof(buf));
! 232: }
! 233: if (stat(buf, &st) == -1)
! 234: break;
! 235: print_entry(entry->d_name, &st);
! 236: nr_file++;
! 237: }
! 238: closedir(dir);
! 239: if (ls_flags & LSF_LONG)
! 240: printf("total %d\n", nr_file);
! 241: else
! 242: putchar('\n');
! 243: } else {
! 244: print_entry(path, &st);
! 245: putchar('\n');
! 246: }
! 247: return 0;
! 248: }
CVSweb