BSD 4_3 release
[unix-history] / usr / src / usr.bin / uucp / cico.c
#ifndef lint
static char sccsid[] = "@(#)cico.c 5.14 (Berkeley) 4/14/86";
#endif
#include <signal.h>
#include "uucp.h"
#include <setjmp.h>
#ifdef USG
#include <termio.h>
#endif
#ifndef USG
#include <sgtty.h>
#endif
#ifdef BSDTCP
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif BSDTCP
#include <sys/stat.h>
#include "uust.h"
#include "uusub.h"
#if defined(VMS) && defined(BSDTCP)
#define NOGETPEER
#endif
#ifdef BSD2_9
#define NOGETPEER
#endif
jmp_buf Sjbuf;
jmp_buf Pipebuf;
/* call fail text */
char *Stattext[] = {
"",
"BAD SYSTEM",
"WRONG TIME TO CALL",
"SYSTEM LOCKED",
"NO DEVICE",
"CALL FAILED",
"LOGIN FAILED",
"BAD SEQUENCE"
};
/* call fail codes */
int Stattype[] = {
0,
0,
SS_WRONGTIME,
0,
SS_NODEVICE,
SS_FAIL,
SS_FAIL,
SS_BADSEQ
};
/* Arguments to setdebug(): */
#define DBG_TEMP 0 /* Create a temporary audit file */
#define DBG_PERM 1 /* Create a permanent audit file */
#define DBG_CLEAN 2 /* Cleanup, discard temp file */
int ReverseRole = 0;
int Role = SLAVE;
int onesys = 0;
int turntime = 30 * 60; /* 30 minutes expressed in seconds */
char *ttyn = NULL;
extern int LocalOnly;
extern int errno;
extern char MaxGrade, DefMaxGrade;
extern char Myfullname[];
#ifdef USG
struct termio Savettyb;
#endif
#ifndef USG
struct sgttyb Savettyb;
#endif
/*
* this program is used to place a call to a
* remote machine, login, and copy files between the two machines.
*/
main(argc, argv)
int argc;
register char *argv[];
{
register int ret;
int seq;
char wkpre[NAMESIZE], file[NAMESIZE];
char msg[MAXFULLNAME], *q;
register char *p;
extern onintr(), timeout(), dbg_signal();
extern char *pskip();
char rflags[MAXFULLNAME];
#ifdef NOGETPEER
u_long Hostnumber = 0;
#endif NOGETPEER
strcpy(Progname, "uucico");
#ifdef BSD4_2
sigsetmask(0); /* in case we inherit blocked signals */
#endif BSD4_2
signal(SIGINT, onintr);
signal(SIGHUP, onintr);
signal(SIGQUIT, onintr);
signal(SIGTERM, onintr);
signal(SIGPIPE, onintr); /* 4.1a tcp-ip stupidity */
signal(SIGFPE, dbg_signal);
ret = guinfo(getuid(), User, msg);
strcpy(Loginuser, User);
uucpname(Myname);
ASSERT(ret == 0, "BAD UID", CNULL, ret);
setbuf (stderr, CNULL);
rflags[0] = '\0';
umask(WFMASK);
strcpy(Rmtname, Myname);
Ifn = Ofn = -1;
while(argc>1 && argv[1][0] == '-'){
switch(argv[1][1]){
case 'd':
Spool = &argv[1][2];
break;
case 'g':
case 'p':
MaxGrade = DefMaxGrade = argv[1][2];
break;
case 'r':
Role = atoi(&argv[1][2]);
break;
case 'R':
ReverseRole++;
Role = MASTER;
break;
case 's':
strncpy(Rmtname, &argv[1][2], MAXBASENAME);
Rmtname[MAXBASENAME] = '\0';
if (Rmtname[0] != '\0')
onesys = 1;
break;
case 'x':
Debug = atoi(&argv[1][2]);
if (Debug <= 0)
Debug = 1;
strcat(rflags, argv[1]);
break;
case 't':
turntime = atoi(&argv[1][2])*60;/* minutes to seconds */
break;
case 'L': /* local calls only */
LocalOnly++;
break;
#ifdef NOGETPEER
case 'h':
Hostnumber = inet_addr(&argv[1][2]);
break;
#endif NOGETPEER
default:
printf("unknown flag %s (ignored)\n", argv[1]);
break;
}
--argc; argv++;
}
while (argc > 1) {
fprintf(stderr, "unknown argument %s (ignored)\n", argv[1]);
--argc; argv++;
}
if (Debug && Role == MASTER)
chkdebug();
/* Try to run as uucp */
setgid(getegid());
setuid(geteuid());
#ifdef TIOCNOTTY
/*
* detach uucico from controlling terminal
* to defend against rlogind sending us a SIGKILL (!!!)
*/
if (Role == MASTER && (ret = open("/dev/tty", 2)) >= 0) {
ioctl(ret, TIOCNOTTY, STBNULL);
close(ret);
}
#endif TIOCNOTTY
#ifdef BSD4_2
if (getpgrp(0) == 0) { /* We have no controlling terminal */
setpgrp(0, getpid());
}
#endif BSD4_2
ret = subchdir(Spool);
ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret);
strcpy(Wrkdir, Spool);
if (Debug) {
setdebug ((Role == SLAVE) ? DBG_TEMP : DBG_PERM);
if (Debug > 0)
logent ("Local Enabled", "DEBUG");
}
/*
* First time through: If we're the slave, do initial checking.
*/
if (Role == SLAVE) {
/* check for /etc/nologin */
if (access(NOLOGIN, 0) == 0) {
logent(NOLOGIN, "UUCICO SHUTDOWN");
if (Debug > 4)
logent("DEBUGGING", "continuing anyway");
else
cleanup(1);
}
Ifn = 0;
Ofn = 1;
#ifdef TCPIP
/*
* Determine if we are on TCPIP
*/
if (isatty(Ifn) < 0) {
IsTcpIp = 1;
DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
} else
IsTcpIp = 0;
#endif TCPIP
/* initial handshake */
onesys = 1;
if (!IsTcpIp) {
#ifdef USG
ret = ioctl(Ifn, TCGETA, &Savettyb);
Savettyb.c_cflag = (Savettyb.c_cflag & ~CS8) | CS7;
Savettyb.c_oflag |= OPOST;
Savettyb.c_lflag |= (ISIG|ICANON|ECHO);
#else !USG
ret = ioctl(Ifn, TIOCGETP, &Savettyb);
Savettyb.sg_flags |= ECHO;
Savettyb.sg_flags &= ~RAW;
#endif !USG
ttyn = ttyname(Ifn);
}
fixmode(Ifn);
/*
* Initial Message -- tell them we're here, and who we are.
*/
sprintf(msg, "here=%s", Myfullname);
omsg('S', msg, Ofn);
signal(SIGALRM, timeout);
alarm(MAXMSGTIME);
if (setjmp(Sjbuf)) {
/* timed out */
if (!IsTcpIp) {
#ifdef USG
ret = ioctl(Ifn, TCSETA, &Savettyb);
#else !USG
ret = ioctl(Ifn, TIOCSETP, &Savettyb);
#endif !USG
}
cleanup(0);
}
for (;;) {
ret = imsg(msg, Ifn);
if (ret != SUCCESS) {
alarm(0);
if (!IsTcpIp) {
#ifdef USG
ret = ioctl(Ifn, TCSETA, &Savettyb);
#else !USG
ret = ioctl(Ifn, TIOCSETP, &Savettyb);
#endif !USG
}
cleanup(0);
}
if (msg[0] == 'S')
break;
}
alarm(0);
q = &msg[1];
p = pskip(q);
strncpy(Rmtname, q, MAXBASENAME);
Rmtname[MAXBASENAME] = '\0';
/*
* Now that we know who they are, give the audit file the right
* name.
*/
setdebug (DBG_PERM);
DEBUG(4, "sys-%s\n", Rmtname);
/* The versys will also do an alias on the incoming name */
if (versys(&Rmtname)) {
/* If we don't know them, we won't talk to them... */
#ifdef NOSTRANGERS
logent(Rmtname, "UNKNOWN HOST");
omsg('R', "You are unknown to me", Ofn);
cleanup(0);
#endif NOSTRANGERS
}
#ifdef BSDTCP
/* we must make sure they are really who they say they
* are. We compare the hostnumber with the number in the hosts
* table for the site they claim to be.
*/
if (IsTcpIp) {
struct hostent *hp;
char *cpnt, *inet_ntoa();
int fromlen;
struct sockaddr_in from;
extern char PhoneNumber[];
#ifdef NOGETPEER
from.sin_addr.s_addr = Hostnumber;
from.sin_family = AF_INET;
#else !NOGETPEER
fromlen = sizeof(from);
if (getpeername(Ifn, &from, &fromlen) < 0) {
logent(Rmtname, "NOT A TCP CONNECTION");
omsg('R', "NOT TCP", Ofn);
cleanup(0);
}
#endif !NOGETPEER
hp = gethostbyaddr(&from.sin_addr,
sizeof (struct in_addr), from.sin_family);
if (hp == NULL) {
/* security break or just old host table? */
logent(Rmtname, "UNKNOWN IP-HOST Name =");
cpnt = inet_ntoa(from.sin_addr),
logent(cpnt, "UNKNOWN IP-HOST Number =");
sprintf(wkpre, "%s/%s isn't in my host table",
Rmtname, cpnt);
omsg('R' ,wkpre ,Ofn);
cleanup(0);
}
if (Debug > 99)
logent(Rmtname,"Request from IP-Host name =");
/*
* The following is to determine if the name given us by
* the Remote uucico matches any of the names
* given its network number (remote machine) in our
* host table.
* We could check the aliases, but that won't work in
* all cases (like if you are running the domain
* server, where you don't get any aliases). The only
* reliable way I can think of that works in ALL cases
* is too look up the site in L.sys and see if the
* sitename matches what we would call him if we
* originated the call.
*/
/* PhoneNumber contains the official network name of the host we are checking. (set in versys.c) */
if (sncncmp(PhoneNumber, hp->h_name, SYSNSIZE) == 0) {
if (Debug > 99)
logent(q,"Found in host Tables");
} else {
logent(hp->h_name, "FORGED HOSTNAME");
logent(inet_ntoa(from.sin_addr), "ORIGINATED AT");
logent(PhoneNumber, "SHOULD BE");
sprintf(wkpre, "You're not who you claim to be: %s != %s", hp->h_name, PhoneNumber);
omsg('R', wkpre, Ofn);
cleanup(0);
}
}
#endif BSDTCP
if (mlock(Rmtname)) {
omsg('R', "LCK", Ofn);
cleanup(0);
}
else if (callback(Loginuser)) {
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
omsg('R', "CB", Ofn);
logent("CALLBACK", "REQUIRED");
/* set up for call back */
systat(Rmtname, SS_CALLBACK, "CALLING BACK");
gename(CMDPRE, Rmtname, 'C', file);
close(creat(subfile(file), 0666));
xuucico(Rmtname);
cleanup(0);
}
seq = 0;
while (*p == '-') {
q = pskip(p);
switch(*(++p)) {
case 'x':
if (Debug == 0) {
Debug = atoi(++p);
if (Debug <= 0)
Debug = 1;
setdebug(DBG_PERM);
if (Debug > 0)
logent("Remote Enabled", "DEBUG");
} else {
DEBUG(1, "Remote debug request ignored\n",
CNULL);
}
break;
case 'Q':
seq = atoi(++p);
break;
case 'p':
MaxGrade = DefMaxGrade = *++p;
DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
break;
case 'v':
if (strncmp(p, "grade", 5) == 0) {
p += 6;
MaxGrade = DefMaxGrade = *p++;
DEBUG(4, "MaxGrade set to %c\n", MaxGrade);
}
break;
default:
break;
}
p = q;
}
if (callok(Rmtname) == SS_BADSEQ) {
logent("BADSEQ", "PREVIOUS");
omsg('R', "BADSEQ", Ofn);
cleanup(0);
}
#ifdef GNXSEQ
if ((ret = gnxseq(Rmtname)) == seq) {
omsg('R', "OK", Ofn);
cmtseq();
} else {
#else !GNXSEQ
if (seq == 0)
omsg('R', "OK", Ofn);
else {
#endif !GNXSEQ
systat(Rmtname, Stattype[7], Stattext[7]);
logent("BAD SEQ", "FAILED HANDSHAKE");
#ifdef GNXSEQ
ulkseq();
#endif GNXSEQ
omsg('R', "BADSEQ", Ofn);
cleanup(0);
}
if (ttyn != NULL)
chmod(ttyn, 0600);
}
loop:
if(setjmp(Pipebuf)) { /* come here on SIGPIPE */
clsacu();
close(Ofn);
close(Ifn);
Ifn = Ofn = -1;
rmlock(CNULL);
sleep(3);
}
if (!onesys) {
ret = gnsys(Rmtname, Spool, CMDPRE);
setdebug(DBG_PERM);
if (ret == FAIL)
cleanup(100);
if (ret == SUCCESS)
cleanup(0);
} else if (Role == MASTER && callok(Rmtname) != 0) {
logent("SYSTEM STATUS", "CAN NOT CALL");
cleanup(0);
}
sprintf(wkpre, "%c.%.*s", CMDPRE, SYSNSIZE, Rmtname);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
if (Role == MASTER) {
/* check for /etc/nologin */
if (access(NOLOGIN, 0) == 0) {
logent(NOLOGIN, "UUCICO SHUTDOWN");
if (Debug > 4)
logent("DEBUGGING", "continuing anyway");
else
cleanup(1);
}
/* master part */
signal(SIGHUP, SIG_IGN);
if (Ifn != -1 && Role == MASTER) {
write(Ofn, EOTMSG, strlen(EOTMSG));
clsacu();
close(Ofn);
close(Ifn);
Ifn = Ofn = -1;
rmlock(CNULL);
sleep(3);
}
sprintf(msg, "call to %s ", Rmtname);
if (mlock(Rmtname) != SUCCESS) {
logent(msg, "LOCKED");
US_SST(us_s_lock);
goto next;
}
Ofn = Ifn = conn(Rmtname);
if (Ofn < 0) {
if (Ofn != CF_TIME)
logent(msg, _FAILED);
/* avoid excessive 'wrong time' info */
if (Stattype[-Ofn] != SS_WRONGTIME){
systat(Rmtname, Stattype[-Ofn], Stattext[-Ofn]);
US_SST(-Ofn);
UB_SST(-Ofn);
}
goto next;
} else {
logent(msg, "SUCCEEDED");
US_SST(us_s_cok);
UB_SST(ub_ok);
}
#ifdef TCPIP
/*
* Determine if we are on TCPIP
*/
if (isatty(Ifn) == 0) {
IsTcpIp = 1;
DEBUG(4, "TCPIP connection -- ioctl-s disabled\n", CNULL);
} else
IsTcpIp = 0;
#endif
if (setjmp(Sjbuf))
goto next;
signal(SIGALRM, timeout);
alarm(2 * MAXMSGTIME);
for (;;) {
ret = imsg(msg, Ifn);
if (ret != 0) {
alarm(0);
logent("imsg 1", _FAILED);
goto Failure;
}
if (msg[0] == 'S')
break;
}
alarm(MAXMSGTIME);
#ifdef GNXSEQ
seq = gnxseq(Rmtname);
#else !GNXSEQ
seq = 0;
#endif !GNXSEQ
if (MaxGrade != '\177') {
DEBUG(2, "Max Grade this transfer is %c\n", MaxGrade);
sprintf(msg, "%s -Q%d -p%c -vgrade=%c %s",
Myname, seq, MaxGrade, MaxGrade, rflags);
} else
sprintf(msg, "%s -Q%d %s", Myname, seq, rflags);
omsg('S', msg, Ofn);
for (;;) {
ret = imsg(msg, Ifn);
DEBUG(4, "msg-%s\n", msg);
if (ret != SUCCESS) {
alarm(0);
#ifdef GNXSEQ
ulkseq();
#endif GNXSEQ
logent("imsg 2", _FAILED);
goto Failure;
}
if (msg[0] == 'R')
break;
}
alarm(0);
if (msg[1] == 'B') {
/* bad sequence */
logent("BAD SEQ", "FAILED HANDSHAKE");
US_SST(us_s_hand);
systat(Rmtname, SS_BADSEQ, Stattext[SS_BADSEQ]);
#ifdef GNXSEQ
ulkseq();
#endif GNXSEQ
goto next;
}
if (strcmp(&msg[1], "OK") != SAME) {
logent(&msg[1], "FAILED HANDSHAKE");
US_SST(us_s_hand);
#ifdef GNXSEQ
ulkseq();
#endif GNXSEQ
systat(Rmtname, SS_INPROGRESS,
strcmp(&msg[1], "CB") == SAME?
"AWAITING CALLBACK": "FAILED HANDSHAKE");
goto next;
}
#ifdef GNXSEQ
cmtseq();
#endif GNXSEQ
}
DEBUG(1, "Rmtname %s, ", Rmtname);
DEBUG(1, "Role %s, ", Role ? "MASTER" : "SLAVE");
DEBUG(1, "Ifn - %d, ", Ifn);
DEBUG(1, "Loginuser - %s\n", Loginuser);
ttyn = ttyname(Ifn);
alarm(MAXMSGTIME);
if (ret=setjmp(Sjbuf))
goto Failure;
ret = startup(Role);
alarm(0);
if (ret != SUCCESS) {
logent("startup", _FAILED);
Failure:
US_SST(us_s_start);
systat(Rmtname, SS_FAIL, ret > 0 ? "CONVERSATION FAILED" :
"STARTUP FAILED");
goto next;
} else {
if (ttyn != NULL) {
char startupmsg[BUFSIZ];
extern int linebaudrate;
sprintf(startupmsg, "startup %s %d baud", &ttyn[5],
linebaudrate);
logent(startupmsg, "OK");
} else
logent("startup", "OK");
US_SST(us_s_gress);
systat(Rmtname, SS_INPROGRESS, "TALKING");
ret = cntrl(Role, wkpre);
DEBUG(1, "cntrl - %d\n", ret);
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGALRM, timeout);
if (ret == SUCCESS) {
logent("conversation complete", "OK");
US_SST(us_s_ok);
rmstat(Rmtname);
} else {
logent("conversation complete", _FAILED);
US_SST(us_s_cf);
systat(Rmtname, SS_FAIL, "CONVERSATION FAILED");
}
alarm(MAXMSGTIME);
DEBUG(4, "send OO %d,", ret);
if (!setjmp(Sjbuf)) {
for (;;) {
omsg('O', "OOOOO", Ofn);
ret = imsg(msg, Ifn);
if (ret != 0)
break;
if (msg[0] == 'O')
break;
}
}
alarm(0);
clsacu();
rmlock(CNULL);
}
next:
if (!onesys) {
goto loop;
}
cleanup(0);
}
#ifndef USG
struct sgttyb Hupvec;
#endif
/*
* cleanup and exit with "code" status
*/
cleanup(code)
register int code;
{
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
rmlock(CNULL);
sleep(5); /* Wait for any pending output */
clsacu();
logcls();
if (Role == SLAVE) {
if (!IsTcpIp) {
#ifdef USG
Savettyb.c_cflag |= HUPCL;
(void) ioctl(0, TCSETA, &Savettyb);
#else !USG
(void) ioctl(0, TIOCHPCL, STBNULL);
#ifdef TIOCSDTR
(void) ioctl(0, TIOCCDTR, STBNULL);
sleep(2);
(void) ioctl(0, TIOCSDTR, STBNULL);
#else !TIOCSDTR
(void) ioctl(0, TIOCGETP, &Hupvec);
Hupvec.sg_ispeed = B0;
Hupvec.sg_ospeed = B0;
(void) ioctl(0, TIOCSETP, &Hupvec);
#endif !TIOCSDTR
sleep(2);
(void) ioctl(0, TIOCSETP, &Savettyb);
/* make *sure* exclusive access is off */
(void) ioctl(0, TIOCNXCL, STBNULL);
#endif !USG
}
if (ttyn != NULL)
chmod(ttyn, 0600);
}
if (Ofn != -1) {
if (Role == MASTER)
write(Ofn, EOTMSG, strlen(EOTMSG));
close(Ifn);
close(Ofn);
}
#ifdef DIALINOUT
/* reenable logins on dialout */
reenable();
#endif DIALINOUT
if (code == 0)
xuuxqt();
else
DEBUG(1, "exit code %d\n", code);
setdebug (DBG_CLEAN);
exit(code);
}
/*
* on interrupt - remove locks and exit
*/
onintr(inter)
register int inter;
{
char str[30];
signal(inter, SIG_IGN);
sprintf(str, "SIGNAL %d", inter);
logent(str, "CAUGHT");
US_SST(us_s_intr);
if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME))
systat(Rmtname, SS_FAIL, str);
if (inter == SIGPIPE && !onesys)
longjmp(Pipebuf, 1);
cleanup(inter);
}
/*
* Catch a special signal
* (SIGFPE, ugh), and toggle debugging between 0 and 30.
* Handy for looking in on long running uucicos.
*/
dbg_signal()
{
Debug = (Debug == 0) ? 30 : 0;
setdebug(DBG_PERM);
if (Debug > 0)
logent("Signal Enabled", "DEBUG");
}
/*
* Check debugging requests, and open RMTDEBUG audit file if necessary. If an
* audit file is needed, the parm argument indicates how to create the file:
*
* DBG_TEMP - Open a temporary file, with filename = RMTDEBUG/pid.
* DBG_PERM - Open a permanent audit file, filename = RMTDEBUG/Rmtname.
* If a temp file already exists, it is mv'ed to be permanent.
* DBG_CLEAN - Cleanup; unlink temp files.
*
* Restrictions - this code can only cope with one open debug file at a time.
* Each call creates a new file; if an old one of the same name exists it will
* be overwritten.
*/
setdebug(parm)
int parm;
{
char buf[BUFSIZ]; /* Buffer for building filenames */
static char *temp = NULL; /* Ptr to temporary file name */
static int auditopen = 0; /* Set to 1 when we open a file */
struct stat stbuf; /* File status buffer */
/*
* If movement or cleanup of a temp file is indicated, we do it no
* matter what.
*/
if (temp != CNULL && parm == DBG_PERM) {
sprintf(buf, "%s/%s", RMTDEBUG, Rmtname);
unlink(buf);
if (link(temp, buf) != 0) {
Debug = 0;
assert("RMTDEBUG LINK FAIL", temp, errno);
cleanup(1);
}
parm = DBG_CLEAN;
}
if (parm == DBG_CLEAN) {
if (temp != CNULL) {
unlink(temp);
free(temp);
temp = CNULL;
}
return;
}
if (Debug == 0)
return; /* Gotta be in debug to come here. */
/*
* If we haven't opened a file already, we can just return if it's
* alright to use the stderr we came in with. We can if:
*
* Role == MASTER, and Stderr is a regular file, a TTY or a pipe.
*
* Caution: Detecting when stderr is a pipe is tricky, because the 4.2
* man page for fstat(2) disagrees with reality, and System V leaves it
* undefined, which means different implementations act differently.
*/
if (!auditopen && Role == MASTER) {
if (isatty(fileno(stderr)))
return;
else if (fstat(fileno(stderr), &stbuf) == 0) {
#ifdef USG
/* Is Regular File or Fifo */
if ((stbuf.st_mode & 0060000) == 0)
return;
#else !USG
#ifdef BSD4_2
/* Is Regular File */
if ((stbuf.st_mode & S_IFMT) == S_IFREG ||
stbuf.st_mode == 0) /* Is a pipe */
return;
#else !BSD4_2
/* Is Regular File or Pipe */
if ((stbuf.st_mode & S_IFMT) == S_IFREG)
return;
#endif BSD4_2
#endif USG
}
}
/*
* We need RMTDEBUG directory to do auditing. If the file doesn't exist,
* then we forget about debugging; if it exists but has improper owner-
* ship or modes, we gripe about it in ERRLOG.
*/
if (stat(RMTDEBUG, &stbuf) != SUCCESS) {
Debug = 0;
return;
}
if ((geteuid() != stbuf.st_uid) || /* We must own it */
((stbuf.st_mode & 0170700) != 040700)) { /* Directory, rwx */
Debug = 0;
assert("INVALID RMTDEBUG DIRECTORY:", RMTDEBUG, stbuf.st_mode);
return;
}
if (parm == DBG_TEMP) {
sprintf(buf, "%s/%d", RMTDEBUG, getpid());
temp = malloc(strlen (buf) + 1);
if (temp == CNULL) {
Debug = 0;
assert("RMTDEBUG MALLOC ERROR:", temp, errno);
cleanup(1);
}
strcpy(temp, buf);
} else
sprintf(buf, "%s/%s", RMTDEBUG, Rmtname);
unlink(buf);
if (freopen(buf, "w", stderr) != stderr) {
Debug = 0;
assert("FAILED RMTDEBUG FILE OPEN:", buf, errno);
cleanup(1);
}
setbuf(stderr, CNULL);
auditopen = 1;
}
/*
* catch SIGALRM routine
*/
timeout()
{
extern int HaveSentHup;
if (!HaveSentHup) {
logent(Rmtname, "TIMEOUT");
if (*Rmtname && strncmp(Rmtname, Myname, MAXBASENAME)) {
US_SST(us_s_tmot);
systat(Rmtname, SS_FAIL, "TIMEOUT");
}
}
longjmp(Sjbuf, 1);
}
static char *
pskip(p)
register char *p;
{
while(*p && *p != ' ')
++p;
while(*p && *p == ' ')
*p++ = 0;
return p;
}