From: gsm@mendelson.com (Geoffrey S. Mendelson)
Subject: Replacement for listfiles (ls) command.
Organization: Mendelson Computer Consulting
Date: Mon, 13 Apr 92 04:02:08 GMT

Enclosed is a shar archive of a replacement list command for Coherent.
It requires libndir.

This program will do most of the things that ls does except that it does
not sort the listing and the deepest recusrsion it will list (for -R option)
is 12.

This program may not be sold. If distributed, or modified the copyright
notice must stay intact.

Geoff.


#-----------------------------------CUT HERE-----------------------------------
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the currecnt directory owned by you
# with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--   1 root     root        9976 Mar 30  1992 ls2.c
# -rw-r--r--   1 root     root          64 Mar 30  1992 Makefile
#
echo 'x - ls2.c'
if test -f ls2.c; then echo 'shar: not overwriting ls2.c'; else
sed 's/^X//' > ls2.c << '________This_Is_The_END________'
X/*
X
X							l	s	2
X
X					Alternative file lister.
X	
X			Copyright (C) 1992, Geoffrey S. Mendelson.
X	
X						All rights reserved.
X	
X	See help information at the end of the program for more info.
X	
X*/
X#include <stdio.h>
X#include <dirent.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <pwd.h>
X#include <grp.h>
X#include <time.h>
X
X#define MAX_DEPTH 12
X#define VERSION "1.0"
X
Xstruct passwd *passwd_ptr;
Xstruct group *group_ptr;
Xstruct stat *stat_ptr;
Xstruct tm *time_ptr;
X
Xextern char *optarg;
Xextern int optind;	int n_dir;
Xlong blocks;
Xlong bytes;
Xstruct dirent *dir_ptr;
Xchar o;
XFILE *r_dir[MAX_DEPTH+1];
Xchar r_path[MAX_DEPTH+1][128];
Xint recursion;
X
Xchar directory_name[128];
Xchar out_string[255];
Xchar temp_buffer[255];
Xint n_list;
Xint opt_a;
Xint opt_l;
Xint opt_i;
Xint opt_s;
Xint opt_g;
Xint opt_n;
Xint opt_c;
Xint opt_u;
Xint opt_d;
Xint opt_h;
Xint opt_R;
Xint opt_m;
Xlong temp_bytes;
Xint name_list;
Xint current_year;
Xchar months[12][4];
Xchar days[7][4];
X
Xvoid get_dir();
Xvoid print_list(); 
Xvoid help_them();
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int n;
X	int start;
X	int finish;
X	time_t temp_time;
X	
X	time(&temp_time);
X	time_ptr = localtime(&temp_time);
X	current_year = time_ptr->tm_year;
X
X	strcpy(months[0],"Jan");
X	strcpy(months[1],"Feb");
X	strcpy(months[2],"Mar");
X	strcpy(months[3],"Apr");
X	strcpy(months[4],"May");
X	strcpy(months[5],"Jun");
X	strcpy(months[6],"Jul");
X	strcpy(months[7],"Aug");
X	strcpy(months[8],"Sep");
X	strcpy(months[9],"Oct");
X	strcpy(months[10],"Nov");
X	strcpy(months[11],"Dec");
X
X	strcpy(days[0],"Sun");
X	strcpy(days[1],"Mon");
X	strcpy(days[2],"Tue");
X	strcpy(days[3],"Wed");
X	strcpy(days[4],"Thu");
X	strcpy(days[5],"Fri");
X	strcpy(days[6],"Sat");
X							
X	opt_a = 0;
X	opt_l = 0;
X	blocks = 0;
X	bytes = 0;
X	n_list = 0;
X	opt_i = 0;
X	opt_s = 0;
X	opt_g = 0;
X	opt_n = 0;
X	opt_c = 0;
X	opt_u = 0;
X	opt_d = 0;
X	opt_h = 0;
X	opt_R = 0;
X	opt_m = 0;
X	name_list = 0;
X	recursion = 0;
X
X	stat_ptr = malloc(128);
X	if (stat_ptr == NULL)
X		{
X		fprintf(stderr,"ls2: unable to allocate %d bytes.\n",128);
X		exit(222);
X		}
X	
X	
X	while ((o = getopt(argc,argv,"acdpgilnrRstuhm")) != EOF)
X		{
X		switch(o)
X			{
X			case('l'):
X				opt_l = 1;
X				break;
X			case('a'):
X				opt_a = 1;
X				break;
X			case('i'):
X				opt_i = 1;
X				break;
X			case('s'):
X				opt_s = 1;
X				break;
X			case('g'):
X				opt_g = 1;
X				break;
X			case('n'):
X				opt_n = 1;
X				break;
X			case('c'):
X				opt_c = 1;
X				break;
X			case('u'):
X				opt_u = 1;
X				break;
X			case('d'):
X				opt_d = 1;
X				break;
X			case('h'):
X				opt_h = 1;
X				break;
X			case('R'):
X				opt_R = 1;
X				break;
X			case('m'):
X				opt_m = 1;
X				break;
X			case('f'):
X			case('r'):
X			case('t'):
X				fprintf(stderr,"ls2: Unsupported option %c.\n",o);
X				exit(112);
X				break;
X			case('?'):
X			default:
X				fprintf(stderr,"Type %s -h for help.\n",argv[0]);
X				exit(111);
X				break;
X			}
X		}
X		
X	if (opt_h == 1)
X		{
X		help_them();
X		exit(0);
X		}
X	if ((opt_R == 1) && (opt_d == 1))
X		{
X		fprintf(stderr,
X			"ls2: using options R and d together is illogical.\n");
X		exit(120);
X		}
X	if ((opt_c == 1) && (opt_u == 1))
X		{
X		fprintf(stderr,
X			"ls2: using options c and u together is illogical.\n");
X		exit(121);
X		}
X	if (opt_l == 0)
X		{
X		if ((opt_c + opt_m + opt_g + opt_n + opt_u) > 0)
X			{
X			opt_l = 1;
X			}
X		}
X	start = optind;
X	finish = argc;
X	if (optind >= argc) 
X		{
X		get_dir(".");
X		}
X		else
X		{
X		name_list = 1;
X		for (n = start; n < finish; n++)
X			{
X			strcpy(directory_name,argv[n]);
X			get_dir(directory_name); 
X			}
X		}
X	if (opt_l)
X		{
X		printf("%d files, %ld blocks, %ld bytes.\n",n_list,blocks,bytes);
X		}
X	exit(0);
X}
Xvoid get_dir(file_name)
Xchar file_name[];
X{
X	int rc;
X	
X	rc = stat(file_name,stat_ptr);
X	if (rc !=0)
X		{
X		perror(file_name);
X		return;
X		}	
X		if (((stat_ptr->st_mode & S_IFMT) != S_IFDIR)  || (opt_d == 1))
X			{
X			print_list(file_name);
X			}
X			else
X			{
X			r_dir[recursion] = opendir(file_name);
X			if (r_dir[recursion] == NULL)
X				{
X				perror(file_name);
X				return;
X				}
X			n_dir = 0;
X			if ((name_list == 1) || (recursion > 0))
X				{
X				printf("%s:\n",file_name);
X				}
X			for (;;)
X				{
X				dir_ptr = readdir(r_dir[recursion]);
X				if (dir_ptr == NULL) break;
X				if (ferror(r_dir[recursion]) != 0)
X					{
X					perror(file_name);
X					break;
X					}
X				if (opt_a != 1)
X					{
X					if (strncmp(dir_ptr->d_name,".",1) == 0) continue;
X					}
X				strcpy(r_path[recursion],file_name);
X				if (strcmp(r_path[recursion],"/") != 0)
X					{
X					strcat(r_path[recursion],"/");
X					}
X				strcat(r_path[recursion],dir_ptr->d_name);
X				rc = stat(r_path[recursion],stat_ptr);
X				if (rc !=0)
X					{
X					perror(r_path[recursion]);
X					continue;
X					}	
X				print_list(dir_ptr->d_name);
X				}
X			closedir(r_dir[recursion]);
X		}
X}
Xvoid print_list(entry_name)
Xchar entry_name[];
X{
X	int n2;
X	int mode;
X	unsigned char flags[11];
X	long temp_blocks;
X	time_t temp_time;
X	char temp_name[128];
X
X	mode = stat_ptr->st_mode;
X	if ( ((mode & S_IFMT) == S_IFDIR) && (opt_R == 1))
X		{
X		if ((strcmp(entry_name,".") != 0) && (strcmp(entry_name,"..") != 0))
X			{
X/*
X			printf("subdirectory level %d %s (%s):\n",
X					recursion,entry_name,r_path[recursion]);
X*/
X			if (recursion >= MAX_DEPTH)
X				{
X				fprintf(stderr,
X					"ls2: directory recursion more than %d.\n",MAX_DEPTH);
X				return;
X				}
X			strcpy(temp_name,r_path[recursion]);
X			recursion++;
X			get_dir(temp_name);
X			recursion--;
X			if (recursion < 0) 
X				{
X				fprintf(stderr,"ls2.: oops, recursion is less than 0.\n");
X				exit(69);
X				}
X			return;
X			}
X		}
X	bytes = bytes + stat_ptr->st_size;
X	temp_bytes = stat_ptr->st_size;
X	temp_bytes = temp_bytes + 511;
X	temp_blocks = temp_bytes / 512;
X	blocks = blocks + temp_blocks;
X		
X	for (n2 =0; n2 < 10; n2++)
X		{
X		flags[n2] = '-';
X		}
X	flags[10] = 0x00;
X	strcpy(out_string,"");
X	if (opt_i == 1)
X		{
X		sprintf(temp_buffer,"%6d ",stat_ptr->st_ino);
X		strcat(out_string,temp_buffer);			
X		}
X	if (opt_s == 1)
X		{	
X		sprintf(temp_buffer,"%6ld ",temp_blocks);
X		strcat(out_string,temp_buffer);
X		}			
X	if (opt_l == 1)
X		{
X		if (opt_m == 1)
X			{
X			sprintf(temp_buffer,"%07o ",mode);
X			}
X			else
X			{
X			if ((mode & S_IFMT) == S_IFDIR)  flags[0] = 'd';
X			if ((mode & S_IFMT) == S_IFCHR)  flags[0] = 'c';
X			if ((mode & S_IFMT) == S_IFBLK)  flags[0] = 'b';
X			if ((mode & S_IFMT) == S_IFREG)  flags[0] = '-';
X			if ((mode & S_IFMT) == S_IFPIP)  flags[0] = 'p';
X
X			if ((mode & 00400) != 0) flags[1] = 'r';
X			if ((mode & 00200) != 0) flags[2] = 'w';
X			if ((mode & 00100) != 0) flags[3] = 'x';
X			if ((mode & 04000) != 0) flags[3] = 's';
X
X			if ((mode & 00040) != 0) flags[4] = 'r';
X			if ((mode & 00020) != 0) flags[5] = 'w';
X			if ((mode & 00010) != 0) flags[6] = 'x';
X			if ((mode & 02000) != 0) flags[6] = 's';
X
X			if ((mode & 00004) != 0) flags[7] = 'r';
X			if ((mode & 00002) != 0) flags[8] = 'w';
X			if ((mode & 00001) != 0) flags[9] = 'x';
X			if ((mode & 01000) != 0) flags[9] = 's';
X		
X			sprintf(temp_buffer,"%s ",flags);
X			}
X		strcat(out_string,temp_buffer);
X		
X		sprintf(temp_buffer,"%2d ",stat_ptr->st_nlink);
X		strcat(out_string,temp_buffer);
X					
X		if (opt_g != 1)
X			{
X			if (opt_n == 1)
X				{
X				sprintf(temp_buffer,"%8d ",stat_ptr->st_uid);
X				}
X				else
X				{
X				passwd_ptr = getpwuid(stat_ptr->st_uid);
X				if (passwd_ptr == NULL)
X					{
X					sprintf(temp_buffer,"?%-7d ",stat_ptr->st_uid);
X					}
X					else
X					{
X					sprintf(temp_buffer,"%-8s ",passwd_ptr->pw_name);
X					}
X				}
X			strcat(out_string,temp_buffer);
X			}		
X		if (opt_n == 1)
X			{
X			sprintf(temp_buffer,"%8d ",stat_ptr->st_gid);
X			}
X			else
X			{
X			group_ptr = getgrgid(stat_ptr->st_gid);
X			if (group_ptr == NULL)
X				{
X				sprintf(temp_buffer,"?%-7d ",stat_ptr->st_gid);
X				}
X				else
X				{
X				sprintf(temp_buffer,"%-8s ",group_ptr->gr_name);
X				}
X			}
X		strcat(out_string,temp_buffer);
X
X		if (((mode & S_IFMT) == S_IFCHR) || ((mode & S_IFMT) == S_IFBLK))
X			{
X			sprintf(temp_buffer," %3d  %3d ",
X				major(stat_ptr->st_rdev),
X				minor(stat_ptr->st_rdev));
X			}
X			else
X			{
X			sprintf(temp_buffer,"%9ld ",stat_ptr->st_size);
X			}
X		strcat(out_string,temp_buffer);			
X		
X		temp_time = stat_ptr->st_mtime;
X		if (opt_u == 1) temp_time = stat_ptr->st_atime;
X		if (opt_c == 1) temp_time = stat_ptr->st_ctime;
X
X		time_ptr = localtime(&temp_time);
X		if (time_ptr->tm_year == current_year)
X			{
X
X			sprintf(temp_buffer,
X					"%3s %3s %2d  %02d:%02d ",
X					days[time_ptr->tm_wday],
X					months[time_ptr->tm_mon],
X					time_ptr->tm_mday,
X					time_ptr->tm_hour,
X					time_ptr->tm_min);
X			}
X			else
X			{
X
X			sprintf(temp_buffer,
X					"%3s %3s %2d   %04d ",
X					days[time_ptr->tm_wday],
X					months[time_ptr->tm_mon],
X					time_ptr->tm_mday,
X					(time_ptr->tm_year+1900));
X
X			}
X		strcat(out_string,temp_buffer);
X
X		}
X	strcat(out_string,entry_name);
X	printf("%s\n",out_string);
X	n_list++;
X	return;
X}
Xvoid help_them()
X{
X	printf("ls2: Alternative file lister Version %s.\n",VERSION);
X	printf(
X	"Copyright (C) 1992, Geoffrey S. Mendelson, All rights reserved.\n");
X	printf(
X"This program performs most of the functions of ls, but is not limited\n");
X	printf("to 255 files in a directory.\n");
X	printf(
X	"Not all the options of ls are supported, and the listings are unsorted.\n");
X	printf("\nOptions supported:\n");
X	printf(
X"a    List all files (files begining with a dot \".\" are normally not listed.)\n");
X	printf("c    List creation time (implies option l).\n");
X	printf("d    List directories as files.\n");
X	printf("g    List only group name (implies option l).\n");
X	printf("h    Show this information.\n");
X	printf("i    Show inode number.\n");
X	printf("l    Show lots of information (same as ls).\n");
X	printf("m    Show mode as an octal number. (implies option l).\n");
X	printf("n    Show owner and group as numbers. (implies option l).\n");
X	printf("s    Show size in blocks.\n");
X	printf("u    List time of last use (implies option l).\n");
X	printf("R    List subdirectory contents (illogical with option d).\n");
X	printf("          Maximum recursion depth including first is %d.\n",
X					MAX_DEPTH);
X	return;
X}
________This_Is_The_END________
if test `wc -l < ls2.c` -ne 490; then
  echo 'shar: ls2.c was damaged during transit (should have been 490 lines)'
fi
fi
echo 'x - Makefile'
if test -f Makefile; then echo 'shar: not overwriting Makefile'; else
sed 's/^X//' > Makefile << '________This_Is_The_END________'
Xls2:	ls2.c
X		cc -A ls2.c -lndir
X
Xinstall:	ls2
X		cp ls2 /usr/bin
________This_Is_The_END________
if test `wc -l < Makefile` -ne 5; then
  echo 'shar: Makefile was damaged during transit (should have been 5 lines)'
fi
fi

-- 
Copyright (C) 1992, Geoffrey S. Mendelson.              All Rights Reserved.
Except for usenet followups, may not be reproduced without permsission. 
----------------------------------------------------------------------------
|                   |  Computer Software Consulting    |                   |
----------------------------------------------------------------------------
Geoffrey S. Mendelson                    Israel
geoffrey@mendelson.com                          or
mwcbbs!mailgsm!geoffrey                            Bust!
(215) 242-8712                          Looks like August now :-(