diff options
author | Theodore Ts'o <tytso@mit.edu> | 2003-07-25 07:03:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2003-07-25 07:03:00 -0400 |
commit | 151c86abb96f1820ba0cb3b86689875d5faee2cf (patch) | |
tree | cffc7fd218fd0489d2efbfc895c73a91a3e227dc | |
parent | 9bf19713c8b4e5b325ad33c1b14271a2881fa381 (diff) | |
download | e2fsprogs-151c86abb96f1820ba0cb3b86689875d5faee2cf.tar.gz |
Separate out shared libraries out of e2fsprogs to real pacakges:
libss2, libcomerr2, libuuid1, and e2fslibs.
Remove Yann's TODO and README.Debian files.
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | debian/control | 121 | ||||
-rw-r--r-- | debian/e2fslibs.copyright | 25 | ||||
-rw-r--r-- | debian/e2fslibs.files | 3 | ||||
-rw-r--r-- | debian/e2fsprogs.README.Debian | 101 | ||||
-rw-r--r-- | debian/e2fsprogs.TODO | 13 | ||||
-rw-r--r-- | debian/e2fsprogs.copyright | 19 | ||||
-rw-r--r-- | debian/e2fsprogs.shlibs.local | 5 | ||||
-rw-r--r-- | debian/libcomerr2.files | 2 | ||||
-rw-r--r-- | debian/libss2.files | 1 | ||||
-rw-r--r-- | debian/libuuid1.copyright | 18 | ||||
-rw-r--r-- | debian/libuuid1.files | 3 | ||||
-rw-r--r-- | debian/rules | 103 | ||||
-rw-r--r-- | debian/shlibs.local | 1 | ||||
-rw-r--r-- | doc/draft-leach-uuids-guids-01.txt | 1708 |
15 files changed, 1896 insertions, 231 deletions
@@ -190,3 +190,7 @@ TODO list. Debugfs's link command should set the file type information --------------------------------------------------------------- +From e2fsprogs Debian TODO file as of 1.10-13. + +* Maybe make -dbg packages. Look at how others do it. + diff --git a/debian/control b/debian/control index 4a78f74b..71bf9ea1 100644 --- a/debian/control +++ b/debian/control @@ -21,24 +21,49 @@ Description: A statically-linked version of the ext2 filesystem checker You may want to install a statically-linked shell as well, to be able to run this program if something like your C library gets corrupted. +Package: libcomerr2 +Section: libs +Priority: required +Provides: libcomerr-kth-compat +Depends: ${shlibs:Depends} +Replaces: e2fsprogs (<< 1.34-1) +Architecture: any +Description: The Common Error Description library + libcomerr is an attempt to present a common error-handling mechanism to + manipulate the most common form of error code in a fashion that does not + have the problems identified with mechanisms commonly in use. + Package: comerr-dev Section: libdevel Priority: extra -Depends: ${libcdev:Depends}, libcomerr2 +Depends: libcomerr2 Suggests: doc-base -Conflicts: e2fsprogs (<< 1.10-6) Replaces: e2fslibs-dev (<< 1.33-2), libkrb5-dev (<< 1.3) Architecture: any Description: The Common Error Description library - headers and static libraries - libcomerr is an attempt to present a common error-handling mechanism to + libcom_err is an attempt to present a common error-handling mechanism to manipulate the most common form of error code in a fashion that does not have the problems identified with mechanisms commonly in use. + . + This package contains the development environment for the com_err library. + +Package: libss2 +Section: libs +Priority: required +Depends: libcomerr2 +Replaces: e2fsprogs (<< 1.34-1) +Architecture: any +Description: Command-line interface parsing library + This package includes a tool that parses a command table to generate + a simple command-line interface parser, the include files needed to + compile and use it, and the static libs. + . + It was originally inspired by the Multics SubSystem library. Package: ss-dev Section: libdevel Priority: extra -Depends: ${libcdev:Depends}, libss2 -Conflicts: e2fsprogs (<< 1.10-6) +Depends: libss2 Architecture: any Description: Command-line interface parsing library - headers and static libraries This package includes a tool that parses a command table to generate @@ -46,12 +71,28 @@ Description: Command-line interface parsing library - headers and static librari compile and use it, and the static libs. . It was originally inspired by the Multics SubSystem library. + . + This package contains the development environment for the ss library. + +Package: libuuid1 +Section: libs +Priority: required +Depends: ${shlibs:Depends} +Replaces: e2fsprogs (<< 1.34-1) +Architecture: any +Description: Universally unique id library + libuuid generates and parses 128-bit universally unique id's (UUID's), + using a standard which is blessed by both Microsoft and DCE, and is + being proposed as an internet standard. See the internet-draft: + . + draft-leach-uuids-guids-01.txt + . + for more information. Package: uuid-dev Section: libdevel Priority: extra -Depends: ${libcdev:Depends}, e2fsprogs (= ${Source-Version}) -Conflicts: e2fsprogs (<< 1.10-6) +Depends: libuuid1 (= ${Source-Version}) Replaces: e2fslibs-dev (<< 1.15) Architecture: any Description: Universally unique id library - headers and static libraries @@ -62,6 +103,8 @@ Description: Universally unique id library - headers and static libraries draft-leach-uuids-guids-01.txt . for more information. + . + This package contains the development environment for the uuid library. Package: libblkid1 Section: libs @@ -117,13 +160,44 @@ Description: A stripped-down versions of e2fsprogs, for debian-installer Don't attempt to install this package, it has no support for a couple of features you surely want. Anyway it should refuse to install. +Package: e2fslibs +Section: libs +Priority: required +Depends: ${shlibs:Depends} +Replaces: e2fsprogs (<< 1.34-1) +Provides: libext2fs2, libe2p2 +Architecture: any +Description: The EXT2 filesystem libraries + The ext2fs and e2p libraries are used by programs that directly access + EXT2 filesystems from usermode programs. The EXT2 filesystem is very often + used as the default filesystem on Linux systems. Various system programs + that use libext2fs include e2fsck, mke2fs, tune2fs, etc. Programs that use + libe2p include dumpe2fs, chattr, and lsattr. + +Package: e2fslibs-dev +Section: libdevel +Priority: extra +Depends: comerr-dev, e2fslibs (= ${Source-Version}) +Suggests: doc-base +Provides: ext2fs-dev, e2p-dev +Replaces: libkrb5-dev (<< 1.3) +Architecture: any +Description: The EXT2 filesystem libraries - headers and static libraries + The ext2fs and e2p libraries are used by programs that directly access + EXT2 filesystems from usermode programs. The EXT2 filesystem is very often + used as the default filesystem on Linux systems. Various system programs + that use libext2fs include e2fsck, mke2fs, tune2fs, etc. Programs that use + libe2p include dumpe2fs, chattr, and lsattr. + . + This package contains the development environment for the ext2fs and e2p + libraries. + Package: e2fsprogs Essential: yes Pre-Depends: ${shlibs:Depends} Depends: Suggests: gpart, parted, e2fsck-static Conflicts: dump (<< 0.4b4-4), quota (<< 1.55-8.1), initscripts (<< 2.85-4) -Provides: libcomerr2, libcomerr-kth-compat, libss2, libext2fs2, libe2p2, libuuid1 Architecture: any Description: The EXT2 file system utilities and libraries EXT2 stands for "Extended Filesystem", version 2. It's the main @@ -131,34 +205,3 @@ Description: The EXT2 file system utilities and libraries . This package contains programs for creating, checking, and maintaining EXT2 filesystems, and the generic `fsck' wrapper. - -Package: e2fslibs-dev -Section: libdevel -Priority: extra -Depends: comerr-dev, e2fsprogs (= ${Source-Version}) -Suggests: doc-base -Provides: ext2fs-dev, e2p-dev -Conflicts: e2fsprogs (<< 1.10-6) -Replaces: libkrb5-dev (<< 1.3) -Architecture: any -Description: The headers and static libraries for ext2fs-aware tools-development - EXT2FS stands for "Extended Filesystem", version 2. It's the filesystem - type used for hard disks on Debian and other Linux systems. - . - This package contains the headers and shared libraries needed to compile - ext2fs-aware programs. Only programmers that really manipulate - features specific to the ext2 filesystem will need this. Most - programmers will use the generic filesystem-independent interface - from libc. - . - It also contains dev files for the e2p lib used by - the e2fsprogs, but which is not yet packaged all by itself - because it lacks documentation. It may also lack some support - files, by I can't really know until someone uses it... - . - libe2p is for user-level e2fsprogs commands. It's used by dumpe2fs, - chattr, and lsattr. Functions in libe2p typically have two - characteristics (a) don't require that block device containing the - filesystem be opened directly (functions in libext2fs do), and (b) - libe2p typically contains printf statements or parse user input, and so - have more internationalization issues. diff --git a/debian/e2fslibs.copyright b/debian/e2fslibs.copyright new file mode 100644 index 00000000..8d9faa09 --- /dev/null +++ b/debian/e2fslibs.copyright @@ -0,0 +1,25 @@ +This is the Debian GNU/Linux prepackaged version of the EXT2 file +system utilities (e2fsck, mke2fs, etc.). The EXT2 utilities were +written by Theodore Ts'o <tytso@mit.edu> and Remy Card <card@masi.ibp.fr>. + +Sources were obtained from http://sourceforge.net/projects/e2fsprogs + +Packaging is copyright (c) 2003 Theodore Ts'o <tytso@mit.edu> + copyright (c) 1997-2003 Yann Dirson <dirson@debian.org> + copyright (c) 2001 Alcove <http://www.alcove.com/> + copyright (c) 1997 Klee Dienes + copyright (c) 1995-1996 Michael Nonweiler <mrn20@cam.ac.uk> + +Upstream Author: Theodore Ts'o <tytso@mit.edu> + +Copyright notice: + +This package, the EXT2 filesystem libraries, are protected by the GNU +Public License. + + Theodore Ts'o + 15-Mar-2003 + +On Debian GNU systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. + diff --git a/debian/e2fslibs.files b/debian/e2fslibs.files new file mode 100644 index 00000000..5678875e --- /dev/null +++ b/debian/e2fslibs.files @@ -0,0 +1,3 @@ +lib/libext2fs* +lib/libe2p* + diff --git a/debian/e2fsprogs.README.Debian b/debian/e2fsprogs.README.Debian deleted file mode 100644 index 07722be2..00000000 --- a/debian/e2fsprogs.README.Debian +++ /dev/null @@ -1,101 +0,0 @@ -e2fsprogs for Debian -==================== - -e2fsprogs includes the uuidgen(1) program, although it is not directly -to e2fsprogs - it would belong to the libuuid package, but the uuid -shared lib is currently part of the e2fsprogs package. See below for -more details. - - -Here's the documentation for the Conflicts/Provides fields: - -* old dump and quota packages used to depend on old (libc5) e2fsprogs -itself, as it contained the shared libs. We must conflict with these -incompatible versions. - - -* All -g package names were a transient experiment during hamm -development. - - -* Here's the reasonning for not moving the libs outside of the -e2fsprogs package (this may be partly obsolete): - -If we have: - -e2fsprogs_1.10-2 is essential - -e2fsprogs_1.10-11 is essential - predepends on comerr2g - -comerr2g_2.0-1.10-11: - is not essential - conflicts with e2fsprogs_1.10-2 - -...then e2fsprogs_1.10-11 can't be installed before comerr2g because -of the predependency, and comerr2g cannot be installed before -e2fsprogs_1.10-11 because of the conflict. - -This totally comes from the fact that e2fsprogs was initially built as -an *essential package with shared libs*. - -My initial solution, namely changing the predependency into a simple -dependency, turns out to be a system-integrity problem: - -$ dpkg -i e2fsprogs_1.10-11*deb comerr2g_2.0-1.10-11*deb - -...will, if comerr2g fails to unpack or configure, let e2fsprogs in an -unusable state. - - -* This raises the problem that most of these libs are general-purpose -libs, and will be used by more and more packages. The lib-dependency -mechanism requires for proper fonctionning that we keep track of these -libs changing version, as well as infos such as libc5/6 issues. - -The standard way to do it is using standalone packages for those libs, -which is not possible here (see above). - -My solution in this case is the use of the following virtual packages: - - libss2, libcomerr2, libe2p2, libuuid1, libext2fs2 - -These are automatically referenced thanks to the shlibs file. They -are currently provided by e2fsprogs. - - -* Additionally, we must add to the shlibs file a dep on "e2fsprogs (>= -<current-version>)", so that programs using new functions from those -libs will not break (see #139274). Note that this will be superceeded -by versionned Provides: when they will come in dpkg. - -We can see the reality of the problem: - -$ diff <(nm -D 1.18/lib/libuuid.so.1 | cut -c10- | grep -v ^U) \ - <(nm -D 1.27/lib/libuuid.so.1 | cut -c10- | grep -v ^U) -3a4 -> w __cxa_finalize -6a8,9 -> T __udivdi3 -> T __umoddi3 - -<=== Actually, there are **no** API changes in libuuid between - e2fsprogs 1.27 and 1.18. The observant reader will notice - that the "reality of the problem" show above shows symbol - names which are are prefixed with "__". This means no program - should be using them. In point of fact, these are functions - created by gcc, and the incompatibility reported in #139274 - was much more likely casued by glibc or gcc incompatibilities, - not changes in the libuuid library. Hence, I am removing the - shlibs hack, because it does far more harm than it does good. - (Next time, *please* consult me before making changes like - this.) - -- Theodore Ts'o, tytso@mit.edu. - - -* e2fsprogs still Provides/Conflicts with e2fslibsg to allow upgrading -from pre 1.10-13 releases (from unstable hamm). This does not seem to -be possible for ss2g and comerr2g for some still-to-be-investigated -reason. - -Yann Dirson <dirson@debian.org> diff --git a/debian/e2fsprogs.TODO b/debian/e2fsprogs.TODO deleted file mode 100644 index a716f49d..00000000 --- a/debian/e2fsprogs.TODO +++ /dev/null @@ -1,13 +0,0 @@ -e2fsprogs Debian TODO file as of 1.10-13. -This file may or may not be up to date. - -* Report to Ted: inconsistent "et/com_err.h", <et/com_err.h>, <com_err.h> - under lib/ -* What about making com_err more self-consistant ("et" / "com_err") - -* Suppress as many references as possible to the libcom_err version number in - source control files and debian/ subdir. - -* Maybe make -dbg packages. Look at how others do it. - -* Fix com_err.texinfo. diff --git a/debian/e2fsprogs.copyright b/debian/e2fsprogs.copyright index 047c40be..a7f390f5 100644 --- a/debian/e2fsprogs.copyright +++ b/debian/e2fsprogs.copyright @@ -4,8 +4,8 @@ written by Theodore Ts'o <tytso@mit.edu> and Remy Card <card@masi.ibp.fr>. Sources were obtained from http://sourceforge.net/projects/e2fsprogs -Packaging is copyright (c) 1997-2003 Yann Dirson <dirson@debian.org> - copyright (c) 2003 Theodore Ts'o <tytso@mit.edu> +Packaging is copyright (c) 2003 Theodore Ts'o <tytso@mit.edu> + copyright (c) 1997-2003 Yann Dirson <dirson@debian.org> copyright (c) 2001 Alcove <http://www.alcove.com/> copyright (c) 1997 Klee Dienes copyright (c) 1995-1996 Michael Nonweiler <mrn20@cam.ac.uk> @@ -41,18 +41,3 @@ enough lead time. On Debian GNU systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. - -The 1.19 RELEASE-NOTES mentions that the UUID library (libuuid) is -covered by the LGPL. After clarification from upstream author, it -appears to refer to the so-called "Library General Public License" -(aka LGPL v2), and not the "Lesser General Public License" (aka LGPL -v2.1). - -On Debian GNU systems, the complete text of the GNU LGPL v2 can be -found in `/usr/share/common-licenses/LGPL-2'. - - -The ss and com_err libraries, available in separate packages, fall -under another licence. Please refer to the relevant copyright files -for these libs. - diff --git a/debian/e2fsprogs.shlibs.local b/debian/e2fsprogs.shlibs.local new file mode 100644 index 00000000..f62a1dcf --- /dev/null +++ b/debian/e2fsprogs.shlibs.local @@ -0,0 +1,5 @@ +libcom_err 2 libcomerr2 (>= 1.34-1) +libss 2 libss2 (>= 1.34-1) +libuuid 1 libuuid1 (>= 1.34-1) +libext2fs 2 e2fslibs (>= 1.34-1) +libe2p 2 e2fslibs (>= 1.34-1) diff --git a/debian/libcomerr2.files b/debian/libcomerr2.files new file mode 100644 index 00000000..2600ae0f --- /dev/null +++ b/debian/libcomerr2.files @@ -0,0 +1,2 @@ +lib/libcom_err* + diff --git a/debian/libss2.files b/debian/libss2.files new file mode 100644 index 00000000..5f8175a2 --- /dev/null +++ b/debian/libss2.files @@ -0,0 +1 @@ +lib/libss* diff --git a/debian/libuuid1.copyright b/debian/libuuid1.copyright new file mode 100644 index 00000000..42bf8230 --- /dev/null +++ b/debian/libuuid1.copyright @@ -0,0 +1,18 @@ +This package was added to the e2fsprogs debian source package by +Theodore Ts'o <tytso@mit.edu> on Sat Mar 15 15:33:37 EST 2003 + +It is part of the main e2fsprogs distribution, which can be found at: + + http://sourceforge.net/projects/e2fsprogs + +Upstream Author: Theodore Ts'o <tytso@mit.edu> + +Copyright: + +Copyright (C) 1999, 2000, 2003 by Theodore Ts'o + +You are free to distribute this software under the terms of the GNU +Library General Public License. (aka LGPL v2) + +On Debian GNU systems, the complete text of the GNU LGPL v2 can be +found in `/usr/share/common-licenses/LGPL-2'. diff --git a/debian/libuuid1.files b/debian/libuuid1.files new file mode 100644 index 00000000..fb1c3cb8 --- /dev/null +++ b/debian/libuuid1.files @@ -0,0 +1,3 @@ +lib/libuuid* +usr/bin/uuidgen +usr/share/man/man1/uuidgen.1* diff --git a/debian/rules b/debian/rules index 97f7744d..8a600486 100644 --- a/debian/rules +++ b/debian/rules @@ -61,8 +61,6 @@ UDEB_PRIORITY = $(shell grep '^Package: e2fsprogs-udeb' debian/control -A 10 | g BLKID_UDEB_NAME = libblkid1-udeb_$(MAIN_VERSION)_$(DEB_HOST_ARCH).udeb BLKID_UDEB_PRIORITY = $(shell grep '^Package: libblkid1-udeb' debian/control -A 10 | grep ^Priority: | cut -d ' ' -f 2) -SUBPACKAGES_DIRS = tmp e2fslibs-dev comerr-dev ss-dev - STAMPSDIR=debian/stampdir CFGSTDSTAMP=${STAMPSDIR}/configure-std-stamp CFGBFSTAMP=${STAMPSDIR}/configure-bf-stamp @@ -275,106 +273,89 @@ binary-arch: install install-udeb mkdir -p ${debdir}/e2fsck-static/usr/share/doc/ ln -sf e2fsprogs ${debdir}/e2fsck-static/usr/share/doc/e2fsck-static - mkdir -p ${debdir}/e2fslibs-dev/usr/share/doc/e2fsprogs - ln -sf e2fsprogs ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs-dev + mkdir -p ${debdir}/libblkid${BLKID_SOVERSION}/usr/share/doc/libblkid${BLKID_SOVERSION} + mkdir -p ${debdir}/libblkid-dev/usr/share/doc + ln -sf libblkid${BLKID_SOVERSION} ${debdir}/libblkid-dev/usr/share/doc/libblkid-dev - mkdir -p ${debdir}/uuid-dev/usr/share/doc/e2fsprogs - ln -sf e2fsprogs ${debdir}/uuid-dev/usr/share/doc/uuid-dev + mkdir -p ${debdir}/libss${SS_SOVERSION}/usr/share/doc/libss${SS_SOVERSION} + mkdir -p ${debdir}/ss-dev/usr/share/doc + ln -sf libss${SS_SOVERSION} ${debdir}/ss-dev/usr/share/doc/ss-dev - # comerr and ss have their own copyright notices - mkdir -p ${maindir}/usr/share/doc/libcomerr${COMERR_SOVERSION} - mkdir -p ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION} + mkdir -p ${debdir}/libcomerr${COMERR_SOVERSION}/usr/share/doc/libcomerr${COMERR_SOVERSION} + mkdir -p ${debdir}/comerr-dev/usr/share/doc ln -sf libcomerr${COMERR_SOVERSION} ${debdir}/comerr-dev/usr/share/doc/comerr-dev - mkdir -p ${maindir}/usr/share/doc/libss${SS_SOVERSION} - mkdir -p ${debdir}/ss-dev/usr/share/doc/libss${SS_SOVERSION} - ln -sf libss${SS_SOVERSION} ${debdir}/ss-dev/usr/share/doc/ss-dev + mkdir -p ${debdir}/libuuid${UUID_SOVERSION}/usr/share/doc/libuuid${UUID_SOVERSION} + mkdir -p ${debdir}/uuid-dev/usr/share/doc + ln -sf libuuid${UUID_SOVERSION} ${debdir}/uuid-dev/usr/share/doc/uuid-dev - mkdir -p ${debdir}/libblkid${BLKID_SOVERSION}/usr/share/doc/libblkid${BLKID_SOVERSION} - mkdir -p ${debdir}/libblkid-dev/usr/share/doc - ln -sf libblkid${BLKID_SOVERSION} ${debdir}/libblkid-dev/usr/share/doc/libblkid-dev - - for i in libcomerr${COMERR_SOVERSION} libss${SS_SOVERSION}; do \ - install -m 644 debian/$$i.copyright \ - ${maindir}/usr/share/doc/$$i/copyright ; \ - done + mkdir -p ${debdir}/e2fslibs/usr/share/doc/e2fslibs + mkdir -p ${debdir}/e2fslibs-dev/usr/share/doc + ln -sf e2fslibs ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs-dev install -m 644 debian/libblkid.copyright \ ${debdir}/libblkid${BLKID_SOVERSION}/usr/share/doc/libblkid${BLKID_SOVERSION}/copyright dh_installdocs -Ne2fsprogs-udeb -Nlibblkid1-udeb - # libblkid is under the the LGPL - # HTML docs - install -d ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs-dev/html-info/ + install -d ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs/html-info/ install -p ${stdbuilddir}/doc/libext2fs_*.html \ - ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs-dev/html-info/ - install -d ${debdir}/comerr-dev/usr/share/doc/comerr-dev/html-info/ + ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs/html-info/ + install -d ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION}/html-info/ install -p ${stdbuilddir}/lib/et/com_err_*.html \ - ${debdir}/comerr-dev/usr/share/doc/comerr-dev/html-info/ + ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION}/html-info/ # texinfo docs + mkdir -p ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION} install -p ${topdir}/doc/libext2fs.texinfo \ - ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs-dev/libext2fs.texi + ${debdir}/e2fslibs-dev/usr/share/doc/e2fslibs/libext2fs.texi install -p ${topdir}/lib/et/com_err.texinfo \ ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION}/com_err.texi - dh_installexamples + install -d ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION}/examples + install -p -m 0644 lib/ss/ss_err.et \ + ${stdbuilddir}/lib/ext2fs/ext2_err.et \ + ${debdir}/comerr-dev/usr/share/doc/libcomerr${COMERR_SOVERSION}/examples + install -d ${debdir}/ss-dev/usr/share/doc/libss${SS_SOVERSION}/examples + install -p -m 0644 debugfs/debug_cmds.ct \ + ${debdir}/ss-dev/usr/share/doc/libss${SS_SOVERSION}/examples + + install -d ${debdir}/uuid-dev/usr/share/doc/libuuid${UUID_SOVERSION} + install -p -m 0644 doc/draft-leach-uuids-guids-01.txt \ + ${debdir}/uuid-dev/usr/share/doc/libuuid${UUID_SOVERSION} dh_installinfo -pcomerr-dev ${stdbuilddir}/lib/et/com_err.info dh_installinfo -pe2fslibs-dev ${stdbuilddir}/doc/libext2fs.info DH_OPTIONS= dh_installchangelogs -pe2fsprogs -plibblkid${BLKID_SOVERSION} - - for i in libcomerr${COMERR_SOVERSION} libss${SS_SOVERSION} ; do \ - mkdir -p ${maindir}/usr/share/doc/$$i ; \ - ln -s ../e2fsprogs/changelog.Debian.gz ${maindir}/usr/share/doc/$$i/ ; \ - ln -s ../e2fsprogs/changelog.gz ${maindir}/usr/share/doc/$$i/ ; \ - done + DH_OPTIONS= dh_installchangelogs -pe2fsprogs -plibcomerr${COMERR_SOVERSION} + DH_OPTIONS= dh_installchangelogs -pe2fsprogs -plibss${SS_SOVERSION} + DH_OPTIONS= dh_installchangelogs -pe2fsprogs -plibuuid${UUID_SOVERSION} + DH_OPTIONS= dh_installchangelogs -pe2fsprogs -pe2fslibs dh_strip dh_compress dh_fixperms - echo "libcdev:Depends=${LIBC-DEV}" > debian/comerr-dev.substvars - echo "libcdev:Depends=${LIBC-DEV}" > debian/ss-dev.substvars - echo "libcdev:Depends=${LIBC-DEV}" > debian/uuid-dev.substvars - echo "libcdev:Depends=${LIBC-DEV}" > debian/blkid-dev.substvars - echo "libcdev:Depends=${LIBC-DEV}" > debian/e2fslibs-dev.substvars - -# Call this mostly to get the maintainer-script snippets - dh_makeshlibs -pe2fsprogs -# We overwrite the shlibs by hand because of virtual packages used - : > debian/e2fsprogs/DEBIAN/shlibs - echo "libext2fs ${EXT2FS_SOVERSION} libext2fs${EXT2FS_SOVERSION}" \ - >> debian/e2fsprogs/DEBIAN/shlibs - echo "libe2p ${E2P_SOVERSION} libe2p${E2P_SOVERSION}" \ - >> debian/e2fsprogs/DEBIAN/shlibs - echo "libuuid ${UUID_SOVERSION} libuuid${UUID_SOVERSION}" \ - >> debian/e2fsprogs/DEBIAN/shlibs - echo "libcom_err ${COMERR_SOVERSION} libcomerr${COMERR_SOVERSION}, libcomerr-kth-compat" \ - >> debian/e2fsprogs/DEBIAN/shlibs - echo "libss ${SS_SOVERSION} libss${SS_SOVERSION}" \ - >> debian/e2fsprogs/DEBIAN/shlibs - - dh_makeshlibs -plibblkid${BLKID_SOVERSION} + dh_makeshlibs + dh_makeshlibs -plibcomerr${COMERR_SOVERSION} \ + -V 'libcomerr2 (>= 1.33-3)' dh_installdeb dh_shlibdeps -l${stdbuilddir}/lib + dh_shlibdeps -pe2fsprogs -l${stdbuilddir}/lib \ + -u"-Ldebian/e2fsprogs.shlibs.local" - dh_gencontrol -Ncomerr-dev -Nss-dev -Nuuid-dev -Ne2fsprogs-udeb -Nlibblkid1-udeb + dh_gencontrol -Ncomerr-dev -Nss-dev -Nuuid-dev \ + -Ne2fsprogs-udeb -Nlibblkid1-udeb DH_OPTIONS= dh_gencontrol -pcomerr-dev \ -u '-v${COMERR_VERSION}-${MAIN_VERSION}' DH_OPTIONS= dh_gencontrol -pss-dev \ -u '-v${SS_VERSION}-${MAIN_VERSION}' DH_OPTIONS= dh_gencontrol -puuid-dev \ -u '-v${UUID_VERSION}-${MAIN_VERSION}' - DH_OPTIONS= dh_gencontrol -plibblkid-dev \ - -u '-v${MAIN_VERSION}' - DH_OPTIONS= dh_gencontrol -plibblkid${BLKID_SOVERSION} \ - -u '-v${MAIN_VERSION}' dh_md5sums -Ne2fsprogs-udeb -Nlibblkid1-udeb dh_builddeb -Ne2fsprogs-udeb -Nlibblkid1-udeb diff --git a/debian/shlibs.local b/debian/shlibs.local index 1cd5693a..e678de0b 100644 --- a/debian/shlibs.local +++ b/debian/shlibs.local @@ -3,3 +3,4 @@ libe2p 2 libuuid 1 libcom_err 2 libss 2 +libblkid 1 diff --git a/doc/draft-leach-uuids-guids-01.txt b/doc/draft-leach-uuids-guids-01.txt new file mode 100644 index 00000000..d611d06f --- /dev/null +++ b/doc/draft-leach-uuids-guids-01.txt @@ -0,0 +1,1708 @@ + + + + + + +Network Working Group Paul J. Leach, Microsoft +INTERNET-DRAFT Rich Salz, Certco +<draft-leach-uuids-guids-01.txt> +Category: Standards Track +Expires August 4, 1998 February 4, 1998 + + + + UUIDs and GUIDs + +STATUS OF THIS MEMO + + This document is an Internet-Draft. Internet-Drafts are working + documents of the Internet Engineering Task Force (IETF), its areas, + and its working groups. Note that other groups may also distribute + working documents as Internet-Drafts. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress". + + To learn the current status of any Internet-Draft, please check the + "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow + Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), + munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or + ftp.isi.edu (US West Coast). + + Distribution of this document is unlimited. Please send comments to + the authors or the CIFS mailing list at <cifs@discuss.microsoft.com>. + Discussions of the mailing list are archived at + <URL:http://discuss.microsoft.com/archives/index. + + +ABSTRACT + + This specification defines the format of UUIDs (Universally Unique + IDentifier), also known as GUIDs (Globally Unique IDentifier). A UUID + is 128 bits long, and if generated according to the one of the + mechanisms in this document, is either guaranteed to be different + from all other UUIDs/GUIDs generated until 3400 A.D. or extremely + likely to be different (depending on the mechanism chosen). UUIDs + were originally used in the Network Computing System (NCS) [1] and + later in the Open Software Foundation's (OSF) Distributed Computing + Environment [2]. + + This specification is derived from the latter specification with the + kind permission of the OSF. + + +Table of Contents + +1. Introduction .......................................................3 + + +[Page 1] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + +2. Motivation .........................................................3 + +3. Specification ......................................................3 + + 3.1 Format............................................................4 + + 3.1.1 Variant......................................................4 + + 3.1.2 UUID layout..................................................5 + + 3.1.3 Version......................................................5 + + 3.1.4 Timestamp....................................................6 + + 3.1.5 Clock sequence...............................................6 + + 3.1.6 Node.........................................................7 + + 3.1.7 Nil UUID.....................................................7 + + 3.2 Algorithms for creating a time-based UUID.........................7 + + 3.2.1 Basic algorithm..............................................7 + + 3.2.2 Reading stable storage.......................................8 + + 3.2.3 System clock resolution......................................8 + + 3.2.4 Writing stable storage.......................................9 + + 3.2.5 Sharing state across processes...............................9 + + 3.2.6 UUID Generation details......................................9 + + 3.3 Algorithm for creating a name-based UUID.........................10 + + 3.4 Algorithms for creating a UUID from truly random or pseudo-random + numbers .............................................................11 + + 3.5 String Representation of UUIDs...................................12 + + 3.6 Comparing UUIDs for equality.....................................12 + + 3.7 Comparing UUIDs for relative order...............................13 + + 3.8 Byte order of UUIDs..............................................13 + +4. Node IDs when no IEEE 802 network card is available ...............14 + +5. Obtaining IEEE 802 addresses ......................................15 + +6. Security Considerations ...........................................15 + +7. Acknowledgements ..................................................15 + + Leach, Salz expires Aug 1998 [Page 2] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + +8. References ........................................................15 + +9. Authors' addresses ................................................16 + +10.Notice ............................................................16 + +11.Full Copyright Statement ..........................................16 + +Appendix A _ UUID Sample Implementation...............................17 + +Appendix B _ Sample output of utest...................................27 + +Appendix C _ Some name space IDs......................................27 + + + + +1. Introduction + + This specification defines the format of UUIDs (Universally Unique + IDentifiers), also known as GUIDs (Globally Unique IDentifiers). A + UUID is 128 bits long, and if generated according to the one of the + mechanisms in this document, is either guaranteed to be different + from all other UUIDs/GUIDs generated until 3400 A.D. or extremely + likely to be different (depending on the mechanism chosen). + + +2. Motivation + + One of the main reasons for using UUIDs is that no centralized + authority is required to administer them (beyond the one that + allocates IEEE 802.1 node identifiers). As a result, generation on + demand can be completely automated, and they can be used for a wide + variety of purposes. The UUID generation algorithm described here + supports very high allocation rates: 10 million per second per + machine if you need it, so that they could even be used as + transaction IDs. + + UUIDs are fixed-size (128-bits) which is reasonably small relative to + other alternatives. This fixed, relatively small size lends itself + well to sorting, ordering, and hashing of all sorts, storing in + databases, simple allocation, and ease of programming in general. + + +3. Specification + + A UUID is an identifier that is unique across both space and time, + with respect to the space of all UUIDs. To be precise, the UUID + consists of a finite bit space. Thus the time value used for + constructing a UUID is limited and will roll over in the future + (approximately at A.D. 3400, based on the specified algorithm). A + UUID can be used for multiple purposes, from tagging objects with an + extremely short lifetime, to reliably identifying very persistent + objects across a network. + + Leach, Salz expires Aug 1998 [Page 3] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + The generation of UUIDs does not require that a registration + authority be contacted for each identifier. Instead, it requires a + unique value over space for each UUID generator. This spatially + unique value is specified as an IEEE 802 address, which is usually + already available to network-connected systems. This 48-bit address + can be assigned based on an address block obtained through the IEEE + registration authority. This section of the UUID specification + assumes the availability of an IEEE 802 address to a system desiring + to generate a UUID, but if one is not available section 4 specifies a + way to generate a probabilistically unique one that can not conflict + with any properly assigned IEEE 802 address. + + +3.1 Format + + In its most general form, all that can be said of the UUID format is + that a UUID is 16 octets, and that some bits of octet 8 of the UUID + called the variant field (specified in the next section) determine + finer structure. + + +3.1.1 Variant + The variant field determines the layout of the UUID. That is, the + interpretation of all other bits in the UUID depends on the setting + of the bits in the variant field. The variant field consists of a + variable number of the msbs of octet 8 of the UUID. + + The following table lists the contents of the variant field. + + Msb0 Msb1 Msb2 Description + + 0 - - Reserved, NCS backward compatibility. + + 1 0 - The variant specified in this document. + + 1 1 0 Reserved, Microsoft Corporation backward + compatibility + + 1 1 1 Reserved for future definition. + + + + Other UUID variants may not interoperate with the UUID variant + specified in this document, where interoperability is defined as the + applicability of operations such as string conversion and lexical + ordering across different systems. However, UUIDs allocated according + to the stricture of different variants, though they may define + different interpretations of the bits outside the variant field, will + not result in duplicate UUID allocation, because of the differing + values of the variant field itself. + + The remaining fields described below (version, timestamp, etc.) are + defined only for the UUID variant noted above. + + + Leach, Salz expires Aug 1998 [Page 4] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + +3.1.2 UUID layout + The following table gives the format of a UUID for the variant + specified herein. The UUID consists of a record of 16 octets. To + minimize confusion about bit assignments within octets, the UUID + record definition is defined only in terms of fields that are + integral numbers of octets. The fields are in order of significance + for comparison purposes, with "time_low" the most significant, and + "node" the least significant. + + Field Data Type Octet Note + # + + time_low unsigned 32 0-3 The low field of the + bit integer timestamp. + + time_mid unsigned 16 4-5 The middle field of the + bit integer timestamp. + + time_hi_and_version unsigned 16 6-7 The high field of the + bit integer timestamp multiplexed + with the version number. + + clock_seq_hi_and_rese unsigned 8 8 The high field of the + rved bit integer clock sequence + multiplexed with the + variant. + + clock_seq_low unsigned 8 9 The low field of the + bit integer clock sequence. + + node unsigned 48 10-15 The spatially unique + bit integer node identifier. + + + + +3.1.3 Version + The version number is in the most significant 4 bits of the time + stamp (time_hi_and_version). + + The following table lists currently defined versions of the UUID. + + Msb0 Msb1 Msb2 Msb3 Version Description + + 0 0 0 1 1 The time-based version + specified in this + document. + + 0 0 1 0 2 Reserved for DCE + Security version, with + embedded POSIX UIDs. + + 0 0 1 1 3 The name-based version + specified in this + + Leach, Salz expires Aug 1998 [Page 5] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + document + + 0 1 0 0 4 The randomly or pseudo- + randomly generated + version specified in + this document + + +3.1.4 Timestamp + The timestamp is a 60 bit value. For UUID version 1, this is + represented by Coordinated Universal Time (UTC) as a count of 100- + nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of + Gregorian reform to the Christian calendar). + + For systems that do not have UTC available, but do have local time, + they MAY use local time instead of UTC, as long as they do so + consistently throughout the system. This is NOT RECOMMENDED, however, + and it should be noted that all that is needed to generate UTC, given + local time, is a time zone offset. + + For UUID version 3, it is a 60 bit value constructed from a name. + + For UUID version 4, it is a randomly or pseudo-randomly generated 60 + bit value. + + +3.1.5 Clock sequence + For UUID version 1, the clock sequence is used to help avoid + duplicates that could arise when the clock is set backwards in time + or if the node ID changes. + + If the clock is set backwards, or even might have been set backwards + (e.g., while the system was powered off), and the UUID generator can + not be sure that no UUIDs were generated with timestamps larger than + the value to which the clock was set, then the clock sequence has to + be changed. If the previous value of the clock sequence is known, it + can be just incremented; otherwise it should be set to a random or + high-quality pseudo random value. + + Similarly, if the node ID changes (e.g. because a network card has + been moved between machines), setting the clock sequence to a random + number minimizes the probability of a duplicate due to slight + differences in the clock settings of the machines. (If the value of + clock sequence associated with the changed node ID were known, then + the clock sequence could just be incremented, but that is unlikely.) + + The clock sequence MUST be originally (i.e., once in the lifetime of + a system) initialized to a random number to minimize the correlation + across systems. This provides maximum protection against node + identifiers that may move or switch from system to system rapidly. + The initial value MUST NOT be correlated to the node identifier. + + For UUID version 3, it is a 14 bit value constructed from a name. + + + Leach, Salz expires Aug 1998 [Page 6] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + For UUID version 4, it is a randomly or pseudo-randomly generated 14 + bit value. + + +3.1.6 Node + For UUID version 1, the node field consists of the IEEE address, + usually the host address. For systems with multiple IEEE 802 + addresses, any available address can be used. The lowest addressed + octet (octet number 10) contains the global/local bit and the + unicast/multicast bit, and is the first octet of the address + transmitted on an 802.3 LAN. + + For systems with no IEEE address, a randomly or pseudo-randomly + generated value may be used (see section 4). The multicast bit must + be set in such addresses, in order that they will never conflict with + addresses obtained from network cards. + + For UUID version 3, the node field is a 48 bit value constructed from + a name. + + For UUID version 4, the node field is a randomly or pseudo-randomly + generated 48 bit value. + + +3.1.7 Nil UUID + The nil UUID is special form of UUID that is specified to have all + 128 bits set to 0 (zero). + + +3.2 Algorithms for creating a time-based UUID + + Various aspects of the algorithm for creating a version 1 UUID are + discussed in the following sections. UUID generation requires a + guarantee of uniqueness within the node ID for a given variant and + version. Interoperability is provided by complying with the specified + data structure. + + +3.2.1 Basic algorithm + The following algorithm is simple, correct, and inefficient: + + . Obtain a system wide global lock + + . From a system wide shared stable store (e.g., a file), read the + UUID generator state: the values of the time stamp, clock sequence, + and node ID used to generate the last UUID. + + . Get the current time as a 60 bit count of 100-nanosecond intervals + since 00:00:00.00, 15 October 1582 + + . Get the current node ID + + + + + Leach, Salz expires Aug 1998 [Page 7] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + . If the state was unavailable (non-existent or corrupted), or the + saved node ID is different than the current node ID, generate a + random clock sequence value + + . If the state was available, but the saved time stamp is later than + the current time stamp, increment the clock sequence value + + . Format a UUID from the current time stamp, clock sequence, and node + ID values according to the structure in section 3.1 (see section + 3.2.6 for more details) + + . Save the state (current time stamp, clock sequence, and node ID) + back to the stable store + + . Release the system wide global lock + + If UUIDs do not need to be frequently generated, the above algorithm + may be perfectly adequate. For higher performance requirements, + however, issues with the basic algorithm include: + + . Reading the state from stable storage each time is inefficient + + . The resolution of the system clock may not be 100-nanoseconds + + . Writing the state to stable storage each time is inefficient + + . Sharing the state across process boundaries may be inefficient + + Each of these issues can be addressed in a modular fashion by local + improvements in the functions that read and write the state and read + the clock. We address each of them in turn in the following sections. + + +3.2.2 Reading stable storage + The state only needs to be read from stable storage once at boot + time, if it is read into a system wide shared volatile store (and + updated whenever the stable store is updated). + + If an implementation does not have any stable store available, then + it can always say that the values were unavailable. This is the least + desirable implementation, because it will increase the frequency of + creation of new clock sequence numbers, which increases the + probability of duplicates. + + If the node ID can never change (e.g., the net card is inseparable + from the system), or if any change also reinitializes the clock + sequence to a random value, then instead of keeping it in stable + store, the current node ID may be returned. + + +3.2.3 System clock resolution + The time stamp is generated from the system time, whose resolution + may be less than the resolution of the UUID time stamp. + + + Leach, Salz expires Aug 1998 [Page 8] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + If UUIDs do not need to be frequently generated, the time stamp can + simply be the system time multiplied by the number of 100-nanosecond + intervals per system time interval. + + If a system overruns the generator by requesting too many UUIDs + within a single system time interval, the UUID service MUST either: + return an error, or stall the UUID generator until the system clock + catches up. + + A high resolution time stamp can be simulated by keeping a count of + how many UUIDs have been generated with the same value of the system + time, and using it to construction the low-order bits of the time + stamp. The count will range between zero and the number of 100- + nanosecond intervals per system time interval. + + Note: if the processors overrun the UUID generation frequently, + additional node identifiers can be allocated to the system, which + will permit higher speed allocation by making multiple UUIDs + potentially available for each time stamp value. + + +3.2.4 Writing stable storage + The state does not always need to be written to stable store every + time a UUID is generated. The timestamp in the stable store can be + periodically set to a value larger than any yet used in a UUID; as + long as the generated UUIDs have time stamps less than that value, + and the clock sequence and node ID remain unchanged, only the shared + volatile copy of the state needs to be updated. Furthermore, if the + time stamp value in stable store is in the future by less than the + typical time it takes the system to reboot, a crash will not cause a + reinitialization of the clock sequence. + + +3.2.5 Sharing state across processes + If it is too expensive to access shared state each time a UUID is + generated, then the system wide generator can be implemented to + allocate a block of time stamps each time it is called, and a per- + process generator can allocate from that block until it is exhausted. + + +3.2.6 UUID Generation details + UUIDs are generated according to the following algorithm: + + - Determine the values for the UTC-based timestamp and clock sequence + to be used in the UUID, as described above. + + - For the purposes of this algorithm, consider the timestamp to be a + 60-bit unsigned integer and the clock sequence to be a 14-bit + unsigned integer. Sequentially number the bits in a field, starting + from 0 (zero) for the least significant bit. + + - Set the time_low field equal to the least significant 32-bits (bits + numbered 0 to 31 inclusive) of the time stamp in the same order of + significance. + + Leach, Salz expires Aug 1998 [Page 9] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + - Set the time_mid field equal to the bits numbered 32 to 47 + inclusive of the time stamp in the same order of significance. + + - Set the 12 least significant bits (bits numbered 0 to 11 inclusive) + of the time_hi_and_version field equal to the bits numbered 48 to 59 + inclusive of the time stamp in the same order of significance. + + - Set the 4 most significant bits (bits numbered 12 to 15 inclusive) + of the time_hi_and_version field to the 4-bit version number + corresponding to the UUID version being created, as shown in the + table in section 3.1.3. + + - Set the clock_seq_low field to the 8 least significant bits (bits + numbered 0 to 7 inclusive) of the clock sequence in the same order of + significance. + + - Set the 6 least significant bits (bits numbered 0 to 5 inclusive) + of the clock_seq_hi_and_reserved field to the 6 most significant bits + (bits numbered 8 to 13 inclusive) of the clock sequence in the same + order of significance. + + - Set the 2 most significant bits (bits numbered 6 and 7) of the + clock_seq_hi_and_reserved to 0 and 1, respectively. + + - Set the node field to the 48-bit IEEE address in the same order of + significance as the address. + + +3.3 Algorithm for creating a name-based UUID + + The version 3 UUID is meant for generating UUIDs from "names" that + are drawn from, and unique within, some "name space". Some examples + of names (and, implicitly, name spaces) might be DNS names, URLs, ISO + Object IDs (OIDs), reserved words in a programming language, or X.500 + Distinguished Names (DNs); thus, the concept of name and name space + should be broadly construed, and not limited to textual names. The + mechanisms or conventions for allocating names from, and ensuring + their uniqueness within, their name spaces are beyond the scope of + this specification. + + The requirements for such UUIDs are as follows: + + . The UUIDs generated at different times from the same name in the + same namespace MUST be equal + + . The UUIDs generated from two different names in the same namespace + should be different (with very high probability) + + . The UUIDs generated from the same name in two different namespaces + should be different with (very high probability) + + . If two UUIDs that were generated from names are equal, then they + were generated from the same name in the same namespace (with very + high probability). + + Leach, Salz expires Aug 1998 [Page 10] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + The algorithm for generating the a UUID from a name and a name space + are as follows: + + . Allocate a UUID to use as a "name space ID" for all UUIDs generated + from names in that name space + + . Convert the name to a canonical sequence of octets (as defined by + the standards or conventions of its name space); put the name space + ID in network byte order + + . Compute the MD5 [3] hash of the name space ID concatenated with the + name + + . Set octets 0-3 of time_low field to octets 0-3 of the MD5 hash + + . Set octets 0-1 of time_mid field to octets 4-5 of the MD5 hash + + . Set octets 0-1 of time_hi_and_version field to octets 6-7 of the + MD5 hash + + . Set the clock_seq_hi_and_reserved field to octet 8 of the MD5 hash + + . Set the clock_seq_low field to octet 9 of the MD5 hash + + . Set octets 0-5 of the node field to octets 10-15 of the MD5 hash + + . Set the 2 most significant bits (bits numbered 6 and 7) of the + clock_seq_hi_and_reserved to 0 and 1, respectively. + + . Set the 4 most significant bits (bits numbered 12 to 15 inclusive) + of the time_hi_and_version field to the 4-bit version number + corresponding to the UUID version being created, as shown in the + table above. + + . Convert the resulting UUID to local byte order. + + +3.4 Algorithms for creating a UUID from truly random or pseudo-random +numbers + + The version 4 UUID is meant for generating UUIDs from truly-random or + pseudo-random numbers. + + The algorithm is as follows: + + . Set the 2 most significant bits (bits numbered 6 and 7) of the + clock_seq_hi_and_reserved to 0 and 1, respectively. + + . Set the 4 most significant bits (bits numbered 12 to 15 inclusive) + of the time_hi_and_version field to the 4-bit version number + corresponding to the UUID version being created, as shown in the + table above. + + + + Leach, Salz expires Aug 1998 [Page 11] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + . Set all the other bits to randomly (or pseudo-randomly) chosen + values. + + Here are several possible ways to generate the random values: + + . Use a physical source of randomness: for example, a white noise + generator, radioactive decay, or a lava lamp. + + . Use a cryptographic strength random number generator. + + +3.5 String Representation of UUIDs + + For use in human readable text, a UUID string representation is + specified as a sequence of fields, some of which are separated by + single dashes. + + Each field is treated as an integer and has its value printed as a + zero-filled hexadecimal digit string with the most significant digit + first. The hexadecimal values a to f inclusive are output as lower + case characters, and are case insensitive on input. The sequence is + the same as the UUID constructed type. + + The formal definition of the UUID string representation is provided + by the following extended BNF: + + UUID = <time_low> "-" <time_mid> "-" + <time_high_and_version> "-" + <clock_seq_and_reserved> + <clock_seq_low> "-" <node> + time_low = 4*<hexOctet> + time_mid = 2*<hexOctet> + time_high_and_version = 2*<hexOctet> + clock_seq_and_reserved = <hexOctet> + clock_seq_low = <hexOctet> + node = 6*<hexOctet + hexOctet = <hexDigit> <hexDigit> + hexDigit = + "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + | "a" | "b" | "c" | "d" | "e" | "f" + | "A" | "B" | "C" | "D" | "E" | "F" + + The following is an example of the string representation of a UUID: + + f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + +3.6 Comparing UUIDs for equality + + Consider each field of the UUID to be an unsigned integer as shown in + the table in section 3.1. Then, to compare a pair of UUIDs, + arithmetically compare the corresponding fields from each UUID in + order of significance and according to their data type. Two UUIDs are + equal if and only if all the corresponding fields are equal. + + + Leach, Salz expires Aug 1998 [Page 12] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + Note: as a practical matter, on many systems comparison of two UUIDs + for equality can be performed simply by comparing the 128 bits of + their in-memory representation considered as a 128 bit unsigned + integer. Here, it is presumed that by the time the in-memory + representation is obtained the appropriate byte-order + canonicalizations have been carried out. + + +3.7 Comparing UUIDs for relative order + + Two UUIDs allocated according to the same variant can also be ordered + lexicographically. For the UUID variant herein defined, the first of + two UUIDs follows the second if the most significant field in which + the UUIDs differ is greater for the first UUID. The first of a pair + of UUIDs precedes the second if the most significant field in which + the UUIDs differ is greater for the second UUID. + + +3.8 Byte order of UUIDs + + UUIDs may be transmitted in many different forms, some of which may + be dependent on the presentation or application protocol where the + UUID may be used. In such cases, the order, sizes and byte orders of + the UUIDs fields on the wire will depend on the relevant presentation + or application protocol. However, it is strongly RECOMMENDED that + the order of the fields conform with ordering set out in section 3.1 + above. Furthermore, the payload size of each field in the application + or presentation protocol MUST be large enough that no information + lost in the process of encoding them for transmission. + + In the absence of explicit application or presentation protocol + specification to the contrary, a UUID is encoded as a 128-bit object, + as follows: the fields are encoded as 16 octets, with the sizes and + order of the fields defined in section 3.1, and with each field + encoded with the Most Significant Byte first (also known as network + byte order). + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_low | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_mid | time_hi_and_version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |clk_seq_hi_res | clk_seq_low | node (0-1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | node (2-5) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + + + + + + Leach, Salz expires Aug 1998 [Page 13] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + +4. Node IDs when no IEEE 802 network card is available + + If a system wants to generate UUIDs but has no IEE 802 compliant + network card or other source of IEEE 802 addresses, then this section + describes how to generate one. + + 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. + + If a system does not have a primitive to generate cryptographic + quality random numbers, then in most systems there are usually a + fairly large number of sources of randomness available from which one + can be generated. Such sources are system specific, but often + include: + + - the percent of memory in use + - the size of main memory in bytes + - the amount of free main memory in bytes + - the size of the paging or swap file in bytes + - free bytes of paging or swap file + - the total size of user virtual address space in bytes + - the total available user address space bytes + - the size of boot disk drive in bytes + - the free disk space on boot drive in bytes + - the current time + - the amount of time since the system booted + - the individual sizes of files in various system directories + - the creation, last read, and modification times of files in various + system directories + - the utilization factors of various system resources (heap, etc.) + - current mouse cursor position + - current caret position + - current number of running processes, threads + - handles or IDs of the desktop window and the active window + - the value of stack pointer of the caller + - the process and thread ID of caller + - various processor architecture specific performance counters + (instructions executed, cache misses, TLB misses) + + (Note that it precisely the above kinds of sources of randomness that + are used to seed cryptographic quality random number generators on + systems without special hardware for their construction.) + + In addition, items such as the computer's name and the name of the + operating system, while not strictly speaking random, will help + differentiate the results from those obtained by other systems. + + The exact algorithm to generate a node ID using these data is system + specific, because both the data available and the functions to obtain + + Leach, Salz expires Aug 1998 [Page 14] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + them are often very system specific. However, assuming that one can + concatenate all the values from the randomness sources into a buffer, + and that a cryptographic hash function such as MD5 [3] is available, + then any 6 bytes of the MD5 hash of the buffer, with the multicast + bit (the high bit of the first byte) set will be an appropriately + random node ID. + + Other hash functions, such as SHA-1 [4], can also be used. The only + requirement is that the result be suitably random _ in the sense that + the outputs from a set uniformly distributed inputs are themselves + uniformly distributed, and that a single bit change in the input can + be expected to cause half of the output bits to change. + + +5. Obtaining IEEE 802 addresses + + At the time of writing, the following URL + + http://standards.ieee.org/db/oui/forms/ + + contains information on how to obtain an IEEE 802 address block. At + the time of writing, the cost is $1250 US. + + +6. Security Considerations + + It should not be assumed that UUIDs are hard to guess; they should + not be used as capabilities. + + +7. Acknowledgements + + This document draws heavily on the OSF DCE specification for UUIDs. + Ted Ts'o provided helpful comments, especially on the byte ordering + section which we mostly plagiarized from a proposed wording he + supplied (all errors in that section are our responsibility, + however). + + +8. References + + [1] Lisa Zahn, et. al., Network Computing Architecture, Prentice + Hall, Englewood Cliffs, NJ, 1990 + + [2] DCE: Remote Procedure Call, Open Group CAE Specification C309 + ISBN 1-85912-041-5 28cm. 674p. pbk. 1,655g. 8/94 + + [3] R. Rivest, RFC 1321, "The MD5 Message-Digest Algorithm", + 04/16/1992. + + [4] NIST FIPS PUB 180-1, "Secure Hash Standard," National Institute + of Standards and Technology, U.S. Department of Commerce, DRAFT, May + 31, 1994. + + + Leach, Salz expires Aug 1998 [Page 15] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + +9. Authors' addresses + + Paul J. Leach + Microsoft + 1 Microsoft Way + Redmond, WA, 98052, U.S.A. + paulle@microsoft.com + Tel. 425 882 8080 + Fax. 425 936 7329 + + Rich Salz + 100 Cambridge Park Drive + Cambridge MA 02140 + salzr@certco.com + Tel. 617 499 4075 + Fax. 617 576 0019 + + +10. Notice + + The IETF takes no position regarding the validity or scope of any + intellectual property or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; neither does it represent that it + has made any effort to identify any such rights. Information on the + IETF's procedures with respect to rights in standards-track and + standards-related documentation can be found in BCP-11. Copies of + claims of rights made available for publication and any assurances of + licenses to be made available, or the result of an attempt made to + obtain a general license or permission for the use of such + proprietary rights by implementors or users of this specification can + be obtained from the IETF Secretariat. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights which may cover technology that may be required to practice + this standard. Please address the information to the IETF Executive + Director. + + +11. Full Copyright Statement + + Copyright (C) The Internet Society 1997. All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + + Leach, Salz expires Aug 1998 [Page 16] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + Appendix A _ UUID Sample Implementation + + This implementation consists of 5 files: uuid.h, uuid.c, sysdep.h, + sysdep.c and utest.c. The uuid.* files are the system independent + implementation of the UUID generation algorithms described above, + with all the optimizations described above except efficient state + sharing across processes included. The code has been tested on Linux + (Red Hat 4.0) with GCC (2.7.2), and Windows NT 4.0 with VC++ 5.0. The + code assumes 64 bit integer support, which makes it a lot clearer. + + All the following source files should be considered to have the + following copyright notice included: + + copyrt.h + + /* + ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. + ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & + ** Digital Equipment Corporation, Maynard, Mass. + ** Copyright (c) 1998 Microsoft. + ** To anyone who acknowledges that this file is provided "AS IS" + ** without any express or implied warranty: permission to use, copy, + ** modify, and distribute this file for any purpose is hereby + ** granted without fee, provided that the above copyright notices and + ** this notice appears in all source code copies, and that none of + ** the names of Open Software Foundation, Inc., Hewlett-Packard + ** Company, or Digital Equipment Corporation be used in advertising + ** or publicity pertaining to distribution of the software without + ** specific, written prior permission. Neither Open Software + ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital + Equipment + ** Corporation makes any representations about the suitability of + ** this software for any purpose. + */ + + + uuid.h + + + Leach, Salz expires Aug 1998 [Page 17] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + #include "copyrt.h" + #undef uuid_t + typedef struct _uuid_t { + unsigned32 time_low; + unsigned16 time_mid; + unsigned16 time_hi_and_version; + unsigned8 clock_seq_hi_and_reserved; + unsigned8 clock_seq_low; + byte node[6]; + } uuid_t; + + /* uuid_create -- generate a UUID */ + int uuid_create(uuid_t * uuid); + + /* uuid_create_from_name -- create a UUID using a "name" + from a "name space" */ + void uuid_create_from_name( + uuid_t * uuid, /* resulting UUID */ + uuid_t nsid, /* UUID to serve as context, so identical + names from different name spaces generate + different UUIDs */ + void * name, /* the name from which to generate a UUID */ + int namelen /* the length of the name */ + ); + + /* uuid_compare -- Compare two UUID's "lexically" and return + -1 u1 is lexically before u2 + 0 u1 is equal to u2 + 1 u1 is lexically after u2 + Note: lexical ordering is not temporal ordering! + */ + int uuid_compare(uuid_t *u1, uuid_t *u2); + + uuid.c + + #include "copyrt.h" + #include <string.h> + #include <stdio.h> + #include <stdlib.h> + #include <time.h> + #include "sysdep.h" + #include "uuid.h" + + /* various forward declarations */ + static int read_state(unsigned16 *clockseq, uuid_time_t *timestamp, + uuid_node_t * node); + static void write_state(unsigned16 clockseq, uuid_time_t timestamp, + uuid_node_t node); + static void format_uuid_v1(uuid_t * uuid, unsigned16 clockseq, + uuid_time_t timestamp, uuid_node_t node); + static void format_uuid_v3(uuid_t * uuid, unsigned char hash[16]); + static void get_current_time(uuid_time_t * timestamp); + static unsigned16 true_random(void); + + + Leach, Salz expires Aug 1998 [Page 18] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + /* uuid_create -- generator a UUID */ + int uuid_create(uuid_t * uuid) { + uuid_time_t timestamp, last_time; + unsigned16 clockseq; + uuid_node_t node; + uuid_node_t last_node; + int f; + + /* acquire system wide lock so we're alone */ + LOCK; + + /* get current time */ + get_current_time(×tamp); + + /* get node ID */ + get_ieee_node_identifier(&node); + + /* get saved state from NV storage */ + f = read_state(&clockseq, &last_time, &last_node); + + /* if no NV state, or if clock went backwards, or node ID changed + (e.g., net card swap) change clockseq */ + if (!f || memcmp(&node, &last_node, sizeof(uuid_node_t))) + clockseq = true_random(); + else if (timestamp < last_time) + clockseq++; + + /* stuff fields into the UUID */ + format_uuid_v1(uuid, clockseq, timestamp, node); + + /* save the state for next time */ + write_state(clockseq, timestamp, node); + + UNLOCK; + return(1); + }; + + /* format_uuid_v1 -- make a UUID from the timestamp, clockseq, + and node ID */ + void format_uuid_v1(uuid_t * uuid, unsigned16 clock_seq, uuid_time_t + timestamp, uuid_node_t node) { + /* Construct a version 1 uuid with the information we've gathered + * plus a few constants. */ + uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF); + uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF); + uuid->time_hi_and_version = (unsigned short)((timestamp >> 48) & + 0x0FFF); + uuid->time_hi_and_version |= (1 << 12); + uuid->clock_seq_low = clock_seq & 0xFF; + uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; + uuid->clock_seq_hi_and_reserved |= 0x80; + memcpy(&uuid->node, &node, sizeof uuid->node); + }; + + + Leach, Salz expires Aug 1998 [Page 19] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + /* data type for UUID generator persistent state */ + typedef struct { + uuid_time_t ts; /* saved timestamp */ + uuid_node_t node; /* saved node ID */ + unsigned16 cs; /* saved clock sequence */ + } uuid_state; + + static uuid_state st; + + /* read_state -- read UUID generator state from non-volatile store */ + int read_state(unsigned16 *clockseq, uuid_time_t *timestamp, + uuid_node_t *node) { + FILE * fd; + static int inited = 0; + + /* only need to read state once per boot */ + if (!inited) { + fd = fopen("state", "rb"); + if (!fd) + return (0); + fread(&st, sizeof(uuid_state), 1, fd); + fclose(fd); + inited = 1; + }; + *clockseq = st.cs; + *timestamp = st.ts; + *node = st.node; + return(1); + }; + + /* write_state -- save UUID generator state back to non-volatile + storage */ + void write_state(unsigned16 clockseq, uuid_time_t timestamp, + uuid_node_t node) { + FILE * fd; + static int inited = 0; + static uuid_time_t next_save; + + if (!inited) { + next_save = timestamp; + inited = 1; + }; + /* always save state to volatile shared state */ + st.cs = clockseq; + st.ts = timestamp; + st.node = node; + if (timestamp >= next_save) { + fd = fopen("state", "wb"); + fwrite(&st, sizeof(uuid_state), 1, fd); + fclose(fd); + /* schedule next save for 10 seconds from now */ + next_save = timestamp + (10 * 10 * 1000 * 1000); + }; + }; + + Leach, Salz expires Aug 1998 [Page 20] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + + /* get-current_time -- get time as 60 bit 100ns ticks since whenever. + Compensate for the fact that real clock resolution is + less than 100ns. */ + void get_current_time(uuid_time_t * timestamp) { + uuid_time_t time_now; + static uuid_time_t time_last; + static unsigned16 uuids_this_tick; + static int inited = 0; + + if (!inited) { + get_system_time(&time_now); + uuids_this_tick = UUIDS_PER_TICK; + inited = 1; + }; + + while (1) { + get_system_time(&time_now); + + /* if clock reading changed since last UUID generated... */ + if (time_last != time_now) { + /* reset count of uuids gen'd with this clock reading */ + uuids_this_tick = 0; + break; + }; + if (uuids_this_tick < UUIDS_PER_TICK) { + uuids_this_tick++; + break; + }; + /* going too fast for our clock; spin */ + }; + /* add the count of uuids to low order bits of the clock reading */ + *timestamp = time_now + uuids_this_tick; + }; + + /* true_random -- generate a crypto-quality random number. + This sample doesn't do that. */ + static unsigned16 + true_random(void) + { + static int inited = 0; + uuid_time_t time_now; + + if (!inited) { + get_system_time(&time_now); + time_now = time_now/UUIDS_PER_TICK; + srand((unsigned int)(((time_now >> 32) ^ time_now)&0xffffffff)); + inited = 1; + }; + + return (rand()); + } + + + + Leach, Salz expires Aug 1998 [Page 21] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + /* uuid_create_from_name -- create a UUID using a "name" from a "name + space" */ + void uuid_create_from_name( + uuid_t * uuid, /* resulting UUID */ + uuid_t nsid, /* UUID to serve as context, so identical + names from different name spaces generate + different UUIDs */ + void * name, /* the name from which to generate a UUID */ + int namelen /* the length of the name */ + ) { + MD5_CTX c; + unsigned char hash[16]; + uuid_t net_nsid; /* context UUID in network byte order */ + + /* put name space ID in network byte order so it hashes the same + no matter what endian machine we're on */ + net_nsid = nsid; + htonl(net_nsid.time_low); + htons(net_nsid.time_mid); + htons(net_nsid.time_hi_and_version); + + MD5Init(&c); + MD5Update(&c, &net_nsid, sizeof(uuid_t)); + MD5Update(&c, name, namelen); + MD5Final(hash, &c); + + /* the hash is in network byte order at this point */ + format_uuid_v3(uuid, hash); + }; + + /* format_uuid_v3 -- make a UUID from a (pseudo)random 128 bit number + */ + void format_uuid_v3(uuid_t * uuid, unsigned char hash[16]) { + /* Construct a version 3 uuid with the (pseudo-)random number + * plus a few constants. */ + + memcpy(uuid, hash, sizeof(uuid_t)); + + /* convert UUID to local byte order */ + ntohl(uuid->time_low); + ntohs(uuid->time_mid); + ntohs(uuid->time_hi_and_version); + + /* put in the variant and version bits */ + uuid->time_hi_and_version &= 0x0FFF; + uuid->time_hi_and_version |= (3 << 12); + uuid->clock_seq_hi_and_reserved &= 0x3F; + uuid->clock_seq_hi_and_reserved |= 0x80; + }; + + /* uuid_compare -- Compare two UUID's "lexically" and return + -1 u1 is lexically before u2 + 0 u1 is equal to u2 + 1 u1 is lexically after u2 + + Leach, Salz expires Aug 1998 [Page 22] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + Note: lexical ordering is not temporal ordering! + */ + int uuid_compare(uuid_t *u1, uuid_t *u2) + { + int i; + + #define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1; + CHECK(u1->time_low, u2->time_low); + CHECK(u1->time_mid, u2->time_mid); + CHECK(u1->time_hi_and_version, u2->time_hi_and_version); + CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved); + CHECK(u1->clock_seq_low, u2->clock_seq_low) + for (i = 0; i < 6; i++) { + if (u1->node[i] < u2->node[i]) + return -1; + if (u1->node[i] > u2->node[i]) + return 1; + } + return 0; + }; + + sysdep.h + + #include "copyrt.h" + /* remove the following define if you aren't running WIN32 */ + #define WININC 0 + + #ifdef WININC + #include <windows.h> + #else + #include <sys/types.h> + #include <sys/time.h> + #include <sys/sysinfo.h> + #endif + + /* change to point to where MD5 .h's live */ + /* get MD5 sample implementation from RFC 1321 */ + #include "global.h" + #include "md5.h" + + /* set the following to the number of 100ns ticks of the actual + resolution of + your system's clock */ + #define UUIDS_PER_TICK 1024 + + /* Set the following to a call to acquire a system wide global lock + */ + #define LOCK + #define UNLOCK + + typedef unsigned long unsigned32; + typedef unsigned short unsigned16; + typedef unsigned char unsigned8; + typedef unsigned char byte; + + Leach, Salz expires Aug 1998 [Page 23] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + + /* Set this to what your compiler uses for 64 bit data type */ + #ifdef WININC + #define unsigned64_t unsigned __int64 + #define I64(C) C + #else + #define unsigned64_t unsigned long long + #define I64(C) C##LL + #endif + + + typedef unsigned64_t uuid_time_t; + typedef struct { + char nodeID[6]; + } uuid_node_t; + + void get_ieee_node_identifier(uuid_node_t *node); + void get_system_time(uuid_time_t *uuid_time); + void get_random_info(char seed[16]); + + + sysdep.c + + #include "copyrt.h" + #include <stdio.h> + #include "sysdep.h" + + /* system dependent call to get IEEE node ID. + This sample implementation generates a random node ID + */ + void get_ieee_node_identifier(uuid_node_t *node) { + char seed[16]; + FILE * fd; + static inited = 0; + static uuid_node_t saved_node; + + if (!inited) { + fd = fopen("nodeid", "rb"); + if (fd) { + fread(&saved_node, sizeof(uuid_node_t), 1, fd); + fclose(fd); + } + else { + get_random_info(seed); + seed[0] |= 0x80; + memcpy(&saved_node, seed, sizeof(uuid_node_t)); + fd = fopen("nodeid", "wb"); + if (fd) { + fwrite(&saved_node, sizeof(uuid_node_t), 1, fd); + fclose(fd); + }; + }; + inited = 1; + }; + + Leach, Salz expires Aug 1998 [Page 24] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + *node = saved_node; + }; + + /* system dependent call to get the current system time. + Returned as 100ns ticks since Oct 15, 1582, but resolution may be + less than 100ns. + */ + #ifdef _WINDOWS_ + + void get_system_time(uuid_time_t *uuid_time) { + ULARGE_INTEGER time; + + GetSystemTimeAsFileTime((FILETIME *)&time); + + /* NT keeps time in FILETIME format which is 100ns ticks since + Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. + The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) + + 18 years and 5 leap days. + */ + + time.QuadPart += + (unsigned __int64) (1000*1000*10) // seconds + * (unsigned __int64) (60 * 60 * 24) // days + * (unsigned __int64) (17+30+31+365*18+5); // # of days + + *uuid_time = time.QuadPart; + + }; + + void get_random_info(char seed[16]) { + MD5_CTX c; + typedef struct { + MEMORYSTATUS m; + SYSTEM_INFO s; + FILETIME t; + LARGE_INTEGER pc; + DWORD tc; + DWORD l; + char hostname[MAX_COMPUTERNAME_LENGTH + 1]; + } randomness; + randomness r; + + MD5Init(&c); + /* memory usage stats */ + GlobalMemoryStatus(&r.m); + /* random system stats */ + GetSystemInfo(&r.s); + /* 100ns resolution (nominally) time of day */ + GetSystemTimeAsFileTime(&r.t); + /* high resolution performance counter */ + QueryPerformanceCounter(&r.pc); + /* milliseconds since last boot */ + r.tc = GetTickCount(); + r.l = MAX_COMPUTERNAME_LENGTH + 1; + + Leach, Salz expires Aug 1998 [Page 25] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + GetComputerName(r.hostname, &r.l ); + MD5Update(&c, &r, sizeof(randomness)); + MD5Final(seed, &c); + }; + #else + + void get_system_time(uuid_time_t *uuid_time) + { + struct timeval tp; + + gettimeofday(&tp, (struct timezone *)0); + + /* Offset between UUID formatted times and Unix formatted times. + UUID UTC base time is October 15, 1582. + Unix base time is January 1, 1970. + */ + *uuid_time = (tp.tv_sec * 10000000) + (tp.tv_usec * 10) + + I64(0x01B21DD213814000); + }; + + void get_random_info(char seed[16]) { + MD5_CTX c; + typedef struct { + struct sysinfo s; + struct timeval t; + char hostname[257]; + } randomness; + randomness r; + + MD5Init(&c); + sysinfo(&r.s); + gettimeofday(&r.t, (struct timezone *)0); + gethostname(r.hostname, 256); + MD5Update(&c, &r, sizeof(randomness)); + MD5Final(seed, &c); + }; + + #endif + + utest.c + + #include "copyrt.h" + #include "sysdep.h" + #include <stdio.h> + #include "uuid.h" + + uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b810, + 0x9dad, + 0x11d1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + }; + + + + Leach, Salz expires Aug 1998 [Page 26] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + /* puid -- print a UUID */ + void puid(uuid_t u); + + /* Simple driver for UUID generator */ + void main(int argc, char **argv) { + uuid_t u; + int f; + + uuid_create(&u); + printf("uuid_create() -> "); puid(u); + + f = uuid_compare(&u, &u); + printf("uuid_compare(u,u): %d\n", f); /* should be 0 */ + f = uuid_compare(&u, &NameSpace_DNS); + printf("uuid_compare(u, NameSpace_DNS): %d\n", f); /* s.b. 1 */ + f = uuid_compare(&NameSpace_DNS, &u); + printf("uuid_compare(NameSpace_DNS, u): %d\n", f); /* s.b. -1 */ + + uuid_create_from_name(&u, NameSpace_DNS, "www.widgets.com", 15); + printf("uuid_create_from_name() -> "); puid(u); + }; + + void puid(uuid_t u) { + int i; + + printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, + u.time_hi_and_version, u.clock_seq_hi_and_reserved, + u.clock_seq_low); + for (i = 0; i < 6; i++) + printf("%2.2x", u.node[i]); + printf("\n"); + }; + +Appendix B _ Sample output of utest + + uuid_create() -> 7d444840-9dc0-11d1-b245-5ffdce74fad2 + uuid_compare(u,u): 0 + uuid_compare(u, NameSpace_DNS): 1 + uuid_compare(NameSpace_DNS, u): -1 + uuid_create_from_name() -> e902893a-9d22-3c7e-a7b8-d6e313b71d9f + +Appendix C _ Some name space IDs + + This appendix lists the name space IDs for some potentially + interesting name spaces, as initialized C structures and in the + string representation defined in section 3.5 + + uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b810, + 0x9dad, + 0x11d1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + }; + + + Leach, Salz expires Aug 1998 [Page 27] + + + Internet-Draft UUIDs and GUIDs (DRAFT) 02/04/98 + + + uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b811, + 0x9dad, + 0x11d1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + }; + + uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b812, + 0x9dad, + 0x11d1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + }; + + uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */ + 0x6ba7b814, + 0x9dad, + 0x11d1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 + }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + |