|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/usr/bin/ls/ls.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.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] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |