slattach.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 751 行

C
751
字号
#ifndef lintstatic char	*sccsid="@(#)slattach.c	4.3	(ULTRIX)	2/1/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 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.	* *									* ************************************************************************//*#ifndef lintstatic char sccsid[] = "slattach.c	4.1 (Berkeley) 2/17/86";#endif*//* * TODO: *	-Redial on failure (if option set to do so). */#include <stdio.h>#include <sys/param.h>#include <sgtty.h>#include <sys/socket.h>#include <netinet/in.h>#include <net/if.h>#include <netdb.h>#include <fcntl.h>#include <syslog.h>#include <sys/ioctl.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#define DEFAULT_BAUD	2400#define MAXHOSTLEN 255#define SLHOSTS "/etc/sliphosts"int	slipdisc = SLPDISC;char	devname[32];char	ifconfigbuf[255];char 	argbuf[256];char 	gbuf[1024], respbuf[1024];int fd = 0;/************************************************************************ *			Modification History				* * * 09/25/89	R. Bhanukitsiri *		Make syslog log errno. * * # comment *//* 9+ allow destination gateway mask speed device modemtype phone# login *//* 8+ allow destination gateway mask speed device hw login *//* 6 destination gateway mask speed device *//*									* ************************************************************************/#define ALIAS		0#define DESTINATION 	1#define GATEWAY		2#define MASK		3#define SPEED		4#define DEVICE		5#define TYPE		6#define PHONE		7#define LOGIN_INFO	8#define MAXARGS 40char *arptr[MAXARGS];char *modem_type, *phone, *master; extern int errno;/* Parity control during login procedure */#define P_ZERO  0#define P_ONE   1#define P_EVEN  2#define P_ODD   3#ifndef IFF_D1/* * These defines for device specific interface flags will eventually * get added to net/if.h.  Until then ... */#define IFF_D1	0x8000#define IFF_D2	0x4000#define IFF_D3	0x2000#endifint set_flags;		/* interface flag bits to set */int clear_flags;	/* interface flag bits to clear */huphandler(){	int pid;	syslog(LOG_ERR, "HUP - shutdown");	exit(0);}		int sldebug = 0;	main(argc, argv)	int argc;	char *argv[];{	register FILE *fp;	int login = 0;	struct sgttyb sgtty;	int n, pid=0, typeofslip=0, incoming = 0;	int unit = 0;	int	speed = 0;	if ((argc > 2) && (argv[1][0] != '-' && argv[1][0] != '+')) {	  fprintf(stderr,		  "slattach: usage slattach [{+|-}{c|e|i} ...] [system]\n");	  exit(1);	} 	while (argc > 2 && (argv[1][0] == '-' || argv[1][0] == '+')) {		switch (argv[1][1]) {		case 'c':	/* enable or disable hdr compression */			if (argv[1][0] == '-')				clear_flags |= IFF_D1;			else				set_flags |= IFF_D1;			break;		case 'e':	/* enable or disable hdr.comp. `auto-enable' */			if (argv[1][0] == '-')				clear_flags |= IFF_D2;			else				set_flags |= IFF_D2;			break;		case 'i':	/* enable or disable icmp discard */			if (argv[1][0] == '-')				clear_flags |= IFF_D3;			else				set_flags |= IFF_D3;			break;		default:			fprintf(stderr,"%s: unknown flag `%s'\n", argv[0],				argv[1]);			exit(1);		}		--argc;		++argv;	}	/* Become root */	setuid(geteuid());	if(argc == 1)		typeofslip = setup(getlogin());	else		typeofslip = setup(argv[1]);	if(!typeofslip) {		fprintf(stderr, "slattach: Unknown host\n");		exit(1);	}	openlog("slattach", LOG_ERR);	if(strcmp(arptr[SPEED], "any") != 0) {		speed = findspeed(arptr[SPEED] ? atoi(arptr[SPEED]) : DEFAULT_BAUD);		modem_type = arptr[TYPE];		phone = arptr[PHONE];		/* hw means no phone # */		if(strcmp(modem_type, "hw") == 0)			login = PHONE;		else			login = LOGIN_INFO;	} else {		incoming++;	}	master = arptr[DESTINATION];	if(sldebug)		syslog(LOG_ERR,"type %d %d\n", typeofslip, login);	if (!incoming && speed == 0) {		fprintf(stderr, "unknown speed %s", argv[2]);		exit(1);	}	/*	if(!incoming) {		for (n = 0; n < 20; n++)			(void) close(n);		(void) open("/", 0);		(void) dup2(0, 1);		(void) dup2(0, 2);		n = open("/dev/tty", 2);		if (n >= 0) {			ioctl(n, TIOCNOTTY, (char *)0);			(void) close(n);		}	}	*/	if(modem_type != 0 && strcmp(modem_type, "hw") != 0) {		if((fd = open(arptr[DEVICE], O_RDWR|O_NDELAY)) < 0) {			syslog(LOG_ERR, arptr[DEVICE]);			exit(1);		}		if(ioctl(fd, TIOCSINUSE) < 0) {			syslog(LOG_ERR,"Shared line in use: %m");			exit(1);		}		} else {		if ((fd = open(arptr[DEVICE], O_RDWR|O_NDELAY)) < 0) {			syslog(LOG_ERR,arptr[DEVICE]);			exit(1);		}	}	if(incoming) { /* leave speed alone */		if (ioctl(fd, TIOCGETP, &sgtty) < 0) {			syslog(LOG_ERR,"ioctl(TIOCGETP): %m");			exit(1);		}		speed = sgtty.sg_ospeed;		syslog(LOG_ERR,"speeds %d %d\n", sgtty.sg_ospeed, sgtty.sg_ispeed);	}	/* Enable hangup handler */	(void) signal(SIGHUP, huphandler);	(void) signal(SIGINT, huphandler);	sgtty.sg_flags = RAW;	sgtty.sg_flags &= ~ANYP; /* NONE */	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;	if (ioctl(fd, TIOCSETP, &sgtty) < 0) {		syslog(LOG_ERR,"ioctl(TIOCSETP): %m");		exit(1);	}	if(sldebug)		syslog(LOG_ERR, "modem_type %s %d\n", modem_type, login);	if(modem_type != NULL) {		if(strcmp(modem_type, "hw") != 0 && phone && agetent(gbuf, modem_type) != 0) {			char tmpbuf[1024];			gen_setup(gbuf, fd);			if(phone) {				if(!gen_dialer(phone, "sl_network")) {					syslog(LOG_ERR,"Can't get remote system");					exit(1);				}			if(login) 				dologin(login);			}		} else if(strcmp(modem_type, "hw") == 0 && login) {			/* These lines fool generic dialing routines */			extern int FDD, stupidi, debugn, lsleep;			int temp = 0;			FDD = fd;			stupidi = debugn = lsleep = 0;	/* Ignore modem signals in case line is configured incorrectly */			ioctl(fd, TIOCNMODEM, &temp);			dologin(login);		}	}	sgtty.sg_flags = RAW;	sgtty.sg_flags &= ~ANYP; /* NONE */	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;	if (ioctl(fd, TIOCSETP, &sgtty) < 0) {		syslog(LOG_ERR,"ioctl(TIOCSETP): %m");		exit(1);	}	if (ioctl(fd, TIOCSETD, &slipdisc) < 0) {		syslog(LOG_ERR,"ioctl(TIOCSETD): %m");		exit(99);	}	if(ioctl(fd, TIOCGETD, &unit) < 0) {		syslog(LOG_ERR,"ioctl(TIOCGETD): %m");		exit(1);	}	if(master != NULL) { /* Setting up a comm link */		sprintf(ifconfigbuf,"/etc/ifconfig sl%d %s %s netmask %s", unit, arptr[GATEWAY], master, arptr[MASK]);		syslog(LOG_ERR, "create interface: %s", ifconfigbuf);	}	if ((pid = fork())>0) {		system(ifconfigbuf);		exit(0);	}	wait(pid);/* If we are receiving a call then allow compression.  It may then be * enabled by the machine calling us. */	if (incoming) {	  clear_flags = 0;	  set_flags = IFF_D2;	}		if (set_flags || clear_flags) {	  int s;	  struct	ifreq ifr;	  sprintf(ifr.ifr_name, "sl%d", unit);	  s = socket(AF_INET, SOCK_DGRAM, 0);	  if (s < 0) {	    perror("ifattach: socket");	    syslog(LOG_INFO, "socket: %m");	    cleandeath(1);	  }	  	  if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {	    perror("ioctl (SIOCGIFFLAGS)");	    syslog(LOG_INFO, "SIOCGIFFLAGS: %m");	    cleandeath(1);	  }	  ifr.ifr_flags &=~ clear_flags;	  ifr.ifr_flags |=  set_flags;	  if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {	    perror("ioctl (SIOCSIFFLAGS)");	    syslog(LOG_INFO, "SIOCSIFFLAGS: %m");	    cleandeath(1);	  }	}		for(;;)		sigpause(0);}struct sg_spds {	int sp_val, sp_name;}       spds[] = {#ifdef B50	{ 50, B50 },#endif#ifdef B75	{ 75, B75 },#endif#ifdef B110	{ 110, B110 },#endif#ifdef B150	{ 150, B150 },#endif#ifdef B200	{ 200, B200 },#endif#ifdef B300	{ 300, B300 },#endif#ifdef B600	{ 600, B600 },#endif#ifdef B1200	{ 1200, B1200 },#endif#ifdef B1800	{ 1800, B1800 },#endif#ifdef B2000	{ 2000, B2000 },#endif#ifdef B2400	{ 2400, B2400 },#endif#ifdef B3600	{ 3600, B3600 },#endif#ifdef B4800	{ 4800, B4800 },#endif#ifdef B7200	{ 7200, B7200 },#endif#ifdef B9600	{ 9600, B9600 },#endif#ifdef EXTA	{ 19200, EXTA },#endif#ifdef EXTB	{ 38400, EXTB },#endif	{ 0, 0 }};findspeed(speed)	register int speed;{	register struct sg_spds *sp;	sp = spds;	while (sp->sp_val && sp->sp_val != speed) {		sp++;	}	return (sp->sp_name);}setup(host)char *host;{	FILE *fp;	int c;	if((fp = fopen(SLHOSTS, "r")) == 0)		return(1);	while(fgets(argbuf, 256, fp) != NULL) {		c = getargs(argbuf, arptr);		if(strcmp(host, arptr[ALIAS]) == 0) {			fclose(fp);			return(c);		}		}	fclose(fp);	return(0);}/* *	The following code is adapted from uucico to present a *	somewhat smarter interface to dialing slip hosts */getargs(s, arps)char *s, *arps[];{	int i;	for(i=0; i<MAXARGS; i++)		arps[i] = NULL;	i = 0;	while (1) {		arps[i] = NULL;		while (*s == ' ' || *s == '\t')			*s++ = '\0';		if (*s == '\n')			*s = '\0';		if (*s == '\0')			break;		arps[i++] = s++;		while (*s != '\0' && *s != ' '			&& *s != '\t' && *s != '\n')				s++;	}	return(i);}dologin(loginind){	register char *want, *altern;        extern char *index();        int k, ok;	char **login = &arptr[loginind];	while(*login) {		if(sldebug)			syslog(LOG_ERR, "login: %x %s\n", login, *login);		want = *login;		ok = 1;		while(ok != 0) {			altern = index(want, '-');			if(altern != NULL)				*altern++ = '\0';			ok = expect(want);			if(ok == 0)				break;			if(altern == NULL)				return;			want = index(altern, '-');			if(want != NULL)				*want++ = '\0';			sendthem(altern);		}		login++;		sleep(2);		if(sldebug)			syslog(LOG_ERR, "login: %x %s\n", login, *login);		sendthem(*login);		login++;	}	}jmp_buf Sjbuf;alarmtr(){	signal(SIGALRM, alarmtr);	longjmp(Sjbuf, 1);}#define MR 4096expect(str)char *str;{	static char rdvec[MR];	register char *rp = rdvec;	int kr;	char nextch;	if (strcmp(str, "\"\"") == 0)		return(0);	*rp = 0;	if (setjmp(Sjbuf)) {		return(-1);	}	signal(SIGALRM, alarmtr);	alarm(10);	if(sldebug)		syslog(LOG_ERR,"expect %s\n", str);	while (notin(str, rdvec)) {		kr = read(fd, &nextch, 1);		if (kr <= 0) {			alarm(0);			return(-1);		}		{		int c;		c = nextch & 0177;		}		if ((*rp = nextch & 0177) != '\0')			rp++;		if (rp >= rdvec + MR) {			alarm(0);			return(-1);		}		*rp = '\0';	}	alarm(0);	return(0);}char par_tab[128];sendthem(str)char *str;{	register char *strptr;	int i=0;	int n, cr = 1;	static int p_init = 0;	if(!p_init) {		p_init++;		bld_partab(P_EVEN);	}	if(prefix("BREAK", str)) {		sscanf(&str[5], "%1d", &i);		if(i<=0 || i>10)			i=3;		genbrk(i);		return;	}	if(prefix("PAUSE", str)) {		sscanf(&str[5], "%1d", &i);		if(i<=0 || i>10)			i=3;		sleep((unsigned)i);		return;	}	if(strcmp(str, "EOT") == 0) {		p_chwrite('\04');		return;	}	/* Send a '\n' */	if (strcmp(str, "LF") == 0)		str = "\\n\\c";	/* Send a '\r' */	if (strcmp(str, "CR") == 0)		str = "\\r\\c";	/* Set parity as needed */	if (strcmp(str, "P_ZERO") == 0) {		bld_partab(P_ZERO);		return;	}	if (strcmp(str, "P_ONE") == 0) {		bld_partab(P_ONE);		return;	}	if (strcmp(str, "P_EVEN") == 0) {		bld_partab(P_EVEN);		return;	}	if (strcmp(str, "P_ODD") == 0) {		bld_partab(P_ODD);		return;	}	/* If "", just send '\r' */	if (strcmp(str, "\"\"") != 0)	for (strptr = str; *strptr; strptr++) {		if (*strptr == '\\') switch(*++strptr) {		case 's':			*strptr = ' ';			break;		case 'd':			sleep(1);			continue;		case 'r':			*strptr = '\r';			break;		case 'b':			if (isdigit(*(strptr+1))) {				i = (*++strptr - '0');				if (i <= 0 || i > 10)					i = 3;			} else				i = 3;			/* send break */			genbrk(i);			continue;		case 'c':			if (*(strptr+1) == '\0') {				cr = 0;				continue;			}			continue;		default:			if (isdigit(strptr[1])) {				i = 0;				n = 0;				while (isdigit(strptr[1]) && ++n <= 3)					i = i*8 + (*++strptr - '0');				p_chwrite(i);				continue;			}			strptr--;		}		p_chwrite(*strptr);	}	if (cr)		p_chwrite('\r');}p_chwrite(c)int c;{	char t[2];	t[0] = par_tab[c&0177];	t[1] = '\0';	write(fd, t, 1);}		/* * generate parity table for use by p_chwrite. */bld_partab(type)int type;{	register int i, j, n;	for (i = 0; i < sizeof(par_tab); i++) {		n = 0;		for (j = i&(sizeof(par_tab)-1); j; j = (j-1)&j)			n++;		par_tab[i] = i;		if (type == P_ONE		 || (type == P_EVEN && (n&01) != 0)		 || (type == P_ODD && (n&01) == 0))			par_tab[i] |= sizeof(par_tab);	}}notin(sh, lg)register char *sh, *lg;{        while (*lg != '\0') {                if (wprefix(sh, lg))                        return(0);                else			lg++;        }        return(1);}prefix(s1, s2)register char *s1, *s2;{	register char c;		while((c = *s1++) == *s2++)		if (c == '\0')			return(1);	return(c == '\0');}wprefix(s1, s2)register char *s1, *s2;{	register char c;	while ((c = *s1++) != '\0')		if (*s2 == '\0'  ||  (c != *s2++  &&  c != '?'))		return(0);	return(1);}#define STBNULL (struct sgttyb *) 0genbrk(bnulls)register int bnulls;{	register int ret;#ifdef  TIOCSBRK	ret = ioctl(fd, TIOCSBRK, STBNULL);#ifdef  TIOCCBRK	ret = write(fd, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls);	sleep(1);	ret = ioctl(fd, TIOCCBRK, STBNULL);#endif#endif}cleandeath(error){#ifdef notdef        if (ioctl(fd, TIOCSETD, &olddisc) < 0) {                fputs(dev, stderr);                perror(": restore discipline:");                syslog(LOG_INFO, "%s: restore discipline: %m", dev);        } else if (ioctl(fd, TIOCSETP, &otty) < 0) {                fputs(dev, stderr);                perror(": restore parameters:");                syslog(LOG_INFO, "%s: restore parameters: %m", dev);        }#endif        exit(error);}

⌨️ 快捷键说明

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