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

    /* TODO:
	This whole code is a mess that was hacked together quickly. Clean it up!
    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
    */
    
	for (executable = argv[0]; *executable; ++executable) {
		*executable = tolower(*executable);
	}
	executable = argv[0];
    if (ends_with(executable, "cubex-encoder") ||
		ends_with(executable, "cubex-encoder.exe")) {
        userkey = cubex_key;
        extension = ".cubex";
    } else if (ends_with(executable, "cube3-encoder") ||
		ends_with(executable, "cube3-encoder.exe")) {
        extension = ".cube3";
    }

    // "Parse" arguments
    if (argc == 2) {
        infilename = argv[1];
        size_t inlength = strlen(infilename);
        outfilename = malloc(inlength + 10);
        if (outfilename == NULL) {
            perror("Unable to allocate memory for output file name");
            return 4;
        }
        strncpy(outfilename, infilename, inlength);
        if (strncmp(outfilename + inlength - 4, ".bfb", 4) == 0) {
            strcpy(outfilename + inlength - 4, extension);
        } else {
            strcpy(outfilename + inlength, extension);
        }
    } else if (argc == 3) {
        infilename = argv[1];
        outfilename = argv[2];
    } else {
        printf("Usage:\n"
               "    %s inputfile [outputfile]\n"
               "    Default outputfile is inputfile minus the .bfb extension plus %s\n",
               argv[0], extension);
        return 1;
    }


    // 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;
    }
    size_t outfilesize = ((infilesize + 8) / 8) * 8;
    BYTE *data = malloc(outfilesize);
    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);

    // Pad input data
    BYTE pad = outfilesize - infilesize;
    for (i = infilesize; i < outfilesize; i++) {
        data[i] = pad;
    }

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


    // 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 $0x1120, %rsp           # imm = 0x1120
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x2ce0(%rip), %rax      # 0x4010
movq %rax, -0x30(%rbp)
movq 0x2cdd(%rip), %rax      # 0x4018
movq %rax, -0x28(%rbp)
movb 0x2cdb(%rip), %al       # 0x4020
movb %al, -0x20(%rbp)
movq 0x2ce1(%rip), %rax      # 0x4030
movq %rax, -0x50(%rbp)
movq 0x2cde(%rip), %rax      # 0x4038
movq %rax, -0x48(%rbp)
movb 0x2cdc(%rip), %al       # 0x4040
movb %al, -0x40(%rbp)
leaq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq 0x2ccb(%rip), %rax      # 0x4041
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10c8(%rbp)
movq -0x10c8(%rbp), %rax
cmpb $0x0, (%rax)
je 0x13c2
movq -0x10c8(%rbp), %rax
movsbl (%rax), %edi
callq 0x10d0
movb %al, %cl
movq -0x10c8(%rbp), %rax
movb %cl, (%rax)
movq -0x10c8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10c8(%rbp)
jmp 0x1388
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10c8(%rbp)
movq -0x10c8(%rbp), %rdi
leaq 0x2c6c(%rip), %rsi      # 0x404a
callq 0x1290
cmpl $0x0, %eax
jne 0x1400
movq -0x10c8(%rbp), %rdi
leaq 0x2c62(%rip), %rsi      # 0x4058
callq 0x1290
cmpl $0x0, %eax
je 0x1415
leaq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq 0x2c5b(%rip), %rax      # 0x406a
movq %rax, -0x60(%rbp)
jmp 0x1452
movq -0x10c8(%rbp), %rdi
leaq 0x2c4e(%rip), %rsi      # 0x4071
callq 0x1290
cmpl $0x0, %eax
jne 0x1445
movq -0x10c8(%rbp), %rdi
leaq 0x2c44(%rip), %rsi      # 0x407f
callq 0x1290
cmpl $0x0, %eax
je 0x1450
leaq 0x2c45(%rip), %rax      # 0x4091
movq %rax, -0x60(%rbp)
jmp 0x1452
cmpl $0x2, -0x8(%rbp)
jne 0x152f
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10b0(%rbp)
movq -0x10b0(%rbp), %rdi
callq 0x1080
movq %rax, -0x10d0(%rbp)
movq -0x10d0(%rbp), %rdi
addq $0xa, %rdi
callq 0x10e0
movq %rax, -0x10b8(%rbp)
cmpq $0x0, -0x10b8(%rbp)
jne 0x14b7
leaq 0x2bf2(%rip), %rdi      # 0x4098
callq 0x1110
movl $0x4, -0x4(%rbp)
jmp 0x182e
movq -0x10b8(%rbp), %rdi
movq -0x10b0(%rbp), %rsi
movq -0x10d0(%rbp), %rdx
callq 0x1030
movq -0x10b8(%rbp), %rdi
addq -0x10d0(%rbp), %rdi
addq $-0x4, %rdi
leaq 0x2bdd(%rip), %rsi      # 0x40c7
movl $0x4, %edx
callq 0x1040
cmpl $0x0, %eax
jne 0x1516
movq -0x10b8(%rbp), %rdi
addq -0x10d0(%rbp), %rdi
addq $-0x4, %rdi
movq -0x60(%rbp), %rsi
callq 0x1050
jmp 0x152d
movq -0x10b8(%rbp), %rdi
addq -0x10d0(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x1050
jmp 0x157c
cmpl $0x3, -0x8(%rbp)
jne 0x1555
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10b0(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x10b8(%rbp)
jmp 0x157a
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movq -0x60(%rbp), %rdx
leaq 0x2b65(%rip), %rdi      # 0x40cc
movb $0x0, %al
callq 0x1090
movl $0x1, -0x4(%rbp)
jmp 0x182e
jmp 0x157c
movq -0x10b0(%rbp), %rdi
leaq 0x2bad(%rip), %rsi      # 0x4137
callq 0x1100
movq %rax, -0x10d8(%rbp)
cmpq $0x0, -0x10d8(%rbp)
jne 0x15b8
leaq 0x2b93(%rip), %rdi      # 0x413a
callq 0x1110
movl $0x2, -0x4(%rbp)
jmp 0x182e
movq -0x10d8(%rbp), %rdi
callq 0x1230
movq %rax, -0x10e0(%rbp)
cmpq $0x0, -0x10e0(%rbp)
jae 0x15ed
leaq 0x2b78(%rip), %rdi      # 0x4154
callq 0x1110
movl $0x3, -0x4(%rbp)
jmp 0x182e
movq -0x10e0(%rbp), %rax
addq $0x8, %rax
shrq $0x3, %rax
shlq $0x3, %rax
movq %rax, -0x10e8(%rbp)
movq -0x10e8(%rbp), %rdi
callq 0x10e0
movq %rax, -0x10f0(%rbp)
cmpq $0x0, -0x10f0(%rbp)
jne 0x163c
leaq 0x2b50(%rip), %rdi      # 0x417b
callq 0x1110
movl $0x4, -0x4(%rbp)
jmp 0x182e
movq -0x10f0(%rbp), %rdi
movq -0x10e0(%rbp), %rdx
movq -0x10d8(%rbp), %rcx
movl $0x1, %esi
callq 0x1060
movq %rax, -0x10f8(%rbp)
movq -0x10f8(%rbp), %rax
cmpq -0x10e0(%rbp), %rax
je 0x169a
movq -0x10f8(%rbp), %rsi
movq -0x10e0(%rbp), %rdx
leaq 0x2b1d(%rip), %rdi      # 0x41a4
movb $0x0, %al
callq 0x1090
movl $0x5, -0x4(%rbp)
jmp 0x182e
movq -0x10d8(%rbp), %rdi
callq 0x1070
movq -0x10e8(%rbp), %rax
subq -0x10e0(%rbp), %rax
movb %al, -0x10f9(%rbp)
movq -0x10e0(%rbp), %rax
movl %eax, -0x10bc(%rbp)
movslq -0x10bc(%rbp), %rax
cmpq -0x10e8(%rbp), %rax
jae 0x16ff
movb -0x10f9(%rbp), %dl
movq -0x10f0(%rbp), %rax
movslq -0x10bc(%rbp), %rcx
movb %dl, (%rax,%rcx)
movl -0x10bc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10bc(%rbp)
jmp 0x16c7
movq -0x58(%rbp), %rax
movq %rax, -0x1118(%rbp)
movq -0x58(%rbp), %rdi
callq 0x1080
movq -0x1118(%rbp), %rdi
movq %rax, %rdx
leaq -0x10a8(%rbp), %rsi
callq 0x2ea0
movl $0x0, -0x10bc(%rbp)
movslq -0x10bc(%rbp), %rax
cmpq -0x10e8(%rbp), %rax
jae 0x1787
movq -0x10f0(%rbp), %rdi
movslq -0x10bc(%rbp), %rax
addq %rax, %rdi
movq -0x10f0(%rbp), %rsi
movslq -0x10bc(%rbp), %rax
addq %rax, %rsi
leaq -0x10a8(%rbp), %rdx
movl $0x1, %ecx
callq 0x1840
movl -0x10bc(%rbp), %eax
addl $0x8, %eax
movl %eax, -0x10bc(%rbp)
jmp 0x1733
movq -0x10b8(%rbp), %rdi
leaq 0x2a40(%rip), %rsi      # 0x41d5
callq 0x1100
movq %rax, -0x1108(%rbp)
cmpq $0x0, -0x1108(%rbp)
jne 0x17c0
leaq 0x2a27(%rip), %rdi      # 0x41d9
callq 0x1110
movl $0x6, -0x4(%rbp)
jmp 0x182e
movq -0x10f0(%rbp), %rdi
movq -0x10e8(%rbp), %rdx
movq -0x1108(%rbp), %rcx
movl $0x1, %esi
callq 0x1120
movq %rax, -0x1110(%rbp)
movq -0x1110(%rbp), %rax
cmpq -0x10e8(%rbp), %rax
je 0x181b
movq -0x1110(%rbp), %rsi
movq -0x10e8(%rbp), %rdx
leaq 0x29e9(%rip), %rdi      # 0x41f4
movb $0x0, %al
callq 0x1090
movl $0x7, -0x4(%rbp)
jmp 0x182e
movq -0x1108(%rbp), %rdi
callq 0x1070
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1120, %rsp           # imm = 0x1120
popq %rbp
retq
nopw (%rax,%rax)