bug fixes and changes from Rick Adams
[unix-history] / usr / src / usr.bin / uucp / uucico / cntrl.c
#ifndef lint
static char sccsid[] = "@(#)cntrl.c 5.4 (Berkeley) %G%";
#endif
#include "uucp.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "uust.h"
extern int errno;
struct Proto {
char P_id;
int (*P_turnon)();
int (*P_rdmsg)();
int (*P_wrmsg)();
int (*P_rddata)();
int (*P_wrdata)();
int (*P_turnoff)();
};
extern int gturnon(), gturnoff();
extern int grdmsg(), grddata();
extern int gwrmsg(), gwrdata();
extern int imsg(), omsg();
#ifdef BSDTCP
extern int tnullf();
extern int twrmsg(), trdmsg();
extern int twrdata(), trddata();
#endif BSDTCP
#ifdef PAD
extern int fturnon(), fturnoff();
extern int frdmsg(), frddata();
extern int fwrmsg(), fwrdata();
#endif PAD
struct Proto Ptbl[]={
#ifdef BSDTCP
't', tnullf, trdmsg, twrmsg, trddata, twrdata, tnullf,
#endif BSDTCP
#ifdef PAD
'f', fturnon, frdmsg, fwrmsg, frddata, fwrdata, fturnoff,
#endif PAD
'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
'\0'
};
int (*Imsg)() = imsg, (*Omsg)() = omsg;
int (*Rdmsg)()=imsg, (*Rddata)();
int (*Wrmsg)()=omsg, (*Wrdata)();
int (*Turnon)(), (*Turnoff)();
static char *YES = "Y";
static char *NO = "N";
/* failure messages */
#define EM_MAX 6
#define EM_LOCACC "N1" /* local access to file denied */
#define EM_RMTACC "N2" /* remote access to file/path denied */
#define EM_BADUUCP "N3" /* a bad uucp command was generated */
#define EM_NOTMP "N4" /* remote error - can't create temp */
#define EM_RMTCP "N5" /* can't copy to remote directory - file in public */
#define EM_LOCCP "N6" /* can't copy on local system */
char *Em_msg[] = {
"COPY FAILED (reason not given by remote)",
"local access to file denied",
"remote access to path/file denied",
"system error - bad uucp command generated",
"remote system can't create temp file",
"can't copy to file/directory - file left in PUBDIR/user/file",
"can't copy to file/directory on local system - file left in PUBDIR/user/file"
};
#define XUUCP 'X' /* execute uucp (string) */
#define SLTPTCL 'P' /* select protocol (string) */
#define USEPTCL 'U' /* use protocol (character) */
#define RCVFILE 'R' /* receive file (string) */
#define SNDFILE 'S' /* send file (string) */
#define RQSTCMPT 'C' /* request complete (string - yes | no) */
#define HUP 'H' /* ready to hangup (string - yes | no) */
#define RESET 'X' /* reset line modes */
#define W_TYPE wrkvec[0]
#define W_FILE1 wrkvec[1]
#define W_FILE2 wrkvec[2]
#define W_USER wrkvec[3]
#define W_OPTNS wrkvec[4]
#define W_DFILE wrkvec[5]
#define W_MODE wrkvec[6]
#define W_NUSER wrkvec[7]
#define XFRRATE 35000L
#define RMESG(m, s, n) if (rmesg(m, s, n) != 0) {(*Turnoff)(); return FAIL;} else
#define RAMESG(s, n) if (rmesg('\0', s, n) != 0) {(*Turnoff)(); return FAIL;} else
#define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return FAIL;} else
char Wfile[MAXFULLNAME] = {'\0'};
char Dfile[MAXFULLNAME];
/*
* To avoid a huge backlog of X. files, start uuxqt every so often.
*/
static int nXfiles = 0; /* number of X files since last uuxqt start */
static int nXQTs = 0; /* number of uuxqts started */
static char send_or_receive;
struct stat stbuf;
/*
* cntrl - this routine will execute the conversation
* between the two machines after both programs are
* running.
*
* return codes
* SUCCESS - ok
* FAIL - failed
*/
cntrl(role, wkpre)
int role;
char *wkpre;
{
char msg[BUFSIZ], rqstr[BUFSIZ];
register FILE *fp;
int filemode;
char filename[MAXFULLNAME], wrktype, *wrkvec[20];
extern (*Rdmsg)(), (*Wrmsg)();
extern char *index(), *lastpart();
int status = 1;
register int i, narg;
int mailopt, ntfyopt;
int ret;
static int pnum, tmpnum = 0;
extern int ReverseRole;
pnum = getpid();
Wfile[0] = '\0';
top:
for (i = 0; i < sizeof wrkvec / sizeof wrkvec[0]; i++)
wrkvec[i] = 0;
DEBUG(4, "*** TOP *** - role=%s\n", role ? "MASTER" : "SLAVE");
setline(RESET);
send_or_receive = RESET;
if (role == MASTER) {
/* get work */
if (ReverseRole || (narg = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) {
ReverseRole = 0;
WMESG(HUP, "");
RMESG(HUP, msg, 1);
goto process;
}
wrktype = W_TYPE[0];
msg[0] = '\0';
for (i = 1; i < narg; i++) {
strcat(msg, " ");
strcat(msg, wrkvec[i]);
}
if (wrktype == XUUCP) {
sprintf(rqstr, "X %s", msg);
logent(rqstr, "REQUEST");
goto sendmsg;
}
mailopt = index(W_OPTNS, 'm') != NULL;
ntfyopt = index(W_OPTNS, 'n') != NULL;
if (narg < 5) {
char *bnp;
bnp = rindex(Wfile, '/');
sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : Wfile);
xmv(Wfile, rqstr);
logent(Wfile, "CMD FILE CORRUPTED");
Wfile[0] = '\0';
goto top;
}
sprintf(User, "%.9s", W_USER);
sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,
W_FILE2, W_USER);
logent(rqstr, "REQUEST");
if (wrktype == SNDFILE ) {
strcpy(filename, W_FILE1);
i = expfile(filename);
DEBUG(4, "expfile type - %d, ", i);
if (i != 0 && chkpth(User, "", filename))
goto e_access;
strcpy(Dfile, W_DFILE);
fp = NULL;
if (index(W_OPTNS, 'c') == NULL) {
fp = fopen(subfile(Dfile), "r");
if (fp != NULL)
i = 0;
}
if (fp == NULL &&
(fp = fopen(subfile(filename), "r")) == NULL) {
/* can not read data file */
logent("CAN'T READ DATA", _FAILED);
USRF(USR_LOCACC);
unlinkdf(Dfile);
lnotify(User, filename, "can't access");
goto top;
}
/* if file exists but is not generally readable... */
if (i != 0 && fstat(fileno(fp), &stbuf) == 0
&& (stbuf.st_mode & ANYREAD) == 0) {
e_access:;
/* access denied */
fclose(fp);
fp = NULL;
logent("DENIED", "ACCESS");
USRF(USR_LOCACC);
unlinkdf(W_DFILE);
lnotify(User, filename, "access denied");
goto top;
}
setline(SNDFILE);
}
if (wrktype == RCVFILE) {
strcpy(filename, W_FILE2);
expfile(filename);
if (chkpth(User, "", filename)
|| chkperm(filename, index(W_OPTNS, 'd'))) {
/* access denied */
logent("DENIED", "ACCESS");
USRF(USR_LOCACC);
lnotify(User, filename, "access denied");
goto top;
}
sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
if ((fp = fopen(subfile(Dfile), "w")) == NULL) {
/* can not create temp */
logent("CAN'T CREATE TM", _FAILED);
USRF(USR_LNOTMP);
unlinkdf(Dfile);
goto top;
}
setline(RCVFILE);
}
sendmsg:
DEBUG(4, "wrktype - %c\n", wrktype);
WMESG(wrktype, msg);
RMESG(wrktype, msg, 1);
goto process;
}
/* role is slave */
RAMESG(msg, 1);
goto process;
process:
DEBUG(4, "PROCESS: msg - %s\n", msg);
switch (msg[0]) {
case RQSTCMPT:
DEBUG(4, "RQSTCMPT:\n", CNULL);
if (msg[1] == 'N') {
i = atoi(&msg[2]);
if (i<0 || i>EM_MAX) i=0;
USRF( 1 << i );
i = 0;
logent(Em_msg[i], "REQUEST FAILED");
if (strcmp(&msg[1], EM_NOTMP) == 0) {
/* dont send him files he can't save */
WMESG(HUP, "");
RMESG(HUP, msg, 1);
goto process;
}
}
if (msg[1] == 'Y')
USRF(USR_COK);
if (role == MASTER) {
notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
}
goto top;
case HUP:
DEBUG(4, "HUP:\n", CNULL);
if (msg[1] == 'Y') {
if (role == MASTER)
WMESG(HUP, YES);
(*Turnoff)();
Rdmsg = Imsg;
Wrmsg = Omsg;
return SUCCESS;
}
if (msg[1] == 'N') {
ASSERT(role == MASTER, "WRONG ROLE - HUP", CNULL, role);
role = SLAVE;
goto top;
}
/* get work */
if (!iswrk(Wfile, "chk", Spool, wkpre)) {
WMESG(HUP, YES);
RMESG(HUP, msg, 1);
goto process;
}
WMESG(HUP, NO);
role = MASTER;
goto top;
case XUUCP:
if (role == MASTER) {
goto top;
}
/* slave part */
i = getargs(msg, wrkvec, 20);
strcpy(filename, W_FILE1);
if (index(filename, ';') != NULL || index(W_FILE2, ';') != NULL
|| i < 3) {
WMESG(XUUCP, NO);
goto top;
}
expfile(filename);
if (chkpth("", Rmtname, filename)) {
WMESG(XUUCP, NO);
logent("XUUCP DENIED", filename);
USRF(USR_XUUCP);
goto top;
}
sprintf(rqstr, "%s %s", filename, W_FILE2);
xuucp(rqstr);
WMESG(XUUCP, YES);
goto top;
case SNDFILE:
/* MASTER section of SNDFILE */
DEBUG(4, "%s\n", "SNDFILE:");
if (msg[1] == 'N') {
i = atoi(&msg[2]);
if (i < 0 || i > EM_MAX)
i = 0;
logent(Em_msg[i], "REQUEST FAILED");
USRF( 1 << i );
fclose(fp);
fp = NULL;
if (strcmp(&msg[1], EM_NOTMP) == 0) {
/* dont send him files he can't save */
WMESG(HUP, "");
RMESG(HUP, msg, 1);
goto process;
}
notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
ASSERT(role == MASTER, "WRONG ROLE - SN", CNULL, role);
if (msg[1] != '4')
unlinkdf(W_DFILE);
goto top;
}
if (msg[1] == 'Y') {
/* send file */
ASSERT(role == MASTER, "WRONG ROLE - SY", CNULL, role);
ret = fstat(fileno(fp), &stbuf);
ASSERT(ret != -1, "STAT FAILED", filename, 0);
i = 1 + (int)(stbuf.st_size / XFRRATE);
if (send_or_receive != SNDFILE) {
send_or_receive = SNDFILE;
systat(Rmtname, SS_INPROGRESS, "SENDING");
}
ret = (*Wrdata)(fp, Ofn);
fclose(fp);
fp = NULL;
if (ret != SUCCESS) {
(*Turnoff)();
USRF(USR_CFAIL);
return FAIL;
}
RMESG(RQSTCMPT, msg, i);
unlinkdf(W_DFILE);
goto process;
}
/* SLAVE section of SNDFILE */
ASSERT(role == SLAVE, "WRONG ROLE - SLAVE", CNULL, role);
/* request to receive file */
/* check permissions */
i = getargs(msg, wrkvec, 20);
if (i < 5) {
char *bnp;
bnp = rindex(Wfile, '/');
sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : Wfile);
xmv(Wfile, rqstr);
logent(Wfile, "CMD FILE CORRUPTED");
Wfile[0] = '\0';
goto top;
}
sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1, W_FILE2, W_USER);
logent(rqstr, "REQUESTED");
DEBUG(4, "msg - %s\n", msg);
strcpy(filename, W_FILE2);
/* Run uuxqt occasionally */
if (filename[0] == XQTPRE) {
if (++nXfiles > 10) {
nXfiles = 0;
/*
* want to create an orphan uuxqt,
* so a double-fork is needed.
*/
if (fork() == 0) {
xuuxqt();
_exit(0);
}
wait((int *)0);
}
}
/* expand filename, i is set to 0 if this is
* is a vanilla spool file, so no stat(II)s are needed */
i = expfile(filename);
DEBUG(4, "expfile type - %d\n", i);
if (i != 0) {
if (chkpth("", Rmtname, filename)
|| chkperm(filename, index(W_OPTNS, 'd'))) {
WMESG(SNDFILE, EM_RMTACC);
logent("DENIED", "PERMISSION");
goto top;
}
if (isdir(filename)) {
strcat(filename, "/");
strcat(filename, lastpart(W_FILE1));
}
}
sprintf(User, "%.9s", W_USER);
DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
/* speed things up by OKing file before
* creating TM file. If the TM file cannot be created,
* then the conversation bombs, but that seems reasonable,
* as there are probably serious problems then.
*/
WMESG(SNDFILE, YES);
sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);
if((fp = fopen(subfile(Dfile), "w")) == NULL) {
/* WMESG(SNDFILE, EM_NOTMP);*/
logent("CAN'T OPEN", "TM FILE");
unlinkdf(Dfile);
(*Turnoff)();
return FAIL;
}
if (send_or_receive != RCVFILE) {
send_or_receive = RCVFILE;
systat(Rmtname, SS_INPROGRESS, "RECEIVING");
}
ret = (*Rddata)(Ifn, fp);
fflush(fp);
if (ferror(fp) || fclose(fp))
ret = FAIL;
if (ret != SUCCESS) {
(void) unlinkdf(Dfile);
(*Turnoff)();
return FAIL;
}
/* copy to user directory */
ntfyopt = index(W_OPTNS, 'n') != NULL;
status = xmv(Dfile, filename);
WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
if (i == 0)
; /* vanilla file, nothing to do */
else if (status == 0) {
if (W_MODE == 0 || sscanf(W_MODE, "%o", &filemode) != 1)
filemode = BASEMODE;
chmod(subfile(filename), (filemode|BASEMODE)&0777);
arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
} else {
logent(_FAILED, "COPY");
status = putinpub(filename, Dfile, W_USER);
DEBUG(4, "->PUBDIR %d\n", status);
if (status == 0)
arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
}
goto top;
case RCVFILE:
/* MASTER section of RCVFILE */
DEBUG(4, "%s\n", "RCVFILE:");
if (msg[1] == 'N') {
i = atoi(&msg[2]);
if (i < 0 || i > EM_MAX)
i = 0;
logent(Em_msg[i], "REQUEST FAILED");
USRF( 1 << i );
fclose(fp);
fp = NULL;
if (strcmp(&msg[1], EM_NOTMP) == 0) {
/* dont send him files he can't save */
WMESG(HUP, "");
RMESG(HUP, msg, 1);
goto process;
}
notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]);
ASSERT(role == MASTER, "WRONG ROLE - RN", CNULL, role);
unlinkdf(Dfile);
goto top;
}
if (msg[1] == 'Y') {
/* receive file */
ASSERT(role == MASTER, "WRONG ROLE - RY", CNULL, role);
if (send_or_receive != RCVFILE) {
send_or_receive = RCVFILE;
systat(Rmtname, SS_INPROGRESS, "RECEIVING");
}
ret = (*Rddata)(Ifn, fp);
fflush(fp);
if (ferror(fp) || fclose(fp))
ret = FAIL;
if (ret != SUCCESS) {
unlinkdf(Dfile);
(*Turnoff)();
USRF(USR_CFAIL);
return FAIL;
}
/* copy to user directory */
if (isdir(filename)) {
strcat(filename, "/");
strcat(filename, lastpart(W_FILE1));
}
status = xmv(Dfile, filename);
WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
notify(mailopt, W_USER, filename, Rmtname,
status ? EM_LOCCP : YES);
if (status == 0) {
sscanf(&msg[2], "%o", &filemode);
if (filemode <= 0)
filemode = BASEMODE;
chmod(subfile(filename), (filemode|BASEMODE)&0777);
USRF(USR_COK);
}
else {
logent(_FAILED, "COPY");
putinpub(filename, Dfile, W_USER);
USRF(USR_LOCCP);
}
goto top;
}
/* SLAVE section of RCVFILE */
ASSERT(role == SLAVE, "WRONG ROLE - SLAVE RCV", CNULL, role);
/* request to send file */
strcpy(rqstr, msg);
logent(rqstr, "REQUESTED");
/* check permissions */
i = getargs(msg, wrkvec, 20);
if (i < 4) {
char *bnp;
bnp = rindex(Wfile, '/');
sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : Wfile);
xmv(Wfile, rqstr);
logent(Wfile, "CMD FILE CORRUPTED");
Wfile[0] = '\0';
goto top;
}
DEBUG(4, "msg - %s\n", msg);
DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
strcpy(filename, W_FILE1);
expfile(filename);
if (isdir(filename)) {
strcat(filename, "/");
strcat(filename, lastpart(W_FILE2));
}
sprintf(User, "%.9s", W_USER);
if (chkpth("", Rmtname, filename) || anyread(filename)) {
WMESG(RCVFILE, EM_RMTACC);
logent("DENIED", "PERMISSION");
goto top;
}
DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
if ((fp = fopen(subfile(filename), "r")) == NULL) {
WMESG(RCVFILE, EM_RMTACC);
logent("CAN'T OPEN", "DENIED");
goto top;
}
/* ok to send file */
ret = fstat(fileno(fp), &stbuf);
ASSERT(ret != -1, "STAT FAILED", filename, 0);
i = 1 + (int)(stbuf.st_size / XFRRATE);
sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);
WMESG(RCVFILE, msg);
if (send_or_receive != SNDFILE) {
send_or_receive = SNDFILE;
systat(Rmtname, SS_INPROGRESS, "SENDING");
}
ret = (*Wrdata)(fp, Ofn);
fclose(fp);
if (ret != SUCCESS) {
(*Turnoff)();
return FAIL;
}
RMESG(RQSTCMPT, msg, i);
goto process;
}
(*Turnoff)();
return FAIL;
}
/***
* rmesg(c, msg, n) read message 'c'
* try 'n' times
* char *msg, c;
*
* return code: 0 | FAIL
*/
rmesg(c, msg, n)
register char *msg, c;
register int n;
{
char str[128];
DEBUG(4, "rmesg - '%c' ", c);
while ((*Rdmsg)(msg, Ifn) != SUCCESS) {
if (--n > 0) {
sprintf(str, "%d", n);
logent(str, "PATIENCE");
continue;
}
DEBUG(4, "got FAIL\n", CNULL);
if (c != '\0')
sprintf(str, "expected '%c' got FAIL (%d)", c, errno);
else
sprintf(str, "expected ANY got FAIL (%d)", errno);
logent(str, "BAD READ");
return FAIL;
}
if (c != '\0' && msg[0] != c) {
DEBUG(4, "got %s\n", msg);
sprintf(str, "expected '%c' got %s", c, msg);
logent(str, "BAD READ");
return FAIL;
}
DEBUG(4, "got %s\n", msg);
return SUCCESS;
}
/***
* wmesg(m, s) write a message (type m)
* char *s, m;
*
* return codes: 0 - ok | FAIL - ng
*/
wmesg(m, s)
register char *s, m;
{
DEBUG(4, "wmesg '%c' ", m);
DEBUG(4, "%s\n", s);
return (*Wrmsg)(m, s, Ofn);
}
/***
* notify mail results of command
*
* return codes: none
*/
notify(mailopt, user, file, sys, msgcode)
char *user, *file, *sys, *msgcode;
{
char str[200];
int i;
char *msg;
if (!mailopt && *msgcode == 'Y')
return;
if (*msgcode == 'Y')
msg = "copy succeeded";
else {
i = atoi(msgcode + 1);
if (i < 1 || i > EM_MAX)
i = 0;
msg = Em_msg[i];
}
sprintf(str, "file %s!%s -- %s\n",
sys,file, msg);
mailst(user, str, CNULL);
return;
}
/***
* lnotify(user, file, mesg) - local notify
*
* return code - none
*/
lnotify(user, file, mesg)
char *user, *file, *mesg;
{
char mbuf[200];
sprintf(mbuf, "file %s!%s -- %s\n", Myname, file, mesg);
mailst(user, mbuf, CNULL);
return;
}
/***
* startup(role)
* int role;
*
* startup - this routine will converse with the remote
* machine, agree upon a protocol (if possible) and start the
* protocol.
*
* return codes:
* SUCCESS - successful protocol selection
* FAIL - can't find common or open failed
*/
startup(role)
int role;
{
extern (*Rdmsg)(), (*Wrmsg)();
extern char *blptcl(), fptcl();
char msg[BUFSIZ], str[MAXFULLNAME];
Rdmsg = Imsg;
Wrmsg = Omsg;
if (role == MASTER) {
RMESG(SLTPTCL, msg, 1);
if ((str[0] = fptcl(&msg[1])) == NULL) {
/* no protocol match */
WMESG(USEPTCL, NO);
return FAIL;
}
str[1] = '\0';
WMESG(USEPTCL, str);
if (stptcl(str) != 0)
return FAIL;
DEBUG(4, "protocol %s\n", str);
return SUCCESS;
}
else {
WMESG(SLTPTCL, blptcl(str));
RMESG(USEPTCL, msg, 1);
if (msg[1] == 'N') {
return FAIL;
}
if (stptcl(&msg[1]) != 0)
return FAIL;
DEBUG(4, "Protocol %s\n", msg);
return SUCCESS;
}
}
/*******
* char
* fptcl(str)
* char *str;
*
* fptcl - this routine will choose a protocol from
* the input string (str) and return the found letter.
*
* return codes:
* '\0' - no acceptable protocol
* any character - the chosen protocol
*/
char
fptcl(str)
register char *str;
{
register struct Proto *p;
extern char *Flds[];
for (p = Ptbl; p->P_id != '\0'; p++) {
#ifdef BSDTCP
if (!IsTcpIp && p->P_id == 't') /* Only use 't' on TCP/IP */
continue;
#endif BSDTCP
/* only use 'f' protocol on PAD */
if (strcmp("PAD", Flds[F_LINE]) && p->P_id == 'f')
continue;
if (index(str, p->P_id) != NULL) {
return p->P_id;
}
}
return '\0';
}
/***
* char *
* blptcl(str)
* char *str;
*
* blptcl - this will build a string of the
* letters of the available protocols and return
* the string (str).
*
* return:
* a pointer to string (str)
*/
char *
blptcl(str)
register char *str;
{
register struct Proto *p;
register char *s;
for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++)
;
*s = '\0';
return str;
}
/***
* stptcl(c)
* char *c;
*
* stptcl - this routine will set up the six routines
* (Rdmsg, Wrmsg, Rddata, Wrdata, Turnon, Turnoff) for the
* desired protocol.
*
* return codes:
* SUCCESS - ok
* FAIL - no find or failed to open
*
*/
stptcl(c)
register char *c;
{
register struct Proto *p;
for (p = Ptbl; p->P_id != '\0'; p++) {
if (*c == p->P_id) {
/* found protocol - set routines */
Rdmsg = p->P_rdmsg;
Wrmsg = p->P_wrmsg;
Rddata = p->P_rddata;
Wrdata = p->P_wrdata;
Turnon = p->P_turnon;
Turnoff = p->P_turnoff;
if ((*Turnon)() != SUCCESS)
return FAIL;
DEBUG(4, "Proto started %c\n", *c);
return SUCCESS;
}
}
DEBUG(4, "Proto start-fail %c\n", *c);
return FAIL;
}
/***
* putinpub put file in public place
* if successful, filename is modified
*
* return code 0 | FAIL
*/
putinpub(file, tmp, user)
register char *file, *user, *tmp;
{
char fullname[MAXFULLNAME];
char *lastpart();
int status;
sprintf(fullname, "%s/%s/", PUBDIR, user);
if (mkdirs(fullname) != 0) {
/* can not make directories */
return FAIL;
}
strcat(fullname, lastpart(file));
status = xmv(tmp, fullname);
if (status == 0) {
strcpy(file, fullname);
chmod(subfile(fullname), BASEMODE);
}
return status;
}
/***
* unlinkdf(file) - unlink D. file
*
* return code - none
*/
unlinkdf(file)
register char *file;
{
if (strlen(file) > 6)
unlink(subfile(file));
return;
}
/***
* arrived - notify receiver of arrived file
*
* return code - none
*/
arrived(opt, file, nuser, rmtsys, rmtuser)
char *file, *nuser, *rmtsys, *rmtuser;
{
char mbuf[200];
if (!opt)
return;
sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser);
mailst(nuser, mbuf, CNULL);
return;
}