14a5d661aSToomas Soome /*
24a5d661aSToomas Soome * $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $
34a5d661aSToomas Soome */
44a5d661aSToomas Soome
5*a90a1f42SToomas Soome /*
64a5d661aSToomas Soome * Copyright (c) 1993
74a5d661aSToomas Soome * The Regents of the University of California. All rights reserved.
84a5d661aSToomas Soome * Copyright (c) 1996
94a5d661aSToomas Soome * Matthias Drochner. All rights reserved.
104a5d661aSToomas Soome *
114a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without
124a5d661aSToomas Soome * modification, are permitted provided that the following conditions
134a5d661aSToomas Soome * are met:
144a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright
154a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer.
164a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
174a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the
184a5d661aSToomas Soome * documentation and/or other materials provided with the distribution.
194a5d661aSToomas Soome * 3. All advertising materials mentioning features or use of this software
204a5d661aSToomas Soome * must display the following acknowledgement:
214a5d661aSToomas Soome * This product includes software developed by the University of
224a5d661aSToomas Soome * California, Berkeley and its contributors.
234a5d661aSToomas Soome * 4. Neither the name of the University nor the names of its contributors
244a5d661aSToomas Soome * may be used to endorse or promote products derived from this software
254a5d661aSToomas Soome * without specific prior written permission.
264a5d661aSToomas Soome *
274a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
284a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
294a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
304a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
314a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
324a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
334a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
344a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
354a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
364a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
374a5d661aSToomas Soome * SUCH DAMAGE.
384a5d661aSToomas Soome */
394a5d661aSToomas Soome
404a5d661aSToomas Soome #include <sys/cdefs.h>
414a5d661aSToomas Soome
424a5d661aSToomas Soome #include <sys/param.h>
434a5d661aSToomas Soome #include <ufs/ufs/dinode.h>
444a5d661aSToomas Soome #include <ufs/ufs/dir.h>
454a5d661aSToomas Soome
464a5d661aSToomas Soome #include <stand.h>
474a5d661aSToomas Soome #include <string.h>
484a5d661aSToomas Soome
494a5d661aSToomas Soome #include "bootstrap.h"
504a5d661aSToomas Soome
514a5d661aSToomas Soome static char typestr[] = "?fc?d?b? ?l?s?w";
524a5d661aSToomas Soome
534a5d661aSToomas Soome static int ls_getdir(char **pathp);
544a5d661aSToomas Soome
554a5d661aSToomas Soome COMMAND_SET(ls, "ls", "list files", command_ls);
564a5d661aSToomas Soome
574a5d661aSToomas Soome static int
command_ls(int argc,char * argv[])584a5d661aSToomas Soome command_ls(int argc, char *argv[])
594a5d661aSToomas Soome {
604a5d661aSToomas Soome int fd;
614a5d661aSToomas Soome struct stat sb;
624a5d661aSToomas Soome struct dirent *d;
634a5d661aSToomas Soome char *buf, *path;
644a5d661aSToomas Soome char lbuf[128]; /* one line */
654a5d661aSToomas Soome int result, ch;
664a5d661aSToomas Soome int verbose;
674a5d661aSToomas Soome
684a5d661aSToomas Soome result = CMD_OK;
694a5d661aSToomas Soome fd = -1;
704a5d661aSToomas Soome verbose = 0;
714a5d661aSToomas Soome optind = 1;
724a5d661aSToomas Soome optreset = 1;
734a5d661aSToomas Soome while ((ch = getopt(argc, argv, "l")) != -1) {
744a5d661aSToomas Soome switch (ch) {
754a5d661aSToomas Soome case 'l':
764a5d661aSToomas Soome verbose = 1;
774a5d661aSToomas Soome break;
784a5d661aSToomas Soome case '?':
794a5d661aSToomas Soome default:
804a5d661aSToomas Soome /* getopt has already reported an error */
814a5d661aSToomas Soome return (CMD_OK);
824a5d661aSToomas Soome }
834a5d661aSToomas Soome }
844a5d661aSToomas Soome argv += (optind - 1);
854a5d661aSToomas Soome argc -= (optind - 1);
864a5d661aSToomas Soome
874a5d661aSToomas Soome if (argc < 2) {
884a5d661aSToomas Soome path = "";
894a5d661aSToomas Soome } else {
904a5d661aSToomas Soome path = argv[1];
914a5d661aSToomas Soome }
924a5d661aSToomas Soome
934a5d661aSToomas Soome if (stat(path, &sb) == 0 && !S_ISDIR(sb.st_mode)) {
944a5d661aSToomas Soome if (verbose) {
954a5d661aSToomas Soome printf(" %c %8d %s\n",
964a5d661aSToomas Soome typestr[sb.st_mode >> 12],
974a5d661aSToomas Soome (int)sb.st_size, path);
984a5d661aSToomas Soome } else {
994a5d661aSToomas Soome printf(" %c %s\n",
1004a5d661aSToomas Soome typestr[sb.st_mode >> 12], path);
1014a5d661aSToomas Soome }
1024a5d661aSToomas Soome return (CMD_OK);
1034a5d661aSToomas Soome }
1044a5d661aSToomas Soome
1054a5d661aSToomas Soome fd = ls_getdir(&path);
1064a5d661aSToomas Soome if (fd == -1) {
1074a5d661aSToomas Soome result = CMD_ERROR;
1084a5d661aSToomas Soome goto out;
1094a5d661aSToomas Soome }
1104a5d661aSToomas Soome pager_open();
1114a5d661aSToomas Soome pager_output(path);
1124a5d661aSToomas Soome pager_output("\n");
1134a5d661aSToomas Soome
1144a5d661aSToomas Soome while ((d = readdirfd(fd)) != NULL) {
1154a5d661aSToomas Soome if (strcmp(d->d_name, ".") && strcmp(d->d_name, "..")) {
1164a5d661aSToomas Soome if (d->d_type == 0 || verbose) {
1174a5d661aSToomas Soome /* stat the file, if possible */
1184a5d661aSToomas Soome sb.st_size = 0;
1194a5d661aSToomas Soome sb.st_mode = 0;
1204a5d661aSToomas Soome buf = malloc(strlen(path) + strlen(d->d_name) + 2);
121*a90a1f42SToomas Soome if (buf != NULL) {
1224a5d661aSToomas Soome sprintf(buf, "%s/%s", path, d->d_name);
1234a5d661aSToomas Soome /* ignore return, could be symlink, etc. */
124*a90a1f42SToomas Soome if (stat(buf, &sb)) {
1254a5d661aSToomas Soome sb.st_size = 0;
126*a90a1f42SToomas Soome sb.st_mode = 0;
127*a90a1f42SToomas Soome }
1284a5d661aSToomas Soome free(buf);
1294a5d661aSToomas Soome }
130*a90a1f42SToomas Soome }
1314a5d661aSToomas Soome if (verbose) {
132*a90a1f42SToomas Soome snprintf(lbuf, sizeof (lbuf), " %c %8d %s\n",
1334a5d661aSToomas Soome typestr[d->d_type? d->d_type:sb.st_mode >> 12],
1344a5d661aSToomas Soome (int)sb.st_size, d->d_name);
1354a5d661aSToomas Soome } else {
136*a90a1f42SToomas Soome snprintf(lbuf, sizeof (lbuf), " %c %s\n",
1374a5d661aSToomas Soome typestr[d->d_type? d->d_type:sb.st_mode >> 12], d->d_name);
1384a5d661aSToomas Soome }
1394a5d661aSToomas Soome if (pager_output(lbuf))
1404a5d661aSToomas Soome goto out;
1414a5d661aSToomas Soome }
1424a5d661aSToomas Soome }
1434a5d661aSToomas Soome out:
1444a5d661aSToomas Soome pager_close();
1454a5d661aSToomas Soome if (fd != -1)
1464a5d661aSToomas Soome close(fd);
147*a90a1f42SToomas Soome free(path); /* ls_getdir() did allocate path */
1484a5d661aSToomas Soome return (result);
1494a5d661aSToomas Soome }
1504a5d661aSToomas Soome
1514a5d661aSToomas Soome /*
1524a5d661aSToomas Soome * Given (path) containing a vaguely reasonable path specification, return an fd
1534a5d661aSToomas Soome * on the directory, and an allocated copy of the path to the directory.
1544a5d661aSToomas Soome */
1554a5d661aSToomas Soome static int
ls_getdir(char ** pathp)1564a5d661aSToomas Soome ls_getdir(char **pathp)
1574a5d661aSToomas Soome {
1584a5d661aSToomas Soome struct stat sb;
1594a5d661aSToomas Soome int fd;
1604a5d661aSToomas Soome const char *cp;
1614a5d661aSToomas Soome char *path;
1624a5d661aSToomas Soome
1634a5d661aSToomas Soome fd = -1;
1644a5d661aSToomas Soome
1654a5d661aSToomas Soome /* one extra byte for a possible trailing slash required */
1664a5d661aSToomas Soome path = malloc(strlen(*pathp) + 2);
167*a90a1f42SToomas Soome if (path == NULL) {
168*a90a1f42SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
169*a90a1f42SToomas Soome "out of memory");
170*a90a1f42SToomas Soome goto out;
171*a90a1f42SToomas Soome }
172*a90a1f42SToomas Soome
1734a5d661aSToomas Soome strcpy(path, *pathp);
1744a5d661aSToomas Soome
1754a5d661aSToomas Soome /* Make sure the path is respectable to begin with */
1764a5d661aSToomas Soome if (archsw.arch_getdev(NULL, path, &cp)) {
1774a5d661aSToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
1784a5d661aSToomas Soome "bad path '%s'", path);
1794a5d661aSToomas Soome goto out;
1804a5d661aSToomas Soome }
1814a5d661aSToomas Soome
1824a5d661aSToomas Soome /* If there's no path on the device, assume '/' */
1834a5d661aSToomas Soome if (*cp == 0)
1844a5d661aSToomas Soome strcat(path, "/");
1854a5d661aSToomas Soome
1864a5d661aSToomas Soome fd = open(path, O_RDONLY);
1874a5d661aSToomas Soome if (fd < 0) {
1884a5d661aSToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
1894a5d661aSToomas Soome "open '%s' failed: %s", path, strerror(errno));
1904a5d661aSToomas Soome goto out;
1914a5d661aSToomas Soome }
1924a5d661aSToomas Soome if (fstat(fd, &sb) < 0) {
1934a5d661aSToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
1944a5d661aSToomas Soome "stat failed: %s", strerror(errno));
1954a5d661aSToomas Soome goto out;
1964a5d661aSToomas Soome }
1974a5d661aSToomas Soome if (!S_ISDIR(sb.st_mode)) {
1984a5d661aSToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
1994a5d661aSToomas Soome "%s: %s", path, strerror(ENOTDIR));
2004a5d661aSToomas Soome goto out;
2014a5d661aSToomas Soome }
2024a5d661aSToomas Soome
2034a5d661aSToomas Soome *pathp = path;
2044a5d661aSToomas Soome return (fd);
2054a5d661aSToomas Soome
2064a5d661aSToomas Soome out:
2074a5d661aSToomas Soome free(path);
2084a5d661aSToomas Soome *pathp = NULL;
2094a5d661aSToomas Soome if (fd != -1)
2104a5d661aSToomas Soome close(fd);
2114a5d661aSToomas Soome return (-1);
2124a5d661aSToomas Soome }
213