xapian-core  1.4.27
uuids.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2008 Lemur Consulting Ltd
5  * Copyright (C) 2013,2015,2016,2017,2018 Olly Betts
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <config.h>
23 
24 #include "uuids.h"
25 
26 #include "xapian/error.h"
27 
28 #include <cerrno>
29 #include <cstring>
30 #include "stringutils.h"
31 
32 #include <sys/types.h>
33 #include "safefcntl.h"
34 #include "safeunistd.h"
35 
36 #ifdef USE_PROC_FOR_UUID
37 # include "safesysstat.h"
38 #elif defined HAVE_UUID_UUID_H
39 # include <exception>
40 # include <uuid/uuid.h>
41 #elif defined HAVE_UUID_H
42 // UUID API on FreeBSD, NetBSD, OpenBSD and AIX.
43 # include <arpa/inet.h> // For htonl() and htons().
44 # include <exception>
45 # include <uuid.h>
46 #elif defined USE_WIN32_UUID_API
47 # include "safewindows.h"
48 # include <rpc.h>
49 # ifdef __WIN32__
50 # include "safewinsock2.h" // For htonl() and htons().
51 # else
52 // Cygwin:
53 # include <arpa/inet.h> // For htonl() and htons().
54 # endif
55 #endif
56 
57 using namespace std;
58 
60 static constexpr unsigned UUID_GAP_MASK = 0x2a8;
61 
62 void
64 {
65 #ifdef USE_PROC_FOR_UUID
66  char buf[STRING_SIZE];
67  int fd = open("/proc/sys/kernel/random/uuid", O_RDONLY);
68  if (rare(fd == -1)) {
69  throw Xapian::DatabaseCreateError("Opening UUID generator failed", errno);
70  }
71  bool failed = (read(fd, buf, STRING_SIZE) != STRING_SIZE);
72  close(fd);
73  if (failed) {
74  throw Xapian::DatabaseCreateError("Generating UUID failed");
75  }
76  parse(buf);
77 #elif defined HAVE_UUID_UUID_H
78  uuid_t uu;
79  uuid_generate(uu);
80  memcpy(uuid_data, &uu, BINARY_SIZE);
81 #elif defined HAVE_UUID_H
82  uuid_t uu;
83  uint32_t status;
84  uuid_create(&uu, &status);
85  if (status != uuid_s_ok) {
86  // Can only be uuid_s_no_memory it seems.
87  throw std::bad_alloc();
88  }
89  uu.time_low = htonl(uu.time_low);
90  uu.time_mid = htons(uu.time_mid);
91  uu.time_hi_and_version = htons(uu.time_hi_and_version);
92  memcpy(uuid_data, &uu, BINARY_SIZE);
93 #elif defined USE_WIN32_UUID_API
94  UUID uuid;
95  if (rare(UuidCreate(&uuid) != RPC_S_OK)) {
96  // Throw a DatabaseCreateError, since we can't make a UUID. The
97  // windows API documentation is a bit unclear about the situations in
98  // which this can happen.
99  throw Xapian::DatabaseCreateError("Cannot create UUID");
100  }
101  uuid.Data1 = htonl(uuid.Data1);
102  uuid.Data2 = htons(uuid.Data2);
103  uuid.Data3 = htons(uuid.Data3);
104  memcpy(uuid_data, &uuid, BINARY_SIZE);
105 #else
106 # error Do not know how to generate UUIDs
107 #endif
108 }
109 
110 void
111 Uuid::parse(const char* in)
112 {
113  for (unsigned i = 0; i != BINARY_SIZE; ++i) {
114  uuid_data[i] = hex_decode(in[0], in[1]);
115  in += ((UUID_GAP_MASK >> i) & 1) | 2;
116  }
117 }
118 
119 string
121 {
122  string result;
123  result.reserve(STRING_SIZE);
124  for (unsigned i = 0; i != BINARY_SIZE; ++i) {
125  unsigned char ch = uuid_data[i];
126  result += "0123456789abcdef"[ch >> 4];
127  result += "0123456789abcdef"[ch & 0x0f];
128  if ((UUID_GAP_MASK >> i) & 1)
129  result += '-';
130  }
131  return result;
132 }
int close(FD &fd)
Definition: fd.h:63
WritableDatabase open()
Construct a WritableDatabase object for a new, empty InMemory database.
Definition: dbfactory.h:104
static constexpr unsigned UUID_GAP_MASK
Bit-mask to determine where to put hyphens in the string representation.
Definition: uuids.cc:60
STL namespace.
#define rare(COND)
Definition: config.h:575
include <sys/stat.h> with portability enhancements
Hierarchy of classes which Xapian can throw as exceptions.
DatabaseCreateError indicates a failure to create a database.
Definition: error.h:451
include <winsock2.h> but working around problems.
std::string to_string() const
Definition: uuids.cc:120
void parse(const char *in)
Definition: uuids.cc:111
include <windows.h> without all the bloat and damage.
char hex_decode(char ch1, char ch2)
Decode a pair of ASCII hex digits.
Definition: stringutils.h:243
Various handy helpers which std::string really should provide.
Class for handling UUIDs.
<unistd.h>, but with compat.
include <fcntl.h>, but working around broken platforms.
void generate()
Definition: uuids.cc:63