1
0
Files
irix-657m-src/eoe/cmd/bru/sys2.c
2022-09-29 17:59:04 +03:00

565 lines
13 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* This file contains intersystem compatibility routines derived from
* various public domain sources. This file is not subject to any of
* the licensing or distribution restrictions applicable to the rest
* of the bru source code. It is provided to improved transportability
* of bru source code between various flavors of unix.
*
* Fred Fish, Oct 1985.
*/
/*
* NOTE: The directory access routines are derived from a
* public domain version of the BSD compatible directory access
* library by Doug Gwyn at BRL. They are not subject to any distribution
* restrictions and Doug's contribution to the Unix community
* is gratefully acknowledged. They are provided for
* convenience in using the bru source code on non-BSD systems.
* They have been reformatted to fit in with the style in the
* rest of the bru source code but other than that are essentially
* unchanged.
*
* To disable use of these internal routines, and use the equivalent
* in a library available on your system, define "HAVE_SEEKDIR" in
* either CFLAGS in the makefile or in autoconfig.h.
*/
#include "autoconfig.h"
#include <stdio.h>
#include "typedefs.h"
#include "config.h"
#include "dbug.h"
#if unix && !HAVE_SEEKDIR
#include "dir.h"
#if unix || xenix
# include <sys/types.h>
# include <sys/stat.h>
#else
# include "sys.h"
#endif
extern VOID *get_memory ();
/* extern char *s_malloc (); */
extern int s_open ();
extern int s_fstat ();
extern VOID s_free ();
extern int s_close ();
extern int s_read ();
extern char *s_strncpy ();
extern int s_strlen ();
extern long s_lseek ();
#ifndef NULL
#define NULL 0
#endif
#define DIRSIZ 14
struct olddir {
ino_t od_ino; /* inode */
char od_name[DIRSIZ]; /* filename */
};
/*
* closedir -- C library extension routine
*
* last edit: 21-Jan-1984 D A Gwyn
*/
VOID closedir (dirp)
register DIR *dirp; /* stream from opendir() */
{
(VOID) s_close (dirp -> dd_fd);
s_free ((char *) dirp);
}
/*
* opendir -- C library extension routine
*
* last edit: 09-Jul-1983 D A Gwyn
*/
DIR *opendir (filename)
char *filename; /* name of directory */
{
register DIR *dirp; /* -> malloc'ed storage */
register int fd; /* file descriptor for read */
struct stat64 sbuf; /* result of fstat() */
if ((fd = s_open (filename, 0, 0)) < 0) {
return (NULL);
}
if (s_fstat (fd, &sbuf) < 0
|| (sbuf.st_mode & S_IFMT) != S_IFDIR
|| (dirp = (DIR *) get_memory (sizeof (DIR), 0)) == NULL
) {
(VOID) s_close (fd);
return (NULL); /* bad luck today */
}
dirp -> dd_fd = fd;
dirp -> dd_loc = dirp -> dd_size = 0; /* refill needed */
return (dirp);
}
/*
* readdir -- C library extension routine for non-BSD UNIX
*
* last edit: 09-Jul-1983 D A Gwyn
*/
struct direct *readdir (dirp)
register DIR *dirp; /* stream from opendir() */
{
register struct olddir *dp; /* -> directory data */
for (;;) {
if (dirp -> dd_loc >= dirp -> dd_size) {
dirp -> dd_loc = dirp -> dd_size = 0;
}
if (dirp -> dd_size == 0 /* refill buffer */
&& (dirp -> dd_size = s_read (dirp -> dd_fd, dirp -> dd_buf,
DIRBLKSIZ
)
) <= 0
)
return (NULL); /* error or EOF */
dp = (struct olddir *) &(dirp -> dd_buf[dirp -> dd_loc]);
dirp -> dd_loc += sizeof (struct olddir);
if (dp -> od_ino != 0) { /* not deleted entry */
static struct direct dir; /* simulated */
dir.d_ino = dp -> od_ino;
(VOID) s_strncpy (dir.d_name, dp -> od_name, DIRSIZ);
dir.d_name[DIRSIZ] = '\0';
dir.d_namlen = s_strlen (dir.d_name);
dir.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3;
dir.d_reclen += dir.d_namlen - dir.d_namlen % 4;
return (&dir); /* -> simulated structure */
}
}
}
/*
* seekdir -- C library extension routine
*
* last edit: 21-Jan-1984 D A Gwyn
*/
VOID seekdir (dirp, loc)
register DIR *dirp; /* stream from opendir() */
long loc; /* position from telldir() */
{
long base; /* file location of block */
long offset; /* offset within block */
if (telldir (dirp) == loc) {
return; /* save time */
}
offset = loc % DIRBLKSIZ;
base = loc - offset;
(VOID) s_lseek (dirp -> dd_fd, base, 0); /* change blocks */
dirp -> dd_loc = dirp -> dd_size = 0;
while (dirp -> dd_loc < offset) { /* skip entries */
if (readdir (dirp) == NULL) {
return; /* "can't happen" */
}
}
}
/*
* telldir -- C library extension routine
*
* last edit: 09-Jul-1983 D A Gwyn
*/
long telldir (dirp)
DIR *dirp; /* stream from opendir() */
{
return (s_lseek (dirp -> dd_fd, 0L, 1) - (long) dirp -> dd_size
+ (long) dirp -> dd_loc);
}
#endif /* !HAVE_SEEKDIR */
#if BSD4_2 || xenix || amiga
#include "manifest.h"
#include <ctype.h>
#endif
#if BSD4_2 || amiga
#ifndef amiga
#include <errno.h>
#endif
#include "utsname.h"
extern int errno;
extern char *s_strcpy ();
extern char *s_strncpy ();
/* strtok --- s1 is tokens separated by stuff in s2, see S5 man page */
char *strtok (s1, s2)
char *s1, *s2;
{
static char *save = NULL; /* save the string between calls */
char *cp;
extern char *s_strchr ();
DBUG_ENTER ("strtok");
DBUG_PRINT ("strtok", ("s1 = <%s>, s2 = <%s>", s1, s2));
if (s1 != NULL) { /* first call */
save = s1;
} else if (save == NULL || *save == EOS) { /* no saved string, or empty */
DBUG_RETURN ((char *) NULL);
}
for (; *save && s_strchr (s2, *save) != NULL; save++) { ; }
/* skip leading token separators */
if (*save == EOS) {
save = NULL;
DBUG_RETURN ((char *) NULL);
}
cp = save; /* save start of string */
while (*save != EOS && s_strchr (s2, *save) == NULL) {
save++; /* skip non separators (the body of the token) */
}
if (*save == EOS) {
if (cp == save) { /* do the test before clearing save */
cp = save = NULL;
}
/* else cp is ok */
DBUG_RETURN (cp);
} else {
*save++ = EOS;
}
/* clobber trailing separator, and increment save */
if (cp == save) {
cp = NULL;
}
DBUG_RETURN (cp);
}
#endif /* BSD4_2 */
/* strtol --- convert an arbitrary base number to a long int, see S5 manual */
#if BSD4_2 || xenix || amiga
long strtol (str, ptr, base)
char *str, **ptr;
int base;
{
long val = 0L;
int sign = FALSE;
int converted = FALSE;
char *save = str;
int lim; /* limiting character not in base */
DBUG_ENTER ("strtol");
while (isspace (*str)) {
str++;
}
if (*str == '-') {
str++;
sign = TRUE;
} else if (*str == '+') {
str++;
}
if (base < 0 || base > 36) {
base = 0; /* don't use it */
}
if (base == 0) {
if (*str == '0' && s_tolower (str[1]) == 'x') {
str += 2;
base = 16;
} else if (*str == '0') {
base = 8;
} else {
base = 10;
}
} else if (base == 16 && *str == '0' && s_tolower (str[1]) == 'x') {
str += 2;
}
if (base == 10) {
lim = '9' + 1;
} else if (base > 10) {
lim = base - 10 + 'a'; /* >= lim is not range */
} else {
lim = base + '0';
}
DBUG_PRINT ("strtol", ("base %d lim '%c'", base, lim));
while (*str == '0') {
str++;
}
for (; *str; str++) {
DBUG_PRINT ("strtol", ("examining '%c'", *str));
if (! isalnum (*str) || s_tolower(*str) >= lim
|| s_tolower(*str) < '0') {
break;
}
val *= base;
if (isalpha (*str)) {
val += s_tolower (*str) - 'a';
} else {
val += *str - '0';
}
converted = TRUE;
}
if (sign) {
val = -val;
DBUG_PRINT ("strtol", ("number is negative"));
}
if (ptr != NULL) {
if (! converted) {
*ptr = save;
val = 0L;
} else {
*ptr = str;
}
}
DBUG_RETURN (val);
}
#endif /* BSD4_2 or xenix */
#if BSD4_2 || amiga
/*
* From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985
* Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET
* Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP
* Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix
* From: std-unix@ut-sally.UUCP (Moderator, John Quarterman)
* Newsgroups: mod.std.unix
* Subject: public domain AT&T getopt source
* Message-ID: <3352@ut-sally.UUCP>
* Date: 3 Nov 85 19:34:15 GMT
* Date-Received: 4 Nov 85 12:25:09 GMT
* Organization: IEEE/P1003 Portable Operating System Environment Committee
* Lines: 91
* Approved: jsq@ut-sally.UUCP
*
* Here's something you've all been waiting for: the AT&T public domain
* source for getopt(3). It is the code which was given out at the 1985
* UNIFORUM conference in Dallas. I obtained it by electronic mail
* directly from AT&T. The people there assure me that it is indeed
* in the public domain.
*
* There is no manual page. That is because the one they gave out at
* UNIFORUM was slightly different from the current System V Release 2
* manual page. The difference apparently involved a note about the
* famous rules 5 and 6, recommending using white space between an option
* and its first argument, and not grouping options that have arguments.
* Getopt itself is currently lenient about both of these things White
* space is allowed, but not mandatory, and the last option in a group can
* have an argument. That particular version of the man page evidently
* has no official existence, and my source at AT&T did not send a copy.
* The current SVR2 man page reflects the actual behavor of this getopt.
* However, I am not about to post a copy of anything licensed by AT&T.
*
* I will submit this source to Berkeley as a bug fix.
*
* I, personally, make no claims or guarantees of any kind about the
* following source. I did compile it to get some confidence that
* it arrived whole, but beyond that you're on your own.
*
*/
/*LINTLIBRARY*/
#ifndef NULL
#define NULL 0
#endif
#ifndef EOF
#define EOF (-1)
#endif
#define ERR(s, c) if(opterr){\
extern int s_strlen(), s_write();\
char errbuf[2];\
errbuf[0] = c; errbuf[1] = '\n';\
(VOID) s_write(2, argv[0], (unsigned)s_strlen(argv[0]));\
(VOID) s_write(2, s, (unsigned)s_strlen(s));\
(VOID) s_write(2, errbuf, (unsigned)2);}
extern int s_strcmp();
extern char *s_strchr();
int opterr = 1;
int optind = 1;
int optopt;
char *optarg;
int
getopt(argc, argv, opts)
int argc;
char **argv, *opts;
{
static int sp = 1;
register int c;
register char *cp;
if(sp == 1)
if(optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return(EOF);
else if(s_strcmp(argv[optind], "--") == NULL) {
optind++;
return(EOF);
}
optopt = c = argv[optind][sp];
if(c == ':' || (cp=s_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);
}
/*
uname -- system call emulation for 4.2BSD
based on System V Emulation from BRL
original's last edit: 05-Mar-1984 D A Gwyn
last edit: 18-Jun-1985 Arnold Robbins
*/
/* note that all stuff which originates at BRL is public domain */
static int s_gethostname ();
#ifndef EFAULT
#define EFAULT 0
#endif
int uname (name)
register struct utsname *name; /* where to put results */
{
register char *np; /* -> array being cleared */
if (name == NULL) {
errno = EFAULT;
return -1;
}
for (np = name->nodename; np < &name->nodename[sizeof(name->nodename)];
np++)
*np = '\0'; /* for cleanliness */
if (s_gethostname (name->nodename, sizeof (name->nodename)) != 0)
(VOID) s_strcpy (name->nodename, "unknown");
(VOID) s_strncpy (name->sysname, name->nodename, sizeof (name->sysname));
#ifdef amiga
(VOID) s_strncpy (name->release, "AmigaDos", sizeof (name->release));
#else
(VOID) s_strncpy (name->release, "4.2BSD", sizeof (name->release));
#endif
(VOID) s_strncpy (name->version, "vm", sizeof (name->version));
(VOID) s_strncpy (name->machine,
#ifdef interdata
"interdata",
#else
#ifdef pdp11
"pdp11",
#else
#ifdef sun
"sun",
#else
#ifdef u370
"u370",
#else
#ifdef u3b
"u3b",
#else
#ifdef vax
"vax",
#else
#ifdef pyr
"pyramid",
#else
#ifdef amiga
"amiga",
#else
"unknown",
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#endif
sizeof name->machine);
/* add a trailing end of string, just to be sure -- ADR */
name->sysname [sizeof (name->sysname) - 1] = '\0';
name->nodename [sizeof (name->nodename) - 1] = '\0';
name->release [sizeof (name->release) - 1] = '\0';
name->version [sizeof (name->version) - 1] = '\0';
name->machine [sizeof (name->machine) - 1] = '\0';
return 0;
}
extern int gethostname();
static int s_gethostname (name, namelen)
char *name;
int namelen;
{
#if unix || xenix
#ifdef lint
return (gethostname (name, (int *) namelen)); /* Stupid lint lib! */
#else
return (gethostname (name, namelen));
#endif /* lint */
#else
return (-1);
#endif
}
#endif /* BSD4_2 */