[comp.os.minix] Diffs for more ls enhancements

hgm@beta.UUCP (Harry McGavran) (05/09/87)

Here are the diffs for an improved ls. This one prints multiple columns
sorted DOWN rather than across.

I think it reasonably reliable detects
whether the output is going to the tty or not, in spite of the fact
that isatty(stdout) doesn't seem to work. What I did here is real
hoaky, but until fstat can get fixed or someone finds a better way,
it is what I came up with. When it detects that stdout is not the tty,
it defaults to a single column.

By default it also appends a "*" to the
executables and a "/" to the directories.

I have added to options to disable the above features. "-1" causes single
column output, and "-m" cause multiple column output when stdout is not
to the tty.

"-n" will turn off the addition of "*" and "/".

I make no claims as to the suitability of these changes for anything.

I extend my appreciation to Ed Nather, whose "ls" for MS-DOS gave me
the ideas and some of the code for this. I believe he doesn't mind
redistribution of it, as long as he gets credit.

Hope you find this useful.

To install it, move your ORIGINAL ls source to some system with the
latest version of "patch".  Cut the diffs below out into a file
called "ls.pat". Then type "patch -l ls.c <ls.pat" to get your
new ls.c.

------------------------------Cut here----------------------------------
*** ls.c	Fri May  8 15:28:26 1987
--- ls.new	Fri May  8 15:27:58 1987
***************
*** 11,17 ****
  #define NFILE            256    /* max files in arg list to ls */
  #define MAXPATHLEN       256    /* max chars in a path name */
  #define NDIRBLOCKS        16    /* max length of a directory */
! #define LEGAL      0x1E096DL    /* legal flags to ls */
  
  struct file {
    char *name;
--- 11,17 ----
  #define NFILE            256    /* max files in arg list to ls */
  #define MAXPATHLEN       256    /* max chars in a path name */
  #define NDIRBLOCKS        16    /* max length of a directory */
! #define LEGAL      0x1E396DL    /* legal flags to ls */
  
  struct file {
    char *name;
***************
*** 48,55 ****
  extern char *getuidgid();
  extern int errno;
  
  
- 
  main(argc, argv)
  int argc;
  char *argv[];
--- 48,58 ----
  extern char *getuidgid();
  extern int errno;
  
+ int tty_flag;                   /* flag for whether stdout is tty or not */
+ int cc;                         /* column count */
+ int multcol;                    /* flag for multiple columns */
+ #define COLSIZ  16              /* width of field in multi-column mode */
  
  main(argc, argv)
  int argc;
  char *argv[];
***************
*** 57,64 ****
--- 60,71 ----
    int expand_flag;              /* allows or inhibits directory expansion */
    char *pwfile;
  
+   tty_flag = istty();           /* check stdout before doing ANY output */
+ 
    setbuf(stdout, buffer);
    expand_flag = 1;
+   cc = 0;
+   multcol = 1;
    flags = get_flags(argc, argv);
    expand_args(argc, argv);
  
***************
*** 67,73 ****
          exp_dir(&file[NFILE]);
          expand_flag = 0;
    }
!   if (present('f')) flags = 0x21;       /* -f forces other flags on and off */
    sort(0, nrfiles, expand_flag);
  
    if (present('l')) {
--- 74,84 ----
          exp_dir(&file[NFILE]);
          expand_flag = 0;
    }
!   /* if (present('f')) flags = 0x21; */ /* -f forces other flags on and off */
!   if (present('f')) flags &= (~(0x1A0004L));
!   if (!present('m'))
!         if (!tty_flag)  /* if stdout is a file, use one column */
!                 multcol = 0;
    sort(0, nrfiles, expand_flag);
  
    if (present('l')) {
***************
*** 97,103 ****
    k = argc - topfiles;
    statflag = (topfiles == 0 ? 0 : 1);
    if (present('c') || present('t') || present('u')) statflag = 1;
!   if (present('s') || present('l')) statflag = 1;
    while (k < argc) fill_file("", argv[k++], statflag);
  }
  
--- 108,114 ----
    k = argc - topfiles;
    statflag = (topfiles == 0 ? 0 : 1);
    if (present('c') || present('t') || present('u')) statflag = 1;
!   if (present('s') || present('l') || !present('n')) statflag = 1;
    while (k < argc) fill_file("", argv[k++], statflag);
  }
  
***************
*** 110,116 ****
  {
  /* Sort the elements file[index] ... file[index+count-1] as needed. */
  
!   int i, j, tmp;
  
    if (count == 0) return;
    for (i = index; i < index + count; i++) sort_index[i] = i;
--- 121,128 ----
  {
  /* Sort the elements file[index] ... file[index+count-1] as needed. */
  
!   int i, j, m, n, tmp;
!   short tmp_index[5];
  
    if (count == 0) return;
    for (i = index; i < index + count; i++) sort_index[i] = i;
***************
*** 125,130 ****
--- 137,143 ----
                          sort_index[i] = tmp;
                  }
          }
+ 
  }
  
  
***************
*** 203,232 ****
  {
  /*  If an entry is a file, print it; if a directory, process it. */
  
!   int k, m, nrf;
    struct file *fp;
  
    nrf = nrfiles;
!   for (k = index; k < index + count; k++) {
!         fp = &file[sort_index[k]];
!         if (present('l') || present('s') || present('i'))
!                 if (fp->size == -1L)    /* -1 means stat not done */
!                         if (stat_file(dirname, fp) < 0) continue;
  
!         m = fp->mode & I_TYPE;  /* 'm' may be junk if 'expand' = 0 */
!         if (present('f')) m = I_DIRECTORY;
!         if (m != I_DIRECTORY || present('d') || expand == 0) {
!                 /* List a single line. */
!                 print_line(fp);
!         } else {
!                 /* Expand and print directory. */
!                 exp_dir(fp);
!                 sort(nrf, nrfiles - nrf, 0);
!                 if (topfiles > 1) fprintf(stdout, "\n%s:\n", fp->name);
!                 print_total(nrf, nrfiles - nrf);
!                 print(nrf, nrfiles - nrf, 0, fp->name); /* recursion ! */
!                 nrfiles = nrf;
          }
    }
  }
  
--- 216,254 ----
  {
  /*  If an entry is a file, print it; if a directory, process it. */
  
!   int k, l, m, n, nrf;
    struct file *fp;
  
+   if(present('1') || present('i') || present('s') || present ('l'))
+         n = count;              /* set for 1-column listing */
+   else
+         n = (count + 4)/5;      /* or 5-column */
+ 
    nrf = nrfiles;
!   for (k = index; k < (index+n); k++) {
!         for(l = 0; (k+l) < (index+count); l += n) {
!                 fp = &file[sort_index[k+l]];
!                 if (present('l') || present('s') || present('i'))
!                         if (fp->size == -1L)    /* -1 means stat not done */
!                                 if (stat_file(dirname, fp) < 0) continue;
  
!                 m = fp->mode & I_TYPE;  /* 'm' may be junk if 'expand' = 0 */
!                 if (present('f')) m = I_DIRECTORY;
!                 if (m != I_DIRECTORY || present('d') || expand == 0) {
!                         /* List a single line. */
!                         print_line(fp);
!                 } else {
!                         /* Expand and print directory. */
!                         exp_dir(fp);
!                         sort(nrf, nrfiles - nrf, 0);
!                         if (topfiles > 1) fprintf(stdout, "\n%s:\n", fp->name);
!                         print_total(nrf, nrfiles - nrf);
!                         print(nrf, nrfiles - nrf, 0, fp->name); /* recursion ! */
!                         nrfiles = nrf;
!                 }
          }
+         cc = 0;
+         fputc('\n',stdout);
    }
  }
  
***************
*** 260,266 ****
    }
    statflag = 0;
    if (present('c') || present('t') || present('u')) statflag = 1;
!   if (present('s') || present('l')) statflag = 1;
  
    for (k = 0; k < klim; k++) {
          if (dir[k].inum != 0) {
--- 282,288 ----
    }
    statflag = 0;
    if (present('c') || present('t') || present('u')) statflag = 1;
!   if (present('s') || present('l') || !present('n')) statflag = 1;
  
    for (k = 0; k < klim; k++) {
          if (dir[k].inum != 0) {
***************
*** 355,362 ****
          date(fp->modtime);
    }
  
!         /* Print file name. */
!         fprintf(stdout, "%s\n",fp->name);
  }
  
  
--- 377,404 ----
          date(fp->modtime);
    }
  
!   /* Print file name. */
!   while(cc % COLSIZ) {          /* pad to columnarize */
!         fputc(' ', stdout);
!         cc++;
!   }
! 
!   m = 0;
!   while((c = (fp->name)[m++]) != 0) {
!         fputc(c, stdout);
!         cc++;
!   }
! 
!   if (!present('n')) {          /* add entry type */
!         if ((fp->mode & I_TYPE) == I_DIRECTORY) {
!                 fputc('/', stdout);
!                 cc++;
!         } else if (fp->mode & 0111) {
!                 fputc('*', stdout);
!                 cc++;
!         }
!   }
! 
  }
  
  
***************
*** 452,457 ****
--- 494,504 ----
          ptr++;
  
          while (*ptr != 0) {
+                 if (*ptr == '1') {
+                         multcol = 0;
+                         ptr++;
+                         continue;
+                 }
                  k = *ptr - 'a';
                  t = 1L << k;
                  if (*ptr < 'a' || *ptr > 'z' || (t|LEGAL) != LEGAL) {
***************
*** 470,475 ****
--- 517,524 ----
  present(let)
  char let;
  {
+   if (let == '1')
+         return (!multcol);
    return  (flags >> (let - 'a')) & 01;
  }
  
***************
*** 580,590 ****
    char lbuf[100], *ptr, *ptr1;
    int bin;
  
    if (usrid == lastuid) return(lastname);
    lseek(passwd, 0L, 0);         /* rewind the file */
    linenext = 0;
    linelimit = 0;
!   
    /* Scan the file. */
    while (1) {
          ptr = lbuf;
--- 629,641 ----
    char lbuf[100], *ptr, *ptr1;
    int bin;
  
+   extern long lseek();
+ 
    if (usrid == lastuid) return(lastname);
    lseek(passwd, 0L, 0);         /* rewind the file */
    linenext = 0;
    linelimit = 0;
! 
    /* Scan the file. */
    while (1) {
          ptr = lbuf;
***************
*** 639,642 ****
--- 690,717 ----
    blocks += (fileb + NR_INDIRECTS - 1)/NR_INDIRECTS;
    return(blocks);
  }
+ 
+ 
+ 
+ 
+ 
+ istty()
+ {
+ /* see if stdout is to a tty, since isatty doesn't work on stdout */
+ 
+         long cur_pos, end_file;
+ 
+         extern long lseek();
+ 
+         if ((cur_pos = lseek(1, 0L, 1)) > 0L) {
+                 if ((end_file = lseek(1, 0L, 2)) == 0L)
+                         return (1);
+                 if (end_file > 0L)
+                         lseek(1, cur_pos, 0);
+         }
+ 
+         return (0);
+ 
+ }
+ 
  
-----------------------------Cut here---------------------------------

Harry McGavran
hgm@LANL.GOV
Los Alamos National Laboratory
MS-B294, Group C-8
Los Alamos, New Mexico 87545
505/667-4050