386BSD 0.1 development
[unix-history] / usr / src / bin / ls / print.c
index c237c3c..09ab426 100644 (file)
@@ -2,21 +2,40 @@
  * 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.
  *
- * 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,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)print.c    5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)print.c    5.24 (Berkeley) 10/19/90";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -24,115 +43,111 @@ 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;
 {
        register int num;
 {
-       extern int (*lengthfcn)();
-       register int entry;
-       long blocks;            /* sum of blocks in longform listing */
-       int i;                  /* subscript to stats */
-       int maxlen;             /* length of longest name string */
-       int colwidth;           /* width of a printing column */
-       int numcols;            /* number of columns */
-       int collength;          /* lines in longest column */
-       int base;               /* subscript for leftmost column */
-       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;
+       for (; num--; ++stats) {
+               (void)printaname(stats);
+               (void)putchar('\n');
        }
        }
+}
 
 
-       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;
+printlong(stats, num)
+       LS *stats;
+       register int num;
+{
+       extern int errno;
+       char modep[15], *user_from_uid(), *group_from_gid(), *strerror();
+
+       if (f_total)
+               (void)printf("total %lu\n", f_kblocks ?
+                   howmany(stats[0].lstat.st_btotal, 2) :
+                   stats[0].lstat.st_btotal);
+       for (; num--; ++stats) {
+               if (f_inode)
+                       (void)printf("%6lu ", stats->lstat.st_ino);
+               if (f_size)
+                       (void)printf("%4ld ", f_kblocks ?
+                           howmany(stats->lstat.st_blocks, 2) :
+                           stats->lstat.st_blocks);
+               (void)strmode(stats->lstat.st_mode, modep);
+               (void)printf("%s %3u %-*s ", modep, stats->lstat.st_nlink,
+                   UT_NAMESIZE, user_from_uid(stats->lstat.st_uid, 0));
+               if (f_group)
+                       (void)printf("%-*s ", UT_NAMESIZE,
+                           group_from_gid(stats->lstat.st_gid, 0));
+               if (S_ISCHR(stats->lstat.st_mode) ||
+                   S_ISBLK(stats->lstat.st_mode))
+                       (void)printf("%3d, %3d ", 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');
        }
        }
+}
 
 
-       /*
-        * assume tabs every 8 columns WARNING: bad code (hard coded
-        * constants) follows:
-        */
+#define        TAB     8
 
 
-       /* figure out max width */
-       maxlen = -1;
-       for (i = 0; i < num; ++i) {
-               if (maxlen < lengthfcn(stats[i].name))
-                       maxlen = lengthfcn(stats[i].name);
-       }
+printcol(stats, num)
+       LS *stats;
+       int num;
+{
+       extern int termwidth;
+       register int base, chcnt, cnt, col, colwidth;
+       int endcol, numcols, numrows, row;
 
 
-       /* add fudge factors to max name length */
+       colwidth = stats[0].lstat.st_maxlen;
        if (f_inode)
        if (f_inode)
-               maxlen += 6;
+               colwidth += 6;
        if (f_size)
        if (f_size)
-               maxlen += 5;
+               colwidth += 5;
        if (f_type)
        if (f_type)
-               maxlen += 1;
-       /* one tab after maxlen */
-       colwidth = (maxlen + 9) & ~0x7;
-       numcols = (80 + colwidth - maxlen) / colwidth;
-       collength = (int)((float)num / (float)numcols + 0.999);
+               colwidth += 1;
+
+       colwidth = (colwidth + TAB) & ~(TAB - 1);
+       if (termwidth < 2 * colwidth) {
+               printscol(stats, num);
+               return;
+       }
 
 
-       for (base = 0; base < collength; base++) {
-               for (offset = 0, i = 0; i < numcols; ++i, offset += collength) {
-                       if (base + offset >= num)
+       numcols = termwidth / colwidth;
+       numrows = num / numcols;
+       if (num % numcols)
+               ++numrows;
+
+       if (f_size && f_total)
+               (void)printf("total %lu\n", f_kblocks ?
+                   howmany(stats[0].lstat.st_btotal, 2) :
+                   stats[0].lstat.st_btotal);
+       for (row = 0; row < numrows; ++row) {
+               endcol = colwidth;
+               for (base = row, chcnt = col = 0; col < numcols; ++col) {
+                       chcnt += printaname(stats + base);
+                       if ((base += numrows) >= num)
                                break;
                                break;
-                       chcnt = printaname(&stats[base + offset]);
-                       if (base + offset + collength < num) {
-                               while (chcnt + 8 < colwidth) {
-                                       (void)putchar('\t');
-                                       chcnt += 8;
-                               }
-                               if (chcnt < colwidth)
-                                       (void)putchar('\t');
-                               chcnt = (chcnt + 8) & ~0x7;
+                       while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
+                               (void)putchar('\t');
+                               chcnt = cnt;
                        }
                        }
+                       endcol += colwidth;
                }
                }
-               if (base + offset < num)
-                       (void)printaname(&stats[base + offset]);
-               (void)printf("\n");
+               putchar('\n');
        }
 }
 
        }
 }
 
@@ -140,52 +155,23 @@ 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 ", f_kblocks ?
+                   howmany(lp->lstat.st_blocks, 2) : lp->lstat.st_blocks);
+       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;
-{
-       struct group *groupentry;
-
-       if ((groupentry = getgrgid((int)gid)) == NULL) {
-               /* can't find group, print out number instead */
-               (void)printf("%-9u ", gid);
-               return;
-       }
-       (void)printf("%-9s", groupentry->gr_name);
-       (void)getgrent();               /* to rewind group file */
-}
-
-printowner(uid)
-       uid_t uid;
-{
-       struct passwd *pwentry;
-
-       if ((pwentry = getpwuid((int)uid)) == NULL) {
-               /* can't find owner, print out number instead */
-               (void)printf("%-9u ", uid);
-               return;
-       }
-       (void)printf("%-9s", pwentry->pw_name);
-       (void)getpwent();
-}
-
 printtime(ftime)
        time_t ftime;
 {
 printtime(ftime)
        time_t ftime;
 {
@@ -198,7 +184,10 @@ printtime(ftime)
                (void)putchar(longstring[i]);
 
 #define        SIXMONTHS       ((DAYSPERNYEAR / 2) * SECSPERDAY)
                (void)putchar(longstring[i]);
 
 #define        SIXMONTHS       ((DAYSPERNYEAR / 2) * SECSPERDAY)
-       if (ftime + SIXMONTHS > time((time_t *)NULL))
+       if (f_sectime)
+               for (i = 11; i < 24; i++)
+                       (void)putchar(longstring[i]);
+       else if (ftime + SIXMONTHS > time((time_t *)NULL))
                for (i = 11; i < 16; ++i)
                        (void)putchar(longstring[i]);
        else {
                for (i = 11; i < 16; ++i)
                        (void)putchar(longstring[i]);
        else {
@@ -209,112 +198,6 @@ printtime(ftime)
        (void)putchar(' ');
 }
 
        (void)putchar(' ');
 }
 
-/*
- * do the permissions printing, passed the mode
- */
-printperms(mode)
-       mode_t mode;
-{
-        /* print type */
-       switch (mode & S_IFMT) {
-       case S_IFDIR:                   /* directory */
-               (void)putchar('d');
-               break;
-       case S_IFCHR:                   /* character special */
-               (void)putchar('c');
-               break;
-       case S_IFBLK:                   /* block special */
-               (void)putchar('b');
-               break;
-       case S_IFREG:                   /* regular */
-               (void)putchar('-');
-               break;
-       case S_IFLNK:                   /* symbolic link */
-               (void)putchar('l');
-               break;
-       case S_IFSOCK:                  /* socket */
-               (void)putchar('s');
-               break;
-#ifdef S_IFIFO
-       case S_IFIFO:                   /* fifo */
-               (void)putchar('p');
-               break;
-#endif
-       default:                        /* unknown */
-               (void)putchar('?');
-               break;
-       }
-       /* usr */
-       if (mode & S_IRUSR)
-               (void)putchar('r');
-       else
-               (void)putchar('-');
-       if (mode & S_IWUSR)
-               (void)putchar('w');
-       else
-               (void)putchar('-');
-       switch (mode & (S_IXUSR | S_ISUID)) {
-       case 0:
-               (void)putchar('-');
-               break;
-       case S_IXUSR:
-               (void)putchar('x');
-               break;
-       case S_ISUID:
-               (void)putchar('S');
-               break;
-       case S_IXUSR | S_ISUID:
-               (void)putchar('s');
-               break;
-       }
-       /* group */
-       if (mode & S_IRGRP)
-               (void)putchar('r');
-       else
-               (void)putchar('-');
-       if (mode & S_IWGRP)
-               (void)putchar('w');
-       else
-               (void)putchar('-');
-       switch (mode & (S_IXGRP | S_ISGID)) {
-       case 0:
-               (void)putchar('-');
-               break;
-       case S_IXGRP:
-               (void)putchar('x');
-               break;
-       case S_ISGID:
-               (void)putchar('S');
-               break;
-       case S_IXGRP | S_ISGID:
-               (void)putchar('s');
-               break;
-       }
-       /* other */
-       if (mode & S_IROTH)
-               (void)putchar('r');
-       else
-               (void)putchar('-');
-       if (mode & S_IWOTH)
-               (void)putchar('w');
-       else
-               (void)putchar('-');
-       switch (mode & (S_IXOTH | S_ISVTX)) {
-       case 0:
-               (void)putchar('-');
-               break;
-       case S_IXOTH:
-               (void)putchar('x');
-               break;
-       case S_ISVTX:
-               (void)putchar('T');
-               break;
-       case S_IXOTH | S_ISVTX:
-               (void)putchar('t');
-               break;
-       }
-}
-
 printtype(mode)
        mode_t mode;
 {
 printtype(mode)
        mode_t mode;
 {