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 2002/02/27 01:16:43 hobbs 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
42 static char hostname[TCL_HOSTNAME_LEN + 1];
43 static int hostnameInited = 0;
TCL_DECLARE_MUTEX(hostMutex)44 TCL_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
65 CONST char *
66 Tcl_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 = gethostbyname(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 = gethostbyname(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
145 int
TclpHasSockets(interp)146 TclpHasSockets(interp)
147 Tcl_Interp *interp; /* Not used. */
148 {
149 return TCL_OK;
150 }
151