1 /* $OpenBSD: main.c,v 1.54 2016/03/17 19:40:43 krw Exp $ */ 2 3 /* 4 * main.c - Point-to-Point Protocol main module 5 * 6 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name "Carnegie Mellon University" must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. For permission or any legal 23 * details, please contact 24 * Office of Technology Transfer 25 * Carnegie Mellon University 26 * 5000 Forbes Avenue 27 * Pittsburgh, PA 15213-3890 28 * (412) 268-4387, fax: (412) 268-7395 29 * tech-transfer@andrew.cmu.edu 30 * 31 * 4. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by Computing Services 34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 35 * 36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 43 */ 44 45 #include <sys/types.h> 46 #include <sys/wait.h> 47 #include <sys/time.h> 48 #include <sys/resource.h> 49 #include <sys/stat.h> 50 #include <sys/socket.h> 51 #include <net/if.h> 52 #include <stdio.h> 53 #include <ctype.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <unistd.h> 57 #include <limits.h> 58 #include <signal.h> 59 #include <errno.h> 60 #include <fcntl.h> 61 #include <syslog.h> 62 #include <netdb.h> 63 #include <utmp.h> 64 #include <pwd.h> 65 66 #include "pppd.h" 67 #include "magic.h" 68 #include "fsm.h" 69 #include "lcp.h" 70 #include "ipcp.h" 71 #include "upap.h" 72 #include "chap.h" 73 #include "ccp.h" 74 #include "pathnames.h" 75 #include "patchlevel.h" 76 77 #ifdef CBCP_SUPPORT 78 #include "cbcp.h" 79 #endif 80 81 #if defined(SUNOS4) 82 extern char *strerror(); 83 #endif 84 85 #ifdef AT_CHANGE 86 #include "atcp.h" 87 #endif 88 89 /* interface vars */ 90 char ifname[IFNAMSIZ]; /* Interface name */ 91 int ifunit; /* Interface unit number */ 92 93 char hostname[HOST_NAME_MAX+1]; /* Our hostname */ 94 static char default_devnam[PATH_MAX]; /* name of default device */ 95 static pid_t pid; /* Our pid */ 96 static uid_t uid; /* Our real user-id */ 97 static int conn_running; /* we have a [dis]connector running */ 98 static int crashed = 0; 99 100 int ttyfd = -1; /* Serial port file descriptor */ 101 mode_t tty_mode = -1; /* Original access permissions to tty */ 102 int baud_rate; /* Actual bits/second for serial device */ 103 int hungup; /* terminal has been hung up */ 104 int privileged; /* we're running as real uid root */ 105 int need_holdoff; /* need holdoff period before restarting */ 106 int detached; /* have detached from terminal */ 107 108 int phase; /* where the link is at */ 109 int kill_link; 110 int open_ccp_flag; 111 112 char **script_env; /* Env. variable values for scripts */ 113 int s_env_nalloc; /* # words avail at script_env */ 114 115 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ 116 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ 117 118 static int n_children; /* # child processes still running */ 119 120 static int locked; /* lock() has succeeded */ 121 122 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; 123 124 /* Prototypes for procedures local to this file. */ 125 126 static void cleanup(void); 127 static void close_tty(void); 128 static void get_input(void); 129 static void calltimeout(void); 130 static struct timeval *timeleft(struct timeval *); 131 static void kill_my_pg(int); 132 static void hup(int); 133 static void term(int); 134 static void chld(int); 135 static void toggle_debug(int); 136 static void open_ccp(int); 137 static void bad_signal(int); 138 static void holdoff_end(void *); 139 static int device_script(char *, int, int); 140 static void reap_kids(void); 141 static void pr_log(void *, char *, ...); 142 143 extern char *ttyname(int); 144 extern char *getlogin(void); 145 int main(int, char *[]); 146 147 #ifdef ultrix 148 #undef O_NONBLOCK 149 #define O_NONBLOCK O_NDELAY 150 #endif 151 152 #ifdef ULTRIX 153 #define setlogmask(x) 154 #endif 155 156 /* 157 * PPP Data Link Layer "protocol" table. 158 * One entry per supported protocol. 159 * The last entry must be NULL. 160 */ 161 struct protent *protocols[] = { 162 &lcp_protent, 163 &pap_protent, 164 &chap_protent, 165 #ifdef CBCP_SUPPORT 166 &cbcp_protent, 167 #endif 168 &ipcp_protent, 169 &ccp_protent, 170 #ifdef AT_CHANGE 171 &atcp_protent, 172 #endif 173 NULL 174 }; 175 176 int 177 main(argc, argv) 178 int argc; 179 char *argv[]; 180 { 181 int i, fdflags; 182 struct sigaction sa; 183 char *p; 184 struct passwd *pw; 185 struct timeval timo; 186 sigset_t mask; 187 struct protent *protp; 188 struct stat statbuf; 189 char numbuf[16]; 190 191 phase = PHASE_INITIALIZE; 192 p = ttyname(0); 193 if (p) 194 strlcpy(devnam, p, PATH_MAX); 195 strlcpy(default_devnam, devnam, sizeof default_devnam); 196 197 script_env = NULL; 198 199 /* Initialize syslog facilities */ 200 #ifdef ULTRIX 201 openlog("pppd", LOG_PID); 202 #else 203 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); 204 setlogmask(LOG_UPTO(LOG_INFO)); 205 #endif 206 207 if (gethostname(hostname, sizeof hostname) < 0 ) { 208 option_error("Couldn't get hostname: %m"); 209 die(1); 210 } 211 212 uid = getuid(); 213 privileged = uid == 0; 214 snprintf(numbuf, sizeof numbuf, "%u", uid); 215 script_setenv("UID", numbuf); 216 217 /* 218 * Initialize to the standard option set, then parse, in order, 219 * the system options file, the user's options file, 220 * the tty's options file, and the command line arguments. 221 */ 222 for (i = 0; (protp = protocols[i]) != NULL; ++i) 223 (*protp->init)(0); 224 225 if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) 226 || !options_from_user()) 227 exit(1); 228 scan_args(argc-1, argv+1); /* look for tty name on command line */ 229 if (!options_for_tty() 230 || !parse_args(argc-1, argv+1)) 231 exit(1); 232 233 /* 234 * Check that we are running as root. 235 */ 236 if (geteuid() != 0) { 237 option_error("must be root to run %s, since it is not setuid-root", 238 argv[0]); 239 die(1); 240 } 241 242 if (!ppp_available()) { 243 option_error(no_ppp_msg); 244 exit(1); 245 } 246 247 /* 248 * Check that the options given are valid and consistent. 249 */ 250 sys_check_options(); 251 auth_check_options(); 252 for (i = 0; (protp = protocols[i]) != NULL; ++i) 253 if (protp->check_options != NULL) 254 (*protp->check_options)(); 255 if (demand && connector == 0) { 256 option_error("connect script required for demand-dialling\n"); 257 exit(1); 258 } 259 260 script_setenv("DEVICE", devnam); 261 snprintf(numbuf, sizeof numbuf, "%d", baud_rate); 262 script_setenv("SPEED", numbuf); 263 264 /* 265 * If the user has specified the default device name explicitly, 266 * pretend they hadn't. 267 */ 268 if (!default_device && strcmp(devnam, default_devnam) == 0) 269 default_device = 1; 270 if (default_device) 271 nodetach = 1; 272 273 /* 274 * Initialize system-dependent stuff and magic number package. 275 */ 276 sys_init(); 277 magic_init(); 278 if (debug) 279 setlogmask(LOG_UPTO(LOG_DEBUG)); 280 281 /* 282 * Detach ourselves from the terminal, if required, 283 * and identify who is running us. 284 */ 285 if (nodetach == 0) 286 detach(); 287 pid = getpid(); 288 p = getlogin(); 289 if (p == NULL) { 290 pw = getpwuid(uid); 291 if (pw != NULL && pw->pw_name != NULL) 292 p = pw->pw_name; 293 else 294 p = "(unknown)"; 295 } 296 syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %u", 297 VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); 298 299 /* 300 * Compute mask of all interesting signals and install signal handlers 301 * for each. Only one signal handler may be active at a time. Therefore, 302 * all other signals should be masked when any handler is executing. 303 */ 304 sigemptyset(&mask); 305 sigaddset(&mask, SIGHUP); 306 sigaddset(&mask, SIGINT); 307 sigaddset(&mask, SIGTERM); 308 sigaddset(&mask, SIGCHLD); 309 310 #define SIGNAL(s, handler) { \ 311 sa.sa_handler = handler; \ 312 if (sigaction(s, &sa, NULL) < 0) { \ 313 syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ 314 die(1); \ 315 } \ 316 } 317 318 sa.sa_mask = mask; 319 sa.sa_flags = 0; 320 SIGNAL(SIGHUP, hup); /* Hangup */ 321 SIGNAL(SIGINT, term); /* Interrupt */ 322 SIGNAL(SIGTERM, term); /* Terminate */ 323 SIGNAL(SIGCHLD, chld); 324 325 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ 326 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ 327 328 /* 329 * Install a handler for other signals which would otherwise 330 * cause pppd to exit without cleaning up. 331 */ 332 SIGNAL(SIGABRT, bad_signal); 333 SIGNAL(SIGALRM, bad_signal); 334 SIGNAL(SIGFPE, bad_signal); 335 SIGNAL(SIGILL, bad_signal); 336 SIGNAL(SIGPIPE, bad_signal); 337 SIGNAL(SIGQUIT, bad_signal); 338 #if SIGSEGV_CHECK 339 SIGNAL(SIGSEGV, bad_signal); 340 #endif 341 #ifdef SIGBUS 342 SIGNAL(SIGBUS, bad_signal); 343 #endif 344 #ifdef SIGEMT 345 SIGNAL(SIGEMT, bad_signal); 346 #endif 347 #ifdef SIGPOLL 348 SIGNAL(SIGPOLL, bad_signal); 349 #endif 350 #ifdef SIGPROF 351 SIGNAL(SIGPROF, bad_signal); 352 #endif 353 #ifdef SIGSYS 354 SIGNAL(SIGSYS, bad_signal); 355 #endif 356 #ifdef SIGTRAP 357 SIGNAL(SIGTRAP, bad_signal); 358 #endif 359 #ifdef SIGVTALRM 360 SIGNAL(SIGVTALRM, bad_signal); 361 #endif 362 #ifdef SIGXCPU 363 SIGNAL(SIGXCPU, bad_signal); 364 #endif 365 #ifdef SIGXFSZ 366 SIGNAL(SIGXFSZ, bad_signal); 367 #endif 368 369 /* 370 * Apparently we can get a SIGPIPE when we call syslog, if 371 * syslogd has died and been restarted. Ignoring it seems 372 * be sufficient. 373 */ 374 signal(SIGPIPE, SIG_IGN); 375 376 /* 377 * If we're doing dial-on-demand, set up the interface now. 378 */ 379 if (demand) { 380 /* 381 * Open the loopback channel and set it up to be the ppp interface. 382 */ 383 open_ppp_loopback(); 384 385 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 386 (void) snprintf(ifname, sizeof ifname, "ppp%d", ifunit); 387 script_setenv("IFNAME", ifname); 388 389 /* 390 * Configure the interface and mark it up, etc. 391 */ 392 demand_conf(); 393 } 394 395 for (;;) { 396 397 need_holdoff = 1; 398 399 if (demand) { 400 /* 401 * Don't do anything until we see some activity. 402 */ 403 phase = PHASE_DORMANT; 404 kill_link = 0; 405 demand_unblock(); 406 for (;;) { 407 wait_loop_output(timeleft(&timo)); 408 calltimeout(); 409 if (kill_link) { 410 if (!persist) 411 die(0); 412 kill_link = 0; 413 } 414 if (get_loop_output()) 415 break; 416 reap_kids(); 417 } 418 419 /* 420 * Now we want to bring up the link. 421 */ 422 demand_drop(); 423 syslog(LOG_INFO, "Starting link"); 424 } 425 426 /* 427 * Lock the device if we've been asked to. 428 */ 429 if (lockflag && !default_device) { 430 if (lock(devnam) < 0) 431 goto fail; 432 locked = 1; 433 } 434 435 /* 436 * Open the serial device and set it up to be the ppp interface. 437 * First we open it in non-blocking mode so we can set the 438 * various termios flags appropriately. If we aren't dialling 439 * out and we want to use the modem lines, we reopen it later 440 * in order to wait for the carrier detect signal from the modem. 441 */ 442 while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0)) < 0) { 443 if (errno != EINTR) 444 syslog(LOG_ERR, "Failed to open %s: %m", devnam); 445 if (!persist || errno != EINTR) 446 goto fail; 447 } 448 if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 449 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 450 syslog(LOG_WARNING, 451 "Couldn't reset non-blocking mode on device: %m"); 452 453 hungup = 0; 454 kill_link = 0; 455 456 /* 457 * Do the equivalent of `mesg n' to stop broadcast messages. 458 */ 459 if (fstat(ttyfd, &statbuf) < 0 460 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { 461 syslog(LOG_WARNING, 462 "Couldn't restrict write permissions to %s: %m", devnam); 463 } else 464 tty_mode = statbuf.st_mode; 465 466 /* run connection script */ 467 if (connector && connector[0]) { 468 MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); 469 470 /* 471 * Set line speed, flow control, etc. 472 * On most systems we set CLOCAL for now so that we can talk 473 * to the modem before carrier comes up. But this has the 474 * side effect that we might miss it if CD drops before we 475 * get to clear CLOCAL below. On systems where we can talk 476 * successfully to the modem with CLOCAL clear and CD down, 477 * we can clear CLOCAL at this point. 478 */ 479 set_up_tty(ttyfd, (modem_chat == 0)); 480 481 /* drop dtr to hang up in case modem is off hook */ 482 if (!default_device && modem) { 483 setdtr(ttyfd, FALSE); 484 sleep(1); 485 setdtr(ttyfd, TRUE); 486 } 487 488 if (device_script(connector, ttyfd, ttyfd) < 0) { 489 syslog(LOG_ERR, "Connect script failed"); 490 setdtr(ttyfd, FALSE); 491 goto fail; 492 } 493 494 syslog(LOG_INFO, "Serial connection established."); 495 sleep(1); /* give it time to set up its terminal */ 496 } 497 498 set_up_tty(ttyfd, 0); 499 500 /* reopen tty if necessary to wait for carrier */ 501 if (connector == NULL && modem) { 502 while ((i = open(devnam, O_RDWR)) < 0) { 503 if (errno != EINTR) 504 syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); 505 if (!persist || errno != EINTR || hungup || kill_link) 506 goto fail; 507 } 508 close(i); 509 } 510 511 /* run welcome script, if any */ 512 if (welcomer && welcomer[0]) { 513 if (device_script(welcomer, ttyfd, ttyfd) < 0) 514 syslog(LOG_WARNING, "Welcome script failed"); 515 } 516 517 /* set up the serial device as a ppp interface */ 518 establish_ppp(ttyfd); 519 520 if (!demand) { 521 522 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 523 (void) snprintf(ifname, sizeof ifname, "ppp%d", ifunit); 524 script_setenv("IFNAME", ifname); 525 } 526 527 /* 528 * Start opening the connection and wait for 529 * incoming events (reply, timeout, etc.). 530 */ 531 syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); 532 lcp_lowerup(0); 533 lcp_open(0); /* Start protocol */ 534 for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { 535 wait_input(timeleft(&timo)); 536 calltimeout(); 537 get_input(); 538 if (kill_link) { 539 lcp_close(0, "User request"); 540 kill_link = 0; 541 } 542 if (open_ccp_flag) { 543 if (phase == PHASE_NETWORK) { 544 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ 545 (*ccp_protent.open)(0); 546 } 547 open_ccp_flag = 0; 548 } 549 reap_kids(); /* Don't leave dead kids lying around */ 550 } 551 552 /* 553 * If we may want to bring the link up again, transfer 554 * the ppp unit back to the loopback. Set the 555 * real serial device back to its normal mode of operation. 556 */ 557 clean_check(); 558 if (demand) 559 restore_loop(); 560 disestablish_ppp(ttyfd); 561 562 /* 563 * Run disconnector script, if requested. 564 * XXX we may not be able to do this if the line has hung up! 565 */ 566 if (disconnector && !hungup) { 567 set_up_tty(ttyfd, 1); 568 if (device_script(disconnector, ttyfd, ttyfd) < 0) { 569 syslog(LOG_WARNING, "disconnect script failed"); 570 } else { 571 syslog(LOG_INFO, "Serial link disconnected."); 572 } 573 } 574 575 fail: 576 if (ttyfd >= 0) 577 close_tty(); 578 if (locked) { 579 unlock(); 580 locked = 0; 581 } 582 583 if (!persist) 584 die(1); 585 586 if (holdoff > 0 && need_holdoff) { 587 phase = PHASE_HOLDOFF; 588 TIMEOUT(holdoff_end, NULL, holdoff); 589 do { 590 wait_time(timeleft(&timo)); 591 calltimeout(); 592 if (kill_link) { 593 if (!persist) 594 die(0); 595 kill_link = 0; 596 phase = PHASE_DORMANT; /* allow signal to end holdoff */ 597 } 598 reap_kids(); 599 } while (phase == PHASE_HOLDOFF); 600 } 601 } 602 603 die(0); 604 return 0; 605 } 606 607 /* 608 * detach - detach us from the controlling terminal. 609 */ 610 void 611 detach() 612 { 613 if (detached) 614 return; 615 if (daemon(0, 0) < 0) { 616 perror("Couldn't detach from controlling terminal"); 617 die(1); 618 } 619 detached = 1; 620 pid = getpid(); 621 } 622 623 /* 624 * holdoff_end - called via a timeout when the holdoff period ends. 625 */ 626 static void 627 holdoff_end(arg) 628 void *arg; 629 { 630 phase = PHASE_DORMANT; 631 } 632 633 /* 634 * get_input - called when incoming data is available. 635 */ 636 static void 637 get_input() 638 { 639 int len, i; 640 u_char *p; 641 u_short protocol; 642 struct protent *protp; 643 644 p = inpacket_buf; /* point to beginning of packet buffer */ 645 646 len = read_packet(inpacket_buf); 647 if (len < 0) 648 return; 649 650 if (len == 0) { 651 syslog(LOG_NOTICE, "Modem hangup"); 652 hungup = 1; 653 lcp_lowerdown(0); /* serial link is no longer available */ 654 link_terminated(0); 655 return; 656 } 657 658 if (debug /*&& (debugflags & DBG_INPACKET)*/) 659 log_packet(p, len, "rcvd ", LOG_DEBUG); 660 661 if (len < PPP_HDRLEN) { 662 MAINDEBUG((LOG_INFO, "io(): Received short packet.")); 663 return; 664 } 665 666 p += 2; /* Skip address and control */ 667 GETSHORT(protocol, p); 668 len -= PPP_HDRLEN; 669 670 /* 671 * Toss all non-LCP packets unless LCP is OPEN. 672 */ 673 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { 674 MAINDEBUG((LOG_INFO, 675 "get_input: Received non-LCP packet when LCP not open.")); 676 return; 677 } 678 679 /* 680 * Until we get past the authentication phase, toss all packets 681 * except LCP, LQR and authentication packets. 682 */ 683 if (phase <= PHASE_AUTHENTICATE 684 && !(protocol == PPP_LCP || protocol == PPP_LQR 685 || protocol == PPP_PAP || protocol == PPP_CHAP)) { 686 MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d", 687 protocol, phase)); 688 return; 689 } 690 691 /* 692 * Upcall the proper protocol input routine. 693 */ 694 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 695 if (protp->protocol == protocol && protp->enabled_flag) { 696 (*protp->input)(0, p, len); 697 return; 698 } 699 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag 700 && protp->datainput != NULL) { 701 (*protp->datainput)(0, p, len); 702 return; 703 } 704 } 705 706 if (debug) 707 syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); 708 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); 709 } 710 711 712 /* 713 * quit - Clean up state and exit (with an error indication). 714 */ 715 void 716 quit() 717 { 718 die(1); 719 } 720 721 /* 722 * die - like quit, except we can specify an exit status. 723 */ 724 void 725 die(status) 726 int status; 727 { 728 struct syslog_data sdata = SYSLOG_DATA_INIT; 729 730 cleanup(); 731 syslog_r(LOG_INFO, &sdata, "Exit."); 732 _exit(status); 733 } 734 735 /* 736 * cleanup - restore anything which needs to be restored before we exit 737 */ 738 /* ARGSUSED */ 739 static void 740 cleanup() 741 { 742 sys_cleanup(); 743 744 if (ttyfd >= 0) 745 close_tty(); 746 747 if (locked) 748 unlock(); 749 } 750 751 /* 752 * close_tty - restore the terminal device and close it. 753 */ 754 static void 755 close_tty() 756 { 757 disestablish_ppp(ttyfd); 758 759 /* drop dtr to hang up */ 760 if (modem) { 761 setdtr(ttyfd, FALSE); 762 /* 763 * This sleep is in case the serial port has CLOCAL set by default, 764 * and consequently will reassert DTR when we close the device. 765 */ 766 sleep(1); 767 } 768 769 restore_tty(ttyfd); 770 771 if (tty_mode != (mode_t) -1) 772 fchmod(ttyfd, tty_mode); 773 774 close(ttyfd); 775 ttyfd = -1; 776 } 777 778 779 struct callout { 780 struct timeval c_time; /* time at which to call routine */ 781 void *c_arg; /* argument to routine */ 782 void (*c_func)(void *); /* routine */ 783 struct callout *c_next; 784 }; 785 786 static struct callout *callout = NULL; /* Callout list */ 787 static struct timeval timenow; /* Current time */ 788 789 /* 790 * timeout - Schedule a timeout. 791 * 792 * Note that this timeout takes the number of seconds, NOT hz (as in 793 * the kernel). 794 */ 795 void 796 timeout(func, arg, time) 797 void (*func)(void *); 798 void *arg; 799 int time; 800 { 801 struct callout *newp, *p, **pp; 802 803 MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", 804 (long) func, (long) arg, time)); 805 806 /* 807 * Allocate timeout. 808 */ 809 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { 810 syslog(LOG_ERR, "Out of memory in timeout()!"); 811 die(1); 812 } 813 newp->c_arg = arg; 814 newp->c_func = func; 815 gettimeofday(&timenow, NULL); 816 newp->c_time.tv_sec = timenow.tv_sec + time; 817 newp->c_time.tv_usec = timenow.tv_usec; 818 819 /* 820 * Find correct place and link it in. 821 */ 822 for (pp = &callout; (p = *pp); pp = &p->c_next) 823 if (newp->c_time.tv_sec < p->c_time.tv_sec 824 || (newp->c_time.tv_sec == p->c_time.tv_sec 825 && newp->c_time.tv_usec < p->c_time.tv_sec)) 826 break; 827 newp->c_next = p; 828 *pp = newp; 829 } 830 831 832 /* 833 * untimeout - Unschedule a timeout. 834 */ 835 void 836 untimeout(func, arg) 837 void (*func)(void *); 838 void *arg; 839 { 840 struct callout **copp, *freep; 841 842 MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); 843 844 /* 845 * Find first matching timeout and remove it from the list. 846 */ 847 for (copp = &callout; (freep = *copp); copp = &freep->c_next) 848 if (freep->c_func == func && freep->c_arg == arg) { 849 *copp = freep->c_next; 850 (void) free((char *) freep); 851 break; 852 } 853 } 854 855 856 /* 857 * calltimeout - Call any timeout routines which are now due. 858 */ 859 static void 860 calltimeout() 861 { 862 struct callout *p; 863 864 while (callout != NULL) { 865 p = callout; 866 867 if (gettimeofday(&timenow, NULL) < 0) { 868 syslog(LOG_ERR, "Failed to get time of day: %m"); 869 die(1); 870 } 871 if (!(p->c_time.tv_sec < timenow.tv_sec 872 || (p->c_time.tv_sec == timenow.tv_sec 873 && p->c_time.tv_usec <= timenow.tv_usec))) 874 break; /* no, it's not time yet */ 875 876 callout = p->c_next; 877 (*p->c_func)(p->c_arg); 878 879 free((char *) p); 880 } 881 } 882 883 884 /* 885 * timeleft - return the length of time until the next timeout is due. 886 */ 887 static struct timeval * 888 timeleft(tvp) 889 struct timeval *tvp; 890 { 891 if (callout == NULL) 892 return NULL; 893 894 gettimeofday(&timenow, NULL); 895 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; 896 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; 897 if (tvp->tv_usec < 0) { 898 tvp->tv_usec += 1000000; 899 tvp->tv_sec -= 1; 900 } 901 if (tvp->tv_sec < 0) 902 tvp->tv_sec = tvp->tv_usec = 0; 903 904 return tvp; 905 } 906 907 908 /* 909 * kill_my_pg - send a signal to our process group, and ignore it ourselves. 910 */ 911 static void 912 kill_my_pg(sig) 913 int sig; 914 { 915 struct sigaction act, oldact; 916 917 act.sa_handler = SIG_IGN; 918 act.sa_flags = 0; 919 kill(0, sig); 920 sigaction(sig, &act, &oldact); 921 sigaction(sig, &oldact, NULL); 922 } 923 924 925 /* 926 * hup - Catch SIGHUP signal. 927 * 928 * Indicates that the physical layer has been disconnected. 929 * We don't rely on this indication; if the user has sent this 930 * signal, we just take the link down. 931 */ 932 static void 933 hup(sig) 934 int sig; 935 { 936 int save_errno = errno; 937 struct syslog_data sdata = SYSLOG_DATA_INIT; 938 939 if (crashed) 940 _exit(127); 941 syslog_r(LOG_INFO, &sdata, "Hangup (SIGHUP)"); 942 kill_link = 1; 943 if (conn_running) 944 /* Send the signal to the [dis]connector process(es) also */ 945 kill_my_pg(sig); 946 errno = save_errno; 947 } 948 949 950 /* 951 * term - Catch SIGTERM signal and SIGINT signal (^C/del). 952 * 953 * Indicates that we should initiate a graceful disconnect and exit. 954 */ 955 /*ARGSUSED*/ 956 static void 957 term(sig) 958 int sig; 959 { 960 int save_errno = errno; 961 struct syslog_data sdata = SYSLOG_DATA_INIT; 962 963 if (crashed) 964 _exit(127); 965 syslog_r(LOG_INFO, &sdata, "Terminating on signal %d.", sig); 966 persist = 0; /* don't try to restart */ 967 kill_link = 1; 968 if (conn_running) 969 /* Send the signal to the [dis]connector process(es) also */ 970 kill_my_pg(sig); 971 errno = save_errno; 972 } 973 974 975 /* 976 * chld - Catch SIGCHLD signal. 977 * Calls reap_kids to get status for any dead kids. 978 */ 979 static void 980 chld(sig) 981 int sig; 982 { 983 int save_errno = errno; 984 985 reap_kids(); /* XXX somewhat unsafe */ 986 errno = save_errno; 987 } 988 989 990 /* 991 * toggle_debug - Catch SIGUSR1 signal. 992 * 993 * Toggle debug flag. 994 */ 995 /*ARGSUSED*/ 996 static void 997 toggle_debug(sig) 998 int sig; 999 { 1000 debug = !debug; 1001 if (debug) { 1002 setlogmask(LOG_UPTO(LOG_DEBUG)); /* XXX safe, but wrong */ 1003 } else { 1004 setlogmask(LOG_UPTO(LOG_WARNING)); /* XXX safe, but wrong */ 1005 } 1006 } 1007 1008 1009 /* 1010 * open_ccp - Catch SIGUSR2 signal. 1011 * 1012 * Try to (re)negotiate compression. 1013 */ 1014 /*ARGSUSED*/ 1015 static void 1016 open_ccp(sig) 1017 int sig; 1018 { 1019 open_ccp_flag = 1; 1020 } 1021 1022 1023 /* 1024 * bad_signal - We've caught a fatal signal. Clean up state and exit. 1025 */ 1026 static void 1027 bad_signal(sig) 1028 int sig; 1029 { 1030 struct syslog_data sdata = SYSLOG_DATA_INIT; 1031 1032 if (crashed) 1033 _exit(127); 1034 crashed = 1; 1035 syslog_r(LOG_ERR, &sdata, "Fatal signal %d", sig); 1036 if (conn_running) 1037 kill_my_pg(SIGTERM); 1038 die(1); /* XXX unsafe! */ 1039 } 1040 1041 1042 /* 1043 * device_script - run a program to connect or disconnect the 1044 * serial device. 1045 */ 1046 static int 1047 device_script(program, in, out) 1048 char *program; 1049 int in, out; 1050 { 1051 pid_t pid; 1052 int status; 1053 int errfd; 1054 gid_t gid; 1055 uid_t uid; 1056 1057 conn_running = 1; 1058 pid = fork(); 1059 1060 if (pid < 0) { 1061 conn_running = 0; 1062 syslog(LOG_ERR, "Failed to create child process: %m"); 1063 die(1); 1064 } 1065 1066 if (pid == 0) { 1067 sys_close(); 1068 closelog(); 1069 if (in == out) { 1070 if (in != 0) { 1071 dup2(in, 0); 1072 close(in); 1073 } 1074 dup2(0, 1); 1075 } else { 1076 if (out == 0) 1077 out = dup(out); 1078 if (in != 0) { 1079 dup2(in, 0); 1080 close(in); 1081 } 1082 if (out != 1) { 1083 dup2(out, 1); 1084 close(out); 1085 } 1086 } 1087 if (nodetach == 0) { 1088 close(2); 1089 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); 1090 if (errfd >= 0 && errfd != 2) { 1091 dup2(errfd, 2); 1092 close(errfd); 1093 } 1094 } 1095 1096 /* revoke privs */ 1097 gid = getgid(); 1098 uid = getuid(); 1099 if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) { 1100 syslog(LOG_ERR, "revoke privileges: %s", strerror(errno)); 1101 _exit(1); 1102 } 1103 1104 execl("/bin/sh", "sh", "-c", program, (char *)NULL); 1105 syslog(LOG_ERR, "could not exec /bin/sh: %m"); 1106 _exit(99); 1107 /* NOTREACHED */ 1108 } 1109 1110 while (waitpid(pid, &status, 0) < 0) { 1111 if (errno == EINTR) 1112 continue; 1113 syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); 1114 die(1); 1115 } 1116 conn_running = 0; 1117 1118 return (status == 0 ? 0 : -1); 1119 } 1120 1121 1122 /* 1123 * run-program - execute a program with given arguments, 1124 * but don't wait for it. 1125 * If the program can't be executed, logs an error unless 1126 * must_exist is 0 and the program file doesn't exist. 1127 */ 1128 int 1129 run_program(prog, args, must_exist) 1130 char *prog; 1131 char **args; 1132 int must_exist; 1133 { 1134 pid_t pid; 1135 uid_t uid; 1136 gid_t gid; 1137 1138 pid = fork(); 1139 if (pid == -1) { 1140 syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); 1141 return -1; 1142 } 1143 if (pid == 0) { 1144 int new_fd; 1145 1146 /* Leave the current location */ 1147 (void) setsid(); /* No controlling tty. */ 1148 (void) umask (S_IRWXG|S_IRWXO); 1149 (void) chdir ("/"); /* no current directory. */ 1150 1151 /* revoke privs */ 1152 uid = getuid(); 1153 gid = getgid(); 1154 if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) { 1155 syslog(LOG_ERR, "revoke privileges: %s", strerror(errno)); 1156 _exit(1); 1157 } 1158 1159 /* Ensure that nothing of our device environment is inherited. */ 1160 sys_close(); 1161 closelog(); 1162 close (0); 1163 close (1); 1164 close (2); 1165 close (ttyfd); /* tty interface to the ppp device */ 1166 1167 /* Don't pass handles to the PPP device, even by accident. */ 1168 new_fd = open (_PATH_DEVNULL, O_RDWR); 1169 if (new_fd >= 0) { 1170 if (new_fd != 0) { 1171 dup2 (new_fd, 0); /* stdin <- /dev/null */ 1172 close (new_fd); 1173 } 1174 dup2 (0, 1); /* stdout -> /dev/null */ 1175 dup2 (0, 2); /* stderr -> /dev/null */ 1176 } 1177 1178 /* Force the priority back to zero if pppd is running higher. */ 1179 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 1180 syslog (LOG_WARNING, "can't reset priority to 0: %m"); 1181 1182 /* SysV recommends a second fork at this point. */ 1183 1184 /* run the program; give it a null environment */ 1185 execve(prog, args, script_env); 1186 if (must_exist || errno != ENOENT) 1187 syslog(LOG_WARNING, "Can't execute %s: %m", prog); 1188 _exit(1); 1189 } 1190 MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %ld", prog, (long)pid)); 1191 ++n_children; 1192 return 0; 1193 } 1194 1195 1196 /* 1197 * reap_kids - get status from any dead child processes, 1198 * and log a message for abnormal terminations. 1199 */ 1200 static void 1201 reap_kids() 1202 { 1203 int status; 1204 pid_t pid; 1205 1206 if (n_children == 0) 1207 return; 1208 if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { 1209 if (errno != ECHILD) 1210 syslog(LOG_ERR, "Error waiting for child process: %m"); 1211 return; 1212 } 1213 if (pid > 0) { 1214 --n_children; 1215 if (WIFSIGNALED(status)) { 1216 syslog(LOG_WARNING, "Child process %ld terminated with signal %d", 1217 (long)pid, WTERMSIG(status)); 1218 } 1219 } 1220 } 1221 1222 1223 /* 1224 * log_packet - format a packet and log it. 1225 */ 1226 1227 char line[256]; /* line to be logged accumulated here */ 1228 char *linep; 1229 1230 void 1231 log_packet(p, len, prefix, level) 1232 u_char *p; 1233 int len; 1234 char *prefix; 1235 int level; 1236 { 1237 strlcpy(line, prefix, sizeof line); 1238 linep = line + strlen(line); 1239 format_packet(p, len, pr_log, NULL); 1240 if (linep != line) 1241 syslog(level, "%s", line); 1242 } 1243 1244 /* 1245 * format_packet - make a readable representation of a packet, 1246 * calling `printer(arg, format, ...)' to output it. 1247 */ 1248 void 1249 format_packet(p, len, printer, arg) 1250 u_char *p; 1251 int len; 1252 void (*printer)(void *, char *, ...); 1253 void *arg; 1254 { 1255 int i, n; 1256 u_short proto; 1257 u_char x; 1258 struct protent *protp; 1259 1260 if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { 1261 p += 2; 1262 GETSHORT(proto, p); 1263 len -= PPP_HDRLEN; 1264 for (i = 0; (protp = protocols[i]) != NULL; ++i) 1265 if (proto == protp->protocol) 1266 break; 1267 if (protp != NULL) { 1268 printer(arg, "[%s", protp->name); 1269 n = (*protp->printpkt)(p, len, printer, arg); 1270 printer(arg, "]"); 1271 p += n; 1272 len -= n; 1273 } else { 1274 printer(arg, "[proto=0x%x]", proto); 1275 } 1276 } 1277 1278 for (; len > 0; --len) { 1279 GETCHAR(x, p); 1280 printer(arg, " %.2x", x); 1281 } 1282 } 1283 1284 static void 1285 pr_log(void *arg, char *fmt, ...) 1286 { 1287 int n; 1288 va_list pvar; 1289 char buf[256]; 1290 1291 va_start(pvar, fmt); 1292 1293 n = vfmtmsg(buf, sizeof(buf), fmt, pvar); 1294 va_end(pvar); 1295 1296 if (linep + n + 1 > line + sizeof(line)) { 1297 syslog(LOG_DEBUG, "%s", line); 1298 linep = line; 1299 } 1300 strlcpy(linep, buf, line + sizeof line - linep); 1301 linep += n; 1302 } 1303 1304 /* 1305 * print_string - print a readable representation of a string using 1306 * printer. 1307 */ 1308 void 1309 print_string(p, len, printer, arg) 1310 char *p; 1311 int len; 1312 void (*printer)(void *, char *, ...); 1313 void *arg; 1314 { 1315 int c; 1316 1317 printer(arg, "\""); 1318 for (; len > 0; --len) { 1319 c = *p++; 1320 if (' ' <= c && c <= '~') { 1321 if (c == '\\' || c == '"') 1322 printer(arg, "\\"); 1323 printer(arg, "%c", c); 1324 } else { 1325 switch (c) { 1326 case '\n': 1327 printer(arg, "\\n"); 1328 break; 1329 case '\r': 1330 printer(arg, "\\r"); 1331 break; 1332 case '\t': 1333 printer(arg, "\\t"); 1334 break; 1335 default: 1336 printer(arg, "\\%.3o", c); 1337 } 1338 } 1339 } 1340 printer(arg, "\""); 1341 } 1342 1343 /* 1344 * novm - log an error message saying we ran out of memory, and die. 1345 */ 1346 void 1347 novm(msg) 1348 char *msg; 1349 { 1350 syslog(LOG_ERR, "Virtual memory exhausted allocating %s", msg); 1351 die(1); 1352 } 1353 1354 /* 1355 * fmtmsg - format a message into a buffer. Like snprintf except we 1356 * also specify the length of the output buffer, and we handle 1357 * %m (error message) and %I (IP address) formats. 1358 * Doesn't do floating-point formats. 1359 * Returns the number of chars put into buf. 1360 */ 1361 int 1362 fmtmsg(char *buf, int buflen, char *fmt, ...) 1363 { 1364 va_list args; 1365 int n; 1366 1367 va_start(args, fmt); 1368 n = vfmtmsg(buf, buflen, fmt, args); 1369 va_end(args); 1370 return n; 1371 } 1372 1373 /* 1374 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. 1375 */ 1376 #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) 1377 1378 int 1379 vfmtmsg(buf, buflen, fmt, args) 1380 char *buf; 1381 int buflen; 1382 char *fmt; 1383 va_list args; 1384 { 1385 int c, i, n; 1386 int width, prec, fillch; 1387 int base, len, neg, quoted; 1388 unsigned long val = 0; 1389 char *str, *f, *buf0; 1390 unsigned char *p; 1391 char num[32]; 1392 time_t t; 1393 static char hexchars[] = "0123456789abcdef"; 1394 1395 buf0 = buf; 1396 --buflen; 1397 while (buflen > 0) { 1398 for (f = fmt; *f != '%' && *f != 0; ++f) 1399 ; 1400 if (f > fmt) { 1401 len = f - fmt; 1402 if (len > buflen) 1403 len = buflen; 1404 memcpy(buf, fmt, len); 1405 buf += len; 1406 buflen -= len; 1407 fmt = f; 1408 } 1409 if (*fmt == 0) 1410 break; 1411 c = *++fmt; 1412 width = prec = 0; 1413 fillch = ' '; 1414 if (c == '0') { 1415 fillch = '0'; 1416 c = *++fmt; 1417 } 1418 if (c == '*') { 1419 width = va_arg(args, int); 1420 c = *++fmt; 1421 } else { 1422 while (isdigit(c)) { 1423 width = width * 10 + c - '0'; 1424 c = *++fmt; 1425 } 1426 } 1427 if (c == '.') { 1428 c = *++fmt; 1429 if (c == '*') { 1430 prec = va_arg(args, int); 1431 c = *++fmt; 1432 } else { 1433 while (isdigit(c)) { 1434 prec = prec * 10 + c - '0'; 1435 c = *++fmt; 1436 } 1437 } 1438 } 1439 str = 0; 1440 base = 0; 1441 neg = 0; 1442 ++fmt; 1443 switch (c) { 1444 case 'd': 1445 i = va_arg(args, int); 1446 if (i < 0) { 1447 neg = 1; 1448 val = -i; 1449 } else 1450 val = i; 1451 base = 10; 1452 break; 1453 case 'o': 1454 val = va_arg(args, unsigned int); 1455 base = 8; 1456 break; 1457 case 'x': 1458 val = va_arg(args, unsigned int); 1459 base = 16; 1460 break; 1461 case 'p': 1462 val = (unsigned long) va_arg(args, void *); 1463 base = 16; 1464 neg = 2; 1465 break; 1466 case 's': 1467 str = va_arg(args, char *); 1468 break; 1469 case 'c': 1470 num[0] = va_arg(args, int); 1471 num[1] = 0; 1472 str = num; 1473 break; 1474 case 'm': 1475 str = strerror(errno); 1476 break; 1477 case 'I': 1478 str = ip_ntoa(va_arg(args, u_int32_t)); 1479 break; 1480 case 't': 1481 time(&t); 1482 str = ctime(&t); 1483 str += 4; /* chop off the day name */ 1484 str[15] = 0; /* chop off year and newline */ 1485 break; 1486 case 'v': /* "visible" string */ 1487 case 'q': /* quoted string */ 1488 quoted = c == 'q'; 1489 p = va_arg(args, unsigned char *); 1490 if (fillch == '0' && prec > 0) { 1491 n = prec; 1492 } else { 1493 n = strlen((char *)p); 1494 if (prec > 0 && prec < n) 1495 n = prec; 1496 } 1497 while (n > 0 && buflen > 0) { 1498 c = *p++; 1499 --n; 1500 if (!quoted && c >= 0x80) { 1501 OUTCHAR('M'); 1502 OUTCHAR('-'); 1503 c -= 0x80; 1504 } 1505 if (quoted && (c == '"' || c == '\\')) 1506 OUTCHAR('\\'); 1507 if (c < 0x20 || (0x7f <= c && c < 0xa0)) { 1508 if (quoted) { 1509 OUTCHAR('\\'); 1510 switch (c) { 1511 case '\t': OUTCHAR('t'); break; 1512 case '\n': OUTCHAR('n'); break; 1513 case '\b': OUTCHAR('b'); break; 1514 case '\f': OUTCHAR('f'); break; 1515 default: 1516 OUTCHAR('x'); 1517 OUTCHAR(hexchars[c >> 4]); 1518 OUTCHAR(hexchars[c & 0xf]); 1519 } 1520 } else { 1521 if (c == '\t') 1522 OUTCHAR(c); 1523 else { 1524 OUTCHAR('^'); 1525 OUTCHAR(c ^ 0x40); 1526 } 1527 } 1528 } else 1529 OUTCHAR(c); 1530 } 1531 continue; 1532 default: 1533 *buf++ = '%'; 1534 if (c != '%') 1535 --fmt; /* so %z outputs %z etc. */ 1536 --buflen; 1537 continue; 1538 } 1539 if (base != 0) { 1540 str = num + sizeof(num); 1541 *--str = 0; 1542 while (str > num + neg) { 1543 *--str = hexchars[val % base]; 1544 val = val / base; 1545 if (--prec <= 0 && val == 0) 1546 break; 1547 } 1548 switch (neg) { 1549 case 1: 1550 *--str = '-'; 1551 break; 1552 case 2: 1553 *--str = 'x'; 1554 *--str = '0'; 1555 break; 1556 } 1557 len = num + sizeof(num) - 1 - str; 1558 } else { 1559 len = strlen(str); 1560 if (prec > 0 && len > prec) 1561 len = prec; 1562 } 1563 if (width > 0) { 1564 if (width > buflen) 1565 width = buflen; 1566 if ((n = width - len) > 0) { 1567 buflen -= n; 1568 for (; n > 0; --n) 1569 *buf++ = fillch; 1570 } 1571 } 1572 if (len > buflen) 1573 len = buflen; 1574 memcpy(buf, str, len); 1575 buf += len; 1576 buflen -= len; 1577 } 1578 *buf = 0; 1579 return buf - buf0; 1580 } 1581 1582 /* 1583 * script_setenv - set an environment variable value to be used 1584 * for scripts that we run (e.g. ip-up, auth-up, etc.) 1585 */ 1586 void 1587 script_setenv(var, value) 1588 char *var, *value; 1589 { 1590 int vl = strlen(var); 1591 int i; 1592 char *p, *newstring; 1593 1594 if (asprintf(&newstring, "%s=%s", var, value) == -1) 1595 novm("script_setenv"); 1596 1597 /* check if this variable is already set */ 1598 if (script_env != 0) { 1599 for (i = 0; (p = script_env[i]) != 0; ++i) { 1600 if (strncmp(p, var, vl) == 0 && p[vl] == '=') { 1601 free(p); 1602 script_env[i] = newstring; 1603 return; 1604 } 1605 } 1606 } else { 1607 i = 0; 1608 script_env = (char **) calloc(16, sizeof(char *)); 1609 if (script_env == 0) 1610 novm("script_setenv"); 1611 s_env_nalloc = 16; 1612 } 1613 1614 /* reallocate script_env with more space if needed */ 1615 if (i + 1 >= s_env_nalloc) { 1616 int new_n = i + 17; 1617 char **newenv = reallocarray(script_env, 1618 new_n, sizeof(char *)); 1619 if (newenv == 0) 1620 novm("script_setenv"); 1621 script_env = newenv; 1622 s_env_nalloc = new_n; 1623 } 1624 1625 script_env[i] = newstring; 1626 script_env[i+1] = 0; 1627 } 1628