2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include "libuutil_common.h"
2N/A
2N/A#include <string.h>
2N/A
2N/A/*
2N/A * We require names of the form:
2N/A * [provider,]identifier[/[provider,]identifier]...
2N/A *
2N/A * Where provider is either a stock symbol (SUNW) or a java-style reversed
2N/A * domain name (com.sun).
2N/A *
2N/A * Both providers and identifiers must start with a letter, and may
2N/A * only contain alphanumerics, dashes, and underlines. Providers
2N/A * may also contain periods.
2N/A *
2N/A * Note that we do _not_ use the macros in <ctype.h>, since they are affected
2N/A * by the current locale settings.
2N/A */
2N/A
2N/A#define IS_ALPHA(c) \
2N/A (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
2N/A
2N/A#define IS_DIGIT(c) \
2N/A ((c) >= '0' && (c) <= '9')
2N/A
2N/Astatic int
2N/Ais_valid_ident(const char *s, const char *e, int allowdot)
2N/A{
2N/A char c;
2N/A
2N/A if (s >= e)
2N/A return (0); /* name is empty */
2N/A
2N/A c = *s++;
2N/A if (!IS_ALPHA(c))
2N/A return (0); /* does not start with letter */
2N/A
2N/A while (s < e && (c = *s++) != 0) {
2N/A if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' ||
2N/A (allowdot && c == '.'))
2N/A continue;
2N/A return (0); /* invalid character */
2N/A }
2N/A return (1);
2N/A}
2N/A
2N/Astatic int
2N/Ais_valid_component(const char *b, const char *e, uint_t flags)
2N/A{
2N/A char *sp;
2N/A
2N/A if (flags & UU_NAME_DOMAIN) {
2N/A sp = strchr(b, ',');
2N/A if (sp != NULL && sp < e) {
2N/A if (!is_valid_ident(b, sp, 1))
2N/A return (0);
2N/A b = sp + 1;
2N/A }
2N/A }
2N/A
2N/A return (is_valid_ident(b, e, 0));
2N/A}
2N/A
2N/Aint
2N/Auu_check_name(const char *name, uint_t flags)
2N/A{
2N/A const char *end = name + strlen(name);
2N/A const char *p;
2N/A
2N/A if (flags & ~(UU_NAME_DOMAIN | UU_NAME_PATH)) {
2N/A uu_set_error(UU_ERROR_UNKNOWN_FLAG);
2N/A return (-1);
2N/A }
2N/A
2N/A if (!(flags & UU_NAME_PATH)) {
2N/A if (!is_valid_component(name, end, flags))
2N/A goto bad;
2N/A return (0);
2N/A }
2N/A
2N/A while ((p = strchr(name, '/')) != NULL) {
2N/A if (!is_valid_component(name, p - 1, flags))
2N/A goto bad;
2N/A name = p + 1;
2N/A }
2N/A if (!is_valid_component(name, end, flags))
2N/A goto bad;
2N/A
2N/A return (0);
2N/A
2N/Abad:
2N/A uu_set_error(UU_ERROR_INVALID_ARGUMENT);
2N/A return (-1);
2N/A}