int rmt_tcp_context_connect_addr(tcp_context *tc, const char *addr, int len,
    const struct timeval *timeout, const char *source_addr)
{
    int ret;
    int port;
    sds *ip_port = NULL;
    int ip_port_count = 0;

    ip_port = sdssplitlen(addr, len, IP_PORT_SEPARATOR, 
        rmt_strlen(IP_PORT_SEPARATOR), &ip_port_count);
    if(ip_port == NULL || ip_port_count != 2)
    {
        log_error("Error: ip port parsed error");
        goto error;
    }

    port = rmt_atoi(ip_port[1], sdslen(ip_port[1]));
    if(rmt_valid_port(port) == 0)
    {
        log_error("Error: port is invalid");
        goto error;
    }
    
    ret = rmt_tcp_context_connect(tc, ip_port[0], port, timeout, source_addr);
    if(ret != RMT_OK)
    {
        log_error("Error: can't connect to redis master");
        goto error;
    }

    sdsfreesplitres(ip_port, ip_port_count);
    ip_port = NULL;
    ip_port_count = 0;
    
    return RMT_OK;

error:

    if(ip_port != NULL)
    {
        sdsfreesplitres(ip_port, ip_port_count);
    }
    
    return RMT_ERROR;
}
Exemple #2
0
void emit_command_help (const char *plist, FILE *fp)
{
    int i, count;
    sds *p;
    if (!(p = sdssplitlen (plist, strlen (plist), ":", 1, &count)))
        return;
    for (i = 0; i < count; i++)
        emit_command_help_from_pattern (p[i], fp);
    sdsfreesplitres (p, count);
}
Exemple #3
0
fastonosql::core::unqlite::Config ConvertFromString(const std::string& line) {
  int argc = 0;
  sds* argv = sdssplitargslong(line.c_str(), &argc);
  if (argv) {
    auto cfg = fastonosql::core::unqlite::parseOptions(argc, argv);
    sdsfreesplitres(argv, argc);
    return cfg;
  }

  return fastonosql::core::unqlite::Config();
}
Exemple #4
0
void jsondocvalidateCommand(redisClient *c) {
    /* args 0-1: ["jsondocvalidate", json] */

    sds err = sdsempty();
    struct jsonObj *root = yajl_decode(c->argv[1]->ptr, &err);

    if (!root) {
        int sz;
        sds *error_lines = sdssplitlen(err, sdslen(err), "\n", 1, &sz);
        addReplyMultiBulkLen(c, sz + 1);
        addReply(c, g.err_parse);
        for (int i = 0; i < sz; i++) {
            addReplyBulkCBuffer(c, error_lines[i], sdslen(error_lines[i]));
        }
        sdsfreesplitres(error_lines, sz);
    } else {
        addReply(c, shared.ok);
    }
    sdsfree(err);
}
void InnerServerCommandSeqParser::handleInnerDataReceived(InnerClient* connection,
                                                          char* buff,
                                                          uint32_t buff_len) {
  ssize_t nwrite = 0;
  char* end = strstr(buff, END_OF_COMMAND);
  if (!end) {
    DEBUG_MSG_FORMAT<MAX_COMMAND_SIZE>(common::logging::L_WARNING, "UNKNOWN SEQUENCE: %s", buff);
    const cmd_responce_t resp = make_responce(next_id(), STATE_COMMAND_RESP_FAIL_1S, buff);
    common::Error err = connection->write(resp, &nwrite);
    if (err && err->isError()) {
      DEBUG_MSG_ERROR(err);
    }
    connection->close();
    delete connection;
    return;
  }

  *end = 0;

  char* star_seq = NULL;
  cmd_id_t seq = strtoul(buff, &star_seq, 10);
  if (*star_seq != ' ') {
    DEBUG_MSG_FORMAT<MAX_COMMAND_SIZE>(common::logging::L_WARNING,
                                       "PROBLEM EXTRACTING SEQUENCE: %s", buff);
    const cmd_responce_t resp = make_responce(next_id(), STATE_COMMAND_RESP_FAIL_1S, buff);
    common::Error err = connection->write(resp, &nwrite);
    if (err && err->isError()) {
      DEBUG_MSG_ERROR(err);
    }
    connection->close();
    delete connection;
    return;
  }

  const char* id_ptr = strchr(star_seq + 1, ' ');
  if (!id_ptr) {
    DEBUG_MSG_FORMAT<MAX_COMMAND_SIZE>(common::logging::L_WARNING, "PROBLEM EXTRACTING ID: %s",
                                       buff);
    const cmd_responce_t resp = make_responce(next_id(), STATE_COMMAND_RESP_FAIL_1S, buff);
    common::Error err = connection->write(resp, &nwrite);
    if (err && err->isError()) {
      DEBUG_MSG_ERROR(err);
    }
    connection->close();
    delete connection;
    return;
  }

  size_t len_seq = id_ptr - (star_seq + 1);
  cmd_seq_t id = std::string(star_seq + 1, len_seq);
  const char* cmd = id_ptr;

  int argc;
  sds* argv = sdssplitargs(cmd, &argc);
  processRequest(id, argc, argv);
  if (argv == NULL) {
    DEBUG_MSG_FORMAT<MAX_COMMAND_SIZE>(common::logging::L_WARNING,
                                       "PROBLEM PARSING INNER COMMAND: %s", buff);
    const cmd_responce_t resp = make_responce(id, STATE_COMMAND_RESP_FAIL_1S, buff);
    common::Error err = connection->write(resp, &nwrite);
    if (err && err->isError()) {
      DEBUG_MSG_ERROR(err);
    }
    connection->close();
    delete connection;
    return;
  }

  DEBUG_MSG_FORMAT<MAX_COMMAND_SIZE>(
      common::logging::L_INFO, "HANDLE INNER COMMAND client[%s] seq:% " CID_FMT ", id:%s, cmd: %s",
      connection->formatedName(), seq, id, cmd);
  if (seq == REQUEST_COMMAND) {
    handleInnerRequestCommand(connection, id, argc, argv);
  } else if (seq == RESPONCE_COMMAND) {
    handleInnerResponceCommand(connection, id, argc, argv);
  } else if (seq == APPROVE_COMMAND) {
    handleInnerApproveCommand(connection, id, argc, argv);
  } else {
    NOTREACHED();
  }
  sdsfreesplitres(argv, argc);
}
Exemple #6
0
size_t cetcd_parse_response(char *ptr, size_t size, size_t nmemb, void *userdata) {
    int len, i;
    char *key, *val;
    cetcd_response *resp;
    cetcd_response_parser *parser;
    yajl_status status;

    enum resp_parser_st {
        request_line_start_st,
        request_line_end_st,
        request_line_http_status_start_st,
        request_line_http_status_st,
        request_line_http_status_end_st,
        header_key_start_st,
        header_key_st,
        header_key_end_st,
        header_val_start_st,
        header_val_st,
        header_val_end_st,
        blank_line_st,
        json_start_st,
        json_end_st,
        response_discard_st
    };
    /* Headers we are interested in:
     * X-Etcd-Index: 14695
     * X-Raft-Index: 672930
     * X-Raft-Term: 12
     * */

    parser = userdata;
    resp = parser->resp;
    len = size * nmemb;
    for (i = 0; i < len; ++i) {
        if (parser->st == request_line_start_st) {
            if (ptr[i] == ' ') {
                parser->st = request_line_http_status_start_st;
            }
            continue;
        }
        if (parser->st == request_line_end_st) {
            if (ptr[i] == '\n') {
                parser->st = header_key_start_st;
            }
            continue;
        }
        if (parser->st == request_line_http_status_start_st) {
            parser->buf = sdscatlen(parser->buf, ptr+i, 1);
            parser->st = request_line_http_status_st;
            continue;
        }
        if (parser->st == request_line_http_status_st) {
            if (ptr[i] == ' ') {
                parser->st = request_line_http_status_end_st;
            } else {
                parser->buf = sdscatlen(parser->buf, ptr+i, 1);
                continue;
            }
        }
        if (parser->st == request_line_http_status_end_st) {
            val = parser->buf;
            parser->http_status = atoi(val);
            sdsclear(parser->buf);
            parser->st = request_line_end_st;
            continue;
        }
        if (parser->st == header_key_start_st) {
            if (ptr[i] == '\r') {
                ++i;
            }
            if (ptr[i] == '\n') {
                parser->st = blank_line_st;
                if (parser->http_status >= 300 && parser->http_status < 400) {
                    /*this is a redirection, restart the state machine*/
                    parser->st = request_line_start_st;
                    break;
                }
                continue;
            }
            parser->st = header_key_st;
        }
        if (parser->st == header_key_st) {
            parser->buf = sdscatlen(parser->buf, ptr+i, 1);
            if (ptr[i] == ':') {
                parser->st = header_key_end_st;
            } else {
                continue;
            }
        }
        if (parser->st == header_key_end_st) {
            parser->st = header_val_start_st;
            continue;
        }
        if (parser->st == header_val_start_st) {
            if (ptr[i] == ' ') {
                continue;
            }
            parser->st = header_val_st;
        }
        if (parser->st == header_val_st) {
            if (ptr[i] == '\r') {
                ++i;
            }
            if (ptr[i] == '\n') {
                parser->st = header_val_end_st;
            } else {
                parser->buf = sdscatlen(parser->buf, ptr+i, 1);
                continue;
            }
        }
        if (parser->st == header_val_end_st) {
            parser->st = header_key_start_st;
            int count = 0;
            sds *kvs = sdssplitlen(parser->buf, sdslen(parser->buf), ":", 1, &count);
            sdsclear(parser->buf);
            if (count < 2) {
                sdsfreesplitres(kvs, count);
                continue;
            }
            key = kvs[0];
            val = kvs[1];
            if (strncmp(key, "X-Etcd-Index", sizeof("X-Etcd-Index")-1) == 0) {
                resp->etcd_index = atoi(val);
            } else if (strncmp(key, "X-Raft-Index", sizeof("X-Raft-Index")-1) == 0) {
                resp->raft_index = atoi(val);
            } else if (strncmp(key, "X-Raft-Term", sizeof("X-Raft-Term")-1) == 0) {
                resp->raft_term = atoi(val);
            }
            sdsfreesplitres(kvs, count);
            continue;
        }
        if (parser->st == blank_line_st) {
            if (ptr[i] != '{') {
                /*not a json response, discard*/
                parser->st = response_discard_st;
                if (resp->err == NULL) {
                    resp->err = calloc(1, sizeof(cetcd_error));
                    resp->err->ecode = error_response_parsed_failed;
                    resp->err->message = sdsnew("not a json response");
                    resp->err->cause = sdsnewlen(ptr, len);
                }
                continue;
            }
            parser->st = json_start_st;
            cetcd_array_init(&parser->ctx.keystack, 10);
            cetcd_array_init(&parser->ctx.nodestack, 10);
            if (parser->http_status != 200 && parser->http_status != 201) {
                resp->err = calloc(1, sizeof(cetcd_error));
                parser->ctx.userdata = resp->err;
                parser->json = yajl_alloc(&error_callbacks, 0, &parser->ctx);
            } else {
                parser->ctx.userdata = resp;
                parser->json = yajl_alloc(&callbacks, 0, &parser->ctx);
            }
        }
        if (parser->st == json_start_st) {
            if (yajl_status_ok != yajl_parse(parser->json, (const unsigned char *)ptr + i, len - i)) {
                parser->st = json_end_st;
            } else {
                parser->st = response_discard_st;
                yajl_free(parser->json);
                cetcd_array_destory(&parser->ctx.keystack);
                cetcd_array_destory(&parser->ctx.nodestack);
            }
        }
        if (parser->st == json_end_st) {
            status = yajl_complete_parse(parser->json);
            yajl_free(parser->json);
            cetcd_array_destory(&parser->ctx.keystack);
            cetcd_array_destory(&parser->ctx.nodestack);
            /*parse failed, TODO set error message*/
            if (status != yajl_status_ok) {
                if (resp->err == NULL) {
                    resp->err = calloc(1, sizeof(cetcd_error));
                    resp->err->ecode = error_response_parsed_failed;
                    resp->err->message = sdsnew("http response is invalid json format");
                    resp->err->cause = sdsnewlen(ptr, len);
                }
                return 0;
            }
            break;
        }
        if (parser->st == response_discard_st) {
            return len;
        }
    }
    return len;
}
Exemple #7
0
void load_conf_from_string(char *config)
{
    char *err = NULL;
    int linenum = 0, tlines, i;
    sds *lines;

    lines = sdssplitlen(config, strlen(config), "\n", 1, &tlines);

    for(i = 0; i < tlines; i++)
    {
        sds *argv;
        int argc;

        linenum = i+1;

        log_debug(">> %0.3d %s", linenum,  lines[i]);

        lines[i] = sdstrim(lines[i], " \t\r\n");

        // skip comments and blank lines
        if(lines[i][0] == '#' || lines[i][0] == '\0')
            continue;

        argv = sdssplitargs(lines[i], &argc);
        if(argv == NULL)
        {
            err = "Unbalanced quotes in configuration line";
            goto loaderr;
        }

        if(argc == 0)
        {
            sdsfreesplitres(argv, argc);
            continue;
        }

        sdstolower(argv[0]);

        if(!strcasecmp(argv[0], "name") && argc == 2)
        {
            server.name = sdsdup(argv[1]);
        }else if(!strcasecmp(argv[0], "bind") && argc >= 2)
        {
            server.bind_addr_count = argc-1;

            if((argc-1) > ZR_MAX_BIND_ADDR)
            {
                err = "Too many bind address specified.";
                goto loaderr;
            }
            int j;

            for(j = 0; j < server.bind_addr_count; j++)
            {
                server.bind_arr[j].addr_str = sdsnew(argv[j+1]);
                server.bind_arr[j].addr.sin_family = AF_INET;
                server.bind_arr[j].addr.sin_addr.s_addr = inet_addr(argv[j+1]);
                if(server.bind_arr[j].addr.sin_addr.s_addr == INADDR_NONE)
                {
                    err = sdscatprintf(sdsempty(), "Wrong binding ip address: %s", argv[j+1]);
                    goto loaderr;
                }
            }
        }else if(!strcasecmp(argv[0], "port") && argc == 2)
        {
            server.port = atoi(argv[1]);

            if (server.port < 0 || server.port > 65535)
            {
                err = "Invalid port"; goto loaderr;
            }

        }else if(!strcasecmp(argv[0], "req-log-uds") && argc == 2)
        {
            server.req_log_uds = sdsnew(argv[1]);

        }else if(!strcasecmp(argv[0], "client-max") && argc == 2)
        {
            server.client_max = atoi(argv[1]);
            if(server.client_max < 0)
            {
                err = "Invalid server-connection-max value.";
                goto loaderr;
            }
        } else if (!strcasecmp(argv[0],"tcp-backlog") && argc == 2)
        {
            server.tcp_backlog = atoi(argv[1]);
            if (server.tcp_backlog < 0)
            {
                err = "Invalid backlog value";
                goto loaderr;
            }
/*
        } else if (!strcasecmp(argv[0],"rr-counter-buffer") && argc == 2)
        {
            server.tcp_backlog = atoi(argv[1]);
            if (server.tcp_backlog < 0)
            {
                err = "Invalid rr-counter-buffer value";
                goto loaderr;
            }
*/
        }else if(!strcasecmp(argv[0], "log-level") && argc == 2)
        {
            server.log_level = log_get_level_str(argv[1]);
        }else if(!strcasecmp(argv[0], "log-file") && argc == 2)
        {
            server.log_file = sdsdup(argv[1]);
            if(!strcasecmp(argv[1], "stdout"))
            {
                log_set_out(stdout);
            }else if(!strcasecmp(argv[1], "stderr"))
            {
                log_set_out(stderr);
            }else
            {
                FILE *fd;
                fd = fopen(argv[1], "a");
                if(fd == NULL)
                {
                    err = sdscatprintf(sdsempty(), "Can't open the log file: %s", strerror(errno));
                    goto loaderr;
                }
                
                log_set_out(fd);
            }
        }else if(!strcasecmp(argv[0], "zookeeper-health-uri") && argc == 2)
        {
            struct z_conn_info *zcinfo = z_parse_conn_string(argv[1]);
            if(zcinfo == NULL)
            {
                err = "Invalid zookeeper-health-url(Zookeeper URI) value.\n"
//                      "Zookeeper URI must be as below.\n"
//                      " - zoo://[USER[:PASS]@]HOST_STRING/NODE/PATH\n"
//                      "   ex) zoo://192.168.1.2:2181/test/node\n"
//                      "   ex) zoo://[email protected]:2181,192.168.1.3:2181/test/node\n"
//                      "   ex) zoo://foo:[email protected]:2181,192.168.1.3:2181/test/node\n"
                      "";
                goto loaderr;
            }

            server.z_health_conn = zcinfo;
        }else if(!strcasecmp(argv[0], "zookeeper-timeout") && argc == 2)
        {
            server.zoo_timeout = atoi(argv[1]);
            if(server.zoo_timeout < 0)
            {
                err = "Invalid zookeeper-timeout value";
                goto loaderr;
            }

        }else if(!strcasecmp(argv[0], "service") && argc == 3)
        {
            if(strlen(argv[1]) > ZR_MAX_SVC_NAME)
            {
                err = sdscatprintf(sdsempty(), "Service name is too long, first argument(service name) must be less then %d.", ZR_MAX_SVC_NAME);
                goto loaderr;
            }

            struct z_conn_info *cinfo = z_parse_conn_string(argv[2]);
            if(!cinfo)
            {
                err = "Invalid zookeeper-health-url(Zookeeper URI) value.\n"
//                      "Zookeeper URI must be as below.\n"
//                      " - zoo://[USER[:PASS]@]HOST_STRING/NODE/PATH\n"
//                      "   ex) zoo://192.168.1.2:2181/test/node\n"
//                      "   ex) zoo://[email protected]:2181,192.168.1.3:2181/test/node\n"
//                      "   ex) zoo://foo:[email protected]:2181,192.168.1.3:2181/test/node\n"
                      "";
                goto loaderr;
            }

            int j;
            for(j = 0; j < server.svc_count; j++)
            {
                struct svc *tsvc = server.svc_arr[j];
                if(!sdscmp(argv[1], tsvc->name))
                {
                    err = sdscatprintf(sdsempty(), "\"%s\" service name already exists.", argv[1]);
                    goto loaderr;
                }
            }

            struct svc *svc = svc_alloc(argv[1], strlen(argv[1]), server.svc_count);
            svc->z_conn = cinfo;
            server.svc_arr[server.svc_count] = svc;
            server.svc_count++;
        }else
        {
            err = "Bad config directive or wrong number of arguments";
            goto loaderr;
        }

        sdsfreesplitres(argv,argc);
    }

    sdsfreesplitres(lines,tlines);
    return;

loaderr:
    log_eerr("CONFIG FILE ERROR.");
    log_eerr("Reading configureation file, at line %d", linenum);
    log_eerr(">> '%s'", lines[i]);
    log_eerr("%s", err);
    exit(1);
}
Exemple #8
0
void load_config_from_string(sds config) {
	char *err = NULL;
	int linenum = 0, totlines, i;
	sds *lines = sdssplitlen(config, strlen(config), "\n", 1, &totlines);

	for (i = 0; i < totlines; i++) {
		sds *argv;
		int argc;

		linenum = i + 1;
		lines[i] = sdstrim(lines[i], " \t\r\n");

		if (lines[i][0] == '#' || lines[i][0] == '\0')
			continue;

		argv = sdssplitargs(lines[i], &argc);
		if (argv == NULL) {
			err = "Unbalanced quotes in configuration line";
			goto loaderr;
		}

		if (argc == 0) {
			sdsfreesplitres(argv, argc);
			continue;
		}
		sdstolower(argv[0]);

		if (strcasecmp(argv[0], "working-directory") == 0 && argc == 2) {
			destor.working_directory = sdscpy(destor.working_directory,
					argv[1]);
		} else if (strcasecmp(argv[0], "simulation-level") == 0 && argc == 2) {
			if (strcasecmp(argv[1], "all") == 0) {
				destor.simulation_level = SIMULATION_ALL;
			} else if (strcasecmp(argv[1], "append") == 0) {
				destor.simulation_level = SIMULATION_APPEND;
			} else if (strcasecmp(argv[1], "restore") == 0) {
				destor.simulation_level = SIMULATION_RESTORE;
			} else if (strcasecmp(argv[1], "no") == 0) {
				destor.simulation_level = SIMULATION_NO;
			} else {
				err = "Invalid simulation level";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "log-level") == 0 && argc == 2) {
			if (strcasecmp(argv[1], "debug") == 0) {
				destor.verbosity = DESTOR_DEBUG;
			} else if (strcasecmp(argv[1], "verbose") == 0) {
				destor.verbosity = DESTOR_VERBOSE;
			} else if (strcasecmp(argv[1], "notice") == 0) {
				destor.verbosity = DESTOR_NOTICE;
			} else if (strcasecmp(argv[1], "warning") == 0) {
				destor.verbosity = DESTOR_WARNING;
			} else {
				err = "Invalid log level";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "chunk-algorithm") == 0 && argc == 2) {
			if (strcasecmp(argv[1], "fixed") == 0) {
				destor.chunk_algorithm = CHUNK_FIXED;
			} else if (strcasecmp(argv[1], "rabin") == 0) {
				destor.chunk_algorithm = CHUNK_RABIN;
			} else if (strcasecmp(argv[1], "normalized rabin") == 0) {
				destor.chunk_algorithm = CHUNK_NORMALIZED_RABIN;
			} else if (strcasecmp(argv[1], "file") == 0) {
				destor.chunk_algorithm = CHUNK_FILE;
			} else {
				err = "Invalid chunk algorithm";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "chunk-avg-size") == 0 && argc == 2) {
			destor.chunk_avg_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "chunk-max-size") == 0 && argc == 2) {
			destor.chunk_max_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "chunk-min-size") == 0 && argc == 2) {
			destor.chunk_min_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "fingerprint-index") == 0 && argc >= 3) {
			if (strcasecmp(argv[1], "exact") == 0) {
				destor.index_category[0] = INDEX_CATEGORY_EXACT;
			} else if (strcasecmp(argv[1], "near-exact") == 0) {
				destor.index_category[0] = INDEX_CATEGORY_NEAR_EXACT;
			} else {
				err = "Invalid index category";
				goto loaderr;
			}

			if (strcasecmp(argv[2], "physical") == 0) {
				destor.index_category[1] = INDEX_CATEGORY_PHYSICAL_LOCALITY;
			} else if (strcasecmp(argv[2], "logical") == 0) {
				destor.index_category[1] = INDEX_CATEGORY_LOGICAL_LOCALITY;
			} else {
				err = "Invalid index category";
				goto loaderr;
			}

			if (argc > 3) {
				if (strcasecmp(argv[3], "ddfs") == 0) {
					assert(destor.index_category[0] == INDEX_CATEGORY_EXACT 
                            && destor.index_category[1] == INDEX_CATEGORY_PHYSICAL_LOCALITY);
					destor.index_specific = INDEX_SPECIFIC_DDFS;
				} else if (strcasecmp(argv[3], "sampled index") == 0) {
					assert(destor.index_category[0] == INDEX_CATEGORY_NEAR_EXACT 
                            && destor.index_category[1] == INDEX_CATEGORY_PHYSICAL_LOCALITY);
					destor.index_specific = INDEX_SPECIFIC_SAMPLED;
				} else if (strcasecmp(argv[3], "block locality caching") == 0) {
					assert(destor.index_category[0] == INDEX_CATEGORY_EXACT 
                            && destor.index_category[1] == INDEX_CATEGORY_LOGICAL_LOCALITY);
					destor.index_specific =	INDEX_SPECIFIC_BLOCK_LOCALITY_CACHING;
				} else if (strcasecmp(argv[3], "extreme binning") == 0) {
					assert(destor.index_category[0] == INDEX_CATEGORY_NEAR_EXACT 
                            && destor.index_category[1] == INDEX_CATEGORY_LOGICAL_LOCALITY);
					destor.index_specific = INDEX_SPECIFIC_EXTREME_BINNING;
				} else if (strcasecmp(argv[3], "sparse index") == 0) {
					assert(destor.index_category[0] == INDEX_CATEGORY_NEAR_EXACT 
                            && destor.index_category[1] == INDEX_CATEGORY_LOGICAL_LOCALITY);
					destor.index_specific = INDEX_SPECIFIC_SPARSE;
				} else if (strcasecmp(argv[3], "silo") == 0) {
					assert(destor.index_category[0] == INDEX_CATEGORY_NEAR_EXACT 
                            && destor.index_category[1] == INDEX_CATEGORY_LOGICAL_LOCALITY);
					destor.index_specific = INDEX_SPECIFIC_SILO;
				} else {
					err = "Invalid index specific";
					goto loaderr;
				}
			}
		} else if (strcasecmp(argv[0], "fingerprint-index-cache-size")
				== 0 && argc == 2) {
			destor.index_cache_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "fingerprint-index-key-value") == 0
				&& argc == 2) {
			if (strcasecmp(argv[1], "htable") == 0) {
				destor.index_key_value_store = INDEX_KEY_VALUE_HTABLE;
			} else {
				err = "Invalid key-value store";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "fingerprint-index-key-size") == 0
				&& argc == 2) {
			destor.index_key_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "fingerprint-index-value-length") == 0
				&& argc == 2) {
			destor.index_value_length = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "fingerprint-index-bloom-filter") == 0
				&& argc == 2) {
			destor.index_bloom_filter_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "fingerprint-index-sampling-method") == 0
				&& argc >= 2) {
			if (strcasecmp(argv[1], "optmin") == 0)
				destor.index_sampling_method[0] = INDEX_SAMPLING_OPTIMIZED_MIN;
			else if (strcasecmp(argv[1], "random") == 0)
				destor.index_sampling_method[0] = INDEX_SAMPLING_RANDOM;
			else if (strcasecmp(argv[1], "min") == 0)
				destor.index_sampling_method[0] = INDEX_SAMPLING_MIN;
			else if (strcasecmp(argv[1], "uniform") == 0)
				destor.index_sampling_method[0] = INDEX_SAMPLING_UNIFORM;
			else {
				err = "Invalid feature method!";
				goto loaderr;
			}

			if (argc > 2) {
				destor.index_sampling_method[1] = atoi(argv[2]);
			} else {
				destor.index_sampling_method[1] = 0;
			}
		} else if (strcasecmp(argv[0], "fingerprint-index-segment-algorithm")
				== 0 && argc >= 2) {
			if (strcasecmp(argv[1], "fixed") == 0)
				destor.index_segment_algorithm[0] = INDEX_SEGMENT_FIXED;
			else if (strcasecmp(argv[1], "file-defined") == 0)
				destor.index_segment_algorithm[0] = INDEX_SEGMENT_FILE_DEFINED;
			else if (strcasecmp(argv[1], "content-defined") == 0)
				destor.index_segment_algorithm[0] =	INDEX_SEGMENT_CONTENT_DEFINED;
			else {
				err = "Invalid segment algorithm";
				goto loaderr;
			}

			if (argc > 2) {
				assert(destor.index_segment_algorithm[0] != INDEX_SEGMENT_FILE_DEFINED);
				destor.index_segment_algorithm[1] = atoi(argv[2]);
			}
		} else if (strcasecmp(argv[0], "fingerprint-index-segment-boundary") == 0
				&& argc == 3) {
			destor.index_segment_min = atoi(argv[1]);
			destor.index_segment_max = atoi(argv[2]);
		} else if (strcasecmp(argv[0], "fingerprint-index-segment-selection")
				== 0 && argc >= 2) {
			destor.index_segment_selection_method[1] = 1;
			if (strcasecmp(argv[1], "base") == 0)
				destor.index_segment_selection_method[0] = INDEX_SEGMENT_SELECT_BASE;
			else if (strcasecmp(argv[1], "top") == 0) {
				destor.index_segment_selection_method[0] = INDEX_SEGMENT_SELECT_TOP;
				if (argc > 2)
					destor.index_segment_selection_method[1] = atoi(argv[2]);
			} else if (strcasecmp(argv[1], "mix") == 0)
				destor.index_segment_selection_method[0] = INDEX_SEGMENT_SELECT_MIX;
			else {
				err = "Invalid selection method!";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "fingerprint-index-segment-prefetching")	== 0 && argc == 2) {
			destor.index_segment_prefech = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-algorithm") == 0 && argc >= 2) {
			if (strcasecmp(argv[1], "no") == 0)
				destor.rewrite_algorithm[0] = REWRITE_NO;
			else if (strcasecmp(argv[1], "cfl-based selective deduplication")
					== 0 || strcasecmp(argv[1], "cfl") == 0)
				destor.rewrite_algorithm[0] =
				REWRITE_CFL_SELECTIVE_DEDUPLICATION;
			else if (strcasecmp(argv[1], "context-based rewriting") == 0
					|| strcasecmp(argv[1], "cbr") == 0)
				destor.rewrite_algorithm[0] = REWRITE_CONTEXT_BASED;
			else if (strcasecmp(argv[1], "capping") == 0
					|| strcasecmp(argv[1], "cap") == 0)
				destor.rewrite_algorithm[0] = REWRITE_CAPPING;
			else {
				err = "Invalid rewriting algorithm";
				goto loaderr;
			}

			if (argc > 2) {
				assert(destor.rewrite_algorithm != REWRITE_NO);
				destor.rewrite_algorithm[1] = atoi(argv[2]);
			} else {
				destor.rewrite_algorithm[1] = 1024;
			}
		} else if (strcasecmp(argv[0], "rewrite-enable-cfl-switch") == 0
				&& argc == 2) {
			destor.rewrite_enable_cfl_switch = yesnotoi(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-cfl-require") == 0
				&& argc == 2) {
			destor.rewrite_cfl_require = atof(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-cfl-usage-threshold") == 0
				&& argc == 2) {
			destor.rewrite_cfl_usage_threshold = atof(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-cbr-limit") == 0 && argc == 2) {
			destor.rewrite_cbr_limit = atof(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-cbr-minimal-utility") == 0
				&& argc == 2) {
			destor.rewrite_cbr_minimal_utility = atof(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-capping-level") == 0
				&& argc == 2) {
			destor.rewrite_capping_level = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-enable-har") == 0
				&& argc == 2) {
			destor.rewrite_enable_har = yesnotoi(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-har-utilization-threshold") == 0
				&& argc == 2) {
			destor.rewrite_har_utilization_threshold = atof(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-har-rewrite-limit") == 0
				&& argc == 2) {
			destor.rewrite_har_rewrite_limit = atof(argv[1]);
		} else if (strcasecmp(argv[0], "rewrite-enable-cache-aware") == 0
				&& argc == 2) {
			destor.rewrite_enable_cache_aware = yesnotoi(argv[1]);
		} else if (strcasecmp(argv[0], "restore-cache") == 0 && argc == 3) {
			if (strcasecmp(argv[1], "lru") == 0)
				destor.restore_cache[0] = RESTORE_CACHE_LRU;
			else if (strcasecmp(argv[1], "optimal cache") == 0
					|| strcasecmp(argv[1], "opt") == 0)
				destor.restore_cache[0] = RESTORE_CACHE_OPT;
			else if (strcasecmp(argv[1], "forward assembly") == 0
					|| strcasecmp(argv[1], "asm") == 0)
				destor.restore_cache[0] = RESTORE_CACHE_ASM;
			else {
				err = "Invalid restore cache";
				goto loaderr;
			}

			destor.restore_cache[1] = atoi(argv[2]);
		} else if (strcasecmp(argv[0], "restore-opt-window-size") == 0
				&& argc == 2) {
			destor.restore_opt_window_size = atoi(argv[1]);
		} else if (strcasecmp(argv[0], "backup-retention-time") == 0
				&& argc == 2) {
			destor.backup_retention_time = atoi(argv[1]);
		} else {
			err = "Bad directive or wrong number of arguments";
			goto loaderr;
		}
		sdsfreesplitres(argv, argc);
	}
	sdsfreesplitres(lines, totlines);
	return;

	loaderr: fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR in destor ***\n");
	fprintf(stderr, "Reading the configuration file, at line %d\n", linenum);
	fprintf(stderr, ">>> '%s'\n", lines[i]);
	fprintf(stderr, "%s\n", err);
	exit(1);
}
/* ----------------- */
static sds
get_bitmap_from_argv (int argc, robj ** argv)
{
  sds bitmap;
  int i;

  bitmap = sdsgrowzero (sdsempty (), ARC_KS_SIZE);

  for (i = 0; i < argc; i++)
    {
      int ok, n, j;
      long long ll, from, to;
      sds *tokens;
      sds from_to = (sds) argv[i]->ptr;

      /* There are two kinds of argument type.
       * 1. <slotNo>                     ex) 1024
       * 2. <slotNo from>-<slotNo to>    ex) 0-2047 */
      tokens = sdssplitlen (from_to, sdslen (from_to), "-", 1, &n);
      if (tokens == NULL)
	{
	  return NULL;
	}

      if (n == 1)
	{
	  /* Type 1 <slotNo> */
	  ok = string2ll (tokens[0], sdslen (tokens[0]), &ll);
	  if (!ok)
	    {
	      sdsfreesplitres (tokens, n);
	      return NULL;
	    }
	  from = ll;
	  to = ll;
	}
      else if (n == 2)
	{
	  /* Type 2 <slotNo from>-<slotNo to> */
	  ok = string2ll (tokens[0], sdslen (tokens[0]), &ll);
	  if (!ok)
	    {
	      sdsfreesplitres (tokens, n);
	      return NULL;
	    }
	  from = ll;

	  ok = string2ll (tokens[1], sdslen (tokens[1]), &ll);
	  if (!ok)
	    {
	      sdsfreesplitres (tokens, n);
	      return NULL;
	    }
	  to = ll;
	}
      else
	{
	  /* not belong to Type 1 or Type 2 */
	  sdsfreesplitres (tokens, n);
	  return NULL;
	}

      sdsfreesplitres (tokens, n);

      /* range check */
      if (from < 0 || to >= ARC_KS_SIZE || from > to)
	{
	  return NULL;
	}

      /* set bit */
      for (j = from; j <= to; j++)
	{
	  bitmapSetBit ((unsigned char *) bitmap, j);
	}
    }
  return bitmap;
}
Exemple #10
0
void load_config_from_string(sds config) {
	char *err = NULL;
	int linenum = 0, totlines, i;
	sds *lines = sdssplitlen(config, strlen(config), "\n", 1, &totlines);

	for (i = 0; i < totlines; i++) {
		sds *argv;
		int argc;

		linenum = i + 1;
		lines[i] = sdstrim(lines[i], " \t\r\n");

		if (lines[i][0] == '#' || lines[i][0] == '\0')
			continue;

		argv = sdssplitargs(lines[i], &argc);
		if (argv == NULL) {
			err = "Unbalanced quotes in configuration line";
			goto loaderr;
		}

		if (argc == 0) {
			sdsfreesplitres(argv, argc);
			continue;
		}
		sdstolower(argv[0]);

		if (strcasecmp(argv[0], "working-directory") == 0 && argc == 2) {
			destor.working_directory = sdscpy(destor.working_directory,
					argv[1]);
		} else if (strcasecmp(argv[0], "simulation-level") == 0 && argc == 2) {
			if (strcasecmp(argv[1], "all") == 0) {
				destor.simulation_level = SIMULATION_ALL;
			} else if (strcasecmp(argv[1], "append") == 0) {
				destor.simulation_level = SIMULATION_APPEND;
			} else if (strcasecmp(argv[1], "restore") == 0) {
				destor.simulation_level = SIMULATION_RESTORE;
			} else if (strcasecmp(argv[1], "no") == 0) {
				destor.simulation_level = SIMULATION_NO;
			} else {
				err = "Invalid simulation level";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "log-level") == 0 && argc == 2) {
			if (strcasecmp(argv[1], "debug") == 0) {
				destor.verbosity = DESTOR_DEBUG;
			} else if (strcasecmp(argv[1], "verbose") == 0) {
				destor.verbosity = DESTOR_VERBOSE;
			} else if (strcasecmp(argv[1], "notice") == 0) {
				destor.verbosity = DESTOR_NOTICE;
			} else if (strcasecmp(argv[1], "warning") == 0) {
				destor.verbosity = DESTOR_WARNING;
			} else {
				err = "Invalid log level";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "chunk-algorithm") == 0 && argc == 2) {
			if (strcasecmp(argv[1], "fixed") == 0) {
				destor.chunk_algorithm = CHUNK_FIXED;
			} else if (strcasecmp(argv[1], "rabin") == 0) {
				destor.chunk_algorithm = CHUNK_RABIN;
			} else if (strcasecmp(argv[1], "normalized rabin") == 0) {
				destor.chunk_algorithm = CHUNK_NORMALIZED_RABIN;
			} else {
				err = "Invalid chunk algorithm";
				goto loaderr;
			}
		} else if (strcasecmp(argv[0], "chunk-avg-size") == 0 && argc == 2) {
			destor.chunk_avg_size = atoi(argv[1]);
			int pwr;
			for (pwr = 0; destor.chunk_avg_size; pwr++) {
				destor.chunk_avg_size >>= 1;
			}
			destor.chunk_avg_size = 1 << (pwr - 1);
		} else if (strcasecmp(argv[0], "chunk-max-size") == 0 && argc == 2) {
static int
conf_pre_validate(rmt_conf *cf)
{
    int ret;
    FILE *fh;
    char line[256];
    dict *organization = NULL;
    sds str = NULL;
    sds org_name = NULL;
    sds *key_value = NULL;
    int key_value_count = 0;
    sds key = NULL;
    conf_value *cv = NULL, **cv_sub;

    if (cf == NULL) {
        return RMT_ERROR;
    }

    fh = cf->fh;
    if (fh == NULL) {
        return RMT_ERROR;
    }

    while (!feof(fh)) {
        if (fgets(line,256,fh) == NULL) {
            if(feof(fh)) break;
            
            log_error("ERROR: Read a line from conf file %s failed: %s", 
                cf->fname, strerror(errno));
            goto error;
        }

        if(str != NULL){
            sdsfree(str);
            str = NULL;
        }

        if(key_value!= NULL){
            sdsfreesplitres(key_value, key_value_count);
            key_value = NULL;
            key_value_count = 0;
        }
        
        ASSERT(str == NULL);
        str = sdsnew(line);
        if(str == NULL){
            log_error("ERROR: Out of memory");
            goto error;
        }

        sdstrim(str, " \n");
        if(strchr(str, '#') != NULL){
            if(str[0] == '#'){
                log_debug(LOG_VVERB, "This line is comment");
                sdsfree(str);
                str = NULL;
                continue;
            }

            sds *content_comment = NULL;
            int content_comment_count = 0;

            content_comment = sdssplitlenonce(str, sdslen(str), 
                "#", 1, &content_comment_count);
            if(content_comment == NULL || content_comment_count != 2){
                log_error("ERROR: Split content and comment error.");
                goto error;
            }

            sdsfree(str);
            str = content_comment[0];
            content_comment[0] = NULL;
            sdsfreesplitres(content_comment, content_comment_count);
        }
        
        log_debug(LOG_VVERB, "%s", str);

        if(sdslen(str) == 0){
            log_debug(LOG_VVERB, "This line is space");
            sdsfree(str);
            str = NULL;
            continue;
        }else if(*str == '['){
            if(sdslen(str) <= 2 || *(str+sdslen(str)-1) != ']') {
                log_error("ERROR: Organization name %s in conf file %s error",
                    str, cf->fname);
                goto error;
            }

            if(key != NULL || cv != NULL){
                ret = conf_key_value_insert(organization, key, cv);
                if(ret != RMT_OK){
                    log_error("ERROR: Key value insert into organization failed");
                    goto error;
                }
                organization = NULL;
                key = NULL;
                cv = NULL;
            }

            ASSERT(org_name == NULL);
            sdsrange(str,1,-2);
            org_name = sdstrim(str, " ");
            str = NULL;

            if(sdslen(org_name) == 0){
                log_error("ERROR: Organization name %s in conf file %s error",
                    str, cf->fname);
                goto error;
            }

            organization = dictCreate(&KeyValueDictType, NULL);
            if(organization == NULL){
                log_error("ERROR: Create dict organization %s failed", 
                    org_name);
                goto error;
            }

            ret = dictAdd(cf->organizations, org_name, organization);
            if(ret != DICT_OK){
                log_error("ERROR: Organization %s in conf file is duplicate", 
                    org_name);
                goto error;
            }
            org_name = NULL;
        }else if(*str == '-'){
            
            if(cv == NULL || cv->type != CONF_VALUE_ARRAY){
                log_error("ERROR: Array %s in conf file %s has wrong conf value",
                    str, cf->fname);
                goto error;
            }

            sdsrange(str,1,-1);
            sdstrim(str, " ");
            
            cv_sub = array_push(cv->value);
            *cv_sub = conf_value_create(CONF_VALUE_STRING);
            if(*cv_sub == NULL){
                log_error("ERROR: Conf value create failed");
                goto error;
            }
            
            (*cv_sub)->value = str;
            str = NULL;
        }else{        
            key_value = sdssplitlenonce(str,sdslen(str),":",1,&key_value_count);
            log_debug(LOG_VVERB, "key_value_count: %d", key_value_count);
            if(key_value == NULL || key_value_count == 0){
                log_error("ERROR: line %s split by : failed", str);
                goto error;
            }else if(key_value_count == 1){
                log_error("ERROR: Line %s in conf file %s has no :", 
                    str, cf->fname);
                goto error;
            }else if(key_value_count == 2){           

                if(key != NULL || cv != NULL){
                    ret = conf_key_value_insert(organization, key, cv);
                    if(ret != RMT_OK){
                        log_error("ERROR: Key value insert into organization failed");
                        goto error;
                    }
                    key = NULL;
                    cv = NULL;
                }

                sdstrim(key_value[0]," ");
                sdstrim(key_value[1]," ");
                
                if(sdslen(key_value[1]) == 0){
                    ASSERT(cv == NULL);
                    cv = conf_value_create(CONF_VALUE_ARRAY);
                    if(cv == NULL){
                        log_error("ERROR: Conf value create failed");
                        goto error;
                    }

                    ASSERT(key == NULL);
                    key = key_value[0];
                    key_value[0] = NULL;
                    
                    continue;
                }

                ASSERT(cv == NULL);
                cv = conf_value_create(CONF_VALUE_STRING);
                if(cv == NULL){
                    log_error("ERROR: Conf value create failed");
                    goto error;
                }

                cv->value = key_value[1];
                key_value[1] = NULL;

                if(organization == NULL){
                    log_error("ERROR: line %s in conf file %s has no organization", 
                        str, cf->fname);
                    goto error;
                }
                ret = dictAdd(organization,key_value[0],cv);
                if(ret != DICT_OK){
                    log_error("ERROR: Key %s in organization of conf file is duplicate", 
                        key_value[0]);
                    goto error;
                }
                key_value[0] = NULL;
                cv = NULL;     
            }else{
                NOT_REACHED();
            }
        }
        
    }

    if(key != NULL || cv != NULL){
        ret = conf_key_value_insert(organization, key, cv);
        if(ret != RMT_OK){
            log_error("ERROR: Key value insert into organization failed");
            goto error;
        }
        key = NULL;
        cv = NULL;
    }

    if(str != NULL){
        sdsfree(str);
        str = NULL;
    }

    if(key_value!= NULL){
        sdsfreesplitres(key_value, key_value_count);
        key_value = NULL;
        key_value_count = 0;
    }

    return RMT_OK;

error:

    if(str != NULL){
        sdsfree(str);
    }

    if(key != NULL){
        sdsfree(key);
    }

    if(org_name != NULL){
        sdsfree(org_name);
    }

    if(key_value != NULL){
        sdsfreesplitres(key_value, key_value_count);
    }

    if(cv != NULL){
        conf_value_destroy(cv);
    }

    return RMT_ERROR;
}
Exemple #12
0
static void repl() {
    sds historyfile = NULL;
    int history = 0;
    char *line;
    int argc;
    sds *argv;

    config.interactive = 1;
    linenoiseSetCompletionCallback(completionCallback);

    /* Only use history when stdin is a tty. */
    if (isatty(fileno(stdin))) {
        history = 1;

        if (getenv("HOME") != NULL) {
            historyfile = sdscatprintf(sdsempty(),"%s/.rediscli_history",getenv("HOME"));
            linenoiseHistoryLoad(historyfile);
        }
    }

    cliRefreshPrompt();
    while((line = linenoise(context ? config.prompt : "not connected> ")) != NULL) {
        if (line[0] != '\0') {
            argv = sdssplitargs(line,&argc);
            if (history) linenoiseHistoryAdd(line);
            if (historyfile) linenoiseHistorySave(historyfile);

            if (argv == NULL) {
                printf("Invalid argument(s)\n");
                free(line);
                continue;
            } else if (argc > 0) {
                if (strcasecmp(argv[0],"quit") == 0 ||
                    strcasecmp(argv[0],"exit") == 0)
                {
                    exit(0);
                } else if (argc == 3 && !strcasecmp(argv[0],"connect")) {
                    sdsfree(config.hostip);
                    config.hostip = sdsnew(argv[1]);
                    config.hostport = atoi(argv[2]);
                    cliRefreshPrompt();
                    cliConnect(1);
                } else if (argc == 1 && !strcasecmp(argv[0],"clear")) {
                    linenoiseClearScreen();
                } else {
                    long long start_time = mstime(), elapsed;
                    int repeat, skipargs = 0;

                    repeat = atoi(argv[0]);
                    if (argc > 1 && repeat) {
                        skipargs = 1;
                    } else {
                        repeat = 1;
                    }

                    while (1) {
                        config.cluster_reissue_command = 0;
                        if (cliSendCommand(argc-skipargs,argv+skipargs,repeat)
                            != REDIS_OK)
                        {
                            cliConnect(1);

                            /* If we still cannot send the command print error.
                             * We'll try to reconnect the next time. */
                            if (cliSendCommand(argc-skipargs,argv+skipargs,repeat)
                                != REDIS_OK)
                                cliPrintContextError();
                        }
                        /* Issue the command again if we got redirected in cluster mode */
                        if (config.cluster_mode && config.cluster_reissue_command) {
                            cliConnect(1);
                        } else {
                            break;
                        }
                    }
                    elapsed = mstime()-start_time;
                    if (elapsed >= 500) {
                        printf("(%.2fs)\n",(double)elapsed/1000);
                    }
                }
            }
            /* Free the argument vector */
            sdsfreesplitres(argv,argc);
        }
        /* linenoise() returns malloc-ed lines like readline() */
        free(line);
    }
    exit(0);
}
Exemple #13
0
static int
initFromConfigBuffer (sds config, conf_t * conf)
{
  char *err = NULL;
  int linenum = 0, totlines, i;
  sds *lines;

  lines = sdssplitlen (config, sdslen (config), "\n", 1, &totlines);

  for (i = 0; i < totlines; i++)
    {
      sds *argv;
      int argc;

      linenum = i + 1;
      lines[i] = sdstrim (lines[i], " \t\r\n");

      /* Skip comments and blank lines */
      if (lines[i][0] == '#' || lines[i][0] == '\0')
	continue;

      /* Split into arguments */
      argv = sdssplitargs (lines[i], &argc);
      if (argv == NULL)
	{
	  err = "Unbalanced quotes in configuration line";
	  goto err;
	}

      /* Skip this line if the resulting command vector is empty. */
      if (argc == 0)
	{
	  sdsfreesplitres (argv, argc);
	  continue;
	}
      sdstolower (argv[0]);

      if (!strcasecmp (argv[0], "zookeeper") && argc == 2)
	{
	  conf->zk_addr = strdup (argv[1]);
	}
      else if (!strcasecmp (argv[0], "cluster_name") && argc == 2)
	{
	  conf->cluster_name = strdup (argv[1]);
	}
      else if (!strcasecmp (argv[0], "port") && argc == 2)
	{
	  conf->port = atoi (argv[1]);
	  if (conf->port < 0 || conf->port > 65535)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid port";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "daemonize") && argc == 2)
	{
	  if (!strcasecmp (argv[1], "yes"))
	    {
	      conf->daemonize = 1;
	    }
	  else if (!strcasecmp (argv[1], "no"))
	    {
	      conf->daemonize = 0;
	    }
	  else
	    {
	      sdsfreesplitres (argv, argc);
	      err = "argument must be 'yes' or 'no'";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "num_conn_per_gw") && argc == 2)
	{
	  conf->capi_conf.num_conn_per_gw = atoi (argv[1]);
	  if (conf->capi_conf.num_conn_per_gw < 1
	      || conf->capi_conf.num_conn_per_gw > 32)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid num_conn_per_gw value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "init_timeout_millis") && argc == 2)
	{
	  conf->capi_conf.init_timeout_millis = atoi (argv[1]);
	  if (conf->capi_conf.init_timeout_millis < 3000
	      || conf->capi_conf.init_timeout_millis > 600000)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid init_timeout_millis value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "log_level") && argc == 2)
	{
	  if (!strcasecmp (argv[1], "NOLOG"))
	    {
	      conf->capi_conf.log_level = ARC_LOG_LEVEL_NOLOG;
	    }
	  else if (!strcasecmp (argv[1], "ERROR"))
	    {
	      conf->capi_conf.log_level = ARC_LOG_LEVEL_ERROR;
	    }
	  else if (!strcasecmp (argv[1], "WARN"))
	    {
	      conf->capi_conf.log_level = ARC_LOG_LEVEL_WARN;
	    }
	  else if (!strcasecmp (argv[1], "INFO"))
	    {
	      conf->capi_conf.log_level = ARC_LOG_LEVEL_INFO;
	    }
	  else if (!strcasecmp (argv[1], "DEBUG"))
	    {
	      conf->capi_conf.log_level = ARC_LOG_LEVEL_DEBUG;
	    }
	  else
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid log_level value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "log_file_prefix") && argc == 2)
	{
	  if (argv[1][0] != '\0')
	    {
	      conf->capi_conf.log_file_prefix = strdup (argv[1]);
	    }
	}
      else if (!strcasecmp (argv[0], "max_fd") && argc == 2)
	{
	  conf->capi_conf.max_fd = atoi (argv[1]);
	  if (conf->capi_conf.max_fd < 1024 || conf->capi_conf.max_fd > 16000)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid max_fd value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "conn_reconnect_millis") && argc == 2)
	{
	  conf->capi_conf.conn_reconnect_millis = atoi (argv[1]);
	  if (conf->capi_conf.conn_reconnect_millis < 100
	      || conf->capi_conf.conn_reconnect_millis > 600000)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid conn_reconnect_millis value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "zk_reconnect_millis") && argc == 2)
	{
	  conf->capi_conf.zk_reconnect_millis = atoi (argv[1]);
	  if (conf->capi_conf.zk_reconnect_millis < 100
	      || conf->capi_conf.zk_reconnect_millis > 600000)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid zk_reconnect_millis value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "zk_session_timeout_millis")
	       && argc == 2)
	{
	  conf->capi_conf.zk_session_timeout_millis = atoi (argv[1]);
	  if (conf->capi_conf.zk_session_timeout_millis < 1000
	      || conf->capi_conf.zk_session_timeout_millis > 600000)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid zk_session_timeout_millis value";
	      goto err;
	    }
	}
      else if (!strcasecmp (argv[0], "local_proxy_query_timeout_millis")
	       && argc == 2)
	{
	  conf->query_timeout_millis = atoi (argv[1]);
	  if (conf->query_timeout_millis < 1000
	      || conf->query_timeout_millis > 600000)
	    {
	      sdsfreesplitres (argv, argc);
	      err = "Invalid local_proxy_query_timeout_millis";
	      goto err;
	    }
	}
      else
	{
	  sdsfreesplitres (argv, argc);
	  err = "Bad directive or wrong number of arguments";
	  goto err;
	}
      sdsfreesplitres (argv, argc);
    }
  sdsfreesplitres (lines, totlines);
  return 0;

err:
  fprintf (stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
  fprintf (stderr, "Reading the configuration file, at line %d\n", linenum);
  fprintf (stderr, ">>> '%s'\n", lines[i]);
  fprintf (stderr, "%s\n", err);
  sdsfreesplitres (lines, totlines);
  return -1;
}