summaryrefslogtreecommitdiff
path: root/bin/ls
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /bin/ls
initial import of NetBSD tree
Diffstat (limited to 'bin/ls')
-rw-r--r--bin/ls/Makefile7
-rw-r--r--bin/ls/cmp.c132
-rw-r--r--bin/ls/extern.h54
-rw-r--r--bin/ls/ls.1347
-rw-r--r--bin/ls/ls.c557
-rw-r--r--bin/ls/ls.h74
-rw-r--r--bin/ls/print.c302
-rw-r--r--bin/ls/stat_flags.c159
-rw-r--r--bin/ls/util.c78
9 files changed, 1710 insertions, 0 deletions
diff --git a/bin/ls/Makefile b/bin/ls/Makefile
new file mode 100644
index 00000000000..7d4df687133
--- /dev/null
+++ b/bin/ls/Makefile
@@ -0,0 +1,7 @@
+# $NetBSD: Makefile,v 1.8 1995/03/21 09:06:18 cgd Exp $
+# @(#)Makefile 8.1 (Berkeley) 6/2/93
+
+PROG= ls
+SRCS= cmp.c stat_flags.c ls.c print.c util.c
+
+.include <bsd.prog.mk>
diff --git a/bin/ls/cmp.c b/bin/ls/cmp.c
new file mode 100644
index 00000000000..df493bc5527
--- /dev/null
+++ b/bin/ls/cmp.c
@@ -0,0 +1,132 @@
+/* $NetBSD: cmp.c,v 1.8 1995/03/21 09:06:20 cgd Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Fischbein.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)cmp.c 8.1 (Berkeley) 5/31/93";
+#else
+static char rcsid[] = "$NetBSD: cmp.c,v 1.8 1995/03/21 09:06:20 cgd Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fts.h>
+#include <string.h>
+
+#include "ls.h"
+#include "extern.h"
+
+int
+namecmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (strcmp(a->fts_name, b->fts_name));
+}
+
+int
+revnamecmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (strcmp(b->fts_name, a->fts_name));
+}
+
+int
+modcmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (b->fts_statp->st_mtime - a->fts_statp->st_mtime);
+}
+
+int
+revmodcmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (a->fts_statp->st_mtime - b->fts_statp->st_mtime);
+}
+
+int
+acccmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (b->fts_statp->st_atime - a->fts_statp->st_atime);
+}
+
+int
+revacccmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (a->fts_statp->st_atime - b->fts_statp->st_atime);
+}
+
+int
+statcmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (b->fts_statp->st_ctime - a->fts_statp->st_ctime);
+}
+
+int
+revstatcmp(a, b)
+ const FTSENT *a, *b;
+{
+ return (a->fts_statp->st_ctime - b->fts_statp->st_ctime);
+}
+
+int
+sizecmp(a, b)
+ const FTSENT *a, *b;
+{
+ if (b->fts_statp->st_size > a->fts_statp->st_size)
+ return 1;
+ if (b->fts_statp->st_size < a->fts_statp->st_size)
+ return -1;
+ return 0;
+}
+
+int
+revsizecmp(a, b)
+ const FTSENT *a, *b;
+{
+ if (a->fts_statp->st_size > b->fts_statp->st_size)
+ return 1;
+ if (a->fts_statp->st_size < b->fts_statp->st_size)
+ return -1;
+ return 0;
+}
diff --git a/bin/ls/extern.h b/bin/ls/extern.h
new file mode 100644
index 00000000000..431037a7c68
--- /dev/null
+++ b/bin/ls/extern.h
@@ -0,0 +1,54 @@
+/* $NetBSD: extern.h,v 1.5 1995/03/21 09:06:24 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991, 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)extern.h 8.1 (Berkeley) 5/31/93
+ */
+
+int acccmp __P((const FTSENT *, const FTSENT *));
+int revacccmp __P((const FTSENT *, const FTSENT *));
+int modcmp __P((const FTSENT *, const FTSENT *));
+int revmodcmp __P((const FTSENT *, const FTSENT *));
+int namecmp __P((const FTSENT *, const FTSENT *));
+int revnamecmp __P((const FTSENT *, const FTSENT *));
+int statcmp __P((const FTSENT *, const FTSENT *));
+int revstatcmp __P((const FTSENT *, const FTSENT *));
+int sizecmp __P((const FTSENT *, const FTSENT *));
+int revsizecmp __P((const FTSENT *, const FTSENT *));
+
+char *flags_to_string __P((u_long, char *));
+void prcopy __P((char *, char *, int));
+void printcol __P((DISPLAY *));
+void printlong __P((DISPLAY *));
+void printscol __P((DISPLAY *));
+void usage __P((void));
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
new file mode 100644
index 00000000000..a73e748b901
--- /dev/null
+++ b/bin/ls/ls.1
@@ -0,0 +1,347 @@
+.\" $NetBSD: ls.1,v 1.13 1995/09/26 05:04:45 jtc Exp $
+.\"
+.\" Copyright (c) 1980, 1990, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. 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.
+.\"
+.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
+.\"
+.Dd July 29, 1994
+.Dt LS 1
+.Os
+.Sh NAME
+.Nm ls
+.Nd list directory contents
+.Sh SYNOPSIS
+.Nm ls
+.Op Fl ACFLRSTWacdfikloqrstu1
+.Op Ar file ...
+.Sh DESCRIPTION
+For each operand that names a
+.Ar file
+of a type other than
+directory,
+.Nm ls
+displays its name as well as any requested,
+associated information.
+For each operand that names a
+.Ar file
+of type directory,
+.Nm ls
+displays the names of files contained
+within that directory, as well as any requested, associated
+information.
+.Pp
+If no operands are given, the contents of the current
+directory are displayed.
+If more than one operand is given,
+non-directory operands are displayed first; directory
+and non-directory operands are sorted separately and in
+lexicographical order.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl A
+List all entries except for
+.Ql \&.
+and
+.Ql \&.. .
+Always set for the super-user.
+.It Fl C
+Force multi-column output; this is the default when output is to a terminal.
+.It Fl F
+Display a slash (/) immediately after each pathname that is a directory,
+an asterisk (*) after each that is executable,
+an at sign (@) after each symbolic link,
+a percent sign (%) after each whiteout,
+and a vertical bar (|) after each that is a
+.Tn FIFO .
+.It Fl L
+If argument is a symbolic link, list the file or directory the link references
+rather than the link itself.
+.It Fl R
+Recursively list subdirectories encountered.
+.It Fl S
+Sort by size, largest file first.
+.It Fl T
+Display complete time information for the file, including
+month, day, hour, minute, second, and year.
+.It Fl W
+Display whiteouts when scanning directories.
+.It Fl a
+Include directory entries whose names begin with a
+dot (.).
+.It Fl c
+Use time when file status was last changed for sorting or printing.
+.It Fl d
+Directories are listed as plain files (not searched recursively) and
+symbolic links in the argument list are not indirected through.
+.It Fl f
+Output is not sorted.
+.It Fl i
+For each file, print the file's file serial number (inode number).
+.It Fl k
+Modifies the
+.Fl s
+option, causing the sizes to be reported in kilobytes.
+.It Fl l
+(The lowercase letter ``ell.'') List in long format. (See below.)
+If the output is to a terminal, a total sum for all the file
+sizes is output on a line before the long listing.
+.It Fl o
+Include the file flags in a long
+.Pq Fl l
+output
+.It Fl q
+Force printing of non-graphic characters in file names as
+the character `?'; this is the default when output is to a terminal.
+.It Fl r
+Reverse the order of the sort to get reverse
+lexicographical order or the smallest or oldest entries first.
+.It Fl s
+Display the number of file system blocks actually used by each file, in units
+of 512 bytes, where partial units are rounded up to the next integer value.
+If the output is to a terminal, a total sum for all the file
+sizes is output on a line before the listing.
+.It Fl t
+Sort by time modified (most recently modified
+first) before sorting the operands by lexicographical
+order.
+.It Fl u
+Use time of last access,
+instead of last modification
+of the file for sorting
+.Pq Fl t
+or printing
+.Pq Fl l .
+.It Fl \&1
+(The numeric digit ``one.'') Force output to be
+one entry per line.
+This is the default when
+output is not to a terminal.
+.El
+.Pp
+The
+.Fl 1 ,
+.Fl C ,
+and
+.Fl l
+options all override each other; the last one specified determines
+the format used.
+.Pp
+The
+.Fl c ,
+and
+.Fl u
+options override each other; the last one specified determines
+the file time used.
+.Pp
+By default,
+.Nm ls
+lists one entry per line to standard
+output; the exceptions are to terminals or when the
+.Fl C
+option is specified.
+.Pp
+File information is displayed with one or more
+<blank>s separating the information associated with the
+.Fl i ,
+.Fl s ,
+and
+.Fl l
+options.
+.Ss The Long Format
+If the
+.Fl l
+option is given, the following information
+is displayed for each file:
+file mode,
+number of links, owner name, group name,
+number of bytes in the file, abbreviated
+month, day-of-month file was last modified,
+hour file last modified, minute file last
+modified, and the pathname.
+In addition, for each directory whose contents are displayed, the total
+number of 512-byte blocks used by the files in the directory is displayed
+on a line by itself immediately before the information for the files in the
+directory.
+.Pp
+If the owner or group names are not a known user or group name
+the numeric ID's are displayed.
+.Pp
+If the file is a character special or block special file,
+the major and minor device numbers for the file are displayed
+in the size field. If the file is a symbolic link the pathname of the
+linked-to file is preceded by
+.Dq \-> .
+.Pp
+The file mode printed under the -l option consists of the
+entry type, owner permissions, and group permissions.
+The entry type character describes the type of file, as
+follows:
+.Pp
+.Bl -tag -width 4n -offset indent -compact
+.It Sy b
+Block special file.
+.It Sy c
+Character special file.
+.It Sy d
+Directory.
+.It Sy l
+Symbolic link.
+.It Sy s
+Socket link.
+.\" .It Sy p
+.\" .Tn FIFO .
+.It Sy w
+Whiteout.
+.It Sy \-
+Regular file.
+.El
+.Pp
+The next three fields
+are three characters each:
+owner permissions,
+group permissions, and
+other permissions.
+Each field has three character positions:
+.Bl -enum -offset indent
+.It
+If
+.Sy r ,
+the file is readable; if
+.Sy \- ,
+it is not readable.
+.It
+If
+.Sy w ,
+the file is writable; if
+.Sy \- ,
+it is not writable.
+.It
+The first of the following that applies:
+.Bl -tag -width 4n -offset indent
+.It Sy S
+If in the owner permissions, the file is not executable and
+set-user-ID mode is set.
+If in the group permissions, the file is not executable
+and set-group-ID mode is set.
+.It Sy s
+If in the owner permissions, the file is executable
+and set-user-ID mode is set.
+If in the group permissions, the file is executable
+and setgroup-ID mode is set.
+.It Sy x
+The file is executable or the directory is
+searchable.
+.It Sy \-
+The file is neither readable, writable, executable,
+nor set-user-ID nor set-group-ID mode, nor sticky. (See below.)
+.El
+.Pp
+These next two apply only to the third character in the last group
+(other permissions).
+.Bl -tag -width 4n -offset indent
+.It Sy T
+The sticky bit is set
+(mode
+.Li 1000 ) ,
+but not execute or search permission. (See
+.Xr chmod 1
+or
+.Xr sticky 8 . )
+.It Sy t
+The sticky bit is set (mode
+.Li 1000 ) ,
+and is searchable or executable.
+(See
+.Xr chmod 1
+or
+.Xr sticky 8 . )
+.El
+.El
+.Pp
+The
+.Nm ls
+utility exits 0 on success, and >0 if an error occurs.
+.Sh ENVIRONMENTAL VARIABLES
+The following environment variables affect the execution of
+.Nm ls :
+.Bl -tag -width BLOCKSIZE
+.It Ev BLOCKSIZE
+If the environmental variable
+.Ev BLOCKSIZE
+is set, and the
+.Fl k
+option is not specified, the block counts
+(see
+.Fl s )
+will be displayed in units of that size block.
+.It COLUMNS
+If this variable contains a string representing a
+decimal integer, it is used as the
+column position width for displaying
+multiple-text-column output.
+The
+.Nm ls
+utility calculates how
+many pathname text columns to display
+based on the width provided.
+(See
+.Fl C . )
+.It Ev TZ
+The timezone to use when displaying dates.
+See
+.Xr environ 7
+for more information.
+.El
+.Sh COMPATIBILITY
+The group field is now automatically included in the long listing for
+files in order to be compatible with the
+.St -p1003.2
+specification.
+.Sh SEE ALSO
+.Xr chmod 1 ,
+.Xr symlink 7 ,
+.Xr sticky 8
+.Sh HISTORY
+An
+.Nm ls
+utility appeared in
+.At v6 .
+.Sh STANDARDS
+The
+.Nm ls
+utility is expected to be a superset of the
+.St -p1003.2
+specification.
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
new file mode 100644
index 00000000000..c64d7c8e657
--- /dev/null
+++ b/bin/ls/ls.c
@@ -0,0 +1,557 @@
+/* $NetBSD: ls.c,v 1.15 1995/09/07 06:42:58 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Fischbein.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ls.c 8.7 (Berkeley) 8/5/94";
+#else
+static char rcsid[] = "$NetBSD: ls.c,v 1.15 1995/09/07 06:42:58 jtc Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fts.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ls.h"
+#include "extern.h"
+
+char *group_from_gid __P((u_int, int));
+char *user_from_uid __P((u_int, int));
+
+static void display __P((FTSENT *, FTSENT *));
+static int mastercmp __P((const FTSENT **, const FTSENT **));
+static void traverse __P((int, char **, int));
+
+static void (*printfcn) __P((DISPLAY *));
+static int (*sortfcn) __P((const FTSENT *, const FTSENT *));
+
+#define BY_NAME 0
+#define BY_SIZE 1
+#define BY_TIME 2
+
+long blocksize; /* block size units */
+int termwidth = 80; /* default terminal width */
+int sortkey = BY_NAME;
+
+/* flags */
+int f_accesstime; /* use time of last access */
+int f_column; /* columnated format */
+int f_flags; /* show flags associated with a file */
+int f_inode; /* print inode */
+int f_listdir; /* list actual directory, not contents */
+int f_listdot; /* list files beginning with . */
+int f_longform; /* long listing format */
+int f_newline; /* if precede with newline */
+int f_nonprint; /* show unprintables as ? */
+int f_nosort; /* don't sort output */
+int f_recursive; /* ls subdirectories also */
+int f_reversesort; /* reverse whatever sort is used */
+int f_sectime; /* print the real time for all files */
+int f_singlecol; /* use single column output */
+int f_size; /* list size in short listing */
+int f_statustime; /* use time of last mode change */
+int f_dirname; /* if precede with directory name */
+int f_type; /* add type character for non-regular files */
+int f_whiteout; /* show whiteout entries */
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ static char dot[] = ".", *dotav[] = { dot, NULL };
+ struct winsize win;
+ int ch, fts_options, notused;
+ int kflag = 0;
+ char *p;
+
+ /* Terminal defaults to -Cq, non-terminal defaults to -1. */
+ if (isatty(STDOUT_FILENO)) {
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1 ||
+ !win.ws_col) {
+ if ((p = getenv("COLUMNS")) != NULL)
+ termwidth = atoi(p);
+ }
+ else
+ termwidth = win.ws_col;
+ f_column = f_nonprint = 1;
+ } else
+ f_singlecol = 1;
+
+ /* Root is -A automatically. */
+ if (!getuid())
+ f_listdot = 1;
+
+ fts_options = FTS_PHYSICAL;
+ while ((ch = getopt(argc, argv, "1ACFLRSTWacdfgikloqrstu")) != -1) {
+ switch (ch) {
+ /*
+ * The -1, -C and -l options all override each other so shell
+ * aliasing works right.
+ */
+ case '1':
+ f_singlecol = 1;
+ f_column = f_longform = 0;
+ break;
+ case 'C':
+ f_column = 1;
+ f_longform = f_singlecol = 0;
+ break;
+ case 'l':
+ f_longform = 1;
+ f_column = f_singlecol = 0;
+ break;
+ /* The -c and -u options override each other. */
+ case 'c':
+ f_statustime = 1;
+ f_accesstime = 0;
+ break;
+ case 'u':
+ f_accesstime = 1;
+ f_statustime = 0;
+ break;
+ case 'F':
+ f_type = 1;
+ break;
+ case 'L':
+ fts_options &= ~FTS_PHYSICAL;
+ fts_options |= FTS_LOGICAL;
+ break;
+ case 'R':
+ f_recursive = 1;
+ break;
+ case 'a':
+ fts_options |= FTS_SEEDOT;
+ /* FALLTHROUGH */
+ case 'A':
+ f_listdot = 1;
+ break;
+ /* The -d option turns off the -R option. */
+ case 'd':
+ f_listdir = 1;
+ f_recursive = 0;
+ break;
+ case 'f':
+ f_nosort = 1;
+ break;
+ case 'g': /* Compatibility with 4.3BSD. */
+ break;
+ case 'i':
+ f_inode = 1;
+ break;
+ case 'k':
+ blocksize = 1024;
+ kflag = 1;
+ break;
+ case 'o':
+ f_flags = 1;
+ break;
+ case 'q':
+ f_nonprint = 1;
+ break;
+ case 'r':
+ f_reversesort = 1;
+ break;
+ case 'S':
+ sortkey = BY_SIZE;
+ break;
+ case 's':
+ f_size = 1;
+ break;
+ case 'T':
+ f_sectime = 1;
+ break;
+ case 't':
+ sortkey = BY_TIME;
+ break;
+ case 'W':
+ f_whiteout = 1;
+ break;
+ default:
+ case '?':
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /*
+ * If not -F, -i, -l, -S, -s or -t options, don't require stat
+ * information.
+ */
+ if (!f_inode && !f_longform && !f_size && !f_type &&
+ sortkey == BY_NAME)
+ fts_options |= FTS_NOSTAT;
+
+ /*
+ * If not -F, -d or -l options, follow any symbolic links listed on
+ * the command line.
+ */
+ if (!f_longform && !f_listdir && !f_type)
+ fts_options |= FTS_COMFOLLOW;
+
+ /*
+ * If -W, show whiteout entries
+ */
+#ifdef FTS_WHITEOUT
+ if (f_whiteout)
+ fts_options |= FTS_WHITEOUT;
+#endif
+
+ /* If -l or -s, figure out block size. */
+ if (f_longform || f_size) {
+ if (!kflag)
+ (void)getbsize(&notused, &blocksize);
+ blocksize /= 512;
+ }
+
+ /* Select a sort function. */
+ if (f_reversesort) {
+ switch (sortkey) {
+ case BY_NAME:
+ sortfcn = revnamecmp;
+ break;
+ case BY_SIZE:
+ sortfcn = revsizecmp;
+ break;
+ case BY_TIME:
+ if (f_accesstime)
+ sortfcn = revacccmp;
+ else if (f_statustime)
+ sortfcn = revstatcmp;
+ else /* Use modification time. */
+ sortfcn = revmodcmp;
+ break;
+ }
+ } else {
+ switch (sortkey) {
+ case BY_NAME:
+ sortfcn = namecmp;
+ break;
+ case BY_SIZE:
+ sortfcn = sizecmp;
+ break;
+ case BY_TIME:
+ if (f_accesstime)
+ sortfcn = acccmp;
+ else if (f_statustime)
+ sortfcn = statcmp;
+ else /* Use modification time. */
+ sortfcn = modcmp;
+ break;
+ }
+ }
+
+ /* Select a print function. */
+ if (f_singlecol)
+ printfcn = printscol;
+ else if (f_longform)
+ printfcn = printlong;
+ else
+ printfcn = printcol;
+
+ if (argc)
+ traverse(argc, argv, fts_options);
+ else
+ traverse(1, dotav, fts_options);
+ exit(0);
+}
+
+static int output; /* If anything output. */
+
+/*
+ * Traverse() walks the logical directory structure specified by the argv list
+ * in the order specified by the mastercmp() comparison function. During the
+ * traversal it passes linked lists of structures to display() which represent
+ * a superset (may be exact set) of the files to be displayed.
+ */
+static void
+traverse(argc, argv, options)
+ int argc, options;
+ char *argv[];
+{
+ FTS *ftsp;
+ FTSENT *p, *chp;
+ int ch_options;
+
+ if ((ftsp =
+ fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
+ err(1, NULL);
+
+ display(NULL, fts_children(ftsp, 0));
+ if (f_listdir)
+ return;
+
+ /*
+ * If not recursing down this tree and don't need stat info, just get
+ * the names.
+ */
+ ch_options = !f_recursive && options & FTS_NOSTAT ? FTS_NAMEONLY : 0;
+
+ while ((p = fts_read(ftsp)) != NULL)
+ switch (p->fts_info) {
+ case FTS_DC:
+ warnx("%s: directory causes a cycle", p->fts_name);
+ break;
+ case FTS_DNR:
+ case FTS_ERR:
+ warnx("%s: %s", p->fts_name, strerror(p->fts_errno));
+ break;
+ case FTS_D:
+ if (p->fts_level != FTS_ROOTLEVEL &&
+ p->fts_name[0] == '.' && !f_listdot)
+ break;
+
+ /*
+ * If already output something, put out a newline as
+ * a separator. If multiple arguments, precede each
+ * directory with its name.
+ */
+ if (output)
+ (void)printf("\n%s:\n", p->fts_path);
+ else if (argc > 1) {
+ (void)printf("%s:\n", p->fts_path);
+ output = 1;
+ }
+
+ chp = fts_children(ftsp, ch_options);
+ display(p, chp);
+
+ if (!f_recursive && chp != NULL)
+ (void)fts_set(ftsp, p, FTS_SKIP);
+ break;
+ }
+ if (errno)
+ err(1, "fts_read");
+}
+
+/*
+ * Display() takes a linked list of FTSENT structures and passes the list
+ * along with any other necessary information to the print function. P
+ * points to the parent directory of the display list.
+ */
+static void
+display(p, list)
+ FTSENT *p, *list;
+{
+ struct stat *sp;
+ DISPLAY d;
+ FTSENT *cur;
+ NAMES *np;
+ u_quad_t maxsize;
+ u_long btotal, maxblock, maxinode, maxlen, maxnlink;
+ int bcfile, flen, glen, ulen, maxflags, maxgroup, maxuser;
+ int entries, needstats;
+ char *user, *group, *flags, buf[20]; /* 32 bits == 10 digits */
+
+ /*
+ * If list is NULL there are two possibilities: that the parent
+ * directory p has no children, or that fts_children() returned an
+ * error. We ignore the error case since it will be replicated
+ * on the next call to fts_read() on the post-order visit to the
+ * directory p, and will be signalled in traverse().
+ */
+ if (list == NULL)
+ return;
+
+ needstats = f_inode || f_longform || f_size;
+ flen = 0;
+ btotal = maxblock = maxinode = maxlen = maxnlink = 0;
+ bcfile = 0;
+ maxuser = maxgroup = maxflags = 0;
+ maxsize = 0;
+ for (cur = list, entries = 0; cur; cur = cur->fts_link) {
+ if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
+ warnx("%s: %s",
+ cur->fts_name, strerror(cur->fts_errno));
+ cur->fts_number = NO_PRINT;
+ continue;
+ }
+
+ /*
+ * P is NULL if list is the argv list, to which different rules
+ * apply.
+ */
+ if (p == NULL) {
+ /* Directories will be displayed later. */
+ if (cur->fts_info == FTS_D && !f_listdir) {
+ cur->fts_number = NO_PRINT;
+ continue;
+ }
+ } else {
+ /* Only display dot file if -a/-A set. */
+ if (cur->fts_name[0] == '.' && !f_listdot) {
+ cur->fts_number = NO_PRINT;
+ continue;
+ }
+ }
+ if (f_nonprint)
+ prcopy(cur->fts_name, cur->fts_name, cur->fts_namelen);
+ if (cur->fts_namelen > maxlen)
+ maxlen = cur->fts_namelen;
+ if (needstats) {
+ sp = cur->fts_statp;
+ if (sp->st_blocks > maxblock)
+ maxblock = sp->st_blocks;
+ if (sp->st_ino > maxinode)
+ maxinode = sp->st_ino;
+ if (sp->st_nlink > maxnlink)
+ maxnlink = sp->st_nlink;
+ if (sp->st_size > maxsize)
+ maxsize = sp->st_size;
+
+ btotal += sp->st_blocks;
+ if (f_longform) {
+ user = user_from_uid(sp->st_uid, 0);
+ if ((ulen = strlen(user)) > maxuser)
+ maxuser = ulen;
+ group = group_from_gid(sp->st_gid, 0);
+ if ((glen = strlen(group)) > maxgroup)
+ maxgroup = glen;
+ if (f_flags) {
+ flags =
+ flags_to_string(sp->st_flags, "-");
+ if ((flen = strlen(flags)) > maxflags)
+ maxflags = flen;
+ } else
+ flen = 0;
+
+ if ((np = malloc(sizeof(NAMES) +
+ ulen + glen + flen + 3)) == NULL)
+ err(1, NULL);
+
+ np->user = &np->data[0];
+ (void)strcpy(np->user, user);
+ np->group = &np->data[ulen + 1];
+ (void)strcpy(np->group, group);
+
+ if (S_ISCHR(sp->st_mode) ||
+ S_ISBLK(sp->st_mode))
+ bcfile = 1;
+
+ if (f_flags) {
+ np->flags = &np->data[ulen + glen + 2];
+ (void)strcpy(np->flags, flags);
+ }
+ cur->fts_pointer = np;
+ }
+ }
+ ++entries;
+ }
+
+ if (!entries)
+ return;
+
+ d.list = list;
+ d.entries = entries;
+ d.maxlen = maxlen;
+ if (needstats) {
+ d.bcfile = bcfile;
+ d.btotal = btotal;
+ (void)snprintf(buf, sizeof(buf), "%lu", maxblock);
+ d.s_block = strlen(buf);
+ d.s_flags = maxflags;
+ d.s_group = maxgroup;
+ (void)snprintf(buf, sizeof(buf), "%lu", maxinode);
+ d.s_inode = strlen(buf);
+ (void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
+ d.s_nlink = strlen(buf);
+ (void)snprintf(buf, sizeof(buf), "%qu", maxsize);
+ d.s_size = strlen(buf);
+ d.s_user = maxuser;
+ }
+
+ printfcn(&d);
+ output = 1;
+
+ if (f_longform)
+ for (cur = list; cur; cur = cur->fts_link)
+ free(cur->fts_pointer);
+}
+
+/*
+ * Ordering for mastercmp:
+ * If ordering the argv (fts_level = FTS_ROOTLEVEL) return non-directories
+ * as larger than directories. Within either group, use the sort function.
+ * All other levels use the sort function. Error entries remain unsorted.
+ */
+static int
+mastercmp(a, b)
+ const FTSENT **a, **b;
+{
+ int a_info, b_info;
+
+ a_info = (*a)->fts_info;
+ if (a_info == FTS_ERR)
+ return (0);
+ b_info = (*b)->fts_info;
+ if (b_info == FTS_ERR)
+ return (0);
+
+ if (a_info == FTS_NS || b_info == FTS_NS)
+ return (namecmp(*a, *b));
+
+ if (a_info == b_info)
+ return (sortfcn(*a, *b));
+
+ if ((*a)->fts_level == FTS_ROOTLEVEL)
+ if (a_info == FTS_D)
+ return (1);
+ else if (b_info == FTS_D)
+ return (-1);
+ else
+ return (sortfcn(*a, *b));
+ else
+ return (sortfcn(*a, *b));
+}
diff --git a/bin/ls/ls.h b/bin/ls/ls.h
new file mode 100644
index 00000000000..0feaaaef592
--- /dev/null
+++ b/bin/ls/ls.h
@@ -0,0 +1,74 @@
+/* $NetBSD: ls.h,v 1.7 1995/03/21 09:06:33 cgd Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Fischbein.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ *
+ * @(#)ls.h 8.1 (Berkeley) 5/31/93
+ */
+
+#define NO_PRINT 1
+
+extern long blocksize; /* block size units */
+
+extern int f_accesstime; /* use time of last access */
+extern int f_flags; /* show flags associated with a file */
+extern int f_inode; /* print inode */
+extern int f_longform; /* long listing format */
+extern int f_sectime; /* print the real time for all files */
+extern int f_size; /* list size in short listing */
+extern int f_statustime; /* use time of last mode change */
+extern int f_type; /* add type character for non-regular files */
+
+typedef struct {
+ FTSENT *list;
+ u_long btotal;
+ int bcfile;
+ int entries;
+ int maxlen;
+ int s_block;
+ int s_flags;
+ int s_group;
+ int s_inode;
+ int s_nlink;
+ int s_size;
+ int s_user;
+} DISPLAY;
+
+typedef struct {
+ char *user;
+ char *group;
+ char *flags;
+ char data[1];
+} NAMES;
diff --git a/bin/ls/print.c b/bin/ls/print.c
new file mode 100644
index 00000000000..f647fcd97c4
--- /dev/null
+++ b/bin/ls/print.c
@@ -0,0 +1,302 @@
+/* $NetBSD: print.c,v 1.14 1995/09/07 06:43:00 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Fischbein.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)print.c 8.5 (Berkeley) 7/28/94";
+#else
+static char rcsid[] = "$NetBSD: print.c,v 1.14 1995/09/07 06:43:00 jtc Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fts.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <utmp.h>
+
+#include "ls.h"
+#include "extern.h"
+
+static int printaname __P((FTSENT *, u_long, u_long));
+static void printlink __P((FTSENT *));
+static void printtime __P((time_t));
+static int printtype __P((u_int));
+
+#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
+
+void
+printscol(dp)
+ DISPLAY *dp;
+{
+ FTSENT *p;
+
+ for (p = dp->list; p; p = p->fts_link) {
+ if (IS_NOPRINT(p))
+ continue;
+ (void)printaname(p, dp->s_inode, dp->s_block);
+ (void)putchar('\n');
+ }
+}
+
+void
+printlong(dp)
+ DISPLAY *dp;
+{
+ struct stat *sp;
+ FTSENT *p;
+ NAMES *np;
+ char buf[20];
+
+ if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
+ (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
+
+ for (p = dp->list; p; p = p->fts_link) {
+ if (IS_NOPRINT(p))
+ continue;
+ sp = p->fts_statp;
+ if (f_inode)
+ (void)printf("%*lu ", dp->s_inode, sp->st_ino);
+ if (f_size)
+ (void)printf("%*qd ",
+ dp->s_block, howmany(sp->st_blocks, blocksize));
+ (void)strmode(sp->st_mode, buf);
+ np = p->fts_pointer;
+ (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink,
+ sp->st_nlink, dp->s_user, np->user, dp->s_group,
+ np->group);
+ if (f_flags)
+ (void)printf("%-*s ", dp->s_flags, np->flags);
+ if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
+ (void)printf("%3d, %3d ",
+ major(sp->st_rdev), minor(sp->st_rdev));
+ else if (dp->bcfile)
+ (void)printf("%*s%*qd ",
+ 8 - dp->s_size, "", dp->s_size, sp->st_size);
+ else
+ (void)printf("%*qd ", dp->s_size, sp->st_size);
+ if (f_accesstime)
+ printtime(sp->st_atime);
+ else if (f_statustime)
+ printtime(sp->st_ctime);
+ else
+ printtime(sp->st_mtime);
+ (void)printf("%s", p->fts_name);
+ if (f_type)
+ (void)printtype(sp->st_mode);
+ if (S_ISLNK(sp->st_mode))
+ printlink(p);
+ (void)putchar('\n');
+ }
+}
+
+#define TAB 8
+
+void
+printcol(dp)
+ DISPLAY *dp;
+{
+ extern int termwidth;
+ static FTSENT **array;
+ static int lastentries = -1;
+ FTSENT *p;
+ int base, chcnt, cnt, col, colwidth, num;
+ int endcol, numcols, numrows, row;
+
+ /*
+ * Have to do random access in the linked list -- build a table
+ * of pointers.
+ */
+ if (dp->entries > lastentries) {
+ lastentries = dp->entries;
+ if ((array =
+ realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
+ warn(NULL);
+ printscol(dp);
+ }
+ }
+ for (p = dp->list, num = 0; p; p = p->fts_link)
+ if (p->fts_number != NO_PRINT)
+ array[num++] = p;
+
+ colwidth = dp->maxlen;
+ if (f_inode)
+ colwidth += dp->s_inode + 1;
+ if (f_size)
+ colwidth += dp->s_block + 1;
+ if (f_type)
+ colwidth += 1;
+
+ colwidth = (colwidth + TAB) & ~(TAB - 1);
+ if (termwidth < 2 * colwidth) {
+ printscol(dp);
+ return;
+ }
+
+ numcols = termwidth / colwidth;
+ numrows = num / numcols;
+ if (num % numcols)
+ ++numrows;
+
+ if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
+ (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
+ for (row = 0; row < numrows; ++row) {
+ endcol = colwidth;
+ for (base = row, chcnt = col = 0; col < numcols; ++col) {
+ chcnt += printaname(array[base], dp->s_inode,
+ dp->s_block);
+ if ((base += numrows) >= num)
+ break;
+ while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
+ (void)putchar('\t');
+ chcnt = cnt;
+ }
+ endcol += colwidth;
+ }
+ (void)putchar('\n');
+ }
+}
+
+/*
+ * print [inode] [size] name
+ * return # of characters printed, no trailing characters.
+ */
+static int
+printaname(p, inodefield, sizefield)
+ FTSENT *p;
+ u_long sizefield, inodefield;
+{
+ struct stat *sp;
+ int chcnt;
+
+ sp = p->fts_statp;
+ chcnt = 0;
+ if (f_inode)
+ chcnt += printf("%*lu ", (int)inodefield, sp->st_ino);
+ if (f_size)
+ chcnt += printf("%*qd ",
+ (int)sizefield, howmany(sp->st_blocks, blocksize));
+ chcnt += printf("%s", p->fts_name);
+ if (f_type)
+ chcnt += printtype(sp->st_mode);
+ return (chcnt);
+}
+
+static void
+printtime(ftime)
+ time_t ftime;
+{
+ int i;
+ char *longstring;
+
+ longstring = ctime(&ftime);
+ for (i = 4; i < 11; ++i)
+ (void)putchar(longstring[i]);
+
+#define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY)
+ if (f_sectime)
+ for (i = 11; i < 24; i++)
+ (void)putchar(longstring[i]);
+ else if (ftime + SIXMONTHS > time(NULL))
+ for (i = 11; i < 16; ++i)
+ (void)putchar(longstring[i]);
+ else {
+ (void)putchar(' ');
+ for (i = 20; i < 24; ++i)
+ (void)putchar(longstring[i]);
+ }
+ (void)putchar(' ');
+}
+
+static int
+printtype(mode)
+ u_int mode;
+{
+ switch (mode & S_IFMT) {
+ case S_IFDIR:
+ (void)putchar('/');
+ return (1);
+ case S_IFIFO:
+ (void)putchar('|');
+ return (1);
+ case S_IFLNK:
+ (void)putchar('@');
+ return (1);
+ case S_IFSOCK:
+ (void)putchar('=');
+ return (1);
+ case S_IFWHT:
+ (void)putchar('%');
+ return (1);
+ }
+ if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
+ (void)putchar('*');
+ return (1);
+ }
+ return (0);
+}
+
+static void
+printlink(p)
+ FTSENT *p;
+{
+ int lnklen;
+ char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
+
+ if (p->fts_level == FTS_ROOTLEVEL)
+ (void)snprintf(name, sizeof(name), "%s", p->fts_name);
+ else
+ (void)snprintf(name, sizeof(name),
+ "%s/%s", p->fts_parent->fts_accpath, p->fts_name);
+ if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
+ (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
+ return;
+ }
+ path[lnklen] = '\0';
+ (void)printf(" -> %s", path);
+}
diff --git a/bin/ls/stat_flags.c b/bin/ls/stat_flags.c
new file mode 100644
index 00000000000..7ba8f41586e
--- /dev/null
+++ b/bin/ls/stat_flags.c
@@ -0,0 +1,159 @@
+/* $NetBSD: stat_flags.c,v 1.5 1995/09/07 06:43:01 jtc 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)stat_flags.c 8.2 (Berkeley) 7/28/94";
+#else
+static char rcsid[] = "$NetBSD: stat_flags.c,v 1.5 1995/09/07 06:43:01 jtc Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#define SAPPEND(s) { \
+ if (prefix != NULL) \
+ (void)strcat(string, prefix); \
+ (void)strcat(string, s); \
+ prefix = ","; \
+}
+
+/*
+ * flags_to_string --
+ * Convert stat flags to a comma-separated string. If no flags
+ * are set, return the default string.
+ */
+char *
+flags_to_string(flags, def)
+ u_long flags;
+ char *def;
+{
+ static char string[128];
+ char *prefix;
+
+ string[0] = '\0';
+ prefix = NULL;
+ if (flags & UF_APPEND)
+ SAPPEND("uappnd");
+ if (flags & UF_IMMUTABLE)
+ SAPPEND("uchg");
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & UF_OPAQUE)
+ SAPPEND("opaque");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+ return (prefix == NULL && def != NULL ? def : string);
+}
+
+#define TEST(a, b, f) { \
+ if (!memcmp(a, b, sizeof(b))) { \
+ if (clear) { \
+ if (clrp) \
+ *clrp |= (f); \
+ } else if (setp) \
+ *setp |= (f); \
+ break; \
+ } \
+}
+
+/*
+ * string_to_flags --
+ * Take string of arguments and return stat flags. Return 0 on
+ * success, 1 on failure. On failure, stringp is set to point
+ * to the offending token.
+ */
+int
+string_to_flags(stringp, setp, clrp)
+ char **stringp;
+ u_long *setp, *clrp;
+{
+ int clear;
+ char *string, *p;
+
+ clear = 0;
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ *stringp = p;
+ if (*p == '\0')
+ continue;
+ if (p[0] == 'n' && p[1] == 'o') {
+ clear = 1;
+ p += 2;
+ }
+ switch (p[0]) {
+ case 'a':
+ TEST(p, "arch", SF_ARCHIVED);
+ TEST(p, "archived", SF_ARCHIVED);
+ return (1);
+ case 'd':
+ clear = !clear;
+ TEST(p, "dump", UF_NODUMP);
+ return (1);
+ case 'o':
+ TEST(p, "opaque", UF_OPAQUE);
+ return (1);
+ case 's':
+ TEST(p, "sappnd", SF_APPEND);
+ TEST(p, "sappend", SF_APPEND);
+ TEST(p, "schg", SF_IMMUTABLE);
+ TEST(p, "schange", SF_IMMUTABLE);
+ TEST(p, "simmutable", SF_IMMUTABLE);
+ return (1);
+ case 'u':
+ TEST(p, "uappnd", UF_APPEND);
+ TEST(p, "uappend", UF_APPEND);
+ TEST(p, "uchg", UF_IMMUTABLE);
+ TEST(p, "uchange", UF_IMMUTABLE);
+ TEST(p, "uimmutable", UF_IMMUTABLE);
+ /* FALLTHROUGH */
+ default:
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/bin/ls/util.c b/bin/ls/util.c
new file mode 100644
index 00000000000..764c283695c
--- /dev/null
+++ b/bin/ls/util.c
@@ -0,0 +1,78 @@
+/* $NetBSD: util.c,v 1.12 1995/09/07 06:43:02 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Fischbein.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)util.c 8.5 (Berkeley) 4/28/95";
+#else
+static char rcsid[] = "$NetBSD: util.c,v 1.12 1995/09/07 06:43:02 jtc Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <fts.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ls.h"
+#include "extern.h"
+
+void
+prcopy(src, dest, len)
+ char *src, *dest;
+ int len;
+{
+ int ch;
+
+ while (len--) {
+ ch = *src++;
+ *dest++ = isprint(ch) ? ch : '?';
+ }
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: ls [-1ACFLRSTWacdfikloqrstu] [file ...]\n");
+ exit(1);
+}