A bit too much at a time but could work some time...

This commit is contained in:
Pierre Pronchery 2005-09-18 02:29:48 +00:00
parent 13b1356904
commit 0f4bd6a379
4 changed files with 241 additions and 8 deletions

View File

@ -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 */

View File

@ -1 +1,181 @@
/* appclient.c */
#include <sys/socket.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#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;
}

View File

@ -6,7 +6,9 @@
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef DEBUG
# include <stdio.h>
#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,

View File

@ -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 */