summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c')
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c b/mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c
index 37174ab13..d18053c45 100644
--- a/mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c
+++ b/mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c
@@ -5,15 +5,10 @@
#include <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
-#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
-
-#include <stdio.h>
-
-extern int __dns_gethostbyx_r(const char* name, struct hostent* result,
- char *buf, size_t buflen,
- struct hostent **RESULT, int *h_errnop, int lookfor);
+#include "dietfeatures.h"
+#include "dietdns.h"
static int i2a(char* dest,unsigned int x) {
register unsigned int tmp=x;
@@ -24,6 +19,10 @@ static int i2a(char* dest,unsigned int x) {
return len+1;
}
+static char hexdigit(char c) {
+ return c>9?c-10+'a':c+'0';
+}
+
/* Oh boy, this interface sucks so badly, there are no words for it.
* Not one, not two, but _three_ error signalling methods! (*h_errnop
* nonzero? return value nonzero? *RESULT zero?) The glibc goons
@@ -31,21 +30,55 @@ static int i2a(char* dest,unsigned int x) {
int gethostbyaddr_r(const char* addr, size_t length, int format,
struct hostent* result, char *buf, size_t buflen,
struct hostent **RESULT, int *h_errnop) {
+ char tmpbuf[100];
+ char* tmp;
+ int res;
+ (void)length; /* shut gcc up about unused length. The length is implicit with format */
+#ifdef WANT_ETC_HOSTS
+ {
+ struct hostent* r;
+ while ((r=gethostent_r(buf,buflen))) {
+ if (r->h_addrtype==format && !memcmp(r->h_addr_list[0],addr,r->h_length)) { /* found it! */
+ memmove(result,r,sizeof(struct hostent));
+ *RESULT=result;
+ *h_errnop=0;
+ return 0;
+ }
+ }
+ endhostent();
+ }
+#endif
if (format==AF_INET) {
- char tmpbuf[50];
- char *tmp;
- int res;
tmp=tmpbuf+i2a(tmpbuf,(unsigned char)addr[3]); *tmp++='.';
tmp+=i2a(tmp,(unsigned char)addr[2]); *tmp++='.';
tmp+=i2a(tmp,(unsigned char)addr[1]); *tmp++='.';
tmp+=i2a(tmp,(unsigned char)addr[0]); strcpy(tmp,".in-addr.arpa");
- res= __dns_gethostbyx_r(tmpbuf,result,buf+4,buflen-4,RESULT,h_errnop,12); /* 12 == ns_t_ptr */
- if (res==0) {
- result->h_addr_list[0]=buf;
- result->h_addr_list[1]=buf;
- *(int*)buf=*(int*)addr;
+ } else if (format==AF_INET6) {
+ int i;
+ tmp=tmpbuf;
+ for (i=15; i>=0; --i) {
+ tmp[0]=hexdigit(addr[i]&0xf);
+ tmp[1]='.';
+ tmp[2]=hexdigit((addr[i]>>4)&0xf);
+ tmp[3]='.';
+ tmp+=4;
+ }
+ strcpy(tmp,".ip6.int");
+ } else return 1;
+ if (buflen<sizeof(struct hostent)+16) {
+ errno=ENOMEM;
+ *h_errnop=NO_RECOVERY;
+ return 1;
+ }
+ res= __dns_gethostbyx_r(tmpbuf,result,buf+16,buflen-16,RESULT,h_errnop,12); /* 12 == ns_t_ptr */
+ if (res==0) {
+ if (format==AF_INET) {
+ result->h_length=4;
+ result->h_addrtype=format;
}
- return res;
+ memcpy(buf,addr,result->h_length);
+ result->h_addr_list[0]=buf;
+ result->h_addr_list[1]=0;
}
- return 1;
+ return res;
}