1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "libuutil_common.h" 28 29 #include <string.h> 30 31 /* 32 * We require names of the form: 33 * [provider,]identifier[/[provider,]identifier]... 34 * 35 * Where provider is either a stock symbol (SUNW) or a java-style reversed 36 * domain name (com.sun). 37 * 38 * Both providers and identifiers must start with a letter, and may 39 * only contain alphanumerics, dashes, and underlines. Providers 40 * may also contain periods. 41 * 42 * Note that we do _not_ use the macros in <ctype.h>, since they are affected 43 * by the current locale settings. 44 */ 45 46 #define IS_ALPHA(c) \ 47 (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) 48 49 #define IS_DIGIT(c) \ 50 ((c) >= '0' && (c) <= '9') 51 52 static int 53 is_valid_ident(const char *s, const char *e, int allowdot) 54 { 55 char c; 56 57 if (s >= e) 58 return (0); /* name is empty */ 59 60 c = *s++; 61 if (!IS_ALPHA(c)) 62 return (0); /* does not start with letter */ 63 64 while (s < e && (c = *s++) != 0) { 65 if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' || 66 (allowdot && c == '.')) 67 continue; 68 return (0); /* invalid character */ 69 } 70 return (1); 71 } 72 73 static int 74 is_valid_component(const char *b, const char *e, uint_t flags) 75 { 76 char *sp; 77 78 if (flags & UU_NAME_DOMAIN) { 79 sp = strchr(b, ','); 80 if (sp != NULL && sp < e) { 81 if (!is_valid_ident(b, sp, 1)) 82 return (0); 83 b = sp + 1; 84 } 85 } 86 87 return (is_valid_ident(b, e, 0)); 88 } 89 90 int 91 uu_check_name(const char *name, uint_t flags) 92 { 93 const char *end = name + strlen(name); 94 const char *p; 95 96 if (flags & ~(UU_NAME_DOMAIN | UU_NAME_PATH)) { 97 uu_set_error(UU_ERROR_UNKNOWN_FLAG); 98 return (-1); 99 } 100 101 if (!(flags & UU_NAME_PATH)) { 102 if (!is_valid_component(name, end, flags)) 103 goto bad; 104 return (0); 105 } 106 107 while ((p = strchr(name, '/')) != NULL) { 108 if (!is_valid_component(name, p - 1, flags)) 109 goto bad; 110 name = p + 1; 111 } 112 if (!is_valid_component(name, end, flags)) 113 goto bad; 114 115 return (0); 116 117 bad: 118 uu_set_error(UU_ERROR_INVALID_ARGUMENT); 119 return (-1); 120 } 121