slattach.c

来自「Linux下网络相关工具源代码。」· C语言 代码 · 共 724 行 · 第 1/2 页

C
724
字号
tty_set_state(struct termios *tty){  if (ioctl(tty_fd, TCSETS, tty) < 0) {	if (opt_q == 0) fprintf(stderr,		"slattach: tty_set_state: %s\n", strerror(errno));	return(-errno);  }  return(0);}/* Get the line discipline of a terminal line. */static inttty_get_disc(int *disc){  if (ioctl(tty_fd, TIOCGETD, disc) < 0) {	if (opt_q == 0) fprintf(stderr,		"slattach: tty_get_disc: %s\n", strerror(errno));	return(-errno);  }  return(0);}/* Set the line discipline of a terminal line. */static inttty_set_disc(int disc){  if (disc == -1) disc = tty_sdisc;  if (ioctl(tty_fd, TIOCSETD, &disc) < 0) {	if (opt_q == 0) fprintf(stderr,		"slattach: tty_set_disc(%d, %d): %s\n", tty_fd,			disc, strerror(errno));	return(-errno);  }  return(0);}/* Fetch the name of the network interface attached to this terminal. */static inttty_get_name(char *name){  if (ioctl(tty_fd, SIOCGIFNAME, name) < 0) {	if (opt_q == 0) fprintf(stderr,		"slattach: tty_get_name: %s\n", strerror(errno));	return(-errno);  }  return(0);}/* Hangup the line. */static inttty_hangup(void){  struct termios tty;  tty = tty_current;  (void) tty_set_speed(&tty, "0");  if (tty_set_state(&tty) < 0) {	if (opt_q == 0) fprintf(stderr, _("slattach: tty_hangup(DROP): %s\n"), strerror(errno));	return(-errno);  }  (void) sleep(1);  if (tty_set_state(&tty_current) < 0) {	if (opt_q == 0) fprintf(stderr, _("slattach: tty_hangup(RAISE): %s\n"), strerror(errno));	return(-errno);  }  return(0);}/* Close down a terminal line. */static inttty_close(void){  (void) tty_set_disc(tty_sdisc);  (void) tty_hangup();  (void) tty_lock(NULL, 0);  return(0);}/* Open and initialize a terminal line. */static inttty_open(char *name, char *speed){  char path[PATH_MAX];  register char *sp;  int fd;  /* Try opening the TTY device. */  if (name != NULL) {	if ((sp = strrchr(name, '/')) != (char *)NULL) *sp++ = '\0';	  else sp = name;	sprintf(path, "/dev/%s", sp);	if (tty_lock(sp, 1)) return(-1); /* can we lock the device? */	if ((fd = open(path, O_RDWR)) < 0) {		if (opt_q == 0) fprintf(stderr,			"slattach: tty_open(%s, RW): %s\n",					path, strerror(errno));		return(-errno);	}	tty_fd = fd;	if (opt_d) printf("slattach: tty_open: %s (%d) ", path, fd);  } else {	tty_fd = 0;	sp = (char *)NULL;  }  /* Fetch the current state of the terminal. */  if (tty_get_state(&tty_saved) < 0) {	if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot get current state!\n"));	return(-errno);  }  tty_current = tty_saved;  /* Fetch the current line discipline of this terminal. */  if (tty_get_disc(&tty_sdisc) < 0) {	if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot get current line disc!\n"));	return(-errno);  }   tty_ldisc = tty_sdisc;  /* Put this terminal line in a 8-bit transparent mode. */  if (opt_m == 0) {	if (tty_set_raw(&tty_current) < 0) {		if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot set RAW mode!\n"));		return(-errno);	}	/* Set the default speed if we need to. */	if (speed != NULL) {		if (tty_set_speed(&tty_current, speed) != 0) {			if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot set %s bps!\n"),						speed);			return(-errno);		}	}	/* Set up a completely 8-bit clean line. */	if (tty_set_databits(&tty_current, "8") ||	    tty_set_stopbits(&tty_current, "1") ||	    tty_set_parity(&tty_current, "N")) {		if (opt_q == 0) fprintf(stderr, _("slattach: tty_open: cannot set 8N1 mode!\n"));		return(-errno);  	}	/* Set the new line mode. */	if ((fd = tty_set_state(&tty_current)) < 0) return(fd);  }  /* OK, line is open.  Do we need to "silence" it? */  (void) tty_nomesg(tty_fd);  return(0);}/* Catch any signals. */static voidsig_catch(int sig){/*  (void) signal(sig, sig_catch); */  tty_close();  exit(0);}static voidusage(void){  char *usage_msg = "Usage: slattach [-ehlLmnqv] "#ifdef SIOCSKEEPALIVE	  "[-k keepalive] "#endif#ifdef SIOCSOUTFILL	  "[-o outfill] "#endif	  "[-c cmd] [-s speed] [-p protocol] tty | -\n"	  "       slattach -V | --version\n";  fprintf(stderr, usage_msg);  exit(1);}static void version(void){    printf("%s\n%s\n%s\n", Release, Version, Signature);    exit(E_VERSION);}intmain(int argc, char *argv[]){  char path[128];  char buff[128];  char *speed = NULL;  char *proto = DEF_PROTO;  char *extcmd = (char *)0;  struct hwtype *ht;  char *sp;  int s;  static struct option longopts[] = {    { "version", 0, NULL, 'V' },    { NULL, 0, NULL, 0 }  };  strcpy(path, "");  /* Scan command line for any arguments. */  opterr = 0;  while ((s = getopt_long(argc, argv, "c:ehlLmnp:qs:vdVk:o:", longopts, NULL)) != EOF) switch(s) {	case 'c':		extcmd = optarg;		break;	case 'e':		opt_e = 1 - opt_e;		break;	case 'h':		opt_h = 1 - opt_h;		break;#ifdef SIOCSKEEPALIVE	case 'k':		opt_k = atoi(optarg);		break;#endif	case 'L':		opt_L = 1 - opt_L;		break;	case 'l':		opt_l = 1 - opt_l;		break;	case 'm':		opt_m = 1 - opt_m;		break;	case 'n':		opt_n = 1 - opt_n;		break;#ifdef SIOCSOUTFILL	case 'o':		opt_o = atoi(optarg);		break;#endif	case 'p':		proto = optarg;		break;	case 'q':		opt_q = 1 - opt_q;		break;	case 's':		speed = optarg;		break;	case 'd':		opt_d = 1 - opt_d;		break;	case 'v':		opt_v = 1 - opt_v;		break;        case 'V':		version();		/*NOTREACHED*/	default:		usage();		/*NOTREACHED*/  }    activate_init();  /* Check the protocol. */  if ((ht = get_hwtype(proto)) == NULL && strcmp(proto, "tty")) {	if (opt_q == 0) fprintf(stderr, _("slattach: unsupported protocol %s\n"), proto);	return(2);  }  if (ht == NULL) opt_m++;  /* Is a terminal given? */  if (optind != (argc - 1)) usage();  strncpy(path, argv[optind], 128);  if (!strcmp(path, "-")) {	opt_e = 1;	sp = NULL;	if (tty_open(NULL, speed) < 0) { return(3); }  } else {	if ((sp = strrchr(path, '/')) != NULL) *sp++ = '\0';	  else sp = path;	if (tty_open(sp, speed) < 0) { return(3); }  }  /* Start the correct protocol. */  if (ht == NULL) {	tty_sdisc = N_TTY;	tty_close();	return(0);  }  (*ht->activate)(tty_fd);  if (opt_v == 1) {	tty_get_name(buff);	printf(_("%s started"), proto);	if (sp != NULL) printf(_(" on %s"), sp);	printf(_(" interface %s\n"), buff);  }  /* Configure keepalive and outfill. */#ifdef SIOCSKEEPALIVE  if (opt_k && (ioctl(tty_fd, SIOCSKEEPALIVE, &opt_k) < 0))	  fprintf(stderr, "slattach: ioctl(SIOCSKEEPALIVE): %s\n", strerror(errno));#endif#ifdef SIOCSOUTFILL  if (opt_o && (ioctl(tty_fd, SIOCSOUTFILL, &opt_o) < 0))	  fprintf(stderr, "slattach: ioctl(SIOCSOUTFILL): %s\n", strerror(errno));#endif  (void) signal(SIGHUP, sig_catch);  (void) signal(SIGINT, sig_catch);  (void) signal(SIGQUIT, sig_catch);  (void) signal(SIGTERM, sig_catch);  /* Wait until we get killed if hanging on a terminal. */  if (opt_e == 0) {	while(1) {		if(opt_h == 1) { /* hangup on carrier loss */			int n = 0;		        ioctl(tty_fd, TIOCMGET, &n);			if(!(n & TIOCM_CAR))				break;			sleep(15);		}		else			sleep(60);	};	tty_close();	if(extcmd!=(char *)0) /* external command on exit */		system(extcmd);  }  exit(0);}

⌨️ 快捷键说明

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