decompiled_code:
__int64 __fastcall is_cmd(char *s1)
{
__int64 v1; // rax
char v2; // dl
size_t v3; // r12
const char **v4; // rbx

if ( (*s1 & 0xDF) != 0 )
{
v1 = 1LL;
do
{
v2 = s1[v1];
v3 = v1++;
}
while ( (v2 & 0xDF) != 0 );
}
else
{
v3 = 0LL;
}
v4 = (const char **)cmd_list;
while ( strncmp(s1, *v4, v3) )
{
v4 += 3;
if ( (const char **)(unsigned int)((_DWORD)cmd_list + 144) == v4 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(char *s1)
{
__int64 v1; // rax
char v2; // dl
size_t v3; // r12
const char **v4; // rbx

if ( (*s1 & 0xDF) != 0 )
{
v1 = 1LL;
do
{
v2 = s1[v1];
v3 = v1++;
}
while ( (v2 & 0xDF) != 0 );
}
else
{
v3 = 0LL;
}
v4 = (const char **)cmd_list;
while ( strncmp(s1, *v4, v3) )
{
v4 += 3;
if ( (const char **)(unsigned int)((_DWORD)cmd_list + 144) == v4 )
return 0LL;
}
return 1LL;
}

original_code:
static int is_cmd(const char *cmd)
{
 int i, j;
 for (i = 0; cmd[i] != ' ' && cmd[i] != '\0'; i++);
 for (j = 0; j < sizeof(cmd_list) / sizeof(cmd_list[0]); j++) {
  if (!strncmp(cmd, cmd_list[j].name, i))
   return 1;
 }
 return 0;
}

canonical_original_code:
static int is_cmd(char *cmd)
{
 int i; int j;
 for (i = 0; cmd[i] != ' ' && cmd[i] != '\0'; i++);
 for (j = 0; j < sizeof(cmd_list) / sizeof(cmd_list[0]); j++) {
  if (!strncmp(cmd, cmd_list[j].name, i))
   return 1;
 }
 return 0;
}

variable_types:
cmd
char *

variable_types: j int


repo: Jery-Mong/flyfile

decompiled_code:
__int64 __fastcall wait_file_ack(__int64 a1)
{
unsigned int v1; // ebx
__int64 result; // rax

v1 = 10;
while ( 1 )
{
sleep(1u);
m_printf("%d ", v1);
result = *(unsigned int *)(a1 + 40);
if ( (_DWORD)result == 1 )
break;
if ( !--v1 )
{
*(_DWORD *)(a1 + 40) = 0;
return result;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
unsigned int v1; // ebx
__int64 result; // rax

v1 = 10;
while ( 1 )
{
sleep(1u);
m_printf("%d ", v1);
result = *(unsigned int *)(a1 + 40);
if ( (_DWORD)result == 1 )
break;
if ( !--v1 )
{
*(_DWORD *)(a1 + 40) = 0;
return result;
}
}
return result;
}

original_code:
void wait_file_ack(struct peer *pr)
{
 int i;
 for (i = 10; i > 0; i--) {
  sleep(1);
  m_printf("%d ", i);
  if (pr->file_rsq_stat == RSP_YES)
   return;
 }
 pr->file_rsq_stat = RSP_NO;
}

variable_types: struct peer { int idnum; struct base_inf { char name[32]; unsigned int ip; } id; int file_rsq_stat; int chat_rsq_stat; } *

variable_types: i int

return_type: void

user_defined_types: struct peer { int idnum; struct base_inf id; int file_rsq_stat; int chat_rsq_stat; }


decompiled_code:
char *__fastcall get_filename(char *dest, char *src)
{
char *v2; // rax
char *result; // rax

v2 = strrchr(src, 47);
if ( v2 )
result = strcpy(dest, v2 + 1);
else
result = strcpy(dest, src);
return result;
}

canonical_decompiled_code:
char *__fastcall func9(char *dest, char *src)
{
char *v2; // rax
char *result; // rax

v2 = strrchr(src, 47);
if ( v2 )
result = strcpy(dest, v2 + 1);
else
result = strcpy(dest, src);
return result;
}

original_code:
void get_filename(char *buf, char *path)
{
 char *p;
 p = strrchr(path, '/');
 if (p == ((void *)0))
  strcpy(buf, path);
 else
  strcpy(buf, p + 1);
}

variable_types:
buf
char *

variable_types:
path
char *

variable_types:
p
char *


decompiled_code:
__int64 __fastcall cmd_send(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rbx
unsigned int v3; // ebp
int v5; // er13
int v6; // ebx
int v7; // [rsp+0h] [rbp-128h] BYREF
__m128i v8; // [rsp+4h] [rbp-124h]
__m128i v9; // [rsp+14h] [rbp-114h]
int v10; // [rsp+24h] [rbp-104h]
char dest[64]; // [rsp+28h] [rbp-100h] BYREF
int v12; // [rsp+68h] [rbp-C0h]
struct stat v13; // [rsp+70h] [rbp-B8h] BYREF

v1 = getpeerbyidnum(*(_QWORD *)(a1 + 8));
if ( v1 && (v2 = v1, (v3 = stat(*(const char **)(a1 + 16), &v13)) == 0) )
{
v7 = 2;
v8 = _mm_loadu_si128(self);
v9 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v10 = *(_DWORD *)(self + 32LL);
get_filename(dest, *(char **)(a1 + 16));
v12 = v13.st_size;
v5 = getsockfd(4LL, v2);
send(v5, &v7, 0x6CuLL, 0);
close(v5);
wait_file_ack(v2);
if ( *(_DWORD *)(v2 + 40) && (v6 = getsockfd(1LL, v2), v6 >= 0) )
{
*(_DWORD *)(self + 48LL) = 0;
send_file((unsigned int)v6, *(_QWORD *)(a1 + 16));
*(_DWORD *)(self + 48LL) = 1;
close(v6);
v3 = 1;
}
else
{
m_printf("rejected\n");
}
}
else
{
m_printf("Invalid\n");
v3 = 0;
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rbx
unsigned int v3; // ebp
int v5; // er13
int v6; // ebx
int v7; // [rsp+0h] [rbp-128h] BYREF
__m128i v8; // [rsp+4h] [rbp-124h]
__m128i v9; // [rsp+14h] [rbp-114h]
int v10; // [rsp+24h] [rbp-104h]
char dest[64]; // [rsp+28h] [rbp-100h] BYREF
int v12; // [rsp+68h] [rbp-C0h]
struct stat v13; // [rsp+70h] [rbp-B8h] BYREF

v1 = getpeerbyidnum(*(_QWORD *)(a1 + 8));
if ( v1 && (v2 = v1, (v3 = stat(*(const char **)(a1 + 16), &v13)) == 0) )
{
v7 = 2;
v8 = _mm_loadu_si128(self);
v9 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v10 = *(_DWORD *)(self + 32LL);
func9(dest, *(char **)(a1 + 16));
v12 = v13.st_size;
v5 = getsockfd(4LL, v2);
send(v5, &v7, 0x6CuLL, 0);
close(v5);
func8(v2);
if ( *(_DWORD *)(v2 + 40) && (v6 = getsockfd(1LL, v2), v6 >= 0) )
{
*(_DWORD *)(self + 48LL) = 0;
send_file((unsigned int)v6, *(_QWORD *)(a1 + 16));
*(_DWORD *)(self + 48LL) = 1;
close(v6);
v3 = 1;
}
else
{
m_printf("rejected\n");
}
}
else
{
m_printf("Invalid\n");
v3 = 0;
}
return v3;
}

original_code:
int cmd_send(char **cmd)
{
 struct peer *pr = getpeerbyidnum(cmd[1]);
 if (pr == ((void *)0))
  goto err;
 struct stat st;
 if (stat(cmd[2], &st))
  goto err;
 struct message msg;
 msg.type = MSG_FILE_RQST;
 memcpy(&msg.id, &self->id, sizeof(struct base_inf));
 get_filename(msg.mdata.m_file.fname, cmd[2]);
 msg.mdata.m_file.fsize = st.st_size;
 int fd = getsockfd(FD_SENDMSG, pr);
 send(fd, &msg, sizeof(msg), 0);
 close(fd);
 wait_file_ack(pr);
 if (pr->file_rsq_stat == RSP_NO)
  goto out;
 fd = getsockfd(FD_DATA_SEND, pr);
 if (fd < 0)
  goto out;
 self->file_status = FILE_BUSY;
 send_file(fd, cmd[2]);
 self->file_status = FILE_AVAL;
 close(fd);
 return 1;
err:
 m_printf("Invalid\n");
 return 0;
out:
 m_printf("rejected\n");
 return 0;
}

variable_types:
cmd
char **

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

variable_types: struct message { int type; struct base_inf { char name[32]; unsigned int ip; } id; union { int m_answer; struct file_inf { char fname[64]; unsigned int fsize; } m_file; char m_news[64]; char m_chat[64]; } mdata; }

variable_types: fd int

return_type: int

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

user_defined_types: struct message { int type; struct base_inf id; union { int m_answer; struct file_inf m_file; char m_news[64]; char m_chat[64]; } mdata; }


original_code:
char **cmdstr_to_list(char *raw_cmd)
{
 int i;
 for (i = 0; raw_cmd[i] == ' '; i++);
 raw_cmd += i;
 if (*raw_cmd == '\0')
  goto out2;
 char **args_list = (char **)malloc(sizeof(char **) * 16);
 memset(args_list, 0, sizeof(char **) * 8);
 if (!is_cmd(raw_cmd))
  goto out1;
 int k = 0;
 for (;;) {
  for (i = 0; raw_cmd[i] != ' ' && raw_cmd[i] != '\0'; i++);
  args_list[k] = (char *)malloc(i + 1);
  strncpy(args_list[k], raw_cmd, i);
  args_list[k][i] = '\0';
  raw_cmd += i;
  for (; *raw_cmd == ' '; raw_cmd++);
  if (*raw_cmd == '\0')
   return args_list;
  k++;
 }
out1:
 free(args_list);
out2:
 return ((void *)0);
}

variable_types: k int

return_type: char **


decompiled_code:
__int64 __fastcall cmd_handler(void **a1)
{
const char *v1; // r12
__int64 v2; // rbx
unsigned int v3; // ebp

v1 = (const char *)*a1;
v2 = 0LL;
while ( 1 )
{
v3 = strcmp(v1, cmd_list[3 * v2]);
if ( !v3 )
break;
if ( ++v2 == 6 )
return (unsigned int)-1;
}
((void (__fastcall *)(void **))cmd_list[3 * (int)v2 + 2])(a1);
free_cmd(a1);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func12(void **a1)
{
const char *v1; // r12
__int64 v2; // rbx
unsigned int v3; // ebp

v1 = (const char *)*a1;
v2 = 0LL;
while ( 1 )
{
v3 = strcmp(v1, cmd_list[3 * v2]);
if ( !v3 )
break;
if ( ++v2 == 6 )
return (unsigned int)-1;
}
((void (__fastcall *)(void **))cmd_list[3 * (int)v2 + 2])(a1);
func6(a1);
return v3;
}

original_code:
int cmd_handler(char **cmd)
{
 int i;
 for (i = 0; i < sizeof(cmd_list) / sizeof(cmd_list[0]); i++)
  if (!strcmp(cmd[0], cmd_list[i].name)) {
   cmd_list[i].cmd_func(cmd);
   free_cmd(cmd);
   return 0;
  }
 return -1;
}


main

canonical_name: main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

global_init(argc, argv, envp);
pthread_create(newthread, 0LL, (void *(*)(void *))&recv_msg, 0LL);
bcast_online();
while ( 1 )
main_wind();
}

original_code:
int main()
{
 pthread_t tid1;
 global_init();
 pthread_create(&tid1, ((void *)0), recv_msg, ((void *)0));
 bcast_online();
 while(1)
  main_wind();
}

canonical_original_code:
int main()
{
 unsigned long tid1;
 global_init();
 pthread_create(&tid1, ((void *)0), recv_msg, ((void *)0));
 bcast_online();
 while(1)
  main_wind();
}


decompiled_code:
void sig_do_nothing()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
static void sig_do_nothing(int signo)
{
}

variable_types: signo int


decompiled_code:
__int64 __fastcall popwin_getrsp(__int64 a1)
{
signal(10, (__sighandler_t)sig_do_nothing);
display_popinf(a1);
pop_flag = 1;
pause();
return (unsigned int)dword_6E8;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
signal(10, (__sighandler_t)sig_do_nothing);
func1(a1);
pop_flag = 1;
pause();
return (unsigned int)dword_6E8;
}

original_code:
int popwin_getrsp(void *data)
{
 signal(10, sig_do_nothing);
 display_popinf((struct message *)data);
 pop_flag = 1;
 pause();
 int ret = rsp;
 return ret;
}

variable_types:
data
void *

variable_types: ret int

user_defined_types: struct base_inf { char name[32]; unsigned int ip; }

user_defined_types: struct file_inf { char fname[64]; unsigned int fsize; }


decompiled_code:
int winds_quit()
{
del_panel(pn_inf);
del_panel(pn_main);
del_panel(pn_prgs);
return endwin();
}

canonical_decompiled_code:
int func8()
{
del_panel(pn_inf);
del_panel(pn_main);
del_panel(pn_prgs);
return endwin();
}

original_code:
void winds_quit()
{
 del_panel(pn_inf);
 del_panel(pn_main);
 del_panel(pn_prgs);
 endwin();
}


decompiled_code:
__int64 global_init()
{
_QWORD *v0; // rax

v0 = malloc(0x38uLL);
self = v0;
*v0 = 0LL;
v0[1] = 0LL;
v0[2] = 0LL;
v0[3] = 0LL;
v0[4] = 0LL;
v0[5] = 0LL;
v0[6] = 0LL;
*((_DWORD *)v0 + 12) = 1;
gethostname((char *)v0, 0x20uLL);
get_local_ipinf(self + 32LL, self + 36LL);
if ( !*(_DWORD *)(self + 32LL) )
{
puts("error: you don't seem to have connected to LAN, please check your network");
exit(1);
}
peer_list = malloc(0x10uLL);
list_init(peer_list);
return winds_init();
}

canonical_decompiled_code:
__int64 func2()
{
_QWORD *v0; // rax

v0 = malloc(0x38uLL);
self = v0;
*v0 = 0LL;
v0[1] = 0LL;
v0[2] = 0LL;
v0[3] = 0LL;
v0[4] = 0LL;
v0[5] = 0LL;
v0[6] = 0LL;
*((_DWORD *)v0 + 12) = 1;
gethostname((char *)v0, 0x20uLL);
get_local_ipinf(self + 32LL, self + 36LL);
if ( !*(_DWORD *)(self + 32LL) )
{
puts("error: you don't seem to have connected to LAN, please check your network");
exit(1);
}
peer_list = malloc(0x10uLL);
list_init(peer_list);
return winds_init();
}

original_code:
void global_init()
{
 self = (struct host *)malloc(sizeof(struct host));
 memset(self, 0, sizeof(struct host));
 self->file_status = FILE_AVAL;
 gethostname(self->id.name, 32);
 get_local_ipinf(&(self->id.ip), &self->bcastaddr);
 if (!self->id.ip) {
  printf("error: you don't seem to have connected to LAN, please check your network\n");
  exit(1);
 }
 peer_list = (list_t *)malloc(sizeof(list_t));
 list_init(peer_list);
 winds_init();
}

canonical_original_code:
void global_init()
{
 self = (struct host *)malloc(sizeof(struct host));
 memset(self, 0, sizeof(struct host));
 self->file_status = FILE_AVAL;
 gethostname(self->id.name, 32);
 get_local_ipinf(&(self->id.ip), &self->bcastaddr);
 if (!self->id.ip) {
  printf("error: you don't seem to have connected to LAN, please check your network\n");
  exit(1);
 }
 peer_list = (struct list *)malloc(sizeof(list_t));
 list_init(peer_list);
 winds_init();
}

user_defined_types: struct host { struct base_inf id; unsigned int bcastaddr; unsigned long msg_handler_thr; int file_status; }

user_defined_types: struct list { int node_cnt; struct list_node *head; }

user_defined_types: struct list_node { void *data; struct list_node *prev; struct list_node *next; }


getpeerbyid

decompiled_code:
__int64 __fastcall getpeerbyid(__int64 a1)
{
_QWORD *v1; // rcx
_QWORD *v2; // rax
__int64 v3; // rdx

v1 = *(_QWORD **)(peer_list + 8LL);
v2 = (_QWORD *)v1[2];
if ( v1 == v2 )
return 0LL;
while ( 1 )
{
v3 = *v2;
if ( *(_DWORD *)(a1 + 32) == *(_DWORD *)(*v2 + 36LL) )
break;
v2 = (_QWORD *)v2[2];
if ( v1 == v2 )
return 0LL;
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
_QWORD *v1; // rcx
_QWORD *v2; // rax
__int64 v3; // rdx

v1 = *(_QWORD **)(peer_list + 8LL);
v2 = (_QWORD *)v1[2];
if ( v1 == v2 )
return 0LL;
while ( 1 )
{
v3 = *v2;
if ( *(_DWORD *)(a1 + 32) == *(_DWORD *)(*v2 + 36LL) )
break;
v2 = (_QWORD *)v2[2];
if ( v1 == v2 )
return 0LL;
}
return v3;
}

original_code:
struct peer *getpeerbyid(struct base_inf *id)
{
 node_t *iter;
 for(iter = (peer_list)->head->next; iter != (peer_list)->head ; iter = iter->next) {
  if (id->ip == ((struct peer *)(iter->data))->id.ip)
   return iter->data;
 }
 return ((void *)0);
}

canonical_original_code:
struct peer *getpeerbyid(struct base_inf *id)
{
 struct list_node *iter;
 for(iter = (peer_list)->head->next; iter != (peer_list)->head ; iter = iter->next) {
  if (id->ip == ((struct peer *)(iter->data))->id.ip)
   return iter->data;
 }
 return ((void *)0);
}

variable_types:
id
struct base_inf *

variable_types: struct list_node { void *data; struct list_node *prev; struct list_node *next; } *

return_type: struct peer { int idnum; struct base_inf { char name[32]; unsigned int ip; } id; int file_rsq_stat; int chat_rsq_stat; } *


decompiled_code:
void __fastcall peer_outlist(__int64 a1)
{
__int64 v1; // rax
void *v2; // rbx

v1 = getpeerbyid(a1 + 4);
if ( v1 )
{
v2 = (void *)v1;
list_del_node(peer_list, v1);
free(v2);
}
}

canonical_decompiled_code:
void __fastcall func5(__int64 a1)
{
__int64 v1; // rax
void *v2; // rbx

v1 = func3(a1 + 4);
if ( v1 )
{
v2 = (void *)v1;
list_del_node(peer_list, v1);
free(v2);
}
}

original_code:
void peer_outlist(struct message *msg)
{
 struct peer *pr = getpeerbyid(&msg->id);
 if (pr == ((void *)0))
  return;
 list_del_node(peer_list, pr);
 free(pr);
}

variable_types: struct message { int type; struct base_inf { char name[32]; unsigned int ip; } id; union { int m_answer; struct file_inf { char fname[64]; unsigned int fsize; } m_file; char m_news[64]; char m_chat[64]; } mdata; } *


decompiled_code:
void __fastcall respond_rqst(void *ptr)
{
__int64 v1; // rax
__int64 v2; // rbp
int v3; // er12
int v4; // er13
int v5; // ebp
int v6; // [rsp+0h] [rbp-98h] BYREF
__m128i v7; // [rsp+4h] [rbp-94h]
__m128i v8; // [rsp+14h] [rbp-84h]
int v9; // [rsp+24h] [rbp-74h]
int v10; // [rsp+28h] [rbp-70h]

v1 = getpeerbyid((__int64)ptr + 4);
if ( v1 )
{
v2 = v1;
if ( *(_DWORD *)(self + 48LL) )
{
v3 = popwin_getrsp(ptr);
v6 = 2 * (*(_DWORD *)ptr != 2) + 3;
v7 = _mm_loadu_si128(self);
v8 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v9 = *(_DWORD *)(self + 32LL);
v10 = v3;
v4 = getsockfd(4LL, v2);
send(v4, &v6, 0x6CuLL, 0);
close(v4);
if ( v3 )
m_printf("You Answer Is [Yes]\n");
else
m_printf("You Answer Is [No]\n");
if ( *(_DWORD *)ptr == 4 )
{
*(_DWORD *)(v2 + 44) = v3;
}
else
{
v5 = getsockfd(2LL, v2);
if ( v5 >= 0 )
{
*(_DWORD *)(self + 48LL) = 0;
recv_file((unsigned int)v5, (char *)ptr + 40);
*(_DWORD *)(self + 48LL) = 1;
close(v5);
}
}
free(ptr);
}
}
}

canonical_decompiled_code:
void __fastcall func6(void *ptr)
{
__int64 v1; // rax
__int64 v2; // rbp
int v3; // er12
int v4; // er13
int v5; // ebp
int v6; // [rsp+0h] [rbp-98h] BYREF
__m128i v7; // [rsp+4h] [rbp-94h]
__m128i v8; // [rsp+14h] [rbp-84h]
int v9; // [rsp+24h] [rbp-74h]
int v10; // [rsp+28h] [rbp-70h]

v1 = func3((__int64)ptr + 4);
if ( v1 )
{
v2 = v1;
if ( *(_DWORD *)(self + 48LL) )
{
v3 = popwin_getrsp(ptr);
v6 = 2 * (*(_DWORD *)ptr != 2) + 3;
v7 = _mm_loadu_si128(self);
v8 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v9 = *(_DWORD *)(self + 32LL);
v10 = v3;
v4 = getsockfd(4LL, v2);
send(v4, &v6, 0x6CuLL, 0);
close(v4);
if ( v3 )
m_printf("You Answer Is [Yes]\n");
else
m_printf("You Answer Is [No]\n");
if ( *(_DWORD *)ptr == 4 )
{
*(_DWORD *)(v2 + 44) = v3;
}
else
{
v5 = getsockfd(2LL, v2);
if ( v5 >= 0 )
{
*(_DWORD *)(self + 48LL) = 0;
recv_file((unsigned int)v5, (char *)ptr + 40);
*(_DWORD *)(self + 48LL) = 1;
close(v5);
}
}
free(ptr);
}
}
}

original_code:
void respond_rqst(struct message *msg)
{
 struct peer *pr;
 int rsp;
 struct message r_msg;
 if ((pr = getpeerbyid(&msg->id)) == ((void *)0))
  return;
 if (self->file_status == FILE_BUSY)
  return;
 else
  rsp = popwin_getrsp(msg);
 if (msg->type == MSG_FILE_RQST)
  r_msg.type = MSG_FILE_ACK;
 else
  r_msg.type = MSG_CHAT_ACK;
 memcpy(&r_msg.id, &self->id, sizeof(struct base_inf));
 r_msg.mdata.m_answer = rsp;
 int fd = getsockfd(FD_SENDMSG, pr);
 send(fd, &r_msg, sizeof(struct message), 0);
 close(fd);
 if (rsp == RSP_NO)
  m_printf("You Answer Is [No]\n");
 else
  m_printf("You Answer Is [Yes]\n");
 if (msg->type == MSG_CHAT_RQST) {
  pr->chat_rsq_stat = rsp;
  goto out;
 }
 fd = getsockfd(FD_DATA_RECV, pr);
 if (fd < 0)
  goto out;
 self->file_status = FILE_BUSY;
 recv_file(fd, &msg->mdata.m_file);
 self->file_status = FILE_AVAL;
 close(fd);
out:
 free(msg);
}

variable_types: rsp int


decompiled_code:
__int64 __fastcall handle_ack(_DWORD *a1)
{
__int64 result; // rax

result = getpeerbyid((__int64)(a1 + 1));
if ( result )
{
if ( *a1 == 3 )
*(_DWORD *)(result + 40) = a1[10];
else
*(_DWORD *)(result + 44) = a1[10];
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(_DWORD *a1)
{
__int64 result; // rax

result = func3((__int64)(a1 + 1));
if ( result )
{
if ( *a1 == 3 )
*(_DWORD *)(result + 40) = a1[10];
else
*(_DWORD *)(result + 44) = a1[10];
}
return result;
}

original_code:
void handle_ack(struct message *msg)
{
 struct peer *pr;
 if ((pr = getpeerbyid(&msg->id)) == ((void *)0))
  return;
 if (msg->type == MSG_FILE_ACK) {
  pr->file_rsq_stat = msg->mdata.m_answer;
 } else {
  pr->chat_rsq_stat = msg->mdata.m_answer;
 }
}

variable_types: struct peer { int idnum; struct base_inf { char name[32]; unsigned int ip; } id; int file_rsq_stat; int chat_rsq_stat; } *


decompiled_code:
void __fastcall chat_get_comment(void *ptr)
{
unsigned int *v1; // rax

v1 = (unsigned int *)getpeerbyid((__int64)ptr + 4);
if ( v1 && v1[11] )
print_chat_comment((char *)ptr + 4, *v1, (char *)ptr + 40);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func8(void *ptr)
{
unsigned int *v1; // rax

v1 = (unsigned int *)func3((__int64)ptr + 4);
if ( v1 && v1[11] )
print_chat_comment((char *)ptr + 4, *v1, (char *)ptr + 40);
free(ptr);
}

original_code:
void chat_get_comment(struct message *msg)
{
 struct peer *pr;
 if ((pr = getpeerbyid(&msg->id)) == ((void *)0))
  goto out;
 if (pr->chat_rsq_stat == RSP_NO)
  goto out;
 print_chat_comment(msg->id.name, pr->idnum, msg->mdata.m_chat);
out:
 free(msg);
}


getsockfd

decompiled_code:
__int64 __fastcall getsockfd(int a1, __int64 a2)
{
unsigned int v2; // er12
int v4; // ebx
int optval; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

addr.sa_family = 2;
switch ( a1 )
{
case 0:
case 4:
*(_WORD *)addr.sa_data = _bswap_16(3333);
v2 = socket(2, 2, 0);
if ( a1 )
{
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(a2 + 36);
}
else
{
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(self + 36LL);
optval = 1;
setsockopt(v2, 1, 6, &optval, 4u);
}
if ( connect(v2, &addr, 0x10u) < 0 )
v2 = -1;
break;
case 1:
*(_WORD *)addr.sa_data = _bswap_16(3334);
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(a2 + 36);
v2 = socket(2, 1, 0);
if ( connect(v2, &addr, 0x10u) < 0 )
v2 = -1;
break;
case 2:
*(_WORD *)addr.sa_data = _bswap_16(3334);
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(self + 32LL);
v4 = socket(2, 1, 0);
bind(v4, &addr, 0x10u);
listen(v4, 1);
v2 = accept(v4, 0LL, 0LL);
break;
case 3:
*(_WORD *)addr.sa_data = _bswap_16(3333);
*(_DWORD *)&addr.sa_data[2] = 0;
v2 = socket(2, 2, 0);
bind(v2, &addr, 0x10u);
break;
default:
v2 = -1;
break;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, __int64 a2)
{
unsigned int v2; // er12
int v4; // ebx
int optval; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

addr.sa_family = 2;
switch ( a1 )
{
case 0:
case 4:
*(_WORD *)addr.sa_data = func0(3333);
v2 = socket(2, 2, 0);
if ( a1 )
{
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(a2 + 36);
}
else
{
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(self + 36LL);
optval = 1;
setsockopt(v2, 1, 6, &optval, 4u);
}
if ( connect(v2, &addr, 0x10u) < 0 )
v2 = -1;
break;
case 1:
*(_WORD *)addr.sa_data = func0(3334);
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(a2 + 36);
v2 = socket(2, 1, 0);
if ( connect(v2, &addr, 0x10u) < 0 )
v2 = -1;
break;
case 2:
*(_WORD *)addr.sa_data = func0(3334);
*(_DWORD *)&addr.sa_data[2] = *(_DWORD *)(self + 32LL);
v4 = socket(2, 1, 0);
bind(v4, &addr, 0x10u);
listen(v4, 1);
v2 = accept(v4, 0LL, 0LL);
break;
case 3:
*(_WORD *)addr.sa_data = func0(3333);
*(_DWORD *)&addr.sa_data[2] = 0;
v2 = socket(2, 2, 0);
bind(v2, &addr, 0x10u);
break;
default:
v2 = -1;
break;
}
return v2;
}

original_code:
int getsockfd(int type, void *data)
{
 struct peer *pr = (struct peer *)data;
 int fd;
 struct sockaddr_in addr;
 addr.sin_family = 2;
 switch (type) {
 case FD_GETMSG:
  addr.sin_port = htons(3333);
  addr.sin_addr.s_addr = ((in_addr_t) 0x00000000);
  fd = socket(2, SOCK_DGRAM, 0);
  bind(fd, (struct sockaddr *)&addr, sizeof(addr));
  return fd;
 case FD_BROADCAST:
 case FD_SENDMSG:
  addr.sin_port = htons(3333);
  fd = socket(2, SOCK_DGRAM, 0);
  if (type == FD_BROADCAST) {
   addr.sin_addr.s_addr = self->bcastaddr;
   int broadcast = 1;
   setsockopt(fd, 1, 6, &broadcast, sizeof(int));
  } else {
   addr.sin_addr.s_addr = pr->id.ip;
  }
  if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
   return -1;
  return fd;
 case FD_DATA_SEND:
  addr.sin_port = htons(3334);
  addr.sin_addr.s_addr = pr->id.ip;
  fd = socket(2, SOCK_STREAM, 0);
  if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
   return -1;
  return fd;
 case FD_DATA_RECV:
  addr.sin_port = htons(3334);
  addr.sin_addr.s_addr = self->id.ip;
  fd = socket(2, SOCK_STREAM, 0);
  bind(fd, (struct sockaddr *)&addr, sizeof(addr));
  listen(fd, 1);
  return accept(fd, ((void *)0), ((void *)0));
 default:
  break;
 }
 return -1;
}

canonical_original_code:
int getsockfd(int type, void *data)
{
 struct peer *pr = (struct peer *)data;
 int fd;
 struct sockaddr_in addr;
 addr.sin_family = 2;
 switch (type) {
 case FD_GETMSG:
  addr.sin_port = htons(3333);
  addr.sin_addr.s_addr = ((unsigned int) 0x00000000);
  fd = socket(2, SOCK_DGRAM, 0);
  bind(fd, (struct sockaddr *)&addr, sizeof(addr));
  return fd;
 case FD_BROADCAST:
 case FD_SENDMSG:
  addr.sin_port = htons(3333);
  fd = socket(2, SOCK_DGRAM, 0);
  if (type == FD_BROADCAST) {
   addr.sin_addr.s_addr = self->bcastaddr;
   int broadcast = 1;
   setsockopt(fd, 1, 6, &broadcast, sizeof(int));
  } else {
   addr.sin_addr.s_addr = pr->id.ip;
  }
  if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
   return -1;
  return fd;
 case FD_DATA_SEND:
  addr.sin_port = htons(3334);
  addr.sin_addr.s_addr = pr->id.ip;
  fd = socket(2, SOCK_STREAM, 0);
  if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
   return -1;
  return fd;
 case FD_DATA_RECV:
  addr.sin_port = htons(3334);
  addr.sin_addr.s_addr = self->id.ip;
  fd = socket(2, SOCK_STREAM, 0);
  bind(fd, (struct sockaddr *)&addr, sizeof(addr));
  listen(fd, 1);
  return accept(fd, ((void *)0), ((void *)0));
 default:
  break;
 }
 return -1;
}

variable_types: type int

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

variable_types: broadcast int

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

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


decompiled_code:
int __fastcall bcast_status(int a1)
{
int v1; // ebx
int v3; // [rsp+0h] [rbp-88h] BYREF
__m128i v4; // [rsp+4h] [rbp-84h]
__m128i v5; // [rsp+14h] [rbp-74h]
int v6; // [rsp+24h] [rbp-64h]

v1 = getsockfd(0, 0LL);
v3 = a1;
v4 = _mm_loadu_si128(self);
v5 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v6 = *(_DWORD *)(self + 32LL);
send(v1, &v3, 0x6CuLL, 0);
return close(v1);
}

canonical_decompiled_code:
int __fastcall func2(int a1)
{
int v1; // ebx
int v3; // [rsp+0h] [rbp-88h] BYREF
__m128i v4; // [rsp+4h] [rbp-84h]
__m128i v5; // [rsp+14h] [rbp-74h]
int v6; // [rsp+24h] [rbp-64h]

v1 = func1(0, 0LL);
v3 = a1;
v4 = _mm_loadu_si128(self);
v5 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v6 = *(_DWORD *)(self + 32LL);
send(v1, &v3, 0x6CuLL, 0);
return close(v1);
}

original_code:
void bcast_status(int status)
{
 int fd = getsockfd(FD_BROADCAST, ((void *)0));
 struct message bmsg;
 bmsg.type = status;
 memcpy(&bmsg.id, &self->id, sizeof(struct base_inf));
 send(fd, &bmsg, sizeof(struct message), 0);
 close(fd);
}

variable_types: status int


decompiled_code:
int bcast_online()
{
return bcast_status(0);
}

canonical_decompiled_code:
int func3()
{
return func2(0);
}

original_code:
void bcast_online()
{
 bcast_status(MSG_ONLINE);
}


decompiled_code:
int bcast_offline()
{
return bcast_status(1);
}

canonical_decompiled_code:
int func4()
{
return func2(1);
}

original_code:
void bcast_offline()
{
 bcast_status(MSG_OFFLINE);
}


decompiled_code:
int __fastcall get_local_ipinf(int *a1, int *a2)
{
in_addr_t v2; // ebp
int v3; // er12
unsigned __int64 v4; // rdx
__int64 v5; // rbx
char *v6; // rcx
int result; // eax
int v8; // [rsp+0h] [rbp-38h] BYREF
char *v9; // [rsp+8h] [rbp-30h]

v2 = inet_addr("192.168.0.0");
v8 = 160;
v9 = (char *)malloc(0xA0uLL);
v3 = socket(2, 2, 0);
if ( ioctl(v3, 0x8912uLL, &v8) < 0 )
perror("ioctl");
v4 = v8 / 0x28uLL;
v5 = (__int64)v9;
if ( (int)v4 <= 0 )
return close(v3);
v6 = &v9[40 * (unsigned int)(v4 - 1) + 40];
while ( 1 )
{
result = *(_DWORD *)(v5 + 20);
if ( (result & v2) == v2 )
break;
v5 += 40LL;
if ( (char *)v5 == v6 )
return close(v3);
}
if ( a1 )
*a1 = result;
if ( a2 )
{
ioctl(v3, 0x8919uLL, v5, v6);
result = *(_DWORD *)(v5 + 20);
*a2 = result;
}
return result;
}

canonical_decompiled_code:
int __fastcall func5(int *a1, int *a2)
{
in_addr_t v2; // ebp
int v3; // er12
unsigned __int64 v4; // rdx
__int64 v5; // rbx
char *v6; // rcx
int result; // eax
int v8; // [rsp+0h] [rbp-38h] BYREF
char *v9; // [rsp+8h] [rbp-30h]

v2 = inet_addr("192.168.0.0");
v8 = 160;
v9 = (char *)malloc(0xA0uLL);
v3 = socket(2, 2, 0);
if ( ioctl(v3, 0x8912uLL, &v8) < 0 )
perror("ioctl");
v4 = v8 / 0x28uLL;
v5 = (__int64)v9;
if ( (int)v4 <= 0 )
return close(v3);
v6 = &v9[40 * (unsigned int)(v4 - 1) + 40];
while ( 1 )
{
result = *(_DWORD *)(v5 + 20);
if ( (result & v2) == v2 )
break;
v5 += 40LL;
if ( (char *)v5 == v6 )
return close(v3);
}
if ( a1 )
*a1 = result;
if ( a2 )
{
ioctl(v3, 0x8919uLL, v5, v6);
result = *(_DWORD *)(v5 + 20);
*a2 = result;
}
return result;
}

original_code:
void get_local_ipinf(void *lip, void *bip)
{
 int fd;
 in_addr_t ip;
 struct sockaddr_in *addr;
 in_addr_t mask = inet_addr("192.168.0.0");
 struct ifconf ifc;
 struct ifreq *ifr;
 ifc.ifc_len = sizeof(struct ifreq) * 4;
 ifc.ifc_ifcu.ifcu_req = (struct ifreq *)malloc(ifc.ifc_len);
 fd = socket(2, SOCK_DGRAM, 0);
 if (ioctl(fd, 0x8912, &ifc) < 0)
  perror("ioctl");
 int i = ifc.ifc_len / sizeof(struct ifreq);
 for (ifr = ifc.ifc_ifcu.ifcu_req; i > 0; i--) {
  addr = (struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr;
  ip = addr->sin_addr.s_addr;
  if ((ip & mask) == mask) {
   if (lip != ((void *)0))
    *(in_addr_t *)lip = ip;
   if (bip != ((void *)0)) {
    ioctl(fd, 0x8919, ifr);
    *(in_addr_t *)bip = (((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr).s_addr;
   }
   return;
  }
  ifr++;
 }
 close(fd);
}

canonical_original_code:
void get_local_ipinf(void *lip, void *bip)
{
 int fd;
 unsigned int ip;
 struct sockaddr_in *addr;
 unsigned int mask = inet_addr("192.168.0.0");
 struct ifconf ifc;
 struct ifreq *ifr;
 ifc.ifc_len = sizeof(struct ifreq) * 4;
 ifc.ifc_ifcu.ifcu_req = (struct ifreq *)malloc(ifc.ifc_len);
 fd = socket(2, SOCK_DGRAM, 0);
 if (ioctl(fd, 0x8912, &ifc) < 0)
  perror("ioctl");
 int i = ifc.ifc_len / sizeof(struct ifreq);
 for (ifr = ifc.ifc_ifcu.ifcu_req; i > 0; i--) {
  addr = (struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr;
  ip = addr->sin_addr.s_addr;
  if ((ip & mask) == mask) {
   if (lip != ((void *)0))
    *(unsigned int *)lip = ip;
   if (bip != ((void *)0)) {
    ioctl(fd, 0x8919, ifr);
    *(unsigned int *)bip = (((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr).s_addr;
   }
   return;
  }
  ifr++;
 }
 close(fd);
}

variable_types:
lip
void *

variable_types:
bip
void *

variable_types:
ip
unsigned int

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

variable_types:
mask
unsigned int

variable_types: struct ifconf { int ifc_len; union { char *ifcu_buf; struct ifreq { union { char ifrn_name[16]; } ifr_ifrn; union { struct sockaddr { unsigned short sa_family; char sa_data[14]; } ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; } ifru_map; char ifru_slave[16]; char ifru_newname[16]; char *ifru_data; } ifr_ifru; } *ifcu_req; } ifc_ifcu; }

variable_types: i int

user_defined_types: struct ifconf { int ifc_len; union { char *ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu; }

user_defined_types: struct ifreq { union { char ifrn_name[16]; } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; struct ifmap ifru_map; char ifru_slave[16]; char ifru_newname[16]; char *ifru_data; } ifr_ifru; }


decompiled_code:
int peer_online()
{
__int64 v0; // rsi
int v1; // ebp
int v2; // ebx
int result; // eax
int v4; // [rsp+0h] [rbp-88h] BYREF
__m128i v5; // [rsp+4h] [rbp-84h]
__m128i v6; // [rsp+14h] [rbp-74h]
int v7; // [rsp+24h] [rbp-64h]

v0 = peer_inlist();
v4 = 6;
v5 = _mm_loadu_si128(self);
v6 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v7 = *(_DWORD *)(self + 32LL);
v1 = getsockfd(4, v0);
if ( v1 < 0 )
m_printf("send msg error\n");
v2 = 3;
do
{
sleep(1u);
send(v1, &v4, 0x6CuLL, 0);
result = close(v1);
--v2;
}
while ( v2 );
return result;
}

canonical_decompiled_code:
int func6()
{
__int64 v0; // rsi
int v1; // ebp
int v2; // ebx
int result; // eax
int v4; // [rsp+0h] [rbp-88h] BYREF
__m128i v5; // [rsp+4h] [rbp-84h]
__m128i v6; // [rsp+14h] [rbp-74h]
int v7; // [rsp+24h] [rbp-64h]

v0 = peer_inlist();
v4 = 6;
v5 = _mm_loadu_si128(self);
v6 = _mm_loadu_si128((const __m128i *)(self + 16LL));
v7 = *(_DWORD *)(self + 32LL);
v1 = func1(4, v0);
if ( v1 < 0 )
m_printf("send msg error\n");
v2 = 3;
do
{
sleep(1u);
send(v1, &v4, 0x6CuLL, 0);
result = close(v1);
--v2;
}
while ( v2 );
return result;
}

original_code:
void peer_online(void *data)
{
 struct peer *pr = peer_inlist((struct message *)data);
 struct message msg;
 msg.type = MSG_PEER_INF;
 memcpy(&msg.id, &self->id, sizeof(struct base_inf));
 int fd = getsockfd(FD_SENDMSG, pr);
 if (fd < 0)
  m_printf("send msg error\n");
 int i;
 for (i = 0; i < 3; i++) {
  sleep(1);
  send(fd, &msg, sizeof(struct message), 0);
  close(fd);
 }
}

variable_types:
data
void *

variable_types: struct message { int type; struct base_inf { char name[32]; unsigned int ip; } id; union { int m_answer; struct file_inf { char fname[64]; unsigned int fsize; } m_file; char m_news[64]; char m_chat[64]; } mdata; }

variable_types: fd int


original_code:
void *recv_msg(void *data)
{
 struct message msg;
 struct message *dupmsg;
 pthread_attr_t attr;
 pthread_attr_init(&attr);
 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 int fd = getsockfd(FD_GETMSG, ((void *)0));
 while (1) {
  recv(fd, &msg, sizeof(struct message), 0);
  if (msg.id.ip == self->id.ip)
   continue;
  dupmsg = (struct message *)malloc(sizeof(struct message));
  memcpy(dupmsg, &msg, sizeof(struct message));
  pthread_create(&self->msg_handler_thr, &attr, msg_handler, dupmsg);
 }
}

canonical_original_code:
void *recv_msg(void *data)
{
 struct message msg;
 struct message *dupmsg;
 union pthread_attr_t attr;
 pthread_attr_init(&attr);
 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 int fd = getsockfd(FD_GETMSG, ((void *)0));
 while (1) {
  recv(fd, &msg, sizeof(struct message), 0);
  if (msg.id.ip == self->id.ip)
   continue;
  dupmsg = (struct message *)malloc(sizeof(struct message));
  memcpy(dupmsg, &msg, sizeof(struct message));
  pthread_create(&self->msg_handler_thr, &attr, msg_handler, dupmsg);
 }
}

variable_types: struct message { int type; struct base_inf { char name[32]; unsigned int ip; } id; union { int m_answer; struct file_inf { char fname[64]; unsigned int fsize; } m_file; char m_news[64]; char m_chat[64]; } mdata; } *

variable_types: union pthread_attr_t { char __size[56]; long __align; }

return_type: void *


decompiled_code:
__int64 __fastcall msg_handler(_DWORD *a1)
{
__int64 result; // rax

switch ( *a1 )
{
case 0:
peer_online();
goto LABEL_3;
case 1:
peer_outlist();
goto LABEL_3;
case 2:
case 4:
respond_rqst();
goto LABEL_3;
case 3:
case 5:
handle_ack();
goto LABEL_3;
case 6:
peer_inlist();
goto LABEL_3;
case 7:
chat_get_comment();
LABEL_3:
result = 0LL;
break;
default:
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_DWORD *a1)
{
__int64 result; // rax

switch ( *a1 )
{
case 0:
peer_online();
goto LABEL_3;
case 1:
peer_outlist();
goto LABEL_3;
case 2:
case 4:
respond_rqst();
goto LABEL_3;
case 3:
case 5:
handle_ack();
goto LABEL_3;
case 6:
peer_inlist();
goto LABEL_3;
case 7:
chat_get_comment();
LABEL_3:
result = 0LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
void *msg_handler(void *data)
{
 struct message *msg = (struct message *)data;
 switch (msg->type) {
 case MSG_OFFLINE:
  peer_outlist(msg) ;
  break;
 case MSG_ONLINE:
  peer_online(msg);
  break;
 case MSG_PEER_INF:
  peer_inlist(msg);
  break;
 case MSG_FILE_RQST:
 case MSG_CHAT_RQST:
  respond_rqst(msg);
  break;
 case MSG_FILE_ACK:
 case MSG_CHAT_ACK:
  handle_ack(msg);
  break;
 case MSG_CHAT:
  chat_get_comment(msg);
 default:
  break;
 }
 return ((void *)0);
}


decompiled_code:
int __fastcall send_file(int fd, char *file)
{
int result; // eax
int v3; // er13
int v4; // er15
int v5; // er12
__int64 v6; // rbp
unsigned int v7; // ebx
unsigned int v8; // [rsp+8h] [rbp-300h]
int arg; // [rsp+1Ch] [rbp-2ECh] BYREF
int v10; // [rsp+20h] [rbp-2E8h] BYREF
char buf[524]; // [rsp+24h] [rbp-2E4h] BYREF
struct stat v12; // [rsp+230h] [rbp-D8h] BYREF
pthread_t newthread[8]; // [rsp+2C8h] [rbp-40h] BYREF

arg = 0;
result = open(file, 0);
if ( result >= 0 )
{
v3 = result;
stat(file, &v12);
v8 = v12.st_size;
if ( (v12.st_size & 0x1FF) != 0 )
{
v4 = (LODWORD(v12.st_size) >> 9) + 1;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
}
else
{
v4 = LODWORD(v12.st_size) >> 9;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
if ( !(v8 >> 9) )
return pthread_join(newthread[0], 0LL);
}
v5 = 0;
v6 = 0LL;
do
{
v10 = v5;
v7 = _readn(v3, buf, 0x200uLL);
_writen(fd, &v10, v7 + 4);
v6 += v7;
arg = 100 * v6 / (unsigned __int64)v8;
++v5;
}
while ( v5 < v4 );
return pthread_join(newthread[0], 0LL);
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(int fd, char *file)
{
int result; // eax
int v3; // er13
int v4; // er15
int v5; // er12
__int64 v6; // rbp
unsigned int v7; // ebx
unsigned int v8; // [rsp+8h] [rbp-300h]
int arg; // [rsp+1Ch] [rbp-2ECh] BYREF
int v10; // [rsp+20h] [rbp-2E8h] BYREF
char buf[524]; // [rsp+24h] [rbp-2E4h] BYREF
struct stat v12; // [rsp+230h] [rbp-D8h] BYREF
pthread_t newthread[8]; // [rsp+2C8h] [rbp-40h] BYREF

arg = 0;
result = open(file, 0);
if ( result >= 0 )
{
v3 = result;
stat(file, &v12);
v8 = v12.st_size;
if ( (v12.st_size & 0x1FF) != 0 )
{
v4 = (LODWORD(v12.st_size) >> 9) + 1;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
}
else
{
v4 = LODWORD(v12.st_size) >> 9;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
if ( !(v8 >> 9) )
return pthread_join(newthread[0], 0LL);
}
v5 = 0;
v6 = 0LL;
do
{
v10 = v5;
v7 = func0(v3, buf, 0x200uLL);
func1(fd, &v10, v7 + 4);
v6 += v7;
arg = 100 * v6 / (unsigned __int64)v8;
++v5;
}
while ( v5 < v4 );
return pthread_join(newthread[0], 0LL);
}
return result;
}

original_code:
void send_file(int sockfd, char *path)
{
 int fd;
 int pack_cnt;
 pthread_t tid;
 struct stat st;
 unsigned int fsize;
 struct file_piece piece;
 int percent = 0;
 unsigned int rnbytes;
 unsigned long long cur_sum = 0;
 if ((fd = open(path, 00)) < 0)
  return;
 stat(path, &st);
 fsize = st.st_size;
 if (fsize % 512)
  pack_cnt = fsize / 512 + 1;
 else
  pack_cnt = fsize / 512;
 pthread_create(&tid, ((void *)0), show_progress, &percent);
 int i;
 for (i = 0; i < pack_cnt; i++) {
  piece.pi_idx = i;
  rnbytes = __readn(fd, &piece.pi_data, 512);
  __writen(sockfd, &piece, rnbytes + sizeof(piece.pi_idx));
  cur_sum += rnbytes;
  percent = (cur_sum*100) / fsize;
 }
 pthread_join(tid, ((void *)0));
}

canonical_original_code:
void send_file(int sockfd, char *path)
{
 int fd;
 int pack_cnt;
 unsigned long tid;
 struct stat st;
 unsigned int fsize;
 struct file_piece piece;
 int percent = 0;
 unsigned int rnbytes;
 unsigned long long cur_sum = 0;
 if ((fd = open(path, 00)) < 0)
  return;
 stat(path, &st);
 fsize = st.st_size;
 if (fsize % 512)
  pack_cnt = fsize / 512 + 1;
 else
  pack_cnt = fsize / 512;
 pthread_create(&tid, ((void *)0), show_progress, &percent);
 int i;
 for (i = 0; i < pack_cnt; i++) {
  piece.pi_idx = i;
  rnbytes = __readn(fd, &piece.pi_data, 512);
  __writen(sockfd, &piece, rnbytes + sizeof(piece.pi_idx));
  cur_sum += rnbytes;
  percent = (cur_sum*100) / fsize;
 }
 pthread_join(tid, ((void *)0));
}

variable_types: sockfd int

variable_types:
path
char *

variable_types:
tid
unsigned long

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

variable_types:
fsize
unsigned int

variable_types: struct file_piece { int pi_idx; char pi_data[512]; }

variable_types: percent int

variable_types:
rnbytes
unsigned int


decompiled_code:
int __fastcall recv_file(int a1, __int64 a2)
{
char *v2; // rax
int v3; // er13
unsigned int v4; // er14
int v5; // er14
__int64 v6; // rbp
int v7; // er12
unsigned int v8; // ebx
int arg; // [rsp+1Ch] [rbp-24Ch] BYREF
int buf; // [rsp+20h] [rbp-248h] BYREF
char v12[516]; // [rsp+24h] [rbp-244h] BYREF
pthread_t newthread[8]; // [rsp+228h] [rbp-40h] BYREF

arg = 0;
v2 = getenv("HOME");
chdir(v2);
v3 = open((const char *)a2, 577, 420LL);
v4 = *(_DWORD *)(a2 + 64);
if ( (v4 & 0x1FF) != 0 )
{
v5 = (v4 >> 9) + 1;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
}
else
{
v5 = v4 >> 9;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
if ( v5 <= 0 )
return pthread_join(newthread[0], 0LL);
}
v6 = 0LL;
v7 = 0;
do
{
v8 = _readn(a1, &buf, 0x204uLL);
lseek(v3, buf << 9, 0);
_writen(v3, v12, v8 - 4);
v6 = v6 + v8 - 4;
arg = 100 * v6 / (unsigned __int64)*(unsigned int *)(a2 + 64);
++v7;
}
while ( v7 < v5 );
return pthread_join(newthread[0], 0LL);
}

canonical_decompiled_code:
int __fastcall func3(int a1, __int64 a2)
{
char *v2; // rax
int v3; // er13
unsigned int v4; // er14
int v5; // er14
__int64 v6; // rbp
int v7; // er12
unsigned int v8; // ebx
int arg; // [rsp+1Ch] [rbp-24Ch] BYREF
int buf; // [rsp+20h] [rbp-248h] BYREF
char v12[516]; // [rsp+24h] [rbp-244h] BYREF
pthread_t newthread[8]; // [rsp+228h] [rbp-40h] BYREF

arg = 0;
v2 = getenv("HOME");
chdir(v2);
v3 = open((const char *)a2, 577, 420LL);
v4 = *(_DWORD *)(a2 + 64);
if ( (v4 & 0x1FF) != 0 )
{
v5 = (v4 >> 9) + 1;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
}
else
{
v5 = v4 >> 9;
pthread_create(newthread, 0LL, (void *(*)(void *))&show_progress, &arg);
if ( v5 <= 0 )
return pthread_join(newthread[0], 0LL);
}
v6 = 0LL;
v7 = 0;
do
{
v8 = func0(a1, &buf, 0x204uLL);
lseek(v3, buf << 9, 0);
func1(v3, v12, v8 - 4);
v6 = v6 + v8 - 4;
arg = 100 * v6 / (unsigned __int64)*(unsigned int *)(a2 + 64);
++v7;
}
while ( v7 < v5 );
return pthread_join(newthread[0], 0LL);
}

original_code:
void recv_file(int sockfd, void *data)
{
 int fd;
 pthread_t tid;
 int pack_cnt, i;
 struct file_piece piece;
 int percent = 0;
 unsigned int rnbytes;
 unsigned long long cur_sum = 0;
 struct file_inf *finf = (struct file_inf *)data;
 chdir(getenv("HOME"));
 fd = open(finf->fname, 0100 | 01 | 01000, 0644);
 if (finf->fsize % 512)
  pack_cnt = finf->fsize / 512 + 1;
 else
  pack_cnt = finf->fsize / 512;
 pthread_create(&tid, ((void *)0), show_progress, &percent);
 for (i = 0; i < pack_cnt; i++) {
  rnbytes = __readn(sockfd, &piece, (512 + sizeof(unsigned int)));
  lseek(fd, piece.pi_idx * 512, 0);
  __writen(fd, &piece.pi_data, rnbytes - sizeof(piece.pi_idx));
  cur_sum += rnbytes - sizeof(piece.pi_idx);
  percent = (cur_sum * 100) / finf->fsize;
 }
 pthread_join(tid, ((void *)0));
}

canonical_original_code:
void recv_file(int sockfd, void *data)
{
 int fd;
 unsigned long tid;
 int pack_cnt; int i;
 struct file_piece piece;
 int percent = 0;
 unsigned int rnbytes;
 unsigned long long cur_sum = 0;
 struct file_inf *finf = (struct file_inf *)data;
 chdir(getenv("HOME"));
 fd = open(finf->fname, 0100 | 01 | 01000, 0644);
 if (finf->fsize % 512)
  pack_cnt = finf->fsize / 512 + 1;
 else
  pack_cnt = finf->fsize / 512;
 pthread_create(&tid, ((void *)0), show_progress, &percent);
 for (i = 0; i < pack_cnt; i++) {
  rnbytes = __readn(sockfd, &piece, (512 + sizeof(unsigned int)));
  lseek(fd, piece.pi_idx * 512, 0);
  __writen(fd, &piece.pi_data, rnbytes - sizeof(piece.pi_idx));
  cur_sum += rnbytes - sizeof(piece.pi_idx);
  percent = (cur_sum * 100) / finf->fsize;
 }
 pthread_join(tid, ((void *)0));
}

variable_types: struct file_inf { char fname[64]; unsigned int fsize; } *

user_defined_types: struct file_piece { int pi_idx; char pi_data[512]; }


original_code:
void list_destroy(list_t *lst)
{
 node_t *iter;
 for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
  free(iter->data);
  free(iter);
 }
 free(lst->head);
}

canonical_original_code:
void list_destroy(struct list *lst)
{
 struct list_node *iter;
 for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
  free(iter->data);
  free(iter);
 }
 free(lst->head);
}

variable_types: struct list { int node_cnt; struct list_node { void *data; struct list_node *prev; struct list_node *next; } *head; } *


original_code:
void *list_del_next(list_t *lst, void *data)
{
 void *tmp;
 node_t *iter;
 if (data != ((void *)0)) {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (iter->data == data)
    break;
  }
  if (iter == lst->head || iter->next == lst->head)
   return ((void *)0);
 } else {
  iter = lst->head;
 }
 tmp = iter->next->data;
 free(iter->next);
 iter->next = iter->next->next;
 iter->next->prev = iter;
 lst->node_cnt--;
 return tmp;
}

canonical_original_code:
void *list_del_next(struct list *lst, void *data)
{
 void *tmp;
 struct list_node *iter;
 if (data != ((void *)0)) {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (iter->data == data)
    break;
  }
  if (iter == lst->head || iter->next == lst->head)
   return ((void *)0);
 } else {
  iter = lst->head;
 }
 tmp = iter->next->data;
 free(iter->next);
 iter->next = iter->next->next;
 iter->next->prev = iter;
 lst->node_cnt--;
 return tmp;
}

variable_types:
tmp
void *

variable_types: struct list_node { void *data; struct list_node *prev; struct list_node *next; } *


original_code:
void *list_del_after(list_t *lst, void *data)
{
 void *tmp;
 node_t *iter;
 if (data != ((void *)0)) {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (iter->data == data)
    break;
  }
  if(iter->prev == lst->head || iter == lst->head)
   return ((void *)0);
 } else {
  iter = lst->head;
 }
 tmp = iter->prev->data;
 free(iter->prev);
 iter->prev = iter->prev->prev;
 iter->prev->next = iter;
 lst->node_cnt--;
 return tmp;
}

canonical_original_code:
void *list_del_after(struct list *lst, void *data)
{
 void *tmp;
 struct list_node *iter;
 if (data != ((void *)0)) {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (iter->data == data)
    break;
  }
  if(iter->prev == lst->head || iter == lst->head)
   return ((void *)0);
 } else {
  iter = lst->head;
 }
 tmp = iter->prev->data;
 free(iter->prev);
 iter->prev = iter->prev->prev;
 iter->prev->next = iter;
 lst->node_cnt--;
 return tmp;
}

variable_types:
data
void *


decompiled_code:
__int64 __fastcall list_del_node(__int64 a1, __int64 a2)
{
_QWORD *v3; // rax
_QWORD *v4; // rdi
__int64 v6; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
if ( !*(_DWORD *)a1 )
return 0xFFFFFFFFLL;
v3 = *(_QWORD **)(a1 + 8);
v4 = (_QWORD *)v3[2];
if ( v3 == v4 )
return 0xFFFFFFFFLL;
while ( *v4 != a2 )
{
v4 = (_QWORD *)v4[2];
if ( v3 == v4 )
return 0xFFFFFFFFLL;
}
v6 = v4[2];
*(_QWORD *)(v4[1] + 16LL) = v6;
*(_QWORD *)(v6 + 8) = v4[1];
--*(_DWORD *)a1;
free(v4);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
_QWORD *v3; // rax
_QWORD *v4; // rdi
__int64 v6; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
if ( !*(_DWORD *)a1 )
return 0xFFFFFFFFLL;
v3 = *(_QWORD **)(a1 + 8);
v4 = (_QWORD *)v3[2];
if ( v3 == v4 )
return 0xFFFFFFFFLL;
while ( *v4 != a2 )
{
v4 = (_QWORD *)v4[2];
if ( v3 == v4 )
return 0xFFFFFFFFLL;
}
v6 = v4[2];
*(_QWORD *)(v4[1] + 16LL) = v6;
*(_QWORD *)(v6 + 8) = v4[1];
--*(_DWORD *)a1;
free(v4);
return 0LL;
}

original_code:
int list_del_node(list_t *lst, void *data)
{
 node_t *iter;
 if (data == ((void *)0) || lst->node_cnt == 0)
  return -1;
 for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
  if (iter->data == data) {
   iter->prev->next = iter->next;
   iter->next->prev = iter->prev;
   lst->node_cnt--;
   free(iter);
   return 0;
  }
 }
 return -1;
}

canonical_original_code:
int list_del_node(struct list *lst, void *data)
{
 struct list_node *iter;
 if (data == ((void *)0) || lst->node_cnt == 0)
  return -1;
 for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
  if (iter->data == data) {
   iter->prev->next = iter->next;
   iter->next->prev = iter->prev;
   lst->node_cnt--;
   free(iter);
   return 0;
  }
 }
 return -1;
}


decompiled_code:
__int64 __fastcall list_insert_next(__int64 a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
_QWORD *v5; // rbx
_QWORD *v7; // rax

if ( !a3 )
return 0xFFFFFFFFLL;
if ( a2 )
{
v4 = *(_QWORD **)(a1 + 8);
v5 = (_QWORD *)v4[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
while ( *v5 != a2 )
{
v5 = (_QWORD *)v5[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
else
{
v5 = *(_QWORD **)(a1 + 8);
}
v7 = malloc(0x18uLL);
*v7 = a3;
v7[1] = v5;
v7[2] = v5[2];
v5[2] = v7;
*(_QWORD *)(v7[2] + 8LL) = v7;
++*(_DWORD *)a1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
_QWORD *v5; // rbx
_QWORD *v7; // rax

if ( !a3 )
return 0xFFFFFFFFLL;
if ( a2 )
{
v4 = *(_QWORD **)(a1 + 8);
v5 = (_QWORD *)v4[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
while ( *v5 != a2 )
{
v5 = (_QWORD *)v5[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
else
{
v5 = *(_QWORD **)(a1 + 8);
}
v7 = malloc(0x18uLL);
*v7 = a3;
v7[1] = v5;
v7[2] = v5[2];
v5[2] = v7;
*(_QWORD *)(v7[2] + 8LL) = v7;
++*(_DWORD *)a1;
return 0LL;
}

original_code:
int list_insert_next(list_t *lst, void *tag_data, void *inst_data)
{
 if (inst_data == ((void *)0))
  return -1;
 node_t *node1;
 if (tag_data != ((void *)0)) {
  for(node1 = (lst)->head->next; node1 != (lst)->head ; node1 = node1->next) {
   if (node1->data == tag_data)
    break;
  }
  if (node1 == lst->head)
   return -1;
 } else {
  node1 = lst->head;
 }
 node_t *node2 = (node_t *)malloc(sizeof(node_t));
 node2->data = inst_data;
 node2->prev = node1;
 node2->next = node1->next;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}

canonical_original_code:
int list_insert_next(struct list *lst, void *tag_data, void *inst_data)
{
 if (inst_data == ((void *)0))
  return -1;
 struct list_node *node1;
 if (tag_data != ((void *)0)) {
  for(node1 = (lst)->head->next; node1 != (lst)->head ; node1 = node1->next) {
   if (node1->data == tag_data)
    break;
  }
  if (node1 == lst->head)
   return -1;
 } else {
  node1 = lst->head;
 }
 struct list_node *node2 = (node_t *)malloc(sizeof(node_t));
 node2->data = inst_data;
 node2->prev = node1;
 node2->next = node1->next;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}


decompiled_code:
__int64 __fastcall list_insert_after(__int64 a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
_QWORD *v5; // rbx
_QWORD *v7; // rax
__int64 v8; // rdx

if ( !a3 )
return 0xFFFFFFFFLL;
if ( a2 )
{
v4 = *(_QWORD **)(a1 + 8);
v5 = (_QWORD *)v4[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
while ( *v5 != a2 )
{
v5 = (_QWORD *)v5[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
else
{
v5 = *(_QWORD **)(a1 + 8);
}
v7 = malloc(0x18uLL);
*v7 = a3;
v8 = v5[1];
v7[1] = v8;
v7[2] = v5;
*(_QWORD *)(v8 + 16) = v7;
*(_QWORD *)(v7[2] + 8LL) = v7;
++*(_DWORD *)a1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
_QWORD *v5; // rbx
_QWORD *v7; // rax
__int64 v8; // rdx

if ( !a3 )
return 0xFFFFFFFFLL;
if ( a2 )
{
v4 = *(_QWORD **)(a1 + 8);
v5 = (_QWORD *)v4[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
while ( *v5 != a2 )
{
v5 = (_QWORD *)v5[2];
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
if ( v4 == v5 )
return 0xFFFFFFFFLL;
}
else
{
v5 = *(_QWORD **)(a1 + 8);
}
v7 = malloc(0x18uLL);
*v7 = a3;
v8 = v5[1];
v7[1] = v8;
v7[2] = v5;
*(_QWORD *)(v8 + 16) = v7;
*(_QWORD *)(v7[2] + 8LL) = v7;
++*(_DWORD *)a1;
return 0LL;
}

original_code:
int list_insert_after(list_t *lst, void *tag_data, void *inst_data)
{
 if (inst_data == ((void *)0))
  return -1;
 node_t *node1;
 if (tag_data != ((void *)0)) {
  for(node1 = (lst)->head->next; node1 != (lst)->head ; node1 = node1->next) {
   if (node1->data == tag_data)
    break;
  }
  if (node1 == lst->head)
   return -1;
 } else {
  node1 = lst->head;
 }
 node_t *node2 = (node_t *)malloc(sizeof(node_t));
 node2->data = inst_data;
 node2->prev = node1->prev;
 node2->next = node1;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}

canonical_original_code:
int list_insert_after(struct list *lst, void *tag_data, void *inst_data)
{
 if (inst_data == ((void *)0))
  return -1;
 struct list_node *node1;
 if (tag_data != ((void *)0)) {
  for(node1 = (lst)->head->next; node1 != (lst)->head ; node1 = node1->next) {
   if (node1->data == tag_data)
    break;
  }
  if (node1 == lst->head)
   return -1;
 } else {
  node1 = lst->head;
 }
 struct list_node *node2 = (node_t *)malloc(sizeof(node_t));
 node2->data = inst_data;
 node2->prev = node1->prev;
 node2->next = node1;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}


decompiled_code:
__int64 __fastcall list_insert_tail(__int64 a1, __int64 a2)
{
list_insert_after(a1, 0LL, a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
func5(a1, 0LL, a2);
return 0LL;
}

original_code:
int list_insert_tail(list_t *lst, void *data)
{
 list_insert_after(lst, ((void *)0), data);
 return 0;
}

canonical_original_code:
int list_insert_tail(struct list *lst, void *data)
{
 list_insert_after(lst, ((void *)0), data);
 return 0;
}


decompiled_code:
__int64 __fastcall list_insert_head(__int64 a1, __int64 a2)
{
list_insert_next(a1, 0LL, a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, __int64 a2)
{
func4(a1, 0LL, a2);
return 0LL;
}

original_code:
int list_insert_head(list_t *lst, void *data)
{
 list_insert_next(lst, ((void *)0), data);
 return 0;
}

canonical_original_code:
int list_insert_head(struct list *lst, void *data)
{
 list_insert_next(lst, ((void *)0), data);
 return 0;
}


decompiled_code:
__int64 __fastcall list_del_head(__int64 a1)
{
return list_del_next(a1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
return func1(a1, 0LL);
}

original_code:
void *list_del_head(list_t *lst)
{
 return list_del_next(lst, ((void *)0));
}

canonical_original_code:
void *list_del_head(struct list *lst)
{
 return list_del_next(lst, ((void *)0));
}


decompiled_code:
__int64 __fastcall list_del_tail(__int64 a1)
{
return list_del_after(a1, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
return func2(a1, 0LL);
}

original_code:
void *list_del_tail(list_t *lst)
{
 return list_del_after(lst, ((void *)0));
}

canonical_original_code:
void *list_del_tail(struct list *lst)
{
 return list_del_after(lst, ((void *)0));
}


original_code:
int list_sort_insert(list_t *lst, void *data, int (*cmp_fn)(void *d1, void *d2))
{
 node_t *iter;
 if (data == ((void *)0))
  return -1;
 if (lst->node_cnt == 0)
  list_insert_tail(lst, data);
 else if (!cmp_fn(data, (lst->head->prev)->data))
  list_insert_tail(lst, data);
 else {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (cmp_fn(data, iter->data)) {
    list_insert_after(lst, iter->data, data);
    break;
   }
  }
 }
 return 0;
}

canonical_original_code:
int list_sort_insert(struct list *lst, void *data, int (*cmp_fn)(void *d1, void *d2))
{
 struct list_node *iter;
 if (data == ((void *)0))
  return -1;
 if (lst->node_cnt == 0)
  list_insert_tail(lst, data);
 else if (!cmp_fn(data, (lst->head->prev)->data))
  list_insert_tail(lst, data);
 else {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (cmp_fn(data, iter->data)) {
    list_insert_after(lst, iter->data, data);
    break;
   }
  }
 }
 return 0;
}


repo: Jery-Mong/huffman

decompiled_code:
__int64 __fastcall list_del_next(_DWORD *a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx

result = *(_QWORD *)(a2 + 16);
if ( result == a2 )
return 0LL;
v3 = *(_QWORD *)(result + 16);
*(_QWORD *)(a2 + 16) = v3;
*(_QWORD *)(v3 + 8) = a2;
--*a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func15(_DWORD *a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx

result = *(_QWORD *)(a2 + 16);
if ( result == a2 )
return 0LL;
v3 = *(_QWORD *)(result + 16);
*(_QWORD *)(a2 + 16) = v3;
*(_QWORD *)(v3 + 8) = a2;
--*a1;
return result;
}

original_code:
node_t* list_del_next(list_t *lst, node_t *node)
{
 node_t *tmp;
 if (node->next == node)
  return ((void *)0);
 tmp = node->next;
 node->next = node->next->next;
 node->next->prev = node;
 lst->node_cnt--;
 return tmp;
}

canonical_original_code:
struct list_node *list_del_next(struct list *lst, struct list_node *node)
{
 struct list_node *tmp;
 if (node->next == node)
  return ((void *)0);
 tmp = node->next;
 node->next = node->next->next;
 node->next->prev = node;
 lst->node_cnt--;
 return tmp;
}

variable_types: struct list { int node_cnt; struct list_node *head; } *

variable_types:
node
struct list_node *

return_type: struct list_node { void *data; struct list_node *prev; struct list_node *next; } *


decompiled_code:
__int64 __fastcall list_del_after(_DWORD *a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx

result = *(_QWORD *)(a2 + 8);
if ( result == a2 )
return 0LL;
v3 = *(_QWORD *)(result + 8);
*(_QWORD *)(a2 + 8) = v3;
*(_QWORD *)(v3 + 16) = a2;
--*a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(_DWORD *a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx

result = *(_QWORD *)(a2 + 8);
if ( result == a2 )
return 0LL;
v3 = *(_QWORD *)(result + 8);
*(_QWORD *)(a2 + 8) = v3;
*(_QWORD *)(v3 + 16) = a2;
--*a1;
return result;
}

original_code:
node_t * list_del_after(list_t *lst, node_t *node)
{
 node_t *tmp;
 if(node->prev == node)
  return ((void *)0);
 tmp = node->prev;
 node->prev = node->prev->prev;
 node->prev->next = node;
 lst->node_cnt--;
 return tmp;
}

canonical_original_code:
struct list_node *list_del_after(struct list *lst, struct list_node *node)
{
 struct list_node *tmp;
 if(node->prev == node)
  return ((void *)0);
 tmp = node->prev;
 node->prev = node->prev->prev;
 node->prev->next = node;
 lst->node_cnt--;
 return tmp;
}


original_code:
int list_insert_next(list_t *lst, node_t *node1, node_t *node2)
{
 if (node1 == ((void *)0) || node2 == ((void *)0))
  return -1;
 node2->prev = node1;
 node2->next = node1->next;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}

canonical_original_code:
int list_insert_next(struct list *lst, struct list_node *node1, struct list_node *node2)
{
 if (node1 == ((void *)0) || node2 == ((void *)0))
  return -1;
 node2->prev = node1;
 node2->next = node1->next;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}


original_code:
int list_insert_after(list_t *lst, node_t *node1, node_t *node2)
{
 if (node1 == ((void *)0) || node2 == ((void *)0))
  return -1;
 node2->prev = node1->prev;
 node2->next = node1;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}

canonical_original_code:
int list_insert_after(struct list *lst, struct list_node *node1, struct list_node *node2)
{
 if (node1 == ((void *)0) || node2 == ((void *)0))
  return -1;
 node2->prev = node1->prev;
 node2->next = node1;
 node2->prev->next = node2;
 node2->next->prev = node2;
 lst->node_cnt++;
 return 0;
}


decompiled_code:
__int64 __fastcall list_del_node(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // rax
__int64 result; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
if ( !*(_DWORD *)a1 )
return 0xFFFFFFFFLL;
v2 = *(_QWORD *)(a1 + 8);
v3 = *(_QWORD *)(v2 + 16);
if ( v2 == v3 )
return 0xFFFFFFFFLL;
if ( a2 == v3 )
{
LABEL_7:
list_del_next((_DWORD *)a1, *(_QWORD *)(a2 + 8));
--*(_DWORD *)a1;
result = 0LL;
}
else
{
while ( 1 )
{
v3 = *(_QWORD *)(v3 + 16);
if ( v2 == v3 )
break;
if ( a2 == v3 )
goto LABEL_7;
}
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func19(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // rax
__int64 result; // rax

if ( !a2 )
return 0xFFFFFFFFLL;
if ( !*(_DWORD *)a1 )
return 0xFFFFFFFFLL;
v2 = *(_QWORD *)(a1 + 8);
v3 = *(_QWORD *)(v2 + 16);
if ( v2 == v3 )
return 0xFFFFFFFFLL;
if ( a2 == v3 )
{
LABEL_7:
func15((_DWORD *)a1, *(_QWORD *)(a2 + 8));
--*(_DWORD *)a1;
result = 0LL;
}
else
{
while ( 1 )
{
v3 = *(_QWORD *)(v3 + 16);
if ( v2 == v3 )
break;
if ( a2 == v3 )
goto LABEL_7;
}
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int list_del_node(list_t *lst, node_t *node)
{
 node_t *iter;
 if (node == ((void *)0) || lst->node_cnt == 0)
  return -1;
 for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
  if (iter == node) {
   list_del_next(lst, node->prev);
   lst->node_cnt--;
   return 0;
  }
 }
 return -1;
}

canonical_original_code:
int list_del_node(struct list *lst, struct list_node *node)
{
 struct list_node *iter;
 if (node == ((void *)0) || lst->node_cnt == 0)
  return -1;
 for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
  if (iter == node) {
   list_del_next(lst, node->prev);
   lst->node_cnt--;
   return 0;
  }
 }
 return -1;
}


decompiled_code:
__int64 __fastcall list_insert_tail(__int64 a1, __int64 a2)
{
list_insert_after((_DWORD *)a1, *(_QWORD *)(a1 + 8), a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1, __int64 a2)
{
func18((_DWORD *)a1, *(_QWORD *)(a1 + 8), a2);
return 0LL;
}

original_code:
int list_insert_tail(list_t *lst, node_t *node)
{
 list_insert_after(lst, lst->head, node);
 return 0;
}

canonical_original_code:
int list_insert_tail(struct list *lst, struct list_node *node)
{
 list_insert_after(lst, lst->head, node);
 return 0;
}


decompiled_code:
__int64 __fastcall list_insert_head(__int64 a1, __int64 a2)
{
list_insert_next((_DWORD *)a1, *(_QWORD *)(a1 + 8), a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func21(__int64 a1, __int64 a2)
{
func17((_DWORD *)a1, *(_QWORD *)(a1 + 8), a2);
return 0LL;
}

original_code:
int list_insert_head(list_t *lst, node_t *node)
{
 list_insert_next(lst, lst->head, node);
 return 0;
}

canonical_original_code:
int list_insert_head(struct list *lst, struct list_node *node)
{
 list_insert_next(lst, lst->head, node);
 return 0;
}


decompiled_code:
__int64 __fastcall list_del_head(__int64 a1)
{
return list_del_next((_DWORD *)a1, *(_QWORD *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func22(__int64 a1)
{
return func15((_DWORD *)a1, *(_QWORD *)(a1 + 8));
}

original_code:
node_t *list_del_head(list_t *lst)
{
 return list_del_next(lst, lst->head);
}

canonical_original_code:
struct list_node *list_del_head(struct list *lst)
{
 return list_del_next(lst, lst->head);
}


decompiled_code:
__int64 __fastcall list_del_tail(__int64 a1)
{
return list_del_after((_DWORD *)a1, *(_QWORD *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1)
{
return func16((_DWORD *)a1, *(_QWORD *)(a1 + 8));
}

original_code:
node_t *list_del_tail(list_t *lst)
{
 return list_del_after(lst, lst->head);
}

canonical_original_code:
struct list_node *list_del_tail(struct list *lst)
{
 return list_del_after(lst, lst->head);
}


original_code:
int list_sort_insert(list_t *lst, node_t *node, int (*cmp_fn)(node_t *, node_t *))
{
 node_t *iter;
 if (node == ((void *)0))
  return -1;
 if (lst->node_cnt == 0)
  list_insert_tail(lst, node);
 else if (!cmp_fn(node, ((lst)->node_cnt ? (lst)->head->prev : ((void *)0))))
  list_insert_tail(lst, node);
 else {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (cmp_fn(node, iter)) {
    list_insert_after(lst, iter, node);
    break;
   }
  }
 }
 return 0;
}

canonical_original_code:
int list_sort_insert(struct list *lst, struct list_node *node, int (*cmp_fn)(struct list_node *, struct list_node *))
{
 struct list_node *iter;
 if (node == ((void *)0))
  return -1;
 if (lst->node_cnt == 0)
  list_insert_tail(lst, node);
 else if (!cmp_fn(node, ((lst)->node_cnt ? (lst)->head->prev : ((void *)0))))
  list_insert_tail(lst, node);
 else {
  for(iter = (lst)->head->next; iter != (lst)->head ; iter = iter->next) {
   if (cmp_fn(node, iter)) {
    list_insert_after(lst, iter, node);
    break;
   }
  }
 }
 return 0;
}

variable_types: int (*)(struct list_node *, struct list_node *)


decompiled_code:
__int64 __fastcall match_item(void *s2)
{
size_t v1; // r12
unsigned __int8 *v2; // rbp
unsigned int v3; // ebx

v1 = *(char *)s2 / 8 + 2;
v2 = (unsigned __int8 *)level_idx_tb[*(char *)s2];
do
{
v3 = *v2;
if ( (_BYTE)v3 == 0xFF )
break;
++v2;
}
while ( memcmp(*(&map_tb + (char)v3), s2, v1) );
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func7(void *s2)
{
size_t v1; // r12
unsigned __int8 *v2; // rbp
unsigned int v3; // ebx

v1 = *(char *)s2 / 8 + 2;
v2 = (unsigned __int8 *)level_idx_tb[*(char *)s2];
do
{
v3 = *v2;
if ( (_BYTE)v3 == 0xFF )
break;
++v2;
}
while ( memcmp(*(&map_tb + (char)v3), s2, v1) );
return v3;
}

original_code:
char match_item(char *code)
{
 int idx;
 int i = 0;
 int level = code[0];
 while ((idx = level_idx_tb[level][i++]) != -1) {
  if (!memcmp(map_tb[idx], code, level / 8 + 2))
   return idx;
 }
 return -1;
}

variable_types:
code
char *

variable_types: idx int

variable_types: i int

variable_types: level int

return_type: char


decompiled_code:
void *make_level_idx_table()
{
__int64 i; // rbp
__int64 v1; // rax
char *v2; // rdx
int v3; // ebx
void *v4; // r13
void *result; // rax
char v6[168]; // [rsp+0h] [rbp-A8h] BYREF

for ( i = 1LL; i != 128; ++i )
{
v1 = 128LL;
v3 = 0;
do
{
v2 = (char *)*(&map_tb + v1);
if ( v2 )
{
if ( *v2 == (_DWORD)i )
v6[v3++] = v1;
}
--v1;
}
while ( v1 != -1 );
v4 = malloc(v3 + 1);
level_idx_tb[i] = (__int64)v4;
memset(v4, -1, v3 + 1);
result = memcpy(v4, v6, v3);
}
return result;
}

canonical_decompiled_code:
void *func8()
{
__int64 i; // rbp
__int64 v1; // rax
char *v2; // rdx
int v3; // ebx
void *v4; // r13
void *result; // rax
char v6[168]; // [rsp+0h] [rbp-A8h] BYREF

for ( i = 1LL; i != 128; ++i )
{
v1 = 128LL;
v3 = 0;
do
{
v2 = (char *)*(&map_tb + v1);
if ( v2 )
{
if ( *v2 == (_DWORD)i )
v6[v3++] = v1;
}
--v1;
}
while ( v1 != -1 );
v4 = malloc(v3 + 1);
level_idx_tb[i] = (__int64)v4;
memset(v4, -1, v3 + 1);
result = memcpy(v4, v6, v3);
}
return result;
}

original_code:
void make_level_idx_table()
{
 int i, j;
 int level_cnt;
 char tp[128];
 for (i = 1; i < 128; i++) {
  for (j = 128, level_cnt = 0; j >= 0 ; --j) {
   if (map_tb[j] == (void *)0)
    continue;
   if (map_tb[j][0] == i)
    tp[level_cnt++] = j;
  }
  level_idx_tb[i] = (char *)malloc(level_cnt + 1);
  memset(level_idx_tb[i], -1, level_cnt + 1);
  memcpy(level_idx_tb[i], tp, level_cnt);
 }
}

canonical_original_code:
void make_level_idx_table()
{
 int i; int j;
 int level_cnt;
 char tp[128];
 for (i = 1; i < 128; i++) {
  for (j = 128, level_cnt = 0; j >= 0 ; --j) {
   if (map_tb[j] == (void *)0)
    continue;
   if (map_tb[j][0] == i)
    tp[level_cnt++] = j;
  }
  level_idx_tb[i] = (char *)malloc(level_cnt + 1);
  memset(level_idx_tb[i], -1, level_cnt + 1);
  memcpy(level_idx_tb[i], tp, level_cnt);
 }
}

variable_types: j int

variable_types:
tp
char [128]


decompiled_code:
__int64 find_min_level()
{
unsigned int v0; // ecx
__int64 *v1; // rax

v0 = *(char *)map_tb;
v1 = (__int64 *)&unk_4040C8;
do
{
if ( *v1 && (int)v0 > *(char *)*v1 )
v0 = *(char *)*v1;
++v1;
}
while ( v1 != level_idx_tb );
return v0;
}

canonical_decompiled_code:
__int64 func9()
{
unsigned int v0; // ecx
__int64 *v1; // rax

v0 = *(char *)map_tb;
v1 = (__int64 *)&unk_4040C8;
do
{
if ( *v1 && (int)v0 > *(char *)*v1 )
v0 = *(char *)*v1;
++v1;
}
while ( v1 != level_idx_tb );
return v0;
}

original_code:
int find_min_level()
{
 int i;
 int min;
 min = map_tb[0][0];
 for (i = 1; i < 128; i++) {
  if (map_tb[i] != (void *)0) {
   if (map_tb[i][0] < min)
    min = map_tb[i][0];
  }
 }
 return min;
}

variable_types: min int


repo: Jery-Mong/snake

decompiled_code:
int paint_apple()
{
int *v0; // rbx
int result; // eax

v0 = &apple;
do
{
wmove(game_erea, v0[1], *v0);
result = waddch(game_erea, 0x40041uLL);
v0 += 2;
}
while ( v0 != (int *)(unsigned int)((_DWORD)&apple + 24) );
return result;
}

canonical_decompiled_code:
int func0()
{
int *v0; // rbx
int result; // eax

v0 = &apple;
do
{
wmove(game_erea, v0[1], *v0);
result = waddch(game_erea, 0x40041uLL);
v0 += 2;
}
while ( v0 != (int *)(unsigned int)((_DWORD)&apple + 24) );
return result;
}

original_code:
void paint_apple()
{
 int i;
 for (i = 0; i < 3; i++) {
  wmove(game_erea, apple[i].y, apple[i].x);
  waddch(game_erea, 'A' | ((chtype)((1U)) << ((10) + 8)));
 }
}


decompiled_code:
void __fastcall paint_seg(__int64 a1)
{
int v1; // esi
int v2; // er12
unsigned int v3; // er12
int v4; // er13
int v5; // ebp
int v6; // er14
int v7; // eax
int v8; // edx
unsigned int v9; // ebp

if ( a1 )
{
if ( *(_DWORD *)(a1 + 12) )
{
v4 = *(_DWORD *)a1;
v5 = *(_DWORD *)a1;
v6 = *(_DWORD *)(a1 + 4);
v2 = v6;
v7 = *(_DWORD *)(a1 + 8);
if ( v7 == -1 )
{
do
{
v1 = v2--;
wmove(game_erea, v1, v5);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
}
while ( *(_DWORD *)(a1 + 12) > (unsigned int)(v6 - v2) );
}
else if ( v7 < 0 )
{
v9 = 0;
if ( v7 == -2 )
{
do
{
wmove(game_erea, v6, v9 + v4);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
++v9;
}
while ( *(_DWORD *)(a1 + 12) > v9 );
}
}
else if ( v7 == 1 )
{
v3 = 0;
do
{
wmove(game_erea, v3 + v6, v5);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
++v3;
}
while ( *(_DWORD *)(a1 + 12) > v3 );
}
else if ( v7 == 2 )
{
do
{
v8 = v5--;
wmove(game_erea, v6, v8);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
}
while ( *(_DWORD *)(a1 + 12) > (unsigned int)(v4 - v5) );
}
}
else if ( snake_head != a1 )
{
return;
}
paint_seg(*(_QWORD *)(a1 + 24));
}
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1)
{
int v1; // esi
int v2; // er12
unsigned int v3; // er12
int v4; // er13
int v5; // ebp
int v6; // er14
int v7; // eax
int v8; // edx
unsigned int v9; // ebp

if ( a1 )
{
if ( *(_DWORD *)(a1 + 12) )
{
v4 = *(_DWORD *)a1;
v5 = *(_DWORD *)a1;
v6 = *(_DWORD *)(a1 + 4);
v2 = v6;
v7 = *(_DWORD *)(a1 + 8);
if ( v7 == -1 )
{
do
{
v1 = v2--;
wmove(game_erea, v1, v5);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
}
while ( *(_DWORD *)(a1 + 12) > (unsigned int)(v6 - v2) );
}
else if ( v7 < 0 )
{
v9 = 0;
if ( v7 == -2 )
{
do
{
wmove(game_erea, v6, v9 + v4);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
++v9;
}
while ( *(_DWORD *)(a1 + 12) > v9 );
}
}
else if ( v7 == 1 )
{
v3 = 0;
do
{
wmove(game_erea, v3 + v6, v5);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
++v3;
}
while ( *(_DWORD *)(a1 + 12) > v3 );
}
else if ( v7 == 2 )
{
do
{
v8 = v5--;
wmove(game_erea, v6, v8);
waddch(game_erea, 0x40020uLL);
waddch(game_erea, 0x40020uLL);
}
while ( *(_DWORD *)(a1 + 12) > (unsigned int)(v4 - v5) );
}
}
else if ( snake_head != a1 )
{
return;
}
func1(*(_QWORD *)(a1 + 24));
}
}

original_code:
void paint_seg(struct segment *p)
{
 if (p == ((void *)0))
  return;
 if ( p->count == 0 && p != snake_head)
  return;
 int x = p->x;
 int y = p->y;
 switch (p->dir) {
 case -1:
  do {for (int i = 0; i < (p->count); i++) { wmove(game_erea,(y--),(x)); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); } } while (0);
  break;
 case 1:
  do {for (int i = 0; i < (p->count); i++) { wmove(game_erea,(y++),(x)); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); } } while (0);
  break;
 case 2:
  do {for (int i = 0; i < (p->count); i++) { wmove(game_erea,(y),(x--)); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); } } while (0);
  break;
 case -2:
  do {for (int i = 0; i < (p->count); i++) { wmove(game_erea,(y),(x++)); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); waddch(game_erea, ' ' | ((chtype)((1U)) << ((10) + 8))); } } while (0);
  break;
 }
 paint_seg(p->next);
}

variable_types: struct segment { unsigned int x; int dir; unsigned int count; struct segment *pre; struct segment *next; } *

variable_types: x int

variable_types: y int


decompiled_code:
__int64 count_seg()
{
__int64 v0; // rax
unsigned int v1; // edx

v0 = snake_head;
if ( !snake_head )
return 0;
v1 = 0;
do
{
++v1;
v0 = *(_QWORD *)(v0 + 24);
}
while ( v0 );
return v1;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 v0; // rax
unsigned int v1; // edx

v0 = snake_head;
if ( !snake_head )
return 0;
v1 = 0;
do
{
++v1;
v0 = *(_QWORD *)(v0 + 24);
}
while ( v0 );
return v1;
}

original_code:
unsigned int count_seg()
{
 struct segment *p = snake_head;
 int i = 0;
 for(p = snake_head; p; p = p->next)
  i++;
 return i;
}

return_type: unsigned int

user_defined_types: struct segment { unsigned int x; int dir; unsigned int count; struct segment *pre; struct segment *next; }


decompiled_code:
__int64 count_node()
{
__int64 v0; // rax
unsigned int v1; // edx

v0 = snake_head;
if ( !snake_head )
return 0;
v1 = 0;
do
{
v1 += *(_DWORD *)(v0 + 12);
v0 = *(_QWORD *)(v0 + 24);
}
while ( v0 );
return v1;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 v0; // rax
unsigned int v1; // edx

v0 = snake_head;
if ( !snake_head )
return 0;
v1 = 0;
do
{
v1 += *(_DWORD *)(v0 + 12);
v0 = *(_QWORD *)(v0 + 24);
}
while ( v0 );
return v1;
}

original_code:
unsigned int count_node()
{
 struct segment *p;
 unsigned int cnt = 0;
 for(p = snake_head; p; p = p->next)
  cnt += p->count;
 return cnt;
}

variable_types:
cnt
unsigned int


decompiled_code:
int paint_node_nr()
{
unsigned int v0; // eax
char s[8]; // [rsp+6h] [rbp-12h] BYREF
__int16 v3; // [rsp+Eh] [rbp-Ah]

*(_QWORD *)s = 0LL;
v3 = 0;
v0 = count_node();
sprintf(s, "%d", v0);
wmove(game_erea, 0, 0);
return waddnstr(game_erea, s, -1);
}

canonical_decompiled_code:
int func4()
{
unsigned int v0; // eax
char s[8]; // [rsp+6h] [rbp-12h] BYREF
__int16 v3; // [rsp+Eh] [rbp-Ah]

*(_QWORD *)s = 0LL;
v3 = 0;
v0 = func3();
sprintf(s, "%d", v0);
wmove(game_erea, 0, 0);
return waddnstr(game_erea, s, -1);
}

original_code:
void paint_node_nr()
{
 char buf[10] = {0};
 sprintf(buf, "%d", count_node());
 wmove(game_erea, 0, 0);
 waddnstr(game_erea,buf,-1);
}

variable_types:
buf
char [10]


display

decompiled_code:
int display()
{
wclear(game_erea);
wborder(game_erea, 0x7CuLL, 0x7CuLL, 0x3DuLL, 0x3DuLL, 0LL, 0LL, 0LL, 0LL);
pthread_mutex_lock(&sync_lock);
paint_seg(snake_head);
pthread_mutex_unlock(&sync_lock);
paint_apple();
paint_node_nr();
return wrefresh(game_erea);
}

canonical_decompiled_code:
int func5()
{
wclear(game_erea);
wborder(game_erea, 0x7CuLL, 0x7CuLL, 0x3DuLL, 0x3DuLL, 0LL, 0LL, 0LL, 0LL);
pthread_mutex_lock(&sync_lock);
func1(snake_head);
pthread_mutex_unlock(&sync_lock);
func0();
func4();
return wrefresh(game_erea);
}

original_code:
void display()
{
 wclear(game_erea);
 wborder(game_erea, '|', '|', '=', '=', 0, 0, 0, 0);
 pthread_mutex_lock(&sync_lock);
 paint_seg(snake_head);
 pthread_mutex_unlock(&sync_lock);
 paint_apple();
 paint_node_nr();
 wrefresh(game_erea);
}


decompiled_code:
__int64 __fastcall change_tail(__int64 *a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *a1;
if ( snake_head != *a1 )
{
v2 = *(_QWORD *)(result + 16);
*a1 = v2;
*(_QWORD *)(v2 + 24) = 0LL;
result = item_push(result, &snake_pool);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 *a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *a1;
if ( snake_head != *a1 )
{
v2 = *(_QWORD *)(result + 16);
*a1 = v2;
*(_QWORD *)(v2 + 24) = 0LL;
result = item_push(result, &snake_pool);
}
return result;
}

original_code:
void change_tail(struct segment **tailp)
{
 struct segment *tmp = *tailp;
 if (*tailp != snake_head) {
  *tailp = (*tailp)->pre;
  (*tailp)->next = ((void *)0);
  item_push(tmp, &snake_pool);
 }
}

variable_types: struct segment { unsigned int x; int dir; unsigned int count; struct segment *pre; struct segment *next; } **


decompiled_code:
__int64 __fastcall check_node_at_snake(__int64 a1, unsigned int a2, unsigned int a3)
{
__int64 result; // rax
unsigned int v4; // eax
unsigned int v5; // ecx

if ( !a1 )
return 0LL;
do
{
result = *(unsigned int *)(a1 + 8);
if ( (_DWORD)result == 1 )
{
if ( *(_DWORD *)a1 == a2 )
{
v5 = *(_DWORD *)(a1 + 4);
if ( v5 <= a3 && *(_DWORD *)(a1 + 12) + v5 >= a3 )
return result;
}
}
else if ( (int)result > 1 )
{
if ( (_DWORD)result == 2
&& *(_DWORD *)(a1 + 4) == a3
&& *(_DWORD *)a1 >= a2
&& *(_DWORD *)a1 - *(_DWORD *)(a1 + 12) <= a2 )
{
return 1LL;
}
}
else if ( (_DWORD)result == -2 )
{
if ( *(_DWORD *)(a1 + 4) == a3 && *(_DWORD *)a1 <= a2 && *(_DWORD *)(a1 + 12) + *(_DWORD *)a1 >= a2 )
return 1LL;
}
else if ( (_DWORD)result == -1 && *(_DWORD *)a1 == a2 )
{
v4 = *(_DWORD *)(a1 + 4);
if ( v4 >= a3 && v4 - *(_DWORD *)(a1 + 12) <= a3 )
return 1LL;
}
a1 = *(_QWORD *)(a1 + 24);
}
while ( a1 );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, unsigned int a2, unsigned int a3)
{
__int64 result; // rax
unsigned int v4; // eax
unsigned int v5; // ecx

if ( !a1 )
return 0LL;
do
{
result = *(unsigned int *)(a1 + 8);
if ( (_DWORD)result == 1 )
{
if ( *(_DWORD *)a1 == a2 )
{
v5 = *(_DWORD *)(a1 + 4);
if ( v5 <= a3 && *(_DWORD *)(a1 + 12) + v5 >= a3 )
return result;
}
}
else if ( (int)result > 1 )
{
if ( (_DWORD)result == 2
&& *(_DWORD *)(a1 + 4) == a3
&& *(_DWORD *)a1 >= a2
&& *(_DWORD *)a1 - *(_DWORD *)(a1 + 12) <= a2 )
{
return 1LL;
}
}
else if ( (_DWORD)result == -2 )
{
if ( *(_DWORD *)(a1 + 4) == a3 && *(_DWORD *)a1 <= a2 && *(_DWORD *)(a1 + 12) + *(_DWORD *)a1 >= a2 )
return 1LL;
}
else if ( (_DWORD)result == -1 && *(_DWORD *)a1 == a2 )
{
v4 = *(_DWORD *)(a1 + 4);
if ( v4 >= a3 && v4 - *(_DWORD *)(a1 + 12) <= a3 )
return 1LL;
}
a1 = *(_QWORD *)(a1 + 24);
}
while ( a1 );
return 0LL;
}

original_code:
int check_node_at_snake(struct segment *p, unsigned int hx, unsigned int hy)
{
 while (p) {
  switch (p->dir) {
  case -1:
   if (hx == p->x )
    if (hy <= p->y && hy >= (p->y - p->count))
     return 1;
   break;
  case 1:
   if (hx == p->x)
    if (hy >= p->y && hy <= (p->y + p->count))
     return 1;
   break;
  case 2:
   if (hy == p->y)
    if (hx <= p->x && hx >= (p->x - p->count))
     return 1;
   break;
  case -2:
   if (hy == p->y)
    if (hx >= p->x && hx <= (p->x + p->count))
     return 1;
   break;
  }
  p = p->next;
 }
 return 0;
}

variable_types:
hx
unsigned int

variable_types:
hy
unsigned int


decompiled_code:
__int64 terminated_check()
{
__int64 v0; // rbx
signed int v1; // ebp
signed int v2; // er12
unsigned int v3; // edx
__int64 result; // rax

v0 = snake_head;
v1 = *(_DWORD *)snake_head;
v2 = *(_DWORD *)(snake_head + 4);
if ( real_x < *(_DWORD *)snake_head )
return 0xFFFFFFFFLL;
if ( real_y < v2 )
return 0xFFFFFFFFLL;
if ( v1 <= 0 || v2 <= 0 )
return 0xFFFFFFFFLL;
v3 = count_seg();
result = 0LL;
if ( v3 > 3 )
result = (unsigned int)-((unsigned int)check_node_at_snake(
*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(v0 + 24) + 24LL) + 24LL),
v1,
v2) != 0);
return result;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 v0; // rbx
signed int v1; // ebp
signed int v2; // er12
unsigned int v3; // edx
__int64 result; // rax

v0 = snake_head;
v1 = *(_DWORD *)snake_head;
v2 = *(_DWORD *)(snake_head + 4);
if ( real_x < *(_DWORD *)snake_head )
return 0xFFFFFFFFLL;
if ( real_y < v2 )
return 0xFFFFFFFFLL;
if ( v1 <= 0 || v2 <= 0 )
return 0xFFFFFFFFLL;
v3 = func2();
result = 0LL;
if ( v3 > 3 )
result = (unsigned int)-((unsigned int)func7(
*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(v0 + 24) + 24LL) + 24LL),
v1,
v2) != 0);
return result;
}

original_code:
int terminated_check()
{
 struct segment *p = snake_head;
 int hx = p->x;
 int hy = p->y;
 if (hx > real_x || hy > real_y || hx < 1 || hy < 1)
  return -1;
 if (count_seg() < 4)
  return 0;
 p = ((p->next)->next)->next;
 if (check_node_at_snake(p, hx, hy))
  return -1;
 return 0;
}

variable_types: hx int

variable_types: hy int


decompiled_code:
__int64 __fastcall update_apple(unsigned int a1)
{
unsigned int v1; // eax
int *v2; // rbx
int v3; // eax
__int64 result; // rax
int v5; // et2
int v6; // eax
int v7; // et2

v1 = time(0LL);
srand(v1);
v2 = apple;
if ( a1 <= 2 )
{
apple[2 * a1] = rand() % real_x + 1;
v6 = rand();
v7 = v6 % real_y;
result = (unsigned int)(v6 / real_y);
apple[2 * a1 + 1] = v7 + 1;
}
else
{
do
{
*v2 = rand() % real_x + 1;
v3 = rand();
v5 = v3 % real_y;
result = (unsigned int)(v3 / real_y);
v2[1] = v5 + 1;
v2 += 2;
}
while ( v2 != (int *)(unsigned int)((_DWORD)apple + 24) );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned int a1)
{
unsigned int v1; // eax
int *v2; // rbx
int v3; // eax
__int64 result; // rax
int v5; // et2
int v6; // eax
int v7; // et2

v1 = time(0LL);
srand(v1);
v2 = apple;
if ( a1 <= 2 )
{
apple[2 * a1] = rand() % real_x + 1;
v6 = rand();
v7 = v6 % real_y;
result = (unsigned int)(v6 / real_y);
apple[2 * a1 + 1] = v7 + 1;
}
else
{
do
{
*v2 = rand() % real_x + 1;
v3 = rand();
v5 = v3 % real_y;
result = (unsigned int)(v3 / real_y);
v2[1] = v5 + 1;
v2 += 2;
}
while ( v2 != (int *)(unsigned int)((_DWORD)apple + 24) );
}
return result;
}

original_code:
void update_apple(int index)
{
 int i;
 srand((unsigned int)time(((void *)0)));
 if (index >=0 && index < 3 ) {
  apple[index].x = (unsigned int)(rand() % real_x) + 1;
  apple[index].y = (unsigned int)(rand() % real_y) + 1;
 } else
  for (i = 0; i < 3; i++) {
   apple[i].x = (unsigned int)(rand() % real_x) + 1;
   apple[i].y = (unsigned int)(rand() % real_y) + 1;
  }
}

variable_types: index int


decompiled_code:
__int64 eat_apple()
{
__int64 i; // rax

for ( i = 0LL; i != 3; ++i )
{
if ( *(_DWORD *)snake_head == apple[2 * i] && *(_DWORD *)(snake_head + 4) == apple[2 * i + 1] )
{
++*(_DWORD *)(snake_head + 12);
update_apple(i);
g_speed = (int)((double)(int)g_speed - (double)(int)g_speed * 0.01);
return 1LL;
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 func10()
{
__int64 i; // rax

for ( i = 0LL; i != 3; ++i )
{
if ( *(_DWORD *)snake_head == apple[2 * i] && *(_DWORD *)(snake_head + 4) == apple[2 * i + 1] )
{
++*(_DWORD *)(snake_head + 12);
func9(i);
g_speed = (int)((double)(int)g_speed - (double)(int)g_speed * 0.01);
return 1LL;
}
}
return 0LL;
}

original_code:
int eat_apple()
{
 int i;
 for (i = 0; i < 3; i++) {
  if (snake_head->x == apple[i].x && snake_head->y == apple[i].y) {
   snake_head->count++;
   update_apple(i);
   g_speed -= g_speed * 0.01;
   return 1;
  }
 }
 return 0;
}


original_code:
int snake_move()
{
 struct segment *p = snake_head;
 struct segment *tail = ((void *)0);
 tail = snake_head;
 while (tail->next)
  tail = tail->next;
 if (snake_head != tail) {
  if (tail->count == 0)
   change_tail(&tail);
  tail->count--;
  p->count++;
 }
 switch(p->dir) {
 case -1:
  p->y++;
  p->y = p->y + eat_apple();
  break;
 case 1:
  p->y--;
  p->y = p->y - eat_apple();
  break;
 case 2:
  p->x++;
  p->x = p->x + eat_apple();
  break;
 case -2 :
  p->x--;
  p->x = p->x - eat_apple();
  break;
 }
 if (terminated_check())
  return -1;
 return 0;
}


decompiled_code:
void __noreturn quit_game()
{
wmove(game_erea, real_y / 2, real_x / 2);
waddnstr(game_erea, "Game Over\n", -1);
wrefresh(game_erea);
wgetch(stdscr);
endwin();
exit(0);
}

canonical_decompiled_code:
void __noreturn func12()
{
wmove(game_erea, real_y / 2, real_x / 2);
waddnstr(game_erea, "Game Over\n", -1);
wrefresh(game_erea);
wgetch(stdscr);
endwin();
exit(0);
}

original_code:
void quit_game()
{
 wmove(game_erea, real_y / 2, real_x / 2);
 waddnstr(game_erea,"Game Over\n",-1);
 wrefresh(game_erea);
 wgetch(stdscr);
 endwin();
 exit(0);
}


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

if ( a1 )
{
result = snake_head;
*(_QWORD *)(a1 + 24) = snake_head;
*(_QWORD *)(a1 + 16) = a1;
*(_QWORD *)(result + 16) = a1;
snake_head = a1;
}
return result;
}

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

if ( a1 )
{
result = snake_head;
*(_QWORD *)(a1 + 24) = snake_head;
*(_QWORD *)(a1 + 16) = a1;
*(_QWORD *)(result + 16) = a1;
snake_head = a1;
}
return result;
}

original_code:
void insert_head(struct segment *p)
{
 if (p == ((void *)0))
  return;
 struct segment *tmp = snake_head;
 p->next = tmp;
 p->pre = p;
 tmp->pre = p;
 snake_head = p;
}


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

result = wgetch(game_erea);
if ( result == 119 )
return 1;
if ( result > 119 )
{
if ( result == 260 )
{
result = -2;
}
else if ( result <= 260 )
{
if ( result == 258 )
result = -1;
else
result = result == 259;
}
else
{
result = 2 * (result == 261);
}
}
else if ( result == 97 )
{
result = -2;
}
else if ( result <= 97 )
{
if ( result != 32 )
result = 0;
}
else if ( result == 100 )
{
result = 2;
}
else
{
result = -(result == 115);
}
return result;
}

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

result = wgetch(game_erea);
if ( result == 119 )
return 1;
if ( result > 119 )
{
if ( result == 260 )
{
result = -2;
}
else if ( result <= 260 )
{
if ( result == 258 )
result = -1;
else
result = result == 259;
}
else
{
result = 2 * (result == 261);
}
}
else if ( result == 97 )
{
result = -2;
}
else if ( result <= 97 )
{
if ( result != 32 )
result = 0;
}
else if ( result == 100 )
{
result = 2;
}
else
{
result = -(result == 115);
}
return result;
}

original_code:
int get_arrow_key(void)
{
 int key;
 switch (wgetch(game_erea)) {
 case 'a':
 case 0404:
  key = -2;
  break;
 case 'd':
 case 0405:
  key = 2;
  break;
 case 'w':
 case 0403:
  key = 1;
  break;
 case 's':
 case 0402:
  key = -1;
  break;
 case ' ':
  key = ' ';
  break;
 default:
  key = 0;
  break;
 }
 return key;
}

canonical_original_code:
int get_arrow_key()
{
 int key;
 switch (wgetch(game_erea)) {
 case 'a':
 case 0404:
  key = -2;
  break;
 case 'd':
 case 0405:
  key = 2;
  break;
 case 'w':
 case 0403:
  key = 1;
  break;
 case 's':
 case 0402:
  key = -1;
  break;
 case ' ':
  key = ' ';
  break;
 default:
  key = 0;
  break;
 }
 return key;
}

variable_types: key int


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

result = pthread_mutex_trylock(&run_lock);
if ( result )
result = pthread_mutex_unlock(&run_lock);
return result;
}

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

result = pthread_mutex_trylock(&run_lock);
if ( result )
result = pthread_mutex_unlock(&run_lock);
return result;
}

original_code:
void resume_and_pause_snake()
{
 if (pthread_mutex_trylock(&run_lock))
  pthread_mutex_unlock(&run_lock);
}


decompiled_code:
void __fastcall __noreturn guide_snake(void *a1)
{
_DWORD *v1; // rax
int v2; // ebx

keypad(game_erea, 1);
while ( 1 )
{
do
v2 = get_arrow_key();
while ( !*(_DWORD *)(snake_head + 12) );
if ( v2 <= 2 )
{
if ( v2 > 0 || (unsigned int)v2 >= 0xFFFFFFFE )
{
pthread_mutex_lock(&sync_lock);
v1 = new_segment(v2);
insert_head((__int64)v1);
pthread_mutex_unlock(&sync_lock);
}
}
else if ( v2 == 32 )
{
resume_and_pause_snake();
}
}
}

canonical_decompiled_code:
void __fastcall __noreturn func16(void *a1)
{
_DWORD *v1; // rax
int v2; // ebx

keypad(game_erea, 1);
while ( 1 )
{
do
v2 = func14();
while ( !*(_DWORD *)(snake_head + 12) );
if ( v2 <= 2 )
{
if ( v2 > 0 || (unsigned int)v2 >= 0xFFFFFFFE )
{
pthread_mutex_lock(&sync_lock);
v1 = new_segment(v2);
func13((__int64)v1);
pthread_mutex_unlock(&sync_lock);
}
}
else if ( v2 == 32 )
{
func15();
}
}
}

original_code:
void *guide_snake(void * data)
{
 int key;
 struct segment *new;
 keypad(game_erea, 1);
 while (1) {
  key = get_arrow_key();
  if (snake_head->count == 0)
   continue;
  switch (key){
  case -1:
  case 1:
  case 2:
  case -2:
   pthread_mutex_lock(&sync_lock);
   new = new_segment(key);
   insert_head(new);
   pthread_mutex_unlock(&sync_lock);
   break;
  case ' ':
   resume_and_pause_snake();
   break;
  default:
   break;
  }
 }
}

canonical_original_code:
void *guide_snake(void *data)
{
 int key;
 struct segment *new;
 keypad(game_erea, 1);
 while (1) {
  key = get_arrow_key();
  if (snake_head->count == 0)
   continue;
  switch (key){
  case -1:
  case 1:
  case 2:
  case -2:
   pthread_mutex_lock(&sync_lock);
   new = new_segment(key);
   insert_head(new);
   pthread_mutex_unlock(&sync_lock);
   break;
  case ' ':
   resume_and_pause_snake();
   break;
  default:
   break;
  }
 }
}

variable_types:
data
void *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
_DWORD *v4; // rdx
__int64 v5; // rax
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

initscr();
if ( real_x + 1 < COLS && real_y + 1 < LINES )
{
game_erea = derwin(stdscr, real_y + 2, real_x + 2, (LINES - real_y - 2) / 5, (COLS - real_x - 2) / 2);
pthread_mutex_init(&sync_lock, 0LL);
pthread_mutex_init(&run_lock, 0LL);
mem_pool_init(&snake_pool);
noecho();
v4 = (_DWORD *)item_pop(&snake_pool);
snake_head = (__int64)v4;
result = -1;
if ( v4 )
{
*v4 = 15;
*(_DWORD *)(snake_head + 4) = 20;
v5 = snake_head;
*(_DWORD *)(snake_head + 8) = 2;
*(_DWORD *)(v5 + 12) = 15;
*(_QWORD *)(v5 + 16) = v5;
*(_QWORD *)(v5 + 24) = 0LL;
pthread_create(newthread, 0LL, (void *(*)(void *))guide_snake, 0LL);
update_apple(0xFFFFFFFF);
while ( 1 )
{
pthread_mutex_lock(&run_lock);
pthread_mutex_unlock(&run_lock);
pthread_mutex_lock(&sync_lock);
if ( (unsigned int)snake_move() )
break;
pthread_mutex_unlock(&sync_lock);
display();
if ( ((*(_DWORD *)(snake_head + 8) + 2) & 0xFFFFFFFB) != 0 )
usleep((int)((double)(int)g_speed * 2.5));
else
usleep(g_speed);
}
pthread_cancel(newthread[0]);
quit_game();
}
}
else
{
wmove(stdscr, 0, 0);
printw(
"To play this game, the window size request at least x : 94, y : 30,\n but this window size is x : %d, y : %d\n",
(unsigned int)COLS,
(unsigned int)LINES);
wgetch(stdscr);
result = 0;
}
return result;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
_DWORD *v4; // rdx
__int64 v5; // rax
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

initscr();
if ( real_x + 1 < COLS && real_y + 1 < LINES )
{
game_erea = derwin(stdscr, real_y + 2, real_x + 2, (LINES - real_y - 2) / 5, (COLS - real_x - 2) / 2);
pthread_mutex_init(&sync_lock, 0LL);
pthread_mutex_init(&run_lock, 0LL);
mem_pool_init(&snake_pool);
noecho();
v4 = (_DWORD *)item_pop(&snake_pool);
snake_head = (__int64)v4;
result = -1;
if ( v4 )
{
*v4 = 15;
*(_DWORD *)(snake_head + 4) = 20;
v5 = snake_head;
*(_DWORD *)(snake_head + 8) = 2;
*(_DWORD *)(v5 + 12) = 15;
*(_QWORD *)(v5 + 16) = v5;
*(_QWORD *)(v5 + 24) = 0LL;
pthread_create(newthread, 0LL, (void *(*)(void *))guide_snake, 0LL);
func9(0xFFFFFFFF);
while ( 1 )
{
pthread_mutex_lock(&run_lock);
pthread_mutex_unlock(&run_lock);
pthread_mutex_lock(&sync_lock);
if ( (unsigned int)func11() )
break;
pthread_mutex_unlock(&sync_lock);
func5();
if ( ((*(_DWORD *)(snake_head + 8) + 2) & 0xFFFFFFFB) != 0 )
usleep((int)((double)(int)g_speed * 2.5));
else
usleep(g_speed);
}
pthread_cancel(newthread[0]);
func12();
}
}
else
{
wmove(stdscr, 0, 0);
printw(
"To play this game, the window size request at least x : 94, y : 30,\n but this window size is x : %d, y : %d\n",
(unsigned int)COLS,
(unsigned int)LINES);
wgetch(stdscr);
result = 0;
}
return result;
}

original_code:
int main(void)
{
 pthread_t tid;
  initscr();
 if (COLS < real_x + 2 || LINES < real_y + 2) {
  wmove(stdscr,(0),(0));
  printw("To play this game, the window size request at least x : 94, y : 30,\n but this window size is x : %d, y : %d\n", COLS, LINES);
  wgetch(stdscr);
  return 0;
 }
 game_erea = derwin(stdscr, real_y + 2, real_x + 2, (LINES - real_y - 2) / 5, (COLS - real_x - 2) / 2);
 pthread_mutex_init(&sync_lock, ((void *)0));
 pthread_mutex_init(&run_lock, ((void *)0));
 mem_pool_init(&snake_pool);
 noecho();
 snake_head = (struct segment *)item_pop(&snake_pool);
 if (((void *)0) == snake_head)
  return -1;
 snake_head->x = 15;
 snake_head->y = 20;
 snake_head->dir = 2;
 snake_head->count = 15;
 snake_head->pre = snake_head;
 snake_head->next = ((void *)0);
 pthread_create(&tid, ((void *)0), guide_snake, ((void *)0));
 update_apple(-1);
 while(1) {
  {pthread_mutex_lock(&run_lock);pthread_mutex_unlock(&run_lock);};
  pthread_mutex_lock(&sync_lock);
  if(snake_move()) {
   pthread_cancel(tid);
   quit_game();
  }
  pthread_mutex_unlock(&sync_lock);
  display();
  if (snake_head->dir == 2 ||
   snake_head->dir == -2)
   usleep(g_speed);
  else
   usleep(g_speed * 2.5);
 }
 return 0;
}

canonical_original_code:
int main()
{
 unsigned long tid;
  initscr();
 if (COLS < real_x + 2 || LINES < real_y + 2) {
  wmove(stdscr,(0),(0));
  printw("To play this game, the window size request at least x : 94, y : 30,\n but this window size is x : %d, y : %d\n", COLS, LINES);
  wgetch(stdscr);
  return 0;
 }
 game_erea = derwin(stdscr, real_y + 2, real_x + 2, (LINES - real_y - 2) / 5, (COLS - real_x - 2) / 2);
 pthread_mutex_init(&sync_lock, ((void *)0));
 pthread_mutex_init(&run_lock, ((void *)0));
 mem_pool_init(&snake_pool);
 noecho();
 snake_head = (struct segment *)item_pop(&snake_pool);
 if (((void *)0) == snake_head)
  return -1;
 snake_head->x = 15;
 snake_head->y = 20;
 snake_head->dir = 2;
 snake_head->count = 15;
 snake_head->pre = snake_head;
 snake_head->next = ((void *)0);
 pthread_create(&tid, ((void *)0), guide_snake, ((void *)0));
 update_apple(-1);
 while(1) {
  {pthread_mutex_lock(&run_lock);pthread_mutex_unlock(&run_lock);};
  pthread_mutex_lock(&sync_lock);
  if(snake_move()) {
   pthread_cancel(tid);
   quit_game();
  }
  pthread_mutex_unlock(&sync_lock);
  display();
  if (snake_head->dir == 2 ||
   snake_head->dir == -2)
   usleep(g_speed);
  else
   usleep(g_speed * 2.5);
 }
 return 0;
}

variable_types:
tid
unsigned long


decompiled_code:
__int64 __fastcall mem_pool_init(__int64 a1)
{
unsigned int v2; // edi
__int64 v3; // rbp
void **v4; // r12
void *v5; // rdi
unsigned int v6; // eax
__int64 result; // rax
__int64 v8; // r12
unsigned __int64 v9; // rbp

v2 = *(_DWORD *)a1;
if ( v2 <= 1 )
return 0xFFFFFFFFLL;
if ( *(int *)(a1 + 4) <= 0 )
return 0xFFFFFFFFLL;
*(_QWORD *)(a1 + 8) = malloc(8LL * v2);
v3 = 0LL;
while ( 1 )
{
v4 = (void **)(*(_QWORD *)(a1 + 8) + 8 * v3);
*v4 = malloc(*(int *)(a1 + 4));
v5 = *(void **)(*(_QWORD *)(a1 + 8) + 8 * v3);
if ( !v5 )
break;
memset(v5, 0, *(int *)(a1 + 4));
v6 = *(_DWORD *)a1 >> 1;
if ( v6 <= (unsigned int)++v3 )
{
*(_DWORD *)(a1 + 16) = v6;
*(_DWORD *)(a1 + 32) = v6;
return 0LL;
}
}
result = 0xFFFFFFFFLL;
if ( (int)v3 - 1 >= 0 )
{
v8 = 8LL * ((int)v3 - 1);
v9 = 8 * ((int)v3 - (unsigned __int64)(unsigned int)(v3 - 1)) - 16;
do
{
free(*(void **)(*(_QWORD *)(a1 + 8) + v8));
v8 -= 8LL;
}
while ( v8 != v9 );
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
unsigned int v2; // edi
__int64 v3; // rbp
void **v4; // r12
void *v5; // rdi
unsigned int v6; // eax
__int64 result; // rax
__int64 v8; // r12
unsigned __int64 v9; // rbp

v2 = *(_DWORD *)a1;
if ( v2 <= 1 )
return 0xFFFFFFFFLL;
if ( *(int *)(a1 + 4) <= 0 )
return 0xFFFFFFFFLL;
*(_QWORD *)(a1 + 8) = malloc(8LL * v2);
v3 = 0LL;
while ( 1 )
{
v4 = (void **)(*(_QWORD *)(a1 + 8) + 8 * v3);
*v4 = malloc(*(int *)(a1 + 4));
v5 = *(void **)(*(_QWORD *)(a1 + 8) + 8 * v3);
if ( !v5 )
break;
memset(v5, 0, *(int *)(a1 + 4));
v6 = *(_DWORD *)a1 >> 1;
if ( v6 <= (unsigned int)++v3 )
{
*(_DWORD *)(a1 + 16) = v6;
*(_DWORD *)(a1 + 32) = v6;
return 0LL;
}
}
result = 0xFFFFFFFFLL;
if ( (int)v3 - 1 >= 0 )
{
v8 = 8LL * ((int)v3 - 1);
v9 = 8 * ((int)v3 - (unsigned __int64)(unsigned int)(v3 - 1)) - 16;
do
{
free(*(void **)(*(_QWORD *)(a1 + 8) + v8));
v8 -= 8LL;
}
while ( v8 != v9 );
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int mem_pool_init(mem_pool_t *pool)
{
 int i;
 if (pool->item_max_quantum < 2 || pool->item_size < 1)
  return -1;
 pool->available = (void **)malloc(pool->item_max_quantum * sizeof(void *));
 for (i = 0; i < pool->item_max_quantum / 2; i++) {
  pool->available[i] = malloc(pool->item_size);
  if (pool->available[i] == ((void *)0))
   goto err;
  memset(pool->available[i], 0,pool->item_size);
 }
 pool->avail_cnt = pool->item_max_quantum / 2;
 pool->total_malloc = pool->avail_cnt;
 return 0;
err:
 for (i--; i >= 0; i--) {
  free(pool->available[i]);
 }
 return -1;
}

canonical_original_code:
int mem_pool_init(struct mem_pool_struct *pool)
{
 int i;
 if (pool->item_max_quantum < 2 || pool->item_size < 1)
  return -1;
 pool->available = (void **)malloc(pool->item_max_quantum * sizeof(void *));
 for (i = 0; i < pool->item_max_quantum / 2; i++) {
  pool->available[i] = malloc(pool->item_size);
  if (pool->available[i] == ((void *)0))
   goto err;
  memset(pool->available[i], 0,pool->item_size);
 }
 pool->avail_cnt = pool->item_max_quantum / 2;
 pool->total_malloc = pool->avail_cnt;
 return 0;
err:
 for (i--; i >= 0; i--) {
  free(pool->available[i]);
 }
 return -1;
}

variable_types: struct mem_pool_struct { unsigned int item_max_quantum; int item_size; void **available; unsigned int avail_cnt; void **used; unsigned int total_malloc; } *

variable_types: i int


decompiled_code:
void *__fastcall item_pop(__int64 a1)
{
int v1; // eax
unsigned int v2; // ebp
void *result; // rax
unsigned int v4; // eax

v1 = *(_DWORD *)(a1 + 16);
if ( v1 )
{
v4 = v1 - 1;
*(_DWORD *)(a1 + 16) = v4;
result = *(void **)(*(_QWORD *)(a1 + 8) + 8LL * v4);
}
else
{
v2 = *(_DWORD *)(a1 + 32);
result = 0LL;
if ( v2 < *(_DWORD *)a1 )
{
result = malloc(*(int *)(a1 + 4));
*(_DWORD *)(a1 + 32) = v2 + 1;
}
}
return result;
}

canonical_decompiled_code:
void *__fastcall func1(__int64 a1)
{
int v1; // eax
unsigned int v2; // ebp
void *result; // rax
unsigned int v4; // eax

v1 = *(_DWORD *)(a1 + 16);
if ( v1 )
{
v4 = v1 - 1;
*(_DWORD *)(a1 + 16) = v4;
result = *(void **)(*(_QWORD *)(a1 + 8) + 8LL * v4);
}
else
{
v2 = *(_DWORD *)(a1 + 32);
result = 0LL;
if ( v2 < *(_DWORD *)a1 )
{
result = malloc(*(int *)(a1 + 4));
*(_DWORD *)(a1 + 32) = v2 + 1;
}
}
return result;
}

original_code:
void* item_pop(mem_pool_t * pool)
{
 void *p;
 unsigned int used_cnt = pool->total_malloc - pool->avail_cnt;
 if (pool->avail_cnt < 1)
  if (pool->total_malloc < pool->item_max_quantum) {
   p = (void *)malloc(pool->item_size);
   pool->total_malloc++;
   return p ? p : ((void *)0);
  } else
   return ((void *)0);
 pool->avail_cnt--;
 return pool->available[pool->avail_cnt];
}

canonical_original_code:
void *item_pop(struct mem_pool_struct *pool)
{
 void *p;
 unsigned int used_cnt = pool->total_malloc - pool->avail_cnt;
 if (pool->avail_cnt < 1)
  if (pool->total_malloc < pool->item_max_quantum) {
   p = (void *)malloc(pool->item_size);
   pool->total_malloc++;
   return p ? p : ((void *)0);
  } else
   return ((void *)0);
 pool->avail_cnt--;
 return pool->available[pool->avail_cnt];
}

variable_types:
p
void *

user_defined_types: struct mem_pool_struct { unsigned int item_max_quantum; int item_size; void **available; unsigned int avail_cnt; void **used; unsigned int total_malloc; }