// File: /workspace/github_c_makefile_star2_O0/fritzw[P]cube-utils/cube-decoder.c
// Function: main
int main(int argc, char **argv) {
    char cubepro_key[] = "221BBakerMycroft";
    char cubex_key[] = "kWd$qG*25Xmgf-Sg";
    char *userkey = cubepro_key;
    BLOWFISH_KEY key;
    char *infilename, *outfilename;
    size_t outfilesize;
    int i;

    /* TODO:
    Implement flag to enable CubeX encoding?
    Implement decoding of .cubepro/.cubex files?
    Implement legacy mode for compatibility with CodeX:
    argv[0] [CUBEPRO | CUBEX] [ENCODE | DECODE | RECODE] inputfile outputfile
    */

    // "Parse" arguments
    if (argc == 4 && strcmp("-x", argv[1]) == 0) {
        userkey = cubex_key;
        infilename = argv[2];
        outfilename = argv[3];
    } else if (argc == 3) {
        infilename = argv[1];
        outfilename = argv[2];
    } else {
        printf("Usage:\n"
               "    %s [-x] inputfile outputfile\n"
               "    Normally, the inputfile will be decoded as a .cubepro file.\n"
               "    If the file name ends in .cubex or the -x parameter is present,i\n"
               "    it will be decoded as a .cubex file instead.\n",
               argv[0]);
        return 1;
    }

    if (strcmp(infilename + strlen(infilename) - 6, ".cubex") == 0) {
        userkey = cubex_key;
    }

    // Load input file
    FILE *infile = fopen(infilename, "rb");
    if (infile == NULL) {
        perror("Unable to open input file");
        return 2;
    }
    size_t infilesize = fsize(infile);
    if (infilesize < 0) {
        perror("Unable to determine size of input file");
        return 3;
    }
    BYTE *data = malloc(infilesize);
    if (data == NULL) {
        perror("Unable to allocate memory for input file");
        return 4;
    }
    size_t readcount = fread(data, 1, infilesize, infile);
    if (readcount != infilesize) {
        printf("Unable to read the whole input file: %zd != %zd\n", readcount, infilesize);
        return 5;
    }
    fclose(infile);

    // Decrypt data
    blowfish_key_setup((BYTE*) userkey, &key, strlen(userkey));
    for (i = 0; i < infilesize; i += 8) {
        blowfish_decrypt(&data[i], &data[i], &key, 1);
    }

    // Remove padding
    BYTE pad = data[infilesize - 1];
    if (pad > 8) {
        printf("Decoding error: Invalid padding. Make sure that this is a valid encoded file.\n");
        //return 8;
    }
    outfilesize = infilesize - pad;

    // Save data to output file
    FILE *outfile = fopen(outfilename, "wb+");
    if (outfile == NULL) {
        perror("Unable to open output file");
        return 6;
    }
    size_t writecount = fwrite(data, 1, outfilesize, outfile);
    if (writecount != outfilesize) {
        printf("Unable to write the whole output file: %zd != %zd\n", writecount, outfilesize);
        return 7;
    }
    fclose(outfile);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1110, %rsp           # imm = 0x1110
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x1d90(%rip), %rax      # 0x3010
movq %rax, -0x30(%rbp)
movq 0x1d8d(%rip), %rax      # 0x3018
movq %rax, -0x28(%rbp)
movb 0x1d8b(%rip), %al       # 0x3020
movb %al, -0x20(%rbp)
movq 0x1d91(%rip), %rax      # 0x3030
movq %rax, -0x50(%rbp)
movq 0x1d8e(%rip), %rax      # 0x3038
movq %rax, -0x48(%rbp)
movb 0x1d8c(%rip), %al       # 0x3040
movb %al, -0x40(%rbp)
leaq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpl $0x4, -0x8(%rbp)
jne 0x1306
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x1d6d(%rip), %rdi      # 0x3041
callq 0x1080
cmpl $0x0, %eax
jne 0x1306
leaq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x10a8(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x10b0(%rbp)
jmp 0x134f
cmpl $0x3, -0x8(%rbp)
jne 0x132c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10a8(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x10b0(%rbp)
jmp 0x134d
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0x1d0a(%rip), %rdi      # 0x3044
movb $0x0, %al
callq 0x1060
movl $0x1, -0x4(%rbp)
jmp 0x161c
jmp 0x134f
movq -0x10a8(%rbp), %rax
movq %rax, -0x1100(%rbp)
movq -0x10a8(%rbp), %rdi
callq 0x1050
movq -0x1100(%rbp), %rdi
addq %rax, %rdi
addq $-0x6, %rdi
leaq 0x1da5(%rip), %rsi      # 0x3123
callq 0x1080
cmpl $0x0, %eax
jne 0x1390
leaq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x10a8(%rbp), %rdi
leaq 0x1d8c(%rip), %rsi      # 0x312a
callq 0x10d0
movq %rax, -0x10c8(%rbp)
cmpq $0x0, -0x10c8(%rbp)
jne 0x13cc
leaq 0x1d72(%rip), %rdi      # 0x312d
callq 0x10e0
movl $0x2, -0x4(%rbp)
jmp 0x161c
movq -0x10c8(%rbp), %rdi
callq 0x1200
movq %rax, -0x10d0(%rbp)
cmpq $0x0, -0x10d0(%rbp)
jae 0x1401
leaq 0x1d57(%rip), %rdi      # 0x3147
callq 0x10e0
movl $0x3, -0x4(%rbp)
jmp 0x161c
movq -0x10d0(%rbp), %rdi
callq 0x10b0
movq %rax, -0x10d8(%rbp)
cmpq $0x0, -0x10d8(%rbp)
jne 0x1436
leaq 0x1d49(%rip), %rdi      # 0x316e
callq 0x10e0
movl $0x4, -0x4(%rbp)
jmp 0x161c
movq -0x10d8(%rbp), %rdi
movq -0x10d0(%rbp), %rdx
movq -0x10c8(%rbp), %rcx
movl $0x1, %esi
callq 0x1030
movq %rax, -0x10e0(%rbp)
movq -0x10e0(%rbp), %rax
cmpq -0x10d0(%rbp), %rax
je 0x1494
movq -0x10e0(%rbp), %rsi
movq -0x10d0(%rbp), %rdx
leaq 0x1d16(%rip), %rdi      # 0x3197
movb $0x0, %al
callq 0x1060
movl $0x5, -0x4(%rbp)
jmp 0x161c
movq -0x10c8(%rbp), %rdi
callq 0x1040
movq -0x58(%rbp), %rax
movq %rax, -0x1108(%rbp)
movq -0x58(%rbp), %rdi
callq 0x1050
movq -0x1108(%rbp), %rdi
movq %rax, %rdx
leaq -0x10a0(%rbp), %rsi
callq 0x2c90
movl $0x0, -0x10bc(%rbp)
movslq -0x10bc(%rbp), %rax
cmpq -0x10d0(%rbp), %rax
jae 0x1528
movq -0x10d8(%rbp), %rdi
movslq -0x10bc(%rbp), %rax
addq %rax, %rdi
movq -0x10d8(%rbp), %rsi
movslq -0x10bc(%rbp), %rax
addq %rax, %rsi
leaq -0x10a0(%rbp), %rdx
movl $0x1, %ecx
callq 0x2160
movl -0x10bc(%rbp), %eax
addl $0x8, %eax
movl %eax, -0x10bc(%rbp)
jmp 0x14d4
movq -0x10d8(%rbp), %rax
movq -0x10d0(%rbp), %rcx
subq $0x1, %rcx
movb (%rax,%rcx), %al
movb %al, -0x10e1(%rbp)
movzbl -0x10e1(%rbp), %eax
cmpl $0x8, %eax
jle 0x155d
leaq 0x1c72(%rip), %rdi      # 0x31c8
movb $0x0, %al
callq 0x1060
movq -0x10d0(%rbp), %rax
movzbl -0x10e1(%rbp), %ecx
subq %rcx, %rax
movq %rax, -0x10b8(%rbp)
movq -0x10b0(%rbp), %rdi
leaq 0x1c94(%rip), %rsi      # 0x3217
callq 0x10d0
movq %rax, -0x10f0(%rbp)
cmpq $0x0, -0x10f0(%rbp)
jne 0x15ae
leaq 0x1c7b(%rip), %rdi      # 0x321b
callq 0x10e0
movl $0x6, -0x4(%rbp)
jmp 0x161c
movq -0x10d8(%rbp), %rdi
movq -0x10b8(%rbp), %rdx
movq -0x10f0(%rbp), %rcx
movl $0x1, %esi
callq 0x10f0
movq %rax, -0x10f8(%rbp)
movq -0x10f8(%rbp), %rax
cmpq -0x10b8(%rbp), %rax
je 0x1609
movq -0x10f8(%rbp), %rsi
movq -0x10b8(%rbp), %rdx
leaq 0x1c3d(%rip), %rdi      # 0x3236
movb $0x0, %al
callq 0x1060
movl $0x7, -0x4(%rbp)
jmp 0x161c
movq -0x10f0(%rbp), %rdi
callq 0x1040
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1110, %rsp           # imm = 0x1110
popq %rbp
retq
nopl (%rax,%rax)