ls.c revision 38466
1/* 2 * $Id$ 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 char dirbuf[DIRBLKSIZ]; 61 char pathbuf[128]; /* XXX path length constant? */ 62 char buf[128]; /* must be long enough for dir entry! */ 63 char *path; 64 int result, ch; 65#ifdef VERBOSE_LS 66 int verbose; 67 68 verbose = 0; 69 optind = 1; 70 while ((ch = getopt(argc, argv, "l")) != -1) { 71 switch(ch) { 72 case 'l': 73 verbose = 1; 74 break; 75 case '?': 76 default: 77 /* getopt has already reported an error */ 78 return(CMD_OK); 79 } 80 } 81 argv += (optind - 1); 82 argc -= (optind - 1); 83#endif 84 85 if (argc < 2) { 86 path = "/"; 87 } else { 88 path = argv[1]; 89 } 90 91 pager_open(); 92 pager_output(path); 93 pager_output("\n"); 94 95 fd = open(path, O_RDONLY); 96 if (fd < 0) { 97 sprintf(command_errbuf, "open '%s' failed: %s", path, strerror(errno)); 98 return(CMD_ERROR); 99 } 100 result = CMD_OK; 101 if (fstat(fd, &sb) < 0) { 102 sprintf(command_errbuf, "stat failed: %s", strerror(errno)); 103 result = CMD_ERROR; 104 goto out; 105 } 106 if (!S_ISDIR(sb.st_mode)) { 107 sprintf(command_errbuf, "%s: %s", path, strerror(ENOTDIR)); 108 result = CMD_ERROR; 109 goto out; 110 } 111 while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) { 112 struct direct *dp, *edp; 113 114 dp = (struct direct *) dirbuf; 115 edp = (struct direct *) (dirbuf + size); 116 117 while (dp < edp) { 118 if (dp->d_ino != (ino_t) 0) { 119 120 if ((dp->d_namlen > MAXNAMLEN + 1) || (dp->d_type > sizeof(typestr))) { 121 /* 122 * This does not handle "old" 123 * filesystems properly. On little 124 * endian machines, we get a bogus 125 * type name if the namlen matches a 126 * valid type identifier. We could 127 * check if we read namlen "0" and 128 * handle this case specially, if 129 * there were a pressing need... 130 */ 131 command_errmsg = "bad dir entry"; 132 result = CMD_ERROR; 133 goto out; 134 } 135 136 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) { 137#ifdef VERBOSE_LS /* too much UFS activity blows the heap out */ 138 if (verbose) { 139 /* stat the file, if possible */ 140 sb.st_size = 0; 141 sprintf(buf, "%s/%s", pathbuf, dp->d_name); 142 /* ignore return */ 143 if (stat(buf, &sb)) 144 sb.st_size = -1; 145 sprintf(buf, " %c %8d %s\n", typestr[dp->d_type], (int)sb.st_size, dp->d_name); 146#endif 147 } else 148 sprintf(buf, " %c %s\n", typestr[dp->d_type], dp->d_name); 149 if (pager_output(buf)) 150 goto out; 151 } 152 } 153 dp = (struct direct *) ((char *) dp + dp->d_reclen); 154 } 155 } 156 out: 157 pager_close(); 158 close(fd); 159 return(result); 160} 161