📄 cntrl.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)cntrl.c 4.1 (decvax!larry) 7/2/90";#endif/******* * cntrl(role, wkpre) * int role; * char *wkpre; * * cntrl - this routine will execute the conversation * between the two machines after both programs are * running. * * return codes * SUCCESS - ok * FAIL - failed * * * * decvax!larry - only exit when there is an administrative * problem e.g USERFILE corrupted. If problem * with conversation to current remote site then * return(FAIL) and have cico find another site * to talk to. * * - reject incoming C.files (security risk) * * - if NOINPUT exist then dont allow any files * to be transferred to the local site. Useful * for clearing out huge backlogs. * * - mods. for new spooling structure. *//************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/#include "uucp.h"#include <sys/types.h>#include <sys/stat.h>#include "uust.h"struct Proto { char P_id; int (*P_turnon)(); int (*P_rdmsg)(); int (*P_wrmsg)(); int (*P_rddata)(); int (*P_wrdata)(); int (*P_turnoff)();};char Prefproto;extern int gturnon(), gturnoff();extern int grdmsg(), grddata();extern int gwrmsg(), gwrdata();extern int fturnon(), fturnoff();extern int frdmsg(), frddata();extern int fwrmsg(), fwrdata();extern int imsg(), omsg();struct Proto Ptbl[]={ 'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff, 'f', fturnon, frdmsg, fwrmsg, frddata, fwrdata, fturnoff, '\0'};int (*Imsg)() = imsg, (*Omsg)() = omsg; /* avoid SEL compiler limitation */int (*Rdmsg)()=imsg, (*Rddata)();int (*Wrmsg)()=omsg, (*Wrdata)();int (*Turnon)(), (*Turnoff)();#define YES "Y"#define 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 - 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 350000L#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#define NOINPUT "/usr/var/uucp/NOINPUT"char Wfile[MAXFULLNAME] = {'\0'};char Dfile[MAXFULLNAME];static int nXfiles; /* Number of X. files that have arrived */cntrl(role, wkpre)int role;char *wkpre;{ char msg[BUFSIZ], rqstr[BUFSIZ]; register FILE *fp; int filemode; struct stat stbuf; 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; pnum = getpid();/* * ima.247, John Levine, IECC, PO Box 349, Cambridge MA 02238; (617) 491-5450 * zap Wfile to prevent reuse of wrong C. file */ Wfile[0] = '\0';top: for (i = 0; i < sizeof wrkvec / sizeof wrkvec[0]; i++) wrkvec[i] = 0; DEBUG(4, "*** TOP *** - role=%d, ", role); setline(RESET); if (role == MASTER) { /* get work */ if ((narg = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) { WMESG(HUP, ""); RMESG(HUP, msg, 1); goto process; } wrktype = W_TYPE[0]; mailopt = index(W_OPTNS, 'm') != NULL; ntfyopt = index(W_OPTNS, 'n') != NULL; 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; } if ((narg < 5) || (narg > 10)) { ASSERT_NOFAIL(narg > 4, "ARG COUNT<5", Wfile, narg); ASSERT_NOFAIL(narg < 11, "ARG COUNT>10", Wfile, narg); sprintf(filename,"%s/BADCFILES/",SPOOL); mkdirs(filename); strcat(filename,lastpart(Wfile)); /* move bad file to SPOOL/BADCFILES */ link(subfile(Wfile), filename); unlink(subfile(Wfile)); logent(filename, "BAD CFILE"); anlwrk("",wrkvec); /* close file pointer */ 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 'c' option is present then data is spooled in a D.file */ if (index(W_OPTNS, 'c') == NULL) { if((fp = fopen(subfile(Dfile), "r"))==NULL) { logent("CAN'T READ SPOOLED DATA", "FAILED"); USRF(USR_LOCACC); unlinkdf(Dfile); goto top; } i = 0; } if (fp == NULL && (fp = fopen(subfile(filename), "r")) == NULL) { /* can not read non-spooled 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./TM.%05d.%03d", SPOOL, pnum, tmpnum++); if ((fp = fopen(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:/* rti!trt: ultouch is now done in gio.c (yes, kludge) * 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; USRF( 1 << i ); logent(msg, "REQUESTED"); } 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, "%s\n", "HUP:"); if (msg[1] == 'Y') { WMESG(HUP, YES); (*Turnoff)(); Rdmsg = Imsg; Wrmsg = Omsg; return(0); } if (msg[1] == 'N') { ASSERT2(role == MASTER, "WRONG ROLE", "", 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); 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"); USRF( 1 << i ); notify(mailopt, W_USER, W_FILE1, Rmtname, &msg[1]); fclose(fp); fp = NULL; /* the 4 is for EM_NOTMP - no temp space at remote */ if (msg[1] != '4') unlinkdf(W_DFILE); ASSERT2(role == MASTER, "WRONG ROLE", "",role); /* * if remote system cannot create temp files then it makes no * sense to continue. Note this fact in ERRLOG and update CNT * field in STST. file so that this does not continue forever. */ if (i == 4) { systat(Rmtname, SS_FAIL, "NO SPACE"); ASSERT2(i != 4,Em_msg[i],Rmtname,role); } goto top; } if (msg[1] == 'Y') { /* send file */ ASSERT2(role == MASTER, "WRONG ROLE", "",role); ret = fstat(fileno(fp), &stbuf); ASSERT_NOFAIL(ret != -1, "STAT FAILED", filename, 0); if (ret == -1) { fclose(fp); fp = NULL; goto top; } i = 1 + (int)(stbuf.st_size / XFRRATE); ret = (*Wrdata)(fp, Ofn); fclose(fp); fp = NULL; if (ret != 0) { (*Turnoff)(); USRF(USR_CFAIL); return(FAIL); } RMESG(RQSTCMPT, msg, i);/* put the unlink *after* the RMESG -- fortune!Dave-Yost */ unlinkdf(W_DFILE); goto process; } /* SLAVE section of SNDFILE */ ASSERT2(role == SLAVE, "WRONG ROLE", "", role);/********ULTRA HACK --- dont except input if NOINPUT exists **********/ if (stat(NOINPUT,&stbuf)==0) { WMESG(HUP, ""); logent(Rmtname, "NOINPUT set, no incoming files allowed"); (*Turnoff)(); return(0); } /* request to receive file */ /* check permissions */ i = getargs(msg, wrkvec); ASSERT2(i > 4, "ARG COUNT<5", "", i); 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); /* rti!trt: 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(subfile(filename))) { strcat(filename, "/"); strcat(filename, lastpart(W_FILE1));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -