mirror of https://github.com/GnoConsortium/gno.git
initial checkin of libc source and tests
This commit is contained in:
parent
cb5fd8e82d
commit
596add410c
|
@ -0,0 +1,19 @@
|
|||
List of Contributers
|
||||
====================
|
||||
|
||||
$Id: Contributers,v 1.1 1997/02/28 05:12:39 gdr Exp $
|
||||
|
||||
The following people and organizations have contributed, knowingly or
|
||||
otherwise, to the code in this library. Some other contributions were
|
||||
necessarily anonymous, as they were derived from code fragments for which
|
||||
no author information was available:
|
||||
|
||||
Jawaid Bazyar
|
||||
Soenke Behrens
|
||||
Douglas Gwyn
|
||||
Devin Reade
|
||||
Derek Taubert
|
||||
Phillip Vandry
|
||||
|
||||
The Byte Works, Inc.
|
||||
University of California, Berkeley.
|
|
@ -0,0 +1,59 @@
|
|||
#
|
||||
# This is the top-level makefile for libc, GNO v2.0.6
|
||||
#
|
||||
# dmake is too bloated right now to due recursive makes well, so before
|
||||
# you run make in this directory, ensure you run make in the following
|
||||
# directories:
|
||||
# gen, gno, locale, stdio, stdlib, string, sys
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:39 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../const.mk
|
||||
|
||||
LIBC_OBJ = \
|
||||
sys/exec.o \
|
||||
sys/syscall.o \
|
||||
sys/trap.o \
|
||||
gno/gnocmd.o \
|
||||
gno/gnomisc.o \
|
||||
gno/gsstring.o \
|
||||
gno/map.o \
|
||||
gno/parsearg.o \
|
||||
gno/stack.o \
|
||||
gen/basename.o \
|
||||
gen/bmem.o \
|
||||
gen/compat.o \
|
||||
gen/crypt.o \
|
||||
gen/crypta.o \
|
||||
gen/dirent.o \
|
||||
gen/err.o \
|
||||
gen/fnmatch.o \
|
||||
gen/getcwd.o \
|
||||
gen/getgrent.o \
|
||||
gen/getpass.o \
|
||||
gen/getpwent.o \
|
||||
gen/getttyent.o \
|
||||
gen/hostname.o \
|
||||
gen/oldlog.o \
|
||||
gen/popen.o \
|
||||
gen/pwcache.o \
|
||||
gen/scandir.o \
|
||||
gen/setjmp.o \
|
||||
gen/sleep.o \
|
||||
gen/syslog.o \
|
||||
gen/tty.o \
|
||||
gen/utime.o \
|
||||
locale/table.o \
|
||||
stdio/mktemp.o \
|
||||
stdio/perror.o \
|
||||
stdio/tempnam.o \
|
||||
stdlib/environ.o \
|
||||
stdlib/getopt.o \
|
||||
stdlib/getsubopt.o \
|
||||
string/case.o \
|
||||
string/str.o
|
||||
|
||||
libc: $(LIBC_OBJ)
|
||||
$(RM) -f $@
|
||||
$(MAKELIB) $(MAKELIBFLAGS) -l $@ $(LIBC_OBJ)
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# Makefile for libc/gen.
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJ_ASM = crypta.o setjmp.o syslog.o
|
||||
OBJ_C = basename.o bmem.o compat.o crypt.o dirent.o err.o fnmatch.o getcwd.o \
|
||||
getgrent.o getpass.o getpwent.o getttyent.o hostname.o oldlog.o \
|
||||
popen.o pwcache.o scandir.o sleep.o tty.o utime.o
|
||||
NOT_YET = fts.o
|
||||
|
||||
OBJS = $(OBJ_ASM) $(OBJ_C)
|
||||
|
||||
default: $(OBJS)
|
||||
asm: $(OBJ_ASM)
|
||||
c: $(OBJ_C)
|
||||
|
||||
.INCLUDE: ../rules.mk
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* These routines were written by Devin Reade for GNO v2.0.4.
|
||||
*
|
||||
* $Id: basename.c,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tabs every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* basename
|
||||
*
|
||||
* returns the filename component of <path>. If <path> contains colons,
|
||||
* they are assumed to be the directory separators, otherwise any '/' is
|
||||
* assumed to be a directory separator.
|
||||
*
|
||||
* If no directory separators are found, then the full path is returned.
|
||||
*
|
||||
* No check is done as to whether the pathname is valid on the any
|
||||
* given filesystem.
|
||||
*/
|
||||
|
||||
char *
|
||||
basename (const char *path) {
|
||||
char delim, *p;
|
||||
|
||||
delim = strchr(path,':') ? ':' : '/';
|
||||
p = strrchr(path,delim);
|
||||
return p ? p+1 : path;
|
||||
}
|
||||
|
||||
/*
|
||||
* dirname
|
||||
*
|
||||
* Returns a pointer to an internal buffer that contains a string that
|
||||
* matches the directory component
|
||||
* of <path>. If <path> contains at least one ':', then it is assumed
|
||||
* that colons are directory separators, otherwise any '/' character
|
||||
* is treated as a directory separator.
|
||||
*
|
||||
* If <path> contains no pathname separators, then dirname() will
|
||||
* return an empty (zero-length) string.
|
||||
*
|
||||
* No check is done as to whether the pathname is valid on the any
|
||||
* given filesystem.
|
||||
*/
|
||||
|
||||
char *
|
||||
dirname (const char *path)
|
||||
{
|
||||
char delim, *p;
|
||||
size_t len;
|
||||
static char dir[PATH_MAX];
|
||||
|
||||
len = strlen(path);
|
||||
if (len >= PATH_MAX) {
|
||||
len = PATH_MAX -1;
|
||||
strncpy(dir,path,len);
|
||||
dir[len] = '\0';
|
||||
} else {
|
||||
strcpy(dir, path);
|
||||
}
|
||||
delim = strchr(dir,':') ? ':' : '/';
|
||||
p = strrchr(dir,delim);
|
||||
if (p == NULL) {
|
||||
*dir = '\0';
|
||||
} else {
|
||||
*p = '\0';
|
||||
}
|
||||
return dir;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* $Id: bmem.c,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tabs every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
bzero(void *buf, size_t len) {
|
||||
memset(buf, 0, len);
|
||||
}
|
||||
|
||||
void
|
||||
bcopy(const void *src, const void *dest, size_t len) {
|
||||
memmove(dest, src, len);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* These functions really belong in a separate library, libcompat, if
|
||||
* we're trying to be BSD-ish. They are all obsolete functions.
|
||||
*
|
||||
* $Id: compat.c,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tabs every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <sgtty.h>
|
||||
|
||||
int
|
||||
gtty(int filedes, struct sgttyb *argp) {
|
||||
return ioctl(filedes,TIOCGETP,argp);
|
||||
}
|
||||
|
||||
int
|
||||
stty (int filedes, struct sgttyb *argp) {
|
||||
return ioctl(filedes,TIOCSETP,argp);
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* From Andy Tanenbaum's book "Computer Networks", rewritten in C.
|
||||
*
|
||||
* Many performance modifications made
|
||||
* January 19-22, 1992 by Jawaid Bazyar
|
||||
* Copyright 1992-1997, Procyon Inc.
|
||||
*
|
||||
* $Id: crypt.c,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
/* segment "libc_gen__"; *//* don't segment this until crypt.asm is done */
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* These symbols have been moved to or are referenced from crypta.asm */
|
||||
#ifndef NOTDEFINED
|
||||
#define f(i,key,a,x) __crypt_f(i, key, a, x)
|
||||
#define transpose(data,t,n) __crypt_transpose(data, t, n)
|
||||
#define rotate(key) __crypt_rotate(key)
|
||||
#define s_boxes __crypt_s_boxes
|
||||
#define rots __crypt_rots
|
||||
#endif
|
||||
|
||||
struct block {
|
||||
unsigned char b_data[64];
|
||||
};
|
||||
|
||||
struct ordering {
|
||||
unsigned char o_data[64];
|
||||
};
|
||||
|
||||
static struct block key; /* gdr added "static" */
|
||||
|
||||
static struct ordering InitialTr = {
|
||||
58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
|
||||
62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
|
||||
57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
|
||||
61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
|
||||
};
|
||||
|
||||
static struct ordering FinalTr = {
|
||||
40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
|
||||
38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
|
||||
36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
|
||||
34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25,
|
||||
};
|
||||
|
||||
static struct ordering swap = {
|
||||
33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
|
||||
49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
|
||||
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
|
||||
};
|
||||
|
||||
static struct ordering KeyTr1 = {
|
||||
57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
|
||||
10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
|
||||
63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
|
||||
14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4,
|
||||
};
|
||||
|
||||
struct ordering KeyTr2 = {
|
||||
14,17,11,24, 1, 5, 3,28,15, 6,21,10,
|
||||
23,19,12, 4,26, 8,16, 7,27,20,13, 2,
|
||||
41,52,31,37,47,55,30,40,51,45,33,48,
|
||||
44,49,39,56,34,53,46,42,50,36,29,32,
|
||||
};
|
||||
|
||||
static struct ordering etr = {
|
||||
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
|
||||
8, 9,10,11,12,13,12,13,14,15,16,17,
|
||||
16,17,18,19,20,21,20,21,22,23,24,25,
|
||||
24,25,26,27,28,29,28,29,30,31,32, 1,
|
||||
};
|
||||
|
||||
struct ordering ptr = {
|
||||
16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
|
||||
2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,
|
||||
};
|
||||
|
||||
char s_boxes[8][64] = {
|
||||
{ 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
|
||||
0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
|
||||
4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
|
||||
15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
|
||||
},
|
||||
|
||||
{ 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
|
||||
3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
|
||||
0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
|
||||
13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
|
||||
},
|
||||
|
||||
{ 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
|
||||
13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
|
||||
13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
|
||||
1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
|
||||
},
|
||||
|
||||
{ 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
|
||||
13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
|
||||
10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
|
||||
3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
|
||||
},
|
||||
|
||||
{ 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
|
||||
14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
|
||||
4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
|
||||
11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
|
||||
},
|
||||
|
||||
{ 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
|
||||
10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
|
||||
9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
|
||||
4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
|
||||
},
|
||||
|
||||
{ 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
|
||||
13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
|
||||
1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
|
||||
6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
|
||||
},
|
||||
|
||||
{ 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
|
||||
1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
|
||||
7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
|
||||
2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
|
||||
},
|
||||
};
|
||||
|
||||
int rots[] = {
|
||||
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
|
||||
};
|
||||
|
||||
/* transpose, rotate, and f were rewritten in assembly- see crypta.asm */
|
||||
#ifndef NOTDEFINED
|
||||
void __crypt_f __P((int i, struct block *key, struct block *a, struct block *x));
|
||||
void __crypt_transpose __P((struct block *data, struct ordering *t, int n));
|
||||
void __crypt_rotate __P((struct block *key));
|
||||
#else
|
||||
|
||||
static
|
||||
transpose(data, t, n)
|
||||
register struct block *data;
|
||||
register struct ordering *t;
|
||||
register int n;
|
||||
{
|
||||
struct block x;
|
||||
|
||||
memcpy(&x,data,sizeof(struct block));
|
||||
/* x = *data; you can't do that in C!!! */
|
||||
|
||||
while (n-- > 0) {
|
||||
data->b_data[n] = x.b_data[t->o_data[n] - 1];
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
rotate(key)
|
||||
register struct block *key;
|
||||
{
|
||||
register unsigned char *p = key->b_data;
|
||||
register unsigned char *ep = &(key->b_data[55]);
|
||||
int data0 = key->b_data[0], data28 = key->b_data[28];
|
||||
|
||||
while (p++ < ep) *(p-1) = *p;
|
||||
key->b_data[27] = data0;
|
||||
key->b_data[55] = data28;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct ordering *EP = &etr;
|
||||
|
||||
#ifdef NOTDEFINED
|
||||
static
|
||||
f(i, key, a, x)
|
||||
struct block *key, *a;
|
||||
register struct block *x;
|
||||
{
|
||||
struct block e, ikey, y;
|
||||
int k;
|
||||
register unsigned char *p, *q, *r;
|
||||
|
||||
memcpy(&e,a,sizeof(struct block));
|
||||
/* e = *a; */
|
||||
transpose(&e, EP, 48);
|
||||
for (k = rots[i]; k; k--) rotate(key);
|
||||
memcpy(&ikey,key,sizeof(struct block));
|
||||
/* ikey = *key; */
|
||||
transpose(&ikey, &KeyTr2, 48);
|
||||
p = &(y.b_data[48]);
|
||||
q = &(e.b_data[48]);
|
||||
r = &(ikey.b_data[48]);
|
||||
while (p > y.b_data) {
|
||||
*--p = *--q ^ *--r;
|
||||
}
|
||||
q = x->b_data;
|
||||
for (k = 0; k < 8; k++) {
|
||||
register int xb, r;
|
||||
|
||||
r = *p++ << 5;
|
||||
r += *p++ << 3;
|
||||
r += *p++ << 2;
|
||||
r += *p++ << 1;
|
||||
r += *p++;
|
||||
r += *p++ << 4;
|
||||
|
||||
xb = s_boxes[k][r];
|
||||
|
||||
*q++ = (xb >> 3) & 1;
|
||||
*q++ = (xb>>2) & 1;
|
||||
*q++ = (xb>>1) & 1;
|
||||
*q++ = (xb & 1);
|
||||
}
|
||||
transpose(x, &ptr, 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
setkey(register const char *k)
|
||||
{
|
||||
|
||||
key = *((struct block *) k);
|
||||
transpose(&key, &KeyTr1, 56);
|
||||
}
|
||||
|
||||
void
|
||||
encrypt(char *blck, int edflag)
|
||||
{
|
||||
register struct block *p = (struct block *) blck;
|
||||
register int i;
|
||||
|
||||
transpose(p, &InitialTr, 64);
|
||||
for (i = 15; i>= 0; i--) {
|
||||
int j = edflag ? i : 15 - i;
|
||||
register int k;
|
||||
struct block b, x;
|
||||
|
||||
memcpy(&b,p,sizeof(struct block));
|
||||
/* b = *p; */
|
||||
for (k = 31; k >= 0; k--) {
|
||||
p->b_data[k] = b.b_data[k + 32];
|
||||
}
|
||||
f(j, &key, p, &x);
|
||||
for (k = 31; k >= 0; k--) {
|
||||
p->b_data[k+32] = b.b_data[k] ^ x.b_data[k];
|
||||
}
|
||||
}
|
||||
transpose(p, &swap, 64);
|
||||
transpose(p, &FinalTr, 64);
|
||||
}
|
||||
|
||||
char *
|
||||
crypt(register const char *pw, const char *salt)
|
||||
{
|
||||
/* Unfortunately, I had to look at the sources of V7 crypt.
|
||||
There was no other way to find out what this routine
|
||||
actually does.
|
||||
*/
|
||||
|
||||
char pwb[66];
|
||||
static char result[16];
|
||||
register char *p = pwb;
|
||||
struct ordering new_etr;
|
||||
register int i;
|
||||
char *pw2;
|
||||
|
||||
while (*pw && p < &pwb[64]) {
|
||||
register int j = 7;
|
||||
|
||||
while (j--) {
|
||||
*p++ = (*pw >> j) & 01;
|
||||
}
|
||||
pw++;
|
||||
*p++ = 0;
|
||||
}
|
||||
while (p < &pwb[64]) *p++ = 0;
|
||||
|
||||
setkey(p = pwb);
|
||||
|
||||
while (p < &pwb[66]) *p++ = 0;
|
||||
|
||||
new_etr = etr;
|
||||
EP = &new_etr;
|
||||
for (i = 0; i < 2; i++) {
|
||||
register char c = *salt++;
|
||||
register int j;
|
||||
|
||||
result[i] = c;
|
||||
if ( c > 'Z') c -= 6 + 7 + '.'; /* c was a lower case letter */
|
||||
else if ( c > '9') c -= 7 + '.';/* c was upper case letter */
|
||||
else c -= '.'; /* c was digit, '.' or '/'. */
|
||||
/* now, 0 <= c <= 63 */
|
||||
for (j = 0; j < 6; j++) {
|
||||
if ((c >> j) & 01) {
|
||||
int t = 6*i + j;
|
||||
int temp = new_etr.o_data[t];
|
||||
new_etr.o_data[t] = new_etr.o_data[t+24];
|
||||
new_etr.o_data[t+24] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result[1] == 0) result[1] = result[0];
|
||||
|
||||
for (i = 0; i < 25; i++) encrypt(pwb,0);
|
||||
EP = &etr;
|
||||
|
||||
p = pwb;
|
||||
pw2 = result+2;
|
||||
while (p < &pwb[66]) {
|
||||
register int c = 0;
|
||||
register int j = 6;
|
||||
|
||||
while (j--) {
|
||||
c <<= 1;
|
||||
c |= *p++;
|
||||
}
|
||||
c += '.'; /* becomes >= '.' */
|
||||
if (c > '9') c += 7; /* not in [./0-9], becomes upper */
|
||||
if (c > 'Z') c += 6; /* not in [A-Z], becomes lower */
|
||||
*pw2++ = c;
|
||||
}
|
||||
*pw2 = 0;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
*
|
||||
* Performance modifications to crypt.c routines.
|
||||
* 19-22 January 1992 by Jawaid Bazyar
|
||||
* Copyright 1992, Procyon Inc.
|
||||
*
|
||||
* $Id: crypta.asm,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*
|
||||
* Because of the four storage blocks listed below (copyOfData, e, ikey, and
|
||||
* yb), this doesn't seem to be compatible with the large memory model.
|
||||
* This should be changed. These routines should also be placed in the
|
||||
* libc_gen__ load segment.
|
||||
*
|
||||
mcopy crypta.mac
|
||||
case on
|
||||
|
||||
* void __crypt_transpose (struct block *data, struct ordering *t, int n);
|
||||
__crypt_transpose START
|
||||
subroutine (2:n,4:t,4:data),2
|
||||
|
||||
ldy #62
|
||||
lp lda [data],y
|
||||
sta copyOfData,y
|
||||
dey2
|
||||
bpl lp
|
||||
lda #0 ; clear out hi-byte of A
|
||||
short m
|
||||
|
||||
lp2 ldy n
|
||||
beq donelp2
|
||||
dec n
|
||||
ldy n
|
||||
lda [t],y
|
||||
dec a
|
||||
tay
|
||||
lda copyOfData,y
|
||||
ldy n
|
||||
sta [data],y
|
||||
bra lp2
|
||||
donelp2 long m
|
||||
return
|
||||
|
||||
copyOfData ds 64
|
||||
END
|
||||
|
||||
* void __crypt_rotate (struct block *key);
|
||||
__crypt_rotate START
|
||||
data0 equ 0
|
||||
data28 equ 2
|
||||
ep equ 4
|
||||
subroutine (4:key),6
|
||||
|
||||
lda #55
|
||||
sta ep
|
||||
short m
|
||||
lda [key]
|
||||
sta data0
|
||||
ldy #28
|
||||
lda [key],y
|
||||
sta data28
|
||||
ldy #0
|
||||
|
||||
lp cpy ep
|
||||
bcs donelp
|
||||
iny
|
||||
lda [key],y
|
||||
dey
|
||||
sta [key],y
|
||||
iny
|
||||
bra lp
|
||||
donelp lda data0
|
||||
ldy #27
|
||||
sta [key],y
|
||||
lda data28
|
||||
ldy #55
|
||||
sta [key],y
|
||||
long m
|
||||
return
|
||||
END
|
||||
|
||||
* void __crypt_f (int i, struct block *key, struct block *a, struct block *x);
|
||||
__crypt_f START
|
||||
k equ 0
|
||||
p equ 2
|
||||
q equ 4
|
||||
r equ 6
|
||||
xb equ 8
|
||||
subroutine (4:x,4:a,4:key,2:i),10
|
||||
|
||||
ldy #62
|
||||
lp1 lda [a],y
|
||||
sta e,y
|
||||
dey2
|
||||
bpl lp1
|
||||
|
||||
ph2 #48
|
||||
ph4 __crypt_EP
|
||||
ph4 #e
|
||||
jsl transpose
|
||||
|
||||
lda i
|
||||
asl a
|
||||
tay
|
||||
lda __crypt_rots,y
|
||||
sta k
|
||||
lp2 lda k
|
||||
beq donelp2
|
||||
ph4 key
|
||||
jsl rotate
|
||||
dec k
|
||||
bra lp2
|
||||
|
||||
donelp2 anop
|
||||
ldy #62
|
||||
lp3 lda [key],y
|
||||
sta ikey,y
|
||||
dey2
|
||||
bpl lp3
|
||||
|
||||
ph2 #48
|
||||
ph4 #KeyTr2
|
||||
ph4 #ikey
|
||||
jsl transpose
|
||||
|
||||
short m
|
||||
ldy #48
|
||||
lp4 cpy #0
|
||||
beq donelp4
|
||||
dey
|
||||
lda e,y
|
||||
eor ikey,y
|
||||
sta yb,y
|
||||
bra lp4
|
||||
|
||||
donelp4 anop
|
||||
long m
|
||||
ldy #0
|
||||
stz p
|
||||
stz q
|
||||
stz k
|
||||
|
||||
kloop lda k
|
||||
cmp #8
|
||||
bcc okay
|
||||
jmp donekloop
|
||||
|
||||
okay ldy p
|
||||
lda yb,y
|
||||
iny
|
||||
and #$FF
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
sta r
|
||||
|
||||
lda yb,y
|
||||
iny
|
||||
and #$FF
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
clc
|
||||
adc r
|
||||
sta r
|
||||
|
||||
lda yb,y
|
||||
iny
|
||||
and #$FF
|
||||
asl a
|
||||
asl a
|
||||
clc
|
||||
adc r
|
||||
sta r
|
||||
|
||||
lda yb,y
|
||||
iny
|
||||
and #$FF
|
||||
asl a
|
||||
clc
|
||||
adc r
|
||||
sta r
|
||||
|
||||
lda yb,y
|
||||
iny
|
||||
and #$FF
|
||||
clc
|
||||
adc r
|
||||
sta r
|
||||
|
||||
lda yb,y
|
||||
iny
|
||||
and #$FF
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
clc
|
||||
adc r
|
||||
sta r
|
||||
sty p ; store it temporarily
|
||||
|
||||
lda k
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a ; k * 64
|
||||
clc
|
||||
adc r ; + r;
|
||||
tay
|
||||
lda __crypt_s_boxes,y
|
||||
and #$FF
|
||||
sta xb
|
||||
|
||||
* *q++ = (xb >> 3) & 1;
|
||||
ldy q
|
||||
lda xb
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
and #1
|
||||
short m
|
||||
sta [x],y
|
||||
long m
|
||||
iny
|
||||
|
||||
* *q++ = (xb >> 2) & 1;
|
||||
lda xb
|
||||
lsr a
|
||||
lsr a
|
||||
and #1
|
||||
short m
|
||||
sta [x],y
|
||||
long m
|
||||
iny
|
||||
|
||||
* *q++ = (xb >> 1) & 1
|
||||
lda xb
|
||||
lsr a
|
||||
and #1
|
||||
short m
|
||||
sta [x],y
|
||||
long m
|
||||
iny
|
||||
|
||||
* *q++ = xb & 1;
|
||||
lda xb
|
||||
and #1
|
||||
short m
|
||||
sta [x],y
|
||||
long m
|
||||
iny
|
||||
sty q
|
||||
inc k
|
||||
jmp kloop
|
||||
donekloop anop
|
||||
ph2 #32
|
||||
ph4 #ptr
|
||||
ph4 x
|
||||
jsl transpose
|
||||
return
|
||||
|
||||
e ds 64
|
||||
ikey ds 64
|
||||
yb ds 64
|
||||
END
|
|
@ -0,0 +1,249 @@
|
|||
MACRO
|
||||
&lab subroutine &parms,&work
|
||||
&lab anop
|
||||
aif c:&work,.a
|
||||
lclc &work
|
||||
&work setc 0
|
||||
.a
|
||||
gbla &totallen
|
||||
gbla &worklen
|
||||
&worklen seta &work
|
||||
&totallen seta 0
|
||||
aif c:&parms=0,.e
|
||||
lclc &len
|
||||
lclc &p
|
||||
lcla &i
|
||||
&i seta c:&parms
|
||||
.b
|
||||
&p setc &parms(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.c
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .d
|
||||
.c
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.d
|
||||
&p equ &totallen+3+&work
|
||||
&totallen seta &totallen+&len
|
||||
&i seta &i-1
|
||||
aif &i,^b
|
||||
.e
|
||||
tsc
|
||||
sec
|
||||
sbc #&work
|
||||
tcs
|
||||
inc a
|
||||
phd
|
||||
tcd
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
mend
|
||||
MACRO
|
||||
&lab return &r
|
||||
&lab anop
|
||||
lclc &len
|
||||
aif c:&r,.a
|
||||
lclc &r
|
||||
&r setc 0
|
||||
&len setc 0
|
||||
ago .h
|
||||
.a
|
||||
&len amid &r,2,1
|
||||
aif "&len"=":",.b
|
||||
&len amid &r,1,2
|
||||
&r amid &r,4,l:&r-3
|
||||
ago .c
|
||||
.b
|
||||
&len amid &r,1,1
|
||||
&r amid &r,3,l:&r-2
|
||||
.c
|
||||
aif &len<>2,.d
|
||||
ldy &r
|
||||
ago .h
|
||||
.d
|
||||
aif &len<>4,.e
|
||||
ldx &r+2
|
||||
ldy &r
|
||||
ago .h
|
||||
.e
|
||||
aif &len<>10,.g
|
||||
ldy #&r
|
||||
ldx #^&r
|
||||
ago .h
|
||||
.g
|
||||
mnote 'Not a valid return length',16
|
||||
mexit
|
||||
.h
|
||||
aif &totallen=0,.i
|
||||
lda &worklen+1
|
||||
sta &worklen+&totallen+1
|
||||
lda &worklen
|
||||
sta &worklen+&totallen
|
||||
.i
|
||||
plb
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #&worklen+&totallen
|
||||
tcs
|
||||
aif &len=0,.j
|
||||
tya
|
||||
.j
|
||||
rtl
|
||||
mend
|
||||
MACRO
|
||||
&lab short &stat
|
||||
&lab anop
|
||||
lcla &t
|
||||
lcla &len
|
||||
lclc &ch
|
||||
&t seta 0
|
||||
&len seta l:&stat
|
||||
.a
|
||||
aif &len=0,.b
|
||||
&ch amid &stat,&len,1
|
||||
aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i
|
||||
aif ("&ch"="a").or.("&ch"="m"),.m
|
||||
.c
|
||||
&len seta &len-1
|
||||
ago ^a
|
||||
.i
|
||||
longi off
|
||||
&t seta &t+16
|
||||
ago ^c
|
||||
.m
|
||||
longa off
|
||||
&t seta &t+32
|
||||
ago ^c
|
||||
.b
|
||||
aif &t=0,.d
|
||||
sep #&t
|
||||
.d
|
||||
mend
|
||||
MACRO
|
||||
&lab dey2
|
||||
&lab dey
|
||||
dey
|
||||
mend
|
||||
MACRO
|
||||
&lab long &stat
|
||||
&lab anop
|
||||
lcla &t
|
||||
lcla &len
|
||||
lclc &ch
|
||||
&t seta 0
|
||||
&len seta l:&stat
|
||||
.a
|
||||
aif &len=0,.b
|
||||
&ch amid &stat,&len,1
|
||||
aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i
|
||||
aif ("&ch"="a").or.("&ch"="m"),.m
|
||||
.c
|
||||
&len seta &len-1
|
||||
ago ^a
|
||||
.i
|
||||
longi on
|
||||
&t seta &t+16
|
||||
ago ^c
|
||||
.m
|
||||
longa on
|
||||
&t seta &t+32
|
||||
ago ^c
|
||||
.b
|
||||
aif &t=0,.d
|
||||
rep #&t
|
||||
.d
|
||||
mend
|
||||
macro
|
||||
&lab ph4 &n1
|
||||
aif "&n1"="*",.f
|
||||
lclc &c
|
||||
&lab anop
|
||||
&c amid &n1,1,1
|
||||
aif "&c"="#",.d
|
||||
aif s:longa=1,.a
|
||||
rep #%00100000
|
||||
.a
|
||||
aif "&c"<>"{",.b
|
||||
&c amid &n1,l:&n1,1
|
||||
aif "&c"<>"}",.g
|
||||
&n1 amid &n1,2,l:&n1-2
|
||||
ldy #2
|
||||
lda (&n1),y
|
||||
pha
|
||||
lda (&n1)
|
||||
pha
|
||||
ago .e
|
||||
.b
|
||||
aif "&c"<>"[",.c
|
||||
ldy #2
|
||||
lda &n1,y
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.c
|
||||
aif "&c"<>"<",.c1
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pei &n1+2
|
||||
pei &n1
|
||||
ago .e
|
||||
.c1
|
||||
lda &n1+2
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.d
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pea +(&n1)|-16
|
||||
pea &n1
|
||||
ago .f
|
||||
.e
|
||||
aif s:longa=1,.f
|
||||
sep #%00100000
|
||||
.f
|
||||
mexit
|
||||
.g
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
MACRO
|
||||
&lab ph2 &parm
|
||||
lclc &char
|
||||
&lab anop
|
||||
aif c:&parm=0,.done
|
||||
&char amid &parm,1,1
|
||||
aif "&char"="#",.immediate
|
||||
aif "&char"="@",.at
|
||||
aif s:longa=1,.chk
|
||||
rep #%00100000
|
||||
.chk
|
||||
aif "&char"<>"{",.absolute
|
||||
&char amid &parm,l:&parm,1
|
||||
aif "&char"<>"}",.error
|
||||
&parm amid &parm,2,l:&parm-2
|
||||
lda (&parm)
|
||||
pha
|
||||
ago .shorten
|
||||
.absolute
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.immediate
|
||||
&parm amid &parm,2,l:&parm-1
|
||||
pea &parm
|
||||
ago .done
|
||||
.at
|
||||
&char amid &parm,2,1
|
||||
ph&char
|
||||
.shorten
|
||||
aif s:longa=1,.done
|
||||
sep #%00100000
|
||||
.done
|
||||
mexit
|
||||
.error
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* The original version of these routines (for GNO v2.0.5 and earlier)
|
||||
* were by Derek Taubert and Jawaid Bazyar. Reimplemented from scratch
|
||||
* by Devin Reade.
|
||||
*
|
||||
* $Id: dirent.c,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#define __LIBC_DIRENT /* needed for decls in <dirent.h> */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gsos.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
DIR *
|
||||
opendir (char *filename) {
|
||||
DIR *dirp;
|
||||
OpenRecGS *openRecPtr;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* the original version of this code used an ExpandDevices call
|
||||
* to expand filename before the call to OpenGS
|
||||
*/
|
||||
|
||||
/* do the allocations */
|
||||
if ((dirp = malloc(sizeof(DIR))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if ((dirp->dd_ent = malloc(sizeof(DirEntryRecGS))) == NULL) {
|
||||
free(dirp);
|
||||
return NULL;
|
||||
}
|
||||
if ((dirp->dd_ent->name = (ResultBuf255Ptr) GOinit (255, NULL))
|
||||
== NULL) {
|
||||
free(dirp->dd_ent);
|
||||
free(dirp);
|
||||
return NULL;
|
||||
}
|
||||
if ((dirp->dd_data = malloc(sizeof(struct dirent))) == NULL) {
|
||||
free(dirp->dd_ent->name);
|
||||
free(dirp->dd_ent);
|
||||
free(dirp);
|
||||
return NULL;
|
||||
}
|
||||
if ((openRecPtr = malloc(sizeof(OpenRecGS))) == NULL) {
|
||||
free(dirp->dd_data);
|
||||
free(dirp->dd_ent->name);
|
||||
free(dirp->dd_ent);
|
||||
free(dirp);
|
||||
return NULL;
|
||||
}
|
||||
if ((openRecPtr->pathname = (GSString255Ptr) __C2GSMALLOC(filename))
|
||||
== NULL) {
|
||||
free(openRecPtr);
|
||||
free(dirp->dd_data);
|
||||
free(dirp->dd_ent->name);
|
||||
free(dirp->dd_ent);
|
||||
free(dirp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open what is believed to be a directory */
|
||||
openRecPtr->pCount = 8;
|
||||
openRecPtr->requestAccess = readEnable;
|
||||
openRecPtr->resourceNumber = 0;
|
||||
OpenGS(openRecPtr);
|
||||
if ((err = _mapErr(_toolErr)) == 0) {
|
||||
if (openRecPtr->storageType != 0x0d && /* subdirectory */
|
||||
openRecPtr->storageType != 0x0f) { /* volume directory */
|
||||
err = ENOTDIR;
|
||||
openRecPtr->pCount = 1;
|
||||
CloseGS(openRecPtr); /* cheat a bit */
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
free(openRecPtr->pathname);
|
||||
free(openRecPtr);
|
||||
free(dirp->dd_data);
|
||||
free(dirp->dd_ent->name);
|
||||
free(dirp->dd_ent);
|
||||
free(dirp);
|
||||
errno = err;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* if we're here, filename has been opened and it's a directory */
|
||||
dirp->dd_fd = openRecPtr->refNum;
|
||||
dirp->dd_ent->pCount = 7;
|
||||
dirp->dd_ent->refNum = dirp->dd_fd;
|
||||
free(openRecPtr->pathname);
|
||||
free(openRecPtr);
|
||||
return dirp;
|
||||
}
|
||||
|
||||
struct dirent *
|
||||
readdir (DIR *dirp) {
|
||||
struct dirent *result;
|
||||
int err;
|
||||
|
||||
/* get the info from GS/OS */
|
||||
dirp->dd_ent->base = 1;
|
||||
dirp->dd_ent->displacement = 1;
|
||||
GetDirEntryGS(dirp->dd_ent);
|
||||
if ((err = _mapErr(_toolErr)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy it into the user-usable buffer */
|
||||
result = dirp->dd_data;
|
||||
result->d_fileno = dirp->dd_ent->entryNum;
|
||||
result->d_reclen = sizeof(struct dirent);
|
||||
switch (dirp->dd_ent->fileType) {
|
||||
case 0x0f:
|
||||
result->d_type = DT_DIR;
|
||||
default:
|
||||
result->d_type = DT_REG;
|
||||
}
|
||||
result->d_namlen = (char) dirp->dd_ent->name->bufString.length;
|
||||
memcpy(result->d_name, dirp->dd_ent->name->bufString.text,
|
||||
(size_t) result->d_namlen);
|
||||
result->d_name[result->d_namlen] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
rewinddir (DIR *dirp) {
|
||||
dirp->dd_ent->base = 0;
|
||||
dirp->dd_ent->displacement = 0;
|
||||
GetDirEntryGS(dirp->dd_ent);
|
||||
}
|
||||
|
||||
long
|
||||
telldir (DIR *dirp) {
|
||||
return (long) dirp->dd_ent->entryNum;
|
||||
}
|
||||
|
||||
void
|
||||
seekdir (DIR *dirp, long loc) {
|
||||
dirp->dd_ent->base = 0;
|
||||
dirp->dd_ent->displacement = loc;
|
||||
GetDirEntryGS(dirp->dd_ent);
|
||||
}
|
||||
|
||||
int
|
||||
closedir (DIR *dirp) {
|
||||
int closerec[2];
|
||||
int err;
|
||||
|
||||
closerec[0] = 1;
|
||||
closerec[1] = dirp->dd_ent->refNum;
|
||||
CloseGS(closerec);
|
||||
err = _mapErr(_toolErr);
|
||||
free(dirp->dd_data);
|
||||
free(dirp->dd_ent->name);
|
||||
free(dirp->dd_ent);
|
||||
free(dirp);
|
||||
if (err) {
|
||||
errno = err;
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*
|
||||
* $Id: err.c,v 1.1 1997/02/28 05:12:43 gdr Exp $
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma memorymodel 0
|
||||
|
||||
/* need bit 3 for variadic function definitions */
|
||||
#pragma optimize 8
|
||||
#pragma debug 0
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
/*
|
||||
* 4.4BSD uses __progname of type char *. That requires having access
|
||||
* to the compiler startup code. We use __prognameGS() to get us that
|
||||
* information from GS/OS.
|
||||
*/
|
||||
|
||||
static FILE *err_file = NULL; /* file to use for error output */
|
||||
static void (*err_exit)(int) = NULL;
|
||||
|
||||
void err_set_file(void *fp);
|
||||
void err_set_exit(void (*ef)(int));
|
||||
|
||||
void
|
||||
err_set_file(void *fp)
|
||||
{
|
||||
if (fp) {
|
||||
err_file = fp;
|
||||
} else {
|
||||
err_file = stderr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
err_set_exit(void (*ef)(int))
|
||||
{
|
||||
err_exit = ef;
|
||||
}
|
||||
|
||||
volatile void
|
||||
err(int eval, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verr(eval, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
volatile void
|
||||
verr(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
if (! err_file) {
|
||||
err_set_file((FILE *)0);
|
||||
}
|
||||
fprintf(err_file, "%s: ", __prognameGS());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
fprintf(err_file, ": ");
|
||||
}
|
||||
fprintf(err_file, "%s\n", strerror(sverrno));
|
||||
if(err_exit) {
|
||||
err_exit(eval);
|
||||
}
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
volatile void
|
||||
errx(int eval, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrx(eval, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
volatile void
|
||||
verrx(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
if (! err_file) {
|
||||
err_set_file((FILE *)0);
|
||||
}
|
||||
fprintf(err_file, "%s: ", __prognameGS());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
}
|
||||
fprintf(err_file, "\n");
|
||||
if (err_exit) {
|
||||
err_exit(eval);
|
||||
}
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarn(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarn(const char *fmt, va_list ap)
|
||||
{
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
if (! err_file) {
|
||||
err_set_file((FILE *)0);
|
||||
}
|
||||
fprintf(err_file, "%s: ", __prognameGS());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
fprintf(err_file, ": ");
|
||||
}
|
||||
fprintf(err_file, "%s\n", strerror(sverrno));
|
||||
}
|
||||
|
||||
void
|
||||
warnx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarnx(const char *fmt, va_list ap)
|
||||
{
|
||||
if (! err_file) {
|
||||
err_set_file((FILE *)0);
|
||||
}
|
||||
fprintf(err_file, "%s: ", __prognameGS());
|
||||
if (fmt != NULL) {
|
||||
vfprintf(err_file, fmt, ap);
|
||||
}
|
||||
fprintf(err_file, "\n");
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Guido van Rossum.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implementation uses recursion. It should be rewritten to avoid
|
||||
* it due to stack limitations on the IIgs.
|
||||
*
|
||||
* $Id: fnmatch.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tab stops every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
|
||||
* Compares a filename or pathname to a pattern.
|
||||
*/
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
|
||||
#define EOS '\0'
|
||||
|
||||
static const char *rangematch __P((const char *, int, int));
|
||||
static void _fnmatch_map (const char *, const char *, char **, char **, int);
|
||||
|
||||
int
|
||||
fnmatch(const char *opattern, const char *ostring, int flags)
|
||||
{
|
||||
const char *stringstart;
|
||||
char c, test;
|
||||
char *pattern, *string;
|
||||
|
||||
_fnmatch_map(ostring, opattern, &string, &pattern, flags);
|
||||
|
||||
for (stringstart = string;;)
|
||||
switch (c = *pattern++) {
|
||||
case EOS:
|
||||
return (*string == EOS ? 0 : FNM_NOMATCH);
|
||||
case '?':
|
||||
if (*string == EOS)
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '/' && (flags & FNM_PATHNAME))
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||
return (FNM_NOMATCH);
|
||||
++string;
|
||||
break;
|
||||
case '*':
|
||||
c = *pattern;
|
||||
/* Collapse multiple stars. */
|
||||
while (c == '*')
|
||||
c = *++pattern;
|
||||
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
/* Optimize for pattern with * at end or before /. */
|
||||
if (c == EOS)
|
||||
if (flags & FNM_PATHNAME)
|
||||
return (strchr(string, '/') == NULL ?
|
||||
0 : FNM_NOMATCH);
|
||||
else
|
||||
return (0);
|
||||
else if (c == '/' && flags & FNM_PATHNAME) {
|
||||
if ((string = strchr(string, '/')) == NULL)
|
||||
return (FNM_NOMATCH);
|
||||
break;
|
||||
}
|
||||
|
||||
/* General case, use recursion. */
|
||||
while ((test = *string) != EOS) {
|
||||
if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
|
||||
return (0);
|
||||
if (test == '/' && flags & FNM_PATHNAME)
|
||||
break;
|
||||
++string;
|
||||
}
|
||||
return (FNM_NOMATCH);
|
||||
case '[':
|
||||
if (*string == EOS)
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '/' && flags & FNM_PATHNAME)
|
||||
return (FNM_NOMATCH);
|
||||
if ((pattern =
|
||||
rangematch(pattern, *string, flags)) == NULL)
|
||||
return (FNM_NOMATCH);
|
||||
++string;
|
||||
break;
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE)) {
|
||||
if ((c = *pattern++) == EOS) {
|
||||
c = '\\';
|
||||
--pattern;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (c != *string++)
|
||||
return (FNM_NOMATCH);
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static const char *
|
||||
rangematch(const char *pattern, int test, int flags)
|
||||
{
|
||||
int negate, ok;
|
||||
char c, c2;
|
||||
|
||||
/*
|
||||
* A bracket expression starting with an unquoted circumflex
|
||||
* character produces unspecified results (IEEE 1003.2-1992,
|
||||
* 3.13.2). This implementation treats it like '!', for
|
||||
* consistency with the regular expression syntax.
|
||||
* J.T. Conklin (conklin@ngai.kaleida.com)
|
||||
*/
|
||||
if (negate = (*pattern == '!' || *pattern == '^'))
|
||||
++pattern;
|
||||
|
||||
for (ok = 0; (c = *pattern++) != ']';) {
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *pattern++;
|
||||
if (c == EOS)
|
||||
return (NULL);
|
||||
if (*pattern == '-'
|
||||
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
|
||||
pattern += 2;
|
||||
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c2 = *pattern++;
|
||||
if (c2 == EOS)
|
||||
return (NULL);
|
||||
if (c <= test && test <= c2)
|
||||
ok = 1;
|
||||
} else if (c == test)
|
||||
ok = 1;
|
||||
}
|
||||
return (ok == negate ? NULL : pattern);
|
||||
}
|
||||
|
||||
static void
|
||||
_fnmatch_map (const char *opath, const char *orex, char **npath, char **nrex,
|
||||
int flags) {
|
||||
static char *path = NULL;
|
||||
static char *rex = NULL;
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* create copies of opath and orex; this depends on an
|
||||
* ANSI implementation of realloc (accepts NULL pointer)
|
||||
*/
|
||||
path = realloc(path, strlen(opath) + 1);
|
||||
rex = realloc(rex, strlen(orex) + 1);
|
||||
if (path == NULL || rex == NULL) {
|
||||
err (1, "fnmatch could not allocate internal buffer");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
strcpy(path, opath);
|
||||
strcpy(rex, orex);
|
||||
|
||||
/* fold case if necessary */
|
||||
if (flags & FNM_CASEFOLD) {
|
||||
for (p = path; *p != '\0'; p++) {
|
||||
if (isupper(*p)) {
|
||||
*p = _tolower(*p);
|
||||
}
|
||||
}
|
||||
for (p = rex; *p != '\0'; p++) {
|
||||
if (isupper(*p)) {
|
||||
*p = _tolower(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If either pattern or string contain _both_ a ':' and a '/',
|
||||
* then we leave them exactly as they are. Otherwise, all colons
|
||||
* are mapped to '/'.
|
||||
*/
|
||||
if (!((strchr(path, ':') && strchr(path, '/')) ||
|
||||
(strchr(rex, ':') && strchr(rex, '/')))) {
|
||||
for (i=0; i<2; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
p = path;
|
||||
break;
|
||||
case 1:
|
||||
p = rex;
|
||||
break;
|
||||
}
|
||||
while (*p) {
|
||||
if (*p == ':') {
|
||||
*p = '/';
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* give the caller pointers to our buffer */
|
||||
*npath = path;
|
||||
*nrex = rex;
|
||||
return;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,114 @@
|
|||
#line 1 ":trenco4:gno.src:lib:libc:gen:getcwd.c"
|
||||
/*
|
||||
* getwd originally by Derek Taubert. First appeared in GNO v1.0 (?).
|
||||
* Modified for BSD 4.4 compatibility and dynamically allocated structs
|
||||
* by Devin Reade.
|
||||
*
|
||||
* $Id: getcwd.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tabs every 8 columns.
|
||||
*/
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <types.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <orca.h>
|
||||
#include <gno/gno.h>
|
||||
#include <gsos.h>
|
||||
|
||||
char *
|
||||
getcwd(char *pathname, size_t size) {
|
||||
PrefixRecGS *prefx;
|
||||
ResultBufPtr where;
|
||||
int e, allocated, i;
|
||||
char *result;
|
||||
|
||||
if (size == 0 && pathname != NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if ((prefx = malloc (sizeof(PrefixRecGS))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (pathname == NULL) {
|
||||
size = MAXPATHLEN;
|
||||
if ((pathname = malloc(size)) == NULL) {
|
||||
e = errno;
|
||||
free(prefx);
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
allocated = 1;
|
||||
} else {
|
||||
allocated = 0;
|
||||
}
|
||||
result = pathname;
|
||||
if ((where = GOinit (size, NULL)) == NULL) {
|
||||
e = errno;
|
||||
free(prefx);
|
||||
if (allocated) free(pathname);
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prefx->pCount = 2;
|
||||
prefx->buffer.getPrefix = (ResultBuf255Ptr) where;
|
||||
for (i=0; i<2; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
prefx->prefixNum = 0;
|
||||
break;
|
||||
case 1:
|
||||
prefx->prefixNum = 8;
|
||||
break;
|
||||
}
|
||||
GetPrefixGS(prefx);
|
||||
if (i == 0 && _toolErr == 0 && where->bufString.length == 0) {
|
||||
/* prefix 0 not set */
|
||||
continue;
|
||||
} else if ((e = _toolErr) != 0) {
|
||||
e = (e == buffTooSmall) ? ERANGE : _mapErr(e);
|
||||
result = NULL;
|
||||
break;
|
||||
} else {
|
||||
e = errno;
|
||||
strncpy(pathname, where->bufString.text, where->bufString.length);
|
||||
pathname[where->bufString.length] = 0;
|
||||
if (pathname[where->bufString.length-1] == ':') {
|
||||
pathname[where->bufString.length-1] = '\0';
|
||||
}
|
||||
|
||||
/* convert the filename? */
|
||||
if (_mapPath(pathname) == NULL) {
|
||||
e = EINVAL;
|
||||
result = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
free(prefx);
|
||||
GOfree(where);
|
||||
if (allocated && result == NULL) {
|
||||
free(pathname);
|
||||
}
|
||||
errno = e;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
getwd (char *pathname) {
|
||||
return getcwd(pathname, MAXPATHLEN);
|
||||
}
|
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*
|
||||
* $Id: getgrent.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <paths.h>
|
||||
#include <grp.h>
|
||||
|
||||
static FILE *_gr_fp;
|
||||
static struct group _gr_group;
|
||||
static int _gr_stayopen;
|
||||
static int grscan(register int search, register int gid,
|
||||
register const char *name);
|
||||
static int start_gr(void);
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
static int _gr_stepping_yp;
|
||||
static int _gr_yp_enabled;
|
||||
static int _getypgroup(struct group *, const char *, char *);
|
||||
static int _nextypgroup(struct group *);
|
||||
#endif
|
||||
|
||||
#define MAXGRP 200
|
||||
static char *members[MAXGRP];
|
||||
#define MAXLINELENGTH 1024
|
||||
static char line[MAXLINELENGTH];
|
||||
|
||||
struct group *
|
||||
getgrent(void)
|
||||
{
|
||||
if (!_gr_fp && !start_gr()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef YP
|
||||
if (_gr_stepping_yp) {
|
||||
if (_nextypgroup(&_gr_group))
|
||||
return(&_gr_group);
|
||||
}
|
||||
tryagain:
|
||||
#endif
|
||||
|
||||
if (!grscan(0, 0, NULL))
|
||||
return(NULL);
|
||||
#ifdef YP
|
||||
if(_gr_group.gr_name[0] == '+' && _gr_group.gr_name[1]) {
|
||||
_getypgroup(&_gr_group, &_gr_group.gr_name[1],
|
||||
"group.byname");
|
||||
} else if(_gr_group.gr_name[0] == '+') {
|
||||
if (!_nextypgroup(&_gr_group))
|
||||
goto tryagain;
|
||||
else
|
||||
return(&_gr_group);
|
||||
}
|
||||
#endif
|
||||
return(&_gr_group);
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrnam(const char *name)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if (!start_gr())
|
||||
return(NULL);
|
||||
#ifdef YP
|
||||
tryagain:
|
||||
#endif
|
||||
rval = grscan(1, 0, name);
|
||||
#ifdef YP
|
||||
if(rval == -1 && (_gr_yp_enabled < 0 || (_gr_yp_enabled &&
|
||||
_gr_group.gr_name[0] == '+'))) {
|
||||
if (!(rval = _getypgroup(&_gr_group, name, "group.byname")))
|
||||
goto tryagain;
|
||||
}
|
||||
#endif
|
||||
if (!_gr_stayopen)
|
||||
endgrent();
|
||||
return(rval ? &_gr_group : NULL);
|
||||
}
|
||||
|
||||
struct group *
|
||||
#ifdef __STDC__
|
||||
getgrgid(gid_t gid)
|
||||
#else
|
||||
getgrgid(gid)
|
||||
gid_t gid;
|
||||
#endif
|
||||
{
|
||||
int rval;
|
||||
|
||||
if (!start_gr())
|
||||
return(NULL);
|
||||
#ifdef YP
|
||||
tryagain:
|
||||
#endif
|
||||
rval = grscan(1, gid, NULL);
|
||||
#ifdef YP
|
||||
if(rval == -1 && _gr_yp_enabled) {
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof buf, "%d", (unsigned)gid);
|
||||
if (!(rval = _getypgroup(&_gr_group, buf, "group.bygid")))
|
||||
goto tryagain;
|
||||
}
|
||||
#endif
|
||||
if (!_gr_stayopen)
|
||||
endgrent();
|
||||
return(rval ? &_gr_group : NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
start_gr(void)
|
||||
{
|
||||
if (_gr_fp) {
|
||||
rewind(_gr_fp);
|
||||
return(1);
|
||||
}
|
||||
_gr_fp = fopen(_PATH_GROUP, "r");
|
||||
if(!_gr_fp) return 0;
|
||||
#ifdef YP
|
||||
/*
|
||||
* This is a disgusting hack, used to determine when YP is enabled.
|
||||
* This would be easier if we had a group database to go along with
|
||||
* the password database.
|
||||
*/
|
||||
{
|
||||
char *line;
|
||||
size_t linelen;
|
||||
_gr_yp_enabled = 0;
|
||||
while((line = fgetln(_gr_fp, &linelen)) != NULL) {
|
||||
if(line[0] == '+') {
|
||||
if(line[1] && !_gr_yp_enabled) {
|
||||
_gr_yp_enabled = 1;
|
||||
} else {
|
||||
_gr_yp_enabled = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rewind(_gr_fp);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
setgrent(void)
|
||||
{
|
||||
return(setgroupent(0));
|
||||
}
|
||||
|
||||
int
|
||||
setgroupent(int stayopen)
|
||||
{
|
||||
if (!start_gr())
|
||||
return(0);
|
||||
_gr_stayopen = stayopen;
|
||||
#ifdef YP
|
||||
_gr_stepping_yp = 0;
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
endgrent(void)
|
||||
{
|
||||
#ifdef YP
|
||||
_gr_stepping_yp = 0;
|
||||
#endif
|
||||
if (_gr_fp) {
|
||||
(void)fclose(_gr_fp);
|
||||
_gr_fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
grscan(register int search, register int gid, register const char *name)
|
||||
{
|
||||
register char *cp, **m;
|
||||
char *bp;
|
||||
#ifdef YP
|
||||
int _ypfound = 0;
|
||||
#endif
|
||||
for (;;) {
|
||||
if (!fgets(line, sizeof(line), _gr_fp))
|
||||
return(0);
|
||||
bp = line;
|
||||
/* skip lines that are too big */
|
||||
if (!index(line, '\n')) {
|
||||
int ch;
|
||||
|
||||
while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
|
||||
;
|
||||
continue;
|
||||
}
|
||||
if ((_gr_group.gr_name = strsep(&bp, ":\n")) == NULL)
|
||||
break;
|
||||
#ifdef YP
|
||||
/*
|
||||
* XXX We need to be careful to avoid proceeding
|
||||
* past this point under certain circumstances or
|
||||
* we risk dereferencing null pointers down below.
|
||||
*/
|
||||
if (_gr_group.gr_name[0] == '+') {
|
||||
if (strlen(_gr_group.gr_name) == 1) {
|
||||
switch(search) {
|
||||
case 0:
|
||||
return(1);
|
||||
case 1:
|
||||
return(-1);
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
} else {
|
||||
if (!_getypgroup(&_gr_group, &_gr_group.gr_name[1],
|
||||
"group.byname"))
|
||||
continue;
|
||||
/* We're going to override -- tell the world. */
|
||||
members[0] = NULL;
|
||||
_ypfound++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (_gr_group.gr_name[0] == '+')
|
||||
continue;
|
||||
#endif /* YP */
|
||||
if (search && name) {
|
||||
if(strcmp(_gr_group.gr_name, name)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((_gr_group.gr_passwd = strsep(&bp, ":\n")) == NULL)
|
||||
break;;
|
||||
if (!(cp = strsep(&bp, ":\n")))
|
||||
continue;
|
||||
#ifdef YP
|
||||
if (!_ypfound)
|
||||
#endif
|
||||
_gr_group.gr_gid = atoi(cp);
|
||||
if (search && name == NULL && _gr_group.gr_gid != gid)
|
||||
continue;
|
||||
cp = NULL;
|
||||
for (m = _gr_group.gr_mem = members;; bp++) {
|
||||
if (m == &members[MAXGRP - 1])
|
||||
break;
|
||||
if (*bp == ',') {
|
||||
if (cp) {
|
||||
*bp = '\0';
|
||||
*m++ = cp;
|
||||
cp = NULL;
|
||||
}
|
||||
} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
|
||||
if (cp) {
|
||||
*bp = '\0';
|
||||
*m++ = cp;
|
||||
}
|
||||
break;
|
||||
} else if (cp == NULL)
|
||||
cp = bp;
|
||||
}
|
||||
*m = NULL;
|
||||
return(1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef YP
|
||||
|
||||
static int
|
||||
_gr_breakout_yp(struct group *gr, char *result)
|
||||
{
|
||||
char *s, *cp;
|
||||
char **m;
|
||||
|
||||
/*
|
||||
* XXX If 's' ends up being a NULL pointer, punt on this group.
|
||||
* It means the NIS group entry is badly formatted and should
|
||||
* be skipped.
|
||||
*/
|
||||
if ((s = strsep(&result, ":")) == NULL) return 0; /* name */
|
||||
gr->gr_name = s;
|
||||
|
||||
if ((s = strsep(&result, ":")) == NULL) return 0; /* password */
|
||||
gr->gr_passwd = s;
|
||||
|
||||
if ((s = strsep(&result, ":")) == NULL) return 0; /* gid */
|
||||
gr->gr_gid = atoi(s);
|
||||
|
||||
if ((s = result) == NULL) return 0;
|
||||
cp = 0;
|
||||
|
||||
for (m = _gr_group.gr_mem = members; /**/; s++) {
|
||||
if (m == &members[MAXGRP - 1]) {
|
||||
break;
|
||||
}
|
||||
if (*s == ',') {
|
||||
if (cp) {
|
||||
*s = '\0';
|
||||
*m++ = cp;
|
||||
cp = NULL;
|
||||
}
|
||||
} else if (*s == '\0' || *s == '\n' || *s == ' ') {
|
||||
if (cp) {
|
||||
*s = '\0';
|
||||
*m++ = cp;
|
||||
}
|
||||
break;
|
||||
} else if (cp == NULL) {
|
||||
cp = s;
|
||||
}
|
||||
}
|
||||
*m = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *_gr_yp_domain;
|
||||
|
||||
static int
|
||||
_getypgroup(struct group *gr, const char *name, char *map)
|
||||
{
|
||||
char *result, *s;
|
||||
static char resultbuf[1024];
|
||||
int resultlen;
|
||||
|
||||
if(!_gr_yp_domain) {
|
||||
if(yp_get_default_domain(&_gr_yp_domain))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(yp_match(_gr_yp_domain, map, name, strlen(name),
|
||||
&result, &resultlen))
|
||||
return 0;
|
||||
|
||||
s = strchr(result, '\n');
|
||||
if(s) *s = '\0';
|
||||
|
||||
if(resultlen >= sizeof resultbuf) return 0;
|
||||
strcpy(resultbuf, result);
|
||||
result = resultbuf;
|
||||
return(_gr_breakout_yp(gr, resultbuf));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_nextypgroup(struct group *gr)
|
||||
{
|
||||
static char *key;
|
||||
static int keylen;
|
||||
char *lastkey, *result;
|
||||
static char resultbuf[1024];
|
||||
int resultlen;
|
||||
int rv;
|
||||
|
||||
if(!_gr_yp_domain) {
|
||||
if(yp_get_default_domain(&_gr_yp_domain))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!_gr_stepping_yp) {
|
||||
if(key) free(key);
|
||||
rv = yp_first(_gr_yp_domain, "group.byname",
|
||||
&key, &keylen, &result, &resultlen);
|
||||
if(rv) {
|
||||
return 0;
|
||||
}
|
||||
_gr_stepping_yp = 1;
|
||||
goto unpack;
|
||||
} else {
|
||||
tryagain:
|
||||
lastkey = key;
|
||||
rv = yp_next(_gr_yp_domain, "group.byname", key, keylen,
|
||||
&key, &keylen, &result, &resultlen);
|
||||
free(lastkey);
|
||||
unpack:
|
||||
if(rv) {
|
||||
_gr_stepping_yp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(resultlen > sizeof(resultbuf)) {
|
||||
free(result);
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
strcpy(resultbuf, result);
|
||||
free(result);
|
||||
if((result = strchr(resultbuf, '\n')) != NULL)
|
||||
*result = '\0';
|
||||
if (_gr_breakout_yp(gr, resultbuf))
|
||||
return(1);
|
||||
else
|
||||
goto tryagain;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* YP */
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* GDR: This file could probably be cleaned up a bit ...
|
||||
*
|
||||
* $Id: getpass.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tab stops every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getpass.c 5.9 (Berkeley) 5/6/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sgtty.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <texttool.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <signal.h>
|
||||
#undef echo
|
||||
|
||||
char *
|
||||
getpass(const char *prompt) {
|
||||
struct sgttyb term;
|
||||
register int ch;
|
||||
register char *p;
|
||||
FILE *fp, *outfp;
|
||||
long omask;
|
||||
int echo;
|
||||
static char buf[_PASSWORD_LEN + 1];
|
||||
|
||||
/*
|
||||
* read and write to /dev/tty if possible; else read from
|
||||
* stdin and write to stderr.
|
||||
*/
|
||||
/* if ((outfp = fp = fopen(".tty", "w+")) == NULL) { */
|
||||
if ((outfp = fp = fopen(".tty", "r+")) == NULL) {
|
||||
outfp = stderr;
|
||||
fp = stdin;
|
||||
}
|
||||
setbuf(outfp,NULL);
|
||||
/*
|
||||
* note - blocking signals isn't necessarily the
|
||||
* right thing, but we leave it for now.
|
||||
*/
|
||||
omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
|
||||
/*(void)tcgetattr(fileno(fp), &term); */
|
||||
gtty(fileno(fp),&term);
|
||||
if (echo = (term.sg_flags & ECHO)) {
|
||||
term.sg_flags &= ~ECHO;
|
||||
stty(fileno(fp),&term);
|
||||
/*(void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term);*/
|
||||
}
|
||||
/* (void)fputs(prompt, outfp);*/
|
||||
/* rewind(outfp); */ /* implied flush */
|
||||
write(fileno(outfp),prompt,strlen(prompt));
|
||||
/* for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';) */
|
||||
for (p = buf; (ch = ReadChar(0)&0x7F) != 0 && ch != '\n' && ch != '\r';)
|
||||
if (p < buf + _PASSWORD_LEN)
|
||||
*p++ = ch;
|
||||
*p = '\0';
|
||||
(void)write(fileno(outfp), "\r", 1);
|
||||
if (echo) {
|
||||
term.sg_flags |= ECHO;
|
||||
stty(fileno(fp), &term);
|
||||
}
|
||||
(void)sigsetmask(omask);
|
||||
if (fp != stdin)
|
||||
(void)fclose(fp);
|
||||
return(buf);
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an old implementation and needs to be replaced; just not quite
|
||||
* yet -- gdr
|
||||
*
|
||||
* $Id: getpwent.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#define _PATH_PASSWD "/etc/passwd"
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
|
||||
#define LENGTH 128
|
||||
#define _PATH_PASSWD "/etc/passwd"
|
||||
|
||||
static struct passwd _pw_passwd; /* password structure */
|
||||
static char pwline[LENGTH]; /* line in /etc/passwd */
|
||||
static FILE * f_passwd = NULL;
|
||||
#if 0
|
||||
static int _pw_stayopen = 0; /* keep fd's open */
|
||||
#endif
|
||||
|
||||
static FILE *
|
||||
_getpwfp (void) {
|
||||
if (f_passwd == NULL) {
|
||||
f_passwd = fopen(_PATH_PASSWD, "r");
|
||||
if (f_passwd == NULL) {
|
||||
/* this should really be going out via syslog */
|
||||
errx(1, "couldn't open %s", _PATH_PASSWD);
|
||||
}
|
||||
}
|
||||
return f_passwd;
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
_parsepw (struct passwd *_pw, char *line)
|
||||
{
|
||||
char *q, *r;
|
||||
|
||||
_pw->pw_fields = 0L; /* no fields filled in yet */
|
||||
if ((q = strchr(line, '\n')) != NULL) {
|
||||
*q = '\0';
|
||||
}
|
||||
|
||||
/* user name */
|
||||
_pw->pw_name = line;
|
||||
if ((q = strchr(line,':')) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*q++ = '\0';
|
||||
_pw->pw_fields |= _PWF_NAME;
|
||||
|
||||
/* password */
|
||||
_pw->pw_passwd = q;
|
||||
if ((q = strchr(q,':')) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*q++ = '\0';
|
||||
_pw->pw_fields |= _PWF_PASSWD;
|
||||
|
||||
/* user id */
|
||||
errno = 0;
|
||||
_pw->pw_uid = (int) strtol(q, &r, 10);
|
||||
if (errno == ERANGE || q == r) {
|
||||
return NULL;
|
||||
}
|
||||
q = r;
|
||||
*q++ = '\0';
|
||||
_pw->pw_fields |= _PWF_UID;
|
||||
|
||||
/* group id */
|
||||
errno = 0;
|
||||
_pw->pw_gid = (int) strtol(q, &r, 10);
|
||||
if (errno == ERANGE || q == r) {
|
||||
return NULL;
|
||||
}
|
||||
q = r;
|
||||
*q++ = '\0';
|
||||
_pw->pw_fields |= _PWF_GID;
|
||||
|
||||
/* real name */
|
||||
_pw->pw_gecos = q;
|
||||
if ((q = strchr(q,':')) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*q++ = '\0';
|
||||
_pw->pw_fields |= _PWF_GECOS;
|
||||
|
||||
/* home directory */
|
||||
_pw->pw_dir = q;
|
||||
if ((q = strchr(q,':')) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*q++ = '\0';
|
||||
_pw->pw_fields |= _PWF_DIR;
|
||||
|
||||
/* shell -- last one, so handle it differently */
|
||||
_pw->pw_shell = q;
|
||||
if ((q = strchr(q,':')) != NULL) {
|
||||
*q = '\0';
|
||||
}
|
||||
_pw->pw_fields |= _PWF_SHELL;
|
||||
|
||||
/* "not filled in":
|
||||
* password change time
|
||||
* user access class
|
||||
* account expiry time
|
||||
*/
|
||||
_pw->pw_change = _pw->pw_expire = 0L;
|
||||
_pw->pw_class = NULL;
|
||||
|
||||
return _pw;
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwent(void)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = _getpwfp();
|
||||
if (fgets(pwline, LENGTH, fp) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return _parsepw (&_pw_passwd, pwline);
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnam(char *name) {
|
||||
FILE *fp;
|
||||
struct passwd *result;
|
||||
|
||||
fp = _getpwfp();
|
||||
rewind(fp);
|
||||
while (fgets(pwline, LENGTH, fp) != NULL) {
|
||||
result = _parsepw (&_pw_passwd, pwline);
|
||||
if (result == NULL || !strcmp(name, result->pw_name)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwuid(uid_t uid)
|
||||
{
|
||||
FILE *fp;
|
||||
struct passwd *result;
|
||||
|
||||
fp = _getpwfp();
|
||||
rewind(fp);
|
||||
while (fgets(pwline, LENGTH, fp) != NULL) {
|
||||
result = _parsepw (&_pw_passwd, pwline);
|
||||
if (result == NULL || uid == result->pw_uid) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
setpwent(void)
|
||||
{
|
||||
if (f_passwd != NULL) {
|
||||
rewind(f_passwd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
endpwent(void)
|
||||
{
|
||||
if (f_passwd != NULL) {
|
||||
fclose(f_passwd);
|
||||
f_passwd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NOTDEFINED
|
||||
int
|
||||
setpassent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
_pw_keynum = 0;
|
||||
_pw_stayopen = stayopen;
|
||||
return(1);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getttyent.c 5.10 (Berkeley) 3/23/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#define index strchr
|
||||
|
||||
#include <ttyent.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
static char zapchar;
|
||||
static FILE *tf;
|
||||
|
||||
static char *skip(register char *p);
|
||||
static char *value(register char *p);
|
||||
|
||||
struct ttyent *
|
||||
getttynam (const char *tty) {
|
||||
register struct ttyent *t;
|
||||
|
||||
setttyent();
|
||||
while (t = getttyent())
|
||||
if (!strcmp(tty, t->ty_name))
|
||||
break;
|
||||
endttyent();
|
||||
return (t);
|
||||
}
|
||||
|
||||
struct ttyent *
|
||||
getttyent(void) {
|
||||
static struct ttyent tty;
|
||||
register int c;
|
||||
register char *p;
|
||||
#define MAXLINELENGTH 100
|
||||
static char line[MAXLINELENGTH];
|
||||
|
||||
if (!tf && !setttyent())
|
||||
return (NULL);
|
||||
for (;;) {
|
||||
if (!fgets(p = line, sizeof(line), tf))
|
||||
return (NULL);
|
||||
/* skip lines that are too big */
|
||||
if (!index(p, '\n')) {
|
||||
while ((c = getc(tf)) != '\n' && c != EOF)
|
||||
;
|
||||
continue;
|
||||
}
|
||||
while (isspace(*p))
|
||||
++p;
|
||||
if (*p && *p != '#')
|
||||
break;
|
||||
}
|
||||
zapchar = 0;
|
||||
tty.ty_name = p;
|
||||
p = skip(p);
|
||||
if (!*(tty.ty_getty = p))
|
||||
tty.ty_getty = tty.ty_type = NULL;
|
||||
else {
|
||||
p = skip(p);
|
||||
if (!*(tty.ty_type = p))
|
||||
tty.ty_type = NULL;
|
||||
else
|
||||
p = skip(p);
|
||||
}
|
||||
tty.ty_status = 0;
|
||||
tty.ty_window = NULL;
|
||||
|
||||
#ifdef __ORCAC__
|
||||
#define scmp(e) !strncmp(p, e, strlen(e) ) && isspace(p[strlen(e)])
|
||||
#define vcmp(e) !strncmp(p, e, strlen(e) ) && p[strlen(e)] == '='
|
||||
#else
|
||||
#define scmp(e) !strncmp(p, e, sizeof e - 1) && isspace(p[sizeof e])
|
||||
#define vcmp(e) !strncmp(p, e, sizeof e - 1) && p[sizeof e] == '='
|
||||
#endif
|
||||
for (; *p; p = skip(p)) {
|
||||
if (scmp(_TTYS_OFF))
|
||||
tty.ty_status &= ~TTY_ON;
|
||||
else if (scmp(_TTYS_ON))
|
||||
tty.ty_status |= TTY_ON;
|
||||
else if (scmp(_TTYS_SECURE))
|
||||
tty.ty_status |= TTY_SECURE;
|
||||
else if (vcmp(_TTYS_WINDOW))
|
||||
tty.ty_window = value(p);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (zapchar == '#' || *p == '#')
|
||||
while ((c = *++p) == ' ' || c == '\t')
|
||||
;
|
||||
tty.ty_comment = p;
|
||||
if (*p == 0)
|
||||
tty.ty_comment = 0;
|
||||
if (p = index(p, '\r'))
|
||||
*p = '\0';
|
||||
return (&tty);
|
||||
}
|
||||
|
||||
#define QUOTED 1
|
||||
|
||||
/*
|
||||
* Skip over the current field, removing quotes, and return a pointer to
|
||||
* the next field.
|
||||
*/
|
||||
static char *
|
||||
skip(register char *p)
|
||||
{
|
||||
register char *t;
|
||||
register int c, q;
|
||||
|
||||
for (q = 0, t = p; (c = *p) != '\0'; p++) {
|
||||
if (c == '"') {
|
||||
q ^= QUOTED; /* obscure, but nice */
|
||||
continue;
|
||||
}
|
||||
if (q == QUOTED && *p == '\\' && *(p+1) == '"')
|
||||
p++;
|
||||
*t++ = *p;
|
||||
if (q == QUOTED)
|
||||
continue;
|
||||
if (c == '#') {
|
||||
zapchar = c;
|
||||
*p = 0;
|
||||
break;
|
||||
}
|
||||
if (c == '\t' || c == ' ' || c == '\n' || c == '\r') {
|
||||
zapchar = c;
|
||||
*p++ = 0;
|
||||
while ((c = *p) == '\t' || c == ' ' || c == '\n' || c == '\r')
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*--t = '\0';
|
||||
return (p);
|
||||
}
|
||||
|
||||
static char *
|
||||
value(register char *p)
|
||||
{
|
||||
return ((p = index(p, '=')) ? ++p : NULL);
|
||||
}
|
||||
|
||||
int
|
||||
setttyent(void)
|
||||
{
|
||||
if (tf) {
|
||||
(void)rewind(tf);
|
||||
return (1);
|
||||
} else if (tf = fopen(_PATH_TTYS, "r"))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
endttyent(void)
|
||||
{
|
||||
int rval;
|
||||
|
||||
if (tf) {
|
||||
rval = !(fclose(tf) == EOF);
|
||||
tf = NULL;
|
||||
return (rval);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* $Id: hostname.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <orca.h>
|
||||
#include <locator.h>
|
||||
#include <memory.h>
|
||||
#include <misctool.h>
|
||||
|
||||
typedef struct NMRec {
|
||||
word blockLen;
|
||||
unsigned char nameLength;
|
||||
char nameString[64];
|
||||
} NMRec;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
word messageID;
|
||||
word createFlag;
|
||||
} w;
|
||||
unsigned long l;
|
||||
} ResponseR;
|
||||
|
||||
int
|
||||
sethostname(const char *name, int namelen) {
|
||||
int size;
|
||||
NMRec rec;
|
||||
ResponseR mbnResp;
|
||||
|
||||
strcpy(rec.nameString, "Procyon~GNO/ME~HoStNaMe");
|
||||
rec.nameLength = 23;
|
||||
size = MIN(MAXHOSTNAMELEN-1, namelen);
|
||||
strncpy(rec.nameString+23, name, size);
|
||||
(rec.nameString+23)[size] = 0;
|
||||
rec.blockLen = 2 + (1+23) + (1+size);
|
||||
|
||||
mbnResp.l = MessageByName(1,(Pointer)&rec);
|
||||
if (_toolErr) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gethostname(char *name, int namelen) {
|
||||
NMRec rec = {30,23,"Procyon~GNO/ME~HoStNaMe"}; /* why blockLen = 30? */
|
||||
ResponseR mbnResp;
|
||||
Handle message;
|
||||
|
||||
mbnResp.l = MessageByName(0,(Pointer)&rec);
|
||||
if (_toolErr) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
#if 0
|
||||
printf("MBN returned %X %X\n", mbnResp.w.messageID,
|
||||
mbnResp.w.createFlag);
|
||||
#endif
|
||||
MessageCenter(getMessage,mbnResp.w.messageID,
|
||||
message = NewHandle(0l,userid(),0,0l));
|
||||
if (_toolErr) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
strncpy(name, (char *)*message+6+2+(1+23),
|
||||
MIN(MAXHOSTNAMELEN, namelen));
|
||||
DisposeHandle(message);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* old_syslog library routine. Used if syslogd is not present. This routine
|
||||
* has a subset of the functions of syslogd. It always outputs to
|
||||
* /etc/syslog, and it accepts only one string, and does no error checking.
|
||||
* It also prints the facility/log level as a number.
|
||||
*
|
||||
* If you're sure syslogd will be available when your program is run (or you
|
||||
* want syslog() to do nothing if it isn't), create a dummy old_syslog() that
|
||||
* simply returns. This will make your program smaller.
|
||||
*
|
||||
* Phillip Vandry, August 1993.
|
||||
*
|
||||
* $Id: oldlog.c,v 1.1 1997/02/28 05:12:44 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <memory.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#define _PATH_SYSLOG "/etc/syslog"
|
||||
|
||||
/* Perhaps this struct decl belongs in <sys/syslog.h> ? */
|
||||
|
||||
struct syslogd {
|
||||
int version; /* == 0 */
|
||||
int prio; /* priority and facility */
|
||||
int numstrings; /* number of strings sent to syslogd */
|
||||
int string1; /* offset of string #1 */
|
||||
/* offset of more strings. This routine handles only one string */
|
||||
int string1_len; /* length of string #1 (GS/OS string) */
|
||||
char string1_text; /* variable length */
|
||||
};
|
||||
|
||||
void
|
||||
old_syslog (Handle datahand)
|
||||
{
|
||||
struct syslogd *data;
|
||||
static time_t trec;
|
||||
int where;
|
||||
static char number[32];
|
||||
|
||||
HLock(datahand);
|
||||
data = (struct syslogd *)*datahand;
|
||||
if ((where = open(_PATH_SYSLOG, O_APPEND|O_WRONLY|O_CREAT)) == -1) {
|
||||
return;
|
||||
}
|
||||
trec = time(NULL);
|
||||
sprintf(number,"%s: <%d> ", ctime(&trec), data->prio);
|
||||
write(where,number,(size_t)strlen(number));
|
||||
write(where,&(data->string1_text),(size_t)data->string1_len);
|
||||
write(where,"\r",1l);
|
||||
close(where);
|
||||
DisposeHandle(datahand);
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software written by Ken Arnold and
|
||||
* published in UNIX Review, Vol. 6, No. 8.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char *sccsid = "from: @(#)popen.c 5.15 (Berkeley) 2/23/91";
|
||||
static char *rcsid = "popen.c,v 1.5 1993/08/26 00:44:55 jtc Exp";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <paths.h>
|
||||
#include <assert.h>
|
||||
|
||||
static pid_t *pids;
|
||||
|
||||
#ifdef __GNO__
|
||||
#pragma databank 1
|
||||
static void
|
||||
_popen_child(int *pdes, char type, char *command)
|
||||
{
|
||||
if (type == 'r') {
|
||||
if (pdes[1] != STDOUT_FILENO) {
|
||||
(void) dup2(pdes[1], STDOUT_FILENO);
|
||||
(void) close(pdes[1]);
|
||||
}
|
||||
(void) close(pdes[0]);
|
||||
} else {
|
||||
if (pdes[0] != STDIN_FILENO) {
|
||||
(void) dup2(pdes[0], STDIN_FILENO);
|
||||
(void) close(pdes[0]);
|
||||
}
|
||||
(void) close(pdes[1]);
|
||||
}
|
||||
|
||||
/* change this when we have an sh(1) for GNO */
|
||||
#if 1
|
||||
execl(_PATH_GSHELL, "gsh", "-c", command, (char *) 0);
|
||||
#else
|
||||
execl(_PATH_BSHELL, "sh", "-c", command, (char *) 0);
|
||||
#endif
|
||||
_exit(127);
|
||||
}
|
||||
#pragma databank 0
|
||||
|
||||
#endif /* __GNO__ */
|
||||
|
||||
FILE *
|
||||
popen(const char *command, const char *type)
|
||||
{
|
||||
FILE *iop;
|
||||
int fds, pid;
|
||||
int pdes[2];
|
||||
|
||||
if (*type != 'r' && *type != 'w' || type[1]) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (pids == NULL) {
|
||||
if ((fds = getdtablesize()) <= 0) {
|
||||
return (NULL);
|
||||
}
|
||||
if ((pids = malloc(fds * sizeof(int))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
bzero((char *) pids, fds * sizeof(pid_t));
|
||||
}
|
||||
if (pipe(pdes) < 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef __GNO__
|
||||
pid = fork2(_popen_child, 1024, 0, "forked child of popen", 5,
|
||||
pdes, *type, command);
|
||||
switch (pid) {
|
||||
#else
|
||||
switch (pid = vfork()) {
|
||||
#endif
|
||||
|
||||
case -1: /* error */
|
||||
(void) close(pdes[0]);
|
||||
(void) close(pdes[1]);
|
||||
return (NULL);
|
||||
/* NOTREACHED */
|
||||
|
||||
#ifndef __GNO__
|
||||
case 0: /* child */
|
||||
if (*type == 'r') {
|
||||
if (pdes[1] != STDOUT_FILENO) {
|
||||
(void) dup2(pdes[1], STDOUT_FILENO);
|
||||
(void) close(pdes[1]);
|
||||
}
|
||||
(void) close(pdes[0]);
|
||||
} else {
|
||||
if (pdes[0] != STDIN_FILENO) {
|
||||
(void) dup2(pdes[0], STDIN_FILENO);
|
||||
(void) close(pdes[0]);
|
||||
}
|
||||
(void) close(pdes[1]);
|
||||
}
|
||||
execl(_PATH_BSHELL, "sh", "-c", command, (char *) 0);
|
||||
_exit(127);
|
||||
/* NOTREACHED */
|
||||
#endif /* ! __GNO__ */
|
||||
}
|
||||
/* parent; assume fdopen can't fail... */
|
||||
if (*type == 'r') {
|
||||
iop = fdopen(pdes[0], type);
|
||||
(void) close(pdes[1]);
|
||||
} else {
|
||||
iop = fdopen(pdes[1], type);
|
||||
(void) close(pdes[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* this assert may be removed when getdtablesize is replaced by
|
||||
* a kernel system call rather than just a stub returning OPEN_MAX
|
||||
*/
|
||||
assert(fileno(iop) < getdtablesize());
|
||||
|
||||
pids[fileno(iop)] = pid;
|
||||
return (iop);
|
||||
}
|
||||
|
||||
int
|
||||
pclose(FILE * iop)
|
||||
{
|
||||
register int fdes;
|
||||
int omask;
|
||||
union wait pstat;
|
||||
pid_t pid;
|
||||
|
||||
|
||||
/*
|
||||
* this assert may be removed when getdtablesize is replaced by
|
||||
* a kernel system call rather than just a stub returning OPEN_MAX
|
||||
*/
|
||||
assert(fileno(iop) < getdtablesize());
|
||||
|
||||
/*
|
||||
* pclose returns -1 if stream is not associated with a
|
||||
* `popened' command, if already `pclosed', or waitpid
|
||||
* returns an error.
|
||||
*/
|
||||
fdes = fileno(iop);
|
||||
if (pids == NULL || pids[fdes] == 0) {
|
||||
return (-1);
|
||||
}
|
||||
(void) fclose(iop);
|
||||
do {
|
||||
pid = waitpid(pids[fdes], &pstat, 0);
|
||||
} while (pid == -1 && errno == EINTR);
|
||||
pids[fdes] = 0;
|
||||
return (pid == -1 ? -1 : pstat.w_retcode);
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)pwcache.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <utmp.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#define NCACHE 64 /* power of 2 */
|
||||
#define MASK (NCACHE - 1) /* bits to store with */
|
||||
|
||||
char *group_from_gid(gid_t gid, int nogroup);
|
||||
char *user_from_uid(uid_t uid, int nouser);
|
||||
|
||||
char *
|
||||
user_from_uid(uid_t uid, int nouser)
|
||||
{
|
||||
static struct ncache {
|
||||
uid_t uid;
|
||||
int found;
|
||||
char name[UT_NAMESIZE + 1];
|
||||
} c_uid[NCACHE];
|
||||
static int pwopen;
|
||||
register struct passwd *pw;
|
||||
register struct ncache *cp;
|
||||
|
||||
cp = c_uid + (uid & MASK);
|
||||
if (cp->uid != uid || !*cp->name) {
|
||||
if (pwopen == 0) {
|
||||
setpassent(1);
|
||||
pwopen = 1;
|
||||
}
|
||||
pw = getpwuid(uid);
|
||||
cp->uid = uid;
|
||||
if (pw != NULL) {
|
||||
cp->found = 1;
|
||||
(void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE);
|
||||
cp->name[UT_NAMESIZE] = '\0';
|
||||
} else {
|
||||
cp->found = 0;
|
||||
(void)snprintf(cp->name, UT_NAMESIZE, "%u", uid);
|
||||
if (nouser)
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return (cp->name);
|
||||
}
|
||||
|
||||
char *
|
||||
group_from_gid(gid_t gid, int nogroup)
|
||||
{
|
||||
static struct ncache {
|
||||
gid_t gid;
|
||||
int found;
|
||||
char name[UT_NAMESIZE + 1];
|
||||
} c_gid[NCACHE];
|
||||
static int gropen;
|
||||
struct group *gr;
|
||||
struct ncache *cp;
|
||||
|
||||
cp = c_gid + (gid & MASK);
|
||||
if (cp->gid != gid || !*cp->name) {
|
||||
if (gropen == 0) {
|
||||
setgroupent(1);
|
||||
gropen = 1;
|
||||
}
|
||||
gr = getgrgid(gid);
|
||||
cp->gid = gid;
|
||||
if (gr != NULL) {
|
||||
cp->found = 1;
|
||||
(void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE);
|
||||
cp->name[UT_NAMESIZE] = '\0';
|
||||
} else {
|
||||
cp->found = 0;
|
||||
(void)snprintf(cp->name, UT_NAMESIZE, "%u", gid);
|
||||
if (nogroup)
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return (cp->name);
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is formatted for tab stops set every 8 columns.
|
||||
*
|
||||
* $Id: scandir.c,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Scan the directory dirname calling select to make a list of selected
|
||||
* directory entries then sort using qsort and compare routine dcomp.
|
||||
* Returns the number of entries and a pointer to a list of pointers to
|
||||
* struct dirent (through namelist). Returns -1 if there were any errors.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* The DIRSIZ macro is the minimum record length which will hold the directory
|
||||
* entry. This requires the amount of space in struct dirent without the
|
||||
* d_name field, plus enough space for the name and a terminating nul byte
|
||||
* (dp->d_namlen + 1), rounded up to a 4 byte boundary.
|
||||
*/
|
||||
#undef DIRSIZ
|
||||
#define DIRSIZ(dp) \
|
||||
((sizeof(struct dirent) - sizeof(dp)->d_name) + \
|
||||
(((dp)->d_namlen + 1 + 3) &~ 3))
|
||||
|
||||
/*
|
||||
* This is the quantum by which we allocate slots for of directory
|
||||
* entries. Using 64 * sizeof(caddr_t) gives as 256 bytes at a time.
|
||||
*/
|
||||
#define QUANTUM 64
|
||||
|
||||
int
|
||||
scandir(const char *dirname,
|
||||
struct dirent ***namelist,
|
||||
int (*select) (struct dirent *),
|
||||
int (*dcomp) (const void *, const void *))
|
||||
{
|
||||
register struct dirent *d, *p, **names;
|
||||
register size_t nitems;
|
||||
long arraysz;
|
||||
DIR *dirp;
|
||||
|
||||
if ((dirp = opendir(dirname)) == NULL)
|
||||
return(-1);
|
||||
|
||||
arraysz = QUANTUM;
|
||||
if ((names = malloc (arraysz * sizeof(struct dirent *))) == NULL) {
|
||||
closedir(dirp);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nitems = 0;
|
||||
while ((d = readdir(dirp)) != NULL) {
|
||||
if (select != NULL && !(*select)(d))
|
||||
continue; /* just selected names */
|
||||
/*
|
||||
* Make a minimum size copy of the data
|
||||
*/
|
||||
p = (struct dirent *)malloc(DIRSIZ(d));
|
||||
if (p == NULL)
|
||||
return(-1);
|
||||
p->d_fileno = d->d_fileno;
|
||||
p->d_type = d->d_type;
|
||||
p->d_reclen = d->d_reclen;
|
||||
p->d_namlen = d->d_namlen;
|
||||
bcopy(d->d_name, p->d_name, p->d_namlen + 1);
|
||||
/*
|
||||
* Check to make sure the array has space left and
|
||||
* realloc the maximum size.
|
||||
*/
|
||||
if (++nitems >= arraysz) {
|
||||
arraysz += QUANTUM;
|
||||
names = realloc(names,
|
||||
arraysz * sizeof(struct dirent *));
|
||||
if (names == NULL) {
|
||||
closedir(dirp);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
names[nitems-1] = p;
|
||||
}
|
||||
closedir(dirp);
|
||||
if (nitems && dcomp != NULL)
|
||||
qsort(names, nitems, sizeof(struct dirent *), dcomp);
|
||||
*namelist = names;
|
||||
return(nitems);
|
||||
}
|
||||
|
||||
/*
|
||||
* Alphabetic order comparison routine for those who want it.
|
||||
*/
|
||||
int
|
||||
alphasort(const void *d1, const void *d2)
|
||||
{
|
||||
return(strcmp((*(struct dirent **)d1)->d_name,
|
||||
(*(struct dirent **)d2)->d_name));
|
||||
}
|
||||
|
||||
int
|
||||
alphacasesort(const void *d1, const void *d2)
|
||||
{
|
||||
return(strcasecmp((*(struct dirent **)d1)->d_name,
|
||||
(*(struct dirent **)d2)->d_name));
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
*
|
||||
* Modified ORCA/C setjmp() and longjmp() routines to save and restore sigmask
|
||||
*
|
||||
* Original code from orcalib 2.0.1 - Copyright Byte Works, Inc.
|
||||
* changes by Derek Taubert
|
||||
* June 14, 1995
|
||||
*
|
||||
* $Id: setjmp.asm,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*
|
||||
|
||||
case on
|
||||
|
||||
dummy start ; ends up in .root
|
||||
end
|
||||
|
||||
LONGA ON
|
||||
LONGI ON
|
||||
setjmp START
|
||||
TSC
|
||||
PHD
|
||||
TCD
|
||||
CLC
|
||||
ADC #$0004
|
||||
STA [$04] ; stack pointer
|
||||
LDY #$0002
|
||||
LDA $01,S
|
||||
STA [$04],Y ; direct page register
|
||||
LDY #$0004
|
||||
LDA $00
|
||||
STA [$04],Y ; LSB program counter
|
||||
INY
|
||||
INY
|
||||
LDA $02
|
||||
STA [$04],Y ; MSB program counter
|
||||
; start sigmask changes
|
||||
pea $0000
|
||||
pea $0000
|
||||
jsl sigblock
|
||||
ldy #$0008
|
||||
sta [$04],Y ; LSB sigmask
|
||||
iny
|
||||
iny
|
||||
txa
|
||||
sta [$04],Y ; MSB sigmask
|
||||
; end sigmask changes
|
||||
PLD
|
||||
PHB
|
||||
PLX
|
||||
PLY
|
||||
PLA
|
||||
PLA
|
||||
PHY
|
||||
PHX
|
||||
PLB
|
||||
LDA #$0000
|
||||
RTL
|
||||
END
|
||||
|
||||
LONGA ON
|
||||
LONGI ON
|
||||
longjmp START
|
||||
TSC
|
||||
TCD
|
||||
PHB
|
||||
PHK
|
||||
PLB
|
||||
; start sigmask changes
|
||||
ldy #$000A
|
||||
lda [$04],Y ; MSB sigmask
|
||||
pha
|
||||
dey
|
||||
dey
|
||||
lda [$04],Y ; LSB sigmask
|
||||
pha
|
||||
jsl sigsetmask
|
||||
|
||||
LDY #$0006
|
||||
lstk LDA [$04],Y
|
||||
STA sp,Y
|
||||
DEY
|
||||
DEY
|
||||
BPL lstk
|
||||
|
||||
LDX $08
|
||||
BNE argok
|
||||
INX
|
||||
; end sigmask changes
|
||||
argok PLB
|
||||
LDA >sp
|
||||
TCS
|
||||
LDA >pc+$00000002
|
||||
STA $02,S
|
||||
LDA >pc
|
||||
STA $00,S
|
||||
LDA >dp
|
||||
TCD
|
||||
TXA
|
||||
RTL
|
||||
sp DC H'AD'
|
||||
DC H'00'
|
||||
dp DC H'00'
|
||||
DC H'00'
|
||||
pc DC H'19'
|
||||
DC H'00'
|
||||
DC H'00'
|
||||
DC H'04'
|
||||
END
|
||||
|
||||
LONGA ON
|
||||
LONGI ON
|
||||
_setjmp START
|
||||
TSC
|
||||
PHD
|
||||
TCD
|
||||
CLC
|
||||
ADC #$0004
|
||||
STA [$04]
|
||||
LDY #$0002
|
||||
LDA $01,S
|
||||
STA [$04],Y
|
||||
LDY #$0004
|
||||
LDA $00
|
||||
STA [$04],Y
|
||||
INY
|
||||
INY
|
||||
LDA $02
|
||||
STA [$04],Y
|
||||
PLD
|
||||
PHB
|
||||
PLX
|
||||
PLY
|
||||
PLA
|
||||
PLA
|
||||
PHY
|
||||
PHX
|
||||
PLB
|
||||
LDA #$0000
|
||||
RTL
|
||||
END
|
||||
|
||||
LONGA ON
|
||||
LONGI ON
|
||||
_longjmp START
|
||||
TSC
|
||||
TCD
|
||||
PHB
|
||||
PHK
|
||||
PLB
|
||||
LDX $08
|
||||
BNE argok
|
||||
INX
|
||||
argok LDY #$0006
|
||||
lstk LDA [$04],Y
|
||||
STA sp,Y
|
||||
DEY
|
||||
DEY
|
||||
BPL lstk
|
||||
PLB
|
||||
LDA >sp
|
||||
TCS
|
||||
LDA >pc+$00000002
|
||||
STA $02,S
|
||||
LDA >pc
|
||||
STA $00,S
|
||||
LDA >dp
|
||||
TCD
|
||||
TXA
|
||||
RTL
|
||||
sp DC H'AD'
|
||||
DC H'00'
|
||||
dp DC H'00'
|
||||
DC H'00'
|
||||
pc DC H'19'
|
||||
DC H'00'
|
||||
DC H'00'
|
||||
DC H'04'
|
||||
END
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* The sleep(3) code is from BSD 4.3-reno, heavily modified (shorted)
|
||||
* for use with GNO.
|
||||
*
|
||||
* $Id: sleep.c,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*
|
||||
* This file has been formatted for tabs every 8 columns
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int _ringring;
|
||||
|
||||
#pragma databank 1
|
||||
static void
|
||||
_sleephandler(int sig, int code) {
|
||||
_ringring = 1;
|
||||
}
|
||||
#pragma databank 0
|
||||
|
||||
unsigned int
|
||||
sleep(unsigned int seconds) {
|
||||
sig_t ovec;
|
||||
long omask;
|
||||
|
||||
if (seconds == 0) {
|
||||
return 0;
|
||||
}
|
||||
ovec = signal(SIGALRM, _sleephandler);
|
||||
omask = sigblock(sigmask(SIGALRM));
|
||||
_ringring = 0;
|
||||
alarm(seconds);
|
||||
while (!_ringring) {
|
||||
sigpause(omask &~ sigmask(SIGALRM));
|
||||
}
|
||||
signal(SIGALRM, ovec);
|
||||
sigsetmask(omask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pause(void)
|
||||
{
|
||||
sigpause(0L);
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,501 @@
|
|||
* These syslog() related routines use syslogd. They replace the old
|
||||
* syslog() routines in the lbsd library.
|
||||
*
|
||||
* If syslogd is not found, syslog() calls old_syslog with the handle it
|
||||
* would have passed to syslogd. If you are sure your program will have
|
||||
* syslogd available when it is run, you can replace old_syslog() with
|
||||
* a dummy routine that does nothing and returns. This will make your
|
||||
* program smaller.
|
||||
*
|
||||
* syslogd is built into init and is automatically started by it. I
|
||||
* recommend that you use init with GNO/ME 2.0
|
||||
*
|
||||
* Phillip Vandry, August 1993
|
||||
*
|
||||
* $Id: syslog.asm,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tab stops at positions 10, 16, 41, 40, 57,
|
||||
* 65, and 73 (standard Orca/M systabs setting).
|
||||
*
|
||||
keep syslog
|
||||
mcopy syslog.mac
|
||||
case on
|
||||
|
||||
dummy start ; ends up in .root
|
||||
end
|
||||
|
||||
syslog start libc_gen__
|
||||
tsc
|
||||
sec
|
||||
sbc #$8
|
||||
tcs
|
||||
phd
|
||||
tcd
|
||||
* Direct: 1=va_list, 9=RTL, 12=prio, 14=char *, 18=args
|
||||
|
||||
lda #0
|
||||
sta 3
|
||||
sta 7
|
||||
tdc
|
||||
clc
|
||||
adc #18
|
||||
sta 1
|
||||
sta 5
|
||||
|
||||
pea 0
|
||||
tdc
|
||||
inc a
|
||||
pha
|
||||
pei 16
|
||||
pei 14
|
||||
pei 12
|
||||
jsl vsyslog
|
||||
|
||||
lda 1
|
||||
clc
|
||||
sec
|
||||
sbc 5
|
||||
tax ; num extra parms
|
||||
|
||||
* Direct: 1=va_list, 9=RTL, 12=prio, 14=char *, 18=args
|
||||
lda 10
|
||||
sta 16,x
|
||||
lda 9
|
||||
sta 15,x
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #14
|
||||
phx
|
||||
adc 1,s
|
||||
tcs
|
||||
rtl
|
||||
end
|
||||
|
||||
vsyslog start libc_gen__
|
||||
using syslog_dat
|
||||
|
||||
space equ 26
|
||||
argstart equ space+4
|
||||
|
||||
tsc
|
||||
sec
|
||||
sbc #space
|
||||
tcs
|
||||
phd
|
||||
tcd
|
||||
phb
|
||||
|
||||
prio equ argstart
|
||||
format equ argstart+2
|
||||
valist equ argstart+6
|
||||
|
||||
sendhand equ 1
|
||||
sendptr equ 5
|
||||
lerrno equ 9
|
||||
errlen equ 9
|
||||
chand equ 11
|
||||
cptr equ 15
|
||||
cumlen equ 19
|
||||
error equ 23
|
||||
|
||||
lda >~USER_ID ; uck! bad name!
|
||||
sta >memid
|
||||
|
||||
* Log only if bit clear in LogMask
|
||||
lda >errno
|
||||
sta lerrno
|
||||
lda prio
|
||||
and #7
|
||||
tax
|
||||
lda >LogMask
|
||||
lsrloop lsr a
|
||||
dex
|
||||
bpl lsrloop
|
||||
* carry = apropriate bit
|
||||
bcc dolog
|
||||
|
||||
* get rif of parameters by running through sprintf
|
||||
jsr mksendhand
|
||||
pei valist+2
|
||||
pei valist
|
||||
pei format+2
|
||||
pei format
|
||||
pei sendptr+2
|
||||
pei sendptr
|
||||
jsl vsprintf
|
||||
~DisposeHandle <sendhand
|
||||
brl return
|
||||
|
||||
dolog anop
|
||||
lda prio
|
||||
and #$3f8
|
||||
bne gotone
|
||||
lda prio
|
||||
ora >LogFacility
|
||||
sta prio
|
||||
gotone anop
|
||||
jsr mksendhand
|
||||
jsr cpsendhand
|
||||
|
||||
lda >LogTag
|
||||
sta cptr
|
||||
lda >LogTag+2
|
||||
sta cptr+2
|
||||
ora cptr
|
||||
beq notag
|
||||
|
||||
lda >TagLen
|
||||
bne already
|
||||
ldy #0
|
||||
short m
|
||||
lppp lda [cptr],y
|
||||
beq foundlen
|
||||
iny
|
||||
bra lppp
|
||||
foundlen long m
|
||||
tya
|
||||
sta >TagLen
|
||||
|
||||
already sta [cumlen]
|
||||
tay
|
||||
short m
|
||||
fincp2 dey
|
||||
bmi fincp
|
||||
lda [cptr],y
|
||||
sta [sendptr],y
|
||||
bra fincp2
|
||||
fincp long m
|
||||
lda [cumlen]
|
||||
clc
|
||||
adc sendptr
|
||||
sta sendptr
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
|
||||
notag anop
|
||||
lda >LogFlag
|
||||
lsr a
|
||||
bcc nopid
|
||||
|
||||
pha
|
||||
ldx #$0903
|
||||
jsl $e10008 ; getpid
|
||||
pea fmt|-16
|
||||
pea fmt
|
||||
pei sendptr+2
|
||||
pei sendptr
|
||||
jsl sprintf
|
||||
pha
|
||||
clc
|
||||
adc [cumlen]
|
||||
sta [cumlen]
|
||||
pla
|
||||
clc
|
||||
adc sendptr
|
||||
sta sendptr
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
|
||||
nopid anop
|
||||
lda >LogTag
|
||||
ora >LogTag+2
|
||||
beq notagsecond
|
||||
lda [cumlen]
|
||||
inc a
|
||||
inc a
|
||||
sta [cumlen]
|
||||
lda #$203a
|
||||
sta [sendptr]
|
||||
lda sendptr
|
||||
clc
|
||||
adc #2
|
||||
sta sendptr
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
|
||||
notagsecond anop
|
||||
lda lerrno
|
||||
bne isone
|
||||
lda #ptrtozero
|
||||
sta error
|
||||
lda #^ptrtozero
|
||||
sta error+2
|
||||
bra none
|
||||
isone pha
|
||||
jsl strerror
|
||||
sta error
|
||||
stx error+2
|
||||
phx
|
||||
pha
|
||||
jsl strlen
|
||||
sta errlen
|
||||
|
||||
none ldx #2 ; = bytes needed in copy (one null+slop)
|
||||
ldy #0
|
||||
runthrough lda [format],y
|
||||
cmp #$6d25 ; '%m'
|
||||
beq account
|
||||
and #$ff
|
||||
beq endstring
|
||||
iny
|
||||
inx
|
||||
bra runthrough
|
||||
account iny
|
||||
iny
|
||||
txa
|
||||
clc
|
||||
adc errlen
|
||||
tax
|
||||
bra runthrough
|
||||
endstring pha
|
||||
pha
|
||||
pea 0
|
||||
phx ; length
|
||||
stz chand
|
||||
stz chand+2
|
||||
lda format
|
||||
sta cptr
|
||||
lda format+2
|
||||
sta cptr+2
|
||||
lda >memid
|
||||
pha
|
||||
pea $4000
|
||||
pha
|
||||
pha
|
||||
~NewHandle *,*,*,*
|
||||
pla
|
||||
plx
|
||||
bcs impossible
|
||||
sta chand
|
||||
stx chand+2
|
||||
ldy #2
|
||||
lda [chand],y
|
||||
sta cptr+2
|
||||
lda [chand]
|
||||
sta cptr
|
||||
|
||||
pea 0 ; offset in source
|
||||
ldy #0 ; offset in dest
|
||||
realtime tyx
|
||||
ply
|
||||
lda [format],y
|
||||
cmp #$6d25 ; '%m'
|
||||
beq coper
|
||||
and #$ff
|
||||
beq excited
|
||||
iny
|
||||
phy
|
||||
txy
|
||||
sta [cptr],y
|
||||
iny
|
||||
bra realtime
|
||||
coper iny
|
||||
iny
|
||||
phy
|
||||
txy ; Y=offset in destination
|
||||
pea 0 ; offset in source
|
||||
anotherreal tyx
|
||||
ply
|
||||
lda [error],y
|
||||
and #$ff
|
||||
beq donerr
|
||||
iny
|
||||
phy
|
||||
txy
|
||||
sta [cptr],y
|
||||
iny
|
||||
bra anotherreal
|
||||
donerr txy
|
||||
bra realtime
|
||||
excited txy
|
||||
sta [cptr],y ; zero
|
||||
|
||||
impossible anop ; jump here if malloc() failed
|
||||
pei valist+2
|
||||
pei valist
|
||||
pei cptr+2
|
||||
pei cptr
|
||||
pei sendptr+2
|
||||
pei sendptr
|
||||
jsl vsprintf
|
||||
clc
|
||||
adc [cumlen]
|
||||
sta [cumlen]
|
||||
lda >LogFlag
|
||||
and #$20 ; PERROR
|
||||
beq noper
|
||||
|
||||
ldx cumlen
|
||||
ldy cumlen+2
|
||||
lda #3
|
||||
jsl WriteGString ; echo on standard error
|
||||
ldx #nlonly
|
||||
ldy #^nlonly
|
||||
lda #3
|
||||
jsl WriteGString
|
||||
|
||||
noper lda chand
|
||||
ora chand+2
|
||||
beq nochand
|
||||
~DisposeHandle <chand
|
||||
|
||||
nochand pei sendhand+2
|
||||
pei sendhand
|
||||
pea portname|-16
|
||||
pea portname
|
||||
jsl pgetport
|
||||
cmp #$ffff
|
||||
beq nosyslogd
|
||||
pha
|
||||
jsl psend
|
||||
ldy #6
|
||||
tryagain lda [sendhand],y
|
||||
cmp >memid
|
||||
bne return
|
||||
cop $7f
|
||||
bra tryagain
|
||||
|
||||
return plb
|
||||
lda argstart-3
|
||||
sta valist+1
|
||||
lda argstart-2
|
||||
sta valist+2
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #(space+10)
|
||||
tcs
|
||||
rtl
|
||||
nosyslogd jsl old_syslog
|
||||
bra return
|
||||
|
||||
mksendhand pha
|
||||
pha
|
||||
pea 0
|
||||
pea 1024
|
||||
lda >memid
|
||||
pha
|
||||
pea $4000
|
||||
pha
|
||||
pha
|
||||
~NewHandle *,*,*,*
|
||||
plx
|
||||
stx sendhand
|
||||
plx
|
||||
stx sendhand+2
|
||||
bcs giveup
|
||||
ldy #2
|
||||
lda [sendhand],y
|
||||
sta sendptr+2
|
||||
lda [sendhand]
|
||||
sta sendptr
|
||||
rts
|
||||
giveup pea 1
|
||||
jsl sleep
|
||||
bra mksendhand
|
||||
|
||||
cpsendhand ldy #(Xthis-Xsyslog-2) ; is even
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
still lda Xsyslog,y
|
||||
sta [sendptr],y
|
||||
dey
|
||||
dey
|
||||
bpl still
|
||||
plb
|
||||
ldy #2
|
||||
lda prio
|
||||
sta [sendptr],y
|
||||
lda sendptr
|
||||
clc
|
||||
adc #(Xthis-Xsyslog)
|
||||
sta cumlen
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta cumlen+2
|
||||
lda #0
|
||||
sta [cumlen]
|
||||
lda cumlen
|
||||
clc
|
||||
adc #2
|
||||
sta sendptr
|
||||
lda cumlen+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
rts
|
||||
end
|
||||
|
||||
setlogmask start libc_gen__
|
||||
using syslog_dat
|
||||
* Stack: 1:RTL, 4:mask
|
||||
lda 4,s
|
||||
tax
|
||||
lda >LogMask
|
||||
sta 4,s
|
||||
txa
|
||||
sta >LogMask
|
||||
phb
|
||||
plx
|
||||
ply
|
||||
pla
|
||||
phy
|
||||
phx
|
||||
plb
|
||||
rtl
|
||||
end
|
||||
|
||||
closelog start libc_gen__
|
||||
using syslog_dat
|
||||
rtl
|
||||
end
|
||||
|
||||
openlog start libc_gen__
|
||||
using syslog_dat
|
||||
phb
|
||||
plx
|
||||
ply
|
||||
* Stack: 1:char *, 5:int, 7:int
|
||||
lda 1,s
|
||||
ora 3,s
|
||||
beq notag
|
||||
pla
|
||||
sta >LogTag
|
||||
pla
|
||||
sta >LogTag+2
|
||||
lda #0
|
||||
sta >TagLen
|
||||
dc h'a9'
|
||||
notag pla
|
||||
pla
|
||||
wastag pla
|
||||
sta >LogFlag
|
||||
pla
|
||||
sta >LogFacility
|
||||
phy
|
||||
phx
|
||||
plb
|
||||
rtl
|
||||
end
|
||||
|
||||
syslog_dat privdata libc_gen__
|
||||
LogTag ds 4
|
||||
TagLen ds 2
|
||||
LogFlag ds 2
|
||||
LogMask ds 2
|
||||
LogFacility ds 2
|
||||
memid ds 2
|
||||
|
||||
Xsyslog dc i'0,0,1,0,Xthis-Xsyslog'
|
||||
Xthis anop
|
||||
|
||||
fmt dc c'[%u] ',h'0'
|
||||
portname dc c'syslogd'
|
||||
ptrtozero dc h'0'
|
||||
|
||||
nlonly dc h'01 00 0d'
|
||||
end
|
|
@ -0,0 +1,146 @@
|
|||
macro
|
||||
&lab ~DisposeHandle &p1
|
||||
&lab ph4 &p1
|
||||
ldx #$1002
|
||||
jsl $E10000
|
||||
mend
|
||||
macro
|
||||
&lab ~NewHandle &p1,&p2,&p3,&p4
|
||||
&lab ph4 &p1
|
||||
ph2 &p2
|
||||
ph2 &p2
|
||||
ph4 &p4
|
||||
ldx #$0902
|
||||
jsl $E10000
|
||||
mend
|
||||
macro
|
||||
&l long &a,&b
|
||||
lclb &i
|
||||
lclb &m
|
||||
&a amid &a,1,1
|
||||
&m setb ("&a"="M").or.("&a"="m")
|
||||
&i setb ("&a"="I").or.("&a"="i")
|
||||
aif c:&b=0,.a
|
||||
&b amid &b,1,1
|
||||
&m setb ("&b"="M").or.("&b"="m").or.&m
|
||||
&i setb ("&b"="I").or.("&b"="i").or.&i
|
||||
.a
|
||||
&l rep #&m*32+&i*16
|
||||
aif .not.&m,.b
|
||||
longa on
|
||||
.b
|
||||
aif .not.&i,.c
|
||||
longi on
|
||||
.c
|
||||
mend
|
||||
macro
|
||||
&l ph2 &n1
|
||||
aif "&n1"="*",.f
|
||||
lclc &c
|
||||
&l anop
|
||||
&c amid &n1,1,1
|
||||
aif "&c"="#",.d
|
||||
aif s:longa=1,.a
|
||||
rep #%00100000
|
||||
.a
|
||||
aif "&c"<>"{",.b
|
||||
&c amid &n1,l:&n1,1
|
||||
aif "&c"<>"}",.g
|
||||
&n1 amid &n1,2,l:&n1-2
|
||||
lda (&n1)
|
||||
pha
|
||||
ago .e
|
||||
.b
|
||||
aif "&c"="<",.c
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.c
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pei &n1
|
||||
ago .e
|
||||
.d
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pea &n1
|
||||
ago .f
|
||||
.e
|
||||
aif s:longa=1,.f
|
||||
sep #%00100000
|
||||
.f
|
||||
mexit
|
||||
.g
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&l ph4 &n1
|
||||
aif "&n1"="*",.f
|
||||
lclc &c
|
||||
&l anop
|
||||
&c amid &n1,1,1
|
||||
aif "&c"="#",.d
|
||||
aif s:longa=1,.a
|
||||
rep #%00100000
|
||||
.a
|
||||
aif "&c"<>"{",.b
|
||||
&c amid &n1,l:&n1,1
|
||||
aif "&c"<>"}",.g
|
||||
&n1 amid &n1,2,l:&n1-2
|
||||
ldy #2
|
||||
lda (&n1),y
|
||||
pha
|
||||
lda (&n1)
|
||||
pha
|
||||
ago .e
|
||||
.b
|
||||
aif "&c"<>"[",.c
|
||||
ldy #2
|
||||
lda &n1,y
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.c
|
||||
aif "&c"<>"<",.c1
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pei &n1+2
|
||||
pei &n1
|
||||
ago .e
|
||||
.c1
|
||||
lda &n1+2
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.d
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pea +(&n1)|-16
|
||||
pea &n1
|
||||
ago .f
|
||||
.e
|
||||
aif s:longa=1,.f
|
||||
sep #%00100000
|
||||
.f
|
||||
mexit
|
||||
.g
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&l short &a,&b
|
||||
lclb &i
|
||||
lclb &m
|
||||
&a amid &a,1,1
|
||||
&m setb ("&a"="M").or.("&a"="m")
|
||||
&i setb ("&a"="I").or.("&a"="i")
|
||||
aif c:&b=0,.a
|
||||
&b amid &b,1,1
|
||||
&m setb ("&b"="M").or.("&b"="m").or.&m
|
||||
&i setb ("&b"="I").or.("&b"="i").or.&i
|
||||
.a
|
||||
&l sep #&m*32+&i*16
|
||||
aif .not.&m,.b
|
||||
longa off
|
||||
.b
|
||||
aif .not.&i,.c
|
||||
longi off
|
||||
.c
|
||||
mend
|
|
@ -0,0 +1,501 @@
|
|||
* These syslog() related routines use syslogd. They replace the old
|
||||
* syslog() routines in the lbsd library.
|
||||
*
|
||||
* If syslogd is not found, syslog() calls old_syslog with the handle it
|
||||
* would have passed to syslogd. If you are sure your program will have
|
||||
* syslogd available when it is run, you can replace old_syslog() with
|
||||
* a dummy routine that does nothing and returns. This will make your
|
||||
* program smaller.
|
||||
*
|
||||
* syslogd is built into init and is automatically started by it. I
|
||||
* recommend that you use init with GNO/ME 2.0
|
||||
*
|
||||
* Phillip Vandry, August 1993
|
||||
*
|
||||
* $Id: syslog2.asm,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tab stops at positions 10, 16, 41, 40, 57,
|
||||
* 65, and 73 (standard Orca/M systabs setting).
|
||||
*
|
||||
keep syslog
|
||||
mcopy syslog.mac
|
||||
case on
|
||||
|
||||
dummy start ; ends up in .root
|
||||
end
|
||||
|
||||
syslog start libc_gen__
|
||||
tsc
|
||||
sec
|
||||
sbc #$8
|
||||
tcs
|
||||
phd
|
||||
tcd
|
||||
* Direct: 1=va_list, 9=RTL, 12=prio, 14=char *, 18=args
|
||||
|
||||
lda #0
|
||||
sta 3
|
||||
sta 7
|
||||
tdc
|
||||
clc
|
||||
adc #18
|
||||
sta 1
|
||||
sta 5
|
||||
|
||||
pea 0
|
||||
tdc
|
||||
inc a
|
||||
pha
|
||||
pei 16
|
||||
pei 14
|
||||
pei 12
|
||||
jsl vsyslog
|
||||
|
||||
lda 1
|
||||
clc
|
||||
sec
|
||||
sbc 5
|
||||
tax ; num extra parms
|
||||
|
||||
* Direct: 1=va_list, 9=RTL, 12=prio, 14=char *, 18=args
|
||||
lda 10
|
||||
sta 16,x
|
||||
lda 9
|
||||
sta 15,x
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #14
|
||||
phx
|
||||
adc 1,s
|
||||
tcs
|
||||
rtl
|
||||
end
|
||||
|
||||
vsyslog start libc_gen__
|
||||
using syslog_dat
|
||||
|
||||
space equ 26
|
||||
argstart equ space+4
|
||||
|
||||
tsc
|
||||
sec
|
||||
sbc #space
|
||||
tcs
|
||||
phd
|
||||
tcd
|
||||
phb
|
||||
|
||||
prio equ argstart
|
||||
format equ argstart+2
|
||||
valist equ argstart+6
|
||||
|
||||
sendhand equ 1
|
||||
sendptr equ 5
|
||||
lerrno equ 9
|
||||
errlen equ 9
|
||||
chand equ 11
|
||||
cptr equ 15
|
||||
cumlen equ 19
|
||||
error equ 23
|
||||
|
||||
lda >~USER_ID ; uck! bad name!
|
||||
sta >memid
|
||||
|
||||
* Log only if bit clear in LogMask
|
||||
lda >errno
|
||||
sta lerrno
|
||||
lda prio
|
||||
and #7
|
||||
tax
|
||||
lda >LogMask
|
||||
lsrloop lsr a
|
||||
dex
|
||||
bpl lsrloop
|
||||
* carry = apropriate bit
|
||||
bcc dolog
|
||||
|
||||
* get rif of parameters by running through sprintf
|
||||
jsr mksendhand
|
||||
pei valist+2
|
||||
pei valist
|
||||
pei format+2
|
||||
pei format
|
||||
pei sendptr+2
|
||||
pei sendptr
|
||||
jsl vsprintf
|
||||
~DisposeHandle <sendhand
|
||||
brl return
|
||||
|
||||
dolog anop
|
||||
lda prio
|
||||
and #$3f8
|
||||
bne gotone
|
||||
lda prio
|
||||
ora >LogFacility
|
||||
sta prio
|
||||
gotone anop
|
||||
jsr mksendhand
|
||||
jsr cpsendhand
|
||||
|
||||
lda >LogTag
|
||||
sta cptr
|
||||
lda >LogTag+2
|
||||
sta cptr+2
|
||||
ora cptr
|
||||
beq notag
|
||||
|
||||
lda >TagLen
|
||||
bne already
|
||||
ldy #0
|
||||
short m
|
||||
lppp lda [cptr],y
|
||||
beq foundlen
|
||||
iny
|
||||
bra lppp
|
||||
foundlen long m
|
||||
tya
|
||||
sta >TagLen
|
||||
|
||||
already sta [cumlen]
|
||||
tay
|
||||
short m
|
||||
fincp2 dey
|
||||
bmi fincp
|
||||
lda [cptr],y
|
||||
sta [sendptr],y
|
||||
bra fincp2
|
||||
fincp long m
|
||||
lda [cumlen]
|
||||
clc
|
||||
adc sendptr
|
||||
sta sendptr
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
|
||||
notag anop
|
||||
lda >LogFlag
|
||||
lsr a
|
||||
bcc nopid
|
||||
|
||||
pha
|
||||
ldx #$0903
|
||||
jsl $e10008 ; getpid
|
||||
pea fmt|-16
|
||||
pea fmt
|
||||
pei sendptr+2
|
||||
pei sendptr
|
||||
jsl sprintf
|
||||
pha
|
||||
clc
|
||||
adc [cumlen]
|
||||
sta [cumlen]
|
||||
pla
|
||||
clc
|
||||
adc sendptr
|
||||
sta sendptr
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
|
||||
nopid anop
|
||||
lda >LogTag
|
||||
ora >LogTag+2
|
||||
beq notagsecond
|
||||
lda [cumlen]
|
||||
inc a
|
||||
inc a
|
||||
sta [cumlen]
|
||||
lda #$203a
|
||||
sta [sendptr]
|
||||
lda sendptr
|
||||
clc
|
||||
adc #2
|
||||
sta sendptr
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
|
||||
notagsecond anop
|
||||
lda lerrno
|
||||
bne isone
|
||||
lda #ptrtozero
|
||||
sta error
|
||||
lda #^ptrtozero
|
||||
sta error+2
|
||||
bra none
|
||||
isone pha
|
||||
jsl strerror
|
||||
sta error
|
||||
stx error+2
|
||||
phx
|
||||
pha
|
||||
jsl strlen
|
||||
sta errlen
|
||||
|
||||
none ldx #2 ; = bytes needed in copy (one null+slop)
|
||||
ldy #0
|
||||
runthrough lda [format],y
|
||||
cmp #$6d25 ; '%m'
|
||||
beq account
|
||||
and #$ff
|
||||
beq endstring
|
||||
iny
|
||||
inx
|
||||
bra runthrough
|
||||
account iny
|
||||
iny
|
||||
txa
|
||||
clc
|
||||
adc errlen
|
||||
tax
|
||||
bra runthrough
|
||||
endstring pha
|
||||
pha
|
||||
pea 0
|
||||
phx ; length
|
||||
stz chand
|
||||
stz chand+2
|
||||
lda format
|
||||
sta cptr
|
||||
lda format+2
|
||||
sta cptr+2
|
||||
lda >memid
|
||||
pha
|
||||
pea $4000
|
||||
pha
|
||||
pha
|
||||
~NewHandle *,*,*,*
|
||||
pla
|
||||
plx
|
||||
bcs impossible
|
||||
sta chand
|
||||
stx chand+2
|
||||
ldy #2
|
||||
lda [chand],y
|
||||
sta cptr+2
|
||||
lda [chand]
|
||||
sta cptr
|
||||
|
||||
pea 0 ; offset in source
|
||||
ldy #0 ; offset in dest
|
||||
realtime tyx
|
||||
ply
|
||||
lda [format],y
|
||||
cmp #$6d25 ; '%m'
|
||||
beq coper
|
||||
and #$ff
|
||||
beq excited
|
||||
iny
|
||||
phy
|
||||
txy
|
||||
sta [cptr],y
|
||||
iny
|
||||
bra realtime
|
||||
coper iny
|
||||
iny
|
||||
phy
|
||||
txy ; Y=offset in destination
|
||||
pea 0 ; offset in source
|
||||
anotherreal tyx
|
||||
ply
|
||||
lda [error],y
|
||||
and #$ff
|
||||
beq donerr
|
||||
iny
|
||||
phy
|
||||
txy
|
||||
sta [cptr],y
|
||||
iny
|
||||
bra anotherreal
|
||||
donerr txy
|
||||
bra realtime
|
||||
excited txy
|
||||
sta [cptr],y ; zero
|
||||
|
||||
impossible anop ; jump here if malloc() failed
|
||||
pei valist+2
|
||||
pei valist
|
||||
pei cptr+2
|
||||
pei cptr
|
||||
pei sendptr+2
|
||||
pei sendptr
|
||||
jsl vsprintf
|
||||
clc
|
||||
adc [cumlen]
|
||||
sta [cumlen]
|
||||
lda >LogFlag
|
||||
and #$20 ; PERROR
|
||||
beq noper
|
||||
|
||||
ldx cumlen
|
||||
ldy cumlen+2
|
||||
lda #3
|
||||
jsl WriteGString ; echo on standard error
|
||||
ldx #nlonly
|
||||
ldy #^nlonly
|
||||
lda #3
|
||||
jsl WriteGString
|
||||
|
||||
noper lda chand
|
||||
ora chand+2
|
||||
beq nochand
|
||||
~DisposeHandle <chand
|
||||
|
||||
nochand pei sendhand+2
|
||||
pei sendhand
|
||||
pea portname|-16
|
||||
pea portname
|
||||
jsl pgetport
|
||||
cmp #$ffff
|
||||
beq nosyslogd
|
||||
pha
|
||||
jsl psend
|
||||
ldy #6
|
||||
tryagain lda [sendhand],y
|
||||
cmp >memid
|
||||
bne return
|
||||
cop $7f
|
||||
bra tryagain
|
||||
|
||||
return plb
|
||||
lda argstart-3
|
||||
sta valist+1
|
||||
lda argstart-2
|
||||
sta valist+2
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #(space+10)
|
||||
tcs
|
||||
rtl
|
||||
nosyslogd jsl old_syslog
|
||||
bra return
|
||||
|
||||
mksendhand pha
|
||||
pha
|
||||
pea 0
|
||||
pea 1024
|
||||
lda >memid
|
||||
pha
|
||||
pea $4000
|
||||
pha
|
||||
pha
|
||||
~NewHandle *,*,*,*
|
||||
plx
|
||||
stx sendhand
|
||||
plx
|
||||
stx sendhand+2
|
||||
bcs giveup
|
||||
ldy #2
|
||||
lda [sendhand],y
|
||||
sta sendptr+2
|
||||
lda [sendhand]
|
||||
sta sendptr
|
||||
rts
|
||||
giveup pea 1
|
||||
jsl sleep
|
||||
bra mksendhand
|
||||
|
||||
cpsendhand ldy #(Xthis-Xsyslog-2) ; is even
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
still lda Xsyslog,y
|
||||
sta [sendptr],y
|
||||
dey
|
||||
dey
|
||||
bpl still
|
||||
plb
|
||||
ldy #2
|
||||
lda prio
|
||||
sta [sendptr],y
|
||||
lda sendptr
|
||||
clc
|
||||
adc #(Xthis-Xsyslog)
|
||||
sta cumlen
|
||||
lda sendptr+2
|
||||
adc #0
|
||||
sta cumlen+2
|
||||
lda #0
|
||||
sta [cumlen]
|
||||
lda cumlen
|
||||
clc
|
||||
adc #2
|
||||
sta sendptr
|
||||
lda cumlen+2
|
||||
adc #0
|
||||
sta sendptr+2
|
||||
rts
|
||||
end
|
||||
|
||||
setlogmask start libc_gen__
|
||||
using syslog_dat
|
||||
* Stack: 1:RTL, 4:mask
|
||||
lda 4,s
|
||||
tax
|
||||
lda >LogMask
|
||||
sta 4,s
|
||||
txa
|
||||
sta >LogMask
|
||||
phb
|
||||
plx
|
||||
ply
|
||||
pla
|
||||
phy
|
||||
phx
|
||||
plb
|
||||
rtl
|
||||
end
|
||||
|
||||
closelog start libc_gen__
|
||||
using syslog_dat
|
||||
rtl
|
||||
end
|
||||
|
||||
openlog start libc_gen__
|
||||
using syslog_dat
|
||||
phb
|
||||
plx
|
||||
ply
|
||||
* Stack: 1:char *, 5:int, 7:int
|
||||
lda 1,s
|
||||
ora 3,s
|
||||
beq notag
|
||||
pla
|
||||
sta >LogTag
|
||||
pla
|
||||
sta >LogTag+2
|
||||
lda #0
|
||||
sta >TagLen
|
||||
dc h'a9'
|
||||
notag pla
|
||||
pla
|
||||
wastag pla
|
||||
sta >LogFlag
|
||||
pla
|
||||
sta >LogFacility
|
||||
phy
|
||||
phx
|
||||
plb
|
||||
rtl
|
||||
end
|
||||
|
||||
syslog_dat privdata libc_gen__
|
||||
LogTag ds 4
|
||||
TagLen ds 2
|
||||
LogFlag ds 2
|
||||
LogMask ds 2
|
||||
LogFacility ds 2
|
||||
memid ds 2
|
||||
|
||||
Xsyslog dc i'0,0,1,0,Xthis-Xsyslog'
|
||||
Xthis anop
|
||||
|
||||
fmt dc c'[%u] ',h'0'
|
||||
portname dc c'syslogd'
|
||||
ptrtozero dc h'0'
|
||||
|
||||
nlonly dc h'01 00 0d'
|
||||
end
|
|
@ -0,0 +1,146 @@
|
|||
macro
|
||||
&lab ~DisposeHandle &p1
|
||||
&lab ph4 &p1
|
||||
ldx #$1002
|
||||
jsl $E10000
|
||||
mend
|
||||
macro
|
||||
&lab ~NewHandle &p1,&p2,&p3,&p4
|
||||
&lab ph4 &p1
|
||||
ph2 &p2
|
||||
ph2 &p2
|
||||
ph4 &p4
|
||||
ldx #$0902
|
||||
jsl $E10000
|
||||
mend
|
||||
macro
|
||||
&l long &a,&b
|
||||
lclb &i
|
||||
lclb &m
|
||||
&a amid &a,1,1
|
||||
&m setb ("&a"="M").or.("&a"="m")
|
||||
&i setb ("&a"="I").or.("&a"="i")
|
||||
aif c:&b=0,.a
|
||||
&b amid &b,1,1
|
||||
&m setb ("&b"="M").or.("&b"="m").or.&m
|
||||
&i setb ("&b"="I").or.("&b"="i").or.&i
|
||||
.a
|
||||
&l rep #&m*32+&i*16
|
||||
aif .not.&m,.b
|
||||
longa on
|
||||
.b
|
||||
aif .not.&i,.c
|
||||
longi on
|
||||
.c
|
||||
mend
|
||||
macro
|
||||
&l ph2 &n1
|
||||
aif "&n1"="*",.f
|
||||
lclc &c
|
||||
&l anop
|
||||
&c amid &n1,1,1
|
||||
aif "&c"="#",.d
|
||||
aif s:longa=1,.a
|
||||
rep #%00100000
|
||||
.a
|
||||
aif "&c"<>"{",.b
|
||||
&c amid &n1,l:&n1,1
|
||||
aif "&c"<>"}",.g
|
||||
&n1 amid &n1,2,l:&n1-2
|
||||
lda (&n1)
|
||||
pha
|
||||
ago .e
|
||||
.b
|
||||
aif "&c"="<",.c
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.c
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pei &n1
|
||||
ago .e
|
||||
.d
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pea &n1
|
||||
ago .f
|
||||
.e
|
||||
aif s:longa=1,.f
|
||||
sep #%00100000
|
||||
.f
|
||||
mexit
|
||||
.g
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&l ph4 &n1
|
||||
aif "&n1"="*",.f
|
||||
lclc &c
|
||||
&l anop
|
||||
&c amid &n1,1,1
|
||||
aif "&c"="#",.d
|
||||
aif s:longa=1,.a
|
||||
rep #%00100000
|
||||
.a
|
||||
aif "&c"<>"{",.b
|
||||
&c amid &n1,l:&n1,1
|
||||
aif "&c"<>"}",.g
|
||||
&n1 amid &n1,2,l:&n1-2
|
||||
ldy #2
|
||||
lda (&n1),y
|
||||
pha
|
||||
lda (&n1)
|
||||
pha
|
||||
ago .e
|
||||
.b
|
||||
aif "&c"<>"[",.c
|
||||
ldy #2
|
||||
lda &n1,y
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.c
|
||||
aif "&c"<>"<",.c1
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pei &n1+2
|
||||
pei &n1
|
||||
ago .e
|
||||
.c1
|
||||
lda &n1+2
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.d
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pea +(&n1)|-16
|
||||
pea &n1
|
||||
ago .f
|
||||
.e
|
||||
aif s:longa=1,.f
|
||||
sep #%00100000
|
||||
.f
|
||||
mexit
|
||||
.g
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&l short &a,&b
|
||||
lclb &i
|
||||
lclb &m
|
||||
&a amid &a,1,1
|
||||
&m setb ("&a"="M").or.("&a"="m")
|
||||
&i setb ("&a"="I").or.("&a"="i")
|
||||
aif c:&b=0,.a
|
||||
&b amid &b,1,1
|
||||
&m setb ("&b"="M").or.("&b"="m").or.&m
|
||||
&i setb ("&b"="I").or.("&b"="i").or.&i
|
||||
.a
|
||||
&l sep #&m*32+&i*16
|
||||
aif .not.&m,.b
|
||||
longa off
|
||||
.b
|
||||
aif .not.&i,.c
|
||||
longi off
|
||||
.c
|
||||
mend
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*
|
||||
* $Id: tty.c,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)ttyslot.c 5.6 (Berkeley) 2/23/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <types.h>
|
||||
#include <ttyent.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <gsos.h>
|
||||
|
||||
/*
|
||||
* gdr: ttyslot is probably buggy -- there is a search for '/' but
|
||||
* not for ':'
|
||||
*/
|
||||
|
||||
int
|
||||
ttyslot(void) {
|
||||
register struct ttyent *ttyp;
|
||||
register int slot;
|
||||
register char *p;
|
||||
int cnt;
|
||||
char *name;
|
||||
|
||||
setttyent();
|
||||
for (cnt = 0; cnt < 3; ++cnt)
|
||||
if (name = ttyname(cnt)) {
|
||||
if (p = rindex(name, '/'))
|
||||
++p;
|
||||
else
|
||||
p = name;
|
||||
/*printf("p: %s\n",p);*/
|
||||
for (slot = 1; ttyp = getttyent(); ++slot){
|
||||
/*printf("ty_name: %s\n",ttyp->ty_name);*/
|
||||
|
||||
if (!strcmp(ttyp->ty_name, p)) {
|
||||
endttyent();
|
||||
return(slot);
|
||||
} }
|
||||
break;
|
||||
}
|
||||
endttyent();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ttyname(int fino) {
|
||||
static ResultBuf32 resBuf;
|
||||
static RefInfoRecGS refInfo = {3,1,0,(ResultBuf255Ptr)&resBuf};
|
||||
|
||||
if (!isatty(fino)) {
|
||||
return NULL;
|
||||
}
|
||||
resBuf.bufSize = 32;
|
||||
refInfo.refNum = fino;
|
||||
GetRefInfoGS(&refInfo);
|
||||
refInfo.pathname->bufString.text
|
||||
[refInfo.pathname->bufString.length] = 0;
|
||||
return refInfo.pathname->bufString.text;
|
||||
}
|
||||
|
||||
int
|
||||
isatty(int filedes) {
|
||||
struct stat sb;
|
||||
|
||||
if (fstat(filedes,&sb) == -1) {
|
||||
return 0;
|
||||
} else if (sb.st_mode & S_IFCHR) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* utime, utimes. Implementation by Devin Reade.
|
||||
*
|
||||
* $Id: utime.c,v 1.1 1997/02/28 05:12:45 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gen__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <utime.h>
|
||||
#include <sys/errno.h>
|
||||
#include <gno/gno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include <gsos.h>
|
||||
|
||||
extern int _toolErr;
|
||||
|
||||
int
|
||||
utime(const char *path, const struct utimbuf *buf)
|
||||
{
|
||||
FileInfoRecPtrGS infoPtr;
|
||||
time_t t;
|
||||
struct tm *tmptr;
|
||||
int i;
|
||||
|
||||
/* allocate structures */
|
||||
infoPtr = malloc (sizeof (FileInfoRecGS));
|
||||
if (infoPtr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
infoPtr->pathname = (GSString255Ptr) __C2GSMALLOC(path);
|
||||
if (infoPtr->pathname == NULL) {
|
||||
i = errno;
|
||||
free(infoPtr);
|
||||
errno = i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* initialize structure and get current file info */
|
||||
infoPtr->pCount = 7;
|
||||
_toolErr = 0;
|
||||
GetFileInfoGS(infoPtr);
|
||||
if (_toolErr) {
|
||||
i = _mapErr(_toolErr);
|
||||
free(infoPtr->pathname);
|
||||
free(infoPtr);
|
||||
errno = i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* change the file creation time */
|
||||
if (buf == NULL) {
|
||||
time(&t);
|
||||
tmptr = localtime(&t);
|
||||
} else {
|
||||
tmptr = localtime(&(buf->actime));
|
||||
}
|
||||
infoPtr->createDateTime.second = tmptr->tm_sec;
|
||||
infoPtr->createDateTime.minute = tmptr->tm_min;
|
||||
infoPtr->createDateTime.hour = tmptr->tm_hour;
|
||||
infoPtr->createDateTime.year = tmptr->tm_year;
|
||||
infoPtr->createDateTime.day = tmptr->tm_mday;
|
||||
infoPtr->createDateTime.month = tmptr->tm_mon;
|
||||
infoPtr->createDateTime.weekDay = tmptr->tm_wday;
|
||||
|
||||
/* change the file modification time */
|
||||
if (buf == NULL) {
|
||||
infoPtr->modDateTime = infoPtr->createDateTime;
|
||||
} else {
|
||||
tmptr = localtime(&(buf->modtime));
|
||||
infoPtr->modDateTime.second = tmptr->tm_sec;
|
||||
infoPtr->modDateTime.minute = tmptr->tm_min;
|
||||
infoPtr->modDateTime.hour = tmptr->tm_hour;
|
||||
infoPtr->modDateTime.year = tmptr->tm_year;
|
||||
infoPtr->modDateTime.day = tmptr->tm_mday;
|
||||
infoPtr->modDateTime.month = tmptr->tm_mon;
|
||||
infoPtr->modDateTime.weekDay = tmptr->tm_wday;
|
||||
}
|
||||
|
||||
/* write the info to the filesystem */
|
||||
infoPtr->storageType = 0x0000;
|
||||
SetFileInfoGS(infoPtr);
|
||||
i = (_toolErr) ? _mapErr(_toolErr) : 0;
|
||||
free(infoPtr->pathname);
|
||||
free(infoPtr);
|
||||
if (i != 0) {
|
||||
errno = i;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
utimes (const char *path, const struct timeval *tvp) {
|
||||
struct utimbuf tmpval;
|
||||
|
||||
if (tvp) {
|
||||
tmpval.actime = tvp[0].tv_sec;
|
||||
tmpval.modtime = tvp[1].tv_sec;
|
||||
return utime(path, &tmpval);
|
||||
} else {
|
||||
return utime(path, NULL);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# Makefile for libc/gno
|
||||
# Devin Reade, 1996
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:46 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJ_ASM = gnocmd.o parsearg.o stack.o
|
||||
OBJ_C = gnomisc.o gsstring.o map.o
|
||||
OBJS = $(OBJ_ASM) $(OBJ_C)
|
||||
|
||||
MACROS_ORCA = $(ORCA_DIST)/OrcaInclude
|
||||
MACRO_FILES = $(MACROS_ORCA)/m16.tools $(MACROS_ORCA)/m16.orca
|
||||
|
||||
build: $(OBJS)
|
||||
|
||||
stack.mac:
|
||||
macgen -p stack.asm $@ $(MACRO_FILES)
|
||||
|
||||
clean clobber:
|
||||
$(RM) -f $(OBJS) stack.mac
|
||||
|
||||
.INCLUDE: ../rules.mk
|
||||
|
||||
gnocmd.o:: gnocmd.mac
|
||||
parsearg.o:: parsearg.mac
|
||||
stack.o:: stack.mac
|
|
@ -0,0 +1,74 @@
|
|||
***********************************************************************
|
||||
*
|
||||
* GNO command startup
|
||||
* Version 1.0a
|
||||
* Written by Tim Meekins
|
||||
* Copyright (C) 1991-1996 by Procyon, Inc.
|
||||
*
|
||||
* This function emulates the startup code of a C program for assembly
|
||||
* language programmers.
|
||||
*
|
||||
* To use it, have your first segment immediately JML to this routine.
|
||||
* Then, make sure you have a segment called main() which will take argv
|
||||
* and argc on the stack.
|
||||
*
|
||||
* $Id: gnocmd.asm,v 1.1 1997/02/28 05:12:46 gdr Exp $
|
||||
*
|
||||
**************************************************************************
|
||||
|
||||
keep gnocmd
|
||||
mcopy gnocmd.mac
|
||||
|
||||
dummy START ; ends up in .root file
|
||||
END
|
||||
|
||||
~GNO_COMMAND START
|
||||
|
||||
argv equ 0
|
||||
argc equ 4
|
||||
|
||||
phk
|
||||
plb
|
||||
|
||||
sta ~USER_ID
|
||||
sty ~COMMANDLINE
|
||||
stx ~COMMANDLINE+2
|
||||
|
||||
jsl ~MM_INIT
|
||||
|
||||
ph4 ~COMMANDLINE
|
||||
clc
|
||||
tdc
|
||||
adc #argv
|
||||
pea 0
|
||||
pha
|
||||
jsl ~GNO_PARSEARG
|
||||
sta argc
|
||||
|
||||
cmp #0
|
||||
beq error
|
||||
ora2 argv,argv+2,@a
|
||||
beq error
|
||||
|
||||
pei (argc)
|
||||
pei (argv+2)
|
||||
pei (argv)
|
||||
jsl main
|
||||
|
||||
pha ;save return value
|
||||
|
||||
pei (argv+2)
|
||||
pei (argv)
|
||||
pei (argc)
|
||||
jsl ~GNO_FREEARG
|
||||
|
||||
pla
|
||||
rtl
|
||||
|
||||
error ErrWriteCString #gnoerror
|
||||
lda #1
|
||||
rtl
|
||||
|
||||
gnoerror dc c'~GNO_COMMAND SYSTEM FAILURE!',h'0d0a00'
|
||||
|
||||
END
|
|
@ -0,0 +1,108 @@
|
|||
macro
|
||||
&lab ph4 &parm
|
||||
lclc &char
|
||||
lclc &char1
|
||||
lclc &char2
|
||||
&lab anop
|
||||
&char amid &parm,1,1
|
||||
aif "&char"="#",.immediate
|
||||
aif "&char"="@",.at
|
||||
aif s:longa=1,.chk1
|
||||
rep #%00100000
|
||||
.chk1
|
||||
aif "&char"<>"{",.chk2
|
||||
&char amid &parm,l:&parm,1
|
||||
aif "&char"<>"}",.error
|
||||
&parm amid &parm,2,l:&parm-2
|
||||
ldy #2
|
||||
lda (&parm),y
|
||||
pha
|
||||
lda (&parm)
|
||||
pha
|
||||
ago .shorten
|
||||
.chk2
|
||||
aif "&char"<>"[",.absolute
|
||||
ldy #2
|
||||
lda &parm,y
|
||||
pha
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.absolute
|
||||
lda &parm+2
|
||||
pha
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.at
|
||||
&char1 amid &parm,2,1
|
||||
&char2 setc &char1
|
||||
ph&char1
|
||||
aif l:&parm<3,.chk2a
|
||||
&char2 amid &parm,3,1
|
||||
.chk2a
|
||||
ph&char2
|
||||
ago .shorten
|
||||
.immediate
|
||||
&parm amid &parm,2,l:&parm-1
|
||||
pea +(&parm)|-16
|
||||
pea &parm
|
||||
ago .done
|
||||
.shorten
|
||||
aif s:longa=1,.done
|
||||
sep #%00100000
|
||||
.done
|
||||
mexit
|
||||
.error
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&lab ErrWriteCString &a1
|
||||
&lab ph4 &a1
|
||||
Tool $210c
|
||||
mend
|
||||
macro
|
||||
&lab tool &a1
|
||||
&lab ldx #&a1
|
||||
jsl $e10000
|
||||
mend
|
||||
macro
|
||||
&lab ora2 &arg1,&arg2,&dest
|
||||
&lab anop
|
||||
lclc &char
|
||||
&char amid &arg1,1,1
|
||||
aif "&char"="@",.at1
|
||||
lda &arg1
|
||||
ago .add
|
||||
.at1
|
||||
&char amid &arg1,2,1
|
||||
aif "&char"="x",.x1
|
||||
aif "&char"="X",.x1
|
||||
aif "&char"="y",.y1
|
||||
aif "&char"="Y",.y1
|
||||
ago .add
|
||||
.x1
|
||||
txa
|
||||
ago .add
|
||||
.y1
|
||||
tya
|
||||
.add
|
||||
ora &arg2
|
||||
&char amid &dest,1,1
|
||||
aif "&char"="@",.at2
|
||||
sta &dest
|
||||
ago .b
|
||||
.at2
|
||||
&char amid &dest,2,1
|
||||
aif "&char"="x",.x2
|
||||
aif "&char"="X",.x2
|
||||
aif "&char"="y",.y2
|
||||
aif "&char"="Y",.y2
|
||||
ago .b
|
||||
.x2
|
||||
tax
|
||||
ago .b
|
||||
.y2
|
||||
tay
|
||||
.b
|
||||
mend
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* $Id: gnomisc.c,v 1.1 1997/02/28 05:12:47 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tabs every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gno__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0 /* optimization breaks this file (79, 15 tried) */
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <sys/syslimits.h>
|
||||
#include <unistd.h>
|
||||
#include <gsos.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
int
|
||||
needsgno(void) {
|
||||
kernStatus();
|
||||
if (_toolErr) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static char *unknown = "(unknown)";
|
||||
static GetNameRecGS namerec = { 1, NULL };
|
||||
|
||||
char *
|
||||
__prognameGS (void) {
|
||||
namerec.pCount = 1;
|
||||
if (namerec.dataBuffer == NULL) {
|
||||
namerec.dataBuffer =
|
||||
(ResultBuf255Ptr) GOchange (NULL, NAME_MAX, NULL);
|
||||
if (namerec.dataBuffer == NULL) {
|
||||
return unknown;
|
||||
}
|
||||
GetNameGS(&namerec);
|
||||
if (_toolErr) {
|
||||
GOfree(namerec.dataBuffer);
|
||||
namerec.dataBuffer = NULL;
|
||||
return unknown;
|
||||
}
|
||||
/* NULL-terminate it */
|
||||
namerec.dataBuffer->bufString.text
|
||||
[namerec.dataBuffer->bufString.length] = '\0';
|
||||
}
|
||||
return namerec.dataBuffer->bufString.text;
|
||||
}
|
||||
|
||||
void
|
||||
WriteGString (GSStringPtr gp) {
|
||||
/* perhaps this should call WriteGS directly */
|
||||
write(STDERR_FILENO, gp->text, gp->length);
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Apple IIgs specific string handling routines.
|
||||
*
|
||||
* The routines GIinit, GOinit, GIchange, GOchange, the macros
|
||||
* GIfree and GOfree (in <gsos.h>), and typdefs for the GSString
|
||||
* and ResultBuf pointers (in <types.h>) come from Soenke Behrens'
|
||||
* GSString library.
|
||||
*
|
||||
* __C2GSMALLOC, __GS2CMALLOC, and __GS2C were rewritten from spec
|
||||
* from the GNO v2.0.4 libc(3) man page (with a change of argument and
|
||||
* result types) by Devin Reade. __C2GS was written by Devin Reade.
|
||||
*
|
||||
* $Id: gsstring.c,v 1.1 1997/02/28 05:12:47 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gno__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0 /* 79 seems to work */
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <machine/limits.h>
|
||||
#include <types.h>
|
||||
#include <gno/gno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize a GSString structure by allocating memory for a string
|
||||
* of length 'length'. The caller has to check for errors, if any
|
||||
* occured, the returned ptr will be NULL.
|
||||
*
|
||||
* gdr:
|
||||
* - Add space for an extra NULL byte in the text field.
|
||||
* - Allow the user to specify a C string initializer.
|
||||
*/
|
||||
|
||||
GSStringPtr
|
||||
GIinit (word length, const char *str)
|
||||
{
|
||||
return GIchange(NULL, length, str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the length of a GSString. Again, the caller has to check for errors,
|
||||
* the returned ptr is NULL if any occured.
|
||||
*
|
||||
* gdr:
|
||||
* - Add space for an extra NULL byte in the text field.
|
||||
* - Allow the user to specify a C string initializer.
|
||||
*/
|
||||
|
||||
GSStringPtr
|
||||
GIchange (GSStringPtr original, word length, const char *str)
|
||||
{
|
||||
/* this depends on a well-behaved realloc when given the NULL ptr */
|
||||
original = realloc (original, sizeof(word) + length + 1);
|
||||
if (original == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
original->length = length;
|
||||
if (str != NULL) {
|
||||
/* can't walk off end of str, so don't use memcpy */
|
||||
strncpy(original->text, str, length);
|
||||
} else {
|
||||
original->text[0] = '\0';
|
||||
}
|
||||
original->text[length] = '\0';
|
||||
return original;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a ResultBuf structure by allocating memory for a string
|
||||
* of length 'length'. The caller has to check for errors, if any
|
||||
* occured, the returned ptr will be NULL.
|
||||
*/
|
||||
|
||||
ResultBufPtr
|
||||
GOinit (unsigned int length, const char *str)
|
||||
{
|
||||
return GOchange(NULL, length, str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the length of the ResultBuf. Again, the caller has to check for
|
||||
* errors, the function returns NULL if any occured.
|
||||
*
|
||||
* gdr:
|
||||
* - Add space for an extra NULL byte in the text field.
|
||||
* - Allow the user to specify a C string initializer.
|
||||
*/
|
||||
|
||||
ResultBufPtr
|
||||
GOchange (ResultBufPtr original, unsigned int length, const char *str)
|
||||
{
|
||||
size_t len, orglen;
|
||||
ResultBufPtr result;
|
||||
|
||||
/* this depends on a well-behaved realloc when given the NULL ptr */
|
||||
len = 2 * sizeof(word) + length;
|
||||
orglen = (original) ? original->bufString.length : 0;
|
||||
result = realloc (original, len + 1);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
result->bufSize = len;
|
||||
if (str != NULL) {
|
||||
/* can't walk off end of str, so don't use memcpy */
|
||||
len = strlen(str);
|
||||
len = MIN(len, length);
|
||||
result->bufString.length = len;
|
||||
strncpy(result->bufString.text, str, len);
|
||||
result->bufString.text[len] = '\0';
|
||||
} else if (original == NULL) { /* && str == NULL */
|
||||
result->bufString.length = 0;
|
||||
result->bufString.text[0] = '\0';
|
||||
} else if (length < orglen) {
|
||||
result->bufString.length = length;
|
||||
} /* else leave original GSStringPtr untouched */
|
||||
|
||||
result->bufString.text[length] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* reimplementations for the next three ...
|
||||
*/
|
||||
|
||||
GSStringPtr
|
||||
__C2GSMALLOC (const char *s) {
|
||||
size_t len;
|
||||
|
||||
len = strlen(s);
|
||||
if (len > USHRT_MAX - 1) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
return GIchange(NULL, len, s);
|
||||
}
|
||||
|
||||
char *
|
||||
__GS2CMALLOC (const GSStringPtr g) {
|
||||
char *p;
|
||||
|
||||
if ((p = malloc(g->length + 1)) != NULL) {
|
||||
strncpy(p, g->text, g->length);
|
||||
p[g->length] = '\0';
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
__GS2C (char *s, const GSStringPtr g) {
|
||||
strncpy(s, g->text, g->length);
|
||||
s[g->length] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* __C2GS
|
||||
*
|
||||
* Converts a null-terminated C string into a class 1 GS/OS string.
|
||||
* Space for the GS/OS string must already be allocated, and the
|
||||
* length of s must be less than USHRT_MAX chars.
|
||||
*
|
||||
* If the s is too long, __C2GS will return NULL, otherwise it will
|
||||
* return the GS/OS string g.
|
||||
*
|
||||
* As a side effect, g->text will also be NULL-terminated.
|
||||
*/
|
||||
|
||||
GSStringPtr
|
||||
__C2GS(const char *s, GSStringPtr g)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = strlen(s);
|
||||
if (len > USHRT_MAX - 1) {
|
||||
errno = EINVAL;
|
||||
return NULL; /* the string won't fit */
|
||||
}
|
||||
g->length = len;
|
||||
strncpy(g->text, s, len);
|
||||
g->text[len] = '\0';
|
||||
return g;
|
||||
}
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* libc/gno/map.c -- various mapping functions
|
||||
*
|
||||
* $Id: map.c,v 1.1 1997/02/28 05:12:47 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tabstops every 8 columns
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_gno__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma memorymodel 0
|
||||
#pragma debug 0
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
/* needed only during debugging */
|
||||
#include <stdio.h>
|
||||
|
||||
#define GS_READ 0x0001
|
||||
#define GS_WRITE 0x0002
|
||||
#define GS_INVISIBLE 0x0004
|
||||
#define GS_BACKUP 0x0020
|
||||
#define GS_RENAME 0x0040
|
||||
#define GS_DESTROY 0x0080
|
||||
#define GS_MASK 0xFF18 /* complement of bitwise-OR of above GS- values */
|
||||
|
||||
static int __fileModeEmulation = 1; /* do we emulate Unix mode parameters? */
|
||||
|
||||
/*
|
||||
* _getModeEmulation
|
||||
*/
|
||||
|
||||
int
|
||||
_getModeEmulation (void) {
|
||||
return __fileModeEmulation;
|
||||
}
|
||||
|
||||
/*
|
||||
* _setModeEmulation
|
||||
*/
|
||||
|
||||
int
|
||||
_setModeEmulation (int newval) {
|
||||
int result;
|
||||
|
||||
result = __fileModeEmulation;
|
||||
__fileModeEmulation = !(newval == 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* _mapMode2GS -- Take a Unix mode and return the GS/OS equivalent.
|
||||
*
|
||||
* Devin Reade <gdr@myrias.com>
|
||||
*/
|
||||
|
||||
mode_t
|
||||
_mapMode2GS(mode_t oldmode) {
|
||||
mode_t newmode = GS_BACKUP;
|
||||
|
||||
if (__fileModeEmulation == 0) {
|
||||
return oldmode;
|
||||
}
|
||||
if (oldmode & S_IRUSR) {
|
||||
newmode |= GS_READ;
|
||||
}
|
||||
if (oldmode & S_IWUSR) {
|
||||
newmode |= GS_WRITE | GS_RENAME | GS_DESTROY;
|
||||
}
|
||||
return newmode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _mapMode2Unix -- Take a GS/OS mode and return the Unix equivalent.
|
||||
*
|
||||
* Devin Reade <gdr@myrias.com>
|
||||
*/
|
||||
|
||||
mode_t
|
||||
_mapMode2Unix(mode_t oldmode) {
|
||||
mode_t newmode = S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
int mask;
|
||||
|
||||
if (__fileModeEmulation == 0) {
|
||||
return oldmode;
|
||||
}
|
||||
if (oldmode & GS_READ) {
|
||||
newmode |= S_IRUSR | S_IRGRP | S_IROTH;
|
||||
}
|
||||
if ((oldmode & GS_WRITE) && (oldmode & GS_RENAME) &&
|
||||
(oldmode & GS_DESTROY)) {
|
||||
newmode |= S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
}
|
||||
|
||||
/* get the umask */
|
||||
umask((mask = umask(0)));
|
||||
return newmode & mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* _setPathMapping -- control whether or not we map pathnames
|
||||
*
|
||||
* Devin Reade <gdr@myrias.com>
|
||||
*/
|
||||
|
||||
static int __force_slash = 0; /* default: no pathname mapping */
|
||||
|
||||
int
|
||||
_setPathMapping (int val) {
|
||||
int previous = __force_slash;
|
||||
|
||||
__force_slash = (val != 0);
|
||||
return previous;
|
||||
}
|
||||
|
||||
int
|
||||
_getPathMapping (void) {
|
||||
return __force_slash;
|
||||
}
|
||||
|
||||
/*
|
||||
* _mapPath -- map all occurances of ':' to '/'
|
||||
*
|
||||
* Devin Reade <gdr@myrias.com>
|
||||
*/
|
||||
|
||||
char *
|
||||
_mapPath (char *pathname) {
|
||||
char *p;
|
||||
int foundSlash, foundColon;
|
||||
|
||||
if (! __force_slash) {
|
||||
return pathname;
|
||||
}
|
||||
|
||||
/* validity check */
|
||||
foundSlash = foundColon = 0;
|
||||
for (p = pathname; *p != '\0'; p++) {
|
||||
if (*p == ':') foundColon = 1;
|
||||
if (*p == '/') foundSlash = 1;
|
||||
}
|
||||
if (foundSlash && foundColon) {
|
||||
return NULL;
|
||||
}
|
||||
for (p = pathname; *p != '\0'; p++) {
|
||||
if (*p == ':') *p = '/';
|
||||
}
|
||||
return pathname;
|
||||
}
|
||||
|
||||
/*
|
||||
* _mapPathGS -- map all occurances of ':' to '/'
|
||||
*
|
||||
* Devin Reade <gdr@myrias.com>
|
||||
*/
|
||||
|
||||
GSStringPtr
|
||||
_mapPathGS (GSStringPtr pathname) {
|
||||
char *p, *q;
|
||||
int foundSlash, foundColon;
|
||||
|
||||
if (! __force_slash || pathname->length == 0) {
|
||||
return pathname;
|
||||
}
|
||||
|
||||
/* validity check */
|
||||
foundSlash = foundColon = 0;
|
||||
p = pathname->text;
|
||||
q = p + pathname->length;
|
||||
while (p < q) {
|
||||
if (*p == ':') foundColon = 1;
|
||||
if (*p == '/') foundSlash = 1;
|
||||
p++;
|
||||
}
|
||||
if (foundSlash && foundColon) {
|
||||
return NULL;
|
||||
}
|
||||
p = pathname->text;
|
||||
while (p < q) {
|
||||
if (*p == ':') *p = '/';
|
||||
p++;
|
||||
}
|
||||
return pathname;
|
||||
}
|
||||
|
||||
/*
|
||||
* _mapErr -- Take a GS/OS error and maps it to a kernel errno. If there
|
||||
* is no direct mapping, then map it to EIO.
|
||||
*/
|
||||
|
||||
int
|
||||
_mapErr (int err) {
|
||||
if (!err) {
|
||||
return 0;
|
||||
}
|
||||
if ((err & 0xff00) == 0x4300) {
|
||||
/* GNO already mapped the error */
|
||||
return (err & 0x00ff);
|
||||
}
|
||||
switch (err) {
|
||||
case 0x43: return EBADF;
|
||||
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x46: return ENOENT;
|
||||
|
||||
case 0x47: return EEXIST;
|
||||
|
||||
case 0x48:
|
||||
case 0x49: return ENOSPC;
|
||||
case 0x4A: return ENOTDIR;
|
||||
|
||||
case 0x4B:
|
||||
case 0x4F:
|
||||
case 0x53: return EINVAL;
|
||||
case 0x54: return ENOMEM;
|
||||
case 0x4E: return EACCES;
|
||||
case 0x58: return ENOTBLK;
|
||||
default: return EIO;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
***********************************************************************
|
||||
*
|
||||
* GNO command-line parser
|
||||
* Version 1.0b
|
||||
* Written by Tim Meekins
|
||||
* Copyright (C) 1991-1996 by Procyon, Inc.
|
||||
*
|
||||
* This function will take the command-line passed to a utility and parse
|
||||
* it into an argv,argc structure like those used in C programs. This
|
||||
* was written NOT as a replacement for a C parser, but for use by assembly
|
||||
* language programmers writing shell commands.
|
||||
*
|
||||
* This function ASSUMES that the ByteWorks Memory Manager has been started
|
||||
* up and is usable. This will eventually be superceded by the GNO Memory
|
||||
* Management library.
|
||||
*
|
||||
* This function is based on actual GNO/ME shell (gsh) parsing code.
|
||||
*
|
||||
* $Id: parsearg.asm,v 1.1 1997/02/28 05:12:47 gdr Exp $
|
||||
*
|
||||
**************************************************************************
|
||||
|
||||
keep parsearg
|
||||
mcopy parsearg.mac
|
||||
|
||||
dummy START ; ends up in .root
|
||||
END
|
||||
|
||||
**************************************************************************
|
||||
*
|
||||
* Parse a single command
|
||||
*
|
||||
**************************************************************************
|
||||
|
||||
~GNO_PARSEARG START
|
||||
;
|
||||
; TOKENS used by the parser
|
||||
;
|
||||
T_WORD equ 1
|
||||
T_EOF equ 2
|
||||
|
||||
MAXARG equ 256
|
||||
;
|
||||
; What state is the lexical analyzer in
|
||||
;
|
||||
NEUTRAL equ 0 ;a neutral state, get anything
|
||||
INQUOTE equ 1 ;parsing a quoted string
|
||||
INWORD equ 2 ;parsing a word
|
||||
SINGQUOTE equ 3 ;single quote string
|
||||
;
|
||||
; local variables and function parameters
|
||||
;
|
||||
ptr equ 1
|
||||
ch equ ptr+4
|
||||
state equ ch+2
|
||||
buf equ state+2
|
||||
argv equ buf+4
|
||||
word equ argv+4
|
||||
temp equ word+4
|
||||
argc equ temp+4
|
||||
space equ argc+2
|
||||
argptr equ space+3
|
||||
commandline equ argptr+4
|
||||
end equ commandline+4
|
||||
|
||||
; subroutine (4:commandline,4:argptr),space
|
||||
|
||||
tsc
|
||||
sec
|
||||
sbc #space-1
|
||||
tcs
|
||||
phd
|
||||
tcd
|
||||
|
||||
add4 commandline,#8,buf
|
||||
|
||||
ph4 #1024
|
||||
jsl ~NEW
|
||||
sta word
|
||||
stx word+2
|
||||
|
||||
ph4 #MAXARG*4
|
||||
jsl ~NEW
|
||||
sta argv
|
||||
stx argv+2
|
||||
ldy #2
|
||||
sta [argptr]
|
||||
txa
|
||||
sta [argptr],y
|
||||
|
||||
stz argc
|
||||
|
||||
loop jsr gettoken
|
||||
cmp #T_WORD
|
||||
beq tok_word
|
||||
jmp tok_eof
|
||||
;
|
||||
; Parse a word token
|
||||
;
|
||||
tok_word if2 argc,ne,#MAXARG,word1
|
||||
jmp done
|
||||
word1 anop
|
||||
ldy #0
|
||||
lenloop lda [word],y
|
||||
iny
|
||||
and #$FF
|
||||
bne lenloop
|
||||
pea 0
|
||||
phy
|
||||
jsl ~NEW
|
||||
sta temp
|
||||
stx temp+2
|
||||
ora temp+2
|
||||
bne word2
|
||||
jmp error
|
||||
word2 lda argc ;Copy word to argv[argc]
|
||||
asl2 a
|
||||
tay
|
||||
lda temp
|
||||
sta [argv],y
|
||||
lda temp+2
|
||||
iny2
|
||||
sta [argv],y
|
||||
ldy #0
|
||||
short a
|
||||
copyloop lda [word],y
|
||||
sta [temp],y
|
||||
iny
|
||||
cmp #0
|
||||
bne copyloop
|
||||
long a
|
||||
|
||||
inc argc ;increment argument count
|
||||
jmp loop
|
||||
;
|
||||
; Parse a command terminator
|
||||
;
|
||||
tok_eof anop
|
||||
|
||||
lda argc
|
||||
asl2 a
|
||||
tay
|
||||
lda #0
|
||||
sta [argv],y
|
||||
iny2
|
||||
sta [argv],y
|
||||
|
||||
pei (word+2)
|
||||
pei (word)
|
||||
jsl ~DISPOSE
|
||||
|
||||
done ldy argc
|
||||
|
||||
exit lda space
|
||||
sta end-3
|
||||
lda space+1
|
||||
sta end-2
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #end-4
|
||||
tcs
|
||||
|
||||
tya
|
||||
rtl
|
||||
|
||||
error anop
|
||||
|
||||
ldy #0
|
||||
jmp exit
|
||||
|
||||
;=====================================================================
|
||||
;
|
||||
; lexical stage, return the next token
|
||||
;
|
||||
;=====================================================================
|
||||
|
||||
gettoken anop
|
||||
|
||||
mv4 word,ptr
|
||||
;
|
||||
; start in the neutral state
|
||||
;
|
||||
ld2 NEUTRAL,state
|
||||
;
|
||||
; the main loop
|
||||
;
|
||||
lexloop lda [buf]
|
||||
inc buf
|
||||
and2 @a,#$FF,ch
|
||||
bne switch
|
||||
|
||||
if2 state,ne,#INWORD,loop2
|
||||
jmp endword
|
||||
|
||||
loop2 lda #T_EOF
|
||||
jmp lexdone
|
||||
;
|
||||
; jump to the current state
|
||||
;
|
||||
switch lda state
|
||||
asl a
|
||||
tax
|
||||
jmp (statetbl,x)
|
||||
statetbl dc a2'case_neutral'
|
||||
dc a2'case_inquote'
|
||||
dc a2'case_inword'
|
||||
dc a2'case_single'
|
||||
;
|
||||
; CASE NEUTRAL
|
||||
;
|
||||
case_neutral if2 ch,eq,#' ',lexloop ;space
|
||||
if2 @a,eq,#9,lexloop ;tab
|
||||
if2 @a,ne,#13,neut4 ;return
|
||||
lda #T_EOF
|
||||
jmp lexdone
|
||||
neut4 if2 @a,ne,#0,neut5 ;EOF
|
||||
lda #T_EOF
|
||||
jmp lexdone
|
||||
neut5 if2 @a,ne,#'"',neut7
|
||||
startquote lda #INQUOTE
|
||||
bra neut10
|
||||
neut7 if2 @a,ne,#"'",neut8
|
||||
startsingle lda #SINGQUOTE
|
||||
bra neut10
|
||||
neut8 if2 @a,ne,#'\',neut9
|
||||
lda [buf]
|
||||
and #$FF
|
||||
inc buf
|
||||
neut9 sta [ptr] ;default
|
||||
inc ptr
|
||||
lda #INWORD
|
||||
neut10 sta state
|
||||
jmp lexloop
|
||||
;
|
||||
; CASE INQUOTE
|
||||
;
|
||||
case_inquote if2 ch,ne,#'\',quote2 ;is it a quoted character?
|
||||
lda [buf]
|
||||
inc buf
|
||||
putword sta [ptr]
|
||||
inc ptr
|
||||
jmp lexloop
|
||||
quote2 if2 @a,ne,#'"',putword
|
||||
ld2 INWORD,state
|
||||
jmp lexloop
|
||||
;
|
||||
; CASE SINGLEQUOTE
|
||||
;
|
||||
case_single anop
|
||||
if2 ch,ne,#"'",putword
|
||||
ld2 INWORD,state
|
||||
jmp lexloop
|
||||
;
|
||||
; CASE INWORD
|
||||
;
|
||||
case_inword if2 ch,eq,#000,endword
|
||||
if2 @a,eq,#' ',endword
|
||||
if2 @a,eq,#009,endword
|
||||
if2 @a,eq,#013,endword
|
||||
cmp #'"'
|
||||
jeq startquote
|
||||
cmp #"'"
|
||||
jeq startsingle
|
||||
if2 @a,ne,#'\',putword
|
||||
lda [buf]
|
||||
inc buf
|
||||
bra putword
|
||||
endword dec buf
|
||||
finiword lda #0
|
||||
sta [ptr]
|
||||
lda #T_WORD
|
||||
|
||||
lexdone rts
|
||||
|
||||
END
|
||||
|
||||
**************************************************************************
|
||||
*
|
||||
* Free the argv[] list
|
||||
*
|
||||
**************************************************************************
|
||||
|
||||
~GNO_FREEARG START
|
||||
|
||||
space equ 1
|
||||
argc equ space+3
|
||||
argv equ argc+2
|
||||
end equ argv+4
|
||||
|
||||
; subroutine (4:argv,2:argc),space
|
||||
|
||||
tsc
|
||||
phd
|
||||
tcd
|
||||
|
||||
ldy #0
|
||||
loop lda argc
|
||||
beq done
|
||||
dec argc
|
||||
lda [argv],y
|
||||
tax
|
||||
iny2
|
||||
lda [argv],y
|
||||
iny2
|
||||
phy
|
||||
pha
|
||||
phx
|
||||
jsl ~DISPOSE
|
||||
ply
|
||||
bra loop
|
||||
|
||||
done pei (argv+2)
|
||||
pei (argv)
|
||||
jsl ~DISPOSE
|
||||
|
||||
lda space
|
||||
sta end-3
|
||||
lda space+1
|
||||
sta end-2
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #end-4
|
||||
tcs
|
||||
|
||||
rtl
|
||||
|
||||
END
|
|
@ -0,0 +1,263 @@
|
|||
macro
|
||||
&lab ph4 &parm
|
||||
lclc &char
|
||||
lclc &char1
|
||||
lclc &char2
|
||||
&lab anop
|
||||
&char amid &parm,1,1
|
||||
aif "&char"="#",.immediate
|
||||
aif "&char"="@",.at
|
||||
aif s:longa=1,.chk1
|
||||
rep #%00100000
|
||||
.chk1
|
||||
aif "&char"<>"{",.chk2
|
||||
&char amid &parm,l:&parm,1
|
||||
aif "&char"<>"}",.error
|
||||
&parm amid &parm,2,l:&parm-2
|
||||
ldy #2
|
||||
lda (&parm),y
|
||||
pha
|
||||
lda (&parm)
|
||||
pha
|
||||
ago .shorten
|
||||
.chk2
|
||||
aif "&char"<>"[",.absolute
|
||||
ldy #2
|
||||
lda &parm,y
|
||||
pha
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.absolute
|
||||
lda &parm+2
|
||||
pha
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.at
|
||||
&char1 amid &parm,2,1
|
||||
&char2 setc &char1
|
||||
ph&char1
|
||||
aif l:&parm<3,.chk2a
|
||||
&char2 amid &parm,3,1
|
||||
.chk2a
|
||||
ph&char2
|
||||
ago .shorten
|
||||
.immediate
|
||||
&parm amid &parm,2,l:&parm-1
|
||||
pea +(&parm)|-16
|
||||
pea &parm
|
||||
ago .done
|
||||
.shorten
|
||||
aif s:longa=1,.done
|
||||
sep #%00100000
|
||||
.done
|
||||
mexit
|
||||
.error
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&lab LD2 &val,&adr
|
||||
&lab lcla &count
|
||||
lda #&val
|
||||
&count seta 1
|
||||
.loop
|
||||
sta &adr(&count)
|
||||
&count seta &count+1
|
||||
aif &count>c:&adr,.done
|
||||
ago ^loop
|
||||
.done
|
||||
mend
|
||||
macro
|
||||
&lab MV4 &src,&adr
|
||||
&lab lcla &count
|
||||
lda &src
|
||||
&count seta 1
|
||||
.loop1
|
||||
sta &adr(&count)
|
||||
&count seta &count+1
|
||||
aif &count>c:&adr,.part2
|
||||
ago ^loop1
|
||||
.part2
|
||||
lda &src+2
|
||||
&count seta 1
|
||||
.loop2
|
||||
sta &adr(&count)+2
|
||||
&count seta &count+1
|
||||
aif &count>c:&adr,.done
|
||||
ago ^loop2
|
||||
.done
|
||||
mend
|
||||
macro
|
||||
&lab long &stat
|
||||
&lab anop
|
||||
lcla &t
|
||||
lcla &len
|
||||
lclc &ch
|
||||
&t seta 0
|
||||
&len seta l:&stat
|
||||
.a
|
||||
aif &len=0,.b
|
||||
&ch amid &stat,&len,1
|
||||
aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i
|
||||
aif ("&ch"="a").or.("&ch"="m"),.m
|
||||
.c
|
||||
&len seta &len-1
|
||||
ago ^a
|
||||
.i
|
||||
longi on
|
||||
&t seta &t+16
|
||||
ago ^c
|
||||
.m
|
||||
longa on
|
||||
&t seta &t+32
|
||||
ago ^c
|
||||
.b
|
||||
aif &t=0,.d
|
||||
rep #&t
|
||||
.d
|
||||
mend
|
||||
macro
|
||||
&lab short &stat
|
||||
&lab anop
|
||||
lcla &t
|
||||
lcla &len
|
||||
lclc &ch
|
||||
&t seta 0
|
||||
&len seta l:&stat
|
||||
.a
|
||||
aif &len=0,.b
|
||||
&ch amid &stat,&len,1
|
||||
aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i
|
||||
aif ("&ch"="a").or.("&ch"="m"),.m
|
||||
.c
|
||||
&len seta &len-1
|
||||
ago ^a
|
||||
.i
|
||||
longi off
|
||||
&t seta &t+16
|
||||
ago ^c
|
||||
.m
|
||||
longa off
|
||||
&t seta &t+32
|
||||
ago ^c
|
||||
.b
|
||||
aif &t=0,.d
|
||||
sep #&t
|
||||
.d
|
||||
mend
|
||||
macro
|
||||
&lab asl2 &a
|
||||
&lab asl &a
|
||||
asl &a
|
||||
mend
|
||||
macro
|
||||
&lab iny2
|
||||
&lab iny
|
||||
iny
|
||||
mend
|
||||
macro
|
||||
&lab and2 &arg1,&arg2,&dest
|
||||
&lab anop
|
||||
lclc &char
|
||||
&char amid &arg1,1,1
|
||||
aif "&char"="@",.at1
|
||||
lda &arg1
|
||||
ago .add
|
||||
.at1
|
||||
&char amid &arg1,2,1
|
||||
aif "&char"="x",.x1
|
||||
aif "&char"="X",.x1
|
||||
aif "&char"="y",.y1
|
||||
aif "&char"="Y",.y1
|
||||
ago .add
|
||||
.x1
|
||||
txa
|
||||
ago .add
|
||||
.y1
|
||||
tya
|
||||
.add
|
||||
and &arg2
|
||||
&char amid &dest,1,1
|
||||
aif "&char"="@",.at2
|
||||
sta &dest
|
||||
ago .b
|
||||
.at2
|
||||
&char amid &dest,2,1
|
||||
aif "&char"="x",.x2
|
||||
aif "&char"="X",.x2
|
||||
aif "&char"="y",.y2
|
||||
aif "&char"="Y",.y2
|
||||
ago .b
|
||||
.x2
|
||||
tax
|
||||
ago .b
|
||||
.y2
|
||||
tay
|
||||
.b
|
||||
mend
|
||||
macro
|
||||
&lab if2 &var,&rel,&val,&label
|
||||
&lab ago .skip
|
||||
ble
|
||||
bgt
|
||||
.skip
|
||||
lclc &char1
|
||||
lclc &char2
|
||||
&char1 amid &var,1,1
|
||||
&char2 amid &var,2,1
|
||||
aif "&char1"="@",.index
|
||||
lda &var
|
||||
.cmp
|
||||
cmp &val
|
||||
ago .branch
|
||||
.index
|
||||
aif "&char2"="x",.x1
|
||||
aif "&char2"="X",.x1
|
||||
aif "&char2"="y",.y1
|
||||
aif "&char2"="Y",.y1
|
||||
ago ^cmp
|
||||
.x1
|
||||
cpx &val
|
||||
ago .branch
|
||||
.y1
|
||||
cpy &val
|
||||
.branch
|
||||
&char1 amid &rel,1,1
|
||||
aif "&char1"="@",.done
|
||||
b&rel &label
|
||||
.done
|
||||
mend
|
||||
macro
|
||||
&lab bgt &loc
|
||||
&lab beq *+4
|
||||
bcs &loc
|
||||
mend
|
||||
macro
|
||||
&lab ble &loc
|
||||
&lab bcc &loc
|
||||
beq &loc
|
||||
mend
|
||||
macro
|
||||
&lab jeq &loc
|
||||
&lab bne *+5
|
||||
jmp &loc
|
||||
mend
|
||||
macro
|
||||
&lab add4 &arg1,&arg2,&dest
|
||||
&lab anop
|
||||
lclc &ch
|
||||
&ch amid &arg2,1,1
|
||||
clc
|
||||
lda &arg1
|
||||
adc &arg2
|
||||
sta &dest
|
||||
lda &arg1+2
|
||||
aif "&ch"="#",.a
|
||||
adc &arg2+2
|
||||
ago .b
|
||||
.a
|
||||
adc &arg2|-16
|
||||
.b
|
||||
sta &dest+2
|
||||
mend
|
|
@ -0,0 +1,124 @@
|
|||
;
|
||||
; Stack checking routines by Phillip Vandry <vandry@cam.org>. Added
|
||||
; to GNO by Devin Reade <gdr@myrias.com>. See the man page for details.
|
||||
;
|
||||
; $Id: stack.asm,v 1.1 1997/02/28 05:12:47 gdr Exp $
|
||||
;
|
||||
|
||||
keep stack
|
||||
|
||||
mcopy stack.mac
|
||||
case on
|
||||
|
||||
* This test function goes into "stack.ROOT", which is not used
|
||||
|
||||
main start
|
||||
jsl _beginStackCheck
|
||||
ldx #16
|
||||
jsr recurse
|
||||
jsl _endStackCheck
|
||||
rtl
|
||||
recurse dex
|
||||
beq outs
|
||||
jsr recurse
|
||||
outs rts
|
||||
end
|
||||
|
||||
_beginStackCheck start libc_gno__
|
||||
using stack_str
|
||||
phb
|
||||
pha
|
||||
pha
|
||||
pea 0
|
||||
phd
|
||||
~FindHandle *
|
||||
tsc
|
||||
phd
|
||||
tcd
|
||||
pha
|
||||
pha
|
||||
pei 3
|
||||
pei 1
|
||||
~GetHandleSize *
|
||||
pla
|
||||
sta >stack_size
|
||||
pla
|
||||
lda [1]
|
||||
|
||||
* leave 256 bytes at the beginning for SANE
|
||||
clc
|
||||
adc #256
|
||||
|
||||
tay ; start of handle
|
||||
sta >stack_loc
|
||||
ldx #0
|
||||
tsc
|
||||
dec a
|
||||
dec a
|
||||
sta 3
|
||||
pea 0
|
||||
plb
|
||||
plb
|
||||
lppp anop
|
||||
txa
|
||||
and #%111
|
||||
tax
|
||||
lda >stack_str,x
|
||||
sta |0,y
|
||||
iny
|
||||
inx
|
||||
cpy 3
|
||||
bcc lppp
|
||||
pld
|
||||
pla
|
||||
pla
|
||||
plb
|
||||
rtl
|
||||
end
|
||||
|
||||
_endStackCheck start libc_gno__
|
||||
using stack_str
|
||||
phb
|
||||
pea 0
|
||||
plb
|
||||
plb
|
||||
lda >stack_loc
|
||||
tay
|
||||
ldx #0
|
||||
lda |0,y
|
||||
cmp >stack_str,x
|
||||
beq lp2
|
||||
lda #$ffff ; gone over
|
||||
bra terminate
|
||||
|
||||
lp2 anop
|
||||
txa
|
||||
and #%111
|
||||
tax
|
||||
lda |0,y
|
||||
cmp >stack_str,x
|
||||
bne gotend
|
||||
inx
|
||||
iny
|
||||
bra lp2
|
||||
gotend anop ; Y = Stack not used
|
||||
tya
|
||||
sec
|
||||
sbc >stack_loc
|
||||
pha
|
||||
lda >stack_size
|
||||
sec
|
||||
sbc 1,s
|
||||
ply
|
||||
terminate plb
|
||||
rtl
|
||||
end
|
||||
|
||||
setcom 50
|
||||
|
||||
stack_str privdata libc_gno__
|
||||
|
||||
dc c'StackChkS'
|
||||
stack_size ds 2
|
||||
stack_loc ds 2
|
||||
end
|
|
@ -0,0 +1,65 @@
|
|||
macro
|
||||
&l ~FindHandle &p1
|
||||
&l ph4 &p1
|
||||
ldx #$1A02
|
||||
jsl $E10000
|
||||
mend
|
||||
macro
|
||||
&l ~GetHandleSize &p1
|
||||
&l ph4 &p1
|
||||
ldx #$1802
|
||||
jsl $E10000
|
||||
mend
|
||||
macro
|
||||
&l ph4 &n1
|
||||
&l anop
|
||||
aif "&n1"="*",.f
|
||||
lclc &c
|
||||
&c amid &n1,1,1
|
||||
aif "&c"="#",.d
|
||||
aif s:longa=1,.a
|
||||
rep #%00100000
|
||||
.a
|
||||
aif "&c"<>"{",.b
|
||||
&c amid &n1,l:&n1,1
|
||||
aif "&c"<>"}",.g
|
||||
&n1 amid &n1,2,l:&n1-2
|
||||
ldy #2
|
||||
lda (&n1),y
|
||||
pha
|
||||
lda (&n1)
|
||||
pha
|
||||
ago .e
|
||||
.b
|
||||
aif "&c"<>"[",.c
|
||||
ldy #2
|
||||
lda &n1,y
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.c
|
||||
aif "&c"<>"<",.c1
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pei &n1+2
|
||||
pei &n1
|
||||
ago .e
|
||||
.c1
|
||||
lda &n1+2
|
||||
pha
|
||||
lda &n1
|
||||
pha
|
||||
ago .e
|
||||
.d
|
||||
&n1 amid &n1,2,l:&n1-1
|
||||
pea +(&n1)|-16
|
||||
pea &n1
|
||||
ago .f
|
||||
.e
|
||||
aif s:longa=1,.f
|
||||
sep #%00100000
|
||||
.f
|
||||
mexit
|
||||
.g
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:48 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJS = table.o
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
.INCLUDE: ../rules.mk
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* This is a dummy file for now. We need this definition so that
|
||||
* code compiled with #pragma debug -1 will not have the symbol unresolved.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int __mb_cur_max = 1;
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# Default rules for libc/gno (override of /usr/local/lib/startup.mk)
|
||||
# Devin Reade, 1997
|
||||
#
|
||||
# $Id: rules.mk,v 1.1 1997/02/28 05:12:39 gdr Exp $
|
||||
#
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -o $@ -c $(__OFLAG) $(CFLAGS) $<
|
||||
# $(MAKELIB) -l $(LIBC) $(MAKELIBFLAGS) $@
|
||||
|
||||
%.o: %.asm
|
||||
$(AS) -o $@ -c $(__OFLAG) $(ASFLAGS) $<
|
||||
@$(RM) $*.root
|
||||
# $(MAKELIB) -l $(LIBC) $(MAKELIBFLAGS) $@
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJS = mktemp.o perror.o tempnam.o
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
.INCLUDE: ../rules.mk
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is formatted with tab stops every 8 columns
|
||||
*
|
||||
* $Id: mktemp.c,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_stdio";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int _gettemp(char *path, int *doopen);
|
||||
|
||||
int
|
||||
mkstemp(char *path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
return (_gettemp(path, &fd) ? fd : -1);
|
||||
}
|
||||
|
||||
char *
|
||||
mktemp(char *path)
|
||||
{
|
||||
return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
_gettemp(char *path, register int *doopen)
|
||||
{
|
||||
extern int errno;
|
||||
register char *start, *trv;
|
||||
struct stat sbuf;
|
||||
u_int pid;
|
||||
char savechar;
|
||||
|
||||
pid = getpid();
|
||||
for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
|
||||
while (*--trv == 'X') {
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
|
||||
/*
|
||||
* check the target directory; if you have six X's and it
|
||||
* doesn't exist this runs for a *very* long time.
|
||||
*/
|
||||
for (start = trv + 1;; --trv) {
|
||||
if (trv <= path)
|
||||
break;
|
||||
if (*trv == '/' || *trv == ':') {
|
||||
savechar = *trv;
|
||||
*trv = '\0';
|
||||
if (stat(path, &sbuf))
|
||||
return(0);
|
||||
if (!S_ISDIR(sbuf.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
return(0);
|
||||
}
|
||||
*trv = savechar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (doopen) {
|
||||
if ((*doopen =
|
||||
open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
|
||||
return(1);
|
||||
if (errno != EEXIST)
|
||||
return(0);
|
||||
}
|
||||
else if (stat(path, &sbuf))
|
||||
return(errno == ENOENT ? 1 : 0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
for (trv = start;;) {
|
||||
if (!*trv)
|
||||
return(0);
|
||||
if (*trv == 'z')
|
||||
*trv++ = 'a';
|
||||
else {
|
||||
if (isdigit(*trv))
|
||||
*trv = 'a';
|
||||
else
|
||||
++*trv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Implementation by Devin Reade.
|
||||
*
|
||||
* $Id: perror.c,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
/* I have to do this until I can modify ORCALib */
|
||||
#define sys_errlist _gno_sys_errlist
|
||||
#define sys_nerr _gno_sys_nerr
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_stdio";
|
||||
#endif
|
||||
|
||||
#pragma databank 1
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <sys/errno.h> /* for ELAST */
|
||||
#include <stdio.h> /* for remainder */
|
||||
|
||||
const char * const sys_errlist[] = {
|
||||
|
||||
/* the following are used by both GNO and the Orca/Shell */
|
||||
|
||||
"unknown error", /* 0 */
|
||||
"domain error", /* 1 */
|
||||
"result too large", /* 2 */
|
||||
"not enough memory", /* 3 */
|
||||
"no such file or directory", /* 4 */
|
||||
"I/O error", /* 5 */
|
||||
"invalid argument", /* 6 */
|
||||
"bad file descriptor", /* 7 */
|
||||
"too many open files", /* 8 */
|
||||
"permission denied", /* 9 */
|
||||
"file exists", /* 10 */
|
||||
"no space left on device", /* 11 */
|
||||
|
||||
/* the following are GNO-specific */
|
||||
|
||||
"operation not permitted", /* 12 */
|
||||
"no such process", /* 13 */
|
||||
"interrupted system call", /* 14 */
|
||||
"arg list too long", /* 15 */
|
||||
"exec format error", /* 16 */
|
||||
"no child processes", /* 17 */
|
||||
"resource unavailable", /* 18 */
|
||||
"not a directory", /* 19 */
|
||||
"inappropriate ioctl for device", /* 20 */
|
||||
"broken pipe", /* 21 */
|
||||
"illegal seek", /* 22 */
|
||||
"block device required", /* 23 */
|
||||
"is a directory", /* 24 */
|
||||
"not a socket", /* 25 */
|
||||
"destination address required", /* 26 */
|
||||
"message too long", /* 27 */
|
||||
"wrong protocol for socket", /* 28 */
|
||||
"protocol not available", /* 29 */
|
||||
"protocol not supported", /* 30 */
|
||||
"socket type not supported", /* 31 */
|
||||
"operation not supported on socket", /* 32 */
|
||||
"protocol family not supported", /* 33 */
|
||||
"address family not supported", /* 34 */
|
||||
"address already in use", /* 35 */
|
||||
"can't assign requested address", /* 36 */
|
||||
"network is down", /* 37 */
|
||||
"network is unreachable", /* 38 */
|
||||
"network dropped connection on reset", /* 39 */
|
||||
"connection aborted", /* 40 */
|
||||
"connection reset by peer", /* 41 */
|
||||
"no buffer space available", /* 42 */
|
||||
"socket is already connected", /* 43 */
|
||||
"socket is not connected", /* 44 */
|
||||
"can't send after socket shutdown", /* 45 */
|
||||
"too many references: can't splice", /* 46 */
|
||||
"connection timed out", /* 47 */
|
||||
"connection refused", /* 48 */
|
||||
"operation would block", /* 49 */
|
||||
"operation now in progress", /* 50 */
|
||||
"operation already in progress", /* 51 */
|
||||
"bad address", /* 52 */
|
||||
"no such device", /* 53 */
|
||||
"host is down", /* 54 */
|
||||
"no route to host", /* 55 */
|
||||
#define SYS_NERR 56 /* 55 + 1 for zeroth entry */
|
||||
};
|
||||
|
||||
#if (ELAST + 1 != SYS_NERR)
|
||||
#error message table out of sync
|
||||
#endif
|
||||
|
||||
const int
|
||||
sys_nerr = SYS_NERR;
|
||||
|
||||
const char * const *
|
||||
_errnoText = sys_errlist; /* backward compatible */
|
||||
|
||||
char *
|
||||
strerror (int errnum)
|
||||
{
|
||||
/*
|
||||
* the size of buff must be greater than
|
||||
* strlen(sys_errlist[0]) + max number of digits in an int + 3
|
||||
* == 13 + 5 + 3 == 21
|
||||
*/
|
||||
static char buff[30];
|
||||
|
||||
if (errnum > 0 || errnum < sys_nerr) {
|
||||
return sys_errlist[errnum];
|
||||
}
|
||||
sprintf(buff, "unknown error: %d", errnum);
|
||||
return buff;
|
||||
}
|
||||
|
||||
/*
|
||||
* This implementation of perror should be replaced with one similar to
|
||||
* that for 4.4BSD, so that stdio doesn't need to get linked in.
|
||||
*/
|
||||
|
||||
void
|
||||
perror (char *s)
|
||||
{
|
||||
char *s1, *s2;
|
||||
|
||||
if (s == NULL) {
|
||||
s1 = s2 = "";
|
||||
} else {
|
||||
s1 = s;
|
||||
s2 = ": ";
|
||||
}
|
||||
if (errno <= 0 || errno >= sys_nerr) {
|
||||
fprintf(stderr, "%s%s%s: %d\n", s1, s2, sys_errlist[0], errno);
|
||||
} else {
|
||||
fprintf(stderr,"%s%s%s\n", s1, s2, sys_errlist[errno]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Temporary file and filename routines.
|
||||
*
|
||||
* $Id: tempnam.c,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 characters.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_stdio";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define max(A,B) (((A)<(B))?(B):(A))
|
||||
|
||||
/*
|
||||
* tempnam
|
||||
*
|
||||
* Generate a pathname for a temporary file.
|
||||
*
|
||||
* tempnam will select a directory for the temporary file by using the
|
||||
* following criteria:
|
||||
*
|
||||
* If dir is not the NULL pointer, tempnam uses the pathname pointed to by
|
||||
* dir as the directory,
|
||||
*
|
||||
* otherwise, tmpdir uses the value of the TMPDIR environment variable if
|
||||
* the variable is defined,
|
||||
*
|
||||
* otherwise the directory defined by P_tmpdir in the stdio.h header file
|
||||
* if that directory is writable by the caller,
|
||||
*
|
||||
* otherwise, tempnam will use "/tmp" as a last resort.
|
||||
*/
|
||||
|
||||
|
||||
static char seed[4]="AAA";
|
||||
|
||||
/*
|
||||
* cpdir - copy <str> into <buf>, removing the trailing directory separator
|
||||
* if necessary.
|
||||
*/
|
||||
|
||||
static char *
|
||||
cpdir(char *buf, char *str)
|
||||
{
|
||||
char *p, pbrk;
|
||||
|
||||
if(str != NULL) {
|
||||
strcpy(buf, str);
|
||||
p = buf + strlen(buf) -1;
|
||||
pbrk = strchr(buf,':') ? ':' : '/'; /* for GS/OS */
|
||||
if(*p == pbrk) *p = '\0';
|
||||
}
|
||||
return(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* tempnam
|
||||
* dir -- use this directory please (if non-NULL)
|
||||
* prefix -- use this (if non-NULL) as filename prefix
|
||||
*/
|
||||
|
||||
char *
|
||||
tempnam (const char *dir, const char *prefix)
|
||||
{
|
||||
register char *p, *q, *tmpdir, pbrk;
|
||||
int tl=0, dl=0, pl;
|
||||
|
||||
/* create a buffer <p> that's as large as necessary */
|
||||
pl = strlen(P_tmpdir);
|
||||
if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir);
|
||||
if( dir != NULL ) dl = strlen(dir);
|
||||
if( (p = malloc((unsigned int)(max(max(dl,tl),pl)+16))) == NULL )
|
||||
return(NULL);
|
||||
*p = '\0';
|
||||
|
||||
#define PERM W_OK
|
||||
|
||||
if( (dl == 0) || (access( cpdir(p, dir), PERM) != 0) )
|
||||
if( (tl == 0) || (access( cpdir(p, tmpdir), PERM) != 0) )
|
||||
if( access( cpdir(p, P_tmpdir), PERM) != 0 )
|
||||
if( access( cpdir(p, "/tmp"), PERM) != 0 )
|
||||
return(NULL);
|
||||
|
||||
pbrk = strchr(p,':') ? ':' : '/';
|
||||
q = p + strlen(p);
|
||||
*q++ = pbrk;
|
||||
*q = '\0';
|
||||
if(prefix) {
|
||||
*(p+strlen(p)+5) = '\0';
|
||||
(void)strncat(p, prefix, 5);
|
||||
}
|
||||
|
||||
strcat(p, seed);
|
||||
strcat(p, "XXXXXX");
|
||||
|
||||
q = seed;
|
||||
while(*q == 'Z') *q++ = 'A';
|
||||
++*q;
|
||||
|
||||
if(*mktemp(p) == '\0') return(NULL);
|
||||
return(p);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJS = environ.o getopt.o getsubopt.o
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
.INCLUDE: ../rules.mk
|
|
@ -0,0 +1,689 @@
|
|||
/*
|
||||
* These routines were written by Devin Reade for GNO 2.0.1.
|
||||
*
|
||||
* $Id: environ.c,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 3 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_stdlb";
|
||||
#endif
|
||||
|
||||
#pragma databank 1
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <stddef.h>
|
||||
#include <types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <gsos.h>
|
||||
#include <orca.h>
|
||||
#include <shell.h>
|
||||
|
||||
|
||||
typedef struct stackelm {
|
||||
struct stackelm *next;
|
||||
char **env;
|
||||
} stack_elm;
|
||||
|
||||
char **environ = NULL;
|
||||
|
||||
static short __environ_initialized = 0;
|
||||
static short __use_environ = 0;
|
||||
static short __in_environInit = 0;
|
||||
static stack_elm *env_stack = NULL;
|
||||
|
||||
static char *__findenv(const char *name, int *offset);
|
||||
static char *getvar(const char *name);
|
||||
static int setvar(char *name, const char *value);
|
||||
static void unsetvar (const char *name);
|
||||
|
||||
/*
|
||||
* int environPush(void);
|
||||
*
|
||||
* Pre: none
|
||||
*
|
||||
* Post: The current state of the shell variable list is saved. This
|
||||
* affects both the internal and the list pointed to by environ.
|
||||
*
|
||||
* Returns 0 on success, -1 otherwise.
|
||||
*/
|
||||
|
||||
int
|
||||
environPush(void) {
|
||||
stack_elm *p;
|
||||
PushVariablesGSPB parmBlock;
|
||||
|
||||
parmBlock.pCount = 0;
|
||||
PushVariablesGS(&parmBlock);
|
||||
|
||||
/* if we're not using environ, then we're finished */
|
||||
if(!__use_environ) return 0;
|
||||
|
||||
/* push environ onto the environment stack */
|
||||
if ((p = (stack_elm *) malloc (sizeof(stack_elm))) == NULL)
|
||||
return -1;
|
||||
p->next = env_stack;
|
||||
env_stack = p;
|
||||
env_stack->env = environ;
|
||||
|
||||
/* zero the new environment and initialize */
|
||||
environ = NULL;
|
||||
__environ_initialized = 0;
|
||||
if (environInit() != 0) { /* environInit failed; restore old environ */
|
||||
__environ_initialized = 1;
|
||||
environ = env_stack->env;
|
||||
p = env_stack;
|
||||
env_stack = env_stack->next;
|
||||
free(p);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* void environPop(void);
|
||||
*
|
||||
* Pre: none
|
||||
*
|
||||
* Post: The shell variable list is restored to the state that it was in
|
||||
* when the most recent environPush() call was made. This affects both
|
||||
* the internal version, and the list pointed to by environ.
|
||||
*/
|
||||
|
||||
void
|
||||
environPop(void) {
|
||||
stack_elm *s;
|
||||
char **p, **q;
|
||||
PushVariablesGSPB parmBlock;
|
||||
|
||||
parmBlock.pCount = 0;
|
||||
PopVariablesGS(&parmBlock);
|
||||
|
||||
/* if we're not using environ, then we're finished */
|
||||
if(!__use_environ) return;
|
||||
|
||||
if(!env_stack) return; /* empty stack */
|
||||
|
||||
/* restore environ to its previous value */
|
||||
p = environ;
|
||||
environ = (env_stack) ? env_stack->env : NULL;
|
||||
s = env_stack;
|
||||
env_stack = (env_stack) ? env_stack->next : NULL;
|
||||
|
||||
/* free up each element in the discarded environment */
|
||||
q = p;
|
||||
while (q && *q) {
|
||||
free(*q);
|
||||
q++;
|
||||
}
|
||||
|
||||
/* free the discarded environment */
|
||||
if (p) free(p);
|
||||
|
||||
/* free the discarded environment stack element */
|
||||
if (s) free(s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* static int setvar (char *name, const char *value);
|
||||
*
|
||||
* Purpose: to set shell variable <name> to <value>. This affects only
|
||||
* the internal representation, not that of the environ variable.
|
||||
*
|
||||
* Pre: <name> and <value> are null-terminated strings
|
||||
*
|
||||
* Post: <name> is set to <value>. Returns 0 on success, -1 on failure
|
||||
*
|
||||
* Acknowledgements: This routine is modified from code written by
|
||||
* Dave Tribby [ GEnie: D.TRIBBY Internet: tribby@cup.hp.com ]
|
||||
* for the "evaluate" shell utility for the Orca shell. Used
|
||||
* with permission.
|
||||
*/
|
||||
|
||||
static int
|
||||
setvar(char *name, const char *value) {
|
||||
int error;
|
||||
GSString255Ptr var_value; /* Holds variable sized string */
|
||||
SetGSPB set_var_pb;
|
||||
static GSString255 var_name;
|
||||
|
||||
|
||||
/* Shell call requires three parameters */
|
||||
set_var_pb.pCount = 3;
|
||||
|
||||
/* Create GSOS string that holds the name of the variable */
|
||||
/* Truncate value if > size of GSString255 */
|
||||
var_name.length = strlen(name);
|
||||
if (var_name.length > sizeof(var_name.text)) {
|
||||
var_name.length = sizeof(var_name.text);
|
||||
strncpy(var_name.text, name, sizeof(var_name.text));
|
||||
} else {
|
||||
strcpy(var_name.text, name);
|
||||
}
|
||||
set_var_pb.name = &var_name;
|
||||
|
||||
/* Allocate a GS string large enough to hold the value */
|
||||
var_value = (GSString255Ptr) malloc(strlen(value)+sizeof(Word));
|
||||
if (var_value == NULL) return (-1);
|
||||
|
||||
var_value->length = strlen(value);
|
||||
strcpy(var_value->text, value);
|
||||
|
||||
set_var_pb.value = var_value;
|
||||
set_var_pb.export = 1;
|
||||
|
||||
/* Make the shell call to set the variable */
|
||||
SetGS(&set_var_pb);
|
||||
error = toolerror();
|
||||
free (var_value);
|
||||
if (error) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} /* setvar */
|
||||
|
||||
|
||||
/*
|
||||
* static void unsetvar (const char *name);
|
||||
*
|
||||
* Pre: <name> points to the name of the shell variable to be deleted. It
|
||||
* may have a trailing '='.
|
||||
*
|
||||
* Post: The variable is deleted from the shell's internal environment.
|
||||
* Any further references to it will return a NULL pointer.
|
||||
*/
|
||||
|
||||
static void
|
||||
unsetvar (const char *name) {
|
||||
UnsetVariableGSPB parmblock;
|
||||
GSString255 parmname;
|
||||
|
||||
/*
|
||||
** delete the internal version
|
||||
*/
|
||||
|
||||
/* set up the parameters */
|
||||
parmblock.pCount = 1;
|
||||
parmblock.name = &parmname;
|
||||
parmname.length = strlen(name);
|
||||
if (parmname.length > 254) parmname.length = 254;
|
||||
strncpy(parmname.text,name,parmname.length);
|
||||
if (parmname.text[parmname.length -1] == '=') {
|
||||
parmname.text[parmname.length -1] = (char) NULL;
|
||||
} else {
|
||||
parmname.text[parmname.length] = (char) NULL;
|
||||
}
|
||||
|
||||
UnsetVariableGS(&parmblock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* static char *getvar (const char *name);
|
||||
*
|
||||
* Purpose: to get the value of shell variable <name>, using the internal
|
||||
* (not environ) representation.
|
||||
*
|
||||
* Pre: <name> is a null-terminated string
|
||||
*
|
||||
* Post: returns a pointer to the value of <name>. If the variable has
|
||||
* not been set or if the program is executing from an environment
|
||||
* where shell variables do not exist, a NULL value is returned.
|
||||
*
|
||||
* Acknowledgements: This routine is modified from code written by
|
||||
* Dave Tribby [ GEnie: D.TRIBBY Internet: tribby@cup.hp.com ]
|
||||
* for the "evaluate" shell utility for the Orca shell. Used
|
||||
* with permission.
|
||||
*/
|
||||
|
||||
static char *getvar(const char *name) {
|
||||
|
||||
ReadVariableGSPB get_var_pb;
|
||||
static ResultBuf255 var_value;
|
||||
static GSString255 var_name;
|
||||
char *result;
|
||||
int length;
|
||||
|
||||
/* Shell call requires three parameters */
|
||||
get_var_pb.pCount = 3;
|
||||
|
||||
/* Create GSOS string that holds the name of the variable */
|
||||
/* Truncate value if > size of GSString255 */
|
||||
var_name.length = strlen(name);
|
||||
if (var_name.length > sizeof(var_name.text)) {
|
||||
var_name.length = sizeof(var_name.text);
|
||||
strncpy(var_name.text, name, sizeof(var_name.text));
|
||||
} else {
|
||||
strcpy(var_name.text, name);
|
||||
}
|
||||
get_var_pb.name = &var_name;
|
||||
|
||||
/* initialize the result buffer */
|
||||
var_value.bufSize = sizeof (GSString255);
|
||||
get_var_pb.value = &var_value;
|
||||
|
||||
/* Make the shell call to get the variable */
|
||||
ReadVariableGS(&get_var_pb);
|
||||
|
||||
/* failed if tool error or not for export */
|
||||
if (toolerror() || (get_var_pb.export == 0)) return (NULL);
|
||||
|
||||
/* get length of variable value */
|
||||
length = ((ResultBuf255Ptr) get_var_pb.value)->bufString.length;
|
||||
|
||||
/* failed if variable not defined (length zero) */
|
||||
if (length == 0) return (NULL);
|
||||
|
||||
/* set the NULL terminator */
|
||||
result = (((ResultBuf255Ptr) get_var_pb.value)->bufString.text);
|
||||
result[length] = (char) NULL;
|
||||
|
||||
return (result);
|
||||
} /* getvar */
|
||||
|
||||
|
||||
/* int environInit (void)
|
||||
*
|
||||
* Purpose: to initialize environ. This need not be done if the calling
|
||||
* program does not need to access environ directly [that is, if it
|
||||
* restricts itself to using getenv(), setenv(), putenv(), and
|
||||
* unsetenv() ]
|
||||
*
|
||||
* Pre: none
|
||||
*
|
||||
* Post: the environment environ is initialized, and contains entries for
|
||||
* all defined internal shell variables. Returns 0 on success,
|
||||
* non-zero otherwise.
|
||||
*/
|
||||
|
||||
int environInit (void) {
|
||||
|
||||
static ReadIndexedGSPB parmBuffer;
|
||||
static ResultBuf255 nameBuffer, valueBuffer;
|
||||
unsigned int nameLength, valueLength;
|
||||
char *name;
|
||||
char *value;
|
||||
|
||||
/* make sure we only do this once */
|
||||
if (__environ_initialized) return 0;
|
||||
__environ_initialized = 1;
|
||||
__use_environ = 1;
|
||||
__in_environInit = 1;
|
||||
|
||||
/*
|
||||
** initialize the parameter block
|
||||
*/
|
||||
|
||||
parmBuffer.pCount = 4;
|
||||
parmBuffer.index = 1;
|
||||
nameBuffer.bufSize = sizeof (GSString255);
|
||||
valueBuffer.bufSize = sizeof (GSString255);
|
||||
parmBuffer.name = &nameBuffer;
|
||||
parmBuffer.value = &valueBuffer;
|
||||
|
||||
/* get space for our name and value buffers */
|
||||
name = (char *) malloc (255 * sizeof(char));
|
||||
if (!name) {
|
||||
__in_environInit = 0;
|
||||
return 1;
|
||||
}
|
||||
value = (char *) malloc (255 * sizeof(char));
|
||||
if (!value) {
|
||||
free(name);
|
||||
__in_environInit = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** add each variable into environ as they appear in the shell
|
||||
** environment
|
||||
*/
|
||||
|
||||
ReadIndexedGS (&parmBuffer);
|
||||
nameLength = nameBuffer.bufString.length;
|
||||
while (nameLength != 0) {
|
||||
valueLength = valueBuffer.bufString.length;
|
||||
|
||||
/* copy the name and value */
|
||||
strncpy (name, nameBuffer.bufString.text, nameLength);
|
||||
name[nameLength] = (char) NULL;
|
||||
strncpy (value, valueBuffer.bufString.text, valueLength);
|
||||
value[valueLength] = (char) NULL;
|
||||
|
||||
/* try to place it in environ */
|
||||
if (setenv(name, value, 1) != 0) {
|
||||
free(name);
|
||||
free(value);
|
||||
__in_environInit = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get the next shell variable and continue ... */
|
||||
parmBuffer.index++;
|
||||
ReadIndexedGS (&parmBuffer);
|
||||
nameLength = nameBuffer.bufString.length;
|
||||
}
|
||||
|
||||
free(name);
|
||||
free(value);
|
||||
__in_environInit = 0;
|
||||
return 0;
|
||||
} /* environInit() */
|
||||
|
||||
|
||||
/*
|
||||
* int putenv (const char *str)
|
||||
*
|
||||
* Purpose: Take a string of the form NAME=value and stick it into the
|
||||
* environment.
|
||||
*
|
||||
* Pre: <str> is a null-terminated string of the form NAME=value
|
||||
*
|
||||
* Post: returns zero if successful. A non-zero value indicates that
|
||||
* space to expand the environment pointer table could not be
|
||||
* acquired; in this case, the string has not been added
|
||||
*
|
||||
* Warning:
|
||||
* Certain naming restrictions may apply if the environment variable
|
||||
* is referenced by shell programs
|
||||
*/
|
||||
|
||||
|
||||
int putenv (const char *str) {
|
||||
char *name, *value;
|
||||
size_t l_str;
|
||||
int result;
|
||||
|
||||
/* get space for our buffer */
|
||||
l_str = strlen(str);
|
||||
name = (char *) malloc (l_str + 1);
|
||||
if (!name) return -1;
|
||||
|
||||
strcpy(name,str);
|
||||
|
||||
/* replace the '=' with a null and set value */
|
||||
for (value=name; (*value) && (*value != '='); value++);
|
||||
if (*value == '=') { /* found the end of name */
|
||||
*value = (char) NULL;
|
||||
value++;
|
||||
result = (*value) ? setenv(name,value,1) : -1;
|
||||
} else {
|
||||
result = -1;
|
||||
}
|
||||
free(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* char *getenv (const char *NAME)
|
||||
*
|
||||
* Purpose: search the environment for a string of the format NAME=VALUE
|
||||
*
|
||||
* Pre: NAME is the name of the variable for which the value is to be
|
||||
* retrieved. It may end with an extra '=' which is not part of the
|
||||
* name.
|
||||
*
|
||||
* Post: returns a pointer to the value of NAME. If NAME is not defined, it
|
||||
* returns NULL. getenv() is case sensitive to NAME.
|
||||
*/
|
||||
|
||||
char *getenv(const char *name) {
|
||||
char *result;
|
||||
size_t length;
|
||||
|
||||
length = strlen(name);
|
||||
if (!length) return NULL;
|
||||
|
||||
if(name[length-1] == '=') {
|
||||
char *tmp_name;
|
||||
|
||||
if ((tmp_name = malloc(length+1)) == NULL) return NULL;
|
||||
strcpy(tmp_name,name);
|
||||
tmp_name[length-1] = (char) NULL;
|
||||
result = getvar(tmp_name);
|
||||
free(tmp_name);
|
||||
} else {
|
||||
result = getvar(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *__findenv(const char *name, int *offset);
|
||||
*
|
||||
* Pre: <name> is a null-terminated string, which may end with '='.
|
||||
*
|
||||
* Post: returns a pointer to the value associated with <name> in the
|
||||
* environment, if any, else it returns NULL. Sets <offset> to
|
||||
* be the offset of the name/value combination in the environmental
|
||||
* array (environ), for use by setenv(3) and unsetenv(3). It
|
||||
* explicitly removes '=' in argument <name>.
|
||||
*
|
||||
* Acknowledgements: This is based on UCB code; see the above legalese.
|
||||
*/
|
||||
|
||||
static char *__findenv(const char *name, int *offset) {
|
||||
unsigned int len;
|
||||
char **P, *C;
|
||||
|
||||
if (environ==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (C = name, len = 0; *C && (*C != '='); C++, len++);
|
||||
|
||||
for (P = environ; *P; P++) {
|
||||
if (!strncmp(*P, name, len)) {
|
||||
C = *P + len;
|
||||
if (*C == '=') {
|
||||
*offset = P - environ;
|
||||
C++;
|
||||
return(C);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int setenv (const char *name, const char *value, int rewrite);
|
||||
*
|
||||
* Pre: <name> is the name of the environment variable to be set with
|
||||
* value <value>. <rewrite> is either unset (zero) or set (non-
|
||||
* zero).
|
||||
*
|
||||
* Post: If <name> does not previously exist, then it is added to the
|
||||
* environment with value <value>. If <name> has been previously
|
||||
* set, then <rewrite> is tested: If <rewrite> is non-zero then
|
||||
* the old value is replaced, otherwise the call has no effect.
|
||||
*
|
||||
* Returns zero on success or if <name> already exists and <rewrite>
|
||||
* is not set. Returns -1 and sets errno on failure.
|
||||
*/
|
||||
|
||||
int setenv (const char *name, const char *value, int rewrite) {
|
||||
static int alloced; /* if allocated space before */
|
||||
char *C;
|
||||
size_t l_value, l_name;
|
||||
int offset;
|
||||
char *tmp_name;
|
||||
char *tmp_str;
|
||||
|
||||
if (*value == '=') value++; /* ignore any prepended '=' in value */
|
||||
l_name = strlen(name); /* get the string lengths */
|
||||
l_value = strlen(value);
|
||||
if(name[l_name-1] == '=') l_name--; /* ignore any appended '=' in name */
|
||||
if ((l_name == 0) || (l_value == 0)) { /* bad args! */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** make a copy of the name
|
||||
*/
|
||||
|
||||
tmp_name = (char *) malloc (l_name+1); /* allocate necessary memory */
|
||||
if (tmp_name == NULL) return -1;
|
||||
strncpy(tmp_name, name, l_name); /* do the copy */
|
||||
tmp_name[l_name] = '\0';
|
||||
|
||||
/*
|
||||
** make a string of the form name=value, if necessary
|
||||
*/
|
||||
|
||||
if (__use_environ) { /* are we using the environ structure? */
|
||||
tmp_str = (char *) malloc (l_name + l_value + 2);
|
||||
if (!tmp_str) {
|
||||
free(tmp_name);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
strcpy (tmp_str,tmp_name);
|
||||
strcat (tmp_str,"=");
|
||||
strcat (tmp_str,value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Change the internal version
|
||||
*/
|
||||
if ((!__in_environInit) && ((rewrite) || (getenv(tmp_name) == NULL))) {
|
||||
if (setvar(tmp_name, value)) {
|
||||
int tmp_err = errno;
|
||||
|
||||
free(tmp_name);
|
||||
if (__use_environ) free(tmp_str);
|
||||
errno = tmp_err;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (__use_environ==0) {
|
||||
free(tmp_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the external (environ) version
|
||||
*/
|
||||
|
||||
C = __findenv(tmp_name, &offset); /* find if already exists */
|
||||
if (C!=NULL) {
|
||||
if (!rewrite) {
|
||||
free(tmp_name);
|
||||
free(tmp_str);
|
||||
return 0;
|
||||
}
|
||||
if (strlen(C) >= l_value) { /* old larger; copy over */
|
||||
while (*value) {
|
||||
*C = *value;
|
||||
C++;
|
||||
value++;
|
||||
}
|
||||
free(tmp_name);
|
||||
free(tmp_str);
|
||||
return 0;
|
||||
}
|
||||
} else { /* not found; create new slot */
|
||||
int cnt;
|
||||
char **P;
|
||||
|
||||
cnt = 0;
|
||||
if (environ) for (P = environ; *P; P++) cnt++;
|
||||
|
||||
if (alloced) { /* done before; just increase size */
|
||||
|
||||
P = (char **) realloc ((char *)environ,
|
||||
(size_t)(sizeof(char *) * (cnt + 2)));
|
||||
if (!P) { /* realloc failed */
|
||||
unsetvar(tmp_name);
|
||||
free(tmp_name);
|
||||
free(tmp_str);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
} else {
|
||||
environ = P;
|
||||
}
|
||||
} else { /* first time; get new space */
|
||||
alloced = 1; /* copy old entries into it */
|
||||
P = (char **) malloc ((size_t) (sizeof(char *) * (cnt + 2)));
|
||||
if (!P) {
|
||||
unsetvar(tmp_name);
|
||||
free(tmp_name);
|
||||
free(tmp_str);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* original was:
|
||||
* bcopy(environ, P, cnt * sizeof(char *));
|
||||
* changed so that we could use the standard Orca libraries
|
||||
* for non-gno implementations.
|
||||
*/
|
||||
if (environ) memcpy(P, environ, cnt * sizeof(char *));
|
||||
environ = P;
|
||||
}
|
||||
environ[cnt + 1] = NULL;
|
||||
offset = cnt;
|
||||
}
|
||||
|
||||
/* we've got the new slot, now add it in */
|
||||
environ[offset] = tmp_str;
|
||||
free(tmp_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* void unsetenv (const char *name);
|
||||
*
|
||||
* Pre: <name> points to the name of the shell variable to be deleted. It
|
||||
* may have a trailing '='.
|
||||
*
|
||||
* Post: The variable is deleted. Any further references to it will return
|
||||
* a NULL pointer. This routine unsets both the internal and, if it's
|
||||
* initialized, the environ representations.
|
||||
*
|
||||
* Acknowledgements: Contains BSD code. See the above legalese.
|
||||
*/
|
||||
|
||||
void unsetenv (const char *name) {
|
||||
char **P;
|
||||
int offset;
|
||||
|
||||
/*
|
||||
** delete the internal version
|
||||
*/
|
||||
|
||||
unsetvar(name);
|
||||
if(!__use_environ) return;
|
||||
|
||||
/*
|
||||
** delete the environ version, if necessary.
|
||||
*/
|
||||
|
||||
while (__findenv(name, &offset)!=NULL) { /* if set multiple times */
|
||||
|
||||
free(environ[offset]);
|
||||
for (P = &environ[offset];; P++)
|
||||
if (!(*P = *(P + 1)))
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is formatted for tab stops every 8 characters.
|
||||
*
|
||||
* $Id: getopt.c,v 1.1 1997/02/28 05:12:49 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_stdlb";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getopt.c 8.2 (Berkeley) 4/2/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gno/gno.h> /* needed for __prognameGS() */
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(int nargc, char * const *nargv, const char *ostr)
|
||||
{
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (EOF);
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (EOF);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means EOF.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return (EOF);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", __prognameGS(), optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
}
|
||||
else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__prognameGS(), optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
||||
|
||||
int
|
||||
getopt_restart (void) {
|
||||
optreset = 1;
|
||||
optind = 1;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is formatted for tab stops every 8 characters.
|
||||
*
|
||||
* $Id: getsubopt.c,v 1.1 1997/02/28 05:12:50 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_stdlb";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* The SVID interface to getsubopt provides no way of figuring out which
|
||||
* part of the suboptions list wasn't matched. This makes error messages
|
||||
* tricky... The extern variable suboptarg is a pointer to the token
|
||||
* which didn't match.
|
||||
*/
|
||||
char *suboptarg;
|
||||
|
||||
int
|
||||
getsubopt(register char **optionp, register char * const *tokens,
|
||||
register char **valuep)
|
||||
{
|
||||
register int cnt;
|
||||
register char *p;
|
||||
|
||||
suboptarg = *valuep = NULL;
|
||||
|
||||
if (!optionp || !*optionp)
|
||||
return(-1);
|
||||
|
||||
/* skip leading white-space, commas */
|
||||
for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
|
||||
|
||||
if (!*p) {
|
||||
*optionp = p;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* save the start of the token, and skip the rest of the token. */
|
||||
for (suboptarg = p;
|
||||
*++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
|
||||
|
||||
if (*p) {
|
||||
/*
|
||||
* If there's an equals sign, set the value pointer, and
|
||||
* skip over the value part of the token. Terminate the
|
||||
* token.
|
||||
*/
|
||||
if (*p == '=') {
|
||||
*p = '\0';
|
||||
for (*valuep = ++p;
|
||||
*p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
} else
|
||||
*p++ = '\0';
|
||||
/* Skip any whitespace or commas after this token. */
|
||||
for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
|
||||
}
|
||||
|
||||
/* set optionp for next round. */
|
||||
*optionp = p;
|
||||
|
||||
for (cnt = 0; *tokens; ++tokens, ++cnt)
|
||||
if (!strcmp(suboptarg, *tokens))
|
||||
return(cnt);
|
||||
return(-1);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Makefile for libc/gen.
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:50 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJS = case.o str.o
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
.INCLUDE: ../rules.mk
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Implementation by Devin Reade
|
||||
*
|
||||
* $Id: case.c,v 1.1 1997/02/28 05:12:50 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_str__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#undef TOLOWER
|
||||
#define TOLOWER(c) isupper(c) ? _tolower(c) : c
|
||||
|
||||
int
|
||||
strcasecmp (const char *s1, const char *s2) {
|
||||
unsigned int c1, c2;
|
||||
|
||||
for (;;) {
|
||||
c1 = TOLOWER(*s1);
|
||||
c2 = TOLOWER(*s2);
|
||||
if (c1 == '\0' && c2 == '\0') {
|
||||
return 0;
|
||||
} else if (c1 == c2) {
|
||||
s1++; s2++;
|
||||
} else {
|
||||
/* don't do subtraction -- see man page */
|
||||
return (c1 > c2) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
strncasecmp (const char *s1, const char *s2, size_t n) {
|
||||
unsigned int c1, c2;
|
||||
size_t i;
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
c1 = TOLOWER(*s1);
|
||||
c2 = TOLOWER(*s2);
|
||||
if (c1 == '\0' && c2 == '\0') {
|
||||
return 0;
|
||||
} else if (c1 == c2) {
|
||||
s1++; s2++;
|
||||
} else {
|
||||
/* don't do subtraction -- see man page */
|
||||
return (c1 > c2) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
short
|
||||
stricmp (const char *s1, const char *s2) {
|
||||
return strcasecmp(s1, s2);
|
||||
}
|
||||
|
||||
short
|
||||
strincmp (const char *s1, const char *s2, unsigned n) {
|
||||
return strncasecmp(s1, s2, n);
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* str.c
|
||||
*
|
||||
* Various string routines not available in OrcaLib. For an explanation
|
||||
* of these functions, see the appropriate man page.
|
||||
*
|
||||
* $Id: str.c,v 1.1 1997/02/28 05:12:50 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tabs in every 8 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_str__";
|
||||
#endif
|
||||
|
||||
#pragma optimize 0
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* index
|
||||
*/
|
||||
|
||||
char *
|
||||
index(const char *a, int b)
|
||||
{
|
||||
return strchr(a,b);
|
||||
}
|
||||
|
||||
/*
|
||||
* rindex
|
||||
*/
|
||||
|
||||
char *
|
||||
rindex(const char *a, int b)
|
||||
{
|
||||
return strrchr(a,b);
|
||||
}
|
||||
|
||||
/*
|
||||
* strsep
|
||||
*
|
||||
* Get next token from string *stringp, where tokens are nonempty
|
||||
* strings separated by characters from delim.
|
||||
*
|
||||
* Writes NULs into the string at *stringp to end tokens.
|
||||
* delim need not remain constant from call to call.
|
||||
* On return, *stringp points past the last NUL written (if there might
|
||||
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||
*
|
||||
* If *stringp is NULL, strtoken returns NULL.
|
||||
*/
|
||||
|
||||
char *
|
||||
strsep(register char **stringp, register const char *delim)
|
||||
{
|
||||
register char *s;
|
||||
register const char *spanp;
|
||||
register int c, sc;
|
||||
char *tok;
|
||||
|
||||
if ((s = *stringp) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
for (tok = s;;) {
|
||||
c = *s++;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0) {
|
||||
s = NULL;
|
||||
} else {
|
||||
s[-1] = 0;
|
||||
}
|
||||
*stringp = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* strdup
|
||||
*/
|
||||
|
||||
char *
|
||||
strdup(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
char *buf;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if ((buf = malloc(len)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
strcpy(buf, str);
|
||||
return buf;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:50 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
OBJS = trap.o syscall.o exec.o
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
.INCLUDE: ../rules.mk
|
||||
|
||||
trap.o:: trap.mac
|
|
@ -0,0 +1,604 @@
|
|||
/*
|
||||
* exec(2) library calls. Written as part of lenviron by Devin Reade
|
||||
* for GNO v2.0.3. Incorporated into libc as of GNO v2.0.6.
|
||||
*
|
||||
* $Id: exec.c,v 1.1 1997/02/28 05:12:50 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tabs every 3 columns. The remainder of
|
||||
* the comments in this section are from the lenviron v1.1.3 implementation.
|
||||
* Of course, the GNO distribution headers now reflect these changes.
|
||||
*
|
||||
*************************************************************************
|
||||
*
|
||||
* These calls will only work with the GNO kernel! They were tested with
|
||||
* GNO v2.0.3 and later, but _might_ work with other versions.
|
||||
*
|
||||
* These have been implemented using the standard Unix declarations. In
|
||||
* particular, the prototype for execve(2) does _not_ match that of
|
||||
* Procyon's distribution of GNO v2.0.5 and earlier.
|
||||
*
|
||||
* If you wish to make use of the execve call as provided with the GNO
|
||||
* v2.0.5 (and earlier) distribution, that call is still available as the
|
||||
* function
|
||||
*
|
||||
* int _execve(const char *path, const char *params);
|
||||
*
|
||||
* Note that execle(2) is not currently implemented. exect(2) probably
|
||||
* never will be so implemented.
|
||||
*
|
||||
* Note that the current version of gsh parses $PATH backwards for some
|
||||
* reason. For consistency, execvp() and execlp() will do the same for now.
|
||||
* If gsh gets fixed or if you switch to a shell that parses $PATH front-to-
|
||||
* back, just undefine BACKWARDS within this file an recompile. The
|
||||
* appropriate code has already been tested.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_sys__";
|
||||
#endif
|
||||
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
/*
|
||||
* Use bits 0, 1, 2, 6 (== decimal 71) for optimization. In Orca/C v2.1.0,
|
||||
* bits 4 and 5 are still reported to be buggy.
|
||||
*
|
||||
* Around variadic routines, we also add in optimization bit 3 (== 79).
|
||||
*/
|
||||
|
||||
/* pragma optimize 71 */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <types.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <orca.h>
|
||||
#include <gno/gno.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define PARMSGUESS 10 /* initial length of argv array in execl, execlp */
|
||||
|
||||
#define BACKWARDS /* undefine this for shells that parse $PATH */
|
||||
/* front to back. gsh as of Dec 93 needs this */
|
||||
/* defined. */
|
||||
|
||||
pascal int Kexecve(char *pathname, char *cmdline, int *errno)
|
||||
inline(0x1D03,0xE10008);
|
||||
|
||||
|
||||
/*
|
||||
* int isRootPath(const char *name);
|
||||
*
|
||||
* Pre: <name> is a file name
|
||||
*
|
||||
* Post: Return TRUE if the name is the full specification of a path name
|
||||
* to a file starting at the root of the file system, otherwise
|
||||
* return FALSE. Note that no test for existence is carried out;
|
||||
* this routine only judges whether or not the given name is a valid
|
||||
* one file starting at the root of the file system.
|
||||
*
|
||||
* Caveat: Unlike the Unix filesystem, "/" is not recognised as a complete
|
||||
* file (or directory) name. Therefore, it will return FALSE if the
|
||||
* the name is one character long and isn't "*" or "@" or a digit.
|
||||
*/
|
||||
|
||||
/* allowable start of full file/device/prefix names */
|
||||
static char* PfxBrkStr = "/:0123456789.*@";
|
||||
|
||||
int
|
||||
isRootPath(const char *name) {
|
||||
char *p;
|
||||
|
||||
p = strchr(PfxBrkStr, *name);
|
||||
if (p == NULL) return FALSE;
|
||||
|
||||
switch (*p) {
|
||||
case '/': /* FALLTHROUGH */
|
||||
case ':':
|
||||
/* "zero" length volume/prefix names not allowed */
|
||||
if (*(p+1) == '\0') return FALSE;
|
||||
else return TRUE;
|
||||
/* NOTREACHED */
|
||||
case '.':
|
||||
/* "zero" length volume/prefix names not allowed. "./" and ".:" fail */
|
||||
switch (*(p+1)) {
|
||||
case '\0': /* FALLTHROUGH */
|
||||
case '/': /* FALLTHROUGH */
|
||||
case ':':
|
||||
return FALSE;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case '*': /* FALLTHROUGH */
|
||||
case '@':
|
||||
switch (*(p+1)) {
|
||||
case '\0': /* FALLTHROUGH */
|
||||
case '/': /* FALLTHROUGH */
|
||||
case ':':
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
/* it must be starting with a digit */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* char *buildCmd (char *const *argv);
|
||||
*
|
||||
* Pre: argv is a pointer to an array of strings, ending with a NULL pointer
|
||||
*
|
||||
* Post: Returns a pointer to a string consisting of all of the elements of
|
||||
* argv, delimited by single spaces. Returns NULL if memory for the
|
||||
* string cannot be allocated. If argv[0] == NULL, buildCmd() will
|
||||
* return a pointer to a zero-length string. If it returns NULL,
|
||||
* errno is also set to ENOMEM.
|
||||
*
|
||||
* Any GS/OS prefix (numerical or otherwise) on argv[0] will be stripped.
|
||||
*/
|
||||
|
||||
char *
|
||||
buildCmd (char *const *argv) {
|
||||
|
||||
char *comdbuf; /* pointer to the command line buffer */
|
||||
size_t comdsize; /* length of the command line buffer */
|
||||
int i;
|
||||
char *s; /* a temporary pointer */
|
||||
char delim; /* delimiter for pathnames (':' or '/') */
|
||||
|
||||
/* allocate memory for command line */
|
||||
comdsize = 1;
|
||||
i = 0;
|
||||
while (argv[i] != NULL) {
|
||||
comdsize = comdsize + strlen(argv[i]) + 1;
|
||||
i++;
|
||||
}
|
||||
if ((comdbuf = malloc (comdsize)) == NULL) return NULL;
|
||||
|
||||
/* build command line from argv */
|
||||
i = 0;
|
||||
if (argv[i] == NULL) {
|
||||
comdbuf[0] = (char) NULL;
|
||||
} else {
|
||||
/* find delimiter */
|
||||
delim = (strchr(argv[0],':') == NULL) ? '/' : ':';
|
||||
|
||||
/* drop leading prefix */
|
||||
s = argv[i];
|
||||
while (*s) s++;
|
||||
while ((s>argv[i]) && (*s != delim)) s--;
|
||||
if (*s==delim) s++;
|
||||
|
||||
strcpy(comdbuf,s);
|
||||
i++;
|
||||
while (argv[i] != NULL) {
|
||||
strcat(comdbuf, " ");
|
||||
strcat(comdbuf, argv[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return comdbuf;
|
||||
}
|
||||
|
||||
|
||||
/* int _fileExists (const char *file, const char *path)
|
||||
*
|
||||
* Pre: file is a file name, path is a full legal directory name
|
||||
*
|
||||
* Post: Returns 1 if file is in path, returns 0 and errno set on failure.
|
||||
* Possible errno values on return are 0, ENOMEM, and ENOENT.
|
||||
*
|
||||
* Notes: If <path> is a zero-length string (not NULL!), then existence
|
||||
* of <file> will be tested based on <file> being a partial pathname.
|
||||
*
|
||||
* _fileExists() will also fail if file is either a full path name or
|
||||
* a zero-length string.
|
||||
*/
|
||||
|
||||
static int
|
||||
_fileExists (const char *file, const char *path) {
|
||||
|
||||
static char *buffer = NULL;
|
||||
static size_t buffersize = 0;
|
||||
size_t pathlen, length;
|
||||
char delim;
|
||||
char *tp;
|
||||
|
||||
delim = (strchr(path,':') == NULL) ? '/' : ':'; /* find delimiter */
|
||||
|
||||
/* <file> is a full pathname or empty string? Fail! */
|
||||
if ((*file == '\0') || (isRootPath(file))) {
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* calculate length of path prefix and full pathname */
|
||||
pathlen = strlen(path);
|
||||
length = strlen(file) + pathlen + 2;
|
||||
|
||||
/*
|
||||
* Allocate more mem for buffer, if necessary. This fragment's behavior
|
||||
* is dependant on the implementation of realloc and is not necessarily
|
||||
* portable. It assumes that realloc() called with a NULL pointer behaves
|
||||
* the same as malloc().
|
||||
*/
|
||||
|
||||
if (length > buffersize) {
|
||||
tp = (char *) realloc (buffer, length);
|
||||
if (tp == NULL) {
|
||||
if (buffer) free (buffer);
|
||||
buffer = NULL;
|
||||
buffersize = 0;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
buffer = tp;
|
||||
}
|
||||
|
||||
strcpy(buffer,path); /* make copy of path, */
|
||||
if (pathlen) {
|
||||
if (buffer[pathlen-1] != delim) { /* delimiter and terminate */
|
||||
buffer[pathlen] = delim;
|
||||
buffer[pathlen+1] = '\0';
|
||||
}
|
||||
} else {
|
||||
*buffer = '\0';
|
||||
}
|
||||
|
||||
strcat(buffer,file);
|
||||
|
||||
if (access(buffer, F_OK) == 0) { /* file found */
|
||||
errno = 0;
|
||||
return 1;
|
||||
} /* else ... */
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* char *buildPath (const char *filename);
|
||||
*
|
||||
* Pre: <filename> is the name of the file which we wish to locate.
|
||||
*
|
||||
* Post: If <filename> resides within $PATH, then buildPath will return a
|
||||
* malloc'd pointer to the full pathname of the file.
|
||||
* If <filename> cannot be found with $PATH, buildPath the default
|
||||
* which is to search "/bin", then "/usr/bin". On error, NULL is
|
||||
* returned and errno is set either to ENOENT or ENOMEM, as appropriate.
|
||||
*
|
||||
* If <filename> is in fact a full pathname, then a pointer to a malloc'd
|
||||
* copy of the filename is returned; in this case, no test for existence
|
||||
* is done <filename> is considered to be a full pathname if it
|
||||
* begins with any of '/', ':', '.', '@', '*', or a digit.
|
||||
* If any of '/', ':', or '.' is the first character, the
|
||||
* filename must have a length of at least two characters.
|
||||
*
|
||||
* Caveat: There is a conditional compilation in this function; gsh currently
|
||||
* parses the $PATH variable backwards, so for compatibility buildPath
|
||||
* will also do a backwards parse if BACKWARDS is defined. Otherwise,
|
||||
* $PATH will be parsed front-to-back.
|
||||
*/
|
||||
|
||||
char *
|
||||
buildPath (const char *filename) {
|
||||
char *pathptr; /* pointer to the PATH shell variable */
|
||||
char *path; /* pointer to the current PATH token */
|
||||
char *buffptr; /* where we will store the full pathname */
|
||||
size_t pathlen; /* for calculating space for malloc() */
|
||||
char delim[2]; /* delimiter for pathnames. */
|
||||
/* Assumption: if a path doesn't */
|
||||
/* contain any '/' chars, the */
|
||||
/* delimiter is ':'. */
|
||||
#ifdef BACKWARDS
|
||||
static char *default_path = "/usr/bin /bin";
|
||||
char *path_copy;
|
||||
#else
|
||||
static char *default_path = "/bin /usr/bin";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* if for some weird and wonderful reason, filename is a full pathname,
|
||||
* then just return a pointer to a copy of it. In this case no test
|
||||
* for existence is done.
|
||||
*/
|
||||
if (isRootPath(filename)) {
|
||||
buffptr = (char *) malloc (strlen(filename) + 1);
|
||||
if (buffptr == NULL) return NULL;
|
||||
strcpy (buffptr,filename);
|
||||
return buffptr;
|
||||
}
|
||||
|
||||
/* get the value of the PATH shell variable */
|
||||
pathptr = getenv ("PATH");
|
||||
if (pathptr == NULL || *pathptr == '\0') {
|
||||
/* PATH doesn't exist -- use default */
|
||||
pathptr = default_path;
|
||||
}
|
||||
|
||||
/* define the pathname delimiter */
|
||||
(strstr(pathptr,"/") == NULL) ? strcpy (delim, ":") : strcpy (delim, "/");
|
||||
|
||||
/*
|
||||
* search paths for filename -- backwards or forwards as appropriate
|
||||
*/
|
||||
|
||||
#ifdef BACKWARDS
|
||||
/* make a copy of the path */
|
||||
pathlen = strlen(pathptr) + 1;
|
||||
if ((path_copy = (char *) malloc((size_t) strlen(pathptr) + 1))==NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
strcpy(path_copy,pathptr);
|
||||
path = path_copy + pathlen;
|
||||
|
||||
/* look for the file */
|
||||
while (path>=path_copy) {
|
||||
while ((path>path_copy) && (*path != ' ')) path--;
|
||||
if (path>path_copy) { /* not done parsing $PATH */
|
||||
if (_fileExists(filename, path+1)) { /* found it! */
|
||||
path++;
|
||||
break;
|
||||
} else { /* not found; terminate string and try again */
|
||||
*path = '\0';
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* at this point, path points to either first listed directory or
|
||||
* whitespace; check it
|
||||
*/
|
||||
if (isprint(*path) && _fileExists(filename, path)) { /* found it! */
|
||||
break;
|
||||
} else {
|
||||
free(path_copy); /* not in $PATH; parse failed */
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
path = strtok (pathptr, " ");
|
||||
while (path != NULL) {
|
||||
if (_fileExists(filename, path)) break;
|
||||
path = strtok (NULL, NULL);
|
||||
}
|
||||
|
||||
/* filename not within listed paths */
|
||||
if (path == NULL) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
#endif /* BACKWARDS */
|
||||
|
||||
|
||||
/* allocate the buffer */
|
||||
pathlen = strlen(filename) + strlen(path) + 2;
|
||||
if ((buffptr = malloc (pathlen)) == NULL) {
|
||||
#ifdef BACKWARDS
|
||||
free(path_copy);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* build the full pathname */
|
||||
strcpy (buffptr,path);
|
||||
strcat (buffptr,delim);
|
||||
strcat (buffptr,filename);
|
||||
|
||||
#ifdef BACKWARDS
|
||||
free(path_copy);
|
||||
#endif
|
||||
|
||||
return buffptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* int buildEnv (char *const *envp);
|
||||
*
|
||||
* Pre: envp is a pointer to an array of strings of the format NAME=VALUE.
|
||||
*
|
||||
* Post: On success, the strings in envp are added to the environment via
|
||||
* putenv(), and 0 is returned. Returns -1 and sets errno=ENOMEM
|
||||
* on failure.
|
||||
*/
|
||||
|
||||
int
|
||||
buildEnv (char *const *envp) {
|
||||
while (*envp != NULL) {
|
||||
if (putenv(*envp) == -1) return -1;
|
||||
envp++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function provides the functionality of the execve() routine
|
||||
* provided with the GNO distribution. Unfortunately, GNO's version
|
||||
* uses a non-standard prototype. (That's why execve is given a
|
||||
* different prototype in this library.
|
||||
*/
|
||||
|
||||
#if 0 /* it resides in trap.asm */
|
||||
int _execve(const char *path, const char *params) {
|
||||
return(Kexecve(path, params, &errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* exec -- this function has been obsoleted, but is provided for
|
||||
* backward compatibility
|
||||
*/
|
||||
|
||||
#pragma databank 1
|
||||
|
||||
static void
|
||||
_exec_child (const char *filename, const char *cmdline) {
|
||||
_execve(filename, cmdline);
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
#pragma databank 0
|
||||
|
||||
int
|
||||
exec (const char *filename, const char *cmdline) {
|
||||
return fork2 (_exec_child, 1024, 0, "forked child of exec(2)", 4,
|
||||
filename, cmdline);
|
||||
}
|
||||
|
||||
/*
|
||||
* The next functions (execv, execvp, execve, execl, execlp) are as per
|
||||
* their man page descriptions. On error, errno could be set to any of
|
||||
* ENOMEM, EIO, ENOENT. Note that there is no execle; Orca/C pukes on
|
||||
* its declaration.
|
||||
*/
|
||||
|
||||
int
|
||||
execv(const char *path, char * const *argv) {
|
||||
char *comd;
|
||||
|
||||
/* BUG BUG BUG BUG! -- this should be using <path> ! */
|
||||
|
||||
/* build the command line */
|
||||
if ((comd = buildCmd (argv)) == NULL) return -1;
|
||||
|
||||
/* execute it */
|
||||
return (Kexecve(path, comd, &errno));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
execvp(const char *file, char * const *argv) {
|
||||
char *comd;
|
||||
char *path;
|
||||
|
||||
/* build the path name, if necessary */
|
||||
path = buildPath (file);
|
||||
|
||||
/* build the command line */
|
||||
if ((comd = buildCmd (argv)) == NULL) return -1;
|
||||
|
||||
/* execute it */
|
||||
return(Kexecve(path, comd, &errno));
|
||||
}
|
||||
|
||||
int
|
||||
execve (const char *path, char * const *argv, char * const *envp) {
|
||||
char *comd;
|
||||
|
||||
/* build the command line */
|
||||
if ((comd = buildCmd (argv)) == NULL) return -1;
|
||||
|
||||
/* build the environment */
|
||||
if (buildEnv(envp) == -1) return -1;
|
||||
|
||||
/* execute it */
|
||||
return(Kexecve(path, comd, &errno));
|
||||
}
|
||||
|
||||
/* no stack repair code on variadic function definitions */
|
||||
/* pragma optimize 79 */
|
||||
#pragma optimize 8
|
||||
#pragma debug 0
|
||||
|
||||
int
|
||||
execl(const char *path, const char *arg, ...) {
|
||||
va_list list;
|
||||
char **argv;
|
||||
char *p;
|
||||
char **q;
|
||||
int i=0;
|
||||
size_t vect_length;
|
||||
int result;
|
||||
|
||||
/* allocate memory for initial guess of number of parameters */
|
||||
argv = (char **) malloc (sizeof(char *) * PARMSGUESS);
|
||||
if (argv==NULL) return -1;
|
||||
vect_length = PARMSGUESS;
|
||||
|
||||
/* build the array */
|
||||
p = arg;
|
||||
va_start (list, arg);
|
||||
while (p && *p) {
|
||||
argv[i] = p; i++;
|
||||
p = va_arg(list, char* );
|
||||
|
||||
/* reallocate memory if necessary */
|
||||
if (i>=vect_length) {
|
||||
vect_length += PARMSGUESS;
|
||||
q = (char **) realloc(argv,vect_length);
|
||||
if (p == NULL) {
|
||||
free(argv);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
argv = q;
|
||||
}
|
||||
}
|
||||
argv[i] = (char *) NULL;
|
||||
|
||||
va_end(list);
|
||||
result = execv(path,argv);
|
||||
|
||||
/* execvp failed; free argv */
|
||||
free(argv);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
execlp(const char *file, const char *arg, ...) {
|
||||
va_list list;
|
||||
char **argv;
|
||||
char *p;
|
||||
char **q;
|
||||
int i=0;
|
||||
size_t vect_length;
|
||||
int result;
|
||||
|
||||
/* allocate memory for initial guess of number of parameters */
|
||||
argv = (char **) malloc (sizeof(char *) * PARMSGUESS);
|
||||
if (argv==NULL) return -1;
|
||||
vect_length = PARMSGUESS;
|
||||
|
||||
/* build the array */
|
||||
p = arg;
|
||||
va_start (list, arg);
|
||||
while (p && *p) {
|
||||
argv[i] = p; i++;
|
||||
p = va_arg(list, char* );
|
||||
|
||||
/* reallocate memory if necessary */
|
||||
if (i>=vect_length) {
|
||||
vect_length += PARMSGUESS;
|
||||
q = (char **) realloc(argv,vect_length);
|
||||
if (p == NULL) {
|
||||
free(argv);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
argv = q;
|
||||
}
|
||||
}
|
||||
argv[i] = (char *) NULL;
|
||||
|
||||
va_end(list);
|
||||
result = execvp(file,argv);
|
||||
|
||||
/* execvp failed; free argv */
|
||||
free(argv);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,952 @@
|
|||
/*
|
||||
* libc/sys/syscall.c
|
||||
*
|
||||
* System Call (Trap) Interface. This file contains those functions
|
||||
* which are in Chapter 2 but emulate system traps as opposed to directly
|
||||
* trapping to the GNO kernel. The actual kernel trap calls are in trap.c
|
||||
* There are also a few support routines in here.
|
||||
*
|
||||
* Unless otherwise specified, see the respective man pages for details
|
||||
* about these routines.
|
||||
*
|
||||
* $Id: syscall.c,v 1.1 1997/02/28 05:12:51 gdr Exp $
|
||||
*
|
||||
* This file is formatted with tab stops every 3 columns.
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "libc_sys__";
|
||||
#endif
|
||||
|
||||
#pragma debug 0
|
||||
#pragma memorymodel 0
|
||||
|
||||
/*
|
||||
* Use bits 0, 1, 2, 6 (== decimal 71) for optimization. In Orca/C v2.1.0,
|
||||
* bits 4 and 5 are still reported to be buggy.
|
||||
*
|
||||
* Around variadic routines, we also add in optimization bit 3 (== 79).
|
||||
*/
|
||||
|
||||
/* pragma optimize 71 */
|
||||
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <gsos.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <orca.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <gno/gno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
/*
|
||||
* This is the maximum file name length allowed to be returned by GS/OS
|
||||
* in these stubs.
|
||||
*/
|
||||
|
||||
#define GSOS_NAME_MAX PATH_MAX
|
||||
|
||||
/* these are prototyped in the Orca/C manual, but not in any header */
|
||||
extern pascal void SystemQuitFlags (unsigned int);
|
||||
extern pascal void SystemQuitPath (GSStringPtr);
|
||||
|
||||
/* these are the access bits to the GS/OS Create call */
|
||||
#define GSOS_READ 0x0001
|
||||
#define GSOS_WRITE 0x0002
|
||||
#define GSOS_INVISIBLE 0x0004
|
||||
#define GSOS_BACKUP 0x0020
|
||||
#define GSOS_RENAME 0x0040
|
||||
#define GSOS_DESTROY 0x0080
|
||||
|
||||
/* file types and, for EXEC, the auxtype */
|
||||
#define TXT 0x04 /* text file */
|
||||
#define BIN 0x06 /* binary file */
|
||||
#define EXE 0xB5 /* shell command */
|
||||
#define DIR 0x0F /* directory */
|
||||
#define S16 0xB3 /* system file (application) */
|
||||
#define SRC 0xB0 /* SRC + EXEC = shell script */
|
||||
#define EXEC 0x0006
|
||||
|
||||
/*
|
||||
* _chdir
|
||||
*
|
||||
* chdir and fchdir are implemented in terms of this function. Note that
|
||||
* <pathname> _might_ be changed by _chdir() -- if an error occurs setting
|
||||
* prefix 0, then the length of <pathname> will be set to zero.
|
||||
*/
|
||||
|
||||
static int
|
||||
_chdir(GSStringPtr pathname) {
|
||||
PrefixRecGS prefx;
|
||||
struct { /* truncated version of GetFileInfoRec */
|
||||
word pCount;
|
||||
GSString255Ptr pathname;
|
||||
word access;
|
||||
word fileType;
|
||||
longword auxType;
|
||||
word storageType;
|
||||
} shortFileInfo;
|
||||
int err;
|
||||
|
||||
/* make sure it's a directory */
|
||||
shortFileInfo.pCount = 5;
|
||||
shortFileInfo.pathname = (GSString255Ptr) pathname;
|
||||
GetFileInfoGS(&shortFileInfo);
|
||||
if ((errno = _mapErr(_toolErr)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (shortFileInfo.storageType != 0x0d && /* subdirectory */
|
||||
shortFileInfo.storageType != 0x0f) { /* volume directory */
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
prefx.pCount = 2;
|
||||
prefx.prefixNum = 8;
|
||||
prefx.buffer.setPrefix = shortFileInfo.pathname;
|
||||
SetPrefixGS(&prefx);
|
||||
if ((errno = _mapErr(_toolErr)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
prefx.prefixNum = 0;
|
||||
if (prefx.buffer.setPrefix->length < 64) {
|
||||
SetPrefixGS(&prefx);
|
||||
if (_toolErr == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
prefx.buffer.setPrefix->length = 0;
|
||||
SetPrefixGS(&prefx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* _setFdTranslation, _getFdTranslation
|
||||
*
|
||||
* Does newline translation occur for read/write calls on the specified
|
||||
* file descriptor? Off by default. Returns previous value for the
|
||||
* specified fd.
|
||||
*
|
||||
* If by any chance we manage to open more than OPEN_MAX files, then
|
||||
* translation is always off for those file descriptors.
|
||||
*/
|
||||
|
||||
static int fdTranslationTable[OPEN_MAX];
|
||||
|
||||
#define _getFdTranslation(fd) \
|
||||
(((fd) >= 0) && ((fd) < OPEN_MAX) && fdTranslationTable[fd])
|
||||
|
||||
static int
|
||||
_setFdTranslation(int fd, int isOn) {
|
||||
int oldval;
|
||||
|
||||
if (fd < 0 || fd >= OPEN_MAX) {
|
||||
return 0;
|
||||
}
|
||||
oldval = fdTranslationTable[fd];
|
||||
fdTranslationTable[fd] = (isOn != 0);
|
||||
return oldval;
|
||||
}
|
||||
|
||||
/*
|
||||
* _statfs
|
||||
*
|
||||
* _statfs is a routine common to both statfs and fstatfs. The first
|
||||
* parameter, gstr, is a pointer to a GSString containing the pathname.
|
||||
* Other than the type of the first argument, this call is identical
|
||||
* to the regular definition of statfs.
|
||||
*/
|
||||
|
||||
static int
|
||||
_statfs (GSStringPtr gstr, struct statfs *buf) {
|
||||
DevNumRecGS gd;
|
||||
VolumeRecGS vo;
|
||||
char printbuf[20]; /* device name in .dxx format */
|
||||
int err;
|
||||
|
||||
/* get the volume number for the file name gstr */
|
||||
gd.pCount = 2;
|
||||
gd.devName = (GSString32Ptr) gstr; /* does this work with a pathname? */
|
||||
GetDevNumberGS(&gd);
|
||||
if (_toolErr) {
|
||||
errno = _mapErr(_toolErr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get the other volume info */
|
||||
vo.pCount = 6;
|
||||
sprintf(printbuf,".d%d", gd.devNum);
|
||||
vo.devName = (GSString32Ptr) __C2GSMALLOC(printbuf);
|
||||
vo.volName = (ResultBuf255Ptr) GOinit(32, NULL);
|
||||
VolumeGS(&vo);
|
||||
err = _toolErr;
|
||||
|
||||
/* copy over our information */
|
||||
buf->f_type = (long) vo.fileSysID; /* FST type */
|
||||
buf->f_bsize = (long) vo.blockSize; /* size of blocks in filesystem */
|
||||
buf->f_blocks = vo.totalBlocks; /* number of blocks on the volume */
|
||||
buf->f_bfree = vo.freeBlocks; /* number of free blocks */
|
||||
buf->f_bavail = vo.freeBlocks; /* none reserved for superuser */
|
||||
buf->f_files = -1; /* undefined by this filesystem */
|
||||
buf->f_ffree = -1; /* undefined by this filesystem */
|
||||
buf->f_fsid.hi = 0;
|
||||
buf->f_fsid.lo = gd.devNum; /* device number */
|
||||
buf->f_spare[0] = -1;
|
||||
buf->f_spare[1] = -1;
|
||||
buf->f_spare[2] = -1;
|
||||
buf->f_spare[3] = -1;
|
||||
buf->f_spare[4] = -1;
|
||||
buf->f_spare[5] = -1;
|
||||
buf->f_spare[6] = -1;
|
||||
|
||||
/* clean up, set up return conditions */
|
||||
GOfree(vo.volName);
|
||||
free(vo.devName);
|
||||
if (err) {
|
||||
errno = _mapErr(err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* access -- a replacement for the GNO v2.0.4 one; this one will actually
|
||||
* return 0 when testing X_OK on a directory.
|
||||
*
|
||||
* This function uses gotos. Too bad; sometimes it's more efficient.
|
||||
*/
|
||||
|
||||
int
|
||||
access (const char *name, int mode) {
|
||||
FileInfoRecGS *recptr;
|
||||
GSStringPtr gptr;
|
||||
size_t len;
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
/* verify validity of args */
|
||||
if (!name || !*name) { /* for SYSV */
|
||||
errno=ENOENT;
|
||||
return -1;
|
||||
}
|
||||
len = strlen(name);
|
||||
if (len >= USHRT_MAX || (mode & ~(R_OK|W_OK|X_OK|F_OK))) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate and initialize the GS/OS variables */
|
||||
if ((gptr = GIinit(len, name)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if ((recptr = malloc(sizeof(FileInfoRecGS))) == NULL) {
|
||||
GIfree(gptr);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
recptr->pCount = 4;
|
||||
recptr->pathname = (GSString255Ptr) gptr;
|
||||
|
||||
/* get the info and check for errors */
|
||||
GetFileInfoGS(recptr);
|
||||
i = toolerror();
|
||||
if (i) {
|
||||
errno = _mapErr(i);
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* check read permission */
|
||||
if ((mode & R_OK) && !(recptr->access & GSOS_READ)) {
|
||||
errno = EACCES;
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* check write permission */
|
||||
if ((mode & W_OK) &&
|
||||
!((recptr->access & GSOS_WRITE) &&
|
||||
(recptr->access & GSOS_RENAME) &&
|
||||
(recptr->access & GSOS_DESTROY))) {
|
||||
errno = EACCES;
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check execute mode. This is true if:
|
||||
* the file is a directory;
|
||||
* the file is a shell command;
|
||||
* the file is a shell script;
|
||||
* the file is a S16 file;
|
||||
* But NOT if
|
||||
* the file is a SYS or other type of file.
|
||||
*/
|
||||
if ((mode & X_OK) &&
|
||||
!((recptr->fileType == EXE) ||
|
||||
(recptr->fileType == DIR) ||
|
||||
(recptr->fileType == SRC && recptr->auxType == EXEC) ||
|
||||
(recptr->fileType == S16))) {
|
||||
errno = EACCES;
|
||||
result = -1;
|
||||
}
|
||||
|
||||
done:
|
||||
GIfree(gptr);
|
||||
free(recptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* chdir
|
||||
*/
|
||||
|
||||
int
|
||||
chdir (const char *pathname) {
|
||||
GSStringPtr pathnameGS;
|
||||
int result, err;
|
||||
|
||||
if ((pathnameGS = __C2GSMALLOC(pathname)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
result = _chdir(pathnameGS);
|
||||
err = errno;
|
||||
free(pathnameGS);
|
||||
if (result != 0) {
|
||||
errno = err;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* close
|
||||
*/
|
||||
|
||||
int
|
||||
close (int filds) {
|
||||
int cl[2] = {1, filds};
|
||||
int err;
|
||||
|
||||
_setFdTranslation(filds, 0);
|
||||
CloseGS(cl);
|
||||
if (_toolErr) {
|
||||
errno = _mapErr(_toolErr);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* creat
|
||||
*/
|
||||
|
||||
int
|
||||
creat(const char *path, mode_t mode) {
|
||||
return open (path, O_CREAT | O_TRUNC | O_WRONLY, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* fchdir
|
||||
*/
|
||||
|
||||
int
|
||||
fchdir (int fd)
|
||||
{
|
||||
RefInfoRecGS inforec;
|
||||
int err, result;
|
||||
|
||||
/* get the pathname based on the file descriptor */
|
||||
inforec.pCount = 3;
|
||||
inforec.refNum = fd;
|
||||
inforec.pathname = (ResultBuf255Ptr) GOinit(GSOS_NAME_MAX, NULL);
|
||||
GetRefInfoGS (&inforec);
|
||||
if ((err = _mapErr(_toolErr)) != 0) {
|
||||
GOfree(inforec.pathname);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* change directory */
|
||||
result = _chdir((GSStringPtr) &inforec.pathname->bufString);
|
||||
err = errno;
|
||||
GOfree(inforec.pathname);
|
||||
errno = err;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* fstatfs
|
||||
*/
|
||||
|
||||
int
|
||||
fstatfs (int fd, struct statfs *buf)
|
||||
{
|
||||
RefInfoRecGS inforec;
|
||||
int err, result;
|
||||
|
||||
/* get the pathname based on the file descriptor */
|
||||
inforec.pCount = 3;
|
||||
inforec.refNum = fd;
|
||||
inforec.pathname = (ResultBuf255Ptr) GOinit(GSOS_NAME_MAX, NULL);
|
||||
GetRefInfoGS (&inforec);
|
||||
if ((err = _mapErr(_toolErr)) != 0) {
|
||||
GOfree(inforec.pathname);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* _statfs does the rest */
|
||||
result = _statfs((GSStringPtr) &inforec.pathname->bufString, buf);
|
||||
err = errno;
|
||||
GOfree(inforec.pathname);
|
||||
errno = err;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* fsync
|
||||
*/
|
||||
|
||||
int
|
||||
fsync(int fd) {
|
||||
short ff[2];
|
||||
|
||||
ff[0] = 1;
|
||||
ff[1] = fd;
|
||||
FlushGS(ff);
|
||||
if (_toolErr) {
|
||||
errno = _mapErr(_toolErr);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ftruncate
|
||||
*/
|
||||
|
||||
int
|
||||
ftruncate(int fd, off_t length)
|
||||
{
|
||||
SetPositionRecGS p;
|
||||
|
||||
p.pCount = 3;
|
||||
p.base = 0;
|
||||
p.refNum = fd;
|
||||
p.displacement = length;
|
||||
SetEOFGS(&p);
|
||||
if (_toolErr) {
|
||||
errno = _mapErr(_toolErr);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* getdtablesize
|
||||
*/
|
||||
|
||||
int
|
||||
getdtablesize (void) {
|
||||
return OPEN_MAX;
|
||||
}
|
||||
|
||||
/*
|
||||
* getpgrp
|
||||
*/
|
||||
|
||||
pid_t
|
||||
getpgrp (void) {
|
||||
return _getpgrp(getpid());
|
||||
}
|
||||
|
||||
/*
|
||||
* gettimeofday
|
||||
*
|
||||
* IIgs HACK! HACK! HACK! We need a real gettimeofday!
|
||||
*/
|
||||
|
||||
int
|
||||
gettimeofday (struct timeval *tp, struct timezone *tzp) {
|
||||
tp->tv_sec = time(NULL);
|
||||
tp->tv_usec = 0l;
|
||||
}
|
||||
|
||||
/*
|
||||
* lseek
|
||||
*/
|
||||
|
||||
off_t
|
||||
lseek(int filds, off_t offset, int whence) {
|
||||
SetPositionRecGS s;
|
||||
PositionRecGS m;
|
||||
EOFRecGS e;
|
||||
int err;
|
||||
|
||||
e.pCount = m.pCount = 2;
|
||||
e.refNum = s.refNum = m.refNum = filds;
|
||||
GetEOFGS(&e);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
errno = err;
|
||||
return -1L;
|
||||
}
|
||||
GetMarkGS(&m);
|
||||
|
||||
s.pCount = 3;
|
||||
s.base = 0;
|
||||
switch (whence) {
|
||||
case SEEK_SET: s.displacement = offset; break;
|
||||
case SEEK_CUR: s.displacement = m.position + offset; break;
|
||||
case SEEK_END: s.displacement = e.eof + offset; break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1L;
|
||||
}
|
||||
if (s.displacement < 0) {
|
||||
errno = EINVAL;
|
||||
return -1L;
|
||||
}
|
||||
if (s.displacement > e.eof) {
|
||||
SetEOFGS(&s);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
errno = err;
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
SetMarkGS(&s);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
errno = err;
|
||||
return -1L;
|
||||
}
|
||||
return s.displacement;
|
||||
}
|
||||
|
||||
/*
|
||||
* mkdir
|
||||
*/
|
||||
|
||||
int
|
||||
mkdir(char *dirname)
|
||||
{
|
||||
CreateRecGS cr;
|
||||
int err;
|
||||
|
||||
cr.pCount = 5;
|
||||
cr.pathname = (GSString255Ptr) __C2GSMALLOC(dirname);
|
||||
if (cr.pathname == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
cr.access = 0xC3;
|
||||
cr.fileType = 0x0F;
|
||||
cr.auxType = 0L;
|
||||
cr.storageType = 0x0D;
|
||||
CreateGS(&cr);
|
||||
err = _toolErr;
|
||||
free(cr.pathname);
|
||||
if (err) {
|
||||
errno = _mapErr(err);
|
||||
return -1;
|
||||
}
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* raise
|
||||
*/
|
||||
|
||||
int
|
||||
raise (int sig) {
|
||||
return kill (getpid(), sig);
|
||||
}
|
||||
|
||||
/*
|
||||
* read
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
read (int filds, void *buf, size_t bytecount) {
|
||||
IORecGS iorec = {4, filds, buf, (long) bytecount, 0L};
|
||||
char *p;
|
||||
size_t i;
|
||||
int err;
|
||||
ssize_t result;
|
||||
|
||||
/* read in the buffer */
|
||||
ReadGS(&iorec);
|
||||
if (_toolErr == 0 || _toolErr == 0x4C) {
|
||||
result = (size_t) iorec.transferCount;
|
||||
} else if (err = _mapErr(_toolErr)) {
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* translate newlines if necessary */
|
||||
if (_getFdTranslation(filds)) {
|
||||
p = (char *) buf;
|
||||
for (i = 0; i < result; i++, p++) {
|
||||
if (*p == '\r') {
|
||||
*p = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rexit
|
||||
*/
|
||||
|
||||
void
|
||||
rexit (int code) {
|
||||
SystemQuitFlags (0x4000);
|
||||
SystemQuitPath (NULL);
|
||||
exit(code);
|
||||
}
|
||||
|
||||
/*
|
||||
* statfs
|
||||
*/
|
||||
|
||||
int
|
||||
statfs(char *path, struct statfs *buf) {
|
||||
ExpandPathRecGS ep;
|
||||
int err, result;
|
||||
|
||||
/* get the full pathname of this file */
|
||||
ep.pCount = 3;
|
||||
if ((ep.inputPath = (GSString255Ptr) __C2GSMALLOC(path)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ep.outputPath = (ResultBuf255Ptr) GOinit(GSOS_NAME_MAX, NULL);
|
||||
if (ep.outputPath == NULL) {
|
||||
err = errno;
|
||||
free(ep.inputPath);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
ep.flags = 0;
|
||||
ExpandPathGS(&ep);
|
||||
if (_toolErr) {
|
||||
result = -1;
|
||||
err = _mapErr(_toolErr);
|
||||
} else {
|
||||
result = _statfs((GSStringPtr) &ep.outputPath->bufString, buf);
|
||||
err = errno;
|
||||
}
|
||||
free(ep.inputPath);
|
||||
GOfree(ep.outputPath);
|
||||
errno = err;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* truncate
|
||||
*/
|
||||
|
||||
int
|
||||
truncate(const char *path, off_t length)
|
||||
{
|
||||
SetPositionRecGS p;
|
||||
int closerec[2];
|
||||
struct {
|
||||
Word pCount;
|
||||
Word refNum;
|
||||
GSStringPtr pathname;
|
||||
Word requestAccess;
|
||||
} openrec; /* abbreviated version of OpenRecGS */
|
||||
int err, result;
|
||||
|
||||
/* open the file */
|
||||
openrec.pCount = 3;
|
||||
if ((openrec.pathname = __C2GSMALLOC(path)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
openrec.requestAccess = readWriteEnable;
|
||||
OpenGS(&openrec);
|
||||
err = _mapErr(_toolErr);
|
||||
free(openrec.pathname);
|
||||
if (err) {
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set up the close block */
|
||||
closerec[0] = 1;
|
||||
closerec[1] = openrec.refNum;
|
||||
|
||||
p.pCount = 3;
|
||||
p.base = 0;
|
||||
p.refNum = openrec.refNum;
|
||||
p.displacement = length;
|
||||
SetEOFGS(&p);
|
||||
if (_toolErr) {
|
||||
errno = _mapErr(_toolErr);
|
||||
result = -1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
CloseGS(closerec);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* umask
|
||||
*/
|
||||
|
||||
mode_t
|
||||
umask (mode_t mask) {
|
||||
static mode_t currentMask = 0xFFFF;
|
||||
static int maskInitialized = 0;
|
||||
char *p;
|
||||
mode_t result;
|
||||
char maskStr[5];
|
||||
const char *umaskStr = "UMASK";
|
||||
|
||||
/* initialize off of environment first time through -- hack */
|
||||
if (! maskInitialized) {
|
||||
if ((p = getenv(umaskStr)) == NULL) {
|
||||
currentMask = 022;
|
||||
} else {
|
||||
currentMask = strtoul(p, NULL, 8);
|
||||
}
|
||||
maskInitialized = 1;
|
||||
}
|
||||
|
||||
result = currentMask;
|
||||
currentMask = mask & 0777;
|
||||
maskStr[0] = '0';
|
||||
maskStr[1] = '0' + ((currentMask & 0700) >> 6);
|
||||
maskStr[2] = '0' + ((currentMask & 0070) >> 3);
|
||||
maskStr[3] = '0' + (currentMask & 0007);
|
||||
maskStr[4] = '\0';
|
||||
setenv(umaskStr, maskStr, 1); /* ignore errors */
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* unlink
|
||||
*/
|
||||
|
||||
int unlink(char *fname)
|
||||
{
|
||||
/*
|
||||
* Orca/C doesn't specify what the "non-zero" return code is, so
|
||||
* force it to be -1.
|
||||
*/
|
||||
return (remove(fname) == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* When GNO supports wait4(2) (and assuming that it doesn't have waitpid()),
|
||||
* this routine can be changed to the following:
|
||||
*
|
||||
* return (wait4(pid, istat, options, (struct rusage *)0));
|
||||
*
|
||||
* This implementation is flawed since it's not done in the kernel. See
|
||||
* the BUGS section of the man page for details.
|
||||
*/
|
||||
|
||||
pid_t
|
||||
waitpid(pid_t pid, union wait *istat, int options)
|
||||
{
|
||||
int result;
|
||||
pid_t pgid;
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* there's a note in <unistd.h> about the implementation of
|
||||
* getpgrp() being buggy.
|
||||
*/
|
||||
if (pid < -1 || pid == 0) {
|
||||
fprintf(stderr,"waitpid: process groups not implemented. Aborted.\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We really need to do this in the kernel. */
|
||||
if (pid < -1) {
|
||||
pgid = -pid;
|
||||
} else if (pid == 0) {
|
||||
pgid = _getpgrp(getpid());
|
||||
} else {
|
||||
pgid = -1;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
result = wait(istat);
|
||||
if ((result == -1) ||
|
||||
(pid == result) ||
|
||||
((pgid > 1) && (pgid == _getpgrp(result)))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* write
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
write(int filds, void *buf, size_t bytecount) {
|
||||
IORecGS iorec = {4, filds, buf, (long) bytecount, 0L};
|
||||
int err;
|
||||
size_t i;
|
||||
char *p;
|
||||
|
||||
/* translate newlines if necessary */
|
||||
if (_getFdTranslation(filds)) {
|
||||
p = (char *) buf;
|
||||
for (i = 0; i < bytecount; i++, p++) {
|
||||
if (*p == '\n') {
|
||||
*p = '\r';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write the file block */
|
||||
WriteGS(&iorec);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
return (size_t) iorec.transferCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* open -- end of file because of higher optimization required
|
||||
*/
|
||||
|
||||
/* pragma optimize 79 */
|
||||
#pragma optimize 8
|
||||
#pragma debug 0
|
||||
|
||||
int
|
||||
open (const char *path, int oflag, ...) {
|
||||
OpenRecGS openRec;
|
||||
CreateRecGS createRec;
|
||||
SetPositionRecGS setMarkRec;
|
||||
va_list list;
|
||||
mode_t openmode;
|
||||
int err; /* saved errno */
|
||||
int result; /* returned value */
|
||||
size_t currentEof; /* saved eof nec for append */
|
||||
|
||||
/* grab extra parameter if necessary */
|
||||
va_start(list, oflag);
|
||||
if (oflag & O_CREAT) {
|
||||
openmode = va_arg(list, mode_t);
|
||||
}
|
||||
err = 0;
|
||||
|
||||
/* try to open the file */
|
||||
openRec.pCount = 12;
|
||||
openRec.pathname = (GSString255Ptr) __C2GSMALLOC(path);
|
||||
if (openRec.pathname == NULL) {
|
||||
va_end(list);
|
||||
errno = ENOMEM;
|
||||
return -1; /* DON'T goto label 'done' ... spurious free() */
|
||||
}
|
||||
if ((oflag & O_ACCMODE) == O_RDONLY) {
|
||||
openRec.requestAccess = readEnable;
|
||||
} else if ((oflag & O_ACCMODE) == O_WRONLY) {
|
||||
openRec.requestAccess = writeEnable;
|
||||
} else if ((oflag & O_ACCMODE) == O_RDWR) {
|
||||
openRec.requestAccess = readWriteEnable;
|
||||
} else {
|
||||
openRec.requestAccess = 0;
|
||||
}
|
||||
openRec.resourceNumber = 0; /* data fork */
|
||||
openRec.optionList = NULL; /* no FST-specific info */
|
||||
|
||||
OpenGS(&openRec);
|
||||
if ((_toolErr == 0) && (oflag & O_CREAT) && (oflag & O_EXCL)) {
|
||||
/* file already existed */
|
||||
close(openRec.refNum);
|
||||
err = EEXIST;
|
||||
result = -1;
|
||||
goto done;
|
||||
} else if ((_toolErr == 0) && (oflag & O_WRONLY) &&
|
||||
(openRec.storageType == 0x0d || openRec.storageType == 0x0f)) {
|
||||
/* opening a volume directory or subdirectory for writing not permitted */
|
||||
close(openRec.refNum);
|
||||
err = EISDIR;
|
||||
result = -1;
|
||||
goto done;
|
||||
} else if ((err = _mapErr(_toolErr)) && (err == ENOENT)) {
|
||||
/* file doesn't exist -- create? */
|
||||
if (oflag & O_CREAT) {
|
||||
createRec.pCount = 3;
|
||||
createRec.pathname = openRec.pathname;
|
||||
createRec.access = _mapMode2GS(openmode);
|
||||
createRec.fileType = (oflag & O_BINARY) ? BIN : TXT;
|
||||
CreateGS(&createRec);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
OpenGS(&openRec);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
/* no create and didn't exist -- error */
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
} else if (err) {
|
||||
/* unknown error on open */
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* if we got here, the file is open */
|
||||
currentEof = openRec.eof;
|
||||
|
||||
/* truncate the file if necessary */
|
||||
if ((oflag & O_TRUNC) && ((oflag & O_ACCMODE) != O_RDONLY)) {
|
||||
ftruncate(openRec.refNum, 0L);
|
||||
currentEof = 0L;
|
||||
}
|
||||
|
||||
/* append to file? */
|
||||
if ((oflag & O_APPEND) && ((oflag & O_ACCMODE) != O_RDONLY)) {
|
||||
setMarkRec.pCount = 3;
|
||||
setMarkRec.refNum = openRec.refNum;
|
||||
setMarkRec.base = 0;
|
||||
setMarkRec.displacement = currentEof;
|
||||
SetMarkGS(&setMarkRec);
|
||||
if (err = _mapErr(_toolErr)) {
|
||||
result = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* success! */
|
||||
err = 0;
|
||||
result = openRec.refNum;
|
||||
if (oflag & O_TRANS) {
|
||||
_setFdTranslation(result, 1);
|
||||
}
|
||||
|
||||
done:
|
||||
free(openRec.pathname);
|
||||
va_end(list);
|
||||
errno = err;
|
||||
return result;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,251 @@
|
|||
macro
|
||||
&lab ph4 &parm
|
||||
lclc &char
|
||||
lclc &char1
|
||||
lclc &char2
|
||||
&lab anop
|
||||
&char amid &parm,1,1
|
||||
aif "&char"="#",.immediate
|
||||
aif "&char"="@",.at
|
||||
aif s:longa=1,.chk1
|
||||
rep #%00100000
|
||||
.chk1
|
||||
aif "&char"<>"{",.chk2
|
||||
&char amid &parm,l:&parm,1
|
||||
aif "&char"<>"}",.error
|
||||
&parm amid &parm,2,l:&parm-2
|
||||
ldy #2
|
||||
lda (&parm),y
|
||||
pha
|
||||
lda (&parm)
|
||||
pha
|
||||
ago .shorten
|
||||
.chk2
|
||||
aif "&char"<>"[",.absolute
|
||||
ldy #2
|
||||
lda &parm,y
|
||||
pha
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.absolute
|
||||
lda &parm+2
|
||||
pha
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.at
|
||||
&char1 amid &parm,2,1
|
||||
&char2 setc &char1
|
||||
ph&char1
|
||||
aif l:&parm<3,.chk2a
|
||||
&char2 amid &parm,3,1
|
||||
.chk2a
|
||||
ph&char2
|
||||
ago .shorten
|
||||
.immediate
|
||||
&parm amid &parm,2,l:&parm-1
|
||||
pea +(&parm)|-16
|
||||
pea &parm
|
||||
ago .done
|
||||
.shorten
|
||||
aif s:longa=1,.done
|
||||
sep #%00100000
|
||||
.done
|
||||
mexit
|
||||
.error
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
MACRO
|
||||
&lab return2
|
||||
&lab anop
|
||||
.h
|
||||
aif &totallen=0,.i
|
||||
lda &worklen+1
|
||||
sta &worklen+&totallen+1
|
||||
lda &worklen
|
||||
sta &worklen+&totallen
|
||||
.i
|
||||
plb
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #&worklen+&totallen
|
||||
tcs
|
||||
tya
|
||||
.j
|
||||
rtl
|
||||
mend
|
||||
MACRO
|
||||
&lab ph2 &parm
|
||||
lclc &char
|
||||
&lab anop
|
||||
aif c:&parm=0,.done
|
||||
&char amid &parm,1,1
|
||||
aif "&char"="#",.immediate
|
||||
aif "&char"="@",.at
|
||||
aif s:longa=1,.chk
|
||||
rep #%00100000
|
||||
.chk
|
||||
aif "&char"<>"{",.absolute
|
||||
&char amid &parm,l:&parm,1
|
||||
aif "&char"<>"}",.error
|
||||
&parm amid &parm,2,l:&parm-2
|
||||
lda (&parm)
|
||||
pha
|
||||
ago .shorten
|
||||
.absolute
|
||||
lda &parm
|
||||
pha
|
||||
ago .shorten
|
||||
.immediate
|
||||
&parm amid &parm,2,l:&parm-1
|
||||
pea &parm
|
||||
ago .done
|
||||
.at
|
||||
&char amid &parm,2,1
|
||||
ph&char
|
||||
.shorten
|
||||
aif s:longa=1,.done
|
||||
sep #%00100000
|
||||
.done
|
||||
mexit
|
||||
.error
|
||||
mnote "Missing closing '}'",16
|
||||
mend
|
||||
macro
|
||||
&l ret &r
|
||||
&l anop
|
||||
lclc &len
|
||||
aif c:&r,.a
|
||||
lclc &r
|
||||
&r setc 0
|
||||
&len setc 0
|
||||
ago .h
|
||||
.a
|
||||
&len amid &r,2,1
|
||||
aif "&len"=":",.b
|
||||
&len amid &r,1,2
|
||||
&r amid &r,4,l:&r-3
|
||||
ago .c
|
||||
.b
|
||||
&len amid &r,1,1
|
||||
&r amid &r,3,l:&r-2
|
||||
.c
|
||||
aif &len<>2,.d
|
||||
ldy &r
|
||||
ago .h
|
||||
.d
|
||||
aif &len<>4,.e
|
||||
ldx &r+2
|
||||
ldy &r
|
||||
ago .h
|
||||
.e
|
||||
aif &len<>10,.g
|
||||
ldy #&r
|
||||
ldx #^&r
|
||||
ago .h
|
||||
.g
|
||||
mnote 'Not a valid return length',16
|
||||
mexit
|
||||
.h
|
||||
aif &totallen=0,.i
|
||||
lda &worklen+2
|
||||
sta &worklen+&totallen+2
|
||||
lda &worklen+1
|
||||
sta &worklen+&totallen+1
|
||||
.i
|
||||
pld
|
||||
tsc
|
||||
clc
|
||||
adc #&worklen+&totallen
|
||||
tcs
|
||||
aif &len=0,.j
|
||||
tya
|
||||
.j
|
||||
rtl
|
||||
mend
|
||||
macro
|
||||
&l sub &parms,&work
|
||||
&l anop
|
||||
aif c:&work,.a
|
||||
lclc &work
|
||||
&work setc 0
|
||||
.a
|
||||
gbla &totallen
|
||||
gbla &worklen
|
||||
&worklen seta &work
|
||||
&totallen seta 0
|
||||
aif c:&parms=0,.e
|
||||
lclc &len
|
||||
lclc &p
|
||||
lcla &i
|
||||
&i seta c:&parms
|
||||
.b
|
||||
&p setc &parms(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.c
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .d
|
||||
.c
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.d
|
||||
&p equ &totallen+4+&work
|
||||
&totallen seta &totallen+&len
|
||||
&i seta &i-1
|
||||
aif &i,^b
|
||||
.e
|
||||
tsc
|
||||
aif &work=0,.f
|
||||
sec
|
||||
sbc #&work
|
||||
tcs
|
||||
.f
|
||||
phd
|
||||
tcd
|
||||
mend
|
||||
MACRO
|
||||
&lab subroutine &parms,&work
|
||||
&lab anop
|
||||
aif c:&work,.a
|
||||
lclc &work
|
||||
&work setc 0
|
||||
.a
|
||||
gbla &totallen
|
||||
gbla &worklen
|
||||
&worklen seta &work
|
||||
&totallen seta 0
|
||||
aif c:&parms=0,.e
|
||||
lclc &len
|
||||
lclc &p
|
||||
lcla &i
|
||||
&i seta c:&parms
|
||||
.b
|
||||
&p setc &parms(&i)
|
||||
&len amid &p,2,1
|
||||
aif "&len"=":",.c
|
||||
&len amid &p,1,2
|
||||
&p amid &p,4,l:&p-3
|
||||
ago .d
|
||||
.c
|
||||
&len amid &p,1,1
|
||||
&p amid &p,3,l:&p-2
|
||||
.d
|
||||
&p equ &totallen+3+&work
|
||||
&totallen seta &totallen+&len
|
||||
&i seta &i-1
|
||||
aif &i,^b
|
||||
.e
|
||||
tsc
|
||||
sec
|
||||
sbc #&work
|
||||
tcs
|
||||
inc a
|
||||
phd
|
||||
tcd
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
mend
|
|
@ -0,0 +1,12 @@
|
|||
#
|
||||
# Makefile for libc/tests.
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:51 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../const.mk
|
||||
|
||||
TESTS =
|
||||
|
||||
default: $(TESTS)
|
||||
/bin/true
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:51 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../../const.mk
|
||||
|
||||
STACK =
|
||||
LIBC := ../../libc
|
||||
LDLIBS = -l$(LIBC)
|
||||
CFLAGS := -v -w -G25 $(STACK) $(DEFINES) $(INCLUDES)
|
||||
|
||||
default: basename dirent envtest err getcwd getgrent scandir sleep
|
||||
|
||||
.PRECIOUS: basename dirent.o envtest.o err.o getcwd.o getgrent.o scandir.o \
|
||||
sleep.o
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Test by Devin Reade
|
||||
*
|
||||
* $Id: basename.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"usage: %s filename\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("basename(\"%s\") = \"%s\"\n", argv[1], basename(argv[1]));
|
||||
printf("dirname(\"%s\") = \"%s\"\n", argv[1], dirname(argv[1]));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Test by Devin Reade
|
||||
*
|
||||
* $Id: dirent.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define FAIL(arg) { fprintf(stderr,"%s (errno==%d)\n", arg, errno); exit(1); }
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
DIR *dirp;
|
||||
struct dirent *ent;
|
||||
char *path;
|
||||
int count;
|
||||
long offset;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: %s dir_name\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
path = argv[1];
|
||||
|
||||
printf("opening %s\n", path);
|
||||
|
||||
/* test opendir */
|
||||
if ((dirp = opendir(path)) == NULL) {
|
||||
FAIL("opendir failed");
|
||||
}
|
||||
|
||||
/* test dirfd */
|
||||
printf("dirfd returns %d\n", dirfd(dirp));
|
||||
|
||||
/* test readdir and telldir */
|
||||
count = 0;
|
||||
printf("current offset is %ld\n", telldir(dirp));
|
||||
while ((ent = readdir(dirp)) != NULL) {
|
||||
printf("\t%lu %hu %hu %hu %s\n", ent->d_fileno,
|
||||
ent->d_reclen, (unsigned short) ent->d_type,
|
||||
(unsigned short) ent->d_namlen, ent->d_name);
|
||||
if (count == 1) {
|
||||
offset = telldir(dirp);
|
||||
printf("count %d has offset %ld\n", count, offset);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
/* test seekdir */
|
||||
printf("seeking to saved offset\n");
|
||||
seekdir(dirp, offset);
|
||||
if ((ent = readdir(dirp)) != NULL) {
|
||||
printf("\t%lu %hu %hu %hu %s\n", ent->d_fileno,
|
||||
ent->d_reclen, (unsigned short) ent->d_type,
|
||||
(unsigned short) ent->d_namlen, ent->d_name);
|
||||
}
|
||||
|
||||
/* test rewinddir */
|
||||
printf("rewinding directory:\n");
|
||||
rewinddir(dirp);
|
||||
while ((ent = readdir(dirp)) != NULL) {
|
||||
printf("\t%lu %hu %hu %hu %s\n", ent->d_fileno,
|
||||
ent->d_reclen, (unsigned short) ent->d_type,
|
||||
(unsigned short) ent->d_namlen, ent->d_name);
|
||||
}
|
||||
|
||||
/* test closedir */
|
||||
printf("closedir returns %d\n", closedir(dirp));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Tests for gen/err.c
|
||||
* Written by Devin Reade
|
||||
*
|
||||
* $Id: err.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
void
|
||||
custom_exit(int val) {
|
||||
printf("in custom_exit with val %d\n", val);
|
||||
exit(val);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("testing err_set_file\n");
|
||||
err_set_file(stdout);
|
||||
printf("testing err_set_exit\n");
|
||||
err_set_exit(custom_exit);
|
||||
|
||||
errno = ENOMEM;
|
||||
|
||||
printf("testing warn and vwarn\n");
|
||||
warn("\ttest of %s", "warn");
|
||||
printf("testing warnx and vwarnx\n");
|
||||
warnx("\ttest of warnx");
|
||||
|
||||
i = atoi(argv[1]);
|
||||
switch (i) {
|
||||
case 0:
|
||||
printf("testing err and verr\n");
|
||||
err(1, "\ttest of %s", "err");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
printf("testing errx and verrx\n");
|
||||
errx(2, "\ttest of %s", "verrx"); /* bogus */
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown case: %d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Test written by Devin Reade
|
||||
*
|
||||
* This one doesn't test the flags parameter yet.
|
||||
*
|
||||
* $Id: fnmatch.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv) {
|
||||
int result;
|
||||
|
||||
if (argc != 3) {
|
||||
printf("usage: %s pattern filename\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result = fnmatch (argv[1], argv[2], FNM_CASEFOLD);
|
||||
printf("result is %d\n", result);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#line 1 ":trenco4:gno.src:lib:libc:tests:gen:getcwd.c"
|
||||
/*
|
||||
* Test written by Devin Reade.
|
||||
*
|
||||
* $Id: getcwd.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define BUFFERSIZE PATH_MAX
|
||||
#define BUFFERSIZE2 15
|
||||
|
||||
__const char *__const sys_siglist[] = { "dummy list", NULL };
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
static char buffer[BUFFERSIZE];
|
||||
static char buffer2[BUFFERSIZE2];
|
||||
|
||||
char *p, *buf;
|
||||
int i, len;
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
switch (i) {
|
||||
case 0: buf = NULL; len = 0; break; /* should pass */
|
||||
case 1: buf = buffer; len = BUFFERSIZE; break; /* should pass */
|
||||
case 2: buf = buffer2; len = BUFFERSIZE2; break; /* should fail */
|
||||
default: assert(0);
|
||||
}
|
||||
p = getcwd(buf, len);
|
||||
if (p == NULL) {
|
||||
perror("getcwd failed");
|
||||
} else {
|
||||
printf("cwd is \"%s\"\n", p);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Test by Devin Reade.
|
||||
*
|
||||
* $Id: getgrent.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WHEEL "wheel"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct group *gp;
|
||||
int id, i, j;
|
||||
char **pp;
|
||||
|
||||
for (j=0; j<2; j++) {
|
||||
switch (j) {
|
||||
case 0:
|
||||
printf("printing all entries\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("resetting file pointer\n");
|
||||
setgrent();
|
||||
break;
|
||||
}
|
||||
while((gp = getgrent()) != NULL) {
|
||||
printf("entry: %s %s %d ", gp->gr_name,
|
||||
gp->gr_passwd, gp->gr_gid);
|
||||
pp = gp->gr_mem;
|
||||
for (i=0; pp[i] != NULL; i++) {
|
||||
printf ("%s ", pp[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strcmp(argv[1], WHEEL)) {
|
||||
if ((gp = getgrnam(argv[1])) == NULL) {
|
||||
printf("%s not present in database\n",
|
||||
argv[1]);
|
||||
} else {
|
||||
printf("group number for %s is %d\n",
|
||||
argv[1], gp->gr_gid);
|
||||
}
|
||||
} else {
|
||||
id = atoi(argv[1]);
|
||||
if ((gp = getgrgid(id)) == NULL) {
|
||||
printf("group %d not present in database\n",
|
||||
id);
|
||||
} else {
|
||||
printf("group name for %d is %s\n",
|
||||
id, gp->gr_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endgrent();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Test by Devin Reade.
|
||||
*
|
||||
* $Id: getpwent.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#pragma debug 25
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WHOAMI "glyn"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct passwd *pw;
|
||||
int id, i, j;
|
||||
char **pp;
|
||||
|
||||
for (j=0; j<2; j++) {
|
||||
switch (j) {
|
||||
case 0:
|
||||
printf("printing all entries\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("resetting file pointer\n");
|
||||
setpwent();
|
||||
break;
|
||||
}
|
||||
while((pw = getpwent()) != NULL) {
|
||||
printf("entry: \"%s\" \"%s\" %u %u\n",
|
||||
pw->pw_name, pw->pw_passwd,
|
||||
pw->pw_uid, pw->pw_gid);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
if (!strcmp(argv[1], WHOAMI)) {
|
||||
if ((pw = getpwnam(argv[1])) == NULL) {
|
||||
printf("%s not present in database\n",
|
||||
argv[1]);
|
||||
} else {
|
||||
printf("uid for %s is %u\n",
|
||||
argv[1], pw->pw_uid);
|
||||
}
|
||||
} else {
|
||||
id = atoi(argv[1]);
|
||||
if ((pw = getpwuid(id)) == NULL) {
|
||||
printf("uid %u not present in database\n",
|
||||
id);
|
||||
} else {
|
||||
printf("id for %u is %s using shell %s\n",
|
||||
id, pw->pw_name, pw->pw_shell ?
|
||||
pw->pw_shell : "(null)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endpwent();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Test by Devin Reade
|
||||
*
|
||||
* $Id: popen.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
|
||||
#define BUFFERSIZE 1024
|
||||
char buffer[BUFFERSIZE];
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
FILE *fp;
|
||||
int errflag = 0;
|
||||
int c;
|
||||
char *mode;
|
||||
|
||||
while ((c = getopt(argc, argv, "rw")) != EOF) {
|
||||
switch (c) {
|
||||
case 'r':
|
||||
mode = "r";
|
||||
break;
|
||||
case 'w':
|
||||
mode = "w";
|
||||
break;
|
||||
default:
|
||||
warnx("unknown option: %c", c);
|
||||
errflag++;
|
||||
}
|
||||
}
|
||||
if (errflag) {
|
||||
exit(1);
|
||||
}
|
||||
if (argc - optind != 1) {
|
||||
errx(1,"one argument required");
|
||||
}
|
||||
|
||||
if ((fp = popen(argv[optind], mode)) == NULL) {
|
||||
err(1, "popen failed");
|
||||
}
|
||||
while (fgets(buffer, BUFFERSIZE, fp) != NULL) {
|
||||
printf("T: %s", buffer);
|
||||
}
|
||||
printf("now doing pclose\n");
|
||||
c = pclose(fp);
|
||||
printf("pclose returned %d\n", c);
|
||||
|
||||
return c;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Test by Devin Reade.
|
||||
*
|
||||
* $Id: scandir.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define FAIL(arg) { fprintf(stderr,"%s (errno==%d)\n", arg, errno); exit(1); }
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
struct dirent **namelist;
|
||||
char *path;
|
||||
int count, i, loop;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: %s dir_name\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
path = argv[1];
|
||||
|
||||
for (loop = 0; loop < 2; loop++) {
|
||||
switch(loop) {
|
||||
case 0:
|
||||
printf("sorting %s\n", path);
|
||||
count = scandir(path, &namelist, NULL, alphasort);
|
||||
break;
|
||||
case 1:
|
||||
printf("sorting %s (case insensitive)\n", path);
|
||||
count = scandir(path, &namelist, NULL, alphacasesort);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (count == -1) {
|
||||
FAIL("scandir failed");
|
||||
}
|
||||
for (i=0; i<count; i++) {
|
||||
printf("\t%s\n", namelist[i]->d_name);
|
||||
}
|
||||
printf("freeing pointers: ");
|
||||
for (i=0; i<count; i++) {
|
||||
printf(" %d", i);
|
||||
free(namelist[i]);
|
||||
}
|
||||
printf("\n");
|
||||
free(namelist);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
#pragma optimize -1
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
jmp_buf my_jump;
|
||||
|
||||
#pragma databank 1
|
||||
void my_handler(int sig, int code)
|
||||
{
|
||||
printf("WHEEE!\n");
|
||||
asm {brk 2}
|
||||
longjmp(my_jump, 1);
|
||||
}
|
||||
#pragma databank 0
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
sigblock(sigmask(SIGPIPE)); /* something to make the mask interesting */
|
||||
signal(SIGTSTP, my_handler);
|
||||
asm {brk 0}
|
||||
setjmp(my_jump);
|
||||
asm {brk 1}
|
||||
for (;;);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define DURATION 3
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
printf("sleeping for %d seconds\n", DURATION);
|
||||
sleep(DURATION);
|
||||
printf("now awake, starting pause\n");
|
||||
pause();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#line 1 ":trenco4:gno.src:lib:libc:gen:testit.c"
|
||||
#pragma lint -1
|
||||
#pragma keep "testit"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef __GNO__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int fd1, fd2;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("trying first open\n");
|
||||
fd1 = open(argv[1], O_RDONLY);
|
||||
if (fd1 == -1) {
|
||||
perror("open 1 failed\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
printf("trying second open\n");
|
||||
fd2 = open(argv[1], O_RDONLY);
|
||||
if (fd2 == -1) {
|
||||
perror("open 2 failed\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
printf("done!\n");
|
||||
close(fd1);
|
||||
close(fd2);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Test by Devin Reade
|
||||
*
|
||||
* $Id: utime.c,v 1.1 1997/02/28 05:12:52 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <utime.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <time.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct utimbuf utb;
|
||||
|
||||
if (argc != 2) {
|
||||
errx(1, "usage: %s filename", __prognameGS());
|
||||
}
|
||||
|
||||
if ((utb.actime = time(NULL)) == -1) {
|
||||
err(1, "time failed! (shouldn't happen)");
|
||||
}
|
||||
utb.modtime = utb.actime;
|
||||
|
||||
if (utime(argv[1], &utb) == -1) {
|
||||
err(1, "utime for %s failed", argv[1]);
|
||||
}
|
||||
printf("passed\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:54 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
LIBC := ../../libc
|
||||
LDLIBS = -l$(LIBC)
|
||||
CFLAGS := -v -w -G25 $(STACK) $(DEFINES) $(INCLUDES)
|
||||
|
||||
TARGETS = gnomisc gsstring
|
||||
OBJS = gnomisc.o gsstring.o
|
||||
|
||||
default: $(TARGETS)
|
||||
|
||||
.PRECIOUS: $(OBJS)
|
||||
|
||||
clobber clean:
|
||||
$(RM) -f $(TARGETS) $(OBJS)
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This file tests routines from gno/gnomisc.c and gno/stack.asm
|
||||
* Written by Devin Reade
|
||||
*
|
||||
* $Id: gnomisc.c,v 1.1 1997/02/28 05:12:54 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
/* early debugging */
|
||||
#if 0
|
||||
char *optarg, *suboptarg;
|
||||
int optopt, optind, opterr, __mb_cur_max;
|
||||
#endif
|
||||
|
||||
void cleanup (void) {
|
||||
printf("stack usage: %d bytes\n", _endStackCheck());
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
char *p;
|
||||
|
||||
printf("starting stack check\n");
|
||||
_beginStackCheck();
|
||||
atexit(cleanup);
|
||||
|
||||
printf("checking for GNO\n");
|
||||
if (needsgno() == 0) {
|
||||
printf("GNO is NOT active\n");
|
||||
} else {
|
||||
printf("GNO is active\n");
|
||||
}
|
||||
p = __prognameGS();
|
||||
printf("program name is %s\n", p);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Tests by Devin Reade
|
||||
*
|
||||
* $Id: gsstring.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <gno/gno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FAIL() \
|
||||
{ \
|
||||
printf("test failed at line %d of %s\n", __LINE__, __FILE__); \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
#if 1
|
||||
#define NO_RESOURCE() { printf("resource failure\n"); exit(EXIT_FAILURE); }
|
||||
#else
|
||||
#define NO_RESOURCE() \
|
||||
{ \
|
||||
perror("resource failure"); \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *str1 = "this is a test string\n";
|
||||
const char *str2 = "this is longer than the first\n";
|
||||
|
||||
int main(int argc, char **arv) {
|
||||
GSStringPtr ptr1, ptr2;
|
||||
ResultBufPtr ptr3, ptr4;
|
||||
size_t len1, len2;
|
||||
|
||||
printf("testing GIinit\n");
|
||||
len1 = strlen(str1);
|
||||
if ((ptr1 = GIinit(len1, str1)) == NULL) NO_RESOURCE();
|
||||
if (len1 != ptr1->length) FAIL();
|
||||
if (ptr1->text[len1] != '\0') FAIL();
|
||||
if (strcmp(str1, ptr1->text)) FAIL();
|
||||
|
||||
printf("testing GIchange\n");
|
||||
len2 = strlen(str2);
|
||||
if ((ptr2 = GIchange(ptr1, len2, NULL)) == NULL) NO_RESOURCE();
|
||||
if (len2 != ptr2->length) FAIL();
|
||||
if (ptr2->text[len2] != '\0') FAIL();
|
||||
if (ptr2->text[0] != '\0') FAIL();
|
||||
|
||||
printf("testing GIfree\n");
|
||||
GIfree(ptr2);
|
||||
|
||||
#define RESULT_LEN1 300
|
||||
#define RESULT_LEN2 10
|
||||
|
||||
printf("testing GOinit\n");
|
||||
if ((ptr3 = GOinit(RESULT_LEN1, str1)) == NULL) NO_RESOURCE();
|
||||
if (ptr3->bufSize != RESULT_LEN1 + 2*sizeof(word)) FAIL();
|
||||
if (ptr3->bufString.length != len1) FAIL();
|
||||
if (ptr3->bufString.text[len1] != '\0') FAIL();
|
||||
if (strcmp(ptr3->bufString.text, str1)) FAIL();
|
||||
|
||||
printf("testing GOchange\n");
|
||||
if (RESULT_LEN2 >= len1) FAIL();
|
||||
if ((ptr4 = GOchange(ptr3, RESULT_LEN2, NULL)) == NULL) FAIL();
|
||||
if (ptr4->bufSize != RESULT_LEN2 + 2*sizeof(word)) FAIL();
|
||||
if (ptr4->bufString.length != RESULT_LEN2) FAIL();
|
||||
if (ptr4->bufString.text[RESULT_LEN2] != '\0') FAIL();
|
||||
if (strncmp(ptr4->bufString.text, str1, RESULT_LEN2)) FAIL();
|
||||
|
||||
printf("testing GOfree\n");
|
||||
GOfree(ptr4);
|
||||
|
||||
printf("\nPASSED\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#
|
||||
# Makefile for libc/tests/hdr.compile
|
||||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
#
|
||||
# These should be tested with and without the following macros #defined:
|
||||
# _ANSI_SOURCE
|
||||
# _POSIX_SOURCE
|
||||
# TEST_SGTTY
|
||||
# KERNEL
|
||||
# Currently, defining KERNEL makes no difference for the arpa, protocols,
|
||||
# or rpc tests.
|
||||
#
|
||||
# We don't currently test:
|
||||
# net.c -- non-BSD and unprototyped; insufficient info
|
||||
# protocols.c -- unchanged from Derek's original, which
|
||||
# matches the BSD version.
|
||||
#
|
||||
|
||||
CFLAGS += -DKERNEL
|
||||
|
||||
OBJS = netinet.o machine.o rpc.o arpa.o gno.o sys.o base.o
|
||||
|
||||
default: $(OBJS)
|
||||
|
||||
clobber:
|
||||
$(RM) -f $(OBJS)
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* $Id: arpa.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <arpa/ftp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/telnet.h>
|
||||
#include <arpa/tftp.h>
|
||||
|
||||
int i;
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* $Id: base.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* This set has no #include dependancies in the base directory, so the
|
||||
* order doesn't matter.
|
||||
*/
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#ifndef KERNEL
|
||||
#include <fts.h>
|
||||
#endif
|
||||
#include <glob.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <regexp.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/*
|
||||
* we can't include both of these; they are mutually exclusive ways
|
||||
* of handling ttys
|
||||
*/
|
||||
#ifdef TEST_SGTTY
|
||||
#include <sgtty.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <termcap.h>
|
||||
#include <time.h>
|
||||
#include <ttyent.h>
|
||||
#include <types.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
/*
|
||||
* This set has _some_ dependancies in the base directory, so watch
|
||||
* the order.
|
||||
*/
|
||||
#include <curses.h>
|
||||
#include <db.h>
|
||||
#include <resolv.h>
|
||||
#include <utmp.h>
|
||||
|
||||
/* a real mess ... */
|
||||
#if 0
|
||||
#include <appletalk.h>
|
||||
#endif
|
||||
|
||||
int i;
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* $Id: gno.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
#include <gno/conf.h>
|
||||
#include <gno/gno.h>
|
||||
#include <gno/proc.h>
|
||||
#include <gno/kvm.h>
|
||||
#include <gno/sim.h>
|
||||
|
||||
/* haven't yet determined if it will be dropped */
|
||||
#if 0
|
||||
#include <gno/kerntool.h>
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* $Id: machine.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <machine/types.h>
|
||||
#include <machine/ansi.h>
|
||||
#include <machine/endian.h>
|
||||
#include <machine/limits.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/signal.h>
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* $Id: net.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <net/af.h>
|
||||
#include <net/dli_var.h>
|
||||
#include <net/etherdefs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/netbuf.h>
|
||||
#include <net/netif.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/raw_cb.h>
|
||||
#include <net/route.h>
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* $Id: netinet.c,v 1.1 1997/02/28 05:12:55 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
/* test begins */
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
int i;
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* $Id: protocols.c,v 1.1 1997/02/28 05:12:56 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
/* this is probably missing a goodly number of prerequisites */
|
||||
#include <protocols/talkd.h>
|
||||
|
||||
int i;
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* $Id: rpc.c,v 1.1 1997/02/28 05:12:56 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <rpc/types.h>
|
||||
|
||||
int i;
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* $Id: sys.c,v 1.1 1997/02/28 05:12:56 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
/*
|
||||
* This set has no #include dependancies in sys, so the order doesn't
|
||||
* matter.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/ttydefaults.h>
|
||||
#include <sys/ttydev.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
||||
/* This set has _some_ dependancies in sys, so watch the order. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/ports.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ttychars.h>
|
||||
#include <sys/ioctl_compat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
int i;
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* $Id: test.h,v 1.1 1997/02/28 05:12:56 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
#ifdef __STDC__
|
||||
#define __P(a) a
|
||||
#else
|
||||
#define __P(a) ()
|
||||
#endif
|
||||
|
||||
typedef void (*__SIG_FUNC__) __P((int, int));
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
typedef __SIG_FUNC__ sig_t;
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL */
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:56 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
LIBC := ../../libc
|
||||
LDLIBS = -l$(LIBC)
|
||||
CFLAGS := -v -w -G25 $(STACK) $(DEFINES) $(INCLUDES)
|
||||
|
||||
default: perror
|
||||
|
||||
.PRECIOUS: perror.o
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Test by Devin Reade
|
||||
*
|
||||
* $Id: perror.c,v 1.1 1997/02/28 05:12:57 gdr Exp $
|
||||
*/
|
||||
|
||||
#pragma debug 25
|
||||
|
||||
/* for now ... */
|
||||
#define sys_nerr _gno_sys_nerr
|
||||
#define sys_errlist _gno_sys_errlist
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "ELAST is %d\n", ELAST);
|
||||
if (argc > 1) {
|
||||
for (i=0; i<sys_nerr; i++) {
|
||||
fprintf(stderr, "loop %d\t\"%s\"\n", i, sys_errlist[i]);
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<sys_nerr; i++) {
|
||||
fprintf(stderr, "loop %d\t", i);
|
||||
errno = i;
|
||||
perror("testing perror");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:57 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../const.mk
|
||||
|
||||
LIBC := ../../libc
|
||||
LDLIBS = -l$(LIBC)
|
||||
CFLAGS := -v -w -G25 $(STACK) $(DEFINES) $(INCLUDES)
|
||||
|
||||
default: environ
|
||||
|
||||
.PRECIOUS: environ.o
|
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
* Tests implemented by Devin Reade
|
||||
*
|
||||
* $Id: environ.c,v 1.1 1997/02/28 05:12:57 gdr Exp $
|
||||
*
|
||||
* This file has been formatted with tab stops every 8 columns.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <types.h>
|
||||
#include <shell.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define NONE_SET 0x00
|
||||
#define UNIX_SET 0x01
|
||||
#define ORCA_SET 0x02
|
||||
#define BOTH_SET 0x03
|
||||
|
||||
extern char **environ;
|
||||
|
||||
static char *string1="testname";
|
||||
static char *string2="testvalue";
|
||||
static char *string3="testname=testvalue";
|
||||
int use_environ;
|
||||
|
||||
/*
|
||||
* void print_Unix_environ (void);
|
||||
*
|
||||
* Pre: none.
|
||||
*
|
||||
* Post: the environment residing in the environ structure is printed
|
||||
* to stdout.
|
||||
*/
|
||||
|
||||
void
|
||||
print_Unix_environ (void) {
|
||||
char **e, *s;
|
||||
const char *fname = "print_Unix_environ";
|
||||
|
||||
if (!environ) {
|
||||
printf("%s: environ is NULL\n", fname);
|
||||
return;
|
||||
}
|
||||
|
||||
e = environ;
|
||||
if (*e==NULL) {
|
||||
printf("%s: environment is empty\n", fname);
|
||||
}
|
||||
while (*e != NULL) {
|
||||
s = *e;
|
||||
if (*s == (char)NULL) {
|
||||
printf("%s: entry of zero length\n", fname);
|
||||
} else {
|
||||
printf("%s\n",s);
|
||||
}
|
||||
e++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* void print_Orca_environ (void);
|
||||
*
|
||||
* Pre: none.
|
||||
*
|
||||
* Post: the environment residing internal to the shell is printed to stderr.
|
||||
* It's not terribly efficient, but then it doesn't have to be ;)
|
||||
*/
|
||||
|
||||
void
|
||||
print_Orca_environ (void) {
|
||||
|
||||
static ReadIndexedGSPB parmBuffer;
|
||||
static ResultBuf255 nameBuffer, valueBuffer;
|
||||
static char *fname = "print_Orca_environ";
|
||||
char *entry;
|
||||
unsigned int nameLength, valueLength;
|
||||
|
||||
/*
|
||||
* initialize the parameter block
|
||||
*/
|
||||
|
||||
parmBuffer.pCount = 4;
|
||||
parmBuffer.index = 1;
|
||||
nameBuffer.bufSize = sizeof (GSString255);
|
||||
valueBuffer.bufSize = sizeof (GSString255);
|
||||
parmBuffer.name = &nameBuffer;
|
||||
parmBuffer.value = &valueBuffer;
|
||||
|
||||
/* loop until we've got them all */
|
||||
ReadIndexedGS (&parmBuffer);
|
||||
nameLength = nameBuffer.bufString.length;
|
||||
while (nameLength != 0) {
|
||||
valueLength = valueBuffer.bufString.length;
|
||||
|
||||
/* allocate the new environ entry */
|
||||
entry = malloc (nameLength + valueLength + 2);
|
||||
if (entry == NULL) {
|
||||
printf("malloc failed in %s: %s\n", fname,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* copy the name and value */
|
||||
strncpy (entry, nameBuffer.bufString.text, nameLength);
|
||||
entry[nameLength] = (char) NULL;
|
||||
strcat (entry, "=");
|
||||
strncat (entry, valueBuffer.bufString.text, valueLength);
|
||||
entry[nameLength + valueLength + 1] = (char) NULL;
|
||||
|
||||
printf("%s\n",entry);
|
||||
free(entry);
|
||||
|
||||
/* get the next shell variable and continue ... */
|
||||
parmBuffer.index++;
|
||||
ReadIndexedGS (&parmBuffer);
|
||||
nameLength = nameBuffer.bufString.length;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
test_environ (void) {
|
||||
|
||||
unsigned int unix_set = 0;
|
||||
unsigned int orca_set = 0;
|
||||
char *s;
|
||||
char **e;
|
||||
|
||||
/* test unix version */
|
||||
if (use_environ) {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\n\nUnix environment:\n\n");
|
||||
print_Unix_environ ();
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
e = environ;
|
||||
while (e && *e) {
|
||||
if (strncmp(*e,string3,strlen(string3)) == 0) {
|
||||
unix_set = UNIX_SET;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
||||
/* test Orca version */
|
||||
if (getenv(string1) != NULL) {
|
||||
orca_set = ORCA_SET;
|
||||
}
|
||||
|
||||
return (unix_set | orca_set);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv) {
|
||||
|
||||
int i=1; /* the number of the test */
|
||||
unsigned int result;
|
||||
|
||||
if (argc > 1) {
|
||||
use_environ = 1;
|
||||
} else {
|
||||
use_environ = 0;
|
||||
printf("NOT ");
|
||||
}
|
||||
printf("using environ global variable\n");
|
||||
|
||||
/*
|
||||
* initial Test 1:1
|
||||
*/
|
||||
|
||||
result = test_environ();
|
||||
if (result != NONE_SET) {
|
||||
printf("Please unset the variable \"%s\" for this test.\n",
|
||||
string1);
|
||||
return -1;
|
||||
}
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
|
||||
#define FAIL(fmt) { printf(fmt, i, string1); exit(1); }
|
||||
|
||||
/*
|
||||
* environInit(); Test :2
|
||||
*/
|
||||
|
||||
if (use_environ) {
|
||||
environInit();
|
||||
result = test_environ();
|
||||
switch (result) {
|
||||
case BOTH_SET: FAIL("Test %d failed. %s prematurely set\n");
|
||||
case ORCA_SET: FAIL("Test %d failed. %s set internally\n");
|
||||
case UNIX_SET: FAIL("Test %d failed. %s set in environ\n");
|
||||
case NONE_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
printf("Test internal error: test %d returned %ud\n",
|
||||
i, result);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* setenv(); Test 2:3
|
||||
*/
|
||||
|
||||
if (setenv(string1,string2,1) != 0) {
|
||||
printf("Test %d: setenv() failed\n",i);
|
||||
return -1;
|
||||
}
|
||||
result = test_environ();
|
||||
if (use_environ) {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case ORCA_SET:
|
||||
FAIL("Test %d failed. %s not set in environ\n");
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
printf("Test internal error: test %d returned %ud\n",
|
||||
i, result);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
FAIL("Test %d failed. %s set in environ\n");
|
||||
case ORCA_SET:
|
||||
printf("Test %d passed.\n", i);
|
||||
i++;
|
||||
break;
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s set in environ, not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
printf("Test internal error: test %d returned %ud\n",
|
||||
i, result);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* unsetenv() Test 3:4
|
||||
*/
|
||||
|
||||
unsetenv(string1);
|
||||
result = test_environ();
|
||||
if (use_environ) {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
FAIL("Test %d failed. %s set\n");
|
||||
case ORCA_SET:
|
||||
FAIL("Test %d failed. %s set internally\n");
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s set in in environ\n");
|
||||
case NONE_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
printf("Test internal error: test %d returned %ud\n",
|
||||
i, result);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
FAIL("Test %d failed. %s set\n");
|
||||
case ORCA_SET:
|
||||
FAIL("Test %d failed. %s set internally\n");
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s set in environ\n");
|
||||
case NONE_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
printf("Test internal error: test %d returned %ud\n",
|
||||
i, result);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* environPush() Test 4:5 bork
|
||||
*/
|
||||
|
||||
if (setenv(string1,string2,1) != 0) {
|
||||
printf("Test %d: setenv() failed\n",i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (environPush() != 0) {
|
||||
printf("Test %d: environPush() failed\n",i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = test_environ();
|
||||
if (use_environ) {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case ORCA_SET:
|
||||
FAIL("Test %d failed. %s not set in environ\n");
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
FAIL("Test %d failed. %s set in environ\n");
|
||||
case ORCA_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s set in environ, not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* environPop() Test 5:6
|
||||
*/
|
||||
|
||||
unsetenv(string1);
|
||||
environPop();
|
||||
result = test_environ();
|
||||
if (use_environ) {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case ORCA_SET:
|
||||
FAIL("Test %d failed. %s not set in environ\n");
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
FAIL("Test %d failed. %s set in environ\n");
|
||||
case ORCA_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s set in environ, not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* putenv() Test 6:7
|
||||
*/
|
||||
|
||||
unsetenv(string1);
|
||||
if (putenv(string3) != 0) {
|
||||
printf("Test %d: putenv() failed\n",i);
|
||||
return -1;
|
||||
}
|
||||
result = test_environ();
|
||||
if (use_environ) {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case ORCA_SET:
|
||||
FAIL("Test %d failed. %s not set in environ\n");
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
switch (result) {
|
||||
case BOTH_SET:
|
||||
FAIL("Test %d failed. %s set in environ\n");
|
||||
case ORCA_SET:
|
||||
printf("Test %d passed.\n",i);
|
||||
i++;
|
||||
break;
|
||||
case UNIX_SET:
|
||||
FAIL("Test %d failed. %s set in environ, not set internally\n");
|
||||
case NONE_SET:
|
||||
FAIL("Test %d failed. %s not set\n");
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
unsetenv(string1);
|
||||
printf("Tests done.\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# $Id: Makefile,v 1.1 1997/02/28 05:12:57 gdr Exp $
|
||||
#
|
||||
|
||||
.INCLUDE: ../../../const.mk
|
||||
|
||||
LDLIBS = -l ../../libc
|
||||
|
||||
CFLAGS := -v -w -G25 $(STACK) $(DEFINES) $(INCLUDES)
|
||||
|
||||
default: creat exectest stat.o trap1
|
||||
|
||||
.PRECIOUS: creat.o exectest.o stat.o trap1.o
|
||||
|
||||
.INCLUDE: ../../rules.mk
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* $Id: creat.c,v 1.1 1997/02/28 05:12:57 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define FILE1 "data/creat1"
|
||||
#define FILE2 "data/creat2"
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
int i;
|
||||
|
||||
if ((i = creat(FILE1, 0644)) == -1) {
|
||||
printf("mode 0644 failed: %d\n", errno);
|
||||
exit(1);
|
||||
} else {
|
||||
close(i);
|
||||
}
|
||||
|
||||
if ((i = creat(FILE2, 0444)) == -1) {
|
||||
printf("mode 0444 failed: %d\n", errno);
|
||||
unlink(FILE1);
|
||||
exit(1);
|
||||
} else {
|
||||
close(i);
|
||||
}
|
||||
|
||||
unlink(FILE1);
|
||||
unlink(FILE2);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Test for exec* routines written by Devin Reade
|
||||
*
|
||||
* $Id: exectest.c,v 1.1 1997/02/28 05:12:57 gdr Exp $
|
||||
*
|
||||
* This file is formatted for tab stops every 8 characters.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#pragma debug 0
|
||||
|
||||
char *argarray[4];
|
||||
char *envarray[2]; /* for execve test */
|
||||
char *envstring="bork=thingamadoo";
|
||||
char *filestr1="now2";
|
||||
|
||||
int
|
||||
main (int argc, char **argv) {
|
||||
int i;
|
||||
|
||||
if (argc!=5) {
|
||||
printf("usage: exectest case prog opt1 opt2\n");
|
||||
printf("\tcase is one of:\n");
|
||||
printf("\t\t0 - execl\n");
|
||||
printf("\t\t1 - execlp\n");
|
||||
printf("\t\t2 - execve\n");
|
||||
printf("\t\t3 - execv\n");
|
||||
printf("\t\t4 - execvp\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
i = atoi(argv[1]);
|
||||
switch (i) {
|
||||
case 0:
|
||||
execl(argv[2], argv[2], argv[3], argv[4], (char *) NULL);
|
||||
perror("execl() failed");
|
||||
break;
|
||||
case 1:
|
||||
execlp(argv[2], argv[2], argv[3], argv[4], (char *) NULL);
|
||||
perror("execlp() failed");
|
||||
break;
|
||||
case 2:
|
||||
envarray[0]=envstring;
|
||||
envarray[1]=NULL;
|
||||
|
||||
argarray[0]=argv[2];
|
||||
argarray[1]=argv[3];
|
||||
argarray[2]=argv[4];
|
||||
argarray[3]=NULL;
|
||||
execve(argarray[0], argarray, envarray);
|
||||
perror("execve failed");
|
||||
break;
|
||||
case 3:
|
||||
argarray[0]=argv[2];
|
||||
argarray[1]=argv[3];
|
||||
argarray[2]=argv[4];
|
||||
argarray[3]=NULL;
|
||||
|
||||
execv(argarray[0], argarray);
|
||||
perror("execv failed");
|
||||
break;
|
||||
case 4:
|
||||
argarray[0]=argv[2];
|
||||
argarray[1]=argv[3];
|
||||
argarray[2]=argv[4];
|
||||
argarray[3]=NULL;
|
||||
|
||||
execvp(argarray[0], argarray);
|
||||
perror("execvp failed");
|
||||
break;
|
||||
default:
|
||||
printf("bad case value: %d\n", i);
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Test by Devin Reade
|
||||
*
|
||||
* $Id: stat.c,v 1.1 1997/02/28 05:12:58 gdr Exp $
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FAIL(msg) {printf("%s\n", msg); exit(1); }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct stat sb;
|
||||
char *path;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: %s filename\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
path = argv[1];
|
||||
|
||||
if (stat (path, &sb) == -1) {
|
||||
FAIL("stat failed");
|
||||
}
|
||||
|
||||
printf("file\t= %s\n", path);
|
||||
printf("device\t= %#4x\n", sb.st_dev);
|
||||
printf("mode\t= %#4x\n", sb.st_mode);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#line 1 ":trenco4:custom.src:contrib:libc:tests:sys:trap1.c"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <gno/gno.h>
|
||||
|
||||
#define FAIL() { printf("TEST FAILED\n"); exit (1); }
|
||||
#define PASS() { printf("test passed\n"); exit (0); }
|
||||
|
||||
#define VERSION_TRIPLE(val) \
|
||||
(((val)&0xFF00) >> 8), \
|
||||
(((val)&0x00F0) >> 4), \
|
||||
(((val)&0x000F) >> 0)
|
||||
|
||||
extern int _toolErr;
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
u_short kernelVersion;
|
||||
|
||||
kernStatus();
|
||||
if (_toolErr) {
|
||||
printf("kernStatus returned %d\n", _toolErr);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
kernelVersion = kernVersion();
|
||||
if (_toolErr) {
|
||||
printf("kernVersion failed with code %d\n", _toolErr);
|
||||
FAIL();
|
||||
} else if (kernelVersion < 0x0204) {
|
||||
printf("there are no tests for kernel version %d.%d.%d\n",
|
||||
VERSION_TRIPLE(0x0204));
|
||||
} else {
|
||||
printf("running tests for kernel version %d.%d.%d\n",
|
||||
VERSION_TRIPLE(0x0204));
|
||||
}
|
||||
|
||||
printf("SYSTEM CALL\t\t\tRETURN VALUE\n");
|
||||
|
||||
printf("getpid\t\t\t\t%d\n", getpid());
|
||||
printf("setdebug(%d)\t\t\t%d\n", dbgSYSCALL, setdebug(dbgSYSCALL));
|
||||
printf("setdebug(%d)\t\t\t%d\n", 0, setdebug(0));
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue