pax_global_header00006660000000000000000000000064147256125360014525gustar00rootroot0000000000000052 comment=7ad624132ebcf5570f08ffb3d85edb5d3f664c3c ossp-uuid-UUID_1_6_4/000077500000000000000000000000001472561253600144555ustar00rootroot00000000000000ossp-uuid-UUID_1_6_4/.builds/000077500000000000000000000000001472561253600160155ustar00rootroot00000000000000ossp-uuid-UUID_1_6_4/.builds/freebsd-latest.yml000066400000000000000000000004341472561253600214450ustar00rootroot00000000000000# SPDX-License-Identifier: 0BSD image: freebsd/latest packages: - gmake - autoconf - automake - libtool tasks: - build: | cd ossp-uuid autoreconf -fi ./configure --with-cxx --with-dce # TODO: --with-perl make make check sudo make install ossp-uuid-UUID_1_6_4/.builds/openbsd-latest.yml000066400000000000000000000015501472561253600214650ustar00rootroot00000000000000# SPDX-License-Identifier: 0BSD image: openbsd/latest packages: - gmake - libtool tasks: - prep-autohell: | doas pkg_add $(doas pkg_add autoconf 2>&1 | grep -o 'autoconf-[0-9a-z.]*' | sort -rV | { read -r pkg; echo $pkg; }) \ $(doas pkg_add automake 2>&1 | grep -o 'automake-[0-9a-z.]*' | sort -rV | { read -r pkg; echo $pkg; }) printf 'export %s_VERSION=%s\n' AUTOCONF "$(printf '%s\n' /usr/local/bin/autoreconf-* | sort -rV | { IFS=- read -r _ v; echo $v; })" \ AUTOMAKE "$(printf '%s\n' /usr/local/bin/automake-* | sort -rV | { IFS=- read -r _ v; echo $v; })" >> .buildenv - build: | cd ossp-uuid autoreconf-$AUTOCONF_VERSION -fi ./configure --with-cxx --with-dce --with-perl --with-perl-compat --with-libname=libgaming make make check doas make install ossp-uuid-UUID_1_6_4/.builds/sid.yml000066400000000000000000000047441472561253600173300ustar00rootroot00000000000000# SPDX-License-Identifier: 0BSD image: debian/sid secrets: - f226accf-2ed4-4d94-ab0e-35f195dd8273 # ossp-uuid SSH key packages: - clang - lld - perl - autoconf - automake - libtool-bin - libmd-dev - groff - ghostscript tasks: - autoreconf: | autoreconf -fi ossp-uuid mkdir -p ossp-uuid/gcc ossp-uuid/clang - build-gcc: | cd ossp-uuid/gcc ../configure --with-cxx --with-dce --with-perl --with-perl-compat make make check make distclean - build-clang: | cd ossp-uuid/clang ../configure --with-cxx --with-dce --with-perl --with-perl-compat CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld make make check - install: | sudo make -C ossp-uuid/clang install - manual: | sudo sh -c 'curl https://git.sr.ht/~nabijaczleweli/groff-1.23-unfucking/blob/trunk/mdoc.local >> /etc/groff/mdoc.local' git -C ossp-uuid/ worktree add ../ossp-uuid-man man cd ossp-uuid-man git ls-tree -z --name-only HEAD | xargs -0 rm -r rm -rf ../ossp-uuid/autom4te.cache find ../ossp-uuid -name '*.[1-8]' -exec cp -vt . {} + find ../ossp-uuid -name '*.[1-8]perl' -exec cp -vt . {} + || : sed -e 's/…/.../g' $(printf '%s\n' *.[0-8]* | awk -F. '{print substr($2, 2) "\t" $2 "\t" $0}' | tr - _ | sort | tr _ - | cut -f3) | groff -K utf8 -tpe -mdoc -Tps -dpaper=a4 -P-pa4 > ossp-uuid.ps ps2pdf ossp-uuid.ps ossp-uuid.pdf git add . git config user.email "nabijaczleweli/autouploader@nabijaczleweli.xyz" git config user.name "наб autouploader" git commit -m "Manpage update by job $JOB_ID" || exit 0 git remote set-url origin 'git@git.sr.ht:~nabijaczleweli/ossp-uuid' ssh-keyscan git.sr.ht > ~/.ssh/known_hosts git push # - void: | # curl https://repo-default.voidlinux.org/live/current/sha256sum.txt | grep -w tar | grep -w x86_64 | grep -m1 musl > sha256sum.txt # curl -SL https://repo-default.voidlinux.org/live/current/"$(awk -F'[( )]' '{print $3}' < sha256sum.txt)" | tar -xJ # cp /etc/resolv.conf etc # printf '%s\n' 'xbps-install -yS' \ # 'xbps-install -yu xbps' \ # 'xbps-install -y make gcc pkgconf fuse3-devel libcurl-devel' \ # 'mount -t devtmpfs devtmpfs /dev' \ # 'make -C ossp-uuid clean' \ # 'make -C ossp-uuid VERSION=sid.yml SOURCE_DATE_EPOCH=0 all check' \ # 'make -C ossp-uuid install' | # sudo chroot . sh -ex ossp-uuid-UUID_1_6_4/.clang-format000066400000000000000000000020771472561253600170360ustar00rootroot00000000000000--- Language : Cpp BasedOnStyle : LLVM AlignAfterOpenBracket : true AlignEscapedNewlinesLeft : true AlignConsecutiveAssignments : true AllowShortFunctionsOnASingleLine : Inline AlwaysBreakTemplateDeclarations : true ColumnLimit : 160 ConstructorInitializerIndentWidth : 6 IndentCaseLabels : true MaxEmptyLinesToKeep : 2 KeepEmptyLinesAtTheStartOfBlocks : false NamespaceIndentation : All PointerAlignment : Middle SpacesBeforeTrailingComments : 2 IndentWidth : 2 TabWidth : 2 UseTab : ForIndentation SpaceBeforeParens : Never FixNamespaceComments : false ... ossp-uuid-UUID_1_6_4/.gitignore000066400000000000000000000002631472561253600164460ustar00rootroot00000000000000Makefile *~ *.m4 .libs autom4te.cache config.* configure ltmain.sh uuid-config uuid-config.1 uuid.pc uuid.h uuid.1 uuid.3 uuid++.3 uuid libtool libtest libtest_dce *.[ao] *.l[oa] ossp-uuid-UUID_1_6_4/BINDINGS000066400000000000000000000021121472561253600155710ustar00rootroot00000000000000 _ ___ ____ ____ ____ _ _ |_|_ _ / _ \/ ___/ ___|| _ \ _ _ _ _(_) __| | _|_||_| | | | \___ \___ \| |_) | | | | | | | | |/ _` | |_||_|_| | |_| |___) |__) | __/ | |_| | |_| | | (_| | |_|_|_| \___/|____/____/|_| \__,_|\__,_|_|\__,_| OSSP uuid - Universally Unique Identifier LANGUAGE BINDINGS Various programming language bindings exist for OSSP uuid. The following is the list of known bindings: o C (native API) o C++ (addon API; part of the OSSP uuid distribution; see uuid++.* files) Broken, unsalvageable, and unfixable. Also just really bad. Use the C library. o Perl (addon API; part of the OSSP uuid distribution; see perl/ directory) o PHP (addon API; part of the OSSP uuid distribution; see php/ directory) Removed. Targeted PHP4 and PHP5 in ≤1.6.2. o PostgreSQL (was part of the OSSP uuid distribution, now included in postgres) https://www.postgresql.org/docs/16/uuid-ossp.html o Chicken (Scheme) http://www.call-with-current-continuation.org/eggs/uuid-ossp.html ossp-uuid-UUID_1_6_4/HISTORY000066400000000000000000000403071472561253600155450ustar00rootroot00000000000000 _ ___ ____ ____ ____ _ _ |_|_ _ / _ \/ ___/ ___|| _ \ _ _ _ _(_) __| | _|_||_| | | | \___ \___ \| |_) | | | | | | | | |/ _` | |_||_|_| | |_| |___) |__) | __/ | |_| | |_| | | (_| | |_|_|_| \___/|____/____/|_| \__,_|\__,_|_|\__,_| OSSP uuid - Universally Unique Identifier HISTORY During OSSP uuid we were totally puzzled by a subtle bug in the UUID standards related to the generation of multi-cast MAC addresses. This part of the history shows a very interesting technical bug, the unusual way of having to fix a standard (which was multiple times revised by different standard authorities, including the IETF, the OpenGroup and ISO/IEC) afterwards plus the fixing of six implementations into which the bug was inherited similarly. Below are some snapshot of this part of history: the first implementation fix (for FreeBSD) and the notification of the IETF standards authors. ___________________________________________________________________________ Date: Fri, 13 Feb 2004 16:09:31 +0100 From: "Ralf S. Engelschall" To: paulle@microsoft.com, michael@neonym.net, rsalz@datapower.com Subject: [PATCH] draft-mealling-uuid-urn-02.txt Message-ID: <20040213150931.GA7656@engelschall.com> During implementation of OSSP uuid (a flexible CLI and C API for generation and partial decoding of version 1, 3 and 4 UUIDs, see http://www.ossp.org/pkg/lib/uuid/ for details), I discovered a nasty bug in the generation of random multicast MAC addresses. It is present in all standards and drafts (both expired ones and current ones) and was also inherited (until I fixed it by submitting patches to the authors recently) by all six freely available UUID implementations (Apache APR, FreeBSD uuidgen(2), Java JUG, Linux's libuuid from e2fsutil, Perl's Data::UUID and WINE's UUID generator)). In case no real/physical IEEE 802 address is available, both the expired "draft-leach-uuids-guids-01" (section "4. Node IDs when no IEEE 802 network card is available"), RFC 2518 (section "6.4.1 Node Field Generation Without the IEEE 802 Address") and now even your current "draft-mealling-uuid-urn-02.txt" (section "4.5 Node IDs that do not identify the host") recommend: "A better solution is to obtain a 47-bit cryptographic quality random number, and use it as the low 47 bits of the node ID, with the _most_ significant bit of the first octet of the node ID set to one. This bit is the unicast/multicast bit, which will never be set in IEEE 802 addresses obtained from network cards; hence, there can never be a conflict between UUIDs generated by machines with and without network cards." Unfortunately, this incorrectly explains how to implement this and even the example implementation (draft-mealling-uuid-urn-02.txt, "Appendix A. Appendix A - Sample Implementation") inherited this. Correct is "the _least_ significant bit of the first octet of the node ID" as the multicast bit in a memory and hexadecimal string representation of a 48-bit IEEE 802 MAC address. This standards bug arised from a false interpretation, as the multicast bit is actually the _most_ significant bit in IEEE 802.3 (Ethernet) _transmission order_ of an IEEE 802 MAC address. But you forgot that the bitwise order of an _octet_ from a MAC address _memory_ and hexadecimal string representation is still always from left (MSB, bit 7) to right (LSB, bit 0). And the standard deals with memory representations only, so the transmission order of a MAC doesnt' matter here. As mentioned, OSSP uuid already implements this correctly. The FreeBSD uuidgen(2) and Apache APR generators I've also fixed myself recently in CVS. And for the remaining implementations I've submitted patches to the authors and they all (except for WINE) responded that they took over the patch. So the results of this long-standing bug we were able to fix -- at least for the free software world ;-). What is now remaining is that you finally also should fix this in your standard so the bug does not spread any longer into other implementations. Here is the minimal required patch against your draft: --- draft-mealling-uuid-urn-02.txt.orig Mon Feb 2 21:50:35 2004 +++ draft-mealling-uuid-urn-02.txt Fri Feb 13 15:41:49 2004 @@ -751,7 +751,7 @@ [6], and the cost was US$550. A better solution is to obtain a 47-bit cryptographic quality random - number, and use it as the low 47 bits of the node ID, with the most + number, and use it as the low 47 bits of the node ID, with the least significant bit of the first octet of the node ID set to one. This bit is the unicast/multicast bit, which will never be set in IEEE 802 addresses obtained from network cards; hence, there can never be a @@ -1369,7 +1369,7 @@ } else { get_random_info(seed); - seed[0] |= 0x80; + seed[0] |= 0x01; memcpy(&saved_node, seed, sizeof saved_node); fp = fopen("nodeid", "wb"); if (fp) { But I recommend you to perhaps also add one or two sentences which explain what I explained above (the difference between memory and transmission order), just to make sure people are not confused in the other direction and then think there is a bug (in the then fixed and correct) standard, because they know about the transmission order of MAC addresses. Yours, Ralf S. Engelschall rse@engelschall.com www.engelschall.com Date: Fri, 13 Feb 2004 11:05:51 -0500 From: Rich Salz To: rse@engelschall.com Cc: paulle@microsoft.com, michael@neonym.net Message-ID: <402CF5DF.4020601@datapower.com> Subject: Re: [PATCH] draft-mealling-uuid-urn-02.txt References: <20040213150931.GA7656@engelschall.com> Content-Length: 431 Lines: 11 Thanks for writing, Ralf. You're correct, and this has been noted by the IESG and will be fixed in the next draft. It's unfortunate we made it this far with the bug. /r$ -- Rich Salz, Chief Security Architect DataPower Technology http://www.datapower.com XS40 XML Security Gateway http://www.datapower.com/products/xs40.html XML Security Overview http://www.datapower.com/xmldev/xmlsecurity.html Date: Thu, 22 Jan 2004 05:34:11 -0800 (PST) From: "Ralf S. Engelschall" Message-Id: <200401221334.i0MDYB1K018137@repoman.freebsd.org> To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: cvs commit: src/sys/kern kern_uuid.c X-FreeBSD-CVS-Branch: HEAD X-Loop: FreeBSD.ORG Content-Length: 1907 Lines: 42 rse 2004/01/22 05:34:11 PST FreeBSD src repository Modified files: sys/kern kern_uuid.c Log: Fix generation of random multicast MAC address. In case no real/physical IEEE 802 address is available, both the expired "draft-leach-uuids-guids-01" (section "4. Node IDs when no IEEE 802 network card is available") and RFC 2518 (section "6.4.1 Node Field Generation Without the IEEE 802 Address") recommend (quoted from RFC 2518): "The ideal solution is to obtain a 47 bit cryptographic quality random number, and use it as the low 47 bits of the node ID, with the _most_ significant bit of the first octet of the node ID set to 1. This bit is the unicast/multicast bit, which will never be set in IEEE 802 addresses obtained from network cards; hence, there can never be a conflict between UUIDs generated by machines with and without network cards." Unfortunately, this incorrectly explains how to implement this and the FreeBSD UUID generator code inherited this generation bug from the broken reference code in the standards draft. They should instead specify the "_least_ significant bit of the first octet of the node ID" as the multicast bit in a memory and hexadecimal string representation of a 48-bit IEEE 802 MAC address. This standards bug arised from a false interpretation, as the multicast bit is actually the _most_ significant bit in IEEE 802.3 (Ethernet) _transmission order_ of an IEEE 802 MAC address. The standards authors forgot that the bitwise order of an _octet_ from a MAC address _memory_ and hexadecimal string representation is still always from left (MSB, bit 7) to right (LSB, bit 0). Fortunately, this UUID generation bug could have occurred on systems without any Ethernet NICs only. Revision Changes Path 1.7 +1 -1 src/sys/kern/kern_uuid.c Date: Thu, 22 Jan 2004 15:20:22 -0800 From: Marcel Moolenaar To: "Ralf S. Engelschall" Cc: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/sys/kern kern_uuid.c Message-ID: <20040122232022.GA77798@ns1.xcllnt.net> References: <200401221334.i0MDYB1K018137@repoman.freebsd.org> Content-Length: 380 Lines: 14 On Thu, Jan 22, 2004 at 05:34:11AM -0800, Ralf S. Engelschall wrote: > rse 2004/01/22 05:34:11 PST > > FreeBSD src repository > > Modified files: > sys/kern kern_uuid.c > Log: > Fix generation of random multicast MAC address. An excellent catch and an outstanding commit log. Chapeau! -- Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net ___________________________________________________________________________ Index: ChangeLog =================================================================== RCS file: /e/ossp/cvs/ossp-pkg/uuid/ChangeLog,v retrieving revision 1.42 diff -u -d -r1.42 ChangeLog --- ChangeLog 13 Feb 2004 16:17:07 -0000 1.42 +++ ChangeLog 13 Feb 2004 21:01:07 -0000 @@ -13,6 +13,14 @@ Changes between 0.9.6 and 0.9.7 (11-Feb-2004 to 13-Feb-2004) + o remove --with-rfc2518 option and functionality because + even the IETF/IESG has finally approved our report about the broken + random multicast MAC address generation in the standard (and + will fix it in new versions of the draft-mealling-uuid-urn). So, + finally get rid of this broken-by-design backward compatibility + functionality. + [Ralf S. Engelschall] + o Add support to uuid(1) CLI for decoding from stdin for both binary and string representations. [Ralf S. Engelschall] Index: uuid.ac =================================================================== RCS file: /e/ossp/cvs/ossp-pkg/uuid/uuid.ac,v retrieving revision 1.10 diff -u -d -r1.10 uuid.ac --- uuid.ac 11 Feb 2004 14:38:40 -0000 1.10 +++ uuid.ac 13 Feb 2004 19:20:32 -0000 @@ -71,12 +71,6 @@ AC_CHECK_SIZEOF(unsigned long long, 8) dnl # options - AC_ARG_WITH(rfc2518, - AC_HELP_STRING([--with-rfc2518], [use incorrect generation of IEEE 802 multicast addresses according to RFC2518]), - [ac_cv_with_rfc2518=$withval], [ac_cv_with_rfc2518=no]) - if test ".$ac_cv_with_rfc2518" = ".yes"; then - AC_DEFINE(WITH_RFC2518, 1, [whether to use incorrect generation of IEEE 802 multicast addresses according to RFC2518]) - fi AC_ARG_WITH(dce, AC_HELP_STRING([--with-dce], [build DCE 1.1 backward compatibility API]), [ac_cv_with_dce=$withval], [ac_cv_with_dce=no]) Index: uuid.c =================================================================== RCS file: /e/ossp/cvs/ossp-pkg/uuid/uuid.c,v retrieving revision 1.44 diff -u -d -r1.44 uuid.c --- uuid.c 19 Jan 2004 14:56:35 -0000 1.44 +++ uuid.c 13 Feb 2004 19:22:01 -0000 @@ -61,69 +61,9 @@ Unix UTC base time is January 1, 1970) */ #define UUID_TIMEOFFSET "01B21DD213814000" -/* IEEE 802 MAC address encoding/decoding bit fields - - ATTENTION: - - In case no real/physical IEEE 802 address is available, both - "draft-leach-uuids-guids-01" (section "4. Node IDs when no IEEE 802 - network card is available") and RFC 2518 (section "6.4.1 Node Field - Generation Without the IEEE 802 Address") recommend (quoted from RFC - 2518): - - "The ideal solution is to obtain a 47 bit cryptographic quality - random number, and use it as the low 47 bits of the node ID, with - the most significant bit of the first octet of the node ID set to - 1. This bit is the unicast/multicast bit, which will never be set - in IEEE 802 addresses obtained from network cards; hence, there can - never be a conflict between UUIDs generated by machines with and - without network cards." - - This passage clearly explains the intention to use IEEE 802 multicast - addresses. Unfortunately, it incorrectly explains how to implement - this! It should instead specify the "*LEAST* significant bit of the - first octet of the node ID" as the multicast bit in a memory and - hexadecimal string representation of a 48-bit IEEE 802 MAC address. - - Unfortunately, even the reference implementation included in the - expired IETF "draft-leach-uuids-guids-01" incorrectly set the - multicast bit with an OR bit operation and an incorrect mask of - 0x80. Hence, several other UUID implementations found on the - Internet have inherited this bug. - - Luckily, neither DCE 1.1 nor ISO/IEC 11578:1996 are affected by this - problem. They disregard the topic of missing IEEE 802 addresses - entirely, and thus avoid adopting this bug from the original draft - and code ;-) - - It seems that this standards bug arises from a false interpretation, - as the multicast bit is actually the *MOST* significant bit in IEEE - 802.3 (Ethernet) _transmission order_ of an IEEE 802 MAC address. The - authors were likely not aware that the bitwise order of an octet from - a MAC address memory and hexadecimal string representation is still - always from left (MSB, bit 7) to right (LSB, bit 0). - - For more information, see "Understanding Physical Addresses" in - "Ethernet -- The Definitive Guide", p.43, and the section "ETHERNET - MULTICAST ADDRESSES" in http://www.iana.org/assignments/ethernet-numbers. - - At OSSP, we do it the intended/correct way and generate a real - IEEE 802 multicast address. Those wanting to encode broken IEEE - 802 MAC addresses (as specified) can nevertheless use a brain dead - compile-time option to switch off the correct behavior. When decoding - we always use the correct behavior of course. */ - -/* encoding */ -#ifdef WITH_RFC2518 -#define IEEE_MAC_MCBIT_ENC BM_OCTET(1,0,0,0,0,0,0,0) -#else -#define IEEE_MAC_MCBIT_ENC BM_OCTET(0,0,0,0,0,0,0,1) -#endif -#define IEEE_MAC_LOBIT_ENC BM_OCTET(0,0,0,0,0,0,1,0) - -/* decoding */ -#define IEEE_MAC_MCBIT_DEC BM_OCTET(0,0,0,0,0,0,0,1) -#define IEEE_MAC_LOBIT_DEC BM_OCTET(0,0,0,0,0,0,1,0) +/* IEEE 802 MAC address encoding/decoding bit fields */ +#define IEEE_MAC_MCBIT BM_OCTET(0,0,0,0,0,0,0,1) +#define IEEE_MAC_LOBIT BM_OCTET(0,0,0,0,0,0,1,0) /* IEEE 802 MAC address octet length */ #define IEEE_MAC_OCTETS 6 @@ -622,8 +562,8 @@ (unsigned int)uuid->obj.node[3], (unsigned int)uuid->obj.node[4], (unsigned int)uuid->obj.node[5], - (uuid->obj.node[0] & IEEE_MAC_LOBIT_DEC ? "local" : "global"), - (uuid->obj.node[0] & IEEE_MAC_MCBIT_DEC ? "multicast" : "unicast")); + (uuid->obj.node[0] & IEEE_MAC_LOBIT ? "local" : "global"), + (uuid->obj.node[0] & IEEE_MAC_MCBIT ? "multicast" : "unicast")); } else { /* decode anything else as hexadecimal byte-string only */ @@ -843,8 +783,8 @@ if ((mode & UUID_MAKE_MC) || (uuid->mac[0] & BM_OCTET(1,0,0,0,0,0,0,0))) { /* generate random IEEE 802 local multicast MAC address */ prng_data(uuid->prng, (void *)&(uuid->obj.node), sizeof(uuid->obj.node)); - uuid->obj.node[0] |= IEEE_MAC_MCBIT_ENC; - uuid->obj.node[0] |= IEEE_MAC_LOBIT_ENC; + uuid->obj.node[0] |= IEEE_MAC_MCBIT; + uuid->obj.node[0] |= IEEE_MAC_LOBIT; } else { /* use real regular MAC address */ ossp-uuid-UUID_1_6_4/LICENSES/000077500000000000000000000000001472561253600156625ustar00rootroot00000000000000ossp-uuid-UUID_1_6_4/LICENSES/0BSD.txt000066400000000000000000000011371472561253600171150ustar00rootroot00000000000000Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ossp-uuid-UUID_1_6_4/Makefile.PL000066400000000000000000000043611472561253600164330ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2008 Ralf S. Engelschall ## Copyright (c) 2004-2008 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## Makefile.PL: top-level Perl ExtUtils::MakeMaker wrapper script ## require 5.008; use IO::File; my $ARGS = join(" ", @ARGV); print "++ writing Makefile\n"; my $mk = new IO::File ">Makefile" or die; $mk->print(<< "EOF"); PERL = $^X FULLPERL = $^X ARGS = $ARGS all pure_all: \@if [ ! -d build ]; then mkdir build; fi \@if [ ! -f build/Makefile ]; then (cd build && ../configure --disable-shared); fi \@if [ ! -f build/libuuid.la ]; then (cd build && \$(MAKE) \$(MFLAGS) libuuid.la); fi \@if [ ! -f perl/Makefile ]; then (cd perl && \$(PERL) Makefile.PL \$(ARGS)); fi \@cd perl && \$(MAKE) \$(MFLAGS) \$\@ install pure_install test: \@cd perl && \$(MAKE) \$(MFLAGS) \$\@ clean: \@cd build && \$(MAKE) \$(MFLAGS) \$\@ \@cd perl && \$(MAKE) \$(MFLAGS) \$\@ distclean realclean: \@cd build && \$(MAKE) \$(MFLAGS) \$\@ \@cd perl && \$(MAKE) \$(MFLAGS) \$\@ -rm -rf build || true -rm -rf Makefile || true EOF $mk->close(); ossp-uuid-UUID_1_6_4/Makefile.in000066400000000000000000000155651472561253600165360ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2008 Ralf S. Engelschall ## Copyright (c) 2004-2008 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## Makefile.in: make(1) build procedure ## @SET_MAKE@ VPATH = @srcdir@ S = @srcdir@ DESTDIR = prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ mandir = @mandir@ CC = @CC@ CXX = @CXX@ CPPFLAGS = -I. -I$(S) @CPPFLAGS@ @DEFS@ -D_DEFAULT_SOURCE CFLAGS = @CFLAGS@ -Wall -Wextra -std=c11 CXXFLAGS = @CXXFLAGS@ -Wall -Wextra LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ RM = rm -f CP = cp RMDIR = rmdir LIBTOOL = ./libtool TARGETS = .PHONY: c dce cxx perl all: c @WITH_DCE@ @WITH_CXX@ @WITH_PERL@ .SUFFIXES: .lo .c.lo: $(LIBTOOL) --tag CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $< c: lib@libname@.la libtest uuid lib@libname@.la: uuid.lo uuid_mac.lo libuuid.ver $(LIBTOOL) --tag CC --mode=link $(CC) $(LDFLAGS) -o lib@libname@.la uuid.lo uuid_mac.lo $(LIBS) -rpath $(libdir) -version-info @UUID_VERSION_LIBTOOL@ -Wl,--version-script=$(S)/libuuid.ver libtest: libtest.o lib@libname@.la $(LIBTOOL) --tag CC --mode=link $(CC) $(LDFLAGS) -o libtest libtest.o lib@libname@.la uuid_cli.o: uuid.h uuid: uuid_cli.o lib@libname@.la $(LIBTOOL) --tag CC --mode=link $(CC) $(LDFLAGS) -o uuid uuid_cli.o lib@libname@.la dce: lib@libname@_dce.la libtest_dce uuid_dce.lo: uuid_dce.h uuid.h lib@libname@_dce.la: uuid_dce.lo lib@libname@.la $(LIBTOOL) --tag CC --mode=link $(CC) $(LDFLAGS) -o lib@libname@_dce.la uuid_dce.lo lib@libname@.la -rpath $(libdir) -version-info @UUID_VERSION_LIBTOOL@ libtest_dce: libtest_dce.o lib@libname@_dce.la $(LIBTOOL) --tag CC --mode=link $(CC) $(LDFLAGS) -o libtest_dce libtest_dce.o lib@libname@_dce.la cxx: lib@libname@++.la uuid++.lo: uuid++.cc uuid++.hh $(LIBTOOL) --tag CXX --mode=compile $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(S)/uuid++.cc -o uuid++.lo -Wno-deprecated-declarations lib@libname@++.la: uuid++.lo lib@libname@.la $(LIBTOOL) --tag CXX --mode=link $(CXX) $(LDFLAGS) -o lib@libname@++.la uuid++.lo lib@libname@.la -rpath $(libdir) -version-info @UUID_VERSION_LIBTOOL@ perl: $(S)/perl/blib/arch/auto/OSSP/uuid/uuid.so $(S)/perl/blib/arch/auto/OSSP/uuid/uuid.so: $(S)/perl/uuid.pm.in lib@libname@.la cd $(S)/perl && COMPAT=@WITH_PERL_COMPAT@ UUID_VERSION_MDOC_DATE="@UUID_VERSION_MDOC_DATE@" UUID_VERSION_RAW="@UUID_VERSION_RAW@" BLD="@abs_builddir@" LIBNAME=@libname@ @PERL@ Makefile.PL PREFIX=$(prefix) && $(MAKE) $(MFLAGS) all check: all $(LIBTOOL) --mode=execute ./libtest [ -z "@WITH_DCE@" ] || $(LIBTOOL) --mode=execute ./libtest_dce uuid="$(LIBTOOL) --mode=execute ./uuid" $(S)/test $(LIBTOOL) --mode=execute ./uuid -v6 -n5 # MAC extraction (validate visually) [ -z "@WITH_PERL@" ] || LD_LIBRARY_PATH="@abs_builddir@/.libs" DYLD_LIBRARY_PATH="@abs_builddir@/.libs" $(MAKE) -C $(S)/perl $(MFLAGS) test .PHONY: install install: all mkdir -p $(DESTDIR)$(prefix) $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/pkgconfig $(DESTDIR)$(mandir)/man3 $(DESTDIR)$(mandir)/man1 cp uuid.h $(DESTDIR)$(includedir)/ $(LIBTOOL) --mode=install install -c -m 644 lib@libname@.la $(DESTDIR)$(libdir)/ cp uuid.pc $(DESTDIR)$(libdir)/pkgconfig/@libname@.pc $(LIBTOOL) --mode=install install -c -m 755 uuid@EXEEXT@ $(DESTDIR)$(bindir)/ cp uuid-config $(DESTDIR)$(bindir)/ cp uuid.1 $(DESTDIR)$(mandir)/man1/ cp uuid-config.1 $(DESTDIR)$(mandir)/man1/ cp uuid.3 $(DESTDIR)$(mandir)/man3/ [ -z "@WITH_DCE@" ] || cp $(S)/uuid_dce.h $(DESTDIR)$(includedir)/ [ -z "@WITH_DCE@" ] || $(LIBTOOL) --mode=install install -c -m 644 lib@libname@_dce.la $(DESTDIR)$(libdir)/ [ -z "@WITH_CXX@" ] || cp $(S)/uuid++.hh $(DESTDIR)$(includedir)/ [ -z "@WITH_CXX@" ] || cp uuid++.3 $(DESTDIR)$(mandir)/man3/ [ -z "@WITH_CXX@" ] || $(LIBTOOL) --mode=install install -c -m 644 lib@libname@++.la $(DESTDIR)$(libdir)/ [ -z "@WITH_PERL@" ] || $(MAKE) -C $(S)/perl $(MFLAGS) install DESTDIR=$(DESTDIR) .PHONY: uninstall uninstall: -$(RM) $(DESTDIR)$(includedir)/uuid.h -$(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(libdir)/lib@libname@.la -$(RM) $(DESTDIR)$(libdir)/pkgconfig/@libname@.pc -$(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(bindir)/uuid@EXEEXT@ -$(RM) $(DESTDIR)$(bindir)/uuid-config -$(RM) $(DESTDIR)$(mandir)/man1/uuid.1 -$(RM) $(DESTDIR)$(mandir)/man1/uuid-config.1 -$(RM) $(DESTDIR)$(mandir)/man3/uuid.3 -[ -z "@WITH_DCE@" ] || $(RM) $(DESTDIR)$(includedir)/uuid_dce.h -[ -z "@WITH_DCE@" ] || $(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(libdir)/lib@libname@_dce.la -[ -z "@WITH_CXX@" ] || $(RM) $(DESTDIR)$(includedir)/uuid++.hh -[ -z "@WITH_CXX@" ] || $(RM) $(DESTDIR)$(mandir)/man3/uuid++.3 -[ -z "@WITH_CXX@" ] || $(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(libdir)/lib@libname@++.la -[ -z "@WITH_PERL@" ] || $(MAKE) -C $(S)/perl $(MFLAGS) uninstall DESTDIR=$(DESTDIR) $(RMDIR) $(DESTDIR)$(mandir)/man3 $(DESTDIR)$(mandir)/man1 $(DESTDIR)$(mandir) $(DESTDIR)$(libdir)/pkgconfig $(DESTDIR)$(libdir) $(DESTDIR)$(includedir) $(DESTDIR)$(bindir) $(DESTDIR)$(prefix) 2>/dev/null .PHONY: clean clean: -$(RM) -r libtest libtest_dce uuid *.l[oa] *.[oa] .libs -[ -z "@WITH_PERL@" ] || $(MAKE) -C $(S)/perl $(MFLAGS) clean distclean: clean -$(RM) -r configure configure~ config.h.in config.h.in~ ltmain.sh libtool.m4 config.guess config.sub aclocal.m4 autom4te.cache config.log config.status config.cache libtool -$(RM) Makefile config.h uuid-config uuid.h uuid.pc uuid.1 uuid++.3 uuid-config.1 uuid.3 -[ -z "@WITH_PERL@" ] || $(MAKE) -C $(S)/perl $(MFLAGS) distclean ossp-uuid-UUID_1_6_4/README000066400000000000000000000075141472561253600153440ustar00rootroot00000000000000 _ ___ ____ ____ ____ _ _ |_|_ _ / _ \/ ___/ ___|| _ \ _ _ _ _(_) __| | _|_||_| | | | \___ \___ \| |_) | | | | | | | | |/ _` | |_||_|_| | |_| |___) |__) | __/ | |_| | |_| | | (_| | |_|_|_| \___/|____/____/|_| \__,_|\__,_|_|\__,_| OSSP uuid - Universally Unique Identifier Version 1.6.4 (2024-12-09) ABSTRACT OSSP uuid is a C API and corresponding CLI program for the generation and analysis of DCE 1.1 and, IETF RFC-9562- compliant Universally Unique Identifiers (UUIDs). It supports variant 1 UUIDs of versions: 1 (time and node), 3 (name (namespace+data), MD5), 4 (random), 5 (name (namespace+data), SHA-1), 6 (time and node with improved locality), 7 (UNIX time, random data). Additional API bindings are provided for C++98 (deprecated) and Perl:5. Optional backward compatibility exists for the ISO-C DCE-1.1 and Perl Data::UUID APIs. UUIDs are 128 bit numbers which are intended to have a high likelihood of uniqueness over space and time and are computationally difficult to guess. They are globally unique identifiers which can be locally generated without contacting a global registration authority. UUIDs are intended as unique identifiers for both mass tagging objects with an extremely short lifetime and to reliably identifying very persistent objects across a network. HOME AND DOCUMENTATION This is a thawed OSSP project; for git repository/bug tracker/mailing list see https://sr.ht/~nabijaczleweli/ossp The manual is available on-line and at https://srhtcdn.githack.com/~nabijaczleweli/ossp-uuid/blob/man/ossp-uuid.pdf Release tarballs are signed with nabijaczleweli@nabijaczleweli.xyz (pull with WKD, but 7D69 474E 8402 8C5C C0C4 4163 BCFD 0B01 8D26 58F1). аnd stored in git notes as-if via the example program provided at https://man.sr.ht/git.sr.ht/#signing-tags-tarballs and are thus available on the refs listing/tag page as .tar.gz{,.asc}: https://git.sr.ht/~nabijaczleweli/ossp-uuid/refs COMPATIBILITY Wants libmd-dev, a C11 compiler, and autoconf/automake/libtool-bin. $ autoreconf -fi $ ./configure [--with-dce] [--with-cxx] [--with-perl] [--with-perl-compat] \ [--with-libname=libossp-uuid] [usual autoconf variables]... # the default is libuuid $ make ... MAC address detection has been verified to work under Linux, the Hurd, {Free,Net,Open}BSD, the Macintosh, and the illumos gate. COPYRIGHT AND LICENSE Files from the original OSSP project bear the licence seen below; new files are provided under the 0BSD licence (cf. LICENSES/0BSD). Copyright (c) 2004-2008 Ralf S. Engelschall Copyright (c) 2004-2008 The OSSP Project This file is part of OSSP uuid, a library for the generation of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ossp-uuid-UUID_1_6_4/THANKS000066400000000000000000000025041472561253600153710ustar00rootroot00000000000000 _ ___ ____ ____ ____ _ _ |_|_ _ / _ \/ ___/ ___|| _ \ _ _ _ _(_) __| | _|_||_| | | | \___ \___ \| |_) | | | | | | | | |/ _` | |_||_|_| | |_| |___) |__) | __/ | |_| | |_| | | (_| | |_|_|_| \___/|____/____/|_| \__,_|\__,_|_|\__,_| OSSP uuid - Universally Unique Identifier THANKS Credit has to be given to the following people who contributed ideas, bugfixes, hints, gave platform feedback, etc. (in alphabetical order): o Matthias Andree o Neil Caunt o Neil Conway o M. Daniel o Simon "janus" Dassow o Fuyuki o Thomas Lotterer o Roman Neuhauser o Hrvoje Niksic o Piotr Roszatycki o Hiroshi Saito o Michael Schloh o Guerry Semones o David Wheeler o Wu Yongwei ossp-uuid-UUID_1_6_4/configure.ac000066400000000000000000000075001472561253600167450ustar00rootroot00000000000000dnl ## dnl ## OSSP uuid - Universally Unique Identifier dnl ## Copyright (c) 2004-2008 Ralf S. Engelschall dnl ## Copyright (c) 2004-2008 The OSSP Project dnl ## dnl ## This file is part of OSSP uuid, a library for the generation dnl ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ dnl ## dnl ## Permission to use, copy, modify, and distribute this software for dnl ## any purpose with or without fee is hereby granted, provided that dnl ## the above copyright notice and this permission notice appear in all dnl ## copies. dnl ## dnl ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED dnl ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF dnl ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. dnl ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR dnl ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, dnl ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT dnl ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF dnl ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND dnl ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, dnl ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT dnl ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF dnl ## SUCH DAMAGE. dnl ## dnl ## configure.ac: GNU Autoconf source script dnl ## AC_PREREQ([2.71]) AC_INIT UUID_VERSION_RAW="1.6.4" UUID_VERSION_MDOC_DATE="December 9, 2024" UUID_VERSION_STR="$UUID_VERSION_RAW (2024-12-09)" UUID_VERSION_HEX=0x106204 UUID_VERSION_LIBTOOL=16:22 echo "ossp-uuid $UUID_VERSION_STR" AC_SUBST(UUID_VERSION_RAW) AC_SUBST(UUID_VERSION_MDOC_DATE) AC_SUBST(UUID_VERSION_STR) AC_SUBST(UUID_VERSION_HEX) AC_SUBST(UUID_VERSION_LIBTOOL) AC_PROG_MAKE_SET AC_PROG_CC LT_INIT AC_ARG_WITH([libname], AS_HELP_STRING([--with-libname=libuuid], [library name (default libuuid), also affects DCE compat and C++ libraries])) case "$with_libname" in yes|no|"") with_libname="libuuid" ;; esac libname="${with_libname#lib}" AC_SUBST(libname) AC_SEARCH_LIBS(getifaddrs, socket) CFLAGS="$CFLAGS $(${PKG_CONFIG-"pkg-config"} --cflags libmd)" LIBS=" $LIBS $(${PKG_CONFIG-"pkg-config"} --libs libmd)" || { AC_CHECK_FUNCS(SHA1Final) test "$ac_cv_func_SHA1Final" = yes || LIBS="$LIBS -lmd" } AC_CHECK_HEADERS(sys/param.h sys/time.h sys/socket.h sys/sockio.h sys/ioctl.h) AC_CHECK_HEADERS(ifaddrs.h net/if.h net/if_dl.h net/if_arp.h netinet/in.h,,, [[ #if HAVE_SYS_TYPES_H #include #endif #if HAVE_SYS_SOCKET_H #include #endif #if HAVE_SYS_IOCTL_H #include #endif ]]) AC_CHECK_FUNCS(getentropy) AC_ARG_WITH([dce], AS_HELP_STRING([--with-dce], [build DCE 1.1 backward compatibility API])) if test "$with_dce" = "yes"; then AC_SUBST(WITH_DCE, [dce]) else AC_SUBST(WITH_DCE, []):; fi AC_ARG_WITH([cxx], AS_HELP_STRING([--with-cxx], [build C++ bindings to C API])) if test "$with_cxx" = "yes"; then AC_SUBST(WITH_CXX, [cxx]) AC_PROG_CXX else AC_SUBST(WITH_CXX, []):; fi AC_ARG_WITH([perl], AS_HELP_STRING([--with-perl], [build Perl bindings to C API])) if test "$with_perl" = "yes"; then AC_SUBST(WITH_PERL, [perl]) AC_ARG_WITH([perl-compat], AS_HELP_STRING([--with-perl-compat], [build Perl compatibility API])) ! test "$with_perl_compat" = "yes"; WITH_PERL_COMPAT=$? AC_SUBST(WITH_PERL_COMPAT) AC_PATH_PROG(PERL, perl, NA) if test "$PERL" = "NA"; then AC_MSG_ERROR(required Perl interpreter not found in \$PATH) fi else AC_SUBST(WITH_PERL, []):; fi AC_CONFIG_HEADERS(config.h) AC_CONFIG_FILES([Makefile uuid-config uuid.pc uuid.h uuid.1 uuid++.3 uuid-config.1 uuid.3]) AC_CONFIG_COMMANDS([substituted-executables], [chmod a+x uuid-config]) AC_OUTPUT ossp-uuid-UUID_1_6_4/libtest.c000066400000000000000000000116101472561253600162660ustar00rootroot00000000000000// SPDX-License-Identifier: 0BSD #include "uuid.h" #include #include #include static const char expecting[] = "encode: STR: f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6\n" " SIV: 325725109554302597798550804656796594934\n" "decode: variant: DCE 1.1, ISO/IEC 11578:1996\n" " version: 1 (time and node based)\n" " content: time: 2024-09-05 09:12:21.383982.0 UTC\n" " clock: 15100 (usually random)\n" " node: ef:df:f7:d5:f2:f6 (local multicast)\n"; static const char expecting_str[] = "f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6"; static const char expecting_siv[] = "325725109554302597798550804656796594934"; static const unsigned char expecting_bin[UUID_LEN_BIN] = {0xF5, 0x0C, 0x5F, 0xCC, 0x6B, 0x66, 0x11, 0xEF, 0xBA, 0xFC, 0xEF, 0xDF, 0xF7, 0xD5, 0xF2, 0xF6}; #define assert_eq_expecting_str(uuid, tp, val) \ { \ char * desc = NULL; \ size_t desc_len; \ assert(uuid_export(uuid, tp, &desc, &desc_len) == UUID_RC_OK); \ assert(!strcmp(desc, val)); \ assert(desc_len == (tp == UUID_FMT_SIV ? (UUID_LEN_SIV + 1) : sizeof(val))); \ free(desc); \ } #define assert_eq_expecting_bin(uuid, val) \ { \ unsigned char * desc = NULL; \ size_t desc_len; \ assert(uuid_export(uuid, UUID_FMT_BIN, &desc, &desc_len) == UUID_RC_OK); \ assert(desc_len == sizeof(val)); \ assert(!memcmp(desc, val, sizeof(val))); \ free(desc); \ } #define assert_eq_expecting(uuid) \ assert_eq_expecting_str(uuid, UUID_FMT_TXT, expecting); \ assert_eq_expecting_str(uuid, UUID_FMT_STR, expecting_str); \ assert_eq_expecting_str(uuid, UUID_FMT_SIV, expecting_siv); \ assert_eq_expecting_bin(uuid, expecting_bin); int main() { uuid_t * uuid; assert(uuid_create(&uuid) == UUID_RC_OK); assert_eq_expecting_str(uuid, UUID_FMT_TXT, "encode: STR: 00000000-0000-0000-0000-000000000000\n" " SIV: 0\n" "decode: variant: n.a.\n" " version: 0 (n.a.)\n" " content: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00\n" " (special case: DCE 1.1 Nil UUID)\n"); assert_eq_expecting_str(uuid, UUID_FMT_STR, "00000000-0000-0000-0000-000000000000"); assert_eq_expecting_str(uuid, UUID_FMT_SIV, "0"); static const unsigned char null_bin[UUID_LEN_BIN] = {}; assert_eq_expecting_bin(uuid, null_bin); assert(uuid_import(uuid, UUID_FMT_STR, expecting_str, sizeof(expecting_str)) == UUID_RC_OK); assert_eq_expecting(uuid); assert(uuid_import(uuid, UUID_FMT_SIV, expecting_siv, sizeof(expecting_siv)) == UUID_RC_OK); assert_eq_expecting(uuid); assert(uuid_import(uuid, UUID_FMT_SIV, expecting_siv, strlen(expecting_siv)) == UUID_RC_OK); assert_eq_expecting(uuid); char shortbuf_nonul[sizeof(expecting_siv)]; strcpy(shortbuf_nonul, expecting_siv); shortbuf_nonul[sizeof(shortbuf_nonul) - 1] = 'Q'; assert(uuid_import(uuid, UUID_FMT_SIV, shortbuf_nonul, strlen(expecting_siv)) == UUID_RC_OK); assert_eq_expecting(uuid); shortbuf_nonul[sizeof(shortbuf_nonul) - 1] = '1'; assert(uuid_import(uuid, UUID_FMT_SIV, shortbuf_nonul, strlen(expecting_siv)) == UUID_RC_OK); assert_eq_expecting(uuid); assert(uuid_import(uuid, UUID_FMT_BIN, expecting_bin, sizeof(expecting_bin)) == UUID_RC_OK); assert_eq_expecting(uuid); assert(uuid_import(uuid, UUID_FMT_STR, "4eb841ca-ce98-4590-8ea2-c4643bfa", sizeof("4eb841ca-ce98-4590-8ea2-c4643bfa")) == UUID_RC_ARG); assert(uuid_import(uuid, UUID_FMT_STR, "4eb841ca-ce98-4590-8ea2-c4643bfaqwe", sizeof("4eb841ca-ce98-4590-8ea2-c4643bfaqwe")) == UUID_RC_ARG); assert(uuid_import(uuid, UUID_FMT_STR, "4eb841ca-ce98-4590-8ea2-c4643bfa537bad", sizeof("4eb841ca-ce98-4590-8ea2-c4643bfa537bad")) == UUID_RC_ARG); assert(uuid_destroy(uuid) == UUID_RC_OK); } ossp-uuid-UUID_1_6_4/libtest_dce.c000066400000000000000000000053141472561253600171050ustar00rootroot00000000000000// SPDX-License-Identifier: 0BSD #include "uuid_dce.h" #include #include #include #include _Static_assert(sizeof(uuid_t) == 16, "UUIDs are 16 bytes"); static const uuid_t nil; int main() { int status; assert(uuid_is_nil((uuid_t *)&nil, &status)); assert(status == uuid_s_ok); assert(!uuid_is_nil(NULL, &status)); assert(status == uuid_s_error); uuid_t uuid; uuid_create_nil(&uuid, &status); assert(status == uuid_s_ok); assert(!memcmp(&uuid, &nil, sizeof(uuid))); assert(uuid_is_nil(&uuid, &status)); assert(status == uuid_s_ok); uuid_create(&uuid, &status); // this generates a V1 UUID assert(status == uuid_s_ok); assert(memcmp(&uuid, &nil, sizeof(uuid))); assert(status == uuid_s_ok); if(uuid.data[0] == 0 || uuid.data[0] == 0xFF) // avoid wrapping below uuid.data[0] = 0x80; uuid_t uuid_copy = uuid; assert(uuid_compare(&uuid, &uuid_copy, &status) == 0); assert(status == uuid_s_ok); uuid_copy.data[0] -= 1; assert(uuid_compare(&uuid, &uuid_copy, &status) >= 0); assert(status == uuid_s_ok); uuid_copy.data[0] += 2; assert(uuid_compare(&uuid, &uuid_copy, &status) <= 0); assert(status == uuid_s_ok); uuid_t uuid2; uuid_create(&uuid2, &status); // this generates a V1 UUID assert(status == uuid_s_ok); assert(!uuid_equal(&uuid, &uuid2, &status)); assert(status == uuid_s_ok); uuid_t uuid2_copy = uuid2; assert(uuid_equal(&uuid2, &uuid2_copy, &status)); assert(status == uuid_s_ok); assert(!uuid_equal(&uuid2, NULL, &status)); assert(status == uuid_s_error); assert(!uuid_equal(NULL, &uuid2_copy, &status)); assert(status == uuid_s_error); uuid_from_string("f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6", &uuid, &status); assert(status == uuid_s_ok); assert(!memcmp(uuid.data, (unsigned char[]){0xF5, 0x0C, 0x5F, 0xCC, 0x6B, 0x66, 0x11, 0xEF, 0xBA, 0xFC, 0xEF, 0xDF, 0xF7, 0xD5, 0xF2, 0xF6}, 16)); assert(uuid_dce_hash(NULL, &status) == 0); assert(status == uuid_s_error); assert(uuid_dce_hash(&uuid, &status) == 0xCC5F0CF5); // https://pubs.opengroup.org/onlinepubs/9629399/uuid_hash.htm says "may vary between implementations" // but for this one it's the top 4 bytes in little-endian assert(status == uuid_s_ok); char * str = NULL; uuid_to_string((uuid_t *)&nil, NULL, &status); assert(status == uuid_s_error); uuid_to_string((uuid_t *)&nil, &str, NULL); assert(status == uuid_s_error); uuid_to_string((uuid_t *)&nil, &str, &status); assert(status == uuid_s_ok); assert(!strcmp(str, "00000000-0000-0000-0000-000000000000")); free(str); str = NULL; uuid_to_string(&uuid, &str, &status); assert(status == uuid_s_ok); assert(!strcmp(str, "f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6")); free(str); } ossp-uuid-UUID_1_6_4/libuuid.ver000066400000000000000000000005401472561253600166270ustar00rootroot00000000000000# Unversioned: # uuid_create() # uuid_destroy() # uuid_clone() # # uuid_load() # uuid_make() # # uuid_isnil() # uuid_compare() # # uuid_import() # uuid_export() # # uuid_error() # uuid_version() OSSP_UUID_1.6.3 { uuid_ismax; # uuid_load() also understands "max" # uuid_make() also understands UUID_MAKE_V6 and UUID_MAKE_V7 }; ossp-uuid-UUID_1_6_4/perl/000077500000000000000000000000001472561253600154175ustar00rootroot00000000000000ossp-uuid-UUID_1_6_4/perl/.gitignore000066400000000000000000000001131472561253600174020ustar00rootroot00000000000000Makefile Makefile.old blib pm_to_blib uuid.bs uuid.c MYMETA.* *.pm *.3perl ossp-uuid-UUID_1_6_4/perl/Data::UUID.3perl.in000066400000000000000000000041431472561253600205210ustar00rootroot00000000000000.\" .\" OSSP uuid - Universally Unique Identifier .\" Copyright (c) 2004-2007 Ralf S. Engelschall .\" Copyright (c) 2004-2007 The OSSP Project .\" .\" This file is part of OSSP uuid, a library for the generation .\" of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ .\" .\" Permission to use, copy, modify, and distribute this software for .\" any purpose with or without fee is hereby granted, provided that .\" the above copyright notice and this permission notice appear in all .\" copies. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED .\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR .\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" uuid_compat.pod: Data::UUID Backward Compatibility Perl API (Perl/POD part) .\" .Dd @UUID_VERSION_MDOC_DATE@ .ds doc-volume-operating-system OSSP .Dt Data::UUID 3perl .Os ossp-uuid @UUID_VERSION_RAW@ . .Sh NAME .Nm Data::UUID .Nd OSSP uuid Backward Compatibility Perl Binding .Sh DESCRIPTION .Nm is the OSSP .Nm uuid backward compatibility Perl binding to the API of the original .Nm module. It allows other .Nm based Perl modules to run with .Nm OSSP::uuid without changes. . .Sh SEE ALSO .Xr OSSP::uuid 3perl . .Sh HISTORY The backward compatibility Perl binding .Nm to OSSP .Nm uuid was originally implemented in 2004 by .An Piotr Roszatycki Aq dexter@debian.org . It was later cleaned up and speed optimized in December 2005 by .An David Wheeler Aq david@justatheory.com . ossp-uuid-UUID_1_6_4/perl/Makefile.PL000066400000000000000000000065671472561253600174070ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2007 Ralf S. Engelschall ## Copyright (c) 2004-2007 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## Makefile.PL: Perl MakeMaker build source procedure ## require 5.008; use Config; use ExtUtils::MakeMaker; my $blddir = $ENV{BLD}; my $libname = $ENV{LIBNAME}; my $compat = $ENV{COMPAT}; my $version = $ENV{UUID_VERSION_RAW}; for my $f (qw(uuid.pm uuid_compat.pm)) { open(my $ifh, '<', "$f.in") or die; open(my $ofh, '>', "$f") or die; while(<$ifh>) { chomp; s/%VERSION%/$version/; print $ofh "$_\n"; } close($ifh); close($ofh); } WriteMakefile( NAME => 'OSSP::uuid', VERSION_FROM => 'uuid.pm', ABSTRACT => 'OSSP uuid Perl Binding', PREREQ_PM => {}, LIBS => [ "-L$blddir/.libs -L.. -l$libname" ], DEFINE => '', INC => "-I.. -I$blddir", PM => { 'uuid.pm' => '$(INST_LIBDIR)/uuid.pm', ($compat ? ('uuid_compat.pm' => '$(INST_LIBDIR)/../Data/UUID.pm') : ()), }, MAN3PODS => { }, TYPEMAPS => [ 'uuid.tm' ], test => { TESTS => 'uuid.ts' . ($compat ? ' uuid_compat.ts' : '') }, NO_META => 1, # cruel hack to workaround the conflict between OSSP uuid's # uuid_create() function and one from FreeBSD's libc (( "$Config{'osname'}$Config{'osvers'}" =~ m/^freebsd[56]\./ and $Config{'ld'} =~ m/cc$/ and -f "/usr/include/uuid.h") ? ( LDDLFLAGS => $Config{'lddlflags'} . ' -Wl,-Bsymbolic') : ()) ); system 'sed "s/PERL_DL_NONLAZY=1//g" < Makefile > Makefile.old'; open(my $Makefile, '>>', 'Makefile.old') or die; print $Makefile (<< "EOF"); all:: manuals_custom manuals_custom: blibdirs sed -e "s/\@UUID_VERSION_MDOC_DATE\@/$ENV{UUID_VERSION_MDOC_DATE}/" -e "s/\@UUID_VERSION_RAW\@/$version/" < Data::UUID.3perl.in > \$(INST_MAN3DIR)/Data::UUID.3perl sed -e "s/\@UUID_VERSION_MDOC_DATE\@/$ENV{UUID_VERSION_MDOC_DATE}/" -e "s/\@UUID_VERSION_RAW\@/$version/" < OSSP::uuid.3perl.in > \$(INST_MAN3DIR)/OSSP::uuid.3perl clean:: custom_clean custom_clean: rm -f uuid.pm uuid_compat.pm Makefile.old EOF close($Makefile); rename('Makefile.old', 'Makefile'); ossp-uuid-UUID_1_6_4/perl/OSSP::uuid.3perl.in000066400000000000000000000135301472561253600206340ustar00rootroot00000000000000.\" .\" OSSP uuid - Universally Unique Identifier .\" Copyright (c) 2004-2007 Ralf S. Engelschall .\" Copyright (c) 2004-2007 The OSSP Project .\" .\" This file is part of OSSP uuid, a library for the generation .\" of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ .\" .\" Permission to use, copy, modify, and distribute this software for .\" any purpose with or without fee is hereby granted, provided that .\" the above copyright notice and this permission notice appear in all .\" copies. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED .\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR .\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" uuid.pod: Perl Binding (Perl/POD part) .\" .Dd @UUID_VERSION_MDOC_DATE@ .ds doc-volume-operating-system OSSP .Dt OSSP::uuid 3perl .Os ossp-uuid @UUID_VERSION_RAW@ . .Sh NAME .Nm OSSP::uuid .Nd OSSP uuid Perl Binding .Sh DESCRIPTION OSSP .Nm is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of RFC 9562, ISO/IEC 11578:1996 and IETF RFC-4122 compliant .Em Universally Unique Identifier (UUID). It supports DCE 1.1 variant UUIDs of version 1 (time and node based), version 3 (name based, MD5), version 4 (random number based) and version 5 (name based, SHA-1). Additional API bindings are provided for the Perl:5 language. Optional backward compatibility exists for the ISO-C DCE-1.1 and Perl Data::UUID APIs. .Pp .Nm is the Perl binding to the OSSP .Nm uuid API. Three variants are provided: . .Ss TIE-STYLE API The TIE-style API is a functionality-reduced wrapper around the OO-style API and intended for very high-level convenience programming: . .Bd -literal -offset 2n use OSSP::uuid; .Ic tie Li my $uuid, 'OSSP::uuid::tie', $mode, ...; $uuid = [ $mode, ... ]; print "UUID=$uuid\\n"; untie $uuid; .Ed . .Ss OO-STYLE API The OO-style API is a wrapper around the C-style API and intended for high-level regular programming. . .Bd -literal -offset 2n use OSSP::uuid; .Li my $uuid = Ic new Li OSSP::uuid; .Li $uuid-> Ns Ic load Li ($name); .Li $uuid-> Ns Ic make Li ($mode, ...); .Li $result = $uuid-> Ns Ic isnil Ns Li (); .Li $result = $uuid-> Ns Ic compare Ns Li ($uuid2); .Li $uuid-> Ns Ic import Ns Ic ($fmt, $data_ptr); .Li $data_ptr = $uuid-> Ns Ic export Ns Li ($fmt); .Li [(]$str[, $rc)] = $uuid-> Ns Ic error Ns Li (); .Li $ver = $uuid-> Ns Ic version Ns Li (); undef $uuid; .Pp .Ed Additionally, the strings .Li \&"v1" , .Li \&"v3" , .Li \&"v4" , .Li \&"v5" , .Li \&"v6" , .Li \&"v7" , and .Li \&"mc" can be used in .Li $mode and the strings .Li \&"bin" , .Li \&"str" , and .Li \&"txt" .Li $fmt . . .Ss C-STYLE API The C-style API is a direct mapping of the OSSP .Nm uuid ISO-C API to Perl and is intended for low-level programming. See .Xr uuid 3 for a description of the functions and their expected arguments. . .Bd -literal -offset 2n use OSSP::uuid qw(:all); .Li my $uuid; $rc = Ic uuid_create Ns Li ($uuid); .Li $rc = Ic uuid_load Ns Li ($uuid, $name); .Li $rc = Ic uuid_make Ns Li ($uuid, $mode, ...); .Li $rc = Ic uuid_isnil Ns Li ($uuid, $result); .Li $rc = Ic uuid_ismax Ns Li ($uuid, $result); .Li $rc = Ic uuid_compare Ns Li ($uuid, $uuid2, $result); .Li $rc = Ic uuid_import Ns Li ($uuid, $fmt, $data_ptr, $data_len); .Li $rc = Ic uuid_export Ns Li ($uuid, $fmt, $data_ptr, $data_len); .Li $str = Ic uuid_error Ns Li ($rc); .Li $ver = Ic uuid_version Ns Li (); .Li $rc = Ic uuid_destroy Ns Li ($uuid); .Ed .Pp Additionally, the following constants are exported for use in .Li $rc , .Li $mode , .Li $fmt , and .Li $ver : .Li UUID_VERSION , .Li UUID_LEN_BIN , .Li UUID_LEN_STR , .Li UUID_RC_OK , .Li UUID_RC_ARG , .Li UUID_RC_MEM , .Li UUID_RC_SYS , .Li UUID_RC_INT , .Li UUID_RC_IMP , .Li UUID_MAKE_V1 , .Li UUID_MAKE_V3 , .Li UUID_MAKE_V4 , .Li UUID_MAKE_V5 , .Li UUID_MAKE_MC , .Li UUID_MAKE_V6 , .Li UUID_MAKE_V7 , .Li UUID_FMT_BIN , .Li UUID_FMT_STR , .Li UUID_FMT_SIV , .Li UUID_FMT_TXT . . .Sh EXAMPLES The following two examples create the version 3 UUID .Li 02d9e6d5-9467-382e-8f9b-9300a64ac3cd , both via the OO-style and the C-style API. Error handling is omitted here for easier reading, but has to be added for production-quality code. . .Bd -literal # TIE-style API (very high-level) use OSSP::uuid; tie my $uuid, 'OSSP::uuid::tie'; $uuid = [ "v1" ]; print "UUIDs: $uuid, $uuid, $uuid\\n"; $uuid = [ "v3", "ns:URL", "http://www.ossp.org/" ]; print "UUIDs: $uuid, $uuid, $uuid\\n"; untie $uuid; # OO-style API (high-level) use OSSP::uuid; my $uuid = new OSSP::uuid; my $uuid_ns = new OSSP::uuid; $uuid_ns->load("ns:URL"); $uuid->make("v3", $uuid_ns, "http://www.ossp.org/"); undef $uuid_ns; my $str = $uuid->export("str"); undef $uuid; print "$str\\n"; # C-style API (low-level) use OSSP::uuid qw(:all); my $uuid; uuid_create($uuid); my $uuid_ns; uuid_create($uuid_ns); uuid_load($uuid_ns, "ns:URL"); uuid_make($uuid, UUID_MAKE_V3, $uuid_ns, "http://www.ossp.org/"); uuid_destroy($uuid_ns); my $str; uuid_export($uuid, UUID_FMT_STR, $str, undef); uuid_destroy($uuid); print "$str\\n"; .Ed . .Sh SEE ALSO .Xr uuid 1 , .Xr uuid-config 1 , .Xr uuid 3 . .Sh HISTORY The Perl binding .Nm to OSSP .Nm uuid was implemented in November 2004 by .An Ralf S. Engelschall Aq rse@engelschall.com . ossp-uuid-UUID_1_6_4/perl/uuid.pm.in000066400000000000000000000250401472561253600173310ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2007 Ralf S. Engelschall ## Copyright (c) 2004-2007 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid.pm: Perl Binding (Perl part) ## ## ## High-Level Perl Module TIE-style API ## (just a functionality-reduced TIE wrapper around the OO-style API) ## package OSSP::uuid::tie; use 5.008; use strict; use warnings; use Carp; # inhert from Tie::Scalar require Tie::Scalar; our @ISA = qw(Tie::Scalar); # helper function sub mode_sanity { my ($mode) = @_; if (not ( defined($mode) and ref($mode) eq 'ARRAY' and ( (@{$mode} == 1 and $mode->[0] =~ m|^v[14]$|) or (@{$mode} == 3 and $mode->[0] =~ m|^v[35]$|)))) { return (undef, "invalid UUID generation mode specification"); } if ($mode->[0] =~ m|^v[35]$|) { my $uuid_ns = new OSSP::uuid; $uuid_ns->load($mode->[1]) or return (undef, "failed to load UUID $mode->[0] namespace"); $mode->[1] = $uuid_ns; } return ($mode, undef); } # constructor sub TIESCALAR { my ($class, @args) = @_; my $self = {}; bless ($self, $class); $self->{-uuid} = new OSSP::uuid or croak "failed to create OSSP::uuid object"; my ($mode, $error) = mode_sanity(defined($args[0]) ? [ @args ] : [ "v1" ]); croak $error if defined($error); $self->{-mode} = $mode; return $self; } # destructor sub DESTROY { my ($self) = @_; delete $self->{-uuid}; delete $self->{-mode}; return; } # fetch value from scalar # (applied semantic: export UUID in string format) sub FETCH { my ($self) = @_; $self->{-uuid}->make(@{$self->{-mode}}) or croak "failed to generate new UUID"; my $value = $self->{-uuid}->export("str") or croak "failed to export new UUID"; return $value; } # store value into scalar # (applied semantic: configure new UUID generation mode) sub STORE { my ($self, $value) = @_; my ($mode, $error) = mode_sanity($value); croak $error if defined($error); $self->{-mode} = $mode; return; } ## ## High-Level Perl Module OO-style API ## (just an OO wrapper around the C-style API) ## package OSSP::uuid; use 5.008; use strict; use warnings; use Carp; use XSLoader; use Exporter; # API version our $VERSION = do { my @v = ('%VERSION%' =~ m/\d+/g); sprintf("%d.".("%02d"x$#v), @v); }; # API inheritance our @ISA = qw(Exporter); # API symbols my $symbols = { 'const' => [qw( UUID_VERSION UUID_LEN_BIN UUID_LEN_STR UUID_LEN_SIV UUID_RC_OK UUID_RC_ARG UUID_RC_MEM UUID_RC_SYS UUID_RC_INT UUID_RC_IMP UUID_MAKE_V1 UUID_MAKE_V3 UUID_MAKE_V4 UUID_MAKE_V5 UUID_MAKE_MC UUID_MAKE_V6 UUID_MAKE_V7 UUID_FMT_BIN UUID_FMT_STR UUID_FMT_SIV UUID_FMT_TXT )], 'func' => [qw( uuid_create uuid_destroy uuid_load uuid_make uuid_isnil uuid_ismax uuid_compare uuid_import uuid_export uuid_error uuid_version )] }; # API symbol exportation our %EXPORT_TAGS = ( 'all' => [ @{$symbols->{'const'}}, @{$symbols->{'func'}} ], 'const' => [ @{$symbols->{'const'}} ], 'func' => [ @{$symbols->{'func'}} ] ); our @EXPORT_OK = @{$EXPORT_TAGS{'all'}}; our @EXPORT = (); # constructor sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless ($self, $class); $self->{-uuid} = undef; $self->{-rc} = $self->UUID_RC_OK; my $rc = uuid_create($self->{-uuid}); if ($rc != $self->UUID_RC_OK) { croak(sprintf("OSSP::uuid::new: uuid_create: %s (%d)", uuid_error($rc), $rc)); return undef; } return $self; } # destructor sub DESTROY ($) { my ($self) = @_; $self->{-rc} = uuid_destroy($self->{-uuid}) if (defined($self->{-uuid})); if ($self->{-rc} != $self->UUID_RC_OK) { carp(sprintf("OSSP::uuid::DESTROY: uuid_destroy: %s (%d)", uuid_error($self->{-rc}), $self->{-rc})); return; } $self->{-uuid} = undef; $self->{-rc} = undef; return; } sub load ($$) { my ($self, $name) = @_; $self->{-rc} = uuid_load($self->{-uuid}, $name); return ($self->{-rc} == $self->UUID_RC_OK); } sub make ($$;@) { my ($self, $mode, @valist) = @_; my $mode_code = 0; foreach my $spec (split(/,/, $mode)) { if ($spec eq 'v1') { $mode_code |= $self->UUID_MAKE_V1; } elsif ($spec eq 'v3') { $mode_code |= $self->UUID_MAKE_V3; } elsif ($spec eq 'v4') { $mode_code |= $self->UUID_MAKE_V4; } elsif ($spec eq 'v5') { $mode_code |= $self->UUID_MAKE_V5; } elsif ($spec eq 'mc') { $mode_code |= $self->UUID_MAKE_MC; } elsif ($spec eq 'v6') { $mode_code |= $self->UUID_MAKE_V6; } elsif ($spec eq 'v7') { $mode_code |= $self->UUID_MAKE_V7; } else { croak("invalid mode specification \"$spec\""); } } if (($mode_code & $self->UUID_MAKE_V3) or ($mode_code & $self->UUID_MAKE_V5)) { if (not (ref($valist[0]) and $valist[0]->isa("OSSP::uuid"))) { croak("UUID_MAKE_V3/UUID_MAKE_V5 requires namespace argument to be OSSP::uuid object"); } my $ns = $valist[0]->{-uuid}; my $name = $valist[1]; $self->{-rc} = uuid_make($self->{-uuid}, $mode_code, $ns, $name); } else { $self->{-rc} = uuid_make($self->{-uuid}, $mode_code); } return ($self->{-rc} == $self->UUID_RC_OK); } sub isnil ($) { my ($self) = @_; my $result; $self->{-rc} = uuid_isnil($self->{-uuid}, $result); return ($self->{-rc} == $self->UUID_RC_OK ? $result : undef); } sub ismax ($) { my ($self) = @_; my $result; $self->{-rc} = uuid_ismax($self->{-uuid}, $result); return ($self->{-rc} == $self->UUID_RC_OK ? $result : undef); } sub compare ($$) { my ($self, $other) = @_; my $result = 0; if (not (ref($other) and $other->isa("OSSP::uuid"))) { croak("argument has to be an OSSP::uuid object"); } $self->{-rc} = uuid_compare($self->{-uuid}, $other->{-uuid}, $result); return ($self->{-rc} == $self->UUID_RC_OK ? $result : undef); } sub import { # ATTENTION: The OSSP uuid API function "import" conflicts with # the standardized "import" method the Perl world expects from # their modules. In order to keep the Perl binding consist # with the C API, we solve the conflict under run-time by # distinguishing between the two types of "import" calls. if (defined($_[0]) and ref($_[0]) =~ m/^OSSP::uuid/) { # the regular OSSP::uuid "import" method croak("import method expects 3 or 4 arguments") if (@_ < 3 or @_ > 4); # emulate prototype my ($self, $fmt, $data_ptr, $data_len) = @_; if ($fmt eq 'bin') { $fmt = $self->UUID_FMT_BIN; } elsif ($fmt eq 'str') { $fmt = $self->UUID_FMT_STR; } elsif ($fmt eq 'siv') { $fmt = $self->UUID_FMT_SIV; } elsif ($fmt eq 'txt') { $fmt = $self->UUID_FMT_TXT; } else { croak("invalid format \"$fmt\""); } $data_len ||= length($data_ptr); # functional redudant, but Perl dislikes undef value here $self->{-rc} = uuid_import($self->{-uuid}, $fmt, $data_ptr, $data_len); return ($self->{-rc} == $self->UUID_RC_OK); } else { # the special Perl "import" method # (usually inherited from the Exporter) no strict "refs"; return OSSP::uuid->export_to_level(1, @_); } } sub export { # ATTENTION: The OSSP uuid API function "export" conflicts with # the standardized "export" method the Perl world expects from # their modules. In order to keep the Perl binding consist # with the C API, we solve the conflict under run-time by # distinguishing between the two types of "export" calls. if (defined($_[0]) and ref($_[0]) =~ m/^OSSP::uuid/) { # the regular OSSP::uuid "export" method croak("export method expects 2 arguments") if (@_ != 2); # emulate prototype my ($self, $fmt) = @_; my $data_ptr; if ($fmt eq 'bin') { $fmt = $self->UUID_FMT_BIN; } elsif ($fmt eq 'str') { $fmt = $self->UUID_FMT_STR; } elsif ($fmt eq 'siv') { $fmt = $self->UUID_FMT_SIV; } elsif ($fmt eq 'txt') { $fmt = $self->UUID_FMT_TXT; } else { croak("invalid format \"$fmt\""); } $self->{-rc} = uuid_export($self->{-uuid}, $fmt, $data_ptr, undef); return ($self->{-rc} == $self->UUID_RC_OK ? $data_ptr : undef); } else { # the special Perl "export" method # (usually inherited from the Exporter) return Exporter::export(@_); } } sub error ($;$) { my ($self, $rc) = @_; $rc = $self->{-rc} if (not defined($rc)); return wantarray ? (uuid_error($rc), $rc) : uuid_error($rc); } sub version (;$) { my ($self) = @_; return uuid_version(); } ## ## Low-Level Perl XS C-style API ## (actually just the activation of the XS part) ## # auto-loading constants sub AUTOLOAD { my $constname; our $AUTOLOAD; ($constname = $AUTOLOAD) =~ s/.*:://; croak "&OSSP::uuid::constant not defined" if ($constname eq 'constant'); my ($error, $val) = constant($constname); croak $error if ($error); { no strict 'refs'; *$AUTOLOAD = sub { $val }; } goto &$AUTOLOAD; } # static-loading functions XSLoader::load('OSSP::uuid', $VERSION); 1; ossp-uuid-UUID_1_6_4/perl/uuid.tm000066400000000000000000000030431472561253600167270ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2007 Ralf S. Engelschall ## Copyright (c) 2004-2007 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid.tm: Perl XS typemap for xsubpp(1) ## TYPEMAP uuid_t * T_PTRREF uuid_t ** T_PTRREF uuid_rc_t T_IV uuid_fmt_t T_IV int * T_PV size_t * T_PV const void * T_PV void ** T_PV ossp-uuid-UUID_1_6_4/perl/uuid.ts000066400000000000000000000140361472561253600167410ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2007 Ralf S. Engelschall ## Copyright (c) 2004-2007 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid.ts: Perl Binding (Perl test suite part) ## use Test::More tests => 43; ## ## Module Loading ## BEGIN { use_ok('OSSP::uuid'); }; BEGIN { use OSSP::uuid qw(:all); ok(defined(UUID_VERSION), "UUID_VERSION"); ok(UUID_RC_OK == 0, "UUID_RC_OK"); }; ## ## C-Style API ## my ($rc, $result, $uuid, $uuid_ns, $str, $ptr, $len); $rc = uuid_create($uuid); ok($rc == UUID_RC_OK, "uuid_create (1)"); $rc = uuid_create($uuid_ns); ok($rc == UUID_RC_OK, "uuid_create (2)"); $rc = uuid_isnil($uuid, $result); ok(($rc == UUID_RC_OK and $result == 1), "uuid_isnil (1)"); $rc = uuid_isnil($uuid_ns, $result); ok(($rc == UUID_RC_OK and $result == 1), "uuid_isnil (2)"); $rc = uuid_compare($uuid, $uuid_ns, $result); ok(($rc == UUID_RC_OK and $result == 0), "uuid_compare (1)"); $rc = uuid_export($uuid, UUID_FMT_STR, $ptr, $len); ok(( $rc == UUID_RC_OK and $ptr eq "00000000-0000-0000-0000-000000000000" and $len == UUID_LEN_STR), "uuid_export (1)"); $rc = uuid_load($uuid, "max"); ok($rc == UUID_RC_OK, "uuid_load (1)"); $rc = uuid_export($uuid, UUID_FMT_STR, $ptr, $len); ok(( $rc == UUID_RC_OK and $ptr eq "ffffffff-ffff-ffff-ffff-ffffffffffff" and $len == UUID_LEN_STR), "uuid_export (1.5)"); $rc = uuid_ismax($uuid, $result); ok(($rc == UUID_RC_OK and $result == 1), "uuid_ismax"); $rc = uuid_load($uuid_ns, "ns:URL"); ok($rc == UUID_RC_OK, "uuid_load (1)"); $rc = uuid_export($uuid_ns, UUID_FMT_STR, $ptr, $len); ok(( $rc == UUID_RC_OK and $ptr eq "6ba7b811-9dad-11d1-80b4-00c04fd430c8" and $len == UUID_LEN_STR), "uuid_export (2)"); $rc = uuid_make($uuid, UUID_MAKE_V3, $uuid_ns, "http://www.ossp.org/"); ok($rc == UUID_RC_OK, "uuid_make (1)"); $rc = uuid_export($uuid, UUID_FMT_STR, $ptr, $len); ok(( $rc == UUID_RC_OK and $ptr eq "02d9e6d5-9467-382e-8f9b-9300a64ac3cd" and $len == UUID_LEN_STR), "uuid_export (3)"); $rc = uuid_export($uuid, UUID_FMT_BIN, $ptr, $len); ok(( $rc == UUID_RC_OK and $len == UUID_LEN_BIN), "uuid_export (4)"); $rc = uuid_import($uuid_ns, UUID_FMT_BIN, $ptr, $len); ok($rc == UUID_RC_OK, "uuid_import (1)"); $rc = uuid_export($uuid_ns, UUID_FMT_STR, $ptr, $len); ok(( $rc == UUID_RC_OK and $ptr eq "02d9e6d5-9467-382e-8f9b-9300a64ac3cd" and $len == UUID_LEN_STR), "uuid_export (5)"); $rc = uuid_export($uuid_ns, UUID_FMT_SIV, $ptr, $len); ok(( $rc == UUID_RC_OK and $ptr eq "3789866285607910888100818383505376205" and $len <= UUID_LEN_SIV), "uuid_export (6)"); $rc = uuid_destroy($uuid_ns); ok($rc == UUID_RC_OK, "uuid_destroy (1)"); $rc = uuid_destroy($uuid); ok($rc == UUID_RC_OK, "uuid_destroy (2)"); ## ## OO-style API ## $uuid = new OSSP::uuid; ok(defined($uuid), "new OSSP::uuid (1)"); $uuid_ns = new OSSP::uuid; ok(defined($uuid_ns), "new OSSP::uuid (2)"); $rc = $uuid->isnil(); ok((defined($rc) and $rc == 1), "isnil (1)"); $rc = $uuid_ns->isnil(); ok((defined($rc) and $rc == 1), "isnil (2)"); $rc = $uuid->compare($uuid_ns); ok((defined($rc) and $rc == 0), "compare (1)"); $ptr = $uuid->export("str"); ok(( defined($ptr) and $ptr eq "00000000-0000-0000-0000-000000000000" and length($ptr) == UUID_LEN_STR), "export (1)"); $rc = $uuid_ns->load("ns:URL"); ok(defined($rc), "uuid_load (1)"); $ptr = $uuid_ns->export("str"); ok(( defined($ptr) and $ptr eq "6ba7b811-9dad-11d1-80b4-00c04fd430c8" and length($ptr) == UUID_LEN_STR), "export (2)"); $rc = $uuid->make("v3", $uuid_ns, "http://www.ossp.org/"); ok(defined($rc), "make (1)"); $ptr = $uuid->export("str"); ok(( defined($ptr) and $ptr eq "02d9e6d5-9467-382e-8f9b-9300a64ac3cd" and length($ptr) == UUID_LEN_STR), "export (3)"); $ptr = $uuid->export("bin"); ok(( defined($ptr) and length($ptr) == UUID_LEN_BIN), "export (4)"); $rc = $uuid_ns->import("bin", $ptr); ok(defined($rc), "import (1)"); $ptr = $uuid_ns->export("str"); ok(( defined($ptr) and $ptr eq "02d9e6d5-9467-382e-8f9b-9300a64ac3cd" and length($ptr) == UUID_LEN_STR), "export (5)"); $rc = $uuid->make("v6"); ok(defined($rc), "make (v6)"); $rc = $uuid->make("v7"); ok(defined($rc), "make (v7)"); $rc = $uuid->load("max"); ok(defined($rc), "uuid_load (max)"); $rc = $uuid->ismax(); ok((defined($rc) and $rc == 1), "ismax"); undef $uuid; undef $uuid_ns; ## ## TIE API ## $uuid = new OSSP::uuid; tie my $var, 'OSSP::uuid::tie'; my $val_get1 = $var; my $val_get2 = $var; ok($val_get1 ne $val_get2, "subsequent generation"); $uuid->import("str", $val_get1); my $val_cmp1 = $uuid->export("str"); $uuid->import("str", $val_get2); my $val_cmp2 = $uuid->export("str"); ok($val_get1 eq $val_cmp1, "validity comparison 1"); ok($val_get2 eq $val_cmp2, "validity comparison 2"); $var = [ "v3", "ns:URL", "http://www.ossp.org/" ]; $val_get1 = $var; ok($val_get1 eq "02d9e6d5-9467-382e-8f9b-9300a64ac3cd", "generation of UUID v3"); ossp-uuid-UUID_1_6_4/perl/uuid.xs000066400000000000000000000156041472561253600167470ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2007 Ralf S. Engelschall ** Copyright (c) 2004-2007 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid.xs: Perl Binding (Perl/XS part) */ #include "uuid.h" /* workaround conflicts with system headers */ #define uuid_t __vendor_uuid_t #define uuid_create __vendor_uuid_create #define uuid_compare __vendor_uuid_compare #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #undef uuid_t #undef uuid_create #undef uuid_compare MODULE = OSSP::uuid PACKAGE = OSSP::uuid void constant(sv) PREINIT: dXSTARG; STRLEN len; int i; static struct { const char *name; int value; } constant_table[] = { { "UUID_VERSION", UUID_VERSION }, { "UUID_LEN_BIN", UUID_LEN_BIN }, { "UUID_LEN_STR", UUID_LEN_STR }, { "UUID_LEN_SIV", UUID_LEN_SIV }, { "UUID_RC_OK", UUID_RC_OK }, { "UUID_RC_ARG", UUID_RC_ARG }, { "UUID_RC_MEM", UUID_RC_MEM }, { "UUID_RC_SYS", UUID_RC_SYS }, { "UUID_RC_INT", UUID_RC_INT }, { "UUID_RC_IMP", UUID_RC_IMP }, { "UUID_MAKE_V1", UUID_MAKE_V1 }, { "UUID_MAKE_V3", UUID_MAKE_V3 }, { "UUID_MAKE_V4", UUID_MAKE_V4 }, { "UUID_MAKE_V5", UUID_MAKE_V5 }, { "UUID_MAKE_MC", UUID_MAKE_MC }, { "UUID_MAKE_V6", UUID_MAKE_V6 }, { "UUID_MAKE_V7", UUID_MAKE_V7 }, { "UUID_FMT_BIN", UUID_FMT_BIN }, { "UUID_FMT_STR", UUID_FMT_STR }, { "UUID_FMT_SIV", UUID_FMT_SIV }, { "UUID_FMT_TXT", UUID_FMT_TXT } }; INPUT: SV *sv; const char *s = SvPV(sv, len); PPCODE: for (i = 0; i < sizeof(constant_table)/sizeof(constant_table[0]); i++) { if (strcmp(s, constant_table[i].name) == 0) { EXTEND(SP, 1); PUSHs(&PL_sv_undef); PUSHi(constant_table[i].value); break; } } if (i == sizeof(constant_table)/sizeof(constant_table[0])) { sv = sv_2mortal(newSVpvf("unknown constant OSSP::uuid::%s", s)); PUSHs(sv); } uuid_rc_t uuid_create(uuid) PROTOTYPE: $ INPUT: uuid_t *&uuid = NO_INIT CODE: RETVAL = uuid_create(&uuid); OUTPUT: uuid RETVAL uuid_rc_t uuid_destroy(uuid) PROTOTYPE: $ INPUT: uuid_t *uuid CODE: RETVAL = uuid_destroy(uuid); OUTPUT: RETVAL uuid_rc_t uuid_load(uuid,name) PROTOTYPE: $$ INPUT: uuid_t *uuid const char *name CODE: RETVAL = uuid_load(uuid, name); OUTPUT: RETVAL uuid_rc_t uuid_make(uuid,mode,...) PROTOTYPE: $$;$$ INPUT: uuid_t *uuid unsigned int mode PREINIT: uuid_t *ns; const char *name; CODE: if ((mode & UUID_MAKE_V3) || (mode & UUID_MAKE_V5)) { if (items != 4) croak("mode UUID_MAKE_V3/UUID_MAKE_V5 requires two additional arguments to uuid_make()"); if (!SvROK(ST(2))) croak("mode UUID_MAKE_V3/UUID_MAKE_V5 requires a UUID object as namespace"); ns = INT2PTR(uuid_t *, SvIV((SV*)SvRV(ST(2)))); name = (const char *)SvPV_nolen(ST(3)); RETVAL = uuid_make(uuid, mode, ns, name); } else { if (items != 2) croak("invalid number of arguments to uuid_make()"); RETVAL = uuid_make(uuid, mode); } OUTPUT: RETVAL uuid_rc_t uuid_isnil(uuid,result) PROTOTYPE: $$ INPUT: uuid_t *uuid int &result = NO_INIT CODE: RETVAL = uuid_isnil(uuid, &result); OUTPUT: result RETVAL uuid_rc_t uuid_ismax(uuid,result) PROTOTYPE: $$ INPUT: uuid_t *uuid int &result = NO_INIT CODE: RETVAL = uuid_ismax(uuid, &result); OUTPUT: result RETVAL uuid_rc_t uuid_compare(uuid,uuid2,result) PROTOTYPE: $$$ INPUT: uuid_t *uuid uuid_t *uuid2 int &result = NO_INIT CODE: RETVAL = uuid_compare(uuid, uuid2, &result); OUTPUT: result RETVAL uuid_rc_t uuid_import(uuid,fmt,data_ptr,data_len) PROTOTYPE: $$$$ INPUT: uuid_t *uuid uuid_fmt_t fmt const void *data_ptr size_t data_len CODE: if (ST(3) == &PL_sv_undef) data_len = sv_len(ST(2)); RETVAL = uuid_import(uuid, fmt, data_ptr, data_len); OUTPUT: RETVAL uuid_rc_t uuid_export(uuid,fmt,data_ptr,data_len) PROTOTYPE: $$$$ INPUT: uuid_t *uuid uuid_fmt_t fmt void *&data_ptr = NO_INIT size_t &data_len = NO_INIT PPCODE: data_ptr = NULL; data_len = 0; RETVAL = uuid_export(uuid, fmt, &data_ptr, &data_len); if (RETVAL == UUID_RC_OK) { if (fmt == UUID_FMT_SIV) data_len = strlen((char *)data_ptr); else if (fmt == UUID_FMT_STR || fmt == UUID_FMT_TXT) data_len--; /* Perl doesn't wish NUL-termination on strings */ sv_setpvn(ST(2), data_ptr, data_len); free(data_ptr); if (ST(3) != &PL_sv_undef) sv_setuv(ST(3), (UV)data_len); } PUSHi((IV)RETVAL); char * uuid_error(rc) PROTOTYPE: $ INPUT: uuid_rc_t rc CODE: RETVAL = uuid_error(rc); OUTPUT: RETVAL unsigned long uuid_version() PROTOTYPE: INPUT: CODE: RETVAL = uuid_version(); OUTPUT: RETVAL ossp-uuid-UUID_1_6_4/perl/uuid_compat.pm.in000066400000000000000000000111051472561253600206710ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2007 Ralf S. Engelschall ## Copyright (c) 2004-2007 The OSSP Project ## Copyright (c) 2004 Piotr Roszatycki ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid_compat.pm: Data::UUID Backward Compatibility Perl API ## package Data::UUID; use 5.006; use warnings; use strict; use OSSP::uuid; use MIME::Base64 qw(); require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(NameSpace_DNS NameSpace_OID NameSpace_URL NameSpace_X500); our $VERSION = do { my @v = ('%VERSION%' =~ m/\d+/g); sprintf("%d.".("%02d"x$#v), @v); }; sub new { my $class = shift; my $self = bless {}, $class; return $self; } sub create { my ($self) = @_; my $uuid = OSSP::uuid->new; $uuid->make('v4'); return $uuid->export('bin'); } sub create_from_name { my ($self, $nsid, $name) = @_; my $uuid = OSSP::uuid->new; my $nsiduuid = OSSP::uuid->new; $nsiduuid->import('bin', $nsid); $uuid = OSSP::uuid->new; $uuid->make('v3', $nsiduuid, $name); return $uuid->export('bin'); } sub to_string { my ($self, $bin) = @_; my $uuid = OSSP::uuid->new; $uuid->import('bin', $bin); return $uuid->export('str'); } sub to_hexstring { my ($self, $bin) = @_; my $uuid = OSSP::uuid->new; $uuid->import('bin', $bin); (my $string = '0x' . $uuid->export('str')) =~ s/-//g; return $string; } sub to_b64string { my ($self, $bin) = @_; return MIME::Base64::encode_base64($bin, ''); } sub from_string { my ($self, $str) = @_; my $uuid = OSSP::uuid->new; $uuid->import('str', $str =~ /^0x/ ? join '-', unpack('x2 a8 a4 a4 a4 a12', $str) : $str =~ /-/ ? $str : join '-', unpack('A8 A4 A4 A4 A12', $str) ); return $uuid->export('bin'); } sub from_hexstring { my ($self, $str) = @_; my $uuid = OSSP::uuid->new; $uuid->import('str', join '-', unpack('x2 a8 a4 a4 a4 a12', $str)); return $uuid->export('bin'); } sub from_b64string { my ($self, $b64) = @_; return MIME::Base64::decode_base64($b64); } sub compare { my ($self, $bin1, $bin2) = @_; my $uuid1 = OSSP::uuid->new; my $uuid2 = OSSP::uuid->new; $uuid1->import('bin', $bin1); $uuid2->import('bin', $bin2); return $uuid1->compare($uuid2); } my %NS = ( 'NameSpace_DNS' => 'ns:DNS', 'NameSpace_URL' => 'ns:URL', 'NameSpace_OID' => 'ns:OID', 'NameSpace_X500' => 'ns:X500', ); while (my ($k, $v) = each %NS) { no strict 'refs'; *{$k} = sub () { my $uuid = OSSP::uuid->new; $uuid->load($v); return $uuid->export('bin'); }; } sub constant { my ($self, $arg) = @_; my $uuid = OSSP::uuid->new; $uuid->load($NS{$arg} || 'nil'); return $uuid->export('bin'); } sub create_str { my $self = shift; return $self->to_string($self->create); } sub create_hex { my $self = shift; return $self->to_hexstring($self->create); } sub create_b64 { my $self = shift; return $self->to_b64string($self->create); } sub create_bin { my ($self) = @_; return $self->create($self); } sub create_from_name_str { my $self = shift; return $self->to_string($self->create_from_name(@_)); } sub create_from_name_hex { my $self = shift; return $self->to_hexstring($self->create_from_name(@_)); } sub create_from_name_b64 { my $self = shift; return $self->to_b64string($self->create_from_name(@_)); } 1; ossp-uuid-UUID_1_6_4/perl/uuid_compat.ts000066400000000000000000000045041472561253600203030ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2007 Ralf S. Engelschall ## Copyright (c) 2004-2007 The OSSP Project ## Copyright (c) 2004 Piotr Roszatycki ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid_compat.ts: Data::UUID Backward Compatibility Perl API (Perl test suite part) ## use Test::More tests => 19; BEGIN { use_ok('Data::UUID'); use Data::UUID; }; ok($ug = new Data::UUID); ok($uuid1 = $ug->create()); ok($uuid2 = $ug->to_hexstring($uuid1)); ok($uuid3 = $ug->from_string($uuid2)); ok($ug->compare($uuid1, $uuid3) == 0); ok($uuid4 = $ug->to_b64string($uuid1)); ok($uuid5 = $ug->to_b64string($uuid3)); ok($uuid4 eq $uuid5); ok($uuid6 = $ug->from_b64string($uuid5)); ok($ug->compare($uuid6, $uuid1) == 0); ok($uuid7 = NameSpace_URL); ok($uuid8 = $ug->from_string("6ba7b811-9dad-11d1-80b4-00c04fd430c8")); ok($ug->compare($uuid7, $uuid8) == 0); ok($uuid9 = $ug->from_string("6ba7b8119dad11d180b400c04fd430c8")); ok($ug->compare($uuid7, $uuid9) == 0); ok($uuid10 = $ug->create_from_name(NameSpace_URL, "https://hinfo.network/")); ok($uuid11 = $ug->from_string("c7f3eb3b-e7c8-3b6f-9b26-5a627478c57c")); ok($ug->compare($uuid10, $uuid11) == 0); ossp-uuid-UUID_1_6_4/test000077500000000000000000000166761472561253600154020ustar00rootroot00000000000000#!/bin/sh : ${uuid=./uuid} exp='encode: STR: f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6 SIV: 325725109554302597798550804656796594934 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 1 (time and node based) content: time: 2024-09-05 09:12:21.383982.0 UTC clock: 15100 (usually random) node: ef:df:f7:d5:f2:f6 (local multicast)' [ "$($uuid -d f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6 )" = "$exp" ] || { echo "uuid: -d f50c5fcc-6b66-11ef-bafc-efdff7d5f2f6 wrong" >&2; exit 1; } [ "$($uuid -dF SIV 325725109554302597798550804656796594934)" = "$exp" ] || { echo "uuid: -dF SIV 325725109554302597798550804656796594934 wrong" >&2; exit 1; } [ "$(printf '\365\014\137\314\153\146\021\357\272\374\357\337\367\325\362\366' | $uuid -dF BIN -)" = "$exp" ] || { echo "uuid: -dF BIN ... wrong" >&2; exit 1; } # https://bugs.debian.org/1041542 timemin='encode: STR: 00000000-0000-1100-a000-000000000000 SIV: 80291759423830037102592 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 1 (time and node based) content: time: 1811-02-16 23:50:03.792793.6 UTC clock: 8192 (usually random) node: 00:00:00:00:00:00 (global unicast)' [ "$($uuid -d 00000000-0000-1100-a000-000000000000)" = "$timemin" ] || { echo "uuid: -d 00000000-0000-1100-a000-000000000000 wrong" >&2 [ "$($uuid -d 00000000-0000-1100-a000-000000000000)" = "$(printf '%s\n' "$timemin" | sed 's/1811-02-16 23:50:03.792793.6/1947-03-26 06:18:19.792793.6/')" ] && \ echo " 32-bit time_t!" >&2 || exit 1 } timemax='encode: STR: ffffffff-ffff-1fff-bfc1-efc8990bbfa4 SIV: 340282366920937405648653289334120365988 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 1 (time and node based) content: time: 5236-03-31 21:21:00.684697.5 UTC clock: 16321 (usually random) node: ef:c8:99:0b:bf:a4 (local multicast)' [ "$($uuid -d FFFFFFFF-FFFF-1FFF-bfc1-efc8990bbfa4)" = "$timemax" ] || { echo "uuid: -d FFFFFFFF-FFFF-1FFF-bfc1-efc8990bbfa4 wrong" >&2 [ "$($uuid -d FFFFFFFF-FFFF-1FFF-bfc1-efc8990bbfa4)" = "$(printf '%s\n' "$timemax" | sed 's/5236-03-31 21:21:00.684697.5/1969-10-19 10:02:36.684697.5/')" ] && \ echo " 32-bit time_t!" >&2 || exit 1 } # https://bugs.debian.org/864530 # TODO: joey@darkstar:~>perl -le 'use OSSP::uuid; my $uuid = OSSP::uuid->new; $uuid->import("str", "4eb841ca-ce98-4590-8ea2-c4643bfa537bad"); print $uuid->export("str")' $uuid -d 4eb841ca-ce98-4590-8ea2-c4643bfa537bad >&2 2>/dev/null && { echo "uuid: -d 4eb841ca-ce98-4590-8ea2-c4643bfa537bad was accepted (\"bad\" trailer)" >&2; exit 1; } variant() { [ "$($uuid -d "00000000-0000-0000-${1}00-000000000001" | sed -n '/variant/s/.*: //p')" = "$2" ] || { echo "uuid: -d 00000000-0000-0000-${1}00-000000000001 variant != $2" >&2; exit 1; } } variant 00 "reserved (NCS backward compatible)" # 0 variant 80 "DCE 1.1, ISO/IEC 11578:1996" # 1 variant C0 "reserved (Microsoft GUID)" # 2 variant E0 "reserved (future use)" # 3 variant F0 "unknown" # 4 variant F8 "unknown" # 5 variant FC "unknown" # 6 variant FE "unknown" # 7 variant FF "unknown" # 8 version() { [ "$($uuid -d "00000000-0000-${1}000-0000-000000000001" | sed -n '/ version/s/.*: //p')" = "$2" ] || { echo "uuid: -d 00000000-0000-${1}000-0000-000000000001 version != $2" >&2; exit 1; } } version 0 "0 (unknown)" version 1 "1 (time and node based)" version 2 "2 (unknown)" version 3 "3 (name based, MD5)" version 4 "4 (random data based)" version 5 "5 (name based, SHA-1)" version 6 "6 (time and node based (time in reverse order))" version 7 "7 (UNIX time + random data)" for i in "8 8" "9 9" "a 10" "b 11" "c 12" "d 13" "e 14" "f 15"; do version ${i% *} "${i#* } (unknown)" done # https://datatracker.ietf.org/doc/html/rfc9562#appendix-A.1 $uuid -d C232AB00-9414-11EC-B3C8-9F6BDECED846 | grep -qF '2022-02-22 19:22:22.000000.0' || { echo "uuid: v1 vector C232AB00-9414-11EC-B3C8-9F6BDECED846 wrong" >&2; exit 1; } [ "$($uuid -v3 6ba7b810-9dad-11d1-80b4-00c04fd430c8 www.example.com)" = "5df41881-3aed-3515-88a7-2f4a814cf09e" ] || { echo "uuid: v3 vector 6ba7b810-9dad-11d1-80b4-00c04fd430c8 www.example.com wrong" >&2; exit 1; } [ "$($uuid -v5 6ba7b810-9dad-11d1-80b4-00c04fd430c8 www.example.com)" = "2ed6657d-e927-568b-95e1-2665a8aea6a2" ] || { echo "uuid: v5 vector 6ba7b810-9dad-11d1-80b4-00c04fd430c8 www.example.com wrong" >&2; exit 1; } $uuid -d 1EC9414C-232A-6B00-B3C8-9F6BDECED846 | grep -qF '2022-02-22 19:22:22.000000.0' || { echo "uuid: v6 vector 1EC9414C-232A-6B00-B3C8-9F6BDECED846 wrong" >&2; exit 1; } $uuid -d 017F22E2-79B0-7CC3-98C4-DC0C0C07398F | grep -qF '2022-02-22 19:22:22.000' || { echo "uuid: v7 vector 017F22E2-79B0-7CC3-98C4-DC0C0C07398F wrong" >&2; exit 1; } [ "$($uuid -v3 ns:URL https://hinfo.network/)" = c7f3eb3b-e7c8-3b6f-9b26-5a627478c57c ] || { echo "uuid: -v3 ns:URL https://hinfo.network/ != c7f3eb3b-e7c8-3b6f-9b26-5a627478c57c" >&2; exit 1; } [ "$($uuid -v3 nil https://hinfo.network/)" = 22f64d2e-f513-3e3b-bb47-aff88457bfff ] || { echo "uuid: -v3 nil https://hinfo.network/ != 22f64d2e-f513-3e3b-bb47-aff88457bfff" >&2; exit 1; } [ "$($uuid -v5 ns:URL https://hinfo.network/)" = a09c8ed6-09ed-5e3e-92b4-50352f02076f ] || { echo "uuid: -v5 ns:URL https://hinfo.network/ != a09c8ed6-09ed-5e3e-92b4-50352f02076f" >&2; exit 1; } [ "$($uuid -v5 nil https://hinfo.network/)" = 40b5012d-2428-5f89-925c-fe1a8d2a7a6c ] || { echo "uuid: -v5 nil https://hinfo.network/ != 40b5012d-2428-5f89-925c-fe1a8d2a7a6c" >&2; exit 1; } [ "$($uuid -d 0191c41a-9de1-7f96-b8cb-88e4348ee74c)" = \ 'encode: STR: 0191c41a-9de1-7f96-b8cb-88e4348ee74c SIV: 2086088501348764349551890213853128524 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 7 (UNIX time + random data) content: time: 2024-09-05 21:32:44.385 UTC random: 0F:96:38:CB:88:E4:34:8E:E7:4C' ] || { echo "uuid: -d 0191c41a-9de1-7f96-b8cb-88e4348ee74c wrong" >&2; exit 1; } timemax='encode: STR: ffffffff-ffff-7fff-bfff-ffffffffffff SIV: 340282366920937858995853114098753470463 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 7 (UNIX time + random data) content: time: 10889-08-02 05:31:50.655 UTC random: 0F:FF:3F:FF:FF:FF:FF:FF:FF:FF' [ "$($uuid -d ffffffff-ffff-7fff-bfff-ffffffffffff)" = "$timemax" ] || { echo "uuid: -d ffffffff-ffff-7fff-bfff-ffffffffffff wrong" >&2 [ "$($uuid -d ffffffff-ffff-7fff-bfff-ffffffffffff)" = "$(printf '%s\n' "$timemax" | sed 's/10889-08-02 05:31:50.655/1906-11-07 10:26:14.655/')" ] && \ echo " 32-bit time_t!" >&2 || exit 1 } [ "$($uuid -dFSIV 0)" = \ 'encode: STR: 00000000-0000-0000-0000-000000000000 SIV: 0 decode: variant: n.a. version: 0 (n.a.) content: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 (special case: DCE 1.1 Nil UUID)' ] || { echo "uuid: -d 00000000-0000-0000-0000-000000000000 wrong" >&2; exit 1; } [ "$($uuid -d ffffffff-ffff-ffff-ffff-ffffffffffff)" = \ 'encode: STR: ffffffff-ffff-ffff-ffff-ffffffffffff SIV: 340282366920938463463374607431768211455 decode: variant: n.a. version: 15 (n.a.) content: FF:FF:FF:FF:FF:FF:0F:FF:3F:FF:FF:FF:FF:FF:FF:FF (special case: RFC 9562 Max UUID)' ] || { echo "uuid: -d ffffffff-ffff-ffff-ffff-ffffffffffff wrong" >&2; exit 1; } ossp-uuid-UUID_1_6_4/uuid++.3.in000066400000000000000000000047251472561253600162520ustar00rootroot00000000000000.\" SPDX-License-Identifier: 0BSD .\" .Dd @UUID_VERSION_MDOC_DATE@ .ds doc-volume-operating-system OSSP .Dt UUID++ 3 .Os ossp-uuid @UUID_VERSION_RAW@ . .Sh NAME .Nm uuid++ .Nd deprecated unusable API to the C++ OSSP Universally Unique Identifier library .Sh SYNOPSIS .Bd -literal -compact .if t .in -10n #include class [[deprecated("the OSSP uuid++ library is broken, unsalvageable, and strictly worse than the C library (cf. uuid(3)). use that one")]] uuid { public: uuid(); uuid(const uuid &obj); uuid(const uuid_t *obj); // copy from C library uuid_t uuid(const void *bin); // import from UUID_FMT_BIN uuid(const char *str); // import from UUID_LEN_STR (or UUID_LEN_SIV if that fails) ~uuid(); uuid& operator=(const uuid &obj); uuid& operator=(const uuid_t *obj); // copy from C library uuid_t uuid& operator=(const void *bin); // import from UUID_FMT_BIN uuid& operator=(const char *str); // import from UUID_LEN_STR (or UUID_LEN_SIV if that fails) uuid clone(); // crash (or produce a broken UUID if it doesn't) void load(const char *name); // replace with uuid_load() void make(unsigned int mode, ...); // replace with uuid_make() int isnil(); // replace with uuid_isnil() int compare(const uuid &obj); // replace with uuid_compare() // == != < <= > >= operators void import(const void *bin); // replace with uuid_import(UUID_FMT_BIN) void import(const char *str); // replace with uuid_import(UUID_FMT_STR), uuid_import(UUID_FMT_SIV) void* binary(); // replace with uuid_export(UUID_FMT_BIN); always malloc()s char* string(); // replace with uuid_export(UUID_FMT_STR); always malloc()s char* integer(); // replace with uuid_export(UUID_FMT_SIV); always malloc()s char* summary(); // replace with uuid_export(UUID_FMT_TXT); always malloc()s unsigned long version(); // replace with uuid_version() }; class [[deprecated("the OSSP uuid++ library is broken, unsalvageable, and strictly worse than the C library (cf. uuid(3)). use that one")]] uuid_error_t { public: uuid_error_t() : uuid_error_t(UUID_RC_OK) {} uuid_error_t(uuid_rc_t code); ~uuid_error_t(); void code(uuid_rc_t code); // setter uuid_rc_t code(); // getter char * string(); // replace with uuid_error() }; .if t .in +10n .Ed . .Sh DESCRIPTION Replace with .Xr uuid 3 . ossp-uuid-UUID_1_6_4/uuid++.cc000066400000000000000000000170451472561253600160670ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid++.cc: library C++ API implementation */ #include #include #include "uuid++.hh" /* standard constructor */ uuid::uuid() { uuid_rc_t rc; if ((rc = uuid_create(&ctx)) != UUID_RC_OK) throw uuid_error_t(rc); } /* copy constructor */ uuid::uuid(const uuid &obj) { /* Notice: the copy constructor is the same as the assignment operator (with the object as the argument) below, except that (1) no check for self-assignment is required, (2) no existing internals have to be destroyed and (3) no return value is given back. */ uuid_rc_t rc; if ((rc = uuid_clone(obj.ctx, &ctx)) != UUID_RC_OK) throw uuid_error_t(rc); return; } /* extra constructor via C API object */ uuid::uuid(const uuid_t *obj) { uuid_rc_t rc; if (obj == NULL) throw uuid_error_t(UUID_RC_ARG); if ((rc = uuid_clone(obj, &ctx)) != UUID_RC_OK) throw uuid_error_t(rc); return; } /* extra constructor via binary representation */ uuid::uuid(const void *bin) { uuid_rc_t rc; if (bin == NULL) throw uuid_error_t(UUID_RC_ARG); if ((rc = uuid_create(&ctx)) != UUID_RC_OK) throw uuid_error_t(rc); import(bin); return; } /* extra constructor via string representation */ uuid::uuid(const char *str) { uuid_rc_t rc; if (str == NULL) throw uuid_error_t(UUID_RC_ARG); if ((rc = uuid_create(&ctx)) != UUID_RC_OK) throw uuid_error_t(rc); import(str); return; } /* standard destructor */ uuid::~uuid() { uuid_destroy(ctx); return; } /* assignment operator: import of other C++ API object */ uuid &uuid::operator=(const uuid &obj) { uuid_rc_t rc; if (this == &obj) return *this; if ((rc = uuid_destroy(ctx)) != UUID_RC_OK) throw uuid_error_t(rc); if ((rc = uuid_clone(obj.ctx, &ctx)) != UUID_RC_OK) throw uuid_error_t(rc); return *this; } /* assignment operator: import of other C API object */ uuid &uuid::operator=(const uuid_t *obj) { uuid_rc_t rc; if (obj == NULL) throw uuid_error_t(UUID_RC_ARG); if ((rc = uuid_clone(obj, &ctx)) != UUID_RC_OK) throw uuid_error_t(rc); return *this; } /* assignment operator: import of binary representation */ uuid &uuid::operator=(const void *bin) { if (bin == NULL) throw uuid_error_t(UUID_RC_ARG); import(bin); return *this; } /* assignment operator: import of string representation */ uuid &uuid::operator=(const char *str) { if (str == NULL) throw uuid_error_t(UUID_RC_ARG); import(str); return *this; } /* method: clone object */ uuid uuid::clone(void) { return new uuid(this); } /* method: loading existing UUID by name */ void uuid::load(const char *name) { uuid_rc_t rc; if (name == NULL) throw uuid_error_t(UUID_RC_ARG); if ((rc = uuid_load(ctx, name)) != UUID_RC_OK) throw uuid_error_t(rc); return; } /* method: making new UUID one from scratch */ void uuid::make(unsigned int mode, ...) { uuid_rc_t rc; va_list ap; va_start(ap, mode); if ((mode & UUID_MAKE_V3) || (mode & UUID_MAKE_V5)) { const uuid *ns = (const uuid *)va_arg(ap, const uuid *); const char *name = (const char *)va_arg(ap, char *); if (ns == NULL || name == NULL) throw uuid_error_t(UUID_RC_ARG); rc = uuid_make(ctx, mode, ns->ctx, name); } else rc = uuid_make(ctx, mode); va_end(ap); if (rc != UUID_RC_OK) throw uuid_error_t(rc); return; } /* method: comparison for Nil UUID */ int uuid::isnil(void) { uuid_rc_t rc; int rv; if ((rc = uuid_isnil(ctx, &rv)) != UUID_RC_OK) throw uuid_error_t(rc); return rv; } /* method: comparison against other object */ int uuid::compare(const uuid &obj) { uuid_rc_t rc; int rv; if ((rc = uuid_compare(ctx, obj.ctx, &rv)) != UUID_RC_OK) throw uuid_error_t(rc); return rv; } /* method: comparison for equality */ int uuid::operator==(const uuid &obj) { return (compare(obj) == 0); } /* method: comparison for inequality */ int uuid::operator!=(const uuid &obj) { return (compare(obj) != 0); } /* method: comparison for lower-than */ int uuid::operator<(const uuid &obj) { return (compare(obj) < 0); } /* method: comparison for lower-than-or-equal */ int uuid::operator<=(const uuid &obj) { return (compare(obj) <= 0); } /* method: comparison for greater-than */ int uuid::operator>(const uuid &obj) { return (compare(obj) > 0); } /* method: comparison for greater-than-or-equal */ int uuid::operator>=(const uuid &obj) { return (compare(obj) >= 0); } /* method: import binary representation */ void uuid::import(const void *bin) { uuid_rc_t rc; if ((rc = uuid_import(ctx, UUID_FMT_BIN, bin, UUID_LEN_BIN)) != UUID_RC_OK) throw uuid_error_t(rc); return; } /* method: import string or single integer value representation */ void uuid::import(const char *str) { uuid_rc_t rc; if ((rc = uuid_import(ctx, UUID_FMT_STR, str, UUID_LEN_STR)) != UUID_RC_OK) if ((rc = uuid_import(ctx, UUID_FMT_SIV, str, UUID_LEN_SIV)) != UUID_RC_OK) throw uuid_error_t(rc); return; } /* method: export binary representation */ void *uuid::binary(void) { uuid_rc_t rc; void *bin = NULL; if ((rc = uuid_export(ctx, UUID_FMT_BIN, &bin, NULL)) != UUID_RC_OK) throw uuid_error_t(rc); return bin; } /* method: export string representation */ char *uuid::string(void) { uuid_rc_t rc; char *str = NULL; if ((rc = uuid_export(ctx, UUID_FMT_STR, (void **)&str, NULL)) != UUID_RC_OK) throw uuid_error_t(rc); return str; } /* method: export single integer value representation */ char *uuid::integer(void) { uuid_rc_t rc; char *str = NULL; if ((rc = uuid_export(ctx, UUID_FMT_SIV, (void **)&str, NULL)) != UUID_RC_OK) throw uuid_error_t(rc); return str; } /* method: export textual summary representation */ char *uuid::summary(void) { uuid_rc_t rc; char *txt = NULL; if ((rc = uuid_export(ctx, UUID_FMT_TXT, (void **)&txt, NULL)) != UUID_RC_OK) throw uuid_error_t(rc); return txt; } /* method: return library version */ unsigned long uuid::version(void) { return uuid_version(); } ossp-uuid-UUID_1_6_4/uuid++.hh000066400000000000000000000117261472561253600161010ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid++.hh: library C++ API definition */ #ifndef __UUIDXX_HH__ #define __UUIDXX_HH__ #include "uuid.h" /* UUID object class */ class [[deprecated("the OSSP uuid++ library is broken, unsalvageable, and strictly worse than the C library (cf. uuid(3)). use that one")]] uuid { public: /* construction & destruction */ uuid (); /* standard constructor */ uuid (const uuid &_obj); /* copy constructor */ uuid (const uuid_t *_obj); /* import constructor */ uuid (const void *_bin); /* import constructor */ uuid (const char *_str); /* import constructor */ ~uuid (); /* destructor */ /* copying & cloning */ uuid &operator= (const uuid &_obj); /* copy assignment operator */ uuid &operator= (const uuid_t *_obj); /* import assignment operator */ uuid &operator= (const void *_bin); /* import assignment operator */ uuid &operator= (const char *_str); /* import assignment operator */ uuid clone (void); /* regular method */ // this uses the void* constructor lol /* content generation */ void load (const char *_name); /* regular method */ void make (unsigned int _mode, ...); /* regular method */ /* content comparison */ int isnil (void); /* regular method */ int compare (const uuid &_obj); /* regular method */ int operator== (const uuid &_obj); /* comparison operator */ int operator!= (const uuid &_obj); /* comparison operator */ int operator< (const uuid &_obj); /* comparison operator */ int operator<= (const uuid &_obj); /* comparison operator */ int operator> (const uuid &_obj); /* comparison operator */ int operator>= (const uuid &_obj); /* comparison operator */ /* content importing & exporting */ void import (const void *_bin); /* regular method */ void import (const char *_str); /* regular method */ void *binary (void); /* regular method */ char *string (void); /* regular method */ char *integer (void); /* regular method */ char *summary (void); /* regular method */ unsigned long version (void); /* regular method */ private: uuid_t *ctx; }; /* UUID exception class */ class [[deprecated("the OSSP uuid++ library is broken, unsalvageable, and strictly worse than the C library (cf. uuid(3)). use that one")]] uuid_error_t { public: uuid_error_t () { code(UUID_RC_OK); }; uuid_error_t (uuid_rc_t _code) { code(_code); }; ~uuid_error_t () { }; void code (uuid_rc_t _code) { rc = _code; }; uuid_rc_t code (void) { return rc; }; char *string (void) { return uuid_error(rc); }; private: uuid_rc_t rc; }; #endif /* __UUIDXX_HH__ */ ossp-uuid-UUID_1_6_4/uuid-config.1.in000066400000000000000000000075251472561253600173660ustar00rootroot00000000000000.\" .\" OSSP uuid - Universally Unique Identifier .\" Copyright (c) 2004-2008 Ralf S. Engelschall .\" Copyright (c) 2004-2008 The OSSP Project .\" .\" This file is part of OSSP uuid, a library for the generation .\" of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ .\" .\" Permission to use, copy, modify, and distribute this software for .\" any purpose with or without fee is hereby granted, provided that .\" the above copyright notice and this permission notice appear in all .\" copies. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED .\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR .\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" uuid-config.pod: library build utility manpage .Dd @UUID_VERSION_MDOC_DATE@ .ds doc-volume-operating-system OSSP .Dt UUID-CONFIG 1 .Os ossp-uuid @UUID_VERSION_RAW@ . .Sh NAME .Nm uuid-config .Nd OSSP uuid API build utility .Sh SYNOPSIS .Nm .Op Fl -help .Op Fl -version .Op Fl -prefix .Op Fl -exec-prefix .Op Fl -bindir .Op Fl -libdir .Op Fl -includedir .Op Fl -mandir .Op Fl -datadir .Op Fl -acdir .Op Fl -cflags .Op Fl -ldflags .Op Fl -libs . .Sh DESCRIPTION The .Nm program is a little helper utility for easy configuring and building of applications based on the .Xr uuid 3 library. It can be used to query the C compiler and linker flags which are required to correctly compile and link the application against the .Xr uuid 3 library. .Pp OSSP uuid also ships .Xr pkg-config 1 definition .Pq as Pa @libname@.pc . Use that instead. . .Sh OPTIONS .Bl -tag -compact -width ".Fl -exec-prefix" .It Fl -help Prints the short usage information. . .It Fl -version Prints the version number and date of the installed .Xr uuid 3 library. . .It Fl -prefix Prints the installation prefix of architecture independent files . .It Fl -exec-prefix Prints the installation prefix of architecture dependent files. . .It Fl -bindir Prints the installation directory of binaries. . .It Fl -libdir Prints the installation directory of libraries. . .It Fl -includedir Prints the installation directory of include headers. . .It Fl -mandir Prints the installation directory of manual pages. . .It Fl -datadir Prints the installation directory of shared data. . .It Fl -acdir Prints the installation directory of .Nm autoconf data. . .It Fl -cflags Prints the C compiler flags which are needed to compile the .Xr uuid 3 Ns -based application. The output is usually added to the .Ev CFLAGS uuidiable of the applications .Pa Makefile . . .It Fl ldflags Prints the linker flags .Pq Fl L which are needed to link the application with the .Xr uuid 3 library. The output is usually added to the .Ev LDFLAGS uuidiable of the applications .Pa Makefile . . .It Fl libs Prints the library flags .Pq Fl l which are needed to link the application with the C .Xr uuid 3 library. The output is usually added to the .Ev LIBS uuidiable of the applications .Pa Makefile . .El . .Sh EXAMPLES .Bd -literal -compact CC = cc CFLAGS = -O `uuid-config --cflags` LDFLAGS = `uuid-config --ldflags` LIBS = -lm `uuid-config --libs` all: foo foo: foo.o $(CC) $(LDFLAGS) -o foo foo.o $(LIBS) foo.o: foo.c $(CC) $(CFLAGS) -c foo.c .Ed . .Sh SEE ALSO .Xr uuid 1 , .Xr uuid 3 , .Xr OSSP::uuid 3 ossp-uuid-UUID_1_6_4/uuid-config.in000066400000000000000000000064651472561253600172310ustar00rootroot00000000000000#!/bin/sh ## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2008 Ralf S. Engelschall ## Copyright (c) 2004-2008 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid-config.in: library build utility ## prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" uuid_prefix="$prefix" uuid_exec_prefix="$exec_prefix" uuid_bindir="@bindir@" uuid_libdir="@libdir@" uuid_includedir="@includedir@" uuid_mandir="@mandir@" uuid_datadir="@datadir@" uuid_acdir="@datadir@/aclocal" uuid_version="@UUID_VERSION_STR@" usage="uuid-config" usage="$usage [--help] [--version]" usage="$usage [--prefix] [--exec-prefix] [--bindir] [--libdir] [--includedir] [--mandir] [--datadir] [--acdir]" usage="$usage [--cflags] [--ldflags] [--libs]" if [ $# -eq 0 ]; then echo "uuid-config:Error: Invalid option" >&2 echo "uuid-config:Usage: $usage" >&2 exit 1 fi output= for option; do option="${option%%=*}" case "$option" in --help|-h) echo "Usage: $usage" exit 0 ;; --version|-v) echo "OSSP uuid $uuid_version" exit 0 ;; --prefix) output="$output $uuid_prefix" ;; --exec-prefix) output="$output $uuid_exec_prefix" ;; --bindir) output="$output $uuid_bindir" ;; --libdir) output="$output $uuid_libdir" ;; --includedir) output="$output $uuid_includedir" ;; --mandir) output="$output $uuid_mandir" ;; --datadir) output="$output $uuid_datadir" ;; --acdir) output="$output $uuid_acdir" ;; --cflags) output="$output -I$uuid_includedir" ;; --ldflags) output="$output -L$uuid_libdir" ;; --libs) output="$output -l@libname@" ;; * ) echo "uuid-config:Error: Invalid option" >&2 echo "uuid-config:Usage: $usage" >&2 exit 1; ;; esac done if [ -n "$output" ]; then echo "${output# }" fi ossp-uuid-UUID_1_6_4/uuid.1.in000066400000000000000000000174211472561253600161170ustar00rootroot00000000000000.\" SPDX-License-Identifier: 0BSD .\" .Dd @UUID_VERSION_MDOC_DATE@ .ds doc-volume-operating-system OSSP .Dt UUID 1 .Os ossp-uuid @UUID_VERSION_RAW@ . .Sh NAME .Nm uuid .Nd generate, convert, and decode Universally Unique IDentifiers .Sh SYNOPSIS .Nm .Op Fl n Ar count .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Op Fl v Cm 1 .Op Fl m1 . .Nm .Op Fl n Ar count .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Fl v Cm 3 .Ar uuid Ns \&| Ns Cm nil Ns \&| Ns Cm max Ns \&| Ns Cm ns:\& Ns Brq Cm DNS Ns \&| Ns Cm URL Ns \&| Ns Cm OID Ns \&| Ns Cm X500 .Ar data . .Nm .Op Fl n Ar count .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Fl v Cm 4 . .Nm .Op Fl n Ar count .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Fl v Cm 5 .Ar uuid Ns \&| Ns Cm nil Ns \&| Ns Cm max Ns \&| Ns Cm ns:\& Ns Brq Cm DNS Ns \&| Ns Cm URL Ns \&| Ns Cm OID Ns \&| Ns Cm X500 .Ar data . .Nm .Op Fl n Ar count .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Fl v Cm 6 . .Nm .Op Fl n Ar count .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Fl v Cm 7 .Pp . .Nm .Fl d .Op Fl o Ar outfile .Op Cm \h'\w'\|-r\fR|\fP'u' Ns Fl F Cm \h'\w'BIN\fR|\fP'u'STR Ns \&| Ns Cm SIV .Ar uuid . .Nm .Fl d .Op Fl o Ar outfile .Op Fl r Ns \&| Ns Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV .Sy - . .Sh DESCRIPTION By default, generates a UUID (Universally Unique Identifier), of a version specified by .Fl v .Pq default Sy 1 in the canonical .Cm STR Ns ing format. .br With .Fl d , decodes .Ar uuid .Pq or reads it in from the standard input stream if Qq Sy - , yielding something akin to .Bd -literal -compact -offset 2n encode: STR: 92a3d3de-6bbf-11ef-9f5b-774ebb537938 SIV: 194917928982963228599463962120788605240 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 1 (time and node based) content: time: 2024-09-05 19:46:41.491043.0 UTC clock: 8027 (usually random) node: 77:4e:bb:53:79:38 (local multicast) .Ed or .Bd -literal -compact -offset 2n encode: STR: 7e017d98-cecc-41f6-8030-552d23cd38e6 SIV: 167490467173639937831846401373276813542 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 4 (random data based) content: 7E:01:7D:98:CE:CC:01:F6:00:30:55:2D:23:CD:38:E6 (no semantics: random data only) .Ed .Pp A UUID is a 128-bit (16-byte) number whose format (method of generation) makes it very likely that it will be unique, both spatially and temporally. This makes them well-suited for identifying anything from ephemera like database queries to databases themselves. .Pp The three principal .Fl F Ns ormats are: .Bl -tag -compact -offset 2n -width ".Cm SIV Pq Single Integer Value" .It Cm STR Ns ing .Li 01234567-890a-bcde-f012-3456789abcde (hexadecimal string broken up by dashes) . .It Cm SIV Pq Single Integer Value 128-bit decimal integer . .It Cm BIN Ns ary or \&"raw" the 16 bytes of the UUID in big endian order (most significant first) .El .Pp UUIDs come in a few .Fl v Ns ersions : .Bl -tag -compact -offset 2n -width ".Sy 4" .It Sy 1 based on the current time (to the precision of 100ns), and the host's MAC address (this implementation uses the MAC address of the first NIC it finds, unless .Fl m , in which case random data is substituted for the MAC) . .It Sy 6 very similar, but the most significant (slowest-changing) parts of the timestamp are stored first, which improves locality in some database applications .Pp . .It Sy 7 contains the current .Em \s[-1z]UNIX\s0 time \(em versions .Sy 1 and .Sy 6 encode a UUID time which is off by like 400 years \(em (to the precision of 1ms), then 10 bytes of random data. .br .Em This version should be preferred to 1 and 6.\& .Pp . .It Sy 3 hashes the "namespace" (first argument, either a .Cm STR Ns ing-format UUID or a well-known name (see below)) and the "name" (second argument, arbitrary data) with the .Xr MD5 3 digest, and uses that directly (a few branding bytes are replaced to identify the format) . .It Sy 5 the same as version .Sy 3 , but uses the first 16 bytes of the .Xr SHA1 3 digest .Pp . .It Sy 4 just random data .El .Pp The namespaces understood when generating version 3 and 5 UUIDs are: .Bl -tag -compact -offset 2n -width ".Cm ns:X500" .It Ar uuid (any valid .Cm STR Ns ingified UUID) .It Cm nil .Li 00000000-0000-0000-0000-000000000000 \(em the special all-zero UUID . .It Cm max .Li ffffffff-ffff-ffff-ffff-ffffffffffff \(em the special all-bits-set/sorts-after-everything sentinel UUID . .It Cm ns:DNS .Li 6ba7b810-9dad-11d1-80b4-00c04fd430c8 \(em for fully-qualified domain names . .It Cm ns:URL .Li 6ba7b811-9dad-11d1-80b4-00c04fd430c8 \(em for URLs . .It Cm ns:OID .Li 6ba7b812-9dad-11d1-80b4-00c04fd430c8 \(em for ISO OIDs . .It Cm ns:X500 .Li 6ba7b814-9dad-11d1-80b4-00c04fd430c8 \(em for X.500 Distinguished Names .El . .Sh OPTIONS .Bl -tag -compact -width ".Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV" .It Fl n Ar count Generate .Ar count UUIDs. Defaults to .Sy 1 . . .It Fl o Ar outfile Write to .Ar outfile . . .It Fl F Cm BIN Ns \&| Ns Cm STR Ns \&| Ns Cm SIV Produce output in the given format. Defaults to .Cm STR . . .It Fl r .Fl F Cm BIN . .It Fl v Cm 1 Ns \&| Ns Cm 3 Ns \&| Ns Cm 4 Ns \&| Ns Cm 5 Ns \&| Ns Cm 6 Ns \&| Ns Cm 7 Version to generate. Defaults to .Cm 1 . . .It Fl m .Fl v Cm 1 Ns \&| Ns Cm 6 only: ignore the current host's MAC addresses, use random data instead (this may still happen if the if a MAC can't be determined or all MACs are multicast). . .It Fl 1 .Fl v Cm 1 only, .Ar count >1 only: generate each UUID independently. Version 1 UUIDs have a field that increases monotonically within a session; thus, for example, in .Bd -literal -compact -offset 2n .Li $ Nm Fl n Ar 4 366ab5a3-6bc4-11ef-a31a-0026b986fdd4 366ab5ce-6bc4-11ef-a31b-0026b986fdd4 366ab5f8-6bc4-11ef-a31c-0026b986fdd4 366ab621-6bc4-11ef-a31d-0026b986fdd4 \(ha\(ha\(ha\(ha .Ed the highlighted column .Em starts random, but then increments. .Fl 1 generates each UUID de novo. .Pp . .It Fl d Decode and parse .Ar uuid . .Fl F sets which format to .Em read . .Fl F Cm BIN is only available when reading from the standard input stream .Pq Qq Sy - . .El . .Sh EXAMPLES A web site can be uniquely identified with a version 5 (SHA-1), namespace .Cm ns:DNS UUID, and a web-page \(em .Cm ns:URL (note that this information cannot be extracted, and only serves as a way to avoid collisions for otherwise-identical names): .Bd -literal -compact .Li $ Nm Fl v Cm 5 ns:DNS Ar hinfo.network.\& f50b485f-ac66-591d-b95f-2c946c5a5668 .Li $ Nm Fl v Cm 5 ns:URL Ar https://hinfo.network 8cebc56f-51d0-5323-a031-1b9258de14f8 .Li $ Nm Fl d Ar 8cebc56f-51d0-5323-a031-1b9258de14f8 encode: STR: f50b485f-ac66-591d-b95f-2c946c5a5668 SIV: 325719442146270326702531202385345926760 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 5 (name based, SHA-1) content: F5:0B:48:5F:AC:66:09:1D:39:5F:2C:94:6C:5A:56:68 (not decipherable: truncated SHA-1 message digest only) .Ed .Pp .Bd -literal -compact .Li $ Nm Fl v Cm 7 8cebc56f-51d0-5323-a031-1b9258de14f8 .Li $ Nm Fl d Ar 8cebc56f-51d0-5323-a031-1b9258de14f8 encode: STR: 0191c41a-9de1-7f96-b8cb-88e4348ee74c SIV: 2086088501348764349551890213853128524 decode: variant: DCE 1.1, ISO/IEC 11578:1996 version: 7 (UNIX time + random data) content: time: 2024-09-05 21:32:44.385 UTC random: 0F:96:38:CB:88:E4:34:8E:E7:4C .Ed . .Sh SEE ALSO .Xr uuid 3 , .Xr OSSP::uuid 3 . .Sh STANDARDS .Lk https://datatracker.ietf.org/doc/html/rfc9562 "RFC 9562: Universally Unique IDentifiers (UUIDs)" supersedes all previous standards with an unbecoming brevity. .Pp There are many Versions, but only one useful Variant. ossp-uuid-UUID_1_6_4/uuid.3.in000066400000000000000000000532561472561253600161270ustar00rootroot00000000000000'\" e .\" OSSP uuid - Universally Unique Identifier .\" Copyright (c) 2004-2008 Ralf S. Engelschall .\" Copyright (c) 2004-2008 The OSSP Project .\" .\" This file is part of OSSP uuid, a library for the generation .\" of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ .\" .\" Permission to use, copy, modify, and distribute this software for .\" any purpose with or without fee is hereby granted, provided that .\" the above copyright notice and this permission notice appear in all .\" copies. .\" .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED .\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR .\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND .\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .Dd @UUID_VERSION_MDOC_DATE@ .ds doc-volume-operating-system OSSP .Dt UUID 3 .Os ossp-uuid @UUID_VERSION_RAW@ . .Sh NAME .Nm uuid .Nd Universally Unique IDentifier .Sh SYNOPSIS .In uuid.h .Nm cc Li $( Ns Cm pkg-config Fl -libs -cflags Ar @libname@ Ns Li )\& ... . .Sh DESCRIPTION OSSP .Nm is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of RFC 9562, ISO/IEC 11578:1996 and IETF RFC-4122 compliant .Em Universally Unique Identifier (UUID). It supports DCE 1.1 variant UUIDs of version 1 (time and node based), version 3 (name based, MD5), version 4 (random number based) and version 5 (name based, SHA-1). Additional API bindings are provided for the Perl:5 language. Optional backward compatibility exists for the ISO-C DCE-1.1 and Perl Data::UUID APIs. .Pp UUIDs are 128 bit numbers which are intended to have a high likelihood of uniqueness over space and time and are computationally difficult to guess. They are globally unique identifiers which can be locally generated without contacting a global registration authority. UUIDs are intended as unique identifiers for both mass tagging objects with an extremely short lifetime and to reliably identifying very persistent objects across a network. .Pp This is the ISO-C application programming interface (API) of OSSP .Nm . . .Ss UUID Binary Representation According to RFC 9562, ISO/IEC 11578:1996 and IETF RFC-4122 standards, a DCE 1.1 variant UUID is a 128 bit number defined out of 7 fields, each field a multiple of an octet in size and stored in network byte order: .Bd -literal -compact [4] version -->| |<-- | | | | [16] [32] [16] | |time_hi time_low time_mid | _and_version |<---------------------------->||<------------>||<------------>| | MSB || || | | | / || || | | |/ || || | | +------++------++------++------++------++------++------++------+~~ | 15 || 14 || 13 || 12 || 11 || 10 |####9 || 8 | | MSO || || || || || |#### || | +------++------++------++------++------++------++------++------+~~ 7654321076543210765432107654321076543210765432107654321076543210 ~~+------++------++------++------++------++------++------++------+ ##* 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 | ##* || || || || || || || LSO | ~~+------++------++------++------++------++------++------++------+ 7654321076543210765432107654321076543210765432107654321076543210 | | || || /| | | || || / | | | || || LSB | |<---->||<---->||<-------------------------------------------->| |clk_seq clk_seq node |_hi_res _low [48] |[5-6] [8] | | -->| |<-- variant [2-3] .Ed .Pp An example of a UUID binary representation is the octet stream .Li 0xF8 0x1D 0x4F 0xAE 0x7D 0xEC 0x11 0xD0 0xA7 0x65 0x00 0xA0 0xC9 0x1E 0x6B 0xF6 . The binary representation format is exactly what the OSSP .Nm API functions .Fn uuid_import and .Fn uuid_export deal with under .Dv UUID_FMT_BIN . . .Ss UUID ASCII String Representation According to RFC 9562, ISO/IEC 11578:1996 and IETF RFC-4122 standards, a DCE 1.1 variant UUID is represented as an ASCII string consisting of 8 hexadecimal digits followed by a hyphen, then three groups of 4 hexadecimal digits each followed by a hyphen, then 12 hexadecimal digits. Formally, the string representation is defined by the following grammar: .Bd -literal -compact uuid = "-" "-" "-" "-" time_low = 4* time_mid = 2* time_high_and_version = 2* clock_seq_high_and_reserved = clock_seq_low = node = 6* hex_octet = hex_digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" |"a"|"b"|"c"|"d"|"e"|"f" |"A"|"B"|"C"|"D"|"E"|"F" .Ed .Pp An example of a UUID string representation is the ASCII string .Qq Li f81d4fae-7dec-11d0-a765-00a0c91e6bf6 . The string representation format is exactly what the OSSP .Nm API functions .Fn uuid_import and .Fn uuid_export deal with under .Dv UUID_FMT_STR . .Pp Notice: a corresponding URL can be generated out of a ASCII string representation of an UUID by prefixing with .Cm urn:uuid:\& as in .Qq Li urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 . . .Ss UUID Single Integer Value Representation According to the ISO/IEC 11578:1996 and ITU-T Rec. X.667 standards, a DCE 1.1 variant UUID can be also represented as a single integer value consisting of a decimal number with up to 39 digits. .Pp An example of a UUID single integer value representation is the decimal number .Qq Li 329800735698586629295641978511506172918 . The string representation format is exactly what the OSSP .Nm uuid API functions .Fn uuid_import and .Fn uuid_export deal with under .Dv UUID_FMT_SIV . .Pp Notice: a corresponding ISO OID can be generated under the .Qq "{joint-iso-itu-t(2) uuid(25)}" arc out of a single integer value representation of a UUID by prefixing with .Cm 2.25.\& . An example OID is .Qq Li 2.25.329800735698586629295641978511506172918 . Additionally, an URL can be generated by further prefixing with .Cm urn:oid:\& as in .Qq Li urn:oid:2.25.329800735698586629295641978511506172918 . . .Ss UUID Variants and Versions A UUID has a variant and version. The variant defines the layout of the UUID. The version defines the content of the UUID. The UUID variant supported in OSSP .Nm uuid is DCE 1.1 variant only. DCE 1.1 UUID variant versions supported in OSSP .Nm are: .Pp .Bl -tag -compact -width 4n .It Version Sy 1 Pq time and node based These are the classical UUIDs, created out of a 60-bit system time, a 14-bit local clock sequence and 48-bit system MAC address. The MAC address can be either the real one of a physical network interface card (NIC) or a random multi-cast MAC address. Version 1 UUIDs are usually used as one-time global unique identifiers. .Pp . .It Version Sy 3 Pq name based, MD5 These are UUIDs which are based on the 128-bit MD5 message digest of the concatenation of a 128-bit namespace UUID and a name string of arbitrary length. Version 3 UUIDs are usually used for non-unique but repeatable message digest identifiers. .Pp . .It Version Sy 4 Pq random data based These are UUIDs which are based on just 128-bit of random data. Version 4 UUIDs are usually used as one-time local unique identifiers. .Pp . .It Version Sy 5 Pq name based, SHA-1 These are UUIDs which are based on the 160-bit SHA-1 message digest of the concatenation of a 128-bit namespace UUID and a name string of arbitrary length. Version 5 UUIDs are usually used for non-unique but repeatable message digest identifiers. .Pp . .It Version Sy 5 Pq name based, SHA-1 These are UUIDs which are based on the 160-bit SHA-1 message digest of the concatenation of a 128-bit namespace UUID and a name string of arbitrary length. Version 5 UUIDs are usually used for non-unique but repeatable message digest identifiers. .Pp . .It Version Sy 6 Pq time (reverse) and node based These are compatible with and very similar to Version .Sy 1 UUIDs, except the time is stored from the most significant parts to the least significant parts. This improves locality in some database implementations. .Pp . .It Version Sy 7 Pq UNIX time based These UUIDs consist of a 48-bit UNIX time (with 1ms precision) in big-endian, then 10 bytes of random data. RFC 9562 .Em recommends these for new designs. .El . .Ss UUID Uniqueness Version .Sy 1 Ns / Ns Sy 6 UUIDs are guaranteed to be unique through combinations of hardware addresses, time stamps and random seeds. There is a reference in the UUID to the hardware (MAC) address of the first network interface card (NIC) on the host which generated the UUID \(em this reference is intended to ensure the UUID will be unique in space as the MAC address of every network card is assigned by a single global authority (IEEE) and is guaranteed to be unique. The next component in a UUID is a timestamp which, as clock always (should) move forward, will be unique in time. Just in case some part of the above goes wrong (the hardware address cannot be determined or the clock moved steps backward), there is a random clock sequence component placed into the UUID as a "catch-all" for uniqueness. .Pp Version .Sy 3 Ns / Ns Sy 5 UUIDs are guaranteed to be inherently globally unique if the combination of namespace and name used to generate them is unique. .Pp Version .Sy 4 UUIDs are not guaranteed to be globally unique, because they are generated out of locally gathered random numbers only. Nevertheless there is still a high likelihood of uniqueness over space and time and that they are computationally difficult to guess. .Pp Version .Sy 7 UUIDs attempt to guarantee uniqueness by subdividing each millisecond of real time into .ie t . \{ .EQ 2 sup 80 ( 10 sup 24 ) .EN . \} .el 2^80 (10^24) possible values. . .Ss Nil UUID There is a special .Va Nil UUID consisting of all octets set to zero in the binary representation. It can be used as a special UUID value which does not conflict with real UUIDs. . .Ss Max UUID Similarly to the .Va Nil UUID, the .Va Max UUID consists of all octets set to 0xFF (255, all bits set) in the binary representation. It can be used as a special UUID value which does not conflict with real UUIDs, but sorts after everything else. . .Sh APPLICATION PROGRAMMING INTERFACE The ISO-C Application Programming Interface (API) of OSSP .Nm uuid consists of the following components. . .Ss CONSTANTS The following constants are provided: .Bl -tag -compact -width 4n .It Dv UUID_VERSION The hexadecimal encoded OSSP .Nm version. This allows compile-time checking of the OSSP .Nm version. For run-time checking use .Fn uuid_version instead. .Pp The current value .Li @UUID_VERSION_HEX@ encodes .Li @UUID_VERSION_RAW@ . .Pp . .It Dv UUID_LEN_BIN , UUID_LEN_STR , UUID_LEN_SIV The number of octets of the UUID binary and string representations. Notice that the lengths of the string representation .Pq Dv UUID_LEN_STR and the lengths of the single integer value representation .Pq Dv UUID_LEN_SIV does .Em not include the necessary NUL termination character. .Pp . .It Dv UUID_MAKE_V1 , UUID_MAKE_V3 , UUID_MAKE_V4 , UUID_MAKE_V5 , UUID_MAKE_V6 , UUID_MAKE_V7 , UUID_MAKE_MC The .Fa mode bits for use with .Fn uuid_make . .Dv UUID_MAKE_V Ns Va n specify which UUID version to generate. .Dv UUID_MAKE_MC forces the use of a random multi-cast MAC address instead of the real physical MAC address in version 1 and 6 UUIDs. .Pp . .It Dv UUID_RC_OK , UUID_RC_ARG , UUID_RC_MEM , UUID_RC_SYS , UUID_RC_INT , UUID_RC_IMP The possible numerical return-codes of API functions. The .Dv UUID_RC_OK indicates success, the others indicate errors. Use .Fn uuid_error to translate them into string versions. .Pp . .It Dv UUID_FMT_BIN , UID_FMT_STR , UID_FMT_SIV , UID_FMT_TXT The .Fa fmt formats for use with .Fn uuid_import and .Fn uuid_export : .Bl -tag -compact -offset 2n -width ".Dv UUID_FMT_BIN" .It Dv UUID_FMT_BIN indicates the UUID binary representation .Pq of length Dv UUID_LEN_BIN , . .It Dv UUID_FMT_STR indicates the UUID string representation .Pq of length Dv UUID_LEN_STR , . .It Dv UUID_FMT_SIV indicates the UUID single integer value representation .Pq of maximum length Dv UUID_LEN_SIV , and . .It Dv UUID_FMT_TXT indicates the textual description (of arbitrary length) of a UUID .Pq this powers Xr uuid 1 Fl d . .El .El . .Ss FUNCTIONS .Bl -tag -compact -width 4n .It Xo .Ft uuid_rc_t .Fo uuid_create .Fa "uuid_t **uuid" .Fc .Xc Create a new UUID object and store a pointer to it in .Fa *uuid . A UUID object consists of an internal representation of a UUID, potential internal RNG context, and timestamp information. The initial UUID is the .Va Nil UUID. .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_destroy .Fa "uuid_t *uuid" .Fc .Xc Destroy UUID object .Fa uuid . .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_clone .Fa "const uuid_t *uuid" .Fa "uuid_t **uuid_clone" .Fc .Xc Clone UUID object .Fa uuid and store new UUID object in .Fa *uuid_clone . .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_isnil .Fa "const uuid_t *uuid" .Fa "int *result" .Fc .Xc Checks whether the UUID in uuid is the .Va Nil UUID. If this is the case, it returns .Sy 1 in .Fa *result . Else it returns .Sy false in .Fa *result . .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_ismax .Fa "const uuid_t *uuid" .Fa "int *result" .Fc .Xc Checks whether the UUID in uuid is the .Va Max UUID. If this is the case, it returns .Sy 1 in .Fa *result . Else it returns .Sy false in .Fa *result . .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_compare .Fa "const uuid_t *uuid" .Fa "const uuid_t *uuid2" .Fa "int *result" .Fc .Xc Compares the order of the two UUIDs and returns the result in .Fa *result : .Sy \-1 if .Fa uuid < .Fa uuid2 , .Sy 0 if .Fa uuid = .Fa uuid2 , and .Sy +1 if .Fa uuid > .Fa uuid2 . .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_import .Fa "uuid_t *uuid" .Fa "uuid_fmt_t fmt" .Fa "const void *data_ptr" .Fa "size_t data_len" .Fc .Xc Imports .Fa uuid from an external representation of format .Fa fmt . The data is read from the buffer at .Fa data_ptr which contains at least .Fa data_len bytes. .Pp The format of the external representation is specified by .Fa fmt and the minimum expected length in .Fa data_len depends on it. Valid values for .Fa fmt are .Dv UUID_FMT_BIN , .Dv UUID_FMT_STR , and .Dv UUID_FMT_SIV . .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_export .Fa "const uuid_t *uuid" .Fa "uuid_fmt_t fmt" .Fa "void *data_ptr" .Fa "size_t *data_len" .Fc .Xc Exports .Fa uuid into an external representation of format .Fa fmt . Valid values for .Fa fmt are .Dv UUID_FMT_BIN , .Dv UUID_FMT_STR , .Dv UUID_FMT_SIV , and .Dv UUID_FMT_TXT . .Pp The data is written to the buffer located at .Fa "*(type **)data_ptr" , where .Va type is .Vt uint8_t for .Dv UUID_FMT_BIN and .Vt char for other formats. .Pp The buffer has to have room for at least .Fa *data_len bytes. If .Fa "*(type **)data_ptr" is .Dv NULL , .Fa data_len is ignored as input and a new buffer is allocated with .Xr malloc 3 and returned in .Fa "*(type **)data_ptr" . .Pp If .Fa data_len is not .Dv NULL , the number of available bytes in the buffer has to be provided in .Fa *data_len . The number of actually written bytes are returned in .Fa *data_len again. The minimum required buffer length depends on the external representation as specified by .Fa fmt (see above). For .Dv UUID_FMT_TXT , a buffer of unspecified length is required, and hence it is recommended to allow OSSP .Nm to allocate the buffer as necessary. .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_load .Fa "uuid_t *uuid" .Fa "const char *name" .Fc .Xc Loads a pre-defined UUID value into .Fa uuid . The following .Fa name arguments are currently known: .Bl -tag -compact -offset 2n -width ".Cm ns:X500" .It Cm nil .Li 00000000-0000-0000-0000-000000000000 .It Cm max .Li ffffffff-ffff-ffff-ffff-ffffffffffff .It Cm ns:DNS .Li 6ba7b810-9dad-11d1-80b4-00c04fd430c8 .It Cm ns:URL .Li 6ba7b811-9dad-11d1-80b4-00c04fd430c8 .It Cm ns:OID .Li 6ba7b812-9dad-11d1-80b4-00c04fd430c8 .It Cm ns:X500 .Li 6ba7b814-9dad-11d1-80b4-00c04fd430c8 .El .Cm ns:\& Ns Va XXX are names of pre-defined name-space UUIDs for use in the generation of DCE 1.1 version 3 and version 5 UUIDs. .Pp . .It Xo .Ft uuid_rc_t .Fo uuid_make .Fa "uuid_t *uuid" .Fa "unsigned int mode" .Fa ... .Fc .Xc Generates a new UUID in .Fa uuid according to .Fa mode and optional arguments .Pq dependent on Fa mode . .Pp If .Fa mode contains the .Dv UUID_MAKE_V1 or .Dv UUID_MAKE_V6 bit, a DCE 1.1 variant UUID of version .Sy 1 or .Sy 6 is generated. Then optionally the bit .Dv UUID_MAKE_MC forces the use of random multi-cast MAC address instead of the real physical MAC address (the default). The UUID is generated out of the 60-bit current system time, a 12-bit clock sequence (initialised to random, then incremental in .Pf v Sy 1 ; always random in .Pf v Sy 6 ) and the 48-bit MAC address. .Pp If .Fa mode contains the .Dv UUID_MAKE_V3 or .Dv UUID_MAKE_V5 bit, a DCE 1.1 variant UUID of version .Sy 3 or .Sy 5 is generated and two additional arguments are expected: first, a namespace UUID object .Pq Vt "uuid_t *" . Second, a name string of arbitrary length .Pq Vt "const char *" . The UUID is generated out of the 128-bit MD5 or 160-bit SHA-1 from the concatenated octet stream of namespace UUID and name string. .Pp If .Fa mode contains the .Dv UUID_MAKE_V4 bit, a DCE 1.1 variant UUID of version 4 is generated. The UUID is generated out of 128-bit random data. .Pp If .Fa mode contains the .Dv UUID_MAKE_V7 bit, a DCE 1.1 variant UUID of version 7 is generated. The UUID is generated out of 48 bits of time and 80 bits of random data. .Pp . .It Xo .Ft "char *" .Fo uuid_error .Fa "uuid_rc_t rc" .Fc .Xc Returns a constant string representation corresponding to the return-code .Fa rc for use in displaying OSSP .Nm errors. .Pp . .It Xo .Ft unsigned long .Fo uuid_version .Fc .Xc Returns the hexadecimal encoded OSSP .Nm version as compiled into the library object files. This allows run-time checking of the OSSP .Nm version . For compile-time checking use .Dv UUID_VERSION instead. .El . .Sh EXAMPLES The following shows an example usage of the API. Error handling is omitted for code simplification and has to be re-added for production code. .Bd -literal -compact /* generate a RFC 9562 v1 UUID from system environment */ char *uuid_v1() { uuid_t *uuid; uuid_create(&uuid); uuid_make(uuid, UUID_MAKE_V1); char *str = NULL; uuid_export(uuid, UUID_FMT_STR, &str, NULL); uuid_destroy(uuid); return str; } /* generate a RFC 9562 v3 UUID from an URL */ char *uuid_v3(const char *url) { uuid_t *uuid_ns; uuid_create(&uuid_ns); uuid_load(uuid_ns, "ns:URL"); uuid_t *uuid; uuid_create(&uuid); uuid_make(uuid, UUID_MAKE_V3, uuid_ns, url); char *str = NULL; uuid_export(uuid, UUID_FMT_STR, &str, NULL); uuid_destroy(uuid_ns); uuid_destroy(uuid); return str; } .Ed . .Sh SEE ALSO .Xr uuid 1 , .Xr OSSP::uuid 3 .Pp The following are references to UUID documentation and specifications: . .Rs .%T Universally Unique IDentifiers (UUIDs) .%Q IETF .%N RFC-9562 .%N ISSN 2070-1721 .%A K. Davis .%Q Cisco Systems .%A B. Peabody .%Q Uncloud .%A P. Leach .%Q University of Washington .%U https://datatracker.ietf.org/doc/html/rfc9562 .Re This is the current UUID standard. . .Rs .%T A Universally Unique IDentifier (UUID) URN Namespace .%A P. Leach .%A M. Mealling .%A R. Salz .%Q IETF .%N RFC-4122 .%D July 2005 .%U http://www.ietf.org/rfc/rfc4122.txt .Re . .Rs .%T Information Technology \(en Open Systems Interconnection (OSI), Procedures for the operation of OSI Registration Authorities: Generation and Registration of Universally Unique Identifiers (UUIDs) and their Use as ASN.1 Object Identifier Components .%Q ISO/IEC .%N 9834-8:2004 / ITU-T Rec. X.667 2004 .%D December 2004 .%U http://www.itu.int/ITU-T/studygroups/com17/oid/X.667-E.pdf .Re . .Rs .%B DCE 1.1: Remote Procedure Call .%T Universally Unique Identifier .%Q Open Group Technical Standard .%D August 1997 .%N Document Number C706 .%U http://www.opengroup.org/publications/catalog/c706.htm .Re . .Rs .%B HTTP Extensions for Distributed Authoring (WebDAV) .%T 6.4.1 Node Field Generation Without the IEEE 802 Address .%Q IETF .%N RFC-2518 .%D February 1999 .%U http://www.ietf.org/rfc/rfc2518.txt .Re . .Rs .%T DCE 1.1 compliant UUID functions .%B FreeBSD manual pages uuid(3) and uuidgen(2) .%U http://www.freebsd.org/cgi/man.cgi?query=uuid&manpath=FreeBSD+6.0-RELEASE .Re . .Sh HISTORY OSSP .Nm was implemented in January 2004 by .An Ralf S. Engelschall Aq rse@engelschall.com . It was prompted by the use of UUIDs in the OSSP .Nm as and .Nm OpenPKG projects. It is a clean room implementation intended to be strictly standards compliant and maximally portable. ossp-uuid-UUID_1_6_4/uuid.c000066400000000000000000001143301472561253600155710ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid.c: library API implementation */ /* own headers (part 1/2) */ #include "uuid.h" #include "config.h" /* system headers */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __has_include() #include #else #include // FreeBSD #define SHA1Init SHA1_Init #define SHA1Update SHA1_Update #define SHA1Final SHA1_Final #define SHA1_DIGEST_LENGTH 20 #endif /* own headers (part 2/2) */ #include "uuid_random.h" #include "uuid_mac.h" #include "uuid_time.h" #include "uuid_ui128.h" #include "config.h" /* time offset between UUID and Unix Epoch time in seconds. (UUID UTC base time is October 15, 1582 Unix UTC base time is January 1, 1970) */ static const uint64_t UUID_TIMEOFFSET = 12219292800ULL; /* IEEE 802 MAC address encoding/decoding bit fields */ #define IEEE_MAC_MCBIT 0b00000001 #define IEEE_MAC_LOBIT 0b00000010 /* UUID v1 representation */ typedef struct { uint32_t time_low; /* bits 0-31 of time field */ uint16_t time_mid; /* bits 32-47 of time field */ uint16_t time_hi_and_version; /* bits 48-59 of time field plus 4 bit version */ uint8_t clock_seq_hi_and_reserved; /* bits 8-13 of clock sequence field plus 2 bit variant */ uint8_t clock_seq_low; /* bits 0-7 of clock sequence field */ uint8_t node[MAC_LEN]; /* bits 0-47 of node MAC address */ } uuid_obj_t; /* abstract data type (ADT) of API */ struct uuid_st { uuid_obj_t obj; /* inlined UUID object */ struct timespec time_last; /* last retrieved timestamp */ random_t random; /* random sub-object */ }; static uint8_t selected_mac[MAC_LEN]; /* resolve MAC address for insertion into node field of UUIDs */ static __attribute__((constructor)) void loadmac() { if (!mac_address(selected_mac)) selected_mac[0] = IEEE_MAC_MCBIT; } /* create UUID object */ uuid_rc_t uuid_create(uuid_t **uuid) { uuid_t *obj; /* argument sanity check */ if (uuid == NULL) return UUID_RC_ARG; /* allocate UUID object */ if ((obj = (uuid_t *)malloc(sizeof(uuid_t))) == NULL) return UUID_RC_MEM; /* create random sub-object */ obj->random = (random_t){.fd = -1}; /* set UUID object initially to "Nil UUID" */ obj->obj = (uuid_obj_t){}; /* initialize time attributes */ obj->time_last.tv_sec = 0; obj->time_last.tv_nsec = 0; /* store result object */ *uuid = obj; return UUID_RC_OK; } /* destroy UUID object */ uuid_rc_t uuid_destroy(uuid_t *uuid) { /* argument sanity check */ if (uuid == NULL) return UUID_RC_ARG; random_destroy(&uuid->random); /* free UUID object */ free(uuid); return UUID_RC_OK; } /* clone UUID object */ uuid_rc_t uuid_clone(const uuid_t *uuid, uuid_t **clone) { uuid_t *obj; /* argument sanity check */ if (uuid == NULL || clone == NULL) return UUID_RC_ARG; /* allocate UUID object */ if ((obj = (uuid_t *)malloc(sizeof(uuid_t))) == NULL) return UUID_RC_MEM; /* clone entire internal state */ memcpy(obj, uuid, sizeof(uuid_t)); /* re-initialize with new random sub-object */ obj->random = (random_t){.fd = -1}; /* store result object */ *clone = obj; return UUID_RC_OK; } /* check whether UUID object represents "Nil UUID" */ uuid_rc_t uuid_isnil(const uuid_t *uuid, int *result) { /* sanity check argument(s) */ if (uuid == NULL || result == NULL) return UUID_RC_ARG; /* a "Nil UUID" is defined as all octets zero, so check for this case */ uuid_obj_t nil = {}; *result = !memcmp(&uuid->obj, &nil, sizeof(nil)); return UUID_RC_OK; } /* check whether UUID object represents "Max UUID" */ uuid_rc_t uuid_ismax(const uuid_t *uuid, int *result) { /* sanity check argument(s) */ if (uuid == NULL || result == NULL) return UUID_RC_ARG; /* a "Max UUID" is defined as all octets 0xFF, so check for this case */ uuid_obj_t max; memset(&max, 0xFF, sizeof(uuid->obj));; *result = !memcmp(&uuid->obj, &max, sizeof(max)); return UUID_RC_OK; } /* compare UUID objects */ uuid_rc_t uuid_compare(const uuid_t *uuid1, const uuid_t *uuid2, int *result) { int r; /* argument sanity check */ if (result == NULL) return UUID_RC_ARG; /* convenience macro for setting result */ #define RESULT(r) \ do { \ *result = (r); \ return UUID_RC_OK; \ } while (0) \ /* special cases: NULL or equal UUIDs */ if (uuid1 == uuid2) RESULT(0); if (uuid1 == NULL && uuid2 == NULL) RESULT(0); if (uuid1 == NULL) RESULT((uuid_isnil(uuid2, &r) == UUID_RC_OK ? r : 0) ? 0 : -1); if (uuid2 == NULL) RESULT((uuid_isnil(uuid1, &r) == UUID_RC_OK ? r : 0) ? 0 : 1); /* standard cases: regular different UUIDs */ if (uuid1->obj.time_low != uuid2->obj.time_low) RESULT((uuid1->obj.time_low < uuid2->obj.time_low) ? -1 : 1); if ((r = (int)uuid1->obj.time_mid - (int)uuid2->obj.time_mid) != 0) RESULT((r < 0) ? -1 : 1); if ((r = (int)uuid1->obj.time_hi_and_version - (int)uuid2->obj.time_hi_and_version) != 0) RESULT((r < 0) ? -1 : 1); if ((r = (int)uuid1->obj.clock_seq_hi_and_reserved - (int)uuid2->obj.clock_seq_hi_and_reserved) != 0) RESULT((r < 0) ? -1 : 1); if ((r = (int)uuid1->obj.clock_seq_low - (int)uuid2->obj.clock_seq_low) != 0) RESULT((r < 0) ? -1 : 1); if ((r = memcmp(uuid1->obj.node, uuid2->obj.node, sizeof(uuid1->obj.node))) != 0) RESULT((r < 0) ? -1 : 1); /* default case: the keys are equal */ *result = 0; return UUID_RC_OK; } /* INTERNAL: unpack UUID binary presentation into UUID object (allows in-place operation for internal efficiency!) */ static uuid_rc_t uuid_import_bin(uuid_t *uuid, const void *data_ptr, size_t data_len) { const uint8_t *in; uint32_t tmp32; uint16_t tmp16; unsigned int i; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL || data_len < UUID_LEN_BIN) return UUID_RC_ARG; /* treat input data buffer as octet stream */ in = (const uint8_t *)data_ptr; /* unpack "time_low" field */ tmp32 = (uint32_t)(*in++); tmp32 = (tmp32 << 8) | (uint32_t)(*in++); tmp32 = (tmp32 << 8) | (uint32_t)(*in++); tmp32 = (tmp32 << 8) | (uint32_t)(*in++); uuid->obj.time_low = tmp32; /* unpack "time_mid" field */ tmp16 = (uint16_t)(*in++); tmp16 = (uint16_t)(tmp16 << 8) | (uint16_t)(*in++); uuid->obj.time_mid = tmp16; /* unpack "time_hi_and_version" field */ tmp16 = (uint16_t)*in++; tmp16 = (uint16_t)(tmp16 << 8) | (uint16_t)(*in++); uuid->obj.time_hi_and_version = tmp16; /* unpack "clock_seq_hi_and_reserved" field */ uuid->obj.clock_seq_hi_and_reserved = *in++; /* unpack "clock_seq_low" field */ uuid->obj.clock_seq_low = *in++; /* unpack "node" field */ for (i = 0; i < (unsigned int)sizeof(uuid->obj.node); i++) uuid->obj.node[i] = *in++; return UUID_RC_OK; } /* INTERNAL: pack UUID object into binary representation (allows in-place operation for internal efficiency!) */ static uuid_rc_t uuid_export_bin(const uuid_t *uuid, void *_data_ptr, size_t *data_len) { uint8_t **data_ptr; uint8_t *out; uint32_t tmp32; uint16_t tmp16; unsigned int i; /* cast generic data pointer to particular pointer to pointer type */ data_ptr = (uint8_t **)_data_ptr; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* optionally allocate octet data buffer */ if (*data_ptr == NULL) { if ((*data_ptr = (uint8_t *)malloc(sizeof(uuid_t))) == NULL) return UUID_RC_MEM; if (data_len != NULL) *data_len = UUID_LEN_BIN; } else { if (data_len == NULL) return UUID_RC_ARG; if (*data_len < UUID_LEN_BIN) return UUID_RC_MEM; *data_len = UUID_LEN_BIN; } /* treat output data buffer as octet stream */ out = *data_ptr; /* pack "time_low" field */ tmp32 = uuid->obj.time_low; out[3] = (uint8_t)(tmp32 & 0xff); tmp32 >>= 8; out[2] = (uint8_t)(tmp32 & 0xff); tmp32 >>= 8; out[1] = (uint8_t)(tmp32 & 0xff); tmp32 >>= 8; out[0] = (uint8_t)(tmp32 & 0xff); /* pack "time_mid" field */ tmp16 = uuid->obj.time_mid; out[5] = (uint8_t)(tmp16 & 0xff); tmp16 >>= 8; out[4] = (uint8_t)(tmp16 & 0xff); /* pack "time_hi_and_version" field */ tmp16 = uuid->obj.time_hi_and_version; out[7] = (uint8_t)(tmp16 & 0xff); tmp16 >>= 8; out[6] = (uint8_t)(tmp16 & 0xff); /* pack "clock_seq_hi_and_reserved" field */ out[8] = uuid->obj.clock_seq_hi_and_reserved; /* pack "clock_seq_low" field */ out[9] = uuid->obj.clock_seq_low; /* pack "node" field */ for (i = 0; i < (unsigned int)sizeof(uuid->obj.node); i++) out[10+i] = uuid->obj.node[i]; return UUID_RC_OK; } /* INTERNAL: check for valid UUID string representation syntax like "f81d4fae-7dec-11d0-a765-00a0c91e6bf6" */ static bool uuid_isstr(const char *str, size_t str_len) { if (strnlen(str, str_len) != UUID_LEN_STR) return false; for (size_t i = 0; i < UUID_LEN_STR; i++, str++) { if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { if (*str == '-') continue; else return false; } if (!isxdigit((unsigned char)*str)) return false; } return true; } /* INTERNAL: import UUID object from string representation */ static uuid_rc_t uuid_import_str(uuid_t *uuid, const void *data_ptr, size_t data_len) { uint16_t tmp16; const char *cp; char hexbuf[3]; const char *str = data_ptr; unsigned int i; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* check for correct UUID string representation syntax */ if (!uuid_isstr(str, data_len)) return UUID_RC_ARG; /* parse hex values of "time" parts */ uuid->obj.time_low = (uint32_t)strtoul(str, NULL, 16); uuid->obj.time_mid = (uint16_t)strtoul(str+9, NULL, 16); uuid->obj.time_hi_and_version = (uint16_t)strtoul(str+14, NULL, 16); /* parse hex values of "clock" parts */ tmp16 = (uint16_t)strtoul(str+19, NULL, 16); uuid->obj.clock_seq_low = (uint8_t)(tmp16 & 0xff); tmp16 >>= 8; uuid->obj.clock_seq_hi_and_reserved = (uint8_t)(tmp16 & 0xff); /* parse hex values of "node" part */ cp = str+24; hexbuf[2] = '\0'; for (i = 0; i < (unsigned int)sizeof(uuid->obj.node); i++) { hexbuf[0] = *cp++; hexbuf[1] = *cp++; uuid->obj.node[i] = (uint8_t)strtoul(hexbuf, NULL, 16); } return UUID_RC_OK; } /* INTERNAL: import UUID object from single integer value representation */ static uuid_rc_t uuid_import_siv(uuid_t *uuid, const void *data_ptr, size_t data_len) { /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL || data_len < 1) return UUID_RC_ARG; const char *str = data_ptr, *end; ui128_t parsed = strtou128(str, data_len, &end); if (end != str+data_len && *end != '\0') return UUID_RC_ARG; _Static_assert(UUID_LEN_BIN == sizeof(parsed.x), "16 != 16"); uint8_t tmp[UUID_LEN_BIN]; for(size_t i = 0; i < sizeof(tmp); ++i) // UUIDs are reverse endianness vs our 128-bit ints tmp[i] = parsed.x[(sizeof(parsed.x)-1) - i]; /* import into internal UUID representation */ return uuid_import(uuid, UUID_FMT_BIN, tmp, sizeof(tmp)); } /* INTERNAL: export UUID object to string representation */ static uuid_rc_t uuid_export_str(const uuid_t *uuid, void *_data_ptr, size_t *data_len) { char **data_ptr; char *data_buf; /* cast generic data pointer to particular pointer to pointer type */ data_ptr = (char **)_data_ptr; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* determine output buffer */ if (*data_ptr == NULL) { if ((data_buf = (char *)malloc(UUID_LEN_STR+1)) == NULL) return UUID_RC_MEM; if (data_len != NULL) *data_len = UUID_LEN_STR+1; } else { data_buf = (char *)(*data_ptr); if (data_len == NULL) return UUID_RC_ARG; if (*data_len < UUID_LEN_STR+1) return UUID_RC_MEM; *data_len = UUID_LEN_STR+1; } /* format UUID into string representation */ if (snprintf(data_buf, UUID_LEN_STR+1, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", (unsigned long)uuid->obj.time_low, (unsigned int)uuid->obj.time_mid, (unsigned int)uuid->obj.time_hi_and_version, (unsigned int)uuid->obj.clock_seq_hi_and_reserved, (unsigned int)uuid->obj.clock_seq_low, (unsigned int)uuid->obj.node[0], (unsigned int)uuid->obj.node[1], (unsigned int)uuid->obj.node[2], (unsigned int)uuid->obj.node[3], (unsigned int)uuid->obj.node[4], (unsigned int)uuid->obj.node[5]) != UUID_LEN_STR) { if (*data_ptr == NULL) free(data_buf); return UUID_RC_INT; } /* pass back new buffer if locally allocated */ if (*data_ptr == NULL) *data_ptr = data_buf; return UUID_RC_OK; } /* INTERNAL: export UUID object to single integer value representation */ static uuid_rc_t uuid_export_siv(const uuid_t *uuid, void *_data_ptr, size_t *data_len) { char **data_ptr; char *data_buf; void *tmp_ptr; size_t tmp_len; uint8_t tmp_bin[UUID_LEN_BIN]; uuid_rc_t rc; /* cast generic data pointer to particular pointer to pointer type */ data_ptr = (char **)_data_ptr; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* determine output buffer */ if (*data_ptr == NULL) { if ((data_buf = (char *)malloc(UUID_LEN_SIV+1)) == NULL) return UUID_RC_MEM; if (data_len != NULL) *data_len = UUID_LEN_SIV+1; } else { data_buf = (char *)(*data_ptr); if (data_len == NULL) return UUID_RC_ARG; if (*data_len < UUID_LEN_SIV+1) return UUID_RC_MEM; *data_len = UUID_LEN_SIV+1; } /* export into UUID binary representation */ tmp_ptr = (void *)&tmp_bin; tmp_len = sizeof(tmp_bin); if ((rc = uuid_export(uuid, UUID_FMT_BIN, &tmp_ptr, &tmp_len)) != UUID_RC_OK) { if (*data_ptr == NULL) free(data_buf); return rc; } /* import from UUID binary representation */ ui128_t ret = {}; _Static_assert(sizeof(tmp_bin) == sizeof(ret.x), "16 != 16"); for(size_t i = 0; i < sizeof(tmp_bin); ++i) // UUIDs are reverse endianness vs our 128-bit ints ret.x[(sizeof(ret.x)-1) - i] = tmp_bin[i]; u128tostr(ret, data_buf, UUID_LEN_SIV+1); /* pass back new buffer if locally allocated */ if (*data_ptr == NULL) *data_ptr = data_buf; return UUID_RC_OK; } /* INTERNAL: dump UUID object as descriptive text */ static uuid_rc_t uuid_export_txt(const uuid_t *uuid, void *_data_ptr, size_t *data_len) { char **data_ptr; uuid_rc_t rc; const char *version; const char *variant; char *content; int isnil, ismax; uint32_t tmp32; uint8_t tmp_bin[UUID_LEN_BIN]; char tmp_str[UUID_LEN_STR+1]; char tmp_siv[UUID_LEN_SIV+1]; void *tmp_ptr; size_t tmp_len; char t_buf[sizeof("10889-08-02 07:31:50")]; // The maximal representable UUID time is 0x0FFFFFFFFFFFFFFF (5236-03-31 21:21:00); // the maximal UUIDv7 UNIX time is 0xFFFFFFFFFFFF, q.v. struct tm *tm; char out_buf[512], *cur = out_buf; /* cast generic data pointer to particular pointer to pointer type */ data_ptr = (char **)_data_ptr; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* check for special case of "Nil" and "Max" UUID */ if ((rc = uuid_isnil(uuid, &isnil)) != UUID_RC_OK) return rc; if ((rc = uuid_ismax(uuid, &ismax)) != UUID_RC_OK) return rc; /* decode into various representations */ tmp_ptr = (void *)&tmp_str; tmp_len = sizeof(tmp_str); if ((rc = uuid_export(uuid, UUID_FMT_STR, &tmp_ptr, &tmp_len)) != UUID_RC_OK) return rc; tmp_ptr = (void *)&tmp_siv; tmp_len = sizeof(tmp_siv); if ((rc = uuid_export(uuid, UUID_FMT_SIV, &tmp_ptr, &tmp_len)) != UUID_RC_OK) return rc; cur += sprintf(cur, "encode: STR: %s\n", tmp_str); cur += sprintf(cur, " SIV: %s\n", tmp_siv); /* decode UUID variant */ uint8_t cshar = uuid->obj.clock_seq_hi_and_reserved; unsigned variant_n = (cshar == 0xFF) ? 8 : __builtin_clz(~(unsigned)cshar << ((sizeof(unsigned) - 1) * 8)); // variant = count leading 1s // TODO: replace with stdc_leading_ones if(isnil || ismax) variant = "n.a."; else switch(variant_n) { case 0: variant = "reserved (NCS backward compatible)"; break; case 1: variant = "DCE 1.1, ISO/IEC 11578:1996"; break; case 2: variant = "reserved (Microsoft GUID)"; break; case 3: variant = "reserved (future use)"; break; default: variant = "unknown"; break; } cur += sprintf(cur, "decode: variant: %s\n", variant); /* decode UUID version */ unsigned version_n = (uuid->obj.time_hi_and_version >> 12) & 0b1111; if (isnil || ismax) version = "n.a."; else switch(version_n) { case 1: version = "time and node based"; break; case 6: version = "time and node based (time in reverse order)"; break; case 7: version = "UNIX time + random data"; break; case 3: version = "name based, MD5"; break; case 4: version = "random data based"; break; case 5: version = "name based, SHA-1"; break; default: version = "unknown"; break; } cur += sprintf(cur, " version: %u (%s)\n", version_n, version); /* * decode UUID content */ if (variant_n == 1 && (version_n == 1 || version_n == 6)) { /* decode RFC 9562 version 1 or 6 UUID */ /* decode system time */ uint64_t t = 0; if(version_n == 1) { t |= (uint64_t)(uuid->obj.time_low & 0xFFFFFFFF) << (64 - 64); t |= (uint64_t)(uuid->obj.time_mid & 0xFFFF) << (64 - 32); t |= (uint64_t)(uuid->obj.time_hi_and_version & 0x0FFF) << (64 - 16); } else { t |= (uint64_t)(uuid->obj.time_low & 0xFFFFFFFF) << 28; t |= (uint64_t)(uuid->obj.time_mid & 0xFFFF) << 12; t |= (uint64_t)(uuid->obj.time_hi_and_version & 0x0FFF) << 0; } uint64_t t_nsec = t % 10; t /= 10; uint64_t t_usec = t % 1000000; t /= 1000000; tm = gmtime(&(time_t){t - UUID_TIMEOFFSET}); (void)strftime(t_buf, sizeof(t_buf), "%Y-%m-%d %H:%M:%S", tm); cur += sprintf(cur, " content: time: %s.%06" PRIu64 ".%" PRIu64 " UTC\n", t_buf, t_usec, t_nsec); /* decode clock sequence */ tmp32 = ((uuid->obj.clock_seq_hi_and_reserved & 0b111111) << 8) + uuid->obj.clock_seq_low; cur += sprintf(cur, " clock: %ld (usually random)\n", (long)tmp32); /* decode node MAC address */ cur += sprintf(cur, " node: %02x:%02x:%02x:%02x:%02x:%02x (%s %s)\n", (unsigned int)uuid->obj.node[0], (unsigned int)uuid->obj.node[1], (unsigned int)uuid->obj.node[2], (unsigned int)uuid->obj.node[3], (unsigned int)uuid->obj.node[4], (unsigned int)uuid->obj.node[5], (uuid->obj.node[0] & IEEE_MAC_LOBIT ? "local" : "global"), (uuid->obj.node[0] & IEEE_MAC_MCBIT ? "multicast" : "unicast")); } else if (variant_n == 1 && version_n == 7) { /* decode RFC 9562 version 7 UUID */ /* pack UUID into binary representation */ tmp_ptr = (void *)&tmp_bin; tmp_len = sizeof(tmp_bin); if ((rc = uuid_export(uuid, UUID_FMT_BIN, &tmp_ptr, &tmp_len)) != UUID_RC_OK) return rc; /* decode system time */ uint64_t t = ((uint64_t)tmp_bin[0] << 40) | ((uint64_t)tmp_bin[1] << 32) | ((uint64_t)tmp_bin[2] << 24) | ((uint64_t)tmp_bin[3] << 16) | ((uint64_t)tmp_bin[4] << 8) | ((uint64_t)tmp_bin[5] << 0); uint64_t millis = t % 1000; t /= 1000; tm = gmtime(&(time_t){t}); (void)strftime(t_buf, sizeof(t_buf), "%Y-%m-%d %H:%M:%S", tm); cur += sprintf(cur, " content: time: %s.%03" PRIu64 " UTC\n", t_buf, millis); tmp_bin[6] &= ~0b11110000; // clear version tmp_bin[8] &= ~0b11000000; // clear variant cur += sprintf(cur, " random: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX\n", tmp_bin[6], tmp_bin[7], tmp_bin[8], tmp_bin[9], tmp_bin[10], tmp_bin[11], tmp_bin[12], tmp_bin[13], tmp_bin[14], tmp_bin[15]); } else { /* decode anything else as hexadecimal byte-string only */ if(isnil) content = "special case: DCE 1.1 Nil UUID"; else if(ismax) content = "special case: RFC 9562 Max UUID"; else switch(version_n) { case 3: content = "not decipherable: MD5 message digest only"; break; case 4: content = "no semantics: random data only"; break; case 5: content = "not decipherable: truncated SHA-1 message digest only"; break; default: content = "not decipherable: unknown UUID version"; break; } /* pack UUID into binary representation */ tmp_ptr = (void *)&tmp_bin; tmp_len = sizeof(tmp_bin); if ((rc = uuid_export(uuid, UUID_FMT_BIN, &tmp_ptr, &tmp_len)) != UUID_RC_OK) return rc; /* mask out version and variant parts */ tmp_bin[6] &= 0b1111; tmp_bin[8] &= 0b111111; /* dump as colon-seperated hexadecimal byte-string */ cur += sprintf(cur, " content: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n" " (%s)\n", (unsigned int)tmp_bin[0], (unsigned int)tmp_bin[1], (unsigned int)tmp_bin[2], (unsigned int)tmp_bin[3], (unsigned int)tmp_bin[4], (unsigned int)tmp_bin[5], (unsigned int)tmp_bin[6], (unsigned int)tmp_bin[7], (unsigned int)tmp_bin[8], (unsigned int)tmp_bin[9], (unsigned int)tmp_bin[10], (unsigned int)tmp_bin[11], (unsigned int)tmp_bin[12], (unsigned int)tmp_bin[13], (unsigned int)tmp_bin[14], (unsigned int)tmp_bin[15], content); } /* provide result */ if (*data_ptr == NULL) { *data_ptr = strdup(out_buf); if (data_len != NULL) *data_len = cur - out_buf + 1; } else { if (data_len == NULL) return UUID_RC_ARG; if (*data_len < (size_t)(cur - out_buf + 1)) return UUID_RC_MEM; memcpy(*data_ptr, out_buf, cur - out_buf + 1); } return UUID_RC_OK; } /* UUID importing */ uuid_rc_t uuid_import(uuid_t *uuid, uuid_fmt_t fmt, const void *data_ptr, size_t data_len) { uuid_rc_t rc; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* dispatch into format-specific functions */ switch (fmt) { case UUID_FMT_BIN: rc = uuid_import_bin(uuid, data_ptr, data_len); break; case UUID_FMT_STR: rc = uuid_import_str(uuid, data_ptr, data_len); break; case UUID_FMT_SIV: rc = uuid_import_siv(uuid, data_ptr, data_len); break; case UUID_FMT_TXT: rc = UUID_RC_IMP; /* not implemented */ break; default: rc = UUID_RC_ARG; } return rc; } /* UUID exporting */ uuid_rc_t uuid_export(const uuid_t *uuid, uuid_fmt_t fmt, void *data_ptr, size_t *data_len) { uuid_rc_t rc; /* sanity check argument(s) */ if (uuid == NULL || data_ptr == NULL) return UUID_RC_ARG; /* dispatch into format-specific functions */ switch (fmt) { case UUID_FMT_BIN: rc = uuid_export_bin(uuid, data_ptr, data_len); break; case UUID_FMT_STR: rc = uuid_export_str(uuid, data_ptr, data_len); break; case UUID_FMT_SIV: rc = uuid_export_siv(uuid, data_ptr, data_len); break; case UUID_FMT_TXT: rc = uuid_export_txt(uuid, data_ptr, data_len); break; default: rc = UUID_RC_ARG; } return rc; } /* INTERNAL: brand UUID with version and variant */ static void uuid_brand(uuid_t *uuid, unsigned int version) { /* set version (as given) */ uuid->obj.time_hi_and_version &= 0b111111111111; uuid->obj.time_hi_and_version |= (uint16_t)(version << 12); /* set variant (always DCE 1.1 only) */ uuid->obj.clock_seq_hi_and_reserved &= 0b111111; uuid->obj.clock_seq_hi_and_reserved |= (0x02 << 6); return; } /* INTERNAL: generate UUID version 1 or 6: time, clock and node based */ static uuid_rc_t uuid_make_v1_v6(uuid_t *uuid, unsigned int mode, unsigned version) { struct timespec time_now; uint16_t clck; /* * GENERATE TIME */ /* determine current system time and sequence counter */ for (;;) { /* determine current system time */ timespec_get(&time_now, TIME_UTC); /* check whether system time changed since last retrieve */ if (!( time_now.tv_sec == uuid->time_last.tv_sec && (time_now.tv_nsec / 100) == (uuid->time_last.tv_nsec / 100))) { /* reset time sequence counter and continue */ break; } /* stall the UUID generation until the system clock (rounded up to our 100ns resolution) catches up */ sched_yield(); } /* convert from timeval (sec,usec,UNIX) to UUID (nsec/100,UUID) format */ uint64_t t = time_now.tv_sec + UUID_TIMEOFFSET; t *= 10000000; t += time_now.tv_nsec / 100; /* store the 60 LSB of the time in the UUID */ if (version == 1) { uuid->obj.time_hi_and_version = (uint16_t)((t & 0x0FFF000000000000ull) >> (64 - 16)); /* 12 of 16 bits only! */ uuid->obj.time_mid = (uint16_t)((t & 0x0000FFFF00000000ull) >> (64 - 32)); /* all 16 bits */ uuid->obj.time_low = (uint32_t)((t & 0x00000000FFFFFFFFull) >> (64 - 64)); /* all 32 bits */ } else { // version == 6 uuid->obj.time_low = (uint32_t)((t & 0x0FFFFFFFF0000000ull) >> 28); uuid->obj.time_mid = (uint16_t)((t & 0x000000000FFFF000ull) >> 12); uuid->obj.time_hi_and_version = (uint16_t)((t & 0x0000000000000FFFull) >> 0); } /* * GENERATE CLOCK */ /* retrieve current clock sequence */ clck = ((uuid->obj.clock_seq_hi_and_reserved & 0b111111) << 8) + uuid->obj.clock_seq_low; /* generate new random clock sequence (initially or if the time has stepped backwards or if generating v6) or else just increase it */ if ( version != 1 || clck == 0 || ( time_now.tv_sec < uuid->time_last.tv_sec || ( time_now.tv_sec == uuid->time_last.tv_sec && time_now.tv_nsec < uuid->time_last.tv_nsec))) { if (!random_data(&uuid->random, (void *)&clck, sizeof(clck))) return UUID_RC_INT; } else clck++; clck %= (1 << 14); // 2^14 /* store back new clock sequence */ uuid->obj.clock_seq_hi_and_reserved = (uuid->obj.clock_seq_hi_and_reserved & 0b11000000) | (uint8_t)((clck >> 8) & 0xff); uuid->obj.clock_seq_low = (uint8_t)(clck & 0xff); /* * GENERATE NODE */ if ((mode & UUID_MAKE_MC) || (selected_mac[0] & IEEE_MAC_MCBIT)) { /* generate random IEEE 802 local multicast MAC address */ if (!random_data(&uuid->random, uuid->obj.node, sizeof(uuid->obj.node))) return UUID_RC_INT; uuid->obj.node[0] |= IEEE_MAC_MCBIT; uuid->obj.node[0] |= IEEE_MAC_LOBIT; } else { /* use real regular MAC address */ memcpy(uuid->obj.node, selected_mac, sizeof(selected_mac)); } /* * FINISH */ /* remember current system time for next iteration */ uuid->time_last = time_now; /* brand with version and variant */ uuid_brand(uuid, version); return UUID_RC_OK; } /* INTERNAL: pre-defined UUID values. (defined as network byte ordered octet stream) */ #define UUID_MAKE(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) \ { (uint8_t)(a1), (uint8_t)(a2), (uint8_t)(a3), (uint8_t)(a4), \ (uint8_t)(a5), (uint8_t)(a6), (uint8_t)(a7), (uint8_t)(a8), \ (uint8_t)(a9), (uint8_t)(a10), (uint8_t)(a11), (uint8_t)(a12), \ (uint8_t)(a13), (uint8_t)(a14), (uint8_t)(a15), (uint8_t)(a16) } static const struct { char *name; uint8_t uuid[UUID_LEN_BIN]; } uuid_value_table[] = { { "nil", /* 00000000-0000-0000-0000-000000000000 ("Nil UUID") */ UUID_MAKE(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }, { "max", /* ffffffff-ffff-ffff-ffff-ffffffffffff ("Max UUID") */ UUID_MAKE(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF) }, { "ns:DNS", /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 (see RFC 4122) */ UUID_MAKE(0x6b,0xa7,0xb8,0x10,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8) }, { "ns:URL", /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 (see RFC 4122) */ UUID_MAKE(0x6b,0xa7,0xb8,0x11,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8) }, { "ns:OID", /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 (see RFC 4122) */ UUID_MAKE(0x6b,0xa7,0xb8,0x12,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8) }, { "ns:X500", /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 (see RFC 4122) */ UUID_MAKE(0x6b,0xa7,0xb8,0x14,0x9d,0xad,0x11,0xd1,0x80,0xb4,0x00,0xc0,0x4f,0xd4,0x30,0xc8) } }; /* load UUID object with pre-defined value */ uuid_rc_t uuid_load(uuid_t *uuid, const char *name) { const uint8_t *uuid_octets; uuid_rc_t rc; unsigned int i; /* sanity check argument(s) */ if (uuid == NULL || name == NULL) return UUID_RC_ARG; /* search for UUID in table */ uuid_octets = NULL; for (i = 0; i < (unsigned int)sizeof(uuid_value_table)/sizeof(uuid_value_table[0]); i++) { if (strcmp(uuid_value_table[i].name, name) == 0) { uuid_octets = uuid_value_table[i].uuid; break; } } if (uuid_octets == NULL) return UUID_RC_ARG; /* import value into UUID object */ if ((rc = uuid_import(uuid, UUID_FMT_BIN, uuid_octets, UUID_LEN_BIN)) != UUID_RC_OK) return rc; return UUID_RC_OK; } /* INTERNAL: generate UUID version 3: name based with MD5 */ static uuid_rc_t uuid_make_v3(uuid_t *uuid, unsigned int mode, va_list ap) { (void)mode; char *str; uuid_t *uuid_ns; uint8_t uuid_buf[UUID_LEN_BIN]; void *uuid_ptr; size_t uuid_len; uuid_rc_t rc; /* determine namespace UUID and name string arguments */ if ((uuid_ns = va_arg(ap, uuid_t *)) == NULL) return UUID_RC_ARG; if ((str = va_arg(ap, char *)) == NULL) return UUID_RC_ARG; /* initialize MD5 context */ MD5_CTX ctx; MD5Init(&ctx); /* load the namespace UUID into MD5 context */ uuid_ptr = (void *)&uuid_buf; uuid_len = sizeof(uuid_buf); if ((rc = uuid_export(uuid_ns, UUID_FMT_BIN, &uuid_ptr, &uuid_len)) != UUID_RC_OK) return rc; MD5Update(&ctx, uuid_buf, uuid_len); /* load the argument name string into MD5 context */ MD5Update(&ctx, (void *)str, strlen(str)); /* store MD5 result into UUID (requires MD5_LEN_BIN space, UUID_LEN_BIN space is available, and both are equal in size, so we are safe!) */ uuid_ptr = (void *)&(uuid->obj); MD5Final(uuid_ptr, &ctx); /* fulfill requirement of standard and convert UUID data into local/host byte order (this uses fact that uuid_import_bin() is able to operate in-place!) */ if ((rc = uuid_import(uuid, UUID_FMT_BIN, (void *)&(uuid->obj), UUID_LEN_BIN)) != UUID_RC_OK) return rc; /* brand UUID with version and variant */ uuid_brand(uuid, 3); return UUID_RC_OK; } /* INTERNAL: generate UUID version 4: random number based */ static uuid_rc_t uuid_make_v4(uuid_t *uuid, unsigned int mode, va_list ap) { (void)mode, (void)ap; /* fill UUID with random data */ if (!random_data(&uuid->random, (void *)&(uuid->obj), sizeof(uuid->obj))) return UUID_RC_INT; /* brand UUID with version and variant */ uuid_brand(uuid, 4); return UUID_RC_OK; } /* INTERNAL: generate UUID version 5: name based with SHA-1 */ static uuid_rc_t uuid_make_v5(uuid_t *uuid, unsigned int mode, va_list ap) { (void)mode; char *str; uuid_t *uuid_ns; uint8_t uuid_buf[UUID_LEN_BIN]; void *uuid_ptr; size_t uuid_len; uint8_t sha1_buf[SHA1_DIGEST_LENGTH]; uuid_rc_t rc; /* determine namespace UUID and name string arguments */ if ((uuid_ns = (uuid_t *)va_arg(ap, void *)) == NULL) return UUID_RC_ARG; if ((str = (char *)va_arg(ap, char *)) == NULL) return UUID_RC_ARG; /* initialize SHA-1 context */ SHA1_CTX ctx; SHA1Init(&ctx); /* load the namespace UUID into SHA-1 context */ uuid_ptr = (void *)&uuid_buf; uuid_len = sizeof(uuid_buf); if ((rc = uuid_export(uuid_ns, UUID_FMT_BIN, &uuid_ptr, &uuid_len)) != UUID_RC_OK) return rc; SHA1Update(&ctx, uuid_buf, uuid_len); /* load the argument name string into SHA-1 context */ SHA1Update(&ctx, (void *)str, strlen(str)); /* store SHA-1 result into UUID (requires SHA1_DIGEST_LENGTH space, but UUID_LEN_BIN space is available only, so use a temporary buffer to store SHA-1 results and then use lower part only according to standard */ SHA1Final(sha1_buf, &ctx); memcpy(&(uuid->obj), sha1_buf, UUID_LEN_BIN); /* fulfill requirement of standard and convert UUID data into local/host byte order (this uses fact that uuid_import_bin() is able to operate in-place!) */ if ((rc = uuid_import(uuid, UUID_FMT_BIN, (void *)&(uuid->obj), UUID_LEN_BIN)) != UUID_RC_OK) // TODO: strict aliasing? packing? what the fuck? return rc; /* brand UUID with version and variant */ uuid_brand(uuid, 5); return UUID_RC_OK; } /* INTERNAL: generate UUID version 7: UNIX timestamp + random data */ static uuid_rc_t uuid_make_v7(uuid_t *uuid, unsigned int mode, va_list ap) { (void)mode, (void)ap; struct timespec time_now; timespec_get(&time_now, TIME_UTC); uint64_t millis = time_now.tv_sec * 1000 + time_now.tv_nsec / 1000000; uint8_t uuid_buf[UUID_LEN_BIN] = {}; uuid_buf[0] = (millis & 0xFF0000000000) >> 40; uuid_buf[1] = (millis & 0x00FF00000000) >> 32; uuid_buf[2] = (millis & 0x0000FF000000) >> 24; uuid_buf[3] = (millis & 0x000000FF0000) >> 16; uuid_buf[4] = (millis & 0x00000000FF00) >> 8; uuid_buf[5] = (millis & 0x0000000000FF) >> 0; if (!random_data(&uuid->random, &uuid_buf[6], sizeof(uuid_buf)-6)) return UUID_RC_INT; uuid_rc_t rc; if ((rc = uuid_import(uuid, UUID_FMT_BIN, uuid_buf, sizeof(uuid_buf))) != UUID_RC_OK) return rc; uuid_brand(uuid, 7); return UUID_RC_OK; } /* generate UUID */ uuid_rc_t uuid_make(uuid_t *uuid, unsigned int mode, ...) { va_list ap; uuid_rc_t rc; /* sanity check argument(s) */ if (uuid == NULL) return UUID_RC_ARG; /* dispatch into version dependent generation functions */ va_start(ap, mode); if (mode & UUID_MAKE_V1) rc = uuid_make_v1_v6(uuid, mode, 1); else if (mode & UUID_MAKE_V3) rc = uuid_make_v3(uuid, mode, ap); else if (mode & UUID_MAKE_V4) rc = uuid_make_v4(uuid, mode, ap); else if (mode & UUID_MAKE_V5) rc = uuid_make_v5(uuid, mode, ap); else if (mode & UUID_MAKE_V6) rc = uuid_make_v1_v6(uuid, mode, 6); else if (mode & UUID_MAKE_V7) rc = uuid_make_v7(uuid, mode, ap); else rc = UUID_RC_ARG; va_end(ap); return rc; } /* translate UUID API error code into corresponding error string */ char *uuid_error(uuid_rc_t rc) { switch (rc) { case UUID_RC_OK: return "everything ok"; case UUID_RC_ARG: return "invalid argument"; case UUID_RC_MEM: return "out of memory"; case UUID_RC_SYS: return "system error"; case UUID_RC_INT: return "internal error"; case UUID_RC_IMP: return "not implemented"; default: return NULL; } } /* OSSP uuid version (link-time information) */ unsigned long uuid_version(void) { return (unsigned long)UUID_VERSION; } ossp-uuid-UUID_1_6_4/uuid.h.in000066400000000000000000000105761472561253600162120ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid.h: library API definition */ #ifndef __UUID_H__ #define __UUID_H__ /* workaround conflicts with system headers */ #define uuid_t __vendor_uuid_t #define uuid_create __vendor_uuid_create #define uuid_compare __vendor_uuid_compare #include #include #undef uuid_t #undef uuid_create #undef uuid_compare /* required system headers */ #include /* minimum C++ support */ #ifdef __cplusplus extern "C" { #endif /* OSSP uuid version (compile-time information) */ #define UUID_VERSION @UUID_VERSION_HEX@ /* encoding octet stream lengths */ #define UUID_LEN_BIN (128 /*bit*/ / 8 /*bytes*/) #define UUID_LEN_STR (128 /*bit*/ / 4 /*nibbles*/ + 4 /*hyphens*/) #define UUID_LEN_SIV (39 /*int(log(10,exp(2,128)-1)+1) digits*/) /* API return codes */ typedef enum { UUID_RC_OK = 0, /* everything ok */ UUID_RC_ARG = 1, /* invalid argument */ UUID_RC_MEM = 2, /* out of memory */ UUID_RC_SYS = 3, /* system error */ UUID_RC_INT = 4, /* internal error */ UUID_RC_IMP = 5 /* not implemented */ } uuid_rc_t; /* UUID make modes */ enum { UUID_MAKE_V1 = (1 << 0), /* RFC 9562 v1 UUID */ UUID_MAKE_V3 = (1 << 1), /* RFC 9562 v3 UUID */ UUID_MAKE_V4 = (1 << 2), /* RFC 9562 v4 UUID */ UUID_MAKE_V5 = (1 << 3), /* RFC 9562 v5 UUID */ UUID_MAKE_MC = (1 << 4), /* enforce multi-cast MAC address */ UUID_MAKE_V6 = (1 << 5), /* RFC 9562 v6 UUID */ UUID_MAKE_V7 = (1 << 6), /* RFC 9562 v7 UUID */ }; /* UUID import/export formats */ typedef enum { UUID_FMT_BIN = 0, /* binary representation (import/export) */ UUID_FMT_STR = 1, /* string representation (import/export) */ UUID_FMT_SIV = 2, /* single integer value (import/export) */ UUID_FMT_TXT = 3 /* textual description (export only) */ } uuid_fmt_t; /* UUID abstract data type */ struct uuid_st; typedef struct uuid_st uuid_t; /* UUID object handling */ extern uuid_rc_t uuid_create ( uuid_t **_uuid); extern uuid_rc_t uuid_destroy ( uuid_t *_uuid); extern uuid_rc_t uuid_clone (const uuid_t *_uuid, uuid_t **_clone); /* UUID generation */ extern uuid_rc_t uuid_load ( uuid_t *_uuid, const char *_name); extern uuid_rc_t uuid_make ( uuid_t *_uuid, unsigned int _mode, ...); /* UUID comparison */ extern uuid_rc_t uuid_isnil (const uuid_t *_uuid, int *_result); extern uuid_rc_t uuid_ismax (const uuid_t *_uuid, int *_result); extern uuid_rc_t uuid_compare (const uuid_t *_uuid, const uuid_t *_uuid2, int *_result); /* UUID import/export */ extern uuid_rc_t uuid_import ( uuid_t *_uuid, uuid_fmt_t _fmt, const void *_data_ptr, size_t _data_len); extern uuid_rc_t uuid_export (const uuid_t *_uuid, uuid_fmt_t _fmt, void *_data_ptr, size_t *_data_len); /* library utilities */ extern char *uuid_error (uuid_rc_t _rc); extern unsigned long uuid_version (void); #ifdef __cplusplus } #endif #endif /* __UUID_H__ */ ossp-uuid-UUID_1_6_4/uuid.pc.in000066400000000000000000000031751472561253600163620ustar00rootroot00000000000000## ## OSSP uuid - Universally Unique Identifier ## Copyright (c) 2004-2008 Ralf S. Engelschall ## Copyright (c) 2004-2008 The OSSP Project ## ## This file is part of OSSP uuid, a library for the generation ## of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## ## uuid.pc.in: pkg-config(1) specification ## prefix=@prefix@ includedir=@includedir@ libdir=@libdir@ Name: OSSP uuid Description: Universally Unique Identifier (UUID) Library Version: @UUID_VERSION_RAW@ URL: https://sr.ht/~nabijaczleweli/ossp Cflags: -I${includedir} Libs: -L${libdir} -l@libname@ Libs.private: @LIBS@ ossp-uuid-UUID_1_6_4/uuid_cli.c000066400000000000000000000202321472561253600164150ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid_cli.c: command line tool */ /* own headers */ #include "config.h" #include "uuid.h" /* system headers */ #include #include #include #include #include #include #include #include #include #define max(a, b) ((a) > (b) ? (a) : (b)) #define USAGE \ "usage: %1$s [-n count] [-o outfile] [-r|-F BIN|STR|SIV] [-v 1] [-m1]\n" \ " %1$s [-n count] [-o outfile] [-r|-F BIN|STR|SIV] -v 3 uuid|{nil|max|ns:{DNS|URL|OID|X500}} data\n" \ " %1$s [-n count] [-o outfile] [-r|-F BIN|STR|SIV] -v 4\n" \ " %1$s [-n count] [-o outfile] [-r|-F BIN|STR|SIV] -v 5 uuid|{nil|max|ns:{DNS|URL|OID|X500}} data\n" \ " %1$s [-n count] [-o outfile] [-r|-F BIN|STR|SIV] -v 6\n" \ " %1$s [-n count] [-o outfile] [-r|-F BIN|STR|SIV] -v 7\n" \ "\n" \ " %1$s -d [-o outfile] [ -F STR|SIV] uuid\n" \ " %1$s -d [-o outfile] [-r|-F BIN|STR|SIV] -\n" /* main procedure */ int main(int argc, char * argv[]) { const char * altfile = NULL; size_t count = 1; bool iterate = false; // not one at a time uuid_fmt_t fmt = UUID_FMT_STR; // default is ASCII output bool decode = false; // default is to encode unsigned int version = UUID_MAKE_V1; /* command line parsing */ for(int ch; (ch = getopt(argc, argv, "1n:rF:dmo:v:")) != -1;) { switch(ch) { case '1': iterate = true; break; case 'n': { char * p; long long c = strtoll(optarg, &p, 10); if(*p != '\0' || (c < 1 && (errno = ERANGE))) return fprintf(stderr, "%s: -n %s: %s\n", argv[0], optarg, strerror(errno ?: EINVAL)), 1; count = c; } break; case 'r': fmt = UUID_FMT_BIN; break; case 'F': if(!strcasecmp(optarg, "bin")) fmt = UUID_FMT_BIN; else if(!strcasecmp(optarg, "str")) fmt = UUID_FMT_STR; else if(!strcasecmp(optarg, "siv")) fmt = UUID_FMT_SIV; else return fprintf(stderr, "%s: -F %s: unknown; may be any of {\"BIN\", \"STR\", \"SIV\"}\n", argv[0], optarg), 1; break; case 'd': decode = true; break; case 'o': altfile = optarg; break; case 'm': version |= UUID_MAKE_MC; break; case 'v': { char * p; long v = strtol(optarg, &p, 10); if(*p != '\0') return fprintf(stderr, "%s: -v %s: %s\n", argv[0], optarg, strerror(errno ?: EINVAL)), 1; version = version & UUID_MAKE_MC; switch(v) { case 1: version |= UUID_MAKE_V1; break; case 3: version |= UUID_MAKE_V3; break; case 4: version |= UUID_MAKE_V4; break; case 5: version |= UUID_MAKE_V5; break; case 6: version |= UUID_MAKE_V6; break; case 7: version |= UUID_MAKE_V7; break; default: return fprintf(stderr, "%s: -v %s: %s\n", argv[0], optarg, strerror(ERANGE)), 1; } } break; default: return fprintf(stderr, USAGE, argv[0]), 1; } } const char * self = argv[0]; argv += optind; argc -= optind; if(altfile) if(!freopen(altfile, "w", stdout)) return fprintf(stderr, "%s: -o %s: %s\n", self, optarg, strerror(ERANGE)), 1; uuid_t * uuid; uuid_rc_t rc; if((rc = uuid_create(&uuid)) != UUID_RC_OK) return fprintf(stderr, "%s: allocate: %s\n", self, uuid_error(rc)), 1; char buf[max(UUID_LEN_BIN, max(UUID_LEN_STR, UUID_LEN_SIV)) + 1]; if(decode) { if(argc != 1) return fprintf(stderr, USAGE, self), 1; /* decoding */ const char * source = argv[0]; if(!strcmp(argv[0], "-")) { const char * lenname; size_t len = (fmt == UUID_FMT_BIN) ? ((lenname = "BIN"), UUID_LEN_BIN) : (fmt == UUID_FMT_STR) ? ((lenname = "STR"), UUID_LEN_STR) : (fmt == UUID_FMT_SIV) ? ((lenname = "SIV"), UUID_LEN_SIV) : (__builtin_unreachable(), 0); source = buf; if(fread(buf, len, 1, stdin) != 1) return fprintf(stderr, "%s: -: read %zu (UUID_LEN_%s): %s\n", self, len, lenname, strerror(errno)), 1; buf[len] = '\0'; if((rc = uuid_import(uuid, fmt, buf, len)) != UUID_RC_OK) return fprintf(stderr, "%s: -: import %s: %s\n", self, buf, uuid_error(rc)), 1; } else { if(fmt == UUID_FMT_BIN) return fprintf(stderr, "%s: -dF BIN: only acceptable with - (when reading from the standard input stream)\n", self), 1; else if(fmt == UUID_FMT_STR || fmt == UUID_FMT_SIV) { if((rc = uuid_import(uuid, fmt, argv[0], strlen(argv[0]))) != UUID_RC_OK) return fprintf(stderr, "%s: import %s: %s\n", self, argv[0], uuid_error(rc)), 1; } } void * vp = NULL; if((rc = uuid_export(uuid, UUID_FMT_TXT, &vp, NULL)) != UUID_RC_OK) return fprintf(stderr, "%s: export %s: %s\n", self, source, uuid_error(rc)), 1; fputs((char *)vp, stdout); } else { if((version & UUID_MAKE_V1 && argc != 0) || // (version & UUID_MAKE_V3 && argc != 2) || // (version & UUID_MAKE_V4 && argc != 0) || // (version & UUID_MAKE_V5 && argc != 2) || // (version & UUID_MAKE_V6 && argc != 0) || // (version & UUID_MAKE_V7 && argc != 0)) return fprintf(stderr, USAGE, self), 1; /* encoding */ for(size_t i = 0; i < count; ++i) { if(iterate) assert(uuid_load(uuid, "nil") == UUID_RC_OK); if(version & UUID_MAKE_V3 || version & UUID_MAKE_V5) { uuid_t * uuid_ns; if((rc = uuid_create(&uuid_ns)) != UUID_RC_OK) return fprintf(stderr, "%s: allocate: %s\n", self, uuid_error(rc)), 1; if((rc = uuid_load(uuid_ns, argv[0])) != UUID_RC_OK) if((rc = uuid_import(uuid_ns, UUID_FMT_STR, argv[0], strlen(argv[0]))) != UUID_RC_OK) return fprintf(stderr, "%s: import %s: %s\n", self, argv[0], uuid_error(rc)), 1; if((rc = uuid_make(uuid, version, uuid_ns, argv[1])) != UUID_RC_OK) return fprintf(stderr, "%s: make UUID %zu/%zu (%s %s): %s\n", self, i + 1, count, argv[0], argv[1], uuid_error(rc)), 1; assert(uuid_destroy(uuid_ns) == UUID_RC_OK); } else { if((rc = uuid_make(uuid, version)) != UUID_RC_OK) return fprintf(stderr, "%s: make UUID %zu/%zu: %s\n", self, i + 1, count, uuid_error(rc)), 1; } size_t buflen = sizeof(buf); if((rc = uuid_export(uuid, fmt, &(void *){buf}, &buflen)) != UUID_RC_OK) return fprintf(stderr, "%s: export UUID %zu/%zu: %s\n", self, i + 1, count, uuid_error(rc)), 1; if(fmt == UUID_FMT_BIN) fwrite(buf, buflen, 1, stdout); else if(fmt == UUID_FMT_STR || fmt == UUID_FMT_SIV) puts(buf); } } } ossp-uuid-UUID_1_6_4/uuid_dce.c000066400000000000000000000166431472561253600164140ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid_dce.c: DCE 1.1 compatibility API implementation */ /* include DCE 1.1 API */ #define uuid_t uuid_dce_t #include "uuid_dce.h" #undef uuid_t #undef uuid_create #undef uuid_create_nil #undef uuid_is_nil #undef uuid_compare #undef uuid_equal #undef uuid_from_string #undef uuid_to_string #undef uuid_hash /* include regular API */ #include "uuid.h" #include /* create a UUID (v1 only) */ void uuid_dce_create(uuid_dce_t *uuid_dce, int *status) { uuid_t *uuid; size_t len; void *vp; /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (uuid_dce == NULL) return; /* create UUID and export as binary representation */ if (uuid_create(&uuid) != UUID_RC_OK) return; if (uuid_make(uuid, UUID_MAKE_V1) != UUID_RC_OK) { uuid_destroy(uuid); return; } vp = uuid_dce; len = UUID_LEN_BIN; if (uuid_export(uuid, UUID_FMT_BIN, &vp, &len) != UUID_RC_OK) { uuid_destroy(uuid); return; } uuid_destroy(uuid); /* return successfully */ if (status != NULL) *status = uuid_s_ok; return; } /* create a Nil UUID */ void uuid_dce_create_nil(uuid_dce_t *uuid_dce, int *status) { /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (uuid_dce == NULL) return; /* short-circuit implementation, because Nil UUID is trivial to create, so no need to use regular OSSP uuid API */ memset(uuid_dce, 0, UUID_LEN_BIN); /* return successfully */ if (status != NULL) *status = uuid_s_ok; return; } /* check whether it is Nil UUID */ int uuid_dce_is_nil(uuid_dce_t *uuid_dce, int *status) { /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (uuid_dce == NULL) return 0; /* return successfully with result */ if (status != NULL) *status = uuid_s_ok; /* short-circuit implementation, because Nil UUID is trivial to check, so no need to use regular OSSP uuid API */ uuid_dce_t nil = {}; return !memcmp(uuid_dce, &nil, sizeof(uuid_dce_t)); } /* compare two UUIDs */ int uuid_dce_compare(uuid_dce_t *uuid_dce1, uuid_dce_t *uuid_dce2, int *status) { uuid_t *uuid1 = NULL; uuid_t *uuid2 = NULL; int result = 0; /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (uuid_dce1 == NULL || uuid_dce2 == NULL) return 0; /* import both UUID binary representations and compare them */ if (uuid_create(&uuid1) != UUID_RC_OK) goto leave; if (uuid_create(&uuid2) != UUID_RC_OK) goto leave; if (uuid_import(uuid1, UUID_FMT_BIN, uuid_dce1, UUID_LEN_BIN) != UUID_RC_OK) goto leave; if (uuid_import(uuid2, UUID_FMT_BIN, uuid_dce2, UUID_LEN_BIN) != UUID_RC_OK) goto leave; if (uuid_compare(uuid1, uuid2, &result) != UUID_RC_OK) goto leave; /* indicate successful operation */ if (status != NULL) *status = uuid_s_ok; /* cleanup and return */ leave: if (uuid1 != NULL) uuid_destroy(uuid1); if (uuid2 != NULL) uuid_destroy(uuid2); return result; } /* compare two UUIDs (equality only) */ int uuid_dce_equal(uuid_dce_t *uuid_dce1, uuid_dce_t *uuid_dce2, int *status) { /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (uuid_dce1 == NULL || uuid_dce2 == NULL) return 0; /* pass through to generic compare function */ return (uuid_dce_compare(uuid_dce1, uuid_dce2, status) == 0 ? 1 : 0); } /* import UUID from string representation */ void uuid_dce_from_string(const char *str, uuid_dce_t *uuid_dce, int *status) { uuid_t *uuid = NULL; size_t len; void *vp; /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (str == NULL || uuid_dce == NULL) return; /* import string representation and export binary representation */ if (uuid_create(&uuid) != UUID_RC_OK) goto leave; if (uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR) != UUID_RC_OK) goto leave; vp = uuid_dce; len = UUID_LEN_BIN; if (uuid_export(uuid, UUID_FMT_BIN, &vp, &len) != UUID_RC_OK) goto leave; /* indicate successful operation */ if (status != NULL) *status = uuid_s_ok; /* cleanup and return */ leave: if (uuid != NULL) uuid_destroy(uuid); return; } /* export UUID to string representation */ void uuid_dce_to_string(uuid_dce_t *uuid_dce, char **str, int *status) { uuid_t *uuid = NULL; /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (str == NULL || uuid_dce == NULL) return; /* import binary representation and export string representation */ if (uuid_create(&uuid) != UUID_RC_OK) goto leave; if (uuid_import(uuid, UUID_FMT_BIN, uuid_dce, UUID_LEN_BIN) != UUID_RC_OK) goto leave; size_t len = UUID_LEN_STR + 1; if (uuid_export(uuid, UUID_FMT_STR, str, &len) != UUID_RC_OK) goto leave; /* indicate successful operation */ if (status != NULL) *status = uuid_s_ok; /* cleanup and return */ leave: if (uuid != NULL) uuid_destroy(uuid); return; } /* export UUID into hash value */ unsigned int uuid_dce_hash(uuid_dce_t *uuid_dce, int *status) { unsigned int hash; /* initialize status */ if (status != NULL) *status = uuid_s_error; /* sanity check argument(s) */ if (uuid_dce == NULL) return 0; /* generate a hash value (DCE 1.1 actually requires 16-bit only) */ hash = (unsigned)uuid_dce->data[3] << 24 | // (unsigned)uuid_dce->data[2] << 16 | // (unsigned)uuid_dce->data[1] << 8 | // (unsigned)uuid_dce->data[0] << 0; /* return successfully */ if (status != NULL) *status = uuid_s_ok; return hash; } ossp-uuid-UUID_1_6_4/uuid_dce.h000066400000000000000000000064611472561253600164160ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid_dce.h: DCE 1.1 compatibility API definition */ #ifndef __UUID_DCE_H___ #define __UUID_DCE_H___ /* sanity check usage */ #ifdef __UUID_H__ #error the regular OSSP uuid API and the DCE 1.1 backward compatibility API are mutually exclusive -- you cannot use them at the same time. #endif /* resolve namespace conflicts (at linking level) with regular OSSP uuid API */ #define uuid_create uuid_dce_create #define uuid_create_nil uuid_dce_create_nil #define uuid_is_nil uuid_dce_is_nil #define uuid_compare uuid_dce_compare #define uuid_equal uuid_dce_equal #define uuid_from_string uuid_dce_from_string #define uuid_to_string uuid_dce_to_string #define uuid_hash uuid_dce_hash /* DCE 1.1 uuid_t type */ typedef struct { #if 0 /* stricter but unportable version */ uint32_t time_low; uint16_t time_mid; uint16_t time_hi_and_version; uint8_t clock_seq_hi_and_reserved; uint8_t clock_seq_low; uint8_t node[6]; #else /* sufficient and portable version */ unsigned char data[16]; #endif } uuid_t; typedef uuid_t *uuid_p_t; /* DCE 1.1 uuid_vector_t type */ typedef struct { unsigned int count; uuid_t *uuid[1]; } uuid_vector_t; /* DCE 1.1 UUID API status codes */ enum { uuid_s_ok = 0, /* standardized */ uuid_s_error = 1 /* implementation specific */ }; /* DCE 1.1 UUID API functions */ extern void uuid_create (uuid_t *, int *); extern void uuid_create_nil (uuid_t *, int *); extern int uuid_is_nil (uuid_t *, int *); extern int uuid_compare (uuid_t *, uuid_t *, int *); extern int uuid_equal (uuid_t *, uuid_t *, int *); extern void uuid_from_string (const char *, uuid_t *, int *); extern void uuid_to_string (uuid_t *, char **, int *); extern unsigned int uuid_hash (uuid_t *, int *); #endif /* __UUID_DCE_H___ */ ossp-uuid-UUID_1_6_4/uuid_mac.c000066400000000000000000000074441472561253600164200ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2004-2008 Ralf S. Engelschall ** Copyright (c) 2004-2008 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** uuid_mac.c: Media Access Control (MAC) resolver implementation */ /* own headers (part (1/2) */ #include "config.h" #define __EXTENSIONS__ // illumos /* system headers */ #include #include #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef HAVE_NET_IF_H #include #endif #ifdef HAVE_NET_IF_DL_H #include #endif #ifdef HAVE_NET_IF_ARP_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_IFADDRS_H #include #endif /* own headers (part (1/2) */ #include "uuid_mac.h" /* IEEE 802 MAC address encoding/decoding bit fields */ #define IEEE_MAC_MCBIT 0b00000001 #define min(a, b) ((a) < (b) ? (a) : (b)) /* return the Media Access Control (MAC) address of the first network interface card (NIC) with a non-multicast address */ bool mac_address(uint8_t * data_ptr) { #ifdef HAVE_IFADDRS_H struct ifaddrs *alloc = NULL, addr = {.ifa_name = "eth0", .ifa_flags = IFF_UP | IFF_BROADCAST}, *itr = &addr; if(getifaddrs(&alloc) == -1) alloc = NULL; else itr = alloc; bool ret = false; #if defined(HAVE_NET_IF_DL_H) // BSD class platforms (xxxBSD, MacOS X, etc) for(; itr; itr = itr->ifa_next) if(itr->ifa_addr != NULL && itr->ifa_addr->sa_family == AF_LINK) { struct sockaddr_dl * sdl = (void *)itr->ifa_addr; uint8_t * mac = (void *)(sdl->sdl_data + sdl->sdl_nlen); if(sdl->sdl_alen && !(mac[0] & IEEE_MAC_MCBIT)) { memcpy(data_ptr, mac, min(MAC_LEN, sdl->sdl_alen)); ret = true; break; } } #endif #if defined(HAVE_NET_IF_H) && defined(SIOCGIFHWADDR) // Linux and the illumos gate int s = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if(s == -1) return false; for(; itr; itr = itr->ifa_next) if((itr->ifa_flags & IFF_UP) && (itr->ifa_flags & IFF_BROADCAST)) { struct ifreq ifr; strncpy(ifr.ifr_name, itr->ifa_name, sizeof(ifr.ifr_name)); if(ioctl(s, SIOCGIFHWADDR, &ifr) == -1) continue; if(ifr.ifr_addr.sa_data[0] & IEEE_MAC_MCBIT) continue; memcpy(data_ptr, ifr.ifr_addr.sa_data, MAC_LEN); ret = true; goto ret; } ret: close(s); #endif if(alloc) freeifaddrs(alloc); return ret; #endif return false; } ossp-uuid-UUID_1_6_4/uuid_mac.h000066400000000000000000000003471472561253600164200ustar00rootroot00000000000000// SPDX-License-Identifier: 0BSD #ifndef __UUID_MAC_H__ #define __UUID_MAC_H__ #include #include #define MAC_LEN 6 extern __attribute__((visibility("hidden"))) bool mac_address(uint8_t * mac); #endif ossp-uuid-UUID_1_6_4/uuid_random.h000066400000000000000000000021631472561253600171360ustar00rootroot00000000000000// SPDX-License-Identifier: 0BSD #ifndef __RANDOM_H___ #define __RANDOM_H___ #include #include #include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #include #endif typedef struct { int fd; } random_t; static bool random_data(random_t * random, void * data_ptr, size_t data_len) { #ifdef _WIN32 (void)random; if(BCryptGenRandom(NULL, data_ptr, data_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) return false; #elif defined(HAVE_GETENTROPY) (void)random; if(getentropy(data_ptr, data_len)) return false; #else if(random->fd == -1) random->fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); if(random->fd == -1) random->fd = open("/dev/random", O_RDONLY | O_CLOEXEC); if(random->fd < 0) { random->fd = -2; return false; } char * data_itr = data_ptr; while(data_len) { ssize_t rd = read(random->fd, data_itr, data_len); if(rd == -1) { if(errno == EINTR) continue; return false; } data_itr += rd; data_len -= rd; } #endif return true; } static void random_destroy(random_t * random) { if(random->fd >= 0) close(random->fd); } #endif ossp-uuid-UUID_1_6_4/uuid_time.h000066400000000000000000000004271472561253600166150ustar00rootroot00000000000000// SPDX-License-Identifier: 0BSD #ifndef __UUID_TIME_H__ #define __UUID_TIME_H__ #if __has_include() #include #endif #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include static int sched_yield() { SwitchToThread(); return 0; } #endif #endif ossp-uuid-UUID_1_6_4/uuid_ui128.h000066400000000000000000000067031472561253600165320ustar00rootroot00000000000000/* ** OSSP uuid - Universally Unique Identifier ** Copyright (c) 2002-2005 Ralf S. Engelschall ** Copyright (c) 2002-2005 The OSSP Project ** ** This file is part of OSSP uuid, a library for the generation ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. */ #ifndef __UI128_H__ #define __UI128_H__ #include #include #define UI128_BASE 256 /* 2^8 */ typedef struct { uint8_t x[16]; /* 8*16 = 128 bit */ } ui128_t; static ui128_t strtou128(const char * str, size_t strmax, const char ** end); static void u128tostr(ui128_t x, char * str, size_t len); static ui128_t ui128_addn(ui128_t x, int y, int * ov); static ui128_t ui128_muln(ui128_t x, int y, int * ov); static ui128_t ui128_divn(ui128_t x, int y, int * ov); static int ui128_len(ui128_t x); /* decode decimal digits to a 16-byte array */ static ui128_t strtou128(const char * str, size_t strmax, const char ** end) { ui128_t z = {}; const char * cp = str; for(int carry; cp != str + strmax && *cp >= '0' && *cp <= '9'; ++cp) { z = ui128_muln(z, 10, &carry); if(carry) break; z = ui128_addn(z, *cp - '0', &carry); if(carry) break; } *end = cp; return z; } /* convert 16-byte array to decimal digits */ static void u128tostr(ui128_t x, char * str, size_t len) { int n = ui128_len(x); int i = 0; do { int r; x = ui128_divn(x, 10, &r); str[i++] = '0' + r; while(n > 1 && x.x[n - 1] == 0) n--; } while(i < ((int)len - 1) && (n > 1 || x.x[0] != 0)); str[i] = '\0'; for(int j = 0; j < --i; ++j) { char c = str[j]; str[j] = str[i]; str[i] = c; } } /* addition of an ui128_t and a single digit */ static ui128_t ui128_addn(ui128_t x, int y, int * ov) { ui128_t z; for(size_t i = 0; i < sizeof(x.x); ++i) { y += x.x[i]; z.x[i] = (y % UI128_BASE); y /= UI128_BASE; } *ov = y; return z; } static ui128_t ui128_muln(ui128_t x, int y, int * ov) { ui128_t z; int carry = 0; for(size_t i = 0; i < sizeof(x.x); ++i) { carry += (x.x[i] * y); z.x[i] = (carry % UI128_BASE); carry /= UI128_BASE; } *ov = carry; return z; } static ui128_t ui128_divn(ui128_t x, int y, int * ov) { ui128_t z; unsigned carry = 0; for(int i = (sizeof(x.x) - 1); i >= 0; --i) { carry = (carry * UI128_BASE) + x.x[i]; z.x[i] = (carry / y); carry %= y; } *ov = carry; return z; } static int ui128_len(ui128_t x) { int i; for(i = sizeof(x.x); i > 1 && x.x[i - 1] == 0; --i) ; return i; } #endif