关键词搜索

源码搜索 ×
×

漫话Redis源码之二十八

发布2021-12-12浏览530次

详情内容

这里主要是一些控制信息,看似复杂,其实还是比较明朗的:

  1. /* Cluster Manager Command Info */
  2. typedef struct clusterManagerCommand {
  3. char *name;
  4. int argc;
  5. char **argv;
  6. int flags;
  7. int replicas;
  8. char *from;
  9. char *to;
  10. char **weight;
  11. int weight_argc;
  12. char *master_id;
  13. int slots;
  14. int timeout;
  15. int pipeline;
  16. float threshold;
  17. char *backup_dir;
  18. char *from_user;
  19. char *from_pass;
  20. int from_askpass;
  21. } clusterManagerCommand;
  22. static void createClusterManagerCommand(char *cmdname, int argc, char **argv);
  23. static redisContext *context;
  24. static struct config {
  25. char *hostip;
  26. int hostport;
  27. char *hostsocket;
  28. int tls;
  29. cliSSLconfig sslconfig;
  30. long repeat;
  31. long interval;
  32. int dbnum; /* db num currently selected */
  33. int input_dbnum; /* db num user input */
  34. int interactive;
  35. int shutdown;
  36. int monitor_mode;
  37. int pubsub_mode;
  38. int latency_mode;
  39. int latency_dist_mode;
  40. int latency_history;
  41. int lru_test_mode;
  42. long long lru_test_sample_size;
  43. int cluster_mode;
  44. int cluster_reissue_command;
  45. int cluster_send_asking;
  46. int slave_mode;
  47. int pipe_mode;
  48. int pipe_timeout;
  49. int getrdb_mode;
  50. int stat_mode;
  51. int scan_mode;
  52. int intrinsic_latency_mode;
  53. int intrinsic_latency_duration;
  54. sds pattern;
  55. char *rdb_filename;
  56. int bigkeys;
  57. int memkeys;
  58. unsigned memkeys_samples;
  59. int hotkeys;
  60. int stdinarg; /* get last arg from stdin. (-x option) */
  61. char *auth;
  62. int askpass;
  63. char *user;
  64. int quoted_input; /* Force input args to be treated as quoted strings */
  65. int output; /* output mode, see OUTPUT_* defines */
  66. int push_output; /* Should we display spontaneous PUSH replies */
  67. sds mb_delim;
  68. sds cmd_delim;
  69. char prompt[128];
  70. char *eval;
  71. int eval_ldb;
  72. int eval_ldb_sync; /* Ask for synchronous mode of the Lua debugger. */
  73. int eval_ldb_end; /* Lua debugging session ended. */
  74. int enable_ldb_on_eval; /* Handle manual SCRIPT DEBUG + EVAL commands. */
  75. int last_cmd_type;
  76. int verbose;
  77. int set_errcode;
  78. clusterManagerCommand cluster_manager_command;
  79. int no_auth_warning;
  80. int resp3;
  81. int in_multi;
  82. int pre_multi_dbnum;
  83. } config;
  84. /* User preferences. */
  85. static struct pref {
  86. int hints;
  87. } pref;
  88. static volatile sig_atomic_t force_cancel_loop = 0;
  89. static void usage(void);
  90. static void slaveMode(void);
  91. char *redisGitSHA1(void);
  92. char *redisGitDirty(void);
  93. static int cliConnect(int force);
  94. static char *getInfoField(char *info, char *field);
  95. static long getLongInfoField(char *info, char *field);
  96. /*------------------------------------------------------------------------------
  97. * Utility functions
  98. *--------------------------------------------------------------------------- */
  99. static void cliPushHandler(void *, void *);
  100. uint16_t crc16(const char *buf, int len);
  101. static long long ustime(void) {
  102. struct timeval tv;
  103. long long ust;
  104. gettimeofday(&tv, NULL);
  105. ust = ((long long)tv.tv_sec)*1000000;
  106. ust += tv.tv_usec;
  107. return ust;
  108. }
  109. static long long mstime(void) {
  110. return ustime()/1000;
  111. }
  112. static void cliRefreshPrompt(void) {
  113. if (config.eval_ldb) return;
  114. sds prompt = sdsempty();
  115. if (config.hostsocket != NULL) {
  116. prompt = sdscatfmt(prompt,"redis %s",config.hostsocket);
  117. } else {
  118. char addr[256];
  119. anetFormatAddr(addr, sizeof(addr), config.hostip, config.hostport);
  120. prompt = sdscatlen(prompt,addr,strlen(addr));
  121. }
  122. /* Add [dbnum] if needed */
  123. if (config.dbnum != 0)
  124. prompt = sdscatfmt(prompt,"[%i]",config.dbnum);
  125. /* Add TX if in transaction state*/
  126. if (config.in_multi)
  127. prompt = sdscatlen(prompt,"(TX)",4);
  128. /* Copy the prompt in the static buffer. */
  129. prompt = sdscatlen(prompt,"> ",2);
  130. snprintf(config.prompt,sizeof(config.prompt),"%s",prompt);
  131. sdsfree(prompt);
  132. }
  133. /* Return the name of the dotfile for the specified 'dotfilename'.
  134. * Normally it just concatenates user $HOME to the file specified
  135. * in 'dotfilename'. However if the environment variable 'envoverride'
  136. * is set, its value is taken as the path.
  137. *
  138. * The function returns NULL (if the file is /dev/null or cannot be
  139. * obtained for some error), or an SDS string that must be freed by
  140. * the user. */
  141. static sds getDotfilePath(char *envoverride, char *dotfilename) {
  142. char *path = NULL;
  143. sds dotPath = NULL;
  144. /* Check the env for a dotfile override. */
  145. path = getenv(envoverride);
  146. if (path != NULL && *path != '\0') {
  147. if (!strcmp("/dev/null", path)) {
  148. return NULL;
  149. }
  150. /* If the env is set, return it. */
  151. dotPath = sdsnew(path);
  152. } else {
  153. char *home = getenv("HOME");
  154. if (home != NULL && *home != '\0') {
  155. /* If no override is set use $HOME/<dotfilename>. */
  156. dotPath = sdscatprintf(sdsempty(), "%s/%s", home, dotfilename);
  157. }
  158. }
  159. return dotPath;
  160. }
  161. /* URL-style percent decoding. */
  162. #define isHexChar(c) (isdigit(c) || (c >= 'a' && c <= 'f'))
  163. #define decodeHexChar(c) (isdigit(c) ? c - '0' : c - 'a' + 10)
  164. #define decodeHex(h, l) ((decodeHexChar(h) << 4) + decodeHexChar(l))
  165. static sds percentDecode(const char *pe, size_t len) {
  166. const char *end = pe + len;
  167. sds ret = sdsempty();
  168. const char *curr = pe;
  169. while (curr < end) {
  170. if (*curr == '%') {
  171. if ((end - curr) < 2) {
  172. fprintf(stderr, "Incomplete URI encoding\n");
  173. exit(1);
  174. }
  175. char h = tolower(*(++curr));
  176. char l = tolower(*(++curr));
  177. if (!isHexChar(h) || !isHexChar(l)) {
  178. fprintf(stderr, "Illegal character in URI encoding\n");
  179. exit(1);
  180. }
  181. char c = decodeHex(h, l);
  182. ret = sdscatlen(ret, &c, 1);
  183. curr++;
  184. } else {
  185. ret = sdscatlen(ret, curr++, 1);
  186. }
  187. }
  188. return ret;
  189. }
  190. /* Parse a URI and extract the server connection information.
  191. * URI scheme is based on the the provisional specification[1] excluding support
  192. * for query parameters. Valid URIs are:
  193. * scheme: "redis://"
  194. * authority: [[<username> ":"] <password> "@"] [<hostname> [":" <port>]]
  195. * path: ["/" [<db>]]
  196. *
  197. * [1]: https://www.iana.org/assignments/uri-schemes/prov/redis */
  198. static void parseRedisUri(const char *uri) {
  199. const char *scheme = "redis://";
  200. const char *tlsscheme = "rediss://";
  201. const char *curr = uri;
  202. const char *end = uri + strlen(uri);
  203. const char *userinfo, *username, *port, *host, *path;
  204. /* URI must start with a valid scheme. */
  205. if (!strncasecmp(tlsscheme, curr, strlen(tlsscheme))) {
  206. #ifdef USE_OPENSSL
  207. config.tls = 1;
  208. curr += strlen(tlsscheme);
  209. #else
  210. fprintf(stderr,"rediss:// is only supported when redis-cli is compiled with OpenSSL\n");
  211. exit(1);
  212. #endif
  213. } else if (!strncasecmp(scheme, curr, strlen(scheme))) {
  214. curr += strlen(scheme);
  215. } else {
  216. fprintf(stderr,"Invalid URI scheme\n");
  217. exit(1);
  218. }
  219. if (curr == end) return;
  220. /* Extract user info. */
  221. if ((userinfo = strchr(curr,'@'))) {
  222. if ((username = strchr(curr, ':')) && username < userinfo) {
  223. config.user = percentDecode(curr, username - curr);
  224. curr = username + 1;
  225. }
  226. config.auth = percentDecode(curr, userinfo - curr);
  227. curr = userinfo + 1;
  228. }
  229. if (curr == end) return;
  230. /* Extract host and port. */
  231. path = strchr(curr, '/');
  232. if (*curr != '/') {
  233. host = path ? path - 1 : end;
  234. if ((port = strchr(curr, ':'))) {
  235. config.hostport = atoi(port + 1);
  236. host = port - 1;
  237. }
  238. config.hostip = sdsnewlen(curr, host - curr + 1);
  239. }
  240. curr = path ? path + 1 : end;
  241. if (curr == end) return;
  242. /* Extract database number. */
  243. config.input_dbnum = atoi(curr);
  244. }
  245. static uint64_t dictSdsHash(const void *key) {
  246. return dictGenHashFunction((unsigned char*)key, sdslen((char*)key));
  247. }
  248. static int dictSdsKeyCompare(void *privdata, const void *key1,
  249. const void *key2)
  250. {
  251. int l1,l2;
  252. DICT_NOTUSED(privdata);
  253. l1 = sdslen((sds)key1);
  254. l2 = sdslen((sds)key2);
  255. if (l1 != l2) return 0;
  256. return memcmp(key1, key2, l1) == 0;
  257. }
  258. static void dictSdsDestructor(void *privdata, void *val)
  259. {
  260. DICT_NOTUSED(privdata);
  261. sdsfree(val);
  262. }
  263. void dictListDestructor(void *privdata, void *val)
  264. {
  265. DICT_NOTUSED(privdata);
  266. listRelease((list*)val);
  267. }
  268. /* _serverAssert is needed by dict */
  269. void _serverAssert(const char *estr, const char *file, int line) {
  270. fprintf(stderr, "=== ASSERTION FAILED ===");
  271. fprintf(stderr, "==> %s:%d '%s' is not true",file,line,estr);
  272. *((char*)-1) = 'x';
  273. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载