decompiled_code:
__int64 init_signal()
{
int *v1; // rax
char *v2; // rax
struct sigaction vars0; // [rsp+0h] [rbp+0h] BYREF

memset(&vars0, 0, sizeof(vars0));
sigemptyset(&vars0.sa_mask);
vars0.sa_handler = (__sighandler_t)handle_signal;
if ( sigaction(17, &vars0, 0LL) >= 0 && sigaction(3, &vars0, 0LL) >= 0 )
return 0LL;
v1 = _errno_location();
v2 = strerror(*v1);
fprintf(stderr, "sigaction %s\n", v2);
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 func3()
{
int *v1; // rax
char *v2; // rax
struct sigaction vars0; // [rsp+0h] [rbp+0h] BYREF

memset(&vars0, 0, sizeof(vars0));
sigemptyset(&vars0.sa_mask);
vars0.sa_handler = (__sighandler_t)handle_signal;
if ( sigaction(17, &vars0, 0LL) >= 0 && sigaction(3, &vars0, 0LL) >= 0 )
return 0LL;
v1 = _errno_location();
v2 = strerror(*v1);
fprintf(stderr, "sigaction %s\n", v2);
return 0xFFFFFFFFLL;
}

original_code:
static
int init_signal() {
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sigemptyset(&sa.sa_mask);
    sa.__sigaction_handler.sa_handler = &handle_signal;
    if (sigaction(17, &sa, ((void *)0)) < 0
            || sigaction(3, &sa, ((void *)0)) < 0) {
        fprintf(stderr, "sigaction %s" "\n", strerror((*__errno_location ())));
        return -1;
    }
    return 0;
}

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)(); }

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; }


repo: nqv/aranea

decompiled_code:
void __fastcall handle_signal(int a1)
{
if ( a1 == 3 )
{
flags_ |= 1u;
}
else if ( a1 == 17 )
{
while ( waitpid(-1, 0LL, 1) > 0 )
;
}
}

canonical_decompiled_code:
void __fastcall func4(int a1)
{
if ( a1 == 3 )
{
flags_ |= 1u;
}
else if ( a1 == 17 )
{
while ( waitpid(-1, 0LL, 1) > 0 )
;
}
}

original_code:
static
void handle_signal(int sig) {
    switch (sig) {
    case 17:
        while (waitpid(-1, ((void *)0), 1) > 0);
        break;
    case 3:
        flags_ |= FLAG_QUIT;
        break;
    }
}

variable_types: sig int

return_type: void


cleanup

decompiled_code:
__int64 cleanup()
{
_QWORD *v0; // rbx
void *v1; // rbp

v0 = (_QWORD *)g_server[2];
while ( v0 )
{
v1 = v0;
v0 = (_QWORD *)v0[159];
client_close(v1);
free(v1);
}
return clientpool_cleanup();
}

canonical_decompiled_code:
__int64 func5()
{
_QWORD *v0; // rbx
void *v1; // rbp

v0 = (_QWORD *)g_server[2];
while ( v0 )
{
v1 = v0;
v0 = (_QWORD *)v0[159];
client_close(v1);
free(v1);
}
return clientpool_cleanup();
}

original_code:
static
void cleanup() {
    struct client_t *c, *tc;
    for (c = g_server.clients; c != ((void *)0); ) {
        tc = c;
        c = c->next;
        client_close(tc);
        free(tc);
    }
    clientpool_cleanup();
}

canonical_original_code:
static void cleanup() {
    struct client_t *c; struct client_t *tc;
    for (c = g_server.clients; c != ((void *)0); ) {
        tc = c;
        c = c->next;
        client_close(tc);
        free(tc);
    }
    clientpool_cleanup();
}

variable_types: struct client_t { int remote_fd; int local_rfd; long timeout; int state; char ip[40]; struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; } request; char data[1024]; long data_length; long data_sent; struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; } response; long file_sent; unsigned int flags; struct client_t *next; struct client_t **prev; } *

user_defined_types: struct client_t { int remote_fd; int local_rfd; long timeout; int state; char ip[40]; struct request_t request; char data[1024]; long data_length; long data_sent; struct response_t response; long file_sent; unsigned int flags; struct client_t *next; struct client_t **prev; }


main

canonical_name: main

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

if ( (unsigned int)parse_options(argc, argv) )
return 1;
if ( (flags_ & 2) != 0 )
daemonize_constprop_0();
if ( (unsigned int)init_conf() )
return 1;
if ( (unsigned int)init_signal() )
return 1;
v3 = server_init(g_server);
if ( v3 )
return 1;
while ( (flags_ & 1) == 0 )
server_poll(g_server);
cleanup();
return v3;
}

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

if ( (unsigned int)func2(argc, argv) )
return 1;
if ( (flags_ & 2) != 0 )
func6();
if ( (unsigned int)func0() )
return 1;
if ( (unsigned int)func3() )
return 1;
v3 = server_init(g_server);
if ( v3 )
return 1;
while ( (flags_ & 1) == 0 )
server_poll(g_server);
func5();
return v3;
}

original_code:
int main(int argc, char **argv) {
    if (parse_options(argc, argv) != 0) {
        return 1;
    }
    if (flags_ & FLAG_DAEMON) {
        daemonize(argv);
    }
    if (init_conf() != 0) {
        return 1;
    }
    if (init_signal() != 0) {
        return 1;
    }
    if (server_init(&g_server) != 0) {
        return 1;
    }
    while (!(flags_ & FLAG_QUIT)) {
        server_poll(&g_server);
    }
    cleanup();
    return 0;
}

variable_types: argc int

variable_types:
argv
char **

return_type: int


decompiled_code:
void *clientpool_alloc()
{
void *v0; // r12
void *result; // rax

v0 = poolclient_;
if ( !poolclient_ )
return malloc(0x508uLL);
client_detach(poolclient_);
result = v0;
--poolclient_len_;
return result;
}

canonical_decompiled_code:
void *func0()
{
void *v0; // r12
void *result; // rax

v0 = poolclient_;
if ( !poolclient_ )
return malloc(0x508uLL);
client_detach(poolclient_);
result = v0;
--poolclient_len_;
return result;
}

original_code:
struct client_t *clientpool_alloc() {
    struct client_t *cli;
    if (poolclient_ != ((void *)0)) {
        cli = poolclient_;
        client_detach(cli);
        --poolclient_len_;
    } else {
        cli = malloc(sizeof(struct client_t));
    }
    return cli;
}

return_type: struct client_t { int remote_fd; int local_rfd; long timeout; int state; char ip[40]; struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; } request; char data[1024]; long data_length; long data_sent; struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; } response; long file_sent; unsigned int flags; struct client_t *next; struct client_t **prev; } *


decompiled_code:
void __fastcall clientpool_free(void *a1)
{
if ( poolclient_len_ <= 4 )
{
client_add(a1, &poolclient_);
++poolclient_len_;
}
else
{
free(a1);
}
}

canonical_decompiled_code:
void __fastcall func1(void *a1)
{
if ( poolclient_len_ <= 4 )
{
client_add(a1, &poolclient_);
++poolclient_len_;
}
else
{
free(a1);
}
}

original_code:
void clientpool_free(struct client_t *cli) {
    if (poolclient_len_ > 4) {
        free(cli);
    } else {
        client_add(cli, &poolclient_);
        ++poolclient_len_;
    }
}

user_defined_types: struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; }

user_defined_types: struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; }


decompiled_code:
void clientpool_cleanup()
{
void *v0; // rbx
void *v1; // rdi

v0 = poolclient_;
while ( v0 )
{
v1 = v0;
v0 = (void *)*((_QWORD *)v0 + 159);
free(v1);
}
}

canonical_decompiled_code:
void func2()
{
void *v0; // rbx
void *v1; // rdi

v0 = poolclient_;
while ( v0 )
{
v1 = v0;
v0 = (void *)*((_QWORD *)v0 + 159);
free(v1);
}
}

original_code:
void clientpool_cleanup() {
 struct client_t *c, *tc;
    for (c = poolclient_; c != ((void *)0); ) {
        tc = c;
        c = c->next;
        free(tc);
    }
}

canonical_original_code:
void clientpool_cleanup() {
 struct client_t *c; struct client_t *tc;
    for (c = poolclient_; c != ((void *)0); ) {
        tc = c;
        c = c->next;
        free(tc);
    }
}


original_code:
static
int client_open_file(struct client_t *self, const char *path) {
    struct stat st;
    self->local_rfd = open(path, 00 | 04000);
    if (self->local_rfd == -1) {
        fprintf(stderr, "open: %s %s" "\n", path, strerror((*__errno_location ())));
        switch ((*__errno_location ())) {
        case 13:
            self->response.status_code = HTTP_STATUS_FORBIDDEN;
            break;
        case 2:
            self->response.status_code = HTTP_STATUS_NOTFOUND;
            break;
        default:
            self->response.status_code = HTTP_STATUS_SERVERERROR;
            break;
        }
        return -1;
    }
    if (fstat(self->local_rfd, &st) == -1) {
        fprintf(stderr, "stat: %s" "\n", strerror((*__errno_location ())));
        self->response.status_code = HTTP_STATUS_SERVERERROR;
        goto err;
    }
    if (((((st.st_mode)) & 0170000) == (0040000)) || !((((st.st_mode)) & 0170000) == (0100000))) {
        fprintf(stderr, "not a regular file 0x%x" "\n", st.st_mode);
        self->response.status_code = HTTP_STATUS_FORBIDDEN;
        goto err;
    }
    self->response.last_mod = st.st_mtim.tv_sec;
    self->response.total_length = st.st_size;
    self->response.content_length = st.st_size;
    self->response.content_type = mimetype_get(path);
    self->response.content_from = 0;
    return 0;
err:
    do { close(self->local_rfd); self->local_rfd = -1; } while (0);
    return -1;
}

canonical_original_code:
static int client_open_file(struct client_t *self, char *path) {
    struct stat st;
    self->local_rfd = open(path, 00 | 04000);
    if (self->local_rfd == -1) {
        fprintf(stderr, "open: %s %s" "\n", path, strerror((*__errno_location ())));
        switch ((*__errno_location ())) {
        case 13:
            self->response.status_code = HTTP_STATUS_FORBIDDEN;
            break;
        case 2:
            self->response.status_code = HTTP_STATUS_NOTFOUND;
            break;
        default:
            self->response.status_code = HTTP_STATUS_SERVERERROR;
            break;
        }
        return -1;
    }
    if (fstat(self->local_rfd, &st) == -1) {
        fprintf(stderr, "stat: %s" "\n", strerror((*__errno_location ())));
        self->response.status_code = HTTP_STATUS_SERVERERROR;
        goto err;
    }
    if (((((st.st_mode)) & 0170000) == (0040000)) || !((((st.st_mode)) & 0170000) == (0100000))) {
        fprintf(stderr, "not a regular file 0x%x" "\n", st.st_mode);
        self->response.status_code = HTTP_STATUS_FORBIDDEN;
        goto err;
    }
    self->response.last_mod = st.st_mtim.tv_sec;
    self->response.total_length = st.st_size;
    self->response.content_length = st.st_size;
    self->response.content_type = mimetype_get(path);
    self->response.content_from = 0;
    return 0;
err:
    do { close(self->local_rfd); self->local_rfd = -1; } while (0);
    return -1;
}

variable_types:
path
char *

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

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


decompiled_code:
__int64 __fastcall client_check_filemod(__int64 a1)
{
struct tm *v1; // rax
int v2; // eax
char v4[40]; // [rsp-28h] [rbp-28h] BYREF

if ( !*(_QWORD *)(a1 + 104) )
return 1LL;
v1 = gmtime((const time_t *)(a1 + 1248));
v2 = strftime(v4, 0x20uLL, "%a, %d %b %Y %H:%M:%S GMT", v1);
return (unsigned int)-(strncmp(*(const char **)(a1 + 104), v4, v2) != 0);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
struct tm *v1; // rax
int v2; // eax
char v4[40]; // [rsp-28h] [rbp-28h] BYREF

if ( !*(_QWORD *)(a1 + 104) )
return 1LL;
v1 = gmtime((const time_t *)(a1 + 1248));
v2 = strftime(v4, 0x20uLL, "%a, %d %b %Y %H:%M:%S GMT", v1);
return (unsigned int)-(strncmp(*(const char **)(a1 + 104), v4, v2) != 0);
}

original_code:
static
int client_check_filemod(struct client_t *self) {
    char date[32];
    int len;
    if (self->request.header[HEADER_IFMODIFIEDSINCE] == ((void *)0)) {
        return 1;
    }
    len = strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S GMT",
            gmtime(&self->response.last_mod));
    if (strncmp(self->request.header[HEADER_IFMODIFIEDSINCE], date, len) == 0) {
        return 0;
    }
    return -1;
}

variable_types:
date
char [32]

variable_types: len int


original_code:
static
int client_check_filerange(struct client_t *self) {
    off_t pos;
    if (self->request.range_from != ((void *)0)) {
        self->response.content_from = strtol(self->request.range_from, ((void *)0), 10);
        if (self->response.content_from >= self->response.content_length) {
            goto err;
        }
        if (self->request.range_to != ((void *)0)) {
            pos = strtol(self->request.range_to, ((void *)0), 10);
            if (pos < self->response.content_from) {
                goto err;
            }
            self->response.content_length = pos - self->response.content_from + 1;
        } else {
            self->response.content_length -= self->response.content_from - 1;
        }
    } else {
        if (self->request.range_to != ((void *)0)) {
            pos = strtol(self->request.range_to, ((void *)0), 10);
            if (pos >= self->response.content_length) {
                goto err;
            }
            self->response.content_from = self->response.content_length - pos;
            self->response.content_length = pos;
        } else {
            return 1;
        }
    }
    ;
    return 0;
err:
    self->response.status_code = HTTP_STATUS_RANGENOTSATISFIABLE;
    return -1;
}

canonical_original_code:
static int client_check_filerange(struct client_t *self) {
    long pos;
    if (self->request.range_from != ((void *)0)) {
        self->response.content_from = strtol(self->request.range_from, ((void *)0), 10);
        if (self->response.content_from >= self->response.content_length) {
            goto err;
        }
        if (self->request.range_to != ((void *)0)) {
            pos = strtol(self->request.range_to, ((void *)0), 10);
            if (pos < self->response.content_from) {
                goto err;
            }
            self->response.content_length = pos - self->response.content_from + 1;
        } else {
            self->response.content_length -= self->response.content_from - 1;
        }
    } else {
        if (self->request.range_to != ((void *)0)) {
            pos = strtol(self->request.range_to, ((void *)0), 10);
            if (pos >= self->response.content_length) {
                goto err;
            }
            self->response.content_from = self->response.content_length - pos;
            self->response.content_length = pos;
        } else {
            return 1;
        }
    }
    ;
    return 0;
err:
    self->response.status_code = HTTP_STATUS_RANGENOTSATISFIABLE;
    return -1;
}

variable_types: pos long


original_code:
static
int client_respond(struct client_t *self) {
    int len;
    char path[512];
    http_decode_url(self->request.url);
    http_sanitize_url(self->request.url);
    len = http_get_realpath(self->request.url, path);
    if (self->request.header[HEADER_CONNECTION] != ((void *)0)
            && strcmp("keep-alive", self->request.header[HEADER_CONNECTION]) == 0) {
        self->flags |= CLIENT_FLAG_KEEPALIVE;
    }
    if (client_open_file(self, path) != 0) {
        return -1;
    }
    if (client_check_filemod(self) == 0) {
        do { close(self->local_rfd); self->local_rfd = -1; } while (0);
        self->response.status_code = HTTP_STATUS_NOTMODIFIED;
        self->data_length = http_gen_header(&self->response, self->data,
                sizeof(self->data), HTTP_FLAG_END);
        self->state = STATE_SEND_HEADER;
        return 0;
    }
    len = client_check_filerange(self);
    if (len < 0) {
        do { close(self->local_rfd); self->local_rfd = -1; } while (0);
        return -1;
    }
    if (len == 0) {
        self->response.status_code = HTTP_STATUS_PARTIALCONTENT;
        self->data_length = http_gen_header(&self->response, self->data,
                sizeof(self->data), HTTP_FLAG_ACCEPT | HTTP_FLAG_CONTENT
                | HTTP_FLAG_RANGE | HTTP_FLAG_END);
        self->state = STATE_SEND_HEADER;
        return 0;
    }
    if (self->flags & CLIENT_FLAG_HEADERONLY) {
        do { close(self->local_rfd); self->local_rfd = -1; } while (0);
    }
    self->response.status_code = HTTP_STATUS_OK;
    self->data_length = http_gen_header(&self->response, self->data,
            sizeof(self->data), HTTP_FLAG_ACCEPT | HTTP_FLAG_CONTENT
            | HTTP_FLAG_END);
    self->state = STATE_SEND_HEADER;
    return 0;
}

variable_types:
path
char [512]


original_code:
void client_add(struct client_t *self, struct client_t **list) {
    if (*list == ((void *)0)) {
        self->next = ((void *)0);
    } else {
        self->next = *list;
        (*list)->prev = &self->next;
    }
    *list = self;
    self->prev = list;
}

variable_types:
list
struct client_t **


decompiled_code:
int __fastcall client_close(int *a1)
{
int v2; // edi
int result; // eax
int v4; // edi

v2 = *a1;
if ( v2 != -1 )
{
result = close(v2);
*a1 = -1;
}
v4 = a1[1];
if ( v4 != -1 )
{
result = close(v4);
a1[1] = -1;
}
return result;
}

canonical_decompiled_code:
int __fastcall func6(int *a1)
{
int v2; // edi
int result; // eax
int v4; // edi

v2 = *a1;
if ( v2 != -1 )
{
result = close(v2);
*a1 = -1;
}
v4 = a1[1];
if ( v4 != -1 )
{
result = close(v4);
a1[1] = -1;
}
return result;
}

original_code:
void client_close(struct client_t *self) {
    if (self->remote_fd != -1) {
        do { close(self->remote_fd); self->remote_fd = -1; } while (0);
    }
    if (self->local_rfd != -1) {
        do { close(self->local_rfd); self->local_rfd = -1; } while (0);
    }
}


original_code:
void client_reset(struct client_t *self) {
    self->data_length = 0;
    self->data_sent = 0;
    self->file_sent = 0;
    self->flags = 0;
    memset(&self->request, 0, sizeof(self->request));
    memset(&self->response, 0, sizeof(self->response));
}


decompiled_code:
__int64 __fastcall client_init(__int64 a1)
{
*(_QWORD *)a1 = -1LL;
*(_BYTE *)(a1 + 20) = 0;
*(_DWORD *)(a1 + 16) = 0;
return client_reset(a1);
}

original_code:
void client_init(struct client_t *self) {
    self->remote_fd = -1;
    self->local_rfd = -1;
    self->ip[0] = '\0';
    self->state = STATE_NONE;
    client_reset(self);
}


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

if ( (unsigned int)http_parse(a1 + 64, a1 + 168, *(unsigned int *)(a1 + 1192))
|| !*(_QWORD *)(a1 + 112)
|| !*(_QWORD *)(a1 + 120)
|| !*(_QWORD *)(a1 + 136) )
{
*(_DWORD *)(a1 + 1208) = 400;
goto LABEL_10;
}
if ( !strcmp(*(const char **)(a1 + 112), "GET") )
goto LABEL_13;
if ( !strcmp(*(const char **)(a1 + 112), "HEAD") )
{
*(_DWORD *)(a1 + 1264) |= 1u;
LABEL_13:
result = client_respond(a1);
goto LABEL_14;
}
if ( strcmp(*(const char **)(a1 + 112), "POST") )
{
*(_DWORD *)(a1 + 1208) = 501;
LABEL_10:
LODWORD(result) = http_gen_errorpage(a1 + 1208, a1 + 168, 1024LL);
*(_DWORD *)(a1 + 16) = 2;
result = (int)result;
*(_QWORD *)(a1 + 1192) = (int)result;
return result;
}
*(_DWORD *)(a1 + 1264) |= 2u;
result = client_respond(a1);
LABEL_14:
if ( (_DWORD)result )
goto LABEL_10;
return result;
}

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

if ( (unsigned int)http_parse(a1 + 64, a1 + 168, *(unsigned int *)(a1 + 1192))
|| !*(_QWORD *)(a1 + 112)
|| !*(_QWORD *)(a1 + 120)
|| !*(_QWORD *)(a1 + 136) )
{
*(_DWORD *)(a1 + 1208) = 400;
goto LABEL_10;
}
if ( !strcmp(*(const char **)(a1 + 112), "GET") )
goto LABEL_13;
if ( !strcmp(*(const char **)(a1 + 112), "HEAD") )
{
*(_DWORD *)(a1 + 1264) |= 1u;
LABEL_13:
result = func3(a1);
goto LABEL_14;
}
if ( strcmp(*(const char **)(a1 + 112), "POST") )
{
*(_DWORD *)(a1 + 1208) = 501;
LABEL_10:
LODWORD(result) = http_gen_errorpage(a1 + 1208, a1 + 168, 1024LL);
*(_DWORD *)(a1 + 16) = 2;
result = (int)result;
*(_QWORD *)(a1 + 1192) = (int)result;
return result;
}
*(_DWORD *)(a1 + 1264) |= 2u;
result = func3(a1);
LABEL_14:
if ( (_DWORD)result )
goto LABEL_10;
return result;
}

original_code:
void client_process(struct client_t *self) {
    int ret;
    if (http_parse(&self->request, self->data, self->data_length) != 0
            || self->request.method == ((void *)0) || self->request.url == ((void *)0)
            || self->request.version == ((void *)0)) {
        self->response.status_code = HTTP_STATUS_BADREQUEST;
        ret = -1;
    } else if (strcmp(self->request.method, "GET") == 0) {
        ret = client_respond(self);
    } else if (strcmp(self->request.method, "HEAD") == 0) {
        self->flags |= CLIENT_FLAG_HEADERONLY;
        ret = client_respond(self);
    } else if (strcmp(self->request.method, "POST") == 0) {
        self->flags |= CLIENT_FLAG_POST;
        ret = client_respond(self);
    } else {
        self->response.status_code = HTTP_STATUS_NOTIMPLEMENTED;
        ret = -1;
    }
    if (ret != 0) {
        self->data_length = http_gen_errorpage(&self->response, self->data,
                sizeof(self->data));
        self->state = STATE_SEND_HEADER;
    }
}

variable_types: ret int


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

if ( (unsigned __int8)(a1 - 48) <= 9u )
return (unsigned int)(char)(a1 - 48);
if ( (unsigned __int8)(a1 - 65) <= 5u )
return (unsigned int)(char)(a1 - 55);
result = (unsigned int)(char)(a1 - 87);
if ( (unsigned __int8)(a1 - 97) >= 6u )
result = 0LL;
return result;
}

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

if ( (unsigned __int8)(a1 - 48) <= 9u )
return (unsigned int)(char)(a1 - 48);
if ( (unsigned __int8)(a1 - 65) <= 5u )
return (unsigned int)(char)(a1 - 55);
result = (unsigned int)(char)(a1 - 87);
if ( (unsigned __int8)(a1 - 97) >= 6u )
result = 0LL;
return result;
}

original_code:
static
int hex_to_int(const char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    }
    if (c >= 'a' && c <= 'f') {
        return c - 'a' + 10;
    }
    return 0;
}

variable_types: c char


decompiled_code:
char *__fastcall http_parse_querystring(const char *a1)
{
char *result; // rax

result = strchr(a1, 63);
if ( result )
*result++ = 0;
return result;
}

canonical_decompiled_code:
char *__fastcall func1(const char *a1)
{
char *result; // rax

result = strchr(a1, 63);
if ( result )
*result++ = 0;
return result;
}

original_code:
static
char *http_parse_querystring(char *url) {
    char *p;
    p = strchr(url, '?');
    if (p == ((void *)0)) {
        return ((void *)0);
    }
    *p = '\0';
    return p + 1;
}

variable_types:
url
char *

variable_types:
p
char *

return_type: char *


decompiled_code:
int __fastcall http_parse_range(__int64 a1, const char *a2)
{
const char *v4; // r12
char *v5; // rax
char *v6; // rax

if ( !memcmp(a2, "bytes=", 6uLL) )
{
v4 = a2 + 6;
v5 = strchr(a2 + 6, 45);
if ( v5 )
{
if ( v4 == v5 )
{
*(_QWORD *)(a1 + 80) = 0LL;
}
else
{
*v5 = 0;
*(_QWORD *)(a1 + 80) = v4;
}
*(_QWORD *)(a1 + 88) = v5 + 1;
v6 = strchr(v5 + 1, 44);
if ( v6 )
*v6 = 0;
}
else
{
LODWORD(v6) = fprintf(stderr, "no hyphen: %s\n", v4);
}
}
else
{
LODWORD(v6) = fprintf(stderr, "ranges are not in bytes: %s\n", a2);
}
return (int)v6;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1, const char *a2)
{
const char *v4; // r12
char *v5; // rax
char *v6; // rax

if ( !memcmp(a2, "bytes=", 6uLL) )
{
v4 = a2 + 6;
v5 = strchr(a2 + 6, 45);
if ( v5 )
{
if ( v4 == v5 )
{
*(_QWORD *)(a1 + 80) = 0LL;
}
else
{
*v5 = 0;
*(_QWORD *)(a1 + 80) = v4;
}
*(_QWORD *)(a1 + 88) = v5 + 1;
v6 = strchr(v5 + 1, 44);
if ( v6 )
*v6 = 0;
}
else
{
LODWORD(v6) = fprintf(stderr, "no hyphen: %s\n", v4);
}
}
else
{
LODWORD(v6) = fprintf(stderr, "ranges are not in bytes: %s\n", a2);
}
return (int)v6;
}

original_code:
static
void http_parse_range(struct request_t *self, char *val) {
    char *delim;
    if (strncmp(val, "bytes=", 6) != 0) {
        fprintf(stderr, "ranges are not in bytes: %s" "\n", val);
        return;
    }
    val += 6;
    delim = strchr(val, '-');
    if (delim == ((void *)0)) {
        fprintf(stderr, "no hyphen: %s" "\n", val);
        return;
    }
    if (delim == val) {
        self->range_from = ((void *)0);
    } else {
        *delim = '\0';
        self->range_from = val;
    }
    self->range_to = delim + 1;
    delim = strchr(self->range_to, ',');
    if (delim != ((void *)0)) {
        *delim = '\0';
    }
}

variable_types: struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; } *

variable_types:
val
char *

variable_types:
delim
char *


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

v4 = 0LL;
result = strcasecmp(a2, "Connection");
if ( result )
{
while ( ++v4 != 6 )
{
result = strcasecmp(a2, HTTP_REQUEST_HEADERS[v4]);
if ( !result )
goto LABEL_4;
}
}
else
{
LABEL_4:
result = v4;
*(_QWORD *)(a1 + 8LL * (int)v4) = a3;
if ( (_DWORD)v4 == 2 )
result = http_parse_range(a1, a3);
}
return result;
}

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

v4 = 0LL;
result = strcasecmp(a2, "Connection");
if ( result )
{
while ( ++v4 != 6 )
{
result = strcasecmp(a2, HTTP_REQUEST_HEADERS[v4]);
if ( !result )
goto LABEL_4;
}
}
else
{
LABEL_4:
result = v4;
*(_QWORD *)(a1 + 8LL * (int)v4) = a3;
if ( (_DWORD)v4 == 2 )
result = func2(a1, a3);
}
return result;
}

original_code:
static
void http_save_header(struct request_t *self, char *key, char *val) {
    int i;
    for (i = 0; i < NUM_REQUEST_HEADER; ++i) {
        if (strcasecmp(key, HTTP_REQUEST_HEADERS[i]) == 0) {
            self->header[i] = val;
            break;
        }
    }
    if (i == HEADER_CONTENTRANGE) {
        http_parse_range(self, val);
    }
}

variable_types:
key
char *

variable_types: i int


decompiled_code:
int __fastcall http_put_headerrange(_QWORD *a1, char *a2, int a3)
{
return snprintf(a2, a3, "Content-Range: bytes %ld-%ld/%ld\r\n", a1[4], a1[4] + a1[3] - 1LL, a1[2]);
}

canonical_decompiled_code:
int __fastcall func4(_QWORD *a1, char *a2, int a3)
{
return snprintf(a2, a3, "Content-Range: bytes %ld-%ld/%ld\r\n", a1[4], a1[4] + a1[3] - 1LL, a1[2]);
}

original_code:
static
int http_put_headerrange(struct response_t *self, char *data, int sz) {
    off_t to;
    to = self->content_from + self->content_length - 1;
    return snprintf(data, sz, "Content-Range: bytes %ld-%ld/%ld\r\n",
            self->content_from, to, self->total_length);
}

canonical_original_code:
static int http_put_headerrange(struct response_t *self, char *data, int sz) {
    long to;
    to = self->content_from + self->content_length - 1;
    return snprintf(data, sz, "Content-Range: bytes %ld-%ld/%ld\r\n",
            self->content_from, to, self->total_length);
}

variable_types: struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; } *

variable_types:
data
char *

variable_types: sz int

variable_types: to long


decompiled_code:
__int64 __fastcall http_put_headercontent(__int64 a1, char *a2, int a3)
{
unsigned int v3; // er12
int v4; // ebx
__int64 v5; // rcx
const char *v6; // rcx
int v7; // eax
int v9; // eax
struct tm *v10; // rax
int v11; // eax

v3 = 0;
v4 = a3;
v5 = *(_QWORD *)(a1 + 24);
if ( v5 >= 0 )
{
v9 = snprintf(a2, a3, "Content-Length: %ld\r\n", v5);
v3 = v9;
if ( v4 <= v9 )
return (unsigned int)-1;
v4 -= v9;
}
v6 = *(const char **)(a1 + 8);
if ( v6 )
{
v7 = snprintf(&a2[v3], v4, "Content-Type: %s\r\n", v6);
if ( v7 < 0 || v4 <= v7 )
return (unsigned int)-1;
v4 -= v7;
v3 += v7;
}
if ( *(__int64 *)(a1 + 40) < 0 )
return v3;
v10 = gmtime((const time_t *)(a1 + 40));
v11 = strftime(&a2[v3], v4, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", v10);
if ( v11 < 0 || v4 <= v11 )
return (unsigned int)-1;
return v11 + v3;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, char *a2, int a3)
{
unsigned int v3; // er12
int v4; // ebx
__int64 v5; // rcx
const char *v6; // rcx
int v7; // eax
int v9; // eax
struct tm *v10; // rax
int v11; // eax

v3 = 0;
v4 = a3;
v5 = *(_QWORD *)(a1 + 24);
if ( v5 >= 0 )
{
v9 = snprintf(a2, a3, "Content-Length: %ld\r\n", v5);
v3 = v9;
if ( v4 <= v9 )
return (unsigned int)-1;
v4 -= v9;
}
v6 = *(const char **)(a1 + 8);
if ( v6 )
{
v7 = snprintf(&a2[v3], v4, "Content-Type: %s\r\n", v6);
if ( v7 < 0 || v4 <= v7 )
return (unsigned int)-1;
v4 -= v7;
v3 += v7;
}
if ( *(__int64 *)(a1 + 40) < 0 )
return v3;
v10 = gmtime((const time_t *)(a1 + 40));
v11 = strftime(&a2[v3], v4, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", v10);
if ( v11 < 0 || v4 <= v11 )
return (unsigned int)-1;
return v11 + v3;
}

original_code:
static
int http_put_headercontent(struct response_t *self, char *data, int sz) {
    int len, i;
    len = 0;
    if (self->content_length >= 0) {
        i = snprintf(data, sz, "Content-Length: %ld\r\n",
                self->content_length);
        if (i < 0 || i >= sz) {
            return -1;
        }
        sz -= i;
        len += i;
    }
    if (self->content_type != ((void *)0)) {
        i = snprintf(data + len, sz, "Content-Type: %s\r\n",
                self->content_type);
        if (i < 0 || i >= sz) {
            return -1;
        }
        sz -= i;
        len += i;
    }
    if (self->last_mod >= 0) {
        i = strftime(data + len, sz, "Last-Modified: " "%a, %d %b %Y %H:%M:%S GMT" "\r\n",
                gmtime(&self->last_mod));
        if (i < 0 || i >= sz) {
            return -1;
        }
        sz -= i;
        len += i;
    }
    return len;
}

canonical_original_code:
static int http_put_headercontent(struct response_t *self, char *data, int sz) {
    int len; int i;
    len = 0;
    if (self->content_length >= 0) {
        i = snprintf(data, sz, "Content-Length: %ld\r\n",
                self->content_length);
        if (i < 0 || i >= sz) {
            return -1;
        }
        sz -= i;
        len += i;
    }
    if (self->content_type != ((void *)0)) {
        i = snprintf(data + len, sz, "Content-Type: %s\r\n",
                self->content_type);
        if (i < 0 || i >= sz) {
            return -1;
        }
        sz -= i;
        len += i;
    }
    if (self->last_mod >= 0) {
        i = strftime(data + len, sz, "Last-Modified: " "%a, %d %b %Y %H:%M:%S GMT" "\r\n",
                gmtime(&self->last_mod));
        if (i < 0 || i >= sz) {
            return -1;
        }
        sz -= i;
        len += i;
    }
    return len;
}

variable_types: len int


decompiled_code:
__int64 __fastcall http_parse(_QWORD *a1, const void *a2, unsigned int a3)
{
_BYTE *v4; // rax
_BYTE *v5; // r12
signed int v6; // ebx
_BYTE *v7; // rax

v4 = http_parse_request(a1, a2, a3);
if ( !v4 )
return 0xFFFFFFFFLL;
v5 = v4;
v6 = a3 - ((_DWORD)v4 - (_DWORD)a2);
if ( v6 > 0 )
{
while ( *v5 != 10 && (v6 == 1 || *v5 != 13 || v5[1] != 10) )
{
v7 = http_parse_header((__int64)a1, v5, v6);
if ( !v7 )
return 0xFFFFFFFFLL;
v6 -= (_DWORD)v7 - (_DWORD)v5;
if ( v6 <= 0 )
break;
v5 = v7;
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func8(_QWORD *a1, const void *a2, unsigned int a3)
{
_BYTE *v4; // rax
_BYTE *v5; // r12
signed int v6; // ebx
_BYTE *v7; // rax

v4 = http_parse_request(a1, a2, a3);
if ( !v4 )
return 0xFFFFFFFFLL;
v5 = v4;
v6 = a3 - ((_DWORD)v4 - (_DWORD)a2);
if ( v6 > 0 )
{
while ( *v5 != 10 && (v6 == 1 || *v5 != 13 || v5[1] != 10) )
{
v7 = http_parse_header((__int64)a1, v5, v6);
if ( !v7 )
return 0xFFFFFFFFLL;
v6 -= (_DWORD)v7 - (_DWORD)v5;
if ( v6 <= 0 )
break;
v5 = v7;
}
}
return 0LL;
}

original_code:
int http_parse(struct request_t *self, char *data, int len) {
    char *p;
    p = http_parse_request(self, data, len);
    if (p == ((void *)0)) {
        return -1;
    }
    len -= p - data;
    data = p;
    while ((len > 0) && !((data[0] == '\n')
            || (len >= 2 && data[0] == '\r' && data[1] == '\n'))) {
        p = http_parse_header(self, data, len);
        if (p == ((void *)0)) {
            return -1;
        }
        len -= p - data;
        data = p;
    }
    return 0;
}


decompiled_code:
__int64 __fastcall http_decode_url(unsigned __int8 *a1)
{
__int64 result; // rax
_BYTE *v2; // rsi
unsigned __int8 *v3; // r8
char v4; // r9
char v5; // al
char v6; // cl

result = *a1;
v2 = a1;
if ( (_BYTE)result )
{
v3 = a1;
do
{
while ( 1 )
{
++v2;
if ( (_BYTE)result == 37 && v3[1] && v3[2] )
break;
++v3;
*(v2 - 1) = result;
result = *v3;
if ( !(_BYTE)result )
goto LABEL_8;
}
hex_to_int(v3[1]);
v5 = hex_to_int(v4);
*(v2 - 1) = 16 * v6 + v5;
result = *v3;
}
while ( (_BYTE)result );
}
LABEL_8:
*v2 = 0;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned __int8 *a1)
{
__int64 result; // rax
_BYTE *v2; // rsi
unsigned __int8 *v3; // r8
char v4; // r9
char v5; // al
char v6; // cl

result = *a1;
v2 = a1;
if ( (_BYTE)result )
{
v3 = a1;
do
{
while ( 1 )
{
++v2;
if ( (_BYTE)result == 37 && v3[1] && v3[2] )
break;
++v3;
*(v2 - 1) = result;
result = *v3;
if ( !(_BYTE)result )
goto LABEL_8;
}
func0(v3[1]);
v5 = func0(v4);
*(v2 - 1) = 16 * v6 + v5;
result = *v3;
}
while ( (_BYTE)result );
}
LABEL_8:
*v2 = 0;
return result;
}

variable_types:
out
char *


decompiled_code:
__int64 __fastcall http_sanitize_url(unsigned __int8 *a1)
{
__int64 result; // rax
unsigned __int8 *v2; // rdx

result = *a1;
v2 = a1;
while ( (_BYTE)result )
{
if ( (_BYTE)result == 47 )
{
if ( a1 != v2 )
*v2 = 47;
for ( result = *++a1; (_BYTE)result == 46; ++a1 )
result = a1[1];
++v2;
}
else
{
if ( a1 != v2 )
*v2 = result;
result = a1[1];
++v2;
++a1;
}
}
if ( a1 != v2 )
*v2 = 0;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned __int8 *a1)
{
__int64 result; // rax
unsigned __int8 *v2; // rdx

result = *a1;
v2 = a1;
while ( (_BYTE)result )
{
if ( (_BYTE)result == 47 )
{
if ( a1 != v2 )
*v2 = 47;
for ( result = *++a1; (_BYTE)result == 46; ++a1 )
result = a1[1];
++v2;
}
else
{
if ( a1 != v2 )
*v2 = result;
result = a1[1];
++v2;
++a1;
}
}
if ( a1 != v2 )
*v2 = 0;
return result;
}

original_code:
void http_sanitize_url(char *url) {
    char *out;
    char c;
    out = url;
    for (;;) {
        c = *url;
        switch (c) {
        case '/':
            if (out != url) {
                *out = c;
            }
            ++out;
            ++url;
            while ('.' == *url) {
                ++url;
            }
            break;
        case '\0':
            if (out != url) {
                *out = c;
            }
            return;
        default:
            if (out != url) {
                *out = c;
            }
            ++out;
            ++url;
            break;
        }
    }
}


decompiled_code:
__int64 __fastcall http_get_realpath(const char *a1, char *a2)
{
__int64 result; // rax
int v3; // er12

LODWORD(result) = snprintf(a2, 0x200uLL, "%s%s", g_config, a1);
if ( (int)result > 511 )
LODWORD(result) = 511;
if ( a2[(int)result - 1] != 47 )
return (unsigned int)result;
v3 = result + 10;
snprintf(&a2[(int)result], 512 - (int)result, "%s", "index.html");
if ( v3 > 511 )
v3 = 511;
return (unsigned int)v3;
}

canonical_decompiled_code:
__int64 __fastcall func11(const char *a1, char *a2)
{
__int64 result; // rax
int v3; // er12

LODWORD(result) = snprintf(a2, 0x200uLL, "%s%s", g_config, a1);
if ( (int)result > 511 )
LODWORD(result) = 511;
if ( a2[(int)result - 1] != 47 )
return (unsigned int)result;
v3 = result + 10;
snprintf(&a2[(int)result], 512 - (int)result, "%s", "index.html");
if ( v3 > 511 )
v3 = 511;
return (unsigned int)v3;
}

original_code:
int http_get_realpath(const char *url, char *path) {
    int len;
    len = snprintf(path, 512, "%s%s", g_config.root, url);
    if (len >= 512) {
        len = 512 - 1;
    }
    if (path[len - 1] == '/') {
        len += snprintf(path + len, 512 - len, "%s", "index.html");
        if (len >= 512) {
            len = 512 - 1;
        }
    }
    return len;
}

canonical_original_code:
int http_get_realpath(char *url, char *path) {
    int len;
    len = snprintf(path, 512, "%s%s", g_config.root, url);
    if (len >= 512) {
        len = 512 - 1;
    }
    if (path[len - 1] == '/') {
        len += snprintf(path + len, 512 - len, "%s", "index.html");
        if (len >= 512) {
            len = 512 - 1;
        }
    }
    return len;
}

variable_types:
path
char *


decompiled_code:
__int64 __fastcall http_find_headerlength(const void *a1, int a2)
{
int v2; // edx
int v3; // ebx
char *v4; // rax
int v5; // edx

v2 = 0;
v3 = (int)a1;
while ( 1 )
{
v4 = (char *)memchr(a1, 10, a2 - v2);
if ( !v4 )
return 0xFFFFFFFFLL;
v5 = (_DWORD)v4 - v3;
if ( (int)v4 - v3 > 0 && a2 - 2 > v5 && *(v4 - 1) == 13 && v4[1] == 13 )
{
if ( v4[2] == 10 )
return (unsigned int)(v5 + 3);
goto LABEL_4;
}
if ( a2 > v5 && v4[1] == 10 )
return (unsigned int)((_DWORD)v4 - v3 + 2);
LABEL_4:
v2 = v5 + 1;
a1 = v4 + 1;
if ( a2 <= v2 )
return 0xFFFFFFFFLL;
}
}

canonical_decompiled_code:
__int64 __fastcall func12(const void *a1, int a2)
{
int v2; // edx
int v3; // ebx
char *v4; // rax
int v5; // edx

v2 = 0;
v3 = (int)a1;
while ( 1 )
{
v4 = (char *)memchr(a1, 10, a2 - v2);
if ( !v4 )
return 0xFFFFFFFFLL;
v5 = (_DWORD)v4 - v3;
if ( (int)v4 - v3 > 0 && a2 - 2 > v5 && *(v4 - 1) == 13 && v4[1] == 13 )
{
if ( v4[2] == 10 )
return (unsigned int)(v5 + 3);
goto LABEL_4;
}
if ( a2 > v5 && v4[1] == 10 )
return (unsigned int)((_DWORD)v4 - v3 + 2);
LABEL_4:
v2 = v5 + 1;
a1 = v4 + 1;
if ( a2 <= v2 )
return 0xFFFFFFFFLL;
}
}

original_code:
int http_find_headerlength(const char *data, int len) {
    int sz = 0;
    const char *crlf = data;
    for (;;) {
        crlf = memchr(crlf, '\n', len - sz);
        if (crlf == ((void *)0)) {
            break;
        }
        sz = crlf - data;
        if (sz > 0 && sz <= (len - 3) && *(crlf - 1) == '\r'
                && *(crlf + 1) == '\r' && *(crlf + 2) == '\n') {
            return sz + 3;
        }
        if (sz <= (len - 1) && *(crlf + 1) == '\n') {
            return sz + 2;
        }
        ++crlf;
        ++sz;
        if (sz >= len) {
            break;
        }
    }
    return -1;
}

canonical_original_code:
int http_find_headerlength(char *data, int len) {
    int sz = 0;
    char *crlf = data;
    for (;;) {
        crlf = memchr(crlf, '\n', len - sz);
        if (crlf == ((void *)0)) {
            break;
        }
        sz = crlf - data;
        if (sz > 0 && sz <= (len - 3) && *(crlf - 1) == '\r'
                && *(crlf + 1) == '\r' && *(crlf + 2) == '\n') {
            return sz + 3;
        }
        if (sz <= (len - 1) && *(crlf + 1) == '\n') {
            return sz + 2;
        }
        ++crlf;
        ++sz;
        if (sz >= len) {
            break;
        }
    }
    return -1;
}

variable_types:
crlf
char *


decompiled_code:
const char *__fastcall http_string_status(int a1)
{
const char *result; // rax
__int64 v2; // rax

if ( a1 > 299 )
{
if ( a1 > 399 )
{
if ( a1 <= 499 )
{
switch ( a1 )
{
case 400:
result = "Bad Request";
break;
case 401:
result = "Authorization Required";
break;
case 403:
result = "Forbidden";
break;
case 404:
result = "Not Found";
break;
case 413:
result = "Request Entity Too Large";
break;
case 416:
result = "Requested Range Not Satisfiable";
break;
default:
goto LABEL_4;
}
}
else
{
result = "Server Error";
if ( a1 != 500 )
{
result = "Not Implemented";
if ( a1 != 501 )
goto LABEL_4;
}
}
}
else
{
v2 = (unsigned int)(a1 - 301);
if ( (unsigned int)v2 > 3 )
{
LABEL_4:
fprintf(stderr, "unknown code %d\n", (unsigned int)a1);
return "Unknown";
}
result = CSWTCH_36[v2];
}
}
else
{
result = "OK";
if ( a1 != 200 )
{
result = "Partial Content";
if ( a1 != 206 )
goto LABEL_4;
}
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func13(int a1)
{
const char *result; // rax
__int64 v2; // rax

if ( a1 > 299 )
{
if ( a1 > 399 )
{
if ( a1 <= 499 )
{
switch ( a1 )
{
case 400:
result = "Bad Request";
break;
case 401:
result = "Authorization Required";
break;
case 403:
result = "Forbidden";
break;
case 404:
result = "Not Found";
break;
case 413:
result = "Request Entity Too Large";
break;
case 416:
result = "Requested Range Not Satisfiable";
break;
default:
goto LABEL_4;
}
}
else
{
result = "Server Error";
if ( a1 != 500 )
{
result = "Not Implemented";
if ( a1 != 501 )
goto LABEL_4;
}
}
}
else
{
v2 = (unsigned int)(a1 - 301);
if ( (unsigned int)v2 > 3 )
{
LABEL_4:
fprintf(stderr, "unknown code %d\n", (unsigned int)a1);
return "Unknown";
}
result = CSWTCH_36[v2];
}
}
else
{
result = "OK";
if ( a1 != 200 )
{
result = "Partial Content";
if ( a1 != 206 )
goto LABEL_4;
}
}
return result;
}

original_code:
const char *http_string_status(int code) {
    if (code < 300) {
        switch (code) {
        case HTTP_STATUS_OK:
            return "OK";
        case HTTP_STATUS_PARTIALCONTENT:
            return "Partial Content";
        }
    } else if (code < 400) {
        switch (code) {
        case HTTP_STATUS_MOVEDPERMANENTLY:
            return "Moved Permanently";
        case 302:
            return "Moved Temporarily ";
        case 303:
            return "See Other";
        case HTTP_STATUS_NOTMODIFIED:
            return "Not Modified";
        }
    } else if (code < 500) {
        switch (code) {
        case HTTP_STATUS_BADREQUEST:
            return "Bad Request";
        case HTTP_STATUS_AUTHORIZATIONREQUIRED:
            return "Authorization Required";
        case HTTP_STATUS_FORBIDDEN:
            return "Forbidden";
        case HTTP_STATUS_NOTFOUND:
            return "Not Found";
        case HTTP_STATUS_ENTITYTOOLARGE:
            return "Request Entity Too Large";
        case HTTP_STATUS_RANGENOTSATISFIABLE:
            return "Requested Range Not Satisfiable";
        }
    } else {
        switch (code) {
        case HTTP_STATUS_SERVERERROR:
            return "Server Error";
        case HTTP_STATUS_NOTIMPLEMENTED:
            return "Not Implemented";
        }
    }
    fprintf(stderr, "unknown code %d" "\n", code);
    return "Unknown";
}

variable_types: code int


decompiled_code:
int __fastcall http_put_headerstatus(int *a1, char *a2, int a3)
{
const char *v4; // rax

v4 = http_string_status(*a1);
return snprintf(a2, a3, "HTTP/1.1 %d %s\r\nServer: Aranea/0.1\r\n", (unsigned int)*a1, v4);
}

canonical_decompiled_code:
int __fastcall func14(int *a1, char *a2, int a3)
{
const char *v4; // rax

v4 = func13(*a1);
return snprintf(a2, a3, "HTTP/1.1 %d %s\r\nServer: Aranea/0.1\r\n", (unsigned int)*a1, v4);
}

original_code:
static
int http_put_headerstatus(struct response_t *self, char *data, int sz) {
    return snprintf(data, sz,
            "HTTP/1.1" " %d %s\r\n"
            "Server: " "Aranea" "/" "0.1" "\r\n",
            self->status_code, http_string_status(self->status_code));
}


decompiled_code:
__int64 __fastcall http_gen_header(int *a1, char *a2, int a3, char a4)
{
int v6; // eax
unsigned int v7; // er12
int v8; // ebx
unsigned int v10; // eax
int v11; // eax
int v12; // eax
int v13; // eax

v6 = http_put_headerstatus(a1, a2, a3);
if ( v6 < 0 )
return (unsigned int)-1;
v7 = v6;
if ( a3 <= v6 )
return (unsigned int)-1;
v8 = a3 - v6;
if ( (a4 & 0x10) != 0 )
{
v10 = http_put_headerdate_constprop_0(&a2[v6], v8);
if ( v8 <= v10 )
return (unsigned int)-1;
v8 -= v10;
v7 += v10;
if ( (a4 & 2) == 0 )
{
LABEL_5:
if ( (a4 & 4) == 0 )
goto LABEL_6;
LABEL_14:
v12 = http_put_headercontent((__int64)a1, &a2[v7], v8);
if ( v12 < 0 || v8 <= v12 )
return (unsigned int)-1;
v8 -= v12;
v7 += v12;
if ( (a4 & 8) == 0 )
goto LABEL_7;
goto LABEL_17;
}
}
else if ( (a4 & 2) == 0 )
{
goto LABEL_5;
}
v11 = http_put_headeraccept_constprop_0(&a2[v7], v8);
if ( v11 < 0 || v8 <= v11 )
return (unsigned int)-1;
v8 -= v11;
v7 += v11;
if ( (a4 & 4) != 0 )
goto LABEL_14;
LABEL_6:
if ( (a4 & 8) == 0 )
{
LABEL_7:
if ( (a4 & 1) == 0 )
return v7;
goto LABEL_20;
}
LABEL_17:
v13 = http_put_headerrange(a1, &a2[v7], v8);
if ( v13 < 0 || v8 <= v13 )
return (unsigned int)-1;
v8 -= v13;
v7 += v13;
if ( (a4 & 1) == 0 )
return v7;
LABEL_20:
snprintf(&a2[v7], v8, "\r\n");
if ( v8 <= 2 )
return (unsigned int)-1;
return v7 + 2;
}

canonical_decompiled_code:
__int64 __fastcall func15(int *a1, char *a2, int a3, char a4)
{
int v6; // eax
unsigned int v7; // er12
int v8; // ebx
unsigned int v10; // eax
int v11; // eax
int v12; // eax
int v13; // eax

v6 = func14(a1, a2, a3);
if ( v6 < 0 )
return (unsigned int)-1;
v7 = v6;
if ( a3 <= v6 )
return (unsigned int)-1;
v8 = a3 - v6;
if ( (a4 & 0x10) != 0 )
{
v10 = func7(&a2[v6], v8);
if ( v8 <= v10 )
return (unsigned int)-1;
v8 -= v10;
v7 += v10;
if ( (a4 & 2) == 0 )
{
LABEL_5:
if ( (a4 & 4) == 0 )
goto LABEL_6;
LABEL_14:
v12 = func5((__int64)a1, &a2[v7], v8);
if ( v12 < 0 || v8 <= v12 )
return (unsigned int)-1;
v8 -= v12;
v7 += v12;
if ( (a4 & 8) == 0 )
goto LABEL_7;
goto LABEL_17;
}
}
else if ( (a4 & 2) == 0 )
{
goto LABEL_5;
}
v11 = func6(&a2[v7], v8);
if ( v11 < 0 || v8 <= v11 )
return (unsigned int)-1;
v8 -= v11;
v7 += v11;
if ( (a4 & 4) != 0 )
goto LABEL_14;
LABEL_6:
if ( (a4 & 8) == 0 )
{
LABEL_7:
if ( (a4 & 1) == 0 )
return v7;
goto LABEL_20;
}
LABEL_17:
v13 = func4(a1, &a2[v7], v8);
if ( v13 < 0 || v8 <= v13 )
return (unsigned int)-1;
v8 -= v13;
v7 += v13;
if ( (a4 & 1) == 0 )
return v7;
LABEL_20:
snprintf(&a2[v7], v8, "\r\n");
if ( v8 <= 2 )
return (unsigned int)-1;
return v7 + 2;
}

original_code:
int http_gen_header(struct response_t *self, char *data, int sz,
        const unsigned int flags) {
    int len, i;
    len = http_put_headerstatus(self, data, sz);
    if (len < 0 || len >= sz) {
        return -1;
    }
    sz -= len;
    do { if (flags & HTTP_FLAG_DATE) { i = http_put_headerdate(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    do { if (flags & HTTP_FLAG_ACCEPT) { i = http_put_headeraccept(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    do { if (flags & HTTP_FLAG_CONTENT) { i = http_put_headercontent(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    do { if (flags & HTTP_FLAG_RANGE) { i = http_put_headerrange(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    if (flags & HTTP_FLAG_END) {
        i = snprintf(data + len, sz, "\r\n");
        if (i < 0 || i >= sz) {
            return -1;
        }
        len += i;
    }
    return len;
}

canonical_original_code:
int http_gen_header(struct response_t *self, char *data, int sz, unsigned int flags) {
    int len; int i;
    len = http_put_headerstatus(self, data, sz);
    if (len < 0 || len >= sz) {
        return -1;
    }
    sz -= len;
    do { if (flags & HTTP_FLAG_DATE) { i = http_put_headerdate(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    do { if (flags & HTTP_FLAG_ACCEPT) { i = http_put_headeraccept(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    do { if (flags & HTTP_FLAG_CONTENT) { i = http_put_headercontent(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    do { if (flags & HTTP_FLAG_RANGE) { i = http_put_headerrange(self, data + len, sz); if (i < 0 || i >= sz) { return -1; } sz -= i; len += i; } } while (0);
    if (flags & HTTP_FLAG_END) {
        i = snprintf(data + len, sz, "\r\n");
        if (i < 0 || i >= sz) {
            return -1;
        }
        len += i;
    }
    return len;
}

variable_types:
flags
unsigned int


decompiled_code:
__int64 __fastcall http_gen_errorpage(unsigned int *a1, char *a2, int a3)
{
int v4; // eax
int v5; // ebp
int v6; // ebx
int v7; // ebp
int v8; // ebx
const char *v9; // rax
int v10; // eax
__int64 result; // rax

v4 = http_put_headerstatus((int *)a1, a2, a3);
if ( v4 < 0
|| (v5 = v4, a3 <= v4)
|| (v6 = a3 - v4, snprintf(&a2[v4], v6, "Content-Type: text/html\r\n\r\n"), v6 <= 27)
|| (v7 = v5 + 27,
v8 = v6 - 27,
v9 = http_string_status(*a1),
v10 = snprintf(
&a2[v7],
v8,
"<title>%d</title>
%d %s

Aranea/0.1",
*a1,
*a1,
v9),
v10 < 0)
|| v8 <= v10 )
{
result = 0xFFFFFFFFLL;
}
else
{
result = (unsigned int)(v7 + v10);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(unsigned int *a1, char *a2, int a3)
{
int v4; // eax
int v5; // ebp
int v6; // ebx
int v7; // ebp
int v8; // ebx
const char *v9; // rax
int v10; // eax
__int64 result; // rax

v4 = func14((int *)a1, a2, a3);
if ( v4 < 0
|| (v5 = v4, a3 <= v4)
|| (v6 = a3 - v4, snprintf(&a2[v4], v6, "Content-Type: text/html\r\n\r\n"), v6 <= 27)
|| (v7 = v5 + 27,
v8 = v6 - 27,
v9 = func13(*a1),
v10 = snprintf(
&a2[v7],
v8,
"<title>%d</title>
%d %s

Aranea/0.1",
*a1,
*a1,
v9),
v10 < 0)
|| v8 <= v10 )
{
result = 0xFFFFFFFFLL;
}
else
{
result = (unsigned int)(v7 + v10);
}
return result;
}

original_code:
int http_gen_errorpage(struct response_t *self, char *data, int sz) {
    int len, i;
    len = http_put_headerstatus(self, data, sz);
    if (len < 0 || len >= sz) {
        return -1;
    }
    sz -= len;
    i = snprintf(data + len, sz,
            "Content-Type: text/html\r\n\r\n");
    if (i < 0 || i >= sz) {
        return -1;
    }
    sz -= i;
    len += i;
    i = snprintf(data + len, sz,
            "<title>%d</title>"
            "
%d %s

" "Aranea" "/" "0.1"
            "",
            self->status_code, self->status_code,
            http_string_status(self->status_code));
    if (i < 0 || i >= sz) {
        return -1;
    }
    return len + i;
}

canonical_original_code:
int http_gen_errorpage(struct response_t *self, char *data, int sz) {
    int len; int i;
    len = http_put_headerstatus(self, data, sz);
    if (len < 0 || len >= sz) {
        return -1;
    }
    sz -= len;
    i = snprintf(data + len, sz,
            "Content-Type: text/html\r\n\r\n");
    if (i < 0 || i >= sz) {
        return -1;
    }
    sz -= i;
    len += i;
    i = snprintf(data + len, sz,
            "<title>%d</title>"
            "
%d %s

" "Aranea" "/" "0.1"
            "",
            self->status_code, self->status_code,
            http_string_status(self->status_code));
    if (i < 0 || i >= sz) {
        return -1;
    }
    return len + i;
}


decompiled_code:
__int64 __fastcall forget_client(__int64 a1)
{
client_close();
client_detach(a1);
return clientpool_free(a1);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
client_close();
client_detach(a1);
return clientpool_free(a1);
}

original_code:
static
void forget_client(struct client_t *c) {
    client_close(c);
    client_detach(c);
    clientpool_free(c);
}

variable_types: struct client_t { int remote_fd; int local_rfd; long timeout; int state; char ip[40]; struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; } request; char data[1024]; long data_length; long data_sent; struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; } response; long file_sent; unsigned int flags; struct client_t *next; struct client_t **prev; } *


decompiled_code:
__int64 __fastcall server_init(__int64 a1)
{
const char *v1; // rsi
int v2; // eax
unsigned int v3; // er12
struct addrinfo *v4; // rbx
int v5; // eax
int v6; // ebp
int *v8; // rax
char *v9; // rax
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
int *v14; // rax
char *v15; // rax
const char *v16; // rax
int *v17; // rax
char *v18; // rax
int optval; // [rsp+0h] [rbp-64h] BYREF
struct addrinfo *pai; // [rsp+4h] [rbp-60h] BYREF
struct addrinfo req; // [rsp+Ch] [rbp-58h] BYREF

v1 = *(const char **)(a1 + 8);
*(_OWORD *)&req.ai_flags = 0LL;
optval = 1;
req.ai_socktype = 1;
req.ai_flags = 1;
*(_OWORD *)&req.ai_addrlen = 0LL;
*(_OWORD *)&req.ai_canonname = 0LL;
v2 = getaddrinfo(0LL, v1, &req, &pai);
v3 = v2;
if ( v2 )
{
v3 = -1;
v16 = gai_strerror(v2);
fprintf(stderr, "getaddrinfo: %s\n\n", v16);
return v3;
}
v4 = pai;
if ( !pai )
{
LABEL_11:
v10 = _errno_location();
v3 = -1;
v11 = strerror(*v10);
fprintf(stderr, "bind: %s\n", v11);
return v3;
}
while ( 1 )
{
v5 = socket(v4->ai_family, v4->ai_socktype, v4->ai_protocol);
v6 = v5;
if ( v5 != -1 )
break;
v8 = _errno_location();
v9 = strerror(*v8);
fprintf(stderr, "socket: %s\n", v9);
LABEL_10:
v4 = v4->ai_next;
if ( !v4 )
goto LABEL_11;
}
if ( setsockopt(v5, 1, 2, &optval, 4u) == -1 )
{
v3 = -1;
close(v6);
v14 = _errno_location();
v15 = strerror(*v14);
fprintf(stderr, "setsockopt: %s\n", v15);
return v3;
}
if ( bind(v6, v4->ai_addr, v4->ai_addrlen) == -1 )
{
close(v6);
v12 = _errno_location();
v13 = strerror(*v12);
fprintf(stderr, "bind: %s\n", v13);
goto LABEL_10;
}
freeaddrinfo(pai);
if ( listen(v6, 10) == -1 )
{
v3 = -1;
close(v6);
v17 = _errno_location();
v18 = strerror(*v17);
fprintf(stderr, "listen: %s\n", v18);
}
else
{
*(_DWORD *)a1 = v6;
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
const char *v1; // rsi
int v2; // eax
unsigned int v3; // er12
struct addrinfo *v4; // rbx
int v5; // eax
int v6; // ebp
int *v8; // rax
char *v9; // rax
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
int *v14; // rax
char *v15; // rax
const char *v16; // rax
int *v17; // rax
char *v18; // rax
int optval; // [rsp+0h] [rbp-64h] BYREF
struct addrinfo *pai; // [rsp+4h] [rbp-60h] BYREF
struct addrinfo req; // [rsp+Ch] [rbp-58h] BYREF

v1 = *(const char **)(a1 + 8);
*(_OWORD *)&req.ai_flags = 0LL;
optval = 1;
req.ai_socktype = 1;
req.ai_flags = 1;
*(_OWORD *)&req.ai_addrlen = 0LL;
*(_OWORD *)&req.ai_canonname = 0LL;
v2 = getaddrinfo(0LL, v1, &req, &pai);
v3 = v2;
if ( v2 )
{
v3 = -1;
v16 = gai_strerror(v2);
fprintf(stderr, "getaddrinfo: %s\n\n", v16);
return v3;
}
v4 = pai;
if ( !pai )
{
LABEL_11:
v10 = _errno_location();
v3 = -1;
v11 = strerror(*v10);
fprintf(stderr, "bind: %s\n", v11);
return v3;
}
while ( 1 )
{
v5 = socket(v4->ai_family, v4->ai_socktype, v4->ai_protocol);
v6 = v5;
if ( v5 != -1 )
break;
v8 = _errno_location();
v9 = strerror(*v8);
fprintf(stderr, "socket: %s\n", v9);
LABEL_10:
v4 = v4->ai_next;
if ( !v4 )
goto LABEL_11;
}
if ( setsockopt(v5, 1, 2, &optval, 4u) == -1 )
{
v3 = -1;
close(v6);
v14 = _errno_location();
v15 = strerror(*v14);
fprintf(stderr, "setsockopt: %s\n", v15);
return v3;
}
if ( bind(v6, v4->ai_addr, v4->ai_addrlen) == -1 )
{
close(v6);
v12 = _errno_location();
v13 = strerror(*v12);
fprintf(stderr, "bind: %s\n", v13);
goto LABEL_10;
}
freeaddrinfo(pai);
if ( listen(v6, 10) == -1 )
{
v3 = -1;
close(v6);
v17 = _errno_location();
v18 = strerror(*v17);
fprintf(stderr, "listen: %s\n", v18);
}
else
{
*(_DWORD *)a1 = v6;
}
return v3;
}

original_code:
int server_init(struct server_t *self) {
    struct addrinfo hints, *info, *p;
    int enable = 1;
    int fd;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = 0;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0x0001;
    fd = getaddrinfo(((void *)0), self->port, &hints, &info);
    if (fd != 0) {
        fprintf(stderr, "getaddrinfo: %s\n" "\n", gai_strerror(fd));
        return -1;
    }
    for (p = info; p != ((void *)0); p = p->ai_next) {
        fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (fd == -1) {
            fprintf(stderr, "socket: %s" "\n", strerror((*__errno_location ())));
            continue;
        }
        if (setsockopt(fd, 1, 2, &enable, sizeof(int)) == -1) {
            close(fd);
            fprintf(stderr, "setsockopt: %s" "\n", strerror((*__errno_location ())));
            return -1;
        }
        if (bind(fd, p->ai_addr, p->ai_addrlen) == -1) {
            close(fd);
            fprintf(stderr, "bind: %s" "\n", strerror((*__errno_location ())));
            continue;
        }
        break;
    }
    if (p == ((void *)0)) {
        fprintf(stderr, "bind: %s" "\n", strerror((*__errno_location ())));
        return -1;
    }
    freeaddrinfo(info);
    if (listen(fd, 10) == -1) {
        close(fd);
        fprintf(stderr, "listen: %s" "\n", strerror((*__errno_location ())));
        return -1;
    }
    ;
    self->fd = fd;
    return 0;
}

canonical_original_code:
int server_init(struct server_t *self) {
    struct addrinfo hints; struct addrinfo *info; struct addrinfo *p;
    int enable = 1;
    int fd;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = 0;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0x0001;
    fd = getaddrinfo(((void *)0), self->port, &hints, &info);
    if (fd != 0) {
        fprintf(stderr, "getaddrinfo: %s\n" "\n", gai_strerror(fd));
        return -1;
    }
    for (p = info; p != ((void *)0); p = p->ai_next) {
        fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (fd == -1) {
            fprintf(stderr, "socket: %s" "\n", strerror((*__errno_location ())));
            continue;
        }
        if (setsockopt(fd, 1, 2, &enable, sizeof(int)) == -1) {
            close(fd);
            fprintf(stderr, "setsockopt: %s" "\n", strerror((*__errno_location ())));
            return -1;
        }
        if (bind(fd, p->ai_addr, p->ai_addrlen) == -1) {
            close(fd);
            fprintf(stderr, "bind: %s" "\n", strerror((*__errno_location ())));
            continue;
        }
        break;
    }
    if (p == ((void *)0)) {
        fprintf(stderr, "bind: %s" "\n", strerror((*__errno_location ())));
        return -1;
    }
    freeaddrinfo(info);
    if (listen(fd, 10) == -1) {
        close(fd);
        fprintf(stderr, "listen: %s" "\n", strerror((*__errno_location ())));
        return -1;
    }
    ;
    self->fd = fd;
    return 0;
}

variable_types: struct server_t { int fd; char *port; struct client_t { int remote_fd; int local_rfd; long timeout; int state; char ip[40]; struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; } request; char data[1024]; long data_length; long data_sent; struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; } response; long file_sent; unsigned int flags; struct client_t *next; struct client_t **prev; } *clients; } *

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

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

user_defined_types: struct server_t { int fd; char *port; struct client_t *clients; }


decompiled_code:
__int64 __fastcall server_accept(int *a1)
{
int v1; // edi
int v2; // eax
int v3; // ebp
unsigned int v4; // eax
__int64 v5; // rax
__int64 v6; // r12
int v7; // edi
char *v8; // rsi
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
int *v14; // rax
char *v15; // rax
socklen_t addr_len; // [rsp+Ch] [rbp-9Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-98h] BYREF

v1 = *a1;
addr_len = 128;
v2 = accept(v1, &addr, &addr_len);
if ( v2 == -1 )
{
v12 = _errno_location();
v6 = 0LL;
v13 = strerror(*v12);
fprintf(stderr, "accept: %s\n", v13);
return v6;
}
v3 = v2;
v4 = fcntl(v2, 3, 0LL);
if ( v4 == -1 )
{
v10 = _errno_location();
v11 = strerror(*v10);
fprintf(stderr, "fcntl: F_GETFL %s\n", v11);
}
else
{
BYTE1(v4) |= 8u;
if ( fcntl(v3, 4, v4) == -1 )
{
v14 = _errno_location();
v15 = strerror(*v14);
fprintf(stderr, "fcntl: F_SETFL O_NONBLOCK %s\n", v15);
}
else
{
v5 = clientpool_alloc();
v6 = v5;
if ( v5 )
{
client_init(v5);
v7 = addr.sa_family;
v8 = &addr.sa_data[2];
*(_DWORD *)v6 = v3;
*(_DWORD *)(v6 + 16) = 1;
if ( (_WORD)v7 != 2 )
v8 = &addr.sa_data[6];
inet_ntop(v7, v8, (char *)(v6 + 20), 0x28u);
return v6;
}
}
}
close(v3);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(int *a1)
{
int v1; // edi
int v2; // eax
int v3; // ebp
unsigned int v4; // eax
__int64 v5; // rax
__int64 v6; // r12
int v7; // edi
char *v8; // rsi
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
int *v14; // rax
char *v15; // rax
socklen_t addr_len; // [rsp+Ch] [rbp-9Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-98h] BYREF

v1 = *a1;
addr_len = 128;
v2 = accept(v1, &addr, &addr_len);
if ( v2 == -1 )
{
v12 = _errno_location();
v6 = 0LL;
v13 = strerror(*v12);
fprintf(stderr, "accept: %s\n", v13);
return v6;
}
v3 = v2;
v4 = fcntl(v2, 3, 0LL);
if ( v4 == -1 )
{
v10 = _errno_location();
v11 = strerror(*v10);
fprintf(stderr, "fcntl: F_GETFL %s\n", v11);
}
else
{
BYTE1(v4) |= 8u;
if ( fcntl(v3, 4, v4) == -1 )
{
v14 = _errno_location();
v15 = strerror(*v14);
fprintf(stderr, "fcntl: F_SETFL O_NONBLOCK %s\n", v15);
}
else
{
v5 = clientpool_alloc();
v6 = v5;
if ( v5 )
{
client_init(v5);
v7 = addr.sa_family;
v8 = &addr.sa_data[2];
*(_DWORD *)v6 = v3;
*(_DWORD *)(v6 + 16) = 1;
if ( (_WORD)v7 != 2 )
v8 = &addr.sa_data[6];
inet_ntop(v7, v8, (char *)(v6 + 20), 0x28u);
return v6;
}
}
}
close(v3);
return 0LL;
}

original_code:
struct client_t *server_accept(struct server_t *self) {
    socklen_t len;
    struct sockaddr_storage addr;
    int fd;
    int flags;
    struct client_t *c;
    len = sizeof(addr);
    fd = accept(self->fd, (struct sockaddr *)&addr, &len);
    if (fd == -1) {
        fprintf(stderr, "accept: %s" "\n", strerror((*__errno_location ())));
        return ((void *)0);
    }
    flags = fcntl(fd, 3, ((void *)0));
    if (flags == -1) {
        fprintf(stderr, "fcntl: F_GETFL %s" "\n", strerror((*__errno_location ())));
        goto err;
    }
    if (fcntl(fd, 4, flags | 04000) == -1) {
        fprintf(stderr, "fcntl: F_SETFL O_NONBLOCK %s" "\n", strerror((*__errno_location ())));
        goto err;
    }
    c = clientpool_alloc();
    if (c == ((void *)0)) {
        goto err;
    }
    client_init(c);
    c->remote_fd = fd;
    c->state = STATE_RECV_HEADER;
    inet_ntop(addr.ss_family, (((struct sockaddr *)(&addr))->sa_family == 2) ? (void *)&(((struct sockaddr_in *)(&addr))->sin_addr) : (void *)&(((struct sockaddr_in6 *)(&addr))->sin6_addr), c->ip, sizeof(c->ip));
    ;
    return c;
err:
    close(fd);
    return ((void *)0);
}

canonical_original_code:
struct client_t *server_accept(struct server_t *self) {
    unsigned int len;
    struct sockaddr_storage addr;
    int fd;
    int flags;
    struct client_t *c;
    len = sizeof(addr);
    fd = accept(self->fd, (struct sockaddr *)&addr, &len);
    if (fd == -1) {
        fprintf(stderr, "accept: %s" "\n", strerror((*__errno_location ())));
        return ((void *)0);
    }
    flags = fcntl(fd, 3, ((void *)0));
    if (flags == -1) {
        fprintf(stderr, "fcntl: F_GETFL %s" "\n", strerror((*__errno_location ())));
        goto err;
    }
    if (fcntl(fd, 4, flags | 04000) == -1) {
        fprintf(stderr, "fcntl: F_SETFL O_NONBLOCK %s" "\n", strerror((*__errno_location ())));
        goto err;
    }
    c = clientpool_alloc();
    if (c == ((void *)0)) {
        goto err;
    }
    client_init(c);
    c->remote_fd = fd;
    c->state = STATE_RECV_HEADER;
    inet_ntop(addr.ss_family, (((struct sockaddr *)(&addr))->sa_family == 2) ? (void *)&(((struct sockaddr_in *)(&addr))->sin_addr) : (void *)&(((struct sockaddr_in6 *)(&addr))->sin6_addr), c->ip, sizeof(c->ip));
    ;
    return c;
err:
    close(fd);
    return ((void *)0);
}

variable_types: struct server_t { int fd; char *port; struct client_t *clients; } *

variable_types:
len
unsigned int

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

variable_types: flags int

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

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

user_defined_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr sin6_addr; unsigned int sin6_scope_id; }

user_defined_types: struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; }


original_code:
void server_poll(struct server_t *self) {
    fd_set rfds, wfds;
    int max_rfd, max_wfd;
    int num_fd;
    time_t chk_time;
    struct timeval timeout;
    struct client_t *c, *tc;
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&rfds)->__fds_bits)[0]) : "memory"); } while (0);
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&wfds)->__fds_bits)[0]) : "memory"); } while (0);
    max_rfd = max_wfd = -1;
    do { ((void) (((&rfds)->__fds_bits)[((self->fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((self->fd) % (8 * (int) sizeof (__fd_mask))))))); if (self->fd > max_rfd) { max_rfd = self->fd; } } while (0);
    g_curtime = time(((void *)0));
    for (c = self->clients; c != ((void *)0); ) {
        if (g_curtime > c->timeout) {
            ;
            tc = c;
            c = c->next;
            forget_client(tc);
            continue;
        }
        switch (c->state) {
        case STATE_RECV_HEADER:
            do { ((void) (((&rfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask))))))); if (c->remote_fd > max_rfd) { max_rfd = c->remote_fd; } } while (0);
            break;
        case STATE_SEND_HEADER:
        case STATE_SEND_FILE:
            do { ((void) (((&wfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask))))))); if (c->remote_fd > max_wfd) { max_wfd = c->remote_fd; } } while (0);
            break;
        }
        c = c->next;
    }
    timeout.tv_sec = 60;
    timeout.tv_usec = 0;
    for (;;) {
        num_fd = select((max_rfd > max_wfd) ? (max_rfd + 1) : (max_wfd + 1),
                &rfds, (max_wfd != -1) ? &wfds : ((void *)0),
                ((void *)0), &timeout);
        if (num_fd > 0) {
            break;
        }
        if (num_fd < 0) {
            if ((*__errno_location ()) == 4) {
                continue;
            } else {
                fprintf(stderr, "select: %s" "\n", strerror((*__errno_location ())));
                sleep(1);
            }
        }
        return;
    }
    g_curtime = time(((void *)0));
    chk_time = g_curtime + 60;
    if (((((&rfds)->__fds_bits)[((self->fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((self->fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
        c = server_accept(self);
        if (c != ((void *)0)) {
            client_add(c, &self->clients);
            c->timeout = chk_time;
            state_recv_header(c);
            if (c->state == STATE_NONE) {
                forget_client(c);
            }
        }
        --num_fd;
    }
    for (c = self->clients; num_fd > 0 && c != ((void *)0); ) {
        switch (c->state) {
        case STATE_NONE:
            break;
        case STATE_RECV_HEADER:
            if (((((&rfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
                c->timeout = chk_time;
                state_recv_header(c);
                --num_fd;
            }
            break;
        case STATE_SEND_HEADER:
            if (((((&wfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
                c->timeout = chk_time;
                state_send_header(c);
                --num_fd;
            }
            break;
        case STATE_SEND_FILE:
            if (((((&wfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
                c->timeout = chk_time;
                state_send_file(c);
                --num_fd;
            }
            break;
        default:
            ;
            c->state = STATE_NONE;
            break;
        }
        if (c->state == STATE_NONE) {
            ;
            tc = c;
            c = c->next;
            forget_client(tc);
        } else {
            c = c->next;
        }
    }
}

canonical_original_code:
void server_poll(struct server_t *self) {
    struct fd_set rfds; struct fd_set wfds;
    int max_rfd; int max_wfd;
    int num_fd;
    long chk_time;
    struct timeval timeout;
    struct client_t *c; struct client_t *tc;
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&rfds)->__fds_bits)[0]) : "memory"); } while (0);
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&wfds)->__fds_bits)[0]) : "memory"); } while (0);
    max_rfd = max_wfd = -1;
    do { ((void) (((&rfds)->__fds_bits)[((self->fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((self->fd) % (8 * (int) sizeof (__fd_mask))))))); if (self->fd > max_rfd) { max_rfd = self->fd; } } while (0);
    g_curtime = time(((void *)0));
    for (c = self->clients; c != ((void *)0); ) {
        if (g_curtime > c->timeout) {
            ;
            tc = c;
            c = c->next;
            forget_client(tc);
            continue;
        }
        switch (c->state) {
        case STATE_RECV_HEADER:
            do { ((void) (((&rfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask))))))); if (c->remote_fd > max_rfd) { max_rfd = c->remote_fd; } } while (0);
            break;
        case STATE_SEND_HEADER:
        case STATE_SEND_FILE:
            do { ((void) (((&wfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask))))))); if (c->remote_fd > max_wfd) { max_wfd = c->remote_fd; } } while (0);
            break;
        }
        c = c->next;
    }
    timeout.tv_sec = 60;
    timeout.tv_usec = 0;
    for (;;) {
        num_fd = select((max_rfd > max_wfd) ? (max_rfd + 1) : (max_wfd + 1),
                &rfds, (max_wfd != -1) ? &wfds : ((void *)0),
                ((void *)0), &timeout);
        if (num_fd > 0) {
            break;
        }
        if (num_fd < 0) {
            if ((*__errno_location ()) == 4) {
                continue;
            } else {
                fprintf(stderr, "select: %s" "\n", strerror((*__errno_location ())));
                sleep(1);
            }
        }
        return;
    }
    g_curtime = time(((void *)0));
    chk_time = g_curtime + 60;
    if (((((&rfds)->__fds_bits)[((self->fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((self->fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
        c = server_accept(self);
        if (c != ((void *)0)) {
            client_add(c, &self->clients);
            c->timeout = chk_time;
            state_recv_header(c);
            if (c->state == STATE_NONE) {
                forget_client(c);
            }
        }
        --num_fd;
    }
    for (c = self->clients; num_fd > 0 && c != ((void *)0); ) {
        switch (c->state) {
        case STATE_NONE:
            break;
        case STATE_RECV_HEADER:
            if (((((&rfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
                c->timeout = chk_time;
                state_recv_header(c);
                --num_fd;
            }
            break;
        case STATE_SEND_HEADER:
            if (((((&wfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
                c->timeout = chk_time;
                state_send_header(c);
                --num_fd;
            }
            break;
        case STATE_SEND_FILE:
            if (((((&wfds)->__fds_bits)[((c->remote_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((c->remote_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
                c->timeout = chk_time;
                state_send_file(c);
                --num_fd;
            }
            break;
        default:
            ;
            c->state = STATE_NONE;
            break;
        }
        if (c->state == STATE_NONE) {
            ;
            tc = c;
            c = c->next;
            forget_client(tc);
        } else {
            c = c->next;
        }
    }
}

variable_types:
rfds
struct fd_set { long __fds_bits[-1]; }

variable_types:
wfds
struct fd_set { long __fds_bits[-1]; }

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


decompiled_code:
int server_close_fds()
{
int result; // eax
__int64 i; // rbx
int v2; // edi

result = close(g_server);
for ( i = *((_QWORD *)&g_server + 2); i; i = *(_QWORD *)(i + 1272) )
{
result = close(*(_DWORD *)i);
v2 = *(_DWORD *)(i + 4);
if ( v2 != -1 )
result = close(v2);
}
return result;
}

canonical_decompiled_code:
int func4()
{
int result; // eax
__int64 i; // rbx
int v2; // edi

result = close(g_server);
for ( i = *((_QWORD *)&g_server + 2); i; i = *(_QWORD *)(i + 1272) )
{
result = close(*(_DWORD *)i);
v2 = *(_DWORD *)(i + 4);
if ( v2 != -1 )
result = close(v2);
}
return result;
}

original_code:
void server_close_fds() {
    struct client_t *c;
    close(g_server.fd);
    for (c = g_server.clients; c != ((void *)0); c = c->next) {
        close(c->remote_fd);
        if (c->local_rfd != -1) {
            close(c->local_rfd);
        }
    }
}


decompiled_code:
__int64 __fastcall mimetype_find_def(char *s2)
{
int v1; // edx
signed int v2; // er13
int v3; // ebp
const char *i; // rdi
unsigned int v6; // er12
int v7; // eax

v1 = 41;
v2 = 0;
v3 = 41;
for ( i = (const char *)&unk_C5; ; i = DEFAULT_MIME_TYPES[2 * ((v3 + v2) >> 1)] )
{
v6 = v1 >> 1;
v7 = strcasecmp(i, s2);
if ( v7 >= 0 )
break;
v2 = v6 + 1;
if ( v3 < (int)(v6 + 1) )
return (unsigned int)-1;
LABEL_4:
v1 = v3 + v2;
}
if ( !v7 )
return v6;
v3 = v6 - 1;
if ( (int)(v6 - 1) >= v2 )
goto LABEL_4;
return (unsigned int)-1;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *s2)
{
int v1; // edx
signed int v2; // er13
int v3; // ebp
const char *i; // rdi
unsigned int v6; // er12
int v7; // eax

v1 = 41;
v2 = 0;
v3 = 41;
for ( i = (const char *)&unk_C5; ; i = DEFAULT_MIME_TYPES[2 * ((v3 + v2) >> 1)] )
{
v6 = v1 >> 1;
v7 = strcasecmp(i, s2);
if ( v7 >= 0 )
break;
v2 = v6 + 1;
if ( v3 < (int)(v6 + 1) )
return (unsigned int)-1;
LABEL_4:
v1 = v3 + v2;
}
if ( !v7 )
return v6;
v3 = v6 - 1;
if ( (int)(v6 - 1) >= v2 )
goto LABEL_4;
return (unsigned int)-1;
}

original_code:
static
int mimetype_find_def(const char *ext) {
    int l, m, h, r;
    h = (sizeof(DEFAULT_MIME_TYPES) / sizeof((DEFAULT_MIME_TYPES)[0])) - 1;
    l = 0;
    while (h >= l) {
        m = (h + l) / 2;
        r = strcasecmp(DEFAULT_MIME_TYPES[m].ext, ext);
        if (r < 0) {
            l = m + 1;
        } else if (r > 0) {
            h = m - 1;
        } else {
            return m;
        }
    }
    return -1;
}

canonical_original_code:
static int mimetype_find_def(char *ext) {
    int l; int m; int h; int r;
    h = (sizeof(DEFAULT_MIME_TYPES) / sizeof((DEFAULT_MIME_TYPES)[0])) - 1;
    l = 0;
    while (h >= l) {
        m = (h + l) / 2;
        r = strcasecmp(DEFAULT_MIME_TYPES[m].ext, ext);
        if (r < 0) {
            l = m + 1;
        } else if (r > 0) {
            h = m - 1;
        } else {
            return m;
        }
    }
    return -1;
}

variable_types:
ext
char *

variable_types: l int

variable_types: m int

variable_types: h int

variable_types: r int


decompiled_code:
const char *__fastcall mimetype_get(const char *a1)
{
char *v1; // rax
int v2; // eax
const char *result; // rax

v1 = strrchr(a1, 46);
if ( v1 && (v2 = mimetype_find_def(v1 + 1), v2 >= 0) )
result = off_368[2 * v2];
else
result = "text/plain";
return result;
}

canonical_decompiled_code:
const char *__fastcall func1(const char *a1)
{
char *v1; // rax
int v2; // eax
const char *result; // rax

v1 = strrchr(a1, 46);
if ( v1 && (v2 = func0(v1 + 1), v2 >= 0) )
result = off_368[2 * v2];
else
result = "text/plain";
return result;
}

original_code:
const char *mimetype_get(const char *name) {
    int i;
    name = strrchr(name, '.');
    if (name != ((void *)0)) {
        i = mimetype_find_def(name + 1);
        if (i >= 0) {
            return DEFAULT_MIME_TYPES[i].type;
        }
    }
    return "text/plain";
}

canonical_original_code:
char *mimetype_get(char *name) {
    int i;
    name = strrchr(name, '.');
    if (name != ((void *)0)) {
        i = mimetype_find_def(name + 1);
        if (i >= 0) {
            return DEFAULT_MIME_TYPES[i].type;
        }
    }
    return "text/plain";
}

variable_types:
name
char *

variable_types: i int


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

if ( (*(_BYTE *)(a1 + 1264) & 4) != 0 )
{
result = client_reset();
*(_DWORD *)(a1 + 16) = 1;
}
else
{
*(_DWORD *)(a1 + 16) = 0;
}
return result;
}

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

if ( (*(_BYTE *)(a1 + 1264) & 4) != 0 )
{
result = client_reset();
*(_DWORD *)(a1 + 16) = 1;
}
else
{
*(_DWORD *)(a1 + 16) = 0;
}
return result;
}

original_code:
static
void state_finish(struct client_t *client) {
    if (client->flags & CLIENT_FLAG_KEEPALIVE) {
        client_reset(client);
        client->state = STATE_RECV_HEADER;
    } else {
        client->state = STATE_NONE;
    }
}

variable_types: struct client_t { int remote_fd; int local_rfd; long timeout; int state; char ip[40]; struct request_t { char *header[-1]; char *method; char *url; char *query_string; char *version; char *range_from; char *range_to; long header_length; } request; char data[1024]; long data_length; long data_sent; struct response_t { int status_code; char *content_type; long total_length; long content_length; long content_from; long last_mod; } response; long file_sent; unsigned int flags; struct client_t *next; struct client_t **prev; } *


original_code:
void state_send_header(struct client_t *client) {
    ssize_t len;
    len = send(client->remote_fd, client->data + client->data_sent,
                client->data_length - client->data_sent, MSG_NOSIGNAL);
    do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "send", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
    client->data_sent += len;
    if (client->data_sent >= client->data_length) {
        client->data_length = client->data_sent = 0;
        if (client->local_rfd == -1) {
            state_finish(client);
        } else {
            client->state = STATE_SEND_FILE;
        }
    }
}

canonical_original_code:
void state_send_header(struct client_t *client) {
    long len;
    len = send(client->remote_fd, client->data + client->data_sent,
                client->data_length - client->data_sent, MSG_NOSIGNAL);
    do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "send", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
    client->data_sent += len;
    if (client->data_sent >= client->data_length) {
        client->data_length = client->data_sent = 0;
        if (client->local_rfd == -1) {
            state_finish(client);
        } else {
            client->state = STATE_SEND_FILE;
        }
    }
}

variable_types: len long


decompiled_code:
int __fastcall state_recv_header(unsigned int *a1)
{
__int64 v1; // rdx
char *v2; // rbx
int *v3; // rax
__int64 v4; // r12
char *v5; // rax
__int64 v6; // rcx
const char *v7; // rdx
const char *v8; // r8
char *v9; // rax
int v10; // eax

v1 = *((_QWORD *)a1 + 20);
v2 = (char *)(a1 + 42);
if ( v1 > 0 )
goto LABEL_2;
v3 = (int *)recv(*a1, v2, 0x400uLL, 2);
v4 = (__int64)v3;
if ( v3 == (int *)-1LL )
{
v3 = _errno_location();
if ( *v3 == 11 )
return (int)v3;
v9 = strerror(*v3);
v6 = *a1;
v7 = "peek";
v8 = v9;
goto LABEL_18;
}
if ( !v3 )
goto LABEL_10;
if ( (__int64)v3 <= 4 )
{
v1 = *((_QWORD *)a1 + 20);
goto LABEL_14;
}
LODWORD(v3) = http_find_headerlength(v2, (unsigned int)v3);
v1 = (int)v3;
*((_QWORD *)a1 + 20) = (int)v3;
if ( (int)v3 >= 0LL || v4 <= 1023 )
{
LABEL_14:
if ( v1 <= 0 )
goto LABEL_6;
goto LABEL_2;
}
a1[302] = 413;
v10 = http_gen_errorpage(a1 + 302, v2, 1024LL);
v1 = *((_QWORD *)a1 + 20);
a1[4] = 2;
*((_QWORD *)a1 + 149) = v10;
if ( v1 > 0 )
{
LABEL_2:
v3 = (int *)recv(*a1, &v2[*((_QWORD *)a1 + 149)], v1 - *((_QWORD *)a1 + 149), 0);
if ( v3 != (int *)-1LL )
{
if ( v3 )
{
v3 = (int *)((char *)v3 + *((_QWORD *)a1 + 149));
*((_QWORD *)a1 + 149) = v3;
if ( (__int64)v3 >= *((_QWORD *)a1 + 20) )
LODWORD(v3) = client_process(a1);
LABEL_6:
if ( a1[4] != 2 )
return (int)v3;
goto LABEL_7;
}
LABEL_10:
a1[4] = 0;
return (int)v3;
}
v3 = _errno_location();
if ( *v3 == 11 )
return (int)v3;
v5 = strerror(*v3);
v6 = *a1;
v7 = "recv";
v8 = v5;
LABEL_18:
LODWORD(v3) = fprintf(stderr, "%s: client %d %s\n", v7, v6, v8);
goto LABEL_10;
}
LABEL_7:
LODWORD(v3) = state_send_header(a1);
return (int)v3;
}

canonical_decompiled_code:
int __fastcall func2(unsigned int *a1)
{
__int64 v1; // rdx
char *v2; // rbx
int *v3; // rax
__int64 v4; // r12
char *v5; // rax
__int64 v6; // rcx
const char *v7; // rdx
const char *v8; // r8
char *v9; // rax
int v10; // eax

v1 = *((_QWORD *)a1 + 20);
v2 = (char *)(a1 + 42);
if ( v1 > 0 )
goto LABEL_2;
v3 = (int *)recv(*a1, v2, 0x400uLL, 2);
v4 = (__int64)v3;
if ( v3 == (int *)-1LL )
{
v3 = _errno_location();
if ( *v3 == 11 )
return (int)v3;
v9 = strerror(*v3);
v6 = *a1;
v7 = "peek";
v8 = v9;
goto LABEL_18;
}
if ( !v3 )
goto LABEL_10;
if ( (__int64)v3 <= 4 )
{
v1 = *((_QWORD *)a1 + 20);
goto LABEL_14;
}
LODWORD(v3) = http_find_headerlength(v2, (unsigned int)v3);
v1 = (int)v3;
*((_QWORD *)a1 + 20) = (int)v3;
if ( (int)v3 >= 0LL || v4 <= 1023 )
{
LABEL_14:
if ( v1 <= 0 )
goto LABEL_6;
goto LABEL_2;
}
a1[302] = 413;
v10 = http_gen_errorpage(a1 + 302, v2, 1024LL);
v1 = *((_QWORD *)a1 + 20);
a1[4] = 2;
*((_QWORD *)a1 + 149) = v10;
if ( v1 > 0 )
{
LABEL_2:
v3 = (int *)recv(*a1, &v2[*((_QWORD *)a1 + 149)], v1 - *((_QWORD *)a1 + 149), 0);
if ( v3 != (int *)-1LL )
{
if ( v3 )
{
v3 = (int *)((char *)v3 + *((_QWORD *)a1 + 149));
*((_QWORD *)a1 + 149) = v3;
if ( (__int64)v3 >= *((_QWORD *)a1 + 20) )
LODWORD(v3) = client_process(a1);
LABEL_6:
if ( a1[4] != 2 )
return (int)v3;
goto LABEL_7;
}
LABEL_10:
a1[4] = 0;
return (int)v3;
}
v3 = _errno_location();
if ( *v3 == 11 )
return (int)v3;
v5 = strerror(*v3);
v6 = *a1;
v7 = "recv";
v8 = v5;
LABEL_18:
LODWORD(v3) = fprintf(stderr, "%s: client %d %s\n", v7, v6, v8);
goto LABEL_10;
}
LABEL_7:
LODWORD(v3) = func1(a1);
return (int)v3;
}

original_code:
void state_recv_header(struct client_t *client) {
    ssize_t len;
    if (client->request.header_length <= 0) {
        len = recv(client->remote_fd, client->data, sizeof(client->data),
                MSG_PEEK);
        do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "peek", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
        if (len > 4) {
            client->request.header_length = http_find_headerlength(client->data,
                    len);
            if (client->request.header_length < 0) {
                if (len >= 1024) {
                    client->response.status_code = HTTP_STATUS_ENTITYTOOLARGE;
                    client->data_length = http_gen_errorpage(&client->response,
                            client->data, sizeof(client->data));
                    client->state = STATE_SEND_HEADER;
                }
            }
        }
    }
    if (client->request.header_length > 0) {
        len = recv(client->remote_fd, client->data + client->data_length,
                client->request.header_length - client->data_length, 0);
        do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "recv", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
        client->data_length += len;
        if (client->data_length >= client->request.header_length) {
            client_process(client);
        }
    }
    if (client->state == STATE_SEND_HEADER) {
        state_send_header(client);
    }
}

canonical_original_code:
void state_recv_header(struct client_t *client) {
    long len;
    if (client->request.header_length <= 0) {
        len = recv(client->remote_fd, client->data, sizeof(client->data),
                MSG_PEEK);
        do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "peek", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
        if (len > 4) {
            client->request.header_length = http_find_headerlength(client->data,
                    len);
            if (client->request.header_length < 0) {
                if (len >= 1024) {
                    client->response.status_code = HTTP_STATUS_ENTITYTOOLARGE;
                    client->data_length = http_gen_errorpage(&client->response,
                            client->data, sizeof(client->data));
                    client->state = STATE_SEND_HEADER;
                }
            }
        }
    }
    if (client->request.header_length > 0) {
        len = recv(client->remote_fd, client->data + client->data_length,
                client->request.header_length - client->data_length, 0);
        do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "recv", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
        client->data_length += len;
        if (client->data_length >= client->request.header_length) {
            client_process(client);
        }
    }
    if (client->state == STATE_SEND_HEADER) {
        state_send_header(client);
    }
}


decompiled_code:
int __fastcall state_send_file(unsigned int *a1)
{
__int64 v2; // rax
__int64 v3; // rcx
int v4; // esi
off_t v5; // rdx
int v6; // edi
int *v7; // rax
char *v8; // rax
off_t offset[2]; // [rsp+8h] [rbp-10h] BYREF

v2 = *((_QWORD *)a1 + 157);
v3 = *((_QWORD *)a1 + 154);
v4 = a1[1];
v5 = v2 + *((_QWORD *)a1 + 155);
v6 = *a1;
offset[0] = v5;
v7 = (int *)sendfile(v6, v4, offset, v3 - v2);
if ( v7 == (int *)-1LL )
{
v7 = _errno_location();
if ( *v7 != 11 )
{
v8 = strerror(*v7);
LODWORD(v7) = fprintf(stderr, "%s: client %d %s\n", "sendfile", *a1, v8);
a1[4] = 0;
}
}
else if ( v7 )
{
v7 = (int *)((char *)v7 + *((_QWORD *)a1 + 157));
*((_QWORD *)a1 + 157) = v7;
if ( (__int64)v7 >= *((_QWORD *)a1 + 154) )
{
close(a1[1]);
a1[1] = -1;
LODWORD(v7) = state_finish((__int64)a1);
}
}
else
{
a1[4] = 0;
}
return (int)v7;
}

original_code:
void state_send_file(struct client_t *client) {
    ssize_t len;
    off_t offset;
    offset = client->response.content_from + client->file_sent;
    len = sendfile(client->remote_fd, client->local_rfd, &offset,
            client->response.content_length - client->file_sent);
    do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "sendfile", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
    client->file_sent += len;
    if (client->file_sent >= client->response.content_length) {
        close(client->local_rfd);
        client->local_rfd = -1;
        state_finish(client);
    }
}

canonical_original_code:
void state_send_file(struct client_t *client) {
    long len;
    long offset;
    offset = client->response.content_from + client->file_sent;
    len = sendfile(client->remote_fd, client->local_rfd, &offset,
            client->response.content_length - client->file_sent);
    do { if (len == -1) { if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11) { ; } else { fprintf(stderr, "%s: client %d %s" "\n", "sendfile", client->remote_fd, strerror((*__errno_location ()))); client->state = STATE_NONE; } return; } else if (len == 0) { client->state = STATE_NONE; return; } } while (0);
    client->file_sent += len;
    if (client->file_sent >= client->response.content_length) {
        close(client->local_rfd);
        client->local_rfd = -1;
        state_finish(client);
    }
}

variable_types: offset long


repo: nqv/niscy

decompiled_code:
__int64 __fastcall parse_args(int a1, __int64 a2)
{
__int64 result; // rax
__int64 v5; // rsi
_BYTE *v6; // rcx
char *v7; // rdx
char *v8; // rdx
char *v9; // rdx
char *v10; // rdx
__int64 v11; // rdx
char *v12; // rdx
char *v13; // rdx
char *v14; // rdx
__int64 v15; // rdx

result = 1LL;
if ( a1 > 1 )
{
while ( 2 )
{
v5 = 8LL * (int)result;
v6 = *(_BYTE **)(a2 + v5);
if ( *v6 == 45 )
{
result = (unsigned int)(result + 1);
switch ( v6[1] )
{
case 'F':
v15 = (__int64)(v6 + 2);
if ( !v6[2] )
{
v15 = *(_QWORD *)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E20 = v15;
if ( a1 > (int)result )
continue;
return result;
case 'P':
v14 = v6 + 2;
if ( !v6[2] )
{
v14 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E00 = v14;
if ( a1 > (int)result )
continue;
return result;
case 'U':
v13 = v6 + 2;
if ( !v6[2] )
{
v13 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
s = v13;
if ( a1 > (int)result )
continue;
return result;
case 'a':
v12 = v6 + 2;
if ( !v6[2] )
{
v12 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E10 = v12;
if ( a1 > (int)result )
continue;
return result;
case 'c':
v11 = (__int64)(v6 + 2);
if ( !v6[2] )
{
v11 = *(_QWORD *)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E18 = v11;
if ( a1 > (int)result )
continue;
return result;
case 'd':
v10 = v6 + 2;
if ( !v6[2] )
{
v10 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
off_E08 = v10;
if ( a1 > (int)result )
continue;
return result;
case 'h':
v9 = v6 + 2;
if ( !v6[2] )
{
v9 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
smtp_[0] = v9;
if ( a1 > (int)result )
continue;
return result;
case 'p':
v8 = v6 + 2;
if ( !v6[2] )
{
v8 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
off_DE8 = v8;
if ( a1 > (int)result )
continue;
return result;
case 's':
v7 = v6 + 2;
if ( !v6[2] )
{
v7 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
s1 = v7;
goto LABEL_7;
default:
LABEL_7:
if ( a1 <= (int)result )
return result;
continue;
}
}
break;
}
qword_E28 = a2 + v5;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, __int64 a2)
{
__int64 result; // rax
__int64 v5; // rsi
_BYTE *v6; // rcx
char *v7; // rdx
char *v8; // rdx
char *v9; // rdx
char *v10; // rdx
__int64 v11; // rdx
char *v12; // rdx
char *v13; // rdx
char *v14; // rdx
__int64 v15; // rdx

result = 1LL;
if ( a1 > 1 )
{
while ( 2 )
{
v5 = 8LL * (int)result;
v6 = *(_BYTE **)(a2 + v5);
if ( *v6 == 45 )
{
result = (unsigned int)(result + 1);
switch ( v6[1] )
{
case 'F':
v15 = (__int64)(v6 + 2);
if ( !v6[2] )
{
v15 = *(_QWORD *)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E20 = v15;
if ( a1 > (int)result )
continue;
return result;
case 'P':
v14 = v6 + 2;
if ( !v6[2] )
{
v14 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E00 = v14;
if ( a1 > (int)result )
continue;
return result;
case 'U':
v13 = v6 + 2;
if ( !v6[2] )
{
v13 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
s = v13;
if ( a1 > (int)result )
continue;
return result;
case 'a':
v12 = v6 + 2;
if ( !v6[2] )
{
v12 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E10 = v12;
if ( a1 > (int)result )
continue;
return result;
case 'c':
v11 = (__int64)(v6 + 2);
if ( !v6[2] )
{
v11 = *(_QWORD *)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
qword_E18 = v11;
if ( a1 > (int)result )
continue;
return result;
case 'd':
v10 = v6 + 2;
if ( !v6[2] )
{
v10 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
off_E08 = v10;
if ( a1 > (int)result )
continue;
return result;
case 'h':
v9 = v6 + 2;
if ( !v6[2] )
{
v9 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
smtp_[0] = v9;
if ( a1 > (int)result )
continue;
return result;
case 'p':
v8 = v6 + 2;
if ( !v6[2] )
{
v8 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
off_DE8 = v8;
if ( a1 > (int)result )
continue;
return result;
case 's':
v7 = v6 + 2;
if ( !v6[2] )
{
v7 = *(char **)(a2 + v5 + 8);
result = (unsigned int)(result + 1);
}
s1 = v7;
goto LABEL_7;
default:
LABEL_7:
if ( a1 <= (int)result )
return result;
continue;
}
}
break;
}
qword_E28 = a2 + v5;
}
return result;
}

original_code:
static void parse_args(int argc, char **argv) {
    int i;
    char *arg;
    for (i = 1; i < argc; ++i) {
        arg = argv[i];
        if (arg[0] != '-') {
            smtp_.mail_to = (const char **)&argv[i];
            break;
        }
        switch (arg[1]) {
        case 'U':
            smtp_.user = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'P':
            smtp_.pass = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'F':
            smtp_.mail_from = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'a':
            smtp_.auth = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'c':
            smtp_.cert = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'd':
            smtp_.domain = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'h':
            smtp_.host = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'p':
            smtp_.port = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 's':
            smtp_.security = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        }
    }
}

canonical_original_code:
static void parse_args(int argc, char **argv) {
    int i;
    char *arg;
    for (i = 1; i < argc; ++i) {
        arg = argv[i];
        if (arg[0] != '-') {
            smtp_.mail_to = (char **)&argv[i];
            break;
        }
        switch (arg[1]) {
        case 'U':
            smtp_.user = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'P':
            smtp_.pass = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'F':
            smtp_.mail_from = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'a':
            smtp_.auth = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'c':
            smtp_.cert = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'd':
            smtp_.domain = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'h':
            smtp_.host = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 'p':
            smtp_.port = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        case 's':
            smtp_.security = (arg[2] == '\0') ? argv[++i] : &arg[2];
            break;
        }
    }
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
arg
char *