]> git.saurik.com Git - apple/file_cmds.git/blobdiff - ls/print.c
file_cmds-272.201.1.tar.gz
[apple/file_cmds.git] / ls / print.c
index a9d651e96f8655e6b26d65f8620669dbd0b67b5a..de04bf300661fa22f064666e4514377aa5847b74 100644 (file)
@@ -46,9 +46,11 @@ __RCSID("$FreeBSD: src/bin/ls/print.c,v 1.57 2002/08/29 14:29:09 keramida Exp $"
 #include <sys/stat.h>
 #ifdef __APPLE__
 #include <sys/acl.h>
+#include <sys/xattr.h>
 #include <sys/types.h>
 #include <grp.h>
 #include <pwd.h>
+#include <TargetConditionals.h>
 #include <membership.h>
 #include <membershipPriv.h>
 #include <uuid/uuid.h>
@@ -59,6 +61,7 @@ __RCSID("$FreeBSD: src/bin/ls/print.c,v 1.57 2002/08/29 14:29:09 keramida Exp $"
 #include <fts.h>
 #include <math.h>
 #include <langinfo.h>
+#include <libutil.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -69,6 +72,13 @@ __RCSID("$FreeBSD: src/bin/ls/print.c,v 1.57 2002/08/29 14:29:09 keramida Exp $"
 #include <termcap.h>
 #include <signal.h>
 #endif
+#include <stdint.h>            /* intmax_t */
+#include <assert.h>
+#ifdef __APPLE__ 
+#include <get_compat.h>
+#else 
+#define COMPAT_MODE(a,b) (1)
+#endif /* __APPLE__ */
 
 #include "ls.h"
 #include "extern.h"
@@ -85,27 +95,6 @@ static int   colortype(mode_t);
 
 #define        IS_NOPRINT(p)   ((p)->fts_number == NO_PRINT)
 
-#define KILO_SZ(n) (n)
-#define MEGA_SZ(n) ((n) * (n))
-#define GIGA_SZ(n) ((n) * (n) * (n))
-#define TERA_SZ(n) ((n) * (n) * (n) * (n))
-#define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n))
-
-#define KILO_2_SZ (KILO_SZ(1024ULL))
-#define MEGA_2_SZ (MEGA_SZ(1024ULL))
-#define GIGA_2_SZ (GIGA_SZ(1024ULL))
-#define TERA_2_SZ (TERA_SZ(1024ULL))
-#define PETA_2_SZ (PETA_SZ(1024ULL))
-
-static u_int64_t vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ};
-
-typedef enum {
-       NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX
-} unit_t;
-static unit_t unit_adjust(off_t *);
-
-static int unitp[] = {NONE, KILO, MEGA, GIGA, TERA, PETA};
-
 #ifdef COLORLS
 /* Most of these are taken from <sys/stat.h> */
 typedef enum Colors {
@@ -139,6 +128,12 @@ printscol(DISPLAY *dp)
 {
        FTSENT *p;
 
+       assert(dp);
+       if (COMPAT_MODE("bin/ls", "Unix2003") && (dp->list != NULL)) {
+               if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
+                       (void)printf("total %qu\n", (u_int64_t)howmany(dp->btotal, blocksize));
+       }
+
        for (p = dp->list; p; p = p->fts_link) {
                if (IS_NOPRINT(p))
                        continue;
@@ -158,7 +153,7 @@ printname(const char *name)
        else if (f_nonprint)
                return prn_printable(name);
        else
-               return printf("%s", name);
+               return prn_normal(name);
 }
 
 /*
@@ -206,52 +201,52 @@ static struct {
 static char *
 uuid_to_name(uuid_t *uu) 
 {
-  int is_gid = -1;
-  struct group *tgrp = NULL;
-  struct passwd *tpass = NULL;
-  char *name = NULL;
-  uid_t id;
-
-
+       int type;
+       char *name = NULL;
+       char *recname = NULL;
+       
 #define MAXNAMETAG (MAXLOGNAME + 6) /* + strlen("group:") */
-  name = (char *) malloc(MAXNAMETAG);
-  
-  if (NULL == name)
-         err(1, "malloc");
-
-  if (0 != mbr_uuid_to_id(uu, &id, &is_gid))
-         goto errout;
-  
-  switch (is_gid) {
-  case ID_TYPE_UID:
-         tpass = getpwuid(id);
-         if (!tpass) {
-                 goto errout;
-         }
-         snprintf(name, MAXNAMETAG, "%s:%s", "user", tpass->pw_name);
-         break;
-  case ID_TYPE_GID:
-         tgrp = getgrgid((gid_t) id);
-         if (!tgrp) {
-                 goto errout;
-         }
-         snprintf(name, MAXNAMETAG, "%s:%s", "group", tgrp->gr_name);
-         break;
-  default:
-         if (0 != mbr_uuid_to_string(uu, name))
-                 goto errout;
-  }
-  return name;
- errout:
-  fprintf(stderr, "Unable to translate qualifier on ACL\n");
-  strcpy(name, "<UNKNOWN>");
-  return name;
+       name = (char *) malloc(MAXNAMETAG);
+       
+       if (NULL == name) {
+               err(1, "malloc");
+       }
+       
+       if (f_numericonly) {
+               goto errout;
+       }
+       
+       if (mbr_identifier_translate(ID_TYPE_UUID, *uu, sizeof(*uu), ID_TYPE_NAME, (void **) &recname, &type)) {
+               goto errout;
+       }
+       
+       snprintf(name, MAXNAMETAG, "%s:%s", (type == MBR_REC_TYPE_USER ? "user" : "group"), recname);
+       free(recname);
+       
+       return name;
+errout:
+       uuid_unparse_upper(*uu, name);
+       
+       return name;
+}
+
+static void
+printxattr(DISPLAY *dp, int count, char *buf, int sizes[])
+{
+       for (int i = 0; i < count; i++) {
+               putchar('\t');
+               printname(buf);
+               putchar('\t');
+               printsize(dp->s_size, sizes[i]);
+               putchar('\n');
+               buf += strlen(buf) + 1;
+       }
 }
 
 static void
 printacl(acl_t acl, int isdir)
 {
-       acl_entry_t     entry;
+       acl_entry_t     entry = NULL;
        int             index;
        uuid_t          *applicable;
        char            *name = NULL;
@@ -265,18 +260,16 @@ printacl(acl_t acl, int isdir)
        for (index = 0;
             acl_get_entry(acl, entry == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY, &entry) == 0;
             index++) {
-               if ((applicable = (uuid_t *) acl_get_qualifier(entry)) == NULL)
-                       continue;
                if (acl_get_tag_type(entry, &tag) != 0)
                        continue;
                if (acl_get_flagset_np(entry, &flags) != 0)
                        continue;
                if (acl_get_permset(entry, &perms) != 0)
                        continue;
-
+               if ((applicable = (uuid_t *) acl_get_qualifier(entry)) == NULL)
+                       continue;
                name = uuid_to_name(applicable);
                acl_free(applicable);
-
                switch(tag) {
                case ACL_EXTENDED_ALLOW:
                        type = "allow";
@@ -324,10 +317,6 @@ printlong(DISPLAY *dp)
        FTSENT *p;
        NAMES *np;
        char buf[20];
-#ifdef __APPLE__
-       acl_t acl = NULL;
-       char full_path[MAXPATHLEN];
-#endif
 #ifdef COLORLS
        int color_printed = 0;
 #endif
@@ -339,34 +328,51 @@ printlong(DISPLAY *dp)
                if (IS_NOPRINT(p))
                        continue;
                sp = p->fts_statp;
-               if (f_inode)
+               if (f_inode) 
+#if _DARWIN_FEATURE_64_BIT_INODE
+                       (void)printf("%*llu ", dp->s_inode, (u_quad_t)sp->st_ino);
+#else
                        (void)printf("%*lu ", dp->s_inode, (u_long)sp->st_ino);
+#endif
                if (f_size)
                        (void)printf("%*qu ",
                            dp->s_block, (u_int64_t)howmany(sp->st_blocks, blocksize));
                strmode(sp->st_mode, buf);
                np = p->fts_pointer;
 #ifdef __APPLE__
-               if (p->fts_parent->fts_name && *p->fts_parent->fts_name)
-               {
-                   snprintf(full_path, sizeof full_path, "%s/%s",
-                           p->fts_parent->fts_accpath, p->fts_accpath);
-                   acl = acl_get_file(full_path, ACL_TYPE_EXTENDED);
-               } else
-                   acl = acl_get_file(p->fts_accpath, ACL_TYPE_EXTENDED);
+               buf[10] = '\0'; /* make +/@ abut the mode */
+               char str[2] = { np->mode_suffix, '\0' };
 #endif /* __APPLE__ */
-               if (f_group) {
+               if (f_group && f_owner) {       /* means print neither */
+#ifdef __APPLE__
+                       (void)printf("%s%s %*u   ", buf, str, dp->s_nlink,
+                                    sp->st_nlink);
+#else  /* ! __APPLE__ */
+                       (void)printf("%s %*u   ", buf, dp->s_nlink,
+                                    sp->st_nlink);
+#endif /* __APPLE__ */
+               }
+               else if (f_group) {
 #ifdef __APPLE__
-                       (void)printf("%s%s %*u %-*s  ", buf, acl == NULL ? " " : "+", dp->s_nlink,
+                       (void)printf("%s%s %*u %-*s  ", buf, str, dp->s_nlink,
                                     sp->st_nlink, dp->s_group, np->group);
 #else  /* ! __APPLE__ */
                        (void)printf("%s %*u %-*s  ", buf, dp->s_nlink,
                                     sp->st_nlink, dp->s_group, np->group);
+#endif /* __APPLE__ */
+               }
+               else if (f_owner) {
+#ifdef __APPLE__
+                       (void)printf("%s%s %*u %-*s  ", buf, str, dp->s_nlink,
+                                    sp->st_nlink, dp->s_user, np->user);
+#else  /* ! __APPLE__ */
+                       (void)printf("%s %*u %-*s  ", buf, dp->s_nlink,
+                                    sp->st_nlink, dp->s_user, np->user);
 #endif /* __APPLE__ */
                }
                else {
 #ifdef __APPLE__
-                       (void)printf("%s%s %*u %-*s  %-*s  ", buf, acl == NULL ? " " : "+", dp->s_nlink,
+                       (void)printf("%s%s %*u %-*s  %-*s  ", buf, str, dp->s_nlink,
                                     sp->st_nlink, dp->s_user, np->user, dp->s_group,
                                     np->group);
 #else  /* ! __APPLE__ */
@@ -394,6 +400,8 @@ printlong(DISPLAY *dp)
                        printtime(sp->st_atime);
                else if (f_statustime)
                        printtime(sp->st_ctime);
+               else if (f_birthtime) 
+                       printtime(sp->st_birthtime);
                else
                        printtime(sp->st_mtime);
 #ifdef COLORLS
@@ -411,9 +419,12 @@ printlong(DISPLAY *dp)
                        printlink(p);
                (void)putchar('\n');
 #ifdef __APPLE__
-               if (f_acl && (acl != NULL))
-                       printacl(acl, S_ISDIR(sp->st_mode));
-               acl_free(acl);
+               if (np->xattr_count && f_xattr) {
+                       printxattr(dp, np->xattr_count, np->xattr_names, np->xattr_sizes);
+               }
+                if (np->acl != NULL && f_acl) {
+                       printacl(np->acl, S_ISDIR(sp->st_mode));
+               }
 #endif /* __APPLE__ */
        }
 }
@@ -471,14 +482,15 @@ printcol(DISPLAY *dp)
         * Have to do random access in the linked list -- build a table
         * of pointers.
         */
-       if (dp->entries > lastentries) {
+       if ((lastentries == -1) || (dp->entries > lastentries)) {
                lastentries = dp->entries;
-               if ((array =
-                   realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
+               if ((array = realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
                        warn(NULL);
                        printscol(dp);
+                       return;
                }
        }
+       memset(array, 0, dp->entries * sizeof(FTSENT *));
        for (p = dp->list, num = 0; p; p = p->fts_link)
                if (p->fts_number != NO_PRINT)
                        array[num++] = p;
@@ -501,6 +513,7 @@ printcol(DISPLAY *dp)
        if (num % numcols)
                ++numrows;
 
+       assert(dp->list);
        if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
                (void)printf("total %qu\n", (u_int64_t)howmany(dp->btotal, blocksize));
 
@@ -510,8 +523,8 @@ printcol(DISPLAY *dp)
                if (!f_sortacross)
                        base = row;
                for (col = 0, chcnt = 0; col < numcols; ++col) {
-                       chcnt += printaname(array[base], dp->s_inode,
-                           dp->s_block);
+                       assert(base < dp->entries);
+                       chcnt += printaname(array[base], dp->s_inode, dp->s_block);
                        if (f_sortacross)
                                base++;
                        else
@@ -547,7 +560,11 @@ printaname(FTSENT *p, u_long inodefield, u_long sizefield)
        sp = p->fts_statp;
        chcnt = 0;
        if (f_inode)
+#if _DARWIN_FEATURE_64_BIT_INODE
+               chcnt += printf("%*llu ", (int)inodefield, (u_quad_t)sp->st_ino);
+#else
                chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino);
+#endif
        if (f_size)
                chcnt += printf("%*qu ",
                    (int)sizefield, (u_int64_t)howmany(sp->st_blocks, blocksize));
@@ -582,6 +599,14 @@ printtime(time_t ftime)
        if (f_sectime)
                /* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */
                format = d_first ? "%e %b %T %Y " : "%b %e %T %Y ";
+       else if (COMPAT_MODE("bin/ls", "Unix2003")) {
+               if (ftime + SIXMONTHS > now && ftime <= now)
+                       /* mmm dd hh:mm || dd mmm hh:mm */
+                       format = d_first ? "%e %b %R " : "%b %e %R ";
+               else
+                       /* mmm dd  yyyy || dd mmm  yyyy */
+                       format = d_first ? "%e %b  %Y " : "%b %e  %Y ";
+       }
        else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS)
                /* mmm dd hh:mm || dd mmm hh:mm */
                format = d_first ? "%e %b %R " : "%b %e %R ";
@@ -800,43 +825,13 @@ printlink(FTSENT *p)
 static void
 printsize(size_t width, off_t bytes)
 {
-       unit_t unit;
-
-       if (f_humanval) {
-               unit = unit_adjust(&bytes);
 
-               if (bytes == 0)
-                       (void)printf("%*s ", (int)width, "0B");
-               else
-                       (void)printf("%*lld%c ", (int)width - 1, bytes,
-                           "BKMGTPE"[unit]);
-       } else
-               (void)printf("%*lld ", (int)width, bytes);
-}
-
-/*
- * Output in "human-readable" format.  Uses 3 digits max and puts
- * unit suffixes at the end.  Makes output compact and easy to read,
- * especially on huge disks.
- *
- */
-unit_t
-unit_adjust(off_t *val)
-{
-       double abval;
-       unit_t unit;
-       unsigned int unit_sz;
-
-       abval = fabs((double)*val);
-
-       unit_sz = abval ? ilogb(abval) / 10 : 0;
-
-       if (unit_sz >= UNIT_MAX) {
-               unit = NONE;
-       } else {
-               unit = unitp[unit_sz];
-               *val /= (double)vals_base2[unit_sz];
-       }
+  if (f_humanval) {
+    char buf[5];
 
-       return (unit);
+    humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
+                   HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
+    (void)printf("%5s ", buf);
+  } else
+    (void)printf("%*jd ", (u_int)width, (intmax_t)bytes);
 }