From 09e967c2d732783b2579e4e120cd9b608404cb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwenol=C3=A9=20Beauchesne?= Date: Wed, 4 Jun 2003 18:31:57 +0000 Subject: Merge from R9_0-AMD64, most notably: - AMD64 support to insmod-busybox, minilibc, et al. - Sync with insmod-modutils 2.4.19 something but everyone should use dietlibc nowadays - Factor out compilation and prefix with $(DIET) for dietlibc builds - 64-bit & varargs fixes --- mdk-stage1/dietlibc/libcruft/dnscruft.c | 132 +++++++++--- mdk-stage1/dietlibc/libcruft/dnscruft2.c | 264 +++++++++++------------- mdk-stage1/dietlibc/libcruft/getgrgid.c | 13 +- mdk-stage1/dietlibc/libcruft/getgrnam.c | 13 +- mdk-stage1/dietlibc/libcruft/gethostbyaddr.c | 37 ++-- mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c | 67 ++++-- mdk-stage1/dietlibc/libcruft/gethostbyname.c | 39 ++-- mdk-stage1/dietlibc/libcruft/gethostbyname2.c | 40 ++-- mdk-stage1/dietlibc/libcruft/gethostbyname2_r.c | 35 +++- mdk-stage1/dietlibc/libcruft/gethostbyname_r.c | 54 ++++- mdk-stage1/dietlibc/libcruft/getlogin.c | 3 +- mdk-stage1/dietlibc/libcruft/getpagesize.c | 1 + mdk-stage1/dietlibc/libcruft/getpass.c | 24 ++- mdk-stage1/dietlibc/libcruft/getpwnam.c | 15 +- mdk-stage1/dietlibc/libcruft/getpwuid.c | 12 +- mdk-stage1/dietlibc/libcruft/getspnam.c | 15 +- mdk-stage1/dietlibc/libcruft/herrno_location.c | 9 +- mdk-stage1/dietlibc/libcruft/inet_aton.c | 2 +- mdk-stage1/dietlibc/libcruft/inet_ntoa.c | 2 - mdk-stage1/dietlibc/libcruft/inet_ntop.c | 12 +- mdk-stage1/dietlibc/libcruft/inet_pton.c | 17 +- mdk-stage1/dietlibc/libcruft/initgroups.c | 3 +- mdk-stage1/dietlibc/libcruft/mkstemp.c | 14 +- mdk-stage1/dietlibc/libcruft/res_init.c | 6 +- 24 files changed, 490 insertions(+), 339 deletions(-) (limited to 'mdk-stage1/dietlibc/libcruft') diff --git a/mdk-stage1/dietlibc/libcruft/dnscruft.c b/mdk-stage1/dietlibc/libcruft/dnscruft.c index d7a0efa50..bd8bee79a 100644 --- a/mdk-stage1/dietlibc/libcruft/dnscruft.c +++ b/mdk-stage1/dietlibc/libcruft/dnscruft.c @@ -7,51 +7,100 @@ #include #include #include +#include +#include +#include "dietfeatures.h" int __dns_fd=-1; +#ifdef WANT_IPV6_DNS +int __dns_fd6=-1; +#endif -void __dns_make_fd() { +/* the ad-hoc internal API from hell ;-) */ +void __dns_make_fd(void); +void __dns_make_fd6(void); +void __dns_readstartfiles(void); +int __dns_decodename(unsigned char *packet,unsigned int offset,unsigned char *dest, + unsigned int maxlen,unsigned char* behindpacket); + +void __dns_make_fd(void) { int tmp; struct sockaddr_in si; - if (__dns_fd>0) return; + if (__dns_fd>=0) return; tmp=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); - if (tmp<0) { - perror("__dns_make_fd!socket"); - return; - } + if (tmp<0) return; si.sin_family=AF_INET; si.sin_port=0; si.sin_addr.s_addr=INADDR_ANY; - if (bind(tmp,(struct sockaddr*)&si,sizeof(si))) { - perror("__dns_make_fd!bind"); - return; - } + if (bind(tmp,(struct sockaddr*)&si,sizeof(si))) return; __dns_fd=tmp; } -int __dns_servers=0; -struct sockaddr __dns_server_ips[8]; +#ifdef WANT_IPV6_DNS +void __dns_make_fd6(void) { + int tmp; + struct sockaddr_in6 si; + if (__dns_fd6>=0) return; + tmp=socket(PF_INET6,SOCK_DGRAM,IPPROTO_UDP); + if (tmp<0) return; + si.sin6_family=AF_INET6; + si.sin6_port=0; + memset(&si.sin6_addr,0,16); + if (bind(tmp,(struct sockaddr*)&si,sizeof(si))) return; + __dns_fd6=tmp; +} +#endif -int __dns_search=0; +static int parsesockaddr(const char* c,void* x) { + struct sockaddr_in to; + if (inet_aton(c,&to.sin_addr)) { + to.sin_port=htons(53); + to.sin_family=AF_INET; + memmove(x,&to,sizeof(struct sockaddr_in_pad)); + return 1; +#ifdef WANT_IPV6_DNS + } else { + struct sockaddr_in6 to6; + char* d=strchr(c,'%'); + to6.sin6_flowinfo=to6.sin6_scope_id=0; + if (d) + to6.sin6_scope_id=if_nametoindex(d+1); + if (inet_pton(AF_INET6,c,&to6.sin6_addr)) { + to6.sin6_port=htons(53); + to6.sin6_family=AF_INET6; + memmove(x,&to6,sizeof(struct sockaddr_in_pad)); + return 1; + } +#endif + } + return 0; +} + +#ifdef WANT_FULL_RESOLV_CONF +int __dns_search; char *__dns_domains[8]; +#endif -void __dns_readstartfiles() { +void __dns_readstartfiles(void) { int fd; - char *buf=alloca(4096); + char __buf[4096]; + char *buf=__buf; int len; - if (__dns_servers>0) return; + if (_res.nscount>0) return; { struct sockaddr_in to; +#ifdef WANT_IPV6_DNS + struct sockaddr_in6 to6; +#endif char *cacheip=getenv("DNSCACHEIP"); - if (cacheip) { - to.sin_port=htons(53); - to.sin_family=AF_INET; - if (inet_aton(cacheip,&to.sin_addr)) { - memmove(__dns_server_ips,&to,sizeof(struct sockaddr)); - ++__dns_servers; - } - } +#ifdef WANT_FULL_RESOLV_CONF + __dns_search=0; +#endif + if (cacheip) + if (parsesockaddr(cacheip,_res.nsaddr_list)) + ++_res.nscount; } + _res.options=RES_RECURSE; if ((fd=open("/etc/resolv.conf",O_RDONLY))<0) return; len=read(fd,buf,4096); close(fd); @@ -65,21 +114,35 @@ void __dns_readstartfiles() { { char *tmp=buf; struct sockaddr_in i; + char save; while (buf=last) break; + save=*buf; *buf=0; - if (inet_aton(tmp,&i.sin_addr)) { - i.sin_family=AF_INET; - i.sin_port=htons(53); - memmove(&__dns_server_ips[__dns_servers],&i,sizeof(struct sockaddr)); - if (__dns_servers<8) ++__dns_servers; - } + if (parsesockaddr(tmp,&_res.nsaddr_list[_res.nscount])) + if (_res.nscount0&&*tmp; ) { + if (tmp>=behindpacket) return -1; if ((*tmp>>6)==3) { /* goofy DNS decompression */ unsigned int ofs=((unsigned int)(*tmp&0x3f)<<8)|*(tmp+1); - if (ofs>=offset) return -1; /* RFC1035: "pointer to a _prior_ occurrance" */ + if (ofs>=(unsigned int)offset) return -1; /* RFC1035: "pointer to a _prior_ occurrance" */ if (aftermax) return -1; + if (tmp+*tmp+1>=behindpacket) return -1; for (duh=*tmp; duh>0; --duh) *dest++=*++tmp; *dest++='.'; ok=1; diff --git a/mdk-stage1/dietlibc/libcruft/dnscruft2.c b/mdk-stage1/dietlibc/libcruft/dnscruft2.c index b59207072..d4e132e42 100644 --- a/mdk-stage1/dietlibc/libcruft/dnscruft2.c +++ b/mdk-stage1/dietlibc/libcruft/dnscruft2.c @@ -8,178 +8,166 @@ #include #include #include +#include +#include +#include "dietfeatures.h" +#include "dietdns.h" -#include +extern void __dns_readstartfiles(void); -extern int h_errno; - -static char dnspacket[]="\xfe\xfe\001\000\000\001\000\000\000\000\000\000"; - -extern void __dns_make_fd(); -extern int __dns_fd; - -extern int __dns_servers; -extern struct sockaddr __dns_server_ips[]; - -extern void __dns_readstartfiles(); - -extern int __dns_decodename(unsigned char *packet,int offset,unsigned char *dest,int maxlen); +extern int __dns_decodename(unsigned char *packet,unsigned int offset,unsigned char *dest, + unsigned int maxlen,unsigned char* behindpacket); /* 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 * really outdid themselves with this one. */ +#ifdef WANT_FULL_RESOLV_CONF +static int __dns_gethostbyx_r_inner(const char* name, struct hostent* result, + char *buf, size_t buflen, + struct hostent **RESULT, int *h_errnop, int lookfor); + +static int __dns_gethostbyx_r_inner(const char* name, struct hostent* result, + char *buf, size_t buflen, + struct hostent **RESULT, int *h_errnop, int lookfor) { +#else int __dns_gethostbyx_r(const char* name, struct hostent* result, char *buf, size_t buflen, struct hostent **RESULT, int *h_errnop, int lookfor) { +#endif int names,ips; unsigned char *cur; unsigned char *max; - unsigned char packet[512]; - __dns_make_fd(); + unsigned char inpkg[1500]; + char* tmp; + int size; if (lookfor==1) { - result->h_aliases=(char**)(buf+8*4); result->h_addrtype=AF_INET; result->h_length=4; - result->h_addr_list=(char**)buf; } else { - result->h_aliases=(char**)(buf+8*16); result->h_addrtype=AF_INET6; result->h_length=16; - result->h_addr_list=(char**)buf; } + result->h_aliases=(char**)(buf+8*sizeof(char*)); + result->h_addr_list=(char**)buf; result->h_aliases[0]=0; cur=buf+16*sizeof(char*); max=buf+buflen; names=ips=0; - memmove(packet,dnspacket,12); - *(unsigned short*)packet=rand(); + if ((size=res_query(name,C_IN,lookfor,inpkg,512))<0) { +invalidpacket: + *h_errnop=HOST_NOT_FOUND; + return -1; + } { - unsigned char* x; - const char* y,* tmp; - x=packet+12; y=name; - while (*y) { - while (*y=='.') ++y; - for (tmp=y; *tmp && *tmp!='.'; ++tmp) ; - *x=tmp-y; - if (!(tmp-y)) break; - ++x; - if (x>=packet+510-(tmp-y)) { *h_errnop=ERANGE; return 1; } - memmove(x,y,tmp-y); - x+=tmp-y; - if (!*tmp) { - *x=0; - break; - } - y=tmp; - } - *++x= 0; *++x= lookfor; /* A */ - *++x= 0; *++x= 1; /* IN */ - ++x; + tmp=inpkg+12; { - int i; /* current server */ - int j; /* timeout count down */ - struct pollfd duh; - i=0; j=30; - __dns_readstartfiles(); - duh.fd=__dns_fd; - duh.events=POLLIN; - for (j=30; j>0; --j) { - sendto(__dns_fd,packet,x-packet,0,(struct sockaddr*)&(__dns_server_ips[i]),sizeof(struct sockaddr)); - if (++i > __dns_servers) i=0; - if (poll(&duh,1,1) == 1) { - /* read and parse answer */ - unsigned char inpkg[1500]; - /*int len=*/ read(__dns_fd,inpkg,1500); -#if 0 - { - int tft=open("duh",0); - read(tft,inpkg,1500); - close(tft); - } -#endif - /* header, question, answer, authority, additional */ - if (inpkg[0]!=packet[0] || inpkg[1]!=packet[1]) continue; /* wrong ID */ - if ((inpkg[2]&0xf9) != 0x81) continue; /* not answer */ - if ((inpkg[3]&0x0f) != 0) break; /* error */ - tmp=inpkg+12; - { - char name[257]; - unsigned short q=((unsigned short)inpkg[4]<<8)+inpkg[5]; - while (q>0) { - while (*tmp) tmp+=*tmp+1; - tmp+=5; - --q; - } - q=((unsigned short)inpkg[6]<<8)+inpkg[7]; - if (q<1) break; - while (q>0) { - int decofs=__dns_decodename(inpkg,tmp-(char*)inpkg,name,256); - if (decofs<0) break; - tmp=inpkg+decofs; - --q; - if (tmp[0]!=0 || tmp[1]!=lookfor || /* TYPE != A */ - tmp[2]!=0 || tmp[3]!=1) { /* CLASS != IN */ - if (tmp[1]==5) { /* CNAME */ - tmp+=10; - decofs=__dns_decodename(inpkg,tmp-(char*)inpkg,name,256); - if (decofs<0) break; - tmp=inpkg+decofs; - } else - break; - continue; - } - tmp+=10; /* skip type, class, TTL and length */ - { - int slen; - if (lookfor==1 || lookfor==28) /* A or AAAA*/ { - slen=strlen(name); - if (cur+slen+8+(lookfor==28?12:0)>=max) { *h_errnop=NO_RECOVERY; return 1; } - } else if (lookfor==12) /* PTR */ { - decofs=__dns_decodename(inpkg,tmp-(char*)inpkg,name,256); - if (decofs<0) break; - tmp=inpkg+decofs; - slen=strlen(name); - } else - slen=strlen(name); - strcpy(cur,name); - if (names==0) - result->h_name=cur; - else - result->h_aliases[names-1]=cur; - result->h_aliases[names]=0; - ++names; + char Name[257]; + unsigned short q=((unsigned short)inpkg[4]<<8)+inpkg[5]; + while (q>0) { + if (tmp>(char*)inpkg+size) goto invalidpacket; + while (*tmp) { tmp+=*tmp+1; if (tmp>(char*)inpkg+size) goto invalidpacket; } + tmp+=5; + --q; + } + if (tmp>(char*)inpkg+size) goto invalidpacket; + q=((unsigned short)inpkg[6]<<8)+inpkg[7]; + if (q<1) goto nodata; + while (q>0) { + int decofs=__dns_decodename(inpkg,(size_t)(tmp-(char*)inpkg),Name,256,inpkg+size); + if (decofs<0) break; + tmp=inpkg+decofs; + --q; + if (tmp[0]!=0 || tmp[1]!=lookfor || /* TYPE != A */ + tmp[2]!=0 || tmp[3]!=1) { /* CLASS != IN */ + if (tmp[1]==5) { /* CNAME */ + tmp+=10; + decofs=__dns_decodename(inpkg,(size_t)(tmp-(char*)inpkg),Name,256,inpkg+size); + if (decofs<0) break; + tmp=inpkg+decofs; + } else + break; + continue; + } + tmp+=10; /* skip type, class, TTL and length */ + { + int slen; + if (lookfor==1 || lookfor==28) /* A or AAAA*/ { + slen=strlen(Name); + if (cur+slen+8+(lookfor==28?12:0)>=max) { *h_errnop=NO_RECOVERY; return -1; } + } else if (lookfor==12) /* PTR */ { + decofs=__dns_decodename(inpkg,(size_t)(tmp-(char*)inpkg),Name,256,inpkg+size); + if (decofs<0) break; + tmp=inpkg+decofs; + slen=strlen(Name); + } else + slen=strlen(Name); + strcpy(cur,Name); + if (names==0) + result->h_name=cur; + else + result->h_aliases[names-1]=cur; + result->h_aliases[names]=0; + if (names<8) ++names; /* cur+=slen+1; */ - cur+=(slen|3)+1; - result->h_addr_list[ips++] = cur; - if (lookfor==1) /* A */ { - *(int*)cur=*(int*)tmp; - cur+=4; - result->h_addr_list[ips]=0; - } else if (lookfor==28) /* AAAA */ { - { - int i; - for (i=0; i<16; ++i) cur[i]=tmp[i]; - } - cur+=16; - result->h_addr_list[ips]=0; - } - } -/* puts(name); */ + cur+=(slen|3)+1; + result->h_addr_list[ips++] = cur; + if (lookfor==1) /* A */ { + *(int*)cur=*(int*)tmp; + cur+=4; + result->h_addr_list[ips]=0; + } else if (lookfor==28) /* AAAA */ { + { + int k; + for (k=0; k<16; ++k) cur[k]=tmp[k]; } + cur+=16; + result->h_addr_list[ips]=0; } -/* printf("%d answers\n",((unsigned short)inpkg[6]<<8)+inpkg[7]); - printf("ok\n");*/ - *h_errnop=0; - *RESULT=result; - return 0; } -/*kaputt:*/ +/* puts(Name); */ } } } - return 1; + if (!names) { +nodata: + *h_errnop=NO_DATA; + return -1; + } + *h_errnop=0; + *RESULT=result; + return 0; +} + +#ifdef WANT_FULL_RESOLV_CONF +extern int __dns_search; +extern char *__dns_domains[]; + +int __dns_gethostbyx_r(const char* name, struct hostent* result, + char *buf, size_t buflen, + struct hostent **RESULT, int *h_errnop, int lookfor) { + const char *tmp=name; + char Buf[MAXDNAME+1]; + int res; + size_t len=strlen(name); + int count=0; + __dns_readstartfiles(); + memmove(Buf,name,len); + Buf[len]=Buf[MAXDNAME]=0; +// printf("appending %d: %p\n",count,__dns_domains[count]); + while ((res=__dns_gethostbyx_r_inner(tmp,result,buf,buflen,RESULT,h_errnop,lookfor))) { + if (res==-1 && *h_errnop!=HOST_NOT_FOUND) break; + if (count==__dns_search) break; + Buf[len]='.'; +// printf("appending %d: %p (%s)\n",count,__dns_domains[count],__dns_domains[count]); + memccpy(Buf+len+1,__dns_domains[count],0,MAXDNAME-len-1); + tmp=Buf; + ++count; + } + return res; } +#endif + diff --git a/mdk-stage1/dietlibc/libcruft/getgrgid.c b/mdk-stage1/dietlibc/libcruft/getgrgid.c index 0c223056c..c0daac5e0 100644 --- a/mdk-stage1/dietlibc/libcruft/getgrgid.c +++ b/mdk-stage1/dietlibc/libcruft/getgrgid.c @@ -1,14 +1,11 @@ #include #include -#include + +extern struct group __group_pw; +extern char __group_buf[1000]; struct group *getgrgid(gid_t gid) { struct group *tmp; - setgrent(); - for (;;) { - tmp=getgrent(); - if (!tmp) return 0; - if (tmp->gr_gid == gid) - return tmp; - } + getgrgid_r(gid,&__group_pw,__group_buf,sizeof(__group_buf),&tmp); + return tmp; } diff --git a/mdk-stage1/dietlibc/libcruft/getgrnam.c b/mdk-stage1/dietlibc/libcruft/getgrnam.c index 1bdbb42a8..2664ab3f6 100644 --- a/mdk-stage1/dietlibc/libcruft/getgrnam.c +++ b/mdk-stage1/dietlibc/libcruft/getgrnam.c @@ -1,14 +1,11 @@ #include #include -#include + +extern struct group __group_pw; +extern char __group_buf[1000]; struct group *getgrnam(const char* name) { struct group *tmp; - setgrent(); - for (;;) { - tmp=getgrent(); - if (!tmp) return 0; - if (!strcmp(tmp->gr_name,name)) - return tmp; - } + getgrnam_r(name,&__group_pw,__group_buf,sizeof(__group_buf),&tmp); + return tmp; } diff --git a/mdk-stage1/dietlibc/libcruft/gethostbyaddr.c b/mdk-stage1/dietlibc/libcruft/gethostbyaddr.c index a4207d44d..74828df56 100644 --- a/mdk-stage1/dietlibc/libcruft/gethostbyaddr.c +++ b/mdk-stage1/dietlibc/libcruft/gethostbyaddr.c @@ -5,34 +5,31 @@ #include #include #include -#include #include #include +#include "dietwarning.h" -extern int h_errno; +static const int hostentsize=((sizeof(struct hostent)+15)&(-16)); + +extern size_t __dns_buflen; +extern char* __dns_buf; +extern void __dns_makebuf(size_t x); struct hostent* gethostbyaddr(const void *addr, socklen_t len, int type) { - static struct hostent hostbuf; + struct hostent *hostbuf; struct hostent *hp; - size_t hstbuflen; - char *tmphstbuf; int res; - int herr; - - hstbuflen = 1024; - /* Allocate buffer, remember to free it to avoid a memory leakage. */ - tmphstbuf = malloc (hstbuflen); - while ((res = gethostbyaddr_r (addr, len, type, &hostbuf, tmphstbuf, hstbuflen, - &hp, &herr)) == ERANGE) - { - /* Enlarge the buffer. */ - hstbuflen *= 2; - tmphstbuf = realloc (tmphstbuf, hstbuflen); - } - /* Check for errors. */ - if (res || hp == NULL) - return NULL; + __dns_buflen=512; + do { + __dns_makebuf(__dns_buflen*2); if (!__dns_buf) return 0; + hostbuf=(struct hostent*)__dns_buf; + } while ((res = gethostbyaddr_r (addr, len, type, hostbuf, + __dns_buf+hostentsize, + __dns_buflen-hostentsize, &hp, + &h_errno)) == ERANGE); + if (res) hp=0; return hp; } +link_warning("gethostbyaddr","warning: gethostbyaddr() leaks memory. Use gethostbyaddr_r instead!") 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 #include #include -#include #include #include - -#include - -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 (buflenh_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; } diff --git a/mdk-stage1/dietlibc/libcruft/gethostbyname.c b/mdk-stage1/dietlibc/libcruft/gethostbyname.c index 5db5bf3c5..b4849be96 100644 --- a/mdk-stage1/dietlibc/libcruft/gethostbyname.c +++ b/mdk-stage1/dietlibc/libcruft/gethostbyname.c @@ -5,35 +5,30 @@ #include #include #include -#include #include #include +#include "dietwarning.h" -extern int h_errno; +static const int hostentsize=((sizeof(struct hostent)+15)&(-16)); -struct hostent* gethostbyname (const char *host) -{ - static struct hostent hostbuf; +extern size_t __dns_buflen; +extern char* __dns_buf; +extern void __dns_makebuf(size_t x); + +struct hostent* gethostbyname (const char *host) { + struct hostent *hostbuf; struct hostent *hp; - size_t hstbuflen; - char *tmphstbuf; int res; - int herr; - - hstbuflen = 1024; - /* Allocate buffer, remember to free it to avoid a memory leakage. */ - tmphstbuf = malloc (hstbuflen); - while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen, - &hp, &herr)) == ERANGE) - { - /* Enlarge the buffer. */ - hstbuflen *= 2; - tmphstbuf = realloc (tmphstbuf, hstbuflen); - } - /* Check for errors. */ - if (res || hp == NULL) - return NULL; + __dns_buflen=512; + do { + __dns_makebuf(__dns_buflen*2); if (!__dns_buf) return 0; + hostbuf=(struct hostent*)__dns_buf; + } while ((res = gethostbyname_r (host, hostbuf, __dns_buf+hostentsize, + __dns_buflen-hostentsize, &hp, + &h_errno)) == ERANGE); + if (res) hp=0; return hp; } +link_warning("gethostbyname","warning: gethostbyname() leaks memory. Use gethostbyname_r instead!") diff --git a/mdk-stage1/dietlibc/libcruft/gethostbyname2.c b/mdk-stage1/dietlibc/libcruft/gethostbyname2.c index 3d8296616..1ca140dbe 100644 --- a/mdk-stage1/dietlibc/libcruft/gethostbyname2.c +++ b/mdk-stage1/dietlibc/libcruft/gethostbyname2.c @@ -1,4 +1,3 @@ - #include #include #include @@ -6,35 +5,32 @@ #include #include #include -#include #include #include +#include "dietwarning.h" + +static const int hostentsize=((sizeof(struct hostent)+15)&(-16)); -extern int h_errno; +extern size_t __dns_buflen; +extern char* __dns_buf; +extern void __dns_makebuf(size_t x); -struct hostent* gethostbyname2(const char *host,int AF) -{ - static struct hostent hostbuf; +struct hostent* gethostbyname2(const char *host,int AF) { + struct hostent *hostbuf; struct hostent *hp; - size_t hstbuflen; - char *tmphstbuf; int res; int herr; - hstbuflen = 1024; - /* Allocate buffer, remember to free it to avoid a memory leakage. */ - tmphstbuf = malloc (hstbuflen); - - while ((res = gethostbyname2_r (host, AF,&hostbuf, tmphstbuf, hstbuflen, - &hp, &herr)) == ERANGE) - { - /* Enlarge the buffer. */ - hstbuflen *= 2; - tmphstbuf = realloc (tmphstbuf, hstbuflen); - } - /* Check for errors. */ - if (res || hp == NULL) - return NULL; + __dns_buflen=512; + do { + __dns_makebuf(__dns_buflen*2); if (!__dns_buf) return 0; + hostbuf=(struct hostent*)__dns_buf; + } while ((res = gethostbyname2_r (host, AF, hostbuf, + __dns_buf+hostentsize, + __dns_buflen-hostentsize, &hp, + &herr)) == ERANGE); + if (res) hp=0; return hp; } +link_warning("gethostbyname2","warning: gethostbyname2() leaks memory. Use gethostbyname2_r instead!") diff --git a/mdk-stage1/dietlibc/libcruft/gethostbyname2_r.c b/mdk-stage1/dietlibc/libcruft/gethostbyname2_r.c index b505ccfbc..75da5e320 100644 --- a/mdk-stage1/dietlibc/libcruft/gethostbyname2_r.c +++ b/mdk-stage1/dietlibc/libcruft/gethostbyname2_r.c @@ -5,15 +5,10 @@ #include #include #include -#include #include +#include "dietfeatures.h" #include - -#include - -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 "dietdns.h" /* Oh boy, this interface sucks so badly, there are no words for it. * Not one, not two, but _three_ error signalling methods! (*h_errnop @@ -22,7 +17,7 @@ extern int __dns_gethostbyx_r(const char* name, struct hostent* result, int gethostbyname2_r(const char* name, int AF, struct hostent* result, char *buf, size_t buflen, struct hostent **RESULT, int *h_errnop) { - int L=strlen(name); + size_t L=strlen(name); int lookfor=0; switch (AF) { case AF_INET: lookfor=1; break; @@ -31,6 +26,30 @@ int gethostbyname2_r(const char* name, int AF, struct hostent* result, } result->h_name=buf; if (buflenh_addrtype==AF) { + int i; + if (!strcmp(r->h_name,name)) { /* found it! */ +found: + memmove(result,r,sizeof(struct hostent)); + *RESULT=result; + *h_errnop=0; + endhostent(); + return 0; + } + for (i=0; i<16; ++i) { + if (r->h_aliases[i]) { + if (!strcmp(r->h_aliases[i],name)) goto found; + } else break; + } + } + } + endhostent(); + } +#endif strcpy(buf,name); return __dns_gethostbyx_r(name,result,buf+L,buflen-L,RESULT,h_errnop,lookfor); } diff --git a/mdk-stage1/dietlibc/libcruft/gethostbyname_r.c b/mdk-stage1/dietlibc/libcruft/gethostbyname_r.c index d5a531f0f..d7a713e20 100644 --- a/mdk-stage1/dietlibc/libcruft/gethostbyname_r.c +++ b/mdk-stage1/dietlibc/libcruft/gethostbyname_r.c @@ -1,19 +1,15 @@ #include +#include #include #include #include #include #include #include -#include #include +#include "dietfeatures.h" #include - -#include - -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 "dietdns.h" /* Oh boy, this interface sucks so badly, there are no words for it. * Not one, not two, but _three_ error signalling methods! (*h_errnop @@ -22,9 +18,51 @@ extern int __dns_gethostbyx_r(const char* name, struct hostent* result, int gethostbyname_r(const char* name, struct hostent* result, char *buf, size_t buflen, struct hostent **RESULT, int *h_errnop) { - int L=strlen(name); + size_t L=strlen(name); result->h_name=buf; if (buflenh_addr_list=(char**)(buf+strlen(name)+1); + result->h_addr_list+=sizeof(unsigned long)-((unsigned long)(result->h_addr_list)&(sizeof(unsigned long)-1)); + result->h_addr_list[0]=(char*)&result->h_addr_list[2]; + if (inet_pton(AF_INET,name,result->h_addr_list[0])) { + result->h_addrtype=AF_INET; + result->h_length=4; +commonip: + result->h_aliases=result->h_addr_list+2*sizeof(char**); + result->h_aliases[0]=0; + result->h_addr_list[1]=0; + *RESULT=result; + *h_errnop=0; + return 0; + } else if (inet_pton(AF_INET6,name,result->h_addr_list[0])) { + result->h_addrtype=AF_INET6; + result->h_length=16; + goto commonip; + } +#endif +#ifdef WANT_ETC_HOSTS + { + struct hostent* r; + while ((r=gethostent_r(buf,buflen))) { + int i; + if (r->h_addrtype==AF_INET && !strcasecmp(r->h_name,name)) { /* found it! */ +found: + memmove(result,r,sizeof(struct hostent)); + *RESULT=result; + *h_errnop=0; + endhostent(); + return 0; + } + for (i=0; i<16; ++i) { + if (r->h_aliases[i]) { + if (!strcasecmp(r->h_aliases[i],name)) goto found; + } else break; + } + } + endhostent(); + } +#endif return __dns_gethostbyx_r(name,result,buf+L,buflen-L,RESULT,h_errnop,1); } diff --git a/mdk-stage1/dietlibc/libcruft/getlogin.c b/mdk-stage1/dietlibc/libcruft/getlogin.c index 359f44d9f..844d68c70 100644 --- a/mdk-stage1/dietlibc/libcruft/getlogin.c +++ b/mdk-stage1/dietlibc/libcruft/getlogin.c @@ -1,5 +1,6 @@ #include +#include -char* getlogin() { +char* getlogin(void) { return getenv("LOGNAME"); } diff --git a/mdk-stage1/dietlibc/libcruft/getpagesize.c b/mdk-stage1/dietlibc/libcruft/getpagesize.c index dea4a9693..536d3dcef 100644 --- a/mdk-stage1/dietlibc/libcruft/getpagesize.c +++ b/mdk-stage1/dietlibc/libcruft/getpagesize.c @@ -6,6 +6,7 @@ #define PAGE_SIZE 4096 #endif +size_t __libc_getpagesize(void); size_t __libc_getpagesize(void) { return PAGE_SIZE; } diff --git a/mdk-stage1/dietlibc/libcruft/getpass.c b/mdk-stage1/dietlibc/libcruft/getpass.c index 3da7cd2b3..2183284b3 100644 --- a/mdk-stage1/dietlibc/libcruft/getpass.c +++ b/mdk-stage1/dietlibc/libcruft/getpass.c @@ -3,30 +3,42 @@ #include #include #include +#include + +static inline int _tcsetattr(int fd,int optional,struct termios *termios_p) { + int tmp; + for (;;) { + if ((tmp=tcsetattr(fd,optional,termios_p))) + if (errno==EINTR) continue; + break; + } + return tmp; +} char *getpass(const char* prompt) { struct termios old,tmp; int out,in=open("/dev/tty",O_RDWR); int doclose=(in>=0); static char buf[PASS_MAX]; - if (doclose) { in=0; out=2; } else out=in; + if (!doclose) { in=0; out=2; } else out=in; if (!tcgetattr(in,&old)) { tmp=old; tmp.c_lflag &= ~(ECHO|ISIG); - tcsetattr(in,TCSAFLUSH,&tmp); + _tcsetattr(in,TCSAFLUSH,&tmp); } write(out,prompt,strlen(prompt)); { int nread,ofs=0; for (;;) { - nread=read(in,buf+ofs,PASS_MAX-ofs); - if (nread<0) { + nread=read(in,buf+ofs,1); + if (nread<=0) { + if (errno==EINTR) continue; buf[ofs]=0; break; } else if (ofs+nread>=PASS_MAX) { buf[PASS_MAX-1]=0; break; - } else if (buf[ofs+nread-1]=='\n') { + } else if (buf[ofs]=='\n') { buf[ofs+nread-1]=0; break; } @@ -34,7 +46,7 @@ char *getpass(const char* prompt) { } write(out,"\n",1); } - tcsetattr(in,TCSAFLUSH,&old); + _tcsetattr(in,TCSAFLUSH,&old); if (doclose) close(in); return buf; } diff --git a/mdk-stage1/dietlibc/libcruft/getpwnam.c b/mdk-stage1/dietlibc/libcruft/getpwnam.c index 53aae74d1..d2e204150 100644 --- a/mdk-stage1/dietlibc/libcruft/getpwnam.c +++ b/mdk-stage1/dietlibc/libcruft/getpwnam.c @@ -1,14 +1,11 @@ #include #include -#include -struct passwd *getpwnam(const char * name) { +extern struct passwd __passwd_pw; +extern char __passwd_buf[1000]; + +struct passwd *getpwnam(const char* name) { struct passwd *tmp; - setpwent(); - for (;;) { - tmp=getpwent(); - if (!tmp) return 0; - if (!strcmp(tmp->pw_name,name)) - return tmp; - } + getpwnam_r(name,&__passwd_pw,__passwd_buf,sizeof(__passwd_buf),&tmp); + return tmp; } diff --git a/mdk-stage1/dietlibc/libcruft/getpwuid.c b/mdk-stage1/dietlibc/libcruft/getpwuid.c index eef14e6e8..bca6a8a0c 100644 --- a/mdk-stage1/dietlibc/libcruft/getpwuid.c +++ b/mdk-stage1/dietlibc/libcruft/getpwuid.c @@ -2,13 +2,11 @@ #include #include +extern struct passwd __passwd_pw; +extern char __passwd_buf[1000]; + struct passwd *getpwuid(uid_t uid) { struct passwd *tmp; - setpwent(); - for (;;) { - tmp=getpwent(); - if (!tmp) return 0; - if (tmp->pw_uid==uid) - return tmp; - } + getpwuid_r(uid,&__passwd_pw,__passwd_buf,sizeof(__passwd_buf),&tmp); + return tmp; } diff --git a/mdk-stage1/dietlibc/libcruft/getspnam.c b/mdk-stage1/dietlibc/libcruft/getspnam.c index e6573345d..a4eafbfb2 100644 --- a/mdk-stage1/dietlibc/libcruft/getspnam.c +++ b/mdk-stage1/dietlibc/libcruft/getspnam.c @@ -1,14 +1,11 @@ #include #include -#include -struct spwd *getspnam(const char * name) { +extern struct spwd __shadow_pw; +extern char __shadow_buf[1000]; + +struct spwd *getspnam(const char* name) { struct spwd *tmp; - setspent(); - for (;;) { - tmp=getspent(); - if (!tmp) return 0; - if (!strcmp(tmp->sp_namp,name)) - return tmp; - } + getspnam_r(name,&__shadow_pw,__shadow_buf,sizeof(__shadow_buf),&tmp); + return tmp; } diff --git a/mdk-stage1/dietlibc/libcruft/herrno_location.c b/mdk-stage1/dietlibc/libcruft/herrno_location.c index 203f73d4b..5908fe212 100644 --- a/mdk-stage1/dietlibc/libcruft/herrno_location.c +++ b/mdk-stage1/dietlibc/libcruft/herrno_location.c @@ -1,5 +1,8 @@ -extern int h_errno; +#include +#include +#include -int *__h_errno_location() { return &h_errno; } +int *__h_errno_location(void); +int *__h_errno_location(void) { return &h_errno; } -int *h_errno_location() __attribute__((weak,alias("__h_errno_location"))); +int *h_errno_location(void) __attribute__((weak,alias("__h_errno_location"))); diff --git a/mdk-stage1/dietlibc/libcruft/inet_aton.c b/mdk-stage1/dietlibc/libcruft/inet_aton.c index ac7d9d007..01adb341e 100644 --- a/mdk-stage1/dietlibc/libcruft/inet_aton.c +++ b/mdk-stage1/dietlibc/libcruft/inet_aton.c @@ -24,7 +24,7 @@ int inet_aton(const char *cp, struct in_addr *inp) { char *tmp=(char*)cp; for (i=24; ;) { long j; - j=strtol(tmp,&tmp,0); + j=strtoul(tmp,&tmp,0); if (*tmp==0) { ip|=j; break; diff --git a/mdk-stage1/dietlibc/libcruft/inet_ntoa.c b/mdk-stage1/dietlibc/libcruft/inet_ntoa.c index f8c975f7a..632d81424 100644 --- a/mdk-stage1/dietlibc/libcruft/inet_ntoa.c +++ b/mdk-stage1/dietlibc/libcruft/inet_ntoa.c @@ -2,8 +2,6 @@ #include #include -extern char *inet_ntoa_r(struct in_addr in,char* buf); - char *inet_ntoa(struct in_addr in) { static char buf[20]; return inet_ntoa_r(in,buf); diff --git a/mdk-stage1/dietlibc/libcruft/inet_ntop.c b/mdk-stage1/dietlibc/libcruft/inet_ntop.c index 77c47f239..81bee0a90 100644 --- a/mdk-stage1/dietlibc/libcruft/inet_ntop.c +++ b/mdk-stage1/dietlibc/libcruft/inet_ntop.c @@ -1,6 +1,6 @@ +#include #include - -extern char *inet_ntoa_r(struct in_addr in,char* buf); +#include static const unsigned char V4mappedprefix[12]={0,0,0,0,0,0,0,0,0,0,0xff,0xff}; @@ -17,8 +17,7 @@ static int fmt_xlong(char* s,unsigned int i) { return s-bak+1; } -unsigned int fmt_ip6(char *s,const char ip[16]) -{ +static unsigned int fmt_ip6(char *s,const char ip[16]) { unsigned int len; unsigned int i; unsigned int temp; @@ -53,13 +52,16 @@ unsigned int fmt_ip6(char *s,const char ip[16]) } } } + if (compressing) { + *s++=':'; ++len; + } *s=0; return len; } const char* inet_ntop(int AF, const void *CP, char *BUF, size_t LEN) { char buf[100]; - int len; + size_t len; if (AF==AF_INET) { inet_ntoa_r(*(struct in_addr*)CP,buf); len=strlen(buf); diff --git a/mdk-stage1/dietlibc/libcruft/inet_pton.c b/mdk-stage1/dietlibc/libcruft/inet_pton.c index d5c17509c..a62785d5f 100644 --- a/mdk-stage1/dietlibc/libcruft/inet_pton.c +++ b/mdk-stage1/dietlibc/libcruft/inet_pton.c @@ -1,6 +1,9 @@ #include +#include #include #include +#include +#include "dietfeatures.h" static unsigned int scan_ip6(const char *s,char ip[16]) { @@ -9,8 +12,8 @@ static unsigned int scan_ip6(const char *s,char ip[16]) unsigned long u; char suffix[16]; - int prefixlen=0; - int suffixlen=0; + unsigned int prefixlen=0; + unsigned int suffixlen=0; for (i=0; i<16; i++) ip[i]=0; @@ -26,7 +29,7 @@ static unsigned int scan_ip6(const char *s,char ip[16]) } { char *tmp; - u=strtol(s,&tmp,16); + u=strtoul(s,&tmp,16); i=tmp-s; } @@ -60,7 +63,7 @@ static unsigned int scan_ip6(const char *s,char ip[16]) i=tmp-s; } if (!i) { - len--; + if (*s) len--; break; } if (suffixlen+prefixlen<=12 && s[i]=='.') { @@ -83,12 +86,14 @@ static unsigned int scan_ip6(const char *s,char ip[16]) } int inet_pton(int AF, const char *CP, void *BUF) { + int len; if (AF==AF_INET) { if (!inet_aton(CP,(struct in_addr*)BUF)) return 0; } else if (AF==AF_INET6) { - if (CP[scan_ip6(CP,BUF)]) - return 0; + if (CP[len=scan_ip6(CP,BUF)]) + if (CP[len]!='%') /* allow "fe80::220:e0ff:fe69:ad92%eth0" */ + return 0; } else { errno=EAFNOSUPPORT; return -1; diff --git a/mdk-stage1/dietlibc/libcruft/initgroups.c b/mdk-stage1/dietlibc/libcruft/initgroups.c index 7d24866e9..932fddfd6 100644 --- a/mdk-stage1/dietlibc/libcruft/initgroups.c +++ b/mdk-stage1/dietlibc/libcruft/initgroups.c @@ -3,9 +3,10 @@ #include int initgroups(const char *user, gid_t group) { - int n=0; + int n=1; gid_t grouplist[32]; struct group *g; + grouplist[0]=group; setgrent(); while ((g=getgrent())) { char **duh=g->gr_mem; diff --git a/mdk-stage1/dietlibc/libcruft/mkstemp.c b/mdk-stage1/dietlibc/libcruft/mkstemp.c index 3b24ecb54..7dc19d4ed 100644 --- a/mdk-stage1/dietlibc/libcruft/mkstemp.c +++ b/mdk-stage1/dietlibc/libcruft/mkstemp.c @@ -1,14 +1,21 @@ #include #include #include +#include #include +#include "dietfeatures.h" + +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 0 +#endif int mkstemp(char* template) { char *tmp=template+strlen(template)-6; int randfd; int i,res; unsigned int random; - for (i=0; i<6; ++i) if (tmp[i]!='X') { __set_errno(EINVAL); return -1; } + if (tmp>(i*5))&0x1f; tmp[i]=hexdigit>9?hexdigit+'a'-10:hexdigit+'0'; } - res=open(template,O_CREAT|O_RDWR|O_EXCL,0600); - if (res>=0) return res; + res=open(template,O_CREAT|O_RDWR|O_EXCL|O_NOFOLLOW,0600); + if (res>=0 || errno!=EEXIST) break; } close(randfd); + return res; } diff --git a/mdk-stage1/dietlibc/libcruft/res_init.c b/mdk-stage1/dietlibc/libcruft/res_init.c index 9322af298..78baa2b30 100644 --- a/mdk-stage1/dietlibc/libcruft/res_init.c +++ b/mdk-stage1/dietlibc/libcruft/res_init.c @@ -1,7 +1,9 @@ -extern int __dns_servers; +#include + extern void __dns_readstartfiles(void); int res_init(void) { - __dns_servers=0; + _res.nscount=0; __dns_readstartfiles(); + return 0; } -- cgit v1.2.1