From 4cd6a4a5d7e49d54d53dcf4a6f3393d50bd88e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwenol=C3=A9=20Beauchesne?= Date: Wed, 4 Jun 2003 18:44:09 +0000 Subject: Import dietlibc 0.22 + other fixes for AMD64 --- mdk-stage1/dietlibc/libugly/difftime.c | 8 ++ mdk-stage1/dietlibc/libugly/dirfd.c | 8 ++ mdk-stage1/dietlibc/libugly/freeaddrinfo.c | 11 ++ mdk-stage1/dietlibc/libugly/ftime.c | 15 +++ mdk-stage1/dietlibc/libugly/gai_strerror.c | 13 +++ mdk-stage1/dietlibc/libugly/getaddrinfo.c | 140 +++++++++++++++++++++++ mdk-stage1/dietlibc/libugly/gethostent.c | 116 +++++++++++++++++++ mdk-stage1/dietlibc/libugly/getnameinfo.c | 46 ++++++++ mdk-stage1/dietlibc/libugly/getprotobyname.c | 12 ++ mdk-stage1/dietlibc/libugly/getprotobyname_r.c | 17 +++ mdk-stage1/dietlibc/libugly/getprotobynumber.c | 12 ++ mdk-stage1/dietlibc/libugly/getprotobynumber_r.c | 13 +++ mdk-stage1/dietlibc/libugly/getprotoent_r.c | 78 +++++++++++++ mdk-stage1/dietlibc/libugly/getservbyname.c | 12 ++ mdk-stage1/dietlibc/libugly/getservbyname_r.c | 18 +++ mdk-stage1/dietlibc/libugly/getservbyport.c | 12 ++ mdk-stage1/dietlibc/libugly/getservbyport_r.c | 13 +++ mdk-stage1/dietlibc/libugly/getservent.c | 10 ++ mdk-stage1/dietlibc/libugly/getservent_r.c | 91 +++++++++++++++ mdk-stage1/dietlibc/libugly/grantpt.c | 13 +++ mdk-stage1/dietlibc/libugly/hasmntopt.c | 18 +++ mdk-stage1/dietlibc/libugly/iconv.c | 71 ++++++++++++ mdk-stage1/dietlibc/libugly/iconv_close.c | 7 ++ mdk-stage1/dietlibc/libugly/iconv_open.c | 28 +++++ mdk-stage1/dietlibc/libugly/netent.c | 130 +++++++++++++++++++++ mdk-stage1/dietlibc/libugly/openpty.c | 54 +++++++++ mdk-stage1/dietlibc/libugly/protoent_buf.c | 5 + mdk-stage1/dietlibc/libugly/ptsname.c | 17 +++ mdk-stage1/dietlibc/libugly/putpwent.c | 19 +++ mdk-stage1/dietlibc/libugly/servent_buf.c | 5 + mdk-stage1/dietlibc/libugly/strndup.c | 10 ++ mdk-stage1/dietlibc/libugly/timezone.c | 3 + mdk-stage1/dietlibc/libugly/unlockpt.c | 10 ++ mdk-stage1/dietlibc/libugly/utent.c | 103 +++++++++++++++++ mdk-stage1/dietlibc/libugly/wtent.c | 30 +++++ 35 files changed, 1168 insertions(+) create mode 100644 mdk-stage1/dietlibc/libugly/difftime.c create mode 100644 mdk-stage1/dietlibc/libugly/dirfd.c create mode 100644 mdk-stage1/dietlibc/libugly/freeaddrinfo.c create mode 100644 mdk-stage1/dietlibc/libugly/ftime.c create mode 100644 mdk-stage1/dietlibc/libugly/gai_strerror.c create mode 100644 mdk-stage1/dietlibc/libugly/getaddrinfo.c create mode 100644 mdk-stage1/dietlibc/libugly/gethostent.c create mode 100644 mdk-stage1/dietlibc/libugly/getnameinfo.c create mode 100644 mdk-stage1/dietlibc/libugly/getprotobyname.c create mode 100644 mdk-stage1/dietlibc/libugly/getprotobyname_r.c create mode 100644 mdk-stage1/dietlibc/libugly/getprotobynumber.c create mode 100644 mdk-stage1/dietlibc/libugly/getprotobynumber_r.c create mode 100644 mdk-stage1/dietlibc/libugly/getprotoent_r.c create mode 100644 mdk-stage1/dietlibc/libugly/getservbyname.c create mode 100644 mdk-stage1/dietlibc/libugly/getservbyname_r.c create mode 100644 mdk-stage1/dietlibc/libugly/getservbyport.c create mode 100644 mdk-stage1/dietlibc/libugly/getservbyport_r.c create mode 100644 mdk-stage1/dietlibc/libugly/getservent.c create mode 100644 mdk-stage1/dietlibc/libugly/getservent_r.c create mode 100644 mdk-stage1/dietlibc/libugly/grantpt.c create mode 100644 mdk-stage1/dietlibc/libugly/hasmntopt.c create mode 100644 mdk-stage1/dietlibc/libugly/iconv.c create mode 100644 mdk-stage1/dietlibc/libugly/iconv_close.c create mode 100644 mdk-stage1/dietlibc/libugly/iconv_open.c create mode 100644 mdk-stage1/dietlibc/libugly/netent.c create mode 100644 mdk-stage1/dietlibc/libugly/openpty.c create mode 100644 mdk-stage1/dietlibc/libugly/protoent_buf.c create mode 100644 mdk-stage1/dietlibc/libugly/ptsname.c create mode 100644 mdk-stage1/dietlibc/libugly/putpwent.c create mode 100644 mdk-stage1/dietlibc/libugly/servent_buf.c create mode 100644 mdk-stage1/dietlibc/libugly/strndup.c create mode 100644 mdk-stage1/dietlibc/libugly/timezone.c create mode 100644 mdk-stage1/dietlibc/libugly/unlockpt.c create mode 100644 mdk-stage1/dietlibc/libugly/utent.c create mode 100644 mdk-stage1/dietlibc/libugly/wtent.c (limited to 'mdk-stage1/dietlibc/libugly') diff --git a/mdk-stage1/dietlibc/libugly/difftime.c b/mdk-stage1/dietlibc/libugly/difftime.c new file mode 100644 index 000000000..fc71363c7 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/difftime.c @@ -0,0 +1,8 @@ +#include +#include "../dietwarning.h" + +double difftime(time_t time1, time_t time2) { + return (double)time1 - (double)time2; +} + +link_warning("difftime","warning: difftime introduces an unnecessary floating point dependency. Don't use it!") diff --git a/mdk-stage1/dietlibc/libugly/dirfd.c b/mdk-stage1/dietlibc/libugly/dirfd.c new file mode 100644 index 000000000..8d5af8b9a --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/dirfd.c @@ -0,0 +1,8 @@ +#include +#include "dietdirent.h" +#define _BSD_SOURCE +#include + +int dirfd(DIR* dirp) { + return dirp->fd; +} diff --git a/mdk-stage1/dietlibc/libugly/freeaddrinfo.c b/mdk-stage1/dietlibc/libugly/freeaddrinfo.c new file mode 100644 index 000000000..72a13f5e1 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/freeaddrinfo.c @@ -0,0 +1,11 @@ +#include +#include + +void freeaddrinfo(struct addrinfo *res) { + while (res) { + struct addrinfo *duh; + duh=res; + res=res->ai_next; + free(duh); + } +} diff --git a/mdk-stage1/dietlibc/libugly/ftime.c b/mdk-stage1/dietlibc/libugly/ftime.c new file mode 100644 index 000000000..3aa2d15c3 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/ftime.c @@ -0,0 +1,15 @@ +#include +#include +#include + +int ftime(struct timeb *tp) { + struct timeval tv; + struct timezone tz; + int ret=gettimeofday(&tv,&tz); + tp->time = tv.tv_sec; + tp->millitm = tv.tv_usec/1000; + tp->timezone = tz.tz_minuteswest; + tp->dstflag = tz.tz_dsttime; + return ret; +} + diff --git a/mdk-stage1/dietlibc/libugly/gai_strerror.c b/mdk-stage1/dietlibc/libugly/gai_strerror.c new file mode 100644 index 000000000..9dc4f5dde --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/gai_strerror.c @@ -0,0 +1,13 @@ +#include + +const char* gai_strerror(int error) { + switch (error) { + case EAI_FAMILY: return "family not supported"; + case EAI_SOCKTYPE: return "socket type not supported"; + case EAI_NONAME: return "unknown host"; + case EAI_SERVICE: return "unknown service"; + case EAI_MEMORY: return "memory allocation failure"; + case EAI_AGAIN: return "temporary failure"; + } + return "DNS error. Sorry."; +} diff --git a/mdk-stage1/dietlibc/libugly/getaddrinfo.c b/mdk-stage1/dietlibc/libugly/getaddrinfo.c new file mode 100644 index 000000000..a4675d92b --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getaddrinfo.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include +#include +#include + +/* XXX TODO FIXME */ + +int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { + struct addrinfo **tmp; + int family; + tmp=res; *res=0; + if (hints) { + if (hints->ai_family && hints->ai_family != PF_INET6 && hints->ai_family != PF_INET) return EAI_FAMILY; + if (hints->ai_socktype && hints->ai_socktype != SOCK_STREAM && hints->ai_socktype != SOCK_DGRAM) return EAI_SOCKTYPE; + } + for (family=PF_INET6; ; family=PF_INET) { + if (!hints || hints->ai_family==family || hints->ai_family==AF_UNSPEC) { /* IPv6 addresses are OK */ + struct hostent h; + struct hostent *H; + int herrno=0; + char buf[4096]; + int lookupok=0; + h.h_addr_list=(char**)buf+16; + if (node) { + if (inet_pton(family,node,buf)>0) { + h.h_name=(char*)node; + h.h_addr_list[0]=buf; + lookupok=1; + } else if ((!hints || !(hints->ai_flags&AI_NUMERICHOST)) && + !gethostbyname2_r(node,family,&h,buf,4096,&H,&herrno)) { + lookupok=1; + } else { + if (herrno==TRY_AGAIN) { freeaddrinfo(*res); return EAI_AGAIN; } + } + } else { + h.h_name=0; + h.h_addr_list[0]=buf; + memset(buf,0,16); + if (!hints || !(hints->ai_flags&AI_PASSIVE)) { + if (family==AF_INET) { + buf[0]=127; buf[3]=1; + } else + buf[15]=1; + } + lookupok=1; + } + if (lookupok) { + struct ai_v6 { + struct addrinfo ai; + union { + struct sockaddr_in6 ip6; + struct sockaddr_in ip4; + } ip; + char name[1]; + } *foo; + unsigned short port; + int len=sizeof(struct ai_v6)+(h.h_name?strlen(h.h_name):0); + if (!(foo=malloc(len))) goto error; + foo->ai.ai_next=0; + foo->ai.ai_socktype=SOCK_STREAM; + foo->ai.ai_protocol=IPPROTO_TCP; + foo->ai.ai_addrlen=family==PF_INET6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in); + foo->ai.ai_addr=(struct sockaddr*)&foo->ip; + if (family==PF_INET6) { + memset(&foo->ip,0,sizeof(foo->ip)); + memmove(&foo->ip.ip6.sin6_addr,h.h_addr_list[0],16); + } else { + memmove(&foo->ip.ip4.sin_addr,h.h_addr_list[0],4); + } + foo->ip.ip6.sin6_family=foo->ai.ai_family=family; + if (h.h_name) { + foo->ai.ai_canonname=foo->name; + memmove(foo->name,h.h_name,strlen(h.h_name)+1); + } else + foo->ai.ai_canonname=0; + if (!hints || hints->ai_socktype!=SOCK_DGRAM) { /* TCP is OK */ + char *x; + port=htons(strtol(service?service:"0",&x,0)); + if (*x) { /* service is not numeric :-( */ + struct servent* se; + if ((se=getservbyname(service,"tcp"))) { /* found a service. */ + port=se->s_port; + blah1: + if (family==PF_INET6) + foo->ip.ip6.sin6_port=port; + else + foo->ip.ip4.sin_port=port; + if (!*tmp) *tmp=&(foo->ai); else (*tmp)->ai_next=&(foo->ai); + if (!(foo=malloc(len))) goto error; + memmove(foo,*tmp,len); + tmp=&(*tmp)->ai_next; + foo->ai.ai_addr=(struct sockaddr*)&foo->ip; + if (foo->ai.ai_canonname) + foo->ai.ai_canonname=foo->name; + } else { + freeaddrinfo(*res); + return EAI_SERVICE; + } + } else goto blah1; + } + foo->ai.ai_socktype=SOCK_DGRAM; + foo->ai.ai_protocol=IPPROTO_UDP; + if (!hints || hints->ai_socktype!=SOCK_STREAM) { /* UDP is OK */ + char *x; + port=htons(strtol(service?service:"0",&x,0)); + if (*x) { /* service is not numeric :-( */ + struct servent* se; + if ((se=getservbyname(service,"udp"))) { /* found a service. */ + port=se->s_port; + blah2: + if (family==PF_INET6) + foo->ip.ip6.sin6_port=port; + else + foo->ip.ip4.sin_port=port; + if (!*tmp) *tmp=&(foo->ai); else (*tmp)->ai_next=&(foo->ai); + if (!(foo=malloc(len))) goto error; + memmove(foo,*tmp,len); + tmp=&(*tmp)->ai_next; + foo->ai.ai_addr=(struct sockaddr*)&foo->ip; + foo->ai.ai_canonname=foo->name; + } else { + freeaddrinfo(*res); + return EAI_SERVICE; + } + } else goto blah2; + } + free(foo); + } + } + if (family==PF_INET) break; + } + if (*res==0) return EAI_NONAME; /* kludge kludge... */ + return 0; +error: + freeaddrinfo(*res); + return EAI_MEMORY; +} diff --git a/mdk-stage1/dietlibc/libugly/gethostent.c b/mdk-stage1/dietlibc/libugly/gethostent.c new file mode 100644 index 000000000..fe92beacf --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/gethostent.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dietfeatures.h" + +static char* hostmap=0; +static unsigned int hostlen; + +static char *cur; + +/* ::1 localhost6 alias1 alias2 # internet protocol, pseudo protocol number */ +struct hostent* gethostent_r(char* buf, int len) { + char *dest; + struct hostent* pe=(struct hostent*)buf; + char* last; + char* max=buf+len; + int aliasidx; + if (!hostmap) { + int hostfd=open(_PATH_HOSTS,O_RDONLY); + if (hostfd<0) return 0; + hostlen=lseek(hostfd,0,SEEK_END); + hostmap=mmap(0,hostlen,PROT_READ|PROT_WRITE,MAP_PRIVATE,hostfd,0); + if ((long)hostmap==(-1)) { close(hostfd); hostmap=0; goto error; } + close(hostfd); hostfd=-1; + cur=hostmap; + } + last=hostmap+hostlen; +again: + if ((size_t)lenh_name=0; + pe->h_aliases=(char**)dest; pe->h_aliases[0]=0; dest+=10*sizeof(char*); + pe->h_addr_list=(char**)dest; dest+=2*sizeof(char**); + if (cur>=last) return 0; + if (*cur=='#' || *cur=='\n') goto parseerror; + /* first, the ip number */ + pe->h_name=cur; + while (cur=last) return 0; + if (*cur=='\n') goto parseerror; + { + char save=*cur; + *cur=0; + pe->h_addr_list[0]=dest; + pe->h_addr_list[1]=0; + if (max-dest<16) goto nospace; + if (inet_pton(AF_INET6,pe->h_name,dest)>0) { + pe->h_addrtype=AF_INET6; + pe->h_length=16; + dest+=16; + } else if (inet_pton(AF_INET,pe->h_name,dest)>0) { + pe->h_addrtype=AF_INET; + pe->h_length=4; + dest+=4; + } else { + *cur=save; + goto parseerror; + } + *cur=save; + } + ++cur; + /* now the aliases */ + for (aliasidx=0;aliasidx<9;++aliasidx) { + while (curh_aliases[aliasidx]=cur; + while (curh_aliases[aliasidx]; + int len=cur-from; + if (max-desth_aliases[aliasidx]=dest; + memmove(dest,from,(size_t)(cur-from)); + dest+=len; + *dest=0; ++dest; + } + if (*cur=='\n') { ++cur; ++aliasidx; break; } + if (cur>=last || !isblank(*cur)) break; + cur++; + } + pe->h_aliases[aliasidx]=0; + pe->h_name=pe->h_aliases[0]; + pe->h_aliases++; + return pe; +parseerror: + while (cur +#include +#include +#include +#include + +extern int __ltostr(char *s, int size, unsigned long i, int base, char UpCase); + +int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) { + sa_family_t f=((struct sockaddr_storage *)sa)->ss_family; + (void)salen; /* shut gcc up about unused salen */ + if (host && hostlen>0) { /* user wants me to resolve the host name */ + register const char*addr=(f==AF_INET6)?(char*)&((struct sockaddr_in6*)sa)->sin6_addr: + (char*)&((struct sockaddr_in*)sa)->sin_addr; + if (flags&NI_NUMERICHOST) { + if (!inet_ntop(f,addr,host,hostlen)) + return EAI_NONAME; + } else { + char buf[4096]; + struct hostent h; + struct hostent *H; + int herrno; + if (gethostbyaddr_r(addr,f==AF_INET6?16:4,f,&h,buf,4096,&H,&herrno)) { + switch (herrno) { + case TRY_AGAIN: return EAI_AGAIN; + case NO_DATA: + case HOST_NOT_FOUND: return EAI_NONAME; + } + } + strncpy(host,h.h_name,hostlen-1); + host[hostlen-1]=0; + } + } + if (serv && servlen>0) { + register short int port=(f==AF_INET6)?((struct sockaddr_in6*)sa)->sin6_port:((struct sockaddr_in*)sa)->sin_port; + if (flags&NI_NUMERICSERV) { + __ltostr(serv,servlen,ntohs(port),10,0); + } else { + struct servent *s; + if (!(s=getservbyport(port,flags&NI_DGRAM?"udp":"tcp"))) + return EAI_SERVICE; + } + } + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/getprotobyname.c b/mdk-stage1/dietlibc/libugly/getprotobyname.c new file mode 100644 index 000000000..1de348791 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getprotobyname.c @@ -0,0 +1,12 @@ +#include +#include + +extern struct protoent __protoent_pw; +extern char __protoent_buf[1000]; + +struct protoent *getprotobyname(const char *name) { + struct protoent* tmp; + if (getprotobyname_r(name,&__protoent_pw,__protoent_buf,sizeof(__protoent_buf),&tmp)==0) + return tmp; + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/getprotobyname_r.c b/mdk-stage1/dietlibc/libugly/getprotobyname_r.c new file mode 100644 index 000000000..3b1219aa7 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getprotobyname_r.c @@ -0,0 +1,17 @@ +#include +#include + +extern int getprotobyname_r(const char* name, + struct protoent *res, char *buf, size_t buflen, + struct protoent **res_sig) { + while (!getprotoent_r(res,buf,buflen,res_sig)) { + int i; + if (!strcmp(res->p_name,name)) goto found; + for (i=0; res->p_aliases[i]; ++i) + if (!strcmp(res->p_aliases[i],name)) goto found; + } + *res_sig=0; +found: + endprotoent(); + return *res_sig?0:-1; +} diff --git a/mdk-stage1/dietlibc/libugly/getprotobynumber.c b/mdk-stage1/dietlibc/libugly/getprotobynumber.c new file mode 100644 index 000000000..6170753e2 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getprotobynumber.c @@ -0,0 +1,12 @@ +#include +#include + +extern struct protoent __protoent_pw; +extern char __protoent_buf[1000]; + +struct protoent *getprotobynumber(int proto) { + struct protoent* tmp; + if (getprotobynumber_r(proto,&__protoent_pw,__protoent_buf,sizeof(__protoent_buf),&tmp)==0) + return tmp; + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/getprotobynumber_r.c b/mdk-stage1/dietlibc/libugly/getprotobynumber_r.c new file mode 100644 index 000000000..2ca439fc6 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getprotobynumber_r.c @@ -0,0 +1,13 @@ +#include +#include + +extern int getprotobynumber_r(int proto, + struct protoent *res, char *buf, size_t buflen, + struct protoent **res_sig) { + while (!getprotoent_r(res,buf,buflen,res_sig)) + if (proto==res->p_proto) goto found; + *res_sig=0; +found: + endprotoent(); + return *res_sig?0:-1; +} diff --git a/mdk-stage1/dietlibc/libugly/getprotoent_r.c b/mdk-stage1/dietlibc/libugly/getprotoent_r.c new file mode 100644 index 000000000..aa9af79c3 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getprotoent_r.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include "parselib.h" + +static struct state __ps; + +void setprotoent(int stayopen) { + (void)stayopen; + __prepare_parse(_PATH_PROTOCOLS,&__ps); +} + +void endprotoent(void) { + __end_parse(&__ps); +} + +#define ALIASES 16 + +/* "igmp 2 IGMP # internet group management protocol" */ +int getprotoent_r(struct protoent *res, char *buf, size_t buflen, + struct protoent **res_sig) { + size_t i,j,n,g; + unsigned long l; + if (!__ps.buffirst) setprotoent(0); + if (!__ps.buffirst) goto error; + if (__ps.cur>=__ps.buflen) goto error; + res->p_aliases=(char**)buf; +/* getprotoent */ +again: + n=ALIASES*sizeof(char*); g=0; + for (i=0; i<3; ++i) { + char found; + __ps.cur+=__parse_ws(&__ps); + if (__ps.cur>=__ps.buflen) { if (i==2) break; else goto error; } + j=__parse_nws(&__ps); + if (!isblank(found=__ps.buffirst[__ps.cur+j])) { + if (i==2) break; /* it's ok, no (more) aliases necessary */ +parseerror: + while (__ps.cur+j<__ps.buflen) { + if (__ps.buffirst[__ps.cur+j]=='\n') { + __ps.cur+=j+1; + goto again; + } + ++j; + } + } + switch (i) { + case 0: + res->p_name=buf+n; +copy: + if ((size_t)buflen<=n+j) goto error; + memcpy(buf+n,__ps.buffirst+__ps.cur,j); + buf[n+j]=0; + n+=j+1; + if ((found=='\n' || found=='#') && i==1) i=3; + break; + case 1: + if (scan_ulong(__ps.buffirst+__ps.cur,&l)!=j) goto parseerror; + res->p_proto=l; + break; + case 2: + res->p_aliases[g]=buf+n; + ++g; + if (g==(ALIASES-1)) break; + --i; /* again */ + goto copy; + } + __ps.cur+=j+1; + } + res->p_aliases[g]=0; + *res_sig=res; + return 0; +error: + *res_sig=0;/* the glibc people should be taken behind the barn and shot */ + return -1; +} diff --git a/mdk-stage1/dietlibc/libugly/getservbyname.c b/mdk-stage1/dietlibc/libugly/getservbyname.c new file mode 100644 index 000000000..f1c74eaa9 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getservbyname.c @@ -0,0 +1,12 @@ +#include +#include + +extern struct servent __servent_pw; +extern char __servent_buf[1000]; + +struct servent *getservbyname(const char *name, const char *proto) { + struct servent* tmp; + if (getservbyname_r(name,proto,&__servent_pw,__servent_buf,sizeof(__servent_buf),&tmp)==0) + return tmp; + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/getservbyname_r.c b/mdk-stage1/dietlibc/libugly/getservbyname_r.c new file mode 100644 index 000000000..f523a01ca --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getservbyname_r.c @@ -0,0 +1,18 @@ +#include +#include + +extern int getservbyname_r(const char* name,const char* proto, + struct servent *res, char *buf, size_t buflen, + struct servent **res_sig) { + while (!getservent_r(res,buf,buflen,res_sig)) { + int i; + if (proto && strcmp(res->s_proto,proto)) continue; + if (!strcmp(res->s_name,name)) goto found; + for (i=0; res->s_aliases[i]; ++i) + if (!strcmp(res->s_aliases[i],name)) goto found; + } + *res_sig=0; +found: + endservent(); + return *res_sig?0:-1; +} diff --git a/mdk-stage1/dietlibc/libugly/getservbyport.c b/mdk-stage1/dietlibc/libugly/getservbyport.c new file mode 100644 index 000000000..2821deb63 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getservbyport.c @@ -0,0 +1,12 @@ +#include +#include + +extern struct servent __servent_pw; +extern char __servent_buf[1000]; + +struct servent *getservbyport(int port, const char *proto) { + struct servent* tmp; + if (getservbyport_r(port,proto,&__servent_pw,__servent_buf,sizeof(__servent_buf),&tmp)==0) + return tmp; + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/getservbyport_r.c b/mdk-stage1/dietlibc/libugly/getservbyport_r.c new file mode 100644 index 000000000..9c0f21bdf --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getservbyport_r.c @@ -0,0 +1,13 @@ +#include +#include + +extern int getservbyport_r(int port,const char* proto, + struct servent *res, char *buf, size_t buflen, + struct servent **res_sig) { + while (!getservent_r(res,buf,buflen,res_sig)) + if (port==res->s_port && !strcmp(res->s_proto,proto)) goto ok; + *res_sig=0; +ok: + endservent(); + return *res_sig?0:-1; +} diff --git a/mdk-stage1/dietlibc/libugly/getservent.c b/mdk-stage1/dietlibc/libugly/getservent.c new file mode 100644 index 000000000..9eabc972a --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getservent.c @@ -0,0 +1,10 @@ +#include + +extern struct servent __servent_pw; +extern char __servent_buf[1000]; + +struct servent *getservent(void) { + struct servent* tmp; + getservent_r(&__servent_pw,__servent_buf,sizeof(__servent_buf),&tmp); + return tmp; +} diff --git a/mdk-stage1/dietlibc/libugly/getservent_r.c b/mdk-stage1/dietlibc/libugly/getservent_r.c new file mode 100644 index 000000000..33db6f31d --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/getservent_r.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include "parselib.h" + +static struct state __ps; + +void setservent(int stayopen) { + (void)stayopen; + __prepare_parse(_PATH_SERVICES,&__ps); +} + +void endservent(void) { + __end_parse(&__ps); +} + +#define ALIASES 16 + +/* "tcpmux 1/tcp # TCP port multiplexer (RFC1078)" */ +int getservent_r(struct servent *res, char *buf, size_t buflen, + struct servent **res_sig) { + size_t i,j,n,g; + unsigned long l; + if (!__ps.buffirst) setservent(0); + if (!__ps.buffirst) goto error; + if (__ps.cur>=__ps.buflen) goto error; + res->s_aliases=(char**)buf; +/* getservent */ +again: + n=ALIASES*sizeof(char*); g=0; + for (i=0; i<3; ++i) { + char found; + __ps.cur+=__parse_ws(&__ps); + if (__ps.cur>=__ps.buflen) { if (i==2) break; else goto error; } + j=__parse_nws(&__ps); + if (!isblank(found=__ps.buffirst[__ps.cur+j])) { + if (i==2 && found=='#') break; + if (found=='#' || (i>1 && found!='\n')) { +parseerror: + while (__ps.cur+j<__ps.buflen) { + if (__ps.buffirst[__ps.cur+j]=='\n') { + __ps.cur+=j+1; + goto again; + } + ++j; + } + goto error; + } + } + switch (i) { + case 0: + res->s_name=buf+n; +copy: + if (!j) goto parseerror; + if ((size_t)buflen<=n+j) goto error; + memcpy(buf+n,__ps.buffirst+__ps.cur,j); + buf[n+j]=0; + n+=j+1; + if ((found=='\n' || found=='#') && i==1) i=3; + break; + case 1: + { + int k; + k=scan_ulong(__ps.buffirst+__ps.cur,&l); + if (__ps.buffirst[__ps.cur+k]!='/') { + goto parseerror; + } + res->s_port=htons(l); + res->s_proto=buf+n; + j-=k+1; __ps.cur+=k+1; + goto copy; + } + case 2: + res->s_aliases[g]=buf+n; + ++g; + if (g==(ALIASES-1)) break; + --i; /* again */ + goto copy; + } + __ps.cur+=j+1; + } + res->s_aliases[g]=0; + *res_sig=res; + return 0; +error: + *res_sig=0;/* the glibc people should be taken behind the barn and shot */ + return -1; +} diff --git a/mdk-stage1/dietlibc/libugly/grantpt.c b/mdk-stage1/dietlibc/libugly/grantpt.c new file mode 100644 index 000000000..0aa903b29 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/grantpt.c @@ -0,0 +1,13 @@ +#define _XOPEN_SOURCE +#include +#include +#include +#include + +int grantpt (int fd) { + struct stat st; + if ((fstat(fd, &st))<0) return -1; + if ((chmod((char*)ptsname(fd), st.st_mode | S_IRUSR | S_IWUSR | S_IWGRP))<0) + return -1; + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/hasmntopt.c b/mdk-stage1/dietlibc/libugly/hasmntopt.c new file mode 100644 index 000000000..2a547feee --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/hasmntopt.c @@ -0,0 +1,18 @@ +#include +#include + +char *hasmntopt(const struct mntent *mnt, const char *opt) { + char *s=mnt->mnt_opts; + char *c; + int len=strlen(opt); + if (!s) return 0; + for (c=s;;) { + if (!(c=strstr(c,opt))) break; + if (c==s || c[-1]==',') { + if (c[len]==0 || c[len]==',' || c[len]=='=') + return c; + } + c+=len+1; + } + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/iconv.c b/mdk-stage1/dietlibc/libugly/iconv.c new file mode 100644 index 000000000..45be5d91d --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/iconv.c @@ -0,0 +1,71 @@ +#include "dietfeatures.h" +#include +#include "dieticonv.h" +#include + +size_t iconv(iconv_t cd, const char* * inbuf, size_t * + inbytesleft, char* * outbuf, size_t * outbytesleft) { + size_t converted=0,i,j,k; + int bits; + if (!inbuf || !*inbuf) return 0; + while (*inbytesleft) { + unsigned int v=0; + v=*(unsigned char*)*inbuf; + i=j=1; + switch (ic_from(cd)) { + case UCS_2: + v=ntohs(*(unsigned short*)*inbuf); + i=2; + break; + case UCS_4: + v=ntohs(*(unsigned int*)*inbuf); + i=4; + case ISO_8859_1: + break; + case UTF_8: + if (!(v&0x80)) break; + for (i=0xC0; i!=0xFC; i=(i>>1)+0x80) + if ((v&((i>>1)|0x80))==i) { + v&=~i; + break; + } + for (i=1; ((*inbuf)[i]&0xc0)==0x80; ++i) + v=(v<<6)|((*inbuf)[i]&0x3f); +/* printf("got %u in %u bytes, buflen %u\n",v,i,*inbytesleft); */ + break; + } + switch (ic_to(cd)) { + case ISO_8859_1: + **outbuf=(unsigned char)v; + break; + case UCS_2: + *(unsigned short*)*outbuf=htons(v); + j=2; + break; + case UCS_4: + *(unsigned int*)*outbuf=htonl(v); + j=4; + break; + case UTF_8: + if (v>0x04000000) { bits=30; **outbuf=0xFC; j=6; } else + if (v>0x00200000) { bits=24; **outbuf=0xF8; j=5; } else + if (v>0x00010000) { bits=18; **outbuf=0xF0; j=4; } else + if (v>0x00000800) { bits=12; **outbuf=0xE0; j=3; } else + if (v>0x00000080) { bits=6; **outbuf=0xC0; j=2; } else + { bits=0; **outbuf=0; } + **outbuf |= (unsigned char)(v>>bits); + if (*outbytesleft>bits)&0x3F); + } + break; + } + *inbuf+=i; *inbytesleft-=i; ++converted; + *outbuf+=j; *outbytesleft-=j; + } + return converted; +} diff --git a/mdk-stage1/dietlibc/libugly/iconv_close.c b/mdk-stage1/dietlibc/libugly/iconv_close.c new file mode 100644 index 000000000..7d5d4c4b9 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/iconv_close.c @@ -0,0 +1,7 @@ +#include +#include "dieticonv.h" + +int iconv_close(iconv_t cd) { + (void)cd; /* shut gcc up about unused cd */ + return 0; +} diff --git a/mdk-stage1/dietlibc/libugly/iconv_open.c b/mdk-stage1/dietlibc/libugly/iconv_open.c new file mode 100644 index 000000000..eabab4273 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/iconv_open.c @@ -0,0 +1,28 @@ +#include +#include +#include "dietfeatures.h" +#include +#include +#include "dieticonv.h" + +static enum charset parsecharset(const char* s) { + if (!strcasecmp(s,"UTF-8")) return UTF_8; else + if (!strcasecmp(s,"UCS-2") || !strcasecmp(s,"UCS2")) return UCS_2; else + if (!strcasecmp(s,"UCS-4") || !strcasecmp(s,"UCS4")) return UCS_4; else + if (!strcasecmp(s,"ISO-8859-1")) return ISO_8859_1; else + if (!strcasecmp(s,"US-ASCII")) return ISO_8859_1; else + return INVALID; +} + +iconv_t iconv_open(const char* tocode, const char* fromcode) { + int f,t; + + f=parsecharset(fromcode); + t=parsecharset(tocode); + + if (f==INVALID || t==INVALID) { + errno=EINVAL; + return (iconv_t)(-1); + } + return (f|t<<16); +} diff --git a/mdk-stage1/dietlibc/libugly/netent.c b/mdk-stage1/dietlibc/libugly/netent.c new file mode 100644 index 000000000..4710d0fe6 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/netent.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "dietfeatures.h" +#include +#include + +static int netfd=-1; +static char* netmap; +static unsigned int netlen; + +static char* aliases[10]; + +static char *cur; + +/* loopback 127.0.0.0 lo # comment */ +struct netent *getnetent(void) { + static struct netent ne; + char *last; + int aliasidx; + if (netfd<0) { + netfd=open(_PATH_NETWORKS,O_RDONLY); + if (netfd<0) return 0; + fcntl (netfd, F_SETFD, FD_CLOEXEC); + netlen=lseek(netfd,0,SEEK_END); + netmap=mmap(0,netlen,PROT_READ|PROT_WRITE,MAP_PRIVATE,netfd,0); + if ((long)netmap==(-1)) goto error; + cur=netmap; + } + last=netmap+netlen; +again: + ne.n_name=0; + ne.n_aliases=aliases; aliases[0]=0; + ne.n_addrtype=AF_INET; + ne.n_net=0; + if (cur>=last) return 0; + if (*cur=='#' || *cur=='\n') goto parseerror; + /* first, the primary name */ + if (!isalpha(*cur)) goto parseerror; + ne.n_name=cur; + ne.n_aliases=aliases; + while (cur=last) return 0; + if (*cur=='\n') goto parseerror; + *cur=0; cur++; + /* second, the ip */ + while (cur=last) return 0; + /* now the aliases */ + for (aliasidx=0;aliasidx<10;++aliasidx) { + while (cur=last || !isblank(*cur)) break; + *cur++=0; + } + aliases[aliasidx]=0; + return ≠ +parseerror: + while (curn_net && type==s->n_addrtype) + return s; + } + return 0; +} + +void endnetent(void) { + if (netmap!=(char*)-1) munmap(netmap,netlen); + if (netfd!=-1) close(netfd); + netmap=(char*)-1; + netfd=-1; +} + +void setnetent(int stayopen) { + (void)stayopen; + endnetent(); +} + +struct netent *getnetbyname(const char *name) { + struct netent *s; + setnetent(0); + for (s=getnetent(); s; s=getnetent()) { + char **tmp; +#if 0 + write(1,"found ",6); + write(1,s->s_name,strlen(s->s_name)); + write(1,"/",1); + write(1,s->s_proto,strlen(s->s_proto)); + write(1,"\n",1); + if (!strcmp(s->s_name,"ssh")) { + write(2,"ssh!\n",5); + } +#endif + if (!strcmp(name,s->n_name)) + return s; + tmp=s->n_aliases; + while (*tmp) + if (!strcmp(name,*tmp++)) return s; + } + return 0; +} + diff --git a/mdk-stage1/dietlibc/libugly/openpty.c b/mdk-stage1/dietlibc/libugly/openpty.c new file mode 100644 index 000000000..8d06f329c --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/openpty.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include + +extern int __ltostr(char *s, int size, unsigned long i, int base, char UpCase); + +int openpty(int *amaster, int *aslave, char *name, struct termios + *termp, struct winsize *winp) { + int fd; + char buf[20]; +#if 0 + This is what glibc does: + open("/dev/ptmx", O_RDWR) = 4 + statfs("/dev/pts", {f_type=0x1cd1, f_bsize=1024, f_blocks=0, f_bfree=0, f_files=0, f_ffree=0, f_namelen=255}) = 0 + ioctl(4, TCGETS, {B38400 opost isig icanon echo ...}) = 0 + ioctl(4, 0x80045430, [0]) = 0 + stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 + statfs("/dev/pts/0", {f_type=0x1cd1, f_bsize=1024, f_blocks=0, f_bfree=0, f_files=0, f_ffree=0, f_namelen=255}) = 0 + ioctl(4, 0x40045431, [0]) = 0 + ioctl(4, TCGETS, {B38400 opost isig icanon echo ...}) = 0 + ioctl(4, 0x80045430, [0]) = 0 + stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 + open("/dev/pts/0", O_RDWR|O_NOCTTY) = 5 +#endif + if ((fd=open("/dev/ptmx",O_RDWR))<0) return -1; +#if 0 + if (ioctl(fd,TCGETS,&ts)<0) goto kaputt; +#endif + { + int unlock=0; + while (ioctl(fd,TIOCSPTLCK, &unlock)<0) if (errno!=EINTR) goto kaputt; + } + { + int ptyno; + while (ioctl(fd,TIOCGPTN,&ptyno)<0) if (errno!=EINTR) goto kaputt; + strcpy(buf,"/dev/pts/"); + __ltostr(buf+9,10,ptyno,10,0); + } + *aslave=open(buf,O_RDWR|O_NOCTTY); + if (*aslave<0) goto kaputt; + *amaster=fd; + if (name) strcpy(name,buf); + if (termp) + while (tcsetattr(*aslave,TCSAFLUSH,termp) && errno==EINTR); + if (winp) while (ioctl(*aslave, TIOCSWINSZ, winp) && errno==EINTR); + return 0; +kaputt: + close(fd); + return -1; +} diff --git a/mdk-stage1/dietlibc/libugly/protoent_buf.c b/mdk-stage1/dietlibc/libugly/protoent_buf.c new file mode 100644 index 000000000..0e303a5d4 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/protoent_buf.c @@ -0,0 +1,5 @@ +#include + +struct protoent __protoent_pw; +char __protoent_buf[1000]; + diff --git a/mdk-stage1/dietlibc/libugly/ptsname.c b/mdk-stage1/dietlibc/libugly/ptsname.c new file mode 100644 index 000000000..a332faf6c --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/ptsname.c @@ -0,0 +1,17 @@ +#define _XOPEN_SOURCE +#include +#include +#include +#include + +# define MAX_FDS 4 + +char *ptsname(int fd) { + static char buffer[9+MAX_FDS]; /* Ahh..great */ + int pty; + + strcpy(buffer,"/dev/pts/"); + if ((ioctl(fd, TIOCGPTN, &pty)) == -1) return 0; + __ltostr(buffer+9, MAX_FDS, pty, 10, 0); + return buffer; +} diff --git a/mdk-stage1/dietlibc/libugly/putpwent.c b/mdk-stage1/dietlibc/libugly/putpwent.c new file mode 100644 index 000000000..f192c5934 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/putpwent.c @@ -0,0 +1,19 @@ +/* man, what a crook! */ + +#include +#include +#include +#include +#include "dietwarning.h" + +int putpwent(const struct passwd *p, FILE *stream) { + if (p && stream) { + fprintf(stream,"%s:%s:%d:%d:%s:%s:%s\n", p->pw_name, p->pw_passwd, + p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell); + return 0; + } + (*__errno_location())=EINVAL; + return -1; +} + +link_warning("putpwent","putpwent is garbage, don't use!") diff --git a/mdk-stage1/dietlibc/libugly/servent_buf.c b/mdk-stage1/dietlibc/libugly/servent_buf.c new file mode 100644 index 000000000..b9e992adf --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/servent_buf.c @@ -0,0 +1,5 @@ +#include + +struct servent __servent_pw; +char __servent_buf[1000]; + diff --git a/mdk-stage1/dietlibc/libugly/strndup.c b/mdk-stage1/dietlibc/libugly/strndup.c new file mode 100644 index 000000000..7f912d4c6 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/strndup.c @@ -0,0 +1,10 @@ +#include +#include + +char *strndup(const char *s,size_t n) { + char *tmp=(char *)malloc(n+1); + if (!tmp) return 0; + strncpy(tmp,s,n); + tmp[n]=0; + return tmp; +} diff --git a/mdk-stage1/dietlibc/libugly/timezone.c b/mdk-stage1/dietlibc/libugly/timezone.c new file mode 100644 index 000000000..e8a94a906 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/timezone.c @@ -0,0 +1,3 @@ + +long int timezone; +int daylight; diff --git a/mdk-stage1/dietlibc/libugly/unlockpt.c b/mdk-stage1/dietlibc/libugly/unlockpt.c new file mode 100644 index 000000000..e0246ed8e --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/unlockpt.c @@ -0,0 +1,10 @@ +#define _XOPEN_SOURCE +#include +#include +#include + +int unlockpt (int fd) { + int foo; + /* hehe, that one is easy */ + return (ioctl (fd, TIOCSPTLCK, &foo)); +} diff --git a/mdk-stage1/dietlibc/libugly/utent.c b/mdk-stage1/dietlibc/libugly/utent.c new file mode 100644 index 000000000..d8d5d1ba7 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/utent.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +static const char *utmp_file_name = _PATH_UTMP; +static int fd = -1; + +static int lock_record(int type) { + struct flock fl; + fl.l_whence = SEEK_CUR; + fl.l_start = 0; + fl.l_len = sizeof(struct utmp); + fl.l_pid = 0; + fl.l_type = type; + return fcntl(fd, F_SETLKW, &fl); +} + +static int unlock_record() { + struct flock fl; + fl.l_whence = SEEK_CUR; + fl.l_start = -sizeof(struct utmp); + fl.l_len = sizeof(struct utmp); + fl.l_pid = 0; + fl.l_type = F_UNLCK; + return fcntl(fd, F_SETLK, &fl); +} + +void utmpname(const char *file) { + if (file) + utmp_file_name = file; + else + utmp_file_name = _PATH_UTMP; +} + +void setutent() { + if (fd<0) fd = open(utmp_file_name,O_RDWR); + if (fd<0) fd = open(utmp_file_name,O_RDONLY); + fcntl (fd, F_SETFD, FD_CLOEXEC); + lseek(fd,0,SEEK_SET); +} + +void endutent() { + if (fd<0) return; + close(fd); fd=-1; +} + +struct utmp *getutent(void) { + static struct utmp getutent_tmp; + int ret; + + if (fd<0) { + setutent(); + if (fd<0) return 0; + } + if (lock_record(F_RDLCK)) return 0; + ret=read(fd, &getutent_tmp, sizeof(struct utmp)); + unlock_record(); + if (ret<1) return 0; + return &getutent_tmp; +} + +struct utmp *getutid(struct utmp *ut) { + struct utmp *tmp; + + while ((tmp = getutent())) { + if (ut->ut_type && (ut->ut_type <= OLD_TIME)) { + if (ut->ut_type == tmp->ut_type) break; + } + if ((ut->ut_type >= INIT_PROCESS) && (ut->ut_type <= DEAD_PROCESS)) { + if (!strncmp(ut->ut_id,tmp->ut_id,4)) break; + } + } + return tmp; +} + +struct utmp *getutline(struct utmp *ut) { + struct utmp *tmp; + + while ((tmp = getutent())) { + if ((tmp->ut_type == USER_PROCESS) || (tmp->ut_type == LOGIN_PROCESS)) { + if (!strncmp(ut->ut_line,tmp->ut_line,UT_LINESIZE)) break; + } + } + return tmp; +} + +void pututline(struct utmp *ut) { + struct utmp *tmp; + + if ((tmp = getutid(ut))) { + lseek(fd, - (off_t)sizeof(struct utmp), SEEK_CUR); + if (lock_record(F_WRLCK)) return; + write(fd, ut, sizeof(struct utmp)); + } + else { + lseek(fd, 0, SEEK_END); + if (lock_record(F_WRLCK)) return; + write(fd, ut, (off_t)sizeof(struct utmp)); + } + unlock_record(); +} + diff --git a/mdk-stage1/dietlibc/libugly/wtent.c b/mdk-stage1/dietlibc/libugly/wtent.c new file mode 100644 index 000000000..1ca7c3202 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/wtent.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +void updwtmp(const char *wtmp_file, const struct utmp *ut) { + int fd = open(wtmp_file, O_WRONLY|O_APPEND); + if (fd<0) return; + fcntl (fd, F_SETFD, FD_CLOEXEC); + write(fd, ut, sizeof(struct utmp)); + close(fd); +} + +void logwtmp(const char *line, const char *name, const char *host) { + struct utmp ut; + + memset(&ut, 0, sizeof(struct utmp)); + + ut.ut_pid = getpid (); + ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS; + + memccpy (ut.ut_line, line, 0, sizeof ut.ut_line); + memccpy (ut.ut_name, name, 0, sizeof ut.ut_name); + memccpy (ut.ut_host, host, 0, sizeof ut.ut_host); + + gettimeofday (&ut.ut_tv, NULL); + + updwtmp (_PATH_WTMP, &ut); +} + -- cgit v1.2.1