client: renamed internal functions and variables

Rename all static functions, variables and macros which have
"interface" in their name to something nicer prefixed with "client_".
This commit is contained in:
Max Kellermann 2008-08-28 20:02:59 +02:00
parent fe03cb9549
commit 6d18e00099

View File

@ -33,34 +33,34 @@
#define GREETING "OK MPD " PROTOCOL_VERSION "\n" #define GREETING "OK MPD " PROTOCOL_VERSION "\n"
#define INTERFACE_MAX_BUFFER_LENGTH (40960) #define CLIENT_MAX_BUFFER_LENGTH (40960)
#define INTERFACE_LIST_MODE_BEGIN "command_list_begin" #define CLIENT_LIST_MODE_BEGIN "command_list_begin"
#define INTERFACE_LIST_OK_MODE_BEGIN "command_list_ok_begin" #define CLIENT_LIST_OK_MODE_BEGIN "command_list_ok_begin"
#define INTERFACE_LIST_MODE_END "command_list_end" #define CLIENT_LIST_MODE_END "command_list_end"
#define INTERFACE_DEFAULT_OUT_BUFFER_SIZE (4096) #define CLIENT_DEFAULT_OUT_BUFFER_SIZE (4096)
#define INTERFACE_TIMEOUT_DEFAULT (60) #define CLIENT_TIMEOUT_DEFAULT (60)
#define INTERFACE_MAX_CONNECTIONS_DEFAULT (10) #define CLIENT_MAX_CONNECTIONS_DEFAULT (10)
#define INTERFACE_MAX_COMMAND_LIST_DEFAULT (2048*1024) #define CLIENT_MAX_COMMAND_LIST_DEFAULT (2048*1024)
#define INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT (8192*1024) #define CLIENT_MAX_OUTPUT_BUFFER_SIZE_DEFAULT (8192*1024)
/* set this to zero to indicate we have no possible interfaces */ /* set this to zero to indicate we have no possible clients */
static unsigned int interface_max_connections; /*INTERFACE_MAX_CONNECTIONS_DEFAULT; */ static unsigned int client_max_connections; /*CLIENT_MAX_CONNECTIONS_DEFAULT; */
static int interface_timeout = INTERFACE_TIMEOUT_DEFAULT; static int client_timeout = CLIENT_TIMEOUT_DEFAULT;
static size_t interface_max_command_list_size = static size_t client_max_command_list_size =
INTERFACE_MAX_COMMAND_LIST_DEFAULT; CLIENT_MAX_COMMAND_LIST_DEFAULT;
static size_t interface_max_output_buffer_size = static size_t client_max_output_buffer_size =
INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT; CLIENT_MAX_OUTPUT_BUFFER_SIZE_DEFAULT;
/* maybe make conf option for this, or... 32 might be good enough */ /* maybe make conf option for this, or... 32 might be good enough */
static long int interface_list_cache_size = 32; static long int client_list_cache_size = 32;
/* shared globally between all interfaces: */ /* shared globally between all clients: */
static struct strnode *list_cache; static struct strnode *list_cache;
static struct strnode *list_cache_head; static struct strnode *list_cache_head;
static struct strnode *list_cache_tail; static struct strnode *list_cache_tail;
struct client { struct client {
char buffer[INTERFACE_MAX_BUFFER_LENGTH]; char buffer[CLIENT_MAX_BUFFER_LENGTH];
size_t bufferLength; size_t bufferLength;
size_t bufferPos; size_t bufferPos;
int fd; /* file descriptor */ int fd; /* file descriptor */
@ -73,9 +73,9 @@ struct client {
int cmd_list_dup; /* has the cmd_list been copied to private space? */ int cmd_list_dup; /* has the cmd_list been copied to private space? */
struct sllnode *deferred_send; /* for output if client is slow */ struct sllnode *deferred_send; /* for output if client is slow */
size_t deferred_bytes; /* mem deferred_send consumes */ size_t deferred_bytes; /* mem deferred_send consumes */
int expired; /* set whether this interface should be closed on next int expired; /* set whether this client should be closed on next
check of old interfaces */ check of old clients */
unsigned int num; /* interface number */ unsigned int num; /* client number */
char *send_buf; char *send_buf;
size_t send_buf_used; /* bytes used this instance */ size_t send_buf_used; /* bytes used this instance */
@ -83,71 +83,71 @@ struct client {
size_t send_buf_alloc; /* bytes actually allocated */ size_t send_buf_alloc; /* bytes actually allocated */
}; };
static struct client *interfaces; static struct client *clients;
static void flushInterfaceBuffer(struct client *interface); static void client_write_deferred(struct client *client);
static void printInterfaceOutBuffer(struct client *interface); static void client_write_output(struct client *client);
#ifdef SO_SNDBUF #ifdef SO_SNDBUF
static size_t get_default_snd_buf_size(struct client *interface) static size_t get_default_snd_buf_size(struct client *client)
{ {
int new_size; int new_size;
socklen_t sockOptLen = sizeof(int); socklen_t sockOptLen = sizeof(int);
if (getsockopt(interface->fd, SOL_SOCKET, SO_SNDBUF, if (getsockopt(client->fd, SOL_SOCKET, SO_SNDBUF,
(char *)&new_size, &sockOptLen) < 0) { (char *)&new_size, &sockOptLen) < 0) {
DEBUG("problem getting sockets send buffer size\n"); DEBUG("problem getting sockets send buffer size\n");
return INTERFACE_DEFAULT_OUT_BUFFER_SIZE; return CLIENT_DEFAULT_OUT_BUFFER_SIZE;
} }
if (new_size > 0) if (new_size > 0)
return (size_t)new_size; return (size_t)new_size;
DEBUG("sockets send buffer size is not positive\n"); DEBUG("sockets send buffer size is not positive\n");
return INTERFACE_DEFAULT_OUT_BUFFER_SIZE; return CLIENT_DEFAULT_OUT_BUFFER_SIZE;
} }
#else /* !SO_SNDBUF */ #else /* !SO_SNDBUF */
static size_t get_default_snd_buf_size(struct client *interface) static size_t get_default_snd_buf_size(struct client *client)
{ {
return INTERFACE_DEFAULT_OUT_BUFFER_SIZE; return CLIENT_DEFAULT_OUT_BUFFER_SIZE;
} }
#endif /* !SO_SNDBUF */ #endif /* !SO_SNDBUF */
static void set_send_buf_size(struct client *interface) static void set_send_buf_size(struct client *client)
{ {
size_t new_size = get_default_snd_buf_size(interface); size_t new_size = get_default_snd_buf_size(client);
if (interface->send_buf_size != new_size) { if (client->send_buf_size != new_size) {
interface->send_buf_size = new_size; client->send_buf_size = new_size;
/* don't resize to get smaller, only bigger */ /* don't resize to get smaller, only bigger */
if (interface->send_buf_alloc < new_size) { if (client->send_buf_alloc < new_size) {
if (interface->send_buf) if (client->send_buf)
free(interface->send_buf); free(client->send_buf);
interface->send_buf = xmalloc(new_size); client->send_buf = xmalloc(new_size);
interface->send_buf_alloc = new_size; client->send_buf_alloc = new_size;
} }
} }
} }
static void openInterface(struct client *interface, int fd) static void client_init(struct client *client, int fd)
{ {
assert(interface->fd < 0); assert(client->fd < 0);
interface->cmd_list_size = 0; client->cmd_list_size = 0;
interface->cmd_list_dup = 0; client->cmd_list_dup = 0;
interface->cmd_list_OK = -1; client->cmd_list_OK = -1;
interface->bufferLength = 0; client->bufferLength = 0;
interface->bufferPos = 0; client->bufferPos = 0;
interface->fd = fd; client->fd = fd;
set_nonblocking(fd); set_nonblocking(fd);
interface->lastTime = time(NULL); client->lastTime = time(NULL);
interface->cmd_list = NULL; client->cmd_list = NULL;
interface->cmd_list_tail = NULL; client->cmd_list_tail = NULL;
interface->deferred_send = NULL; client->deferred_send = NULL;
interface->expired = 0; client->expired = 0;
interface->deferred_bytes = 0; client->deferred_bytes = 0;
interface->send_buf_used = 0; client->send_buf_used = 0;
interface->permission = getDefaultPermissions(); client->permission = getDefaultPermissions();
set_send_buf_size(interface); set_send_buf_size(client);
xwrite(fd, GREETING, strlen(GREETING)); xwrite(fd, GREETING, strlen(GREETING));
} }
@ -168,26 +168,26 @@ static void free_cmd_list(struct strnode *list)
} }
} }
static void cmd_list_clone(struct client *interface) static void cmd_list_clone(struct client *client)
{ {
struct strnode *new = dup_strlist(interface->cmd_list); struct strnode *new = dup_strlist(client->cmd_list);
free_cmd_list(interface->cmd_list); free_cmd_list(client->cmd_list);
interface->cmd_list = new; client->cmd_list = new;
interface->cmd_list_dup = 1; client->cmd_list_dup = 1;
/* new tail */ /* new tail */
while (new && new->next) while (new && new->next)
new = new->next; new = new->next;
interface->cmd_list_tail = new; client->cmd_list_tail = new;
} }
static void new_cmd_list_ptr(struct client *interface, char *s, const int size) static void new_cmd_list_ptr(struct client *client, char *s, const int size)
{ {
int i; int i;
struct strnode *new; struct strnode *new;
if (!interface->cmd_list_dup) { if (!client->cmd_list_dup) {
for (i = interface_list_cache_size - 1; i >= 0; --i) { for (i = client_list_cache_size - 1; i >= 0; --i) {
if (list_cache[i].data) if (list_cache[i].data)
continue; continue;
new = &(list_cache[i]); new = &(list_cache[i]);
@ -199,49 +199,49 @@ static void new_cmd_list_ptr(struct client *interface, char *s, const int size)
} }
/* allocate from the heap */ /* allocate from the heap */
new = interface->cmd_list_dup ? new_strnode_dup(s, size) new = client->cmd_list_dup ? new_strnode_dup(s, size)
: new_strnode(s); : new_strnode(s);
out: out:
if (interface->cmd_list) { if (client->cmd_list) {
interface->cmd_list_tail->next = new; client->cmd_list_tail->next = new;
interface->cmd_list_tail = new; client->cmd_list_tail = new;
} else } else
interface->cmd_list = interface->cmd_list_tail = new; client->cmd_list = client->cmd_list_tail = new;
} }
static void closeInterface(struct client *interface) static void client_close(struct client *client)
{ {
struct sllnode *buf; struct sllnode *buf;
if (interface->fd < 0) if (client->fd < 0)
return; return;
xclose(interface->fd); xclose(client->fd);
interface->fd = -1; client->fd = -1;
if (interface->cmd_list) { if (client->cmd_list) {
free_cmd_list(interface->cmd_list); free_cmd_list(client->cmd_list);
interface->cmd_list = NULL; client->cmd_list = NULL;
} }
if ((buf = interface->deferred_send)) { if ((buf = client->deferred_send)) {
do { do {
struct sllnode *prev = buf; struct sllnode *prev = buf;
buf = buf->next; buf = buf->next;
free(prev); free(prev);
} while (buf); } while (buf);
interface->deferred_send = NULL; client->deferred_send = NULL;
} }
SECURE("interface %i: closed\n", interface->num); SECURE("client %i: closed\n", client->num);
} }
void openAInterface(int fd, const struct sockaddr *addr) void openAInterface(int fd, const struct sockaddr *addr)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < interface_max_connections for (i = 0; i < client_max_connections
&& interfaces[i].fd >= 0; i++) /* nothing */ ; && clients[i].fd >= 0; i++) /* nothing */ ;
if (i == interface_max_connections) { if (i == client_max_connections) {
ERROR("Max Connections Reached!\n"); ERROR("Max Connections Reached!\n");
xclose(fd); xclose(fd);
} else { } else {
@ -279,120 +279,120 @@ void openAInterface(int fd, const struct sockaddr *addr)
default: default:
hostname = "unknown"; hostname = "unknown";
} }
SECURE("interface %i: opened from %s\n", i, hostname); SECURE("client %i: opened from %s\n", i, hostname);
openInterface(&(interfaces[i]), fd); client_init(&(clients[i]), fd);
} }
} }
static int processLineOfInput(struct client *interface) static int client_process_line(struct client *client)
{ {
int ret = 1; int ret = 1;
char *line = interface->buffer + interface->bufferPos; char *line = client->buffer + client->bufferPos;
if (interface->cmd_list_OK >= 0) { if (client->cmd_list_OK >= 0) {
if (strcmp(line, INTERFACE_LIST_MODE_END) == 0) { if (strcmp(line, CLIENT_LIST_MODE_END) == 0) {
DEBUG("interface %i: process command " DEBUG("client %i: process command "
"list\n", interface->num); "list\n", client->num);
ret = processListOfCommands(interface->fd, ret = processListOfCommands(client->fd,
&(interface->permission), &(client->permission),
&(interface->expired), &(client->expired),
interface->cmd_list_OK, client->cmd_list_OK,
interface->cmd_list); client->cmd_list);
DEBUG("interface %i: process command " DEBUG("client %i: process command "
"list returned %i\n", interface->num, ret); "list returned %i\n", client->num, ret);
if (ret == 0) if (ret == 0)
commandSuccess(interface->fd); commandSuccess(client->fd);
else if (ret == COMMAND_RETURN_CLOSE else if (ret == COMMAND_RETURN_CLOSE
|| interface->expired) || client->expired)
closeInterface(interface); client_close(client);
printInterfaceOutBuffer(interface); client_write_output(client);
free_cmd_list(interface->cmd_list); free_cmd_list(client->cmd_list);
interface->cmd_list = NULL; client->cmd_list = NULL;
interface->cmd_list_OK = -1; client->cmd_list_OK = -1;
} else { } else {
size_t len = strlen(line) + 1; size_t len = strlen(line) + 1;
interface->cmd_list_size += len; client->cmd_list_size += len;
if (interface->cmd_list_size > if (client->cmd_list_size >
interface_max_command_list_size) { client_max_command_list_size) {
ERROR("interface %i: command " ERROR("client %i: command "
"list size (%lu) is " "list size (%lu) is "
"larger than the max " "larger than the max "
"(%lu)\n", "(%lu)\n",
interface->num, client->num,
(unsigned long)interface->cmd_list_size, (unsigned long)client->cmd_list_size,
(unsigned long) (unsigned long)
interface_max_command_list_size); client_max_command_list_size);
closeInterface(interface); client_close(client);
ret = COMMAND_RETURN_CLOSE; ret = COMMAND_RETURN_CLOSE;
} else } else
new_cmd_list_ptr(interface, line, len); new_cmd_list_ptr(client, line, len);
} }
} else { } else {
if (strcmp(line, INTERFACE_LIST_MODE_BEGIN) == 0) { if (strcmp(line, CLIENT_LIST_MODE_BEGIN) == 0) {
interface->cmd_list_OK = 0; client->cmd_list_OK = 0;
ret = 1; ret = 1;
} else if (strcmp(line, INTERFACE_LIST_OK_MODE_BEGIN) == 0) { } else if (strcmp(line, CLIENT_LIST_OK_MODE_BEGIN) == 0) {
interface->cmd_list_OK = 1; client->cmd_list_OK = 1;
ret = 1; ret = 1;
} else { } else {
DEBUG("interface %i: process command \"%s\"\n", DEBUG("client %i: process command \"%s\"\n",
interface->num, line); client->num, line);
ret = processCommand(interface->fd, ret = processCommand(client->fd,
&(interface->permission), line); &(client->permission), line);
DEBUG("interface %i: command returned %i\n", DEBUG("client %i: command returned %i\n",
interface->num, ret); client->num, ret);
if (ret == 0) if (ret == 0)
commandSuccess(interface->fd); commandSuccess(client->fd);
else if (ret == COMMAND_RETURN_CLOSE else if (ret == COMMAND_RETURN_CLOSE
|| interface->expired) { || client->expired) {
closeInterface(interface); client_close(client);
} }
printInterfaceOutBuffer(interface); client_write_output(client);
} }
} }
return ret; return ret;
} }
static int processBytesRead(struct client *interface, int bytesRead) static int client_input_received(struct client *client, int bytesRead)
{ {
int ret = 0; int ret = 0;
char *buf_tail = &(interface->buffer[interface->bufferLength - 1]); char *buf_tail = &(client->buffer[client->bufferLength - 1]);
while (bytesRead > 0) { while (bytesRead > 0) {
interface->bufferLength++; client->bufferLength++;
bytesRead--; bytesRead--;
buf_tail++; buf_tail++;
if (*buf_tail == '\n') { if (*buf_tail == '\n') {
*buf_tail = '\0'; *buf_tail = '\0';
if (interface->bufferLength > interface->bufferPos) { if (client->bufferLength > client->bufferPos) {
if (*(buf_tail - 1) == '\r') if (*(buf_tail - 1) == '\r')
*(buf_tail - 1) = '\0'; *(buf_tail - 1) = '\0';
} }
ret = processLineOfInput(interface); ret = client_process_line(client);
if (interface->expired) if (client->expired)
return ret; return ret;
interface->bufferPos = interface->bufferLength; client->bufferPos = client->bufferLength;
} }
if (interface->bufferLength == INTERFACE_MAX_BUFFER_LENGTH) { if (client->bufferLength == CLIENT_MAX_BUFFER_LENGTH) {
if (interface->bufferPos == 0) { if (client->bufferPos == 0) {
ERROR("interface %i: buffer overflow\n", ERROR("client %i: buffer overflow\n",
interface->num); client->num);
closeInterface(interface); client_close(client);
return 1; return 1;
} }
if (interface->cmd_list_OK >= 0 && if (client->cmd_list_OK >= 0 &&
interface->cmd_list && client->cmd_list &&
!interface->cmd_list_dup) !client->cmd_list_dup)
cmd_list_clone(interface); cmd_list_clone(client);
assert(interface->bufferLength >= interface->bufferPos assert(client->bufferLength >= client->bufferPos
&& "bufferLength >= bufferPos"); && "bufferLength >= bufferPos");
interface->bufferLength -= interface->bufferPos; client->bufferLength -= client->bufferPos;
memmove(interface->buffer, memmove(client->buffer,
interface->buffer + interface->bufferPos, client->buffer + client->bufferPos,
interface->bufferLength); client->bufferLength);
interface->bufferPos = 0; client->bufferPos = 0;
} }
if (ret == COMMAND_RETURN_KILL || ret == COMMAND_RETURN_CLOSE) { if (ret == COMMAND_RETURN_KILL || ret == COMMAND_RETURN_CLOSE) {
return ret; return ret;
@ -403,54 +403,53 @@ static int processBytesRead(struct client *interface, int bytesRead)
return ret; return ret;
} }
static int interfaceReadInput(struct client *interface) static int client_read(struct client *client)
{ {
int bytesRead; int bytesRead;
bytesRead = read(interface->fd, bytesRead = read(client->fd,
interface->buffer + interface->bufferLength, client->buffer + client->bufferLength,
INTERFACE_MAX_BUFFER_LENGTH - interface->bufferLength); CLIENT_MAX_BUFFER_LENGTH - client->bufferLength);
if (bytesRead > 0) if (bytesRead > 0)
return processBytesRead(interface, bytesRead); return client_input_received(client, bytesRead);
else if (bytesRead == 0 || (bytesRead < 0 && errno != EINTR)) { else if (bytesRead == 0 || (bytesRead < 0 && errno != EINTR)) {
closeInterface(interface); client_close(client);
} else } else
return 0; return 0;
return 1; return 1;
} }
static void addInterfacesReadyToReadAndListenSocketToFdSet(fd_set * fds, static void client_manager_register_read_fd(fd_set * fds, int *fdmax)
int *fdmax)
{ {
unsigned int i; unsigned int i;
FD_ZERO(fds); FD_ZERO(fds);
addListenSocketsToFdSet(fds, fdmax); addListenSocketsToFdSet(fds, fdmax);
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd >= 0 && !interfaces[i].expired if (clients[i].fd >= 0 && !clients[i].expired
&& !interfaces[i].deferred_send) { && !clients[i].deferred_send) {
FD_SET(interfaces[i].fd, fds); FD_SET(clients[i].fd, fds);
if (*fdmax < interfaces[i].fd) if (*fdmax < clients[i].fd)
*fdmax = interfaces[i].fd; *fdmax = clients[i].fd;
} }
} }
} }
static void addInterfacesForBufferFlushToFdSet(fd_set * fds, int *fdmax) static void client_manager_register_write_fd(fd_set * fds, int *fdmax)
{ {
unsigned int i; unsigned int i;
FD_ZERO(fds); FD_ZERO(fds);
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd >= 0 && !interfaces[i].expired if (clients[i].fd >= 0 && !clients[i].expired
&& interfaces[i].deferred_send) { && clients[i].deferred_send) {
FD_SET(interfaces[i].fd, fds); FD_SET(clients[i].fd, fds);
if (*fdmax < interfaces[i].fd) if (*fdmax < clients[i].fd)
*fdmax = interfaces[i].fd; *fdmax = clients[i].fd;
} }
} }
} }
@ -464,13 +463,13 @@ static void closeNextErroredInterface(void)
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 0; tv.tv_usec = 0;
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd >= 0) { if (clients[i].fd >= 0) {
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(interfaces[i].fd, &fds); FD_SET(clients[i].fd, &fds);
if (select(interfaces[i].fd + 1, if (select(clients[i].fd + 1,
&fds, NULL, NULL, &tv) < 0) { &fds, NULL, NULL, &tv) < 0) {
closeInterface(&interfaces[i]); client_close(&clients[i]);
return; return;
} }
} }
@ -490,8 +489,8 @@ int doIOForInterfaces(void)
fdmax = 0; fdmax = 0;
FD_ZERO( &efds ); FD_ZERO( &efds );
addInterfacesReadyToReadAndListenSocketToFdSet(&rfds, &fdmax); client_manager_register_read_fd(&rfds, &fdmax);
addInterfacesForBufferFlushToFdSet(&wfds, &fdmax); client_manager_register_write_fd(&wfds, &fdmax);
registered_IO_add_fds(&fdmax, &rfds, &wfds, &efds); registered_IO_add_fds(&fdmax, &rfds, &wfds, &efds);
@ -514,19 +513,19 @@ int doIOForInterfaces(void)
getConnections(&rfds); getConnections(&rfds);
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd >= 0 if (clients[i].fd >= 0
&& FD_ISSET(interfaces[i].fd, &rfds)) { && FD_ISSET(clients[i].fd, &rfds)) {
if (COMMAND_RETURN_KILL == if (COMMAND_RETURN_KILL ==
interfaceReadInput(&(interfaces[i]))) { client_read(&(clients[i]))) {
return COMMAND_RETURN_KILL; return COMMAND_RETURN_KILL;
} }
interfaces[i].lastTime = time(NULL); clients[i].lastTime = time(NULL);
} }
if (interfaces[i].fd >= 0 if (clients[i].fd >= 0
&& FD_ISSET(interfaces[i].fd, &wfds)) { && FD_ISSET(clients[i].fd, &wfds)) {
flushInterfaceBuffer(&interfaces[i]); client_write_deferred(&clients[i]);
interfaces[i].lastTime = time(NULL); clients[i].lastTime = time(NULL);
} }
} }
@ -545,8 +544,8 @@ void initInterfaces(void)
param = getConfigParam(CONF_CONN_TIMEOUT); param = getConfigParam(CONF_CONN_TIMEOUT);
if (param) { if (param) {
interface_timeout = strtol(param->value, &test, 10); client_timeout = strtol(param->value, &test, 10);
if (*test != '\0' || interface_timeout <= 0) { if (*test != '\0' || client_timeout <= 0) {
FATAL("connection timeout \"%s\" is not a positive " FATAL("connection timeout \"%s\" is not a positive "
"integer, line %i\n", CONF_CONN_TIMEOUT, "integer, line %i\n", CONF_CONN_TIMEOUT,
param->line); param->line);
@ -556,13 +555,13 @@ void initInterfaces(void)
param = getConfigParam(CONF_MAX_CONN); param = getConfigParam(CONF_MAX_CONN);
if (param) { if (param) {
interface_max_connections = strtol(param->value, &test, 10); client_max_connections = strtol(param->value, &test, 10);
if (*test != '\0' || interface_max_connections <= 0) { if (*test != '\0' || client_max_connections <= 0) {
FATAL("max connections \"%s\" is not a positive integer" FATAL("max connections \"%s\" is not a positive integer"
", line %i\n", param->value, param->line); ", line %i\n", param->value, param->line);
} }
} else } else
interface_max_connections = INTERFACE_MAX_CONNECTIONS_DEFAULT; client_max_connections = CLIENT_MAX_CONNECTIONS_DEFAULT;
param = getConfigParam(CONF_MAX_COMMAND_LIST_SIZE); param = getConfigParam(CONF_MAX_COMMAND_LIST_SIZE);
@ -572,7 +571,7 @@ void initInterfaces(void)
FATAL("max command list size \"%s\" is not a positive " FATAL("max command list size \"%s\" is not a positive "
"integer, line %i\n", param->value, param->line); "integer, line %i\n", param->value, param->line);
} }
interface_max_command_list_size = tmp * 1024; client_max_command_list_size = tmp * 1024;
} }
param = getConfigParam(CONF_MAX_OUTPUT_BUFFER_SIZE); param = getConfigParam(CONF_MAX_OUTPUT_BUFFER_SIZE);
@ -583,109 +582,109 @@ void initInterfaces(void)
FATAL("max output buffer size \"%s\" is not a positive " FATAL("max output buffer size \"%s\" is not a positive "
"integer, line %i\n", param->value, param->line); "integer, line %i\n", param->value, param->line);
} }
interface_max_output_buffer_size = tmp * 1024; client_max_output_buffer_size = tmp * 1024;
} }
interfaces = xmalloc(sizeof(interfaces[0]) * interface_max_connections); clients = xmalloc(sizeof(clients[0]) * client_max_connections);
list_cache = xcalloc(interface_list_cache_size, sizeof(struct strnode)); list_cache = xcalloc(client_list_cache_size, sizeof(struct strnode));
list_cache_head = &(list_cache[0]); list_cache_head = &(list_cache[0]);
list_cache_tail = &(list_cache[interface_list_cache_size - 1]); list_cache_tail = &(list_cache[client_list_cache_size - 1]);
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
interfaces[i].fd = -1; clients[i].fd = -1;
interfaces[i].send_buf = NULL; clients[i].send_buf = NULL;
interfaces[i].send_buf_size = 0; clients[i].send_buf_size = 0;
interfaces[i].send_buf_alloc = 0; clients[i].send_buf_alloc = 0;
interfaces[i].num = i; clients[i].num = i;
} }
} }
static void closeAllInterfaces(void) static void client_close_all(void)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd >= 0) if (clients[i].fd >= 0)
closeInterface(&(interfaces[i])); client_close(&(clients[i]));
if (interfaces[i].send_buf) if (clients[i].send_buf)
free(interfaces[i].send_buf); free(clients[i].send_buf);
} }
free(list_cache); free(list_cache);
} }
void freeAllInterfaces(void) void freeAllInterfaces(void)
{ {
closeAllInterfaces(); client_close_all();
free(interfaces); free(clients);
interface_max_connections = 0; client_max_connections = 0;
} }
void closeOldInterfaces(void) void closeOldInterfaces(void)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd >= 0) { if (clients[i].fd >= 0) {
if (interfaces[i].expired) { if (clients[i].expired) {
DEBUG("interface %i: expired\n", i); DEBUG("client %i: expired\n", i);
closeInterface(&(interfaces[i])); client_close(&(clients[i]));
} else if (time(NULL) - interfaces[i].lastTime > } else if (time(NULL) - clients[i].lastTime >
interface_timeout) { client_timeout) {
DEBUG("interface %i: timeout\n", i); DEBUG("client %i: timeout\n", i);
closeInterface(&(interfaces[i])); client_close(&(clients[i]));
} }
} }
} }
} }
static void flushInterfaceBuffer(struct client *interface) static void client_write_deferred(struct client *client)
{ {
struct sllnode *buf; struct sllnode *buf;
ssize_t ret = 0; ssize_t ret = 0;
buf = interface->deferred_send; buf = client->deferred_send;
while (buf) { while (buf) {
ret = write(interface->fd, buf->data, buf->size); ret = write(client->fd, buf->data, buf->size);
if (ret < 0) if (ret < 0)
break; break;
else if ((size_t)ret < buf->size) { else if ((size_t)ret < buf->size) {
assert(interface->deferred_bytes >= (size_t)ret); assert(client->deferred_bytes >= (size_t)ret);
interface->deferred_bytes -= ret; client->deferred_bytes -= ret;
buf->data = (char *)buf->data + ret; buf->data = (char *)buf->data + ret;
buf->size -= ret; buf->size -= ret;
} else { } else {
struct sllnode *tmp = buf; struct sllnode *tmp = buf;
size_t decr = (buf->size + sizeof(struct sllnode)); size_t decr = (buf->size + sizeof(struct sllnode));
assert(interface->deferred_bytes >= decr); assert(client->deferred_bytes >= decr);
interface->deferred_bytes -= decr; client->deferred_bytes -= decr;
buf = buf->next; buf = buf->next;
free(tmp); free(tmp);
interface->deferred_send = buf; client->deferred_send = buf;
} }
interface->lastTime = time(NULL); client->lastTime = time(NULL);
} }
if (!interface->deferred_send) { if (!client->deferred_send) {
DEBUG("interface %i: buffer empty %lu\n", interface->num, DEBUG("client %i: buffer empty %lu\n", client->num,
(unsigned long)interface->deferred_bytes); (unsigned long)client->deferred_bytes);
assert(interface->deferred_bytes == 0); assert(client->deferred_bytes == 0);
} else if (ret < 0 && errno != EAGAIN && errno != EINTR) { } else if (ret < 0 && errno != EAGAIN && errno != EINTR) {
/* cause interface to close */ /* cause client to close */
DEBUG("interface %i: problems flushing buffer\n", DEBUG("client %i: problems flushing buffer\n",
interface->num); client->num);
buf = interface->deferred_send; buf = client->deferred_send;
do { do {
struct sllnode *prev = buf; struct sllnode *prev = buf;
buf = buf->next; buf = buf->next;
free(prev); free(prev);
} while (buf); } while (buf);
interface->deferred_send = NULL; client->deferred_send = NULL;
interface->deferred_bytes = 0; client->deferred_bytes = 0;
interface->expired = 1; client->expired = 1;
} }
} }
@ -693,105 +692,105 @@ int interfacePrintWithFD(int fd, const char *buffer, size_t buflen)
{ {
static unsigned int i; static unsigned int i;
size_t copylen; size_t copylen;
struct client *interface; struct client *client;
assert(fd >= 0); assert(fd >= 0);
if (i >= interface_max_connections || if (i >= client_max_connections ||
interfaces[i].fd < 0 || interfaces[i].fd != fd) { clients[i].fd < 0 || clients[i].fd != fd) {
for (i = 0; i < interface_max_connections; i++) { for (i = 0; i < client_max_connections; i++) {
if (interfaces[i].fd == fd) if (clients[i].fd == fd)
break; break;
} }
if (i == interface_max_connections) if (i == client_max_connections)
return -1; return -1;
} }
/* if fd isn't found or interfaces is going to be closed, do nothing */ /* if fd isn't found or client is going to be closed, do nothing */
if (interfaces[i].expired) if (clients[i].expired)
return 0; return 0;
interface = interfaces + i; client = clients + i;
while (buflen > 0 && !interface->expired) { while (buflen > 0 && !client->expired) {
size_t left; size_t left;
assert(interface->send_buf_size >= interface->send_buf_used); assert(client->send_buf_size >= client->send_buf_used);
left = interface->send_buf_size - interface->send_buf_used; left = client->send_buf_size - client->send_buf_used;
copylen = buflen > left ? left : buflen; copylen = buflen > left ? left : buflen;
memcpy(interface->send_buf + interface->send_buf_used, buffer, memcpy(client->send_buf + client->send_buf_used, buffer,
copylen); copylen);
buflen -= copylen; buflen -= copylen;
interface->send_buf_used += copylen; client->send_buf_used += copylen;
buffer += copylen; buffer += copylen;
if (interface->send_buf_used >= interface->send_buf_size) if (client->send_buf_used >= client->send_buf_size)
printInterfaceOutBuffer(interface); client_write_output(client);
} }
return 0; return 0;
} }
static void printInterfaceOutBuffer(struct client *interface) static void client_write_output(struct client *client)
{ {
ssize_t ret; ssize_t ret;
struct sllnode *buf; struct sllnode *buf;
if (interface->fd < 0 || interface->expired || if (client->fd < 0 || client->expired ||
!interface->send_buf_used) !client->send_buf_used)
return; return;
if ((buf = interface->deferred_send)) { if ((buf = client->deferred_send)) {
interface->deferred_bytes += sizeof(struct sllnode) client->deferred_bytes += sizeof(struct sllnode)
+ interface->send_buf_used; + client->send_buf_used;
if (interface->deferred_bytes > if (client->deferred_bytes >
interface_max_output_buffer_size) { client_max_output_buffer_size) {
ERROR("interface %i: output buffer size (%lu) is " ERROR("client %i: output buffer size (%lu) is "
"larger than the max (%lu)\n", "larger than the max (%lu)\n",
interface->num, client->num,
(unsigned long)interface->deferred_bytes, (unsigned long)client->deferred_bytes,
(unsigned long)interface_max_output_buffer_size); (unsigned long)client_max_output_buffer_size);
/* cause interface to close */ /* cause client to close */
interface->expired = 1; client->expired = 1;
do { do {
struct sllnode *prev = buf; struct sllnode *prev = buf;
buf = buf->next; buf = buf->next;
free(prev); free(prev);
} while (buf); } while (buf);
interface->deferred_send = NULL; client->deferred_send = NULL;
interface->deferred_bytes = 0; client->deferred_bytes = 0;
} else { } else {
while (buf->next) while (buf->next)
buf = buf->next; buf = buf->next;
buf->next = new_sllnode(interface->send_buf, buf->next = new_sllnode(client->send_buf,
interface->send_buf_used); client->send_buf_used);
} }
} else { } else {
if ((ret = write(interface->fd, interface->send_buf, if ((ret = write(client->fd, client->send_buf,
interface->send_buf_used)) < 0) { client->send_buf_used)) < 0) {
if (errno == EAGAIN || errno == EINTR) { if (errno == EAGAIN || errno == EINTR) {
interface->deferred_send = client->deferred_send =
new_sllnode(interface->send_buf, new_sllnode(client->send_buf,
interface->send_buf_used); client->send_buf_used);
} else { } else {
DEBUG("interface %i: problems writing\n", DEBUG("client %i: problems writing\n",
interface->num); client->num);
interface->expired = 1; client->expired = 1;
return; return;
} }
} else if ((size_t)ret < interface->send_buf_used) { } else if ((size_t)ret < client->send_buf_used) {
interface->deferred_send = client->deferred_send =
new_sllnode(interface->send_buf + ret, new_sllnode(client->send_buf + ret,
interface->send_buf_used - ret); client->send_buf_used - ret);
} }
if (interface->deferred_send) { if (client->deferred_send) {
DEBUG("interface %i: buffer created\n", interface->num); DEBUG("client %i: buffer created\n", client->num);
interface->deferred_bytes = client->deferred_bytes =
interface->deferred_send->size client->deferred_send->size
+ sizeof(struct sllnode); + sizeof(struct sllnode);
} }
} }
interface->send_buf_used = 0; client->send_buf_used = 0;
} }