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

994 lines
21 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "$Revision: 1.9 $"
#include "uucp.h"
#ifdef sgi
#include <paths.h>
#endif
struct Proto {
char P_id;
int (*P_turnon)(void);
int (*P_rdmsg)(char *, int);
int (*P_wrmsg)(char, char *, int);
int (*P_rddata)(int, FILE *);
int (*P_wrdata)(FILE *, int);
int (*P_turnoff)(void);
};
struct Proto Ptbl[]={
'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,
#if defined (TCP) || defined (UNET) || defined (TLI)
'e', eturnon, erdmsg, ewrmsg, erddata, ewrdata, eturnoff,
#endif /* TCP || UNET || TLI */
#ifdef sgi
't', tturnon, trdmsg, twrmsg, trddata, twrdata, tturnoff,
#endif
#ifdef DATAKIT
'd', dturnon, drdmsg, dwrmsg, drddata, dwrdata, dturnoff,
#endif /* DATAKIT */
#ifdef X25
'x', xturnon, xrdmsg, xwrmsg, xrddata, xwrdata, xturnoff,
#endif /* X25 */
'\0'
};
int (*Rdmsg)(char *, int)=imsg, (*Rddata)(int, FILE *);
int (*Wrmsg)(char, char *, int)=omsg, (*Wrdata)(FILE *, int);
int (*Turnon)(void), (*Turnoff)(void);
#define YES "Y"
#define NO "N"
/*
* failure messages
*/
#define EM_MAX 7
#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 - file left in PUBDIR/user/file",
"forwarding error"
};
#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_MAX 10 /* maximum number of C. files per line */
#define W_MIN 7 /* min number of entries */
#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 W_SFILE wrkvec[8]
#define W_RFILE wrkvec[5]
#define W_XFILE wrkvec[5]
char *mf;
#define RMESG(m, s) if (rmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);}
#define RAMESG(s) if (rmesg('\0', s) != 0) {(*Turnoff)(); return(FAIL);}
#define WMESG(m, s) if(wmesg(m, s) != 0) {(*Turnoff)(); return(FAIL);}
char Wfile[MAXFULLNAME] = {'\0'};
char Dfile[MAXFULLNAME];
static int rmesg(char, char *);
static int wmesg(char, char *);
static void stmesg(char *, char *);
static int nospace(char *);
static void unlinkdf(char *);
static void notify(int, char *, char *, char *, char *);
static void lnotify(char *, char *, char *);
static char *blptcl(char *);
static char fptcl(char *);
static void arrived(int, char *, char *, char *, char *);
static int stptcl(char *);
static int putinpub(char *, char *, char *);
/*
* execute the conversation between the two machines
* after both programs are running.
* returns:
* SUCCESS -> ok
* FAIL -> failed
*/
char *wrkvec[W_MAX+1];
int statfopt;
cntrl(role)
register int role;
{
FILE * fp;
struct stat stbuf;
int filemode;
int status = 1;
int i, narg;
int mailopt, ntfyopt;
int ret;
char rqstr[BUFSIZ]; /* contains the current request message */
char msg[BUFSIZ];
char filename[MAXFULLNAME], wrktype;
static int pnum;
pnum = getpid();
Wfile[0] = '\0';
top:
#ifdef sgi
/*
* shut down if /etc/nologin exists.
*/
if (!access(_PATH_NOLOGIN, F_OK)) {
(void)sprintf(msg, "%s exists",_PATH_NOLOGIN);
logent(msg, "FAILED");
DEBUG(1, "*** stopping *** - %s exists,", _PATH_NOLOGIN);
(*Turnoff)();
return(FAIL);
}
#endif /* sgi */
(void) strcpy(User, Uucp);
statfopt = 0;
*Jobid = '\0';
DEBUG(4, "*** TOP *** - role=%d, ", role);
setline(RESET);
if (role == MASTER) {
/*
* get work
*/
if ((narg = gtwvec(Wfile, wrkvec, W_MAX)) == 0) {
WMESG(HUP, "");
RMESG(HUP, msg);
goto process;
}
DEBUG(7, "Wfile - %s,", Wfile);
strncpy(Jobid, BASENAME(Wfile, '/')+2, NAMESIZE);
Jobid[NAMESIZE-1] = '\0';
DEBUG(7, "Jobid = %s\n", Jobid);
wrktype = W_TYPE[0];
mailopt = strchr(W_OPTNS, 'm') != NULL;
statfopt = strchr(W_OPTNS, 'o') != NULL;
ntfyopt = strchr(W_OPTNS, 'n') != NULL;
msg[0] = '\0';
for (i = 1; i < narg; i++) {
(void) strcat(msg, " ");
(void) strcat(msg, wrkvec[i]);
}
/*
* We used to check for corrupt workfiles here (narg < 5),
* but we were doing it wrong, and besides, anlwrk.c is the
* appropriate place to do it.
*/
(void) sprintf(User, "%s", W_USER);
if (wrktype == SNDFILE ) {
(void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Myname,
W_FILE1, Rmtname, W_FILE2, User);
logent(rqstr, "REQUEST");
CDEBUG(1, "Request: %s\n", rqstr);
mf = W_SFILE;
(void) strcpy(filename, W_FILE1);
expfile(filename);
if ( !READSOME(filename) && !READSOME(W_DFILE)) {
/*
* access denied
*/
logent("DENIED", "ACCESS");
unlinkdf(W_DFILE);
lnotify(User, rqstr, "access denied");
CDEBUG0(1, "Failed: Access Denied\n");
goto top;
}
(void) strcpy(Dfile, W_DFILE);
fp = NULL;
fp = fopen(Dfile, "r");
if (fp == NULL &&
(fp = fopen(filename, "r")) == NULL) {
/* can not read data file */
unlinkdf(Dfile);
lnotify(User, rqstr, "can't access");
(void) sprintf(msg, "CAN'T READ %s %d",
filename, errno);
logent(msg, "FAILED");
CDEBUG(1, "Failed: Can't Read %s\n", filename);
goto top;
}
Seqn++;
setline(SNDFILE);
}
if (wrktype == RCVFILE) {
(void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Rmtname,
W_FILE1, Myname, W_FILE2, User);
logent(rqstr, "REQUEST");
CDEBUG(1, "Request: %s\n", rqstr);
mf = W_RFILE;
(void) strcpy(filename, W_FILE2);
expfile(filename);
if (chkperm(W_FILE1, filename, strchr(W_OPTNS, 'd'))) {
/* access denied */
logent("DENIED", "ACCESS");
lnotify(User, rqstr, "access denied");
CDEBUG(1, "Failed: Access Denied--File: %s\n",
filename);
goto top;
}
TMname(Dfile, pnum); /* get TM file name */
if ( ((fp = fopen(Dfile, "w")) == NULL)
|| nospace(Dfile)) {
/* can not create temp */
logent("CAN'T CREATE TM", "FAILED");
CDEBUG0(1, "Failed: No Space!\n");
unlinkdf(Dfile);
assert(Ct_CREATE, Dfile, nospace(Dfile),
__FILE__, __LINE__);
cleanup(FAIL);
}
Seqn++;
chmod(Dfile, DFILEMODE); /* no peeking! */
setline(RCVFILE);
}
DEBUG(4, "wrktype - %c\n ", wrktype);
WMESG(wrktype, msg);
RMESG(wrktype, msg);
goto process;
}
/*
* role is slave
*/
RAMESG(msg);
process:
/*
* touch all lock files
*/
ultouch();
DEBUG(4, " PROCESS: msg - %s\n", msg);
switch (msg[0]) {
case RQSTCMPT:
DEBUG(4, "%s\n", "RQSTCMPT:");
if (msg[1] == 'N') {
i = atoi(&msg[2]);
if (i < 0 || i > EM_MAX)
i = 0;
logent(Em_msg[i], "REQUESTED");
}
if (role == MASTER) {
notify(mailopt, W_USER, rqstr, Rmtname, &msg[1]);
}
goto top;
case HUP:
DEBUG(4, "%s\n", "HUP:");
if (msg[1] == 'Y') {
WMESG(HUP, YES);
(*Turnoff)();
Rdmsg = imsg;
Wrmsg = omsg;
return(0);
}
if (msg[1] == 'N') {
ASSERT(role == MASTER, Wr_ROLE, "", role);
role = SLAVE;
goto top;
}
/*
* get work
*/
if ( (switchRole() == FALSE) || !iswrk(Wfile) ) {
DEBUG(5, "SLAVE-switchRole (%s)\n",
switchRole() ? "TRUE" : "FALSE");
WMESG(HUP, YES);
RMESG(HUP, msg);
goto process;
}
/* Note that Wfile is the first C. to process at top
* set above by iswrk() call
*/
WMESG(HUP, NO);
role = MASTER;
goto top;
case XUUCP:
/*
* slave part
* No longer accepted
*/
WMESG(XUUCP, NO);
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");
notify(mailopt, W_USER, rqstr, Rmtname, &msg[1]);
ASSERT(role == MASTER, Wr_ROLE, "", role);
(void) fclose(fp);
ASSERT(i != 4, Em_msg[4], Rmtname, i); /* EM_NOTMP */
unlinkdf(W_DFILE);
goto top;
}
if (msg[1] == 'Y') {
/*
* send file
*/
ASSERT(role == MASTER, Wr_ROLE, "", role);
if (fstat(fileno(fp), &stbuf)) /* never fail but .. */
stbuf.st_size = 0; /* for time loop calculation */
ret = (*Wrdata)(fp, Ofn);
(void) fclose(fp);
if (ret != 0) {
(*Turnoff)();
return(FAIL);
}
/* loop depending on the size of the file */
/* give an extra try for each megabyte */
for (i = stbuf.st_size >> 10; i >= 0; --i) {
if ((ret = rmesg(RQSTCMPT, msg)) == 0)
break; /* got message */
}
if (ret != 0) {
(*Turnoff)();
return(FAIL);
}
unlinkdf(W_DFILE);
goto process;
}
/*
* SLAVE section of SNDFILE
*/
ASSERT(role == SLAVE, Wr_ROLE, "", role);
/*
* request to receive file
* check permissions
*/
i = getargs(msg, wrkvec, W_MAX);
/* Check for bad request */
if (i < W_MIN) {
WMESG(SNDFILE, EM_BADUUCP);
logent("DENIED", "TOO FEW ARGS IN SLAVE SNDFILE");
goto top;
}
mf = W_SFILE;
(void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Rmtname,
W_FILE1, Myname, W_FILE2, W_USER);
logent(rqstr, "REMOTE REQUESTED");
DEBUG(4, "msg - %s\n", msg);
CDEBUG(1, "Remote Requested: %s\n", rqstr);
(void) strcpy(filename, W_FILE2);
expfile(filename);
DEBUG(4, "SLAVE - filename: %s\n", filename);
if (chkpth(filename, CK_WRITE)
|| chkperm(W_FILE1, filename, strchr(W_OPTNS, 'd'))) {
WMESG(SNDFILE, EM_RMTACC);
logent("DENIED", "PERMISSION");
CDEBUG0(1, "Failed: Access Denied\n");
goto top;
}
(void) sprintf(User, "%s", W_USER);
DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);
TMname(Dfile, pnum); /* get TM file name */
if ( ((fp = fopen(Dfile, "w")) == NULL) || nospace(Dfile) ) {
WMESG(SNDFILE, EM_NOTMP);
logent("CAN'T OPEN", "DENIED");
CDEBUG0(1, "Failed: Can't Create Temp File\n");
unlinkdf(Dfile);
goto top;
}
Seqn++;
chmod(Dfile, DFILEMODE); /* no peeking! */
WMESG(SNDFILE, YES);
ret = (*Rddata)(Ifn, fp);
(void) fclose(fp);
if ( ret == EFBIG ) {
WMESG(RQSTCMPT, EM_NOTMP);
logent("FILE EXCEEDS ULIMIT","FAILED");
CDEBUG0(1, "Failed: file size exceeds ulimit");
goto top;
}
if (ret != 0) {
(*Turnoff)();
logent("INPUT FAILURE", "IN SEND/SLAVE MODE");
return(FAIL);
}
/* copy to user directory */
ntfyopt = strchr(W_OPTNS, 'n') != NULL;
status = xmv(Dfile, filename);
WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
if (status == 0) {
sscanf(W_MODE, "%o", &filemode);
if (filemode <= 0)
filemode = 0666;
if (PREFIX(RemSpool, filename))
chmod(filename, 0600);
else
chmod(filename, filemode | 0666);
arrived(ntfyopt, filename, W_NUSER, Rmtname, User);
} else {
logent("FAILED", "COPY");
status = putinpub(filename, Dfile,
BASENAME(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 RCVFULE
*/
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");
notify(mailopt, W_USER, rqstr, Rmtname, &msg[1]);
ASSERT(role == MASTER, Wr_ROLE, "", role);
(void) fclose(fp);
unlinkdf(Dfile);
goto top;
}
if (msg[1] == 'Y') {
/*
* receive file
*/
ASSERT(role == MASTER, Wr_ROLE, "", role);
ret = (*Rddata)(Ifn, fp);
(void) fclose(fp);
if (ret != 0) {
(*Turnoff)();
return(FAIL);
}
status = xmv(Dfile, filename);
WMESG(RQSTCMPT, status ? EM_RMTCP : YES);
notify(mailopt, W_USER, rqstr, Rmtname,
status ? EM_LOCCP : YES);
if (status == 0) {
sscanf(&msg[2], "%o", &filemode);
if (filemode <= 0)
filemode = 0666;
if (PREFIX(RemSpool, filename))
chmod(filename, 0600);
else
chmod(filename, filemode | 0666);
} else {
logent("FAILED", "COPY");
putinpub(filename, Dfile, W_USER);
}
goto top;
}
/*
* SLAVE section of RCVFILE
* (request to send file)
*/
ASSERT(role == SLAVE, Wr_ROLE, "", role);
/* check permissions */
i = getargs(msg, wrkvec, W_MAX);
/* Check for bad request */
if (i < 5) {
WMESG(RCVFILE, EM_BADUUCP);
logent("DENIED", "TOO FEW ARGS IN SLAVE RCVFILE");
goto top;
}
(void) sprintf(rqstr, "%s!%s --> %s!%s (%s)", Myname,
W_FILE1, Rmtname, W_FILE2, W_USER);
logent(rqstr, "REMOTE REQUESTED");
CDEBUG(1, "Remote Requested: %s\n", rqstr);
mf = W_RFILE;
DEBUG(4, "msg - %s\n", msg);
DEBUG(4, "W_FILE1 - %s\n", W_FILE1);
(void) strcpy(filename, W_FILE1);
expfile(filename);
if (DIRECTORY(filename)) {
(void) strcat(filename, "/");
(void) strcat(filename, BASENAME(W_FILE2, '/'));
}
(void) sprintf(User, "%s", W_USER);
if (requestOK() == FALSE) {
WMESG(RCVFILE, EM_RMTACC);
logent("DENIED", "REQUESTING");
CDEBUG0(1, "Failed: Access Denied\n");
goto top;
}
DEBUG(4, "requestOK for Loginuser - %s\n", Loginuser);
if (chkpth(filename, CK_READ) || !READANY(filename)) {
WMESG(RCVFILE, EM_RMTACC);
logent("DENIED", "PERMISSION");
CDEBUG0(1, "Failed: Access Denied\n");
goto top;
}
DEBUG(4, "chkpth ok Loginuser - %s\n", Loginuser);
if ((fp = fopen(filename, "r")) == NULL) {
WMESG(RCVFILE, EM_RMTACC);
logent("CAN'T OPEN", "DENIED");
CDEBUG(1, "Failed: Can't Open %s\n", filename);
goto top;
}
/*
* ok to send file
*/
ASSERT(fstat(fileno(fp), &stbuf) == 0, Ct_STAT,
filename, errno);
(void) sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);
WMESG(RCVFILE, msg);
Seqn++;
ret = (*Wrdata)(fp, Ofn);
(void) fclose(fp);
if (ret != 0) {
(*Turnoff)();
return(FAIL);
}
/* loop depending on the size of the file */
/* give an extra try for each megabyte */
/* stbuf set in fstat several lines back */
for (i = stbuf.st_size >> 10; i >= 0; --i) {
if ((ret = rmesg(RQSTCMPT, msg)) == 0)
break; /* got message */
}
if (ret != 0) {
(*Turnoff)();
return(FAIL);
}
goto process;
}
(*Turnoff)();
return(FAIL);
}
/*
* read message
* returns:
* 0 -> success
* FAIL -> failure
*/
static int
rmesg(char c, char *msg)
{
char str[50];
DEBUG(4, "rmesg - '%c' ", c);
if ((*Rdmsg)(msg, Ifn) != 0) {
DEBUG(4, "got %s\n", "FAIL");
(void) sprintf(str, "expected '%c' got FAIL", c);
logent(str, "BAD READ");
return(FAIL);
}
if (c != '\0' && msg[0] != c) {
DEBUG(4, "got %s\n", msg);
(void) sprintf(str, "expected '%c' got %s", c, msg);
logent(str, "BAD READ");
return(FAIL);
}
DEBUG(4, "got %s\n", msg);
return(0);
}
/*
* write a message
* returns:
* 0 -> ok
* FAIL -> ng
*/
static int
wmesg(char m, char *s)
{
CDEBUG(4, "wmesg '%c'", m);
CDEBUG(4, "%s\n", s);
return((*Wrmsg)(m, s, Ofn));
}
/*
* mail results of command
* return:
* none
*/
static void
notify(mailopt, user, msgin, sys, msgcode)
char *user, *msgin, *sys;
register char *msgcode;
{
register int i;
char str[BUFSIZ];
register char *msg;
DEBUG(4,"mailopt %d, ", mailopt);
DEBUG(4,"statfopt %d\n", statfopt);
if (statfopt == 0 && mailopt == 0 && *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];
}
if(statfopt){
stmesg(msgin, msg);
return;
}
(void) sprintf(str, "REQUEST: %s\n(SYSTEM: %s) %s\n",
msgin, sys, msg);
mailst(user, str, "", "");
}
/*
* local notify
* return:
* none
*/
static void
lnotify(user, msgin, mesg)
char *user, *msgin, *mesg;
{
char mbuf[BUFSIZ];
if(statfopt){
stmesg(msgin, mesg);
return;
}
(void) sprintf(mbuf, "REQUEST: %s\n(SYSTEM: %s) %s\n",
msgin, Myname, mesg);
mailst(user, mbuf, "", "");
}
static void
stmesg(f, m)
char *f, *m;
{
FILE *Cf;
time_t clock;
long td, th, tm, ts;
DEBUG(4,"STMES %s\n",mf);
if((Cf = fopen(mf, "a+")) == NULL){
chmod(mf, 0666);
return;
}
(void) time(&clock);
(void) fprintf(Cf, "uucp job: %s (%s) ", Jobid, timeStamp());
td = clock - Nstat.t_qtime;
ts = td%60;
td /= 60;
tm = td%60;
td /= 60;
th = td;
(void) fprintf(Cf, "(%ld:%ld:%ld)\n%s\n%s\n\n", th, tm, ts, f, m);
(void) fclose(Cf);
chmod(mf, 0666);
}
/*
* converse with the remote machine, agree upon a
* protocol (if possible) and start the protocol.
* return:
* SUCCESS -> successful protocol selection
* FAIL -> can't find common or open failed
*/
startup(role)
register int role;
{
char msg[BUFSIZ], str[BUFSIZ];
Rdmsg = imsg;
Wrmsg = omsg;
if (role == MASTER) {
RMESG(SLTPTCL, msg);
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);
return(SUCCESS);
} else {
WMESG(SLTPTCL, blptcl(str));
RMESG(USEPTCL, msg);
if (msg[1] == 'N') {
return(FAIL);
}
if (stptcl(&msg[1]) != 0)
return(FAIL);
return(SUCCESS);
}
}
/*
* choose a protocol from the input string (str)
* and return the found letter.
* Use the MASTER string for order of selection.
* return:
* '\0' -> no acceptable protocol
* any character -> the chosen protocol
*/
static char
fptcl(str)
register char *str;
{
char *l, list[20]; /* assume less than 20 protocols */
blptcl(list);
for (l = list; *l != '\0'; l++) {
if ( strchr(str, *l) != NULL) {
return(*l);
}
}
return('\0');
}
/*
* build a string of the letters of the available
* protocols and return the string (str).
* return:
* a pointer to string (str)
*/
static char *
blptcl(str)
register char *str;
{
register struct Proto *p;
char *s;
if (protoString() != NULL)
(void) strcpy(str, protoString());
else
for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++);
return(str);
}
/*
* set up the six routines (Rdmg. Wrmsg, Rddata
* Wrdata, Turnon, Turnoff) for the desired protocol.
* returns:
* SUCCESS -> ok
* FAIL -> no find or failed to open
*/
static int
stptcl(register char *c)
{
register struct Proto *p;
for (p = Ptbl; p->P_id != '\0'; p++) {
if (*c == p->P_id) {
/*
* found protocol
* set routine
*/
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)() != 0)
break;
CDEBUG(4, "Proto started %c\n", *c);
return(SUCCESS);
}
}
CDEBUG(4, "Proto start-fail %c\n", *c);
return(FAIL);
}
/*
* put file in public place
* if successful, filename is modified
* returns:
* 0 -> success
* FAIL -> failure
*/
static int
putinpub(file, tmp, user)
char *file, *user, *tmp;
{
int status;
char fullname[MAXFULLNAME];
(void) sprintf(fullname, "%s/%s/", Pubdir, user);
if (mkdirs(fullname) != 0) {
/*
* can not make directories
*/
return(FAIL);
}
(void) strcat(fullname, BASENAME(file, '/'));
status = xmv(tmp, fullname);
if (status == 0) {
(void) strcpy(file, fullname);
(void) chmod(fullname,0666);
}
return(status);
}
/*
* unlink D. file
* returns:
* none
*/
static void
unlinkdf(file)
register char *file;
{
if (strlen(file) > 6)
(void) unlink(file);
}
/*
* notify receiver of arrived file
* returns:
* none
*/
static void
arrived(opt, file, nuser, rmtsys, rmtuser)
char *file, *nuser, *rmtsys, *rmtuser;
{
char mbuf[200];
if (!opt)
return;
(void) sprintf(mbuf, "%s from %s!%s arrived\n", file, rmtsys, rmtuser);
mailst(nuser, mbuf, "", "");
}
/*
* Check to see if there is space for file
*/
#define FREESPACE 50 /* Minimum freespace in blocks to permit transfer */
#define FREENODES 5 /* Minimum number of inodes to permit transfer */
/*ARGSUSED*/
static
nospace(name)
char *name;
#ifdef NOUSTAT
{return(FALSE);}
#else
{
struct stat statb;
struct ustat ustatb;
if( stat(name, &statb) < 0 )
return(TRUE);
#ifdef RT
if( (statb.st_mode|S_IFMT) == S_IFREG ||
(statb.st_mode|S_IFMT) == S_IFEXT ||
(statb.st_mode&S_IFMT) == S_IF1EXT )
#else
if( (statb.st_mode&S_IFMT) == S_IFREG )
#endif
{
if( ustat(statb.st_dev, &ustatb)<0 )
return(TRUE);
if( ustatb.f_tfree < FREESPACE ) {
logent("FREESPACE IS LOW","REMOTE TRANSFER DENIED - ");
return(TRUE);
}
if( ustatb.f_tinode < FREENODES ) {
logent("TOO FEW INODES","REMOTE TRANSFER DENIED - ");
return(TRUE);
}
}
return(FALSE);
}
#endif
#ifdef V7USTAT
ustat(dev, ustat)
int dev;
struct ustat *ustat;
{
FILE *dfp, *popen();
struct fstab *fstab = NULL;
char *fval, buf[BUFSIZ];
sprintf(buf, "%s %d %d 2>&1", V7USTAT, major(dev), minor(dev));
if ((dfp = popen(buf, "r")) == NULL)
return(-1);
fval = fgets(buf, sizeof(buf), dfp);
if (pclose(dfp) != 0
|| fval == NULL
|| sscanf(buf, "%d %d", &ustat->f_tfree, &ustat->f_tinode) != 2)
return(-1);
return(0);
}
#endif /* V7USTAT */