I am getting AWFULLY close to being able to run this code
This commit is contained in:
parent
116f4f9f6b
commit
c4fa41dab4
8 changed files with 439 additions and 77 deletions
|
@ -2,7 +2,7 @@
|
|||
#define _PATTY_AX25_CALL_H
|
||||
|
||||
enum patty_ax25_call {
|
||||
PATTY_AX25_CALL_UNKNOWN,
|
||||
PATTY_AX25_CALL_NONE,
|
||||
PATTY_AX25_CALL_SOCKET,
|
||||
PATTY_AX25_CALL_BIND,
|
||||
PATTY_AX25_CALL_LISTEN,
|
||||
|
@ -10,7 +10,8 @@ enum patty_ax25_call {
|
|||
PATTY_AX25_CALL_CONNECT,
|
||||
PATTY_AX25_CALL_CLOSE,
|
||||
PATTY_AX25_CALL_SENDTO,
|
||||
PATTY_AX25_CALL_RECVFROM
|
||||
PATTY_AX25_CALL_RECVFROM,
|
||||
PATTY_AX25_CALL_COUNT
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#define PATTY_AX25_IF_OPT_TYPE(n) \
|
||||
((n) & PATTY_AX25_IF_OPT_TYPE_MASK)
|
||||
|
||||
#define PATTY_AX25_IF_BUFSZ 4096
|
||||
|
||||
enum patty_ax25_if_type {
|
||||
PATTY_AX25_IF_UNKNOWN,
|
||||
PATTY_AX25_IF_KISS_TNC,
|
||||
|
@ -31,6 +33,9 @@ typedef struct _patty_ax25_if {
|
|||
|
||||
char name[8];
|
||||
|
||||
void *rx_buf;
|
||||
size_t rx_bufsz;
|
||||
|
||||
patty_kiss_tnc *tnc;
|
||||
patty_list *addrs;
|
||||
} patty_ax25_if;
|
||||
|
@ -48,4 +53,11 @@ int patty_ax25_if_add_addr(patty_ax25_if *iface,
|
|||
int patty_ax25_if_delete_addr(patty_ax25_if *iface,
|
||||
const char *callsign, uint8_t ssid);
|
||||
|
||||
ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
|
||||
void **buf);
|
||||
|
||||
ssize_t patty_ax25_if_send(patty_ax25_if *iface,
|
||||
const void *buf,
|
||||
size_t len);
|
||||
|
||||
#endif /* _PATTY_AX25_IF_H */
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#ifndef _PATTY_AX25_SERVER_H
|
||||
#define _PATTY_AX25_SERVER_H
|
||||
|
||||
#define PATTY_AX25_SERVER_PATH "/var/run/patty/patty.sock"
|
||||
#define PATTY_AX25_SERVER_CLIENT_PATH_FORMAT "/var/run/patty/%d.sock"
|
||||
|
||||
typedef struct _patty_ax25_server patty_ax25_server;
|
||||
|
||||
int patty_ax25_server_init(patty_ax25_server *server);
|
||||
|
||||
void patty_ax25_server_stop(patty_ax25_server *server);
|
||||
|
||||
int patty_ax25_server_run(patty_ax25_server *server);
|
||||
void patty_ax25_server_destroy(patty_ax25_server *server);
|
||||
|
||||
int patty_ax25_server_add_if(patty_ax25_server *server,
|
||||
patty_ax25_if *iface);
|
||||
|
@ -22,4 +23,6 @@ int patty_ax25_server_each_if(patty_ax25_server *server,
|
|||
int (*callback)(patty_ax25_if *, void *),
|
||||
void *ctx);
|
||||
|
||||
int patty_ax25_server_run(patty_ax25_server *server);
|
||||
|
||||
#endif /* _PATTY_AX25_SERVER_H */
|
||||
|
|
|
@ -29,13 +29,14 @@ patty_dict *patty_dict_new();
|
|||
|
||||
patty_dict_slot *patty_dict_slot_find(patty_dict *dict, uint32_t hash);
|
||||
|
||||
typedef int (*patty_dict_callback)(
|
||||
void * key,
|
||||
size_t keysz,
|
||||
void * value,
|
||||
void * ctx);
|
||||
typedef int (*patty_dict_callback)(void *key,
|
||||
size_t keysz,
|
||||
void *value,
|
||||
void *ctx);
|
||||
|
||||
int patty_dict_each(patty_dict *dict, patty_dict_callback callback, void *ctx);
|
||||
int patty_dict_each(patty_dict *dict,
|
||||
patty_dict_callback callback,
|
||||
void *ctx);
|
||||
|
||||
void *patty_dict_get(patty_dict *dict, void *key, size_t keysz);
|
||||
|
||||
|
|
|
@ -59,9 +59,8 @@ void patty_list_reset(patty_list_iterator *iterator);
|
|||
|
||||
void patty_list_finish(patty_list_iterator *iterator);
|
||||
|
||||
void patty_list_each(
|
||||
patty_list * list,
|
||||
patty_list_callback callback,
|
||||
void * ctx);
|
||||
void patty_list_each(patty_list *list,
|
||||
patty_list_callback callback,
|
||||
void *ctx);
|
||||
|
||||
#endif /* _PATTY_LIST_H */
|
||||
|
|
12
src/call.c
12
src/call.c
|
@ -6,7 +6,7 @@
|
|||
|
||||
int patty_ax25_call_socket(int server,
|
||||
int type) {
|
||||
int call = PATTY_AX25_CALL_SOCKET;
|
||||
enum patty_ax25_call call = PATTY_AX25_CALL_SOCKET;
|
||||
|
||||
patty_ax25_call_socket_request request = {
|
||||
type
|
||||
|
@ -37,7 +37,7 @@ error_io:
|
|||
int patty_ax25_call_bind(int server,
|
||||
int socket,
|
||||
patty_ax25_addr *peer) {
|
||||
int call = PATTY_AX25_CALL_BIND;
|
||||
enum patty_ax25_call call = PATTY_AX25_CALL_BIND;
|
||||
|
||||
patty_ax25_call_bind_request request = {
|
||||
socket
|
||||
|
@ -69,7 +69,7 @@ error_io:
|
|||
|
||||
int patty_ax25_call_listen(int server,
|
||||
int socket) {
|
||||
int call = PATTY_AX25_CALL_LISTEN;
|
||||
enum patty_ax25_call call = PATTY_AX25_CALL_LISTEN;
|
||||
|
||||
patty_ax25_call_listen_request request = {
|
||||
socket
|
||||
|
@ -101,7 +101,7 @@ int patty_ax25_call_accept(int server,
|
|||
int socket,
|
||||
patty_ax25_addr *peer,
|
||||
char *path) {
|
||||
int call = PATTY_AX25_CALL_ACCEPT;
|
||||
enum patty_ax25_call call = PATTY_AX25_CALL_ACCEPT;
|
||||
|
||||
patty_ax25_call_accept_request request = {
|
||||
socket
|
||||
|
@ -138,7 +138,7 @@ int patty_ax25_call_connect(int server,
|
|||
int socket,
|
||||
patty_ax25_addr *peer,
|
||||
char *path) {
|
||||
int call = PATTY_AX25_CALL_CONNECT;
|
||||
enum patty_ax25_call call = PATTY_AX25_CALL_CONNECT;
|
||||
|
||||
patty_ax25_call_connect_request request = {
|
||||
socket
|
||||
|
@ -174,7 +174,7 @@ error_io:
|
|||
|
||||
int patty_ax25_call_close(int server,
|
||||
int socket) {
|
||||
int call = PATTY_AX25_CALL_CLOSE;
|
||||
enum patty_ax25_call call = PATTY_AX25_CALL_CLOSE;
|
||||
|
||||
patty_ax25_call_close_request request = {
|
||||
socket
|
||||
|
|
121
src/if.c
121
src/if.c
|
@ -5,17 +5,9 @@
|
|||
|
||||
#include <patty/ax25.h>
|
||||
|
||||
static patty_ax25_if *create_tnc(const char *device) {
|
||||
patty_ax25_if *iface;
|
||||
|
||||
static char * prefix = "kiss";
|
||||
static int number = 0;
|
||||
|
||||
if ((iface = malloc(sizeof(*iface))) == NULL) {
|
||||
goto error_malloc_iface;
|
||||
}
|
||||
|
||||
memset(iface, '\0', sizeof(*iface));
|
||||
static int init_tnc(patty_ax25_if *iface, const char *device) {
|
||||
static char *prefix = "kiss";
|
||||
static int number = 0;
|
||||
|
||||
if ((iface->tnc = patty_kiss_tnc_open(device)) == NULL) {
|
||||
goto error_kiss_tnc_open;
|
||||
|
@ -25,58 +17,79 @@ static patty_ax25_if *create_tnc(const char *device) {
|
|||
|
||||
snprintf(iface->name, sizeof(iface->name), "%s%d", prefix, number++);
|
||||
|
||||
return iface;
|
||||
return 0;
|
||||
|
||||
error_kiss_tnc_open:
|
||||
free(iface);
|
||||
|
||||
error_malloc_iface:
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void destroy_tnc(patty_ax25_if *iface) {
|
||||
static void close_tnc(patty_ax25_if *iface) {
|
||||
patty_kiss_tnc_close(iface->tnc);
|
||||
}
|
||||
|
||||
patty_ax25_if *patty_ax25_if_create(int opts, void *info) {
|
||||
patty_ax25_if *iface;
|
||||
|
||||
switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
|
||||
case PATTY_AX25_IF_KISS_TNC: {
|
||||
iface = create_tnc((const char *)info);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
errno = EINVAL;
|
||||
|
||||
goto error;
|
||||
}
|
||||
if ((iface = malloc(sizeof(*iface))) == NULL) {
|
||||
goto error_malloc_iface;
|
||||
}
|
||||
|
||||
if (iface == NULL) {
|
||||
goto error;
|
||||
memset(iface, '\0', sizeof(*iface));
|
||||
|
||||
if ((iface->rx_buf = malloc(PATTY_AX25_IF_BUFSZ)) == NULL) {
|
||||
goto error_malloc_rx_buf;
|
||||
} else {
|
||||
iface->rx_bufsz = PATTY_AX25_IF_BUFSZ;
|
||||
}
|
||||
|
||||
if ((iface->addrs = patty_list_new()) == NULL) {
|
||||
goto error;
|
||||
goto error_list_new;
|
||||
}
|
||||
|
||||
switch (PATTY_AX25_IF_OPT_TYPE(opts)) {
|
||||
case PATTY_AX25_IF_KISS_TNC:
|
||||
if (init_tnc(iface, (const char *)info) < 0) {
|
||||
goto error_init;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
|
||||
goto error_invalid_if_type;
|
||||
}
|
||||
|
||||
return iface;
|
||||
|
||||
error:
|
||||
error_invalid_if_type:
|
||||
error_init:
|
||||
patty_list_destroy(iface->addrs);
|
||||
|
||||
error_list_new:
|
||||
free(iface->rx_buf);
|
||||
|
||||
error_malloc_rx_buf:
|
||||
free(iface);
|
||||
|
||||
error_malloc_iface:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void patty_ax25_if_destroy(patty_ax25_if *iface) {
|
||||
switch (iface->type) {
|
||||
case PATTY_AX25_IF_KISS_TNC: {
|
||||
destroy_tnc(iface); break;
|
||||
}
|
||||
case PATTY_AX25_IF_KISS_TNC:
|
||||
close_tnc(iface);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
patty_list_destroy(iface->addrs);
|
||||
|
||||
free(iface->rx_buf);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
int patty_ax25_if_each_addr(patty_ax25_if *iface,
|
||||
|
@ -221,3 +234,37 @@ error_ntop:
|
|||
return -1;
|
||||
}
|
||||
|
||||
ssize_t patty_ax25_if_recv(patty_ax25_if *iface,
|
||||
void **buf) {
|
||||
ssize_t readlen;
|
||||
int port;
|
||||
|
||||
if ((readlen = patty_kiss_tnc_recv(iface->tnc,
|
||||
iface->rx_buf,
|
||||
iface->rx_bufsz,
|
||||
&port)) < 0) {
|
||||
goto error_kiss_tnc_recv;
|
||||
}
|
||||
|
||||
*buf = iface->rx_buf;
|
||||
|
||||
return readlen;
|
||||
|
||||
error_kiss_tnc_recv:
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t patty_ax25_if_send(patty_ax25_if *iface,
|
||||
const void *buf,
|
||||
size_t len) {
|
||||
ssize_t wrlen;
|
||||
|
||||
if ((wrlen = patty_kiss_tnc_send(iface->tnc, buf, len, 0)) < 0) {
|
||||
goto error_kiss_tnc_send;
|
||||
}
|
||||
|
||||
return wrlen;
|
||||
|
||||
error_kiss_tnc_send:
|
||||
return -1;
|
||||
}
|
||||
|
|
337
src/server.c
337
src/server.c
|
@ -10,7 +10,20 @@
|
|||
|
||||
#include <patty/ax25.h>
|
||||
|
||||
typedef int (*patty_ax25_server_call)(patty_ax25_server *, int);
|
||||
|
||||
struct _patty_ax25_server {
|
||||
int fd, /* fd of UNIX domain socket */
|
||||
fd_max;
|
||||
|
||||
struct timeval timeout;
|
||||
|
||||
fd_set fds_watch, /* fds to monitor with select() */
|
||||
fds_socks, /* fds belonging to socks */
|
||||
fds_clients, /* fds belonging to clients */
|
||||
fds_r, /* fds select()ed for reading */
|
||||
fds_w; /* fds select()ed for writing */
|
||||
|
||||
patty_list *ifaces;
|
||||
|
||||
patty_dict *socks_by_fd,
|
||||
|
@ -18,13 +31,8 @@ struct _patty_ax25_server {
|
|||
*socks_pending_connect,
|
||||
*socks_established;
|
||||
|
||||
patty_dict *clients_by_sock;
|
||||
|
||||
int fd_max;
|
||||
|
||||
fd_set fds_watch, /* fds to monitor with select() */
|
||||
fds_socks, /* fds belonging to socks */
|
||||
fds_clients; /* fds belonging to clients */
|
||||
patty_dict *clients,
|
||||
*clients_by_sock;
|
||||
};
|
||||
|
||||
int patty_ax25_server_init(patty_ax25_server *server) {
|
||||
|
@ -50,6 +58,10 @@ int patty_ax25_server_init(patty_ax25_server *server) {
|
|||
goto error_dict_new_socks_established;
|
||||
}
|
||||
|
||||
if ((server->clients = patty_dict_new()) == NULL) {
|
||||
goto error_dict_new_clients;
|
||||
}
|
||||
|
||||
if ((server->clients_by_sock = patty_dict_new()) == NULL) {
|
||||
goto error_dict_new_clients_by_sock;
|
||||
}
|
||||
|
@ -57,6 +69,9 @@ int patty_ax25_server_init(patty_ax25_server *server) {
|
|||
return 0;
|
||||
|
||||
error_dict_new_clients_by_sock:
|
||||
patty_dict_destroy(server->clients);
|
||||
|
||||
error_dict_new_clients:
|
||||
patty_dict_destroy(server->socks_established);
|
||||
|
||||
error_dict_new_socks_established:
|
||||
|
@ -81,17 +96,6 @@ static int destroy_if(patty_ax25_if *iface, void *ctx) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void patty_ax25_server_stop(patty_ax25_server *server) {
|
||||
patty_dict_destroy(server->clients_by_sock);
|
||||
patty_dict_destroy(server->socks_established);
|
||||
patty_dict_destroy(server->socks_pending_connect);
|
||||
patty_dict_destroy(server->socks_pending_accept);
|
||||
patty_dict_destroy(server->socks_by_fd);
|
||||
|
||||
patty_ax25_server_each_if(server, destroy_if, NULL);
|
||||
patty_list_destroy(server->ifaces);
|
||||
}
|
||||
|
||||
static void sock_init(patty_ax25_sock *sock, enum patty_ax25_sock_type type) {
|
||||
memset(sock, '\0', sizeof(*sock));
|
||||
|
||||
|
@ -576,7 +580,10 @@ static int server_accept_unix(patty_ax25_server *server,
|
|||
goto error_socket;
|
||||
}
|
||||
|
||||
if (snprintf(response->path, PATTY_AX25_SOCK_PATH_SIZE, "/var/run/patty/%d.sock", sock->fd) < 0) {
|
||||
if (snprintf(response->path,
|
||||
PATTY_AX25_SOCK_PATH_SIZE,
|
||||
PATTY_AX25_SERVER_CLIENT_PATH_FORMAT,
|
||||
sock->fd) < 0) {
|
||||
goto error_snprintf;
|
||||
}
|
||||
|
||||
|
@ -787,3 +794,295 @@ error_sock_by_fd:
|
|||
error_io:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static patty_ax25_server_call server_calls[PATTY_AX25_CALL_COUNT] = {
|
||||
NULL,
|
||||
server_socket,
|
||||
server_bind,
|
||||
server_listen,
|
||||
server_accept,
|
||||
server_connect,
|
||||
server_close,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int listen_unix(patty_ax25_server *server, const char *path) {
|
||||
struct sockaddr_un addr;
|
||||
|
||||
if (server->fd) {
|
||||
errno = EBUSY;
|
||||
|
||||
goto error_listening;
|
||||
}
|
||||
|
||||
if ((server->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
goto error_socket;
|
||||
}
|
||||
|
||||
memset(&addr, '\0', sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||
|
||||
if (bind(server->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
goto error_bind;
|
||||
}
|
||||
|
||||
if (listen(server->fd, 0) < 0) {
|
||||
goto error_listen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_listen:
|
||||
error_bind:
|
||||
close(server->fd);
|
||||
|
||||
error_socket:
|
||||
error_listening:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int accept_client(patty_ax25_server *server) {
|
||||
int fd;
|
||||
struct sockaddr addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (!FD_ISSET(server->fd, &server->fds_r)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((fd = accept(server->fd, &addr, &addrlen)) < 0) {
|
||||
goto error_accept;
|
||||
}
|
||||
|
||||
if (patty_dict_set(server->clients,
|
||||
NULL + fd,
|
||||
sizeof(fd),
|
||||
NULL + fd) == NULL) {
|
||||
goto error_dict_set;
|
||||
}
|
||||
|
||||
FD_SET(fd, &server->fds_clients);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
||||
error_dict_set:
|
||||
close(fd);
|
||||
|
||||
error_accept:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_client(void *key,
|
||||
size_t keysz,
|
||||
void *value,
|
||||
void *ctx) {
|
||||
patty_ax25_server *server = ctx;
|
||||
int client = (int)(key - NULL);
|
||||
|
||||
ssize_t readlen;
|
||||
enum patty_ax25_call call;
|
||||
|
||||
if (!FD_ISSET(client, &server->fds_r)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((readlen = read(server->fd, &call, sizeof(call))) < 0) {
|
||||
goto error_io;
|
||||
} else if (readlen == 0) {
|
||||
FD_CLR(client, &server->fds_watch);
|
||||
FD_CLR(client, &server->fds_clients);
|
||||
|
||||
if (patty_dict_delete(server->clients,
|
||||
key,
|
||||
keysz) < 0) {
|
||||
goto error_dict_delete;
|
||||
}
|
||||
|
||||
if (close(client) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (call <= PATTY_AX25_CALL_NONE || call >= PATTY_AX25_CALL_COUNT) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
return server_calls[call](server, client);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
||||
error_dict_delete:
|
||||
error_io:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_clients(patty_ax25_server *server) {
|
||||
return patty_dict_each(server->clients, handle_client, server);
|
||||
}
|
||||
|
||||
static int handle_packet_rx(patty_ax25_server *server,
|
||||
patty_ax25_if *iface,
|
||||
void *buf,
|
||||
size_t len) {
|
||||
patty_ax25_frame frame;
|
||||
|
||||
if (patty_ax25_frame_decode(&frame, buf, len) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Handle inbound packet
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
||||
error_io:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_iface(patty_ax25_server *server, patty_ax25_if *iface) {
|
||||
int fd = patty_kiss_tnc_fd(iface->tnc);
|
||||
|
||||
void *buf;
|
||||
ssize_t readlen;
|
||||
|
||||
if (!FD_ISSET(fd, &server->fds_r)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((readlen = patty_ax25_if_recv(iface, &buf)) < 0) {
|
||||
goto error_io;
|
||||
} else if (readlen == 0) {
|
||||
FD_CLR(fd, &server->fds_watch);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (handle_packet_rx(server, iface, buf, readlen) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
||||
error_io:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_ifaces(patty_ax25_server *server) {
|
||||
patty_list_iterator *iter;
|
||||
patty_ax25_if *iface;
|
||||
|
||||
if ((iter = patty_list_start(server->ifaces)) == NULL) {
|
||||
goto error_list_start;
|
||||
}
|
||||
|
||||
while ((iface = patty_list_next(iter)) != NULL) {
|
||||
if (handle_iface(server, iface) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
}
|
||||
|
||||
patty_list_finish(iter);
|
||||
|
||||
return 0;
|
||||
|
||||
error_io:
|
||||
patty_list_finish(iter);
|
||||
|
||||
error_list_start:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int handle_sock(void *key,
|
||||
size_t keysz,
|
||||
void *value,
|
||||
void *ctx) {
|
||||
patty_ax25_server *server = ctx;
|
||||
patty_ax25_sock *sock = value;
|
||||
int fd = (int)(key - NULL);
|
||||
|
||||
ssize_t readlen;
|
||||
|
||||
if (!FD_ISSET(fd, &server->fds_r)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Finish this
|
||||
*/
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_socks(patty_ax25_server *server) {
|
||||
return patty_dict_each(server->socks_by_fd,
|
||||
handle_sock,
|
||||
server);
|
||||
}
|
||||
|
||||
int patty_ax25_server_run(patty_ax25_server *server) {
|
||||
if (listen_unix(server, PATTY_AX25_SERVER_PATH) < 0) {
|
||||
goto error_listen_unix;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int nready;
|
||||
|
||||
FD_COPY(&server->fds_watch, &server->fds_r);
|
||||
FD_COPY(&server->fds_watch, &server->fds_w);
|
||||
|
||||
if ((nready = select( server->fd_max,
|
||||
&server->fds_r,
|
||||
&server->fds_w,
|
||||
NULL,
|
||||
&server->timeout)) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (accept_client(server) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (handle_clients(server) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (handle_ifaces(server) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (handle_socks(server) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
}
|
||||
|
||||
close(server->fd);
|
||||
|
||||
return 0;
|
||||
|
||||
error_io:
|
||||
close(server->fd);
|
||||
|
||||
error_listen_unix:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void patty_ax25_server_destroy(patty_ax25_server *server) {
|
||||
patty_dict_destroy(server->clients_by_sock);
|
||||
patty_dict_destroy(server->clients);
|
||||
patty_dict_destroy(server->socks_established);
|
||||
patty_dict_destroy(server->socks_pending_connect);
|
||||
patty_dict_destroy(server->socks_pending_accept);
|
||||
patty_dict_destroy(server->socks_by_fd);
|
||||
|
||||
patty_ax25_server_each_if(server, destroy_if, NULL);
|
||||
patty_list_destroy(server->ifaces);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue