You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

102 lines
2.3 KiB

/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "common.h"
#include "buf.h"
#include "log.h"
#include "commands.h"
#include "csocket.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/un.h>
typedef struct f2b_conn_t {
int sock;
const char *path;
f2b_buf_t recv;
f2b_buf_t send;
} f2b_conn_t;
struct f2b_csock_t {
f2b_conn_t *clients[MAXCONNS];
const char *path;
int sock;
bool shutdown;
};
f2b_csock_t *
f2b_csocket_create(const char *path) {
f2b_csock_t *csock;
struct sockaddr_un addr;
int sock = -1;
assert(path != NULL);
if ((sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) {
f2b_log_msg(log_error, "can't create control socket: %s", strerror(errno));
return NULL;
}
memset(&addr, 0x0, sizeof(addr));
addr.sun_family = AF_UNIX;
strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
unlink(path);
if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) != 0) {
f2b_log_msg(log_error, "bind() on socket failed: %s", strerror(errno));
return NULL;
}
if (listen(sock, 5) < 0) {
f2b_log_msg(log_error, "listen() on socket failed: %s", strerror(errno));
return NULL;
}
if ((csock = calloc(1, sizeof(f2b_csock_t))) == NULL) {
f2b_log_msg(log_error, "can't allocate memory for csocket struct");
shutdown(sock, SHUT_RDWR);
unlink(path);
return NULL;
}
csock->sock = sock;
csock->path = path;
return csock;
}
void
f2b_csocket_destroy(f2b_csock_t *csock) {
f2b_conn_t *conn = NULL;
assert(csock != NULL);
if (csock->sock >= 0)
shutdown(csock->sock, SHUT_RDWR);
if (csock->path != NULL)
unlink(csock->path);
for (int i = 0; i < MAXCONNS; i++) {
if ((conn = csock->clients[i]) == NULL)
continue;
shutdown(conn->sock, SHUT_RDWR);
f2b_buf_free(&conn->recv);
f2b_buf_free(&conn->send);
free(conn);
}
free(csock);
return;
}
int
f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) {
f2b_cmd_t *cmd = NULL;
int ret, processed = 0;
assert(csock != NULL);
assert(cb != NULL);
return processed;
}