2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <afsconfig.h>
15 #include <afs/param.h>
20 #include "../afs/sysincludes.h"
21 #include "../afs/afsutil.h"
24 #include <sys/types.h>
30 #include <netinet/in.h>
31 #include <sys/socket.h>
32 #include <arpa/inet.h>
48 /* also parse a.b.c.d addresses */
49 struct hostent *hostutil_GetHostByName(register char *ahost)
52 static struct hostent thostent;
53 static char *addrp[2];
55 register char *ptr = ahost;
56 afs_uint32 tval, numeric=0;
59 tc = *ahost; /* look at the first char */
60 if (tc >= '0' && tc <= '9') {
62 while ((tc = *ptr++)) {
69 } else if (tc > '9' || tc < '0') {
76 tc = *ahost; /* look at the first char */
77 /* decimal address, return fake hostent with only hostaddr field good */
80 memset(addr, 0, sizeof(addr));
81 while ((tc = *ahost++)) {
83 if (dots >= 3) return NULL; /* too many dots */
87 else if (tc > '9' || tc < '0') return NULL;
98 thostent.h_addr_list = &addrp[0];
100 /* 4.2 and older systems */
101 thostent.h_addr = addr;
107 if (afs_winsockInit()<0)
110 return gethostbyname(ahost);
114 /* Translate an internet address into a nice printable string. The
115 * variable addr is in network byte order.
117 char *hostutil_GetNameByINet(afs_uint32 addr)
120 static char tbuffer[256];
123 if (afs_winsockInit()<0)
126 th = gethostbyaddr((void *)&addr, sizeof(addr), AF_INET);
128 strcpy(tbuffer, th->h_name);
131 sprintf(tbuffer, "%d.%d.%d.%d",
132 (int)((addr>>24) & 0xff), (int)((addr>>16) & 0xff),
133 (int)((addr>>8) & 0xff), (int)( addr & 0xff));
139 /* the parameter is a pointer to a buffer containing a string of
141 ** w.x.y.z # machineName
142 ** returns the network interface in network byte order
144 afs_uint32 extractAddr(char *line, int maxSize)
146 char byte1[32], byte2[32], byte3[32], byte4[32];
149 afs_uint32 val1, val2, val3, val4;
152 /* skip empty spaces */
153 while ( isspace(*line) && maxSize )
159 /* skip empty lines */
160 if ( !maxSize || !*line ) return AFS_IPINVALIDIGNORE;
162 while ( ( *line != '.' ) && maxSize) /* extract first byte */
164 if ( !isdigit(*line) ) return AFS_IPINVALID;
165 if ( i > 31 ) return AFS_IPINVALID; /* no space */
166 byte1[i++] = *line++;
169 if ( !maxSize ) return AFS_IPINVALID;
173 while ( ( *line != '.' ) && maxSize) /* extract second byte */
175 if ( !isdigit(*line) ) return AFS_IPINVALID;
176 if ( i > 31 ) return AFS_IPINVALID; /* no space */
177 byte2[i++] = *line++;
180 if ( !maxSize ) return AFS_IPINVALID;
184 while ( ( *line != '.' ) && maxSize)
186 if ( !isdigit(*line) ) return AFS_IPINVALID;
187 if ( i > 31 ) return AFS_IPINVALID; /* no space */
188 byte3[i++] = *line++;
191 if ( !maxSize ) return AFS_IPINVALID;
195 while ( *line && !isspace(*line) && maxSize)
197 if ( !isdigit(*line) ) return AFS_IPINVALID;
198 if ( i > 31 ) return AFS_IPINVALID; /* no space */
199 byte4[i++] = *line++;
202 if ( !maxSize ) return AFS_IPINVALID;
206 val1 = strtol(byte1, &endPtr, 10);
207 if (( val1== 0 ) && ( errno != 0 || byte1 == endPtr))
208 return AFS_IPINVALID;
211 val2 = strtol(byte2, &endPtr, 10);
212 if (( val2== 0 ) && ( errno !=0 || byte2 == endPtr))/* no conversion */
213 return AFS_IPINVALID;
216 val3 = strtol(byte3, &endPtr, 10);
217 if (( val3== 0 ) && ( errno !=0 || byte3 == endPtr))/* no conversion */
218 return AFS_IPINVALID;
221 val4 = strtol(byte4, &endPtr, 10);
222 if (( val4== 0 ) && ( errno !=0 || byte4 == endPtr))/* no conversion */
223 return AFS_IPINVALID;
225 val = ( val1 << 24 ) | ( val2 << 16 ) | ( val3 << 8 ) | val4;
231 ** converts a 4byte IP address into a static string (e.g. w.x.y.z)
232 ** On Solaris, if we pass a 4 byte integer directly into inet_ntoa(), it
233 ** causes a memory fault.
235 char *afs_inet_ntoa(afs_uint32 addr)
239 return (char *) inet_ntoa(temp);
242 /* same as above, but to a non-static buffer, must be freed by called */
243 char *afs_inet_ntoa_r(afs_uint32 addr, char *buf)
248 sprintf(buf, "%d.%d.%d.%d",
249 (temp >> 24 ) & 0xff,
250 (temp >> 16 ) & 0xff,
257 * gettmpdir() -- Returns pointer to global temporary directory string.
258 * Always succeeds. Never attempt to deallocate directory string.
261 char *gettmpdir(void)
263 char *tmpdirp = NULL;
266 static char *saveTmpDir = NULL;
268 if (saveTmpDir == NULL) {
269 /* initialize global temporary directory string */
270 char *dirp = (char *)malloc(MAX_PATH);
274 DWORD pathLen = GetTempPath(MAX_PATH, dirp);
276 if (pathLen == 0 || pathLen > MAX_PATH) {
277 /* can't get tmp path; get cur work dir */
278 pathLen = GetCurrentDirectory(MAX_PATH, dirp);
279 if (pathLen == 0 || pathLen > MAX_PATH) {
286 /* Have a valid dir path; check that actually exists. */
287 DWORD fileAttr = GetFileAttributes(dirp);
289 if ((fileAttr == 0xFFFFFFFF) ||
290 ((fileAttr & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
298 FilepathNormalize(dirp);
300 /* most likely TMP or TEMP env vars specify a non-existent dir */
305 /* atomically initialize shared buffer pointer IF still null */
308 if (InterlockedCompareExchange(&saveTmpDir, dirp, NULL) != NULL) {
309 /* shared buffer pointer already initialized by another thread */
313 } /* interlock xchng */
316 /* Above is what we really want to do, but Windows 95 does not have
317 * InterlockedCompareExchange(). So we just atomically swap
318 * the buffer pointer values but we do NOT deallocate the
319 * previously installed buffer, if any, in case it is in use.
321 InterlockedExchange((LPLONG)&saveTmpDir, (LONG)dirp);
323 } /* if (!saveTmpDir) */
325 tmpdirp = saveTmpDir;
328 #endif /* AFS_NT40_ENV */