* ./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);
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();
/* 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) {
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]=='/')) {
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, ','))) {
}
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;