Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / api / gethostnamadr.c
blob8a32476a8985d068f52d0e7bf9b4fec103b0a992
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 - 2007 The AROS Dev Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
24 * Copyright (c) 1985, 1988 Regents of the University of California.
25 * All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
56 #if defined(LIBC_SCCS) && !defined(lint)
57 static char sccsid[] = "@(#)gethostnamadr.c 6.45 (Berkeley) 2/24/91";
58 #endif /* LIBC_SCCS and not lint */
60 #include <conf.h>
62 #include <aros/libcall.h>
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/socket.h>
67 #include <sys/malloc.h>
68 #include <netinet/in.h>
69 #include <net/if.h> /* for the gethostid() needs */
70 #include <arpa/inet.h>
71 #include <netdb.h>
72 #include <ctype.h>
73 #include <sys/errno.h>
75 #include <arpa/nameser.h>
76 #include <api/resolv.h>
77 #include <kern/amiga_includes.h>
78 #include <api/amiga_api.h>
79 #include <api/amiga_libcallentry.h>
80 #include <api/amiga_raf.h>
81 #include <api/allocdatabuffer.h>
82 #include <kern/amiga_subr.h>
84 #include <api/gethtbynamadr.h> /* prototypes (NO MORE BUGS HERE) */
85 #include <api/apicalls.h>
87 #include <proto/bsdsocket.h>
89 #define MAXALIASES 35
90 #define MAXADDRS 35
92 #if PACKETSZ > 1024
93 #define MAXPACKET PACKETSZ
94 #else
95 #define MAXPACKET 1024
96 #endif
98 typedef union {
99 HEADER hdr;
100 u_char buf[MAXPACKET];
101 } querybuf;
103 typedef union {
104 long al;
105 char ac;
106 } align;
109 * macro for getting error value from another library base function
110 * ( which is called directly here )
114 * hostent structure in SocketBase
116 #define HOSTENT ((struct hostent *)libPtr->hostents.db_Addr)
119 * longword align given pointer (i.e. divides by 4)
121 #define ALIGN(p) (((long)(p) + (sizeof(long) - 1)) &~ (sizeof (long) -1))
123 #define MAXALIASES 35
124 #define MAXADDRS 35
126 typedef char hostbuf_t[512];
128 struct hoststruct {
129 char * host_aliases[MAXALIASES + 1];
130 char * h_addr_ptrs[MAXADDRS + 1];
131 short host_alias_count;
132 short h_addr_count;
133 struct hostent host;
134 hostbuf_t hostbuf;
137 static struct hostent * makehostent(struct SocketBase * libPtr,
138 struct hoststruct * HS,
139 char * ptr);
141 LONG usens = 2;
143 static char *
144 getanswer(struct SocketBase * libPtr, querybuf *answer,int anslen, int iquery,
145 struct hoststruct * HS)
147 register HEADER *hp;
148 register u_char *cp; /* pointer to traverse in 'answer' */
149 register int n;
150 u_char *eom;
151 int buflen = sizeof HS->hostbuf;
152 char *bp; /* bp -- answer buffer pointer */
153 int type, class, ancount, qdcount;
154 int haveanswer, getclass = C_ANY;
155 char **ap, **hap;
157 #if defined(__AROS__)
158 D(bug("[AROSTCP](gethostnameadr.c) getanswer()\n"));
159 #endif
161 eom = answer->buf + anslen;
163 * find first satisfactory answer
165 hp = &answer->hdr;
166 ancount = ntohs(hp->ancount); /* how many answers returned from nameserver */
167 qdcount = ntohs(hp->qdcount); /* how many questions in nameserver query */
170 * bp, points to start of buffer space where new resolved answer is to
171 * be written. the bp is moved to next free space. Initially it is
172 * set below, to start of buffer allocated for it-
174 bp = HS->hostbuf;
176 * address cp to start of nameserver answers (after static sized header)
178 cp = answer->buf + sizeof(HEADER);
181 * Any questions asked..hmm this should always be the case
183 if (qdcount) {
184 #if 0 /* added by too 8.Sep.1993: skipping strange parts */
186 * gethostbyaddr uses inverse query...
188 if (iquery) {
189 if ((n = dn_expand((u_char *)answer->buf,
190 (u_char *)eom, (u_char *)cp, (u_char *)bp,
191 buflen)) < 0) {
192 h_errno = NO_RECOVERY;
193 return NULL;
195 cp += n + QFIXEDSZ;
197 * Hostname in final hostent structure is written here in case
198 * of gethostbyaddr. (from question section ???)
200 HS->host.h_name = bp;
201 n = strlen(bp) + 1;
202 bp += n;
203 buflen -= n;
205 else
206 #endif /* 0 */ /* 8Sep93: now code below skips all question strings */
208 * here is normal query (gethostbyname). skipping query section
209 * hmm, wondering why is it originally implemented as 2
210 * __dn_skipname function calls ?
212 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
213 while (--qdcount > 0)
214 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
216 else if (iquery) {
218 * no questions and inverse query :o
220 if (hp->aa)
221 h_errno = HOST_NOT_FOUND;
222 else
223 h_errno = TRY_AGAIN;
224 return NULL;
226 ap = HS->host_aliases;
227 HS->host_alias_count = 1; /* there is always NULL as last pointer */
228 hap = HS->h_addr_ptrs;
229 HS->h_addr_count = 1; /* there is always NULL as last pointer */
231 haveanswer = 0;
232 while (--ancount >= 0 && cp < eom) {
233 if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom,
234 (u_char *)cp, (u_char *)bp, buflen)) < 0)
235 break;
236 cp += n;
238 * Type and class are type and class of answer in returned resource
239 * record. see arpa[_/]nameserver.h for more information.
241 type = _getshort(cp);
242 cp += sizeof(u_short);
243 class = _getshort(cp);
244 cp += sizeof(u_short) + sizeof(u_int32_t);
245 n = _getshort(cp);
246 cp += sizeof(u_short);
248 if (type == T_CNAME) { /* canonical name (add alias names)*/
249 cp += n;
250 if (HS->host_alias_count >= MAXALIASES)
251 continue;
252 *ap++ = bp;
253 HS->host_alias_count++;
254 n = strlen(bp) + 1;
255 bp += n;
256 buflen -= n;
257 continue;
259 if (iquery && type == T_PTR) { /* domain name pointer (get domain
260 name and return) */
261 if ((n = dn_expand((u_char *)answer->buf,
262 (u_char *)eom, (u_char *)cp, (u_char *)bp,
263 buflen)) < 0) {
264 cp += n;
265 continue;
267 cp += n;
268 HS->host.h_name = bp; /* well, rewrites name pointer if there were
269 returned questions also... */
270 haveanswer = 1;
271 bp+= (strlen(bp) + 1);
272 break;
274 if (iquery || type != T_A) {
276 * here is strange answer from nameserver: inverse query should have
277 * been handled earlyer and there should not be any other types
278 * left than "host address"
280 #ifdef RES_DEBUG
281 printf("unexpected answer type %d, size %d\n",
282 type, n);
283 #endif
284 cp += n;
285 continue;
287 if (haveanswer) {
289 * Here if one host address answer is already returned (rather odd...)
291 if (n != HS->host.h_length) {
292 cp += n;
293 continue;
295 if (class != getclass) {
296 cp += n;
297 continue;
300 else {
302 * Fill in host address data and comparing info for next cycle (if any)
304 HS->host.h_length = n;
305 getclass = class;
306 HS->host.h_addrtype = (class == C_IN) ?
307 AF_INET : AF_UNSPEC;
308 if (!iquery) {
310 * if not inverse query and haveanswer = 0 host name is first in
311 * bp pointed buffer. (rather strange if answer already returned
312 * and new addresses are to be added since aren't in that case
313 * also names returned or is it inconsistent or have i missed
314 * something ?
316 int n1;
318 HS->host.h_name = bp;
319 n1 = strlen(bp) + 1;
320 bp += n1;
321 buflen -= n1;
325 // bp = (char *)ALIGN(bp); /* align answer buffer for next host address */
327 if (HS->host.h_length >= buflen) {
328 #ifdef RES_DEBUG
329 printf("size (%d) too big\n", HS->host.h_length);
330 #endif
331 break;
334 * Fill next host address in address list
336 bcopy(cp, *hap++ = bp, n);
337 HS->h_addr_count++;
338 bp += n;
339 buflen -= n;
340 cp += n;
341 haveanswer++;
342 } /* while (--ancount ...) */
344 if (haveanswer) {
345 *ap = NULL;
346 *hap = NULL;
347 return bp;
349 else {
350 h_errno = TRY_AGAIN;
351 return NULL;
355 int isipaddr(const char *name)
357 const char *c;
358 int i=0;
359 for (c=name;*c;c++)
361 if (!isdigit(*c))
363 if ((*c) == '.')
364 i++;
365 else
366 return 0;
369 return (i == 3);
372 struct hostent *__gethostbyname(const char *name, struct SocketBase *libPtr)
374 querybuf *buf;
375 int n;
376 char * ptr;
377 struct hoststruct * HS = NULL;
378 struct hostent * anshost = NULL;
380 #if defined(__AROS__)
381 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname('%s')\n", name));
382 #endif
384 CHECK_TASK2();
387 * check if name consists of only dots and digits.
389 if (isipaddr(name)) {
390 struct in_addr inaddr;
391 u_long * lptr;
393 #if defined(__AROS__)
394 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: name IS an IP address\n"));
395 #endif
397 if (!__inet_aton(name, &inaddr)) {
398 writeErrnoValue(libPtr, EINVAL);
399 h_errno = 0;
400 return NULL;
403 if (allocDataBuffer(&libPtr->hostents,
404 sizeof (struct hostent) + 28) == FALSE) {
405 writeErrnoValue(libPtr, ENOMEM);
406 h_errno = 0;
407 return NULL;
409 HOSTENT->h_addrtype = AF_INET;
410 HOSTENT->h_length = sizeof (struct in_addr);
411 lptr = (u_long *)(HOSTENT + 1);
412 *lptr++ = inaddr.s_addr;
413 *(u_long **)(lptr) = lptr - 1;
414 HOSTENT->h_addr_list = (char **)lptr;
415 *++lptr = 0;
416 HOSTENT->h_aliases = (char **)lptr;
417 HOSTENT->h_name = strcpy((char *)++lptr, name);
419 return HOSTENT;
421 else
423 #if defined(__AROS__)
424 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: name ISNT an IP address\n"));
425 #endif
429 * Search local database (first) is usens not FIRST
431 if (usens != 1)
432 if ((anshost =_gethtbyname(libPtr, name)) != NULL || usens == 0)
434 #if defined(__AROS__)
435 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: host found in local database\n"));
436 #endif
437 return anshost;
440 * Here if usens is FIRST or host not in local database and usens is SECOND
442 if ((HS = bsd_malloc(sizeof (querybuf) + sizeof (struct hoststruct),
443 M_TEMP, M_WAITOK)) == NULL) {
444 #if defined(__AROS__)
445 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: couldnt allocate memory for res search entry\n"));
446 #endif
447 writeErrnoValue(libPtr, ENOMEM);
448 return NULL;
450 buf = (querybuf *)(HS + 1);
452 n = res_search(libPtr, name, C_IN, T_A, buf->buf, sizeof (querybuf));
453 if (n >= 0) {
454 #if defined(__AROS__)
455 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: [res_search] returns %d\n", n));
456 #endif
457 ptr = getanswer(libPtr, buf, n, 0, HS);
458 if (ptr != NULL) {
459 #if defined(__AROS__)
460 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: [getanswer] returns valid ptr\n"));
461 #endif
462 if ((anshost = makehostent(libPtr, HS, ptr)) != NULL) {
463 #if defined(__AROS__)
464 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: [makehostent] returns success\n"));
465 #endif
466 anshost->h_addrtype = HS->host.h_addrtype;
467 anshost->h_length = HS->host.h_length;
471 else {
472 #if defined(__AROS__)
473 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: [res_search] failed\n"));
474 #endif
475 #ifdef RES_DEBUG
476 printf("res_search failed\n");
477 #endif
479 * If usens is FIRST and host not found using resolver.
481 if (usens != 2)
482 anshost =_gethtbyname(libPtr, name);
484 #if defined(__AROS__)
485 D(bug("[AROSTCP](gethostnameadr.c) gethostbyname: finished search\n"));
486 #endif
488 if (HS)
489 bsd_free(HS, M_TEMP);
490 return anshost;
493 AROS_LH1(struct hostent *, gethostbyname,
494 AROS_LHA(char *, name, A0),
495 struct SocketBase *, libPtr, 35, UL)
497 AROS_LIBFUNC_INIT
498 return __gethostbyname(name, libPtr);
499 AROS_LIBFUNC_EXIT
504 struct hostent * __gethostbyaddr(UBYTE *addr, int len, int type, struct SocketBase * libPtr)
506 querybuf * buf;
507 int n;
508 char * ptr;
509 struct hoststruct * HS = NULL;
510 char * qbuf;
511 struct hostent * anshost = NULL;
513 #if defined(__AROS__)
514 D(bug("[AROSTCP](gethostnameadr.c) __gethostbyaddr()\n"));
515 #endif
517 CHECK_TASK2();
519 if (type != AF_INET)
520 return ((struct hostent *) NULL);
523 * Search local database (first) is usens not FIRST
525 if (usens != 1)
526 if ((anshost =_gethtbyaddr(libPtr, addr, len, type)) != NULL || usens == 0)
527 return anshost;
530 * Here if usens is FIRST or host not in local database and usens is SECOND
532 if ((HS = bsd_malloc(sizeof (querybuf) + MAXDNAME + 1 +
533 sizeof (struct hoststruct), M_TEMP, M_WAITOK))
534 == NULL) {
535 writeErrnoValue(libPtr, ENOMEM);
536 return NULL;
538 buf = (querybuf *)(HS + 1);
539 qbuf = (caddr_t)(buf + 1);
541 (void)sprintf(qbuf, "%lu.%lu.%lu.%lu.in-addr.arpa",
542 ((unsigned long)addr[3] & 0xff),
543 ((unsigned long)addr[2] & 0xff),
544 ((unsigned long)addr[1] & 0xff),
545 ((unsigned long)addr[0] & 0xff));
546 n = res_query(libPtr, qbuf, C_IN, T_PTR, (char *)buf, sizeof (querybuf));
548 if (n >= 0) {
549 ptr = getanswer(libPtr, buf, n, 1, HS);
550 if (ptr != NULL) {
551 if (HS->h_addr_count == 1) {
552 HS->h_addr_count++;
553 bcopy(addr, ptr, len);
554 HS->h_addr_ptrs[0] = ptr;
555 ptr += len;
557 else
558 bcopy(addr, &HS->h_addr_ptrs[0], len);
559 HS->h_addr_ptrs[1] = NULL;
560 if ((anshost = makehostent(libPtr, HS, ptr)) != NULL) {
561 anshost->h_addrtype = type;
562 anshost->h_length = len;
566 else {
567 #ifdef RES_DEBUG
568 printf("res_query failed\n");
569 #endif
571 * If usens is FIRST and host not found using resolver.
573 if (usens != 2)
574 anshost = _gethtbyaddr(libPtr, addr, len, type);
576 if (HS)
577 bsd_free(HS, M_TEMP);
578 return anshost;
581 AROS_LH3(struct hostent *, gethostbyaddr,
582 AROS_LHA(UBYTE *, addr, A0),
583 AROS_LHA(int, len, D0),
584 AROS_LHA(int, type, D1),
585 struct SocketBase *, libPtr, 36, UL)
587 AROS_LIBFUNC_INIT
588 #if defined(__AROS__)
589 D(bug("[AROSTCP](gethostnameadr.c) gethostbyaddr()\n"));
590 #endif
592 return __gethostbyaddr(addr, len, type, libPtr);
593 AROS_LIBFUNC_EXIT
596 static struct hostent * makehostent(struct SocketBase * libPtr,
597 struct hoststruct * HS,
598 char * ptr)
600 int n, i;
602 #if defined(__AROS__)
603 D(bug("[AROSTCP](gethostnameadr.c) makehostent()\n"));
604 #endif
606 i = (caddr_t)ALIGN(ptr) - (caddr_t)&HS->hostbuf;
607 n = i + sizeof (struct hostent) + HS->h_addr_count * sizeof (char *) +
608 HS->host_alias_count * sizeof (char *);
610 if (allocDataBuffer(&libPtr->hostents, n) == FALSE) {
611 writeErrnoValue(libPtr, ENOMEM);
612 return NULL;
615 * copy ent data to user buffer (pointers will be set later)
617 bcopy(HS->hostbuf, (caddr_t)(HOSTENT + 1), i);
620 * how much to add to old pointers
622 n = (caddr_t)HOSTENT + sizeof(struct hostent) - (caddr_t)&HS->hostbuf;
625 * fill vital fields in user hostent structure
627 HOSTENT->h_name = HS->host.h_name + n;
629 HOSTENT->h_aliases = (char **)((char *)(HOSTENT + 1) + i);
630 for (i = 0; HS->host_aliases[i]; i++)
631 HOSTENT->h_aliases[i] = HS->host_aliases[i] + n;
632 HOSTENT->h_aliases[i++] = NULL;
634 HOSTENT->h_addr_list = HOSTENT->h_aliases + i;
635 for (i = 0; HS->h_addr_ptrs[i]; i++)
636 HOSTENT->h_addr_list[i] = HS->h_addr_ptrs[i] + n;
637 HOSTENT->h_addr_list[i] = NULL;
639 return HOSTENT;
643 * id_addr variable is used by both the gethostname() and gethostid().
645 * host_name is the host_name configuration variable.
647 static ULONG id_addr = 0;
649 void findid(ULONG *); /* defined in net/if.c */
652 * Global host name and name length
654 char host_name[MAXHOSTNAMELEN+1] = { 0 };
655 size_t host_namelen = 0;
657 /****i* AmiTCP/sethostname *********************************************
659 * NAME
660 * sethostname -- set the name of the host
662 * SYNOPSIS
663 * error = sethostname(name, namelen);
665 * int sethostname(const char *, size_t);
667 * FUNCTION
668 * Set the name of the host to the given 'name' of length 'namelen'.
670 * INPUTS
671 * name - Pointer to the name string.
672 * namelen - Length of the name.
674 * RESULT
675 * error - 0 on success.
677 * EXAMPLE
679 * NOTES
680 * This function is not intended to be provided to the applications,
681 * this is for AmiTCP internal use only (at least for now).
683 * BUGS
685 * SEE ALSO
686 *****************************************************************************
689 int sethostname(const char *name, size_t namelen)
691 #if defined(__AROS__)
692 D(bug("[AROSTCP](gethostnameadr.c) sethostname()\n"));
693 #endif
695 if (namelen > MAXHOSTNAMELEN)
696 namelen = MAXHOSTNAMELEN;
698 memcpy(host_name, name, namelen);
699 host_name[namelen] = '\0';
700 host_namelen = namelen;
701 SetVar("HOSTNAME", name, namelen, GVF_GLOBAL_ONLY);
703 return 0;
706 /****** bsdsocket.library/gethostname *************************************
708 * NAME
709 * gethostname -- get the name of the host
711 * SYNOPSIS
712 * error = gethostname(name, namelen);
714 * long gethostname(char *, long);
716 * FUNCTION
717 * Get the name of the host to the buffer name of length namelen.
718 * The name is queried from the netdb and/or the name server if
719 * it is not explicitly configured (configuration variable
720 * HOSTNAME).
722 * INPUTS
723 * name - Pointer to the buffer where the name should be
724 * stored.
725 * namelen - Length of the buffer name.
727 * RESULT
728 * error - 0 on success.
730 * EXAMPLE
731 * char hostname[MAXHOSTNAMELEN];
732 * long error;
734 * error = gethostname(hostname, sizeof(hostname));
735 * if (error < 0)
736 * exit(10);
738 * printf("My name is \"%s\".\n", hostname);
740 * NOTES
742 * BUGS
743 * Unlike the Unix version, this version assures that the
744 * resulting string is always NULL-terminated.
746 * SEE ALSO
747 * gethostid()
748 *****************************************************************************
751 LONG __gethostname(STRPTR name, LONG namelen, struct SocketBase * libPtr)
753 size_t host_namelen = 0;
755 #if defined(__AROS__)
756 D(bug("[AROSTCP](gethostnameadr.c) __gethostname()\n"));
757 #endif
759 CHECK_TASK();
762 * Get the name with the gethostbyaddr(), if the name is not set yet.
764 if (*host_name == '\0')
766 struct hostent * hent;
767 /* gethostid() */
768 if (id_addr == 0)
769 findid(&id_addr);
771 if (id_addr != 0)
772 { /* query if we have an address */
773 hent = __gethostbyaddr((UBYTE *)&id_addr,
774 sizeof(id_addr), AF_INET, libPtr);
776 if (hent != NULL)
778 host_namelen = strlen(hent->h_name);
779 sethostname(hent->h_name, host_namelen);
781 else
783 #if defined(__AROS__)
784 D(bug("[AROSTCP](gethostnameadr.c) __gethostname: BUG!?! No Host ??\n"));
785 #endif
789 else host_namelen = strlen(host_name);
791 #if defined(__AROS__)
792 D(bug("[AROSTCP](gethostnameadr.c) __gethostname: namelen: %d host_namelen: %d\n", namelen, host_namelen));
793 #endif
796 * Copy the name to the user buffer. stccpy() ensures that the buffer
797 * is not written over and that it will be null-terminated.
799 if (namelen > host_namelen)
800 namelen = host_namelen;
801 else
802 namelen--; /* make space for the trailing '\0' */
804 memcpy(name, host_name, namelen);
805 name[namelen] = '\0';
807 API_STD_RETURN(0, 0);
810 AROS_LH2(LONG, gethostname,
811 AROS_LHA(STRPTR, name, A0),
812 AROS_LHA(LONG, namelen, D0),
813 struct SocketBase *, libPtr, 47, UL)
815 AROS_LIBFUNC_INIT
816 #if defined(__AROS__)
817 D(bug("[AROSTCP](gethostnameadr.c) gethostname()\n"));
818 #endif
819 return __gethostname(name, namelen, libPtr);
820 AROS_LIBFUNC_EXIT
823 /****** bsdsocket.library/gethostid ***************************************
825 * NAME
826 * gethostid -- get an unique 32-bit id to this host
828 * SYNOPSIS
829 * id = gethostid();
831 * ULONG gethostid(void);
833 * FUNCTION
834 * Return the 32-bit unique id for this host. The Internet
835 * address if the primary interface is used as the unique id.
836 * This means that this function is also a supported way to get
837 * the hosts IP address in AmiTCP/IP. If no interfaces are
838 * configured, zero is returned. Any non-loobpack interface with
839 * is preferred. Only if no other interfaces are present, is the
840 * loopback address returned.
842 * INPUTS
844 * RESULT
845 * id - non-zero on success.
847 * EXAMPLE
848 * ULONG id;
850 * id = gethostid();
851 * if (id == 0)
852 * exit(10);
854 * printf("My primary IP address is: %s.\n", Inet_NtoA(id));
856 * NOTES
857 * Non-zero id is returned as soon as a interface is configured.
858 * After that the id will not change, not even if the id is the
859 * address of the loopback interface.
861 * BUGS
863 * SEE ALSO
864 *****************************************************************************
867 /*ULONG SAVEDS gethostid(
868 REG(a6, struct SocketBase * libPtr))*/
869 AROS_LH0(ULONG, gethostid,
870 struct SocketBase *, libPtr, 48, UL)
872 AROS_LIBFUNC_INIT
874 #if defined(__AROS__)
875 D(bug("[AROSTCP](gethostnameadr.c) gethostid()\n"));
876 #endif
878 if (id_addr == 0)
879 findid(&id_addr);
880 return id_addr;
881 AROS_LIBFUNC_EXIT