ls.c revision 39660
1/* 2 * $Id: ls.c,v 1.2 1998/09/03 02:10:07 msmith Exp $ 3 * From: $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $ 4 */ 5 6/* 7 * Copyright (c) 1993 8 * The Regents of the University of California. All rights reserved. 9 * Copyright (c) 1996 10 * Matthias Drochner. All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41 42#include <sys/param.h> 43#include <ufs/ufs/dinode.h> 44#include <ufs/ufs/dir.h> 45 46#include <stand.h> 47 48#include "bootstrap.h" 49 50static char typestr[] = "?fc?d?b? ?l?s?w"; 51 52COMMAND_SET(ls, "ls", "list files", command_ls); 53 54static int 55command_ls(int argc, char *argv[]) 56{ 57 int fd; 58 struct stat sb; 59 size_t size; 60 static char dirbuf[DIRBLKSIZ]; 61 static char buf[128]; /* must be long enough for full pathname */ 62 char *path; 63 int result, ch; 64#ifdef VERBOSE_LS 65 int verbose; 66 67 verbose = 0; 68 optind = 1; 69 while ((ch = getopt(argc, argv, "l")) != -1) { 70 switch(ch) { 71 case 'l': 72 verbose = 1; 73 break; 74 case '?': 75 default: 76 /* getopt has already reported an error */ 77 return(CMD_OK); 78 } 79 } 80 argv += (optind - 1); 81 argc -= (optind - 1); 82#endif 83 84 if (argc < 2) { 85 path = "/"; 86 } else { 87 path = argv[1]; 88 } 89 90 pager_open(); 91 pager_output(path); 92 pager_output("\n"); 93 94 fd = open(path, O_RDONLY); 95 if (fd < 0) { 96 sprintf(command_errbuf, "open '%s' failed: %s", path, strerror(errno)); 97 return(CMD_ERROR); 98 } 99 result = CMD_OK; 100 if (fstat(fd, &sb) < 0) { 101 sprintf(command_errbuf, "stat failed: %s", strerror(errno)); 102 result = CMD_ERROR; 103 goto out; 104 } 105 if (!S_ISDIR(sb.st_mode)) { 106 sprintf(command_errbuf, "%s: %s", path, strerror(ENOTDIR)); 107 result = CMD_ERROR; 108 goto out; 109 } 110#ifdef VERBOSE_LS 111 /* fixup path for stat()ing files */ 112 if (!strcmp(path, "/")) 113 path = ""; 114#endif 115 116 while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) { 117 struct direct *dp, *edp; 118 119 dp = (struct direct *) dirbuf; 120 edp = (struct direct *) (dirbuf + size); 121 122 while (dp < edp) { 123 if (dp->d_ino != (ino_t) 0) { 124 125 if ((dp->d_namlen > MAXNAMLEN + 1) || (dp->d_type > sizeof(typestr))) { 126 /* 127 * This does not handle "old" 128 * filesystems properly. On little 129 * endian machines, we get a bogus 130 * type name if the namlen matches a 131 * valid type identifier. We could 132 * check if we read namlen "0" and 133 * handle this case specially, if 134 * there were a pressing need... 135 */ 136 command_errmsg = "bad dir entry"; 137 result = CMD_ERROR; 138 goto out; 139 } 140 141 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) { 142#ifdef VERBOSE_LS /* too much UFS activity blows the heap out */ 143 if (verbose) { 144 /* stat the file, if possible */ 145 sb.st_size = 0; 146 sprintf(buf, "%s/%s", path, dp->d_name); 147 /* ignore return */ 148 if (stat(buf, &sb)) { 149 printf("stat(%s) failed: %s\n", buf, strerror(errno)); 150 sb.st_size = -1; 151 } 152 sprintf(buf, " %c %8d %s\n", typestr[dp->d_type], (int)sb.st_size, dp->d_name); 153#endif 154 } else 155 sprintf(buf, " %c %s\n", typestr[dp->d_type], dp->d_name); 156 if (pager_output(buf)) 157 goto out; 158 } 159 } 160 dp = (struct direct *) ((char *) dp + dp->d_reclen); 161 } 162 } 163 out: 164 pager_close(); 165 close(fd); 166 return(result); 167} 168