Initial revision
This commit is contained in:
parent
d8486967aa
commit
94db19641a
19
lang/cem/libcc.ansi/misc/.distr
Normal file
19
lang/cem/libcc.ansi/misc/.distr
Normal file
|
@ -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
|
17
lang/cem/libcc.ansi/misc/LIST
Normal file
17
lang/cem/libcc.ansi/misc/LIST
Normal file
|
@ -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
|
29
lang/cem/libcc.ansi/misc/Makefile
Normal file
29
lang/cem/libcc.ansi/misc/Makefile
Normal file
|
@ -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:
|
36
lang/cem/libcc.ansi/misc/closedir.c
Normal file
36
lang/cem/libcc.ansi/misc/closedir.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
closedir -- close a directory stream
|
||||
|
||||
last edit: 11-Nov-1988 D A Gwyn
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
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 );
|
||||
}
|
61
lang/cem/libcc.ansi/misc/fdopen.c
Normal file
61
lang/cem/libcc.ansi/misc/fdopen.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* fdopen - convert a (UNIX) file descriptor into a FILE pointer
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#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;
|
||||
}
|
289
lang/cem/libcc.ansi/misc/getdents.c
Normal file
289
lang/cem/libcc.ansi/misc/getdents.c
Normal file
|
@ -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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef BSD_SYSV
|
||||
#include <sys/_dir.h> /* 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 <sys/dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef UNK
|
||||
#ifndef UFS
|
||||
#error UNK applies only to UFS
|
||||
/* One could do something similar for getdirentries(), but I didn't bother. */
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#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 */
|
||||
}
|
135
lang/cem/libcc.ansi/misc/getgrent.c
Normal file
135
lang/cem/libcc.ansi/misc/getgrent.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* getgrent - get entry form group file
|
||||
*
|
||||
* Author: Patrick van Kleef
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <grp.h>
|
||||
|
||||
#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;
|
||||
}
|
62
lang/cem/libcc.ansi/misc/getopt.c
Normal file
62
lang/cem/libcc.ansi/misc/getopt.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* getopt - parse command-line options
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
44
lang/cem/libcc.ansi/misc/getpass.c
Normal file
44
lang/cem/libcc.ansi/misc/getpass.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* getpass - ask for a password
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sgtty.h>
|
||||
|
||||
#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);
|
||||
}
|
38
lang/cem/libcc.ansi/misc/getpw.c
Normal file
38
lang/cem/libcc.ansi/misc/getpw.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* getpw - get a password from the password file
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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*/
|
||||
}
|
19
lang/cem/libcc.ansi/misc/getw.c
Normal file
19
lang/cem/libcc.ansi/misc/getw.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* getw - read a word from a stream
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
71
lang/cem/libcc.ansi/misc/opendir.c
Normal file
71
lang/cem/libcc.ansi/misc/opendir.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
opendir -- open a directory stream
|
||||
|
||||
last edit: 16-Jun-1987 D A Gwyn
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#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;
|
||||
}
|
108
lang/cem/libcc.ansi/misc/popen.c
Normal file
108
lang/cem/libcc.ansi/misc/popen.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* popen - open a pipe
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#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 */
|
19
lang/cem/libcc.ansi/misc/putw.c
Normal file
19
lang/cem/libcc.ansi/misc/putw.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* putw - write an word on a stream
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
47
lang/cem/libcc.ansi/misc/readdir.c
Normal file
47
lang/cem/libcc.ansi/misc/readdir.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
readdir -- read next entry from a directory stream
|
||||
|
||||
last edit: 25-Apr-1987 D A Gwyn
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/* 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;
|
||||
}
|
37
lang/cem/libcc.ansi/misc/rewinddir.c
Normal file
37
lang/cem/libcc.ansi/misc/rewinddir.c
Normal file
|
@ -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 <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
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 */
|
||||
}
|
109
lang/cem/libcc.ansi/misc/seekdir.c
Normal file
109
lang/cem/libcc.ansi/misc/seekdir.c
Normal file
|
@ -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 <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
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 */
|
||||
}
|
||||
}
|
||||
}
|
47
lang/cem/libcc.ansi/misc/sleep.c
Normal file
47
lang/cem/libcc.ansi/misc/sleep.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* sleep - suspend current process for a number of seconds
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
34
lang/cem/libcc.ansi/misc/telldir.c
Normal file
34
lang/cem/libcc.ansi/misc/telldir.c
Normal file
|
@ -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 <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
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 );
|
||||
}
|
428
lang/cem/libcc.ansi/misc/termcap.c
Normal file
428
lang/cem/libcc.ansi/misc/termcap.c
Normal file
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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...
|
||||
*/
|
Loading…
Reference in a new issue