Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
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 | |
8 | */ | |
9 | ||
10 | /* | |
11 | * ALL RIGHTS RESERVED | |
12 | */ | |
13 | ||
14 | #include <afsconfig.h> | |
15 | #include <afs/param.h> | |
16 | ||
17 | #include <roken.h> | |
18 | ||
19 | #ifdef AFS_NT40_ENV | |
20 | #include <direct.h> | |
21 | #else | |
22 | #include <ctype.h> | |
23 | #endif | |
24 | ||
25 | #include "afsutil.h" | |
26 | ||
27 | /* also parse a.b.c.d addresses */ | |
28 | struct hostent * | |
29 | hostutil_GetHostByName(char *ahost) | |
30 | { | |
31 | int tc; | |
32 | static struct hostent thostent; | |
33 | static char *addrp[2]; | |
34 | static char addr[4]; | |
35 | char *ptr = ahost; | |
36 | afs_uint32 tval, numeric = 0; | |
37 | int dots = 0; | |
38 | ||
39 | tc = *ahost; /* look at the first char */ | |
40 | if (tc >= '0' && tc <= '9') { | |
41 | numeric = 1; | |
42 | while ((tc = *ptr++)) { | |
43 | if (tc == '.') { | |
44 | if (dots >= 3) { | |
45 | numeric = 0; | |
46 | break; | |
47 | } | |
48 | dots++; | |
49 | } else if (tc > '9' || tc < '0') { | |
50 | numeric = 0; | |
51 | break; | |
52 | } | |
53 | } | |
54 | } | |
55 | if (numeric) { | |
56 | /* decimal address, return fake hostent with only hostaddr field good */ | |
57 | tval = 0; | |
58 | dots = 0; | |
59 | memset(addr, 0, sizeof(addr)); | |
60 | while ((tc = *ahost++)) { | |
61 | if (tc == '.') { | |
62 | if (dots >= 3) | |
63 | return NULL; /* too many dots */ | |
64 | addr[dots++] = tval; | |
65 | tval = 0; | |
66 | } else if (tc > '9' || tc < '0') | |
67 | return NULL; | |
68 | else { | |
69 | tval *= 10; | |
70 | tval += tc - '0'; | |
71 | } | |
72 | } | |
73 | addr[dots] = tval; | |
74 | #ifdef h_addr | |
75 | /* 4.3 system */ | |
76 | addrp[0] = addr; | |
77 | addrp[1] = NULL; | |
78 | thostent.h_addr_list = &addrp[0]; | |
79 | #else /* h_addr */ | |
80 | /* 4.2 and older systems */ | |
81 | thostent.h_addr = addr; | |
82 | #endif /* h_addr */ | |
83 | return &thostent; | |
84 | } else { | |
85 | #ifdef AFS_NT40_ENV | |
86 | if (afs_winsockInit() < 0) | |
87 | return NULL; | |
88 | #endif | |
89 | return gethostbyname(ahost); | |
90 | } | |
91 | } | |
92 | ||
93 | /* Translate an internet address into a nice printable string. The | |
94 | * variable addr is in network byte order. | |
95 | */ | |
96 | char * | |
97 | hostutil_GetNameByINet(afs_uint32 addr) | |
98 | { | |
99 | struct hostent *th; | |
100 | static char tbuffer[256]; | |
101 | ||
102 | #ifdef AFS_NT40_ENV | |
103 | if (afs_winsockInit() < 0) | |
104 | return NULL; | |
105 | #endif | |
106 | th = gethostbyaddr((void *)&addr, sizeof(addr), AF_INET); | |
107 | if (th && strlen(th->h_name) < sizeof(tbuffer)) { | |
108 | strlcpy(tbuffer, th->h_name, sizeof(tbuffer)); | |
109 | } else { | |
110 | addr = ntohl(addr); | |
111 | sprintf(tbuffer, "%d.%d.%d.%d", (int)((addr >> 24) & 0xff), | |
112 | (int)((addr >> 16) & 0xff), (int)((addr >> 8) & 0xff), | |
113 | (int)(addr & 0xff)); | |
114 | } | |
115 | ||
116 | return tbuffer; | |
117 | } | |
118 | ||
119 | /* the parameter is a pointer to a buffer containing a string of | |
120 | ** bytes of the form | |
121 | ** w.x.y.z # machineName | |
122 | ** returns the network interface in network byte order | |
123 | */ | |
124 | ||
125 | #define MAXBYTELEN 32 | |
126 | afs_uint32 | |
127 | extractAddr(char *line, int maxSize) | |
128 | { | |
129 | char byte1[MAXBYTELEN], byte2[MAXBYTELEN]; | |
130 | char byte3[MAXBYTELEN], byte4[MAXBYTELEN]; | |
131 | int i = 0; | |
132 | char *endPtr; | |
133 | afs_uint32 val1, val2, val3, val4; | |
134 | afs_uint32 val = 0; | |
135 | ||
136 | /* skip empty spaces */ | |
137 | while (isspace(*line) && maxSize) { | |
138 | line++; | |
139 | maxSize--; | |
140 | } | |
141 | ||
142 | /* skip empty lines */ | |
143 | if (!maxSize || !*line) | |
144 | return AFS_IPINVALIDIGNORE; | |
145 | ||
146 | while ((*line != '.') && maxSize) { /* extract first byte */ | |
147 | if (!isdigit(*line)) | |
148 | return AFS_IPINVALID; | |
149 | if (i >= MAXBYTELEN-1) | |
150 | return AFS_IPINVALID; /* no space */ | |
151 | byte1[i++] = *line++; | |
152 | maxSize--; | |
153 | } | |
154 | if (!maxSize) | |
155 | return AFS_IPINVALID; | |
156 | byte1[i] = 0; | |
157 | ||
158 | i = 0, line++; | |
159 | while ((*line != '.') && maxSize) { /* extract second byte */ | |
160 | if (!isdigit(*line)) | |
161 | return AFS_IPINVALID; | |
162 | if (i >= MAXBYTELEN-1) | |
163 | return AFS_IPINVALID; /* no space */ | |
164 | byte2[i++] = *line++; | |
165 | maxSize--; | |
166 | } | |
167 | if (!maxSize) | |
168 | return AFS_IPINVALID; | |
169 | byte2[i] = 0; | |
170 | ||
171 | i = 0, line++; | |
172 | while ((*line != '.') && maxSize) { | |
173 | if (!isdigit(*line)) | |
174 | return AFS_IPINVALID; | |
175 | if (i >= MAXBYTELEN-1) | |
176 | return AFS_IPINVALID; /* no space */ | |
177 | byte3[i++] = *line++; | |
178 | maxSize--; | |
179 | } | |
180 | if (!maxSize) | |
181 | return AFS_IPINVALID; | |
182 | byte3[i] = 0; | |
183 | ||
184 | i = 0, line++; | |
185 | while (*line && !isspace(*line) && maxSize) { | |
186 | if (!isdigit(*line)) | |
187 | return AFS_IPINVALID; | |
188 | if (i >= MAXBYTELEN-1) | |
189 | return AFS_IPINVALID; /* no space */ | |
190 | byte4[i++] = *line++; | |
191 | maxSize--; | |
192 | } | |
193 | if (!maxSize) | |
194 | return AFS_IPINVALID; | |
195 | byte4[i] = 0; | |
196 | ||
197 | errno = 0; | |
198 | val1 = strtol(byte1, &endPtr, 10); | |
199 | if ((val1 == 0) && (errno != 0 || byte1 == endPtr)) | |
200 | return AFS_IPINVALID; | |
201 | ||
202 | errno = 0; | |
203 | val2 = strtol(byte2, &endPtr, 10); | |
204 | if ((val2 == 0) && (errno != 0 || byte2 == endPtr)) /* no conversion */ | |
205 | return AFS_IPINVALID; | |
206 | ||
207 | errno = 0; | |
208 | val3 = strtol(byte3, &endPtr, 10); | |
209 | if ((val3 == 0) && (errno != 0 || byte3 == endPtr)) /* no conversion */ | |
210 | return AFS_IPINVALID; | |
211 | ||
212 | errno = 0; | |
213 | val4 = strtol(byte4, &endPtr, 10); | |
214 | if ((val4 == 0) && (errno != 0 || byte4 == endPtr)) /* no conversion */ | |
215 | return AFS_IPINVALID; | |
216 | ||
217 | val = (val1 << 24) | (val2 << 16) | (val3 << 8) | val4; | |
218 | val = htonl(val); | |
219 | return val; | |
220 | } | |
221 | ||
222 | /* same as inet_ntoa, but to a non-static buffer, must be freed by called */ | |
223 | char * | |
224 | afs_inet_ntoa_r(afs_uint32 addr, char *buf) | |
225 | { | |
226 | int temp; | |
227 | ||
228 | temp = ntohl(addr); | |
229 | sprintf(buf, "%d.%d.%d.%d", (temp >> 24) & 0xff, (temp >> 16) & 0xff, | |
230 | (temp >> 8) & 0xff, (temp) & 0xff); | |
231 | return buf; | |
232 | } | |
233 | ||
234 | /* | |
235 | * gettmpdir() -- Returns pointer to global temporary directory string. | |
236 | * Always succeeds. Never attempt to deallocate directory string. | |
237 | */ | |
238 | ||
239 | char * | |
240 | gettmpdir(void) | |
241 | { | |
242 | char *tmpdirp = NULL; | |
243 | ||
244 | #ifdef AFS_NT40_ENV | |
245 | static char *saveTmpDir = NULL; | |
246 | ||
247 | if (saveTmpDir == NULL) { | |
248 | /* initialize global temporary directory string */ | |
249 | char *dirp = malloc(MAX_PATH+1); | |
250 | int freeDirp = 1; | |
251 | ||
252 | if (dirp != NULL) { | |
253 | DWORD pathLen = GetTempPath(MAX_PATH+1, dirp); | |
254 | ||
255 | if (pathLen == 0 || pathLen > MAX_PATH) { | |
256 | /* can't get tmp path; get cur work dir */ | |
257 | pathLen = GetCurrentDirectory(MAX_PATH, dirp); | |
258 | if (pathLen == 0 || pathLen > MAX_PATH) { | |
259 | free(dirp); | |
260 | dirp = NULL; | |
261 | } | |
262 | } | |
263 | ||
264 | if (dirp != NULL) { | |
265 | /* Have a valid dir path; check that actually exists. */ | |
266 | DWORD fileAttr = GetFileAttributes(dirp); | |
267 | ||
268 | if ((fileAttr == 0xFFFFFFFF) | |
269 | || ((fileAttr & FILE_ATTRIBUTE_DIRECTORY) == 0)) { | |
270 | free(dirp); | |
271 | dirp = NULL; | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
276 | if (dirp != NULL) { | |
277 | FilepathNormalize(dirp); | |
278 | } else { | |
279 | /* most likely TMP or TEMP env vars specify a non-existent dir */ | |
280 | dirp = "/"; | |
281 | freeDirp = 0; | |
282 | } | |
283 | ||
284 | /* atomically initialize shared buffer pointer IF still null */ | |
285 | if (InterlockedCompareExchangePointer(&saveTmpDir, dirp, NULL) != NULL) { | |
286 | /* shared buffer pointer already initialized by another thread */ | |
287 | if (freeDirp) | |
288 | free(dirp); | |
289 | } | |
290 | } | |
291 | /* if (!saveTmpDir) */ | |
292 | tmpdirp = saveTmpDir; | |
293 | #else | |
294 | tmpdirp = "/tmp"; | |
295 | #endif /* AFS_NT40_ENV */ | |
296 | ||
297 | return tmpdirp; | |
298 | } |