xref: /titanic_53/usr/src/boot/sys/boot/common/ls.c (revision a90a1f427a651b4eac14fbb8f9aeecaa666a6e1d)
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