From 0f4bd6a379ffb746231ba728c77428c779dba9da Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 18 Sep 2005 02:29:48 +0000 Subject: [PATCH] A bit too much at a time but could work some time... --- include/appclient.h | 3 + src/appclient.c | 180 ++++++++++++++++++++++++++++++++++++++++++++ src/appserver.c | 49 ++++++++++-- src/common.h | 17 +++++ 4 files changed, 241 insertions(+), 8 deletions(-) diff --git a/include/appclient.h b/include/appclient.h index 1bded77..c62dd80 100644 --- a/include/appclient.h +++ b/include/appclient.h @@ -18,4 +18,7 @@ AppClient * appclient_new(char * service); AppClient * appclient_new_event(char * service, Event * event); void appclient_delete(AppClient * appclient); +/* useful */ +int appclient_call(AppClient * appclient, char * function, ...); + #endif /* !_APPCLIENT_H */ diff --git a/src/appclient.c b/src/appclient.c index afe8faa..55e0cf2 100644 --- a/src/appclient.c +++ b/src/appclient.c @@ -1 +1,181 @@ /* appclient.c */ + + + +#include +#include +#include +#include +#include + +#include "string.h" +#include "common.h" +#include "appclient.h" + + +/* AppClient */ +/* private */ +/* types */ +struct _AppClient +{ + Event * event; + int fd; + char buf_read[ASC_BUFSIZE]; + int buf_read_cnt; + char buf_write[ASC_BUFSIZE]; + int buf_write_cnt; + ASCCall * ascc; + int ascc_cnt; +}; + + +/* private */ +static int _appclient_timeout(AppClient * appclient) +{ + static int cnt = 0; + + return cnt++ > 1000 || appclient->fd > -1; /* FIXME use a constant */ +} + + +static int _appclient_read(int fd, AppClient * ac) +{ + ssize_t len; + + if((len = sizeof(ac->buf_read) - ac->buf_read_cnt) < 0 + || (len = read(fd, &ac->buf_read[ac->buf_read_cnt], + len)) <= 0) + { + /* FIXME */ + return 1; + } + ac->buf_read_cnt+=len; + /* FIXME */ + return 0; +} + + +static int _appclient_write(int fd, AppClient * ac) +{ + ssize_t len; + + len = ac->buf_write_cnt; + if((len = write(fd, ac->buf_write, len)) <= 0) + { + /* FIXME */ + return 1; + } + memmove(ac->buf_write, &ac->buf_write[len], len); + ac->buf_write_cnt-=len; + return 0; +} + + +/* public */ +/* functions */ +AppClient * appclient_new(char * app) +{ + AppClient * appclient; + Event * event; + + if((event = event_new()) == NULL) + return NULL; + if((appclient = appclient_new_event(app, event)) == NULL) + { + event_delete(event); + return NULL; + } + return appclient; +} + + +static int _new_connect(AppClient * appclient, char * app); +AppClient * appclient_new_event(char * app, Event * event) +{ + AppClient * appclient; + + if((appclient = malloc(sizeof(AppClient))) == NULL) + return NULL; + appclient->event = event; + appclient->fd = -1; + appclient->buf_read_cnt = 0; + appclient->buf_write_cnt = 0; + appclient->ascc = NULL; + appclient->ascc_cnt = 0; + if(_new_connect(appclient, app) != 0) + { + free(appclient); + return NULL; + } + return appclient; +} + +static int _new_connect(AppClient * appclient, char * app) +{ + struct sockaddr_in sa; + struct timeval tv = { 0, 10 }; + int port; + + if((appclient->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return 1; + sa.sin_family = AF_INET; + sa.sin_port = htons(ASC_PORT_SESSION); + sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if(connect(appclient->fd, &sa, sizeof(sa)) != 0) + return 1; + event_register_timeout(appclient->event, tv, + (EventTimeoutFunc)_appclient_timeout, appclient); + event_register_io_write(appclient->event, appclient->fd, + (EventIOFunc)_appclient_write, appclient); + if((port = appclient_call(appclient, "service_info", app)) == -1) + return 1; + if(port == 0) + return 0; + close(appclient->fd); + if((appclient->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return 1; + sa.sin_port = htons(port); + if(connect(appclient->fd, &sa, sizeof(sa)) != 0) + return 1; + return 0; +} + + +/* appclient_delete */ +void appclient_delete(AppClient * appclient) +{ + free(appclient); +} + + +/* useful */ +int appclient_call(AppClient * appclient, char * function, ...) +{ + ASCCall * ascc = NULL; + va_list arg; + int ret; + int i; + void ** args = NULL; + void ** p; + + for(i = 0; i < appclient->ascc_cnt; i++) + { + if(string_compare(appclient->ascc[i].name, function) != 0) + continue; + ascc = &appclient->ascc[i]; + break; + } + if(ascc == NULL) + return 1; + va_start(arg, function); + for(i = 0; i < ascc->args_cnt; i++) + { + if((p = realloc(args, i * sizeof(void*))) == NULL) + break; + args = p; + args[i] = va_arg(arg, void *); + } + va_end(arg); + ret = asc_send_call(ascc, &appclient->buf_write[appclient->buf_write_cnt], sizeof(appclient->buf_write) - appclient->buf_write_cnt, args); + return ret; +} diff --git a/src/appserver.c b/src/appserver.c index ec8bc4a..4c62620 100644 --- a/src/appserver.c +++ b/src/appserver.c @@ -6,7 +6,9 @@ #include #include #include -#include +#ifdef DEBUG +# include +#endif #include "array.h" #include "string.h" @@ -53,8 +55,13 @@ AppServerClient * appserverclient_new(int fd, uint32_t addr, uint16_t port) void appserverclient_delete(AppServerClient * appserverclient) { + /* FIXME find a way to properly report error */ +#ifdef DEBUG if(close(appserverclient->fd) != 0) - perror("close"); /* FIXME find a way to properly report error */ + perror("close"); +# else + close(appserverclient->fd); +#endif free(appserverclient); } @@ -85,7 +92,6 @@ static int _appserver_accept(int fd, AppServer * appserver) fprintf(stderr, "%s%d%s%p%s", "_appserver_accept(", fd, ", ", appserver, ")\n"); #endif - /* FIXME append client to the clients list with the appropriate state */ if((newfd = accept(fd, (struct sockaddr *)&sa, &sa_size)) == -1) return 1; if((asc = appserverclient_new(newfd, sa.sin_addr.s_addr, sa.sin_port)) @@ -102,6 +108,7 @@ static int _appserver_accept(int fd, AppServer * appserver) } +static int _read_process(AppServer * appserver, AppServerClient * asc); static int _appserver_read(int fd, AppServer * appserver) { AppServerClient * asc = NULL; @@ -122,6 +129,8 @@ static int _appserver_read(int fd, AppServer * appserver) || (len = read(fd, &asc->buf_read[asc->buf_read_cnt], len)) <= 0) { + /* FIXME do all this in appserverclient_delete() or something + * like appserver_remove_client() */ if(asc->buf_write_cnt > 0) event_unregister_io_write(appserver->event, fd); event_unregister_io_read(appserver->event, fd); @@ -134,6 +143,19 @@ static int _appserver_read(int fd, AppServer * appserver) fprintf(stderr, "%s%d%s%d%s", "_appserver_read(", fd, ", appserver): ", len, " characters read\n"); #endif + return _read_process(appserver, asc); +} + +static int _read_process(AppServer * appserver, AppServerClient * asc) +{ + switch(asc->state) + { + case ASCS_NEW: + /* FIXME authenticate */ + case ASCS_LOGGED: + /* FIXME check errors */ + break; + } return 0; } @@ -177,8 +199,6 @@ static int _appserver_write(int fd, AppServer * appserver) /* public */ /* functions */ /* appserver_new */ -static int _new_interface(AppServer * appserver, const char * app); -static int _new_server(AppServer * appserver, int options); AppServer * appserver_new(const char * app, int options) { AppServer * appserver; @@ -196,6 +216,8 @@ AppServer * appserver_new(const char * app, int options) /* appserver_new_event */ +static int _new_interface(AppServer * appserver, const char * app); +static int _new_server(AppServer * appserver, int options); AppServer * appserver_new_event(const char * app, int options, Event * event) { AppServer * appserver; @@ -218,16 +240,23 @@ static int _new_interface(AppServer * appserver, const char * app) { if(string_compare(app, "Session") == 0) { - appserver->port = 4242; /* FIXME */ + appserver->port = ASC_PORT_SESSION; /* FIXME */ return 0; } + else if(string_compare(app, "Hello") == 0) + { + appserver->port = 4343; + return 0; /* FIXME */ + } else if(string_compare(app, "Network") == 0) { /* FIXME */ + return 0; } else if(string_compare(app, "Probe") == 0) { /* FIXME */ + return 0; } return 1; } @@ -238,7 +267,7 @@ static int _new_server(AppServer * appserver, int options) struct sockaddr_in sa; if((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) - return 1; /* FIXME report error */ + return 1; sa.sin_family = AF_INET; sa.sin_port = htons(appserver->port); sa.sin_addr.s_addr = htonl(options & ASO_LOCAL ? INADDR_LOOPBACK @@ -247,8 +276,12 @@ static int _new_server(AppServer * appserver, int options) || listen(fd, 5) != 0) { /* FIXME report error */ +#ifdef DEBUG if(close(fd) != 0) - perror("close"); /* FIXME report error appropriately */ + perror("close"); +# else + close(fd); +#endif return 1; } event_register_io_read(appserver->event, fd, diff --git a/src/common.h b/src/common.h index 212f2c9..2b9a260 100644 --- a/src/common.h +++ b/src/common.h @@ -8,5 +8,22 @@ /* AppServer/AppClient */ # define ASC_BUFSIZE 65536 +# define ASC_PORT_SESSION 4242 + +typedef enum _ASCCallType { + ASC_INT8, ASC_INT16, ASC_INT32, ASC_INT64, + ASC_UINT8, ASC_UINT16, ASC_UINT32, ASC_UINT64, + ASC_BUFFER +} ASCCallType; + +typedef struct _ASCCall +{ + ASCCallType type; + char * name; + ASCCallType * args; + int args_cnt; +} ASCCall; + +int asc_send_call(ASCCall * call, char * buf, int buflen, void ** args); #endif /* !COMMON_H */