// File: /workspace/github_c_makefile_star2_O2/gplessis[P]dotdeb-redis/src/replication.c
// Function: syncWithMaster
void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
    char tmpfile[256], *err = NULL;
    int dfd = -1, maxtries = 5;
    int sockerr = 0, psync_result;
    socklen_t errlen = sizeof(sockerr);
    UNUSED(el);
    UNUSED(privdata);
    UNUSED(mask);

    /* If this event fired after the user turned the instance into a master
     * with SLAVEOF NO ONE we must just return ASAP. */
    if (server.repl_state == REPL_STATE_NONE) {
        close(fd);
        return;
    }

    /* Check for errors in the socket. */
    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1)
        sockerr = errno;
    if (sockerr) {
        serverLog(LL_WARNING,"Error condition on socket for SYNC: %s",
            strerror(sockerr));
        goto error;
    }

    /* Send a PING to check the master is able to reply without errors. */
    if (server.repl_state == REPL_STATE_CONNECTING) {
        serverLog(LL_NOTICE,"Non blocking connect for SYNC fired the event.");
        /* Delete the writable event so that the readable event remains
         * registered and we can wait for the PONG reply. */
        aeDeleteFileEvent(server.el,fd,AE_WRITABLE);
        server.repl_state = REPL_STATE_RECEIVE_PONG;
        /* Send the PING, don't check for errors at all, we have the timeout
         * that will take care about this. */
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"PING",NULL);
        if (err) goto write_error;
        return;
    }

    /* Receive the PONG command. */
    if (server.repl_state == REPL_STATE_RECEIVE_PONG) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);

        /* We accept only two replies as valid, a positive +PONG reply
         * (we just check for "+") or an authentication error.
         * Note that older versions of Redis replied with "operation not
         * permitted" instead of using a proper error code, so we test
         * both. */
        if (err[0] != '+' &&
            strncmp(err,"-NOAUTH",7) != 0 &&
            strncmp(err,"-ERR operation not permitted",28) != 0)
        {
            serverLog(LL_WARNING,"Error reply to PING from master: '%s'",err);
            sdsfree(err);
            goto error;
        } else {
            serverLog(LL_NOTICE,
                "Master replied to PING, replication can continue...");
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_AUTH;
    }

    /* AUTH with the master if required. */
    if (server.repl_state == REPL_STATE_SEND_AUTH) {
        if (server.masterauth) {
            err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"AUTH",server.masterauth,NULL);
            if (err) goto write_error;
            server.repl_state = REPL_STATE_RECEIVE_AUTH;
            return;
        } else {
            server.repl_state = REPL_STATE_SEND_PORT;
        }
    }

    /* Receive AUTH reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_AUTH) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        if (err[0] == '-') {
            serverLog(LL_WARNING,"Unable to AUTH to MASTER: %s",err);
            sdsfree(err);
            goto error;
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_PORT;
    }

    /* Set the slave port, so that Master's INFO command can list the
     * slave listening port correctly. */
    if (server.repl_state == REPL_STATE_SEND_PORT) {
        sds port = sdsfromlonglong(server.slave_announce_port ?
            server.slave_announce_port : server.port);
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"REPLCONF",
                "listening-port",port, NULL);
        sdsfree(port);
        if (err) goto write_error;
        sdsfree(err);
        server.repl_state = REPL_STATE_RECEIVE_PORT;
        return;
    }

    /* Receive REPLCONF listening-port reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_PORT) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        /* Ignore the error if any, not all the Redis versions support
         * REPLCONF listening-port. */
        if (err[0] == '-') {
            serverLog(LL_NOTICE,"(Non critical) Master does not understand "
                                "REPLCONF listening-port: %s", err);
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_IP;
    }

    /* Skip REPLCONF ip-address if there is no slave-announce-ip option set. */
    if (server.repl_state == REPL_STATE_SEND_IP &&
        server.slave_announce_ip == NULL)
    {
            server.repl_state = REPL_STATE_SEND_CAPA;
    }

    /* Set the slave ip, so that Master's INFO command can list the
     * slave IP address port correctly in case of port forwarding or NAT. */
    if (server.repl_state == REPL_STATE_SEND_IP) {
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"REPLCONF",
                "ip-address",server.slave_announce_ip, NULL);
        if (err) goto write_error;
        sdsfree(err);
        server.repl_state = REPL_STATE_RECEIVE_IP;
        return;
    }

    /* Receive REPLCONF ip-address reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_IP) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        /* Ignore the error if any, not all the Redis versions support
         * REPLCONF listening-port. */
        if (err[0] == '-') {
            serverLog(LL_NOTICE,"(Non critical) Master does not understand "
                                "REPLCONF ip-address: %s", err);
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_CAPA;
    }

    /* Inform the master of our capabilities. While we currently send
     * just one capability, it is possible to chain new capabilities here
     * in the form of REPLCONF capa X capa Y capa Z ...
     * The master will ignore capabilities it does not understand. */
    if (server.repl_state == REPL_STATE_SEND_CAPA) {
        err = sendSynchronousCommand(SYNC_CMD_WRITE,fd,"REPLCONF",
                "capa","eof",NULL);
        if (err) goto write_error;
        sdsfree(err);
        server.repl_state = REPL_STATE_RECEIVE_CAPA;
        return;
    }

    /* Receive CAPA reply. */
    if (server.repl_state == REPL_STATE_RECEIVE_CAPA) {
        err = sendSynchronousCommand(SYNC_CMD_READ,fd,NULL);
        /* Ignore the error if any, not all the Redis versions support
         * REPLCONF capa. */
        if (err[0] == '-') {
            serverLog(LL_NOTICE,"(Non critical) Master does not understand "
                                  "REPLCONF capa: %s", err);
        }
        sdsfree(err);
        server.repl_state = REPL_STATE_SEND_PSYNC;
    }

    /* Try a partial resynchonization. If we don't have a cached master
     * slaveTryPartialResynchronization() will at least try to use PSYNC
     * to start a full resynchronization so that we get the master run id
     * and the global offset, to try a partial resync at the next
     * reconnection attempt. */
    if (server.repl_state == REPL_STATE_SEND_PSYNC) {
        if (slaveTryPartialResynchronization(fd,0) == PSYNC_WRITE_ERROR) {
            err = sdsnew("Write error sending the PSYNC command.");
            goto write_error;
        }
        server.repl_state = REPL_STATE_RECEIVE_PSYNC;
        return;
    }

    /* If reached this point, we should be in REPL_STATE_RECEIVE_PSYNC. */
    if (server.repl_state != REPL_STATE_RECEIVE_PSYNC) {
        serverLog(LL_WARNING,"syncWithMaster(): state machine error, "
                             "state should be RECEIVE_PSYNC but is %d",
                             server.repl_state);
        goto error;
    }

    psync_result = slaveTryPartialResynchronization(fd,1);
    if (psync_result == PSYNC_WAIT_REPLY) return; /* Try again later... */

    /* Note: if PSYNC does not return WAIT_REPLY, it will take care of
     * uninstalling the read handler from the file descriptor. */

    if (psync_result == PSYNC_CONTINUE) {
        serverLog(LL_NOTICE, "MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.");
        return;
    }

    /* PSYNC failed or is not supported: we want our slaves to resync with us
     * as well, if we have any (chained replication case). The mater may
     * transfer us an entirely different data set and we have no way to
     * incrementally feed our slaves after that. */
    disconnectSlaves(); /* Force our slaves to resync with us as well. */
    freeReplicationBacklog(); /* Don't allow our chained slaves to PSYNC. */

    /* Fall back to SYNC if needed. Otherwise psync_result == PSYNC_FULLRESYNC
     * and the server.repl_master_runid and repl_master_initial_offset are
     * already populated. */
    if (psync_result == PSYNC_NOT_SUPPORTED) {
        serverLog(LL_NOTICE,"Retrying with SYNC...");
        if (syncWrite(fd,"SYNC\r\n",6,server.repl_syncio_timeout*1000) == -1) {
            serverLog(LL_WARNING,"I/O error writing to MASTER: %s",
                strerror(errno));
            goto error;
        }
    }

    /* Prepare a suitable temp file for bulk transfer */
    while(maxtries--) {
        snprintf(tmpfile,256,
            "temp-%d.%ld.rdb",(int)server.unixtime,(long int)getpid());
        dfd = open(tmpfile,O_CREAT|O_WRONLY|O_EXCL,0644);
        if (dfd != -1) break;
        sleep(1);
    }
    if (dfd == -1) {
        serverLog(LL_WARNING,"Opening the temp file needed for MASTER <-> SLAVE synchronization: %s",strerror(errno));
        goto error;
    }

    /* Setup the non blocking download of the bulk file. */
    if (aeCreateFileEvent(server.el,fd, AE_READABLE,readSyncBulkPayload,NULL)
            == AE_ERR)
    {
        serverLog(LL_WARNING,
            "Can't create readable event for SYNC: %s (fd=%d)",
            strerror(errno),fd);
        goto error;
    }

    server.repl_state = REPL_STATE_TRANSFER;
    server.repl_transfer_size = -1;
    server.repl_transfer_read = 0;
    server.repl_transfer_last_fsync_off = 0;
    server.repl_transfer_fd = dfd;
    server.repl_transfer_lastio = server.unixtime;
    server.repl_transfer_tmpfile = zstrdup(tmpfile);
    return;

error:
    aeDeleteFileEvent(server.el,fd,AE_READABLE|AE_WRITABLE);
    if (dfd != -1) close(dfd);
    close(fd);
    server.repl_transfer_s = -1;
    server.repl_state = REPL_STATE_CONNECT;
    return;

write_error: /* Handle sendSynchronousCommand(SYNC_CMD_WRITE) errors. */
    serverLog(LL_WARNING,"Sending command to master in replication handshake: %s", err);
    sdsfree(err);
    goto error;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %esi, %ebx
andl $0x0, 0x8(%rsp)
movl $0x4, 0xc(%rsp)
leaq 0xba97a(%rip), %r13     # 0xf98a8
cmpl $0x0, 0x84c(%r13)
je 0x3ef5a
pushq $0x1
popq %rsi
pushq $0x4
popq %rdx
leaq 0x8(%rsp), %rcx
leaq 0xc(%rsp), %r8
movl %ebx, %edi
callq 0x26700
cmpl $-0x1, %eax
je 0x3ef72
movl 0x8(%rsp), %edi
jmp 0x3ef7d
movl %ebx, %edi
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x26180
callq 0x26880
movl (%rax), %edi
movl %edi, 0x8(%rsp)
testl %edi, %edi
je 0x3ef9f
callq 0x26680
leaq 0x747de(%rip), %rsi     # 0xb376b
pushq $0x3
popq %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2b699
jmp 0x3f25a
movl 0x84c(%r13), %edx
leal -0x2(%rdx), %eax
cmpl $0x5, %eax
ja 0x3f0cf
leaq 0x7395f(%rip), %rcx     # 0xb2918
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x747c9(%rip), %rsi     # 0xb3792
pushq $0x2
popq %rbp
movl %ebp, %edi
xorl %eax, %eax
callq 0x2b699
movq 0x40(%r13), %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x28ba8
movl $0x3, 0x84c(%r13)
leaq 0x747cd(%rip), %rdx     # 0xb37c1
movl %ebp, %edi
movl %ebx, %esi
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x3e8bf
testq %rax, %rax
jne 0x3f1d9
jmp 0x3f291
pushq $0x1
popq %rdi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3e8bf
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x3f1de
leaq 0x74815(%rip), %rsi     # 0xb3845
jmp 0x3f245
pushq $0x1
popq %rdi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3e8bf
movq %rax, %r14
cmpb $0x2b, (%rax)
je 0x3f18a
leaq 0x74770(%rip), %rsi     # 0xb37c6
pushq $0x7
popq %rdx
movq %r14, %rdi
callq 0x26350
testl %eax, %eax
je 0x3f18a
leaq 0x7475e(%rip), %rsi     # 0xb37ce
pushq $0x1c
popq %rdx
movq %r14, %rdi
callq 0x26350
testl %eax, %eax
je 0x3f18a
leaq 0x74761(%rip), %rsi     # 0xb37eb
jmp 0x3f245
pushq $0x1
popq %rdi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3e8bf
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x3f0b9
leaq 0x747b6(%rip), %rsi     # 0xb3862
pushq $0x2
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x2b699
movq %r14, %rdi
callq 0x311c8
movl $0x8, 0x84c(%r13)
pushq $0x8
popq %rdx
cmpl $0x8, %edx
sete %al
movq 0x8a0(%r13), %r8
testq %r8, %r8
sete %cl
testb %cl, %al
je 0x3f135
movl $0xa, 0x84c(%r13)
leaq 0x6f9e3(%rip), %rdx     # 0xaeadb
leaq 0x73ea3(%rip), %rcx     # 0xb2fa2
leaq 0x6f68f(%rip), %r8      # 0xae795
pushq $0x2
popq %rdi
movl %ebx, %esi
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x3e8bf
testq %rax, %rax
jne 0x3f1d9
xorl %edi, %edi
callq 0x311c8
movl $0xb, 0x84c(%r13)
jmp 0x3f291
leal -0x8(%rdx), %eax
cmpl $0x5, %eax
ja 0x3f389
leaq 0x737e8(%rip), %rcx     # 0xb2930
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x6f983(%rip), %rdx     # 0xaeadb
leaq 0x73df2(%rip), %rcx     # 0xb2f51
pushq $0x2
popq %rdi
movl %ebx, %esi
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x3e8bf
testq %rax, %rax
jne 0x3f1d9
xorl %edi, %edi
callq 0x311c8
movl $0x9, 0x84c(%r13)
jmp 0x3f291
leaq 0x74680(%rip), %rsi     # 0xb3811
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x2b699
movq %r14, %rdi
callq 0x311c8
movl $0x4, 0x84c(%r13)
movq 0x820(%r13), %rcx
testq %rcx, %rcx
je 0x3f1e6
leaq 0x74608(%rip), %rdx     # 0xb37c9
pushq $0x2
popq %rdi
movl %ebx, %esi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x3e8bf
testq %rax, %rax
je 0x3f2b7
movq %rax, %r14
jmp 0x3f23e
movq %r14, %rdi
callq 0x311c8
movl $0x6, 0x84c(%r13)
movl 0x898(%r13), %eax
testl %eax, %eax
jne 0x3f203
movl 0xa0(%r13), %eax
movslq %eax, %rdi
callq 0x31930
movq %rax, %r15
leaq 0x6f8c6(%rip), %rdx     # 0xaeadb
leaq 0x73d26(%rip), %rcx     # 0xb2f42
pushq $0x2
popq %rdi
movl %ebx, %esi
movq %rax, %r8
xorl %r9d, %r9d
xorl %eax, %eax
callq 0x3e8bf
movq %rax, %r14
movq %r15, %rdi
callq 0x311c8
testq %r14, %r14
je 0x3f2a3
leaq 0x7485f(%rip), %rsi     # 0xb3aa4
pushq $0x3
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x2b699
movq %r14, %rdi
callq 0x311c8
pushq $-0x1
popq %rbp
movq 0x40(%r13), %rdi
pushq $0x3
popq %rdx
movl %ebx, %esi
callq 0x28ba8
cmpl $-0x1, %ebp
je 0x3f277
movl %ebp, %edi
callq 0x26180
movl %ebx, %edi
callq 0x26180
orl $-0x1, 0x868(%r13)
movl $0x1, 0x84c(%r13)
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edi, %edi
callq 0x311c8
movl $0x7, 0x84c(%r13)
jmp 0x3f291
movl $0x5, 0x84c(%r13)
jmp 0x3f291
pushq $0x1
popq %rdi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3e8bf
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x3f2ee
leaq 0x74609(%rip), %rsi     # 0xb38ea
pushq $0x2
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x2b699
movq %r14, %rdi
callq 0x311c8
movl $0xc, 0x84c(%r13)
movl %ebx, %edi
xorl %esi, %esi
callq 0x3ead0
testl %eax, %eax
je 0x3f39f
movl $0xd, 0x84c(%r13)
jmp 0x3f291
pushq $0x1
popq %rdi
movl %ebx, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3e8bf
movq %rax, %r14
cmpb $0x2d, (%rax)
jne 0x3f34c
leaq 0x74569(%rip), %rsi     # 0xb38a8
pushq $0x2
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x2b699
movq %r14, %rdi
callq 0x311c8
jmp 0x3f0e6
pushq $0x1
popq %rsi
movl %ebx, %edi
callq 0x3ead0
cmpl $0x1, %eax
je 0x3f291
movl %eax, %ebp
cmpl $0x2, %eax
jne 0x3f3b0
leaq 0x74622(%rip), %rsi     # 0xb399c
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x2b699
jmp 0x3f291
leaq 0x745bd(%rip), %rsi     # 0xb394d
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0x2b699
jmp 0x3f25a
leaq 0x74580(%rip), %rdi     # 0xb3926
callq 0x3115a
jmp 0x3f1d9
callq 0x37501
callq 0x3cdc1
cmpl $0x4, %ebp
jne 0x3f3f9
leaq 0x7461a(%rip), %rsi     # 0xb39e0
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x2b699
movslq 0x848(%r13), %rax
imulq $0x3e8, %rax, %rcx      # imm = 0x3E8
leaq 0x74611(%rip), %rsi     # 0xb39f6
pushq $0x6
popq %rdx
movl %ebx, %edi
callq 0x5a9e8
cmpq $-0x1, %rax
je 0x3f4d8
pushq $-0x5
popq %r14
leaq 0x10(%rsp), %r15
pushq $0x1
popq %r12
testl %r14d, %r14d
je 0x3f458
movl 0x978(%r13), %ebp
callq 0x26420
movslq %eax, %r8
movl $0x100, %esi            # imm = 0x100
movq %r15, %rdi
leaq 0x745f4(%rip), %rdx     # 0xb3a1d
movl %ebp, %ecx
xorl %eax, %eax
callq 0x26120
movq %r15, %rdi
movl $0xc1, %esi
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x26690
cmpl $-0x1, %eax
jne 0x3f470
movl %r12d, %edi
callq 0x265f0
incl %r14d
jmp 0x3f406
callq 0x26880
movl (%rax), %edi
callq 0x26680
leaq 0x745c2(%rip), %rsi     # 0xb3a2d
jmp 0x3ef8d
movl %eax, %ebp
movq 0x40(%r13), %rdi
leaq -0x110f(%rip), %rcx     # 0x3e36e
pushq $0x1
popq %rdx
movl %ebx, %esi
xorl %r8d, %r8d
callq 0x28ae8
cmpl $-0x1, %eax
je 0x3f4f0
movl $0xe, 0x84c(%r13)
orq $-0x1, 0x850(%r13)
xorps %xmm0, %xmm0
movups %xmm0, 0x858(%r13)
movl %ebp, 0x86c(%r13)
movq 0x978(%r13), %rax
movq %rax, 0x878(%r13)
leaq 0x10(%rsp), %rdi
callq 0x32933
movq %rax, 0x870(%r13)
jmp 0x3f291
callq 0x26880
movl (%rax), %edi
callq 0x26680
leaq 0x74512(%rip), %rsi     # 0xb39fd
jmp 0x3ef8d
callq 0x26880
movl (%rax), %edi
callq 0x26680
leaq 0x74570(%rip), %rsi     # 0xb3a73
pushq $0x3
popq %rdi
movq %rax, %rdx
movl %ebx, %ecx
xorl %eax, %eax
callq 0x2b699
jmp 0x3f25d