📄 main.old.c
字号:
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. */static voidsetup_signals(){ struct sigaction sa; sigset_t mask; /* * Compute mask of all interesting signals and install signal handlers * for each. Only one signal handler may be active at a time. Therefore, * all other signals should be masked when any handler is executing. */ sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); sigaddset(&mask, SIGUSR2);#define SIGNAL(s, handler) do { \ sa.sa_handler = handler; \ if (sigaction(s, &sa, NULL) < 0) \ fatal("Couldn't establish signal handler (%d): %m", s); \ } while (0) sa.sa_mask = mask; sa.sa_flags = 0; SIGNAL(SIGHUP, hup); /* Hangup */ SIGNAL(SIGINT, term); /* Interrupt */ SIGNAL(SIGTERM, term); /* Terminate */ SIGNAL(SIGCHLD, chld); SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ /* * Install a handler for other signals which would otherwise * cause pppd to exit without cleaning up. */ SIGNAL(SIGABRT, bad_signal); SIGNAL(SIGALRM, bad_signal); SIGNAL(SIGFPE, bad_signal); SIGNAL(SIGILL, bad_signal); SIGNAL(SIGPIPE, bad_signal); SIGNAL(SIGQUIT, bad_signal); SIGNAL(SIGSEGV, bad_signal);#ifdef SIGBUS SIGNAL(SIGBUS, bad_signal);#endif#ifdef SIGEMT SIGNAL(SIGEMT, bad_signal);#endif#ifdef SIGPOLL SIGNAL(SIGPOLL, bad_signal);#endif#ifdef SIGPROF SIGNAL(SIGPROF, bad_signal);#endif#ifdef SIGSYS SIGNAL(SIGSYS, bad_signal);#endif#ifdef SIGTRAP SIGNAL(SIGTRAP, bad_signal);#endif#ifdef SIGVTALRM SIGNAL(SIGVTALRM, bad_signal);#endif#ifdef SIGXCPU SIGNAL(SIGXCPU, bad_signal);#endif#ifdef SIGXFSZ SIGNAL(SIGXFSZ, bad_signal);#endif /* * Apparently we can get a SIGPIPE when we call syslog, if * syslogd has died and been restarted. Ignoring it seems * be sufficient. */ signal(SIGPIPE, SIG_IGN);}/* * set_ifunit - do things we need to do once we know which ppp * unit we are using. */voidset_ifunit(iskey) int iskey;{ info("Using interface %s%d", PPP_DRV_NAME, ifunit); slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); script_setenv("IFNAME", ifname, iskey); if (iskey) { create_pidfile(); /* write pid to file */ create_linkpidfile(); }}/* * detach - detach us from the controlling terminal. */voiddetach(){ int pid; char numbuf[16]; if (detached) return; if ((pid = fork()) < 0) { error("Couldn't detach (fork failed: %m)"); die(1); /* or just return? */ } if (pid != 0) { /* parent */ notify(pidchange, pid); exit(0); /* parent dies */ } setsid(); chdir("/"); close(0); close(1); close(2); detached = 1; if (log_default) log_to_fd = -1; /* update pid files if they have been written already */ if (pidfilename[0]) create_pidfile(); if (linkpidfile[0]) create_linkpidfile(); slprintf(numbuf, sizeof(numbuf), "%d", getpid()); script_setenv("PPPD_PID", numbuf, 1);}/* * reopen_log - (re)open our connection to syslog. */voidreopen_log(){#ifdef ULTRIX openlog("pppd", LOG_PID);#else openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO));#endif}/* * Create a file containing our process ID. */static voidcreate_pidfile(){ FILE *pidfile; slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", _PATH_VARRUN, ifname); if ((pidfile = fopen(pidfilename, "w")) != NULL) { fprintf(pidfile, "%d\n", getpid()); (void) fclose(pidfile); } else { error("Failed to create pid file %s: %m", pidfilename); pidfilename[0] = 0; }}static voidcreate_linkpidfile(){ FILE *pidfile; if (linkname[0] == 0) return; script_setenv("LINKNAME", linkname, 1); slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", _PATH_VARRUN, linkname); if ((pidfile = fopen(linkpidfile, "w")) != NULL) { fprintf(pidfile, "%d\n", getpid()); if (ifname[0]) fprintf(pidfile, "%s\n", ifname); (void) fclose(pidfile); } else { error("Failed to create pid file %s: %m", linkpidfile); linkpidfile[0] = 0; }}/* * holdoff_end - called via a timeout when the holdoff period ends. */static voidholdoff_end(arg) void *arg;{ new_phase(PHASE_DORMANT);}/* List of protocol names, to make our messages a little more informative. */struct protocol_list { u_short proto; const char *name;} protocol_list[] = { { 0x21, "IP" }, { 0x23, "OSI Network Layer" }, { 0x25, "Xerox NS IDP" }, { 0x27, "DECnet Phase IV" }, { 0x29, "Appletalk" }, { 0x2b, "Novell IPX" }, { 0x2d, "VJ compressed TCP/IP" }, { 0x2f, "VJ uncompressed TCP/IP" }, { 0x31, "Bridging PDU" }, { 0x33, "Stream Protocol ST-II" }, { 0x35, "Banyan Vines" }, { 0x39, "AppleTalk EDDP" }, { 0x3b, "AppleTalk SmartBuffered" }, { 0x3d, "Multi-Link" }, { 0x3f, "NETBIOS Framing" }, { 0x41, "Cisco Systems" }, { 0x43, "Ascom Timeplex" }, { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, { 0x47, "DCA Remote Lan" }, { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, { 0x4b, "SNA over 802.2" }, { 0x4d, "SNA" }, { 0x4f, "IP6 Header Compression" }, { 0x6f, "Stampede Bridging" }, { 0xfb, "single-link compression" }, { 0xfd, "1st choice compression" }, { 0x0201, "802.1d Hello Packets" }, { 0x0203, "IBM Source Routing BPDU" }, { 0x0205, "DEC LANBridge100 Spanning Tree" }, { 0x0231, "Luxcom" }, { 0x0233, "Sigma Network Systems" }, { 0x8021, "Internet Protocol Control Protocol" }, { 0x8023, "OSI Network Layer Control Protocol" }, { 0x8025, "Xerox NS IDP Control Protocol" }, { 0x8027, "DECnet Phase IV Control Protocol" }, { 0x8029, "Appletalk Control Protocol" }, { 0x802b, "Novell IPX Control Protocol" }, { 0x8031, "Bridging NCP" }, { 0x8033, "Stream Protocol Control Protocol" }, { 0x8035, "Banyan Vines Control Protocol" }, { 0x803d, "Multi-Link Control Protocol" }, { 0x803f, "NETBIOS Framing Control Protocol" }, { 0x8041, "Cisco Systems Control Protocol" }, { 0x8043, "Ascom Timeplex" }, { 0x8045, "Fujitsu LBLB Control Protocol" }, { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, { 0x804b, "SNA over 802.2 Control Protocol" }, { 0x804d, "SNA Control Protocol" }, { 0x804f, "IP6 Header Compression Control Protocol" }, { 0x006f, "Stampede Bridging Control Protocol" }, { 0x80fb, "Single Link Compression Control Protocol" }, { 0x80fd, "Compression Control Protocol" }, { 0xc021, "Link Control Protocol" }, { 0xc023, "Password Authentication Protocol" }, { 0xc025, "Link Quality Report" }, { 0xc027, "Shiva Password Authentication Protocol" }, { 0xc029, "CallBack Control Protocol (CBCP)" }, { 0xc081, "Container Control Protocol" }, { 0xc223, "Challenge Handshake Authentication Protocol" }, { 0xc281, "Proprietary Authentication Protocol" }, { 0, NULL },};/* * protocol_name - find a name for a PPP protocol. */const char *protocol_name(proto) int proto;{ struct protocol_list *lp; for (lp = protocol_list; lp->proto != 0; ++lp) if (proto == lp->proto) return lp->name; return NULL;}/* * get_input - called when incoming data is available. */static voidget_input(){ int len, i; u_char *p; u_short protocol; struct protent *protp; p = inpacket_buf; /* point to beginning of packet buffer */ len = read_packet(inpacket_buf); if (len < 0) return; if (len == 0) { notice("Modem hangup"); hungup = 1; status = EXIT_HANGUP; lcp_lowerdown(0); /* serial link is no longer available */ link_terminated(0); return; } if (debug /*&& (debugflags & DBG_INPACKET)*/) dbglog("rcvd %P", p, len); if (len < PPP_HDRLEN) { MAINDEBUG(("io(): Received short packet.")); return; } p += 2; /* Skip address and control */ GETSHORT(protocol, p); len -= PPP_HDRLEN; /* * Toss all non-LCP packets unless LCP is OPEN. */ if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { MAINDEBUG(("get_input: Received non-LCP packet when LCP not open.")); return; } /* * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ if (phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP || protocol == PPP_LQR || protocol == PPP_PAP || protocol == PPP_CHAP)) { MAINDEBUG(("get_input: discarding proto 0x%x in phase %d", protocol, phase)); return; } /* * Upcall the proper protocol input routine. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { (*protp->input)(0, p, len); return; } if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { (*protp->datainput)(0, p, len); return; } } if (debug) { const char *pname = protocol_name(protocol); if (pname != NULL) warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); else warn("Unsupported protocol 0x%x received", protocol); } lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);}/* * new_phase - signal the start of a new phase of pppd's operation. */voidnew_phase(p) int p;{ phase = p; if (new_phase_hook) (*new_phase_hook)(p); notify(phasechange, p);}/* * die - clean up state and exit with the specified status. */voiddie(status) int status;{ cleanup(); notify(exitnotify, status); syslog(LOG_INFO, "Exit."); exit(status);}/* * cleanup - restore anything which needs to be restored before we exit *//* ARGSUSED */static voidcleanup(){ sys_cleanup(); if (fd_ppp >= 0) the_channel->disestablish_ppp(devfd); if (the_channel->cleanup) (*the_channel->cleanup)(); 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) warn("unable to delete pid file %s: %m", linkpidfile); linkpidfile[0] = 0; if (pppdb != NULL) cleanup_db();}/* * update_link_stats - get stats at link termination. */voidupdate_link_stats(u) int u;{ struct timeval now; char numbuf[32]; if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) return; link_connect_time = now.tv_sec - start_time.tv_sec; link_stats_valid = 1; slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time); script_setenv("CONNECT_TIME", numbuf, 0); slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_out); script_setenv("BYTES_SENT", numbuf, 0); slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_in); script_setenv("BYTES_RCVD", numbuf, 0);}struct callout { struct timeval c_time; /* time at which to call routine */ void *c_arg; /* argument to routine */ void (*c_func) __P((void *)); /* routine */ struct callout *c_next;};static struct callout *callout = NULL; /* Callout list */static struct timeval timenow; /* Current time *//* * timeout - Schedule a timeout. * * Note that this timeout takes the number of milliseconds, NOT hz (as in * the kernel). */voidtimeout(func, arg, secs, usecs) void (*func) __P((void *)); void *arg; int secs, usecs;{ struct callout *newp, *p, **pp; MAINDEBUG(("Timeout %p:%p in %d.%03d seconds.", func, arg, time / 1000, time % 1000)); /* * Allocate timeout. */ if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) fatal("Out of memory in timeout()!"); newp->c_arg = arg; newp->c_func = func; gettimeofday(&timenow, NULL); 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. */ for (pp = &callout; (p = *pp); pp = &p->c_next) if (newp->c_time.tv_sec < p->c_time.tv_sec || (newp->c_time.tv_sec == p->c_time.tv_sec && newp->c_time.tv_usec < p->c_time.tv_usec)) break; newp->c_next = p; *pp = newp;}/* * untimeout - Unschedule a timeout. */voiduntimeout(func, arg) void (*func) __P((void *)); void *arg;{ struct callout **copp, *freep; MAINDEBUG(("Untimeout %p:%p.", func, arg)); /* * Find first matching timeout and remove it from the list. */ for (copp = &callout; (freep = *copp); copp = &freep->c_next) if (freep->c_func == func && freep->c_arg == arg) { *copp = freep->c_next; free((char *) freep); break; }}/* * calltimeout - Call any timeout routines which are now due. */static voidcalltimeout(){ struct callout *p; while (callout != NULL) { p = callout; if (gettimeofday(&timenow, NULL) < 0) fatal("Failed to get time of day: %m"); if (!(p->c_time.tv_sec < timenow.tv_sec || (p->c_time.tv_sec == timenow.tv_sec && p->c_time.tv_usec <= timenow.tv_usec))) break; /* no, it's not time yet */ callout = p->c_next; (*p->c_func)(p->c_arg); free((char *) p); }}/* * timeleft - return the length of time until the next timeout is due. */static struct timeval *timeleft(tvp) struct timeval *tvp;{ if (callout == NULL) return NULL; gettimeofday(&timenow, NULL); tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; if (tvp->tv_usec < 0) { tvp->tv_usec += 1000000; tvp->tv_sec -= 1; } if (tvp->tv_sec < 0) tvp->tv_sec = tvp->tv_usec = 0; return tvp;}/* * kill_my_pg - send a signal to our process group, and ignore it ourselves. */static voidkill_my_pg(sig) int sig;{ struct sigaction act, oldact; act.sa_handler = SIG_IGN; act.sa_flags = 0; kill(0, sig); sigaction(sig, &act, &oldact); sigaction(sig, &oldact, NULL);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -