sm_genid.c revision 0a6b08f8
1/*
2
3Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8the rights to use, copy, modify, merge, publish, distribute, sublicense,
9and/or sell copies of the Software, and to permit persons to whom the
10Software is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice (including the next
13paragraph) shall be included in all copies or substantial portions of the
14Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22DEALINGS IN THE SOFTWARE.
23
24*/
25/*
26
27Copyright 1993, 1998  The Open Group
28
29Permission to use, copy, modify, distribute, and sell this software and its
30documentation for any purpose is hereby granted without fee, provided that
31the above copyright notice appear in all copies and that both that
32copyright notice and this permission notice appear in supporting
33documentation.
34
35The above copyright notice and this permission notice shall be included in
36all copies or substantial portions of the Software.
37
38THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
41OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
42AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
43CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44
45Except as contained in this notice, the name of The Open Group shall not be
46used in advertising or otherwise to promote the sale, use or other dealings
47in this Software without prior written authorization from The Open Group.
48
49*/
50
51/*
52 * Author: Ralph Mor, X Consortium
53 */
54
55#ifdef WIN32
56# define _WILLWINSOCK_
57#endif
58#ifdef HAVE_CONFIG_H
59# include <config.h>
60#endif
61#include <X11/SM/SMlib.h>
62#include "SMlibint.h"
63#ifdef XTHREADS
64# include <X11/Xthreads.h>
65#endif
66#include <stdio.h>
67
68#include <time.h>
69#define Time_t time_t
70
71#ifndef WIN32
72
73# ifdef TCPCONN
74#  include <sys/socket.h>
75#  include <netinet/in.h>
76#  include <arpa/inet.h>
77#  define XOS_USE_NO_LOCKING
78#  define X_INCLUDE_NETDB_H
79#  include <X11/Xos_r.h>
80# endif
81
82#else /* WIN32 */
83
84# include <X11/Xwinsock.h>
85# include <X11/Xw32defs.h>
86# define X_INCLUDE_NETDB_H
87# define XOS_USE_MTSAFE_NETDBAPI
88# include <X11/Xos_r.h>
89
90#endif /* WIN32 */
91
92#ifdef MNX_TCPCONN
93# include <net/gen/netdb.h>
94
95# define TCPCONN
96#endif
97
98#if defined(HAVE_UUID_CREATE)
99# include <uuid.h>
100#elif defined(HAVE_LIBUUID)
101# include <uuid/uuid.h>
102#endif
103
104
105char *
106SmsGenerateClientID(SmsConn smsConn)
107{
108#if defined(HAVE_UUID_CREATE)
109    char *id;
110    char **temp;
111    uuid_t uuid;
112    uint32_t status;
113
114    uuid_create(&uuid, &status);
115
116    uuid_to_string(&uuid, &temp, &status);
117
118    if ((id = malloc (strlen (temp) + 2)) != NULL)
119    {
120        id[0] = '2';
121        strcpy (id+1, temp);
122    }
123
124    free(temp);
125
126    return id;
127#elif defined(HAVE_LIBUUID)
128    char *id;
129    char temp[256];
130    uuid_t uuid;
131
132    uuid_generate(uuid);
133
134    temp[0] = '2';
135    temp[1] = '\0';
136    uuid_unparse_lower(uuid, &temp[1]);
137
138    id = strdup (temp);
139
140    return id;
141#else
142# ifdef TCPCONN
143    static const char hex[] = "0123456789abcdef";
144    char hostname[256];
145    char address[64], *addr_ptr = address;
146    char temp[256];
147    char *id;
148    static int sequence = 0;
149    char* inet_addr;
150    char *ptr1;
151    unsigned char decimal[4];
152    int i;
153    struct in_addr *haddr = NULL;
154#  if defined(IPv6) && defined(AF_INET6)
155    struct addrinfo *ai, *first_ai;
156#  endif
157
158    if (gethostname (hostname, sizeof (hostname)))
159	return (NULL);
160
161#  if defined(IPv6) && defined(AF_INET6)
162    if (getaddrinfo(hostname,NULL,NULL,&ai) != 0)
163	return NULL;
164
165    for (first_ai = ai; ai != NULL; ai = ai->ai_next) {
166	if ( (ai->ai_family == AF_INET) || (ai->ai_family == AF_INET6) )
167	    break;
168    }
169    if (ai == NULL) {
170	freeaddrinfo(first_ai);
171	return NULL;
172    }
173
174    if (ai->ai_family == AF_INET6) {
175	unsigned char *cp = (unsigned char *) &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr;
176
177	*addr_ptr++ = '6';	/* IPv6 address code */
178
179	for (i = 0 ; i < 16 ; i++) {
180            *addr_ptr++ = hex[cp[i] >> 4];
181            *addr_ptr++ = hex[cp[i] & 0x0f];
182	}
183
184        *addr_ptr++ = '\0';
185
186    } else { /* Fall through to IPv4 address handling */
187	haddr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
188#  else
189#   ifdef XTHREADS_NEEDS_BYNAMEPARAMS
190	_Xgethostbynameparams hparams;
191#   endif
192	struct hostent *hostp;
193
194	if ((hostp = _XGethostbyname (hostname,hparams)) != NULL)
195	    haddr = (struct in_addr *)(hostp->h_addr);
196	else
197	    return NULL;
198#  endif
199
200	inet_addr = inet_ntoa (*haddr);
201	for (i = 0, ptr1 = inet_addr; i < 3; i++)
202	{
203	    char temp4[4];
204	    char *ptr2 = strchr (ptr1, '.');
205	    size_t len = (size_t) (ptr2 - ptr1);
206
207	    if (!ptr2 || len > 3) {
208#  if defined(IPv6) && defined(AF_INET6)
209		freeaddrinfo(first_ai);
210#  endif
211		return (NULL);
212	    }
213	    strncpy (temp4, ptr1, len);
214	    temp4[len] = '\0';
215	    decimal[i] = (unsigned char) atoi (temp4);
216	    ptr1 = ptr2 + 1;
217	}
218
219	decimal[3] = (unsigned char) atoi (ptr1);
220
221	*addr_ptr++ = '1';
222
223	for (i = 0; i < 4; i++) {
224	    *addr_ptr++ = hex[decimal[i] >> 4];
225	    *addr_ptr++ = hex[decimal[i] & 0x0f];
226	}
227
228	*addr_ptr++ = '\0';
229
230#  if defined(IPv6) && defined(AF_INET6)
231    }
232    freeaddrinfo(first_ai);
233#  endif
234
235    sprintf (temp, "1%s%.13ld%.10ld%.4d", address, (long)time((Time_t*)0),
236	     (long)getpid(), sequence);
237
238    if (++sequence > 9999)
239	sequence = 0;
240
241    id = strdup (temp);
242
243    return (id);
244# else
245    return (NULL);
246# endif
247#endif
248}
249