Path: utzoo!attcan!utgpu!watmath!uunet!ethos!att!icus!lenny From: lenny@icus.islp.ny.us (Lenny Tropiano) Newsgroups: unix-pc.sources Subject: POSIX/SVID/X3J11 standard routines (libposix.a) (Part 1 of 5) Keywords: POSIX, SVID, X3J11, dirent, News 3.0, good stuff! Message-ID: <935@icus.islp.ny.us> Date: 3 Aug 89 01:49:20 GMT Distribution: unix-pc Organization: ICUS Software Systems, Islip, New York Lines: 1648 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 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 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 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 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 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 X#include X#include 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 dirent.h <<'END_OF_dirent.h' X/* X -- definitions for SVR3 directory access routines X X last edit: 25-Apr-1987 D A Gwyn X X Prerequisite: 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 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 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 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 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 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 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 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 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 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 mkdirtest.c <<'END_OF_mkdirtest.c' X/* mkdirtest.c -- test mkdir and rmdir functions */ X#include X#include 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 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 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 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 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\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.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 X#include 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 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 X#include X#include 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 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 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 X#include X#include 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 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 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 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 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 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 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 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 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 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 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 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 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 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 sys.dirent.h <<'END_OF_sys.dirent.h' X/* X -- file system independent directory entry (SVR3) X X last edit: 13-Oct-1987 D A Gwyn X X prerequisite: 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 , 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 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 X#include X#include 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 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 X#include X#include 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 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 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 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