예제 #1
0
struct net_data *
net_data_create(const char *conf_file) {
	struct net_data *net_data;

	net_data = memget(sizeof (struct net_data));
	if (net_data == NULL)
		return (NULL);
	memset(net_data, 0, sizeof (struct net_data));

	if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) {
		memput(net_data, sizeof (struct net_data));
		return (NULL);
	}
#ifndef DO_PTHREADS
	(*net_data->irs->res_set)(net_data->irs, &_res, NULL);
#endif

	net_data->res = (*net_data->irs->res_get)(net_data->irs);
	if (net_data->res == NULL) {
		(*net_data->irs->close)(net_data->irs);
		memput(net_data, sizeof (struct net_data));
		return (NULL);
	}

	if ((net_data->res->options & RES_INIT) == 0U &&
	    res_ninit(net_data->res) == -1) {
		(*net_data->irs->close)(net_data->irs);
		memput(net_data, sizeof (struct net_data));
		return (NULL);
	}

	return (net_data);
}
예제 #2
0
파일: lcl_sv.cpp 프로젝트: mmanley/Antares
static void
sv_close(struct irs_sv *sv)
{
	struct service_private *service = (struct service_private *)sv->private_data;

	if (service->file)
		fclose(service->file);

	memput(service, sizeof *service);
	memput(sv, sizeof *sv);
}
예제 #3
0
파일: lcl_sv.cpp 프로젝트: mmanley/Antares
extern "C" struct irs_sv *
irs_lcl_sv(struct irs_acc */*acc*/)
{
	struct service_private *service;
	struct irs_sv *sv;

	if ((sv = (irs_sv *)memget(sizeof *sv)) == NULL) {
		errno = ENOMEM;
		return NULL;
	}
	if ((service = (service_private *)memget(sizeof *service)) == NULL) {
		memput(sv, sizeof *sv);
		errno = ENOMEM;
		return NULL;
	}

	memset(service, 0, sizeof *service);

	sv->private_data = service;
	sv->close = sv_close;
	sv->next = sv_next;
	sv->byname = sv_byname;
	sv->byport = sv_byport;
	sv->rewind = sv_rewind;
	sv->minimize = sv_minimize;
	sv->res_get = NULL;
	sv->res_set = NULL;

	return sv;
}
예제 #4
0
파일: logging.c 프로젝트: AmirAbrams/haiku
int
log_remove_channel(log_context lc, int category, log_channel chan) {
	log_channel_list lcl, prev_lcl, next_lcl;
	int found = 0;

	if (lc == NULL || category < 0 || category >= lc->num_categories) {
		errno = EINVAL;
		return (-1);
	}

	for (prev_lcl = NULL, lcl = lc->categories[category];
	     lcl != NULL;
	     lcl = next_lcl) {
		next_lcl = lcl->next;
		if (lcl->channel == chan) {
			log_free_channel(chan);
			if (prev_lcl != NULL)
				prev_lcl->next = next_lcl;
			else
				lc->categories[category] = next_lcl;
			memput(lcl, sizeof (struct log_channel_list));
			/*
			 * We just set found instead of returning because
			 * the channel might be on the list more than once.
			 */
			found = 1;
		} else
			prev_lcl = lcl;
	}
	if (!found) {
		errno = ENOENT;
		return (-1);
	}
	return (0);
}
예제 #5
0
void
ctl_bufput(struct ctl_buf *buf) {

	REQUIRE(allocated_p(*buf));
	memput(buf->text, MAX_LINELEN);
	buf->text = NULL;
	buf->used = 0;
}
예제 #6
0
파일: logging.c 프로젝트: AmirAbrams/haiku
void
log_free_context(log_context lc) {
	log_channel_list lcl, lcl_next;
	log_channel chan;
	int i;

	REQUIRE(lc != NULL);

	for (i = 0; i < lc->num_categories; i++)
		for (lcl = lc->categories[i]; lcl != NULL; lcl = lcl_next) {
			lcl_next = lcl->next;
			chan = lcl->channel;
			(void)log_free_channel(chan);
			memput(lcl, sizeof (struct log_channel_list));
		}
	memput(lc->categories,
	       lc->num_categories * sizeof (log_channel_list));
	memput(lc, sizeof (struct log_context));
}
예제 #7
0
파일: logging.c 프로젝트: AmirAbrams/haiku
int
log_free_channel(log_channel chan) {
	if (chan == NULL || chan->references <= 0) {
		errno = EINVAL;
		return (-1);
	}
	chan->references--;
	if (chan->references == 0) {
		if (chan->type == log_file) {
			if ((chan->flags & LOG_CLOSE_STREAM) &&
			    chan->out.file.stream != NULL)
				(void)fclose(chan->out.file.stream);
			if (chan->out.file.name != NULL)
				memput(chan->out.file.name,
				       chan->out.file.name_size);
		}
		memput(chan, sizeof (struct log_channel));
	}
	return (0);
}
예제 #8
0
void
freehostent(struct hostent *he) {
	char **cpp;
	int names = 1;
	int addresses = 1;

	memput(he->h_name, strlen(he->h_name) + 1);

	cpp = he->h_addr_list;
	while (*cpp != NULL) {
		memput(*cpp, (he->h_addrtype == AF_INET) ?
			     INADDRSZ : IN6ADDRSZ);
		*cpp = NULL;
		cpp++;
		addresses++;
	}

	cpp = he->h_aliases;
	while (*cpp != NULL) {
		memput(*cpp, strlen(*cpp) + 1);
		cpp++;
		names++;
	}

	memput(he->h_aliases, sizeof(char *) * (names));
	memput(he->h_addr_list, sizeof(char *) * (addresses));
	memput(he, sizeof *he);
}
예제 #9
0
void
net_data_destroy(void *p) {
	struct net_data *net_data = p;

	res_ndestroy(net_data->res);
	if (net_data->gr != NULL) {
		(*net_data->gr->close)(net_data->gr);
		net_data->gr = NULL;
	}
	if (net_data->pw != NULL) {
		(*net_data->pw->close)(net_data->pw);
		net_data->pw = NULL;
	}
	if (net_data->sv != NULL) {
		(*net_data->sv->close)(net_data->sv);
		net_data->sv = NULL;
	}
	if (net_data->pr != NULL) {
		(*net_data->pr->close)(net_data->pr);
		net_data->pr = NULL;
	}
	if (net_data->ho != NULL) {
		(*net_data->ho->close)(net_data->ho);
		net_data->ho = NULL;
	}
	if (net_data->nw != NULL) {
		(*net_data->nw->close)(net_data->nw);
		net_data->nw = NULL;
	}
	if (net_data->ng != NULL) {
		(*net_data->ng->close)(net_data->ng);
		net_data->ng = NULL;
	}
	if (net_data->ho_data != NULL) {
		free(net_data->ho_data);
		net_data->ho_data = NULL;
	}
	if (net_data->nw_data != NULL) {
		free(net_data->nw_data);
		net_data->nw_data = NULL;
	}

	(*net_data->irs->close)(net_data->irs);
	memput(net_data, sizeof *net_data);
}
예제 #10
0
파일: logging.c 프로젝트: AmirAbrams/haiku
log_channel
log_new_file_channel(unsigned int flags, int level,
		     const char *name, FILE *stream, unsigned int versions,
		     unsigned long max_size) {
	log_channel chan;

	chan = memget(sizeof (struct log_channel));
	if (chan == NULL) {
		errno = ENOMEM;
		return (NULL);
	}
	chan->type = log_file;
	chan->flags = flags;
	chan->level = level;
	if (name != NULL) {
		size_t len;

		len = strlen(name);
		/*
		 * Quantize length to a multiple of 256.  There's space for the
		 * NUL, since if len is a multiple of 256, the size chosen will
		 * be the next multiple.
		 */
		chan->out.file.name_size = ((len / 256) + 1) * 256;
		chan->out.file.name = memget(chan->out.file.name_size);
		if (chan->out.file.name == NULL) {
			memput(chan, sizeof (struct log_channel));
			errno = ENOMEM;
			return (NULL);
		}
		/* This is safe. */
		strcpy(chan->out.file.name, name);
	} else {
		chan->out.file.name_size = 0;
		chan->out.file.name = NULL;
	}
	chan->out.file.stream = stream;
	chan->out.file.versions = versions;
	chan->out.file.max_size = max_size;
	chan->out.file.owner = getuid();
	chan->out.file.group = getgid();
	chan->references = 0;
	return (chan);
}
예제 #11
0
파일: logging.c 프로젝트: AmirAbrams/haiku
int
log_new_context(int num_categories, char **category_names, log_context *lc) {
	log_context nlc;

	nlc = memget(sizeof (struct log_context));
	if (nlc == NULL) {
		errno = ENOMEM;
		return (-1);
	}
	nlc->num_categories = num_categories;
	nlc->category_names = category_names;
	nlc->categories = memget(num_categories * sizeof (log_channel_list));
	if (nlc->categories == NULL) {
		memput(nlc, sizeof (struct log_context));
		errno = ENOMEM;
		return (-1);
	}
	memset(nlc->categories, '\0',
	       num_categories * sizeof (log_channel_list));
	nlc->flags = 0U;
	nlc->level = 0;
	*lc = nlc;
	return (0);
}
예제 #12
0
파일: crcal.c 프로젝트: tlapicka/crcal
/****************************************************
 *               Hlavní program.
 ****************************************************/
int main(void)
{
    double rnumber;             // číslo se kterým se má počítat
    double inumber;             // číslo se kterým se má počítat
    char enter[CMDLEN];         // vstup od uživatele

    setrad();
    /* Čte řádky až do konce souboru */
    while (readEnter(enter) != EOF) {
        if (sscanf(enter, "%lg,%lg", &rnumber, &inumber) == 2) {
            pushalg(rnumber, inumber);
        } else if (sscanf(enter, "%lgL%lg", &rnumber, &inumber) == 2) {
            pushexp(rnumber, inumber);
        } else if (sscanf(enter, ",%lg", &inumber) == 1) {
            pushalg(0, inumber);
        } else if (sscanf(enter, "%lg", &rnumber) == 1) {
            pushalg(rnumber, 0);
        } else if (strcmp(enter, "pi") == 0) {
            pushalg(M_PI, 0);
        } else if (strcmp(enter, "e") == 0) {
            pushalg(M_E, 0);
        } else if (strcmp(enter, "+") == 0) {
            make2wrap(makePlus, enter);
        } else if (strcmp(enter, "-") == 0) {
            make2wrap(makeMinus, enter);
        } else if (strcmp(enter, "*") == 0) {
            make2wrap(makeTimes, enter);
        } else if (strcmp(enter, "/") == 0) {
            make2wrap(makeDivid, enter);
        } else if (strcmp(enter, "**") == 0) {
            /* n-tá mocnina */
            make2wrap(cpow, enter);
        } else if (strcmp(enter, "^") == 0) {
            /* převrácená hodnota */
            make1wrap(makeFlipp, enter);
        } else if (strcmp(enter, "sqrt") == 0 || strcmp(enter, "t") == 0) {
            make1wrap(csqrt, enter);
        } else if (strcmp(enter, "exp") == 0 || strcmp(enter, "x") == 0) {
            /* exponenciální funkce */
            make1wrap(cexp, enter);
        } else if (strcmp(enter, "ln") == 0) {
            make1wrap(clog, enter);
        } else if (strcmp(enter, "log") == 0) {
            make1wrap(clog10, enter);
        } else if (strcmp(enter, "r") == 0) {
            /* přepne kalkulačku do radiánů */
            setrad();
        } else if (strcmp(enter, "d") == 0) {
            /* přepne kalkulačku do stupňů */
            setdeg();
        } else if (strcmp(enter, "la") == 0) {
            /* poslední číslo převede do algebraickém tvaru */
            last2alg();
            printStack();
        } else if (strcmp(enter, "le") == 0) {
            /* poslední číslo převede exponenciálním tvaru */
            last2exp();
            printStack();
        } else if (strcmp(enter, "aa") == 0) {
            /* všechny čísla převede do algebraickém tvaru */
            all2alg();
            printStack();
        } else if (strcmp(enter, "ae") == 0) {
            /* všechny čísla převede do exponenciálním tvaru */
            all2exp();
            printStack();
        } else if (strcmp(enter, "da") == 0) {
            setalg();
        } else if (strcmp(enter, "de") == 0) {
            setexp();
        } else if (strcmp(enter, "switch") == 0 || strcmp(enter, "s") == 0) {
            if (!lastSwitch())
                fprintf(stderr, " error > Nelze prohodit\n");
        } else if (strcmp(enter, "deg") == 0) {
            make1wrap(rad2deg, enter);
        } else if (strcmp(enter, "rad") == 0) {
            make1wrap(deg2rad, enter);
            /* Goniometrické funkce */
        } else if (strcmp(enter, "sin") == 0) {
            make1wrap(csin, enter);
        } else if (strcmp(enter, "cos") == 0) {
            make1wrap(ccos, enter);
        } else if (strcmp(enter, "tan") == 0 || strcmp(enter, "tg") == 0) {
            make1wrap(ctan, enter);
        } else if (strcmp(enter, "asin") == 0) {
            make1wrap(casin, enter);
        } else if (strcmp(enter, "acos") == 0) {
            make1wrap(cacos, enter);
        } else if (strcmp(enter, "atan") == 0 || strcmp(enter, "atg") == 0) {
            make1wrap(catan, enter);
        } else if (enter[0] == '>') {
            /* ukládá do proměnné */
            complex double number = pop();
            memput(number, enter, algform ? ALGFORM : EXPFORM);
            push(number, algform);
        } else if (enter[0] == '<') {
            /* vybírá obsah proměnné */
            enter[0] = '>';
            char form;
            complex double number = memget(enter, &form);
            push(number, form == ALGFORM ? true : false);
        } else if (strcmp(enter, "rem") == 0 || strcmp(enter, "m") == 0) {
            pop();
            printStack();
        } else if (strcmp(enter, "clr") == 0 || strcmp(enter, "c") == 0) {
            stackclear();       // vymaže celý zásobník
        } else if (strcmp(enter, "p") == 0 || strcmp(enter, "print") == 0) {    // jen tiskne zásobník
            printStack();
        } else if (strcmp(enter, "help") == 0 || strcmp(enter, "h") == 0) {
            printHelp();
        } else if (strcmp(enter, "quit") == 0 || strcmp(enter, "q") == 0) {
            break;
        } else {
            fprintf(stderr, " error > %s\n", enter);
            fprintf(stderr, " error > Neplatný vstup\n");
        }
    }
    stackclear();               // maže zásobník
    memclear();               // maže zásobník
    return 0;
}
예제 #13
0
파일: db_tsig.c 프로젝트: aosm/bind
void
free_tsig(struct tsig_record *tsig) {
	if (tsig == NULL)
		return;
	memput(tsig, sizeof(struct tsig_record));
}
예제 #14
0
static struct hostent *
copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num) {
	struct hostent *he = NULL;
	int addresses = 1;	/*%< NULL terminator */
	int names = 1;		/*%< NULL terminator */
	int len = 0;
	char **cpp, **npp;

	/*
	 * Work out array sizes;
	 */
	if (he1 != NULL) {
		cpp = he1->h_addr_list;
		while (*cpp != NULL) {
			addresses++;
			cpp++;
		}
		cpp = he1->h_aliases;
		while (*cpp != NULL) {
			names++;
			cpp++;
		}
	}

	if (he2 != NULL) {
		cpp = he2->h_addr_list;
		while (*cpp != NULL) {
			addresses++;
			cpp++;
		}
		if (he1 == NULL) {
			cpp = he2->h_aliases;
			while (*cpp != NULL) {
				names++;
				cpp++;
			}
		}
	}

	if (addresses == 1) {
		*error_num = NO_ADDRESS;
		return (NULL);
	}

	he = memget(sizeof *he);
	if (he == NULL)
		goto no_recovery;

	he->h_addr_list = memget(sizeof(char *) * (addresses));
	if (he->h_addr_list == NULL)
		goto cleanup0;
	memset(he->h_addr_list, 0, sizeof(char *) * (addresses));

	/* copy addresses */
	npp = he->h_addr_list;
	if (he1 != NULL) {
		cpp = he1->h_addr_list;
		while (*cpp != NULL) {
			*npp = memget((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
			if (*npp == NULL)
				goto cleanup1;
			/* convert to mapped if required */
			if (af == AF_INET6 && he1->h_addrtype == AF_INET) {
				memcpy(*npp, in6addr_mapped,
				       sizeof in6addr_mapped);
				memcpy(*npp + sizeof in6addr_mapped, *cpp,
				       INADDRSZ);
			} else {
				memcpy(*npp, *cpp,
				       (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
			}
			cpp++;
			npp++;
		}
	}

	if (he2 != NULL) {
		cpp = he2->h_addr_list;
		while (*cpp != NULL) {
			*npp = memget((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
			if (*npp == NULL)
				goto cleanup1;
			/* convert to mapped if required */
			if (af == AF_INET6 && he2->h_addrtype == AF_INET) {
				memcpy(*npp, in6addr_mapped,
				       sizeof in6addr_mapped);
				memcpy(*npp + sizeof in6addr_mapped, *cpp,
				       INADDRSZ);
			} else {
				memcpy(*npp, *cpp,
				       (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
			}
			cpp++;
			npp++;
		}
	}

	he->h_aliases = memget(sizeof(char *) * (names));
	if (he->h_aliases == NULL)
		goto cleanup1;
	memset(he->h_aliases, 0, sizeof(char *) * (names));

	/* copy aliases */
	npp = he->h_aliases;
	cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases;
	while (*cpp != NULL) {
		len = strlen (*cpp) + 1;
		*npp = memget(len);
		if (*npp == NULL)
			goto cleanup2;
		strcpy(*npp, *cpp);
		npp++;
		cpp++;
	}

	/* copy hostname */
	he->h_name = memget(strlen((he1 != NULL) ?
			    he1->h_name : he2->h_name) + 1);
	if (he->h_name == NULL)
		goto cleanup2;
	strcpy(he->h_name, (he1 != NULL) ? he1->h_name : he2->h_name);

	/* set address type and length */
	he->h_addrtype = af;
	he->h_length = (af == AF_INET) ? INADDRSZ : IN6ADDRSZ;
	return(he);

 cleanup2:
	cpp = he->h_aliases;
	while (*cpp != NULL) {
		memput(*cpp, strlen(*cpp) + 1);
		cpp++;
	}
	memput(he->h_aliases, sizeof(char *) * (names));

 cleanup1:
	cpp = he->h_addr_list;
	while (*cpp != NULL) {
		memput(*cpp, (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
		*cpp = NULL;
		cpp++;
	}
	memput(he->h_addr_list, sizeof(char *) * (addresses));

 cleanup0:
	memput(he, sizeof *he);

 no_recovery:
	*error_num = NO_RECOVERY;
	return (NULL);
}
예제 #15
0
static int
scan_interfaces(int *have_v4, int *have_v6) {
	struct ifconf ifc;
	union {
		char _pad[256];		/*%< leave space for IPv6 addresses */
		struct ifreq ifreq;
	} u;
	struct in_addr in4;
	struct in6_addr in6;
	char *buf = NULL, *cp, *cplim;
	static unsigned int bufsiz = 4095;
	int s, n;
	size_t cpsize;

	/* Set to zero.  Used as loop terminators below. */
	*have_v4 = *have_v6 = 0;

#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) 
	/*
	 * Try to scan the interfaces using IPv6 ioctls().
	 */
	scan_interfaces6(have_v4, have_v6);
	if (*have_v4 != 0 && *have_v6 != 0)
		return (0);
#endif
#ifdef __linux
	scan_linux6(have_v6);
#endif

	/* Get interface list from system. */
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		goto err_ret;

	/*
	 * Grow buffer until large enough to contain all interface
	 * descriptions.
	 */
	for (;;) {
		buf = memget(bufsiz);
		if (buf == NULL)
			goto err_ret;
		ifc.ifc_len = bufsiz;
		ifc.ifc_buf = buf;
#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
		/*
		 * This is a fix for IRIX OS in which the call to ioctl with
		 * the flag SIOCGIFCONF may not return an entry for all the
		 * interfaces like most flavors of Unix.
		 */
		if (emul_ioctl(&ifc) >= 0)
			break;
#else
		if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) {
			/*
			 * Some OS's just return what will fit rather
			 * than set EINVAL if the buffer is too small
			 * to fit all the interfaces in.  If 
			 * ifc.ifc_len is too near to the end of the
			 * buffer we will grow it just in case and
			 * retry.
			 */
			if (ifc.ifc_len + 2 * sizeof(u.ifreq) < bufsiz)
				break;
		}
#endif
		if ((n == -1) && errno != EINVAL)
			goto err_ret;

		if (bufsiz > 1000000)
			goto err_ret;

		memput(buf, bufsiz);
		bufsiz += 4096;
	}

	/* Parse system's interface list. */
	cplim = buf + ifc.ifc_len;    /*%< skip over if's with big ifr_addr's */
	for (cp = buf;
	     (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;
	     cp += cpsize) {
		memcpy(&u.ifreq, cp, sizeof u.ifreq);
#ifdef HAVE_SA_LEN
#ifdef FIX_ZERO_SA_LEN
		if (u.ifreq.ifr_addr.sa_len == 0)
			u.ifreq.ifr_addr.sa_len = 16;
#endif
#ifdef HAVE_MINIMUM_IFREQ
		cpsize = sizeof u.ifreq;
		if (u.ifreq.ifr_addr.sa_len > sizeof (struct sockaddr))
			cpsize += (int)u.ifreq.ifr_addr.sa_len -
				(int)(sizeof (struct sockaddr));
#else
		cpsize = sizeof u.ifreq.ifr_name + u.ifreq.ifr_addr.sa_len;
#endif /* HAVE_MINIMUM_IFREQ */
		if (cpsize > sizeof u.ifreq && cpsize <= sizeof u)
			memcpy(&u.ifreq, cp, cpsize);
#elif defined SIOCGIFCONF_ADDR
		cpsize = sizeof u.ifreq;
#else
		cpsize = sizeof u.ifreq.ifr_name;
		/* XXX maybe this should be a hard error? */
		if (ioctl(s, SIOCGIFADDR, (char *)&u.ifreq) < 0)
			continue;
#endif
		switch (u.ifreq.ifr_addr.sa_family) {
		case AF_INET:
			if (*have_v4 == 0) {
				memcpy(&in4,
				       &((struct sockaddr_in *)
				       &u.ifreq.ifr_addr)->sin_addr,
				       sizeof in4);
				if (in4.s_addr == INADDR_ANY)
					break;
				n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq);
				if (n < 0)
					break;
				if ((u.ifreq.ifr_flags & IFF_UP) == 0)
					break;
				*have_v4 = 1;
			} 
			break;
		case AF_INET6:
			if (*have_v6 == 0) {
				memcpy(&in6,
				       &((struct sockaddr_in6 *)
				       &u.ifreq.ifr_addr)->sin6_addr,
				       sizeof in6);
				if (memcmp(&in6, &in6addr_any, sizeof in6) == 0)
					break;
				n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq);
				if (n < 0)
					break;
				if ((u.ifreq.ifr_flags & IFF_UP) == 0)
					break;
				*have_v6 = 1;
			}
			break;
		}
	}
	if (buf != NULL)
		memput(buf, bufsiz);
	close(s);
	/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
	return (0);
 err_ret:
	if (buf != NULL)
		memput(buf, bufsiz);
	if (s != -1)
		close(s);
	/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
	return (-1);
}
예제 #16
0
static void
scan_interfaces6(int *have_v4, int *have_v6) {
	struct LIFCONF lifc;
	struct LIFREQ lifreq;
	struct in_addr in4;
	struct in6_addr in6;
	char *buf = NULL, *cp, *cplim;
	static unsigned int bufsiz = 4095;
	int s, cpsize, n;

	/* Get interface list from system. */
	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
		goto cleanup;

	/*
	 * Grow buffer until large enough to contain all interface
	 * descriptions.
	 */
	for (;;) {
		buf = memget(bufsiz);
		if (buf == NULL)
			goto cleanup;
#ifdef SETFAMILYFLAGS
		lifc.lifc_family = AF_UNSPEC;	/*%< request all families */
		lifc.lifc_flags = 0;
#endif
		lifc.lifc_len = bufsiz;
		lifc.lifc_buf = buf;
		if ((n = ioctl(s, SIOCGLIFCONF, (char *)&lifc)) != -1) {
			/*
			 * Some OS's just return what will fit rather
			 * than set EINVAL if the buffer is too small
			 * to fit all the interfaces in.  If 
			 * lifc.lifc_len is too near to the end of the
			 * buffer we will grow it just in case and
			 * retry.
			 */
			if (lifc.lifc_len + 2 * sizeof(lifreq) < bufsiz)
				break;
		}
		if ((n == -1) && errno != EINVAL)
			goto cleanup;

		if (bufsiz > 1000000)
			goto cleanup;

		memput(buf, bufsiz);
		bufsiz += 4096;
	}

	/* Parse system's interface list. */
	cplim = buf + lifc.lifc_len;    /*%< skip over if's with big ifr_addr's */
	for (cp = buf;
	     (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;
	     cp += cpsize) {
		memcpy(&lifreq, cp, sizeof lifreq);
#ifdef HAVE_SA_LEN
#ifdef FIX_ZERO_SA_LEN
		if (lifreq.lifr_addr.sa_len == 0)
			lifreq.lifr_addr.sa_len = 16;
#endif
#ifdef HAVE_MINIMUM_IFREQ
		cpsize = sizeof lifreq;
		if (lifreq.lifr_addr.sa_len > sizeof (struct sockaddr))
			cpsize += (int)lifreq.lifr_addr.sa_len -
				(int)(sizeof (struct sockaddr));
#else
		cpsize = sizeof lifreq.lifr_name + lifreq.lifr_addr.sa_len;
#endif /* HAVE_MINIMUM_IFREQ */
#elif defined SIOCGIFCONF_ADDR
		cpsize = sizeof lifreq;
#else
		cpsize = sizeof lifreq.lifr_name;
		/* XXX maybe this should be a hard error? */
		if (ioctl(s, SIOCGLIFADDR, (char *)&lifreq) < 0)
			continue;
#endif
		switch (lifreq.lifr_addr.ss_family) {
		case AF_INET:
			if (*have_v4 == 0) {
				memcpy(&in4,
				       &((struct sockaddr_in *)
				       &lifreq.lifr_addr)->sin_addr,
				       sizeof in4);
				if (in4.s_addr == INADDR_ANY)
					break;
				n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq);
				if (n < 0)
					break;
				if ((lifreq.lifr_flags & IFF_UP) == 0)
					break;
				*have_v4 = 1;
			} 
			break;
		case AF_INET6:
			if (*have_v6 == 0) {
				memcpy(&in6,
				       &((struct sockaddr_in6 *)
				       &lifreq.lifr_addr)->sin6_addr, sizeof in6);
				if (memcmp(&in6, &in6addr_any, sizeof in6) == 0)
					break;
				n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq);
				if (n < 0)
					break;
				if ((lifreq.lifr_flags & IFF_UP) == 0)
					break;
				*have_v6 = 1;
			}
			break;
		}
	}
	if (buf != NULL)
		memput(buf, bufsiz);
	close(s);
	/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
	return;
 cleanup:
	if (buf != NULL)
		memput(buf, bufsiz);
	if (s != -1)
		close(s);
	/* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */
	return;
}