1 /*
2 **  OSSP uuid - Universally Unique Identifier
3 **  Copyright (c) 2004-2008 Ralf S. Engelschall <rse@engelschall.com>
4 **  Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/>
5 **
6 **  This file is part of OSSP uuid, a library for the generation
7 **  of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
8 **
9 **  Permission to use, copy, modify, and distribute this software for
10 **  any purpose with or without fee is hereby granted, provided that
11 **  the above copyright notice and this permission notice appear in all
12 **  copies.
13 **
14 **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
15 **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
18 **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 **  SUCH DAMAGE.
26 **
27 **  uuid_dce.c: DCE 1.1 compatibility API implementation
28 */
29 
30 /* include DCE 1.1 API */
31 #define uuid_t uuid_dce_t
32 #include "uuid_dce.h"
33 #undef uuid_t
34 #undef uuid_create
35 #undef uuid_create_nil
36 #undef uuid_is_nil
37 #undef uuid_compare
38 #undef uuid_equal
39 #undef uuid_from_string
40 #undef uuid_to_string
41 #undef uuid_hash
42 
43 /* include regular API */
44 #include "uuid.h"
45 
46 /* helper macro */
47 #define LEAVE /*lint -save -e801*/ goto leave /*lint -restore*/
48 
49 /* create a UUID (v1 only) */
uuid_dce_create(uuid_dce_t * uuid_dce,int * status)50 void uuid_dce_create(uuid_dce_t *uuid_dce, int *status)
51 {
52     uuid_t *uuid;
53     size_t len;
54     void *vp;
55 
56     /* initialize status */
57     if (status != NULL)
58         *status = uuid_s_error;
59 
60     /* sanity check argument(s) */
61     if (uuid_dce == NULL)
62         return;
63 
64     /* create UUID and export as binary representation */
65     if (uuid_create(&uuid) != UUID_RC_OK)
66         return;
67     if (uuid_make(uuid, UUID_MAKE_V1) != UUID_RC_OK) {
68         uuid_destroy(uuid);
69         return;
70     }
71     vp  = uuid_dce;
72     len = UUID_LEN_BIN;
73     if (uuid_export(uuid, UUID_FMT_BIN, &vp, &len) != UUID_RC_OK) {
74         uuid_destroy(uuid);
75         return;
76     }
77     uuid_destroy(uuid);
78 
79     /* return successfully */
80     if (status != NULL)
81         *status = uuid_s_ok;
82     return;
83 }
84 
85 /* create a Nil UUID */
uuid_dce_create_nil(uuid_dce_t * uuid_dce,int * status)86 void uuid_dce_create_nil(uuid_dce_t *uuid_dce, int *status)
87 {
88     /* initialize status */
89     if (status != NULL)
90         *status = uuid_s_error;
91 
92     /* sanity check argument(s) */
93     if (uuid_dce == NULL)
94         return;
95 
96     /* short-circuit implementation, because Nil UUID is trivial to
97        create, so no need to use regular OSSP uuid API */
98     memset(uuid_dce, 0, UUID_LEN_BIN);
99 
100     /* return successfully */
101     if (status != NULL)
102         *status = uuid_s_ok;
103     return;
104 }
105 
106 /* check whether it is Nil UUID */
uuid_dce_is_nil(uuid_dce_t * uuid_dce,int * status)107 int uuid_dce_is_nil(uuid_dce_t *uuid_dce, int *status)
108 {
109     int i;
110     int result;
111     unsigned char *ucp;
112 
113     /* initialize status */
114     if (status != NULL)
115         *status = uuid_s_error;
116 
117     /* sanity check argument(s) */
118     if (uuid_dce == NULL)
119         return 0;
120 
121     /* short-circuit implementation, because Nil UUID is trivial to
122        check, so no need to use regular OSSP uuid API */
123     result = 1;
124     ucp = (unsigned char *)uuid_dce;
125     for (i = 0; i < UUID_LEN_BIN; i++) {
126         if (ucp[i] != '\0') {
127             result = 0;
128             break;
129         }
130     }
131 
132     /* return successfully with result */
133     if (status != NULL)
134         *status = uuid_s_ok;
135     return result;
136 }
137 
138 /* compare two UUIDs */
uuid_dce_compare(uuid_dce_t * uuid_dce1,uuid_dce_t * uuid_dce2,int * status)139 int uuid_dce_compare(uuid_dce_t *uuid_dce1, uuid_dce_t *uuid_dce2, int *status)
140 {
141     uuid_t *uuid1 = NULL;
142     uuid_t *uuid2 = NULL;
143     int result = 0;
144 
145     /* initialize status */
146     if (status != NULL)
147         *status = uuid_s_error;
148 
149     /* sanity check argument(s) */
150     if (uuid_dce1 == NULL || uuid_dce2 == NULL)
151         return 0;
152 
153     /* import both UUID binary representations and compare them */
154     if (uuid_create(&uuid1) != UUID_RC_OK)
155         LEAVE;
156     if (uuid_create(&uuid2) != UUID_RC_OK)
157         LEAVE;
158     if (uuid_import(uuid1, UUID_FMT_BIN, uuid_dce1, UUID_LEN_BIN) != UUID_RC_OK)
159         LEAVE;
160     if (uuid_import(uuid2, UUID_FMT_BIN, uuid_dce2, UUID_LEN_BIN) != UUID_RC_OK)
161         LEAVE;
162     if (uuid_compare(uuid1, uuid2, &result) != UUID_RC_OK)
163         LEAVE;
164 
165     /* indicate successful operation */
166     if (status != NULL)
167         *status = uuid_s_ok;
168 
169     /* cleanup and return */
170     leave:
171     if (uuid1 != NULL)
172         uuid_destroy(uuid1);
173     if (uuid2 != NULL)
174         uuid_destroy(uuid2);
175     return result;
176 }
177 
178 /* compare two UUIDs (equality only) */
uuid_dce_equal(uuid_dce_t * uuid_dce1,uuid_dce_t * uuid_dce2,int * status)179 int uuid_dce_equal(uuid_dce_t *uuid_dce1, uuid_dce_t *uuid_dce2, int *status)
180 {
181     /* initialize status */
182     if (status != NULL)
183         *status = uuid_s_error;
184 
185     /* sanity check argument(s) */
186     if (uuid_dce1 == NULL || uuid_dce2 == NULL)
187         return 0;
188 
189     /* pass through to generic compare function */
190     return (uuid_dce_compare(uuid_dce1, uuid_dce2, status) == 0 ? 1 : 0);
191 }
192 
193 /* import UUID from string representation */
uuid_dce_from_string(const char * str,uuid_dce_t * uuid_dce,int * status)194 void uuid_dce_from_string(const char *str, uuid_dce_t *uuid_dce, int *status)
195 {
196     uuid_t *uuid = NULL;
197     size_t len;
198     void *vp;
199 
200     /* initialize status */
201     if (status != NULL)
202         *status = uuid_s_error;
203 
204     /* sanity check argument(s) */
205     if (str == NULL || uuid_dce == NULL)
206         return;
207 
208     /* import string representation and export binary representation */
209     if (uuid_create(&uuid) != UUID_RC_OK)
210         LEAVE;
211     if (uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR) != UUID_RC_OK)
212         LEAVE;
213     vp  = uuid_dce;
214     len = UUID_LEN_BIN;
215     if (uuid_export(uuid, UUID_FMT_BIN, &vp, &len) != UUID_RC_OK)
216         LEAVE;
217 
218     /* indicate successful operation */
219     if (status != NULL)
220         *status = uuid_s_ok;
221 
222     /* cleanup and return */
223     leave:
224     if (uuid != NULL)
225         uuid_destroy(uuid);
226     return;
227 }
228 
229 /* export UUID to string representation */
uuid_dce_to_string(uuid_dce_t * uuid_dce,char ** str,int * status)230 void uuid_dce_to_string(uuid_dce_t *uuid_dce, char **str, int *status)
231 {
232     uuid_t *uuid = NULL;
233     size_t len;
234     void *vp;
235 
236     /* initialize status */
237     if (status != NULL)
238         *status = uuid_s_error;
239 
240     /* sanity check argument(s) */
241     if (str == NULL || uuid_dce == NULL)
242         return;
243 
244     /* import binary representation and export string representation */
245     if (uuid_create(&uuid) != UUID_RC_OK)
246         LEAVE;
247     if (uuid_import(uuid, UUID_FMT_BIN, uuid_dce, UUID_LEN_BIN) != UUID_RC_OK)
248         LEAVE;
249     vp  = str;
250     len = UUID_LEN_STR;
251     if (uuid_export(uuid, UUID_FMT_STR, &vp, &len) != UUID_RC_OK)
252         LEAVE;
253 
254     /* indicate successful operation */
255     if (status != NULL)
256         *status = uuid_s_ok;
257 
258     /* cleanup and return */
259     leave:
260     if (uuid != NULL)
261         uuid_destroy(uuid);
262     return;
263 }
264 
265 /* export UUID into hash value */
uuid_dce_hash(uuid_dce_t * uuid_dce,int * status)266 unsigned int uuid_dce_hash(uuid_dce_t *uuid_dce, int *status)
267 {
268     int i;
269     unsigned char *ucp;
270     unsigned int hash;
271 
272     /* initialize status */
273     if (status != NULL)
274         *status = uuid_s_error;
275 
276     /* sanity check argument(s) */
277     if (uuid_dce == NULL)
278         return 0;
279 
280     /* generate a hash value
281        (DCE 1.1 actually requires 16-bit only) */
282     hash = 0;
283     ucp = (unsigned char *)uuid_dce;
284     for (i = UUID_LEN_BIN-1; i >= 0; i--) {
285         hash <<= 8;
286         hash |= ucp[i];
287     }
288 
289     /* return successfully */
290     if (status != NULL)
291         *status = uuid_s_ok;
292     return hash;
293 }
294 
295