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