A bit too much at a time but could work some time...
This commit is contained in:
parent
13b1356904
commit
0f4bd6a379
|
@ -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 */
|
||||
|
|
180
src/appclient.c
180
src/appclient.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
17
src/common.h
17
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 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user