trying to get HEAD building again. If you want the code
[samba.git] / source / lib / util_uuid.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  UUID server routines
4  *  Copyright (C) Theodore Ts'o               1996, 1997,
5  *  Copyright (C) Jim McDonough                     2002.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include "includes.h"
23
24 /*
25  * Offset between 15-Oct-1582 and 1-Jan-70
26  */
27 #define TIME_OFFSET_HIGH 0x01B21DD2
28 #define TIME_OFFSET_LOW  0x13814000
29
30 struct uuid {
31         uint32   time_low;
32         uint16   time_mid;
33         uint16   time_hi_and_version;
34         uint8    clock_seq[2];
35         uint8    node[6];
36 };
37
38
39 static void uuid_pack(const struct uuid *uu, GUID *ptr)
40 {
41         uint8 *out = ptr->info;
42
43         SIVAL(out, 0, uu->time_low);
44         SSVAL(out, 4, uu->time_mid);
45         SSVAL(out, 6, uu->time_hi_and_version);
46         memcpy(out+8, uu->clock_seq, 2);
47         memcpy(out+10, uu->node, 6);
48 }
49
50 static void uuid_unpack(const GUID in, struct uuid *uu)
51 {
52         const uint8 *ptr = in.info;
53
54         uu->time_low = IVAL(ptr, 0);
55         uu->time_mid = SVAL(ptr, 4);
56         uu->time_hi_and_version = SVAL(ptr, 6);
57         memcpy(uu->clock_seq, ptr+8, 2);
58         memcpy(uu->node, ptr+10, 6);
59 }
60
61 void smb_uuid_generate_random(GUID *out)
62 {
63         GUID tmp;
64         struct uuid uu;
65
66         generate_random_buffer(tmp.info, sizeof(tmp.info), True);
67         uuid_unpack(tmp, &uu);
68
69         uu.clock_seq[0] = (uu.clock_seq[0] & 0x3F) | 0x80;
70         uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
71         uuid_pack(&uu, out);
72 }
73
74 char *smb_uuid_to_string(const GUID in)
75 {
76         struct uuid uu;
77         char *out;
78
79         uuid_unpack(in, &uu);
80         
81         asprintf(&out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
82                  uu.time_low, uu.time_mid, uu.time_hi_and_version,
83                  uu.clock_seq[0], uu.clock_seq[1],
84                  uu.node[0], uu.node[1], uu.node[2], 
85                  uu.node[3], uu.node[4], uu.node[5]);
86
87         return out;
88 }
89
90 const char *smb_uuid_string_static(const GUID in)
91 {
92         struct uuid uu;
93         static char out[37];
94
95         uuid_unpack(in, &uu);
96         slprintf(out, sizeof(out) -1, 
97                  "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
98                  uu.time_low, uu.time_mid, uu.time_hi_and_version,
99                  uu.clock_seq[0], uu.clock_seq[1],
100                  uu.node[0], uu.node[1], uu.node[2], 
101                  uu.node[3], uu.node[4], uu.node[5]);
102         return out;
103 }