hasAdjacentMonocolors

decompiled_code:
__int64 __fastcall hasAdjacentMonocolors(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rbp
__int64 v3; // rbx
__int64 result; // rax

v1 = getNextLine(a1);
if ( !v1 || (v2 = v1, !(unsigned int)lineFilled(v1)) || (result = lineDiversity(v2), (_DWORD)result != 1) )
{
v3 = getPreviousLine(a1);
result = 0LL;
if ( v3 )
{
result = lineFilled(v3);
if ( (_DWORD)result )
result = (unsigned int)lineDiversity(v3) == 1;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rbp
__int64 v3; // rbx
__int64 result; // rax

v1 = func0(a1);
if ( !v1 || (v2 = v1, !(unsigned int)func7(v1)) || (result = func6(v2), (_DWORD)result != 1) )
{
v3 = func1(a1);
result = 0LL;
if ( v3 )
{
result = func7(v3);
if ( (_DWORD)result )
result = (unsigned int)func6(v3) == 1;
}
}
return result;
}

original_code:
int hasAdjacentMonocolors(Line *line) {
 Line *aux;
 aux = getNextLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 aux = getPreviousLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 return 0;
}

canonical_original_code:
int hasAdjacentMonocolors(struct Line *line) {
 struct Line *aux;
 aux = getNextLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 aux = getPreviousLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 return 0;
}


repo: joaomlneto/iaed-tetraminos

decompiled_code:
__int64 __fastcall getLineT_location(__int64 a1)
{
return *(_QWORD *)(a1 + 32);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
return *(_QWORD *)(a1 + 32);
}

original_code:
t_location** getLineT_location(Line *l) {
 return (l->pieces);
}

canonical_original_code:
struct t_location **getLineT_location(struct Line *l) {
 return (l->pieces);
}

variable_types:
l
struct Line *

return_type: struct t_location { int hash_pos; int num_lines; struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location **pieces; int num_t_locations; } **lines; } **

user_defined_types: struct t_location { int hash_pos; int num_lines; struct Line **lines; }


deleteLine

decompiled_code:
void __fastcall deleteLine(void *ptr)
{
void *v1; // rax

if ( ptr )
{
v1 = (void *)getLineT_location((__int64)ptr);
if ( v1 )
free(v1);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func10(void *ptr)
{
void *v1; // rax

if ( ptr )
{
v1 = (void *)func9((__int64)ptr);
if ( v1 )
free(v1);
free(ptr);
}
}

original_code:
void deleteLine(Line *line) {
 if(line != ((void *)0)) {
  if(getLineT_location(line) != ((void *)0))
   free(getLineT_location(line));
  free(line);
 }
}

canonical_original_code:
void deleteLine(struct Line *line) {
 if(line != ((void *)0)) {
  if(getLineT_location(line) != ((void *)0))
   free(getLineT_location(line));
  free(line);
 }
}

variable_types: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *

return_type: void

user_defined_types: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location **pieces; int num_t_locations; }


getLineTLIndex

decompiled_code:
__int64 __fastcall getLineTLIndex(__int64 a1)
{
return *(unsigned int *)(a1 + 40);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
return *(unsigned int *)(a1 + 40);
}

original_code:
int getLineTLIndex(Line *l) {
 return l->num_t_locations;
}

canonical_original_code:
int getLineTLIndex(struct Line *l) {
 return l->num_t_locations;
}

return_type: int


setLineTLIndex

decompiled_code:
void __fastcall setLineTLIndex(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 40) = a2;
}

canonical_decompiled_code:
void __fastcall func12(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 40) = a2;
}

original_code:
void setLineTLIndex(Line *l, int i) {
 (l->num_t_locations) = i;
}

canonical_original_code:
void setLineTLIndex(struct Line *l, int i) {
 (l->num_t_locations) = i;
}

variable_types: i int


newLine

decompiled_code:
_QWORD *newLine()
{
_QWORD *v0; // rbx
__int64 v1; // rax

v0 = malloc(0x30uLL);
setNextLine((__int64)v0, 0LL);
setPreviousLine(v0, 0LL);
v1 = getLineColumn((__int64)v0);
vectorCharInit(v1, 10LL, 32LL);
setLineTLIndex((__int64)v0, 0);
v0[4] = 0LL;
return v0;
}

canonical_decompiled_code:
_QWORD *func13()
{
_QWORD *v0; // rbx
__int64 v1; // rax

v0 = malloc(0x30uLL);
func3((__int64)v0, 0LL);
func4(v0, 0LL);
v1 = func2((__int64)v0);
vectorCharInit(v1, 10LL, 32LL);
func12((__int64)v0, 0);
v0[4] = 0LL;
return v0;
}

original_code:
Line* newLine() {
 Line *l = malloc(sizeof(Line));
 setNextLine(l, ((void *)0));
 setPreviousLine(l, ((void *)0));
 vectorCharInit(getLineColumn(l), 10, ' ');
 setLineTLIndex(l, 0);
 l->pieces = ((void *)0);
 return l;
}

canonical_original_code:
struct Line *newLine() {
 struct Line *l = malloc(sizeof(Line));
 setNextLine(l, ((void *)0));
 setPreviousLine(l, ((void *)0));
 vectorCharInit(getLineColumn(l), 10, ' ');
 setLineTLIndex(l, 0);
 l->pieces = ((void *)0);
 return l;
}

return_type: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *


processBuffer

decompiled_code:
__int64 __fastcall processBuffer(__int64 a1, char *a2)
{
char *v2; // rax
unsigned int v3; // ebx
char *v4; // rax
unsigned int v5; // er12
char *v6; // rax
__int64 v7; // r13
char *v8; // r14
int v9; // eax
char *v10; // rbx
__int64 v11; // r12
unsigned int v12; // eax
int v13; // ebx
int v14; // eax

v2 = strtok(a2, " \n");
v3 = atoi(v2);
v4 = strtok(0LL, " \n");
v5 = atoi(v4);
v6 = strtok(0LL, " \n");
v7 = newPiece(v3, 0LL, v5, (unsigned int)*v6);
v8 = (char *)getPieceColumns(v7);
getColumnSpan(v7);
v9 = getColumnSpan(v7);
if ( v9 > 0 )
{
v10 = &v8[4 * v9];
v11 = (__int64)&v10[-4 * (v9 - 1) - 4];
do
{
*((_DWORD *)v10 - 1) = getGameAreaColumnHeight(a1, *((unsigned int *)v10 - 1));
v10 -= 4;
}
while ( v10 != (char *)v11 );
}
v12 = getColumnSpan(v7);
v13 = vectorMax(v8, v12);
v14 = getLineSpan(v7);
setPieceLine(v7, (unsigned int)(v13 + v14));
free(v8);
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, char *a2)
{
char *v2; // rax
unsigned int v3; // ebx
char *v4; // rax
unsigned int v5; // er12
char *v6; // rax
__int64 v7; // r13
char *v8; // r14
int v9; // eax
char *v10; // rbx
__int64 v11; // r12
unsigned int v12; // eax
int v13; // ebx
int v14; // eax

v2 = strtok(a2, " \n");
v3 = atoi(v2);
v4 = strtok(0LL, " \n");
v5 = atoi(v4);
v6 = strtok(0LL, " \n");
v7 = newPiece(v3, 0LL, v5, (unsigned int)*v6);
v8 = (char *)getPieceColumns(v7);
getColumnSpan(v7);
v9 = getColumnSpan(v7);
if ( v9 > 0 )
{
v10 = &v8[4 * v9];
v11 = (__int64)&v10[-4 * (v9 - 1) - 4];
do
{
*((_DWORD *)v10 - 1) = getGameAreaColumnHeight(a1, *((unsigned int *)v10 - 1));
v10 -= 4;
}
while ( v10 != (char *)v11 );
}
v12 = getColumnSpan(v7);
v13 = vectorMax(v8, v12);
v14 = getLineSpan(v7);
setPieceLine(v7, (unsigned int)(v13 + v14));
free(v8);
return v7;
}

original_code:
tetromino* processBuffer(GameArea *gameArea, char *buffer) {
 tetromino *t;
 int piece_type;
 int *piece_columns, num_cols;
 int piece_column;
 char piece_color;
 piece_type = atoi(strtok(buffer, " \n\0"));
 piece_column = atoi(strtok(((void *)0), " \n\0"));
 piece_color = *strtok(((void *)0), " \n\0");
 t = newPiece(piece_type, 0, piece_column, piece_color);
 piece_columns = getPieceColumns(t);
 num_cols = getColumnSpan(t);
 for(num_cols = getColumnSpan(t); num_cols > 0; num_cols--) {
  piece_columns[num_cols-1] = getGameAreaColumnHeight(gameArea, piece_columns[num_cols-1]);
 }
 setPieceLine(t, vectorMax(piece_columns, getColumnSpan(t)) + getLineSpan(t));
 free(piece_columns);
 return t;
}

canonical_original_code:
struct tetromino *processBuffer(struct GameArea *gameArea, char *buffer) {
 struct tetromino *t;
 int piece_type;
 int *piece_columns; int num_cols;
 int piece_column;
 char piece_color;
 piece_type = atoi(strtok(buffer, " \n\0"));
 piece_column = atoi(strtok(((void *)0), " \n\0"));
 piece_color = *strtok(((void *)0), " \n\0");
 t = newPiece(piece_type, 0, piece_column, piece_color);
 piece_columns = getPieceColumns(t);
 num_cols = getColumnSpan(t);
 for(num_cols = getColumnSpan(t); num_cols > 0; num_cols--) {
  piece_columns[num_cols-1] = getGameAreaColumnHeight(gameArea, piece_columns[num_cols-1]);
 }
 setPieceLine(t, vectorMax(piece_columns, getColumnSpan(t)) + getLineSpan(t));
 free(piece_columns);
 return t;
}

variable_types: struct GameArea { struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *gameLineFirst; struct Line *gameLineLast; int num_lines; struct HeightMap { int columns[10]; } *heightMap; struct Line *deletedLinesFirst; struct Line *deletedLinesLast; int num_deleted_lines; int score; int *piece_count; } *

variable_types:
buffer
char *

variable_types: struct tetromino { struct position { int line; int column; } position; int type; char color; } *

user_defined_types: struct GameArea { struct Line *gameLineFirst; struct Line *gameLineLast; int num_lines; struct HeightMap *heightMap; struct Line *deletedLinesFirst; struct Line *deletedLinesLast; int num_deleted_lines; int score; int *piece_count; }

user_defined_types: struct tetromino { struct position position; int type; char color; }


gravity

decompiled_code:
void __fastcall gravity(__int64 a1, __int64 a2)
{
int v2; // er15
char *v3; // r14
int v4; // eax
char *v5; // rbx
int v6; // eax

v2 = getFloorSize(a2);
v3 = (char *)getFloor(a2);
while ( v2 <= 0 )
{
LABEL_3:
v4 = getPieceLine(a2);
setPieceLine(a2, (unsigned int)(v4 - 1));
}
v5 = v3;
while ( (unsigned __int8)getPosition(a1, v5) == 32 )
{
v6 = getLine(v5);
setLine(v5, (unsigned int)(v6 - 1));
v5 += 8;
if ( v5 == &v3[8 * (v2 - 1) + 8] )
goto LABEL_3;
}
free(v3);
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1, __int64 a2)
{
int v2; // er15
char *v3; // r14
int v4; // eax
char *v5; // rbx
int v6; // eax

v2 = getFloorSize(a2);
v3 = (char *)getFloor(a2);
while ( v2 <= 0 )
{
LABEL_3:
v4 = getPieceLine(a2);
setPieceLine(a2, (unsigned int)(v4 - 1));
}
v5 = v3;
while ( (unsigned __int8)getPosition(a1, v5) == 32 )
{
v6 = getLine(v5);
setLine(v5, (unsigned int)(v6 - 1));
v5 += 8;
if ( v5 == &v3[8 * (v2 - 1) + 8] )
goto LABEL_3;
}
free(v3);
}

original_code:
void gravity(GameArea *gameArea, tetromino *t) {
 int i, floor_size;
 position *floor;
 floor_size = getFloorSize(t);
 floor = getFloor(t);
 while(1) {
  for (i=0; i<floor_size; i++) {
   if(getPosition(gameArea, &floor[i]) != ' ') {
    free(floor);
    return;
   }
   else {
    setLine(&floor[i], getLine(&floor[i])-1);
   }
  }
  setPieceLine(t, getPieceLine(t) - 1);
 }
 return;
}

canonical_original_code:
void gravity(struct GameArea *gameArea, struct tetromino *t) {
 int i; int floor_size;
 struct position *floor;
 floor_size = getFloorSize(t);
 floor = getFloor(t);
 while(1) {
  for (i=0; i<floor_size; i++) {
   if(getPosition(gameArea, &floor[i]) != ' ') {
    free(floor);
    return;
   }
   else {
    setLine(&floor[i], getLine(&floor[i])-1);
   }
  }
  setPieceLine(t, getPieceLine(t) - 1);
 }
 return;
}

variable_types: struct position { int line; int column; } *


deleteFilledLines

decompiled_code:
void __fastcall deleteFilledLines(__int64 a1, __int64 a2)
{
_DWORD *v2; // r15
int v3; // eax
_DWORD *v4; // rbx
__int64 v5; // r14
__int64 v6; // rbp

v2 = (_DWORD *)getPieceLines(a2);
v3 = getLineSpan(a2);
if ( v3 > 0 )
{
v4 = v2;
v5 = (__int64)&v2[v3 - 1 + 1];
do
{
v6 = getGameLine(a1, (unsigned int)*v4);
if ( (unsigned int)lineFilled(v6) )
{
if ( (unsigned int)hasAdjacentMonocolors(v6) )
{
if ( (unsigned int)lineDiversity(v6) == 1 )
{
increaseScore(a1, 3LL);
eraseLine(a1, (unsigned int)*v4);
}
}
else if ( (unsigned int)lineDiversity(v6) == 1 )
{
increaseScore(a1, 3LL);
eraseLine(a1, (unsigned int)(*v4 + 1));
eraseLine(a1, (unsigned int)*v4);
eraseLine(a1, (unsigned int)(*v4 - 1));
}
else
{
increaseScore(a1, 1LL);
eraseLine(a1, (unsigned int)*v4);
}
}
++v4;
}
while ( v4 != (_DWORD *)v5 );
}
free(v2);
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1, __int64 a2)
{
_DWORD *v2; // r15
int v3; // eax
_DWORD *v4; // rbx
__int64 v5; // r14
__int64 v6; // rbp

v2 = (_DWORD *)getPieceLines(a2);
v3 = getLineSpan(a2);
if ( v3 > 0 )
{
v4 = v2;
v5 = (__int64)&v2[v3 - 1 + 1];
do
{
v6 = getGameLine(a1, (unsigned int)*v4);
if ( (unsigned int)lineFilled(v6) )
{
if ( (unsigned int)hasAdjacentMonocolors(v6) )
{
if ( (unsigned int)lineDiversity(v6) == 1 )
{
increaseScore(a1, 3LL);
eraseLine(a1, (unsigned int)*v4);
}
}
else if ( (unsigned int)lineDiversity(v6) == 1 )
{
increaseScore(a1, 3LL);
eraseLine(a1, (unsigned int)(*v4 + 1));
eraseLine(a1, (unsigned int)*v4);
eraseLine(a1, (unsigned int)(*v4 - 1));
}
else
{
increaseScore(a1, 1LL);
eraseLine(a1, (unsigned int)*v4);
}
}
++v4;
}
while ( v4 != (_DWORD *)v5 );
}
free(v2);
}

original_code:
void deleteFilledLines(GameArea *gameArea, tetromino *t) {
 int* lines = getPieceLines(t);
 int linespan = getLineSpan(t);
 int i;
 Line* line;
 for(i=0; i<linespan; i++) {
  line = getGameLine(gameArea, lines[i]);
  if(lineFilled(line)) {
   if(hasAdjacentMonocolors(line)) {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]);
    }
   }
   else {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]+1);
     eraseLine(gameArea, lines[i]);
     eraseLine(gameArea, lines[i]-1);
    }
    else {
     increaseScore(gameArea, 1);
     eraseLine(gameArea, lines[i]);
    }
   }
  }
 }
 free(lines);
 return;
}

canonical_original_code:
void deleteFilledLines(struct GameArea *gameArea, struct tetromino *t) {
 int *lines = getPieceLines(t);
 int linespan = getLineSpan(t);
 int i;
 struct Line *line;
 for(i=0; i<linespan; i++) {
  line = getGameLine(gameArea, lines[i]);
  if(lineFilled(line)) {
   if(hasAdjacentMonocolors(line)) {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]);
    }
   }
   else {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]+1);
     eraseLine(gameArea, lines[i]);
     eraseLine(gameArea, lines[i]-1);
    }
    else {
     increaseScore(gameArea, 1);
     eraseLine(gameArea, lines[i]);
    }
   }
  }
 }
 free(lines);
 return;
}

variable_types:
lines
int *

variable_types: linespan int

user_defined_types: struct position { int line; int column; }


readInput

decompiled_code:
int __fastcall readInput(__int64 a1)
{
int result; // eax
int v2; // er13
int i; // er12
__int64 v4; // rbx
char v5[56]; // [rsp+0h] [rbp-38h] BYREF

fgets(v5, 16, stdin);
result = atoi(v5);
if ( result > 0 )
{
v2 = result;
for ( i = 0; i != v2; ++i )
{
fgets(v5, 16, stdin);
v4 = processBuffer(a1, v5);
gravity(a1, v4);
insertPiece(a1, v4);
deleteFilledLines(a1, v4);
result = deletePiece(v4);
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
int result; // eax
int v2; // er13
int i; // er12
__int64 v4; // rbx
char v5[56]; // [rsp+0h] [rbp-38h] BYREF

fgets(v5, 16, stdin);
result = atoi(v5);
if ( result > 0 )
{
v2 = result;
for ( i = 0; i != v2; ++i )
{
fgets(v5, 16, stdin);
v4 = func0(a1, v5);
func1(a1, v4);
insertPiece(a1, v4);
func2(a1, v4);
result = deletePiece(v4);
}
}
return result;
}

original_code:
void readInput(GameArea *gameArea) {
 int i, num_pieces;
 char buffer[16];
 tetromino *piece;
 fgets(buffer, 16, stdin);
 num_pieces = atoi(buffer);
 for(i=0; i<num_pieces; i++) {
  fgets(buffer, 16, stdin);
  piece = processBuffer(gameArea, buffer);
  gravity(gameArea, piece);
  insertPiece(gameArea, piece);
  deleteFilledLines(gameArea, piece);
  deletePiece(piece);
 }
 return;
}

canonical_original_code:
void readInput(struct GameArea *gameArea) {
 int i; int num_pieces;
 char buffer[16];
 struct tetromino *piece;
 fgets(buffer, 16, stdin);
 num_pieces = atoi(buffer);
 for(i=0; i<num_pieces; i++) {
  fgets(buffer, 16, stdin);
  piece = processBuffer(gameArea, buffer);
  gravity(gameArea, piece);
  insertPiece(gameArea, piece);
  deleteFilledLines(gameArea, piece);
  deletePiece(piece);
 }
 return;
}

variable_types:
buffer
char [16]


writeOutput

decompiled_code:
int __fastcall writeOutput(__int64 a1)
{
__int64 v1; // rbp
int v2; // er12
unsigned int v3; // eax
unsigned int v4; // eax
__int64 i; // rbx
__int64 v6; // rax
int v7; // ebx
__int64 v8; // rax
unsigned int v9; // eax
int *v10; // r15
int j; // er14
int v12; // ebx
char v13; // al
double v15; // xmm0_8
__m128d v16; // xmm3
__int64 v17; // xmm2_8
__m128d v18; // xmm1
__int64 v19; // rbx
int v20; // ebp
__int64 k; // rbp
__int64 v22; // rax

v1 = getGameAreaLast();
v2 = getGameAreaNumLines(a1);
v3 = getGameAreaNumLines(a1);
printf("%d\n", v3);
v4 = getGameAreaScore(a1);
printf("%d\n", v4);
putchar(10);
if ( v2 > 0 )
{
do
{
putchar(124);
for ( i = 0LL; i != 10; ++i )
{
v6 = getLineColumn(v1);
putchar(*(char *)(v6 + i));
}
printf("| %d\n", (unsigned int)v2);
v1 = getPreviousLine(v1);
--v2;
}
while ( v2 );
}
putchar(32);
v7 = 10;
do
{
putchar(45);
--v7;
}
while ( v7 );
puts("\n");
v8 = getGameAreaPieceCounts(a1);
v9 = vectorSum(v8, 30LL);
printf("%d\n", v9);
v10 = (int *)getGameAreaPieceCounts(a1);
for ( j = 0; j != 30; ++j )
{
if ( *v10 > 0 )
{
v12 = 0;
do
{
v13 = int2color((unsigned int)(j % 6 + 1));
printf("%d %c\n", (unsigned int)(j / 6 + 1), (unsigned int)v13);
++v12;
}
while ( *v10 > v12 );
}
++v10;
}
putchar(10);
if ( (unsigned int)getGameAreaNumDeletedLines(a1) )
{
v15 = (double)(int)getGameAreaNumDeletedLines(a1) * 0.5;
v16.m128d_f64[0] = v15;
v17 = LC8;
*(_QWORD *)&v18.m128d_f64[0] = *(_QWORD *)&v15 & LC8;
if ( COERCE_DOUBLE(*(_QWORD *)&v15 & LC8) < 4.503599627370496e15 )
{
v18.m128d_f64[0] = (double)(int)v15;
v17 = ~LC8 & *(_QWORD *)&v15;
*(_QWORD *)&v16.m128d_f64[0] = COERCE_UNSIGNED_INT64(COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v16, v18) & LC9) + v18.m128d_f64[0]) | v17;
}
v19 = getGameAreaDeletedFirst(a1);
v20 = (int)v16.m128d_f64[0] - 1;
if ( (int)v16.m128d_f64[0] > 1 )
{
do
{
v19 = getNextLine(v19, v15, v18.m128d_f64[0], *(double *)&v17, v16.m128d_f64[0]);
--v20;
}
while ( v20 );
}
for ( k = 0LL; k != 10; ++k )
{
if ( *(_BYTE *)(getLineColumn(v19) + k) == 32 )
break;
v22 = getLineColumn(v19);
putchar(*(char *)(v22 + k));
}
}
else
{
printf("No eliminations");
}
return putchar(10);
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1)
{
__int64 v1; // rbp
int v2; // er12
unsigned int v3; // eax
unsigned int v4; // eax
__int64 i; // rbx
__int64 v6; // rax
int v7; // ebx
__int64 v8; // rax
unsigned int v9; // eax
int *v10; // r15
int j; // er14
int v12; // ebx
char v13; // al
double v15; // xmm0_8
__m128d v16; // xmm3
__int64 v17; // xmm2_8
__m128d v18; // xmm1
__int64 v19; // rbx
int v20; // ebp
__int64 k; // rbp
__int64 v22; // rax

v1 = getGameAreaLast();
v2 = getGameAreaNumLines(a1);
v3 = getGameAreaNumLines(a1);
printf("%d\n", v3);
v4 = getGameAreaScore(a1);
printf("%d\n", v4);
putchar(10);
if ( v2 > 0 )
{
do
{
putchar(124);
for ( i = 0LL; i != 10; ++i )
{
v6 = getLineColumn(v1);
putchar(*(char *)(v6 + i));
}
printf("| %d\n", (unsigned int)v2);
v1 = getPreviousLine(v1);
--v2;
}
while ( v2 );
}
putchar(32);
v7 = 10;
do
{
putchar(45);
--v7;
}
while ( v7 );
puts("\n");
v8 = getGameAreaPieceCounts(a1);
v9 = vectorSum(v8, 30LL);
printf("%d\n", v9);
v10 = (int *)getGameAreaPieceCounts(a1);
for ( j = 0; j != 30; ++j )
{
if ( *v10 > 0 )
{
v12 = 0;
do
{
v13 = int2color((unsigned int)(j % 6 + 1));
printf("%d %c\n", (unsigned int)(j / 6 + 1), (unsigned int)v13);
++v12;
}
while ( *v10 > v12 );
}
++v10;
}
putchar(10);
if ( (unsigned int)getGameAreaNumDeletedLines(a1) )
{
v15 = (double)(int)getGameAreaNumDeletedLines(a1) * 0.5;
v16.m128d_f64[0] = v15;
v17 = LC8;
*(_QWORD *)&v18.m128d_f64[0] = *(_QWORD *)&v15 & LC8;
if ( COERCE_DOUBLE(*(_QWORD *)&v15 & LC8) < 4.503599627370496e15 )
{
v18.m128d_f64[0] = (double)(int)v15;
v17 = ~LC8 & *(_QWORD *)&v15;
*(_QWORD *)&v16.m128d_f64[0] = COERCE_UNSIGNED_INT64(COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v16, v18) & LC9) + v18.m128d_f64[0]) | v17;
}
v19 = getGameAreaDeletedFirst(a1);
v20 = (int)v16.m128d_f64[0] - 1;
if ( (int)v16.m128d_f64[0] > 1 )
{
do
{
v19 = getNextLine(v19, v15, v18.m128d_f64[0], *(double *)&v17, v16.m128d_f64[0]);
--v20;
}
while ( v20 );
}
for ( k = 0LL; k != 10; ++k )
{
if ( *(_BYTE *)(getLineColumn(v19) + k) == 32 )
break;
v22 = getLineColumn(v19);
putchar(*(char *)(v22 + k));
}
}
else
{
printf("No eliminations");
}
return putchar(10);
}

original_code:
void writeOutput(GameArea *gameArea) {
 int i, j, num_lines, *num_pieces, median, color, type;
 Line* line = getGameAreaLast(gameArea);
 num_lines = getGameAreaNumLines(gameArea);
 printf("%d\n", getGameAreaNumLines(gameArea));
 printf("%d\n", getGameAreaScore(gameArea));
 printf("\n");
 for (i=num_lines; i>=1; i--) {
  printf("|");
  for (j=0; j<10; j++) {
   printf("%c", getLineColumn(line)[j]);
  }
  printf("| %d\n", i);
  line = getPreviousLine(line);
 }
 printf(" ");
 for(i=0; i<10; i++) {
  printf("-");
 }
 printf("\n\n");
 printf("%d\n", vectorSum(getGameAreaPieceCounts(gameArea), 5*6));
 num_pieces = getGameAreaPieceCounts(gameArea);
 for(i=0; i<(6*5); i++) {
  color = (i % 6) + 1;
  type = (i / 6) + 1;
  for(j=0; j<num_pieces[i]; j++) {
   printf("%d %c\n", type, int2color(color));
  }
 }
 printf("\n");
 if(getGameAreaNumDeletedLines(gameArea) == 0)
  printf("No eliminations");
 else {
  median = (int)ceil((double)getGameAreaNumDeletedLines(gameArea)/2);
  line = getGameAreaDeletedFirst(gameArea);
  while((median--) > 1)
   line = getNextLine(line);
  for(i=0; i<10 && getLineColumn(line)[i] != ' '; i++) {
   printf("%c", getLineColumn(line)[i]);
  }
 }
 printf("\n");
 return;
}

canonical_original_code:
void writeOutput(struct GameArea *gameArea) {
 int i; int j; int num_lines; int *num_pieces; int median; int color; int type;
 struct Line *line = getGameAreaLast(gameArea);
 num_lines = getGameAreaNumLines(gameArea);
 printf("%d\n", getGameAreaNumLines(gameArea));
 printf("%d\n", getGameAreaScore(gameArea));
 printf("\n");
 for (i=num_lines; i>=1; i--) {
  printf("|");
  for (j=0; j<10; j++) {
   printf("%c", getLineColumn(line)[j]);
  }
  printf("| %d\n", i);
  line = getPreviousLine(line);
 }
 printf(" ");
 for(i=0; i<10; i++) {
  printf("-");
 }
 printf("\n\n");
 printf("%d\n", vectorSum(getGameAreaPieceCounts(gameArea), 5*6));
 num_pieces = getGameAreaPieceCounts(gameArea);
 for(i=0; i<(6*5); i++) {
  color = (i % 6) + 1;
  type = (i / 6) + 1;
  for(j=0; j<num_pieces[i]; j++) {
   printf("%d %c\n", type, int2color(color));
  }
 }
 printf("\n");
 if(getGameAreaNumDeletedLines(gameArea) == 0)
  printf("No eliminations");
 else {
  median = (int)ceil((double)getGameAreaNumDeletedLines(gameArea)/2);
  line = getGameAreaDeletedFirst(gameArea);
  while((median--) > 1)
   line = getNextLine(line);
  for(i=0; i<10 && getLineColumn(line)[i] != ' '; i++) {
   printf("%c", getLineColumn(line)[i]);
  }
 }
 printf("\n");
 return;
}

variable_types: j int

variable_types: median int

variable_types: color int

variable_types: type int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx

v3 = newGameArea(argc, argv, envp);
readInput(v3);
writeOutput(v3);
clearGameArea(v3);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx

v3 = newGameArea(argc, argv, envp);
func3(v3);
func4(v3);
clearGameArea(v3);
return 0;
}

original_code:
int main() {
 GameArea *gameArea = newGameArea();
 readInput(gameArea);
 writeOutput(gameArea);
 clearGameArea(gameArea);
 return 0;
}

canonical_original_code:
int main() {
 struct GameArea *gameArea = newGameArea();
 readInput(gameArea);
 writeOutput(gameArea);
 clearGameArea(gameArea);
 return 0;
}


getLine

decompiled_code:
__int64 __fastcall getLine(unsigned int *a1)
{
return *a1;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int *a1)
{
return *a1;
}

original_code:
int getLine(position *pos) {
 return pos->line;
}

canonical_original_code:
int getLine(struct position *pos) {
 return pos->line;
}


getColumn

decompiled_code:
__int64 __fastcall getColumn(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

original_code:
int getColumn(position *pos) {
 return pos->column;
}

canonical_original_code:
int getColumn(struct position *pos) {
 return pos->column;
}


setColumn

decompiled_code:
void __fastcall setColumn(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 4) = a2;
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 4) = a2;
}

original_code:
void setColumn(position *pos, int column) {
 pos->column = column;
}

canonical_original_code:
void setColumn(struct position *pos, int column) {
 pos->column = column;
}

variable_types: column int


DoInsertNode

repo: joaomlneto/lan-chat

original_code:
static void DoInsertNode(
        struct AvlTree* tree,
        struct AvlTreeNode* root,
        struct AvlTreeNode* node)
{
    if(tree->m_dataComparator(node->m_key, root->m_key) < 0)
    {
        if(root->m_child1 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child1, node);
        else
        {
            root->m_child1 = node;
            root->m_child1->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    else
    {
        if(root->m_child2 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child2, node);
        else
        {
            root->m_child2 = node;
            root->m_child2->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    return;
}

canonical_original_code:
static void DoInsertNode(struct AvlTree *tree, struct AvlTreeNode *root, struct AvlTreeNode *node)
{
    if(tree->m_dataComparator(node->m_key, root->m_key) < 0)
    {
        if(root->m_child1 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child1, node);
        else
        {
            root->m_child1 = node;
            root->m_child1->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    else
    {
        if(root->m_child2 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child2, node);
        else
        {
            root->m_child2 = node;
            root->m_child2->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    return;
}

variable_types: struct AvlTree { int (*m_dataComparator)(void *data1, void *data2); int m_keySize; int m_dataSize; int m_avlTreeSize; struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; } *m_rootNode; struct AvlTreeNode *m_nullNode; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; } *

variable_types:
root
struct AvlTreeNode *

variable_types:
node
struct AvlTreeNode *

user_defined_types: struct AvlTree { int (*m_dataComparator)(void *data1, void *data2); int m_keySize; int m_dataSize; int m_avlTreeSize; struct AvlTreeNode *m_rootNode; struct AvlTreeNode *m_nullNode; union pthread_mutex_t mutex; }

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

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


DoRotateLL

original_code:
static void DoRotateLL(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node0 = node->m_parent;
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child1;
    node1->m_child1 = node2->m_child2;
    node1->m_child1->m_parent = node1;
    node2->m_child2 = node1;
    node2->m_child2->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

canonical_original_code:
static void DoRotateLL(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node0 = node->m_parent;
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child1;
    node1->m_child1 = node2->m_child2;
    node1->m_child1->m_parent = node1;
    node2->m_child2 = node1;
    node2->m_child2->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

variable_types: struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; } *

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


DoRotateRR

original_code:
static void DoRotateRR(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node0 = node->m_parent;
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child2;
    node1->m_child2 = node2->m_child1;
    node1->m_child2->m_parent = node1;
    node2->m_child1 = node1;
    node2->m_child1->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

canonical_original_code:
static void DoRotateRR(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node0 = node->m_parent;
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child2;
    node1->m_child2 = node2->m_child1;
    node1->m_child2->m_parent = node1;
    node2->m_child1 = node1;
    node2->m_child1->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

user_defined_types: struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; }


DoRotateLR

decompiled_code:
void __fastcall DoRotateLR(__int64 a1, __int64 a2)
{
DoRotateRR(a1, *(_QWORD *)(a2 + 24));
DoRotateLL(a1, a2);
}

original_code:
static void DoRotateLR(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child1;
    DoRotateRR(tree, node2);
    DoRotateLL(tree, node1);
    return;
}

canonical_original_code:
static void DoRotateLR(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child1;
    DoRotateRR(tree, node2);
    DoRotateLL(tree, node1);
    return;
}


DoRotateRL

decompiled_code:
void __fastcall DoRotateRL(__int64 a1, __int64 a2)
{
DoRotateLL(a1, *(_QWORD *)(a2 + 32));
DoRotateRR(a1, a2);
}

original_code:
static void DoRotateRL(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child2;
    DoRotateLL(tree, node2);
    DoRotateRR(tree, node1);
    return;
}

canonical_original_code:
static void DoRotateRL(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child2;
    DoRotateLL(tree, node2);
    DoRotateRR(tree, node1);
    return;
}


decompiled_code:
void __fastcall avl_destroy(void *ptr)
{
DoDestroyNode((__int64)ptr, *((_QWORD *)ptr + 3));
free(*((void **)ptr + 4));
pthread_mutex_destroy((pthread_mutex_t *)ptr + 1);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func9(void *ptr)
{
func8((__int64)ptr, *((_QWORD *)ptr + 3));
free(*((void **)ptr + 4));
pthread_mutex_destroy((pthread_mutex_t *)ptr + 1);
free(ptr);
}

original_code:
void avl_destroy(avltree_t* tree)
{
    DoDestroyNode(tree, tree->m_rootNode);
    free(tree->m_nullNode);
    pthread_mutex_destroy(&tree->mutex);
    free(tree);
    return;
}

canonical_original_code:
void avl_destroy(struct AvlTree *tree)
{
    DoDestroyNode(tree, tree->m_rootNode);
    free(tree->m_nullNode);
    pthread_mutex_destroy(&tree->mutex);
    free(tree);
    return;
}


AvlTreeGetSize

decompiled_code:
__int64 __fastcall AvlTreeGetSize(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

original_code:
int AvlTreeGetSize(struct AvlTree* tree)
{
    return tree->m_avlTreeSize;
}

canonical_original_code:
int AvlTreeGetSize(struct AvlTree *tree)
{
    return tree->m_avlTreeSize;
}


AvlTreeNodeData

decompiled_code:
__int64 __fastcall AvlTreeNodeData(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
void* AvlTreeNodeData(struct AvlTreeNode* node)
{
    return node->m_data;
}

canonical_original_code:
void *AvlTreeNodeData(struct AvlTreeNode *node)
{
    return node->m_data;
}

return_type: void *


decompiled_code:
struct __pthread_internal_list *__fastcall avl_insert(pthread_mutex_t *a1, struct __pthread_internal_list *a2, struct __pthread_internal_list *a3)
{
struct __pthread_internal_list *v4; // rbx
struct __pthread_internal_list *v5; // rax
struct __pthread_internal_list *v6; // rsi

v4 = (struct __pthread_internal_list *)malloc(0x30uLL);
v4->__prev = a2;
v4->__next = a3;
v5 = a1->__list.__next;
v4[1].__next = v5;
v4[2].__prev = v5;
v4[2].__next = v5;
LODWORD(v4[1].__prev) = 0;
pthread_mutex_lock(a1 + 1);
v6 = a1->__list.__prev;
if ( v6 == a1->__list.__next )
{
a1->__list.__prev = v4;
}
else
{
DoInsertNode((__int64)a1, v6, v4);
DoRebalance((__int64)a1, (__int64)v4);
}
++a1->__kind;
pthread_mutex_unlock(a1 + 1);
return v4;
}

canonical_decompiled_code:
struct __pthread_internal_list *__fastcall func12(pthread_mutex_t *a1, struct __pthread_internal_list *a2, struct __pthread_internal_list *a3)
{
struct __pthread_internal_list *v4; // rbx
struct __pthread_internal_list *v5; // rax
struct __pthread_internal_list *v6; // rsi

v4 = (struct __pthread_internal_list *)malloc(0x30uLL);
v4->__prev = a2;
v4->__next = a3;
v5 = a1->__list.__next;
v4[1].__next = v5;
v4[2].__prev = v5;
v4[2].__next = v5;
LODWORD(v4[1].__prev) = 0;
pthread_mutex_lock(a1 + 1);
v6 = a1->__list.__prev;
if ( v6 == a1->__list.__next )
{
a1->__list.__prev = v4;
}
else
{
func1((__int64)a1, v6, v4);
func6((__int64)a1, (__int64)v4);
}
++a1->__kind;
pthread_mutex_unlock(a1 + 1);
return v4;
}

original_code:
struct AvlTreeNode* avl_insert(
        struct AvlTree* tree,
        void* key,
        void* data)
{
    struct AvlTreeNode* newNode = malloc(sizeof(struct AvlTreeNode));
    newNode->m_key = key;
    newNode->m_data = data;
    newNode->m_child1 = tree->m_nullNode;
    newNode->m_child2 = tree->m_nullNode;
    newNode->m_parent = tree->m_nullNode;
    newNode->m_height = 0;
 pthread_mutex_lock(&tree->mutex);
    if(tree->m_rootNode == tree->m_nullNode)
    {
        tree->m_rootNode = newNode;
    }
    else
    {
        DoInsertNode(tree, tree->m_rootNode, newNode);
        DoRebalance(tree, newNode);
    }
    tree->m_avlTreeSize += 1;
 pthread_mutex_unlock(&tree->mutex);
    return newNode;
}

canonical_original_code:
struct AvlTreeNode *avl_insert(struct AvlTree *tree, void *key, void *data)
{
    struct AvlTreeNode *newNode = malloc(sizeof(struct AvlTreeNode));
    newNode->m_key = key;
    newNode->m_data = data;
    newNode->m_child1 = tree->m_nullNode;
    newNode->m_child2 = tree->m_nullNode;
    newNode->m_parent = tree->m_nullNode;
    newNode->m_height = 0;
 pthread_mutex_lock(&tree->mutex);
    if(tree->m_rootNode == tree->m_nullNode)
    {
        tree->m_rootNode = newNode;
    }
    else
    {
        DoInsertNode(tree, tree->m_rootNode, newNode);
        DoRebalance(tree, newNode);
    }
    tree->m_avlTreeSize += 1;
 pthread_mutex_unlock(&tree->mutex);
    return newNode;
}

variable_types: struct AvlTree { int (*m_dataComparator)(void *data1, void *data2); int m_keySize; int m_dataSize; int m_avlTreeSize; struct AvlTreeNode *m_rootNode; struct AvlTreeNode *m_nullNode; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; } *

variable_types:
key
void *

variable_types:
data
void *

return_type: struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; } *


AvlTreeDeleteNode

original_code:
void AvlTreeDeleteNode(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* scapegoatNode;
    struct AvlTreeNode* checkNode;
    scapegoatNode = DoFindDeletionScapegoat(tree, node);
    if(node != scapegoatNode)
    {
        memcpy(node->m_key, scapegoatNode->m_key, tree->m_keySize);
        memcpy(node->m_data, scapegoatNode->m_data, tree->m_dataSize);
        AvlTreeDeleteNode(tree, scapegoatNode);
        return;
    }
    checkNode = scapegoatNode->m_parent;
    free(scapegoatNode->m_key);
    free(scapegoatNode->m_data);
    free(scapegoatNode);
    if(checkNode != tree->m_nullNode)
    {
        if(checkNode->m_child1 == scapegoatNode)
            checkNode->m_child1 = tree->m_nullNode;
        if(checkNode->m_child2 == scapegoatNode)
            checkNode->m_child2 = tree->m_nullNode;
        DoUpdateHeight(tree, checkNode);
    }
    else tree->m_rootNode = tree->m_nullNode;
    DoRebalance(tree, checkNode);
    tree->m_avlTreeSize -= 1;
    return;
}

canonical_original_code:
void AvlTreeDeleteNode(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *scapegoatNode;
    struct AvlTreeNode *checkNode;
    scapegoatNode = DoFindDeletionScapegoat(tree, node);
    if(node != scapegoatNode)
    {
        memcpy(node->m_key, scapegoatNode->m_key, tree->m_keySize);
        memcpy(node->m_data, scapegoatNode->m_data, tree->m_dataSize);
        AvlTreeDeleteNode(tree, scapegoatNode);
        return;
    }
    checkNode = scapegoatNode->m_parent;
    free(scapegoatNode->m_key);
    free(scapegoatNode->m_data);
    free(scapegoatNode);
    if(checkNode != tree->m_nullNode)
    {
        if(checkNode->m_child1 == scapegoatNode)
            checkNode->m_child1 = tree->m_nullNode;
        if(checkNode->m_child2 == scapegoatNode)
            checkNode->m_child2 = tree->m_nullNode;
        DoUpdateHeight(tree, checkNode);
    }
    else tree->m_rootNode = tree->m_nullNode;
    DoRebalance(tree, checkNode);
    tree->m_avlTreeSize -= 1;
    return;
}


decompiled_code:
__int64 __fastcall avl_search(__int64 a1, __int64 a2)
{
_QWORD *v2; // rbx
pthread_mutex_t *v3; // r13
__int64 result; // rax

v2 = *(_QWORD **)(a1 + 24);
v3 = (pthread_mutex_t *)(a1 + 40);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
if ( v2 == *(_QWORD **)(a1 + 32) )
{
LABEL_2:
pthread_mutex_unlock(v3);
result = 0LL;
}
else
{
while ( (*(unsigned int (__fastcall **)(__int64, _QWORD))a1)(a2, *v2) )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v2) < 0 )
{
v2 = (_QWORD *)v2[3];
}
else if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v2) > 0 )
{
v2 = (_QWORD *)v2[4];
}
if ( v2 == *(_QWORD **)(a1 + 32) )
goto LABEL_2;
}
pthread_mutex_unlock(v3);
result = v2[1];
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1, __int64 a2)
{
_QWORD *v2; // rbx
pthread_mutex_t *v3; // r13
__int64 result; // rax

v2 = *(_QWORD **)(a1 + 24);
v3 = (pthread_mutex_t *)(a1 + 40);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
if ( v2 == *(_QWORD **)(a1 + 32) )
{
LABEL_2:
pthread_mutex_unlock(v3);
result = 0LL;
}
else
{
while ( (*(unsigned int (__fastcall **)(__int64, _QWORD))a1)(a2, *v2) )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v2) < 0 )
{
v2 = (_QWORD *)v2[3];
}
else if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v2) > 0 )
{
v2 = (_QWORD *)v2[4];
}
if ( v2 == *(_QWORD **)(a1 + 32) )
goto LABEL_2;
}
pthread_mutex_unlock(v3);
result = v2[1];
}
return result;
}

original_code:
struct AvlTreeNode* avl_search(struct AvlTree* tree, void* key)
{
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
    pthread_mutex_unlock(&tree->mutex);
            return currentNode->m_data;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    pthread_mutex_unlock(&tree->mutex);
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *avl_search(struct AvlTree *tree, void *key)
{
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
    pthread_mutex_unlock(&tree->mutex);
            return currentNode->m_data;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    pthread_mutex_unlock(&tree->mutex);
    return ((void *)0);
}


AvlTreeIterateHead

original_code:
struct AvlTreeNode* AvlTreeIterateHead(struct AvlTree* tree)
{
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIterateHead(struct AvlTree *tree)
{
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    return ((void *)0);
}


AvlTreeIterateTail

original_code:
struct AvlTreeNode* AvlTreeIterateTail(struct AvlTree* tree)
{
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIterateTail(struct AvlTree *tree)
{
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    return ((void *)0);
}


AvlTreeIterateNext

original_code:
struct AvlTreeNode* AvlTreeIterateNext(
        struct AvlTree* tree,
        struct AvlTreeNode* node)
{
    struct AvlTreeNode* currentNode;
    if(node->m_child2 != tree->m_nullNode)
    {
        currentNode = node->m_child2;
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child2 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIterateNext(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *currentNode;
    if(node->m_child2 != tree->m_nullNode)
    {
        currentNode = node->m_child2;
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child2 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}


AvlTreeIteratePrev

original_code:
struct AvlTreeNode* AvlTreeIteratePrev(
        struct AvlTree* tree,
        struct AvlTreeNode* node)
{
    struct AvlTreeNode* currentNode;
    if(node->m_child1 != tree->m_nullNode)
    {
        currentNode = node->m_child1;
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child1 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIteratePrev(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *currentNode;
    if(node->m_child1 != tree->m_nullNode)
    {
        currentNode = node->m_child1;
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child1 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}


decompiled_code:
int __fastcall avl_remove(__int64 a1, __int64 a2)
{
void **v2; // rbx
pthread_mutex_t *v3; // r13

v2 = *(void ***)(a1 + 24);
v3 = (pthread_mutex_t *)(a1 + 40);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
if ( v2 == *(void ***)(a1 + 32) )
{
v2 = 0LL;
}
else
{
do
{
if ( !(*(unsigned int (__fastcall **)(__int64, void *))a1)(a2, *v2) )
{
pthread_mutex_unlock(v3);
goto LABEL_4;
}
if ( (*(int (__fastcall **)(__int64, void *))a1)(a2, *v2) < 0 )
{
v2 = (void **)v2[3];
}
else if ( (*(int (__fastcall **)(__int64, void *))a1)(a2, *v2) > 0 )
{
v2 = (void **)v2[4];
}
}
while ( v2 != *(void ***)(a1 + 32) );
v2 = 0LL;
}
LABEL_4:
AvlTreeDeleteNode(a1, v2);
return pthread_mutex_unlock(v3);
}

canonical_decompiled_code:
int __fastcall func19(__int64 a1, __int64 a2)
{
void **v2; // rbx
pthread_mutex_t *v3; // r13

v2 = *(void ***)(a1 + 24);
v3 = (pthread_mutex_t *)(a1 + 40);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
if ( v2 == *(void ***)(a1 + 32) )
{
v2 = 0LL;
}
else
{
do
{
if ( !(*(unsigned int (__fastcall **)(__int64, void *))a1)(a2, *v2) )
{
pthread_mutex_unlock(v3);
goto LABEL_4;
}
if ( (*(int (__fastcall **)(__int64, void *))a1)(a2, *v2) < 0 )
{
v2 = (void **)v2[3];
}
else if ( (*(int (__fastcall **)(__int64, void *))a1)(a2, *v2) > 0 )
{
v2 = (void **)v2[4];
}
}
while ( v2 != *(void ***)(a1 + 32) );
v2 = 0LL;
}
LABEL_4:
func13(a1, v2);
return pthread_mutex_unlock(v3);
}

original_code:
void avl_remove(avltree_t* tree, void* key) {
    struct AvlTreeNode* node = ((void *)0);
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
            pthread_mutex_unlock(&tree->mutex);
            node = currentNode;
            break;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    AvlTreeDeleteNode(tree, node);
    pthread_mutex_unlock(&tree->mutex);
}

canonical_original_code:
void avl_remove(struct AvlTree *tree, void *key) {
    struct AvlTreeNode *node = ((void *)0);
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
            pthread_mutex_unlock(&tree->mutex);
            node = currentNode;
            break;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    AvlTreeDeleteNode(tree, node);
    pthread_mutex_unlock(&tree->mutex);
}


decompiled_code:
__int64 __fastcall avl_lookup(__int64 a1, __int64 a2)
{
return avl_search(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1, __int64 a2)
{
return func14(a1, a2);
}

original_code:
void* avl_lookup(avltree_t* tree, void* key) {
 struct AvlTreeNode* node;
 node = avl_search(tree, key);
 return node ;
}

canonical_original_code:
void *avl_lookup(struct AvlTree *tree, void *key) {
 struct AvlTreeNode *node;
 node = avl_search(tree, key);
 return node ;
}


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

if ( !a2 )
return puts("#### END PRINT ####");
printf("KEY = %d\n", **a2);
v2 = AvlTreeIterateNext(a1, (__int64)a2);
return avl_print_aux(a1, v2);
}

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

if ( !a2 )
return puts("#### END PRINT ####");
printf("KEY = %d\n", **a2);
v2 = func17(a1, (__int64)a2);
return func21(a1, v2);
}

original_code:
void avl_print_aux(avltree_t* tree, struct AvlTreeNode* node) {
 if (node == ((void *)0)) {
  printf("#### END PRINT ####\n");
  return;
 }
 printf("KEY = %d\n", *(int*)node->m_key);
 avl_print_aux(tree, AvlTreeIterateNext(tree, node));
}

canonical_original_code:
void avl_print_aux(struct AvlTree *tree, struct AvlTreeNode *node) {
 if (node == ((void *)0)) {
  printf("#### END PRINT ####\n");
  return;
 }
 printf("KEY = %d\n", *(int *)node->m_key);
 avl_print_aux(tree, AvlTreeIterateNext(tree, node));
}


decompiled_code:
int __fastcall avl_print(__int64 a1)
{
unsigned int **v1; // rax

puts("\n#### AVL PRINT ####");
v1 = (unsigned int **)AvlTreeIterateHead(a1);
return avl_print_aux(a1, v1);
}

canonical_decompiled_code:
int __fastcall func22(__int64 a1)
{
unsigned int **v1; // rax

puts("\n#### AVL PRINT ####");
v1 = (unsigned int **)func15(a1);
return func21(a1, v1);
}

original_code:
void avl_print(avltree_t* tree) {
 printf("\n#### AVL PRINT ####\n");
 avl_print_aux(tree, AvlTreeIterateHead(tree));
}

canonical_original_code:
void avl_print(struct AvlTree *tree) {
 printf("\n#### AVL PRINT ####\n");
 avl_print_aux(tree, AvlTreeIterateHead(tree));
}


decompiled_code:
__int64 __fastcall int_comparator(_DWORD *a1, _DWORD *a2)
{
return (unsigned int)(*a1 - *a2);
}

canonical_decompiled_code:
__int64 __fastcall func0(_DWORD *a1, _DWORD *a2)
{
return (unsigned int)(*a1 - *a2);
}

original_code:
int int_comparator(const void* a, const void* b) {
 return *(int*)a - *(int*)b;
}

canonical_original_code:
int int_comparator(void *a, void *b) {
 return *(int *)a - *(int *)b;
}

variable_types:
a
void *

variable_types:
b
void *


decompiled_code:
void __fastcall __noreturn thr_handler(void *a1)
{
int v1; // ebp
_QWORD *v2; // rbx
__int64 v3; // rax
int v4; // [rsp+Ch] [rbp-12Ch] BYREF
int buf[74]; // [rsp+10h] [rbp-128h] BYREF

mysql_thread_init(a1);
while ( 1 )
{
sem_wait(&Sem_client_requests);
v2 = (_QWORD *)queue_remove(Queue_client_requests);
v3 = 0LL;
memset(buf, 0, 0x108uLL);
do
{
if ( *(_DWORD *)v2 == LODWORD(Service[2 * v3]) )
{
((void (__fastcall *)(_QWORD *, int *, int *))Service[2 * (int)v3 + 1])(v2, buf, &v4);
goto LABEL_3;
}
++v3;
}
while ( v3 != 4 );
buf[1] = 3;
v4 = 8;
puts("[xlcom_server] [H] Unknown request.");
LABEL_3:
v1 = send(*(_DWORD *)(v2[67] + 40LL), buf, v4, 64);
if ( v1 < 0 )
puts("[xlcom_server] [H] Error sending response.");
if ( v4 != v1 )
puts("[xlcom_server] [H] Message size mismatch.");
free(v2);
}
}

canonical_decompiled_code:
void __fastcall __noreturn func1(void *a1)
{
int v1; // ebp
_QWORD *v2; // rbx
__int64 v3; // rax
int v4; // [rsp+Ch] [rbp-12Ch] BYREF
int buf[74]; // [rsp+10h] [rbp-128h] BYREF

mysql_thread_init(a1);
while ( 1 )
{
sem_wait(&Sem_client_requests);
v2 = (_QWORD *)queue_remove(Queue_client_requests);
v3 = 0LL;
memset(buf, 0, 0x108uLL);
do
{
if ( *(_DWORD *)v2 == LODWORD(Service[2 * v3]) )
{
((void (__fastcall *)(_QWORD *, int *, int *))Service[2 * (int)v3 + 1])(v2, buf, &v4);
goto LABEL_3;
}
++v3;
}
while ( v3 != 4 );
buf[1] = 3;
v4 = 8;
puts("[xlcom_server] [H] Unknown request.");
LABEL_3:
v1 = send(*(_DWORD *)(v2[67] + 40LL), buf, v4, 64);
if ( v1 < 0 )
puts("[xlcom_server] [H] Error sending response.");
if ( v4 != v1 )
puts("[xlcom_server] [H] Message size mismatch.");
free(v2);
}
}

original_code:
void* thr_handler(void* arg) {
 client_request_t *request;
 xlcp_msg_res_t response;
 int response_size;
 size_t req_handler_id;
 int found_req_handler;
 int status;
 int i;
 mysql_thread_init();
 while(1) {
  sem_wait(&Sem_client_requests);
  request = queue_remove(Queue_client_requests);
  memset(&response, 0, sizeof(response));
  found_req_handler = 0;
  for (i=0; i<4; i++) {
   if(request->msg.type == Service[i].type) {
    found_req_handler = 1;
    req_handler_id = i;
    break;
   }
  }
  if (!found_req_handler) {
   response.status = RES_UNKNOWN;
   response_size = sizeof(response) - sizeof(response.body);
   printf("[xlcom_server] [H] Unknown request.\n");
  }
  else {
   Service[req_handler_id].handler(request, &response, &response_size);
  }
  status = send(request->client->fd, &response, response_size, MSG_DONTWAIT);
  if (status < 0) {
   printf("[xlcom_server] [H] Error sending response.\n");
  }
  if (status != response_size) {
   printf("[xlcom_server] [H] Message size mismatch.\n");
  }
  free(request);
 }
}

canonical_original_code:
void *thr_handler(void *arg) {
 struct client_request_t *request;
 struct xlcp_msg_res_t response;
 int response_size;
 unsigned long req_handler_id;
 int found_req_handler;
 int status;
 int i;
 mysql_thread_init();
 while(1) {
  sem_wait(&Sem_client_requests);
  request = queue_remove(Queue_client_requests);
  memset(&response, 0, sizeof(response));
  found_req_handler = 0;
  for (i=0; i<4; i++) {
   if(request->msg.type == Service[i].type) {
    found_req_handler = 1;
    req_handler_id = i;
    break;
   }
  }
  if (!found_req_handler) {
   response.status = RES_UNKNOWN;
   response_size = sizeof(response) - sizeof(response.body);
   printf("[xlcom_server] [H] Unknown request.\n");
  }
  else {
   Service[req_handler_id].handler(request, &response, &response_size);
  }
  status = send(request->client->fd, &response, response_size, MSG_DONTWAIT);
  if (status < 0) {
   printf("[xlcom_server] [H] Error sending response.\n");
  }
  if (status != response_size) {
   printf("[xlcom_server] [H] Message size mismatch.\n");
  }
  free(request);
 }
}

variable_types:
arg
void *

variable_types: struct client_request_t { struct xlcp_msg_req_t { enum xlcp_msg_type_t { REQ_NULL=0, REQ_PING=1, REQ_ECHO=2, REQ_AUTH=3, REQ_SEND_MESSAGE=4 } type; union { struct xlcp_msg_req_echo_t { char msg[256]; } echo; struct xlcp_msg_req_auth_t { char user[32]; char pass[40]; } auth; struct xlcp_msg_req_sendmsg_t { int target_id; int target_type; char message[512]; } sendmsg; } body; } msg; unsigned long msg_size; struct client_info_t { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; int fd; char address[16]; int is_authed; int id; char username[32]; } *client; } *

variable_types: struct xlcp_msg_res_t { enum xlcp_msg_type_t { REQ_NULL=0, REQ_PING=1, REQ_ECHO=2, REQ_AUTH=3, REQ_SEND_MESSAGE=4 } type; enum xlcp_msg_res_status_t { RES_OK=0, RES_BUSY=1, RES_ERROR=2, RES_UNKNOWN=3 } status; union { struct xlcp_msg_res_echo_t { char msg[256]; } echo; } body; }

variable_types: status int

variable_types: i int

user_defined_types: struct xlcp_msg_res_t { enum xlcp_msg_type_t type; enum xlcp_msg_res_status_t status; union { struct xlcp_msg_res_echo_t echo; } body; }

user_defined_types: struct client_request_t { struct xlcp_msg_req_t msg; unsigned long msg_size; struct client_info_t *client; }

user_defined_types: struct xlcp_msg_req_t { enum xlcp_msg_type_t type; union { struct xlcp_msg_req_echo_t echo; struct xlcp_msg_req_auth_t auth; struct xlcp_msg_req_sendmsg_t sendmsg; } body; }

user_defined_types: struct client_info_t { union pthread_mutex_t mutex; int fd; char address[16]; int is_authed; int id; char username[32]; }


decompiled_code:
void __fastcall __noreturn thr_poller(void *a1)
{
_QWORD *v1; // rbx
__int64 v2; // rax
const char *v3; // rax
struct epoll_event v4; // [rsp+0h] [rbp-18h] BYREF
int v5[3]; // [rsp+Ch] [rbp-Ch] BYREF

while ( 1 )
{
if ( epoll_wait(Epoll_fd, &v4, 1, -1) != 1 )
printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", 1LL);
v1 = malloc(0x220uLL);
if ( !v1 )
puts("[xlcom_server] [P] malloc failed. No free memory?");
memset(v1, 0, 0x220uLL);
v5[0] = v4.data.fd;
v1[66] = recv(v4.data.fd, v1, 0x20CuLL, 64);
v2 = avl_lookup(Active_connections, v5);
v1[67] = v2;
if ( v2 )
{
if ( v1[66] )
{
queue_add(Queue_client_requests, v1);
sem_post(&Sem_client_requests);
}
else
{
v3 = (const char *)client_info_print_auth(v2);
printf("[xlcom_server] [P] %s disconnected.\n", v3);
avl_remove(Active_connections, v5);
if ( epoll_ctl(Epoll_fd, 2, v5[0], 0LL) )
puts("[xlcom_server] [P] Error removing connection from epoll.");
close(v5[0]);
free(v1);
}
}
else
{
puts("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.");
}
}
}

canonical_decompiled_code:
void __fastcall __noreturn func2(void *a1)
{
_QWORD *v1; // rbx
__int64 v2; // rax
const char *v3; // rax
struct epoll_event v4; // [rsp+0h] [rbp-18h] BYREF
int v5[3]; // [rsp+Ch] [rbp-Ch] BYREF

while ( 1 )
{
if ( epoll_wait(Epoll_fd, &v4, 1, -1) != 1 )
printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", 1LL);
v1 = malloc(0x220uLL);
if ( !v1 )
puts("[xlcom_server] [P] malloc failed. No free memory?");
memset(v1, 0, 0x220uLL);
v5[0] = v4.data.fd;
v1[66] = recv(v4.data.fd, v1, 0x20CuLL, 64);
v2 = avl_lookup(Active_connections, v5);
v1[67] = v2;
if ( v2 )
{
if ( v1[66] )
{
queue_add(Queue_client_requests, v1);
sem_post(&Sem_client_requests);
}
else
{
v3 = (const char *)client_info_print_auth(v2);
printf("[xlcom_server] [P] %s disconnected.\n", v3);
avl_remove(Active_connections, v5);
if ( epoll_ctl(Epoll_fd, 2, v5[0], 0LL) )
puts("[xlcom_server] [P] Error removing connection from epoll.");
close(v5[0]);
free(v1);
}
}
else
{
puts("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.");
}
}
}

original_code:
void* thr_poller(void* arg) {
 int status;
 int client_fd;
 struct epoll_event epoll_ev;
 client_request_t *request;
 while(1) {
  if ((status = epoll_wait(Epoll_fd, &epoll_ev, 1, -1) != 1)) {
   printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", status);
  }
  if ((request = malloc(sizeof(client_request_t))) == ((void *)0)) {
   printf("[xlcom_server] [P] malloc failed. No free memory?\n");
  }
  memset(request, 0, sizeof(client_request_t));
  client_fd = epoll_ev.data.fd;
  request->msg_size = recv(client_fd, (void*)&(request->msg), sizeof(request->msg), MSG_DONTWAIT);
  if ((request->client = avl_lookup(Active_connections, &client_fd)) == ((void *)0)) {
   printf("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.\n");
   continue;
  }
  if (request->msg_size == 0) {
   printf("[xlcom_server] [P] %s disconnected.\n", client_info_print_auth(request->client));
   avl_remove(Active_connections, &client_fd);
   if (epoll_ctl(Epoll_fd, 2, client_fd, ((void *)0)) != 0) {
    printf("[xlcom_server] [P] Error removing connection from epoll.\n");
   }
   close(client_fd);
   free(request);
   continue;
  }
  if (request->msg_size < 0) {
   printf("[xlcom_server] [P] Error receiving request from %s.\n", request->client->address);
   free(request);
   return ((void *)0);
  }
  queue_add(Queue_client_requests, request);
  sem_post(&Sem_client_requests);
 }
}

canonical_original_code:
void *thr_poller(void *arg) {
 int status;
 int client_fd;
 struct epoll_event epoll_ev;
 struct client_request_t *request;
 while(1) {
  if ((status = epoll_wait(Epoll_fd, &epoll_ev, 1, -1) != 1)) {
   printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", status);
  }
  if ((request = malloc(sizeof(client_request_t))) == ((void *)0)) {
   printf("[xlcom_server] [P] malloc failed. No free memory?\n");
  }
  memset(request, 0, sizeof(client_request_t));
  client_fd = epoll_ev.data.fd;
  request->msg_size = recv(client_fd, (void *)&(request->msg), sizeof(request->msg), MSG_DONTWAIT);
  if ((request->client = avl_lookup(Active_connections, &client_fd)) == ((void *)0)) {
   printf("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.\n");
   continue;
  }
  if (request->msg_size == 0) {
   printf("[xlcom_server] [P] %s disconnected.\n", client_info_print_auth(request->client));
   avl_remove(Active_connections, &client_fd);
   if (epoll_ctl(Epoll_fd, 2, client_fd, ((void *)0)) != 0) {
    printf("[xlcom_server] [P] Error removing connection from epoll.\n");
   }
   close(client_fd);
   free(request);
   continue;
  }
  if (request->msg_size < 0) {
   printf("[xlcom_server] [P] Error receiving request from %s.\n", request->client->address);
   free(request);
   return ((void *)0);
  }
  queue_add(Queue_client_requests, request);
  sem_post(&Sem_client_requests);
 }
}

variable_types: struct epoll_event { unsigned int events; union epoll_data { void *ptr; int fd; unsigned int u32; unsigned long u64; } data; }

user_defined_types: struct epoll_event { unsigned int events; union epoll_data data; }

user_defined_types: enum xlcp_msg_type_t { REQ_NULL=0, REQ_PING=1, REQ_ECHO=2, REQ_AUTH=3, REQ_SEND_MESSAGE=4 }

user_defined_types: struct xlcp_msg_req_echo_t { char msg[256]; }

user_defined_types: struct xlcp_msg_req_auth_t { char user[32]; char pass[40]; }

user_defined_types: struct xlcp_msg_req_sendmsg_t { int target_id; int target_type; char message[512]; }


decompiled_code:
void *__fastcall thr_listener(void *a1)
{
int v1; // eax
int v2; // er13
int v3; // ebx
char *v4; // rax
_DWORD *v5; // r12
__int64 v6; // rbp
char *v7; // rax
struct epoll_event v9; // [rsp+0h] [rbp-58h] BYREF
socklen_t addr_len; // [rsp+Ch] [rbp-4Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-48h] BYREF
struct sockaddr v12; // [rsp+20h] [rbp-38h] BYREF

addr_len = 16;
v1 = socket(2, 1, 0);
if ( v1 == -1 )
{
puts("[xlcom_server] [L] cannot open socket.");
}
else
{
v2 = v1;
*(_QWORD *)&addr.sa_family = 2LL;
*(_QWORD *)&addr.sa_data[6] = 0LL;
*(_WORD *)addr.sa_data = _bswap_16(64787);
while ( bind(v2, &addr, 0x10u) == -1 )
{
printf("[xlcom_server] [L] cannot bind port %d. trying again in %d seconds.\n", 64787LL, 5LL);
sleep(5u);
}
listen(v2, 30);
printf("[xlcom_server] [L] Listening on port %d. Max pending connections %d.\n", 64787LL, 30LL);
while ( 1 )
{
v3 = accept(v2, &v12, &addr_len);
if ( v3 < 0 )
{
perror("[xlcom_server] [L] could not accept connection.\n");
close(v2);
return 0LL;
}
v4 = inet_ntoa(*(struct in_addr *)&v12.sa_data[2]);
printf("[xlcom_server] [L] Received new connection from %s on fd %d.\n", v4, (unsigned int)v3);
v9.events = 27;
v9.data.fd = v3;
if ( epoll_ctl(Epoll_fd, 1, v3, &v9) )
break;
v5 = malloc(4uLL);
*v5 = v3;
v6 = client_info_create();
client_info_set_fd(v6, (unsigned int)v3);
v7 = inet_ntoa(*(struct in_addr *)&v12.sa_data[2]);
client_info_set_address(v6, v7);
client_info_set_username(v6, "Anonymous");
avl_insert(Active_connections, v5, v6);
}
puts("[xlcom_server] [L] Error adding new connection to epoll queue.");
close(v2);
}
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func4(void *a1)
{
int v1; // eax
int v2; // er13
int v3; // ebx
char *v4; // rax
_DWORD *v5; // r12
__int64 v6; // rbp
char *v7; // rax
struct epoll_event v9; // [rsp+0h] [rbp-58h] BYREF
socklen_t addr_len; // [rsp+Ch] [rbp-4Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-48h] BYREF
struct sockaddr v12; // [rsp+20h] [rbp-38h] BYREF

addr_len = 16;
v1 = socket(2, 1, 0);
if ( v1 == -1 )
{
puts("[xlcom_server] [L] cannot open socket.");
}
else
{
v2 = v1;
*(_QWORD *)&addr.sa_family = 2LL;
*(_QWORD *)&addr.sa_data[6] = 0LL;
*(_WORD *)addr.sa_data = func3(64787);
while ( bind(v2, &addr, 0x10u) == -1 )
{
printf("[xlcom_server] [L] cannot bind port %d. trying again in %d seconds.\n", 64787LL, 5LL);
sleep(5u);
}
listen(v2, 30);
printf("[xlcom_server] [L] Listening on port %d. Max pending connections %d.\n", 64787LL, 30LL);
while ( 1 )
{
v3 = accept(v2, &v12, &addr_len);
if ( v3 < 0 )
{
perror("[xlcom_server] [L] could not accept connection.\n");
close(v2);
return 0LL;
}
v4 = inet_ntoa(*(struct in_addr *)&v12.sa_data[2]);
printf("[xlcom_server] [L] Received new connection from %s on fd %d.\n", v4, (unsigned int)v3);
v9.events = 27;
v9.data.fd = v3;
if ( epoll_ctl(Epoll_fd, 1, v3, &v9) )
break;
v5 = malloc(4uLL);
*v5 = v3;
v6 = client_info_create();
client_info_set_fd(v6, (unsigned int)v3);
v7 = inet_ntoa(*(struct in_addr *)&v12.sa_data[2]);
client_info_set_address(v6, v7);
client_info_set_username(v6, "Anonymous");
avl_insert(Active_connections, v5, v6);
}
puts("[xlcom_server] [L] Error adding new connection to epoll queue.");
close(v2);
}
return 0LL;
}

original_code:
void* thr_listener(void* arg) {
 int listen_fd, client_fd;
 struct sockaddr_in client_addr, server_addr;
 socklen_t client_sz = sizeof(client_addr);
 struct epoll_event epoll_ev;
 int result;
 int* key_tmp;
 client_info_t* info_tmp;
 if ((listen_fd = socket(2, SOCK_STREAM, 0)) == -1) {
  printf("[xlcom_server] [L] cannot open socket.\n");
  return ((void *)0);
 }
 memset((char *)&server_addr, 0, sizeof(server_addr));
 server_addr.sin_family = 2;
 server_addr.sin_addr.s_addr = ((in_addr_t) 0x00000000);
 server_addr.sin_port = htons(64787);
 while(bind(listen_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
  printf("[xlcom_server] [L] cannot bind port %d. trying again in %d seconds.\n", 64787, 5);
  sleep(5);
 }
 listen(listen_fd, 30);
 printf("[xlcom_server] [L] Listening on port %d. Max pending connections %d.\n", 64787, 30);
 while(1) {
  if ((client_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &client_sz)) < 0) {
   perror("[xlcom_server] [L] could not accept connection.\n");
   close(listen_fd);
   return ((void *)0);
  }
  printf("[xlcom_server] [L] Received new connection from %s on fd %d.\n", inet_ntoa(client_addr.sin_addr), client_fd);
  epoll_ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
  epoll_ev.data.fd = client_fd;
  if ((result = epoll_ctl(Epoll_fd, 1, client_fd, &epoll_ev)) != 0) {
   printf("[xlcom_server] [L] Error adding new connection to epoll queue.\n");
   close(listen_fd);
   return ((void *)0);
  }
  key_tmp = malloc(sizeof(int));
  *key_tmp = client_fd;
  info_tmp = client_info_create();
  client_info_set_fd(info_tmp, client_fd);
  client_info_set_address(info_tmp, inet_ntoa(client_addr.sin_addr));
  client_info_set_username(info_tmp, "Anonymous");
  avl_insert(Active_connections, key_tmp, info_tmp);
 }
}

canonical_original_code:
void *thr_listener(void *arg) {
 int listen_fd; int client_fd;
 struct sockaddr_in client_addr; struct sockaddr_in server_addr;
 unsigned int client_sz = sizeof(client_addr);
 struct epoll_event epoll_ev;
 int result;
 int *key_tmp;
 struct client_info_t *info_tmp;
 if ((listen_fd = socket(2, SOCK_STREAM, 0)) == -1) {
  printf("[xlcom_server] [L] cannot open socket.\n");
  return ((void *)0);
 }
 memset((char *)&server_addr, 0, sizeof(server_addr));
 server_addr.sin_family = 2;
 server_addr.sin_addr.s_addr = ((unsigned int) 0x00000000);
 server_addr.sin_port = htons(64787);
 while(bind(listen_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
  printf("[xlcom_server] [L] cannot bind port %d. trying again in %d seconds.\n", 64787, 5);
  sleep(5);
 }
 listen(listen_fd, 30);
 printf("[xlcom_server] [L] Listening on port %d. Max pending connections %d.\n", 64787, 30);
 while(1) {
  if ((client_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &client_sz)) < 0) {
   perror("[xlcom_server] [L] could not accept connection.\n");
   close(listen_fd);
   return ((void *)0);
  }
  printf("[xlcom_server] [L] Received new connection from %s on fd %d.\n", inet_ntoa(client_addr.sin_addr), client_fd);
  epoll_ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
  epoll_ev.data.fd = client_fd;
  if ((result = epoll_ctl(Epoll_fd, 1, client_fd, &epoll_ev)) != 0) {
   printf("[xlcom_server] [L] Error adding new connection to epoll queue.\n");
   close(listen_fd);
   return ((void *)0);
  }
  key_tmp = malloc(sizeof(int));
  *key_tmp = client_fd;
  info_tmp = client_info_create();
  client_info_set_fd(info_tmp, client_fd);
  client_info_set_address(info_tmp, inet_ntoa(client_addr.sin_addr));
  client_info_set_username(info_tmp, "Anonymous");
  avl_insert(Active_connections, key_tmp, info_tmp);
 }
}

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: result int

variable_types: struct client_info_t { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; int fd; char address[16]; int is_authed; int id; char username[32]; } *

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: union epoll_data { void *ptr; int fd; unsigned int u32; unsigned long u64; }

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


decompiled_code:
int database_init()
{
Database = db_init();
if ( !db_connect(Database, "localhost", 3306LL, "xlcom", "xlcom_secret") )
{
puts("[xlcom_server] [M] Failed to connect to database.");
exit(-1);
}
return printf(
"[xlcom_server] [M] Database connection established: %s@%s:%d/%s\n",
"xlcom",
"localhost",
3306LL,
"xlcom");
}

canonical_decompiled_code:
int func5()
{
Database = db_init();
if ( !db_connect(Database, "localhost", 3306LL, "xlcom", "xlcom_secret") )
{
puts("[xlcom_server] [M] Failed to connect to database.");
exit(-1);
}
return printf(
"[xlcom_server] [M] Database connection established: %s@%s:%d/%s\n",
"xlcom",
"localhost",
3306LL,
"xlcom");
}

original_code:
void database_init() {
 Database = db_init();
 if (db_connect(Database, "localhost", 3306, "xlcom", "xlcom_secret", "xlcom") == ((void *)0)) {
  printf("[xlcom_server] [M] Failed to connect to database.\n");
  exit(-1);
 }
 printf("[xlcom_server] [M] Database connection established: %s@%s:%d/%s\n", "xlcom", "localhost", 3306, "xlcom");
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t *v3; // rbp
unsigned int i; // ebx
int v5; // ebp
__int64 j; // rbx
pthread_t v8[4]; // [rsp+0h] [rbp-48h] BYREF
pthread_t newthread; // [rsp+20h] [rbp-28h] BYREF
pthread_t th[4]; // [rsp+28h] [rbp-20h] BYREF

Epoll_fd = epoll_create1(0);
Queue_client_requests = queue_create(0LL, argv);
sem_init(&Sem_client_requests, 0, 0);
Active_connections = avl_create(int_comparator);
pthread_mutex_init(&Active_connections_mutex, 0LL);
database_init();
xlcom_init(Database, Active_connections);
v3 = v8;
for ( i = 0; i != 4; ++i )
{
if ( pthread_create(v3, 0LL, (void *(*)(void *))thr_handler, 0LL) )
{
printf("[xlcom_server] [M] Error creating handler thread with id %d\n", i);
return -1;
}
++v3;
}
if ( pthread_create(&newthread, 0LL, (void *(*)(void *))thr_poller, 0LL) )
{
puts("[xlcom_server] [M] Error creating poller thread");
v5 = -1;
}
else
{
v5 = pthread_create(th, 0LL, thr_listener, 0LL);
if ( v5 )
{
puts("[xlcom_server] [M] Error creating listener thread");
v5 = -1;
}
else
{
puts("[xlcom_server] [M] Successful initialization.");
printf("[xlcom_server] [M] Created threads: [%d|handler] [%d|poller] [%d|listener]\n", 4LL, 1LL, 1LL);
pthread_join(th[0], 0LL);
puts("[xlcom_server] [M] Listener thread exited.");
pthread_join(newthread, 0LL);
puts("[xlcom_server] [M] Poller thread exited.");
for ( j = 0LL; j != 4; ++j )
{
pthread_join(v8[j], 0LL);
printf("[xlcom_server] [M] Handler thread with id %d exited.\n", (unsigned int)j);
}
puts("[xlcom_server] [M] Graceful termiation. Bye!");
}
}
return v5;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t *v3; // rbp
unsigned int i; // ebx
int v5; // ebp
__int64 j; // rbx
pthread_t v8[4]; // [rsp+0h] [rbp-48h] BYREF
pthread_t newthread; // [rsp+20h] [rbp-28h] BYREF
pthread_t th[4]; // [rsp+28h] [rbp-20h] BYREF

Epoll_fd = epoll_create1(0);
Queue_client_requests = queue_create(0LL, argv);
sem_init(&Sem_client_requests, 0, 0);
Active_connections = avl_create(int_comparator);
pthread_mutex_init(&Active_connections_mutex, 0LL);
func5();
xlcom_init(Database, Active_connections);
v3 = v8;
for ( i = 0; i != 4; ++i )
{
if ( pthread_create(v3, 0LL, (void *(*)(void *))thr_handler, 0LL) )
{
printf("[xlcom_server] [M] Error creating handler thread with id %d\n", i);
return -1;
}
++v3;
}
if ( pthread_create(&newthread, 0LL, (void *(*)(void *))thr_poller, 0LL) )
{
puts("[xlcom_server] [M] Error creating poller thread");
v5 = -1;
}
else
{
v5 = pthread_create(th, 0LL, thr_listener, 0LL);
if ( v5 )
{
puts("[xlcom_server] [M] Error creating listener thread");
v5 = -1;
}
else
{
puts("[xlcom_server] [M] Successful initialization.");
printf("[xlcom_server] [M] Created threads: [%d|handler] [%d|poller] [%d|listener]\n", 4LL, 1LL, 1LL);
pthread_join(th[0], 0LL);
puts("[xlcom_server] [M] Listener thread exited.");
pthread_join(newthread, 0LL);
puts("[xlcom_server] [M] Poller thread exited.");
for ( j = 0LL; j != 4; ++j )
{
pthread_join(v8[j], 0LL);
printf("[xlcom_server] [M] Handler thread with id %d exited.\n", (unsigned int)j);
}
puts("[xlcom_server] [M] Graceful termiation. Bye!");
}
}
return v5;
}

original_code:
int main(int argc, char **argv) {
 pthread_t pthr_listener;
 pthread_t pthr_poller;
 pthread_t pthr_handler[4];
 int i;
 Epoll_fd = epoll_create1(0);
 Queue_client_requests = queue_create();
 sem_init(&Sem_client_requests, 0, 0);
 Active_connections = avl_create(&int_comparator);
 pthread_mutex_init(&Active_connections_mutex, ((void *)0));
 database_init();
 xlcom_init(Database, Active_connections);
 for(i=0; i<4; i++) {
  if (pthread_create(&pthr_handler[i], ((void *)0), thr_handler, (void*) ((void *)0)) != 0) {
   printf("[xlcom_server] [M] Error creating handler thread with id %d\n", i);
   return -1;
  }
 }
 if (pthread_create(&pthr_poller, ((void *)0), thr_poller, (void*) ((void *)0)) != 0) {
  printf("[xlcom_server] [M] Error creating poller thread\n");
  return -1;
 }
 if (pthread_create(&pthr_listener, ((void *)0), thr_listener, (void*) ((void *)0)) != 0) {
  printf("[xlcom_server] [M] Error creating listener thread\n");
  return -1;
 }
 printf("[xlcom_server] [M] Successful initialization.\n");
 printf("[xlcom_server] [M] Created threads: [%d|handler] [%d|poller] [%d|listener]\n", 4, 1, 1);
 pthread_join(pthr_listener, (void**) ((void *)0));
 printf("[xlcom_server] [M] Listener thread exited.\n");
 pthread_join(pthr_poller, (void**) ((void *)0));
 printf("[xlcom_server] [M] Poller thread exited.\n");
 for(i=0; i<4; i++) {
  pthread_join(pthr_handler[i], (void**) ((void *)0));
  printf("[xlcom_server] [M] Handler thread with id %d exited.\n", i);
 }
 printf("[xlcom_server] [M] Graceful termiation. Bye!\n");
 return 0;
}

canonical_original_code:
int main(int argc, char **argv) {
 unsigned long pthr_listener;
 unsigned long pthr_poller;
 unsigned long pthr_handler[4];
 int i;
 Epoll_fd = epoll_create1(0);
 Queue_client_requests = queue_create();
 sem_init(&Sem_client_requests, 0, 0);
 Active_connections = avl_create(&int_comparator);
 pthread_mutex_init(&Active_connections_mutex, ((void *)0));
 database_init();
 xlcom_init(Database, Active_connections);
 for(i=0; i<4; i++) {
  if (pthread_create(&pthr_handler[i], ((void *)0), thr_handler, (void *) ((void *)0)) != 0) {
   printf("[xlcom_server] [M] Error creating handler thread with id %d\n", i);
   return -1;
  }
 }
 if (pthread_create(&pthr_poller, ((void *)0), thr_poller, (void *) ((void *)0)) != 0) {
  printf("[xlcom_server] [M] Error creating poller thread\n");
  return -1;
 }
 if (pthread_create(&pthr_listener, ((void *)0), thr_listener, (void *) ((void *)0)) != 0) {
  printf("[xlcom_server] [M] Error creating listener thread\n");
  return -1;
 }
 printf("[xlcom_server] [M] Successful initialization.\n");
 printf("[xlcom_server] [M] Created threads: [%d|handler] [%d|poller] [%d|listener]\n", 4, 1, 1);
 pthread_join(pthr_listener, (void **) ((void *)0));
 printf("[xlcom_server] [M] Listener thread exited.\n");
 pthread_join(pthr_poller, (void **) ((void *)0));
 printf("[xlcom_server] [M] Poller thread exited.\n");
 for(i=0; i<4; i++) {
  pthread_join(pthr_handler[i], (void **) ((void *)0));
  printf("[xlcom_server] [M] Handler thread with id %d exited.\n", i);
 }
 printf("[xlcom_server] [M] Graceful termiation. Bye!\n");
 return 0;
}

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
pthread_mutex_t *client_info_create()
{
pthread_mutex_t *v0; // rbx

v0 = (pthread_mutex_t *)malloc(0x68uLL);
memset(v0, 0, 0x68uLL);
pthread_mutex_init(v0, 0LL);
return v0;
}

canonical_decompiled_code:
pthread_mutex_t *func0()
{
pthread_mutex_t *v0; // rbx

v0 = (pthread_mutex_t *)malloc(0x68uLL);
memset(v0, 0, 0x68uLL);
pthread_mutex_init(v0, 0LL);
return v0;
}

original_code:
client_info_t* client_info_create() {
 client_info_t* info = malloc(sizeof(client_info_t));
 memset(info, 0, sizeof(client_info_t));
 pthread_mutex_init(&info->mutex, ((void *)0));
 return info;
}

canonical_original_code:
struct client_info_t *client_info_create() {
 struct client_info_t *info = malloc(sizeof(client_info_t));
 memset(info, 0, sizeof(client_info_t));
 pthread_mutex_init(&info->mutex, ((void *)0));
 return info;
}

return_type: struct client_info_t { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; int fd; char address[16]; int is_authed; int id; char username[32]; } *


decompiled_code:
void __fastcall client_info_destroy(void *ptr)
{
pthread_mutex_destroy((pthread_mutex_t *)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
pthread_mutex_destroy((pthread_mutex_t *)ptr);
free(ptr);
}

original_code:
void client_info_destroy(client_info_t* info) {
 pthread_mutex_destroy(&info->mutex);
 free(info);
}

canonical_original_code:
void client_info_destroy(struct client_info_t *info) {
 pthread_mutex_destroy(&info->mutex);
 free(info);
}


decompiled_code:
int __fastcall client_info_set_fd(pthread_mutex_t *mutex, int a2)
{
pthread_mutex_lock(mutex);
mutex[1].__lock = a2;
return pthread_mutex_unlock(mutex);
}

canonical_decompiled_code:
int __fastcall func2(pthread_mutex_t *mutex, int a2)
{
pthread_mutex_lock(mutex);
mutex[1].__lock = a2;
return pthread_mutex_unlock(mutex);
}

original_code:
void client_info_set_fd(client_info_t* info, int fd) {
 pthread_mutex_lock(&info->mutex);
 info->fd = fd;
 pthread_mutex_unlock(&info->mutex);
}

canonical_original_code:
void client_info_set_fd(struct client_info_t *info, int fd) {
 pthread_mutex_lock(&info->mutex);
 info->fd = fd;
 pthread_mutex_unlock(&info->mutex);
}

variable_types: fd int


decompiled_code:
__int64 __fastcall client_info_get_fd(__int64 a1)
{
return *(unsigned int *)(a1 + 40);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
return *(unsigned int *)(a1 + 40);
}

original_code:
int client_info_get_fd(client_info_t* info) {
 return info->fd;
}

canonical_original_code:
int client_info_get_fd(struct client_info_t *info) {
 return info->fd;
}


decompiled_code:
int __fastcall client_info_set_address(pthread_mutex_t *mutex, char *src)
{
pthread_mutex_lock(mutex);
strncpy(&mutex[1].__size[4], src, 0x10uLL);
return pthread_mutex_unlock(mutex);
}

canonical_decompiled_code:
int __fastcall func4(pthread_mutex_t *mutex, char *src)
{
pthread_mutex_lock(mutex);
strncpy(&mutex[1].__size[4], src, 0x10uLL);
return pthread_mutex_unlock(mutex);
}

original_code:
void client_info_set_address(client_info_t* info, char* address) {
 pthread_mutex_lock(&info->mutex);
 strncpy(info->address, address, 16);
 pthread_mutex_unlock(&info->mutex);
}

canonical_original_code:
void client_info_set_address(struct client_info_t *info, char *address) {
 pthread_mutex_lock(&info->mutex);
 strncpy(info->address, address, 16);
 pthread_mutex_unlock(&info->mutex);
}

variable_types:
address
char *


decompiled_code:
__int64 __fastcall client_info_get_address(__int64 a1)
{
return a1 + 44;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
return a1 + 44;
}

original_code:
char* client_info_get_address(client_info_t* info) {
 return info->address;
}

canonical_original_code:
char *client_info_get_address(struct client_info_t *info) {
 return info->address;
}

return_type: char *


decompiled_code:
int __fastcall client_info_set_is_authed(pthread_mutex_t *mutex, int a2)
{
pthread_mutex_lock(mutex);
mutex[1].__spins = a2;
return pthread_mutex_unlock(mutex);
}

canonical_decompiled_code:
int __fastcall func6(pthread_mutex_t *mutex, int a2)
{
pthread_mutex_lock(mutex);
mutex[1].__spins = a2;
return pthread_mutex_unlock(mutex);
}

original_code:
void client_info_set_is_authed(client_info_t* info, int is_authed) {
 pthread_mutex_lock(&info->mutex);
 info->is_authed = is_authed;
 pthread_mutex_unlock(&info->mutex);
}

canonical_original_code:
void client_info_set_is_authed(struct client_info_t *info, int is_authed) {
 pthread_mutex_lock(&info->mutex);
 info->is_authed = is_authed;
 pthread_mutex_unlock(&info->mutex);
}


decompiled_code:
__int64 __fastcall client_info_get_is_authed(__int64 a1)
{
return *(unsigned int *)(a1 + 60);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return *(unsigned int *)(a1 + 60);
}

original_code:
int client_info_get_is_authed(client_info_t* info) {
 return info->is_authed;
}

canonical_original_code:
int client_info_get_is_authed(struct client_info_t *info) {
 return info->is_authed;
}


decompiled_code:
int __fastcall client_info_set_id(pthread_mutex_t *mutex, int a2)
{
pthread_mutex_lock(mutex);
*((_DWORD *)&mutex[1].__align + 6) = a2;
return pthread_mutex_unlock(mutex);
}

canonical_decompiled_code:
int __fastcall func8(pthread_mutex_t *mutex, int a2)
{
pthread_mutex_lock(mutex);
*((_DWORD *)&mutex[1].__align + 6) = a2;
return pthread_mutex_unlock(mutex);
}

original_code:
void client_info_set_id(client_info_t* info, int id) {
 pthread_mutex_lock(&info->mutex);
 info->id = id;
 pthread_mutex_unlock(&info->mutex);
}

canonical_original_code:
void client_info_set_id(struct client_info_t *info, int id) {
 pthread_mutex_lock(&info->mutex);
 info->id = id;
 pthread_mutex_unlock(&info->mutex);
}

variable_types: id int


decompiled_code:
__int64 __fastcall client_info_get_id(__int64 a1)
{
return *(unsigned int *)(a1 + 64);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
return *(unsigned int *)(a1 + 64);
}

original_code:
int client_info_get_id(client_info_t* info) {
 return info->id;
}

canonical_original_code:
int client_info_get_id(struct client_info_t *info) {
 return info->id;
}


decompiled_code:
int __fastcall client_info_set_username(pthread_mutex_t *mutex, char *src)
{
pthread_mutex_lock(mutex);
strncpy(&mutex[1].__size[28], src, 0x20uLL);
return pthread_mutex_unlock(mutex);
}

canonical_decompiled_code:
int __fastcall func10(pthread_mutex_t *mutex, char *src)
{
pthread_mutex_lock(mutex);
strncpy(&mutex[1].__size[28], src, 0x20uLL);
return pthread_mutex_unlock(mutex);
}

original_code:
void client_info_set_username(client_info_t* info, char* username) {
 pthread_mutex_lock(&info->mutex);
 strncpy(info->username, username, 32);
 pthread_mutex_unlock(&info->mutex);
}

canonical_original_code:
void client_info_set_username(struct client_info_t *info, char *username) {
 pthread_mutex_lock(&info->mutex);
 strncpy(info->username, username, 32);
 pthread_mutex_unlock(&info->mutex);
}

variable_types:
username
char *


decompiled_code:
__int64 __fastcall client_info_get_username(__int64 a1)
{
return a1 + 68;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
return a1 + 68;
}

original_code:
char* client_info_get_username(client_info_t* info) {
 return info->username;
}

canonical_original_code:
char *client_info_get_username(struct client_info_t *info) {
 return info->username;
}


decompiled_code:
char *__fastcall client_info_print_auth(pthread_mutex_t *mutex)
{
pthread_mutex_lock(mutex);
if ( (unsigned int)client_info_get_is_authed((__int64)mutex) )
sprintf(message_0, "%s@%s", &mutex[1].__size[28], &mutex[1].__size[4]);
else
strcpy(message_0, &mutex[1].__size[4]);
pthread_mutex_unlock(mutex);
return message_0;
}

canonical_decompiled_code:
char *__fastcall func12(pthread_mutex_t *mutex)
{
pthread_mutex_lock(mutex);
if ( (unsigned int)func7((__int64)mutex) )
sprintf(message_0, "%s@%s", &mutex[1].__size[28], &mutex[1].__size[4]);
else
strcpy(message_0, &mutex[1].__size[4]);
pthread_mutex_unlock(mutex);
return message_0;
}

original_code:
char* client_info_print_auth(client_info_t* info) {
 static char message[100];
 pthread_mutex_lock(&info->mutex);
 if (client_info_get_is_authed(info)) {
  sprintf(message, "%s@%s", info->username, info->address);
 }
 else {
  sprintf(message, "%s", info->address);
 }
 pthread_mutex_unlock(&info->mutex);
 return message;
}

canonical_original_code:
char *client_info_print_auth(struct client_info_t *info) {
 static char message[100];
 pthread_mutex_lock(&info->mutex);
 if (client_info_get_is_authed(info)) {
  sprintf(message, "%s@%s", info->username, info->address);
 }
 else {
  sprintf(message, "%s", info->address);
 }
 pthread_mutex_unlock(&info->mutex);
 return message;
}

variable_types:
message
char [100]


decompiled_code:
_DWORD *client_init()
{
_DWORD *result; // rax

result = malloc(4uLL);
Client_data = (__int64)result;
*result = 0;
return result;
}

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

result = malloc(4uLL);
Client_data = (__int64)result;
*result = 0;
return result;
}

original_code:
void client_init() {
 Client_data = malloc(sizeof(client_data_t));
 Client_data->connection = 0;
}


decompiled_code:
__int64 __fastcall client_connect(__int64 a1, unsigned __int16 a2)
{
return xlcom_connect(a1, a2, Client_data);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned __int16 a2)
{
return xlcom_connect(a1, a2, Client_data);
}

original_code:
int client_connect(char* server_addr, unsigned short port) {
 return xlcom_connect(server_addr, port, &Client_data->connection);
}

canonical_original_code:
int client_connect(char *server_addr, unsigned short port) {
 return xlcom_connect(server_addr, port, &Client_data->connection);
}

variable_types:
port
unsigned short


decompiled_code:
__int64 client_disconnect()
{
return xlcom_disconnect(*(unsigned int *)Client_data);
}

canonical_decompiled_code:
__int64 func2()
{
return xlcom_disconnect(*(unsigned int *)Client_data);
}

original_code:
int client_disconnect() {
 return xlcom_disconnect(Client_data->connection);
}


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

v5[0] = argc;
v4 = argv;
gtk_init(v5, &v4, envp);
client_init();
window_main_create();
gtk_main();
return 0;
}

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

v5[0] = argc;
v4 = argv;
gtk_init(v5, &v4, envp);
func0();
window_main_create();
gtk_main();
return 0;
}

original_code:
int main(int argc, char *argv[]) {
 gtk_init(&argc, &argv);
 client_init();
 window_main_create();
 gtk_main();
 return 0;
}

variable_types:
argv
char *[]


printmenu

decompiled_code:
int printmenu()
{
puts("##########################");
puts("## XL-COM Client - Menu ##");
puts("##########################");
printf("(%d) - Connect to server\n", 1LL);
printf("(%d) - Disconnect from server\n", 2LL);
printf("(%d) - Send ping request\n", 3LL);
printf("(%d) - Send echo request\n", 4LL);
printf("(%d) - Authenticate\n", 5LL);
printf("(%d) - Send message\n", 6LL);
printf("(%d) - Exit\n", 0LL);
return printf("\nOption = ");
}

canonical_decompiled_code:
int func0()
{
puts("##########################");
puts("## XL-COM Client - Menu ##");
puts("##########################");
printf("(%d) - Connect to server\n", 1LL);
printf("(%d) - Disconnect from server\n", 2LL);
printf("(%d) - Send ping request\n", 3LL);
printf("(%d) - Send echo request\n", 4LL);
printf("(%d) - Authenticate\n", 5LL);
printf("(%d) - Send message\n", 6LL);
printf("(%d) - Exit\n", 0LL);
return printf("\nOption = ");
}

original_code:
void printmenu() {
 printf("##########################\n");
 printf("## XL-COM Client - Menu ##\n");
 printf("##########################\n");
 printf("(%d) - Connect to server\n", OPTION_CONNECT);
 printf("(%d) - Disconnect from server\n", OPTION_DISCONNECT);
 printf("(%d) - Send ping request\n", OPTION_PING);
 printf("(%d) - Send echo request\n", OPTION_ECHO);
 printf("(%d) - Authenticate\n", OPTION_AUTH);
 printf("(%d) - Send message\n", OPTION_SEND_MESSAGE);
 printf("(%d) - Exit\n", OPTION_EXIT);
 printf("\nOption = ");
}


decompiled_code:
void __noreturn cmd_exit()
{
puts("Bye!");
exit(0);
}

canonical_decompiled_code:
void __noreturn func1()
{
puts("Bye!");
exit(0);
}

original_code:
void cmd_exit() {
 printf("Bye!\n");
 exit(0);
}


decompiled_code:
int cmd_connect()
{
if ( Connected )
return puts("Aborted. Already connected.");
if ( (unsigned int)xlcom_connect("127.0.0.1", 64787LL, &Sock_fd) )
return puts("Error connecting to server.");
Connected = 1;
return puts("Successfully connected.");
}

canonical_decompiled_code:
int func2()
{
if ( Connected )
return puts("Aborted. Already connected.");
if ( (unsigned int)xlcom_connect("127.0.0.1", 64787LL, &Sock_fd) )
return puts("Error connecting to server.");
Connected = 1;
return puts("Successfully connected.");
}

original_code:
void cmd_connect() {
 char* ip = "127.0.0.1";
 unsigned short port = 64787;
 if(Connected) {
  printf("Aborted. Already connected.\n");
  return;
 }
 if (xlcom_connect(ip, port, &Sock_fd) != XLCOM_STAT_OK) {
  printf("Error connecting to server.\n");
  return;
 }
 Connected = true;
 printf("Successfully connected.\n");
}

canonical_original_code:
void cmd_connect() {
 char *ip = "127.0.0.1";
 unsigned short port = 64787;
 if(Connected) {
  printf("Aborted. Already connected.\n");
  return;
 }
 if (xlcom_connect(ip, port, &Sock_fd) != XLCOM_STAT_OK) {
  printf("Error connecting to server.\n");
  return;
 }
 Connected = true;
 printf("Successfully connected.\n");
}

variable_types:
ip
char *


decompiled_code:
int cmd_disconnect()
{
if ( !Connected )
return puts("Aborted. Not connected.");
if ( (unsigned int)xlcom_disconnect((unsigned int)Sock_fd) )
return puts("Error disconnecting from server.");
Connected = 0;
return puts("Successfully disconnected.");
}

canonical_decompiled_code:
int func3()
{
if ( !Connected )
return puts("Aborted. Not connected.");
if ( (unsigned int)xlcom_disconnect((unsigned int)Sock_fd) )
return puts("Error disconnecting from server.");
Connected = 0;
return puts("Successfully disconnected.");
}

original_code:
void cmd_disconnect() {
 if(!Connected) {
  printf("Aborted. Not connected.\n");
  return;
 }
 if(xlcom_disconnect(Sock_fd) != XLCOM_STAT_OK) {
  printf("Error disconnecting from server.\n");
  return;
 }
 Connected = false;
 printf("Successfully disconnected.\n");
}


decompiled_code:
int cmd_ping()
{
double v1[2]; // [rsp+8h] [rbp-10h] BYREF

if ( !Connected )
return puts("Aborted. Not connected.");
if ( (unsigned int)xlcom_ping((unsigned int)Sock_fd, v1) )
puts("Error pinging the server.");
return printf("Ping time = %f seconds\n", v1[0]);
}

canonical_decompiled_code:
int func4()
{
double v1[2]; // [rsp+8h] [rbp-10h] BYREF

if ( !Connected )
return puts("Aborted. Not connected.");
if ( (unsigned int)xlcom_ping((unsigned int)Sock_fd, v1) )
puts("Error pinging the server.");
return printf("Ping time = %f seconds\n", v1[0]);
}

original_code:
void cmd_ping() {
 double time;
 if (!Connected) {
  printf("Aborted. Not connected.\n");
  return;
 }
 if (xlcom_ping(Sock_fd, &time) != XLCOM_STAT_OK) {
  printf("Error pinging the server.\n");
 }
 printf("Ping time = %f seconds\n", time);
}

variable_types: time double


decompiled_code:
int cmd_echo()
{
int result; // eax
char v1[121]; // [rsp+1h] [rbp-79h]
char v2[120]; // [rsp+2h] [rbp-78h] BYREF

printf("String to send: ");
if ( !fgets(v2, 100, stdin) )
return puts("Error in fgets.");
if ( !Connected )
return puts("Aborted. Not connected.");
v1[strlen(v2)] = 0;
if ( (unsigned int)xlcom_echo((unsigned int)Sock_fd, v2) )
result = puts("Error echoing message.");
else
result = printf("Successfully echoed '%s'.\n", v2);
return result;
}

canonical_decompiled_code:
int func5()
{
int result; // eax
char v1[121]; // [rsp+1h] [rbp-79h]
char v2[120]; // [rsp+2h] [rbp-78h] BYREF

printf("String to send: ");
if ( !fgets(v2, 100, stdin) )
return puts("Error in fgets.");
if ( !Connected )
return puts("Aborted. Not connected.");
v1[strlen(v2)] = 0;
if ( (unsigned int)xlcom_echo((unsigned int)Sock_fd, v2) )
result = puts("Error echoing message.");
else
result = printf("Successfully echoed '%s'.\n", v2);
return result;
}

original_code:
void cmd_echo() {
 char sent_msg[100];
 printf("String to send: ");
 if(fgets(sent_msg, 100, stdin) == ((void *)0)) {
  printf("Error in fgets.\n");
  return;
 }
 if (!Connected) {
  printf("Aborted. Not connected.\n");
  return;
 }
 sent_msg[strlen(sent_msg) - 1] = '\0';
 if (xlcom_echo(Sock_fd, sent_msg) != XLCOM_STAT_OK) {
  printf("Error echoing message.\n");
  return;
 }
 printf("Successfully echoed '%s'.\n", sent_msg);
}


decompiled_code:
int cmd_auth()
{
int result; // eax
char v1[112]; // [rsp+1h] [rbp-E9h]
char v2[112]; // [rsp+2h] [rbp-E8h] BYREF
char s[120]; // [rsp+72h] [rbp-78h] BYREF

printf("Username: ");
if ( !fgets(s, 100, stdin) )
return puts("Error in fgets.");
printf("Password: ");
if ( !fgets(v2, 100, stdin) )
return puts("Error in fgets.");
if ( !Connected )
return puts("Aborted. Not connected.");
v2[strlen(s) + 111] = 0;
v1[strlen(v2)] = 0;
if ( (unsigned int)xlcom_auth((unsigned int)Sock_fd, s, v2) )
result = puts("Error authenticating.");
else
result = printf("Successfully authenticated. Welcome, %s.\n", s);
return result;
}

canonical_decompiled_code:
int func6()
{
int result; // eax
char v1[112]; // [rsp+1h] [rbp-E9h]
char v2[112]; // [rsp+2h] [rbp-E8h] BYREF
char s[120]; // [rsp+72h] [rbp-78h] BYREF

printf("Username: ");
if ( !fgets(s, 100, stdin) )
return puts("Error in fgets.");
printf("Password: ");
if ( !fgets(v2, 100, stdin) )
return puts("Error in fgets.");
if ( !Connected )
return puts("Aborted. Not connected.");
v2[strlen(s) + 111] = 0;
v1[strlen(v2)] = 0;
if ( (unsigned int)xlcom_auth((unsigned int)Sock_fd, s, v2) )
result = puts("Error authenticating.");
else
result = printf("Successfully authenticated. Welcome, %s.\n", s);
return result;
}

original_code:
void cmd_auth() {
 char user[100];
 char pass[100];
 printf("Username: ");
 if(fgets(user, 100, stdin) == ((void *)0)) {
  printf("Error in fgets.\n");
  return;
 }
 printf("Password: ");
 if(fgets(pass, 100, stdin) == ((void *)0)) {
  printf("Error in fgets.\n");
  return;
 }
 if (!Connected) {
  printf("Aborted. Not connected.\n");
  return;
 }
 user[strlen(user)-1] = '\0';
 pass[strlen(pass)-1] = '\0';
 if (xlcom_auth(Sock_fd, user, pass) != XLCOM_STAT_OK) {
  printf("Error authenticating.\n");
  return;
 }
 printf("Successfully authenticated. Welcome, %s.\n", user);
}

variable_types:
user
char [100]

variable_types:
pass
char [100]