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

📄 tty.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 3 页
字号:
	}#endif /* __linux__ */	close(real_ttyfd);	real_ttyfd = -1;}/* * maybe_relock - our PID has changed, maybe update the lock file. */static voidmaybe_relock(arg, pid)    void *arg;    int pid;{    if (locked)	relock(pid);}/* * open_socket - establish a stream socket connection to the nominated * host and port. */static intopen_socket(dest)    char *dest;{    char *sep, *endp = NULL;    int sock, port = -1;    u_int32_t host;    struct hostent *hent;    struct sockaddr_in sad;    /* parse host:port and resolve host to an IP address */    sep = strchr(dest, ':');    if (sep != NULL)	port = strtol(sep+1, &endp, 10);    if (port < 0 || endp == sep+1 || sep == dest) {	error("Can't parse host:port for socket destination");	return -1;    }    *sep = 0;    host = inet_addr(dest);    if (host == (u_int32_t) -1) {	hent = gethostbyname(dest);	if (hent == NULL) {	    error("%s: unknown host in socket option", dest);	    *sep = ':';	    return -1;	}	host = *(u_int32_t *)(hent->h_addr_list[0]);    }    *sep = ':';    /* get a socket and connect it to the other end */    sock = socket(PF_INET, SOCK_STREAM, 0);    if (sock < 0) {	error("Can't create socket: %m");	return -1;    }    memset(&sad, 0, sizeof(sad));    sad.sin_family = AF_INET;    sad.sin_port = htons(port);    sad.sin_addr.s_addr = host;    if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) < 0) {	error("Can't connect to %s: %m", dest);	close(sock);	return -1;    }    return sock;}/* * start_charshunt - create a child process to run the character shunt. */static intstart_charshunt(ifd, ofd)    int ifd, ofd;{    int cpid;    cpid = safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2));    if (cpid == -1) {	error("Can't fork process for character shunt: %m");	return 0;    }    if (cpid == 0) {	/* child */	reopen_log();	if (!nodetach)	    log_to_fd = -1;	else if (log_to_fd >= 0)	    log_to_fd = 2;	setgid(getgid());	setuid(uid);	if (getuid() != uid)	    fatal("setuid failed");	charshunt(0, 1, record_file);	exit(0);    }    charshunt_pid = cpid;    record_child(cpid, "pppd (charshunt)", charshunt_done, NULL);    return 1;}static voidcharshunt_done(arg)    void *arg;{	charshunt_pid = 0;}static voidstop_charshunt(arg, sig)    void *arg;    int sig;{	if (charshunt_pid)		kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM));}/* * charshunt - the character shunt, which passes characters between * the pty master side and the serial port (or stdin/stdout). * This runs as the user (not as root). * (We assume ofd >= ifd which is true the way this gets called. :-). */static voidcharshunt(ifd, ofd, record_file)    int ifd, ofd;    char *record_file;{    int n, nfds;    fd_set ready, writey;    u_char *ibufp, *obufp;    int nibuf, nobuf;    int flags;    int pty_readable, stdin_readable;    struct timeval lasttime;    FILE *recordf = NULL;    int ilevel, olevel, max_level;    struct timeval levelt, tout, *top;    extern u_char inpacket_buf[];    /*     * Reset signal handlers.     */    signal(SIGHUP, SIG_IGN);		/* Hangup */    signal(SIGINT, SIG_DFL);		/* Interrupt */    signal(SIGTERM, SIG_DFL);		/* Terminate */    signal(SIGCHLD, SIG_DFL);    signal(SIGUSR1, SIG_DFL);    signal(SIGUSR2, SIG_DFL);    signal(SIGABRT, SIG_DFL);    signal(SIGALRM, SIG_DFL);    signal(SIGFPE, SIG_DFL);    signal(SIGILL, SIG_DFL);    signal(SIGPIPE, SIG_DFL);    signal(SIGQUIT, SIG_DFL);    signal(SIGSEGV, SIG_DFL);#ifdef SIGBUS    signal(SIGBUS, SIG_DFL);#endif#ifdef SIGEMT    signal(SIGEMT, SIG_DFL);#endif#ifdef SIGPOLL    signal(SIGPOLL, SIG_DFL);#endif#ifdef SIGPROF    signal(SIGPROF, SIG_DFL);#endif#ifdef SIGSYS    signal(SIGSYS, SIG_DFL);#endif#ifdef SIGTRAP    signal(SIGTRAP, SIG_DFL);#endif#ifdef SIGVTALRM    signal(SIGVTALRM, SIG_DFL);#endif#ifdef SIGXCPU    signal(SIGXCPU, SIG_DFL);#endif#ifdef SIGXFSZ    signal(SIGXFSZ, SIG_DFL);#endif    /*     * Check that the fds won't overrun the fd_sets     */    if (ifd >= FD_SETSIZE || ofd >= FD_SETSIZE || pty_master >= FD_SETSIZE)	fatal("internal error: file descriptor too large (%d, %d, %d)",	      ifd, ofd, pty_master);    /*     * Open the record file if required.     */    if (record_file != NULL) {	recordf = fopen(record_file, "a");	if (recordf == NULL)	    error("Couldn't create record file %s: %m", record_file);    }    /* set all the fds to non-blocking mode */    flags = fcntl(pty_master, F_GETFL);    if (flags == -1	|| fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1)	warn("couldn't set pty master to nonblock: %m");    flags = fcntl(ifd, F_GETFL);    if (flags == -1	|| fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1)	warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty"));    if (ofd != ifd) {	flags = fcntl(ofd, F_GETFL);	if (flags == -1	    || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1)	    warn("couldn't set stdout to nonblock: %m");    }    nibuf = nobuf = 0;    ibufp = obufp = NULL;    pty_readable = stdin_readable = 1;    ilevel = olevel = 0;    gettimeofday(&levelt, NULL);    if (max_data_rate) {	max_level = max_data_rate / 10;	if (max_level < 100)	    max_level = 100;    } else	max_level = PPP_MRU + PPP_HDRLEN + 1;    nfds = (ofd > pty_master? ofd: pty_master) + 1;    if (recordf != NULL) {	gettimeofday(&lasttime, NULL);	putc(7, recordf);	/* put start marker */	putc(lasttime.tv_sec >> 24, recordf);	putc(lasttime.tv_sec >> 16, recordf);	putc(lasttime.tv_sec >> 8, recordf);	putc(lasttime.tv_sec, recordf);	lasttime.tv_usec = 0;    }    while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) {	top = 0;	tout.tv_sec = 0;	tout.tv_usec = 10000;	FD_ZERO(&ready);	FD_ZERO(&writey);	if (nibuf != 0) {	    if (ilevel >= max_level)		top = &tout;	    else		FD_SET(pty_master, &writey);	} else if (stdin_readable)	    FD_SET(ifd, &ready);	if (nobuf != 0) {	    if (olevel >= max_level)		top = &tout;	    else		FD_SET(ofd, &writey);	} else if (pty_readable)	    FD_SET(pty_master, &ready);	if (select(nfds, &ready, &writey, NULL, top) < 0) {	    if (errno != EINTR)		fatal("select");	    continue;	}	if (max_data_rate) {	    double dt;	    int nbt;	    struct timeval now;	    gettimeofday(&now, NULL);	    dt = (now.tv_sec - levelt.tv_sec		  + (now.tv_usec - levelt.tv_usec) / 1e6);	    nbt = (int)(dt * max_data_rate);	    ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt;	    olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt;	    levelt = now;	} else	    ilevel = olevel = 0;	if (FD_ISSET(ifd, &ready)) {	    ibufp = inpacket_buf;	    nibuf = read(ifd, ibufp, PPP_MRU + PPP_HDRLEN);	    if (nibuf < 0 && errno == EIO)		nibuf = 0;	    if (nibuf < 0) {		if (!(errno == EINTR || errno == EAGAIN)) {		    error("Error reading standard input: %m");		    break;		}		nibuf = 0;	    } else if (nibuf == 0) {		/* end of file from stdin */		stdin_readable = 0;		if (recordf)		    if (!record_write(recordf, 4, NULL, 0, &lasttime))			recordf = NULL;	    } else {		FD_SET(pty_master, &writey);		if (recordf)		    if (!record_write(recordf, 2, ibufp, nibuf, &lasttime))			recordf = NULL;	    }	}	if (FD_ISSET(pty_master, &ready)) {	    obufp = outpacket_buf;	    nobuf = read(pty_master, obufp, PPP_MRU + PPP_HDRLEN);	    if (nobuf < 0 && errno == EIO)		nobuf = 0;	    if (nobuf < 0) {		if (!(errno == EINTR || errno == EAGAIN)) {		    error("Error reading pseudo-tty master: %m");		    break;		}		nobuf = 0;	    } else if (nobuf == 0) {		/* end of file from the pty - slave side has closed */		pty_readable = 0;		stdin_readable = 0;	/* pty is not writable now */		nibuf = 0;		close(ofd);		if (recordf)		    if (!record_write(recordf, 3, NULL, 0, &lasttime))			recordf = NULL;	    } else {		FD_SET(ofd, &writey);		if (recordf)		    if (!record_write(recordf, 1, obufp, nobuf, &lasttime))			recordf = NULL;	    }	} else if (!stdin_readable)	    pty_readable = 0;	if (FD_ISSET(ofd, &writey)) {	    n = nobuf;	    if (olevel + n > max_level)		n = max_level - olevel;	    n = write(ofd, obufp, n);	    if (n < 0) {		if (errno == EIO) {		    pty_readable = 0;		    nobuf = 0;		} else if (errno != EAGAIN && errno != EINTR) {		    error("Error writing standard output: %m");		    break;		}	    } else {		obufp += n;		nobuf -= n;		olevel += n;	    }	}	if (FD_ISSET(pty_master, &writey)) {	    n = nibuf;	    if (ilevel + n > max_level)		n = max_level - ilevel;	    n = write(pty_master, ibufp, n);	    if (n < 0) {		if (errno == EIO) {		    stdin_readable = 0;		    nibuf = 0;		} else if (errno != EAGAIN && errno != EINTR) {		    error("Error writing pseudo-tty master: %m");		    break;		}	    } else {		ibufp += n;		nibuf -= n;		ilevel += n;	    }	}    }    exit(0);}static intrecord_write(f, code, buf, nb, tp)    FILE *f;    int code;    u_char *buf;    int nb;    struct timeval *tp;{    struct timeval now;    int diff;    gettimeofday(&now, NULL);    now.tv_usec /= 100000;	/* actually 1/10 s, not usec now */    diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec);    if (diff > 0) {	if (diff > 255) {	    putc(5, f);	    putc(diff >> 24, f);	    putc(diff >> 16, f);	    putc(diff >> 8, f);	    putc(diff, f);	} else {	    putc(6, f);	    putc(diff, f);	}	*tp = now;    }    putc(code, f);    if (buf != NULL) {	putc(nb >> 8, f);	putc(nb, f);	fwrite(buf, nb, 1, f);    }    fflush(f);    if (ferror(f)) {	error("Error writing record file: %m");	return 0;    }    return 1;}

⌨️ 快捷键说明

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