tools/adflib: build only host variant which is used by Sam440 target
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / api / getxbyy.c
bloba8dec14ad8a9ddb992082ed619117dae294ecb77
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
5 * Copyright (C) 2005 Neil Cafferkey
6 * Copyright (C) 2005 Pavel Fedin
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 * MA 02111-1307, USA.
24 #include <conf.h>
26 #include <aros/libcall.h>
28 #include <sys/param.h>
29 #include <sys/systm.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <netdb.h>
36 #include <kern/amiga_includes.h>
38 #include <api/amiga_api.h>
39 #include <api/amiga_libcallentry.h>
40 #include <kern/amiga_netdb.h>
41 #include <api/allocdatabuffer.h>
43 #include <api/gethtbynamadr.h> /* prototypes (NO MORE BUGS HERE) */
45 int strcasecmp(const char *, const char *);
47 #if __SASC
48 #define strcasecmp stricmp
49 #endif
52 static long copyGenent(struct SocketBase * libPtr,
53 struct DataBuffer * DB,
54 struct GenentNode *ent)
56 long diff;
58 if (allocDataBuffer(DB, ent->gn_EntSize) == FALSE) {
59 writeErrnoValue(libPtr, ENOMEM);
60 return 0;
64 * how much to add to old pointers
66 diff = (caddr_t)DB->db_Addr - (caddr_t)&ent->gn_Ent;
69 * copy given ent verbatim
71 bcopy((caddr_t)&ent->gn_Ent, DB->db_Addr, ent->gn_EntSize);
73 return diff;
78 * Host queries if Nameserver is not in use *****************************
82 * Match name in aliaslist, used by `...byname()' -queries
85 static BOOL matchAlias(char ** aliases, const char * name)
87 for ( ; *aliases != 0; aliases++)
88 if (strcasecmp(*aliases, name) == 0)
89 return TRUE;
91 return FALSE;
96 * Makehostent() must be called when NDB_Semaphore is obtained.
98 static struct hostent * makehostent(struct SocketBase * libPtr,
99 struct HostentNode * ent)
101 long diff;
102 short i;
104 if ((diff = copyGenent(libPtr, &libPtr->hostents,
105 (struct GenentNode *)ent)) == 0)
106 return NULL; /* failed to allocate memory */
109 * patch pointers
111 #define HOSTENT ((struct hostent *)libPtr->hostents.db_Addr)
112 HOSTENT->h_name += diff;
114 HOSTENT->h_aliases = (char **)((caddr_t)HOSTENT->h_aliases + diff);
115 for (i = 0; HOSTENT->h_aliases[i]; i++)
116 HOSTENT->h_aliases[i] += diff;
117 /* NULL remains null */
119 HOSTENT->h_addr_list = (char **)((caddr_t)HOSTENT->h_addr_list + diff);
120 for (i = 0; HOSTENT->h_addr_list[i]; i++)
121 HOSTENT->h_addr_list[i] += diff;
122 /* NULL remains null */
124 return HOSTENT;
125 #undef HOSTENT
129 struct hostent * _gethtbyname(struct SocketBase * libPtr,
130 const char * name)
132 struct HostentNode * entNode;
133 struct hostent * host;
135 LOCK_R_NDB(NDB);
137 for (entNode = (struct HostentNode *)NDB->ndb_Hosts.mlh_Head;
138 entNode->hn_Node.mln_Succ;
139 entNode = (struct HostentNode *)entNode->hn_Node.mln_Succ)
140 if (strcasecmp(entNode->hn_Ent.h_name, (char *)name) == 0 ||
141 matchAlias(entNode->hn_Ent.h_aliases, name)) {
142 host = makehostent(libPtr, entNode);
143 UNLOCK_NDB(NDB);
144 return host;
146 UNLOCK_NDB(NDB);
147 writeErrnoValue(libPtr, 0);
148 return NULL;
152 struct hostent * _gethtbyaddr(struct SocketBase * libPtr,
153 const char * addr, int len, int type)
155 struct HostentNode * entNode;
156 struct hostent * host;
158 LOCK_R_NDB(NDB);
159 for (entNode = (struct HostentNode *)NDB->ndb_Hosts.mlh_Head;
160 entNode->hn_Node.mln_Succ;
161 entNode = (struct HostentNode *)entNode->hn_Node.mln_Succ)
162 if (entNode->hn_Ent.h_addrtype == type &&
163 ! bcmp(entNode->hn_Ent.h_addr, addr, len)) {
164 host = makehostent(libPtr, entNode);
165 UNLOCK_NDB(NDB);
166 return host;
168 UNLOCK_NDB(NDB);
169 writeErrnoValue(libPtr, 0);
170 return NULL;
175 * Network queries ****************************************************
180 * Makenetent() must be called when NDB_Semaphore is obtained.
182 static struct netent * makenetent(struct SocketBase * libPtr,
183 struct NetentNode * ent)
185 long diff;
186 short i;
188 if ((diff = copyGenent(libPtr, &libPtr->netents,
189 (struct GenentNode *)ent)) == 0)
190 return NULL;
193 * patch pointers
195 #define NETENT ((struct netent *)libPtr->netents.db_Addr)
196 NETENT->n_name += diff;
198 NETENT->n_aliases = (char **)((caddr_t)NETENT->n_aliases + diff);
199 for (i = 0; NETENT->n_aliases[i]; i++)
200 NETENT->n_aliases[i] += diff;
201 /* NULL remains null */
203 return NETENT;
204 #undef NETENT
208 /*struct netent * SAVEDS getnetbyname(
209 REG(a0, const char * name),
210 REG(a6, struct SocketBase * libPtr))*/
211 AROS_LH1(struct netent *, getnetbyname,
212 AROS_LHA(const char *, name, A0),
213 struct SocketBase *, libPtr, 37, UL)
215 AROS_LIBFUNC_INIT
216 struct NetentNode * entNode;
217 struct netent * net;
219 CHECK_TASK2();
221 LOCK_R_NDB(NDB);
222 for (entNode = (struct NetentNode *)NDB->ndb_Networks.mlh_Head;
223 entNode->nn_Node.mln_Succ;
224 entNode = (struct NetentNode *)entNode->nn_Node.mln_Succ)
225 if (strcmp(entNode->nn_Ent.n_name, name) == 0 ||
226 matchAlias(entNode->nn_Ent.n_aliases, name)) {
227 net = makenetent(libPtr, entNode);
228 UNLOCK_NDB(NDB);
229 return net;
231 UNLOCK_NDB(NDB);
232 writeErrnoValue(libPtr, 0);
233 return NULL;
234 AROS_LIBFUNC_EXIT
237 /*struct netent * SAVEDS getnetbyaddr(
238 REG(d0, long netw),
239 REG(d1, long type),
240 REG(a6, struct SocketBase * libPtr))*/
241 AROS_LH2(struct netent *, getnetbyaddr,
242 AROS_LHA(long, netw, D0),
243 AROS_LHA(long, type, D1),
244 struct SocketBase *, libPtr, 38, UL)
246 AROS_LIBFUNC_INIT
247 struct NetentNode * entNode;
248 struct netent * net;
250 CHECK_TASK2();
252 LOCK_R_NDB(NDB);
253 for (entNode = (struct NetentNode *)NDB->ndb_Networks.mlh_Head;
254 entNode->nn_Node.mln_Succ;
255 entNode = (struct NetentNode *)entNode->nn_Node.mln_Succ)
256 if (entNode->nn_Ent.n_addrtype == type && entNode->nn_Ent.n_net == netw) {
257 net = makenetent(libPtr, entNode);
258 UNLOCK_NDB(NDB);
259 return net;
261 UNLOCK_NDB(NDB);
262 writeErrnoValue(libPtr, 0);
263 return NULL;
264 AROS_LIBFUNC_EXIT
269 * Service queries ****************************************************
273 * Makeservent() must be called when NDB_Semaphore is obtained.
275 static struct servent * makeservent(struct SocketBase * libPtr,
276 struct ServentNode * ent)
278 long diff;
279 short i;
281 if ((diff = copyGenent(libPtr, &libPtr->servents,
282 (struct GenentNode *)ent)) == 0)
283 return NULL;
286 * patch pointers
288 #define SERVENT ((struct servent *)libPtr->servents.db_Addr)
289 SERVENT->s_name += diff;
291 SERVENT->s_aliases = (char **)((caddr_t)SERVENT->s_aliases + diff);
292 for (i = 0; SERVENT->s_aliases[i]; i++)
293 SERVENT->s_aliases[i] += diff;
294 /* NULL remains null */
296 SERVENT->s_proto += diff;
298 return SERVENT;
299 #undef SERVENT
304 * findservent is needed for external call.
306 struct ServentNode * findServentNode(struct NetDataBase * ndb,
307 const char * name, const char * proto)
309 struct ServentNode * entNode;
311 for (entNode = (struct ServentNode *)ndb->ndb_Services.mlh_Head;
312 entNode->sn_Node.mln_Succ;
313 entNode = (struct ServentNode *)entNode->sn_Node.mln_Succ)
314 if ((strcmp(entNode->sn_Ent.s_name, name) == 0 ||
315 matchAlias(entNode->sn_Ent.s_aliases, name)) &&
316 (proto == NULL || strcmp(entNode->sn_Ent.s_proto, proto) == 0))
317 return entNode;
319 return NULL;
324 /*struct servent * SAVEDS getservbyname(
325 REG(a0, const char * name),
326 REG(a1, const char * proto),
327 REG(a6, struct SocketBase * libPtr))*/
328 AROS_LH2(struct servent *, getservbyname,
329 AROS_LHA(const char *, name, A0),
330 AROS_LHA(const char *, proto, A1),
331 struct SocketBase *, libPtr, 39, UL)
333 AROS_LIBFUNC_INIT
334 struct ServentNode * entNode;
335 struct servent * serv;
337 CHECK_TASK2();
339 LOCK_R_NDB(NDB);
340 if ((entNode = findServentNode(NDB, name, proto)) != NULL) {
341 serv = makeservent(libPtr, entNode);
342 UNLOCK_NDB(NDB);
343 return serv;
345 UNLOCK_NDB(NDB);
346 writeErrnoValue(libPtr, 0);
347 return NULL;
348 AROS_LIBFUNC_EXIT
351 /*struct servent * SAVEDS getservbyport(
352 REG(d0, LONG port),
353 REG(a0, const char * proto),
354 REG(a6, struct SocketBase * libPtr))*/
355 AROS_LH2(struct servent *, getservbyport,
356 AROS_LHA(LONG, port, D0),
357 AROS_LHA(const char *, proto, A0),
358 struct SocketBase *, libPtr, 40, UL)
360 AROS_LIBFUNC_INIT
361 struct ServentNode * entNode;
362 struct servent * serv;
364 CHECK_TASK2();
366 LOCK_R_NDB(NDB);
367 for (entNode = (struct ServentNode *)NDB->ndb_Services.mlh_Head;
368 entNode->sn_Node.mln_Succ;
369 entNode = (struct ServentNode *)entNode->sn_Node.mln_Succ)
370 if (entNode->sn_Ent.s_port == port &&
371 (proto == NULL || strcmp(entNode->sn_Ent.s_proto, proto) == 0)) {
372 serv = makeservent(libPtr, entNode);
373 UNLOCK_NDB(NDB);
374 return serv;
377 UNLOCK_NDB(NDB);
378 writeErrnoValue(libPtr, 0);
379 return NULL;
380 AROS_LIBFUNC_EXIT
385 * Protocol queries ****************************************************
389 * Makeprotoent() must be called when NDB_Semaphore is obtained.
391 static struct protoent * makeprotoent(struct SocketBase * libPtr,
392 struct ProtoentNode * ent)
394 long diff;
395 short i;
397 if ((diff = copyGenent(libPtr, &libPtr->protoents,
398 (struct GenentNode *)ent)) == 0)
399 return NULL;
402 * patch pointers
404 #define PROTOENT ((struct protoent *)libPtr->protoents.db_Addr)
405 PROTOENT->p_name += diff;
407 PROTOENT->p_aliases = (char **)((caddr_t)PROTOENT->p_aliases + diff);
408 for (i = 0; PROTOENT->p_aliases[i]; i++)
409 PROTOENT->p_aliases[i] += diff;
410 /* NULL remains null */
412 return PROTOENT;
413 #undef PROTOENT
416 /*struct protoent * SAVEDS getprotobyname(
417 REG(a0, const char * name),
418 REG(a6, struct SocketBase * libPtr))*/
419 AROS_LH1(struct protoent *, getprotobyname,
420 AROS_LHA(const char *, name, A0),
421 struct SocketBase *, libPtr, 41, UL)
423 AROS_LIBFUNC_INIT
424 struct ProtoentNode * entNode;
425 struct protoent * proto;
427 CHECK_TASK2();
429 LOCK_R_NDB(NDB);
430 for (entNode = (struct ProtoentNode *)NDB->ndb_Protocols.mlh_Head;
431 entNode->pn_Node.mln_Succ;
432 entNode = (struct ProtoentNode *)entNode->pn_Node.mln_Succ)
433 if (strcmp(entNode->pn_Ent.p_name, name) == 0 ||
434 matchAlias(entNode->pn_Ent.p_aliases, name)) {
435 proto = makeprotoent(libPtr, entNode);
436 UNLOCK_NDB(NDB);
437 return proto;
439 UNLOCK_NDB(NDB);
440 writeErrnoValue(libPtr, 0);
441 return NULL;
442 AROS_LIBFUNC_EXIT
445 /*struct protoent * SAVEDS getprotobynumber(
446 REG(a0, long protoc),
447 REG(a6, struct SocketBase * libPtr))*/
448 AROS_LH1(struct protoent *, getprotobynumber,
449 AROS_LHA(long, protoc, A0),
450 struct SocketBase *, libPtr, 42, UL)
452 AROS_LIBFUNC_INIT
453 struct ProtoentNode * entNode;
454 struct protoent * proto;
456 CHECK_TASK2();
458 LOCK_R_NDB(NDB);
459 for (entNode = (struct ProtoentNode *)NDB->ndb_Protocols.mlh_Head;
460 entNode->pn_Node.mln_Succ;
461 entNode = (struct ProtoentNode *)entNode->pn_Node.mln_Succ)
462 if (entNode->pn_Ent.p_proto == protoc) {
463 proto = makeprotoent(libPtr, entNode);
464 UNLOCK_NDB(NDB);
465 return proto;
468 UNLOCK_NDB(NDB);
469 writeErrnoValue(libPtr, 0);
470 return NULL;
471 AROS_LIBFUNC_EXIT