// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelCommand
void sentinelCommand(redisClient *c) {
    if (!strcasecmp(c->argv[1]->ptr,"masters")) {
        /* SENTINEL MASTERS */
        if (c->argc != 2) goto numargserr;
        addReplyDictOfRedisInstances(c,sentinel.masters);
    } else if (!strcasecmp(c->argv[1]->ptr,"master")) {
        /* SENTINEL MASTER <name> */
        sentinelRedisInstance *ri;

        if (c->argc != 3) goto numargserr;
        if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
            == NULL) return;
        addReplySentinelRedisInstance(c,ri);
    } else if (!strcasecmp(c->argv[1]->ptr,"slaves")) {
        /* SENTINEL SLAVES <master-name> */
        sentinelRedisInstance *ri;

        if (c->argc != 3) goto numargserr;
        if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
            return;
        addReplyDictOfRedisInstances(c,ri->slaves);
    } else if (!strcasecmp(c->argv[1]->ptr,"sentinels")) {
        /* SENTINEL SENTINELS <master-name> */
        sentinelRedisInstance *ri;

        if (c->argc != 3) goto numargserr;
        if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
            return;
        addReplyDictOfRedisInstances(c,ri->sentinels);
    } else if (!strcasecmp(c->argv[1]->ptr,"is-master-down-by-addr")) {
        /* SENTINEL IS-MASTER-DOWN-BY-ADDR <ip> <port> <current-epoch> <runid>*/
        sentinelRedisInstance *ri;
        long long req_epoch;
        uint64_t leader_epoch = 0;
        char *leader = NULL;
        long port;
        int isdown = 0;

        if (c->argc != 6) goto numargserr;
        if (getLongFromObjectOrReply(c,c->argv[3],&port,NULL) != REDIS_OK ||
            getLongLongFromObjectOrReply(c,c->argv[4],&req_epoch,NULL)
                                                              != REDIS_OK)
            return;
        ri = getSentinelRedisInstanceByAddrAndRunID(sentinel.masters,
            c->argv[2]->ptr,port,NULL);

        /* It exists? Is actually a master? Is subjectively down? It's down.
         * Note: if we are in tilt mode we always reply with "0". */
        if (!sentinel.tilt && ri && (ri->flags & SRI_S_DOWN) &&
                                    (ri->flags & SRI_MASTER))
            isdown = 1;

        /* Vote for the master (or fetch the previous vote) if the request
         * includes a runid, otherwise the sender is not seeking for a vote. */
        if (ri && ri->flags & SRI_MASTER && strcasecmp(c->argv[5]->ptr,"*")) {
            leader = sentinelVoteLeader(ri,(uint64_t)req_epoch,
                                            c->argv[5]->ptr,
                                            &leader_epoch);
        }

        /* Reply with a three-elements multi-bulk reply:
         * down state, leader, vote epoch. */
        // 多条回复
        // 1) <down_state>    1 代表下线， 0 代表未下线
        // 2) <leader_runid>  Sentinel 选举作为领头 Sentinel 的运行 ID
        // 3) <leader_epoch>  领头 Sentinel 目前的配置纪元
        addReplyMultiBulkLen(c,3);
        addReply(c, isdown ? shared.cone : shared.czero);
        addReplyBulkCString(c, leader ? leader : "*");
        addReplyLongLong(c, (long long)leader_epoch);
        if (leader) sdsfree(leader);
    } else if (!strcasecmp(c->argv[1]->ptr,"reset")) {
        /* SENTINEL RESET <pattern> */
        if (c->argc != 3) goto numargserr;
        addReplyLongLong(c,sentinelResetMastersByPattern(c->argv[2]->ptr,SENTINEL_GENERATE_EVENT));
    } else if (!strcasecmp(c->argv[1]->ptr,"get-master-addr-by-name")) {
        /* SENTINEL GET-MASTER-ADDR-BY-NAME <master-name> */
        sentinelRedisInstance *ri;

        if (c->argc != 3) goto numargserr;
        ri = sentinelGetMasterByName(c->argv[2]->ptr);
        if (ri == NULL) {
            addReply(c,shared.nullmultibulk);
        } else {
            sentinelAddr *addr = sentinelGetCurrentMasterAddress(ri);

            addReplyMultiBulkLen(c,2);
            addReplyBulkCString(c,addr->ip);
            addReplyBulkLongLong(c,addr->port);
        }
    } else if (!strcasecmp(c->argv[1]->ptr,"failover")) {
        /* SENTINEL FAILOVER <master-name> */
        sentinelRedisInstance *ri;

        if (c->argc != 3) goto numargserr;
        if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
            return;
        if (ri->flags & SRI_FAILOVER_IN_PROGRESS) {
            addReplySds(c,sdsnew("-INPROG Failover already in progress\r\n"));
            return;
        }
        if (sentinelSelectSlave(ri) == NULL) {
            addReplySds(c,sdsnew("-NOGOODSLAVE No suitable slave to promote\r\n"));
            return;
        }
        redisLog(REDIS_WARNING,"Executing user requested FAILOVER of '%s'",
            ri->name);
        sentinelStartFailover(ri);
        ri->flags |= SRI_FORCE_FAILOVER;
        addReply(c,shared.ok);
    } else if (!strcasecmp(c->argv[1]->ptr,"pending-scripts")) {
        /* SENTINEL PENDING-SCRIPTS */

        if (c->argc != 2) goto numargserr;
        sentinelPendingScriptsCommand(c);
    } else if (!strcasecmp(c->argv[1]->ptr,"monitor")) {
        /* SENTINEL MONITOR <name> <ip> <port> <quorum> */
        sentinelRedisInstance *ri;
        long quorum, port;
        char buf[32];

        if (c->argc != 6) goto numargserr;
        if (getLongFromObjectOrReply(c,c->argv[5],&quorum,"Invalid quorum")
            != REDIS_OK) return;
        if (getLongFromObjectOrReply(c,c->argv[4],&port,"Invalid port")
            != REDIS_OK) return;
        /* Make sure the IP field is actually a valid IP before passing it
         * to createSentinelRedisInstance(), otherwise we may trigger a
         * DNS lookup at runtime. */
        if (anetResolveIP(NULL,c->argv[3]->ptr,buf,sizeof(buf)) == ANET_ERR) {
            addReplyError(c,"Invalid IP address specified");
            return;
        }

        /* Parameters are valid. Try to create the master instance. */
        ri = createSentinelRedisInstance(c->argv[2]->ptr,SRI_MASTER,
                c->argv[3]->ptr,port,quorum,NULL);
        if (ri == NULL) {
            switch(errno) {
            case EBUSY:
                addReplyError(c,"Duplicated master name");
                break;
            case EINVAL:
                addReplyError(c,"Invalid port number");
                break;
            default:
                addReplyError(c,"Unspecified error adding the instance");
                break;
            }
        } else {
            sentinelFlushConfig();
            sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
            addReply(c,shared.ok);
        }
    } else if (!strcasecmp(c->argv[1]->ptr,"remove")) {
        /* SENTINEL REMOVE <name> */
        sentinelRedisInstance *ri;

        if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
            == NULL) return;
        sentinelEvent(REDIS_WARNING,"-monitor",ri,"%@");
        dictDelete(sentinel.masters,c->argv[2]->ptr);
        sentinelFlushConfig();
        addReply(c,shared.ok);
    } else if (!strcasecmp(c->argv[1]->ptr,"set")) {
        if (c->argc < 3 || c->argc % 2 == 0) goto numargserr;
        sentinelSetCommand(c);
    } else {
        addReplyErrorFormat(c,"Unknown sentinel subcommand '%s'",
                               (char*)c->argv[1]->ptr);
    }
    return;

numargserr:
    addReplyErrorFormat(c,"Wrong number of arguments for 'sentinel %s'",
                          (char*)c->argv[1]->ptr);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x30, %rsp
movq %rdi, %rbx
movq 0x38(%rdi), %r15
movq 0x8(%r15), %rax
movq 0x8(%rax), %r14
leaq 0x44e16(%rip), %rsi     # 0x9f90c
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5ac23
leaq 0x422fa(%rip), %rsi     # 0x9ce07
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5ac48
leaq 0x44aa3(%rip), %rsi     # 0x9f5c7
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5ac6a
leaq 0x44d23(%rip), %rsi     # 0x9f85e
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5ac88
leaq 0x44dc2(%rip), %rsi     # 0x9f914
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5acdb
leaq 0x423ea(%rip), %rsi     # 0x9cf53
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5adb3
leaq 0x44dab(%rip), %rsi     # 0x9f92b
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5ade6
leaq 0x451b3(%rip), %rsi     # 0x9fd4a
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5ae52
leaq 0x44e12(%rip), %rsi     # 0x9f9c0
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5aec0
leaq 0x4429e(%rip), %rsi     # 0x9ee63
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5aede
leaq 0x44e5d(%rip), %rsi     # 0x9fa39
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5afe0
leaq 0x3a8eb(%rip), %rsi     # 0x954de
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5b0bc
leaq 0x44e3f(%rip), %rsi     # 0x9fa49
movq %rbx, %rdi
movq %r14, %rdx
xorl %eax, %eax
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2d9fe
cmpl $0x2, 0x30(%rbx)
jne 0x5acb1
movq 0x83cbc(%rip), %rsi     # 0xde8f0
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5ee9d
movl 0x30(%rbx), %ebp
cmpl $0x3, %ebp
jne 0x5acb1
movq %rbx, %rdi
callq 0x5eeeb
testq %rax, %rax
je 0x5acac
movq %rbx, %rdi
movq %rax, %rsi
callq 0x5e81b
jmp 0x5acac
movl 0x30(%rbx), %ebp
cmpl $0x3, %ebp
jne 0x5acb1
movq %rbx, %rdi
callq 0x5eeeb
testq %rax, %rax
je 0x5acac
movq 0xc8(%rax), %rsi
jmp 0x5aca4
movl 0x30(%rbx), %ebp
cmpl $0x3, %ebp
jne 0x5acb1
movq %rbx, %rdi
callq 0x5eeeb
testq %rax, %rax
je 0x5acac
movq 0xc0(%rax), %rsi
movq %rbx, %rdi
callq 0x5ee9d
cmpl $0x3, %ebp
je 0x5acce
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdx
leaq 0x44da6(%rip), %rsi     # 0x9fa6a
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2d9fe
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq $0x0, (%rsp)
movl 0x30(%rbx), %ebp
cmpl $0x6, %ebp
jne 0x5acb1
movq 0x18(%r15), %rsi
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x310df
testl %eax, %eax
jne 0x5b0a5
movq 0x38(%rbx), %rax
movq 0x20(%rax), %rsi
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x31082
testl %eax, %eax
jne 0x5b0a5
movq 0x83bc4(%rip), %rdi     # 0xde8f0
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movl 0x8(%rsp), %edx
xorl %ecx, %ecx
callq 0x5c59e
movq %rax, %r14
cmpl $0x0, 0x83bab(%rip)     # 0xde8f8
movb $0x1, %r12b
jne 0x5ad62
testq %r14, %r14
je 0x5ad62
movl (%r14), %eax
notl %eax
testb $0x11, %al
setne %r12b
testq %r14, %r14
je 0x5b04a
testb $0x1, (%r14)
je 0x5b04a
movq 0x38(%rbx), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %r15
leaq 0x39aac(%rip), %rsi     # 0x94834
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5b04a
movq 0x10(%rsp), %rsi
movq %rsp, %rcx
movq %r14, %rdi
movq %r15, %rdx
callq 0x5ef1f
movq %rax, %r14
jmp 0x5b04d
cmpl $0x3, 0x30(%rbx)
jne 0x5acb1
movq 0x10(%r15), %rax
movq 0x8(%rax), %rdi
movl $0x10000, %esi          # imm = 0x10000
callq 0x5c876
movslq %eax, %rsi
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2dea3
movl 0x30(%rbx), %ebp
cmpl $0x3, %ebp
jne 0x5acb1
movq 0x10(%r15), %rax
movq 0x8(%rax), %rdi
callq 0x5c679
testq %rax, %rax
je 0x5afc8
testb $-0x80, (%rax)
je 0x5ae22
movq 0x158(%rax), %rcx
testq %rcx, %rcx
je 0x5ae22
cmpl $0x4, 0x130(%rax)
jg 0x5ae25
movq %rax, %rcx
movq 0x20(%rcx), %r14
movl $0x2, %esi
movq %rbx, %rdi
callq 0x2ded8
movq (%r14), %rsi
movq %rbx, %rdi
callq 0x2ddc1
movslq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x2dfe7
jmp 0x5acac
movl 0x30(%rbx), %ebp
cmpl $0x3, %ebp
jne 0x5acb1
movq %rbx, %rdi
callq 0x5eeeb
testq %rax, %rax
je 0x5acac
movq %rax, %r14
testb $-0x80, (%rax)
jne 0x5b0b3
movq %r14, %rdi
callq 0x5f065
testq %rax, %rax
je 0x5b0e6
movq 0x8(%r14), %rdx
leaq 0x44aff(%rip), %rsi     # 0x9f996
movl $0x3, %edi
xorl %eax, %eax
callq 0x23064
movq %r14, %rdi
callq 0x5f19a
orb $0x10, 0x1(%r14)
leaq 0x6f949(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
jmp 0x5afd3
cmpl $0x2, 0x30(%rbx)
jne 0x5acb1
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5befd
movl 0x30(%rbx), %ebp
cmpl $0x6, %ebp
jne 0x5acb1
movq 0x28(%r15), %rsi
leaq 0x44adb(%rip), %rcx     # 0x9f9d0
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x310df
testl %eax, %eax
jne 0x5b0a5
movq 0x38(%rbx), %rax
movq 0x20(%rax), %rsi
leaq 0x3e81b(%rip), %rcx     # 0x99732
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
callq 0x310df
testl %eax, %eax
jne 0x5b0a5
movq 0x38(%rbx), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rsi
leaq 0x10(%rsp), %rdx
movl $0x20, %ecx
xorl %edi, %edi
callq 0x21534
cmpl $-0x1, %eax
je 0x5b102
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rcx
movq 0x18(%rax), %rax
movq 0x8(%rcx), %rdi
movq 0x8(%rax), %rdx
movl 0x8(%rsp), %ecx
movl (%rsp), %r8d
movl $0x1, %esi
xorl %r9d, %r9d
callq 0x5c139
testq %rax, %rax
je 0x5b113
movq %rax, %r14
callq 0x5cac1
movl 0xd0(%r14), %r8d
leaq 0x43ec8(%rip), %rsi     # 0x9ee62
leaq 0x43eca(%rip), %rcx     # 0x9ee6b
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x5b66f
leaq 0x6f849(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x2d6f0
jmp 0x5b0a5
leaq 0x6f831(%rip), %rax     # 0xca800
movq 0x58(%rax), %rsi
movq %rbx, %rdi
callq 0x2d6f0
jmp 0x5acac
movq %rbx, %rdi
callq 0x5eeeb
testq %rax, %rax
je 0x5acce
leaq 0x44a48(%rip), %rsi     # 0x9fa40
leaq 0x43fff(%rip), %rcx     # 0x9effe
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x5b66f
movq 0x838db(%rip), %rdi     # 0xde8f0
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
callq 0x225d3
callq 0x5cac1
leaq 0x6f7ce(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2d6f0
xorl %r14d, %r14d
movl $0x3, %esi
movq %rbx, %rdi
callq 0x2ded8
leaq 0x6f79f(%rip), %rax     # 0xca800
xorb $0x1, %r12b
movzbl %r12b, %ecx
movq 0x20(%rax,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x2d6f0
testq %r14, %r14
leaq 0x397b4(%rip), %rsi     # 0x94834
cmovneq %r14, %rsi
movq %rbx, %rdi
callq 0x2ddc1
movq (%rsp), %rsi
movq %rbx, %rdi
callq 0x2dea3
testq %r14, %r14
je 0x5b0a5
movq %r14, %rdi
callq 0x28204
cmpl $0x6, %ebp
jne 0x5acb1
jmp 0x5acce
leaq 0x44889(%rip), %rdi     # 0x9f943
jmp 0x5b0ed
movl 0x30(%rbx), %eax
cmpl $0x3, %eax
setl %cl
testb $0x1, %al
sete %al
orb %cl, %al
jne 0x5acb1
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5f27b
leaq 0x4487d(%rip), %rdi     # 0x9f96a
callq 0x281da
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2d894
jmp 0x5acac
leaq 0x448d6(%rip), %rsi     # 0x9f9df
movq %rbx, %rdi
callq 0x2d9d7
jmp 0x5b0a5
callq 0x1f810
movl (%rax), %eax
cmpl $0x16, %eax
je 0x5b12d
cmpl $0x10, %eax
jne 0x5b136
leaq 0x448d1(%rip), %rsi     # 0x9f9fc
jmp 0x5b109
leaq 0x43f31(%rip), %rsi     # 0x9f065
jmp 0x5b109
leaq 0x448d6(%rip), %rsi     # 0x9fa13
jmp 0x5b109