static void validate(RedisModuleCtx *ctx, RedisModuleCallReply *reply, RedisModuleString *password) { const char *reply_str; size_t reply_len; const char *pass; size_t pass_len; const char *crypt_pass; size_t crypt_pass_len; char crypt_buf[64]; if (RedisModule_CallReplyType(reply) == REDISMODULE_REPLY_NULL) { RedisModule_ReplyWithLongLong(ctx, 0); return; } if (RedisModule_CallReplyType(reply) != REDISMODULE_REPLY_STRING) { RedisModule_ReplyWithError(ctx, "WRONGTYPE Operation against a key holding the wrong kind of value"); return; } reply_str = RedisModule_CallReplyStringPtr(reply, &reply_len); pass = RedisModule_StringPtrLen(password, &pass_len); crypt_pass = crypt_rn(pass, reply_str, crypt_buf, sizeof(crypt_buf)); if (!crypt_pass) { RedisModule_ReplyWithError(ctx, "ERR hash error"); return; } crypt_pass_len = strlen(crypt_pass); if (crypt_pass_len == reply_len && !memcmp(reply_str, crypt_pass, crypt_pass_len)) { RedisModule_ReplyWithLongLong(ctx, 1); } else { RedisModule_ReplyWithLongLong(ctx, 0); } }
RMUtilInfo *RMUtil_HGetAll(RedisModuleCtx *ctx, RedisModuleString *id) { RedisModuleCallReply *reply = RedisModule_Call(ctx, "HGETALL", "s", id); if(RedisModule_CallReplyType(reply) != REDISMODULE_REPLY_ARRAY) { printf("ERROE expecting an array \n"); return NULL; } size_t reply_len = RedisModule_CallReplyLength(reply); RMUtilInfo *hgetall = malloc(sizeof(RMUtilInfo)); hgetall->numEntries = reply_len/2; hgetall->entries = malloc(sizeof(RMUtilInfoEntry) * hgetall->numEntries); // Consume HGETALL for(int idx = 0; idx < reply_len; idx+=2) { RedisModuleCallReply *subreply; subreply = RedisModule_CallReplyArrayElement(reply, idx); size_t len; char *key = strdup(RedisModule_CallReplyStringPtr(subreply, &len)); key[len] = 0; hgetall->entries[idx/2].key = key; subreply = RedisModule_CallReplyArrayElement(reply, idx+1); char *val = strdup(RedisModule_CallReplyStringPtr(subreply, &len)); val[len] = 0; hgetall->entries[idx/2].val = val; } RedisModule_FreeCallReply(reply); return hgetall; }
RMUtilInfo *RMUtil_GetRedisInfo(RedisModuleCtx *ctx) { RedisModuleCallReply *r = RedisModule_Call(ctx, "INFO", "c", "all"); if (r == NULL || RedisModule_CallReplyType(r) == REDISMODULE_REPLY_ERROR) { return NULL; } int cap = 100; // rough estimate of info lines RMUtilInfo *info = malloc(sizeof(RMUtilInfo)); info->entries = calloc(cap, sizeof(RMUtilInfoEntry)); int i = 0; char *text = (char *)RedisModule_StringPtrLen(RedisModule_CreateStringFromCallReply(r), NULL); char *line = text; while (line) { char *line = strsep(&text, "\r\n"); if (line == NULL) break; if (!(*line >= 'a' && *line <= 'z')) { //skip non entry lines continue; } char *key = strsep(&line, ":"); info->entries[i].key = key; info->entries[i].val = line; printf("Got info '%s' = '%s'\n", key, line); i++; if (i >= cap) { cap *=2; info->entries = realloc(info->entries, cap*sizeof(RMUtilInfoEntry)); } } info->numEntries = i; return info; }