version 1.19, 2003/05/06 21:52:25 |
version 1.20, 2003/05/14 01:34:35 |
|
|
* SUCH DAMAGE. |
* SUCH DAMAGE. |
*/ |
*/ |
|
|
|
#include "defs.h" |
#ifndef lint |
#ifndef lint |
#if 0 |
#if 0 |
static char RCSid[] = |
static char RCSid[] __attribute__((__unused__)) = |
"$From: common.c,v 6.82 1998/03/23 23:27:33 michaelc Exp $"; |
"$From: common.c,v 1.8 2001/03/12 18:16:36 kim Exp $"; |
#else |
#else |
static char RCSid[] = |
static char RCSid[] __attribute__((__unused__)) = |
"$OpenBSD$"; |
"$OpenBSD$"; |
#endif |
#endif |
|
|
static char sccsid[] = "@(#)common.c"; |
static char sccsid[] __attribute__((__unused__)) = |
|
"@(#)common.c"; |
|
|
static char copyright[] = |
static char copyright[] __attribute__((__unused__)) = |
"@(#) Copyright (c) 1983 Regents of the University of California.\n\ |
"@(#) Copyright (c) 1983 Regents of the University of California.\n\ |
All rights reserved.\n"; |
All rights reserved.\n"; |
#endif /* !lint */ |
#endif /* !lint */ |
|
|
* Things common to both the client and server. |
* Things common to both the client and server. |
*/ |
*/ |
|
|
#include "defs.h" |
|
#if defined(NEED_UTIME_H) |
#if defined(NEED_UTIME_H) |
#include <utime.h> |
#include <utime.h> |
#endif /* defined(NEED_UTIME_H) */ |
#endif /* defined(NEED_UTIME_H) */ |
#include <sys/socket.h> |
|
#include <sys/wait.h> |
#include <sys/wait.h> |
|
#include <sys/socket.h> |
|
|
/* |
/* |
* Variables common to both client and server |
* Variables common to both client and server |
|
|
int rem_r = -1; /* Client file descriptor */ |
int rem_r = -1; /* Client file descriptor */ |
int rem_w = -1; /* Client file descriptor */ |
int rem_w = -1; /* Client file descriptor */ |
struct passwd *pw = NULL; /* Local user's pwd entry */ |
struct passwd *pw = NULL; /* Local user's pwd entry */ |
int contimedout = FALSE; /* Connection timed out */ |
volatile sig_atomic_t contimedout = FALSE; /* Connection timed out */ |
int proto_version = -1; /* Protocol version */ |
int proto_version = -1; /* Protocol version */ |
int rtimeout = RTIMEOUT; /* Response time out */ |
int rtimeout = RTIMEOUT; /* Response time out */ |
jmp_buf finish_jmpbuf; /* Finish() jmp buffer */ |
jmp_buf finish_jmpbuf; /* Finish() jmp buffer */ |
|
|
char **realargv; /* Real main() argv */ |
char **realargv; /* Real main() argv */ |
int realargc; /* Real main() argc */ |
int realargc; /* Real main() argc */ |
opt_t options = 0; /* Global install options */ |
opt_t options = 0; /* Global install options */ |
|
char defowner[64] = "bin"; /* Default owner */ |
|
char defgroup[64] = "bin"; /* Default group */ |
|
|
|
static int sendcmdmsg(int, char *, size_t); |
|
static int remread(int, u_char *, int); |
|
static int remmore(void); |
|
|
/* |
/* |
* Front end to write() that handles partial write() requests. |
* Front end to write() that handles partial write() requests. |
*/ |
*/ |
extern WRITE_RETURN_T xwrite(fd, buf, len) |
WRITE_RETURN_T |
int fd; |
xwrite(int fd, void *buf, WRITE_AMT_T len) |
void *buf; |
|
WRITE_AMT_T len; |
|
{ |
{ |
WRITE_AMT_T nleft = len; |
WRITE_AMT_T nleft = len; |
WRITE_RETURN_T nwritten; |
WRITE_RETURN_T nwritten; |
|
|
} |
} |
|
|
/* |
/* |
* Set program name |
|
*/ |
|
extern void setprogname(argv) |
|
char **argv; |
|
{ |
|
char *cp; |
|
|
|
if (!progname) { |
|
progname = xstrdup(argv[0]); |
|
if ((cp = strrchr(progname, '/'))) |
|
progname = cp + 1; |
|
} |
|
} |
|
|
|
/* |
|
* Do run-time initialization |
* Do run-time initialization |
*/ |
*/ |
extern int init(argc, argv, envp) |
int |
/*ARGSUSED*/ |
init(int argc, char **argv, char **envp) |
int argc; |
|
char **argv; |
|
char **envp; |
|
{ |
{ |
int i; |
int i; |
char *cp; |
|
|
|
#ifdef SIGSEGV_CHECK |
#ifdef SIGSEGV_CHECK |
if (!isserver) |
if (!isserver) |
(void) signal(SIGSEGV, sighandler); |
(void) signal(SIGSEGV, sighandler); |
#endif |
#endif |
|
|
setprogname(argv); |
|
|
|
/* |
/* |
* Save a copy of our argc and argv before setargs() overwrites them |
* Save a copy of our argc and argv before setargs() overwrites them |
*/ |
*/ |
|
|
return(-1); |
return(-1); |
} |
} |
|
|
debugmsg(DM_MISC, "UserID = %d pwname = '%s' home = '%s'\n", |
debugmsg(DM_MISC, "UserID = %u pwname = '%s' home = '%s'\n", |
userid, pw->pw_name, pw->pw_dir); |
userid, pw->pw_name, pw->pw_dir); |
homedir = xstrdup(pw->pw_dir); |
homedir = xstrdup(pw->pw_dir); |
locuser = xstrdup(pw->pw_name); |
locuser = xstrdup(pw->pw_name); |
groupid = pw->pw_gid; |
groupid = pw->pw_gid; |
gethostname(host, sizeof(host)); |
gethostname(host, sizeof(host)); |
|
#if 0 |
if ((cp = strchr(host, '.')) != NULL) |
if ((cp = strchr(host, '.')) != NULL) |
*cp = CNULL; |
*cp = CNULL; |
|
#endif |
|
|
/* |
/* |
* If we're not root, disable paranoid ownership checks |
* If we're not root, disable paranoid ownership checks |
|
|
/* |
/* |
* Finish things up before ending. |
* Finish things up before ending. |
*/ |
*/ |
extern void finish() |
void |
|
finish(void) |
{ |
{ |
extern jmp_buf finish_jmpbuf; |
extern jmp_buf finish_jmpbuf; |
|
|
debugmsg(DM_CALL, |
debugmsg(DM_CALL, |
"finish() called: do_fork = %d amchild = %d isserver = %d", |
"finish() called: do_fork = %d amchild = %d isserver = %d", |
do_fork, amchild, isserver); |
do_fork, amchild, isserver); |
cleanup(); |
cleanup(0); |
|
|
/* |
/* |
* There's no valid finish_jmpbuf for the rdist master parent. |
* There's no valid finish_jmpbuf for the rdist master parent. |
|
|
/* |
/* |
* Handle lost connections |
* Handle lost connections |
*/ |
*/ |
extern void lostconn() |
void |
|
lostconn(void) |
{ |
{ |
/* Prevent looping */ |
/* Prevent looping */ |
(void) signal(SIGPIPE, SIG_IGN); |
(void) signal(SIGPIPE, SIG_IGN); |
|
|
/* |
/* |
* Do a core dump |
* Do a core dump |
*/ |
*/ |
extern void coredump() |
void |
|
coredump(void) |
{ |
{ |
error("Segmentation violation - dumping core [PID = %ld, %s]", |
error("Segmentation violation - dumping core [PID = %d, %s]", |
(long)getpid(), |
getpid(), |
(isserver) ? "isserver" : ((amchild) ? "amchild" : "parent")); |
(isserver) ? "isserver" : ((amchild) ? "amchild" : "parent")); |
abort(); |
abort(); |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
|
|
/* |
/* |
* General signal handler |
* General signal handler |
*/ |
*/ |
extern void sighandler(sig) |
void |
int sig; |
sighandler(int sig) |
{ |
{ |
int save_errno = errno; |
int save_errno = errno; |
|
|
|
|
* Function to actually send the command char and message to the |
* Function to actually send the command char and message to the |
* remote host. |
* remote host. |
*/ |
*/ |
static int sendcmdmsg(cmd, msg, msgsize) |
static int |
char cmd; |
sendcmdmsg(int cmd, char *msg, size_t msgsize) |
char *msg; |
|
size_t msgsize; |
|
{ |
{ |
int len; |
int len; |
|
|
|
|
/* |
/* |
* Stdarg frontend to sendcmdmsg() |
* Stdarg frontend to sendcmdmsg() |
*/ |
*/ |
extern int sendcmd(char cmd, char *fmt, ...) |
int |
|
sendcmd(char cmd, char *fmt, ...) |
{ |
{ |
static char buf[BUFSIZ]; |
static char buf[BUFSIZ]; |
va_list args; |
va_list args; |
|
|
va_start(args, fmt); |
va_start(args, fmt); |
if (fmt) |
if (fmt) |
(void) vsnprintf(buf + (cmd != C_NONE), |
(void) vsnprintf(buf + (cmd != C_NONE), |
sizeof(buf) - (cmd != C_NONE), fmt, args); |
sizeof(buf) - (cmd != C_NONE), fmt, args); |
else |
else |
buf[1] = CNULL; |
buf[1] = CNULL; |
va_end(args); |
va_end(args); |
|
|
/* |
/* |
* Varargs frontend to sendcmdmsg() |
* Varargs frontend to sendcmdmsg() |
*/ |
*/ |
extern int sendcmd(va_alist) |
int |
|
sendcmd(va_alist) |
va_dcl |
va_dcl |
{ |
{ |
static char buf[BUFSIZ]; |
static char buf[BUFSIZ]; |
|
|
fmt = va_arg(args, char *); |
fmt = va_arg(args, char *); |
if (fmt) |
if (fmt) |
(void) vsnprintf(buf + (cmd != C_NONE), |
(void) vsnprintf(buf + (cmd != C_NONE), |
sizeof(buf) - (cmd != C_NONE), fmt, args); |
sizeof(buf) - (cmd != C_NONE), fmt, args); |
else |
else |
buf[1] = CNULL; |
buf[1] = CNULL; |
va_end(args); |
va_end(args); |
|
|
} |
} |
#endif /* ARG_TYPE == ARG_VARARGS */ |
#endif /* ARG_TYPE == ARG_VARARGS */ |
|
|
#if !defined(ARG_TYPE) |
|
/* |
/* |
* Stupid frontend to sendcmdmsg() |
|
*/ |
|
/*VARARGS2*/ |
|
extern int sendcmd(cmd, fmt, a1, a2, a3, a4, a5, a6, a7, a8) |
|
char cmd; |
|
char *fmt; |
|
{ |
|
static char buf[BUFSIZ]; |
|
|
|
if (fmt) |
|
(void) snprintf(buf + (cmd != C_NONE), |
|
sizeof(buf) - (cmd != C_NONE), |
|
fmt, a1, a2, a3, a4, a5, a6, a7, a8); |
|
else |
|
buf[1] = CNULL; |
|
|
|
return(sendcmdmsg(cmd, buf, sizeof(buf))); |
|
} |
|
#endif /* !ARG_TYPE */ |
|
|
|
/* |
|
* Internal variables and routines for reading lines from the remote. |
* Internal variables and routines for reading lines from the remote. |
*/ |
*/ |
static u_char rembuf[BUFSIZ]; |
static u_char rembuf[BUFSIZ]; |
|
|
/* |
/* |
* Back end to remote read() |
* Back end to remote read() |
*/ |
*/ |
static int remread(fd, buf, bufsiz) |
static int |
int fd; |
remread(int fd, u_char *buf, int bufsiz) |
u_char *buf; |
|
int bufsiz; |
|
{ |
{ |
return(read(fd, (char *)buf, bufsiz)); |
return(read(fd, (char *)buf, bufsiz)); |
} |
} |
|
|
static int remmore() |
static int |
|
remmore(void) |
{ |
{ |
(void) signal(SIGALRM, sighandler); |
(void) signal(SIGALRM, sighandler); |
(void) alarm(rtimeout); |
(void) alarm(rtimeout); |
|
|
* errors, call cleanup() or lostconn(). In other words, unless |
* errors, call cleanup() or lostconn(). In other words, unless |
* the third argument is nonzero, this routine never returns failure. |
* the third argument is nonzero, this routine never returns failure. |
*/ |
*/ |
extern int remline(buffer, space, doclean) |
int |
u_char *buffer; |
remline(u_char *buffer, int space, int doclean) |
int space; |
|
int doclean; |
|
{ |
{ |
int c, left = space; |
int c, left = space; |
u_char *p = buffer; |
u_char *p = buffer; |
|
|
if (debug) { |
if (debug) { |
static char mbuf[BUFSIZ]; |
static char mbuf[BUFSIZ]; |
|
|
(void) snprintf(mbuf, sizeof mbuf, |
(void) snprintf(mbuf, sizeof(mbuf), |
"<<< Cmd = %c (\\%3.3o) Msg = \"%s\"", |
"<<< Cmd = %c (\\%3.3o) Msg = \"%s\"", |
buffer[0], buffer[0], |
buffer[0], buffer[0], |
buffer + 1); |
buffer + 1); |
|
|
* Non-line-oriented remote read. |
* Non-line-oriented remote read. |
*/ |
*/ |
int |
int |
readrem(p, space) |
readrem(char *p, int space) |
char *p; |
|
int space; |
|
{ |
{ |
if (remleft <= 0) { |
if (remleft <= 0) { |
/* |
/* |
|
|
if (remleft < space) |
if (remleft < space) |
space = remleft; |
space = remleft; |
|
|
bcopy((char *) remptr, p, space); |
memcpy(p, remptr, space); |
|
|
remptr += space; |
remptr += space; |
remleft -= space; |
remleft -= space; |
|
|
/* |
/* |
* Get the user name for the uid. |
* Get the user name for the uid. |
*/ |
*/ |
extern char *getusername(uid, file, opts) |
char * |
UID_T uid; |
getusername(UID_T uid, char *file, opt_t opts) |
char *file; |
|
opt_t opts; |
|
{ |
{ |
static char buf[100]; |
static char buf[100]; |
static UID_T lastuid = (UID_T)-1; |
static UID_T lastuid = (UID_T)-1; |
|
|
* do the opts check. |
* do the opts check. |
*/ |
*/ |
if (IS_ON(opts, DO_NUMCHKOWNER)) { |
if (IS_ON(opts, DO_NUMCHKOWNER)) { |
(void) snprintf(buf, sizeof buf, ":%u", uid); |
(void) snprintf(buf, sizeof(buf), ":%u", uid); |
return(buf); |
return(buf); |
} |
} |
|
|
|
|
lastuid = uid; |
lastuid = uid; |
|
|
if ((pwd = getpwuid(uid)) == NULL) { |
if ((pwd = getpwuid(uid)) == NULL) { |
message(MT_WARNING, |
if (IS_ON(opts, DO_DEFOWNER) && !isserver) |
"%s: No password entry for uid %u", file, uid); |
(void) strlcpy(buf, defowner, sizeof(buf)); |
(void) snprintf(buf, sizeof buf, ":%u", uid); |
else { |
} else |
message(MT_WARNING, |
(void) strlcpy(buf, pwd->pw_name, sizeof buf); |
"%s: No password entry for uid %u", file, uid); |
|
(void) snprintf(buf, sizeof(buf), ":%u", uid); |
|
} |
|
} else { |
|
(void) strlcpy(buf, pwd->pw_name, sizeof(buf)); |
|
} |
|
|
return(buf); |
return(buf); |
} |
} |
|
|
/* |
/* |
* Get the group name for the gid. |
* Get the group name for the gid. |
*/ |
*/ |
extern char *getgroupname(gid, file, opts) |
char * |
GID_T gid; |
getgroupname(GID_T gid, char *file, opt_t opts) |
char *file; |
|
opt_t opts; |
|
{ |
{ |
static char buf[100]; |
static char buf[100]; |
static GID_T lastgid = (GID_T)-1; |
static GID_T lastgid = (GID_T)-1; |
|
|
* do the opts check. |
* do the opts check. |
*/ |
*/ |
if (IS_ON(opts, DO_NUMCHKGROUP)) { |
if (IS_ON(opts, DO_NUMCHKGROUP)) { |
(void) snprintf(buf, sizeof buf, ":%u", gid); |
(void) snprintf(buf, sizeof(buf), ":%u", gid); |
return(buf); |
return(buf); |
} |
} |
|
|
|
|
lastgid = gid; |
lastgid = gid; |
|
|
if ((grp = (struct group *)getgrgid(gid)) == NULL) { |
if ((grp = (struct group *)getgrgid(gid)) == NULL) { |
message(MT_WARNING, "%s: No name for group %u", file, gid); |
if (IS_ON(opts, DO_DEFGROUP) && !isserver) |
(void) snprintf(buf, sizeof buf, ":%u", gid); |
(void) strlcpy(buf, defgroup, sizeof(buf)); |
|
else { |
|
message(MT_WARNING, "%s: No name for group %u", |
|
file, gid); |
|
(void) snprintf(buf, sizeof(buf), ":%u", gid); |
|
} |
} else |
} else |
(void) strlcpy(buf, grp->gr_name, sizeof buf); |
(void) strlcpy(buf, grp->gr_name, sizeof(buf)); |
|
|
return(buf); |
return(buf); |
} |
} |
|
|
/* |
/* |
* Read a response from the remote host. |
* Read a response from the remote host. |
*/ |
*/ |
extern int response() |
int |
|
response(void) |
{ |
{ |
static u_char resp[BUFSIZ]; |
static u_char resp[BUFSIZ]; |
u_char *s; |
u_char *s; |
|
|
if (s) |
if (s) |
message(MT_FERROR, "%s", s); |
message(MT_FERROR, "%s", s); |
finish(); |
finish(); |
|
return(-1); |
} |
} |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
} |
} |
|
|
* user's home directory path name. Return a pointer in buf to the |
* user's home directory path name. Return a pointer in buf to the |
* part corresponding to `file'. |
* part corresponding to `file'. |
*/ |
*/ |
extern char *exptilde(ebuf, file, ebufsize) |
char * |
char *ebuf; |
exptilde(char *ebuf, char *file, size_t ebufsize) |
size_t ebufsize; |
|
char *file; |
|
{ |
{ |
char *pw_dir, *rest; |
char *pw_dir, *rest; |
size_t len; |
size_t len; |
|
|
* Set our effective user id to the user running us. |
* Set our effective user id to the user running us. |
* This should be the uid we do most of our work as. |
* This should be the uid we do most of our work as. |
*/ |
*/ |
extern int becomeuser() |
int |
|
becomeuser(void) |
{ |
{ |
int r = 0; |
int r = 0; |
|
|
|
|
#endif /* HAVE_SAVED_IDS */ |
#endif /* HAVE_SAVED_IDS */ |
|
|
if (r < 0) |
if (r < 0) |
error("becomeuser %d failed: %s (ruid = %u euid = %u)", |
error("becomeuser %u failed: %s (ruid = %u euid = %u)", |
userid, SYSERR, getuid(), geteuid()); |
userid, SYSERR, getuid(), geteuid()); |
|
|
return(r); |
return(r); |
|
|
/* |
/* |
* Set our effective user id to "root" (uid = 0) |
* Set our effective user id to "root" (uid = 0) |
*/ |
*/ |
extern int becomeroot() |
int |
|
becomeroot(void) |
{ |
{ |
int r = 0; |
int r = 0; |
|
|
|
|
/* |
/* |
* Set access and modify times of a given file |
* Set access and modify times of a given file |
*/ |
*/ |
extern int setfiletime(file, atime, mtime) |
int |
char *file; |
setfiletime(char *file, time_t atime, time_t mtime) |
time_t atime; |
|
time_t mtime; |
|
{ |
{ |
#if SETFTIME_TYPE == SETFTIME_UTIMES |
#if SETFTIME_TYPE == SETFTIME_UTIMES |
struct timeval tv[2]; |
struct timeval tv[2]; |
|
|
/* |
/* |
* Get version info |
* Get version info |
*/ |
*/ |
extern char *getversion() |
char * |
|
getversion(void) |
{ |
{ |
static char buff[BUFSIZ]; |
static char buff[BUFSIZ]; |
|
|
(void) snprintf(buff, sizeof buff, |
(void) snprintf(buff, sizeof(buff), |
"Version %s.%d (%s) - Protocol Version %d, Release %s, Patch level %d", |
"Version %s.%d (%s) - Protocol Version %d, Release %s, Patch level %d", |
DISTVERSION, PATCHLEVEL, DISTSTATUS, |
DISTVERSION, PATCHLEVEL, DISTSTATUS, |
VERSION, DISTVERSION, PATCHLEVEL); |
VERSION, DISTVERSION, PATCHLEVEL); |
|
|
* Execute a shell command to handle special cases. |
* Execute a shell command to handle special cases. |
* This is now common to both server and client |
* This is now common to both server and client |
*/ |
*/ |
void runcommand(cmd) |
void |
char *cmd; |
runcommand(char *cmd) |
{ |
{ |
int fd[2]; |
ssize_t nread; |
int status; |
pid_t pid, wpid; |
char *cp, *s; |
char *cp, *s; |
char sbuf[BUFSIZ], buf[BUFSIZ]; |
char sbuf[BUFSIZ], buf[BUFSIZ]; |
pid_t pid, i; |
int fd[2], status; |
|
|
if (pipe(fd) < 0) { |
if (pipe(fd) < 0) { |
error("pipe of %s failed: %s", cmd, SYSERR); |
error("pipe of %s failed: %s", cmd, SYSERR); |
return; |
return; |
|
|
(void) close(fd[PIPE_WRITE]); |
(void) close(fd[PIPE_WRITE]); |
s = sbuf; |
s = sbuf; |
*s++ = C_LOGMSG; |
*s++ = C_LOGMSG; |
while ((i = read(fd[PIPE_READ], buf, sizeof(buf))) > 0) { |
while ((nread = read(fd[PIPE_READ], buf, sizeof(buf))) > 0) { |
cp = buf; |
cp = buf; |
do { |
do { |
*s++ = *cp++; |
*s++ = *cp++; |
|
|
message(MT_INFO, "%s", sbuf+1); |
message(MT_INFO, "%s", sbuf+1); |
} |
} |
s = &sbuf[1]; |
s = &sbuf[1]; |
} while (--i); |
} while (--nread); |
} |
} |
if (s > (char *) &sbuf[1]) { |
if (s > (char *) &sbuf[1]) { |
*s++ = '\n'; |
*s++ = '\n'; |
|
|
message(MT_INFO, "%s", sbuf+1); |
message(MT_INFO, "%s", sbuf+1); |
} |
} |
} |
} |
while ((i = wait(&status)) != pid && i != -1) |
while ((wpid = wait(&status)) != pid && wpid != -1) |
; |
; |
if (i == -1) |
if (wpid == -1) |
status = -1; |
status = -1; |
(void) close(fd[PIPE_READ]); |
(void) close(fd[PIPE_READ]); |
if (status) |
if (status) |
|
|
/* |
/* |
* Malloc with error checking |
* Malloc with error checking |
*/ |
*/ |
char *xmalloc(amt) |
char * |
int amt; |
xmalloc(size_t amt) |
{ |
{ |
char *ptr; |
char *ptr; |
extern POINTER *malloc(); |
|
|
|
if ((ptr = (char *)malloc(amt)) == NULL) |
if ((ptr = (char *)malloc(amt)) == NULL) |
fatalerr("Cannot malloc %d bytes of memory.", amt); |
fatalerr("Cannot malloc %d bytes of memory.", amt); |
|
|
/* |
/* |
* realloc with error checking |
* realloc with error checking |
*/ |
*/ |
char *xrealloc(baseptr, amt) |
char * |
char *baseptr; |
xrealloc(char *baseptr, size_t amt) |
unsigned int amt; |
|
{ |
{ |
char *new; |
char *new; |
extern POINTER *realloc(); |
|
|
|
if ((new = (char *)realloc(baseptr, amt)) == NULL) |
if ((new = (char *)realloc(baseptr, amt)) == NULL) |
fatalerr("Cannot realloc %d bytes of memory.", amt); |
fatalerr("Cannot realloc %d bytes of memory.", amt); |
|
|
/* |
/* |
* calloc with error checking |
* calloc with error checking |
*/ |
*/ |
char *xcalloc(num, esize) |
char * |
unsigned int num; |
xcalloc(size_t num, size_t esize) |
unsigned int esize; |
|
{ |
{ |
char *ptr; |
char *ptr; |
extern POINTER *calloc(); |
|
|
|
if ((ptr = (char *)calloc(num, esize)) == NULL) |
if ((ptr = (char *)calloc(num, esize)) == NULL) |
fatalerr("Cannot calloc %d * %d = %d bytes of memory.", |
fatalerr("Cannot calloc %d * %d = %d bytes of memory.", |
|
|
/* |
/* |
* Strdup with error checking |
* Strdup with error checking |
*/ |
*/ |
char *xstrdup(str) |
char * |
char *str; |
xstrdup(const char *str) |
{ |
{ |
char *nstr; |
size_t len = strlen(str) + 1; |
|
char *nstr = (char *) malloc(len); |
|
|
if ((nstr = strdup(str)) == NULL) |
if (nstr == NULL) |
fatalerr("Cannot malloc %d bytes of memory.", strlen(str) + 1); |
fatalerr("Cannot malloc %u bytes of memory.", len); |
|
|
return(nstr); |
return(memcpy(nstr, str, len)); |
} |
} |
|
|
/* |
/* |
* Private version of basename() |
* Private version of basename() |
*/ |
*/ |
extern char *xbasename(path) |
char * |
char *path; |
xbasename(char *path) |
{ |
{ |
char *cp; |
char *cp; |
|
|
if ((cp = strrchr(path, '/'))) |
if ((cp = strrchr(path, '/')) != NULL) |
return(cp+1); |
return(cp+1); |
else |
else |
return(path); |
return(path); |
|
|
* search until a component of that path is found and |
* search until a component of that path is found and |
* return the found file name. |
* return the found file name. |
*/ |
*/ |
extern char *searchpath(path) |
char * |
char *path; |
searchpath(char *path) |
{ |
{ |
char *file; |
char *file; |
char *space; |
char *space; |
|
|
/* |
/* |
* Set line buffering. |
* Set line buffering. |
*/ |
*/ |
extern void |
int |
mysetlinebuf(fp) |
mysetlinebuf(FILE *fp) |
FILE *fp; |
|
{ |
{ |
#if SETBUF_TYPE == SETBUF_SETLINEBUF |
#if SETBUF_TYPE == SETBUF_SETLINEBUF |
setlinebuf(fp); |
return(setlinebuf(fp)); |
#endif /* SETBUF_SETLINEBUF */ |
#endif /* SETBUF_SETLINEBUF */ |
#if SETBUF_TYPE == SETBUF_SETVBUF |
#if SETBUF_TYPE == SETBUF_SETVBUF |
setvbuf(stdout, NULL, _IOLBF, BUFSIZ); |
return(setvbuf(stdout, NULL, _IOLBF, BUFSIZ)); |
#endif /* SETBUF_SETVBUF */ |
#endif /* SETBUF_SETVBUF */ |
#if !defined(SETBUF_TYPE) |
#if !defined(SETBUF_TYPE) |
No SETBUF_TYPE is defined! |
No SETBUF_TYPE is defined! |
|
|
* Our interface to system call to get a socket pair. |
* Our interface to system call to get a socket pair. |
*/ |
*/ |
int |
int |
getsocketpair(domain, type, protocol, sv) |
getsocketpair(int domain, int type, int protocol, int sv[]) |
int domain; |
|
int type; |
|
int protocol; |
|
int sv[]; |
|
{ |
{ |
#if SOCKPAIR_TYPE == SOCKPAIR_SOCKETPAIR |
#if SOCKPAIR_TYPE == SOCKPAIR_SOCKETPAIR |
return(socketpair(domain, type, protocol, sv)); |
return(socketpair(domain, type, protocol, sv)); |