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 of
9 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 */
11
12 #include "tclInt.h"
13
14 /*
15 * The following variable holds the network name of this host.
16 */
17
18 static TclInitProcessGlobalValueProc InitializeHostName;
19 static ProcessGlobalValue hostName =
20 {0, 0, NULL, NULL, InitializeHostName, NULL, NULL};
21
22
23 /*
24 *----------------------------------------------------------------------
25 *
26 * InitializeHostName --
27 *
28 * This routine sets the process global value of the name of the local
29 * host on which the process is running.
30 *
31 * Results:
32 * None.
33 *
34 *----------------------------------------------------------------------
35 */
36
37 static void
InitializeHostName(char ** valuePtr,int * lengthPtr,Tcl_Encoding * encodingPtr)38 InitializeHostName(
39 char **valuePtr,
40 int *lengthPtr,
41 Tcl_Encoding *encodingPtr)
42 {
43 CONST char *native = NULL;
44
45 #ifndef NO_UNAME
46 struct utsname u;
47 struct hostent *hp;
48
49 memset(&u, (int) 0, sizeof(struct utsname));
50 if (uname(&u) > -1) { /* INTL: Native. */
51 hp = TclpGetHostByName(u.nodename); /* INTL: Native. */
52 if (hp == NULL) {
53 /*
54 * Sometimes the nodename is fully qualified, but gets truncated
55 * as it exceeds SYS_NMLN. See if we can just get the immediate
56 * nodename and get a proper answer that way.
57 */
58
59 char *dot = strchr(u.nodename, '.');
60
61 if (dot != NULL) {
62 char *node = ckalloc((unsigned) (dot - u.nodename + 1));
63
64 memcpy(node, u.nodename, (size_t) (dot - u.nodename));
65 node[dot - u.nodename] = '\0';
66 hp = TclpGetHostByName(node);
67 ckfree(node);
68 }
69 }
70 if (hp != NULL) {
71 native = hp->h_name;
72 } else {
73 native = u.nodename;
74 }
75 }
76 if (native == NULL) {
77 native = tclEmptyStringRep;
78 }
79 #else
80 /*
81 * Uname doesn't exist; try gethostname instead.
82 *
83 * There is no portable macro for the maximum length of host names
84 * returned by gethostbyname(). We should only trust SYS_NMLN if it is at
85 * least 255 + 1 bytes to comply with DNS host name limits.
86 *
87 * Note: SYS_NMLN is a restriction on "uname" not on gethostbyname!
88 *
89 * For example HP-UX 10.20 has SYS_NMLN == 9, while gethostbyname() can
90 * return a fully qualified name from DNS of up to 255 bytes.
91 *
92 * Fix suggested by Viktor Dukhovni (viktor@esm.com)
93 */
94
95 # if defined(SYS_NMLN) && SYS_NMLEN >= 256
96 char buffer[SYS_NMLEN];
97 # else
98 char buffer[256];
99 # endif
100
101 if (gethostname(buffer, sizeof(buffer)) > -1) { /* INTL: Native. */
102 native = buffer;
103 }
104 #endif
105
106 *encodingPtr = Tcl_GetEncoding(NULL, NULL);
107 *lengthPtr = strlen(native);
108 *valuePtr = ckalloc((unsigned int) (*lengthPtr)+1);
109 memcpy(*valuePtr, (void *) native, (size_t)(*lengthPtr)+1);
110 }
111
112 /*
113 *----------------------------------------------------------------------
114 *
115 * Tcl_GetHostName --
116 *
117 * Returns the name of the local host.
118 *
119 * Results:
120 * A string containing the network name for this machine, or an empty
121 * string if we can't figure out the name. The caller must not modify or
122 * free this string.
123 *
124 * Side effects:
125 * Caches the name to return for future calls.
126 *
127 *----------------------------------------------------------------------
128 */
129
130 CONST char *
Tcl_GetHostName(void)131 Tcl_GetHostName(void)
132 {
133 return Tcl_GetString(TclGetProcessGlobalValue(&hostName));
134 }
135
136 /*
137 *----------------------------------------------------------------------
138 *
139 * TclpHasSockets --
140 *
141 * Detect if sockets are available on this platform.
142 *
143 * Results:
144 * Returns TCL_OK.
145 *
146 * Side effects:
147 * None.
148 *
149 *----------------------------------------------------------------------
150 */
151
152 int
TclpHasSockets(Tcl_Interp * interp)153 TclpHasSockets(
154 Tcl_Interp *interp) /* Not used. */
155 {
156 return TCL_OK;
157 }
158
159 /*
160 *----------------------------------------------------------------------
161 *
162 * TclpFinalizeSockets --
163 *
164 * Performs per-thread socket subsystem finalization.
165 *
166 * Results:
167 * None.
168 *
169 * Side effects:
170 * None.
171 *
172 *----------------------------------------------------------------------
173 */
174
175 void
TclpFinalizeSockets(void)176 TclpFinalizeSockets(void)
177 {
178 return;
179 }
180
181 /*
182 * Local Variables:
183 * mode: c
184 * c-basic-offset: 4
185 * fill-column: 78
186 * End:
187 */
188