summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libcruft
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/libcruft')
-rw-r--r--mdk-stage1/dietlibc/libcruft/dnscruft.c132
-rw-r--r--mdk-stage1/dietlibc/libcruft/dnscruft2.c264
-rw-r--r--mdk-stage1/dietlibc/libcruft/getgrgid.c13
-rw-r--r--mdk-stage1/dietlibc/libcruft/getgrnam.c13
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyaddr.c37
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyaddr_r.c67
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyname.c39
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyname2.c40
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyname2_r.c35
-rw-r--r--mdk-stage1/dietlibc/libcruft/gethostbyname_r.c54
-rw-r--r--mdk-stage1/dietlibc/libcruft/getlogin.c3
-rw-r--r--mdk-stage1/dietlibc/libcruft/getpagesize.c1
-rw-r--r--mdk-stage1/dietlibc/libcruft/getpass.c24
-rw-r--r--mdk-stage1/dietlibc/libcruft/getpwnam.c15
-rw-r--r--mdk-stage1/dietlibc/libcruft/getpwuid.c12
-rw-r--r--mdk-stage1/dietlibc/libcruft/getspnam.c15
-rw-r--r--mdk-stage1/dietlibc/libcruft/herrno_location.c9
-rw-r--r--mdk-stage1/dietlibc/libcruft/inet_aton.c2
-rw-r--r--mdk-stage1/dietlibc/libcruft/inet_ntoa.c2
-rw-r--r--mdk-stage1/dietlibc/libcruft/inet_ntop.c12
-rw-r--r--mdk-stage1/dietlibc/libcruft/inet_pton.c17
-rw-r--r--mdk-stage1/dietlibc/libcruft/initgroups.c3
-rw-r--r--mdk-stage1/dietlibc/libcruft/mkstemp.c14
-rw-r--r--mdk-stage1/dietlibc/libcruft/res_init.c6
24 files changed, 490 insertions, 339 deletions
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 <string.h>
#include <ctype.h>
#include <stdlib.h>
+#include <resolv.h>
+#include <net/if.h>
+#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 && !isspace(*buf)) ++buf;
if (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.nscount<MAXNS) ++_res.nscount;
+ *buf=save;
}
}
}
- if (!strncmp(buf,"search",6) || !strncmp(buf,"domain",6)) {
+#ifdef WANT_FULL_RESOLV_CONF
+ else if (!strncmp(buf,"search",6) || !strncmp(buf,"domain",6)) {
buf+=6;
+ while (buf<last && *buf!='\n') {
+ char save;
+ while (buf<last && (*buf==',' || isblank(*buf))) ++buf;
+ __dns_domains[__dns_search]=buf;
+ while (buf<last && (*buf=='.' || *buf=='-' || isalnum(*buf))) ++buf;
+ save=*buf;
+ if (buf<last) *buf=0;
+ if (__dns_domains[__dns_search]<buf &&
+ (__dns_domains[__dns_search]=strdup(__dns_domains[__dns_search])))
+ ++__dns_search;
+ if (buf<last) *buf=save;
+ }
+ continue;
}
+#endif
while (buf<last && *buf!='\n') ++buf;
while (buf<last && *buf=='\n') ++buf;
}
@@ -87,21 +150,24 @@ void __dns_readstartfiles() {
}
/* return length of decoded data or -1 */
-int __dns_decodename(unsigned char *packet,int offset,unsigned char *dest,int maxlen) {
+int __dns_decodename(unsigned char *packet,unsigned int offset,unsigned char *dest,
+ unsigned int maxlen,unsigned char* behindpacket) {
unsigned char *tmp;
unsigned char *max=dest+maxlen;
unsigned char *after=packet+offset;
int ok=0;
for (tmp=after; maxlen>0&&*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 (after<tmp+2) after=tmp+2;
tmp=packet+ofs;
ok=0;
} else {
unsigned int duh;
if (dest+*tmp+1>max) 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 <sys/poll.h>
#include <unistd.h>
#include <errno.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include "dietfeatures.h"
+#include "dietdns.h"
-#include <stdio.h>
+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 <grp.h>
#include <string.h>
-#include <stdlib.h>
+
+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 <grp.h>
#include <string.h>
-#include <stdlib.h>
+
+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 <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
-#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
+#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 <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;
}
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 <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
-#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
+#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 <string.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -6,35 +5,32 @@
#include <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
-#include <sys/poll.h>
#include <unistd.h>
#include <errno.h>
+#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 <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
-#include <sys/poll.h>
#include <unistd.h>
+#include "dietfeatures.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 "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 (buflen<L) { *h_errnop=ERANGE; return 1; }
+#ifdef WANT_ETC_HOSTS
+ {
+ struct hostent* r;
+ while ((r=gethostent_r(buf,buflen))) {
+ if (r->h_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 <string.h>
+#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <arpa/inet.h>
-#include <sys/poll.h>
#include <unistd.h>
+#include "dietfeatures.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 "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 (buflen<L) { *h_errnop=ERANGE; return 1; }
strcpy(buf,name);
+#ifdef WANT_INET_ADDR_DNS
+ result->h_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 <stdlib.h>
+#include <unistd.h>
-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 <limits.h>
#include <fcntl.h>
#include <string.h>
+#include <errno.h>
+
+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 <pwd.h>
#include <string.h>
-#include <stdlib.h>
-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 <string.h>
#include <stdlib.h>
+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 <shadow.h>
#include <string.h>
-#include <stdlib.h>
-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 <errno.h>
+#include <resolv.h>
+#include <netdb.h>
-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 <netinet/in.h>
#include <arpa/inet.h>
-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 <sys/socket.h>
#include <arpa/inet.h>
-
-extern char *inet_ntoa_r(struct in_addr in,char* buf);
+#include <string.h>
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 <stdlib.h>
+#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
+#include <string.h>
+#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 <string.h>
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 <unistd.h>
#include <fcntl.h>
#include <string.h>
+#include <stdlib.h>
#include <errno.h>
+#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<template) goto error;
+ for (i=0; i<6; ++i) if (tmp[i]!='X') { error: errno=EINVAL; return -1; }
randfd=open("/dev/urandom",O_RDONLY);
for (;;) {
read(randfd,&random,sizeof(random));
@@ -16,8 +23,9 @@ int mkstemp(char* template) {
int hexdigit=(random>>(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 <resolv.h>
+
extern void __dns_readstartfiles(void);
int res_init(void) {
- __dns_servers=0;
+ _res.nscount=0;
__dns_readstartfiles();
+ return 0;
}