decompiled_code:
__int64 __fastcall ascii_key_handler(unsigned __int8 a1)
{
__int32_t v1; // edx

v1 = (*_ctype_tolower_loc())[a1];
if ( (_BYTE)v1 == 63 )
{
fwrite("Game Commands:\n", 1uLL, 0xFuLL, stderr);
fprintf(stderr, "[%c]:\tSee this help\n", 63LL);
fprintf(stderr, "[%c]:\tSee debug print\n", 46LL);
fprintf(stderr, "[%c]:\tPause or unpause the game\n", 32LL);
fwrite("[ESC]:\tExit the game\n", 1uLL, 0x15uLL, stderr);
fprintf(stderr, "[%c]:\tFIRE!\t(left player)\n", 119LL);
fprintf(stderr, "[%c]:\tturn left\t(left player)\n", 97LL);
fprintf(stderr, "[%c]:\tturn right\t(left player)\n", 100LL);
fwrite("(up arrow):\tFIRE!\t(right player)\n", 1uLL, 0x21uLL, stderr);
fwrite("(left arrow):\tturn left\t(right player)\n", 1uLL, 0x27uLL, stderr);
return fwrite("(right arrow):\tturn right\t(right player)\n", 1uLL, 0x29uLL, stderr);
}
if ( (v1 & 0xC0) != 0 )
{
switch ( (unsigned __int8)v1 )
{
case 'd':
return change_player_direction(2LL, 1LL);
case 'w':
return fire_player_weapon(2LL);
case 'a':
return change_player_direction(2LL, 0LL);
}
return fwrite("unknown keyboard command\n", 1uLL, 0x19uLL, stderr);
}
if ( (unsigned __int8)v1 != 32 )
{
if ( (unsigned __int8)v1 == 46 )
return fwrite("Debug output:\n", 1uLL, 0xEuLL, stderr);
if ( (unsigned __int8)v1 == 27 )
exit(0);
return fwrite("unknown keyboard command\n", 1uLL, 0x19uLL, stderr);
}
if ( (unsigned int)is_running() )
return pause_game();
if ( (unsigned int)is_paused() )
return resume_game();
return new_game();
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int8 a1)
{
__int32_t v1; // edx

v1 = (*_ctype_tolower_loc())[a1];
if ( (_BYTE)v1 == 63 )
{
fwrite("Game Commands:\n", 1uLL, 0xFuLL, stderr);
fprintf(stderr, "[%c]:\tSee this help\n", 63LL);
fprintf(stderr, "[%c]:\tSee debug print\n", 46LL);
fprintf(stderr, "[%c]:\tPause or unpause the game\n", 32LL);
fwrite("[ESC]:\tExit the game\n", 1uLL, 0x15uLL, stderr);
fprintf(stderr, "[%c]:\tFIRE!\t(left player)\n", 119LL);
fprintf(stderr, "[%c]:\tturn left\t(left player)\n", 97LL);
fprintf(stderr, "[%c]:\tturn right\t(left player)\n", 100LL);
fwrite("(up arrow):\tFIRE!\t(right player)\n", 1uLL, 0x21uLL, stderr);
fwrite("(left arrow):\tturn left\t(right player)\n", 1uLL, 0x27uLL, stderr);
return fwrite("(right arrow):\tturn right\t(right player)\n", 1uLL, 0x29uLL, stderr);
}
if ( (v1 & 0xC0) != 0 )
{
switch ( (unsigned __int8)v1 )
{
case 'd':
return change_player_direction(2LL, 1LL);
case 'w':
return fire_player_weapon(2LL);
case 'a':
return change_player_direction(2LL, 0LL);
}
return fwrite("unknown keyboard command\n", 1uLL, 0x19uLL, stderr);
}
if ( (unsigned __int8)v1 != 32 )
{
if ( (unsigned __int8)v1 == 46 )
return fwrite("Debug output:\n", 1uLL, 0xEuLL, stderr);
if ( (unsigned __int8)v1 == 27 )
exit(0);
return fwrite("unknown keyboard command\n", 1uLL, 0x19uLL, stderr);
}
if ( (unsigned int)is_running() )
return pause_game();
if ( (unsigned int)is_paused() )
return resume_game();
return new_game();
}

original_code:
void ascii_key_handler(unsigned char key, int x, int y)
{
    unsigned char keytest = tolower(key);
    switch(keytest){
        case 'a':
            change_player_direction(2, TURN_LEFT);
            break;
        case 'd':
            change_player_direction(2, TURN_RIGHT);
            break;
        case 'w':
            fire_player_weapon(2);
            break;
        case ' ':
            if( is_running() )
                pause_game();
            else if( is_paused() )
                resume_game();
            else
                new_game();
            break;
        case '.':
            fprintf(stderr, "Debug output:\n");
            break;
        case '?':
            fprintf(stderr, "Game Commands:\n");
            fprintf(stderr, "[%c]:\tSee this help\n", '?');
            fprintf(stderr, "[%c]:\tSee debug print\n", '.');
            fprintf(stderr, "[%c]:\tPause or unpause the game\n", ' ');
            if(27 == 27)
                fprintf(stderr, "[ESC]:\tExit the game\n");
            else
                fprintf(stderr, "[%c]:\tExit the game\n", 27);
            fprintf(stderr, "[%c]:\tFIRE!\t(left player)\n", 'w');
            fprintf(stderr, "[%c]:\tturn left\t(left player)\n", 'a');
            fprintf(stderr, "[%c]:\tturn right\t(left player)\n", 'd');
            fprintf(stderr, "(up arrow):\tFIRE!\t(right player)\n");
            fprintf(stderr, "(left arrow):\tturn left\t(right player)\n");
            fprintf(stderr, "(right arrow):\tturn right\t(right player)\n");
            break;
        case 27:
            exit(0);
            break;
        default:
            fprintf(stderr, "unknown keyboard command\n");
            break;
    }
}

variable_types:
key
unsigned char

variable_types: x int

variable_types:
keytest
unsigned char


decompiled_code:
__int64 __fastcall input_init(__int64 a1)
{
Window_registerKeyEventHandler(a1, ascii_key_handler);
return Window_registerSpecialKeyEventHandler((unsigned int)a1, special_key_handler);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
Window_registerKeyEventHandler(a1, ascii_key_handler);
return Window_registerSpecialKeyEventHandler((unsigned int)a1, special_key_handler);
}

original_code:
void input_init( int window_id )
{
    Window_registerKeyEventHandler( window_id, ascii_key_handler );
    Window_registerSpecialKeyEventHandler( window_id, special_key_handler );
}

canonical_original_code:
void input_init(int window_id)
{
    Window_registerKeyEventHandler( window_id, ascii_key_handler );
    Window_registerSpecialKeyEventHandler( window_id, special_key_handler );
}

return_type: void


decompiled_code:
int __fastcall queue_init(__int64 a1)
{
int result; // eax

if ( a1 )
{
*(_QWORD *)(a1 + 8) = 0LL;
*(_QWORD *)a1 = 0LL;
pthread_mutex_init((pthread_mutex_t *)(a1 + 16), 0LL);
result = pthread_cond_init((pthread_cond_t *)(a1 + 56), 0LL);
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
int result; // eax

if ( a1 )
{
*(_QWORD *)(a1 + 8) = 0LL;
*(_QWORD *)a1 = 0LL;
pthread_mutex_init((pthread_mutex_t *)(a1 + 16), 0LL);
result = pthread_cond_init((pthread_cond_t *)(a1 + 56), 0LL);
}
return result;
}

original_code:
void queue_init(client_queue_t *q) {
  if (q != ((void *)0)) {
    q->start = q->end = ((void *)0);
    pthread_mutex_init(&q->queue_mx, ((void *)0));
    pthread_cond_init(&q->queue_cond, ((void *)0));
  }
}

canonical_original_code:
void queue_init(struct __client_queue_s *q) {
  if (q != ((void *)0)) {
    q->start = q->end = ((void *)0);
    pthread_mutex_init(&q->queue_mx, ((void *)0));
    pthread_cond_init(&q->queue_cond, ((void *)0));
  }
}

variable_types: struct __client_queue_s { struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s queue; struct __client_item_s *next; } *sender; struct __queue_item_s *next; } *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } *

user_defined_types: struct __client_queue_s { struct __queue_item_s *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t queue_cond; }

user_defined_types: union pthread_cond_t { struct __pthread_cond_s __data; char __size[48]; long long __align; }

user_defined_types: struct __queue_item_s { struct __message_s *msg; struct __client_item_s *sender; struct __queue_item_s *next; }

user_defined_types: struct __client_item_s { char *name; int socket; union pthread_mutex_t sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s queue; struct __client_item_s *next; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


decompiled_code:
_BOOL8 __fastcall queue_empty(_QWORD *a1)
{
return *a1 == 0LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(_QWORD *a1)
{
return *a1 == 0LL;
}

original_code:
int queue_empty(client_queue_t *queue) {
  return (queue->start == ((void *)0)) ? 1 : 0;
}

canonical_original_code:
int queue_empty(struct __client_queue_s *queue) {
  return (queue->start == ((void *)0)) ? 1 : 0;
}

return_type: int

user_defined_types: struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }

user_defined_types: struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; }

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


decompiled_code:
int __fastcall queue_push(__int64 a1, __int64 a2, __int64 a3)
{
pthread_mutex_t *v4; // r14
_QWORD *v5; // rax
_QWORD *v6; // rbp
int result; // eax

v4 = (pthread_mutex_t *)(a1 + 16);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 16));
v5 = calloc(1uLL, 0x18uLL);
if ( v5 )
{
v6 = v5;
*v5 = a2;
v5[1] = a3;
if ( queue_empty((_QWORD *)a1) )
{
v6[2] = 0LL;
*(_QWORD *)(a1 + 8) = v6;
*(_QWORD *)a1 = v6;
}
else
{
v6[2] = 0LL;
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 16LL) = v6;
}
pthread_cond_signal((pthread_cond_t *)(a1 + 56));
result = pthread_mutex_unlock(v4);
}
else
{
print_error("memory allocation error");
result = pthread_mutex_unlock(v4);
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1, __int64 a2, __int64 a3)
{
pthread_mutex_t *v4; // r14
_QWORD *v5; // rax
_QWORD *v6; // rbp
int result; // eax

v4 = (pthread_mutex_t *)(a1 + 16);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 16));
v5 = calloc(1uLL, 0x18uLL);
if ( v5 )
{
v6 = v5;
*v5 = a2;
v5[1] = a3;
if ( func1((_QWORD *)a1) )
{
v6[2] = 0LL;
*(_QWORD *)(a1 + 8) = v6;
*(_QWORD *)a1 = v6;
}
else
{
v6[2] = 0LL;
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 16LL) = v6;
}
pthread_cond_signal((pthread_cond_t *)(a1 + 56));
result = pthread_mutex_unlock(v4);
}
else
{
print_error("memory allocation error");
result = pthread_mutex_unlock(v4);
}
return result;
}

original_code:
void queue_push(client_queue_t *queue, message_t *msg, client_item_t *sender) {
  pthread_mutex_lock(&queue->queue_mx);
  queue_item_t *item = (queue_item_t *) calloc(1, sizeof(queue_item_t));
  if (item == ((void *)0)) {
    print_error("memory allocation error");
    pthread_mutex_unlock(&queue->queue_mx);
    return;
  }
  item->msg = msg;
  item->sender = sender;
  if (queue_empty(queue)) {
    item->next = ((void *)0);
    queue->start = queue->end = item;
  } else {
    item->next = ((void *)0);
    queue->end->next = item;
  }
  pthread_cond_signal(&queue->queue_cond);
  pthread_mutex_unlock(&queue->queue_mx);
}

canonical_original_code:
void queue_push(struct __client_queue_s *queue, struct __message_s *msg, struct __client_item_s *sender) {
  pthread_mutex_lock(&queue->queue_mx);
  struct __queue_item_s *item = (queue_item_t *) calloc(1, sizeof(queue_item_t));
  if (item == ((void *)0)) {
    print_error("memory allocation error");
    pthread_mutex_unlock(&queue->queue_mx);
    return;
  }
  item->msg = msg;
  item->sender = sender;
  if (queue_empty(queue)) {
    item->next = ((void *)0);
    queue->start = queue->end = item;
  } else {
    item->next = ((void *)0);
    queue->end->next = item;
  }
  pthread_cond_signal(&queue->queue_cond);
  pthread_mutex_unlock(&queue->queue_mx);
}

variable_types:
msg
struct __message_s *

variable_types:
sender
struct __client_item_s *

variable_types: struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *sender; struct __queue_item_s *next; } *


decompiled_code:
__int64 __fastcall queue_pop(__int64 *a1)
{
pthread_mutex_t *v1; // rbp
__int64 v2; // r12

v1 = (pthread_mutex_t *)(a1 + 2);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 2));
while ( queue_empty(a1) )
pthread_cond_wait((pthread_cond_t *)(a1 + 7), v1);
v2 = *a1;
*a1 = *(_QWORD *)(*a1 + 16);
pthread_mutex_unlock(v1);
return v2;
}

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

v1 = (pthread_mutex_t *)(a1 + 2);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 2));
while ( func1(a1) )
pthread_cond_wait((pthread_cond_t *)(a1 + 7), v1);
v2 = *a1;
*a1 = *(_QWORD *)(*a1 + 16);
pthread_mutex_unlock(v1);
return v2;
}

original_code:
queue_item_t* queue_pop(client_queue_t *queue) {
  pthread_mutex_lock(&queue->queue_mx);
  while (queue_empty(queue)) {
    pthread_cond_wait(&queue->queue_cond, &queue->queue_mx);
  }
  queue_item_t *item = queue->start;
  queue->start = item->next;
  pthread_mutex_unlock(&queue->queue_mx);
  return item;
}

canonical_original_code:
struct __queue_item_s *queue_pop(struct __client_queue_s *queue) {
  pthread_mutex_lock(&queue->queue_mx);
  while (queue_empty(queue)) {
    pthread_cond_wait(&queue->queue_cond, &queue->queue_mx);
  }
  struct __queue_item_s *item = queue->start;
  queue->start = item->next;
  pthread_mutex_unlock(&queue->queue_mx);
  return item;
}

variable_types:
queue
struct __client_queue_s *

return_type: struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *sender; struct __queue_item_s *next; } *


decompiled_code:
void __fastcall free_queue_item(void *ptr)
{
if ( ptr )
{
free_message(*(_QWORD *)ptr);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func4(void *ptr)
{
if ( ptr )
{
free_message(*(_QWORD *)ptr);
free(ptr);
}
}

original_code:
void free_queue_item(queue_item_t *item) {
  if (item != ((void *)0)) {
    free_message(item->msg);
    free(item);
  }
}

canonical_original_code:
void free_queue_item(struct __queue_item_s *item) {
  if (item != ((void *)0)) {
    free_message(item->msg);
    free(item);
  }
}


decompiled_code:
void __fastcall free_queue(_QWORD *a1)
{
_QWORD *v1; // rbx
void *v2; // rdi

if ( a1 )
{
v1 = (_QWORD *)*a1;
if ( *a1 )
{
do
{
v2 = v1;
v1 = (_QWORD *)v1[2];
free_queue_item(v2);
}
while ( v1 );
}
}
}

canonical_decompiled_code:
void __fastcall func5(_QWORD *a1)
{
_QWORD *v1; // rbx
void *v2; // rdi

if ( a1 )
{
v1 = (_QWORD *)*a1;
if ( *a1 )
{
do
{
v2 = v1;
v1 = (_QWORD *)v1[2];
func4(v2);
}
while ( v1 );
}
}
}

original_code:
void free_queue(client_queue_t *q) {
  if (q != ((void *)0)) {
    queue_item_t *p, *tmp;
    for (p = q->start; p != ((void *)0);) {
      tmp = p;
      p = p->next;
      free_queue_item(tmp);
    }
  }
}

canonical_original_code:
void free_queue(struct __client_queue_s *q) {
  if (q != ((void *)0)) {
    struct __queue_item_s *p; struct __queue_item_s *tmp;
    for (p = q->start; p != ((void *)0);) {
      tmp = p;
      p = p->next;
      free_queue_item(tmp);
    }
  }
}


decompiled_code:
__int64 __fastcall mesg_recv2(int fd, void *ptr, int a3)
{
ssize_t v3; // rdx
__int64 result; // rax
unsigned __int16 v5; // r14
_BYTE *v6; // r13
unsigned __int64 v7; // rbx
ssize_t v8; // rax
_DWORD *v9; // rbx
size_t v10; // r12
_BYTE *v11; // rax
_BYTE *v12; // rbp
__int16 buf[29]; // [rsp+1Eh] [rbp-3Ah] BYREF

*(_QWORD *)ptr = 0LL;
v3 = recv(fd, buf, 2uLL, 0);
result = 0LL;
if ( v3 )
{
v5 = _bswap_16(buf[0]);
v6 = calloc(v5, 1uLL);
if ( !v6 )
{
print_error("memory allocation failed");
return 0xFFFFFFFFLL;
}
v7 = 0LL;
if ( v5 )
{
do
{
v8 = recv(fd, &v6[v7], v5 - v7, 0);
if ( !v8 )
{
free(v6);
return 0LL;
}
v7 += v8;
}
while ( v5 > v7 );
v9 = calloc(1uLL, 0x18uLL);
if ( !v9 )
goto LABEL_14;
*(_BYTE *)v9 = *v6;
v9[1] = _bswap_32(*(_DWORD *)(v6 + 1));
v10 = v5 - 5LL;
*((_QWORD *)v9 + 2) = v10;
if ( v5 == 5LL )
{
*((_QWORD *)v9 + 1) = 0LL;
goto LABEL_9;
}
}
else
{
v9 = calloc(1uLL, 0x18uLL);
if ( !v9 )
{
LABEL_14:
free(v6);
print_error("memory allocation failed");
return 0xFFFFFFFFLL;
}
*(_BYTE *)v9 = *v6;
v9[1] = _bswap_32(*(_DWORD *)(v6 + 1));
*((_QWORD *)v9 + 2) = -5LL;
v10 = -5LL;
}
v11 = malloc(v5 - 4LL);
v12 = v11;
*((_QWORD *)v9 + 1) = v11;
if ( v11 )
{
memcpy(v11, v6 + 5, v10);
v12[v10] = 0;
LABEL_9:
*(_QWORD *)ptr = v9;
free(v6);
if ( a3 )
print_message(v9);
result = v5;
}
else
{
free(ptr);
free(v9);
print_error("memory allocation failed");
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int fd, void *ptr, int a3)
{
ssize_t v3; // rdx
__int64 result; // rax
unsigned __int16 v5; // r14
_BYTE *v6; // r13
unsigned __int64 v7; // rbx
ssize_t v8; // rax
_DWORD *v9; // rbx
size_t v10; // r12
_BYTE *v11; // rax
_BYTE *v12; // rbp
__int16 buf[29]; // [rsp+1Eh] [rbp-3Ah] BYREF

*(_QWORD *)ptr = 0LL;
v3 = recv(fd, buf, 2uLL, 0);
result = 0LL;
if ( v3 )
{
v5 = func0(buf[0]);
v6 = calloc(v5, 1uLL);
if ( !v6 )
{
print_error("memory allocation failed");
return 0xFFFFFFFFLL;
}
v7 = 0LL;
if ( v5 )
{
do
{
v8 = recv(fd, &v6[v7], v5 - v7, 0);
if ( !v8 )
{
free(v6);
return 0LL;
}
v7 += v8;
}
while ( v5 > v7 );
v9 = calloc(1uLL, 0x18uLL);
if ( !v9 )
goto LABEL_14;
*(_BYTE *)v9 = *v6;
v9[1] = func1(*(_DWORD *)(v6 + 1));
v10 = v5 - 5LL;
*((_QWORD *)v9 + 2) = v10;
if ( v5 == 5LL )
{
*((_QWORD *)v9 + 1) = 0LL;
goto LABEL_9;
}
}
else
{
v9 = calloc(1uLL, 0x18uLL);
if ( !v9 )
{
LABEL_14:
free(v6);
print_error("memory allocation failed");
return 0xFFFFFFFFLL;
}
*(_BYTE *)v9 = *v6;
v9[1] = func1(*(_DWORD *)(v6 + 1));
*((_QWORD *)v9 + 2) = -5LL;
v10 = -5LL;
}
v11 = malloc(v5 - 4LL);
v12 = v11;
*((_QWORD *)v9 + 1) = v11;
if ( v11 )
{
memcpy(v11, v6 + 5, v10);
v12[v10] = 0;
LABEL_9:
*(_QWORD *)ptr = v9;
free(v6);
if ( a3 )
print_message(v9);
result = v5;
}
else
{
free(ptr);
free(v9);
print_error("memory allocation failed");
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
int mesg_recv2(int socket, message_t **msg, int print_msg) {
  size_t len, received;
  char buf[2];
  char *msg_buf = ((void *)0);
  *msg = ((void *)0);
  if ((len = recv(socket, (void *)buf, 2, 0)) <= 0) {
    return len;
  }
  received = 0;
  size_t msg_size;
  msg_size = ntohs(*((uint_16 *)buf));
  msg_buf = (char *) calloc(msg_size, sizeof(char));
  if (msg_buf == ((void *)0)) {
    print_error("memory allocation failed");
    return -1;
  }
  while (received < msg_size) {
    if ((len = recv(socket, (void *)&msg_buf[received], msg_size-received, 0)) <= 0) {
      free(msg_buf);
      return len;
    }
    received += len;
  }
  message_t *mesg_s;
  if ((mesg_s = (message_t *) calloc(1, sizeof(message_t))) == ((void *)0)) {
    free(msg_buf);
    print_error("memory allocation failed");
    return -1;
  }
  mesg_s->type = *((uint_8 *) msg_buf);
  mesg_s->id = ntohl(*((uint_32 *) &msg_buf[1]));
  mesg_s->text_len = msg_size - 5;
  if (mesg_s->text_len > 0) {
    if ((mesg_s->text = (char *) malloc((mesg_s->text_len + 1) * sizeof(char))) == ((void *)0)) {
      free(msg);
      free(mesg_s);
      print_error("memory allocation failed");
      return -1;
    }
    memcpy(mesg_s->text, &msg_buf[5], mesg_s->text_len);
    mesg_s->text[mesg_s->text_len] = (char)0;
  } else {
    mesg_s->text = ((void *)0);
  }
  *msg = mesg_s;
  free(msg_buf); msg_buf = ((void *)0);
  if (print_msg) {
    print_message(mesg_s);
  }
  return msg_size;
}

canonical_original_code:
int mesg_recv2(int socket, struct __message_s **msg, int print_msg) {
  unsigned long len; unsigned long received;
  char buf[2];
  char *msg_buf = ((void *)0);
  *msg = ((void *)0);
  if ((len = recv(socket, (void *)buf, 2, 0)) <= 0) {
    return len;
  }
  received = 0;
  unsigned long msg_size;
  msg_size = ntohs(*((unsigned short *)buf));
  msg_buf = (char *) calloc(msg_size, sizeof(char));
  if (msg_buf == ((void *)0)) {
    print_error("memory allocation failed");
    return -1;
  }
  while (received < msg_size) {
    if ((len = recv(socket, (void *)&msg_buf[received], msg_size-received, 0)) <= 0) {
      free(msg_buf);
      return len;
    }
    received += len;
  }
  struct __message_s *mesg_s;
  if ((mesg_s = (struct __message_s *) calloc(1, sizeof(message_t))) == ((void *)0)) {
    free(msg_buf);
    print_error("memory allocation failed");
    return -1;
  }
  mesg_s->type = *((unsigned char *) msg_buf);
  mesg_s->id = ntohl(*((unsigned int *) &msg_buf[1]));
  mesg_s->text_len = msg_size - 5;
  if (mesg_s->text_len > 0) {
    if ((mesg_s->text = (char *) malloc((mesg_s->text_len + 1) * sizeof(char))) == ((void *)0)) {
      free(msg);
      free(mesg_s);
      print_error("memory allocation failed");
      return -1;
    }
    memcpy(mesg_s->text, &msg_buf[5], mesg_s->text_len);
    mesg_s->text[mesg_s->text_len] = (char)0;
  } else {
    mesg_s->text = ((void *)0);
  }
  *msg = mesg_s;
  free(msg_buf); msg_buf = ((void *)0);
  if (print_msg) {
    print_message(mesg_s);
  }
  return msg_size;
}

variable_types: socket int

variable_types: struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } **

variable_types:
len
unsigned long

variable_types:
received
unsigned long

variable_types:
buf
char [2]


decompiled_code:
__int64 __fastcall mesg_recv(int a1, void *a2)
{
return mesg_recv2(a1, a2, 1);
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1, void *a2)
{
return func2(a1, a2, 1);
}

original_code:
int mesg_recv(int socket, message_t **msg) {
 return mesg_recv2(socket, msg, 1);
}

canonical_original_code:
int mesg_recv(int socket, struct __message_s **msg) {
 return mesg_recv2(socket, msg, 1);
}


decompiled_code:
__int64 __fastcall mesg_send(int fd, int a2, unsigned int a3, const char *a4, int a5)
{
size_t v7; // r15
int v8; // edi
unsigned __int64 v9; // rbx
void *v10; // rsp
int v11; // eax
int v12; // er14
unsigned int v13; // eax
unsigned int v14; // edx
int v16; // eax
__int16 v17; // [rsp+0h] [rbp-40h] BYREF
char v18; // [rsp+2h] [rbp-3Eh]
__int16 v19; // [rsp+3h] [rbp-3Dh]
char v20; // [rsp+5h] [rbp-3Bh]
char v21; // [rsp+6h] [rbp-3Ah]
char dest; // [rsp+7h] [rbp-39h] BYREF
unsigned int v23; // [rsp+8h] [rbp-38h]
int v24; // [rsp+Ch] [rbp-34h]

v24 = a2;
v23 = a3;
if ( a5 <= 0 || (v16 = random(), v14 = 1, (double)v16 / 2147483647.0 >= 0.5) )
{
v7 = strlen(a4);
v8 = (unsigned __int16)(v7 + 5);
v9 = v8 + 2;
v10 = alloca((v8 + 19) & 0x3FFF0);
v17 = _bswap_16(v8);
v18 = v24;
v11 = _bswap_32(v23);
v19 = v11;
v20 = (unsigned int)(v11 << 8) >> 24;
v21 = HIBYTE(v11);
memcpy(&dest, a4, v7);
v12 = 0;
while ( 1 )
{
v13 = send(fd, (char *)&v17 + v12, v9 - v12, 0x4000);
v14 = v13;
if ( v13 == -1 )
break;
v12 += v13;
if ( v12 >= v9 )
return 1;
}
}
return v14;
}

canonical_decompiled_code:
__int64 __fastcall func4(int fd, int a2, unsigned int a3, const char *a4, int a5)
{
size_t v7; // r15
int v8; // edi
unsigned __int64 v9; // rbx
void *v10; // rsp
int v11; // eax
int v12; // er14
unsigned int v13; // eax
unsigned int v14; // edx
int v16; // eax
__int16 v17; // [rsp+0h] [rbp-40h] BYREF
char v18; // [rsp+2h] [rbp-3Eh]
__int16 v19; // [rsp+3h] [rbp-3Dh]
char v20; // [rsp+5h] [rbp-3Bh]
char v21; // [rsp+6h] [rbp-3Ah]
char dest; // [rsp+7h] [rbp-39h] BYREF
unsigned int v23; // [rsp+8h] [rbp-38h]
int v24; // [rsp+Ch] [rbp-34h]

v24 = a2;
v23 = a3;
if ( a5 <= 0 || (v16 = random(), v14 = 1, (double)v16 / 2147483647.0 >= 0.5) )
{
v7 = strlen(a4);
v8 = (unsigned __int16)(v7 + 5);
v9 = v8 + 2;
v10 = alloca((v8 + 19) & 0x3FFF0);
v17 = func0(v8);
v18 = v24;
v11 = func1(v23);
v19 = v11;
v20 = (unsigned int)(v11 << 8) >> 24;
v21 = HIBYTE(v11);
memcpy(&dest, a4, v7);
v12 = 0;
while ( 1 )
{
v13 = send(fd, (char *)&v17 + v12, v9 - v12, 0x4000);
v14 = v13;
if ( v13 == -1 )
break;
v12 += v13;
if ( v12 >= v9 )
return 1;
}
}
return v14;
}

original_code:
int mesg_send(int socket, uint_8 type,
    uint_32 id, const char *msg, int can_fail) {
  if (can_fail > 0 && (double)random()/2147483647 < 0.5) {
    return 1;
  }
  size_t m_len = strlen(msg);
  uint_16 msg_size = 5 +m_len;
  size_t actual_length = msg_size+2;
  char buffer[actual_length+2];
  uint_16 msg_size_net = htons(msg_size);
  char *c = (char *)&msg_size_net;
  buffer[0] = *c; buffer[1] = *(c+1);
  buffer[2] = (char)type;
  uint_32 msg_id_net = htonl(id);
  c = (char *)&msg_id_net;
  int i;
  for (i = 0; i < 4; i++) {
    buffer[3+i] = *(c+i);
  }
  memcpy(&buffer[2+5], msg, m_len);
  int len, sent = 0;
  do {
    if ((len = send(socket, (void *)&buffer[sent], actual_length - sent, MSG_NOSIGNAL)) == -1) {
      return -1;
    }
    sent += len;
  } while(sent < actual_length);
  return 1;
}

canonical_original_code:
int mesg_send(int socket, unsigned char type, unsigned int id, char *msg, int can_fail) {
  if (can_fail > 0 && (double)random()/2147483647 < 0.5) {
    return 1;
  }
  unsigned long m_len = strlen(msg);
  unsigned short msg_size = 5 +m_len;
  unsigned long actual_length = msg_size+2;
  char buffer[-1];
  unsigned short msg_size_net = htons(msg_size);
  char *c = (char *)&msg_size_net;
  buffer[0] = *c; buffer[1] = *(c+1);
  buffer[2] = (char)type;
  unsigned int msg_id_net = htonl(id);
  c = (char *)&msg_id_net;
  int i;
  for (i = 0; i < 4; i++) {
    buffer[3+i] = *(c+i);
  }
  memcpy(&buffer[2+5], msg, m_len);
  int len; int sent = 0;
  do {
    if ((len = send(socket, (void *)&buffer[sent], actual_length - sent, MSG_NOSIGNAL)) == -1) {
      return -1;
    }
    sent += len;
  } while(sent < actual_length);
  return 1;
}

variable_types:
type
unsigned char

variable_types:
id
unsigned int

variable_types:
msg
char *

variable_types:
buffer
char [-1]

variable_types:
c
char *

variable_types: i int

variable_types: len int

variable_types: sent int


decompiled_code:
void __fastcall client_free(void *ptr)
{
if ( ptr )
{
printf("Freeing client: ");
if ( *(_QWORD *)ptr )
{
printf("%s", *(const char **)ptr);
free(*(void **)ptr);
}
putchar(10);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func0(void *ptr)
{
if ( ptr )
{
printf("Freeing client: ");
if ( *(_QWORD *)ptr )
{
printf("%s", *(const char **)ptr);
free(*(void **)ptr);
}
putchar(10);
free(ptr);
}
}

original_code:
void client_free(client_item_t *cl) {
  if (cl != ((void *)0)) {
    printf("Freeing client: ");
    if (cl->name != ((void *)0)) {
      printf("%s", cl->name);
      free(cl->name);
    }
    printf("\n");
    free(cl);
  }
}

canonical_original_code:
void client_free(struct __client_item_s *cl) {
  if (cl != ((void *)0)) {
    printf("Freeing client: ");
    if (cl->name != ((void *)0)) {
      printf("%s", cl->name);
      free(cl->name);
    }
    printf("\n");
    free(cl);
  }
}

variable_types: struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s *sender; struct __queue_item_s *next; } *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *


decompiled_code:
char *__fastcall client_add(_QWORD *a1, int a2, _QWORD *a3)
{
char *v4; // rax
char *v5; // rbx
__int64 v6; // rax

v4 = (char *)calloc(1uLL, 0xE0uLL);
v5 = v4;
if ( v4 )
{
*((_DWORD *)v4 + 2) = a2;
*((_QWORD *)v4 + 12) = *a3;
pthread_mutex_init((pthread_mutex_t *)(v4 + 16), 0LL);
pthread_mutex_init((pthread_mutex_t *)(v5 + 56), 0LL);
queue_init(v5 + 112);
pthread_mutex_lock(&g_client_list_mx);
v6 = a1[1];
if ( v6 )
{
*(_QWORD *)(v6 + 216) = v5;
a1[1] = v5;
}
else
{
a1[1] = v5;
*a1 = v5;
}
pthread_mutex_unlock(&g_client_list_mx);
}
else
{
print_error("memory allocation error");
}
return v5;
}

canonical_decompiled_code:
char *__fastcall func1(_QWORD *a1, int a2, _QWORD *a3)
{
char *v4; // rax
char *v5; // rbx
__int64 v6; // rax

v4 = (char *)calloc(1uLL, 0xE0uLL);
v5 = v4;
if ( v4 )
{
*((_DWORD *)v4 + 2) = a2;
*((_QWORD *)v4 + 12) = *a3;
pthread_mutex_init((pthread_mutex_t *)(v4 + 16), 0LL);
pthread_mutex_init((pthread_mutex_t *)(v5 + 56), 0LL);
queue_init(v5 + 112);
pthread_mutex_lock(&g_client_list_mx);
v6 = a1[1];
if ( v6 )
{
*(_QWORD *)(v6 + 216) = v5;
a1[1] = v5;
}
else
{
a1[1] = v5;
*a1 = v5;
}
pthread_mutex_unlock(&g_client_list_mx);
}
else
{
print_error("memory allocation error");
}
return v5;
}

original_code:
client_item_t* client_add(client_list_t *list, int socket, pthread_t *thread) {
  client_item_t *new_client;
  if ((new_client = (client_item_t *) calloc(1, sizeof(client_item_t))) == ((void *)0)) {
    print_error("memory allocation error");
    return ((void *)0);
  }
  new_client->socket = socket;
  new_client->recv_thread = *thread;
  pthread_mutex_init(&(new_client->sock_w_lock), ((void *)0));
  pthread_mutex_init(&(new_client->sock_r_lock), ((void *)0));
  queue_init(&new_client->queue);
  pthread_mutex_lock(&g_client_list_mx);
  if (list->end == ((void *)0)) {
    list->start = list->end = new_client;
  } else {
    list->end->next = new_client;
    list->end = new_client;
  }
  pthread_mutex_unlock(&g_client_list_mx);
  return new_client;
}

canonical_original_code:
struct __client_item_s *client_add(struct __client_list_s *list, int socket, unsigned long *thread) {
  struct __client_item_s *new_client;
  if ((new_client = (struct __client_item_s *) calloc(1, sizeof(client_item_t))) == ((void *)0)) {
    print_error("memory allocation error");
    return ((void *)0);
  }
  new_client->socket = socket;
  new_client->recv_thread = *thread;
  pthread_mutex_init(&(new_client->sock_w_lock), ((void *)0));
  pthread_mutex_init(&(new_client->sock_r_lock), ((void *)0));
  queue_init(&new_client->queue);
  pthread_mutex_lock(&g_client_list_mx);
  if (list->end == ((void *)0)) {
    list->start = list->end = new_client;
  } else {
    list->end->next = new_client;
    list->end = new_client;
  }
  pthread_mutex_unlock(&g_client_list_mx);
  return new_client;
}

variable_types: struct __client_list_s { struct __client_item_s *start; struct __client_item_s *end; } *

variable_types:
thread
unsigned long *

return_type: struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s *sender; struct __queue_item_s *next; } *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *


original_code:
void client_remove(client_list_t *list, int socket) {
  client_item_t *p, *pp;
  for (p = pp = list->start; p != ((void *)0); pp = p, p = p->next) {
    if (p->socket == socket) {
      pthread_mutex_lock(&g_client_list_mx);
      if (list->start == list->end) {
        list->start = ((void *)0);
        list->end = ((void *)0);
      } else {
        pp->next = p->next;
        if (p == list->start) {
          list->start = p->next;
        }
        if (p == list->end) {
          list->end = pp;
        }
      }
      client_free(p);
      pthread_mutex_unlock(&g_client_list_mx);
      break;
    }
  }
}

canonical_original_code:
void client_remove(struct __client_list_s *list, int socket) {
  struct __client_item_s *p; struct __client_item_s *pp;
  for (p = pp = list->start; p != ((void *)0); pp = p, p = p->next) {
    if (p->socket == socket) {
      pthread_mutex_lock(&g_client_list_mx);
      if (list->start == list->end) {
        list->start = ((void *)0);
        list->end = ((void *)0);
      } else {
        pp->next = p->next;
        if (p == list->start) {
          list->start = p->next;
        }
        if (p == list->end) {
          list->end = pp;
        }
      }
      client_free(p);
      pthread_mutex_unlock(&g_client_list_mx);
      break;
    }
  }
}

variable_types: struct __client_list_s { struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s *sender; struct __queue_item_s *next; } *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *start; struct __client_item_s *end; } *

user_defined_types: struct __client_list_s { struct __client_item_s *start; struct __client_item_s *end; }


decompiled_code:
__int64 __fastcall client_get_by_name(__int64 *a1, const char *a2)
{
__int64 i; // rbx

for ( i = *a1; i; i = *(_QWORD *)(i + 216) )
{
if ( *(_QWORD *)i && !strcmp(*(const char **)i, a2) )
break;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, const char *a2)
{
__int64 i; // rbx

for ( i = *a1; i; i = *(_QWORD *)(i + 216) )
{
if ( *(_QWORD *)i && !strcmp(*(const char **)i, a2) )
break;
}
return i;
}

original_code:
client_item_t* client_get_by_name(client_list_t *list, const char *name) {
  client_item_t *p;
  for (p = list->start; p != ((void *)0); p = p->next) {
    if (p->name != ((void *)0) && strcmp(p->name, name) == 0) {
      return p;
    }
  }
  return ((void *)0);
}

canonical_original_code:
struct __client_item_s *client_get_by_name(struct __client_list_s *list, char *name) {
  struct __client_item_s *p;
  for (p = list->start; p != ((void *)0); p = p->next) {
    if (p->name != ((void *)0) && strcmp(p->name, name) == 0) {
      return p;
    }
  }
  return ((void *)0);
}

variable_types:
name
char *


decompiled_code:
__int64 __fastcall client_get_by_socket(__int64 *a1, int a2)
{
__int64 result; // rax

for ( result = *a1; result; result = *(_QWORD *)(result + 216) )
{
if ( *(_DWORD *)(result + 8) == a2 )
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 *a1, int a2)
{
__int64 result; // rax

for ( result = *a1; result; result = *(_QWORD *)(result + 216) )
{
if ( *(_DWORD *)(result + 8) == a2 )
break;
}
return result;
}

original_code:
client_item_t* client_get_by_socket(client_list_t *list, int socket) {
  client_item_t *p;
  for (p = list->start; p != ((void *)0); p = p->next) {
    if (p->socket == socket) {
      return p;
    }
  }
  return ((void *)0);
}

canonical_original_code:
struct __client_item_s *client_get_by_socket(struct __client_list_s *list, int socket) {
  struct __client_item_s *p;
  for (p = list->start; p != ((void *)0); p = p->next) {
    if (p->socket == socket) {
      return p;
    }
  }
  return ((void *)0);
}

variable_types: socket int


decompiled_code:
__int64 __fastcall client_mesg_recv(__int64 a1, __int64 a2)
{
unsigned int v2; // ebx

pthread_mutex_lock((pthread_mutex_t *)(a1 + 56));
v2 = mesg_recv(*(unsigned int *)(a1 + 8), a2);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 56));
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
unsigned int v2; // ebx

pthread_mutex_lock((pthread_mutex_t *)(a1 + 56));
v2 = mesg_recv(*(unsigned int *)(a1 + 8), a2);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 56));
return v2;
}

original_code:
int client_mesg_recv(client_item_t *cl, message_t **msg) {
  pthread_mutex_lock(&(cl->sock_r_lock));
  int ret = mesg_recv(cl->socket, msg);
  pthread_mutex_unlock(&(cl->sock_r_lock));
  return ret;
}

canonical_original_code:
int client_mesg_recv(struct __client_item_s *cl, struct __message_s **msg) {
  pthread_mutex_lock(&(cl->sock_r_lock));
  int ret = mesg_recv(cl->socket, msg);
  pthread_mutex_unlock(&(cl->sock_r_lock));
  return ret;
}

variable_types:
msg
struct __message_s **

variable_types: ret int


decompiled_code:
__int64 __fastcall client_mesg_send(__int64 a1, unsigned __int8 a2, unsigned int a3, __int64 a4, unsigned int a5)
{
unsigned int v5; // er14

v5 = 1;
if ( *(int *)(a1 + 8) > 0 )
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 16));
v5 = mesg_send(*(unsigned int *)(a1 + 8), a2, a3, a4, a5);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 16));
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, unsigned __int8 a2, unsigned int a3, __int64 a4, unsigned int a5)
{
unsigned int v5; // er14

v5 = 1;
if ( *(int *)(a1 + 8) > 0 )
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 16));
v5 = mesg_send(*(unsigned int *)(a1 + 8), a2, a3, a4, a5);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 16));
}
return v5;
}

original_code:
int client_mesg_send(client_item_t *cl, uint_8 type, uint_32 id,
    const char *msg, int can_fail) {
  int ret = 1;
  if (cl->socket > 0) {
    pthread_mutex_lock(&(cl->sock_w_lock));
    ret = mesg_send(cl->socket, type, id, msg, can_fail);
    pthread_mutex_unlock(&(cl->sock_w_lock));
  }
  return ret;
}

canonical_original_code:
int client_mesg_send(struct __client_item_s *cl, unsigned char type, unsigned int id, char *msg, int can_fail) {
  int ret = 1;
  if (cl->socket > 0) {
    pthread_mutex_lock(&(cl->sock_w_lock));
    ret = mesg_send(cl->socket, type, id, msg, can_fail);
    pthread_mutex_unlock(&(cl->sock_w_lock));
  }
  return ret;
}


decompiled_code:
__int64 __fastcall client_mesg_peek(__int64 a1)
{
int v1; // eax
unsigned int v2; // er12
unsigned int v4; // ebx
char buf[27]; // [rsp+Dh] [rbp-1Bh] BYREF

pthread_mutex_lock((pthread_mutex_t *)(a1 + 56));
v1 = recv(*(_DWORD *)(a1 + 8), buf, 3uLL, 66);
if ( v1 <= 0 )
{
v4 = v1;
v2 = v1;
if ( v1 == -1 && *_errno_location() == 11 )
v2 = 11;
else
printf("peek ret = %d\n", v4);
}
else
{
v2 = (unsigned __int8)buf[2];
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 56));
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
int v1; // eax
unsigned int v2; // er12
unsigned int v4; // ebx
char buf[27]; // [rsp+Dh] [rbp-1Bh] BYREF

pthread_mutex_lock((pthread_mutex_t *)(a1 + 56));
v1 = recv(*(_DWORD *)(a1 + 8), buf, 3uLL, 66);
if ( v1 <= 0 )
{
v4 = v1;
v2 = v1;
if ( v1 == -1 && *_errno_location() == 11 )
v2 = 11;
else
printf("peek ret = %d\n", v4);
}
else
{
v2 = (unsigned __int8)buf[2];
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 56));
return v2;
}

original_code:
int client_mesg_peek(client_item_t *cl) {
  char buffer[3];
  pthread_mutex_lock(&cl->sock_r_lock);
  int len, ret;
  if ((len = recv(cl->socket, (void *)buffer, 3, MSG_DONTWAIT | MSG_PEEK)) <= 0) {
    if (len == -1 && ((*__errno_location ()) == 11 || (*__errno_location ()) == 11)) {
      ret = 11;
    } else {
      printf("peek ret = %d\n", len);
      ret = len;
    }
  } else {
    ret = *((uint_8 *)&buffer[2]);
  }
  pthread_mutex_unlock(&cl->sock_r_lock);
  return ret;
}

canonical_original_code:
int client_mesg_peek(struct __client_item_s *cl) {
  char buffer[3];
  pthread_mutex_lock(&cl->sock_r_lock);
  int len; int ret;
  if ((len = recv(cl->socket, (void *)buffer, 3, MSG_DONTWAIT | MSG_PEEK)) <= 0) {
    if (len == -1 && ((*__errno_location ()) == 11 || (*__errno_location ()) == 11)) {
      ret = 11;
    } else {
      printf("peek ret = %d\n", len);
      ret = len;
    }
  } else {
    ret = *((unsigned char *)&buffer[2]);
  }
  pthread_mutex_unlock(&cl->sock_r_lock);
  return ret;
}

variable_types:
buffer
char [3]


decompiled_code:
__int64 confirm_msg_recv_by_server()
{
mesg_remove_first(mesg_list);
return 0LL;
}

canonical_decompiled_code:
__int64 func0()
{
mesg_remove_first(mesg_list);
return 0LL;
}

original_code:
int confirm_msg_recv_by_server(message_t *new_msg) {
 mesg_remove_first(mesg_list);
 return 0;
}

canonical_original_code:
int confirm_msg_recv_by_server(struct __message_s *new_msg) {
 mesg_remove_first(mesg_list);
 return 0;
}

variable_types: struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *


decompiled_code:
__int64 __fastcall parse_new_msg(char *a1)
{
char v1; // al
unsigned int v2; // edx

v1 = *a1;
if ( *a1 == 2 )
{
print_error("disconnect msg received from the server");
v2 = -1;
}
else
{
switch ( v1 )
{
case 6:
print_error(*((_QWORD *)a1 + 1));
v2 = -2;
break;
case 5:
print_error(*((_QWORD *)a1 + 1));
v2 = 5;
break;
case 4:
v2 = confirm_msg_recv_by_server();
break;
default:
v2 = 0;
if ( v1 == 3 )
{
server_mesg_send(server_socket, 4LL, *((unsigned int *)a1 + 1), &unk_188, 0LL);
printf("-> %s\n", *((const char **)a1 + 1));
v2 = 3;
}
break;
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *a1)
{
char v1; // al
unsigned int v2; // edx

v1 = *a1;
if ( *a1 == 2 )
{
print_error("disconnect msg received from the server");
v2 = -1;
}
else
{
switch ( v1 )
{
case 6:
print_error(*((_QWORD *)a1 + 1));
v2 = -2;
break;
case 5:
print_error(*((_QWORD *)a1 + 1));
v2 = 5;
break;
case 4:
v2 = func0();
break;
default:
v2 = 0;
if ( v1 == 3 )
{
server_mesg_send(server_socket, 4LL, *((unsigned int *)a1 + 1), &unk_188, 0LL);
printf("-> %s\n", *((const char **)a1 + 1));
v2 = 3;
}
break;
}
}
return v2;
}

original_code:
int parse_new_msg(message_t *new_msg) {
 if(new_msg->type == 2) {
  print_error("disconnect msg received from the server");
  return -1;
 } else if(new_msg->type == 6) {
  print_error(new_msg->text);
  return -2;
 } else if(new_msg->type == 5) {
  print_error(new_msg->text);
  return 5;
 } else if(new_msg->type == 4) {
  return confirm_msg_recv_by_server(new_msg);
 } else if(new_msg->type == 3) {
  server_mesg_send(server_socket, 4, new_msg->id, "", 0);
  printf("-> %s\n", new_msg->text);
  return 3;
 }
 return 0;
}

canonical_original_code:
int parse_new_msg(struct __message_s *new_msg) {
 if(new_msg->type == 2) {
  print_error("disconnect msg received from the server");
  return -1;
 } else if(new_msg->type == 6) {
  print_error(new_msg->text);
  return -2;
 } else if(new_msg->type == 5) {
  print_error(new_msg->text);
  return 5;
 } else if(new_msg->type == 4) {
  return confirm_msg_recv_by_server(new_msg);
 } else if(new_msg->type == 3) {
  server_mesg_send(server_socket, 4, new_msg->id, "", 0);
  printf("-> %s\n", new_msg->text);
  return 3;
 }
 return 0;
}


decompiled_code:
__int64 __fastcall server_mesg_recv(unsigned int *a1, __int64 a2)
{
unsigned int v2; // ebx

pthread_mutex_lock((pthread_mutex_t *)(a1 + 12));
v2 = mesg_recv2(*a1, a2, 0LL);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 12));
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int *a1, __int64 a2)
{
unsigned int v2; // ebx

pthread_mutex_lock((pthread_mutex_t *)(a1 + 12));
v2 = mesg_recv2(*a1, a2, 0LL);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 12));
return v2;
}

original_code:
int server_mesg_recv(server_socket_t *server_socket, message_t **msg) {
 pthread_mutex_lock(&(server_socket->sock_r_lock));
 int ret = mesg_recv2(server_socket->socket, msg, 0);
 pthread_mutex_unlock(&(server_socket->sock_r_lock));
 return ret;
}

canonical_original_code:
int server_mesg_recv(struct __server_socket_s *server_socket, struct __message_s **msg) {
 pthread_mutex_lock(&(server_socket->sock_r_lock));
 int ret = mesg_recv2(server_socket->socket, msg, 0);
 pthread_mutex_unlock(&(server_socket->sock_r_lock));
 return ret;
}

variable_types: struct __server_socket_s { int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; } *

variable_types: struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } **

user_defined_types: struct __server_socket_s { int socket; union pthread_mutex_t sock_w_lock; union pthread_mutex_t sock_r_lock; }


decompiled_code:
__int64 __fastcall recv_thread_worker(__int64 a1)
{
char *v2; // [rsp+8h] [rbp-10h] BYREF

server_socket = *(_QWORD *)a1;
mesg_list = *(_QWORD *)(a1 + 8);
while ( (int)server_mesg_recv((unsigned int *)server_socket, (__int64)&v2) > 0 )
{
if ( (int)parse_new_msg(v2) < 0 )
goto LABEL_6;
}
print_error("error receiving packet");
LABEL_6:
pthread_cancel(**(_QWORD **)(a1 + 16));
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
char *v2; // [rsp+8h] [rbp-10h] BYREF

server_socket = *(_QWORD *)a1;
mesg_list = *(_QWORD *)(a1 + 8);
while ( (int)func2((unsigned int *)server_socket, (__int64)&v2) > 0 )
{
if ( (int)func1(v2) < 0 )
goto LABEL_6;
}
print_error("error receiving packet");
LABEL_6:
pthread_cancel(**(_QWORD **)(a1 + 16));
return 0LL;
}

original_code:
void* recv_thread_worker(void *data) {
 thread_args_t *args = (thread_args_t *) data;
 server_socket = args->server_socket;
 mesg_list = args->mesg_list;
 while(1) {
  message_t *new_msg;
  if(server_mesg_recv(server_socket, &new_msg) <= 0) {
   print_error("error receiving packet");
   break;
  }
  if(parse_new_msg(new_msg) < 0) {
   break;
  }
 }
 pthread_cancel(*(args->terminal_thread));
 return ((void *)0);
}

canonical_original_code:
void *recv_thread_worker(void *data) {
 struct __thread_args_s *args = (thread_args_t *) data;
 server_socket = args->server_socket;
 mesg_list = args->mesg_list;
 while(1) {
  struct __message_s *new_msg;
  if(server_mesg_recv(server_socket, &new_msg) <= 0) {
   print_error("error receiving packet");
   break;
  }
  if(parse_new_msg(new_msg) < 0) {
   break;
  }
 }
 pthread_cancel(*(args->terminal_thread));
 return ((void *)0);
}

variable_types:
data
void *

variable_types: struct __thread_args_s { struct __server_socket_s { int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; } *server_socket; struct __mesg_list_s { struct __mesg_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *mesg; struct __mesg_item_s *next; } *start; struct __mesg_item_s *end; union pthread_mutex_t *mesg_mutex; } *mesg_list; unsigned long *terminal_thread; } *

return_type: void *

user_defined_types: struct __thread_args_s { struct __server_socket_s *server_socket; struct __mesg_list_s *mesg_list; unsigned long *terminal_thread; }

user_defined_types: struct __mesg_list_s { struct __mesg_item_s *start; struct __mesg_item_s *end; union pthread_mutex_t *mesg_mutex; }

user_defined_types: struct __mesg_item_s { struct __message_s *mesg; struct __mesg_item_s *next; }


decompiled_code:
__int64 __fastcall send_disconnect_message(__int64 a1)
{
return server_mesg_send(a1, 2LL, 0LL, &unk_B1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return server_mesg_send(a1, 2LL, 0LL, &unk_B1, 0LL);
}

original_code:
void send_disconnect_message(server_socket_t *server_socket) {
 server_mesg_send(server_socket, 2, 0, "", 0);
}

canonical_original_code:
void send_disconnect_message(struct __server_socket_s *server_socket) {
 server_mesg_send(server_socket, 2, 0, "", 0);
}


decompiled_code:
__int64 __fastcall send_message_to_server(__int64 a1, unsigned __int8 *a2)
{
__int64 result; // rax

result = 1LL;
if ( a2 )
result = server_mesg_send(a1, *a2, *((unsigned int *)a2 + 1), *((_QWORD *)a2 + 1), g_fail);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned __int8 *a2)
{
__int64 result; // rax

result = 1LL;
if ( a2 )
result = server_mesg_send(a1, *a2, *((unsigned int *)a2 + 1), *((_QWORD *)a2 + 1), g_fail);
return result;
}

original_code:
int send_message_to_server(server_socket_t *server_socket, message_t *msg) {
 if(msg == ((void *)0)) {
  return 1;
 }
    int ret = server_mesg_send(server_socket, msg->type, msg->id, (msg->text), g_fail);
 return ret;
}

canonical_original_code:
int send_message_to_server(struct __server_socket_s *server_socket, struct __message_s *msg) {
 if(msg == ((void *)0)) {
  return 1;
 }
    int ret = server_mesg_send(server_socket, msg->type, msg->id, (msg->text), g_fail);
 return ret;
}


decompiled_code:
__int64 __fastcall send_first_mesg_from_list(__int64 a1, __int64 a2)
{
unsigned int v2; // ebp

v2 = 1;
if ( *(_QWORD *)a2 )
{
pthread_mutex_lock(*(pthread_mutex_t **)(a2 + 16));
v2 = send_message_to_server(a1, **(unsigned __int8 ***)a2);
pthread_mutex_unlock(*(pthread_mutex_t **)(a2 + 16));
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
unsigned int v2; // ebp

v2 = 1;
if ( *(_QWORD *)a2 )
{
pthread_mutex_lock(*(pthread_mutex_t **)(a2 + 16));
v2 = func1(a1, **(unsigned __int8 ***)a2);
pthread_mutex_unlock(*(pthread_mutex_t **)(a2 + 16));
}
return v2;
}

original_code:
int send_first_mesg_from_list(server_socket_t *server_socket, mesg_list_t *mesg_list) {
 if (mesg_list->start == ((void *)0)) {
  return 1;
 }
 pthread_mutex_lock(mesg_list->mesg_mutex);
 int ret = send_message_to_server(server_socket, mesg_list->start->mesg);
 pthread_mutex_unlock(mesg_list->mesg_mutex);
 return ret;
}

canonical_original_code:
int send_first_mesg_from_list(struct __server_socket_s *server_socket, struct __mesg_list_s *mesg_list) {
 if (mesg_list->start == ((void *)0)) {
  return 1;
 }
 pthread_mutex_lock(mesg_list->mesg_mutex);
 int ret = send_message_to_server(server_socket, mesg_list->start->mesg);
 pthread_mutex_unlock(mesg_list->mesg_mutex);
 return ret;
}

variable_types: struct __mesg_list_s { struct __mesg_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *mesg; struct __mesg_item_s *next; } *start; struct __mesg_item_s *end; union pthread_mutex_t *mesg_mutex; } *


decompiled_code:
void __fastcall __noreturn send_thread_worker(__int64 *a1)
{
__int64 v1; // rbp
__int64 i; // rbx

v1 = *a1;
for ( i = a1[1]; ; send_first_mesg_from_list(v1, i) )
sleep(1u);
}

canonical_decompiled_code:
void __fastcall __noreturn func3(__int64 *a1)
{
__int64 v1; // rbp
__int64 i; // rbx

v1 = *a1;
for ( i = a1[1]; ; func2(v1, i) )
sleep(1u);
}

original_code:
void* send_thread_worker(void *data) {
 thread_args_t *args = (thread_args_t *) data;
 server_socket_t *server_socket = args->server_socket;
 mesg_list_t *mesg_list = args->mesg_list;
 while(1) {
  sleep(1);
  send_first_mesg_from_list(server_socket, mesg_list);
 }
}

canonical_original_code:
void *send_thread_worker(void *data) {
 struct __thread_args_s *args = (thread_args_t *) data;
 struct __server_socket_s *server_socket = args->server_socket;
 struct __mesg_list_s *mesg_list = args->mesg_list;
 while(1) {
  sleep(1);
  send_first_mesg_from_list(server_socket, mesg_list);
 }
}

variable_types: struct __mesg_list_s { struct __mesg_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *mesg; struct __mesg_item_s *next; } *start; struct __mesg_item_s *end; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mesg_mutex; } *


decompiled_code:
__int64 __fastcall disconnect_client(__int64 a1, __int64 a2)
{
client_mesg_send(a1, 2LL, 0LL, &unk_7C1, 0LL);
printf("Disconnecting client: %s\n", *(const char **)a1);
close(*(_DWORD *)(a1 + 8));
return client_remove(a2, *(unsigned int *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
client_mesg_send(a1, 2LL, 0LL, &unk_7C1, 0LL);
printf("Disconnecting client: %s\n", *(const char **)a1);
close(*(_DWORD *)(a1 + 8));
return client_remove(a2, *(unsigned int *)(a1 + 8));
}

original_code:
void disconnect_client(client_item_t *cl, client_list_t *clients) {
  client_mesg_send(cl, 2, 0, "", 0);
  printf("Disconnecting client: %s\n", cl->name);
  close(cl->socket);
  client_remove(clients, cl->socket);
}

canonical_original_code:
void disconnect_client(struct __client_item_s *cl, struct __client_list_s *clients) {
  client_mesg_send(cl, 2, 0, "", 0);
  printf("Disconnecting client: %s\n", cl->name);
  close(cl->socket);
  client_remove(clients, cl->socket);
}


decompiled_code:
__int64 __fastcall send_message_to_user(_QWORD *a1, __int64 a2, __int64 a3)
{
const char *v4; // r12
void *v5; // rsp
char v6; // dl
__int64 v7; // rax
int v8; // ecx
__int64 v9; // r12
unsigned int v10; // er12
char v12[48]; // [rsp+0h] [rbp-30h] BYREF

v4 = *(const char **)(a3 + 8);
v5 = alloca(strlen(v4));
v6 = *v4;
if ( !*v4 || v6 == 58 )
{
v12[0] = 0;
LABEL_14:
client_mesg_send(a1, 5LL, *(unsigned int *)(a3 + 4), "No user name supplied", 0LL);
puts("Wrong message format");
return (unsigned int)-1;
}
v7 = 1LL;
do
{
v8 = v7;
v12[v7 - 1] = v6;
v6 = v4[v7++];
}
while ( v6 && v6 != 58 );
v12[v8] = 0;
if ( !v8 )
goto LABEL_14;
v9 = client_get_by_name(a2, v12);
printf("sending message to %s\n", v12);
if ( v9 )
{
queue_push(v9 + 112, a3, a1);
v10 = 1;
}
else
{
v10 = file_save_message(a3, v12, *a1);
if ( v10 == -1 )
{
client_mesg_send(a1, 5LL, *(unsigned int *)(a3 + 4), "User with this name doesn't exist", 0LL);
fprintf(stderr, "User '%s' not found\n", v12);
}
else
{
client_mesg_send(a1, 5LL, *(unsigned int *)(a3 + 4), "User not logged in, message was saved", 0LL);
v10 = 1;
}
}
return v10;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1, __int64 a2, __int64 a3)
{
const char *v4; // r12
void *v5; // rsp
char v6; // dl
__int64 v7; // rax
int v8; // ecx
__int64 v9; // r12
unsigned int v10; // er12
char v12[48]; // [rsp+0h] [rbp-30h] BYREF

v4 = *(const char **)(a3 + 8);
v5 = alloca(strlen(v4));
v6 = *v4;
if ( !*v4 || v6 == 58 )
{
v12[0] = 0;
LABEL_14:
client_mesg_send(a1, 5LL, *(unsigned int *)(a3 + 4), "No user name supplied", 0LL);
puts("Wrong message format");
return (unsigned int)-1;
}
v7 = 1LL;
do
{
v8 = v7;
v12[v7 - 1] = v6;
v6 = v4[v7++];
}
while ( v6 && v6 != 58 );
v12[v8] = 0;
if ( !v8 )
goto LABEL_14;
v9 = client_get_by_name(a2, v12);
printf("sending message to %s\n", v12);
if ( v9 )
{
queue_push(v9 + 112, a3, a1);
v10 = 1;
}
else
{
v10 = file_save_message(a3, v12, *a1);
if ( v10 == -1 )
{
client_mesg_send(a1, 5LL, *(unsigned int *)(a3 + 4), "User with this name doesn't exist", 0LL);
fprintf(stderr, "User '%s' not found\n", v12);
}
else
{
client_mesg_send(a1, 5LL, *(unsigned int *)(a3 + 4), "User not logged in, message was saved", 0LL);
v10 = 1;
}
}
return v10;
}

original_code:
int send_message_to_user(client_item_t *sender, client_list_t *clients, message_t *msg) {
  char user_name[strlen(msg->text)];
  char *c = msg->text;
  int i = 0;
  while (*c != 0 && *c != ':') {
    user_name[i++] = *(c++);
  }
  user_name[i] = (char)0;
  if (i == 0) {
    client_mesg_send(sender, 5, msg->id, "No user name supplied", 0);
    printf("Wrong message format\n");
    return -1;
  }
  client_item_t *cl = client_get_by_name(clients, user_name);
  printf("sending message to %s\n", user_name);
  if (cl == ((void *)0)) {
    if (file_save_message(msg, user_name, sender->name) == -1) {
      client_mesg_send(sender, 5, msg->id, "User with this name doesn't exist", 0);
      fprintf(stderr, "User '%s' not found\n", user_name);
      return -1;
    } else {
      client_mesg_send(sender, 5, msg->id, "User not logged in, message was saved", 0);
    }
  } else {
    queue_push(&cl->queue, msg, sender);
  }
  return 1;
}

canonical_original_code:
int send_message_to_user(struct __client_item_s *sender, struct __client_list_s *clients, struct __message_s *msg) {
  char user_name[-1];
  char *c = msg->text;
  int i = 0;
  while (*c != 0 && *c != ':') {
    user_name[i++] = *(c++);
  }
  user_name[i] = (char)0;
  if (i == 0) {
    client_mesg_send(sender, 5, msg->id, "No user name supplied", 0);
    printf("Wrong message format\n");
    return -1;
  }
  struct __client_item_s *cl = client_get_by_name(clients, user_name);
  printf("sending message to %s\n", user_name);
  if (cl == ((void *)0)) {
    if (file_save_message(msg, user_name, sender->name) == -1) {
      client_mesg_send(sender, 5, msg->id, "User with this name doesn't exist", 0);
      fprintf(stderr, "User '%s' not found\n", user_name);
      return -1;
    } else {
      client_mesg_send(sender, 5, msg->id, "User not logged in, message was saved", 0);
    }
  } else {
    queue_push(&cl->queue, msg, sender);
  }
  return 1;
}

variable_types:
msg
struct __message_s *

variable_types:
c
char *

variable_types: i int


decompiled_code:
__int64 __fastcall client_thread_worker(void *ptr)
{
__int64 v1; // r12
unsigned int v2; // ebx
const char **v4; // rbx
char *v5; // rdi
__int64 v6; // rbp
char v7; // al
int v8; // eax
__int64 v9; // [rsp+0h] [rbp-28h] BYREF
__int64 v10[4]; // [rsp+8h] [rbp-20h] BYREF

v1 = *((_QWORD *)ptr + 2);
v2 = *(_DWORD *)ptr;
if ( (int)mesg_recv(*(unsigned int *)ptr, v10) <= 0 )
{
free(ptr);
close(v2);
print_error("error receiving login packet");
}
else if ( *(_BYTE *)v10[0] == 1 )
{
printf("user '%s' connected\n", *(const char **)(v10[0] + 8));
if ( client_get_by_name(v1, *(_QWORD *)(v10[0] + 8)) )
{
mesg_send(v2, 2LL, 0LL, &unk_7C1, 0LL);
printf("user '%s' already logged in, disconnecting\n", *(const char **)(v10[0] + 8));
free(ptr);
free_message(v10[0]);
close(v2);
}
else
{
v4 = (const char **)client_add(*((_QWORD *)ptr + 2), *(unsigned int *)ptr, (char *)ptr + 8);
free(ptr);
if ( v4 )
{
v5 = (char *)malloc(*(_QWORD *)(v10[0] + 16) + 1LL);
*v4 = v5;
if ( v5 )
{
v6 = v10[0];
strcpy(v5, *(const char **)(v10[0] + 8));
free_message(v6);
if ( (int)client_mesg_send(v4, 4LL, 0LL, "OK", 0LL) < 0 )
{
disconnect_client((__int64)v4, v1);
print_error("confirmation send failed");
}
else
{
file_login_client(*v4);
pthread_detach((pthread_t)v4[12]);
if ( pthread_create((pthread_t *)v4 + 13, 0LL, client_send_worker, v4) )
{
disconnect_client((__int64)v4, v1);
print_error("create sending thread failed");
}
else
{
file_send_undelivered(v4, v1);
while ( 1 )
{
while ( 1 )
{
v7 = client_mesg_peek(v4);
if ( v7 != 4 && v7 != 11 )
break;
usleep(0x186A0u);
}
v8 = client_mesg_recv(v4, &v9);
if ( v8 <= 0 )
break;
if ( *(_BYTE *)v9 == 2 )
{
free_message(v9);
goto LABEL_32;
}
if ( *(_BYTE *)v9 == 3 )
{
if ( (int)client_mesg_send(v4, 4LL, *(unsigned int *)(v9 + 4), "OK", 0LL) < 0 )
{
print_error("message confirmation failed");
free_message(v9);
}
else if ( (unsigned int)send_message_to_user(v4, v1, v9) == -1 )
{
free_message(v9);
}
}
else
{
fprintf(stderr, "%sreceived message with wrong format from user%s\n", "error: ", *v4);
free_message(v9);
}
}
if ( v8 < 0 )
{
print_error("mesg_recv");
goto LABEL_30;
}
LABEL_32:
print_error("client disconnected");
LABEL_30:
pthread_cancel((pthread_t)v4[13]);
disconnect_client((__int64)v4, v1);
}
}
}
else
{
disconnect_client((__int64)v4, v1);
free_message(v10[0]);
print_error("memory allocation error");
}
}
else
{
disconnect_client(0LL, v1);
free_message(v10[0]);
print_error("memory allocation error");
}
}
}
else
{
print_error("wrong type of packet received");
mesg_send(v2, 6LL, 0LL, "Unexpected message received", 0LL);
free(ptr);
free_message(v10[0]);
close(v2);
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(void *ptr)
{
__int64 v1; // r12
unsigned int v2; // ebx
const char **v4; // rbx
char *v5; // rdi
__int64 v6; // rbp
char v7; // al
int v8; // eax
__int64 v9; // [rsp+0h] [rbp-28h] BYREF
__int64 v10[4]; // [rsp+8h] [rbp-20h] BYREF

v1 = *((_QWORD *)ptr + 2);
v2 = *(_DWORD *)ptr;
if ( (int)mesg_recv(*(unsigned int *)ptr, v10) <= 0 )
{
free(ptr);
close(v2);
print_error("error receiving login packet");
}
else if ( *(_BYTE *)v10[0] == 1 )
{
printf("user '%s' connected\n", *(const char **)(v10[0] + 8));
if ( client_get_by_name(v1, *(_QWORD *)(v10[0] + 8)) )
{
mesg_send(v2, 2LL, 0LL, &unk_7C1, 0LL);
printf("user '%s' already logged in, disconnecting\n", *(const char **)(v10[0] + 8));
free(ptr);
free_message(v10[0]);
close(v2);
}
else
{
v4 = (const char **)client_add(*((_QWORD *)ptr + 2), *(unsigned int *)ptr, (char *)ptr + 8);
free(ptr);
if ( v4 )
{
v5 = (char *)malloc(*(_QWORD *)(v10[0] + 16) + 1LL);
*v4 = v5;
if ( v5 )
{
v6 = v10[0];
strcpy(v5, *(const char **)(v10[0] + 8));
free_message(v6);
if ( (int)client_mesg_send(v4, 4LL, 0LL, "OK", 0LL) < 0 )
{
func0((__int64)v4, v1);
print_error("confirmation send failed");
}
else
{
file_login_client(*v4);
pthread_detach((pthread_t)v4[12]);
if ( pthread_create((pthread_t *)v4 + 13, 0LL, client_send_worker, v4) )
{
func0((__int64)v4, v1);
print_error("create sending thread failed");
}
else
{
file_send_undelivered(v4, v1);
while ( 1 )
{
while ( 1 )
{
v7 = client_mesg_peek(v4);
if ( v7 != 4 && v7 != 11 )
break;
usleep(0x186A0u);
}
v8 = client_mesg_recv(v4, &v9);
if ( v8 <= 0 )
break;
if ( *(_BYTE *)v9 == 2 )
{
free_message(v9);
goto LABEL_32;
}
if ( *(_BYTE *)v9 == 3 )
{
if ( (int)client_mesg_send(v4, 4LL, *(unsigned int *)(v9 + 4), "OK", 0LL) < 0 )
{
print_error("message confirmation failed");
free_message(v9);
}
else if ( (unsigned int)func1(v4, v1, v9) == -1 )
{
free_message(v9);
}
}
else
{
fprintf(stderr, "%sreceived message with wrong format from user%s\n", "error: ", *v4);
free_message(v9);
}
}
if ( v8 < 0 )
{
print_error("mesg_recv");
goto LABEL_30;
}
LABEL_32:
print_error("client disconnected");
LABEL_30:
pthread_cancel((pthread_t)v4[13]);
func0((__int64)v4, v1);
}
}
}
else
{
func0((__int64)v4, v1);
free_message(v10[0]);
print_error("memory allocation error");
}
}
else
{
func0(0LL, v1);
free_message(v10[0]);
print_error("memory allocation error");
}
}
}
else
{
print_error("wrong type of packet received");
mesg_send(v2, 6LL, 0LL, "Unexpected message received", 0LL);
free(ptr);
free_message(v10[0]);
close(v2);
}
return 0LL;
}

original_code:
void* client_thread_worker(void *data) {
  client_thread_param_t *pm = (client_thread_param_t *) data;
  client_list_t *clients = pm->clients;
  int len;
  int client_socket = pm->socket;
  message_t *login_msg;
  if (mesg_recv(client_socket, &login_msg) <= 0) {
    free(pm);
    close(client_socket);
    print_error("error receiving login packet");
    return ((void *)0);
  }
  if (login_msg->type != 1) {
    print_error("wrong type of packet received");
    mesg_send(client_socket, 6, 0, "Unexpected message received", 0);
    free(pm);
    free_message(login_msg);
    close(client_socket);
    return ((void *)0);
  }
  printf("user '%s' connected\n", login_msg->text);
  if (client_get_by_name(clients, login_msg->text) != ((void *)0)) {
    mesg_send(client_socket, 2, 0, "", 0);
    printf("user '%s' already logged in, disconnecting\n", login_msg->text);
    free(pm);
    free_message(login_msg);
    close(client_socket);
    return ((void *)0);
  }
  client_item_t *cl = client_add(pm->clients, pm->socket, &(pm->thread));
  free(pm);
  if (cl == ((void *)0)) {
    disconnect_client(cl, clients);
    free_message(login_msg);
    print_error("memory allocation error");
    return ((void *)0);
  }
  if ((cl->name = (char *) malloc((login_msg->text_len+1)*sizeof(char))) == ((void *)0)) {
    disconnect_client(cl, clients);
    free_message(login_msg);
    print_error("memory allocation error");
    return ((void *)0);
  }
  strcpy(cl->name, login_msg->text);
  free_message(login_msg);
  if (client_mesg_send(cl, 4, 0, "OK", 0) < 0) {
    disconnect_client(cl, clients);
    print_error("confirmation send failed");
    return ((void *)0);
  }
  file_login_client(cl->name);
  pthread_detach(cl->recv_thread);
  if (pthread_create(&(cl->send_thread), ((void *)0), client_send_worker, cl) != 0) {
    disconnect_client(cl, clients);
    print_error("create sending thread failed");
    return ((void *)0);
  }
  file_send_undelivered(cl, clients);
  message_t *msg;
  uint_8 type;
  len = 1;
  while (len > 0) {
    while ((type = client_mesg_peek(cl)) == 11 || type == 4) {
      usleep(100000);
    }
    if ((len = client_mesg_recv(cl, &msg)) > 0) {
      if (msg->type == 2) {
        len = 0;
        free_message(msg);
      } else if (msg->type == 3) {
        if (client_mesg_send(cl, 4, msg->id, "OK", 0) < 0) {
          print_error("message confirmation failed");
          free_message(msg);
        } else {
          if (send_message_to_user(cl, clients, msg) == -1) {
            free_message(msg);
          }
        }
      } else {
        fprintf(stderr,"%sreceived message with wrong format from user%s\n",
            "error: ", cl->name);
        free_message(msg);
      }
    }
  }
  if (len < 0) {
    print_error("mesg_recv");
  } else if (len == 0) {
    print_error("client disconnected");
  }
  pthread_cancel(cl->send_thread);
  disconnect_client(cl, clients);
  return ((void *)0);
}

canonical_original_code:
void *client_thread_worker(void *data) {
  struct __client_thread_param_s *pm = (client_thread_param_t *) data;
  struct __client_list_s *clients = pm->clients;
  int len;
  int client_socket = pm->socket;
  struct __message_s *login_msg;
  if (mesg_recv(client_socket, &login_msg) <= 0) {
    free(pm);
    close(client_socket);
    print_error("error receiving login packet");
    return ((void *)0);
  }
  if (login_msg->type != 1) {
    print_error("wrong type of packet received");
    mesg_send(client_socket, 6, 0, "Unexpected message received", 0);
    free(pm);
    free_message(login_msg);
    close(client_socket);
    return ((void *)0);
  }
  printf("user '%s' connected\n", login_msg->text);
  if (client_get_by_name(clients, login_msg->text) != ((void *)0)) {
    mesg_send(client_socket, 2, 0, "", 0);
    printf("user '%s' already logged in, disconnecting\n", login_msg->text);
    free(pm);
    free_message(login_msg);
    close(client_socket);
    return ((void *)0);
  }
  struct __client_item_s *cl = client_add(pm->clients, pm->socket, &(pm->thread));
  free(pm);
  if (cl == ((void *)0)) {
    disconnect_client(cl, clients);
    free_message(login_msg);
    print_error("memory allocation error");
    return ((void *)0);
  }
  if ((cl->name = (char *) malloc((login_msg->text_len+1)*sizeof(char))) == ((void *)0)) {
    disconnect_client(cl, clients);
    free_message(login_msg);
    print_error("memory allocation error");
    return ((void *)0);
  }
  strcpy(cl->name, login_msg->text);
  free_message(login_msg);
  if (client_mesg_send(cl, 4, 0, "OK", 0) < 0) {
    disconnect_client(cl, clients);
    print_error("confirmation send failed");
    return ((void *)0);
  }
  file_login_client(cl->name);
  pthread_detach(cl->recv_thread);
  if (pthread_create(&(cl->send_thread), ((void *)0), client_send_worker, cl) != 0) {
    disconnect_client(cl, clients);
    print_error("create sending thread failed");
    return ((void *)0);
  }
  file_send_undelivered(cl, clients);
  struct __message_s *msg;
  unsigned char type;
  len = 1;
  while (len > 0) {
    while ((type = client_mesg_peek(cl)) == 11 || type == 4) {
      usleep(100000);
    }
    if ((len = client_mesg_recv(cl, &msg)) > 0) {
      if (msg->type == 2) {
        len = 0;
        free_message(msg);
      } else if (msg->type == 3) {
        if (client_mesg_send(cl, 4, msg->id, "OK", 0) < 0) {
          print_error("message confirmation failed");
          free_message(msg);
        } else {
          if (send_message_to_user(cl, clients, msg) == -1) {
            free_message(msg);
          }
        }
      } else {
        fprintf(stderr,"%sreceived message with wrong format from user%s\n",
            "error: ", cl->name);
        free_message(msg);
      }
    }
  }
  if (len < 0) {
    print_error("mesg_recv");
  } else if (len == 0) {
    print_error("client disconnected");
  }
  pthread_cancel(cl->send_thread);
  disconnect_client(cl, clients);
  return ((void *)0);
}

variable_types: struct __client_thread_param_s { int socket; unsigned long thread; struct __client_list_s { struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s *sender; struct __queue_item_s *next; } *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *start; struct __client_item_s *end; } *clients; } *

variable_types: len int

variable_types:
type
unsigned char

user_defined_types: struct __client_thread_param_s { int socket; unsigned long thread; struct __client_list_s *clients; }


original_code:
char* add_sender(const char *sender, message_t *msg) {
  int colon = 0;
  char *c = msg->text;
  while (*c != ':' && *c != 0) { colon++; c++; }
  size_t s_len = strlen(sender), mesg_len = s_len+msg->text_len-colon+1;
  char *message = (char *) malloc(mesg_len*sizeof(char));
  if (message == ((void *)0)) {
    return ((void *)0);
  }
  strncpy(message, sender, s_len);
  strncpy(&message[s_len], &msg->text[colon], msg->text_len-colon);
  message[mesg_len-1] = (char)0;
  return message;
}

canonical_original_code:
char *add_sender(char *sender, struct __message_s *msg) {
  int colon = 0;
  char *c = msg->text;
  while (*c != ':' && *c != 0) { colon++; c++; }
  unsigned long s_len = strlen(sender); unsigned long mesg_len = s_len+msg->text_len-colon+1;
  char *message = (char *) malloc(mesg_len*sizeof(char));
  if (message == ((void *)0)) {
    return ((void *)0);
  }
  strncpy(message, sender, s_len);
  strncpy(&message[s_len], &msg->text[colon], msg->text_len-colon);
  message[mesg_len-1] = (char)0;
  return message;
}

variable_types:
sender
char *

variable_types: colon int

variable_types:
message
char *

return_type: char *


decompiled_code:
void *__fastcall client_send_worker(void *a1)
{
unsigned int v1; // er14
__int64 v2; // rax
_BOOL4 v4; // ebp
int v5; // ebx
unsigned __int8 **v6; // r15
int v7; // [rsp+Ch] [rbp-5Ch]
char *ptr; // [rsp+10h] [rbp-58h]
__int64 v9[8]; // [rsp+28h] [rbp-40h] BYREF

pthread_detach(*((_QWORD *)a1 + 13));
v1 = 0;
v2 = queue_pop((char *)a1 + 112);
LABEL_20:
v6 = (unsigned __int8 **)v2;
if ( v2 )
{
ptr = add_sender(**(char ***)(v2 + 8), *(_QWORD *)v2);
if ( ptr )
{
v7 = 0;
while ( (int)client_mesg_send(a1, **v6, v1, ptr, g_fail) > 0 )
{
printf("Sending message to client %s (%d)\n", *(const char **)a1, v1);
v9[0] = 0LL;
v5 = 0;
do
{
if ( (unsigned int)client_mesg_peek(a1) == 4 )
{
if ( (int)client_mesg_recv(a1, v9) <= 0 )
{
print_error("error receiving messsage from client");
v4 = 0;
}
else
{
printf("Confirmation of message of id: %d received\n", *(unsigned int *)(v9[0] + 4));
v4 = *(_DWORD *)(v9[0] + 4) == v1;
}
free_message(v9[0]);
}
else
{
usleep(0x30D40u);
v4 = 0;
}
++v5;
}
while ( v5 <= 4 && !v4 );
if ( ++v7 > 9 || v4 )
{
if ( v4 )
{
LABEL_19:
free_queue_item(v6);
free(ptr);
++v1;
v2 = queue_pop((char *)a1 + 112);
goto LABEL_20;
}
LABEL_5:
client_mesg_send(v6[1], 5LL, *((unsigned int *)*v6 + 1), "Message sending failed", 0LL);
fprintf(stderr, "Message sending to client %s failed\n", *(const char **)a1);
goto LABEL_19;
}
}
fprintf(stderr, "error: error sending message to client: %s\n", *(const char **)a1);
client_mesg_send(v6[1], 5LL, 0LL, "error sending message", 0LL);
goto LABEL_5;
}
print_error("memory allocation error");
}
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func4(void *a1)
{
unsigned int v1; // er14
__int64 v2; // rax
_BOOL4 v4; // ebp
int v5; // ebx
unsigned __int8 **v6; // r15
int v7; // [rsp+Ch] [rbp-5Ch]
char *ptr; // [rsp+10h] [rbp-58h]
__int64 v9[8]; // [rsp+28h] [rbp-40h] BYREF

pthread_detach(*((_QWORD *)a1 + 13));
v1 = 0;
v2 = queue_pop((char *)a1 + 112);
LABEL_20:
v6 = (unsigned __int8 **)v2;
if ( v2 )
{
ptr = func3(**(char ***)(v2 + 8), *(_QWORD *)v2);
if ( ptr )
{
v7 = 0;
while ( (int)client_mesg_send(a1, **v6, v1, ptr, g_fail) > 0 )
{
printf("Sending message to client %s (%d)\n", *(const char **)a1, v1);
v9[0] = 0LL;
v5 = 0;
do
{
if ( (unsigned int)client_mesg_peek(a1) == 4 )
{
if ( (int)client_mesg_recv(a1, v9) <= 0 )
{
print_error("error receiving messsage from client");
v4 = 0;
}
else
{
printf("Confirmation of message of id: %d received\n", *(unsigned int *)(v9[0] + 4));
v4 = *(_DWORD *)(v9[0] + 4) == v1;
}
free_message(v9[0]);
}
else
{
usleep(0x30D40u);
v4 = 0;
}
++v5;
}
while ( v5 <= 4 && !v4 );
if ( ++v7 > 9 || v4 )
{
if ( v4 )
{
LABEL_19:
free_queue_item(v6);
free(ptr);
++v1;
v2 = queue_pop((char *)a1 + 112);
goto LABEL_20;
}
LABEL_5:
client_mesg_send(v6[1], 5LL, *((unsigned int *)*v6 + 1), "Message sending failed", 0LL);
fprintf(stderr, "Message sending to client %s failed\n", *(const char **)a1);
goto LABEL_19;
}
}
fprintf(stderr, "error: error sending message to client: %s\n", *(const char **)a1);
client_mesg_send(v6[1], 5LL, 0LL, "error sending message", 0LL);
goto LABEL_5;
}
print_error("memory allocation error");
}
return 0LL;
}

original_code:
void* client_send_worker(void *data) {
  client_item_t *cl = (client_item_t *) data;
  unsigned int msg_id = 0;
  pthread_detach(cl->send_thread);
  queue_item_t *item;
  while (cl != ((void *)0) && (item = queue_pop(&cl->queue))) {
    int tp, i;
    int received = 0;
    char *message = add_sender(item->sender->name, item->msg);
    if (message == ((void *)0)) {
      print_error("memory allocation error");
      break;
    }
    for (i = 0; !received && i < 10; i++) {
      if (client_mesg_send(cl, item->msg->type, msg_id, message, g_fail) < 1) {
        fprintf(stderr, "error: ""error sending message to client: %s\n", cl->name);
        client_mesg_send(item->sender, 5, 0, "error sending message", 0);
        break;
      }
      printf("Sending message to client %s (%d)\n", cl->name, msg_id);
      int j;
      message_t *msg = ((void *)0);
      for (j = 0; !received && j < 5; j++) {
        tp = client_mesg_peek(cl);
        if (tp == 4) {
          if (client_mesg_recv(cl, &msg) > 0) {
            printf("Confirmation of message of id: %d received\n", msg->id);
            if (msg->id == msg_id) {
              received = 1;
            }
          } else {
            print_error("error receiving messsage from client");
          }
          free_message(msg);
        } else {
          usleep(200000);
        }
      }
    }
    if (!received) {
      client_mesg_send(item->sender, 5, item->msg->id, "Message sending failed", 0);
      fprintf(stderr, "Message sending to client %s failed\n", cl->name);
    }
    free_queue_item(item);
    free(message);
    msg_id++;
  }
  return ((void *)0);
}

canonical_original_code:
void *client_send_worker(void *data) {
  struct __client_item_s *cl = (client_item_t *) data;
  unsigned int msg_id = 0;
  pthread_detach(cl->send_thread);
  struct __queue_item_s *item;
  while (cl != ((void *)0) && (item = queue_pop(&cl->queue))) {
    int tp; int i;
    int received = 0;
    char *message = add_sender(item->sender->name, item->msg);
    if (message == ((void *)0)) {
      print_error("memory allocation error");
      break;
    }
    for (i = 0; !received && i < 10; i++) {
      if (client_mesg_send(cl, item->msg->type, msg_id, message, g_fail) < 1) {
        fprintf(stderr, "error: ""error sending message to client: %s\n", cl->name);
        client_mesg_send(item->sender, 5, 0, "error sending message", 0);
        break;
      }
      printf("Sending message to client %s (%d)\n", cl->name, msg_id);
      int j;
      struct __message_s *msg = ((void *)0);
      for (j = 0; !received && j < 5; j++) {
        tp = client_mesg_peek(cl);
        if (tp == 4) {
          if (client_mesg_recv(cl, &msg) > 0) {
            printf("Confirmation of message of id: %d received\n", msg->id);
            if (msg->id == msg_id) {
              received = 1;
            }
          } else {
            print_error("error receiving messsage from client");
          }
          free_message(msg);
        } else {
          usleep(200000);
        }
      }
    }
    if (!received) {
      client_mesg_send(item->sender, 5, item->msg->id, "Message sending failed", 0);
      fprintf(stderr, "Message sending to client %s failed\n", cl->name);
    }
    free_queue_item(item);
    free(message);
    msg_id++;
  }
  return ((void *)0);
}

variable_types: struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s *sender; struct __queue_item_s *next; } *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *

variable_types: struct __queue_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *msg; struct __client_item_s { char *name; int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; unsigned long recv_thread; unsigned long send_thread; struct __client_queue_s { struct __queue_item_s *start; struct __queue_item_s *end; union pthread_mutex_t queue_mx; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } queue_cond; } queue; struct __client_item_s *next; } *sender; struct __queue_item_s *next; } *

variable_types: tp int

variable_types: received int

variable_types: j int


decompiled_code:
void __fastcall mesg_free(void *a1)
{
if ( a1 )
free(a1);
}

canonical_decompiled_code:
void __fastcall func0(void *a1)
{
if ( a1 )
free(a1);
}

original_code:
void mesg_free(mesg_item_t *mesg) {
 if (mesg != ((void *)0)) {
  if (mesg->mesg != ((void *)0)) {
  }
  free(mesg);
 }
}

canonical_original_code:
void mesg_free(struct __mesg_item_s *mesg) {
 if (mesg != ((void *)0)) {
  if (mesg->mesg != ((void *)0)) {
  }
  free(mesg);
 }
}

variable_types: struct __mesg_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *mesg; struct __mesg_item_s *next; } *


decompiled_code:
int __fastcall mesg_remove_first(__int64 a1)
{
_QWORD *v2; // rdi

pthread_mutex_lock(*(pthread_mutex_t **)(a1 + 16));
v2 = *(_QWORD **)a1;
if ( *(_QWORD *)a1 == *(_QWORD *)(a1 + 8) )
{
mesg_free(v2);
*(_QWORD *)a1 = 0LL;
*(_QWORD *)(a1 + 8) = 0LL;
}
else
{
*(_QWORD *)a1 = v2[1];
mesg_free(v2);
}
return pthread_mutex_unlock(*(pthread_mutex_t **)(a1 + 16));
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1)
{
_QWORD *v2; // rdi

pthread_mutex_lock(*(pthread_mutex_t **)(a1 + 16));
v2 = *(_QWORD **)a1;
if ( *(_QWORD *)a1 == *(_QWORD *)(a1 + 8) )
{
func0(v2);
*(_QWORD *)a1 = 0LL;
*(_QWORD *)(a1 + 8) = 0LL;
}
else
{
*(_QWORD *)a1 = v2[1];
func0(v2);
}
return pthread_mutex_unlock(*(pthread_mutex_t **)(a1 + 16));
}

original_code:
void mesg_remove_first(mesg_list_t *list) {
 mesg_item_t *first;
 pthread_mutex_lock(list->mesg_mutex);
 if (list->start == list->end) {
  mesg_free(list->start);
  list->start = ((void *)0);
  list->end = ((void *)0);
 } else {
  first = list->start;
  list->start = first->next;
  mesg_free(first);
 }
 pthread_mutex_unlock(list->mesg_mutex);
}

canonical_original_code:
void mesg_remove_first(struct __mesg_list_s *list) {
 struct __mesg_item_s *first;
 pthread_mutex_lock(list->mesg_mutex);
 if (list->start == list->end) {
  mesg_free(list->start);
  list->start = ((void *)0);
  list->end = ((void *)0);
 } else {
  first = list->start;
  list->start = first->next;
  mesg_free(first);
 }
 pthread_mutex_unlock(list->mesg_mutex);
}


decompiled_code:
__int64 __fastcall server_mesg_send(unsigned int *a1, unsigned __int8 a2, unsigned int a3, __int64 a4, unsigned int a5)
{
unsigned int v8; // ebx

pthread_mutex_lock((pthread_mutex_t *)(a1 + 2));
v8 = mesg_send(*a1, a2, a3, a4, a5);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 2));
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int *a1, unsigned __int8 a2, unsigned int a3, __int64 a4, unsigned int a5)
{
unsigned int v8; // ebx

pthread_mutex_lock((pthread_mutex_t *)(a1 + 2));
v8 = mesg_send(*a1, a2, a3, a4, a5);
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 2));
return v8;
}

original_code:
int server_mesg_send(server_socket_t *server_socket, uint_8 type, uint_32 id,
    const char *msg, int can_fail) {
 pthread_mutex_lock(&(server_socket->sock_w_lock));
 int ret = mesg_send(server_socket->socket, type, id, msg, can_fail);
 pthread_mutex_unlock(&(server_socket->sock_w_lock));
 return ret;
}

canonical_original_code:
int server_mesg_send(struct __server_socket_s *server_socket, unsigned char type, unsigned int id, char *msg, int can_fail) {
 pthread_mutex_lock(&(server_socket->sock_w_lock));
 int ret = mesg_send(server_socket->socket, type, id, msg, can_fail);
 pthread_mutex_unlock(&(server_socket->sock_w_lock));
 return ret;
}

variable_types: struct __server_socket_s { int socket; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } sock_w_lock; union pthread_mutex_t sock_r_lock; } *

variable_types:
id
unsigned int

variable_types:
msg
char *

variable_types: ret int


login

decompiled_code:
__int64 __fastcall login(__int64 a1, _BYTE *a2)
{
_DWORD *v3; // rax
_DWORD *v4; // rsi
int v5; // eax

v3 = calloc(1uLL, 0x18uLL);
if ( !v3 )
{
print_error("memory allocation error");
exit(1);
}
v4 = v3;
*(_BYTE *)v3 = 1;
v3[1] = 0;
*((_QWORD *)v3 + 1) = a2;
if ( *a2 )
{
v5 = 0;
do
{
++a2;
++v5;
}
while ( *a2 );
}
else
{
v5 = 0;
}
*((_QWORD *)v4 + 2) = v5 + 1;
return mesg_add(a1);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, _BYTE *a2)
{
_DWORD *v3; // rax
_DWORD *v4; // rsi
int v5; // eax

v3 = calloc(1uLL, 0x18uLL);
if ( !v3 )
{
print_error("memory allocation error");
exit(1);
}
v4 = v3;
*(_BYTE *)v3 = 1;
v3[1] = 0;
*((_QWORD *)v3 + 1) = a2;
if ( *a2 )
{
v5 = 0;
do
{
++a2;
++v5;
}
while ( *a2 );
}
else
{
v5 = 0;
}
*((_QWORD *)v4 + 2) = v5 + 1;
return mesg_add(a1);
}

original_code:
void login(mesg_list_t *mesg_list, const char* name) {
 message_t* login_msg;
 if ((login_msg = (message_t *) calloc(1, sizeof(message_t))) == ((void *)0)) {
  print_error("memory allocation error");
  exit(1);
 }
 login_msg->type = 1;
 login_msg->id = 0;
 login_msg->text = (char *)name;
  int len = 0;
  while (*name != 0) {
   name++;
   len++;
  }
 login_msg->text_len = len+1;
 mesg_add(mesg_list, login_msg);
}

canonical_original_code:
void login(struct __mesg_list_s *mesg_list, char *name) {
 struct __message_s *login_msg;
 if ((login_msg = (struct __message_s *) calloc(1, sizeof(message_t))) == ((void *)0)) {
  print_error("memory allocation error");
  exit(1);
 }
 login_msg->type = 1;
 login_msg->id = 0;
 login_msg->text = (char *)name;
  int len = 0;
  while (*name != 0) {
   name++;
   len++;
  }
 login_msg->text_len = len+1;
 mesg_add(mesg_list, login_msg);
}

variable_types: struct __mesg_list_s { struct __mesg_item_s { struct __message_s { unsigned char type; unsigned int id; char *text; unsigned long text_len; } *mesg; struct __mesg_item_s *next; } *start; struct __mesg_item_s *end; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *mesg_mutex; } *

variable_types:
name
char *


clean

decompiled_code:
int clean()
{
int result; // eax

if ( !cleaned )
{
cleaned = 1;
puts("Terminating...");
pthread_mutex_lock(mutex);
pthread_cancel(recv_thread);
pthread_cancel(send_thread);
pthread_cancel(terminal_thread);
puts("Disconnecting from server...");
send_disconnect_message(server_socket);
close(*(_DWORD *)server_socket);
result = pthread_mutex_unlock(mutex);
}
return result;
}

canonical_decompiled_code:
int func1()
{
int result; // eax

if ( !cleaned )
{
cleaned = 1;
puts("Terminating...");
pthread_mutex_lock(mutex);
pthread_cancel(recv_thread);
pthread_cancel(send_thread);
pthread_cancel(terminal_thread);
puts("Disconnecting from server...");
send_disconnect_message(server_socket);
close(*(_DWORD *)server_socket);
result = pthread_mutex_unlock(mutex);
}
return result;
}

original_code:
void clean() {
 if(cleaned) {
  return;
 }
 cleaned = 1;
 printf("Terminating...\n");
 pthread_mutex_lock(mesg_list.mesg_mutex);
 pthread_cancel(recv_thread);
 pthread_cancel(send_thread);
 pthread_cancel(terminal_thread);
 printf("Disconnecting from server...\n");
 send_disconnect_message(server_socket);
 close(server_socket->socket);
 pthread_mutex_unlock(mesg_list.mesg_mutex);
}