decompiled_code:
char *__fastcall auth_remote(__int64 a1, __int64 a2, const char *a3)
{
char *result; // rax
unsigned int v5; // er12
size_t v6; // rax
size_t v7; // rax
unsigned int v8; // [rsp+Ch] [rbp-19Ch] BYREF
char v9[128]; // [rsp+10h] [rbp-198h] BYREF
char s[280]; // [rsp+90h] [rbp-118h] BYREF

if ( (unsigned int)_isoc99_sscanf(a3, "%128[^:]:%d", v9, &v8) == 2 )
{
v5 = connect_to_server((__int64)v9, v8, *(_DWORD *)(a2 + 104));
if ( v5 == -1 )
{
syslog(3, "auth_remote: Error connecting to authentication server");
result = strdup("482 Authentication Temporarily Unavailable\r\n");
*(_QWORD *)(a1 + 64) = result;
}
else
{
sprintf(s, "AUTHINFO USER %s\r\n", *(const char **)(a1 + 16));
v6 = strlen(s);
write_socket(v5, s, v6, *(unsigned int *)(a2 + 104));
if ( read_socket(v5, s, 256LL, *(unsigned int *)(a2 + 104)) <= 0
|| (sprintf(s, "AUTHINFO PASS %s\r\n", *(const char **)(a1 + 8)),
v7 = strlen(s),
write_socket(v5, s, v7, *(unsigned int *)(a2 + 104)),
read_socket(v5, s, 256LL, *(unsigned int *)(a2 + 104)) <= 0) )
{
result = strdup("482 Authentication Temporarily Unavailable\r\n");
*(_QWORD *)(a1 + 64) = result;
}
else
{
if ( atoi(s) == 281 )
{
*(_BYTE *)(a1 + 60) = 1;
result = strdup("281 Authentication Accepted\r\n");
}
else
{
result = strdup("482 Authentication Rejected\r\n");
}
*(_QWORD *)(a1 + 64) = result;
}
}
}
else
{
syslog(3, "auth_remote: Wrong argument syntax \"%s\"", a3);
result = strdup("482 Authentication Temporarily Unavailable\r\n");
*(_QWORD *)(a1 + 64) = result;
}
return result;
}

canonical_decompiled_code:
char *__fastcall func1(__int64 a1, __int64 a2, const char *a3)
{
char *result; // rax
unsigned int v5; // er12
size_t v6; // rax
size_t v7; // rax
unsigned int v8; // [rsp+Ch] [rbp-19Ch] BYREF
char v9[128]; // [rsp+10h] [rbp-198h] BYREF
char s[280]; // [rsp+90h] [rbp-118h] BYREF

if ( (unsigned int)_isoc99_sscanf(a3, "%128[^:]:%d", v9, &v8) == 2 )
{
v5 = func0((__int64)v9, v8, *(_DWORD *)(a2 + 104));
if ( v5 == -1 )
{
syslog(3, "auth_remote: Error connecting to authentication server");
result = strdup("482 Authentication Temporarily Unavailable\r\n");
*(_QWORD *)(a1 + 64) = result;
}
else
{
sprintf(s, "AUTHINFO USER %s\r\n", *(const char **)(a1 + 16));
v6 = strlen(s);
write_socket(v5, s, v6, *(unsigned int *)(a2 + 104));
if ( read_socket(v5, s, 256LL, *(unsigned int *)(a2 + 104)) <= 0
|| (sprintf(s, "AUTHINFO PASS %s\r\n", *(const char **)(a1 + 8)),
v7 = strlen(s),
write_socket(v5, s, v7, *(unsigned int *)(a2 + 104)),
read_socket(v5, s, 256LL, *(unsigned int *)(a2 + 104)) <= 0) )
{
result = strdup("482 Authentication Temporarily Unavailable\r\n");
*(_QWORD *)(a1 + 64) = result;
}
else
{
if ( atoi(s) == 281 )
{
*(_BYTE *)(a1 + 60) = 1;
result = strdup("281 Authentication Accepted\r\n");
}
else
{
result = strdup("482 Authentication Rejected\r\n");
}
*(_QWORD *)(a1 + 64) = result;
}
}
}
else
{
syslog(3, "auth_remote: Wrong argument syntax \"%s\"", a3);
result = strdup("482 Authentication Temporarily Unavailable\r\n");
*(_QWORD *)(a1 + 64) = result;
}
return result;
}

original_code:
void auth_remote(AUTHRESULT *authres, struct config *cf, char *args)
{
 char tmp[256];
 char server[128];
 int port;
 int sock;
 if ( sscanf(args, "%128[^:]:%d", server, &port) != 2 )
 {
  syslog(3, "auth_remote: Wrong argument syntax \"%s\"", args);
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 if ( (sock=connect_to_server(server, port, cf->ServerReadTimeout)) == -1 )
 {
  syslog(3, "auth_remote: Error connecting to authentication server");
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 sprintf(tmp, "AUTHINFO USER %s\r\n", authres->username_s);
 write_socket(sock, tmp, strlen(tmp), cf->ServerReadTimeout);
 if ( read_socket(sock, tmp, 256, cf->ServerReadTimeout) <= 0 )
 {
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 sprintf(tmp, "AUTHINFO PASS %s\r\n", authres->password);
 write_socket(sock, tmp, strlen(tmp), cf->ServerReadTimeout);
 if ( read_socket(sock, tmp, 256, cf->ServerReadTimeout) <= 0 )
 {
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 if ( atoi(tmp) == 281 )
 {
  authres->authenticated = 1;
  authres->message = strdup("281 Authentication Accepted\r\n");
  return;
 }
 authres->message = strdup("482 Authentication Rejected\r\n");
 return;
}

canonical_original_code:
void auth_remote(struct AUTHRESULT *authres, struct config *cf, char *args)
{
 char tmp[256];
 char server[128];
 int port;
 int sock;
 if ( sscanf(args, "%128[^:]:%d", server, &port) != 2 )
 {
  syslog(3, "auth_remote: Wrong argument syntax \"%s\"", args);
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 if ( (sock=connect_to_server(server, port, cf->ServerReadTimeout)) == -1 )
 {
  syslog(3, "auth_remote: Error connecting to authentication server");
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 sprintf(tmp, "AUTHINFO USER %s\r\n", authres->username_s);
 write_socket(sock, tmp, strlen(tmp), cf->ServerReadTimeout);
 if ( read_socket(sock, tmp, 256, cf->ServerReadTimeout) <= 0 )
 {
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 sprintf(tmp, "AUTHINFO PASS %s\r\n", authres->password);
 write_socket(sock, tmp, strlen(tmp), cf->ServerReadTimeout);
 if ( read_socket(sock, tmp, 256, cf->ServerReadTimeout) <= 0 )
 {
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  return;
 }
 if ( atoi(tmp) == 281 )
 {
  authres->authenticated = 1;
  authres->message = strdup("281 Authentication Accepted\r\n");
  return;
 }
 authres->message = strdup("482 Authentication Rejected\r\n");
 return;
}

variable_types:
server
char [128]

user_defined_types: struct config { char *ListenPorts; char *BindAddress; char *RunAsUser; char *PidFile; char *StatsFile; int StatsFilePeriod; char *ConnDumpFile; char *BasePath; char *AccessFile; char *ServerFile; char *OverviewFmtFile; char *ActiveFile; char *NewsgroupsFile; int ServerReadTimeout; int ServerConnectTimeout; int ClientReadTimeout; int MaxConnections; int LogWriteclient; int LogReadserver; int LogWriteserver; int LogCommands; int LogMissing; int LogAuthInfo; char *PostServer; int PostServerPort; int PostXTraceHeader; char *ModeratorDomain; char *MailerPath; int BufSize; int SockBufSize; int ListenBackLog; int DenyNoIndexField; int DownDelay; int RetryDelay; int AccountingDelay; int RatePeriod; int DNSLookups; int DropUnknown; char *DisableFile; char *DisableText; int NoSuchArticleRetries; int LocalDreader; int CoreBind; int EnableSSL; char *ListenSSLPorts; char *AsLoginURL; char *AsLogoutURL; int RemoteConfig; char *WildmatURL; int JSONACL; char *ACLURL; int JSONRL; char *RLURL; char *null; }

user_defined_types: struct ARGS { char name[256]; char args[256]; }


initproctitle

repo: tomarus/nntpswitch

decompiled_code:
char **__fastcall initproctitle(int a1, _DWORD *a2)
{
char **v2; // rbp
char *v3; // r14
__int64 v4; // rax
int v5; // edx
char **result; // rax
char **v7; // r12
__int64 i; // rbx
const char *v9; // rbx

v2 = environ;
v3 = *environ;
if ( *environ )
{
v4 = 0LL;
do
v5 = v4++;
while ( environ[v4] );
result = (char **)malloc(8LL * (v5 + 2));
environ = result;
v7 = result;
if ( result )
{
for ( i = 0LL; ; ++i )
{
result = (char **)strdup(v3);
v7[i] = (char *)result;
if ( !result )
break;
v3 = v2[i + 1];
if ( !v3 )
{
argv0 = (__int64)a2;
v7[i + 1] = 0LL;
v9 = v2[i];
goto LABEL_10;
}
}
}
}
else
{
result = (char **)malloc(8uLL);
environ = result;
if ( result )
{
*result = 0LL;
argv0 = (__int64)a2;
v9 = *(const char **)&a2[2 * a1 - 2];
LABEL_10:
result = (char **)strlen(v9);
argv_lth = (_DWORD)result + (_DWORD)v9 - *a2;
}
}
return result;
}

canonical_decompiled_code:
char **__fastcall func0(int a1, _DWORD *a2)
{
char **v2; // rbp
char *v3; // r14
__int64 v4; // rax
int v5; // edx
char **result; // rax
char **v7; // r12
__int64 i; // rbx
const char *v9; // rbx

v2 = environ;
v3 = *environ;
if ( *environ )
{
v4 = 0LL;
do
v5 = v4++;
while ( environ[v4] );
result = (char **)malloc(8LL * (v5 + 2));
environ = result;
v7 = result;
if ( result )
{
for ( i = 0LL; ; ++i )
{
result = (char **)strdup(v3);
v7[i] = (char *)result;
if ( !result )
break;
v3 = v2[i + 1];
if ( !v3 )
{
argv0 = (__int64)a2;
v7[i + 1] = 0LL;
v9 = v2[i];
goto LABEL_10;
}
}
}
}
else
{
result = (char **)malloc(8uLL);
environ = result;
if ( result )
{
*result = 0LL;
argv0 = (__int64)a2;
v9 = *(const char **)&a2[2 * a1 - 2];
LABEL_10:
result = (char **)strlen(v9);
argv_lth = (_DWORD)result + (_DWORD)v9 - *a2;
}
}
return result;
}

original_code:
void
initproctitle (int argc, char **argv) {
 int i;
 char **envp = environ;
 for (i = 0; envp[i] != ((void *)0); i++)
  continue;
 environ = (char **) malloc(sizeof(char *) * (i + 1));
 if (environ == ((void *)0))
  return;
 for (i = 0; envp[i] != ((void *)0); i++)
  if ((environ[i] = strdup(envp[i])) == ((void *)0))
   return;
 environ[i] = ((void *)0);
 argv0 = argv;
 if (i > 0)
  argv_lth = envp[i-1] + strlen(envp[i-1]) - argv0[0];
 else
  argv_lth = argv0[argc-1] + strlen(argv0[argc-1]) - argv0[0];
}

canonical_original_code:
void initproctitle(int argc, char **argv) {
 int i;
 char **envp = environ;
 for (i = 0; envp[i] != ((void *)0); i++)
  continue;
 environ = (char **) malloc(sizeof(char *) * (i + 1));
 if (environ == ((void *)0))
  return;
 for (i = 0; envp[i] != ((void *)0); i++)
  if ((environ[i] = strdup(envp[i])) == ((void *)0))
   return;
 environ[i] = ((void *)0);
 argv0 = argv;
 if (i > 0)
  argv_lth = envp[i-1] + strlen(envp[i-1]) - argv0[0];
 else
  argv_lth = argv0[argc-1] + strlen(argv0[argc-1]) - argv0[0];
}

variable_types: argc int

variable_types:
argv
char **

variable_types: i int

variable_types:
envp
char **

return_type: void


setproctitle

decompiled_code:
void setproctitle(char *format, ...)
{
int v1; // eax
size_t v2; // rdx
__int64 v3; // rbx
gcc_va_list arg; // [rsp+8h] [rbp-8D0h] BYREF
char s[2048]; // [rsp+20h] [rbp-8B8h] BYREF

if ( argv0 )
{
va_start(arg, format);
vsnprintf(s, 0x800uLL, format, arg);
v1 = strlen(s);
v2 = argv_lth;
if ( argv_lth - 1 <= v1 )
s[argv_lth - 2] = 0;
v3 = argv0;
memset(*(void **)argv0, 0, v2);
strcpy(*(char **)v3, s);
*(_QWORD *)(v3 + 8) = 0LL;
}
}

canonical_decompiled_code:
void func1(char *format, ...)
{
int v1; // eax
size_t v2; // rdx
__int64 v3; // rbx
gcc_va_list arg; // [rsp+8h] [rbp-8D0h] BYREF
char s[2048]; // [rsp+20h] [rbp-8B8h] BYREF

if ( argv0 )
{
va_start(arg, format);
vsnprintf(s, 0x800uLL, format, arg);
v1 = strlen(s);
v2 = argv_lth;
if ( argv_lth - 1 <= v1 )
s[argv_lth - 2] = 0;
v3 = argv0;
memset(*(void **)argv0, 0, v2);
strcpy(*(char **)v3, s);
*(_QWORD *)(v3 + 8) = 0LL;
}
}

original_code:
void
setproctitle (const char *fmt,...) {
 int i;
 char buf[2048];
 va_list ap;
 if (!argv0)
  return;
 __builtin_va_start(ap,fmt);
 (void) vsnprintf(buf, 2048, fmt, ap);
 __builtin_va_end(ap);
 i = strlen (buf);
 if (i > argv_lth - 2) {
  i = argv_lth - 2;
  buf[i] = '\0';
 }
 memset(argv0[0], '\0', argv_lth);
 (void) strcpy (argv0[0], buf);
 argv0[1] = ((void *)0);
}

canonical_original_code:
void setproctitle(char *fmt, ...) {
 int i;
 char buf[2048];
 __builtin_va_list ap;
 if (!argv0)
  return;
 __builtin_va_start(ap,fmt);
 (void) vsnprintf(buf, 2048, fmt, ap);
 __builtin_va_end(ap);
 i = strlen (buf);
 if (i > argv_lth - 2) {
  i = argv_lth - 2;
  buf[i] = '\0';
 }
 memset(argv0[0], '\0', argv_lth);
 (void) strcpy (argv0[0], buf);
 argv0[1] = ((void *)0);
}

variable_types:
fmt
char *

variable_types:
buf
char [2048]


freehttpacl

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

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

original_code:
void freehttpacl(ACL * acl)
{
    if ( acl != ((void *)0) )
        free(acl);
}

canonical_original_code:
void freehttpacl(struct ACL *acl)
{
    if ( acl != ((void *)0) )
        free(acl);
}

variable_types: struct ACL { unsigned long start; unsigned long end; unsigned long size; struct _profile { char Name[32]; char ReadPat[256]; char PostPat[256]; int MaxConnections; int MaxUserConcurrent; int MaxHostConcurrent; int Slave; int ASMaxConns; int ASMaxHosts; int MaxUsers; int MaxSessionTime; unsigned long long MaxSessionBytes; unsigned int MaxUserBPS; unsigned int MaxProfileBPS; char XComplaintsTo[256]; char Organization[256]; int ForceOrganization; int AddNNTPPostingHost; int MaxCross; char Hostname[256]; char FooterFile[256]; char Footer[1024]; int FooterSize; int NoControl; int ArticleSearch; int ClientReadTimeout; struct ALIAS { char name[256]; char lib[256]; char args[256]; } *Accounting; char AccountingPrefix[256]; struct LIMITS { int gb; int kbit; } Limits[16]; int NumLimits; char Disabled[256]; int AllowSSL; unsigned int connections; unsigned int numusers; unsigned int realusers; unsigned long long bytes; unsigned long long rbytes; unsigned long articles; unsigned long long postbytes; unsigned long postarticles; unsigned int rl_curbytes; unsigned int rl_lastbytes; double rl_sleep; struct timeval { long tv_sec; long tv_usec; } rl_start; double rl_curbps; double UserRLFactorU; double UserRLFactorD; double ProfileRLFactorU; double ProfileRLFactorD; unsigned int Retention; char XHeaderSSLUpload[1024]; struct PFXMAP { char name[32]; char map[4194303]; } *PrefixMap; struct _profile *FailProfile; } *profile; unsigned int read; unsigned int post; unsigned int apost; unsigned int deny; unsigned int auth; unsigned int stats; unsigned int unlimit; } *

user_defined_types: struct ACL { unsigned long start; unsigned long end; unsigned long size; struct _profile *profile; unsigned int read; unsigned int post; unsigned int apost; unsigned int deny; unsigned int auth; unsigned int stats; unsigned int unlimit; }

user_defined_types: struct _profile { char Name[32]; char ReadPat[256]; char PostPat[256]; int MaxConnections; int MaxUserConcurrent; int MaxHostConcurrent; int Slave; int ASMaxConns; int ASMaxHosts; int MaxUsers; int MaxSessionTime; unsigned long long MaxSessionBytes; unsigned int MaxUserBPS; unsigned int MaxProfileBPS; char XComplaintsTo[256]; char Organization[256]; int ForceOrganization; int AddNNTPPostingHost; int MaxCross; char Hostname[256]; char FooterFile[256]; char Footer[1024]; int FooterSize; int NoControl; int ArticleSearch; int ClientReadTimeout; struct ALIAS *Accounting; char AccountingPrefix[256]; struct LIMITS Limits[16]; int NumLimits; char Disabled[256]; int AllowSSL; unsigned int connections; unsigned int numusers; unsigned int realusers; unsigned long long bytes; unsigned long long rbytes; unsigned long articles; unsigned long long postbytes; unsigned long postarticles; unsigned int rl_curbytes; unsigned int rl_lastbytes; double rl_sleep; struct timeval rl_start; double rl_curbps; double UserRLFactorU; double UserRLFactorD; double ProfileRLFactorU; double ProfileRLFactorD; unsigned int Retention; char XHeaderSSLUpload[1024]; struct PFXMAP *PrefixMap; struct _profile *FailProfile; }


decompiled_code:
void __fastcall auth_http(__int64 a1, __int64 a2, const char *a3)
{
char *v4; // rax
__int64 v5; // rax
char *v6; // rax
const char *v7; // r12
char *v8; // rax
const char *v9; // rdx
int v10; // [rsp+0h] [rbp-458h] BYREF
int v11; // [rsp+4h] [rbp-454h] BYREF
__int64 v12; // [rsp+8h] [rbp-450h] BYREF
void *ptr; // [rsp+10h] [rbp-448h] BYREF
char v14[32]; // [rsp+20h] [rbp-438h] BYREF
char s[1048]; // [rsp+40h] [rbp-418h] BYREF

v4 = strstr(a3, "%S");
if ( v4 )
{
v4[1] = 115;
}
else if ( !strstr(a3, "%s") )
{
syslog(3, "auth_http: No valid url found, check configuration");
*(_QWORD *)(a1 + 64) = strdup("482 Authentication Temporarily Unavailable\r\n");
return;
}
sprintf(s, a3, *(_QWORD *)(a1 + 16), *(_QWORD *)(a1 + 8));
*(_QWORD *)(a1 + 104) = strdup(*(const char **)(a1 + 16));
if ( curlGetURL(s, &ptr) )
{
if ( (unsigned int)_isoc99_sscanf(ptr, "%d:%d:%lld:%32s", &v10, &v11, &v12, v14) != 4 || !v10 )
{
*(_QWORD *)(a1 + 64) = strdup("482 Authentication Rejected\r\n");
goto LABEL_8;
}
if ( getprofile(v14) )
{
v5 = v12;
*(_BYTE *)(a1 + 60) = 1;
*(_QWORD *)(a1 + 88) = v5;
*(_BYTE *)(a1 + 80) = v11;
v6 = strdup(v14);
*(_QWORD *)(a1 + 72) = v6;
v7 = v6;
v8 = strdup("281 Authentication Accepted\r\n");
v9 = *(const char **)a1;
*(_QWORD *)(a1 + 64) = v8;
syslog(5, "auth_http: login %s profile %s", v9, v7);
goto LABEL_8;
}
syslog(3, "auth_http: Unknown profile: %s", v14);
}
*(_QWORD *)(a1 + 64) = strdup("482 Authentication Temporarily Unavailable\r\n");
LABEL_8:
if ( ptr )
free(ptr);
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1, __int64 a2, const char *a3)
{
char *v4; // rax
__int64 v5; // rax
char *v6; // rax
const char *v7; // r12
char *v8; // rax
const char *v9; // rdx
int v10; // [rsp+0h] [rbp-458h] BYREF
int v11; // [rsp+4h] [rbp-454h] BYREF
__int64 v12; // [rsp+8h] [rbp-450h] BYREF
void *ptr; // [rsp+10h] [rbp-448h] BYREF
char v14[32]; // [rsp+20h] [rbp-438h] BYREF
char s[1048]; // [rsp+40h] [rbp-418h] BYREF

v4 = strstr(a3, "%S");
if ( v4 )
{
v4[1] = 115;
}
else if ( !strstr(a3, "%s") )
{
syslog(3, "auth_http: No valid url found, check configuration");
*(_QWORD *)(a1 + 64) = strdup("482 Authentication Temporarily Unavailable\r\n");
return;
}
sprintf(s, a3, *(_QWORD *)(a1 + 16), *(_QWORD *)(a1 + 8));
*(_QWORD *)(a1 + 104) = strdup(*(const char **)(a1 + 16));
if ( curlGetURL(s, &ptr) )
{
if ( (unsigned int)_isoc99_sscanf(ptr, "%d:%d:%lld:%32s", &v10, &v11, &v12, v14) != 4 || !v10 )
{
*(_QWORD *)(a1 + 64) = strdup("482 Authentication Rejected\r\n");
goto LABEL_8;
}
if ( getprofile(v14) )
{
v5 = v12;
*(_BYTE *)(a1 + 60) = 1;
*(_QWORD *)(a1 + 88) = v5;
*(_BYTE *)(a1 + 80) = v11;
v6 = strdup(v14);
*(_QWORD *)(a1 + 72) = v6;
v7 = v6;
v8 = strdup("281 Authentication Accepted\r\n");
v9 = *(const char **)a1;
*(_QWORD *)(a1 + 64) = v8;
syslog(5, "auth_http: login %s profile %s", v9, v7);
goto LABEL_8;
}
syslog(3, "auth_http: Unknown profile: %s", v14);
}
*(_QWORD *)(a1 + 64) = strdup("482 Authentication Temporarily Unavailable\r\n");
LABEL_8:
if ( ptr )
free(ptr);
}

original_code:
void auth_http(AUTHRESULT *authres, struct config *cf, char *args)
{
 char tmp[1024];
 unsigned long long res_bytes;
 int res_auth;
 int res_post;
 char res_profile[32];
 struct _profile * pf;
 struct curlMemStruct curlData;
 char *str;
 if ( (str=strstr(args, "%S")) != ((void *)0) )
 {
  str[1] = 's';
  sprintf(tmp, args, authres->username_s, authres->password);
  authres->logname = strdup( authres->username_s );
 }
 else
 {
  if ( (str = strstr(args, "%s")) == ((void *)0) )
  {
   syslog(3, "auth_http: " "No valid url found, check configuration");
   authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
   return;
  }
  sprintf(tmp, args, authres->username_s, authres->password);
  authres->logname = strdup( authres->username_s );
 }
 if ( ! curlGetURL(tmp, &curlData) ) {
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  goto cleanup;
 }
 int n;
        if ( (n=sscanf(curlData.mem, "%d:%d:%lld:%32s", &res_auth, &res_post, &res_bytes, res_profile)) != 4 )
 {
  authres->message = strdup("482 Authentication Rejected\r\n");
  goto cleanup;
 }
 else
 {
  if ( res_auth == 0 )
  {
   authres->message = strdup("482 Authentication Rejected\r\n");
   goto cleanup;
  }
  if ( (pf=getprofile(res_profile)) == ((void *)0) )
  {
   syslog(3, "auth_http: " "Unknown profile: %s", res_profile);
   authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
   goto cleanup;
  }
  authres->authenticated = 1;
  authres->bytes = res_bytes;
  authres->posting = res_post;
  authres->profile = strdup(res_profile);
  authres->message = strdup("281 Authentication Accepted\r\n");
  syslog(5, "auth_http: " "login %s profile %s", authres->username, authres->profile);
 }
cleanup:
 if ( curlData.mem )
  free(curlData.mem);
 return;
}

canonical_original_code:
void auth_http(struct AUTHRESULT *authres, struct config *cf, char *args)
{
 char tmp[1024];
 unsigned long long res_bytes;
 int res_auth;
 int res_post;
 char res_profile[32];
 struct _profile *pf;
 struct curlMemStruct curlData;
 char *str;
 if ( (str=strstr(args, "%S")) != ((void *)0) )
 {
  str[1] = 's';
  sprintf(tmp, args, authres->username_s, authres->password);
  authres->logname = strdup( authres->username_s );
 }
 else
 {
  if ( (str = strstr(args, "%s")) == ((void *)0) )
  {
   syslog(3, "auth_http: " "No valid url found, check configuration");
   authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
   return;
  }
  sprintf(tmp, args, authres->username_s, authres->password);
  authres->logname = strdup( authres->username_s );
 }
 if ( ! curlGetURL(tmp, &curlData) ) {
  authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
  goto cleanup;
 }
 int n;
        if ( (n=sscanf(curlData.mem, "%d:%d:%lld:%32s", &res_auth, &res_post, &res_bytes, res_profile)) != 4 )
 {
  authres->message = strdup("482 Authentication Rejected\r\n");
  goto cleanup;
 }
 else
 {
  if ( res_auth == 0 )
  {
   authres->message = strdup("482 Authentication Rejected\r\n");
   goto cleanup;
  }
  if ( (pf=getprofile(res_profile)) == ((void *)0) )
  {
   syslog(3, "auth_http: " "Unknown profile: %s", res_profile);
   authres->message = strdup("482 Authentication Temporarily Unavailable\r\n");
   goto cleanup;
  }
  authres->authenticated = 1;
  authres->bytes = res_bytes;
  authres->posting = res_post;
  authres->profile = strdup(res_profile);
  authres->message = strdup("281 Authentication Accepted\r\n");
  syslog(5, "auth_http: " "login %s profile %s", authres->username, authres->profile);
 }
cleanup:
 if ( curlData.mem )
  free(curlData.mem);
 return;
}

variable_types: struct AUTHRESULT { char *username; char *password; char *username_s; int port; char *hostname; struct in_addr { unsigned int s_addr; } in_addr; struct ARGS { char name[256]; char args[256]; } *args; int numargs; unsigned char authenticated; char *message; char *profile; unsigned char posting; unsigned long long bytes; int userkbit; char *logname; char *readpat; char *postpat; int timeleft; unsigned char overquota; unsigned char disabled; char *posthost; char *postabuse; char *postorg; } *

variable_types: struct config { char *ListenPorts; char *BindAddress; char *RunAsUser; char *PidFile; char *StatsFile; int StatsFilePeriod; char *ConnDumpFile; char *BasePath; char *AccessFile; char *ServerFile; char *OverviewFmtFile; char *ActiveFile; char *NewsgroupsFile; int ServerReadTimeout; int ServerConnectTimeout; int ClientReadTimeout; int MaxConnections; int LogWriteclient; int LogReadserver; int LogWriteserver; int LogCommands; int LogMissing; int LogAuthInfo; char *PostServer; int PostServerPort; int PostXTraceHeader; char *ModeratorDomain; char *MailerPath; int BufSize; int SockBufSize; int ListenBackLog; int DenyNoIndexField; int DownDelay; int RetryDelay; int AccountingDelay; int RatePeriod; int DNSLookups; int DropUnknown; char *DisableFile; char *DisableText; int NoSuchArticleRetries; int LocalDreader; int CoreBind; int EnableSSL; char *ListenSSLPorts; char *AsLoginURL; char *AsLogoutURL; int RemoteConfig; char *WildmatURL; int JSONACL; char *ACLURL; int JSONRL; char *RLURL; char *null; } *

variable_types:
args
char *

variable_types:
tmp
char [1024]

variable_types: struct _profile { char Name[32]; char ReadPat[256]; char PostPat[256]; int MaxConnections; int MaxUserConcurrent; int MaxHostConcurrent; int Slave; int ASMaxConns; int ASMaxHosts; int MaxUsers; int MaxSessionTime; unsigned long long MaxSessionBytes; unsigned int MaxUserBPS; unsigned int MaxProfileBPS; char XComplaintsTo[256]; char Organization[256]; int ForceOrganization; int AddNNTPPostingHost; int MaxCross; char Hostname[256]; char FooterFile[256]; char Footer[1024]; int FooterSize; int NoControl; int ArticleSearch; int ClientReadTimeout; struct ALIAS { char name[256]; char lib[256]; char args[256]; } *Accounting; char AccountingPrefix[256]; struct LIMITS { int gb; int kbit; } Limits[16]; int NumLimits; char Disabled[256]; int AllowSSL; unsigned int connections; unsigned int numusers; unsigned int realusers; unsigned long long bytes; unsigned long long rbytes; unsigned long articles; unsigned long long postbytes; unsigned long postarticles; unsigned int rl_curbytes; unsigned int rl_lastbytes; double rl_sleep; struct timeval { long tv_sec; long tv_usec; } rl_start; double rl_curbps; double UserRLFactorU; double UserRLFactorD; double ProfileRLFactorU; double ProfileRLFactorD; unsigned int Retention; char XHeaderSSLUpload[1024]; struct PFXMAP { char name[32]; char map[4194303]; } *PrefixMap; struct _profile *FailProfile; } *

variable_types: struct curlMemStruct { char *mem; unsigned long size; }

variable_types:
str
char *

variable_types: n int

user_defined_types: struct AUTHRESULT { char *username; char *password; char *username_s; int port; char *hostname; struct in_addr in_addr; struct ARGS *args; int numargs; unsigned char authenticated; char *message; char *profile; unsigned char posting; unsigned long long bytes; int userkbit; char *logname; char *readpat; char *postpat; int timeleft; unsigned char overquota; unsigned char disabled; char *posthost; char *postabuse; char *postorg; }


repo: tomasv/tsmtp-c

decompiled_code:
__int64 __fastcall get_session_command(char *s)
{
bool v2; // zf
__int64 result; // rax
char *v4; // rsi

v2 = memcmp(s, "HELO", 4uLL) == 0;
result = !v2;
if ( !v2 )
{
result = 1LL;
if ( memcmp(s, "MAIL FROM:", 0xAuLL) )
{
result = 2LL;
if ( memcmp(s, "RCPT TO:", 8uLL) )
{
result = 3LL;
if ( memcmp(s, "DATA", 4uLL) )
{
if ( *s != 46 || s[1] != 13 || (result = 4LL, s[2] != 10) )
{
v4 = &s[strlen(s) - 5];
result = 4LL;
if ( memcmp(v4, "\r\n.\r\n", 5uLL) )
result = memcmp(s, "QUIT", 4uLL) == 0 ? 5 : -1;
}
}
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *s)
{
bool v2; // zf
__int64 result; // rax
char *v4; // rsi

v2 = memcmp(s, "HELO", 4uLL) == 0;
result = !v2;
if ( !v2 )
{
result = 1LL;
if ( memcmp(s, "MAIL FROM:", 0xAuLL) )
{
result = 2LL;
if ( memcmp(s, "RCPT TO:", 8uLL) )
{
result = 3LL;
if ( memcmp(s, "DATA", 4uLL) )
{
if ( *s != 46 || s[1] != 13 || (result = 4LL, s[2] != 10) )
{
v4 = &s[strlen(s) - 5];
result = 4LL;
if ( memcmp(v4, "\r\n.\r\n", 5uLL) )
result = memcmp(s, "QUIT", 4uLL) == 0 ? 5 : -1;
}
}
}
}
}
return result;
}

original_code:
int get_session_command(char* buffer) {
 if (strncmp(buffer, "HELO", 4) == 0)
  return CMD_HELO;
 if (strncmp(buffer, "MAIL FROM:", 10) == 0)
  return CMD_MAIL;
 if (strncmp(buffer, "RCPT TO:", 8) == 0)
  return CMD_RCPT;
 if (strncmp(buffer, "DATA", 4) == 0)
  return CMD_DATA;
 if (strncmp(buffer, ".\r\n", 3) == 0) {
  return CMD_CRLF;
 }
 if (strncmp(buffer+strlen(buffer)-5, "\r\n.\r\n", 5) == 0) {
  return CMD_CRLF;
 }
 if (strncmp(buffer, "QUIT", 4) == 0)
  return CMD_QUIT;
 return -1;
}

canonical_original_code:
int get_session_command(char *buffer) {
 if (strncmp(buffer, "HELO", 4) == 0)
  return CMD_HELO;
 if (strncmp(buffer, "MAIL FROM:", 10) == 0)
  return CMD_MAIL;
 if (strncmp(buffer, "RCPT TO:", 8) == 0)
  return CMD_RCPT;
 if (strncmp(buffer, "DATA", 4) == 0)
  return CMD_DATA;
 if (strncmp(buffer, ".\r\n", 3) == 0) {
  return CMD_CRLF;
 }
 if (strncmp(buffer+strlen(buffer)-5, "\r\n.\r\n", 5) == 0) {
  return CMD_CRLF;
 }
 if (strncmp(buffer, "QUIT", 4) == 0)
  return CMD_QUIT;
 return -1;
}

variable_types:
buffer
char *

return_type: int


original_code:
int get_session_response(char* buffer) {
 if (strncmp(buffer, "250", 3) == 0)
  return REPLY_OK;
 if (strncmp(buffer, "220", 3) == 0)
  return REPLY_GREET;
 if (strncmp(buffer, "501", 3) == 0)
  return REPLY_SYNTAX_ERROR;
 if (strncmp(buffer, "354", 3) == 0)
  return REPLY_DATA_INFO;
 if (strncmp(buffer, "221", 3) == 0)
  return REPLY_BYE;
 if (strncmp(buffer, "503", 3) == 0)
  return REPLY_OOO;
 return -1;
}

canonical_original_code:
int get_session_response(char *buffer) {
 if (strncmp(buffer, "250", 3) == 0)
  return REPLY_OK;
 if (strncmp(buffer, "220", 3) == 0)
  return REPLY_GREET;
 if (strncmp(buffer, "501", 3) == 0)
  return REPLY_SYNTAX_ERROR;
 if (strncmp(buffer, "354", 3) == 0)
  return REPLY_DATA_INFO;
 if (strncmp(buffer, "221", 3) == 0)
  return REPLY_BYE;
 if (strncmp(buffer, "503", 3) == 0)
  return REPLY_OOO;
 return -1;
}


decompiled_code:
__int64 __fastcall get_argument_string_start(__int64 a1, int a2)
{
return a1 + command_lengths[a2];
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, int a2)
{
return a1 + command_lengths[a2];
}

original_code:
char * get_argument_string_start(char * message, enum session_command cmd) {
 return (message + command_lengths[cmd]);
}

canonical_original_code:
char *get_argument_string_start(char *message, enum session_command cmd) {
 return (message + command_lengths[cmd]);
}

variable_types:
message
char *

variable_types: enum session_command { CMD_HELO=0, CMD_MAIL=1, CMD_RCPT=2, CMD_DATA=3, CMD_CRLF=4, CMD_QUIT=5 }

return_type: char *


decompiled_code:
char *__fastcall get_email(char *s)
{
char *v1; // r12
char *v2; // rax
const char *v3; // rbp
size_t v4; // r12
char *v5; // r13

v1 = strchr(s, 60);
v2 = strchr(s, 62);
if ( v2 == 0LL || v1 == 0LL || v1 >= v2 )
return 0LL;
v3 = v1 + 1;
v4 = (int)v2 - ((int)v1 + 1);
v5 = (char *)malloc(v4 + 1);
strncpy(v5, v3, v4);
v5[strlen(v5)] = 0;
return v5;
}

canonical_decompiled_code:
char *__fastcall func3(char *s)
{
char *v1; // r12
char *v2; // rax
const char *v3; // rbp
size_t v4; // r12
char *v5; // r13

v1 = strchr(s, 60);
v2 = strchr(s, 62);
if ( v2 == 0LL || v1 == 0LL || v1 >= v2 )
return 0LL;
v3 = v1 + 1;
v4 = (int)v2 - ((int)v1 + 1);
v5 = (char *)malloc(v4 + 1);
strncpy(v5, v3, v4);
v5[strlen(v5)] = 0;
return v5;
}

original_code:
char * get_email(char * argument) {
 char * start = strpbrk(argument, "<");
 char * end = strpbrk(argument, ">");
 if (start == ((void *)0) || end == ((void *)0) || start >= end)
  return ((void *)0);
 start++;
 int len = end - start;
 char * email = malloc(len * sizeof(char) + 1);
 strncpy(email, start, len);
 email[strlen(email)] = '\0';
 return email;
}

canonical_original_code:
char *get_email(char *argument) {
 char *start = strpbrk(argument, "<");
 char *end = strpbrk(argument, ">");
 if (start == ((void *)0) || end == ((void *)0) || start >= end)
  return ((void *)0);
 start++;
 int len = end - start;
 char *email = malloc(len * sizeof(char) + 1);
 strncpy(email, start, len);
 email[strlen(email)] = '\0';
 return email;
}

variable_types:
argument
char *

variable_types:
start
char *

variable_types:
end
char *

variable_types: len int

variable_types:
email
char *


decompiled_code:
_BOOL8 __fastcall check_domain(const char *a1)
{
return gethostbyname(a1) != 0LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func4(const char *a1)
{
return gethostbyname(a1) != 0LL;
}

original_code:
int check_domain(char * domain)
{
 if (!gethostbyname(domain))
  return 0;
 return 1;
}

canonical_original_code:
int check_domain(char *domain)
{
 if (!gethostbyname(domain))
  return 0;
 return 1;
}

variable_types:
domain
char *


decompiled_code:
__int64 __fastcall sender_worker(void *ptr)
{
const char *v1; // rsi

puts("sender: starting work");
puts("sender: sending message");
printf("sender: FROM: %s\n", *(const char **)ptr);
printf("sender: TO: %s\n", *((const char **)ptr + 1));
puts("sender: BODY:");
v1 = (const char *)*((_QWORD *)ptr + 2);
if ( v1 )
printf("%s", v1);
else
puts("No body.");
putchar(10);
free(*(void **)ptr);
free(*((void **)ptr + 1));
free(*((void **)ptr + 2));
free(ptr);
puts("sender: finished");
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(void *ptr)
{
const char *v1; // rsi

puts("sender: starting work");
puts("sender: sending message");
printf("sender: FROM: %s\n", *(const char **)ptr);
printf("sender: TO: %s\n", *((const char **)ptr + 1));
puts("sender: BODY:");
v1 = (const char *)*((_QWORD *)ptr + 2);
if ( v1 )
printf("%s", v1);
else
puts("No body.");
putchar(10);
free(*(void **)ptr);
free(*((void **)ptr + 1));
free(*((void **)ptr + 2));
free(ptr);
puts("sender: finished");
return 0LL;
}

original_code:
void* sender_worker(void* data) {
 printf("sender: starting work\n");
 struct message_container* message = (struct message_container*) data;
 printf("sender: sending message\n");
 printf("sender: FROM: %s\n", message->mail_from);
 printf("sender: TO: %s\n", message->rcpt_to);
 printf("sender: BODY:\n");
 if (message->body)
  printf("%s", message->body);
 else
  printf("No body.\n");
 printf("\n");
 free(message->mail_from);
 free(message->rcpt_to);
 free(message->body);
 free(message);
 printf("sender: finished\n");
 return ((void *)0);
}

canonical_original_code:
void *sender_worker(void *data) {
 printf("sender: starting work\n");
 struct message_container *message = (struct message_container*) data;
 printf("sender: sending message\n");
 printf("sender: FROM: %s\n", message->mail_from);
 printf("sender: TO: %s\n", message->rcpt_to);
 printf("sender: BODY:\n");
 if (message->body)
  printf("%s", message->body);
 else
  printf("No body.\n");
 printf("\n");
 free(message->mail_from);
 free(message->rcpt_to);
 free(message->body);
 free(message);
 printf("sender: finished\n");
 return ((void *)0);
}

variable_types:
data
void *

variable_types: struct message_container { char *mail_from; char *rcpt_to; char *body; } *

return_type: void *


decompiled_code:
int __fastcall session_submit(unsigned int *a1)
{
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

printf("session %d: received message '%s'\n", *a1, *(const char **)(*((_QWORD *)a1 + 3) + 16LL));
printf("session %d: handing off message to sender\n", *a1);
return pthread_create(newthread, 0LL, (void *(*)(void *))&sender_worker, *((void **)a1 + 3));
}

canonical_decompiled_code:
int __fastcall func0(unsigned int *a1)
{
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

printf("session %d: received message '%s'\n", *a1, *(const char **)(*((_QWORD *)a1 + 3) + 16LL));
printf("session %d: handing off message to sender\n", *a1);
return pthread_create(newthread, 0LL, (void *(*)(void *))&sender_worker, *((void **)a1 + 3));
}

original_code:
void session_submit(struct session_data * session) {
 printf("session %d: received message '%s'\n", session->sockfd, session->message->body);
 printf("session %d: handing off message to sender\n", session->sockfd);
 pthread_t sender;
 pthread_create(&sender, ((void *)0), sender_worker, session->message);
}

canonical_original_code:
void session_submit(struct session_data *session) {
 printf("session %d: received message '%s'\n", session->sockfd, session->message->body);
 printf("session %d: handing off message to sender\n", session->sockfd);
 unsigned long sender;
 pthread_create(&sender, ((void *)0), sender_worker, session->message);
}

variable_types: struct session_data { int sockfd; int state; int command; char *domain; struct message_container { char *mail_from; char *rcpt_to; char *body; } *message; } *

variable_types:
sender
unsigned long

user_defined_types: struct session_data { int sockfd; int state; int command; char *domain; struct message_container *message; }


decompiled_code:
__int64 __fastcall session_worker(void *ptr)
{
unsigned int v2; // er13
void *v3; // r14
int v4; // ebx
struct epoll_event *v5; // r12
int v6; // eax
int v8; // eax
char *v9; // rax
const char **v10; // r8
char *v11; // r8
const char *v12; // rdi
__int64 v13; // rdx
const char **v14; // r8
const char *v15; // rsi
char *v16; // rax
char *v17; // rax
void *v18; // rdi
size_t v19; // rax
const char *v20; // rdi
char **v21; // rdx
char *v22; // rax
__int64 v23; // r11
const char *v24; // rsi
char *v25; // rax
char *v26; // rax
char *v27; // rax
__int64 v28; // r10
void *v29; // rdi
char *v30; // rax
char *ptra; // [rsp+0h] [rbp-78h]
char *ptrd; // [rsp+0h] [rbp-78h]
const char **ptrb; // [rsp+0h] [rbp-78h]
char *ptre; // [rsp+0h] [rbp-78h]
char *ptrf; // [rsp+0h] [rbp-78h]
void *ptrg; // [rsp+0h] [rbp-78h]
char *ptrh; // [rsp+0h] [rbp-78h]
char *ptri; // [rsp+0h] [rbp-78h]
char *ptrc; // [rsp+0h] [rbp-78h]
char *ptrj; // [rsp+0h] [rbp-78h]
char *ptrk; // [rsp+0h] [rbp-78h]
char *ptrl; // [rsp+0h] [rbp-78h]
_QWORD *ptrm; // [rsp+0h] [rbp-78h]
void *ptrn; // [rsp+0h] [rbp-78h]
char *ptro; // [rsp+0h] [rbp-78h]
const char **ptrp; // [rsp+0h] [rbp-78h]
_QWORD *ptrq; // [rsp+0h] [rbp-78h]
size_t s; // [rsp+8h] [rbp-70h]
char *sa; // [rsp+8h] [rbp-70h]
char *sb; // [rsp+8h] [rbp-70h]
size_t v51; // [rsp+10h] [rbp-68h]
size_t v52; // [rsp+10h] [rbp-68h]
__int64 v53; // [rsp+20h] [rbp-58h]
__int64 v54; // [rsp+20h] [rbp-58h]
char *v55; // [rsp+28h] [rbp-50h]
char *v56; // [rsp+28h] [rbp-50h]
struct epoll_event event; // [rsp+34h] [rbp-44h] BYREF

v2 = *(_DWORD *)ptr;
session_reset(ptr);
printf("session %d: starting work, state %d\n", v2, *((unsigned int *)ptr + 1));
send(v2, "220 SMTP tsmtp\n", 0xFuLL, 0);
v3 = calloc(0x400uLL, 1uLL);
event.data.fd = v2;
v4 = epoll_create(1);
event.events = 1;
epoll_ctl(v4, 1, v2, &event);
v5 = (struct epoll_event *)calloc(1uLL, 0xCuLL);
while ( *((_DWORD *)ptr + 1) != 5 )
{
v6 = epoll_wait(v4, v5, 1, 30000);
if ( !v6 )
{
close(v2);
printf("session %d: timeout, work is over\n", v2);
break;
}
if ( v6 == 1 )
{
memset(v3, 0, 0x400uLL);
v8 = recv(v2, v3, 0x3FFuLL, 0);
if ( !v8 )
{
printf("session %d: client closed connection\n", v2);
break;
}
if ( v8 < 0 )
{
printf("session %d: recv error\n", v2);
break;
}
v9 = (char *)parse_request(v3);
v10 = (const char **)v9;
if ( *((_DWORD *)ptr + 1) != 4 )
{
switch ( *(_DWORD *)v9 )
{
case 0:
goto LABEL_19;
case 1:
goto LABEL_11;
case 2:
goto LABEL_17;
case 3:
goto LABEL_15;
case 4:
goto LABEL_12;
case 5:
goto LABEL_22;
default:
goto LABEL_30;
}
}
if ( *(_DWORD *)v9 != 4 )
{
v15 = *(const char **)(*((_QWORD *)ptr + 3) + 16LL);
if ( v15 )
{
v53 = *((_QWORD *)ptr + 3);
v55 = v9;
ptrg = (void *)strlen((const char *)v3);
v51 = strlen(v15);
s = (int)ptrg + (int)v51 + 1;
v16 = (char *)malloc(s);
v17 = strncpy(v16, v15, v51 + 1);
ptrh = strncat(v17, (const char *)v3, (size_t)ptrg);
ptrh[s] = 0;
free(*(void **)(v53 + 16));
v11 = v55;
*(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = ptrh;
}
else
{
ptrm = (_QWORD *)*((_QWORD *)ptr + 3);
sa = v9;
v22 = strdup((const char *)v3);
v11 = sa;
ptrm[2] = v22;
}
v18 = (void *)*((_QWORD *)v11 + 1);
if ( v18 )
{
ptri = v11;
free(v18);
v11 = ptri;
}
goto LABEL_14;
}
ptrc = v9;
v19 = strlen((const char *)v3);
v10 = (const char **)ptrc;
if ( v19 <= 3 )
goto LABEL_29;
v23 = *((_QWORD *)ptr + 3);
v24 = *(const char **)(v23 + 16);
if ( v24 )
{
v56 = ptrc;
v54 = *((_QWORD *)ptr + 3);
ptrn = (void *)v19;
v52 = strlen(*(const char **)(v23 + 16));
v25 = (char *)malloc((int)ptrn + (int)v52 + 1);
v26 = strncpy(v25, v24, v52 + 1);
v27 = strncat(v26, (const char *)v3, (size_t)ptrn - 5);
v28 = (int)ptrn + (int)v52 + 1;
ptro = v27;
v27[v28] = 0;
free(*(void **)(v54 + 16));
v10 = (const char **)v56;
v29 = (void *)*((_QWORD *)v56 + 1);
*(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = ptro;
if ( !v29 )
goto LABEL_36;
}
else
{
sb = ptrc;
ptrq = (_QWORD *)*((_QWORD *)ptr + 3);
v30 = strdup((const char *)v3);
v10 = (const char **)sb;
v29 = (void *)*((_QWORD *)sb + 1);
ptrq[2] = v30;
if ( !v29 )
{
LABEL_29:
ptrj = (char *)v10;
session_submit((unsigned int *)ptr);
session_reset(ptr);
*((_DWORD *)ptr + 1) = 1;
send(v2, "250 Ok\n", 7uLL, 0);
printf("session %d: data transaction over, state changed to greeted\n", v2);
v11 = ptrj;
goto LABEL_14;
}
}
ptrp = v10;
free(v29);
v10 = ptrp;
LABEL_36:
switch ( *(_DWORD *)v10 )
{
case 0:
LABEL_19:
ptrb = v10;
session_reset(ptr);
v14 = ptrb;
if ( !*((_DWORD *)ptr + 1) )
{
send(v2, "250 Ok\n", 7uLL, 0);
v14 = ptrb;
}
*((_DWORD *)ptr + 1) = 1;
ptre = (char *)v14;
*((_QWORD *)ptr + 2) = strdup(v14[1]);
printf("session %d: state changed to greeted\n", v2);
v11 = ptre;
break;
case 1:
LABEL_11:
if ( *((_DWORD *)ptr + 1) != 1 )
goto LABEL_12;
v20 = v10[1];
v21 = (char **)*((_QWORD *)ptr + 3);
*((_DWORD *)ptr + 1) = 2;
ptrl = (char *)v10;
*v21 = strdup(v20);
send(v2, "250 Ok\n", 7uLL, 0);
printf("session %d: got mail from\n", v2);
v11 = ptrl;
break;
case 2:
LABEL_17:
if ( (unsigned int)(*((_DWORD *)ptr + 1) - 2) > 1 )
goto LABEL_12;
v12 = v10[1];
v13 = *((_QWORD *)ptr + 3);
*((_DWORD *)ptr + 1) = 3;
ptrd = (char *)v10;
*(_QWORD *)(v13 + 8) = strdup(v12);
send(v2, "250 Ok\n", 7uLL, 0);
printf("session %d: state changed to got receipients\n", v2);
v11 = ptrd;
break;
case 3:
LABEL_15:
ptra = (char *)v10;
if ( *((_DWORD *)ptr + 1) != 3 )
goto LABEL_13;
*((_DWORD *)ptr + 1) = 4;
send(v2, "354 End data with <CR><LF>.<CR><LF>\n", 0x24uLL, 0);
printf("session %d: state changed to data receival\n", v2);
v11 = ptra;
break;
case 4:
if ( *((_DWORD *)ptr + 1) == 4 )
goto LABEL_29;
LABEL_12:
ptra = (char *)v10;
LABEL_13:
send(
v2,
"503 Commands out of order: HELO -> (MAIL -> RCPT (+) -> DATA -> text -> CRLF.CRLF)(*) -> QUIT\n",
0x5EuLL,
0);
v11 = ptra;
break;
case 5:
LABEL_22:
*((_DWORD *)ptr + 1) = 5;
ptrf = (char *)v10;
send(v2, "221 Bye\n", 8uLL, 0);
printf("session %d: state changed to quit\n", v2);
v11 = ptrf;
break;
default:
LABEL_30:
ptrk = (char *)v10;
send(v2, "501 Syntax error\n", 0x11uLL, 0);
printf("session %d: syntax error\n", v2);
v11 = ptrk;
break;
}
LABEL_14:
free(v11);
}
}
free(v3);
free(ptr);
printf("session %d: finished\n", v2);
close(v2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *ptr)
{
unsigned int v2; // er13
void *v3; // r14
int v4; // ebx
struct epoll_event *v5; // r12
int v6; // eax
int v8; // eax
char *v9; // rax
const char **v10; // r8
char *v11; // r8
const char *v12; // rdi
__int64 v13; // rdx
const char **v14; // r8
const char *v15; // rsi
char *v16; // rax
char *v17; // rax
void *v18; // rdi
size_t v19; // rax
const char *v20; // rdi
char **v21; // rdx
char *v22; // rax
__int64 v23; // r11
const char *v24; // rsi
char *v25; // rax
char *v26; // rax
char *v27; // rax
__int64 v28; // r10
void *v29; // rdi
char *v30; // rax
char *ptra; // [rsp+0h] [rbp-78h]
char *ptrd; // [rsp+0h] [rbp-78h]
const char **ptrb; // [rsp+0h] [rbp-78h]
char *ptre; // [rsp+0h] [rbp-78h]
char *ptrf; // [rsp+0h] [rbp-78h]
void *ptrg; // [rsp+0h] [rbp-78h]
char *ptrh; // [rsp+0h] [rbp-78h]
char *ptri; // [rsp+0h] [rbp-78h]
char *ptrc; // [rsp+0h] [rbp-78h]
char *ptrj; // [rsp+0h] [rbp-78h]
char *ptrk; // [rsp+0h] [rbp-78h]
char *ptrl; // [rsp+0h] [rbp-78h]
_QWORD *ptrm; // [rsp+0h] [rbp-78h]
void *ptrn; // [rsp+0h] [rbp-78h]
char *ptro; // [rsp+0h] [rbp-78h]
const char **ptrp; // [rsp+0h] [rbp-78h]
_QWORD *ptrq; // [rsp+0h] [rbp-78h]
size_t s; // [rsp+8h] [rbp-70h]
char *sa; // [rsp+8h] [rbp-70h]
char *sb; // [rsp+8h] [rbp-70h]
size_t v51; // [rsp+10h] [rbp-68h]
size_t v52; // [rsp+10h] [rbp-68h]
__int64 v53; // [rsp+20h] [rbp-58h]
__int64 v54; // [rsp+20h] [rbp-58h]
char *v55; // [rsp+28h] [rbp-50h]
char *v56; // [rsp+28h] [rbp-50h]
struct epoll_event event; // [rsp+34h] [rbp-44h] BYREF

v2 = *(_DWORD *)ptr;
session_reset(ptr);
printf("session %d: starting work, state %d\n", v2, *((unsigned int *)ptr + 1));
send(v2, "220 SMTP tsmtp\n", 0xFuLL, 0);
v3 = calloc(0x400uLL, 1uLL);
event.data.fd = v2;
v4 = epoll_create(1);
event.events = 1;
epoll_ctl(v4, 1, v2, &event);
v5 = (struct epoll_event *)calloc(1uLL, 0xCuLL);
while ( *((_DWORD *)ptr + 1) != 5 )
{
v6 = epoll_wait(v4, v5, 1, 30000);
if ( !v6 )
{
close(v2);
printf("session %d: timeout, work is over\n", v2);
break;
}
if ( v6 == 1 )
{
memset(v3, 0, 0x400uLL);
v8 = recv(v2, v3, 0x3FFuLL, 0);
if ( !v8 )
{
printf("session %d: client closed connection\n", v2);
break;
}
if ( v8 < 0 )
{
printf("session %d: recv error\n", v2);
break;
}
v9 = (char *)parse_request(v3);
v10 = (const char **)v9;
if ( *((_DWORD *)ptr + 1) != 4 )
{
switch ( *(_DWORD *)v9 )
{
case 0:
goto LABEL_19;
case 1:
goto LABEL_11;
case 2:
goto LABEL_17;
case 3:
goto LABEL_15;
case 4:
goto LABEL_12;
case 5:
goto LABEL_22;
default:
goto LABEL_30;
}
}
if ( *(_DWORD *)v9 != 4 )
{
v15 = *(const char **)(*((_QWORD *)ptr + 3) + 16LL);
if ( v15 )
{
v53 = *((_QWORD *)ptr + 3);
v55 = v9;
ptrg = (void *)strlen((const char *)v3);
v51 = strlen(v15);
s = (int)ptrg + (int)v51 + 1;
v16 = (char *)malloc(s);
v17 = strncpy(v16, v15, v51 + 1);
ptrh = strncat(v17, (const char *)v3, (size_t)ptrg);
ptrh[s] = 0;
free(*(void **)(v53 + 16));
v11 = v55;
*(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = ptrh;
}
else
{
ptrm = (_QWORD *)*((_QWORD *)ptr + 3);
sa = v9;
v22 = strdup((const char *)v3);
v11 = sa;
ptrm[2] = v22;
}
v18 = (void *)*((_QWORD *)v11 + 1);
if ( v18 )
{
ptri = v11;
free(v18);
v11 = ptri;
}
goto LABEL_14;
}
ptrc = v9;
v19 = strlen((const char *)v3);
v10 = (const char **)ptrc;
if ( v19 <= 3 )
goto LABEL_29;
v23 = *((_QWORD *)ptr + 3);
v24 = *(const char **)(v23 + 16);
if ( v24 )
{
v56 = ptrc;
v54 = *((_QWORD *)ptr + 3);
ptrn = (void *)v19;
v52 = strlen(*(const char **)(v23 + 16));
v25 = (char *)malloc((int)ptrn + (int)v52 + 1);
v26 = strncpy(v25, v24, v52 + 1);
v27 = strncat(v26, (const char *)v3, (size_t)ptrn - 5);
v28 = (int)ptrn + (int)v52 + 1;
ptro = v27;
v27[v28] = 0;
free(*(void **)(v54 + 16));
v10 = (const char **)v56;
v29 = (void *)*((_QWORD *)v56 + 1);
*(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = ptro;
if ( !v29 )
goto LABEL_36;
}
else
{
sb = ptrc;
ptrq = (_QWORD *)*((_QWORD *)ptr + 3);
v30 = strdup((const char *)v3);
v10 = (const char **)sb;
v29 = (void *)*((_QWORD *)sb + 1);
ptrq[2] = v30;
if ( !v29 )
{
LABEL_29:
ptrj = (char *)v10;
func0((unsigned int *)ptr);
session_reset(ptr);
*((_DWORD *)ptr + 1) = 1;
send(v2, "250 Ok\n", 7uLL, 0);
printf("session %d: data transaction over, state changed to greeted\n", v2);
v11 = ptrj;
goto LABEL_14;
}
}
ptrp = v10;
free(v29);
v10 = ptrp;
LABEL_36:
switch ( *(_DWORD *)v10 )
{
case 0:
LABEL_19:
ptrb = v10;
session_reset(ptr);
v14 = ptrb;
if ( !*((_DWORD *)ptr + 1) )
{
send(v2, "250 Ok\n", 7uLL, 0);
v14 = ptrb;
}
*((_DWORD *)ptr + 1) = 1;
ptre = (char *)v14;
*((_QWORD *)ptr + 2) = strdup(v14[1]);
printf("session %d: state changed to greeted\n", v2);
v11 = ptre;
break;
case 1:
LABEL_11:
if ( *((_DWORD *)ptr + 1) != 1 )
goto LABEL_12;
v20 = v10[1];
v21 = (char **)*((_QWORD *)ptr + 3);
*((_DWORD *)ptr + 1) = 2;
ptrl = (char *)v10;
*v21 = strdup(v20);
send(v2, "250 Ok\n", 7uLL, 0);
printf("session %d: got mail from\n", v2);
v11 = ptrl;
break;
case 2:
LABEL_17:
if ( (unsigned int)(*((_DWORD *)ptr + 1) - 2) > 1 )
goto LABEL_12;
v12 = v10[1];
v13 = *((_QWORD *)ptr + 3);
*((_DWORD *)ptr + 1) = 3;
ptrd = (char *)v10;
*(_QWORD *)(v13 + 8) = strdup(v12);
send(v2, "250 Ok\n", 7uLL, 0);
printf("session %d: state changed to got receipients\n", v2);
v11 = ptrd;
break;
case 3:
LABEL_15:
ptra = (char *)v10;
if ( *((_DWORD *)ptr + 1) != 3 )
goto LABEL_13;
*((_DWORD *)ptr + 1) = 4;
send(v2, "354 End data with <CR><LF>.<CR><LF>\n", 0x24uLL, 0);
printf("session %d: state changed to data receival\n", v2);
v11 = ptra;
break;
case 4:
if ( *((_DWORD *)ptr + 1) == 4 )
goto LABEL_29;
LABEL_12:
ptra = (char *)v10;
LABEL_13:
send(
v2,
"503 Commands out of order: HELO -> (MAIL -> RCPT (+) -> DATA -> text -> CRLF.CRLF)(*) -> QUIT\n",
0x5EuLL,
0);
v11 = ptra;
break;
case 5:
LABEL_22:
*((_DWORD *)ptr + 1) = 5;
ptrf = (char *)v10;
send(v2, "221 Bye\n", 8uLL, 0);
printf("session %d: state changed to quit\n", v2);
v11 = ptrf;
break;
default:
LABEL_30:
ptrk = (char *)v10;
send(v2, "501 Syntax error\n", 0x11uLL, 0);
printf("session %d: syntax error\n", v2);
v11 = ptrk;
break;
}
LABEL_14:
free(v11);
}
}
free(v3);
free(ptr);
printf("session %d: finished\n", v2);
close(v2);
return 0LL;
}

original_code:
void* session_worker(void* data) {
 int capacity = 1;
 int timeout = 30000;
 struct session_data * session = (struct session_data*) data;
 int sockfd = session->sockfd;
 session_reset(session);
 printf("session %d: starting work, state %d\n", sockfd, session->state);
 send(sockfd, (void*) server_replies[REPLY_GREET], strlen(server_replies[REPLY_GREET]), 0);
 int buffer_size = 1024;
 char* buffer = calloc(buffer_size, sizeof(char));
 int epoll_set = epoll_create(capacity);
 struct epoll_event listen_event;
 listen_event.data.fd = sockfd;
 listen_event.events = EPOLLIN;
 epoll_ctl(epoll_set, 1, sockfd, &listen_event);
 struct epoll_event* caught_events = calloc(capacity, sizeof(struct epoll_event));
 while (session->state != SESSION_QUIT) {
  int nfds = epoll_wait(epoll_set, caught_events, 1, timeout);
  if (nfds == 0) {
   close(sockfd);
   printf("session %d: timeout, work is over\n", sockfd);
   break;
  }
  if (nfds == 1) {
   memset(buffer, 0, 1024);
   int received_bytes = recv(sockfd, buffer, buffer_size - 1, 0);
   if (received_bytes == 0) {
    printf("session %d: client closed connection\n", sockfd);
    break;
   }
   if (received_bytes < 0) {
    printf("session %d: recv error\n", sockfd);
    break;
   }
   struct request* req = parse_request(buffer);
   if (session->state == SESSION_DATA && req->command != CMD_CRLF) {
    if (!session->message->body) {
     session->message->body = strdup(buffer);
    } else {
     int size = strlen(buffer) + strlen(session->message->body) + 1;
     char * extended_message = (char*) malloc(sizeof(char) * size);
     strncpy(extended_message, session->message->body, strlen(session->message->body)+1);
     strncat(extended_message, buffer, strlen(buffer));
     extended_message[size] = '\0';
     free(session->message->body);
     session->message->body = extended_message;
    }
    if (req->arguments) {
     free(req->arguments);
    }
    free(req);
    continue;
   }
   if (session->state == SESSION_DATA && req->command == CMD_CRLF && (strlen(buffer) > 3)) {
    if (!session->message->body) {
     session->message->body = strdup(buffer);
    } else {
     int size = strlen(buffer) + strlen(session->message->body) + 1;
     char * extended_message = (char*) malloc(sizeof(char) * size);
     strncpy(extended_message, session->message->body, strlen(session->message->body)+1);
     strncat(extended_message, buffer, strlen(buffer)-5);
     extended_message[size] = '\0';
     free(session->message->body);
     session->message->body = extended_message;
    }
    if (req->arguments) {
     free(req->arguments);
    }
   }
   switch(req->command) {
    case CMD_HELO:
     session_reset(session);
     if (session->state == SESSION_NEW) {
      send(sockfd, (void*) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
     }
     session->state = SESSION_GREET;
     session->domain = strdup((char*) (req->arguments));
     printf("session %d: state changed to greeted\n", sockfd);
     break;
    case CMD_MAIL:
     if (session->state == SESSION_GREET) {
      session->state = SESSION_MAIL;
      session->message->mail_from = strdup((char*) (req->arguments));
      send(sockfd, (void*) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
      printf("session %d: got mail from\n", sockfd);
     } else {
      send(sockfd, (void*) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_RCPT:
     if (session->state == SESSION_MAIL || session->state == SESSION_RCPT) {
      session->state = SESSION_RCPT;
      session->message->rcpt_to = strdup((char*) (req->arguments));
      send(sockfd, (void*) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
      printf("session %d: state changed to got receipients\n", sockfd);
     } else {
      send(sockfd, (void*) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_DATA:
     if (session->state == SESSION_RCPT) {
      session->state = SESSION_DATA;
      send(sockfd, (void*) server_replies[REPLY_DATA_INFO], strlen(server_replies[REPLY_DATA_INFO]), 0);
      printf("session %d: state changed to data receival\n", sockfd);
     } else {
      send(sockfd, (void*) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_CRLF:
     if (session->state == SESSION_DATA) {
      session_submit(session);
      session_reset(session);
      session->state = SESSION_GREET;
      send(sockfd, (void*) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
      printf("session %d: data transaction over, state changed to greeted\n", sockfd);
     } else {
      send(sockfd, (void*) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_QUIT:
     session->state = SESSION_QUIT;
     send(sockfd, (void*) server_replies[REPLY_BYE], strlen(server_replies[REPLY_BYE]), 0);
     printf("session %d: state changed to quit\n", sockfd);
     break;
    default:
     send(sockfd, (void*) server_replies[REPLY_SYNTAX_ERROR], strlen(server_replies[REPLY_SYNTAX_ERROR]), 0);
     printf("session %d: syntax error\n", sockfd);
     break;
   }
   free(req);
  }
 }
 free(buffer);
 free(data);
 printf("session %d: finished\n", sockfd);
 close(sockfd);
 return ((void *)0);
}

canonical_original_code:
void *session_worker(void *data) {
 int capacity = 1;
 int timeout = 30000;
 struct session_data *session = (struct session_data*) data;
 int sockfd = session->sockfd;
 session_reset(session);
 printf("session %d: starting work, state %d\n", sockfd, session->state);
 send(sockfd, (void *) server_replies[REPLY_GREET], strlen(server_replies[REPLY_GREET]), 0);
 int buffer_size = 1024;
 char *buffer = calloc(buffer_size, sizeof(char));
 int epoll_set = epoll_create(capacity);
 struct epoll_event listen_event;
 listen_event.data.fd = sockfd;
 listen_event.events = EPOLLIN;
 epoll_ctl(epoll_set, 1, sockfd, &listen_event);
 struct epoll_event *caught_events = calloc(capacity, sizeof(struct epoll_event));
 while (session->state != SESSION_QUIT) {
  int nfds = epoll_wait(epoll_set, caught_events, 1, timeout);
  if (nfds == 0) {
   close(sockfd);
   printf("session %d: timeout, work is over\n", sockfd);
   break;
  }
  if (nfds == 1) {
   memset(buffer, 0, 1024);
   int received_bytes = recv(sockfd, buffer, buffer_size - 1, 0);
   if (received_bytes == 0) {
    printf("session %d: client closed connection\n", sockfd);
    break;
   }
   if (received_bytes < 0) {
    printf("session %d: recv error\n", sockfd);
    break;
   }
   struct request *req = parse_request(buffer);
   if (session->state == SESSION_DATA && req->command != CMD_CRLF) {
    if (!session->message->body) {
     session->message->body = strdup(buffer);
    } else {
     int size = strlen(buffer) + strlen(session->message->body) + 1;
     char *extended_message = (char*) malloc(sizeof(char) * size);
     strncpy(extended_message, session->message->body, strlen(session->message->body)+1);
     strncat(extended_message, buffer, strlen(buffer));
     extended_message[size] = '\0';
     free(session->message->body);
     session->message->body = extended_message;
    }
    if (req->arguments) {
     free(req->arguments);
    }
    free(req);
    continue;
   }
   if (session->state == SESSION_DATA && req->command == CMD_CRLF && (strlen(buffer) > 3)) {
    if (!session->message->body) {
     session->message->body = strdup(buffer);
    } else {
     int size = strlen(buffer) + strlen(session->message->body) + 1;
     char *extended_message = (char*) malloc(sizeof(char) * size);
     strncpy(extended_message, session->message->body, strlen(session->message->body)+1);
     strncat(extended_message, buffer, strlen(buffer)-5);
     extended_message[size] = '\0';
     free(session->message->body);
     session->message->body = extended_message;
    }
    if (req->arguments) {
     free(req->arguments);
    }
   }
   switch(req->command) {
    case CMD_HELO:
     session_reset(session);
     if (session->state == SESSION_NEW) {
      send(sockfd, (void *) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
     }
     session->state = SESSION_GREET;
     session->domain = strdup((char *) (req->arguments));
     printf("session %d: state changed to greeted\n", sockfd);
     break;
    case CMD_MAIL:
     if (session->state == SESSION_GREET) {
      session->state = SESSION_MAIL;
      session->message->mail_from = strdup((char *) (req->arguments));
      send(sockfd, (void *) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
      printf("session %d: got mail from\n", sockfd);
     } else {
      send(sockfd, (void *) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_RCPT:
     if (session->state == SESSION_MAIL || session->state == SESSION_RCPT) {
      session->state = SESSION_RCPT;
      session->message->rcpt_to = strdup((char *) (req->arguments));
      send(sockfd, (void *) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
      printf("session %d: state changed to got receipients\n", sockfd);
     } else {
      send(sockfd, (void *) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_DATA:
     if (session->state == SESSION_RCPT) {
      session->state = SESSION_DATA;
      send(sockfd, (void *) server_replies[REPLY_DATA_INFO], strlen(server_replies[REPLY_DATA_INFO]), 0);
      printf("session %d: state changed to data receival\n", sockfd);
     } else {
      send(sockfd, (void *) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_CRLF:
     if (session->state == SESSION_DATA) {
      session_submit(session);
      session_reset(session);
      session->state = SESSION_GREET;
      send(sockfd, (void *) server_replies[REPLY_OK], strlen(server_replies[REPLY_OK]), 0);
      printf("session %d: data transaction over, state changed to greeted\n", sockfd);
     } else {
      send(sockfd, (void *) server_replies[REPLY_OOO], strlen(server_replies[REPLY_OOO]), 0);
     }
     break;
    case CMD_QUIT:
     session->state = SESSION_QUIT;
     send(sockfd, (void *) server_replies[REPLY_BYE], strlen(server_replies[REPLY_BYE]), 0);
     printf("session %d: state changed to quit\n", sockfd);
     break;
    default:
     send(sockfd, (void *) server_replies[REPLY_SYNTAX_ERROR], strlen(server_replies[REPLY_SYNTAX_ERROR]), 0);
     printf("session %d: syntax error\n", sockfd);
     break;
   }
   free(req);
  }
 }
 free(buffer);
 free(data);
 printf("session %d: finished\n", sockfd);
 close(sockfd);
 return ((void *)0);
}

variable_types: capacity int

variable_types: timeout int

variable_types: sockfd int

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

variable_types: nfds int

variable_types: struct request { int command; char *arguments; } *

variable_types: size int

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

user_defined_types: struct message_container { char *mail_from; char *rcpt_to; char *body; }


listener

decompiled_code:
void __fastcall __noreturn listener(char *service)
{
struct addrinfo *v1; // rax
int v2; // eax
int v3; // ebx
int v4; // eax
int v5; // er12
struct epoll_event *v6; // rbp
int v7; // eax
epoll_data_t *v8; // r15
__int64 v9; // r8
_WORD *v10; // rax
socklen_t v11; // ecx
_DWORD *v12; // rax
int v13; // [rsp+0h] [rbp-154h]
__int64 v14; // [rsp+4h] [rbp-150h]
socklen_t addr_len; // [rsp+14h] [rbp-140h] BYREF
int optval; // [rsp+18h] [rbp-13Ch] BYREF
struct addrinfo *pai; // [rsp+1Ch] [rbp-138h] BYREF
pthread_t newthread; // [rsp+24h] [rbp-130h] BYREF
struct epoll_event event; // [rsp+30h] [rbp-124h] BYREF
char buf[48]; // [rsp+3Ch] [rbp-118h] BYREF
struct addrinfo req; // [rsp+6Ch] [rbp-E8h] BYREF
struct sockaddr addr; // [rsp+9Ch] [rbp-B8h] BYREF

*(_OWORD *)&req.ai_flags = 0LL;
*(_OWORD *)&req.ai_addrlen = 0LL;
req.ai_socktype = 1;
req.ai_flags = 1;
*(_OWORD *)&req.ai_canonname = 0LL;
getaddrinfo(0LL, service, &req, &pai);
v1 = pai;
if ( !pai )
{
puts("Cannot resolve remote address.");
v1 = pai;
}
v2 = socket(v1->ai_family, v1->ai_socktype, v1->ai_protocol);
v3 = v2;
if ( v2 < 0 )
{
puts("Cannot create socket.");
exit(1);
}
optval = 1;
if ( setsockopt(v2, 1, 2, &optval, 4u) < 0 )
{
puts("setsockopt failed.");
exit(1);
}
if ( bind(v3, pai->ai_addr, pai->ai_addrlen) < 0 )
{
puts("Bind failed.");
exit(1);
}
freeaddrinfo(pai);
if ( listen(v3, 10) < 0 )
{
puts("Listening failed.");
exit(1);
}
puts("listener: waiting for connections...");
v4 = epoll_create(16);
event.data.fd = v3;
event.events = 1;
v5 = v4;
epoll_ctl(v4, 1, v3, &event);
v6 = (struct epoll_event *)calloc(0x10uLL, 0xCuLL);
while ( 1 )
{
do
v7 = epoll_wait(v5, v6, 1, -1);
while ( v7 <= 0 );
v8 = &v6->data;
v9 = (__int64)&v6[(unsigned int)(v7 - 1) + 1].data;
if ( v6->data.fd == v3 )
{
LABEL_12:
v14 = v9;
addr_len = 128;
v13 = accept(v3, &addr, &addr_len);
v10 = get_in_addr(&addr);
inet_ntop(addr.sa_family, v10, buf, v11);
printf("listener: got connection from %s\n", buf);
v12 = malloc(0x20uLL);
v12[1] = 0;
*v12 = v13;
pthread_create(&newthread, 0LL, (void *(*)(void *))&session_worker, v12);
puts("listener: initiated a new session worker");
v9 = v14;
}
while ( 1 )
{
v8 = (epoll_data_t *)((char *)v8 + 12);
if ( v8 == (epoll_data_t *)v9 )
break;
if ( v8->fd == v3 )
goto LABEL_12;
}
}
}

canonical_decompiled_code:
void __fastcall __noreturn func0(char *service)
{
struct addrinfo *v1; // rax
int v2; // eax
int v3; // ebx
int v4; // eax
int v5; // er12
struct epoll_event *v6; // rbp
int v7; // eax
epoll_data_t *v8; // r15
__int64 v9; // r8
_WORD *v10; // rax
socklen_t v11; // ecx
_DWORD *v12; // rax
int v13; // [rsp+0h] [rbp-154h]
__int64 v14; // [rsp+4h] [rbp-150h]
socklen_t addr_len; // [rsp+14h] [rbp-140h] BYREF
int optval; // [rsp+18h] [rbp-13Ch] BYREF
struct addrinfo *pai; // [rsp+1Ch] [rbp-138h] BYREF
pthread_t newthread; // [rsp+24h] [rbp-130h] BYREF
struct epoll_event event; // [rsp+30h] [rbp-124h] BYREF
char buf[48]; // [rsp+3Ch] [rbp-118h] BYREF
struct addrinfo req; // [rsp+6Ch] [rbp-E8h] BYREF
struct sockaddr addr; // [rsp+9Ch] [rbp-B8h] BYREF

*(_OWORD *)&req.ai_flags = 0LL;
*(_OWORD *)&req.ai_addrlen = 0LL;
req.ai_socktype = 1;
req.ai_flags = 1;
*(_OWORD *)&req.ai_canonname = 0LL;
getaddrinfo(0LL, service, &req, &pai);
v1 = pai;
if ( !pai )
{
puts("Cannot resolve remote address.");
v1 = pai;
}
v2 = socket(v1->ai_family, v1->ai_socktype, v1->ai_protocol);
v3 = v2;
if ( v2 < 0 )
{
puts("Cannot create socket.");
exit(1);
}
optval = 1;
if ( setsockopt(v2, 1, 2, &optval, 4u) < 0 )
{
puts("setsockopt failed.");
exit(1);
}
if ( bind(v3, pai->ai_addr, pai->ai_addrlen) < 0 )
{
puts("Bind failed.");
exit(1);
}
freeaddrinfo(pai);
if ( listen(v3, 10) < 0 )
{
puts("Listening failed.");
exit(1);
}
puts("listener: waiting for connections...");
v4 = epoll_create(16);
event.data.fd = v3;
event.events = 1;
v5 = v4;
epoll_ctl(v4, 1, v3, &event);
v6 = (struct epoll_event *)calloc(0x10uLL, 0xCuLL);
while ( 1 )
{
do
v7 = epoll_wait(v5, v6, 1, -1);
while ( v7 <= 0 );
v8 = &v6->data;
v9 = (__int64)&v6[(unsigned int)(v7 - 1) + 1].data;
if ( v6->data.fd == v3 )
{
LABEL_12:
v14 = v9;
addr_len = 128;
v13 = accept(v3, &addr, &addr_len);
v10 = get_in_addr(&addr);
inet_ntop(addr.sa_family, v10, buf, v11);
printf("listener: got connection from %s\n", buf);
v12 = malloc(0x20uLL);
v12[1] = 0;
*v12 = v13;
pthread_create(&newthread, 0LL, (void *(*)(void *))&session_worker, v12);
puts("listener: initiated a new session worker");
v9 = v14;
}
while ( 1 )
{
v8 = (epoll_data_t *)((char *)v8 + 12);
if ( v8 == (epoll_data_t *)v9 )
break;
if ( v8->fd == v3 )
goto LABEL_12;
}
}
}

original_code:
int listener(char* service) {
 int sockfd, new_fd;
 struct addrinfo hints, *servinfo;
 struct sockaddr_storage their_addr;
 socklen_t sin_size;
 char s[46];
 memset(&hints, 0, sizeof hints);
 hints.ai_family = 0;
 hints.ai_socktype = SOCK_STREAM;
 hints.ai_flags = 0x0001;
 getaddrinfo(((void *)0), service, &hints, &servinfo);
 if (!servinfo) {
  printf("Cannot resolve remote address.\n");
 }
 if ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) < 0) {
  printf("Cannot create socket.\n");
  exit(1);
 }
 int on = 1;
 if (setsockopt(sockfd, 1, 2, &on, sizeof(on)) < 0) {
  printf("setsockopt failed.\n");
  exit(1);
 }
 if (bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
  printf("Bind failed.\n");
  exit(1);
 }
 freeaddrinfo(servinfo);
 if (listen(sockfd, 10) < 0) {
  printf("Listening failed.\n");
  exit(1);
 }
 printf("listener: waiting for connections...\n");
 int epfd = epoll_create(16);
 struct epoll_event listen_event;
 listen_event.data.fd = sockfd;
 listen_event.events = EPOLLIN;
 epoll_ctl(epfd, 1, sockfd, &listen_event);
 struct epoll_event* caught_events = calloc(16, sizeof(struct epoll_event));
 for (;;) {
  int nfds = epoll_wait(epfd, caught_events, 1, -1);
  int i;
  for (i = 0; i < nfds; i++) {
   if (caught_events[i].data.fd == sockfd) {
    sin_size = sizeof their_addr;
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
    printf("listener: got connection from %s\n", s);
    pthread_t session_thread;
    struct session_data * data = malloc(sizeof(struct session_data));
    data->sockfd = new_fd;
    data->state = SESSION_NEW;
    pthread_create(&session_thread, ((void *)0), session_worker, data);
    printf("listener: initiated a new session worker\n");
   }
  }
 }
 free(caught_events);
 printf("listener: finished\n");
 return 0;
}

canonical_original_code:
int listener(char *service) {
 int sockfd; int new_fd;
 struct addrinfo hints; struct addrinfo *servinfo;
 struct sockaddr_storage their_addr;
 unsigned int sin_size;
 char s[46];
 memset(&hints, 0, sizeof hints);
 hints.ai_family = 0;
 hints.ai_socktype = SOCK_STREAM;
 hints.ai_flags = 0x0001;
 getaddrinfo(((void *)0), service, &hints, &servinfo);
 if (!servinfo) {
  printf("Cannot resolve remote address.\n");
 }
 if ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) < 0) {
  printf("Cannot create socket.\n");
  exit(1);
 }
 int on = 1;
 if (setsockopt(sockfd, 1, 2, &on, sizeof(on)) < 0) {
  printf("setsockopt failed.\n");
  exit(1);
 }
 if (bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
  printf("Bind failed.\n");
  exit(1);
 }
 freeaddrinfo(servinfo);
 if (listen(sockfd, 10) < 0) {
  printf("Listening failed.\n");
  exit(1);
 }
 printf("listener: waiting for connections...\n");
 int epfd = epoll_create(16);
 struct epoll_event listen_event;
 listen_event.data.fd = sockfd;
 listen_event.events = EPOLLIN;
 epoll_ctl(epfd, 1, sockfd, &listen_event);
 struct epoll_event *caught_events = calloc(16, sizeof(struct epoll_event));
 for (;;) {
  int nfds = epoll_wait(epfd, caught_events, 1, -1);
  int i;
  for (i = 0; i < nfds; i++) {
   if (caught_events[i].data.fd == sockfd) {
    sin_size = sizeof their_addr;
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
    printf("listener: got connection from %s\n", s);
    unsigned long session_thread;
    struct session_data *data = malloc(sizeof(struct session_data));
    data->sockfd = new_fd;
    data->state = SESSION_NEW;
    pthread_create(&session_thread, ((void *)0), session_worker, data);
    printf("listener: initiated a new session worker\n");
   }
  }
 }
 free(caught_events);
 printf("listener: finished\n");
 return 0;
}

variable_types:
service
char *

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *

variable_types: struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; }

variable_types:
s
char [46]

variable_types: on int

variable_types: epfd int

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

variable_types: i int

user_defined_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }


decompiled_code:
void __fastcall free_list(void *ptr)
{
void **i; // rbp
void **v2; // rbx

if ( ptr )
{
for ( i = (void **)ptr; ; i = v2 )
{
if ( *i )
free(*i);
v2 = (void **)i[1];
free(i);
if ( !v2 )
break;
}
}
}

canonical_decompiled_code:
void __fastcall func0(void *ptr)
{
void **i; // rbp
void **v2; // rbx

if ( ptr )
{
for ( i = (void **)ptr; ; i = v2 )
{
if ( *i )
free(*i);
v2 = (void **)i[1];
free(i);
if ( !v2 )
break;
}
}
}

original_code:
void free_list(struct list* head) {
 struct list *node = head, *temp;
 while (node) {
  if (node->data)
   free(node->data);
  temp = node;
  node = node->next;
  free(temp);
 }
}

canonical_original_code:
void free_list(struct list *head) {
 struct list *node = head; struct list *temp;
 while (node) {
  if (node->data)
   free(node->data);
  temp = node;
  node = node->next;
  free(temp);
 }
}

variable_types: struct list { void *data; struct list *next; } *


main

canonical_name: main

repo: tomhennigan/stripe-ctf

original_code:
int main(void)
{
    char * output = malloc((size_t)(4096 * 4));
    short output_i = 0;
    setvbuf(stdout, ((void *)0), 2, 0);
    char * input = malloc((size_t)(4096 * 4));
    char * wordbuf = malloc(40);
    unsigned int wordbuf_i = 0;
    unsigned int n, i;
    char c;
    uint64_t * i_wp;
    n = fread(input, 1, (size_t)(4096 * 4), stdin);
    for (i=0; i<n; i++) {
        c = input[i];
        if (c == '\0') {
            break;
        }
        wordbuf[wordbuf_i] = c;
        if (c == ' ' || c == '\n') {
            if (wordbuf_i != 0) {
                i_wp = (uint64_t *)&wordbuf[wordbuf_i];
                *i_wp = 0x0000000000000000;
                if (contains(wordbuf, wordbuf_i) == 0) {
                    output[output_i++] = '<';
                    memcpy(output + output_i, wordbuf, wordbuf_i);
                    output_i += wordbuf_i;
                    output[output_i++] = '>';
                } else {
                    memcpy(output + output_i, wordbuf, wordbuf_i);
                    output_i += wordbuf_i;
                }
                wordbuf_i = 0;
            }
            output[output_i++] = c;
        } else {
            wordbuf_i++;
        }
    }
    write(1, output, output_i);
    return 0;
}

canonical_original_code:
int main()
{
    char *output = malloc((size_t)(4096 * 4));
    short output_i = 0;
    setvbuf(stdout, ((void *)0), 2, 0);
    char *input = malloc((size_t)(4096 * 4));
    char *wordbuf = malloc(40);
    unsigned int wordbuf_i = 0;
    unsigned int n; unsigned int i;
    char c;
    unsigned long *i_wp;
    n = fread(input, 1, (unsigned long)(4096 * 4), stdin);
    for (i=0; i<n; i++) {
        c = input[i];
        if (c == '\0') {
            break;
        }
        wordbuf[wordbuf_i] = c;
        if (c == ' ' || c == '\n') {
            if (wordbuf_i != 0) {
                i_wp = (unsigned long *)&wordbuf[wordbuf_i];
                *i_wp = 0x0000000000000000;
                if (contains(wordbuf, wordbuf_i) == 0) {
                    output[output_i++] = '<';
                    memcpy(output + output_i, wordbuf, wordbuf_i);
                    output_i += wordbuf_i;
                    output[output_i++] = '>';
                } else {
                    memcpy(output + output_i, wordbuf, wordbuf_i);
                    output_i += wordbuf_i;
                }
                wordbuf_i = 0;
            }
            output[output_i++] = c;
        } else {
            wordbuf_i++;
        }
    }
    write(1, output, output_i);
    return 0;
}

variable_types:
output
char *

variable_types:
input
char *

variable_types:
wordbuf
char *

variable_types:
n
unsigned int

variable_types:
i
unsigned int

variable_types: c char


repo: tommythorn/multisim

decompiled_code:
__int64 __fastcall memory_lookup(__int64 a1, unsigned __int64 a2)
{
int v2; // ecx
unsigned __int64 *v3; // rax
int v4; // edx

v2 = *(_DWORD *)(a1 + 192);
if ( v2 <= 0 )
return 0LL;
v3 = (unsigned __int64 *)(a1 + 8);
v4 = 0;
while ( *v3 > a2 || v3[1] <= a2 )
{
++v4;
v3 += 3;
if ( v4 == v2 )
return 0LL;
}
return a1 + 24LL * v4;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned __int64 a2)
{
int v2; // ecx
unsigned __int64 *v3; // rax
int v4; // edx

v2 = *(_DWORD *)(a1 + 192);
if ( v2 <= 0 )
return 0LL;
v3 = (unsigned __int64 *)(a1 + 8);
v4 = 0;
while ( *v3 > a2 || v3[1] <= a2 )
{
++v4;
v3 += 3;
if ( v4 == v2 )
return 0LL;
}
return a1 + 24LL * v4;
}

original_code:
static struct entry *memory_lookup(memory_t *m, uint64_t addr)
{
    for (int i = 0; i < m->segments; ++i)
        if (m->segment[i].start <= addr && addr < m->segment[i].end)
            return m->segment + i;
    return ((void *)0);
}

canonical_original_code:
static struct entry *memory_lookup(struct memory_st *m, unsigned long addr)
{
    for (int i = 0; i < m->segments; ++i)
        if (m->segment[i].start <= addr && addr < m->segment[i].end)
            return m->segment + i;
    return ((void *)0);
}

variable_types: struct memory_st { struct entry segment[8]; int segments; _Bool endian_is_big; unsigned long addr_mask; } *

variable_types:
addr
unsigned long

return_type: struct entry { void *phys; unsigned long start; } *


decompiled_code:
int __fastcall list_segments(__int64 a1)
{
int result; // eax
__int64 *v2; // rbx
int v3; // ebp
__int64 v4; // rdx
__int64 v5; // rsi

puts("Segments");
result = *(_DWORD *)(a1 + 192);
if ( result > 0 )
{
v2 = (__int64 *)(a1 + 8);
v3 = 0;
do
{
v4 = v2[1];
v5 = *v2;
++v3;
v2 += 3;
result = printf(" [%016lx; %016lx)\n", v5, v4);
}
while ( *(_DWORD *)(a1 + 192) > v3 );
}
return result;
}

original_code:
static void
list_segments(memory_t *m)
{
    printf("Segments\n");
    for (int i = 0; i < m->segments; ++i)
        printf("  [%016""l" "x""; %016""l" "x"")\n",
               m->segment[i].start,
               m->segment[i].end);
}

canonical_original_code:
static void list_segments(struct memory_st *m)
{
    printf("Segments\n");
    for (int i = 0; i < m->segments; ++i)
        printf("  [%016""l" "x""; %016""l" "x"")\n",
               m->segment[i].start,
               m->segment[i].end);
}

variable_types: struct memory_st { struct entry { void *phys; unsigned long start; } segment[8]; int segments; _Bool endian_is_big; unsigned long addr_mask; } *

user_defined_types: struct memory_st { struct entry segment[8]; int segments; _Bool endian_is_big; unsigned long addr_mask; }


decompiled_code:
_QWORD *memory_create()
{
_QWORD *result; // rax

result = safe_calloc_constprop_0(0xD0uLL);
result[25] = -1LL;
return result;
}

canonical_decompiled_code:
_QWORD *func5()
{
_QWORD *result; // rax

result = func4(0xD0uLL);
result[25] = -1LL;
return result;
}

original_code:
memory_t *memory_create(void)
{
    memory_t *m = safe_calloc(sizeof (memory_t), 1);
    m->addr_mask = ~0ULL;
    return m;
}

canonical_original_code:
struct memory_st *memory_create()
{
    struct memory_st *m = safe_calloc(sizeof (memory_t), 1);
    m->addr_mask = ~0ULL;
    return m;
}

return_type: struct memory_st { struct entry { void *phys; unsigned long start; } segment[8]; int segments; _Bool endian_is_big; unsigned long addr_mask; } *


decompiled_code:
// attributes: thunk
void memory_destroy(void *ptr)
{
free(ptr);
}

canonical_decompiled_code:
void func6(void *ptr)
{
free(ptr);
}

original_code:
void memory_destroy(memory_t *m)
{
    free(m);
}

canonical_original_code:
void memory_destroy(struct memory_st *m)
{
    free(m);
}

user_defined_types: struct entry { void *phys; unsigned long start; }


decompiled_code:
void __fastcall memory_set_endian(__int64 a1, char a2)
{
*(_BYTE *)(a1 + 196) = a2;
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1, char a2)
{
*(_BYTE *)(a1 + 196) = a2;
}

original_code:
void memory_set_endian(memory_t *m, _Bool bigendian)
{
    m->endian_is_big = bigendian;
}

canonical_original_code:
void memory_set_endian(struct memory_st *m, _Bool bigendian)
{
    m->endian_is_big = bigendian;
}


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

result = 0xFFFFFFFFLL;
*(_QWORD *)(a1 + 200) = 0xFFFFFFFFLL;
return result;
}

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

result = 0xFFFFFFFFLL;
*(_QWORD *)(a1 + 200) = 0xFFFFFFFFLL;
return result;
}

original_code:
void memory_set_32bit_mode(memory_t *m)
{
    m->addr_mask = 0xFFFFFFFF;
}

canonical_original_code:
void memory_set_32bit_mode(struct memory_st *m)
{
    m->addr_mask = 0xFFFFFFFF;
}


decompiled_code:
__int64 __fastcall memory_endian_fix64(__int64 a1, __int64 a2)
{
if ( *(_BYTE *)(a1 + 196) )
_assert_fail("!m->endian_is_big", "memory.c", 0x63u, "memory_endian_fix64");
return a2;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, __int64 a2)
{
if ( *(_BYTE *)(a1 + 196) )
_assert_fail("!m->endian_is_big", "memory.c", 0x63u, "memory_endian_fix64");
return a2;
}

original_code:
uint64_t memory_endian_fix64(memory_t *m, uint64_t v)
{
    ((!m->endian_is_big) ? (void) (0) : __assert_fail ("!m->endian_is_big", "memory.c", 99, __extension__ __PRETTY_FUNCTION__));
    return v;
}

canonical_original_code:
unsigned long memory_endian_fix64(struct memory_st *m, unsigned long v)
{
    ((!m->endian_is_big) ? (void) (0) : __assert_fail ("!m->endian_is_big", "memory.c", 99, __extension__ __PRETTY_FUNCTION__));
    return v;
}

variable_types:
v
unsigned long

return_type: unsigned long


decompiled_code:
__int64 __fastcall memory_endian_fix32(__int64 a1, unsigned int a2)
{
__int64 result; // rax

result = a2;
if ( *(_BYTE *)(a1 + 196) )
result = _bswap_32(a2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, unsigned int a2)
{
__int64 result; // rax

result = a2;
if ( *(_BYTE *)(a1 + 196) )
result = func1(a2);
return result;
}

original_code:
uint32_t memory_endian_fix32(memory_t *m, uint32_t v)
{
    return m->endian_is_big ? htonl(v) : v;
}

canonical_original_code:
unsigned int memory_endian_fix32(struct memory_st *m, unsigned int v)
{
    return m->endian_is_big ? htonl(v) : v;
}

variable_types:
v
unsigned int

return_type: unsigned int


decompiled_code:
__int16 __fastcall memory_endian_fix16(__int64 a1, __int16 a2)
{
__int16 result; // ax

if ( *(_BYTE *)(a1 + 196) )
result = _bswap_16(a2);
else
result = a2;
return result;
}

canonical_decompiled_code:
__int16 __fastcall func11(__int64 a1, __int16 a2)
{
__int16 result; // ax

if ( *(_BYTE *)(a1 + 196) )
result = func2(a2);
else
result = a2;
return result;
}

original_code:
uint16_t memory_endian_fix16(memory_t *m, uint16_t v)
{
    return m->endian_is_big ? htons(v) : v;
}

canonical_original_code:
unsigned short memory_endian_fix16(struct memory_st *m, unsigned short v)
{
    return m->endian_is_big ? htons(v) : v;
}

variable_types:
v
unsigned short

return_type: unsigned short


test

decompiled_code:
void __fastcall __noreturn test(__int64 a1)
{
__int64 v1; // rbp
_QWORD *v2; // rbx

v1 = 4096LL;
v2 = &unk_5C8;
do
{
++v2;
printf("Add segment [%016lx; %016lx)\n", v1, v1 + 4096);
memory_ensure_mapped_range(a1, v1, v1 + 4096);
list_segments(a1);
v1 = *(v2 - 1);
}
while ( v1 );
exit(0);
}

original_code:
static void
test(memory_t *m)
{
    static uint64_t starts[] = {
        0x1000, 0x4000, 0x5000, 0x2000, 0x3000, 0
    };
    for (int i = 0; starts[i]; ++i) {
        printf("Add segment [%016""l" "x""; %016""l" "x"")\n",
               starts[i], starts[i] + 0x1000);
        memory_ensure_mapped_range(m, starts[i], starts[i] + 0x1000);
        list_segments(m);
    }
    exit(0);
}

canonical_original_code:
static void test(struct memory_st *m)
{
    static unsigned long starts[] = {
        0x1000, 0x4000, 0x5000, 0x2000, 0x3000, 0
    };
    for (int i = 0; starts[i]; ++i) {
        printf("Add segment [%016""l" "x""; %016""l" "x"")\n",
               starts[i], starts[i] + 0x1000);
        memory_ensure_mapped_range(m, starts[i], starts[i] + 0x1000);
        list_segments(m);
    }
    exit(0);
}

variable_types:
starts
unsigned long []


usage

decompiled_code:
void __fastcall __noreturn usage(char *s)
{
char *v1; // r12
const char *v2; // rdx
struct option *v3; // rbx

v1 = s;
if ( strchr(s, 47) )
v1 = strrchr(s, 47) + 1;
fprintf(
stderr,
"Multi ISA Simulator\n"
"\n"
"Usage: %s [options] <elf-files ...>\n"
"\n"
" where options can be one or more of\n"
"\n"
" -i<diskimage>\n"
" -d disassemble executed instructions\n"
" -o=$X options\n"
" -c compliance\n"
" --no-cosim disable cosimulation\n",
v1);
v2 = long_options.name;
if ( long_options.name )
{
v3 = &long_options;
do
{
++v3;
fprintf(stderr, " --%s\n", v2);
v2 = v3->name;
}
while ( v3->name );
}
fwrite("\nComments to <tommy-git@thorn.ws>\n", 1uLL, 0x22uLL, stderr);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(char *s)
{
char *v1; // r12
const char *v2; // rdx
struct option *v3; // rbx

v1 = s;
if ( strchr(s, 47) )
v1 = strrchr(s, 47) + 1;
fprintf(
stderr,
"Multi ISA Simulator\n"
"\n"
"Usage: %s [options] <elf-files ...>\n"
"\n"
" where options can be one or more of\n"
"\n"
" -i<diskimage>\n"
" -d disassemble executed instructions\n"
" -o=$X options\n"
" -c compliance\n"
" --no-cosim disable cosimulation\n",
v1);
v2 = long_options.name;
if ( long_options.name )
{
v3 = &long_options;
do
{
++v3;
fprintf(stderr, " --%s\n", v2);
v2 = v3->name;
}
while ( v3->name );
}
fwrite("\nComments to <tommy-git@thorn.ws>\n", 1uLL, 0x22uLL, stderr);
exit(1);
}

original_code:
void usage(char *program)
{
    int i;
    if (strchr(program, '/')) {
        program = strrchr(program, '/') + 1;
    }
    fprintf(stderr,
            "Multi ISA Simulator\n"
            "\n"
            "Usage: %s [options] <elf-files ...>\n"
            "\n"
            "  where options can be one or more of\n"
            "\n"
            "  -i<diskimage>\n"
            "  -d          disassemble executed instructions\n"
            "  -o=$X       options\n"
            "  -c          compliance\n"
            "  --no-cosim  disable cosimulation\n"
            , program);
    for (i = 0; long_options[i].name; ++i) {
        fprintf(stderr, "  --%s\n", long_options[i].name);
    }
    fprintf(stderr,
            "\n"
            "Comments to <tommy-git@thorn.ws>\n");
    exit(1);
}

variable_types:
program
char *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er13
int v4; // eax
unsigned int v5; // ebp
unsigned int v6; // er12
const char **v7; // rbp
int longind[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v3 = 33;
while ( 1 )
{
while ( 1 )
{
LABEL_2:
longind[0] = 0;
v4 = getopt_long(argc, (char *const *)argv, "cdf:i:o:12N", &long_options, longind);
v5 = v4;
if ( v4 == -1 )
{
if ( optind < argc )
{
v6 = argc - optind;
v7 = &argv[optind];
_sysv_signal(2, (__sighandler_t)&exit);
if ( run == 49 )
{
run_simple(v6, v7, v3);
}
else
{
if ( run != 50 )
{
puts("No XX-run option given");
exit(1);
}
run_ooo(v6, v7, v3);
}
exit(0);
}
LABEL_15:
usage((char *)*argv);
}
if ( v4 <= 111 )
break;
LABEL_6:
if ( ((*_ctype_b_loc())[v4] & 0x800) != 0 )
run = v5;
else
printf("?? getopt returned character code 0%o ??\n", v5);
}
if ( v4 > 77 )
{
switch ( v4 )
{
case 'N':
v3 |= 0x40u;
goto LABEL_2;
case 'c':
v3 |= 0x10u;
goto LABEL_2;
case 'd':
v3 |= 2u;
goto LABEL_2;
case 'i':
disk_image = (__int64)optarg;
goto LABEL_2;
case 'o':
CONFIG_EARLY_RELEASE = atoi(optarg) & 1;
goto LABEL_2;
default:
goto LABEL_6;
}
}
if ( v4 )
{
if ( v4 == 63 )
goto LABEL_15;
goto LABEL_6;
}
}
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er13
int v4; // eax
unsigned int v5; // ebp
unsigned int v6; // er12
const char **v7; // rbp
int longind[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v3 = 33;
while ( 1 )
{
while ( 1 )
{
LABEL_2:
longind[0] = 0;
v4 = getopt_long(argc, (char *const *)argv, "cdf:i:o:12N", &long_options, longind);
v5 = v4;
if ( v4 == -1 )
{
if ( optind < argc )
{
v6 = argc - optind;
v7 = &argv[optind];
_sysv_signal(2, (__sighandler_t)&exit);
if ( run == 49 )
{
run_simple(v6, v7, v3);
}
else
{
if ( run != 50 )
{
puts("No XX-run option given");
exit(1);
}
run_ooo(v6, v7, v3);
}
exit(0);
}
LABEL_15:
func0((char *)*argv);
}
if ( v4 <= 111 )
break;
LABEL_6:
if ( ((*_ctype_b_loc())[v4] & 0x800) != 0 )
run = v5;
else
printf("?? getopt returned character code 0%o ??\n", v5);
}
if ( v4 > 77 )
{
switch ( v4 )
{
case 'N':
v3 |= 0x40u;
goto LABEL_2;
case 'c':
v3 |= 0x10u;
goto LABEL_2;
case 'd':
v3 |= 2u;
goto LABEL_2;
case 'i':
disk_image = (__int64)optarg;
goto LABEL_2;
case 'o':
CONFIG_EARLY_RELEASE = atoi(optarg) & 1;
goto LABEL_2;
default:
goto LABEL_6;
}
}
if ( v4 )
{
if ( v4 == 63 )
goto LABEL_15;
goto LABEL_6;
}
}
}

original_code:
int main(int argc, char **argv)
{
    char **images;
    int num_images;
    verbosity_t verbosity = VERBOSE_CONSOLE | VERBOSE_TOHOST;
    for (;;) {
        int c;
        int option_index = 0;
        c = getopt_long(argc, argv, "cdf:i:o:12N",
                        long_options, &option_index);
        if (c == -1)
            break;
        switch (c) {
        case 0:
            break;
        case 'o': {
            int arg = atoi(optarg);
            CONFIG_EARLY_RELEASE = (arg & 1) == 1;
            break;
        }
        case 'i':
            disk_image = optarg;
            break;
        case 'd':
            verbosity |= VERBOSE_DISASS;
            break;
        case 'c':
            verbosity |= VERBOSE_COMPLIANCE;
            break;
        case 'N':
            verbosity |= VERBOSE_NO_COSIM;
            break;
        case '?':
            usage(argv[0]);
            break;
        default:
            if (((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISdigit))
                run = c;
            else
                printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }
    if (optind >= argc) {
        usage(argv[0]);
    }
    images = argv + optind;
    num_images = argc - optind;
    signal(2, exit);
    switch (run) {
    case '1':
        run_simple(num_images, images, verbosity);
        break;
    case '2':
        run_ooo(num_images, images, verbosity);
        break;
    default:
        printf("No XX-run option given\n");
        exit(1);
    }
    exit(0);
}

canonical_original_code:
int main(int argc, char **argv)
{
    char **images;
    int num_images;
    enum verbosity_e verbosity = VERBOSE_CONSOLE | VERBOSE_TOHOST;
    for (;;) {
        int c;
        int option_index = 0;
        c = getopt_long(argc, argv, "cdf:i:o:12N",
                        long_options, &option_index);
        if (c == -1)
            break;
        switch (c) {
        case 0:
            break;
        case 'o': {
            int arg = atoi(optarg);
            CONFIG_EARLY_RELEASE = (arg & 1) == 1;
            break;
        }
        case 'i':
            disk_image = optarg;
            break;
        case 'd':
            verbosity |= VERBOSE_DISASS;
            break;
        case 'c':
            verbosity |= VERBOSE_COMPLIANCE;
            break;
        case 'N':
            verbosity |= VERBOSE_NO_COSIM;
            break;
        case '?':
            usage(argv[0]);
            break;
        default:
            if (((*__ctype_b_loc ())[(int) ((c))] & (unsigned short) _ISdigit))
                run = c;
            else
                printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }
    if (optind >= argc) {
        usage(argv[0]);
    }
    images = argv + optind;
    num_images = argc - optind;
    signal(2, exit);
    switch (run) {
    case '1':
        run_simple(num_images, images, verbosity);
        break;
    case '2':
        run_ooo(num_images, images, verbosity);
        break;
    default:
        printf("No XX-run option given\n");
        exit(1);
    }
    exit(0);
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
images
char **

variable_types: enum verbosity_e { VERBOSE_CONSOLE=expr, VERBOSE_DISASS=expr, VERBOSE_PIPE=expr, VERBOSE_CACHE=expr, VERBOSE_COMPLIANCE=expr, VERBOSE_TOHOST=expr, VERBOSE_NO_COSIM=expr }

variable_types: c int

variable_types: arg int


repo: tomoasleep/nemuish

decompiled_code:
char *__fastcall create_bcmd(__int64 a1, const char *a2, __int64 a3)
{
char *v4; // rax
char *result; // rax

v4 = (char *)malloc(0x28uLL);
result = strcpy(v4, a2);
*((_QWORD *)result + 3) = a1;
*((_QWORD *)result + 4) = a3;
return result;
}

canonical_decompiled_code:
char *__fastcall func0(__int64 a1, const char *a2, __int64 a3)
{
char *v4; // rax
char *result; // rax

v4 = (char *)malloc(0x28uLL);
result = strcpy(v4, a2);
*((_QWORD *)result + 3) = a1;
*((_QWORD *)result + 4) = a3;
return result;
}

original_code:
buildin_cmd *create_bcmd(
        buildin_cmd *bcmds,
        char *name,
        int (*func)(int argc, char *argv[], char *env[])){
    buildin_cmd *bcmd = malloc(sizeof(buildin_cmd));
    strcpy(bcmd->command_name, name);
    bcmd->next = bcmds;
    bcmd->exec = func;
    return bcmd;
}

canonical_original_code:
struct _buildin_cmd *create_bcmd(struct _buildin_cmd *bcmds, char *name, int (*func)(int argc, char *argv[], char *env[])){
    struct _buildin_cmd *bcmd = malloc(sizeof(buildin_cmd));
    strcpy(bcmd->command_name, name);
    bcmd->next = bcmds;
    bcmd->exec = func;
    return bcmd;
}

variable_types:
bcmds
struct _buildin_cmd *

variable_types:
name
char *

variable_types: int (*)(int argc, char *argv[], char *env[])

variable_types: struct _buildin_cmd { char command_name[20]; struct _buildin_cmd *next; int (*exec)(int argc, char *argv[], char *env[]); } *


decompiled_code:
char *__fastcall search_bcmd(char *s2, char *s1)
{
char *v2; // rbx

if ( !s2 )
return 0LL;
v2 = s2;
do
{
if ( !strcmp(s1, v2) )
return v2;
v2 = (char *)*((_QWORD *)v2 + 3);
}
while ( v2 );
return 0LL;
}

canonical_decompiled_code:
char *__fastcall func1(char *s2, char *s1)
{
char *v2; // rbx

if ( !s2 )
return 0LL;
v2 = s2;
do
{
if ( !strcmp(s1, v2) )
return v2;
v2 = (char *)*((_QWORD *)v2 + 3);
}
while ( v2 );
return 0LL;
}

original_code:
buildin_cmd *search_bcmd(buildin_cmd *target, char *name) {
    buildin_cmd *iter = target;
    for (iter = target; iter != ((void *)0); iter = iter->next) {
        if (strcmp(name, iter->command_name) == 0) {
            return iter;
        }
    }
    return ((void *)0);
}

canonical_original_code:
struct _buildin_cmd *search_bcmd(struct _buildin_cmd *target, char *name) {
    struct _buildin_cmd *iter = target;
    for (iter = target; iter != ((void *)0); iter = iter->next) {
        if (strcmp(name, iter->command_name) == 0) {
            return iter;
        }
    }
    return ((void *)0);
}

variable_types:
target
struct _buildin_cmd *

return_type: struct _buildin_cmd { char command_name[20]; struct _buildin_cmd *next; int (*exec)(int argc, char *argv[], char *env[]); } *


decompiled_code:
void __fastcall free_process(void *ptr)
{
void *v2; // rdi
void *v3; // rdi
void *v4; // rdi
void **v5; // r8
void *v6; // rdi
__int64 v7; // rbx

if ( ptr )
{
free_process(*((void **)ptr + 6));
v2 = *(void **)ptr;
if ( v2 )
free(v2);
v3 = (void *)*((_QWORD *)ptr + 3);
if ( v3 )
free(v3);
v4 = (void *)*((_QWORD *)ptr + 5);
if ( v4 )
free(v4);
v5 = (void **)*((_QWORD *)ptr + 1);
if ( v5 )
{
v6 = *v5;
if ( *v5 )
{
v7 = 1LL;
do
{
free(v6);
v5 = (void **)*((_QWORD *)ptr + 1);
v6 = v5[v7++];
}
while ( v6 );
}
free(v5);
}
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func0(void *ptr)
{
void *v2; // rdi
void *v3; // rdi
void *v4; // rdi
void **v5; // r8
void *v6; // rdi
__int64 v7; // rbx

if ( ptr )
{
func0(*((void **)ptr + 6));
v2 = *(void **)ptr;
if ( v2 )
free(v2);
v3 = (void *)*((_QWORD *)ptr + 3);
if ( v3 )
free(v3);
v4 = (void *)*((_QWORD *)ptr + 5);
if ( v4 )
free(v4);
v5 = (void **)*((_QWORD *)ptr + 1);
if ( v5 )
{
v6 = *v5;
if ( *v5 )
{
v7 = 1LL;
do
{
free(v6);
v5 = (void **)*((_QWORD *)ptr + 1);
v6 = v5[v7++];
}
while ( v6 );
}
free(v5);
}
free(ptr);
}
}

original_code:
static void free_process(process *p) {
    if(!p) return;
    free_process(p->next);
    if(p->program_name) free(p->program_name);
    if(p->input_redirection) free(p->input_redirection);
    if(p->output_redirection) free(p->output_redirection);
    if(p->argument_list) {
        int i;
        for(i=0; p->argument_list[i] != ((void *)0); i++)
            free(p->argument_list[i]);
        free(p->argument_list);
    }
    free(p);
}

canonical_original_code:
static void free_process(struct process_ *p) {
    if(!p) return;
    free_process(p->next);
    if(p->program_name) free(p->program_name);
    if(p->input_redirection) free(p->input_redirection);
    if(p->output_redirection) free(p->output_redirection);
    if(p->argument_list) {
        int i;
        for(i=0; p->argument_list[i] != ((void *)0); i++)
            free(p->argument_list[i]);
        free(p->argument_list);
    }
    free(p);
}

variable_types: struct process_ { char *program_name; char **argument_list; int pid; char *input_redirection; enum write_option_ { TRUNC=0, APPEND=1 } output_option; char *output_redirection; struct process_ *next; } *

variable_types: i int

user_defined_types: struct process_ { char *program_name; char **argument_list; int pid; char *input_redirection; enum write_option_ output_option; char *output_redirection; struct process_ *next; }


decompiled_code:
__int64 initialize_process()
{
_QWORD *v0; // rax
__int64 v1; // r12

v0 = malloc(0x38uLL);
v1 = (__int64)v0;
if ( v0 )
{
initialize_program_name_isra_0(v0);
initialize_argument_list_isra_0(v1);
initialize_argument_list_element_isra_0(*(_QWORD *)(v1 + 8), 0);
*(_DWORD *)(v1 + 16) = -1;
*(_QWORD *)(v1 + 24) = 0LL;
*(_DWORD *)(v1 + 32) = 0;
*(_QWORD *)(v1 + 40) = 0LL;
*(_QWORD *)(v1 + 48) = 0LL;
}
return v1;
}

original_code:
static process* initialize_process() {
    process *p;
    if((p = (process*)malloc(sizeof(process))) == ((void *)0))
        return ((void *)0);
    initialize_program_name(p);
    initialize_argument_list(p);
    initialize_argument_list_element(p, 0);
    p->pid = -1;
    p->input_redirection = ((void *)0);
    p->output_option = TRUNC;
    p->output_redirection = ((void *)0);
    p->next = ((void *)0);
    return p;
}

canonical_original_code:
static struct process_ *initialize_process() {
    struct process_ *p;
    if((p = (struct process_ *)malloc(sizeof(process))) == ((void *)0))
        return ((void *)0);
    initialize_program_name(p);
    initialize_argument_list(p);
    initialize_argument_list_element(p, 0);
    p->pid = -1;
    p->input_redirection = ((void *)0);
    p->output_option = TRUNC;
    p->output_redirection = ((void *)0);
    p->next = ((void *)0);
    return p;
}

return_type: struct process_ { char *program_name; char **argument_list; int pid; char *input_redirection; enum write_option_ { TRUNC=0, APPEND=1 } output_option; char *output_redirection; struct process_ *next; } *


decompiled_code:
_DWORD *initialize_job()
{
_DWORD *v0; // rax
_DWORD *v1; // r12
__int64 v2; // rax

v0 = malloc(0x18uLL);
v1 = v0;
if ( v0 )
{
*v0 = 0;
v2 = initialize_process();
*((_QWORD *)v1 + 2) = 0LL;
*((_QWORD *)v1 + 1) = v2;
}
return v1;
}

original_code:
static job* initialize_job() {
    job *j;
    if((j = (job*)malloc(sizeof(job))) == ((void *)0))
        return ((void *)0);
    j->mode = FOREGROUND;
    j->process_list = initialize_process();
    j->next = ((void *)0);
    return j;
}

canonical_original_code:
static struct job_ *initialize_job() {
    struct job_ *j;
    if((j = (struct job_ *)malloc(sizeof(job))) == ((void *)0))
        return ((void *)0);
    j->mode = FOREGROUND;
    j->process_list = initialize_process();
    j->next = ((void *)0);
    return j;
}

variable_types: struct job_ { enum job_mode_ { FOREGROUND=0, BACKGROUND=1 } mode; struct process_ { char *program_name; char **argument_list; int pid; char *input_redirection; enum write_option_ { TRUNC=0, APPEND=1 } output_option; char *output_redirection; struct process_ *next; } *process_list; struct job_ *next; } *

user_defined_types: struct job_ { enum job_mode_ mode; struct process_ *process_list; struct job_ *next; }


decompiled_code:
char *__fastcall get_line(char *s, int n)
{
char *v2; // r12

printf("nemuish$ ");
while ( 1 )
{
v2 = fgets(s, n, stdin);
if ( v2 )
break;
if ( *_errno_location() != 4 )
return v2;
}
return s;
}

canonical_decompiled_code:
char *__fastcall func8(char *s, int n)
{
char *v2; // r12

printf("nemuish$ ");
while ( 1 )
{
v2 = fgets(s, n, stdin);
if ( v2 )
break;
if ( *_errno_location() != 4 )
return v2;
}
return s;
}

original_code:
char* get_line(char *s, int size) {
    printf("nemuish$ ");
    while(fgets(s, size, stdin) == ((void *)0)) {
        if((*__errno_location ()) == 4)
            continue;
        return ((void *)0);
    }
    return s;
}

canonical_original_code:
char *get_line(char *s, int size) {
    printf("nemuish$ ");
    while(fgets(s, size, stdin) == ((void *)0)) {
        if((*__errno_location ()) == 4)
            continue;
        return ((void *)0);
    }
    return s;
}

variable_types:
s
char *

variable_types: size int


decompiled_code:
void __fastcall free_job(void *ptr)
{
if ( ptr )
{
free_job(*((void **)ptr + 2));
free_process(*((void **)ptr + 1));
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func9(void *ptr)
{
if ( ptr )
{
func9(*((void **)ptr + 2));
func0(*((void **)ptr + 1));
free(ptr);
}
}

original_code:
void free_job(job *j) {
    if(!j) return;
    free_job(j->next);
    free_process(j->process_list);
    free(j);
}

canonical_original_code:
void free_job(struct job_ *j) {
    if(!j) return;
    free_job(j->next);
    free_process(j->process_list);
    free(j);
}

user_defined_types: enum job_mode_ { FOREGROUND=0, BACKGROUND=1 }

user_defined_types: enum write_option_ { TRUNC=0, APPEND=1 }