⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cu.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
#include <stdio.h>#include <signal.h>#include <sgtty.h>/* *	cu telno [-t] [-s speed] [-l line] [-a acu] * *	-t is for dial-out to terminal. *	speeds are: 110, 134, 150, 300, 1200. 300 is default. * *	Escape with `~' at beginning of line. *	Ordinary diversions are ~<, ~> and ~>>. *	Silent output diversions are ~>: and ~>>:. *	Terminate output diversion with ~> alone. *	Quit is ~. and ~! gives local command or shell. *	Also ~$ for canned procedure pumping remote. *	~%put from [to]  and  ~%take from [to] invoke builtins */#define CRLF "\r\n"#define wrc(ds) write(ds,&c,1)char	*devcul	= "/dev/cul0";char	*devcua	= "/dev/cua0";char	*lspeed	= "300";int	ln;	/* fd for comm line */char	tkill, terase;	/* current input kill & erase */char	c;char	*connmsg[] = {	"",	"line busy",	"call dropped",	"no carrier",	"can't fork",	"acu access",	"tty access",	"tty hung",	"usage: cu telno [-t] [-s speed] [-l line] [-a acu]"};rdc(ds) {	ds=read(ds,&c,1); 	c&= 0177; 	return (ds);}int intr;sig2(){	signal(SIGINT, SIG_IGN); 	intr = 1;}int set14;xsleep(n){	xalarm(n);	pause();	xalarm(0);}xalarm(n){	set14=n; 	alarm(n);}sig14(){	signal(SIGALRM, sig14); 	if (set14) alarm(1);}int	dout;int	nhup;/* *	main: get connection, set speed for line. *	spawn child to invoke rd to read from line, output to fd 1 *	main line invokes wr to read tty, write to line */main(ac,av)char *av[];{	int fk;	int speed;	char *telno;	struct sgttyb stbuf;	signal(SIGALRM, sig14);	if (ac < 2) {		prf(connmsg[8]);		exit(8);	}	telno = av[1];	av += 2;	ac -= 2;	for (; ac > 0; av++) {		if (equal(*av, "-t")) {			dout = 1;			--ac;			continue;		}		if (ac < 2)			break;		if (equal(*av, "-s"))			lspeed = *++av;		else if (equal(*av, "-l"))			devcul = *++av;		else if (equal(*av, "-a"))			devcua = *++av;		else			break;		ac -= 2;	}	if (!exists(devcua) || !exists(devcul))		exit(9);	ln = conn(devcul, devcua, telno);	if (ln < 0) {		prf("Connect failed: %s",connmsg[-ln]);		exit(-ln);	}	switch(atoi(lspeed)) {	case 110:		speed = B110;break;	case 150:		speed = B150;break;	default:	case 300:		speed = B300;break;	case 1200:		speed = B1200;break;	}	stbuf.sg_ispeed = speed;	stbuf.sg_ospeed = speed;	stbuf.sg_flags = EVENP|ODDP;	if (!dout)		stbuf.sg_flags |= RAW;	ioctl(TIOCSETP, ln, &stbuf);	ioctl(TIOCEXCL, ln, (struct sgttyb *)NULL);	ioctl(TIOCHPCL, ln, (struct sgttyb *)NULL);	prf("Connected");	if (dout)		fk = -1;	else		fk = fork();	nhup = (int)signal(SIGINT, SIG_IGN);	if (fk == 0) {		rd();		prf("\007Lost carrier");		exit(3);	}	mode(1);	wr();	mode(0);	kill(fk, SIGKILL);	wait((int *)NULL);	stbuf.sg_ispeed = 0;	stbuf.sg_ospeed = 0;	ioctl(TIOCSETP, ln, &stbuf);	prf("Disconnected");	exit(0);}/* *	conn: establish dial-out connection. *	Example:  fd = conn("/dev/ttyh","/dev/dn1","4500"); *	Returns descriptor open to tty for reading and writing. *	Negative values (-1...-7) denote errors in connmsg. *	Uses alarm and fork/wait; requires sig14 handler. *	Be sure to disconnect tty when done, via HUPCL or stty 0. */conn(dev,acu,telno)char *dev, *acu, *telno;{	struct sgttyb stbuf;	extern errno;	char *p, *q, b[30];	int er, fk, dn, dh, t;	er=0; 	fk=(-1);	if ((dn=open(acu,1))<0) {		er=(errno == 6? 1:5); 		goto X;	}	if ((fk=fork()) == (-1)) {		er=4; 		goto X;	}	if (fk == 0) {		open(dev,2); 		for (;;) pause();	}	xsleep(2);	/*	 *	copy phone #, assure EON	 */	p=b; 	q=telno;	while (*p++=(*q++))		;	p--;	if (*(p-1)!='<') {		if (*(p-1)!='-') *p++='-';		*p++='<';	}	t=p-b;	xalarm(5*t);	t=write(dn,b,t);	xalarm(0);	if (t<0) {		er=2; 		goto X;	}	/* close(dn) */	xalarm(40);		/* was 5; sometimes missed carrier */	dh = open(dev,2);	xalarm(0);	if (dh<0) {		er=(errno == 4? 3:6); 		goto X;	}	ioctl(TIOCGETP, ln, &stbuf);	stbuf.sg_flags &= ~ECHO;	xalarm(10);	ioctl(TIOCSETP, dh, &stbuf);	ioctl(TIOCHPCL, dh, (struct sgttyb *)NULL);	xalarm(0);X: 	if (er) close(dn);	if (fk!=(-1)) {		kill(fk, SIGKILL);		xalarm(10);		while ((t=wait((int *)NULL))!=(-1) && t!=fk);		xalarm(0);	}	return (er? -er:dh);}/* *	wr: write to remote: 0 -> line. *	~.	terminate *	~<file	send file *	~!	local login-style shell *	~!cmd	execute cmd locally *	~$proc	execute proc locally, send output to line *	~%cmd	execute builtin cmd (put and take) */wr(){	int ds,fk,lcl,x;	char *p,b[600];	for (;;) {		p=b;		while (rdc(0) == 1) {			if (p == b) lcl=(c == '~');			if (p == b+1 && b[0] == '~') lcl=(c!='~');			if (c == 0) c=0177;			if (!lcl) {				if (wrc(ln) == 0) {					prf("line gone"); return;				}			}			if (lcl) {				if (c == 0177) c=tkill;				if (c == '\r' || c == '\n') goto A;				if (!dout) wrc(0);			}			*p++=c;			if (c == terase) {				p=p-2; 				if (p<b) p=b;			}			if (c == tkill || c == 0177 || c == '\r' || c == '\n') p=b;		}		return;A: 		if (!dout) echo("");		*p=0;		switch (b[1]) {		case '.':		case '\004':			return;		case '!':		case '$':			fk = fork();			if (fk == 0) {				close(1);				dup(b[1] == '$'? ln:2);				close(ln);				mode(0);				if (!nhup) signal(SIGINT, SIG_DFL);				if (b[2] == 0) execl("/bin/sh","-",0);				else execl("/bin/sh","sh","-c",b+2,0);				prf("Can't execute shell");				exit(~0);			}			if (fk!=(-1)) {				while (wait(&x)!=fk);			}			mode(1);			if (b[1] == '!') echo("!");			else {				if (dout) echo("$");			}			break;		case '<':			if (b[2] == 0) break;			if ((ds=open(b+2,0))<0) {				prf("Can't divert %s",b+1); 				break;			}			intr=x=0;			mode(2);			if (!nhup) signal(SIGINT, sig2);			while (!intr && rdc(ds) == 1) {				if (wrc(ln) == 0) {					x=1; 					break;				}			}			signal(SIGINT, SIG_IGN);			close(ds);			mode(1);			if (x) return;			if (dout) echo("<");			break;		case '%':			dopercen(&b[2]);			break;		default:			prf("Use `~~' to start line with `~'");		}		continue;	}}dopercen(line)register char *line;{	char *args[10];	register narg, f;	int rcount;	for (narg = 0; narg < 10;) {		while(*line == ' ' || *line == '\t')			line++;		if (*line == '\0')			break;		args[narg++] = line;		while(*line != '\0' && *line != ' ' && *line != '\t')			line++;		if (*line == '\0')			break;		*line++ = '\0';	}	if (equal(args[0], "take")) {		if (narg < 2) {			prf("usage: ~%%take from [to]");			return;		}		if (narg < 3)			args[2] = args[1];		wrln("echo '~>:'");		wrln(args[2]);		wrln(";tee /dev/null <");		wrln(args[1]);		wrln(";echo '~>'\n");		return;	} else if (equal(args[0], "put")) {		if (narg < 2) {			prf("usage: ~%%put from [to]");			return;		}		if (narg < 3)			args[2] = args[1];		if ((f = open(args[1], 0)) < 0) {			prf("cannot open: %s", args[1]);			return;		}		wrln("stty -echo;cat >");		wrln(args[2]);		wrln(";stty echo\n");		xsleep(5);		intr = 0;		if (!nhup)			signal(SIGINT, sig2);		mode(2);		rcount = 0;		while(!intr && rdc(f) == 1) {			rcount++;			if (c == tkill || c == terase)				wrln("\\");			if (wrc(ln) != 1) {				xsleep(2);				if (wrc(ln) != 1) {					prf("character missed");					intr = 1;					break;				}			}		}		signal(SIGINT, SIG_IGN);		close(f);		if (intr) {			wrln("\n");			prf("stopped after %d bytes", rcount);		}		wrln("\004");		xsleep(5);		mode(1);		return;	}	prf("~%%%s unknown\n", args[0]);}equal(s1, s2)register char *s1, *s2;{	while (*s1++ == *s2)		if (*s2++ == '\0')			return(1);	return(0);}wrln(s)register char *s;{	while (*s)		write(ln, s++, 1);}/* *	rd: read from remote: line -> 1 *	catch: *	~>[>][:][file] *	stuff from file... *	~>	(ends diversion) */rd(){	int ds,slnt;	char *p,*q,b[600];	p=b;	ds=(-1);	while (rdc(ln) == 1) {		if (ds<0) slnt=0;		if (!slnt) wrc(1);		*p++=c;		if (c!='\n') continue;		q=p; 		p=b;		if (b[0]!='~' || b[1]!='>') {			if (*(q-2) == '\r') {				q--; 				*(q-1)=(*q);			}			if (ds>=0) write(ds,b,q-b);			continue;		}		if (ds>=0) close(ds);		if (slnt) {			write(1, b, q - b);			write(1, CRLF, sizeof(CRLF));		}		if (*(q-2) == '\r') q--;		*(q-1)=0;		slnt=0;		q=b+2;		if (*q == '>') q++;		if (*q == ':') {			slnt=1; 			q++;		}		if (*q == 0) {			ds=(-1); 			continue;		}		if (b[2]!='>' || (ds=open(q,1))<0) ds=creat(q,0644);		lseek(ds, (long)0, 2);		if (ds<0) prf("Can't divert %s",b+1);	}}struct {char lobyte; char hibyte;};mode(f){	struct sgttyb stbuf;	if (dout) return;	ioctl(TIOCGETP, 0, &stbuf);	tkill = stbuf.sg_kill;	terase = stbuf.sg_erase;	if (f == 0) {		stbuf.sg_flags &= ~RAW;		stbuf.sg_flags |= ECHO|CRMOD;	}	if (f == 1) {		stbuf.sg_flags |= RAW;		stbuf.sg_flags &= ECHO|CRMOD;	}	if (f == 2) {		stbuf.sg_flags &= ~RAW;		stbuf.sg_flags &= ~(ECHO|CRMOD);	}	ioctl(TIOCSETP, 0, &stbuf);}echo(s)char *s;{	char *p;	for (p=s;*p;p++);	if (p>s) write(0,s,p-s);	write(0,CRLF, sizeof(CRLF));}prf(f, s)char *f;char *s;{	fprintf(stderr, f, s);	fprintf(stderr, CRLF);}exists(devname)char *devname;{	if (access(devname, 0)==0)		return(1);	prf("%s does not exist", devname);	return(0);}

⌨️ 快捷键说明

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