diff --git a/configure b/configure index 17f3f26..46853e8 100755 --- a/configure +++ b/configure @@ -657,7 +657,6 @@ acx_pthread_config have_win32_dbghelp HAVE_IPV6 LIBOBJS -OSSP_UUID_LIBS ZIC python_enable_shared python_additional_libs @@ -705,7 +704,7 @@ with_system_tzdata with_libxslt with_libxml XML2_CONFIG -with_ossp_uuid +with_uuid with_selinux with_openssl krb_srvtab @@ -826,7 +825,7 @@ with_openssl with_selinux with_readline with_libedit_preferred -with_ossp_uuid +with_uuid with_libxml with_libxslt with_system_tzdata @@ -1512,7 +1511,8 @@ Optional Packages: --without-readline do not use GNU Readline nor BSD Libedit for editing --with-libedit-preferred prefer BSD Libedit over GNU Readline - --with-ossp-uuid build contrib/uuid-ossp, requires OSSP UUID library + --with-uuid build contrib/uuid, requires Linux or BSD UUID + library --with-libxml build with XML support --with-libxslt use XSLT support when building contrib/xml2 --with-system-tzdata=DIR @@ -5614,14 +5614,14 @@ fi # -# OSSP UUID library +# UUID library # -# Check whether --with-ossp-uuid was given. -if test "${with_ossp_uuid+set}" = set; then : - withval=$with_ossp_uuid; +# Check whether --with-uuid was given. +if test "${with_uuid+set}" = set; then : + withval=$with_uuid; case $withval in yes) : @@ -5630,12 +5630,12 @@ if test "${with_ossp_uuid+set}" = set; then : : ;; *) - as_fn_error $? "no argument expected for --with-ossp-uuid option" "$LINENO" 5 + as_fn_error $? "no argument expected for --with-uuid option" "$LINENO" 5 ;; esac else - with_ossp_uuid=no + with_uuid=no fi @@ -8774,15 +8774,14 @@ fi fi -# for contrib/uuid-ossp -if test "$with_ossp_uuid" = yes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -lossp-uuid" >&5 -$as_echo_n "checking for uuid_export in -lossp-uuid... " >&6; } -if ${ac_cv_lib_ossp_uuid_uuid_export+:} false; then : +# for contrib/uuid +if test "$with_uuid" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing uuid_generate" >&5 +$as_echo_n "checking for library containing uuid_generate... " >&6; } +if ${ac_cv_search_uuid_generate+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lossp-uuid $LIBS" + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8792,36 +8791,54 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char uuid_export (); +char uuid_generate (); int main () { -return uuid_export (); +return uuid_generate (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ossp_uuid_uuid_export=yes -else - ac_cv_lib_ossp_uuid_uuid_export=no +for ac_lib in '' uuid; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_uuid_generate=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + conftest$ac_exeext + if ${ac_cv_search_uuid_generate+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ossp_uuid_uuid_export" >&5 -$as_echo "$ac_cv_lib_ossp_uuid_uuid_export" >&6; } -if test "x$ac_cv_lib_ossp_uuid_uuid_export" = xyes; then : - OSSP_UUID_LIBS="-lossp-uuid" +done +if ${ac_cv_search_uuid_generate+:} false; then : + +else + ac_cv_search_uuid_generate=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_uuid_generate" >&5 +$as_echo "$ac_cv_search_uuid_generate" >&6; } +ac_res=$ac_cv_search_uuid_generate +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_LINUX_UUID 1" >>confdefs.h + else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -luuid" >&5 -$as_echo_n "checking for uuid_export in -luuid... " >&6; } -if ${ac_cv_lib_uuid_uuid_export+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing uuid_create" >&5 +$as_echo_n "checking for library containing uuid_create... " >&6; } +if ${ac_cv_search_uuid_create+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-luuid $LIBS" + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8831,36 +8848,54 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char uuid_export (); +char uuid_create (); int main () { -return uuid_export (); +return uuid_create (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_uuid_uuid_export=yes -else - ac_cv_lib_uuid_uuid_export=no +for ac_lib in '' ; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_uuid_create=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + conftest$ac_exeext + if ${ac_cv_search_uuid_create+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_export" >&5 -$as_echo "$ac_cv_lib_uuid_uuid_export" >&6; } -if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then : - OSSP_UUID_LIBS="-luuid" +done +if ${ac_cv_search_uuid_create+:} false; then : + else - as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP-UUID" "$LINENO" 5 + ac_cv_search_uuid_create=no fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_uuid_create" >&5 +$as_echo "$ac_cv_search_uuid_create" >&6; } +ac_res=$ac_cv_search_uuid_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_BSD_UUID 1" >>confdefs.h +else + as_fn_error $? "either Linux or BSD variants of uuid support are required" "$LINENO" 5 fi fi +fi ## @@ -9397,28 +9432,28 @@ fi fi -# for contrib/uuid-ossp -if test "$with_ossp_uuid" = yes ; then - for ac_header in ossp/uuid.h +# for contrib/uuid +if test "$with_uuid" = yes ; then + for ac_header in uuid.h do : - ac_fn_c_check_header_mongrel "$LINENO" "ossp/uuid.h" "ac_cv_header_ossp_uuid_h" "$ac_includes_default" -if test "x$ac_cv_header_ossp_uuid_h" = xyes; then : + ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_OSSP_UUID_H 1 +#define HAVE_UUID_H 1 _ACEOF else - for ac_header in uuid.h + for ac_header in uuid/uuid.h do : - ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default" -if test "x$ac_cv_header_uuid_h" = xyes; then : + ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_UUID_H 1 +#define HAVE_UUID_UUID_H 1 _ACEOF else - as_fn_error $? "header file or is required for OSSP-UUID" "$LINENO" 5 + as_fn_error $? "header file or is required for UUID" "$LINENO" 5 fi done diff --git a/configure.in b/configure.in index b94db35..f82f111 100644 --- a/configure.in +++ b/configure.in @@ -694,10 +694,10 @@ PGAC_ARG_BOOL(with, libedit-preferred, no, # -# OSSP UUID library +# UUID library # -PGAC_ARG_BOOL(with, ossp-uuid, no, [build contrib/uuid-ossp, requires OSSP UUID library]) -AC_SUBST(with_ossp_uuid) +PGAC_ARG_BOOL(with, uuid, no, [build contrib/uuid, requires Linux or BSD UUID library]) +AC_SUBST(with_uuid) # @@ -947,15 +947,12 @@ if test "$with_selinux" = yes; then [AC_MSG_ERROR([library 'libselinux', version 2.1.10 or newer, is required for SELinux support])]) fi -# for contrib/uuid-ossp -if test "$with_ossp_uuid" = yes ; then - AC_CHECK_LIB(ossp-uuid, uuid_export, - [OSSP_UUID_LIBS="-lossp-uuid"], - [AC_CHECK_LIB(uuid, uuid_export, - [OSSP_UUID_LIBS="-luuid"], - [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP-UUID])])]) +# for contrib/uuid +if test "$with_uuid" = yes ; then + AC_SEARCH_LIBS([uuid_generate], [uuid], [AC_DEFINE([HAVE_LINUX_UUID], 1, [Define to 1 if you have Linux UUID support.])], + [AC_SEARCH_LIBS([uuid_create], [], [AC_DEFINE([HAVE_BSD_UUID], 1, [Define to 1 if you have BSD UUID support.])], + [AC_MSG_ERROR([either Linux or BSD variants of uuid support are required])])]) fi -AC_SUBST(OSSP_UUID_LIBS) ## @@ -1074,11 +1071,11 @@ if test "$with_bonjour" = yes ; then AC_CHECK_HEADER(dns_sd.h, [], [AC_MSG_ERROR([header file is required for Bonjour])]) fi -# for contrib/uuid-ossp -if test "$with_ossp_uuid" = yes ; then - AC_CHECK_HEADERS(ossp/uuid.h, [], [ - AC_CHECK_HEADERS(uuid.h, [], - [AC_MSG_ERROR([header file or is required for OSSP-UUID])])]) +# for contrib/uuid +if test "$with_uuid" = yes ; then + AC_CHECK_HEADERS(uuid.h, [], [ + AC_CHECK_HEADERS(uuid/uuid.h, [], + [AC_MSG_ERROR([header file or is required for UUID])])]) fi if test "$PORTNAME" = "win32" ; then diff --git a/contrib/uuid-ossp/Makefile b/contrib/uuid-ossp/Makefile deleted file mode 100644 index 9b2d2e3..0000000 --- a/contrib/uuid-ossp/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# contrib/uuid-ossp/Makefile - -MODULE_big = uuid-ossp -OBJS = uuid-ossp.o - -EXTENSION = uuid-ossp -DATA = uuid-ossp--1.0.sql uuid-ossp--unpackaged--1.0.sql - -SHLIB_LINK += $(OSSP_UUID_LIBS) - -ifdef USE_PGXS -PG_CONFIG = pg_config -PGXS := $(shell $(PG_CONFIG) --pgxs) -include $(PGXS) -else -subdir = contrib/uuid-ossp -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global -include $(top_srcdir)/contrib/contrib-global.mk -endif diff --git a/contrib/uuid-ossp/uuid-ossp--1.0.sql b/contrib/uuid-ossp/uuid-ossp--1.0.sql deleted file mode 100644 index 0427320..0000000 --- a/contrib/uuid-ossp/uuid-ossp--1.0.sql +++ /dev/null @@ -1,54 +0,0 @@ -/* contrib/uuid-ossp/uuid-ossp--1.0.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use '''CREATE EXTENSION "uuid-ossp"''' to load this file. \quit - -CREATE FUNCTION uuid_nil() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_nil' -IMMUTABLE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_ns_dns() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_ns_dns' -IMMUTABLE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_ns_url() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_ns_url' -IMMUTABLE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_ns_oid() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_ns_oid' -IMMUTABLE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_ns_x500() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_ns_x500' -IMMUTABLE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_generate_v1() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_generate_v1' -VOLATILE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_generate_v1mc() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_generate_v1mc' -VOLATILE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_generate_v3(namespace uuid, name text) -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_generate_v3' -IMMUTABLE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_generate_v4() -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_generate_v4' -VOLATILE STRICT LANGUAGE C; - -CREATE FUNCTION uuid_generate_v5(namespace uuid, name text) -RETURNS uuid -AS 'MODULE_PATHNAME', 'uuid_generate_v5' -IMMUTABLE STRICT LANGUAGE C; diff --git a/contrib/uuid-ossp/uuid-ossp--unpackaged--1.0.sql b/contrib/uuid-ossp/uuid-ossp--unpackaged--1.0.sql deleted file mode 100644 index 5776b6f..0000000 --- a/contrib/uuid-ossp/uuid-ossp--unpackaged--1.0.sql +++ /dev/null @@ -1,15 +0,0 @@ -/* contrib/uuid-ossp/uuid-ossp--unpackaged--1.0.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use '''CREATE EXTENSION "uuid-ossp"''' to load this file. \quit - -ALTER EXTENSION "uuid-ossp" ADD function uuid_nil(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_ns_dns(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_ns_url(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_ns_oid(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_ns_x500(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_generate_v1(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_generate_v1mc(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_generate_v3(namespace uuid, name text); -ALTER EXTENSION "uuid-ossp" ADD function uuid_generate_v4(); -ALTER EXTENSION "uuid-ossp" ADD function uuid_generate_v5(namespace uuid, name text); diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c deleted file mode 100644 index 8f99084..0000000 --- a/contrib/uuid-ossp/uuid-ossp.c +++ /dev/null @@ -1,238 +0,0 @@ -/*------------------------------------------------------------------------- - * - * UUID generation functions using the OSSP UUID library - * - * Copyright (c) 2007-2014, PostgreSQL Global Development Group - * - * contrib/uuid-ossp/uuid-ossp.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "fmgr.h" -#include "utils/builtins.h" -#include "utils/uuid.h" - -/* - * There's some confusion over the location of the uuid.h header file. - * On Debian, it's installed as ossp/uuid.h, while on Fedora, or if you - * install ossp-uuid from a tarball, it's installed as uuid.h. Don't know - * what other systems do. - */ -#ifdef HAVE_OSSP_UUID_H -#include -#else -#ifdef HAVE_UUID_H -#include -#else -#error OSSP uuid.h not found -#endif -#endif - -/* better both be 16 */ -#if (UUID_LEN != UUID_LEN_BIN) -#error UUID length mismatch -#endif - - -PG_MODULE_MAGIC; - - -PG_FUNCTION_INFO_V1(uuid_nil); -PG_FUNCTION_INFO_V1(uuid_ns_dns); -PG_FUNCTION_INFO_V1(uuid_ns_url); -PG_FUNCTION_INFO_V1(uuid_ns_oid); -PG_FUNCTION_INFO_V1(uuid_ns_x500); - -PG_FUNCTION_INFO_V1(uuid_generate_v1); -PG_FUNCTION_INFO_V1(uuid_generate_v1mc); -PG_FUNCTION_INFO_V1(uuid_generate_v3); -PG_FUNCTION_INFO_V1(uuid_generate_v4); -PG_FUNCTION_INFO_V1(uuid_generate_v5); - -static void -pguuid_complain(uuid_rc_t rc) -{ - char *err = uuid_error(rc); - - if (err != NULL) - ereport(ERROR, - (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), - errmsg("OSSP uuid library failure: %s", err))); - else - ereport(ERROR, - (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), - errmsg("OSSP uuid library failure: error code %d", rc))); -} - -static char * -uuid_to_string(const uuid_t *uuid) -{ - char *buf = palloc(UUID_LEN_STR + 1); - void *ptr = buf; - size_t len = UUID_LEN_STR + 1; - uuid_rc_t rc; - - rc = uuid_export(uuid, UUID_FMT_STR, &ptr, &len); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - - return buf; -} - - -static void -string_to_uuid(const char *str, uuid_t *uuid) -{ - uuid_rc_t rc; - - rc = uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR + 1); - if (rc != UUID_RC_OK) - pguuid_complain(rc); -} - - -static Datum -special_uuid_value(const char *name) -{ - uuid_t *uuid; - char *str; - uuid_rc_t rc; - - rc = uuid_create(&uuid); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - rc = uuid_load(uuid, name); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - str = uuid_to_string(uuid); - rc = uuid_destroy(uuid); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - - return DirectFunctionCall1(uuid_in, CStringGetDatum(str)); -} - - -Datum -uuid_nil(PG_FUNCTION_ARGS) -{ - return special_uuid_value("nil"); -} - - -Datum -uuid_ns_dns(PG_FUNCTION_ARGS) -{ - return special_uuid_value("ns:DNS"); -} - - -Datum -uuid_ns_url(PG_FUNCTION_ARGS) -{ - return special_uuid_value("ns:URL"); -} - - -Datum -uuid_ns_oid(PG_FUNCTION_ARGS) -{ - return special_uuid_value("ns:OID"); -} - - -Datum -uuid_ns_x500(PG_FUNCTION_ARGS) -{ - return special_uuid_value("ns:X500"); -} - - -static Datum -uuid_generate_internal(int mode, const uuid_t *ns, const char *name) -{ - uuid_t *uuid; - char *str; - uuid_rc_t rc; - - rc = uuid_create(&uuid); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - rc = uuid_make(uuid, mode, ns, name); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - str = uuid_to_string(uuid); - rc = uuid_destroy(uuid); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - - return DirectFunctionCall1(uuid_in, CStringGetDatum(str)); -} - - -Datum -uuid_generate_v1(PG_FUNCTION_ARGS) -{ - return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL); -} - - -Datum -uuid_generate_v1mc(PG_FUNCTION_ARGS) -{ - return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL); -} - - -static Datum -uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name) -{ - uuid_t *ns_uuid; - Datum result; - uuid_rc_t rc; - - rc = uuid_create(&ns_uuid); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))), - ns_uuid); - - result = uuid_generate_internal(mode, - ns_uuid, - text_to_cstring(name)); - - rc = uuid_destroy(ns_uuid); - if (rc != UUID_RC_OK) - pguuid_complain(rc); - - return result; -} - - -Datum -uuid_generate_v3(PG_FUNCTION_ARGS) -{ - pg_uuid_t *ns = PG_GETARG_UUID_P(0); - text *name = PG_GETARG_TEXT_P(1); - - return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name); -} - - -Datum -uuid_generate_v4(PG_FUNCTION_ARGS) -{ - return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL); -} - - -Datum -uuid_generate_v5(PG_FUNCTION_ARGS) -{ - pg_uuid_t *ns = PG_GETARG_UUID_P(0); - text *name = PG_GETARG_TEXT_P(1); - - return uuid_generate_v35_internal(UUID_MAKE_V5, ns, name); -} diff --git a/contrib/uuid-ossp/uuid-ossp.control b/contrib/uuid-ossp/uuid-ossp.control deleted file mode 100644 index f52ae99..0000000 --- a/contrib/uuid-ossp/uuid-ossp.control +++ /dev/null @@ -1,5 +0,0 @@ -# uuid-ossp extension -comment = 'generate universally unique identifiers (UUIDs)' -default_version = '1.0' -module_pathname = '$libdir/uuid-ossp' -relocatable = true diff --git a/contrib/uuid/Makefile b/contrib/uuid/Makefile new file mode 100644 index 0000000..bd5f774 --- /dev/null +++ b/contrib/uuid/Makefile @@ -0,0 +1,20 @@ + +EXTENSION = uuid +DATA = uuid--1.0.sql +MODULE_big = uuid +OBJS = uuid.o md5.o sha1.o + +SHLIB_LINK += $(filter -luuid, $(LIBS)) + +REGRESS = init v1 v35 + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/uuid +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/uuid/expected/init.out b/contrib/uuid/expected/init.out new file mode 100644 index 0000000..dfa0155 --- /dev/null +++ b/contrib/uuid/expected/init.out @@ -0,0 +1 @@ +CREATE EXTENSION uuid; diff --git a/contrib/uuid/expected/v1.out b/contrib/uuid/expected/v1.out new file mode 100644 index 0000000..2d03343 --- /dev/null +++ b/contrib/uuid/expected/v1.out @@ -0,0 +1,30 @@ +SELECT uuid_generate_v1() < uuid_generate_v1(); + ?column? +---------- + t +(1 row) + +SELECT uuid_generate_v1() < uuid_generate_v1mc(); + ?column? +---------- + t +(1 row) + +SELECT substr(uuid_generate_v1()::text, 20) = substr(uuid_generate_v1()::text, 20); + ?column? +---------- + t +(1 row) + +SELECT substr(uuid_generate_v1()::text, 20) <> substr(uuid_generate_v1mc()::text, 20); + ?column? +---------- + t +(1 row) + +SELECT substr(uuid_generate_v1mc()::text, 20) <> substr(uuid_generate_v1mc()::text, 20); + ?column? +---------- + t +(1 row) + diff --git a/contrib/uuid/expected/v35.out b/contrib/uuid/expected/v35.out new file mode 100644 index 0000000..f37a989 --- /dev/null +++ b/contrib/uuid/expected/v35.out @@ -0,0 +1,12 @@ +SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com'); + uuid_generate_v3 +-------------------------------------- + 3d813cbb-47fb-32ba-91df-831e1593ac29 +(1 row) + +SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com'); + uuid_generate_v5 +-------------------------------------- + 21f7f8de-8051-5b89-8680-0195ef798b6a +(1 row) + diff --git a/contrib/uuid/md5.c b/contrib/uuid/md5.c new file mode 100644 index 0000000..cac4e40 --- /dev/null +++ b/contrib/uuid/md5.c @@ -0,0 +1,397 @@ +/* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS 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 PROJECT OR 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. + * + * contrib/pgcrypto/md5.c + */ + +#include "postgres.h" + +#include + +#include "md5.h" + +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s)))) + +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z))) +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z))) +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z))) + +#define ROUND1(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define ROUND2(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define ROUND3(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define ROUND4(a, b, c, d, k, s, i) \ +do { \ + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \ + (a) = SHIFT((a), (s)); \ + (a) = (b) + (a); \ +} while (0) + +#define Sa 7 +#define Sb 12 +#define Sc 17 +#define Sd 22 + +#define Se 5 +#define Sf 9 +#define Sg 14 +#define Sh 20 + +#define Si 4 +#define Sj 11 +#define Sk 16 +#define Sl 23 + +#define Sm 6 +#define Sn 10 +#define So 15 +#define Sp 21 + +#define MD5_A0 0x67452301 +#define MD5_B0 0xefcdab89 +#define MD5_C0 0x98badcfe +#define MD5_D0 0x10325476 + +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */ +static const uint32 T[65] = { + 0, + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, +}; + +static const uint8 md5_paddat[MD5_BUFLEN] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void md5_calc(uint8 *, md5_ctxt *); + +void +md5_init(md5_ctxt *ctxt) +{ + ctxt->md5_n = 0; + ctxt->md5_i = 0; + ctxt->md5_sta = MD5_A0; + ctxt->md5_stb = MD5_B0; + ctxt->md5_stc = MD5_C0; + ctxt->md5_std = MD5_D0; + memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf)); +} + +void +md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len) +{ + unsigned int gap, + i; + + ctxt->md5_n += len * 8; /* byte to bit */ + gap = MD5_BUFLEN - ctxt->md5_i; + + if (len >= gap) + { + memmove(ctxt->md5_buf + ctxt->md5_i, input, gap); + md5_calc(ctxt->md5_buf, ctxt); + + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) + md5_calc((uint8 *) (input + i), ctxt); + + ctxt->md5_i = len - i; + memmove(ctxt->md5_buf, input + i, ctxt->md5_i); + } + else + { + memmove(ctxt->md5_buf + ctxt->md5_i, input, len); + ctxt->md5_i += len; + } +} + +void +md5_pad(md5_ctxt *ctxt) +{ + unsigned int gap; + + /* Don't count up padding. Keep md5_n. */ + gap = MD5_BUFLEN - ctxt->md5_i; + if (gap > 8) + { + memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, + gap - sizeof(ctxt->md5_n)); + } + else + { + /* including gap == 8 */ + memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap); + md5_calc(ctxt->md5_buf, ctxt); + memmove(ctxt->md5_buf, md5_paddat + gap, + MD5_BUFLEN - sizeof(ctxt->md5_n)); + } + + /* 8 byte word */ +#ifndef WORDS_BIGENDIAN + memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8); +#else + ctxt->md5_buf[56] = ctxt->md5_n8[7]; + ctxt->md5_buf[57] = ctxt->md5_n8[6]; + ctxt->md5_buf[58] = ctxt->md5_n8[5]; + ctxt->md5_buf[59] = ctxt->md5_n8[4]; + ctxt->md5_buf[60] = ctxt->md5_n8[3]; + ctxt->md5_buf[61] = ctxt->md5_n8[2]; + ctxt->md5_buf[62] = ctxt->md5_n8[1]; + ctxt->md5_buf[63] = ctxt->md5_n8[0]; +#endif + + md5_calc(ctxt->md5_buf, ctxt); +} + +void +md5_result(uint8 *digest, md5_ctxt *ctxt) +{ + /* 4 byte words */ +#ifndef WORDS_BIGENDIAN + memmove(digest, &ctxt->md5_st8[0], 16); +#else + digest[0] = ctxt->md5_st8[3]; + digest[1] = ctxt->md5_st8[2]; + digest[2] = ctxt->md5_st8[1]; + digest[3] = ctxt->md5_st8[0]; + digest[4] = ctxt->md5_st8[7]; + digest[5] = ctxt->md5_st8[6]; + digest[6] = ctxt->md5_st8[5]; + digest[7] = ctxt->md5_st8[4]; + digest[8] = ctxt->md5_st8[11]; + digest[9] = ctxt->md5_st8[10]; + digest[10] = ctxt->md5_st8[9]; + digest[11] = ctxt->md5_st8[8]; + digest[12] = ctxt->md5_st8[15]; + digest[13] = ctxt->md5_st8[14]; + digest[14] = ctxt->md5_st8[13]; + digest[15] = ctxt->md5_st8[12]; +#endif +} + +#ifdef WORDS_BIGENDIAN +static uint32 X[16]; +#endif + +static void +md5_calc(uint8 *b64, md5_ctxt *ctxt) +{ + uint32 A = ctxt->md5_sta; + uint32 B = ctxt->md5_stb; + uint32 C = ctxt->md5_stc; + uint32 D = ctxt->md5_std; + +#ifndef WORDS_BIGENDIAN + uint32 *X = (uint32 *) b64; +#else + /* 4 byte words */ + /* what a brute force but fast! */ + uint8 *y = (uint8 *) X; + + y[0] = b64[3]; + y[1] = b64[2]; + y[2] = b64[1]; + y[3] = b64[0]; + y[4] = b64[7]; + y[5] = b64[6]; + y[6] = b64[5]; + y[7] = b64[4]; + y[8] = b64[11]; + y[9] = b64[10]; + y[10] = b64[9]; + y[11] = b64[8]; + y[12] = b64[15]; + y[13] = b64[14]; + y[14] = b64[13]; + y[15] = b64[12]; + y[16] = b64[19]; + y[17] = b64[18]; + y[18] = b64[17]; + y[19] = b64[16]; + y[20] = b64[23]; + y[21] = b64[22]; + y[22] = b64[21]; + y[23] = b64[20]; + y[24] = b64[27]; + y[25] = b64[26]; + y[26] = b64[25]; + y[27] = b64[24]; + y[28] = b64[31]; + y[29] = b64[30]; + y[30] = b64[29]; + y[31] = b64[28]; + y[32] = b64[35]; + y[33] = b64[34]; + y[34] = b64[33]; + y[35] = b64[32]; + y[36] = b64[39]; + y[37] = b64[38]; + y[38] = b64[37]; + y[39] = b64[36]; + y[40] = b64[43]; + y[41] = b64[42]; + y[42] = b64[41]; + y[43] = b64[40]; + y[44] = b64[47]; + y[45] = b64[46]; + y[46] = b64[45]; + y[47] = b64[44]; + y[48] = b64[51]; + y[49] = b64[50]; + y[50] = b64[49]; + y[51] = b64[48]; + y[52] = b64[55]; + y[53] = b64[54]; + y[54] = b64[53]; + y[55] = b64[52]; + y[56] = b64[59]; + y[57] = b64[58]; + y[58] = b64[57]; + y[59] = b64[56]; + y[60] = b64[63]; + y[61] = b64[62]; + y[62] = b64[61]; + y[63] = b64[60]; +#endif + + ROUND1(A, B, C, D, 0, Sa, 1); + ROUND1(D, A, B, C, 1, Sb, 2); + ROUND1(C, D, A, B, 2, Sc, 3); + ROUND1(B, C, D, A, 3, Sd, 4); + ROUND1(A, B, C, D, 4, Sa, 5); + ROUND1(D, A, B, C, 5, Sb, 6); + ROUND1(C, D, A, B, 6, Sc, 7); + ROUND1(B, C, D, A, 7, Sd, 8); + ROUND1(A, B, C, D, 8, Sa, 9); + ROUND1(D, A, B, C, 9, Sb, 10); + ROUND1(C, D, A, B, 10, Sc, 11); + ROUND1(B, C, D, A, 11, Sd, 12); + ROUND1(A, B, C, D, 12, Sa, 13); + ROUND1(D, A, B, C, 13, Sb, 14); + ROUND1(C, D, A, B, 14, Sc, 15); + ROUND1(B, C, D, A, 15, Sd, 16); + + ROUND2(A, B, C, D, 1, Se, 17); + ROUND2(D, A, B, C, 6, Sf, 18); + ROUND2(C, D, A, B, 11, Sg, 19); + ROUND2(B, C, D, A, 0, Sh, 20); + ROUND2(A, B, C, D, 5, Se, 21); + ROUND2(D, A, B, C, 10, Sf, 22); + ROUND2(C, D, A, B, 15, Sg, 23); + ROUND2(B, C, D, A, 4, Sh, 24); + ROUND2(A, B, C, D, 9, Se, 25); + ROUND2(D, A, B, C, 14, Sf, 26); + ROUND2(C, D, A, B, 3, Sg, 27); + ROUND2(B, C, D, A, 8, Sh, 28); + ROUND2(A, B, C, D, 13, Se, 29); + ROUND2(D, A, B, C, 2, Sf, 30); + ROUND2(C, D, A, B, 7, Sg, 31); + ROUND2(B, C, D, A, 12, Sh, 32); + + ROUND3(A, B, C, D, 5, Si, 33); + ROUND3(D, A, B, C, 8, Sj, 34); + ROUND3(C, D, A, B, 11, Sk, 35); + ROUND3(B, C, D, A, 14, Sl, 36); + ROUND3(A, B, C, D, 1, Si, 37); + ROUND3(D, A, B, C, 4, Sj, 38); + ROUND3(C, D, A, B, 7, Sk, 39); + ROUND3(B, C, D, A, 10, Sl, 40); + ROUND3(A, B, C, D, 13, Si, 41); + ROUND3(D, A, B, C, 0, Sj, 42); + ROUND3(C, D, A, B, 3, Sk, 43); + ROUND3(B, C, D, A, 6, Sl, 44); + ROUND3(A, B, C, D, 9, Si, 45); + ROUND3(D, A, B, C, 12, Sj, 46); + ROUND3(C, D, A, B, 15, Sk, 47); + ROUND3(B, C, D, A, 2, Sl, 48); + + ROUND4(A, B, C, D, 0, Sm, 49); + ROUND4(D, A, B, C, 7, Sn, 50); + ROUND4(C, D, A, B, 14, So, 51); + ROUND4(B, C, D, A, 5, Sp, 52); + ROUND4(A, B, C, D, 12, Sm, 53); + ROUND4(D, A, B, C, 3, Sn, 54); + ROUND4(C, D, A, B, 10, So, 55); + ROUND4(B, C, D, A, 1, Sp, 56); + ROUND4(A, B, C, D, 8, Sm, 57); + ROUND4(D, A, B, C, 15, Sn, 58); + ROUND4(C, D, A, B, 6, So, 59); + ROUND4(B, C, D, A, 13, Sp, 60); + ROUND4(A, B, C, D, 4, Sm, 61); + ROUND4(D, A, B, C, 11, Sn, 62); + ROUND4(C, D, A, B, 2, So, 63); + ROUND4(B, C, D, A, 9, Sp, 64); + + ctxt->md5_sta += A; + ctxt->md5_stb += B; + ctxt->md5_stc += C; + ctxt->md5_std += D; +} diff --git a/contrib/uuid/md5.h b/contrib/uuid/md5.h new file mode 100644 index 0000000..07d08c1 --- /dev/null +++ b/contrib/uuid/md5.h @@ -0,0 +1,79 @@ +/* contrib/pgcrypto/md5.h */ +/* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS 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 PROJECT OR 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 _NETINET6_MD5_H_ +#define _NETINET6_MD5_H_ + +#define MD5_BUFLEN 64 + +typedef struct +{ + union + { + uint32 md5_state32[4]; + uint8 md5_state8[16]; + } md5_st; + +#define md5_sta md5_st.md5_state32[0] +#define md5_stb md5_st.md5_state32[1] +#define md5_stc md5_st.md5_state32[2] +#define md5_std md5_st.md5_state32[3] +#define md5_st8 md5_st.md5_state8 + + union + { + uint64 md5_count64; + uint8 md5_count8[8]; + } md5_count; +#define md5_n md5_count.md5_count64 +#define md5_n8 md5_count.md5_count8 + + unsigned int md5_i; + uint8 md5_buf[MD5_BUFLEN]; +} md5_ctxt; + +extern void md5_init(md5_ctxt *); +extern void md5_loop(md5_ctxt *, const uint8 *, unsigned int); +extern void md5_pad(md5_ctxt *); +extern void md5_result(uint8 *, md5_ctxt *); + +/* compatibility */ +#define MD5_CTX md5_ctxt +#define MD5Init(x) md5_init((x)) +#define MD5Update(x, y, z) md5_loop((x), (y), (z)) +#define MD5Final(x, y) \ +do { \ + md5_pad((y)); \ + md5_result((x), (y)); \ +} while (0) + +#endif /* ! _NETINET6_MD5_H_ */ diff --git a/contrib/uuid/sha1.c b/contrib/uuid/sha1.c new file mode 100644 index 0000000..0e753ce --- /dev/null +++ b/contrib/uuid/sha1.c @@ -0,0 +1,341 @@ +/* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS 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 PROJECT OR 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. + * + * contrib/pgcrypto/sha1.c + */ +/* + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) + * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm + * implemented by Jun-ichiro itojun Itoh + */ + +#include "postgres.h" + +#include + +#include "sha1.h" + +/* constant table */ +static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; + +#define K(t) _K[(t) / 20] + +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) +#define F1(b, c, d) (((b) ^ (c)) ^ (d)) +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define F3(b, c, d) (((b) ^ (c)) ^ (d)) + +#define S(n, x) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define H(n) (ctxt->h.b32[(n)]) +#define COUNT (ctxt->count) +#define BCOUNT (ctxt->c.b64[0] / 8) +#define W(n) (ctxt->m.b32[(n)]) + +#define PUTBYTE(x) \ +do { \ + ctxt->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + ctxt->c.b64[0] += 8; \ + if (COUNT % 64 == 0) \ + sha1_step(ctxt); \ +} while (0) + +#define PUTPAD(x) \ +do { \ + ctxt->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + if (COUNT % 64 == 0) \ + sha1_step(ctxt); \ +} while (0) + +static void sha1_step(struct sha1_ctxt *); + +static void +sha1_step(struct sha1_ctxt * ctxt) +{ + uint32 a, + b, + c, + d, + e; + size_t t, + s; + uint32 tmp; + +#ifndef WORDS_BIGENDIAN + struct sha1_ctxt tctxt; + + memmove(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); + ctxt->m.b8[0] = tctxt.m.b8[3]; + ctxt->m.b8[1] = tctxt.m.b8[2]; + ctxt->m.b8[2] = tctxt.m.b8[1]; + ctxt->m.b8[3] = tctxt.m.b8[0]; + ctxt->m.b8[4] = tctxt.m.b8[7]; + ctxt->m.b8[5] = tctxt.m.b8[6]; + ctxt->m.b8[6] = tctxt.m.b8[5]; + ctxt->m.b8[7] = tctxt.m.b8[4]; + ctxt->m.b8[8] = tctxt.m.b8[11]; + ctxt->m.b8[9] = tctxt.m.b8[10]; + ctxt->m.b8[10] = tctxt.m.b8[9]; + ctxt->m.b8[11] = tctxt.m.b8[8]; + ctxt->m.b8[12] = tctxt.m.b8[15]; + ctxt->m.b8[13] = tctxt.m.b8[14]; + ctxt->m.b8[14] = tctxt.m.b8[13]; + ctxt->m.b8[15] = tctxt.m.b8[12]; + ctxt->m.b8[16] = tctxt.m.b8[19]; + ctxt->m.b8[17] = tctxt.m.b8[18]; + ctxt->m.b8[18] = tctxt.m.b8[17]; + ctxt->m.b8[19] = tctxt.m.b8[16]; + ctxt->m.b8[20] = tctxt.m.b8[23]; + ctxt->m.b8[21] = tctxt.m.b8[22]; + ctxt->m.b8[22] = tctxt.m.b8[21]; + ctxt->m.b8[23] = tctxt.m.b8[20]; + ctxt->m.b8[24] = tctxt.m.b8[27]; + ctxt->m.b8[25] = tctxt.m.b8[26]; + ctxt->m.b8[26] = tctxt.m.b8[25]; + ctxt->m.b8[27] = tctxt.m.b8[24]; + ctxt->m.b8[28] = tctxt.m.b8[31]; + ctxt->m.b8[29] = tctxt.m.b8[30]; + ctxt->m.b8[30] = tctxt.m.b8[29]; + ctxt->m.b8[31] = tctxt.m.b8[28]; + ctxt->m.b8[32] = tctxt.m.b8[35]; + ctxt->m.b8[33] = tctxt.m.b8[34]; + ctxt->m.b8[34] = tctxt.m.b8[33]; + ctxt->m.b8[35] = tctxt.m.b8[32]; + ctxt->m.b8[36] = tctxt.m.b8[39]; + ctxt->m.b8[37] = tctxt.m.b8[38]; + ctxt->m.b8[38] = tctxt.m.b8[37]; + ctxt->m.b8[39] = tctxt.m.b8[36]; + ctxt->m.b8[40] = tctxt.m.b8[43]; + ctxt->m.b8[41] = tctxt.m.b8[42]; + ctxt->m.b8[42] = tctxt.m.b8[41]; + ctxt->m.b8[43] = tctxt.m.b8[40]; + ctxt->m.b8[44] = tctxt.m.b8[47]; + ctxt->m.b8[45] = tctxt.m.b8[46]; + ctxt->m.b8[46] = tctxt.m.b8[45]; + ctxt->m.b8[47] = tctxt.m.b8[44]; + ctxt->m.b8[48] = tctxt.m.b8[51]; + ctxt->m.b8[49] = tctxt.m.b8[50]; + ctxt->m.b8[50] = tctxt.m.b8[49]; + ctxt->m.b8[51] = tctxt.m.b8[48]; + ctxt->m.b8[52] = tctxt.m.b8[55]; + ctxt->m.b8[53] = tctxt.m.b8[54]; + ctxt->m.b8[54] = tctxt.m.b8[53]; + ctxt->m.b8[55] = tctxt.m.b8[52]; + ctxt->m.b8[56] = tctxt.m.b8[59]; + ctxt->m.b8[57] = tctxt.m.b8[58]; + ctxt->m.b8[58] = tctxt.m.b8[57]; + ctxt->m.b8[59] = tctxt.m.b8[56]; + ctxt->m.b8[60] = tctxt.m.b8[63]; + ctxt->m.b8[61] = tctxt.m.b8[62]; + ctxt->m.b8[62] = tctxt.m.b8[61]; + ctxt->m.b8[63] = tctxt.m.b8[60]; +#endif + + a = H(0); + b = H(1); + c = H(2); + d = H(3); + e = H(4); + + for (t = 0; t < 20; t++) + { + s = t & 0x0f; + if (t >= 16) + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + for (t = 20; t < 40; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + for (t = 40; t < 60; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + for (t = 60; t < 80; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); + e = d; + d = c; + c = S(30, b); + b = a; + a = tmp; + } + + H(0) = H(0) + a; + H(1) = H(1) + b; + H(2) = H(2) + c; + H(3) = H(3) + d; + H(4) = H(4) + e; + + memset(&ctxt->m.b8[0], 0, 64); +} + +/*------------------------------------------------------------*/ + +void +sha1_init(struct sha1_ctxt * ctxt) +{ + memset(ctxt, 0, sizeof(struct sha1_ctxt)); + H(0) = 0x67452301; + H(1) = 0xefcdab89; + H(2) = 0x98badcfe; + H(3) = 0x10325476; + H(4) = 0xc3d2e1f0; +} + +void +sha1_pad(struct sha1_ctxt * ctxt) +{ + size_t padlen; /* pad length in bytes */ + size_t padstart; + + PUTPAD(0x80); + + padstart = COUNT % 64; + padlen = 64 - padstart; + if (padlen < 8) + { + memset(&ctxt->m.b8[padstart], 0, padlen); + COUNT += padlen; + COUNT %= 64; + sha1_step(ctxt); + padstart = COUNT % 64; /* should be 0 */ + padlen = 64 - padstart; /* should be 64 */ + } + memset(&ctxt->m.b8[padstart], 0, padlen - 8); + COUNT += (padlen - 8); + COUNT %= 64; +#ifdef WORDS_BIGENDIAN + PUTPAD(ctxt->c.b8[0]); + PUTPAD(ctxt->c.b8[1]); + PUTPAD(ctxt->c.b8[2]); + PUTPAD(ctxt->c.b8[3]); + PUTPAD(ctxt->c.b8[4]); + PUTPAD(ctxt->c.b8[5]); + PUTPAD(ctxt->c.b8[6]); + PUTPAD(ctxt->c.b8[7]); +#else + PUTPAD(ctxt->c.b8[7]); + PUTPAD(ctxt->c.b8[6]); + PUTPAD(ctxt->c.b8[5]); + PUTPAD(ctxt->c.b8[4]); + PUTPAD(ctxt->c.b8[3]); + PUTPAD(ctxt->c.b8[2]); + PUTPAD(ctxt->c.b8[1]); + PUTPAD(ctxt->c.b8[0]); +#endif +} + +void +sha1_loop(struct sha1_ctxt * ctxt, const uint8 *input0, size_t len) +{ + const uint8 *input; + size_t gaplen; + size_t gapstart; + size_t off; + size_t copysiz; + + input = (const uint8 *) input0; + off = 0; + + while (off < len) + { + gapstart = COUNT % 64; + gaplen = 64 - gapstart; + + copysiz = (gaplen < len - off) ? gaplen : len - off; + memmove(&ctxt->m.b8[gapstart], &input[off], copysiz); + COUNT += copysiz; + COUNT %= 64; + ctxt->c.b64[0] += copysiz * 8; + if (COUNT % 64 == 0) + sha1_step(ctxt); + off += copysiz; + } +} + +void +sha1_result(struct sha1_ctxt * ctxt, uint8 *digest0) +{ + uint8 *digest; + + digest = (uint8 *) digest0; + sha1_pad(ctxt); +#ifdef WORDS_BIGENDIAN + memmove(digest, &ctxt->h.b8[0], 20); +#else + digest[0] = ctxt->h.b8[3]; + digest[1] = ctxt->h.b8[2]; + digest[2] = ctxt->h.b8[1]; + digest[3] = ctxt->h.b8[0]; + digest[4] = ctxt->h.b8[7]; + digest[5] = ctxt->h.b8[6]; + digest[6] = ctxt->h.b8[5]; + digest[7] = ctxt->h.b8[4]; + digest[8] = ctxt->h.b8[11]; + digest[9] = ctxt->h.b8[10]; + digest[10] = ctxt->h.b8[9]; + digest[11] = ctxt->h.b8[8]; + digest[12] = ctxt->h.b8[15]; + digest[13] = ctxt->h.b8[14]; + digest[14] = ctxt->h.b8[13]; + digest[15] = ctxt->h.b8[12]; + digest[16] = ctxt->h.b8[19]; + digest[17] = ctxt->h.b8[18]; + digest[18] = ctxt->h.b8[17]; + digest[19] = ctxt->h.b8[16]; +#endif +} diff --git a/contrib/uuid/sha1.h b/contrib/uuid/sha1.h new file mode 100644 index 0000000..5532ca1 --- /dev/null +++ b/contrib/uuid/sha1.h @@ -0,0 +1,75 @@ +/* contrib/pgcrypto/sha1.h */ +/* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS 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 PROJECT OR 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. + */ +/* + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) + * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm + * implemented by Jun-ichiro itojun Itoh + */ + +#ifndef _NETINET6_SHA1_H_ +#define _NETINET6_SHA1_H_ + +struct sha1_ctxt +{ + union + { + uint8 b8[20]; + uint32 b32[5]; + } h; + union + { + uint8 b8[8]; + uint64 b64[1]; + } c; + union + { + uint8 b8[64]; + uint32 b32[16]; + } m; + uint8 count; +}; + +extern void sha1_init(struct sha1_ctxt *); +extern void sha1_pad(struct sha1_ctxt *); +extern void sha1_loop(struct sha1_ctxt *, const uint8 *, size_t); +extern void sha1_result(struct sha1_ctxt *, uint8 *); + +/* compatibilty with other SHA1 source codes */ +typedef struct sha1_ctxt SHA1_CTX; + +#define SHA1Init(x) sha1_init((x)) +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z)) +#define SHA1Final(x, y) sha1_result((y), (x)) + +#define SHA1_RESULTLEN (160/8) + +#endif /* _NETINET6_SHA1_H_ */ diff --git a/contrib/uuid/sql/init.sql b/contrib/uuid/sql/init.sql new file mode 100644 index 0000000..764aae9 --- /dev/null +++ b/contrib/uuid/sql/init.sql @@ -0,0 +1,3 @@ + +CREATE EXTENSION uuid; + diff --git a/contrib/uuid/sql/v1.sql b/contrib/uuid/sql/v1.sql new file mode 100644 index 0000000..5cc6d21 --- /dev/null +++ b/contrib/uuid/sql/v1.sql @@ -0,0 +1,10 @@ + +SELECT uuid_generate_v1() < uuid_generate_v1(); +SELECT uuid_generate_v1() < uuid_generate_v1mc(); + +SELECT substr(uuid_generate_v1()::text, 20) = substr(uuid_generate_v1()::text, 20); +SELECT substr(uuid_generate_v1()::text, 20) <> substr(uuid_generate_v1mc()::text, 20); +SELECT substr(uuid_generate_v1mc()::text, 20) <> substr(uuid_generate_v1mc()::text, 20); + + + diff --git a/contrib/uuid/sql/v35.sql b/contrib/uuid/sql/v35.sql new file mode 100644 index 0000000..3a8c21a --- /dev/null +++ b/contrib/uuid/sql/v35.sql @@ -0,0 +1,3 @@ + +SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com'); +SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com'); diff --git a/contrib/uuid/uuid--1.0.sql b/contrib/uuid/uuid--1.0.sql new file mode 100644 index 0000000..df2d791 --- /dev/null +++ b/contrib/uuid/uuid--1.0.sql @@ -0,0 +1,56 @@ +-- uuid extension + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use CREATE EXTENSION "uuid"; to load this file. \quit + +CREATE FUNCTION uuid_nil() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_nil' +IMMUTABLE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_ns_dns() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_ns_dns' +IMMUTABLE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_ns_url() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_ns_url' +IMMUTABLE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_ns_oid() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_ns_oid' +IMMUTABLE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_ns_x500() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_ns_x500' +IMMUTABLE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_generate_v1() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_generate_v1' +VOLATILE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_generate_v1mc() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_generate_v1mc' +VOLATILE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_generate_v3(namespace uuid, name text) +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_generate_v3' +IMMUTABLE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_generate_v4() +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_generate_v4' +VOLATILE STRICT LANGUAGE C; + +CREATE FUNCTION uuid_generate_v5(namespace uuid, name text) +RETURNS uuid +AS 'MODULE_PATHNAME', 'uuid_generate_v5' +IMMUTABLE STRICT LANGUAGE C; + +-- end diff --git a/contrib/uuid/uuid.c b/contrib/uuid/uuid.c new file mode 100644 index 0000000..0fe304f --- /dev/null +++ b/contrib/uuid/uuid.c @@ -0,0 +1,389 @@ +/*------------------------------------------------------------------------- + * + * UUID generation functions for PostgreSQL + * + * Copyright (c) 2014 Matteo Beccati + * Copyright (c) 2009 Andrew Gierth + * + * Some parts originated from contrib/uuid-ossp, which is + * Copyright (c) 2007-2008 PostgreSQL Global Development Group + * + * 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 BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR + * 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. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" +#include "fmgr.h" +#include "utils/builtins.h" +#include "utils/uuid.h" + +#ifdef HAVE_BSD_UUID +/* OS has a uuid_hash that conflicts with ours; kill it*/ +/* explicit path since we do _not_ want to get any other version */ +#undef uuid_hash +#define uuid_hash bsd_uuid_hash +#include "/usr/include/uuid.h" +#undef uuid_hash +#include +#endif + +#ifdef HAVE_LINUX_UUID +#include +#endif + +/* Some BSD variants offer md5 and sha1 implementations + * but Linux does not, so we use a copy of the ones from + * pgcrypto */ +#include "md5.h" +#include "sha1.h" + +PG_MODULE_MAGIC; + +Datum uuid_nil(PG_FUNCTION_ARGS); +Datum uuid_ns_dns(PG_FUNCTION_ARGS); +Datum uuid_ns_url(PG_FUNCTION_ARGS); +Datum uuid_ns_oid(PG_FUNCTION_ARGS); +Datum uuid_ns_x500(PG_FUNCTION_ARGS); + +Datum uuid_generate_v1(PG_FUNCTION_ARGS); +Datum uuid_generate_v1mc(PG_FUNCTION_ARGS); +Datum uuid_generate_v3(PG_FUNCTION_ARGS); +Datum uuid_generate_v4(PG_FUNCTION_ARGS); +Datum uuid_generate_v5(PG_FUNCTION_ARGS); + +PG_FUNCTION_INFO_V1(uuid_nil); +PG_FUNCTION_INFO_V1(uuid_ns_dns); +PG_FUNCTION_INFO_V1(uuid_ns_url); +PG_FUNCTION_INFO_V1(uuid_ns_oid); +PG_FUNCTION_INFO_V1(uuid_ns_x500); + +PG_FUNCTION_INFO_V1(uuid_generate_v1); +PG_FUNCTION_INFO_V1(uuid_generate_v1mc); +PG_FUNCTION_INFO_V1(uuid_generate_v3); +PG_FUNCTION_INFO_V1(uuid_generate_v4); +PG_FUNCTION_INFO_V1(uuid_generate_v5); + + +#ifdef HAVE_LINUX_UUID +/* A DCE 1.1 compatible source representation of UUIDs, derived from + * the BSD implementation + */ +typedef struct dce_uuid { + 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]; +} dce_uuid_t; +#else +#define dce_uuid_t uuid_t +#endif + +#define UUID_TO_NETWORK(uu) \ +do \ +{ \ + uu.time_low = htonl(uu.time_low); \ + uu.time_mid = htons(uu.time_mid); \ + uu.time_hi_and_version = htons(uu.time_hi_and_version); \ +} while (0) + +#define UUID_TO_LOCAL(uu) \ +do \ +{ \ + uu.time_low = ntohl(uu.time_low); \ + uu.time_mid = ntohs(uu.time_mid); \ + uu.time_hi_and_version = ntohs(uu.time_hi_and_version); \ +} while (0) + +#define UUID_V3_OR_V5(uu, v) \ +do \ +{ \ + uu.time_hi_and_version &= 0x0FFF; \ + uu.time_hi_and_version |= (v << 12); \ + uu.clock_seq_hi_and_reserved &= 0x3F; \ + uu.clock_seq_hi_and_reserved |= 0x80; \ +} while(0) + + +static Datum +internal_uuid_create(int v, unsigned char *ns, char *ptr, int len) +{ + char strbuf[40]; + + switch (v) + { + case 0: /* constant-value uuids: nil, or namespace uuids */ + strlcpy(strbuf, ptr, 37); + break; + + case 4: default: /* random uuid */ + { +#ifdef HAVE_LINUX_UUID + uuid_t uu; + + uuid_generate_random(uu); + uuid_unparse(uu, strbuf); +#else + sprintf(strbuf, "%08lx-%04x-%04x-%04x-%04x%08lx", + (unsigned long) arc4random(), + (unsigned) (arc4random() & 0xffff), + (unsigned) ((arc4random() & 0xfff) | 0x4000), + (unsigned) ((arc4random() & 0x3fff) | 0x8000), + (unsigned) (arc4random() & 0xffff), + (unsigned long) arc4random()); +#endif + break; + } + + case 1: /* time/node-based uuids */ + { + uuid_t uu; +#ifdef HAVE_BSD_UUID + uint32_t status = uuid_s_ok; + char *str = NULL; + + uuid_create(&uu, &status); + + if (status == uuid_s_ok) + { + uuid_to_string(&uu, &str, &status); + if (status == uuid_s_ok) + { + strlcpy(strbuf, str, 37); + + /* PTR, if set, replaces the trailing characters of the uuid; + * this is to support v1mc, where a random multicast MAC is + * used instead of the physical one + */ + + if (ptr && len <= 36) + strcpy(strbuf + (36 - len), ptr); + } + if (str) + free(str); + } + + if (status != uuid_s_ok) + { + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), + errmsg("uuid library failure: %d", (int) status))); + } +#else + + uuid_generate_time(uu); + uuid_unparse(uu, strbuf); + break; + } + + case -1: /* v1mc variant for Linux */ + { + char buf[40]; + uuid_t ut, ur; + + uuid_generate_time(ut); + uuid_generate_random(ur); + + uuid_unparse(ut, strbuf); + uuid_unparse(ur, buf); + + /* the first part of the uuid is time based + * while the second one is random */ + strlcpy(strbuf + 18, buf + 18, 19); +#endif + break; + } + + case 3: /* namespace-based MD5 uuids */ + { + MD5_CTX ctx; + dce_uuid_t uu; +#ifdef HAVE_BSD_UUID + uint32_t status = uuid_s_ok; + char *str = NULL; +#endif + + MD5Init(&ctx); + MD5Update(&ctx, ns, sizeof(uu)); + MD5Update(&ctx, (unsigned char *)ptr, len); + MD5Final((unsigned char *)&uu, &ctx); + + /* the calculated hash is using local order */ + UUID_TO_NETWORK(uu); + UUID_V3_OR_V5(uu, 3); + +#ifdef HAVE_LINUX_UUID + /* uuid_unparse expects local order */ + UUID_TO_LOCAL(uu); + uuid_unparse((unsigned char *)&uu, strbuf); +#else + uuid_to_string(&uu, &str, &status); + + if (status == uuid_s_ok) + { + strlcpy(strbuf, str, 37); + } + if (str) + { + free(str); + } + + + if (status != uuid_s_ok) + { + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), + errmsg("uuid library failure: %d", (int) status))); + } + +#endif + break; + } + + case 5: /* namespace-based SHA1 uuids */ + { + SHA1_CTX ctx; + dce_uuid_t uu; +#ifdef HAVE_BSD_UUID + uint32_t status = uuid_s_ok; + char *str = NULL; +#endif + + SHA1Init(&ctx); + SHA1Update(&ctx, ns, sizeof(uu)); + SHA1Update(&ctx, (unsigned char *)ptr, len); + SHA1Final((unsigned char *)&uu, &ctx); + + /* the calculated hash is using local order */ + UUID_TO_NETWORK(uu); + UUID_V3_OR_V5(uu, 5); + +#ifdef HAVE_LINUX_UUID + /* uuid_unparse expects local order */ + UUID_TO_LOCAL(uu); + uuid_unparse((unsigned char *)&uu, strbuf); +#else + uuid_to_string(&uu, &str, &status); + + if (status == uuid_s_ok) + { + strlcpy(strbuf, str, 37); + } + if (str) + { + free(str); + } + + + if (status != uuid_s_ok) + { + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), + errmsg("uuid library failure: %d", (int) status))); + } + +#endif + break; + } + } + + return DirectFunctionCall1(uuid_in, CStringGetDatum(strbuf)); +} + +Datum +uuid_nil(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(0, NULL, "00000000-0000-0000-0000-000000000000", 36); +} + +Datum +uuid_ns_dns(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(0, NULL, "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 36); +} + +Datum +uuid_ns_url(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(0, NULL, "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 36); +} + +Datum +uuid_ns_oid(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(0, NULL, "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 36); +} + +Datum +uuid_ns_x500(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(0, NULL, "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 36); +} + +Datum +uuid_generate_v1(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(1, NULL, NULL, 0); +} + +Datum +uuid_generate_v1mc(PG_FUNCTION_ARGS) +{ +#ifdef HAVE_BSD_UUID + char buf[20]; + + sprintf(buf, "-%04x-%04x%08lx", + (unsigned)((arc4random() & 0x3FFF) | 0x8000), + /* set IEEE802 multicast and local-admin bits */ + (unsigned)((arc4random() & 0xffff) | 0x0300), + (unsigned long) arc4random()); + + return internal_uuid_create(1, NULL, buf, 18); +#else + return internal_uuid_create(-1, NULL, NULL, 0);; +#endif +} + +Datum +uuid_generate_v3(PG_FUNCTION_ARGS) +{ + pg_uuid_t *ns = PG_GETARG_UUID_P(0); + text *name = PG_GETARG_TEXT_P(1); + + return internal_uuid_create(3, (unsigned char *)ns, + VARDATA(name), VARSIZE(name) - VARHDRSZ); +} + +Datum +uuid_generate_v4(PG_FUNCTION_ARGS) +{ + return internal_uuid_create(4, NULL, NULL, 0); +} + +Datum +uuid_generate_v5(PG_FUNCTION_ARGS) +{ + pg_uuid_t *ns = PG_GETARG_UUID_P(0); + text *name = PG_GETARG_TEXT_P(1); + + return internal_uuid_create(5, (unsigned char *)ns, + VARDATA(name), VARSIZE(name) - VARHDRSZ); +} diff --git a/contrib/uuid/uuid.control b/contrib/uuid/uuid.control new file mode 100644 index 0000000..f46bb04 --- /dev/null +++ b/contrib/uuid/uuid.control @@ -0,0 +1,4 @@ +# uuid +default_version = '1.0' +relocatable = 'true' +module_pathname = '$libdir/uuid' diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 4b31c0a..c8c59ea 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -163,7 +163,7 @@ with_perl = @with_perl@ with_python = @with_python@ with_tcl = @with_tcl@ with_openssl = @with_openssl@ -with_ossp_uuid = @with_ossp_uuid@ +with_uuid = @with_uuid@ with_selinux = @with_selinux@ with_libxml = @with_libxml@ with_libxslt = @with_libxslt@ @@ -240,7 +240,6 @@ DLLWRAP = @DLLWRAP@ LIBS = @LIBS@ LDAP_LIBS_FE = @LDAP_LIBS_FE@ LDAP_LIBS_BE = @LDAP_LIBS_BE@ -OSSP_UUID_LIBS = @OSSP_UUID_LIBS@ LD = @LD@ with_gnu_ld = @with_gnu_ld@ ld_R_works = @ld_R_works@ diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index db930f5..fc959a8 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -339,9 +339,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H -/* Define to 1 if you have the header file. */ -#undef HAVE_OSSP_UUID_H - /* Define to 1 if you have the header file. */ #undef HAVE_PAM_PAM_APPL_H @@ -602,9 +599,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H +/* Define to 1 if you have BSD uuid support. */ +#undef HAVE_BSD_UUID + +/* Define to 1 if you have Linux uuid support. */ +#undef HAVE_LINUX_UUID + /* Define to 1 if you have the header file. */ #undef HAVE_UUID_H +/* Define to 1 if you have the header file. */ +#undef HAVE_UUID_UUID_H + /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF