date and time created 89/06/24 18:19:56 by bostic
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sun, 25 Jun 1989 09:19:56 +0000 (01:19 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sun, 25 Jun 1989 09:19:56 +0000 (01:19 -0800)
SCCS-vsn: bin/ls/print.c 5.1

usr/src/bin/ls/print.c [new file with mode: 0644]

diff --git a/usr/src/bin/ls/print.c b/usr/src/bin/ls/print.c
new file mode 100644 (file)
index 0000000..c237c3c
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)print.c    5.1 (Berkeley) %G%";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include <tzfile.h>
+#include "ls.h"
+
+printdir(stats, num)
+       LS *stats;              /* the statted, sorted directory */
+       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;
+       }
+
+       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);
+       }
+
+       /* add fudge factors to max name length */
+       if (f_inode)
+               maxlen += 6;
+       if (f_size)
+               maxlen += 5;
+       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);
+
+       for (base = 0; base < collength; base++) {
+               for (offset = 0, i = 0; i < numcols; ++i, offset += collength) {
+                       if (base + offset >= num)
+                               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;
+                       }
+               }
+               if (base + offset < num)
+                       (void)printaname(&stats[base + offset]);
+               (void)printf("\n");
+       }
+}
+
+/*
+ * print [inode] [size] name
+ * return # of characters printed, no trailing characters
+ */
+printaname(entry)
+       LS *entry;
+{
+       int chcnt = 0;
+
+       if (f_inode)
+               chcnt += printf("%5lu ", entry->lstat.st_ino);
+       if (f_size)
+               chcnt += printf("%4ld ", entry->lstat.st_blocks / 2);
+       chcnt += printf("%s", entry->name);
+       if (f_type)
+               chcnt += printtype(entry->lstat.st_mode);
+       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;
+{
+       int i;
+       char *longstring, *ctime();
+       time_t time();
+
+       longstring = ctime((long *)&ftime);
+       for (i = 4; i < 11; ++i)
+               (void)putchar(longstring[i]);
+
+#define        SIXMONTHS       ((DAYSPERNYEAR / 2) * SECSPERDAY)
+       if (ftime + SIXMONTHS > time((time_t *)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(' ');
+}
+
+/*
+ * 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;
+{
+       switch(mode & S_IFMT) {
+       case S_IFDIR:
+               (void)putchar('/');
+               return(1);
+       case S_IFLNK:
+               (void)putchar('@');
+               return(1);
+       case S_IFSOCK:
+               (void)putchar('=');
+               return(1);
+       }
+       if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
+               (void)putchar('*');
+               return(1);
+       }
+       return(0);
+}
+
+printlink(name)
+       char *name;
+{
+       int lnklen;
+       char path[MAXPATHLEN + 1], *strerror();
+
+       if ((lnklen = readlink(name, path, MAXPATHLEN)) == -1) {
+               (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
+               return;
+       }
+       path[lnklen] = '\0';
+       (void)printf(" -> %s", path);
+}