1/*
2 * tclUnixSock.c --
3 *
4 *	This file contains Unix-specific socket related code.
5 *
6 * Copyright (c) 1995 Sun Microsystems, Inc.
7 *
8 * See the file "license.terms" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 *
11 * RCS: @(#) $Id: tclUnixSock.c,v 1.6.2.4 2006/09/07 09:01:07 vasiljevic Exp $
12 */
13
14#include "tcl.h"
15#include "tclPort.h"
16
17/*
18 * There is no portable macro for the maximum length
19 * of host names returned by gethostbyname().  We should only
20 * trust SYS_NMLN if it is at least 255 + 1 bytes to comply with DNS
21 * host name limits.
22 *
23 * Note:  SYS_NMLN is a restriction on "uname" not on gethostbyname!
24 *
25 * For example HP-UX 10.20 has SYS_NMLN == 9,  while gethostbyname()
26 * can return a fully qualified name from DNS of up to 255 bytes.
27 *
28 * Fix suggested by Viktor Dukhovni (viktor@esm.com)
29 */
30
31#if defined(SYS_NMLN) && SYS_NMLEN >= 256
32#define TCL_HOSTNAME_LEN SYS_NMLEN
33#else
34#define TCL_HOSTNAME_LEN 256
35#endif
36
37
38/*
39 * The following variable holds the network name of this host.
40 */
41
42static char hostname[TCL_HOSTNAME_LEN + 1];
43static int  hostnameInited = 0;
44TCL_DECLARE_MUTEX(hostMutex)
45
46
47/*
48 *----------------------------------------------------------------------
49 *
50 * Tcl_GetHostName --
51 *
52 *	Returns the name of the local host.
53 *
54 * Results:
55 *	A string containing the network name for this machine, or
56 *	an empty string if we can't figure out the name.  The caller
57 *	must not modify or free this string.
58 *
59 * Side effects:
60 *	None.
61 *
62 *----------------------------------------------------------------------
63 */
64
65CONST char *
66Tcl_GetHostName()
67{
68#ifndef NO_UNAME
69    struct utsname u;
70    struct hostent *hp;
71#else
72    char buffer[sizeof(hostname)];
73#endif
74    CONST char *native;
75
76    Tcl_MutexLock(&hostMutex);
77    if (hostnameInited) {
78	Tcl_MutexUnlock(&hostMutex);
79        return hostname;
80    }
81
82    native = NULL;
83#ifndef NO_UNAME
84    (VOID *) memset((VOID *) &u, (int) 0, sizeof(struct utsname));
85    if (uname(&u) > -1) {				/* INTL: Native. */
86        hp = TclpGetHostByName(u.nodename);			/* INTL: Native. */
87	if (hp == NULL) {
88	    /*
89	     * Sometimes the nodename is fully qualified, but gets truncated
90	     * as it exceeds SYS_NMLN.  See if we can just get the immediate
91	     * nodename and get a proper answer that way.
92	     */
93	    char *dot = strchr(u.nodename, '.');
94	    if (dot != NULL) {
95		char *node = ckalloc((unsigned) (dot - u.nodename + 1));
96		memcpy(node, u.nodename, (size_t) (dot - u.nodename));
97		node[dot - u.nodename] = '\0';
98		hp = TclpGetHostByName(node);
99		ckfree(node);
100	    }
101	}
102        if (hp != NULL) {
103	    native = hp->h_name;
104        } else {
105	    native = u.nodename;
106        }
107    }
108#else
109    /*
110     * Uname doesn't exist; try gethostname instead.
111     */
112
113    if (gethostname(buffer, sizeof(buffer)) > -1) {	/* INTL: Native. */
114	native = buffer;
115    }
116#endif
117
118    if (native == NULL) {
119	hostname[0] = 0;
120    } else {
121	Tcl_ExternalToUtf(NULL, NULL, native, -1, 0, NULL, hostname,
122		sizeof(hostname), NULL, NULL, NULL);
123    }
124    hostnameInited = 1;
125    Tcl_MutexUnlock(&hostMutex);
126    return hostname;
127}
128
129/*
130 *----------------------------------------------------------------------
131 *
132 * TclpHasSockets --
133 *
134 *	Detect if sockets are available on this platform.
135 *
136 * Results:
137 *	Returns TCL_OK.
138 *
139 * Side effects:
140 *	None.
141 *
142 *----------------------------------------------------------------------
143 */
144
145int
146TclpHasSockets(interp)
147    Tcl_Interp *interp;		/* Not used. */
148{
149    return TCL_OK;
150}
151
152/*
153 *----------------------------------------------------------------------
154 *
155 * TclpFinalizeSockets --
156 *
157 *	Performs per-thread socket subsystem finalization.
158 *
159 * Results:
160 *	None.
161 *
162 * Side effects:
163 *	None.
164 *
165 *----------------------------------------------------------------------
166 */
167
168void
169TclpFinalizeSockets()
170{
171    return;
172}
173