]> git.saurik.com Git - apple/file_cmds.git/blobdiff - ls/ls.c
file_cmds-230.tar.gz
[apple/file_cmds.git] / ls / ls.c
diff --git a/ls/ls.c b/ls/ls.c
index 99f45b27c026298f054a3e588e7e7961c85fc545..13be69b19d27c1d3e3442e9e4578f96553cca800 100644 (file)
--- a/ls/ls.c
+++ b/ls/ls.c
@@ -68,12 +68,13 @@ __RCSID("$FreeBSD: src/bin/ls/ls.c,v 1.66 2002/09/21 01:28:36 wollman Exp $");
 #include <termcap.h>
 #include <signal.h>
 #endif
-
+#ifdef __APPLE__
+#include <get_compat.h>
+#else
+#define COMPAT_MODE(a,b) (1)
+#endif /* __APPLE__ */
 #include "ls.h"
 #include "extern.h"
-#ifndef __APPLE__
-#include "lomac.h"
-#endif /* __APPLE__ */
 
 /*
  * Upward approximation of the maximum number of characters needed to
@@ -83,8 +84,8 @@ __RCSID("$FreeBSD: src/bin/ls/ls.c,v 1.66 2002/09/21 01:28:36 wollman Exp $");
 #define        STRBUF_SIZEOF(t)        (1 + CHAR_BIT * sizeof(t) / 3 + 1)
 
 static void     display(FTSENT *, FTSENT *);
-static u_quad_t         makenines(u_long);
-static int      mastercmp(const FTSENT * const *, const FTSENT * const *);
+static u_quad_t         makenines(u_quad_t);
+static int      mastercmp(const FTSENT **, const FTSENT **);
 static void     traverse(int, char **, int);
 
 static void (*printfcn)(DISPLAY *);
@@ -95,6 +96,7 @@ int termwidth = 80;           /* default terminal width */
 
 /* flags */
        int f_accesstime;       /* use time of last access */
+       int f_birthtime;                /* use time of file birth */
        int f_flags;            /* show flags associated with a file */
        int f_humanval;         /* show human-readable file sizes */
        int f_inode;            /* print inode */
@@ -105,7 +107,7 @@ static int f_listdot;               /* list files beginning with . */
        int f_nonprint;         /* show unprintables as ? */
 static int f_nosort;           /* don't sort output */
        int f_notabs;           /* don't use tab-separated multi-col output */
-static int f_numericonly;      /* don't convert uid/gid to name */
+       int f_numericonly;      /* don't convert uid/gid to name */
        int f_octal;            /* show unprintables as \xxx */
        int f_octal_escape;     /* like f_octal but use C escapes if possible */
 static int f_recursive;                /* ls subdirectories also */
@@ -121,7 +123,10 @@ static int f_timesort;             /* sort by time vice name */
 static int f_sizesort;         /* sort by size */
        int f_type;             /* add type character for non-regular files */
 static int f_whiteout;         /* show whiteout entries */
-       int f_lomac;            /* show LOMAC attributes */
+       int f_acl;              /* show ACLs in long listing */
+       int f_xattr;            /* show extended attributes in long listing */
+       int f_group;            /* show group */
+       int f_owner;            /* show owner */
 #ifdef COLORLS
        int f_color;            /* add type in color for non-regular files */
 
@@ -147,6 +152,8 @@ main(int argc, char *argv[])
        char *bp = tcapbuf;
 #endif
 
+       if (argc < 1)
+               usage();
        (void)setlocale(LC_ALL, "");
 
        /* Terminal defaults to -Cq, non-terminal defaults to -1. */
@@ -171,7 +178,7 @@ main(int argc, char *argv[])
                f_listdot = 1;
 
        fts_options = FTS_PHYSICAL;
-       while ((ch = getopt(argc, argv, "1ABCFGHLPRSTWZabcdfghiklmnopqrstuvwx")) 
+       while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTUWabcdefghiklmnopqrstuvwx")) 
            != -1) {
                switch (ch) {
                /*
@@ -204,18 +211,27 @@ main(int argc, char *argv[])
                /* The -c and -u options override each other. */
                case 'c':
                        f_statustime = 1;
-                       f_accesstime = 0;
+                       f_accesstime = f_birthtime = 0;
                        break;
                case 'u':
                        f_accesstime = 1;
-                       f_statustime = 0;
+                       f_statustime = f_birthtime = 0;
+                       break;
+               case 'U':
+                       f_birthtime = 1;
+                       f_statustime = f_accesstime = 0;
                        break;
                case 'F':
                        f_type = 1;
                        f_slash = 0;
                        break;
                case 'H':
-                       fts_options |= FTS_COMFOLLOW;
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               fts_options &= ~FTS_LOGICAL;
+                               fts_options |= FTS_PHYSICAL;
+                               fts_options |= FTS_COMFOLLOWDIR;
+                       } else
+                               fts_options |= FTS_COMFOLLOW;
                        break;
                case 'G':
                        setenv("CLICOLOR", "", 1);
@@ -223,9 +239,12 @@ main(int argc, char *argv[])
                case 'L':
                        fts_options &= ~FTS_PHYSICAL;
                        fts_options |= FTS_LOGICAL;
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               fts_options &= ~(FTS_COMFOLLOW|FTS_COMFOLLOWDIR);
+                       }
                        break;
                case 'P':
-                       fts_options &= ~FTS_COMFOLLOW;
+                       fts_options &= ~(FTS_COMFOLLOW|FTS_COMFOLLOWDIR);
                        fts_options &= ~FTS_LOGICAL;
                        fts_options |= FTS_PHYSICAL;
                        break;
@@ -245,8 +264,18 @@ main(int argc, char *argv[])
                        break;
                case 'f':
                        f_nosort = 1;
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               fts_options |= FTS_SEEDOT;
+                               f_listdot = 1;
+                       }
                        break;
-               case 'g':       /* Compatibility with 4.3BSD. */
+               case 'g':       /* Compatibility with Unix03 */
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               f_group = 1;
+                               f_longform = 1;
+                               f_singlecol = 0;
+                               f_stream = 0;
+                       }
                        break;
                case 'h':
                        f_humanval = 1;
@@ -264,9 +293,21 @@ main(int argc, char *argv[])
                        break;
                case 'n':
                        f_numericonly = 1;
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               f_longform = 1;
+                               f_singlecol = 0;
+                               f_stream = 0;
+                       }
                        break;
                case 'o':
-                       f_flags = 1;
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               f_owner = 1;
+                               f_longform = 1;
+                               f_singlecol = 0;
+                               f_stream = 0;
+                       } else {
+                               f_flags = 1;
+                       }
                        break;
                case 'p':
                        f_slash = 1;
@@ -310,8 +351,14 @@ main(int argc, char *argv[])
                        f_octal = 0;
                        f_octal_escape = 0;
                        break;
-               case 'Z':
-                       f_lomac = 1;
+               case 'e':
+                       f_acl = 1;
+                       break;
+               case '@':
+                       f_xattr = 1;
+                       break;
+               case 'O':
+                       f_flags = 1;
                        break;
                default:
                case '?':
@@ -374,7 +421,7 @@ main(int argc, char *argv[])
         * If not -F, -d or -l options, follow any symbolic links listed on
         * the command line.
         */
-       if (!f_longform && !f_listdir && !f_type)
+       if (!f_longform && !f_listdir && !f_type && !f_inode)
                fts_options |= FTS_COMFOLLOW;
 
        /*
@@ -404,6 +451,8 @@ main(int argc, char *argv[])
                        sortfcn = revacccmp;
                else if (f_statustime)
                        sortfcn = revstatcmp;
+               else if (f_birthtime)
+                       sortfcn = revbirthcmp;
                else            /* Use modification time. */
                        sortfcn = revmodcmp;
        } else {
@@ -415,6 +464,8 @@ main(int argc, char *argv[])
                        sortfcn = acccmp;
                else if (f_statustime)
                        sortfcn = statcmp;
+               else if (f_birthtime)
+                       sortfcn = birthcmp;
                else            /* Use modification time. */
                        sortfcn = modcmp;
        }
@@ -449,15 +500,17 @@ traverse(int argc, char *argv[], int options)
 {
        FTS *ftsp;
        FTSENT *p, *chp;
-       int ch_options;
+       int ch_options, error;
 
        if ((ftsp =
            fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
                err(1, "fts_open");
 
        display(NULL, fts_children(ftsp, 0));
-       if (f_listdir)
+       if (f_listdir) {
+               fts_close(ftsp);
                return;
+       }
 
        /*
         * If not recursing down this tree and don't need stat info, just get
@@ -469,6 +522,9 @@ traverse(int argc, char *argv[], int options)
                switch (p->fts_info) {
                case FTS_DC:
                        warnx("%s: directory causes a cycle", p->fts_name);
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               rval = 1;
+                       }
                        break;
                case FTS_DNR:
                case FTS_ERR:
@@ -492,14 +548,33 @@ traverse(int argc, char *argv[], int options)
                                output = 1;
                        }
                        chp = fts_children(ftsp, ch_options);
+                       if (COMPAT_MODE("bin/ls", "Unix2003") && ((options & FTS_LOGICAL)!=0)) {
+                               FTSENT *curr;
+                               for (curr = chp; curr; curr = curr->fts_link) {
+                                       if (curr->fts_info == FTS_SLNONE)
+                                               curr->fts_number = NO_PRINT;
+                               }
+                       }
                        display(p, chp);
 
                        if (!f_recursive && chp != NULL)
                                (void)fts_set(ftsp, p, FTS_SKIP);
                        break;
+               case FTS_SLNONE:        /* Same as default unless Unix conformance */
+                       if (COMPAT_MODE("bin/ls", "Unix2003")) {
+                               if ((options & FTS_LOGICAL)!=0) {       /* -L was specified */
+                                       warnx("%s: %s", p->fts_name, strerror(p->fts_errno ?: ENOENT));
+                                       rval = 1;
+                               }
+                       }
+                       break;
                default:
                        break;
                }
+       error = errno;
+       fts_close(ftsp);
+       errno = error;
+
        if (errno)
                err(1, "fts_read");
 }
@@ -518,7 +593,8 @@ display(FTSENT *p, FTSENT *list)
        NAMES *np;
        off_t maxsize;
        u_int64_t btotal, maxblock;
-       u_long lattrlen, maxinode, maxlen, maxnlink, maxlattr;
+       u_long lattrlen, maxlen, maxnlink, maxlattr;
+       ino_t maxinode;
        int bcfile, maxflags;
        gid_t maxgroup;
        uid_t maxuser;
@@ -542,7 +618,6 @@ display(FTSENT *p, FTSENT *list)
                return;
 
        needstats = f_inode || f_longform || f_size;
-       flen = 0;
        btotal = 0;
        initmax = getenv("LS_COLWIDTHS");
        /* Fields match -lios order.  New ones should be added at the end. */
@@ -574,7 +649,11 @@ display(FTSENT *p, FTSENT *list)
                        strcpy(initmax2, "0");
 
                ninitmax = sscanf(jinitmax,
+#if _DARWIN_FEATURE_64_BIT_INODE
+                   " %llu : %qu : %lu : %i : %i : %i : %qu : %lu : %lu ",
+#else
                    " %lu : %qu : %lu : %i : %i : %i : %qu : %lu : %lu ",
+#endif
                    &maxinode, &maxblock, &maxnlink, &maxuser,
                    &maxgroup, &maxflags, &maxsize, &maxlen, &maxlattr);
                f_notabs = 1;
@@ -619,10 +698,6 @@ display(FTSENT *p, FTSENT *list)
                maxnlink = makenines(maxnlink);
                maxsize = makenines(maxsize);
        }
-#ifndef __APPLE__
-       if (f_lomac)
-               lomac_start();
-#endif /* __APPLE__ */
        bcfile = 0;
        flags = NULL;
        for (cur = list, entries = 0; cur; cur = cur->fts_link) {
@@ -630,13 +705,7 @@ display(FTSENT *p, FTSENT *list)
                        warnx("%s: %s",
                            cur->fts_name, strerror(cur->fts_errno));
                        cur->fts_number = NO_PRINT;
-#ifndef __APPLE__
-                       /* Don't count this as an error.  This is for
-                        * binary compatibility with Matlab installer script.
-                        * 3252074
-                        */
                        rval = 1;
-#endif
                        continue;
                }
                /*
@@ -706,16 +775,8 @@ display(FTSENT *p, FTSENT *list)
                                } else
                                        flen = 0;
                                lattr = NULL;
-#ifndef __APPLE__
-                               if (f_lomac) {
-                                       lattr = get_lattr(cur);
-                                       lattrlen = strlen(lattr);
-                                       if (lattrlen > maxlattr)
-                                               maxlattr = lattrlen;
-                               } else
-#endif /* __APPLE__ */
-                                       lattrlen = 0;
-
+                               lattrlen = 0;
+                               
                                if ((np = malloc(sizeof(NAMES) + lattrlen +
                                    ulen + glen + flen + 4)) == NULL)
                                        err(1, "malloc");
@@ -734,14 +795,6 @@ display(FTSENT *p, FTSENT *list)
                                        (void)strcpy(np->flags, flags);
                                        free(flags);
                                }
-#ifndef __APPLE__
-                               if (f_lomac) {
-                                       np->lattr = &np->data[ulen + glen + 2
-                                           + (f_flags ? flen + 1 : 0)];
-                                       (void)strcpy(np->lattr, lattr);
-                                       free(lattr);
-                               }
-#endif /* __APPLE__ */
                                cur->fts_pointer = np;
                        }
                }
@@ -762,7 +815,11 @@ display(FTSENT *p, FTSENT *list)
                d.s_flags = maxflags;
                d.s_lattr = maxlattr;
                d.s_group = maxgroup;
+#if _DARWIN_FEATURE_64_BIT_INODE
+               (void)snprintf(buf, sizeof(buf), "%llu", maxinode);
+#else
                (void)snprintf(buf, sizeof(buf), "%lu", maxinode);
+#endif
                d.s_inode = strlen(buf);
                (void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
                d.s_nlink = strlen(buf);
@@ -776,10 +833,6 @@ display(FTSENT *p, FTSENT *list)
        if (f_longform)
                for (cur = list; cur; cur = cur->fts_link)
                        free(cur->fts_pointer);
-#ifndef __APPLE__
-       if (f_lomac)
-               lomac_stop();
-#endif /* __APPLE__ */
 }
 
 /*
@@ -789,7 +842,7 @@ display(FTSENT *p, FTSENT *list)
  * All other levels use the sort function.  Error entries remain unsorted.
  */
 static int
-mastercmp(const FTSENT * const *a, const FTSENT * const *b)
+mastercmp(const FTSENT **a, const FTSENT **b)
 {
        int a_info, b_info;
 
@@ -818,7 +871,7 @@ mastercmp(const FTSENT * const *a, const FTSENT * const *b)
  * into a number that wide in decimal.
  */
 static u_quad_t
-makenines(u_long n)
+makenines(u_quad_t n)
 {
        u_long i;
        u_quad_t reg;