fprintf(stderr, "%s: connect script required for demand-dialling\n", progname);
option_error("connect script required for demand-dialling\n");
main(argc, argv)    int argc;    char *argv[];{    int i, nonblock, fdflags;    struct sigaction sa;    FILE *pidfile;    char *p;    struct passwd *pw;    struct timeval timo;    sigset_t mask;    struct protent *protp;    struct stat statbuf;    phase = PHASE_INITIALIZE;    p = ttyname(0);    if (p)	strcpy(devnam, p);    strcpy(default_devnam, devnam);    /* Initialize syslog facilities */#ifdef PRIMITIVE_SYSLOG    openlog("pppd", LOG_PID);#else    openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);    setlogmask(LOG_UPTO(LOG_INFO));#endif    if (gethostname(hostname, MAXNAMELEN) < 0 ) {        syslog(LOG_ERR, "couldn't get hostname: %m");	die(1);    }    hostname[MAXNAMELEN-1] = 0;    uid = getuid();    /*     * 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);      progname = *argv;    if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0)        || !options_from_user())        exit(1);    scan_args(argc-1, argv+1);  /* look for tty name on command line */    if (!options_for_tty()        || !parse_args(argc-1, argv+1))	exit(1);    if (!ppp_available()) {	fprintf(stderr, no_ppp_msg);	exit(1);    }    /*     * Check that the options given are valid and consistent.     */    sys_check_options();    auth_check_options();    for (i = 0; (protp = protocols[i]) != NULL; ++i)	if (protp->check_options != NULL)	    (*protp->check_options)();    if (demand && connector == 0) {	fprintf(stderr, "%s: connect script required for demand-dialling\n",		progname);	exit(1);    }    /*     * If the user has specified the default device name explicitly,     * pretend they hadn't.     */    if (!default_device && strcmp(devnam, default_devnam) == 0)	default_device = 1;    redirect_stderr = !nodetach || default_device;    /*     * Initialize system-dependent stuff and magic number package.     */    sys_init();    magic_init();    if (debug)      setlogmask(LOG_UPTO(LOG_DEBUG));    /*     * Detach ourselves from the terminal, if required,     * and identify who is running us.     */    if (!default_device && !nodetach && daemon(0, 0) < 0) {	perror("Couldn't detach from controlling terminal");	exit(1);    }    pid = getpid();    p = getlogin();    if (p == NULL) {	pw = getpwuid(uid);	if (pw != NULL && pw->pw_name != NULL)	    p = pw->pw_name;	else	    p = "(unknown)";    }    syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d",	   VERSION, PATCHLEVEL, p, uid);      /*     * Compute mask of all interesting signals and install signal handlers     * for each.  Only one signal handler may be active at a time.  Therefore,     * all other signals should be masked when any handler is executing.     */    sigemptyset(&mask);    sigaddset(&mask, SIGHUP);    sigaddset(&mask, SIGINT);    sigaddset(&mask, SIGTERM);    sigaddset(&mask, SIGCHLD);#define SIGNAL(s, handler)	{ \	sa.sa_handler = handler; \	if (sigaction(s, &sa, NULL) < 0) { \	    syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \	    die(1); \	} \    }    sa.sa_mask = mask;    sa.sa_flags = 0;    SIGNAL(SIGHUP, hup);		/* Hangup */    SIGNAL(SIGINT, term);		/* Interrupt */    SIGNAL(SIGTERM, term);		/* Terminate */    SIGNAL(SIGCHLD, chld);    SIGNAL(SIGUSR1, toggle_debug);	/* Toggle debug flag */    SIGNAL(SIGUSR2, open_ccp);		/* Reopen CCP */    /*     * Install a handler for other signals which would otherwise     * cause pppd to exit without cleaning up.     */    SIGNAL(SIGABRT, bad_signal);    SIGNAL(SIGALRM, bad_signal);    SIGNAL(SIGFPE, bad_signal);    SIGNAL(SIGILL, bad_signal);    SIGNAL(SIGPIPE, bad_signal);    SIGNAL(SIGQUIT, bad_signal);    SIGNAL(SIGSEGV, bad_signal);#ifdef SIGBUS    SIGNAL(SIGBUS, bad_signal);#endif#ifdef SIGEMT    SIGNAL(SIGEMT, bad_signal);#endif#ifdef SIGPOLL    SIGNAL(SIGPOLL, bad_signal);#endif#ifdef SIGPROF    SIGNAL(SIGPROF, bad_signal);#endif#ifdef SIGSYS    SIGNAL(SIGSYS, bad_signal);#endif#ifdef SIGTRAP    SIGNAL(SIGTRAP, bad_signal);#endif#ifdef SIGVTALRM    SIGNAL(SIGVTALRM, bad_signal);#endif#ifdef SIGXCPU    SIGNAL(SIGXCPU, bad_signal);#endif#ifdef SIGXFSZ    SIGNAL(SIGXFSZ, bad_signal);#endif    /*     * Apparently we can get a SIGPIPE when we call syslog, if     * syslogd has died and been restarted.  Ignoring it seems     * be sufficient.     */    signal(SIGPIPE, SIG_IGN);    /*     * If we're doing dial-on-demand, set up the interface now.     */    if (demand) {	/*	 * Open the loopback channel and set it up to be the ppp interface.	 */	open_ppp_loopback();	syslog(LOG_INFO, "Using interface ppp%d", ifunit);	(void) sprintf(ifname, "ppp%d", ifunit);	/* write pid to file */	(void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);	if ((pidfile = fopen(pidfilename, "w")) != NULL) {	    fprintf(pidfile, "%d\n", pid);	    (void) fclose(pidfile);	} else {	    syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename);	    pidfilename[0] = 0;	}	/*	 * Configure the interface and mark it up, etc.	 */	demand_conf();    }    for (;;) {	if (demand) {	    /*	     * Don't do anything until we see some activity.	     */	    phase = PHASE_DORMANT;	    kill_link = 0;	    demand_unblock();	    for (;;) {		wait_loop_output(timeleft(&timo));		calltimeout();		if (kill_link) {		    if (!persist)			die(0);		    kill_link = 0;		}		if (get_loop_output())		    break;		reap_kids();	    }	    /*	     * Now we want to bring up the link.	     */	    demand_block();	    syslog(LOG_INFO, "Starting link");	}	/*	 * Lock the device if we've been asked to.	 */	if (lockflag && !default_device) {	    if (lock(devnam) < 0)		goto fail;	    locked = 1;	}	/*	 * Open the serial device and set it up to be the ppp interface.	 * If we're dialling out, or we don't want to use the modem lines,	 * we open it in non-blocking mode, but then we need to clear	 * the non-blocking I/O bit.	 */	nonblock = (connector || !modem)? O_NONBLOCK: 0;	if ((ttyfd = open(devnam, nonblock | O_RDWR, 0)) < 0) {	    syslog(LOG_ERR, "Failed to open %s: %m", devnam);	    goto fail;	}	if (nonblock) {	    if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1		|| fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)		syslog(LOG_WARNING,		       "Couldn't reset non-blocking mode on device: %m");	}	hungup = 0;	kill_link = 0;        /*         * Do the equivalent of `mesg n' to stop broadcast messages.         */        if (fstat(ttyfd, &statbuf) < 0            || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {            syslog(LOG_WARNING,                   "Couldn't restrict write permissions to %s: %m", devnam);        } else            tty_mode = statbuf.st_mode;	/* run connection script */	if (connector && connector[0]) {	    MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));	    /* set line speed, flow control, etc.; set CLOCAL for now */	    set_up_tty(ttyfd, 1);	    /* drop dtr to hang up in case modem is off hook */	    if (!default_device && modem) {		setdtr(ttyfd, FALSE);		sleep(1);		setdtr(ttyfd, TRUE);	    }	    if (device_script(connector, ttyfd, ttyfd) < 0) {		syslog(LOG_ERR, "Connect script failed");		setdtr(ttyfd, FALSE);		goto fail;	    }	    syslog(LOG_INFO, "Serial connection established.");	    sleep(1);		/* give it time to set up its terminal */	}	/* set line speed, flow control, etc.; clear CLOCAL if modem option */	set_up_tty(ttyfd, 0);	/* run welcome script, if any */	if (welcomer && welcomer[0]) {	    if (device_script(welcomer, ttyfd, ttyfd) < 0)		syslog(LOG_WARNING, "Welcome script failed");	}	/* set up the serial device as a ppp interface */	establish_ppp(ttyfd);	if (!demand) {	    	    syslog(LOG_INFO, "Using interface ppp%d", ifunit);	    (void) sprintf(ifname, "ppp%d", ifunit);	    	    /* write pid to file */	    (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);	    if ((pidfile = fopen(pidfilename, "w")) != NULL) {		fprintf(pidfile, "%d\n", pid);		(void) fclose(pidfile);	    } else {		syslog(LOG_ERR, "Failed to create pid file %s: %m",		       pidfilename);		pidfilename[0] = 0;	    }	}	/*	 * Set a timeout to close the connection once the maximum	 * connect time has expired.	 */	if (maxconnect > 0)	    TIMEOUT(connect_time_expired, 0, maxconnect);	/*	 * Start opening the connection and wait for	 * incoming events (reply, timeout, etc.).	 */	syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam);	lcp_lowerup(0);	lcp_open(0);		/* Start protocol */	for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {	    wait_input(timeleft(&timo));	    calltimeout();	    get_input();	    if (kill_link) {		lcp_close(0, "User request");		phase = PHASE_TERMINATE;		kill_link = 0;	    }	    if (open_ccp_flag) {		if (phase == PHASE_NETWORK) {		    ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */                    (*ccp_protent.open)(0);		}		open_ccp_flag = 0;	    }	    reap_kids();	/* Don't leave dead kids lying around */	}	/*	 * 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);	/*	 * Run disconnector script, if requested.	 * XXX we may not be able to do this if the line has hung up!	 */	if (disconnector && !hungup) {	    set_up_tty(ttyfd, 1);	    if (device_script(disconnector, ttyfd, ttyfd) < 0) {		syslog(LOG_WARNING, "disconnect script failed");	    } else {		syslog(LOG_INFO, "Serial link disconnected.");	    }	}    fail:	close_tty();	if (locked) {	    unlock();	    locked = 0;	}	if (!demand) {            if (pidfilename[0] != 0                && unlink(pidfilename) < 0 && errno != ENOENT)		syslog(LOG_WARNING, "unable to delete pid file: %m");	    pidfilename[0] = 0;	}	if (!persist)	    die(1);	if (demand)	    demand_discard();	if (holdoff > 0) {	    phase = PHASE_HOLDOFF;	    TIMEOUT(holdoff_end, NULL, holdoff);	    do {		wait_time(timeleft(&timo));		calltimeout();		if (kill_link) {		    if (!persist)			die(0);		    kill_link = 0;		    phase = PHASE_DORMANT; /* allow signal to end holdoff */		}		reap_kids();	    } while (phase == PHASE_HOLDOFF);	}    }    die(0);}