// File: /workspace/github_c_makefile_star2_O3/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 0x45492(%rip), %rsi     # 0x9f97c
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a603
leaq 0x42946(%rip), %rsi     # 0x9ce47
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a628
leaq 0x4511f(%rip), %rsi     # 0x9f637
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a65a
leaq 0x4539f(%rip), %rsi     # 0x9f8ce
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a67e
leaq 0x4543e(%rip), %rsi     # 0x9f984
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a6a5
leaq 0x42a36(%rip), %rsi     # 0x9cf93
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a739
leaq 0x45427(%rip), %rsi     # 0x9f99b
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a76c
leaq 0x4582f(%rip), %rsi     # 0x9fdba
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a7dd
leaq 0x4548e(%rip), %rsi     # 0x9fa30
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a83e
leaq 0x4491a(%rip), %rsi     # 0x9eed3
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a85c
leaq 0x454d9(%rip), %rsi     # 0x9faa9
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a951
leaq 0x3af47(%rip), %rsi     # 0x9552e
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5a9c7
leaq 0x454bb(%rip), %rsi     # 0x9fab9
jmp 0x5a9e4
cmpl $0x2, 0x30(%rbx)
jne 0x5a9dd
movq 0x842dc(%rip), %rsi     # 0xde8f0
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5e914
cmpl $0x3, 0x30(%rbx)
jne 0x5a9dd
movq %rbx, %rdi
callq 0x5e962
testq %rax, %rax
je 0x5ab20
movq %rbx, %rdi
movq %rax, %rsi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5e27c
cmpl $0x3, 0x30(%rbx)
jne 0x5a9dd
movq %rbx, %rdi
callq 0x5e962
testq %rax, %rax
je 0x5ab20
movq 0xc8(%rax), %rsi
jmp 0x5a614
cmpl $0x3, 0x30(%rbx)
jne 0x5a9dd
movq %rbx, %rdi
callq 0x5e962
testq %rax, %rax
je 0x5ab20
movq 0xc0(%rax), %rsi
jmp 0x5a614
movq $0x0, 0x8(%rsp)
cmpl $0x6, 0x30(%rbx)
jne 0x5a9dd
movq 0x18(%r15), %rsi
movq %rsp, %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x313b2
testl %eax, %eax
jne 0x5ab20
movq 0x38(%rbx), %rax
movq 0x20(%rax), %rsi
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x31355
testl %eax, %eax
jne 0x5ab20
movq 0x841f9(%rip), %rdi     # 0xde8f0
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
movl (%rsp), %edx
xorl %ecx, %ecx
callq 0x5bfdc
movq %rax, %r14
cmpl $0x0, 0x841e1(%rip)     # 0xde8f8
jne 0x5a9fd
testq %r14, %r14
je 0x5a9fd
movl (%r14), %eax
movl %eax, %ecx
notl %ecx
testb $0x11, %cl
setne %bpl
jmp 0x5aa0c
cmpl $0x3, 0x30(%rbx)
jne 0x5a9dd
movq 0x10(%r15), %rax
movq 0x8(%rax), %rdi
movl $0x10000, %esi          # imm = 0x10000
callq 0x5c28c
movslq %eax, %rsi
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2e133
cmpl $0x3, 0x30(%rbx)
jne 0x5a9dd
movq 0x10(%r15), %rax
movq 0x8(%rax), %rdi
callq 0x5c08f
testq %rax, %rax
je 0x5a944
testb $-0x80, (%rax)
je 0x5a7a6
movq 0x158(%rax), %rcx
testq %rcx, %rcx
je 0x5a7a6
cmpl $0x4, 0x130(%rax)
jg 0x5a7a9
movq %rax, %rcx
movq 0x20(%rcx), %r14
movl $0x2, %esi
movq %rbx, %rdi
callq 0x2e168
movq (%r14), %rsi
movq %rbx, %rdi
callq 0x2e051
movslq 0x8(%r14), %rsi
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2e277
cmpl $0x3, 0x30(%rbx)
jne 0x5a9dd
movq %rbx, %rdi
callq 0x5e962
testq %rax, %rax
je 0x5ab20
movq %rax, %r14
testb $-0x80, (%rax)
jne 0x5a9bb
movq %r14, %rdi
callq 0x5eaef
testq %rax, %rax
je 0x5aaa6
movq 0x8(%r14), %rdx
leaq 0x451e6(%rip), %rsi     # 0x9fa06
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movq %r14, %rdi
callq 0x5ec28
orb $0x10, 0x1(%r14)
jmp 0x5a99c
cmpl $0x2, 0x30(%rbx)
jne 0x5a9dd
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5b93b
cmpl $0x6, 0x30(%rbx)
jne 0x5a9dd
movq 0x28(%r15), %rsi
leaq 0x451cf(%rip), %rcx     # 0x9fa40
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
callq 0x313b2
testl %eax, %eax
jne 0x5ab20
movq 0x38(%rbx), %rax
movq 0x20(%rax), %rsi
leaq 0x3eee5(%rip), %rcx     # 0x9977a
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x313b2
testl %eax, %eax
jne 0x5ab20
movq 0x38(%rbx), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rsi
leaq 0x10(%rsp), %rdx
movl $0x20, %ecx
xorl %edi, %edi
callq 0x21788
cmpl $-0x1, %eax
je 0x5ab2d
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rcx
movq 0x18(%rax), %rax
movq 0x8(%rcx), %rdi
movq 0x8(%rax), %rdx
movl (%rsp), %ecx
movl 0x8(%rsp), %r8d
movl $0x1, %esi
xorl %r9d, %r9d
callq 0x5bb77
testq %rax, %rax
je 0x5ab3e
movq %rax, %r14
callq 0x5c4d7
movl 0xd0(%r14), %r8d
leaq 0x445bc(%rip), %rsi     # 0x9eed2
leaq 0x445be(%rip), %rcx     # 0x9eedb
movl $0x3, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x5b0ac
leaq 0x6fecd(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x2d97c
jmp 0x5ab20
leaq 0x6feb5(%rip), %rax     # 0xca800
movq 0x58(%rax), %rsi
jmp 0x5a9a7
movq %rbx, %rdi
callq 0x5e962
testq %rax, %rax
je 0x5ab20
leaq 0x45147(%rip), %rsi     # 0x9fab0
leaq 0x446fe(%rip), %rcx     # 0x9f06e
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x5b0ac
movq 0x83f6a(%rip), %rdi     # 0xde8f0
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rsi
callq 0x22796
callq 0x5c4d7
leaq 0x6fe5d(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2d97c
leaq 0x44ff1(%rip), %rdi     # 0x9f9b3
jmp 0x5aaad
movl 0x30(%rbx), %eax
cmpl $0x3, %eax
setl %cl
testb $0x1, %al
sete %al
orb %cl, %al
je 0x5aa92
leaq 0x450f6(%rip), %rsi     # 0x9fada
movq %rbx, %rdi
movq %r14, %rdx
xorl %eax, %eax
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2dc8a
testq %r14, %r14
je 0x5aac9
movl (%r14), %eax
movb $0x1, %bpl
testb $0x1, %al
je 0x5aa6d
movq 0x38(%rbx), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %r15
leaq 0x39e61(%rip), %rsi     # 0x94884
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5aa6d
movq 0x10(%rsp), %rsi
leaq 0x8(%rsp), %r12
movq %r14, %rdi
movq %r15, %rdx
movq %r12, %rcx
callq 0x5e9a3
movq %rax, %r14
movq (%r12), %r15
movl $0x3, %esi
movq %rbx, %rdi
callq 0x2e168
testb %bpl, %bpl
jne 0x5aadc
leaq 0x6fd99(%rip), %rax     # 0xca800
addq $0x28, %rax
jmp 0x5aae7
movl $0x3, %esi
movq %rbx, %rdi
callq 0x2e168
xorl %r14d, %r14d
testb %bpl, %bpl
jne 0x5aad9
leaq 0x6fd77(%rip), %rax     # 0xca800
addq $0x28, %rax
xorl %r15d, %r15d
jmp 0x5aae7
movq %rbx, %rdi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x5ed09
leaq 0x44f2d(%rip), %rdi     # 0x9f9da
callq 0x28486
movq %rbx, %rdi
movq %rax, %rsi
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2db20
movl $0x3, %esi
movq %rbx, %rdi
callq 0x2e168
xorl %r14d, %r14d
xorl %r15d, %r15d
leaq 0x6fd1d(%rip), %rax     # 0xca800
addq $0x20, %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x2d97c
testq %r14, %r14
leaq 0x39d88(%rip), %rsi     # 0x94884
cmovneq %r14, %rsi
movq %rbx, %rdi
callq 0x2e051
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2e133
testq %r14, %r14
je 0x5ab20
movq %r14, %rdi
callq 0x2850d
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x44f1b(%rip), %rsi     # 0x9fa4f
movq %rbx, %rdi
callq 0x2dc63
jmp 0x5ab20
callq 0x1f810
movl (%rax), %eax
cmpl $0x16, %eax
je 0x5ab58
cmpl $0x10, %eax
jne 0x5ab61
leaq 0x44f16(%rip), %rsi     # 0x9fa6c
jmp 0x5ab34
leaq 0x44576(%rip), %rsi     # 0x9f0d5
jmp 0x5ab34
leaq 0x44f1b(%rip), %rsi     # 0x9fa83
jmp 0x5ab34