static Embryo_Cell _embryo_str_strcut(Embryo_Program *ep, Embryo_Cell *params) { char *s1, *s2; int l1; /* params[1] = dst */ /* params[2] = str */ /* params[3] = n */ /* params[4] = n2 */ if (params[0] != (4 * sizeof(Embryo_Cell))) return 0; if (params[3] < 0) params[3] = 0; if (params[4] < params[3]) params[4] = params[3]; STRGET(ep, s1, params[2]); if (!s1) return 0; l1 = strlen(s1); if (params[3] >= l1) params[3] = l1; if (params[4] >= l1) params[4] = l1; if (params[4] == params[3]) { STRSET(ep, params[1], ""); return 0; } s2 = alloca(params[4] - params[3] + 1); strncpy(s2, s1 + params[3], params[4] - params[3]); s2[params[4] - params[3]] = 0; STRSET(ep, params[1], s2); return 0; }
static Embryo_Cell _embryo_str_strcpy(Embryo_Program *ep, Embryo_Cell *params) { char *s1; /* params[1] = dst */ /* params[2] = str */ if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; STRGET(ep, s1, params[2]); if (!s1) return 0; STRSET(ep, params[1], s1); return 0; }
static int PopFile(void) { IncludeStruct *i; /* Assume we own the file for now */ RunDisabled &= ~RUN_NOTOWNER; if (!Hush && NumIfs) Eprint("%s", ErrMsg[E_MISS_ENDIF]); if (!IStackPtr) return E_EOF; i = &IStack[IStackPtr-1]; if (i->chain) { int oldRunDisabled = RunDisabled; if (NextChainedFile(i) == OK) { return OK; } RunDisabled = oldRunDisabled; } if (IStackPtr <= 1) { return E_EOF; } IStackPtr--; LineNo = i->LineNo; IfFlags = i->IfFlags; NumIfs = i->NumIfs; CLine = i->CLine; fp = NULL; STRSET(FileName, i->filename); if (!i->ownedByMe) { RunDisabled |= RUN_NOTOWNER; } if (!CLine && (i->offset != -1L)) { /* We must open the file, then seek to specified position */ if (strcmp(i->filename, "-")) { fp = fopen(i->filename, "r"); if (!fp || !CheckSafety()) return E_CANT_OPEN; if (PurgeMode) OpenPurgeFile(i->filename, "a"); } else { fp = stdin; if (PurgeMode) PurgeFP = stdout; } if (fp != stdin) (void) fseek(fp, i->offset, 0); /* Trust that it works... */ } free((char *) i->filename); return OK; }
static Embryo_Cell _embryo_str_strprep(Embryo_Program *ep, Embryo_Cell *params) { char *s1, *s2, *s3; /* params[1] = dst */ /* params[2] = str */ if (params[0] != (2 * sizeof(Embryo_Cell))) return 0; STRGET(ep, s1, params[1]); STRGET(ep, s2, params[2]); if ((!s1) || (!s2)) return 0; s3 = alloca(strlen(s1) + strlen(s2) + 1); if (!s3) return 0; strcpy(s3, s2); strcat(s3, s1); STRSET(ep, params[1], s3); return 0; }
static Embryo_Cell _embryo_str_strncpy(Embryo_Program *ep, Embryo_Cell *params) { char *s1; int l; /* params[1] = dst */ /* params[2] = str */ /* params[3] = n */ if (params[0] != (3 * sizeof(Embryo_Cell))) return 0; if (params[3] < 0) params[3] = 0; STRGET(ep, s1, params[2]); if (!s1) return 0; l = strlen(s1); if (l > params[3]) s1[params[3]] = 0; STRSET(ep, params[1], s1); return 0; }
static Embryo_Cell _embryo_str_strnprep(Embryo_Program *ep, Embryo_Cell *params) { char *s1, *s2, *s3; int l1, l2; /* params[1] = dst */ /* params[2] = str */ /* params[3] = n */ if (params[0] != (3 * sizeof(Embryo_Cell))) return 0; if (params[3] < 0) params[3] = 0; STRGET(ep, s1, params[1]); STRGET(ep, s2, params[2]); if ((!s1) || (!s2)) return 0; l1 = strlen(s1); l2 = strlen(s2); s3 = alloca(l1 + l2 + 1); if (!s3) return 0; strncpy(s3, s2, params[3]); if (params[3] <= l2) s3[params[3]] = 0; strcat(s3, s1); STRSET(ep, params[1], s3); return 0; }
/* * v_replace -- [count]r<char> * * !!! * The r command in historic vi was almost beautiful in its badness. For * example, "r<erase>" and "r<word erase>" beeped the terminal and deleted * a single character. "Nr<carriage return>", where N was greater than 1, * inserted a single carriage return. "r<escape>" did cancel the command, * but "r<literal><escape>" erased a single character. To enter a literal * <literal> character, it required three <literal> characters after the * command. This may not be right, but at least it's not insane. * * PUBLIC: int v_replace __P((SCR *, VICMD *)); */ int v_replace(SCR *sp, VICMD *vp) { EVENT ev; VI_PRIVATE *vip; TEXT *tp; size_t blen, len; u_long cnt; int quote, rval; CHAR_T *bp; CHAR_T *p; vip = VIP(sp); /* * If the line doesn't exist, or it's empty, replacement isn't * allowed. It's not hard to implement, but: * * 1: It's historic practice (vi beeped before the replacement * character was even entered). * 2: For consistency, this change would require that the more * general case, "Nr", when the user is < N characters from * the end of the line, also work, which would be a bit odd. * 3: Replacing with a <newline> has somewhat odd semantics. */ if (db_get(sp, vp->m_start.lno, DBG_FATAL, &p, &len)) return (1); if (len == 0) { msgq(sp, M_BERR, "186|No characters to replace"); return (1); } /* * Figure out how many characters to be replace. For no particular * reason (other than that the semantics of replacing the newline * are confusing) only permit the replacement of the characters in * the current line. I suppose we could append replacement characters * to the line, but I see no compelling reason to do so. Check this * before we get the character to match historic practice, where Nr * failed immediately if there were less than N characters from the * cursor to the end of the line. */ cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; vp->m_stop.lno = vp->m_start.lno; vp->m_stop.cno = vp->m_start.cno + cnt - 1; if (vp->m_stop.cno > len - 1) { v_eol(sp, &vp->m_start); return (1); } /* * If it's not a repeat, reset the current mode and get a replacement * character. */ quote = 0; if (!F_ISSET(vp, VC_ISDOT)) { sp->showmode = SM_REPLACE; if (vs_refresh(sp, 0)) return (1); next: if (v_event_get(sp, &ev, 0, 0)) return (1); switch (ev.e_event) { case E_CHARACTER: /* * <literal_next> means escape the next character. * <escape> means they changed their minds. */ if (!quote) { if (ev.e_value == K_VLNEXT) { quote = 1; goto next; } if (ev.e_value == K_ESCAPE) return (0); } vip->rlast = ev.e_c; vip->rvalue = ev.e_value; break; case E_ERR: case E_EOF: F_SET(sp, SC_EXIT_FORCE); return (1); case E_INTERRUPT: /* <interrupt> means they changed their minds. */ return (0); case E_WRESIZE: /* <resize> interrupts the input mode. */ v_emsg(sp, NULL, VIM_WRESIZE); return (0); case E_REPAINT: if (vs_repaint(sp, &ev)) return (1); goto next; default: v_event_err(sp, &ev); return (0); } } /* Copy the line. */ GET_SPACE_RETW(sp, bp, blen, len); MEMMOVE(bp, p, len); p = bp; /* * Versions of nvi before 1.57 created N new lines when they replaced * N characters with <carriage-return> or <newline> characters. This * is different from the historic vi, which replaced N characters with * a single new line. Users complained, so we match historic practice. */ if ((!quote && vip->rvalue == K_CR) || vip->rvalue == K_NL) { /* Set return line. */ vp->m_stop.lno = vp->m_start.lno + 1; vp->m_stop.cno = 0; /* The first part of the current line. */ if (db_set(sp, vp->m_start.lno, p, vp->m_start.cno)) goto err_ret; /* * The rest of the current line. And, of course, now it gets * tricky. If there are characters left in the line and if * the autoindent edit option is set, white space after the * replaced character is discarded, autoindent is applied, and * the cursor moves to the last indent character. */ p += vp->m_start.cno + cnt; len -= vp->m_start.cno + cnt; if (len != 0 && O_ISSET(sp, O_AUTOINDENT)) for (; len && isblank(*p); --len, ++p); if ((tp = text_init(sp, p, len, len)) == NULL) goto err_ret; if (len != 0 && O_ISSET(sp, O_AUTOINDENT)) { if (v_txt_auto(sp, vp->m_start.lno, NULL, 0, tp)) goto err_ret; vp->m_stop.cno = tp->ai ? tp->ai - 1 : 0; } else vp->m_stop.cno = 0; vp->m_stop.cno = tp->ai ? tp->ai - 1 : 0; if (db_append(sp, 1, vp->m_start.lno, tp->lb, tp->len)) err_ret: rval = 1; else { text_free(tp); rval = 0; } } else { STRSET(bp + vp->m_start.cno, vip->rlast, cnt); rval = db_set(sp, vp->m_start.lno, bp, len); } FREE_SPACEW(sp, bp, blen); vp->m_final = vp->m_stop; return (rval); }
int OpenFile(char const *fname) { CachedFile *h = CachedFiles; int r; if (PurgeMode) { if (PurgeFP != NULL && PurgeFP != stdout) { fclose(PurgeFP); } PurgeFP = NULL; } /* Assume we own the file for now */ RunDisabled &= ~RUN_NOTOWNER; /* If it's in the cache, get it from there. */ while (h) { if (!strcmp(fname, h->filename)) { if (DebugFlag & DB_TRACE_FILES) { fprintf(ErrFp, "Reading `%s': Found in cache\n", fname); } CLine = h->cache; STRSET(FileName, fname); LineNo = 0; if (!h->ownedByMe) { RunDisabled |= RUN_NOTOWNER; } if (FileName) return OK; else return E_NO_MEM; } h = h->next; } /* If it's a dash, then it's stdin */ if (!strcmp(fname, "-")) { fp = stdin; if (PurgeMode) { PurgeFP = stdout; } if (DebugFlag & DB_TRACE_FILES) { fprintf(ErrFp, "Reading `-': Reading stdin\n"); } } else { fp = fopen(fname, "r"); if (DebugFlag & DB_TRACE_FILES) { fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname); } if (PurgeMode) { OpenPurgeFile(fname, "w"); } } if (!fp || !CheckSafety()) return E_CANT_OPEN; CLine = NULL; if (ShouldCache) { LineNo = 0; r = CacheFile(fname); if (r == OK) { fp = NULL; CLine = CachedFiles->cache; } else { if (strcmp(fname, "-")) { fp = fopen(fname, "r"); if (!fp || !CheckSafety()) return E_CANT_OPEN; if (PurgeMode) OpenPurgeFile(fname, "w"); } else { fp = stdin; if (PurgeMode) PurgeFP = stdout; } } } STRSET(FileName, fname); LineNo = 0; if (FileName) return OK; else return E_NO_MEM; }
static Embryo_Cell _embryo_str_snprintf(Embryo_Program *ep, Embryo_Cell *params) { char *s1, *s2; int i, o; int inesc = 0; int insub = 0; int p, pnum; /* params[1] = buf */ /* params[2] = bufsize */ /* params[3] = format_string */ /* params[4] = first arg ... */ if (params[0] < (Embryo_Cell)(3 * sizeof(Embryo_Cell))) return 0; if (params[2] <= 0) return 0; STRGET(ep, s1, params[3]); if (!s1) return -1; s2 = alloca(params[2] + 1); if (!s2) return -1; s2[0] = 0; pnum = (params[0] / sizeof(Embryo_Cell)) - 3; for (p = 0, o = 0, i = 0; (s1[i]) && (o < (params[2] - 1)) && (p < (pnum + 1)); i++) { if ((!inesc) && (!insub)) { if (s1[i] == '\\') inesc = 1; else if (s1[i] == '%') insub = 1; if ((!inesc) && (!insub)) { s2[o] = s1[i]; o++; } } else { Embryo_Cell *cptr; if (inesc) { switch (s1[i]) { case 't': s2[o] = '\t'; o++; break; case 'n': s2[o] = '\n'; o++; break; default: s2[o] = s1[i]; o++; break; } inesc = 0; } if ((insub) && (s1[i] == '%')) pnum++; if ((insub) && (p < pnum)) { switch (s1[i]) { case '%': s2[o] = '%'; o++; break; case 'c': cptr = embryo_data_address_get(ep, params[4 + p]); if (cptr) s2[o] = (char)(*cptr); p++; o++; break; case 'i': case 'd': case 'x': case 'X': { char fmt[10] = ""; char tmp[256] = ""; int l; if (s1[i] == 'i') strcpy(fmt, "%i"); else if (s1[i] == 'd') strcpy(fmt, "%d"); else if (s1[i] == 'x') strcpy(fmt, "%x"); else if (s1[i] == 'X') strcpy(fmt, "%08x"); cptr = embryo_data_address_get(ep, params[4 + p]); if (cptr) snprintf(tmp, sizeof(tmp), fmt, (int)(*cptr)); l = strlen(tmp); if ((o + l) > (params[2] - 1)) { l = params[2] - 1 - o; if (l < 0) l = 0; tmp[l] = 0; } strcpy(s2 + o, tmp); o += l; p++; } break; case 'f': { char tmp[256] = ""; int l; cptr = embryo_data_address_get(ep, params[4 + p]); if (cptr) snprintf(tmp, sizeof(tmp), "%f", (double)EMBRYO_CELL_TO_FLOAT(*cptr)); l = strlen(tmp); if ((o + l) > (params[2] - 1)) { l = params[2] - 1 - o; if (l < 0) l = 0; tmp[l] = 0; } strcpy(s2 + o, tmp); o += l; p++; } break; case 's': { char *tmp; int l; STRGET(ep, tmp, params[4 + p]); l = strlen(tmp); if ((o + l) > (params[2] - 1)) { l = params[2] - 1 - o; if (l < 0) l = 0; tmp[l] = 0; } strcpy(s2 + o, tmp); o += l; p++; } break; default: break; } insub = 0; } else if (insub) insub = 0; } } s2[o] = 0; STRSET(ep, params[1], s2); return o; }
/* * Allocate and fill in the interfaces global variable with the * machine's ip addresses and netmasks. */ void load_interfaces() { struct ifconf *ifconf; struct ifreq *ifr, ifr_tmp; struct sockaddr_in *sin; int sock, n, i; size_t len = sizeof(struct ifconf) + BUFSIZ; char *previfname = "", *ifconf_buf = NULL; #ifdef _ISC struct strioctl strioctl; #endif /* _ISC */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) error(1, "cannot open socket"); /* * Get interface configuration or return (leaving num_interfaces == 0) */ for (;;) { ifconf_buf = erealloc(ifconf_buf, len); ifconf = (struct ifconf *) ifconf_buf; ifconf->ifc_len = len - sizeof(struct ifconf); ifconf->ifc_buf = (caddr_t) (ifconf_buf + sizeof(struct ifconf)); #ifdef _ISC STRSET(SIOCGIFCONF, (caddr_t) ifconf, len); if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0) { #else /* Note that some kernels return EINVAL if the buffer is too small */ if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0 && errno != EINVAL) { #endif /* _ISC */ efree(ifconf_buf); (void) close(sock); return; } /* Break out of loop if we have a big enough buffer. */ if (ifconf->ifc_len + sizeof(struct ifreq) < len) break; len += BUFSIZ; } /* Allocate space for the maximum number of interfaces that could exist. */ if ((n = ifconf->ifc_len / sizeof(struct ifreq)) == 0) return; interfaces = (struct interface *) emalloc2(n, sizeof(struct interface)); /* For each interface, store the ip address and netmask. */ for (i = 0; i < ifconf->ifc_len; ) { /* Get a pointer to the current interface. */ ifr = (struct ifreq *) &ifconf->ifc_buf[i]; /* Set i to the subscript of the next interface. */ i += sizeof(struct ifreq); #ifdef HAVE_SA_LEN if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr)) i += ifr->ifr_addr.sa_len - sizeof(struct sockaddr); #endif /* HAVE_SA_LEN */ /* Skip duplicates and interfaces with NULL addresses. */ sin = (struct sockaddr_in *) &ifr->ifr_addr; if (sin->sin_addr.s_addr == 0 || strncmp(previfname, ifr->ifr_name, sizeof(ifr->ifr_name) - 1) == 0) continue; if (ifr->ifr_addr.sa_family != AF_INET) continue; #ifdef SIOCGIFFLAGS zero_bytes(&ifr_tmp, sizeof(ifr_tmp)); strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1); if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr_tmp) < 0) #endif ifr_tmp = *ifr; /* Skip interfaces marked "down" and "loopback". */ if (!ISSET(ifr_tmp.ifr_flags, IFF_UP) || ISSET(ifr_tmp.ifr_flags, IFF_LOOPBACK)) continue; sin = (struct sockaddr_in *) &ifr->ifr_addr; interfaces[num_interfaces].addr.ip4.s_addr = sin->sin_addr.s_addr; /* Stash the name of the interface we saved. */ previfname = ifr->ifr_name; /* Get the netmask. */ zero_bytes(&ifr_tmp, sizeof(ifr_tmp)); strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1); #ifdef SIOCGIFNETMASK #ifdef _ISC STRSET(SIOCGIFNETMASK, (caddr_t) &ifr_tmp, sizeof(ifr_tmp)); if (ioctl(sock, I_STR, (caddr_t) &strioctl) == 0) { #else if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) &ifr_tmp) == 0) { #endif /* _ISC */ sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr; interfaces[num_interfaces].netmask.ip4.s_addr = sin->sin_addr.s_addr; } else { #else { #endif /* SIOCGIFNETMASK */ if (IN_CLASSC(interfaces[num_interfaces].addr.ip4.s_addr)) interfaces[num_interfaces].netmask.ip4.s_addr = htonl(IN_CLASSC_NET); else if (IN_CLASSB(interfaces[num_interfaces].addr.ip4.s_addr)) interfaces[num_interfaces].netmask.ip4.s_addr = htonl(IN_CLASSB_NET); else interfaces[num_interfaces].netmask.ip4.s_addr = htonl(IN_CLASSA_NET); } /* Only now can we be sure it was a good/interesting interface. */ interfaces[num_interfaces].family = AF_INET; num_interfaces++; } /* If the expected size < real size, realloc the array. */ if (n != num_interfaces) { if (num_interfaces != 0) interfaces = (struct interface *) erealloc3(interfaces, num_interfaces, sizeof(struct interface)); else efree(interfaces); } efree(ifconf_buf); (void) close(sock); } #else /* !SIOCGIFCONF || STUB_LOAD_INTERFACES */ /* * Stub function for those without SIOCGIFCONF */ void load_interfaces() { return; } #endif /* SIOCGIFCONF && !STUB_LOAD_INTERFACES */ void dump_interfaces() { int i; #ifdef HAVE_IN6_ADDR char addrbuf[INET6_ADDRSTRLEN], maskbuf[INET6_ADDRSTRLEN]; #endif puts("Local IP address and netmask pairs:"); for (i = 0; i < num_interfaces; i++) { switch(interfaces[i].family) { case AF_INET: printf("\t%s / ", inet_ntoa(interfaces[i].addr.ip4)); puts(inet_ntoa(interfaces[i].netmask.ip4)); break; #ifdef HAVE_IN6_ADDR case AF_INET6: inet_ntop(AF_INET6, &interfaces[i].addr.ip6, addrbuf, sizeof(addrbuf)); inet_ntop(AF_INET6, &interfaces[i].netmask.ip6, maskbuf, sizeof(maskbuf)); printf("\t%s / %s\n", addrbuf, maskbuf); break; #endif /* HAVE_IN6_ADDR */ } } }
/* * Allocate and fill in the interfaces global variable with the * machine's ip addresses and netmasks. */ int get_net_ifs(char **addrinfo) { struct ifconf *ifconf; struct ifreq *ifr, ifr_tmp; struct sockaddr_in *sin; int ailen, i, len, n, sock, num_interfaces = 0; size_t buflen = sizeof(struct ifconf) + BUFSIZ; char *cp, *previfname = "", *ifconf_buf = NULL; #ifdef _ISC struct strioctl strioctl; #endif /* _ISC */ debug_decl(get_net_ifs, SUDO_DEBUG_NETIF) sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) error(1, _("unable to open socket")); /* * Get interface configuration or return. */ for (;;) { ifconf_buf = emalloc(buflen); ifconf = (struct ifconf *) ifconf_buf; ifconf->ifc_len = buflen - sizeof(struct ifconf); ifconf->ifc_buf = (caddr_t) (ifconf_buf + sizeof(struct ifconf)); #ifdef _ISC STRSET(SIOCGIFCONF, (caddr_t) ifconf, buflen); if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0) #else /* Note that some kernels return EINVAL if the buffer is too small */ if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0 && errno != EINVAL) #endif /* _ISC */ goto done; /* Break out of loop if we have a big enough buffer. */ if (ifconf->ifc_len + sizeof(struct ifreq) < buflen) break; buflen += BUFSIZ; efree(ifconf_buf); } /* Allocate space for the maximum number of interfaces that could exist. */ if ((n = ifconf->ifc_len / sizeof(struct ifreq)) == 0) debug_return_int(0); ailen = n * 2 * INET6_ADDRSTRLEN; *addrinfo = cp = emalloc(ailen); /* For each interface, store the ip address and netmask. */ for (i = 0; i < ifconf->ifc_len; ) { /* Get a pointer to the current interface. */ ifr = (struct ifreq *) &ifconf->ifc_buf[i]; /* Set i to the subscript of the next interface. */ i += sizeof(struct ifreq); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr)) i += ifr->ifr_addr.sa_len - sizeof(struct sockaddr); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ /* Skip duplicates and interfaces with NULL addresses. */ sin = (struct sockaddr_in *) &ifr->ifr_addr; if (sin->sin_addr.s_addr == 0 || strncmp(previfname, ifr->ifr_name, sizeof(ifr->ifr_name) - 1) == 0) continue; if (ifr->ifr_addr.sa_family != AF_INET) continue; #ifdef SIOCGIFFLAGS memset(&ifr_tmp, 0, sizeof(ifr_tmp)); strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1); if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr_tmp) < 0) #endif ifr_tmp = *ifr; /* Skip interfaces marked "down" and "loopback". */ if (!ISSET(ifr_tmp.ifr_flags, IFF_UP) || ISSET(ifr_tmp.ifr_flags, IFF_LOOPBACK)) continue; sin = (struct sockaddr_in *) &ifr->ifr_addr; len = snprintf(cp, ailen - (*addrinfo - cp), "%s%s/", cp == *addrinfo ? "" : " ", inet_ntoa(sin->sin_addr)); if (len <= 0 || len >= ailen - (*addrinfo - cp)) { warningx(_("load_interfaces: overflow detected")); goto done; } cp += len; /* Stash the name of the interface we saved. */ previfname = ifr->ifr_name; /* Get the netmask. */ memset(&ifr_tmp, 0, sizeof(ifr_tmp)); strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1); #ifdef _ISC STRSET(SIOCGIFNETMASK, (caddr_t) &ifr_tmp, sizeof(ifr_tmp)); if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0) { #else if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) &ifr_tmp) < 0) { #endif /* _ISC */ sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr; sin->sin_addr.s_addr = htonl(IN_CLASSC_NET); } sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr; len = snprintf(cp, ailen - (*addrinfo - cp), "%s", inet_ntoa(sin->sin_addr)); if (len <= 0 || len >= ailen - (*addrinfo - cp)) { warningx(_("load_interfaces: overflow detected")); goto done; } cp += len; num_interfaces++; } done: efree(ifconf_buf); (void) close(sock); debug_return_int(num_interfaces); } #else /* !SIOCGIFCONF || STUB_LOAD_INTERFACES */ /* * Stub function for those without SIOCGIFCONF or getifaddrs() */ int get_net_ifs(char **addrinfo) { debug_decl(get_net_ifs, SUDO_DEBUG_NETIF) debug_return_int(0); }