cntrl.c

来自「unix v7是最后一个广泛发布的研究型UNIX版本」· C语言 代码 · 共 633 行

C
633
字号
#include "uucp.h"#include <sys/types.h>#include <sys/stat.h>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();extern int omsg();struct Proto Ptbl[]={	'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff,	'\0'};int (*Rdmsg)()=imsg, (*Rddata)();int (*Wrmsg)()=omsg, (*Wrdata)();int (*Turnon)(), (*Turnoff)();#define YES "Y"#define NO "N"#define Y 'Y'#define N 'N'#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 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 RMESG(m, s) if (rmesg(m, s) != 0) return(FAIL);#define RAMESG(s) if (rmesg('\0', s) != 0) return(FAIL)#define WMESG(m, s) if(wmesg(m, s) != 0) return(FAIL)char Wfile[MAXFULLNAME] = {'\0'};char Dfile[MAXFULLNAME];/******* *	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 */cntrl(role, wkpre)int role;char *wkpre;{	char msg[BUFSIZ], rqstr[BUFSIZ];	FILE *fp;	int filemode;	struct stat stbuf;	char filename[MAXFULLNAME], wrktype, *wrkvec[20];	extern (*Rdmsg)(), (*Wrmsg)();	extern char *index(), *lastpart();	int status = 1, i;	int ret;	static int pnum, tmpnum = 0;	pnum = getpid();top:	DEBUG(4, "*** TOP ***  -  role=%d, ", role);	if (role == MASTER) {		/* get work */		if ((i = gtwvec(Wfile, Spool, wkpre, wrkvec)) == 0) {			WMESG(HUP, "");			RMESG(HUP, msg);			goto process;		}		wrktype = W_TYPE[0];		DEBUG(4, "wrktype %c, ", wrktype);		if (wrktype == XUUCP) {			int n;			msg[0] = '\0';			for (n = 1; n < i; n++) {				strcat(msg, " ");				strcat(msg, wrkvec[n]);			}			sprintf(rqstr, "X %s", msg);			logent(rqstr, "REQUEST");			goto sendmsg;		}		ASSERT(i > 4, "ARG COUNT - %d\n", i);		sprintf(msg, " %s %s %s %s %s %s",			W_FILE1, W_FILE2, W_USER,			W_OPTNS, W_DFILE, W_MODE);		strcpy(User, W_USER);		ASSERT(strlen(User) <= 10, "User - %s\n", User);		sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,		  W_FILE2, W_USER);		logent(rqstr, "REQUEST");		DEBUG(4, "User - %s\n", User);		if (wrktype == SNDFILE ) {			strcpy(filename, W_FILE1);			expfile(filename);			if (chkpth(User, "", filename)) {				/*  access denied  */				logent("DENIED", "ACCESS");				unlink(W_DFILE);				unlink(Wfile);				goto top;			}			strcpy(Dfile, W_DFILE);			if ((fp = fopen(Dfile, "r")) == NULL			  && (fp = fopen(filename, "r")) == NULL) {				/*  can not read data file  */				logent("CAN'T READ DATA", "FAILED");				unlink(Wfile);				unlink(Dfile);				goto top;			}		}		if (wrktype == RCVFILE) {			strcpy(filename, W_FILE2);			expfile(filename);			if (chkpth(User, "", filename)			 || chkperm(filename, User, index(W_OPTNS, 'd'))) {				/*  access denied  */				logent("DENIED", "ACCESS");				unlink(Wfile);				goto top;			}			sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);			if ((fp = fopen(Dfile, "w")) == NULL) {				/*  can not create temp  */				logent("CAN'T CREATE TM", "FAILED");				unlink(Wfile);				unlink(Dfile);				goto top;			}			chmod(Dfile, 0666);		}sendmsg:		DEBUG(4, "wrktype - %c, ", wrktype);		DEBUG(4, " fileno - %d\n", fileno(fp));		WMESG(wrktype, msg);		RMESG(wrktype, msg);		goto process;	}	/* role is slave */	RAMESG(msg);	goto process;process:	DEBUG(4, " PROCESS: msg - %s\n", msg);	switch (msg[0]) {	case RQSTCMPT:		DEBUG(4, "%s\n", "RQSTCMPT:");		logent((msg[1] == 'N') ? "FAILED" : "SUCCEEDED", "REQUEST");		if (role == MASTER) {			notify(W_OPTNS, W_USER, W_FILE1, Rmtname,			  (msg[1] == N) ? "failed" : "succeeded");		}		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,				"role - %d", role);			role = SLAVE;			goto top;		}		/* get work */		if (!iswrk(Wfile, "chk", Spool, wkpre)) {			WMESG(HUP, YES);			RMESG(HUP, msg);			goto process;		}		WMESG(HUP, NO);		role = MASTER;		goto top;	case XUUCP:		if (role == MASTER) {			unlink(Wfile);			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);			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) {			logent("DENIED", "REQUEST");			ASSERT(role == MASTER,				"role - %d", role);			fclose(fp);			unlink(W_DFILE);			unlink(Wfile);			goto top;		}		if (msg[1] == Y) {			/* send file */			ASSERT(role == MASTER,				"role - %d", role);			ret = (*Wrdata)(fp, Ofn);			fclose(fp);			if (ret != 0)				return(FAIL);			unlink(W_DFILE);			RMESG(RQSTCMPT, msg);			goto process;		}		/*  SLAVE section of SNDFILE  */		ASSERT(role == SLAVE,			"role - %d", role);		/* request to receive file */		/* check permissions */		i = getargs(msg, wrkvec);		ASSERT(i > 4, "ARG COUNT - %d\n", i);		sprintf(rqstr, "%s %s %s %s", W_TYPE, W_FILE1,		  W_FILE2, W_USER);		logent(rqstr, "REQUESTED");		DEBUG(4, "msg - %s\n", msg);		DEBUG(4, "W_FILE2 - %s\n", W_FILE2);		strcpy(filename, W_FILE2);		expfile(filename);		if (chkpth("", Rmtname, filename)		 || chkperm(filename, Loginuser, index(W_OPTNS, 'd'))) {			WMESG(SNDFILE, NO);			logent("DENIED", "PERMISSION");			goto top;		}		if (isdir(filename)) {			strcat(filename, "/");			strcat(filename, lastpart(W_FILE1));		}		strcpy(User, W_USER);		ASSERT(strlen(User) <= 10, "User - %s\n", User);		DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);		sprintf(Dfile, "%s/TM.%05d.%03d", Spool, pnum, tmpnum++);		if((fp = fopen(Dfile, "w")) == NULL) {			WMESG(SNDFILE, NO);			logent("CAN'T OPEN", "DENIED");			unlink(Dfile);			goto top;		}		chmod(Dfile, 0666);		WMESG(SNDFILE, YES);		ret = (*Rddata)(Ifn, fp);		fclose(fp);		if (ret != 0)			return(FAIL);		/* copy to user directory */		status = xmv(Dfile, filename);		WMESG(RQSTCMPT, status ? NO : YES);		logent(status ? "FAILED" : "SUCCEEDED", "COPY");		sscanf(W_MODE, "%o", &filemode);		DEBUG(4, "mode - %o\n", filemode);		if (filemode <= 0)			filemode = 0666;		if (status == 0) {			filemode |= 0666;			chmod(filename, filemode | 0666);		}		goto top;	case RCVFILE:		/*  MASTER section of RCVFILE  */		DEBUG(4, "%s\n", "RCVFILE:");		if (msg[1] == N) {			logent("REQUEST", "DENIED");			ASSERT(role == MASTER,				"role - %d", role);			unlink(Wfile);			fclose(fp);			goto top;		}		if (msg[1] == Y) {			/* receive file */			ASSERT(role == MASTER,				"role - %d", role);			ret = (*Rddata)(Ifn, fp);			fclose(fp);			if (ret != 0)				return(FAIL);			/* copy to user directory */			if (isdir(filename)) {				strcat(filename, "/");				strcat(filename, lastpart(W_FILE1));			}			status = xmv(Dfile, filename);			WMESG(RQSTCMPT, status ? NO : YES);			logent(status ? "FAILED" : "SUCCEEDED", "COPY");			notify(W_OPTNS, W_USER, filename, Rmtname,			  status ? "failed" : "succeeded");			sscanf(&msg[2], "%o", &filemode);			DEBUG(4, "mode - %o\n", filemode);			if (filemode <= 0)				filemode = 0666;			if (status == 0) {				unlink(Dfile);				filemode |= 0666;				chmod(filename, filemode | 0666);			}			goto top;		}		/*  SLAVE section of RCVFILE  */		ASSERT(role == SLAVE,			"role - %d", role);		/* request to send file */		strcpy(rqstr, msg);		logent(rqstr, "REQUESTED");		/* check permissions */		i = getargs(msg, wrkvec);		ASSERT(i > 3, "ARG COUNT - %d\n", i);		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));		}		strcpy(User, W_USER);		ASSERT(strlen(User) <= 10, "User - %s\n", User);		if (chkpth("", Rmtname, filename) != 0) {			WMESG(RCVFILE, NO);			logent("DENIED", "PERMISSION");			goto top;		}		DEBUG(4, "chkpth ok Rmtname - %s\n", Rmtname);		if ((fp = fopen(filename, "r")) == NULL) {			WMESG(RCVFILE, NO);			logent("CAN'T OPEN", "DENIED");			goto top;		}		/*  ok to send file */		ret = stat(filename, &stbuf);		ASSERT(ret != -1, "STAT FAILED %s", filename);		sprintf(msg, "%s %o", YES, stbuf.st_mode & 0777);		WMESG(RCVFILE, msg);		ret = (*Wrdata)(fp, Ofn);		fclose(fp);		if (ret != 0)			return(FAIL);		RMESG(RQSTCMPT, msg);		goto process;	}	return(FAIL);}/*** *	rmesg(c, msg)	read message 'c' *	char *msg, c; * *	return code:  0  |  FAIL */rmesg(c, msg)char *msg, c;{	char str[50];	DEBUG(4, "rmesg - '%c' ", c);	if ((*Rdmsg)(msg, Ifn) != 0) {		DEBUG(4, "got %s\n", "FAIL");		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);		sprintf(str, "expected '%c' got %.25s", c, msg);		logent(str, "BAD READ");		return(FAIL);	}	DEBUG(4, "got %.25s\n", msg);	return(0);}/*** *	wmesg(m, s)	write a message (type m) *	char *s, m; * *	return codes: 0 - ok | FAIL - ng */wmesg(m, s)char *s, m;{	DEBUG(4, "wmesg '%c'", m);	DEBUG(4, "%.25s\n", s);	return((*Wrmsg)(m, s, Ofn));}/*** *	notify(options, user, file, sys, stwork)	mail results of copy *	char *options, *user, *file, *sys, *stword); * *	return codes:  none */notify(options, user, file, sys, stword)char *options, *user, *file, *sys, *stword;{	char str[200];	if (index(options, 'm') == NULL)		return;	sprintf(str, "file %s, system %s, copy %s\n", file, sys, stword);	mailst(user, str);	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 imsg(), omsg();	extern char *blptcl(), fptcl();	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);		DEBUG(4, "protocol %s\n", str);		return(SUCCESS);	}	else {		WMESG(SLTPTCL, blptcl(str));		RMESG(USEPTCL, msg);		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 */charfptcl(str)char *str;{	struct Proto *p;	extern char *index();	for (p = Ptbl; p->P_id != '\0'; p++) {		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)char *str;{	struct Proto *p;	char *s;	for (p = Ptbl, s = str; (*s++ = p->P_id) != '\0'; p++);	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)char *c;{	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)() != 0)				return(FAIL);			DEBUG(4, "Proto started %c\n", *c);			return(SUCCESS);		}	}	DEBUG(4, "Proto start-fail %c\n", *c);	return(FAIL);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?