Ejemplo n.º 1
0
int
uu_check_name(const char *name, uint32_t flags)
{
	const char *end = name + strlen(name);
	const char *p;

	if (flags & ~(UU_NAME_DOMAIN | UU_NAME_PATH)) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (-1);
	}

	if (!(flags & UU_NAME_PATH)) {
		if (!is_valid_component(name, end, flags))
			goto bad;
		return (0);
	}

	while ((p = strchr(name, '/')) != NULL) {
		if (!is_valid_component(name, p - 1, flags))
			goto bad;
		name = p + 1;
	}
	if (!is_valid_component(name, end, flags))
		goto bad;

	return (0);

bad:
	uu_set_error(UU_ERROR_INVALID_ARGUMENT);
	return (-1);
}
Ejemplo n.º 2
0
uu_list_t *
uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
{
    uu_list_t *lp, *next, *prev;

    if (flags & ~(UU_LIST_DEBUG | UU_LIST_SORTED)) {
        uu_set_error(UU_ERROR_UNKNOWN_FLAG);
        return (NULL);
    }

    if ((flags & UU_LIST_SORTED) && pp->ulp_cmp == NULL) {
        if (pp->ulp_debug)
            uu_panic("uu_list_create(%p, ...): requested "
                     "UU_LIST_SORTED, but pool has no comparison func\n",
                     (void *)pp);
        uu_set_error(UU_ERROR_NOT_SUPPORTED);
        return (NULL);
    }

    lp = uu_zalloc(sizeof (*lp));
    if (lp == NULL) {
        uu_set_error(UU_ERROR_NO_MEMORY);
        return (NULL);
    }

    lp->ul_pool = pp;
    lp->ul_parent_enc = UU_PTR_ENCODE(parent);
    lp->ul_offset = pp->ulp_nodeoffset;
    lp->ul_debug = pp->ulp_debug || (flags & UU_LIST_DEBUG);
    lp->ul_sorted = (flags & UU_LIST_SORTED);
    lp->ul_numnodes = 0;
    lp->ul_index = (pp->ulp_last_index = INDEX_NEXT(pp->ulp_last_index));

    lp->ul_null_node.uln_next = &lp->ul_null_node;
    lp->ul_null_node.uln_prev = &lp->ul_null_node;

    lp->ul_null_walk.ulw_next = &lp->ul_null_walk;
    lp->ul_null_walk.ulw_prev = &lp->ul_null_walk;

    (void) pthread_mutex_lock(&pp->ulp_lock);
    next = &pp->ulp_null_list;
    prev = UU_PTR_DECODE(next->ul_prev_enc);
    lp->ul_next_enc = UU_PTR_ENCODE(next);
    lp->ul_prev_enc = UU_PTR_ENCODE(prev);
    next->ul_prev_enc = UU_PTR_ENCODE(lp);
    prev->ul_next_enc = UU_PTR_ENCODE(lp);
    (void) pthread_mutex_unlock(&pp->ulp_lock);

    return (lp);
}
Ejemplo n.º 3
0
uu_dprintf_t *
uu_dprintf_create(const char *name, uu_dprintf_severity_t severity,
    uint_t flags)
{
	uu_dprintf_t *D;

	if (uu_check_name(name, UU_NAME_DOMAIN) == -1) {
		uu_set_error(UU_ERROR_INVALID_ARGUMENT);
		return (NULL);
	}

	if ((D = uu_zalloc(sizeof (uu_dprintf_t))) == NULL)
		return (NULL);

	if (name != NULL) {
		D->uud_name = strdup(name);
		if (D->uud_name == NULL) {
			uu_free(D);
			return (NULL);
		}
	} else {
		D->uud_name = NULL;
	}

	D->uud_severity = severity;
	D->uud_flags = flags;

	return (D);
}
Ejemplo n.º 4
0
uu_avl_pool_t *
uu_avl_pool_create(const char *name, size_t objsize, size_t nodeoffset,
    uu_compare_fn_t *compare_func, uint32_t flags)
{
	uu_avl_pool_t *pp, *next, *prev;

	if (name == NULL ||
	    uu_check_name(name, UU_NAME_DOMAIN) == -1 ||
	    nodeoffset + sizeof (uu_avl_node_t) > objsize ||
	    compare_func == NULL) {
		uu_set_error(UU_ERROR_INVALID_ARGUMENT);
		return (NULL);
	}

	if (flags & ~UU_AVL_POOL_DEBUG) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (NULL);
	}

	pp = uu_zalloc(sizeof (uu_avl_pool_t));
	if (pp == NULL) {
		uu_set_error(UU_ERROR_NO_MEMORY);
		return (NULL);
	}

	(void) strlcpy(pp->uap_name, name, sizeof (pp->uap_name));
	pp->uap_nodeoffset = nodeoffset;
	pp->uap_objsize = objsize;
	pp->uap_cmp = compare_func;
	if (flags & UU_AVL_POOL_DEBUG)
		pp->uap_debug = 1;
	pp->uap_last_index = 0;

	(void) pthread_mutex_init(&pp->uap_lock, NULL);

	pp->uap_null_avl.ua_next_enc = UU_PTR_ENCODE(&pp->uap_null_avl);
	pp->uap_null_avl.ua_prev_enc = UU_PTR_ENCODE(&pp->uap_null_avl);

	(void) pthread_mutex_lock(&uu_apool_list_lock);
	pp->uap_next = next = &uu_null_apool;
	pp->uap_prev = prev = next->uap_prev;
	next->uap_prev = pp;
	prev->uap_next = pp;
	(void) pthread_mutex_unlock(&uu_apool_list_lock);

	return (pp);
}
Ejemplo n.º 5
0
uu_avl_walk_t *
uu_avl_walk_start(uu_avl_t *ap, uint32_t flags)
{
	uu_avl_walk_t *wp;

	if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (NULL);
	}

	wp = uu_zalloc(sizeof (*wp));
	if (wp == NULL) {
		uu_set_error(UU_ERROR_NO_MEMORY);
		return (NULL);
	}

	_avl_walk_init(wp, ap, flags);
	return (wp);
}
Ejemplo n.º 6
0
uu_avl_t *
uu_avl_create(uu_avl_pool_t *pp, void *parent, uint32_t flags)
{
	uu_avl_t *ap, *next, *prev;

	if (flags & ~UU_AVL_DEBUG) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (NULL);
	}

	ap = uu_zalloc(sizeof (*ap));
	if (ap == NULL) {
		uu_set_error(UU_ERROR_NO_MEMORY);
		return (NULL);
	}

	ap->ua_pool = pp;
	ap->ua_parent_enc = UU_PTR_ENCODE(parent);
	ap->ua_debug = pp->uap_debug || (flags & UU_AVL_DEBUG);
	ap->ua_index = (pp->uap_last_index = INDEX_NEXT(pp->uap_last_index));

	avl_create(&ap->ua_tree, &uu_avl_node_compare, pp->uap_objsize,
	    pp->uap_nodeoffset);

	ap->ua_null_walk.uaw_next = &ap->ua_null_walk;
	ap->ua_null_walk.uaw_prev = &ap->ua_null_walk;

	(void) pthread_mutex_lock(&pp->uap_lock);
	next = &pp->uap_null_avl;
	prev = UU_PTR_DECODE(next->ua_prev_enc);
	ap->ua_next_enc = UU_PTR_ENCODE(next);
	ap->ua_prev_enc = UU_PTR_ENCODE(prev);
	next->ua_prev_enc = UU_PTR_ENCODE(ap);
	prev->ua_next_enc = UU_PTR_ENCODE(ap);
	(void) pthread_mutex_unlock(&pp->uap_lock);

	return (ap);
}
Ejemplo n.º 7
0
static int
strtoint(const char *s_arg, uint64_t *out, uint32_t base, int sign)
{
	const unsigned char *s = (const unsigned char *)s_arg;

	uint64_t val = 0;
	uint64_t multmax;

	unsigned c, i;

	int neg = 0;

	int bad_digit = 0;
	int bad_char = 0;
	int overflow = 0;

	if (s == NULL || base == 1 || base > MAX_BASE) {
		uu_set_error(UU_ERROR_INVALID_ARGUMENT);
		return (-1);
	}

	while ((c = *s) != 0 && isspace(c))
		s++;

	switch (c) {
	case '-':
		if (!sign)
			overflow = 1;		/* becomes underflow below */
		neg = 1;
		/*FALLTHRU*/
	case '+':
		c = *++s;
		break;
	default:
		break;
	}

	if (c == '\0') {
		uu_set_error(UU_ERROR_EMPTY);
		return (-1);
	}

	if (base == 0) {
		if (c != '0')
			base = 10;
		else if (s[1] == 'x' || s[1] == 'X')
			base = 16;
		else
			base = 8;
	}

	if (base == 16 && c == '0' && (s[1] == 'x' || s[1] == 'X'))
		c = *(s += 2);

	if ((val = CTOI(c)) >= base) {
		if (IS_DIGIT(c))
			bad_digit = 1;
		else
			bad_char = 1;
		val = 0;
	}

	multmax = (uint64_t)UINT64_MAX / (uint64_t)base;

	for (c = *++s; c != '\0'; c = *++s) {
		if ((i = CTOI(c)) >= base) {
			if (isspace(c))
				break;
			if (IS_DIGIT(c))
				bad_digit = 1;
			else
				bad_char = 1;
			i = 0;
		}

		if (val > multmax)
			overflow = 1;

		val *= base;
		if ((uint64_t)UINT64_MAX - val < (uint64_t)i)
			overflow = 1;

		val += i;
	}

	while ((c = *s) != 0) {
		if (!isspace(c))
			bad_char = 1;
		s++;
	}

	if (sign) {
		if (neg) {
			if (val > -(uint64_t)INT64_MIN)
				overflow = 1;
		} else {
			if (val > INT64_MAX)
				overflow = 1;
		}
	}

	if (neg)
		val = -val;

	if (bad_char | bad_digit | overflow) {
		if (bad_char)
			uu_set_error(UU_ERROR_INVALID_CHAR);
		else if (bad_digit)
			uu_set_error(UU_ERROR_INVALID_DIGIT);
		else if (overflow) {
			if (neg)
				uu_set_error(UU_ERROR_UNDERFLOW);
			else
				uu_set_error(UU_ERROR_OVERFLOW);
		}
		return (-1);
	}

	*out = val;
	return (0);
}
Ejemplo n.º 8
0
int
uu_strtouint(const char *s, void *v, size_t sz, int base,
    uint64_t min, uint64_t max)
{
	uint64_t val;

	if (min > max)
		goto bad_argument;

	switch (sz) {
	case 1:
		if (max > UINT8_MAX)
			goto bad_argument;
		break;
	case 2:
		if (max > UINT16_MAX)
			goto bad_argument;
		break;
	case 4:
		if (max > UINT32_MAX)
			goto bad_argument;
		break;
	case 8:
		if (max > UINT64_MAX)
			goto bad_argument;
		break;
	default:
		goto bad_argument;
	}

	if (min == 0 && max == 0) {
		/* we have to be careful, since << can overflow */
		max = (1ULL << (8 * sz - 1)) * 2 - 1;
	}

	if (strtoint(s, &val, base, 0) == -1)
		return (-1);

	if (val < min) {
		uu_set_error(UU_ERROR_UNDERFLOW);
		return (-1);
	} else if (val > max) {
		uu_set_error(UU_ERROR_OVERFLOW);
		return (-1);
	}

	switch (sz) {
	case 1:
		*(uint8_t *)v = val;
		return (0);
	case 2:
		*(uint16_t *)v = val;
		return (0);
	case 4:
		*(uint32_t *)v = val;
		return (0);
	case 8:
		*(uint64_t *)v = val;
		return (0);
	default:
		break;		/* shouldn't happen, fall through */
	}

bad_argument:
	uu_set_error(UU_ERROR_INVALID_ARGUMENT);
	return (-1);
}
Ejemplo n.º 9
0
int
uu_strtoint(const char *s, void *v, size_t sz, int base,
    int64_t min, int64_t max)
{
	uint64_t val_u;
	int64_t val;

	if (min > max)
		goto bad_argument;

	switch (sz) {
	case 1:
		if (max > INT8_MAX || min < INT8_MIN)
			goto bad_argument;
		break;
	case 2:
		if (max > INT16_MAX || min < INT16_MIN)
			goto bad_argument;
		break;
	case 4:
		if (max > INT32_MAX || min < INT32_MIN)
			goto bad_argument;
		break;
	case 8:
		if (max > INT64_MAX || min < INT64_MIN)
			goto bad_argument;
		break;
	default:
		goto bad_argument;
	}

	if (min == 0 && max == 0) {
		min = -(1ULL << (8 * sz - 1));
		max = (1ULL << (8 * sz - 1)) - 1;
	}

	if (strtoint(s, &val_u, base, 1) == -1)
		return (-1);

	val = (int64_t)val_u;

	if (val < min) {
		uu_set_error(UU_ERROR_UNDERFLOW);
		return (-1);
	} else if (val > max) {
		uu_set_error(UU_ERROR_OVERFLOW);
		return (-1);
	}

	switch (sz) {
	case 1:
		*(int8_t *)v = val;
		return (0);
	case 2:
		*(int16_t *)v = val;
		return (0);
	case 4:
		*(int32_t *)v = val;
		return (0);
	case 8:
		*(int64_t *)v = val;
		return (0);
	default:
		break;		/* fall through to bad_argument */
	}

bad_argument:
	uu_set_error(UU_ERROR_INVALID_ARGUMENT);
	return (-1);
}