1 1.1 cherry /* 2 1.4 christos * $NetBSD: ls.c,v 1.4 2014/03/25 18:35:32 christos Exp $ 3 1.1 cherry */ 4 1.1 cherry 5 1.1 cherry /*- 6 1.1 cherry * Copyright (c) 1993 7 1.1 cherry * The Regents of the University of California. All rights reserved. 8 1.1 cherry * Copyright (c) 1996 9 1.1 cherry * Matthias Drochner. All rights reserved. 10 1.1 cherry * 11 1.1 cherry * Redistribution and use in source and binary forms, with or without 12 1.1 cherry * modification, are permitted provided that the following conditions 13 1.1 cherry * are met: 14 1.1 cherry * 1. Redistributions of source code must retain the above copyright 15 1.1 cherry * notice, this list of conditions and the following disclaimer. 16 1.1 cherry * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 cherry * notice, this list of conditions and the following disclaimer in the 18 1.1 cherry * documentation and/or other materials provided with the distribution. 19 1.1 cherry * 3. All advertising materials mentioning features or use of this software 20 1.1 cherry * must display the following acknowledgement: 21 1.1 cherry * This product includes software developed by the University of 22 1.1 cherry * California, Berkeley and its contributors. 23 1.1 cherry * 4. Neither the name of the University nor the names of its contributors 24 1.1 cherry * may be used to endorse or promote products derived from this software 25 1.1 cherry * without specific prior written permission. 26 1.1 cherry * 27 1.1 cherry * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 1.1 cherry * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 1.1 cherry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 1.1 cherry * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 1.1 cherry * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 1.1 cherry * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 1.1 cherry * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 1.1 cherry * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 1.1 cherry * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 1.1 cherry * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 1.1 cherry * SUCH DAMAGE. 38 1.1 cherry */ 39 1.1 cherry 40 1.1 cherry #include <sys/cdefs.h> 41 1.2 cherry /* __FBSDID("$FreeBSD: src/sys/boot/common/ls.c,v 1.11 2003/08/25 23:30:41 obrien Exp $"); */ 42 1.2 cherry 43 1.1 cherry 44 1.1 cherry #include <sys/param.h> 45 1.1 cherry #include <ufs/ufs/dinode.h> 46 1.1 cherry #include <ufs/ufs/dir.h> 47 1.1 cherry #include <sys/dirent.h> 48 1.1 cherry 49 1.1 cherry #include <lib/libsa/stand.h> 50 1.3 kiyohara #include <lib/libsa/loadfile.h> 51 1.1 cherry 52 1.1 cherry #include "bootstrap.h" 53 1.1 cherry 54 1.1 cherry static char typestr[] = "?fc?d?b? ?l?s?w"; 55 1.1 cherry 56 1.1 cherry static int ls_getdir(char **pathp); 57 1.1 cherry 58 1.1 cherry int 59 1.1 cherry command_ls(int argc, char *argv[]) 60 1.1 cherry { 61 1.1 cherry int fd; 62 1.1 cherry struct stat sb; 63 1.1 cherry struct dirent *d; 64 1.1 cherry char *buf, *path; 65 1.1 cherry char lbuf[128]; /* one line */ 66 1.1 cherry int result, ch; 67 1.1 cherry int verbose; 68 1.1 cherry 69 1.1 cherry result = CMD_OK; 70 1.1 cherry fd = -1; 71 1.1 cherry verbose = 0; 72 1.1 cherry optind = 1; 73 1.1 cherry optreset = 1; 74 1.1 cherry while ((ch = getopt(argc, argv, "l")) != -1) { 75 1.1 cherry switch(ch) { 76 1.1 cherry case 'l': 77 1.1 cherry verbose = 1; 78 1.1 cherry break; 79 1.1 cherry case '?': 80 1.1 cherry default: 81 1.1 cherry /* getopt has already reported an error */ 82 1.1 cherry return(CMD_OK); 83 1.1 cherry } 84 1.1 cherry } 85 1.1 cherry argv += (optind - 1); 86 1.1 cherry argc -= (optind - 1); 87 1.1 cherry 88 1.1 cherry if (argc < 2) { 89 1.1 cherry path = ""; 90 1.1 cherry } else { 91 1.1 cherry path = argv[1]; 92 1.1 cherry } 93 1.1 cherry 94 1.1 cherry fd = ls_getdir(&path); 95 1.1 cherry if (fd == -1) { 96 1.1 cherry result = CMD_ERROR; 97 1.1 cherry goto out; 98 1.1 cherry } 99 1.1 cherry 100 1.1 cherry pager_open(); 101 1.1 cherry pager_output(path); 102 1.1 cherry pager_output("\n"); 103 1.1 cherry 104 1.1 cherry while ((d = readdirfd(fd)) != NULL) { 105 1.1 cherry /* if (strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) { */ 106 1.1 cherry if (verbose) { 107 1.4 christos size_t buflen; 108 1.1 cherry /* stat the file, if possible */ 109 1.1 cherry sb.st_size = 0; 110 1.4 christos buflen = strlen(path) + strlen(d->d_name) + 2; 111 1.4 christos buf = alloc(buflen); 112 1.4 christos snprintf(buf, buflen, "%s/%s", path, d->d_name); 113 1.1 cherry /* ignore return, could be symlink, etc. */ 114 1.1 cherry if (stat(buf, &sb)) 115 1.1 cherry sb.st_size = 0; 116 1.1 cherry free(buf); 117 1.4 christos snprintf(lbuf, sizeof(lbuf), " %c %8d %s\n", typestr[d->d_type], 118 1.1 cherry (int)sb.st_size, d->d_name); 119 1.1 cherry } else { 120 1.4 christos snprintf(lbuf, sizeof(lbuf), " %c %s\n", typestr[d->d_type], 121 1.4 christos d->d_name); 122 1.1 cherry } 123 1.1 cherry if (pager_output(lbuf)) 124 1.1 cherry goto out; 125 1.1 cherry /* } */ 126 1.1 cherry } 127 1.1 cherry out: 128 1.1 cherry pager_close(); 129 1.1 cherry if (fd != -1) 130 1.1 cherry close(fd); 131 1.1 cherry if (path != NULL) 132 1.1 cherry free(path); 133 1.1 cherry return(result); 134 1.1 cherry } 135 1.1 cherry 136 1.1 cherry /* 137 1.1 cherry * Given (path) containing a vaguely reasonable path specification, return an fd 138 1.1 cherry * on the directory, and an allocated copy of the path to the directory. 139 1.1 cherry */ 140 1.1 cherry static int 141 1.1 cherry ls_getdir(char **pathp) 142 1.1 cherry { 143 1.1 cherry struct stat sb; 144 1.1 cherry int fd; 145 1.1 cherry const char *cp; 146 1.1 cherry char *path, *tail; 147 1.1 cherry 148 1.1 cherry tail = NULL; 149 1.1 cherry fd = -1; 150 1.1 cherry 151 1.1 cherry /* one extra byte for a possible trailing slash required */ 152 1.1 cherry path = alloc(strlen(*pathp) + 2); 153 1.1 cherry strcpy(path, *pathp); 154 1.1 cherry 155 1.1 cherry /* Make sure the path is respectable to begin with */ 156 1.1 cherry if (archsw.arch_getdev(NULL, path, &cp)) { 157 1.4 christos command_seterr("bad path '%s'", path); 158 1.1 cherry goto out; 159 1.1 cherry } 160 1.1 cherry 161 1.1 cherry /* If there's no path on the device, assume '/' */ 162 1.1 cherry if (*cp == 0) 163 1.1 cherry strcat(path, "/"); 164 1.1 cherry fd = open(path, O_RDONLY); 165 1.1 cherry if (fd < 0) { 166 1.4 christos command_seterr("open '%s' failed: %s", path, strerror(errno)); 167 1.1 cherry goto out; 168 1.1 cherry } 169 1.1 cherry if (fstat(fd, &sb) < 0) { 170 1.4 christos command_seterr("stat failed: %s", strerror(errno)); 171 1.1 cherry goto out; 172 1.1 cherry } 173 1.1 cherry if (!S_ISDIR(sb.st_mode)) { 174 1.4 christos command_seterr("%s: %s", path, strerror(ENOTDIR)); 175 1.1 cherry goto out; 176 1.1 cherry } 177 1.1 cherry 178 1.1 cherry *pathp = path; 179 1.1 cherry return(fd); 180 1.1 cherry 181 1.1 cherry out: 182 1.1 cherry free(path); 183 1.1 cherry *pathp = NULL; 184 1.1 cherry if (fd != -1) 185 1.1 cherry close(fd); 186 1.1 cherry return(-1); 187 1.1 cherry } 188