📄 sys-next.c
字号:
* Scan through the system's network interfaces. */ ifc.ifc_len = sizeof(ifs); ifc.ifc_req = ifs; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { warn("ioctl(SIOCGIFCONF): %m"); return mask; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) { /* * Check the interface's internet address. */ if (ifr->ifr_addr.sa_family != AF_INET) continue; ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; if ((ntohl(ina) & nmask) != (addr & nmask)) continue; /* * Check that the interface is up, and not point-to-point or loopback. */ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) != IFF_UP) continue; /* * Get its netmask and OR it into our mask. */ if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) continue; mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; } return mask;}/* * have_route_to - determine if the system has any route to * a given IP address. * For demand mode to work properly, we have to ignore routes * through our own interface. */int have_route_to(u_int32_t addr){ return -1;}#if 0/* * daemon - Detach us from the terminal session. */intdaemon(nochdir, noclose) int nochdir, noclose;{ int pid; if ((pid = fork()) < 0) return -1; if (pid != 0) exit(0); /* parent dies */ (void)setsid(); if (!nochdir) chdir("/"); if (!noclose) { fclose(stdin); /* don't need stdin, stdout, stderr */ fclose(stdout); fclose(stderr); } return 0;}#endifchar *strdup(s) const char *s;{ char *d = malloc(strlen(s) + 1); if (d) strcpy(d, s); return d;}/* * This logwtmp() implementation is subject to the following copyright: * * Copyright (c) 1988 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#define WTMPFILE "/usr/adm/wtmp"voidlogwtmp(line, name, host) const char *line, *name, *host;{ int fd; struct stat buf; struct utmp ut; if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { strncpy(ut.ut_line, line, sizeof(ut.ut_line)); strncpy(ut.ut_name, name, sizeof(ut.ut_name)); strncpy(ut.ut_host, host, sizeof(ut.ut_host)); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); } close(fd);}#if 0/* * Routines for locking and unlocking the serial device, moved here * from chat.c. */#define LOCK_PREFIX "/usr/spool/uucp/LCK/LCK.."static char *lock_file;/* * lock - create a lock file for the named device */intlock(dev) char *dev;{ int fd, pid, n; char *p; size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; l = strlen(LOCK_PREFIX) + strlen(dev) + 1; lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST && (fd = open(lock_file, O_RDONLY, 0)) >= 0) { /* Read the lock file to find out who has the device locked */ n = read(fd, &pid, sizeof(pid)); if (n <= 0) { error("Can't read pid from lock file %s", lock_file); close(fd); } else { if (kill(pid, 0) == -1 && errno == ESRCH) { /* pid no longer exists - remove the lock file */ if (unlink(lock_file) == 0) { close(fd); notice("Removed stale lock on %s (pid %d)", dev, pid); continue; } else warn("Couldn't remove stale lock on %s", dev); } else notice("Device %s is locked by pid %d", dev, pid); } close(fd); } else error("Can't create lock file %s: %m", lock_file); free(lock_file); lock_file = NULL; return -1; } pid = getpid(); write(fd, &pid, sizeof pid); close(fd); return 0;}/* * unlock - remove our lockfile */voidunlock(){ if (lock_file) { unlink(lock_file); free(lock_file); lock_file = NULL; }}#endif#if defined(i386) && defined(HAS_BROKEN_IOCTL)intioctl(fd, cmd, c) int fd, cmd; caddr_t c;{#undef ioctl int ret;#ifdef DEBUGIOCTL int serrno; u_char let, code, size; size = (cmd >> 16) & IOCPARM_MASK; let = (cmd >> 8); code = cmd; if (let == 't' && (75 <= code && code <= 90)) info("ioctl(%d, 0x%x ('%c', %d, %d), 0x%x)\n", fd, cmd, let, code, size, c);#endif ret = ioctl(fd, cmd, c);#ifdef DEBUGIOCTL serrno = errno; if (ret == -1) info("ioctl('%c', %d, %d) errno = %d (%m)\n", let, code, size, errno); if (let == 't' && (75 <= code && code <= 90) && (cmd & IOC_OUT)) { int i, len = ((cmd >> 16) & IOCPARM_MASK); for (i = 0; i < len / 4; ++i) info("word[%d] @ 0x%06x = 0x%x\n", i, &((int *) c)[i],((int *)c)[i]); } errno = serrno;#endif if (ret == -1 && errno == EPERM) errno = ret = 0; return ret;}#endif /* HAS_BROKEN_IOCTL */#if defined(FIXSIGS) && (defined (hppa) || defined(sparc))/* * These redefinitions of Posix functions are necessary * because HPPA systems have an OS bug that causes * sigaction to core dump: * * AlainF 9-Nov-1994 HACK FOR HP-PA/NEXTSTEP * sigaction(3) seems broken in the HP-PA NeXTSTEP 3.2 * Posix lib. This causes pppd to SIGBUS at the expiration * of the first timeout (_sigtramp seems to invoke * the SIGALRM handler at an unreasonably low address). * All calls so sigaction(3) have been changed to calls * to sigvec(2) and sigprocmask(SIG_BLOCK,...) to * sigblock(2). * This is kind of a hack, especially since there are * other routines of the Posix lib still used, but * it worked for me. * * Dave Hess <David-Hess@net.tamu.edu> noted that 3.3 Sparc seems to * have the same bug. Thus this fix has been enabled for SPARC also. * * */int sigemptyset(sigset_t *mask){ *mask = 0;}sigaddset(sigset_t *mask, int which_sig){ *mask |= sigmask(which_sig);}int sigaction(int sig, const struct sigaction *act, struct sigaction *oact){ struct sigvec sv; static int in = 0; sv.sv_handler = act->sa_handler; sv.sv_mask = act->sa_mask; sv.sv_flags = 0; if (!in) { in = 1; warn("PPPD: Inside modified HP and SPARC sigaction\n"); } return sigvec(sig, &sv, NULL);}#endif/* * Code following is added for 2.3 compatibility *//* * get_idle_time - return how long the link has been idle. */intget_idle_time(u, ip) int u; struct ppp_idle *ip;{ return (ioctl(ttyfd, PPPIOCGIDLE, ip) >= 0); }/* * get_ppp_stats - return statistics for the link. */intget_ppp_stats(u, stats) int u; struct pppd_stats *stats;{ struct ifpppstatsreq req; memset (&req, 0, sizeof (req)); strlcpy(req.ifr_name, interface, sizeof(req.ifr_name)); if (ioctl(sockfd, SIOCGPPPSTATS, &req) < 0) { error("Couldn't get PPP statistics: %m"); return 0; } stats->bytes_in = req.stats.p.ppp_ibytes; stats->bytes_out = req.stats.p.ppp_obytes; return 1;}/* * get_loop_output - read characters from the loopback, form them * into frames, and detect when we want to bring the real link up. * Return value is 1 if we need to bring up the link, 0 otherwise. */intget_loop_output(){#if 0 int rv = 0; int n; while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) { if (loop_chars(inbuf, n)) rv = 1; } if (n == 0) fatal("eof on loopback"); if (errno != EWOULDBLOCK) fatal("read from loopback: %m"); return rv;#endif return 0;}/* * sifnpmode - Set the mode for handling packets for a given NP. */intsifnpmode(u, proto, mode) int u; int proto; enum NPmode mode;{ struct npioctl npi; npi.protocol = proto; npi.mode = mode; if (ioctl(ttyfd, PPPIOCSNPMODE, &npi) < 0) { error("ioctl(set NP %d mode to %d): %m", proto, mode); return 0; } return 1;}/* * open_ppp_loopback - open the device we use for getting * packets in demand mode, and connect it to a ppp interface. * Here we use a pty. */intopen_ppp_loopback(){#if 0 int flags; struct termios tios; int pppdisc = PPPDISC; fatal("open_ppp_loopback called!"); if (openpty(&loop_master, &loop_slave, loop_name, NULL, NULL) < 0) fatal("No free pty for loopback"); SYSDEBUG(("using %s for loopback", loop_name)); if (tcgetattr(loop_slave, &tios) == 0) { tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); tios.c_cflag |= CS8 | CREAD; tios.c_iflag = IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0) warn("couldn't set attributes on loopback: %m"); } if ((flags = fcntl(loop_master, F_GETFL)) != -1) if (fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set loopback to nonblock: %m"); ttyfd = loop_slave; if (ioctl(ttyfd, TIOCSETD, &pppdisc) < 0) fatal("ioctl(TIOCSETD): %m"); /* * Find out which interface we were given. */ if (ioctl(ttyfd, PPPIOCGUNIT, &ifunit) < 0) fatal("ioctl(PPPIOCGUNIT): %m"); /* * Enable debug in the driver if requested. */ if (kdebugflag) { if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) { warn("ioctl (PPPIOCGFLAGS): %m"); } else { flags |= (kdebugflag & 0xFF) * SC_DEBUG; if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) warn("ioctl(PPPIOCSFLAGS): %m"); } } return loop_master;#endif}/* * restore_loop - reattach the ppp unit to the loopback. */voidrestore_loop(){ int x; /* * Transfer the ppp interface back to the loopback. */ if (ioctl(ttyfd, PPPIOCXFERUNIT, 0) < 0) fatal("ioctl(transfer ppp unit): %m"); x = PPPDISC; if (ioctl(loop_slave, TIOCSETD, &x) < 0) fatal("ioctl(TIOCSETD): %m"); /* * Check that we got the same unit again. */ if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0) fatal("ioctl(PPPIOCGUNIT): %m"); if (x != ifunit) fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); ttyfd = loop_slave;}/* * Use the hostid as part of the random number seed. */intget_host_seed(){ return gethostid();}/* * sys_check_options - check the options that the user specified */intsys_check_options(){ /* * We don't support demand dialing yet. */ if (demand) { option_error("PPP-2.3 for NeXTSTEP does not yet support demand dialing"); return 0; } return 1;}/* * sys_close - Clean up in a child process before execing. */voidsys_close(){ close(sockfd); if (loop_slave >= 0) { close(loop_slave); close(loop_master); } closelog();}#if 0/* * wait_loop_output - wait until there is data available on the * loopback, for the length of time specified by *timo (indefinite * if timo is NULL). */void wait_loop_output(timo) struct timeval *timo;{ fd_set ready; int n; FD_ZERO(&ready); FD_SET(loop_master, &ready); n = select(loop_master + 1, &ready, NULL, &ready, timo); if (n < 0 && errno != EINTR) fatal("select: %m");}/* * wait_time - wait for a given length of time or until a * signal is received. */void wait_time(timo) struct timeval *timo;{ int n; n = select(0, NULL, NULL, NULL, timo); if (n < 0 && errno != EINTR) fatal("select: %m");}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -