1126a8a12Smrg/*
2126a8a12Smrg
36bea0e4fSmrgCopyright (c) 2002, Oracle and/or its affiliates.
4555991fdSmrg
5555991fdSmrgPermission is hereby granted, free of charge, to any person obtaining a
6555991fdSmrgcopy of this software and associated documentation files (the "Software"),
7555991fdSmrgto deal in the Software without restriction, including without limitation
8555991fdSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
9555991fdSmrgand/or sell copies of the Software, and to permit persons to whom the
10555991fdSmrgSoftware is furnished to do so, subject to the following conditions:
11555991fdSmrg
12555991fdSmrgThe above copyright notice and this permission notice (including the next
13555991fdSmrgparagraph) shall be included in all copies or substantial portions of the
14555991fdSmrgSoftware.
15555991fdSmrg
16555991fdSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17555991fdSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18555991fdSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19555991fdSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20555991fdSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21555991fdSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22555991fdSmrgDEALINGS IN THE SOFTWARE.
23555991fdSmrg
24555991fdSmrg*/
25555991fdSmrg/*
26555991fdSmrg
27126a8a12SmrgCopyright 1993, 1998  The Open Group
28126a8a12Smrg
29126a8a12SmrgPermission to use, copy, modify, distribute, and sell this software and its
30126a8a12Smrgdocumentation for any purpose is hereby granted without fee, provided that
31126a8a12Smrgthe above copyright notice appear in all copies and that both that
32126a8a12Smrgcopyright notice and this permission notice appear in supporting
33126a8a12Smrgdocumentation.
34126a8a12Smrg
35126a8a12SmrgThe above copyright notice and this permission notice shall be included in
36126a8a12Smrgall copies or substantial portions of the Software.
37126a8a12Smrg
38126a8a12SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39126a8a12SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40126a8a12SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
41126a8a12SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
42126a8a12SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
43126a8a12SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44126a8a12Smrg
45126a8a12SmrgExcept as contained in this notice, the name of The Open Group shall not be
46126a8a12Smrgused in advertising or otherwise to promote the sale, use or other dealings
47126a8a12Smrgin this Software without prior written authorization from The Open Group.
48126a8a12Smrg
49126a8a12Smrg*/
50126a8a12Smrg
51126a8a12Smrg/*
52126a8a12Smrg * Author: Ralph Mor, X Consortium
53126a8a12Smrg */
54126a8a12Smrg
55126a8a12Smrg#ifdef WIN32
563c15da26Smrg# define _WILLWINSOCK_
57126a8a12Smrg#endif
58126a8a12Smrg#ifdef HAVE_CONFIG_H
593c15da26Smrg# include <config.h>
60126a8a12Smrg#endif
61126a8a12Smrg#include <X11/SM/SMlib.h>
62126a8a12Smrg#include "SMlibint.h"
63126a8a12Smrg#ifdef XTHREADS
643c15da26Smrg# include <X11/Xthreads.h>
65126a8a12Smrg#endif
66126a8a12Smrg#include <stdio.h>
67300346aeSmrg#include <unistd.h>
68126a8a12Smrg
69126a8a12Smrg#include <time.h>
70126a8a12Smrg#define Time_t time_t
71126a8a12Smrg
726bea0e4fSmrg#if defined(HAVE_UUID_CREATE)
736bea0e4fSmrg# include <uuid.h>
746bea0e4fSmrg#elif defined(HAVE_LIBUUID)
756bea0e4fSmrg# include <uuid/uuid.h>
766bea0e4fSmrg#else
77126a8a12Smrg
786bea0e4fSmrg# ifndef WIN32
79126a8a12Smrg
806bea0e4fSmrg#  ifdef TCPCONN
816bea0e4fSmrg#   include <sys/socket.h>
826bea0e4fSmrg#   include <netinet/in.h>
836bea0e4fSmrg#   include <arpa/inet.h>
846bea0e4fSmrg#   define XOS_USE_NO_LOCKING
856bea0e4fSmrg#   define X_INCLUDE_NETDB_H
866bea0e4fSmrg#   include <X11/Xos_r.h>
876bea0e4fSmrg#  endif
88126a8a12Smrg
896bea0e4fSmrg# else /* WIN32 */
90126a8a12Smrg
916bea0e4fSmrg#  include <X11/Xwinsock.h>
926bea0e4fSmrg#  include <X11/Xw32defs.h>
936bea0e4fSmrg#  define X_INCLUDE_NETDB_H
946bea0e4fSmrg#  define XOS_USE_MTSAFE_NETDBAPI
956bea0e4fSmrg#  include <X11/Xos_r.h>
96126a8a12Smrg
976bea0e4fSmrg# endif /* WIN32 */
98126a8a12Smrg
996bea0e4fSmrg# if defined(IPv6) && !defined(AF_INET6)
1006bea0e4fSmrg#  error "Cannot build IPv6 support without AF_INET6"
1016bea0e4fSmrg# endif
102126a8a12Smrg
1036bea0e4fSmrg#endif /* !(HAVE_UUID_CREATE || HAVE_LIBUUID) */
104d656433aSmrg
105126a8a12Smrg
106126a8a12Smrgchar *
107d656433aSmrgSmsGenerateClientID(SmsConn smsConn)
108126a8a12Smrg{
109d656433aSmrg#if defined(HAVE_UUID_CREATE)
110d656433aSmrg    char *id;
111300346aeSmrg    char *temp;
112d656433aSmrg    uuid_t uuid;
113d656433aSmrg    uint32_t status;
114300346aeSmrg    size_t len;
115d656433aSmrg
116d656433aSmrg    uuid_create(&uuid, &status);
117d656433aSmrg
118d656433aSmrg    uuid_to_string(&uuid, &temp, &status);
119d656433aSmrg
120300346aeSmrg    len = strlen(temp) + 2;
121300346aeSmrg    if ((id = malloc(len)) != NULL)
122300346aeSmrg        snprintf(id, len, "2%s", temp);
123d656433aSmrg
124d656433aSmrg    free(temp);
125d656433aSmrg
126d656433aSmrg    return id;
127d656433aSmrg#elif defined(HAVE_LIBUUID)
128d656433aSmrg    char *id;
129d656433aSmrg    char temp[256];
130d656433aSmrg    uuid_t uuid;
131d656433aSmrg
132d656433aSmrg    uuid_generate(uuid);
133d656433aSmrg
134d656433aSmrg    temp[0] = '2';
135d656433aSmrg    temp[1] = '\0';
136d656433aSmrg    uuid_unparse_lower(uuid, &temp[1]);
137d656433aSmrg
1383c15da26Smrg    id = strdup (temp);
139d656433aSmrg
140d656433aSmrg    return id;
1416bea0e4fSmrg#elif defined(TCPCONN)
142126a8a12Smrg    static const char hex[] = "0123456789abcdef";
143126a8a12Smrg    char hostname[256];
144126a8a12Smrg    char address[64], *addr_ptr = address;
145126a8a12Smrg    char temp[256];
146126a8a12Smrg    char *id;
147126a8a12Smrg    static int sequence = 0;
148126a8a12Smrg    char* inet_addr;
1493c15da26Smrg    char *ptr1;
150126a8a12Smrg    unsigned char decimal[4];
1510a6b08f8Smrg    int i;
152126a8a12Smrg    struct in_addr *haddr = NULL;
1536bea0e4fSmrg# ifdef HAVE_GETADDRINFO
154126a8a12Smrg    struct addrinfo *ai, *first_ai;
1556bea0e4fSmrg# endif
1563c15da26Smrg
1573c15da26Smrg    if (gethostname (hostname, sizeof (hostname)))
1583c15da26Smrg	return (NULL);
1593c15da26Smrg
1606bea0e4fSmrg# ifdef HAVE_GETADDRINFO
161126a8a12Smrg    if (getaddrinfo(hostname,NULL,NULL,&ai) != 0)
162126a8a12Smrg	return NULL;
163126a8a12Smrg
164126a8a12Smrg    for (first_ai = ai; ai != NULL; ai = ai->ai_next) {
1656bea0e4fSmrg	if (ai->ai_family == AF_INET)
1666bea0e4fSmrg	    break;
1676bea0e4fSmrg#  ifdef IPv6
1686bea0e4fSmrg	if (ai->ai_family == AF_INET6)
169126a8a12Smrg	    break;
1706bea0e4fSmrg#  endif
171126a8a12Smrg    }
172126a8a12Smrg    if (ai == NULL) {
173126a8a12Smrg	freeaddrinfo(first_ai);
174126a8a12Smrg	return NULL;
1753c15da26Smrg    }
176126a8a12Smrg
1776bea0e4fSmrg#  ifdef IPv6
178126a8a12Smrg    if (ai->ai_family == AF_INET6) {
179126a8a12Smrg	unsigned char *cp = (unsigned char *) &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr.s6_addr;
1803c15da26Smrg
181126a8a12Smrg	*addr_ptr++ = '6';	/* IPv6 address code */
182126a8a12Smrg
183126a8a12Smrg	for (i = 0 ; i < 16 ; i++) {
184126a8a12Smrg            *addr_ptr++ = hex[cp[i] >> 4];
185126a8a12Smrg            *addr_ptr++ = hex[cp[i] & 0x0f];
186126a8a12Smrg	}
187126a8a12Smrg
188126a8a12Smrg        *addr_ptr++ = '\0';
1896bea0e4fSmrg    } else  /* Fall through to IPv4 address handling */
1906bea0e4fSmrg#  endif /* IPv6 */
1916bea0e4fSmrg    {
192126a8a12Smrg	haddr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
1936bea0e4fSmrg# else /* !HAVE_GETADDRINFO */
1946bea0e4fSmrg#  ifdef XTHREADS_NEEDS_BYNAMEPARAMS
1953c15da26Smrg	_Xgethostbynameparams hparams;
1966bea0e4fSmrg#  endif
1973c15da26Smrg	struct hostent *hostp;
1983c15da26Smrg
1993c15da26Smrg	if ((hostp = _XGethostbyname (hostname,hparams)) != NULL)
2003c15da26Smrg	    haddr = (struct in_addr *)(hostp->h_addr);
2013c15da26Smrg	else
2023c15da26Smrg	    return NULL;
2036bea0e4fSmrg# endif /* !HAVE_GETADDRINFO */
2046bea0e4fSmrg
2056bea0e4fSmrg	*addr_ptr++ = '1';
2063c15da26Smrg
2073c15da26Smrg	{
2086bea0e4fSmrg	    unsigned char *cp = (unsigned char *) &(haddr->s_addr);
2093c15da26Smrg
2106bea0e4fSmrg	    for (i = 0; i < 4; i++) {
2116bea0e4fSmrg		*addr_ptr++ = hex[cp[i] >> 4];
2126bea0e4fSmrg		*addr_ptr++ = hex[cp[i] & 0x0f];
2133c15da26Smrg	    }
2143c15da26Smrg	}
215126a8a12Smrg
2163c15da26Smrg	*addr_ptr++ = '\0';
217126a8a12Smrg
2186bea0e4fSmrg# ifdef HAVE_GETADDRINFO
219126a8a12Smrg    }
220126a8a12Smrg    freeaddrinfo(first_ai);
2216bea0e4fSmrg# endif
222126a8a12Smrg
223126a8a12Smrg    sprintf (temp, "1%s%.13ld%.10ld%.4d", address, (long)time((Time_t*)0),
224126a8a12Smrg	     (long)getpid(), sequence);
225126a8a12Smrg
226126a8a12Smrg    if (++sequence > 9999)
227126a8a12Smrg	sequence = 0;
228126a8a12Smrg
2293c15da26Smrg    id = strdup (temp);
230126a8a12Smrg
231126a8a12Smrg    return (id);
2326bea0e4fSmrg#else /* no supported id generation method, neither UUID nor TCPCONN */
233126a8a12Smrg    return (NULL);
234d656433aSmrg#endif
235126a8a12Smrg}
236