[comp.os.minix] nlist path alloca source

walls@attctc.Dallas.TX.US (Monty Walls) (09/30/89)

--------------------------------------------------------------------------

	Here are some odds and ends I ended up writing in the process
of debugging and porting some software to minix.  Included are versions
of nlist(3), path(1), alloca(3).  The alloca version is a reverse
engineered version of the 'atari' alloca that was adapted from
Peter S. Housel's 1.1 pc minix version.


-Monty Walls

---------------------------cut here---------------------------------------
echo x - nlist.c
sed '/^X/s///' > nlist.c << '/'
X/*
X * nlist(filename, nl) - get name list from file
X */
X
X/* author:	Monty Walls
X * written:	9/29/89
X * Copyright:	Copyright (c) 1989 by Monty Walls.
X *		Not derived from licensed software.
X *
X *		Permission to copy and/or distribute granted under the
X *		following conditions:
X *	
X *		1). This notice must remain intact.
X *		2). The author is not responsible for the consequences of use
X *			this software, no matter how awful, even if they
X *			arise from defects in it.
X *		3). Altered version must not be represented as being the 
X *			original software.
X */
X
X#include <stdio.h>
X#include <a.out.h>
X
X#ifndef SEEK_SET
X#define SEEK_SET	0
X#endif
X
Xstatic int
X_nlist(f, nl, ne)
XFILE *f;
Xstruct nlist *nl;
Xlong ne;
X{
X	int todo = 0, names = 0, i;
X	long l;
X	register struct nlist *n;
X	static struct nlist item;
X	
X	/* count elements in users name list */
X	for (n = nl; n->n_name[0] != '\0'; ++n)
X		++todo;
X
X	/* save number of user names so we can test the boundary */
X	names = todo;
X
X	for (l = 0l; l < ne && todo; ++l) {
X		
X		/* read a name list entry in */
X		if (fread(&item, sizeof(struct nlist), 1, f) != 1)
X			return (-1);
X		
X		/* scan users list of names */
X		for (n = nl, i = 0; i < names; ++i, ++n)
X		
X			/* check if we've done this one already,
X			 * if so skip it, else check to see if this 
X			 * one is a match
X			 */
X			if (n->n_value == 0 && strncmp(item.n_name, n->n_name, SYMLENGTH) == 0) {
X				
X				/* ok - so copy the version from the a.out file
X				 * over the top of users version, this way 
X				 * we get all of the info
X				 */
X				memcpy(n, &item, sizeof(struct nlist));
X				
X				/* found this one so decrease count remaining */
X				--todo;
X				/* cancel this scan, we were successfull */
X				break;
X			}
X	}
X	return (0);
X}
X
Xint
Xnlist(filename, nl)
Xchar *filename;
Xstruct nlist *nl;
X{
X	FILE *f;
X	struct exec e;
X	int ret = -1;
X
X	/* verify user's input as OK */	
X	if (nl == (struct nlist *)NULL || filename == (char *)NULL)
X		return (ret);
X		
X	if ((f = fopen(filename, "rb")) == (FILE *)NULL)
X		return (ret);
X		
X	if (fread(&e, sizeof(struct exec), 1, f) == 1) {
X		if (!BADMAG(e) && e.a_syms > 0l)
X			if (fseek(f, A_SYMPOS(e), SEEK_SET) == 0)
X				ret = _nlist(f, nl, e.a_syms);
X	}
X
X	fclose(f);	
X	return (ret);
X}
/
echo x - path.c
sed '/^X/s///' > path.c << '/'
X/*
X * path [ progname .... ]
X *
X * prints out full pathname of progname.
X *
X * base on my vague memory of the SYS 5.3 utility
X *
X */
X
X/* author:	Monty Walls
X * written:	9/29/89
X * Copyright:	Copyright (c) 1989 by Monty Walls.
X *		Not derived from licensed software.
X *
X *		Permission to copy and/or distribute granted under the
X *		following conditions:
X *	
X *		1). This notice must remain intact.
X *		2). The author is not responsible for the consequences of use
X *			this software, no matter how awful, even if they
X *			arise from defects in it.
X *		3). Altered version must not be represented as being the 
X *			original software.
X */
X 
X#include <stdio.h>
X#include <unistd.h>
X
Xextern char *path();
Xextern char *getenv();
X
Xint
Xmain(argc, argv, envp)
Xint argc;
Xchar **argv, **envp;
X{
X	int i;
X	char *syspath = getenv("PATH");
X	char *location;
X	
X#ifdef DEBUG
X	fprintf(stderr, "path = %s\n", syspath);
X#endif		
X	
X	for (i = 1; i < argc; ++i) {
X#ifdef DEBUG
X		fprintf(stderr, "looking at - %s\n", argv[i]);
X#endif		
X		if ((location = path(syspath, argv[i], X_OK)) != (char *)NULL)
X			printf("%s\n", location);
X	}
X}
X
X/*
X * path(pathstring, name, access): make fully qualified pathname for command
X *
X */
X
X#include <sys/param.h>
X
X#ifndef NULL
X#define NULL		(char *)0
X#endif
X
X#ifdef MINIX
X#define SEPARATOR	"/"
X#endif
X
Xextern char *malloc();
Xextern char *strcat();
Xextern access();
X
Xchar *
Xpath(pathstring, name, acc_mode)
Xchar *pathstring;		/* NULL or results of getenv(3) */
Xchar *name;			/* file to locate path to */
Xunsigned acc_mode;		/* how we want to access it (X_OK) */
X{
X	char *s;
X	int i;
X
X	if (pathstring == (char *)NULL) {
X		if (access(name,acc_mode) == 0)
X			return (name);
X		else
X			return ((char *)NULL);
X	}
X	else {
X		if ((s = malloc(MAXPATHLEN)) == (char *)NULL)
X			return ((char *)NULL);
X		for (i = 0; *pathstring ; i = 0) {
X			s[0] = '\0'; /* not to take a chance */
X			while (*pathstring && *pathstring != ':')
X				if (i < MAXPATHLEN) {
X					s[i++] = *pathstring++;
X					s[i] = '\0';
X				}
X				else
X					return ((char *)NULL);
X			if (i > 0)
X				strcat(s,SEPARATOR);
X			strcat(s,name);
X#ifdef DEBUG
X			fprintf(stderr, "trying - %s=%d\n", s, access(s, acc_mode));
X#endif		
X			if (access(s,acc_mode) == 0)
X				return (s);
X			else if (*pathstring)
X				++pathstring;
X		}
X		return ((char *)NULL);
X	}
X			
X}
/
echo x - alloca.s
sed '/^X/s///' > alloca.s << '/'
X.define _alloca
X.globl _alloca, _brksize
X|
X| alloca() for Minix
X| by Peter S. Housel 8/15/88 - in the public domain
X|
X| Changed for 68000 - Terrence W. Holm  &
X|		    - Frans Meulenbroeks  - Nov. 1988
X| Changed from 68000 to pc minix 1.2 compiler - Monty Walls
X|
X|		+------High Memory------+ 64k ( data segment )
X|		|			|
X|		|	(stack)		|
X|		|			|
X|		+=======================+ <- 0[sp), stack grows down
X|		|			|
X|		|	(free)		|
X|		|			|
X|		+=======================+
X|		|			|
X|		|	(heap)		|
X|		|			|
X|	endbss	+=======================+ <- 0[_brksize), heap grows upward
X|		|			|
X|		| (uninitialized data)	|
X|		|			|
X|	edata	+=======================+
X|		|			|
X|		| (initialized data)	|
X|		|			|
X|		|			|
X|	bss	+-------Low Memory------+ 0k
X|
X|
X|	char *
X|	alloca(size)
X|	unsigned size;
X|
X.text
X_alloca:
X	push	bp
X	mov	bp,sp
X	mov	ax,sp		| get current sp value
X	mov	cx,sp		| copy current sp to return register
X|
X|	compute new stack pointer
X|
X	sub	cx,4(bp)	| adjust copy of sp by size
X|
X|	round address to long alignment
X|
X	and	cx,#0xfffc	| round to long address
X|
X|	check if stack and heap collides
X|
X	mov	dx,_brksize	| get highest address for break
X	add	dx,40		| stack cushion (40)
X	cmp	cx,dx		| check for stack over flow
X	jb	_1		| if overflow return NULL
X|
X|	now begin setting up for our return
X|
X	sub	cx,#2		| space for popping of our argument on return
X	mov	bx,2(bp)	| get return address
X	mov	bp,0(bp)	| restore old bp of our caller
X	mov	sp,cx		| insert new sp
X|
X|	alloca return of allocated memory
X|
X	jmp	(bx)		| use our own return
X|
X|	alloca return of NULL
X|
X_1:	xor	ax,ax		| Return NULL
X	mov	sp,bp
X	pop	bp
X	ret
X
/
---------------------------end here---------------------------------------

Monty Walls
Work:						Home:
	MIS Division, Tech. Support			2224 Houston Apt #8
	Oklahoma Tax Commission				Norman, OK, 73701
	2501 N. Lincoln					USA
	OKC, OK, 73194 					Phone - 405-364-5123
	USA						uucp - attctc!walls
	Phone - 405-521-4300