#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "remote_pool.h"
#include "common.h"
void remote_pool_init (struct remote_pool *pool_info) {
memset(pool_info, 0, sizeof(*pool_info));
}
int remote_pool_add (struct remote_pool *pool_info, const char *hostname, const char *portname) {
int i;
struct remote_node *node_info = NULL;
// find a free remote_node entry and store its pointer in node_info
for (i = 0; i < REMOTE_POOL_MAX; i++) {
if (!pool_info->nodes[i].valid) {
node_info = &pool_info->nodes[i];
break;
}
}
if (!node_info) {
error("remote_pool_add: pool full, consider increasing REMOTE_POOL_MAX");
return -1;
}
return remote_node_init(node_info, hostname, portname);
}
int remote_pool_load (struct remote_pool *pool_info, const char *filename) {
// open the file
FILE *fh = fopen(filename, "r");
if (!fh) {
perr("remote_pool_load: fopen(%s)", filename);
return -1;
}
// read it in line-by-line
char line_buf[POOL_FILE_LINE_LENGTH], *hostname, *portname, *c;
// non-ferror error indicator
int error_flag = 0;
while (1) {
// read in a line
if (!fgets(line_buf, POOL_FILE_LINE_LENGTH, fh)) {
perr("remote_pool_load: fgets");
break;
}
// strip comments
c = strchr(line_buf, '#');
if (c)
*c = '\0';
// skip empty lines
for (c = line_buf; *c != '\0'; c++)
if (!isspace(*c))
break;
if (*c == '\0')
continue;
// parse
if (!parse_hostport(line_buf, &hostname, &portname)) {
error_flag = 1;
break;
}
// add it to the pool
if (remote_pool_add(pool_info, hostname, portname)) {
error_flag = 1;
break;
}
}
// pick up ferrors if otherwise fine
error_flag = error_flag || ferror(fh);
// close the fd
fclose(fh);
// error return?
if (error_flag)
return -1;
return 0;
}
struct remote_node *remote_pool_get (struct remote_pool *pool_info) {
int i;
struct remote_node *node_info = NULL;
// find a the appropriate remote_node entry and store its pointer in node_info
for (i = 0; i < REMOTE_POOL_MAX; i++) {
if (pool_info->nodes[i].valid && (node_info == NULL || pool_info->nodes[i].current_load < node_info->current_load)) {
node_info = &pool_info->nodes[i];
}
}
// either NULL or the right remote_info
return node_info;
}
int remote_pool_size (struct remote_pool *pool_info) {
int i, size = 0;
for (i = 0; i < REMOTE_POOL_MAX; i++) {
if (pool_info->nodes[i].valid) {
size++;
}
}
return size;
}