decompiled_code:
char *__fastcall parse_src(__int64 a1, char *a2)
{
char *v2; // rax
char **v3; // r12
char *v4; // r12
char *result; // rax
char v6; // al
__int64 v7; // r12
char *v8; // rax
__int64 v9; // rbx
char *v10; // rax
char *v11; // r12
__int64 v12; // rbx
char *v13; // rax
char *v14; // r12
char *stringp[4]; // [rsp+8h] [rbp-20h] BYREF

stringp[0] = a2;
v2 = strpbrk(a2, "! ");
v3 = *(char ***)(a1 + 16);
if ( *v2 != 33 )
{
*v3 = strsep(stringp, " ");
return stringp[0];
}
v3[1] = strsep(stringp, "!");
v4 = stringp[0];
v6 = *strpbrk(stringp[0], "@ ");
if ( v6 == 32 )
{
v12 = *(_QWORD *)(a1 + 16);
v13 = strsep(stringp, " ");
v14 = stringp[0];
*(_QWORD *)(v12 + 16) = v13;
result = v14;
}
else
{
if ( v6 != 64 )
return v4;
v7 = *(_QWORD *)(a1 + 16);
v8 = strsep(stringp, "@");
v9 = *(_QWORD *)(a1 + 16);
*(_QWORD *)(v7 + 16) = v8;
v10 = strsep(stringp, " ");
v11 = stringp[0];
*(_QWORD *)(v9 + 24) = v10;
result = v11;
}
return result;
}

canonical_decompiled_code:
char *__fastcall func4(__int64 a1, char *a2)
{
char *v2; // rax
char **v3; // r12
char *v4; // r12
char *result; // rax
char v6; // al
__int64 v7; // r12
char *v8; // rax
__int64 v9; // rbx
char *v10; // rax
char *v11; // r12
__int64 v12; // rbx
char *v13; // rax
char *v14; // r12
char *stringp[4]; // [rsp+8h] [rbp-20h] BYREF

stringp[0] = a2;
v2 = strpbrk(a2, "! ");
v3 = *(char ***)(a1 + 16);
if ( *v2 != 33 )
{
*v3 = strsep(stringp, " ");
return stringp[0];
}
v3[1] = strsep(stringp, "!");
v4 = stringp[0];
v6 = *strpbrk(stringp[0], "@ ");
if ( v6 == 32 )
{
v12 = *(_QWORD *)(a1 + 16);
v13 = strsep(stringp, " ");
v14 = stringp[0];
*(_QWORD *)(v12 + 16) = v13;
result = v14;
}
else
{
if ( v6 != 64 )
return v4;
v7 = *(_QWORD *)(a1 + 16);
v8 = strsep(stringp, "@");
v9 = *(_QWORD *)(a1 + 16);
*(_QWORD *)(v7 + 16) = v8;
v10 = strsep(stringp, " ");
v11 = stringp[0];
*(_QWORD *)(v9 + 24) = v10;
result = v11;
}
return result;
}

original_code:
char *parse_src(struct IRC_MSG *msg, char *raw_msg_ptr) {
    if (*strpbrk(raw_msg_ptr, "! ") != '!') {
 msg->src->server_name = strsep(&raw_msg_ptr, " ");
 return raw_msg_ptr;
    } else {
 msg->src->nick = strsep(&raw_msg_ptr, "!");
    }
    switch (*strpbrk(raw_msg_ptr, "@ ")) {
 case '@':
     msg->src->user = strsep(&raw_msg_ptr, "@");
     msg->src->host = strsep(&raw_msg_ptr, " ");
     break;
 case ' ':
     msg->src->user = strsep(&raw_msg_ptr, " ");
     break;
    }
    return raw_msg_ptr;
}

return_type: char *


repo: codyharrington/ircbot

decompiled_code:
char *__fastcall parse_command(__int64 a1, char *a2)
{
char *stringp; // [rsp+8h] [rbp-10h] BYREF

stringp = a2;
*(_QWORD *)(a1 + 24) = strsep(&stringp, " ");
return stringp;
}

canonical_decompiled_code:
char *__fastcall func5(__int64 a1, char *a2)
{
char *stringp; // [rsp+8h] [rbp-10h] BYREF

stringp = a2;
*(_QWORD *)(a1 + 24) = strsep(&stringp, " ");
return stringp;
}

original_code:
char *parse_command(struct IRC_MSG *msg, char *raw_msg_ptr) {
    msg->command = strsep(&raw_msg_ptr, " ");
    return raw_msg_ptr;
}

variable_types: struct IRC_MSG { char *_raw; unsigned long _raw_len; struct IRC_SRC { char *server_name; char *nick; char *user; char *host; } *src; char *command; int argc; char **argv; char *text; int valid; } *

user_defined_types: struct IRC_MSG { char *_raw; unsigned long _raw_len; struct IRC_SRC *src; char *command; int argc; char **argv; char *text; int valid; }


decompiled_code:
char *__fastcall parse_params(__int64 a1, char *a2)
{
char *v2; // rax
char *v3; // r8
char *v4; // r12
int v5; // eax
char **v6; // rbp
char *v7; // rax
char *stringp; // [rsp+8h] [rbp-20h] BYREF

stringp = a2;
v2 = (char *)calloc(8uLL, 8uLL);
v3 = a2;
v4 = v2;
if ( *a2 != 58 )
{
v5 = *(_DWORD *)(a1 + 32);
do
{
if ( v5 > 7 )
break;
v6 = (char **)&v4[8 * v5];
v7 = strsep(&stringp, " ");
v3 = stringp;
*v6 = v7;
v5 = *(_DWORD *)(a1 + 32) + 1;
*(_DWORD *)(a1 + 32) = v5;
}
while ( *v3 != 58 );
}
*(_QWORD *)(a1 + 40) = v4;
return v3;
}

canonical_decompiled_code:
char *__fastcall func6(__int64 a1, char *a2)
{
char *v2; // rax
char *v3; // r8
char *v4; // r12
int v5; // eax
char **v6; // rbp
char *v7; // rax
char *stringp; // [rsp+8h] [rbp-20h] BYREF

stringp = a2;
v2 = (char *)calloc(8uLL, 8uLL);
v3 = a2;
v4 = v2;
if ( *a2 != 58 )
{
v5 = *(_DWORD *)(a1 + 32);
do
{
if ( v5 > 7 )
break;
v6 = (char **)&v4[8 * v5];
v7 = strsep(&stringp, " ");
v3 = stringp;
*v6 = v7;
v5 = *(_DWORD *)(a1 + 32) + 1;
*(_DWORD *)(a1 + 32) = v5;
}
while ( *v3 != 58 );
}
*(_QWORD *)(a1 + 40) = v4;
return v3;
}

original_code:
char *parse_params(struct IRC_MSG *msg, char *raw_msg_ptr) {
    char **argv = (char **) calloc (8, sizeof(char *));
    while (*raw_msg_ptr != ':' && msg->argc < 8) {
 argv[msg->argc] = strsep(&raw_msg_ptr, " ");
 msg->argc += 1;
    }
    msg->argv = argv;
    return raw_msg_ptr;
}

variable_types:
argv
char **

user_defined_types: struct IRC_SRC { char *server_name; char *nick; char *user; char *host; }


decompiled_code:
char *__fastcall parse_text(__int64 a1, char *a2)
{
char *stringp; // [rsp+8h] [rbp-10h] BYREF

stringp = a2;
*(_QWORD *)(a1 + 48) = strsep(&stringp, "\r\n");
return stringp;
}

canonical_decompiled_code:
char *__fastcall func7(__int64 a1, char *a2)
{
char *stringp; // [rsp+8h] [rbp-10h] BYREF

stringp = a2;
*(_QWORD *)(a1 + 48) = strsep(&stringp, "\r\n");
return stringp;
}

original_code:
char *parse_text(struct IRC_MSG *msg, char *raw_msg_ptr) {
    msg->text = strsep(&raw_msg_ptr, "\r\n");
    return raw_msg_ptr;
}


decompiled_code:
char **__fastcall create_message(void *src, size_t n)
{
char **v2; // r12
char *v3; // rax
char *v4; // rbp
char *v5; // rax
char *v6; // rax
char *v7; // r13
char *v8; // rax
char *v10; // rax
char *v11; // rax
char *stringp; // [rsp+8h] [rbp-20h] BYREF

v2 = (char **)init_msg();
v3 = (char *)calloc(n + 1, 1uLL);
*v2 = v3;
memcpy(v3, src, n);
v2[1] = (char *)n;
v4 = *v2;
stringp = *v2;
v5 = strpbrk(stringp, ": ");
if ( v5 && *v5 == 58 )
{
stringp = parse_src((__int64)v2, v4 + 1);
v4 = stringp;
}
v6 = strpbrk(v4, " :");
if ( v6 )
{
v7 = stringp;
if ( *v6 == 32 )
{
v10 = strsep(&stringp, " ");
v4 = stringp;
v2[3] = v10;
v7 = v4;
v11 = strpbrk(v4, " :");
if ( !v11 )
goto LABEL_7;
if ( *v11 == 32 )
{
stringp = parse_params((__int64)v2, v4);
v4 = stringp;
goto LABEL_7;
}
}
v4 = v7;
}
LABEL_7:
v8 = strpbrk(v4, ":\r\n");
if ( v8 && *v8 == 58 )
{
stringp = v4 + 1;
stringp = parse_text((__int64)v2, v4 + 1);
}
*((_DWORD *)v2 + 14) = msg_is_valid((__int64)v2);
return v2;
}

canonical_decompiled_code:
char **__fastcall func8(void *src, size_t n)
{
char **v2; // r12
char *v3; // rax
char *v4; // rbp
char *v5; // rax
char *v6; // rax
char *v7; // r13
char *v8; // rax
char *v10; // rax
char *v11; // rax
char *stringp; // [rsp+8h] [rbp-20h] BYREF

v2 = (char **)func0();
v3 = (char *)calloc(n + 1, 1uLL);
*v2 = v3;
memcpy(v3, src, n);
v2[1] = (char *)n;
v4 = *v2;
stringp = *v2;
v5 = strpbrk(stringp, ": ");
if ( v5 && *v5 == 58 )
{
stringp = func4((__int64)v2, v4 + 1);
v4 = stringp;
}
v6 = strpbrk(v4, " :");
if ( v6 )
{
v7 = stringp;
if ( *v6 == 32 )
{
v10 = strsep(&stringp, " ");
v4 = stringp;
v2[3] = v10;
v7 = v4;
v11 = strpbrk(v4, " :");
if ( !v11 )
goto LABEL_7;
if ( *v11 == 32 )
{
stringp = func6((__int64)v2, v4);
v4 = stringp;
goto LABEL_7;
}
}
v4 = v7;
}
LABEL_7:
v8 = strpbrk(v4, ":\r\n");
if ( v8 && *v8 == 58 )
{
stringp = v4 + 1;
stringp = func7((__int64)v2, v4 + 1);
}
*((_DWORD *)v2 + 14) = func2((__int64)v2);
return v2;
}

original_code:
struct IRC_MSG *create_message(char *raw, size_t raw_len) {
    struct IRC_MSG *msg = init_msg();
    msg->_raw = calloc(raw_len + 1, sizeof(char));
    char *raw_msg_ptr = ((void *)0);
    char *delim_match = ((void *)0);
    memcpy(msg->_raw, raw, raw_len);
    msg->_raw_len = raw_len;
    raw_msg_ptr = msg->_raw;
    delim_match = strpbrk(raw_msg_ptr, ": ");
    if (delim_match != ((void *)0) && *delim_match == ':') {
 raw_msg_ptr = parse_src(msg, ++raw_msg_ptr);
    }
    delim_match = strpbrk(raw_msg_ptr, " :");
    if (delim_match != ((void *)0) && *delim_match == ' ') {
        msg->command = strsep(&raw_msg_ptr, " ");
    }
    delim_match = strpbrk(raw_msg_ptr, " :");
    if (delim_match != ((void *)0) && *delim_match == ' ') {
 raw_msg_ptr = parse_params(msg, raw_msg_ptr);
    }
    delim_match = strpbrk(raw_msg_ptr, ":\r\n");
    if (delim_match != ((void *)0) && *delim_match == ':') {
       raw_msg_ptr = parse_text(msg, ++raw_msg_ptr);
    }
    msg->valid = msg_is_valid(msg);
    return msg;
}

canonical_original_code:
struct IRC_MSG *create_message(char *raw, unsigned long raw_len) {
    struct IRC_MSG *msg = init_msg();
    msg->_raw = calloc(raw_len + 1, sizeof(char));
    char *raw_msg_ptr = ((void *)0);
    char *delim_match = ((void *)0);
    memcpy(msg->_raw, raw, raw_len);
    msg->_raw_len = raw_len;
    raw_msg_ptr = msg->_raw;
    delim_match = strpbrk(raw_msg_ptr, ": ");
    if (delim_match != ((void *)0) && *delim_match == ':') {
 raw_msg_ptr = parse_src(msg, ++raw_msg_ptr);
    }
    delim_match = strpbrk(raw_msg_ptr, " :");
    if (delim_match != ((void *)0) && *delim_match == ' ') {
        msg->command = strsep(&raw_msg_ptr, " ");
    }
    delim_match = strpbrk(raw_msg_ptr, " :");
    if (delim_match != ((void *)0) && *delim_match == ' ') {
 raw_msg_ptr = parse_params(msg, raw_msg_ptr);
    }
    delim_match = strpbrk(raw_msg_ptr, ":\r\n");
    if (delim_match != ((void *)0) && *delim_match == ':') {
       raw_msg_ptr = parse_text(msg, ++raw_msg_ptr);
    }
    msg->valid = msg_is_valid(msg);
    return msg;
}

variable_types:
raw
char *

return_type: struct IRC_MSG { char *_raw; unsigned long _raw_len; struct IRC_SRC { char *server_name; char *nick; char *user; char *host; } *src; char *command; int argc; char **argv; char *text; int valid; } *


decompiled_code:
void *__fastcall parse_read_buffer(__int64 a1, char *a2, size_t *a3)
{
const char *v3; // r14
char *v7; // rdi
size_t v8; // rsi
char *v9; // rax
size_t v10; // rax

v3 = a2;
while ( 1 )
{
v9 = strstr(v3, "\r\n");
if ( !v9 )
break;
v7 = (char *)v3;
v8 = v9 + 3 - v3;
v3 = v9 + 2;
*(_QWORD *)(a1 + 56) = create_message(v7, v8);
}
v10 = strlen(v3);
*a3 = v10;
return memmove(a2, v3, v10);
}

canonical_decompiled_code:
void *__fastcall func9(__int64 a1, char *a2, size_t *a3)
{
const char *v3; // r14
char *v7; // rdi
size_t v8; // rsi
char *v9; // rax
size_t v10; // rax

v3 = a2;
while ( 1 )
{
v9 = strstr(v3, "\r\n");
if ( !v9 )
break;
v7 = (char *)v3;
v8 = v9 + 3 - v3;
v3 = v9 + 2;
*(_QWORD *)(a1 + 56) = func8(v7, v8);
}
v10 = strlen(v3);
*a3 = v10;
return memmove(a2, v3, v10);
}

original_code:
void parse_read_buffer(struct IRC_CTX *ctx, char *read_buf, size_t *remainder_size) {
 char *msg_end_ptr = ((void *)0);
 char *read_buf_ptr = read_buf;
 size_t msg_len = 0;
 while ((msg_end_ptr = strstr(read_buf, "\r\n")) != ((void *)0)) {
  msg_len = (msg_end_ptr + sizeof("\r\n")) - read_buf;
  ctx->msg = create_message(read_buf, msg_len);
  read_buf += (msg_len - 1);
 }
 *remainder_size = strlen(read_buf);
 memmove(read_buf_ptr, read_buf, *remainder_size);
}

canonical_original_code:
void parse_read_buffer(struct IRC_CTX *ctx, char *read_buf, unsigned long *remainder_size) {
 char *msg_end_ptr = ((void *)0);
 char *read_buf_ptr = read_buf;
 unsigned long msg_len = 0;
 while ((msg_end_ptr = strstr(read_buf, "\r\n")) != ((void *)0)) {
  msg_len = (msg_end_ptr + sizeof("\r\n")) - read_buf;
  ctx->msg = create_message(read_buf, msg_len);
  read_buf += (msg_len - 1);
 }
 *remainder_size = strlen(read_buf);
 memmove(read_buf_ptr, read_buf, *remainder_size);
}

variable_types: struct IRC_CTX { struct sockaddr { unsigned short sa_family; char sa_data[14]; } servaddr; unsigned int servaddr_len; char *servaddr_str; char *channel; char *nick; int sockfd; int port; struct IRC_MSG { char *_raw; unsigned long _raw_len; struct IRC_SRC { char *server_name; char *nick; char *user; char *host; } *src; char *command; int argc; char **argv; char *text; int valid; } *msg; union sem_t { char __size[32]; long __align; } msg_mutex; } *

return_type: void

user_defined_types: struct IRC_CTX { struct sockaddr servaddr; unsigned int servaddr_len; char *servaddr_str; char *channel; char *nick; int sockfd; int port; struct IRC_MSG *msg; union sem_t msg_mutex; }


decompiled_code:
__int64 __fastcall display_message(__int64 a1)
{
return debug_print_msg(*(_QWORD *)(a1 + 56));
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return debug_print_msg(*(_QWORD *)(a1 + 56));
}

original_code:
void display_message(struct IRC_CTX *ctx) {
    debug_print_msg(ctx->msg);
}

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

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


decompiled_code:
int write_to_socket(__int64 a1, const char *a2, ...)
{
size_t v2; // rax
ssize_t v3; // rax
const char *v4; // rdx
gcc_va_list arg; // [rsp+8h] [rbp-4D0h] BYREF
char s[16]; // [rsp+20h] [rbp-4B8h] BYREF
char v8[1008]; // [rsp+30h] [rbp-4A8h] BYREF
__int64 v9; // [rsp+430h] [rbp-A8h]

va_start(arg, a2);
v9 = va_arg(arg, _QWORD);
va_end(arg);
va_start(arg, a2);
memset(v8, 0, sizeof(v8));
*(_OWORD *)s = 0LL;
vsnprintf(s, 0x400uLL, a2, arg);
printf("<< %s", s);
v2 = strlen(s);
v3 = write(*(_DWORD *)(a1 + 48), s, v2);
if ( v3 == -1 )
{
error((int)"write", (int)s, v4);
goto LABEL_3;
}
if ( !v3 )
LABEL_3:
LODWORD(v3) = printf("wrote nothing");
return v3;
}

canonical_decompiled_code:
int func1(__int64 a1, const char *a2, ...)
{
size_t v2; // rax
ssize_t v3; // rax
const char *v4; // rdx
gcc_va_list arg; // [rsp+8h] [rbp-4D0h] BYREF
char s[16]; // [rsp+20h] [rbp-4B8h] BYREF
char v8[1008]; // [rsp+30h] [rbp-4A8h] BYREF
__int64 v9; // [rsp+430h] [rbp-A8h]

va_start(arg, a2);
v9 = va_arg(arg, _QWORD);
va_end(arg);
va_start(arg, a2);
memset(v8, 0, sizeof(v8));
*(_OWORD *)s = 0LL;
vsnprintf(s, 0x400uLL, a2, arg);
printf("<< %s", s);
v2 = strlen(s);
v3 = write(*(_DWORD *)(a1 + 48), s, v2);
if ( v3 == -1 )
{
error((int)"write", (int)s, v4);
goto LABEL_3;
}
if ( !v3 )
LABEL_3:
LODWORD(v3) = printf("wrote nothing");
return v3;
}

original_code:
void write_to_socket(struct IRC_CTX *ctx, char *fmt, ...) {
 ssize_t ret = 0;
 char sbuf[1024] = {'\0'};
 va_list ap;
 __builtin_va_start(ap,fmt);
 vsnprintf(sbuf, 1024, fmt, ap);
 __builtin_va_end(ap);
 printf("<< %s", sbuf);
 ret = write(ctx->sockfd, sbuf, strlen(sbuf));
 switch (ret) {
  case -1:
   error("write");
  case 0:
   printf("wrote nothing");
  default: ;
 }
}

canonical_original_code:
void write_to_socket(struct IRC_CTX *ctx, char *fmt, ...) {
 long ret = 0;
 char sbuf[1024] = {'\0'};
 __builtin_va_list ap;
 __builtin_va_start(ap,fmt);
 vsnprintf(sbuf, 1024, fmt, ap);
 __builtin_va_end(ap);
 printf("<< %s", sbuf);
 ret = write(ctx->sockfd, sbuf, strlen(sbuf));
 switch (ret) {
  case -1:
   error("write");
  case 0:
   printf("wrote nothing");
  default: ;
 }
}

variable_types:
fmt
char *

variable_types: ret long

variable_types:
sbuf
char [1024]


decompiled_code:
__int64 __fastcall listen_server(__int64 a1)
{
__int64 v1; // rbx
void *v2; // rsi
ssize_t v3; // rax
__int64 i; // [rsp+8h] [rbp-420h] BYREF
char v6[1048]; // [rsp+10h] [rbp-418h] BYREF

v1 = 0LL;
for ( i = 0LL; ; v1 = i )
{
v2 = memset(&v6[v1], 0, 1024 - v1);
v3 = read(*(_DWORD *)(a1 + 48), v2, 1023 - v1);
if ( v3 == -1 )
break;
if ( !v3 )
{
printf("Finished reading.");
free_context(a1);
return 0LL;
}
while ( 1 )
{
parse_read_buffer(a1, v6, &i);
if ( *(_DWORD *)(*(_QWORD *)(a1 + 56) + 56LL) )
break;
free_msg();
}
handle_irc_command(a1);
display_message(a1);
}
close(*(_DWORD *)(a1 + 48));
perror("Read error");
free_context(a1);
return (unsigned int)*_errno_location();
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
__int64 v1; // rbx
void *v2; // rsi
ssize_t v3; // rax
__int64 i; // [rsp+8h] [rbp-420h] BYREF
char v6[1048]; // [rsp+10h] [rbp-418h] BYREF

v1 = 0LL;
for ( i = 0LL; ; v1 = i )
{
v2 = memset(&v6[v1], 0, 1024 - v1);
v3 = read(*(_DWORD *)(a1 + 48), v2, 1023 - v1);
if ( v3 == -1 )
break;
if ( !v3 )
{
printf("Finished reading.");
free_context(a1);
return 0LL;
}
while ( 1 )
{
parse_read_buffer(a1, v6, &i);
if ( *(_DWORD *)(*(_QWORD *)(a1 + 56) + 56LL) )
break;
free_msg();
}
handle_irc_command(a1);
func0(a1);
}
close(*(_DWORD *)(a1 + 48));
perror("Read error");
free_context(a1);
return (unsigned int)*_errno_location();
}

original_code:
int listen_server(struct IRC_CTX *ctx) {
 ssize_t ret = 0;
 size_t offset = 0;
 char read_buf[1024];
 int return_value = 0;
 int checked_valid = 0;
 for (;;) {
  memset(read_buf + offset, 0, 1024 - offset);
  ret = read(ctx->sockfd, read_buf + offset,
    (1024 - 1) - offset);
  checked_valid = 0;
  switch (ret) {
   case -1:
    close(ctx->sockfd);
    perror("Read error");
    goto cleanup;
    break;
   case 0:
    printf("Finished reading.");
    goto cleanup;
    break;
   default:
    while (!checked_valid) {
        parse_read_buffer(ctx, read_buf, &offset);
        if (!ctx->msg->valid)
     free_msg(ctx->msg);
        else
     checked_valid = 1;
    }
    handle_irc_command(ctx);
    display_message(ctx);
    break;
  }
 }
cleanup:
 free_context(ctx);
 return_value = ret ? (*__errno_location ()) : ret;
 return return_value;
}

canonical_original_code:
int listen_server(struct IRC_CTX *ctx) {
 long ret = 0;
 unsigned long offset = 0;
 char read_buf[1024];
 int return_value = 0;
 int checked_valid = 0;
 for (;;) {
  memset(read_buf + offset, 0, 1024 - offset);
  ret = read(ctx->sockfd, read_buf + offset,
    (1024 - 1) - offset);
  checked_valid = 0;
  switch (ret) {
   case -1:
    close(ctx->sockfd);
    perror("Read error");
    goto cleanup;
    break;
   case 0:
    printf("Finished reading.");
    goto cleanup;
    break;
   default:
    while (!checked_valid) {
        parse_read_buffer(ctx, read_buf, &offset);
        if (!ctx->msg->valid)
     free_msg(ctx->msg);
        else
     checked_valid = 1;
    }
    handle_irc_command(ctx);
    display_message(ctx);
    break;
  }
 }
cleanup:
 free_context(ctx);
 return_value = ret ? (*__errno_location ()) : ret;
 return return_value;
}

variable_types:
offset
unsigned long

return_type: int


repo: cohenadair/assignments

decompiled_code:
__pid_t sigchld_handler()
{
__pid_t result; // eax

do
result = waitpid(-1, 0LL, 1);
while ( result > 0 );
return result;
}

canonical_decompiled_code:
__pid_t func0()
{
__pid_t result; // eax

do
result = waitpid(-1, 0LL, 1);
while ( result > 0 );
return result;
}

original_code:
void sigchld_handler(int s)
{
 while(waitpid(-1, ((void *)0), 1) > 0);
}

variable_types: s int


handleOptions

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

if ( a1 != 2 )
{
fprintf(stderr, "usage: %s <port number>\n", *a2);
exit(-1);
}
result = atoi(a2[1]);
*a3 = result;
return result;
}

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

if ( a1 != 2 )
{
fprintf(stderr, "usage: %s <port number>\n", *a2);
exit(-1);
}
result = atoi(a2[1]);
*a3 = result;
return result;
}

original_code:
void handleOptions( int argc, char *argv[], int *portnoPtr )
{
     if (argc != 2){
     fprintf(stderr, "usage: %s <port number>\n", argv[0]);
     exit(-1);
 }
 *portnoPtr = atoi(argv[1]);
}

canonical_original_code:
void handleOptions(int argc, char *argv[], int *portnoPtr)
{
     if (argc != 2){
     fprintf(stderr, "usage: %s <port number>\n", argv[0]);
     exit(-1);
 }
 *portnoPtr = atoi(argv[1]);
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
portnoPtr
int *


handleFortuneRequest

decompiled_code:
__int64 __fastcall handleFortuneRequest(__int64 a1)
{
int v2; // eax
char v4; // [rsp+Eh] [rbp-Ah] BYREF
char v5[9]; // [rsp+Fh] [rbp-9h] BYREF

v4 = 2;
v5[0] = strlen(fortunes[fortuneIndex % 3]);
(*(void (__fastcall **)(__int64, char *, __int64))(a1 + 16))(a1, &v4, 1LL);
v5[0] = strlen(fortunes[fortuneIndex % 3]);
(*(void (__fastcall **)(__int64, char *, __int64))(a1 + 16))(a1, v5, 1LL);
v2 = fortuneIndex++;
(*(void (__fastcall **)(__int64, char *, _QWORD))(a1 + 16))(a1, fortunes[v2 % 3], (unsigned __int8)v5[0]);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
int v2; // eax
char v4; // [rsp+Eh] [rbp-Ah] BYREF
char v5[9]; // [rsp+Fh] [rbp-9h] BYREF

v4 = 2;
v5[0] = strlen(fortunes[fortuneIndex % 3]);
(*(void (__fastcall **)(__int64, char *, __int64))(a1 + 16))(a1, &v4, 1LL);
v5[0] = strlen(fortunes[fortuneIndex % 3]);
(*(void (__fastcall **)(__int64, char *, __int64))(a1 + 16))(a1, v5, 1LL);
v2 = fortuneIndex++;
(*(void (__fastcall **)(__int64, char *, _QWORD))(a1 + 16))(a1, fortunes[v2 % 3], (unsigned __int8)v5[0]);
return 1LL;
}

original_code:
int handleFortuneRequest(nmu_socket_t serviceSocket)
{
 uint8_t fortuneReply = 2;
 uint8_t count = (uint8_t)strlen(fortunes[fortuneIndex % 3]);
 serviceSocket->write(serviceSocket, &fortuneReply, sizeof(uint8_t));
 count = strlen(fortunes[fortuneIndex % 3]);
 serviceSocket->write(serviceSocket, &count, sizeof(uint8_t));
 serviceSocket->write(serviceSocket, fortunes[fortuneIndex++ % 3], count);
 return 1;
}

canonical_original_code:
int handleFortuneRequest(struct NMUSocket *serviceSocket)
{
 unsigned char fortuneReply = 2;
 unsigned char count = (uint8_t)strlen(fortunes[fortuneIndex % 3]);
 serviceSocket->write(serviceSocket, &fortuneReply, sizeof(unsigned char));
 count = strlen(fortunes[fortuneIndex % 3]);
 serviceSocket->write(serviceSocket, &count, sizeof(unsigned char));
 serviceSocket->write(serviceSocket, fortunes[fortuneIndex++ % 3], count);
 return 1;
}

variable_types: struct NMUSocket { struct NMUSocket *(*accept)(struct NMUSocket *); int (*read)(struct NMUSocket *, void *, int); int (*write)(struct NMUSocket *, void *, int); void (*close)(struct NMUSocket *); void (*error)(struct NMUSocket *, char *); struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; } sockAddr; int sockfd; } *

variable_types:
fortuneReply
unsigned char

variable_types:
count
unsigned char

user_defined_types: struct NMUSocket { struct NMUSocket *(*accept)(struct NMUSocket *); int (*read)(struct NMUSocket *, void *, int); int (*write)(struct NMUSocket *, void *, int); void (*close)(struct NMUSocket *); void (*error)(struct NMUSocket *, char *); struct sockaddr_in sockAddr; int sockfd; }

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


handleFortuneQuit

decompiled_code:
__int64 __fastcall handleFortuneQuit(__int64 a1)
{
(*(void (**)(void))(a1 + 24))();
return 2LL;
}

original_code:
int handleFortuneQuit(nmu_socket_t serviceSocket)
{
 serviceSocket->close(serviceSocket);
 return 2;
}

canonical_original_code:
int handleFortuneQuit(struct NMUSocket *serviceSocket)
{
 serviceSocket->close(serviceSocket);
 return 2;
}


handleFortuneServerProtocol

decompiled_code:
__int64 __fastcall handleFortuneServerProtocol(__int64 a1)
{
__int64 result; // rax
char v2[9]; // [rsp+Fh] [rbp-9h] BYREF

result = 1LL;
state = 1;
LABEL_2:
while ( (_DWORD)result != 2 )
{
while ( 1 )
{
(*(void (__fastcall **)(__int64, char *, __int64))(a1 + 8))(a1, v2, 1LL);
if ( v2[0] == 1 )
{
result = handleFortuneRequest(a1);
state = result;
goto LABEL_2;
}
if ( v2[0] == 3 )
break;
if ( v2[0] )
(*(void (__fastcall **)(__int64, const char *))(a1 + 32))(a1, "ERROR, protocol error");
result = (unsigned int)state;
if ( state == 2 )
return result;
}
result = handleFortuneQuit(a1);
state = result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
__int64 result; // rax
char v2[9]; // [rsp+Fh] [rbp-9h] BYREF

result = 1LL;
state = 1;
LABEL_2:
while ( (_DWORD)result != 2 )
{
while ( 1 )
{
(*(void (__fastcall **)(__int64, char *, __int64))(a1 + 8))(a1, v2, 1LL);
if ( v2[0] == 1 )
{
result = func2(a1);
state = result;
goto LABEL_2;
}
if ( v2[0] == 3 )
break;
if ( v2[0] )
(*(void (__fastcall **)(__int64, const char *))(a1 + 32))(a1, "ERROR, protocol error");
result = (unsigned int)state;
if ( state == 2 )
return result;
}
result = func3(a1);
state = result;
}
return result;
}

original_code:
void handleFortuneServerProtocol(nmu_socket_t serviceSocket)
{
 uint8_t pduId;
 state = 1;
 while( state != 2 ){
  serviceSocket->read(serviceSocket, &pduId, sizeof(uint8_t));
  switch( pduId ){
  case 1:
   state = handleFortuneRequest(serviceSocket);
   break;
  case 3:
   state = handleFortuneQuit(serviceSocket);
   break;
  case 0:
   break;
  default:
   serviceSocket->error(serviceSocket, "ERROR, protocol error" );
  }
 }
}

canonical_original_code:
void handleFortuneServerProtocol(struct NMUSocket *serviceSocket)
{
 unsigned char pduId;
 state = 1;
 while( state != 2 ){
  serviceSocket->read(serviceSocket, &pduId, sizeof(unsigned char));
  switch( pduId ){
  case 1:
   state = handleFortuneRequest(serviceSocket);
   break;
  case 3:
   state = handleFortuneQuit(serviceSocket);
   break;
  case 0:
   break;
  default:
   serviceSocket->error(serviceSocket, "ERROR, protocol error" );
  }
 }
}

variable_types:
pduId
unsigned char


main

canonical_name: main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rbp
__pid_t v5; // eax
int v6; // [rsp+Ch] [rbp-BCh] BYREF
struct sigaction v7; // [rsp+10h] [rbp-B8h] BYREF

handleOptions(argc, argv, &v6);
((void (*)(void))socketFactory[2])();
v7.sa_handler = (__sighandler_t)sigchld_handler;
sigemptyset(&v7.sa_mask);
v7.sa_flags = 0x10000000;
if ( sigaction(17, &v7, 0LL) != -1 )
{
v3 = ((__int64 (__fastcall **)(const char *, _QWORD))socketFactory)[0]("localhost", (unsigned int)(__int16)v6);
while ( 1 )
{
v4 = (*(__int64 (__fastcall **)(__int64))v3)(v3);
v5 = fork();
if ( v5 >= 0 )
{
if ( !v5 )
{
(*(void (__fastcall **)(__int64))(v3 + 24))(v3);
handleFortuneServerProtocol(v4);
exit(0);
}
}
else
{
fwrite("Could not fork protocol handler.\n", 1uLL, 0x21uLL, stderr);
(*(void (__fastcall **)(__int64))(v4 + 24))(v4);
}
(*(void (__fastcall **)(__int64))(v4 + 24))(v4);
}
}
fwrite("Could not set SIGCHLD handler.\n", 1uLL, 0x1FuLL, stderr);
exit(-1);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rbp
__pid_t v5; // eax
int v6; // [rsp+Ch] [rbp-BCh] BYREF
struct sigaction v7; // [rsp+10h] [rbp-B8h] BYREF

func1(argc, argv, &v6);
((void (*)(void))socketFactory[2])();
v7.sa_handler = (__sighandler_t)sigchld_handler;
sigemptyset(&v7.sa_mask);
v7.sa_flags = 0x10000000;
if ( sigaction(17, &v7, 0LL) != -1 )
{
v3 = ((__int64 (__fastcall **)(const char *, _QWORD))socketFactory)[0]("localhost", (unsigned int)(__int16)v6);
while ( 1 )
{
v4 = (*(__int64 (__fastcall **)(__int64))v3)(v3);
v5 = fork();
if ( v5 >= 0 )
{
if ( !v5 )
{
(*(void (__fastcall **)(__int64))(v3 + 24))(v3);
func4(v4);
exit(0);
}
}
else
{
fwrite("Could not fork protocol handler.\n", 1uLL, 0x21uLL, stderr);
(*(void (__fastcall **)(__int64))(v4 + 24))(v4);
}
(*(void (__fastcall **)(__int64))(v4 + 24))(v4);
}
}
fwrite("Could not set SIGCHLD handler.\n", 1uLL, 0x1FuLL, stderr);
exit(-1);
}

original_code:
int main(int argc, char *argv[])
{
 int port;
 _Bool notDone = 1;
 nmu_socket_t serverSocket;
 struct sigaction sigact;
 handleOptions( argc, argv, &port );
 socketFactory.initialize();
 sigact.__sigaction_handler.sa_handler = sigchld_handler;
 sigemptyset(&sigact.sa_mask);
 sigact.sa_flags = 0x10000000;
 if( sigaction(17, &sigact, ((void *)0)) == -1){
  fprintf(stderr, "Could not set SIGCHLD handler.\n");
  exit(-1);
 }
 serverSocket = socketFactory.serveTCPForHostnameAndPort( "localhost", port );
 while( notDone ) {
  pid_t childPid;
  nmu_socket_t serviceSocket;
  serviceSocket = serverSocket->accept(serverSocket);
  childPid = fork();
  if(childPid < 0){
   fprintf( stderr, "Could not fork protocol handler.\n" );
   serviceSocket->close(serviceSocket);
  }
  if(childPid){
   serviceSocket->close(serviceSocket);
  }
  else {
   serverSocket->close(serverSocket);
   handleFortuneServerProtocol(serviceSocket);
   exit(0);
  }
 }
 serverSocket->close(serverSocket);
 return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
 int port;
 _Bool notDone = 1;
 struct NMUSocket *serverSocket;
 struct sigaction sigact;
 handleOptions( argc, argv, &port );
 socketFactory.initialize();
 sigact.__sigaction_handler.sa_handler = sigchld_handler;
 sigemptyset(&sigact.sa_mask);
 sigact.sa_flags = 0x10000000;
 if( sigaction(17, &sigact, ((void *)0)) == -1){
  fprintf(stderr, "Could not set SIGCHLD handler.\n");
  exit(-1);
 }
 serverSocket = socketFactory.serveTCPForHostnameAndPort( "localhost", port );
 while( notDone ) {
  int childPid;
  struct NMUSocket *serviceSocket;
  serviceSocket = serverSocket->accept(serverSocket);
  childPid = fork();
  if(childPid < 0){
   fprintf( stderr, "Could not fork protocol handler.\n" );
   serviceSocket->close(serviceSocket);
  }
  if(childPid){
   serviceSocket->close(serviceSocket);
  }
  else {
   serverSocket->close(serverSocket);
   handleFortuneServerProtocol(serviceSocket);
   exit(0);
  }
 }
 serverSocket->close(serverSocket);
 return 0;
}

variable_types: port int

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

variable_types: childPid int

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

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


handleError

decompiled_code:
void __fastcall __noreturn handleError(const char *a1)
{
fprintf(stderr, "%s\n", a1);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func7(const char *a1)
{
fprintf(stderr, "%s\n", a1);
exit(-1);
}

original_code:
void handleError(char *msg)
{
    fprintf(stderr, "%s\n", msg);
    exit(-1);
}

variable_types:
msg
char *


connectToServer

decompiled_code:
__int64 __fastcall connectToServer(const char *a1, const char *a2)
{
int v2; // er12
struct addrinfo *v3; // rbp
int v4; // eax
struct addrinfo *pai; // [rsp+0h] [rbp-50h] BYREF
struct addrinfo req; // [rsp+8h] [rbp-48h] BYREF

*(_QWORD *)&req.ai_flags = 0LL;
pai = 0LL;
*(_QWORD *)&req.ai_socktype = 0x600000001LL;
*(_OWORD *)&req.ai_addrlen = 0LL;
*(_OWORD *)&req.ai_canonname = 0LL;
if ( getaddrinfo(a1, a2, &req, &pai) )
handleError("ERROR getaddrinfo failed");
v3 = pai;
if ( !pai )
{
LABEL_10:
freeaddrinfo(v3);
if ( v2 >= 0 )
handleError("ERROR connecting to server");
LABEL_11:
handleError("ERROR creating socket");
}
while ( 1 )
{
v4 = socket(v3->ai_family, v3->ai_socktype, v3->ai_protocol);
v2 = v4;
if ( v4 != -1 )
break;
LABEL_8:
v3 = v3->ai_next;
if ( !v3 )
{
v3 = pai;
goto LABEL_10;
}
}
if ( connect(v4, v3->ai_addr, v3->ai_addrlen) == -1 )
{
close(v2);
goto LABEL_8;
}
freeaddrinfo(pai);
if ( v2 < 0 )
goto LABEL_11;
return (unsigned int)v2;
}

canonical_decompiled_code:
__int64 __fastcall func9(const char *a1, const char *a2)
{
int v2; // er12
struct addrinfo *v3; // rbp
int v4; // eax
struct addrinfo *pai; // [rsp+0h] [rbp-50h] BYREF
struct addrinfo req; // [rsp+8h] [rbp-48h] BYREF

*(_QWORD *)&req.ai_flags = 0LL;
pai = 0LL;
*(_QWORD *)&req.ai_socktype = 0x600000001LL;
*(_OWORD *)&req.ai_addrlen = 0LL;
*(_OWORD *)&req.ai_canonname = 0LL;
if ( getaddrinfo(a1, a2, &req, &pai) )
func7("ERROR getaddrinfo failed");
v3 = pai;
if ( !pai )
{
LABEL_10:
freeaddrinfo(v3);
if ( v2 >= 0 )
func7("ERROR connecting to server");
LABEL_11:
func7("ERROR creating socket");
}
while ( 1 )
{
v4 = socket(v3->ai_family, v3->ai_socktype, v3->ai_protocol);
v2 = v4;
if ( v4 != -1 )
break;
LABEL_8:
v3 = v3->ai_next;
if ( !v3 )
{
v3 = pai;
goto LABEL_10;
}
}
if ( connect(v4, v3->ai_addr, v3->ai_addrlen) == -1 )
{
close(v2);
goto LABEL_8;
}
freeaddrinfo(pai);
if ( v2 < 0 )
goto LABEL_11;
return (unsigned int)v2;
}

original_code:
int connectToServer(char *hostname, char *port)
{
 struct addrinfo *result = ((void *)0);
 struct addrinfo *next = ((void *)0);
 struct addrinfo hints;
 int sockfd;
 memset(&hints, 0, sizeof(struct addrinfo));
 hints.ai_family = 0;
 hints.ai_socktype = SOCK_STREAM;
 hints.ai_protocol = IPPROTO_TCP;
 if (getaddrinfo(hostname, port, &hints, &result) != 0)
  handleError("ERROR getaddrinfo failed");
 for(next = result; next != ((void *)0); next = next->ai_next) {
  sockfd = socket(next->ai_family, next->ai_socktype, next->ai_protocol);
  if( sockfd == -1 )
   continue;
  if(connect(sockfd, next->ai_addr, next->ai_addrlen) == -1){
   close(sockfd);
   continue;
  }
  break;
 }
 freeaddrinfo(result);
 if (sockfd < 0)
  handleError("ERROR creating socket");
 if (next == ((void *)0))
  handleError("ERROR connecting to server");
 return sockfd;
}

variable_types:
hostname
char *

variable_types:
port
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: sockfd 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; }


handleReply

decompiled_code:
__int64 __fastcall handleReply(int fd)
{
__int64 result; // rax
unsigned __int8 buf; // [rsp+Fh] [rbp-119h] BYREF
char v3[280]; // [rsp+10h] [rbp-118h] BYREF

memset(v3, 0, 0x100uLL);
if ( read(fd, &buf, 1uLL) == -1 )
{
perror("Error reading count");
result = 0LL;
}
else if ( read(fd, v3, buf) == -1 )
{
perror("Error reading fortune");
result = 0LL;
}
else
{
printf("%s", v3);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(int fd)
{
__int64 result; // rax
unsigned __int8 buf; // [rsp+Fh] [rbp-119h] BYREF
char v3[280]; // [rsp+10h] [rbp-118h] BYREF

memset(v3, 0, 0x100uLL);
if ( read(fd, &buf, 1uLL) == -1 )
{
perror("Error reading count");
result = 0LL;
}
else if ( read(fd, v3, buf) == -1 )
{
perror("Error reading fortune");
result = 0LL;
}
else
{
printf("%s", v3);
result = 1LL;
}
return result;
}

original_code:
_Bool handleReply(int sockfd)
{
 uint8_t count;
 char buffer[256];
 memset(buffer, 0, 256);
 if (read(sockfd, &count, sizeof(uint8_t)) == -1) {
  perror("Error reading count");
  return 0;
 }
 if (read(sockfd, buffer, count) == -1) {
  perror("Error reading fortune");
  return 0;
 }
 printf("%s", buffer);
 return 1;
}

canonical_original_code:
_Bool handleReply(int sockfd)
{
 unsigned char count;
 char buffer[256];
 memset(buffer, 0, 256);
 if (read(sockfd, &count, sizeof(unsigned char)) == -1) {
  perror("Error reading count");
  return 0;
 }
 if (read(sockfd, buffer, count) == -1) {
  perror("Error reading fortune");
  return 0;
 }
 printf("%s", buffer);
 return 1;
}

variable_types:
buffer
char [256]


handleFortuneProtocol

decompiled_code:
int __fastcall handleFortuneProtocol(int fd)
{
int v1; // ebx
char buf[25]; // [rsp+Fh] [rbp-19h] BYREF

if ( killServer )
{
buf[0] = 3;
if ( write(fd, buf, 1uLL) == -1 )
perror("Error writing FORTUNE_KILL");
close(fd);
handleError("Killed server.");
}
v1 = 9;
while ( 1 )
{
buf[0] = 0;
if ( write(fd, buf, 1uLL) == -1 )
{
perror("Error writing pduId");
goto LABEL_8;
}
if ( read(fd, buf, 1uLL) == -1 )
break;
if ( buf[0] != 1 )
{
close(fd);
handleError("Protocol violation");
}
if ( (unsigned __int8)handleReply(fd) )
{
if ( --v1 )
continue;
}
goto LABEL_8;
}
perror("Error reading pduId");
LABEL_8:
buf[0] = 2;
write(fd, buf, 1uLL);
return close(fd);
}

canonical_decompiled_code:
int __fastcall func11(int fd)
{
int v1; // ebx
char buf[25]; // [rsp+Fh] [rbp-19h] BYREF

if ( killServer )
{
buf[0] = 3;
if ( write(fd, buf, 1uLL) == -1 )
perror("Error writing FORTUNE_KILL");
close(fd);
func7("Killed server.");
}
v1 = 9;
while ( 1 )
{
buf[0] = 0;
if ( write(fd, buf, 1uLL) == -1 )
{
perror("Error writing pduId");
goto LABEL_8;
}
if ( read(fd, buf, 1uLL) == -1 )
break;
if ( buf[0] != 1 )
{
close(fd);
func7("Protocol violation");
}
if ( (unsigned __int8)func10(fd) )
{
if ( --v1 )
continue;
}
goto LABEL_8;
}
perror("Error reading pduId");
LABEL_8:
buf[0] = 2;
write(fd, buf, 1uLL);
return close(fd);
}

original_code:
void handleFortuneProtocol(int sockfd)
{
 uint8_t pduId;
 int fortuneCount;
 if (killServer) {
  pduId = 3;
  if (write(sockfd, &pduId, sizeof(uint8_t)) == -1)
   perror("Error writing FORTUNE_KILL");
  close(sockfd);
  handleError("Killed server.");
 }
 for (fortuneCount = 1; fortuneCount <= 9; fortuneCount++) {
  pduId = 0;
  if (write(sockfd, &pduId, sizeof(uint8_t)) == -1) {
   perror("Error writing pduId");
   break;
  }
  if (read(sockfd, &pduId, sizeof(uint8_t)) == -1) {
   perror("Error reading pduId");
   break;
  }
  if (pduId == 1) {
   if (!handleReply(sockfd))
    break;
  } else {
   close(sockfd);
   handleError("Protocol violation");
  }
 }
 pduId = 2;
 write(sockfd, &pduId, sizeof(uint8_t));
 close(sockfd);
}

canonical_original_code:
void handleFortuneProtocol(int sockfd)
{
 unsigned char pduId;
 int fortuneCount;
 if (killServer) {
  pduId = 3;
  if (write(sockfd, &pduId, sizeof(unsigned char)) == -1)
   perror("Error writing FORTUNE_KILL");
  close(sockfd);
  handleError("Killed server.");
 }
 for (fortuneCount = 1; fortuneCount <= 9; fortuneCount++) {
  pduId = 0;
  if (write(sockfd, &pduId, sizeof(unsigned char)) == -1) {
   perror("Error writing pduId");
   break;
  }
  if (read(sockfd, &pduId, sizeof(unsigned char)) == -1) {
   perror("Error reading pduId");
   break;
  }
  if (pduId == 1) {
   if (!handleReply(sockfd))
    break;
  } else {
   close(sockfd);
   handleError("Protocol violation");
  }
 }
 pduId = 2;
 write(sockfd, &pduId, sizeof(unsigned char));
 close(sockfd);
}

variable_types: fortuneCount int


handleFortuneError

decompiled_code:
__int64 __fastcall handleFortuneError(__int64 a1)
{
(*(void (__fastcall **)(__int64, const char *))(a1 + 40))(a1, "fortuneServer: ERROR protocolError\n");
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
(*(void (__fastcall **)(__int64, const char *))(a1 + 40))(a1, "fortuneServer: ERROR protocolError\n");
return 1LL;
}

original_code:
int handleFortuneError(nmu_socket_t serviceSocket)
{
 serviceSocket->error(serviceSocket, "fortuneServer: ERROR protocolError\n");
 return 1;
}

canonical_original_code:
int handleFortuneError(struct NMUSocket *serviceSocket)
{
 serviceSocket->error(serviceSocket, "fortuneServer: ERROR protocolError\n");
 return 1;
}

variable_types: struct NMUSocket { struct NMUSocket *(*accept)(struct NMUSocket *); void (*acceptAndServe)(struct NMUSocket *, void *(*)(struct NMUSocket *)); int (*read)(struct NMUSocket *, void *, int); int (*write)(struct NMUSocket *, void *, int); void (*close)(struct NMUSocket *); void (*error)(struct NMUSocket *, char *); struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; } sockAddr; int sockfd; } *

user_defined_types: struct NMUSocket { struct NMUSocket *(*accept)(struct NMUSocket *); void (*acceptAndServe)(struct NMUSocket *, void *(*)(struct NMUSocket *)); int (*read)(struct NMUSocket *, void *, int); int (*write)(struct NMUSocket *, void *, int); void (*close)(struct NMUSocket *); void (*error)(struct NMUSocket *, char *); struct sockaddr_in sockAddr; int sockfd; }


handleProtocolError

decompiled_code:
void __fastcall __noreturn handleProtocolError(__int64 a1)
{
(*(void (**)(void))(a1 + 32))();
fwrite("Protocol violation.\n", 1uLL, 0x14uLL, stderr);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func1(__int64 a1)
{
(*(void (**)(void))(a1 + 32))();
fwrite("Protocol violation.\n", 1uLL, 0x14uLL, stderr);
exit(-1);
}

original_code:
int handleProtocolError(nmu_socket_t pSocket)
{
 pSocket->close(pSocket);
 fprintf(stderr, "Protocol violation.\n");
 exit(-1);
 return 1;
}

canonical_original_code:
int handleProtocolError(struct NMUSocket *pSocket)
{
 pSocket->close(pSocket);
 fprintf(stderr, "Protocol violation.\n");
 exit(-1);
 return 1;
}


shouldQuit

decompiled_code:
bool shouldQuit()
{
bool v0; // zf
bool v1; // sf
bool v2; // of

v2 = __OFSUB__(fortuneCount_0, 8);
v0 = fortuneCount_0 == 8;
v1 = fortuneCount_0 - 8 < 0;
++fortuneCount_0;
return !(v1 ^ v2 | v0);
}

canonical_decompiled_code:
bool func2()
{
bool v0; // zf
bool v1; // sf
bool v2; // of

v2 = __OFSUB__(fortuneCount_0, 8);
v0 = fortuneCount_0 == 8;
v1 = fortuneCount_0 - 8 < 0;
++fortuneCount_0;
return !(v1 ^ v2 | v0);
}

original_code:
_Bool shouldQuit(void)
{
 static int fortuneCount = 0;
 return (fortuneCount++ >= 9);
}

canonical_original_code:
_Bool shouldQuit()
{
 static int fortuneCount = 0;
 return (fortuneCount++ >= 9);
}


wstrlen

decompiled_code:
__int64 __fastcall wstrlen(__int64 a1)
{
return *(unsigned int *)(a1 - 8);
}

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

original_code:
static inline int wstrlen(const wstr s)
{
    struct wstrhd *hd = (struct wstrhd *)(s - sizeof(struct wstrhd));
    return hd->len;
}

canonical_original_code:
static inline int wstrlen(char *s)
{
    struct wstrhd *hd = (struct wstrhd *)(s - sizeof(struct wstrhd));
    return hd->len;
}

variable_types:
s
char *

variable_types: struct wstrhd { int len; int free; char buf[]; } *


extraValidator

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

if ( (int)Server[275] >= (int)Server[271] )
wheat_assert("Server.stat_refresh_seconds < Server.worker_timeout", "config.c", 211LL, 1LL);
if ( !Server[2] || !Server[3] || (result = Server[274], !(_DWORD)result) )
result = wheat_assert(
"Server.port_range_start && Server.port_range_end && Server.stat_port",
"config.c",
212LL,
1LL);
return result;
}

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

if ( (int)Server[275] >= (int)Server[271] )
wheat_assert("Server.stat_refresh_seconds < Server.worker_timeout", "config.c", 211LL, 1LL);
if ( !Server[2] || !Server[3] || (result = Server[274], !(_DWORD)result) )
result = wheat_assert(
"Server.port_range_start && Server.port_range_end && Server.stat_port",
"config.c",
212LL,
1LL);
return result;
}

original_code:
static void extraValidator()
{
    do { if (!(Server.stat_refresh_seconds < Server.worker_timeout)) { wheat_assert("Server.stat_refresh_seconds < Server.worker_timeout", "config.c", 211, 1); } } while (0);
    do { if (!(Server.port_range_start && Server.port_range_end && Server.stat_port)) { wheat_assert("Server.port_range_start && Server.port_range_end && Server.stat_port", "config.c", 212, 1); } } while (0);
}


stringValidator

decompiled_code:
__int64 __fastcall stringValidator(__int64 a1, __int64 a2, const char *a3)
{
if ( !a3 )
wheat_assert("val", "config.c", 125LL, 1LL);
if ( *(_QWORD *)(a1 + 24) && !*(_QWORD *)(a1 + 32) )
{
wfree();
*(_QWORD *)(a1 + 32) = 0LL;
}
if ( !strncasecmp(a3, "NULL", 5uLL) )
*(_QWORD *)(a1 + 24) = 0LL;
else
*(_QWORD *)(a1 + 24) = strdup(a3);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, const char *a3)
{
if ( !a3 )
wheat_assert("val", "config.c", 125LL, 1LL);
if ( *(_QWORD *)(a1 + 24) && !*(_QWORD *)(a1 + 32) )
{
wfree();
*(_QWORD *)(a1 + 32) = 0LL;
}
if ( !strncasecmp(a3, "NULL", 5uLL) )
*(_QWORD *)(a1 + 24) = 0LL;
else
*(_QWORD *)(a1 + 24) = strdup(a3);
return 0LL;
}

original_code:
int stringValidator(struct configuration *conf, const char *key, const char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 125, 1); } } while (0);
    if (conf->target.ptr && !conf->helper) {
        wfree(conf->target.ptr);
        conf->helper = ((void *)0);
    }
    if (!strncasecmp(val, "NULL", sizeof("NULL")))
        conf->target.ptr = ((void *)0);
    else
        conf->target.ptr = strdup(val);
    return 0;
}

canonical_original_code:
int stringValidator(struct configuration *conf, char *key, char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 125, 1); } } while (0);
    if (conf->target.ptr && !conf->helper) {
        wfree(conf->target.ptr);
        conf->helper = ((void *)0);
    }
    if (!strncasecmp(val, "NULL", sizeof("NULL")))
        conf->target.ptr = ((void *)0);
    else
        conf->target.ptr = strdup(val);
    return 0;
}

variable_types: struct configuration { char *name; int args; int (*validator)(struct configuration *conf, char *key, char *value); union { int val; void *ptr; struct enumIdName { int id; char *name; } *enum_ptr; } target; void *helper; enum printFormat { INT_FORMAT=0, STRING_FORMAT=1, ENUM_FORMAT=2, BOOL_FORMAT=3, LIST_FORMAT=4 } format; } *

variable_types:
key
char *

variable_types:
val
char *

user_defined_types: struct configuration { char *name; int args; int (*validator)(struct configuration *conf, char *key, char *value); union { int val; void *ptr; struct enumIdName *enum_ptr; } target; void *helper; enum printFormat format; }


unsignedIntValidator

decompiled_code:
__int64 __fastcall unsignedIntValidator(__int64 a1, __int64 a2, const char *a3)
{
int v4; // eax
__int64 v5; // r12
__int64 v6; // rdx
bool v7; // cl
bool v8; // al
__int64 result; // rax
int v10; // edx

if ( !a3 )
wheat_assert("val", "config.c", 154LL, 1LL);
v4 = *a3;
if ( *(_QWORD *)(a1 + 32) )
{
v5 = *(_QWORD *)(a1 + 32);
if ( !(_BYTE)v4 )
{
v10 = atoi(a3);
goto LABEL_15;
}
}
else
{
v5 = 0LL;
if ( !(_BYTE)v4 )
{
v10 = atoi(a3);
LABEL_13:
*(_DWORD *)(a1 + 24) = v10;
return 0LL;
}
}
if ( (unsigned int)(v4 - 48) > 9 )
return 1LL;
v6 = 1LL;
while ( a3[v6] )
{
v7 = (unsigned int)(a3[v6] - 48) > 9;
v8 = (_DWORD)v6++ == 10;
if ( v8 || v7 )
return 1LL;
}
v10 = atoi(a3);
if ( !v5 )
goto LABEL_13;
LABEL_15:
result = 1LL;
if ( v10 <= v5 )
goto LABEL_13;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2, const char *a3)
{
int v4; // eax
__int64 v5; // r12
__int64 v6; // rdx
bool v7; // cl
bool v8; // al
__int64 result; // rax
int v10; // edx

if ( !a3 )
wheat_assert("val", "config.c", 154LL, 1LL);
v4 = *a3;
if ( *(_QWORD *)(a1 + 32) )
{
v5 = *(_QWORD *)(a1 + 32);
if ( !(_BYTE)v4 )
{
v10 = atoi(a3);
goto LABEL_15;
}
}
else
{
v5 = 0LL;
if ( !(_BYTE)v4 )
{
v10 = atoi(a3);
LABEL_13:
*(_DWORD *)(a1 + 24) = v10;
return 0LL;
}
}
if ( (unsigned int)(v4 - 48) > 9 )
return 1LL;
v6 = 1LL;
while ( a3[v6] )
{
v7 = (unsigned int)(a3[v6] - 48) > 9;
v8 = (_DWORD)v6++ == 10;
if ( v8 || v7 )
return 1LL;
}
v10 = atoi(a3);
if ( !v5 )
goto LABEL_13;
LABEL_15:
result = 1LL;
if ( v10 <= v5 )
goto LABEL_13;
return result;
}

original_code:
int unsignedIntValidator(struct configuration *conf, const char *key, const char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 154, 1); } } while (0);
    int i, digit, value;
    intptr_t max_limit = 0;
    if (conf->helper)
        max_limit = (intptr_t)conf->helper;
    for (i = 0; val[i] != '\0'; i++) {
        digit = val[i] - 48;
        if (digit < 0 || digit > 9)
            return 1;
        if (i >= 10)
            return 1;
    }
    value = atoi(val);
    if (max_limit != 0 && value > max_limit)
        return 1;
    conf->target.val = value;
    return 0;
}

canonical_original_code:
int unsignedIntValidator(struct configuration *conf, char *key, char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 154, 1); } } while (0);
    int i; int digit; int value;
    long max_limit = 0;
    if (conf->helper)
        max_limit = (long)conf->helper;
    for (i = 0; val[i] != '\0'; i++) {
        digit = val[i] - 48;
        if (digit < 0 || digit > 9)
            return 1;
        if (i >= 10)
            return 1;
    }
    value = atoi(val);
    if (max_limit != 0 && value > max_limit)
        return 1;
    conf->target.val = value;
    return 0;
}

variable_types: i int

variable_types: digit int

variable_types: value int

user_defined_types: enum printFormat { INT_FORMAT=0, STRING_FORMAT=1, ENUM_FORMAT=2, BOOL_FORMAT=3, LIST_FORMAT=4 }

user_defined_types: struct enumIdName { int id; char *name; }


enumValidator

decompiled_code:
int __fastcall enumValidator(__int64 a1, __int64 a2, const char *a3)
{
__int64 v4; // r13
size_t v5; // rax
int result; // eax
const char *v7; // rbp

if ( !a3 )
wheat_assert("val", "config.c", 179LL, 1LL);
v4 = *(_QWORD *)(a1 + 32);
if ( !v4 )
{
wheat_assert("conf->helper", "config.c", 180LL, 1LL);
v4 = *(_QWORD *)(a1 + 32);
}
while ( 1 )
{
v7 = *(const char **)(v4 + 8);
if ( !v7 )
return 1;
v5 = strlen(*(const char **)(v4 + 8));
result = strncasecmp(a3, v7, v5);
if ( !result )
break;
v4 += 16LL;
}
*(_QWORD *)(a1 + 24) = v4;
return result;
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1, __int64 a2, const char *a3)
{
__int64 v4; // r13
size_t v5; // rax
int result; // eax
const char *v7; // rbp

if ( !a3 )
wheat_assert("val", "config.c", 179LL, 1LL);
v4 = *(_QWORD *)(a1 + 32);
if ( !v4 )
{
wheat_assert("conf->helper", "config.c", 180LL, 1LL);
v4 = *(_QWORD *)(a1 + 32);
}
while ( 1 )
{
v7 = *(const char **)(v4 + 8);
if ( !v7 )
return 1;
v5 = strlen(*(const char **)(v4 + 8));
result = strncasecmp(a3, v7, v5);
if ( !result )
break;
v4 += 16LL;
}
*(_QWORD *)(a1 + 24) = v4;
return result;
}

original_code:
int enumValidator(struct configuration *conf, const char *key, const char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 179, 1); } } while (0);
    do { if (!(conf->helper)) { wheat_assert("conf->helper", "config.c", 180, 1); } } while (0);
    struct enumIdName *sentinel = (struct enumIdName *)conf->helper;
    while (sentinel->name) {
        if (strncasecmp(val, sentinel->name, strlen(sentinel->name)) == 0) {
            conf->target.enum_ptr = sentinel;
            return 0;
        }
        else if (sentinel == ((void *)0))
            break ;
        sentinel++;
    }
    return 1;
}

canonical_original_code:
int enumValidator(struct configuration *conf, char *key, char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 179, 1); } } while (0);
    do { if (!(conf->helper)) { wheat_assert("conf->helper", "config.c", 180, 1); } } while (0);
    struct enumIdName *sentinel = (struct enumIdName *)conf->helper;
    while (sentinel->name) {
        if (strncasecmp(val, sentinel->name, strlen(sentinel->name)) == 0) {
            conf->target.enum_ptr = sentinel;
            return 0;
        }
        else if (sentinel == ((void *)0))
            break ;
        sentinel++;
    }
    return 1;
}

variable_types: struct enumIdName { int id; char *name; } *


boolValidator

decompiled_code:
int __fastcall boolValidator(__int64 a1, __int64 a2, const char *a3)
{
size_t v4; // r12
int result; // eax

v4 = strlen(a3) + 1;
result = memcmp("on", a3, v4);
if ( result )
{
result = memcmp("off", a3, v4);
if ( result )
result = 1;
else
*(_DWORD *)(a1 + 24) = 0;
}
else
{
*(_DWORD *)(a1 + 24) = 1;
}
return result;
}

canonical_decompiled_code:
int __fastcall func5(__int64 a1, __int64 a2, const char *a3)
{
size_t v4; // r12
int result; // eax

v4 = strlen(a3) + 1;
result = memcmp("on", a3, v4);
if ( result )
{
result = memcmp("off", a3, v4);
if ( result )
result = 1;
else
*(_DWORD *)(a1 + 24) = 0;
}
else
{
*(_DWORD *)(a1 + 24) = 1;
}
return result;
}

original_code:
int boolValidator(struct configuration *conf, const char *key, const char *val)
{
    size_t len = strlen(val) + 1;
    if (memcmp("on", val, len) == 0) {
        conf->target.val = 1;
    } else if (memcmp("off", val, len) == 0) {
        conf->target.val = 0;
    } else
        return 1;
    return 0;
}

canonical_original_code:
int boolValidator(struct configuration *conf, char *key, char *val)
{
    unsigned long len = strlen(val) + 1;
    if (memcmp("on", val, len) == 0) {
        conf->target.val = 1;
    } else if (memcmp("off", val, len) == 0) {
        conf->target.val = 0;
    } else
        return 1;
    return 0;
}

variable_types:
len
unsigned long


handleList

original_code:
static struct list *handleList(wstr *lines, int *i, int count)
{
    int pos = *i + 1;
    wstr line = ((void *)0);
    struct list *l = createList();
    ((l)->free = ((void(*)(void *))wstrFree));
    while (pos < count) {
        line = wstrStrip(lines[pos], "\t\n\r ");
        int len = 0;
        int line_valid = 0;
        while (len < wstrlen(line)) {
            char ch = line[len];
            switch(ch) {
                case ' ':
                    len++;
                    break;
                case '-':
                    if (!line_valid)
                        line_valid = 1;
                    else
                        goto handle_error;
                    len++;
                    break;
                default:
                    if (!line_valid)
                        goto handle_error;
                    appendToListTail(l, wstrNew(&line[len]));
                    len = wstrlen(line);
                    break;
            }
        }
        pos++;
    }
handle_error:
    pos--;
    *i = pos;
    return l;
}

canonical_original_code:
static struct list *handleList(char **lines, int *i, int count)
{
    int pos = *i + 1;
    char *line = ((void *)0);
    struct list *l = createList();
    ((l)->free = ((void (*)(void *))wstrFree));
    while (pos < count) {
        line = wstrStrip(lines[pos], "\t\n\r ");
        int len = 0;
        int line_valid = 0;
        while (len < wstrlen(line)) {
            char ch = line[len];
            switch(ch) {
                case ' ':
                    len++;
                    break;
                case '-':
                    if (!line_valid)
                        line_valid = 1;
                    else
                        goto handle_error;
                    len++;
                    break;
                default:
                    if (!line_valid)
                        goto handle_error;
                    appendToListTail(l, wstrNew(&line[len]));
                    len = wstrlen(line);
                    break;
            }
        }
        pos++;
    }
handle_error:
    pos--;
    *i = pos;
    return l;
}

variable_types:
lines
char **

variable_types:
i
int *

variable_types: count int

variable_types: pos int

variable_types:
line
char *

variable_types: struct list { struct listNode { struct listNode *next; struct listNode *prev; void *value; } *first; void *(*dup)(void *ptr); int (*match)(void *ptr, void *key); void (*free)(void *ptr); unsigned long len; } *

variable_types: len int

variable_types: ch char

user_defined_types: struct list { struct listNode *first; void *(*dup)(void *ptr); int (*match)(void *ptr, void *key); void (*free)(void *ptr); unsigned long len; }


fillServerConfig

decompiled_code:
__int64 fillServerConfig()
{
__int64 v0; // rax
__int64 v1; // rdx
__int64 result; // rax
unsigned int v3; // edx
unsigned int v4; // edx

v0 = (__int64)*(&configTable + 9);
Server[4] = *((_DWORD *)&configTable + 42);
v1 = (__int64)*(&configTable + 27);
*(_QWORD *)Server = v0;
result = *((unsigned int *)&configTable + 30);
*(_QWORD *)&Server[6] = *(_QWORD *)(v1 + 8);
*(_QWORD *)&Server[21044] = *(&configTable + 33);
Server[21046] = *(_DWORD *)*(&configTable + 39);
Server[267] = *((_DWORD *)&configTable + 90);
*(_QWORD *)&Server[268] = *(&configTable + 51);
Server[270] = *((_DWORD *)&configTable + 114);
*(_QWORD *)&Server[272] = *(&configTable + 63);
Server[274] = *((_DWORD *)&configTable + 138);
Server[275] = *((_DWORD *)&configTable + 150);
*(_QWORD *)&Server[276] = *(&configTable + 81);
Server[271] = *((_DWORD *)&configTable + 174);
*(_QWORD *)&Server[21028] = *((int *)&configTable + 186);
v3 = *((_DWORD *)&configTable + 198);
if ( !v3 )
v3 = result;
Server[2] = v3;
v4 = *((_DWORD *)&configTable + 210);
if ( v4 )
result = v4;
Server[3] = result;
return result;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 v0; // rax
__int64 v1; // rdx
__int64 result; // rax
unsigned int v3; // edx
unsigned int v4; // edx

v0 = (__int64)*(&configTable + 9);
Server[4] = *((_DWORD *)&configTable + 42);
v1 = (__int64)*(&configTable + 27);
*(_QWORD *)Server = v0;
result = *((unsigned int *)&configTable + 30);
*(_QWORD *)&Server[6] = *(_QWORD *)(v1 + 8);
*(_QWORD *)&Server[21044] = *(&configTable + 33);
Server[21046] = *(_DWORD *)*(&configTable + 39);
Server[267] = *((_DWORD *)&configTable + 90);
*(_QWORD *)&Server[268] = *(&configTable + 51);
Server[270] = *((_DWORD *)&configTable + 114);
*(_QWORD *)&Server[272] = *(&configTable + 63);
Server[274] = *((_DWORD *)&configTable + 138);
Server[275] = *((_DWORD *)&configTable + 150);
*(_QWORD *)&Server[276] = *(&configTable + 81);
Server[271] = *((_DWORD *)&configTable + 174);
*(_QWORD *)&Server[21028] = *((int *)&configTable + 186);
v3 = *((_DWORD *)&configTable + 198);
if ( !v3 )
v3 = result;
Server[2] = v3;
v4 = *((_DWORD *)&configTable + 210);
if ( v4 )
result = v4;
Server[3] = result;
return result;
}

original_code:
void fillServerConfig()
{
    struct configuration *conf = &configTable[1];
    Server.bind_addr = conf->target.ptr;
    conf++;
    Server.port_range_start = Server.port_range_end = conf->target.val;
    conf++;
    Server.worker_number = conf->target.val;
    conf++;
    Server.worker_type = conf->target.enum_ptr->name;
    conf++;
    Server.logfile = conf->target.ptr;
    conf++;
    Server.verbose = conf->target.enum_ptr->id;
    conf++;
    Server.daemon = conf->target.val;
    conf++;
    Server.pidfile = conf->target.ptr;
    conf++;
    Server.max_buffer_size = conf->target.val;
    conf++;
    Server.stat_addr = conf->target.ptr;
    conf++;
    Server.stat_port = conf->target.val;
    conf++;
    Server.stat_refresh_seconds = conf->target.val;
    conf++;
    Server.stat_file = conf->target.ptr;
    conf++;
    Server.worker_timeout = conf->target.val;
    conf++;
    Server.mbuf_size = conf->target.val;
    conf++;
    if (conf->target.val)
        Server.port_range_start = conf->target.val;
    conf++;
    if (conf->target.val)
        Server.port_range_end = conf->target.val;
}


listValidator

decompiled_code:
__int64 __fastcall listValidator(__int64 a1, __int64 a2, __int64 a3)
{
if ( !a3 )
wheat_assert("val", "config.c", 141LL, 1LL);
if ( *(_QWORD *)(a1 + 24) )
freeList();
*(_QWORD *)(a1 + 24) = a3;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, __int64 a2, __int64 a3)
{
if ( !a3 )
wheat_assert("val", "config.c", 141LL, 1LL);
if ( *(_QWORD *)(a1 + 24) )
freeList();
*(_QWORD *)(a1 + 24) = a3;
return 0LL;
}

original_code:
int listValidator(struct configuration *conf, const char *key, const char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 141, 1); } } while (0);
    if (conf->target.ptr) {
        freeList(conf->target.ptr);
    }
    conf->target.ptr = (struct list *)val;
    return 0;
}

canonical_original_code:
int listValidator(struct configuration *conf, char *key, char *val)
{
    do { if (!(val)) { wheat_assert("val", "config.c", 141, 1); } } while (0);
    if (conf->target.ptr) {
        freeList(conf->target.ptr);
    }
    conf->target.ptr = (struct list *)val;
    return 0;
}

user_defined_types: struct listNode { struct listNode *next; struct listNode *prev; void *value; }


initServerConfs

decompiled_code:
__int64 __fastcall initServerConfs(__int64 a1)
{
char **v1; // rbx
char **v2; // rsi
__int64 result; // rax

v1 = &configTable;
do
{
v2 = v1;
v1 += 6;
result = appendToListTail(a1, v2);
}
while ( v1 != &configTable + 114 );
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
char **v1; // rbx
char **v2; // rsi
__int64 result; // rax

v1 = &configTable;
do
{
v2 = v1;
v1 += 6;
result = appendToListTail(a1, v2);
}
while ( v1 != &configTable + 114 );
return result;
}

original_code:
void initServerConfs(struct list *confs)
{
    struct configuration *conf;
    int len, i;
    len = sizeof(configTable) / sizeof(struct configuration);
    i = 0;
    while (i != len) {
        conf = &configTable[i];
        appendToListTail(confs, conf);
        i++;
    }
}

canonical_original_code:
void initServerConfs(struct list *confs)
{
    struct configuration *conf;
    int len; int i;
    len = sizeof(configTable) / sizeof(struct configuration);
    i = 0;
    while (i != len) {
        conf = &configTable[i];
        appendToListTail(confs, conf);
        i++;
    }
}


getConfiguration

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

v1 = listGetIterator(*(_QWORD *)&Server[21038], 0LL);
do
{
v4 = listNext(v1);
v2 = (const char **)v4;
if ( !v4 )
break;
v2 = *(const char ***)(v4 + 16);
v3 = strlen(s);
}
while ( strncasecmp(s, *v2, v3) );
freeListIterator(v1);
return v2;
}

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

v1 = listGetIterator(*(_QWORD *)&Server[21038], 0LL);
do
{
v4 = listNext(v1);
v2 = (const char **)v4;
if ( !v4 )
break;
v2 = *(const char ***)(v4 + 16);
v3 = strlen(s);
}
while ( strncasecmp(s, *v2, v3) );
freeListIterator(v1);
return v2;
}

original_code:
struct configuration *getConfiguration(const char *name)
{
    struct listNode *node;
    struct listIterator *iter;
    struct configuration *conf;
    iter = listGetIterator(Server.confs, 0);
    while ((node = listNext(iter)) != ((void *)0)) {
        conf = ((void*)((node)->value));
        if (!strncasecmp(name, conf->name, strlen(name))) {
            freeListIterator(iter);
            return conf;
        }
    }
    freeListIterator(iter);
    return ((void *)0);
}

canonical_original_code:
struct configuration *getConfiguration(char *name)
{
    struct listNode *node;
    struct listIterator *iter;
    struct configuration *conf;
    iter = listGetIterator(Server.confs, 0);
    while ((node = listNext(iter)) != ((void *)0)) {
        conf = ((void *)((node)->value));
        if (!strncasecmp(name, conf->name, strlen(name))) {
            freeListIterator(iter);
            return conf;
        }
    }
    freeListIterator(iter);
    return ((void *)0);
}

variable_types:
name
char *

variable_types: struct listIterator { struct listNode { struct listNode *next; struct listNode *prev; void *value; } *next; int direction; } *

return_type: struct configuration { char *name; int args; int (*validator)(struct configuration *conf, char *key, char *value); union { int val; void *ptr; struct enumIdName { int id; char *name; } *enum_ptr; } target; void *helper; enum printFormat { INT_FORMAT=0, STRING_FORMAT=1, ENUM_FORMAT=2, BOOL_FORMAT=3, LIST_FORMAT=4 } format; } *

user_defined_types: struct listIterator { struct listNode *next; int direction; }


applyConfig

decompiled_code:
__int64 __fastcall applyConfig(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // r12
__int64 v3; // rsi
int v4; // eax
int v5; // edx
_BYTE *v6; // rdi
char **v7; // rax
char **v8; // rbp
const char **v9; // rbx
unsigned int v10; // eax
__int64 v11; // r8
const char *v13; // r13
int v14; // [rsp+4h] [rbp-34h] BYREF
unsigned int v15; // [rsp+8h] [rbp-30h] BYREF
int v16[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v1 = wstrNewSplit(a1, "\n", 1LL, &v14);
v16[0] = 0;
v2 = v1;
if ( !v1 )
{
LABEL_18:
v13 = "Memory alloc failed";
goto LABEL_19;
}
v3 = (unsigned int)v14;
if ( v14 <= 0 )
{
LABEL_17:
wstrFreeSplit(v2, v3);
return fillServerConfig();
}
v4 = 0;
while ( 1 )
{
v6 = (_BYTE *)wstrStrip(*(_QWORD *)(v2 + 8LL * v4), "\t\n\r ");
if ( (*v6 & 0xDF) == 0 || *v6 == 35 )
goto LABEL_8;
v7 = (char **)wstrNewSplit(v6, " ", 1LL, &v15);
v8 = v7;
if ( !v7 )
goto LABEL_18;
v9 = getConfiguration(*v7);
if ( !v9 )
{
v13 = "Unknown configuration name";
goto LABEL_19;
}
v10 = v15;
v11 = (__int64)v8[1];
if ( v15 == 1 && *((_DWORD *)v9 + 10) == 4 )
break;
LABEL_4:
v5 = *((_DWORD *)v9 + 2);
if ( v5 != v10 && v5 != -1 )
{
v13 = "Incorrect args";
goto LABEL_19;
}
if ( ((unsigned int (__fastcall *)(const char **, char *, __int64))v9[2])(v9, *v8, v11) )
{
v13 = "Validate Failed";
goto LABEL_19;
}
wstrFreeSplit(v8, v15);
LABEL_8:
v3 = (unsigned int)v14;
v4 = v16[0] + 1;
v16[0] = v4;
if ( v4 >= v14 )
goto LABEL_17;
}
v11 = handleList(v2, v16, v14);
if ( v11 )
{
v10 = v15;
goto LABEL_4;
}
v13 = "parse list failed";
LABEL_19:
fwrite("\n*** FATAL CONFIG FILE ERROR ***\n", 1uLL, 0x21uLL, stderr);
fprintf(stderr, "Reading the configuration file, at line %d\n", (unsigned int)(v16[0] + 1));
fprintf(stderr, ">>> '%s'\n", *(const char **)(v2 + 8LL * v16[0]));
fprintf(stderr, "Reason: %s\n", v13);
return halt(1LL);
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // r12
__int64 v3; // rsi
int v4; // eax
int v5; // edx
_BYTE *v6; // rdi
char **v7; // rax
char **v8; // rbp
const char **v9; // rbx
unsigned int v10; // eax
__int64 v11; // r8
const char *v13; // r13
int v14; // [rsp+4h] [rbp-34h] BYREF
unsigned int v15; // [rsp+8h] [rbp-30h] BYREF
int v16[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v1 = wstrNewSplit(a1, "\n", 1LL, &v14);
v16[0] = 0;
v2 = v1;
if ( !v1 )
{
LABEL_18:
v13 = "Memory alloc failed";
goto LABEL_19;
}
v3 = (unsigned int)v14;
if ( v14 <= 0 )
{
LABEL_17:
wstrFreeSplit(v2, v3);
return func8();
}
v4 = 0;
while ( 1 )
{
v6 = (_BYTE *)wstrStrip(*(_QWORD *)(v2 + 8LL * v4), "\t\n\r ");
if ( (*v6 & 0xDF) == 0 || *v6 == 35 )
goto LABEL_8;
v7 = (char **)wstrNewSplit(v6, " ", 1LL, &v15);
v8 = v7;
if ( !v7 )
goto LABEL_18;
v9 = func11(*v7);
if ( !v9 )
{
v13 = "Unknown configuration name";
goto LABEL_19;
}
v10 = v15;
v11 = (__int64)v8[1];
if ( v15 == 1 && *((_DWORD *)v9 + 10) == 4 )
break;
LABEL_4:
v5 = *((_DWORD *)v9 + 2);
if ( v5 != v10 && v5 != -1 )
{
v13 = "Incorrect args";
goto LABEL_19;
}
if ( ((unsigned int (__fastcall *)(const char **, char *, __int64))v9[2])(v9, *v8, v11) )
{
v13 = "Validate Failed";
goto LABEL_19;
}
wstrFreeSplit(v8, v15);
LABEL_8:
v3 = (unsigned int)v14;
v4 = v16[0] + 1;
v16[0] = v4;
if ( v4 >= v14 )
goto LABEL_17;
}
v11 = func6(v2, v16, v14);
if ( v11 )
{
v10 = v15;
goto LABEL_4;
}
v13 = "parse list failed";
LABEL_19:
fwrite("\n*** FATAL CONFIG FILE ERROR ***\n", 1uLL, 0x21uLL, stderr);
fprintf(stderr, "Reading the configuration file, at line %d\n", (unsigned int)(v16[0] + 1));
fprintf(stderr, ">>> '%s'\n", *(const char **)(v2 + 8LL * v16[0]));
fprintf(stderr, "Reason: %s\n", v13);
return halt(1LL);
}

original_code:
void applyConfig(wstr config)
{
    int count, args;
    wstr *lines = wstrNewSplit(config, "\n", 1, &count);
    char *err = ((void *)0);
    struct configuration *conf;
    void *ptr = ((void *)0);
    int i = 0;
    if (lines == ((void *)0)) {
        err = "Memory alloc failed";
        goto loaderr;
    }
    for (i = 0; i < count; i++) {
        wstr line = wstrStrip(lines[i], "\t\n\r ");
        if (line[0] == '#' || line[0] == '\0' || line[0] == ' ')
            continue;
        wstr *argvs = wstrNewSplit(line, " ", 1, &args);
        if (argvs == ((void *)0)) {
            err = "Memory alloc failed";
            goto loaderr;
        }
        if ((conf = getConfiguration(argvs[0])) == ((void *)0)) {
            err = "Unknown configuration name";
            goto loaderr;
        }
        ptr = argvs[1];
        if (args == 1 && conf->format == LIST_FORMAT) {
            struct list *l = handleList(lines, &i, count);
            if (!l) {
                err = "parse list failed";
                goto loaderr;
            }
            ptr = l;
        } else if (args != conf->args && args == 2) {
            int j;
            for (j = 2; j < args; ++j) {
                argvs[1] = wstrCatLen(argvs[1], argvs[j], wstrlen(argvs[j]));
                if (!argvs[1]) {
                    err = "Unknown configuration name";
                    goto loaderr;
                }
            }
        }
        if (args != conf->args && conf->args != (-1)) {
            err = "Incorrect args";
            goto loaderr;
        }
        if (conf->validator(conf, argvs[0], ptr) != 0) {
            err = "Validate Failed";
            goto loaderr;
        }
        wstrFreeSplit(argvs, args);
    }
    wstrFreeSplit(lines, count);
    fillServerConfig();
    return ;
loaderr:
    fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
    fprintf(stderr, "Reading the configuration file, at line %d\n", i+1);
    fprintf(stderr, ">>> '%s'\n", lines[i]);
    fprintf(stderr, "Reason: %s\n", err);
    halt(1);
}

canonical_original_code:
void applyConfig(char *config)
{
    int count; int args;
    char **lines = wstrNewSplit(config, "\n", 1, &count);
    char *err = ((void *)0);
    struct configuration *conf;
    void *ptr = ((void *)0);
    int i = 0;
    if (lines == ((void *)0)) {
        err = "Memory alloc failed";
        goto loaderr;
    }
    for (i = 0; i < count; i++) {
        char *line = wstrStrip(lines[i], "\t\n\r ");
        if (line[0] == '#' || line[0] == '\0' || line[0] == ' ')
            continue;
        char **argvs = wstrNewSplit(line, " ", 1, &args);
        if (argvs == ((void *)0)) {
            err = "Memory alloc failed";
            goto loaderr;
        }
        if ((conf = getConfiguration(argvs[0])) == ((void *)0)) {
            err = "Unknown configuration name";
            goto loaderr;
        }
        ptr = argvs[1];
        if (args == 1 && conf->format == LIST_FORMAT) {
            struct list *l = handleList(lines, &i, count);
            if (!l) {
                err = "parse list failed";
                goto loaderr;
            }
            ptr = l;
        } else if (args != conf->args && args == 2) {
            int j;
            for (j = 2; j < args; ++j) {
                argvs[1] = wstrCatLen(argvs[1], argvs[j], wstrlen(argvs[j]));
                if (!argvs[1]) {
                    err = "Unknown configuration name";
                    goto loaderr;
                }
            }
        }
        if (args != conf->args && conf->args != (-1)) {
            err = "Incorrect args";
            goto loaderr;
        }
        if (conf->validator(conf, argvs[0], ptr) != 0) {
            err = "Validate Failed";
            goto loaderr;
        }
        wstrFreeSplit(argvs, args);
    }
    wstrFreeSplit(lines, count);
    fillServerConfig();
    return ;
loaderr:
    fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
    fprintf(stderr, "Reading the configuration file, at line %d\n", i+1);
    fprintf(stderr, ">>> '%s'\n", lines[i]);
    fprintf(stderr, "Reason: %s\n", err);
    halt(1);
}

variable_types:
config
char *

variable_types: args int

variable_types:
err
char *

variable_types: struct configuration { char *name; int args; int (*validator)(struct configuration *conf, char *key, char *value); union { int val; void *ptr; struct enumIdName { int id; char *name; } *enum_ptr; } target; void *helper; enum printFormat { INT_FORMAT=0, STRING_FORMAT=1, ENUM_FORMAT=2, BOOL_FORMAT=3, LIST_FORMAT=4 } format; } *

variable_types:
ptr
void *

variable_types:
argvs
char **

variable_types: j int


configCommand

decompiled_code:
__int64 __fastcall configCommand(__int64 a1)
{
const char **v1; // rax
__int64 v2; // rdx
__m128i v4; // [rsp+0h] [rbp-118h] BYREF
char v5[16]; // [rsp+10h] [rbp-108h] BYREF

v1 = getConfiguration(*(char **)(*(_QWORD *)(a1 + 32) + 8LL));
if ( v1 )
{
v2 = constructConfigFormat_constprop_0(v1, v4.m128i_i8);
}
else
{
v2 = 27LL;
strcpy(v5, "nfiguration");
v4 = _mm_load_si128((const __m128i *)&LC25);
}
return replyMasterClient(a1, &v4, v2);
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1)
{
const char **v1; // rax
__int64 v2; // rdx
__m128i v4; // [rsp+0h] [rbp-118h] BYREF
char v5[16]; // [rsp+10h] [rbp-108h] BYREF

v1 = func11(*(char **)(*(_QWORD *)(a1 + 32) + 8LL));
if ( v1 )
{
v2 = func7(v1, v4.m128i_i8);
}
else
{
v2 = 27LL;
strcpy(v5, "nfiguration");
v4 = _mm_load_si128((const __m128i *)&LC25);
}
return replyMasterClient(a1, &v4, v2);
}

original_code:
void configCommand(struct masterClient *c)
{
    struct configuration *conf = ((void *)0);
    char buf[255];
    ssize_t len;
    conf = getConfiguration(c->argv[1]);
    if (conf == ((void *)0)) {
        len = snprintf(buf, 255, "No Correspond Configuration");
    } else {
        len = constructConfigFormat(conf, buf, 255);
    }
    replyMasterClient(c, buf, len);
}

canonical_original_code:
void configCommand(struct masterClient *c)
{
    struct configuration *conf = ((void *)0);
    char buf[255];
    long len;
    conf = getConfiguration(c->argv[1]);
    if (conf == ((void *)0)) {
        len = snprintf(buf, 255, "No Correspond Configuration");
    } else {
        len = constructConfigFormat(conf, buf, 255);
    }
    replyMasterClient(c, buf, len);
}

variable_types: struct masterClient { int fd; char *request_buf; char *response_buf; int argc; char **argv; } *

variable_types:
buf
char [255]

variable_types: len long


printServerConfig

decompiled_code:
__int64 __fastcall printServerConfig(unsigned int a1)
{
unsigned int v1; // ebp
__int64 v2; // r12
__int64 v3; // rax
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

v1 = a1;
if ( a1 )
v1 = 2;
wheatLog(v1, "---- Now Configuration are ----");
v2 = listGetIterator(*(_QWORD *)&Server[21038], 0LL);
while ( 1 )
{
v3 = listNext(v2);
if ( !v3 )
break;
constructConfigFormat_constprop_0(*(const char ***)(v3 + 16), v5);
wheatLog(v1, "%s", v5);
}
freeListIterator(v2);
return wheatLog(v1, "-------------------------------");
}

canonical_decompiled_code:
__int64 __fastcall func14(unsigned int a1)
{
unsigned int v1; // ebp
__int64 v2; // r12
__int64 v3; // rax
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

v1 = a1;
if ( a1 )
v1 = 2;
wheatLog(v1, "---- Now Configuration are ----");
v2 = listGetIterator(*(_QWORD *)&Server[21038], 0LL);
while ( 1 )
{
v3 = listNext(v2);
if ( !v3 )
break;
func7(*(const char ***)(v3 + 16), v5);
wheatLog(v1, "%s", v5);
}
freeListIterator(v2);
return wheatLog(v1, "-------------------------------");
}

original_code:
void printServerConfig(int test)
{
    struct configuration *conf;
    int level;
    struct listNode *node;
    struct listIterator *iter;
    char buf[255];
    level = test ? 2 : 0;
    wheatLog(level, "---- Now Configuration are ----");
    iter = listGetIterator(Server.confs, 0);
    while ((node = listNext(iter)) != ((void *)0)) {
        conf = ((void*)((node)->value));
        constructConfigFormat(conf, buf, 255);
        wheatLog(level, "%s", buf);
    }
    freeListIterator(iter);
    wheatLog(level, "-------------------------------");
}

canonical_original_code:
void printServerConfig(int test)
{
    struct configuration *conf;
    int level;
    struct listNode *node;
    struct listIterator *iter;
    char buf[255];
    level = test ? 2 : 0;
    wheatLog(level, "---- Now Configuration are ----");
    iter = listGetIterator(Server.confs, 0);
    while ((node = listNext(iter)) != ((void *)0)) {
        conf = ((void *)((node)->value));
        constructConfigFormat(conf, buf, 255);
        wheatLog(level, "%s", buf);
    }
    freeListIterator(iter);
    wheatLog(level, "-------------------------------");
}

variable_types: test int

variable_types: level int

variable_types: struct listNode { struct listNode *next; struct listNode *prev; void *value; } *


eventInit

decompiled_code:
__int64 __fastcall eventInit(int a1)
{
__int64 v1; // r12
__int64 v2; // rax
int v3; // eax

v1 = wmalloc(16LL);
if ( !v1 )
return v1;
v2 = wmalloc(12LL * a1);
*(_QWORD *)(v1 + 8) = v2;
if ( v2 )
{
v3 = epoll_create(1024);
*(_DWORD *)v1 = v3;
if ( v3 != -1 )
return v1;
wfree(*(_QWORD *)(v1 + 8));
}
wfree(v1);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
__int64 v1; // r12
__int64 v2; // rax
int v3; // eax

v1 = wmalloc(16LL);
if ( !v1 )
return v1;
v2 = wmalloc(12LL * a1);
*(_QWORD *)(v1 + 8) = v2;
if ( v2 )
{
v3 = epoll_create(1024);
*(_DWORD *)v1 = v3;
if ( v3 != -1 )
return v1;
wfree(*(_QWORD *)(v1 + 8));
}
wfree(v1);
return 0LL;
}

original_code:
static struct apiState *eventInit(int nevent) {
    struct apiState *state = wmalloc(sizeof(struct apiState));
    if (!state) return ((void *)0);
    state->events = wmalloc(sizeof(struct epoll_event)*nevent);
    if (!state->events) {
        wfree(state);
        return ((void *)0);
    }
    state->epfd = epoll_create(1024);
    if (state->epfd == -1) {
        wfree(state->events);
        wfree(state);
        return ((void *)0);
    }
    return state;
}

variable_types: nevent int

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

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

user_defined_types: struct apiState { int epfd; struct epoll_event *events; }


eventDeinit

decompiled_code:
__int64 __fastcall eventDeinit(__int64 a1)
{
close(*(_DWORD *)a1);
wfree(*(_QWORD *)(a1 + 8));
return wfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
close(*(_DWORD *)a1);
wfree(*(_QWORD *)(a1 + 8));
return wfree(a1);
}

original_code:
static void eventDeinit(struct apiState *state) {
    close(state->epfd);
    wfree(state->events);
    wfree(state);
}

user_defined_types: union epoll_data { void *ptr; int fd; unsigned int u32; unsigned long u64; }


eventWait

original_code:
static int eventWait(struct evcenter *center, struct timeval *tvp) {
    struct apiState *state = center->apidata;
    int retval, numevents = 0;
    retval = epoll_wait(state->epfd, state->events, center->nevent,
            tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
    if (retval > 0) {
        int j;
        numevents = retval;
        for (j = 0; j < numevents; j++) {
            int mask = 0;
            struct epoll_event *e = state->events + j;
            if (e->events & EPOLLIN) mask |= 1;
            if (e->events & EPOLLOUT) mask |= 2;
            if (e->events & EPOLLERR) mask |= 2;
            if (e->events & EPOLLHUP) mask |= 2;
            center->fired_events[j].fd = e->data.fd;
            center->fired_events[j].mask = mask;
        }
    }
    return numevents;
}

canonical_original_code:
static int eventWait(struct evcenter *center, struct timeval *tvp) {
    struct apiState *state = center->apidata;
    int retval; int numevents = 0;
    retval = epoll_wait(state->epfd, state->events, center->nevent,
            tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
    if (retval > 0) {
        int j;
        numevents = retval;
        for (j = 0; j < numevents; j++) {
            int mask = 0;
            struct epoll_event *e = state->events + j;
            if (e->events & EPOLLIN) mask |= 1;
            if (e->events & EPOLLOUT) mask |= 2;
            if (e->events & EPOLLERR) mask |= 2;
            if (e->events & EPOLLHUP) mask |= 2;
            center->fired_events[j].fd = e->data.fd;
            center->fired_events[j].mask = mask;
        }
    }
    return numevents;
}

variable_types: struct evcenter { int nevent; struct event { int mask; void *client_data; void (*read_proc)(struct evcenter *center, int fd, void *client_data, int mask); void (*write_proc)(struct evcenter *center, int fd, void *client_data, int mask); } *events; struct fired_event { int mask; int fd; } *fired_events; void *apidata; } *

variable_types: struct timeval { long tv_sec; long tv_usec; } *

variable_types: retval int

variable_types: numevents int

variable_types: mask int

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

user_defined_types: struct evcenter { int nevent; struct event *events; struct fired_event *fired_events; void *apidata; }


eventcenterInit

decompiled_code:
__int64 __fastcall eventcenterInit(int a1)
{
__int64 v1; // r12
void *v2; // r13
void *v3; // rbp
__int64 v4; // rax
int *v6; // rax
char *v7; // rax
int *v8; // rax
char *v9; // rax
int *v10; // rax
char *v11; // rax

v1 = wmalloc(32LL);
if ( !v1 )
{
v10 = _errno_location();
v11 = strerror(*v10);
wheatLog(4LL, "center create failed: %s", v11);
return v1;
}
v2 = (void *)wmalloc(32LL * a1);
v3 = (void *)wmalloc(8LL * a1);
if ( !v3 || !v2 )
{
v6 = _errno_location();
v7 = strerror(*v6);
wheatLog(4LL, "event and fired_event create failed: %s", v7);
wfree(v1);
if ( !v3 )
{
v1 = 0LL;
if ( !v2 )
return v1;
LABEL_9:
wfree(v2);
return v1;
}
LABEL_11:
v1 = 0LL;
wfree(v3);
if ( !v2 )
return v1;
goto LABEL_9;
}
memset(v2, 0, 32LL * a1);
memset(v3, 0, 8LL * a1);
v4 = eventInit(a1);
if ( !v4 )
{
v8 = _errno_location();
v9 = strerror(*v8);
wheatLog(4LL, "naive event init failed", v9);
wfree(v1);
goto LABEL_11;
}
*(_DWORD *)v1 = a1;
*(_QWORD *)(v1 + 8) = v2;
*(_QWORD *)(v1 + 16) = v3;
*(_QWORD *)(v1 + 24) = v4;
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1)
{
__int64 v1; // r12
void *v2; // r13
void *v3; // rbp
__int64 v4; // rax
int *v6; // rax
char *v7; // rax
int *v8; // rax
char *v9; // rax
int *v10; // rax
char *v11; // rax

v1 = wmalloc(32LL);
if ( !v1 )
{
v10 = _errno_location();
v11 = strerror(*v10);
wheatLog(4LL, "center create failed: %s", v11);
return v1;
}
v2 = (void *)wmalloc(32LL * a1);
v3 = (void *)wmalloc(8LL * a1);
if ( !v3 || !v2 )
{
v6 = _errno_location();
v7 = strerror(*v6);
wheatLog(4LL, "event and fired_event create failed: %s", v7);
wfree(v1);
if ( !v3 )
{
v1 = 0LL;
if ( !v2 )
return v1;
LABEL_9:
wfree(v2);
return v1;
}
LABEL_11:
v1 = 0LL;
wfree(v3);
if ( !v2 )
return v1;
goto LABEL_9;
}
memset(v2, 0, 32LL * a1);
memset(v3, 0, 8LL * a1);
v4 = func0(a1);
if ( !v4 )
{
v8 = _errno_location();
v9 = strerror(*v8);
wheatLog(4LL, "naive event init failed", v9);
wfree(v1);
goto LABEL_11;
}
*(_DWORD *)v1 = a1;
*(_QWORD *)(v1 + 8) = v2;
*(_QWORD *)(v1 + 16) = v3;
*(_QWORD *)(v1 + 24) = v4;
return v1;
}

original_code:
struct evcenter *eventcenterInit(int nevent)
{
    struct event *events = ((void *)0);
    struct evcenter *center = ((void *)0);
    struct fired_event *fired_events = ((void *)0);
    void *api_state = ((void *)0);
    center = wmalloc(sizeof(struct evcenter));
    if (center == ((void *)0)) {
        wheatLog(4, "center create failed: %s", strerror((*__errno_location ())));
        return ((void *)0);
    }
    events = wmalloc(nevent*sizeof(struct event));
    fired_events = wmalloc(nevent*sizeof(struct fired_event));
    if (fired_events == ((void *)0) || events == ((void *)0)) {
        wheatLog(4, "event and fired_event create failed: %s",
                strerror((*__errno_location ())));
        goto cleanup;
    }
    memset(events, 0, nevent*sizeof(struct event));
    memset(fired_events, 0, nevent*sizeof(struct fired_event));
    api_state = eventInit(nevent);
    if (!api_state) {
        wheatLog(4, "naive event init failed", strerror((*__errno_location ())));
        goto cleanup;
    }
    center->nevent = nevent;
    center->events = events;
    center->fired_events = fired_events;
    center->apidata = api_state;
    return center;
cleanup:
    if (center)
        wfree(center);
    if (fired_events)
        wfree(fired_events);
    if (events)
        wfree(events);
    return ((void *)0);
}

variable_types: struct event { int mask; void *client_data; void (*read_proc)(struct evcenter { int nevent; struct event *events; struct fired_event { int mask; int fd; } *fired_events; void *apidata; } *center, int fd, void *client_data, int mask); void (*write_proc)(struct evcenter *center, int fd, void *client_data, int mask); } *

return_type: struct evcenter { int nevent; struct event { int mask; void *client_data; void (*read_proc)(struct evcenter *center, int fd, void *client_data, int mask); void (*write_proc)(struct evcenter *center, int fd, void *client_data, int mask); } *events; struct fired_event { int mask; int fd; } *fired_events; void *apidata; } *


eventcenterDealloc

decompiled_code:
__int64 __fastcall eventcenterDealloc(__int64 a1)
{
eventDeinit(*(_QWORD *)(a1 + 24));
wfree(*(_QWORD *)(a1 + 8));
return wfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
func1(*(_QWORD *)(a1 + 24));
wfree(*(_QWORD *)(a1 + 8));
return wfree(a1);
}

original_code:
void eventcenterDealloc(struct evcenter *center)
{
    eventDeinit(center->apidata);
    wfree(center->events);
    wfree(center);
}

user_defined_types: struct event { int mask; void *client_data; void (*read_proc)(struct evcenter *center, int fd, void *client_data, int mask); void (*write_proc)(struct evcenter *center, int fd, void *client_data, int mask); }

user_defined_types: struct fired_event { int mask; int fd; }


createEvent

original_code:
int createEvent(struct evcenter *center, int fd, int mask, eventProc *proc, void *client_data)
{
    if (fd >= center->nevent) {
        (*__errno_location ()) = 34;
        return -1;
    }
    struct event *event = &center->events[fd];
    if (addEvent(center, fd, mask) == -1)
        return -1;
    event->mask |= mask;
    if (mask & 1) event->read_proc = proc;
    if (mask & 2) event->write_proc = proc;
    event->client_data = client_data;
    return 0;
}

canonical_original_code:
int createEvent(struct evcenter *center, int fd, int mask, void (*proc)(struct evcenter *center, int fd, void *client_data, int mask), void *client_data)
{
    if (fd >= center->nevent) {
        (*__errno_location ()) = 34;
        return -1;
    }
    struct event *event = &center->events[fd];
    if (addEvent(center, fd, mask) == -1)
        return -1;
    event->mask |= mask;
    if (mask & 1) event->read_proc = proc;
    if (mask & 2) event->write_proc = proc;
    event->client_data = client_data;
    return 0;
}

variable_types: fd int

variable_types: void (*)(struct evcenter *center, int fd, void *client_data, int mask)


deleteEvent

original_code:
void deleteEvent(struct evcenter *center, int fd, int mask)
{
    if (fd >= center->nevent) return;
    struct event *event = &center->events[fd];
    if (event->mask == 0) return;
    event->mask = event->mask & (~mask);
    delEvent(center, fd, mask);
}


processEvents

original_code:
int processEvents(struct evcenter *center, int timeout_millionseconds)
{
    struct timeval tv;
    int j, processed, numevents, mask, fd, rfired;
    struct event *event;
    if (timeout_millionseconds > 0) {
        tv.tv_sec = timeout_millionseconds / 1000;
        tv.tv_usec = (timeout_millionseconds % 1000) * 1000;
    }
    else {
        tv.tv_sec = 0;
        tv.tv_usec = 0;
    }
    processed = 0;
    numevents = eventWait(center, &tv);
    for (j = 0; j < numevents; j++) {
        event = &center->events[center->fired_events[j].fd];
        mask = center->fired_events[j].mask;
        fd = center->fired_events[j].fd;
        rfired = 0;
        if (event->mask & mask & 1) {
            rfired = 1;
            event->read_proc(center, fd, event->client_data, mask);
        }
        if (event->mask & mask & 2) {
            if (!rfired || event->read_proc != event->write_proc)
                event->write_proc(center, fd, event->client_data, mask);
        }
        processed++;
    }
    return processed;
}

canonical_original_code:
int processEvents(struct evcenter *center, int timeout_millionseconds)
{
    struct timeval tv;
    int j; int processed; int numevents; int mask; int fd; int rfired;
    struct event *event;
    if (timeout_millionseconds > 0) {
        tv.tv_sec = timeout_millionseconds / 1000;
        tv.tv_usec = (timeout_millionseconds % 1000) * 1000;
    }
    else {
        tv.tv_sec = 0;
        tv.tv_usec = 0;
    }
    processed = 0;
    numevents = eventWait(center, &tv);
    for (j = 0; j < numevents; j++) {
        event = &center->events[center->fired_events[j].fd];
        mask = center->fired_events[j].mask;
        fd = center->fired_events[j].fd;
        rfired = 0;
        if (event->mask & mask & 1) {
            rfired = 1;
            event->read_proc(center, fd, event->client_data, mask);
        }
        if (event->mask & mask & 2) {
            if (!rfired || event->read_proc != event->write_proc)
                event->write_proc(center, fd, event->client_data, mask);
        }
        processed++;
    }
    return processed;
}

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types: j int

variable_types: processed int

variable_types: rfired int


createList

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

result = (_QWORD *)wmalloc(48LL);
result[1] = 0LL;
*result = 0LL;
result[5] = 0LL;
result[2] = 0LL;
result[3] = 0LL;
result[4] = 0LL;
return result;
}

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

result = (_QWORD *)wmalloc(48LL);
result[1] = 0LL;
*result = 0LL;
result[5] = 0LL;
result[2] = 0LL;
result[3] = 0LL;
result[4] = 0LL;
return result;
}

original_code:
struct list *createList()
{
    struct list *l = wmalloc(sizeof(struct list));
    l->first = l->last = ((void *)0);
    l->len = 0;
    l->dup = ((void *)0);
    l->match = ((void *)0);
    l->free = ((void *)0);
    return l;
}

variable_types: struct list { struct listNode { struct listNode *next; struct listNode *prev; void *value; } *first; void *(*dup)(void *ptr); int (*match)(void *ptr, void *key); void (*free)(void *ptr); unsigned long len; } *


listClear

decompiled_code:
__int64 __fastcall listClear(__int64 a1)
{
__int64 result; // rax
_QWORD *v2; // rbp
__int64 v3; // rbx
void (__fastcall *v4)(_QWORD); // rax
_QWORD *v5; // r12

result = *(_QWORD *)(a1 + 40);
v2 = *(_QWORD **)a1;
if ( result )
{
v3 = result - 1;
do
{
v4 = *(void (__fastcall **)(_QWORD))(a1 + 32);
v5 = v2;
v2 = (_QWORD *)*v2;
if ( v4 )
v4(v5[2]);
result = wfree(v5);
}
while ( v3-- != 0 );
}
*(_QWORD *)(a1 + 40) = 0LL;
*(_QWORD *)(a1 + 8) = 0LL;
*(_QWORD *)a1 = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 result; // rax
_QWORD *v2; // rbp
__int64 v3; // rbx
void (__fastcall *v4)(_QWORD); // rax
_QWORD *v5; // r12

result = *(_QWORD *)(a1 + 40);
v2 = *(_QWORD **)a1;
if ( result )
{
v3 = result - 1;
do
{
v4 = *(void (__fastcall **)(_QWORD))(a1 + 32);
v5 = v2;
v2 = (_QWORD *)*v2;
if ( v4 )
v4(v5[2]);
result = wfree(v5);
}
while ( v3-- != 0 );
}
*(_QWORD *)(a1 + 40) = 0LL;
*(_QWORD *)(a1 + 8) = 0LL;
*(_QWORD *)a1 = 0LL;
return result;
}

original_code:
void listClear(struct list *l)
{
    struct listNode *current, *next;
    unsigned long len = l->len;
    current = l->first;
    while (len--) {
        next = current->next;
        if (l->free)
            l->free((void*)current->value);
        wfree(current);
        current = next;
    }
    l->len = 0;
    l->first = l->last = ((void *)0);
}

canonical_original_code:
void listClear(struct list *l)
{
    struct listNode *current; struct listNode *next;
    unsigned long len = l->len;
    current = l->first;
    while (len--) {
        next = current->next;
        if (l->free)
            l->free((void *)current->value);
        wfree(current);
        current = next;
    }
    l->len = 0;
    l->first = l->last = ((void *)0);
}

variable_types: struct listNode { struct listNode *next; struct listNode *prev; void *value; } *

variable_types:
len
unsigned long


freeList

decompiled_code:
__int64 __fastcall freeList(__int64 a1)
{
listClear(a1);
return wfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
func1(a1);
return wfree(a1);
}

original_code:
void freeList(struct list *l)
{
    listClear(l);
    wfree(l);
}


removeListNode

decompiled_code:
void __fastcall removeListNode(_QWORD *a1, __int64 *a2)
{
_QWORD *v2; // rax
__int64 v3; // rdx
void (__fastcall *v4)(__int64); // rax

if ( !a2 )
return;
v2 = (_QWORD *)a2[1];
v3 = *a2;
if ( !v2 )
{
*a1 = v3;
if ( v3 )
goto LABEL_4;
LABEL_9:
a1[1] = v2;
goto LABEL_5;
}
*v2 = v3;
if ( !v3 )
goto LABEL_9;
LABEL_4:
*(_QWORD *)(v3 + 8) = v2;
LABEL_5:
v4 = (void (__fastcall *)(__int64))a1[4];
if ( v4 )
v4(a2[2]);
--a1[5];
wfree(a2);
}

canonical_decompiled_code:
void __fastcall func3(_QWORD *a1, __int64 *a2)
{
_QWORD *v2; // rax
__int64 v3; // rdx
void (__fastcall *v4)(__int64); // rax

if ( !a2 )
return;
v2 = (_QWORD *)a2[1];
v3 = *a2;
if ( !v2 )
{
*a1 = v3;
if ( v3 )
goto LABEL_4;
LABEL_9:
a1[1] = v2;
goto LABEL_5;
}
*v2 = v3;
if ( !v3 )
goto LABEL_9;
LABEL_4:
*(_QWORD *)(v3 + 8) = v2;
LABEL_5:
v4 = (void (__fastcall *)(__int64))a1[4];
if ( v4 )
v4(a2[2]);
--a1[5];
wfree(a2);
}

original_code:
void removeListNode(struct list *l, struct listNode *node)
{
    if (node == ((void *)0))
        return ;
    if (node->prev)
        node->prev->next = node->next;
    else
        l->first = node->next;
    if (node->next)
        node->next->prev = node->prev;
    else
        l->last = node->prev;
    if (l->free) l->free((void*)(node->value));
    l->len--;
    wfree(node);
}

canonical_original_code:
void removeListNode(struct list *l, struct listNode *node)
{
    if (node == ((void *)0))
        return ;
    if (node->prev)
        node->prev->next = node->next;
    else
        l->first = node->next;
    if (node->next)
        node->next->prev = node->prev;
    else
        l->last = node->prev;
    if (l->free) l->free((void *)(node->value));
    l->len--;
    wfree(node);
}

variable_types:
node
struct listNode *


listGetIterator

decompiled_code:
__int64 __fastcall listGetIterator(__int64 *a1, int a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rdx

result = wmalloc(16LL);
if ( result )
{
if ( a2 )
{
v4 = a1[1];
*(_DWORD *)(result + 8) = 1;
*(_QWORD *)result = v4;
}
else
{
v3 = *a1;
*(_DWORD *)(result + 8) = 0;
*(_QWORD *)result = v3;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 *a1, int a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rdx

result = wmalloc(16LL);
if ( result )
{
if ( a2 )
{
v4 = a1[1];
*(_DWORD *)(result + 8) = 1;
*(_QWORD *)result = v4;
}
else
{
v3 = *a1;
*(_DWORD *)(result + 8) = 0;
*(_QWORD *)result = v3;
}
}
return result;
}

original_code:
struct listIterator *listGetIterator(struct list *list, int direction)
{
    struct listIterator *iter = wmalloc(sizeof(struct listIterator));
    if (iter == ((void *)0))
        return ((void *)0);
    if (direction == 0) {
        iter->next = list->first;
        iter->direction = 0;
    }
    else {
        iter->next = list->last;
        iter->direction = 1;
    }
    return iter;
}

variable_types: struct list { struct listNode *first; void *(*dup)(void *ptr); int (*match)(void *ptr, void *key); void (*free)(void *ptr); unsigned long len; } *

variable_types: direction int

variable_types: struct listIterator { struct listNode { struct listNode *next; struct listNode *prev; void *value; } *next; int direction; } *


freeListIterator

decompiled_code:
// attributes: thunk
__int64 __fastcall freeListIterator(__int64 a1)
{
return wfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return wfree(a1);
}

original_code:
void freeListIterator(struct listIterator *iter)
{
    wfree(iter);
}


listPrint

decompiled_code:
void __fastcall listPrint(__int64 *a1)
{
unsigned int v1; // ebx
__int64 v2; // rbp
__int64 v3; // rsi
_QWORD *v4; // rax

if ( a1 )
{
v1 = 0;
v2 = listGetIterator(a1, 0);
while ( 1 )
{
v4 = listNext(v2);
if ( !v4 )
break;
v3 = v1++;
printf("%d: %s -> ", v3, (const char *)v4[2]);
}
freeListIterator(v2);
putchar(10);
}
}

canonical_decompiled_code:
void __fastcall func8(__int64 *a1)
{
unsigned int v1; // ebx
__int64 v2; // rbp
__int64 v3; // rsi
_QWORD *v4; // rax

if ( a1 )
{
v1 = 0;
v2 = func6(a1, 0);
while ( 1 )
{
v4 = listNext(v2);
if ( !v4 )
break;
v3 = v1++;
printf("%d: %s -> ", v3, (const char *)v4[2]);
}
func7(v2);
putchar(10);
}
}

original_code:
void listPrint(struct list *list)
{
    if (list == ((void *)0))
        return ;
    struct listIterator *iter = listGetIterator(list, 0);
    struct listNode *current;
    int i = 0;
    while ((current = listNext(iter)) != ((void *)0)) {
        printf("%d: %s -> ", i, (char *)current->value);
        i++;
    }
    freeListIterator(iter);
    printf("\n");
}

variable_types: i int


wstrlen

decompiled_code:
__int64 __fastcall wstrlen(__int64 a1)
{
return *(unsigned int *)(a1 - 8);
}

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

original_code:
static inline int wstrlen(const wstr s)
{
    struct wstrhd *hd = (struct wstrhd *)(s - sizeof(struct wstrhd));
    return hd->len;
}

canonical_original_code:
static inline int wstrlen(char *s)
{
    struct wstrhd *hd = (struct wstrhd *)(s - sizeof(struct wstrhd));
    return hd->len;
}

variable_types:
s
char *

variable_types: struct wstrhd { int len; int free; char buf[]; } *


deallocStaticFile

decompiled_code:
__int64 deallocStaticFile()
{
if ( AllowExtensions )
dictRelease();
if ( DirectoryIndex )
freeList();
MaxFileSize = 0;
return wstrFree(IfModifiedSince);
}

canonical_decompiled_code:
__int64 func4()
{
if ( AllowExtensions )
dictRelease();
if ( DirectoryIndex )
freeList();
MaxFileSize = 0;
return wstrFree(IfModifiedSince);
}

original_code:
void deallocStaticFile()
{
    if (AllowExtensions)
        dictRelease(AllowExtensions);
    if (DirectoryIndex)
        freeList(DirectoryIndex);
    MaxFileSize = 0;
    wstrFree(IfModifiedSince);
}


freeStaticFileData

decompiled_code:
__int64 __fastcall freeStaticFileData(__int64 a1)
{
int v2; // edi

wstrFree(*(_QWORD *)(a1 + 8));
wstrFree(*(_QWORD *)a1);
v2 = *(_DWORD *)(a1 + 16);
if ( v2 > 0 )
close(v2);
return wfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
int v2; // edi

wstrFree(*(_QWORD *)(a1 + 8));
wstrFree(*(_QWORD *)a1);
v2 = *(_DWORD *)(a1 + 16);
if ( v2 > 0 )
close(v2);
return wfree(a1);
}

original_code:
void freeStaticFileData(void *app_data)
{
    struct staticFileData *data = app_data;
    wstrFree(data->extension);
    wstrFree(data->filename);
    if (data->fd > 0)
        close(data->fd);
    wfree(data);
}

variable_types: struct staticFileData { char *filename; char *extension; int fd; } *