xref: /csrg-svn/usr.bin/tip/cmds.c (revision 5333)
1*5333Sshannon /*	cmds.c	4.8	82/01/06	*/
23688Sroot #include "tip.h"
33688Sroot /*
43688Sroot  * tip
53688Sroot  *
63688Sroot  * miscellaneous commands
73688Sroot  */
83688Sroot 
93688Sroot int	quant[] = { 60, 60, 24 };
103688Sroot 
113688Sroot char	null = '\0';
123688Sroot char	*sep[] = { "second", "minute", "hour" };
133688Sroot static char *argv[10];		/* argument vector for take and put */
143688Sroot 
153688Sroot int	timeout();		/* timeout function called on alarm */
163688Sroot int	stopsnd();		/* SIGINT handler during file transfers */
173688Sroot int	intprompt();		/* used in handling SIG_INT during prompt */
183688Sroot int	intcopy();		/* interrupt routine for file transfers */
193688Sroot 
203688Sroot /*
213688Sroot  * FTP - remote ==> local
223688Sroot  *  get a file from the remote host
233688Sroot  */
243688Sroot getfl(c)
253688Sroot 	char c;
263688Sroot {
273688Sroot 	char buf[256];
283688Sroot 
293688Sroot 	putchar(c);
303688Sroot 	/*
313688Sroot 	 * get the UNIX receiving file's name
323688Sroot 	 */
333688Sroot 	if (prompt("Local file name? ", copyname))
343688Sroot 		return;
353688Sroot 	if ((sfd = creat(copyname, 0666)) < 0) {
363688Sroot 		printf("\r\n%s: cannot creat\r\n", copyname);
373688Sroot 		return;
383688Sroot 	}
393688Sroot 
403688Sroot 	/*
413688Sroot 	 * collect parameters
423688Sroot 	 */
433688Sroot 	if (prompt("List command for remote system? ", buf)) {
443688Sroot 		unlink(copyname);
453688Sroot 		return;
463688Sroot 	}
473688Sroot 	transfer(buf, sfd, value(EOFREAD));
483688Sroot }
493688Sroot 
503688Sroot /*
513688Sroot  * Cu-like take command
523688Sroot  */
533688Sroot cu_take(cc)
543688Sroot 	char cc;
553688Sroot {
563688Sroot 	int fd, argc;
573688Sroot 	char line[BUFSIZ];
583688Sroot 
593688Sroot 	if (prompt("[take] ", copyname))
603688Sroot 		return;
613688Sroot 	if ((argc = args(copyname, argv)) < 1 || argc > 2) {
623688Sroot 		printf("usage: <take> from [to]\r\n");
633688Sroot 		return;
643688Sroot 	}
653688Sroot 	if (argc == 1)
663688Sroot 		argv[1] = argv[0];
673688Sroot 	if ((fd = creat(argv[1], 0666)) < 0) {
683688Sroot 		printf("\r\n%s: cannot create\r\n", argv[1]);
693688Sroot 		return;
703688Sroot 	}
713688Sroot 	sprintf(line, "cat '%s';echo \01", argv[0]);
723688Sroot 	transfer(line, fd, "\01");
733688Sroot }
743688Sroot 
753688Sroot /*
763688Sroot  * Bulk transfer routine --
773688Sroot  *  used by getfl(), cu_take(), and pipefile()
783688Sroot  */
793688Sroot transfer(buf, fd, eofchars)
803688Sroot 	char *buf, *eofchars;
813688Sroot {
823688Sroot 	register int ct;
833688Sroot 	char c, buffer[BUFSIZ];
843688Sroot 	register char *p = buffer;
853688Sroot 	register int cnt, eof;
863688Sroot 	time_t start;
873688Sroot 
883688Sroot 	write(FD, buf, size(buf));
893688Sroot 	quit = 0;
903688Sroot 	signal(SIGINT, intcopy);
913688Sroot 	kill(pid, SIGIOT);
923688Sroot 	read(repdes[0], (char *)&ccc, 1);  /* Wait until read process stops */
933688Sroot 
943688Sroot 	/*
953688Sroot 	 * finish command
963688Sroot 	 */
973688Sroot 	write(FD, "\r", 1);
983688Sroot 	do
993688Sroot 		read(FD, &c, 1);
1003688Sroot 	while ((c&0177) != '\n');
1013688Sroot 	ioctl(0, TIOCSETC, &defchars);
1023688Sroot 
1033688Sroot 	start = time(0);
1043688Sroot 	for (ct = 0; !quit;) {
1053688Sroot 		eof = read(FD, &c, 1) <= 0;
1063688Sroot 		c &= 0177;
1073688Sroot 		if (quit)
1083688Sroot 			continue;
1093688Sroot 		if (eof || any(c, eofchars))
1103688Sroot 			break;
1113688Sroot 		if (c == 0)
1123688Sroot 			continue;	/* ignore nulls */
1133688Sroot 		if (c == '\r')
1143688Sroot 			continue;
1153688Sroot 		*p++ = c;
1163688Sroot 
1173688Sroot 		if (c == '\n' && boolean(value(VERBOSE)))
1183688Sroot 			printf("\r%d", ++ct);
1193688Sroot 		if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) {
1203688Sroot 			if (write(fd, buffer, cnt) != cnt) {
1213688Sroot 				printf("\r\nwrite error\r\n");
1223688Sroot 				quit = 1;
1233688Sroot 			}
1243688Sroot 			p = buffer;
1253688Sroot 		}
1263688Sroot 	}
1273688Sroot 	if (cnt = (p-buffer))
1283688Sroot 		if (write(fd, buffer, cnt) != cnt)
1293688Sroot 			printf("\r\nwrite error\r\n");
1303688Sroot 
1313688Sroot 	if (boolean(value(VERBOSE)))
1323688Sroot 		prtime(" lines transferred in ", time(0)-start);
1333688Sroot 	ioctl(0, TIOCSETC, &tchars);
1343688Sroot 	write(fildes[1], (char *)&ccc, 1);
1353688Sroot 	signal(SIGINT, SIG_DFL);
1363688Sroot 	close(fd);
1373688Sroot }
1383688Sroot 
1393688Sroot /*
1403688Sroot  * FTP - remote ==> local process
1413688Sroot  *   send remote input to local process via pipe
1423688Sroot  */
1433688Sroot pipefile()
1443688Sroot {
1453688Sroot 	int cpid, pdes[2];
1463688Sroot 	char buf[256];
1473688Sroot 	int status, p;
1483688Sroot 	extern int errno;
1493688Sroot 
1503688Sroot 	if (prompt("Local command? ", buf))
1513688Sroot 		return;
1523688Sroot 
1533688Sroot 	if (pipe(pdes)) {
1543688Sroot 		printf("can't establish pipe\r\n");
1553688Sroot 		return;
1563688Sroot 	}
1573688Sroot 
1583688Sroot 	if ((cpid = fork()) < 0) {
1593688Sroot 		printf("can't fork!\r\n");
1603688Sroot 		return;
1613688Sroot 	} else if (cpid) {
1623688Sroot 		if (prompt("List command for remote system? ", buf)) {
1633688Sroot 			close(pdes[0]), close(pdes[1]);
1643688Sroot 			kill (cpid, SIGKILL);
1653688Sroot 		} else {
1663688Sroot 			close(pdes[0]);
1673688Sroot 			signal(SIGPIPE, intcopy);
1683688Sroot 			transfer(buf, pdes[1], value(EOFREAD));
1693688Sroot 			signal(SIGPIPE, SIG_DFL);
1703688Sroot 			while ((p = wait(&status)) > 0 && p != cpid)
1713688Sroot 				;
1723688Sroot 		}
1733688Sroot 	} else {
1743688Sroot 		register int f;
1753688Sroot 
1763688Sroot 		dup2(pdes[0], 0);
1773688Sroot 		close(pdes[0]);
1783688Sroot 		for (f = 3; f < 20; f++)
1793688Sroot 			close(f);
1803688Sroot 		execute(buf);
1813688Sroot 		printf("can't execl!\r\n");
1823688Sroot 		exit(0);
1833688Sroot 	}
1843688Sroot }
1853688Sroot 
1863688Sroot /*
1873688Sroot  * Interrupt service routine for FTP
1883688Sroot  */
1893688Sroot stopsnd()
1903688Sroot {
1913688Sroot 	stop = 1;
1923688Sroot 	signal(SIGINT, SIG_IGN);
1933688Sroot }
1943688Sroot 
1953688Sroot /*
1963688Sroot  * FTP - local ==> remote
1973688Sroot  *  send local file to remote host
1983688Sroot  *  terminate transmission with pseudo EOF sequence
1993688Sroot  */
2003688Sroot sendfile(cc)
2013688Sroot 	char cc;
2023688Sroot {
2033688Sroot 	FILE *fd;
2043688Sroot 
2053688Sroot 	putchar(cc);
2063688Sroot 	/*
2073688Sroot 	 * get file name
2083688Sroot 	 */
2093688Sroot 	if (prompt("Local file name? ", fname))
2103688Sroot 		return;
2113688Sroot 
2123688Sroot 	/*
2133688Sroot 	 * look up file
2143688Sroot 	 */
2153688Sroot 	if ((fd = fopen(fname, "r")) == NULL) {
2163688Sroot 		printf("%s: cannot open\r\n", fname);
2173688Sroot 		return;
2183688Sroot 	}
2193688Sroot 	transmit(fd, value(EOFWRITE), NULL);
2203843Ssam 	if (!boolean(value(ECHOCHECK))) {
2213843Ssam 		struct sgttyb buf;
2223843Ssam 
2233843Ssam 		ioctl(FD, TIOCGETP, &buf);	/* this does a */
2243843Ssam 		ioctl(FD, TIOCSETP, &buf);	/*   wflushtty */
2253843Ssam 	}
2263688Sroot }
2273688Sroot 
2283688Sroot /*
2293688Sroot  * Bulk transfer routine to remote host --
2303688Sroot  *   used by sendfile() and cu_put()
2313688Sroot  */
2323688Sroot transmit(fd, eofchars, command)
2333688Sroot 	FILE *fd;
2343688Sroot 	char *eofchars, *command;
2353688Sroot {
2363688Sroot 	char *pc, lastc;
2373688Sroot 	int c, ccount, lcount;
2383688Sroot 	time_t start_t, stop_t;
2393688Sroot 
2403688Sroot 	kill(pid, SIGIOT);	/* put TIPOUT into a wait state */
2413688Sroot 	signal(SIGINT, stopsnd);
2423688Sroot 	stop = 0;
2433688Sroot 	ioctl(0, TIOCSETC, &defchars);
2443688Sroot 	read(repdes[0], (char *)&ccc, 1);
2453688Sroot 	if (command != NULL) {
2463688Sroot 		for (pc = command; *pc; pc++)
2473688Sroot 			send(*pc);
2483843Ssam 		if (boolean(value(ECHOCHECK)))
2493843Ssam 			read(FD, (char *)&c, 1);	/* trailing \n */
2503843Ssam 		else {
2513843Ssam 			struct sgttyb buf;
2523843Ssam 
2533843Ssam 			ioctl(FD, TIOCGETP, &buf);	/* this does a */
2543843Ssam 			ioctl(FD, TIOCSETP, &buf);	/*   wflushtty */
2553843Ssam 			sleep(5); /* wait for remote stty to take effect */
2563843Ssam 		}
2573688Sroot 	}
2583688Sroot 	lcount = 0;
2593688Sroot 	lastc = '\0';
2603688Sroot 	start_t = time(0);
2615133Ssam 	while (1) {
2623688Sroot 		ccount = 0;
2633688Sroot 		do {
2643688Sroot 			c = getc(fd);
2653688Sroot 			if (stop)
2663688Sroot 				goto out;
2673688Sroot 			if (c == EOF)
2683688Sroot 				goto out;
2693688Sroot 			if (c == 0177)
2703688Sroot 				continue;
2713688Sroot 			lastc = c;
2723688Sroot 			if (c < 040) {
2733688Sroot 				if (c == '\n')
2743688Sroot 					c = '\r';
2753688Sroot 				else if (c == '\t') {
2763688Sroot 					if (boolean(value(TABEXPAND))) {
2773688Sroot 						send(' ');
2785133Ssam 						while ((++ccount % 8) != 0)
2793688Sroot 							send(' ');
2803688Sroot 						continue;
2813688Sroot 					}
2823688Sroot 				} else
2833688Sroot 					continue;
2843688Sroot 			}
2853688Sroot 			send(c);
2863688Sroot 		} while (c != '\r');
2873688Sroot 		if (boolean(value(VERBOSE)))
2883688Sroot 			printf("\r%d", ++lcount);
2893843Ssam 		if (boolean(value(ECHOCHECK))) {
2903843Ssam 			alarm(10);
2913843Ssam 			timedout = 0;
2923843Ssam 			do {	/* wait for prompt */
2933843Ssam 				read(FD, (char *)&c, 1);
2943843Ssam 				if (timedout || stop) {
2953843Ssam 					if (timedout)
2963843Ssam 						printf("\r\ntimed out at eol\r\n");
2973843Ssam 					alarm(0);
2983843Ssam 					goto out;
2993843Ssam 				}
3003843Ssam 			} while ((c&0177) != character(value(PROMPT)));
3013843Ssam 			alarm(0);
3023843Ssam 		}
3033688Sroot 	}
3043688Sroot out:
3053688Sroot 	if (lastc != '\n')
3063688Sroot 		send('\r');
3073688Sroot 	for (pc = eofchars; *pc; pc++)
3083688Sroot 		send(*pc);
3093688Sroot 	stop_t = time(0);
3103688Sroot 	fclose(fd);
3113688Sroot 	signal(SIGINT, SIG_DFL);
3123688Sroot 	if (boolean(value(VERBOSE)))
3133688Sroot 		prtime(" lines transferred in ", stop_t-start_t);
3143688Sroot 	write(fildes[1], (char *)&ccc, 1);
3153688Sroot 	ioctl(0, TIOCSETC, &tchars);
3163688Sroot }
3173688Sroot 
3183688Sroot /*
3193688Sroot  * Cu-like put command
3203688Sroot  */
3213688Sroot cu_put(cc)
3223688Sroot 	char cc;
3233688Sroot {
3243688Sroot 	FILE *fd;
3253688Sroot 	char line[BUFSIZ];
3263688Sroot 	int argc;
3273688Sroot 
3283688Sroot 	if (prompt("[put] ", copyname))
3293688Sroot 		return;
3303688Sroot 	if ((argc = args(copyname, argv)) < 1 || argc > 2) {
3313688Sroot 		printf("usage: <put> from [to]\r\n");
3323688Sroot 		return;
3333688Sroot 	}
3343688Sroot 	if (argc == 1)
3353688Sroot 		argv[1] = argv[0];
3363688Sroot 	if ((fd = fopen(argv[0], "r")) == NULL) {
3373688Sroot 		printf("%s: cannot open\r\n", argv[0]);
3383688Sroot 		return;
3393688Sroot 	}
3403843Ssam 	if (boolean(value(ECHOCHECK)))
3413843Ssam 		sprintf(line, "cat>'%s'\r", argv[1]);
3423843Ssam 	else
3433843Ssam 		sprintf(line, "stty -echo;cat>'%s';stty echo\r", argv[1]);
3443688Sroot 	transmit(fd, "\04", line);
3453688Sroot }
3463688Sroot 
3473688Sroot /*
3483688Sroot  * FTP - send single character
3493688Sroot  *  wait for echo & handle timeout
3503688Sroot  */
3513688Sroot send(c)
3523688Sroot 	char c;
3533688Sroot {
3543688Sroot 	int cc;
3553688Sroot 	int retry = 0;
3563688Sroot 
3573688Sroot 	cc = c;
3583688Sroot 	write(FD, (char *)&cc, 1);
3593843Ssam 	if (!boolean(value(ECHOCHECK)))
3603843Ssam 		return;
3613688Sroot tryagain:
3623688Sroot 	timedout = 0;
3633688Sroot 	alarm(10);
3643688Sroot 	read(FD, (char *)&cc, 1);
3653688Sroot 	alarm(0);
3663688Sroot 	if (timedout) {
3673688Sroot 		printf("\r\ntimeout error (%s)\r\n", ctrl(c));
3683688Sroot 		if (retry++ > 3)
3693688Sroot 			return;
3703688Sroot 		write(FD, &null, 1); /* poke it */
3713688Sroot 		goto tryagain;
3723688Sroot 	}
3733688Sroot }
3743688Sroot 
3753688Sroot timeout()
3763688Sroot {
3773688Sroot 	signal(SIGALRM, timeout);
3783688Sroot 	timedout = 1;
3793688Sroot }
3803688Sroot 
3813688Sroot #ifdef CONNECT
3823688Sroot /*
3833688Sroot  * Fork a program with:
3843688Sroot  *  0 <-> local tty in
3853688Sroot  *  1 <-> local tty out
3863688Sroot  *  2 <-> local tty out
3873688Sroot  *  3 <-> remote tty in
3883688Sroot  *  4 <-> remote tty out
3893688Sroot  */
3903688Sroot consh(c)
3913688Sroot {
3923688Sroot 	char buf[256];
3933688Sroot 	int cpid, status, p;
3943688Sroot 	time_t start;
3953688Sroot 
3963688Sroot 	putchar(c);
3973688Sroot 	if (prompt("Local command? ", buf))
3983688Sroot 		return;
3993688Sroot 	kill(pid, SIGIOT);	/* put TIPOUT into a wait state */
4003688Sroot 	signal(SIGINT, SIG_IGN);
4013688Sroot 	signal(SIGQUIT, SIG_IGN);
4023688Sroot 	ioctl(0, TIOCSETC, &defchars);
4033688Sroot 	read(repdes[0], (char *)&ccc, 1);
4043688Sroot 	/*
4053688Sroot 	 * Set up file descriptors in the child and
4063688Sroot 	 *  let it go...
4073688Sroot 	 */
4083688Sroot 	if ((cpid = fork()) < 0)
4093688Sroot 		printf("can't fork!\r\n");
4103688Sroot 	else if (cpid) {
4113688Sroot 		start = time(0);
4123688Sroot 		while ((p = wait(&status)) > 0 && p != cpid)
4133688Sroot 			;
4143688Sroot 	} else {
4153688Sroot 		register int i;
4163688Sroot 
4173688Sroot 		dup2(FD, 3);
4183688Sroot 		dup2(3, 4);
4193688Sroot 		for (i = 5; i < 20; i++)
4203688Sroot 			close(i);
4213688Sroot 		signal(SIGINT, SIG_DFL);
4223688Sroot 		signal(SIGQUIT, SIG_DFL);
4233688Sroot 		execute(buf);
4243688Sroot 		printf("can't find `%s'\r\n", buf);
4253688Sroot 		exit(0);
4263688Sroot 	}
4273688Sroot 	if (boolean(value(VERBOSE)))
4283688Sroot 		prtime("away for ", time(0)-start);
4293688Sroot 	write(fildes[1], (char *)&ccc, 1);
4303688Sroot 	ioctl(0, TIOCSETC, &tchars);
4313688Sroot 	signal(SIGINT, SIG_DFL);
4323688Sroot 	signal(SIGQUIT, SIG_DFL);
4333688Sroot }
4343688Sroot #endif
4353688Sroot 
4363688Sroot /*
4373688Sroot  * Escape to local shell
4383688Sroot  */
4393688Sroot shell()
4403688Sroot {
4413688Sroot 	int shpid, status;
4423688Sroot 	extern char **environ;
4433688Sroot 	char *cp;
4443688Sroot 
4453688Sroot 	printf("[sh]\r\n");
4463688Sroot 	signal(SIGINT, SIG_IGN);
4473688Sroot 	signal(SIGQUIT, SIG_IGN);
4483688Sroot 	unraw();
4493688Sroot 	if (shpid = fork()) {
4503688Sroot 		while (shpid != wait(&status));
4513688Sroot 		raw();
4523688Sroot 		printf("\r\n!\r\n");
4533688Sroot 		signal(SIGINT, SIG_DFL);
4543688Sroot 		signal(SIGQUIT, SIG_DFL);
4553688Sroot 		return;
4563688Sroot 	} else {
4573688Sroot 		signal(SIGQUIT, SIG_DFL);
4583688Sroot 		signal(SIGINT, SIG_DFL);
4593688Sroot 		if ((cp = rindex(value(SHELL), '/')) == NULL)
4603688Sroot 			cp = value(SHELL);
4613688Sroot 		else
4623688Sroot 			cp++;
4633688Sroot 		execl(value(SHELL), cp, 0);
4643688Sroot 		printf("\r\ncan't execl!\r\n");
4653688Sroot 		exit(1);
4663688Sroot 	}
4673688Sroot }
4683688Sroot 
4693688Sroot /*
4703688Sroot  * TIPIN portion of scripting
4713688Sroot  *   initiate the conversation with TIPOUT
4723688Sroot  */
4733688Sroot setscript()
4743688Sroot {
4753688Sroot 	char c;
4763688Sroot 	/*
4773688Sroot 	 * enable TIPOUT side for dialogue
4783688Sroot 	 */
4793688Sroot 	kill(pid, SIGEMT);
4803688Sroot 	if (boolean(value(SCRIPT)))
4813688Sroot 		write(fildes[1], value(RECORD), size(value(RECORD)));
4823688Sroot 	write(fildes[1], "\n", 1);
4833688Sroot 	/*
4843688Sroot 	 * wait for TIPOUT to finish
4853688Sroot 	 */
4863688Sroot 	read(repdes[0], &c, 1);
4873688Sroot 	if (c == 'n')
4883688Sroot 		printf("can't create %s\r\n", value(RECORD));
4893688Sroot }
4903688Sroot 
4913688Sroot /*
4923688Sroot  * Change current working directory of
4933688Sroot  *   local portion of tip
4943688Sroot  */
4953688Sroot chdirectory()
4963688Sroot {
4973688Sroot 	char	dirname[80];
4983688Sroot 	register char *cp = dirname;
4993688Sroot 
5003688Sroot 	if (prompt("[cd] ", dirname))
5013688Sroot 		if (stoprompt)
5023688Sroot 			return;
5033688Sroot 		else
5043688Sroot 			cp = value(HOME);
5053688Sroot 	if (chdir(cp) < 0)
5063688Sroot 		printf("%s: bad directory\r\n", cp);
5073688Sroot 	printf("!\r\n");
5083688Sroot }
5093688Sroot 
5103688Sroot finish()
5113688Sroot {
5123688Sroot 	kill(pid, SIGTERM);
5133688Sroot 	disconnect();
5143688Sroot 	printf("\r\n[EOT]\r\n");
5153688Sroot 	delock(uucplock);
5163688Sroot 	unraw();
5173688Sroot 	exit(0);
5183688Sroot }
5193688Sroot 
5203688Sroot intcopy()
5213688Sroot {
5223688Sroot 	raw();
5233688Sroot 	quit = 1;
5243688Sroot }
5253688Sroot 
5263688Sroot execute(s)
5273688Sroot 	char *s;
5283688Sroot {
5293688Sroot 	register char *cp;
5303688Sroot 
5313688Sroot 	if ((cp = rindex(value(SHELL), '/')) == NULL)
5323688Sroot 		cp = value(SHELL);
5333688Sroot 	else
5343688Sroot 		cp++;
5353688Sroot 	execl(value(SHELL), cp, "-c", s, 0);
5363688Sroot }
5373688Sroot 
5383688Sroot args(buf, a)
5393688Sroot 	char *buf, *a[];
5403688Sroot {
5413688Sroot 	register char *p = buf, *start;
5423688Sroot 	register char **parg = a;
5433688Sroot 	register int n = 0;
5443688Sroot 
5453688Sroot 	do {
5463688Sroot 		while (*p && (*p == ' ' || *p == '\t'))
5473688Sroot 			p++;
5483688Sroot 		start = p;
5493688Sroot 		if (*p)
5503688Sroot 			*parg = p;
5513688Sroot 		while (*p && (*p != ' ' && *p != '\t'))
5523688Sroot 			p++;
5533688Sroot 		if (p != start)
5543688Sroot 			parg++, n++;
5553688Sroot 		if (*p)
5563688Sroot 			*p++ = '\0';
5573688Sroot 	} while (*p);
5583688Sroot 
5593688Sroot 	return(n);
5603688Sroot }
5613688Sroot 
5623688Sroot prtime(s, a)
5633688Sroot 	char *s;
5643688Sroot 	time_t a;
5653688Sroot {
5663688Sroot 	register i;
5673688Sroot 	int nums[3];
5683688Sroot 
5693688Sroot 	for (i = 0; i < 3; i++) {
5703688Sroot 		nums[i] = (int)(a % quant[i]);
5713688Sroot 		a /= quant[i];
5723688Sroot 	}
5733688Sroot 	printf("%s", s);
5743688Sroot 	while (--i >= 0)
5753688Sroot 		if (nums[i])
5763688Sroot 			printf("%d %s%c ", nums[i], sep[i],
5773688Sroot 				nums[i] == 1 ? '\0' : 's');
5783688Sroot 	printf("\r\n!\r\n");
5793688Sroot }
5803688Sroot 
5813688Sroot variable()
5823688Sroot {
5833688Sroot 	char	buf[256];
5843688Sroot 
5853688Sroot 	if (prompt("[set] ", buf))
5863688Sroot 		return;
5873688Sroot 	vlex(buf);
5883688Sroot 	if (vtable[BEAUTIFY].v_access&CHANGED) {
5893688Sroot 		vtable[BEAUTIFY].v_access &= ~CHANGED;
590*5333Sshannon 		kill(pid, SIGSYS);
5913688Sroot 	}
5923688Sroot 	if (vtable[SCRIPT].v_access&CHANGED) {
5933688Sroot 		vtable[SCRIPT].v_access &= ~CHANGED;
5943688Sroot 		setscript();
5953865Ssam 		/*
5963865Ssam 		 * So that "set record=blah script" doesn't
5973865Ssam 		 *  cause two transactions to occur.
5983865Ssam 		 */
5993865Ssam 		if (vtable[RECORD].v_access&CHANGED)
6003865Ssam 			vtable[RECORD].v_access &= ~CHANGED;
6013688Sroot 	}
6023688Sroot 	if (vtable[RECORD].v_access&CHANGED) {
6033688Sroot 		vtable[RECORD].v_access &= ~CHANGED;
6043688Sroot 		if (boolean(value(SCRIPT)))
6053688Sroot 			setscript();
6063688Sroot 	}
6073688Sroot }
6083822Ssam 
6093822Ssam /*
6103822Ssam  * Send a break.
6113822Ssam  * If we can't do it directly (as on VMUNIX), then simulate it.
6123822Ssam  */
6133822Ssam genbrk()
6143822Ssam {
6153822Ssam #ifdef VMUNIX
6163822Ssam 	ioctl(FD, TIOCSBRK, NULL);
6173822Ssam 	sleep(1);
6183822Ssam 	ioctl(FD, TIOCCBRK, NULL);
6193822Ssam #else
6203822Ssam 	struct sgttyb ttbuf;
6213822Ssam 	int sospeed;
6223822Ssam 
6233822Ssam 	ioctl(FD, TIOCGETP, &ttbuf);
6243822Ssam 	sospeed = ttbuf.sg_ospeed;
6253822Ssam 	ttbuf.sg_ospeed = B150;
6263822Ssam 	ioctl(FD, TIOCSETP, &ttbuf);
6273822Ssam 	write(FD, "\0\0\0\0\0\0\0\0\0\0", 10);
6283822Ssam 	ttbuf.sg_ospeed = sospeed;
6293822Ssam 	ioctl(FD, TIOCSETP, &ttbuf);
6303822Ssam 	write(FD, "@", 1);
6313822Ssam #endif
6323822Ssam }
6335133Ssam 
6345133Ssam #ifdef SIGTSTP
6355133Ssam /*
6365133Ssam  * Suspend tip
6375133Ssam  */
6385133Ssam suspend()
6395133Ssam {
6405133Ssam 	unraw();
6415133Ssam 	kill(0, SIGTSTP);
6425133Ssam 	raw();
6435133Ssam }
6445133Ssam #endif
645