From 94db19641af4166446e63f299c159dcc4252d64f Mon Sep 17 00:00:00 2001 From: eck Date: Mon, 18 Dec 1989 14:40:54 +0000 Subject: [PATCH] Initial revision --- lang/cem/libcc.ansi/misc/.distr | 19 ++ lang/cem/libcc.ansi/misc/LIST | 17 ++ lang/cem/libcc.ansi/misc/Makefile | 29 ++ lang/cem/libcc.ansi/misc/closedir.c | 36 +++ lang/cem/libcc.ansi/misc/fdopen.c | 61 ++++ lang/cem/libcc.ansi/misc/getdents.c | 289 ++++++++++++++++++ lang/cem/libcc.ansi/misc/getgrent.c | 135 +++++++++ lang/cem/libcc.ansi/misc/getopt.c | 62 ++++ lang/cem/libcc.ansi/misc/getpass.c | 44 +++ lang/cem/libcc.ansi/misc/getpw.c | 38 +++ lang/cem/libcc.ansi/misc/getw.c | 19 ++ lang/cem/libcc.ansi/misc/opendir.c | 71 +++++ lang/cem/libcc.ansi/misc/popen.c | 108 +++++++ lang/cem/libcc.ansi/misc/putw.c | 19 ++ lang/cem/libcc.ansi/misc/readdir.c | 47 +++ lang/cem/libcc.ansi/misc/rewinddir.c | 37 +++ lang/cem/libcc.ansi/misc/seekdir.c | 109 +++++++ lang/cem/libcc.ansi/misc/sleep.c | 47 +++ lang/cem/libcc.ansi/misc/telldir.c | 34 +++ lang/cem/libcc.ansi/misc/termcap.c | 428 +++++++++++++++++++++++++++ 20 files changed, 1649 insertions(+) create mode 100644 lang/cem/libcc.ansi/misc/.distr create mode 100644 lang/cem/libcc.ansi/misc/LIST create mode 100644 lang/cem/libcc.ansi/misc/Makefile create mode 100644 lang/cem/libcc.ansi/misc/closedir.c create mode 100644 lang/cem/libcc.ansi/misc/fdopen.c create mode 100644 lang/cem/libcc.ansi/misc/getdents.c create mode 100644 lang/cem/libcc.ansi/misc/getgrent.c create mode 100644 lang/cem/libcc.ansi/misc/getopt.c create mode 100644 lang/cem/libcc.ansi/misc/getpass.c create mode 100644 lang/cem/libcc.ansi/misc/getpw.c create mode 100644 lang/cem/libcc.ansi/misc/getw.c create mode 100644 lang/cem/libcc.ansi/misc/opendir.c create mode 100644 lang/cem/libcc.ansi/misc/popen.c create mode 100644 lang/cem/libcc.ansi/misc/putw.c create mode 100644 lang/cem/libcc.ansi/misc/readdir.c create mode 100644 lang/cem/libcc.ansi/misc/rewinddir.c create mode 100644 lang/cem/libcc.ansi/misc/seekdir.c create mode 100644 lang/cem/libcc.ansi/misc/sleep.c create mode 100644 lang/cem/libcc.ansi/misc/telldir.c create mode 100644 lang/cem/libcc.ansi/misc/termcap.c diff --git a/lang/cem/libcc.ansi/misc/.distr b/lang/cem/libcc.ansi/misc/.distr new file mode 100644 index 000000000..afac1241f --- /dev/null +++ b/lang/cem/libcc.ansi/misc/.distr @@ -0,0 +1,19 @@ +LIST +Makefile +closedir.c +fdopen.c +getdents.c +getgrent.c +getopt.c +getpass.c +getpw.c +getw.c +opendir.c +popen.c +putw.c +readdir.c +rewinddir.c +seekdir.c +sleep.c +telldir.c +termcap.c diff --git a/lang/cem/libcc.ansi/misc/LIST b/lang/cem/libcc.ansi/misc/LIST new file mode 100644 index 000000000..ab676f088 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/LIST @@ -0,0 +1,17 @@ +getgrent.c +getopt.c +getpass.c +getpw.c +getw.c +putw.c +popen.c +sleep.c +termcap.c +fdopen.c +closedir.c +getdents.c +opendir.c +readdir.c +rewinddir.c +seekdir.c +telldir.c diff --git a/lang/cem/libcc.ansi/misc/Makefile b/lang/cem/libcc.ansi/misc/Makefile new file mode 100644 index 000000000..a94ae104d --- /dev/null +++ b/lang/cem/libcc.ansi/misc/Makefile @@ -0,0 +1,29 @@ +CFLAGS=-L -LIB -DNFS + +.SUFFIXES: .o .e .c + +.e.o: + $(CC) $(CFLAGS) -c -o $@ $*.e + +clean: + rm -rf getgrent.o getopt.o getpass.o getpw.o getw.o putw.o \ + popen.o sleep.o termcap.o fdopen.o closedir.o getdents.o \ + opendir.o readdir.o rewinddir.o seekdir.o telldir.o OLIST + +getgrent.o: +getopt.o: +getpass.o: +getpw.o: +getw.o: +putw.o: +popen.o: +sleep.o: +termcap.o: +fdopen.o: +closedir.o: +getdents.o: +opendir.o: +readdir.o: +rewinddir.o: +seekdir.o: +telldir.o: diff --git a/lang/cem/libcc.ansi/misc/closedir.c b/lang/cem/libcc.ansi/misc/closedir.c new file mode 100644 index 000000000..c6cad9ce8 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/closedir.c @@ -0,0 +1,36 @@ +/* + closedir -- close a directory stream + + last edit: 11-Nov-1988 D A Gwyn +*/ + +#include +#include +#include +#include +#include + +typedef void *pointer; /* (void *) if you have it */ + +#ifndef NULL +#define NULL 0 +#endif + +int close(int d); + +int +closedir(register DIR *dirp) /* stream from opendir */ +{ + register int fd; + + if ( dirp == NULL || dirp->dd_buf == NULL ) + { + errno = EFAULT; + return -1; /* invalid pointer */ + } + + fd = dirp->dd_fd; /* bug fix thanks to R. Salz */ + free( (pointer)dirp->dd_buf ); + free( (pointer)dirp ); + return close( fd ); +} diff --git a/lang/cem/libcc.ansi/misc/fdopen.c b/lang/cem/libcc.ansi/misc/fdopen.c new file mode 100644 index 000000000..7a928d6d7 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/fdopen.c @@ -0,0 +1,61 @@ +/* + * fdopen - convert a (UNIX) file descriptor into a FILE pointer + */ +/* $Header$ */ + +#include +#include +#include "../stdio/loc_incl.h" + +int lseek(int d, int offset, int whence); + +FILE * +fdopen(int fd, const char *mode) +{ + register int i; + FILE *stream; + int flags = 0; + + if (fd < 0) return (FILE *)NULL; + for (i = 0; __iotab[i] != 0 ; i++) + if (i >= FOPEN_MAX) + return (FILE *)NULL; + + switch(*mode++) { + case 'r': + flags |= _IOREAD | _IOREADING; + break; + case 'a': + flags |= _IOAPPEND; + case 'w': + flags |= _IOWRITE | _IOWRITING; + break; + default: + return (FILE *)NULL; + } + while(*mode) { + switch(*mode++) { + case 'b': + break; + case '+': + flags |= _IOREAD | _IOWRITE; + break; + default: + return (FILE *)NULL; + } + } + + if ((stream = (FILE *) malloc(sizeof(FILE))) == NULL) { + return (FILE *)NULL; + } + + if ((flags & _IOREAD) && (flags & _IOWRITE)) + flags &= ~(_IOREADING | _IOWRITING); + + stream->_count = 0; + stream->_fd = fd; + stream->_flags = flags; + stream->_buf = NULL; + __iotab[i] = stream; + return stream; +} diff --git a/lang/cem/libcc.ansi/misc/getdents.c b/lang/cem/libcc.ansi/misc/getdents.c new file mode 100644 index 000000000..2fc7ccdc8 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/getdents.c @@ -0,0 +1,289 @@ +/* + getdents -- get directory entries in a file system independent format + (SVR3 system call emulation) + + last edit: 06-Jul-1987 D A Gwyn + + This single source file supports several different methods of + getting directory entries from the operating system. Define + whichever one of the following describes your system: + + UFS original UNIX filesystem (14-character name limit) + BFS 4.2BSD (also 4.3BSD) native filesystem (long names) + NFS getdirentries() system call + + Also define any of the following that are pertinent: + + ATT_SPEC check user buffer address for longword alignment + BSD_SYSV BRL UNIX System V emulation environment on 4.nBSD + UNK have _getdents() system call, but kernel may not + support it + + If your C library has a getdents() system call interface, but you + can't count on all kernels on which your application binaries may + run to support it, change the system call interface name to + _getdents() and define "UNK" to enable the system-call validity + test in this "wrapper" around _getdents(). + + If your system has a getdents() system call that is guaranteed + to always work, you shouldn't be using this source file at all. +*/ + +#include +#include +#include +#include +#include +#ifdef BSD_SYSV +#include /* BSD flavor, not System V */ +#else +#if defined(UFS) +#define DIRSIZ 14 /* 14 char filename in Version 7 */ +#endif +#define MAXNAMLEN 255 +struct direct { + off_t d_off; /* offset of next disk directory entry */ + u_long d_fileno; /* file number of entry */ + u_short d_reclen; /* length of this record */ + u_short d_namlen; /* length of string in d_name */ + char d_name[MAXNAMLEN + 1]; /* name (up to MAXNAMLEN + 1) */ +}; +#undef MAXNAMLEN /* avoid conflict with SVR3 */ + +#define d_ino d_fileno /* compatability */ + +#ifdef d_ino /* 4.3BSD/NFS using d_fileno */ +#undef d_ino /* (not absolutely necessary) */ +#else +#define d_fileno d_ino /* (struct direct) member */ +#endif +#endif +#include +#include +#ifdef UNK +#ifndef UFS +#error UNK applies only to UFS +/* One could do something similar for getdirentries(), but I didn't bother. */ +#endif +#include +#endif + +#if defined(UFS) + defined(BFS) + defined(NFS) != 1 /* sanity check */ +#error exactly one of UFS, BFS, or NFS must be defined +#endif + +#ifdef UFS +#define RecLen( dp ) (sizeof(struct direct)) /* fixed-length entries */ +#else /* BFS || NFS */ +#define RecLen( dp ) ((dp)->d_reclen) /* variable-length entries */ +#endif + +#ifdef NFS +#ifdef BSD_SYSV +#define getdirentries _getdirentries /* package hides this system call */ +#endif +extern int getdirentries(int fd, char *buf, int nbytes, long *basep); +static long dummy; /* getdirentries() needs basep */ +#define GetBlock( fd, buf, n ) getdirentries( fd, buf, (unsigned)n, &dummy ) +#else /* UFS || BFS */ +#ifdef BSD_SYSV +#define read _read /* avoid emulation overhead */ +#endif +extern int read(); +#define GetBlock( fd, buf, n ) read( fd, buf, (unsigned)n ) +#endif + +#ifdef UNK +extern int _getdents(); /* actual system call */ +#endif + +extern int fstat(int fd, struct stat *buf); +extern off_t lseek(int d, int offset, int whence); + +#ifndef DIRBLKSIZ +#define DIRBLKSIZ 4096 /* directory file read buffer size */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef S_ISDIR /* macro to test for directory file */ +#define S_ISDIR( mode ) (((mode) & S_IFMT) == S_IFDIR) +#endif + +#ifdef UFS + +/* + The following routine is necessary to handle DIRSIZ-long entry names. + Thanks to Richard Todd for pointing this out. +*/ + +static int +NameLen( char name[] ) /* return # chars in embedded name */ + /* -> name embedded in struct direct */ +{ + register char *s; /* -> name[.] */ + register char *stop = &name[DIRSIZ]; /* -> past end of name field */ + + for ( s = &name[1]; /* (empty names are impossible) */ + *s != '\0' /* not NUL terminator */ + && ++s < stop; /* < DIRSIZ characters scanned */ + ) + ; + + return s - name; /* # valid characters in name */ +} + +#else /* BFS || NFS */ + +#define NameLen( name ) strlen( name ) /* names are always NUL-terminated */ + +#endif + +#ifdef UNK +static enum { maybe, no, yes } state = maybe; + /* does _getdents() work? */ + +/*ARGSUSED*/ +static void +sig_catch(int sig) /* sig must be SIGSYS */ +{ + state = no; /* attempted _getdents() faulted */ +} +#endif + +int +getdents(int fildes, char *buf, unsigned nbyte) /* returns # bytes read; + 0 on EOF, -1 on error */ +/* fildes == directory file descriptor */ +/* *buf == where to put the (struct dirent)s */ +/* nbyte == size of buf[] */ +{ + int serrno; /* entry errno */ + off_t offset; /* initial directory file offset */ + struct stat statb; /* fstat() info */ + union { + char dblk[DIRBLKSIZ]; + /* directory file block buffer */ + struct direct dummy; /* just for alignment */ + } u; /* (avoids having to malloc()) */ + register struct direct *dp; /* -> u.dblk[.] */ + register struct dirent *bp; /* -> buf[.] */ + +#ifdef UNK + switch ( state ) + { + void (*shdlr)(); /* entry SIGSYS handler */ + register int retval; /* return from _getdents() if any */ + + case yes: /* _getdents() is known to work */ + return _getdents( fildes, buf, nbyte ); + + case maybe: /* first time only */ + shdlr = signal( SIGSYS, sig_catch ); + retval = _getdents( fildes, buf, nbyte ); /* try it */ + (void)signal( SIGSYS, shdlr ); + + if ( state == maybe ) /* SIGSYS did not occur */ + { + state = yes; /* so _getdents() must have worked */ + return retval; + } + /* else fall through into emulation */ + +/* case no: /* fall through into emulation */ + } +#endif + + if ( buf == NULL +#ifdef ATT_SPEC + || (unsigned long)buf % sizeof(long) != 0 /* ugh */ +#endif + ) { + errno = EFAULT; /* invalid pointer */ + return -1; + } + + if ( fstat( fildes, &statb ) != 0 ) + return -1; /* errno set by fstat() */ + + if ( !S_ISDIR( statb.st_mode ) ) + { + errno = ENOTDIR; /* not a directory */ + return -1; + } + + if ( (offset = lseek( fildes, (off_t)0, SEEK_CUR )) < 0 ) + return -1; /* errno set by lseek() */ + +#ifdef BFS /* no telling what remote hosts do */ + if ( (unsigned long)offset % DIRBLKSIZ != 0 ) + { + errno = ENOENT; /* file pointer probably misaligned */ + return -1; + } +#endif + + serrno = errno; /* save entry errno */ + + for ( bp = (struct dirent *)buf; bp == (struct dirent *)buf; ) + { /* convert next directory block */ + int size; + + do size = GetBlock( fildes, u.dblk, DIRBLKSIZ ); + while ( size == -1 && errno == EINTR ); + + if ( size <= 0 ) + return size; /* EOF or error (EBADF) */ + + for ( dp = (struct direct *)u.dblk; + (char *)dp < &u.dblk[size]; + dp = (struct direct *)((char *)dp + RecLen( dp )) + ) { +#ifndef UFS + if ( dp->d_reclen <= 0 ) + { + errno = EIO; /* corrupted directory */ + return -1; + } +#endif + + if ( dp->d_fileno != 0 ) + { /* non-empty; copy to user buffer */ + register int reclen = + DIRENTSIZ( NameLen( dp->d_name ) ); + + if ( (char *)bp + reclen > &buf[nbyte] ) + { + errno = EINVAL; + return -1; /* buf too small */ + } + + bp->d_ino = dp->d_fileno; + bp->d_off = offset + ((char *)dp - u.dblk); + bp->d_reclen = reclen; + (void)strncpy( bp->d_name, dp->d_name, + reclen - DIRENTBASESIZ + ); /* adds NUL padding */ + + bp = (struct dirent *)((char *)bp + reclen); + } + } + +#ifndef BFS /* 4.2BSD screwed up; fixed in 4.3BSD */ + if ( (char *)dp > &u.dblk[size] ) + { + errno = EIO; /* corrupted directory */ + return -1; + } +#endif + } + + errno = serrno; /* restore entry errno */ + return (char *)bp - buf; /* return # bytes read */ +} diff --git a/lang/cem/libcc.ansi/misc/getgrent.c b/lang/cem/libcc.ansi/misc/getgrent.c new file mode 100644 index 000000000..247479fa1 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/getgrent.c @@ -0,0 +1,135 @@ +/* + * getgrent - get entry form group file + * + * Author: Patrick van Kleef + */ +/* $Header$ */ + +#include +#include +#include + +#define O_RDONLY 0 + +int open(const char *path, int flags); + +#if defined(__BSD4_2) +typedef int off_t; /* see lseek(2) */ +#else +typedef long off_t; +#endif + +off_t lseek(int d, off_t offset, int whence); +int read(int d, char *buf, int nbytes); +int close(int d); + +#define RBUFSIZE 1024 +static char _gr_file[] = "/etc/group"; +static char _grbuf[256]; +static char _buffer[RBUFSIZE]; +static char *_pnt; +static char *_buf; +static int _gfd = -1; +static int _bufcnt; +static struct group grp; + +int +setgrent(void) +{ + if (_gfd >= 0) + lseek(_gfd, 0L, 0); + else + _gfd = open(_gr_file, O_RDONLY); + + _bufcnt = 0; + return _gfd; +} + +int +endgrent(void) +{ + if (_gfd >= 0) + close(_gfd); + + _gfd = -1; + _bufcnt = 0; +} + + +static int +getline(void) +{ + if (_gfd < 0 && setgrent() < 0) + return 0; + + _buf = _grbuf; + do { + if (--_bufcnt <= 0){ + if ((_bufcnt = read(_gfd, _buffer, RBUFSIZE)) <= 0) + return 0; + else + _pnt = _buffer; + } + *_buf++ = *_pnt++; + } while (*_pnt != '\n'); + _pnt++; + _bufcnt--; + *_buf = 0; + _buf = _grbuf; + return 1; +} + +static int +skip_period(void) +{ + while (*_buf && *_buf != ':') + _buf++; + *_buf++ = '\0'; +} + +struct group * +getgrent(void) +{ + if (getline() == 0) + return 0; + + grp.gr_name = _buf; + skip_period(); + grp.gr_passwd = _buf; + skip_period(); + grp.gr_gid = atoi(_buf); + skip_period(); + return &grp; +} + +struct group * +getgrnam(const char *name) +{ + struct group *grp; + + setgrent(); + while ((grp = getgrent()) != 0) + if (!strcmp(grp -> gr_name, name)) + break; + endgrent(); + if (grp != 0) + return grp; + else + return 0; +} + +struct group * +getgrgid(int gid) +{ + struct group *grp; + + setgrent(); + while ((grp = getgrent()) != 0) + if (grp -> gr_gid == gid) + break; + endgrent(); + if (grp != 0) + return grp; + else + return 0; +} diff --git a/lang/cem/libcc.ansi/misc/getopt.c b/lang/cem/libcc.ansi/misc/getopt.c new file mode 100644 index 000000000..55d843c2a --- /dev/null +++ b/lang/cem/libcc.ansi/misc/getopt.c @@ -0,0 +1,62 @@ +/* + * getopt - parse command-line options + */ +/* $Header$ */ + +#include +#include + +#define ERR(s, c) if(opterr){\ + fputs(argv[0], stderr);\ + fputs(s, stderr);\ + fputc(c, stderr);\ + fputc('\n', stderr);} + +int opterr = 1; +int optind = 1; +int optopt; +char *optarg; + +int +getopt(int argc, char **argv, char *opts) +{ + static int sp = 1; + register c; + register char *cp; + + if (sp == 1) + if (optind >= argc || + argv[optind][0] != '-' || argv[optind][1] == '\0') + return EOF; + else if (!strcmp(argv[optind], "--")) { + optind++; + return EOF; + } + optopt = c = argv[optind][sp]; + if (c == ':' || (cp=strchr(opts, c)) == NULL) { + ERR (": illegal option -- ", c); + if (argv[optind][++sp] == '\0') { + optind++; + sp = 1; + } + return '?'; + } + if (*++cp == ':') { + if (argv[optind][sp+1] != '\0') + optarg = &argv[optind++][sp+1]; + else if (++optind >= argc) { + ERR (": option requires an argument -- ", c); + sp = 1; + return '?'; + } else + optarg = argv[optind++]; + sp = 1; + } else { + if (argv[optind][++sp] == '\0') { + sp = 1; + optind++; + } + optarg = NULL; + } + return c; +} diff --git a/lang/cem/libcc.ansi/misc/getpass.c b/lang/cem/libcc.ansi/misc/getpass.c new file mode 100644 index 000000000..e1a535b68 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/getpass.c @@ -0,0 +1,44 @@ +/* + * getpass - ask for a password + */ +/* $Header$ */ + +#include +#include +#include + +#define O_RDONLY 0 +int open(const char *path, int flags); +int write(int d, const char *buf, int nbytes); +int read(int d, char *buf, int nbytes); +int close(int d); + +int stty(int, struct sgttyb *); +int gtty(int, struct sgttyb *); + +char * +getpass(const char *prompt) +{ + int i = 0; + struct sgttyb tty, ttysave; + static char pwdbuf[9]; + int fd; + void (*savesig)(int); + + if ((fd = open("/dev/tty", O_RDONLY)) < 0) fd = 0; + savesig = signal(SIGINT, SIG_IGN); + write(2, prompt, strlen(prompt)); + gtty(fd, &tty); + ttysave = tty; + tty.sg_flags &= ~ECHO; + stty(fd, &tty); + i = read(fd, pwdbuf, 9); + while (pwdbuf[i - 1] != '\n') + read(fd, &pwdbuf[i - 1], 1); + pwdbuf[i - 1] = '\0'; + stty(fd, &ttysave); + write(2, "\n", 1); + if (fd != 0) close(fd); + signal(SIGINT, savesig); + return(pwdbuf); +} diff --git a/lang/cem/libcc.ansi/misc/getpw.c b/lang/cem/libcc.ansi/misc/getpw.c new file mode 100644 index 000000000..bbd9c3935 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/getpw.c @@ -0,0 +1,38 @@ +/* + * getpw - get a password from the password file + */ +/* $Header$ */ + +#include + +getpw(int uid, char buf[]) +{ + register FILE *pwf; + register int ch, i; + register char *bp; + + pwf = fopen("/etc/passwd", "r"); + if (pwf == NULL) return(1); + + for (;;) { + bp = buf; + while ((ch = getc(pwf)) != '\n') { + if (ch == EOF) return 1; + *bp++ = ch; + } + *bp++ = '\0'; + bp = buf; + for (i = 2; i; i--) { + while ((ch = *bp++) != ':') { + if(ch = '\0') return 1; + } + } + i = 0; + while ((ch = *bp++) != ':') { + if (ch < '0' || ch > '9') return 1; + i = i * 10 + (ch - '0'); + } + if (i == uid) return(0); + } + /*NOTREACHED*/ +} diff --git a/lang/cem/libcc.ansi/misc/getw.c b/lang/cem/libcc.ansi/misc/getw.c new file mode 100644 index 000000000..68a79780b --- /dev/null +++ b/lang/cem/libcc.ansi/misc/getw.c @@ -0,0 +1,19 @@ +/* + * getw - read a word from a stream + */ +/* $Header$ */ + +#include + +int getw(register FILE *stream) +{ + register int cnt = sizeof(int); + int w; + register char *p = (char *) &w; + + while (cnt--) { + *p++ = getc(stream); + } + if (feof(stream) || ferror(stream)) return EOF; + return w; +} diff --git a/lang/cem/libcc.ansi/misc/opendir.c b/lang/cem/libcc.ansi/misc/opendir.c new file mode 100644 index 000000000..7386b6084 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/opendir.c @@ -0,0 +1,71 @@ +/* + opendir -- open a directory stream + + last edit: 16-Jun-1987 D A Gwyn +*/ + +#include +#include +#include +#include +#include +#include + +#ifdef BSD_SYSV +#define open _open /* avoid emulation overhead */ +#endif + +typedef void *pointer; /* (void *) if you have it */ + +extern int open(const char *path, int flags, int mode); +extern int close(int d); +extern int fstat(int fd, struct stat *buf); + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif + +#ifndef S_ISDIR /* macro to test for directory file */ +#define S_ISDIR( mode ) (((mode) & S_IFMT) == S_IFDIR) +#endif + +DIR * +opendir(const char *dirname) /* name of directory */ +{ + register DIR *dirp; /* -> malloc'ed storage */ + register int fd; /* file descriptor for read */ + struct stat sbuf; /* result of fstat() */ + + if ( (fd = open( dirname, O_RDONLY, 0 )) < 0 ) + return NULL; /* errno set by open() */ + + if ( fstat( fd, &sbuf ) != 0 || !S_ISDIR( sbuf.st_mode ) ) + { + (void)close( fd ); + errno = ENOTDIR; + return NULL; /* not a directory */ + } + + if ( (dirp = (DIR *)malloc( sizeof(DIR) )) == NULL + || (dirp->dd_buf = (char *)malloc( (unsigned)DIRBUF )) == NULL + ) { + register int serrno = errno; + /* errno set to ENOMEM by sbrk() */ + + if ( dirp != NULL ) + free( (pointer)dirp ); + + (void)close( fd ); + errno = serrno; + return NULL; /* not enough memory */ + } + + dirp->dd_fd = fd; + dirp->dd_loc = dirp->dd_size = 0; /* refill needed */ + + return dirp; +} diff --git a/lang/cem/libcc.ansi/misc/popen.c b/lang/cem/libcc.ansi/misc/popen.c new file mode 100644 index 000000000..c566c5f2d --- /dev/null +++ b/lang/cem/libcc.ansi/misc/popen.c @@ -0,0 +1,108 @@ +/* + * popen - open a pipe + */ +/* $Header$ */ + +#include +#include +#include +#if defined(__BSD4_2) +#if _EM_WSIZE != 4 +#error union wait is too small +#endif +union wait { + int w_status; +}; +typedef union wait wait_arg; +#else +typedef int wait_arg; +#endif /* __BSD4_2 */ +#include "../stdio/loc_incl.h" + +int close(int d); +int dup2(int oldd, int newd); /* not present in System 5 */ +int execl(const char *name, ... ); +int fork(void); +int pipe(int fildes[2]); +int wait(wait_arg *status); +void _exit(int status); + +static int pids[20]; + +FILE * +popen(const char *command, const char *type) +{ + int piped[2]; + int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2; + int pid; + + if (Xtype == 2 || + pipe(piped) < 0 || + (pid = fork()) < 0) return 0; + + if (pid == 0) { + /* child */ + register int *p; + + for (p = pids; p < &pids[ FOPEN_MAX]; p++) { + if (*p) close(p - pids); + } + close(piped[Xtype]); + dup2(piped[!Xtype], !Xtype); + close(piped[!Xtype]); + execl("/bin/sh", "sh", "-c", command, (char *) 0); + _exit(127); /* like system() ??? */ + } + + pids[piped[Xtype]] = pid; + close(piped[!Xtype]); + return fdopen(piped[Xtype], type); +} + +#if defined(__BSD4_2) +#define ret_val status.w_status +#else +#define ret_val status +#endif + +int +pclose(FILE *stream) +{ + int fd = fileno(stream); + wait_arg status; + int wret; + void (*intsave)(int) = signal(SIGINT, SIG_IGN); + void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN); + + fclose(stream); + while ((wret = wait(&status)) != -1) { + if (wret == pids[fd]) break; + } + if (wret == -1) ret_val = -1; + signal(SIGINT, intsave); + signal(SIGQUIT, quitsave); + pids[fd] = 0; + return ret_val; +} + +#if defined(__USG) +int +dup2(int oldd, int newd) +{ + int i = 0, fd, tmp; + int fdbuf[_NFILES]; + + /* ignore the error on the close() */ + tmp = errno; (void) close(newd); errno = tmp; + while ((fd = dup(oldd)) != newd) { + if (fd == -1) break; + fdbuf[i++] = fd; + } + tmp = errno; + while (--i >= 0) { + close(fdbuf[i]); + } + errno = tmp; + return -(fd == -1); +} +#endif /* __USG */ diff --git a/lang/cem/libcc.ansi/misc/putw.c b/lang/cem/libcc.ansi/misc/putw.c new file mode 100644 index 000000000..23a591a5d --- /dev/null +++ b/lang/cem/libcc.ansi/misc/putw.c @@ -0,0 +1,19 @@ +/* + * putw - write an word on a stream + */ +/* $Header$ */ + +#include + +int +putw(int w, register FILE *stream) +{ + register int cnt = sizeof(int); + register char *p = (char *) &w; + + while (cnt--) { + putc(*p++, stream); + } + if (ferror(stream)) return EOF; + return w; +} diff --git a/lang/cem/libcc.ansi/misc/readdir.c b/lang/cem/libcc.ansi/misc/readdir.c new file mode 100644 index 000000000..2497e4673 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/readdir.c @@ -0,0 +1,47 @@ +/* + readdir -- read next entry from a directory stream + + last edit: 25-Apr-1987 D A Gwyn +*/ + +#include +#include +#include +#include + +/* SVR3 system call, or emulation for getdents() */ +extern int getdents(int fildes, char *buf, unsigned nbyte); + +#ifndef NULL +#define NULL 0 +#endif + +struct dirent * +readdir(register DIR *dirp) +{ + register struct dirent *dp; /* -> directory data */ + + if ( dirp == NULL || dirp->dd_buf == NULL ) + { + errno = EFAULT; + return NULL; /* invalid pointer */ + } + + do { + if ( dirp->dd_loc >= dirp->dd_size ) /* empty or obsolete */ + dirp->dd_loc = dirp->dd_size = 0; + + if ( dirp->dd_size == 0 /* need to refill buffer */ + && (dirp->dd_size = + getdents( dirp->dd_fd, dirp->dd_buf, (unsigned)DIRBUF ) + ) <= 0 + ) + return NULL; /* EOF or error */ + + dp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc]; + dirp->dd_loc += dp->d_reclen; + } + while ( dp->d_ino == 0L ); /* don't rely on getdents() */ + + return dp; +} diff --git a/lang/cem/libcc.ansi/misc/rewinddir.c b/lang/cem/libcc.ansi/misc/rewinddir.c new file mode 100644 index 000000000..6b52f69d9 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/rewinddir.c @@ -0,0 +1,37 @@ +/* + rewinddir -- rewind a directory stream + + last edit: 25-Apr-1987 D A Gwyn + + This is not simply a call to seekdir(), because seekdir() + will use the current buffer whenever possible and we need + rewinddir() to forget about buffered data. +*/ + +#include +#include +#include +#include + +extern off_t lseek(int d, int offset, int whence); + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +void +rewinddir(register DIR *dirp) +{ + if ( dirp == NULL || dirp->dd_buf == NULL ) + { + errno = EFAULT; + return; /* invalid pointer */ + } + + dirp->dd_loc = dirp->dd_size = 0; /* invalidate buffer */ + (void)lseek( dirp->dd_fd, (off_t)0, SEEK_SET ); /* may set errno */ +} diff --git a/lang/cem/libcc.ansi/misc/seekdir.c b/lang/cem/libcc.ansi/misc/seekdir.c new file mode 100644 index 000000000..eff0ef5dd --- /dev/null +++ b/lang/cem/libcc.ansi/misc/seekdir.c @@ -0,0 +1,109 @@ +/* + seekdir -- reposition a directory stream + + last edit: 24-May-1987 D A Gwyn + + An unsuccessful seekdir() will in general alter the current + directory position; beware. + + NOTE: 4.nBSD directory compaction makes seekdir() & telldir() + practically impossible to do right. Avoid using them! +*/ + +#include +#include +#include +#include + +extern off_t lseek(int d, int offset, int whence); + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +typedef int bool; /* Boolean data type */ +#define false 0 +#define true 1 + +void +seekdir(register DIR *dirp, register off_t loc) +/* loc == position from telldir() */ +{ + register bool rewind; /* "start over when stymied" flag */ + + if ( dirp == NULL || dirp->dd_buf == NULL ) + { + errno = EFAULT; + return; /* invalid pointer */ + } + + /* A (struct dirent)'s d_off is an invented quantity on 4.nBSD + NFS-supporting systems, so it is not safe to lseek() to it. */ + + /* Monotonicity of d_off is heavily exploited in the following. */ + + /* This algorithm is tuned for modest directory sizes. For + huge directories, it might be more efficient to read blocks + until the first d_off is too large, then back up one block, + or even to use binary search on the directory blocks. I + doubt that the extra code for that would be worthwhile. */ + + if ( dirp->dd_loc >= dirp->dd_size /* invalid index */ + || ((struct dirent *)&dirp->dd_buf[dirp->dd_loc])->d_off > loc + /* too far along in buffer */ + ) + dirp->dd_loc = 0; /* reset to beginning of buffer */ + /* else save time by starting at current dirp->dd_loc */ + + for ( rewind = true; ; ) + { + register struct dirent *dp; + + /* See whether the matching entry is in the current buffer. */ + + if ( (dirp->dd_loc < dirp->dd_size /* valid index */ + || readdir( dirp ) != NULL /* next buffer read */ + && (dirp->dd_loc = 0, true) /* beginning of buffer set */ + ) + && (dp = (struct dirent *)&dirp->dd_buf[dirp->dd_loc])->d_off + <= loc /* match possible in this buffer */ + ) { + for ( /* dp initialized above */ ; + (char *)dp < &dirp->dd_buf[dirp->dd_size]; + dp = (struct dirent *)((char *)dp + dp->d_reclen) + ) + if ( dp->d_off == loc ) + { /* found it! */ + dirp->dd_loc = + (char *)dp - dirp->dd_buf; + return; + } + + rewind = false; /* no point in backing up later */ + dirp->dd_loc = dirp->dd_size; /* set end of buffer */ + } + else /* whole buffer past matching entry */ + if ( !rewind ) + { /* no point in searching further */ + errno = EINVAL; + return; /* no entry at specified loc */ + } + else { /* rewind directory and start over */ + rewind = false; /* but only once! */ + + dirp->dd_loc = dirp->dd_size = 0; + + if ( lseek( dirp->dd_fd, (off_t)0, SEEK_SET ) + != 0 + ) + return; /* errno already set (EBADF) */ + + if ( loc == 0 ) + return; /* save time */ + } + } +} diff --git a/lang/cem/libcc.ansi/misc/sleep.c b/lang/cem/libcc.ansi/misc/sleep.c new file mode 100644 index 000000000..abb147e6f --- /dev/null +++ b/lang/cem/libcc.ansi/misc/sleep.c @@ -0,0 +1,47 @@ +/* + * sleep - suspend current process for a number of seconds + */ +/* $Header$ */ + +#include +#include + +int alarm(int n); +void pause(void); + +static jmp_buf setjmpbuf; + +static void +alfun(int sig) +{ + longjmp(setjmpbuf, 1); +} /* used with sleep() below */ + +void +sleep(int n) +{ +/* sleep(n) pauses for 'n' seconds by scheduling an alarm interrupt. */ + unsigned oldalarm; + void (*oldsig)(int); + + if (n <= 0) return; + if (setjmp(setjmpbuf)) { + signal(SIGALRM, oldsig); + alarm(oldalarm); + return; + } + oldalarm = alarm(5000); /* Who cares how long, as long + * as it is long enough + */ + if (oldalarm > n) oldalarm -= n; + else if (oldalarm) { + n = oldalarm; + oldalarm = 1; + } + oldsig = signal(SIGALRM, alfun); + alarm(n); + for (;;) { + /* allow for other handlers ... */ + pause(); + } +} diff --git a/lang/cem/libcc.ansi/misc/telldir.c b/lang/cem/libcc.ansi/misc/telldir.c new file mode 100644 index 000000000..359c7bfc8 --- /dev/null +++ b/lang/cem/libcc.ansi/misc/telldir.c @@ -0,0 +1,34 @@ +/* + telldir -- report directory stream position + + last edit: 25-Apr-1987 D A Gwyn + + NOTE: 4.nBSD directory compaction makes seekdir() & telldir() + practically impossible to do right. Avoid using them! +*/ + +#include +#include +#include +#include + +extern off_t lseek(int d, int offset, int whence); + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +off_t +telldir(register DIR *dirp) /* return offset of next entry */ +{ + if ( dirp == NULL || dirp->dd_buf == NULL ) + { + errno = EFAULT; + return -1; /* invalid pointer */ + } + + if ( dirp->dd_loc < dirp->dd_size ) /* valid index */ + return ((struct dirent *)&dirp->dd_buf[dirp->dd_loc])->d_off; + else /* beginning of next directory block */ + return lseek( dirp->dd_fd, (off_t)0, SEEK_CUR ); +} diff --git a/lang/cem/libcc.ansi/misc/termcap.c b/lang/cem/libcc.ansi/misc/termcap.c new file mode 100644 index 000000000..ef874e36a --- /dev/null +++ b/lang/cem/libcc.ansi/misc/termcap.c @@ -0,0 +1,428 @@ +/* + * termcap.c 1.1 20/7/87 agc Joypace Ltd + * + * Copyright Joypace Ltd, London, UK, 1987. All rights reserved. + * This file may be freely distributed provided that this notice + * remains attached. + * + * A public domain implementation of the termcap(3) routines. + * + * Made fully functional by Ceriel J.H. Jacobs. + * + * BUGS: + * - does not check termcap entry sizes + * - not fully tested + */ +/* $Header$ */ + +#include +#include +#include + +#define CAPABLEN 2 + +#define ISSPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n') +#define ISDIGIT(x) ((x) >= '0' && (x) <= '9') + +short ospeed; /* output speed */ +char PC; /* padding character */ +char *BC; /* back cursor movement */ +char *UP; /* up cursor movement */ + +static const char *capab; /* the capability itself */ +static int check_for_tc(void); +static int match_name(const char *buf, const char *name); + +/* + * tgetent - get the termcap entry for terminal name, and put it + * in bp (which must be an array of 1024 chars). Returns 1 if + * termcap entry found, 0 if not found, and -1 if file not found. + */ +int +tgetent(char *bp, const char *name) +{ + FILE *fp; + char *file; + char *cp; + short len = strlen(name); + char buf[1024]; + + capab = bp; + if ((file = getenv("TERMCAP")) != (char *) NULL) { + if (*file != '/' && + (cp = getenv("TERM")) != NULL && strcmp(name, cp) == 0) { + (void) strcpy(bp, file); + return(1); + } + else file = "/etc/termcap"; + } else + file = "/etc/termcap"; + if ((fp = fopen(file, "r")) == (FILE *) NULL) + return(-1); + while (fgets(buf, 1024, fp) != NULL) { + if (buf[0] == '#') continue; + while (*(cp = &buf[strlen(buf) - 2]) == '\\') + if (fgets(cp, 1024, fp) == NULL) + return (0); + if (match_name(buf, name)) { + strcpy(bp, buf); + fclose(fp); + return(check_for_tc()); + } + } + fclose(fp); + return(0); +} + +/* + * Compare the terminal name with each termcap entry name; Return 1 if a + * match is found. + */ +static int +match_name(const char *buf, const char *name) +{ + register const char *tp = buf; + register const char *np; + + for (;;) { + for (np = name; *np && *tp == *np; np++, tp++) { } + if (*np == 0 && (*tp == '|' || *tp == ':' || *tp == 0)) + return(1); + while (*tp != 0 && *tp != '|' && *tp != ':') tp++; + if (*tp++ != '|') return (0); + } +} + +/* + * Handle tc= definitions recursively. + */ +static int +check_for_tc(void) +{ + static int count = 0; + const char *savcapab = capab; + char buf[1024]; + char terminalname[128]; + register char *p = (char *)capab + strlen(capab) - 2, *q; + + while (*p != ':') + if (--p < (char *)capab) + return(0); /* no : in termcap entry */ + if (p[1] != 't' || p[2] != 'c') + return(1); + if (count > 16) return(0); /* recursion in tc= definitions */ + count++; + strcpy(terminalname, &p[4]); + q = terminalname; + while (*q && *q != ':') q++; + *q = 0; + if (tgetent(buf, terminalname) != 1) { + --count; + return(0); + } + --count; + for (q = buf; *q && *q != ':'; q++) { } + strcpy(p, q); + capab = savcapab; + return(1); +} + +/* + * tgetnum - get the numeric terminal capability corresponding + * to id. Returns the value, -1 if invalid. + */ +int +tgetnum(const char *id) +{ + const char *cp; + int ret; + + if ((cp = capab) == NULL || id == NULL) + return(-1); + while (*++cp != ':') + ; + while (*cp) { + cp++; + while (ISSPACE(*cp)) + cp++; + if (strncmp(cp, id, CAPABLEN) == 0) { + while (*cp && *cp != ':' && *cp != '#') + cp++; + if (*cp != '#') + return(-1); + for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++) + ret = ret * 10 + *cp - '0'; + return(ret); + } + while (*cp && *cp != ':') + cp++; + } + return(-1); +} + +/* + * tgetflag - get the boolean flag corresponding to id. Returns -1 + * if invalid, 0 if the flag is not in termcap entry, or 1 if it is + * present. + */ +int +tgetflag(const char *id) +{ + const char *cp; + + if ((cp = capab) == NULL || id == NULL) + return(-1); + while (*++cp != ':') + ; + while (*cp) { + cp++; + while (ISSPACE(*cp)) + cp++; + if (strncmp(cp, id, CAPABLEN) == 0) + return(1); + while (*cp && *cp != ':') + cp++; + } + return(0); +} + +/* + * tgetstr - get the string capability corresponding to id and place + * it in area (advancing area at same time). Expand escape sequences + * etc. Returns the string, or NULL if it can't do it. + */ +char * +tgetstr(const char *id, char ** const area) +{ + const char *cp; + char *ret; + int i; + + if ((cp = capab) == NULL || id == NULL) + return(NULL); + while (*++cp != ':') + ; + while (*cp) { + cp++; + while (ISSPACE(*cp)) + cp++; + if (strncmp(cp, id, CAPABLEN) == 0) { + while (*cp && *cp != ':' && *cp != '=') + cp++; + if (*cp != '=') + return(NULL); + for (ret = *area, cp++; *cp && *cp != ':' ; (*area)++, cp++) + switch(*cp) { + case '^' : + **area = *++cp - 'A' + 1; + break; + case '\\' : + switch(*++cp) { + case 'E' : + **area = '\033'; + break; + case 'n' : + **area = '\n'; + break; + case 'r' : + **area = '\r'; + break; + case 't' : + **area = '\t'; + break; + case 'b' : + **area = '\b'; + break; + case 'f' : + **area = '\f'; + break; + case '0' : + case '1' : + case '2' : + case '3' : + for (i=0 ; *cp && ISDIGIT(*cp) ; cp++) + i = i * 8 + *cp - '0'; + **area = i; + cp--; + break; + case '^' : + case '\\' : + **area = *cp; + break; + } + break; + default : + **area = *cp; + } + *(*area)++ = '\0'; + return(ret); + } + while (*cp && *cp != ':') + cp++; + } + return(NULL); +} + +/* + * tgoto - given the cursor motion string cm, make up the string + * for the cursor to go to (destcol, destline), and return the string. + * Returns "OOPS" if something's gone wrong, or the string otherwise. + */ +char * +tgoto(const char *cm, int destcol, int destline) +{ + register char *rp; + static char ret[24]; + char added[16]; + int *dp = &destline; + int numval; + int swapped = 0; + + added[0] = 0; + for (rp = ret ; *cm ; cm++) { + if (*cm == '%') { + switch(*++cm) { + case '>' : + if (dp == NULL) + return("OOPS"); + cm++; + if (*dp > *cm++) { + *dp += *cm; + } + break; + case '+' : + case '.' : + if (dp == NULL) + return("OOPS"); + if (*cm == '+') *dp = *dp + *++cm; + for (;;) { + switch(*dp) { + case 0: + case 04: + case '\t': + case '\n': + /* filter these out */ + if (dp == &destcol || swapped || UP) { + strcat(added, dp == &destcol || swapped ? + (BC ? BC : "\b") : + UP); + (*dp)++; + continue; + } + } + break; + } + *rp++ = *dp; + dp = (dp == &destline) ? &destcol : NULL; + break; + + case 'r' : { + int tmp = destline; + + destline = destcol; + destcol = tmp; + swapped = 1 - swapped; + break; + } + case 'n' : + destcol ^= 0140; + destline ^= 0140; + break; + + case '%' : + *rp++ = '%'; + break; + + case 'i' : + destcol++; + destline++; + break; + + case 'B' : + if (dp == NULL) + return("OOPS"); + *dp = 16 * (*dp / 10) + *dp % 10; + break; + + case 'D' : + if (dp == NULL) + return("OOPS"); + *dp = *dp - 2 * (*dp % 16); + break; + + case 'd' : + case '2' : + case '3' : + if (dp == NULL) + return("OOPS"); + numval = *dp; + dp = (dp == &destline) ? &destcol : NULL; + if (numval >= 100) { + *rp++ = '0' + numval / 100; + } + else if (*cm == '3') { + *rp++ = ' '; + } + if (numval >= 10) { + *rp++ = '0' + ((numval%100)/10); + } + else if (*cm == '3' || *cm == '2') { + *rp++ = ' '; + } + *rp++ = '0' + (numval%10); + break; + default : + return("OOPS"); + } + } + else *rp++ = *cm; + } + *rp = '\0'; + strcpy(rp, added); + return(ret); +} + +static int tens_of_ms_p_char[] = { /* index as returned by gtty */ + /* assume 10 bits per char */ + 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 2 +}; +/* + * tputs - put the string cp out onto the terminal, using the function + * outc. Also handle padding. + */ +int +tputs(register const char *cp, int affcnt, int (*outc)(int)) +{ + int delay = 0; + if (cp == NULL) + return(1); + while (ISDIGIT(*cp)) { + delay = delay * 10 + (*cp++ - '0'); + } + delay *= 10; + if (*cp == '.') { + cp++; + if (ISDIGIT(*cp)) { + delay += *cp++ - '0'; + } + while (ISDIGIT(*cp)) cp++; + } + if (*cp == '*') { + delay *= affcnt; + cp++; + } + while (*cp) + (*outc)(*cp++); + if (delay != 0 && + ospeed > 0 && + ospeed < (sizeof tens_of_ms_p_char / sizeof tens_of_ms_p_char[0])) { + delay = (delay + tens_of_ms_p_char[ospeed] - 1) / + tens_of_ms_p_char[ospeed]; + while (delay--) (*outc)(PC); + } + return(1); +} + +/* + * That's all, folks... + */