[net.sources] ls.c hack for 4.2BSD and System V

jlw@ariel.UUCP (05/13/84)

Here is a hack for ls.c in 4.2bsd (or others of that ilk)
(sccsid = 4.5) and System V (sccsid = 1.12).
This fixes what I condsider to be brain damage for both
bsd ls.c and System V ls.c although the forms of brain damage
are different in the two cases.
For bsd just replace the tail of the file from the first line below
the cut to the end with the code provided.
For System V do the following:

1. change the declaration tbufu[15],tbufg[16] -> *tbufu,*tbufg
2. put in a foreward declaration:
	char *getname(),*getgroup();
	in routine pentry(ap)
3. change the calls from:
	if(getname(p->luid, tbufu, 0)==0)
	and
	if(getname(p->lgid, tbufg, 1)==0)
	to
	if((tbufu = getname(p->luid)) != (char *)NULL)
	and
	if((tbufg = getgroup(p->lgid)) != (char *)NULL)
	respectively.
4. delete the getname routine in its entirety.
5. concatenate these hacks to the end of the file.

Enjoy.



					Joseph L. Wood, III
					AT&T Information Systems
					Laboratories, Holmdel
					(201) 834-3759
					ariel!jlw

-----------------cut here------------------------------
/* rest should be done with nameserver or database */

#include <pwd.h>
#include <grp.h>
#include <utmp.h>

struct	utmp utmp;

#define NUID	1024
#define NGID	256
#define	NMAX	(sizeof (utmp.ut_name))

struct	hash {
		short	id;	/* user or group id */
		char	*name;	/* pointer to name */
		};


char	buf[(NUID+NGID)*(NMAX+1)];
char	*bufptr = buf;
struct	hash	namtab[NUID];
struct	hash	grptab[NGID];

char *
getname(uid)
{
	register struct passwd *pw;
	static init;
	char *np;
	struct passwd *getpwent();
	char *lookup();
	void install();

	switch (init){

	case 0:	/* first time */
		setpwent();
		install( 0, "root", namtab, NUID );
		init = 1;
	case 1:	/* regular entry */
		if( (np = lookup( uid, namtab, NUID )) != (char *)NULL )
			return np;
		while (pw = getpwent()) {
			if (pw->pw_uid < 0)
				continue;
			install( pw->pw_uid, pw->pw_name, namtab, NUID );
			if(pw->pw_uid == uid)
				return lookup( uid, namtab, NUID );
		}
		/* and fall through */
	case 2:	/* fall out of password file */
		if( init == 1 ){
			init = 2;
			endpwent();
		}
		return lookup( uid, namtab, NUID );
	default:
		printf(stderr, "ls: Bad case in getname\n");
		exit(1);
	}
}

char *
getgroup(gid)
{
	register struct group *gr;
	static init;
	char *np;
	struct group *getgrent();
	char *lookup();
	void install();

	switch (init){

	case 0:	/* first time */
		setgrent();
		install( 0, "root", grptab, NGID );
		init = 1;
	case 1:	/* regular entry */
		if( (np = lookup( gid, grptab, NGID )) != (char *)NULL )
			return np;
		while (gr = getgrent()) {
			if (gr->gr_gid < 0)
				continue;
			install( gr->gr_gid, gr->gr_name, grptab, NGID );
			if (gr->gr_gid == gid)
				return lookup( gid, grptab, NGID );
		}
		/* and fall through */
	case 2:	/* fall out of group file */
		if( init == 1 ){
			init = 2;
			endgrent();
		}
		return lookup( gid, grptab, NGID );
	default:
		printf(stderr, "ls: Bad case in getgroup\n");
		exit(1);
	}
}

#define HASHIT(a)	((maxtab/256)*((a>>8)+(a&0177)))

void
install( id, name, tab, maxtab )
short id;
char *name;
struct hash tab[];
short maxtab;
{

	short hid, thid;

	hid = thid = HASHIT(id);

	if( hid < 0 || hid > maxtab ){
		printf( stderr, "ls: name hashing out of range uid = %d, hashed uid =%d\n", id, hid );
		exit(1);
	}

	do {
		if(tab[hid].id == 0){
			tab[hid].id = id;
			tab[hid].name = bufptr;
			(void) strcpy( bufptr, name);
			bufptr += strlen(tab[hid].name) + 1;
			break;
		}
		if( tab[hid].id == id )
			break;	/* per current custom save only first name */
		if(++hid == maxtab)
			hid = 1;
	} while(hid != thid);
}

char *
lookup( id, tab, maxtab )
short id;
struct hash tab[];
short maxtab;
{

	short hid, thid;

	hid = thid = HASHIT(id);

	if(id == 0)
		return tab[hid].name;
	do {
		if(tab[hid].id == id)
		{
			return tab[hid].name;
		}
		if(tab[hid].id == 0)
			break;
		if(++hid == maxtab)
			hid = 1;
	} while(hid != thid);
	return (char *)NULL;
}