decompiled_code:
_QWORD *new_threaded_binary_node()
{
_QWORD *result; // rax

result = malloc(0x20uLL);
if ( result )
{
*result = 0LL;
result[1] = 0LL;
*((_BYTE *)result + 16) = 110;
result[3] = 0LL;
}
return result;
}

canonical_decompiled_code:
_QWORD *func0()
{
_QWORD *result; // rax

result = malloc(0x20uLL);
if ( result )
{
*result = 0LL;
result[1] = 0LL;
*((_BYTE *)result + 16) = 110;
result[3] = 0LL;
}
return result;
}

original_code:
struct threaded_binary_node * new_threaded_binary_node() {
    struct threaded_binary_node * result = malloc( sizeof( struct threaded_binary_node ) );
    if ( !result ) {
        return ((void *)0);
    }
    result->left_link = ((void *)0);
    result->right_link = ((void *)0);
    result->threaded = 'n';
    result->data = ((void *)0);
    return result;
}

canonical_original_code:
struct threaded_binary_node *new_threaded_binary_node() {
    struct threaded_binary_node *result = malloc( sizeof( struct threaded_binary_node ) );
    if ( !result ) {
        return ((void *)0);
    }
    result->left_link = ((void *)0);
    result->right_link = ((void *)0);
    result->threaded = 'n';
    result->data = ((void *)0);
    return result;
}

variable_types: struct threaded_binary_node { struct threaded_binary_node *left_link; struct threaded_binary_node *right_link; char threaded; void *data; } *


decompiled_code:
_QWORD *new_threaded_binary_head()
{
_QWORD *result; // rax

result = new_threaded_binary_node();
result[1] = result;
*result = result;
*((_BYTE *)result + 16) = 108;
return result;
}

canonical_decompiled_code:
_QWORD *func1()
{
_QWORD *result; // rax

result = func0();
result[1] = result;
*result = result;
*((_BYTE *)result + 16) = 108;
return result;
}

original_code:
struct threaded_binary_node * new_threaded_binary_head() {
    struct threaded_binary_node * head = new_threaded_binary_node();
    head->right_link = head;
    head->left_link = head;
    head->threaded = 'l';
    return head;
}

canonical_original_code:
struct threaded_binary_node *new_threaded_binary_head() {
    struct threaded_binary_node *head = new_threaded_binary_node();
    head->right_link = head;
    head->left_link = head;
    head->threaded = 'l';
    return head;
}

return_type: struct threaded_binary_node { struct threaded_binary_node *left_link; struct threaded_binary_node *right_link; char threaded; void *data; } *


original_code:
struct threaded_binary_node * insert_left_leaf( struct threaded_binary_node * node, struct threaded_binary_node * child ) {
    child->left_link = node->left_link;
    node->left_link = child;
    child->right_link = node;
    child->threaded = 'b';
    if ( node->right_link == node ||
         node->threaded == 'l' ) {
        node->threaded = 'n';
    } else {
        node->threaded = 'r';
    }
    return child;
}

canonical_original_code:
struct threaded_binary_node *insert_left_leaf(struct threaded_binary_node *node, struct threaded_binary_node *child) {
    child->left_link = node->left_link;
    node->left_link = child;
    child->right_link = node;
    child->threaded = 'b';
    if ( node->right_link == node ||
         node->threaded == 'l' ) {
        node->threaded = 'n';
    } else {
        node->threaded = 'r';
    }
    return child;
}

variable_types:
node
struct threaded_binary_node *

variable_types:
child
struct threaded_binary_node *

user_defined_types: struct threaded_binary_node { struct threaded_binary_node *left_link; struct threaded_binary_node *right_link; char threaded; void *data; }


original_code:
struct threaded_binary_node * insert_right_leaf( struct threaded_binary_node * node, struct threaded_binary_node * child ) {
    child->right_link = node->right_link;
    node->right_link = child;
    child->left_link = node;
    child->threaded = 'b';
    if ( node->threaded == 'b' ) {
        node->threaded = 'l';
    } else {
        node->threaded = 'n';
    }
    return child;
}

canonical_original_code:
struct threaded_binary_node *insert_right_leaf(struct threaded_binary_node *node, struct threaded_binary_node *child) {
    child->right_link = node->right_link;
    node->right_link = child;
    child->left_link = node;
    child->threaded = 'b';
    if ( node->threaded == 'b' ) {
        node->threaded = 'l';
    } else {
        node->threaded = 'n';
    }
    return child;
}


decompiled_code:
__int64 __fastcall get_threaded_left_child(__int64 *a1)
{
char v1; // al
__int64 result; // rax

v1 = *((_BYTE *)a1 + 16);
if ( v1 == 108 || v1 == 98 )
result = 0LL;
else
result = *a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 *a1)
{
char v1; // al
__int64 result; // rax

v1 = *((_BYTE *)a1 + 16);
if ( v1 == 108 || v1 == 98 )
result = 0LL;
else
result = *a1;
return result;
}

original_code:
struct threaded_binary_node * get_threaded_left_child( struct threaded_binary_node * self ) {
    if ( self->threaded == 'l' || self->threaded == 'b' ) {
        return ((void *)0);
    }
    return self->left_link;
}

canonical_original_code:
struct threaded_binary_node *get_threaded_left_child(struct threaded_binary_node *self) {
    if ( self->threaded == 'l' || self->threaded == 'b' ) {
        return ((void *)0);
    }
    return self->left_link;
}

variable_types:
self
struct threaded_binary_node *


decompiled_code:
__int64 __fastcall get_threaded_right_child(__int64 a1)
{
__int64 result; // rax

if ( (*(_BYTE *)(a1 + 16) & 0xEF) == 98 )
result = 0LL;
else
result = *(_QWORD *)(a1 + 8);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 result; // rax

if ( (*(_BYTE *)(a1 + 16) & 0xEF) == 98 )
result = 0LL;
else
result = *(_QWORD *)(a1 + 8);
return result;
}

original_code:
struct threaded_binary_node * get_threaded_right_child( struct threaded_binary_node * self ) {
    if ( self->threaded == 'r' || self->threaded == 'b' ) {
        return ((void *)0);
    }
    return self->right_link;
}

canonical_original_code:
struct threaded_binary_node *get_threaded_right_child(struct threaded_binary_node *self) {
    if ( self->threaded == 'r' || self->threaded == 'b' ) {
        return ((void *)0);
    }
    return self->right_link;
}


decompiled_code:
char *__fastcall print_threaded_tree(__int64 a1)
{
const char *v2; // rbx
__int64 v3; // rax
__int64 v4; // rax
const char *v5; // rbp
int v6; // er13
int v7; // eax
char *v8; // rax
__int64 v9; // rdx
const void *v10; // r9
char *v11; // r13
unsigned int *v12; // rax
const void *v13; // r8
__int64 v14; // rdi
__int64 v15; // rsi
__int64 v16; // rcx

v2 = &s;
v3 = get_threaded_left_child((__int64 *)a1);
if ( v3 )
v2 = (const char *)print_threaded_tree(v3);
v4 = get_threaded_right_child(a1);
if ( !v4 || a1 == v4 )
{
v6 = 0;
v5 = &s;
}
else
{
v5 = (const char *)print_threaded_tree(v4);
v6 = strlen(v5);
}
v7 = strlen(v2);
v8 = (char *)malloc(v6 + v7 + 545);
v9 = (unsigned int)*(char *)(a1 + 16);
v10 = *(const void **)(a1 + 8);
*v8 = 0;
v11 = v8;
v12 = *(unsigned int **)(a1 + 24);
v13 = *(const void **)a1;
if ( v12 )
{
v14 = v12[2];
v15 = *v12;
v16 = (unsigned int)*((char *)v12 + 4);
}
else
{
v15 = 0LL;
v14 = 0xFFFFFFFFLL;
v16 = 32LL;
}
sprintf(
v11,
"

address : %p
value : %c
left_link: %p
right_link"
" : %p
threaded : %c
priority : %d
first_index : %d

%s	%s

",
(const void *)a1,
v16,
v13,
v10,
v9,
v15,
v14,
v2,
v5);
return v11;
}

canonical_decompiled_code:
char *__fastcall func6(__int64 a1)
{
const char *v2; // rbx
__int64 v3; // rax
__int64 v4; // rax
const char *v5; // rbp
int v6; // er13
int v7; // eax
char *v8; // rax
__int64 v9; // rdx
const void *v10; // r9
char *v11; // r13
unsigned int *v12; // rax
const void *v13; // r8
__int64 v14; // rdi
__int64 v15; // rsi
__int64 v16; // rcx

v2 = &s;
v3 = func4((__int64 *)a1);
if ( v3 )
v2 = (const char *)func6(v3);
v4 = func5(a1);
if ( !v4 || a1 == v4 )
{
v6 = 0;
v5 = &s;
}
else
{
v5 = (const char *)func6(v4);
v6 = strlen(v5);
}
v7 = strlen(v2);
v8 = (char *)malloc(v6 + v7 + 545);
v9 = (unsigned int)*(char *)(a1 + 16);
v10 = *(const void **)(a1 + 8);
*v8 = 0;
v11 = v8;
v12 = *(unsigned int **)(a1 + 24);
v13 = *(const void **)a1;
if ( v12 )
{
v14 = v12[2];
v15 = *v12;
v16 = (unsigned int)*((char *)v12 + 4);
}
else
{
v15 = 0LL;
v14 = 0xFFFFFFFFLL;
v16 = 32LL;
}
sprintf(
v11,
"

address : %p
value : %c
left_link: %p
right_link"
" : %p
threaded : %c
priority : %d
first_index : %d

%s	%s

",
(const void *)a1,
v16,
v13,
v10,
v9,
v15,
v14,
v2,
v5);
return v11;
}

original_code:
char * print_threaded_tree( struct threaded_binary_node * self ) {
    char * left_string = "";
    char * right_string = "";
    char * template =
        "
"
            "
"
                "address : %p
value : %c
left_link: %p
right_link : %p
threaded : %c
priority : %d
first_index : %d	"
            "
"
            "
"
                "%s	"
                "%s	"
            "
"
        "
";
    int template_length = 512;
    char * result_string;
    int result_string_length;
    struct threaded_binary_node * child;
    if ( child = get_threaded_left_child( self ) ) {
        left_string = print_threaded_tree( child );
    }
    if ( child = get_threaded_right_child( self ) ) {
        if ( child != self ) {
            right_string = print_threaded_tree( child );
        }
    }
    result_string_length = template_length + strlen( left_string ) + strlen( right_string ) + 32;
    result_string = malloc( ( result_string_length + 1 ) * sizeof( char ) );
    *result_string = '\0';
    struct treap_data * data = self->data;
    sprintf( result_string, template,
             self,
             ( data ) ? data->value : ' ',
             self->left_link,
             self->right_link,
             self->threaded,
             ( data ) ? data->priority : 0,
             ( data ) ? data->first_index : -1,
             left_string,
             right_string );
    return result_string;
}

canonical_original_code:
char *print_threaded_tree(struct threaded_binary_node *self) {
    char *left_string = "";
    char *right_string = "";
    char *template = "
"
            "
"
                "address : %p
value : %c
left_link: %p
right_link : %p
threaded : %c
priority : %d
first_index : %d	"
            "
"
            "
"
                "%s	"
                "%s	"
            "
"
        "
";
    int template_length = 512;
    char *result_string;
    int result_string_length;
    struct threaded_binary_node *child;
    if ( child = get_threaded_left_child( self ) ) {
        left_string = print_threaded_tree( child );
    }
    if ( child = get_threaded_right_child( self ) ) {
        if ( child != self ) {
            right_string = print_threaded_tree( child );
        }
    }
    result_string_length = template_length + strlen( left_string ) + strlen( right_string ) + 32;
    result_string = malloc( ( result_string_length + 1 ) * sizeof( char ) );
    *result_string = '\0';
    struct treap_data *data = self->data;
    sprintf( result_string, template,
             self,
             ( data ) ? data->value : ' ',
             self->left_link,
             self->right_link,
             self->threaded,
             ( data ) ? data->priority : 0,
             ( data ) ? data->first_index : -1,
             left_string,
             right_string );
    return result_string;
}

variable_types:
template
char *

variable_types: struct treap_data { int priority; char value; int first_index; } *

return_type: char *


decompiled_code:
__int64 __fastcall get_rightmost_threaded_descendent(__int64 a1)
{
__int64 v2; // r8

do
a1 = get_threaded_right_child(a1);
while ( a1 );
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
__int64 v2; // r8

do
a1 = func5(a1);
while ( a1 );
return v2;
}

original_code:
struct threaded_binary_node * get_rightmost_threaded_descendent( struct threaded_binary_node * node ) {
    struct threaded_binary_node * child;
    while ( child = get_threaded_right_child( node ) ) {
        node = child;
    }
    return node;
}

canonical_original_code:
struct threaded_binary_node *get_rightmost_threaded_descendent(struct threaded_binary_node *node) {
    struct threaded_binary_node *child;
    while ( child = get_threaded_right_child( node ) ) {
        node = child;
    }
    return node;
}


decompiled_code:
__int64 __fastcall get_threaded_predecessor(__int64 a1)
{
char v1; // al
__int64 v2; // rdi
__int64 result; // rax

v1 = *(_BYTE *)(a1 + 16);
v2 = *(_QWORD *)a1;
if ( v1 == 108 || v1 == 98 )
result = v2;
else
result = get_rightmost_threaded_descendent(v2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
char v1; // al
__int64 v2; // rdi
__int64 result; // rax

v1 = *(_BYTE *)(a1 + 16);
v2 = *(_QWORD *)a1;
if ( v1 == 108 || v1 == 98 )
result = v2;
else
result = func9(v2);
return result;
}

original_code:
struct threaded_binary_node * get_threaded_predecessor( struct threaded_binary_node * node ) {
    if ( node->threaded == 'l' || node->threaded == 'b' ) {
        return node->left_link;
    }
    return get_rightmost_threaded_descendent( node->left_link );
}

canonical_original_code:
struct threaded_binary_node *get_threaded_predecessor(struct threaded_binary_node *node) {
    if ( node->threaded == 'l' || node->threaded == 'b' ) {
        return node->left_link;
    }
    return get_rightmost_threaded_descendent( node->left_link );
}


decompiled_code:
__int64 __fastcall get_threaded_parent(__int64 *a1)
{
__int64 v1; // rax
__int64 result; // rax
__int64 v3; // r9
__int64 v4; // rax

v1 = get_leftmost_threaded_descendent(a1);
result = get_threaded_predecessor(v1);
if ( *(_QWORD *)(result + 8) != v3 )
{
v4 = get_rightmost_threaded_descendent(v3);
result = get_threaded_successor(v4);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 *a1)
{
__int64 v1; // rax
__int64 result; // rax
__int64 v3; // r9
__int64 v4; // rax

v1 = func7(a1);
result = func10(v1);
if ( *(_QWORD *)(result + 8) != v3 )
{
v4 = func9(v3);
result = func8(v4);
}
return result;
}

original_code:
struct threaded_binary_node * get_threaded_parent( struct threaded_binary_node * self ) {
    struct threaded_binary_node * leaf;
    struct threaded_binary_node * parent;
    leaf = get_leftmost_threaded_descendent( self );
    parent = get_threaded_predecessor( leaf );
    if ( parent->right_link == self ) {
        return parent;
    }
    leaf = get_rightmost_threaded_descendent( self );
    parent = get_threaded_successor( leaf );
    return parent;
}

canonical_original_code:
struct threaded_binary_node *get_threaded_parent(struct threaded_binary_node *self) {
    struct threaded_binary_node *leaf;
    struct threaded_binary_node *parent;
    leaf = get_leftmost_threaded_descendent( self );
    parent = get_threaded_predecessor( leaf );
    if ( parent->right_link == self ) {
        return parent;
    }
    leaf = get_rightmost_threaded_descendent( self );
    parent = get_threaded_successor( leaf );
    return parent;
}


decompiled_code:
_BOOL8 __fastcall is_threaded_left_child(__int64 *a1)
{
_QWORD *v1; // rax
__int64 v2; // rdx

v1 = (_QWORD *)get_threaded_parent(a1);
return *v1 == v2;
}

canonical_decompiled_code:
_BOOL8 __fastcall func12(__int64 *a1)
{
_QWORD *v1; // rax
__int64 v2; // rdx

v1 = (_QWORD *)func11(a1);
return *v1 == v2;
}

original_code:
int is_threaded_left_child( struct threaded_binary_node * self ) {
    struct threaded_binary_node * parent = get_threaded_parent( self );
    if ( parent->left_link == self ) {
        return 1;
    }
    return 0;
}

canonical_original_code:
int is_threaded_left_child(struct threaded_binary_node *self) {
    struct threaded_binary_node *parent = get_threaded_parent( self );
    if ( parent->left_link == self ) {
        return 1;
    }
    return 0;
}

return_type: int


decompiled_code:
_BOOL8 __fastcall is_threaded_right_child(__int64 *a1)
{
__int64 v1; // rax
__int64 v2; // rdx

v1 = get_threaded_parent(a1);
return *(_QWORD *)(v1 + 8) == v2;
}

original_code:
int is_threaded_right_child( struct threaded_binary_node * self ) {
    struct threaded_binary_node * parent = get_threaded_parent( self );
    if ( parent->right_link == self ) {
        return 1;
    }
    return 0;
}

canonical_original_code:
int is_threaded_right_child(struct threaded_binary_node *self) {
    struct threaded_binary_node *parent = get_threaded_parent( self );
    if ( parent->right_link == self ) {
        return 1;
    }
    return 0;
}


decompiled_code:
void __fastcall delete_right_leaf(__int64 *a1)
{
__int64 v1; // r10
__int64 v2; // rax
__int64 v3; // rdx
char v4; // cl
void *v5; // r10
bool v6; // zf
char v7; // al

get_threaded_parent(a1);
v2 = get_threaded_successor(v1);
v6 = *(_BYTE *)(v3 + 16) == 108;
*(_QWORD *)(v3 + 8) = v2;
v7 = 98;
if ( !v6 )
v7 = v4;
*(_BYTE *)(v3 + 16) = v7;
free(v5);
}

original_code:
void delete_right_leaf( struct threaded_binary_node * leaf ) {
    struct threaded_binary_node * parent = get_threaded_parent( leaf );
    parent->right_link = get_threaded_successor( leaf );
    if ( parent->threaded == 'l' ) {
        parent->threaded = 'b';
    } else {
        parent->threaded = 'r';
    }
    free( leaf );
    return;
}

canonical_original_code:
void delete_right_leaf(struct threaded_binary_node *leaf) {
    struct threaded_binary_node *parent = get_threaded_parent( leaf );
    parent->right_link = get_threaded_successor( leaf );
    if ( parent->threaded == 'l' ) {
        parent->threaded = 'b';
    } else {
        parent->threaded = 'r';
    }
    free( leaf );
    return;
}

return_type: void


decompiled_code:
void __fastcall delete_left_leaf(__int64 *a1)
{
__int64 v1; // r10
__int64 v2; // rax
__int64 v3; // rdx
char v4; // cl
void *v5; // r10
bool v6; // zf
char v7; // al

get_threaded_parent(a1);
v2 = get_threaded_predecessor(v1);
v6 = *(_BYTE *)(v3 + 16) == 114;
*(_QWORD *)v3 = v2;
v7 = 98;
if ( !v6 )
v7 = v4;
*(_BYTE *)(v3 + 16) = v7;
free(v5);
}

original_code:
void delete_left_leaf( struct threaded_binary_node * leaf ) {
    struct threaded_binary_node * parent = get_threaded_parent( leaf );
    parent->left_link = get_threaded_predecessor( leaf );
    if ( parent->threaded == 'r' ) {
        parent->threaded = 'b';
    } else {
        parent->threaded = 'l';
    }
    free( leaf );
    return;
}

canonical_original_code:
void delete_left_leaf(struct threaded_binary_node *leaf) {
    struct threaded_binary_node *parent = get_threaded_parent( leaf );
    parent->left_link = get_threaded_predecessor( leaf );
    if ( parent->threaded == 'r' ) {
        parent->threaded = 'b';
    } else {
        parent->threaded = 'l';
    }
    free( leaf );
    return;
}


decompiled_code:
void __fastcall delete_leaf(__int64 *a1)
{
__int64 *v1; // r10

if ( is_threaded_left_child(a1) )
delete_left_leaf(v1);
else
delete_right_leaf(v1);
}

canonical_decompiled_code:
void __fastcall func16(__int64 *a1)
{
__int64 *v1; // r10

if ( func12(a1) )
func15(v1);
else
func14(v1);
}

original_code:
void delete_leaf( struct threaded_binary_node * leaf ) {
    if ( is_threaded_left_child( leaf ) ) {
        delete_left_leaf( leaf );
    } else {
        delete_right_leaf( leaf );
    }
    return;
}

canonical_original_code:
void delete_leaf(struct threaded_binary_node *leaf) {
    if ( is_threaded_left_child( leaf ) ) {
        delete_left_leaf( leaf );
    } else {
        delete_right_leaf( leaf );
    }
    return;
}


decompiled_code:
_BOOL8 __fastcall has_right_thread(__int64 a1)
{
return (*(_BYTE *)(a1 + 16) & 0xEF) == 98;
}

original_code:
int has_right_thread( struct threaded_binary_node * p ) {
    if ( p->threaded == 'r' || p->threaded == 'b' ) {
        return 1;
    }
    return 0;
}

canonical_original_code:
int has_right_thread(struct threaded_binary_node *p) {
    if ( p->threaded == 'r' || p->threaded == 'b' ) {
        return 1;
    }
    return 0;
}


original_code:
int has_left_thread( struct threaded_binary_node * p ) {
    if ( p->threaded == 'l' || p->threaded == 'b' ) {
        return 1;
    }
    return 0;
}

canonical_original_code:
int has_left_thread(struct threaded_binary_node *p) {
    if ( p->threaded == 'l' || p->threaded == 'b' ) {
        return 1;
    }
    return 0;
}


decompiled_code:
__int64 __fastcall add_left_threaded_status(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 110 )
{
*(_BYTE *)(a1 + 16) = 108;
}
else if ( (_BYTE)result == 114 )
{
*(_BYTE *)(a1 + 16) = 98;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func19(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 110 )
{
*(_BYTE *)(a1 + 16) = 108;
}
else if ( (_BYTE)result == 114 )
{
*(_BYTE *)(a1 + 16) = 98;
}
return result;
}

original_code:
void add_left_threaded_status( struct threaded_binary_node * p ) {
    if ( p->threaded == 'n' ) {
        p->threaded = 'l';
    } else if ( p->threaded == 'r' ) {
        p->threaded = 'b';
    }
    return;
}

canonical_original_code:
void add_left_threaded_status(struct threaded_binary_node *p) {
    if ( p->threaded == 'n' ) {
        p->threaded = 'l';
    } else if ( p->threaded == 'r' ) {
        p->threaded = 'b';
    }
    return;
}


decompiled_code:
__int64 __fastcall add_right_threaded_status(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 110 )
{
*(_BYTE *)(a1 + 16) = 114;
}
else if ( (_BYTE)result == 108 )
{
*(_BYTE *)(a1 + 16) = 98;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 110 )
{
*(_BYTE *)(a1 + 16) = 114;
}
else if ( (_BYTE)result == 108 )
{
*(_BYTE *)(a1 + 16) = 98;
}
return result;
}

original_code:
void add_right_threaded_status( struct threaded_binary_node * p ) {
    if ( p->threaded == 'n' ) {
        p->threaded = 'r';
    } else if ( p->threaded == 'l' ) {
        p->threaded = 'b';
    }
    return;
}

canonical_original_code:
void add_right_threaded_status(struct threaded_binary_node *p) {
    if ( p->threaded == 'n' ) {
        p->threaded = 'r';
    } else if ( p->threaded == 'l' ) {
        p->threaded = 'b';
    }
    return;
}


decompiled_code:
__int64 __fastcall replace_child(__int64 a1, __int64 *a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // rdx
__int64 v6; // rcx

result = get_threaded_left_child(a2);
if ( v4 == result )
{
*a2 = v3;
}
else
{
result = get_threaded_right_child((__int64)a2);
if ( v6 == result )
a2[1] = v5;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func21(__int64 a1, __int64 *a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // rdx
__int64 v6; // rcx

result = func4(a2);
if ( v4 == result )
{
*a2 = v3;
}
else
{
result = func5((__int64)a2);
if ( v6 == result )
a2[1] = v5;
}
return result;
}

original_code:
void replace_child( struct threaded_binary_node * old_child, struct threaded_binary_node * parent, struct threaded_binary_node * new_child ) {
    if ( old_child == get_threaded_left_child( parent ) ) {
        parent->left_link = new_child;
    } else if ( old_child == get_threaded_right_child( parent ) ) {
        parent->right_link = new_child;
    }
    return;
}

canonical_original_code:
void replace_child(struct threaded_binary_node *old_child, struct threaded_binary_node *parent, struct threaded_binary_node *new_child) {
    if ( old_child == get_threaded_left_child( parent ) ) {
        parent->left_link = new_child;
    } else if ( old_child == get_threaded_right_child( parent ) ) {
        parent->right_link = new_child;
    }
    return;
}

variable_types:
parent
struct threaded_binary_node *


decompiled_code:
__int64 __fastcall remove_right_threaded_status(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 98 )
{
*(_BYTE *)(a1 + 16) = 108;
}
else if ( (_BYTE)result == 114 )
{
*(_BYTE *)(a1 + 16) = 110;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func22(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 98 )
{
*(_BYTE *)(a1 + 16) = 108;
}
else if ( (_BYTE)result == 114 )
{
*(_BYTE *)(a1 + 16) = 110;
}
return result;
}

original_code:
void remove_right_threaded_status( struct threaded_binary_node * p ) {
    if ( p->threaded == 'b' ) {
        p->threaded = 'l';
    } else if ( p->threaded == 'r' ) {
        p->threaded = 'n';
    }
    return;
}

canonical_original_code:
void remove_right_threaded_status(struct threaded_binary_node *p) {
    if ( p->threaded == 'b' ) {
        p->threaded = 'l';
    } else if ( p->threaded == 'r' ) {
        p->threaded = 'n';
    }
    return;
}


decompiled_code:
__int64 __fastcall remove_left_threaded_status(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 98 )
{
*(_BYTE *)(a1 + 16) = 114;
}
else if ( (_BYTE)result == 108 )
{
*(_BYTE *)(a1 + 16) = 110;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1)
{
__int64 result; // rax

result = *(unsigned __int8 *)(a1 + 16);
if ( (_BYTE)result == 98 )
{
*(_BYTE *)(a1 + 16) = 114;
}
else if ( (_BYTE)result == 108 )
{
*(_BYTE *)(a1 + 16) = 110;
}
return result;
}

original_code:
void remove_left_threaded_status( struct threaded_binary_node * p ) {
    if ( p->threaded == 'b' ) {
        p->threaded = 'r';
    } else if ( p->threaded == 'l' ) {
        p->threaded = 'n';
    }
    return;
}

canonical_original_code:
void remove_left_threaded_status(struct threaded_binary_node *p) {
    if ( p->threaded == 'b' ) {
        p->threaded = 'r';
    } else if ( p->threaded == 'l' ) {
        p->threaded = 'n';
    }
    return;
}


decompiled_code:
_BYTE *new_treap_data()
{
_BYTE *result; // rax

result = malloc(0xCuLL);
if ( result )
{
result[4] = 0;
*(_DWORD *)result = 0;
}
return result;
}

canonical_decompiled_code:
_BYTE *func0()
{
_BYTE *result; // rax

result = malloc(0xCuLL);
if ( result )
{
result[4] = 0;
*(_DWORD *)result = 0;
}
return result;
}

original_code:
struct treap_data * new_treap_data() {
    struct treap_data * new_data = malloc( sizeof( struct treap_data ) );
    if ( !new_data ) {
        return ((void *)0);
    }
    new_data->value = '\0';
    new_data->priority = 0;
    return new_data;
}

canonical_original_code:
struct treap_data *new_treap_data() {
    struct treap_data *new_data = malloc( sizeof( struct treap_data ) );
    if ( !new_data ) {
        return ((void *)0);
    }
    new_data->value = '\0';
    new_data->priority = 0;
    return new_data;
}

return_type: struct treap_data { int priority; char value; int first_index; } *


compare

decompiled_code:
__int64 __fastcall compare(__int64 a1, __int64 a2)
{
unsigned __int8 v2; // al
bool v3; // cc
__int64 result; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
v2 = *(_BYTE *)(a2 + 4);
v3 = *(_BYTE *)(a1 + 4) < v2;
result = *(_BYTE *)(a1 + 4) > v2;
if ( v3 )
result = 0xFFFFFFFFLL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
unsigned __int8 v2; // al
bool v3; // cc
__int64 result; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
v2 = *(_BYTE *)(a2 + 4);
v3 = *(_BYTE *)(a1 + 4) < v2;
result = *(_BYTE *)(a1 + 4) > v2;
if ( v3 )
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int compare( struct treap_data * data1, struct treap_data * data2 ) {
    if ( !data2 || ( data1->value < data2->value ) ) {
        return -1;
    }
    if ( data1->value > data2->value ) {
        return 1;
    }
    return 0;
}

canonical_original_code:
int compare(struct treap_data *data1, struct treap_data *data2) {
    if ( !data2 || ( data1->value < data2->value ) ) {
        return -1;
    }
    if ( data1->value > data2->value ) {
        return 1;
    }
    return 0;
}

user_defined_types: struct treap_data { int priority; char value; int first_index; }


search

decompiled_code:
__int64 __fastcall search(__int64 a1, char a2)
{
__int64 v2; // r12
_BYTE *v3; // rax
void *v4; // rbp
__int64 v5; // rax
int v6; // eax

v2 = a1;
v3 = new_treap_data();
v3[4] = a2;
v4 = v3;
if ( a1 )
{
while ( 1 )
{
v6 = compare((__int64)v4, *(_QWORD *)(v2 + 24));
if ( !v6 )
break;
if ( v6 == -1 )
{
v5 = get_threaded_left_child(v2);
if ( !v5 )
break;
}
else
{
v5 = get_threaded_right_child(v2);
if ( !v5 )
break;
}
v2 = v5;
}
}
free(v4);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, char a2)
{
__int64 v2; // r12
_BYTE *v3; // rax
void *v4; // rbp
__int64 v5; // rax
int v6; // eax

v2 = a1;
v3 = func0();
v3[4] = a2;
v4 = v3;
if ( a1 )
{
while ( 1 )
{
v6 = func1((__int64)v4, *(_QWORD *)(v2 + 24));
if ( !v6 )
break;
if ( v6 == -1 )
{
v5 = get_threaded_left_child(v2);
if ( !v5 )
break;
}
else
{
v5 = get_threaded_right_child(v2);
if ( !v5 )
break;
}
v2 = v5;
}
}
free(v4);
return v2;
}

original_code:
struct threaded_binary_node * search( struct threaded_binary_node * p, char value ) {
    struct treap_data * target_data = new_treap_data();
    target_data->value = value;
    struct threaded_binary_node * previous = ((void *)0);
    int comparison;
    while ( p ) {
        comparison = compare( target_data, p->data );
        if ( comparison == 0 ) {
            previous = p;
            break;
        }
        previous = p;
        if ( comparison == -1 ) {
            p = get_threaded_left_child( p );
        } else {
            p = get_threaded_right_child( p );
        }
    }
    free( target_data );
    return previous;
}

canonical_original_code:
struct threaded_binary_node *search(struct threaded_binary_node *p, char value) {
    struct treap_data *target_data = new_treap_data();
    target_data->value = value;
    struct threaded_binary_node *previous = ((void *)0);
    int comparison;
    while ( p ) {
        comparison = compare( target_data, p->data );
        if ( comparison == 0 ) {
            previous = p;
            break;
        }
        previous = p;
        if ( comparison == -1 ) {
            p = get_threaded_left_child( p );
        } else {
            p = get_threaded_right_child( p );
        }
    }
    free( target_data );
    return previous;
}

variable_types:
p
struct threaded_binary_node *

variable_types: value char

variable_types: comparison int


decompiled_code:
__int64 __fastcall rotate_right(__int64 *a1)
{
__int64 v1; // r12
__int64 v2; // r13

v1 = get_threaded_left_child(a1);
v2 = get_threaded_parent(a1);
if ( (unsigned int)has_right_thread(v1) )
{
*a1 = v1;
add_left_threaded_status(a1);
remove_right_threaded_status(v1);
}
else
{
*a1 = *(_QWORD *)(v1 + 8);
}
*(_QWORD *)(v1 + 8) = a1;
return replace_child(a1, v2, v1);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1)
{
__int64 v1; // r12
__int64 v2; // r13

v1 = get_threaded_left_child(a1);
v2 = get_threaded_parent(a1);
if ( (unsigned int)has_right_thread(v1) )
{
*a1 = v1;
add_left_threaded_status(a1);
remove_right_threaded_status(v1);
}
else
{
*a1 = *(_QWORD *)(v1 + 8);
}
*(_QWORD *)(v1 + 8) = a1;
return replace_child(a1, v2, v1);
}

original_code:
void rotate_right( struct threaded_binary_node * pivot ) {
    struct threaded_binary_node * child = get_threaded_left_child( pivot );
    struct threaded_binary_node * parent = get_threaded_parent( pivot );
    if ( has_right_thread( child ) ) {
        pivot->left_link = child;
        add_left_threaded_status( pivot );
        remove_right_threaded_status( child );
    } else {
        pivot->left_link = child->right_link;
    }
    child->right_link = pivot;
    replace_child( pivot, parent, child );
}

canonical_original_code:
void rotate_right(struct threaded_binary_node *pivot) {
    struct threaded_binary_node *child = get_threaded_left_child( pivot );
    struct threaded_binary_node *parent = get_threaded_parent( pivot );
    if ( has_right_thread( child ) ) {
        pivot->left_link = child;
        add_left_threaded_status( pivot );
        remove_right_threaded_status( child );
    } else {
        pivot->left_link = child->right_link;
    }
    child->right_link = pivot;
    replace_child( pivot, parent, child );
}


decompiled_code:
__int64 __fastcall rotate_left(__int64 a1)
{
_QWORD *v1; // r12
__int64 v2; // r13

v1 = (_QWORD *)get_threaded_right_child(a1);
v2 = get_threaded_parent(a1);
if ( (unsigned int)has_left_thread(v1) )
{
*(_QWORD *)(a1 + 8) = v1;
add_right_threaded_status(a1);
remove_left_threaded_status(v1);
}
else
{
*(_QWORD *)(a1 + 8) = *v1;
}
*v1 = a1;
return replace_child(a1, v2, v1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
_QWORD *v1; // r12
__int64 v2; // r13

v1 = (_QWORD *)get_threaded_right_child(a1);
v2 = get_threaded_parent(a1);
if ( (unsigned int)has_left_thread(v1) )
{
*(_QWORD *)(a1 + 8) = v1;
add_right_threaded_status(a1);
remove_left_threaded_status(v1);
}
else
{
*(_QWORD *)(a1 + 8) = *v1;
}
*v1 = a1;
return replace_child(a1, v2, v1);
}

original_code:
void rotate_left( struct threaded_binary_node * pivot ) {
    struct threaded_binary_node * child = get_threaded_right_child( pivot );
    struct threaded_binary_node * parent = get_threaded_parent( pivot );
    if ( has_left_thread( child ) ) {
        pivot->right_link = child;
        add_right_threaded_status( pivot );
        remove_left_threaded_status( child );
    } else {
        pivot->right_link = child->left_link;
    }
    child->left_link = pivot;
    replace_child( pivot, parent, child );
}

canonical_original_code:
void rotate_left(struct threaded_binary_node *pivot) {
    struct threaded_binary_node *child = get_threaded_right_child( pivot );
    struct threaded_binary_node *parent = get_threaded_parent( pivot );
    if ( has_left_thread( child ) ) {
        pivot->right_link = child;
        add_right_threaded_status( pivot );
        remove_left_threaded_status( child );
    } else {
        pivot->right_link = child->left_link;
    }
    child->left_link = pivot;
    replace_child( pivot, parent, child );
}


original_code:
int is_dominated( struct threaded_binary_node * child, struct threaded_binary_node * parent ) {
    if ( !parent->data ) {
        return 1;
    }
    struct treap_data * parent_data = parent->data;
    struct treap_data * child_data = child->data;
    if ( child_data->priority > parent_data->priority ) {
        return 1;
    } else if ( child_data->priority == parent_data->priority ) {
        if ( child_data->first_index > parent_data->first_index ) {
            return 1;
        }
        else {
            return 0;
        }
    } else {
        return 0;
    }
}

canonical_original_code:
int is_dominated(struct threaded_binary_node *child, struct threaded_binary_node *parent) {
    if ( !parent->data ) {
        return 1;
    }
    struct treap_data *parent_data = parent->data;
    struct treap_data *child_data = child->data;
    if ( child_data->priority > parent_data->priority ) {
        return 1;
    } else if ( child_data->priority == parent_data->priority ) {
        if ( child_data->first_index > parent_data->first_index ) {
            return 1;
        }
        else {
            return 0;
        }
    } else {
        return 0;
    }
}


decompiled_code:
__int64 __fastcall get_highest_priority_child(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // r12
__int64 v3; // rsi

v1 = get_threaded_left_child(a1);
if ( !v1 )
return get_threaded_right_child(a1);
v2 = v1;
v3 = get_threaded_right_child(a1);
if ( v3 )
{
if ( (unsigned int)is_dominated(v2, v3) )
v2 = v3;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // r12
__int64 v3; // rsi

v1 = get_threaded_left_child(a1);
if ( !v1 )
return get_threaded_right_child(a1);
v2 = v1;
v3 = get_threaded_right_child(a1);
if ( v3 )
{
if ( (unsigned int)func5(v2, v3) )
v2 = v3;
}
return v2;
}

original_code:
struct threaded_binary_node * get_highest_priority_child( struct threaded_binary_node * parent ) {
    struct threaded_binary_node * highest_priority_child = ((void *)0);
    int highest_priority;
    struct threaded_binary_node * child = ((void *)0);
    struct treap_data * child_data = ((void *)0);
    if ( ( child = get_threaded_left_child( parent ) ) ) {
        highest_priority_child = child;
        child_data = child->data;
        highest_priority = child_data->priority;
    }
    if ( ( child = get_threaded_right_child( parent ) ) ) {
        if ( !highest_priority_child ) {
            highest_priority_child = child;
        } else {
            if ( is_dominated( highest_priority_child, child ) ) {
                highest_priority_child = child;
            }
        }
    }
    return highest_priority_child;
}

canonical_original_code:
struct threaded_binary_node *get_highest_priority_child(struct threaded_binary_node *parent) {
    struct threaded_binary_node *highest_priority_child = ((void *)0);
    int highest_priority;
    struct threaded_binary_node *child = ((void *)0);
    struct treap_data *child_data = ((void *)0);
    if ( ( child = get_threaded_left_child( parent ) ) ) {
        highest_priority_child = child;
        child_data = child->data;
        highest_priority = child_data->priority;
    }
    if ( ( child = get_threaded_right_child( parent ) ) ) {
        if ( !highest_priority_child ) {
            highest_priority_child = child;
        } else {
            if ( is_dominated( highest_priority_child, child ) ) {
                highest_priority_child = child;
            }
        }
    }
    return highest_priority_child;
}


decompiled_code:
__int64 __fastcall perform_rotations(__int64 *a1)
{
__int64 v2; // rax
__int64 *v3; // r9
__int64 *v4; // rdi
__int64 result; // rax
__int64 v6; // rdi
bool v7; // zf

while ( 1 )
{
while ( 1 )
{
v2 = get_threaded_parent(a1);
if ( (unsigned int)is_dominated((__int64)a1, v2) )
break;
v4 = v3;
if ( (__int64 *)*v3 != a1 )
goto LABEL_3;
LABEL_7:
rotate_right(v4);
}
result = get_highest_priority_child((__int64)a1);
v6 = result;
if ( !result )
return result;
result = is_dominated(result, (__int64)a1);
if ( (_DWORD)result )
return result;
v7 = *a1 == v6;
v4 = a1;
if ( v7 )
goto LABEL_7;
LABEL_3:
rotate_left((__int64)v4);
}
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 *a1)
{
__int64 v2; // rax
__int64 *v3; // r9
__int64 *v4; // rdi
__int64 result; // rax
__int64 v6; // rdi
bool v7; // zf

while ( 1 )
{
while ( 1 )
{
v2 = get_threaded_parent(a1);
if ( (unsigned int)func5((__int64)a1, v2) )
break;
v4 = v3;
if ( (__int64 *)*v3 != a1 )
goto LABEL_3;
LABEL_7:
func3(v4);
}
result = func6((__int64)a1);
v6 = result;
if ( !result )
return result;
result = func5(result, (__int64)a1);
if ( (_DWORD)result )
return result;
v7 = *a1 == v6;
v4 = a1;
if ( v7 )
goto LABEL_7;
LABEL_3:
func4((__int64)v4);
}
}

original_code:
void perform_rotations( struct threaded_binary_node * t ) {
    struct threaded_binary_node * parent = get_threaded_parent( t );
    if ( !is_dominated( t, parent ) ) {
        if ( parent->left_link == t ) {
            rotate_right( parent );
        } else {
            rotate_left( parent );
        }
        perform_rotations( t );
        return;
    }
    struct threaded_binary_node * highest_priority_child = get_highest_priority_child( t );
    if ( !highest_priority_child ) {
        return;
    }
    if ( !is_dominated( highest_priority_child, t ) ) {
        if ( t->left_link == highest_priority_child ) {
            rotate_right( t );
        } else {
            rotate_left( t );
        }
        perform_rotations( t );
    }
    return;
}

canonical_original_code:
void perform_rotations(struct threaded_binary_node *t) {
    struct threaded_binary_node *parent = get_threaded_parent( t );
    if ( !is_dominated( t, parent ) ) {
        if ( parent->left_link == t ) {
            rotate_right( parent );
        } else {
            rotate_left( parent );
        }
        perform_rotations( t );
        return;
    }
    struct threaded_binary_node *highest_priority_child = get_highest_priority_child( t );
    if ( !highest_priority_child ) {
        return;
    }
    if ( !is_dominated( highest_priority_child, t ) ) {
        if ( t->left_link == highest_priority_child ) {
            rotate_right( t );
        } else {
            rotate_left( t );
        }
        perform_rotations( t );
    }
    return;
}


reverse

decompiled_code:
__int64 __fastcall reverse(const char *a1)
{
__int64 result; // rax
__int64 v2; // rdx
char v3; // cl

result = (unsigned int)strlen(a1) - 1;
if ( (int)result > 0 )
{
result = (int)result;
v2 = 0LL;
do
{
v3 = a1[v2];
a1[v2++] = a1[result];
a1[result--] = v3;
}
while ( (int)v2 < (int)result );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1)
{
__int64 result; // rax
__int64 v2; // rdx
char v3; // cl

result = (unsigned int)strlen(a1) - 1;
if ( (int)result > 0 )
{
result = (int)result;
v2 = 0LL;
do
{
v3 = a1[v2];
a1[v2++] = a1[result];
a1[result--] = v3;
}
while ( (int)v2 < (int)result );
}
return result;
}

original_code:
void reverse( char * string ) {
    int i, j;
    char c;
    for ( i = 0, j = strlen(string) - 1; i < j; i++, j-- ) {
 c = string[i];
 string[i] = string[j];
 string[j] = c;
    }
    return;
}

canonical_original_code:
void reverse(char *string) {
    int i; int j;
    char c;
    for ( i = 0, j = strlen(string) - 1; i < j; i++, j-- ) {
 c = string[i];
 string[i] = string[j];
 string[j] = c;
    }
    return;
}

variable_types:
string
char *

variable_types: i int

variable_types: j int

variable_types: c char


original_code:
int num_decimal_digits( int num ) {
    if ( num == 0 ) {
 return 1;
    }
    return floor( log(num) / log(10) ) + 1;
}

canonical_original_code:
int num_decimal_digits(int num) {
    if ( num == 0 ) {
 return 1;
    }
    return floor( log(num) / log(10) ) + 1;
}

variable_types: num int


decompiled_code:
const char *__fastcall num_to_string(int a1)
{
unsigned int v1; // ebx
int v2; // eax
const char *v3; // rax
const char *v4; // r12
char *v5; // rsi
int v6; // ecx
int v7; // eax

v1 = abs32(a1);
v2 = num_decimal_digits(v1);
v3 = (const char *)malloc((int)(((unsigned int)a1 >> 31) + v2 + 1));
if ( !v3 )
return "Out of memory!";
v4 = v3;
v5 = (char *)v3;
v6 = 0;
do
{
*v5++ = v1 % 0xA + 48;
v1 /= 0xAu;
v7 = v6++;
}
while ( v1 );
if ( a1 < 0 )
{
v4[v6] = 45;
v6 = v7 + 2;
}
v4[v6] = 0;
reverse(v4);
return v4;
}

canonical_decompiled_code:
const char *__fastcall func4(int a1)
{
unsigned int v1; // ebx
int v2; // eax
const char *v3; // rax
const char *v4; // r12
char *v5; // rsi
int v6; // ecx
int v7; // eax

v1 = abs32(a1);
v2 = func3(v1);
v3 = (const char *)malloc((int)(((unsigned int)a1 >> 31) + v2 + 1));
if ( !v3 )
return "Out of memory!";
v4 = v3;
v5 = (char *)v3;
v6 = 0;
do
{
*v5++ = v1 % 0xA + 48;
v1 /= 0xAu;
v7 = v6++;
}
while ( v1 );
if ( a1 < 0 )
{
v4[v6] = 45;
v6 = v7 + 2;
}
v4[v6] = 0;
func2(v4);
return v4;
}

original_code:
char * num_to_string( int num ) {
    int is_negative = ( num < 0 ) ? 1 : 0;
    int abs_num = abs(num);
    int string_length = num_decimal_digits(abs_num) + is_negative;
    char * result = malloc( ( string_length + 1 ) * sizeof(char) );
    if ( ! result ) {
 return "Out of memory!";
    }
    int i = 0;
    int r;
    do {
 r = abs_num % 10;
 result[i] = r + '0';
 abs_num /= 10;
 i++;
    } while ( abs_num );
    if ( is_negative ) {
 result[i++] = '-';
    }
    result[i] = '\0';
    reverse(result);
    return result;
}

canonical_original_code:
char *num_to_string(int num) {
    int is_negative = ( num < 0 ) ? 1 : 0;
    int abs_num = abs(num);
    int string_length = num_decimal_digits(abs_num) + is_negative;
    char *result = malloc( ( string_length + 1 ) * sizeof(char) );
    if ( ! result ) {
 return "Out of memory!";
    }
    int i = 0;
    int r;
    do {
 r = abs_num % 10;
 result[i] = r + '0';
 abs_num /= 10;
 i++;
    } while ( abs_num );
    if ( is_negative ) {
 result[i++] = '-';
    }
    result[i] = '\0';
    reverse(result);
    return result;
}

variable_types:
result
char *

variable_types: r int


dump

repo: tbook/ping

decompiled_code:
void __fastcall dump(_QWORD *a1, int a2)
{
_QWORD *v3; // rax
void *v4; // rdi

while ( 1 )
{
v3 = a1;
a1 = (_QWORD *)a1[3];
if ( !a1 )
break;
if ( *(_DWORD *)a1 == a2 )
{
v4 = (void *)a1[4];
v3[3] = a1[3];
free(v4);
free(a1);
return;
}
}
}

canonical_decompiled_code:
void __fastcall func1(_QWORD *a1, int a2)
{
_QWORD *v3; // rax
void *v4; // rdi

while ( 1 )
{
v3 = a1;
a1 = (_QWORD *)a1[3];
if ( !a1 )
break;
if ( *(_DWORD *)a1 == a2 )
{
v4 = (void *)a1[4];
v3[3] = a1[3];
free(v4);
free(a1);
return;
}
}
}

original_code:
void dump(struct node *head, int socket) {
  struct node *current, *temp;
  current = head;
  while (current->next) {
    if (current->next->socket == socket) {
      temp = current->next;
      current->next = temp->next;
      free(temp->buffer);
      free(temp);
      return;
    } else {
      current = current->next;
    }
  }
}

canonical_original_code:
void dump(struct node *head, int socket) {
  struct node *current; struct node *temp;
  current = head;
  while (current->next) {
    if (current->next->socket == socket) {
      temp = current->next;
      current->next = temp->next;
      free(temp->buffer);
      free(temp);
      return;
    } else {
      current = current->next;
    }
  }
}

variable_types: struct node { int socket; 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]; } client_addr; int pending_data; struct node *next; char *buffer; int n_bytes; int msg_size; } *

variable_types: socket int

user_defined_types: struct node { int socket; struct sockaddr_in client_addr; int pending_data; struct node *next; char *buffer; int n_bytes; int msg_size; }

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


add

original_code:
void add(struct node *head, int socket, struct sockaddr_in addr) {
  struct node *new_node;
  new_node = (struct node *)malloc(sizeof(struct node));
  new_node->socket = socket;
  new_node->client_addr = addr;
  new_node->pending_data = 0;
  new_node->next = head->next;
  new_node->buffer = (char*)malloc(sizeof(char)*(2<<16));
  new_node->n_bytes = 0;
  new_node->msg_size = 0;
  head->next = new_node;
}

canonical_original_code:
void add(struct node *head, int socket, struct sockaddr_in addr) {
  struct node *new_node;
  new_node = (struct node *)malloc(sizeof(struct node));
  new_node->socket = socket;
  new_node->client_addr = addr;
  new_node->pending_data = 0;
  new_node->next = head->next;
  new_node->buffer = (char *)malloc(sizeof(char)*(2<<16));
  new_node->n_bytes = 0;
  new_node->msg_size = 0;
  head->next = new_node;
}

variable_types:
addr
struct sockaddr_in


decompiled_code:
__int64 free_resource()
{
__int64 result; // rax
void *i; // rbp
int v2; // edi

result = root;
for ( i = *(void **)(root + 24); i; i = *(void **)(root + 24) )
{
v2 = *(_DWORD *)i;
*(_QWORD *)(result + 24) = *((_QWORD *)i + 3);
close(v2);
free(*((void **)i + 4));
free(i);
result = root;
}
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 result; // rax
void *i; // rbp
int v2; // edi

result = root;
for ( i = *(void **)(root + 24); i; i = *(void **)(root + 24) )
{
v2 = *(_DWORD *)i;
*(_QWORD *)(result + 24) = *((_QWORD *)i + 3);
close(v2);
free(*((void **)i + 4));
free(i);
result = root;
}
return result;
}

original_code:
void free_resource()
{
  struct node* tmp;
  while(root->next){
    tmp = root->next;
    root->next = tmp->next;
    close(tmp->socket);
    free(tmp->buffer);
    free(tmp);
  }
}

canonical_original_code:
void free_resource()
{
  struct node *tmp;
  while(root->next){
    tmp = root->next;
    root->next = tmp->next;
    close(tmp->socket);
    free(tmp->buffer);
    free(tmp);
  }
}


decompiled_code:
void __noreturn exit_handler()
{
free_resource();
puts("force close.");
exit(1);
}

canonical_decompiled_code:
void __noreturn func4()
{
func3();
puts("force close.");
exit(1);
}

original_code:
void exit_handler(int sig)
{
  free_resource();
  printf("force close.\n");
  exit(1);
}

variable_types: sig int


decompiled_code:
char get_local_ip()
{
int v0; // eax
struct ifaddrs *i; // rbx
const struct sockaddr *v2; // rdi
int v3; // eax
bool v4; // zf
const char *v5; // rax
struct ifaddrs *ifap; // [rsp+8h] [rbp-420h] BYREF
char host[1048]; // [rsp+10h] [rbp-418h] BYREF

v0 = getifaddrs(&ifap);
if ( v0 == -1 )
{
perror("getifaddrs");
exit(1);
}
for ( i = ifap; i; i = i->ifa_next )
{
while ( 1 )
{
v2 = i->ifa_addr;
if ( v2->sa_family == 2 )
{
v3 = getnameinfo(v2, 0x10u, host, 0x401u, 0LL, 0, 1);
if ( v3 )
{
v5 = gai_strerror(v3);
printf("getnameinfo() failed: %s\n", v5);
exit(1);
}
v4 = strcmp(i->ifa_name, "bond0") == 0;
v0 = !v4;
if ( v4 )
break;
}
i = i->ifa_next;
if ( !i )
return v0;
}
LOBYTE(v0) = printf("local server is %s.\n", host);
}
return v0;
}

canonical_decompiled_code:
char func5()
{
int v0; // eax
struct ifaddrs *i; // rbx
const struct sockaddr *v2; // rdi
int v3; // eax
bool v4; // zf
const char *v5; // rax
struct ifaddrs *ifap; // [rsp+8h] [rbp-420h] BYREF
char host[1048]; // [rsp+10h] [rbp-418h] BYREF

v0 = getifaddrs(&ifap);
if ( v0 == -1 )
{
perror("getifaddrs");
exit(1);
}
for ( i = ifap; i; i = i->ifa_next )
{
while ( 1 )
{
v2 = i->ifa_addr;
if ( v2->sa_family == 2 )
{
v3 = getnameinfo(v2, 0x10u, host, 0x401u, 0LL, 0, 1);
if ( v3 )
{
v5 = gai_strerror(v3);
printf("getnameinfo() failed: %s\n", v5);
exit(1);
}
v4 = strcmp(i->ifa_name, "bond0") == 0;
v0 = !v4;
if ( v4 )
break;
}
i = i->ifa_next;
if ( !i )
return v0;
}
LOBYTE(v0) = printf("local server is %s.\n", host);
}
return v0;
}

original_code:
void get_local_ip()
{
  struct ifaddrs *ifaddr, *ifa;
  int family, s;
  char host[1025];
  if (getifaddrs(&ifaddr) == -1) {
    perror("getifaddrs");
    exit(1);
  }
  for (ifa = ifaddr; ifa != ((void *)0); ifa = ifa->ifa_next) {
    family = ifa->ifa_addr->sa_family;
    if (family == 2) {
      s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),
                                               host, 1025, ((void *)0), 0, 1);
      if (s != 0) {
        printf("getnameinfo() failed: %s\n", gai_strerror(s));
        exit(1);
      }
      if(!strcmp(ifa->ifa_name, "bond0"))
        printf("local server is %s.\n", host);
    }
  }
}

canonical_original_code:
void get_local_ip()
{
  struct ifaddrs *ifaddr; struct ifaddrs *ifa;
  int family; int s;
  char host[1025];
  if (getifaddrs(&ifaddr) == -1) {
    perror("getifaddrs");
    exit(1);
  }
  for (ifa = ifaddr; ifa != ((void *)0); ifa = ifa->ifa_next) {
    family = ifa->ifa_addr->sa_family;
    if (family == 2) {
      s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),
                                               host, 1025, ((void *)0), 0, 1);
      if (s != 0) {
        printf("getnameinfo() failed: %s\n", gai_strerror(s));
        exit(1);
      }
      if(!strcmp(ifa->ifa_name, "bond0"))
        printf("local server is %s.\n", host);
    }
  }
}

variable_types: struct ifaddrs { struct ifaddrs *ifa_next; char *ifa_name; unsigned int ifa_flags; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ifa_addr; struct sockaddr *ifa_netmask; union { struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; void *ifa_data; } *

variable_types: family int

variable_types: s int

variable_types:
host
char [1025]

user_defined_types: struct ifaddrs { struct ifaddrs *ifa_next; char *ifa_name; unsigned int ifa_flags; struct sockaddr *ifa_addr; struct sockaddr *ifa_netmask; union { struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; void *ifa_data; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rbp
socklen_t v4; // edx
int v5; // er13
__int64 v6; // rsi
int v7; // edi
int v8; // edx
int v9; // eax
__int64 v10; // rax
int v11; // ecx
int v12; // er8
int v13; // eax
char *v14; // rax
__int64 v15; // r14
__int64 v16; // rbp
int v17; // edi
int v18; // eax
int v19; // eax
__int64 v20; // rdx
int v21; // edx
__int64 v22; // rax
void *v23; // rsi
int v24; // eax
bool v25; // sf
int v26; // eax
int v27; // edx
int v28; // eax
int v29; // eax
int v30; // eax
int v31; // eax
char *v32; // rax
__int64 v34; // [rsp+0h] [rbp-258h]
int fd; // [rsp+8h] [rbp-250h]
char v36; // [rsp+Fh] [rbp-249h]
__int16 v37; // [rsp+10h] [rbp-248h] BYREF
int v38; // [rsp+14h] [rbp-244h] BYREF
int optval; // [rsp+18h] [rbp-240h] BYREF
socklen_t addr_len; // [rsp+1Ch] [rbp-23Ch] BYREF
struct sockaddr v41; // [rsp+20h] [rbp-238h] BYREF
struct sockaddr addr; // [rsp+30h] [rbp-228h] BYREF
struct timeval timeout; // [rsp+40h] [rbp-218h] BYREF
_QWORD v44[3]; // [rsp+50h] [rbp-208h] BYREF
__int64 v45; // [rsp+68h] [rbp-1F0h]
__int64 v46; // [rsp+70h] [rbp-1E8h]
fd_set readfds; // [rsp+80h] [rbp-1D8h] BYREF
fd_set writefds; // [rsp+100h] [rbp-158h] BYREF
struct sigaction v49; // [rsp+180h] [rbp-D8h] BYREF

get_local_ip();
v49.sa_handler = (__sighandler_t)exit_handler;
sigemptyset(&v49.sa_mask);
v49.sa_flags = 0;
sigaction(2, &v49, 0LL);
if ( (unsigned int)(argc - 2) > 2 )
{
fprintf(stderr, "Syntax: %s port [mode] [root_directory]\n", *argv);
}
else if ( (int)_isoc99_sscanf(argv[1], "%d", &v37) <= 0 )
{
fwrite("port should be numeric\n", 1uLL, 0x17uLL, stderr);
}
else
{
if ( argc == 2 )
goto LABEL_7;
if ( argc == 3 )
{
fwrite("Input server root!\n", 1uLL, 0x13uLL, stderr);
}
else
{
if ( (int)parse_root(argv[3]) >= 0 )
{
v3 = argv[2];
if ( (int)strlen(v3) > 2 && !strncmp(v3, "www", 3uLL) )
{
puts("Starting in web mode");
v36 = 1;
LABEL_8:
optval = 1;
addr_len = 16;
root = (__int64)v44;
LODWORD(v44[0]) = -1;
v45 = 0LL;
v46 = 0LL;
fd = socket(2, 1, 6);
if ( fd < 0 )
{
perror("opening TCP socket");
abort();
}
if ( setsockopt(fd, 1, 2, &optval, 4u) < 0 )
{
perror("setting TCP socket option");
abort();
}
v41 = 0LL;
v41.sa_family = 2;
*(_WORD *)v41.sa_data = _bswap_16(v37);
if ( bind(fd, &v41, v4) < 0 )
{
perror("binding socket to address");
abort();
}
if ( listen(fd, 5) < 0 )
{
perror("listen on socket failed");
abort();
}
v34 = 1LL << fd;
v5 = fd >> 6;
while ( 1 )
{
do
{
LABEL_13:
memset(&readfds, 0, sizeof(readfds));
memset(&writefds, 0, sizeof(writefds));
v6 = v45;
v7 = fd;
readfds.fds_bits[v5] |= v34;
while ( v6 )
{
v8 = *(_DWORD *)v6;
v9 = *(_DWORD *)v6 + 63;
if ( *(int *)v6 >= 0 )
v9 = *(_DWORD *)v6;
v10 = v9 >> 6;
v11 = *(_DWORD *)v6 % 64;
v12 = *(_DWORD *)(v6 + 20);
readfds.fds_bits[v10] |= 1LL << v11;
if ( v12 )
writefds.fds_bits[v10] |= 1LL << v11;
v6 = *(_QWORD *)(v6 + 24);
if ( v7 < v8 )
v7 = v8;
}
timeout.tv_usec = 100000LL;
timeout.tv_sec = 0LL;
v13 = select(v7 + 1, &readfds, &writefds, 0LL, &timeout);
if ( v13 < 0 )
{
perror("select failed");
abort();
}
}
while ( !v13 );
if ( (readfds.fds_bits[v5] & v34) == 0 )
goto LABEL_29;
v38 = accept(fd, &addr, &addr_len);
if ( v38 < 0 )
{
perror("error accepting connection");
abort();
}
if ( !v36 )
break;
service_request(&v38);
}
if ( fcntl(v38, 4, 2048LL) < 0 )
{
perror("making socket non-blocking");
abort();
}
v14 = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
printf("Accepted connection. Client IP address is: %s\n", v14);
add((__int64)v44, v38, *(__int64 *)&addr.sa_family, *(__int64 *)&addr.sa_data[6]);
LABEL_29:
v15 = v45;
while ( 1 )
{
if ( !v15 )
goto LABEL_13;
v16 = v15;
v15 = *(_QWORD *)(v15 + 24);
v17 = *(_DWORD *)v16;
v18 = *(_DWORD *)v16 + 63;
if ( *(int *)v16 >= 0 )
v18 = *(_DWORD *)v16;
v19 = v18 >> 6;
v20 = 1LL << (*(_DWORD *)v16 % 64);
if ( (writefds.fds_bits[v19] & v20) == 0 )
goto LABEL_34;
v29 = send(
v17,
(const void *)(*(_QWORD *)(v16 + 32) + *(int *)(v16 + 40)),
*(_DWORD *)(v16 + 44) - *(_DWORD *)(v16 + 40),
64);
if ( v29 >= 0 )
break;
if ( *_errno_location() == 11 )
{
puts("socket not ready for send.");
v30 = *(_DWORD *)(v16 + 40);
LABEL_45:
if ( *(_DWORD *)(v16 + 44) == v30 )
goto LABEL_57;
goto LABEL_46;
}
perror("not an good errno. closing the connection...");
close(*(_DWORD *)v16);
dump(v44, *(_DWORD *)v16);
if ( *(_DWORD *)(v16 + 44) == *(_DWORD *)(v16 + 40) )
{
LABEL_57:
*(_DWORD *)(v16 + 20) = 0;
*(_DWORD *)(v16 + 40) = 0;
goto LABEL_47;
}
LABEL_46:
*(_DWORD *)(v16 + 20) = 1;
LABEL_47:
v17 = *(_DWORD *)v16;
v31 = *(_DWORD *)v16 + 63;
if ( *(int *)v16 >= 0 )
v31 = *(_DWORD *)v16;
v19 = v31 >> 6;
v20 = 1LL << (*(_DWORD *)v16 % 64);
LABEL_34:
if ( (readfds.fds_bits[v19] & v20) != 0 )
{
v21 = *(_DWORD *)(v16 + 44);
v22 = *(int *)(v16 + 40);
v23 = (void *)(*(_QWORD *)(v16 + 32) + v22);
if ( v21 )
{
v24 = recv(v17, v23, v21 - (int)v22, 64);
v25 = v24 < 0;
if ( !v24 )
{
LABEL_51:
v32 = inet_ntoa(*(struct in_addr *)(v16 + 8));
printf("Client closed connection. Client IP address is: %s\n", v32);
goto LABEL_52;
}
}
else
{
v24 = recv(v17, v23, 0x20000 - (int)v22, 64);
v25 = v24 < 0;
if ( !v24 )
goto LABEL_51;
}
if ( v25 )
{
if ( *_errno_location() == 11 )
{
puts("socket not ready for recv.");
}
else
{
perror("error receiving from a client, closed down the connecion");
LABEL_52:
close(*(_DWORD *)v16);
dump(v44, *(_DWORD *)v16);
}
}
else
{
v26 = *(_DWORD *)(v16 + 40) + v24;
*(_DWORD *)(v16 + 40) = v26;
v27 = v26;
if ( v26 > 2 )
{
v28 = *(_DWORD *)(v16 + 44);
if ( !v28 )
{
v28 = (unsigned __int16)_bswap_16(**(_WORD **)(v16 + 32));
*(_DWORD *)(v16 + 44) = (unsigned __int16)v28;
}
if ( v27 == v28 )
{
*(_DWORD *)(v16 + 20) = 1;
*(_DWORD *)(v16 + 40) = 0;
}
}
}
}
}
v30 = *(_DWORD *)(v16 + 40) + v29;
*(_DWORD *)(v16 + 40) = v30;
goto LABEL_45;
}
LABEL_7:
v36 = 0;
goto LABEL_8;
}
fwrite("Invalid server root\n", 1uLL, 0x14uLL, stderr);
}
}
return -1;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rbp
socklen_t v4; // edx
int v5; // er13
__int64 v6; // rsi
int v7; // edi
int v8; // edx
int v9; // eax
__int64 v10; // rax
int v11; // ecx
int v12; // er8
int v13; // eax
char *v14; // rax
__int64 v15; // r14
__int64 v16; // rbp
int v17; // edi
int v18; // eax
int v19; // eax
__int64 v20; // rdx
int v21; // edx
__int64 v22; // rax
void *v23; // rsi
int v24; // eax
bool v25; // sf
int v26; // eax
int v27; // edx
int v28; // eax
int v29; // eax
int v30; // eax
int v31; // eax
char *v32; // rax
__int64 v34; // [rsp+0h] [rbp-258h]
int fd; // [rsp+8h] [rbp-250h]
char v36; // [rsp+Fh] [rbp-249h]
__int16 v37; // [rsp+10h] [rbp-248h] BYREF
int v38; // [rsp+14h] [rbp-244h] BYREF
int optval; // [rsp+18h] [rbp-240h] BYREF
socklen_t addr_len; // [rsp+1Ch] [rbp-23Ch] BYREF
struct sockaddr v41; // [rsp+20h] [rbp-238h] BYREF
struct sockaddr addr; // [rsp+30h] [rbp-228h] BYREF
struct timeval timeout; // [rsp+40h] [rbp-218h] BYREF
_QWORD v44[3]; // [rsp+50h] [rbp-208h] BYREF
__int64 v45; // [rsp+68h] [rbp-1F0h]
__int64 v46; // [rsp+70h] [rbp-1E8h]
fd_set readfds; // [rsp+80h] [rbp-1D8h] BYREF
fd_set writefds; // [rsp+100h] [rbp-158h] BYREF
struct sigaction v49; // [rsp+180h] [rbp-D8h] BYREF

func5();
v49.sa_handler = (__sighandler_t)exit_handler;
sigemptyset(&v49.sa_mask);
v49.sa_flags = 0;
sigaction(2, &v49, 0LL);
if ( (unsigned int)(argc - 2) > 2 )
{
fprintf(stderr, "Syntax: %s port [mode] [root_directory]\n", *argv);
}
else if ( (int)_isoc99_sscanf(argv[1], "%d", &v37) <= 0 )
{
fwrite("port should be numeric\n", 1uLL, 0x17uLL, stderr);
}
else
{
if ( argc == 2 )
goto LABEL_7;
if ( argc == 3 )
{
fwrite("Input server root!\n", 1uLL, 0x13uLL, stderr);
}
else
{
if ( (int)parse_root(argv[3]) >= 0 )
{
v3 = argv[2];
if ( (int)strlen(v3) > 2 && !strncmp(v3, "www", 3uLL) )
{
puts("Starting in web mode");
v36 = 1;
LABEL_8:
optval = 1;
addr_len = 16;
root = (__int64)v44;
LODWORD(v44[0]) = -1;
v45 = 0LL;
v46 = 0LL;
fd = socket(2, 1, 6);
if ( fd < 0 )
{
perror("opening TCP socket");
abort();
}
if ( setsockopt(fd, 1, 2, &optval, 4u) < 0 )
{
perror("setting TCP socket option");
abort();
}
v41 = 0LL;
v41.sa_family = 2;
*(_WORD *)v41.sa_data = func0(v37);
if ( bind(fd, &v41, v4) < 0 )
{
perror("binding socket to address");
abort();
}
if ( listen(fd, 5) < 0 )
{
perror("listen on socket failed");
abort();
}
v34 = 1LL << fd;
v5 = fd >> 6;
while ( 1 )
{
do
{
LABEL_13:
memset(&readfds, 0, sizeof(readfds));
memset(&writefds, 0, sizeof(writefds));
v6 = v45;
v7 = fd;
readfds.fds_bits[v5] |= v34;
while ( v6 )
{
v8 = *(_DWORD *)v6;
v9 = *(_DWORD *)v6 + 63;
if ( *(int *)v6 >= 0 )
v9 = *(_DWORD *)v6;
v10 = v9 >> 6;
v11 = *(_DWORD *)v6 % 64;
v12 = *(_DWORD *)(v6 + 20);
readfds.fds_bits[v10] |= 1LL << v11;
if ( v12 )
writefds.fds_bits[v10] |= 1LL << v11;
v6 = *(_QWORD *)(v6 + 24);
if ( v7 < v8 )
v7 = v8;
}
timeout.tv_usec = 100000LL;
timeout.tv_sec = 0LL;
v13 = select(v7 + 1, &readfds, &writefds, 0LL, &timeout);
if ( v13 < 0 )
{
perror("select failed");
abort();
}
}
while ( !v13 );
if ( (readfds.fds_bits[v5] & v34) == 0 )
goto LABEL_29;
v38 = accept(fd, &addr, &addr_len);
if ( v38 < 0 )
{
perror("error accepting connection");
abort();
}
if ( !v36 )
break;
service_request(&v38);
}
if ( fcntl(v38, 4, 2048LL) < 0 )
{
perror("making socket non-blocking");
abort();
}
v14 = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
printf("Accepted connection. Client IP address is: %s\n", v14);
func2((__int64)v44, v38, *(__int64 *)&addr.sa_family, *(__int64 *)&addr.sa_data[6]);
LABEL_29:
v15 = v45;
while ( 1 )
{
if ( !v15 )
goto LABEL_13;
v16 = v15;
v15 = *(_QWORD *)(v15 + 24);
v17 = *(_DWORD *)v16;
v18 = *(_DWORD *)v16 + 63;
if ( *(int *)v16 >= 0 )
v18 = *(_DWORD *)v16;
v19 = v18 >> 6;
v20 = 1LL << (*(_DWORD *)v16 % 64);
if ( (writefds.fds_bits[v19] & v20) == 0 )
goto LABEL_34;
v29 = send(
v17,
(const void *)(*(_QWORD *)(v16 + 32) + *(int *)(v16 + 40)),
*(_DWORD *)(v16 + 44) - *(_DWORD *)(v16 + 40),
64);
if ( v29 >= 0 )
break;
if ( *_errno_location() == 11 )
{
puts("socket not ready for send.");
v30 = *(_DWORD *)(v16 + 40);
LABEL_45:
if ( *(_DWORD *)(v16 + 44) == v30 )
goto LABEL_57;
goto LABEL_46;
}
perror("not an good errno. closing the connection...");
close(*(_DWORD *)v16);
func1(v44, *(_DWORD *)v16);
if ( *(_DWORD *)(v16 + 44) == *(_DWORD *)(v16 + 40) )
{
LABEL_57:
*(_DWORD *)(v16 + 20) = 0;
*(_DWORD *)(v16 + 40) = 0;
goto LABEL_47;
}
LABEL_46:
*(_DWORD *)(v16 + 20) = 1;
LABEL_47:
v17 = *(_DWORD *)v16;
v31 = *(_DWORD *)v16 + 63;
if ( *(int *)v16 >= 0 )
v31 = *(_DWORD *)v16;
v19 = v31 >> 6;
v20 = 1LL << (*(_DWORD *)v16 % 64);
LABEL_34:
if ( (readfds.fds_bits[v19] & v20) != 0 )
{
v21 = *(_DWORD *)(v16 + 44);
v22 = *(int *)(v16 + 40);
v23 = (void *)(*(_QWORD *)(v16 + 32) + v22);
if ( v21 )
{
v24 = recv(v17, v23, v21 - (int)v22, 64);
v25 = v24 < 0;
if ( !v24 )
{
LABEL_51:
v32 = inet_ntoa(*(struct in_addr *)(v16 + 8));
printf("Client closed connection. Client IP address is: %s\n", v32);
goto LABEL_52;
}
}
else
{
v24 = recv(v17, v23, 0x20000 - (int)v22, 64);
v25 = v24 < 0;
if ( !v24 )
goto LABEL_51;
}
if ( v25 )
{
if ( *_errno_location() == 11 )
{
puts("socket not ready for recv.");
}
else
{
perror("error receiving from a client, closed down the connecion");
LABEL_52:
close(*(_DWORD *)v16);
func1(v44, *(_DWORD *)v16);
}
}
else
{
v26 = *(_DWORD *)(v16 + 40) + v24;
*(_DWORD *)(v16 + 40) = v26;
v27 = v26;
if ( v26 > 2 )
{
v28 = *(_DWORD *)(v16 + 44);
if ( !v28 )
{
v28 = (unsigned __int16)func0(**(_WORD **)(v16 + 32));
*(_DWORD *)(v16 + 44) = (unsigned __int16)v28;
}
if ( v27 == v28 )
{
*(_DWORD *)(v16 + 20) = 1;
*(_DWORD *)(v16 + 40) = 0;
}
}
}
}
}
v30 = *(_DWORD *)(v16 + 40) + v29;
*(_DWORD *)(v16 + 40) = v30;
goto LABEL_45;
}
LABEL_7:
v36 = 0;
goto LABEL_8;
}
fwrite("Invalid server root\n", 1uLL, 0x14uLL, stderr);
}
}
return -1;
}

original_code:
int main(int argc, char **argv) {
  get_local_ip();
   struct sigaction sigIntHandler;
   sigIntHandler.__sigaction_handler.sa_handler = exit_handler;
   sigemptyset(&sigIntHandler.sa_mask);
   sigIntHandler.sa_flags = 0;
   sigaction(2, &sigIntHandler, ((void *)0));
  int server_port;
  char *mode;
  char webMode = 0;
  if ((argc < 2) || (argc > 4)) {
    fprintf(stderr, "Syntax: %s port [mode] [root_directory]\n",argv[0]);
    return -1;
  }
  if (sscanf(argv[1], "%d", &server_port) < 1) {
    fprintf(stderr, "port should be numeric\n");
    return -1;
  }
  if (argc > 2) {
    if (argc == 3) {
        fprintf(stderr, "Input server root!\n");
          return -1;
    } else {
        if (parse_root(argv[3]) < 0) {
          fprintf(stderr, "Invalid server root\n");
          return -1;
        }
    }
    mode = argv[2];
    int modelen = strlen(mode);
    if (modelen > 2) {
      if (strncmp(mode, "www", 3) == 0) {
        printf("Starting in web mode\n");
        webMode = 1;
      }
    }
  }
  int sock, new_sock, max;
  int optval = 1;
  struct sockaddr_in sin, addr;
  socklen_t addr_len = sizeof(struct sockaddr_in);
  int BACKLOG = 5;
  fd_set read_set, write_set;
  struct timeval time_out;
  int select_retval;
  int count;
  struct node head;
  struct node *current, *next;
  root = &head;
  head.socket = -1;
  head.next = 0;
  head.buffer = ((void *)0);
  if ((sock = socket (2, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
      perror ("opening TCP socket");
      abort ();
    }
  if (setsockopt (sock, 1, 2, &optval, sizeof (optval)) <0)
    {
      perror ("setting TCP socket option");
      abort ();
    }
  memset (&sin, 0, sizeof (sin));
  sin.sin_family = 2;
  sin.sin_addr.s_addr = ((in_addr_t) 0x00000000);
  sin.sin_port = htons (server_port);
  if (bind(sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
    {
      perror("binding socket to address");
      abort();
    }
  if (listen (sock, BACKLOG) < 0)
    {
      perror ("listen on socket failed");
      abort();
    }
  while (1){
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&read_set)->__fds_bits)[0]) : "memory"); } while (0);
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&write_set)->__fds_bits)[0]) : "memory"); } while (0);
    ((void) (((&read_set)->__fds_bits)[((sock) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((sock) % (8 * (int) sizeof (__fd_mask)))))));
    max = sock;
    for (current = head.next; current; current = current->next) {
      ((void) (((&read_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))));
      if (current->pending_data) {
        ((void) (((&write_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))));
      }
      if (current->socket > max) {
        max = current->socket;
      }
    }
    time_out.tv_usec = 100000;
    time_out.tv_sec = 0;
    select_retval = select(max+1, &read_set, &write_set, ((void *)0), &time_out);
    if (select_retval < 0){
      perror ("select failed");
      abort ();
    }
    if (select_retval == 0){
      continue;
    }
    if (select_retval > 0) {
      if (((((&read_set)->__fds_bits)[((sock) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((sock) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
        new_sock = accept (sock, (struct sockaddr *) &addr, &addr_len);
        if (new_sock < 0){
                 perror ("error accepting connection");
                 abort ();
              }
        if (webMode) {
          service_request(&new_sock);
          continue;
        }
        if (fcntl (new_sock, 4, 04000) < 0){
          perror ("making socket non-blocking");
          abort ();
        }
        printf("Accepted connection. Client IP address is: %s\n",
              inet_ntoa(addr.sin_addr));
        add(&head, new_sock, addr);
      }
      for (current = head.next; current; current = next) {
        next = current->next;
        if (((((&write_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
          count = send(current->socket, current->buffer + current->n_bytes, current->msg_size - current->n_bytes, MSG_DONTWAIT);
          if (count < 0) {
            switch((*__errno_location ())){
            case 11:
              printf("socket not ready for send.\n");
              break;
            default:
              perror("not an good errno. closing the connection...");
              close(current->socket);
              dump(&head, current->socket);
              break;
            }
          }
          else{
            current->n_bytes += count;
          }
          if(current->n_bytes == current->msg_size){
            current->pending_data = 0;
            current->n_bytes = 0;
          }
          else{
            current->pending_data = 1;
          }
        }
        if (((((&read_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
          if(current->msg_size == 0){
            count = recv(current->socket, current->buffer + current->n_bytes, (2<<16) - current->n_bytes, MSG_DONTWAIT);
          }
          else{
            count = recv(current->socket, current->buffer + current->n_bytes, current->msg_size - current->n_bytes, MSG_DONTWAIT);
          }
          if (count == 0) {
              printf("Client closed connection. Client IP address is: %s\n", inet_ntoa(current->client_addr.sin_addr));
              close(current->socket);
              dump(&head, current->socket);
          }
          else if (count < 0){
            switch((*__errno_location ())){
            case 11:
              printf("socket not ready for recv.\n");
              break;
            default:
              perror("error receiving from a client, closed down the connecion");
              close(current->socket);
              dump(&head, current->socket);
              break;
            }
          }
          else {
            current->n_bytes += count;
            if(current->n_bytes > 2){
              if(current->msg_size == 0){
                current->msg_size = ntohs(*(unsigned short *)current->buffer);
              }
              if(current->n_bytes == current->msg_size){
                current->pending_data = 1;
                current->n_bytes = 0;
              }
            }
          }
        }
      }
    }
  }
}

canonical_original_code:
int main(int argc, char **argv) {
  get_local_ip();
   struct sigaction sigIntHandler;
   sigIntHandler.__sigaction_handler.sa_handler = exit_handler;
   sigemptyset(&sigIntHandler.sa_mask);
   sigIntHandler.sa_flags = 0;
   sigaction(2, &sigIntHandler, ((void *)0));
  int server_port;
  char *mode;
  char webMode = 0;
  if ((argc < 2) || (argc > 4)) {
    fprintf(stderr, "Syntax: %s port [mode] [root_directory]\n",argv[0]);
    return -1;
  }
  if (sscanf(argv[1], "%d", &server_port) < 1) {
    fprintf(stderr, "port should be numeric\n");
    return -1;
  }
  if (argc > 2) {
    if (argc == 3) {
        fprintf(stderr, "Input server root!\n");
          return -1;
    } else {
        if (parse_root(argv[3]) < 0) {
          fprintf(stderr, "Invalid server root\n");
          return -1;
        }
    }
    mode = argv[2];
    int modelen = strlen(mode);
    if (modelen > 2) {
      if (strncmp(mode, "www", 3) == 0) {
        printf("Starting in web mode\n");
        webMode = 1;
      }
    }
  }
  int sock; int new_sock; int max;
  int optval = 1;
  struct sockaddr_in sin; struct sockaddr_in addr;
  unsigned int addr_len = sizeof(struct sockaddr_in);
  int BACKLOG = 5;
  struct fd_set read_set; struct fd_set write_set;
  struct timeval time_out;
  int select_retval;
  int count;
  struct node head;
  struct node *current; struct node *next;
  root = &head;
  head.socket = -1;
  head.next = 0;
  head.buffer = ((void *)0);
  if ((sock = socket (2, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
      perror ("opening TCP socket");
      abort ();
    }
  if (setsockopt (sock, 1, 2, &optval, sizeof (optval)) <0)
    {
      perror ("setting TCP socket option");
      abort ();
    }
  memset (&sin, 0, sizeof (sin));
  sin.sin_family = 2;
  sin.sin_addr.s_addr = ((unsigned int) 0x00000000);
  sin.sin_port = htons (server_port);
  if (bind(sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
    {
      perror("binding socket to address");
      abort();
    }
  if (listen (sock, BACKLOG) < 0)
    {
      perror ("listen on socket failed");
      abort();
    }
  while (1){
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&read_set)->__fds_bits)[0]) : "memory"); } while (0);
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&write_set)->__fds_bits)[0]) : "memory"); } while (0);
    ((void) (((&read_set)->__fds_bits)[((sock) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((sock) % (8 * (int) sizeof (__fd_mask)))))));
    max = sock;
    for (current = head.next; current; current = current->next) {
      ((void) (((&read_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))));
      if (current->pending_data) {
        ((void) (((&write_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))));
      }
      if (current->socket > max) {
        max = current->socket;
      }
    }
    time_out.tv_usec = 100000;
    time_out.tv_sec = 0;
    select_retval = select(max+1, &read_set, &write_set, ((void *)0), &time_out);
    if (select_retval < 0){
      perror ("select failed");
      abort ();
    }
    if (select_retval == 0){
      continue;
    }
    if (select_retval > 0) {
      if (((((&read_set)->__fds_bits)[((sock) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((sock) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
        new_sock = accept (sock, (struct sockaddr *) &addr, &addr_len);
        if (new_sock < 0){
                 perror ("error accepting connection");
                 abort ();
              }
        if (webMode) {
          service_request(&new_sock);
          continue;
        }
        if (fcntl (new_sock, 4, 04000) < 0){
          perror ("making socket non-blocking");
          abort ();
        }
        printf("Accepted connection. Client IP address is: %s\n",
              inet_ntoa(addr.sin_addr));
        add(&head, new_sock, addr);
      }
      for (current = head.next; current; current = next) {
        next = current->next;
        if (((((&write_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
          count = send(current->socket, current->buffer + current->n_bytes, current->msg_size - current->n_bytes, MSG_DONTWAIT);
          if (count < 0) {
            switch((*__errno_location ())){
            case 11:
              printf("socket not ready for send.\n");
              break;
            default:
              perror("not an good errno. closing the connection...");
              close(current->socket);
              dump(&head, current->socket);
              break;
            }
          }
          else{
            current->n_bytes += count;
          }
          if(current->n_bytes == current->msg_size){
            current->pending_data = 0;
            current->n_bytes = 0;
          }
          else{
            current->pending_data = 1;
          }
        }
        if (((((&read_set)->__fds_bits)[((current->socket) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((current->socket) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
          if(current->msg_size == 0){
            count = recv(current->socket, current->buffer + current->n_bytes, (2<<16) - current->n_bytes, MSG_DONTWAIT);
          }
          else{
            count = recv(current->socket, current->buffer + current->n_bytes, current->msg_size - current->n_bytes, MSG_DONTWAIT);
          }
          if (count == 0) {
              printf("Client closed connection. Client IP address is: %s\n", inet_ntoa(current->client_addr.sin_addr));
              close(current->socket);
              dump(&head, current->socket);
          }
          else if (count < 0){
            switch((*__errno_location ())){
            case 11:
              printf("socket not ready for recv.\n");
              break;
            default:
              perror("error receiving from a client, closed down the connecion");
              close(current->socket);
              dump(&head, current->socket);
              break;
            }
          }
          else {
            current->n_bytes += count;
            if(current->n_bytes > 2){
              if(current->msg_size == 0){
                current->msg_size = ntohs(*(unsigned short *)current->buffer);
              }
              if(current->n_bytes == current->msg_size){
                current->pending_data = 1;
                current->n_bytes = 0;
              }
            }
          }
        }
      }
    }
  }
}

variable_types: argc int

variable_types:
argv
char **

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)(); }

variable_types:
mode
char *

variable_types: webMode char

variable_types: modelen int

variable_types: sock int

variable_types: max int

variable_types: optval int

variable_types: BACKLOG int

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types: count int

variable_types: struct node { int socket; 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]; } client_addr; int pending_data; struct node *next; char *buffer; int n_bytes; int msg_size; }

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 sockaddr { unsigned short sa_family; char sa_data[14]; }

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; }


parse

decompiled_code:
__int64 __fastcall parse(char *file)
{
size_t v1; // rax
const char *v2; // r14
size_t v3; // r13
size_t v4; // r13
char *v5; // rax
size_t v6; // rdx
unsigned int v7; // er13
char *v8; // rbp
size_t v9; // rax
char v11; // [rsp+8h] [rbp-C0h] BYREF
char v12; // [rsp+Ch] [rbp-BCh] BYREF
struct stat v13; // [rsp+10h] [rbp-B8h] BYREF

if ( (unsigned int)_isoc99_sscanf(file, "GET %s HTTP/%d.%d \r\n\r\n", file, &v11, &v12) == 3 )
{
if ( strstr(file, "../") )
{
v7 = -2;
fprintf(stderr, "Illegal request: %s\n", file);
}
else
{
v1 = strlen(file);
v2 = serverPath;
v3 = v1;
if ( v1 + strlen(serverPath) + 1 > 0x400 )
{
v7 = -1;
fprintf(stderr, "Request too long for buffer: %s%s\n", v2, file);
}
else
{
v4 = v3 + 1;
v5 = (char *)malloc(v4);
v6 = v4;
v7 = 0;
v8 = v5;
memcpy(v5, file, v6);
sprintf(file, "%s%s", v2, v8);
free(v8);
stat(file, &v13);
if ( (v13.st_mode & 0x4000) != 0 )
{
v9 = strlen(file);
if ( v9 + 11 > 0x3FF )
{
v7 = -1;
fprintf(stderr, "Request too long for buffer: %s%s/index.html\n", serverPath, file);
}
else
{
strcpy(&file[v9], "/index.html");
}
}
}
}
}
else
{
v7 = -1;
fprintf(stderr, "Failed to scan client request: %s\n", file);
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *file)
{
size_t v1; // rax
const char *v2; // r14
size_t v3; // r13
size_t v4; // r13
char *v5; // rax
size_t v6; // rdx
unsigned int v7; // er13
char *v8; // rbp
size_t v9; // rax
char v11; // [rsp+8h] [rbp-C0h] BYREF
char v12; // [rsp+Ch] [rbp-BCh] BYREF
struct stat v13; // [rsp+10h] [rbp-B8h] BYREF

if ( (unsigned int)_isoc99_sscanf(file, "GET %s HTTP/%d.%d \r\n\r\n", file, &v11, &v12) == 3 )
{
if ( strstr(file, "../") )
{
v7 = -2;
fprintf(stderr, "Illegal request: %s\n", file);
}
else
{
v1 = strlen(file);
v2 = serverPath;
v3 = v1;
if ( v1 + strlen(serverPath) + 1 > 0x400 )
{
v7 = -1;
fprintf(stderr, "Request too long for buffer: %s%s\n", v2, file);
}
else
{
v4 = v3 + 1;
v5 = (char *)malloc(v4);
v6 = v4;
v7 = 0;
v8 = v5;
memcpy(v5, file, v6);
sprintf(file, "%s%s", v2, v8);
free(v8);
stat(file, &v13);
if ( (v13.st_mode & 0x4000) != 0 )
{
v9 = strlen(file);
if ( v9 + 11 > 0x3FF )
{
v7 = -1;
fprintf(stderr, "Request too long for buffer: %s%s/index.html\n", serverPath, file);
}
else
{
strcpy(&file[v9], "/index.html");
}
}
}
}
}
else
{
v7 = -1;
fprintf(stderr, "Failed to scan client request: %s\n", file);
}
return v7;
}

original_code:
int parse(char *buffer) {
 int version_major;
 int version_minor;
 char *temp_buf;
 struct stat s;
 if (sscanf(buffer, "GET %s HTTP/%d.%d \r\n\r\n", buffer, &version_major, &version_minor) != 3) {
  fprintf(stderr, "Failed to scan client request: %s\n", buffer);
  return -1;
 }
 if (0)
  printf("Received request for %s (HTTP %d.%d)\n", buffer, version_major, version_minor);
 if (strstr(buffer,"../") != ((void *)0)) {
  fprintf(stderr, "Illegal request: %s\n", buffer);
  return -2;
 }
 if (strlen(buffer) + strlen(serverPath) + 1 > 1024) {
  fprintf(stderr, "Request too long for buffer: %s%s\n", serverPath,buffer);
  return -1;
 }
 temp_buf = malloc(strlen(buffer) + 1);
 strcpy(temp_buf, buffer);
 sprintf(buffer,"%s%s",serverPath,temp_buf);
 free(temp_buf);
 stat(buffer, &s);
 if (s.st_mode & 0040000) {
  if (0 > 1)
   printf("Request is for a directory.\n");
  if (strlen(buffer) + strlen("/index.html") >= 1024) {
   fprintf(stderr, "Request too long for buffer: %s%s/index.html\n", serverPath,buffer);
   return -1;
  }
  strcpy(buffer + strlen(buffer), "/index.html");
 }
 return 0;
}

variable_types:
buffer
char *

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


decompiled_code:
__int64 __fastcall send_error(int *a1, unsigned int a2, const char *a3)
{
size_t v4; // rax
char *v5; // rbp
size_t v6; // rax

v4 = strlen(a3);
v5 = (char *)malloc(2 * v4 + 184);
sprintf(
v5,
"HTTP/1.1 %d %s\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<title>Error %d</title>
Error %d: %s

We were unable to complete your request."
"  ",
a2,
a3,
a2,
a2,
a3);
v6 = strlen(v5);
if ( write(*a1, v5, v6) <= 0 )
fwrite("Unable to write error message to socket\n", 1uLL, 0x28uLL, stderr);
close(*a1);
free(v5);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(int *a1, unsigned int a2, const char *a3)
{
size_t v4; // rax
char *v5; // rbp
size_t v6; // rax

v4 = strlen(a3);
v5 = (char *)malloc(2 * v4 + 184);
sprintf(
v5,
"HTTP/1.1 %d %s\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<title>Error %d</title>
Error %d: %s

We were unable to complete your request."
"  ",
a2,
a3,
a2,
a2,
a3);
v6 = strlen(v5);
if ( write(*a1, v5, v6) <= 0 )
fwrite("Unable to write error message to socket\n", 1uLL, 0x28uLL, stderr);
close(*a1);
free(v5);
return 0LL;
}

original_code:
int send_error(int *socket_fd, int error_code, char *msg) {
 char *buf = malloc(strlen("HTTP/1.1 %d %s\r\nContent-Type: text/html\r\n\r\n<title>Error %d</title>
Error %d: %s

We were unable to complete your request.  ") + 2 * strlen(msg) + 3*3);
 sprintf(buf, "HTTP/1.1 %d %s\r\nContent-Type: text/html\r\n\r\n<title>Error %d</title>
Error %d: %s

We were unable to complete your request.  ", error_code, msg, error_code, error_code, msg);
 if (write(*socket_fd, buf, strlen(buf)) < 1)
  fprintf(stderr, "Unable to write error message to socket\n");
 close(*socket_fd);
 free(buf);
 return 0;
}

variable_types:
msg
char *

variable_types:
buf
char *


decompiled_code:
__int64 __fastcall parse_root(char *a1)
{
serverPath = a1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *a1)
{
serverPath = a1;
return 0LL;
}

original_code:
int parse_root(char *path) {
 serverPath = path;
 return 0;
}

variable_types:
path
char *


decompiled_code:
__int64 __fastcall service_request(int *a1)
{
char *v2; // rax
char *v3; // rbp
unsigned int v4; // eax
unsigned int v5; // er13
int v6; // er13
__int64 v7; // r14
size_t v8; // rax
int v9; // eax
int v10; // edi
const char *v12; // rdx
unsigned int v13; // esi

v2 = (char *)malloc(0x400uLL);
if ( !v2 )
{
v5 = -1;
send_error(a1, 0x1F4u, "Internal Server Error");
return v5;
}
v3 = v2;
if ( read(*a1, v2, 0x400uLL) == -1 )
goto LABEL_13;
v4 = parse(v3);
v5 = v4;
if ( v4 == -1 )
{
send_error(a1, 0x190u, "Bad Request");
free(v3);
return v5;
}
if ( v4 == -2 )
{
LABEL_13:
v12 = "Bad Request";
v13 = 400;
LABEL_14:
v5 = -1;
send_error(a1, v13, v12);
free(v3);
return v5;
}
v6 = open(v3, 0);
if ( v6 < 0 )
{
v12 = "Not Found";
v13 = 404;
goto LABEL_14;
}
v7 = magic_init(0LL);
magic_read_entries(v7, "magic");
magic_identify_file(v7, v3);
sprintf(v3, "HTTP/1.1 200 OK \r\nContent-Type: %s \r\n\r\n", 0LL);
v8 = strlen(v3);
if ( write(*a1, v3, v8) > 0 )
{
while ( 1 )
{
v9 = read(v6, v3, 0x400uLL);
if ( v9 <= 0 )
break;
if ( v9 > (int)write(*a1, v3, v9) )
{
fwrite("Error writing file to socket\n", 1uLL, 0x1DuLL, stderr);
break;
}
}
}
else
{
fwrite("Unable to write OK message to socket\n", 1uLL, 0x25uLL, stderr);
}
v10 = v6;
v5 = 0;
close(v10);
free(v3);
shutdown(*a1, 2);
close(*a1);
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func3(int *a1)
{
char *v2; // rax
char *v3; // rbp
unsigned int v4; // eax
unsigned int v5; // er13
int v6; // er13
__int64 v7; // r14
size_t v8; // rax
int v9; // eax
int v10; // edi
const char *v12; // rdx
unsigned int v13; // esi

v2 = (char *)malloc(0x400uLL);
if ( !v2 )
{
v5 = -1;
func1(a1, 0x1F4u, "Internal Server Error");
return v5;
}
v3 = v2;
if ( read(*a1, v2, 0x400uLL) == -1 )
goto LABEL_13;
v4 = func0(v3);
v5 = v4;
if ( v4 == -1 )
{
func1(a1, 0x190u, "Bad Request");
free(v3);
return v5;
}
if ( v4 == -2 )
{
LABEL_13:
v12 = "Bad Request";
v13 = 400;
LABEL_14:
v5 = -1;
func1(a1, v13, v12);
free(v3);
return v5;
}
v6 = open(v3, 0);
if ( v6 < 0 )
{
v12 = "Not Found";
v13 = 404;
goto LABEL_14;
}
v7 = magic_init(0LL);
magic_read_entries(v7, "magic");
magic_identify_file(v7, v3);
sprintf(v3, "HTTP/1.1 200 OK \r\nContent-Type: %s \r\n\r\n", 0LL);
v8 = strlen(v3);
if ( write(*a1, v3, v8) > 0 )
{
while ( 1 )
{
v9 = read(v6, v3, 0x400uLL);
if ( v9 <= 0 )
break;
if ( v9 > (int)write(*a1, v3, v9) )
{
fwrite("Error writing file to socket\n", 1uLL, 0x1DuLL, stderr);
break;
}
}
}
else
{
fwrite("Unable to write OK message to socket\n", 1uLL, 0x25uLL, stderr);
}
v10 = v6;
v5 = 0;
close(v10);
free(v3);
shutdown(*a1, 2);
close(*a1);
return v5;
}

original_code:
int service_request(int *socket_fd) {
 char *request_buffer;
 int result;
 int content_fd;
 int size;
 char *mime_type;
 request_buffer = malloc(1024);
 if (request_buffer == ((void *)0)) {
  send_error(socket_fd, 500, "Internal Server Error");
  free(request_buffer);
  return -1;
 }
 if (read(*socket_fd, request_buffer, 1024) == -1) {
  send_error(socket_fd, 400, "Bad Request");
  free(request_buffer);
  return -1;
 }
 result = parse(request_buffer);
 if (result == -1) {
  send_error(socket_fd, 400, "Bad Request");
  free(request_buffer);
  return -1;
 }
 if (result == -2) {
  send_error(socket_fd, 400, "Bad Request");
  free(request_buffer);
  return -1;
 }
 if (0 > 1)
  printf("Opening %s\n", request_buffer);
 content_fd = open(request_buffer, 00);
 if (content_fd < 0) {
  send_error(socket_fd, 404, "Not Found");
  free(request_buffer);
  return -1;
 }
 magichandle_t* mh;
 mh = magic_init (0x0);
 magic_read_entries(mh,"magic");
 magic_identify_file (mh, request_buffer);
 sprintf(request_buffer, "HTTP/1.1 200 OK \r\nContent-Type: %s \r\n\r\n", mime_type);
 if (write(*socket_fd, request_buffer, strlen(request_buffer)) < 1) {
  fprintf(stderr, "Unable to write OK message to socket\n");
  goto cleanup;
 }
 while ((size = read(content_fd, request_buffer, 1024)) > 0) {
  result = write(*socket_fd, request_buffer, size);
  if (result < size) {
   fprintf(stderr, "Error writing file to socket\n");
   goto cleanup;
  }
 }
 cleanup:
 close(content_fd);
 free(request_buffer);
 shutdown(*socket_fd, 2);
 close(*socket_fd);
 return 0;
}

canonical_original_code:
int service_request(int *socket_fd) {
 char *request_buffer;
 int result;
 int content_fd;
 int size;
 char *mime_type;
 request_buffer = malloc(1024);
 if (request_buffer == ((void *)0)) {
  send_error(socket_fd, 500, "Internal Server Error");
  free(request_buffer);
  return -1;
 }
 if (read(*socket_fd, request_buffer, 1024) == -1) {
  send_error(socket_fd, 400, "Bad Request");
  free(request_buffer);
  return -1;
 }
 result = parse(request_buffer);
 if (result == -1) {
  send_error(socket_fd, 400, "Bad Request");
  free(request_buffer);
  return -1;
 }
 if (result == -2) {
  send_error(socket_fd, 400, "Bad Request");
  free(request_buffer);
  return -1;
 }
 if (0 > 1)
  printf("Opening %s\n", request_buffer);
 content_fd = open(request_buffer, 00);
 if (content_fd < 0) {
  send_error(socket_fd, 404, "Not Found");
  free(request_buffer);
  return -1;
 }
 struct magichandle_t *mh;
 mh = magic_init (0x0);
 magic_read_entries(mh,"magic");
 magic_identify_file (mh, request_buffer);
 sprintf(request_buffer, "HTTP/1.1 200 OK \r\nContent-Type: %s \r\n\r\n", mime_type);
 if (write(*socket_fd, request_buffer, strlen(request_buffer)) < 1) {
  fprintf(stderr, "Unable to write OK message to socket\n");
  goto cleanup;
 }
 while ((size = read(content_fd, request_buffer, 1024)) > 0) {
  result = write(*socket_fd, request_buffer, size);
  if (result < size) {
   fprintf(stderr, "Error writing file to socket\n");
   goto cleanup;
  }
 }
 cleanup:
 close(content_fd);
 free(request_buffer);
 shutdown(*socket_fd, 2);
 close(*socket_fd);
 return 0;
}

variable_types: result int

variable_types: size int

variable_types: struct magichandle_t { unsigned int flags; unsigned long numentries; unsigned long num_l0_ents; unsigned long *l0_ents; struct magicentry_t { unsigned int level; unsigned char hits; unsigned int offset; enum type_t { byte_type=0, short_type=1, long_type=2, date_type=3, string_type=4 } type; enum comp_t { equ_comp=0, lt_comp=1, gt_comp=2, and_comp=3, xor_comp=4, any_comp=5, not_comp=6 } comp; struct { enum endian_t { native_endian=0, big_endian=1, little_endian=2 } endian; unsigned int value; unsigned int mask; } num; struct { unsigned char *value; unsigned long length; } str; char *msg; unsigned int indirect; struct { enum endian_t { native_endian=0, big_endian=1, little_endian=2 } endian; enum type_t { byte_type=0, short_type=1, long_type=2, date_type=3, string_type=4 } type; int delta; } indir; unsigned int relative; } *mentries; char desc[512]; } *

user_defined_types: struct magichandle_t { unsigned int flags; unsigned long numentries; unsigned long num_l0_ents; unsigned long *l0_ents; struct magicentry_t *mentries; char desc[512]; }

user_defined_types: struct magicentry_t { unsigned int level; unsigned char hits; unsigned int offset; enum type_t type; enum comp_t comp; struct { enum endian_t endian; unsigned int value; unsigned int mask; } num; struct { unsigned char *value; unsigned long length; } str; char *msg; unsigned int indirect; struct { enum endian_t endian; enum type_t type; int delta; } indir; unsigned int relative; }


decompiled_code:
__int64 __fastcall init_genrand(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rdx
__int64 result; // rax

v2 = a2;
result = 1LL;
*(_QWORD *)a1 = a2;
while ( 1 )
{
v2 = 1812433253 * ((unsigned int)v2 ^ (unsigned int)(v2 >> 30)) + (unsigned int)result;
*(_QWORD *)(a1 + 8 * result) = v2;
if ( result == 623 )
break;
++result;
}
*(_DWORD *)(a1 + 4992) = 624;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rdx
__int64 result; // rax

v2 = a2;
result = 1LL;
*(_QWORD *)a1 = a2;
while ( 1 )
{
v2 = 1812433253 * ((unsigned int)v2 ^ (unsigned int)(v2 >> 30)) + (unsigned int)result;
*(_QWORD *)(a1 + 8 * result) = v2;
if ( result == 623 )
break;
++result;
}
*(_DWORD *)(a1 + 4992) = 624;
return result;
}

original_code:
void init_genrand(ellipsis_mt19937_rng* rng,unsigned long s)
{
    rng->mti=624 +1;
    rng->mt[0]= s & 0xffffffffUL;
    for (rng->mti=1; rng->mti<624; rng->mti++) {
        rng->mt[rng->mti] =
     (1812433253UL * (rng->mt[rng->mti-1] ^ (rng->mt[rng->mti-1] >> 30)) + rng->mti);
        rng->mt[rng->mti] &= 0xffffffffUL;
    }
}

canonical_original_code:
void init_genrand(struct ellipsis_mt19937_rng *rng, unsigned long s)
{
    rng->mti=624 +1;
    rng->mt[0]= s & 0xffffffffUL;
    for (rng->mti=1; rng->mti<624; rng->mti++) {
        rng->mt[rng->mti] =
     (1812433253UL * (rng->mt[rng->mti-1] ^ (rng->mt[rng->mti-1] >> 30)) + rng->mti);
        rng->mt[rng->mti] &= 0xffffffffUL;
    }
}

variable_types: struct ellipsis_mt19937_rng { unsigned long mt[624]; int mti; } *

variable_types:
s
unsigned long


variable_types: i int

variable_types: j int

variable_types: k int

user_defined_types: struct ellipsis_mt19937_rng { unsigned long mt[624]; int mti; }


variable_types:
y
unsigned long

variable_types: kk int

return_type: unsigned long


decompiled_code:
unsigned __int64 __fastcall genrand_int31(__int64 a1)
{
return genrand_int32(a1) >> 1;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func3(__int64 a1)
{
return func2(a1) >> 1;
}

original_code:
long genrand_int31(ellipsis_mt19937_rng* rng)
{
    return (long)(genrand_int32(rng)>>1);
}

canonical_original_code:
long genrand_int31(struct ellipsis_mt19937_rng *rng)
{
    return (long)(genrand_int32(rng)>>1);
}

return_type: long


original_code:
double genrand_real1(ellipsis_mt19937_rng* rng)
{
    return genrand_int32(rng)*(1.0/4294967295.0);
}

canonical_original_code:
double genrand_real1(struct ellipsis_mt19937_rng *rng)
{
    return genrand_int32(rng)*(1.0/4294967295.0);
}

return_type: double


original_code:
double genrand_real2(ellipsis_mt19937_rng* rng)
{
    return genrand_int32(rng)*(1.0/4294967296.0);
}

canonical_original_code:
double genrand_real2(struct ellipsis_mt19937_rng *rng)
{
    return genrand_int32(rng)*(1.0/4294967296.0);
}


original_code:
double genrand_real3(ellipsis_mt19937_rng* rng)
{
    return (((double)genrand_int32(rng)) + 0.5)*(1.0/4294967296.0);
}

canonical_original_code:
double genrand_real3(struct ellipsis_mt19937_rng *rng)
{
    return (((double)genrand_int32(rng)) + 0.5)*(1.0/4294967296.0);
}


decompiled_code:
double __fastcall genrand_res53(__int64 a1)
{
unsigned __int64 v1; // rax
unsigned __int64 v2; // r9

genrand_int32(a1);
v1 = genrand_int32(a1);
return ((double)(int)(v2 >> 5) * 67108864.0 + (double)(int)(v1 >> 6)) * 1.110223024625157e-16;
}

original_code:
double genrand_res53(ellipsis_mt19937_rng* rng)
{
    unsigned long a=genrand_int32(rng)>>5, b=genrand_int32(rng)>>6;
    return(a*67108864.0+b)*(1.0/9007199254740992.0);
}

canonical_original_code:
double genrand_res53(struct ellipsis_mt19937_rng *rng)
{
    unsigned long a = genrand_int32(rng)>>5; unsigned long b = genrand_int32(rng)>>6;
    return(a*67108864.0+b)*(1.0/9007199254740992.0);
}

variable_types:
a
unsigned long

variable_types:
b
unsigned long


decompiled_code:
// attributes: thunk
double __fastcall genrand_uniform(__int64 a1)
{
return genrand_real1(a1);
}

canonical_decompiled_code:
double __fastcall func8(__int64 a1)
{
return func4(a1);
}

original_code:
double genrand_uniform(ellipsis_mt19937_rng* rng)
{
 return genrand_int32(rng)*(1.0/4294967295.0);
}

canonical_original_code:
double genrand_uniform(struct ellipsis_mt19937_rng *rng)
{
 return genrand_int32(rng)*(1.0/4294967295.0);
}


decompiled_code:
double __fastcall gerand_gauss(__int64 a1)
{
double v1; // xmm0_8
double v2; // xmm1_8
double v3; // xmm0_8
double v4; // xmm1_8
double v5; // xmm2_8
double v6; // xmm4_8
double v7; // xmm0_8
double v8; // xmm0_8

do
{
do
{
v1 = genrand_real1(a1);
v2 = v1 + v1;
v3 = genrand_real1(a1);
v4 = v2 - 1.0;
v5 = v4 * v4 + (v3 + v3 - 1.0) * (v3 + v3 - 1.0);
}
while ( v5 == v6 );
}
while ( v5 > 1.0 );
v7 = log(v5) * -2.0 / v5;
if ( v7 < 0.0 )
v8 = sqrt(v7);
else
v8 = sqrt(v7);
return v8 * v4;
}

original_code:
double gerand_gauss(ellipsis_mt19937_rng* rng)
{
 double u,v,r,c;
 u=2.*genrand_real1(rng)-1.;
 v=2.*genrand_real1(rng)-1.;
 r=u*u+v*v;
 if (r==0||r>1)
 {
  return gerand_gauss(rng);
 }
 c=sqrt(-2.*log(r)/r);
 return u*c;
}

canonical_original_code:
double gerand_gauss(struct ellipsis_mt19937_rng *rng)
{
 double u; double v; double r; double c;
 u=2.*genrand_real1(rng)-1.;
 v=2.*genrand_real1(rng)-1.;
 r=u*u+v*v;
 if (r==0||r>1)
 {
  return gerand_gauss(rng);
 }
 c=sqrt(-2.*log(r)/r);
 return u*c;
}

variable_types: u double

variable_types: v double

variable_types: r double

variable_types: c double