From a63faf6fa95017dbbfeaf0ff43fdb526c4ae7068 Mon Sep 17 00:00:00 2001
From: Florent Le Coz <louiz@louiz.org>
Date: Fri, 30 May 2014 13:39:00 +0200
Subject: Use libuuid to generate unique IDs for iq and adhoc sessions

---
 CMakeLists.txt                  |  5 ++++-
 cmake/Modules/FindLibuuid.cmake | 41 +++++++++++++++++++++++++++++++++++++++++
 src/test.cpp                    | 11 ++++++++---
 src/xmpp/xmpp_component.cpp     | 10 +++++++---
 src/xmpp/xmpp_component.hpp     |  2 --
 5 files changed, 60 insertions(+), 9 deletions(-)
 create mode 100644 cmake/Modules/FindLibuuid.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1589399..90b5432 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
 include(FindEXPAT)
 find_package(EXPAT REQUIRED)
 find_package(Iconv REQUIRED)
+find_package(Libuuid REQUIRED)
 find_package(Libidn)
 find_package(SystemdDaemon)
 
@@ -26,6 +27,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/")
 include_directories("${CMAKE_CURRENT_BINARY_DIR}/src/")
 include_directories(${EXPAT_INCLUDE_DIRS})
 include_directories(${ICONV_INCLUDE_DIRS})
+include_directories(${LIBUUID_INCLUDE_DIRS})
 
 if(LIBIDN_FOUND)
   include_directories(${LIBIDN_INCLUDE_DIRS})
@@ -109,7 +111,8 @@ file(GLOB source_xmpp
   src/xmpp/*.[hc]pp)
 add_library(xmpp STATIC ${source_xmpp})
 target_link_libraries(xmpp bridge network utils logger
-  ${EXPAT_LIBRARIES})
+  ${EXPAT_LIBRARIES}
+  ${LIBUUID_LIBRARIES})
 if(LIBIDN_FOUND)
   target_link_libraries(xmpp ${LIBIDN_LIBRARIES})
 endif()
diff --git a/cmake/Modules/FindLibuuid.cmake b/cmake/Modules/FindLibuuid.cmake
new file mode 100644
index 0000000..25b330b
--- /dev/null
+++ b/cmake/Modules/FindLibuuid.cmake
@@ -0,0 +1,41 @@
+# - Find libuuid
+# Find the libuuid library
+#
+# This module defines the following variables:
+#   LIBUUID_FOUND  -  True if library and include directory are found
+# If set to TRUE, the following are also defined:
+#   LIBUUID_INCLUDE_DIRS  -  The directory where to find the header file
+#   LIBUUID_LIBRARIES  -  Where to find the library file
+#
+# For conveniance, these variables are also set. They have the same values
+# than the variables above.  The user can thus choose his/her prefered way
+# to write them.
+#   LIBUUID_INCLUDE_DIR
+#   LIBUUID_LIBRARY
+#
+# This file is in the public domain
+
+include(FindPkgConfig)
+pkg_check_modules(LIBUUID uuid)
+
+if(NOT LIBUUID_FOUND)
+  find_path(LIBUUID_INCLUDE_DIRS NAMES uuid.h
+    PATH uuid
+    DOC "The libuuid include directory")
+
+  find_library(LIBUUID_LIBRARIES NAMES uuid
+    DOC "The libuuid library")
+
+  # Use some standard module to handle the QUIETLY and REQUIRED arguments, and
+  # set LIBUUID_FOUND to TRUE if these two variables are set.
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(LIBUUID REQUIRED_VARS LIBUUID_LIBRARIES LIBUUID_INCLUDE_DIRS)
+
+  # Compatibility for all the ways of writing these variables
+  if(LIBUUID_FOUND)
+    set(LIBUUID_INCLUDE_DIR ${LIBUUID_INCLUDE_DIRS})
+    set(LIBUUID_LIBRARY ${LIBUUID_LIBRARIES})
+  endif()
+endif()
+
+mark_as_advanced(LIBUUID_INCLUDE_DIRS LIBUUID_LIBRARIES)
diff --git a/src/test.cpp b/src/test.cpp
index 8fe739c..ac14377 100644
--- a/src/test.cpp
+++ b/src/test.cpp
@@ -121,9 +121,14 @@ int main()
   /**
    * Id generation
    */
-  assert(XmppComponent::next_id() == "0");
-  assert(XmppComponent::next_id() == "1");
-  assert(XmppComponent::next_id() == "2");
+  std::cout << color << "Testing id generation…" << reset << std::endl;
+  const std::string first_uuid = XmppComponent::next_id();
+  const std::string second_uuid = XmppComponent::next_id();
+  std::cout << first_uuid << std::endl;
+  std::cout << second_uuid << std::endl;
+  assert(first_uuid.size() == 36);
+  assert(second_uuid.size() == 36);
+  assert(first_uuid != second_uuid);
 
   /**
    * Utils
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index 4c62aa7..9547e3a 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -13,14 +13,14 @@
 
 #include <config.h>
 
+#include <uuid.h>
+
 #ifdef SYSTEMDDAEMON_FOUND
 # include <systemd/sd-daemon.h>
 #endif
 
 using namespace std::string_literals;
 
-unsigned long XmppComponent::current_id = 0;
-
 static std::set<std::string> kickable_errors{
     "gone",
     "internal-server-error",
@@ -934,5 +934,9 @@ void XmppComponent::send_iq_version_request(const std::string& from,
 
 std::string XmppComponent::next_id()
 {
-  return std::to_string(XmppComponent::current_id++);
+  char uuid_str[37];
+  uuid_t uuid;
+  uuid_generate(uuid);
+  uuid_unparse(uuid, uuid_str);
+  return uuid_str;
 }
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index b234d76..e3e24e0 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -235,8 +235,6 @@ private:
    */
   std::unordered_map<std::string, std::unique_ptr<Bridge>> bridges;
 
-  static unsigned long current_id;
-
   AdhocCommandsHandler adhoc_commands_handler;
   XmppComponent(const XmppComponent&) = delete;
   XmppComponent(XmppComponent&&) = delete;
-- 
cgit v1.2.3