decompiled_code:
void __fastcall control_connect(int fd, char *name)
{
struct addrinfo *v2; // rbx
struct addrinfo *pai; // [rsp+8h] [rbp-50h] BYREF
struct addrinfo req; // [rsp+10h] [rbp-48h] BYREF

*(_QWORD *)&req.ai_flags = 0x200000000LL;
*(_QWORD *)&req.ai_socktype = 1LL;
*(_QWORD *)&req.ai_addrlen = 0LL;
req.ai_addr = 0LL;
req.ai_canonname = 0LL;
req.ai_next = 0LL;
if ( getaddrinfo(name, "30021", &req, &pai) )
{
perror("Error getting server address info");
puts("Please check that the server hostname is correct");
exit(1);
}
v2 = pai;
if ( !pai )
{
LABEL_5:
perror("Unable to open control connection with specified host");
close(fd);
exit(1);
}
while ( connect(fd, v2->ai_addr, v2->ai_addrlen) == -1 )
{
v2 = v2->ai_next;
if ( !v2 )
goto LABEL_5;
}
freeaddrinfo(pai);
}

canonical_decompiled_code:
void __fastcall func1(int fd, char *name)
{
struct addrinfo *v2; // rbx
struct addrinfo *pai; // [rsp+8h] [rbp-50h] BYREF
struct addrinfo req; // [rsp+10h] [rbp-48h] BYREF

*(_QWORD *)&req.ai_flags = 0x200000000LL;
*(_QWORD *)&req.ai_socktype = 1LL;
*(_QWORD *)&req.ai_addrlen = 0LL;
req.ai_addr = 0LL;
req.ai_canonname = 0LL;
req.ai_next = 0LL;
if ( getaddrinfo(name, "30021", &req, &pai) )
{
perror("Error getting server address info");
puts("Please check that the server hostname is correct");
exit(1);
}
v2 = pai;
if ( !pai )
{
LABEL_5:
perror("Unable to open control connection with specified host");
close(fd);
exit(1);
}
while ( connect(fd, v2->ai_addr, v2->ai_addrlen) == -1 )
{
v2 = v2->ai_next;
if ( !v2 )
goto LABEL_5;
}
freeaddrinfo(pai);
}

original_code:
void control_connect(int ctrl_fd, char * host) {
    struct addrinfo hints, *results, *p;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = 2;
    hints.ai_socktype = SOCK_STREAM;
    if(getaddrinfo(host, "30021", &hints, &results) != 0) {
        perror("Error getting server address info");
        printf("Please check that the server hostname is correct\n");
        exit(1);
    }
    for(p = results; p != ((void *)0); p = p->ai_next) {
        if(connect(ctrl_fd, p->ai_addr, p->ai_addrlen) != -1) {
            freeaddrinfo(results);
            return;
        }
    }
    perror("Unable to open control connection with specified host");
    close(ctrl_fd);
    exit(1);
}

canonical_original_code:
void control_connect(int ctrl_fd, char *host) {
    struct addrinfo hints; struct addrinfo *results; struct addrinfo *p;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = 2;
    hints.ai_socktype = SOCK_STREAM;
    if(getaddrinfo(host, "30021", &hints, &results) != 0) {
        perror("Error getting server address info");
        printf("Please check that the server hostname is correct\n");
        exit(1);
    }
    for(p = results; p != ((void *)0); p = p->ai_next) {
        if(connect(ctrl_fd, p->ai_addr, p->ai_addrlen) != -1) {
            freeaddrinfo(results);
            return;
        }
    }
    perror("Unable to open control connection with specified host");
    close(ctrl_fd);
    exit(1);
}

variable_types:
host
char *

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *

user_defined_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }


repo: NathanJCochran/ftp

decompiled_code:
int __fastcall receive_message(int fd)
{
char *v2; // rbx
int v3; // eax
char v5[255]; // [rsp+0h] [rbp-128h] BYREF
char v6; // [rsp+FFh] [rbp-29h] BYREF

v2 = v5;
while ( 1 )
{
v3 = read(fd, v2, 1uLL);
if ( v3 == -1 )
{
perror("Error reading from control socket");
close(fd);
exit(1);
}
if ( !v3 )
{
printf("%s", v5);
close(fd);
exit(0);
}
if ( !memcmp(v2 - 1, ">>", 2uLL) )
break;
if ( ++v2 == &v6 )
return printf("%s", v5);
}
v5[(_DWORD)v2 - (unsigned int)v5 + 1] = 0;
return printf("%s", v5);
}

canonical_decompiled_code:
int __fastcall func2(int fd)
{
char *v2; // rbx
int v3; // eax
char v5[255]; // [rsp+0h] [rbp-128h] BYREF
char v6; // [rsp+FFh] [rbp-29h] BYREF

v2 = v5;
while ( 1 )
{
v3 = read(fd, v2, 1uLL);
if ( v3 == -1 )
{
perror("Error reading from control socket");
close(fd);
exit(1);
}
if ( !v3 )
{
printf("%s", v5);
close(fd);
exit(0);
}
if ( !memcmp(v2 - 1, ">>", 2uLL) )
break;
if ( ++v2 == &v6 )
return printf("%s", v5);
}
v5[(_DWORD)v2 - (unsigned int)v5 + 1] = 0;
return printf("%s", v5);
}

original_code:
void receive_message(int ctrl_fd) {
    int i, num_read;
    char buffer[256];
    for(i=0; i<256 -1; i++) {
        if((num_read = read(ctrl_fd, &buffer[i], 1)) == -1) {
            perror("Error reading from control socket");
            close(ctrl_fd);
            exit(1);
        }
        if(num_read == 0)
            break;
        if(strncmp(&buffer[i-(strlen(">>")-1)], ">>", strlen(">>")) == 0) {
            buffer[i+1] = '\0';
            break;
        }
    }
    printf("%s", buffer);
    if(num_read == 0) {
        close(ctrl_fd);
        exit(0);
    }
}

canonical_original_code:
void receive_message(int ctrl_fd) {
    int i; int num_read;
    char buffer[256];
    for(i=0; i<256 -1; i++) {
        if((num_read = read(ctrl_fd, &buffer[i], 1)) == -1) {
            perror("Error reading from control socket");
            close(ctrl_fd);
            exit(1);
        }
        if(num_read == 0)
            break;
        if(strncmp(&buffer[i-(strlen(">>")-1)], ">>", strlen(">>")) == 0) {
            buffer[i+1] = '\0';
            break;
        }
    }
    printf("%s", buffer);
    if(num_read == 0) {
        close(ctrl_fd);
        exit(0);
    }
}

variable_types: i int

variable_types:
buffer
char [256]

return_type: void


decompiled_code:
char *__fastcall get_request(int fd, char *s)
{
char *result; // rax

result = fgets(s, 256, stdin);
if ( !result )
{
perror("Error reading user input");
close(fd);
exit(1);
}
return result;
}

canonical_decompiled_code:
char *__fastcall func3(int fd, char *s)
{
char *result; // rax

result = fgets(s, 256, stdin);
if ( !result )
{
perror("Error reading user input");
close(fd);
exit(1);
}
return result;
}

original_code:
void get_request(int ctrl_fd, char * response) {
    if(fgets(response, 256, stdin) == ((void *)0)) {
        perror("Error reading user input");
        close(ctrl_fd);
        exit(1);
    }
}

canonical_original_code:
void get_request(int ctrl_fd, char *response) {
    if(fgets(response, 256, stdin) == ((void *)0)) {
        perror("Error reading user input");
        close(ctrl_fd);
        exit(1);
    }
}

variable_types:
response
char *


decompiled_code:
__int64 __fastcall open_data_connection(int fd)
{
__int64 v1; // rbp
unsigned int v2; // ebx
socklen_t len; // [rsp+Ch] [rbp-3Ch] BYREF
struct sockaddr v5; // [rsp+10h] [rbp-38h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-28h] BYREF

len = 16;
if ( getpeername(fd, &addr, &len) == -1 )
{
perror("Error getting peer's address");
close(fd);
exit(1);
}
v1 = (unsigned int)create_socket();
bind_socket(v1, 30020LL);
listen_socket((unsigned int)v1);
while ( 1 )
{
len = 16;
v2 = accept(v1, &v5, &len);
if ( v2 == -1 )
{
perror("Error accepting incoming data connection");
close(fd);
close(v1);
exit(1);
}
if ( *(_DWORD *)&addr.sa_data[2] == *(_DWORD *)&v5.sa_data[2] )
break;
close(v2);
}
close(v1);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func4(int fd)
{
__int64 v1; // rbp
unsigned int v2; // ebx
socklen_t len; // [rsp+Ch] [rbp-3Ch] BYREF
struct sockaddr v5; // [rsp+10h] [rbp-38h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-28h] BYREF

len = 16;
if ( getpeername(fd, &addr, &len) == -1 )
{
perror("Error getting peer's address");
close(fd);
exit(1);
}
v1 = (unsigned int)create_socket();
bind_socket(v1, 30020LL);
listen_socket((unsigned int)v1);
while ( 1 )
{
len = 16;
v2 = accept(v1, &v5, &len);
if ( v2 == -1 )
{
perror("Error accepting incoming data connection");
close(fd);
close(v1);
exit(1);
}
if ( *(_DWORD *)&addr.sa_data[2] == *(_DWORD *)&v5.sa_data[2] )
break;
close(v2);
}
close(v1);
return v2;
}

original_code:
int open_data_connection(int ctrl_fd) {
    struct sockaddr_in ctrl_address, data_address;
    int passive_fd, data_fd;
    unsigned int length;
    length = sizeof(ctrl_address);
    if(getpeername(ctrl_fd, (struct sockaddr *) &ctrl_address, &length) == -1) {
        perror("Error getting peer's address");
        close(ctrl_fd);
        exit(1);
    }
    passive_fd = create_socket();
    bind_socket(passive_fd, 30020);
    listen_socket(passive_fd);
    while(1) {
        length = sizeof(data_address);
        if((data_fd = accept(passive_fd, (struct sockaddr *) &data_address, &length)) == -1) {
            perror("Error accepting incoming data connection");
            close(ctrl_fd);
            close(passive_fd);
            exit(1);
        }
        if(ctrl_address.sin_addr.s_addr == data_address.sin_addr.s_addr) {
            break;
        }
        close(data_fd);
    }
    close(passive_fd);
    return data_fd;
}

canonical_original_code:
int open_data_connection(int ctrl_fd) {
    struct sockaddr_in ctrl_address; struct sockaddr_in data_address;
    int passive_fd; int data_fd;
    unsigned int length;
    length = sizeof(ctrl_address);
    if(getpeername(ctrl_fd, (struct sockaddr *) &ctrl_address, &length) == -1) {
        perror("Error getting peer's address");
        close(ctrl_fd);
        exit(1);
    }
    passive_fd = create_socket();
    bind_socket(passive_fd, 30020);
    listen_socket(passive_fd);
    while(1) {
        length = sizeof(data_address);
        if((data_fd = accept(passive_fd, (struct sockaddr *) &data_address, &length)) == -1) {
            perror("Error accepting incoming data connection");
            close(ctrl_fd);
            close(passive_fd);
            exit(1);
        }
        if(ctrl_address.sin_addr.s_addr == data_address.sin_addr.s_addr) {
            break;
        }
        close(data_fd);
    }
    close(passive_fd);
    return data_fd;
}

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; }

variable_types:
length
unsigned int

return_type: int

user_defined_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


decompiled_code:
ssize_t __fastcall receive_listing(int fd)
{
ssize_t result; // rax
char v2[264]; // [rsp+0h] [rbp-108h] BYREF

while ( 1 )
{
result = read(fd, v2, 0x100uLL);
if ( (int)result <= 0 )
break;
printf("%s", v2);
}
return result;
}

canonical_decompiled_code:
ssize_t __fastcall func5(int fd)
{
ssize_t result; // rax
char v2[264]; // [rsp+0h] [rbp-108h] BYREF

while ( 1 )
{
result = read(fd, v2, 0x100uLL);
if ( (int)result <= 0 )
break;
printf("%s", v2);
}
return result;
}

original_code:
void receive_listing(int data_fd) {
    char buffer[256];
    int num_read;
    while((num_read = read(data_fd, buffer, 256)) > 0) {
        printf("%s", buffer);
    }
}


decompiled_code:
int __fastcall receive_file(int fd, char *file)
{
int result; // eax
int v3; // ebx
int v4; // er12
int v5; // eax
_BYTE v6[4136]; // [rsp+0h] [rbp-1028h] BYREF

result = read(fd, v6, 0x1000uLL);
if ( result > 0 )
{
v3 = result;
v4 = open(file, 193, 432LL);
if ( v4 == -1 )
{
if ( *_errno_location() != 17 )
{
perror("Error creating file");
close(fd);
exit(1);
}
if ( !(unsigned int)input_yn("File already exists. Overwrite? ") )
{
printf("File not received: %s\n", file);
return close(fd);
}
v4 = open(file, 1, 438LL);
if ( v4 == -1 )
{
perror("Error creating file");
close(fd);
exit(1);
}
}
do
{
if ( write(v4, v6, v3) == -1 )
{
perror("Error writing to file");
close(fd);
exit(1);
}
v5 = read(fd, v6, 0x1000uLL);
v3 = v5;
}
while ( v5 > 0 );
if ( v5 == -1 )
{
perror("Error reading file from data connection");
close(fd);
exit(1);
}
result = printf("File received: %s\n", file);
}
else if ( result == -1 )
{
perror("Error reading file from data connection");
close(fd);
exit(1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func6(int fd, char *file)
{
int result; // eax
int v3; // ebx
int v4; // er12
int v5; // eax
_BYTE v6[4136]; // [rsp+0h] [rbp-1028h] BYREF

result = read(fd, v6, 0x1000uLL);
if ( result > 0 )
{
v3 = result;
v4 = open(file, 193, 432LL);
if ( v4 == -1 )
{
if ( *_errno_location() != 17 )
{
perror("Error creating file");
close(fd);
exit(1);
}
if ( !(unsigned int)input_yn("File already exists. Overwrite? ") )
{
printf("File not received: %s\n", file);
return close(fd);
}
v4 = open(file, 1, 438LL);
if ( v4 == -1 )
{
perror("Error creating file");
close(fd);
exit(1);
}
}
do
{
if ( write(v4, v6, v3) == -1 )
{
perror("Error writing to file");
close(fd);
exit(1);
}
v5 = read(fd, v6, 0x1000uLL);
v3 = v5;
}
while ( v5 > 0 );
if ( v5 == -1 )
{
perror("Error reading file from data connection");
close(fd);
exit(1);
}
result = printf("File received: %s\n", file);
}
else if ( result == -1 )
{
perror("Error reading file from data connection");
close(fd);
exit(1);
}
return result;
}

original_code:
void receive_file(int data_fd, char * filename) {
    int file_fd, num_read;
    char buffer[4096];
    if((num_read=read(data_fd, buffer, 4096)) > 0) {
        if((file_fd = open(filename, 0100 | 0200 | 01, 0660)) == -1) {
            if((*__errno_location ()) == 17) {
                if(input_yn("File already exists. Overwrite? ")) {
                    if((file_fd = open(filename, 01, 0666)) == -1) {
                        perror("Error creating file");
                        close(data_fd);
                        exit(1);
                    }
                }
                else {
                    printf("File not received: %s\n", filename);
                    close(data_fd);
                    return;
                }
            }
            else {
                perror("Error creating file");
                close(data_fd);
                exit(1);
            }
        }
        do {
            if(write(file_fd, buffer, num_read) == -1) {
                perror("Error writing to file");
                close(data_fd);
                exit(1);
            }
        } while((num_read = read(data_fd, buffer, 4096)) > 0);
        if(num_read == -1) {
            perror("Error reading file from data connection");
            close(data_fd);
            exit(1);
        }
        printf("File received: %s\n", filename);
    }
    if(num_read == -1) {
        perror("Error reading file from data connection");
        close(data_fd);
        exit(1);
    }
}

canonical_original_code:
void receive_file(int data_fd, char *filename) {
    int file_fd; int num_read;
    char buffer[4096];
    if((num_read=read(data_fd, buffer, 4096)) > 0) {
        if((file_fd = open(filename, 0100 | 0200 | 01, 0660)) == -1) {
            if((*__errno_location ()) == 17) {
                if(input_yn("File already exists. Overwrite? ")) {
                    if((file_fd = open(filename, 01, 0666)) == -1) {
                        perror("Error creating file");
                        close(data_fd);
                        exit(1);
                    }
                }
                else {
                    printf("File not received: %s\n", filename);
                    close(data_fd);
                    return;
                }
            }
            else {
                perror("Error creating file");
                close(data_fd);
                exit(1);
            }
        }
        do {
            if(write(file_fd, buffer, num_read) == -1) {
                perror("Error writing to file");
                close(data_fd);
                exit(1);
            }
        } while((num_read = read(data_fd, buffer, 4096)) > 0);
        if(num_read == -1) {
            perror("Error reading file from data connection");
            close(data_fd);
            exit(1);
        }
        printf("File received: %s\n", filename);
    }
    if(num_read == -1) {
        perror("Error reading file from data connection");
        close(data_fd);
        exit(1);
    }
}

variable_types:
filename
char *

variable_types:
buffer
char [4096]


decompiled_code:
int __fastcall make_request(int fd, __int64 a2)
{
int result; // eax
int v3; // ebx
int v4; // ebx
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

send_message((unsigned int)control_fd, a2);
result = parse_command(a2, v5);
if ( result == 2 )
{
v3 = open_data_connection(fd);
receive_file(v3, v5);
result = close(v3);
}
else if ( result == 1 )
{
v4 = open_data_connection(fd);
receive_listing(v4);
result = close(v4);
}
return result;
}

canonical_decompiled_code:
int __fastcall func7(int fd, __int64 a2)
{
int result; // eax
int v3; // ebx
int v4; // ebx
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

send_message((unsigned int)control_fd, a2);
result = parse_command(a2, v5);
if ( result == 2 )
{
v3 = func4(fd);
func6(v3, v5);
result = close(v3);
}
else if ( result == 1 )
{
v4 = func4(fd);
func5(v4);
result = close(v4);
}
return result;
}

original_code:
void make_request(int ctrl_fd, char * request) {
    int data_fd, command;
    char arg[256];
    send_message(control_fd, request);
    command = parse_command(request, arg);
    if(command == 2) {
        data_fd = open_data_connection(ctrl_fd);
        receive_file(data_fd, arg);
        close(data_fd);
    }
    else if(command == 1) {
        data_fd = open_data_connection(ctrl_fd);
        receive_listing(data_fd);
        close(data_fd);
    }
}

canonical_original_code:
void make_request(int ctrl_fd, char *request) {
    int data_fd; int command;
    char arg[256];
    send_message(control_fd, request);
    command = parse_command(request, arg);
    if(command == 2) {
        data_fd = open_data_connection(ctrl_fd);
        receive_file(data_fd, arg);
        close(data_fd);
    }
    else if(command == 1) {
        data_fd = open_data_connection(ctrl_fd);
        receive_listing(data_fd);
        close(data_fd);
    }
}

variable_types:
request
char *

variable_types: command int

variable_types:
arg
char [256]


decompiled_code:
int install_signal_handlers()
{
struct sigaction v1; // [rsp+0h] [rbp-A8h] BYREF

v1.sa_handler = (__sighandler_t)signal_handler;
sigemptyset(&v1.sa_mask);
v1.sa_flags = 0;
sigaction(2, &v1, 0LL);
return sigaction(15, &v1, 0LL);
}

canonical_decompiled_code:
int func8()
{
struct sigaction v1; // [rsp+0h] [rbp-A8h] BYREF

v1.sa_handler = (__sighandler_t)signal_handler;
sigemptyset(&v1.sa_mask);
v1.sa_flags = 0;
sigaction(2, &v1, 0LL);
return sigaction(15, &v1, 0LL);
}

original_code:
void install_signal_handlers(void) {
    struct sigaction sig;
    sig.__sigaction_handler.sa_handler = signal_handler;
    sigemptyset(&sig.sa_mask);
    sig.sa_flags = 0;
    sigaction(2, &sig, ((void *)0));
    sigaction(15, &sig, ((void *)0));
}

canonical_original_code:
void install_signal_handlers() {
    struct sigaction sig;
    sig.__sigaction_handler.sa_handler = signal_handler;
    sigemptyset(&sig.sa_mask);
    sig.sa_flags = 0;
    sigaction(2, &sig, ((void *)0));
    sigaction(15, &sig, ((void *)0));
}

variable_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval { int sival_int; void *sival_ptr; } si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; } *, void *); } __sigaction_handler; struct __sigset_t { unsigned long __val[-1]; } sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t *, void *); } __sigaction_handler; struct __sigset_t sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; }


decompiled_code:
void __noreturn signal_handler()
{
puts("\nClosing connection to server...");
send_message((unsigned int)control_fd, "exit\n");
close(control_fd);
puts("Connection closed");
exit(0);
}

canonical_decompiled_code:
void __noreturn func0()
{
puts("\nClosing connection to server...");
send_message((unsigned int)control_fd, "exit\n");
close(control_fd);
puts("Connection closed");
exit(0);
}

original_code:
void signal_handler(int sig) {
    printf("\nClosing connection to server...\n");
    send_message(control_fd, "exit\n");
    close(control_fd);
    printf("Connection closed\n");
    exit(0);
}

variable_types: sig int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[264]; // [rsp+0h] [rbp-108h] BYREF

if ( argc != 2 )
{
printf("Usage:\n\t%s <server hostname>\n", *argv);
exit(0);
}
install_signal_handlers();
control_fd = create_socket();
control_connect(control_fd, (char *)argv[1]);
do
{
receive_message(control_fd);
get_request(control_fd, v4);
make_request(control_fd, (__int64)v4);
}
while ( (unsigned int)parse_command(v4, 0LL) );
close(control_fd);
puts("Connection closed");
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[264]; // [rsp+0h] [rbp-108h] BYREF

if ( argc != 2 )
{
printf("Usage:\n\t%s <server hostname>\n", *argv);
exit(0);
}
func8();
control_fd = create_socket();
func1(control_fd, (char *)argv[1]);
do
{
func2(control_fd);
func3(control_fd, v4);
func7(control_fd, (__int64)v4);
}
while ( (unsigned int)parse_command(v4, 0LL) );
close(control_fd);
puts("Connection closed");
return 0;
}

original_code:
int main(int argc, char * argv[]) {
    char request[256];
    if(argc != 2) {
        printf("Usage:\n\t%s <server hostname>\n", argv[0]);
        exit(0);
    }
    install_signal_handlers();
    control_fd = create_socket();
    control_connect(control_fd, argv[1]);
    do {
        receive_message(control_fd);
        get_request(control_fd, request);
        make_request(control_fd, request);
    } while(parse_command(request, ((void *)0)) != 0);
    close(control_fd);
    printf("Connection closed\n");
    return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
    char request[256];
    if(argc != 2) {
        printf("Usage:\n\t%s <server hostname>\n", argv[0]);
        exit(0);
    }
    install_signal_handlers();
    control_fd = create_socket();
    control_connect(control_fd, argv[1]);
    do {
        receive_message(control_fd);
        get_request(control_fd, request);
        make_request(control_fd, request);
    } while(parse_command(request, ((void *)0)) != 0);
    close(control_fd);
    printf("Connection closed\n");
    return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
request
char [256]


decompiled_code:
__int64 start_server()
{
__int64 v0; // rbx

v0 = (unsigned int)create_socket();
bind_socket(v0, 30021LL);
listen_socket((unsigned int)v0);
puts("Server started");
puts("Listening for incoming connections...");
return (unsigned int)v0;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 v0; // rbx

v0 = (unsigned int)create_socket();
bind_socket(v0, 30021LL);
listen_socket((unsigned int)v0);
puts("Server started");
puts("Listening for incoming connections...");
return (unsigned int)v0;
}

original_code:
int start_server(void) {
    int fd;
    fd = create_socket();
    bind_socket(fd, 30021);
    listen_socket(fd);
    printf("Server started\n");
    printf("Listening for incoming connections...\n");
    return fd;
}

canonical_original_code:
int start_server() {
    int fd;
    fd = create_socket();
    bind_socket(fd, 30021);
    listen_socket(fd);
    printf("Server started\n");
    printf("Listening for incoming connections...\n");
    return fd;
}

variable_types: fd int


decompiled_code:
__int64 __fastcall accept_connection(int fd)
{
int v1; // eax
unsigned int v2; // ebx
socklen_t addr_len; // [rsp+Ch] [rbp-12Ch] BYREF
char buf[256]; // [rsp+10h] [rbp-128h] BYREF
struct sockaddr addr; // [rsp+110h] [rbp-28h] BYREF

addr_len = 16;
v1 = accept(fd, &addr, &addr_len);
if ( v1 == -1 )
{
perror("Error accepting incoming connection");
close(fd);
exit(1);
}
v2 = v1;
if ( !inet_ntop(2, &addr.sa_data[2], buf, 0x100u) )
{
perror("Error converting ip address to string");
close(fd);
exit(1);
}
printf("Connection accepted: %s\n", buf);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(int fd)
{
int v1; // eax
unsigned int v2; // ebx
socklen_t addr_len; // [rsp+Ch] [rbp-12Ch] BYREF
char buf[256]; // [rsp+10h] [rbp-128h] BYREF
struct sockaddr addr; // [rsp+110h] [rbp-28h] BYREF

addr_len = 16;
v1 = accept(fd, &addr, &addr_len);
if ( v1 == -1 )
{
perror("Error accepting incoming connection");
close(fd);
exit(1);
}
v2 = v1;
if ( !inet_ntop(2, &addr.sa_data[2], buf, 0x100u) )
{
perror("Error converting ip address to string");
close(fd);
exit(1);
}
printf("Connection accepted: %s\n", buf);
return v2;
}

original_code:
int accept_connection(int socket_fd) {
    struct sockaddr_in address;
    char address_str[256];
    int connection_fd;
    unsigned int length;
    length = sizeof(address);
    if((connection_fd = accept(socket_fd, (struct sockaddr *) &address, &length)) == -1) {
        perror("Error accepting incoming connection");
        close(socket_fd);
        exit(1);
    }
    if(inet_ntop(2, &address.sin_addr, address_str, 256) == ((void *)0)) {
        perror("Error converting ip address to string");
        close(socket_fd);
        exit(1);
    }
    printf("Connection accepted: %s\n", address_str);
    return connection_fd;
}


decompiled_code:
__int64 __fastcall get_command(int fd, __int64 a2)
{
int v2; // ebx
char v3; // al
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

v2 = 0;
do
{
while ( 1 )
{
if ( !v2 )
send_message((unsigned int)fd, ">>");
if ( read(fd, &v5[v2], 1uLL) == -1 )
{
perror("Error reading from socket");
exit(1);
}
v3 = v5[v2];
if ( v3 == 10 || v3 == 13 )
break;
if ( ++v2 > 255 )
return parse_command(v5, a2);
}
}
while ( !v2 );
return parse_command(v5, a2);
}

canonical_decompiled_code:
__int64 __fastcall func4(int fd, __int64 a2)
{
int v2; // ebx
char v3; // al
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

v2 = 0;
do
{
while ( 1 )
{
if ( !v2 )
send_message((unsigned int)fd, ">>");
if ( read(fd, &v5[v2], 1uLL) == -1 )
{
perror("Error reading from socket");
exit(1);
}
v3 = v5[v2];
if ( v3 == 10 || v3 == 13 )
break;
if ( ++v2 > 255 )
return parse_command(v5, a2);
}
}
while ( !v2 );
return parse_command(v5, a2);
}

original_code:
int get_command(int ctrl_fd, char * arg) {
    int i;
    char buffer[256];
    for(i=0; i<256; i++) {
        if(i==0) {
            send_message(ctrl_fd, ">>");
        }
        if(read(ctrl_fd, &buffer[i], 1) == -1) {
            perror("Error reading from socket");
            exit(1);
        };
        if((buffer[i] == '\n') || (buffer[i] == '\r')) {
            if(i==0) {
                i--;
                continue;
            }
            else {
                break;
            }
        }
    }
    return parse_command(buffer, arg);
}

canonical_original_code:
int get_command(int ctrl_fd, char *arg) {
    int i;
    char buffer[256];
    for(i=0; i<256; i++) {
        if(i==0) {
            send_message(ctrl_fd, ">>");
        }
        if(read(ctrl_fd, &buffer[i], 1) == -1) {
            perror("Error reading from socket");
            exit(1);
        };
        if((buffer[i] == '\n') || (buffer[i] == '\r')) {
            if(i==0) {
                i--;
                continue;
            }
            else {
                break;
            }
        }
    }
    return parse_command(buffer, arg);
}

variable_types:
arg
char *


decompiled_code:
__int64 __fastcall data_connect(int fd)
{
unsigned int v1; // ebx
socklen_t len; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

len = 16;
if ( getpeername(fd, &addr, &len) == -1 )
{
perror("Error getting peer's address");
close(fd);
exit(1);
}
*(_WORD *)addr.sa_data = _bswap_16(30020);
v1 = create_socket();
if ( connect(v1, &addr, 0x10u) == -1 )
{
perror("Error opening data connection");
close(fd);
exit(1);
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func5(int fd)
{
unsigned int v1; // ebx
socklen_t len; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

len = 16;
if ( getpeername(fd, &addr, &len) == -1 )
{
perror("Error getting peer's address");
close(fd);
exit(1);
}
*(_WORD *)addr.sa_data = func1(30020);
v1 = create_socket();
if ( connect(v1, &addr, 0x10u) == -1 )
{
perror("Error opening data connection");
close(fd);
exit(1);
}
return v1;
}

original_code:
int data_connect(int ctrl_fd) {
    struct sockaddr_in address;
    int data_fd;
    unsigned int length;
    length = sizeof(address);
    if(getpeername(ctrl_fd, (struct sockaddr *) &address, &length) == -1) {
        perror("Error getting peer's address");
        close(ctrl_fd);
        exit(1);
    }
    address.sin_port = htons(30020);
    data_fd = create_socket();
    if(connect(data_fd, (struct sockaddr *) &address, sizeof(address)) == -1) {
        perror("Error opening data connection");
        close(ctrl_fd);
        exit(1);
    }
    return data_fd;
}


decompiled_code:
int __fastcall send_file(unsigned int a1, const char *a2)
{
int v2; // ebp
int v3; // ebx
int v4; // eax
int result; // eax
char buf[25]; // [rsp+Fh] [rbp-19h] BYREF

v2 = data_connect(a1);
v3 = open(a2, 0);
if ( v3 == -1 )
{
if ( *_errno_location() != 2 )
{
perror("Error opening file");
exit(1);
}
send_message(a1, "Invalid filename: file does not exist\n");
result = close(v2);
}
else
{
while ( 1 )
{
v4 = read(v3, buf, 1uLL);
if ( v4 <= 0 )
break;
if ( write(v2, buf, 1uLL) != 1 )
{
perror("Error writing to data socket");
exit(1);
}
}
if ( v4 == -1 )
{
perror("Error reading from file");
exit(1);
}
close(v3);
result = close(v2);
}
return result;
}

canonical_decompiled_code:
int __fastcall func7(unsigned int a1, const char *a2)
{
int v2; // ebp
int v3; // ebx
int v4; // eax
int result; // eax
char buf[25]; // [rsp+Fh] [rbp-19h] BYREF

v2 = func5(a1);
v3 = open(a2, 0);
if ( v3 == -1 )
{
if ( *_errno_location() != 2 )
{
perror("Error opening file");
exit(1);
}
send_message(a1, "Invalid filename: file does not exist\n");
result = close(v2);
}
else
{
while ( 1 )
{
v4 = read(v3, buf, 1uLL);
if ( v4 <= 0 )
break;
if ( write(v2, buf, 1uLL) != 1 )
{
perror("Error writing to data socket");
exit(1);
}
}
if ( v4 == -1 )
{
perror("Error reading from file");
exit(1);
}
close(v3);
result = close(v2);
}
return result;
}

original_code:
void send_file(int ctrl_fd, char * filename) {
    int data_fd, file_fd, num_read;
    char c;
    data_fd = data_connect(ctrl_fd);
    if((file_fd = open(filename, 00)) == -1) {
        if((*__errno_location ()) == 2) {
            send_message(ctrl_fd, "Invalid filename: file does not exist\n");
            close(data_fd);
            return;
        }
        perror("Error opening file");
        exit(1);
    }
    while((num_read = read(file_fd, &c, 1)) > 0) {
        if(write(data_fd, &c, 1) != 1) {
            perror("Error writing to data socket");
            exit(1);
        }
    }
    if(num_read == -1) {
        perror("Error reading from file");
        exit(1);
    }
    close(file_fd);
    close(data_fd);
}

canonical_original_code:
void send_file(int ctrl_fd, char *filename) {
    int data_fd; int file_fd; int num_read;
    char c;
    data_fd = data_connect(ctrl_fd);
    if((file_fd = open(filename, 00)) == -1) {
        if((*__errno_location ()) == 2) {
            send_message(ctrl_fd, "Invalid filename: file does not exist\n");
            close(data_fd);
            return;
        }
        perror("Error opening file");
        exit(1);
    }
    while((num_read = read(file_fd, &c, 1)) > 0) {
        if(write(data_fd, &c, 1) != 1) {
            perror("Error writing to data socket");
            exit(1);
        }
    }
    if(num_read == -1) {
        perror("Error reading from file");
        exit(1);
    }
    close(file_fd);
    close(data_fd);
}

variable_types: c char


decompiled_code:
__int64 __fastcall show_cwd(int fd)
{
char v2[264]; // [rsp+0h] [rbp-108h] BYREF

if ( !getcwd(v2, 0x100uLL) )
{
perror("Error getting the current working directory");
close(fd);
exit(1);
}
send_message((unsigned int)fd, "Remote working directory: ");
send_message((unsigned int)fd, v2);
return send_message((unsigned int)fd, "\n");
}

canonical_decompiled_code:
__int64 __fastcall func8(int fd)
{
char v2[264]; // [rsp+0h] [rbp-108h] BYREF

if ( !getcwd(v2, 0x100uLL) )
{
perror("Error getting the current working directory");
close(fd);
exit(1);
}
send_message((unsigned int)fd, "Remote working directory: ");
send_message((unsigned int)fd, v2);
return send_message((unsigned int)fd, "\n");
}

original_code:
void show_cwd(int ctrl_fd) {
    char buf[256];
    if(getcwd(buf, 256) == ((void *)0)) {
        perror("Error getting the current working directory");
        close(ctrl_fd);
        exit(1);
    }
    send_message(ctrl_fd, "Remote working directory: ");
    send_message(ctrl_fd, buf);
    send_message(ctrl_fd, "\n");
}

variable_types:
buf
char [256]


decompiled_code:
__int64 __fastcall change_directory(int fd, char *path)
{
int v2; // eax

if ( chdir(path) != -1 )
return show_cwd(fd);
v2 = *_errno_location();
if ( v2 == 13 )
return send_message((unsigned int)fd, "Error: permission denied\n");
if ( v2 == 20 || v2 == 2 )
return send_message((unsigned int)fd, "Error: invalid directory\n");
return send_message((unsigned int)fd, "Error: could not change directories\n");
}

canonical_decompiled_code:
__int64 __fastcall func9(int fd, char *path)
{
int v2; // eax

if ( chdir(path) != -1 )
return func8(fd);
v2 = *_errno_location();
if ( v2 == 13 )
return send_message((unsigned int)fd, "Error: permission denied\n");
if ( v2 == 20 || v2 == 2 )
return send_message((unsigned int)fd, "Error: invalid directory\n");
return send_message((unsigned int)fd, "Error: could not change directories\n");
}

original_code:
void change_directory(int ctrl_fd, char * directory) {
    if(chdir(directory) == -1) {
        if((*__errno_location ()) == 13) {
            send_message(ctrl_fd, "Error: permission denied\n");
        }
        else if((*__errno_location ()) == 20 || (*__errno_location ()) == 2) {
            send_message(ctrl_fd, "Error: invalid directory\n");
        }
        else {
            send_message(ctrl_fd, "Error: could not change directories\n");
        }
    }
    else {
        show_cwd(ctrl_fd);
    }
}

canonical_original_code:
void change_directory(int ctrl_fd, char *directory) {
    if(chdir(directory) == -1) {
        if((*__errno_location ()) == 13) {
            send_message(ctrl_fd, "Error: permission denied\n");
        }
        else if((*__errno_location ()) == 20 || (*__errno_location ()) == 2) {
            send_message(ctrl_fd, "Error: invalid directory\n");
        }
        else {
            send_message(ctrl_fd, "Error: could not change directories\n");
        }
    }
    else {
        show_cwd(ctrl_fd);
    }
}

variable_types:
directory
char *


decompiled_code:
__int64 __fastcall handle_request(__int64 fd)
{
__int64 result; // rax
char v2[264]; // [rsp+0h] [rbp-108h] BYREF

send_message(fd, "Welcome to Nathan's File Transfer Program\nCommands:\n\t");
send_message((unsigned int)fd, "exit\t- end the ftp session\n\t");
send_message((unsigned int)fd, "pwd\t- print working directory\n\t");
send_message((unsigned int)fd, "list\t- view files in current directory\n\t");
send_message((unsigned int)fd, "cd <directory>\t- change directory\n\t");
send_message((unsigned int)fd, "get <filename>\t- get the specified file\n");
while ( 1 )
{
result = get_command(fd, (__int64)v2);
if ( !(_DWORD)result )
return result;
switch ( (int)result )
{
case -1:
send_message((unsigned int)fd, "Invalid command\n");
break;
case 1:
list_directories(fd);
break;
case 2:
send_file(fd, v2);
break;
case 3:
change_directory(fd, v2);
break;
case 4:
show_cwd(fd);
break;
default:
continue;
}
}
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 fd)
{
__int64 result; // rax
char v2[264]; // [rsp+0h] [rbp-108h] BYREF

send_message(fd, "Welcome to Nathan's File Transfer Program\nCommands:\n\t");
send_message((unsigned int)fd, "exit\t- end the ftp session\n\t");
send_message((unsigned int)fd, "pwd\t- print working directory\n\t");
send_message((unsigned int)fd, "list\t- view files in current directory\n\t");
send_message((unsigned int)fd, "cd <directory>\t- change directory\n\t");
send_message((unsigned int)fd, "get <filename>\t- get the specified file\n");
while ( 1 )
{
result = func4(fd, (__int64)v2);
if ( !(_DWORD)result )
return result;
switch ( (int)result )
{
case -1:
send_message((unsigned int)fd, "Invalid command\n");
break;
case 1:
func6(fd);
break;
case 2:
func7(fd, v2);
break;
case 3:
func9(fd, v2);
break;
case 4:
func8(fd);
break;
default:
continue;
}
}
}

original_code:
void handle_request(int ctrl_fd) {
    int command;
    char arg[256];
    send_message(ctrl_fd, "Welcome to Nathan's File Transfer Program\nCommands:\n\t");
    send_message(ctrl_fd, "exit\t- end the ftp session\n\t");
    send_message(ctrl_fd, "pwd\t- print working directory\n\t");
    send_message(ctrl_fd, "list\t- view files in current directory\n\t");
    send_message(ctrl_fd, "cd <directory>\t- change directory\n\t");
    send_message(ctrl_fd, "get <filename>\t- get the specified file\n");
    while((command = get_command(ctrl_fd, arg)) != 0) {
        switch(command) {
            case -1:
                send_message(ctrl_fd, "Invalid command\n");
                break;
            case 1:
                list_directories(ctrl_fd);
                break;
            case 2:
                send_file(ctrl_fd, arg);
                break;
            case 3:
                change_directory(ctrl_fd, arg);
                break;
            case 4:
                show_cwd(ctrl_fd);
                break;
        }
    }
}


decompiled_code:
int install_sigint_handler()
{
struct sigaction v1; // [rsp+0h] [rbp-A8h] BYREF

v1.sa_handler = (__sighandler_t)signal_handler;
sigemptyset(&v1.sa_mask);
v1.sa_flags = 0;
sigaction(2, &v1, 0LL);
return sigaction(15, &v1, 0LL);
}

canonical_decompiled_code:
int func11()
{
struct sigaction v1; // [rsp+0h] [rbp-A8h] BYREF

v1.sa_handler = (__sighandler_t)signal_handler;
sigemptyset(&v1.sa_mask);
v1.sa_flags = 0;
sigaction(2, &v1, 0LL);
return sigaction(15, &v1, 0LL);
}

original_code:
void install_sigint_handler(void) {
    struct sigaction sig;
    sig.__sigaction_handler.sa_handler = signal_handler;
    sigemptyset(&sig.sa_mask);
    sig.sa_flags = 0;
    sigaction(2, &sig, ((void *)0));
    sigaction(15, &sig, ((void *)0));
}

canonical_original_code:
void install_sigint_handler() {
    struct sigaction sig;
    sig.__sigaction_handler.sa_handler = signal_handler;
    sigemptyset(&sig.sa_mask);
    sig.sa_flags = 0;
    sigaction(2, &sig, ((void *)0));
    sigaction(15, &sig, ((void *)0));
}

user_defined_types: struct __sigset_t { unsigned long __val[-1]; }

user_defined_types: union sigval { int sival_int; void *sival_ptr; }


decompiled_code:
void __noreturn signal_handler()
{
if ( control_fd != -1 )
{
puts("Closing client connection...");
send_message((unsigned int)control_fd, "Server closed connection.\n");
close(control_fd);
control_fd = -1;
puts("Client connection closed");
}
close(server_fd);
puts("Server shut down");
exit(0);
}

canonical_decompiled_code:
void __noreturn func0()
{
if ( control_fd != -1 )
{
puts("Closing client connection...");
send_message((unsigned int)control_fd, "Server closed connection.\n");
close(control_fd);
control_fd = -1;
puts("Client connection closed");
}
close(server_fd);
puts("Server shut down");
exit(0);
}

original_code:
void signal_handler(int sig) {
    if(control_fd != -1) {
        printf("Closing client connection...\n");
        send_message(control_fd, "Server closed connection.\n");
        close(control_fd);
        control_fd = -1;
        printf("Client connection closed\n");
    }
    close(server_fd);
    printf("Server shut down\n");
    exit(0);
}


decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
install_sigint_handler();
server_fd = start_server(argc, argv);
while ( 1 )
{
control_fd = accept_connection(server_fd);
handle_request((unsigned int)control_fd);
close(control_fd);
control_fd = -1;
puts("Connection closed by client");
}
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
func11();
server_fd = func2(argc, argv);
while ( 1 )
{
control_fd = func3(server_fd);
func10((unsigned int)control_fd);
close(control_fd);
control_fd = -1;
puts("Connection closed by client");
}
}

original_code:
int main(int argc, char * argv[]) {
    install_sigint_handler();
    server_fd = start_server();
    while(1) {
        control_fd = accept_connection(server_fd);
        handle_request(control_fd);
        close(control_fd);
        control_fd = -1;
        printf("Connection closed by client\n");
    }
    close(server_fd);
    return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
    install_sigint_handler();
    server_fd = start_server();
    while(1) {
        control_fd = accept_connection(server_fd);
        handle_request(control_fd);
        close(control_fd);
        control_fd = -1;
        printf("Connection closed by client\n");
    }
    close(server_fd);
    return 0;
}


repo: NathanJCochran/myar

decompiled_code:
int __fastcall d_delete(char *name, __int64 a2, unsigned int a3)
{
__int64 v4; // rbp
int v5; // eax
unsigned int v6; // er14
int v7; // eax
__int64 v8; // rbx

v4 = create_arch_itr();
if ( unlink(name) == -1 )
{
perror("Error unlinking file");
exit(0);
}
v5 = open(name, 65, 438LL);
v6 = v5;
if ( v5 == -1 )
{
perror("Error creating new archive file");
exit(0);
}
v7 = write(v5, "!<arch>\n", 8uLL);
if ( v7 != 8 )
{
if ( v7 == -1 )
perror("Error writing archive header to file");
else
printf("Error writing full archive header to file: %s", name);
exit(0);
}
while ( (unsigned __int8)hasNextFile(v4) )
{
v8 = nextFile(v4);
if ( (unsigned __int8)is_member(v8, a2, a3) )
{
remove_member(v8, a2, a3);
}
else
{
write_file_header_to(v4, v6);
write_file_contents_to(v4, v6);
if ( strtol((const char *)(v8 + 53), 0LL, 10) % 2 == 1 )
write(v6, "\n", 1uLL);
}
}
free_arch_itr(v4);
return close(v6);
}

canonical_decompiled_code:
int __fastcall func1(char *name, __int64 a2, unsigned int a3)
{
__int64 v4; // rbp
int v5; // eax
unsigned int v6; // er14
int v7; // eax
__int64 v8; // rbx

v4 = create_arch_itr();
if ( unlink(name) == -1 )
{
perror("Error unlinking file");
exit(0);
}
v5 = open(name, 65, 438LL);
v6 = v5;
if ( v5 == -1 )
{
perror("Error creating new archive file");
exit(0);
}
v7 = write(v5, "!<arch>\n", 8uLL);
if ( v7 != 8 )
{
if ( v7 == -1 )
perror("Error writing archive header to file");
else
printf("Error writing full archive header to file: %s", name);
exit(0);
}
while ( (unsigned __int8)hasNextFile(v4) )
{
v8 = nextFile(v4);
if ( (unsigned __int8)is_member(v8, a2, a3) )
{
remove_member(v8, a2, a3);
}
else
{
write_file_header_to(v4, v6);
write_file_contents_to(v4, v6);
if ( strtol((const char *)(v8 + 53), 0LL, 10) % 2 == 1 )
write(v6, "\n", 1uLL);
}
}
free_arch_itr(v4);
return close(v6);
}

original_code:
void d_delete(char * arch_name, char * members[], int mem_len) {
 int fd, num_written;
 struct ar_file * archfile;
 struct arch_itr * itr = create_arch_itr(arch_name);
 if(unlink(arch_name) == -1) {
  perror("Error unlinking file");
  exit(0);
 }
 if((fd = open(arch_name, 01 | 0100, 0666)) == -1) {
  perror("Error creating new archive file");
  exit(0);
 }
 if ((num_written = write(fd, "!<arch>\n", 8)) != 8) {
  if (num_written == -1)
   perror("Error writing archive header to file");
  else
   printf("Error writing full archive header to file: %s", arch_name);
  exit(0);
 }
 while (hasNextFile(itr)) {
  archfile = nextFile(itr);
  if(is_member(archfile->name, members, mem_len)) {
   remove_member(archfile->name, members, mem_len);
  }
  else {
   write_file_header_to(itr, fd);
   write_file_contents_to(itr, fd);
   if(strtol(archfile->size, ((void *)0), 10)%2 ==1) {
    write(fd, "\n", 1);
   }
  }
 }
 free_arch_itr(itr);
 close(fd);
}

canonical_original_code:
void d_delete(char *arch_name, char *members[], int mem_len) {
 int fd; int num_written;
 struct ar_file *archfile;
 struct arch_itr *itr = create_arch_itr(arch_name);
 if(unlink(arch_name) == -1) {
  perror("Error unlinking file");
  exit(0);
 }
 if((fd = open(arch_name, 01 | 0100, 0666)) == -1) {
  perror("Error creating new archive file");
  exit(0);
 }
 if ((num_written = write(fd, "!<arch>\n", 8)) != 8) {
  if (num_written == -1)
   perror("Error writing archive header to file");
  else
   printf("Error writing full archive header to file: %s", arch_name);
  exit(0);
 }
 while (hasNextFile(itr)) {
  archfile = nextFile(itr);
  if(is_member(archfile->name, members, mem_len)) {
   remove_member(archfile->name, members, mem_len);
  }
  else {
   write_file_header_to(itr, fd);
   write_file_contents_to(itr, fd);
   if(strtol(archfile->size, ((void *)0), 10)%2 ==1) {
    write(fd, "\n", 1);
   }
  }
 }
 free_arch_itr(itr);
 close(fd);
}

variable_types:
members
char *[]

variable_types: struct arch_itr { int fd; struct ar_hdr { char ar_name[16]; char ar_date[12]; char ar_uid[6]; char ar_mode[8]; char ar_size[10]; char ar_fmag[2]; } *header; struct ar_file { char name[17]; char date[13]; char uid[7]; char mode[9]; char size[11]; char fmag[3]; } *archfile; } *

user_defined_types: struct arch_itr { int fd; struct ar_hdr *header; struct ar_file *archfile; }


decompiled_code:
__int64 __fastcall x_extract(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v4; // rbx
__int64 v5; // rax

v4 = create_arch_itr();
if ( a3 )
{
while ( (unsigned __int8)hasNextFile(v4) )
{
v5 = nextFile(v4);
if ( (unsigned __int8)is_member(v5, a2, a3) )
extractFile(v4);
}
}
else
{
while ( (unsigned __int8)hasNextFile(v4) )
extractFile(v4);
}
return free_arch_itr(v4);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v4; // rbx
__int64 v5; // rax

v4 = create_arch_itr();
if ( a3 )
{
while ( (unsigned __int8)hasNextFile(v4) )
{
v5 = nextFile(v4);
if ( (unsigned __int8)is_member(v5, a2, a3) )
extractFile(v4);
}
}
else
{
while ( (unsigned __int8)hasNextFile(v4) )
extractFile(v4);
}
return free_arch_itr(v4);
}

original_code:
void x_extract(char * arch_name, char * members[], int mem_len) {
 struct ar_file * archfile;
 struct arch_itr * itr = create_arch_itr(arch_name);
 if (mem_len == 0) {
  while (hasNextFile(itr)) {
   extractFile(itr);
  }
 }
 else {
  while (hasNextFile(itr)) {
   archfile = nextFile(itr);
   if(is_member(archfile->name, members, mem_len)) {
    extractFile(itr);
   }
  }
 }
 free_arch_itr(itr);
}

canonical_original_code:
void x_extract(char *arch_name, char *members[], int mem_len) {
 struct ar_file *archfile;
 struct arch_itr *itr = create_arch_itr(arch_name);
 if (mem_len == 0) {
  while (hasNextFile(itr)) {
   extractFile(itr);
  }
 }
 else {
  while (hasNextFile(itr)) {
   archfile = nextFile(itr);
   if(is_member(archfile->name, members, mem_len)) {
    extractFile(itr);
   }
  }
 }
 free_arch_itr(itr);
}

variable_types: struct ar_file { char name[17]; char date[13]; char uid[7]; char mode[9]; char size[11]; char fmag[3]; } *

user_defined_types: struct ar_hdr { char ar_name[16]; char ar_date[12]; char ar_uid[6]; char ar_mode[8]; char ar_size[10]; char ar_fmag[2]; }


decompiled_code:
__int64 v_contents()
{
__int64 v0; // rbp
const char *v1; // rbx

v0 = create_arch_itr();
while ( (unsigned __int8)hasNextFile(v0) )
{
v1 = (const char *)nextFile(v0);
print_perms(v1 + 44);
printf("%s/%s ", v1 + 30, v1 + 37);
printf("%6s ", v1 + 53);
print_date(v1 + 17);
printf("%.16s\n", v1);
}
return free_arch_itr(v0);
}

canonical_decompiled_code:
__int64 func3()
{
__int64 v0; // rbp
const char *v1; // rbx

v0 = create_arch_itr();
while ( (unsigned __int8)hasNextFile(v0) )
{
v1 = (const char *)nextFile(v0);
print_perms(v1 + 44);
printf("%s/%s ", v1 + 30, v1 + 37);
printf("%6s ", v1 + 53);
print_date(v1 + 17);
printf("%.16s\n", v1);
}
return free_arch_itr(v0);
}

original_code:
void v_contents(char * arch_name) {
 struct ar_file * archfile;
 struct arch_itr * itr = create_arch_itr(arch_name);
 while (hasNextFile(itr)) {
  archfile = nextFile(itr);
  print_perms(archfile->mode);
  printf("%s/%s ", archfile->uid, archfile->gid);
  printf("%6s ", archfile->size);
  print_date(archfile->date);
  printf("%.16s\n", archfile->name);
 }
 free_arch_itr(itr);
}

canonical_original_code:
void v_contents(char *arch_name) {
 struct ar_file *archfile;
 struct arch_itr *itr = create_arch_itr(arch_name);
 while (hasNextFile(itr)) {
  archfile = nextFile(itr);
  print_perms(archfile->mode);
  printf("%s/%s ", archfile->uid, archfile->gid);
  printf("%6s ", archfile->size);
  print_date(archfile->date);
  printf("%.16s\n", archfile->name);
 }
 free_arch_itr(itr);
}

user_defined_types: struct ar_file { char name[17]; char date[13]; char uid[7]; char mode[9]; char size[11]; char fmag[3]; }


decompiled_code:
__int64 t_contents()
{
__int64 v0; // rbx
const char *v1; // rax

v0 = create_arch_itr();
while ( (unsigned __int8)hasNextFile(v0) )
{
v1 = (const char *)nextFile(v0);
puts(v1);
}
return free_arch_itr(v0);
}

canonical_decompiled_code:
__int64 func4()
{
__int64 v0; // rbx
const char *v1; // rax

v0 = create_arch_itr();
while ( (unsigned __int8)hasNextFile(v0) )
{
v1 = (const char *)nextFile(v0);
puts(v1);
}
return free_arch_itr(v0);
}

original_code:
void t_contents(char * arch_name) {
 struct ar_file * archfile;
 struct arch_itr * itr = create_arch_itr(arch_name);
 while (hasNextFile(itr)) {
  archfile = nextFile(itr);
  printf("%s\n", archfile->name);
 }
 free_arch_itr(itr);
}

canonical_original_code:
void t_contents(char *arch_name) {
 struct ar_file *archfile;
 struct arch_itr *itr = create_arch_itr(arch_name);
 while (hasNextFile(itr)) {
  archfile = nextFile(itr);
  printf("%s\n", archfile->name);
 }
 free_arch_itr(itr);
}


decompiled_code:
int __fastcall q_append(const char *a1, _QWORD *a2, int a3)
{
int v4; // eax
int *v5; // rax
_QWORD *v6; // rbx
__int64 v7; // r12
int v8; // ebx
int v9; // eax

v4 = open(a1, 193, 438LL);
if ( v4 == -1 )
{
v5 = _errno_location();
if ( *v5 != 17 )
{
perror("Error creating new file");
exit(0);
}
}
else
{
v8 = v4;
printf("myar: creating %s\n", a1);
v9 = write(v8, "!<arch>\n", 8uLL);
if ( v9 != 8 )
{
if ( v9 == -1 )
perror("Error writing archive header to file");
else
printf("Error writing full archive header to file: %s", a1);
exit(0);
}
LODWORD(v5) = close(v8);
}
if ( a3 > 0 )
{
v6 = a2;
v7 = (__int64)&a2[(unsigned int)(a3 - 1) + 1];
do
LODWORD(v5) = append_to_arch(a1, *v6++);
while ( v6 != (_QWORD *)v7 );
}
return (int)v5;
}

canonical_decompiled_code:
int __fastcall func5(const char *a1, _QWORD *a2, int a3)
{
int v4; // eax
int *v5; // rax
_QWORD *v6; // rbx
__int64 v7; // r12
int v8; // ebx
int v9; // eax

v4 = open(a1, 193, 438LL);
if ( v4 == -1 )
{
v5 = _errno_location();
if ( *v5 != 17 )
{
perror("Error creating new file");
exit(0);
}
}
else
{
v8 = v4;
printf("myar: creating %s\n", a1);
v9 = write(v8, "!<arch>\n", 8uLL);
if ( v9 != 8 )
{
if ( v9 == -1 )
perror("Error writing archive header to file");
else
printf("Error writing full archive header to file: %s", a1);
exit(0);
}
LODWORD(v5) = close(v8);
}
if ( a3 > 0 )
{
v6 = a2;
v7 = (__int64)&a2[(unsigned int)(a3 - 1) + 1];
do
LODWORD(v5) = append_to_arch(a1, *v6++);
while ( v6 != (_QWORD *)v7 );
}
return (int)v5;
}

original_code:
void q_append(char * arch_name, char * members[], int mem_len) {
 int fd, num_written, i;
 if((fd = open(arch_name, 01 | 0100 | 0200, 0666)) != -1 ) {
  printf("myar: creating %s\n", arch_name);
  if ((num_written = write(fd, "!<arch>\n", 8)) != 8) {
   if (num_written == -1)
    perror("Error writing archive header to file");
   else
    printf("Error writing full archive header to file: %s", arch_name);
   exit(0);
  }
  close(fd);
 }
 else if((*__errno_location ()) != 17) {
  perror("Error creating new file");
  exit(0);
 }
 for (i=0; i<mem_len; i++) {
  append_to_arch(arch_name, members[i]);
 }
}

canonical_original_code:
void q_append(char *arch_name, char *members[], int mem_len) {
 int fd; int num_written; int i;
 if((fd = open(arch_name, 01 | 0100 | 0200, 0666)) != -1 ) {
  printf("myar: creating %s\n", arch_name);
  if ((num_written = write(fd, "!<arch>\n", 8)) != 8) {
   if (num_written == -1)
    perror("Error writing archive header to file");
   else
    printf("Error writing full archive header to file: %s", arch_name);
   exit(0);
  }
  close(fd);
 }
 else if((*__errno_location ()) != 17) {
  perror("Error creating new file");
  exit(0);
 }
 for (i=0; i<mem_len; i++) {
  append_to_arch(arch_name, members[i]);
 }
}

variable_types: i int


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rsp
char s1[64]; // [rsp+0h] [rbp-40h] BYREF

v3 = alloca(8LL * (argc - 3));
get_arch_name(argc, argv, s1);
get_members((unsigned int)argc, argv, s1);
if ( (unsigned __int8)get_arch_opt((unsigned int)argc, argv) != 65 )
{
print_usage(*argv);
exit(0);
}
a_append(s1);
free_members(s1, (unsigned int)(argc - 3));
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rsp
char s1[64]; // [rsp+0h] [rbp-40h] BYREF

v3 = alloca(8LL * (argc - 3));
get_arch_name(argc, argv, s1);
get_members((unsigned int)argc, argv, s1);
if ( (unsigned __int8)get_arch_opt((unsigned int)argc, argv) != 65 )
{
print_usage(*argv);
exit(0);
}
func0(s1);
free_members(s1, (unsigned int)(argc - 3));
return 0;
}

original_code:
int main(int argc, char * argv[]) {
 int mem_len = argc-3;
 char * members[mem_len];
 char arch_name[32];
 get_arch_name(argc, argv, arch_name);
 get_members(argc, argv, members);
 switch(get_arch_opt(argc, argv)){
  case 'q':
   q_append(arch_name, members, mem_len);
   break;
  case 'x':
   x_extract(arch_name, members, mem_len);
   break;
  case 't':
   t_contents(arch_name);
   break;
  case 'v':
   v_contents(arch_name);
   break;
  case 'd':
   d_delete(arch_name, members, mem_len);
   break;
  case 'A':
   a_append(arch_name);
   break;
        default:
            print_usage(argv[0]);
            exit(0);
 }
 free_members(members, mem_len);
 return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
 int mem_len = argc-3;
 char *members[-1];
 char arch_name[32];
 get_arch_name(argc, argv, arch_name);
 get_members(argc, argv, members);
 switch(get_arch_opt(argc, argv)){
  case 'q':
   q_append(arch_name, members, mem_len);
   break;
  case 'x':
   x_extract(arch_name, members, mem_len);
   break;
  case 't':
   t_contents(arch_name);
   break;
  case 'v':
   v_contents(arch_name);
   break;
  case 'd':
   d_delete(arch_name, members, mem_len);
   break;
  case 'A':
   a_append(arch_name);
   break;
        default:
            print_usage(argv[0]);
            exit(0);
 }
 free_members(members, mem_len);
 return 0;
}

variable_types:
members
char *[-1]


decompiled_code:
int __fastcall print_usage(const char *a1)
{
printf("\nUsage: %s {-q|-A|-x|-d|-t|-v} <archive file> [member files...]\n", a1);
puts("\tOptions:");
puts("\t-q - Quickly append the specified member files to the archive.");
puts("\t-A - Append all files in the current directory to the archive");
puts("\t-x - Extract the specified member files from the archive. If no member files are specified, extract all.");
puts("\t-d - Delete the first instance of the specified member files from the archive");
puts("\t-t - Display a table of contents for the archive");
puts("\t-v - Display a verbose table of contents for the archive");
return puts("\t ");
}

canonical_decompiled_code:
int __fastcall func0(const char *a1)
{
printf("\nUsage: %s {-q|-A|-x|-d|-t|-v} <archive file> [member files...]\n", a1);
puts("\tOptions:");
puts("\t-q - Quickly append the specified member files to the archive.");
puts("\t-A - Append all files in the current directory to the archive");
puts("\t-x - Extract the specified member files from the archive. If no member files are specified, extract all.");
puts("\t-d - Delete the first instance of the specified member files from the archive");
puts("\t-t - Display a table of contents for the archive");
puts("\t-v - Display a verbose table of contents for the archive");
return puts("\t ");
}

original_code:
void print_usage(char * prog_name) {
    printf("\nUsage: %s {-q|-A|-x|-d|-t|-v} <archive file> [member files...]\n", prog_name);
    printf("\tOptions:\n");
    printf("\t-q - Quickly append the specified member files to the archive.\n");
    printf("\t-A - Append all files in the current directory to the archive\n");
    printf("\t-x - Extract the specified member files from the archive. If no member files are specified, extract all.\n");
    printf("\t-d - Delete the first instance of the specified member files from the archive\n");
    printf("\t-t - Display a table of contents for the archive\n");
    printf("\t-v - Display a verbose table of contents for the archive\n");
    printf("\t \n");
}

canonical_original_code:
void print_usage(char *prog_name) {
    printf("\nUsage: %s {-q|-A|-x|-d|-t|-v} <archive file> [member files...]\n", prog_name);
    printf("\tOptions:\n");
    printf("\t-q - Quickly append the specified member files to the archive.\n");
    printf("\t-A - Append all files in the current directory to the archive\n");
    printf("\t-x - Extract the specified member files from the archive. If no member files are specified, extract all.\n");
    printf("\t-d - Delete the first instance of the specified member files from the archive\n");
    printf("\t-t - Display a table of contents for the archive\n");
    printf("\t-v - Display a verbose table of contents for the archive\n");
    printf("\t \n");
}


decompiled_code:
__int64 __fastcall get_arch_opt(int a1, const char **a2)
{
const char *v2; // rdx
__int64 result; // rax

if ( a1 <= 1 )
{
puts("Error: No option provided.");
print_usage(*a2);
exit(0);
}
v2 = a2[1];
if ( !strcmp(v2, "-q") )
return 113LL;
if ( !strcmp(v2, "-x") )
return 120LL;
if ( !strcmp(v2, "-t") )
return 116LL;
if ( !strcmp(v2, "-v") )
return 118LL;
if ( !strcmp(v2, "-d") )
return 100LL;
if ( !strcmp(v2, "-A") )
return 65LL;
result = 119LL;
if ( strcmp(v2, "-w") )
{
printf("Error: Invalid option '%s'\n", v2);
exit(0);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, const char **a2)
{
const char *v2; // rdx
__int64 result; // rax

if ( a1 <= 1 )
{
puts("Error: No option provided.");
func0(*a2);
exit(0);
}
v2 = a2[1];
if ( !strcmp(v2, "-q") )
return 113LL;
if ( !strcmp(v2, "-x") )
return 120LL;
if ( !strcmp(v2, "-t") )
return 116LL;
if ( !strcmp(v2, "-v") )
return 118LL;
if ( !strcmp(v2, "-d") )
return 100LL;
if ( !strcmp(v2, "-A") )
return 65LL;
result = 119LL;
if ( strcmp(v2, "-w") )
{
printf("Error: Invalid option '%s'\n", v2);
exit(0);
}
return result;
}

original_code:
char get_arch_opt(int argc, char* argv[]) {
    if(argc < 2) {
        printf("Error: No option provided.\n");
        print_usage(argv[0]);
        exit(0);
    }
    if(strcmp(argv[1], "-q") == 0) {return 'q';}
    if(strcmp(argv[1], "-x") == 0) {return 'x';}
    if(strcmp(argv[1], "-t") == 0) {return 't';}
    if(strcmp(argv[1], "-v") == 0) {return 'v';}
    if(strcmp(argv[1], "-d") == 0) {return 'd';}
    if(strcmp(argv[1], "-A") == 0) {return 'A';}
    if(strcmp(argv[1], "-w") == 0) {return 'w';}
    printf("Error: Invalid option '%s'\n", argv[1]);
    exit(0);
}

canonical_original_code:
char get_arch_opt(int argc, char *argv[]) {
    if(argc < 2) {
        printf("Error: No option provided.\n");
        print_usage(argv[0]);
        exit(0);
    }
    if(strcmp(argv[1], "-q") == 0) {return 'q';}
    if(strcmp(argv[1], "-x") == 0) {return 'x';}
    if(strcmp(argv[1], "-t") == 0) {return 't';}
    if(strcmp(argv[1], "-v") == 0) {return 'v';}
    if(strcmp(argv[1], "-d") == 0) {return 'd';}
    if(strcmp(argv[1], "-A") == 0) {return 'A';}
    if(strcmp(argv[1], "-w") == 0) {return 'w';}
    printf("Error: Invalid option '%s'\n", argv[1]);
    exit(0);
}

return_type: char


decompiled_code:
char *__fastcall get_arch_name(int a1, const char **a2, char *a3)
{
if ( a1 <= 2 )
{
puts("Error: No archive specified.");
print_usage(*a2);
exit(0);
}
return strcpy(a3, a2[2]);
}

canonical_decompiled_code:
char *__fastcall func2(int a1, const char **a2, char *a3)
{
if ( a1 <= 2 )
{
puts("Error: No archive specified.");
func0(*a2);
exit(0);
}
return strcpy(a3, a2[2]);
}

original_code:
void get_arch_name(int argc, char * argv[], char * arch_name) {
    if(argc < 3) {
        printf("Error: No archive specified.\n");
        print_usage(argv[0]);
        exit(0);
    }
 strcpy(arch_name, argv[2]);
}

canonical_original_code:
void get_arch_name(int argc, char *argv[], char *arch_name) {
    if(argc < 3) {
        printf("Error: No archive specified.\n");
        print_usage(argv[0]);
        exit(0);
    }
 strcpy(arch_name, argv[2]);
}


original_code:
void get_members(int argc, char * argv[], char * members[]) {
    int i;
    for (i=0; i<argc-3; i++) {
        members[i] = (char *) malloc(16*sizeof(char));
        strcpy(members[i], argv[i+3]);
    }
}

canonical_original_code:
void get_members(int argc, char *argv[], char *members[]) {
    int i;
    for (i=0; i<argc-3; i++) {
        members[i] = (char *) malloc(16*sizeof(char));
        strcpy(members[i], argv[i+3]);
    }
}


decompiled_code:
void __fastcall free_members(void **a1, int a2)
{
void **v2; // rbx

if ( a2 > 0 )
{
v2 = a1;
do
{
if ( *v2 )
free(*v2);
++v2;
}
while ( v2 != &a1[(unsigned int)(a2 - 1) + 1] );
}
}

canonical_decompiled_code:
void __fastcall func4(void **a1, int a2)
{
void **v2; // rbx

if ( a2 > 0 )
{
v2 = a1;
do
{
if ( *v2 )
free(*v2);
++v2;
}
while ( v2 != &a1[(unsigned int)(a2 - 1) + 1] );
}
}

original_code:
void free_members(char * members[], int mem_len) {
    int i;
    for (i=0; i<mem_len; i++) {
        if (members[i] != ((void *)0)) {
            free(members[i]);
        }
    }
}

canonical_original_code:
void free_members(char *members[], int mem_len) {
    int i;
    for (i=0; i<mem_len; i++) {
        if (members[i] != ((void *)0)) {
            free(members[i]);
        }
    }
}


decompiled_code:
__int64 __fastcall is_member(char *s1, const char **a2, int a3)
{
const char **v3; // rbx
__int64 v4; // rbp

if ( a3 <= 0 )
return 0LL;
v3 = a2;
v4 = (__int64)&a2[(unsigned int)(a3 - 1) + 1];
do
{
if ( *v3 && !strcmp(s1, *v3) )
return 1LL;
++v3;
}
while ( v3 != (const char **)v4 );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *s1, const char **a2, int a3)
{
const char **v3; // rbx
__int64 v4; // rbp

if ( a3 <= 0 )
return 0LL;
v3 = a2;
v4 = (__int64)&a2[(unsigned int)(a3 - 1) + 1];
do
{
if ( *v3 && !strcmp(s1, *v3) )
return 1LL;
++v3;
}
while ( v3 != (const char **)v4 );
return 0LL;
}

original_code:
_Bool is_member(char * name, char * members[], int mem_len) {
    int i;
    for (i=0; i<mem_len; i++) {
        if((members[i] != ((void *)0)) && (strcmp(name, members[i]) == 0)) {
            return 1;
        }
    }
    return 0;
}

canonical_original_code:
_Bool is_member(char *name, char *members[], int mem_len) {
    int i;
    for (i=0; i<mem_len; i++) {
        if((members[i] != ((void *)0)) && (strcmp(name, members[i]) == 0)) {
            return 1;
        }
    }
    return 0;
}

variable_types:
name
char *


decompiled_code:
void __fastcall remove_member(char *s1, const char **a2, int a3)
{
const char **v3; // rbx
__int64 v4; // r13
char *v5; // rbp

if ( a3 > 0 )
{
v3 = a2;
v4 = (__int64)&a2[(unsigned int)(a3 - 1) + 1];
do
{
v5 = (char *)*v3;
if ( *v3 )
{
if ( !strcmp(s1, *v3) )
{
free(v5);
*v3 = 0LL;
}
}
++v3;
}
while ( v3 != (const char **)v4 );
}
}

canonical_decompiled_code:
void __fastcall func6(char *s1, const char **a2, int a3)
{
const char **v3; // rbx
__int64 v4; // r13
char *v5; // rbp

if ( a3 > 0 )
{
v3 = a2;
v4 = (__int64)&a2[(unsigned int)(a3 - 1) + 1];
do
{
v5 = (char *)*v3;
if ( *v3 )
{
if ( !strcmp(s1, *v3) )
{
free(v5);
*v3 = 0LL;
}
}
++v3;
}
while ( v3 != (const char **)v4 );
}
}

original_code:
void remove_member(char * name, char * members[], int mem_len) {
    int i;
    for (i=0; i<mem_len; i++) {
        if((members[i] != ((void *)0)) && (strcmp(name, members[i]) == 0)) {
            free(members[i]);
            members[i] = ((void *)0);
        }
    }
}

canonical_original_code:
void remove_member(char *name, char *members[], int mem_len) {
    int i;
    for (i=0; i<mem_len; i++) {
        if((members[i] != ((void *)0)) && (strcmp(name, members[i]) == 0)) {
            free(members[i]);
            members[i] = ((void *)0);
        }
    }
}


decompiled_code:
int __fastcall print_date(const char *a1)
{
struct tm *v1; // rax
char v3[24]; // [rsp+0h] [rbp-28h] BYREF
time_t timer; // [rsp+18h] [rbp-10h] BYREF

timer = strtol(a1, 0LL, 10);
v1 = localtime(&timer);
if ( !v1 )
{
perror("Error getting localtime");
exit(0);
}
strftime(v3, 0x13uLL, "%b %d %R %Y", v1);
return printf("%s ", v3);
}

canonical_decompiled_code:
int __fastcall func7(const char *a1)
{
struct tm *v1; // rax
char v3[24]; // [rsp+0h] [rbp-28h] BYREF
time_t timer; // [rsp+18h] [rbp-10h] BYREF

timer = strtol(a1, 0LL, 10);
v1 = localtime(&timer);
if ( !v1 )
{
perror("Error getting localtime");
exit(0);
}
strftime(v3, 0x13uLL, "%b %d %R %Y", v1);
return printf("%s ", v3);
}

original_code:
void print_date(char * date_str) {
    long timep;
    char time_str[20];
    struct tm * time_tm;
    timep = strtol(date_str, ((void *)0), 10);
    if((time_tm = localtime((time_t *) &timep)) == ((void *)0)) {
  perror("Error getting localtime");
  exit(0);
 }
    strftime(time_str, sizeof(time_str)-1, "%b %d %R %Y", time_tm);
    printf("%s ", time_str);
}

canonical_original_code:
void print_date(char *date_str) {
    long timep;
    char time_str[20];
    struct tm *time_tm;
    timep = strtol(date_str, ((void *)0), 10);
    if((time_tm = localtime((long *) &timep)) == ((void *)0)) {
  perror("Error getting localtime");
  exit(0);
 }
    strftime(time_str, sizeof(time_str)-1, "%b %d %R %Y", time_tm);
    printf("%s ", time_str);
}

variable_types: timep long

variable_types: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long tm_gmtoff; char *tm_zone; } *


variable_types:
mode
unsigned long

variable_types:
perms
char [10]


decompiled_code:
void *__fastcall init_arch_itr(__int64 a1)
{
void *v1; // rbp
void *result; // rax

v1 = malloc(0x3CuLL);
*(_QWORD *)(a1 + 8) = v1;
result = malloc(0x43uLL);
*(_QWORD *)(a1 + 16) = result;
if ( !result || !v1 )
{
perror("Error allocating memory");
exit(0);
}
return result;
}

canonical_decompiled_code:
void *__fastcall func0(__int64 a1)
{
void *v1; // rbp
void *result; // rax

v1 = malloc(0x3CuLL);
*(_QWORD *)(a1 + 8) = v1;
result = malloc(0x43uLL);
*(_QWORD *)(a1 + 16) = result;
if ( !result || !v1 )
{
perror("Error allocating memory");
exit(0);
}
return result;
}

original_code:
void init_arch_itr(struct arch_itr * itr) {
 itr->header = (struct ar_hdr *) malloc(sizeof(struct ar_hdr));
 itr->archfile = (struct ar_file *) malloc(sizeof(struct ar_file));
 if((itr->header == ((void *)0)) || (itr->archfile == ((void *)0))) {
  perror("Error allocating memory");
  exit(0);
 }
}

canonical_original_code:
void init_arch_itr(struct arch_itr *itr) {
 itr->header = (struct ar_hdr *) malloc(sizeof(struct ar_hdr));
 itr->archfile = (struct ar_file *) malloc(sizeof(struct ar_file));
 if((itr->header == ((void *)0)) || (itr->archfile == ((void *)0))) {
  perror("Error allocating memory");
  exit(0);
 }
}


decompiled_code:
void __fastcall free_arch_itr(void *ptr)
{
if ( close(*(_DWORD *)ptr) == -1 )
{
perror("Error closing archive file");
exit(0);
}
free(*((void **)ptr + 1));
free(*((void **)ptr + 2));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
if ( close(*(_DWORD *)ptr) == -1 )
{
perror("Error closing archive file");
exit(0);
}
free(*((void **)ptr + 1));
free(*((void **)ptr + 2));
free(ptr);
}

original_code:
void free_arch_itr(struct arch_itr * itr) {
 if(close(itr->fd) == -1) {
  perror("Error closing archive file");
  exit(0);
 }
 free(itr->header);
 free(itr->archfile);
 free(itr);
}

canonical_original_code:
void free_arch_itr(struct arch_itr *itr) {
 if(close(itr->fd) == -1) {
  perror("Error closing archive file");
  exit(0);
 }
 free(itr->header);
 free(itr->archfile);
 free(itr);
}


nextFile

decompiled_code:
__int64 __fastcall nextFile(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

original_code:
struct ar_file * nextFile(struct arch_itr * itr) {
 return itr->archfile;
}

canonical_original_code:
struct ar_file *nextFile(struct arch_itr *itr) {
 return itr->archfile;
}

variable_types: struct arch_itr { int fd; struct ar_hdr { char ar_name[16]; char ar_date[12]; char ar_uid[6]; char ar_mode[8]; char ar_size[10]; char ar_fmag[2]; } *header; struct ar_file *archfile; } *

return_type: struct ar_file { char name[17]; char date[13]; char uid[7]; char mode[9]; char size[11]; char fmag[3]; } *


decompiled_code:
ssize_t __fastcall write_file_header_to(__int64 a1, int a2)
{
ssize_t result; // rax

result = write(a2, *(const void **)(a1 + 8), 0x3CuLL);
if ( result == -1 )
{
perror("Error writing file header");
exit(0);
}
return result;
}

canonical_decompiled_code:
ssize_t __fastcall func3(__int64 a1, int a2)
{
ssize_t result; // rax

result = write(a2, *(const void **)(a1 + 8), 0x3CuLL);
if ( result == -1 )
{
perror("Error writing file header");
exit(0);
}
return result;
}

original_code:
void write_file_header_to(struct arch_itr * itr, int fd) {
 if(write(fd, (void *) itr->header, sizeof(struct ar_hdr)) == -1) {
  perror("Error writing file header");
  exit(0);
 }
}

canonical_original_code:
void write_file_header_to(struct arch_itr *itr, int fd) {
 if(write(fd, (void *) itr->header, sizeof(struct ar_hdr)) == -1) {
  perror("Error writing file header");
  exit(0);
 }
}


decompiled_code:
signed __int64 __fastcall get_offset(const char *a1)
{
signed __int64 v1; // rax

v1 = strtoul(a1, 0LL, 10);
return (v1 % 2 == 1) + v1;
}

canonical_decompiled_code:
signed __int64 __fastcall func4(const char *a1)
{
signed __int64 v1; // rax

v1 = strtoul(a1, 0LL, 10);
return (v1 % 2 == 1) + v1;
}

original_code:
long get_offset(char * size) {
 long bytes;
 bytes = strtoul(size, ((void *)0), 10);
    if (bytes % 2 == 1)
        bytes += 1;
 return bytes;
}

canonical_original_code:
long get_offset(char *size) {
 long bytes;
 bytes = strtoul(size, ((void *)0), 10);
    if (bytes % 2 == 1)
        bytes += 1;
 return bytes;
}

variable_types:
size
char *

variable_types: bytes long

return_type: long


decompiled_code:
__int64 __fastcall write_file_contents_to(__int64 a1, int a2)
{
signed __int64 v2; // rax
__int64 v3; // rbx
__int64 result; // rax
char buf[25]; // [rsp+Fh] [rbp-19h] BYREF

v2 = get_offset((const char *)(*(_QWORD *)(a1 + 16) + 53LL));
v3 = 0LL;
if ( lseek(*(_DWORD *)a1, -v2, 1) == -1 )
{
perror("Error seeking in archive file");
exit(0);
}
while ( strtol((const char *)(*(_QWORD *)(a1 + 16) + 53LL), 0LL, 10) > v3 )
{
if ( read(*(_DWORD *)a1, buf, 1uLL) == -1 )
{
perror("Error reading from archive file");
exit(0);
}
++v3;
if ( write(a2, buf, 1uLL) == -1 )
{
perror("Error writing file contents");
exit(0);
}
}
result = strtol((const char *)(*(_QWORD *)(a1 + 16) + 53LL), 0LL, 10) % 2;
if ( result == 1 )
{
result = lseek(*(_DWORD *)a1, 1LL, 1);
if ( result == -1 )
{
perror("Error seeking in archive file");
exit(0);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, int a2)
{
signed __int64 v2; // rax
__int64 v3; // rbx
__int64 result; // rax
char buf[25]; // [rsp+Fh] [rbp-19h] BYREF

v2 = func4((const char *)(*(_QWORD *)(a1 + 16) + 53LL));
v3 = 0LL;
if ( lseek(*(_DWORD *)a1, -v2, 1) == -1 )
{
perror("Error seeking in archive file");
exit(0);
}
while ( strtol((const char *)(*(_QWORD *)(a1 + 16) + 53LL), 0LL, 10) > v3 )
{
if ( read(*(_DWORD *)a1, buf, 1uLL) == -1 )
{
perror("Error reading from archive file");
exit(0);
}
++v3;
if ( write(a2, buf, 1uLL) == -1 )
{
perror("Error writing file contents");
exit(0);
}
}
result = strtol((const char *)(*(_QWORD *)(a1 + 16) + 53LL), 0LL, 10) % 2;
if ( result == 1 )
{
result = lseek(*(_DWORD *)a1, 1LL, 1);
if ( result == -1 )
{
perror("Error seeking in archive file");
exit(0);
}
}
return result;
}

original_code:
void write_file_contents_to(struct arch_itr * itr, int fd) {
 char c;
 if(lseek(itr->fd, (off_t) -(get_offset(itr->archfile->size)), 1) == -1) {
  perror("Error seeking in archive file");
  exit(0);
 }
 int i;
 for(i=0; i<strtol(itr->archfile->size, ((void *)0), 10); i++) {
  if(read(itr->fd, &c, sizeof(c)) == -1) {
   perror("Error reading from archive file");
   exit(0);
  }
  if(write(fd, &c, sizeof(c)) == -1) {
   perror("Error writing file contents");
   exit(0);
  }
 }
 if (strtol(itr->archfile->size, ((void *)0), 10)%2 == 1) {
  if(lseek(itr->fd, (off_t) 1, 1) == -1) {
   perror("Error seeking in archive file");
   exit(0);
  }
 }
}

canonical_original_code:
void write_file_contents_to(struct arch_itr *itr, int fd) {
 char c;
 if(lseek(itr->fd, (off_t) -(get_offset(itr->archfile->size)), 1) == -1) {
  perror("Error seeking in archive file");
  exit(0);
 }
 int i;
 for(i=0; i<strtol(itr->archfile->size, ((void *)0), 10); i++) {
  if(read(itr->fd, &c, sizeof(c)) == -1) {
   perror("Error reading from archive file");
   exit(0);
  }
  if(write(fd, &c, sizeof(c)) == -1) {
   perror("Error writing file contents");
   exit(0);
  }
 }
 if (strtol(itr->archfile->size, ((void *)0), 10)%2 == 1) {
  if(lseek(itr->fd, (long) 1, 1) == -1) {
   perror("Error seeking in archive file");
   exit(0);
  }
 }
}

variable_types: fd int


extractFile

decompiled_code:
int __fastcall extractFile(__int64 a1)
{
unsigned __int64 v1; // rbp
int v2; // eax
int v3; // ebp
int result; // eax
struct utimbuf v5; // [rsp+0h] [rbp-28h] BYREF

v1 = strtoul((const char *)(*(_QWORD *)(a1 + 16) + 44LL), 0LL, 8);
v5.modtime = strtoul((const char *)(*(_QWORD *)(a1 + 16) + 17LL), 0LL, 10);
v5.actime = v5.modtime;
v2 = open(*(const char **)(a1 + 16), 65, v1);
if ( v2 == -1 )
{
perror("Error opening/creating file");
exit(0);
}
v3 = v2;
write_file_contents_to(a1, v2);
if ( close(v3) == -1 )
{
perror("Error closing extracted file");
exit(0);
}
result = utime(*(const char **)(a1 + 16), &v5);
if ( result == -1 )
{
perror("Error setting timestamp of extracted file");
exit(0);
}
return result;
}

canonical_decompiled_code:
int __fastcall func6(__int64 a1)
{
unsigned __int64 v1; // rbp
int v2; // eax
int v3; // ebp
int result; // eax
struct utimbuf v5; // [rsp+0h] [rbp-28h] BYREF

v1 = strtoul((const char *)(*(_QWORD *)(a1 + 16) + 44LL), 0LL, 8);
v5.modtime = strtoul((const char *)(*(_QWORD *)(a1 + 16) + 17LL), 0LL, 10);
v5.actime = v5.modtime;
v2 = open(*(const char **)(a1 + 16), 65, v1);
if ( v2 == -1 )
{
perror("Error opening/creating file");
exit(0);
}
v3 = v2;
func5(a1, v2);
if ( close(v3) == -1 )
{
perror("Error closing extracted file");
exit(0);
}
result = utime(*(const char **)(a1 + 16), &v5);
if ( result == -1 )
{
perror("Error setting timestamp of extracted file");
exit(0);
}
return result;
}

original_code:
void extractFile(struct arch_itr * itr) {
 int fd;
 unsigned long mode;
 struct utimbuf times;
 mode = strtoul(itr->archfile->mode, ((void *)0), 8);
 times.actime = times.modtime = (time_t) strtoul(itr->archfile->date, ((void *)0), 10);
 if ((fd = open(itr->archfile->name, 01 | 0100, mode)) == -1) {
  perror("Error opening/creating file");
  exit(0);
 }
 write_file_contents_to(itr, fd);
 if(close(fd) == -1) {
  perror("Error closing extracted file");
  exit(0);
 }
 if(utime(itr->archfile->name, &times) == -1) {
  perror("Error setting timestamp of extracted file");
  exit(0);
 }
}

canonical_original_code:
void extractFile(struct arch_itr *itr) {
 int fd;
 unsigned long mode;
 struct utimbuf times;
 mode = strtoul(itr->archfile->mode, ((void *)0), 8);
 times.actime = times.modtime = (long) strtoul(itr->archfile->date, ((void *)0), 10);
 if ((fd = open(itr->archfile->name, 01 | 0100, mode)) == -1) {
  perror("Error opening/creating file");
  exit(0);
 }
 write_file_contents_to(itr, fd);
 if(close(fd) == -1) {
  perror("Error closing extracted file");
  exit(0);
 }
 if(utime(itr->archfile->name, &times) == -1) {
  perror("Error setting timestamp of extracted file");
  exit(0);
 }
}

variable_types: struct utimbuf { long actime; long modtime; }


decompiled_code:
bool __fastcall get_header(int a1, void *a2)
{
int v2; // eax

v2 = read(a1, a2, 0x3CuLL);
if ( v2 == -1 )
{
perror("Error reading header from archive file");
exit(0);
}
return v2 == 60;
}

canonical_decompiled_code:
bool __fastcall func7(int a1, void *a2)
{
int v2; // eax

v2 = read(a1, a2, 0x3CuLL);
if ( v2 == -1 )
{
perror("Error reading header from archive file");
exit(0);
}
return v2 == 60;
}

original_code:
_Bool get_header(int fd, struct ar_hdr * header) {
    int num_read = read(fd, (void *) header, sizeof(struct ar_hdr));
    if (num_read == -1) {
        perror("Error reading header from archive file");
        exit(0);
    }
    if (num_read == sizeof(struct ar_hdr)) {
        return 1;
    }
    else {
        return 0;
    }
}

canonical_original_code:
_Bool get_header(int fd, struct ar_hdr *header) {
    int num_read = read(fd, (void *) header, sizeof(struct ar_hdr));
    if (num_read == -1) {
        perror("Error reading header from archive file");
        exit(0);
    }
    if (num_read == sizeof(struct ar_hdr)) {
        return 1;
    }
    else {
        return 0;
    }
}

variable_types: struct ar_hdr { char ar_name[16]; char ar_date[12]; char ar_uid[6]; char ar_mode[8]; char ar_size[10]; char ar_fmag[2]; } *


hasNextFile

decompiled_code:
__int64 __fastcall hasNextFile(__int64 a1)
{
unsigned int v1; // eax
unsigned int v2; // ebp
signed __int64 v4; // rax

LOBYTE(v1) = get_header(*(_DWORD *)a1, *(void **)(a1 + 8));
v2 = v1;
if ( (_BYTE)v1 )
{
get_archfile(*(_BYTE **)(a1 + 8), *(_QWORD *)(a1 + 16));
v4 = get_offset((const char *)(*(_QWORD *)(a1 + 16) + 53LL));
if ( lseek(*(_DWORD *)a1, v4, 1) == -1 )
{
perror("Error seeking in archive file");
exit(0);
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
unsigned int v1; // eax
unsigned int v2; // ebp
signed __int64 v4; // rax

LOBYTE(v1) = func7(*(_DWORD *)a1, *(void **)(a1 + 8));
v2 = v1;
if ( (_BYTE)v1 )
{
get_archfile(*(_BYTE **)(a1 + 8), *(_QWORD *)(a1 + 16));
v4 = func4((const char *)(*(_QWORD *)(a1 + 16) + 53LL));
if ( lseek(*(_DWORD *)a1, v4, 1) == -1 )
{
perror("Error seeking in archive file");
exit(0);
}
}
return v2;
}

original_code:
_Bool hasNextFile(struct arch_itr * itr) {
    if (get_header(itr->fd, itr->header)) {
        get_archfile(itr->header, itr->archfile);
        if(lseek(itr->fd, (off_t) get_offset(itr->archfile->size), 1) == -1) {
   perror("Error seeking in archive file");
   exit(0);
  }
  return 1;
    }
    else {
        return 0;
 }
}

canonical_original_code:
_Bool hasNextFile(struct arch_itr *itr) {
    if (get_header(itr->fd, itr->header)) {
        get_archfile(itr->header, itr->archfile);
        if(lseek(itr->fd, (long) get_offset(itr->archfile->size), 1) == -1) {
   perror("Error seeking in archive file");
   exit(0);
  }
  return 1;
    }
    else {
        return 0;
 }
}


CutString

repo: Nebuleon/hocoslamfy

original_code:
static uint32_t CutString(const char* String, const uint32_t MaxWidth,
 struct StringCut* Cuts, uint32_t CutsAllocated)
{
 uint32_t Cut = 0;
 uint32_t CutStart = 0, Cur = 0, CutWidth = 0;
 uint32_t LastSpace = -1;
 _Bool SpaceInCut = 0;
 while (String[Cur] != '\0')
 {
  if (String[Cur] != '\n')
  {
   if (String[Cur] == ' ')
   {
    LastSpace = Cur;
    SpaceInCut = 1;
   }
   CutWidth += _font_width[(uint8_t) String[Cur]];
  }
  if (String[Cur] == '\n' || CutWidth > MaxWidth)
  {
   if (Cut < CutsAllocated)
    Cuts[Cut].Start = CutStart;
   if (String[Cur] == '\n')
   {
    if (Cut < CutsAllocated)
     Cuts[Cut].End = Cur;
   }
   else if (CutWidth > MaxWidth)
   {
    if (SpaceInCut)
    {
     if (Cut < CutsAllocated)
      Cuts[Cut].End = LastSpace;
     Cur = LastSpace;
    }
    else
    {
     if (Cut < CutsAllocated)
      Cuts[Cut].End = Cur;
     Cur--;
    }
   }
   CutStart = Cur + 1;
   CutWidth = 0;
   SpaceInCut = 0;
   Cut++;
  }
  Cur++;
 }
 if (Cut < CutsAllocated)
 {
  Cuts[Cut].Start = CutStart;
  Cuts[Cut].End = Cur;
 }
 return Cut + 1;
}

canonical_original_code:
static unsigned int CutString(char *String, unsigned int MaxWidth, struct StringCut *Cuts, unsigned int CutsAllocated)
{
 unsigned int Cut = 0;
 unsigned int CutStart = 0; unsigned int Cur = 0; unsigned int CutWidth = 0;
 unsigned int LastSpace = -1;
 _Bool SpaceInCut = 0;
 while (String[Cur] != '\0')
 {
  if (String[Cur] != '\n')
  {
   if (String[Cur] == ' ')
   {
    LastSpace = Cur;
    SpaceInCut = 1;
   }
   CutWidth += _font_width[(unsigned char) String[Cur]];
  }
  if (String[Cur] == '\n' || CutWidth > MaxWidth)
  {
   if (Cut < CutsAllocated)
    Cuts[Cut].Start = CutStart;
   if (String[Cur] == '\n')
   {
    if (Cut < CutsAllocated)
     Cuts[Cut].End = Cur;
   }
   else if (CutWidth > MaxWidth)
   {
    if (SpaceInCut)
    {
     if (Cut < CutsAllocated)
      Cuts[Cut].End = LastSpace;
     Cur = LastSpace;
    }
    else
    {
     if (Cut < CutsAllocated)
      Cuts[Cut].End = Cur;
     Cur--;
    }
   }
   CutStart = Cur + 1;
   CutWidth = 0;
   SpaceInCut = 0;
   Cut++;
  }
  Cur++;
 }
 if (Cut < CutsAllocated)
 {
  Cuts[Cut].Start = CutStart;
  Cuts[Cut].End = Cur;
 }
 return Cut + 1;
}

variable_types:
String
char *

variable_types:
MaxWidth
unsigned int

variable_types: struct StringCut { unsigned int Start; unsigned int End; } *

variable_types:
CutsAllocated
unsigned int

variable_types:
Cut
unsigned int

variable_types:
CutStart
unsigned int

variable_types:
Cur
unsigned int

variable_types:
CutWidth
unsigned int

variable_types:
LastSpace
unsigned int

return_type: unsigned int


GetSectionRenderedWidth

decompiled_code:
__int64 __fastcall GetSectionRenderedWidth(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned __int8 *v3; // rax
__int64 v4; // rsi
unsigned int v5; // edx

if ( a2 >= a3 )
return 0;
v3 = (unsigned __int8 *)(a1 + a2);
v4 = (__int64)&v3[a3 - 1 - a2 + 1];
v5 = 0;
do
v5 += *((unsigned __int8 *)&font_width + *v3++);
while ( v3 != (unsigned __int8 *)v4 );
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned __int8 *v3; // rax
__int64 v4; // rsi
unsigned int v5; // edx

if ( a2 >= a3 )
return 0;
v3 = (unsigned __int8 *)(a1 + a2);
v4 = (__int64)&v3[a3 - 1 - a2 + 1];
v5 = 0;
do
v5 += *((unsigned __int8 *)&font_width + *v3++);
while ( v3 != (unsigned __int8 *)v4 );
return v5;
}

original_code:
uint32_t GetSectionRenderedWidth(const char* String, const uint32_t Start, const uint32_t End)
{
 uint32_t Result = 0, i;
 for (i = Start; i < End; i++)
  Result += _font_width[(uint8_t) String[i]];
 return Result;
}

canonical_original_code:
unsigned int GetSectionRenderedWidth(char *String, unsigned int Start, unsigned int End)
{
 unsigned int Result = 0; unsigned int i;
 for (i = Start; i < End; i++)
  Result += _font_width[(unsigned char) String[i]];
 return Result;
}

variable_types:
Start
unsigned int

variable_types:
End
unsigned int

variable_types:
Result
unsigned int

variable_types:
i
unsigned int


original_code:
void PrintString16(const char* String, uint16_t TextColor,
 void* Dest, uint32_t DestPitch, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height,
 enum HorizontalAlignment HorizontalAlignment, enum VerticalAlignment VerticalAlignment)
{
 struct StringCut* Cuts = malloc((Height / _font_height) * sizeof(struct StringCut));
 uint32_t CutCount = CutString(String, Width, Cuts, Height / _font_height), Cut;
 if (CutCount > Height / _font_height)
  CutCount = Height / _font_height;
 for (Cut = 0; Cut < CutCount; Cut++)
 {
  uint32_t TextWidth = GetSectionRenderedWidth(String, Cuts[Cut].Start, Cuts[Cut].End);
  uint32_t LineX, LineY;
  switch (HorizontalAlignment)
  {
   case LEFT: LineX = X; break;
   case CENTER: LineX = X + (Width - TextWidth) / 2; break;
   case RIGHT: LineX = (X + Width) - TextWidth; break;
   default: LineX = 0; break;
  }
  switch (VerticalAlignment)
  {
   case TOP:
    LineY = Y + Cut * _font_height;
    break;
   case MIDDLE:
    LineY = Y + (Height - CutCount * _font_height) / 2 + Cut * _font_height;
    break;
   case BOTTOM:
    LineY = (Y + Height) - (CutCount - Cut) * _font_height;
    break;
   default:
    LineY = 0;
    break;
  }
  uint32_t Cur;
  for (Cur = Cuts[Cut].Start; Cur < Cuts[Cut].End; Cur++)
  {
   uint32_t glyph_offset = (uint32_t) String[Cur] * _font_height;
   uint32_t glyph_width = _font_width[(uint8_t) String[Cur]];
   uint32_t glyph_column, glyph_row;
   uint16_t current_halfword;
   for(glyph_row = 0; glyph_row < _font_height; glyph_row++, glyph_offset++)
   {
    current_halfword = _font_bits[glyph_offset];
    for (glyph_column = 0; glyph_column < glyph_width; glyph_column++)
    {
     if ((current_halfword >> (15 - glyph_column)) & 0x01)
      *(uint16_t*) ((uint8_t*) Dest + (LineY + glyph_row) * DestPitch + (LineX + glyph_column) * sizeof(uint16_t)) = TextColor;
    }
   }
   LineX += glyph_width;
  }
 }
 free(Cuts);
}

canonical_original_code:
void PrintString16(char *String, unsigned short TextColor, void *Dest, unsigned int DestPitch, unsigned int X, unsigned int Y, unsigned int Width, unsigned int Height, enum HorizontalAlignment HorizontalAlignment, enum VerticalAlignment VerticalAlignment)
{
 struct StringCut *Cuts = malloc((Height / _font_height) * sizeof(struct StringCut));
 unsigned int CutCount = CutString(String, Width, Cuts, Height / _font_height); unsigned int Cut;
 if (CutCount > Height / _font_height)
  CutCount = Height / _font_height;
 for (Cut = 0; Cut < CutCount; Cut++)
 {
  unsigned int TextWidth = GetSectionRenderedWidth(String, Cuts[Cut].Start, Cuts[Cut].End);
  unsigned int LineX; unsigned int LineY;
  switch (HorizontalAlignment)
  {
   case LEFT: LineX = X; break;
   case CENTER: LineX = X + (Width - TextWidth) / 2; break;
   case RIGHT: LineX = (X + Width) - TextWidth; break;
   default: LineX = 0; break;
  }
  switch (VerticalAlignment)
  {
   case TOP:
    LineY = Y + Cut * _font_height;
    break;
   case MIDDLE:
    LineY = Y + (Height - CutCount * _font_height) / 2 + Cut * _font_height;
    break;
   case BOTTOM:
    LineY = (Y + Height) - (CutCount - Cut) * _font_height;
    break;
   default:
    LineY = 0;
    break;
  }
  unsigned int Cur;
  for (Cur = Cuts[Cut].Start; Cur < Cuts[Cut].End; Cur++)
  {
   unsigned int glyph_offset = (uint32_t) String[Cur] * _font_height;
   unsigned int glyph_width = _font_width[(uint8_t) String[Cur]];
   unsigned int glyph_column; unsigned int glyph_row;
   unsigned short current_halfword;
   for(glyph_row = 0; glyph_row < _font_height; glyph_row++, glyph_offset++)
   {
    current_halfword = _font_bits[glyph_offset];
    for (glyph_column = 0; glyph_column < glyph_width; glyph_column++)
    {
     if ((current_halfword >> (15 - glyph_column)) & 0x01)
      *(unsigned short *) ((unsigned char *) Dest + (LineY + glyph_row) * DestPitch + (LineX + glyph_column) * sizeof(unsigned short)) = TextColor;
    }
   }
   LineX += glyph_width;
  }
 }
 free(Cuts);
}

variable_types:
TextColor
unsigned short

variable_types:
Dest
void *

variable_types:
DestPitch
unsigned int

variable_types:
X
unsigned int

variable_types:
Y
unsigned int

variable_types:
Width
unsigned int

variable_types:
Height
unsigned int

variable_types: enum HorizontalAlignment { LEFT=0, CENTER=1, RIGHT=2 }

variable_types: enum VerticalAlignment { TOP=0, MIDDLE=1, BOTTOM=2 }

variable_types:
CutCount
unsigned int

variable_types:
TextWidth
unsigned int

variable_types:
LineX
unsigned int

variable_types:
LineY
unsigned int

user_defined_types: struct StringCut { unsigned int Start; unsigned int End; }


original_code:
void PrintString32(const char* String, uint32_t TextColor,
 void* Dest, uint32_t DestPitch, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height,
 enum HorizontalAlignment HorizontalAlignment, enum VerticalAlignment VerticalAlignment)
{
 struct StringCut* Cuts = malloc((Height / _font_height) * sizeof(struct StringCut));
 uint32_t CutCount = CutString(String, Width, Cuts, Height / _font_height), Cut;
 if (CutCount > Height / _font_height)
  CutCount = Height / _font_height;
 for (Cut = 0; Cut < CutCount; Cut++)
 {
  uint32_t TextWidth = GetSectionRenderedWidth(String, Cuts[Cut].Start, Cuts[Cut].End);
  uint32_t LineX, LineY;
  switch (HorizontalAlignment)
  {
   case LEFT: LineX = X; break;
   case CENTER: LineX = X + (Width - TextWidth) / 2; break;
   case RIGHT: LineX = (X + Width) - TextWidth; break;
   default: LineX = 0; break;
  }
  switch (VerticalAlignment)
  {
   case TOP:
    LineY = Y + Cut * _font_height;
    break;
   case MIDDLE:
    LineY = Y + (Height - CutCount * _font_height) / 2 + Cut * _font_height;
    break;
   case BOTTOM:
    LineY = (Y + Height) - (CutCount - Cut) * _font_height;
    break;
   default:
    LineY = 0;
    break;
  }
  uint32_t Cur;
  for (Cur = Cuts[Cut].Start; Cur < Cuts[Cut].End; Cur++)
  {
   uint32_t glyph_offset = (uint32_t) String[Cur] * _font_height;
   uint32_t glyph_width = _font_width[(uint8_t) String[Cur]];
   uint32_t glyph_column, glyph_row;
   uint16_t current_halfword;
   for(glyph_row = 0; glyph_row < _font_height; glyph_row++, glyph_offset++)
   {
    current_halfword = _font_bits[glyph_offset];
    for (glyph_column = 0; glyph_column < glyph_width; glyph_column++)
    {
     if ((current_halfword >> (15 - glyph_column)) & 0x01)
      *(uint32_t*) ((uint8_t*) Dest + (LineY + glyph_row) * DestPitch + (LineX + glyph_column) * sizeof(uint32_t)) = TextColor;
    }
   }
   LineX += glyph_width;
  }
 }
 free(Cuts);
}

canonical_original_code:
void PrintString32(char *String, unsigned int TextColor, void *Dest, unsigned int DestPitch, unsigned int X, unsigned int Y, unsigned int Width, unsigned int Height, enum HorizontalAlignment HorizontalAlignment, enum VerticalAlignment VerticalAlignment)
{
 struct StringCut *Cuts = malloc((Height / _font_height) * sizeof(struct StringCut));
 unsigned int CutCount = CutString(String, Width, Cuts, Height / _font_height); unsigned int Cut;
 if (CutCount > Height / _font_height)
  CutCount = Height / _font_height;
 for (Cut = 0; Cut < CutCount; Cut++)
 {
  unsigned int TextWidth = GetSectionRenderedWidth(String, Cuts[Cut].Start, Cuts[Cut].End);
  unsigned int LineX; unsigned int LineY;
  switch (HorizontalAlignment)
  {
   case LEFT: LineX = X; break;
   case CENTER: LineX = X + (Width - TextWidth) / 2; break;
   case RIGHT: LineX = (X + Width) - TextWidth; break;
   default: LineX = 0; break;
  }
  switch (VerticalAlignment)
  {
   case TOP:
    LineY = Y + Cut * _font_height;
    break;
   case MIDDLE:
    LineY = Y + (Height - CutCount * _font_height) / 2 + Cut * _font_height;
    break;
   case BOTTOM:
    LineY = (Y + Height) - (CutCount - Cut) * _font_height;
    break;
   default:
    LineY = 0;
    break;
  }
  unsigned int Cur;
  for (Cur = Cuts[Cut].Start; Cur < Cuts[Cut].End; Cur++)
  {
   unsigned int glyph_offset = (uint32_t) String[Cur] * _font_height;
   unsigned int glyph_width = _font_width[(uint8_t) String[Cur]];
   unsigned int glyph_column; unsigned int glyph_row;
   unsigned short current_halfword;
   for(glyph_row = 0; glyph_row < _font_height; glyph_row++, glyph_offset++)
   {
    current_halfword = _font_bits[glyph_offset];
    for (glyph_column = 0; glyph_column < glyph_width; glyph_column++)
    {
     if ((current_halfword >> (15 - glyph_column)) & 0x01)
      *(unsigned int *) ((unsigned char *) Dest + (LineY + glyph_row) * DestPitch + (LineX + glyph_column) * sizeof(unsigned int)) = TextColor;
    }
   }
   LineX += glyph_width;
  }
 }
 free(Cuts);
}

variable_types:
String
char *

variable_types:
TextColor
unsigned int

variable_types: struct StringCut { unsigned int Start; unsigned int End; } *

variable_types:
Cut
unsigned int

variable_types:
Cur
unsigned int

user_defined_types: enum HorizontalAlignment { LEFT=0, CENTER=1, RIGHT=2 }

user_defined_types: enum VerticalAlignment { TOP=0, MIDDLE=1, BOTTOM=2 }


GetRenderedWidth

decompiled_code:
__int64 __fastcall GetRenderedWidth(unsigned __int8 *a1)
{
void *v2; // rbp
unsigned int v3; // eax
unsigned int v4; // er12
__int64 v5; // rdi
unsigned int v6; // ebx
unsigned int v7; // er9
unsigned int v8; // ecx
unsigned __int8 *v9; // rax
unsigned int v10; // edx

v2 = malloc(8uLL);
v3 = CutString(a1, 0xFFFFFFFF, (__int64)v2, 1u);
v4 = v3;
if ( v3 > 1 )
{
v2 = realloc(v2, 8LL * v3);
CutString(a1, 0xFFFFFFFF, (__int64)v2, v4);
}
else if ( !v3 )
{
v6 = 0;
goto LABEL_10;
}
v5 = 0LL;
v6 = 0;
do
{
v7 = *((_DWORD *)v2 + 2 * v5);
v8 = *((_DWORD *)v2 + 2 * v5 + 1);
if ( v7 >= v8 )
{
v10 = 0;
}
else
{
v9 = &a1[v7];
v10 = 0;
do
v10 += *((unsigned __int8 *)&font_width + *v9++);
while ( v9 != &a1[v7 + 1 + v8 - 1 - v7] );
}
if ( v6 < v10 )
v6 = v10;
++v5;
}
while ( v4 > (unsigned int)v5 );
LABEL_10:
free(v2);
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int8 *a1)
{
void *v2; // rbp
unsigned int v3; // eax
unsigned int v4; // er12
__int64 v5; // rdi
unsigned int v6; // ebx
unsigned int v7; // er9
unsigned int v8; // ecx
unsigned __int8 *v9; // rax
unsigned int v10; // edx

v2 = malloc(8uLL);
v3 = func0(a1, 0xFFFFFFFF, (__int64)v2, 1u);
v4 = v3;
if ( v3 > 1 )
{
v2 = realloc(v2, 8LL * v3);
func0(a1, 0xFFFFFFFF, (__int64)v2, v4);
}
else if ( !v3 )
{
v6 = 0;
goto LABEL_10;
}
v5 = 0LL;
v6 = 0;
do
{
v7 = *((_DWORD *)v2 + 2 * v5);
v8 = *((_DWORD *)v2 + 2 * v5 + 1);
if ( v7 >= v8 )
{
v10 = 0;
}
else
{
v9 = &a1[v7];
v10 = 0;
do
v10 += *((unsigned __int8 *)&font_width + *v9++);
while ( v9 != &a1[v7 + 1 + v8 - 1 - v7] );
}
if ( v6 < v10 )
v6 = v10;
++v5;
}
while ( v4 > (unsigned int)v5 );
LABEL_10:
free(v2);
return v6;
}

original_code:
uint32_t GetRenderedWidth(const char* str)
{
 struct StringCut* Cuts = malloc(sizeof(struct StringCut));
 uint32_t CutCount = CutString(str, (4294967295U), Cuts, 1);
 if (CutCount > 1)
 {
  Cuts = realloc(Cuts, CutCount * sizeof(struct StringCut));
  CutString(str, (4294967295U), Cuts, CutCount);
 }
 uint32_t Result = 0, LineWidth, Cut;
 for (Cut = 0; Cut < CutCount; Cut++)
 {
  LineWidth = 0;
  uint32_t Cur;
  for (Cur = Cuts[Cut].Start; Cur < Cuts[Cut].End; Cur++)
  {
   LineWidth += _font_width[(uint8_t) str[Cur]];
  }
  if (LineWidth > Result)
   Result = LineWidth;
 }
 free(Cuts);
 return Result;
}

canonical_original_code:
unsigned int GetRenderedWidth(char *str)
{
 struct StringCut *Cuts = malloc(sizeof(struct StringCut));
 unsigned int CutCount = CutString(str, (4294967295U), Cuts, 1);
 if (CutCount > 1)
 {
  Cuts = realloc(Cuts, CutCount * sizeof(struct StringCut));
  CutString(str, (4294967295U), Cuts, CutCount);
 }
 unsigned int Result = 0; unsigned int LineWidth; unsigned int Cut;
 for (Cut = 0; Cut < CutCount; Cut++)
 {
  LineWidth = 0;
  unsigned int Cur;
  for (Cur = Cuts[Cut].Start; Cur < Cuts[Cut].End; Cur++)
  {
   LineWidth += _font_width[(unsigned char) str[Cur]];
  }
  if (LineWidth > Result)
   Result = LineWidth;
 }
 free(Cuts);
 return Result;
}

variable_types:
str
char *

variable_types:
Result
unsigned int

variable_types:
LineWidth
unsigned int


GetRenderedHeight

decompiled_code:
__int64 __fastcall GetRenderedHeight(unsigned __int8 *a1)
{
return (unsigned int)CutString(a1, 0xFFFFFFFF, 0LL, 0) * font_height;
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned __int8 *a1)
{
return (unsigned int)func0(a1, 0xFFFFFFFF, 0LL, 0) * font_height;
}

original_code:
uint32_t GetRenderedHeight(const char* str)
{
 return CutString(str, (4294967295U), ((void *)0), 0) * _font_height;
}

canonical_original_code:
unsigned int GetRenderedHeight(char *str)
{
 return CutString(str, (4294967295U), ((void *)0), 0) * _font_height;
}