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