tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Second stage bootloader (i386) hangs on ls command for ext2



Hello,

Izumi, thank you for reviewing! New patches are attached.

On Fri, Dec 16, 2011 at 7:42 PM, Izumi Tsutsui 
<tsutsui%ceres.dti.ne.jp@localhost> wrote:
> Evgeniy Ivanov wrote:
>
>> Here is a fix for the issue. Independent on what fs partition
>> contains, ufs_ls() was called. Because of ext2 and ufs similarity it
>> worked successfully in some cases.
>>
>> netbsd_boot2_ls_fix.diff
>>     Fix ls command used in second stage bootloader.
>  :
>> Could someone please review and commit it?
>
> Looks good, but one concern.
>
>>> --- a/sys/arch/i386/stand/bootxx/Makefile.bootxx
>>> +++ b/sys/arch/i386/stand/bootxx/Makefile.bootxx
>>> @@ -87,7 +87,8 @@ CPPFLAGS+= -DLIBSA_SINGLE_FILESYSTEM=xxfs \
>>>              -D"blkdevioctl(x,y,z)=EINVAL" \
>>>              -D"blkdevclose(f)=0" \
>>>              -D"devopen(f,n,fl)=(*(fl)=(void *)n,0)" \
>>> -            -DLIBSA_NO_DISKLABEL_MSGS
>>> +            -DLIBSA_NO_DISKLABEL_MSGS \
>>> +            -DLIBSA_NO_LS_OP
>  :
>
>>> --- a/sys/arch/i386/stand/libsa/nfs.c
>>> +++ b/sys/arch/i386/stand/libsa/nfs.c
>  :
>>> +__compactcall void
>>> +nfs_ls(struct open_file *f, const char *pattern)
>>> +{
>>> +#if !defined(LIBSA_NO_LS_OP)
>>> +    printf("Currently ls command is unsupported by nfs\n");
>>> +#endif
>>> +    return;
>>> +}
>
> I think it's better to use a positive LIBSA_ENABLE_LS_OP option rather
> than LIBSA_NO_LS_OP, and make whole (fs_ops)->ls op part optional because
>  - there are many primary bootloaders (bootxx_foo) which don't need
>   the ls op and have size restrictions (alpha, atari, pmax ...)
>  - there are few bootloaders which support command prompt mode where
>   the `ls' op is actually required (some ports don't have even getchar())

Done.

> We also have to check all other non-x86 bootloaders which refer ufs_ls().
> (ews4800mips, ia64, landisk, x68k, zaurus etc)

Done. I'm not able to check though, but the modification is trivial
and almost the same as for i386.



-- 
Evgeniy Ivanov
From 9925d5065fb5de1e495ff0617887ab41f2ac3d31 Mon Sep 17 00:00:00 2001
From: Evgeniy Ivanov <lolkaantimat%gmail.com@localhost>
Date: Tue, 13 Dec 2011 00:23:32 +0400
Subject: [PATCH 1/3] Fix ls command used in second stage bootloader.

Currently only ufs_ls is supported. But if ls is called on ext2
partition, it hangs bootloader, because ufs_ls() is called.
ls command should always call fs-dependent XXX_ls().

diff --git a/sys/arch/i386/stand/boot/Makefile.boot 
b/sys/arch/i386/stand/boot/Makefile.boot
index feab35f..fc7c5a8 100644
--- a/sys/arch/i386/stand/boot/Makefile.boot
+++ b/sys/arch/i386/stand/boot/Makefile.boot
@@ -76,6 +76,7 @@ CPPFLAGS+= -DPASS_MEMMAP
 CPPFLAGS+= -DEPIA_HACK
 #CPPFLAGS+= -DDEBUG_MEMSIZE
 #CPPFLAGS+= -DBOOT_MSG_COM0
+CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
 
 # The biosboot code is linked to 'virtual' address of zero and is
 # loaded at physical address 0x10000.
@@ -113,6 +114,7 @@ LIBI386= ${I386LIB}
 ### find out what to use for libsa
 SA_AS= library
 SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
+SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
 .include "${S}/lib/libsa/Makefile.inc"
 LIBSA= ${SALIB}
 
diff --git a/sys/arch/i386/stand/boot/boot2.c b/sys/arch/i386/stand/boot/boot2.c
index 587990e..dc50808 100644
--- a/sys/arch/i386/stand/boot/boot2.c
+++ b/sys/arch/i386/stand/boot/boot2.c
@@ -409,7 +409,7 @@ command_ls(char *arg)
        const char *save = default_filename;
 
        default_filename = "/";
-       ufs_ls(arg);
+       ls(arg);
        default_filename = save;
 }
 
diff --git a/sys/arch/i386/stand/dosboot/Makefile 
b/sys/arch/i386/stand/dosboot/Makefile
index 6ae3b40..165971a 100644
--- a/sys/arch/i386/stand/dosboot/Makefile
+++ b/sys/arch/i386/stand/dosboot/Makefile
@@ -17,6 +17,7 @@ SRCS= main.c devopen.c exec.c
 CPPFLAGS+= -DSLOW      # for libz
 CPPFLAGS+= -DCOMPAT_386BSD_MBRPART
 CPPFLAGS+= -DXMS
+CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
 #uncomment if there are problems with memory detection
 #CPPFLAGS+= -DCONSERVATIVE_MEMDETECT
 
@@ -30,7 +31,7 @@ SRCS+= getopt.c
 # XXX these should depend on the size of the image
 CPPFLAGS+= -DSTACK_START=0x10000
 SAMISCCPPFLAGS+= -DHEAP_START=0x20000 -DHEAP_LIMIT=0x50000
-SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_INCLUDE_NET=no
+SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_INCLUDE_NET=no SA_ENABLE_LS_OP=yes
 I386MISCMAKEFLAGS= I386_INCLUDE_DOS=yes
 
 VERSIONFILE= ${.CURDIR}/version
diff --git a/sys/arch/i386/stand/dosboot/main.c 
b/sys/arch/i386/stand/dosboot/main.c
index 87054b0..e529903 100644
--- a/sys/arch/i386/stand/dosboot/main.c
+++ b/sys/arch/i386/stand/dosboot/main.c
@@ -323,12 +323,8 @@ void
 command_ls(char *arg)
 {
        char *help = default_filename;
-       if (strcmp(current_fsmode, "ufs")) {
-               printf("UFS only\n");
-               return;
-       }
        default_filename = "/";
-       ufs_ls(arg);
+       ls(arg);
        default_filename = help;
 }
 
diff --git a/sys/arch/i386/stand/libsa/nfs.c b/sys/arch/i386/stand/libsa/nfs.c
index 18d1bd1..2cbf6ef 100644
--- a/sys/arch/i386/stand/libsa/nfs.c
+++ b/sys/arch/i386/stand/libsa/nfs.c
@@ -630,3 +630,12 @@ nfs_stat(struct open_file *f, struct stat *sb)
 
        return (0);
 }
+
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+nfs_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by nfs\n");
+       return;
+}
+#endif
diff --git a/sys/lib/libsa/Makefile b/sys/lib/libsa/Makefile
index da59909..0ec825e 100644
--- a/sys/lib/libsa/Makefile
+++ b/sys/lib/libsa/Makefile
@@ -7,6 +7,7 @@ NOPROFILE=# defined
 SA_USE_CREAD?= no              # Read compressed kernels
 SA_INCLUDE_NET?= yes           # Netboot via TFTP, NFS
 SA_USE_LOADFILE?= no           # Generic executable loading support
+SA_ENABLE_LS_OP?= no           # Filesystems ls operation
 
 #DEBUGCPPFLAGS= -DBOOTP_DEBUG -DNETIF_DEBUG -DETHER_DEBUG -DNFS_DEBUG 
-DRPC_DEBUG -DRARP_DEBUG -DARP_DEBUG -DNET_DEBUG -DDEBUG -DPARANOID
 CPPFLAGS=      -I${SADIR} ${SACPPFLAGS} ${SAMISCCPPFLAGS} \
@@ -45,6 +46,9 @@ SRCS+=        close.c lseek.c open.c read.c write.c
 CPPFLAGS+= -D__INTERNAL_LIBSA_CREAD
 SRCS+= cread.c
 .endif
+.if (${SA_ENABLE_LS_OP} == "yes")
+SRCS+= ls.c
+.endif
 
 .if (${SA_USE_LOADFILE} == "yes")
 SRCS+= loadfile.c loadfile_ecoff.c loadfile_elf32.c lookup_elf32.c \
@@ -65,7 +69,7 @@ SRCS+=        bootp.c rarp.c bootparam.c
 SRCS+= nfs.c tftp.c
 .endif
 
-SRCS+= ffsv1.c ffsv2.c ufs_ls.c
+SRCS+= ffsv1.c ffsv2.c
 SRCS+= lfsv1.c lfsv2.c
 SRCS+= cd9660.c
 SRCS+= ustarfs.c
diff --git a/sys/lib/libsa/cd9660.c b/sys/lib/libsa/cd9660.c
index 4ebb91a..bf4f30c 100644
--- a/sys/lib/libsa/cd9660.c
+++ b/sys/lib/libsa/cd9660.c
@@ -396,3 +396,12 @@ cd9660_stat(struct open_file *f, struct stat *sb)
        sb->st_size = fp->size;
        return 0;
 }
+
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+cd9660_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by cd9660\n");
+       return;
+}
+#endif
diff --git a/sys/lib/libsa/dosfs.c b/sys/lib/libsa/dosfs.c
index 2dab9be..cbdfb76 100644
--- a/sys/lib/libsa/dosfs.c
+++ b/sys/lib/libsa/dosfs.c
@@ -405,6 +405,15 @@ dosfs_stat(struct open_file *fd, struct stat *sb)
        return 0;
 }
 
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+dosfs_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by dosfs\n");
+       return;
+}
+#endif
+
 /*
  * Parse DOS boot sector
  */
diff --git a/sys/lib/libsa/ext2fs.c b/sys/lib/libsa/ext2fs.c
index 3f08190..6df0b99 100644
--- a/sys/lib/libsa/ext2fs.c
+++ b/sys/lib/libsa/ext2fs.c
@@ -803,6 +803,15 @@ ext2fs_stat(struct open_file *f, struct stat *sb)
        return 0;
 }
 
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+ext2fs_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by ext2fs\n");
+       return;
+}
+#endif
+
 /*
  * byte swap functions for big endian machines
  * (ext2fs is always little endian)
diff --git a/sys/lib/libsa/ffsv1.c b/sys/lib/libsa/ffsv1.c
index 182c997..f04c701 100644
--- a/sys/lib/libsa/ffsv1.c
+++ b/sys/lib/libsa/ffsv1.c
@@ -8,6 +8,9 @@
 #define ufs_write      ffsv1_write
 #define ufs_seek       ffsv1_seek
 #define ufs_stat       ffsv1_stat
+#if defined(LIBSA_ENABLE_LS_OP)
+#define ufs_ls         ffsv1_ls
+#endif
 
 #define ufs_dinode     ufs1_dinode
 #define indp_t         int32_t
diff --git a/sys/lib/libsa/ffsv2.c b/sys/lib/libsa/ffsv2.c
index 2f712f5..fdcc3ff 100644
--- a/sys/lib/libsa/ffsv2.c
+++ b/sys/lib/libsa/ffsv2.c
@@ -8,6 +8,9 @@
 #define ufs_write      ffsv2_write
 #define ufs_seek       ffsv2_seek
 #define ufs_stat       ffsv2_stat
+#if defined(LIBSA_ENABLE_LS_OP)
+#define ufs_ls         ffsv2_ls
+#endif
 
 #define ufs_dinode     ufs2_dinode
 #define indp_t         int64_t
diff --git a/sys/lib/libsa/lfsv1.c b/sys/lib/libsa/lfsv1.c
index 69ed855..d271aca 100644
--- a/sys/lib/libsa/lfsv1.c
+++ b/sys/lib/libsa/lfsv1.c
@@ -9,6 +9,9 @@
 #define        ufs_write               lfsv1_write
 #define        ufs_seek                lfsv1_seek
 #define        ufs_stat                lfsv1_stat
+#if defined(LIBSA_ENABLE_LS_OP)
+#define        ufs_ls                  lfsv1_ls
+#endif
 
 #define        fs_bsize                lfs_ibsize
 #define        IFILE_Vx                IFILE_V1
diff --git a/sys/lib/libsa/lfsv2.c b/sys/lib/libsa/lfsv2.c
index fe28990..a057530 100644
--- a/sys/lib/libsa/lfsv2.c
+++ b/sys/lib/libsa/lfsv2.c
@@ -9,6 +9,9 @@
 #define        ufs_write               lfsv2_write
 #define        ufs_seek                lfsv2_seek
 #define        ufs_stat                lfsv2_stat
+#if defined(LIBSA_ENABLE_LS_OP)
+#define        ufs_ls                  lfsv2_ls
+#endif
 
 #define        fs_bsize                lfs_bsize
 #define        IFILE_Vx                IFILE
diff --git a/sys/lib/libsa/ls.c b/sys/lib/libsa/ls.c
new file mode 100644
index 0000000..8481d3b
--- /dev/null
+++ b/sys/lib/libsa/ls.c
@@ -0,0 +1,158 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2011
+ *      The NetBSD Foundation, Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1996
+ *     Matthias Drochner.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "stand.h"
+#include <sys/stat.h>
+#include <lib/libkern/libkern.h>
+
+void
+ls(const char *path)
+{
+       int             fd;
+       struct stat     sb;
+       size_t          size;
+       const char      *fname = 0;
+       char            *p;
+       struct open_file *f;
+
+       if ((fd = open(path, 0)) < 0
+           || fstat(fd, &sb) < 0
+           || (sb.st_mode & S_IFMT) != S_IFDIR) {
+               /* Path supplied isn't a directory, open parent
+                  directory and list matching files. */
+               if (fd >= 0)
+                       close(fd);
+               fname = strrchr(path, '/');
+               if (fname) {
+                       size = fname - path;
+                       p = alloc(size + 1);
+                       if (!p)
+                               goto out;
+                       memcpy(p, path, size);
+                       p[size] = 0;
+                       fd = open(p, 0);
+                       dealloc(p, size + 1);
+               } else {
+                       fd = open("", 0);
+                       fname = path;
+               }
+
+               if (fd < 0) {
+                       printf("ls: %s\n", strerror(errno));
+                       return;
+               }
+               if (fstat(fd, &sb) < 0) {
+                       printf("stat: %s\n", strerror(errno));
+                       goto out;
+               }
+               if ((sb.st_mode & S_IFMT) != S_IFDIR) {
+                       printf("%s: %s\n", path, strerror(ENOTDIR));
+                       goto out;
+               }
+       }
+
+       f = &files[fd];
+
+#if !defined(LIBSA_NO_FD_CHECKING)
+       if ((unsigned int)fd >= SOPEN_MAX || f->f_flags == 0) {
+               errno = EBADF;
+               goto out;
+       }
+#endif
+
+#if !defined(LIBSA_NO_RAW_ACCESS)
+       /* operation not defined on raw devices */
+       if (f->f_flags & F_RAW) {
+               errno = EOPNOTSUPP;
+               goto out;
+       }
+#endif
+
+       FS_LS(f->f_ops)(f, fname);
+
+out:
+       close(fd);
+}
diff --git a/sys/lib/libsa/nfs.c b/sys/lib/libsa/nfs.c
index a3935ff..5f4f892 100644
--- a/sys/lib/libsa/nfs.c
+++ b/sys/lib/libsa/nfs.c
@@ -655,3 +655,12 @@ nfs_stat(struct open_file *f, struct stat *sb)
 
        return 0;
 }
+
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+nfs_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by nfs\n");
+       return;
+}
+#endif
diff --git a/sys/lib/libsa/nullfs.c b/sys/lib/libsa/nullfs.c
index bc23260..80037a8 100644
--- a/sys/lib/libsa/nullfs.c
+++ b/sys/lib/libsa/nullfs.c
@@ -113,3 +113,12 @@ null_stat(struct open_file *f, struct stat *sb)
 
        return EIO;
 }
+
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+null_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by nullfs\n");
+       return;
+}
+#endif
diff --git a/sys/lib/libsa/stand.h b/sys/lib/libsa/stand.h
index f1af4ce..9b8773e 100644
--- a/sys/lib/libsa/stand.h
+++ b/sys/lib/libsa/stand.h
@@ -87,7 +87,7 @@
 
 struct open_file;
 
-#define FS_DEF(fs) \
+#define FS_DEF_BASE(fs) \
        extern __compactcall int        __CONCAT(fs,_open)(const char *, struct 
open_file *); \
        extern __compactcall int        __CONCAT(fs,_close)(struct open_file 
*); \
        extern __compactcall int        __CONCAT(fs,_read)(struct open_file *, 
void *, \
@@ -97,6 +97,15 @@ struct open_file;
        extern __compactcall off_t      __CONCAT(fs,_seek)(struct open_file *, 
off_t, int); \
        extern __compactcall int        __CONCAT(fs,_stat)(struct open_file *, 
struct stat *)
 
+#if defined(LIBSA_ENABLE_LS_OP)
+#define FS_DEF(fs) \
+       FS_DEF_BASE(fs);\
+       extern __compactcall void       __CONCAT(fs,_ls)(struct open_file *, 
const char *)
+#else
+#define FS_DEF(fs) FS_DEF_BASE(fs)
+#endif
+
+
 /*
  * This structure is used to define file system operations in a file system
  * independent way.
@@ -112,11 +121,24 @@ struct fs_ops {
        __compactcall int       (*write)(struct open_file *, void *, size_t 
size, size_t *);
        __compactcall off_t     (*seek)(struct open_file *, off_t, int);
        __compactcall int       (*stat)(struct open_file *, struct stat *);
+#if defined(LIBSA_ENABLE_LS_OP)
+       __compactcall void      (*ls)(struct open_file *, const char *);
+#endif
 };
 
 extern struct fs_ops file_system[];
 extern int nfsys;
 
+#if defined(LIBSA_ENABLE_LS_OP)
+#define FS_OPS(fs) { \
+       __CONCAT(fs,_open), \
+       __CONCAT(fs,_close), \
+       __CONCAT(fs,_read), \
+       __CONCAT(fs,_write), \
+       __CONCAT(fs,_seek), \
+       __CONCAT(fs,_stat), \
+       __CONCAT(fs,_ls) }
+#else
 #define FS_OPS(fs) { \
        __CONCAT(fs,_open), \
        __CONCAT(fs,_close), \
@@ -124,6 +146,7 @@ extern int nfsys;
        __CONCAT(fs,_write), \
        __CONCAT(fs,_seek), \
        __CONCAT(fs,_stat) }
+#endif
 
 #define        FS_OPEN(fs)             ((fs)->open)
 #define        FS_CLOSE(fs)            ((fs)->close)
@@ -131,6 +154,9 @@ extern int nfsys;
 #define        FS_WRITE(fs)            ((fs)->write)
 #define        FS_SEEK(fs)             ((fs)->seek)
 #define        FS_STAT(fs)             ((fs)->stat)
+#if defined(LIBSA_ENABLE_LS_OP)
+#define        FS_LS(fs)               ((fs)->ls)
+#endif
 
 #else
 
@@ -140,6 +166,9 @@ extern int nfsys;
 #define        FS_WRITE(fs)            
___CONCAT(LIBSA_SINGLE_FILESYSTEM,_write)
 #define        FS_SEEK(fs)             ___CONCAT(LIBSA_SINGLE_FILESYSTEM,_seek)
 #define        FS_STAT(fs)             ___CONCAT(LIBSA_SINGLE_FILESYSTEM,_stat)
+#if defined(LIBSA_ENABLE_LS_OP)
+#define        FS_LS(fs)               ___CONCAT(LIBSA_SINGLE_FILESYSTEM,_ls)
+#endif
 
 FS_DEF(LIBSA_SINGLE_FILESYSTEM);
 
@@ -256,6 +285,9 @@ off_t       lseek(int, off_t, int);
 int    ioctl(int, u_long, char *);
 int    stat(const char *, struct stat *);
 int    fstat(int, struct stat *);
+#if defined(LIBSA_ENABLE_LS_OP)
+void   ls(const char *);
+#endif
 
 typedef int cmp_t(const void *, const void *);
 void   qsort(void *, size_t, size_t, cmp_t *);
diff --git a/sys/lib/libsa/tftp.c b/sys/lib/libsa/tftp.c
index 17bad29..43bac61 100644
--- a/sys/lib/libsa/tftp.c
+++ b/sys/lib/libsa/tftp.c
@@ -429,6 +429,15 @@ tftp_stat(struct open_file *f, struct stat *sb)
        return 0;
 }
 
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+tftp_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by tftp\n");
+       return;
+}
+#endif
+
 __compactcall off_t
 tftp_seek(struct open_file *f, off_t offset, int where)
 {
diff --git a/sys/lib/libsa/ufs.c b/sys/lib/libsa/ufs.c
index 473100d..2f6437c 100644
--- a/sys/lib/libsa/ufs.c
+++ b/sys/lib/libsa/ufs.c
@@ -179,6 +179,66 @@ static void ffs_oldfscompat(struct fs *);
 static int ffs_find_superblock(struct open_file *, struct fs *);
 #endif
 
+#if defined(LIBSA_ENABLE_LS_OP)
+
+#define NELEM(x) (sizeof (x) / sizeof(*x))
+
+typedef struct entry_t entry_t;
+struct entry_t {
+       entry_t *e_next;
+       ino32_t e_ino;
+       uint8_t e_type;
+       char    e_name[1];
+};
+
+static const char    *const typestr[] = {
+       "unknown",
+       "FIFO",
+       "CHR",
+       0,
+       "DIR",
+       0,
+       "BLK",
+       0,
+       "REG",
+       0,
+       "LNK",
+       0,
+       "SOCK",
+       0,
+       "WHT"
+};
+
+static int
+fn_match(const char *fname, const char *pattern)
+{
+       char fc, pc;
+
+       do {
+               fc = *fname++;
+               pc = *pattern++;
+               if (!fc && !pc)
+                       return 1;
+               if (pc == '?' && fc)
+                       pc = fc;
+       } while (fc == pc);
+
+       if (pc != '*')
+               return 0;
+       /*
+        * Too hard (and unnecessary really) too check for "*?name" etc....
+        * "**" will look for a '*' and "*?" a '?'
+        */
+       pc = *pattern++;
+       if (!pc)
+               return 1;
+       while ((fname = strchr(fname, pc)))
+               if (fn_match(++fname, pattern))
+                       return 1;
+       return 0;
+}
+#endif /* LIBSA_ENABLE_LS_OP */
+
 #ifdef LIBSA_LFS
 /*
  * Find an inode's block.  Look it up in the ifile.  Whee!
@@ -852,6 +912,90 @@ ufs_stat(struct open_file *f, struct stat *sb)
        return 0;
 }
 
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+ufs_ls(struct open_file *f, const char *pattern)
+{
+       struct file *fp = (struct file *)f->f_fsdata;
+       char *buf;
+       size_t buf_size;
+       entry_t *names = 0, *n, **np;
+
+       fp->f_seekp = 0;
+       while (fp->f_seekp < (off_t)fp->f_di.di_size) {
+               struct direct  *dp, *edp;
+               int rc = buf_read_file(f, &buf, &buf_size);
+               if (rc)
+                       goto out;
+               if (buf_size != DIRBLKSIZ || buf_size == 0)
+                       goto out;
+
+               dp = (struct direct *)buf;
+               edp = (struct direct *)(buf + buf_size);
+
+               for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) {
+                       const char *t;
+                       if (dp->d_ino ==  0)
+                               continue;
+
+                       if (dp->d_type >= NELEM(typestr) ||
+                           !(t = typestr[dp->d_type])) {
+                               /*
+                                * This does not handle "old"
+                                * filesystems properly. On little
+                                * endian machines, we get a bogus
+                                * type name if the namlen matches a
+                                * valid type identifier. We could
+                                * check if we read namlen "0" and
+                                * handle this case specially, if
+                                * there were a pressing need...
+                                */
+                               printf("bad dir entry\n");
+                               goto out;
+                       }
+                       if (pattern && !fn_match(dp->d_name, pattern))
+                               continue;
+                       n = alloc(sizeof *n + strlen(dp->d_name));
+                       if (!n) {
+                               printf("%d: %s (%s)\n",
+                                       dp->d_ino, dp->d_name, t);
+                               continue;
+                       }
+                       n->e_ino = dp->d_ino;
+                       n->e_type = dp->d_type;
+                       strcpy(n->e_name, dp->d_name);
+                       for (np = &names; *np; np = &(*np)->e_next) {
+                               if (strcmp(n->e_name, (*np)->e_name) < 0)
+                                       break;
+                       }
+                       n->e_next = *np;
+                       *np = n;
+               }
+               fp->f_seekp += buf_size;
+       }
+
+       if (names) {
+               entry_t *p_names = names;
+               do {
+                       n = p_names;
+                       printf("%d: %s (%s)\n",
+                               n->e_ino, n->e_name, typestr[n->e_type]);
+                       p_names = n->e_next;
+               } while (p_names);
+       } else {
+               printf("not found\n");
+       }
+out:
+       if (names) {
+               do {
+                       n = names;
+                       names = n->e_next;
+                       dealloc(n, 0);
+               } while (names);
+       }
+}
+#endif /* LIBSA_ENABLE_LS_OP */
+
 #ifdef LIBSA_FFSv1
 /*
  * Sanity checks for old file systems.
diff --git a/sys/lib/libsa/ufs.h b/sys/lib/libsa/ufs.h
index aa458bf..4340f08 100644
--- a/sys/lib/libsa/ufs.h
+++ b/sys/lib/libsa/ufs.h
@@ -34,5 +34,3 @@
 FS_DEF(ufs);
 FS_DEF(ffsv1);
 FS_DEF(ffsv2);
-
-void ufs_ls(const char *);
diff --git a/sys/lib/libsa/ufs_ls.c b/sys/lib/libsa/ufs_ls.c
deleted file mode 100644
index 55e5b78..0000000
--- a/sys/lib/libsa/ufs_ls.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*     $NetBSD: ufs_ls.c,v 1.14 2007/11/24 13:20:58 isaki Exp $         */
-
-/*
- * Copyright (c) 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Copyright (c) 1996
- *     Matthias Drochner.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <sys/param.h>
-#include <lib/libkern/libkern.h>
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-
-#include "stand.h"
-#include "ufs.h"
-
-#define NELEM(x) (sizeof (x) / sizeof(*x))
-
-
-typedef uint32_t ino32_t;
-typedef struct entry_t entry_t;
-struct entry_t {
-       entry_t *e_next;
-       ino32_t e_ino;
-       uint8_t e_type;
-       char    e_name[1];
-};
-
-static const char    *const typestr[] = {
-       "unknown",
-       "FIFO",
-       "CHR",
-       0,
-       "DIR",
-       0,
-       "BLK",
-       0,
-       "REG",
-       0,
-       "LNK",
-       0,
-       "SOCK",
-       0,
-       "WHT"
-};
-
-static int
-fn_match(const char *fname, const char *pattern)
-{
-       char fc, pc;
-
-       do {
-               fc = *fname++;
-               pc = *pattern++;
-               if (!fc && !pc)
-                       return 1;
-               if (pc == '?' && fc)
-                       pc = fc;
-       } while (fc == pc);
-
-       if (pc != '*')
-               return 0;
-       /*
-        * Too hard (and unnecessary really) too check for "*?name" etc....
-        * "**" will look for a '*' and "*?" a '?'
-        */
-       pc = *pattern++;
-       if (!pc)
-               return 1;
-       while ((fname = strchr(fname, pc)))
-               if (fn_match(++fname, pattern))
-                       return 1;
-       return 0;
-}
-
-void
-ufs_ls(const char *path)
-{
-       int             fd;
-       struct stat     sb;
-       size_t          size;
-       char            dirbuf[DIRBLKSIZ];
-       const char      *fname = 0;
-       char            *p;
-       entry_t         *names = 0, *n, **np;
-
-       if ((fd = open(path, 0)) < 0
-           || fstat(fd, &sb) < 0
-           || (sb.st_mode & IFMT) != IFDIR) {
-               /* Path supplied isn't a directory, open parent
-                  directory and list matching files. */
-               if (fd >= 0)
-                       close(fd);
-               fname = strrchr(path, '/');
-               if (fname) {
-                       size = fname - path;
-                       p = alloc(size + 1);
-                       if (!p)
-                               goto out;
-                       memcpy(p, path, size);
-                       p[size] = 0;
-                       fd = open(p, 0);
-                       dealloc(p, size + 1);
-               } else {
-                       fd = open("", 0);
-                       fname = path;
-               }
-
-               if (fd < 0) {
-                       printf("ls: %s\n", strerror(errno));
-                       return;
-               }
-               if (fstat(fd, &sb) < 0) {
-                       printf("stat: %s\n", strerror(errno));
-                       goto out;
-               }
-               if ((sb.st_mode & IFMT) != IFDIR) {
-                       printf("%s: %s\n", path, strerror(ENOTDIR));
-                       goto out;
-               }
-       }
-
-       while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) {
-               struct direct  *dp, *edp;
-
-               dp = (struct direct *)dirbuf;
-               edp = (struct direct *)(dirbuf + size);
-
-               for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) {
-                       const char *t;
-                       if (dp->d_ino ==  0)
-                               continue;
-
-                       if (dp->d_type >= NELEM(typestr) ||
-                           !(t = typestr[dp->d_type])) {
-                               /*
-                                * This does not handle "old"
-                                * filesystems properly. On little
-                                * endian machines, we get a bogus
-                                * type name if the namlen matches a
-                                * valid type identifier. We could
-                                * check if we read namlen "0" and
-                                * handle this case specially, if
-                                * there were a pressing need...
-                                */
-                               printf("bad dir entry\n");
-                               goto out;
-                       }
-                       if (fname && !fn_match(dp->d_name, fname))
-                               continue;
-                       n = alloc(sizeof *n + strlen(dp->d_name));
-                       if (!n) {
-                               printf("%d: %s (%s)\n",
-                                       dp->d_ino, dp->d_name, t);
-                               continue;
-                       }
-                       n->e_ino = dp->d_ino;
-                       n->e_type = dp->d_type;
-                       strcpy(n->e_name, dp->d_name);
-                       for (np = &names; *np; np = &(*np)->e_next) {
-                               if (strcmp(n->e_name, (*np)->e_name) < 0)
-                                       break;
-                       }
-                       n->e_next = *np;
-                       *np = n;
-               }
-       }
-
-       if (names) {
-               do {
-                       n = names;
-                       printf("%d: %s (%s)\n",
-                               n->e_ino, n->e_name, typestr[n->e_type]);
-                       names = n->e_next;
-                       dealloc(n, 0);
-               } while (names);
-       } else {
-               printf( "%s not found\n", path );
-       }
-out:
-       close(fd);
-}
diff --git a/sys/lib/libsa/ustarfs.c b/sys/lib/libsa/ustarfs.c
index cd41bd2..016f419 100644
--- a/sys/lib/libsa/ustarfs.c
+++ b/sys/lib/libsa/ustarfs.c
@@ -537,6 +537,16 @@ ustarfs_stat(struct open_file *f, struct stat *sb)
        return 0;
 }
 
+
+#if defined(LIBSA_ENABLE_LS_OP)
+__compactcall void
+ustarfs_ls(struct open_file *f, const char *pattern)
+{
+       printf("Currently ls command is unsupported by ustarfs\n");
+       return;
+}
+#endif
+
 #ifndef LIBSA_NO_FS_CLOSE
 __compactcall int
 ustarfs_close(struct open_file *f)
-- 
1.7.3.4

From d67a898b80922e911ccdeb8aef4037d7d110d59e Mon Sep 17 00:00:00 2001
From: Evgeniy Ivanov <lolkaantimat%gmail.com@localhost>
Date: Thu, 15 Dec 2011 14:34:33 +0400
Subject: [PATCH 2/3] Ext2fs ls support.


diff --git a/sys/lib/libsa/ext2fs.c b/sys/lib/libsa/ext2fs.c
index 6df0b99..3b9ffbd 100644
--- a/sys/lib/libsa/ext2fs.c
+++ b/sys/lib/libsa/ext2fs.c
@@ -146,6 +146,59 @@ struct file {
        daddr_t         f_buf_blkno;    /* block number of data block */
 };
 
+#if defined(LIBSA_ENABLE_LS_OP)
+
+#define NELEM(x) (sizeof (x) / sizeof(*x))
+
+typedef struct entry_t entry_t;
+struct entry_t {
+       entry_t *e_next;
+       ino32_t e_ino;
+       uint8_t e_type;
+       char    e_name[1];
+};
+
+static const char    *const typestr[] = {
+       "unknown",
+       "REG",
+       "DIR",
+       "CHR",
+       "BLK",
+       "FIFO",
+       "SOCK",
+       "LNK"
+};
+
+static int
+fn_match(const char *fname, const char *pattern)
+{
+       char fc, pc;
+
+       do {
+               fc = *fname++;
+               pc = *pattern++;
+               if (!fc && !pc)
+                       return 1;
+               if (pc == '?' && fc)
+                       pc = fc;
+       } while (fc == pc);
+
+       if (pc != '*')
+               return 0;
+       /*
+        * Too hard (and unnecessary really) too check for "*?name" etc....
+        * "**" will look for a '*' and "*?" a '?'
+        */
+       pc = *pattern++;
+       if (!pc)
+               return 1;
+       while ((fname = strchr(fname, pc)))
+               if (fn_match(++fname, pattern))
+                       return 1;
+       return 0;
+}
+#endif /* LIBSA_ENABLE_LS_OP */
+
 static int read_inode(ino32_t, struct open_file *);
 static int block_map(struct open_file *, indp_t, indp_t *);
 static int buf_read_file(struct open_file *, char **, size_t *);
@@ -807,7 +860,89 @@ ext2fs_stat(struct open_file *f, struct stat *sb)
 __compactcall void
 ext2fs_ls(struct open_file *f, const char *pattern)
 {
-       printf("Currently ls command is unsupported by ext2fs\n");
+       struct file *fp = (struct file *)f->f_fsdata;
+       size_t block_size = fp->f_fs->e2fs_bsize;
+       char *buf;
+       size_t buf_size;
+       entry_t *names = 0, *n, **np;
+
+       fp->f_seekp = 0;
+       while (fp->f_seekp < (off_t)fp->f_di.e2di_size) {
+               struct ext2fs_direct  *dp, *edp;
+               int rc = buf_read_file(f, &buf, &buf_size);
+               if (rc)
+                       goto out;
+               if (buf_size != block_size || buf_size == 0)
+                       goto out;
+
+               dp = (struct ext2fs_direct *)buf;
+               edp = (struct ext2fs_direct *)(buf + buf_size);
+
+               for (; dp < edp;
+                    dp = (void *)((char *)dp + fs2h16(dp->e2d_reclen))) {
+                       const char *t;
+
+                       if (fs2h16(dp->e2d_reclen) <= 0)
+                               goto out;
+
+                       if (fs2h32(dp->e2d_ino) == 0)
+                               continue;
+
+                       if (dp->e2d_type >= NELEM(typestr) ||
+                           !(t = typestr[dp->e2d_type])) {
+                               /*
+                                * This does not handle "old"
+                                * filesystems properly. On little
+                                * endian machines, we get a bogus
+                                * type name if the namlen matches a
+                                * valid type identifier. We could
+                                * check if we read namlen "0" and
+                                * handle this case specially, if
+                                * there were a pressing need...
+                                */
+                               printf("bad dir entry\n");
+                               goto out;
+                       }
+                       if (pattern && !fn_match(dp->e2d_name, pattern))
+                               continue;
+                       n = alloc(sizeof *n + strlen(dp->e2d_name));
+                       if (!n) {
+                               printf("%d: %s (%s)\n",
+                                       fs2h32(dp->e2d_ino), dp->e2d_name, t);
+                               continue;
+                       }
+                       n->e_ino = fs2h32(dp->e2d_ino);
+                       n->e_type = dp->e2d_type;
+                       strcpy(n->e_name, dp->e2d_name);
+                       for (np = &names; *np; np = &(*np)->e_next) {
+                               if (strcmp(n->e_name, (*np)->e_name) < 0)
+                                       break;
+                       }
+                       n->e_next = *np;
+                       *np = n;
+               }
+               fp->f_seekp += buf_size;
+       }
+
+       if (names) {
+               entry_t *p_names = names;
+               do {
+                       n = p_names;
+                       printf("%d: %s (%s)\n",
+                               n->e_ino, n->e_name, typestr[n->e_type]);
+                       p_names = n->e_next;
+               } while (p_names);
+       } else {
+               printf("not found\n");
+       }
+out:
+       if (names) {
+               do {
+                       n = names;
+                       names = n->e_next;
+                       dealloc(n, 0);
+               } while (names);
+       }
        return;
 }
 #endif
-- 
1.7.3.4

From 1bab0723a3ae5eb2864d0686954603a9576b2b79 Mon Sep 17 00:00:00 2001
From: Evgeniy Ivanov <lolkaantimat%gmail.com@localhost>
Date: Sat, 17 Dec 2011 01:27:11 +0400
Subject: [PATCH 3/3] ufs_ls -> ls for non i386 platforms.


diff --git a/sys/arch/ews4800mips/stand/boot/Makefile 
b/sys/arch/ews4800mips/stand/boot/Makefile
index 1d1d230..9982c91 100644
--- a/sys/arch/ews4800mips/stand/boot/Makefile
+++ b/sys/arch/ews4800mips/stand/boot/Makefile
@@ -89,7 +89,8 @@ LIBKERN=      ${KERNLIB}
 .include "${S}/lib/libz/Makefile.inc"
 LIBZ=          ${ZLIB}
 
-SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes
+CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
+SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes SA_ENABLE_LS_OP=yes
 .include "${S}/lib/libsa/Makefile.inc"
 LIBSA=         ${SALIB}
 
diff --git a/sys/arch/ews4800mips/stand/common/diskutil.c 
b/sys/arch/ews4800mips/stand/common/diskutil.c
index 8765c2b..9bb1e75 100644
--- a/sys/arch/ews4800mips/stand/common/diskutil.c
+++ b/sys/arch/ews4800mips/stand/common/diskutil.c
@@ -85,14 +85,12 @@ cmd_ls(int argc, char *argp[], int interactive)
        if (!device_attach(-1, -1, i))
                return 1;
        switch (fstype(i)) {
-       case FSTYPE_UFS:
-               ufs_ls("/");
-               break;
        case FSTYPE_BFS:
                bfs_ls();
                break;
        default:
-               return 1;
+               ls("/");
+               break;
        }
 
        return 0;
diff --git a/sys/arch/landisk/stand/boot/Makefile.boot 
b/sys/arch/landisk/stand/boot/Makefile.boot
index edb90a9..101dd1d 100644
--- a/sys/arch/landisk/stand/boot/Makefile.boot
+++ b/sys/arch/landisk/stand/boot/Makefile.boot
@@ -22,10 +22,12 @@ CPPFLAGS+=  -DSUPPORT_FFSv2
 CPPFLAGS+=     -DSUPPORT_DOSFS
 CPPFLAGS+=     -DSUPPORT_USTARFS
 CPPFLAGS+=     -DDBMONITOR
+CPPFLAGS+=     -DLIBSA_ENABLE_LS_OP
 #CPPFLAGS+=    -DDEBUG
 
 SAMISCMAKEFLAGS+="SA_USE_CREAD=yes"
 SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
+SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
 
 .include "../Makefile.bootprogs"
 
diff --git a/sys/arch/landisk/stand/boot/boot2.c 
b/sys/arch/landisk/stand/boot/boot2.c
index ab698b1..8cce993 100644
--- a/sys/arch/landisk/stand/boot/boot2.c
+++ b/sys/arch/landisk/stand/boot/boot2.c
@@ -329,7 +329,7 @@ bootcmd_ls(char *arg)
        const char *save = default_filename;
 
        default_filename = "/";
-       ufs_ls(arg);
+       ls(arg);
        default_filename = save;
 }
 
diff --git a/sys/arch/x68k/stand/boot/boot.c b/sys/arch/x68k/stand/boot/boot.c
index eda1749..cdecd29 100644
--- a/sys/arch/x68k/stand/boot/boot.c
+++ b/sys/arch/x68k/stand/boot/boot.c
@@ -217,7 +217,7 @@ ls(char *arg)
                if (*(strchr(arg, ':')+1) == 0)
                        strcat(filename, "/");
        }
-       ufs_ls(filename);
+       ls(filename);
        devopen_open_dir = 0;
 }
 
diff --git a/sys/arch/x68k/stand/libsa/Makefile 
b/sys/arch/x68k/stand/libsa/Makefile
index b9c5666..759e986 100644
--- a/sys/arch/x68k/stand/libsa/Makefile
+++ b/sys/arch/x68k/stand/libsa/Makefile
@@ -10,6 +10,7 @@ CPPFLAGS+=    -D_STANDALONE
 CPPFLAGS+=     -DHEAP_VARIABLE
 CPPFLAGS+=     -DHAVE_CHANGEDISK_HOOK
 CPPFLAGS+=     -DUSTAR_SECT_PER_CYL=16
+CPPFLAGS+=     -DLIBSA_ENABLE_LS_OP
 #CPPFLAGS+=    -DDEBUG
 
 .PATH: ${LIBSADIR} ${LIBKERNDIR} ${LIBZDIR} ${LIBZDIST}
@@ -33,7 +34,7 @@ LIBZ= ${ZLIB}
 
 ### find out what to use for libsa
 SA_AS= library
-SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes SA_EXTRADIR=${.CURDIR}
+SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes SA_ENABLE_LS_OP=yes 
SA_EXTRADIR=${.CURDIR}
 .include "${S}/lib/libsa/Makefile.inc"
 LIBSA= ${SALIB}
 
diff --git a/sys/arch/zaurus/stand/zboot/Makefile 
b/sys/arch/zaurus/stand/zboot/Makefile
index db9dccc..5907daf 100644
--- a/sys/arch/zaurus/stand/zboot/Makefile
+++ b/sys/arch/zaurus/stand/zboot/Makefile
@@ -18,6 +18,7 @@ CFLAGS+=      -Wmissing-prototypes -Wstrict-prototypes 
-Wpointer-arith
 CFLAGS+=       -fno-stack-protector -fno-builtin -ffreestanding
 CPPFLAGS+=     -nostdinc -I. -I${.CURDIR} -I${.OBJDIR} -I${S}
 CPPFLAGS+=     -D_STANDALONE -DHEAP_VARIABLE
+CPPFLAGS+=     -DLIBSA_ENABLE_LS_OP
 AFLAGS+=       -D_LOCORE
 LDFLAGS+=      -nostdlib -Bstatic
 
@@ -43,7 +44,7 @@ LIBZ=         ${ZLIB}
 
 ### find out what to use for libsa
 SA_AS=         library
-SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes
+SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes SA_ENABLE_LS_OP=yes
 .include "${S}/lib/libsa/Makefile.inc"
 LIBSA=         ${SALIB}
 
diff --git a/sys/arch/zaurus/stand/zboot/boot.c 
b/sys/arch/zaurus/stand/zboot/boot.c
index 6d0b4a1..25517e9 100644
--- a/sys/arch/zaurus/stand/zboot/boot.c
+++ b/sys/arch/zaurus/stand/zboot/boot.c
@@ -323,7 +323,7 @@ bootcmd_ls(char *arg)
        const char *save = default_filename;
 
        default_filename = "/";
-       ufs_ls(arg);
+       ls(arg);
        default_filename = save;
 }
 
-- 
1.7.3.4



Home | Main Index | Thread Index | Old Index