X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fmain.c;h=409628c4b0a03383d7647d32be1993851f7cce63;hp=3d4c16acbad4db134f3ed5ea76eee7174327454d;hb=690865e93221a67d2ee33f4d184a8be79c3fc7ec;hpb=52a17b6d41d64d0502a73e5b4224546360581b49 diff --git a/pppd/main.c b/pppd/main.c index 3d4c16a..409628c 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: main.c,v 1.99 2000/06/30 04:54:20 paulus Exp $" +#define RCSID "$Id: main.c,v 1.117 2002/10/27 12:04:07 fcusack Exp $" #include #include @@ -53,9 +53,12 @@ #include "upap.h" #include "chap.h" #include "ccp.h" +#include "ecp.h" #include "pathnames.h" -#include "patchlevel.h" + +#ifdef USE_TDB #include "tdb.h" +#endif #ifdef CBCP_SUPPORT #include "cbcp.h" @@ -74,6 +77,8 @@ static const char rcsid[] = RCSID; char ifname[32]; /* Interface name */ int ifunit; /* Interface unit number */ +struct channel *the_channel; + char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ static char pidfilename[MAXPATHLEN]; /* name of pid file */ @@ -89,16 +94,22 @@ int hungup; /* terminal has been hung up */ int privileged; /* we're running as real uid root */ int need_holdoff; /* need holdoff period before restarting */ int detached; /* have detached from terminal */ -struct stat devstat; /* result of stat() on devnam */ volatile int status; /* exit status for pppd */ int unsuccess; /* # unsuccessful connection attempts */ int do_callback; /* != 0 if we should do callback next */ int doing_callback; /* != 0 if we are doing callback */ +int ppp_session_number; /* Session number, for channels with such a + concept (eg PPPoE) */ +#ifdef USE_TDB TDB_CONTEXT *pppdb; /* database for storing status etc. */ +#endif + char db_key[32]; int (*holdoff_hook) __P((void)) = NULL; int (*new_phase_hook) __P((int)) = NULL; +void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL; +void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL; static int conn_running; /* we have a [dis]connector running */ static int devfd; /* fd of underlying device */ @@ -108,6 +119,10 @@ static int fd_loop; /* fd for getting demand-dial packets */ int phase; /* where the link is at */ int kill_link; int open_ccp_flag; +int listen_time; +int got_sigusr2; +int got_sigterm; +int got_sighup; static int waiting; static sigjmp_buf sigjmp; @@ -166,10 +181,16 @@ static void open_ccp __P((int)); static void bad_signal __P((int)); static void holdoff_end __P((void *)); static int reap_kids __P((int waitfor)); + +#ifdef USE_TDB static void update_db_entry __P((void)); static void add_db_key __P((const char *)); static void delete_db_key __P((const char *)); static void cleanup_db __P((void)); +#endif + +static void handle_events __P((void)); +static void print_link_stats __P((void)); extern char *ttyname __P((int)); extern char *getlogin __P((void)); @@ -201,6 +222,7 @@ struct protent *protocols[] = { &ipv6cp_protent, #endif &ccp_protent, + &ecp_protent, #ifdef IPX_CHANGE &ipxcp_protent, #endif @@ -222,15 +244,13 @@ main(argc, argv) int argc; char *argv[]; { - int i, fdflags, t; + int i, t; char *p; struct passwd *pw; - struct timeval timo; - sigset_t mask; struct protent *protp; - struct stat statbuf; char numbuf[16]; + link_stats_valid = 0; new_phase(PHASE_INITIALIZE); /* @@ -278,39 +298,32 @@ main(argc, argv) for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); + /* + * Initialize the default channel. + */ + tty_init(); + progname = *argv; /* * Parse, in order, the system options file, the user's options file, - * the tty's options file, and the command line arguments. + * and the command line arguments. */ if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) || !options_from_user() || !parse_args(argc-1, argv+1)) exit(EXIT_OPTION_ERROR); + devnam_fixed = 1; /* can no longer change device name */ /* - * Work out the device name, if it hasn't already been specified. + * Work out the device name, if it hasn't already been specified, + * and parse the tty's options file. */ - using_pty = notty || ptycommand != NULL || pty_socket != NULL; - if (!using_pty && default_device) { - char *p; - if (!isatty(0) || (p = ttyname(0)) == NULL) { - option_error("no device specified and stdin is not a tty"); - exit(EXIT_OPTION_ERROR); - } - strlcpy(devnam, p, sizeof(devnam)); - if (stat(devnam, &devstat) < 0) - fatal("Couldn't stat default device %s: %m", devnam); - } + if (the_channel->process_extra_options) + (*the_channel->process_extra_options)(); - /* - * Parse the tty options file. - * The per-tty options file should not change - * ptycommand, pty_socket, notty or devnam. - */ - if (!using_pty && !options_for_tty()) - exit(EXIT_OPTION_ERROR); + if (debug) + setlogmask(LOG_UPTO(LOG_DEBUG)); /* * Check that we are running as root. @@ -322,13 +335,14 @@ main(argc, argv) } if (!ppp_available()) { - option_error(no_ppp_msg); + option_error("%s", no_ppp_msg); exit(EXIT_NO_KERNEL_SUPPORT); } /* * Check that the options given are valid and consistent. */ + check_options(); if (!sys_check_options()) exit(EXIT_OPTION_ERROR); auth_check_options(); @@ -338,66 +352,33 @@ main(argc, argv) for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->check_options != NULL) (*protp->check_options)(); - if (demand && connect_script == 0) { - option_error("connect script is required for demand-dialling\n"); - exit(EXIT_OPTION_ERROR); - } - /* default holdoff to 0 if no connect script has been given */ - if (connect_script == 0 && !holdoff_specified) - holdoff = 0; - - if (using_pty) { - if (!default_device) { - option_error("%s option precludes specifying device name", - notty? "notty": "pty"); - exit(EXIT_OPTION_ERROR); - } - if (ptycommand != NULL && notty) { - option_error("pty option is incompatible with notty option"); - exit(EXIT_OPTION_ERROR); - } - if (pty_socket != NULL && (ptycommand != NULL || notty)) { - option_error("socket option is incompatible with pty and notty"); - exit(EXIT_OPTION_ERROR); - } - default_device = notty; - lockflag = 0; - modem = 0; - if (notty && log_to_fd <= 1) - log_to_fd = -1; - } else { - /* - * If the user has specified a device which is the same as - * the one on stdin, pretend they didn't specify any. - * If the device is already open read/write on stdin, - * we assume we don't need to lock it, and we can open it as root. - */ - if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) - && statbuf.st_rdev == devstat.st_rdev) { - default_device = 1; - fdflags = fcntl(0, F_GETFL); - if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR) - privopen = 1; - } + if (the_channel->check_options) + (*the_channel->check_options)(); + + + if (dump_options || dryrun) { + init_pr_log(NULL, LOG_INFO); + print_options(pr_log, NULL); + end_pr_log(); } - if (default_device) - nodetach = 1; /* - * Don't send log messages to the serial port, it tends to - * confuse the peer. :-) + * Early check for remote number authorization. */ - if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0 - && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) - log_to_fd = -1; + if (!auth_number()) { + warn("calling number %q is not authorized", remote_number); + exit(EXIT_CNID_AUTH_FAILED); + } + + if (dryrun) + die(0); /* * Initialize system-dependent stuff. */ sys_init(); - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); +#ifdef USE_TDB pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); if (pppdb != NULL) { slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); @@ -409,6 +390,7 @@ main(argc, argv) multilink = 0; } } +#endif /* * Detach ourselves from the terminal, if required, @@ -424,8 +406,7 @@ main(argc, argv) else p = "(unknown)"; } - syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d", - VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); + syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); script_setenv("PPPLOGNAME", p, 0); if (devnam[0]) @@ -446,11 +427,14 @@ main(argc, argv) /* * Open the loopback channel and set it up to be the ppp interface. */ +#ifdef USE_TDB tdb_writelock(pppdb); +#endif fd_loop = open_ppp_loopback(); set_ifunit(1); +#ifdef USE_TDB tdb_writeunlock(pppdb); - +#endif /* * Configure the interface and mark it up, etc. */ @@ -460,6 +444,7 @@ main(argc, argv) do_callback = 0; for (;;) { + listen_time = 0; need_holdoff = 1; devfd = -1; status = EXIT_OK; @@ -471,32 +456,15 @@ main(argc, argv) /* * Don't do anything until we see some activity. */ - kill_link = 0; new_phase(PHASE_DORMANT); demand_unblock(); add_fd(fd_loop); for (;;) { - if (sigsetjmp(sigjmp, 1) == 0) { - sigprocmask(SIG_BLOCK, &mask, NULL); - if (kill_link || got_sigchld) { - sigprocmask(SIG_UNBLOCK, &mask, NULL); - } else { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_input(timeleft(&timo)); - } - } - waiting = 0; - calltimeout(); - if (kill_link) { - if (!persist) - break; - kill_link = 0; - } + handle_events(); + if (kill_link && !persist) + break; if (get_loop_output()) break; - if (got_sigchld) - reap_kids(0); } remove_fd(fd_loop); if (kill_link && !persist) @@ -511,92 +479,61 @@ main(argc, argv) new_phase(PHASE_SERIALCONN); - devfd = connect_tty(); + devfd = the_channel->connect(); if (devfd < 0) goto fail; /* set up the serial device as a ppp interface */ +#ifdef USE_TDB tdb_writelock(pppdb); - fd_ppp = establish_ppp(devfd); +#endif + fd_ppp = the_channel->establish_ppp(devfd); if (fd_ppp < 0) { +#ifdef USE_TDB tdb_writeunlock(pppdb); +#endif status = EXIT_FATAL_ERROR; goto disconnect; } if (!demand && ifunit >= 0) set_ifunit(1); +#ifdef USE_TDB tdb_writeunlock(pppdb); +#endif /* * Start opening the connection and wait for * incoming events (reply, timeout, etc.). */ - notice("Connect: %s <--> %s", ifname, ppp_devnam); + if (ifunit >= 0) + notice("Connect: %s <--> %s", ifname, ppp_devnam); + else + notice("Starting negotiation on %s", ppp_devnam); gettimeofday(&start_time, NULL); - link_stats_valid = 0; script_unsetenv("CONNECT_TIME"); script_unsetenv("BYTES_SENT"); script_unsetenv("BYTES_RCVD"); lcp_lowerup(0); - /* - * If we are initiating this connection, wait for a short - * time for something from the peer. This can avoid bouncing - * our packets off his tty before he has it set up. - */ add_fd(fd_ppp); -#ifdef XXX - if (connect_delay != 0 && (connector != NULL || ptycommand != NULL)) { - struct timeval t; - t.tv_sec = connect_delay / 1000; - t.tv_usec = connect_delay % 1000; - wait_input(&t); - } -#endif - lcp_open(0); /* Start protocol */ - open_ccp_flag = 0; status = EXIT_NEGOTIATION_FAILED; new_phase(PHASE_ESTABLISH); while (phase != PHASE_DEAD) { - if (sigsetjmp(sigjmp, 1) == 0) { - sigprocmask(SIG_BLOCK, &mask, NULL); - if (kill_link || open_ccp_flag || got_sigchld) { - sigprocmask(SIG_UNBLOCK, &mask, NULL); - } else { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_input(timeleft(&timo)); - } - } - waiting = 0; - calltimeout(); + handle_events(); get_input(); - if (kill_link) { + if (kill_link) lcp_close(0, "User request"); - kill_link = 0; - } if (open_ccp_flag) { if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ (*ccp_protent.open)(0); } - open_ccp_flag = 0; } - if (got_sigchld) - reap_kids(0); /* Don't leave dead kids lying around */ } - /* - * Print connect time and statistics. - */ - if (link_stats_valid) { - int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ - info("Connect time %d.%d minutes.", t/10, t%10); - info("Sent %d bytes, received %d bytes.", - link_stats.bytes_out, link_stats.bytes_in); - } + print_link_stats(); /* * Delete pid file before disestablishing ppp. Otherwise it @@ -605,7 +542,7 @@ main(argc, argv) */ if (!demand) { if (pidfilename[0] != 0 - && unlink(pidfilename) < 0 && errno != ENOENT) + && unlink(pidfilename) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; } @@ -617,9 +554,7 @@ main(argc, argv) */ remove_fd(fd_ppp); clean_check(); - if (demand) - restore_loop(); - disestablish_ppp(devfd); + the_channel->disestablish_ppp(devfd); fd_ppp = -1; if (!hungup) lcp_lowerdown(0); @@ -632,14 +567,15 @@ main(argc, argv) */ disconnect: new_phase(PHASE_DISCONNECT); - disconnect_tty(); + the_channel->disconnect(); fail: - cleanup_tty(); + if (the_channel->cleanup) + (*the_channel->cleanup)(); if (!demand) { if (pidfilename[0] != 0 - && unlink(pidfilename) < 0 && errno != ENOENT) + && unlink(pidfilename) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; } @@ -647,7 +583,6 @@ main(argc, argv) if (!persist || (maxfail > 0 && unsuccess >= maxfail)) break; - kill_link = 0; if (demand) demand_discard(); t = need_holdoff? holdoff: 0; @@ -657,24 +592,9 @@ main(argc, argv) new_phase(PHASE_HOLDOFF); TIMEOUT(holdoff_end, NULL, t); do { - if (sigsetjmp(sigjmp, 1) == 0) { - sigprocmask(SIG_BLOCK, &mask, NULL); - if (kill_link || got_sigchld) { - sigprocmask(SIG_UNBLOCK, &mask, NULL); - } else { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_input(timeleft(&timo)); - } - } - waiting = 0; - calltimeout(); - if (kill_link) { - kill_link = 0; + handle_events(); + if (kill_link) new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ - } - if (got_sigchld) - reap_kids(0); } while (phase == PHASE_HOLDOFF); if (!persist) break; @@ -698,6 +618,50 @@ main(argc, argv) return 0; } +/* + * handle_events - wait for something to happen and respond to it. + */ +static void +handle_events() +{ + struct timeval timo; + sigset_t mask; + + kill_link = open_ccp_flag = 0; + if (sigsetjmp(sigjmp, 1) == 0) { + sigprocmask(SIG_BLOCK, &mask, NULL); + if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { + sigprocmask(SIG_UNBLOCK, &mask, NULL); + } else { + waiting = 1; + sigprocmask(SIG_UNBLOCK, &mask, NULL); + wait_input(timeleft(&timo)); + } + } + waiting = 0; + calltimeout(); + if (got_sighup) { + kill_link = 1; + got_sighup = 0; + if (status != EXIT_HANGUP) + status = EXIT_USER_REQUEST; + } + if (got_sigterm) { + kill_link = 1; + persist = 0; + status = EXIT_USER_REQUEST; + got_sigterm = 0; + } + if (got_sigchld) { + reap_kids(0); /* Don't leave dead kids lying around */ + got_sigchld = 0; + } + if (got_sigusr2) { + open_ccp_flag = 1; + got_sigusr2 = 0; + } +} + /* * setup_signals - initialize signal handling. */ @@ -825,7 +789,7 @@ detach() close(1); close(2); detached = 1; - if (!log_to_file && !log_to_specific_fd) + if (log_default) log_to_fd = -1; /* update pid files if they have been written already */ if (pidfilename[0]) @@ -1010,14 +974,14 @@ get_input() return; } - if (debug /*&& (debugflags & DBG_INPACKET)*/) - dbglog("rcvd %P", p, len); - if (len < PPP_HDRLEN) { - MAINDEBUG(("io(): Received short packet.")); + dbglog("received short packet:%.*B", len, p); return; } + dump_packet("rcvd", p, len); + if (snoop_recv_hook) snoop_recv_hook(p, len); + p += 2; /* Skip address and control */ GETSHORT(protocol, p); len -= PPP_HDRLEN; @@ -1087,6 +1051,7 @@ void die(status) int status; { + print_link_stats(); cleanup(); notify(exitnotify, status); syslog(LOG_INFO, "Exit."); @@ -1103,18 +1068,36 @@ cleanup() sys_cleanup(); if (fd_ppp >= 0) - disestablish_ppp(devfd); - cleanup_tty(); + the_channel->disestablish_ppp(devfd); + if (the_channel->cleanup) + (*the_channel->cleanup)(); - if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) + if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; - if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) + if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", linkpidfile); linkpidfile[0] = 0; +#ifdef USE_TDB if (pppdb != NULL) cleanup_db(); +#endif + +} + +void +print_link_stats() +{ + /* + * Print connect time and statistics. + */ + if (link_stats_valid) { + int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ + info("Connect time %d.%d minutes.", t/10, t%10); + info("Sent %u bytes, received %u bytes.", + link_stats.bytes_out, link_stats.bytes_in); + } } /* @@ -1133,11 +1116,11 @@ update_link_stats(u) link_connect_time = now.tv_sec - start_time.tv_sec; link_stats_valid = 1; - slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time); + slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); script_setenv("CONNECT_TIME", numbuf, 0); - slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_out); + slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out); script_setenv("BYTES_SENT", numbuf, 0); - slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_in); + slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in); script_setenv("BYTES_RCVD", numbuf, 0); } @@ -1154,20 +1137,18 @@ static struct timeval timenow; /* Current time */ /* * timeout - Schedule a timeout. - * - * Note that this timeout takes the number of seconds, NOT hz (as in - * the kernel). */ void -timeout(func, arg, time) +timeout(func, arg, secs, usecs) void (*func) __P((void *)); void *arg; - int time; + int secs, usecs; { struct callout *newp, *p, **pp; - - MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time)); - + + MAINDEBUG(("Timeout %p:%p in %d.%03d seconds.", func, arg, + secs, usecs/1000)); + /* * Allocate timeout. */ @@ -1176,9 +1157,13 @@ timeout(func, arg, time) newp->c_arg = arg; newp->c_func = func; gettimeofday(&timenow, NULL); - newp->c_time.tv_sec = timenow.tv_sec + time; - newp->c_time.tv_usec = timenow.tv_usec; - + newp->c_time.tv_sec = timenow.tv_sec + secs; + newp->c_time.tv_usec = timenow.tv_usec + usecs; + if (newp->c_time.tv_usec >= 1000000) { + newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; + newp->c_time.tv_usec %= 1000000; + } + /* * Find correct place and link it in. */ @@ -1201,9 +1186,9 @@ untimeout(func, arg) void *arg; { struct callout **copp, *freep; - + MAINDEBUG(("Untimeout %p:%p.", func, arg)); - + /* * Find first matching timeout and remove it from the list. */ @@ -1295,9 +1280,7 @@ hup(sig) int sig; { info("Hangup (SIGHUP)"); - kill_link = 1; - if (status != EXIT_HANGUP) - status = EXIT_USER_REQUEST; + got_sighup = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); @@ -1318,9 +1301,7 @@ term(sig) int sig; { info("Terminating on signal %d.", sig); - persist = 0; /* don't try to restart */ - kill_link = 1; - status = EXIT_USER_REQUEST; + got_sigterm = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); @@ -1373,7 +1354,7 @@ static void open_ccp(sig) int sig; { - open_ccp_flag = 1; + got_sigusr2 = 1; if (waiting) siglongjmp(sigjmp, 1); } @@ -1461,7 +1442,8 @@ device_script(program, in, out, dont_wait) close(1); close(2); sys_close(); - tty_close_fds(); + if (the_channel->close) + (*the_channel->close)(); closelog(); /* dup the in, out, err fds to 0, 1, 2 */ @@ -1543,7 +1525,8 @@ run_program(prog, args, must_exist, done, arg) close (0); close (1); close (2); - tty_close_fds(); + if (the_channel->close) + (*the_channel->close)(); /* Don't pass handles to the PPP device, even by accident. */ new_fd = open (_PATH_DEVNULL, O_RDWR); @@ -1559,7 +1542,7 @@ run_program(prog, args, must_exist, done, arg) #ifdef BSD /* Force the priority back to zero if pppd is running higher. */ if (setpriority (PRIO_PROCESS, 0, 0) < 0) - warn("can't reset priority to 0: %m"); + warn("can't reset priority to 0: %m"); #endif /* SysV recommends a second fork at this point. */ @@ -1624,7 +1607,6 @@ reap_kids(waitfor) int pid, status; struct subprocess *chp, **prevp; - got_sigchld = 0; if (n_children == 0) return 0; while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1 @@ -1641,7 +1623,8 @@ reap_kids(waitfor) (chp? chp->prog: "??"), pid, WTERMSIG(status)); } else if (debug) dbglog("Script %s finished (pid %d), status = 0x%x", - (chp? chp->prog: "??"), pid, status); + (chp? chp->prog: "??"), pid, + WIFEXITED(status) ? WEXITSTATUS(status) : status); if (chp && chp->done) (*chp->done)(chp->arg); if (chp) @@ -1698,7 +1681,7 @@ remove_notifier(notif, func, arg) } /* - * notify - call a set of functions registered with add_notify. + * notify - call a set of functions registered with add_notifier. */ void notify(notif, val) @@ -1747,13 +1730,17 @@ script_setenv(var, value, iskey) if (script_env != 0) { for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, varl) == 0 && p[varl] == '=') { +#ifdef USE_TDB if (p[-1] && pppdb != NULL) delete_db_key(p); +#endif free(p-1); script_env[i] = newstring; +#ifdef USE_TDB if (iskey && pppdb != NULL) add_db_key(newstring); update_db_entry(); +#endif return; } } @@ -1780,11 +1767,13 @@ script_setenv(var, value, iskey) script_env[i] = newstring; script_env[i+1] = 0; +#ifdef USE_TDB if (pppdb != NULL) { if (iskey) add_db_key(newstring); update_db_entry(); } +#endif } /* @@ -1803,18 +1792,23 @@ script_unsetenv(var) return; for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, vl) == 0 && p[vl] == '=') { +#ifdef USE_TDB if (p[-1] && pppdb != NULL) delete_db_key(p); +#endif free(p-1); while ((script_env[i] = script_env[i+1]) != 0) ++i; break; } } +#ifdef USE_TDB if (pppdb != NULL) update_db_entry(); +#endif } +#ifdef USE_TDB /* * update_db_entry - update our entry in the database. */ @@ -1844,6 +1838,9 @@ update_db_entry() if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) error("tdb_store failed: %s", tdb_error(pppdb)); + if (vbuf) + free(vbuf); + } /* @@ -1894,3 +1891,4 @@ cleanup_db() if (p[-1]) delete_db_key(p); } +#endif /* USE_TDB */