in zookeeper-client/zookeeper-client-c/src/cli.c [333:716]
void processline(const char *line) {
int rc;
int async = ((line[0] == 'a') && !(startsWith(line, "addauth ")));
if (async) {
line++;
}
if (startsWith(line, "help")) {
fprintf(stderr, " create [+[e|s|c|t=ttl]] <path>\n");
fprintf(stderr, " create2 [+[e|s|c|t=ttl]] <path>\n");
fprintf(stderr, " delete <path>\n");
fprintf(stderr, " set <path> <data>\n");
fprintf(stderr, " get <path>\n");
fprintf(stderr, " ls <path>\n");
fprintf(stderr, " ls2 <path>\n");
fprintf(stderr, " sync <path>\n");
fprintf(stderr, " exists <path>\n");
fprintf(stderr, " wexists <path>\n");
fprintf(stderr, " myid\n");
fprintf(stderr, " verbose\n");
fprintf(stderr, " addauth <id> <scheme>\n");
fprintf(stderr, " config\n");
fprintf(stderr, " reconfig [-file <path> | -members <serverId=host:port1:port2;port3>,... | "
" -add <serverId=host:port1:port2;port3>,... | -remove <serverId>,...] [-version <version>]\n");
fprintf(stderr, " quit\n");
fprintf(stderr, "\n");
fprintf(stderr, " prefix the command with the character 'a' to run the command asynchronously.\n");
fprintf(stderr, " run the 'verbose' command to toggle verbose logging.\n");
fprintf(stderr, " i.e. 'aget /foo' to get /foo asynchronously\n");
} else if (startsWith(line, "verbose")) {
if (verbose) {
verbose = 0;
zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
fprintf(stderr, "logging level set to WARN\n");
} else {
verbose = 1;
zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
fprintf(stderr, "logging level set to DEBUG\n");
}
} else if (startsWith(line, "get ")) {
line += 4;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
rc = zoo_aget(zh, line, 1, my_data_completion, strdup(line));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (strcmp(line, "config") == 0) {
gettimeofday(&startTime, 0);
rc = zoo_agetconfig(zh, 1, my_data_completion, strdup(ZOO_CONFIG_NODE));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "reconfig ")) {
int syntaxError = 0;
char* p = NULL;
char* joining = NULL;
char* leaving = NULL;
char* members = NULL;
size_t members_size = 0;
int mode = 0; // 0 = not set, 1 = incremental, 2 = non-incremental
int64_t version = -1;
line += 9;
p = strtok (strdup(line)," ");
while (p != NULL) {
if (strcmp(p, "-add")==0) {
p = strtok (NULL," ");
if (mode == 2 || p == NULL) {
syntaxError = 1;
break;
}
mode = 1;
joining = strdup(p);
} else if (strcmp(p, "-remove")==0){
p = strtok (NULL," ");
if (mode == 2 || p == NULL) {
syntaxError = 1;
break;
}
mode = 1;
leaving = strdup(p);
} else if (strcmp(p, "-members")==0) {
p = strtok (NULL," ");
if (mode == 1 || p == NULL) {
syntaxError = 1;
break;
}
mode = 2;
members = strdup(p);
} else if (strcmp(p, "-file")==0){
FILE *fp = NULL;
p = strtok (NULL," ");
if (mode == 1 || p == NULL) {
syntaxError = 1;
break;
}
mode = 2;
fp = fopen(p, "r");
if (fp == NULL) {
fprintf(stderr, "Error reading file: %s\n", p);
syntaxError = 1;
break;
}
fseek(fp, 0L, SEEK_END); /* Position to end of file */
members_size = ftell(fp); /* Get file length */
rewind(fp); /* Back to start of file */
members = calloc(members_size + 1, sizeof(char));
if(members == NULL )
{
fprintf(stderr, "\nInsufficient memory to read file: %s\n", p);
syntaxError = 1;
fclose(fp);
break;
}
/* Read the entire file into members
* NOTE: -- fread returns number of items successfully read
* not the number of bytes. We're requesting one item of
* members_size bytes. So we expect the return value here
* to be 1.
*/
if (fread(members, members_size, 1, fp) != 1){
fprintf(stderr, "Error reading file: %s\n", p);
syntaxError = 1;
fclose(fp);
break;
}
fclose(fp);
} else if (strcmp(p, "-version")==0){
p = strtok (NULL," ");
if (version != -1 || p == NULL){
syntaxError = 1;
break;
}
#ifdef WIN32
version = _strtoui64(p, NULL, 16);
#else
version = strtoull(p, NULL, 16);
#endif
if (version < 0) {
syntaxError = 1;
break;
}
} else {
syntaxError = 1;
break;
}
p = strtok (NULL," ");
}
if (syntaxError) return;
rc = zoo_areconfig(zh, joining, leaving, members, version, my_data_completion, strdup(line));
free(joining);
free(leaving);
free(members);
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "set ")) {
char *ptr;
line += 4;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
ptr = strchr(line, ' ');
if (!ptr) {
fprintf(stderr, "No data found after path\n");
return;
}
*ptr = '\0';
ptr++;
rc = zoo_aset(zh, line, ptr, strlen(ptr), -1, my_stat_completion,
strdup(line));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "ls ")) {
line += 3;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
gettimeofday(&startTime, 0);
rc= zoo_aget_children(zh, line, 1, my_strings_completion, strdup(line));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "ls2 ")) {
line += 4;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
gettimeofday(&startTime, 0);
rc= zoo_aget_children2(zh, line, 1, my_strings_stat_completion, strdup(line));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "create ") || startsWith(line, "create2 ")) {
int mode = 0;
int64_t ttl_value = -1;
int is_create2 = startsWith(line, "create2 ");
line += is_create2 ? 8 : 7;
if (line[0] == '+') {
int ephemeral = 0;
int sequential = 0;
int container = 0;
int ttl = 0;
char *p = NULL;
line++;
while (*line != ' ' && *line != '\0') {
switch (*line) {
case 'e':
ephemeral = 1;
break;
case 's':
sequential = 1;
break;
case 'c':
container = 1;
break;
case 't':
ttl = 1;
line++;
if (*line != '=') {
fprintf(stderr, "Missing ttl value after +t\n");
return;
}
line++;
ttl_value = strtol(line, &p, 10);
if (ttl_value <= 0) {
fprintf(stderr, "ttl value must be a positive integer\n");
return;
}
// move back line pointer to the last digit
line = p - 1;
break;
default:
fprintf(stderr, "Unknown option: %c\n", *line);
return;
}
line++;
}
if (ephemeral != 0 && sequential == 0 && container == 0 && ttl == 0) {
mode = ZOO_EPHEMERAL;
} else if (ephemeral == 0 && sequential != 0 && container == 0 && ttl == 0) {
mode = ZOO_PERSISTENT_SEQUENTIAL;
} else if (ephemeral != 0 && sequential != 0 && container == 0 && ttl == 0) {
mode = ZOO_EPHEMERAL_SEQUENTIAL;
} else if (ephemeral == 0 && sequential == 0 && container != 0 && ttl == 0) {
mode = ZOO_CONTAINER;
} else if (ephemeral == 0 && sequential == 0 && container == 0 && ttl != 0) {
mode = ZOO_PERSISTENT_WITH_TTL;
} else if (ephemeral == 0 && sequential != 0 && container == 0 && ttl != 0) {
mode = ZOO_PERSISTENT_SEQUENTIAL_WITH_TTL;
} else {
fprintf(stderr, "Invalid mode.\n");
return;
}
if (*line == ' ') {
line++;
}
}
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
fprintf(stderr, "Creating [%s] node (mode: %d)\n", line, mode);
// {
// struct ACL _CREATE_ONLY_ACL_ACL[] = {{ZOO_PERM_CREATE, ZOO_ANYONE_ID_UNSAFE}};
// struct ACL_vector CREATE_ONLY_ACL = {1,_CREATE_ONLY_ACL_ACL};
// rc = zoo_acreate(zh, line, "new", 3, &CREATE_ONLY_ACL, flags,
// my_string_completion, strdup(line));
// }
if (is_create2) {
rc = zoo_acreate2_ttl(zh, line, "new", 3, &ZOO_OPEN_ACL_UNSAFE, mode, ttl_value,
my_string_stat_completion_free_data, strdup(line));
} else {
rc = zoo_acreate_ttl(zh, line, "new", 3, &ZOO_OPEN_ACL_UNSAFE, mode, ttl_value,
my_string_completion_free_data, strdup(line));
}
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "delete ")) {
line += 7;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
rc = zoo_adelete(zh, line, -1, my_void_completion, strdup(line));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "sync ")) {
line += 5;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
rc = zoo_async(zh, line, my_string_completion_free_data, strdup(line));
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "wexists ")) {
#ifdef THREADED
struct Stat stat;
#endif
line += 8;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
#ifndef THREADED
rc = zoo_awexists(zh, line, watcher, (void*) 0, my_stat_completion, strdup(line));
#else
rc = zoo_wexists(zh, line, watcher, (void*) 0, &stat);
#endif
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (startsWith(line, "exists ")) {
#ifdef THREADED
struct Stat stat;
#endif
line += 7;
if (line[0] != '/') {
fprintf(stderr, "Path must start with /, found: %s\n", line);
return;
}
#ifndef THREADED
rc = zoo_aexists(zh, line, 1, my_stat_completion, strdup(line));
#else
rc = zoo_exists(zh, line, 1, &stat);
#endif
if (rc) {
fprintf(stderr, "Error %d for %s\n", rc, line);
}
} else if (strcmp(line, "myid") == 0) {
printf("session Id = %llx\n", _LL_CAST_ zoo_client_id(zh)->client_id);
} else if (strcmp(line, "reinit") == 0) {
zookeeper_close(zh);
// we can't send myid to the server here -- zookeeper_close() removes
// the session on the server. We must start anew.
zh = zookeeper_init(hostPort, watcher, 30000, 0, 0, 0);
} else if (startsWith(line, "quit")) {
fprintf(stderr, "Quitting...\n");
shutdownThisThing=1;
} else if (startsWith(line, "od")) {
const char val[]="fire off";
fprintf(stderr, "Overdosing...\n");
rc = zoo_aset(zh, "/od", val, sizeof(val)-1, -1, od_completion, 0);
if (rc)
fprintf(stderr, "od command failed: %d\n", rc);
} else if (startsWith(line, "addauth ")) {
char *ptr;
line += 8;
ptr = strchr(line, ' ');
if (ptr) {
*ptr = '\0';
ptr++;
}
zoo_add_auth(zh, line, ptr, ptr ? strlen(ptr) : 0, NULL, NULL);
}
}