1*0a6a1f1dSLionel Sambuc /* $NetBSD: ls.c,v 1.5 2014/03/20 03:13:18 christos Exp $ */
258a2b000SEvgeniy Ivanov
358a2b000SEvgeniy Ivanov /*-
458a2b000SEvgeniy Ivanov * Copyright (c) 2011
558a2b000SEvgeniy Ivanov * The NetBSD Foundation, Inc. All rights reserved.
658a2b000SEvgeniy Ivanov *
758a2b000SEvgeniy Ivanov * This code is derived from software contributed to The NetBSD Foundation
858a2b000SEvgeniy Ivanov * by Martin Husemann.
958a2b000SEvgeniy Ivanov *
1058a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without
1158a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions
1258a2b000SEvgeniy Ivanov * are met:
1358a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright
1458a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer.
1558a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright
1658a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer in the
1758a2b000SEvgeniy Ivanov * documentation and/or other materials provided with the distribution.
1858a2b000SEvgeniy Ivanov *
1958a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2058a2b000SEvgeniy Ivanov * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2158a2b000SEvgeniy Ivanov * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2258a2b000SEvgeniy Ivanov * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2358a2b000SEvgeniy Ivanov * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2458a2b000SEvgeniy Ivanov * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2558a2b000SEvgeniy Ivanov * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2658a2b000SEvgeniy Ivanov * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2758a2b000SEvgeniy Ivanov * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2858a2b000SEvgeniy Ivanov * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2958a2b000SEvgeniy Ivanov * POSSIBILITY OF SUCH DAMAGE.
3058a2b000SEvgeniy Ivanov */
3158a2b000SEvgeniy Ivanov
3258a2b000SEvgeniy Ivanov /*
3358a2b000SEvgeniy Ivanov * Copyright (c) 1993
3458a2b000SEvgeniy Ivanov * The Regents of the University of California. All rights reserved.
3558a2b000SEvgeniy Ivanov *
3658a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without
3758a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions
3858a2b000SEvgeniy Ivanov * are met:
3958a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright
4058a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer.
4158a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright
4258a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer in the
4358a2b000SEvgeniy Ivanov * documentation and/or other materials provided with the distribution.
4458a2b000SEvgeniy Ivanov * 3. Neither the name of the University nor the names of its contributors
4558a2b000SEvgeniy Ivanov * may be used to endorse or promote products derived from this software
4658a2b000SEvgeniy Ivanov * without specific prior written permission.
4758a2b000SEvgeniy Ivanov *
4858a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4958a2b000SEvgeniy Ivanov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5058a2b000SEvgeniy Ivanov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5158a2b000SEvgeniy Ivanov * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5258a2b000SEvgeniy Ivanov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5358a2b000SEvgeniy Ivanov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5458a2b000SEvgeniy Ivanov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5558a2b000SEvgeniy Ivanov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5658a2b000SEvgeniy Ivanov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5758a2b000SEvgeniy Ivanov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5858a2b000SEvgeniy Ivanov * SUCH DAMAGE.
5958a2b000SEvgeniy Ivanov */
6058a2b000SEvgeniy Ivanov
6158a2b000SEvgeniy Ivanov /*
6258a2b000SEvgeniy Ivanov * Copyright (c) 1996
6358a2b000SEvgeniy Ivanov * Matthias Drochner. All rights reserved.
6458a2b000SEvgeniy Ivanov *
6558a2b000SEvgeniy Ivanov * Redistribution and use in source and binary forms, with or without
6658a2b000SEvgeniy Ivanov * modification, are permitted provided that the following conditions
6758a2b000SEvgeniy Ivanov * are met:
6858a2b000SEvgeniy Ivanov * 1. Redistributions of source code must retain the above copyright
6958a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer.
7058a2b000SEvgeniy Ivanov * 2. Redistributions in binary form must reproduce the above copyright
7158a2b000SEvgeniy Ivanov * notice, this list of conditions and the following disclaimer in the
7258a2b000SEvgeniy Ivanov * documentation and/or other materials provided with the distribution.
7358a2b000SEvgeniy Ivanov *
7458a2b000SEvgeniy Ivanov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
7558a2b000SEvgeniy Ivanov * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7658a2b000SEvgeniy Ivanov * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
7758a2b000SEvgeniy Ivanov * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7858a2b000SEvgeniy Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7958a2b000SEvgeniy Ivanov * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
8058a2b000SEvgeniy Ivanov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
8158a2b000SEvgeniy Ivanov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8258a2b000SEvgeniy Ivanov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
8358a2b000SEvgeniy Ivanov * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8458a2b000SEvgeniy Ivanov */
8558a2b000SEvgeniy Ivanov
8658a2b000SEvgeniy Ivanov
8758a2b000SEvgeniy Ivanov #include "stand.h"
88*0a6a1f1dSLionel Sambuc #include "ls.h"
89*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
90*0a6a1f1dSLionel Sambuc #include <sys/param.h>
91*0a6a1f1dSLionel Sambuc #endif /* defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
9258a2b000SEvgeniy Ivanov #include <sys/stat.h>
9358a2b000SEvgeniy Ivanov #include <lib/libkern/libkern.h>
9458a2b000SEvgeniy Ivanov
9558a2b000SEvgeniy Ivanov void
ls(const char * path)96*0a6a1f1dSLionel Sambuc ls(const char *path)
97*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
9858a2b000SEvgeniy Ivanov {
99*0a6a1f1dSLionel Sambuc load_mods(path, NULL);
100*0a6a1f1dSLionel Sambuc }
101*0a6a1f1dSLionel Sambuc
102*0a6a1f1dSLionel Sambuc void
load_mods(const char * path,void (* funcp)(char * arg))103*0a6a1f1dSLionel Sambuc load_mods(const char *path, void (*funcp)(char* arg))
104*0a6a1f1dSLionel Sambuc {
105*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
10658a2b000SEvgeniy Ivanov int fd;
10758a2b000SEvgeniy Ivanov struct stat sb;
108*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
10984d9c625SLionel Sambuc size_t size = -1;
110*0a6a1f1dSLionel Sambuc #else
111*0a6a1f1dSLionel Sambuc size_t size;
112*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
113*0a6a1f1dSLionel Sambuc
11458a2b000SEvgeniy Ivanov const char *fname = 0;
115*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
11660223321SEvgeniy Ivanov char *p = NULL;
117*0a6a1f1dSLionel Sambuc #else
118*0a6a1f1dSLionel Sambuc char *p;
119*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
12058a2b000SEvgeniy Ivanov struct open_file *f;
12158a2b000SEvgeniy Ivanov
12258a2b000SEvgeniy Ivanov if ((fd = open(path, 0)) < 0
12358a2b000SEvgeniy Ivanov || fstat(fd, &sb) < 0
12458a2b000SEvgeniy Ivanov || (sb.st_mode & S_IFMT) != S_IFDIR) {
12558a2b000SEvgeniy Ivanov /* Path supplied isn't a directory, open parent
12658a2b000SEvgeniy Ivanov directory and list matching files. */
12758a2b000SEvgeniy Ivanov if (fd >= 0)
12858a2b000SEvgeniy Ivanov close(fd);
12958a2b000SEvgeniy Ivanov fname = strrchr(path, '/');
13058a2b000SEvgeniy Ivanov if (fname) {
13158a2b000SEvgeniy Ivanov size = fname - path;
132f119e637SEvgeniy Ivanov fname++;
13358a2b000SEvgeniy Ivanov p = alloc(size + 1);
13458a2b000SEvgeniy Ivanov if (!p)
13558a2b000SEvgeniy Ivanov goto out;
13658a2b000SEvgeniy Ivanov memcpy(p, path, size);
13758a2b000SEvgeniy Ivanov p[size] = 0;
13858a2b000SEvgeniy Ivanov fd = open(p, 0);
139*0a6a1f1dSLionel Sambuc #if defined(__minix) && !defined(LIBSA_ENABLE_LOAD_MODS_OP)
140*0a6a1f1dSLionel Sambuc dealloc(p, size + 1);
141*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && !defined(LIBSA_ENABLE_LOAD_MODS_OP) */
14258a2b000SEvgeniy Ivanov } else {
14358a2b000SEvgeniy Ivanov fd = open("", 0);
14458a2b000SEvgeniy Ivanov fname = path;
14558a2b000SEvgeniy Ivanov }
14658a2b000SEvgeniy Ivanov
14758a2b000SEvgeniy Ivanov if (fd < 0) {
14858a2b000SEvgeniy Ivanov printf("ls: %s\n", strerror(errno));
14958a2b000SEvgeniy Ivanov return;
15058a2b000SEvgeniy Ivanov }
15158a2b000SEvgeniy Ivanov if (fstat(fd, &sb) < 0) {
15258a2b000SEvgeniy Ivanov printf("stat: %s\n", strerror(errno));
15358a2b000SEvgeniy Ivanov goto out;
15458a2b000SEvgeniy Ivanov }
15558a2b000SEvgeniy Ivanov if ((sb.st_mode & S_IFMT) != S_IFDIR) {
15658a2b000SEvgeniy Ivanov printf("%s: %s\n", path, strerror(ENOTDIR));
15758a2b000SEvgeniy Ivanov goto out;
15858a2b000SEvgeniy Ivanov }
15958a2b000SEvgeniy Ivanov }
16058a2b000SEvgeniy Ivanov
16158a2b000SEvgeniy Ivanov f = &files[fd];
16258a2b000SEvgeniy Ivanov
16358a2b000SEvgeniy Ivanov #if !defined(LIBSA_NO_FD_CHECKING)
16458a2b000SEvgeniy Ivanov if ((unsigned int)fd >= SOPEN_MAX || f->f_flags == 0) {
16558a2b000SEvgeniy Ivanov errno = EBADF;
16658a2b000SEvgeniy Ivanov goto out;
16758a2b000SEvgeniy Ivanov }
16858a2b000SEvgeniy Ivanov #endif
16958a2b000SEvgeniy Ivanov
17058a2b000SEvgeniy Ivanov #if !defined(LIBSA_NO_RAW_ACCESS)
17158a2b000SEvgeniy Ivanov /* operation not defined on raw devices */
17258a2b000SEvgeniy Ivanov if (f->f_flags & F_RAW) {
17358a2b000SEvgeniy Ivanov errno = EOPNOTSUPP;
17458a2b000SEvgeniy Ivanov goto out;
17558a2b000SEvgeniy Ivanov }
17658a2b000SEvgeniy Ivanov #endif
17758a2b000SEvgeniy Ivanov
17858a2b000SEvgeniy Ivanov if (FS_LS(f->f_ops) != NULL)
179*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
180*0a6a1f1dSLionel Sambuc FS_LOAD_MODS(f->f_ops)(f, fname, funcp, p);
181*0a6a1f1dSLionel Sambuc #else
182*0a6a1f1dSLionel Sambuc FS_LS(f->f_ops)(f, fname);
183*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
18458a2b000SEvgeniy Ivanov else
18558a2b000SEvgeniy Ivanov printf("no ls support for this file system\n");
18658a2b000SEvgeniy Ivanov
18758a2b000SEvgeniy Ivanov out:
188*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
189f14fb602SLionel Sambuc /* LSC: MINIX Modification for correct glob support, beware! */
19060223321SEvgeniy Ivanov if (p != NULL)
19160223321SEvgeniy Ivanov dealloc(p, size + 1);
192*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
19358a2b000SEvgeniy Ivanov close(fd);
19458a2b000SEvgeniy Ivanov }
195*0a6a1f1dSLionel Sambuc
196*0a6a1f1dSLionel Sambuc struct lsentry {
197*0a6a1f1dSLionel Sambuc struct lsentry *e_next;
198*0a6a1f1dSLionel Sambuc uint32_t e_ino;
199*0a6a1f1dSLionel Sambuc const char *e_type;
200*0a6a1f1dSLionel Sambuc char e_name[1];
201*0a6a1f1dSLionel Sambuc };
202*0a6a1f1dSLionel Sambuc
203*0a6a1f1dSLionel Sambuc __compactcall void
lsadd(lsentry_t ** names,const char * pattern,const char * name,size_t namelen,uint32_t ino,const char * type)204*0a6a1f1dSLionel Sambuc lsadd(lsentry_t **names, const char *pattern, const char *name, size_t namelen,
205*0a6a1f1dSLionel Sambuc uint32_t ino, const char *type)
206*0a6a1f1dSLionel Sambuc {
207*0a6a1f1dSLionel Sambuc lsentry_t *n, **np;
208*0a6a1f1dSLionel Sambuc
209*0a6a1f1dSLionel Sambuc if (pattern && !fnmatch(name, pattern))
210*0a6a1f1dSLionel Sambuc return;
211*0a6a1f1dSLionel Sambuc
212*0a6a1f1dSLionel Sambuc n = alloc(sizeof *n + namelen);
213*0a6a1f1dSLionel Sambuc if (!n) {
214*0a6a1f1dSLionel Sambuc printf("%d: %.*s (%s)\n", ino, (int)namelen, name, type);
215*0a6a1f1dSLionel Sambuc return;
216*0a6a1f1dSLionel Sambuc }
217*0a6a1f1dSLionel Sambuc
218*0a6a1f1dSLionel Sambuc n->e_ino = ino;
219*0a6a1f1dSLionel Sambuc n->e_type = type;
220*0a6a1f1dSLionel Sambuc memcpy(n->e_name, name, namelen);
221*0a6a1f1dSLionel Sambuc n->e_name[namelen] = '\0';
222*0a6a1f1dSLionel Sambuc
223*0a6a1f1dSLionel Sambuc for (np = names; *np; np = &(*np)->e_next) {
224*0a6a1f1dSLionel Sambuc if (strcmp(n->e_name, (*np)->e_name) < 0)
225*0a6a1f1dSLionel Sambuc break;
226*0a6a1f1dSLionel Sambuc }
227*0a6a1f1dSLionel Sambuc n->e_next = *np;
228*0a6a1f1dSLionel Sambuc *np = n;
229*0a6a1f1dSLionel Sambuc }
230*0a6a1f1dSLionel Sambuc
231*0a6a1f1dSLionel Sambuc #if defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP)
232*0a6a1f1dSLionel Sambuc __compactcall void
lsapply(lsentry_t * names,const char * pattern,void (* funcp)(char * arg),char * path)233*0a6a1f1dSLionel Sambuc lsapply(lsentry_t * names, const char * pattern, void (* funcp)(char * arg),
234*0a6a1f1dSLionel Sambuc char * path)
235*0a6a1f1dSLionel Sambuc {
236*0a6a1f1dSLionel Sambuc if (!names) {
237*0a6a1f1dSLionel Sambuc printf("not found\n");
238*0a6a1f1dSLionel Sambuc return;
239*0a6a1f1dSLionel Sambuc }
240*0a6a1f1dSLionel Sambuc if (NULL == funcp) {
241*0a6a1f1dSLionel Sambuc printf("no callback provided\n");
242*0a6a1f1dSLionel Sambuc return;
243*0a6a1f1dSLionel Sambuc }
244*0a6a1f1dSLionel Sambuc do {
245*0a6a1f1dSLionel Sambuc lsentry_t *n = names;
246*0a6a1f1dSLionel Sambuc char namebuf[MAXPATHLEN+1];
247*0a6a1f1dSLionel Sambuc namebuf[0] = '\0';
248*0a6a1f1dSLionel Sambuc
249*0a6a1f1dSLionel Sambuc if (path != pattern) {
250*0a6a1f1dSLionel Sambuc strcpy(namebuf, path);
251*0a6a1f1dSLionel Sambuc namebuf[strlen(path)] = '/';
252*0a6a1f1dSLionel Sambuc namebuf[strlen(path) + 1] = '\0';
253*0a6a1f1dSLionel Sambuc }
254*0a6a1f1dSLionel Sambuc strcat(namebuf, n->e_name);
255*0a6a1f1dSLionel Sambuc
256*0a6a1f1dSLionel Sambuc funcp(namebuf);
257*0a6a1f1dSLionel Sambuc
258*0a6a1f1dSLionel Sambuc names = n->e_next;
259*0a6a1f1dSLionel Sambuc } while (names);
260*0a6a1f1dSLionel Sambuc }
261*0a6a1f1dSLionel Sambuc #endif /* !defined(__minix) && defined(LIBSA_ENABLE_LOAD_MODS_OP) */
262*0a6a1f1dSLionel Sambuc #if defined(__minix)
263*0a6a1f1dSLionel Sambuc __compactcall void
load_modsunsup(const char * name)264*0a6a1f1dSLionel Sambuc load_modsunsup(const char *name) {
265*0a6a1f1dSLionel Sambuc printf("The load_mods command is not currently supported for %s\n", name);
266*0a6a1f1dSLionel Sambuc }
267*0a6a1f1dSLionel Sambuc #endif /* defined(__minix) */
268*0a6a1f1dSLionel Sambuc
269*0a6a1f1dSLionel Sambuc __compactcall void
lsprint(lsentry_t * names)270*0a6a1f1dSLionel Sambuc lsprint(lsentry_t *names) {
271*0a6a1f1dSLionel Sambuc if (!names) {
272*0a6a1f1dSLionel Sambuc printf("not found\n");
273*0a6a1f1dSLionel Sambuc return;
274*0a6a1f1dSLionel Sambuc }
275*0a6a1f1dSLionel Sambuc do {
276*0a6a1f1dSLionel Sambuc lsentry_t *n = names;
277*0a6a1f1dSLionel Sambuc printf("%d: %s (%s)\n", n->e_ino, n->e_name, n->e_type);
278*0a6a1f1dSLionel Sambuc names = n->e_next;
279*0a6a1f1dSLionel Sambuc } while (names);
280*0a6a1f1dSLionel Sambuc }
281*0a6a1f1dSLionel Sambuc
282*0a6a1f1dSLionel Sambuc __compactcall void
lsfree(lsentry_t * names)283*0a6a1f1dSLionel Sambuc lsfree(lsentry_t *names) {
284*0a6a1f1dSLionel Sambuc if (!names)
285*0a6a1f1dSLionel Sambuc return;
286*0a6a1f1dSLionel Sambuc do {
287*0a6a1f1dSLionel Sambuc lsentry_t *n = names;
288*0a6a1f1dSLionel Sambuc names = n->e_next;
289*0a6a1f1dSLionel Sambuc dealloc(n, 0);
290*0a6a1f1dSLionel Sambuc } while (names);
291*0a6a1f1dSLionel Sambuc }
292*0a6a1f1dSLionel Sambuc
293*0a6a1f1dSLionel Sambuc __compactcall void
lsunsup(const char * name)294*0a6a1f1dSLionel Sambuc lsunsup(const char *name) {
295*0a6a1f1dSLionel Sambuc printf("The ls command is not currently supported for %s\n", name);
296*0a6a1f1dSLionel Sambuc }
297