From a8f1f17fb85925c017c2bbfaf1c4f8efb152341f Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" Date: Sat, 21 Jan 2006 21:04:29 +0200 Subject: [PATCH] added AF_INET capable socket functions --- libixp2/ixp.h | 8 ++-- libixp2/server.c | 8 ++-- libixp2/socket.c | 113 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 103 insertions(+), 26 deletions(-) diff --git a/libixp2/ixp.h b/libixp2/ixp.h index 40aa499b..a5578dbe 100644 --- a/libixp2/ixp.h +++ b/libixp2/ixp.h @@ -223,7 +223,7 @@ typedef struct { } IXPClient; /* client.c */ -int ixp_client_init(IXPClient * c, char *sockfile); +int ixp_client_init(IXPClient * c, char *address); void ixp_client_deinit(IXPClient * c); int ixp_client_remove(IXPClient * c, unsigned int newfid, char *filepath); int ixp_client_create(IXPClient * c, unsigned int dirfid, char *name, @@ -277,14 +277,14 @@ IXPConn *ixp_server_add_conn(IXPServer * s, int fd, int dont_close, int ixp_server_tversion(IXPServer *, IXPConn * c); void ixp_server_rm_conn(IXPServer * s, IXPConn * c); void ixp_server_loop(IXPServer * s); -int ixp_server_init(IXPServer * s, char *sockfile, IXPTFunc * funcs, +int ixp_server_init(IXPServer * s, char *address, IXPTFunc * funcs, void (*freeconn) (IXPServer *, IXPConn *)); void ixp_server_deinit(IXPServer * s); /* socket.c */ -int ixp_connect_sock(char *sockfile); +int ixp_connect_sock(char *address); int ixp_accept_sock(int fd); -int ixp_create_sock(char *sockfile, char **errstr); +int ixp_create_sock(char *address, char **errstr); /* transport.c */ unsigned int ixp_send_message(int fd, void *msg, unsigned int msize, diff --git a/libixp2/server.c b/libixp2/server.c index 1efdb652..8acbef40 100644 --- a/libixp2/server.c +++ b/libixp2/server.c @@ -188,18 +188,18 @@ ixp_server_tversion(IXPServer * s, IXPConn * c) } int -ixp_server_init(IXPServer * s, char *sockfile, IXPTFunc * funcs, +ixp_server_init(IXPServer * s, char *address, IXPTFunc * funcs, void (*freeconn) (IXPServer *, IXPConn *)) { int fd, i; s->funcs = funcs; s->freeconn = freeconn; s->errstr = 0; - if(!sockfile) { - s->errstr = "no socket file provided or invalid directory"; + if(!address) { + s->errstr = "no socket address provided or invalid directory"; return -1; } - if((fd = ixp_create_sock(sockfile, &s->errstr)) < 0) + if((fd = ixp_create_sock(address, &s->errstr)) < 0) return -1; for(i = 0; i < IXP_MAX_CONN; i++) s->conn[i] = zero_conn; diff --git a/libixp2/socket.c b/libixp2/socket.c index 0a54ded9..ccb0a3a9 100644 --- a/libixp2/socket.c +++ b/libixp2/socket.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include @@ -17,7 +19,7 @@ #include "ixp.h" static int -connect_unix_sock(char *sockfile) +connect_unix_sock(char *address) { int fd = 0; struct sockaddr_un addr = { 0 }; @@ -25,7 +27,7 @@ connect_unix_sock(char *sockfile) /* init */ addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, sockfile, sizeof(addr.sun_path)); + strncpy(addr.sun_path, address, sizeof(addr.sun_path)); su_len = sizeof(struct sockaddr) + strlen(addr.sun_path); if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) @@ -37,20 +39,52 @@ connect_unix_sock(char *sockfile) return fd; } -int -ixp_connect_sock(char *sockfile) +static int +connect_tcp_sock(char *host) { - char *p = strchr(sockfile, '!'); - char *file, *type; + int fd = 0; + struct sockaddr_in addr = { 0 }; + struct hostent *hp; + char *port = strrchr(host, '!'); + const char *errstr = nil; + + *port = 0; + port++; + addr.sin_port = cext_strtonum(port, 1024, 65535, &errstr); + if(errstr) + return -1; + + /* init */ + if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return -1; + hp = gethostbyname(host); + addr.sin_family = AF_INET; + bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); + + if(connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))) { + close(fd); + return -1; + } + return fd; +} + +int +ixp_connect_sock(char *address) +{ + char *p = strchr(address, '!'); + char *addr, *type; if(!p) return -1; *p = 0; - file = &p[1]; - type = sockfile; /* unix, tcp */ + + addr = &p[1]; + type = address; /* unix, tcp */ if(strncmp(type, "unix", 5)) - return connect_unix_sock(file); + return connect_unix_sock(addr); + else if(!strncmp(type, "tcp", 4)) + return connect_tcp_sock(addr); return -1; } @@ -65,7 +99,45 @@ ixp_accept_sock(int fd) } static int -create_unix_sock(char *sockfile, char **errstr) +create_tcp_sock(char *host, char **errstr) +{ + int fd; + struct sockaddr_in addr = { 0 }; + char *port = strrchr(host, '!'); + + if(!port) { + *errstr = "no port provided in address"; + return -1; + } + *port = 0; + port++; + addr.sin_port = cext_strtonum(port, 1024, 65535, (const char **)errstr); + if(*errstr) + return -1; + signal(SIGPIPE, SIG_IGN); + if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + *errstr = "cannot open socket"; + return -1; + } + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + + if(bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) { + *errstr = "cannot bind socket"; + close(fd); + return -1; + } + + if(listen(fd, IXP_MAX_CONN) < 0) { + *errstr = "cannot listen on socket"; + close(fd); + return -1; + } + return fd; +} + +static int +create_unix_sock(char *file, char **errstr) { int fd; int yes = 1; @@ -84,7 +156,7 @@ create_unix_sock(char *sockfile, char **errstr) return -1; } addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, sockfile, sizeof(addr.sun_path)); + strncpy(addr.sun_path, file, sizeof(addr.sun_path)); su_len = sizeof(struct sockaddr) + strlen(addr.sun_path); if(bind(fd, (struct sockaddr *) &addr, su_len) < 0) { @@ -92,7 +164,7 @@ create_unix_sock(char *sockfile, char **errstr) close(fd); return -1; } - chmod(sockfile, S_IRWXU); + chmod(file, S_IRWXU); if(listen(fd, IXP_MAX_CONN) < 0) { *errstr = "cannot listen on socket"; @@ -103,20 +175,25 @@ create_unix_sock(char *sockfile, char **errstr) } int -ixp_create_sock(char *sockfile, char **errstr) +ixp_create_sock(char *address, char **errstr) { - char *p = strchr(sockfile, '!'); - char *file, *type; + char *p = strchr(address, '!'); + char *addr, *type; if(!p) { *errstr = "no socket type defined"; return -1; } *p = 0; - file = &p[1]; - type = sockfile; /* unix, tcp */ + + addr = &p[1]; + type = address; /* unix, tcp */ if(!strncmp(type, "unix", 5)) - return create_unix_sock(file, errstr); + return create_unix_sock(addr, errstr); + else if(!strncmp(type, "tcp", 4)) + return create_tcp_sock(addr, errstr); + else + *errstr = "unkown socket type"; return -1; }