]> git.ozlabs.org Git - ppp.git/blob - pppd/main.c
remove a couple of ansi-C-isms.
[ppp.git] / pppd / main.c
1 /*
2  * main.c - Point-to-Point Protocol main module
3  *
4  * Copyright (c) 1989 Carnegie Mellon University.
5  * All rights reserved.
6  *
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.
18  */
19
20 #ifndef lint
21 static char rcsid[] = "$Id: main.c,v 1.63 1999/03/19 04:23:40 paulus Exp $";
22 #endif
23
24 #include <stdio.h>
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <syslog.h>
33 #include <netdb.h>
34 #include <utmp.h>
35 #include <pwd.h>
36 #include <setjmp.h>
37 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/wait.h>
40 #include <sys/time.h>
41 #include <sys/resource.h>
42 #include <sys/stat.h>
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45
46 #include "pppd.h"
47 #include "magic.h"
48 #include "fsm.h"
49 #include "lcp.h"
50 #include "ipcp.h"
51 #include "upap.h"
52 #include "chap.h"
53 #include "ccp.h"
54 #include "pathnames.h"
55 #include "patchlevel.h"
56
57 #ifdef CBCP_SUPPORT
58 #include "cbcp.h"
59 #endif
60
61 #if defined(SUNOS4)
62 extern char *strerror();
63 #endif
64
65 #ifdef IPX_CHANGE
66 #include "ipxcp.h"
67 #endif /* IPX_CHANGE */
68 #ifdef AT_CHANGE
69 #include "atcp.h"
70 #endif
71
72 /* interface vars */
73 char ifname[32];                /* Interface name */
74 int ifunit;                     /* Interface unit number */
75
76 char *progname;                 /* Name of this program */
77 char hostname[MAXNAMELEN];      /* Our hostname */
78 static char pidfilename[MAXPATHLEN];    /* name of pid file */
79 static char default_devnam[MAXPATHLEN]; /* name of default device */
80 static pid_t pid;               /* Our pid */
81 static uid_t uid;               /* Our real user-id */
82 static int conn_running;        /* we have a [dis]connector running */
83
84 int ttyfd = -1;                 /* Serial port file descriptor */
85 mode_t tty_mode = -1;           /* Original access permissions to tty */
86 int baud_rate;                  /* Actual bits/second for serial device */
87 int hungup;                     /* terminal has been hung up */
88 int privileged;                 /* we're running as real uid root */
89 int need_holdoff;               /* need holdoff period before restarting */
90 int detached;                   /* have detached from terminal */
91 int log_to_fd;                  /* send log messages to this fd too */
92
93 static int fd_ppp;              /* fd for talking PPP */
94 static int fd_loop;             /* fd for getting demand-dial packets */
95
96 int phase;                      /* where the link is at */
97 int kill_link;
98 int open_ccp_flag;
99
100 static int waiting;
101 static sigjmp_buf sigjmp;
102
103 char **script_env;              /* Env. variable values for scripts */
104 int s_env_nalloc;               /* # words avail at script_env */
105
106 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
107 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
108
109 static int n_children;          /* # child processes still running */
110
111 static int locked;              /* lock() has succeeded */
112
113 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
114
115 GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */
116 int ngroups;                    /* How many groups valid in groups */
117
118 static struct timeval start_time;       /* Time when link was started. */
119
120 struct ppp_stats link_stats;
121 int link_stats_valid;
122
123 /* Prototypes for procedures local to this file. */
124
125 static void create_pidfile __P((void));
126 static void cleanup __P((void));
127 static void close_tty __P((void));
128 static void hangup_modem __P((int));
129 static void get_input __P((void));
130 static void calltimeout __P((void));
131 static struct timeval *timeleft __P((struct timeval *));
132 static void kill_my_pg __P((int));
133 static void hup __P((int));
134 static void term __P((int));
135 static void chld __P((int));
136 static void toggle_debug __P((int));
137 static void open_ccp __P((int));
138 static void bad_signal __P((int));
139 static void holdoff_end __P((void *));
140 static int device_script __P((char *, int));
141 static void reap_kids __P((void));
142 static void pr_log __P((void *, char *, ...));
143 static void logit __P((int, char *, va_list));
144 static void vslp_printer __P((void *, char *, ...));
145 static void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
146                                void *));
147
148 extern  char    *ttyname __P((int));
149 extern  char    *getlogin __P((void));
150 int main __P((int, char *[]));
151
152 #ifdef ultrix
153 #undef  O_NONBLOCK
154 #define O_NONBLOCK      O_NDELAY
155 #endif
156
157 #ifdef ULTRIX
158 #define setlogmask(x)
159 #endif
160
161 /*
162  * PPP Data Link Layer "protocol" table.
163  * One entry per supported protocol.
164  * The last entry must be NULL.
165  */
166 struct protent *protocols[] = {
167     &lcp_protent,
168     &pap_protent,
169     &chap_protent,
170 #ifdef CBCP_SUPPORT
171     &cbcp_protent,
172 #endif
173     &ipcp_protent,
174     &ccp_protent,
175 #ifdef IPX_CHANGE
176     &ipxcp_protent,
177 #endif
178 #ifdef AT_CHANGE
179     &atcp_protent,
180 #endif
181     NULL
182 };
183
184 int
185 main(argc, argv)
186     int argc;
187     char *argv[];
188 {
189     int i, fdflags;
190     struct sigaction sa;
191     char *p;
192     struct passwd *pw;
193     struct timeval timo;
194     sigset_t mask;
195     struct protent *protp;
196     struct stat statbuf;
197     char numbuf[16];
198     struct timeval now;
199
200     phase = PHASE_INITIALIZE;
201     p = ttyname(0);
202     if (p)
203         strlcpy(devnam, p, sizeof(devnam));
204     strlcpy(default_devnam, devnam, sizeof(default_devnam));
205
206     script_env = NULL;
207
208     /* Initialize syslog facilities */
209 #ifdef ULTRIX
210     openlog("pppd", LOG_PID);
211 #else
212     openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
213     setlogmask(LOG_UPTO(LOG_INFO));
214 #endif
215
216     if (gethostname(hostname, MAXNAMELEN) < 0 ) {
217         option_error("Couldn't get hostname: %m");
218         exit(1);
219     }
220     hostname[MAXNAMELEN-1] = 0;
221
222     uid = getuid();
223     privileged = uid == 0;
224     slprintf(numbuf, sizeof(numbuf), "%d", uid);
225     script_setenv("ORIG_UID", numbuf);
226
227     ngroups = getgroups(NGROUPS_MAX, groups);
228
229     /*
230      * Initialize to the standard option set, then parse, in order,
231      * the system options file, the user's options file,
232      * the tty's options file, and the command line arguments.
233      */
234     for (i = 0; (protp = protocols[i]) != NULL; ++i)
235         (*protp->init)(0);
236
237     progname = *argv;
238
239     if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1)
240         || !options_from_user())
241         exit(1);
242     scan_args(argc-1, argv+1);  /* look for tty name on command line */
243     if (!options_for_tty()
244         || !parse_args(argc-1, argv+1))
245         exit(1);
246
247     /*
248      * Check that we are running as root.
249      */
250     if (geteuid() != 0) {
251         option_error("must be root to run %s, since it is not setuid-root",
252                      argv[0]);
253         exit(1);
254     }
255
256     if (!ppp_available()) {
257         option_error(no_ppp_msg);
258         exit(1);
259     }
260
261     /*
262      * Check that the options given are valid and consistent.
263      */
264     if (!sys_check_options())
265         exit(1);
266     auth_check_options();
267     for (i = 0; (protp = protocols[i]) != NULL; ++i)
268         if (protp->check_options != NULL)
269             (*protp->check_options)();
270     if (demand && connector == 0) {
271         option_error("connect script is required for demand-dialling\n");
272         exit(1);
273     }
274
275     script_setenv("DEVICE", devnam);
276     slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);
277     script_setenv("SPEED", numbuf);
278
279     /*
280      * If the user has specified the default device name explicitly,
281      * pretend they hadn't.
282      */
283     if (!default_device && strcmp(devnam, default_devnam) == 0)
284         default_device = 1;
285     if (default_device)
286         nodetach = 1;
287     log_to_fd = !default_device? 1: -1; /* default to stdout */
288
289     /*
290      * Initialize system-dependent stuff and magic number package.
291      */
292     sys_init();
293     magic_init();
294     if (debug)
295         setlogmask(LOG_UPTO(LOG_DEBUG));
296
297     /*
298      * Detach ourselves from the terminal, if required,
299      * and identify who is running us.
300      */
301     if (!nodetach && !updetach)
302         detach();
303     pid = getpid();
304     p = getlogin();
305     if (p == NULL) {
306         pw = getpwuid(uid);
307         if (pw != NULL && pw->pw_name != NULL)
308             p = pw->pw_name;
309         else
310             p = "(unknown)";
311     }
312     syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d",
313            VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid);
314   
315     /*
316      * Compute mask of all interesting signals and install signal handlers
317      * for each.  Only one signal handler may be active at a time.  Therefore,
318      * all other signals should be masked when any handler is executing.
319      */
320     sigemptyset(&mask);
321     sigaddset(&mask, SIGHUP);
322     sigaddset(&mask, SIGINT);
323     sigaddset(&mask, SIGTERM);
324     sigaddset(&mask, SIGCHLD);
325     sigaddset(&mask, SIGUSR2);
326
327 #define SIGNAL(s, handler)      do { \
328         sa.sa_handler = handler; \
329         if (sigaction(s, &sa, NULL) < 0) \
330             fatal("Couldn't establish signal handler (%d): %m", s); \
331     } while (0)
332
333     sa.sa_mask = mask;
334     sa.sa_flags = 0;
335     SIGNAL(SIGHUP, hup);                /* Hangup */
336     SIGNAL(SIGINT, term);               /* Interrupt */
337     SIGNAL(SIGTERM, term);              /* Terminate */
338     SIGNAL(SIGCHLD, chld);
339
340     SIGNAL(SIGUSR1, toggle_debug);      /* Toggle debug flag */
341     SIGNAL(SIGUSR2, open_ccp);          /* Reopen CCP */
342
343     /*
344      * Install a handler for other signals which would otherwise
345      * cause pppd to exit without cleaning up.
346      */
347     SIGNAL(SIGABRT, bad_signal);
348     SIGNAL(SIGALRM, bad_signal);
349     SIGNAL(SIGFPE, bad_signal);
350     SIGNAL(SIGILL, bad_signal);
351     SIGNAL(SIGPIPE, bad_signal);
352     SIGNAL(SIGQUIT, bad_signal);
353     SIGNAL(SIGSEGV, bad_signal);
354 #ifdef SIGBUS
355     SIGNAL(SIGBUS, bad_signal);
356 #endif
357 #ifdef SIGEMT
358     SIGNAL(SIGEMT, bad_signal);
359 #endif
360 #ifdef SIGPOLL
361     SIGNAL(SIGPOLL, bad_signal);
362 #endif
363 #ifdef SIGPROF
364     SIGNAL(SIGPROF, bad_signal);
365 #endif
366 #ifdef SIGSYS
367     SIGNAL(SIGSYS, bad_signal);
368 #endif
369 #ifdef SIGTRAP
370     SIGNAL(SIGTRAP, bad_signal);
371 #endif
372 #ifdef SIGVTALRM
373     SIGNAL(SIGVTALRM, bad_signal);
374 #endif
375 #ifdef SIGXCPU
376     SIGNAL(SIGXCPU, bad_signal);
377 #endif
378 #ifdef SIGXFSZ
379     SIGNAL(SIGXFSZ, bad_signal);
380 #endif
381
382     /*
383      * Apparently we can get a SIGPIPE when we call syslog, if
384      * syslogd has died and been restarted.  Ignoring it seems
385      * be sufficient.
386      */
387     signal(SIGPIPE, SIG_IGN);
388
389     waiting = 0;
390
391     /*
392      * If we're doing dial-on-demand, set up the interface now.
393      */
394     if (demand) {
395         /*
396          * Open the loopback channel and set it up to be the ppp interface.
397          */
398         fd_loop = open_ppp_loopback();
399
400         syslog(LOG_INFO, "Using interface ppp%d", ifunit);
401         slprintf(ifname, sizeof(ifname), "ppp%d", ifunit);
402         script_setenv("IFNAME", ifname);
403
404         create_pidfile();       /* write pid to file */
405
406         /*
407          * Configure the interface and mark it up, etc.
408          */
409         demand_conf();
410     }
411
412     for (;;) {
413
414         need_holdoff = 1;
415
416         if (demand) {
417             /*
418              * Don't do anything until we see some activity.
419              */
420             kill_link = 0;
421             phase = PHASE_DORMANT;
422             demand_unblock();
423             add_fd(fd_loop);
424             for (;;) {
425                 if (sigsetjmp(sigjmp, 1) == 0) {
426                     sigprocmask(SIG_BLOCK, &mask, NULL);
427                     if (kill_link) {
428                         sigprocmask(SIG_UNBLOCK, &mask, NULL);
429                     } else {
430                         waiting = 1;
431                         sigprocmask(SIG_UNBLOCK, &mask, NULL);
432                         wait_input(timeleft(&timo));
433                     }
434                 }
435                 waiting = 0;
436                 calltimeout();
437                 if (kill_link) {
438                     if (!persist)
439                         break;
440                     kill_link = 0;
441                 }
442                 if (get_loop_output())
443                     break;
444                 reap_kids();
445             }
446             remove_fd(fd_loop);
447             if (kill_link && !persist)
448                 break;
449
450             /*
451              * Now we want to bring up the link.
452              */
453             demand_block();
454             info("Starting link");
455         }
456
457         /*
458          * Lock the device if we've been asked to.
459          */
460         if (lockflag && !default_device) {
461             if (lock(devnam) < 0)
462                 goto fail;
463             locked = 1;
464         }
465
466         /*
467          * Open the serial device and set it up to be the ppp interface.
468          * First we open it in non-blocking mode so we can set the
469          * various termios flags appropriately.  If we aren't dialling
470          * out and we want to use the modem lines, we reopen it later
471          * in order to wait for the carrier detect signal from the modem.
472          */
473         hungup = 0;
474         kill_link = 0;
475         for (;;) {
476             /* If the user specified the device name, become the
477                user before opening it. */
478             if (!devnam_info.priv)
479                 seteuid(uid);
480             ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
481             if (!devnam_info.priv)
482                 seteuid(0);
483             if (ttyfd >= 0)
484                 break;
485             if (errno != EINTR)
486                 error("Failed to open %s: %m", devnam);
487             if (!persist || errno != EINTR)
488                 goto fail;
489         }
490         if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
491             || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
492             warn("Couldn't reset non-blocking mode on device: %m");
493
494         /*
495          * Do the equivalent of `mesg n' to stop broadcast messages.
496          */
497         if (fstat(ttyfd, &statbuf) < 0
498             || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
499             warn("Couldn't restrict write permissions to %s: %m", devnam);
500         } else
501             tty_mode = statbuf.st_mode;
502
503         /* run connection script */
504         if (connector && connector[0]) {
505             MAINDEBUG(("Connecting with <%s>", connector));
506
507             if (!default_device && modem) {
508                 hangup_modem(ttyfd);    /* in case modem is off hook */
509                 sleep(1);
510             }
511
512             /*
513              * Set line speed, flow control, etc.
514              * On most systems we set CLOCAL for now so that we can talk
515              * to the modem before carrier comes up.  But this has the
516              * side effect that we might miss it if CD drops before we
517              * get to clear CLOCAL below.  On systems where we can talk
518              * successfully to the modem with CLOCAL clear and CD down,
519              * we could clear CLOCAL at this point.
520              */
521             set_up_tty(ttyfd, 1);
522
523             if (device_script(connector, ttyfd) < 0) {
524                 error("Connect script failed");
525                 goto fail;
526             }
527
528             info("Serial connection established.");
529             sleep(1);           /* give it time to set up its terminal */
530         }
531
532         /* set line speed, flow control, etc.; clear CLOCAL if modem option */
533         set_up_tty(ttyfd, 0);
534
535         /* reopen tty if necessary to wait for carrier */
536         if (connector == NULL && modem) {
537             for (;;) {
538                 if ((i = open(devnam, O_RDWR)) >= 0)
539                     break;
540                 if (errno != EINTR)
541                     error("Failed to reopen %s: %m", devnam);
542                 if (!persist || errno != EINTR || hungup || kill_link)
543                     goto fail;
544             }
545             close(i);
546         }
547
548         /* run welcome script, if any */
549         if (welcomer && welcomer[0]) {
550             if (device_script(welcomer, ttyfd) < 0)
551                 warn("Welcome script failed");
552         }
553
554         /* set up the serial device as a ppp interface */
555         fd_ppp = establish_ppp(ttyfd);
556
557         if (!demand) {
558             
559             info("Using interface ppp%d", ifunit);
560             slprintf(ifname, sizeof(ifname), "ppp%d", ifunit);
561             script_setenv("IFNAME", ifname);
562
563             create_pidfile();   /* write pid to file */
564         }
565
566         /*
567          * Start opening the connection and wait for
568          * incoming events (reply, timeout, etc.).
569          */
570         notice("Connect: %s <--> %s", ifname, devnam);
571         gettimeofday(&start_time, NULL);
572         lcp_lowerup(0);
573         lcp_open(0);            /* Start protocol */
574         open_ccp_flag = 0;
575         add_fd(fd_ppp);
576         for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
577             if (sigsetjmp(sigjmp, 1) == 0) {
578                 sigprocmask(SIG_BLOCK, &mask, NULL);
579                 if (kill_link || open_ccp_flag) {
580                     sigprocmask(SIG_UNBLOCK, &mask, NULL);
581                 } else {
582                     waiting = 1;
583                     sigprocmask(SIG_UNBLOCK, &mask, NULL);
584                     wait_input(timeleft(&timo));
585                 }
586             }
587             waiting = 0;
588             calltimeout();
589             get_input();
590             if (kill_link) {
591                 lcp_close(0, "User request");
592                 kill_link = 0;
593             }
594             if (open_ccp_flag) {
595                 if (phase == PHASE_NETWORK) {
596                     ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
597                     (*ccp_protent.open)(0);
598                 }
599                 open_ccp_flag = 0;
600             }
601             reap_kids();        /* Don't leave dead kids lying around */
602         }
603
604         /*
605          * Print connect time and statistics.
606          */
607         if (gettimeofday(&now, NULL) >= 0) {
608             int t = now.tv_sec - start_time.tv_sec;
609             t = (t + 5) / 6;    /* now in 1/10ths of minutes */
610             info("Connect time %d.%d minutes", t/10, t%10);
611         }
612         if (link_stats_valid) {
613             info("Send %d bytes, received %d bytes",
614                  link_stats.p.ppp_obytes, link_stats.p.ppp_ibytes);
615         }
616
617         /*
618          * If we may want to bring the link up again, transfer
619          * the ppp unit back to the loopback.  Set the
620          * real serial device back to its normal mode of operation.
621          */
622         remove_fd(fd_ppp);
623         clean_check();
624         if (demand)
625             restore_loop();
626         disestablish_ppp(ttyfd);
627
628         /*
629          * Run disconnector script, if requested.
630          * XXX we may not be able to do this if the line has hung up!
631          */
632         if (disconnector && !hungup) {
633             set_up_tty(ttyfd, 1);
634             if (device_script(disconnector, ttyfd) < 0) {
635                 warn("disconnect script failed");
636             } else {
637                 info("Serial link disconnected.");
638             }
639         }
640         if (!hungup)
641             lcp_lowerdown(0);
642
643     fail:
644         if (ttyfd >= 0)
645             close_tty();
646         if (locked) {
647             unlock();
648             locked = 0;
649         }
650
651         if (!demand) {
652             if (pidfilename[0] != 0
653                 && unlink(pidfilename) < 0 && errno != ENOENT) 
654                 warn("unable to delete pid file: %m");
655             pidfilename[0] = 0;
656         }
657
658         if (!persist)
659             break;
660
661         kill_link = 0;
662         if (demand)
663             demand_discard();
664         if (holdoff > 0 && need_holdoff) {
665             phase = PHASE_HOLDOFF;
666             TIMEOUT(holdoff_end, NULL, holdoff);
667             do {
668                 if (sigsetjmp(sigjmp, 1) == 0) {
669                     sigprocmask(SIG_BLOCK, &mask, NULL);
670                     if (kill_link) {
671                         sigprocmask(SIG_UNBLOCK, &mask, NULL);
672                     } else {
673                         waiting = 1;
674                         sigprocmask(SIG_UNBLOCK, &mask, NULL);
675                         wait_input(timeleft(&timo));
676                     }
677                 }
678                 waiting = 0;
679                 calltimeout();
680                 if (kill_link) {
681                     kill_link = 0;
682                     phase = PHASE_DORMANT; /* allow signal to end holdoff */
683                 }
684                 reap_kids();
685             } while (phase == PHASE_HOLDOFF);
686             if (!persist)
687                 break;
688         }
689     }
690
691     /* Wait for scripts to finish */
692     while (n_children > 0)
693         reap_kids();
694
695     die(0);
696     return 0;
697 }
698
699 /*
700  * detach - detach us from the controlling terminal.
701  */
702 void
703 detach()
704 {
705     if (detached)
706         return;
707     if (daemon(0, 0) < 0) {
708         perror("Couldn't detach from controlling terminal");
709         die(1);
710     }
711     detached = 1;
712     log_to_fd = -1;
713     pid = getpid();
714     /* update pid file if it has been written already */
715     if (pidfilename[0])
716         create_pidfile();
717 }
718
719 /*
720  * Create a file containing our process ID.
721  */
722 static void
723 create_pidfile()
724 {
725     FILE *pidfile;
726     char numbuf[16];
727
728     slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
729              _PATH_VARRUN, ifname);
730     if ((pidfile = fopen(pidfilename, "w")) != NULL) {
731         fprintf(pidfile, "%d\n", pid);
732         (void) fclose(pidfile);
733     } else {
734         error("Failed to create pid file %s: %m", pidfilename);
735         pidfilename[0] = 0;
736     }
737     slprintf(numbuf, sizeof(numbuf), "%d", pid);
738     script_setenv("PPPD_PID", numbuf);
739 }
740
741 /*
742  * holdoff_end - called via a timeout when the holdoff period ends.
743  */
744 static void
745 holdoff_end(arg)
746     void *arg;
747 {
748     phase = PHASE_DORMANT;
749 }
750
751 /*
752  * get_input - called when incoming data is available.
753  */
754 static void
755 get_input()
756 {
757     int len, i;
758     u_char *p;
759     u_short protocol;
760     struct protent *protp;
761
762     p = inpacket_buf;   /* point to beginning of packet buffer */
763
764     len = read_packet(inpacket_buf);
765     if (len < 0)
766         return;
767
768     if (len == 0) {
769         notice("Modem hangup");
770         hungup = 1;
771         lcp_lowerdown(0);       /* serial link is no longer available */
772         link_terminated(0);
773         return;
774     }
775
776     if (debug /*&& (debugflags & DBG_INPACKET)*/)
777         dbglog("rcvd %P", p, len);
778
779     if (len < PPP_HDRLEN) {
780         MAINDEBUG(("io(): Received short packet."));
781         return;
782     }
783
784     p += 2;                             /* Skip address and control */
785     GETSHORT(protocol, p);
786     len -= PPP_HDRLEN;
787
788     /*
789      * Toss all non-LCP packets unless LCP is OPEN.
790      */
791     if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
792         MAINDEBUG(("get_input: Received non-LCP packet when LCP not open."));
793         return;
794     }
795
796     /*
797      * Until we get past the authentication phase, toss all packets
798      * except LCP, LQR and authentication packets.
799      */
800     if (phase <= PHASE_AUTHENTICATE
801         && !(protocol == PPP_LCP || protocol == PPP_LQR
802              || protocol == PPP_PAP || protocol == PPP_CHAP)) {
803         MAINDEBUG(("get_input: discarding proto 0x%x in phase %d",
804                    protocol, phase));
805         return;
806     }
807
808     /*
809      * Upcall the proper protocol input routine.
810      */
811     for (i = 0; (protp = protocols[i]) != NULL; ++i) {
812         if (protp->protocol == protocol && protp->enabled_flag) {
813             (*protp->input)(0, p, len);
814             return;
815         }
816         if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
817             && protp->datainput != NULL) {
818             (*protp->datainput)(0, p, len);
819             return;
820         }
821     }
822
823     if (debug)
824         warn("Unsupported protocol (0x%x) received", protocol);
825     lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
826 }
827
828
829 /*
830  * die - clean up state and exit with the specified status.
831  */
832 void
833 die(status)
834     int status;
835 {
836     cleanup();
837     syslog(LOG_INFO, "Exit.");
838     exit(status);
839 }
840
841 /*
842  * cleanup - restore anything which needs to be restored before we exit
843  */
844 /* ARGSUSED */
845 static void
846 cleanup()
847 {
848     sys_cleanup();
849
850     if (ttyfd >= 0)
851         close_tty();
852
853     if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) 
854         warn("unable to delete pid file: %m");
855     pidfilename[0] = 0;
856
857     if (locked)
858         unlock();
859 }
860
861 /*
862  * close_tty - restore the terminal device and close it.
863  */
864 static void
865 close_tty()
866 {
867     disestablish_ppp(ttyfd);
868
869     /* drop dtr to hang up */
870     if (!default_device && modem) {
871         hangup_modem(ttyfd);
872         /*
873          * This sleep is in case the serial port has CLOCAL set by default,
874          * and consequently will reassert DTR when we close the device.
875          */
876         sleep(1);
877     }
878
879     restore_tty(ttyfd);
880
881     if (tty_mode != (mode_t) -1) {
882         if (fchmod(ttyfd, tty_mode) != 0) {
883             /* XXX if devnam is a symlink, this will change the link */
884             chmod(devnam, tty_mode);
885         }
886     }
887
888     close(ttyfd);
889     ttyfd = -1;
890 }
891
892 /*
893  * hangup_modem - hang up the modem by clearing DTR.
894  */
895 static void
896 hangup_modem(ttyfd)
897     int ttyfd;
898 {
899     setdtr(ttyfd, 0);
900 }
901
902
903 struct  callout {
904     struct timeval      c_time;         /* time at which to call routine */
905     void                *c_arg;         /* argument to routine */
906     void                (*c_func) __P((void *)); /* routine */
907     struct              callout *c_next;
908 };
909
910 static struct callout *callout = NULL;  /* Callout list */
911 static struct timeval timenow;          /* Current time */
912
913 /*
914  * timeout - Schedule a timeout.
915  *
916  * Note that this timeout takes the number of seconds, NOT hz (as in
917  * the kernel).
918  */
919 void
920 timeout(func, arg, time)
921     void (*func) __P((void *));
922     void *arg;
923     int time;
924 {
925     struct callout *newp, *p, **pp;
926   
927     MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time));
928   
929     /*
930      * Allocate timeout.
931      */
932     if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
933         fatal("Out of memory in timeout()!");
934     newp->c_arg = arg;
935     newp->c_func = func;
936     gettimeofday(&timenow, NULL);
937     newp->c_time.tv_sec = timenow.tv_sec + time;
938     newp->c_time.tv_usec = timenow.tv_usec;
939   
940     /*
941      * Find correct place and link it in.
942      */
943     for (pp = &callout; (p = *pp); pp = &p->c_next)
944         if (newp->c_time.tv_sec < p->c_time.tv_sec
945             || (newp->c_time.tv_sec == p->c_time.tv_sec
946                 && newp->c_time.tv_usec < p->c_time.tv_usec))
947             break;
948     newp->c_next = p;
949     *pp = newp;
950 }
951
952
953 /*
954  * untimeout - Unschedule a timeout.
955  */
956 void
957 untimeout(func, arg)
958     void (*func) __P((void *));
959     void *arg;
960 {
961     struct callout **copp, *freep;
962   
963     MAINDEBUG(("Untimeout %p:%p.", func, arg));
964   
965     /*
966      * Find first matching timeout and remove it from the list.
967      */
968     for (copp = &callout; (freep = *copp); copp = &freep->c_next)
969         if (freep->c_func == func && freep->c_arg == arg) {
970             *copp = freep->c_next;
971             (void) free((char *) freep);
972             break;
973         }
974 }
975
976
977 /*
978  * calltimeout - Call any timeout routines which are now due.
979  */
980 static void
981 calltimeout()
982 {
983     struct callout *p;
984
985     while (callout != NULL) {
986         p = callout;
987
988         if (gettimeofday(&timenow, NULL) < 0)
989             fatal("Failed to get time of day: %m");
990         if (!(p->c_time.tv_sec < timenow.tv_sec
991               || (p->c_time.tv_sec == timenow.tv_sec
992                   && p->c_time.tv_usec <= timenow.tv_usec)))
993             break;              /* no, it's not time yet */
994
995         callout = p->c_next;
996         (*p->c_func)(p->c_arg);
997
998         free((char *) p);
999     }
1000 }
1001
1002
1003 /*
1004  * timeleft - return the length of time until the next timeout is due.
1005  */
1006 static struct timeval *
1007 timeleft(tvp)
1008     struct timeval *tvp;
1009 {
1010     if (callout == NULL)
1011         return NULL;
1012
1013     gettimeofday(&timenow, NULL);
1014     tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
1015     tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
1016     if (tvp->tv_usec < 0) {
1017         tvp->tv_usec += 1000000;
1018         tvp->tv_sec -= 1;
1019     }
1020     if (tvp->tv_sec < 0)
1021         tvp->tv_sec = tvp->tv_usec = 0;
1022
1023     return tvp;
1024 }
1025
1026
1027 /*
1028  * kill_my_pg - send a signal to our process group, and ignore it ourselves.
1029  */
1030 static void
1031 kill_my_pg(sig)
1032     int sig;
1033 {
1034     struct sigaction act, oldact;
1035
1036     act.sa_handler = SIG_IGN;
1037     act.sa_flags = 0;
1038     kill(0, sig);
1039     sigaction(sig, &act, &oldact);
1040     sigaction(sig, &oldact, NULL);
1041 }
1042
1043
1044 /*
1045  * hup - Catch SIGHUP signal.
1046  *
1047  * Indicates that the physical layer has been disconnected.
1048  * We don't rely on this indication; if the user has sent this
1049  * signal, we just take the link down.
1050  */
1051 static void
1052 hup(sig)
1053     int sig;
1054 {
1055     info("Hangup (SIGHUP)");
1056     kill_link = 1;
1057     if (conn_running)
1058         /* Send the signal to the [dis]connector process(es) also */
1059         kill_my_pg(sig);
1060     if (waiting)
1061         siglongjmp(sigjmp, 1);
1062 }
1063
1064
1065 /*
1066  * term - Catch SIGTERM signal and SIGINT signal (^C/del).
1067  *
1068  * Indicates that we should initiate a graceful disconnect and exit.
1069  */
1070 /*ARGSUSED*/
1071 static void
1072 term(sig)
1073     int sig;
1074 {
1075     info("Terminating on signal %d.", sig);
1076     persist = 0;                /* don't try to restart */
1077     kill_link = 1;
1078     if (conn_running)
1079         /* Send the signal to the [dis]connector process(es) also */
1080         kill_my_pg(sig);
1081     if (waiting)
1082         siglongjmp(sigjmp, 1);
1083 }
1084
1085
1086 /*
1087  * chld - Catch SIGCHLD signal.
1088  * Calls reap_kids to get status for any dead kids.
1089  */
1090 static void
1091 chld(sig)
1092     int sig;
1093 {
1094     if (waiting)
1095         siglongjmp(sigjmp, 1);
1096 }
1097
1098
1099 /*
1100  * toggle_debug - Catch SIGUSR1 signal.
1101  *
1102  * Toggle debug flag.
1103  */
1104 /*ARGSUSED*/
1105 static void
1106 toggle_debug(sig)
1107     int sig;
1108 {
1109     debug = !debug;
1110     if (debug) {
1111         setlogmask(LOG_UPTO(LOG_DEBUG));
1112     } else {
1113         setlogmask(LOG_UPTO(LOG_WARNING));
1114     }
1115 }
1116
1117
1118 /*
1119  * open_ccp - Catch SIGUSR2 signal.
1120  *
1121  * Try to (re)negotiate compression.
1122  */
1123 /*ARGSUSED*/
1124 static void
1125 open_ccp(sig)
1126     int sig;
1127 {
1128     open_ccp_flag = 1;
1129     if (waiting)
1130         siglongjmp(sigjmp, 1);
1131 }
1132
1133
1134 /*
1135  * bad_signal - We've caught a fatal signal.  Clean up state and exit.
1136  */
1137 static void
1138 bad_signal(sig)
1139     int sig;
1140 {
1141     static int crashed = 0;
1142
1143     if (crashed)
1144         _exit(127);
1145     crashed = 1;
1146     error("Fatal signal %d", sig);
1147     if (conn_running)
1148         kill_my_pg(SIGTERM);
1149     die(1);
1150 }
1151
1152
1153 /*
1154  * device_script - run a program to connect or disconnect the
1155  * serial device.
1156  */
1157 static int
1158 device_script(program, inout)
1159     char *program;
1160     int inout;
1161 {
1162     int pid;
1163     int status;
1164     int errfd;
1165
1166     conn_running = 1;
1167     pid = fork();
1168
1169     if (pid < 0) {
1170         conn_running = 0;
1171         fatal("Failed to create child process: %m");
1172     }
1173
1174     if (pid == 0) {
1175         sys_close();
1176         closelog();
1177         if (inout == 2) {
1178             /* aargh!!! */
1179             int newio = dup(inout);
1180             close(inout);
1181             inout = newio;
1182         }
1183         if (log_to_fd >= 0) {
1184             if (log_to_fd != 2)
1185                 dup2(log_to_fd, 2);
1186         } else {
1187             close(2);
1188             errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600);
1189             if (errfd >= 0 && errfd != 2) {
1190                 dup2(errfd, 2);
1191                 close(errfd);
1192             }
1193         }
1194         if (inout != 0) {
1195             dup2(inout, 0);
1196             close(inout);
1197         }
1198         dup2(0, 1);
1199         setuid(uid);
1200         if (getuid() != uid) {
1201             error("setuid failed");
1202             exit(1);
1203         }
1204         setgid(getgid());
1205         execl("/bin/sh", "sh", "-c", program, (char *)0);
1206         error("could not exec /bin/sh: %m");
1207         exit(99);
1208         /* NOTREACHED */
1209     }
1210
1211     while (waitpid(pid, &status, 0) < 0) {
1212         if (errno == EINTR)
1213             continue;
1214         fatal("error waiting for (dis)connection process: %m");
1215     }
1216     conn_running = 0;
1217
1218     return (status == 0 ? 0 : -1);
1219 }
1220
1221
1222 /*
1223  * We maintain a list of child process pids and
1224  * functions to call when they exit.
1225  */
1226 struct subprocess {
1227     pid_t       pid;
1228     char        *prog;
1229     void        (*done) __P((void *));
1230     void        *arg;
1231     struct subprocess *next;
1232 };
1233
1234 struct subprocess *children;
1235
1236 /*
1237  * run-program - execute a program with given arguments,
1238  * but don't wait for it.
1239  * If the program can't be executed, logs an error unless
1240  * must_exist is 0 and the program file doesn't exist.
1241  * Returns -1 if it couldn't fork, 0 if the file doesn't exist
1242  * or isn't an executable plain file, or the process ID of the child.
1243  * If done != NULL, (*done)(arg) will be called later (within
1244  * reap_kids) iff the return value is > 0.
1245  */
1246 pid_t
1247 run_program(prog, args, must_exist, done, arg)
1248     char *prog;
1249     char **args;
1250     int must_exist;
1251     void (*done) __P((void *));
1252     void *arg;
1253 {
1254     int pid;
1255     struct subprocess *chp;
1256     struct stat sbuf;
1257
1258     /*
1259      * First check if the file exists and is executable.
1260      * We don't use access() because that would use the
1261      * real user-id, which might not be root, and the script
1262      * might be accessible only to root.
1263      */
1264     errno = EINVAL;
1265     if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode)
1266         || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
1267         if (must_exist || errno != ENOENT)
1268             warn("Can't execute %s: %m", prog);
1269         return 0;
1270     }
1271
1272     pid = fork();
1273     if (pid == -1)
1274         fatal("Failed to create child process for %s: %m", prog);
1275     if (pid == 0) {
1276         int new_fd;
1277
1278         /* Leave the current location */
1279         (void) setsid();        /* No controlling tty. */
1280         (void) umask (S_IRWXG|S_IRWXO);
1281         (void) chdir ("/");     /* no current directory. */
1282         setuid(0);              /* set real UID = root */
1283         setgid(getegid());
1284
1285         /* Ensure that nothing of our device environment is inherited. */
1286         sys_close();
1287         closelog();
1288         close (0);
1289         close (1);
1290         close (2);
1291         close (ttyfd);  /* tty interface to the ppp device */
1292
1293         /* Don't pass handles to the PPP device, even by accident. */
1294         new_fd = open (_PATH_DEVNULL, O_RDWR);
1295         if (new_fd >= 0) {
1296             if (new_fd != 0) {
1297                 dup2  (new_fd, 0); /* stdin <- /dev/null */
1298                 close (new_fd);
1299             }
1300             dup2 (0, 1); /* stdout -> /dev/null */
1301             dup2 (0, 2); /* stderr -> /dev/null */
1302         }
1303
1304 #ifdef BSD
1305         /* Force the priority back to zero if pppd is running higher. */
1306         if (setpriority (PRIO_PROCESS, 0, 0) < 0)
1307             warn("can't reset priority to 0: %m"); 
1308 #endif
1309
1310         /* SysV recommends a second fork at this point. */
1311
1312         /* run the program */
1313         execve(prog, args, script_env);
1314         if (must_exist || errno != ENOENT)
1315             warn("Can't execute %s: %m", prog);
1316         _exit(-1);
1317     }
1318
1319     if (debug)
1320         dbglog("Script %s started; pid = %d", prog, pid);
1321     ++n_children;
1322
1323     chp = (struct subprocess *) malloc(sizeof(struct subprocess));
1324     if (chp == NULL) {
1325         warn("losing track of %s process", prog);
1326     } else {
1327         chp->pid = pid;
1328         chp->prog = prog;
1329         chp->done = done;
1330         chp->arg = arg;
1331         chp->next = children;
1332         children = chp;
1333     }
1334
1335     return pid;
1336 }
1337
1338
1339 /*
1340  * reap_kids - get status from any dead child processes,
1341  * and log a message for abnormal terminations.
1342  */
1343 static void
1344 reap_kids()
1345 {
1346     int pid, status;
1347     struct subprocess *chp, **prevp;
1348
1349     if (n_children == 0)
1350         return;
1351     while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) {
1352         --n_children;
1353         for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next)
1354             if (chp->pid == pid)
1355                 break;
1356         if (debug)
1357             dbglog("process %d (%s) finished, status = 0x%x",
1358                    pid, (chp? chp->prog: "??"), status);
1359         if (WIFSIGNALED(status)) {
1360             warn("Child process %s (pid %d) terminated with signal %d",
1361                  (chp? chp->prog: "??"), pid, WTERMSIG(status));
1362         }
1363         if (chp && chp->done)
1364             (*chp->done)(chp->arg);
1365     }
1366     if (pid == -1 && errno != ECHILD)
1367         error("Error waiting for child process: %m");
1368 }
1369
1370
1371 /*
1372  * log_packet - format a packet and log it.
1373  */
1374
1375 char line[256];                 /* line to be logged accumulated here */
1376 char *linep;
1377
1378 void
1379 log_packet(p, len, prefix, level)
1380     u_char *p;
1381     int len;
1382     char *prefix;
1383     int level;
1384 {
1385     strlcpy(line, prefix, sizeof(line));
1386     linep = line + strlen(line);
1387     format_packet(p, len, pr_log, NULL);
1388     if (linep != line)
1389         syslog(level, "%s", line);
1390 }
1391
1392 /*
1393  * format_packet - make a readable representation of a packet,
1394  * calling `printer(arg, format, ...)' to output it.
1395  */
1396 static void
1397 format_packet(p, len, printer, arg)
1398     u_char *p;
1399     int len;
1400     void (*printer) __P((void *, char *, ...));
1401     void *arg;
1402 {
1403     int i, n;
1404     u_short proto;
1405     struct protent *protp;
1406
1407     if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
1408         p += 2;
1409         GETSHORT(proto, p);
1410         len -= PPP_HDRLEN;
1411         for (i = 0; (protp = protocols[i]) != NULL; ++i)
1412             if (proto == protp->protocol)
1413                 break;
1414         if (protp != NULL) {
1415             printer(arg, "[%s", protp->name);
1416             n = (*protp->printpkt)(p, len, printer, arg);
1417             printer(arg, "]");
1418             p += n;
1419             len -= n;
1420         } else {
1421             for (i = 0; (protp = protocols[i]) != NULL; ++i)
1422                 if (proto == (protp->protocol & ~0x8000))
1423                     break;
1424             if (protp != 0 && protp->data_name != 0) {
1425                 printer(arg, "[%s data]", protp->data_name);
1426                 if (len > 8)
1427                     printer(arg, "%.8B ...", p);
1428                 else
1429                     printer(arg, "%.*B", len, p);
1430                 len = 0;
1431             } else
1432                 printer(arg, "[proto=0x%x]", proto);
1433         }
1434     }
1435
1436     if (len > 32)
1437         printer(arg, "%.32B ...", p);
1438     else
1439         printer(arg, "%.*B", len, p);
1440 }
1441
1442 static void
1443 pr_log __V((void *arg, char *fmt, ...))
1444 {
1445     int n;
1446     va_list pvar;
1447     char buf[256];
1448
1449 #if __STDC__
1450     va_start(pvar, fmt);
1451 #else
1452     void *arg;
1453     char *fmt;
1454     va_start(pvar);
1455     arg = va_arg(pvar, void *);
1456     fmt = va_arg(pvar, char *);
1457 #endif
1458
1459     n = vslprintf(buf, sizeof(buf), fmt, pvar);
1460     va_end(pvar);
1461
1462     if (linep + n + 1 > line + sizeof(line)) {
1463         syslog(LOG_DEBUG, "%s", line);
1464         linep = line;
1465     }
1466     strlcpy(linep, buf, line + sizeof(line) - linep);
1467     linep += n;
1468 }
1469
1470 /*
1471  * vslp_printer - used in processing a %P format
1472  */
1473 struct buffer_info {
1474     char *ptr;
1475     int len;
1476 };
1477
1478 static void
1479 vslp_printer __V((void *arg, char *fmt, ...))
1480 {
1481     int n;
1482     va_list pvar;
1483     struct buffer_info *bi;
1484
1485 #if __STDC__
1486     va_start(pvar, fmt);
1487 #else
1488     void *arg;
1489     char *fmt;
1490     va_start(pvar);
1491     arg = va_arg(pvar, void *);
1492     fmt = va_arg(pvar, char *);
1493 #endif
1494
1495     bi = (struct buffer_info *) arg;
1496     n = vslprintf(bi->ptr, bi->len, fmt, pvar);
1497     va_end(pvar);
1498
1499     bi->ptr += n;
1500     bi->len -= n;
1501 }
1502
1503 /*
1504  * print_string - print a readable representation of a string using
1505  * printer.
1506  */
1507 void
1508 print_string(p, len, printer, arg)
1509     char *p;
1510     int len;
1511     void (*printer) __P((void *, char *, ...));
1512     void *arg;
1513 {
1514     int c;
1515
1516     printer(arg, "\"");
1517     for (; len > 0; --len) {
1518         c = *p++;
1519         if (' ' <= c && c <= '~') {
1520             if (c == '\\' || c == '"')
1521                 printer(arg, "\\");
1522             printer(arg, "%c", c);
1523         } else {
1524             switch (c) {
1525             case '\n':
1526                 printer(arg, "\\n");
1527                 break;
1528             case '\r':
1529                 printer(arg, "\\r");
1530                 break;
1531             case '\t':
1532                 printer(arg, "\\t");
1533                 break;
1534             default:
1535                 printer(arg, "\\%.3o", c);
1536             }
1537         }
1538     }
1539     printer(arg, "\"");
1540 }
1541
1542 /*
1543  * novm - log an error message saying we ran out of memory, and die.
1544  */
1545 void
1546 novm(msg)
1547     char *msg;
1548 {
1549     fatal("Virtual memory exhausted allocating %s\n", msg);
1550 }
1551
1552 /*
1553  * slprintf - format a message into a buffer.  Like sprintf except we
1554  * also specify the length of the output buffer, and we handle
1555  * %r (recursive format), %m (error message), %v (visible string),
1556  * %q (quoted string), %t (current time) and %I (IP address) formats.
1557  * Doesn't do floating-point formats.
1558  * Returns the number of chars put into buf.
1559  */
1560 int
1561 slprintf __V((char *buf, int buflen, char *fmt, ...))
1562 {
1563     va_list args;
1564     int n;
1565
1566 #if __STDC__
1567     va_start(args, fmt);
1568 #else
1569     char *buf;
1570     int buflen;
1571     char *fmt;
1572     va_start(args);
1573     buf = va_arg(args, char *);
1574     buflen = va_arg(args, int);
1575     fmt = va_arg(args, char *);
1576 #endif
1577     n = vslprintf(buf, buflen, fmt, args);
1578     va_end(args);
1579     return n;
1580 }
1581
1582 /*
1583  * vslprintf - like slprintf, takes a va_list instead of a list of args.
1584  */
1585 #define OUTCHAR(c)      (buflen > 0? (--buflen, *buf++ = (c)): 0)
1586
1587 int
1588 vslprintf(buf, buflen, fmt, args)
1589     char *buf;
1590     int buflen;
1591     char *fmt;
1592     va_list args;
1593 {
1594     int c, i, n;
1595     int width, prec, fillch;
1596     int base, len, neg, quoted;
1597     unsigned long val = 0;
1598     char *str, *f, *buf0;
1599     unsigned char *p;
1600     char num[32];
1601     time_t t;
1602     u_int32_t ip;
1603     static char hexchars[] = "0123456789abcdef";
1604     struct buffer_info bufinfo;
1605
1606     buf0 = buf;
1607     --buflen;
1608     while (buflen > 0) {
1609         for (f = fmt; *f != '%' && *f != 0; ++f)
1610             ;
1611         if (f > fmt) {
1612             len = f - fmt;
1613             if (len > buflen)
1614                 len = buflen;
1615             memcpy(buf, fmt, len);
1616             buf += len;
1617             buflen -= len;
1618             fmt = f;
1619         }
1620         if (*fmt == 0)
1621             break;
1622         c = *++fmt;
1623         width = prec = 0;
1624         fillch = ' ';
1625         if (c == '0') {
1626             fillch = '0';
1627             c = *++fmt;
1628         }
1629         if (c == '*') {
1630             width = va_arg(args, int);
1631             c = *++fmt;
1632         } else {
1633             while (isdigit(c)) {
1634                 width = width * 10 + c - '0';
1635                 c = *++fmt;
1636             }
1637         }
1638         if (c == '.') {
1639             c = *++fmt;
1640             if (c == '*') {
1641                 prec = va_arg(args, int);
1642                 c = *++fmt;
1643             } else {
1644                 while (isdigit(c)) {
1645                     prec = prec * 10 + c - '0';
1646                     c = *++fmt;
1647                 }
1648             }
1649         }
1650         str = 0;
1651         base = 0;
1652         neg = 0;
1653         ++fmt;
1654         switch (c) {
1655         case 'd':
1656             i = va_arg(args, int);
1657             if (i < 0) {
1658                 neg = 1;
1659                 val = -i;
1660             } else
1661                 val = i;
1662             base = 10;
1663             break;
1664         case 'o':
1665             val = va_arg(args, unsigned int);
1666             base = 8;
1667             break;
1668         case 'x':
1669         case 'X':
1670             val = va_arg(args, unsigned int);
1671             base = 16;
1672             break;
1673         case 'p':
1674             val = (unsigned long) va_arg(args, void *);
1675             base = 16;
1676             neg = 2;
1677             break;
1678         case 's':
1679             str = va_arg(args, char *);
1680             break;
1681         case 'c':
1682             num[0] = va_arg(args, int);
1683             num[1] = 0;
1684             str = num;
1685             break;
1686         case 'm':
1687             str = strerror(errno);
1688             break;
1689         case 'I':
1690             ip = va_arg(args, u_int32_t);
1691             ip = ntohl(ip);
1692             slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff,
1693                      (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
1694             str = num;
1695             break;
1696         case 'r':
1697             f = va_arg(args, char *);
1698 #ifndef __powerpc__
1699             n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list));
1700 #else
1701             /* On the powerpc, a va_list is an array of 1 structure */
1702             n = vslprintf(buf, buflen + 1, f, va_arg(args, void *));
1703 #endif
1704             buf += n;
1705             buflen -= n;
1706             continue;
1707         case 't':
1708             time(&t);
1709             str = ctime(&t);
1710             str += 4;           /* chop off the day name */
1711             str[15] = 0;        /* chop off year and newline */
1712             break;
1713         case 'v':               /* "visible" string */
1714         case 'q':               /* quoted string */
1715             quoted = c == 'q';
1716             p = va_arg(args, unsigned char *);
1717             if (fillch == '0' && prec > 0) {
1718                 n = prec;
1719             } else {
1720                 n = strlen((char *)p);
1721                 if (prec > 0 && prec < n)
1722                     n = prec;
1723             }
1724             while (n > 0 && buflen > 0) {
1725                 c = *p++;
1726                 --n;
1727                 if (!quoted && c >= 0x80) {
1728                     OUTCHAR('M');
1729                     OUTCHAR('-');
1730                     c -= 0x80;
1731                 }
1732                 if (quoted && (c == '"' || c == '\\'))
1733                     OUTCHAR('\\');
1734                 if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
1735                     if (quoted) {
1736                         OUTCHAR('\\');
1737                         switch (c) {
1738                         case '\t':      OUTCHAR('t');   break;
1739                         case '\n':      OUTCHAR('n');   break;
1740                         case '\b':      OUTCHAR('b');   break;
1741                         case '\f':      OUTCHAR('f');   break;
1742                         default:
1743                             OUTCHAR('x');
1744                             OUTCHAR(hexchars[c >> 4]);
1745                             OUTCHAR(hexchars[c & 0xf]);
1746                         }
1747                     } else {
1748                         if (c == '\t')
1749                             OUTCHAR(c);
1750                         else {
1751                             OUTCHAR('^');
1752                             OUTCHAR(c ^ 0x40);
1753                         }
1754                     }
1755                 } else
1756                     OUTCHAR(c);
1757             }
1758             continue;
1759         case 'P':               /* print PPP packet */
1760             bufinfo.ptr = buf;
1761             bufinfo.len = buflen + 1;
1762             p = va_arg(args, unsigned char *);
1763             n = va_arg(args, int);
1764             format_packet(p, n, vslp_printer, &bufinfo);
1765             buf = bufinfo.ptr;
1766             buflen = bufinfo.len - 1;
1767             continue;
1768         case 'B':
1769             p = va_arg(args, unsigned char *);
1770             for (n = prec; n > 0; --n) {
1771                 c = *p++;
1772                 if (fillch == ' ')
1773                     OUTCHAR(' ');
1774                 OUTCHAR(hexchars[(c >> 4) & 0xf]);
1775                 OUTCHAR(hexchars[c & 0xf]);
1776             }
1777             continue;
1778         default:
1779             *buf++ = '%';
1780             if (c != '%')
1781                 --fmt;          /* so %z outputs %z etc. */
1782             --buflen;
1783             continue;
1784         }
1785         if (base != 0) {
1786             str = num + sizeof(num);
1787             *--str = 0;
1788             while (str > num + neg) {
1789                 *--str = hexchars[val % base];
1790                 val = val / base;
1791                 if (--prec <= 0 && val == 0)
1792                     break;
1793             }
1794             switch (neg) {
1795             case 1:
1796                 *--str = '-';
1797                 break;
1798             case 2:
1799                 *--str = 'x';
1800                 *--str = '0';
1801                 break;
1802             }
1803             len = num + sizeof(num) - 1 - str;
1804         } else {
1805             len = strlen(str);
1806             if (prec > 0 && len > prec)
1807                 len = prec;
1808         }
1809         if (width > 0) {
1810             if (width > buflen)
1811                 width = buflen;
1812             if ((n = width - len) > 0) {
1813                 buflen -= n;
1814                 for (; n > 0; --n)
1815                     *buf++ = fillch;
1816             }
1817         }
1818         if (len > buflen)
1819             len = buflen;
1820         memcpy(buf, str, len);
1821         buf += len;
1822         buflen -= len;
1823     }
1824     *buf = 0;
1825     return buf - buf0;
1826 }
1827
1828 /*
1829  * script_setenv - set an environment variable value to be used
1830  * for scripts that we run (e.g. ip-up, auth-up, etc.)
1831  */
1832 void
1833 script_setenv(var, value)
1834     char *var, *value;
1835 {
1836     size_t vl = strlen(var) + strlen(value) + 2;
1837     int i;
1838     char *p, *newstring;
1839
1840     newstring = (char *) malloc(vl);
1841     if (newstring == 0)
1842         return;
1843     slprintf(newstring, vl, "%s=%s", var, value);
1844
1845     /* check if this variable is already set */
1846     if (script_env != 0) {
1847         for (i = 0; (p = script_env[i]) != 0; ++i) {
1848             if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
1849                 free(p);
1850                 script_env[i] = newstring;
1851                 return;
1852             }
1853         }
1854     } else {
1855         i = 0;
1856         script_env = (char **) malloc(16 * sizeof(char *));
1857         if (script_env == 0)
1858             return;
1859         s_env_nalloc = 16;
1860     }
1861
1862     /* reallocate script_env with more space if needed */
1863     if (i + 1 >= s_env_nalloc) {
1864         int new_n = i + 17;
1865         char **newenv = (char **) realloc((void *)script_env,
1866                                           new_n * sizeof(char *));
1867         if (newenv == 0)
1868             return;
1869         script_env = newenv;
1870         s_env_nalloc = new_n;
1871     }
1872
1873     script_env[i] = newstring;
1874     script_env[i+1] = 0;
1875 }
1876
1877 /*
1878  * script_unsetenv - remove a variable from the environment
1879  * for scripts.
1880  */
1881 void
1882 script_unsetenv(var)
1883     char *var;
1884 {
1885     int vl = strlen(var);
1886     int i;
1887     char *p;
1888
1889     if (script_env == 0)
1890         return;
1891     for (i = 0; (p = script_env[i]) != 0; ++i) {
1892         if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
1893             free(p);
1894             while ((script_env[i] = script_env[i+1]) != 0)
1895                 ++i;
1896             break;
1897         }
1898     }
1899 }
1900
1901 /*
1902  * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
1903  * always leaves destination null-terminated (for len > 0).
1904  */
1905 size_t
1906 strlcpy(dest, src, len)
1907     char *dest;
1908     const char *src;
1909     size_t len;
1910 {
1911     size_t ret = strlen(src);
1912
1913     if (len != 0) {
1914         if (ret < len)
1915             strcpy(dest, src);
1916         else {
1917             strncpy(dest, src, len - 1);
1918             dest[len-1] = 0;
1919         }
1920     }
1921     return ret;
1922 }
1923
1924 /*
1925  * strlcat - like strcat/strncat, doesn't overflow destination buffer,
1926  * always leaves destination null-terminated (for len > 0).
1927  */
1928 size_t
1929 strlcat(dest, src, len)
1930     char *dest;
1931     const char *src;
1932     size_t len;
1933 {
1934     size_t dlen = strlen(dest);
1935
1936     return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0));
1937 }
1938
1939 /*
1940  * logit - does the hard work for fatal et al.
1941  */
1942 static void
1943 logit(level, fmt, args)
1944     int level;
1945     char *fmt;
1946     va_list args;
1947 {
1948     int n;
1949     char buf[256];
1950
1951     n = vslprintf(buf, sizeof(buf), fmt, args);
1952     syslog(level, "%s", buf);
1953     if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) {
1954         if (buf[n-1] != '\n')
1955             buf[n++] = '\n';
1956         if (write(log_to_fd, buf, n) != n)
1957             log_to_fd = -1;
1958     }
1959 }
1960
1961 /*
1962  * fatal - log an error message and die horribly.
1963  */
1964 void
1965 fatal __V((char *fmt, ...))
1966 {
1967     va_list pvar;
1968
1969 #if __STDC__
1970     va_start(pvar, fmt);
1971 #else
1972     char *fmt;
1973     va_start(pvar);
1974     fmt = va_arg(pvar, char *);
1975 #endif
1976
1977     logit(LOG_ERR, fmt, pvar);
1978     va_end(pvar);
1979
1980     die(1);                     /* as promised */
1981 }
1982
1983 /*
1984  * error - log an error message.
1985  */
1986 void
1987 error __V((char *fmt, ...))
1988 {
1989     va_list pvar;
1990
1991 #if __STDC__
1992     va_start(pvar, fmt);
1993 #else
1994     char *fmt;
1995     va_start(pvar);
1996     fmt = va_arg(pvar, char *);
1997 #endif
1998
1999     logit(LOG_ERR, fmt, pvar);
2000     va_end(pvar);
2001 }
2002
2003 /*
2004  * warn - log a warning message.
2005  */
2006 void
2007 warn __V((char *fmt, ...))
2008 {
2009     va_list pvar;
2010
2011 #if __STDC__
2012     va_start(pvar, fmt);
2013 #else
2014     char *fmt;
2015     va_start(pvar);
2016     fmt = va_arg(pvar, char *);
2017 #endif
2018
2019     logit(LOG_WARNING, fmt, pvar);
2020     va_end(pvar);
2021 }
2022
2023 /*
2024  * notice - log a notice-level message.
2025  */
2026 void
2027 notice __V((char *fmt, ...))
2028 {
2029     va_list pvar;
2030
2031 #if __STDC__
2032     va_start(pvar, fmt);
2033 #else
2034     char *fmt;
2035     va_start(pvar);
2036     fmt = va_arg(pvar, char *);
2037 #endif
2038
2039     logit(LOG_NOTICE, fmt, pvar);
2040     va_end(pvar);
2041 }
2042
2043 /*
2044  * info - log an informational message.
2045  */
2046 void
2047 info __V((char *fmt, ...))
2048 {
2049     va_list pvar;
2050
2051 #if __STDC__
2052     va_start(pvar, fmt);
2053 #else
2054     char *fmt;
2055     va_start(pvar);
2056     fmt = va_arg(pvar, char *);
2057 #endif
2058
2059     logit(LOG_INFO, fmt, pvar);
2060     va_end(pvar);
2061 }
2062
2063 /*
2064  * dbglog - log a debug message.
2065  */
2066 void
2067 dbglog __V((char *fmt, ...))
2068 {
2069     va_list pvar;
2070
2071 #if __STDC__
2072     va_start(pvar, fmt);
2073 #else
2074     char *fmt;
2075     va_start(pvar);
2076     fmt = va_arg(pvar, char *);
2077 #endif
2078
2079     logit(LOG_DEBUG, fmt, pvar);
2080     va_end(pvar);
2081 }