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