keep track of blocks and max file name length in tabdir
[unix-history] / usr / src / bin / ls / print.c
index c237c3c..b083601 100644 (file)
@@ -2,6 +2,9 @@
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 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 are permitted
  * provided that the above copyright notice and this paragraph are
  * duplicated in all such forms and that any documentation,
  * Redistribution and use in source and binary forms are permitted
  * provided that the above copyright notice and this paragraph are
  * duplicated in all such forms and that any documentation,
@@ -16,7 +19,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)print.c    5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)print.c    5.5 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -24,16 +27,61 @@ static char sccsid[] = "@(#)print.c 5.1 (Berkeley) %G%";
 #include <stdio.h>
 #include <grp.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <grp.h>
 #include <pwd.h>
+#include <utmp.h>
 #include <tzfile.h>
 #include "ls.h"
 
 #include <tzfile.h>
 #include "ls.h"
 
-printdir(stats, num)
-       LS *stats;              /* the statted, sorted directory */
+printscol(stats, num)
+       register LS *stats;
+       register int num;
+{
+       for (; num--; ++stats) {
+               (void)printaname(stats);
+               (void)putchar('\n');
+       }
+}
+
+printlong(stats, num)
+       LS *stats;
        register int num;
 {
        register int num;
 {
-       extern int (*lengthfcn)();
-       register int entry;
-       long blocks;            /* sum of blocks in longform listing */
+       (void)printf("total %lu\n", stats[0].lstat.st_flags);
+       for (; num--; ++stats) {
+               if (f_inode)
+                       (void)printf("%6lu ", stats->lstat.st_ino);
+               if (f_size)
+                       (void)printf("%4ld ", stats->lstat.st_blocks / 2);
+               printperms(stats->lstat.st_mode);
+               (void)printf("%3d ", stats->lstat.st_nlink);
+               printowner(stats->lstat.st_uid);
+               if (f_group)
+                       printgrp(stats->lstat.st_gid);
+               if (S_ISCHR(stats->lstat.st_mode) ||
+                   S_ISBLK(stats->lstat.st_mode))
+                       (void)printf("%3d,%4d ", major(stats->lstat.st_rdev),
+                           minor(stats->lstat.st_rdev));
+               else
+                       (void)printf("%8ld ", stats->lstat.st_size);
+               if (f_accesstime)
+                       printtime(stats->lstat.st_atime);
+               else if (f_statustime)
+                       printtime(stats->lstat.st_ctime);
+               else
+                       printtime(stats->lstat.st_mtime);
+               (void)printf("%s", stats->name);
+               if (f_type)
+                       (void)printtype(stats->lstat.st_mode);
+               if (S_ISLNK(stats->lstat.st_mode))
+                       printlink(stats->name);
+               (void)putchar('\n');
+       }
+}
+
+printcol(stats, num)
+       LS *stats;
+       register int num;
+{
+       extern int termwidth;
        int i;                  /* subscript to stats */
        int maxlen;             /* length of longest name string */
        int colwidth;           /* width of a printing column */
        int i;                  /* subscript to stats */
        int maxlen;             /* length of longest name string */
        int colwidth;           /* width of a printing column */
@@ -43,65 +91,7 @@ printdir(stats, num)
        int offset;             /* delta from base to next column */
        int chcnt;              /* character count printed */
 
        int offset;             /* delta from base to next column */
        int chcnt;              /* character count printed */
 
-       if (f_singlecol) {
-               for (entry = 0; entry < num; ++entry) {
-                       (void)printaname(&stats[entry]);
-                       (void)putchar('\n');
-               }
-               return;
-       }
-
-       if (f_longform) {
-               if (!f_firsttime) {
-                       for (i = 0, blocks = 0; i < num; ++i)
-                               blocks += stats[i].lstat.st_blocks;
-                       (void)printf("total %ld\n", blocks / 2);
-               }
-               for (i = 0; i < num; ++i) {
-                       if (f_inode)
-                               (void)printf("%6lu ", stats[i].lstat.st_ino);
-                       if (f_size)
-                               (void)printf("%4ld ",
-                                   stats[i].lstat.st_blocks / 2);
-                       printperms(stats[i].lstat.st_mode);
-                       (void)printf("%3d ", stats[i].lstat.st_nlink);
-                       printowner(stats[i].lstat.st_uid);
-                       if (f_group)
-                               printgrp(stats[i].lstat.st_gid);
-                       if (S_ISCHR(stats[i].lstat.st_mode) ||
-                           S_ISBLK(stats[i].lstat.st_mode))
-                               (void)printf("%3d,%4d ",
-                                   major(stats[i].lstat.st_rdev),
-                                   minor(stats[i].lstat.st_rdev));
-                       else
-                               (void)printf("%8ld ", stats[i].lstat.st_size);
-                       if (f_accesstime)
-                               printtime(stats[i].lstat.st_atime);
-                       else if (f_statustime)
-                               printtime(stats[i].lstat.st_ctime);
-                       else
-                               printtime(stats[i].lstat.st_mtime);
-                       (void)printf("%s", stats[i].name);
-                       if (f_type)
-                               (void)printtype(stats[i].lstat.st_mode);
-                       if (S_ISLNK(stats[i].lstat.st_mode))
-                               printlink(stats[i].name);
-                       (void)putchar('\n');
-               }
-               return;
-       }
-
-       /*
-        * assume tabs every 8 columns WARNING: bad code (hard coded
-        * constants) follows:
-        */
-
-       /* figure out max width */
-       maxlen = -1;
-       for (i = 0; i < num; ++i) {
-               if (maxlen < lengthfcn(stats[i].name))
-                       maxlen = lengthfcn(stats[i].name);
-       }
+       maxlen = stats[0].lstat.st_flags;
 
        /* add fudge factors to max name length */
        if (f_inode)
 
        /* add fudge factors to max name length */
        if (f_inode)
@@ -140,50 +130,68 @@ printdir(stats, num)
  * print [inode] [size] name
  * return # of characters printed, no trailing characters
  */
  * print [inode] [size] name
  * return # of characters printed, no trailing characters
  */
-printaname(entry)
-       LS *entry;
+printaname(lp)
+       LS *lp;
 {
 {
-       int chcnt = 0;
+       int chcnt;
 
 
+       chcnt = 0;
        if (f_inode)
        if (f_inode)
-               chcnt += printf("%5lu ", entry->lstat.st_ino);
+               chcnt += printf("%5lu ", lp->lstat.st_ino);
        if (f_size)
        if (f_size)
-               chcnt += printf("%4ld ", entry->lstat.st_blocks / 2);
-       chcnt += printf("%s", entry->name);
+               chcnt += printf("%4ld ", lp->lstat.st_blocks / 2);
+       chcnt += printf("%s", lp->name);
        if (f_type)
        if (f_type)
-               chcnt += printtype(entry->lstat.st_mode);
+               chcnt += printtype(lp->lstat.st_mode);
        return(chcnt);
 }
 
        return(chcnt);
 }
 
-/*
- * print group and user name
- */
-printgrp(gid)
-       gid_t gid;
+#define        NCACHE  64              /* power of 2 */
+#define        LSMASK  NCACHE - 1      /* bits to store with */
+printowner(uid)
+       uid_t uid;
 {
 {
-       struct group *groupentry;
+       static struct ncache {
+               uid_t   uid;
+               char    name[UT_NAMESIZE];
+       } c_uid[NCACHE];
+       register struct passwd *pw;
+       register struct ncache *cp;
 
 
-       if ((groupentry = getgrgid((int)gid)) == NULL) {
-               /* can't find group, print out number instead */
-               (void)printf("%-9u ", gid);
-               return;
+       cp = c_uid + (uid & LSMASK);
+       if (cp->uid != uid || !*cp->name) {
+               /* if can't find owner, print out number instead */
+               if (!(pw = getpwuid(uid))) {
+                       (void)printf("%-*.*u ", UT_NAMESIZE, UT_NAMESIZE, uid);
+                       return;
+               }
+               cp->uid = uid;
+               (void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE);
        }
        }
-       (void)printf("%-9s", groupentry->gr_name);
-       (void)getgrent();               /* to rewind group file */
+       (void)printf("%-*.*s ", UT_NAMESIZE, UT_NAMESIZE, cp->name);
 }
 
 }
 
-printowner(uid)
-       uid_t uid;
+printgrp(gid)
+       gid_t gid;
 {
 {
-       struct passwd *pwentry;
+       static struct ncache {
+               gid_t   gid;
+               char    name[UT_NAMESIZE];
+       } c_gid[NCACHE];
+       register struct group *gr;
+       register struct ncache *cp;
 
 
-       if ((pwentry = getpwuid((int)uid)) == NULL) {
-               /* can't find owner, print out number instead */
-               (void)printf("%-9u ", uid);
-               return;
+       cp = c_gid + (gid & LSMASK);
+       if (cp->gid != gid || *cp->name) {
+               /* can't find group, print out number instead */
+               if (!(gr = getgrgid(gid))) {
+                       (void)printf("%-*.*u ", UT_NAMESIZE, UT_NAMESIZE, gid);
+                       return;
+               }
+               cp->gid = gid;
+               (void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE);
        }
        }
-       (void)printf("%-9s", pwentry->pw_name);
-       (void)getpwent();
+       (void)printf("%-*.*s ", UT_NAMESIZE, UT_NAMESIZE, cp->name);
 }
 
 printtime(ftime)
 }
 
 printtime(ftime)