|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* misc.c - common miscellaneous functions for lsof
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
|
|
Packit |
6f02de |
* 47907. All rights reserved.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* Written by Victor A. Abell
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* This software is not subject to any license of the American Telephone
|
|
Packit |
6f02de |
* and Telegraph Company or the Regents of the University of California.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* Permission is granted to anyone to use this software for any purpose on
|
|
Packit |
6f02de |
* any computer system, and to alter it and redistribute it freely, subject
|
|
Packit |
6f02de |
* to the following restrictions:
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* 1. Neither the authors nor Purdue University are responsible for any
|
|
Packit |
6f02de |
* consequences of the use of this software.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* 2. The origin of this software must not be misrepresented, either by
|
|
Packit |
6f02de |
* explicit claim or by omission. Credit to the authors and Purdue
|
|
Packit |
6f02de |
* University must appear in documentation and sources.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* 3. Altered versions must be plainly marked as such, and must not be
|
|
Packit |
6f02de |
* misrepresented as being the original software.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* 4. This notice may not be removed or altered.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#ifndef lint
|
|
Packit |
6f02de |
static char copyright[] =
|
|
Packit |
6f02de |
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
|
|
Packit |
6f02de |
static char *rcsid = "$Id: misc.c,v 1.29 2018/02/14 14:20:14 abe Exp $";
|
|
Packit |
6f02de |
#endif
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#include "lsof.h"
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASWIDECHAR)
|
|
Packit |
6f02de |
# if defined(WIDECHARINCL)
|
|
Packit |
6f02de |
#include WIDECHARINCL
|
|
Packit |
6f02de |
# endif /* defined(WIDECHARINCL) */
|
|
Packit |
6f02de |
# if defined(HASWCTYPE_H)
|
|
Packit |
6f02de |
#include <wctype.h>
|
|
Packit |
6f02de |
# endif /* defined(HASWCTYPE_H) */
|
|
Packit |
6f02de |
#endif /* defined(HASWIDECHAR) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Local definitions
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if !defined(MAXSYMLINKS)
|
|
Packit |
6f02de |
#define MAXSYMLINKS 32
|
|
Packit |
6f02de |
#endif /* !defined(MAXSYMLINKS) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Local function prototypes
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
_PROTOTYPE(static void closePipes,(void));
|
|
Packit |
6f02de |
_PROTOTYPE(static int dolstat,(char *path, char *buf, int len));
|
|
Packit |
6f02de |
_PROTOTYPE(static int dostat,(char *path, char *buf, int len));
|
|
Packit |
6f02de |
_PROTOTYPE(static int doreadlink,(char *path, char *buf, int len));
|
|
Packit |
6f02de |
_PROTOTYPE(static int doinchild,(int (*fn)(), char *fp, char *rbuf, int rbln));
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASINTSIGNAL)
|
|
Packit |
6f02de |
_PROTOTYPE(static int handleint,(int sig));
|
|
Packit |
6f02de |
#else /* !defined(HASINTSIGNAL) */
|
|
Packit |
6f02de |
_PROTOTYPE(static void handleint,(int sig));
|
|
Packit |
6f02de |
#endif /* defined(HASINTSIGNAL) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Local variables
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static pid_t Cpid = 0; /* child PID */
|
|
Packit |
6f02de |
static jmp_buf Jmp_buf; /* jump buffer */
|
|
Packit |
6f02de |
static int Pipes[] = /* pipes for child process */
|
|
Packit |
6f02de |
{ -1, -1, -1, -1 };
|
|
Packit |
6f02de |
static int CtSigs[] = { 0, SIGINT, SIGKILL };
|
|
Packit |
6f02de |
/* child termination signals (in order
|
|
Packit |
6f02de |
* of application) -- the first is a
|
|
Packit |
6f02de |
* dummy to allow pipe closure to
|
|
Packit |
6f02de |
* cause the child to exit */
|
|
Packit |
6f02de |
#define NCTSIGS (sizeof(CtSigs) / sizeof(int))
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASNLIST)
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* build-Nl() - build kernel name list table
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static struct drive_Nl *Build_Nl = (struct drive_Nl *)NULL;
|
|
Packit |
6f02de |
/* the default Drive_Nl address */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
build_Nl(d)
|
|
Packit |
6f02de |
struct drive_Nl *d; /* data to drive the construction */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
struct drive_Nl *dp;
|
|
Packit |
6f02de |
int i, n;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
for (dp = d, n = 0; dp->nn; dp++, n++)
|
|
Packit |
6f02de |
;
|
|
Packit |
6f02de |
if (n < 1) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: can't calculate kernel name list length\n", Pn);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (!(Nl = (struct NLIST_TYPE *)calloc((n + 1),
|
|
Packit |
6f02de |
sizeof(struct NLIST_TYPE))))
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: can't allocate %d bytes to kernel name list structure\n",
|
|
Packit |
6f02de |
Pn, (int)((n + 1) * sizeof(struct NLIST_TYPE)));
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
for (dp = d, i = 0; i < n; dp++, i++) {
|
|
Packit |
6f02de |
Nl[i].NL_NAME = dp->knm;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
Nll = (int)((n + 1) * sizeof(struct NLIST_TYPE));
|
|
Packit |
6f02de |
Build_Nl = d;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
#endif /* defined(HASNLIST) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* childx() - make child process exit (if possible)
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
childx()
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
static int at, sx;
|
|
Packit |
6f02de |
pid_t wpid;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (Cpid > 1) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* First close the pipes to and from the child. That should cause the
|
|
Packit |
6f02de |
* child to exit. Compute alarm time shares.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
(void) closePipes();
|
|
Packit |
6f02de |
if ((at = TmLimit / NCTSIGS) < TMLIMMIN)
|
|
Packit |
6f02de |
at = TMLIMMIN;
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Loop, waiting for the child to exit. After the first pass, help
|
|
Packit |
6f02de |
* the child exit by sending it signals.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
for (sx = 0; sx < NCTSIGS; sx++) {
|
|
Packit |
6f02de |
if (setjmp(Jmp_buf)) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* An alarm has rung. Disable further alarms.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* If there are more signals to send, continue the signal loop.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* If the last signal has been sent, issue a warning (unless
|
|
Packit |
6f02de |
* warninge have been suppressed) and exit the signal loop.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
(void) alarm(0);
|
|
Packit |
6f02de |
(void) signal(SIGALRM, SIG_DFL);
|
|
Packit |
6f02de |
if (sx < (NCTSIGS - 1))
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
if (!Fwarn)
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: WARNING -- child process %d may be hung.\n",
|
|
Packit |
6f02de |
Pn, (int)Cpid);
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Send the next signal to the child process, after the first pass
|
|
Packit |
6f02de |
* through the loop.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* Wrap the wait() with an alarm.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (sx)
|
|
Packit |
6f02de |
(void) kill(Cpid, CtSigs[sx]);
|
|
Packit |
6f02de |
(void) signal(SIGALRM, handleint);
|
|
Packit |
6f02de |
(void) alarm(at);
|
|
Packit |
6f02de |
wpid = (pid_t) wait(NULL);
|
|
Packit |
6f02de |
(void) alarm(0);
|
|
Packit |
6f02de |
(void) signal(SIGALRM, SIG_DFL);
|
|
Packit |
6f02de |
if (wpid == Cpid)
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
Cpid = 0;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* closePipes() - close open pipe file descriptors
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static void
|
|
Packit |
6f02de |
closePipes()
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
int i;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
for (i = 0; i < 4; i++) {
|
|
Packit |
6f02de |
if (Pipes[i] >= 0) {
|
|
Packit |
6f02de |
(void) close(Pipes[i]);
|
|
Packit |
6f02de |
Pipes[i] = -1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* compdev() - compare Devtp[] entries
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
compdev(a1, a2)
|
|
Packit |
6f02de |
COMP_P *a1, *a2;
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
struct l_dev **p1 = (struct l_dev **)a1;
|
|
Packit |
6f02de |
struct l_dev **p2 = (struct l_dev **)a2;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if ((dev_t)((*p1)->rdev) < (dev_t)((*p2)->rdev))
|
|
Packit |
6f02de |
return(-1);
|
|
Packit |
6f02de |
if ((dev_t)((*p1)->rdev) > (dev_t)((*p2)->rdev))
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
if ((INODETYPE)((*p1)->inode) < (INODETYPE)((*p2)->inode))
|
|
Packit |
6f02de |
return(-1);
|
|
Packit |
6f02de |
if ((INODETYPE)((*p1)->inode) > (INODETYPE)((*p2)->inode))
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
return(strcmp((*p1)->name, (*p2)->name));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* doinchild() -- do a function in a child process
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static int
|
|
Packit |
6f02de |
doinchild(fn, fp, rbuf, rbln)
|
|
Packit |
6f02de |
int (*fn)(); /* function to perform */
|
|
Packit |
6f02de |
char *fp; /* function parameter */
|
|
Packit |
6f02de |
char *rbuf; /* response buffer */
|
|
Packit |
6f02de |
int rbln; /* response buffer length */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
int en, rv;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Check reply buffer size.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!Fovhd && rbln > MAXPATHLEN) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: doinchild error; response buffer too large: %d\n",
|
|
Packit |
6f02de |
Pn, rbln);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Set up to handle an alarm signal; handle an alarm signal; build
|
|
Packit |
6f02de |
* pipes for exchanging information with a child process; start the
|
|
Packit |
6f02de |
* child process; and perform functions in the child process.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!Fovhd) {
|
|
Packit |
6f02de |
if (setjmp(Jmp_buf)) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Process an alarm that has rung.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
(void) alarm(0);
|
|
Packit |
6f02de |
(void) signal(SIGALRM, SIG_DFL);
|
|
Packit |
6f02de |
(void) childx();
|
|
Packit |
6f02de |
errno = ETIMEDOUT;
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
} else if (!Cpid) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Create pipes to exchange function information with a child
|
|
Packit |
6f02de |
* process.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (pipe(Pipes) < 0 || pipe(&Pipes[2]) < 0) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: can't open pipes: %s\n",
|
|
Packit |
6f02de |
Pn, strerror(errno));
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Fork a child to execute functions.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if ((Cpid = fork()) == 0) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Begin the child process.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int r_al, r_rbln;
|
|
Packit |
6f02de |
char r_arg[MAXPATHLEN+1], r_rbuf[MAXPATHLEN+1];
|
|
Packit |
6f02de |
int (*r_fn)();
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Close sufficient open file descriptors except Pipes[0] and
|
|
Packit |
6f02de |
* Pipes[3].
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HAS_DUP2) && defined(HAS_CLOSEFROM)
|
|
Packit |
6f02de |
int rc;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
rc = dup2(Pipes[0], 0);
|
|
Packit |
6f02de |
if (rc < 0) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: can't dup Pipes[0] to fd 0: %s\n",
|
|
Packit |
6f02de |
Pn, strerror(errno));
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
Pipes[0] = 0;
|
|
Packit |
6f02de |
rc = dup2(Pipes[3], 1);
|
|
Packit |
6f02de |
if (rc < 0) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: can't dup Pipes.[3] to fd 1: %s\n",
|
|
Packit |
6f02de |
Pn, strerror(errno));
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
Pipes[3] = 1;
|
|
Packit |
6f02de |
(void) closefrom(2);
|
|
Packit |
6f02de |
Pipes[1] = -1;
|
|
Packit |
6f02de |
Pipes[2] = -1;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#else /* !defined(HAS_DUP2) && !defined(HAS_CLOSEFROM) */
|
|
Packit |
6f02de |
int fd;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
for (fd = 0; fd < MaxFd; fd++) {
|
|
Packit |
6f02de |
if (fd == Pipes[0] || fd == Pipes[3])
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
(void) close(fd);
|
|
Packit |
6f02de |
if (fd == Pipes[1])
|
|
Packit |
6f02de |
Pipes[1] = -1;
|
|
Packit |
6f02de |
else if (fd == Pipes[2])
|
|
Packit |
6f02de |
Pipes[2] = -1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (Pipes[1] >= 0) {
|
|
Packit |
6f02de |
(void) close(Pipes[1]);
|
|
Packit |
6f02de |
Pipes[1] = -1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (Pipes[2] >= 0) {
|
|
Packit |
6f02de |
(void) close(Pipes[2]);
|
|
Packit |
6f02de |
Pipes[2] = -1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
#endif /* defined(HAS_DUP2) && defined(HAS_CLOSEFROM) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Read function requests, process them, and return replies.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
for (;;) {
|
|
Packit |
6f02de |
if (read(Pipes[0], (char *)&r_fn, sizeof(r_fn))
|
|
Packit |
6f02de |
!= (int)sizeof(r_fn)
|
|
Packit |
6f02de |
|| read(Pipes[0], (char *)&r_al, sizeof(int))
|
|
Packit |
6f02de |
!= (int)sizeof(int)
|
|
Packit |
6f02de |
|| r_al < 1
|
|
Packit |
6f02de |
|| r_al > (int)sizeof(r_arg)
|
|
Packit |
6f02de |
|| read(Pipes[0], r_arg, r_al) != r_al
|
|
Packit |
6f02de |
|| read(Pipes[0], (char *)&r_rbln, sizeof(r_rbln))
|
|
Packit |
6f02de |
!= (int)sizeof(r_rbln)
|
|
Packit |
6f02de |
|| r_rbln < 1 || r_rbln > (int)sizeof(r_rbuf))
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
rv = r_fn(r_arg, r_rbuf, r_rbln);
|
|
Packit |
6f02de |
en = errno;
|
|
Packit |
6f02de |
if (write(Pipes[3], (char *)&rv, sizeof(rv))
|
|
Packit |
6f02de |
!= sizeof(rv)
|
|
Packit |
6f02de |
|| write(Pipes[3], (char *)&en, sizeof(en))
|
|
Packit |
6f02de |
!= sizeof(en)
|
|
Packit |
6f02de |
|| write(Pipes[3], r_rbuf, r_rbln) != r_rbln)
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
(void) _exit(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Continue in the parent process to finish the setup.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (Cpid < 0) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: can't fork: %s\n",
|
|
Packit |
6f02de |
Pn, strerror(errno));
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
(void) close(Pipes[0]);
|
|
Packit |
6f02de |
(void) close(Pipes[3]);
|
|
Packit |
6f02de |
Pipes[0] = Pipes[3] = -1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (!Fovhd) {
|
|
Packit |
6f02de |
int len;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Send a function to the child and wait for the response.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
len = strlen(fp) + 1;
|
|
Packit |
6f02de |
(void) signal(SIGALRM, handleint);
|
|
Packit |
6f02de |
(void) alarm(TmLimit);
|
|
Packit |
6f02de |
if (write(Pipes[1], (char *)&fn, sizeof(fn)) != sizeof(fn)
|
|
Packit |
6f02de |
|| write(Pipes[1], (char *)&len, sizeof(len)) != sizeof(len)
|
|
Packit |
6f02de |
|| write(Pipes[1], fp, len) != len
|
|
Packit |
6f02de |
|| write(Pipes[1], (char *)&rbln, sizeof(rbln)) != sizeof(rbln)
|
|
Packit |
6f02de |
|| read(Pipes[2], (char *)&rv, sizeof(rv)) != sizeof(rv)
|
|
Packit |
6f02de |
|| read(Pipes[2], (char *)&en, sizeof(en)) != sizeof(en)
|
|
Packit |
6f02de |
|| read(Pipes[2], rbuf, rbln) != rbln) {
|
|
Packit |
6f02de |
(void) alarm(0);
|
|
Packit |
6f02de |
(void) signal(SIGALRM, SIG_DFL);
|
|
Packit |
6f02de |
(void) childx();
|
|
Packit |
6f02de |
errno = ECHILD;
|
|
Packit |
6f02de |
return(-1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Do the operation directly -- not in a child.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
(void) signal(SIGALRM, handleint);
|
|
Packit |
6f02de |
(void) alarm(TmLimit);
|
|
Packit |
6f02de |
rv = fn(fp, rbuf, rbln);
|
|
Packit |
6f02de |
en = errno;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Function completed, response collected -- complete the operation.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
(void) alarm(0);
|
|
Packit |
6f02de |
(void) signal(SIGALRM, SIG_DFL);
|
|
Packit |
6f02de |
errno = en;
|
|
Packit |
6f02de |
return(rv);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* dolstat() - do an lstat() function
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static int
|
|
Packit |
6f02de |
dolstat(path, rbuf, rbln)
|
|
Packit |
6f02de |
char *path; /* path */
|
|
Packit |
6f02de |
char *rbuf; /* response buffer */
|
|
Packit |
6f02de |
int rbln; /* response buffer length */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/* ARGSUSED */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
return(lstat(path, (struct stat *)rbuf));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* doreadlink() -- do a readlink() function
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static int
|
|
Packit |
6f02de |
doreadlink(path, rbuf, rbln)
|
|
Packit |
6f02de |
char *path; /* path */
|
|
Packit |
6f02de |
char *rbuf; /* response buffer */
|
|
Packit |
6f02de |
int rbln; /* response buffer length */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
return(readlink(path, rbuf, rbln));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* dostat() - do a stat() function
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
static int
|
|
Packit |
6f02de |
dostat(path, rbuf, rbln)
|
|
Packit |
6f02de |
char *path; /* path */
|
|
Packit |
6f02de |
char *rbuf; /* response buffer */
|
|
Packit |
6f02de |
int rbln; /* response buffer length */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/* ARGSUSED */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
return(stat(path, (struct stat *)rbuf));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(WILLDROPGID)
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* dropgid() - drop setgid permission
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
dropgid()
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (!Setuidroot && Setgid) {
|
|
Packit |
6f02de |
if (setgid(Mygid) < 0) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: can't setgid(%d): %s\n",
|
|
Packit |
6f02de |
Pn, (int)Mygid, strerror(errno));
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
Setgid = 0;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
#endif /* defined(WILLDROPGID) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* enter_dev_ch() - enter device characters in file structure
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
enter_dev_ch(m)
|
|
Packit |
6f02de |
char *m;
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char *mp;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (!m || *m == '\0')
|
|
Packit |
6f02de |
return;
|
|
Packit |
6f02de |
if (!(mp = mkstrcpy(m, (MALLOC_S *)NULL))) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: no more dev_ch space at PID %d: \n",
|
|
Packit |
6f02de |
Pn, Lp->pid);
|
|
Packit |
6f02de |
safestrprt(m, stderr, 1);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (Lf->dev_ch)
|
|
Packit |
6f02de |
(void) free((FREE_P *)Lf->dev_ch);
|
|
Packit |
6f02de |
Lf->dev_ch = mp;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* enter_IPstate() -- enter a TCP or UDP state
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
enter_IPstate(ty, nm, nr)
|
|
Packit |
6f02de |
char *ty; /* type -- TCP or UDP */
|
|
Packit |
6f02de |
char *nm; /* state name (may be NULL) */
|
|
Packit |
6f02de |
int nr; /* state number */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(USE_LIB_PRINT_TCPTPI)
|
|
Packit |
6f02de |
TcpNstates = nr;
|
|
Packit |
6f02de |
#else /* !defined(USE_LIB_PRINT_TCPTPI) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int al, i, j, oc, nn, ns, off, tx;
|
|
Packit |
6f02de |
char *cp;
|
|
Packit |
6f02de |
MALLOC_S len;
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Check the type name and set the type index.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!ty) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: no type specified to enter_IPstate()\n", Pn);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (!strcmp(ty, "TCP"))
|
|
Packit |
6f02de |
tx = 0;
|
|
Packit |
6f02de |
else if (!strcmp(ty, "UDP"))
|
|
Packit |
6f02de |
tx = 1;
|
|
Packit |
6f02de |
else {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: unknown type for enter_IPstate: %s\n",
|
|
Packit |
6f02de |
Pn, ty);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* If the name argument is NULL, reduce the allocated table to its minimum
|
|
Packit |
6f02de |
* size.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!nm) {
|
|
Packit |
6f02de |
if (tx) {
|
|
Packit |
6f02de |
if (UdpSt) {
|
|
Packit |
6f02de |
if (!UdpNstates) {
|
|
Packit |
6f02de |
(void) free((MALLOC_P *)UdpSt);
|
|
Packit |
6f02de |
UdpSt = (char **)NULL;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (UdpNstates < UdpStAlloc) {
|
|
Packit |
6f02de |
len = (MALLOC_S)(UdpNstates * sizeof(char *));
|
|
Packit |
6f02de |
if (!(UdpSt = (char **)realloc((MALLOC_P *)UdpSt, len)))
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: can't reduce UdpSt[]\n", Pn);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
UdpStAlloc = UdpNstates;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (TcpSt) {
|
|
Packit |
6f02de |
if (!TcpNstates) {
|
|
Packit |
6f02de |
(void) free((MALLOC_P *)TcpSt);
|
|
Packit |
6f02de |
TcpSt = (char **)NULL;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (TcpNstates < TcpStAlloc) {
|
|
Packit |
6f02de |
len = (MALLOC_S)(TcpNstates * sizeof(char *));
|
|
Packit |
6f02de |
if (!(TcpSt = (char **)realloc((MALLOC_P *)TcpSt, len)))
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: can't reduce TcpSt[]\n", Pn);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
TcpStAlloc = TcpNstates;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Check the name and number.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if ((len = (size_t)strlen(nm)) < 1) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: bad %s name (\"%s\"), number=%d\n", Pn, ty, nm, nr);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Make a copy of the name.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!(cp = mkstrcpy(nm, (MALLOC_S *)NULL))) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: enter_IPstate(): no %s space for %s\n",
|
|
Packit |
6f02de |
Pn, ty, nm);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Set the necessary offset for using nr as an index. If it is
|
|
Packit |
6f02de |
* a new offset, adjust previous entries.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if ((nr < 0) && ((off = -nr) > (tx ? UdpStOff : TcpStOff))) {
|
|
Packit |
6f02de |
if (tx ? UdpSt : TcpSt) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* A new, larger offset (smaller negative state number) could mean
|
|
Packit |
6f02de |
* a previously allocated state table must be enlarged and its
|
|
Packit |
6f02de |
* previous entries moved.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
oc = off - (tx ? UdpStOff : TcpStOff);
|
|
Packit |
6f02de |
al = tx ? UdpStAlloc : TcpStAlloc;
|
|
Packit |
6f02de |
ns = tx ? UdpNstates : TcpNstates;
|
|
Packit |
6f02de |
if ((nn = ns + oc) >= al) {
|
|
Packit |
6f02de |
while ((nn + 5) > al) {
|
|
Packit |
6f02de |
al += TCPUDPALLOC;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
len = (MALLOC_S)(al * sizeof(char *));
|
|
Packit |
6f02de |
if (tx) {
|
|
Packit |
6f02de |
if (!(UdpSt = (char **)realloc((MALLOC_P *)UdpSt, len)))
|
|
Packit |
6f02de |
goto no_IP_space;
|
|
Packit |
6f02de |
UdpStAlloc = al;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (!(TcpSt = (char **)realloc((MALLOC_P *)TcpSt, len)))
|
|
Packit |
6f02de |
goto no_IP_space;
|
|
Packit |
6f02de |
TcpStAlloc = al;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
for (i = 0, j = oc; i < oc; i++, j++) {
|
|
Packit |
6f02de |
if (tx) {
|
|
Packit |
6f02de |
if (i < UdpNstates)
|
|
Packit |
6f02de |
UdpSt[j] = UdpSt[i];
|
|
Packit |
6f02de |
UdpSt[i] = (char *)NULL;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (i < TcpNstates)
|
|
Packit |
6f02de |
TcpSt[j] = TcpSt[i];
|
|
Packit |
6f02de |
TcpSt[i] = (char *)NULL;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (tx)
|
|
Packit |
6f02de |
UdpNstates += oc;
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
TcpNstates += oc;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (tx)
|
|
Packit |
6f02de |
UdpStOff = off;
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
TcpStOff = off;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Enter name as {Tc|Ud}pSt[nr + {Tc|Ud}pStOff].
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* Allocate space, as required.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
al = tx ? UdpStAlloc : TcpStAlloc;
|
|
Packit |
6f02de |
off = tx ? UdpStOff : TcpStOff;
|
|
Packit |
6f02de |
nn = nr + off + 1;
|
|
Packit |
6f02de |
if (nn > al) {
|
|
Packit |
6f02de |
i = tx ? UdpNstates : TcpNstates;
|
|
Packit |
6f02de |
while ((nn + 5) > al) {
|
|
Packit |
6f02de |
al += TCPUDPALLOC;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
len = (MALLOC_S)(al * sizeof(char *));
|
|
Packit |
6f02de |
if (tx) {
|
|
Packit |
6f02de |
if (UdpSt)
|
|
Packit |
6f02de |
UdpSt = (char **)realloc((MALLOC_P *)UdpSt, len);
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
UdpSt = (char **)malloc(len);
|
|
Packit |
6f02de |
if (!UdpSt) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
no_IP_space:
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: no %s state space\n", Pn, ty);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
UdpNstates = nn;
|
|
Packit |
6f02de |
UdpStAlloc = al;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (TcpSt)
|
|
Packit |
6f02de |
TcpSt = (char **)realloc((MALLOC_P *)TcpSt, len);
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
TcpSt = (char **)malloc(len);
|
|
Packit |
6f02de |
if (!TcpSt)
|
|
Packit |
6f02de |
goto no_IP_space;
|
|
Packit |
6f02de |
TcpNstates = nn;
|
|
Packit |
6f02de |
TcpStAlloc = al;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
while (i < al) {
|
|
Packit |
6f02de |
if (tx)
|
|
Packit |
6f02de |
UdpSt[i] = (char *)NULL;
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
TcpSt[i] = (char *)NULL;
|
|
Packit |
6f02de |
i++;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (tx) {
|
|
Packit |
6f02de |
if (nn > UdpNstates)
|
|
Packit |
6f02de |
UdpNstates = nn;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (nn > TcpNstates)
|
|
Packit |
6f02de |
TcpNstates = nn;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (tx) {
|
|
Packit |
6f02de |
if (UdpSt[nr + UdpStOff]) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
dup_IP_state:
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: duplicate %s state %d (already %s): %s\n",
|
|
Packit |
6f02de |
Pn, ty, nr,
|
|
Packit |
6f02de |
tx ? UdpSt[nr + UdpStOff] : TcpSt[nr + TcpStOff],
|
|
Packit |
6f02de |
nm);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
UdpSt[nr + UdpStOff] = cp;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if (TcpSt[nr + TcpStOff])
|
|
Packit |
6f02de |
goto dup_IP_state;
|
|
Packit |
6f02de |
TcpSt[nr + TcpStOff] = cp;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
#endif /* defined(USE_LIB_PRINT_TCPTPI) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* enter_nm() - enter name in local file structure
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
enter_nm(m)
|
|
Packit |
6f02de |
char *m;
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char *mp;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (!m || *m == '\0')
|
|
Packit |
6f02de |
return;
|
|
Packit |
6f02de |
if (!(mp = mkstrcpy(m, (MALLOC_S *)NULL))) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: no more nm space at PID %d for: ",
|
|
Packit |
6f02de |
Pn, Lp->pid);
|
|
Packit |
6f02de |
safestrprt(m, stderr, 1);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (Lf->nm)
|
|
Packit |
6f02de |
(void) free((FREE_P *)Lf->nm);
|
|
Packit |
6f02de |
Lf->nm = mp;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Exit() - do a clean exit()
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
Exit(xv)
|
|
Packit |
6f02de |
int xv; /* exit() value */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
(void) childx();
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASDCACHE)
|
|
Packit |
6f02de |
if (DCrebuilt && !Fwarn)
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: WARNING: %s was updated.\n",
|
|
Packit |
6f02de |
Pn, DCpath[DCpathX]);
|
|
Packit |
6f02de |
#endif /* defined(HASDCACHE) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
exit(xv);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASNLIST)
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* get_Nl_value() - get Nl value for nickname
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
get_Nl_value(nn, d, v)
|
|
Packit |
6f02de |
char *nn; /* nickname of requested entry */
|
|
Packit |
6f02de |
struct drive_Nl *d; /* drive_Nl table that built Nl
|
|
Packit |
6f02de |
* (if NULL, use Build_Nl) */
|
|
Packit |
6f02de |
KA_T *v; /* returned value (if NULL,
|
|
Packit |
6f02de |
* return nothing) */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
int i;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (!Nl || !Nll)
|
|
Packit |
6f02de |
return(-1);
|
|
Packit |
6f02de |
if (!d)
|
|
Packit |
6f02de |
d = Build_Nl;
|
|
Packit |
6f02de |
for (i = 0; d->nn; d++, i++) {
|
|
Packit |
6f02de |
if (strcmp(d->nn, nn) == 0) {
|
|
Packit |
6f02de |
if (v)
|
|
Packit |
6f02de |
*v = (KA_T)Nl[i].n_value;
|
|
Packit |
6f02de |
return(i);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(-1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
#endif /* defined(HASNLIST) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* handleint() - handle an interrupt
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASINTSIGNAL)
|
|
Packit |
6f02de |
static int
|
|
Packit |
6f02de |
#else
|
|
Packit |
6f02de |
static void
|
|
Packit |
6f02de |
#endif
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/* ARGSUSED */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
handleint(sig)
|
|
Packit |
6f02de |
int sig;
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
longjmp(Jmp_buf, 1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* hashbyname() - hash by name
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
hashbyname(nm, mod)
|
|
Packit |
6f02de |
char *nm; /* pointer to NUL-terminated name */
|
|
Packit |
6f02de |
int mod; /* hash modulus */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
int i, j;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
for (i = j = 0; *nm; nm++) {
|
|
Packit |
6f02de |
i ^= (int)*nm << j;
|
|
Packit |
6f02de |
if (++j > 7)
|
|
Packit |
6f02de |
j = 0;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(((int)(i * 31415)) & (mod - 1));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* is_nw_addr() - is this network address selected?
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
is_nw_addr(ia, p, af)
|
|
Packit |
6f02de |
unsigned char *ia; /* Internet address */
|
|
Packit |
6f02de |
int p; /* port */
|
|
Packit |
6f02de |
int af; /* address family -- e.g., AF_INET,
|
|
Packit |
6f02de |
* AF_INET6 */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
struct nwad *n;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (!(n = Nwad))
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
for (; n; n = n->next) {
|
|
Packit |
6f02de |
if (n->proto) {
|
|
Packit |
6f02de |
if (strcasecmp(n->proto, Lf->iproto) != 0)
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (af && n->af && af != n->af)
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASIPv6)
|
|
Packit |
6f02de |
if (af == AF_INET6) {
|
|
Packit |
6f02de |
if (n->a[15] || n->a[14] || n->a[13] || n->a[12]
|
|
Packit |
6f02de |
|| n->a[11] || n->a[10] || n->a[9] || n->a[8]
|
|
Packit |
6f02de |
|| n->a[7] || n->a[6] || n->a[5] || n->a[4]
|
|
Packit |
6f02de |
|| n->a[3] || n->a[2] || n->a[1] || n->a[0]) {
|
|
Packit |
6f02de |
if (ia[15] != n->a[15] || ia[14] != n->a[14]
|
|
Packit |
6f02de |
|| ia[13] != n->a[13] || ia[12] != n->a[12]
|
|
Packit |
6f02de |
|| ia[11] != n->a[11] || ia[10] != n->a[10]
|
|
Packit |
6f02de |
|| ia[9] != n->a[9] || ia[8] != n->a[8]
|
|
Packit |
6f02de |
|| ia[7] != n->a[7] || ia[6] != n->a[6]
|
|
Packit |
6f02de |
|| ia[5] != n->a[5] || ia[4] != n->a[4]
|
|
Packit |
6f02de |
|| ia[3] != n->a[3] || ia[2] != n->a[2]
|
|
Packit |
6f02de |
|| ia[1] != n->a[1] || ia[0] != n->a[0])
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
} else if (af == AF_INET)
|
|
Packit |
6f02de |
#endif /* defined(HASIPv6) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (n->a[3] || n->a[2] || n->a[1] || n->a[0]) {
|
|
Packit |
6f02de |
if (ia[3] != n->a[3] || ia[2] != n->a[2]
|
|
Packit |
6f02de |
|| ia[1] != n->a[1] || ia[0] != n->a[0])
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASIPv6)
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
#endif /* defined(HASIPv6) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (n->sport == -1 || (p >= n->sport && p <= n->eport)) {
|
|
Packit |
6f02de |
n->f = 1;
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* mkstrcpy() - make a string copy in malloc()'d space
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* return: copy pointer
|
|
Packit |
6f02de |
* copy length (optional)
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
char *
|
|
Packit |
6f02de |
mkstrcpy(src, rlp)
|
|
Packit |
6f02de |
char *src; /* source */
|
|
Packit |
6f02de |
MALLOC_S *rlp; /* returned length pointer (optional)
|
|
Packit |
6f02de |
* The returned length is an strlen()
|
|
Packit |
6f02de |
* equivalent */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
MALLOC_S len;
|
|
Packit |
6f02de |
char *ns;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
len = (MALLOC_S)(src ? strlen(src) : 0);
|
|
Packit |
6f02de |
ns = (char *)malloc(len + 1);
|
|
Packit |
6f02de |
if (ns) {
|
|
Packit |
6f02de |
if (src)
|
|
Packit |
6f02de |
(void) snpf(ns, len + 1, "%s", src);
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
*ns = '\0';
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (rlp)
|
|
Packit |
6f02de |
*rlp = len;
|
|
Packit |
6f02de |
return(ns);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* mkstrcat() - make a catenated copy of up to three strings under optional
|
|
Packit |
6f02de |
* string-by-string count control
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* return: copy pointer
|
|
Packit |
6f02de |
* copy string length (optional)
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
char *
|
|
Packit |
6f02de |
mkstrcat(s1, l1, s2, l2, s3, l3, clp)
|
|
Packit |
6f02de |
char *s1; /* source string 1 */
|
|
Packit |
6f02de |
int l1; /* length of string 1 (-1 if none) */
|
|
Packit |
6f02de |
char *s2; /* source string 2 */
|
|
Packit |
6f02de |
int l2; /* length of string 2 (-1 if none) */
|
|
Packit |
6f02de |
char *s3; /* source string 3 (optional) */
|
|
Packit |
6f02de |
int l3 ; /* length of string 3 (-1 if none) */
|
|
Packit |
6f02de |
MALLOC_S *clp; /* pointer to return of copy length
|
|
Packit |
6f02de |
* (optional) */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
MALLOC_S cl, len1, len2, len3;
|
|
Packit |
6f02de |
char *cp;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (s1)
|
|
Packit |
6f02de |
len1 = (MALLOC_S)((l1 >= 0) ? l1 : strlen(s1));
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
len1 = (MALLOC_S)0;
|
|
Packit |
6f02de |
if (s2)
|
|
Packit |
6f02de |
len2 = (MALLOC_S)((l2 >= 0) ? l2 : strlen(s2));
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
len2 = (MALLOC_S)0;
|
|
Packit |
6f02de |
if (s3)
|
|
Packit |
6f02de |
len3 = (MALLOC_S)((l3 >= 0) ? l3 : strlen(s3));
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
len3 = (MALLOC_S)0;
|
|
Packit |
6f02de |
cl = len1 + len2 + len3;
|
|
Packit |
6f02de |
if ((cp = (char *)malloc(cl + 1))) {
|
|
Packit |
6f02de |
char *tp = cp;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (s1 && len1) {
|
|
Packit |
6f02de |
(void) strncpy(tp, s1, len1);
|
|
Packit |
6f02de |
tp += len1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (s2 && len2) {
|
|
Packit |
6f02de |
(void) strncpy(tp, s2, len2);
|
|
Packit |
6f02de |
tp += len2;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (s3 && len3) {
|
|
Packit |
6f02de |
(void) strncpy(tp, s3, len3);
|
|
Packit |
6f02de |
tp += len3;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
*tp = '\0';
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (clp)
|
|
Packit |
6f02de |
*clp = cl;
|
|
Packit |
6f02de |
return(cp);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* is_readable() -- is file readable
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
is_readable(path, msg)
|
|
Packit |
6f02de |
char *path; /* file path */
|
|
Packit |
6f02de |
int msg; /* issue warning message if 1 */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (access(path, R_OK) < 0) {
|
|
Packit |
6f02de |
if (!Fwarn && msg == 1)
|
|
Packit |
6f02de |
(void) fprintf(stderr, ACCESSERRFMT, Pn, path, strerror(errno));
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* lstatsafely() - lstat path safely (i. e., with timeout)
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
lstatsafely(path, buf)
|
|
Packit |
6f02de |
char *path; /* file path */
|
|
Packit |
6f02de |
struct stat *buf; /* stat buffer address */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (Fblock) {
|
|
Packit |
6f02de |
if (!Fwarn)
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: avoiding stat(%s): -b was specified.\n",
|
|
Packit |
6f02de |
Pn, path);
|
|
Packit |
6f02de |
errno = EWOULDBLOCK;
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(doinchild(dolstat, path, (char *)buf, sizeof(struct stat)));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Readlink() - read and interpret file system symbolic links
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
char *
|
|
Packit |
6f02de |
Readlink(arg)
|
|
Packit |
6f02de |
char *arg; /* argument to be interpreted */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char abuf[MAXPATHLEN+1];
|
|
Packit |
6f02de |
int alen;
|
|
Packit |
6f02de |
char *ap;
|
|
Packit |
6f02de |
char *argp1, *argp2;
|
|
Packit |
6f02de |
int i, len, llen, slen;
|
|
Packit |
6f02de |
char lbuf[MAXPATHLEN+1];
|
|
Packit |
6f02de |
static char *op = (char *)NULL;
|
|
Packit |
6f02de |
static int ss = 0;
|
|
Packit |
6f02de |
char *s1;
|
|
Packit |
6f02de |
static char **stk = (char **)NULL;
|
|
Packit |
6f02de |
static int sx = 0;
|
|
Packit |
6f02de |
char tbuf[MAXPATHLEN+1];
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* See if avoiding kernel blocks.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (Fblock) {
|
|
Packit |
6f02de |
if (!Fwarn) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: avoiding readlink(", Pn);
|
|
Packit |
6f02de |
safestrprt(arg, stderr, 0);
|
|
Packit |
6f02de |
(void) fprintf(stderr, "): -b was specified.\n");
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
op = (char *)NULL;
|
|
Packit |
6f02de |
return(arg);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Save the original path.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!op)
|
|
Packit |
6f02de |
op = arg;
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Evaluate each component of the argument for a symbolic link.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
for (alen = 0, ap = abuf, argp1 = argp2 = arg; *argp2; argp1 = argp2 ) {
|
|
Packit |
6f02de |
for (argp2 = argp1 + 1; *argp2 && *argp2 != '/'; argp2++)
|
|
Packit |
6f02de |
;
|
|
Packit |
6f02de |
if ((len = argp2 - arg) >= (int)sizeof(tbuf)) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
path_too_long:
|
|
Packit |
6f02de |
if (!Fwarn) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: readlink() path too long: ", Pn);
|
|
Packit |
6f02de |
safestrprt(op ? op : arg, stderr, 1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
op = (char *)NULL;
|
|
Packit |
6f02de |
return((char *)NULL);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
(void) strncpy(tbuf, arg, len);
|
|
Packit |
6f02de |
tbuf[len] = '\0';
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Dereference a symbolic link.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if ((llen=doinchild(doreadlink,tbuf,lbuf,sizeof(lbuf) - 1)) >= 0) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* If the link is a new absolute path, replace
|
|
Packit |
6f02de |
* the previous assembly with it.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (lbuf[0] == '/') {
|
|
Packit |
6f02de |
(void) strncpy(abuf, lbuf, llen);
|
|
Packit |
6f02de |
ap = &abuf[llen];
|
|
Packit |
6f02de |
*ap = '\0';
|
|
Packit |
6f02de |
alen = llen;
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
lbuf[llen] = '\0';
|
|
Packit |
6f02de |
s1 = lbuf;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
llen = argp2 - argp1;
|
|
Packit |
6f02de |
s1 = argp1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Make sure two components are separated by a `/'.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* If the first component is not a link, don't force
|
|
Packit |
6f02de |
* a leading '/'.
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* If the first component is a link and the source of
|
|
Packit |
6f02de |
* the link has a leading '/', force a leading '/'.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (*s1 == '/')
|
|
Packit |
6f02de |
slen = 1;
|
|
Packit |
6f02de |
else {
|
|
Packit |
6f02de |
if (alen > 0) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* This is not the first component.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (abuf[alen - 1] == '/')
|
|
Packit |
6f02de |
slen = 1;
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
slen = 2;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* This is the first component.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (s1 == lbuf && tbuf[0] == '/')
|
|
Packit |
6f02de |
slen = 2;
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
slen = 1;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Add to the path assembly.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if ((alen + llen + slen) >= (int)sizeof(abuf))
|
|
Packit |
6f02de |
goto path_too_long;
|
|
Packit |
6f02de |
if (slen == 2)
|
|
Packit |
6f02de |
*ap++ = '/';
|
|
Packit |
6f02de |
(void) strncpy(ap, s1, llen);
|
|
Packit |
6f02de |
ap += llen;
|
|
Packit |
6f02de |
*ap = '\0';
|
|
Packit |
6f02de |
alen += (llen + slen - 1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* If the assembled path and argument are the same, free all but the
|
|
Packit |
6f02de |
* last string in the stack, and return the argument.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (strcmp(arg, abuf) == 0) {
|
|
Packit |
6f02de |
for (i = 0; i < sx; i++) {
|
|
Packit |
6f02de |
if (i < (sx - 1))
|
|
Packit |
6f02de |
(void) free((FREE_P *)stk[i]);
|
|
Packit |
6f02de |
stk[i] = (char *)NULL;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
sx = 0;
|
|
Packit |
6f02de |
op = (char *)NULL;
|
|
Packit |
6f02de |
return(arg);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* If the assembled path and argument are different, add it to the
|
|
Packit |
6f02de |
* string stack, then Readlink() it.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!(s1 = mkstrcpy(abuf, (MALLOC_S *)NULL))) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
no_readlink_space:
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: no Readlink string space for ", Pn);
|
|
Packit |
6f02de |
safestrprt(abuf, stderr, 1);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (sx >= MAXSYMLINKS) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* If there are too many symbolic links, report an error, clear
|
|
Packit |
6f02de |
* the stack, and return no path.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!Fwarn) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: too many (> %d) symbolic links in readlink() path: ",
|
|
Packit |
6f02de |
Pn, MAXSYMLINKS);
|
|
Packit |
6f02de |
safestrprt(op ? op : arg, stderr, 1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
for (i = 0; i < sx; i++) {
|
|
Packit |
6f02de |
(void) free((FREE_P *)stk[i]);
|
|
Packit |
6f02de |
stk[i] = (char *)NULL;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
(void) free((FREE_P *)stk);
|
|
Packit |
6f02de |
(void) free((FREE_P *)s1);
|
|
Packit |
6f02de |
stk = (char **)NULL;
|
|
Packit |
6f02de |
ss = sx = 0;
|
|
Packit |
6f02de |
s1 = (char *)NULL;
|
|
Packit |
6f02de |
op = (char *)NULL;
|
|
Packit |
6f02de |
return((char *)NULL);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (++sx > ss) {
|
|
Packit |
6f02de |
if (!stk)
|
|
Packit |
6f02de |
stk = (char **)malloc((MALLOC_S)(sizeof(char *) * sx));
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
stk = (char **)realloc((MALLOC_P *)stk,
|
|
Packit |
6f02de |
(MALLOC_S)(sizeof(char *) * sx));
|
|
Packit |
6f02de |
if (!stk)
|
|
Packit |
6f02de |
goto no_readlink_space;
|
|
Packit |
6f02de |
ss = sx;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
stk[sx - 1] = s1;
|
|
Packit |
6f02de |
return(Readlink(s1));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASSTREAMS)
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* readstdata() - read stream's stdata structure
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
readstdata(addr, buf)
|
|
Packit |
6f02de |
KA_T addr; /* stdata address in kernel*/
|
|
Packit |
6f02de |
struct stdata *buf; /* buffer addess */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (!addr
|
|
Packit |
6f02de |
|| kread(addr, (char *)buf, sizeof(struct stdata))) {
|
|
Packit |
6f02de |
(void) snpf(Namech, Namechl, "no stream data in %s",
|
|
Packit |
6f02de |
print_kptr(addr, (char *)NULL, 0));
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* readsthead() - read stream head
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
readsthead(addr, buf)
|
|
Packit |
6f02de |
KA_T addr; /* starting queue pointer in kernel */
|
|
Packit |
6f02de |
struct queue *buf; /* buffer for queue head */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
KA_T qp;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (!addr) {
|
|
Packit |
6f02de |
(void) snpf(Namech, Namechl, "no stream queue head");
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
for (qp = addr; qp; qp = (KA_T)buf->q_next) {
|
|
Packit |
6f02de |
if (kread(qp, (char *)buf, sizeof(struct queue))) {
|
|
Packit |
6f02de |
(void) snpf(Namech, Namechl, "bad stream queue link at %s",
|
|
Packit |
6f02de |
print_kptr(qp, (char *)NULL, 0));
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* readstidnm() - read stream module ID name
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
readstidnm(addr, buf, len)
|
|
Packit |
6f02de |
KA_T addr; /* module ID name address in kernel */
|
|
Packit |
6f02de |
char *buf; /* receiving buffer address */
|
|
Packit |
6f02de |
READLEN_T len; /* buffer length */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (!addr || kread(addr, buf, len)) {
|
|
Packit |
6f02de |
(void) snpf(Namech, Namechl, "can't read module ID name from %s",
|
|
Packit |
6f02de |
print_kptr(addr, (char *)NULL, 0));
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* readstmin() - read stream's module info
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
readstmin(addr, buf)
|
|
Packit |
6f02de |
KA_T addr; /* module info address in kernel */
|
|
Packit |
6f02de |
struct module_info *buf; /* receiving buffer address */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (!addr || kread(addr, (char *)buf, sizeof(struct module_info))) {
|
|
Packit |
6f02de |
(void) snpf(Namech, Namechl, "can't read module info from %s",
|
|
Packit |
6f02de |
print_kptr(addr, (char *)NULL, 0));
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* readstqinit() - read stream's queue information structure
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
readstqinit(addr, buf)
|
|
Packit |
6f02de |
KA_T addr; /* queue info address in kernel */
|
|
Packit |
6f02de |
struct qinit *buf; /* receiving buffer address */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (!addr || kread(addr, (char *)buf, sizeof(struct qinit))) {
|
|
Packit |
6f02de |
(void) snpf(Namech, Namechl, "can't read queue info from %s",
|
|
Packit |
6f02de |
print_kptr(addr, (char *)NULL, 0));
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(0);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
#endif /* HASSTREAMS */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* safepup() - safely print an unprintable character -- i.e., print it in a
|
|
Packit |
6f02de |
* printable form
|
|
Packit |
6f02de |
*
|
|
Packit |
6f02de |
* return: char * to printable equivalent
|
|
Packit |
6f02de |
* cl = strlen(printable equivalent)
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
char *
|
|
Packit |
6f02de |
safepup(c, cl)
|
|
Packit |
6f02de |
unsigned int c; /* unprintable (i.e., !isprint())
|
|
Packit |
6f02de |
* character and '\\' */
|
|
Packit |
6f02de |
int *cl; /* returned printable strlen -- NULL if
|
|
Packit |
6f02de |
* no return needed */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
int len;
|
|
Packit |
6f02de |
char *rp;
|
|
Packit |
6f02de |
static char up[8];
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (c < 0x20) {
|
|
Packit |
6f02de |
switch (c) {
|
|
Packit |
6f02de |
case '\b':
|
|
Packit |
6f02de |
rp = "\\b";
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
case '\f':
|
|
Packit |
6f02de |
rp = "\\f";
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
case '\n':
|
|
Packit |
6f02de |
rp = "\\n";
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
case '\r':
|
|
Packit |
6f02de |
rp = "\\r";
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
case '\t':
|
|
Packit |
6f02de |
rp = "\\t";
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
default:
|
|
Packit |
6f02de |
(void) snpf(up, sizeof(up), "^%c", c + 0x40);
|
|
Packit |
6f02de |
rp = up;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
len = 2;
|
|
Packit |
6f02de |
} else if (c == 0xff) {
|
|
Packit |
6f02de |
rp = "^?";
|
|
Packit |
6f02de |
len = 2;
|
|
Packit |
6f02de |
} else if (c == '\\') {
|
|
Packit |
6f02de |
rp = "\\\\";
|
|
Packit |
6f02de |
len = 2;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
(void) snpf(up, sizeof(up), "\\x%02x", (int)(c & 0xff));
|
|
Packit |
6f02de |
rp = up;
|
|
Packit |
6f02de |
len = 4;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (cl)
|
|
Packit |
6f02de |
*cl = len;
|
|
Packit |
6f02de |
return(rp);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* safestrlen() - calculate a "safe" string length -- i.e., compute space for
|
|
Packit |
6f02de |
* non-printable characters when printed in a printable form
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
safestrlen(sp, flags)
|
|
Packit |
6f02de |
char *sp; /* string pointer */
|
|
Packit |
6f02de |
int flags; /* flags:
|
|
Packit |
6f02de |
* bit 0: 0 (0) = no NL
|
|
Packit |
6f02de |
* 1 (1) = add trailing NL
|
|
Packit |
6f02de |
* 1: 0 (0) = ' ' printable
|
|
Packit |
6f02de |
* 1 (2) = ' ' not printable
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char c;
|
|
Packit |
6f02de |
int len = 0;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
c = (flags & 2) ? ' ' : '\0';
|
|
Packit |
6f02de |
if (sp) {
|
|
Packit |
6f02de |
for (; *sp; sp++) {
|
|
Packit |
6f02de |
if (!isprint((unsigned char)*sp)
|
|
Packit |
6f02de |
|| (*sp == '\\') || (*sp == c))
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if ((*sp < 0x20) || ((unsigned char)*sp == 0xff)
|
|
Packit |
6f02de |
|| (*sp == '\\'))
|
|
Packit |
6f02de |
len += 2; /* length of \. or ^. form */
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
len += 4; /* length of "\x%02x" printf */
|
|
Packit |
6f02de |
} else
|
|
Packit |
6f02de |
len++;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(len);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* safestrprt() - print a string "safely" to the indicated stream -- i.e.,
|
|
Packit |
6f02de |
* print unprintable characters in a printable form
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
safestrprt(sp, fs, flags)
|
|
Packit |
6f02de |
char *sp; /* string to print pointer pointer */
|
|
Packit |
6f02de |
FILE *fs; /* destination stream -- e.g., stderr
|
|
Packit |
6f02de |
* or stdout */
|
|
Packit |
6f02de |
int flags; /* flags:
|
|
Packit |
6f02de |
* bit 0: 0 (0) = no NL
|
|
Packit |
6f02de |
* 1 (1) = add trailing NL
|
|
Packit |
6f02de |
* 1: 0 (0) = ' ' printable
|
|
Packit |
6f02de |
* 1 (2) = ' ' not printable
|
|
Packit |
6f02de |
* 2: 0 (0) = print string as is
|
|
Packit |
6f02de |
* 1 (4) = surround string
|
|
Packit |
6f02de |
* with '"'
|
|
Packit |
6f02de |
* 4: 0 (0) = print ending '\n'
|
|
Packit |
6f02de |
* 1 (8) = don't print ending
|
|
Packit |
6f02de |
* '\n'
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char c;
|
|
Packit |
6f02de |
int lnc, lnt, sl;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASWIDECHAR)
|
|
Packit |
6f02de |
wchar_t w;
|
|
Packit |
6f02de |
int wcmx = MB_CUR_MAX;
|
|
Packit |
6f02de |
#else /* !defined(HASWIDECHAR) */
|
|
Packit |
6f02de |
static int wcmx = 1;
|
|
Packit |
6f02de |
#endif /* defined(HASWIDECHAR) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
c = (flags & 2) ? ' ' : '\0';
|
|
Packit |
6f02de |
if (flags & 4)
|
|
Packit |
6f02de |
putc('"', fs);
|
|
Packit |
6f02de |
if (sp) {
|
|
Packit |
6f02de |
for (sl = strlen(sp); *sp; sl -= lnc, sp += lnc) {
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
#if defined(HASWIDECHAR)
|
|
Packit |
6f02de |
if (wcmx > 1) {
|
|
Packit |
6f02de |
lnc = mblen(sp, sl);
|
|
Packit |
6f02de |
if (lnc > 1) {
|
|
Packit |
6f02de |
if ((mbtowc(&w, sp, sl) == lnc) && iswprint(w)) {
|
|
Packit |
6f02de |
for (lnt = 0; lnt < lnc; lnt++) {
|
|
Packit |
6f02de |
putc((int)*(sp + lnt), fs);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
for (lnt = 0; lnt < lnc; lnt++) {
|
|
Packit |
6f02de |
fputs(safepup((unsigned int)*(sp + lnt),
|
|
Packit |
6f02de |
(int *)NULL), fs);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
} else
|
|
Packit |
6f02de |
lnc = 1;
|
|
Packit |
6f02de |
} else
|
|
Packit |
6f02de |
lnc = 1;
|
|
Packit |
6f02de |
#else /* !defined(HASWIDECHAR) */
|
|
Packit |
6f02de |
lnc = 1;
|
|
Packit |
6f02de |
#endif /* defined(HASWIDECHAR) */
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if ((*sp != '\\') && isprint((unsigned char)*sp) && *sp != c)
|
|
Packit |
6f02de |
putc((int)(*sp & 0xff), fs);
|
|
Packit |
6f02de |
else {
|
|
Packit |
6f02de |
if ((flags & 8) && (*sp == '\n') && !*(sp + 1))
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
fputs(safepup((unsigned int)*sp, (int *)NULL), fs);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (flags & 4)
|
|
Packit |
6f02de |
putc('"', fs);
|
|
Packit |
6f02de |
if (flags & 1)
|
|
Packit |
6f02de |
putc('\n', fs);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* safestrprtn() - print a specified number of characters from a string
|
|
Packit |
6f02de |
* "safely" to the indicated stream
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
safestrprtn(sp, len, fs, flags)
|
|
Packit |
6f02de |
char *sp; /* string to print pointer pointer */
|
|
Packit |
6f02de |
int len; /* safe number of characters to
|
|
Packit |
6f02de |
* print */
|
|
Packit |
6f02de |
FILE *fs; /* destination stream -- e.g., stderr
|
|
Packit |
6f02de |
* or stdout */
|
|
Packit |
6f02de |
int flags; /* flags:
|
|
Packit |
6f02de |
* bit 0: 0 (0) = no NL
|
|
Packit |
6f02de |
* 1 (1) = add trailing NL
|
|
Packit |
6f02de |
* 1: 0 (0) = ' ' printable
|
|
Packit |
6f02de |
* 1 (2) = ' ' not printable
|
|
Packit |
6f02de |
* 2: 0 (0) = print string as is
|
|
Packit |
6f02de |
* 1 (4) = surround string
|
|
Packit |
6f02de |
* with '"'
|
|
Packit |
6f02de |
* 4: 0 (0) = print ending '\n'
|
|
Packit |
6f02de |
* 1 (8) = don't print ending
|
|
Packit |
6f02de |
* '\n'
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char c, *up;
|
|
Packit |
6f02de |
int cl, i;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
if (flags & 4)
|
|
Packit |
6f02de |
putc('"', fs);
|
|
Packit |
6f02de |
if (sp) {
|
|
Packit |
6f02de |
c = (flags & 2) ? ' ' : '\0';
|
|
Packit |
6f02de |
for (i = 0; i < len && *sp; sp++) {
|
|
Packit |
6f02de |
if ((*sp != '\\') && isprint((unsigned char)*sp) && *sp != c) {
|
|
Packit |
6f02de |
putc((int)(*sp & 0xff), fs);
|
|
Packit |
6f02de |
i++;
|
|
Packit |
6f02de |
} else {
|
|
Packit |
6f02de |
if ((flags & 8) && (*sp == '\n') && !*(sp + 1))
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
up = safepup((unsigned int)*sp, &cl);
|
|
Packit |
6f02de |
if ((i + cl) > len)
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
fputs(up, fs);
|
|
Packit |
6f02de |
i += cl;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
} else
|
|
Packit |
6f02de |
i = 0;
|
|
Packit |
6f02de |
for (; i < len; i++)
|
|
Packit |
6f02de |
putc(' ', fs);
|
|
Packit |
6f02de |
if (flags & 4)
|
|
Packit |
6f02de |
putc('"', fs);
|
|
Packit |
6f02de |
if (flags & 1)
|
|
Packit |
6f02de |
putc('\n', fs);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* statsafely() - stat path safely (i. e., with timeout)
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
int
|
|
Packit |
6f02de |
statsafely(path, buf)
|
|
Packit |
6f02de |
char *path; /* file path */
|
|
Packit |
6f02de |
struct stat *buf; /* stat buffer address */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
if (Fblock) {
|
|
Packit |
6f02de |
if (!Fwarn)
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: avoiding stat(%s): -b was specified.\n",
|
|
Packit |
6f02de |
Pn, path);
|
|
Packit |
6f02de |
errno = EWOULDBLOCK;
|
|
Packit |
6f02de |
return(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
return(doinchild(dostat, path, (char *)buf, sizeof(struct stat)));
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* stkdir() - stack directory name
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
void
|
|
Packit |
6f02de |
stkdir(p)
|
|
Packit |
6f02de |
char *p; /* directory path */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
MALLOC_S len;
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Provide adequate space for directory stack pointers.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (Dstkx >= Dstkn) {
|
|
Packit |
6f02de |
Dstkn += 128;
|
|
Packit |
6f02de |
len = (MALLOC_S)(Dstkn * sizeof(char *));
|
|
Packit |
6f02de |
if (!Dstk)
|
|
Packit |
6f02de |
Dstk = (char **)malloc(len);
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
Dstk = (char **)realloc((MALLOC_P *)Dstk, len);
|
|
Packit |
6f02de |
if (!Dstk) {
|
|
Packit |
6f02de |
(void) fprintf(stderr,
|
|
Packit |
6f02de |
"%s: no space for directory stack at: ", Pn);
|
|
Packit |
6f02de |
safestrprt(p, stderr, 1);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Allocate space for the name, copy it there and put its pointer on the stack.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (!(Dstk[Dstkx] = mkstrcpy(p, (MALLOC_S *)NULL))) {
|
|
Packit |
6f02de |
(void) fprintf(stderr, "%s: no space for: ", Pn);
|
|
Packit |
6f02de |
safestrprt(p, stderr, 1);
|
|
Packit |
6f02de |
Exit(1);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
Dstkx++;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* x2dev() - convert hexadecimal ASCII string to device number
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
char *
|
|
Packit |
6f02de |
x2dev(s, d)
|
|
Packit |
6f02de |
char *s; /* ASCII string */
|
|
Packit |
6f02de |
dev_t *d; /* device receptacle */
|
|
Packit |
6f02de |
{
|
|
Packit |
6f02de |
char *cp, *cp1;
|
|
Packit |
6f02de |
int n;
|
|
Packit |
6f02de |
dev_t r;
|
|
Packit |
6f02de |
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Skip an optional leading 0x. Count the number of hex digits up to the end
|
|
Packit |
6f02de |
* of the string, or to a space, or to a comma. Return an error if an unknown
|
|
Packit |
6f02de |
* character is encountered. If the count is larger than (2 * sizeof(dev_t))
|
|
Packit |
6f02de |
* -- e.g., because of sign extension -- ignore excess leading hex 0xf digits,
|
|
Packit |
6f02de |
* but return an error if an excess leading digit isn't 0xf.
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
if (strncasecmp(s, "0x", 2) == 0)
|
|
Packit |
6f02de |
s += 2;
|
|
Packit |
6f02de |
for (cp = s, n = 0; *cp; cp++, n++) {
|
|
Packit |
6f02de |
if (isdigit((unsigned char)*cp))
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
if ((unsigned char)*cp >= 'a' && (unsigned char)*cp <= 'f')
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
if ((unsigned char)*cp >= 'A' && (unsigned char)*cp <= 'F')
|
|
Packit |
6f02de |
continue;
|
|
Packit |
6f02de |
if (*cp == ' ' || *cp == ',')
|
|
Packit |
6f02de |
break;
|
|
Packit |
6f02de |
return((char *)NULL);
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
if (!n)
|
|
Packit |
6f02de |
return((char *)NULL);
|
|
Packit |
6f02de |
if (n > (2 * (int)sizeof(dev_t))) {
|
|
Packit |
6f02de |
cp1 = s;
|
|
Packit |
6f02de |
s += (n - (2 * sizeof(dev_t)));
|
|
Packit |
6f02de |
while (cp1 < s) {
|
|
Packit |
6f02de |
if (*cp1 != 'f' && *cp1 != 'F')
|
|
Packit |
6f02de |
return((char *)NULL);
|
|
Packit |
6f02de |
cp1++;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
/*
|
|
Packit |
6f02de |
* Assemble the validated hex digits of the device number, starting at a point
|
|
Packit |
6f02de |
* in the string relevant to sizeof(dev_t).
|
|
Packit |
6f02de |
*/
|
|
Packit |
6f02de |
for (r = 0; s < cp; s++) {
|
|
Packit |
6f02de |
r = r << 4;
|
|
Packit |
6f02de |
if (isdigit((unsigned char)*s))
|
|
Packit |
6f02de |
r |= (unsigned char)(*s - '0') & 0xf;
|
|
Packit |
6f02de |
else {
|
|
Packit |
6f02de |
if (isupper((unsigned char)*s))
|
|
Packit |
6f02de |
r |= ((unsigned char)(*s - 'A') + 10) & 0xf;
|
|
Packit |
6f02de |
else
|
|
Packit |
6f02de |
r |= ((unsigned char)(*s - 'a') + 10) & 0xf;
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
}
|
|
Packit |
6f02de |
*d = r;
|
|
Packit |
6f02de |
return(s);
|
|
Packit |
6f02de |
}
|