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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "libuutil_common.h" 30 31 #include <string.h> 32 33 /* 34 * We require names of the form: 35 * [provider,]identifier[/[provider,]identifier]... 36 * 37 * Where provider is either a stock symbol (SUNW) or a java-style reversed 38 * domain name (com.sun). 39 * 40 * Both providers and identifiers must start with a letter, and may 41 * only contain alphanumerics, dashes, and underlines. Providers 42 * may also contain periods. 43 * 44 * Note that we do _not_ use the macros in <ctype.h>, since they are affected 45 * by the current locale settings. 46 */ 47 48 #define IS_ALPHA(c) \ 49 (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) 50 51 #define IS_DIGIT(c) \ 52 ((c) >= '0' && (c) <= '9') 53 54 static int 55 is_valid_ident(const char *s, const char *e, int allowdot) 56 { 57 char c; 58 59 if (s >= e) 60 return (0); /* name is empty */ 61 62 c = *s++; 63 if (!IS_ALPHA(c)) 64 return (0); /* does not start with letter */ 65 66 while (s < e && (c = *s++) != 0) { 67 if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' || 68 (allowdot && c == '.')) 69 continue; 70 return (0); /* invalid character */ 71 } 72 return (1); 73 } 74 75 static int 76 is_valid_component(const char *b, const char *e, uint_t flags) 77 { 78 char *sp; 79 80 if (flags & UU_NAME_DOMAIN) { 81 sp = strchr(b, ','); 82 if (sp != NULL && sp < e) { 83 if (!is_valid_ident(b, sp, 1)) 84 return (0); 85 b = sp + 1; 86 } 87 } 88 89 return (is_valid_ident(b, e, 0)); 90 } 91 92 int 93 uu_check_name(const char *name, uint_t flags) 94 { 95 const char *end = name + strlen(name); 96 const char *p; 97 98 if (flags & ~(UU_NAME_DOMAIN | UU_NAME_PATH)) { 99 uu_set_error(UU_ERROR_UNKNOWN_FLAG); 100 return (-1); 101 } 102 103 if (!(flags & UU_NAME_PATH)) { 104 if (!is_valid_component(name, end, flags)) 105 goto bad; 106 return (0); 107 } 108 109 while ((p = strchr(name, '/')) != NULL) { 110 if (!is_valid_component(name, p - 1, flags)) 111 goto bad; 112 name = p + 1; 113 } 114 if (!is_valid_component(name, end, flags)) 115 goto bad; 116 117 return (0); 118 119 bad: 120 uu_set_error(UU_ERROR_INVALID_ARGUMENT); 121 return (-1); 122 } 123