mirror of
https://github.com/fluencelabs/redis
synced 2025-06-15 02:01:21 +00:00
Merge remote-tracking branch 'upstream/unstable' into tls
This commit is contained in:
101
src/redis-cli.c
101
src/redis-cli.c
@ -228,6 +228,7 @@ static struct config {
|
||||
int hotkeys;
|
||||
int stdinarg; /* get last arg from stdin. (-x option) */
|
||||
char *auth;
|
||||
char *user;
|
||||
int output; /* output mode, see OUTPUT_* defines */
|
||||
sds mb_delim;
|
||||
char prompt[128];
|
||||
@ -240,6 +241,7 @@ static struct config {
|
||||
int verbose;
|
||||
clusterManagerCommand cluster_manager_command;
|
||||
int no_auth_warning;
|
||||
int resp3;
|
||||
} config;
|
||||
|
||||
/* User preferences. */
|
||||
@ -738,8 +740,13 @@ static int cliAuth(void) {
|
||||
redisReply *reply;
|
||||
if (config.auth == NULL) return REDIS_OK;
|
||||
|
||||
reply = redisCommand(context,"AUTH %s",config.auth);
|
||||
if (config.user == NULL)
|
||||
reply = redisCommand(context,"AUTH %s",config.auth);
|
||||
else
|
||||
reply = redisCommand(context,"AUTH %s %s",config.user,config.auth);
|
||||
if (reply != NULL) {
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
fprintf(stderr,"Warning: AUTH failed\n");
|
||||
freeReplyObject(reply);
|
||||
return REDIS_OK;
|
||||
}
|
||||
@ -826,6 +833,21 @@ error:
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Select RESP3 mode if redis-cli was started with the -3 option. */
|
||||
static int cliSwitchProto(void) {
|
||||
redisReply *reply;
|
||||
if (config.resp3 == 0) return REDIS_OK;
|
||||
|
||||
reply = redisCommand(context,"HELLO 3");
|
||||
if (reply != NULL) {
|
||||
int result = REDIS_OK;
|
||||
if (reply->type == REDIS_REPLY_ERROR) result = REDIS_ERR;
|
||||
freeReplyObject(reply);
|
||||
return result;
|
||||
}
|
||||
return REDIS_ERR;
|
||||
}
|
||||
|
||||
/* Connect to the server. It is possible to pass certain flags to the function:
|
||||
* CC_FORCE: The connection is performed even if there is already
|
||||
* a connected socket.
|
||||
@ -874,11 +896,13 @@ static int cliConnect(int flags) {
|
||||
* errors. */
|
||||
anetKeepAlive(NULL, context->fd, REDIS_CLI_KEEPALIVE_INTERVAL);
|
||||
|
||||
/* Do AUTH and select the right DB. */
|
||||
/* Do AUTH, select the right DB, switch to RESP3 if needed. */
|
||||
if (cliAuth() != REDIS_OK)
|
||||
return REDIS_ERR;
|
||||
if (cliSelect() != REDIS_OK)
|
||||
return REDIS_ERR;
|
||||
if (cliSwitchProto() != REDIS_OK)
|
||||
return REDIS_ERR;
|
||||
}
|
||||
return REDIS_OK;
|
||||
}
|
||||
@ -905,10 +929,17 @@ static sds cliFormatReplyTTY(redisReply *r, char *prefix) {
|
||||
out = sdscatprintf(out,"(double) %s\n",r->str);
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
case REDIS_REPLY_VERB:
|
||||
/* If you are producing output for the standard output we want
|
||||
* a more interesting output with quoted characters and so forth */
|
||||
out = sdscatrepr(out,r->str,r->len);
|
||||
out = sdscat(out,"\n");
|
||||
* a more interesting output with quoted characters and so forth,
|
||||
* unless it's a verbatim string type. */
|
||||
if (r->type == REDIS_REPLY_STRING) {
|
||||
out = sdscatrepr(out,r->str,r->len);
|
||||
out = sdscat(out,"\n");
|
||||
} else {
|
||||
out = sdscatlen(out,r->str,r->len);
|
||||
out = sdscat(out,"\n");
|
||||
}
|
||||
break;
|
||||
case REDIS_REPLY_NIL:
|
||||
out = sdscat(out,"(nil)\n");
|
||||
@ -1047,6 +1078,7 @@ static sds cliFormatReplyRaw(redisReply *r) {
|
||||
break;
|
||||
case REDIS_REPLY_STATUS:
|
||||
case REDIS_REPLY_STRING:
|
||||
case REDIS_REPLY_VERB:
|
||||
if (r->type == REDIS_REPLY_STATUS && config.eval_ldb) {
|
||||
/* The Lua debugger replies with arrays of simple (status)
|
||||
* strings. We colorize the output for more fun if this
|
||||
@ -1066,9 +1098,15 @@ static sds cliFormatReplyRaw(redisReply *r) {
|
||||
out = sdscatlen(out,r->str,r->len);
|
||||
}
|
||||
break;
|
||||
case REDIS_REPLY_BOOL:
|
||||
out = sdscat(out,r->integer ? "(true)" : "(false)");
|
||||
break;
|
||||
case REDIS_REPLY_INTEGER:
|
||||
out = sdscatprintf(out,"%lld",r->integer);
|
||||
break;
|
||||
case REDIS_REPLY_DOUBLE:
|
||||
out = sdscatprintf(out,"%s",r->str);
|
||||
break;
|
||||
case REDIS_REPLY_ARRAY:
|
||||
for (i = 0; i < r->elements; i++) {
|
||||
if (i > 0) out = sdscat(out,config.mb_delim);
|
||||
@ -1077,6 +1115,19 @@ static sds cliFormatReplyRaw(redisReply *r) {
|
||||
sdsfree(tmp);
|
||||
}
|
||||
break;
|
||||
case REDIS_REPLY_MAP:
|
||||
for (i = 0; i < r->elements; i += 2) {
|
||||
if (i > 0) out = sdscat(out,config.mb_delim);
|
||||
tmp = cliFormatReplyRaw(r->element[i]);
|
||||
out = sdscatlen(out,tmp,sdslen(tmp));
|
||||
sdsfree(tmp);
|
||||
|
||||
out = sdscatlen(out," ",1);
|
||||
tmp = cliFormatReplyRaw(r->element[i+1]);
|
||||
out = sdscatlen(out,tmp,sdslen(tmp));
|
||||
sdsfree(tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown reply type: %d\n", r->type);
|
||||
exit(1);
|
||||
@ -1099,13 +1150,21 @@ static sds cliFormatReplyCSV(redisReply *r) {
|
||||
case REDIS_REPLY_INTEGER:
|
||||
out = sdscatprintf(out,"%lld",r->integer);
|
||||
break;
|
||||
case REDIS_REPLY_DOUBLE:
|
||||
out = sdscatprintf(out,"%s",r->str);
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
case REDIS_REPLY_VERB:
|
||||
out = sdscatrepr(out,r->str,r->len);
|
||||
break;
|
||||
case REDIS_REPLY_NIL:
|
||||
out = sdscat(out,"NIL");
|
||||
out = sdscat(out,"NULL");
|
||||
break;
|
||||
case REDIS_REPLY_BOOL:
|
||||
out = sdscat(out,r->integer ? "true" : "false");
|
||||
break;
|
||||
case REDIS_REPLY_ARRAY:
|
||||
case REDIS_REPLY_MAP: /* CSV has no map type, just output flat list. */
|
||||
for (i = 0; i < r->elements; i++) {
|
||||
sds tmp = cliFormatReplyCSV(r->element[i]);
|
||||
out = sdscatlen(out,tmp,sdslen(tmp));
|
||||
@ -1299,7 +1358,8 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
|
||||
if (!strcasecmp(command,"select") && argc == 2 && config.last_cmd_type != REDIS_REPLY_ERROR) {
|
||||
config.dbnum = atoi(argv[1]);
|
||||
cliRefreshPrompt();
|
||||
} else if (!strcasecmp(command,"auth") && argc == 2) {
|
||||
} else if (!strcasecmp(command,"auth") && (argc == 2 || argc == 3))
|
||||
{
|
||||
cliSelect();
|
||||
}
|
||||
}
|
||||
@ -1389,8 +1449,12 @@ static int parseOptions(int argc, char **argv) {
|
||||
config.dbnum = atoi(argv[++i]);
|
||||
} else if (!strcmp(argv[i], "--no-auth-warning")) {
|
||||
config.no_auth_warning = 1;
|
||||
} else if (!strcmp(argv[i],"-a") && !lastarg) {
|
||||
} else if ((!strcmp(argv[i],"-a") || !strcmp(argv[i],"--pass"))
|
||||
&& !lastarg)
|
||||
{
|
||||
config.auth = argv[++i];
|
||||
} else if (!strcmp(argv[i],"--user") && !lastarg) {
|
||||
config.user = argv[++i];
|
||||
} else if (!strcmp(argv[i],"-u") && !lastarg) {
|
||||
parseRedisUri(argv[++i]);
|
||||
} else if (!strcmp(argv[i],"--raw")) {
|
||||
@ -1546,6 +1610,8 @@ static int parseOptions(int argc, char **argv) {
|
||||
printf("redis-cli %s\n", version);
|
||||
sdsfree(version);
|
||||
exit(0);
|
||||
} else if (!strcmp(argv[i],"-3")) {
|
||||
config.resp3 = 1;
|
||||
} else if (CLUSTER_MANAGER_MODE() && argv[i][0] != '-') {
|
||||
if (config.cluster_manager_command.argc == 0) {
|
||||
int j = i + 1;
|
||||
@ -1621,11 +1687,14 @@ static void usage(void) {
|
||||
" You can also use the " REDIS_CLI_AUTH_ENV " environment\n"
|
||||
" variable to pass this password more safely\n"
|
||||
" (if both are used, this argument takes predecence).\n"
|
||||
" -user <username> Used to send ACL style 'AUTH username pass'. Needs -a.\n"
|
||||
" -pass <password> Alias of -a for consistency with the new --user option.\n"
|
||||
" -u <uri> Server URI.\n"
|
||||
" -r <repeat> Execute specified command N times.\n"
|
||||
" -i <interval> When -r is used, waits <interval> seconds per command.\n"
|
||||
" It is possible to specify sub-second times like -i 0.1.\n"
|
||||
" -n <db> Database number.\n"
|
||||
" -3 Start session in RESP3 protocol mode.\n"
|
||||
" -x Read last argument from STDIN.\n"
|
||||
" -d <delimiter> Multi-bulk delimiter in for raw formatting (default: \\n).\n"
|
||||
" -c Enable cluster mode (follow -ASK and -MOVED redirections).\n"
|
||||
@ -1649,7 +1718,9 @@ static void usage(void) {
|
||||
" --csv is specified, or if you redirect the output to a non\n"
|
||||
" TTY, it samples the latency for 1 second (you can use\n"
|
||||
" -i to change the interval), then produces a single output\n"
|
||||
" and exits.\n"
|
||||
" and exits.\n",version);
|
||||
|
||||
fprintf(stderr,
|
||||
" --latency-history Like --latency but tracking latency changes over time.\n"
|
||||
" Default time interval is 15 sec. Change it using -i.\n"
|
||||
" --latency-dist Shows latency as a spectrum, requires xterm 256 colors.\n"
|
||||
@ -1661,7 +1732,7 @@ static void usage(void) {
|
||||
" --pipe-timeout <n> In --pipe mode, abort with error if after sending all data.\n"
|
||||
" no reply is received within <n> seconds.\n"
|
||||
" Default timeout: %d. Use 0 to wait forever.\n",
|
||||
version, REDIS_CLI_DEFAULT_PIPE_TIMEOUT);
|
||||
REDIS_CLI_DEFAULT_PIPE_TIMEOUT);
|
||||
fprintf(stderr,
|
||||
" --bigkeys Sample Redis keys looking for keys with many elements (complexity).\n"
|
||||
" --memkeys Sample Redis keys looking for keys consuming a lot of memory.\n"
|
||||
@ -2476,7 +2547,12 @@ static int clusterManagerNodeConnect(clusterManagerNode *node) {
|
||||
* errors. */
|
||||
anetKeepAlive(NULL, node->context->fd, REDIS_CLI_KEEPALIVE_INTERVAL);
|
||||
if (config.auth) {
|
||||
redisReply *reply = redisCommand(node->context,"AUTH %s",config.auth);
|
||||
redisReply *reply;
|
||||
if (config.user == NULL)
|
||||
reply = redisCommand(node->context,"AUTH %s", config.auth);
|
||||
else
|
||||
reply = redisCommand(node->context,"AUTH %s %s",
|
||||
config.user,config.auth);
|
||||
int ok = clusterManagerCheckRedisReply(node, reply, NULL);
|
||||
if (reply != NULL) freeReplyObject(reply);
|
||||
if (!ok) return 0;
|
||||
@ -3348,7 +3424,7 @@ static redisReply *clusterManagerMigrateKeysInReply(clusterManagerNode *source,
|
||||
redisReply *entry = reply->element[i];
|
||||
size_t idx = i + offset;
|
||||
assert(entry->type == REDIS_REPLY_STRING);
|
||||
argv[idx] = (char *) sdsnew(entry->str);
|
||||
argv[idx] = (char *) sdsnewlen(entry->str, entry->len);
|
||||
argv_len[idx] = entry->len;
|
||||
if (dots) dots[i] = '.';
|
||||
}
|
||||
@ -7804,6 +7880,7 @@ int main(int argc, char **argv) {
|
||||
config.hotkeys = 0;
|
||||
config.stdinarg = 0;
|
||||
config.auth = NULL;
|
||||
config.user = NULL;
|
||||
config.eval = NULL;
|
||||
config.eval_ldb = 0;
|
||||
config.eval_ldb_end = 0;
|
||||
|
Reference in New Issue
Block a user