BSD 4_3 release
[unix-history] / usr / src / bin / ls.c
index 51b5aef..cecc1fe 100644 (file)
@@ -1,20 +1,32 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)ls.c        4.8 82/12/03";
-#endif
+static char sccsid[] = "@(#)ls.c       5.6 (Berkeley) 5/12/86";
+#endif not lint
 
 /*
  * ls
  *
 
 /*
  * ls
  *
- * 4.2bsd version for symbolic links and variable length directory entries.
+ * 4.2bsd version for symbolic links, variable length
+ * directory entries, block size in the inode, etc.
  */
  */
-
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/stat.h>
-#include <dir.h>
+#include <sys/dir.h>
 #include <stdio.h>
 #include <sgtty.h>
 
 #include <stdio.h>
 #include <sgtty.h>
 
-#define        kbytes(size)    ((size + 1023) / 1024)
+#define        kbytes(size)    (((size) + 1023) / 1024)
 
 struct afile {
        char    ftype;          /* file type, e.g. 'd', 'c', 'f' */
 
 struct afile {
        char    ftype;          /* file type, e.g. 'd', 'c', 'f' */
@@ -24,6 +36,7 @@ struct afile {
        short   fuid;           /* owner id */
        short   fgid;           /* group id */
        long    fsize;          /* file size */
        short   fuid;           /* owner id */
        short   fgid;           /* group id */
        long    fsize;          /* file size */
+       long    fblks;          /* number of blocks used */
        time_t  fmtime;         /* time (modify or access or create) */
        char    *fname;         /* file name */
        char    *flinkto;       /* symbolic link value */
        time_t  fmtime;         /* time (modify or access or create) */
        char    *fname;         /* file name */
        char    *flinkto;       /* symbolic link value */
@@ -45,6 +58,9 @@ time_t        now, sixmonthsago;
 
 char   *dotp = ".";
 
 
 char   *dotp = ".";
 
+struct winsize win;
+int    twidth;
+
 struct afile *gstat();
 int    fcmp();
 char   *cat(), *savestr();
 struct afile *gstat();
 int    fcmp();
 char   *cat(), *savestr();
@@ -68,11 +84,13 @@ main(argc, argv)
        if (getuid() == 0)
                Aflg++;
        (void) time(&now); sixmonthsago = now - 6L*30L*24L*60L*60L; now += 60;
        if (getuid() == 0)
                Aflg++;
        (void) time(&now); sixmonthsago = now - 6L*30L*24L*60L*60L; now += 60;
+       twidth = 80;
        if (isatty(1)) {
        if (isatty(1)) {
-
                qflg = Cflg = 1;
                (void) gtty(1, &sgbuf);
                qflg = Cflg = 1;
                (void) gtty(1, &sgbuf);
-               if ((sgbuf.sg_flags & XTABS) == 0)
+               if (ioctl(1, TIOCGWINSZ, &win) != -1)
+                       twidth = (win.ws_col == 0 ? 80 : win.ws_col);
+               if ((sgbuf.sg_flags & XTABS) != XTABS)
                        usetabs = 1;
        } else
                usetabs = 1;
                        usetabs = 1;
        } else
                usetabs = 1;
@@ -197,7 +215,7 @@ formatd(name, title)
                printf("total %ld\n", nkb);
        formatf(dfp0, dfplast);
        if (Rflg)
                printf("total %ld\n", nkb);
        formatf(dfp0, dfplast);
        if (Rflg)
-               for (fp = dfplast; fp >= dfp0; fp--) {
+               for (fp = dfplast - 1; fp >= dfp0; fp--) {
                        if (fp->ftype != 'd' ||
                            !strcmp(fp->fname, ".") ||
                            !strcmp(fp->fname, ".."))
                        if (fp->ftype != 'd' ||
                            !strcmp(fp->fname, ".") ||
                            !strcmp(fp->fname, ".."))
@@ -222,7 +240,7 @@ getdir(dir, pfp0, pfplast)
        register struct afile *fp;
        DIR *dirp;
        register struct direct *dp;
        register struct afile *fp;
        DIR *dirp;
        register struct direct *dp;
-       int nkb, nent = 20;
+       int nb, nent = 20;
 
        dirp = opendir(dir);
        if (dirp == NULL) {
 
        dirp = opendir(dir);
        if (dirp == NULL) {
@@ -232,7 +250,7 @@ getdir(dir, pfp0, pfplast)
        }
        fp = *pfp0 = (struct afile *)calloc(nent, sizeof (struct afile));
        *pfplast = *pfp0 + nent;
        }
        fp = *pfp0 = (struct afile *)calloc(nent, sizeof (struct afile));
        *pfplast = *pfp0 + nent;
-       nkb = 0;
+       nb = 0;
        while (dp = readdir(dirp)) {
                if (dp->d_ino == 0)
                        continue;
        while (dp = readdir(dirp)) {
                if (dp->d_ino == 0)
                        continue;
@@ -240,7 +258,7 @@ getdir(dir, pfp0, pfplast)
                    (Aflg == 0 || dp->d_name[1]==0 ||
                     dp->d_name[1]=='.' && dp->d_name[2]==0))
                        continue;
                    (Aflg == 0 || dp->d_name[1]==0 ||
                     dp->d_name[1]=='.' && dp->d_name[2]==0))
                        continue;
-               if (gstat(fp, cat(dir, dp->d_name), Fflg+Rflg, &nkb) == 0)
+               if (gstat(fp, cat(dir, dp->d_name), Fflg+Rflg, &nb) == 0)
                        continue;
                fp->fnum = dp->d_ino;
                fp->fname = savestr(dp->d_name);
                        continue;
                fp->fnum = dp->d_ino;
                fp->fname = savestr(dp->d_name);
@@ -259,16 +277,16 @@ getdir(dir, pfp0, pfplast)
        }
        closedir(dirp);
        *pfplast = fp;
        }
        closedir(dirp);
        *pfplast = fp;
-       return (nkb);
+       return (kbytes(dbtob(nb)));
 }
 
 int    stat(), lstat();
 
 struct afile *
 }
 
 int    stat(), lstat();
 
 struct afile *
-gstat(fp, file, statarg, pnkb)
+gstat(fp, file, statarg, pnb)
        register struct afile *fp;
        char *file;
        register struct afile *fp;
        char *file;
-       int statarg, *pnkb;
+       int statarg, *pnb;
 {
        int (*statf)() = Lflg ? stat : lstat;
        char buf[BUFSIZ]; int cc;
 {
        int (*statf)() = Lflg ? stat : lstat;
        char buf[BUFSIZ]; int cc;
@@ -282,9 +300,12 @@ gstat(fp, file, statarg, pnkb)
                struct stat stb, stb1;
 
                if ((*statf)(file, &stb) < 0) {
                struct stat stb, stb1;
 
                if ((*statf)(file, &stb) < 0) {
-                       fprintf(stderr, "%s not found\n", file);
-                       return (0);
+                       if (statf == lstat || lstat(file, &stb) < 0) {
+                               fprintf(stderr, "%s not found\n", file);
+                               return (0);
+                       }
                }
                }
+               fp->fblks = stb.st_blocks;
                fp->fsize = stb.st_size;
                switch (stb.st_mode & S_IFMT) {
 
                fp->fsize = stb.st_size;
                switch (stb.st_mode & S_IFMT) {
 
@@ -312,6 +333,7 @@ gstat(fp, file, statarg, pnkb)
                                stb = stb1;
                                fp->ftype = 'd';
                                fp->fsize = stb.st_size;
                                stb = stb1;
                                fp->ftype = 'd';
                                fp->fsize = stb.st_size;
+                               fp->fblks = stb.st_blocks;
                        }
                        break;
                }
                        }
                        break;
                }
@@ -326,10 +348,8 @@ gstat(fp, file, statarg, pnkb)
                        fp->fmtime = stb.st_ctime;
                else
                        fp->fmtime = stb.st_mtime;
                        fp->fmtime = stb.st_ctime;
                else
                        fp->fmtime = stb.st_mtime;
-               if (pnkb)
-                       if (fp->ftype != 'b' && fp->ftype != 'c' &&
-                           fp->ftype != 's')
-                               *pnkb += kbytes(fp->fsize);
+               if (pnb)
+                       *pnb += stb.st_blocks;
        }
        return (fp);
 }
        }
        return (fp);
 }
@@ -357,7 +377,7 @@ formatf(fp0, fplast)
                        width = (width + 8) &~ 7;
                else
                        width += 2;
                        width = (width + 8) &~ 7;
                else
                        width += 2;
-               columns = 80 / width;
+               columns = twidth / width;
                if (columns == 0)
                        columns = 1;
        }
                if (columns == 0)
                        columns = 1;
        }
@@ -489,7 +509,7 @@ fmtinum(p)
 {
        static char inumbuf[8];
 
 {
        static char inumbuf[8];
 
-       (void) sprintf(inumbuf, "%5d ", p->fnum);
+       (void) sprintf(inumbuf, "%6d ", p->fnum);
        return (inumbuf);
 }
 
        return (inumbuf);
 }
 
@@ -499,18 +519,7 @@ fmtsize(p)
 {
        static char sizebuf[32];
 
 {
        static char sizebuf[32];
 
-       switch (p->ftype) {
-
-       case 'b':
-       case 'c':
-       case 's':
-               (void) sprintf(sizebuf, "%4ld ", 0);
-               break;
-
-       default:
-               (void) sprintf(sizebuf, "%4ld ", kbytes(p->fsize));
-               break;
-       }
+       (void) sprintf(sizebuf, "%4ld ", kbytes(dbtob(p->fblks)));
        return (sizebuf);
 }
 
        return (sizebuf);
 }
 
@@ -598,40 +607,41 @@ fmtmode(lp, flags)
 #include <utmp.h>
 
 struct utmp utmp;
 #include <utmp.h>
 
 struct utmp utmp;
+#define        NMAX    (sizeof (utmp.ut_name))
+#define SCPYN(a, b)    strncpy(a, b, NMAX)
 
 
-#define NUID   2048
+#define NUID   64      /* power of 2 */
+#define UIDMASK        0x3f
 #define NGID   300
 #define NGID   300
-#define        NMAX    (sizeof (utmp.ut_name))
 
 
-char   names[NUID][NMAX+1];
+struct ncache {
+       int     uid;
+       char    name[NMAX+1];
+} nc[NUID];
+char   outrangename[NMAX+1];
+int    outrangeuid = -1;
 char   groups[NGID][NMAX+1];
 char   groups[NGID][NMAX+1];
+char   outrangegroup[NMAX+1];
+int    outrangegid = -1;
 
 char *
 getname(uid)
 {
        register struct passwd *pw;
 
 char *
 getname(uid)
 {
        register struct passwd *pw;
-       static init;
        struct passwd *getpwent();
        struct passwd *getpwent();
-
-       if (uid >= 0 && uid < NUID && names[uid][0])
-               return (&names[uid][0]);
-       if (init == 2)
+       extern int _pw_stayopen;
+       register int cp;
+
+       _pw_stayopen = 1;
+       cp = uid & UIDMASK;
+       if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0])
+               return (nc[cp].name);
+       pw = getpwuid(uid);
+       if (!pw)
                return (0);
                return (0);
-       if (init == 0)
-               setpwent(), init = 1;
-       while (pw = getpwent()) {
-               if (pw->pw_uid < 0 || pw->pw_uid >= NUID)
-                       continue;
-               if (names[pw->pw_uid][0])
-                       continue;
-               strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
-               if (pw->pw_uid == uid) {
-                       return (&names[uid][0]);
-               }
-       }
-       init = 2;
-       endpwent();
-       return (0);
+       nc[cp].uid = uid;
+       SCPYN(nc[cp].name, pw->pw_name);
+       return (nc[cp].name);
 }
 
 char *
 }
 
 char *
@@ -643,21 +653,41 @@ getgroup(gid)
 
        if (gid >= 0 && gid < NGID && groups[gid][0])
                return (&groups[gid][0]);
 
        if (gid >= 0 && gid < NGID && groups[gid][0])
                return (&groups[gid][0]);
-       if (init == 2)
+       if (gid >= 0 && gid == outrangegid)
+               return (outrangegroup);
+rescan:
+       if (init == 2) {
+               if (gid < NGID)
+                       return (0);
+               setgrent();
+               while (gr = getgrent()) {
+                       if (gr->gr_gid != gid)
+                               continue;
+                       outrangegid = gr->gr_gid;
+                       SCPYN(outrangegroup, gr->gr_name);
+                       endgrent();
+                       return (outrangegroup);
+               }
+               endgrent();
                return (0);
                return (0);
+       }
        if (init == 0)
                setgrent(), init = 1;
        while (gr = getgrent()) {
        if (init == 0)
                setgrent(), init = 1;
        while (gr = getgrent()) {
-               if (gr->gr_gid < 0 || gr->gr_gid >= NGID)
+               if (gr->gr_gid < 0 || gr->gr_gid >= NGID) {
+                       if (gr->gr_gid == gid) {
+                               outrangegid = gr->gr_gid;
+                               SCPYN(outrangegroup, gr->gr_name);
+                               return (outrangegroup);
+                       }
                        continue;
                        continue;
+               }
                if (groups[gr->gr_gid][0])
                        continue;
                if (groups[gr->gr_gid][0])
                        continue;
-               strncpy(groups[gr->gr_gid], gr->gr_name, NMAX);
-               if (gr->gr_gid == gid) {
+               SCPYN(groups[gr->gr_gid], gr->gr_name);
+               if (gr->gr_gid == gid)
                        return (&groups[gid][0]);
                        return (&groups[gid][0]);
-               }
        }
        init = 2;
        }
        init = 2;
-       endgrent();
-       return (0);
+       goto rescan;
 }
 }