X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=dgram%2Fsockaddr.c;h=7373629bb4341297560ed7400c43318b2d067ebe;hp=bedc10977bb25e82090846a8b2a6b255336c9c0c;hb=cf8e1e165e29df4b0e161751e9e952b75236c932;hpb=d23a32272b954579fe15c78d6ea605e087d0a512 diff --git a/dgram/sockaddr.c b/dgram/sockaddr.c index bedc109..7373629 100644 --- a/dgram/sockaddr.c +++ b/dgram/sockaddr.c @@ -8,14 +8,13 @@ * ./rel/path/to/socket AF_UNIX */ -#include "hbytes.h" -#include "tables.h" +#include "dgram.h" #define SOCKADDR_LEN(sa) ((sa)->end - (sa)->begin) /* parsing */ -int pat_sockaddr(Tcl_Interp *ip, Tcl_Obj *o, SockAddr_Value *val) { +int cht_pat_sockaddr(Tcl_Interp *ip, Tcl_Obj *o, SockAddr_Value *val) { int rc; rc= Tcl_ConvertToType(ip,o,&sockaddr_type); @@ -25,7 +24,7 @@ int pat_sockaddr(Tcl_Interp *ip, Tcl_Obj *o, SockAddr_Value *val) { return TCL_OK; } -Tcl_Obj *ret_sockaddr(Tcl_Interp *ip, SockAddr_Value val) { +Tcl_Obj *cht_ret_sockaddr(Tcl_Interp *ip, SockAddr_Value val) { Tcl_Obj *o; o= Tcl_NewObj(); @@ -37,77 +36,79 @@ Tcl_Obj *ret_sockaddr(Tcl_Interp *ip, SockAddr_Value val) { /* native type methods */ -void sockaddr_clear(SockAddr_Value *v) { v->begin= v->end= 0; } +void cht_sockaddr_clear(SockAddr_Value *v) { v->begin= v->end= 0; } -void sockaddr_create(SockAddr_Value *v, const struct sockaddr *addr, int len) { +void cht_sockaddr_create(SockAddr_Value *v, const struct sockaddr *a, int al) { Byte *begin; - v->begin= begin= TALLOC(len); - memcpy(begin, addr, len); - v->end= begin + len; + v->begin= begin= TALLOC(al); + memcpy(begin, a, al); + v->end= begin + al; } -int sockaddr_len(const SockAddr_Value *v) { +int cht_sockaddr_len(const SockAddr_Value *v) { return SOCKADDR_LEN(v); } -const struct sockaddr *sockaddr_addr(const SockAddr_Value *v) { +const struct sockaddr *cht_sockaddr_addr(const SockAddr_Value *v) { return (const void*)v->begin; } -void sockaddr_free(const SockAddr_Value *v) { +void cht_sockaddr_free(const SockAddr_Value *v) { TFREE(v->begin); } /* Sockaddr Tcl type */ static void sockaddr_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { - objfreeir(dup); - sockaddr_create(OBJ_SOCKADDR(dup), - sockaddr_addr(OBJ_SOCKADDR(src)), - sockaddr_len(OBJ_SOCKADDR(src))); + cht_sockaddr_create(OBJ_SOCKADDR(dup), + cht_sockaddr_addr(OBJ_SOCKADDR(src)), + cht_sockaddr_len(OBJ_SOCKADDR(src))); + dup->typePtr= &cht_hbytes_type; } static void sockaddr_t_free(Tcl_Obj *o) { - sockaddr_free(OBJ_SOCKADDR(o)); + cht_sockaddr_free(OBJ_SOCKADDR(o)); } static void sockaddr_t_ustr(Tcl_Obj *o) { const struct sockaddr *sa; - char i46buf[INET6_ADDRSTRLEN]; - int al, sl, pl; + char i46buf[INET6_ADDRSTRLEN], portbuf[50]; + const struct sockaddr_in *sin; + int al; const char *string, *prepend; - sa= sockaddr_addr(OBJ_SOCKADDR(o)); - al= sockaddr_len(OBJ_SOCKADDR(o)); + sa= cht_sockaddr_addr(OBJ_SOCKADDR(o)); + al= cht_sockaddr_len(OBJ_SOCKADDR(o)); switch (sa->sa_family) { case AF_INET: case AF_INET6: assert(sizeof(i46buf) >= INET_ADDRSTRLEN); assert(al >= sizeof(struct sockaddr_in)); - inet_ntop(sa->sa_family, sa, i46buf, al); - string= i46buf; - prepend= ""; + sin= (const void*)sa; + inet_ntop(sa->sa_family, &sin->sin_addr, i46buf, al); + snprintf(portbuf,sizeof(portbuf),",%d",(int)ntohs(sin->sin_port)); + prepend= i46buf; + string= portbuf; break; case AF_UNIX: - assert(al >= sizeof(struct sockaddr_un)); string= ((const struct sockaddr_un*)sa)->sun_path; prepend= ""; if (!string[0]) string="//"; - else if (string[0] != '/' || string[1] == '/') prepend= "./"; + else if (string[0] != '/' || string[1] == '/') prepend= "./"; + break; default: /* ouch ! */ - obj_updatestr_array_prefix(o,(const void*)sa,al,"?"); + cht_obj_updatestr_array_prefix(o,(const void*)sa,al,"?"); return; } - pl= strlen(prepend); - sl= strlen(string); - o->bytes= TALLOC(sl+1); - memcpy(o->bytes, prepend, pl); - memcpy(o->bytes+pl, string, sl+1); + cht_obj_updatestr_vstringls(o, + prepend, strlen(prepend), + string, strlen(string), + (char*)0); } static int sockaddr_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { @@ -122,7 +123,7 @@ static int sockaddr_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { const char *comma, *path; str= Tcl_GetStringFromObj(o,0); assert(str); - objfreeir(o); + cht_objfreeir(o); memset(&s,0,sizeof(s)); if (str[0]=='/' || (str[0]=='.' && str[1]=='/')) { @@ -130,14 +131,14 @@ static int sockaddr_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { sl= sizeof(s.sun); s.sun.sun_family= AF_UNIX; - if (strcmp(str,"//")) path= ""; - else if (memcmp(str,"./",2) && str[2]) path= str+2; + if (!strcmp(str,"//")) path= ""; + else if (!memcmp(str,"./",2) && str[2]) path= str+2; else { assert(str[0]=='/' && str[1]!='/'); path=str; } if (strlen(str) >= sizeof(s.sun.sun_path)) - return staticerr(ip, "AF_UNIX path too long"); + return cht_staticerr(ip, "AF_UNIX path too long", "SOCKADDR AFUNIX LENGTH"); - strcpy(s.sun.sun_path, str); + strcpy(s.sun.sun_path, path); } else if ((comma= strchr(str, ','))) { @@ -157,25 +158,28 @@ static int sockaddr_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { } TFREE(copy); - if (!iprv) return staticerr(ip, "bad IPv4 address syntax"); + if (!iprv) + return cht_staticerr(ip, "bad IPv4 address syntax", "SOCKADDR SYNTAX IPV4"); comma++; if (!strcmp(comma,"*")) { s.sin.sin_port= 0; } else { errno=0; port_l=strtoul(comma,&ep,10); - if (errno || *ep) return staticerr(ip, "bad IPv4 port"); - if (port_l > 65535) return staticerr(ip, "IPv4 port out of range"); + if (errno || *ep) + return cht_staticerr(ip, "bad IPv4 port", "SOCKADDR SYNTAX IPV4"); + if (port_l > 65535) + return cht_staticerr(ip, "IPv4 port out of range", "SOCKADDR SYNTAX IPV4"); s.sin.sin_port= htons(port_l); } } else { - return staticerr(ip, "bad socket address syntax"); + return cht_staticerr(ip, "bad socket address syntax", "SOCKADDR SYNTAX OTHER"); } - sockaddr_create(OBJ_SOCKADDR(o), (void*)&s, sl); + cht_sockaddr_create(OBJ_SOCKADDR(o), (void*)&s, sl); o->typePtr = &sockaddr_type; return TCL_OK;