Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcs/csaddr.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1990-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* return the address of a host given its name
26
*/
27
28
#include "cslib.h"
29
30
union nl
31
{
32
unsigned char c[4];
33
uint32_t l;
34
};
35
36
static unsigned long local;
37
38
/*
39
* real name to address conversion
40
*/
41
42
static unsigned long
43
realaddr(register Cs_t* state, const char* name)
44
{
45
register int n;
46
register const char* s;
47
int r;
48
const char* t;
49
union nl addr;
50
51
#if CS_LIB_SOCKET
52
53
register struct hostent* hp;
54
55
#endif
56
messagef((state->id, NiL, -8, "realaddr(%s) call", name));
57
state->flags &= ~CS_ADDR_NUMERIC;
58
s = name;
59
if (streq(s, CS_HOST_LOCAL))
60
{
61
messagef((state->id, NiL, -8, "realaddr(%s) = %s, flags = |%s%s%s", name, csntoa(state, local), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
62
return local;
63
}
64
65
/*
66
* check for 0xX.X.X.X or n.n.n.n
67
*/
68
69
if (*s == '0' && *(s + 1) == 'x')
70
{
71
s += 2;
72
r = 16;
73
}
74
else r = 0;
75
addr.l = 0;
76
n = 0;
77
do
78
{
79
addr.c[n] = strtol(s, (char**)&t, r) & 0xff;
80
if (t == s) break;
81
s = t;
82
} while (++n < 4 && *s && *s++ == '.');
83
if (!*s && n == 4)
84
{
85
if (!addr.l || addr.c[0] == 127 && addr.c[1] == 0 && addr.c[2] == 0 && addr.c[3] <= 1)
86
{
87
addr.l = csaddr(state, NiL);
88
if (local == CS_LOCAL)
89
{
90
addr.c[0] = 127;
91
addr.c[1] = 0;
92
addr.c[2] = 0;
93
addr.c[3] = 1;
94
local = addr.l;
95
}
96
else
97
addr.l = local;
98
}
99
state->flags |= CS_ADDR_NUMERIC;
100
messagef((state->id, NiL, -8, "realaddr(%s) = %s, flags = |%s%s%s", name, csntoa(state, addr.l), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
101
return addr.l;
102
}
103
104
/*
105
* local conversion
106
*/
107
108
csdb(state);
109
110
#if CS_LIB_V10 || CS_LIB_SOCKET
111
112
#if CS_LIB_V10
113
if ((addr.l = (unsigned long)in_address(name)) == INADDR_ANY)
114
addr.l = 0;
115
#else
116
addr.l = ((hp = gethostbyname(name)) && hp->h_addrtype == AF_INET && hp->h_length <= sizeof(struct in_addr)) ? (unsigned long)((struct in_addr*)hp->h_addr)->s_addr : 0;
117
#endif
118
if (addr.c[0] == 127 && addr.c[1] == 0 && addr.c[2] == 0 && addr.c[3] <= 1)
119
{
120
if (local == CS_LOCAL)
121
local = addr.l;
122
else
123
addr.l = local;
124
}
125
messagef((state->id, NiL, -8, "realaddr(%s) = %s, flags = |%s%s%s", name, csntoa(state, addr.l), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
126
#else
127
messagef((state->id, NiL, -8, "realaddr(%s) not found", name));
128
addr.l = 0;
129
#endif
130
return addr.l;
131
}
132
133
/*
134
* address conversion with CS_HOST_* aliases
135
* 0 returned on failure
136
* on success:
137
*
138
* state->flags CS_ADDR_* changed to match real host name
139
* state->host real host name after aliases and local truncation
140
*/
141
142
unsigned long
143
csaddr(register Cs_t* state, const char* aname)
144
{
145
register char* name = (char*)aname;
146
register char* s;
147
register unsigned long addr;
148
register Sfio_t* sp = 0;
149
int userlen = 0;
150
int dot = 0;
151
long flags = 0;
152
char* user;
153
154
messagef((state->id, NiL, -8, "addr(%s) call", name));
155
if (!local)
156
{
157
#if CS_LIB_SOCKET
158
if (!state->db)
159
state->db = -1;
160
#endif
161
local = CS_LOCAL;
162
if (addr = realaddr(state, csname(state, 0)))
163
local = addr;
164
}
165
if (!name)
166
{
167
addr = local;
168
goto ok;
169
}
170
if (s = strchr(name, '@'))
171
{
172
userlen = s - name;
173
user = name;
174
name = s + 1;
175
}
176
if (strneq(name, CS_HOST_SHARE, sizeof(CS_HOST_SHARE) - 1))
177
switch (name[sizeof(CS_HOST_SHARE) - 1])
178
{
179
case 0:
180
flags |= CS_ADDR_SHARE;
181
if (sp = csinfo(state, name, NiL))
182
{
183
while (name = sfgetr(sp, '\n', 1))
184
if (addr = realaddr(state, name))
185
goto ok;
186
sfclose(sp);
187
sp = 0;
188
}
189
if (!(addr = realaddr(state, name = CS_HOST_GATEWAY)))
190
addr = local;
191
goto ok;
192
case '.':
193
flags |= CS_ADDR_SHARE;
194
name += sizeof(CS_HOST_SHARE);
195
break;
196
}
197
if (addr = realaddr(state, name))
198
goto ok;
199
if ((flags & CS_ADDR_SHARE) && !(state->flags & CS_ADDR_NUMERIC) && (s = strchr(name, '.')))
200
{
201
char* sb;
202
char* se;
203
char* sx;
204
char* t;
205
char* te;
206
207
dot = s - name;
208
s = state->temp;
209
sx = &state->temp[sizeof(state->temp) - 1];
210
s += sfsprintf(s, sx - s, "%s/", CS_SVC_REMOTE);
211
sb = s;
212
se = 0;
213
t = name;
214
while (*t && s < sx)
215
{
216
if (s - sb >= CS_MNT_MAX)
217
{
218
if (se)
219
{
220
s = se - 1;
221
t = te;
222
}
223
else
224
{
225
if (s >= sx) break;
226
if (*t == '.') t++;
227
}
228
*s++ = '/';
229
sb = s;
230
se = 0;
231
}
232
if ((*s++ = *t++) == '.')
233
{
234
se = s;
235
te = t;
236
}
237
}
238
*s = 0;
239
if (sp = csinfo(state, state->temp, NiL))
240
{
241
while (t = sfgetr(sp, '\n', 1))
242
{
243
if (s = strchr(t, '@')) s++;
244
else s = t;
245
if (addr = realaddr(state, s))
246
{
247
name = s;
248
if (!userlen && s != t)
249
{
250
userlen = s - t - 1;
251
user = t;
252
}
253
goto ok;
254
}
255
}
256
sfclose(sp);
257
sp = 0;
258
}
259
sfsprintf(state->temp, sizeof(state->temp), "%s.%s", CS_HOST_GATEWAY, name);
260
if (addr = realaddr(state, state->temp))
261
{
262
name = state->temp;
263
goto ok;
264
}
265
sfsprintf(state->temp, sizeof(state->temp), "%-.*s.%s", dot, name, name);
266
if (addr = realaddr(state, state->temp))
267
{
268
name = state->temp;
269
goto ok;
270
}
271
}
272
messagef((state->id, NiL, -1, "addr: %s: not found", aname));
273
return 0;
274
ok:
275
if (state->flags & CS_ADDR_NUMERIC)
276
flags &= ~CS_ADDR_SHARE;
277
if (addr == local)
278
{
279
flags |= CS_ADDR_LOCAL;
280
name = csname(state, 0);
281
}
282
else if (!(state->flags & CS_ADDR_NUMERIC))
283
{
284
if (s = strchr(name, '.'))
285
{
286
sfsprintf(state->temp, sizeof(state->temp), "%-.*s", s - name, name);
287
if (realaddr(state, state->temp) == addr)
288
name = state->temp;
289
else flags |= CS_ADDR_REMOTE;
290
}
291
if (!(flags & CS_ADDR_REMOTE) && !streq(name, CS_HOST_PROXY) && !csattr(state, name, "*"))
292
flags |= CS_ADDR_REMOTE;
293
}
294
295
/*
296
* cache host name and user for possible CS_REMOTE_SHELL
297
*/
298
299
strncpy(state->host, name, sizeof(state->host) - 1);
300
if (userlen)
301
{
302
if (userlen >= sizeof(state->user)) userlen = sizeof(state->user) - 1;
303
strncpy(state->user, user, userlen);
304
}
305
state->user[userlen] = 0;
306
if (sp) sfclose(sp);
307
state->flags &= ~(CS_ADDR_LOCAL|CS_ADDR_NOW|CS_ADDR_REMOTE|CS_ADDR_SHARE|CS_DAEMON_SLAVE|CS_ADDR_TEST|CS_ADDR_TRUST);
308
state->flags |= flags;
309
messagef((state->id, NiL, -8, "addr(%s) = %s, flags = |%s%s%s", aname, csntoa(state, addr), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
310
return addr;
311
}
312
313
unsigned long
314
_cs_addr(const char* aname)
315
{
316
return csaddr(&cs, aname);
317
}
318
319