[unix-pc.sources] POSIX/SVID/X3J11 standard routines

lenny@icus.islp.ny.us (Lenny Tropiano) (08/03/89)

Enclosed is some library routines that I find very useful, especially when
taking programs that have SVR3 calls, SVR2 calls that don't appear on
the UNIX pc, or POSIX compatible library calls.   This group of library 
routines is found in the News 3.0 beta distribution.  The routines were 
written by Eric S. Raymond, Henry Spencer, and Doug Gwyn.  Many people
were looking for the DIRENT library routines, well they are found here
too (this will help those who want to compile Gil's "man" program).

I take no responsibility for the code, but I know it's worked time and
time for me.  Especially when compiling things with mkdir(), rename(),
and other SVR3 routines.

There are 5 shar files to prevent any munging by news sites... Unshar all
5 parts and then make the Makefile with:   $ sh Makeposix

-Lenny

--- cut here --- --- cut here --- --- cut here --- --- cut here ---
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 5)."
# Contents:  MANIFEST Makefile.dst README bsearch.c closedir.c dirent.h
#   getopt.c lfind.c lsearch.c memccpy.c memchr.c memcmp.c memory.h
#   memset.c mkdirtest.c posix.lint putpwent.3c putpwent.c readdir.c
#   rename.c rewinddir.c rmdir.c search.h ssignal.c strchr.c strcspn.c
#   strdup.c string.h strpbrk.c strrchr.c strspn.c strtok.c
#   sys.dirent.h telldir.c testdir.c tfind.c unistd.h
# Wrapped by lenny@icus on Wed Aug  2 21:40:15 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(1024 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X DIRENT.INSTALL            3	
X DIRENT.NOTES              3	
X MANIFEST                  1	
X Makefile.dst              1	
X Makeposix                 5	
X README                    1	
X bsearch.3c                3	
X bsearch.c                 1	
X closedir.c                1	
X directory.3c              3	
X dirent.4                  2	
X dirent.h                  1	
X getcwd.c                  3	
X getdents.2                2	
X getdents.c                4	
X getopt.c                  1	
X lfind.c                   1	
X lsearch.3c                2	
X lsearch.c                 1	
X memccpy.c                 1	
X memchr.c                  1	
X memcmp.c                  1	
X memcpy.c                  2	
X memory.3c                 2	
X memory.h                  1	
X memset.c                  1	
X mkdir.3                   2	
X mkdir.c                   3	
X mkdirtest.c               1	
X opendir.c                 2	
X posix.lint                1
END_OF_MANIFEST
echo shar: Missing newline added to \"MANIFEST\"
if test 1024 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.dst -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.dst\"
else
echo shar: Extracting \"Makefile.dst\" \(118 characters\)
sed "s/^X//" >Makefile.dst <<'END_OF_Makefile.dst'
XMakefile: posix_conf
X
Xposix_conf: Makeposix
X	Makeposix
X
Xclean:
X	rm -f libposix.a *.o posix_conf Makefile profiled/*
X	
END_OF_Makefile.dst
if test 118 -ne `wc -c <Makefile.dst`; then
    echo shar: \"Makefile.dst\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(2463 characters\)
sed "s/^X//" >README <<'END_OF_README'
XThis directory provides sources for POSIX/SVID/X3J11 standard routines
Xwhich you can compile and install in your system libraries or in a libposix.a.
XThey include:
X
X	strings(3) -- string function package by Henry Spencer and Eric Raymond
X	directory(3) -- directory-scanning functions by Doug Gwyn
X	strtol(3) -- string-to-long conversion by an anonymous hacker.
X	getopt(3) -- string-to-long conversion by Henry Spencer
X	memory(3) -- memory functions by Eric S. Raymond
X	[btl]search(3) -- binary/tree/linear-search code by Eric S. Raymond
X	gsignal(3) -- user software signals code by Eric S. Raymond
X	putpwent(3) -- write password entry to file
X
XManual pages are provided for all. To install, run Makeposix and follow the
Xinstructions in the Makefile header comment and DIRENT.INSTALL.
X
XNote that Makeposix makes some fairly rigid assumptions about what facilities
Xare associated with which modules in your C library. Some implementations may
Xviolate these assumptions (for example, in 4.2BSD the rewinddir() function
Xlives in a rewinddir.o; in SVr3, it is present but the code lives in one of the
Xother directory library modules).
X
XAs a result, the generated Makefile may want to link modules into your
Xlibrary that duplicate code it aleady contains. This should be harmless, 
Xbecause ar adds the new stuff at the end of the library but does its link-
Xresolution searches from the beginning. But there's no point in altering
Xyour C library if you don't need to, so Makeposix provides a way for you to
Xtell it that particular facilties are in place. Simply call it with one of
Xthe following arguments:
X
X	SVR1	-- assume all System V Release 1 facilities are present
X	SVR2	-- assume all System V Release 1 & 2 facilities are present
X	SVR3	-- assume all System V Release 1, 2 & 3 facilities are present
X	4.2BSD	-- assume all Berkeley 4.2 facilities are present
X	4.3BSD	-- assume all Berkeley 4.2 & 4.3 facilities are present
X
XThis will tell it to act on the assumption that anything normally supported
Xby the given system is present, even if its module checks suggest otherwise.
X
XTo update your lint library to include the right things, you'll need to
Xrecompile your lint library into .ln form. You can do this with lint's -C
Xoption on BSD systems, or its -c option on System V Release 2 sites -- others
Xwill have to dig into the local lint script to find the right magic. A relint
Xproduction that should work for SVr{2,3} sites is provided in the generated
XMakefile.
END_OF_README
if test 2463 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bsearch.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bsearch.c\"
else
echo shar: Extracting \"bsearch.c\" \(897 characters\)
sed "s/^X//" >bsearch.c <<'END_OF_bsearch.c'
X/*
X * A binary search generalized from Knuth (6.2.1) Algorithm B just
X * like the AT&T man page says...
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X
Xchar *bsearch(key, base, nel, width, compar)
Xchar	*key;			/* Key to be located */
Xchar	*base;			/* Beginning of table */
Xunsigned nel;			/* Number of elements in the table */
Xunsigned width;			/* Width of an element (bytes) */
Xint	(*compar)();		/* Comparison function */
X{
X    int doublewidth = width + width;
X
X    char *last = base + width * (nel - 1);
X
X    while (last >= base)
X    {
X	register char *p = base + width * ((last - base)/doublewidth);
X	register int cmp = (*compar)(key, p);
X
X	if (cmp == 0)
X	    return (p);			/* aha, we found it! */
X	if (cmp < 0)
X	    last = p - width;
X	else
X	    base = p + width;
X    }
X    return ((char *) 0);		/* didn't find it */
X}
END_OF_bsearch.c
if test 897 -ne `wc -c <bsearch.c`; then
    echo shar: \"bsearch.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f closedir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"closedir.c\"
else
echo shar: Extracting \"closedir.c\" \(568 characters\)
sed "s/^X//" >closedir.c <<'END_OF_closedir.c'
X/*
X	closedir -- close a directory stream
X
X	last edit:	25-Apr-1987	D A Gwyn
X*/
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#include	<dirent.h>
X
Xtypedef char	*pointer;		/* (void *) if you have it */
X
Xextern void	free();
Xextern int	close();
X
Xextern int	errno;
X
X#ifndef NULL
X#define	NULL	0
X#endif
X
Xint
Xclosedir( dirp )
X	register DIR	*dirp;		/* stream from opendir() */
X	{
X	if ( dirp == NULL || dirp->dd_buf == NULL )
X		{
X		errno = EFAULT;
X		return -1;		/* invalid pointer */
X		}
X
X	free( (pointer)dirp->dd_buf );
X	free( (pointer)dirp );
X	return close( dirp->dd_fd );
X	}
END_OF_closedir.c
if test 568 -ne `wc -c <closedir.c`; then
    echo shar: \"closedir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dirent.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dirent.h\"
else
echo shar: Extracting \"dirent.h\" \(730 characters\)
sed "s/^X//" >dirent.h <<'END_OF_dirent.h'
X/*
X	<dirent.h> -- definitions for SVR3 directory access routines
X
X	last edit:	25-Apr-1987	D A Gwyn
X
X	Prerequisite:	<sys/types.h>
X*/
X
X#include	"sys/dirent.h"
X
X#define	DIRBUF		8192		/* buffer size for fs-indep. dirs */
X	/* must in general be larger than the filesystem buffer size */
X
Xtypedef struct
X	{
X	int	dd_fd;			/* file descriptor */
X	int	dd_loc;			/* offset in block */
X	int	dd_size;		/* amount of valid data */
X	char	*dd_buf;		/* -> directory block */
X	}	DIR;			/* stream data from opendir() */
X
Xextern DIR		*opendir();
Xextern struct dirent	*readdir();
Xextern off_t		telldir();
Xextern void		seekdir();
Xextern void		rewinddir();
Xextern int		closedir();
X
X#ifndef NULL
X#define	NULL	0			/* DAG -- added for convenience */
X#endif
END_OF_dirent.h
if test 730 -ne `wc -c <dirent.h`; then
    echo shar: \"dirent.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f getopt.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"getopt.c\"
else
echo shar: Extracting \"getopt.c\" \(1223 characters\)
sed "s/^X//" >getopt.c <<'END_OF_getopt.c'
X/*
X * getopt - get option letter from argv
X *
X * Copyright (c) Henry Spencer.
X * Written by Henry Spencer.
X *
X */
X
X/*
X * changed index() calls to strchr() - darwin, oct 87.
X */
X
X#include <stdio.h>
X
Xchar	*optarg;	/* Global argument pointer. */
Xint	optind = 0;	/* Global argv index. */
X
Xstatic char	*scan = NULL;	/* Private scan pointer. */
X
Xextern char	*strchr();
X
Xint
Xgetopt(argc, argv, optstring)
Xint argc;
Xchar *argv[];
Xchar *optstring;
X{
X	register char c;
X	register char *place;
X
X	optarg = NULL;
X
X	if (scan == NULL || *scan == '\0') {
X		if (optind == 0)
X			optind++;
X	
X		if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
X			return(EOF);
X		if (strcmp(argv[optind], "--")==0) {
X			optind++;
X			return(EOF);
X		}
X	
X		scan = argv[optind]+1;
X		optind++;
X	}
X
X	c = *scan++;
X	place = strchr(optstring, c);
X
X	if (place == NULL || c == ':') {
X		(void) fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
X		return('?');
X	}
X
X	place++;
X	if (*place == ':') {
X		if (*scan != '\0') {
X			optarg = scan;
X			scan = NULL;
X		} else if (optind < argc) {
X			optarg = argv[optind];
X			optind++;
X		} else {
X			(void) fprintf(stderr,
X				"%s: -%c argument missing\n", argv[0], c);
X			return('?');
X		}
X	}
X
X	return(c);
X}
END_OF_getopt.c
if test 1223 -ne `wc -c <getopt.c`; then
    echo shar: \"getopt.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f lfind.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lfind.c\"
else
echo shar: Extracting \"lfind.c\" \(745 characters\)
sed "s/^X//" >lfind.c <<'END_OF_lfind.c'
X/*
X * Linear search algorithm, generalized from Knuth (6.1) Algorithm S.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X
Xextern char *memcpy();
X
Xchar *lfind(key, base, nelp, width, compar)
Xregister char * key;		/* key to be searched for */
Xregister char * base;		/* base of table */
Xunsigned *nelp;			/* char * to current table size */
Xunsigned width;			/* width of an element (bytes) */
Xint (*compar)();		/* ordering function */
X{
X    register char *next;
X
X    for (next = base + *nelp * width ; base < next; base += width)
X	if ((*compar)(key, base) == 0)
X	    return (base);	/* we found it! */
X    return (char *)(-1);	/* it's not there */
X}
X
X/* lfind.c ends here */
END_OF_lfind.c
if test 745 -ne `wc -c <lfind.c`; then
    echo shar: \"lfind.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f lsearch.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lsearch.c\"
else
echo shar: Extracting \"lsearch.c\" \(814 characters\)
sed "s/^X//" >lsearch.c <<'END_OF_lsearch.c'
X/*
X * Linear search algorithm, generalized from Knuth (6.1) Algorithm S.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X
Xchar *lsearch(key, base, nelp, width, compar)
Xregister char *key;		/* key to be searched for */
Xregister char *base;		/* base of table */
Xunsigned *nelp;			/* pointer to current table size */
Xunsigned width;			/* size of an element (chars) */
Xint (*compar)();		/* ordering function */
X{
X    register char *next;
X    extern char *memcpy();
X
X    for (next = base + *nelp * width ; base < next; base += width)
X	if ((*compar)(key, base) == 0)
X	    return (base);			/* we found it! */
X    ++*nelp;					/* key not found, add it */
X    return(memcpy(base, key, (int)width));	/* bump next ptr */
X}
X
X/* lsearch.c ends here */
END_OF_lsearch.c
if test 814 -ne `wc -c <lsearch.c`; then
    echo shar: \"lsearch.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memccpy.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memccpy.c\"
else
echo shar: Extracting \"memccpy.c\" \(470 characters\)
sed "s/^X//" >memccpy.c <<'END_OF_memccpy.c'
X/*
X * memccpy.c
X *
X * Copy no more than n bytes of t to s, stopping if char c is copied. Return
X * a pointer to the byte following character c, or NULL if c is not found
X * in the first n bytes.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
X
Xchar *memccpy(t, s, c, n)
Xregister char *t, *s;
Xregister int c, n;
X{
X    while (--n >= 0)
X	if ((*t++ = *s++) == c)
X	    return(t);
X    return(0);
X}
END_OF_memccpy.c
if test 470 -ne `wc -c <memccpy.c`; then
    echo shar: \"memccpy.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memchr.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memchr.c\"
else
echo shar: Extracting \"memchr.c\" \(400 characters\)
sed "s/^X//" >memchr.c <<'END_OF_memchr.c'
X/*
X * memchr.c
X *
X * Return address in 1st n chars of sp at which the character c appears;
X * NULL if not found; don't terminate at \0.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
X
Xchar *memchr(sp, c, n)
Xregister char *sp, c;
Xregister int n;
X{
X    while (--n >= 0)
X	if (*sp++ == c)
X	    return(--sp);
X    return(0);
X}
END_OF_memchr.c
if test 400 -ne `wc -c <memchr.c`; then
    echo shar: \"memchr.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memcmp.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memcmp.c\"
else
echo shar: Extracting \"memcmp.c\" \(533 characters\)
sed "s/^X//" >memcmp.c <<'END_OF_memcmp.c'
X/*
X * memcmp.c
X *
X * Compare n bytes using normal lexicographic ordering, so that if
X * sp1 is less than sp2 the result comes out negative, if sp1 == sp2 it
X * is zero, and if sp1 is greater than sp2 it is positive.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
X
Xint memcmp(sp1, sp2, n)
Xregister char *sp1, *sp2;
Xregister int n;
X{
X    int delta;
X
X    if (sp1 != sp2)
X	while (--n >= 0)
X	    if (delta = *sp1++ - *sp2++)
X		return(delta);
X    return(0);
X}
END_OF_memcmp.c
if test 533 -ne `wc -c <memcmp.c`; then
    echo shar: \"memcmp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memory.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memory.h\"
else
echo shar: Extracting \"memory.h\" \(110 characters\)
sed "s/^X//" >memory.h <<'END_OF_memory.h'
X/* memory.h -- memory-area library functions */
X
Xextern char
X	*memccpy(),
X	*memchr(),
X	*memcpy(),
X	*memset();
END_OF_memory.h
if test 110 -ne `wc -c <memory.h`; then
    echo shar: \"memory.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memset.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memset.c\"
else
echo shar: Extracting \"memset.c\" \(342 characters\)
sed "s/^X//" >memset.c <<'END_OF_memset.c'
X/*
X * Fill an array of n chars starting at sp with the character c.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
X
Xchar *memset(sp, c, n)
Xregister char *sp, c;
Xregister int n;
X{
X    register char *base = sp;
X
X    while (--n >= 0)
X	*sp++ = c;
X    return(base);
X}
END_OF_memset.c
if test 342 -ne `wc -c <memset.c`; then
    echo shar: \"memset.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mkdirtest.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mkdirtest.c\"
else
echo shar: Extracting \"mkdirtest.c\" \(885 characters\)
sed "s/^X//" >mkdirtest.c <<'END_OF_mkdirtest.c'
X/* mkdirtest.c -- test mkdir and rmdir functions */
X#include <stdio.h>
X#include <errno.h>
X
Xmain(argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X    int dstat, perms;
X    extern int errno;
X
X    if (strcmp(argv[1], "-d") == 0)
X    {
X	if ((dstat = rmdir(argv[2])) != 0)
X	    (void) fprintf(stderr,
X		    "mkdirtest: cannot rmdir %s: errno = %d\n",argv[1],errno);
X	exit(dstat);
X    }
X
X    /* give user a chance to set the umask before attempting a mkdir */
X    if (strncmp(argv[1], "-u", 2) == 0)
X    {
X	(void) sscanf(argv[1] + 2, "%o", &perms);
X	(void) fprintf(stderr, "mkdirtest: setting umask to %o\n", perms);
X	(void) umask(perms);
X	++argv; --argc;
X    }
X
X    if (argc > 2)
X	(void) sscanf(argv[2], "%o", &perms);
X    else
X	perms = 0777;
X
X    if (mkdir(argv[1], perms) == -1)
X	(void) fprintf(stderr, 
X		"mkdirtest: cannot mkdir %s: errno = %d\n", argv[1], errno);
X}
X
X/* mkdirtest.c ends here */
X
END_OF_mkdirtest.c
if test 885 -ne `wc -c <mkdirtest.c`; then
    echo shar: \"mkdirtest.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f posix.lint -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"posix.lint\"
else
echo shar: Extracting \"posix.lint\" \(663 characters\)
sed "s/^X//" >posix.lint <<'END_OF_posix.lint'
X/* POSIX library extensions */
Xint	lockf(fd, fn, sz) int fd, fn; long sz; {return 0;}
X/* DIRECTORY(3C) */
X#include <dirent.h>
Xint	getdents(f, b, n) int f; char *b; unsigned n; { return 0; }
Xint	closedir(p) DIR *p; { return 0; }
XDIR	*opendir(f) char *f; {return (DIR *)NULL;}
Xstruct dirent	*readdir(p) DIR *p; {return (struct dirent*)NULL;}
Xvoid	seekdir(p, l) DIR *p; long l; {}
Xlong	telldir(p) DIR *p; {return 1L;}
X/* MKDIR(3) */
Xint	mkdir(s, p) char *s; int p; {return (0);}
X/* RMDIR(3) */
Xint	rmdir(s) char *s; {return (0);}
X/* STRING(3C) */
Xchar *	strdup(a) char *a; { return (a); }
X/* MEMORY(3C) */
X/* RENAME(3) */
Xint	rename(s, t) char *s, *t; {return (0);}
END_OF_posix.lint
if test 663 -ne `wc -c <posix.lint`; then
    echo shar: \"posix.lint\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f putpwent.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"putpwent.3c\"
else
echo shar: Extracting \"putpwent.3c\" \(759 characters\)
sed "s/^X//" >putpwent.3c <<'END_OF_putpwent.3c'
X.TH PUTPWENT 3C "Standard Extension"
X.SH NAME
Xputpwent \- write password file entry
X.SH SYNOPSIS
X.B #include <pwd.h>
X.PP
X.B int putpwent (p, f)
X.br
X.B struct passwd \(**p;
X.br
X.B \s-1FILE\s+1 \(**f;
X.SH DESCRIPTION
X.I Putpwent
Xis the inverse of
X.IR getpwent (3C).
XGiven a pointer to a
Xpasswd
Xstructure created by
X.I getpwent
X(or
X.I getpwuid 
Xor
X.IR getpwnam ), 
X.I putpwent
Xwrites a line on the stream
X.IR f ,
Xwhich matches the format of
X.BR /etc/passwd .
X.SH DIAGNOSTICS
X.I Putpwent
Xreturns non-zero if an error was detected during its operation,
Xotherwise zero.
X.SH "SEE ALSO"
Xgetpwent(3C).
X.SH WARNING
XThe above routine uses \fB<stdio.h>\fP, which causes 
Xit to increase the size of programs,
Xnot otherwise using standard I/O, more
Xthan might be expected.
END_OF_putpwent.3c
if test 759 -ne `wc -c <putpwent.3c`; then
    echo shar: \"putpwent.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f putpwent.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"putpwent.c\"
else
echo shar: Extracting \"putpwent.c\" \(633 characters\)
sed "s/^X//" >putpwent.c <<'END_OF_putpwent.c'
X/*
X * putpwent.c -- write a password file entry
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X#include <stdio.h>
X#include <pwd.h>
X
Xint putpwent(pw, fp)
Xstruct passwd *pw;
XFILE *fp;
X{
X    (void) fprintf(fp, "%s:%s", pw->pw_name, pw->pw_passwd);
X#ifdef USG
X    if (pw->pw_age[0] != '\0')
X	(void) fprintf(fp, ",%s", pw->pw_age);
X#endif /* USG */
X    (void) fprintf(fp, ":%u:%u:%s:%s:%s",
X		   pw->pw_uid,
X		   pw->pw_gid,
X		   pw->pw_gecos,
X		   pw->pw_dir,
X		   pw->pw_shell);
X    (void) putc('\n', fp);
X    return(ferror(fp));
X}
X
X/* putpwent.c ends here */
END_OF_putpwent.c
if test 633 -ne `wc -c <putpwent.c`; then
    echo shar: \"putpwent.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f readdir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"readdir.c\"
else
echo shar: Extracting \"readdir.c\" \(991 characters\)
sed "s/^X//" >readdir.c <<'END_OF_readdir.c'
X/*
X	readdir -- read next entry from a directory stream
X
X	last edit:	25-Apr-1987	D A Gwyn
X*/
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#include	<dirent.h>
X
Xextern int	getdents();		/* SVR3 system call, or emulation */
X
Xextern int	errno;
X
X#ifndef NULL
X#define	NULL	0
X#endif
X
Xstruct dirent *
Xreaddir( dirp )
X	register DIR		*dirp;	/* stream from opendir() */
X	{
X	register struct dirent	*dp;	/* -> directory data */
X
X	if ( dirp == NULL || dirp->dd_buf == NULL )
X		{
X		errno = EFAULT;
X		return NULL;		/* invalid pointer */
X		}
X
X	do	{
X		if ( dirp->dd_loc >= dirp->dd_size )	/* empty or obsolete */
X			dirp->dd_loc = dirp->dd_size = 0;
X
X		if ( dirp->dd_size == 0	/* need to refill buffer */
X		  && (dirp->dd_size =
X			getdents( dirp->dd_fd, dirp->dd_buf, (unsigned)DIRBUF )
X		     ) <= 0
X		   )
X			return NULL;	/* EOF or error */
X
X		dp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc];
X		dirp->dd_loc += dp->d_reclen;
X		}
X	while ( dp->d_ino == 0L );	/* don't rely on getdents() */
X
X	return dp;
X	}
END_OF_readdir.c
if test 991 -ne `wc -c <readdir.c`; then
    echo shar: \"readdir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rename.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rename.c\"
else
echo shar: Extracting \"rename.c\" \(377 characters\)
sed "s/^X//" >rename.c <<'END_OF_rename.c'
X/* rename.c -- file renaming routine for systems without rename(2)
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/* LINTLIBRARY */
X
Xint rename(from,to)
Xregister char *from, *to;
X{
X    (void) unlink(to);
X    if (link(from, to) < 0)
X	return(-1);
X
X    (void) unlink(from);
X    return(0);
X}
X
X/* rename.c ends here */
END_OF_rename.c
if test 377 -ne `wc -c <rename.c`; then
    echo shar: \"rename.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rewinddir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rewinddir.c\"
else
echo shar: Extracting \"rewinddir.c\" \(746 characters\)
sed "s/^X//" >rewinddir.c <<'END_OF_rewinddir.c'
X/*
X	rewinddir -- rewind a directory stream
X
X	last edit:	25-Apr-1987	D A Gwyn
X
X	This is not simply a call to seekdir(), because seekdir()
X	will use the current buffer whenever possible and we need
X	rewinddir() to forget about buffered data.
X*/
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#include	<dirent.h>
X
Xextern off_t	lseek();
X
Xextern int	errno;
X
X#ifndef NULL
X#define	NULL	0
X#endif
X
X#ifndef SEEK_SET
X#define	SEEK_SET	0
X#endif
X
Xvoid
Xrewinddir( dirp )
X	register DIR		*dirp;	/* stream from opendir() */
X	{
X	if ( dirp == NULL || dirp->dd_buf == NULL )
X		{
X		errno = EFAULT;
X		return;			/* invalid pointer */
X		}
X
X	dirp->dd_loc = dirp->dd_size = 0;	/* invalidate buffer */
X	(void)lseek( dirp->dd_fd, (off_t)0, SEEK_SET );	/* may set errno */
X	}
END_OF_rewinddir.c
if test 746 -ne `wc -c <rewinddir.c`; then
    echo shar: \"rewinddir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rmdir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rmdir.c\"
else
echo shar: Extracting \"rmdir.c\" \(489 characters\)
sed "s/^X//" >rmdir.c <<'END_OF_rmdir.c'
X/* rmdir.c -- remove a directory.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
X
Xint rmdir(dir)
Xchar *dir;
X{
X    extern char *malloc();
X    char *path = malloc(strlen(dir) + 25);
X    int status;
X
X    if (path == (char *)0)
X	status = -1;
X    else
X    {
X	(void) sprintf(path, "/bin/rmdir %s 2>/dev/null", dir);
X	status = system(path);
X    }
X    (void) free(path);
X    return(status);
X}
X
X/* rmdir.c ends here */
END_OF_rmdir.c
if test 489 -ne `wc -c <rmdir.c`; then
    echo shar: \"rmdir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f search.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"search.h\"
else
echo shar: Extracting \"search.h\" \(259 characters\)
sed "s/^X//" >search.h <<'END_OF_search.h'
X/* search.h -- declarations for POSIX/SVID-compatible search functions */
X
X/* HSEARCH(3C) */
Xtypedef struct entry { char *key, *data; } ENTRY;
Xtypedef enum { FIND, ENTER } ACTION;
X
X/* TSEARCH(3C) */
Xtypedef enum { preorder, postorder, endorder, leaf } VISIT;
END_OF_search.h
if test 259 -ne `wc -c <search.h`; then
    echo shar: \"search.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ssignal.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"ssignal.c\"
else
echo shar: Extracting \"ssignal.c\" \(769 characters\)
sed "s/^X//" >ssignal.c <<'END_OF_ssignal.c'
X/*
X * ssignal -- user-settable software signals facility
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X#include <signal.h>
X
X#define SIGMAX 16
X
Xstatic int (*sigs[SIGMAX])();
X
Xint (*ssignal(sig, fn))()
Xregister int sig, (*fn)();
X{
X    register int (*oldfn)();
X
X    if(sig >= 1 && sig <= SIGMAX)
X    {
X	oldfn = sigs[sig - 1];
X	sigs[sig - 1] = fn;
X    }
X    else
X	oldfn = SIG_DFL;
X    return(oldfn);
X}
X
Xint gsignal(sig)
Xregister int sig;
X{
X    register int (*sigfn)();
X
X    if (sig < 1 || sig > SIGMAX || (sigfn = sigs[sig - 1]) == SIG_DFL)
X	return(0);
X    else if (sigfn == SIG_IGN)
X	return(1);
X    else
X    {
X	sigs[sig - 1] = SIG_DFL;
X	return((*sigfn)(sig));
X    }
X}
X
X/* ssignal.c ends here */
END_OF_ssignal.c
if test 769 -ne `wc -c <ssignal.c`; then
    echo shar: \"ssignal.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strchr.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strchr.c\"
else
echo shar: Extracting \"strchr.c\" \(355 characters\)
sed "s/^X//" >strchr.c <<'END_OF_strchr.c'
X/*
X * Local copy of strchr (a.k.a. index) for portability.
X * Totally public domain.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X
X#include <stdio.h>
X
Xchar *
Xstrchr(s, c)
Xchar *s, c;
X{
X    char *x = s;
X
X    while (*x != c)
X	if (*x == '\0')
X	    return(NULL);
X	else
X	    ++x;
X    return(x);
X}
X
END_OF_strchr.c
if test 355 -ne `wc -c <strchr.c`; then
    echo shar: \"strchr.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strcspn.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strcspn.c\"
else
echo shar: Extracting \"strcspn.c\" \(556 characters\)
sed "s/^X//" >strcspn.c <<'END_OF_strcspn.c'
X/*
X * strcspn - find length of initial segment of s1 consisting entirely
X * of characters not from s2
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X
Xint strcspn(s1, s2)
Xchar *s1, *s2;
X{
X    register char *scan1;
X    register char *scan2;
X    register int count;
X
X    count = 0;
X    for (scan1 = s1; *scan1 != '\0'; scan1++) {
X	for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
X	    if (*scan1 == *scan2++)
X		return(count);
X	count++;
X    }
X    return(count);
X}
X
X/* strcspn.c ends here */
END_OF_strcspn.c
if test 556 -ne `wc -c <strcspn.c`; then
    echo shar: \"strcspn.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strdup.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strdup.c\"
else
echo shar: Extracting \"strdup.c\" \(331 characters\)
sed "s/^X//" >strdup.c <<'END_OF_strdup.c'
X/* strdup.c -- duplicate string contents using malloc(3)
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X
Xchar
X*strdup(str)
Xchar *str;
X{
X	extern char *malloc(), *strcpy();
X
X	char	*copy = malloc(strlen(str) + 1);
X
X	return(strcpy(copy, str));
X}
X
X/* strdup.c ends here */
END_OF_strdup.c
if test 331 -ne `wc -c <strdup.c`; then
    echo shar: \"strdup.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f string.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"string.h\"
else
echo shar: Extracting \"string.h\" \(348 characters\)
sed "s/^X//" >string.h <<'END_OF_string.h'
X/* string.h -- POSIX/X3J11/SVID string and memory-handling declarations */
X
Xextern char *strcpy(), *strncpy(), *strcat(), *strncat();
Xextern char *strchr(), *strrchr(), *strpbrk(), *strtok();
Xextern int strcmp(), strncmp(), strlen(), strspn(), strcspn(), memcmp();
Xextern char *memcpy(), *memccpy(), *memchr(), *memset();
X
X/* string.h ends here */
END_OF_string.h
if test 348 -ne `wc -c <string.h`; then
    echo shar: \"string.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strpbrk.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strpbrk.c\"
else
echo shar: Extracting \"strpbrk.c\" \(1342 characters\)
sed "s/^X//" >strpbrk.c <<'END_OF_strpbrk.c'
X/* strpbrk.c -- return ptr to 1st instance of any char in arg 2 within arg 1
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/* LINTLIBRARY */
X
Xchar *
Xstrpbrk(str, chars)
Xregister char *str, *chars;
X{
X	register char *cp;
X
X	do {
X		cp = chars - 1;
X		while (*++cp) {
X			if (*str == *cp)
X				return str;
X		}
X	} while
X	    (*str++);
X	return (char *)0;
X}
X
X/**************************************************************************
X
XIf you happen to be a 3b2, 3b5, 3b10, or 3b15 (but not a 3b1!) you can use this
X
X	.file	"strpbrk.u3b"	# think of this line as an offering to the gods
X
X# char *strpbrk(s1, s2)  char *s1, *s2;
X# Finds first occurance in s1 of a character in s2.
X
X	.text
X	.globl	strpbrk
X	.align	4
Xstrpbrk:
X	save	&2			# save r7 and r8
X	movw	0(%ap), %r0		# r0 = s1
X	movw	4(%ap), %r8		# r8 = s2
X	movw	&0, %r2			# string termination character
X	jmp	L2
XL1:					# while (*s1 != '\0') {
X	  movw	  %r8, %r7		#   get s2
X	  locce	  %r7, %r1, %r2		#   strchr(s2, *s1)
X	  je	  L4			#   if found, return
X	  addw2	  &1, %r0		#   increment s1
XL2:	  movb	  0(%r0), %r1		#   get *s1
X	  jne	  L1			#   loop if not at end of string
X	movw	&0, %r0			# set s1 to NULL
XL4:	ret	&2			# and return s1
X**************************************************************************/
X/* strpbrk.c ends here */
END_OF_strpbrk.c
if test 1342 -ne `wc -c <strpbrk.c`; then
    echo shar: \"strpbrk.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strrchr.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strrchr.c\"
else
echo shar: Extracting \"strrchr.c\" \(381 characters\)
sed "s/^X//" >strrchr.c <<'END_OF_strrchr.c'
X/*
X * Return ptr in sp at which the character c last appears, or
X * NULL if not found
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
X
Xchar *strrchr(sp, c)
Xregister char *sp, c;
X{
X    register char *rp;
X
X    rp = (char *)0;
X    do {
X	if (*sp == c)
X	    rp = sp;
X	} while
X	    (*sp++);
X    return(rp);
X}
END_OF_strrchr.c
if test 381 -ne `wc -c <strrchr.c`; then
    echo shar: \"strrchr.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strspn.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strspn.c\"
else
echo shar: Extracting \"strspn.c\" \(526 characters\)
sed "s/^X//" >strspn.c <<'END_OF_strspn.c'
X/*
X * strspn - find length of initial segment of s1 consisting entirely
X * of characters from s2
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X
Xint
Xstrspn(s1, s2)
Xchar *s1;
Xchar *s2;
X{
X	register char *scan1;
X	register char *scan2;
X	register int count;
X
X	count = 0;
X	for (scan1 = s1; *scan1 != '\0'; scan1++) {
X		for (scan2 = s2; *scan2 != '\0'; scan2++)
X			if (*scan1 == *scan2)
X				break;
X		if (*scan2 == '\0')
X			return(count);
X		count++;
X	}
X	return(count);
X}
END_OF_strspn.c
if test 526 -ne `wc -c <strspn.c`; then
    echo shar: \"strspn.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strtok.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strtok.c\"
else
echo shar: Extracting \"strtok.c\" \(1333 characters\)
sed "s/^X//" >strtok.c <<'END_OF_strtok.c'
X/* strtok.c -- return tokens from a string, NULL if no token left */
X/* LINTLIBRARY */
X
X/*
X * Get next token from string s1 (NULL on 2nd, 3rd, etc. calls),
X * where tokens are nonempty strings separated by runs of
X * chars from s2.  Writes NULs into s1 to end tokens.  s2 need not
X * remain constant from call to call.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X
X#define	NULL	0
X
Xchar *
Xstrtok(s1, s2)
Xchar *s1;
Xregister char *s2;
X{
X	register char *scan;
X	char *tok;
X	register char *scan2;
X	static char *scanpoint = (char *)NULL;
X
X	if (s1 == (char *)NULL && scanpoint == (char *)NULL)
X		return((char *)NULL);
X	if (s1 != (char *)NULL)
X		scan = s1;
X	else
X		scan = scanpoint;
X
X	/*
X	 * Scan leading delimiters.
X	 */
X	for (; *scan != '\0'; scan++) {
X		for (scan2 = s2; *scan2 != '\0'; scan2++)
X			if (*scan == *scan2)
X				break;
X		if (*scan2 == '\0')
X			break;
X	}
X	if (*scan == '\0') {
X		scanpoint = (char *)NULL;
X		return((char *)NULL);
X	}
X
X	tok = scan;
X
X	/*
X	 * Scan token.
X	 */
X	for (; *scan != '\0'; scan++) {
X		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
X			if (*scan == *scan2++) {
X				scanpoint = scan+1;
X				*scan = '\0';
X				return(tok);
X			}
X	}
X
X	/*
X	 * Reached end of string.
X	 */
X	scanpoint = (char *)NULL;
X	return(tok);
X}
X
X/* strtok.c ends here */
END_OF_strtok.c
if test 1333 -ne `wc -c <strtok.c`; then
    echo shar: \"strtok.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sys.dirent.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sys.dirent.h\"
else
echo shar: Extracting \"sys.dirent.h\" \(1311 characters\)
sed "s/^X//" >sys.dirent.h <<'END_OF_sys.dirent.h'
X/*
X	<sys/dirent.h> -- file system independent directory entry (SVR3)
X
X	last edit:	13-Oct-1987	D A Gwyn
X
X	prerequisite:	<sys/types.h>
X*/
X
Xstruct dirent				/* data from getdents()/readdir() */
X	{
X	long		d_ino;		/* inode number of entry */
X	off_t		d_off;		/* offset of disk directory entry */
X	unsigned short	d_reclen;	/* length of this record */
X	char		d_name[1];	/* name of file */	/* non-POSIX */
X	};
X
X#ifdef BSD_SYSV				/* (e.g., when compiling getdents.c) */
Xextern struct dirent	__dirent;	/* (not actually used) */
X/* The following is portable, although rather silly. */
X#define	DIRENTBASESIZ		(__dirent.d_name - (char *)&__dirent.d_ino)
X
X#else
X/* The following nonportable ugliness could have been avoided by defining
X   DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments.
X   There shouldn't be any problem if you avoid using the DIRENTSIZ() macro. */
X
X#define	DIRENTBASESIZ		(((struct dirent *)0)->d_name \
X				- (char *)&((struct dirent *)0)->d_ino)
X#endif
X
X#define	DIRENTSIZ( namlen )	((DIRENTBASESIZ + sizeof(long) + (namlen)) \
X				/ sizeof(long) * sizeof(long))
X
X/* DAG -- the following was moved from <dirent.h>, which was the wrong place */
X#define	MAXNAMLEN	512		/* maximum filename length */
X
X#ifndef NAME_MAX
X#define	NAME_MAX	(MAXNAMLEN - 1)	/* DAG -- added for POSIX */
X#endif
END_OF_sys.dirent.h
if test 1311 -ne `wc -c <sys.dirent.h`; then
    echo shar: \"sys.dirent.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f telldir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"telldir.c\"
else
echo shar: Extracting \"telldir.c\" \(794 characters\)
sed "s/^X//" >telldir.c <<'END_OF_telldir.c'
X/*
X	telldir -- report directory stream position
X
X	last edit:	25-Apr-1987	D A Gwyn
X
X	NOTE:	4.nBSD directory compaction makes seekdir() & telldir()
X		practically impossible to do right.  Avoid using them!
X*/
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#include	<dirent.h>
X
Xextern off_t	lseek();
X
Xextern int	errno;
X
X#ifndef SEEK_CUR
X#define	SEEK_CUR	1
X#endif
X
Xoff_t
Xtelldir( dirp )				/* return offset of next entry */
X	DIR	*dirp;			/* stream from opendir() */
X	{
X	if ( dirp == NULL || dirp->dd_buf == NULL )
X		{
X		errno = EFAULT;
X		return -1;		/* invalid pointer */
X		}
X
X	if ( dirp->dd_loc < dirp->dd_size )	/* valid index */
X		return ((struct dirent *)&dirp->dd_buf[dirp->dd_loc])->d_off;
X	else				/* beginning of next directory block */
X		return lseek( dirp->dd_fd, (off_t)0, SEEK_CUR );
X	}
END_OF_telldir.c
if test 794 -ne `wc -c <telldir.c`; then
    echo shar: \"telldir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f testdir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"testdir.c\"
else
echo shar: Extracting \"testdir.c\" \(837 characters\)
sed "s/^X//" >testdir.c <<'END_OF_testdir.c'
X/*
X	testdir -- basic test for C library directory access routines
X
X	last edit:	25-Apr-1987	D A Gwyn
X*/
X
X#include	<sys/types.h>
X#include	<stdio.h>
X#include	<dirent.h>
X
Xextern void	exit();
Xextern int	strcmp();
X
Xmain( argc, argv )
X	int			argc;
X	register char		**argv;
X	{
X	register DIR		*dirp;
X	register struct dirent	*dp;
X	int			nerrs = 0;	/* total not found */
X
X	if ( (dirp = opendir( "." )) == NULL )
X		{
X		(void)fprintf( stderr, "Cannot open \".\" directory\n" );
X		exit( 1 );
X		}
X
X	while ( --argc > 0 )
X		{
X		++argv;
X
X		while ( (dp = readdir( dirp )) != NULL )
X			if ( strcmp( dp->d_name, *argv ) == 0 )
X				{
X				(void)printf( "\"%s\" found.\n", *argv );
X				break;
X				}
X
X		if ( dp == NULL )
X			{
X			(void)printf( "\"%s\" not found.\n", *argv );
X			++nerrs;
X			}
X
X		rewinddir( dirp );
X		}
X
X	(void)closedir( dirp );
X	exit( nerrs );
X	}
END_OF_testdir.c
if test 837 -ne `wc -c <testdir.c`; then
    echo shar: \"testdir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tfind.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tfind.c\"
else
echo shar: Extracting \"tfind.c\" \(983 characters\)
sed "s/^X//" >tfind.c <<'END_OF_tfind.c'
X/*
X * Tree search generalized from Knuth (6.2.2) Algorithm T just like
X * the AT&T man page says.
X *
X * The node_t structure is for internal use only, lint doesn't grok it.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X#include <search.h>
X
Xtypedef struct node_t
X{
X    char	  *key;
X    struct node_t *llink, *rlink;
X} node;
X
Xnode *tfind(key, rootp, compar)
X/* find a node, or return 0 */
Xchar		*key;		/* key to be found */
Xregister node	**rootp;	/* address of the tree root */
Xint		(*compar)();	/* ordering function */
X{
X    if (rootp == (struct node_t **)0)
X	return ((struct node_t *)0);
X    while (*rootp != (struct node_t *)0)	/* T1: */
X    {
X	int r;
X	if ((r = (*compar)(key, (*rootp)->key)) == 0)	/* T2: */
X	    return (*rootp);		/* key found */
X	rootp = (r < 0) ?
X	    &(*rootp)->llink :		/* T3: follow left branch */
X	    &(*rootp)->rlink;		/* T4: follow right branch */
X    }
X    return (node *)0;
X}
END_OF_tfind.c
if test 983 -ne `wc -c <tfind.c`; then
    echo shar: \"tfind.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f unistd.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"unistd.h\"
else
echo shar: Extracting \"unistd.h\" \(1088 characters\)
sed "s/^X//" >unistd.h <<'END_OF_unistd.h'
X/* unistd.h -- symbolic constands for POSIX conformance */
X
X#ifndef R_OK	/* 4.2BSD may have got these from /usr/include/sys/file.h */
X
X/* Symbolic constants for the "access" routine: */
X#define	R_OK	4	/* Test for Read permission */
X#define	W_OK	2	/* Test for Write permission */
X#define	X_OK	1	/* Test for eXecute permission */
X#define	F_OK	0	/* Test for existence of File */
X
X#endif /* R_OK */
X
X#ifndef F_ULOCK
X
X#define F_ULOCK	0	/* Unlock a previously locked region */
X#define F_LOCK	1	/* Lock a region for exclusive use */
X#define F_TLOCK	2	/* Test and lock a region for exclusive use */
X#define F_TEST	3	/* Test a region for other processes locks */
X
X#endif /* F_ULOCK */
X
X/* Symbolic constants for the "lseek" routine: */
X#define	SEEK_SET	0	/* Set file pointer to "offset" */
X#define	SEEK_CUR	1	/* Set file pointer to current plus "offset" */
X#define	SEEK_END	2	/* Set file pointer to EOF plus "offset" */
X
X/* Path names: */
X#define	GF_PATH	"/etc/group"	/* Path name of the "group" file */
X#define	PF_PATH	"/etc/passwd"	/* Path name of the "passwd" file */
X
X/* unistd.h ends here */
END_OF_unistd.h
if test 1088 -ne `wc -c <unistd.h`; then
    echo shar: \"unistd.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 5\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 589-7930
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny     attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752

lenny@icus.islp.ny.us (Lenny Tropiano) (08/03/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 5)."
# Contents:  dirent.4 getdents.2 lsearch.3c memcpy.c memory.3c mkdir.3
#   opendir.c rename.3 rmdir.3 seekdir.c ssignal.3c strtol.3c strtol.c
#   sys._dir.h
# Wrapped by lenny@icus on Wed Aug  2 21:40:25 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f dirent.4 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dirent.4\"
else
echo shar: Extracting \"dirent.4\" \(1593 characters\)
sed "s/^X//" >dirent.4 <<'END_OF_dirent.4'
X.TH DIRENT 4 "Standard Extension"
X.SH NAME
Xdirent \- file system independent directory entry
X.SH SYNOPSIS
X.B "#include <sys/types.h>"
X.br
X.B "#include <sys/dirent.h>"
X.SH DESCRIPTION
XDifferent file system types
Xmay have different directory entries.
XThe
X.I dirent
Xstructure defines a
Xfile system independent directory entry,
Xwhich contains information common to
Xdirectory entries in different file system types.
XA set of these structures is returned by the
X.IR getdents (2)
Xsystem call.
X.P
XThe
X.I dirent
Xstructure is defined below.
X.br
Xstruct	dirent	{
X.br
X			long			d_ino;
X.br
X			off_t			d_off;
X.br
X			unsigned short		d_reclen;
X.br
X			char			d_name[1];
X.br
X		};
X.P
XThe field
X.I d_ino
Xis a number which is unique
Xfor each file in the file system.
XThe field
X.I d_off\^
Xrepresents an offset of that directory entry
Xin the actual file system directory.
XThe field
X.I d_name
Xis the beginning of the character array
Xgiving the name of the directory entry.
XThis name is null terminated
Xand may have at most
X.SM NAME_MAX
Xcharacters in addition to the null terminator.
XThis results in file system independent directory entries
Xbeing variable-length entities.
XThe value of
X.I d_reclen
Xis the record length of this entry.
XThis length is defined to be the number of bytes
Xbetween the beginning of the current entry and the next one,
Xadjusted so that the next entry
Xwill start on a long boundary.
X.SH FILES
X/usr/include/sys/dirent.h
X.SH "SEE ALSO"
Xgetdents(2).
X.SH WARNING
XThe field
X.I d_off\^
Xdoes not have a simple interpretation
Xfor some file system types
Xand should not be used directly by applications.
END_OF_dirent.4
if test 1593 -ne `wc -c <dirent.4`; then
    echo shar: \"dirent.4\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f getdents.2 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"getdents.2\"
else
echo shar: Extracting \"getdents.2\" \(1922 characters\)
sed "s/^X//" >getdents.2 <<'END_OF_getdents.2'
X.TH GETDENTS 2 "Standard Extension"
X.SH NAME
Xgetdents \- get directory entries in a file system independent format
X.SH SYNOPSIS
X.B "#include <sys/types.h>"
X.br
X.B "#include <sys/dirent.h>"
X.P
X.B "int getdents (fildes, buf, nbyte)"
X.br
X.B "int fildes;"
X.br
X.B "char \(**buf;"
X.br
X.B "unsigned nbyte;"
X.SH DESCRIPTION
X.I Fildes
Xis a file descriptor obtained from an
X.IR open (2)
Xor
X.IR dup (2)
Xsystem call.
X.P
X.I Getdents
Xattempts to read
X.I nbyte
Xbytes from the directory associated with
X.I fildes
Xand to format them as
Xfile system independent entries
Xin the buffer pointed to by
X.IR buf .
XSince the file system independent directory entries
Xare of variable length,
Xin most cases the actual number of bytes returned
Xwill be less than
X.IR nbyte .
X.P
XThe file system independent directory entry is specified by the
X.I dirent
Xstructure.
XFor a description of this see
X.IR dirent (4).
X.P
XOn devices capable of seeking,
X.I getdents
Xstarts at a position in the file given by
Xthe file pointer associated with
X.IR fildes .
XUpon return from
X.IR getdents ,
Xthe file pointer has been incremented
Xto point to the next directory entry.
X.P
XThis system call was developed in order to implement the
X.I readdir
Xroutine
X[for a description see
X.IR directory (3C)]
Xand should not be used for other purposes.
X.SH "SEE ALSO"
Xdirectory(3C), dirent(4).
X.SH DIAGNOSTICS
XUpon successful completion
Xa non-negative integer is returned
Xindicating the number of bytes of
X.I buf\^
Xactually filled.
X(This need not be the number actually used
Xin the actual directory file.)\|\|
XA value of zero
Xindicates the end of the directory has been reached.
XIf
X.I getdents
Xfails for any other reason,
Xa value of \-1 is returned and
Xthe external integer variable
X.I errno
Xis set to indicate the error.
X.SH WARNINGS
XEntries for "." and ".."
Xmay not be reported for some file system types.
X.P
XThe exact set of
X.I errno
Xvalues and meanings may vary among implementations.
END_OF_getdents.2
if test 1922 -ne `wc -c <getdents.2`; then
    echo shar: \"getdents.2\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f lsearch.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"lsearch.3c\"
else
echo shar: Extracting \"lsearch.3c\" \(2671 characters\)
sed "s/^X//" >lsearch.3c <<'END_OF_lsearch.3c'
X.TH LSEARCH 3C "Standard extension"
X.SH NAME
Xlsearch, lfind \- linear search and update
X.SH SYNOPSIS
X.B #include <stdio.h>
X.br
X.B #include <search.h>
X.PP
X.B "char \(**lsearch ((char \(**)key, (char \(**)base, nelp, sizeof(\(**key), compar)"
X.br
X.B unsigned \(**nelp;
X.br
X.B int (\(**compar)( );
X.PP
X.B "char \(**lfind ((char \(**)key, (char \(**)base, nelp, sizeof(\(**key), compar)"
X.br
X.B unsigned \(**nelp;
X.br
X.B int (\(**compar)( );
X.SH DESCRIPTION
X.I Lsearch
Xis a linear search routine generalized from Knuth (6.1) Algorithm S.
XIt returns a pointer into a table indicating where
Xa datum may be found.
XIf the datum does not occur, it is added
Xat the end of the table.
X.B Key
Xpoints to the datum to be sought in the table.
X.B Base
Xpoints to the first element in the table.
X.B Nelp
Xpoints to an integer containing the current number of 
Xelements in the table.
XThe integer is incremented if the datum is added to the table.
X.B Compar
Xis the name of the comparison function which the user must supply
X.RI ( strcmp ,
Xfor example).
XIt is called with two arguments that point
Xto the elements being compared.
XThe function must return zero if the elements
Xare equal and non-zero otherwise.
X.PP
X.I Lfind
Xis the same as 
X.I lsearch
Xexcept that if the datum is not found, it is not added
Xto the table. 
XInstead, a 
X.SM NULL
Xpointer is returned.
X.SH NOTES
XThe pointers to the key and the element
Xat the base of the table should be
Xof type pointer-to-element,
Xand cast to type pointer-to-character.
X.br
XThe comparison function need not compare every byte,
Xso arbitrary data may be contained in the elements
Xin addition to the values being compared.
X.br
XAlthough declared as type pointer-to-character,
Xthe value returned should be cast into type pointer-to-element.
X.SH EXAMPLE
XThis fragment will read in \(<= \s-1TABSIZE\s+1 
Xstrings of length \(<= \s-1ELSIZE\s+1
Xand store them in a table, eliminating duplicates.
X.PP
X.RS
X.nf
X.ss 18
X#include <stdio.h>
X#include <search.h>
X
X#define \s-1TABSIZE\s+1 50
X#define \s-1ELSIZE\s+1 120
X
X	char line[\s-1ELSIZE\s+1], tab[\s-1TABSIZE\s+1][\s-1ELSIZE\s+1], \(**lsearch( );
X	unsigned nel = 0;
X	int strcmp( );
X	. . .
X	while (fgets(line, \s-1ELSIZE\s+1, stdin) != \s-1NULL\s+1 &&
X	   nel < \s-1TABSIZE\s+1)
X		(void) lsearch(line, (char \(**)tab, &nel,
X			  \s-1ELSIZE\s+1, strcmp);
X	. . .
X.fi
X.SH SEE ALSO
Xbsearch(3C), hsearch(3C), tsearch(3C).
X.SH DIAGNOSTICS
XIf the searched for datum is found, both 
X.I lsearch
Xand 
X.I lfind
Xreturn a pointer
Xto it.
XOtherwise, 
X.I lfind
Xreturns NULL and 
X.I lsearch
Xreturns a pointer to the newly
Xadded element.
X.SH BUGS
XUndefined results can occur if there is not enough room in the table to
Xadd a new item.
END_OF_lsearch.3c
if test 2671 -ne `wc -c <lsearch.3c`; then
    echo shar: \"lsearch.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memcpy.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memcpy.c\"
else
echo shar: Extracting \"memcpy.c\" \(2473 characters\)
sed "s/^X//" >memcpy.c <<'END_OF_memcpy.c'
X/*
X * Copy first n bytes of s to t, return t
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X */
X/*LINTLIBRARY*/
Xchar *memcpy(t, s, n)
Xregister char *t, *s;
Xregister int n;
X{
X    register char *os = t;
X
X    while (--n >= 0)
X	*t++ = *s++;
X    return(os);
X}
X
X/**************************************************************************
X
XIf you happen to be using a PDP-11, you can use this assembler version...
X
X/ MEMCPY(TO, FROM, N)  CHAR *TO, *FROM;
X/
X/	Copy "n" bytes from "from" to "to".
X/
X.globl	_memcpy
X.globl	csav, cret
X
X.text
X_memcpy:	jsr  r0, csav		/ save registers
X	mov  r5, r4		/ get arguments...
X	cmp  (r4)+, (r4)+	/
X	mov  (r4)+, r1		/ to
X	mov  (r4)+, r0		/ from
X	mov  (r4), r2		/ byte count
X	beq  ret		/ if zero then return
X	bit  $1, r1		/ is "to" odd
X	beq  1f			/ yes...
X	  movb (r0)+, (r1)+	/   copy one byte to make it even
X	  dec  r2		/   and adjust byte count
X1:	mov  r2, r3		/ save (low bit of) count
X	asr  r2			/ convert from bytes to words
X	beq  3f			/ if any words to copy...
X	  bit  $1, r0		/   is "from" even now?
X	  beq  2f		/   if not ...
X1:	    movb (r0)+, (r1)+	/     copy bytes...
X	    movb (r0)+, (r1)+	/     ...
X	    sob  r2, 1b		/     ...
X	  br   3f		/   else ...
X2:	    mov  (r0)+, (r1)+	/     copy words...
X	    sob  r2, 2b		/     ...
X3:	ror  r3			/ is byte count odd?
X	bcc  ret		/ if so...
X	   movb (r0)+, (r1)+	/   copy odd byte.
Xret:	jmp  cret		/ return
X
XIf you happen to be a VAX, you can use this:
X
X# memcpy(to, from, count) char *to, *from; int count;
X#
X# Copy "count" bytes from "from" to "to"; not guaranteed to
X# work if "from" and "to" overlap.
X
X	.align	2
X	.globl	_memcpy
X_memcpy:
X	.word	0
X	movl	4(ap), r3		# r3 = to
X	movl	8(ap), r1		# r1 = from
XL1:
X	movzwl	$65535, r0		# while more than 65535 bytes to move
X	cmpl	12(ap), r0
X	jleq	L2			# if <= 65535, break
X	subl2	r0, 12(ap)		# count-=65535 (bytes moved this time)
X	movc3	r0, (r1), (r3)		# r1, r3 magically point to next 65K
X	brb	L1
XL2:
X	movc3	12(ap), (r1), (r3)	# move up to 65535 bytes
X	ret
X
XIf you happen to be a 3b2, 3b5, 3b10, or 3b15 (but not a 3b1!) you can use this
X
X	.file "memcpy.s"		# silly assembler wants this line
X	.globl	memcpy
X	.align	4
Xmemcpy:	save	&0		# set up stack frame
X	movw	0(%ap), %r1	# get source
X	movw	4(%ap), %r0	# and destination
X	movw	8(%ap), %r2	# get count
X	movblb			# this instruction does it all
X	ret	&0		# return
X
X**************************************************************************/
END_OF_memcpy.c
if test 2473 -ne `wc -c <memcpy.c`; then
    echo shar: \"memcpy.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f memory.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"memory.3c\"
else
echo shar: Extracting \"memory.3c\" \(2063 characters\)
sed "s/^X//" >memory.3c <<'END_OF_memory.3c'
X.TH MEMORY 3C "Standard Extension"
X.SH NAME
Xmemccpy, memchr, memcmp, memcpy, memset \- memory operations
X.SH SYNOPSIS
X.nf
X.B #include <memory.h>
X.PP
X.B char \(**memccpy (s1, s2, c, n)
X.B char \(**s1, \(**s2;
X.B int c, n;
X.PP
X.B char \(**memchr (s, c, n)
X.B char \(**s;
X.B int c, n;
X.PP
X.B int memcmp (s1, s2, n)
X.B char \(**s1, \(**s2;
X.B int n;
X.PP
X.B char \(**memcpy (s1, s2, n)
X.B char \(**s1, \(**s2;
X.B int n;
X.PP
X.B char \(**memset (s, c, n)
X.B char \(**s;
X.B int c, n;
X.fi
X.SH DESCRIPTION
XThese functions operate as efficiently as possible on memory areas (arrays of
Xcharacters bounded by a count, not necessarily terminated by a null character).
XThey do not check for overflow of any receiving memory area.
X.PP
X.I Memccpy
Xcopies characters from memory area
X.B s2
Xinto
X.BR s1 ,
Xstopping after the first occurrence of character
X.B c
Xhas been copied, or after
X.B n
Xcharacters have been copied, whichever comes first.
XIt returns a pointer to the character after
Xthe copy of
X.B c
Xin
X.BR s1 ,
Xor a
X.SM NULL
Xpointer if
X.B c
Xwas not found in the first
X.B n
Xcharacters of
X.BR s2 .
X.PP
X.PP
X.I Memchr
Xreturns a pointer to the first
Xoccurrence of character 
X.B c
Xin the first
X.B n
Xcharacters of memory area
X.BR s,
Xor a
X.SM NULL
Xpointer if
X.B c
Xdoes not occur.
X.PP
X.I Memcmp
Xcompares its arguments, looking at the first
X.B n
Xcharacters only, and returns an integer
Xless than, equal to, or greater than 0,
Xaccording as
X.B s1
Xis lexicographically less than, equal to, or
Xgreater than
X.BR s2 .
X.PP
X.I Memcpy
Xcopies
X.B n
Xcharacters from memory area
X.B s2
Xto
X.BR s1 .
XIt returns
X.BR s1 .
X.PP
X.I Memset
Xsets the first
X.B n
Xcharacters in memory area
X.B s
Xto the value of character
X.BR c .
XIt returns
X.BR s .
X.SH NOTE
XAll these functions are declared in the optional
X.I <memory.h>
Xheader file.
X.SH BUGS
X.I Memcmp
Xuses native character comparison, which may be signed or unsigned.
XThus the sign of the value returned when one of the characters has its
Xhigh-order bit set is implementation-dependent.
X.PP
XOverlapping moves may scramble the data in both source and target areas.
END_OF_memory.3c
if test 2063 -ne `wc -c <memory.3c`; then
    echo shar: \"memory.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mkdir.3 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mkdir.3\"
else
echo shar: Extracting \"mkdir.3\" \(2107 characters\)
sed "s/^X//" >mkdir.3 <<'END_OF_mkdir.3'
X.TH MKDIR 3 "Standard Extension"
X.SH NAME
Xmkdir \- make a directory file
X.SH SYNOPSIS
X.nf
X.ft B
Xmkdir(path, mode)
Xchar *path;
Xint mode;
X.fi
X.ft R
X.SH DESCRIPTION
X.I Mkdir
Xcreates a new directory file with name
X.IR path .
XThe mode of the new file
Xis initialized from
X.IR mode .
X(The protection part of the mode
Xis modified by the process's mode mask; see
X.IR umask (2)).
X.PP
XThe directory's owner ID is set to the process's effective user ID.
XThe directory's group ID is set to the process's effective group ID.
X.PP
XThe low-order 9 bits of mode are modified by the process's
Xfile mode creation mask: all bits set in the process's file mode
Xcreation mask are cleared.  See
X.IR umask (2).
X.SH NOTES
XThis function emulates the SVr3 behavior (group ID of the directory
Xis the effective group ID of the calling process) rather than the BSD
Xbehavior (group ID of the directory is the group ID of the parent directory).
X.PP
XOn USG it will succeed if the real or apparent uid of the calling process
Xhas write privileges in the current directory (the latter case is implemented
Xby a kluge that tries to set the parent directory's permissions to 0777, 'ware
Xsecurity holes!). The new directory will be owned by the effective uid.
X.PP
XOn V7 (because it restricts the chown(2) call and mkdir(1) makes
Xdirectories owned by the real ID of its caller) the call will only succeed
Xif the real ID matches, and the new directory will be owned by the real
Xuid.
X.PP
XThe overhead of this emulation is fairly high, requiring a fork/exec (on AT&T
Xversions, two fork-execs).
X.SH "RETURN VALUE
XA 0 return value indicates success.  A \-1 return value
Xindicates an error, and an error code is stored in
X.I errno.
X.SH "ERRORS
X.I Mkdir
Xwill fail and no directory will be created if:
X[ENOTDIR]
XA component of the path prefix is not a directory.
X.TP 15
X[ENOENT]
XA component of the path prefix does not exist.
X.TP 15
X[EEXIST]
XThe named file exists.
X.TP 15
X[EACCES]
XA component of the path prefix denies search permission, or write permission
Xis denied on the parent of the directory to be created.
X.SH "SEE ALSO"
Xchmod(2), stat(2), umask(2)
END_OF_mkdir.3
if test 2107 -ne `wc -c <mkdir.3`; then
    echo shar: \"mkdir.3\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f opendir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"opendir.c\"
else
echo shar: Extracting \"opendir.c\" \(1473 characters\)
sed "s/^X//" >opendir.c <<'END_OF_opendir.c'
X/*
X	opendir -- open a directory stream
X
X	last edit:	16-Jun-1987	D A Gwyn
X*/
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#include	<sys/stat.h>
X#include	<dirent.h>
X
X#ifdef BSD_SYSV
X#define open	_open			/* avoid emulation overhead */
X#endif
X
Xtypedef char	*pointer;		/* (void *) if you have it */
X
Xextern void	free();
Xextern pointer	malloc();
Xextern int	open(), close(), fstat();
X
Xextern int	errno;
X
X#ifndef NULL
X#define	NULL	0
X#endif
X
X#ifndef O_RDONLY
X#define	O_RDONLY	0
X#endif
X
X#ifndef S_ISDIR				/* macro to test for directory file */
X#define	S_ISDIR( mode )		(((mode) & S_IFMT) == S_IFDIR)
X#endif
X
XDIR *
Xopendir( dirname )
X	char		*dirname;	/* name of directory */
X	{
X	register DIR	*dirp;		/* -> malloc'ed storage */
X	register int	fd;		/* file descriptor for read */
X	struct stat	sbuf;		/* result of fstat() */
X
X	if ( (fd = open( dirname, O_RDONLY )) < 0 )
X		return NULL;		/* errno set by open() */
X
X	if ( fstat( fd, &sbuf ) != 0 || !S_ISDIR( sbuf.st_mode ) )
X		{
X		(void)close( fd );
X		errno = ENOTDIR;
X		return NULL;		/* not a directory */
X		}
X
X	if ( (dirp = (DIR *)malloc( sizeof(DIR) )) == NULL
X	  || (dirp->dd_buf = (char *)malloc( (unsigned)DIRBUF )) == NULL
X	   )	{
X		register int	serrno = errno;
X					/* errno set to ENOMEM by sbrk() */
X
X		if ( dirp != NULL )
X			free( (pointer)dirp );
X
X		(void)close( fd );
X		errno = serrno;
X		return NULL;		/* not enough memory */
X		}
X
X	dirp->dd_fd = fd;
X	dirp->dd_loc = dirp->dd_size = 0;	/* refill needed */
X
X	return dirp;
X	}
END_OF_opendir.c
if test 1473 -ne `wc -c <opendir.c`; then
    echo shar: \"opendir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rename.3 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rename.3\"
else
echo shar: Extracting \"rename.3\" \(2283 characters\)
sed "s/^X//" >rename.3 <<'END_OF_rename.3'
X.TH RENAME 3 "Standard Extension"
X.SH NAME
Xrename \- change the name of a file
X.SH SYNOPSIS
X.ft B
X.nf
Xrename(from, to)
Xchar *from, *to;
X.fi
X.ft R
X.SH DESCRIPTION
X.I Rename
Xcauses the link named
X.I from
Xto be renamed as
X.IR to .
XIf 
X.I to
Xexists, then it is first removed.
XBoth 
X.I from
Xand
X.I to
Xmust be of the same type (i.e., both directories or both
Xnon-directories), and must reside on the same file system.
X.PP
X.I Rename
Xguarantees that an instance of
X.I to
Xwill always exist, even if the system should crash in
Xthe middle of the operation.
X.SH CAVEAT
XThe system can deadlock if a loop in the file system graph is present.
XThis loop takes the form of an entry in directory \*(lqa\*(rq,
Xsay \*(lqa/foo\*(rq,
Xbeing a hard link to directory \*(lqb\*(rq, and an entry in
Xdirectory \*(lqb\*(rq, say \*(lqb/bar\*(rq, being a hard link
Xto directory \*(lqa\*(rq.
XWhen such a loop exists and two separate processes attempt to
Xperform \*(lqrename a/foo b/bar\*(rq and \*(lqrename b/bar a/foo\*(rq,
Xrespectively, 
Xthe system may deadlock attempting to lock
Xboth directories for modification.
XOn systems with a symbolic link capability, hard links to directories should be
Xreplaced by symbolic links by the system administrator.
X.SH "RETURN VALUE"
XA 0 value is returned if the operation succeeds, otherwise
X.I rename
Xreturns \-1 and the global variable
X.I errno
Xindicates the reason for the failure.
X.SH "ERRORS
X.I Rename
Xwill fail and nothing will change if any of the following are true:
X.TP 15
X[ENOTDIR]
XA component of either path prefix is not a directory.
X.TP 15
X[ENOENT]
XA component of either path prefix does not exist.
X.TP 15
X[EACCES]
XA component of either path prefix denies search permission.
X.TP 15
X[ENOENT]
XThe file named by \fIfrom\fP does not exist.
X.TP 15
X[EXDEV]
XThe link named by \fIto\fP and the file named by \fIfrom\fP
Xare on different logical devices (file systems).  Note that this error
Xcode will not be returned if the implementation permits cross-device
Xlinks.
X.TP 15
X[EACCES]
XThe requested link requires writing in a directory with a mode
Xthat denies write permission.
X.TP 15
X[EROFS]
XThe requested link requires writing in a directory on a read-only file
Xsystem.
X.TP 15
X[EFAULT]
X.I Path
Xpoints outside the process's allocated address space.
X.SH "SEE ALSO"
Xopen(2)
END_OF_rename.3
if test 2283 -ne `wc -c <rename.3`; then
    echo shar: \"rename.3\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rmdir.3 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rmdir.3\"
else
echo shar: Extracting \"rmdir.3\" \(1443 characters\)
sed "s/^X//" >rmdir.3 <<'END_OF_rmdir.3'
X.TH RMDIR 3 "Standard Extension"
X.SH NAME
Xrmdir \- remove a directory file
X.SH SYNOPSIS
X.nf
X.ft B
Xrmdir(path)
Xchar *path;
X.fi
X.ft R
X.SH DESCRIPTION
X.I Rmdir
Xremoves a directory file
Xwhose name is given by
X.I path.
XThe directory must not have any entries other
Xthan \*(lq.\*(rq and \*(lq..\*(rq.
X.SH "RETURN VALUE
XA 0 is returned if the remove succeeds; otherwise a \-1 is
Xreturned.
X.SH ERRORS
XThe named file is removed unless one or more of the
Xfollowing are true:
X.TP 15
X[ENOTEMPTY]
XThe named directory contains files other than ``.'' and ``..'' in it.
X.TP 15
X[EPERM]
XThe pathname contained a non-ASCII character.
X.TP 15
X[ENOENT]
XThe pathname was too long.
X.TP 15
X[ENOTDIR]
XA component of the path prefix is not a directory.
X.TP 15
X[ENOENT]
XThe named file does not exist.
X.TP 15
X[EACCES]
XA component of the path prefix denies search permission.
X.TP 15
X[EACCES]
XWrite permission is denied on the directory containing the link
Xto be removed.
X.TP 15
X[EBUSY]
XThe directory to be removed is the mount point
Xfor a mounted file system.
X.TP 15
X[EROFS]
XThe directory entry to be removed resides on a read-only file system.
X.TP 15
X[EFAULT]
X.I Path
Xpoints outside the process's allocated address space.
X.SH WARNING
XThis call is implemented via a spawn of /bin/rmdir. Its error return status
Xis therefore unreliable, and the value of errno after the call will not
Xtypically reflect the above error conditions properly.
X.SH "SEE ALSO"
Xmkdir(3), unlink(2)
END_OF_rmdir.3
if test 1443 -ne `wc -c <rmdir.3`; then
    echo shar: \"rmdir.3\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f seekdir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"seekdir.c\"
else
echo shar: Extracting \"seekdir.c\" \(2965 characters\)
sed "s/^X//" >seekdir.c <<'END_OF_seekdir.c'
X/*
X	seekdir -- reposition a directory stream
X
X	last edit:	24-May-1987	D A Gwyn
X
X	An unsuccessful seekdir() will in general alter the current
X	directory position; beware.
X
X	NOTE:	4.nBSD directory compaction makes seekdir() & telldir()
X		practically impossible to do right.  Avoid using them!
X*/
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#include	<dirent.h>
X
Xextern off_t	lseek();
X
Xextern int	errno;
X
X#ifndef NULL
X#define	NULL	0
X#endif
X
X#ifndef SEEK_SET
X#define	SEEK_SET	0
X#endif
X
Xtypedef int	bool;			/* Boolean data type */
X#define	false	0
X#define	true	1
X
Xvoid
Xseekdir( dirp, loc )
X	register DIR	*dirp;		/* stream from opendir() */
X	register off_t	loc;		/* position from telldir() */
X	{
X	register bool	rewind;		/* "start over when stymied" flag */
X
X	if ( dirp == NULL || dirp->dd_buf == NULL )
X		{
X		errno = EFAULT;
X		return;			/* invalid pointer */
X		}
X
X	/* A (struct dirent)'s d_off is an invented quantity on 4.nBSD
X	   NFS-supporting systems, so it is not safe to lseek() to it. */
X
X	/* Monotonicity of d_off is heavily exploited in the following. */
X
X	/* This algorithm is tuned for modest directory sizes.  For
X	   huge directories, it might be more efficient to read blocks
X	   until the first d_off is too large, then back up one block,
X	   or even to use binary search on the directory blocks.  I
X	   doubt that the extra code for that would be worthwhile. */
X
X	if ( dirp->dd_loc >= dirp->dd_size	/* invalid index */
X	  || ((struct dirent *)&dirp->dd_buf[dirp->dd_loc])->d_off > loc
X					/* too far along in buffer */
X	   )
X		dirp->dd_loc = 0;	/* reset to beginning of buffer */
X	/* else save time by starting at current dirp->dd_loc */
X
X	for ( rewind = true; ; )
X		{
X		register struct dirent	*dp;
X
X		/* See whether the matching entry is in the current buffer. */
X
X		if ( (dirp->dd_loc < dirp->dd_size	/* valid index */
X		   || readdir( dirp ) != NULL	/* next buffer read */
X		   && (dirp->dd_loc = 0, true)	/* beginning of buffer set */
X		     )
X		  && (dp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc])->d_off
X			<= loc		/* match possible in this buffer */
X		   )	{
X			for ( /* dp initialized above */ ;
X			      (char *)dp < &dirp->dd_buf[dirp->dd_size];
X			      dp = (struct dirent *)((char *)dp + dp->d_reclen)
X			    )
X				if ( dp->d_off == loc )
X					{	/* found it! */
X					dirp->dd_loc =
X						(char *)dp - dirp->dd_buf;
X					return;
X					}
X
X			rewind = false;	/* no point in backing up later */
X			dirp->dd_loc = dirp->dd_size;	/* set end of buffer */
X			}
X		else			/* whole buffer past matching entry */
X			if ( !rewind )
X				{	/* no point in searching further */
X				errno = EINVAL;
X				return;	/* no entry at specified loc */
X				}
X			else	{	/* rewind directory and start over */
X				rewind = false;	/* but only once! */
X
X				dirp->dd_loc = dirp->dd_size = 0;
X
X				if ( lseek( dirp->dd_fd, (off_t)0, SEEK_SET )
X					!= 0
X				   )
X					return;	/* errno already set (EBADF) */
X
X				if ( loc == 0 )
X					return; /* save time */
X				}
X		}
X	}
END_OF_seekdir.c
if test 2965 -ne `wc -c <seekdir.c`; then
    echo shar: \"seekdir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ssignal.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"ssignal.3c\"
else
echo shar: Extracting \"ssignal.3c\" \(2129 characters\)
sed "s/^X//" >ssignal.3c <<'END_OF_ssignal.3c'
X.TH SSIGNAL 3C "Standard Extension"
X.SH NAME
Xssignal, gsignal \- software signals
X.SH SYNOPSIS
X.B #include <signal.h>
X.PP
X.B int (\(**ssignal (sig, action))( )
X.br
X.B int sig, (\(**action)( );
X.PP
X.B int gsignal (sig)
X.br
X.B int sig;
X.SH DESCRIPTION
X.I Ssignal
Xand
X.I gsignal
Ximplement a software facility similar to
X.IR signal (2).
XOn some AT&T UNIX versions, an implementation of
X.IR ssignal (3)
Xis used by the Standard C Library to enable users to indicate the disposition
Xof error conditions, and is also available to users for other purposes. This
Xlibrary emulates that facility.
X.PP
XSoftware signals made available to users are associated
Xwith integers in the inclusive range 1 through 15. A
Xcall to
X.I ssignal
Xassociates a procedure,
X.IR action ,
Xwith the software signal
X.IR sig ;
Xthe software signal,
X.IR sig ,
Xis raised
Xby a call to
X.IR gsignal .
XRaising a software signal causes the action established for that signal
Xto be
X.IR taken .
X.PP
XThe first argument to
X.I ssignal
Xis a number identifying the type of signal for which an action is to be
Xestablished. The second argument defines the action; it is either the
Xname of a (user-defined)
X.I action function
Xor one of the manifest constants
X.SM
X.B SIG_DFL
X(default) or
X.SM
X.B SIG_IGN
X(ignore).
X.I Ssignal
Xreturns the action previously established for that signal type; if no
Xaction has been established or the signal number is illegal,
X.I ssignal
Xreturns
X.SM
X.BR SIG_DFL .
X.PP
X.I Gsignal
Xraises the signal identified by its argument,
X.IR sig :
X.RS 5
X.PP
XIf an action function has been established for
X.IR sig ,
Xthen that action is reset to
X.SM
X.B SIG_DFL
Xand the action function is entered with argument
X.IR sig .
X.I Gsignal
Xreturns the value returned to it by the action function.
X.PP
XIf the action for
X.I sig
Xis
X.SM
X.BR SIG_IGN ,
X.I gsignal
Xreturns the value 1 and takes no other action.
X.PP
XIf the action for
X.I sig
Xis
X.SM
X.BR SIG_DFL ,
X.I gsignal
Xreturns the value 0 and takes no other action.
X.PP
XIf
X.I sig
Xhas an illegal value or no action was ever specified for
X.IR sig ,
X.I gsignal
Xreturns the value 0 and takes no other action.
X.RE
X.SH "SEE ALSO"
Xsignal(2).
END_OF_ssignal.3c
if test 2129 -ne `wc -c <ssignal.3c`; then
    echo shar: \"ssignal.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strtol.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strtol.3c\"
else
echo shar: Extracting \"strtol.3c\" \(1522 characters\)
sed "s/^X//" >strtol.3c <<'END_OF_strtol.3c'
X.TH STRTOL 3C 
X.SH NAME
Xstrtol, atol, atoi \- convert string to integer
X.SH SYNOPSIS
X.nf
X.B long strtol (str, ptr, base)
X.B char \(**str, \(**\(**ptr;
X.B int base;
X.SH DESCRIPTION
X.I Strtol
Xreturns as a long integer the value represented by the character string pointed
Xto by
X.IR str .
XThe string is scanned up to the first character inconsistent with the base.
XLeading ``white-space'' characters (as defined by
X.I isspace
Xin
X.IR ctype (3C))
Xare ignored.
X.PP
XIf the value of
X.I ptr
Xis not (char \(**\(**)\s-1NULL\s+1, a pointer to the character terminating the
Xscan is returned in the location pointed to by
X.IR ptr .
XIf no integer can be formed, that location is set to
X.IR str ,
Xand zero is returned.
X.PP
XIf
X.I base
Xis positive (and not greater than 36), it is used as the base for conversion.
XAfter an optional leading sign, leading zeros are ignored, and ``0x'' or ``0X''
Xis ignored if
X.I base
Xis 16.
X.PP
XIf
X.I base
Xis zero, the string itself determines the base thusly: After an optional leading
Xsign a leading zero indicates octal conversion, and a leading ``0x'' or ``0X''
Xhexadecimal conversion.  Otherwise, decimal conversion is used.
X.PP
XTruncation from long to int can, of course, take place upon assignment or by
Xan explicit cast.
X.PP
X.I Atol(str)
Xis equivalent to
X.IR "strtol(str, (char \(**\(**)\s-1NULL\s+1, 10)" .
X.PP
X.I Atoi(str)
Xis equivalent to
X.IR "(int) strtol(str, (char \(**\(**)\s-1NULL\s+1, 10)" .
X.SH SEE ALSO
Xctype(3C), scanf(3S), strtod(3C), atoi(3S).
X.SH BUGS
XOverflow conditions are ignored.
END_OF_strtol.3c
if test 1522 -ne `wc -c <strtol.3c`; then
    echo shar: \"strtol.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f strtol.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"strtol.c\"
else
echo shar: Extracting \"strtol.c\" \(1737 characters\)
sed "s/^X//" >strtol.c <<'END_OF_strtol.c'
X/*
X * strtol - convert string to long integer.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X *
X * Compile with -DTEST to get short interactive main() for testing.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X
Xlong
Xstrtol(s, p, b)
Xchar	*s, **p;
Xint	b;
X{
X	int	base = 10, n = 0, sign = 1, valid = 1;
X
X	/*
X	 * leading sign?
X	 */
X	if (*s=='-')
X		sign=(-1);
X	else
X		sign=1;
X	if (*s=='+' || *s=='-')
X		++s; /* skip sign */
X
X	/*
X	 * what base are we really using?
X	 */
X	if (b == 0) {
X		if (strncmp(s, "0x", 2) == 0  ||
X		    strncmp(s, "0X", 2) == 0) {
X			s += 2;
X			base = 16;
X		} else
X			if (*s == '0')
X				base = 8;
X	}
X
X	/*
X	 * convert the string to a number.
X	 */
X	while (isascii(*s) && valid) {
X		switch(*s) {
X		case '0':
X		case '1':
X		case '2':
X		case '3':
X		case '4':
X		case '5':
X		case '6':
X		case '7':
X			n = base*n  +  *s-'0';
X			break;
X		case '8':
X		case '9':
X			if (base >8)
X				n = base*n  +  *s-'0';
X			else
X				valid = 0;
X			break;
X		case 'a':
X		case 'b':
X		case 'c':
X		case 'd':
X		case 'e':
X		case 'f':
X			if (base == 16)
X				n = base*n + *s-'a'+10;
X			else
X				valid = 0;
X			break;
X		case 'A':
X		case 'B':
X		case 'C':
X		case 'D':
X		case 'E':
X		case 'F':
X			if (base == 16)
X				n = base*n + *s-'A'+10;
X			else
X				valid = 0;
X			break;
X		default:
X			valid = 0;
X			break;
X		}
X		++s;
X	}
X
X	/*
X	 * if arg `p' is not NULL, a ptr to the character
X	 * terminating the scan will be returned in `p'
X	 */
X	if (*p != (char *)NULL)
X		*p = s;
X
X	return sign * n;
X}
X
X#ifdef	TEST
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int i;
X	long j, strtol();
X
X	for (i=1; i<argc; i++) {
X		j = strtol(argv[i], 0, 0);
X		(void) printf("%s -> %ld(%lx)\n", argv[i], j, j);
X	}
X	exit(0);
X}
X#endif	/* TEST */
END_OF_strtol.c
if test 1737 -ne `wc -c <strtol.c`; then
    echo shar: \"strtol.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sys._dir.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sys._dir.h\"
else
echo shar: Extracting \"sys._dir.h\" \(2977 characters\)
sed "s/^X//" >sys._dir.h <<'END_OF_sys._dir.h'
X/*
X	<sys/_dir.h> -- definitions for 4.2,4.3BSD directories
X
X	last edit:	25-Apr-1987	D A Gwyn
X
X	A directory consists of some number of blocks of DIRBLKSIZ bytes each,
X	where DIRBLKSIZ is chosen such that it can be transferred to disk in a
X	single atomic operation (e.g., 512 bytes on most machines).
X
X	Each DIRBLKSIZ-byte block contains some number of directory entry
X	structures, which are of variable length.  Each directory entry has the
X	beginning of a (struct direct) at the front of it, containing its
X	filesystem-unique ident number, the length of the entry, and the length
X	of the name contained in the entry.  These are followed by the NUL-
X	terminated name padded to a (long) boundary with 0 bytes.  The maximum
X	length of a name in a directory is MAXNAMELEN.
X
X	The macro DIRSIZ(dp) gives the amount of space required to represent a
X	directory entry.  Free space in a directory is represented by entries
X	that have dp->d_reclen > DIRSIZ(dp).  All DIRBLKSIZ bytes in a
X	directory block are claimed by the directory entries; this usually
X	results in the last entry in a directory having a large dp->d_reclen.
X	When entries are deleted from a directory, the space is returned to the
X	previous entry in the same directory block by increasing its
X	dp->d_reclen.  If the first entry of a directory block is free, then
X	its dp->d_fileno is set to 0; entries other than the first in a
X	directory do not normally have 	dp->d_fileno set to 0.
X
X	prerequisite:	<sys/types.h>
X*/
X
X#if defined(accel) || defined(sun) || defined(vax)
X#define	DIRBLKSIZ	512		/* size of directory block */
X#else
X#ifdef alliant
X#define	DIRBLKSIZ	4096		/* size of directory block */
X#else
X#ifdef gould
X#define	DIRBLKSIZ	1024		/* size of directory block */
X#else
X#ifdef ns32000	/* Dynix System V */
X#define	DIRBLKSIZ	2600		/* size of directory block */
X#else	/* be conservative; multiple blocks are okay but fractions are not */
X#define	DIRBLKSIZ	4096		/* size of directory block */
X#endif
X#endif
X#endif
X#endif
X
X#define	MAXNAMELEN	255		/* maximum filename length */
X/* NOTE:  not MAXNAMLEN, which has been preempted by SVR3 <dirent.h> */
X
Xstruct direct				/* data from read()/_getdirentries() */
X	{
X	unsigned long	d_fileno;	/* unique ident of entry */
X	unsigned short	d_reclen;	/* length of this record */
X	unsigned short	d_namlen;	/* length of string in d_name */
X	char		d_name[MAXNAMELEN+1];	/* NUL-terminated filename */
X	/* typically shorter */
X	};
X
X/*
X	The DIRSIZ macro gives the minimum record length which will hold the
X	directory entry.  This requires the amount of space in a (struct
X	direct) without the d_name field, plus enough space for the name with a
X	terminating NUL character, rounded up to a (long) boundary.
X
X	(Note that Berkeley didn't properly compensate for struct padding,
X	but we nevertheless have to use the same size as the actual system.)
X*/
X
X#define	DIRSIZ( dp )	((sizeof(struct direct) - (MAXNAMELEN+1) \
X			+ sizeof(long) + (dp)->d_namlen) \
X			/ sizeof(long) * sizeof(long))
END_OF_sys._dir.h
if test 2977 -ne `wc -c <sys._dir.h`; then
    echo shar: \"sys._dir.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 5\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 589-7930
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny     attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752

lenny@icus.islp.ny.us (Lenny Tropiano) (08/03/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 5)."
# Contents:  DIRENT.INSTALL DIRENT.NOTES bsearch.3c directory.3c
#   getcwd.c mkdir.c tsearch.c
# Wrapped by lenny@icus on Wed Aug  2 21:40:29 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f DIRENT.INSTALL -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"DIRENT.INSTALL\"
else
echo shar: Extracting \"DIRENT.INSTALL\" \(5490 characters\)
sed "s/^X//" >DIRENT.INSTALL <<'END_OF_DIRENT.INSTALL'
X
X
X			INSTALLATION INSTRUCTIONS
X
X
XThe following instructions are for systems resembling Ninth Edition UNIX, with
Xhints about dealing with variations you may encounter for your specific system.
XInstallation should be done only by someone who is comfortable with modifying
Xthe standard C library and header files.
X
XIf your system already includes directory access routines, you should replace
Xthem with this package.  We're trying to get this standardized; see the
Xdiscussion in the NOTES file.
X
XI have tried to make the source code as generic as possible, but if your system
Xpredates Seventh Edition UNIX you will have problems.
X
XDISCLAIMER:  Although I believe the code and procedures described here to be
Xcorrect, I make no warranty of any kind, and you are advised to perform your
Xown careful testing before making any substantial change like this to your
Xprogramming environment.
X
X
X0)  For antique systems that do not support C's "void" data type, edit the file
X    sys.dirent.h to add the following:
X
X	typedef int		void;	/* good enough for govt work */
X
X    If for some reason your <sys/types.h> doesn't define them, add the
X    following to sys.dirent.h:
X
X	typedef unsigned short	ino_t;	/* (assuming original UFS) */
X	typedef long		off_t;	/* long is forced by lseek() */
X
X    None of this should be necessary for any modern UNIX system.
X
X1)  Copy the file dirent.h to /usr/include/dirent.h and copy the file
X    sys.dirent.h to /usr/include/sys/dirent.h.  (The file sys._dir.h is also
X    provided for the BRL UNIX System V emulation for 4.nBSD.  That environment
X    uses different directory names for everything.)
X
X2)  Copy the file directory.3c to /usr/man/man3/directory.3 and copy the file
X    dirent.4 to /usr/man/man5/dirent.5; edit the new file
X    /usr/man/man3/directory.3 to change the "SEE ALSO" reference from dirent(4)
X    to dirent(5) and to change the 3C on the first line to 3; edit the new file
X    /usr/man/man5/dirent.5 to change the 4 on the first line to 5; then print
X    the manual pages via the command
X
X	man directory dirent
X
X    to see what the new routines are like.  (If you have a "catman" style of
X    on-line manual, adapt these instructions accordingly.  Manual entries are
X    kept in directories with other names on some systems such as UNIX System V.
X    On systems that already had a directory library documented in some other
X    manual entry, remove the superseded manual entry; if the description of the
X    native filesystem directory format found by "man dir" refers to a directory
X    library, modify it to simply refer to the entry for "dirent".)
X
X3)  Copy the files closedir.c, opendir.c, readdir.c, rewinddir.c, seekdir.c,
X    and telldir.c to the "gen" or "port/gen" subdirectory of your C library
X    source directory.  If you do not have a getdents() system call, copy the
X    file getdents.c to the "sys" or "port/sys" subdirectory and copy the file
X    getdents.2 to /usr/man/man2/getdents.2 (actually you may prefer to put this
X    file in section 3 and adjust the references in the other manual entries
X    accordingly; also adjust the references to dirent(4) to be to dirent(5) if
X    that's where the entry is).  Edit the C library makefile(s) to include the
X    new object modules in the C library.  (See the comments at the beginning of
X    getdents.c for symbols that must be defined to configure getdents.c.)  Then
X    remake and reinstall the C library.  Alternatively, you can just compile
X    the new sources and insert their objects near the front of the C library
X    /lib/libc.a using the "ar" utility (seekdir.o should precede readdir.o,
X    which in turn should precede getdents.o).  On some systems you then need to
X    use the "ranlib" utility to update the archive symbol table.
X
X4)  After the C library has been updated, delete /usr/include/ndir.h or any
X    other header used with a previous directory library to prevent inadvertent
X    use of the superseded directory access interface.  Also delete any
X    corresponding library such as /usr/lib/libndir.a.
X
X5)  To verify installation, try compiling, linking, and running the program
X    testdir.c.  This program searches the current directory "." for each file
X    named as a program argument and prints `"FOO" found.' or `"FOO" not found.'
X    where FOO is of course replaced by the name being sought in the directory.
X    Try something like
X
X	cd /usr/bin			# a multi-block directory
X	WHEREVER/testdir FOO lint BAR f77 XYZZY
X
X    which should produce the output
X
X	"FOO" not found.
X	"lint" found.
X	"BAR" not found.
X	"f77" found.
X	"XYZZY" not found.
X
X    A more thorough test would be
X
X	cd /usr/bin			# a multi-block directory
X	WHEREVER/testdir `ls -a` | grep 'not found'
X
X    This program does not test the seekdir() and telldir() functions.
X
X6)  Notify your programmers that all directory access must be made through the
X    new interface, and that documentation is available via
X
X	man directory dirent
X
X    Make the NOTES file available to those programmers who might want to
X    understand what this is all about.
X
X7)  Change all system sources that were accessing directories to use the new
X    routines.  Nearly all such sources contain the line
X
X	#include <sys/dir.h>
X    or
X	#include <ndir.h>
X
X    so they should be easy to find.  (If you earlier removed some other header
X    file, that is, if this package superseded an earlier version of the
X    directory access library, look for its name too.  See the conversion
X    instructions in the NOTES file.)
END_OF_DIRENT.INSTALL
if test 5490 -ne `wc -c <DIRENT.INSTALL`; then
    echo shar: \"DIRENT.INSTALL\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f DIRENT.NOTES -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"DIRENT.NOTES\"
else
echo shar: Extracting \"DIRENT.NOTES\" \(5314 characters\)
sed "s/^X//" >DIRENT.NOTES <<'END_OF_DIRENT.NOTES'
X
X
XNOTES FOR NEARLY-POSIX-COMPATIBLE C LIBRARY DIRECTORY-ACCESS ROUTINES
X
X
XOlder UNIX C libraries lacked support for reading directories, so historically
Xprograms had knowledge of UNIX directory structure hard-coded into them.  When
XBerkeley changed the format of directories for 4.2BSD, it became necessary to
Xchange programs to work with the new structure.  Fortunately, Berkeley designed
Xa small set of directory access routines to encapsulate knowledge of the new
Xdirectory format so that user programs could deal with directory entries as an
Xabstract data type.  (Unfortunately, they didn't get it quite right.)  The
Xinterface to these routines was nearly independent of the particular
Ximplementation of directories on any given UNIX system; this has become a
Xparticularly important requirement with the advent of heterogeneous network
Xfilesystems such as NFS.
X
XIt has consequently become possible to write portable applications that search
Xdirectories by restricting all directory access to use these new interface
Xroutines.  The sources supplied here are a total rewrite of Berkeley's code,
Xincorporating ideas from a variety of sources and conforming as closely to
Xpublished standards as possible, and are in the PUBLIC DOMAIN to encourage
Xtheir widespread adoption.  They support four methods of access to system
Xdirectories: the original UNIX filesystem via read(), the 4.2BSD filesystem via
Xread(), NFS and native filesystems via getdirentries(), and SVR3 getdents().
XThe other three types are accomplished by appropriate emulation of the SVR3
Xgetdents() system call, which attains portability at the cost of slightly more
Xdata movement than absolutely necessary for some systems.  These routines
Xshould be added to the standard C library on all UNIX systems, and all existing
Xand future applications should be changed to use this interface.  Once this is
Xdone, there should be no portability problems due to differences in underlying
Xdirectory structures among UNIX systems.  (When porting your applications to
Xother UNIX systems, you can always carry this package around with you.)
X
XAn additional benefit of these routines is that they buffer directory input,
Xwhich provides improved access speed over raw read()s of one entry at a time.
X
XOne annoying compatibility problem has arisen along the way, namely that the
Xoriginal Berkeley interface used the same name, struct direct, for the new data
Xstructure as had been used for the original UNIX filesystem directory record
Xstructure.  This name was changed by the IEEE 1003.1 (POSIX) Working Group to
X"struct dirent" and was picked up for SVR3 under the new name; it is also the
Xname used in this portable package.  I believe it is necessary to bite the
Xbullet and adopt the new non-conflicting name.  Code using a 4.2BSD-compatible
Xpackage needs to be slightly revised to work with this new package, as follows:
X	Change
X		#include <ndir.h>	/* Ninth Edition UNIX */
X	or
X		#include <sys/dir.h>	/* 4.2BSD */
X	or
X		#include <dir.h>	/* BRL System V emulation */
X	to
X		#include <sys/types.h>	/* if not already #included */
X		#include <dirent.h>
X
X	Change
X		struct direct
X	to
X		struct dirent
X
X	Change
X		(anything)->d_namlen
X	to
X		strlen( (anything)->d_name )
X
XThere is a minor compatibility problem in that the closedir() function was
Xoriginally defined to have type void, but IEEE 1003.1 changed this to type int,
Xwhich is what this implementation supports (even though I disagree with the
Xchange).  However, the difference does not affect most applications.
X
XAnother minor problem is that IEEE 1003.1 defined the d_name member of a struct
Xdirent to be an array of maximum length; this does not permit use of compact
Xvariable-length entries directly from a directory block buffer.  This part of
Xthe specification is incompatible with efficient use of the getdents() system
Xcall, and I have therefore chosen to follow the SVID specification instead of
XIEEE 1003.1 (which I hope is changed for the final-use standard).  This
Xdeviation should have little or no impact on sensibly-coded applications, since
Xthe relevant d_name length is that given by strlen(), not the declared array
Xsize.
X
XError handling is not completely satisfactory, due to the variety of possible
Xfailure modes in a general setting.  For example, the rewinddir() function
Xmight fail, but there is no good way to indicate this.  I have tried to
Xfollow the specifications in IEEE 1003.1 and the SVID as closely as possible,
Xbut there are minor deviations in this regard.  Applications should not rely
Xtoo heavily on exact failure mode semantics.
X
XPlease do not change the new standard interface in any way, as that would
Xdefeat the major purpose of this package!  (It's okay to alter the internal
Ximplementation if you really have to, although I tried to make this unnecessary
Xfor the vast majority of UNIX variants.)
X
XInstallation instructions can be found in the file named INSTALL.
X
XThis implementation is provided by:
X
X	Douglas A. Gwyn
X	U.S. Army Ballistic Research Laboratory
X	SLCBR-VL-V
X	Aberdeen Proving Ground, MD 21005-5066
X
X	(301)278-6647
X
X	Gwyn@BRL.MIL or seismo!brl!gwyn
X
XThis is UNSUPPORTED, use-at-your-own-risk, free software in the public domain.
XHowever, I would appreciate hearing of any actual bugs you find in this
Ximplementation and/or any improvements you come up with.
END_OF_DIRENT.NOTES
if test 5314 -ne `wc -c <DIRENT.NOTES`; then
    echo shar: \"DIRENT.NOTES\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bsearch.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bsearch.3c\"
else
echo shar: Extracting \"bsearch.3c\" \(3005 characters\)
sed "s/^X//" >bsearch.3c <<'END_OF_bsearch.3c'
X.TH BSEARCH 3C "Standard Extension"
X.SH NAME
Xbsearch \- binary search a sorted table
X.SH SYNOPSIS
X.B #include <search.h>
X.PP
X.B "char \(**bsearch ((char \(**) key, (char \(**) base, nel, sizeof (\(**key), compar)"
X.br
X.B unsigned nel;
X.br
X.B int (\(**compar)( );
X.SH DESCRIPTION
X.I Bsearch
Xis a binary search routine generalized from Knuth (6.2.1) Algorithm B.
XIt returns a pointer into a table indicating where a datum may be found.
XThe table must be previously sorted in increasing order according to a
Xprovided comparison function.
X.I Key
Xpoints to a datum instance to be sought in the table.
X.I Base
Xpoints to the element at the base of the table.
X.I Nel
Xis the number of elements in the table.
X.I Compar
Xis the name of the comparison function, which is called with two arguments
Xthat point to the elements being compared. The function must return
Xan integer less than, equal to, or greater than zero as accordinly the first
Xargument is to be considered less than, equal to, or greater than the second.
X.SH EXAMPLE
XThe example below searches a table containing pointers to nodes consisting of
Xa string and its length. The table is ordered alphabetically on the string in
Xthe node pointed to by each entry.
X.PP
XThis code fragment reads in strings and either finds the corresponding node 
Xand prints out the string and its length, or prints an error message.
X.PP
X.RS
X.nf
X.ss 18
X#include <stdio.h>
X#include <search.h>
X
X#define	\s-1TABSIZE\s+1	1000
X
Xstruct node {			/\(** these are stored in the table \(**/
X	char \(**string;
X	int length;
X};
Xstruct node table[\s-1TABSIZE\s+1];	/\(** table to be searched \(**/
X	.
X	.
X	.
X{
X	struct node \(**node_ptr, node;
X	int node_compare( );  /\(** routine to compare 2 nodes \(**/
X	char str_space[20];   /\(** space to read string into \(**/
X	.
X	.
X	.
X	node.string = str_space;
X	while (scanf("%s", node.string) != \s-1EOF\s+1) {
X		node_ptr = (struct node \(**)bsearch((char \(**)(&node),
X			   (char \(**)table, \s-1TABSIZE\s+1,
X			   sizeof(struct node), node_compare);
X		if (node_ptr != \s-1NULL\s+1) {
X			(void)printf("string = %20s, length = %d\en",
X				node_ptr\(mi>string, node_ptr\(mi>length);
X		} else {
X			(void)printf("not found: %s\en", node.string);
X		}
X	}
X}
X/\(**
X	This routine compares two nodes based on an
X	alphabetical ordering of the string field.
X\(**/
Xint
Xnode_compare(node1, node2)
Xstruct node \(**node1, \(**node2;
X{
X	return strcmp(node1\(mi>string, node2\(mi>string);
X}
X.fe
X.SH NOTES
XThe pointers to the key and the element at the base of
Xthe table should be of type pointer-to-element,
Xand cast to type pointer-to-character.
X.br
XThe comparison function need not compare every byte,
Xso arbitrary data may be contained in the elements in addition to the values
Xbeing compared.
X.br
XAlthough declared as type pointer-to-character,
Xthe value returned should be cast into type pointer-to-element.
X.SH SEE ALSO
Xhsearch(3C), lsearch(3C), qsort(3C), tsearch(3C).
X.SH DIAGNOSTICS
XA
X\s-1NULL\s+1
Xpointer is returned if the key cannot be found in the table.
END_OF_bsearch.3c
if test 3005 -ne `wc -c <bsearch.3c`; then
    echo shar: \"bsearch.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f directory.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"directory.3c\"
else
echo shar: Extracting \"directory.3c\" \(4136 characters\)
sed "s/^X//" >directory.3c <<'END_OF_directory.3c'
X.TH DIRECTORY 3C "Standard Extension"
X.SH NAME
Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- directory operations
X.SH SYNOPSIS
X.B "#include <sys/types.h>"
X.br
X.B "#include <dirent.h>"
X.P
X.B "DIR \(**opendir (dirname)"
X.br
X.B "char \(**dirname;"
X.P
X.B "struct dirent \(**readdir (dirp)"
X.br
X.B "DIR \(**dirp;"
X.P
X.B "off_t telldir (dirp)"
X.br
X.B "DIR \(**dirp;"
X.P
X.B "void seekdir (dirp, loc)"
X.br
X.B "DIR \(**dirp;"
X.br
X.B "off_t loc;"
X.P
X.B "void rewinddir (dirp)"
X.br
X.B "DIR \(**dirp;"
X.P
X.B "int closedir (dirp)"
X.br
X.B "DIR \(**dirp;"
X.SH DESCRIPTION
X.I Opendir
Xestablishes a connection between
Xthe directory named by
X.I dirname
Xand a unique object of type
X.SM DIR
Xknown as a
X.I "directory stream"
Xthat it creates.
X.I Opendir
Xreturns a pointer to be used to identify the
Xdirectory stream
Xin subsequent operations.
XA
X.SM NULL
Xpointer is returned if
X.I dirname
Xcannot be accessed or is not a directory,
Xor if
X.I opendir
Xis unable to create the
X.SM DIR
Xobject
X(perhaps due to insufficient memory).
X.P
X.I Readdir
Xreturns a pointer to an internal structure
Xcontaining information about the next active directory entry.
XNo inactive entries are reported.
XThe internal structure may be overwritten by
Xanother operation on the same
Xdirectory stream;
Xthe amount of storage needed to hold a copy
Xof the internal structure is given by the value of a macro,
X.IR DIRENTSIZ(strlen(direntp\->d_name)) ,
Xnot by
X.I "sizeof(struct\ dirent)"
Xas one might expect.
XA
X.SM NULL
Xpointer is returned
Xupon reaching the end of the directory,
Xupon detecting an invalid location in the directory,
Xor upon occurrence of an error while reading the directory.
X.P
X.I Telldir
Xreturns the current position associated with the named
Xdirectory stream
Xfor later use as an argument to
X.IR seekdir .
X.P
X.I Seekdir
Xsets the position of the next
X.I readdir
Xoperation on the named
Xdirectory stream.
XThe new position reverts to the one associated with the
Xdirectory stream
Xwhen the
X.I telldir
Xoperation from which
X.I loc
Xwas obtained was performed.
X.P
X.I Rewinddir
Xresets the position of the named
Xdirectory stream
Xto the beginning of the directory.
XAll buffered data for the directory stream is discarded,
Xthereby guaranteeing that the actual
Xfile system directory will be referred to for the next
X.I readdir
Xon the
Xdirectory stream.
X.P
X.I Closedir
Xcloses the named
Xdirectory stream;
Xinternal resources used for the
Xdirectory stream are liberated,
Xand subsequent use of the associated
X.SM DIR
Xobject is no longer valid.
X.I Closedir
Xreturns a value of zero if no error occurs,
X\-1 otherwise.
X.P
XThere are several possible errors that can occur
Xas a result of these operations;
Xthe external integer variable
X.I errno
Xis set to indicate the specific error.
X.RI ( Readdir 's
Xdetection of the normal end of a directory
Xis not considered to be an error.)
X.SH EXAMPLE
XSample code which searches the current working directory for entry
X.IR name :
X.P
X.ft B
X	dirp = opendir( "." );
X.br
X	while ( (dp = readdir( dirp )) != NULL )
X.br
X		if ( strcmp( dp\->d_name, name ) == 0 )
X.br
X			{
X.br
X			(void) closedir( dirp );
X.br
X			return FOUND;
X.br
X			}
X.br
X	(void) closedir( dirp );
X.br
X	return NOT_FOUND;
X.ft P
X.SH "SEE ALSO"
Xgetdents(2), dirent(4).
X.SH WARNINGS
XEntries for "." and ".."
Xmay not be reported for some file system types.
X.P
XThe value returned by
X.I telldir
Xneed not have any simple interpretation
Xand should only be used as an argument to
X.IR seekdir .
XSimilarly,
Xthe
X.I loc
Xargument to
X.I seekdir
Xmust be obtained from a previous
X.I telldir
Xoperation on the same
Xdirectory stream.
X.P
X.I Telldir
Xand
X.I seekdir
Xare unreliable when used in conjunction with
Xfile systems that perform directory compaction or expansion
Xor when the directory stream has been closed and reopened.
XIt is best to avoid using
X.I telldir
Xand
X.I seekdir
Xaltogether.
X.P
XThe exact set of
X.I errno
Xvalues and meanings may vary among implementations.
X.P
XBecause directory entries can dynamically
Xappear and disappear,
Xand because directory contents are buffered
Xby these routines,
Xan application may need to continually rescan
Xa directory to maintain an accurate picture
Xof its active entries.
END_OF_directory.3c
if test 4136 -ne `wc -c <directory.3c`; then
    echo shar: \"directory.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f getcwd.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"getcwd.c\"
else
echo shar: Extracting \"getcwd.c\" \(5249 characters\)
sed "s/^X//" >getcwd.c <<'END_OF_getcwd.c'
X/*
X	getcwd -- get current working directory name (POSIX and SVID compatible)
X
X	last edit:	21-Sep-1987	D A Gwyn
X
X	This public-domain getcwd() routine can be used to replace the UNIX
X	System V library routine (which uses popen() to capture the output of
X	the "pwd" command).  Once that is done, "pwd" can be reimplemented as
X	just puts(getcwd()).
X
X	This implementation depends on every directory having entries for
X	"." and "..".  It also depends on the internals of the <dirent.h>
X	data structures to some degree.
X
X	I considered using chdir() to ascend the hierarchy, followed by a
X	final chdir() to the path being returned by getcwd() to restore the
X	location, but decided that error recovery was too difficult that way.
X	The algorithm I settled on was inspired by my rewrite of the "pwd"
X	utility, combined with the dotdots[] array trick from the SVR2 shell.
X*/
X
X#include	<sys/types.h>
X#include	<sys/stat.h>
X#include	<dirent.h>
X#include	<errno.h>
X#include	<string.h>
X
Xtypedef char	*pointer;		/* (void *) if you have it */
X
Xextern void	free();
Xextern pointer	malloc();
Xextern int	fstat(), stat();
X
Xextern int	errno;			/* normally done by <errno.h> */
X
X#ifndef NULL
X#define	NULL	0			/* amorphous null pointer constant */
X#endif
X
X#ifndef NAME_MAX
X#define	NAME_MAX	255		/* maximum directory entry size */
X#endif
X
Xchar	*
Xgetcwd( buf, size )			/* returns pointer to CWD pathname */
X	char		*buf;		/* where to put name (NULL to malloc) */
X	int		size;		/* size of buf[] or malloc()ed memory */
X	{
X	static char	dotdots[] =
X"../../../../../../../../../../../../../../../../../../../../../../../../../..";
X	char 		*dotdot;	/* -> dotdots[.], right to left */
X	DIR		*dirp;		/* -> parent directory stream */
X	struct dirent	*dir;		/* -> directory entry */
X	struct stat	stat1, stat2;	/* info from stat() */
X	struct stat	*d = &stat1;	/* -> info about "." */
X	struct stat	*dd = &stat2;	/* -> info about ".." */
X	register char	*buffer;	/* local copy of buf, or malloc()ed */
X	char		*bufend;	/* -> buffer[size] */
X	register char	*endp;		/* -> end of reversed string */
X	register char	*dname;		/* entry name ("" for root) */
X	int		serrno = errno;	/* save entry errno */
X
X	if ( size == 0 )
X		{
X		errno = EINVAL;		/* invalid argument */
X		return NULL;
X		}
X
X	if ( (buffer = buf) == NULL	/* wants us to malloc() the string */
X	  && (buffer = (char *)malloc( (unsigned)size )) == NULL
X	   )	{
X		errno = ENOMEM;		/* cannot malloc() specified size */
X		return NULL;
X		}
X
X	if ( stat( ".", dd ) != 0 )	/* prime the pump */
X		goto error;		/* errno already set */
X
X	endp = buffer;			/* initially, empty string */
X	bufend = &buffer[size];
X
X	for ( dotdot = &dotdots[sizeof(dotdots)]; dotdot != dotdots; )
X		{
X		dotdot -= 3;		/* include one more "/.." section */
X					/* (first time is actually "..") */
X
X		/* swap stat() info buffers */
X		{
X		register struct stat	*temp = d;
X
X		d = dd;			/* new current dir is old parent dir */
X		dd = temp;
X		}
X
X		if ( (dirp = opendir( dotdot )) == NULL )	/* new parent */
X			goto error;	/* errno already set */
X
X		if ( fstat( dirp->dd_fd, dd ) != 0 )
X			{
X			serrno = errno;	/* set by fstat() */
X			(void)closedir( dirp );
X			errno = serrno;	/* in case closedir() clobbered it */
X			goto error;
X			}
X
X		if ( d->st_dev == dd->st_dev )
X			{		/* not crossing a mount point */
X			if ( d->st_ino == dd->st_ino )
X				{	/* root directory */
X				dname = "";
X				goto append;
X				}
X
X			do
X				if ( (dir = readdir( dirp )) == NULL )
X					{
X					(void)closedir( dirp );
X					errno = ENOENT;	/* missing entry */
X					goto error;
X					}
X			while ( dir->d_ino != d->st_ino );
X			}
X		else	{		/* crossing a mount point */
X			struct stat	t;	/* info re. test entry */
X			char		name[sizeof(dotdots) + 1 + NAME_MAX];
X
X			(void)strcpy( name, dotdot );
X			dname = &name[strlen( name )];
X			*dname++ = '/';
X
X			do	{
X				if ( (dir = readdir( dirp )) == NULL )
X					{
X					(void)closedir( dirp );
X					errno = ENOENT;	/* missing entry */
X					goto error;
X					}
X
X				(void)strcpy( dname, dir->d_name );
X				/* must fit if NAME_MAX is not a lie */
X				}
X			while ( stat( name, &t ) != 0
X			     || t.st_ino != d->st_ino
X			     || t.st_dev != d->st_dev
X			      );
X			}
X
X		dname = dir->d_name;
X
X		/* append "/" and reversed dname string onto buffer */
X    append:
X		if ( endp != buffer	/* avoid trailing / in final name */
X		  || dname[0] == '\0'	/* but allow "/" when CWD is root */
X		   )
X			*endp++ = '/';
X
X		{
X		register char	*app;	/* traverses dname string */
X
X		for ( app = dname; *app != '\0'; ++app )
X			;
X
X		if ( app - dname >= bufend - endp )
X			{
X			(void)closedir( dirp );
X			errno = ERANGE;	/* won't fit allotted space */
X			goto error;
X			}
X
X		while ( app != dname )
X			*endp++ = *--app;
X		}
X
X		(void)closedir( dirp );
X
X		if ( dname[0] == '\0' )	/* reached root; wrap it up */
X			{
X			register char	*startp;	/* -> buffer[.] */
X
X			*endp = '\0';	/* plant null terminator */
X
X			/* straighten out reversed pathname string */
X			for ( startp = buffer; --endp > startp; ++startp )
X				{
X				char	temp = *endp;
X
X				*endp = *startp;
X				*startp = temp;
X				}
X
X			errno = serrno;	/* restore entry errno */
X			return buffer;
X			}
X		}
X
X	errno = ENOMEM;			/* actually, algorithm failure */
X
X    error:
X	if ( buf == NULL )
X		free( (pointer)buffer );
X
X	return NULL;
X	}
X
X
END_OF_getcwd.c
if test 5249 -ne `wc -c <getcwd.c`; then
    echo shar: \"getcwd.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mkdir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mkdir.c\"
else
echo shar: Extracting \"mkdir.c\" \(4832 characters\)
sed "s/^X//" >mkdir.c <<'END_OF_mkdir.c'
X/****************************************************************************
X
XNAME
X   mkdir.c -- emulation of BSD/SVr3-style mkdir(2) system call
X
XSYNOPSIS
X   int mkdir(path, perm)    -- make a directory with given permissions
X   char *path; int perm;
X
XDESCRIPTION
X   The mkdir() function is used for making directories on systems that
Xdon't have a mkdir(2) call (that is, V7 and USG systems before V.3). It tries
Xto act as much like mkdir(2) as possible. Due to various bogosities (why, oh
Xwhy wasn't mknod(2) for a directory made a non-privileged call?) it cannot
Xcompletely succeed. It returns 0 on success and -1 on failure but
Xonly detect the following ERRNO conditions; ENOENT, EEXIST, EACCESS, ENOTDIR.
X
X   Note: this function emulates the SVr3 behavior (group ID of the directory
Xis the effective group ID of the calling process) rather than the BSD
Xbehavior (group ID of the directory is the group ID of the parent directory).
X
X   On USG it will succeed if the real or apparent uid of the calling process
Xhas write privileges in the current directory (the latter case is implemented
Xby a kluge that tries to set the parent directory's permissions to 0777, 'ware
Xsecurity holes!). The new directory will be owned by the effective uid.
X
X   On V7 (because it restricts the chown(2) call and mkdir(1) makes
Xdirectories owned by the real ID of its caller) the call will only succeed
Xif the real ID matches, and the new directory will be owned by the real
Xuid.
X
XREVISED BY
X   Eric S. Raymond
X
X****************************************************************************/
X/* LINTLIBRARY */
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X#include <signal.h>
X
Xextern int errno;
X
Xstatic int fwait(pid)
X/* wait on a child process, shielding it from SIGINT and SIGHUP */
Xregister int pid;
X{
X    register int w;
X    int status;
X
X    while ((w = wait(&status)) != pid && w != -1)
X	continue;
X    if (w == -1)
X	status = -1;
X
X    return(status);
X}
X
Xint mkdir(path, perm)
Xchar *path;
Xint perm;
X{
X    int		    status, pid;
X    int		    uid = getuid(), gid = getgid();
X#ifndef lint
X    int		    euid = geteuid();
X    int		    egid = getegid();
X#endif /* lint */
X    struct stat	    pstat, sbuf;
X    register char   *p;
X    char	    parent[200];
X    extern char	    *strrchr();
X
X#ifdef MAIN
X    (void) fprintf(stderr, "Attempting to mkdir %s\n", path);
X#endif /* MAIN */
X
X    errno = 0;
X
X    /*
X     * check that the directory doesn't already exist, so that the
X     * do loop below must run at least once
X     */
X    if (stat(path, &sbuf) == 0)
X    {
X	errno = EEXIST;
X#ifdef MAIN
X	(void) fprintf(stderr, "Directory %s exists\n", path);
X#endif /* MAIN */
X	return(-1);
X    }
X
X    /* construct the parent's name */
X    if (p = strrchr(path, '/'))
X    {
X	*p = '\0';
X	(void) strcpy(parent, path);
X	*p = '/';
X    }
X    else
X	(void) strcpy(parent, ".");
X
X    if (stat(parent, &pstat) == -1)    /* check that the parent exists */
X    {
X	errno = ENOENT;
X	return(-1);
X    }
X    else if (!(pstat.st_mode & S_IFDIR))    /* and that it's a directory */
X    {
X	errno = ENOTDIR;
X	return(-1);
X    }
X
X#ifdef USG
X    /*
X     * If the parent directory is 755 (rwxr-xr-x) the mkdir(1) below
X     * will probably fail because it will get suid'd to our real uid, which
X     * is random (and thus probably won't match the parent owner's).
X     * So we have to temporarily chmod the parent to 777 (rwxrwxrwx).
X     */
X    if (sbuf.st_uid != uid)
X    {
X	if (chmod(parent, 0777) == -1)
X	{
X	    errno = EACCES;
X	    return(-1);
X	}
X    }
X#endif /* USG */
X
X    /* now we can make the new directory */
X    if (pid = fork())	/* parent side */
X    {
X	if (pid == -1)
X	    return(-1);
X
X	status = fwait(pid);	/* wait till mkdir child is done */
X
X#ifdef USG
X	/*
X	 * Spawn another child to set ownership correctly -- we do this so
X	 * that it gets set to effective ID even if we're running su. This
X	 * only works where chown(2) can be called to give files away by a
X	 * non-superuser.
X	 */
X	if (pid = fork())
X	    (void) fwait(pid);
X	else {
X#ifndef lint
X	    int		    oldumask = umask(0777);
X#endif /* lint */
X
X	    (void) stat(".", &pstat);
X	    (void) setuid(uid);
X	    (void) setgid(gid);
X#ifndef lint	    /* USG lints disagree about 2nd argument types */
X	    (void) chmod(path, (unsigned)(perm & ~oldumask));
X	    (void) chown(path, euid, egid);
X	    (void) umask(oldumask);
X#endif /* lint */
X	    _exit(0);
X	}
X#endif /* USG */
X    } else {		/* child side */
X	(void) close(1);	/* stdout */
X	(void) close(2);	/* stderr */
X	(void) execlp("mkdir", "mkdir", path, (char *)0);
X	perror(path);
X	_exit(1);
X    }
X
X#ifndef lint	/* USG lints disagree about the type of arg 2 */
X#ifdef USG
X    if (sbuf.st_uid != uid)
X	(void) chmod(parent, (unsigned) pstat.st_mode);	/* put it back */
X#endif /* USG */
X#endif /* lint */
X
X    return(status);
X}
X
X/* mkdir.c ends here */
END_OF_mkdir.c
if test 4832 -ne `wc -c <mkdir.c`; then
    echo shar: \"mkdir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tsearch.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tsearch.c\"
else
echo shar: Extracting \"tsearch.c\" \(3509 characters\)
sed "s/^X//" >tsearch.c <<'END_OF_tsearch.c'
X/*
X * Tree search generalized from Knuth (6.2.2) Algorithm T just like
X * the AT&T man page says.
X *
X * The node_t structure is for internal use only, lint doesn't grok it.
X *
X * Written by reading the System V Interface Definition, not the code.
X *
X * Totally public domain.
X */
X/*LINTLIBRARY*/
X
X#include <search.h>
X
Xtypedef struct node_t
X{
X    char	  *key;
X    struct node_t *left, *right;
X}
Xnode;
X
Xnode *tsearch(key, rootp, compar)
X/* find or insert datum into search tree */
Xchar 	*key;			/* key to be located */
Xregister node	**rootp;	/* address of tree root */
Xint	(*compar)();		/* ordering function */
X{
X    register node *q;
X
X    if (rootp == (struct node_t **)0)
X	return ((struct node_t *)0);
X    while (*rootp != (struct node_t *)0)	/* Knuth's T1: */
X    {
X	int r;
X
X	if ((r = (*compar)(key, (*rootp)->key)) == 0)	/* T2: */
X	    return (*rootp);		/* we found it! */
X	rootp = (r < 0) ?
X	    &(*rootp)->left :		/* T3: follow left branch */
X	    &(*rootp)->right;		/* T4: follow right branch */
X    }
X    q = (node *) malloc(sizeof(node));	/* T5: key not found */
X    if (q != (struct node_t *)0)	/* make new node */
X    {
X	*rootp = q;			/* link new node to old */
X	q->key = key;			/* initialize new node */
X	q->left = q->right = (struct node_t *)0;
X    }
X    return (q);
X}
X
Xnode *tdelete(key, rootp, compar)
X/* delete node with given key */
Xchar	*key;			/* key to be deleted */
Xregister node	**rootp;	/* address of the root of tree */
Xint	(*compar)();		/* comparison function */
X{
X    node *p;
X    register node *q;
X    register node *r;
X    int cmp;
X
X    if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
X	return ((struct node_t *)0);
X    while ((cmp = (*compar)(key, (*rootp)->key)) != 0)
X    {
X	p = *rootp;
X	rootp = (cmp < 0) ?
X	    &(*rootp)->left :		/* follow left branch */
X	    &(*rootp)->right;		/* follow right branch */
X	if (*rootp == (struct node_t *)0)
X	    return ((struct node_t *)0);	/* key not found */
X    }
X    r = (*rootp)->right;			/* D1: */
X    if ((q = (*rootp)->left) == (struct node_t *)0)	/* Left (struct node_t *)0? */
X	q = r;
X    else if (r != (struct node_t *)0)		/* Right link is null? */
X    {
X	if (r->left == (struct node_t *)0)	/* D2: Find successor */
X	{
X	    r->left = q;
X	    q = r;
X	}
X	else
X	{			/* D3: Find (struct node_t *)0 link */
X	    for (q = r->left; q->left != (struct node_t *)0; q = r->left)
X		r = q;
X	    r->left = q->right;
X	    q->left = (*rootp)->left;
X	    q->right = (*rootp)->right;
X	}
X    }
X    free((struct node_t *) *rootp);	/* D4: Free node */
X    *rootp = q;				/* link parent to new node */
X    return(p);
X}
X
Xstatic void trecurse(root, action, level)
X/* Walk the nodes of a tree */
Xregister node	*root;		/* Root of the tree to be walked */
Xregister void	(*action)();	/* Function to be called at each node */
Xregister int	level;
X{
X    if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
X	(*action)(root, leaf, level);
X    else
X    {
X	(*action)(root, preorder, level);
X	if (root->left != (struct node_t *)0)
X	    trecurse(root->left, action, level + 1);
X	(*action)(root, postorder, level);
X	if (root->right != (struct node_t *)0)
X	    trecurse(root->right, action, level + 1);
X	(*action)(root, endorder, level);
X    }
X}
X
Xvoid twalk(root, action)		/* Walk the nodes of a tree */
Xnode	*root;			/* Root of the tree to be walked */
Xvoid	(*action)();		/* Function to be called at each node */
X{
X    if (root != (node *)0 && action != (void(*)())0)
X	trecurse(root, action, 0);
X}
X
X/* tsearch.c ends here */
END_OF_tsearch.c
if test 3509 -ne `wc -c <tsearch.c`; then
    echo shar: \"tsearch.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 5\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 589-7930
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny     attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752

lenny@icus.islp.ny.us (Lenny Tropiano) (08/03/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 5)."
# Contents:  getdents.c string.3 tsearch.3c
# Wrapped by lenny@icus on Wed Aug  2 21:40:33 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f getdents.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"getdents.c\"
else
echo shar: Extracting \"getdents.c\" \(8062 characters\)
sed "s/^X//" >getdents.c <<'END_OF_getdents.c'
X/*
X	getdents -- get directory entries in a file system independent format
X			(SVR3 system call emulation)
X
X	last edit:	15-Feb-1988	D A Gwyn
X
X	This single source file supports several different methods of
X	getting directory entries from the operating system.  Define
X	whichever one of the following describes your system:
X
X	UFS	original UNIX filesystem (14-character name limit)
X	BFS	4.2BSD (also 4.3BSD) native filesystem (long names)
X	NFS	getdirentries() system call
X
X	Also define any of the following that are pertinent:
X
X	ATT_SPEC	check user buffer address for longword alignment
X	BSD_SYSV	BRL UNIX System V emulation environment on 4.nBSD
X	UNK		have _getdents() system call, but kernel may not
X			support it
X      UW_NFS          You are running an NFS filesystem with an
X                      underlying 4.2 BSD filesystem.  This is true
X                      in particular if you running the NFS port from
X                      the University of Wisconsin.
X
X	If your C library has a getdents() system call interface, but you
X	can't count on all kernels on which your application binaries may
X	run to support it, change the system call interface name to
X	_getdents() and define "UNK" to enable the system-call validity
X	test in this "wrapper" around _getdents().
X
X	If your system has a getdents() system call that is guaranteed 
X	to always work, you shouldn't be using this source file at all.
X*/
X
X#define UFS
X#define ATT_SPEC
X
X#include	<sys/errno.h>
X#include	<sys/types.h>
X#ifdef BSD_SYSV
X#include	<sys/_dir.h>		/* BSD flavor, not System V */
X#else
X#include	<sys/dir.h>
X#undef	MAXNAMLEN			/* avoid conflict with SVR3 */
X	/* Good thing we don't need to use the DIRSIZ() macro! */
X#ifdef d_ino				/* 4.3BSD/NFS using d_fileno */
X#undef	d_ino				/* (not absolutely necessary) */
X#else
X#define	d_fileno	d_ino		/* (struct direct) member */
X#endif
X#endif
X#include	<sys/dirent.h>
X#include	<sys/stat.h>
X#ifdef UNK
X#ifndef UFS
X#include "***** ERROR ***** UNK applies only to UFS"
X/* One could do something similar for getdirentries(), but I didn't bother. */
X#endif
X#include	<signal.h>
X#endif
X
X#if defined(UFS) + defined(BFS) + defined(NFS) != 1	/* sanity check */
X#include "***** ERROR ***** exactly one of UFS, BFS, or NFS must be defined"
X#endif
X
X#ifdef BSD_SYSV
Xstruct dirent	__dirent;		/* (just for the DIRENTBASESIZ macro) */
X#endif
X
X#ifdef UFS
X#define	RecLen( dp )	(sizeof(struct direct))	/* fixed-length entries */
X#else	/* BFS || NFS */
X#define	RecLen( dp )	((dp)->d_reclen)	/* variable-length entries */
X#endif
X
X#ifdef NFS
X#ifdef BSD_SYSV
X#define	getdirentries	_getdirentries	/* package hides this system call */
X#endif
Xextern int	getdirentries();
Xstatic long	dummy;			/* getdirentries() needs basep */
X#define	GetBlock( fd, buf, n )	getdirentries( fd, buf, (unsigned)n, &dummy )
X#else	/* UFS || BFS */
X#ifdef BSD_SYSV
X#define read	_read			/* avoid emulation overhead */
X#endif
Xextern int	read();
X#define	GetBlock( fd, buf, n )	read( fd, buf, (unsigned)n )
X#endif
X
X#ifdef UNK
Xextern int	_getdents();		/* actual system call */
X#endif
X
Xextern char	*strncpy();
Xextern int	fstat();
Xextern off_t	lseek();
X
Xextern int	errno;
X
X#ifndef DIRBLKSIZ
X#define	DIRBLKSIZ	4096		/* directory file read buffer size */
X#endif
X
X#ifndef NULL
X#define	NULL	0
X#endif
X
X#ifndef SEEK_CUR
X#define	SEEK_CUR	1
X#endif
X
X#ifndef S_ISDIR				/* macro to test for directory file */
X#define	S_ISDIR( mode )		(((mode) & S_IFMT) == S_IFDIR)
X#endif
X
X#ifdef UFS
X
X/*
X	The following routine is necessary to handle DIRSIZ-long entry names.
X	Thanks to Richard Todd for pointing this out.
X*/
X
Xstatic int
XNameLen( name )				/* return # chars in embedded name */
X	char		name[];		/* -> name embedded in struct direct */
X	{
X	register char	*s;		/* -> name[.] */
X	register char	*stop = &name[DIRSIZ];	/* -> past end of name field */
X
X	for ( s = &name[1];		/* (empty names are impossible) */
X	      *s != '\0'		/* not NUL terminator */
X	   && ++s < stop;		/* < DIRSIZ characters scanned */
X	    )
X		;
X
X	return s - name;		/* # valid characters in name */
X	}
X
X#else	/* BFS || NFS */
X
Xextern int	strlen();
X
X#define	NameLen( name )	strlen( name )	/* names are always NUL-terminated */
X
X#endif
X
X#ifdef UNK
Xstatic enum	{ maybe, no, yes }	state = maybe;
X					/* does _getdents() work? */
X
X/*ARGSUSED*/
Xstatic void
Xsig_catch( sig )
X	int	sig;			/* must be SIGSYS */
X	{
X	state = no;			/* attempted _getdents() faulted */
X	}
X#endif
X
Xint
Xgetdents( fildes, buf, nbyte )		/* returns # bytes read;
X					   0 on EOF, -1 on error */
X	int			fildes;	/* directory file descriptor */
X	char			*buf;	/* where to put the (struct dirent)s */
X	unsigned		nbyte;	/* size of buf[] */
X	{
X	int			serrno;	/* entry errno */
X	off_t			offset;	/* initial directory file offset */
X	struct stat		statb;	/* fstat() info */
X	union	{
X		char		dblk[DIRBLKSIZ
X#ifdef UFS
X				     +1	/* for last entry name terminator */
X#endif
X				    ];
X					/* directory file block buffer */
X		struct direct	dummy;	/* just for alignment */
X		}	u;		/* (avoids having to malloc()) */
X	register struct direct	*dp;	/* -> u.dblk[.] */
X	register struct dirent	*bp;	/* -> buf[.] */
X
X#ifdef UNK
X	switch ( state )
X		{
X		void		(*shdlr)();	/* entry SIGSYS handler */
X		register int	retval;	/* return from _getdents() if any */
X
X	case yes:			/* _getdents() is known to work */
X		return _getdents( fildes, buf, nbyte );
X
X	case maybe:			/* first time only */
X		shdlr = signal( SIGSYS, sig_catch );
X		retval = _getdents( fildes, buf, nbyte );	/* try it */
X		(void)signal( SIGSYS, shdlr );
X
X		if ( state == maybe )	/* SIGSYS did not occur */
X			{
X			state = yes;	/* so _getdents() must have worked */
X			return retval;
X			}
X		/* else fall through into emulation */
X
X/*	case no:	/* fall through into emulation */
X		}
X#endif
X
X	if ( buf == NULL
X#ifdef ATT_SPEC
X	  || (unsigned long)buf % sizeof(long) != 0	/* ugh */
X#endif
X	   )	{
X		errno = EFAULT;		/* invalid pointer */
X		return -1;
X		}
X
X	if ( fstat( fildes, &statb ) != 0 )
X		return -1;		/* errno set by fstat() */
X
X	if ( !S_ISDIR( statb.st_mode ) )
X		{
X		errno = ENOTDIR;	/* not a directory */
X		return -1;
X		}
X
X	if ( (offset = lseek( fildes, (off_t)0, SEEK_CUR )) < 0 )
X		return -1;		/* errno set by lseek() */
X
X#ifdef BFS				/* no telling what remote hosts do */
X	if ( (unsigned long)offset % DIRBLKSIZ != 0 )
X		{
X		errno = ENOENT;		/* file pointer probably misaligned */
X		return -1;
X		}
X#endif
X
X	serrno = errno;			/* save entry errno */
X
X	for ( bp = (struct dirent *)buf; bp == (struct dirent *)buf; )
X		{			/* convert next directory block */
X		int	size;
X
X		do	size = GetBlock( fildes, u.dblk, DIRBLKSIZ );
X		while ( size == -1 && errno == EINTR );
X
X		if ( size <= 0 )
X			return size;	/* EOF or error (EBADF) */
X
X		for ( dp = (struct direct *)u.dblk;
X		      (char *)dp < &u.dblk[size];
X		      dp = (struct direct *)((char *)dp + RecLen( dp ))
X		    )	{
X#ifndef UFS
X			if ( dp->d_reclen <= 0 )
X				{
X				errno = EIO;	/* corrupted directory */
X				return -1;
X				}
X#endif
X
X			if ( dp->d_fileno != 0 )
X				{	/* non-empty; copy to user buffer */
X				register int	reclen =
X					DIRENTSIZ( NameLen( dp->d_name ) );
X
X				if ( (char *)bp + reclen > &buf[nbyte] )
X					{
X					errno = EINVAL;
X					return -1;	/* buf too small */
X					}
X
X				bp->d_ino = dp->d_fileno;
X				bp->d_off = offset + ((char *)dp - u.dblk);
X				bp->d_reclen = reclen;
X
X				{
X#ifdef UFS
X				/* Is the following kludge ugly?  You bet. */
X
X				register char	save = dp->d_name[DIRSIZ];
X					/* save original data */
X
X				dp->d_name[DIRSIZ] = '\0';
X					/* ensure NUL termination */
X#endif
X				(void)strncpy( bp->d_name, dp->d_name,
X					       reclen - DIRENTBASESIZ
X					     );	/* adds NUL padding */
X#ifdef UFS
X				dp->d_name[DIRSIZ] = save;
X					/* restore original data */
X#endif
X				}
X
X				bp = (struct dirent *)((char *)bp + reclen);
X				}
X			}
X
X#ifndef UW_NFS
X#if !(defined(BFS) || defined(sun))	/* 4.2BSD screwed up; fixed in 4.3BSD */
X		if ( (char *)dp > &u.dblk[size] )
X			{
X			errno = EIO;	/* corrupted directory */
X			return -1;
X			}
X#endif
X#endif
X		}
X
X	errno = serrno;			/* restore entry errno */
X	return (char *)bp - buf;	/* return # bytes read */
X	}
END_OF_getdents.c
if test 8062 -ne `wc -c <getdents.c`; then
    echo shar: \"getdents.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f string.3 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"string.3\"
else
echo shar: Extracting \"string.3\" \(6925 characters\)
sed "s/^X//" >string.3 <<'END_OF_string.3'
X.TH STRING 3 "ANSI/POSIX Standard"
X.SH NAME
Xstrcat, strdup, strncat, strcmp, strncmp, strcpy,
Xstrncpy, strlen, strchr, strrchr, strpbrk, strspn, strcspn,
Xstrtok \- string operations
X.SH SYNOPSIS
X.B #include <string.h>
X.br
X.B #include <sys/types.h>
X.P
X.B "char \(**strcat(s1, s2)"
X.br
X.B "char \(**s1, \(**s2;"
X.P
X.B "char \(**strdup(s1)"
X.br
X.B "char \(**s1;"
X.P
X.B "char \(**strncat(s1, s2, n)"
X.br
X.B "char \(**s1, \(**s2;"
X.br
X.B "size_t n;"
X.P
X.B "int strcmp(s1, s2)"
X.br
X.B "char \(**s1, \(**s2;"
X.P
X.B "strncmp(s1, s2, n)"
X.br
X.B "char \(**s1, \(**s2;"
X.br
X.B "size_t n;"
X.P
X.B "char \(**strcpy(s1, s2)"
X.br
X.B "char \(**s1, \(**s2;"
X.P
X.B "char \(**strncpy(s1, s2, n)"
X.br
X.B "char \(**s1, \(**s2;"
X.br
X.B "size_t n;"
X.P
X.B "int strlen(s)"
X.br
X.B "char \(**s;"
X.P
X.B "char \(**strchr(s, c)"
X.br
X.B "char \(**s;"
X.br
X.B "int c;"
X.P
X.B "char \(**strrchr(s, c)"
X.br
X.B "char \(**s;"
X.br
X.B "int c;"
X.P
X.B "char \(**strpbrk(s1, s2)"
X.br
X.B "char \(**s1, s2;"
X.P
X.B "int strspn(s1, s2)"
X.br
X.B "char \(**s1, \(**s2;"
X.P
X.B "int strcspn(s1, s2)"
X.br
X.B "char \(**s1, \(**s2;"
X.P
X.B "char \(**strtok(s1, s2)"
X.br
X.B "char \(**s1, s2;"
X.br
X.SH DESCRIPTION
XThe arguments \fBs1\fR, \fBs2\fR, and s point to strings (arrays of
Xcharacters terminated by a null character). The functions
Xstrcat, strncat, strcpy, and strncpy all alter \fBs1\fR. These
Xfunctions do not check for overflow of the array pointed to
Xby \fBs1\fR.
X.P
X\fBStrcat\fR appends a copy of string \fBs2\fR to the end of string \fBs1\fR.
X.P
X\fBStrdup\fR returns a pointer to a new string that is a duplicate
Xof the string pointed to by \fBs1\fR. The space for the new
Xstring is obtained using malloc(3C). If the new string
Xcannot be created, a null pointer is returned.
X.P
X\fBStrncat\fR appends at most n characters.  Each returns a
Xpointer to the null-terminated result.
X.P
X\fBStrcmp\fR compares its arguments and returns an integer less
Xthan, equal to, or greater than 0, according as \fBs1\fR is
Xlexicographically less than, equal to, or greater than \fBs2\fR.
X\fBStrncmp\fR makes the same comparison but looks at, at most, n
Xcharacters.
X.P
X\fBStrcpy\fR copies string \fBs2\fR to \fBs1\fR, stopping after the null
Xcharacter has been copied. \fBStrncpy\fR copies exactly n
Xcharacters, truncating \fBs2\fR or adding null characters to \fBs1\fR if
Xnecessary. The result will not be null-terminated if the
Xlength of \fBs2\fR is n or more. Each function returns \fBs1\fR.
X.P
X\fBStrlen\fR returns the number of characters in s, not including
Xthe terminating null character.
X.P
X\fBStrchr\fR (\fBstrrchr\fR) returns a pointer to the first (last)
Xoccurrence of character c in string s, or a NULL pointer if
Xc does not occur in the string. The null character
Xterminating a string is considered to be part of the string.
X.P
X\fBStrpbrk\fR returns a pointer to the first occurrence in string
X\fBS1\fR of any character from string \fBs2\fR, or a NULL pointer if no
Xcharacter from \fBs2\fR exists in \fBs1\fR.
X.P
X\fBStrspn\fR (\fBstrcspn\fR) returns the length of the initial segment
Xof string \fBs1\fR, which consists entirely of characters from
X(not from) string \fBs2\fR.
X.P
X\fBStrtok\fR considers the string \fBs1\fR to consist of a sequence of
Xzero or more text tokens separated by spans of one or more
Xcharacters from the separator string \fBs2\fR. The first call
X(with pointer \fBs1\fR specified) returns a pointer to the first
Xcharacter of the first token, and will have written a null
Xcharacter into \fBs1\fR immediately following the returned token.
XThe function keeps track of its position in the string
Xbetween separate calls, so that subsequent calls (which must
Xbe made with the first argument a NULL pointer) will work
Xthrough the string \fBs1\fR immediately following that token. In
Xthis way, subsequent calls will work through the string \fBs1\fR
Xuntil no tokens remain. The separator string \fBs2\fR may be
Xdifferent from call to call. When no token remains in \fBs1\fR, a
XNULL pointer is returned.
X.P
XFor user convenience, all these functions are declared in
Xthe optional <string.h> header file.
X.SH SEE ALSO
Xmalloc(3C), malloc(3X).
X.SH CAVEATS
X\fBStrcmp\fR and \fBstrncmp\fR are implemented by using the most natural
Xcharacter comparison on the machine. Thus, the sign of the
Xvalue returned when one of the characters has its high-order
Xbit set is not the same in all implementations and should
Xnot be relied upon.
X.P
XCharacter movement is performed differently in different
Ximplementations. Thus, overlapping moves may yield
Xsurprises.!STUFFY!FUNK!
Xchmod 644 src/D.posix/string.3
Xecho Extracting src/D.posix/getopt.3c
Xsed >src/D.posix/getopt.3c <<'!STUFFY!FUNK!' -e 's///'
X.TH GETOPT 3C "Standard Extensions"
X.SH NAME
Xgetopt \- parse arguments from an argument token vector
X.SH SYNOPSIS
X.B int getopt (argc, argv, optstring)
X.br
X.B int argc;
X.br
X.B char \(**\(**argv, \(**opstring;
X.PP
X.B extern char \(**optarg;
X.br
X.B extern int optind, opterr;
X.SH DESCRIPTION
X.I Getopt
Xreturns the next option letter in
X.I argv
Xthat matches
Xa letter in
X.IR optstring .
X.I Optstring
Xis a string of recognized option letters. If a letter is followed by a colon,
Xthe option is expected to have an argument that may or may not be separated
Xfrom it by white space.
X.I Optarg
Xis set to point to the start of the option argument on return from
X.IR getopt .
X.PP
X.I Getopt
Xplaces in
X.I optind
Xthe
X.I argv
Xindex of the next argument to be processed. Because
X.I optind
Xis external, it is normally initialized to zero automatically before the first
Xcall to
X.IR getopt .
X.PP
XWhen all options have been processed (i.e., up to the first non-option
Xargument),
X.I getopt
Xreturns
X.SM
X.BR EOF .
XThe special option
X.B \-\-
Xmay be used to delimit the end of the options;
X.SM
X.B EOF
Xwill be returned, and
X.B \-\-
Xwill be skipped.
X.SH DIAGNOSTICS
X.I Getopt
Xprints an error message on
X.I stderr
Xand returns a
Xquestion mark
X.RB ( ? )
Xwhen it encounters an option letter not included in
X.IR optstring .
XThis error message may be disabled by setting 
X.I opterr
Xto a non-zero value.
X.SH EXAMPLE
XThe following code fragment shows how one might process the arguments for a
Xcommand that can take the mutually exclusive options
X.B a
Xand
X.BR b ,
Xand the options
X.B f
Xand
X.BR o ,
Xboth of which require arguments:
X.PP
X.RS
X.nf
X.ss 18
Xmain (argc, argv)
Xint argc;
Xchar \(**\(**argv;
X{
X	int c;
X	extern char \(**optarg;
X	extern int optind;
X	\&\f3.\fP
X	\&\f3.\fP
X	\&\f3.\fP
X	while ((c = getopt(argc, argv, "abf:o:")) != \s-1EOF\s+1)
X		switch (c) {
X		case \(fma\(fm:
X			if (bflg)
X				errflg++;
X			else
X				aflg++;
X			break;
X		case \(fmb\(fm:
X			if (aflg)
X				errflg++;
X			else
X				bproc( );
X			break;
X		case \(fmf\(fm:
X			ifile = optarg;
X			break;
X		case \(fmo\(fm:
X			ofile = optarg;
X			break;
X		case \(fm?\(fm:
X			errflg++;
X		}
X	if (errflg) {
X		fprintf(stderr, "usage: . . . ");
X		exit (2);
X	}
X	for ( ; optind < argc; optind++) {
X		if (access(argv[optind], 4)) {
X	\&\f3.\fP
X	\&\f3.\fP
X	\&\f3.\fP
X}
X.ss 12
X.fi
END_OF_string.3
if test 6925 -ne `wc -c <string.3`; then
    echo shar: \"string.3\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tsearch.3c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tsearch.3c\"
else
echo shar: Extracting \"tsearch.3c\" \(6251 characters\)
sed "s/^X//" >tsearch.3c <<'END_OF_tsearch.3c'
X.TH TSEARCH 3C "Standard Extension"
X.SH NAME
Xtsearch, tfind, tdelete, twalk \- manipulate binary search trees
X.SH SYNOPSIS
X.B #include <search.h>
X.PP
X.B "char \(**tsearch ((char \(**) key, (char \(**\(**) rootp, compar)"
X.br
X.B int (\(**compar)( );
X.PP
X.B "char \(**tfind ((char \(**) key, (char \(**\(**) rootp, compar)"
X.br
X.B int (\(**compar)( );
X.PP
X.B "char \(**tdelete ((char \(**) key, (char \(**\(**) rootp, compar)"
X.br
X.B int (\(**compar)( );
X.PP
X.B "void twalk ((char \(**) root, action)"
X.br
X.B void (\(**action)( );
X.SH DESCRIPTION
X.I Tsearch,
X.I tfind,
X.I tdelete,
Xand
X.I twalk
Xare routines for manipulating binary search trees.
XThey are generalized from Knuth (6.2.2) Algorithms T and D.
XAll comparisons are done with a user-supplied hook.
XThis routine is called with two arguments,
Xthe pointers to the elements being compared.
XIt returns an integer less than, equal to,
Xor greater than 0, according to whether the first argument
Xis to be considered less than, equal to or greater than the
Xsecond argument (this is the convention used by
X.IR strncmp (3)).
XThe comparison function need not compare every byte,
Xso arbitrary data may be contained in the elements
Xin addition to the key values being compared. 
X.PP
X.I Tsearch
Xis used to build and access the tree.
X.B Key
Xis a pointer to a datum to be accessed or stored.
XIf there is a datum in the tree
Xequal to \(**key (the value pointed to by key),
Xa pointer to this found datum is returned.
XOtherwise, \(**key is inserted, and a pointer to it returned.
XOnly pointers are copied, so the calling routine must store the data.
X.B Rootp
Xmust point to a variable that points to the root
Xof the tree.
XA
X.SM NULL
Xvalue for the variable pointed to by
X.B rootp
Xdenotes an empty tree; in this case,
Xthe variable will be set to point to the datum
Xwhich will be at the root of the new tree.
X.PP
XLike
X.IR tsearch ,
X.I tfind
Xwill search for a datum in the tree, returning a pointer
Xto it if found.
XHowever, if it is not found,
X.I tfind
Xwill return a
X.SM NULL
Xpointer.
XThe arguments for
X.I tfind
Xare the same as for
X.IR tsearch .
X.PP
X.I Tdelete
Xdeletes a node from a binary search tree.
XThe arguments are the same as for 
X.IR tsearch .
XThe variable pointed to by
X.B rootp
Xwill be changed if the deleted node was the root of the tree.
X.I Tdelete
Xreturns a pointer to the parent of the deleted node,
Xor a
X.SM NULL
Xpointer if the node is not found.
X.PP
X.I Twalk
Xtraverses a binary search tree.
X.B Root
Xis the root of the tree to be traversed.
X(Any node in a tree may be used as the root for a walk below that node.)
X.I Action
Xis the name of a routine
Xto be invoked at each node.
XThis routine is, in turn,
Xcalled with three arguments.
XThe first argument is the address of the node being visited.
XThe second argument is a value from an enumeration data type
X.I "typedef enum { preorder, postorder, endorder, leaf }"
X.SM
X.I VISIT;
X(defined in the 
X.RI < search.h >
Xheader file),
Xdepending on whether this is the first, second or third
Xtime that the node has been visited
X(during a depth-first, left-to-right traversal of the tree),
Xor whether the node is a leaf.
XThe third argument is the level of the node
Xin the tree, with the root being level zero.
X.PP
XThe pointers to the key and the root of the tree should be
Xof type pointer-to-element,
Xand cast to type pointer-to-character.
XSimilarly, although declared as type pointer-to-character,
Xthe value returned should be cast into type pointer-to-element.
X.SH EXAMPLE
XThe following code reads in strings and
Xstores structures containing a pointer to each string
Xand a count of its length.
XIt then walks the tree, printing out the stored strings
Xand their lengths in alphabetical order.
X.PP
X.RS
X.nf
X.ss 18
X#include <search.h>
X#include <stdio.h>
X
Xstruct node {		/\(** pointers to these are stored in the tree \(**/
X	char \(**string;
X	int length;
X};
Xchar string_space[10000];	/\(** space to store strings \(**/
Xstruct node nodes[500];		/\(** nodes to store \(**/
Xstruct node \(**root = \s-1NULL\s+1;	/\(** this points to the root \(**/
X
Xmain( )
X{
X	char \(**strptr = string_space;
X	struct node \(**nodeptr = nodes;
X	void print_node( ), twalk( );
X	int i = 0, node_compare( );
X
X	while (gets(strptr) != \s-1NULL\s+1 && i++ < 500)  {
X		/\(** set node \(**/
X		nodeptr\(mi>string = strptr;
X		nodeptr\(mi>length = strlen(strptr);
X		/\(** put node into the tree \(**/
X		(void) tsearch((char \(**)nodeptr, &root,
X			  node_compare);
X		/\(** adjust pointers, so we don't overwrite tree \(**/
X		strptr += nodeptr\(mi>length + 1;
X		nodeptr++;
X	}
X	twalk(root, print_node);
X}
X/\(**
X	This routine compares two nodes, based on an
X	alphabetical ordering of the string field.
X\(**/
Xint
Xnode_compare(node1, node2)
Xstruct node \(**node1, \(**node2;
X{
X	return strcmp(node1\(mi>string, node2\(mi>string);
X}
X/\(**
X	This routine prints out a node, the first time
X	twalk encounters it.
X\(**/
X.bp
Xvoid
Xprint_node(node, order, level)
Xstruct node \(**\(**node;
X\s-1VISIT\s+1 order;
Xint level;
X{
X	if (order == preorder \(or\(or order == leaf)  {
X		(void)printf("string = %20s,  length = %d\en",
X			(\(**node)\(mi>string, (\(**node)\(mi>length);
X	}
X}
X.fi
X.RE
X.SH SEE ALSO
Xbsearch(3C), hsearch(3C), lsearch(3C).
X.SH DIAGNOSTICS
XA
X.SM NULL
Xpointer is returned by 
X.I tsearch
Xif there is not enough space available to create a new node.
X.br
XA
X.SM NULL
Xpointer is returned by
X.I tsearch,
X.I tfind
Xand
X.I tdelete
Xif
X.B rootp
Xis
X.SM NULL
Xon entry.
X.br
XIf the datum is found, both 
X.I tsearch
Xand 
X.I tfind
Xreturn a pointer to it.
XIf not, 
X.I tfind
Xreturns \s-1NULL\s+1, and 
X.I tsearch
Xreturns a pointer to the inserted
Xitem.
X.SH WARNINGS
XThe
X.B root
Xargument to 
X.I twalk
Xis one level of indirection less than the
X.B rootp
Xarguments to
X.I tsearch
Xand
X.IR tdelete .
X.br
XThere are two nomenclatures used to refer to the order in which
Xtree nodes are visited.
X.I Tsearch
Xuses preorder, postorder and endorder to respectively refer to
Xvisting a node before any of its children, after its left child
Xand before its right, and after both its children.
XThe alternate nomenclature uses preorder, inorder and postorder to
Xrefer to the same visits, which could result in some confusion over
Xthe meaning of postorder.
X.SH BUGS
XIf the calling function alters the pointer to the
Xroot, results are unpredictable.
END_OF_tsearch.3c
if test 6251 -ne `wc -c <tsearch.3c`; then
    echo shar: \"tsearch.3c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 5\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 589-7930
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny     attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752

lenny@icus.islp.ny.us (Lenny Tropiano) (08/03/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 5)."
# Contents:  Makeposix
# Wrapped by lenny@icus on Wed Aug  2 21:40:35 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makeposix -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makeposix\"
else
echo shar: Extracting \"Makeposix\" \(16003 characters\)
sed "s/^X//" >Makeposix <<'END_OF_Makeposix'
X: use /bin/sh
X# Makeposix -- add a POSIX-conformant library to your system
X
X: a sanity check
XPATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc'
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh $0; kill $$)
X
X(alias) >/dev/null 2>&1 && \
X    echo "(Some versions of ksh blow up on Makeposix, especially on" && \
X    echo "exotic machines. If yours does, try the Bourne shell instead.)"
X
XLIBC=/lib/libc.a
X
X# . ../configsys.sh
X
Xcase $1 in '') system="$species" ;; *) system=$1 ;; esac
X
Xif test -f /usr/lib/lint/llib-lc
Xthen
X	LINTLIB=/usr/lib/lint/llib-lc
Xelse
X	LINTLIB=/usr/lib/llib-lc
Xfi
X
Xcat <<EOF >/dev/null
XThis script generates a Makefile and lint library patch for your system that,
Xwhen applied, will move it a good part of the way towards conformance with the
XPOSIX/SVID/X3J11 C library standards.
X
XThis script assumes
X
X	1) that your C library is at $LIBC
X	2) that your lint library is at $LINTLIB
X
XIf either of these assumptions is incorrect, you'll need to edit the shell
Xvariable assignments at the beginning of the script.
X
XHit interrupt key to quit, return key to continue.
XEOF
X: read stuff
X
XUSG=-DUSG
X
XHDS=/usr/include
XLINTPATCH=posix.lint
X
X#
X# All pieces of libposix.a must be listed here
X#
XSTRINGS="strchr.o strrchr.o strcspn.o strpbrk.o strspn.o strtok.o strdup.o"
XMEM="memccpy.o memcpy.o memcmp.o memchr.o memset.o"
XDIRENT="seekdir.o readdir.o getdents.o closedir.o opendir.o rewinddir.o telldir.o"
XMKDIR="mkdir.o rmdir.o"
XSEARCH="lsearch.o lfind.o tsearch.o tfind.o bsearch.o"
XMISCOBJS="ssignal.o strtol.o getopt.o rename.o putpwent.o"
X
Xtrap 'rm -f /tmp/needed$$ /tmp/allobjs$$ /tmp/present$$ /tmp/remove$$; exit 0' 0 1 2 15
X
X#
X# ALLOBJS should list all possible libposix.a parts, with one trailing space
X#
XALLOBJS="$STRINGS $MEM $SEARCH $MISCOBJS "
X
X#
X# Put support modules that shouldn't show in the feature lists here
X#
XSUPPORT=getdents.o
X
Xecho $ALLOBJS | tr " " "\012" >/tmp/allobjs$$
Xecho " "
Xecho "Facilities available in the POSIX/SVID/X3J11 compatibility library:"
Xsort /tmp/allobjs$$ | grep -v $SUPPORT | pr -5 -t -l1
X
Xcase $system in SVR3)
X	echo " "
X	echo "You said you're running $system, I'll assume you have:"
X	echo $DIRENT | tr " " "\012" >/tmp/present$$
X	pr -5 -t -l1 </tmp/present$$ 
X;; 
X4.3BSD|BSD4_3)
X	echo " "
X	echo "You said you're running $system, I'll assume you have:"
X	echo $MEM | tr " " "\012" > /tmp/present$$
X	pr -5 -t -l1 </tmp/present$$ 
X	USG=
X;;
X4.[12]BSD|BSD4_[12])
X	USG=
X;; esac
Xecho " "
Xecho "Analyzing your C library, please wait..."
Xar t $LIBC $ALLOBJS 2>/dev/null >>/tmp/present$$
Xsort -u /tmp/present$$ -o /tmp/present$$
Xecho "POSIX/SVID/X3J11 library facilities already present on your system:"
Xgrep -v $SUPPORT </tmp/present$$ | pr -5 -t -l1 2>/dev/null 
Xecho " "
X: echo "Hit interrupt key to quit, return key to continue."
X: read stuff
X
Xif grep rewinddir /tmp/present$$ >/dev/null 2>&1
Xthen
X	cp /dev/null /tmp/needed$$
Xelse
X	echo $DIRENT | tr " " "\012" >/tmp/needed$$
X	echo "You don't have rewinddir, I'll assume you need the new dirent"
X	echo "package."
X	echo " "
Xfi
X
X# Extract already-present faculities from allobjs, preserving sort order
Xsed -e "/^.*$/s//\/&\/d/" </tmp/present$$ >/tmp/remove$$
Xsed -f /tmp/remove$$ </tmp/allobjs$$ >>/tmp/needed$$
Xecho " "
Xecho "POSIX/SVID/X3J11 library facilities that should be installed:"
Xsort /tmp/needed$$ | pr -5 -t -l1 2>/dev/null 
Xecho " "
X: echo "Hit interrupt key to quit, return key to continue."
X: read stuff
X
X# set corresponding shell variable for each object file needed
Xfor x in `tr "\012" " " </tmp/needed$$`
Xdo
X	set eval `expr $x : "\(.*\).o"`"=y" 
Xdone
X
Xecho " "
Xecho "A copy of your lint patch will be written to $LINTPATCH."
Xecho "/* POSIX library extensions */" >$LINTPATCH
X
Xif grep lockf $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	lockf(fd, fn, sz) int fd, fn; long sz; {return 0;}" >>$LINTPATCH
Xfi
Xif [ ! -f $HDS/dirent.h ]
Xthen
X	dirent='yes'
X	man4list="$man4list dirent.4"
Xfi
Xif grep getdents $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse 
X	cat >>$LINTPATCH <<EOF
X/* DIRECTORY(3C) */
X#include <dirent.h>
Xint	getdents(f, b, n) int f; char *b; unsigned n; { return 0; }
XEOF
Xfi
X
Xif grep closedir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	closedir(p) DIR *p; { return 0; }" >>$LINTPATCH
Xfi
Xif grep opendir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "DIR	*opendir(f) char *f; {return (DIR *)NULL;}" >>$LINTPATCH
Xfi
Xif grep readdir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "struct dirent	*readdir(p) DIR *p; {return (struct dirent*)NULL;}" >>$LINTPATCH
Xfi
Xif grep seekdir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "void	seekdir(p, l) DIR *p; long l; {}" >>$LINTPATCH
Xfi
Xif grep telldir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "long	telldir(p) DIR *p; {return 1L;}" >>$LINTPATCH
Xfi
X
Xif grep mkdir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "/* MKDIR(3) */" >>$LINTPATCH
X	echo "int	mkdir(s, p) char *s; int p; {return (0);}" >>$LINTPATCH
X	man3list="$man3list mkdir.3"
Xfi
Xif grep rmdir $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "/* RMDIR(3) */" >>$LINTPATCH
X	echo "int	rmdir(s) char *s; {return (0);}" >>$LINTPATCH
X	man3list="$man3list rmdir.3"
Xfi
X
Xif grep str /tmp/needed$$ >/dev/null 2>&1
Xthen
X	echo "/* STRING(3C) */" >>$LINTPATCH
X	strings='yes'
X	man3list="$man3list string.3"
Xfi
Xif grep strcat $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strcat(a, b) char *a, *b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strncat $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strncat(a, b, n) char *a, *b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strcmp $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	strcmp(a, b) char *a, *b; { return (0); }" >>$LINTPATCH
Xfi
Xif grep strncmp $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	strncmp(a, b, n) char *a, *b; { return (n); }" >>$LINTPATCH
Xfi
Xif grep strcpy $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strcpy(a, b) char *a, *b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strncpy $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strncpy(a, b, n) char *a, *b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strlen $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	strlen(s) char *s; { return (0); }" >>$LINTPATCH
Xfi
Xif grep strchr $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strchr(a, b) char *a, b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strrchr $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strrchr(a, b) char *a, b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strpbrk $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strpbrk(a, b) char *a, *b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strspn $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	strspn(a, b) char *a, *b; { return (0); }" >>$LINTPATCH
Xfi
Xif grep strcspn $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	strcspn(a, b) char *a, *b; { return (0); }" >>$LINTPATCH
Xfi
Xif grep strtok $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strtok(a, b) char *a, *b; { return (a); }" >>$LINTPATCH
Xfi
Xif grep strdup $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *	strdup(a) char *a; { return (a); }" >>$LINTPATCH
Xfi
X
Xif grep str /tmp/needed$$ >/dev/null 2>&1
Xthen
X	echo "/* MEMORY(3C) */" >>$LINTPATCH
X	memory='yes'
X	man3list="$man3list memory.3"
Xfi
Xif [ X$memccpy != X ]
Xthen
X	echo "char	*memccpy(a,b,c,n) char *a,*b; {return(a);}" >>$LINTPATCH
Xfi
Xif [ X$memchr != X ]
Xthen
X	echo "char	*memchr(s,c,n) char *s; {return (s);}" >>$LINTPATCH
Xfi
Xif [ X$memcmp != X ]
Xthen
X	echo "int	memcmp(a, b, n) char *a, *b; {return(n);}" >>$LINTPATCH
Xfi
Xif [ X$memcpy != X ]
Xthen
X	echo "char	*memcpy(a,b,n) char *a, *b; {return (a);}" >>$LINTPATCH
Xfi
Xif [ X$memset != X ]
Xthen
X	echo "char	*memset(s,c,n) char *s; {return (s);}" >>$LINTPATCH
Xfi
X
Xif grep lsearch $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "/* LSEARCH(3C) */" >>$LINTPATCH
X	echo "char *lsearch(k,b,n,w,c) char *k,*b; unsigned *n,w; int (*c)(); {return(k);}" >>$LINTPATCH
Xfi
Xif grep lfind $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *lfind(k,b,n,w,c) char *k,*b; unsigned *n,w; int (*c)();{return(k); }" >>$LINTPATCH
Xfi
X#include <search.h>
Xif grep bsearch /tmp/needed$$ >/dev/null 2>&1
Xthen
X	echo "/* BSEARCH(3C) */" >>$LINTPATCH
X	search='yes'
X	man3list="$man3list bsearch.3c"
Xfi
Xif grep bsearch $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *bsearch(k,b,n,w,c) char *k,*b; unsigned n,w; int (*c)();{return(k);}" >>$LINTPATCH
Xfi
Xif grep tsearch /tmp/needed$$ >/dev/null 2>&1
Xthen
X	echo "/* TSEARCH(3C) */" >>$LINTPATCH
X	search='yes'
X	man3list="$man3list tsearch.3c"
Xfi
Xif grep tsearch $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *tsearch(k,r,c) char *k, **r; int (*c)(); {return(k);}" >>$LINTPATCH
Xfi
Xif grep tfind $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "char *tfind(k,r,c) char *k,**r; int (*c)(); {return(k);}" >>$LINTPATCH
Xfi
Xif grep [gs]signal $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "/* SSIGNAL(3) */" >>$LINTPATCH
X	echo "int (*ssignal(s, a))() int (*a)(); { return (a); }" >>$LINTPATCH
X	echo "int gsignal(s) {return (s);}" >>$LINTPATCH
X	man3list="$man3list ssignal.3c"
Xfi
X
Xif grep strtol $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "long	strtol(s,t,b) char *s,**t; {return(0L);}" >>$LINTPATCH
X	man3list="$man3list strtol.3c"
Xfi
Xif grep getopt $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "int	getopt(c,v,o) char **v, *o; {return(c);}" >>$LINTPATCH
X	man3list="$man3list getopt.3c"
Xfi
Xif grep rename $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "/* RENAME(3) */" >>$LINTPATCH
X	echo "int	rename(s, t) char *s, *t; {return (0);}" >>$LINTPATCH
X	man3list="$man3list rename.3c"
Xfi
Xif grep putpwent $LINTLIB >/dev/null 2>&1
Xthen
X	: do nothing
Xelse
X	echo "/* PUTPWENT(3C) */" >>$LINTPATCH
X	echo "int putpwent(s,f) struct passwd *s; FILE *f; {return(0);}" >>$LINTPATCH
X	man3list="$man3list putpwent.3c"
Xfi
X
Xcat <<EOT >/dev/null
X
XProductions that can install these changes will now be written to Makefile.
XRemember to edit out the -DUSG from the CFLAGS line if you're on a non-AT&T
XUNIX (i.e. a V7 or BSD-based version).  -DUSG will be removed for you
Xautomatically if you had specified 4.2BSD or 4.3BSD as the type of
Xyour system.  Other installation instructions will be found in a
Xleading comment in the generated Makefile. 
XEOT
Xobjlist=`tr '\012' ' ' </tmp/needed$$`
X
Xcat >Makefile <<EOF
X# This makefile will install a number of X3J11/POSIX/SVID functions in your
X# standard C library. If you have a source license, the method described
X# in DIRENT.INSTALL is recommended instead.
X#
X# To make the library:
X#	a. Edit getdents.c if necessary to define UFS, NFS or BFS.
X#
X#	b. Type 'make'. If you get errors, stop and fix them.
X#	   This will create a local copy of the code named libposix.a
X#	   which you can use for testing or install in /lib.
X#
X# To install it:
X#
X#	a. Go superuser and type 'make install'. That's all there is to it.
X#	   You may want to do 'make -n install' first so you know what it's
X#	   doing. If you don't like the default action you can edit the
X#	   Makefile.
X#
X#	b. If you don't like this option, you can put the libposix.a library
X#	   in your libraries directory and add an appropriate -I option to
X#	   your include file search path.
X#
X# Note: the implementations of strchr() and strrchr() are pure C code, so they
X# may be marginally slower than the (presumably tuned) index/rindex in V7/BSD.
X# You can #define them to index/rindex via the the preprocessor, or ar x
X# copies of the index.o and rindex.o object files, patch the function names
X# with adb and wedge the copies in.
X
XSHELL = /bin/sh
XHDS = $HDS
XMAN = /usr/man
XLIBC = $LIBC
XLINTLIB = $LINTLIB
XSTRINGS= $STRINGS
XMEM= $MEM
XDIRENT= $DIRENT
XMKDIR= $MKDIR
XSEARCH= $SEARCH
XMISCOBJS= $MISCOBJS
XPORTOBJS = ${objlist}
X# CF = -Dvoid=int		# Uncomment this for cc versions with no void
XCC = cc
XCFLAGS = -O $USG -I. \$(CF)	
X
XMAINDIR = ..
XLIBSDIR = \$(MAINDIR)
X
Xlibposix.a: \$(PORTOBJS)
X	ar lruv libposix.a \$(PORTOBJS)
X	@echo "If you're on an AT&T UNIX, ignore the next error message"
X	-ranlib libposix.a
X	(cd profiled; ar lrc ../libposix_p.a \$?)
X	@echo "If you're on an AT&T UNIX, ignore the next error message"
X	ranlib libposix_p.a
X
X.c.o:
X	\${CC} -p \${CFLAGS} -c \$*.c
X	mv \$*.o profiled/\$*.o
X	\${CC} \${CFLAGS} -c \$*.c
X
Xexport: libposix.a
X	@rm -f $(LIBSDIR)/libposix.a
X	-ln libposix.a $(LIBSDIR)
X	@rm -f $(LIBSDIR)/profiled/libposix.a
X	-ln libposix_p.a $(LIBSDIR)/profiled/libposix.a
X	@-mkdir ../sys
X	@rm -f ../sys/dirent.h
X	-ln sys.dirent.h ../sys/dirent.h
X	@rm -f ../dirent.h ../search.h ../unistd.h ../memory.h ../string.h
X	-ln dirent.h search.h unistd.h memory.h string.h ..
X
XMakefile: Makeposix posix_conf
X	Makeposix
X
Xclean:
X	rm -f libposix.a *.o posix_conf Makefile profiled/*
X
Xtestdir: testdir.c libposix.a
X	\$(CC) \$(CFLAGS) \$(LFLAGS) testdir.c libposix.a -o testdir
X
Xmkdirtest: mkdirtest.c libposix.a
X	\$(CC) \$(CFLAGS) \$(LFLAGS) mkdirtest.c libposix.a -o mkdirtest
X
XLINTPATCH = $LINTPATCH
X
X# Restore original library, lint and header files
Xrestore:
X	-cp \$(LIBC)-orig \$(LIBC)
X	-cp \$(LINTLIB)-orig \$(LINTLIB)
X	-cp \$(LINTLIB).ln-orig \$(LINTLIB).ln
X	-cp \$(HDS)/string.h-orig \$(HDS)/string.h
X	-cp \$(HDS)/memory.h-orig \$(HDS)/memory.h
X	-cp \$(HDS)/search.h-orig \$(HDS)/search.h
X
X# Recompile the lint library (AT&T SVr2 or later)
Xrelint:
X	cp \$(LINTLIB) llib-lc.c
X	lint -c llib-lc.c; rm llib-lc.c
X	mv llib-lc.ln \$(LINTLIB).ln
X
X# Make everything (for test purposes)
Xtestlib.a: $ALLOBJS
X	ar lruv testlib.a $ALLOBJS
X	@echo "If you're on an AT&T UNIX, ignore the next error message"
X	-ranlib testlib.a
X
X# Install all the portability hacks
Xinstall: \$(PORTOBJS)
XEOF
Xif [ ! -f $HDS/unistd.h ]
Xthen
X	echo "	@echo 'Installing unistd.h header file...'" >>Makefile
X	echo "	-cp unistd.h \$(HDS)/unistd.h;" >>Makefile
Xfi
Xif [ "X$dirent" != "X" ]
Xthen
X	echo "	@echo 'Installing dirent library headers...'" >>Makefile
X	echo "	-cp dirent.h \$(HDS)/dirent.h;" >>Makefile
X	echo "	-cp sys.dirent.h \$(HDS)/sys/dirent.h;" >>Makefile
Xfi
Xif [ "X$strings" != "X" ]
Xthen
X	echo "	@echo 'Installing string library headers...'" >>Makefile
X	echo "	-cp \$(HDS)/string.h \$(HDS)/string.h-orig;" >>Makefile
X	echo "	-cp string.h \$(HDS)/string.h;" >>Makefile
Xfi
Xif [ "X$memory" != "X" ]
Xthen
X	echo "	@echo 'Installing memory library headers...'" >>Makefile
X	echo "	-cp \$(HDS)/memory.h \$(HDS)/memory.h-orig;" >>Makefile
X	echo "	-cp memory.h \$(HDS)/memory.h;" >>Makefile
Xfi
Xif [ "X$search" != "X" ]
Xthen
X	echo "	@echo 'Installing search library headers...'" >>Makefile
X	echo "	-cp \$(HDS)/search.h \$(HDS)/search.h-orig;" >>Makefile
X	echo "	-cp search.h \$(HDS)/search.h;" >>Makefile
Xfi
Xcat >>Makefile <<EOF
X	@echo "Installing new C library functions..."
X	-cp \$(LIBC) \$(LIBC)-orig
X	ar lruv \$(LIBC) \$(PORTOBJS)
X	@echo "If you're on an AT&T UNIX, ignore the next error message"
X	-ranlib \$(LIBC)
X	@echo "Installing extension library manuals..."
X	-cp ${man3list} \$(MAN)/man3;
X	-cp ${man4list} \$(MAN)/man4;
X	@echo "Installing lint library additions..."
X	cp \$(LINTLIB) \$(LINTLIB)-orig
X	cp \$(LINTLIB).ln \$(LINTLIB).ln-orig
X	cat $LINTPATCH >>\$(LINTLIB)
X	@echo "Your $LINTLIB will need to be recompiled"
X	@echo "If you are on an SVr2 or later, just do 'make relint'"
XEOF
X
Xcat <<EOF >/dev/null
X
XNow type 'make' to make the library. Test productions have been
Xincluded. When you're satisfied that everything works, go root and
Xtype 'make install' (you may want to look at the Makefile to make
Xsure it's not doing anything untoward).
X
XIf you're on SVr2 or later, you will probably want to do a 'make relint'
Xafter the installation. On V7, SIII and BSD systems you'll have to work out
Xyour own way of recompiling the modified lint file.
X
XA restore production is provided to back out the changes.
XEOF
X
Xtouch posix_conf
Xmkdir profiled 2>&1 >/dev/null
X# Portability library config script ends here
END_OF_Makeposix
if test 16003 -ne `wc -c <Makeposix`; then
    echo shar: \"Makeposix\" unpacked with wrong size!
fi
chmod +x Makeposix
# end of overwriting check
fi
echo shar: End of archive 5 \(of 5\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 589-7930
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny     attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752