writePrimPacketToStdOut

decompiled_code:
int __fastcall writePrimPacketToStdOut(__int64 a1, const char *a2)
{
int result; // eax

result = *(_DWORD *)a1;
switch ( *(_DWORD *)a1 )
{
case 0:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_req,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 1:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_ind,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 2:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_resp,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 3:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_conf,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 4:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DATA_req,con_number=%c,transaction=%s\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(const char *)(a1 + 5));
break;
case 5:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DATA_ind,con_number=%c,transaction=%s\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(const char *)(a1 + 5));
break;
case 6:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_req,con_number=%c\n",
a2,
(unsigned int)*(char *)(a1 + 4));
break;
case 7:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_ind,con_number=%c\n",
a2,
(unsigned int)*(char *)(a1 + 4));
break;
default:
return result;
}
return result;
}

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

result = *(_DWORD *)a1;
switch ( *(_DWORD *)a1 )
{
case 0:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_req,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 1:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_ind,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 2:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_resp,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 3:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_conf,con_number=%c,src_addr=%i,dest_addr=%i\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(unsigned int)*(char *)(a1 + 5),
(unsigned int)*(char *)(a1 + 6));
break;
case 4:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DATA_req,con_number=%c,transaction=%s\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(const char *)(a1 + 5));
break;
case 5:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DATA_ind,con_number=%c,transaction=%s\n",
a2,
(unsigned int)*(char *)(a1 + 4),
(const char *)(a1 + 5));
break;
case 6:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_req,con_number=%c\n",
a2,
(unsigned int)*(char *)(a1 + 4));
break;
case 7:
result = printf(
"%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_ind,con_number=%c\n",
a2,
(unsigned int)*(char *)(a1 + 4));
break;
default:
return result;
}
return result;
}

original_code:
void writePrimPacketToStdOut(PRIM_PACKET* p, char* WHO_AM_I)
{
    switch(p->prim)
    {
        case N_CONNECT_req:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_req,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_CONNECT_ind:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_ind,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_CONNECT_resp:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_resp,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_CONNECT_conf:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_conf,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_DATA_req:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DATA_req,con_number=%c,transaction=%s\n",
                WHO_AM_I,
                p->data_prim_packet.con_number,
                p->data_prim_packet.transaction);
            break;
        case N_DATA_ind:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DATA_ind,con_number=%c,transaction=%s\n",
                WHO_AM_I,
                p->data_prim_packet.con_number,
                p->data_prim_packet.transaction);
            break;
        case N_DISCONNECT_req:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_req,con_number=%c\n",
                WHO_AM_I,
                p->rel_prim_packet.con_number);
            break;
        case N_DISCONNECT_ind:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_ind,con_number=%c\n",
                WHO_AM_I,
                p->rel_prim_packet.con_number);
            break;
    }
}

canonical_original_code:
void writePrimPacketToStdOut(union PRIM_PACKET *p, char *WHO_AM_I)
{
    switch(p->prim)
    {
        case N_CONNECT_req:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_req,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_CONNECT_ind:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_ind,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_CONNECT_resp:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_resp,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_CONNECT_conf:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_CONNECT_conf,con_number=%c,src_addr=%i,dest_addr=%i\n",
                WHO_AM_I,
                p->con_prim_packet.con_number,
                p->con_prim_packet.src_addr,
                p->con_prim_packet.dest_addr);
            break;
        case N_DATA_req:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DATA_req,con_number=%c,transaction=%s\n",
                WHO_AM_I,
                p->data_prim_packet.con_number,
                p->data_prim_packet.transaction);
            break;
        case N_DATA_ind:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DATA_ind,con_number=%c,transaction=%s\n",
                WHO_AM_I,
                p->data_prim_packet.con_number,
                p->data_prim_packet.transaction);
            break;
        case N_DISCONNECT_req:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_req,con_number=%c\n",
                WHO_AM_I,
                p->rel_prim_packet.con_number);
            break;
        case N_DISCONNECT_ind:
            printf("%s: Envoie du paquet --- PRIMITIVE=N_DISCONNECT_ind,con_number=%c\n",
                WHO_AM_I,
                p->rel_prim_packet.con_number);
            break;
    }
}


genRemotePacketResponse

original_code:
int genRemotePacketResponse(PACKET* p)
{
    switch(p->packet_type)
    {
        case 0:
                if (p->con_packet.src_addr%19 == 0)
                    break;
                if (p->con_packet.src_addr%13 == 0) {
                    p->con_packet.con_packet_type = REL_ind;
                    p->con_packet.reason = REMOTE_DENY;
                    return 1;
                }
                else {
                    p->con_packet.con_packet_type = CON_conf;
                    return 1;
                }
            break;
        case 1:
            if (findConnection(p->data_packet.con_number)->ncon.src_addr%15 == 0)
                break;
            if (((p->data_packet.type << 4) >> 5) == (rand()%8))
            {
                p->data_packet.type = ((((((p->data_packet.type << 4) >> 4) + 0x02) << 4) >> 5)<<5);
                p->data_packet.type += 0x09;
                memset(p->data_packet.segm_data,0,sizeof(p->data_packet.segm_data)-1);
                return -1;
            }
            else {
                p->data_packet.type = ((((((p->data_packet.type << 4) >> 4) + 0x02) << 4) >> 5)<<5);
                p->data_packet.type += 0x01;
                memset(p->data_packet.segm_data,0,sizeof(p->data_packet.segm_data)-1);
                return 1;
            }
            break;
    }
    return 0;
}

canonical_original_code:
int genRemotePacketResponse(union PACKET *p)
{
    switch(p->packet_type)
    {
        case 0:
                if (p->con_packet.src_addr%19 == 0)
                    break;
                if (p->con_packet.src_addr%13 == 0) {
                    p->con_packet.con_packet_type = REL_ind;
                    p->con_packet.reason = REMOTE_DENY;
                    return 1;
                }
                else {
                    p->con_packet.con_packet_type = CON_conf;
                    return 1;
                }
            break;
        case 1:
            if (findConnection(p->data_packet.con_number)->ncon.src_addr%15 == 0)
                break;
            if (((p->data_packet.type << 4) >> 5) == (rand()%8))
            {
                p->data_packet.type = ((((((p->data_packet.type << 4) >> 4) + 0x02) << 4) >> 5)<<5);
                p->data_packet.type += 0x09;
                memset(p->data_packet.segm_data,0,sizeof(p->data_packet.segm_data)-1);
                return -1;
            }
            else {
                p->data_packet.type = ((((((p->data_packet.type << 4) >> 4) + 0x02) << 4) >> 5)<<5);
                p->data_packet.type += 0x01;
                memset(p->data_packet.segm_data,0,sizeof(p->data_packet.segm_data)-1);
                return 1;
            }
            break;
    }
    return 0;
}

variable_types: union PACKET { int packet_type; struct _CONNECTION_PACKET { int packet_type; enum CONNECTION_PACKET_TYPE { CON_req=11, CON_conf=15, REL_ind=19 } con_packet_type; char con_number; char src_addr; char dest_addr; enum REL_REASON { REMOTE_DENY=1, NET_DENY=2 } reason; } con_packet; struct _DATA_PACKET { int packet_type; char type; char con_number; char segm_data[128]; } data_packet; struct _RELEASE_PACKET { int packet_type; char type; char con_number; char src_addr; char dest_addr; } rel_packet; } *

return_type: int

user_defined_types: union PACKET { int packet_type; struct _CONNECTION_PACKET con_packet; struct _DATA_PACKET data_packet; struct _RELEASE_PACKET rel_packet; }

user_defined_types: struct _CONNECTION_PACKET { int packet_type; enum CONNECTION_PACKET_TYPE con_packet_type; char con_number; char src_addr; char dest_addr; enum REL_REASON reason; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
const char *v4; // rdi
unsigned int v5; // eax
unsigned int v6; // eax
__int16 v8; // ax
int v9; // er13
char v10; // al
char v11; // bp
int v12; // ebx
char v13; // al
__m128i v14; // xmm1
__m128i v15; // xmm2
__m128i v16; // xmm3
__m128i v17; // xmm4
__m128i v18; // xmm5
__m128i v19; // xmm6
__m128i v20; // xmm7
int v21; // eax
__int64 v22; // rax
__int64 v23; // rbx
char dest[16]; // [rsp+0h] [rbp-258h] BYREF
__m128i v25; // [rsp+10h] [rbp-248h] BYREF
__m128i v26; // [rsp+20h] [rbp-238h] BYREF
__m128i v27; // [rsp+30h] [rbp-228h] BYREF
__m128i v28; // [rsp+40h] [rbp-218h] BYREF
__m128i v29; // [rsp+50h] [rbp-208h] BYREF
__m128i v30; // [rsp+60h] [rbp-1F8h] BYREF
__m128i v31; // [rsp+70h] [rbp-1E8h] BYREF
__int64 v32; // [rsp+80h] [rbp-1D8h]
__int128 v33[8]; // [rsp+90h] [rbp-1C8h] BYREF
__int64 v34; // [rsp+110h] [rbp-148h]
int v35; // [rsp+120h] [rbp-138h] BYREF
char s[2]; // [rsp+124h] [rbp-134h] BYREF
char v37[306]; // [rsp+126h] [rbp-132h] BYREF

v3 = atoi(argv[1]);
v4 = argv[2];
netToTrans_pipe = v3;
transToNet_pipe = atoi(v4);
v5 = fcntl(transToNet_pipe, 3, 0LL);
BYTE1(v5) |= 8u;
fcntl(transToNet_pipe, 4, v5);
v6 = fcntl(netToTrans_pipe, 3, 0LL);
BYTE1(v6) |= 8u;
fcntl(netToTrans_pipe, 4, v6);
while ( (int)getPacketFromInterface(&v35, (unsigned int)transToNet_pipe) >= 0 )
{
switch ( v35 )
{
case 4:
v9 = strlen(&s[1]);
if ( v9 )
{
v10 = 0;
v11 = 1;
v12 = 0;
while ( 1 )
{
v12 += 128;
*(_DWORD *)dest = 1;
v13 = 32 * v11 + 2 * v10;
if ( v12 < v9 )
v13 |= 0x10u;
dest[4] = v13;
dest[5] = s[0];
strncpy(&dest[6], &s[1], 0x80uLL);
sendPacketToDataLinkLayer(dest, "./L_ECR");
v14 = _mm_loadu_si128(&v25);
v15 = _mm_loadu_si128(&v26);
v16 = _mm_loadu_si128(&v27);
v17 = _mm_loadu_si128(&v28);
v18 = _mm_loadu_si128(&v29);
v33[0] = (__int128)_mm_loadu_si128((const __m128i *)dest);
v19 = _mm_loadu_si128(&v30);
v20 = _mm_loadu_si128(&v31);
v33[1] = (__int128)v14;
v33[2] = (__int128)v15;
v33[3] = (__int128)v16;
v34 = v32;
v33[4] = (__int128)v17;
v33[5] = (__int128)v18;
v33[6] = (__int128)v19;
v33[7] = (__int128)v20;
v21 = genRemotePacketResponse((__int64)v33);
if ( v21 > 0 )
{
sendPacketToDataLinkLayer((const char *)v33, "./L_LEC");
}
else
{
if ( v21 )
sendPacketToDataLinkLayer((const char *)v33, "./L_LEC");
sendPacketToDataLinkLayer(dest, "./L_ECR");
if ( (unsigned int)genRemotePacketResponse((__int64)dest) )
sendPacketToDataLinkLayer(dest, "./L_LEC");
}
v10 = v11;
if ( v12 >= v9 )
break;
++v11;
}
}
break;
case 6:
v8 = *(_WORD *)(findConnection((unsigned int)s[0]) + 10);
*(_DWORD *)dest = 2;
dest[4] = 19;
dest[5] = s[0];
*(_WORD *)&dest[6] = v8;
sendPacketToDataLinkLayer(dest, "./L_ECR");
remove_connection((unsigned int)s[0]);
break;
case 0:
if ( (unsigned __int8)(19 * s[1] + 4) > 8u )
{
v22 = add_connection((unsigned int)s[0], &s[1], v37);
*(_QWORD *)dest = 0xB00000000LL;
v23 = v22;
*(_WORD *)&dest[8] = *(_WORD *)s;
dest[10] = v37[0];
if ( (unsigned int)sendPacketToDataLinkLayer(dest, "./L_ECR") == -1 )
return -1;
if ( !(unsigned int)genRemotePacketResponse((__int64)dest) || *(_DWORD *)&dest[4] == 19 )
{
v35 = 7;
writePrimPacketToStdOut(&v35, "ER");
if ( (unsigned int)sendPacketToInterface(&v35, (unsigned int)netToTrans_pipe) == -1 )
return -1;
}
else
{
sendPacketToDataLinkLayer(dest, "./L_LEC");
v35 = 3;
writePrimPacketToStdOut(&v35, "ER");
if ( (unsigned int)sendPacketToInterface(&v35, (unsigned int)netToTrans_pipe) == -1 )
return -1;
*(_BYTE *)(v23 + 9) = 1;
}
}
else
{
v35 = 7;
writePrimPacketToStdOut(&v35, "ER");
if ( (int)sendPacketToInterface(&v35, (unsigned int)netToTrans_pipe) < 0 )
return -1;
}
break;
}
}
return 0;
}

original_code:
int main(int argc, char** argv)
{
    int i=0, count = 0, flags,flag_response, length, response;
    char segmt[128], pr,ps;
    PRIM_PACKET p;
    PACKET packet, sndPacket;
    Connection* connection;
    netToTrans_pipe = atoi(argv[1]); transToNet_pipe = atoi(argv[2]);
    if (0) printf("NETWORK:\nMes fd sont:\n%i,%i\n",transToNet_pipe,netToTrans_pipe);
    flags = fcntl(transToNet_pipe,3,0);
    fcntl(transToNet_pipe,4, flags | 04000);
    flags = fcntl(netToTrans_pipe,3,0);
    fcntl(netToTrans_pipe,4, flags | 04000);
    while (getPacketFromInterface(&p,transToNet_pipe) > -1) {
        switch(p.prim)
        {
            case N_CONNECT_req:
                if (((int)p.con_prim_packet.src_addr)%27 == 0) {
                    p.prim = N_DISCONNECT_ind;
                    writePrimPacketToStdOut(&p,"ER");
                    if(sendPacketToInterface(&p,netToTrans_pipe) < 0)
                        return -1;
                    break;
                }
                connection = add_connection(p.con_prim_packet.con_number,&p.con_prim_packet.src_addr,&p.con_prim_packet.dest_addr);
                packet.packet_type = 0;
                packet.con_packet.con_packet_type = CON_req;
                packet.con_packet.con_number = p.con_prim_packet.con_number;
                packet.con_packet.src_addr = p.con_prim_packet.src_addr;
                packet.con_packet.dest_addr = p.con_prim_packet.dest_addr;
                if (sendPacketToDataLinkLayer(&packet,"./L_ECR") == -1)
                    return -1;
                flag_response = genRemotePacketResponse(&packet);
                if (!flag_response || packet.con_packet.con_packet_type == REL_ind) {
                    p.prim = N_DISCONNECT_ind;
                    writePrimPacketToStdOut(&p,"ER");
                    if(sendPacketToInterface(&p,netToTrans_pipe) == -1)
                        return -1;
                    break;
                }
                sendPacketToDataLinkLayer(&packet,"./L_LEC");
                p.prim = N_CONNECT_conf;
                writePrimPacketToStdOut(&p,"ER");
                if(sendPacketToInterface(&p,netToTrans_pipe) == -1)
                    return -1;
                connection->ncon.state = 0x01;
                break;
            case N_DATA_req:
                pr=0x01, ps=0x00;
                length = (int) strlen(p.data_prim_packet.transaction);
                for (i = 0; i < length; i+=128) {
                    packet.packet_type = 1;
                    if (i+128 < length)
                        packet.data_packet.type = ((pr << 5) + (ps << 1)) | 0x10;
                    else
                        packet.data_packet.type = (pr << 5) + (ps << 1);
                    packet.data_packet.con_number = p.data_prim_packet.con_number;
                    strncpy(packet.data_packet.segm_data,p.data_prim_packet.transaction,128);
                    sendPacketToDataLinkLayer(&packet,"./L_ECR");
                    sndPacket = packet;
                    if ((response = genRemotePacketResponse(&sndPacket)) <= 0) {
                        if (response < 0)
                            sendPacketToDataLinkLayer(&sndPacket,"./L_LEC");
                        sendPacketToDataLinkLayer(&packet,"./L_ECR");
                        if(genRemotePacketResponse(&packet)) {
                            sendPacketToDataLinkLayer(&packet,"./L_LEC");
                        }
                    }
                    else
                        sendPacketToDataLinkLayer(&sndPacket,"./L_LEC");
                    ps = pr;
                    pr = (((ps+0x01) << 5) >> 5);
                }
                break;
            case N_DISCONNECT_req:
                connection = findConnection(p.rel_prim_packet.con_number);
                packet.packet_type = 2;
                packet.rel_packet.type = 0x13;
                packet.rel_packet.con_number = p.rel_prim_packet.con_number;
                packet.rel_packet.src_addr = connection->ncon.src_addr;
                packet.rel_packet.dest_addr = connection->ncon.dest_addr;
                sendPacketToDataLinkLayer(&packet,"./L_ECR");
                remove_connection(p.rel_prim_packet.con_number);
                break;
        }
    }
    return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
    int i = 0; int count = 0; int flags; int flag_response; int length; int response;
    char segmt[128]; char pr; char ps;
    union PRIM_PACKET p;
    union PACKET packet; union PACKET sndPacket;
    union _Connection *connection;
    netToTrans_pipe = atoi(argv[1]); transToNet_pipe = atoi(argv[2]);
    if (0) printf("NETWORK:\nMes fd sont:\n%i,%i\n",transToNet_pipe,netToTrans_pipe);
    flags = fcntl(transToNet_pipe,3,0);
    fcntl(transToNet_pipe,4, flags | 04000);
    flags = fcntl(netToTrans_pipe,3,0);
    fcntl(netToTrans_pipe,4, flags | 04000);
    while (getPacketFromInterface(&p,transToNet_pipe) > -1) {
        switch(p.prim)
        {
            case N_CONNECT_req:
                if (((int)p.con_prim_packet.src_addr)%27 == 0) {
                    p.prim = N_DISCONNECT_ind;
                    writePrimPacketToStdOut(&p,"ER");
                    if(sendPacketToInterface(&p,netToTrans_pipe) < 0)
                        return -1;
                    break;
                }
                connection = add_connection(p.con_prim_packet.con_number,&p.con_prim_packet.src_addr,&p.con_prim_packet.dest_addr);
                packet.packet_type = 0;
                packet.con_packet.con_packet_type = CON_req;
                packet.con_packet.con_number = p.con_prim_packet.con_number;
                packet.con_packet.src_addr = p.con_prim_packet.src_addr;
                packet.con_packet.dest_addr = p.con_prim_packet.dest_addr;
                if (sendPacketToDataLinkLayer(&packet,"./L_ECR") == -1)
                    return -1;
                flag_response = genRemotePacketResponse(&packet);
                if (!flag_response || packet.con_packet.con_packet_type == REL_ind) {
                    p.prim = N_DISCONNECT_ind;
                    writePrimPacketToStdOut(&p,"ER");
                    if(sendPacketToInterface(&p,netToTrans_pipe) == -1)
                        return -1;
                    break;
                }
                sendPacketToDataLinkLayer(&packet,"./L_LEC");
                p.prim = N_CONNECT_conf;
                writePrimPacketToStdOut(&p,"ER");
                if(sendPacketToInterface(&p,netToTrans_pipe) == -1)
                    return -1;
                connection->ncon.state = 0x01;
                break;
            case N_DATA_req:
                pr=0x01, ps=0x00;
                length = (int) strlen(p.data_prim_packet.transaction);
                for (i = 0; i < length; i+=128) {
                    packet.packet_type = 1;
                    if (i+128 < length)
                        packet.data_packet.type = ((pr << 5) + (ps << 1)) | 0x10;
                    else
                        packet.data_packet.type = (pr << 5) + (ps << 1);
                    packet.data_packet.con_number = p.data_prim_packet.con_number;
                    strncpy(packet.data_packet.segm_data,p.data_prim_packet.transaction,128);
                    sendPacketToDataLinkLayer(&packet,"./L_ECR");
                    sndPacket = packet;
                    if ((response = genRemotePacketResponse(&sndPacket)) <= 0) {
                        if (response < 0)
                            sendPacketToDataLinkLayer(&sndPacket,"./L_LEC");
                        sendPacketToDataLinkLayer(&packet,"./L_ECR");
                        if(genRemotePacketResponse(&packet)) {
                            sendPacketToDataLinkLayer(&packet,"./L_LEC");
                        }
                    }
                    else
                        sendPacketToDataLinkLayer(&sndPacket,"./L_LEC");
                    ps = pr;
                    pr = (((ps+0x01) << 5) >> 5);
                }
                break;
            case N_DISCONNECT_req:
                connection = findConnection(p.rel_prim_packet.con_number);
                packet.packet_type = 2;
                packet.rel_packet.type = 0x13;
                packet.rel_packet.con_number = p.rel_prim_packet.con_number;
                packet.rel_packet.src_addr = connection->ncon.src_addr;
                packet.rel_packet.dest_addr = connection->ncon.dest_addr;
                sendPacketToDataLinkLayer(&packet,"./L_ECR");
                remove_connection(p.rel_prim_packet.con_number);
                break;
        }
    }
    return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: i int

variable_types: count int

variable_types: flags int

variable_types: length int

variable_types: response int

variable_types:
segmt
char [128]

variable_types: pr char

variable_types: ps char

variable_types: union PRIM_PACKET { enum PRIMITIVE { N_CONNECT_req=0, N_CONNECT_ind=1, N_CONNECT_resp=2, N_CONNECT_conf=3, N_DATA_req=4, N_DATA_ind=5, N_DISCONNECT_req=6, N_DISCONNECT_ind=7 } prim; struct _CON_PRIM_PACKET { enum PRIMITIVE { N_CONNECT_req=0, N_CONNECT_ind=1, N_CONNECT_resp=2, N_CONNECT_conf=3, N_DATA_req=4, N_DATA_ind=5, N_DISCONNECT_req=6, N_DISCONNECT_ind=7 } prim; char con_number; char src_addr; char dest_addr; } con_prim_packet; struct _DATA_PRIM_PACKET { enum PRIMITIVE { N_CONNECT_req=0, N_CONNECT_ind=1, N_CONNECT_resp=2, N_CONNECT_conf=3, N_DATA_req=4, N_DATA_ind=5, N_DISCONNECT_req=6, N_DISCONNECT_ind=7 } prim; char con_number; char transaction[256]; } data_prim_packet; struct _REL_PRIM_PACKET { enum PRIMITIVE { N_CONNECT_req=0, N_CONNECT_ind=1, N_CONNECT_resp=2, N_CONNECT_conf=3, N_DATA_req=4, N_DATA_ind=5, N_DISCONNECT_req=6, N_DISCONNECT_ind=7 } prim; char con_number; } rel_prim_packet; }

variable_types: union PACKET { int packet_type; struct _CONNECTION_PACKET { int packet_type; enum CONNECTION_PACKET_TYPE { CON_req=11, CON_conf=15, REL_ind=19 } con_packet_type; char con_number; char src_addr; char dest_addr; enum REL_REASON { REMOTE_DENY=1, NET_DENY=2 } reason; } con_packet; struct _DATA_PACKET { int packet_type; char type; char con_number; char segm_data[128]; } data_packet; struct _RELEASE_PACKET { int packet_type; char type; char con_number; char src_addr; char dest_addr; } rel_packet; }

variable_types: union _Connection { struct _TRANS_CON { union _Connection *next; char con_number; char state; } tcon; struct _NET_CON { union _Connection *next; char con_number; char state; char src_addr; char dest_addr; } ncon; } *

user_defined_types: union PRIM_PACKET { enum PRIMITIVE prim; struct _CON_PRIM_PACKET con_prim_packet; struct _DATA_PRIM_PACKET data_prim_packet; struct _REL_PRIM_PACKET rel_prim_packet; }

user_defined_types: struct _CON_PRIM_PACKET { enum PRIMITIVE prim; char con_number; char src_addr; char dest_addr; }

user_defined_types: struct _DATA_PRIM_PACKET { enum PRIMITIVE prim; char con_number; char transaction[256]; }

user_defined_types: struct _REL_PRIM_PACKET { enum PRIMITIVE prim; char con_number; }

user_defined_types: union _Connection { struct _TRANS_CON tcon; struct _NET_CON ncon; }


getMessageFromBuffer

original_code:
int getMessageFromBuffer(char buffer[], char message[])
{
    int i=0,j;
    for (i = 0; i < 254 ; i++) {
        if (buffer[i] == '\\') {
            break;
        }
    }
    for (j = 0; j < 255 - i; j++) {
        message[j] = buffer[i+j+1];
    }
    return j;
}

canonical_original_code:
int getMessageFromBuffer(char buffer[], char message[])
{
    int i = 0; int j;
    for (i = 0; i < 254 ; i++) {
        if (buffer[i] == '\\') {
            break;
        }
    }
    for (j = 0; j < 255 - i; j++) {
        message[j] = buffer[i+j+1];
    }
    return j;
}

variable_types:
buffer
char []

variable_types:
message
char []

variable_types: j int


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12
__pid_t v4; // eax
__pid_t v5; // eax
__m128i **v7; // rax
__m128i v8; // xmm0
__m128i **v9; // r12
__m128i *v10; // rax
char **v11; // r12
int fd; // [rsp+0h] [rbp-18h] BYREF
int v13; // [rsp+4h] [rbp-14h]
int pipedes[2]; // [rsp+8h] [rbp-10h] BYREF

if ( pipe(&fd) == -1 || (v3 = pipe(pipedes)) != 0 )
{
v3 = -1;
fwrite("Probleme lors de la creation d'un tuyau!\n", 1uLL, 0x29uLL, stderr);
}
else
{
v4 = fork();
if ( v4 == -1 )
{
v3 = -1;
fwrite("Impossible de creer un processus Entite Transport..\n", 1uLL, 0x34uLL, stderr);
}
else
{
if ( !v4 )
{
close(fd);
close(pipedes[1]);
v11 = (char **)makeArgArray(4LL, 18LL);
strcpy(*v11, "./transport-entity");
sprintf(v11[1], "%i", (unsigned int)v13);
sprintf(v11[2], "%i", (unsigned int)pipedes[0]);
execv("./transport-entity", v11);
exit(1);
}
sleep(1u);
v5 = fork();
if ( v5 == -1 )
{
v3 = -1;
fwrite("Impossible de creer un processus Entite Reseau..\n", 1uLL, 0x31uLL, stderr);
}
else
{
if ( !v5 )
{
close(pipedes[0]);
close(v13);
v7 = (__m128i **)makeArgArray(4LL, 16LL);
v8 = _mm_load_si128((const __m128i *)&xmmword_4020D0);
v9 = v7;
v10 = *v7;
v10[1].m128i_i8[0] = 0;
*v10 = v8;
sprintf(v9[1]->m128i_i8, "%i", (unsigned int)pipedes[1]);
sprintf(v9[2]->m128i_i8, "%i", (unsigned int)fd);
execv("./network-entity", (char *const *)v9);
exit(1);
}
close(fd);
close(v13);
close(pipedes[0]);
close(pipedes[1]);
}
}
}
return v3;
}

original_code:
int main()
{
    char** argv;
    int transToNet_pipe[2], netToTrans_pipe[2],i;
    if (pipe(transToNet_pipe) == -1)
    {
        fprintf(stderr,"Probleme lors de la creation d'un tuyau!\n");
        return -1;
    }
    if (pipe(netToTrans_pipe)) {
        fprintf(stderr,"Probleme lors de la creation d'un tuyau!\n");
        return -1;
    }
    if (0) printf("MAIN:\nLes fd sont:\n(%i,%i),(%i,%i)",transToNet_pipe[0],transToNet_pipe[1],netToTrans_pipe[0],netToTrans_pipe[1]);
    pid_t pid = fork();
    if (pid == -1)
    {
        fprintf(stderr,"Impossible de creer un processus Entite Transport..\n");
        return -1;
    }
    else if (pid == 0) {
        close(transToNet_pipe[0]);
        close(netToTrans_pipe[1]);
        argv = makeArgArray(4,18);
        strcpy(argv[0],"./transport-entity");
        sprintf(argv[1],"%i",transToNet_pipe[1]);
        sprintf(argv[2],"%i",netToTrans_pipe[0]);
        execv("./transport-entity",argv);
        exit(1);
    }
    sleep(1);
    pid = fork();
    if (pid == -1)
    {
        fprintf(stderr,"Impossible de creer un processus Entite Reseau..\n");
        return -1;
    }
    else if (pid == 0) {
        close(netToTrans_pipe[0]);
        close(transToNet_pipe[1]);
        argv = makeArgArray(4,16);
        strcpy(argv[0],"./network-entity");
        sprintf(argv[1],"%i",netToTrans_pipe[1]);
        sprintf(argv[2],"%i",transToNet_pipe[0]);
        execv("./network-entity",argv);
        exit(1);
    }
    for (i = 0; i < 2; i++) close(transToNet_pipe[i%2]);
    for (i = 0; i < 2; i++) close(netToTrans_pipe[i%2]);
    return 0;
}

canonical_original_code:
int main()
{
    char **argv;
    int transToNet_pipe[2]; int netToTrans_pipe[2]; int i;
    if (pipe(transToNet_pipe) == -1)
    {
        fprintf(stderr,"Probleme lors de la creation d'un tuyau!\n");
        return -1;
    }
    if (pipe(netToTrans_pipe)) {
        fprintf(stderr,"Probleme lors de la creation d'un tuyau!\n");
        return -1;
    }
    if (0) printf("MAIN:\nLes fd sont:\n(%i,%i),(%i,%i)",transToNet_pipe[0],transToNet_pipe[1],netToTrans_pipe[0],netToTrans_pipe[1]);
    int pid = fork();
    if (pid == -1)
    {
        fprintf(stderr,"Impossible de creer un processus Entite Transport..\n");
        return -1;
    }
    else if (pid == 0) {
        close(transToNet_pipe[0]);
        close(netToTrans_pipe[1]);
        argv = makeArgArray(4,18);
        strcpy(argv[0],"./transport-entity");
        sprintf(argv[1],"%i",transToNet_pipe[1]);
        sprintf(argv[2],"%i",netToTrans_pipe[0]);
        execv("./transport-entity",argv);
        exit(1);
    }
    sleep(1);
    pid = fork();
    if (pid == -1)
    {
        fprintf(stderr,"Impossible de creer un processus Entite Reseau..\n");
        return -1;
    }
    else if (pid == 0) {
        close(netToTrans_pipe[0]);
        close(transToNet_pipe[1]);
        argv = makeArgArray(4,16);
        strcpy(argv[0],"./network-entity");
        sprintf(argv[1],"%i",netToTrans_pipe[1]);
        sprintf(argv[2],"%i",transToNet_pipe[0]);
        execv("./network-entity",argv);
        exit(1);
    }
    for (i = 0; i < 2; i++) close(transToNet_pipe[i%2]);
    for (i = 0; i < 2; i++) close(netToTrans_pipe[i%2]);
    return 0;
}

variable_types: pid int


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

if ( !a1 )
return 0xFFFFFFFFLL;
if ( *(_DWORD *)(a1 + 104) )
return 0xFFFFFFFFLL;
sem_wait(*(sem_t **)(a1 + 96));
result = *(unsigned int *)(a1 + 104);
if ( (_DWORD)result )
{
sem_post(*(sem_t **)(a1 + 96));
result = 0xFFFFFFFFLL;
}
return result;
}

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

if ( !a1 )
return 0xFFFFFFFFLL;
if ( *(_DWORD *)(a1 + 104) )
return 0xFFFFFFFFLL;
sem_wait(*(sem_t **)(a1 + 96));
result = *(unsigned int *)(a1 + 104);
if ( (_DWORD)result )
{
sem_post(*(sem_t **)(a1 + 96));
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int wait_for_connection(connection *con)
{
    if (!con || con->flagged_deleted)
        return -1;
    sem_wait(con->sem);
    if (!con) {
        return -1;
    }
    else if (con->flagged_deleted) {
        sem_post(con->sem);
        return -1;
    }
    return 0;
}

canonical_original_code:
int wait_for_connection(struct _connection *con)
{
    if (!con || con->flagged_deleted)
        return -1;
    sem_wait(con->sem);
    if (!con) {
        return -1;
    }
    else if (con->flagged_deleted) {
        sem_post(con->sem);
        return -1;
    }
    return 0;
}

variable_types: struct _connection { char id[32]; char channel_id[32]; int sockfd; 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]; } addr; unsigned long tid; union sem_t { char __size[32]; long __align; } *sem; int flagged_deleted; struct _connection *next; struct _connection *prev; } *

user_defined_types: struct _connection { char id[32]; char channel_id[32]; int sockfd; struct sockaddr_in addr; unsigned long tid; union sem_t *sem; int flagged_deleted; struct _connection *next; struct _connection *prev; }

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


decompiled_code:
int __fastcall find_connection(char *s1, char **a2)
{
char *v2; // rbx
int result; // eax

v2 = first_con;
if ( !first_con )
return -1;
while ( 1 )
{
result = strcmp(s1, v2);
if ( !result )
break;
v2 = (char *)*((_QWORD *)v2 + 14);
if ( !v2 )
return -1;
}
if ( a2 )
*a2 = v2;
return result;
}

canonical_decompiled_code:
int __fastcall func1(char *s1, char **a2)
{
char *v2; // rbx
int result; // eax

v2 = first_con;
if ( !first_con )
return -1;
while ( 1 )
{
result = strcmp(s1, v2);
if ( !result )
break;
v2 = (char *)*((_QWORD *)v2 + 14);
if ( !v2 )
return -1;
}
if ( a2 )
*a2 = v2;
return result;
}

original_code:
int find_connection(char id[], connection **con)
{
    int equals = 0;
    connection *cur = first_con;
    while (cur) {
        if (!strcmp(id, cur->id)) {
            if (con)
                *con = cur;
            return 0;
        }
        cur = cur->next;
    }
    return -1;
}

canonical_original_code:
int find_connection(char id[], struct _connection **con)
{
    int equals = 0;
    struct _connection *cur = first_con;
    while (cur) {
        if (!strcmp(id, cur->id)) {
            if (con)
                *con = cur;
            return 0;
        }
        cur = cur->next;
    }
    return -1;
}

variable_types:
id
char []

variable_types: struct _connection { char id[32]; char channel_id[32]; int sockfd; 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]; } addr; unsigned long tid; union sem_t { char __size[32]; long __align; } *sem; int flagged_deleted; struct _connection *next; struct _connection *prev; } **

variable_types: equals int


decompiled_code:
char *__fastcall add_connection(char *src, int a2, unsigned __int64 a3, __int64 a4, __int64 a5)
{
unsigned __int64 v5; // r13
__int64 v7; // r14
char *v8; // r12
sem_t *v9; // r8
sem_t *v10; // rdi
void *v12; // rdi

v5 = HIDWORD(a3);
if ( !find_connection(src, 0LL) )
return 0LL;
v7 = last_con;
v8 = (char *)malloc(0x80uLL);
if ( !v8 )
return 0LL;
v9 = (sem_t *)malloc(0x20uLL);
memset(v8, 0, 0x80uLL);
*((_DWORD *)v8 + 16) = a2;
*(_QWORD *)(v8 + 68) = a3;
*(_QWORD *)(v8 + 76) = a4;
*((_QWORD *)v8 + 12) = v9;
*((_QWORD *)v8 + 11) = a5;
if ( sem_init(v9, 0, 1u) )
{
v12 = v8;
v8 = 0LL;
free(v12);
}
else
{
strcpy(v8, src);
strcpy(v8 + 32, "lobby");
printf(
"inf1010tp2-server: nouvelle connexion [id=%s,ip=%u.%u.%u.%u]\n",
src,
(unsigned __int8)v5,
BYTE1(v5),
(_DWORD)v5 << 8 >> 24,
BYTE3(v5));
sem_wait(cons_sem);
if ( __PAIR128__((unsigned __int64)first_con, last_con) == 0 )
{
last_con = (__int64)v8;
first_con = v8;
sem_post(cons_sem);
}
else
{
while ( 2 )
{
sem_post(cons_sem);
while ( 1 )
{
sem_wait(*(sem_t **)(v7 + 96));
if ( last_con == v7 )
{
*(_QWORD *)(v7 + 112) = v8;
v10 = *(sem_t **)(v7 + 96);
*((_QWORD *)v8 + 15) = v7;
last_con = (__int64)v8;
sem_post(v10);
return v8;
}
if ( !last_con )
break;
sem_post(*(sem_t **)(v7 + 96));
v7 = last_con;
}
sem_wait(cons_sem);
v7 = last_con;
if ( last_con )
continue;
break;
}
last_con = (__int64)v8;
first_con = v8;
}
}
return v8;
}

canonical_decompiled_code:
char *__fastcall func2(char *src, int a2, unsigned __int64 a3, __int64 a4, __int64 a5)
{
unsigned __int64 v5; // r13
__int64 v7; // r14
char *v8; // r12
sem_t *v9; // r8
sem_t *v10; // rdi
void *v12; // rdi

v5 = HIDWORD(a3);
if ( !func1(src, 0LL) )
return 0LL;
v7 = last_con;
v8 = (char *)malloc(0x80uLL);
if ( !v8 )
return 0LL;
v9 = (sem_t *)malloc(0x20uLL);
memset(v8, 0, 0x80uLL);
*((_DWORD *)v8 + 16) = a2;
*(_QWORD *)(v8 + 68) = a3;
*(_QWORD *)(v8 + 76) = a4;
*((_QWORD *)v8 + 12) = v9;
*((_QWORD *)v8 + 11) = a5;
if ( sem_init(v9, 0, 1u) )
{
v12 = v8;
v8 = 0LL;
free(v12);
}
else
{
strcpy(v8, src);
strcpy(v8 + 32, "lobby");
printf(
"inf1010tp2-server: nouvelle connexion [id=%s,ip=%u.%u.%u.%u]\n",
src,
(unsigned __int8)v5,
BYTE1(v5),
(_DWORD)v5 << 8 >> 24,
BYTE3(v5));
sem_wait(cons_sem);
if ( __PAIR128__((unsigned __int64)first_con, last_con) == 0 )
{
last_con = (__int64)v8;
first_con = v8;
sem_post(cons_sem);
}
else
{
while ( 2 )
{
sem_post(cons_sem);
while ( 1 )
{
sem_wait(*(sem_t **)(v7 + 96));
if ( last_con == v7 )
{
*(_QWORD *)(v7 + 112) = v8;
v10 = *(sem_t **)(v7 + 96);
*((_QWORD *)v8 + 15) = v7;
last_con = (__int64)v8;
sem_post(v10);
return v8;
}
if ( !last_con )
break;
sem_post(*(sem_t **)(v7 + 96));
v7 = last_con;
}
sem_wait(cons_sem);
v7 = last_con;
if ( last_con )
continue;
break;
}
last_con = (__int64)v8;
first_con = v8;
}
}
return v8;
}

original_code:
connection* add_connection(char id[], int sockfd, struct sockaddr_in addr , pthread_t tid)
{
    if (!find_connection(id, ((void *)0)))
        return ((void *)0);
    connection *new_con, *last = last_con;
    if (!(new_con = malloc(sizeof(connection))))
        return ((void *)0);
    *new_con = (connection) {
        .sockfd = sockfd,
        .addr = addr,
        .tid = tid,
        .flagged_deleted = 0,
        .sem = malloc(sizeof(sem_t)),
        .next = ((void *)0),
        .prev = ((void *)0)
    };
    if(sem_init(new_con->sem, 0, 1)) {
        free(new_con);
        return ((void *)0);
    }
    strcpy(new_con->id, id);
    strcpy(new_con->channel_id, "lobby");
    printf("inf1010tp2-server: nouvelle connexion [id=%s,ip=%u.%u.%u.%u]\n", id,
                    (addr.sin_addr.s_addr<<24)>>24,
                    (addr.sin_addr.s_addr<<16)>>24,
                    (addr.sin_addr.s_addr<<8)>>24,
                    addr.sin_addr.s_addr>>24
      );
    sem_wait(cons_sem);
    if (!first_con && !last_con) {
        first_con = last_con = new_con;
        sem_post(cons_sem);
        return new_con;
    }
    sem_post(cons_sem);
    while (1) {
        sem_wait(last->sem);
        if (last == last_con) {
            last->next = new_con;
            new_con->prev = last;
            last_con = new_con;
            sem_post(last->sem);
            return new_con;
        }
        else if (!last_con) {
            sem_wait(cons_sem);
            if (!last_con) {
                first_con = last_con = new_con;
                return new_con;
            }
            else
                last = last_con;
            sem_post(cons_sem);
        }
        else {
            if (last)
                sem_post(last->sem);
            last = last_con;
        }
    }
}

canonical_original_code:
struct _connection *add_connection(char id[], int sockfd, struct sockaddr_in addr, unsigned long tid)
{
    if (!find_connection(id, ((void *)0)))
        return ((void *)0);
    struct _connection *new_con; struct _connection *last = last_con;
    if (!(new_con = malloc(sizeof(connection))))
        return ((void *)0);
    *new_con = (struct _connection) {
        .sockfd = sockfd,
        .addr = addr,
        .tid = tid,
        .flagged_deleted = 0,
        .sem = malloc(sizeof(sem_t)),
        .next = ((void *)0),
        .prev = ((void *)0)
    };
    if(sem_init(new_con->sem, 0, 1)) {
        free(new_con);
        return ((void *)0);
    }
    strcpy(new_con->id, id);
    strcpy(new_con->channel_id, "lobby");
    printf("inf1010tp2-server: nouvelle connexion [id=%s,ip=%u.%u.%u.%u]\n", id,
                    (addr.sin_addr.s_addr<<24)>>24,
                    (addr.sin_addr.s_addr<<16)>>24,
                    (addr.sin_addr.s_addr<<8)>>24,
                    addr.sin_addr.s_addr>>24
      );
    sem_wait(cons_sem);
    if (!first_con && !last_con) {
        first_con = last_con = new_con;
        sem_post(cons_sem);
        return new_con;
    }
    sem_post(cons_sem);
    while (1) {
        sem_wait(last->sem);
        if (last == last_con) {
            last->next = new_con;
            new_con->prev = last;
            last_con = new_con;
            sem_post(last->sem);
            return new_con;
        }
        else if (!last_con) {
            sem_wait(cons_sem);
            if (!last_con) {
                first_con = last_con = new_con;
                return new_con;
            }
            else
                last = last_con;
            sem_post(cons_sem);
        }
        else {
            if (last)
                sem_post(last->sem);
            last = last_con;
        }
    }
}

variable_types: sockfd int

variable_types:
addr
struct sockaddr_in

variable_types:
tid
unsigned long

return_type: struct _connection { char id[32]; char channel_id[32]; int sockfd; 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]; } addr; unsigned long tid; union sem_t { char __size[32]; long __align; } *sem; int flagged_deleted; struct _connection *next; struct _connection *prev; } *


decompiled_code:
__int64 __fastcall remove_connection(char *s1)
{
char *v1; // r13
unsigned int v2; // er12
__int64 v3; // rdi
void *v4; // rax
__int64 v5; // rcx
__int64 v6; // rdx
sem_t *v8; // rdi
__int64 v9; // rax
sem_t *v10; // rdi
__int64 v11; // rax
sem_t *v12; // rdi
void *ptr; // [rsp+8h] [rbp-20h] BYREF

v1 = first_con;
if ( !first_con || !last_con )
return (unsigned int)-1;
if ( first_con == (char *)last_con )
{
v2 = strcmp(first_con, s1);
if ( !v2 )
{
printf(
aInf1010tp2Serv,
v1,
(unsigned __int8)*((_DWORD *)v1 + 18),
(unsigned __int8)BYTE1(*((_DWORD *)v1 + 18)),
*((_DWORD *)v1 + 18) << 8 >> 24,
(unsigned __int64)*((unsigned int *)v1 + 18) >> 24);
sem_wait(cons_sem);
v8 = cons_sem;
*((_DWORD *)first_con + 26) = 1;
sem_post(v8);
sem_wait(cons_sem);
free(first_con);
last_con = 0LL;
first_con = 0LL;
return v2;
}
}
v2 = find_connection(s1, (char **)&ptr);
if ( v2 )
return (unsigned int)-1;
printf(
aInf1010tp2Serv,
ptr,
(unsigned __int8)*((_DWORD *)ptr + 18),
(unsigned __int8)BYTE1(*((_DWORD *)ptr + 18)),
*((_DWORD *)ptr + 18) << 8 >> 24,
(unsigned __int64)*((unsigned int *)ptr + 18) >> 24);
if ( !(unsigned int)wait_for_connection((__int64)ptr) )
{
if ( ptr == first_con )
{
wait_for_connection(*((_QWORD *)ptr + 14));
v11 = *((_QWORD *)ptr + 14);
*(_QWORD *)(v11 + 120) = 0LL;
v12 = *(sem_t **)(v11 + 96);
first_con = (char *)v11;
sem_post(v12);
v4 = ptr;
}
else
{
v3 = *((_QWORD *)ptr + 15);
if ( ptr == (void *)last_con )
{
wait_for_connection(v3);
v9 = *((_QWORD *)ptr + 15);
*(_QWORD *)(v9 + 112) = 0LL;
v10 = *(sem_t **)(v9 + 96);
last_con = v9;
sem_post(v10);
v4 = ptr;
}
else
{
wait_for_connection(v3);
wait_for_connection(*((_QWORD *)ptr + 14));
v4 = ptr;
v5 = *((_QWORD *)ptr + 15);
v6 = *((_QWORD *)ptr + 14);
*(_QWORD *)(v5 + 112) = v6;
*(_QWORD *)(v6 + 120) = v5;
}
}
*((_DWORD *)v4 + 26) = 1;
v2 = 0;
sem_post(*((sem_t **)v4 + 12));
sem_wait(*((sem_t **)ptr + 12));
free(*((void **)ptr + 12));
free(ptr);
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s1)
{
char *v1; // r13
unsigned int v2; // er12
__int64 v3; // rdi
void *v4; // rax
__int64 v5; // rcx
__int64 v6; // rdx
sem_t *v8; // rdi
__int64 v9; // rax
sem_t *v10; // rdi
__int64 v11; // rax
sem_t *v12; // rdi
void *ptr; // [rsp+8h] [rbp-20h] BYREF

v1 = first_con;
if ( !first_con || !last_con )
return (unsigned int)-1;
if ( first_con == (char *)last_con )
{
v2 = strcmp(first_con, s1);
if ( !v2 )
{
printf(
aInf1010tp2Serv,
v1,
(unsigned __int8)*((_DWORD *)v1 + 18),
(unsigned __int8)BYTE1(*((_DWORD *)v1 + 18)),
*((_DWORD *)v1 + 18) << 8 >> 24,
(unsigned __int64)*((unsigned int *)v1 + 18) >> 24);
sem_wait(cons_sem);
v8 = cons_sem;
*((_DWORD *)first_con + 26) = 1;
sem_post(v8);
sem_wait(cons_sem);
free(first_con);
last_con = 0LL;
first_con = 0LL;
return v2;
}
}
v2 = func1(s1, (char **)&ptr);
if ( v2 )
return (unsigned int)-1;
printf(
aInf1010tp2Serv,
ptr,
(unsigned __int8)*((_DWORD *)ptr + 18),
(unsigned __int8)BYTE1(*((_DWORD *)ptr + 18)),
*((_DWORD *)ptr + 18) << 8 >> 24,
(unsigned __int64)*((unsigned int *)ptr + 18) >> 24);
if ( !(unsigned int)func0((__int64)ptr) )
{
if ( ptr == first_con )
{
func0(*((_QWORD *)ptr + 14));
v11 = *((_QWORD *)ptr + 14);
*(_QWORD *)(v11 + 120) = 0LL;
v12 = *(sem_t **)(v11 + 96);
first_con = (char *)v11;
sem_post(v12);
v4 = ptr;
}
else
{
v3 = *((_QWORD *)ptr + 15);
if ( ptr == (void *)last_con )
{
func0(v3);
v9 = *((_QWORD *)ptr + 15);
*(_QWORD *)(v9 + 112) = 0LL;
v10 = *(sem_t **)(v9 + 96);
last_con = v9;
sem_post(v10);
v4 = ptr;
}
else
{
func0(v3);
func0(*((_QWORD *)ptr + 14));
v4 = ptr;
v5 = *((_QWORD *)ptr + 15);
v6 = *((_QWORD *)ptr + 14);
*(_QWORD *)(v5 + 112) = v6;
*(_QWORD *)(v6 + 120) = v5;
}
}
*((_DWORD *)v4 + 26) = 1;
v2 = 0;
sem_post(*((sem_t **)v4 + 12));
sem_wait(*((sem_t **)ptr + 12));
free(*((void **)ptr + 12));
free(ptr);
}
return v2;
}

original_code:
int remove_connection(char id[])
{
    if (!first_con || !last_con) {
        return -1;
    }
    if (first_con == last_con && !strcmp(first_con->id, id)) {
        printf("inf1010tp2-server: déconnexion d'un client [id=%s,ip=%u.%u.%u.%u]\n", first_con->id,
                        (first_con->addr.sin_addr.s_addr<<24)>>24,
                        (first_con->addr.sin_addr.s_addr<<16)>>24,
                        (first_con->addr.sin_addr.s_addr<<8)>>24,
                         first_con->addr.sin_addr.s_addr>>24
          );
        sem_wait(cons_sem);
        first_con->flagged_deleted = 1;
        sem_post(cons_sem);
        sem_wait(cons_sem);
        free(first_con);
        first_con = last_con = ((void *)0);
        return 0;
    }
    connection *con;
    if (!find_connection(id, &con)) {
        printf("inf1010tp2-server: déconnexion d'un client [id=%s,ip=%u.%u.%u.%u]\n", con->id,
                        (con->addr.sin_addr.s_addr<<24)>>24,
                        (con->addr.sin_addr.s_addr<<16)>>24,
                        (con->addr.sin_addr.s_addr<<8)>>24,
                         con->addr.sin_addr.s_addr>>24
          );
        if (wait_for_connection(con))
            return 0;
        if (con == first_con) {
            wait_for_connection(con->next);
            con->next->prev = ((void *)0);
            first_con = con->next;
            sem_post(con->next->sem);
        }
        else if (con == last_con) {
            wait_for_connection(con->prev);
            con->prev->next = ((void *)0);
            last_con = con->prev;
            sem_post(con->prev->sem);
        }
        else {
            wait_for_connection(con->prev);
            wait_for_connection(con->next);
            con->prev->next = con->next;
            con->next->prev = con->prev;
        }
        con->flagged_deleted = 1;
        sem_post(con->sem);
        sem_wait(con->sem);
        free(con->sem);
        free(con);
        return 0;
    }
    return -1;
}

canonical_original_code:
int remove_connection(char id[])
{
    if (!first_con || !last_con) {
        return -1;
    }
    if (first_con == last_con && !strcmp(first_con->id, id)) {
        printf("inf1010tp2-server: déconnexion d'un client [id=%s,ip=%u.%u.%u.%u]\n", first_con->id,
                        (first_con->addr.sin_addr.s_addr<<24)>>24,
                        (first_con->addr.sin_addr.s_addr<<16)>>24,
                        (first_con->addr.sin_addr.s_addr<<8)>>24,
                         first_con->addr.sin_addr.s_addr>>24
          );
        sem_wait(cons_sem);
        first_con->flagged_deleted = 1;
        sem_post(cons_sem);
        sem_wait(cons_sem);
        free(first_con);
        first_con = last_con = ((void *)0);
        return 0;
    }
    struct _connection *con;
    if (!find_connection(id, &con)) {
        printf("inf1010tp2-server: déconnexion d'un client [id=%s,ip=%u.%u.%u.%u]\n", con->id,
                        (con->addr.sin_addr.s_addr<<24)>>24,
                        (con->addr.sin_addr.s_addr<<16)>>24,
                        (con->addr.sin_addr.s_addr<<8)>>24,
                         con->addr.sin_addr.s_addr>>24
          );
        if (wait_for_connection(con))
            return 0;
        if (con == first_con) {
            wait_for_connection(con->next);
            con->next->prev = ((void *)0);
            first_con = con->next;
            sem_post(con->next->sem);
        }
        else if (con == last_con) {
            wait_for_connection(con->prev);
            con->prev->next = ((void *)0);
            last_con = con->prev;
            sem_post(con->prev->sem);
        }
        else {
            wait_for_connection(con->prev);
            wait_for_connection(con->next);
            con->prev->next = con->next;
            con->next->prev = con->prev;
        }
        con->flagged_deleted = 1;
        sem_post(con->sem);
        sem_wait(con->sem);
        free(con->sem);
        free(con);
        return 0;
    }
    return -1;
}

user_defined_types: union sem_t { char __size[32]; long __align; }


decompiled_code:
void __noreturn handle_sig()
{
close(reception_socket_fd);
exit(0);
}

canonical_decompiled_code:
void __noreturn func1()
{
close(reception_socket_fd);
exit(0);
}

original_code:
void handle_sig()
{
    close(reception_socket_fd);
    exit(0);
}

return_type: void


decompiled_code:
int init_socket()
{
__int16 v0; // ax
sa_family_t v1; // dx
int v2; // er8
int result; // eax

reception_socket_fd = socket(2, 1, 0);
if ( reception_socket_fd <= 0 )
{
perror(s);
return -1;
}
v0 = _bswap_16(server_port);
srv_addr = 0LL;
srv_addr.sa_family = v1;
*(_WORD *)srv_addr.sa_data = v0;
result = bind(v2, &srv_addr, 0x10u);
if ( result )
{
perror(aErreurLorsDeLa);
return -1;
}
return result;
}

canonical_decompiled_code:
int func2()
{
__int16 v0; // ax
sa_family_t v1; // dx
int v2; // er8
int result; // eax

reception_socket_fd = socket(2, 1, 0);
if ( reception_socket_fd <= 0 )
{
perror(s);
return -1;
}
v0 = func0(server_port);
srv_addr = 0LL;
srv_addr.sa_family = v1;
*(_WORD *)srv_addr.sa_data = v0;
result = bind(v2, &srv_addr, 0x10u);
if ( result )
{
perror(aErreurLorsDeLa);
return -1;
}
return result;
}

original_code:
int init_socket()
{
    reception_socket_fd = socket(2, SOCK_STREAM, 0);
    if (reception_socket_fd <= 0) {
        perror("Erreur lors de l'obtention du socket de réception.");
        return -1;
    }
    srv_addr = (struct sockaddr_in) {
        2,
        htons(server_port),
        (struct in_addr) {((in_addr_t) 0x00000000)},
        0
    };
    if (bind(reception_socket_fd, (struct sockaddr *) &srv_addr, sizeof(srv_addr))) {
        perror("Erreur lors de la solicitation du socket. Socket déjà utilisé?");
        return -1;
    }
}

canonical_original_code:
int init_socket()
{
    reception_socket_fd = socket(2, SOCK_STREAM, 0);
    if (reception_socket_fd <= 0) {
        perror("Erreur lors de l'obtention du socket de réception.");
        return -1;
    }
    srv_addr = (struct sockaddr_in) {
        2,
        htons(server_port),
        (struct in_addr) {((unsigned int) 0x00000000)},
        0
    };
    if (bind(reception_socket_fd, (struct sockaddr *) &srv_addr, sizeof(srv_addr))) {
        perror("Erreur lors de la solicitation du socket. Socket déjà utilisé?");
        return -1;
    }
}

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


decompiled_code:
void __noreturn receive_connections()
{
int v0; // ebx
char *v1; // rax
__m128i v2; // xmm0
socklen_t addr_len; // [rsp+4h] [rbp-14h] BYREF
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

addr_len = 16;
if ( listen(reception_socket_fd, 5) )
{
perror(aErreurLorsDeLa_0);
exit(1);
}
cons_sem = malloc(0x20uLL);
if ( !cons_sem || sem_init(cons_sem, 0, 1u) )
{
fwrite("Impossible d'initialiser la liste de connexion..\n", 1uLL, 0x31uLL, stderr);
exit(1);
}
while ( 1 )
{
do
{
v0 = accept(reception_socket_fd, &cli_addr, &addr_len);
v1 = (char *)malloc(0x14uLL);
v2 = _mm_load_si128((const __m128i *)&cli_addr);
*(_DWORD *)v1 = v0;
*(__m128i *)(v1 + 4) = v2;
}
while ( !pthread_create(newthread, 0LL, handle_client_communication, v1) );
fprintf(
stderr,
format,
(unsigned __int8)*(_DWORD *)&cli_addr.sa_data[2],
(unsigned __int8)BYTE1(*(_DWORD *)&cli_addr.sa_data[2]),
(unsigned __int8)cli_addr.sa_data[4],
HIBYTE(*(_DWORD *)&cli_addr.sa_data[2]));
}
}

canonical_decompiled_code:
void __noreturn func3()
{
int v0; // ebx
char *v1; // rax
__m128i v2; // xmm0
socklen_t addr_len; // [rsp+4h] [rbp-14h] BYREF
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

addr_len = 16;
if ( listen(reception_socket_fd, 5) )
{
perror(aErreurLorsDeLa_0);
exit(1);
}
cons_sem = malloc(0x20uLL);
if ( !cons_sem || sem_init(cons_sem, 0, 1u) )
{
fwrite("Impossible d'initialiser la liste de connexion..\n", 1uLL, 0x31uLL, stderr);
exit(1);
}
while ( 1 )
{
do
{
v0 = accept(reception_socket_fd, &cli_addr, &addr_len);
v1 = (char *)malloc(0x14uLL);
v2 = _mm_load_si128((const __m128i *)&cli_addr);
*(_DWORD *)v1 = v0;
*(__m128i *)(v1 + 4) = v2;
}
while ( !pthread_create(newthread, 0LL, handle_client_communication, v1) );
fprintf(
stderr,
format,
(unsigned __int8)*(_DWORD *)&cli_addr.sa_data[2],
(unsigned __int8)BYTE1(*(_DWORD *)&cli_addr.sa_data[2]),
(unsigned __int8)cli_addr.sa_data[4],
HIBYTE(*(_DWORD *)&cli_addr.sa_data[2]));
}
}

original_code:
void receive_connections()
{
    socklen_t clilen = sizeof(struct sockaddr), sockfd;
    pthread_t tid;
    if (listen(reception_socket_fd, 5)) {
        perror("Erreur lors de la mise en écoute sur le socket.");
        exit(1);
    }
    cons_sem = malloc(sizeof(sem_t));
    if (!cons_sem || sem_init(cons_sem, 0, 1)) {
        fprintf(stderr, "Impossible d'initialiser la liste de connexion..\n");
        exit(1);
    }
    while (1) {
        sockfd = accept(reception_socket_fd, (struct sockaddr*) &cli_addr, &clilen);
        hcc_args *args = malloc(sizeof(hcc_args));
        *args = (hcc_args) {sockfd, cli_addr};
        if (pthread_create(&tid, ((void *)0), handle_client_communication, args))
            fprintf(stderr, "Impossible de créer un thread de connexion pour le client %u.%u.%u.%u...\n",
                    (cli_addr.sin_addr.s_addr<<24)>>24,
                    (cli_addr.sin_addr.s_addr<<16)>>24,
                    (cli_addr.sin_addr.s_addr<<8)>>24,
                    cli_addr.sin_addr.s_addr>>24
             );
    }
}

canonical_original_code:
void receive_connections()
{
    unsigned int clilen = sizeof(struct sockaddr); unsigned int sockfd;
    unsigned long tid;
    if (listen(reception_socket_fd, 5)) {
        perror("Erreur lors de la mise en écoute sur le socket.");
        exit(1);
    }
    cons_sem = malloc(sizeof(sem_t));
    if (!cons_sem || sem_init(cons_sem, 0, 1)) {
        fprintf(stderr, "Impossible d'initialiser la liste de connexion..\n");
        exit(1);
    }
    while (1) {
        sockfd = accept(reception_socket_fd, (struct sockaddr *) &cli_addr, &clilen);
        struct _hcc_args *args = malloc(sizeof(hcc_args));
        *args = (struct _hcc_args) {sockfd, cli_addr};
        if (pthread_create(&tid, ((void *)0), handle_client_communication, args))
            fprintf(stderr, "Impossible de créer un thread de connexion pour le client %u.%u.%u.%u...\n",
                    (cli_addr.sin_addr.s_addr<<24)>>24,
                    (cli_addr.sin_addr.s_addr<<16)>>24,
                    (cli_addr.sin_addr.s_addr<<8)>>24,
                    cli_addr.sin_addr.s_addr>>24
             );
    }
}

variable_types:
clilen
unsigned int

variable_types:
sockfd
unsigned int

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

user_defined_types: struct _hcc_args { int cli_socket; struct sockaddr_in cli_addr; }


decompiled_code:
__int64 __fastcall close_connection(__int64 a1, void *a2)
{
free(a2);
close(*(_DWORD *)(a1 + 64));
return remove_connection(a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, void *a2)
{
free(a2);
close(*(_DWORD *)(a1 + 64));
return remove_connection(a1);
}

original_code:
void close_connection(connection *con, hcc_args *args)
{
    free(args);
    close(con->sockfd);
    remove_connection(con->id);
}

canonical_original_code:
void close_connection(struct _connection *con, struct _hcc_args *args)
{
    free(args);
    close(con->sockfd);
    remove_connection(con->id);
}

variable_types: struct _hcc_args { int cli_socket; struct sockaddr_in cli_addr; } *


decompiled_code:
__int64 __fastcall recv_cli_packet(__int64 a1, void *a2)
{
int v2; // ebx
int v3; // eax

v2 = 5;
v3 = recv(*(_DWORD *)(a1 + 64), a2, 0x404uLL, 0);
while ( v3 <= 0 )
{
v3 = recv(*(_DWORD *)(a1 + 64), a2, 0x404uLL, 0);
if ( !--v2 )
return 0xFFFFFFFFLL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, void *a2)
{
int v2; // ebx
int v3; // eax

v2 = 5;
v3 = recv(*(_DWORD *)(a1 + 64), a2, 0x404uLL, 0);
while ( v3 <= 0 )
{
v3 = recv(*(_DWORD *)(a1 + 64), a2, 0x404uLL, 0);
if ( !--v2 )
return 0xFFFFFFFFLL;
}
return 0LL;
}

original_code:
int recv_cli_packet(connection *con, client_packet *packet)
{
    int n=0, nattempts=0;
    while (n<=0) {
        n = recv(con->sockfd, (void*)packet, sizeof(client_packet), 0);
        if (++nattempts > 5) {
            return -1;
        }
    }
    return 0;
}

canonical_original_code:
int recv_cli_packet(struct _connection *con, union client_packet *packet)
{
    int n = 0; int nattempts = 0;
    while (n<=0) {
        n = recv(con->sockfd, (void *)packet, sizeof(client_packet), 0);
        if (++nattempts > 5) {
            return -1;
        }
    }
    return 0;
}

variable_types: union client_packet { unsigned int type; struct _client_cmd { unsigned int type; int argc; char args[5][32]; char main_arg[256]; } cmd; struct _connection_info { unsigned int type; char id[32]; } con_info; struct _cli_text_msg { unsigned int type; char message[1024]; } msg; } *

variable_types: n int

variable_types: nattempts int

user_defined_types: union client_packet { unsigned int type; struct _client_cmd cmd; struct _connection_info con_info; struct _cli_text_msg msg; }


decompiled_code:
__int64 __fastcall send_srv_packet(__int64 a1, const void *a2)
{
int v2; // ebx
int v3; // eax

v2 = 5;
v3 = send(*(_DWORD *)(a1 + 64), a2, 0x428uLL, 0);
while ( v3 <= 0 )
{
v3 = send(*(_DWORD *)(a1 + 64), a2, 0x428uLL, 0);
if ( !--v2 )
return 0xFFFFFFFFLL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, const void *a2)
{
int v2; // ebx
int v3; // eax

v2 = 5;
v3 = send(*(_DWORD *)(a1 + 64), a2, 0x428uLL, 0);
while ( v3 <= 0 )
{
v3 = send(*(_DWORD *)(a1 + 64), a2, 0x428uLL, 0);
if ( !--v2 )
return 0xFFFFFFFFLL;
}
return 0LL;
}

original_code:
int send_srv_packet(connection *con, server_packet *packet)
{
    int n=0, nattempts=0;
    while (n<=0) {
        n = send(con->sockfd, (void*)packet, sizeof(server_packet), 0);
        if (++nattempts > 5) {
            return -1;
        }
    }
    return 0;
}

canonical_original_code:
int send_srv_packet(struct _connection *con, union server_packet *packet)
{
    int n = 0; int nattempts = 0;
    while (n<=0) {
        n = send(con->sockfd, (void *)packet, sizeof(server_packet), 0);
        if (++nattempts > 5) {
            return -1;
        }
    }
    return 0;
}

variable_types: union server_packet { unsigned int type; struct _srv_text_msg { unsigned int type; char from[32]; char priv; char message[1024]; } msg; } *

user_defined_types: union server_packet { unsigned int type; struct _srv_text_msg msg; }


decompiled_code:
void *__fastcall handle_client_communication(void *a1)
{
unsigned int v1; // er13
pthread_t v2; // rax
__int64 v3; // rbp
char *v4; // r13
char *v6; // r14
size_t v7; // rax
char *v8; // rax
char *v9; // r13
size_t v10; // rax
char *v11; // rax
size_t v12; // rax
__m128i *v13; // rax
__m128i v14; // [rsp+10h] [rbp-998h]
char *v15; // [rsp+28h] [rbp-980h] BYREF
char v16[256]; // [rsp+30h] [rbp-978h] BYREF
int buf; // [rsp+130h] [rbp-878h] BYREF
char src[4]; // [rsp+134h] [rbp-874h] BYREF
__int64 v19; // [rsp+138h] [rbp-870h]
__int16 v20; // [rsp+140h] [rbp-868h]
char v21; // [rsp+142h] [rbp-866h]
char v22[2]; // [rsp+158h] [rbp-850h] BYREF
char v23[872]; // [rsp+1D8h] [rbp-7D0h] BYREF
int v24[282]; // [rsp+540h] [rbp-468h] BYREF

v1 = *(_DWORD *)a1;
if ( recv(*(_DWORD *)a1, &buf, 0x404uLL, 0) <= 0 )
{
free(a1);
close(v1);
}
else
{
v2 = pthread_self();
v14 = _mm_loadu_si128((const __m128i *)((char *)a1 + 4));
v3 = add_connection(src, v1, v14.m128i_i64[0], v14.m128i_i64[1], v2);
if ( v3 )
{
memset(v24, 0, 0x428uLL);
if ( (unsigned int)send_srv_packet(v3, v24) )
{
close_connection(v3, a1);
close(v1);
return 0LL;
}
LABEL_4:
while ( 1 )
{
memset(v24, 0, 0x428uLL);
if ( (unsigned int)recv_cli_packet(v3, &buf) )
break;
if ( buf )
{
if ( buf != 2 )
continue;
v4 = first_con;
v15 = first_con;
if ( (_DWORD)v19 == 6779757 )
{
memset(v24, 0, 0x428uLL);
v24[0] = 1;
LOBYTE(v24[9]) = 1;
strcpy((char *)&v24[1], (const char *)v3);
strcpy((char *)&v24[9] + 1, v23);
if ( *(_WORD *)v22 == 45 )
{
while ( v4 )
{
if ( (char *)v3 != v4 )
send_srv_packet((__int64)v4, v24);
v4 = (char *)*((_QWORD *)v15 + 14);
v15 = v4;
}
}
else if ( !(unsigned int)find_connection(v22, &v15) )
{
send_srv_packet((__int64)v15, v24);
}
}
else
{
if ( (_DWORD)v19 == 1701667182 && WORD2(v19) == 115 )
{
v24[0] = 1;
*(_QWORD *)((char *)&v24[9] + 1) = 0LL;
*(_QWORD *)((char *)&v24[263] + 1) = 0LL;
memset(&v24[10], 0, 8LL * (((unsigned int)&v24[9] + 1 - (unsigned int)&v24[10] + 1024) >> 3));
for ( ; v4; v15 = v4 )
{
if ( !strcmp(v4 + 32, (const char *)(v3 + 32)) )
{
v7 = strlen((const char *)&v24[9] + 1);
v8 = stpcpy((char *)&v24[9] + v7 + 1, v4);
if ( !*((_QWORD *)v4 + 14) )
{
v15 = 0LL;
send_srv_packet(v3, v24);
goto LABEL_4;
}
*(_WORD *)v8 = 58;
}
v4 = (char *)*((_QWORD *)v4 + 14);
}
LABEL_40:
send_srv_packet(v3, v24);
continue;
}
if ( (_DWORD)v19 == 1953720684 && !BYTE4(v19) )
{
v9 = first_chan;
v24[0] = 1;
*(_QWORD *)((char *)&v24[9] + 1) = 0LL;
*(_QWORD *)((char *)&v24[263] + 1) = 0LL;
memset(&v24[10], 0, 8LL * (((unsigned int)&v24[9] + 1 - (unsigned int)&v24[10] + 1024) >> 3));
for ( ; v9; v9 = (char *)*((_QWORD *)v9 + 40) )
{
v10 = strlen((const char *)&v24[9] + 1);
v11 = stpcpy((char *)&v24[9] + v10 + 1, v9);
*v11 = 92;
*(_WORD *)stpcpy(v11 + 1, v9 + 32) = 10;
}
goto LABEL_40;
}
if ( (_DWORD)v19 != 1852403562 || BYTE4(v19) )
{
if ( v19 == 0x656E6E6F63736964LL && v20 == 29795 && !v21 )
break;
}
else
{
memset(v16, 0, sizeof(v16));
v12 = strlen(v16);
v13 = (__m128i *)stpcpy(&v16[v12], (const char *)v3);
strcpy(v13[1].m128i_i8, "r le canal.");
*v13 = _mm_load_si128((const __m128i *)&LC11);
wait_for_connection(v3);
strcpy((char *)(v3 + 32), v22);
sem_post(*(sem_t **)(v3 + 96));
add_channel(v22, v16);
}
}
}
else
{
v6 = first_con;
memset(v24, 0, 0x428uLL);
v15 = first_con;
v24[0] = 1;
strcpy((char *)&v24[1], (const char *)v3);
strcpy((char *)&v24[9] + 1, src);
for ( ; v6; v15 = v6 )
{
if ( (char *)v3 != v6 && !strcmp(v6 + 32, (const char *)(v3 + 32)) )
send_srv_packet((__int64)v6, v24);
v6 = (char *)*((_QWORD *)v15 + 14);
}
}
}
close_connection(v3, a1);
}
else
{
v24[0] = -1;
send(v1, v24, 0x428uLL, 0);
close_connection(0LL, a1);
}
}
return 0LL;
}

original_code:
void* handle_client_communication(void *argss)
{
    pthread_t my_tid = pthread_self();
    hcc_args *args = (hcc_args*) argss;
    client_packet cli_packet;
    server_packet srv_packet;
    int sockfd = args->cli_socket, n=0;
    if (recv(sockfd, (void*)&cli_packet, sizeof(client_packet), 0) <= 0) {
        free(args);
        close(sockfd);
        return ((void *)0);
    }
    connection *cur_con, *my_con = add_connection(
                cli_packet.con_info.id,
                sockfd,
                args->cli_addr,
                my_tid
            );
    channel *cur_chan;
    if (!my_con) {
        srv_packet.type = -1;
        send(sockfd, (void*)&srv_packet, sizeof(server_packet), 0);
    }
    else {
        srv_packet = (server_packet) {.type = 0};
        if (send_srv_packet(my_con, &srv_packet)) {
            close_connection(my_con, args);
            close(sockfd);
            return ((void *)0);
        }
        while (1) {
            memset(&srv_packet, 0, sizeof(server_packet));
            if (recv_cli_packet(my_con, &cli_packet)) {
                close_connection(my_con, args);
                return ((void *)0);
            }
            switch(cli_packet.type) {
                case 0:
                    cur_con = first_con;
                    srv_packet = (server_packet){
                        .msg = {
                        .type = 1,
                        .priv = 0
                        }
                    };
                    strcpy(srv_packet.msg.from, my_con->id);
                    strcpy(srv_packet.msg.message, cli_packet.msg.message);
                    while (cur_con) {
                        if (cur_con != my_con && !strcmp(cur_con->channel_id, my_con->channel_id))
                            send_srv_packet(cur_con, &srv_packet);
                        cur_con = cur_con->next;
                    }
                    break;
                case 2:
                    cur_con = first_con;
                    if (!strcmp(cli_packet.cmd.args[0], "msg")) {
                    srv_packet = (server_packet){
                        .msg = {
                        .type = 1,
                        .priv = 1
                        }
                    };
                        strcpy(srv_packet.msg.from, my_con->id);
                        strcpy(srv_packet.msg.message, cli_packet.cmd.main_arg);
                        if (!strcmp(cli_packet.cmd.args[1], "-")) {
                            while (cur_con) {
                                if (cur_con != my_con)
                                    send_srv_packet(cur_con, &srv_packet);
                                cur_con = cur_con->next;
                            }
                        }
                        else if (!find_connection(cli_packet.cmd.args[1], &cur_con))
                            send_srv_packet(cur_con, &srv_packet);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "names")) {
                        srv_packet.type = 1;
                        memset(srv_packet.msg.message, 0, 1024);
                        while (cur_con) {
                            if (!strcmp(cur_con->channel_id, my_con->channel_id)) {
                                strcat(srv_packet.msg.message, cur_con->id);
                                if (cur_con->next)
                                    strcat(srv_packet.msg.message, ":");
                            }
                            cur_con = cur_con->next;
                        }
                        send_srv_packet(my_con, &srv_packet);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "list")) {
                        cur_chan = first_chan;
                        srv_packet.type = 1;
                        memset(srv_packet.msg.message, 0, 1024);
                        while (cur_chan) {
                            strcat(srv_packet.msg.message, cur_chan->id);
                            strcat(srv_packet.msg.message, "\\");
                            strcat(srv_packet.msg.message, cur_chan->topic);
                            strcat(srv_packet.msg.message, "\n");
                            cur_chan = cur_chan->next;
                        }
                        send_srv_packet(my_con, &srv_packet);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "join")) {
                        char topic[256];
                        memset(topic, 0, 256);
                        strcat(topic, my_con->id);
                        strcat(topic, ": vient de créer le canal.");
                        wait_for_connection(my_con);
                        strcpy(my_con->channel_id, cli_packet.cmd.args[1]);
                        sem_post(my_con->sem);
                        add_channel(cli_packet.cmd.args[1],topic);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "disconnect")) {
                        close_connection(my_con, args);
                        return ((void *)0);
                    }
                    break;
                default:
                    break;
            }
        }
    }
    if (!my_con)
        close_connection(my_con, args);
    return ((void *)0);
}

canonical_original_code:
void *handle_client_communication(void *argss)
{
    unsigned long my_tid = pthread_self();
    struct _hcc_args *args = (hcc_args*) argss;
    union client_packet cli_packet;
    union server_packet srv_packet;
    int sockfd = args->cli_socket; int n = 0;
    if (recv(sockfd, (void *)&cli_packet, sizeof(client_packet), 0) <= 0) {
        free(args);
        close(sockfd);
        return ((void *)0);
    }
    struct _connection *cur_con; struct _connection *my_con = add_connection(
                cli_packet.con_info.id,
                sockfd,
                args->cli_addr,
                my_tid
            );
    struct _channel *cur_chan;
    if (!my_con) {
        srv_packet.type = -1;
        send(sockfd, (void *)&srv_packet, sizeof(server_packet), 0);
    }
    else {
        srv_packet = (union server_packet) {.type = 0};
        if (send_srv_packet(my_con, &srv_packet)) {
            close_connection(my_con, args);
            close(sockfd);
            return ((void *)0);
        }
        while (1) {
            memset(&srv_packet, 0, sizeof(server_packet));
            if (recv_cli_packet(my_con, &cli_packet)) {
                close_connection(my_con, args);
                return ((void *)0);
            }
            switch(cli_packet.type) {
                case 0:
                    cur_con = first_con;
                    srv_packet = (union server_packet){
                        .msg = {
                        .type = 1,
                        .priv = 0
                        }
                    };
                    strcpy(srv_packet.msg.from, my_con->id);
                    strcpy(srv_packet.msg.message, cli_packet.msg.message);
                    while (cur_con) {
                        if (cur_con != my_con && !strcmp(cur_con->channel_id, my_con->channel_id))
                            send_srv_packet(cur_con, &srv_packet);
                        cur_con = cur_con->next;
                    }
                    break;
                case 2:
                    cur_con = first_con;
                    if (!strcmp(cli_packet.cmd.args[0], "msg")) {
                    srv_packet = (union server_packet){
                        .msg = {
                        .type = 1,
                        .priv = 1
                        }
                    };
                        strcpy(srv_packet.msg.from, my_con->id);
                        strcpy(srv_packet.msg.message, cli_packet.cmd.main_arg);
                        if (!strcmp(cli_packet.cmd.args[1], "-")) {
                            while (cur_con) {
                                if (cur_con != my_con)
                                    send_srv_packet(cur_con, &srv_packet);
                                cur_con = cur_con->next;
                            }
                        }
                        else if (!find_connection(cli_packet.cmd.args[1], &cur_con))
                            send_srv_packet(cur_con, &srv_packet);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "names")) {
                        srv_packet.type = 1;
                        memset(srv_packet.msg.message, 0, 1024);
                        while (cur_con) {
                            if (!strcmp(cur_con->channel_id, my_con->channel_id)) {
                                strcat(srv_packet.msg.message, cur_con->id);
                                if (cur_con->next)
                                    strcat(srv_packet.msg.message, ":");
                            }
                            cur_con = cur_con->next;
                        }
                        send_srv_packet(my_con, &srv_packet);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "list")) {
                        cur_chan = first_chan;
                        srv_packet.type = 1;
                        memset(srv_packet.msg.message, 0, 1024);
                        while (cur_chan) {
                            strcat(srv_packet.msg.message, cur_chan->id);
                            strcat(srv_packet.msg.message, "\\");
                            strcat(srv_packet.msg.message, cur_chan->topic);
                            strcat(srv_packet.msg.message, "\n");
                            cur_chan = cur_chan->next;
                        }
                        send_srv_packet(my_con, &srv_packet);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "join")) {
                        char topic[256];
                        memset(topic, 0, 256);
                        strcat(topic, my_con->id);
                        strcat(topic, ": vient de créer le canal.");
                        wait_for_connection(my_con);
                        strcpy(my_con->channel_id, cli_packet.cmd.args[1]);
                        sem_post(my_con->sem);
                        add_channel(cli_packet.cmd.args[1],topic);
                    }
                    else if (!strcmp(cli_packet.cmd.args[0], "disconnect")) {
                        close_connection(my_con, args);
                        return ((void *)0);
                    }
                    break;
                default:
                    break;
            }
        }
    }
    if (!my_con)
        close_connection(my_con, args);
    return ((void *)0);
}

variable_types:
argss
void *

variable_types: union client_packet { unsigned int type; struct _client_cmd { unsigned int type; int argc; char args[5][32]; char main_arg[256]; } cmd; struct _connection_info { unsigned int type; char id[32]; } con_info; struct _cli_text_msg { unsigned int type; char message[1024]; } msg; }

variable_types: union server_packet { unsigned int type; struct _srv_text_msg { unsigned int type; char from[32]; char priv; char message[1024]; } msg; }

variable_types: struct _channel { char id[32]; char topic[256]; union sem_t { char __size[32]; long __align; } sem; struct _channel *next; struct _channel *prev; } *

variable_types:
topic
char [256]

return_type: void *

user_defined_types: struct _channel { char id[32]; char topic[256]; union sem_t sem; struct _channel *next; struct _channel *prev; }


decompiled_code:
__int64 __fastcall get_options(int argc, char **argv)
{
int v2; // eax

while ( 1 )
{
v2 = getopt_long(argc, argv, "hp:", &longopts_0, 0LL);
if ( v2 == -1 )
break;
if ( v2 == 104 )
{
puts(aInf1010tp2Serv);
exit(0);
}
if ( v2 != 112 )
{
fprintf(stderr, "%s\n", "essayez inf1010tp2-server --help");
return 0xFFFFFFFFLL;
}
if ( optarg )
server_port = atoi(optarg);
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func8(int argc, char **argv)
{
int v2; // eax

while ( 1 )
{
v2 = getopt_long(argc, argv, "hp:", &longopts_0, 0LL);
if ( v2 == -1 )
break;
if ( v2 == 104 )
{
puts(aInf1010tp2Serv);
exit(0);
}
if ( v2 != 112 )
{
fprintf(stderr, "%s\n", "essayez inf1010tp2-server --help");
return 0xFFFFFFFFLL;
}
if ( optarg )
server_port = atoi(optarg);
}
return 0LL;
}

original_code:
int get_options(int argc, char *argv[])
{
    int opt;
    static const struct option longopts[] = {
        {"help" , 0 , 0 , 'h' },
        {"port" , 1 , 0 , 'p' },
        {0 , 0 , 0 , 0 }
    };
    while ((opt = getopt_long(argc, argv, "hp:", longopts, ((void *)0))) != -1) {
        switch (opt) {
            case 'h':
                printf("%s\n", "inf1010tp2-server -- serveur de chat\n" "SYNOPSYS\n" "\tinf1010tp2-server [OPTIONS]\n" "OPTIONS\n" "\t-h|--help\n" "\t\tAffiche ce texte d'aide.\n" "\t-p|--port port\n" "\t\tSpécifie le port sur lequel le serveur devra écouter.");
                exit(0);
            case 'p':
                if (optarg)
                    server_port = atoi(optarg);
                break;
            default:
                fprintf(stderr, "%s\n", "essayez inf1010tp2-server --help");
                return -1;
        }
    }
    return 0;
}

canonical_original_code:
int get_options(int argc, char *argv[])
{
    int opt;
    static struct option longopts[] = {
        {"help" , 0 , 0 , 'h' },
        {"port" , 1 , 0 , 'p' },
        {0 , 0 , 0 , 0 }
    };
    while ((opt = getopt_long(argc, argv, "hp:", longopts, ((void *)0))) != -1) {
        switch (opt) {
            case 'h':
                printf("%s\n", "inf1010tp2-server -- serveur de chat\n" "SYNOPSYS\n" "\tinf1010tp2-server [OPTIONS]\n" "OPTIONS\n" "\t-h|--help\n" "\t\tAffiche ce texte d'aide.\n" "\t-p|--port port\n" "\t\tSpécifie le port sur lequel le serveur devra écouter.");
                exit(0);
            case 'p':
                if (optarg)
                    server_port = atoi(optarg);
                break;
            default:
                fprintf(stderr, "%s\n", "essayez inf1010tp2-server --help");
                return -1;
        }
    }
    return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: opt int

variable_types: struct option { char *name; int has_arg; int *flag; int val; } []


decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
signal(2, (__sighandler_t)handle_sig);
signal(9, (__sighandler_t)handle_sig);
if ( !(unsigned int)get_options(argc, (char **)argv) )
{
if ( !init_socket() )
{
add_channel("lobby", &unk_B28);
receive_connections();
}
fwrite("Erreur lors de l'initialisation du serveur...\n", 1uLL, 0x2EuLL, stderr);
}
exit(1);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
signal(2, (__sighandler_t)handle_sig);
signal(9, (__sighandler_t)handle_sig);
if ( !(unsigned int)func8(argc, (char **)argv) )
{
if ( !func2() )
{
add_channel("lobby", &unk_B28);
func3();
}
fwrite("Erreur lors de l'initialisation du serveur...\n", 1uLL, 0x2EuLL, stderr);
}
exit(1);
}

original_code:
int main(int argc, char *argv[])
{
    signal(2, handle_sig);
    signal(9, handle_sig);
    if(get_options(argc, argv))
        exit(1);
    if (init_socket()) {
        fprintf(stderr, "Erreur lors de l'initialisation du serveur...\n");
        exit(1);
    }
    add_channel("lobby", "Bienvenue sur le serveur inf1010tp2. Vous avez " "été placé dans le canal par défaut (\"lobby\").");
    receive_connections();
    return 0;
}


decompiled_code:
int __fastcall find_channel(char *s2, char **a2)
{
char *v2; // rbx
int result; // eax

v2 = first_chan;
if ( first_chan )
{
while ( 1 )
{
result = strcmp(v2, s2);
if ( !result )
break;
v2 = (char *)*((_QWORD *)v2 + 40);
if ( !v2 )
goto LABEL_8;
}
if ( a2 )
*a2 = v2;
}
else
{
LABEL_8:
result = -1;
if ( a2 )
*a2 = 0LL;
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(char *s2, char **a2)
{
char *v2; // rbx
int result; // eax

v2 = first_chan;
if ( first_chan )
{
while ( 1 )
{
result = strcmp(v2, s2);
if ( !result )
break;
v2 = (char *)*((_QWORD *)v2 + 40);
if ( !v2 )
goto LABEL_8;
}
if ( a2 )
*a2 = v2;
}
else
{
LABEL_8:
result = -1;
if ( a2 )
*a2 = 0LL;
}
return result;
}

original_code:
int find_channel(char id[], channel **chan)
{
    channel *cur = first_chan;
    while (cur) {
        if (!strcmp(cur->id, id)) {
            if (chan)
                *chan = cur;
            return 0;
        }
        cur = cur->next;
    }
    if (chan)
        *chan = ((void *)0);
    return -1;
}

canonical_original_code:
int find_channel(char id[], struct _channel **chan)
{
    struct _channel *cur = first_chan;
    while (cur) {
        if (!strcmp(cur->id, id)) {
            if (chan)
                *chan = cur;
            return 0;
        }
        cur = cur->next;
    }
    if (chan)
        *chan = ((void *)0);
    return -1;
}

variable_types:
id
char []

variable_types: struct _channel { char id[32]; char topic[256]; union sem_t { char __size[32]; long __align; } sem; struct _channel *next; struct _channel *prev; } **


decompiled_code:
__int64 __fastcall add_channel(char *src, char *a2)
{
char *v2; // rbp
__int64 result; // rax

if ( !find_channel(src, 0LL) )
return 0xFFFFFFFFLL;
v2 = (char *)malloc(0x150uLL);
if ( !v2 )
return 4294967294LL;
memset(v2, 0, 0x150uLL);
strcpy(v2, src);
strcpy(v2 + 32, a2);
result = last_chan;
if ( __PAIR128__((unsigned __int64)first_chan, last_chan) == 0 )
{
last_chan = (__int64)v2;
first_chan = v2;
}
else
{
last_chan = (__int64)v2;
*(_QWORD *)(result + 320) = v2;
*((_QWORD *)v2 + 41) = result;
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *src, char *a2)
{
char *v2; // rbp
__int64 result; // rax

if ( !func0(src, 0LL) )
return 0xFFFFFFFFLL;
v2 = (char *)malloc(0x150uLL);
if ( !v2 )
return 4294967294LL;
memset(v2, 0, 0x150uLL);
strcpy(v2, src);
strcpy(v2 + 32, a2);
result = last_chan;
if ( __PAIR128__((unsigned __int64)first_chan, last_chan) == 0 )
{
last_chan = (__int64)v2;
first_chan = v2;
}
else
{
last_chan = (__int64)v2;
*(_QWORD *)(result + 320) = v2;
*((_QWORD *)v2 + 41) = result;
result = 0LL;
}
return result;
}

original_code:
int add_channel(char id[], char topic[])
{
    if (!find_channel(id, ((void *)0)))
        return -1;
    channel *new_chan;
    if (!(new_chan = malloc(sizeof(channel))))
        return -2;
    *new_chan = (channel) {.next = ((void *)0), .prev = ((void *)0)};
    strcpy(new_chan->id, id);
    strcpy(new_chan->topic, topic);
    if (!first_chan && !last_chan) {
        first_chan = last_chan = new_chan;
    }
    else {
        last_chan->next = new_chan;
        new_chan->prev = last_chan;
        last_chan = new_chan;
    }
    return 0;
}

canonical_original_code:
int add_channel(char id[], char topic[])
{
    if (!find_channel(id, ((void *)0)))
        return -1;
    struct _channel *new_chan;
    if (!(new_chan = malloc(sizeof(channel))))
        return -2;
    *new_chan = (struct _channel) {.next = ((void *)0), .prev = ((void *)0)};
    strcpy(new_chan->id, id);
    strcpy(new_chan->topic, topic);
    if (!first_chan && !last_chan) {
        first_chan = last_chan = new_chan;
    }
    else {
        last_chan->next = new_chan;
        new_chan->prev = last_chan;
        last_chan = new_chan;
    }
    return 0;
}

variable_types:
topic
char []


decompiled_code:
__int64 __fastcall remove_channel(char *s2)
{
char *v1; // r13
unsigned int v2; // er12
void *v3; // rdi
__int64 v4; // rax
__int64 v5; // rdx
void *ptr; // [rsp+8h] [rbp-20h] BYREF

v1 = first_chan;
if ( !first_chan || !last_chan )
return (unsigned int)-1;
if ( first_chan == (char *)last_chan )
{
v2 = strcmp(first_chan, s2);
if ( !v2 )
{
free(v1);
last_chan = 0LL;
first_chan = 0LL;
return v2;
}
}
v2 = find_channel(s2, (char **)&ptr);
if ( v2 )
return (unsigned int)-1;
v3 = ptr;
if ( ptr == (void *)last_chan )
{
*(_QWORD *)(*((_QWORD *)ptr + 41) + 320LL) = 0LL;
}
else
{
v4 = *((_QWORD *)ptr + 40);
if ( ptr == first_chan )
{
first_chan = (char *)*((_QWORD *)ptr + 40);
}
else
{
v5 = *((_QWORD *)ptr + 41);
*(_QWORD *)(v5 + 320) = v4;
*(_QWORD *)(v4 + 328) = v5;
}
}
free(v3);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *s2)
{
char *v1; // r13
unsigned int v2; // er12
void *v3; // rdi
__int64 v4; // rax
__int64 v5; // rdx
void *ptr; // [rsp+8h] [rbp-20h] BYREF

v1 = first_chan;
if ( !first_chan || !last_chan )
return (unsigned int)-1;
if ( first_chan == (char *)last_chan )
{
v2 = strcmp(first_chan, s2);
if ( !v2 )
{
free(v1);
last_chan = 0LL;
first_chan = 0LL;
return v2;
}
}
v2 = func0(s2, (char **)&ptr);
if ( v2 )
return (unsigned int)-1;
v3 = ptr;
if ( ptr == (void *)last_chan )
{
*(_QWORD *)(*((_QWORD *)ptr + 41) + 320LL) = 0LL;
}
else
{
v4 = *((_QWORD *)ptr + 40);
if ( ptr == first_chan )
{
first_chan = (char *)*((_QWORD *)ptr + 40);
}
else
{
v5 = *((_QWORD *)ptr + 41);
*(_QWORD *)(v5 + 320) = v4;
*(_QWORD *)(v4 + 328) = v5;
}
}
free(v3);
return v2;
}

original_code:
int remove_channel(char id[])
{
    if (!first_chan || !last_chan) {
        return -1;
    }
    if (first_chan == last_chan && !strcmp(last_chan->id, id)) {
        free(first_chan);
        first_chan = last_chan = ((void *)0);
        return 0;
    }
    channel *chan;
    if (!find_channel(id, &chan)) {
        if (chan == last_chan) {
            last_chan->prev->next = ((void *)0);
        }
        else if (chan == first_chan) {
            first_chan = chan->next;
        }
        else {
            chan->prev->next = chan->next;
            chan->next->prev = chan->prev;
        }
        free(chan);
        return 0;
    }
    return -1;
}

canonical_original_code:
int remove_channel(char id[])
{
    if (!first_chan || !last_chan) {
        return -1;
    }
    if (first_chan == last_chan && !strcmp(last_chan->id, id)) {
        free(first_chan);
        first_chan = last_chan = ((void *)0);
        return 0;
    }
    struct _channel *chan;
    if (!find_channel(id, &chan)) {
        if (chan == last_chan) {
            last_chan->prev->next = ((void *)0);
        }
        else if (chan == first_chan) {
            first_chan = chan->next;
        }
        else {
            chan->prev->next = chan->next;
            chan->next->prev = chan->prev;
        }
        free(chan);
        return 0;
    }
    return -1;
}


getOptions

decompiled_code:
__int64 __fastcall getOptions(int a1, char *const *a2)
{
int v2; // eax
unsigned int v3; // er12
int longind[7]; // [rsp+Ch] [rbp-1Ch] BYREF

longind[0] = 0;
v2 = getopt_long(a1, a2, "h", &long_options_0, longind);
v3 = v2;
if ( v2 == -1 )
{
if ( optind >= a1 )
{
fprintf(stderr, "%s, %s\n", "Arguemnt manquant", "essayez inf1018tp2 --help");
}
else
{
v3 = 0;
input_filename = (__int64)malloc(4uLL);
strcpy((char *)input_filename, a2[optind]);
}
}
else
{
if ( v2 == 104 )
{
puts(s);
exit(0);
}
v3 = -1;
fprintf(stderr, "%s\n", "essayez inf1018tp2 --help");
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, char *const *a2)
{
int v2; // eax
unsigned int v3; // er12
int longind[7]; // [rsp+Ch] [rbp-1Ch] BYREF

longind[0] = 0;
v2 = getopt_long(a1, a2, "h", &long_options_0, longind);
v3 = v2;
if ( v2 == -1 )
{
if ( optind >= a1 )
{
fprintf(stderr, "%s, %s\n", "Arguemnt manquant", "essayez inf1018tp2 --help");
}
else
{
v3 = 0;
input_filename = (__int64)malloc(4uLL);
strcpy((char *)input_filename, a2[optind]);
}
}
else
{
if ( v2 == 104 )
{
puts(s);
exit(0);
}
v3 = -1;
fprintf(stderr, "%s\n", "essayez inf1018tp2 --help");
}
return v3;
}

original_code:
int getOptions(int argc, char* argv[])
{
    int opt, optindex = 0;
    static struct option long_options[] = {
        {"help" , 0 , 0 , 'h' },
        {0 , 0 , 0 , 0 }
    };
    while ((opt = getopt_long(argc, argv, "h", long_options, &optindex)) != -1) {
        switch(opt){
            case 'h':
                printf("%s\n", "inf1018tp2 -- analyseur lexical et syntaxique\nSYNPOSYS : inf1018tp2 [OPTIONS] file\n\tfile\n\t\tLe fichier duquel tirer le texte à anlayser.\nOPTIONS\n\t-h|--help\n\t\tAffiche un texte d\'aide\n");
                exit(0);
            default:
                fprintf(stderr, "%s\n", "essayez inf1018tp2 --help");
                return -1;
        }
    }
    if (optind >= argc) {
        fprintf(stderr, "%s, %s\n", "Arguemnt manquant", "essayez inf1018tp2 --help");
        return -1;
    }
    input_filename = malloc(sizeof(argc-optind));
    strcpy(input_filename, argv[optind]);
    return 0;
}

canonical_original_code:
int getOptions(int argc, char *argv[])
{
    int opt; int optindex = 0;
    static struct option long_options[] = {
        {"help" , 0 , 0 , 'h' },
        {0 , 0 , 0 , 0 }
    };
    while ((opt = getopt_long(argc, argv, "h", long_options, &optindex)) != -1) {
        switch(opt){
            case 'h':
                printf("%s\n", "inf1018tp2 -- analyseur lexical et syntaxique\nSYNPOSYS : inf1018tp2 [OPTIONS] file\n\tfile\n\t\tLe fichier duquel tirer le texte à anlayser.\nOPTIONS\n\t-h|--help\n\t\tAffiche un texte d\'aide\n");
                exit(0);
            default:
                fprintf(stderr, "%s\n", "essayez inf1018tp2 --help");
                return -1;
        }
    }
    if (optind >= argc) {
        fprintf(stderr, "%s, %s\n", "Arguemnt manquant", "essayez inf1018tp2 --help");
        return -1;
    }
    input_filename = malloc(sizeof(argc-optind));
    strcpy(input_filename, argv[optind]);
    return 0;
}

variable_types: optindex int

user_defined_types: struct option { char *name; int has_arg; int *flag; int val; }


main

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

if ( (unsigned int)getOptions(argc, (char *const *)argv) )
exit(1);
loadFile((void **)&MAIN_BUFFER, (const char *)input_filename);
v3 = MAIN_BUFFER;
BUFLEN = strlen(MAIN_BUFFER);
cur_pos = (__int64)strdup(v3);
INIT_POS = cur_pos;
analyse_syntax();
exit(0);
}

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

if ( (unsigned int)func1(argc, (char *const *)argv) )
exit(1);
func0((void **)&MAIN_BUFFER, (const char *)input_filename);
v3 = MAIN_BUFFER;
BUFLEN = strlen(MAIN_BUFFER);
cur_pos = (__int64)strdup(v3);
INIT_POS = cur_pos;
analyse_syntax();
exit(0);
}

original_code:
int main(int argc, char *argv[])
{
    if (getOptions(argc, argv))
        exit(1);
    loadFile(&MAIN_BUFFER, input_filename);
    BUFLEN = strlen(MAIN_BUFFER);
    cur_pos = strdup(MAIN_BUFFER);
    INIT_POS = cur_pos;
    analyse_syntax();
    exit(0);
}


askForNext

decompiled_code:
__int64 askForNext()
{
__int64 result; // rax

while ( 1 )
{
result = next(&token);
if ( (int)result <= 0 )
break;
token = (char *)malloc((int)result + 1);
}
if ( (_DWORD)result )
{
fprintf(stderr, "%s : Fin du fichier inattendue.\n", "erreur de syntaxe");
exit(1);
}
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 result; // rax

while ( 1 )
{
result = next(&token);
if ( (int)result <= 0 )
break;
token = (char *)malloc((int)result + 1);
}
if ( (_DWORD)result )
{
fprintf(stderr, "%s : Fin du fichier inattendue.\n", "erreur de syntaxe");
exit(1);
}
return result;
}

original_code:
void askForNext()
{
    int size = next(&token);
    if (size > 0) {
        token = malloc(sizeof(char) * (size+1));
        askForNext();
    }
    else if (size < 0) {
        fprintf(stderr, "%s : Fin du fichier inattendue.\n", "erreur de syntaxe");
        exit(1);
    }
}

variable_types: size int


type

decompiled_code:
bool type()
{
bool v0; // zf
bool result; // al

askForNext();
v0 = strcmp(token, "entier") == 0;
result = !v0;
if ( !v0 )
{
v0 = memcmp(token, &unk_8A1, 6uLL) == 0;
result = !v0;
if ( !v0 )
{
fprintf(stderr, aSLeTypeDoit, "erreur de syntaxe");
exit(1);
}
}
return result;
}

canonical_decompiled_code:
bool func1()
{
bool v0; // zf
bool result; // al

func0();
v0 = strcmp(token, "entier") == 0;
result = !v0;
if ( !v0 )
{
v0 = memcmp(token, &unk_8A1, 6uLL) == 0;
result = !v0;
if ( !v0 )
{
fprintf(stderr, aSLeTypeDoit, "erreur de syntaxe");
exit(1);
}
}
return result;
}

original_code:
void type()
{
    askForNext();
    if (strcmp(token, "entier") && strcmp(token, "réel")) {
        fprintf(stderr, "%s : Le type doit être \'entier\' ou \'réel\'\n", "erreur de syntaxe");
        exit(1);
    }
}


identificator

decompiled_code:
__int64 __fastcall identificator(int a1, int a2)
{
char *v2; // r12
unsigned int v3; // er12
char *v5; // r13
char v6; // al

askForNext();
printf("Analyse d'un identificateur, le token est:\n'%s'\n", token);
v2 = token;
if ( strlen(token) > 8 )
{
if ( !a2 )
{
fprintf(stderr, aSUnIdentificat_0, "erreur de syntaxe", 8LL);
exit(1);
}
return 1;
}
v3 = is_reserved(v2);
if ( v3 )
{
fwrite(&unk_9E8, 1uLL, 0x48uLL, stderr);
exit(1);
}
v5 = token;
if ( !a1 )
goto LABEL_12;
if ( !*cur_proc )
{
strcpy(cur_proc, token);
v5 = token;
goto LABEL_12;
}
if ( !strcmp(token, cur_proc) )
{
LABEL_12:
v6 = *v5;
if ( (unsigned __int8)(*v5 - 91) <= 5u || (unsigned __int8)(v6 - 65) > 0x39u )
{
if ( a2 )
return 1;
fprintf(stderr, aSLePremierCara, "erreur de syntaxe");
}
else
{
while ( (unsigned __int8)(v6 - 58) > 6u && (unsigned __int8)(v6 - 48) <= 0x4Au && (unsigned __int8)(v6 - 91) > 5u )
{
v6 = *++v5;
if ( !v6 )
return v3;
}
if ( a2 )
return 1;
fprintf(
stderr,
"%s : Un identificateur doit contenir seulement des lettres et des chiffres.\n",
"erreur de syntaxe");
}
LABEL_23:
exit(1);
}
if ( !a2 )
{
fprintf(
stderr,
"%s : L'identifcateur suivant le terminal \"Procedure\" doit coincider avec celui suivant le te"
"rminal \"Fin_Procedure\"\n",
"erreur de syntaxe");
goto LABEL_23;
}
return 1;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, int a2)
{
char *v2; // r12
unsigned int v3; // er12
char *v5; // r13
char v6; // al

func0();
printf("Analyse d'un identificateur, le token est:\n'%s'\n", token);
v2 = token;
if ( strlen(token) > 8 )
{
if ( !a2 )
{
fprintf(stderr, aSUnIdentificat_0, "erreur de syntaxe", 8LL);
exit(1);
}
return 1;
}
v3 = is_reserved(v2);
if ( v3 )
{
fwrite(&unk_9E8, 1uLL, 0x48uLL, stderr);
exit(1);
}
v5 = token;
if ( !a1 )
goto LABEL_12;
if ( !*cur_proc )
{
strcpy(cur_proc, token);
v5 = token;
goto LABEL_12;
}
if ( !strcmp(token, cur_proc) )
{
LABEL_12:
v6 = *v5;
if ( (unsigned __int8)(*v5 - 91) <= 5u || (unsigned __int8)(v6 - 65) > 0x39u )
{
if ( a2 )
return 1;
fprintf(stderr, aSLePremierCara, "erreur de syntaxe");
}
else
{
while ( (unsigned __int8)(v6 - 58) > 6u && (unsigned __int8)(v6 - 48) <= 0x4Au && (unsigned __int8)(v6 - 91) > 5u )
{
v6 = *++v5;
if ( !v6 )
return v3;
}
if ( a2 )
return 1;
fprintf(
stderr,
"%s : Un identificateur doit contenir seulement des lettres et des chiffres.\n",
"erreur de syntaxe");
}
LABEL_23:
exit(1);
}
if ( !a2 )
{
fprintf(
stderr,
"%s : L'identifcateur suivant le terminal \"Procedure\" doit coincider avec celui suivant le te"
"rminal \"Fin_Procedure\"\n",
"erreur de syntaxe");
goto LABEL_23;
}
return 1;
}

original_code:
int identificator(int is_proc_id, int maybe)
{
    askForNext();
    printf("Analyse d'un identificateur, le token est:\n\'%s\'\n", token);
    if (strlen(token) > 8) {
        if (maybe) {
            return 1;
        }
        fprintf(stderr, "%s : Un identificateur doit contenir maximum %i caractères.\n", "erreur de syntaxe", 8);
        exit(1);
    }
    if (is_reserved(token)) {
        fprintf(stderr, "Un identificateur doit être différent des mots réservés du langage.\n");
        exit(1);
    }
    if (is_proc_id) {
        if (!strcmp(cur_proc->id, "")) {
            strcpy(cur_proc->id, token);
        }
        else if (strcmp(token, cur_proc->id)) {
            if (maybe) {
                return 1;
            }
            fprintf(stderr, "%s : L'identifcateur suivant le terminal \"Procedure\" doit coincider avec celui                     suivant le terminal \"Fin_Procedure\"\n", "erreur de syntaxe");
            exit(1);
        }
    }
    char *tok = token;
    if (*tok < 65 || (*tok > 90 && *tok < 97) || *tok > 122) {
        if (maybe) {
            return 1;
        }
        fprintf(stderr, "%s : Le premier caractère d'un identificateur doit être une lettre.\n", "erreur de syntaxe");
        exit(1);
    }
    while (*tok != '\0') {
        if (*tok < 48 || (*tok > 57 && *tok < 65) || (*tok > 90 && *tok < 97) || *tok > 122) {
            if (maybe) {
                return 1;
            }
            fprintf(stderr, "%s : Un identificateur doit contenir seulement des lettres et des chiffres.\n", "erreur de syntaxe");
            exit(1);
        }
        tok++;
    }
    return 0;
}

variable_types: maybe int

variable_types:
tok
char *