xref: /titanic_41/usr/src/cmd/cmd-inet/usr.bin/pppd/main.c (revision b509e89b2befbaa42939abad9da1d7f5a8c6aaae)
1 /*
2  * main.c - Point-to-Point Protocol main module
3  *
4  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5  * Use is subject to license terms.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation is hereby granted, provided that the above copyright
9  * notice appears in all copies.
10  *
11  * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
12  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
13  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  SUN SHALL NOT BE LIABLE FOR
15  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
16  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
17  *
18  * Copyright (c) 1989 Carnegie Mellon University.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms are permitted
22  * provided that the above copyright notice and this paragraph are
23  * duplicated in all such forms and that any documentation,
24  * advertising materials, and other materials related to such
25  * distribution and use acknowledge that the software was developed
26  * by Carnegie Mellon University.  The name of the
27  * University may not be used to endorse or promote products derived
28  * from this software without specific prior written permission.
29  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
30  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
31  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  */
33 
34 #define RCSID	"$Id: main.c,v 1.97 2000/04/24 02:54:16 masputra Exp $"
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <signal.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <syslog.h>
44 #include <netdb.h>
45 #include <pwd.h>
46 #include <setjmp.h>
47 #include <sys/param.h>
48 #include <sys/types.h>
49 #include <sys/wait.h>
50 #include <sys/time.h>
51 #include <sys/resource.h>
52 #include <sys/stat.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 
57 #include "pppd.h"
58 #include "magic.h"
59 #include "fsm.h"
60 #include "lcp.h"
61 #include "ipcp.h"
62 #ifdef INET6
63 #include "ipv6cp.h"
64 #endif
65 #include "upap.h"
66 #include "chap.h"
67 #include "ccp.h"
68 #include "pathnames.h"
69 #include "patchlevel.h"
70 
71 #ifdef HAVE_MULTILINK
72 #include "tdb.h"
73 #endif
74 
75 #ifdef CBCP_SUPPORT
76 #include "cbcp.h"
77 #endif
78 
79 #ifdef IPX_CHANGE
80 #include "ipxcp.h"
81 #endif /* IPX_CHANGE */
82 #ifdef AT_CHANGE
83 #include "atcp.h"
84 #endif
85 
86 #if !defined(lint) && !defined(_lint)
87 static const char rcsid[] = RCSID;
88 #endif
89 
90 /* interface vars */
91 char ifname[32];		/* Interface name */
92 int ifunit = -1;		/* Interface unit number */
93 
94 char *progname;			/* Name of this program */
95 char hostname[MAXHOSTNAMELEN+1]; /* Our hostname */
96 static char pidfilename[MAXPATHLEN]; /* name of pid file */
97 static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */
98 char ppp_devnam[MAXPATHLEN];	/* name of PPP tty (maybe ttypx) */
99 static uid_t uid;		/* Our real user-id */
100 static int conn_running;	/* we have a [dis]connector running */
101 
102 int ttyfd;			/* Serial port file descriptor */
103 mode_t tty_mode = (mode_t)-1;	/* Original access permissions to tty */
104 int baud_rate;			/* Actual bits/second for serial device */
105 bool hungup;			/* terminal has been hung up */
106 bool privileged;		/* we're running as real uid root */
107 bool need_holdoff;		/* need holdoff period before restarting */
108 bool detached;			/* have detached from terminal */
109 struct stat devstat;		/* result of stat() on devnam */
110 bool prepass = 0;		/* doing prepass to find device name */
111 int devnam_fixed;		/* set while in options.ttyxx file */
112 volatile int status;		/* exit status for pppd */
113 int unsuccess;			/* # unsuccessful connection attempts */
114 int do_callback;		/* != 0 if we should do callback next */
115 int doing_callback;		/* != 0 if we are doing callback */
116 char *callback_script;		/* script for doing callback */
117 #ifdef HAVE_MULTILINK
118 TDB_CONTEXT *pppdb;		/* database for storing status etc. */
119 char db_key[32];
120 #endif
121 
122 /*
123  * For plug-in usage:
124  *
125  *	holdoff_hook - Can be used to change the demand-dial hold-off
126  *		time dynamically.  This is normally set by the
127  *		"holdoff" option, and is 30 seconds by default.
128  *
129  *	new_phase_hook - This is called for each change in the PPP
130  *		phase (per RFC 1661).  This can be used to log
131  *		progress.
132  *
133  *	check_options_hook - This is called before doing sys_init()
134  *		and allows the plugin to verify the selected options.
135  *
136  *	updown_script_hook - This is called with the proposed
137  *		command-line arguments for any of the
138  *		/etc/ppp/{ip,ipv6,ipx,auth}-{up,down} scripts before
139  *		fork/exec.  It can be used to add or change arguments.
140  *
141  *	device_pipe_hook - If this is set, then an extra fd (3) is
142  *		passed to the connect/disconnect script.  This extra
143  *		fd is the write side of a pipe, and the read side is
144  *		passed to this routine.  This can be used to pass
145  *		arbitrary data from the script back to pppd.
146  */
147 int (*holdoff_hook) __P((void)) = NULL;
148 int (*new_phase_hook) __P((int new, int old)) = NULL;
149 int (*check_options_hook) __P((uid_t uid)) = NULL;
150 int (*updown_script_hook) __P((const char ***argsp)) = NULL;
151 void (*device_pipe_hook) __P((int pipefd)) = NULL;
152 
153 static int fd_ppp = -1;		/* fd for talking PPP */
154 static int fd_loop;		/* fd for getting demand-dial packets */
155 static int pty_master;		/* fd for master side of pty */
156 int pty_slave = -1;		/* fd for slave side of pty */
157 static int real_ttyfd;		/* fd for actual serial port (not pty) */
158 
159 int phase;			/* where the link is at */
160 int kill_link;
161 int open_ccp_flag;
162 
163 static int waiting;		/* for input from peer or timer expiration */
164 static sigjmp_buf sigjmp;
165 
166 char **script_env;		/* Env. variable values for scripts */
167 int s_env_nalloc;		/* # words avail at script_env */
168 
169 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
170 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
171 u_char nak_buffer[PPP_MRU];	/* where we construct a nak packet */
172 
173 static int n_children;		/* # child processes still running */
174 static bool got_sigchld;	/* set if we have received a SIGCHLD */
175 static sigset_t main_sigmask;	/* signals blocked while dispatching */
176 
177 static bool locked;		/* lock() has succeeded */
178 static bool privopen;		/* don't lock, open device as root */
179 
180 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
181 
182 GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */
183 int ngroups;			/* How many groups valid in groups */
184 
185 static struct timeval start_time; /* Time when link was started. */
186 
187 struct pppd_stats link_stats;
188 int link_connect_time;
189 bool link_stats_valid;
190 
191 static pid_t charshunt_pid;	/* Process ID for charshunt */
192 
193 extern option_t general_options[];
194 extern option_t auth_options[];
195 
196 /*
197  * We maintain a list of child process pids and
198  * functions to call when they exit.
199  */
200 struct subprocess {
201     pid_t	pid;
202     char	*prog;
203     void	(*done) __P((void *, int));
204     void	*arg;
205     struct subprocess *next;
206 };
207 
208 static struct subprocess *children;
209 
210 /* Prototypes for procedures local to this file. */
211 
212 static void setup_signals __P((void));
213 static void create_pidfile __P((void));
214 static void create_linkpidfile __P((void));
215 static void cleanup __P((void));
216 static void close_tty __P((void));
217 static void get_input __P((void));
218 static void calltimeout __P((void));
219 static struct timeval *timeleft __P((struct timeval *));
220 static void kill_my_pg __P((int));
221 static void hup __P((int));
222 static void term __P((int));
223 static void chld __P((int));
224 static void toggle_debug __P((int));
225 static void open_ccp __P((int));
226 static void bad_signal __P((int));
227 static void holdoff_end __P((void *));
228 static int device_script __P((char *, int, int, int, char *));
229 static int reap_kids __P((int waitfor));
230 static void record_child __P((pid_t, char *, void (*) (void *, int), void *));
231 static int open_socket __P((char *));
232 static int start_charshunt __P((int, int));
233 static void charshunt_done __P((void *, int));
234 static void charshunt __P((int, int, char *));
235 static int record_write __P((FILE *, int code, u_char *buf, int nb,
236     struct timeval *));
237 static void final_reap __P((void));
238 
239 #ifdef HAVE_MULTILINK
240 static void update_db_entry __P((void));
241 static void add_db_key __P((const char *));
242 static void delete_db_key __P((const char *));
243 static void cleanup_db __P((void));
244 #endif
245 
246 int main __P((int, char *[]));
247 
248 #ifdef ultrix
249 #undef	O_NONBLOCK
250 #define	O_NONBLOCK	O_NDELAY
251 #endif
252 
253 #ifdef ULTRIX
254 #define setlogmask(x)	0
255 #endif
256 
257 /* Backward compatibility for Linux */
258 #ifndef RECMARK_TIMESTART
259 #define	RECMARK_STARTSEND	1
260 #define	RECMARK_STARTRECV	2
261 #define	RECMARK_ENDSEND		3
262 #define	RECMARK_ENDRECV		4
263 #define	RECMARK_TIMEDELTA32	5
264 #define	RECMARK_TIMEDELTA8	6
265 #define	RECMARK_TIMESTART	7
266 #endif
267 
268 /*
269  * PPP Data Link Layer "protocol" table.
270  * One entry per supported protocol.
271  * The last entry must be NULL.
272  */
273 struct protent *protocols[] = {
274     &lcp_protent,
275     &pap_protent,
276     &chap_protent,
277 #ifdef CBCP_SUPPORT
278     &cbcp_protent,
279 #endif
280     &ipcp_protent,
281 #ifdef INET6
282     &ipv6cp_protent,
283 #endif
284     &ccp_protent,
285 #ifdef IPX_CHANGE
286     &ipxcp_protent,
287 #endif
288 #ifdef AT_CHANGE
289     &atcp_protent,
290 #endif
291     NULL
292 };
293 
294 int
295 main(argc, argv)
296     int argc;
297     char *argv[];
298 {
299     int i, fdflags, t;
300     char *p, *connector;
301     struct passwd *pw;
302     struct timeval timo;
303     struct protent *protp;
304     struct stat statbuf;
305     char numbuf[16];
306 
307     ifname[0] = '\0';
308     new_phase(PHASE_INITIALIZE);
309 
310     /*
311      * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
312      * This way we can close 0, 1, 2 in detach() without clobbering
313      * a fd that we are using.
314      */
315     if ((i = open(_PATH_DEVNULL, O_RDWR)) >= 0) {
316 	while (0 <= i && i <= 2)
317 	    i = dup(i);
318 	if (i >= 0)
319 	    (void) close(i);
320     }
321 
322     script_env = NULL;
323 
324     /* Initialize syslog facilities */
325     reopen_log();
326 
327     if (gethostname(hostname, MAXHOSTNAMELEN+1) < 0 ) {
328 	option_error("Couldn't get hostname: %m");
329 	exit(1);
330     }
331     hostname[MAXHOSTNAMELEN] = '\0';
332 
333     /* make sure we don't create world or group writable files. */
334     (void) umask(umask(0777) | 022);
335 
336     uid = getuid();
337     privileged = (uid == 0);
338     (void) slprintf(numbuf, sizeof(numbuf), "%d", uid);
339     script_setenv("ORIG_UID", numbuf, 0);
340 
341     ngroups = getgroups(NGROUPS_MAX, groups);
342 
343     /*
344      * Initialize magic number generator now so that protocols may
345      * use magic numbers in initialization.
346      */
347     magic_init();
348 
349     progname = *argv;
350     prepass = 0;
351     /*
352      * Initialize to the standard option set, then parse, in order, the
353      * system options file, the user's options file, the tty's options file,
354      * and the command line arguments.  At last, install the options declared
355      * by each protocol into the extra_option list.
356      */
357     for (i = 0; (protp = protocols[i]) != NULL; ++i) {
358         (*protp->init)(0);
359 	if (protp->options != NULL) {
360 	    add_options(protp->options);
361 	}
362     }
363 
364     /*
365      * Install "generic" options into the extra_options list.
366      */
367     add_options(auth_options);
368     add_options(general_options);
369 
370     /* Install any system-specific options (or remove unusable ones) */
371     sys_options();
372 
373     if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1)
374 	|| !options_from_user())
375 	exit(EXIT_OPTION_ERROR);
376 
377     /* scan command line and options files to find device name */
378     prepass = 1;
379     (void) parse_args(argc-1, argv+1);
380     prepass = 0;
381 
382     /*
383      * Work out the device name, if it hasn't already been specified.
384      */
385     using_pty = notty || ptycommand != NULL || pty_socket != NULL;
386     if (!using_pty && default_device && !direct_tty) {
387 	char *p;
388 
389 	if (!isatty(0) || (p = ttyname(0)) == NULL) {
390 	    option_error("no device specified and stdin is not a tty");
391 	    exit(EXIT_OPTION_ERROR);
392 	}
393 	(void) strlcpy(devnam, p, sizeof(devnam));
394 	if (stat(devnam, &devstat) < 0)
395 	    fatal("Couldn't stat default device %s: %m", devnam);
396     }
397 
398     /*
399      * Parse the tty options file and the command line.
400      * The per-tty options file should not change
401      * ptycommand, pty_socket, notty or devnam.
402      */
403     devnam_fixed = 1;
404     if (!using_pty && !direct_tty) {
405 	if (!options_for_tty())
406 	    exit(EXIT_OPTION_ERROR);
407     }
408 
409     devnam_fixed = 0;
410     if (!parse_args(argc-1, argv+1))
411 	exit(EXIT_OPTION_ERROR);
412 
413     /*
414      * Check that we are running as root.
415      */
416     if (geteuid() != 0) {
417 	option_error("must be root to run %s, since it is not setuid-root",
418 		     argv[0]);
419 	exit(EXIT_NOT_ROOT);
420     }
421 
422     if (!ppp_available()) {
423 	option_error(no_ppp_msg);
424 	exit(EXIT_NO_KERNEL_SUPPORT);
425     }
426 
427     /*
428      * Check that the options given are valid and consistent.
429      */
430     if (!sys_check_options())
431 	exit(EXIT_OPTION_ERROR);
432     auth_check_options();
433 #ifdef HAVE_MULTILINK
434     mp_check_options();
435 #endif
436     for (i = 0; (protp = protocols[i]) != NULL; ++i)
437 	if (protp->enabled_flag && protp->check_options != NULL)
438 	    (*protp->check_options)();
439     if (demand && (connect_script == NULL)) {
440 	option_error("connect script is required for demand-dialling\n");
441 	exit(EXIT_OPTION_ERROR);
442     }
443     if (updetach && (nodetach || demand)) {
444 	option_error("updetach cannot be used with %s",
445 	    nodetach ? "nodetach" : "demand");
446 	exit(EXIT_OPTION_ERROR);
447     }
448     /* default holdoff to 0 if no connect script has been given */
449     if ((connect_script == NULL) && !holdoff_specified)
450 	holdoff = 0;
451 
452     if (using_pty || direct_tty) {
453 	if (!default_device) {
454 	    option_error("%s option precludes specifying device name",
455 			 notty? "notty": "pty");
456 	    exit(EXIT_OPTION_ERROR);
457 	}
458 	if (ptycommand != NULL && (notty || direct_tty)) {
459 	    option_error("pty option is incompatible with notty option");
460 	    exit(EXIT_OPTION_ERROR);
461 	}
462 	if (pty_socket != NULL && (ptycommand != NULL || notty ||
463 	    direct_tty)) {
464 	    option_error("socket option is incompatible with pty and notty");
465 	    exit(EXIT_OPTION_ERROR);
466 	}
467 	default_device = notty || direct_tty;
468 	lockflag = 0;
469 	modem = 0;
470 	if (default_device && log_to_fd <= 1)
471 	    log_to_fd = -1;
472     } else {
473 	/*
474 	 * If the user has specified a device which is the same as
475 	 * the one on stdin, pretend they didn't specify any.
476 	 * If the device is already open read/write on stdin,
477 	 * we assume we don't need to lock it, and we can open it as root.
478 	 */
479 	if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode)
480 	    && statbuf.st_rdev == devstat.st_rdev) {
481 	    default_device = 1;
482 	    fdflags = fcntl(0, F_GETFL);
483 	    if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR)
484 		privopen = 1;
485 	}
486     }
487     if (default_device)
488 	nodetach = 1;
489 
490     /*
491      * Don't send log messages to the serial port, it tends to
492      * confuse the peer. :-)
493      */
494     if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0
495 	&& S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev)
496 	log_to_fd = -1;
497     early_log = 0;
498 
499     if (debug)
500 	(void) setlogmask(LOG_UPTO(LOG_DEBUG));
501 
502     /*
503      * Initialize system-dependent stuff.
504      */
505     if (check_options_hook != NULL &&
506 	(*check_options_hook)(uid) == -1) {
507 	exit(EXIT_OPTION_ERROR);
508     }
509     sys_init(!devnam_info.priv && !privopen);
510 
511 #ifdef HAVE_MULTILINK
512     pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
513     if (pppdb != NULL) {
514 	(void) slprintf(db_key, sizeof(db_key), "pppd%d", getpid());
515 	update_db_entry();
516     } else {
517 	warn("Warning: couldn't open ppp database %s", _PATH_PPPDB);
518 	if (multilink) {
519 	    warn("Warning: disabling multilink");
520 	    multilink = 0;
521 	}
522     }
523 #endif
524 
525     /*
526      * Detach ourselves from the terminal, if required, and identify
527      * who is running us.  Printing to stderr stops here unless
528      * nodetach or updetach is set.
529      */
530     if (!nodetach && !updetach)
531 	detach();
532     p = getlogin();
533     if (p == NULL) {
534 	pw = getpwuid(uid);
535 	if (pw != NULL && pw->pw_name != NULL)
536 	    p = pw->pw_name;
537 	else
538 	    p = "(unknown)";
539     }
540     syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d",
541 	   VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid);
542     script_setenv("PPPLOGNAME", p, 0);
543 
544     if (devnam[0] != '\0')
545 	script_setenv("DEVICE", devnam, 1);
546     (void) slprintf(numbuf, sizeof(numbuf), "%d", getpid());
547     script_setenv("PPPD_PID", numbuf, 1);
548 
549     setup_signals();
550 
551     waiting = 0;
552 
553     create_linkpidfile();
554 
555     /*
556      * If we're doing dial-on-demand, set up the interface now.
557      */
558     if (demand) {
559 	/*
560 	 * Open the loopback channel and set it up to be the ppp interface.
561 	 */
562 #ifdef HAVE_MULTILINK
563 	(void) tdb_writelock(pppdb);
564 #endif
565 	set_ifunit(1);
566 	fd_loop = open_ppp_loopback();
567 #ifdef HAVE_MULTILINK
568 	(void) tdb_writeunlock(pppdb);
569 #endif
570 
571 	/*
572 	 * Configure the interface and mark it up, etc.
573 	 */
574 	demand_conf();
575     }
576 
577     new_phase(PHASE_INITIALIZED);
578     do_callback = 0;
579     for (;;) {
580 
581 	need_holdoff = 1;
582 	ttyfd = -1;
583 	real_ttyfd = -1;
584 	status = EXIT_OK;
585 	++unsuccess;
586 	doing_callback = do_callback;
587 	do_callback = 0;
588 
589 	if (demand && !doing_callback) {
590 	    /*
591 	     * Don't do anything until we see some activity.
592 	     */
593 	    kill_link = 0;
594 	    new_phase(PHASE_DORMANT);
595 	    demand_unblock();
596 	    add_fd(fd_loop);
597 	    for (;;) {
598 		if (sigsetjmp(sigjmp, 1) == 0) {
599 		    (void) sigprocmask(SIG_BLOCK, &main_sigmask, NULL);
600 		    if (kill_link || got_sigchld) {
601 			(void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
602 		    } else {
603 			waiting = 1;
604 			(void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
605 			wait_input(timeleft(&timo));
606 		    }
607 		}
608 		waiting = 0;
609 		calltimeout();
610 		if (kill_link) {
611 		    if (!persist)
612 			break;
613 		    kill_link = 0;
614 		}
615 		if (get_loop_output())
616 		    break;
617 		if (got_sigchld)
618 		    (void) reap_kids(0);
619 	    }
620 	    remove_fd(fd_loop);
621 	    if (kill_link && !persist)
622 		break;
623 
624 	    /*
625 	     * Now we want to bring up the link.
626 	     */
627 	    demand_block();
628 	    info("Starting link");
629 	}
630 
631 	new_phase(doing_callback ? PHASE_CALLINGBACK : PHASE_SERIALCONN);
632 
633 	/*
634 	 * Get a pty master/slave pair if the pty, notty, socket,
635 	 * or record options were specified.
636 	 */
637 	(void) strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
638 	pty_master = -1;
639 	pty_slave = -1;
640 	if (using_pty || record_file != NULL) {
641 	    if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) {
642 		error("Couldn't allocate pseudo-tty");
643 		status = EXIT_FATAL_ERROR;
644 		goto fail;
645 	    }
646 	    set_up_tty(pty_slave, 1);
647 	}
648 
649 	/*
650 	 * Lock the device if we've been asked to.
651 	 */
652 	status = EXIT_LOCK_FAILED;
653 	if (lockflag && !privopen && !direct_tty) {
654 	    if (lock(devnam) < 0)
655 		goto fail;
656 	    locked = 1;
657 	}
658 
659 	/*
660 	 * Open the serial device and set it up to be the ppp interface.
661 	 * First we open it in non-blocking mode so we can set the
662 	 * various termios flags appropriately.  If we aren't dialling
663 	 * out and we want to use the modem lines, we reopen it later
664 	 * in order to wait for the carrier detect signal from the modem.
665 	 */
666 	hungup = 0;
667 	kill_link = 0;
668 	connector = doing_callback? callback_script: connect_script;
669 	if (direct_tty) {
670 	    ttyfd = 0;
671 	} else if (devnam[0] != '\0') {
672 	    for (;;) {
673 		/* If the user specified the device name, become the
674 		   user before opening it. */
675 		int err;
676 		if (!devnam_info.priv && !privopen)
677 		    (void) seteuid(uid);
678 		if ((ttyfd = sys_extra_fd()) < 0)
679 		    ttyfd = open(devnam, O_NONBLOCK | O_RDWR);
680 		err = errno;
681 		if (!devnam_info.priv && !privopen)
682 		    (void) seteuid(0);
683 		if (ttyfd >= 0)
684 		    break;
685 		errno = err;
686 		if (err != EINTR) {
687 		    error("Failed to open %s: %m", devnam);
688 		    status = EXIT_OPEN_FAILED;
689 		}
690 		if (!persist || err != EINTR)
691 		    goto fail;
692 	    }
693 	    if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
694 		|| fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
695 		warn("Couldn't reset non-blocking mode on device: %m");
696 
697 	    /*
698 	     * Do the equivalent of `mesg n' to stop broadcast messages.
699 	     */
700 	    if (fstat(ttyfd, &statbuf) < 0
701 		|| fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
702 		warn("Couldn't restrict write permissions to %s: %m", devnam);
703 	    } else
704 		tty_mode = statbuf.st_mode;
705 
706 	    /*
707 	     * Set line speed, flow control, etc.
708 	     * If we have a non-null connection or initializer script,
709 	     * on most systems we set CLOCAL for now so that we can talk
710 	     * to the modem before carrier comes up.  But this has the
711 	     * side effect that we might miss it if CD drops before we
712 	     * get to clear CLOCAL below.  On systems where we can talk
713 	     * successfully to the modem with CLOCAL clear and CD down,
714 	     * we could clear CLOCAL at this point.
715 	     */
716 	    set_up_tty(ttyfd, ((connector != NULL && connector[0] != '\0')
717 			       || initializer != NULL));
718 	    real_ttyfd = ttyfd;
719 	}
720 
721 	/*
722 	 * If the pty, socket, notty and/or record option was specified,
723 	 * start up the character shunt now.
724 	 */
725 	status = EXIT_PTYCMD_FAILED;
726 	if (ptycommand != NULL) {
727 	    if (record_file != NULL) {
728 		int ipipe[2], opipe[2], ok;
729 
730 		if (pipe(ipipe) < 0 || pipe(opipe) < 0)
731 		    fatal("Couldn't create pipes for record option: %m");
732 		dbglog("starting charshunt for pty option");
733 		ok = device_script(ptycommand, opipe[0], ipipe[1], 1,
734 		    "record") == 0 && start_charshunt(ipipe[0], opipe[1]);
735 		(void) close(ipipe[0]);
736 		(void) close(ipipe[1]);
737 		(void) close(opipe[0]);
738 		(void) close(opipe[1]);
739 		if (!ok)
740 		    goto fail;
741 	    } else {
742 		if (device_script(ptycommand, pty_master, pty_master, 1,
743 		    "pty") < 0)
744 		    goto fail;
745 		ttyfd = pty_slave;
746 		(void) close(pty_master);
747 		pty_master = -1;
748 	    }
749 	} else if (pty_socket != NULL) {
750 	    int fd = open_socket(pty_socket);
751 	    if (fd < 0)
752 		goto fail;
753 	    dbglog("starting charshunt for socket option");
754 	    if (!start_charshunt(fd, fd))
755 		goto fail;
756 	} else if (notty) {
757 	    dbglog("starting charshunt for notty option");
758 	    if (!start_charshunt(0, 1))
759 		goto fail;
760 	} else if (record_file != NULL) {
761 	    dbglog("starting charshunt for record option");
762 	    if (!start_charshunt(ttyfd, ttyfd))
763 		goto fail;
764 	}
765 
766 	/* run connection script */
767 	if (((connector != NULL) && (connector[0] != '\0')) || initializer) {
768 	    if (real_ttyfd != -1) {
769 		/* XXX do this if doing_callback == CALLBACK_DIALIN? */
770 		if (!default_device && modem && !direct_tty) {
771 		    setdtr(real_ttyfd, 0);	/* in case modem is off hook */
772 		    (void) sleep(1);
773 		    setdtr(real_ttyfd, 1);
774 		}
775 	    }
776 
777 	    if ((initializer != NULL) && (initializer[0] != '\0')) {
778 		if (device_script(initializer, ttyfd, ttyfd, 0, "init") < 0) {
779 		    error("Initializer script failed");
780 		    status = EXIT_INIT_FAILED;
781 		    goto fail;
782 		}
783 		if (kill_link)
784 		    goto disconnect;
785 
786 		info("Serial port initialized.");
787 	    }
788 
789 	    if ((connector != NULL) && (connector[0] != '\0')) {
790 		if (device_script(connector, ttyfd, ttyfd, 0, "connect") < 0) {
791 		    error("Connect script failed");
792 		    status = EXIT_CONNECT_FAILED;
793 		    goto fail;
794 		}
795 		if (kill_link)
796 		    goto disconnect;
797 
798 		info("Serial connection established.");
799 	    }
800 
801 	    /*
802 	     * Clear CLOCAL if modem option -- we now have carrier
803 	     * established, and we should respect loss of carrier.
804 	     */
805 	    if (real_ttyfd != -1)
806 		set_up_tty(real_ttyfd, 0);
807 
808 	    if (doing_callback == CALLBACK_DIALIN)
809 		connector = NULL;
810 	}
811 
812 	/* reopen tty if necessary to wait for carrier */
813 	if (connector == NULL && modem && devnam[0] != '\0' && !direct_tty) {
814 	    for (;;) {
815 		if ((i = open(devnam, O_RDWR)) >= 0)
816 		    break;
817 		if (errno != EINTR) {
818 		    error("Failed to reopen %s: %m", devnam);
819 		    status = EXIT_OPEN_FAILED;
820 		}
821 		if (!persist || errno != EINTR || hungup || kill_link)
822 		    goto fail;
823 	    }
824 	    (void) close(i);
825 	}
826 
827 	(void) slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);
828 	script_setenv("SPEED", numbuf, 0);
829 
830 	/* run welcome script, if any */
831 	if ((welcomer != NULL) && (welcomer[0] != '\0')) {
832 	    if (device_script(welcomer, ttyfd, ttyfd, 0, "welcome") < 0)
833 		warn("Welcome script failed");
834 	}
835 
836 	/* set up the serial device as a ppp interface */
837 #ifdef HAVE_MULTILINK
838 	(void) tdb_writelock(pppdb);
839 #endif
840 	fd_ppp = establish_ppp(ttyfd);
841 	if (fd_ppp < 0) {
842 #ifdef HAVE_MULTILINK
843 	    (void) tdb_writeunlock(pppdb);
844 #endif
845 	    status = EXIT_FATAL_ERROR;
846 	    goto disconnect;
847 	}
848 
849 	if (!demand && ifunit >= 0)
850 	    set_ifunit(1);
851 #ifdef HAVE_MULTILINK
852 	(void) tdb_writeunlock(pppdb);
853 #endif
854 
855 	/*
856 	 * Start opening the connection and wait for
857 	 * incoming events (reply, timeout, etc.).
858 	 */
859 	notice("Connect: %s <--> %s", ifname, ppp_devnam);
860 	(void) gettimeofday(&start_time, NULL);
861 	link_stats_valid = 0;
862 	script_unsetenv("CONNECT_TIME");
863 	script_unsetenv("BYTES_SENT");
864 	script_unsetenv("BYTES_RCVD");
865 	lcp_lowerup(0);
866 
867 	/* Mostly for accounting purposes */
868 	new_phase(PHASE_CONNECTED);
869 
870 	/*
871 	 * If we are initiating this connection, wait for a short
872 	 * time for something from the peer.  This can avoid bouncing
873 	 * our packets off his tty before he has it set up.
874 	 */
875 	add_fd(fd_ppp);
876 	if (connect_delay != 0 && (connector != NULL || ptycommand != NULL)) {
877 	    struct timeval t;
878 	    t.tv_sec = connect_delay / 1000;
879 	    t.tv_usec = connect_delay % 1000;
880 	    wait_input(&t);
881 	}
882 
883 	lcp_open(0);		/* Start protocol */
884 	open_ccp_flag = 0;
885 	status = EXIT_NEGOTIATION_FAILED;
886 	new_phase(PHASE_ESTABLISH);
887 	while (phase != PHASE_DEAD) {
888 	    if (sigsetjmp(sigjmp, 1) == 0) {
889 		(void) sigprocmask(SIG_BLOCK, &main_sigmask, NULL);
890 		if (kill_link || open_ccp_flag || got_sigchld) {
891 		    (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
892 		} else {
893 		    waiting = 1;
894 		    (void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
895 		    wait_input(timeleft(&timo));
896 		}
897 	    }
898 	    waiting = 0;
899 	    calltimeout();
900 	    get_input();
901 	    if (kill_link) {
902 		lcp_close(0, "User request");
903 		kill_link = 0;
904 	    }
905 	    if (open_ccp_flag) {
906 		if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) {
907 		    /* Uncloak ourselves. */
908 		    ccp_fsm[0].flags &= ~OPT_SILENT;
909 		    (*ccp_protent.open)(0);
910 		}
911 		open_ccp_flag = 0;
912 	    }
913 	    if (got_sigchld)
914 		(void) reap_kids(0);	/* Don't leave dead kids lying around */
915 	}
916 
917 	/*
918 	 * Print connect time and statistics.
919 	 */
920 	if (link_stats_valid) {
921 	    int t = (link_connect_time + 5) / 6;    /* 1/10ths of minutes */
922 	    info("Connect time %d.%d minutes.", t/10, t%10);
923 	    info("Sent %" PPP_COUNTER_F " bytes (%" PPP_COUNTER_F
924 		" packets), received %" PPP_COUNTER_F " bytes (%" PPP_COUNTER_F
925 		" packets).",
926 		 link_stats.bytes_out, link_stats.pkts_out,
927 		 link_stats.bytes_in, link_stats.pkts_in);
928 	}
929 
930 	/*
931 	 * Delete pid file before disestablishing ppp.  Otherwise it
932 	 * can happen that another pppd gets the same unit and then
933 	 * we delete its pid file.
934 	 */
935 	if (!demand) {
936 	    if (pidfilename[0] != '\0'
937 		&& unlink(pidfilename) < 0 && errno != ENOENT)
938 		warn("unable to delete pid file %s: %m", pidfilename);
939 	    pidfilename[0] = '\0';
940 	}
941 
942 	/*
943 	 * If we may want to bring the link up again, transfer
944 	 * the ppp unit back to the loopback.  Set the
945 	 * real serial device back to its normal mode of operation.
946 	 */
947 	remove_fd(fd_ppp);
948 	clean_check();
949 	if (demand)
950 	    restore_loop();
951 	disestablish_ppp(ttyfd);
952 	fd_ppp = -1;
953 	if (!hungup)
954 	    lcp_lowerdown(0);
955 	if (!demand)
956 	    script_unsetenv("IFNAME");
957 
958 	/*
959 	 * Run disconnector script, if requested.
960 	 * XXX we may not be able to do this if the line has hung up!
961 	 */
962     disconnect:
963 	if ((disconnect_script != NULL) && (disconnect_script[0] != '\0') &&
964 	    !hungup) {
965 	    new_phase(PHASE_DISCONNECT);
966 	    if (real_ttyfd >= 0)
967 		set_up_tty(real_ttyfd, 1);
968 	    if (device_script(disconnect_script, ttyfd, ttyfd, 0,
969 		"disconnect") < 0) {
970 		warn("disconnect script failed");
971 	    } else {
972 		info("Serial link disconnected.");
973 	    }
974 	}
975 
976     fail:
977 	if (pty_master >= 0)
978 	    (void) close(pty_master);
979 	if (pty_slave >= 0) {
980 	    (void) close(pty_slave);
981 	    pty_slave = -1;
982 	}
983 	if (real_ttyfd >= 0)
984 	    close_tty();
985 	if (locked) {
986 	    locked = 0;
987 	    unlock();
988 	}
989 
990 	if (!demand) {
991 	    if (pidfilename[0] != '\0'
992 		&& unlink(pidfilename) < 0 && errno != ENOENT)
993 		warn("unable to delete pid file %s: %m", pidfilename);
994 	    pidfilename[0] = '\0';
995 	}
996 
997 	if (!persist || (maxfail > 0 && unsuccess >= maxfail))
998 	    break;
999 
1000 	kill_link = 0;
1001 	if (demand)
1002 	    demand_discard();
1003 	t = need_holdoff? holdoff: 0;
1004 	if (holdoff_hook != NULL)
1005 	    t = (*holdoff_hook)();
1006 	if (t > 0) {
1007 	    new_phase(PHASE_HOLDOFF);
1008 	    TIMEOUT(holdoff_end, NULL, t);
1009 	    do {
1010 		if (sigsetjmp(sigjmp, 1) == 0) {
1011 		    (void) sigprocmask(SIG_BLOCK, &main_sigmask, NULL);
1012 		    if (kill_link || got_sigchld) {
1013 			(void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
1014 		    } else {
1015 			waiting = 1;
1016 			(void) sigprocmask(SIG_UNBLOCK, &main_sigmask, NULL);
1017 			wait_input(timeleft(&timo));
1018 		    }
1019 		}
1020 		waiting = 0;
1021 		calltimeout();
1022 		if (kill_link) {
1023 		    kill_link = 0;
1024 		    new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
1025 		}
1026 		if (got_sigchld)
1027 		    (void) reap_kids(0);
1028 	    } while (phase == PHASE_HOLDOFF);
1029 	    if (!persist)
1030 		break;
1031 	}
1032     }
1033 
1034     /* Wait for scripts to finish */
1035     final_reap();
1036 
1037     die(status);
1038     return (0);
1039 }
1040 
1041 /*
1042  * setup_signals - initialize signal handling.
1043  */
1044 static void
1045 setup_signals()
1046 {
1047     struct sigaction sa;
1048 
1049     /*
1050      * Compute mask of all interesting signals and install signal handlers
1051      * for each.  Only one signal handler may be active at a time.  Therefore,
1052      * all other signals should be masked when any handler is executing.
1053      */
1054     (void) sigemptyset(&main_sigmask);
1055     (void) sigaddset(&main_sigmask, SIGHUP);
1056     (void) sigaddset(&main_sigmask, SIGINT);
1057     (void) sigaddset(&main_sigmask, SIGTERM);
1058     (void) sigaddset(&main_sigmask, SIGCHLD);
1059     (void) sigaddset(&main_sigmask, SIGUSR2);
1060 
1061 #define SIGNAL(s, handler)	if (1) { \
1062 	sa.sa_handler = handler; \
1063 	if (sigaction(s, &sa, NULL) < 0) \
1064 	    fatal("Couldn't establish signal handler (%d): %m", s); \
1065     } else ((void)0)
1066 
1067     sa.sa_mask = main_sigmask;
1068     sa.sa_flags = 0;
1069 /*CONSTANTCONDITION*/ SIGNAL(SIGHUP, hup);		/* Hangup */
1070 /*CONSTANTCONDITION*/ SIGNAL(SIGINT, term);		/* Interrupt */
1071 /*CONSTANTCONDITION*/ SIGNAL(SIGTERM, term);		/* Terminate */
1072 /*CONSTANTCONDITION*/ SIGNAL(SIGCHLD, chld);
1073 
1074 /*CONSTANTCONDITION*/ SIGNAL(SIGUSR1, toggle_debug);	/* Toggle debug flag */
1075 /*CONSTANTCONDITION*/ SIGNAL(SIGUSR2, open_ccp);	/* Reopen CCP */
1076 
1077     /*
1078      * Install a handler for other signals which would otherwise
1079      * cause pppd to exit without cleaning up.
1080      */
1081 /*CONSTANTCONDITION*/ SIGNAL(SIGALRM, bad_signal);
1082 /*CONSTANTCONDITION*/ SIGNAL(SIGQUIT, bad_signal);
1083 
1084 /* Do not hook any of these signals on Solaris; allow core dump instead */
1085 #ifndef SOL2
1086 /*CONSTANTCONDITION*/ SIGNAL(SIGABRT, bad_signal);
1087 /*CONSTANTCONDITION*/ SIGNAL(SIGFPE, bad_signal);
1088 /*CONSTANTCONDITION*/ SIGNAL(SIGILL, bad_signal);
1089 #ifndef DEBUG
1090 /*CONSTANTCONDITION*/ SIGNAL(SIGSEGV, bad_signal);
1091 #endif
1092 #ifdef SIGBUS
1093 /*CONSTANTCONDITION*/ SIGNAL(SIGBUS, bad_signal);
1094 #endif
1095 #ifdef SIGEMT
1096 /*CONSTANTCONDITION*/ SIGNAL(SIGEMT, bad_signal);
1097 #endif
1098 #ifdef SIGPOLL
1099 /*CONSTANTCONDITION*/ SIGNAL(SIGPOLL, bad_signal);
1100 #endif
1101 #ifdef SIGPROF
1102 /*CONSTANTCONDITION*/ SIGNAL(SIGPROF, bad_signal);
1103 #endif
1104 #ifdef SIGSYS
1105 /*CONSTANTCONDITION*/ SIGNAL(SIGSYS, bad_signal);
1106 #endif
1107 #ifdef SIGTRAP
1108 /*CONSTANTCONDITION*/ SIGNAL(SIGTRAP, bad_signal);
1109 #endif
1110 #ifdef SIGVTALRM
1111 /*CONSTANTCONDITION*/ SIGNAL(SIGVTALRM, bad_signal);
1112 #endif
1113 #ifdef SIGXCPU
1114 /*CONSTANTCONDITION*/ SIGNAL(SIGXCPU, bad_signal);
1115 #endif
1116 #ifdef SIGXFSZ
1117 /*CONSTANTCONDITION*/ SIGNAL(SIGXFSZ, bad_signal);
1118 #endif
1119 #endif
1120 
1121     /*
1122      * Apparently we can get a SIGPIPE when we call syslog, if
1123      * syslogd has died and been restarted.  Ignoring it seems
1124      * be sufficient.
1125      */
1126     (void) signal(SIGPIPE, SIG_IGN);
1127 }
1128 
1129 /*
1130  * set_ifunit - do things we need to do once we know which ppp
1131  * unit we are using.
1132  */
1133 void
1134 set_ifunit(iskey)
1135     int iskey;
1136 {
1137     sys_ifname();
1138     info("Using interface %s", ifname);
1139     script_setenv("IFNAME", ifname, iskey);
1140     if (iskey) {
1141 	create_pidfile();	/* write pid to file */
1142 	create_linkpidfile();
1143     }
1144 }
1145 
1146 /*
1147  * detach - detach us from the controlling terminal.
1148  */
1149 void
1150 detach()
1151 {
1152     pid_t pid;
1153     char numbuf[16];
1154 
1155     if (detached)
1156 	return;
1157     if ((pid = fork()) == (pid_t)-1) {
1158 	error("Couldn't detach (fork failed: %m)");
1159 	die(1);			/* or just return? */
1160     }
1161     if (pid != (pid_t)0) {
1162 	/* parent */
1163 	if (locked)
1164 	    (void) relock(pid);
1165 	exit(0);		/* parent dies */
1166     }
1167     (void) setsid();
1168 	/*
1169 	 * Fork again to relinquish session leadership. This is needed
1170 	 * to prevent the daemon from acquiring controlling terminal.
1171 	 */
1172     if ((pid = fork()) == (pid_t)-1) {
1173 	error("Couldn't detach (second fork failed: %m)");
1174 	die(1);			/* or just return? */
1175     }
1176     if (pid != (pid_t)0) {
1177 	/* parent */
1178 	if (locked)
1179 	    (void) relock(pid);
1180 	exit(0);		/* parent dies */
1181     }
1182     (void) chdir("/");
1183     (void) close(0);
1184     (void) close(1);
1185     (void) close(2);
1186     detached = 1;
1187     if (!log_to_file && !log_to_specific_fd)
1188 	log_to_fd = -1;
1189     /* update pid files if they have been written already */
1190     if (pidfilename[0] != '\0')
1191 	create_pidfile();
1192     if (linkpidfile[0] != '\0')
1193 	create_linkpidfile();
1194     (void) slprintf(numbuf, sizeof(numbuf), "%d", getpid());
1195     script_setenv("PPPD_PID", numbuf, 1);
1196 }
1197 
1198 /*
1199  * reopen_log - (re)open our connection to syslog.
1200  */
1201 void
1202 reopen_log()
1203 {
1204 #ifdef ULTRIX
1205     openlog("pppd", LOG_PID);
1206 #else
1207     openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
1208     (void) setlogmask(LOG_UPTO(LOG_INFO));
1209 #endif
1210 }
1211 
1212 /*
1213  * Create a file containing our process ID.
1214  */
1215 static void
1216 create_pidfile()
1217 {
1218     FILE *pidfile;
1219 
1220     (void) slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
1221 	     _PATH_VARRUN, ifname);
1222     if ((pidfile = fopen(pidfilename, "w")) != NULL) {
1223 	(void) fprintf(pidfile, "%u\n", (unsigned)getpid());
1224 	(void) fclose(pidfile);
1225     } else {
1226 	error("Failed to create pid file %s: %m", pidfilename);
1227 	pidfilename[0] = '\0';
1228     }
1229 }
1230 
1231 static void
1232 create_linkpidfile()
1233 {
1234     FILE *pidfile;
1235 
1236     if (linkname[0] == '\0')
1237 	return;
1238     script_setenv("LINKNAME", linkname, 1);
1239     (void) slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid",
1240 	     _PATH_VARRUN, linkname);
1241     if ((pidfile = fopen(linkpidfile, "w")) != NULL) {
1242 	(void) fprintf(pidfile, "%u\n", (unsigned)getpid());
1243 	if (ifname[0] != '\0')
1244 	    (void) fprintf(pidfile, "%s\n", ifname);
1245 	(void) fclose(pidfile);
1246     } else {
1247 	error("Failed to create pid file %s: %m", linkpidfile);
1248 	linkpidfile[0] = '\0';
1249     }
1250 }
1251 
1252 /*
1253  * holdoff_end - called via a timeout when the holdoff period ends.
1254  */
1255 /*ARGSUSED*/
1256 static void
1257 holdoff_end(arg)
1258     void *arg;
1259 {
1260     new_phase(PHASE_DORMANT);
1261 }
1262 
1263 /* List of protocol names, to make our messages a little more informative. */
1264 struct protocol_list {
1265     u_short	proto;
1266     const char	*name;
1267 } protocol_list[] = {
1268     { 0x21,	"IP" },
1269     { 0x23,	"OSI Network Layer" },
1270     { 0x25,	"Xerox NS IDP" },
1271     { 0x27,	"DECnet Phase IV" },
1272     { 0x29,	"Appletalk" },
1273     { 0x2b,	"Novell IPX" },
1274     { 0x2d,	"VJ compressed TCP/IP" },
1275     { 0x2f,	"VJ uncompressed TCP/IP" },
1276     { 0x31,	"Bridging PDU" },
1277     { 0x33,	"Stream Protocol ST-II" },
1278     { 0x35,	"Banyan Vines" },
1279     { 0x37,	"Old VJ compressed TCP/IP" },
1280     { 0x39,	"AppleTalk EDDP" },
1281     { 0x3b,	"AppleTalk SmartBuffered" },
1282     { 0x3d,	"Multilink" },
1283     { 0x3f,	"NetBIOS Frame" },
1284     { 0x41,	"Cisco LAN Extension" },
1285     { 0x43,	"Ascom Timeplex" },
1286     { 0x45,	"Fujitsu Link Backup and Load Balancing (LBLB)" },
1287     { 0x47,	"DCA Remote Lan" },
1288     { 0x49,	"Serial Data Transport Protocol (PPP-SDTP)" },
1289     { 0x4b,	"SNA over 802.2" },
1290     { 0x4d,	"SNA" },
1291     { 0x4f,	"IP6 Header Compression" },
1292     { 0x51,	"KNX Bridging" },
1293     { 0x53,	"Encrypted" },
1294     { 0x55,	"per-link encrypted" },
1295     { 0x57,	"IPv6" },
1296     { 0x59,	"PPP Muxing" },
1297     { 0x6f,	"Stampede Bridging" },
1298     { 0x73,	"MP+" },
1299     { 0xc1,	"STMF" },
1300     { 0xfb,	"per-link compressed" },
1301     { 0xfd,	"compressed datagram" },
1302     { 0x0201,	"802.1d Hello Packets" },
1303     { 0x0203,	"IBM Source Routing BPDU" },
1304     { 0x0205,	"DEC LANBridge100 Spanning Tree" },
1305     { 0x0207,	"Cisco Discovery Protocol" },
1306     { 0x0231,	"Luxcom" },
1307     { 0x0233,	"Sigma Network Systems" },
1308     { 0x0235,	"Apple Client Server Protocol" },
1309     { 0x0281,	"MPLS Unicast" },
1310     { 0x0283,	"MPLS Multicast" },
1311     { 0x0285,	"IEEE p1284.4" },
1312     { 0x0287,	"ETSI TETRA TNP1" },
1313     { 0x4021,	"Stacker LZS" },
1314     { 0x8021,	"Internet Protocol Control Protocol" },
1315     { 0x8023,	"OSI Network Layer Control Protocol" },
1316     { 0x8025,	"Xerox NS IDP Control Protocol" },
1317     { 0x8027,	"DECnet Phase IV Control Protocol" },
1318     { 0x8029,	"Appletalk Control Protocol" },
1319     { 0x802b,	"Novell IPX Control Protocol" },
1320     { 0x8031,	"Bridging Control Protocol" },
1321     { 0x8033,	"Stream Protocol Control Protocol" },
1322     { 0x8035,	"Banyan Vines Control Protocol" },
1323     { 0x803f,	"NetBIOS Frames Control Protocol" },
1324     { 0x8041,	"Cisco LAN Extension Control Protocol" },
1325     { 0x8043,	"Ascom Timeplex Control Protocol" },
1326     { 0x8045,	"Fujitsu LBLB Control Protocol" },
1327     { 0x8047,	"DCA Remote Lan Network Control Protocol (RLNCP)" },
1328     { 0x8049,	"Serial Data Control Protocol (PPP-SDCP)" },
1329     { 0x804b,	"SNA over 802.2 Control Protocol" },
1330     { 0x804d,	"SNA Control Protocol" },
1331     { 0x8051,	"KNX Bridging Control Protocol" },
1332     { 0x8053,	"Encryption Control Protocol" },
1333     { 0x8055,	"Per-link Encryption Control Protocol" },
1334     { 0x8057,	"IPv6 Control Protocol" },
1335     { 0x806f,	"Stampede Bridging Control Protocol" },
1336     { 0x80c1,	"STMF Control Protocol" },
1337     { 0x80fb,	"Per-link Compression Control Protocol" },
1338     { 0x80fd,	"Compression Control Protocol" },
1339     { 0x8207,	"Cisco Discovery Control Protocol" },
1340     { 0x8235,	"Apple Client Server Control Protocol" },
1341     { 0x8281,	"MPLS Control Protocol" },
1342     { 0x8287,	"ETSI TETRA TNP1 Control Protocol" },
1343     { 0xc021,	"Link Control Protocol" },
1344     { 0xc023,	"Password Authentication Protocol" },
1345     { 0xc025,	"Link Quality Report" },
1346     { 0xc027,	"Shiva Password Authentication Protocol" },
1347     { 0xc029,	"CallBack Control Protocol (CBCP)" },
1348     { 0xc02b,	"Bandwidth Allocation Control Protocol" },
1349     { 0xc02d,	"BAP" },
1350     { 0xc081,	"Container Control Protocol" },
1351     { 0xc223,	"Challenge Handshake Authentication Protocol" },
1352     { 0xc227,	"Extensible Authentication Protocol" },
1353     { 0xc281,	"Funk Proprietary Authentication Protocol" },
1354     { 0,	NULL },
1355 };
1356 
1357 /*
1358  * protocol_name - find a name for a PPP protocol.
1359  */
1360 const char *
1361 protocol_name(proto)
1362     int proto;
1363 {
1364     struct protocol_list *lp;
1365 
1366     for (lp = protocol_list; lp->proto != 0; ++lp)
1367 	if (proto == lp->proto)
1368 	    return (lp->name);
1369     return (NULL);
1370 }
1371 
1372 static const char *phase_names[] = { PHASE__NAMES };
1373 
1374 const char *
1375 phase_name(pval)
1376     int pval;
1377 {
1378     static char buf[32];
1379 
1380     if (pval < 0 || pval >= Dim(phase_names)) {
1381 	(void) slprintf(buf, sizeof (buf), "unknown %d", pval);
1382 	return ((const char *)buf);
1383     }
1384     return (phase_names[pval]);
1385 }
1386 
1387 /*
1388  * get_input - called when incoming data is available.
1389  */
1390 static void
1391 get_input()
1392 {
1393     int len, i;
1394     u_char *p;
1395     u_short protocol;
1396     struct protent *protp;
1397     const char *pname;
1398 
1399     p = inpacket_buf;	/* point to beginning of packet buffer */
1400 
1401     len = read_packet(inpacket_buf);
1402     if (len < 0)
1403 	return;
1404 
1405     if (len == 0) {
1406 	notice("Modem hangup");
1407 	hungup = 1;
1408 	status = EXIT_HANGUP;
1409 	lcp_lowerdown(0);	/* serial link is no longer available */
1410 	link_terminated(0);
1411 	return;
1412     }
1413 
1414     if (debug /*&& (debugflags & DBG_INPACKET)*/)
1415 	dbglog("rcvd %P", p, len);
1416 
1417     if (len < PPP_HDRLEN) {
1418 	dbglog("Discarded short packet (%d < %d)", len, PPP_HDRLEN);
1419 	return;
1420     }
1421 
1422     p += 2;				/* Skip address and control */
1423     GETSHORT(protocol, p);
1424     len -= PPP_HDRLEN;
1425 
1426     pname = debug ? NULL : protocol_name(protocol);
1427 
1428     /*
1429      * Toss all non-LCP packets unless LCP is in Opened state and
1430      * discard non-authentication protocols if we're not yet
1431      * authenticated.
1432      */
1433     if ((protocol != PPP_LCP &&
1434 	(phase < PHASE_AUTHENTICATE || phase > PHASE_RUNNING)) ||
1435 	(phase <= PHASE_AUTHENTICATE &&
1436 	    !(protocol == PPP_LCP || protocol == PPP_LQR ||
1437 		protocol == PPP_PAP || protocol == PPP_CHAP))) {
1438 	    if (pname == NULL)
1439 		    dbglog("Discarded proto 0x%x in %s phase",
1440 			protocol, phase_name(phase));
1441 	    else
1442 		    dbglog("Discarded %s (0x%x) in %s phase",
1443 			pname, protocol, phase_name(phase));
1444 	return;
1445     }
1446 
1447     /*
1448      * Upcall the proper protocol input routine.
1449      */
1450     for (i = 0; (protp = protocols[i]) != NULL; ++i) {
1451 	if (protp->protocol == protocol && protp->enabled_flag) {
1452 	    (*protp->input)(0, p, len);
1453 	    return;
1454 	}
1455         if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
1456 	    && protp->datainput != NULL) {
1457 	    (*protp->datainput)(0, p, len);
1458 	    return;
1459 	}
1460     }
1461 
1462     if (debug) {
1463 	if (pname != NULL)
1464 	    warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
1465 	else
1466 	    warn("Unsupported protocol 0x%x received", protocol);
1467     }
1468     lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
1469 }
1470 
1471 /*
1472  * new_phase - signal the start of a new phase of pppd's operation.
1473  */
1474 void
1475 new_phase(p)
1476     int p;
1477 {
1478     if (new_phase_hook != NULL)
1479 	(*new_phase_hook)(p, phase);
1480     phase = p;
1481 }
1482 
1483 /*
1484  * die - clean up state and exit with the specified status.
1485  */
1486 void
1487 die(status)
1488     int status;
1489 {
1490     cleanup();
1491     if (phase != PHASE_EXIT) {
1492 	syslog(LOG_INFO, "Exit.");
1493 	new_phase(PHASE_EXIT);
1494     }
1495     exit(status);
1496 }
1497 
1498 /*
1499  * cleanup - restore anything which needs to be restored before we exit
1500  */
1501 static void
1502 cleanup()
1503 {
1504     sys_cleanup();  /* XXX: Need to check if this is okay after close_tty */
1505 
1506     if (fd_ppp >= 0) {
1507 	fd_ppp = -1;
1508 	disestablish_ppp(ttyfd);
1509     }
1510     if (real_ttyfd >= 0)
1511 	close_tty();
1512 
1513     if (pidfilename[0] != '\0' && unlink(pidfilename) < 0 && errno != ENOENT)
1514 	warn("unable to delete pid file %s: %m", pidfilename);
1515     pidfilename[0] = '\0';
1516     if (linkpidfile[0] != '\0' && unlink(linkpidfile) < 0 && errno != ENOENT)
1517 	warn("unable to delete pid file %s: %m", linkpidfile);
1518     linkpidfile[0] = '\0';
1519 
1520     if (locked) {
1521 	locked = 0;
1522 	unlock();
1523     }
1524 
1525 #ifdef HAVE_MULTILINK
1526     if (pppdb != NULL) {
1527 	cleanup_db();
1528 	pppdb = NULL;
1529     }
1530 #endif
1531 }
1532 
1533 /*
1534  * close_tty - restore the terminal device and close it.
1535  */
1536 static void
1537 close_tty()
1538 {
1539     int fd = real_ttyfd;
1540 
1541     real_ttyfd = -1;
1542 
1543     /* drop dtr to hang up */
1544     if (!default_device && modem) {
1545 	setdtr(fd, 0);
1546 	/*
1547 	 * This sleep is in case the serial port has CLOCAL set by default,
1548 	 * and consequently will reassert DTR when we close the device.
1549 	 */
1550 	(void) sleep(1);
1551     }
1552 
1553     restore_tty(fd);
1554 
1555     if (tty_mode != (mode_t) -1) {
1556 	if (fchmod(fd, tty_mode) != 0) {
1557 	    /* XXX if devnam is a symlink, this will change the link */
1558 	    if (chmod(devnam, tty_mode) != 0) {
1559 		error("Unable to chmod file %s: %m", devnam);
1560 	    }
1561 	}
1562     }
1563 
1564     (void) close(fd);
1565 }
1566 
1567 /*
1568  * update_link_stats - get stats at link termination.
1569  */
1570 void
1571 update_link_stats(u)
1572     int u;
1573 {
1574     struct timeval now;
1575     char numbuf[32];
1576 
1577     if (gettimeofday(&now, NULL) >= 0) {
1578 	link_connect_time = now.tv_sec - start_time.tv_sec;
1579 	(void) slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time);
1580 	script_setenv("CONNECT_TIME", numbuf, 0);
1581     } else {
1582 	link_connect_time = 0;
1583     }
1584 
1585     if (get_ppp_stats(u, &link_stats)) {
1586 	(void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1587 	    link_stats.bytes_out);
1588 	script_setenv("BYTES_SENT", numbuf, 0);
1589 	(void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1590 	    link_stats.bytes_in);
1591 	script_setenv("BYTES_RCVD", numbuf, 0);
1592 	(void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1593 	    link_stats.pkts_in);
1594 	script_setenv("PKTS_RCVD", numbuf, 0);
1595 	(void) slprintf(numbuf, sizeof(numbuf), "%" PPP_COUNTER_F,
1596 	    link_stats.pkts_out);
1597 	script_setenv("PKTS_SENT", numbuf, 0);
1598 	link_stats_valid = 1;
1599     }
1600 }
1601 
1602 
1603 struct	callout {
1604     struct timeval	c_time;		/* time at which to call routine */
1605     void		*c_arg;		/* argument to routine */
1606     void		(*c_func) __P((void *)); /* routine */
1607     struct		callout *c_next;
1608 };
1609 
1610 static struct callout *callout = NULL;	/* Callout list */
1611 static struct timeval timenow;		/* Current time */
1612 
1613 /*
1614  * timeout - Schedule a timeout.
1615  *
1616  * Note that this timeout takes the number of seconds, NOT hz (as in
1617  * the kernel).
1618  */
1619 void
1620 timeout(func, arg, time)
1621     void (*func) __P((void *));
1622     void *arg;
1623     int time;
1624 {
1625     struct callout *newp, *p, **pp;
1626 
1627     MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time));
1628 
1629     /*
1630      * Allocate timeout.
1631      */
1632     if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
1633 	novm("callout structure for timeout.");
1634     newp->c_arg = arg;
1635     newp->c_func = func;
1636     (void) gettimeofday(&timenow, NULL);
1637     newp->c_time.tv_sec = timenow.tv_sec + time;
1638     newp->c_time.tv_usec = timenow.tv_usec;
1639 
1640     /*
1641      * Find correct place and link it in.
1642      */
1643     for (pp = &callout; (p = *pp) != NULL; pp = &p->c_next)
1644 	if (newp->c_time.tv_sec < p->c_time.tv_sec
1645 	    || (newp->c_time.tv_sec == p->c_time.tv_sec
1646 		&& newp->c_time.tv_usec < p->c_time.tv_usec))
1647 	    break;
1648     newp->c_next = p;
1649     *pp = newp;
1650 }
1651 
1652 
1653 /*
1654  * untimeout - Unschedule a timeout.
1655  */
1656 void
1657 untimeout(func, arg)
1658     void (*func) __P((void *));
1659     void *arg;
1660 {
1661     struct callout **copp, *freep;
1662 
1663     MAINDEBUG(("Untimeout %p:%p.", func, arg));
1664 
1665     /*
1666      * Find first matching timeout and remove it from the list.
1667      */
1668     for (copp = &callout; (freep = *copp) != NULL; copp = &freep->c_next)
1669 	if (freep->c_func == func && freep->c_arg == arg) {
1670 	    *copp = freep->c_next;
1671 	    free((char *) freep);
1672 	    break;
1673 	}
1674 }
1675 
1676 
1677 /*
1678  * calltimeout - Call any timeout routines which are now due.
1679  */
1680 static void
1681 calltimeout()
1682 {
1683     struct callout *p;
1684 
1685     while (callout != NULL) {
1686 	p = callout;
1687 
1688 	if (gettimeofday(&timenow, NULL) < 0)
1689 	    fatal("Failed to get time of day: %m");
1690 	if (!(p->c_time.tv_sec < timenow.tv_sec
1691 	      || (p->c_time.tv_sec == timenow.tv_sec
1692 		  && p->c_time.tv_usec <= timenow.tv_usec)))
1693 	    break;		/* no, it's not time yet */
1694 
1695 	callout = p->c_next;
1696 	(*p->c_func)(p->c_arg);
1697 
1698 	free((char *) p);
1699     }
1700 }
1701 
1702 
1703 /*
1704  * timeleft - return the length of time until the next timeout is due.
1705  */
1706 static struct timeval *
1707 timeleft(tvp)
1708     struct timeval *tvp;
1709 {
1710     if (callout == NULL)
1711 	return (NULL);
1712 
1713     (void) gettimeofday(&timenow, NULL);
1714     tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
1715     tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
1716     if (tvp->tv_usec < 0) {
1717 	tvp->tv_usec += 1000000;
1718 	tvp->tv_sec -= 1;
1719     }
1720     if (tvp->tv_sec < 0)
1721 	tvp->tv_sec = tvp->tv_usec = 0;
1722 
1723     return (tvp);
1724 }
1725 
1726 
1727 /*
1728  * kill_my_pg - send a signal to our process group, and ignore it ourselves.
1729  */
1730 static void
1731 kill_my_pg(sig)
1732     int sig;
1733 {
1734     struct sigaction act, oldact;
1735     sigset_t mask;
1736 
1737     BZERO(&act, sizeof (act));
1738     act.sa_handler = SIG_IGN;
1739     (void) sigemptyset(&mask);
1740     (void) sigaddset(&mask, sig);
1741     /*
1742      * Ignore signal 'sig' temporarily, before finally re-activating the
1743      * original handler.  We need to do it in the following sequence, since
1744      * otherwise the signal handler for 'sig' will be called forever.
1745      */
1746     if (sigaction(sig, &act, &oldact) < 0) {
1747 	fatal("kill_my_pg: couldn't establish signal handler (%d): %m", sig);
1748     }
1749     (void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
1750     /*
1751      * Send signal 'sig' to all processes whose process group ID is equal
1752      * to the process group ID of the sender.
1753      */
1754     (void) kill(0, sig);
1755     if (sigaction(sig, &oldact, NULL) < 0) {
1756 	fatal("kill_my_pg: couldn't establish signal handler (%d): %m", sig);
1757     }
1758 }
1759 
1760 
1761 /*
1762  * hup - Catch SIGHUP signal.
1763  *
1764  * Indicates that the physical layer has been disconnected.
1765  * We don't rely on this indication; if the user has sent this
1766  * signal, we just take the link down.
1767  */
1768 static void
1769 hup(sig)
1770     int sig;
1771 {
1772     info("Hangup (SIGHUP)");
1773     kill_link = 1;
1774     if (status != EXIT_HANGUP)
1775 	status = EXIT_USER_REQUEST;
1776     if (conn_running > 0)
1777 	/* Send the signal to the [dis]connector process(es) also */
1778 	kill_my_pg(sig);
1779     if (charshunt_pid)
1780 	(void) kill(charshunt_pid, sig);
1781     if (waiting)
1782 	siglongjmp(sigjmp, 1);
1783 }
1784 
1785 
1786 /*
1787  * term - Catch SIGTERM signal and SIGINT signal (^C/del).
1788  *
1789  * Indicates that we should initiate a graceful disconnect and exit.
1790  */
1791 /*ARGSUSED*/
1792 static void
1793 term(sig)
1794     int sig;
1795 {
1796     info("Terminating on signal %d.", sig);
1797     persist = 0;		/* don't try to restart */
1798     kill_link = 1;
1799     status = EXIT_USER_REQUEST;
1800     if (conn_running > 0)
1801 	/* Send the signal to the [dis]connector process(es) also */
1802 	kill_my_pg(sig);
1803     if (charshunt_pid)
1804 	(void) kill(charshunt_pid, sig);
1805     if (waiting)
1806 	siglongjmp(sigjmp, 1);
1807 }
1808 
1809 
1810 /*
1811  * chld - Catch SIGCHLD signal.
1812  * Sets a flag so we will call reap_kids in the mainline.
1813  */
1814 /*ARGSUSED*/
1815 static void
1816 chld(sig)
1817     int sig;
1818 {
1819     got_sigchld = 1;
1820     if (waiting)
1821 	siglongjmp(sigjmp, 1);
1822 }
1823 
1824 /*
1825  * toggle_debug - Catch SIGUSR1 signal.
1826  *
1827  * Toggle debug flag.
1828  */
1829 /*ARGSUSED*/
1830 static void
1831 toggle_debug(sig)
1832     int sig;
1833 {
1834     if (debug) {
1835 	print_ncpstate(0, NULL);
1836 	dbglog("debug logging disabled");
1837 	(void) setlogmask(LOG_UPTO(LOG_WARNING));
1838 	debug = 0;
1839     } else {
1840 	(void) setlogmask(LOG_UPTO(LOG_DEBUG));
1841 	dbglog("debug logging enabled");
1842 	print_ncpstate(0, NULL);
1843 	debug = 1;
1844     }
1845 }
1846 
1847 
1848 /*
1849  * open_ccp - Catch SIGUSR2 signal.
1850  *
1851  * Try to (re)negotiate compression.
1852  */
1853 /*ARGSUSED*/
1854 static void
1855 open_ccp(sig)
1856     int sig;
1857 {
1858     open_ccp_flag = 1;
1859     if (waiting)
1860 	siglongjmp(sigjmp, 1);
1861 }
1862 
1863 
1864 /*
1865  * bad_signal - We've caught a fatal signal.  Clean up state and exit.
1866  */
1867 static void
1868 bad_signal(sig)
1869     int sig;
1870 {
1871     static int crashed = 0;
1872 
1873     if (crashed)
1874 	_exit(127);
1875     crashed = 1;
1876     error("Fatal signal %d", sig);
1877     if (conn_running > 0)
1878 	kill_my_pg(SIGTERM);
1879     if (charshunt_pid)
1880 	(void) kill(charshunt_pid, SIGTERM);
1881     die(127);
1882 }
1883 
1884 
1885 /*
1886  * device_script - run a program to talk to the serial device
1887  * (e.g. to run the connector or disconnector script).
1888  */
1889 static int
1890 device_script(program, in, out, dont_wait, optname)
1891     char *program;
1892     int in, out;
1893     int dont_wait;
1894     char *optname;
1895 {
1896     pid_t pid;
1897     int status = -1;
1898     int errfd;
1899     int envpipe[2];
1900 
1901     envpipe[0] = envpipe[1] = -1;
1902     if (!dont_wait && device_pipe_hook != NULL && pipe(envpipe) == -1) {
1903 	error("Cannot create pipe for child: %m");
1904 	return (-1);
1905     }
1906 
1907     ++conn_running;
1908     pid = fork();
1909 
1910     if (pid == (pid_t)-1) {
1911 	--conn_running;
1912 	error("Failed to create child process: %m");
1913 	return (-1);
1914     }
1915 
1916     if (pid == (pid_t)0) {
1917 	sys_close();
1918 	closelog();
1919 	if (envpipe[0] >= 0) {
1920 	    if (envpipe[1] <= 2)
1921 		envpipe[1] = dup(envpipe[1]);
1922 	    (void) close(envpipe[0]);
1923 	}
1924 	if (in == 2) {
1925 	    /* aargh!!! */
1926 	    int newin = dup(in);
1927 	    if (in == out)
1928 		out = newin;
1929 	    in = newin;
1930 	} else if (out == 2) {
1931 	    out = dup(out);
1932 	}
1933 	if (log_to_fd >= 0) {
1934 	    if (log_to_fd != 2) {
1935 		if (dup2(log_to_fd, 2) < 0)
1936 		    error("dup2(log_to_fd, STDERR) failed: %m");
1937 	    }
1938 	} else {
1939 	    (void) close(2);
1940 	    errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600);
1941 	    if (errfd >= 0 && errfd != 2) {
1942 		if (dup2(errfd, 2) < 0)
1943 		    error("dup2(errfd, STDERR) failed: %m");
1944 		(void) close(errfd);
1945 	    }
1946 	}
1947 	if (in != 0) {
1948 	    if (out == 0)
1949 		out = dup(out);
1950 	    if (dup2(in, 0) < 0)
1951 		error("dup2(in, STDIN) failed: %m");
1952 	}
1953 	if (out != 1) {
1954 	    if (dup2(out, 1) < 0)
1955 		error("dup2(out, STDOUT) failed: %m");
1956 	}
1957 	if (envpipe[0] >= 0 && dup2(envpipe[1], 3) < 0)
1958 	    error("dup2(pipe, pipeout) failed: %m");
1959 	if (real_ttyfd > 2)
1960 	    (void) close(real_ttyfd);
1961 	if (pty_master > 2)
1962 	    (void) close(pty_master);
1963 	if (pty_slave > 2) {
1964 	    (void) close(pty_slave);
1965 	    pty_slave = -1;
1966 	}
1967 	(void) setuid(uid);
1968 	if (getuid() != uid) {
1969 	    error("setuid failed");
1970 	    exit(1);
1971 	}
1972 	(void) setgid(getgid());
1973 	if (script_env != NULL) {
1974 	    while (*script_env != NULL) {
1975 		if (putenv(*script_env) == -1)
1976 		    warn("unable to set %s for %s: %m", *script_env, program);
1977 		script_env++;
1978 	    }
1979 	}
1980 	(void) execl("/bin/sh", "sh", "-c", program, (char *)0);
1981 	error("could not exec /bin/sh: %m");
1982 	exit(99);
1983 	/* NOTREACHED */
1984     }
1985 
1986     if (debug)
1987 	dbglog("%s option: '%s' started (pid %d)", optname, program, pid);
1988     if (dont_wait) {
1989 	record_child(pid, program, NULL, NULL);
1990 	status = 0;
1991     } else {
1992 	if (envpipe[0] >= 0) {
1993 	    (void) close(envpipe[1]);
1994 	    (*device_pipe_hook)(envpipe[0]);
1995 	}
1996 	while (waitpid(pid, &status, 0) < 0) {
1997 	    if (errno == EINTR)
1998 		continue;
1999 	    fatal("error waiting for (dis)connection process: %m");
2000 	}
2001 	if (envpipe[0] >= 0)
2002 	    (void) close(envpipe[0]);
2003 	--conn_running;
2004     }
2005 
2006     return (status == 0 ? 0 : -1);
2007 }
2008 
2009 
2010 /*
2011  * run-program - execute a program with given arguments,
2012  * but don't wait for it.
2013  * If the program can't be executed, logs an error unless
2014  * must_exist is 0 and the program file doesn't exist.
2015  * Returns -1 if it couldn't fork, 0 if the file doesn't exist
2016  * or isn't an executable plain file, or the process ID of the child.
2017  * If done != NULL, (*done)(arg, int) will be called later (within
2018  * reap_kids) if this routine returns value > 0.
2019  */
2020 pid_t
2021 run_program(prog, args, must_exist, done, arg)
2022     char *prog;
2023     char **args;
2024     int must_exist;
2025     void (*done) __P((void *arg, int status));
2026     void *arg;
2027 {
2028     pid_t pid;
2029     struct stat sbuf;
2030     int retv;
2031 
2032     /*
2033      * First check if the file exists and is executable.
2034      * We don't use access() because that would use the
2035      * real user-id, which might not be root, and the script
2036      * might be accessible only to root.
2037      */
2038     errno = EINVAL;
2039     if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode)
2040 	|| (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
2041 	if (must_exist || errno != ENOENT)
2042 	    warn("Can't execute %s: %m", prog);
2043 	return (0);
2044     }
2045 
2046     if (updown_script_hook != NULL) {
2047 	retv = (*updown_script_hook)((const char ***)&args);
2048 	if (retv == -1) {
2049 	    return (-1);
2050 	}
2051     }
2052 
2053     pid = fork();
2054     if (pid == (pid_t)-1) {
2055 	error("Failed to create child process for %s: %m", prog);
2056 	return (-1);
2057     }
2058     if (pid == (pid_t)0) {
2059 	int new_fd;
2060 
2061 	/* Leave the current location */
2062 	(void) setsid();	/* No controlling tty. */
2063 	(void) umask (S_IRWXG|S_IRWXO);
2064 	(void) chdir ("/");	/* no current directory. */
2065 	(void) setuid(0);	/* set real UID = root */
2066 	(void) setgid(getegid());
2067 
2068 	/* Ensure that nothing of our device environment is inherited. */
2069 	sys_close();
2070 	closelog();
2071 	(void) close(0);
2072 	(void) close(1);
2073 	(void) close(2);
2074 	(void) close(ttyfd);  /* tty interface to the ppp device */
2075 	if (real_ttyfd >= 0)
2076 	    (void) close(real_ttyfd);
2077 
2078         /* Don't pass handles to the PPP device, even by accident. */
2079 	new_fd = open (_PATH_DEVNULL, O_RDWR);
2080 	if (new_fd >= 0) {
2081 	    if (new_fd != 0) {
2082 	        if (dup2(new_fd, 0) < 0) /* stdin <- /dev/null */
2083 		    error("dup2(/dev/null, STDIN) failed: %m");
2084 		(void) close(new_fd);
2085 	    }
2086 	    if (dup2(0, 1) < 0) /* stdout -> /dev/null */
2087 		error("dup2(/dev/null, STDOUT) failed: %m");
2088 	    if (dup2(0, 2) < 0) /* stderr -> /dev/null */
2089 		error("dup2(/dev/null, STDERR) failed: %m");
2090 	}
2091 
2092 #ifdef BSD
2093 	/* Force the priority back to zero if pppd is running higher. */
2094 	if (setpriority (PRIO_PROCESS, 0, 0) < 0)
2095 	    warn("can't reset priority to 0: %m");
2096 #endif
2097 
2098 	/* SysV recommends a second fork at this point. */
2099 
2100 	/* run the program */
2101 	(void) execve(prog, args, script_env);
2102 	if (must_exist || errno != ENOENT) {
2103 	    /* have to reopen the log, there's nowhere else
2104 	       for the message to go. */
2105 	    reopen_log();
2106 	    syslog(LOG_ERR, "Can't execute %s: %m", prog);
2107 	    closelog();
2108 	}
2109 	_exit(-1);
2110     }
2111 
2112     if (debug)
2113 	dbglog("Script %s started (pid %d)", prog, pid);
2114     record_child(pid, prog, done, arg);
2115 
2116     return (pid);
2117 }
2118 
2119 
2120 /*
2121  * record_child - add a child process to the list for reap_kids
2122  * to use.
2123  */
2124 static void
2125 record_child(pid, prog, done, arg)
2126     pid_t pid;
2127     char *prog;
2128     void (*done) __P((void *, int));
2129     void *arg;
2130 {
2131     struct subprocess *chp;
2132 
2133     ++n_children;
2134 
2135     chp = (struct subprocess *) malloc(sizeof(struct subprocess));
2136     if (chp == NULL) {
2137 	warn("losing track of %s process", prog);
2138     } else {
2139 	chp->pid = pid;
2140 	chp->prog = prog;
2141 	chp->done = done;
2142 	chp->arg = arg;
2143 	chp->next = children;
2144 	children = chp;
2145     }
2146 }
2147 
2148 
2149 /*
2150  * reap_kids - get status from any dead child processes,
2151  * and log a message for abnormal terminations.
2152  */
2153 static int
2154 reap_kids(waitfor)
2155     int waitfor;
2156 {
2157     pid_t pid;
2158     int status, i;
2159     struct subprocess *chp, **prevp;
2160 
2161     got_sigchld = 0;
2162     if (n_children == 0)
2163 	return (0);
2164 
2165     /*CONSTANTCONDITION*/
2166     while (1) {
2167 	pid = waitpid(-1, &status, (waitfor ? 0 : WNOHANG));
2168 	if (pid == 0) {
2169 	    break;	/* return 0 */
2170 	} else if (pid == -1) {
2171 	    if (errno == EINTR)
2172 		continue;
2173 	    if (errno != ECHILD)
2174 		error("Error waiting for child process: %m");
2175 	    return (-1);
2176 	} else {
2177 	    for (prevp = &children; (chp = *prevp) != NULL;
2178 		prevp = &chp->next) {
2179 		if (chp->pid == pid) {
2180 		    --n_children;
2181 		    *prevp = chp->next;
2182 		    break;
2183 		}
2184 	    }
2185 	    if (WIFSIGNALED(status) || WIFSTOPPED(status)) {
2186 		i = WIFSIGNALED(status) ? WTERMSIG(status) : WSTOPSIG(status);
2187 		warn("Child process %s (pid %d) %s with signal %d (%s)",
2188 		    (chp != NULL ? chp->prog : "??"), pid,
2189 		    (WIFSIGNALED(status) ? "terminated" : "stopped"),
2190 		    i, signal_name(i));
2191 	    } else if (debug) {
2192 		dbglog("Child process %s finished (pid %d), status = %d",
2193 		       (chp != NULL ? chp->prog: "??"), pid,
2194 		    WEXITSTATUS(status));
2195 	    }
2196 	    if ((chp != NULL) && (chp->done != NULL))
2197 		(*chp->done)(chp->arg, status);
2198 	    if (chp != NULL)
2199 		free(chp);
2200 	}
2201     }
2202     return (0);
2203 }
2204 
2205 /*
2206  * infanticide - timeout while waiting for child process.
2207  */
2208 /*ARGSUSED*/
2209 static void
2210 infanticide(sig)
2211     int sig;
2212 {
2213     struct subprocess *chp;
2214     static int runcount = 0;
2215 
2216     if (runcount < 2) {
2217 	for (chp = children; chp != NULL; chp = chp->next)
2218 	    (void) kill(chp->pid, runcount == 0 ? SIGTERM : SIGKILL);
2219     } else {
2220 	kill_my_pg(SIGTERM);
2221 	/* Quit and hope for the best. */
2222 	n_children = 0;
2223     }
2224     runcount++;
2225 }
2226 
2227 /*
2228  * Perform final wait before exiting.
2229  */
2230 static void
2231 final_reap()
2232 {
2233     struct sigaction sa;
2234     struct subprocess *chp;
2235 
2236     if (n_children > 0 && debug) {
2237 	dbglog("Waiting for %d child processes...", n_children);
2238 	for (chp = children; chp != NULL; chp = chp->next)
2239 	    dbglog("  pid %d: %s", chp->pid, chp->prog);
2240     }
2241     BZERO(&sa, sizeof (sa));
2242 /*CONSTANTCONDITION*/ SIGNAL(SIGALRM, infanticide);
2243     while (n_children > 0) {
2244 	(void) alarm(7);
2245 	if (reap_kids(1) < 0)
2246 	    break;
2247     }
2248     (void) alarm(0);
2249 }
2250 
2251 /*
2252  * novm - log an error message saying we ran out of memory, and die.
2253  */
2254 void
2255 novm(msg)
2256     char *msg;
2257 {
2258     fatal("Virtual memory exhausted allocating %s\n", msg);
2259 }
2260 
2261 /*
2262  * script_setenv - set an environment variable value to be used
2263  * for scripts that we run (e.g. ip-up, auth-up, etc.)
2264  */
2265 void
2266 script_setenv(var, value, iskey)
2267     const char *var;
2268     const char *value;
2269     int iskey;
2270 {
2271     size_t varl = strlen(var);
2272     size_t vl = varl + strlen(value) + 2;
2273     int i;
2274     char *p, *newstring;
2275 
2276     /*
2277      * XXX: Can we assert that a tdb write lock is held here ?  It appears that
2278      *	    Linux's use of tdb is not safe.
2279      */
2280     newstring = (char *) malloc(vl+1);
2281     if (newstring == NULL) {
2282 	novm("script environment string");
2283 	return;
2284     }
2285     *newstring++ = iskey;
2286     (void) slprintf(newstring, vl, "%s=%s", var, value);
2287 
2288     /* check if this variable is already set */
2289     if (script_env != NULL) {
2290 	for (i = 0; (p = script_env[i]) != NULL; ++i) {
2291 	    if (strncmp(p, var, varl) == 0 && p[varl] == '=') {
2292 #ifdef HAVE_MULTILINK
2293 		if (p[-1] != '\0' && pppdb != NULL)
2294 		    delete_db_key(p);
2295 #endif
2296 		free(p-1);
2297 		script_env[i] = newstring;
2298 #ifdef HAVE_MULTILINK
2299 		if (iskey && pppdb != NULL)
2300 		    add_db_key(newstring);
2301 		update_db_entry();
2302 #endif
2303 		return;
2304 	    }
2305 	}
2306     } else {
2307 	/* no space allocated for script env. ptrs. yet */
2308 	i = 0;
2309 	script_env = (char **) malloc(16 * sizeof(char *));
2310 	if (script_env == NULL) {
2311 	    novm("script environment variable.");
2312 	    return;
2313 	}
2314 	s_env_nalloc = 16;
2315     }
2316 
2317     /* reallocate script_env with more space if needed */
2318     if (i + 1 >= s_env_nalloc) {
2319 	int new_n = i + 17;
2320 	char **newenv = (char **) realloc((void *)script_env,
2321 					  new_n * sizeof(char *));
2322 	if (newenv == NULL) {
2323 	    novm("expanded script environment variable.");
2324 	    return;
2325 	}
2326 	script_env = newenv;
2327 	s_env_nalloc = new_n;
2328     }
2329 
2330     script_env[i] = newstring;
2331     script_env[i+1] = NULL;
2332 
2333 #ifdef HAVE_MULTILINK
2334     if (pppdb != NULL) {
2335 	if (iskey)
2336 	    add_db_key(newstring);
2337 	update_db_entry();
2338     }
2339 #endif
2340 }
2341 
2342 /*
2343  * script_unsetenv - remove a variable from the environment
2344  * for scripts.
2345  */
2346 void
2347 script_unsetenv(var)
2348     const char *var;
2349 {
2350     int vl = strlen(var);
2351     int i;
2352     char *p;
2353 
2354     /*
2355      * XXX: Can we assert that a tdb write lock is held here ?  It appears that
2356      *	    Linux's use of tdb is not safe.
2357      */
2358     if (script_env == NULL)
2359 	return;
2360     for (i = 0; (p = script_env[i]) != NULL; ++i) {
2361 	if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
2362 #ifdef HAVE_MULTILINK
2363 	    if (p[-1] != '\0' && pppdb != NULL)
2364 		delete_db_key(p);
2365 #endif
2366 	    free(p-1);
2367 	    while ((script_env[i] = script_env[i+1]) != NULL)
2368 		++i;
2369 	    break;
2370 	}
2371     }
2372 #ifdef HAVE_MULTILINK
2373     if ((pppdb != NULL) && (p != NULL))
2374 	update_db_entry();
2375 #endif
2376 }
2377 
2378 /*
2379  * script_getenv - find a variable in the script environment.
2380  */
2381 const char *
2382 script_getenv(var)
2383     const char *var;
2384 {
2385     int vl = strlen(var);
2386     int i;
2387     char *p;
2388 
2389     if (script_env == NULL)
2390 	return (NULL);
2391     for (i = 0; (p = script_env[i]) != NULL; ++i) {
2392 	if (strncmp(p, var, vl) == 0 && p[vl] == '=')
2393 	    return ((const char *)p+vl+1);
2394     }
2395     return (NULL);
2396 }
2397 
2398 #ifdef HAVE_MULTILINK
2399 /*
2400  * update_db_entry - update our entry in the database.
2401  */
2402 static void
2403 update_db_entry()
2404 {
2405     TDB_DATA key, dbuf;
2406     int vlen, i;
2407     char *p, *q, *vbuf;
2408 
2409     if (script_env == NULL)
2410 	return;
2411     /*
2412      * vlen needs to be initialized as 1, or otherwise, the last string
2413      * is truncated by slprintf.
2414      */
2415     vlen = 1;
2416     for (i = 0; (p = script_env[i]) != NULL; ++i)
2417 	vlen += strlen(p) + 1;
2418     vbuf = malloc(vlen);
2419     if (vbuf == NULL)
2420 	novm("database entry");
2421     q = vbuf;
2422     for (i = 0; (p = script_env[i]) != NULL; ++i)
2423 	q += slprintf(q, vbuf + vlen - q, "%s;", p);
2424 
2425     key.dptr = db_key;
2426     key.dsize = strlen(db_key);
2427     dbuf.dptr = vbuf;
2428     dbuf.dsize = vlen;
2429     if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
2430 	error("tdb_store failed: %s", tdb_error(pppdb));
2431 }
2432 
2433 /*
2434  * add_db_key - add a key that we can use to look up our database entry.
2435  */
2436 static void
2437 add_db_key(str)
2438     const char *str;
2439 {
2440     TDB_DATA key, dbuf;
2441 
2442     key.dptr = (char *) str;
2443     key.dsize = strlen(str);
2444     dbuf.dptr = db_key;
2445     dbuf.dsize = strlen(db_key);
2446     if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
2447 	error("tdb_store key failed: %s", tdb_error(pppdb));
2448 }
2449 
2450 /*
2451  * delete_db_key - delete a key for looking up our database entry.
2452  */
2453 static void
2454 delete_db_key(str)
2455     const char *str;
2456 {
2457     TDB_DATA key;
2458 
2459     key.dptr = (char *) str;
2460     key.dsize = strlen(str);
2461     (void) tdb_delete(pppdb, key);
2462 }
2463 
2464 /*
2465  * cleanup_db - delete all the entries we put in the database.
2466  */
2467 static void
2468 cleanup_db()
2469 {
2470     TDB_DATA key;
2471     int i;
2472     char *p;
2473 
2474     key.dptr = db_key;
2475     key.dsize = strlen(db_key);
2476     (void) tdb_delete(pppdb, key);
2477     for (i = 0; (p = script_env[i]) != NULL; ++i)
2478 	if (p[-1] != '\0')
2479 	    delete_db_key(p);
2480 }
2481 #endif /* HAVE_MULTILINK */
2482 
2483 /*
2484  * open_socket - establish a stream socket connection to the nominated
2485  * host and port.
2486  * XXX: Need IPv6 support for those systems that support it (use getaddrinfo),
2487  *	but requires portability changes.
2488  */
2489 static int
2490 open_socket(dest)
2491     char *dest;
2492 {
2493     char *sep, *endp = NULL;
2494     int sock;
2495     int port = -1;
2496     u_int32_t host;
2497     struct hostent *hent = NULL;
2498     struct sockaddr_in sad;
2499     struct servent *se;
2500 
2501     /* parse host:port and resolve host to an IP address */
2502     sep = strchr(dest, ':');
2503     if (sep != NULL) {
2504 	se = getservbyname((const char *)sep+1, "tcp");
2505 	if (se != NULL) {
2506 	    port = ntohs(se->s_port);
2507 	} else {
2508 	    port = strtol(sep+1, &endp, 10);
2509 	    if (endp == sep+1 || *endp != '\0') {
2510 		error("Can't parse host:port for socket destination");
2511 		return (-1);
2512 	    }
2513 	}
2514     }
2515     if (port < 0 || port > 65535 || sep == dest) {
2516 	error("Can't parse host:port for socket destination");
2517 	return (-1);
2518     }
2519     *sep = '\0';
2520     host = inet_addr(dest);
2521     if (host == (u_int32_t) -1) {
2522 	hent = gethostbyname(dest);
2523 	if (hent == NULL) {
2524 	    error("%s: unknown host in socket option", dest);
2525 	    *sep = ':';
2526 	    return (-1);
2527 	}
2528 	BCOPY(hent->h_addr_list[0], &host, sizeof(host));
2529 	hent->h_addr_list++;
2530     }
2531     *sep = ':';
2532 
2533     for (;;) {
2534 	/* get a socket and connect it to the other end */
2535 	sock = socket(PF_INET, SOCK_STREAM, 0);
2536 	if (sock < 0) {
2537 	    error("Can't create socket: %m");
2538 	    return (-1);
2539 	}
2540 	BZERO(&sad, sizeof(sad));
2541 	sad.sin_family = AF_INET;
2542 	sad.sin_port = htons(port);
2543 	sad.sin_addr.s_addr = host;
2544 	if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) >= 0) {
2545 	    break;  /* return sock file descriptor */
2546 	}
2547 	if ((hent != NULL) && (hent->h_addr_list != NULL)) {
2548 	    BCOPY(hent->h_addr_list[0], &host, sizeof(host));
2549 	    hent->h_addr_list++;
2550 	    (void) close(sock);
2551 	    continue;
2552 	}
2553 	error("Can't connect to %s: %m", dest);
2554 	(void) close(sock);
2555 	return (-1);
2556     }
2557     return (sock);
2558 }
2559 
2560 /*
2561  * print_ncpstate - prints out current NCP state.
2562  *
2563  * We're normally called from SIGUSR1 here, but this is safe because
2564  * these signals are blocked unless we're idle waiting for events.
2565  * There's no need to otherwise lock the data structures referenced.
2566  */
2567 void
2568 print_ncpstate(unit, strptr)
2569     int unit;
2570     FILE *strptr;
2571 {
2572     struct protent *protp;
2573     int i;
2574 
2575     (void) flprintf(strptr, "In %s phase\n", phase_name(phase));
2576     for (i = 0; (protp = protocols[i]) != NULL; ++i) {
2577 	if (protp->print_stat != NULL)
2578 	    (*protp->print_stat)(unit, strptr);
2579     }
2580     sys_print_state(strptr);
2581 }
2582 
2583 /*
2584  * start_charshunt - create a child process to run the character shunt.
2585  */
2586 static int
2587 start_charshunt(ifd, ofd)
2588     int ifd, ofd;
2589 {
2590     pid_t cpid;
2591 
2592     cpid = fork();
2593     if (cpid == (pid_t)-1) {
2594 	error("Can't fork process for character shunt: %m");
2595 	return (0);
2596     }
2597     if (cpid == (pid_t)0) {
2598 	/* child */
2599 	(void) close(pty_slave);
2600 	pty_slave = -1;
2601 	(void) setgid(getgid());
2602 	(void) setuid(uid);
2603 	if (getuid() != uid)
2604 	    fatal("setuid failed");
2605 	if (!nodetach)
2606 	    log_to_fd = -1;
2607 	charshunt(ifd, ofd, record_file);
2608 	exit(0);
2609     }
2610     charshunt_pid = cpid;
2611     (void) close(pty_master);
2612     pty_master = -1;
2613     ttyfd = pty_slave;
2614     record_child(cpid, "pppd (charshunt)", charshunt_done, NULL);
2615     return (1);
2616 }
2617 
2618 /*ARGSUSED*/
2619 static void
2620 charshunt_done(arg, status)
2621     void *arg;
2622     int status;
2623 {
2624     charshunt_pid = (pid_t)0;
2625 }
2626 
2627 static void
2628 reportme(int signo)
2629 {
2630     dbglog("charshunt taking signal %d", signo);
2631     exit(1);
2632 }
2633 
2634 /*
2635  * charshunt - the character shunt, which passes characters between
2636  * the pty master side and the serial port (or stdin/stdout).
2637  * This runs as the user (not as root).
2638  * (We assume ofd >= ifd which is true the way this gets called. :-).
2639  */
2640 static void
2641 charshunt(ifd, ofd, record_file)
2642     int ifd, ofd;
2643     char *record_file;
2644 {
2645     int n, nfds;
2646     fd_set ready, writey;
2647     u_char *ibufp, *obufp;
2648     int nibuf, nobuf;
2649     int flags;
2650     struct timeval lasttime;
2651     FILE *recordf = NULL;
2652     int ilevel, olevel, max_level;
2653     struct timeval levelt, tout, *top;
2654 
2655     /*
2656      * Reset signal handlers.
2657      */
2658     (void) signal(SIGHUP, SIG_IGN);		/* Hangup */
2659     (void) signal(SIGINT, reportme);		/* Interrupt */
2660     (void) signal(SIGTERM, reportme);		/* Terminate */
2661     (void) signal(SIGCHLD, reportme);
2662     (void) signal(SIGUSR1, reportme);
2663     (void) signal(SIGUSR2, reportme);
2664     (void) signal(SIGABRT, reportme);
2665     (void) signal(SIGALRM, reportme);
2666     (void) signal(SIGFPE, reportme);
2667     (void) signal(SIGILL, reportme);
2668     (void) signal(SIGPIPE, reportme);
2669     (void) signal(SIGQUIT, reportme);
2670 #ifndef DEBUG
2671     (void) signal(SIGSEGV, reportme);
2672 #endif
2673 #ifdef SIGBUS
2674     (void) signal(SIGBUS, reportme);
2675 #endif
2676 #ifdef SIGEMT
2677     (void) signal(SIGEMT, reportme);
2678 #endif
2679 #ifdef SIGPOLL
2680     (void) signal(SIGPOLL, reportme);
2681 #endif
2682 #ifdef SIGPROF
2683     (void) signal(SIGPROF, reportme);
2684 #endif
2685 #ifdef SIGSYS
2686     (void) signal(SIGSYS, reportme);
2687 #endif
2688 #ifdef SIGTRAP
2689     (void) signal(SIGTRAP, reportme);
2690 #endif
2691 #ifdef SIGVTALRM
2692     (void) signal(SIGVTALRM, reportme);
2693 #endif
2694 #ifdef SIGXCPU
2695     (void) signal(SIGXCPU, reportme);
2696 #endif
2697 #ifdef SIGXFSZ
2698     (void) signal(SIGXFSZ, reportme);
2699 #endif
2700 
2701     /*
2702      * Open the record file if required.
2703      */
2704     if (record_file != NULL) {
2705 	recordf = fopen(record_file, "a");
2706 	if (recordf == NULL)
2707 	    error("Couldn't create record file %s: %m", record_file);
2708     }
2709 
2710     /* set all the fds to non-blocking mode */
2711     flags = fcntl(pty_master, F_GETFL);
2712     if (flags == -1
2713 	|| fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1)
2714 	warn("couldn't set pty master to nonblock: %m");
2715     flags = fcntl(ifd, F_GETFL);
2716     if (flags == -1
2717 	|| fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1)
2718 	warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty"));
2719     if (ofd != ifd) {
2720 	flags = fcntl(ofd, F_GETFL);
2721 	if (flags == -1
2722 	    || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1)
2723 	    warn("couldn't set stdout to nonblock: %m");
2724     }
2725 
2726     nibuf = nobuf = 0;
2727     ibufp = obufp = NULL;
2728 
2729     ilevel = olevel = 0;
2730     (void) gettimeofday(&levelt, NULL);
2731     if (max_data_rate) {
2732 	max_level = max_data_rate / 10;
2733 	if (max_level < MAXLEVELMINSIZE)
2734 	    max_level = MAXLEVELMINSIZE;
2735     } else
2736 	max_level = sizeof(inpacket_buf) + 1;
2737 
2738     nfds = (ofd > pty_master? ofd: pty_master) + 1;
2739     if (recordf != NULL) {
2740 	(void) gettimeofday(&lasttime, NULL);
2741 	(void) putc(RECMARK_TIMESTART, recordf);	/* put start marker */
2742 	(void) putc(lasttime.tv_sec >> 24, recordf);
2743 	(void) putc(lasttime.tv_sec >> 16, recordf);
2744 	(void) putc(lasttime.tv_sec >> 8, recordf);
2745 	(void) putc(lasttime.tv_sec, recordf);
2746 	lasttime.tv_usec = 0;
2747     }
2748 
2749     while (nibuf != 0 || nobuf != 0 || ofd >= 0 || pty_master >= 0) {
2750 	top = 0;
2751 	tout.tv_sec = 0;
2752 	tout.tv_usec = 10000;
2753 	FD_ZERO(&ready);
2754 	FD_ZERO(&writey);
2755 	if (nibuf != 0) {
2756 	    if (ilevel >= max_level)
2757 		top = &tout;
2758 	    else if (pty_master >= 0)
2759 		FD_SET(pty_master, &writey);
2760 	} else if (ifd >= 0)
2761 	    FD_SET(ifd, &ready);
2762 	if (nobuf != 0) {
2763 	    if (olevel >= max_level)
2764 		top = &tout;
2765 	    else if (ofd >= 0)
2766 		FD_SET(ofd, &writey);
2767 	} else {
2768 	    /* Don't read from pty if it's gone or it has closed. */
2769 	    if (pty_master >= 0 && ofd >= 0)
2770 		FD_SET(pty_master, &ready);
2771 	}
2772 	if (select(nfds, &ready, &writey, NULL, top) < 0) {
2773 	    if (errno != EINTR)
2774 		fatal("select");
2775 	    continue;
2776 	}
2777 	if (max_data_rate) {
2778 	    double dt;
2779 	    int nbt;
2780 	    struct timeval now;
2781 
2782 	    (void) gettimeofday(&now, NULL);
2783 	    dt = (now.tv_sec - levelt.tv_sec
2784 		  + (now.tv_usec - levelt.tv_usec) / 1e6);
2785 	    nbt = (int)(dt * max_data_rate);
2786 	    ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt;
2787 	    olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt;
2788 	    levelt = now;
2789 	} else
2790 	    ilevel = olevel = 0;
2791 	if (FD_ISSET(ifd, &ready)) {
2792 	    ibufp = inpacket_buf;
2793 	    nibuf = read(ifd, ibufp, sizeof(inpacket_buf));
2794 	    if (nibuf < 0 && errno == EIO)
2795 		nibuf = 0;
2796 	    if (nibuf < 0 || pty_master == -1) {
2797 		if (errno != EINTR && errno != EAGAIN) {
2798 		    error("Error reading standard input: %m");
2799 		    break;
2800 		}
2801 		nibuf = 0;
2802 	    } else if (nibuf == 0) {
2803 		/* end of file from stdin */
2804 		(void) close(pty_master);
2805 		pty_master = -1;
2806 		(void) close(ifd);
2807 		ifd = -1;
2808 		if (recordf)
2809 		    if (!record_write(recordf, RECMARK_ENDRECV, NULL, 0,
2810 			&lasttime))
2811 			recordf = NULL;
2812 	    } else {
2813 		FD_SET(pty_master, &writey);
2814 		if (recordf)
2815 		    if (!record_write(recordf, RECMARK_STARTRECV, ibufp, nibuf,
2816 			&lasttime))
2817 			recordf = NULL;
2818 	    }
2819 	}
2820 	if (ofd >= 0 && pty_master >= 0 && FD_ISSET(pty_master, &ready)) {
2821 	    obufp = outpacket_buf;
2822 	    nobuf = read(pty_master, obufp, sizeof(outpacket_buf));
2823 	    if (nobuf < 0 && errno == EIO)
2824 		nobuf = 0;
2825 	    if (nobuf < 0 || ofd == -1) {
2826 		if (!(errno == EINTR || errno == EAGAIN)) {
2827 		    error("Error reading pseudo-tty master: %m");
2828 		    break;
2829 		}
2830 		nobuf = 0;
2831 	    } else if (nobuf == 0) {
2832 		/* end of file from the pty - slave side has closed */
2833 		nibuf = 0;
2834 		(void) close(ofd);
2835 		ofd = -1;
2836 		if (recordf)
2837 		    if (!record_write(recordf, RECMARK_ENDSEND, NULL, 0,
2838 			&lasttime))
2839 			recordf = NULL;
2840 	    } else {
2841 		FD_SET(ofd, &writey);
2842 		if (recordf)
2843 		    if (!record_write(recordf, RECMARK_STARTSEND, obufp, nobuf,
2844 			&lasttime))
2845 			recordf = NULL;
2846 	    }
2847 	}
2848 	if (ofd == -1)
2849 	    nobuf = 0;
2850 	else if (FD_ISSET(ofd, &writey)) {
2851 	    n = nobuf;
2852 	    if (olevel + n > max_level)
2853 		n = max_level - olevel;
2854 	    n = write(ofd, obufp, n);
2855 	    if (n < 0) {
2856 		if (errno == EIO) {
2857 		    (void) close(ofd);
2858 		    ofd = -1;
2859 		    nobuf = 0;
2860 		} else if (errno != EAGAIN && errno != EINTR) {
2861 		    error("Error writing standard output: %m");
2862 		    break;
2863 		}
2864 	    } else {
2865 		obufp += n;
2866 		nobuf -= n;
2867 		olevel += n;
2868 	    }
2869 	}
2870 	if (pty_master == -1)
2871 	    nibuf = 0;
2872 	else if (FD_ISSET(pty_master, &writey)) {
2873 	    n = nibuf;
2874 	    if (ilevel + n > max_level)
2875 		n = max_level - ilevel;
2876 	    n = write(pty_master, ibufp, n);
2877 	    if (n < 0) {
2878 		if (errno == EAGAIN || errno == EINTR)
2879 		    continue;
2880 		if (errno != EIO) {
2881 		    error("Error writing pseudo-tty master: %m");
2882 		    break;
2883 		}
2884 		(void) close(pty_master);
2885 		pty_master = -1;
2886 		nibuf = 0;
2887 	    } else {
2888 		ibufp += n;
2889 		nibuf -= n;
2890 		ilevel += n;
2891 	    }
2892 	}
2893     }
2894     exit(0);
2895 }
2896 
2897 static int
2898 record_write(f, code, buf, nb, tp)
2899     FILE *f;
2900     int code;
2901     u_char *buf;
2902     int nb;
2903     struct timeval *tp;
2904 {
2905     struct timeval now;
2906     int diff;
2907 
2908     (void) gettimeofday(&now, NULL);
2909     now.tv_usec /= 100000;	/* actually 1/10 s, not usec now */
2910     diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec);
2911     if (diff > 0) {
2912 	if (diff > 255) {
2913 	    (void) putc(RECMARK_TIMEDELTA32, f);
2914 	    (void) putc(diff >> 24, f);
2915 	    (void) putc(diff >> 16, f);
2916 	    (void) putc(diff >> 8, f);
2917 	    (void) putc(diff, f);
2918 	} else {
2919 	    (void) putc(RECMARK_TIMEDELTA8, f);
2920 	    (void) putc(diff, f);
2921 	}
2922 	*tp = now;
2923     }
2924     (void) putc(code, f);
2925     if (buf != NULL) {
2926 	(void) putc(nb >> 8, f);
2927 	(void) putc(nb, f);
2928 	(void) fwrite(buf, nb, 1, f);
2929     }
2930     (void) fflush(f);
2931     if (ferror(f)) {
2932 	error("Error writing record file: %m");
2933 	return (0);
2934     }
2935     return (1);
2936 }
2937