Example #1
0
static void
dl_iterate_phdr_setup(void)
{
	const AuxInfo *aux;

	_DIAGASSERT(_dlauxinfo() != NULL);

	for (aux = _dlauxinfo(); aux->a_type != AT_NULL; ++aux) {
		switch (aux->a_type) {
		case AT_BASE:
			dlpi_addr = aux->a_v;
			break;
		case AT_PHDR:
			dlpi_phdr = (void *)aux->a_v;
			break;
		case AT_PHNUM:
			_DIAGASSERT(__type_fit(Elf_Half, aux->a_v));
			dlpi_phnum = (Elf_Half)aux->a_v;
			break;
		case AT_SUN_EXECNAME:
			dlpi_name = (void *)aux->a_v;
			break;
		}
	}
}
static bool_t  /* knows nothing about records!  Only about input buffers */
get_input_bytes(RECSTREAM *rstrm, char *addr, u_int len)
{
	u_int current;

	if (rstrm->nonblock) {
		if (len > ((uintptr_t)rstrm->in_boundry - (uintptr_t)rstrm->in_finger))
			return FALSE;
		memcpy(addr, rstrm->in_finger, len);
		rstrm->in_finger += len;
		return TRUE;
	}

	while (len > 0) {
		uintptr_t d = ((uintptr_t)rstrm->in_boundry -
		    (uintptr_t)rstrm->in_finger);
		_DIAGASSERT(__type_fit(u_int, d));
		current = (u_int)d;
		if (current == 0) {
			if (! fill_input_buf(rstrm))
				return (FALSE);
			continue;
		}
		current = (len < current) ? len : current;
		memmove(addr, rstrm->in_finger, current);
		rstrm->in_finger += current;
		addr += current;
		len -= current;
	}
	return (TRUE);
}
static bool_t
xdrrec_putbytes(XDR *xdrs, const char *addr, u_int len)
{
	RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
	size_t current;

	while (len > 0) {
		current = (size_t)((u_long)rstrm->out_boundry -
		    (u_long)rstrm->out_finger);
		current = (len < current) ? len : current;
		memmove(rstrm->out_finger, addr, current);
		rstrm->out_finger += current;
		addr += current;
		_DIAGASSERT(__type_fit(u_int, current));
		len -= (u_int)current;
		if (rstrm->out_finger == rstrm->out_boundry) {
			rstrm->frag_sent = TRUE;
			if (! flush_out(rstrm, FALSE))
				return (FALSE);
		}
	}
	return (TRUE);
}
Example #4
0
/*
 * Converts the number given in 'str', which may be given in a humanized
 * form (as described in humanize_number(3), but with some limitations),
 * to an int64_t without units.
 * In case of success, 0 is returned and *size holds the value.
 * Otherwise, -1 is returned and *size is untouched.
 *
 * TODO: Internationalization, SI units.
 */
int
dehumanize_number(const char *str, int64_t *size)
{
	char *ep, unit;
	const char *delimit;
	long multiplier;
	long long tmp, tmp2;
	size_t len;

	len = strlen(str);
	if (len == 0) {
		errno = EINVAL;
		return -1;
	}

	multiplier = 1;

	unit = str[len - 1];
	if (isalpha((unsigned char)unit)) {
		switch (tolower((unsigned char)unit)) {
		case 'b':
			multiplier = 1;
			break;

		case 'k':
			multiplier = 1024;
			break;

		case 'm':
			multiplier = 1024 * 1024;
			break;

		case 'g':
			multiplier = 1024 * 1024 * 1024;
			break;

		default:
			errno = EINVAL;
			return -1; /* Invalid suffix. */
		}

		delimit = &str[len - 1];
	} else
		delimit = NULL;

	errno = 0;
	tmp = strtoll(str, &ep, 10);
	if (str[0] == '\0' || (ep != delimit && *ep != '\0'))
		return -1; /* Not a number. */
	else if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN))
		return -1; /* Out of range. */

	tmp2 = tmp * multiplier;
	tmp2 = tmp2 / multiplier;
	if (tmp != tmp2) {
		errno = ERANGE;
		return -1; /* Out of range. */
	}
	tmp *= multiplier;
	_DIAGASSERT(__type_fit(int64_t, tmp));
	*size = (int64_t)tmp;

	return 0;
}
Example #5
0
SVCXPRT *
svc_dg_create(int fd, u_int sendsize, u_int recvsize)
{
	SVCXPRT *xprt;
	struct svc_dg_data *su = NULL;
	struct __rpc_sockinfo si;
	struct sockaddr_storage ss;
	socklen_t slen;

	if (!__rpc_fd2sockinfo(fd, &si)) {
		warnx(svc_dg_str, svc_dg_err1);
		return (NULL);
	}
	/*
	 * Find the receive and the send size
	 */
	sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
	recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
	if ((sendsize == 0) || (recvsize == 0)) {
		warnx(svc_dg_str, svc_dg_err2);
		return (NULL);
	}

	xprt = mem_alloc(sizeof (SVCXPRT));
	if (xprt == NULL)
		goto freedata;
	memset(xprt, 0, sizeof (SVCXPRT));

	su = mem_alloc(sizeof (*su));
	if (su == NULL)
		goto freedata;
	su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4;
	if ((rpc_buffer(xprt) = malloc(su->su_iosz)) == NULL)
		goto freedata;
	_DIAGASSERT(__type_fit(u_int, su->su_iosz));
	xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), (u_int)su->su_iosz,
		XDR_DECODE);
	su->su_cache = NULL;
	xprt->xp_fd = fd;
	xprt->xp_p2 = (caddr_t)(void *)su;
	xprt->xp_verf.oa_base = su->su_verfbody;
	svc_dg_ops(xprt);
	xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage);

	slen = sizeof ss;
	if (getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0)
		goto freedata;
	xprt->xp_ltaddr.buf = mem_alloc(sizeof (struct sockaddr_storage));
	xprt->xp_ltaddr.maxlen = sizeof (struct sockaddr_storage);
	xprt->xp_ltaddr.len = slen;
	memcpy(xprt->xp_ltaddr.buf, &ss, slen);

	xprt_register(xprt);
	return (xprt);
freedata:
	(void) warnx(svc_dg_str, __no_mem_str);
	if (xprt) {
		if (su)
			(void) mem_free(su, sizeof (*su));
		(void) mem_free(xprt, sizeof (SVCXPRT));
	}
	return (NULL);
}
/*
 * verifies that the head of the tree in the kernel is the same as the
 * head of the tree we already got, integrating new stuff and removing
 * old stuff, if it's not.
 */
static void
relearnhead(void)
{
	struct sysctlnode *h, *i, *o, qnode;
	size_t si, so;
	int rc, name;
	size_t nlen, olen, ni, oi;
	uint32_t t;

	/*
	 * if there's nothing there, there's no need to expend any
	 * effort
	 */
	if (sysctl_mibroot.sysctl_child == NULL)
		return;

	/*
	 * attempt to pull out the head of the tree, starting with the
	 * size we have now, and looping if we need more (or less)
	 * space
	 */
	si = 0;
	so = sysctl_mibroot.sysctl_clen * sizeof(struct sysctlnode);
	name = CTL_QUERY;
	memset(&qnode, 0, sizeof(qnode));
	qnode.sysctl_flags = SYSCTL_VERSION;
	do {
		si = so;
		h = malloc(si);
		rc = sysctl(&name, 1, h, &so, &qnode, sizeof(qnode));
		if (rc == -1 && errno != ENOMEM)
			return;
		if (si < so)
			free(h);
	} while (si < so);

	/*
	 * order the new copy of the head
	 */
	nlen = so / sizeof(struct sysctlnode);
	qsort(h, nlen, sizeof(struct sysctlnode), compar);

	/*
	 * verify that everything is the same.  if it is, we don't
	 * need to do any more work here.
	 */
	olen = sysctl_mibroot.sysctl_clen;
	rc = (nlen == olen) ? 0 : 1;
	o = sysctl_mibroot.sysctl_child;
	for (ni = 0; rc == 0 && ni < nlen; ni++) {
		if (h[ni].sysctl_num != o[ni].sysctl_num ||
		    h[ni].sysctl_ver != o[ni].sysctl_ver)
			rc = 1;
	}
	if (rc == 0) {
		free(h);
		return;
	}

	/*
	 * something changed.  h will become the new head, and we need
	 * pull over any subtrees we already have if they're the same
	 * version.
	 */
	i = h;
	ni = oi = 0;
	while (ni < nlen && oi < olen) {
		/*
		 * something was inserted or deleted
		 */
		if (SYSCTL_TYPE(i[ni].sysctl_flags) == CTLTYPE_NODE)
			i[ni].sysctl_child = NULL;
		if (i[ni].sysctl_num != o[oi].sysctl_num) {
			if (i[ni].sysctl_num < o[oi].sysctl_num) {
				ni++;
			}
			else {
				free_children(&o[oi]);
				oi++;
			}
			continue;
		}

		/*
		 * same number, but different version, so throw away
		 * any accumulated children
		 */
		if (i[ni].sysctl_ver != o[oi].sysctl_ver)
			free_children(&o[oi]);

		/*
		 * this node is the same, but we only need to
		 * move subtrees.
		 */
		else if (SYSCTL_TYPE(i[ni].sysctl_flags) == CTLTYPE_NODE) {	
			/*
			 * move subtree to new parent
			 */
			i[ni].sysctl_clen = o[oi].sysctl_clen;
			i[ni].sysctl_csize = o[oi].sysctl_csize;
			i[ni].sysctl_child = o[oi].sysctl_child;
			/*
			 * reparent inherited subtree
			 */
			for (t = 0;
			     i[ni].sysctl_child != NULL &&
				     t < i[ni].sysctl_clen;
			     t++)
				i[ni].sysctl_child[t].sysctl_parent = &i[ni];
		}
		ni++;
		oi++;
	}

	/*
	 * left over new nodes need to have empty subtrees cleared
	 */
	while (ni < nlen) {
		if (SYSCTL_TYPE(i[ni].sysctl_flags) == CTLTYPE_NODE)
			i[ni].sysctl_child = NULL;
		ni++;
	}

	/*
	 * left over old nodes need to be cleaned out
	 */
	while (oi < olen) {
		free_children(&o[oi]);
		oi++;
	}

	/*
	 * pop new head in
	 */
	_DIAGASSERT(__type_fit(uint32_t, nlen));
	sysctl_mibroot.sysctl_csize =
	    sysctl_mibroot.sysctl_clen = (uint32_t)nlen;
	sysctl_mibroot.sysctl_child = h;
	free(o);
}