// File: /workspace/github_c_makefile_star2_O0/gplessis[P]dotdeb-redis/src/redis-check-rdb.c
// Function: redis_check_rdb
int redis_check_rdb(char *rdbfilename) {
    uint64_t dbid;
    int type, rdbver;
    char buf[1024];
    long long expiretime, now = mstime();
    FILE *fp;
    rio rdb;

    if ((fp = fopen(rdbfilename,"r")) == NULL) return C_ERR;

    rioInitWithFile(&rdb,fp);
    rdbstate.rio = &rdb;
    rdb.update_cksum = rdbLoadProgressCallback;
    if (rioRead(&rdb,buf,9) == 0) goto eoferr;
    buf[9] = '\0';
    if (memcmp(buf,"REDIS",5) != 0) {
        rdbCheckError("Wrong signature trying to load DB from file");
        return 1;
    }
    rdbver = atoi(buf+5);
    if (rdbver < 1 || rdbver > RDB_VERSION) {
        rdbCheckError("Can't handle RDB format version %d",rdbver);
        return 1;
    }

    startLoading(fp);
    while(1) {
        robj *key, *val;
        expiretime = -1;

        /* Read type. */
        rdbstate.doing = RDB_CHECK_DOING_READ_TYPE;
        if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;

        /* Handle special types. */
        if (type == RDB_OPCODE_EXPIRETIME) {
            rdbstate.doing = RDB_CHECK_DOING_READ_EXPIRE;
            /* EXPIRETIME: load an expire associated with the next key
             * to load. Note that after loading an expire we need to
             * load the actual type, and continue. */
            if ((expiretime = rdbLoadTime(&rdb)) == -1) goto eoferr;
            /* We read the time so we need to read the object type again. */
            rdbstate.doing = RDB_CHECK_DOING_READ_TYPE;
            if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
            /* the EXPIRETIME opcode specifies time in seconds, so convert
             * into milliseconds. */
            expiretime *= 1000;
        } else if (type == RDB_OPCODE_EXPIRETIME_MS) {
            /* EXPIRETIME_MS: milliseconds precision expire times introduced
             * with RDB v3. Like EXPIRETIME but no with more precision. */
            rdbstate.doing = RDB_CHECK_DOING_READ_EXPIRE;
            if ((expiretime = rdbLoadMillisecondTime(&rdb)) == -1) goto eoferr;
            /* We read the time so we need to read the object type again. */
            rdbstate.doing = RDB_CHECK_DOING_READ_TYPE;
            if ((type = rdbLoadType(&rdb)) == -1) goto eoferr;
        } else if (type == RDB_OPCODE_EOF) {
            /* EOF: End of file, exit the main loop. */
            break;
        } else if (type == RDB_OPCODE_SELECTDB) {
            /* SELECTDB: Select the specified database. */
            rdbstate.doing = RDB_CHECK_DOING_READ_LEN;
            if ((dbid = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
                goto eoferr;
            rdbCheckInfo("Selecting DB ID %d", dbid);
            continue; /* Read type again. */
        } else if (type == RDB_OPCODE_RESIZEDB) {
            /* RESIZEDB: Hint about the size of the keys in the currently
             * selected data base, in order to avoid useless rehashing. */
            uint64_t db_size, expires_size;
            rdbstate.doing = RDB_CHECK_DOING_READ_LEN;
            if ((db_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
                goto eoferr;
            if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
                goto eoferr;
            continue; /* Read type again. */
        } else if (type == RDB_OPCODE_AUX) {
            /* AUX: generic string-string fields. Use to add state to RDB
             * which is backward compatible. Implementations of RDB loading
             * are requierd to skip AUX fields they don't understand.
             *
             * An AUX field is composed of two strings: key and value. */
            robj *auxkey, *auxval;
            rdbstate.doing = RDB_CHECK_DOING_READ_AUX;
            if ((auxkey = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;
            if ((auxval = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;

            rdbCheckInfo("AUX FIELD %s = '%s'",
                (char*)auxkey->ptr, (char*)auxval->ptr);
            decrRefCount(auxkey);
            decrRefCount(auxval);
            continue; /* Read type again. */
        } else {
            if (!rdbIsObjectType(type)) {
                rdbCheckError("Invalid object type: %d", type);
                return 1;
            }
            rdbstate.key_type = type;
        }

        /* Read key */
        rdbstate.doing = RDB_CHECK_DOING_READ_KEY;
        if ((key = rdbLoadStringObject(&rdb)) == NULL) goto eoferr;
        rdbstate.key = key;
        rdbstate.keys++;
        /* Read value */
        rdbstate.doing = RDB_CHECK_DOING_READ_OBJECT_VALUE;
        if ((val = rdbLoadObject(type,&rdb)) == NULL) goto eoferr;
        /* Check if the key already expired. This function is used when loading
         * an RDB file from disk, either at startup, or when an RDB was
         * received from the master. In the latter case, the master is
         * responsible for key expiry. If we would expire keys here, the
         * snapshot taken by the master may not be reflected on the slave. */
        if (server.masterhost == NULL && expiretime != -1 && expiretime < now)
            rdbstate.already_expired++;
        if (expiretime != -1) rdbstate.expires++;
        rdbstate.key = NULL;
        decrRefCount(key);
        decrRefCount(val);
        rdbstate.key_type = -1;
    }
    /* Verify the checksum if RDB version is >= 5 */
    if (rdbver >= 5 && server.rdb_checksum) {
        uint64_t cksum, expected = rdb.cksum;

        rdbstate.doing = RDB_CHECK_DOING_CHECK_SUM;
        if (rioRead(&rdb,&cksum,8) == 0) goto eoferr;
        memrev64ifbe(&cksum);
        if (cksum == 0) {
            rdbCheckInfo("RDB file was saved with checksum disabled: no check performed.");
        } else if (cksum != expected) {
            rdbCheckError("RDB CRC error");
        } else {
            rdbCheckInfo("Checksum OK");
        }
    }

    fclose(fp);
    return 0;

eoferr: /* unexpected end of file is handled here with a fatal exit */
    if (rdbstate.error_set) {
        rdbCheckError(rdbstate.error);
    } else {
        rdbCheckError("Unexpected EOF reading RDB file");
    }
    return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4e0, %rsp            # imm = 0x4E0
movq %rdi, -0x10(%rbp)
callq 0x2ff70
movq %rax, -0x430(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x97723(%rip), %rsi     # 0x13a7c9
callq 0x26ae0
movq %rax, -0x438(%rbp)
cmpq $0x0, %rax
jne 0xa30c4
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa3616
movq -0x438(%rbp), %rsi
leaq -0x4a0(%rbp), %rdi
callq 0x8e620
leaq -0x4a0(%rbp), %rax
movq %rax, 0xea1e3(%rip)     # 0x18d2c8
leaq -0x4cd5c(%rip), %rax    # 0x56390
movq %rax, -0x480(%rbp)
leaq -0x420(%rbp), %rsi
leaq -0x4a0(%rbp), %rdi
movl $0x9, %edx
callq 0xa3630
cmpq $0x0, %rax
jne 0xa3116
jmp 0xa35e4
movb $0x0, -0x417(%rbp)
leaq -0x420(%rbp), %rdi
leaq 0x9a310(%rip), %rsi     # 0x13d43b
movl $0x5, %edx
callq 0x269b0
cmpl $0x0, %eax
je 0xa3154
leaq 0x9a300(%rip), %rdi     # 0x13d441
movb $0x0, %al
callq 0xa2c30
movl $0x1, -0x4(%rbp)
jmp 0xa3616
leaq -0x420(%rbp), %rdi
addq $0x5, %rdi
callq 0x26760
movl %eax, -0x20(%rbp)
cmpl $0x1, -0x20(%rbp)
jl 0xa3173
cmpl $0x7, -0x20(%rbp)
jle 0xa3190
movl -0x20(%rbp), %esi
leaq 0x9a2f0(%rip), %rdi     # 0x13d46d
movb $0x0, %al
callq 0xa2c30
movl $0x1, -0x4(%rbp)
jmp 0xa3616
movq -0x438(%rbp), %rdi
callq 0x56270
movq $-0x1, -0x428(%rbp)
movl $0x1, 0xea147(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x52c30
movl %eax, -0x1c(%rbp)
cmpl $-0x1, %eax
jne 0xa31ca
jmp 0xa35e4
cmpl $0xfd, -0x1c(%rbp)
jne 0xa3235
movl $0x2, 0xea11b(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x52d50
movq %rax, -0x428(%rbp)
cmpq $-0x1, %rax
jne 0xa31fb
jmp 0xa35e4
movl $0x1, 0xea0f3(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x52c30
movl %eax, -0x1c(%rbp)
cmpl $-0x1, %eax
jne 0xa321e
jmp 0xa35e4
imulq $0x3e8, -0x428(%rbp), %rax # imm = 0x3E8
movq %rax, -0x428(%rbp)
jmp 0xa342f
cmpl $0xfc, -0x1c(%rbp)
jne 0xa328e
movl $0x2, 0xea0b0(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x52dc0
movq %rax, -0x428(%rbp)
cmpq $-0x1, %rax
jne 0xa3266
jmp 0xa35e4
movl $0x1, 0xea088(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x52c30
movl %eax, -0x1c(%rbp)
cmpl $-0x1, %eax
jne 0xa3289
jmp 0xa35e4
jmp 0xa342d
cmpl $0xff, -0x1c(%rbp)
jne 0xa329c
jmp 0xa352d
cmpl $0xfe, -0x1c(%rbp)
jne 0xa32eb
movl $0x6, 0xea049(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x52f10
movl %eax, %eax
movq %rax, -0x18(%rbp)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
jne 0xa32d4
jmp 0xa35e4
movq -0x18(%rbp), %rsi
leaq 0xa5fa6(%rip), %rdi     # 0x149285
movb $0x0, %al
callq 0xa2e00
jmp 0xa319c
cmpl $0xfb, -0x1c(%rbp)
jne 0xa3353
movl $0x6, 0xe9ffa(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x52f10
movl %eax, %eax
movq %rax, -0x4b8(%rbp)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
jne 0xa3326
jmp 0xa35e4
leaq -0x4a0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x52f10
movl %eax, %eax
movq %rax, -0x4c0(%rbp)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
jne 0xa334e
jmp 0xa35e4
jmp 0xa319c
cmpl $0xfa, -0x1c(%rbp)
jne 0xa33e7
movl $0x7, 0xe9f8e(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x53be0
movq %rax, -0x4c8(%rbp)
cmpq $0x0, %rax
jne 0xa3388
jmp 0xa35e4
leaq -0x4a0(%rbp), %rdi
callq 0x53be0
movq %rax, -0x4d0(%rbp)
cmpq $0x0, %rax
jne 0xa33a6
jmp 0xa35e4
movq -0x4c8(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x4d0(%rbp), %rax
movq 0x8(%rax), %rdx
leaq 0xa5ed5(%rip), %rdi     # 0x149298
movb $0x0, %al
callq 0xa2e00
movq -0x4c8(%rbp), %rdi
callq 0x48f70
movq -0x4d0(%rbp), %rdi
callq 0x48f70
jmp 0xa319c
cmpl $0x0, -0x1c(%rbp)
jl 0xa33f3
cmpl $0x4, -0x1c(%rbp)
jle 0xa341c
cmpl $0x9, -0x1c(%rbp)
jl 0xa33ff
cmpl $0xe, -0x1c(%rbp)
jle 0xa341c
movl -0x1c(%rbp), %esi
leaq 0xa5ea3(%rip), %rdi     # 0x1492ac
movb $0x0, %al
callq 0xa2c30
movl $0x1, -0x4(%rbp)
jmp 0xa3616
movl -0x1c(%rbp), %eax
movl %eax, 0xe9eb3(%rip)     # 0x18d2d8
jmp 0xa3427
jmp 0xa3429
jmp 0xa342b
jmp 0xa342d
jmp 0xa342f
movl $0x3, 0xe9ebf(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
callq 0x53be0
movq %rax, -0x4a8(%rbp)
cmpq $0x0, %rax
jne 0xa3457
jmp 0xa35e4
movq -0x4a8(%rbp), %rax
movq %rax, 0xe9e6b(%rip)     # 0x18d2d0
movq 0xe9e74(%rip), %rax     # 0x18d2e0
addq $0x1, %rax
movq %rax, 0xe9e69(%rip)     # 0x18d2e0
movl $0x4, 0xe9e77(%rip)     # 0x18d2f8
movl -0x1c(%rbp), %edi
leaq -0x4a0(%rbp), %rsi
callq 0x55630
movq %rax, -0x4b0(%rbp)
cmpq $0x0, %rax
jne 0xa34a2
jmp 0xa35e4
leaq 0xd4d2f(%rip), %rax     # 0x1781d8
cmpq $0x0, 0x828(%rax)
jne 0xa34df
cmpq $-0x1, -0x428(%rbp)
je 0xa34df
movq -0x428(%rbp), %rax
cmpq -0x430(%rbp), %rax
jge 0xa34df
movq 0xe9e1c(%rip), %rax     # 0x18d2f0
addq $0x1, %rax
movq %rax, 0xe9e11(%rip)     # 0x18d2f0
cmpq $-0x1, -0x428(%rbp)
je 0xa34fb
movq 0xe9df8(%rip), %rax     # 0x18d2e8
addq $0x1, %rax
movq %rax, 0xe9ded(%rip)     # 0x18d2e8
movq $0x0, 0xe9dca(%rip) # 0x18d2d0
movq -0x4a8(%rbp), %rdi
callq 0x48f70
movq -0x4b0(%rbp), %rdi
callq 0x48f70
movl $0xffffffff, 0xe9db0(%rip) # imm = 0xFFFFFFFF
jmp 0xa319c
cmpl $0x5, -0x20(%rbp)
jl 0xa35cf
leaq 0xd4c9a(%rip), %rax     # 0x1781d8
cmpl $0x0, 0x754(%rax)
je 0xa35cf
movq -0x478(%rbp), %rax
movq %rax, -0x4e0(%rbp)
movl $0x5, 0xe9d95(%rip)     # 0x18d2f8
leaq -0x4a0(%rbp), %rdi
leaq -0x4d8(%rbp), %rsi
movl $0x8, %edx
callq 0xa3630
cmpq $0x0, %rax
jne 0xa3583
jmp 0xa35e4
cmpq $0x0, -0x4d8(%rbp)
jne 0xa359d
leaq 0x99f91(%rip), %rdi     # 0x13d525
movb $0x0, %al
callq 0xa2e00
jmp 0xa35cd
movq -0x4d8(%rbp), %rax
cmpq -0x4e0(%rbp), %rax
je 0xa35bd
leaq 0x99fd2(%rip), %rdi     # 0x13d586
movb $0x0, %al
callq 0xa2c30
jmp 0xa35cb
leaq 0xa5d00(%rip), %rdi     # 0x1492c4
movb $0x0, %al
callq 0xa2e00
jmp 0xa35cd
jmp 0xa35cf
movq -0x438(%rbp), %rdi
callq 0x26a10
movl $0x0, -0x4(%rbp)
jmp 0xa3616
cmpl $0x0, 0xe9d11(%rip)     # 0x18d2fc
je 0xa3601
leaq 0xe9cd4(%rip), %rdi     # 0x18d2c8
addq $0x38, %rdi
movb $0x0, %al
callq 0xa2c30
jmp 0xa360f
leaq 0x99fcd(%rip), %rdi     # 0x13d5d5
movb $0x0, %al
callq 0xa2c30
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x4e0, %rsp            # imm = 0x4E0
popq %rbp
retq
nopw %cs:(%rax,%rax)