1/* 2 3Copyright (c) 2002, Oracle and/or its affiliates. 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#include <unistd.h> 68 69#include <time.h> 70#define Time_t time_t 71 72#if defined(HAVE_UUID_CREATE) 73# include <uuid.h> 74#elif defined(HAVE_LIBUUID) 75# include <uuid/uuid.h> 76#else 77 78# ifndef WIN32 79 80# ifdef TCPCONN 81# include <sys/socket.h> 82# include <netinet/in.h> 83# include <arpa/inet.h> 84# define XOS_USE_NO_LOCKING 85# define X_INCLUDE_NETDB_H 86# include <X11/Xos_r.h> 87# endif 88 89# else /* WIN32 */ 90 91# include <X11/Xwinsock.h> 92# include <X11/Xw32defs.h> 93# define X_INCLUDE_NETDB_H 94# define XOS_USE_MTSAFE_NETDBAPI 95# include <X11/Xos_r.h> 96 97# endif /* WIN32 */ 98 99# if defined(IPv6) && !defined(AF_INET6) 100# error "Cannot build IPv6 support without AF_INET6" 101# endif 102 103#endif /* !(HAVE_UUID_CREATE || HAVE_LIBUUID) */ 104 105 106char * 107SmsGenerateClientID(SmsConn smsConn) 108{ 109#if defined(HAVE_UUID_CREATE) 110 char *id; 111 char *temp; 112 uuid_t uuid; 113 uint32_t status; 114 size_t len; 115 116 uuid_create(&uuid, &status); 117 118 uuid_to_string(&uuid, &temp, &status); 119 120 len = strlen(temp) + 2; 121 if ((id = malloc(len)) != NULL) 122 snprintf(id, len, "2%s", temp); 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#elif defined(TCPCONN) 142 static const char hex[] = "0123456789abcdef"; 143 char hostname[256]; 144 char address[64], *addr_ptr = address; 145 char temp[256]; 146 char *id; 147 static int sequence = 0; 148 char* inet_addr; 149 char *ptr1; 150 unsigned char decimal[4]; 151 int i; 152 struct in_addr *haddr = NULL; 153# ifdef HAVE_GETADDRINFO 154 struct addrinfo *ai, *first_ai; 155# endif 156 157 if (gethostname (hostname, sizeof (hostname))) 158 return (NULL); 159 160# ifdef HAVE_GETADDRINFO 161 if (getaddrinfo(hostname,NULL,NULL,&ai) != 0) 162 return NULL; 163 164 for (first_ai = ai; ai != NULL; ai = ai->ai_next) { 165 if (ai->ai_family == AF_INET) 166 break; 167# ifdef IPv6 168 if (ai->ai_family == AF_INET6) 169 break; 170# endif 171 } 172 if (ai == NULL) { 173 freeaddrinfo(first_ai); 174 return NULL; 175 } 176 177# ifdef IPv6 178 if (ai->ai_family == AF_INET6) { 179 unsigned char *cp = (unsigned char *) &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr; 180 181 *addr_ptr++ = '6'; /* IPv6 address code */ 182 183 for (i = 0 ; i < 16 ; i++) { 184 *addr_ptr++ = hex[cp[i] >> 4]; 185 *addr_ptr++ = hex[cp[i] & 0x0f]; 186 } 187 188 *addr_ptr++ = '\0'; 189 } else /* Fall through to IPv4 address handling */ 190# endif /* IPv6 */ 191 { 192 haddr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr; 193# else /* !HAVE_GETADDRINFO */ 194# ifdef XTHREADS_NEEDS_BYNAMEPARAMS 195 _Xgethostbynameparams hparams; 196# endif 197 struct hostent *hostp; 198 199 if ((hostp = _XGethostbyname (hostname,hparams)) != NULL) 200 haddr = (struct in_addr *)(hostp->h_addr); 201 else 202 return NULL; 203# endif /* !HAVE_GETADDRINFO */ 204 205 *addr_ptr++ = '1'; 206 207 { 208 unsigned char *cp = (unsigned char *) &(haddr->s_addr); 209 210 for (i = 0; i < 4; i++) { 211 *addr_ptr++ = hex[cp[i] >> 4]; 212 *addr_ptr++ = hex[cp[i] & 0x0f]; 213 } 214 } 215 216 *addr_ptr++ = '\0'; 217 218# ifdef HAVE_GETADDRINFO 219 } 220 freeaddrinfo(first_ai); 221# endif 222 223 sprintf (temp, "1%s%.13ld%.10ld%.4d", address, (long)time((Time_t*)0), 224 (long)getpid(), sequence); 225 226 if (++sequence > 9999) 227 sequence = 0; 228 229 id = strdup (temp); 230 231 return (id); 232#else /* no supported id generation method, neither UUID nor TCPCONN */ 233 return (NULL); 234#endif 235} 236