2 * main.c - Point-to-Point Protocol main module
4 * Copyright (c) 1989 Carnegie Mellon University.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by Carnegie Mellon University. The name of the
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 #define RCSID "$Id: main.c,v 1.7 2004/08/12 02:56:55 tallest Exp $"
35 #include <sys/param.h>
36 #include <sys/types.h>
39 #include <sys/resource.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
56 #include "pathnames.h"
64 #endif /* IPX_CHANGE */
69 static const char rcsid
[] = RCSID
;
72 char ifname
[32]; /* Interface name */
73 int ifunit
; /* Interface unit number */
76 struct channel
*the_channel
;
78 char *progname
; /* Name of this program */
79 char hostname
[MAXNAMELEN
]; /* Our hostname */
80 static char pidfilename
[MAXPATHLEN
]; /* name of pid file */
81 static char linkpidfile
[MAXPATHLEN
]; /* name of linkname pid file */
82 char ppp_devnam
[MAXPATHLEN
]; /* name of PPP tty (maybe ttypx) */
83 uid_t uid
; /* Our real user-id */
85 int hungup
; /* terminal has been hung up */
86 int privileged
; /* we're running as real uid root */
87 int need_holdoff
; /* need holdoff period before restarting */
88 int detached
; /* have detached from terminal */
89 volatile int status
; /* exit status for pppd */
90 int unsuccess
; /* # unsuccessful connection attempts */
91 int do_callback
; /* != 0 if we should do callback next */
92 int doing_callback
; /* != 0 if we are doing callback */
95 // int (*holdoff_hook) __P((void)) = NULL;
96 int (*new_phase_hook
) __P((int)) = NULL
;
98 static int conn_running
; /* we have a [dis]connector running */
99 static int devfd
; /* fd of underlying device */
100 static int fd_ppp
= -1; /* fd for talking PPP */
101 static int fd_loop
; /* fd for getting demand-dial packets */
103 int phase
; /* where the link is at */
112 static sigjmp_buf sigjmp
;
114 char **script_env
; /* Env. variable values for scripts */
115 int s_env_nalloc
; /* # words avail at script_env */
117 u_char outpacket_buf
[PPP_MRU
+PPP_HDRLEN
]; /* buffer for outgoing packet */
118 u_char inpacket_buf
[PPP_MRU
+PPP_HDRLEN
]; /* buffer for incoming packet */
120 static int n_children
; /* # child processes still running */
121 static int got_sigchld
; /* set if we have received a SIGCHLD */
123 int privopen
; /* don't lock, open device as root */
125 char *no_ppp_msg
= "Sorry - this system lacks PPP kernel support\n";
127 GIDSET_TYPE groups
[NGROUPS_MAX
];/* groups the user is in */
128 int ngroups
; /* How many groups valid in groups */
130 static struct timeval start_time
; /* Time when link was started. */
132 struct pppd_stats link_stats
;
133 int link_connect_time
;
134 int link_stats_valid
;
136 const char pppoe_disc_file
[] = "/var/lib/misc/pppoe-disc";
140 * We maintain a list of child process pids and
141 * functions to call when they exit.
146 void (*done
) __P((void *));
148 struct subprocess
*next
;
151 static struct subprocess
*children
;
153 /* Prototypes for procedures local to this file. */
155 static void setup_signals
__P((void));
156 static void create_pidfile
__P((void));
157 static void create_linkpidfile
__P((void));
158 static void cleanup
__P((void));
159 static void get_input
__P((void));
160 static void calltimeout
__P((void));
161 static struct timeval
*timeleft
__P((struct timeval
*));
162 static void kill_my_pg
__P((int));
163 static void hup
__P((int));
164 static void term
__P((int));
165 static void chld
__P((int));
166 static void toggle_debug
__P((int));
167 static void open_ccp
__P((int));
168 static void bad_signal
__P((int));
169 static void holdoff_end
__P((void *));
170 static int reap_kids
__P((int waitfor
));
171 #define update_db_entry()
172 #define add_db_key(a)
173 #define delete_db_key(a)
175 static void handle_events
__P((void));
177 extern char *ttyname
__P((int));
178 extern char *getlogin
__P((void));
179 int main
__P((int, char *[]));
181 extern void prng_init(); // random.c
186 #define O_NONBLOCK O_NDELAY
190 #define setlogmask(x)
194 * PPP Data Link Layer "protocol" table.
195 * One entry per supported protocol.
196 * The last entry must be NULL.
198 struct protent
*protocols
[] = {
215 * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name.
217 #if !defined(PPP_DRV_NAME)
218 #define PPP_DRV_NAME "ppp"
219 #endif /* !defined(PPP_DRV_NAME) */
221 extern int retransmit_time
;
222 extern int redial_immediately
;
225 int debug_exist(const char *name)
228 return (stat(name, &st) == 0);
240 struct protent
*protp
;
243 new_phase(PHASE_INITIALIZE
);
246 * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
247 * This way we can close 0, 1, 2 in detach() without clobbering
248 * a fd that we are using.
250 if ((i
= open("/dev/null", O_RDWR
)) >= 0) {
251 while (0 <= i
&& i
<= 2)
259 /* Initialize syslog facilities */
262 if (gethostname(hostname
, MAXNAMELEN
) < 0 ) {
263 LOGX_ERROR("Couldn't get hostname");
264 option_error("Couldn't get hostname: %m");
267 hostname
[MAXNAMELEN
-1] = 0;
269 /* make sure we don't create world or group writable files. */
270 umask(umask(0777) | 022);
273 privileged
= uid
== 0;
274 slprintf(numbuf
, sizeof(numbuf
), "%d", uid
);
275 script_setenv("ORIG_UID", numbuf
, 0);
277 ngroups
= getgroups(NGROUPS_MAX
, groups
);
280 * Initialize magic number generator now so that protocols may
281 * use magic numbers in initialization.
286 * Initialize each protocol.
288 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
294 * Parse, in order, the system options file, the user's options file,
295 * and the command line arguments.
298 if (!parse_args(argc
, argv
))
299 exit(EXIT_OPTION_ERROR
);
300 devnam_fixed
= 1; /* can no longer change device name */
302 reopen_log(); // According to ipparam value, decide log name
305 * Work out the device name, if it hasn't already been specified,
306 * and parse the tty's options file.
308 if (the_channel
->process_extra_options
)
309 (*the_channel
->process_extra_options
)();
312 setlogmask(LOG_UPTO(LOG_DEBUG
));
315 * Check that we are running as root.
317 if (geteuid() != 0) {
318 option_error("must be root to run %s, since it is not setuid-root",
323 if (!ppp_available()) {
324 option_error("%s", no_ppp_msg
);
325 exit(EXIT_NO_KERNEL_SUPPORT
);
329 * Check that the options given are valid and consistent.
332 if (!sys_check_options())
333 exit(EXIT_OPTION_ERROR
);
334 auth_check_options();
335 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
336 if (protp
->check_options
!= NULL
)
337 (*protp
->check_options
)();
338 if (the_channel
->check_options
)
339 (*the_channel
->check_options
)();
342 if (dump_options
|| dryrun
) {
343 init_pr_log(NULL
, LOG_INFO
);
344 print_options(pr_log
, NULL
);
351 * Initialize system-dependent stuff.
356 * Initialize random seed.
361 * Detach ourselves from the terminal, if required,
362 * and identify who is running us.
364 if (!nodetach
&& !updetach
)
369 if (pw
!= NULL
&& pw
->pw_name
!= NULL
)
375 LOGX_INFO("Starting");
376 LOGX_DEBUG("demand=%d", demand
);
378 script_setenv("PPPLOGNAME", p
, 0);
381 script_setenv("DEVICE", devnam
, 1);
382 slprintf(numbuf
, sizeof(numbuf
), "%d", getpid());
383 script_setenv("PPPD_PID", numbuf
, 1);
389 create_linkpidfile();
392 * If we're doing dial-on-demand, set up the interface now.
396 * Open the loopback channel and set it up to be the ppp interface.
398 fd_loop
= open_ppp_loopback();
402 * Configure the interface and mark it up, etc.
417 doing_callback
= do_callback
;
420 if (demand
&& !doing_callback
) {
422 * Don't do anything until we see some activity.
424 LOGX_DEBUG("%s: PHASE_DORMANT", __FUNCTION__
);
425 new_phase(PHASE_DORMANT
);
430 if (kill_link
&& !persist
)
432 if (get_loop_output()) {
437 if (kill_link
&& !persist
) {
438 LOGX_DEBUG("%s: (kill_link && !persist)", __FUNCTION__
);
443 * Now we want to bring up the link.
446 info("Starting link");
447 } // if (demand && !doing_callback)
449 new_phase(PHASE_SERIALCONN
);
451 devfd
= the_channel
->connect();
452 LOGX_DEBUG("%s: the_channel->connect()=%d", __FUNCTION__
, devfd
);
454 redial_immediately
= 0;
458 /* set up the serial device as a ppp interface */
459 fd_ppp
= the_channel
->establish_ppp(devfd
);
460 LOGX_DEBUG("%s: the_channel->establish_ppp()=%d", __FUNCTION__
, fd_ppp
);
462 status
= EXIT_FATAL_ERROR
;
466 if (!demand
&& ifunit
>= 0)
470 * Start opening the connection and wait for
471 * incoming events (reply, timeout, etc.).
473 notice("Connect: %s <--> %s", ifname
, ppp_devnam
);
474 my_gettimeofday(&start_time
, NULL
);
475 link_stats_valid
= 0;
476 script_unsetenv("CONNECT_TIME");
477 script_unsetenv("BYTES_SENT");
478 script_unsetenv("BYTES_RCVD");
482 lcp_open(0); /* Start protocol */
483 status
= EXIT_NEGOTIATION_FAILED
;
484 new_phase(PHASE_ESTABLISH
);
485 while (phase
!= PHASE_DEAD
) {
489 lcp_close(0, "User request");
492 if (phase
== PHASE_NETWORK
|| phase
== PHASE_RUNNING
) {
493 ccp_fsm
[0].flags
= OPT_RESTART
; /* clears OPT_SILENT */
494 (*ccp_protent
.open
)(0);
498 } // while (phase != PHASE_DEAD)
500 LOGX_DEBUG("%s: phase == PHASE_DEAD", __FUNCTION__
);
503 * Print connect time and statistics.
505 LOGX_NOTICE("Disconnected.");
506 if (link_stats_valid
) {
507 int tt
= (link_connect_time
+ 5) / 6; /* 1/10ths of minutes */
508 LOGX_NOTICE("Connect time %d.%d minutes.", tt
/ 10, tt
% 10);
509 LOGX_NOTICE("Sent %u bytes, received %u bytes.", link_stats
.bytes_out
, link_stats
.bytes_in
);
513 * Delete pid file before disestablishing ppp. Otherwise it
514 * can happen that another pppd gets the same unit and then
515 * we delete its pid file.
518 if (pidfilename
[0] != 0
519 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
520 warn("unable to delete pid file %s: %m", pidfilename
);
525 * If we may want to bring the link up again, transfer
526 * the ppp unit back to the loopback. Set the
527 * real serial device back to its normal mode of operation.
531 the_channel
->disestablish_ppp(devfd
);
536 script_unsetenv("IFNAME");
539 LOGX_DEBUG("%s: disconnect", __FUNCTION__
);
545 new_phase(PHASE_DISCONNECT
);
546 the_channel
->disconnect();
548 if (the_channel
->cleanup
)
549 (*the_channel
->cleanup
)();
552 if (pidfilename
[0] != 0
553 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
554 warn("unable to delete pid file %s: %m", pidfilename
);
558 if (!persist
|| (maxfail
> 0 && unsuccess
>= maxfail
))
564 LOGX_DEBUG("%s: redial_immediately=%d", __FUNCTION__
, redial_immediately
);
566 /***************************************
567 * modify by tanghui 2006-03-28
568 * first 3 time set to 15 sec
569 * after that, should try to redial randomly
570 * FIXME: has send a PADI before HOLDOFF so, (3 - 1)
571 ***************************************/
572 if (!redial_immediately
)
582 holdoff
= (int)(3 + (((retransmit_time
- 3.0) * rand())/ (RAND_MAX
+ 1.0)));
583 if((holdoff
> 93) && (holdoff
> retransmit_time
- 90))
587 //holdoff = 3 + gen_random_int(retransmit_time - 3);
598 t
= 10; //modified from 0 to 10 //by crazy 20070508
599 redial_immediately
= 0;
602 LOGX_DEBUG("%s: t=%d", __FUNCTION__
, t
);
605 new_phase(PHASE_HOLDOFF
);
606 TIMEOUT(holdoff_end
, NULL
, t
);
610 new_phase(PHASE_DORMANT
); /* allow signal to end holdoff */
611 } while (phase
== PHASE_HOLDOFF
);
617 LOGX_DEBUG("%s: !need_holdoff", __FUNCTION__
);
621 /* Wait for scripts to finish */
622 while (n_children
> 0) {
624 struct subprocess
*chp
;
625 dbglog("Waiting for %d child processes...", n_children
);
626 for (chp
= children
; chp
!= NULL
; chp
= chp
->next
)
627 dbglog(" script %s, pid %d", chp
->prog
, chp
->pid
);
629 if (reap_kids(1) < 0)
638 * handle_events - wait for something to happen and respond to it.
646 kill_link
= open_ccp_flag
= 0;
647 if (sigsetjmp(sigjmp
, 1) == 0) {
648 sigprocmask(SIG_BLOCK
, &mask
, NULL
);
649 if (got_sighup
|| got_sigterm
|| got_sigusr2
|| got_sigchld
) {
650 sigprocmask(SIG_UNBLOCK
, &mask
, NULL
);
653 sigprocmask(SIG_UNBLOCK
, &mask
, NULL
);
654 wait_input(timeleft(&timo
));
662 if (status
!= EXIT_HANGUP
)
663 status
= EXIT_USER_REQUEST
;
671 * remove by tanghui @ 2006-03-31
672 * don't terminate the process
675 /*****************************/
677 status
= EXIT_USER_REQUEST
;
681 reap_kids(0); /* Don't leave dead kids lying around */
691 * setup_signals - initialize signal handling.
700 * Compute mask of all interesting signals and install signal handlers
701 * for each. Only one signal handler may be active at a time. Therefore,
702 * all other signals should be masked when any handler is executing.
705 sigaddset(&mask
, SIGHUP
);
706 sigaddset(&mask
, SIGINT
);
707 sigaddset(&mask
, SIGTERM
);
708 sigaddset(&mask
, SIGCHLD
);
709 sigaddset(&mask
, SIGUSR2
);
711 #define SIGNAL(s, handler) do { \
712 sa.sa_handler = handler; \
713 if (sigaction(s, &sa, NULL) < 0) \
714 fatal("Couldn't establish signal handler (%d): %m", s); \
719 SIGNAL(SIGHUP
, hup
); /* Hangup */
720 SIGNAL(SIGINT
, term
); /* Interrupt */
721 SIGNAL(SIGTERM
, term
); /* Terminate */
722 SIGNAL(SIGCHLD
, chld
);
724 SIGNAL(SIGUSR1
, toggle_debug
); /* Toggle debug flag */
725 SIGNAL(SIGUSR2
, open_ccp
); /* Reopen CCP */
728 * Install a handler for other signals which would otherwise
729 * cause pppd to exit without cleaning up.
731 SIGNAL(SIGABRT
, bad_signal
);
732 SIGNAL(SIGALRM
, bad_signal
);
733 SIGNAL(SIGFPE
, bad_signal
);
734 SIGNAL(SIGILL
, bad_signal
);
735 SIGNAL(SIGPIPE
, bad_signal
);
736 SIGNAL(SIGQUIT
, bad_signal
);
737 SIGNAL(SIGSEGV
, bad_signal
);
739 SIGNAL(SIGBUS
, bad_signal
);
742 SIGNAL(SIGEMT
, bad_signal
);
745 SIGNAL(SIGPOLL
, bad_signal
);
748 SIGNAL(SIGPROF
, bad_signal
);
751 SIGNAL(SIGSYS
, bad_signal
);
754 SIGNAL(SIGTRAP
, bad_signal
);
757 SIGNAL(SIGVTALRM
, bad_signal
);
760 SIGNAL(SIGXCPU
, bad_signal
);
763 SIGNAL(SIGXFSZ
, bad_signal
);
767 * Apparently we can get a SIGPIPE when we call syslog, if
768 * syslogd has died and been restarted. Ignoring it seems
771 signal(SIGPIPE
, SIG_IGN
);
775 * set_ifunit - do things we need to do once we know which ppp
782 info("Using interface %s%d", PPP_DRV_NAME
, ifunit
);
783 slprintf(ifname
, sizeof(ifname
), "%s%d", PPP_DRV_NAME
, ifunit
);
784 script_setenv("IFNAME", ifname
, iskey
);
786 char *arg
[3]={_PATH_SETPPPOEPID
, ipparam
, NULL
}; // tallest 1219
787 run_program(_PATH_SETPPPOEPID
,arg
,0,0,0);
790 create_pidfile(); /* write pid to file */
791 create_linkpidfile();
796 * detach - detach us from the controlling terminal.
806 if ((pid
= fork()) < 0) {
807 error("Couldn't detach (fork failed: %m)");
808 die(1); /* or just return? */
812 exit(0); /* parent dies */
822 /* update pid files if they have been written already */
826 create_linkpidfile();
827 slprintf(numbuf
, sizeof(numbuf
), "%d", getpid());
828 script_setenv("PPPD_PID", numbuf
, 1);
832 * reopen_log - (re)open our connection to syslog.
838 openlog("pppd", LOG_PID
);
840 #ifdef MPPPOE_SUPPORT
841 if(!strncmp(ipparam
, "0", 1))
842 openlog("pppoe", LOG_PID
| LOG_NDELAY
, LOG_PPP
);
844 openlog("pppoe-1", LOG_PID
| LOG_NDELAY
, LOG_PPP
);
846 openlog("pppoe", LOG_PID
| LOG_NDELAY
, LOG_PPP
);
848 setlogmask(LOG_UPTO(logmask
));
853 * Create a file containing our process ID.
860 slprintf(pidfilename
, sizeof(pidfilename
), "%s%s.pid",
861 _PATH_VARRUN
, ifname
);
862 if ((pidfile
= fopen(pidfilename
, "w")) != NULL
) {
863 fprintf(pidfile
, "%d\n", getpid());
864 (void) fclose(pidfile
);
866 error("Failed to create pid file %s: %m", pidfilename
);
876 if (linkname
[0] == 0)
878 script_setenv("LINKNAME", linkname
, 1);
879 slprintf(linkpidfile
, sizeof(linkpidfile
), "%sppp-%s.pid",
880 _PATH_VARRUN
, linkname
);
881 if ((pidfile
= fopen(linkpidfile
, "w")) != NULL
) {
882 fprintf(pidfile
, "%d\n", getpid());
884 fprintf(pidfile
, "%s\n", ifname
);
885 (void) fclose(pidfile
);
887 error("Failed to create pid file %s: %m", linkpidfile
);
893 * holdoff_end - called via a timeout when the holdoff period ends.
899 new_phase(PHASE_DORMANT
);
903 * get_input - called when incoming data is available.
911 struct protent
*protp
;
913 p
= inpacket_buf
; /* point to beginning of packet buffer */
915 len
= read_packet(inpacket_buf
);
920 notice("Modem hangup");
922 status
= EXIT_HANGUP
;
923 lcp_lowerdown(0); /* serial link is no longer available */
928 if (debug
/*&& (debugflags & DBG_INPACKET)*/)
929 dbglog("rcvd %P", p
, len
);
931 if (len
< PPP_HDRLEN
) {
932 MAINDEBUG(("io(): Received short packet."));
936 p
+= 2; /* Skip address and control */
937 GETSHORT(protocol
, p
);
941 * Toss all non-LCP packets unless LCP is OPEN.
943 if (protocol
!= PPP_LCP
&& lcp_fsm
[0].state
!= OPENED
) {
944 MAINDEBUG(("get_input: Received non-LCP packet when LCP not open."));
949 * Until we get past the authentication phase, toss all packets
950 * except LCP, LQR and authentication packets.
952 if (phase
<= PHASE_AUTHENTICATE
953 && !(protocol
== PPP_LCP
|| protocol
== PPP_LQR
954 || protocol
== PPP_PAP
|| protocol
== PPP_CHAP
)) {
955 MAINDEBUG(("get_input: discarding proto 0x%x in phase %d",
961 * Upcall the proper protocol input routine.
963 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
) {
964 if (protp
->protocol
== protocol
&& protp
->enabled_flag
) {
965 (*protp
->input
)(0, p
, len
);
968 if (protocol
== (protp
->protocol
& ~0x8000) && protp
->enabled_flag
969 && protp
->datainput
!= NULL
) {
970 (*protp
->datainput
)(0, p
, len
);
976 warn("Unsupported protocol 0x%x received", protocol
);
978 lcp_sprotrej(0, p
- PPP_HDRLEN
, len
+ PPP_HDRLEN
);
982 * new_phase - signal the start of a new phase of pppd's operation.
990 (*new_phase_hook
)(p
);
994 * die - clean up state and exit with the specified status.
1002 LOGX_INFO("Exiting");
1007 * cleanup - restore anything which needs to be restored before we exit
1016 the_channel
->disestablish_ppp(devfd
);
1017 if (the_channel
->cleanup
)
1018 (*the_channel
->cleanup
)();
1020 if (pidfilename
[0] != 0 && unlink(pidfilename
) < 0 && errno
!= ENOENT
)
1021 warn("unable to delete pid file %s: %m", pidfilename
);
1023 if (linkpidfile
[0] != 0 && unlink(linkpidfile
) < 0 && errno
!= ENOENT
)
1024 warn("unable to delete pid file %s: %m", linkpidfile
);
1027 unlink(pppoe_disc_file
);
1031 * update_link_stats - get stats at link termination.
1034 update_link_stats(u
)
1040 if (!get_ppp_stats(u
, &link_stats
)
1041 || my_gettimeofday(&now
, NULL
) < 0)
1043 link_connect_time
= now
.tv_sec
- start_time
.tv_sec
;
1044 link_stats_valid
= 1;
1046 slprintf(numbuf
, sizeof(numbuf
), "%d", link_connect_time
);
1047 script_setenv("CONNECT_TIME", numbuf
, 0);
1048 slprintf(numbuf
, sizeof(numbuf
), "%d", link_stats
.bytes_out
);
1049 script_setenv("BYTES_SENT", numbuf
, 0);
1050 slprintf(numbuf
, sizeof(numbuf
), "%d", link_stats
.bytes_in
);
1051 script_setenv("BYTES_RCVD", numbuf
, 0);
1056 struct timeval c_time
; /* time at which to call routine */
1057 void *c_arg
; /* argument to routine */
1058 void (*c_func
) __P((void *)); /* routine */
1059 struct callout
*c_next
;
1062 static struct callout
*callout
= NULL
; /* Callout list */
1063 static struct timeval timenow
; /* Current time */
1066 * timeout - Schedule a timeout.
1068 * Note that this timeout takes the number of milliseconds, NOT hz (as in
1072 timeout(func
, arg
, secs
, usecs
)
1073 void (*func
) __P((void *));
1077 struct callout
*newp
, *p
, **pp
;
1080 //MAINDEBUG(("Timeout %p:%p in %d.%03d seconds.", func, arg,
1081 // time / 1000, time % 1000));
1086 if ((newp
= (struct callout
*) malloc(sizeof(struct callout
))) == NULL
)
1087 fatal("Out of memory in timeout()!");
1089 newp
->c_func
= func
;
1090 my_gettimeofday(&timenow
, NULL
);
1091 newp
->c_time
.tv_sec
= timenow
.tv_sec
+ secs
;
1092 newp
->c_time
.tv_usec
= timenow
.tv_usec
+ usecs
;
1093 if (newp
->c_time
.tv_usec
>= 1000000) {
1094 newp
->c_time
.tv_sec
+= newp
->c_time
.tv_usec
/ 1000000;
1095 newp
->c_time
.tv_usec
%= 1000000;
1099 * Find correct place and link it in.
1101 for (pp
= &callout
; (p
= *pp
); pp
= &p
->c_next
)
1102 if (newp
->c_time
.tv_sec
< p
->c_time
.tv_sec
1103 || (newp
->c_time
.tv_sec
== p
->c_time
.tv_sec
1104 && newp
->c_time
.tv_usec
< p
->c_time
.tv_usec
))
1112 * untimeout - Unschedule a timeout.
1115 untimeout(func
, arg
)
1116 void (*func
) __P((void *));
1119 struct callout
**copp
, *freep
;
1121 MAINDEBUG(("Untimeout %p:%p.", func
, arg
));
1124 * Find first matching timeout and remove it from the list.
1126 for (copp
= &callout
; (freep
= *copp
); copp
= &freep
->c_next
)
1127 if (freep
->c_func
== func
&& freep
->c_arg
== arg
) {
1128 *copp
= freep
->c_next
;
1129 free((char *) freep
);
1136 * calltimeout - Call any timeout routines which are now due.
1143 while (callout
!= NULL
) {
1146 if (my_gettimeofday(&timenow
, NULL
) < 0)
1147 fatal("Failed to get time of day: %m");
1148 if (!(p
->c_time
.tv_sec
< timenow
.tv_sec
1149 || (p
->c_time
.tv_sec
== timenow
.tv_sec
1150 && p
->c_time
.tv_usec
<= timenow
.tv_usec
)))
1151 break; /* no, it's not time yet */
1153 callout
= p
->c_next
;
1154 (*p
->c_func
)(p
->c_arg
);
1162 * timeleft - return the length of time until the next timeout is due.
1164 static struct timeval
*
1166 struct timeval
*tvp
;
1168 if (callout
== NULL
)
1171 my_gettimeofday(&timenow
, NULL
);
1172 tvp
->tv_sec
= callout
->c_time
.tv_sec
- timenow
.tv_sec
;
1173 tvp
->tv_usec
= callout
->c_time
.tv_usec
- timenow
.tv_usec
;
1174 if (tvp
->tv_usec
< 0) {
1175 tvp
->tv_usec
+= 1000000;
1178 if (tvp
->tv_sec
< 0)
1179 tvp
->tv_sec
= tvp
->tv_usec
= 0;
1186 * kill_my_pg - send a signal to our process group, and ignore it ourselves.
1192 struct sigaction act
, oldact
;
1194 act
.sa_handler
= SIG_IGN
;
1197 sigaction(sig
, &act
, &oldact
);
1198 sigaction(sig
, &oldact
, NULL
);
1203 * hup - Catch SIGHUP signal.
1205 * Indicates that the physical layer has been disconnected.
1206 * We don't rely on this indication; if the user has sent this
1207 * signal, we just take the link down.
1213 info("Hangup (SIGHUP)");
1216 /* Send the signal to the [dis]connector process(es) also */
1219 siglongjmp(sigjmp
, 1);
1224 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
1226 * Indicates that we should initiate a graceful disconnect and exit.
1233 info("Terminating on signal %d.", sig
);
1236 /* Send the signal to the [dis]connector process(es) also */
1239 siglongjmp(sigjmp
, 1);
1244 * chld - Catch SIGCHLD signal.
1245 * Sets a flag so we will call reap_kids in the mainline.
1253 siglongjmp(sigjmp
, 1);
1258 * toggle_debug - Catch SIGUSR1 signal.
1260 * Toggle debug flag.
1262 static void toggle_debug(int sig
)
1265 setlogmask(LOG_UPTO(debug
? LOG_DEBUG
: logmask
));
1270 * open_ccp - Catch SIGUSR2 signal.
1272 * Try to (re)negotiate compression.
1281 siglongjmp(sigjmp
, 1);
1286 * bad_signal - We've caught a fatal signal. Clean up state and exit.
1292 static int crashed
= 0;
1298 LOGX_ERROR("Fatal signal %d.", sig
);
1301 kill_my_pg(SIGTERM
);
1306 * run-program - execute a program with given arguments,
1307 * but don't wait for it.
1308 * If the program can't be executed, logs an error unless
1309 * must_exist is 0 and the program file doesn't exist.
1310 * Returns -1 if it couldn't fork, 0 if the file doesn't exist
1311 * or isn't an executable plain file, or the process ID of the child.
1312 * If done != NULL, (*done)(arg) will be called later (within
1313 * reap_kids) iff the return value is > 0.
1316 run_program(prog
, args
, must_exist
, done
, arg
)
1320 void (*done
) __P((void *));
1327 * First check if the file exists and is executable.
1328 * We don't use access() because that would use the
1329 * real user-id, which might not be root, and the script
1330 * might be accessible only to root.
1333 if (stat(prog
, &sbuf
) < 0 || !S_ISREG(sbuf
.st_mode
)
1334 || (sbuf
.st_mode
& (S_IXUSR
|S_IXGRP
|S_IXOTH
)) == 0) {
1335 if (must_exist
|| errno
!= ENOENT
)
1336 warn("Can't execute %s: %m", prog
);
1342 error("Failed to create child process for %s: %m", prog
);
1348 /* Leave the current location */
1349 (void) setsid(); /* No controlling tty. */
1350 (void) umask (S_IRWXG
|S_IRWXO
);
1351 (void) chdir ("/"); /* no current directory. */
1352 setuid(0); /* set real UID = root */
1355 /* Ensure that nothing of our device environment is inherited. */
1361 if (the_channel
->close
)
1362 (*the_channel
->close
)();
1364 /* Don't pass handles to the PPP device, even by accident. */
1365 new_fd
= open (_PATH_DEVNULL
, O_RDWR
);
1368 dup2 (new_fd
, 0); /* stdin <- /dev/null */
1371 dup2 (0, 1); /* stdout -> /dev/null */
1372 dup2 (0, 2); /* stderr -> /dev/null */
1376 /* Force the priority back to zero if pppd is running higher. */
1377 if (setpriority (PRIO_PROCESS
, 0, 0) < 0)
1378 warn("can't reset priority to 0: %m");
1381 /* SysV recommends a second fork at this point. */
1383 /* run the program */
1384 execve(prog
, args
, script_env
);
1385 if (must_exist
|| errno
!= ENOENT
) {
1386 /* have to reopen the log, there's nowhere else
1387 for the message to go. */
1389 syslog(LOG_ERR
, "Can't execute %s: %m", prog
);
1396 dbglog("Script %s started (pid %d)", prog
, pid
);
1397 record_child(pid
, prog
, done
, arg
);
1403 * record_child - add a child process to the list for reap_kids
1407 record_child(pid
, prog
, done
, arg
)
1410 void (*done
) __P((void *));
1413 struct subprocess
*chp
;
1417 chp
= (struct subprocess
*) malloc(sizeof(struct subprocess
));
1419 warn("losing track of %s process", prog
);
1425 chp
->next
= children
;
1432 * reap_kids - get status from any dead child processes,
1433 * and log a message for abnormal terminations.
1440 struct subprocess
*chp
, **prevp
;
1442 if (n_children
== 0)
1444 while ((pid
= waitpid(-1, &status
, (waitfor
? 0: WNOHANG
))) != -1
1446 for (prevp
= &children
; (chp
= *prevp
) != NULL
; prevp
= &chp
->next
) {
1447 if (chp
->pid
== pid
) {
1453 if (WIFSIGNALED(status
)) {
1454 warn("Child process %s (pid %d) terminated with signal %d",
1455 (chp
? chp
->prog
: "??"), pid
, WTERMSIG(status
));
1457 dbglog("Script %s finished (pid %d), status = 0x%x",
1458 (chp
? chp
->prog
: "??"), pid
, status
);
1459 if (chp
&& chp
->done
)
1460 (*chp
->done
)(chp
->arg
);
1465 if (errno
== ECHILD
)
1468 error("Error waiting for child process: %m");
1474 * script_setenv - set an environment variable value to be used
1475 * for scripts that we run (e.g. ip-up, auth-up, etc.)
1478 script_setenv(var
, value
, iskey
)
1482 size_t varl
= strlen(var
);
1483 size_t vl
= varl
+ strlen(value
) + 2;
1485 char *p
, *newstring
;
1487 newstring
= (char *) malloc(vl
+1);
1490 *newstring
++ = iskey
;
1491 slprintf(newstring
, vl
, "%s=%s", var
, value
);
1493 /* check if this variable is already set */
1494 if (script_env
!= 0) {
1495 for (i
= 0; (p
= script_env
[i
]) != 0; ++i
) {
1496 if (strncmp(p
, var
, varl
) == 0 && p
[varl
] == '=') {
1497 if (p
[-1] && pppdb
!= NULL
)
1500 script_env
[i
] = newstring
;
1501 if (iskey
&& pppdb
!= NULL
)
1502 add_db_key(newstring
);
1508 /* no space allocated for script env. ptrs. yet */
1510 script_env
= (char **) malloc(16 * sizeof(char *));
1511 if (script_env
== 0)
1516 /* reallocate script_env with more space if needed */
1517 if (i
+ 1 >= s_env_nalloc
) {
1519 char **newenv
= (char **) realloc((void *)script_env
,
1520 new_n
* sizeof(char *));
1523 script_env
= newenv
;
1524 s_env_nalloc
= new_n
;
1527 script_env
[i
] = newstring
;
1528 script_env
[i
+1] = 0;
1530 if (pppdb
!= NULL
) {
1532 add_db_key(newstring
);
1538 * script_unsetenv - remove a variable from the environment
1542 script_unsetenv(var
)
1545 int vl
= strlen(var
);
1549 if (script_env
== 0)
1551 for (i
= 0; (p
= script_env
[i
]) != 0; ++i
) {
1552 if (strncmp(p
, var
, vl
) == 0 && p
[vl
] == '=') {
1553 if (p
[-1] && pppdb
!= NULL
)
1556 while ((script_env
[i
] = script_env
[i
+1]) != 0)