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