decompiled_code:
__int64 __fastcall smtp_send_command(unsigned int a1, unsigned __int64 a2, __int64 a3)
{
__int64 v3; // rbp
size_t v4; // rbx
int v5; // eax
const char *v6; // rbx
size_t v7; // rax
unsigned __int64 v8; // rsi
const char **v9; // rbx
const char *v10; // r12
size_t v11; // rax
__int64 result; // rax
char dest[512]; // [rsp+0h] [rbp-318h] BYREF
char name[264]; // [rsp+200h] [rbp-118h] BYREF
__int64 v15; // [rsp+308h] [rbp-10h]

v15 = v3;
switch ( a2 & 0xF )
{
case 0uLL:
case 7uLL:
return 4294967293LL;
case 1uLL:
case 2uLL:
if ( (a2 & 0xF) == 1 )
*(_DWORD *)dest = 1330399301;
else
*(_DWORD *)dest = 1330398536;
strcpy(&dest[4], " ");
memset(name, 0, 0x100uLL);
if ( gethostname(name, 0x100uLL) != -1 )
{
strncpy(&dest[5], name, 0x1F8uLL);
strcpy(&dest[strlen(name) + 5], "\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
}
return 4294967291LL;
case 3uLL:
if ( !a3 )
return 0xFFFFFFFFLL;
strcpy(dest, "MAIL FROM:<");
v6 = *(const char **)a3;
if ( strlen(*(const char **)a3) <= 0x100 )
{
strncpy(&dest[11], v6, 0x100uLL);
v7 = strlen(v6);
if ( v7 > 0x100 )
v7 = 256LL;
*(_DWORD *)&dest[v7 + 11] = 658750;
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
}
return 4294967290LL;
case 4uLL:
if ( !a3 )
return 0xFFFFFFFFLL;
v8 = a2 >> 4;
if ( (v8 & 0x80000000) != 0LL )
return 4294967293LL;
if ( (unsigned __int64)(int)v8 > *(_QWORD *)(a3 + 16) )
return 4294967293LL;
strcpy(dest, "RCPT TO:<");
v9 = (const char **)(*(_QWORD *)(a3 + 8) + 8LL * (int)v8);
v10 = *v9;
if ( strlen(*v9) <= 0x100 )
{
strncpy(&dest[9], v10, 0x1F8uLL);
v11 = strlen(*v9);
if ( v11 > 0x100 )
v11 = 256LL;
*(_DWORD *)&dest[v11 + 9] = 658750;
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
}
return 4294967290LL;
case 5uLL:
strcpy(dest, "DATA\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
case 6uLL:
strcpy(dest, "RSET\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
case 8uLL:
strcpy(dest, "NOOP\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
case 9uLL:
strcpy(dest, "QUIT\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
LABEL_20:
if ( v5 < 0 )
result = 4294967292LL;
else
result = 4 * (unsigned int)(v5 == v4) - 4;
break;
default:
result = 4294967293LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1, unsigned __int64 a2, __int64 a3)
{
__int64 v3; // rbp
size_t v4; // rbx
int v5; // eax
const char *v6; // rbx
size_t v7; // rax
unsigned __int64 v8; // rsi
const char **v9; // rbx
const char *v10; // r12
size_t v11; // rax
__int64 result; // rax
char dest[512]; // [rsp+0h] [rbp-318h] BYREF
char name[264]; // [rsp+200h] [rbp-118h] BYREF
__int64 v15; // [rsp+308h] [rbp-10h]

v15 = v3;
switch ( a2 & 0xF )
{
case 0uLL:
case 7uLL:
return 4294967293LL;
case 1uLL:
case 2uLL:
if ( (a2 & 0xF) == 1 )
*(_DWORD *)dest = 1330399301;
else
*(_DWORD *)dest = 1330398536;
strcpy(&dest[4], " ");
memset(name, 0, 0x100uLL);
if ( gethostname(name, 0x100uLL) != -1 )
{
strncpy(&dest[5], name, 0x1F8uLL);
strcpy(&dest[strlen(name) + 5], "\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
}
return 4294967291LL;
case 3uLL:
if ( !a3 )
return 0xFFFFFFFFLL;
strcpy(dest, "MAIL FROM:<");
v6 = *(const char **)a3;
if ( strlen(*(const char **)a3) <= 0x100 )
{
strncpy(&dest[11], v6, 0x100uLL);
v7 = strlen(v6);
if ( v7 > 0x100 )
v7 = 256LL;
*(_DWORD *)&dest[v7 + 11] = 658750;
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
}
return 4294967290LL;
case 4uLL:
if ( !a3 )
return 0xFFFFFFFFLL;
v8 = a2 >> 4;
if ( (v8 & 0x80000000) != 0LL )
return 4294967293LL;
if ( (unsigned __int64)(int)v8 > *(_QWORD *)(a3 + 16) )
return 4294967293LL;
strcpy(dest, "RCPT TO:<");
v9 = (const char **)(*(_QWORD *)(a3 + 8) + 8LL * (int)v8);
v10 = *v9;
if ( strlen(*v9) <= 0x100 )
{
strncpy(&dest[9], v10, 0x1F8uLL);
v11 = strlen(*v9);
if ( v11 > 0x100 )
v11 = 256LL;
*(_DWORD *)&dest[v11 + 9] = 658750;
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
}
return 4294967290LL;
case 5uLL:
strcpy(dest, "DATA\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
case 6uLL:
strcpy(dest, "RSET\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
case 8uLL:
strcpy(dest, "NOOP\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
goto LABEL_20;
case 9uLL:
strcpy(dest, "QUIT\r\n");
v4 = strlen(dest);
v5 = writen(a1, dest, v4);
LABEL_20:
if ( v5 < 0 )
result = 4294967292LL;
else
result = 4 * (unsigned int)(v5 == v4) - 4;
break;
default:
result = 4294967293LL;
break;
}
return result;
}

original_code:
int smtp_send_command (int sockfd, size_t cmd, struct mail_object *mail)
{
    int ret;
    size_t slen;
    char domain[256], cmd_line[512];
    size_t pos = 0;
    int rcpt_no = (((cmd) & ~0xF)>>4);
    cmd = ((cmd) & 0xF);
    switch (cmd) {
        case 1:
        case 2:
            if (1 == cmd)
                strcpy(cmd_line, "EHLO ");
            else
                strcpy(cmd_line, "HELO ");
            pos = 5;
            memset(domain, 0, sizeof domain);
            if (-1 == gethostname(domain, sizeof domain))
                return -5;
            strncpy(cmd_line+pos, domain, (512 -8));
            pos += ((256) < (strlen(domain)) ? (256) : (strlen(domain)));
            strcpy(cmd_line+pos, "\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 3:
            if (((void *)0) == mail)
                return -1;
            strcpy(cmd_line, "MAIL FROM:<");
            pos = 11;
            if (strlen(mail->mail_from) > 256)
                return -6;
            strncpy(cmd_line+pos, mail->mail_from, 256);
            pos += ((256) < (strlen(mail->mail_from)) ? (256) : (strlen(mail->mail_from)));
            strcpy(cmd_line+pos, ">\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 4:
            if (((void *)0) == mail)
                return -1;
            if (rcpt_no < 0 || ((size_t) rcpt_no) > mail->no_rcpt)
                return -3;
            strcpy(cmd_line, "RCPT TO:<");
            pos = 9;
            if (strlen(mail->rcpt_to[rcpt_no]) > 256)
                return -6;
            strncpy(cmd_line+pos, mail->rcpt_to[rcpt_no], (512 -8));
            pos += ((256) < (strlen(mail->rcpt_to[rcpt_no])) ? (256) : (strlen(mail->rcpt_to[rcpt_no])));
            strcpy(cmd_line+pos, ">\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 5:
            strcpy(cmd_line, "DATA\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 6:
            strcpy(cmd_line, "RSET\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 7:
            return -3;
            break;
        case 8:
            strcpy(cmd_line, "NOOP\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 9:
            strcpy(cmd_line, "QUIT\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        default:
            return -3;
    }
    if (ret < 0 || (size_t) ret != slen)
        return -4;
    else
        return 0;
}

canonical_original_code:
int smtp_send_command(int sockfd, unsigned long cmd, struct mail_object *mail)
{
    int ret;
    unsigned long slen;
    char domain[256]; char cmd_line[512];
    unsigned long pos = 0;
    int rcpt_no = (((cmd) & ~0xF)>>4);
    cmd = ((cmd) & 0xF);
    switch (cmd) {
        case 1:
        case 2:
            if (1 == cmd)
                strcpy(cmd_line, "EHLO ");
            else
                strcpy(cmd_line, "HELO ");
            pos = 5;
            memset(domain, 0, sizeof domain);
            if (-1 == gethostname(domain, sizeof domain))
                return -5;
            strncpy(cmd_line+pos, domain, (512 -8));
            pos += ((256) < (strlen(domain)) ? (256) : (strlen(domain)));
            strcpy(cmd_line+pos, "\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 3:
            if (((void *)0) == mail)
                return -1;
            strcpy(cmd_line, "MAIL FROM:<");
            pos = 11;
            if (strlen(mail->mail_from) > 256)
                return -6;
            strncpy(cmd_line+pos, mail->mail_from, 256);
            pos += ((256) < (strlen(mail->mail_from)) ? (256) : (strlen(mail->mail_from)));
            strcpy(cmd_line+pos, ">\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 4:
            if (((void *)0) == mail)
                return -1;
            if (rcpt_no < 0 || ((unsigned long) rcpt_no) > mail->no_rcpt)
                return -3;
            strcpy(cmd_line, "RCPT TO:<");
            pos = 9;
            if (strlen(mail->rcpt_to[rcpt_no]) > 256)
                return -6;
            strncpy(cmd_line+pos, mail->rcpt_to[rcpt_no], (512 -8));
            pos += ((256) < (strlen(mail->rcpt_to[rcpt_no])) ? (256) : (strlen(mail->rcpt_to[rcpt_no])));
            strcpy(cmd_line+pos, ">\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 5:
            strcpy(cmd_line, "DATA\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 6:
            strcpy(cmd_line, "RSET\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 7:
            return -3;
            break;
        case 8:
            strcpy(cmd_line, "NOOP\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        case 9:
            strcpy(cmd_line, "QUIT\r\n");
            ret = writen(sockfd, cmd_line, slen = strlen(cmd_line));
            break;
        default:
            return -3;
    }
    if (ret < 0 || (unsigned long) ret != slen)
        return -4;
    else
        return 0;
}

variable_types: sockfd int

variable_types:
cmd
unsigned long

variable_types: ret int

variable_types:
slen
unsigned long

variable_types:
domain
char [256]

variable_types:
pos
unsigned long

user_defined_types: struct mail_object { char *mail_from; char **rcpt_to; unsigned long no_rcpt; char *data; unsigned long data_size; }


repo: tphaster/smime-gate

decompiled_code:
__int64 __fastcall smtp_send_reply(unsigned int a1, __int64 a2, const char *a3, size_t a4)
{
__int64 v4; // rbp
size_t v5; // rbx
int v6; // eax
__int64 result; // rax
size_t v9; // rax
char dest[512]; // [rsp+0h] [rbp-318h] BYREF
char name[272]; // [rsp+200h] [rbp-118h] BYREF
__int64 v12; // [rsp+310h] [rbp-8h]

v12 = v4;
switch ( a2 )
{
case 0LL:
return 4294967293LL;
case 1LL:
if ( a3 )
{
strcpy(dest, "220 ");
goto LABEL_14;
}
strcpy(dest, "220 ");
memset(name, 0, 0x100uLL);
if ( gethostname(name, 0x100uLL) != -1 )
{
strncpy(&dest[4], name, 0x1F9uLL);
strcpy(&dest[strlen(name) + 4], " Service ready\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
}
return 4294967291LL;
case 2LL:
if ( a3 )
{
strcpy(dest, "221 ");
goto LABEL_14;
}
strcpy(dest, "221 closing connection, bye\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 3LL:
if ( a3 )
{
strcpy(dest, "250 ");
goto LABEL_14;
}
strcpy(dest, "250 OK\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 4LL:
if ( a3 )
{
strcpy(dest, "250-");
goto LABEL_14;
}
return 4294967293LL;
case 5LL:
if ( a3 )
{
strcpy(dest, "251 ");
goto LABEL_14;
}
strcpy(dest, "251 User not local; will forward to next hop\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 6LL:
if ( a3 )
{
strcpy(dest, "252 ");
goto LABEL_14;
}
strcpy(dest, "252 cannot VRFY user, but will accept message and attempt delivery\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 7LL:
if ( a3 )
{
strcpy(dest, "354 ");
goto LABEL_14;
}
strcpy(dest, "354 Start mail input; end with <CRLF>.<CRLF>\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 8LL:
if ( a3 )
{
strcpy(dest, "450 ");
goto LABEL_14;
}
strcpy(dest, "450 Requested mail action not taken: mailbox unavailable\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 9LL:
if ( a3 )
{
strcpy(dest, "451 ");
goto LABEL_14;
}
strcpy(dest, "451 Requested action aborted: local error in processing\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 10LL:
if ( a3 )
{
strcpy(dest, "452 ");
goto LABEL_14;
}
strcpy(dest, "452 requested action not taken: insufficient system storage\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 11LL:
if ( a3 )
{
strcpy(dest, "455 ");
goto LABEL_14;
}
strcpy(dest, "455 Server unable to accommodate parameters\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 12LL:
if ( a3 )
{
strcpy(dest, "500 ");
goto LABEL_14;
}
strcpy(dest, "500 Syntax error, command unrecognized\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 13LL:
if ( a3 )
{
strcpy(dest, "502 ");
goto LABEL_14;
}
strcpy(dest, "502 Command not implemented\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 14LL:
if ( a3 )
{
strcpy(dest, "503 ");
goto LABEL_14;
}
strcpy(dest, "503 Bad sequence of commands\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 15LL:
if ( a3 )
{
strcpy(dest, "504 ");
goto LABEL_14;
}
strcpy(dest, "504 Command parameter not implemented\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 16LL:
if ( a3 )
{
strcpy(dest, "550 ");
goto LABEL_14;
}
strcpy(dest, "550 Requested action not taken: mailbox unavailable\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 17LL:
if ( a3 )
{
strcpy(dest, "551 ");
goto LABEL_14;
}
strcpy(dest, "551 User not local; please try next hop\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 18LL:
if ( a3 )
{
strcpy(dest, "552 ");
goto LABEL_14;
}
strcpy(dest, "552 Requested mail action aborted: exceeded storage allocation\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 19LL:
if ( a3 )
{
strcpy(dest, "553 ");
goto LABEL_14;
}
strcpy(dest, "553 Requested action not taken: mailbox name not allowed\r\n");
v9 = strlen(dest);
writen(a1, dest, v9);
return 0LL;
case 20LL:
if ( a3 )
{
strcpy(dest, "554 ");
goto LABEL_14;
}
strcpy(dest, "554 Transaction failed\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 21LL:
if ( a3 )
{
strcpy(dest, "555 ");
LABEL_14:
if ( a4 > 0x1F9 )
return 4294967293LL;
strncpy(&dest[4], a3, a4);
strcpy(&dest[a4 + 4], "\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
}
else
{
strcpy(dest, "555 MAIL FROM/RCPT TO parameters not recognized or not implemented\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
}
LABEL_16:
if ( v6 < 0 )
result = 4294967292LL;
else
result = 4 * (unsigned int)(v6 == v5) - 4;
return result;
default:
return 4294967293LL;
}
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1, __int64 a2, const char *a3, size_t a4)
{
__int64 v4; // rbp
size_t v5; // rbx
int v6; // eax
__int64 result; // rax
size_t v9; // rax
char dest[512]; // [rsp+0h] [rbp-318h] BYREF
char name[272]; // [rsp+200h] [rbp-118h] BYREF
__int64 v12; // [rsp+310h] [rbp-8h]

v12 = v4;
switch ( a2 )
{
case 0LL:
return 4294967293LL;
case 1LL:
if ( a3 )
{
strcpy(dest, "220 ");
goto LABEL_14;
}
strcpy(dest, "220 ");
memset(name, 0, 0x100uLL);
if ( gethostname(name, 0x100uLL) != -1 )
{
strncpy(&dest[4], name, 0x1F9uLL);
strcpy(&dest[strlen(name) + 4], " Service ready\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
}
return 4294967291LL;
case 2LL:
if ( a3 )
{
strcpy(dest, "221 ");
goto LABEL_14;
}
strcpy(dest, "221 closing connection, bye\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 3LL:
if ( a3 )
{
strcpy(dest, "250 ");
goto LABEL_14;
}
strcpy(dest, "250 OK\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 4LL:
if ( a3 )
{
strcpy(dest, "250-");
goto LABEL_14;
}
return 4294967293LL;
case 5LL:
if ( a3 )
{
strcpy(dest, "251 ");
goto LABEL_14;
}
strcpy(dest, "251 User not local; will forward to next hop\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 6LL:
if ( a3 )
{
strcpy(dest, "252 ");
goto LABEL_14;
}
strcpy(dest, "252 cannot VRFY user, but will accept message and attempt delivery\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 7LL:
if ( a3 )
{
strcpy(dest, "354 ");
goto LABEL_14;
}
strcpy(dest, "354 Start mail input; end with <CRLF>.<CRLF>\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 8LL:
if ( a3 )
{
strcpy(dest, "450 ");
goto LABEL_14;
}
strcpy(dest, "450 Requested mail action not taken: mailbox unavailable\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 9LL:
if ( a3 )
{
strcpy(dest, "451 ");
goto LABEL_14;
}
strcpy(dest, "451 Requested action aborted: local error in processing\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 10LL:
if ( a3 )
{
strcpy(dest, "452 ");
goto LABEL_14;
}
strcpy(dest, "452 requested action not taken: insufficient system storage\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 11LL:
if ( a3 )
{
strcpy(dest, "455 ");
goto LABEL_14;
}
strcpy(dest, "455 Server unable to accommodate parameters\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 12LL:
if ( a3 )
{
strcpy(dest, "500 ");
goto LABEL_14;
}
strcpy(dest, "500 Syntax error, command unrecognized\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 13LL:
if ( a3 )
{
strcpy(dest, "502 ");
goto LABEL_14;
}
strcpy(dest, "502 Command not implemented\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 14LL:
if ( a3 )
{
strcpy(dest, "503 ");
goto LABEL_14;
}
strcpy(dest, "503 Bad sequence of commands\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 15LL:
if ( a3 )
{
strcpy(dest, "504 ");
goto LABEL_14;
}
strcpy(dest, "504 Command parameter not implemented\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 16LL:
if ( a3 )
{
strcpy(dest, "550 ");
goto LABEL_14;
}
strcpy(dest, "550 Requested action not taken: mailbox unavailable\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 17LL:
if ( a3 )
{
strcpy(dest, "551 ");
goto LABEL_14;
}
strcpy(dest, "551 User not local; please try next hop\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 18LL:
if ( a3 )
{
strcpy(dest, "552 ");
goto LABEL_14;
}
strcpy(dest, "552 Requested mail action aborted: exceeded storage allocation\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 19LL:
if ( a3 )
{
strcpy(dest, "553 ");
goto LABEL_14;
}
strcpy(dest, "553 Requested action not taken: mailbox name not allowed\r\n");
v9 = strlen(dest);
writen(a1, dest, v9);
return 0LL;
case 20LL:
if ( a3 )
{
strcpy(dest, "554 ");
goto LABEL_14;
}
strcpy(dest, "554 Transaction failed\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
goto LABEL_16;
case 21LL:
if ( a3 )
{
strcpy(dest, "555 ");
LABEL_14:
if ( a4 > 0x1F9 )
return 4294967293LL;
strncpy(&dest[4], a3, a4);
strcpy(&dest[a4 + 4], "\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
}
else
{
strcpy(dest, "555 MAIL FROM/RCPT TO parameters not recognized or not implemented\r\n");
v5 = strlen(dest);
v6 = writen(a1, dest, v5);
}
LABEL_16:
if ( v6 < 0 )
result = 4294967292LL;
else
result = 4 * (unsigned int)(v6 == v5) - 4;
return result;
default:
return 4294967293LL;
}
}

original_code:
int smtp_send_reply (int sockfd, size_t code, const char *msg, size_t msg_len)
{
    int ret;
    size_t slen;
    char domain[256], rply_line[512];
    size_t pos = 0;
    switch (code) {
        case 1:
            if (((void *)0) == msg) {
                strcpy(rply_line, "220 ");
                pos = 4;
                memset(domain, 0, sizeof domain);
                if (-1 == gethostname(domain, sizeof domain))
                    return -5;
                strncpy(rply_line+pos, domain, (512 -7));
                pos += ((256) < (strlen(domain)) ? (256) : (strlen(domain)));
                strcpy(rply_line+pos, " Service ready\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "220 ");
            break;
        case 2:
            if (((void *)0) == msg) {
                strcpy(rply_line, "221 closing connection, bye\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "221 ");
            break;
        case 3:
            if (((void *)0) == msg) {
                strcpy(rply_line, "250 OK\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "250 ");
            break;
        case 4:
            if (((void *)0) == msg)
                return -3;
            else
                strcpy(rply_line, "250-");
            break;
        case 5:
            if (((void *)0) == msg) {
                strcpy(rply_line, "251 User not local; "
                                  "will forward to next hop\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "251 ");
            break;
        case 6:
            if (((void *)0) == msg) {
                strcpy(rply_line, "252 cannot VRFY user, but will "
                                  "accept message and attempt delivery\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "252 ");
            break;
        case 7:
            if (((void *)0) == msg) {
                strcpy(rply_line, "354 Start mail input; "
                                  "end with <CRLF>.<CRLF>\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "354 ");
            break;
        case 8:
            if (((void *)0) == msg) {
                strcpy(rply_line, "450 Requested mail action not taken: "
                                  "mailbox unavailable\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "450 ");
            break;
        case 9:
            if (((void *)0) == msg) {
                strcpy(rply_line, "451 Requested action aborted: "
                                  "local error in processing\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "451 ");
            break;
        case 10:
            if (((void *)0) == msg) {
                strcpy(rply_line, "452 requested action not taken: "
                                  "insufficient system storage\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "452 ");
            break;
        case 11:
            if (((void *)0) == msg) {
                strcpy(rply_line, "455 Server unable to accommodate "
                                  "parameters\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "455  ");
            break;
        case 12:
            if (((void *)0) == msg) {
                strcpy(rply_line, "500 Syntax error, command unrecognized\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "500 ");
            break;
        case 13:
            if (((void *)0) == msg) {
                strcpy(rply_line, "502 Command not implemented\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "502 ");
            break;
        case 14:
            if (((void *)0) == msg) {
                strcpy(rply_line, "503 Bad sequence of commands\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "503 ");
            break;
        case 15:
            if (((void *)0) == msg) {
                strcpy(rply_line, "504 Command parameter not implemented\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "504 ");
            break;
        case 16:
            if (((void *)0) == msg) {
                strcpy(rply_line, "550 Requested action not taken: "
                                  "mailbox unavailable\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "550 ");
            break;
        case 17:
            if (((void *)0) == msg) {
                strcpy(rply_line, "551 User not local; "
                                  "please try next hop\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "551 ");
            break;
        case 18:
            if (((void *)0) == msg) {
                strcpy(rply_line, "552 Requested mail action aborted: "
                                  "exceeded storage allocation\r\n");
                ret = writen(sockfd, rply_line, slen =strlen(rply_line));
            }
            else
                strcpy(rply_line, "552 ");
            break;
        case 19:
            if (((void *)0) == msg) {
                strcpy(rply_line, "553 Requested action not taken: "
                                  "mailbox name not allowed\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
                return 0;
            }
            else
                strcpy(rply_line, "553 ");
            break;
        case 20:
            if (((void *)0) == msg) {
                strcpy(rply_line, "554 Transaction failed\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "554 ");
            break;
        case 21:
            if (((void *)0) == msg) {
                strcpy(rply_line, "555 MAIL FROM/RCPT TO parameters not "
                                  "recognized or not implemented\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "555 ");
            break;
        default:
            return -3;
    }
    if (((void *)0) != msg) {
        pos = 4;
        if (msg_len > (512 -7))
            return -3;
        strncpy(rply_line+pos, msg, ((msg_len) < ((512 -7)) ? (msg_len) : ((512 -7))));
        pos += (((512 -7)) < (msg_len) ? ((512 -7)) : (msg_len));
        strcpy(rply_line+pos, "\r\n");
        ret = writen(sockfd, rply_line, slen = strlen(rply_line));
    }
    if (ret < 0 || (size_t) ret != slen)
        return -4;
    else
        return 0;
}

canonical_original_code:
int smtp_send_reply(int sockfd, unsigned long code, char *msg, unsigned long msg_len)
{
    int ret;
    unsigned long slen;
    char domain[256]; char rply_line[512];
    unsigned long pos = 0;
    switch (code) {
        case 1:
            if (((void *)0) == msg) {
                strcpy(rply_line, "220 ");
                pos = 4;
                memset(domain, 0, sizeof domain);
                if (-1 == gethostname(domain, sizeof domain))
                    return -5;
                strncpy(rply_line+pos, domain, (512 -7));
                pos += ((256) < (strlen(domain)) ? (256) : (strlen(domain)));
                strcpy(rply_line+pos, " Service ready\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "220 ");
            break;
        case 2:
            if (((void *)0) == msg) {
                strcpy(rply_line, "221 closing connection, bye\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "221 ");
            break;
        case 3:
            if (((void *)0) == msg) {
                strcpy(rply_line, "250 OK\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "250 ");
            break;
        case 4:
            if (((void *)0) == msg)
                return -3;
            else
                strcpy(rply_line, "250-");
            break;
        case 5:
            if (((void *)0) == msg) {
                strcpy(rply_line, "251 User not local; "
                                  "will forward to next hop\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "251 ");
            break;
        case 6:
            if (((void *)0) == msg) {
                strcpy(rply_line, "252 cannot VRFY user, but will "
                                  "accept message and attempt delivery\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "252 ");
            break;
        case 7:
            if (((void *)0) == msg) {
                strcpy(rply_line, "354 Start mail input; "
                                  "end with <CRLF>.<CRLF>\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "354 ");
            break;
        case 8:
            if (((void *)0) == msg) {
                strcpy(rply_line, "450 Requested mail action not taken: "
                                  "mailbox unavailable\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "450 ");
            break;
        case 9:
            if (((void *)0) == msg) {
                strcpy(rply_line, "451 Requested action aborted: "
                                  "local error in processing\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "451 ");
            break;
        case 10:
            if (((void *)0) == msg) {
                strcpy(rply_line, "452 requested action not taken: "
                                  "insufficient system storage\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "452 ");
            break;
        case 11:
            if (((void *)0) == msg) {
                strcpy(rply_line, "455 Server unable to accommodate "
                                  "parameters\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "455  ");
            break;
        case 12:
            if (((void *)0) == msg) {
                strcpy(rply_line, "500 Syntax error, command unrecognized\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "500 ");
            break;
        case 13:
            if (((void *)0) == msg) {
                strcpy(rply_line, "502 Command not implemented\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "502 ");
            break;
        case 14:
            if (((void *)0) == msg) {
                strcpy(rply_line, "503 Bad sequence of commands\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "503 ");
            break;
        case 15:
            if (((void *)0) == msg) {
                strcpy(rply_line, "504 Command parameter not implemented\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "504 ");
            break;
        case 16:
            if (((void *)0) == msg) {
                strcpy(rply_line, "550 Requested action not taken: "
                                  "mailbox unavailable\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "550 ");
            break;
        case 17:
            if (((void *)0) == msg) {
                strcpy(rply_line, "551 User not local; "
                                  "please try next hop\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "551 ");
            break;
        case 18:
            if (((void *)0) == msg) {
                strcpy(rply_line, "552 Requested mail action aborted: "
                                  "exceeded storage allocation\r\n");
                ret = writen(sockfd, rply_line, slen =strlen(rply_line));
            }
            else
                strcpy(rply_line, "552 ");
            break;
        case 19:
            if (((void *)0) == msg) {
                strcpy(rply_line, "553 Requested action not taken: "
                                  "mailbox name not allowed\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
                return 0;
            }
            else
                strcpy(rply_line, "553 ");
            break;
        case 20:
            if (((void *)0) == msg) {
                strcpy(rply_line, "554 Transaction failed\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "554 ");
            break;
        case 21:
            if (((void *)0) == msg) {
                strcpy(rply_line, "555 MAIL FROM/RCPT TO parameters not "
                                  "recognized or not implemented\r\n");
                ret = writen(sockfd, rply_line, slen = strlen(rply_line));
            }
            else
                strcpy(rply_line, "555 ");
            break;
        default:
            return -3;
    }
    if (((void *)0) != msg) {
        pos = 4;
        if (msg_len > (512 -7))
            return -3;
        strncpy(rply_line+pos, msg, ((msg_len) < ((512 -7)) ? (msg_len) : ((512 -7))));
        pos += (((512 -7)) < (msg_len) ? ((512 -7)) : (msg_len));
        strcpy(rply_line+pos, "\r\n");
        ret = writen(sockfd, rply_line, slen = strlen(rply_line));
    }
    if (ret < 0 || (unsigned long) ret != slen)
        return -4;
    else
        return 0;
}

variable_types:
code
unsigned long

variable_types:
msg
char *

return_type: int


decompiled_code:
__int64 __fastcall smtp_readline(int fd, _BYTE *a2, unsigned __int64 a3)
{
_BYTE *v3; // rbp
unsigned int v5; // ebx
_BOOL4 v6; // er12
int v7; // eax
_BYTE *v8; // rdx
char v9; // al
__int64 result; // rax
char v11[41]; // [rsp+Fh] [rbp-29h] BYREF

v3 = a2;
if ( a3 <= 1 )
{
v8 = a2;
v5 = 1;
LABEL_11:
*v8 = 0;
return v5;
}
v5 = 1;
v6 = 0;
while ( 1 )
{
v7 = buf_read(fd, v11);
if ( v7 != 1 )
break;
v8 = v3 + 1;
v9 = v11[0];
*v3 = v11[0];
if ( v6 && v9 == 10 )
{
v8 = v3 - 1;
goto LABEL_11;
}
v6 = v9 == 13;
if ( ++v5 >= a3 )
goto LABEL_11;
++v3;
}
if ( v7 )
return -1LL;
result = 0LL;
v8 = v3;
if ( v5 != 1 )
goto LABEL_11;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(int fd, _BYTE *a2, unsigned __int64 a3)
{
_BYTE *v3; // rbp
unsigned int v5; // ebx
_BOOL4 v6; // er12
int v7; // eax
_BYTE *v8; // rdx
char v9; // al
__int64 result; // rax
char v11[41]; // [rsp+Fh] [rbp-29h] BYREF

v3 = a2;
if ( a3 <= 1 )
{
v8 = a2;
v5 = 1;
LABEL_11:
*v8 = 0;
return v5;
}
v5 = 1;
v6 = 0;
while ( 1 )
{
v7 = func0(fd, v11);
if ( v7 != 1 )
break;
v8 = v3 + 1;
v9 = v11[0];
*v3 = v11[0];
if ( v6 && v9 == 10 )
{
v8 = v3 - 1;
goto LABEL_11;
}
v6 = v9 == 13;
if ( ++v5 >= a3 )
goto LABEL_11;
++v3;
}
if ( v7 )
return -1LL;
result = 0LL;
v8 = v3;
if ( v5 != 1 )
goto LABEL_11;
return result;
}

original_code:
ssize_t smtp_readline (int fd, void *vptr, size_t maxlen)
{
    int rc, state;
    unsigned int n;
    char c, *ptr;
    ptr = vptr;
    state = 0;
    for (n = 1; n < maxlen; n++) {
        if ( (rc = buf_read(fd, &c)) == 1) {
            *ptr++ = c;
            if (1 == state) {
                if (c == '\n') {
                    ptr -= 2;
                    break;
                }
                else
                    state = 0;
            }
            if (c == '\r')
                state = 1;
        }
        else if (rc == 0) {
            if (n == 1)
                return 0;
            else
                break;
        }
        else
            return -1;
    }
    *ptr = 0;
    return n;
}

canonical_original_code:
long smtp_readline(int fd, void *vptr, unsigned long maxlen)
{
    int rc; int state;
    unsigned int n;
    char c; char *ptr;
    ptr = vptr;
    state = 0;
    for (n = 1; n < maxlen; n++) {
        if ( (rc = buf_read(fd, &c)) == 1) {
            *ptr++ = c;
            if (1 == state) {
                if (c == '\n') {
                    ptr -= 2;
                    break;
                }
                else
                    state = 0;
            }
            if (c == '\r')
                state = 1;
        }
        else if (rc == 0) {
            if (n == 1)
                return 0;
            else
                break;
        }
        else
            return -1;
    }
    *ptr = 0;
    return n;
}

variable_types: fd int

variable_types:
vptr
void *

variable_types:
maxlen
unsigned long

variable_types: rc int

variable_types: state int

variable_types:
n
unsigned int

variable_types: c char

variable_types:
ptr
char *

return_type: long


decompiled_code:
__int64 __fastcall smtp_recv_command(int a1, __int64 a2)
{
size_t v2; // r13
unsigned int v3; // er12
char v5[6]; // [rsp+1h] [rbp-229h]
char v6[5]; // [rsp+2h] [rbp-228h] BYREF
char src[4]; // [rsp+7h] [rbp-223h] BYREF
char v8[2]; // [rsp+Bh] [rbp-21Fh] BYREF
char v9[541]; // [rsp+Dh] [rbp-21Dh] BYREF

if ( !a2 )
return (unsigned int)-1;
if ( smtp_readline(a1, v6, 0x200uLL) <= 0 )
return (unsigned int)-2;
*(_QWORD *)(a2 + 2) = 0LL;
*(_QWORD *)(a2 + 498) = 0LL;
memset(
(void *)((a2 + 10) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((_DWORD)a2 + 2 - (((_DWORD)a2 + 10) & 0xFFFFFFF8) + 504) >> 3));
v2 = strlen(v6);
if ( v2 <= 3 )
{
*(_WORD *)a2 = 0;
return 2;
}
v3 = strncasecmp("HELO ", v6, 5uLL);
if ( !v3 )
{
*(_WORD *)a2 = 2;
if ( v2 <= 5 )
return 1;
LABEL_9:
strncpy((char *)(a2 + 2), src, 0x100uLL);
return v3;
}
v3 = strncasecmp("EHLO ", v6, 5uLL);
if ( !v3 )
{
*(_WORD *)a2 = 1;
if ( v2 <= 5 )
return 1;
goto LABEL_9;
}
v3 = strncasecmp("MAIL FROM:", v6, 0xAuLL);
if ( !v3 )
{
*(_WORD *)a2 = 3;
if ( v2 <= 0xE )
return 1;
if ( v8[1] != 60 )
return 1;
if ( v5[v2] != 62 )
return 1;
v5[v2] = 0;
strncpy((char *)(a2 + 2), v9, 0x100uLL);
return v3;
}
v3 = strncasecmp("RCPT TO:", v6, 8uLL);
if ( v3 )
{
if ( v2 == 4 )
{
v3 = strncasecmp("DATA", v6, 4uLL);
if ( !v3 )
{
*(_WORD *)a2 = 5;
return v3;
}
v3 = strncasecmp("RSET", v6, 4uLL);
if ( !v3 )
{
*(_WORD *)a2 = 6;
return v3;
}
if ( strncasecmp("VRFY ", v6, 5uLL) )
{
if ( !strncasecmp("NOOP", v6, 4uLL) || !strncasecmp("NOOP ", v6, 5uLL) )
goto LABEL_29;
v3 = strncasecmp("QUIT", v6, 4uLL);
if ( !v3 )
{
*(_WORD *)a2 = 9;
return v3;
}
goto LABEL_35;
}
}
else if ( strncasecmp("VRFY ", v6, 5uLL) )
{
if ( !strncasecmp("NOOP ", v6, 5uLL) )
{
LABEL_29:
*(_WORD *)a2 = 8;
return 0;
}
LABEL_35:
*(_WORD *)a2 = 0;
strncpy((char *)(a2 + 2), v6, 0x200uLL);
return 2;
}
*(_WORD *)a2 = 7;
return 0;
}
*(_WORD *)a2 = 4;
if ( v2 <= 0xC )
return 1;
if ( src[3] != 60 )
return 1;
if ( v5[v2] != 62 )
return 1;
v5[v2] = 0;
strncpy((char *)(a2 + 2), v8, 0x100uLL);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1, __int64 a2)
{
size_t v2; // r13
unsigned int v3; // er12
char v5[6]; // [rsp+1h] [rbp-229h]
char v6[5]; // [rsp+2h] [rbp-228h] BYREF
char src[4]; // [rsp+7h] [rbp-223h] BYREF
char v8[2]; // [rsp+Bh] [rbp-21Fh] BYREF
char v9[541]; // [rsp+Dh] [rbp-21Dh] BYREF

if ( !a2 )
return (unsigned int)-1;
if ( func3(a1, v6, 0x200uLL) <= 0 )
return (unsigned int)-2;
*(_QWORD *)(a2 + 2) = 0LL;
*(_QWORD *)(a2 + 498) = 0LL;
memset(
(void *)((a2 + 10) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((_DWORD)a2 + 2 - (((_DWORD)a2 + 10) & 0xFFFFFFF8) + 504) >> 3));
v2 = strlen(v6);
if ( v2 <= 3 )
{
*(_WORD *)a2 = 0;
return 2;
}
v3 = strncasecmp("HELO ", v6, 5uLL);
if ( !v3 )
{
*(_WORD *)a2 = 2;
if ( v2 <= 5 )
return 1;
LABEL_9:
strncpy((char *)(a2 + 2), src, 0x100uLL);
return v3;
}
v3 = strncasecmp("EHLO ", v6, 5uLL);
if ( !v3 )
{
*(_WORD *)a2 = 1;
if ( v2 <= 5 )
return 1;
goto LABEL_9;
}
v3 = strncasecmp("MAIL FROM:", v6, 0xAuLL);
if ( !v3 )
{
*(_WORD *)a2 = 3;
if ( v2 <= 0xE )
return 1;
if ( v8[1] != 60 )
return 1;
if ( v5[v2] != 62 )
return 1;
v5[v2] = 0;
strncpy((char *)(a2 + 2), v9, 0x100uLL);
return v3;
}
v3 = strncasecmp("RCPT TO:", v6, 8uLL);
if ( v3 )
{
if ( v2 == 4 )
{
v3 = strncasecmp("DATA", v6, 4uLL);
if ( !v3 )
{
*(_WORD *)a2 = 5;
return v3;
}
v3 = strncasecmp("RSET", v6, 4uLL);
if ( !v3 )
{
*(_WORD *)a2 = 6;
return v3;
}
if ( strncasecmp("VRFY ", v6, 5uLL) )
{
if ( !strncasecmp("NOOP", v6, 4uLL) || !strncasecmp("NOOP ", v6, 5uLL) )
goto LABEL_29;
v3 = strncasecmp("QUIT", v6, 4uLL);
if ( !v3 )
{
*(_WORD *)a2 = 9;
return v3;
}
goto LABEL_35;
}
}
else if ( strncasecmp("VRFY ", v6, 5uLL) )
{
if ( !strncasecmp("NOOP ", v6, 5uLL) )
{
LABEL_29:
*(_WORD *)a2 = 8;
return 0;
}
LABEL_35:
*(_WORD *)a2 = 0;
strncpy((char *)(a2 + 2), v6, 0x200uLL);
return 2;
}
*(_WORD *)a2 = 7;
return 0;
}
*(_WORD *)a2 = 4;
if ( v2 <= 0xC )
return 1;
if ( src[3] != 60 )
return 1;
if ( v5[v2] != 62 )
return 1;
v5[v2] = 0;
strncpy((char *)(a2 + 2), v8, 0x100uLL);
return v3;
}

original_code:
int smtp_recv_command (int sockfd, struct smtp_command *cmd)
{
    size_t len;
    char line[512];
    if (((void *)0) == cmd)
        return -1;
    if (smtp_readline(sockfd, line, 512) <= 0)
        return -2;
    memset(cmd->data, 0, sizeof(cmd->data));
    if ((len = strlen(line)) < 4) {
        cmd->code = 0;
        return 2;
    }
    if (0 == strncasecmp("HELO ", line, 5)) {
        cmd->code = 2;
        if (len < 6)
            return 1;
        strncpy(cmd->data, line+5, 256);
    }
    else if (0 == strncasecmp("EHLO ", line, 5)) {
        cmd->code = 1;
        if (len < 6)
            return 1;
        strncpy(cmd->data, line+5, 256);
    }
    else if (0 == strncasecmp("MAIL FROM:", line, 10)) {
        cmd->code = 3;
        if (len < 15 || '<' != line[10] || '>' != line[len-1])
            return 1;
        line[len-1] = '\0';
        strncpy(cmd->data, line+11, 256);
    }
    else if (0 == strncasecmp("RCPT TO:", line, 8)) {
        cmd->code = 4;
        if (len < 13 || '<' != line[8] || '>' != line[len-1])
            return 1;
        line[len-1] = '\0';
        strncpy(cmd->data, line+9, 256);
    }
    else if (4 == len && 0 == strncasecmp("DATA", line, 4))
        cmd->code = 5;
    else if (4 == len && 0 == strncasecmp("RSET", line, 4))
        cmd->code = 6;
    else if (0 == strncasecmp("VRFY ", line, 5))
        cmd->code = 7;
    else if ( (4 == len && 0 == strncasecmp("NOOP", line, 4))
            || 0 == strncasecmp("NOOP ", line, 5) )
        cmd->code = 8;
    else if (4 == len && 0 == strncasecmp("QUIT", line, 4))
        cmd->code = 9;
    else {
        cmd->code = 0;
        strncpy(cmd->data, line, 512);
        return 2;
    }
    return 0;
}

canonical_original_code:
int smtp_recv_command(int sockfd, struct smtp_command *cmd)
{
    unsigned long len;
    char line[512];
    if (((void *)0) == cmd)
        return -1;
    if (smtp_readline(sockfd, line, 512) <= 0)
        return -2;
    memset(cmd->data, 0, sizeof(cmd->data));
    if ((len = strlen(line)) < 4) {
        cmd->code = 0;
        return 2;
    }
    if (0 == strncasecmp("HELO ", line, 5)) {
        cmd->code = 2;
        if (len < 6)
            return 1;
        strncpy(cmd->data, line+5, 256);
    }
    else if (0 == strncasecmp("EHLO ", line, 5)) {
        cmd->code = 1;
        if (len < 6)
            return 1;
        strncpy(cmd->data, line+5, 256);
    }
    else if (0 == strncasecmp("MAIL FROM:", line, 10)) {
        cmd->code = 3;
        if (len < 15 || '<' != line[10] || '>' != line[len-1])
            return 1;
        line[len-1] = '\0';
        strncpy(cmd->data, line+11, 256);
    }
    else if (0 == strncasecmp("RCPT TO:", line, 8)) {
        cmd->code = 4;
        if (len < 13 || '<' != line[8] || '>' != line[len-1])
            return 1;
        line[len-1] = '\0';
        strncpy(cmd->data, line+9, 256);
    }
    else if (4 == len && 0 == strncasecmp("DATA", line, 4))
        cmd->code = 5;
    else if (4 == len && 0 == strncasecmp("RSET", line, 4))
        cmd->code = 6;
    else if (0 == strncasecmp("VRFY ", line, 5))
        cmd->code = 7;
    else if ( (4 == len && 0 == strncasecmp("NOOP", line, 4))
            || 0 == strncasecmp("NOOP ", line, 5) )
        cmd->code = 8;
    else if (4 == len && 0 == strncasecmp("QUIT", line, 4))
        cmd->code = 9;
    else {
        cmd->code = 0;
        strncpy(cmd->data, line, 512);
        return 2;
    }
    return 0;
}

variable_types: struct smtp_command { unsigned short code; char data[-1]; } *

variable_types:
len
unsigned long

variable_types:
line
char [512]


original_code:
int smtp_recv_reply (int sockfd, struct smtp_reply *rply)
{
    char line[512];
    if (((void *)0) == rply)
        return -1;
    if (smtp_readline(sockfd, line, 512) <= 0)
        return -2;
    memset(rply, 0, sizeof(*rply));
    if (0 == strncmp("220", line, 3))
        rply->code = 1;
    else if (0 == strncmp("221", line, 3))
        rply->code = 2;
    else if (0 == strncmp("250-", line, 4))
        rply->code = 4;
    else if (0 == strncmp("250", line, 3))
        rply->code = 3;
    else if (0 == strncmp("251", line, 3))
        rply->code = 5;
    else if (0 == strncmp("252", line, 3))
        rply->code = 6;
    else if (0 == strncmp("354", line, 3))
        rply->code = 7;
    else if (0 == strncmp("450", line, 3))
        rply->code = 8;
    else if (0 == strncmp("451", line, 3))
        rply->code = 9;
    else if (0 == strncmp("452", line, 3))
        rply->code = 10;
    else if (0 == strncmp("455", line, 3))
        rply->code = 11;
    else if (0 == strncmp("500", line, 3))
        rply->code = 12;
    else if (0 == strncmp("502", line, 3))
        rply->code = 13;
    else if (0 == strncmp("503", line, 3))
        rply->code = 14;
    else if (0 == strncmp("504", line, 3))
        rply->code = 15;
    else if (0 == strncmp("550", line, 3))
        rply->code = 16;
    else if (0 == strncmp("551", line, 3))
        rply->code = 17;
    else if (0 == strncmp("552", line, 3))
        rply->code = 18;
    else if (0 == strncmp("553", line, 3))
        rply->code = 19;
    else if (0 == strncmp("554", line, 3))
        rply->code = 20;
    else if (0 == strncmp("555", line, 3))
        rply->code = 21;
    else {
        rply->code = 0;
        strncpy(rply->msg, line, (512 -7));
        return 3;
    }
    if (strlen(line) > 4)
        strncpy(rply->msg, line+4, (512 -7));
    return 0;
}

canonical_original_code:
int smtp_recv_reply(int sockfd, struct smtp_reply *rply)
{
    char line[512];
    if (((void *)0) == rply)
        return -1;
    if (smtp_readline(sockfd, line, 512) <= 0)
        return -2;
    memset(rply, 0, sizeof(*rply));
    if (0 == strncmp("220", line, 3))
        rply->code = 1;
    else if (0 == strncmp("221", line, 3))
        rply->code = 2;
    else if (0 == strncmp("250-", line, 4))
        rply->code = 4;
    else if (0 == strncmp("250", line, 3))
        rply->code = 3;
    else if (0 == strncmp("251", line, 3))
        rply->code = 5;
    else if (0 == strncmp("252", line, 3))
        rply->code = 6;
    else if (0 == strncmp("354", line, 3))
        rply->code = 7;
    else if (0 == strncmp("450", line, 3))
        rply->code = 8;
    else if (0 == strncmp("451", line, 3))
        rply->code = 9;
    else if (0 == strncmp("452", line, 3))
        rply->code = 10;
    else if (0 == strncmp("455", line, 3))
        rply->code = 11;
    else if (0 == strncmp("500", line, 3))
        rply->code = 12;
    else if (0 == strncmp("502", line, 3))
        rply->code = 13;
    else if (0 == strncmp("503", line, 3))
        rply->code = 14;
    else if (0 == strncmp("504", line, 3))
        rply->code = 15;
    else if (0 == strncmp("550", line, 3))
        rply->code = 16;
    else if (0 == strncmp("551", line, 3))
        rply->code = 17;
    else if (0 == strncmp("552", line, 3))
        rply->code = 18;
    else if (0 == strncmp("553", line, 3))
        rply->code = 19;
    else if (0 == strncmp("554", line, 3))
        rply->code = 20;
    else if (0 == strncmp("555", line, 3))
        rply->code = 21;
    else {
        rply->code = 0;
        strncpy(rply->msg, line, (512 -7));
        return 3;
    }
    if (strlen(line) > 4)
        strncpy(rply->msg, line+4, (512 -7));
    return 0;
}

variable_types: sockfd int

variable_types: struct smtp_reply { unsigned short code; char msg[-1]; } *


Calloc

decompiled_code:
void *__fastcall Calloc(size_t a1, size_t a2)
{
void *v2; // rbx

v2 = calloc(a1, a2);
if ( !v2 )
err_sys("calloc error");
return v2;
}

canonical_decompiled_code:
void *__fastcall func0(size_t a1, size_t a2)
{
void *v2; // rbx

v2 = calloc(a1, a2);
if ( !v2 )
err_sys("calloc error");
return v2;
}

original_code:
void *Calloc (size_t n, size_t size)
{
    void *ptr;
    if ( (ptr = calloc(n, size)) == ((void *)0))
        err_sys("calloc error");
    return ptr;
}

canonical_original_code:
void *Calloc(unsigned long n, unsigned long size)
{
    void *ptr;
    if ( (ptr = calloc(n, size)) == ((void *)0))
        err_sys("calloc error");
    return ptr;
}

variable_types:
n
unsigned long

variable_types:
size
unsigned long

variable_types:
ptr
void *

return_type: void *


Close

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

result = close(a1);
if ( result == -1 )
result = err_sys("close error");
return result;
}

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

result = close(a1);
if ( result == -1 )
result = err_sys("close error");
return result;
}

original_code:
void Close (int fd)
{
    if (close(fd) == -1)
        err_sys("close error");
}

canonical_original_code:
void Close(int fd)
{
    if (close(fd) == -1)
        err_sys("close error");
}

return_type: void


Fork

decompiled_code:
__int64 Fork()
{
unsigned int v0; // ebx

v0 = fork();
if ( v0 == -1 )
err_sys("fork error");
return v0;
}

canonical_decompiled_code:
__int64 func2()
{
unsigned int v0; // ebx

v0 = fork();
if ( v0 == -1 )
err_sys("fork error");
return v0;
}

original_code:
pid_t Fork(void)
{
    pid_t pid;
    if ( (pid = fork()) == -1)
        err_sys("fork error");
    return pid;
}

canonical_original_code:
int Fork()
{
    int pid;
    if ( (pid = fork()) == -1)
        err_sys("fork error");
    return pid;
}

variable_types: pid int


Malloc

decompiled_code:
void *__fastcall Malloc(size_t a1)
{
void *v1; // rbx

v1 = malloc(a1);
if ( !v1 )
err_sys("malloc error");
return v1;
}

canonical_decompiled_code:
void *__fastcall func3(size_t a1)
{
void *v1; // rbx

v1 = malloc(a1);
if ( !v1 )
err_sys("malloc error");
return v1;
}

original_code:
void *Malloc (size_t size)
{
    void *ptr;
    if ( (ptr = malloc(size)) == ((void *)0))
        err_sys("malloc error");
    return ptr;
}

canonical_original_code:
void *Malloc(unsigned long size)
{
    void *ptr;
    if ( (ptr = malloc(size)) == ((void *)0))
        err_sys("malloc error");
    return ptr;
}


Bind

decompiled_code:
int __fastcall Bind(int a1, const struct sockaddr *a2, socklen_t a3)
{
int result; // eax

result = bind(a1, a2, a3);
if ( result < 0 )
result = err_sys("bind error");
return result;
}

canonical_decompiled_code:
int __fastcall func0(int a1, const struct sockaddr *a2, socklen_t a3)
{
int result; // eax

result = bind(a1, a2, a3);
if ( result < 0 )
result = err_sys("bind error");
return result;
}

original_code:
void Bind (int fd, const struct sockaddr *sa, socklen_t salen)
{
    if (bind(fd, sa, salen) < 0)
        err_sys("bind error");
}

canonical_original_code:
void Bind(int fd, struct sockaddr *sa, unsigned int salen)
{
    if (bind(fd, sa, salen) < 0)
        err_sys("bind error");
}

variable_types: fd int

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

variable_types:
salen
unsigned int


Connect

decompiled_code:
int __fastcall Connect(int a1, const struct sockaddr *a2, socklen_t a3)
{
int result; // eax

result = connect(a1, a2, a3);
if ( result < 0 )
result = err_sys("connect error");
return result;
}

canonical_decompiled_code:
int __fastcall func1(int a1, const struct sockaddr *a2, socklen_t a3)
{
int result; // eax

result = connect(a1, a2, a3);
if ( result < 0 )
result = err_sys("connect error");
return result;
}

original_code:
void Connect (int fd, const struct sockaddr *sa, socklen_t salen)
{
    if (connect(fd, sa, salen) < 0)
        err_sys("connect error");
}

canonical_original_code:
void Connect(int fd, struct sockaddr *sa, unsigned int salen)
{
    if (connect(fd, sa, salen) < 0)
        err_sys("connect error");
}

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


Listen

decompiled_code:
int __fastcall Listen(int fd, int n)
{
char *v3; // rax
int result; // eax

v3 = getenv("LISTENQ");
if ( v3 )
n = atoi(v3);
result = listen(fd, n);
if ( result < 0 )
result = err_sys("listen error");
return result;
}

canonical_decompiled_code:
int __fastcall func2(int fd, int n)
{
char *v3; // rax
int result; // eax

v3 = getenv("LISTENQ");
if ( v3 )
n = atoi(v3);
result = listen(fd, n);
if ( result < 0 )
result = err_sys("listen error");
return result;
}

original_code:
void Listen (int fd, int backlog)
{
    char *ptr;
    if ( (ptr = getenv("LISTENQ")) != ((void *)0))
        backlog = atoi(ptr);
    if (listen(fd, backlog) < 0)
        err_sys("listen error");
}

canonical_original_code:
void Listen(int fd, int backlog)
{
    char *ptr;
    if ( (ptr = getenv("LISTENQ")) != ((void *)0))
        backlog = atoi(ptr);
    if (listen(fd, backlog) < 0)
        err_sys("listen error");
}

variable_types: backlog int


Socket

decompiled_code:
__int64 __fastcall Socket(int a1, int a2, int a3)
{
int v3; // ebx

v3 = socket(a1, a2, a3);
if ( v3 < 0 )
err_sys("socket error");
return (unsigned int)v3;
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1, int a2, int a3)
{
int v3; // ebx

v3 = socket(a1, a2, a3);
if ( v3 < 0 )
err_sys("socket error");
return (unsigned int)v3;
}

original_code:
int Socket (int family, int type, int protocol)
{
    int n;
    if ( (n = socket(family, type, protocol)) < 0)
        err_sys("socket error");
    return n;
}

canonical_original_code:
int Socket(int family, int type, int protocol)
{
    int n;
    if ( (n = socket(family, type, protocol)) < 0)
        err_sys("socket error");
    return n;
}

variable_types: family int

variable_types: type int

variable_types: protocol int

variable_types: n int


signal

decompiled_code:
__int64 __fastcall signal(int sig, void (*a2)(int))
{
int v2; // eax
bool v3; // sf
__int64 result; // rax
struct sigaction v5; // [rsp+0h] [rbp-148h] BYREF
struct sigaction v6; // [rsp+A0h] [rbp-A8h] BYREF

v6.sa_handler = a2;
sigemptyset(&v6.sa_mask);
v2 = 0x20000000;
if ( sig != 14 )
v2 = 0x10000000;
v6.sa_flags = v2;
v3 = sigaction(sig, &v6, &v5) < 0;
result = -1LL;
if ( !v3 )
result = (__int64)v5.sa_handler;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int sig, void (*a2)(int))
{
int v2; // eax
bool v3; // sf
__int64 result; // rax
struct sigaction v5; // [rsp+0h] [rbp-148h] BYREF
struct sigaction v6; // [rsp+A0h] [rbp-A8h] BYREF

v6.sa_handler = a2;
sigemptyset(&v6.sa_mask);
v2 = 0x20000000;
if ( sig != 14 )
v2 = 0x10000000;
v6.sa_flags = v2;
v3 = sigaction(sig, &v6, &v5) < 0;
result = -1LL;
if ( !v3 )
result = (__int64)v5.sa_handler;
return result;
}

original_code:
Sigfunc *signal (int signo, Sigfunc *func)
{
    struct sigaction act, oact;
    act.__sigaction_handler.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (signo == 14) {
        act.sa_flags |= 0x20000000;
    }
    else {
        act.sa_flags |= 0x10000000;
    }
    if (sigaction(signo, &act, &oact) < 0)
        return ((__sighandler_t) -1);
    return oact.__sigaction_handler.sa_handler;
}

canonical_original_code:
void (*signal(int signo, void (*func)(int)))(int)
{
    struct sigaction act; struct sigaction oact;
    act.__sigaction_handler.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (signo == 14) {
        act.sa_flags |= 0x20000000;
    }
    else {
        act.sa_flags |= 0x10000000;
    }
    if (sigaction(signo, &act, &oact) < 0)
        return ((__sighandler_t) -1);
    return oact.__sigaction_handler.sa_handler;
}

variable_types: signo int

variable_types:
func
void (*)(int)

variable_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval { int sival_int; void *sival_ptr; } si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; } *, void *); } __sigaction_handler; struct __sigset_t { unsigned long __val[-1]; } sa_mask; int sa_flags; void (*sa_restorer)(); }

return_type: void (*)(int)

user_defined_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t *, void *); } __sigaction_handler; struct __sigset_t sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; }


Signal

decompiled_code:
__int64 __fastcall Signal(int a1, void (*a2)(int))
{
__int64 v2; // rbx

v2 = signal(a1, a2);
if ( v2 == -1 )
err_sys("signal error");
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, void (*a2)(int))
{
__int64 v2; // rbx

v2 = func0(a1, a2);
if ( v2 == -1 )
err_sys("signal error");
return v2;
}

original_code:
Sigfunc *Signal (int signo, Sigfunc *func)
{
    Sigfunc *sigfunc;
    if ( (sigfunc = signal(signo, func)) == ((__sighandler_t) -1))
        err_sys("signal error");
    return sigfunc;
}

canonical_original_code:
void (*Signal(int signo, void (*func)(int)))(int)
{
    void (*sigfunc)(int);
    if ( (sigfunc = signal(signo, func)) == ((__sighandler_t) -1))
        err_sys("signal error");
    return sigfunc;
}

variable_types:
sigfunc
void (*)(int)


decompiled_code:
__pid_t sig_chld()
{
__pid_t result; // eax
int stat_loc[3]; // [rsp+Ch] [rbp-Ch] BYREF

while ( 1 )
{
result = waitpid(-1, stat_loc, 1);
if ( result <= 0 )
break;
--sproc_counter;
}
return result;
}

canonical_decompiled_code:
__pid_t func2()
{
__pid_t result; // eax
int stat_loc[3]; // [rsp+Ch] [rbp-Ch] BYREF

while ( 1 )
{
result = waitpid(-1, stat_loc, 1);
if ( result <= 0 )
break;
--sproc_counter;
}
return result;
}

original_code:
void sig_chld (int signo __attribute__((__unused__)))
{
    pid_t pid;
    int stat;
    while ( (pid = waitpid(-1, &stat, 1)) > 0) {
        --sproc_counter;
    }
    return;
}

canonical_original_code:
void sig_chld(int signo)
{
    int pid;
    int stat;
    while ( (pid = waitpid(-1, &stat, 1)) > 0) {
        --sproc_counter;
    }
    return;
}

variable_types: stat int


original_code:
void free_mail_object (struct mail_object *mail)
{
    unsigned int i;
    if (((void *)0) != mail->mail_from) {
        free(mail->mail_from);
        mail->mail_from = ((void *)0);
    }
    if (((void *)0) != mail->rcpt_to) {
        for (i = 0; i < mail->no_rcpt; ++i) {
            if (((void *)0) != mail->rcpt_to[i])
                free(mail->rcpt_to[i]);
        }
        free(mail->rcpt_to);
        mail->rcpt_to = ((void *)0);
    }
    if (((void *)0) != mail->data)
        free(mail->data);
    memset(mail, 0, sizeof(struct mail_object));
}

canonical_original_code:
void free_mail_object(struct mail_object *mail)
{
    unsigned int i;
    if (((void *)0) != mail->mail_from) {
        free(mail->mail_from);
        mail->mail_from = ((void *)0);
    }
    if (((void *)0) != mail->rcpt_to) {
        for (i = 0; i < mail->no_rcpt; ++i) {
            if (((void *)0) != mail->rcpt_to[i])
                free(mail->rcpt_to[i]);
        }
        free(mail->rcpt_to);
        mail->rcpt_to = ((void *)0);
    }
    if (((void *)0) != mail->data)
        free(mail->data);
    memset(mail, 0, sizeof(struct mail_object));
}

variable_types: struct mail_object { char *mail_from; char **rcpt_to; unsigned long no_rcpt; char *data; unsigned long data_size; } *

variable_types:
i
unsigned int


decompiled_code:
void __fastcall print_mail_object(__int64 a1)
{
unsigned int v1; // ebp
__int64 v2; // rax

if ( a1 )
{
fwrite("=== MAIL OBJECT ===\n", 1uLL, 0x14uLL, stderr);
fprintf(stderr, "FROM: %s\n", *(const char **)a1);
if ( *(_QWORD *)(a1 + 16) )
{
v1 = 0;
v2 = 0LL;
do
{
fprintf(stderr, "TO: %s\n", *(const char **)(*(_QWORD *)(a1 + 8) + 8 * v2));
v2 = ++v1;
}
while ( (unsigned __int64)v1 < *(_QWORD *)(a1 + 16) );
}
fprintf(
stderr,
"\nDATA (size: %u octets)\n%s=== END OF MAIL ===\n",
*(_QWORD *)(a1 + 32),
*(const char **)(a1 + 24));
}
}

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

if ( a1 )
{
fwrite("=== MAIL OBJECT ===\n", 1uLL, 0x14uLL, stderr);
fprintf(stderr, "FROM: %s\n", *(const char **)a1);
if ( *(_QWORD *)(a1 + 16) )
{
v1 = 0;
v2 = 0LL;
do
{
fprintf(stderr, "TO: %s\n", *(const char **)(*(_QWORD *)(a1 + 8) + 8 * v2));
v2 = ++v1;
}
while ( (unsigned __int64)v1 < *(_QWORD *)(a1 + 16) );
}
fprintf(
stderr,
"\nDATA (size: %u octets)\n%s=== END OF MAIL ===\n",
*(_QWORD *)(a1 + 32),
*(const char **)(a1 + 24));
}
}

original_code:
void print_mail_object (struct mail_object *mail)
{
    unsigned int i;
    if (((void *)0) == mail)
        return;
    fprintf(stderr, "=== MAIL OBJECT ===\n");
    fprintf(stderr, "FROM: %s\n", mail->mail_from);
    for (i = 0; i < mail->no_rcpt; ++i)
        fprintf(stderr, "TO:   %s\n", mail->rcpt_to[i]);
    fprintf(stderr, "\nDATA (size: %u octets)\n%s=== END OF MAIL ===\n",
            (unsigned int)mail->data_size, mail->data);
}

canonical_original_code:
void print_mail_object(struct mail_object *mail)
{
    unsigned int i;
    if (((void *)0) == mail)
        return;
    fprintf(stderr, "=== MAIL OBJECT ===\n");
    fprintf(stderr, "FROM: %s\n", mail->mail_from);
    for (i = 0; i < mail->no_rcpt; ++i)
        fprintf(stderr, "TO:   %s\n", mail->rcpt_to[i]);
    fprintf(stderr, "\nDATA (size: %u octets)\n%s=== END OF MAIL ===\n",
            (unsigned int)mail->data_size, mail->data);
}


daemonize

decompiled_code:
void __fastcall daemonize(char *ident, int facility)
{
int v2; // ebx

if ( (unsigned int)Fork() )
exit(0);
setsid();
Signal(1LL, 1LL);
v2 = Fork();
if ( v2 )
exit(0);
daemon_proc = 1;
chdir("/");
umask(0);
do
close(v2++);
while ( v2 != 64 );
openlog(ident, 1, facility);
}

canonical_decompiled_code:
void __fastcall func0(char *ident, int facility)
{
int v2; // ebx

if ( (unsigned int)Fork() )
exit(0);
setsid();
Signal(1LL, 1LL);
v2 = Fork();
if ( v2 )
exit(0);
daemon_proc = 1;
chdir("/");
umask(0);
do
close(v2++);
while ( v2 != 64 );
openlog(ident, 1, facility);
}

original_code:
void daemonize (const char *pname, int facility)
{
    int i;
    pid_t pid;
    if ( (pid = Fork()) != 0)
        exit(0);
    setsid();
    Signal(1, ((__sighandler_t) 1));
    if ( (pid = Fork()) != 0)
        exit(0);
    daemon_proc = 1;
    chdir("/");
    umask(0);
    for (i = 0; i < 64; ++i)
        close(i);
    openlog(pname, 0x01, facility);
}

canonical_original_code:
void daemonize(char *pname, int facility)
{
    int i;
    int pid;
    if ( (pid = Fork()) != 0)
        exit(0);
    setsid();
    Signal(1, ((void (*)(int)) 1));
    if ( (pid = Fork()) != 0)
        exit(0);
    daemon_proc = 1;
    chdir("/");
    umask(0);
    for (i = 0; i < 64; ++i)
        close(i);
    openlog(pname, 0x01, facility);
}

variable_types:
pname
char *

variable_types: facility int

variable_types: i int


repo: tracymacding/GtmyMusic

decompiled_code:
__int64 __fastcall send_response(int fd, __int64 a2, int a3)
{
int v3; // edx
__int64 result; // rax

if ( fd <= 0 )
_assert_fail("fd > 0", "main.c", 0x40u, "send_response");
if ( !a2 )
_assert_fail("res != NULL", "main.c", 0x41u, "send_response");
*(_DWORD *)a2 = a3;
v3 = send_data(fd, a2, 8);
result = 0LL;
if ( v3 == 1 )
result = send_data(fd, *(_QWORD *)(a2 + 8), *(_DWORD *)(a2 + 4));
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int fd, __int64 a2, int a3)
{
int v3; // edx
__int64 result; // rax

if ( fd <= 0 )
_assert_fail("fd > 0", "main.c", 0x40u, "send_response");
if ( !a2 )
_assert_fail("res != NULL", "main.c", 0x41u, "send_response");
*(_DWORD *)a2 = a3;
v3 = func0(fd, a2, 8);
result = 0LL;
if ( v3 == 1 )
result = func0(fd, *(_QWORD *)(a2 + 8), *(_DWORD *)(a2 + 4));
return result;
}

original_code:
static int send_response(int fd, struct response *res, int error_code)
{
 ((void) sizeof ((fd > 0) ? 1 : 0), __extension__ ({ if (fd > 0) ; else __assert_fail ("fd > 0", "main.c", 64, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((res != ((void *)0)) ? 1 : 0), __extension__ ({ if (res != ((void *)0)) ; else __assert_fail ("res != NULL", "main.c", 65, __extension__ __PRETTY_FUNCTION__); }));
 res->header.status = error_code;
 if(send_data(fd, &(res->header), sizeof(res->header)) != 1)
  return 0;
 return send_data(fd, res->data, res->header.data_size);
}

variable_types: fd int

variable_types: struct response { struct response_header { int status; int data_size; } header; void *data; } *

user_defined_types: struct response { struct response_header header; void *data; }


decompiled_code:
void *__fastcall thread_loop(void *a1)
{
unsigned int v1; // ebx
int v2; // ebp
__int64 v4; // [rsp+0h] [rbp-38h] BYREF
void *v5; // [rsp+8h] [rbp-30h]
__int64 v6; // [rsp+10h] [rbp-28h] BYREF
void *ptr; // [rsp+18h] [rbp-20h]

v1 = *(_DWORD *)a1;
printf("fd = %d\n", *(unsigned int *)a1);
if ( !g_shutdown )
{
v2 = 200;
do
{
v6 = 0LL;
ptr = 0LL;
v4 = 0LL;
v5 = 0LL;
if ( (unsigned int)read_command(v1, &v6) )
{
if ( (_DWORD)v6 == 3 )
break;
if ( !(unsigned int)process_command(&v6, &v4) )
{
puts("Process command failed");
v2 = 400;
}
}
else
{
printf("Read command failed on %d\n", v1);
v2 = 400;
}
if ( !(unsigned int)send_response(v1, (__int64)&v4, v2) )
printf("Send response failed on fd %d\n", v1);
if ( ptr )
free(ptr);
if ( v5 )
free(v5);
}
while ( !g_shutdown );
}
close(v1);
if ( ptr )
free(ptr);
if ( v5 )
free(v5);
*((_DWORD *)a1 + 1) = 0;
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func2(void *a1)
{
unsigned int v1; // ebx
int v2; // ebp
__int64 v4; // [rsp+0h] [rbp-38h] BYREF
void *v5; // [rsp+8h] [rbp-30h]
__int64 v6; // [rsp+10h] [rbp-28h] BYREF
void *ptr; // [rsp+18h] [rbp-20h]

v1 = *(_DWORD *)a1;
printf("fd = %d\n", *(unsigned int *)a1);
if ( !g_shutdown )
{
v2 = 200;
do
{
v6 = 0LL;
ptr = 0LL;
v4 = 0LL;
v5 = 0LL;
if ( (unsigned int)read_command(v1, &v6) )
{
if ( (_DWORD)v6 == 3 )
break;
if ( !(unsigned int)process_command(&v6, &v4) )
{
puts("Process command failed");
v2 = 400;
}
}
else
{
printf("Read command failed on %d\n", v1);
v2 = 400;
}
if ( !(unsigned int)func1(v1, (__int64)&v4, v2) )
printf("Send response failed on fd %d\n", v1);
if ( ptr )
free(ptr);
if ( v5 )
free(v5);
}
while ( !g_shutdown );
}
close(v1);
if ( ptr )
free(ptr);
if ( v5 )
free(v5);
*((_DWORD *)a1 + 1) = 0;
return 0LL;
}

original_code:
static void *thread_loop(void *arg)
{
 struct thread *t = (thread_t *)arg;
 struct command cmd;
 struct response res;
 int error_code = 200;
 int fd = t->fd;
 printf("fd = %d\n", fd);
 while(!g_shutdown) {
  memset(&cmd, 0, sizeof(cmd));
  memset(&res, 0, sizeof(res));
  if(read_command(fd, &cmd) == 0) {
   printf("Read command failed on %d\n", fd);
   error_code = 400;
   goto send_response;
  }
  if(cmd.header.type == 3)
    break;
  if(process_command(&cmd, &res) == 0) {
   printf("Process command failed\n");
   error_code = 400;
   goto send_response;
  }
send_response:
  if(send_response(fd, &res, error_code) == 0) {
   printf("Send response failed on fd %d\n", fd);
  }
  if(cmd.data != ((void *)0))
   free(cmd.data);
  if(res.data != ((void *)0))
   free(res.data);
 }
 close(fd);
 if(cmd.data != ((void *)0))
  free(cmd.data);
 if(res.data != ((void *)0))
  free(res.data);
 t->running = 0;
 return ((void *)0);
}

variable_types:
arg
void *

variable_types: struct thread { int fd; int running; unsigned long pid; struct thread *next; } *

variable_types: struct command { struct command_header { int type; int data_size; } header; void *data; }

variable_types: struct response { struct response_header { int status; int data_size; } header; void *data; }

user_defined_types: struct command { struct command_header header; void *data; }


decompiled_code:
__int64 __fastcall send_data(int fd, __int64 a2, int a3)
{
int v3; // ebx
int v4; // er12
int v5; // eax

if ( !a2 )
return 1LL;
v3 = a3;
if ( !a3 )
return 1LL;
v4 = 0;
while ( 1 )
{
v5 = write(fd, (const void *)(a2 + v4), v3);
if ( v5 < 0 )
break;
v4 += v5;
v3 -= v5;
if ( v3 <= 0 )
return 1LL;
}
printf("write response to socket %d failed\n", (unsigned int)fd);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, __int64 a2, int a3)
{
int v3; // ebx
int v4; // er12
int v5; // eax

if ( !a2 )
return 1LL;
v3 = a3;
if ( !a3 )
return 1LL;
v4 = 0;
while ( 1 )
{
v5 = write(fd, (const void *)(a2 + v4), v3);
if ( v5 < 0 )
break;
v4 += v5;
v3 -= v5;
if ( v3 <= 0 )
return 1LL;
}
printf("write response to socket %d failed\n", (unsigned int)fd);
return 0LL;
}

original_code:
static int send_data(int fd, void * data, int size)
{
 int written = 0;
 int remain = size;
 int ret;
 if(data == ((void *)0) || size == 0)
  return 1;
 for(; ;) {
  ret = write(fd, (char *)data + written, remain);
  if(ret < 0) {
   if(ret == 4)
    continue;
   printf("write response to socket %d failed\n", fd);
   return 0;
  }
  written += ret;
  remain -= ret;
  if(remain <= 0)
   break;
 }
 return 1;
}

canonical_original_code:
static int send_data(int fd, void *data, int size)
{
 int written = 0;
 int remain = size;
 int ret;
 if(data == ((void *)0) || size == 0)
  return 1;
 for(; ;) {
  ret = write(fd, (char *)data + written, remain);
  if(ret < 0) {
   if(ret == 4)
    continue;
   printf("write response to socket %d failed\n", fd);
   return 0;
  }
  written += ret;
  remain -= ret;
  if(remain <= 0)
   break;
 }
 return 1;
}

variable_types:
data
void *

variable_types: size int

variable_types: written int

variable_types: remain int

variable_types: ret int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int16 v3; // bx
int v4; // eax
int v5; // er13
pthread_t *i; // r12
int v7; // ebp
unsigned int v8; // ebx
char *v9; // rax
pthread_t *v10; // rax
pthread_t *v11; // rbx
pthread_t *v12; // r14
int *v13; // rax
char *v14; // rax
int *v15; // rax
char *v16; // rax
int *v17; // rax
char *v18; // rax
int *v19; // rax
char *v20; // rax
pthread_t *v21; // rbx
pthread_t v22; // rbx
socklen_t addr_len; // [rsp+Ch] [rbp-5Ch] BYREF
struct sockaddr v25; // [rsp+10h] [rbp-58h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-48h] BYREF
char optval[44]; // [rsp+3Ch] [rbp-2Ch] BYREF

addr_len = 16;
if ( argc <= 2 )
{
puts("Usage: ./server port file_dir");
exit(1);
}
v3 = atoi(argv[1]);
strcpy(g_dir, argv[2]);
v4 = socket(2, 1, 0);
v5 = v4;
if ( v4 < 0 )
{
v13 = _errno_location();
v14 = strerror(*v13);
printf("create listen socket failed: %s\n", v14);
exit(1);
}
setsockopt(v4, 1, 2, optval, 4u);
*(_DWORD *)&addr.sa_data[10] = 0;
addr.sa_family = 2;
*(_QWORD *)&addr.sa_data[2] = (unsigned int)_bswap_32(0);
*(_WORD *)addr.sa_data = _bswap_16(v3);
if ( bind(v5, &addr, 0x10u) < 0 )
{
v15 = _errno_location();
v16 = strerror(*v15);
printf("bind error: %s\n", v16);
close(v5);
exit(1);
}
if ( listen(v5, 10) < 0 )
{
v17 = _errno_location();
v18 = strerror(*v17);
printf("listen error: %s\n", v18);
close(v5);
exit(1);
}
for ( i = 0LL; ; i = v11 )
{
v7 = accept(v5, &v25, &addr_len);
if ( v7 < 0 )
{
v19 = _errno_location();
v20 = strerror(*v19);
printf("accept error: %s, we should exit\n", v20);
g_shutdown = 1;
sleep(5u);
goto LABEL_14;
}
v8 = *(unsigned __int16 *)v25.sa_data;
v9 = inet_ntoa(*(struct in_addr *)&v25.sa_data[2]);
printf("Reveive connect from %s, port %d\n", v9, v8);
v10 = (pthread_t *)malloc(0x18uLL);
v11 = v10;
if ( !v10 )
break;
v12 = v10 + 1;
v10[1] = 0LL;
*(_DWORD *)v10 = v7;
*((_DWORD *)v10 + 1) = 1;
v10[2] = (pthread_t)i;
printf("newfd = %d\n", (unsigned int)v7);
pthread_create(v12, 0LL, thread_loop, v11);
}
puts("malloc failed for new thread failed");
LABEL_14:
g_shutdown = 1;
if ( i )
{
v21 = i;
do
{
if ( *((_DWORD *)v21 + 1) )
pthread_join(v21[1], 0LL);
v21 = (pthread_t *)v21[2];
}
while ( v21 );
do
{
v22 = i[2];
free(i);
}
while ( v22 );
}
close(v5);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int16 v3; // bx
int v4; // eax
int v5; // er13
pthread_t *i; // r12
int v7; // ebp
unsigned int v8; // ebx
char *v9; // rax
pthread_t *v10; // rax
pthread_t *v11; // rbx
pthread_t *v12; // r14
int *v13; // rax
char *v14; // rax
int *v15; // rax
char *v16; // rax
int *v17; // rax
char *v18; // rax
int *v19; // rax
char *v20; // rax
pthread_t *v21; // rbx
pthread_t v22; // rbx
socklen_t addr_len; // [rsp+Ch] [rbp-5Ch] BYREF
struct sockaddr v25; // [rsp+10h] [rbp-58h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-48h] BYREF
char optval[44]; // [rsp+3Ch] [rbp-2Ch] BYREF

addr_len = 16;
if ( argc <= 2 )
{
puts("Usage: ./server port file_dir");
exit(1);
}
v3 = atoi(argv[1]);
strcpy(g_dir, argv[2]);
v4 = socket(2, 1, 0);
v5 = v4;
if ( v4 < 0 )
{
v13 = _errno_location();
v14 = strerror(*v13);
printf("create listen socket failed: %s\n", v14);
exit(1);
}
setsockopt(v4, 1, 2, optval, 4u);
*(_DWORD *)&addr.sa_data[10] = 0;
addr.sa_family = 2;
*(_QWORD *)&addr.sa_data[2] = (unsigned int)func3(0);
*(_WORD *)addr.sa_data = func4(v3);
if ( bind(v5, &addr, 0x10u) < 0 )
{
v15 = _errno_location();
v16 = strerror(*v15);
printf("bind error: %s\n", v16);
close(v5);
exit(1);
}
if ( listen(v5, 10) < 0 )
{
v17 = _errno_location();
v18 = strerror(*v17);
printf("listen error: %s\n", v18);
close(v5);
exit(1);
}
for ( i = 0LL; ; i = v11 )
{
v7 = accept(v5, &v25, &addr_len);
if ( v7 < 0 )
{
v19 = _errno_location();
v20 = strerror(*v19);
printf("accept error: %s, we should exit\n", v20);
g_shutdown = 1;
sleep(5u);
goto LABEL_14;
}
v8 = *(unsigned __int16 *)v25.sa_data;
v9 = inet_ntoa(*(struct in_addr *)&v25.sa_data[2]);
printf("Reveive connect from %s, port %d\n", v9, v8);
v10 = (pthread_t *)malloc(0x18uLL);
v11 = v10;
if ( !v10 )
break;
v12 = v10 + 1;
v10[1] = 0LL;
*(_DWORD *)v10 = v7;
*((_DWORD *)v10 + 1) = 1;
v10[2] = (pthread_t)i;
printf("newfd = %d\n", (unsigned int)v7);
pthread_create(v12, 0LL, thread_loop, v11);
}
puts("malloc failed for new thread failed");
LABEL_14:
g_shutdown = 1;
if ( i )
{
v21 = i;
do
{
if ( *((_DWORD *)v21 + 1) )
pthread_join(v21[1], 0LL);
v21 = (pthread_t *)v21[2];
}
while ( v21 );
do
{
v22 = i[2];
free(i);
}
while ( v22 );
}
close(v5);
return 0;
}

original_code:
int main(int argc, char *args[])
{
 int lfd, newfd;
 int reuseaddr;
 struct sockaddr_in server_addr, c_addr;
 int port = 123456;
 struct thread *thread_info = ((void *)0);
 struct thread *t_queue_head = ((void *)0);
 struct thread *entry = ((void *)0);
 struct thread *next = ((void *)0);
 socklen_t sin_len = sizeof(struct sockaddr_in);
 if(argc < 3) {
  printf("Usage: ./server port file_dir\n");
  exit(1);
 }
 port = atoi(args[1]);
 strcpy(g_dir, args[2]);
 lfd = socket(2, SOCK_STREAM, 0);
 if(lfd < 0) {
  printf("create listen socket failed: %s\n", strerror((*__errno_location ())));
  exit(1);
 }
 setsockopt (lfd, 1,2, (const void *) &reuseaddr, sizeof(int));
 bzero(&server_addr, sizeof(server_addr));
 server_addr.sin_family = 2;
 server_addr.sin_addr.s_addr = htonl(((in_addr_t) 0x00000000));
 server_addr.sin_port = htons(port);
 if(bind(lfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) < 0) {
  printf("bind error: %s\n", strerror((*__errno_location ())));
  close(lfd);
  exit(1);
 }
 if(listen(lfd, 10) < 0) {
  printf("listen error: %s\n", strerror((*__errno_location ())));
  close(lfd);
  exit(1);
 }
 for(;;) {
  if((newfd = accept(lfd, (struct sockaddr *)(&c_addr), &sin_len)) < 0) {
   printf("accept error: %s, we should exit\n", strerror((*__errno_location ())));
   g_shutdown = 1;
   break;
  }
  printf("Reveive connect from %s, port %d\n", inet_ntoa(c_addr.sin_addr), c_addr.sin_port);
  if((thread_info = (struct thread *)malloc(sizeof(thread_t))) == ((void *)0)) {
   printf("malloc failed for new thread failed\n");
   goto out;
  }
  memset(thread_info, 0, sizeof(thread_t));
  thread_info->fd = newfd;
  thread_info->running = 1;
  thread_info->next = t_queue_head;
  t_queue_head = thread_info;
  printf("newfd = %d\n", thread_info->fd);
  pthread_create(&(thread_info->pid), ((void *)0), thread_loop, (void *)thread_info);
 }
 sleep(5);
out:
 g_shutdown = 1;
 entry = t_queue_head;
 while(entry != ((void *)0)) {
  if(entry->running)
   pthread_join(entry->pid, ((void *)0));
  entry = entry->next;
 }
 entry = t_queue_head;
 next = entry;
 while(next != ((void *)0)) {
  next = entry->next;
  free(entry);
 }
 close(lfd);
 return 0;
}

canonical_original_code:
int main(int argc, char *args[])
{
 int lfd; int newfd;
 int reuseaddr;
 struct sockaddr_in server_addr; struct sockaddr_in c_addr;
 int port = 123456;
 struct thread *thread_info = ((void *)0);
 struct thread *t_queue_head = ((void *)0);
 struct thread *entry = ((void *)0);
 struct thread *next = ((void *)0);
 unsigned int sin_len = sizeof(struct sockaddr_in);
 if(argc < 3) {
  printf("Usage: ./server port file_dir\n");
  exit(1);
 }
 port = atoi(args[1]);
 strcpy(g_dir, args[2]);
 lfd = socket(2, SOCK_STREAM, 0);
 if(lfd < 0) {
  printf("create listen socket failed: %s\n", strerror((*__errno_location ())));
  exit(1);
 }
 setsockopt (lfd, 1,2, (void *) &reuseaddr, sizeof(int));
 bzero(&server_addr, sizeof(server_addr));
 server_addr.sin_family = 2;
 server_addr.sin_addr.s_addr = htonl(((unsigned int) 0x00000000));
 server_addr.sin_port = htons(port);
 if(bind(lfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) < 0) {
  printf("bind error: %s\n", strerror((*__errno_location ())));
  close(lfd);
  exit(1);
 }
 if(listen(lfd, 10) < 0) {
  printf("listen error: %s\n", strerror((*__errno_location ())));
  close(lfd);
  exit(1);
 }
 for(;;) {
  if((newfd = accept(lfd, (struct sockaddr *)(&c_addr), &sin_len)) < 0) {
   printf("accept error: %s, we should exit\n", strerror((*__errno_location ())));
   g_shutdown = 1;
   break;
  }
  printf("Reveive connect from %s, port %d\n", inet_ntoa(c_addr.sin_addr), c_addr.sin_port);
  if((thread_info = (struct thread *)malloc(sizeof(thread_t))) == ((void *)0)) {
   printf("malloc failed for new thread failed\n");
   goto out;
  }
  memset(thread_info, 0, sizeof(thread_t));
  thread_info->fd = newfd;
  thread_info->running = 1;
  thread_info->next = t_queue_head;
  t_queue_head = thread_info;
  printf("newfd = %d\n", thread_info->fd);
  pthread_create(&(thread_info->pid), ((void *)0), thread_loop, (void *)thread_info);
 }
 sleep(5);
out:
 g_shutdown = 1;
 entry = t_queue_head;
 while(entry != ((void *)0)) {
  if(entry->running)
   pthread_join(entry->pid, ((void *)0));
  entry = entry->next;
 }
 entry = t_queue_head;
 next = entry;
 while(next != ((void *)0)) {
  next = entry->next;
  free(entry);
 }
 close(lfd);
 return 0;
}

variable_types: argc int

variable_types:
args
char *[]

variable_types: lfd int

variable_types: newfd int

variable_types: reuseaddr int

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

variable_types: port int

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

user_defined_types: struct thread { int fd; int running; unsigned long pid; struct thread *next; }


decompiled_code:
__int64 __fastcall read_command_header(int fd, _DWORD *a2)
{
_QWORD *v2; // rax
_DWORD *v3; // rbp
int v4; // ebx
int v5; // eax

if ( fd < 0 )
_assert_fail("fd >= 0", "command.c", 0x22u, "read_command_header");
if ( !a2 )
_assert_fail("header != NULL", "command.c", 0x23u, "read_command_header");
v2 = malloc(8uLL);
v3 = v2;
if ( !v2 )
return 0LL;
*v2 = 0LL;
v4 = 8;
while ( 1 )
{
v5 = read(fd, v3, v4);
if ( v5 < 0 )
break;
v4 -= v5;
if ( v4 <= 0 )
{
*a2 = *v3;
a2[1] = v3[1];
free(v3);
return 1LL;
}
}
free(v3);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, _DWORD *a2)
{
_QWORD *v2; // rax
_DWORD *v3; // rbp
int v4; // ebx
int v5; // eax

if ( fd < 0 )
_assert_fail("fd >= 0", "command.c", 0x22u, "read_command_header");
if ( !a2 )
_assert_fail("header != NULL", "command.c", 0x23u, "read_command_header");
v2 = malloc(8uLL);
v3 = v2;
if ( !v2 )
return 0LL;
*v2 = 0LL;
v4 = 8;
while ( 1 )
{
v5 = read(fd, v3, v4);
if ( v5 < 0 )
break;
v4 -= v5;
if ( v4 <= 0 )
{
*a2 = *v3;
a2[1] = v3[1];
free(v3);
return 1LL;
}
}
free(v3);
return 0LL;
}

original_code:
static int read_command_header(int fd, struct command_header *header)
{
 char *buf = ((void *)0);
 int size = sizeof(*header);
 int ret = 0;
 ((void) sizeof ((fd >= 0) ? 1 : 0), __extension__ ({ if (fd >= 0) ; else __assert_fail ("fd >= 0", "command.c", 34, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((header != ((void *)0)) ? 1 : 0), __extension__ ({ if (header != ((void *)0)) ; else __assert_fail ("header != NULL", "command.c", 35, __extension__ __PRETTY_FUNCTION__); }));
 buf = (char *)malloc(size);
 if(buf == ((void *)0))
  return 0;
 memset(buf, 0, size);
 for(;;) {
  ret = read(fd, buf, size);
  if(ret < 0) {
   if(ret == 4)
    continue;
   free(buf);
   return 0;
  }
  size -= ret;
  if(size <= 0) {
   header->type = *(int *)buf;
   header->data_size = *((int *)buf + 1);
   break;
  }
 }
 free(buf);
 return 1;
}

variable_types: fd int

variable_types: struct command_header { int type; int data_size; } *

variable_types:
buf
char *


decompiled_code:
__int64 __fastcall read_command_body(int fd, void **a2, int a3)
{
int v3; // ebx
int v4; // eax
void *v6; // rax

if ( fd < 0 )
_assert_fail("fd >= 0", "command.c", 0x47u, "read_command_body");
v3 = a3;
if ( a3 <= 0 )
_assert_fail("size > 0", "command.c", 0x48u, "read_command_body");
if ( !*a2 )
{
v6 = malloc(a3);
*a2 = v6;
if ( !v6 )
return 0LL;
}
memset(*a2, 0, v3);
while ( 1 )
{
v4 = read(fd, *a2, v3);
if ( v4 < 0 )
break;
v3 -= v4;
if ( v3 <= 0 )
return 1LL;
}
free(*a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(int fd, void **a2, int a3)
{
int v3; // ebx
int v4; // eax
void *v6; // rax

if ( fd < 0 )
_assert_fail("fd >= 0", "command.c", 0x47u, "read_command_body");
v3 = a3;
if ( a3 <= 0 )
_assert_fail("size > 0", "command.c", 0x48u, "read_command_body");
if ( !*a2 )
{
v6 = malloc(a3);
*a2 = v6;
if ( !v6 )
return 0LL;
}
memset(*a2, 0, v3);
while ( 1 )
{
v4 = read(fd, *a2, v3);
if ( v4 < 0 )
break;
v3 -= v4;
if ( v3 <= 0 )
return 1LL;
}
free(*a2);
return 0LL;
}

original_code:
static int read_command_body(int fd, void **buf, int size)
{
 int ret = 0;
 ((void) sizeof ((fd >= 0) ? 1 : 0), __extension__ ({ if (fd >= 0) ; else __assert_fail ("fd >= 0", "command.c", 71, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((size > 0) ? 1 : 0), __extension__ ({ if (size > 0) ; else __assert_fail ("size > 0", "command.c", 72, __extension__ __PRETTY_FUNCTION__); }));
 if(*buf == ((void *)0)) {
  if((*buf = malloc(size)) == ((void *)0))
   return 0;
 }
 memset(*buf, 0, size);
 for(;;) {
  ret = read(fd, *buf, size);
  if(ret < 0) {
   if(ret == 4)
    continue;
   free(*buf);
   buf = ((void *)0);
   return 0;
  }
  size -= ret;
  if(size <= 0)
   break;
 }
 return 1;
}

variable_types:
buf
void **


decompiled_code:
__int64 __fastcall read_file_data(void *src, int a2, __int64 a3)
{
int v5; // er13
int v6; // ebx
int v7; // ebp
int v8; // eax
__int64 result; // rax
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
__off_t v14; // rbx
void *v15; // rdi
int *v16; // rax
char *v17; // rax
void *v18; // rdi
char v19[256]; // [rsp+0h] [rbp-3B8h] BYREF
char dest[8]; // [rsp+100h] [rbp-2B8h] BYREF
__int64 v21; // [rsp+108h] [rbp-2B0h]
char v22[496]; // [rsp+110h] [rbp-2A8h] BYREF
struct stat v23; // [rsp+300h] [rbp-B8h] BYREF

*(_QWORD *)dest = 0LL;
v21 = 0LL;
memset(v22, 0, sizeof(v22));
memcpy(v19, src, a2);
v19[a2] = 0;
strcpy(dest, &g_dir);
strcat(dest, v19);
if ( stat(dest, &v23) < 0 )
{
v10 = _errno_location();
v11 = strerror(*v10);
printf("get file %s stat failed: %s\n", (const char *)src, v11);
return 0LL;
}
v5 = open(dest, 0);
if ( v5 < 0 )
{
v12 = _errno_location();
v13 = strerror(*v12);
printf("open file %s failed: %s\n", (const char *)src, v13);
return 0LL;
}
if ( !*(_QWORD *)(a3 + 8) )
{
v14 = v23.st_size;
v15 = malloc(v23.st_size);
*(_QWORD *)(a3 + 8) = v15;
if ( !v15 )
{
close(v5);
return 0LL;
}
memset(v15, 0, v14);
}
v6 = v23.st_size;
v7 = 0;
while ( 1 )
{
v8 = read(v5, (void *)(*(_QWORD *)(a3 + 8) + v7), v6);
if ( v8 < 0 )
break;
v6 -= v8;
v7 += v8;
if ( v6 <= 0 )
{
*(_DWORD *)(a3 + 4) = v23.st_size;
close(v5);
return 1LL;
}
}
v16 = _errno_location();
v17 = strerror(*v16);
printf("read file %s failed: %s\n", (const char *)src, v17);
close(v5);
v18 = *(void **)(a3 + 8);
result = 0LL;
if ( v18 )
{
free(v18);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(void *src, int a2, __int64 a3)
{
int v5; // er13
int v6; // ebx
int v7; // ebp
int v8; // eax
__int64 result; // rax
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
__off_t v14; // rbx
void *v15; // rdi
int *v16; // rax
char *v17; // rax
void *v18; // rdi
char v19[256]; // [rsp+0h] [rbp-3B8h] BYREF
char dest[8]; // [rsp+100h] [rbp-2B8h] BYREF
__int64 v21; // [rsp+108h] [rbp-2B0h]
char v22[496]; // [rsp+110h] [rbp-2A8h] BYREF
struct stat v23; // [rsp+300h] [rbp-B8h] BYREF

*(_QWORD *)dest = 0LL;
v21 = 0LL;
memset(v22, 0, sizeof(v22));
memcpy(v19, src, a2);
v19[a2] = 0;
strcpy(dest, &g_dir);
strcat(dest, v19);
if ( stat(dest, &v23) < 0 )
{
v10 = _errno_location();
v11 = strerror(*v10);
printf("get file %s stat failed: %s\n", (const char *)src, v11);
return 0LL;
}
v5 = open(dest, 0);
if ( v5 < 0 )
{
v12 = _errno_location();
v13 = strerror(*v12);
printf("open file %s failed: %s\n", (const char *)src, v13);
return 0LL;
}
if ( !*(_QWORD *)(a3 + 8) )
{
v14 = v23.st_size;
v15 = malloc(v23.st_size);
*(_QWORD *)(a3 + 8) = v15;
if ( !v15 )
{
close(v5);
return 0LL;
}
memset(v15, 0, v14);
}
v6 = v23.st_size;
v7 = 0;
while ( 1 )
{
v8 = read(v5, (void *)(*(_QWORD *)(a3 + 8) + v7), v6);
if ( v8 < 0 )
break;
v6 -= v8;
v7 += v8;
if ( v6 <= 0 )
{
*(_DWORD *)(a3 + 4) = v23.st_size;
close(v5);
return 1LL;
}
}
v16 = _errno_location();
v17 = strerror(*v16);
printf("read file %s failed: %s\n", (const char *)src, v17);
close(v5);
v18 = *(void **)(a3 + 8);
result = 0LL;
if ( v18 )
{
free(v18);
result = 0LL;
}
return result;
}

original_code:
static int read_file_data(char *file_name, int name_len, struct response *res)
{
 int success = 1;
 struct stat file_stat;
 int fd;
 int finished = 0;
 int remain = 0;
 int ret = 0;
 char full_path[512] = {'\0'};
 char name[256];
 memcpy(name, file_name, name_len);
 name[name_len] = '\0';
 strcpy(full_path, g_dir);
 strcat(full_path, name);
 if(stat(full_path, &file_stat) < 0) {
  printf("get file %s stat failed: %s\n", file_name, strerror((*__errno_location ())));
  return 0;
 }
 if((fd = open(full_path, 00)) < 0) {
  printf("open file %s failed: %s\n", file_name, strerror((*__errno_location ())));
  return 0;
 }
 if(res->data == ((void *)0)) {
  if((res->data = malloc(file_stat.st_size)) == ((void *)0)) {
   close(fd);
   return 0;
  }
  memset(res->data, 0, file_stat.st_size);
 }
 remain = file_stat.st_size;
 for(; ;) {
  ret = read(fd, (char *)res->data + finished, remain);
  if(ret < 0) {
   printf("read file %s failed: %s\n", file_name, strerror((*__errno_location ())));
   success = 0;
   goto out;
  }
  remain -= ret;
  finished += ret;
  if(remain <= 0) {
   res->header.data_size = file_stat.st_size;
   break;
  }
 }
out:
 close(fd);
 if(success != 1 && res->data != ((void *)0))
  free(res->data);
 return success;
}

variable_types: struct response { struct response_header { int status; int data_size; } header; void *data; } *

variable_types: success int

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

variable_types: finished int

variable_types:
name
char [256]

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


decompiled_code:
__int64 __fastcall read_command(int fd, void **a2)
{
unsigned int v2; // ebp
int v3; // eax

if ( !a2 )
_assert_fail("comm != NULL", "command.c", 0x6Du, "read_command");
if ( fd < 0 )
_assert_fail("fd >= 0", "command.c", 0x6Eu, "read_command");
*a2 = 0LL;
v2 = read_command_header(fd, a2);
if ( !v2 )
{
printf("Read command header failed of %d\n", (unsigned int)fd);
return v2;
}
v3 = *(_DWORD *)a2;
if ( (unsigned __int8)*(_DWORD *)a2 == 2 )
{
puts("Get PULL command");
return (unsigned int)read_command_body(fd, a2 + 1, *((_DWORD *)a2 + 1));
}
if ( (char)v3 > 2 )
{
if ( (_BYTE)v3 == 3 )
{
puts("Get LEAVE command");
return v2;
}
LABEL_17:
puts("Invalid command");
return 0;
}
if ( !(_BYTE)v3 )
{
puts("Get LIST command");
return v2;
}
if ( (_BYTE)v3 != 1 )
goto LABEL_17;
puts("Get DIFF command");
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(int fd, void **a2)
{
unsigned int v2; // ebp
int v3; // eax

if ( !a2 )
_assert_fail("comm != NULL", "command.c", 0x6Du, "read_command");
if ( fd < 0 )
_assert_fail("fd >= 0", "command.c", 0x6Eu, "read_command");
*a2 = 0LL;
v2 = func0(fd, a2);
if ( !v2 )
{
printf("Read command header failed of %d\n", (unsigned int)fd);
return v2;
}
v3 = *(_DWORD *)a2;
if ( (unsigned __int8)*(_DWORD *)a2 == 2 )
{
puts("Get PULL command");
return (unsigned int)func1(fd, a2 + 1, *((_DWORD *)a2 + 1));
}
if ( (char)v3 > 2 )
{
if ( (_BYTE)v3 == 3 )
{
puts("Get LEAVE command");
return v2;
}
LABEL_17:
puts("Invalid command");
return 0;
}
if ( !(_BYTE)v3 )
{
puts("Get LIST command");
return v2;
}
if ( (_BYTE)v3 != 1 )
goto LABEL_17;
puts("Get DIFF command");
return v2;
}

original_code:
int read_command(int fd, struct command *comm)
{
 char command;
 int res = 1;
 ((void) sizeof ((comm != ((void *)0)) ? 1 : 0), __extension__ ({ if (comm != ((void *)0)) ; else __assert_fail ("comm != NULL", "command.c", 109, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((fd >= 0) ? 1 : 0), __extension__ ({ if (fd >= 0) ; else __assert_fail ("fd >= 0", "command.c", 110, __extension__ __PRETTY_FUNCTION__); }));
 memset(&(comm->header), 0, sizeof(comm->header));
 res = read_command_header(fd, &(comm->header));
 if(res == 0) {
  printf("Read command header failed of %d\n", fd);
  return 0;
 }
 command = comm->header.type;
 switch(command) {
  case 0:
   printf("Get LIST command\n");
   break;
  case 3:
   printf("Get LEAVE command\n");
   break;
  case 1:
   printf("Get DIFF command\n");
   break;
  case 2:
   printf("Get PULL command\n");
   res = read_command_body(fd, &(comm->data), comm->header.data_size);
   break;
  default:
   printf("Invalid command\n");
   res = 0;
 }
 return res;
}

variable_types: struct command { struct command_header { int type; int data_size; } header; void *data; } *

variable_types: command char

variable_types: res int


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

v2 = *(_DWORD *)a1;
if ( (unsigned __int8)*(_DWORD *)a1 == 2 )
return read_file_data(a1[1], *((_DWORD *)a1 + 1), a2);
if ( (char)v2 > 2 )
return (_BYTE)v2 == 3;
if ( (_BYTE)v2 )
return (_BYTE)v2 == 1;
return list_current_files(a2);
}

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

v2 = *(_DWORD *)a1;
if ( (unsigned __int8)*(_DWORD *)a1 == 2 )
return func2(a1[1], *((_DWORD *)a1 + 1), a2);
if ( (char)v2 > 2 )
return (_BYTE)v2 == 3;
if ( (_BYTE)v2 )
return (_BYTE)v2 == 1;
return func4(a2);
}

original_code:
int process_command(struct command *comm, struct response *res)
{
 char command = comm->header.type;
 switch(command) {
  case 0:
   return list_current_files(res);
   break;
  case 1:
   break;
  case 2:
   return read_file_data((char *)comm->data, comm->header.data_size, res);
   break;
  case 3:
   break;
  default:
   return 0;
   break;
 }
 return 1;
}

user_defined_types: struct command_header { int type; int data_size; }

user_defined_types: struct response_header { int status; int data_size; }