这里主要是一些控制信息,看似复杂,其实还是比较明朗的:
- /* Cluster Manager Command Info */
- typedef struct clusterManagerCommand {
- char *name;
- int argc;
- char **argv;
- int flags;
- int replicas;
- char *from;
- char *to;
- char **weight;
- int weight_argc;
- char *master_id;
- int slots;
- int timeout;
- int pipeline;
- float threshold;
- char *backup_dir;
- char *from_user;
- char *from_pass;
- int from_askpass;
- } clusterManagerCommand;
-
- static void createClusterManagerCommand(char *cmdname, int argc, char **argv);
-
-
- static redisContext *context;
- static struct config {
- char *hostip;
- int hostport;
- char *hostsocket;
- int tls;
- cliSSLconfig sslconfig;
- long repeat;
- long interval;
- int dbnum; /* db num currently selected */
- int input_dbnum; /* db num user input */
- int interactive;
- int shutdown;
- int monitor_mode;
- int pubsub_mode;
- int latency_mode;
- int latency_dist_mode;
- int latency_history;
- int lru_test_mode;
- long long lru_test_sample_size;
- int cluster_mode;
- int cluster_reissue_command;
- int cluster_send_asking;
- int slave_mode;
- int pipe_mode;
- int pipe_timeout;
- int getrdb_mode;
- int stat_mode;
- int scan_mode;
- int intrinsic_latency_mode;
- int intrinsic_latency_duration;
- sds pattern;
- char *rdb_filename;
- int bigkeys;
- int memkeys;
- unsigned memkeys_samples;
- int hotkeys;
- int stdinarg; /* get last arg from stdin. (-x option) */
- char *auth;
- int askpass;
- char *user;
- int quoted_input; /* Force input args to be treated as quoted strings */
- int output; /* output mode, see OUTPUT_* defines */
- int push_output; /* Should we display spontaneous PUSH replies */
- sds mb_delim;
- sds cmd_delim;
- char prompt[128];
- char *eval;
- int eval_ldb;
- int eval_ldb_sync; /* Ask for synchronous mode of the Lua debugger. */
- int eval_ldb_end; /* Lua debugging session ended. */
- int enable_ldb_on_eval; /* Handle manual SCRIPT DEBUG + EVAL commands. */
- int last_cmd_type;
- int verbose;
- int set_errcode;
- clusterManagerCommand cluster_manager_command;
- int no_auth_warning;
- int resp3;
- int in_multi;
- int pre_multi_dbnum;
- } config;
-
- /* User preferences. */
- static struct pref {
- int hints;
- } pref;
-
- static volatile sig_atomic_t force_cancel_loop = 0;
- static void usage(void);
- static void slaveMode(void);
- char *redisGitSHA1(void);
- char *redisGitDirty(void);
- static int cliConnect(int force);
-
- static char *getInfoField(char *info, char *field);
- static long getLongInfoField(char *info, char *field);
-
- /*------------------------------------------------------------------------------
- * Utility functions
- *--------------------------------------------------------------------------- */
-
- static void cliPushHandler(void *, void *);
-
- uint16_t crc16(const char *buf, int len);
-
- static long long ustime(void) {
- struct timeval tv;
- long long ust;
-
- gettimeofday(&tv, NULL);
- ust = ((long long)tv.tv_sec)*1000000;
- ust += tv.tv_usec;
- return ust;
- }
-
- static long long mstime(void) {
- return ustime()/1000;
- }
-
- static void cliRefreshPrompt(void) {
- if (config.eval_ldb) return;
-
- sds prompt = sdsempty();
- if (config.hostsocket != NULL) {
- prompt = sdscatfmt(prompt,"redis %s",config.hostsocket);
- } else {
- char addr[256];
- anetFormatAddr(addr, sizeof(addr), config.hostip, config.hostport);
- prompt = sdscatlen(prompt,addr,strlen(addr));
- }
-
- /* Add [dbnum] if needed */
- if (config.dbnum != 0)
- prompt = sdscatfmt(prompt,"[%i]",config.dbnum);
-
- /* Add TX if in transaction state*/
- if (config.in_multi)
- prompt = sdscatlen(prompt,"(TX)",4);
-
- /* Copy the prompt in the static buffer. */
- prompt = sdscatlen(prompt,"> ",2);
- snprintf(config.prompt,sizeof(config.prompt),"%s",prompt);
- sdsfree(prompt);
- }
-
- /* Return the name of the dotfile for the specified 'dotfilename'.
- * Normally it just concatenates user $HOME to the file specified
- * in 'dotfilename'. However if the environment variable 'envoverride'
- * is set, its value is taken as the path.
- *
- * The function returns NULL (if the file is /dev/null or cannot be
- * obtained for some error), or an SDS string that must be freed by
- * the user. */
- static sds getDotfilePath(char *envoverride, char *dotfilename) {
- char *path = NULL;
- sds dotPath = NULL;
-
- /* Check the env for a dotfile override. */
- path = getenv(envoverride);
- if (path != NULL && *path != '\0') {
- if (!strcmp("/dev/null", path)) {
- return NULL;
- }
-
- /* If the env is set, return it. */
- dotPath = sdsnew(path);
- } else {
- char *home = getenv("HOME");
- if (home != NULL && *home != '\0') {
- /* If no override is set use $HOME/<dotfilename>. */
- dotPath = sdscatprintf(sdsempty(), "%s/%s", home, dotfilename);
- }
- }
- return dotPath;
- }
-
- /* URL-style percent decoding. */
- #define isHexChar(c) (isdigit(c) || (c >= 'a' && c <= 'f'))
- #define decodeHexChar(c) (isdigit(c) ? c - '0' : c - 'a' + 10)
- #define decodeHex(h, l) ((decodeHexChar(h) << 4) + decodeHexChar(l))
-
- static sds percentDecode(const char *pe, size_t len) {
- const char *end = pe + len;
- sds ret = sdsempty();
- const char *curr = pe;
-
- while (curr < end) {
- if (*curr == '%') {
- if ((end - curr) < 2) {
- fprintf(stderr, "Incomplete URI encoding\n");
- exit(1);
- }
-
- char h = tolower(*(++curr));
- char l = tolower(*(++curr));
- if (!isHexChar(h) || !isHexChar(l)) {
- fprintf(stderr, "Illegal character in URI encoding\n");
- exit(1);
- }
- char c = decodeHex(h, l);
- ret = sdscatlen(ret, &c, 1);
- curr++;
- } else {
- ret = sdscatlen(ret, curr++, 1);
- }
- }
-
- return ret;
- }
-
- /* Parse a URI and extract the server connection information.
- * URI scheme is based on the the provisional specification[1] excluding support
- * for query parameters. Valid URIs are:
- * scheme: "redis://"
- * authority: [[<username> ":"] <password> "@"] [<hostname> [":" <port>]]
- * path: ["/" [<db>]]
- *
- * [1]: https://www.iana.org/assignments/uri-schemes/prov/redis */
- static void parseRedisUri(const char *uri) {
-
- const char *scheme = "redis://";
- const char *tlsscheme = "rediss://";
- const char *curr = uri;
- const char *end = uri + strlen(uri);
- const char *userinfo, *username, *port, *host, *path;
-
- /* URI must start with a valid scheme. */
- if (!strncasecmp(tlsscheme, curr, strlen(tlsscheme))) {
- #ifdef USE_OPENSSL
- config.tls = 1;
- curr += strlen(tlsscheme);
- #else
- fprintf(stderr,"rediss:// is only supported when redis-cli is compiled with OpenSSL\n");
- exit(1);
- #endif
- } else if (!strncasecmp(scheme, curr, strlen(scheme))) {
- curr += strlen(scheme);
- } else {
- fprintf(stderr,"Invalid URI scheme\n");
- exit(1);
- }
- if (curr == end) return;
-
- /* Extract user info. */
- if ((userinfo = strchr(curr,'@'))) {
- if ((username = strchr(curr, ':')) && username < userinfo) {
- config.user = percentDecode(curr, username - curr);
- curr = username + 1;
- }
-
- config.auth = percentDecode(curr, userinfo - curr);
- curr = userinfo + 1;
- }
- if (curr == end) return;
-
- /* Extract host and port. */
- path = strchr(curr, '/');
- if (*curr != '/') {
- host = path ? path - 1 : end;
- if ((port = strchr(curr, ':'))) {
- config.hostport = atoi(port + 1);
- host = port - 1;
- }
- config.hostip = sdsnewlen(curr, host - curr + 1);
- }
- curr = path ? path + 1 : end;
- if (curr == end) return;
-
- /* Extract database number. */
- config.input_dbnum = atoi(curr);
- }
-
- static uint64_t dictSdsHash(const void *key) {
- return dictGenHashFunction((unsigned char*)key, sdslen((char*)key));
- }
-
- static int dictSdsKeyCompare(void *privdata, const void *key1,
- const void *key2)
- {
- int l1,l2;
- DICT_NOTUSED(privdata);
-
- l1 = sdslen((sds)key1);
- l2 = sdslen((sds)key2);
- if (l1 != l2) return 0;
- return memcmp(key1, key2, l1) == 0;
- }
-
- static void dictSdsDestructor(void *privdata, void *val)
- {
- DICT_NOTUSED(privdata);
- sdsfree(val);
- }
-
- void dictListDestructor(void *privdata, void *val)
- {
- DICT_NOTUSED(privdata);
- listRelease((list*)val);
- }
-
- /* _serverAssert is needed by dict */
- void _serverAssert(const char *estr, const char *file, int line) {
- fprintf(stderr, "=== ASSERTION FAILED ===");
- fprintf(stderr, "==> %s:%d '%s' is not true",file,line,estr);
- *((char*)-1) = 'x';
- }