uuid_from_string.c revision 330897
155714Skris/*- 255714Skris * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 355714Skris * 455714Skris * Copyright (c) 2002 Marcel Moolenaar 555714Skris * Copyright (c) 2002 Hiten Mahesh Pandya 655714Skris * All rights reserved. 755714Skris * 855714Skris * Redistribution and use in source and binary forms, with or without 955714Skris * modification, are permitted provided that the following conditions 1055714Skris * are met: 1155714Skris * 1. Redistributions of source code must retain the above copyright 1255714Skris * notice, this list of conditions and the following disclaimer. 1355714Skris * 2. Redistributions in binary form must reproduce the above copyright 1455714Skris * notice, this list of conditions and the following disclaimer in the 1555714Skris * documentation and/or other materials provided with the distribution. 1655714Skris * 1755714Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1855714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1955714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2055714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2155714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2255714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26142425Snectar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27109998Smarkm * SUCH DAMAGE. 28109998Smarkm * 29109998Smarkm * $FreeBSD: stable/11/lib/libc/uuid/uuid_from_string.c 330897 2018-03-14 03:19:51Z eadler $ 30109998Smarkm */ 31109998Smarkm 32238405Sjkim#include <stdio.h> 33109998Smarkm#include <string.h> 34109998Smarkm#include <uuid.h> 35109998Smarkm 36109998Smarkm/* 37109998Smarkm * uuid_from_string() - convert a string representation of an UUID into 38109998Smarkm * a binary representation. 39109998Smarkm * See also: 40109998Smarkm * http://www.opengroup.org/onlinepubs/009629399/uuid_from_string.htm 41109998Smarkm * 42109998Smarkm * NOTE: The sequence field is in big-endian, while the time fields are in 43109998Smarkm * native byte order. 44109998Smarkm */ 45109998Smarkmvoid 46109998Smarkmuuid_from_string(const char *s, uuid_t *u, uint32_t *status) 47109998Smarkm{ 48109998Smarkm int n; 4955714Skris 5055714Skris /* Short-circuit 2 special cases: NULL pointer and empty string. */ 51205128Ssimon if (s == NULL || *s == '\0') { 52205128Ssimon uuid_create_nil(u, status); 53205128Ssimon return; 54205128Ssimon } 5555714Skris 5659191Skris /* Assume the worst. */ 5755714Skris if (status != NULL) 5855714Skris *status = uuid_s_invalid_string_uuid; 5955714Skris 6055714Skris /* The UUID string representation has a fixed length. */ 6155714Skris if (strlen(s) != 36) 6255714Skris return; 6355714Skris 6455714Skris /* 6555714Skris * We only work with "new" UUIDs. New UUIDs have the form: 6655714Skris * 01234567-89ab-cdef-0123-456789abcdef 6755714Skris * The so called "old" UUIDs, which we don't support, have the form: 6855714Skris * 0123456789ab.cd.ef.01.23.45.67.89.ab 6955714Skris */ 7055714Skris if (s[8] != '-') 7155714Skris return; 7255714Skris 7355714Skris n = sscanf(s, 7455714Skris "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", 7555714Skris &u->time_low, &u->time_mid, &u->time_hi_and_version, 7655714Skris &u->clock_seq_hi_and_reserved, &u->clock_seq_low, &u->node[0], 7755714Skris &u->node[1], &u->node[2], &u->node[3], &u->node[4], &u->node[5]); 78111147Snectar 79111147Snectar /* Make sure we have all conversions. */ 80111147Snectar if (n != 11) 81111147Snectar return; 82111147Snectar 8355714Skris /* We have a successful scan. Check semantics... */ 8455714Skris n = u->clock_seq_hi_and_reserved; 85160814Ssimon if ((n & 0x80) != 0x00 && /* variant 0? */ 8655714Skris (n & 0xc0) != 0x80 && /* variant 1? */ 87160814Ssimon (n & 0xe0) != 0xc0) { /* variant 2? */ 88111147Snectar if (status != NULL) 89111147Snectar *status = uuid_s_bad_version; 90111147Snectar } else { 91111147Snectar if (status != NULL) 92111147Snectar *status = uuid_s_ok; 93111147Snectar } 94111147Snectar} 95111147Snectar