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

📄 rtemsmain.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * main.c - Point-to-Point Protocol main module * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#define RCSID	"$Id: rtemsmain.c,v 1.3.4.1 2003/04/10 13:09:09 joel Exp $"#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <errno.h>#include <fcntl.h>#include <netdb.h>#include <pwd.h>#include <setjmp.h>#include <sys/param.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/stat.h>#include <sys/socket.h>#include <netinet/in.h>#include <rtems.h>#include <rtems/rtems_bsdnet.h>#include "pppd.h"#include "magic.h"#include "fsm.h"#include "lcp.h"#include "ipcp.h"#ifdef INET6#include "ipv6cp.h"#endif#include "upap.h"#include "chap.h"#include "ccp.h"#include "pathnames.h"#include "patchlevel.h"#include "rtemsdialer.h"#ifdef CBCP_SUPPORT#include "cbcp.h"#endif#ifdef IPX_CHANGE#include "ipxcp.h"#endif /* IPX_CHANGE */#ifdef AT_CHANGE#include "atcp.h"#endifstatic const char rcsid[] = RCSID;/* interface vars */char ifname[32];		/* Interface name */int pppifunit;			/* Interface unit number */char hostname[MAXNAMELEN];	/* Our hostname */static char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */int ttyfd;			/* Serial port file descriptor */int baud_rate;			/* Actual bits/second for serial device */int hungup;			/* terminal has been hung up */int privileged;			/* we're running as real uid root */int need_holdoff;		/* need holdoff period before restarting */int detached;			/* have detached from terminal */struct stat devstat;		/* result of stat() on devnam */int prepass = 0;		/* doing prepass to find device name */int devnam_fixed;		/* set while in options.ttyxx file */volatile int pppd_status;		/* exit status for pppd */int unsuccess;			/* # unsuccessful connection attempts */int do_callback;		/* != 0 if we should do callback next */int doing_callback;		/* != 0 if we are doing callback */char *callback_script;		/* script for doing callback */dialerfp pppd_dialer;int (*holdoff_hook) __P((void)) = NULL;int (*new_phase_hook) __P((int)) = NULL;static int fd_ppp = -1;		/* fd for talking PPP */static int pty_master;		/* fd for master side of pty */static int pty_slave;		/* fd for slave side of pty */static int real_ttyfd;		/* fd for actual serial port (not pty) */int pppd_phase;			/* where the link is at */int pppd_kill_link;int open_ccp_flag;char **script_env;		/* Env. variable values for scripts */int s_env_nalloc;		/* # words avail at script_env */u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";static struct timeval start_time;	/* Time when link was started. */struct pppd_stats link_stats;int link_connect_time;int link_stats_valid;/* Prototypes for procedures local to this file. */static void cleanup __P((void));static void close_tty __P((void));static void get_input __P((void));static void calltimeout __P((void));static struct timeval *timeleft __P((struct timeval *));static void holdoff_end __P((void *));static int device_script __P((int, int, char *));extern	char	*ttyname __P((int));extern	char	*getlogin __P((void));int pppdmain __P((int, char *[]));/* * PPP Data Link Layer "protocol" table. * One entry per supported protocol. * The last entry must be NULL. */struct protent *protocols[] = {    &lcp_protent,    &pap_protent,    &chap_protent,#ifdef CBCP_SUPPORT    &cbcp_protent,#endif    &ipcp_protent,#ifdef INET6    &ipv6cp_protent,#endif    &ccp_protent,#ifdef IPX_CHANGE    &ipxcp_protent,#endif#ifdef AT_CHANGE    &atcp_protent,#endif    NULL};intpppdmain(argc, argv)    int argc;    char *argv[];{    int i, fdflags, t;    char *connector;    struct timeval timo;    struct protent *protp;    new_phase(PHASE_INITIALIZE);    script_env = NULL;    hostname[MAXNAMELEN-1] = 0;    privileged = 1;    privileged_option = 1;    /*     * Initialize magic number generator now so that protocols may     * use magic numbers in initialization.     */    magic_init();#ifdef XXX_XXX    /* moved code the the rtems_pppd_reset_options function */    /*     * Initialize to the standard option set, then parse, in order,     * the system options file, the user's options file,     * the tty's options file, and the command line arguments.     */    for (i = 0; (protp = protocols[i]) != NULL; ++i)        (*protp->init)(0);#endif    if (!ppp_available()) {	option_error(no_ppp_msg);	return(EXIT_NO_KERNEL_SUPPORT);    }    /*     * Check that the options given are valid and consistent.     */    if (!sys_check_options()) {	return(EXIT_OPTION_ERROR);    }    if (!auth_check_options()) {	return(EXIT_OPTION_ERROR);    }    for (i = 0; (protp = protocols[i]) != NULL; ++i)	if (protp->check_options != NULL)	    (*protp->check_options)();    /* default holdoff to 0 if no connect script has been given */    if (connect_script == 0 && !holdoff_specified)	holdoff = 0;    if (default_device)	nodetach = 1;    /*     * Initialize system-dependent stuff.     */    sys_init();    /* if (debug)	setlogmask(LOG_UPTO(LOG_DEBUG));    */    do_callback = 0;    for (;;) {	need_holdoff = 1;	ttyfd = -1;	real_ttyfd = -1;	pppd_status = EXIT_OK;	++unsuccess;	doing_callback = do_callback;	do_callback = 0;	new_phase(PHASE_SERIALCONN);	/*	 * Get a pty master/slave pair if the pty, notty, or record	 * options were specified.	 */	strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));	pty_master = -1;	pty_slave = -1;	/*	 * Open the serial device and set it up to be the ppp interface.	 * First we open it in non-blocking mode so we can set the	 * various termios flags appropriately.  If we aren't dialling	 * out and we want to use the modem lines, we reopen it later	 * in order to wait for the carrier detect signal from the modem.	 */	hungup = 0;	pppd_kill_link = 0;	connector = doing_callback? callback_script: connect_script;	if (devnam[0] != 0) {	    for (;;) {		/* If the user specified the device name, become the		   user before opening it. */		int err;		ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);		err = errno;		if (ttyfd >= 0) {		    break;		}		errno = err;		if (err != EINTR) {		    error("Failed to open %s: %m", devnam);		    pppd_status = EXIT_OPEN_FAILED;		}		if (!persist || err != EINTR)		    goto fail;	    }	    if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1		|| fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)		warn("Couldn't reset non-blocking mode on device: %m");	    /*	     * Set line speed, flow control, etc.	     * If we have a non-null connection or initializer script,	     * on most systems we set CLOCAL for now so that we can talk	     * to the modem before carrier comes up.  But this has the	     * side effect that we might miss it if CD drops before we	     * get to clear CLOCAL below.  On systems where we can talk	     * successfully to the modem with CLOCAL clear and CD down,	     * we could clear CLOCAL at this point.	     */	    set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0)			       || initializer != NULL));	    real_ttyfd = ttyfd;	}	/* run connection script */	if ((connector && connector[0]) || initializer) {	    if (real_ttyfd != -1) {		/* XXX do this if doing_callback == CALLBACK_DIALIN? */		if (!default_device && modem) {		    setdtr(real_ttyfd, 0);	/* in case modem is off hook */		    sleep(1);		    setdtr(real_ttyfd, 1);		}	    }	    if (initializer && initializer[0]) {		if (device_script(ttyfd, DIALER_INIT, initializer) < 0) {		    error("Initializer script failed");		    pppd_status = EXIT_INIT_FAILED;		    goto fail;		}		if (pppd_kill_link)		    goto disconnect;		info("Serial port initialized.");	    }	    if (connector && connector[0]) {		if (device_script(ttyfd, DIALER_CONNECT, connector) < 0) {		    error("Connect script failed");		    pppd_status = EXIT_CONNECT_FAILED;		    goto fail;		}		if (pppd_kill_link)		    goto disconnect;		info("Serial connection established.");	    }	    /* set line speed, flow control, etc.;	       clear CLOCAL if modem option */	    if (real_ttyfd != -1)		set_up_tty(real_ttyfd, 0);	    if (doing_callback == CALLBACK_DIALIN)		connector = NULL;	}	/* reopen tty if necessary to wait for carrier */	if (connector == NULL && modem && devnam[0] != 0) {	    for (;;) {		if ((i = open(devnam, O_RDWR)) >= 0)		    break;		if (errno != EINTR) {		    error("Failed to reopen %s: %m", devnam);		    pppd_status = EXIT_OPEN_FAILED;		}		if (!persist || errno != EINTR || hungup || pppd_kill_link)		    goto fail;	    }	    close(i);	}        info("Serial connection established.");        sleep(1);	/* run welcome script, if any */	if (welcomer && welcomer[0]) {	    if (device_script(ttyfd, DIALER_WELCOME, welcomer) < 0)		warn("Welcome script failed");	}	/* set up the serial device as a ppp interface */	fd_ppp = establish_ppp(ttyfd);	if (fd_ppp < 0) {	    pppd_status = EXIT_FATAL_ERROR;	    goto disconnect;	}	if (!demand) {	    info("Using interface ppp%d", pppifunit);	    slprintf(ifname, sizeof(ifname), "ppp%d", pppifunit);	}	/*	 * Start opening the connection and wait for	 * incoming events (reply, timeout, etc.).	 */	notice("Connect: %s <--> %s", ifname, ppp_devnam);	gettimeofday(&start_time, NULL);	lcp_lowerup(0);	lcp_open(0);		/* Start protocol */	open_ccp_flag = 0;	pppd_status = EXIT_NEGOTIATION_FAILED;	new_phase(PHASE_ESTABLISH);	while (pppd_phase != PHASE_DEAD) {   	    wait_input(timeleft(&timo));	    calltimeout();            get_input();	    if (pppd_kill_link) {		lcp_close(0, "User request");		pppd_kill_link = 0;	    }	    if (open_ccp_flag) {		if (pppd_phase == PHASE_NETWORK || pppd_phase == PHASE_RUNNING) {		    ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */		    (*ccp_protent.open)(0);		}		open_ccp_flag = 0;	    }	}	/*	 * If we may want to bring the link up again, transfer	 * the ppp unit back to the loopback.  Set the	 * real serial device back to its normal mode of operation.	 */	clean_check();	if (demand)	    restore_loop();	disestablish_ppp(ttyfd);	fd_ppp = -1;	if (!hungup)	    lcp_lowerdown(0);	/*	 * Run disconnector script, if requested.	 * XXX we may not be able to do this if the line has hung up!	 */    disconnect:	if (disconnect_script && !hungup) {	    new_phase(PHASE_DISCONNECT);	    if (real_ttyfd >= 0)		set_up_tty(real_ttyfd, 1);	    if (device_script(ttyfd, DIALER_DISCONNECT, disconnect_script) < 0) {		warn("disconnect script failed");	    } else {		info("Serial link disconnected.");	    }	}    fail:	if (pty_master >= 0)	    close(pty_master);	if (pty_slave >= 0)	    close(pty_slave);	if (real_ttyfd >= 0)	    close_tty();	if (!persist || (maxfail > 0 && unsuccess >= maxfail))	    break;

⌨️ 快捷键说明

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