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