14a5d661aSToomas Soome /*- 24a5d661aSToomas Soome * Copyright (c) 2015 M. Warner Losh 34a5d661aSToomas Soome * All rights reserved. 44a5d661aSToomas Soome * 54a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without 64a5d661aSToomas Soome * modification, are permitted provided that the following conditions 74a5d661aSToomas Soome * are met: 84a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright 94a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer. 104a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 114a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the 124a5d661aSToomas Soome * documentation and/or other materials provided with the distribution. 134a5d661aSToomas Soome * 144a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 154a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 164a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 174a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 184a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 194a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 204a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 214a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 224a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 234a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 244a5d661aSToomas Soome * SUCH DAMAGE. 254a5d661aSToomas Soome * 264a5d661aSToomas Soome * $FreeBSD$ 274a5d661aSToomas Soome */ 284a5d661aSToomas Soome 294a5d661aSToomas Soome /* 304a5d661aSToomas Soome * Note: some comments taken from lib/libc/uuid/uuid_from_string.c 314a5d661aSToomas Soome * Copyright (c) 2002 Marcel Moolenaar 324a5d661aSToomas Soome * Copyright (c) 2002 Hiten Mahesh Pandya 334a5d661aSToomas Soome */ 344a5d661aSToomas Soome 354a5d661aSToomas Soome 364a5d661aSToomas Soome #include <stand.h> 374a5d661aSToomas Soome #include <uuid.h> 384a5d661aSToomas Soome 394a5d661aSToomas Soome static int 404a5d661aSToomas Soome hex2int(int ch) 414a5d661aSToomas Soome { 424a5d661aSToomas Soome if (ch >= '0' && ch <= '9') 434a5d661aSToomas Soome return ch - '0'; 444a5d661aSToomas Soome if (ch >= 'a' && ch <= 'f') 454a5d661aSToomas Soome return 10 + ch - 'a'; 464a5d661aSToomas Soome if (ch >= 'A' && ch <= 'F') 474a5d661aSToomas Soome return 10 + ch - 'A'; 484a5d661aSToomas Soome return 16; 494a5d661aSToomas Soome } 504a5d661aSToomas Soome 514a5d661aSToomas Soome static uint32_t 524a5d661aSToomas Soome fromhex(const char *s, int len, int *ok) 534a5d661aSToomas Soome { 544a5d661aSToomas Soome uint32_t v; 554a5d661aSToomas Soome int i, h; 564a5d661aSToomas Soome 574a5d661aSToomas Soome if (!*ok) 584a5d661aSToomas Soome return 0; 594a5d661aSToomas Soome v = 0; 60*66f6ec15SToomas Soome for (i = 0; i < len; i++) { 614a5d661aSToomas Soome h = hex2int(s[i]); 624a5d661aSToomas Soome if (h == 16) { 634a5d661aSToomas Soome *ok = 0; 644a5d661aSToomas Soome return v; 654a5d661aSToomas Soome } 664a5d661aSToomas Soome v = (v << 4) | h; 674a5d661aSToomas Soome } 684a5d661aSToomas Soome return v; 694a5d661aSToomas Soome } 704a5d661aSToomas Soome 714a5d661aSToomas Soome /* 724a5d661aSToomas Soome * uuid_from_string() - convert a string representation of an UUID into 734a5d661aSToomas Soome * a binary representation. 744a5d661aSToomas Soome * See also: 754a5d661aSToomas Soome * http://www.opengroup.org/onlinepubs/009629399/uuid_from_string.htm 764a5d661aSToomas Soome * 774a5d661aSToomas Soome * NOTE: The sequence field is in big-endian, while the time fields are in 784a5d661aSToomas Soome * native byte order. 794a5d661aSToomas Soome * 804a5d661aSToomas Soome * 01234567-89ab-cdef-0123-456789abcdef 814a5d661aSToomas Soome * 000000000011111111112222222222333333 824a5d661aSToomas Soome * 012345678901234567890123456789012345 834a5d661aSToomas Soome * - - - - 844a5d661aSToomas Soome * hhhhhhhh-hhhh-hhhh-bbbb-bbbbbbbbbbbb 854a5d661aSToomas Soome * 864a5d661aSToomas Soome */ 874a5d661aSToomas Soome void 884a5d661aSToomas Soome uuid_from_string(const char *s, uuid_t *u, uint32_t *status) 894a5d661aSToomas Soome { 904a5d661aSToomas Soome int ok = 1; 914a5d661aSToomas Soome int n; 924a5d661aSToomas Soome 934a5d661aSToomas Soome if (s == NULL || *s == '\0') { 944a5d661aSToomas Soome uuid_create_nil(u, status); 954a5d661aSToomas Soome return; 964a5d661aSToomas Soome } 974a5d661aSToomas Soome 984a5d661aSToomas Soome if (status != NULL) 994a5d661aSToomas Soome *status = uuid_s_invalid_string_uuid; 1004a5d661aSToomas Soome if (strlen(s) != 36) 1014a5d661aSToomas Soome return; 1024a5d661aSToomas Soome /* Only support new format, check for all the right dashes */ 1034a5d661aSToomas Soome if (s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') 1044a5d661aSToomas Soome return; 1054a5d661aSToomas Soome /* native byte order */ 1064a5d661aSToomas Soome u->time_low = fromhex(s , 8, &ok); 1074a5d661aSToomas Soome u->time_mid = fromhex(s + 9, 4, &ok); 1084a5d661aSToomas Soome u->time_hi_and_version = fromhex(s + 14, 4, &ok); 1094a5d661aSToomas Soome /* Big endian, but presented as a whole number so decode as such */ 1104a5d661aSToomas Soome u->clock_seq_hi_and_reserved = fromhex(s + 19, 2, &ok); 1114a5d661aSToomas Soome u->clock_seq_low = fromhex(s + 21, 2, &ok); 1124a5d661aSToomas Soome u->node[0] = fromhex(s + 24, 2, &ok); 1134a5d661aSToomas Soome u->node[1] = fromhex(s + 26, 2, &ok); 1144a5d661aSToomas Soome u->node[2] = fromhex(s + 28, 2, &ok); 1154a5d661aSToomas Soome u->node[3] = fromhex(s + 30, 2, &ok); 1164a5d661aSToomas Soome u->node[4] = fromhex(s + 32, 2, &ok); 1174a5d661aSToomas Soome u->node[5] = fromhex(s + 34, 2, &ok); 1184a5d661aSToomas Soome if (!ok) 1194a5d661aSToomas Soome return; 1204a5d661aSToomas Soome 1214a5d661aSToomas Soome /* We have a successful scan. Check semantics... */ 1224a5d661aSToomas Soome n = u->clock_seq_hi_and_reserved; 1234a5d661aSToomas Soome if ((n & 0x80) != 0x00 && /* variant 0? */ 1244a5d661aSToomas Soome (n & 0xc0) != 0x80 && /* variant 1? */ 1254a5d661aSToomas Soome (n & 0xe0) != 0xc0) { /* variant 2? */ 1264a5d661aSToomas Soome if (status != NULL) 1274a5d661aSToomas Soome *status = uuid_s_bad_version; 1284a5d661aSToomas Soome } else { 1294a5d661aSToomas Soome if (status != NULL) 1304a5d661aSToomas Soome *status = uuid_s_ok; 1314a5d661aSToomas Soome } 1324a5d661aSToomas Soome } 133