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