decompiled_code:
void *__fastcall hl_parse_file(const char *a1, __int64 a2)
{
char *v2; // rbp
char *v3; // rax
void *v4; // r12

if ( !a1 )
_assert_fail("filename", "hublist.c", 0x115u, "hl_parse_file");
v2 = strdup(a1);
if ( !(unsigned int)str_has_suffix(v2, ".bz2") )
goto LABEL_15;
v3 = strrchr(v2, 46);
if ( !v3 )
_assert_fail("e", "hublist.c", 0x11Bu, "hl_parse_file");
*v3 = 0;
if ( (unsigned int)bz2_decode(a1, v2, a2) )
{
v4 = 0LL;
free(v2);
}
else
{
LABEL_15:
if ( (unsigned int)str_has_suffix(v2, ".xml") )
v4 = hl_parse_file_xml(v2, a2);
else
v4 = hl_parse_file_config(v2, a2);
free(v2);
}
return v4;
}

canonical_decompiled_code:
void *__fastcall func6(const char *a1, __int64 a2)
{
char *v2; // rbp
char *v3; // rax
void *v4; // r12

if ( !a1 )
_assert_fail("filename", "hublist.c", 0x115u, "hl_parse_file");
v2 = strdup(a1);
if ( !(unsigned int)str_has_suffix(v2, ".bz2") )
goto LABEL_15;
v3 = strrchr(v2, 46);
if ( !v3 )
_assert_fail("e", "hublist.c", 0x11Bu, "hl_parse_file");
*v3 = 0;
if ( (unsigned int)bz2_decode(a1, v2, a2) )
{
v4 = 0LL;
free(v2);
}
else
{
LABEL_15:
if ( (unsigned int)str_has_suffix(v2, ".xml") )
v4 = func1(v2, a2);
else
v4 = hl_parse_file_config(v2, a2);
free(v2);
}
return v4;
}

original_code:
hublist_t *hl_parse_file(const char *filename, xerr_t **err)
{
    hublist_t *hlist = 0;
    ((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename) ; else __assert_fail ("filename", "hublist.c", 277, __extension__ __PRETTY_FUNCTION__); }));
    char *xfilename = strdup(filename);
    if(str_has_suffix(xfilename, ".bz2"))
    {
        char *e = strrchr(xfilename, '.');
        ((void) sizeof ((e) ? 1 : 0), __extension__ ({ if (e) ; else __assert_fail ("e", "hublist.c", 283, __extension__ __PRETTY_FUNCTION__); }));
        *e = 0;
        if(bz2_decode(filename, xfilename, err) != 0)
        {
            free(xfilename);
            return ((void *)0);
        }
    }
    if(str_has_suffix(xfilename, ".xml"))
        hlist = hl_parse_file_xml(xfilename, err);
    else
        hlist = hl_parse_file_config(xfilename, err);
    free(xfilename);
    return hlist;
}

canonical_original_code:
struct hublist *hl_parse_file(char *filename, struct xerr **err)
{
    struct hublist *hlist = 0;
    ((void) sizeof ((filename) ? 1 : 0), __extension__ ({ if (filename) ; else __assert_fail ("filename", "hublist.c", 277, __extension__ __PRETTY_FUNCTION__); }));
    char *xfilename = strdup(filename);
    if(str_has_suffix(xfilename, ".bz2"))
    {
        char *e = strrchr(xfilename, '.');
        ((void) sizeof ((e) ? 1 : 0), __extension__ ({ if (e) ; else __assert_fail ("e", "hublist.c", 283, __extension__ __PRETTY_FUNCTION__); }));
        *e = 0;
        if(bz2_decode(filename, xfilename, err) != 0)
        {
            free(xfilename);
            return ((void *)0);
        }
    }
    if(str_has_suffix(xfilename, ".xml"))
        hlist = hl_parse_file_xml(xfilename, err);
    else
        hlist = hl_parse_file_config(xfilename, err);
    free(xfilename);
    return hlist;
}

variable_types:
filename
char *

variable_types: struct xerr { int code; char *message; } **

variable_types:
xfilename
char *

variable_types:
e
char *

return_type: struct hublist { struct hublist_hub { struct { struct hublist_hub *le_next; struct hublist_hub **le_prev; } link; char *name; char *address; char *description; unsigned int max_users; unsigned int current_users; unsigned int reliability; char *country; int min_slots; int max_hubs; unsigned long min_share; } *lh_first; } *


repo: rufuscoder/Shakespeer

decompiled_code:
const char *__fastcall hl_parse_url(char *s, const char *a2, __int64 a3)
{
__int64 v4; // rbp
unsigned __int64 v5; // r12
unsigned int v7; // eax
char *ptr; // [rsp+8h] [rbp-30h] BYREF

v4 = uhttp_init();
if ( (unsigned int)uhttp_open_url(v4, s) )
{
xerr_set(a3, 0xFFFFFFFFLL, "failed to fetch hublist file");
v5 = 0LL;
}
else
{
v5 = (unsigned __int64)strrchr(s, 47);
if ( !v5 )
{
xerr_set(a3, 0xFFFFFFFFLL, "invalid address: %s", s);
return (const char *)v5;
}
uhttp_get(v4);
if ( (unsigned int)uhttp_read_response_headers(v4) == 200 )
{
if ( asprintf(&ptr, "%s/%s", a2, (const char *)(v5 + 1)) == -1 )
{
v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v7, "hl_parse_url", 323LL);
}
v5 = 0LL;
if ( !(unsigned int)uhttp_read_response_file(v4, ptr) )
{
v5 = (unsigned __int64)hl_parse_file(ptr, a3);
a3 |= v5;
}
free(ptr);
}
else
{
xerr_set(a3, 0xFFFFFFFFLL, "failed to fetch hublist file");
v5 = 0LL;
}
uhttp_cleanup(v4);
}
if ( !a3 )
_assert_fail("err || result", "hublist.c", 0x150u, "hl_parse_url");
return (const char *)v5;
}

canonical_decompiled_code:
const char *__fastcall func7(char *s, const char *a2, __int64 a3)
{
__int64 v4; // rbp
unsigned __int64 v5; // r12
unsigned int v7; // eax
char *ptr; // [rsp+8h] [rbp-30h] BYREF

v4 = uhttp_init();
if ( (unsigned int)uhttp_open_url(v4, s) )
{
xerr_set(a3, 0xFFFFFFFFLL, "failed to fetch hublist file");
v5 = 0LL;
}
else
{
v5 = (unsigned __int64)strrchr(s, 47);
if ( !v5 )
{
xerr_set(a3, 0xFFFFFFFFLL, "invalid address: %s", s);
return (const char *)v5;
}
uhttp_get(v4);
if ( (unsigned int)uhttp_read_response_headers(v4) == 200 )
{
if ( asprintf(&ptr, "%s/%s", a2, (const char *)(v5 + 1)) == -1 )
{
v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v7, "hl_parse_url", 323LL);
}
v5 = 0LL;
if ( !(unsigned int)uhttp_read_response_file(v4, ptr) )
{
v5 = (unsigned __int64)func6(ptr, a3);
a3 |= v5;
}
free(ptr);
}
else
{
xerr_set(a3, 0xFFFFFFFFLL, "failed to fetch hublist file");
v5 = 0LL;
}
uhttp_cleanup(v4);
}
if ( !a3 )
_assert_fail("err || result", "hublist.c", 0x150u, "hl_parse_url");
return (const char *)v5;
}

original_code:
hublist_t *hl_parse_url(const char *address, const char *workdir, xerr_t **err)
{
    uhttp_t *uhttp;
    hublist_t *result = 0;
    uhttp = uhttp_init();
    if (uhttp_open_url(uhttp, address) == 0) {
        char *slash;
        slash = strrchr(address, '/');
        if (slash == 0) {
            xerr_set(err, -1, "invalid address: %s", address);
            return ((void *)0);
        }
        uhttp_get(uhttp);
        int rc = uhttp_read_response_headers(uhttp);
        if (rc == 200) {
            char *ofname;
            int num_returned_bytes = asprintf(&ofname, "%s/%s", workdir, slash + 1);
            if (num_returned_bytes == -1)
                sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 323);
            if (uhttp_read_response_file(uhttp, ofname) == 0)
                result = hl_parse_file(ofname, err);
            free(ofname);
        }
        else
            xerr_set(err, -1, "failed to fetch hublist file");
        uhttp_cleanup(uhttp);
    }
    else
        xerr_set(err, -1, "failed to fetch hublist file");
    ((void) sizeof ((err || result) ? 1 : 0), __extension__ ({ if (err || result) ; else __assert_fail ("err || result", "hublist.c", 336, __extension__ __PRETTY_FUNCTION__); }));
    return result;
}

canonical_original_code:
struct hublist *hl_parse_url(char *address, char *workdir, struct xerr **err)
{
    struct uhttp *uhttp;
    struct hublist *result = 0;
    uhttp = uhttp_init();
    if (uhttp_open_url(uhttp, address) == 0) {
        char *slash;
        slash = strrchr(address, '/');
        if (slash == 0) {
            xerr_set(err, -1, "invalid address: %s", address);
            return ((void *)0);
        }
        uhttp_get(uhttp);
        int rc = uhttp_read_response_headers(uhttp);
        if (rc == 200) {
            char *ofname;
            int num_returned_bytes = asprintf(&ofname, "%s/%s", workdir, slash + 1);
            if (num_returned_bytes == -1)
                sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 323);
            if (uhttp_read_response_file(uhttp, ofname) == 0)
                result = hl_parse_file(ofname, err);
            free(ofname);
        }
        else
            xerr_set(err, -1, "failed to fetch hublist file");
        uhttp_cleanup(uhttp);
    }
    else
        xerr_set(err, -1, "failed to fetch hublist file");
    ((void) sizeof ((err || result) ? 1 : 0), __extension__ ({ if (err || result) ; else __assert_fail ("err || result", "hublist.c", 336, __extension__ __PRETTY_FUNCTION__); }));
    return result;
}

variable_types:
address
char *

variable_types:
workdir
char *

variable_types: struct uhttp { int fd; struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; } raddr; struct sockaddr_in laddr; char *hostname; char *directory; int port; unsigned int nheaders; char **headers; int chunked_encoding; unsigned int content_length; int headers_sent; } *

variable_types: struct hublist { struct hublist_hub { struct { struct hublist_hub *le_next; struct hublist_hub **le_prev; } link; char *name; char *address; char *description; unsigned int max_users; unsigned int current_users; unsigned int reliability; char *country; int min_slots; int max_hubs; unsigned long min_share; } *lh_first; } *

variable_types:
slash
char *

variable_types: rc int

variable_types:
ofname
char *

user_defined_types: struct uhttp { int fd; struct sockaddr_in raddr; struct sockaddr_in laddr; char *hostname; char *directory; int port; unsigned int nheaders; char **headers; int chunked_encoding; unsigned int content_length; int headers_sent; }

user_defined_types: struct hublist { struct hublist_hub *lh_first; }

user_defined_types: struct xerr { int code; char *message; }

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


decompiled_code:
char *hl_get_current()
{
char *v0; // rbp
unsigned int v2; // eax
unsigned int v3; // eax
char *ptr[2]; // [rsp+8h] [rbp-10h] BYREF

v0 = (char *)get_working_directory();
if ( asprintf(ptr, "%s/PublicHubList.xml.bz2", v0) == -1 )
{
v2 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v2, "hl_get_current", 348LL);
}
if ( access(ptr[0], 0) )
{
free(ptr[0]);
if ( asprintf(ptr, "%s/PublicHubList.config.bz2", v0) == -1 )
{
v3 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v3, "hl_get_current", 353LL);
}
if ( access(ptr[0], 0) )
{
free(ptr[0]);
ptr[0] = 0LL;
}
}
free(v0);
return ptr[0];
}

canonical_decompiled_code:
char *func8()
{
char *v0; // rbp
unsigned int v2; // eax
unsigned int v3; // eax
char *ptr[2]; // [rsp+8h] [rbp-10h] BYREF

v0 = (char *)get_working_directory();
if ( asprintf(ptr, "%s/PublicHubList.xml.bz2", v0) == -1 )
{
v2 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v2, "hl_get_current", 348LL);
}
if ( access(ptr[0], 0) )
{
free(ptr[0]);
if ( asprintf(ptr, "%s/PublicHubList.config.bz2", v0) == -1 )
{
v3 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v3, "hl_get_current", 353LL);
}
if ( access(ptr[0], 0) )
{
free(ptr[0]);
ptr[0] = 0LL;
}
}
free(v0);
return ptr[0];
}

original_code:
char *hl_get_current(void)
{
    char *working_directory = get_working_directory();
    char *hublist_filename;
    int num_returned_bytes;
    num_returned_bytes = asprintf(&hublist_filename, "%s/PublicHubList.xml.bz2", working_directory);
    if (num_returned_bytes == -1)
        sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 348);
    if (access(hublist_filename, 0) != 0) {
        free(hublist_filename);
        num_returned_bytes = asprintf(&hublist_filename, "%s/PublicHubList.config.bz2", working_directory);
        if (num_returned_bytes == -1)
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 353);
        if (access(hublist_filename, 0) != 0) {
            free(hublist_filename);
            hublist_filename = ((void *)0);
        }
    }
    free(working_directory);
    return hublist_filename;
}

canonical_original_code:
char *hl_get_current()
{
    char *working_directory = get_working_directory();
    char *hublist_filename;
    int num_returned_bytes;
    num_returned_bytes = asprintf(&hublist_filename, "%s/PublicHubList.xml.bz2", working_directory);
    if (num_returned_bytes == -1)
        sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 348);
    if (access(hublist_filename, 0) != 0) {
        free(hublist_filename);
        num_returned_bytes = asprintf(&hublist_filename, "%s/PublicHubList.config.bz2", working_directory);
        if (num_returned_bytes == -1)
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 353);
        if (access(hublist_filename, 0) != 0) {
            free(hublist_filename);
            hublist_filename = ((void *)0);
        }
    }
    free(working_directory);
    return hublist_filename;
}

return_type: char *


decompiled_code:
__int64 __fastcall find_level(char *a1)
{
char v1; // al
unsigned int i; // er8

v1 = *a1;
for ( i = 0; *a1; v1 = *a1 )
{
++a1;
i += v1 == 47;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *a1)
{
char v1; // al
unsigned int i; // er8

v1 = *a1;
for ( i = 0; *a1; v1 = *a1 )
{
++a1;
i += v1 == 47;
}
return i;
}

original_code:
static int find_level(const char *filename)
{
    int level = 0;
    const char *e = filename;
    for(; *e; e++)
    {
        if(*e == '/')
            ++level;
    }
    return level;
}

canonical_original_code:
static int find_level(char *filename)
{
    int level = 0;
    char *e = filename;
    for(; *e; e++)
    {
        if(*e == '/')
            ++level;
    }
    return level;
}

variable_types: level int

return_type: int


decompiled_code:
__int64 __fastcall share_xml_escape(_BYTE *a1)
{
_BYTE *v1; // rbx
__int64 v2; // rax
char v3; // si
__int64 v4; // rbp
const char *v5; // rsi

if ( a1 )
{
v1 = a1;
v2 = dstring_new(0LL);
v3 = *a1;
v4 = v2;
if ( !*a1 )
return dstring_free(v4, 0LL);
while ( 1 )
{
switch ( v3 )
{
case '<':
v5 = "<";
break;
case '>':
v5 = ">";
break;
case '&':
v5 = "&";
break;
case '\'':
v5 = "'";
break;
case '"':
v5 = """;
break;
default:
dstring_append_char(v4);
goto LABEL_9;
}
dstring_append(v4, v5);
LABEL_9:
v3 = *++v1;
if ( !v3 )
return dstring_free(v4, 0LL);
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(_BYTE *a1)
{
_BYTE *v1; // rbx
__int64 v2; // rax
char v3; // si
__int64 v4; // rbp
const char *v5; // rsi

if ( a1 )
{
v1 = a1;
v2 = dstring_new(0LL);
v3 = *a1;
v4 = v2;
if ( !*a1 )
return dstring_free(v4, 0LL);
while ( 1 )
{
switch ( v3 )
{
case '<':
v5 = "<";
break;
case '>':
v5 = ">";
break;
case '&':
v5 = "&";
break;
case '\'':
v5 = "'";
break;
case '"':
v5 = """;
break;
default:
dstring_append_char(v4);
goto LABEL_9;
}
dstring_append(v4, v5);
LABEL_9:
v3 = *++v1;
if ( !v3 )
return dstring_free(v4, 0LL);
}
}
return 0LL;
}

original_code:
static char *share_xml_escape(const char *string)
{
    if(string == ((void *)0))
        return ((void *)0);
    const char *p = string;
    dstring_t *ds = dstring_new(((void *)0));
    while(*p)
    {
        char c = *p;
        char *esc = 0;
        if(c == '<')
            esc = "<";
        else if(c == '>')
            esc = ">";
        else if(c == '&')
            esc = "&";
        else if(c == '\'')
            esc = "'";
        else if(c == '"')
            esc = """;
        if(esc)
            dstring_append(ds, esc);
        else
            dstring_append_char(ds, c);
        p++;
    }
    return dstring_free(ds, 0);
}

canonical_original_code:
static char *share_xml_escape(char *string)
{
    if(string == ((void *)0))
        return ((void *)0);
    char *p = string;
    struct dstring *ds = dstring_new(((void *)0));
    while(*p)
    {
        char c = *p;
        char *esc = 0;
        if(c == '<')
            esc = "<";
        else if(c == '>')
            esc = ">";
        else if(c == '&')
            esc = "&";
        else if(c == '\'')
            esc = "'";
        else if(c == '"')
            esc = """;
        if(esc)
            dstring_append(ds, esc);
        else
            dstring_append_char(ds, c);
        p++;
    }
    return dstring_free(ds, 0);
}

variable_types:
string
char *

variable_types:
p
char *

variable_types: struct dstring { unsigned int length; unsigned int allocated; char *string; } *

variable_types: c char

variable_types:
esc
char *


decompiled_code:
__int64 __fastcall find_common_prefix(char *s, char *a2)
{
char *v2; // r13
char *v3; // r12
size_t v4; // rbx
char *v5; // rbx
char *v6; // rax
size_t v7; // rbx

if ( !a2 )
return 0LL;
if ( !*s )
return 0LL;
v2 = a2;
v3 = s;
do
{
v5 = strchr(v3, 47);
v6 = strchr(v2, 47);
if ( !v5 )
break;
if ( !v6 )
break;
v7 = v5 - v3;
if ( v7 != v6 - v2 )
break;
if ( strncmp(v3, v2, v7) )
break;
v4 = v7 + 1;
v3 += v4;
v2 += v4;
}
while ( *v3 );
return (unsigned int)((_DWORD)v3 - (_DWORD)s);
}

canonical_decompiled_code:
__int64 __fastcall func6(char *s, char *a2)
{
char *v2; // r13
char *v3; // r12
size_t v4; // rbx
char *v5; // rbx
char *v6; // rax
size_t v7; // rbx

if ( !a2 )
return 0LL;
if ( !*s )
return 0LL;
v2 = a2;
v3 = s;
do
{
v5 = strchr(v3, 47);
v6 = strchr(v2, 47);
if ( !v5 )
break;
if ( !v6 )
break;
v7 = v5 - v3;
if ( v7 != v6 - v2 )
break;
if ( strncmp(v3, v2, v7) )
break;
v4 = v7 + 1;
v3 += v4;
v2 += v4;
}
while ( *v3 );
return (unsigned int)((_DWORD)v3 - (_DWORD)s);
}

original_code:
static int find_common_prefix(const char *p, const char *pp)
{
    if(pp == ((void *)0))
        return 0;
    const char *orig_p = p;
    while(*p)
    {
        const char *slash_p = strchr(p, '/');
        const char *slash_pp = strchr(pp, '/');
        if(slash_p == ((void *)0) || slash_pp == ((void *)0))
            break;
        size_t len = slash_p - p;
        if(len != slash_pp - pp)
            break;
        if(strncmp(p, pp, len) != 0)
            break;
        p += len + 1;
        pp += len + 1;
    }
    return p - orig_p;
}

canonical_original_code:
static int find_common_prefix(char *p, char *pp)
{
    if(pp == ((void *)0))
        return 0;
    char *orig_p = p;
    while(*p)
    {
        char *slash_p = strchr(p, '/');
        char *slash_pp = strchr(pp, '/');
        if(slash_p == ((void *)0) || slash_pp == ((void *)0))
            break;
        unsigned long len = slash_p - p;
        if(len != slash_pp - pp)
            break;
        if(strncmp(p, pp, len) != 0)
            break;
        p += len + 1;
        pp += len + 1;
    }
    return p - orig_p;
}

variable_types:
pp
char *

variable_types:
len
unsigned long


decompiled_code:
__int64 __fastcall share_save(__int64 a1, int a2)
{
char v2; // bp
unsigned int v3; // er12
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
char *ptr; // [rsp+8h] [rbp-20h] BYREF

if ( a1 )
{
if ( a2 == 2 )
{
if ( asprintf(&ptr, "%s/files.xml", global_working_directory) == -1 )
{
v6 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v6, "share_save", 328LL);
}
v2 = *(_BYTE *)(a1 + 8);
if ( !v2 || access(ptr, 0) == -1 )
{
v3 = share_save_xml_constprop_0(a1, ptr);
v2 = v3 == 0;
}
else
{
v5 = getpid();
v3 = 0;
sp_log(64LL, "[%d] (%s:%i) share up to date and file exists, skipping saving xml file", v5, "share_save", 332LL);
}
free(ptr);
*(_BYTE *)(a1 + 8) = v2;
}
else
{
v7 = getpid();
v3 = -1;
sp_log(16LL, "[%d] (%s:%i) assert failed: type == FILELIST_XML", v7, "share_save", 322LL);
}
}
else
{
v8 = getpid();
v3 = -1;
sp_log(16LL, "[%d] (%s:%i) assert failed: share", v8, "share_save", 321LL);
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, int a2)
{
char v2; // bp
unsigned int v3; // er12
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
char *ptr; // [rsp+8h] [rbp-20h] BYREF

if ( a1 )
{
if ( a2 == 2 )
{
if ( asprintf(&ptr, "%s/files.xml", global_working_directory) == -1 )
{
v6 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v6, "share_save", 328LL);
}
v2 = *(_BYTE *)(a1 + 8);
if ( !v2 || access(ptr, 0) == -1 )
{
v3 = func8(a1, ptr);
v2 = v3 == 0;
}
else
{
v5 = getpid();
v3 = 0;
sp_log(64LL, "[%d] (%s:%i) share up to date and file exists, skipping saving xml file", v5, "share_save", 332LL);
}
free(ptr);
*(_BYTE *)(a1 + 8) = v2;
}
else
{
v7 = getpid();
v3 = -1;
sp_log(16LL, "[%d] (%s:%i) assert failed: type == FILELIST_XML", v7, "share_save", 322LL);
}
}
else
{
v8 = getpid();
v3 = -1;
sp_log(16LL, "[%d] (%s:%i) assert failed: share", v8, "share_save", 321LL);
}
return v3;
}

original_code:
int share_save(share_t *share, unsigned type)
{
    int rc = 0;
    do { if(!(share)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "share", getpid(), __func__, 321); return (-1); } } while(0);
    do { if(!(type == 2)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "type == FILELIST_XML", getpid(), __func__, 322); return (-1); } } while(0);
    if ((type & 2) == 2) {
        char *xml_filename;
        int num_returned_bytes = asprintf(&xml_filename, "%s/files.xml", global_working_directory);
        if (num_returned_bytes == -1)
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 328);
        if (!share->uptodate || access(xml_filename, 0) == -1)
            rc = share_save_xml(share, xml_filename, ((void *)0));
        else
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "share up to date and file exists, skipping saving xml file", getpid(), __func__, 332);
        free(xml_filename);
    }
    share->uptodate = (rc == 0 ? 1 : 0);
    return rc;
}

canonical_original_code:
int share_save(struct share *share, unsigned int type)
{
    int rc = 0;
    do { if(!(share)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "share", getpid(), __func__, 321); return (-1); } } while(0);
    do { if(!(type == 2)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "type == FILELIST_XML", getpid(), __func__, 322); return (-1); } } while(0);
    if ((type & 2) == 2) {
        char *xml_filename;
        int num_returned_bytes = asprintf(&xml_filename, "%s/files.xml", global_working_directory);
        if (num_returned_bytes == -1)
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 328);
        if (!share->uptodate || access(xml_filename, 0) == -1)
            rc = share_save_xml(share, xml_filename, ((void *)0));
        else
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "share up to date and file exists, skipping saving xml file", getpid(), __func__, 332);
        free(xml_filename);
    }
    share->uptodate = (rc == 0 ? 1 : 0);
    return rc;
}

variable_types: struct share { struct { struct share_mountpoint { struct { struct share_mountpoint *le_next; struct share_mountpoint **le_prev; } link; char *local_root; char *virtual_root; struct share_stats { unsigned long size; unsigned long totsize; unsigned long dupsize; unsigned int nfiles; unsigned int ntotfiles; unsigned int nduplicates; } stats; _Bool scan_in_progress; _Bool removed; } *lh_first; } mountpoints; _Bool uptodate; int scanning; struct bloom { unsigned int length; unsigned char *filter; unsigned int collisions; } *bloom; char *cid; unsigned int listlen; struct file_tree { struct share_file { struct { struct share_file *rbe_left; struct share_file *rbe_right; struct share_file *rbe_parent; int rbe_color; } entry; struct { struct share_file *le_next; struct share_file **le_prev; } inode_link; struct { struct share_file *sle_next; } link; struct share_mountpoint *mp; char *partial_path; enum share_type { SHARE_TYPE_ANY=1, SHARE_TYPE_AUDIO=2, SHARE_TYPE_COMPRESSED=3, SHARE_TYPE_DOCUMENT=4, SHARE_TYPE_EXECUTABLE=5, SHARE_TYPE_IMAGE=6, SHARE_TYPE_MOVIE=7, SHARE_TYPE_DIRECTORY=8, SHARE_TYPE_TTH=9 } type; unsigned long size; unsigned long inode; } *rbh_root; } files; struct file_tree unhashed_files; struct { struct share_file *lh_first; } inodes[509]; } *

variable_types:
type
unsigned int

user_defined_types: struct share { struct { struct share_mountpoint *lh_first; } mountpoints; _Bool uptodate; int scanning; struct bloom *bloom; char *cid; unsigned int listlen; struct file_tree files; struct file_tree unhashed_files; struct { struct share_file *lh_first; } inodes[509]; }

user_defined_types: struct file_tree { struct share_file *rbh_root; }

user_defined_types: struct share_mountpoint { struct { struct share_mountpoint *le_next; struct share_mountpoint **le_prev; } link; char *local_root; char *virtual_root; struct share_stats stats; _Bool scan_in_progress; _Bool removed; }

user_defined_types: struct share_file { struct { struct share_file *rbe_left; struct share_file *rbe_right; struct share_file *rbe_parent; int rbe_color; } entry; struct { struct share_file *le_next; struct share_file **le_prev; } inode_link; struct { struct share_file *sle_next; } link; struct share_mountpoint *mp; char *partial_path; enum share_type type; unsigned long size; unsigned long inode; }


decompiled_code:
__int64 __fastcall hub_set_slots(int a1, char a2)
{
__int64 v2; // r12
const char *v3; // r13
unsigned int v4; // eax
__int64 result; // rax
int v6; // er12
unsigned int v7; // eax

if ( a1 <= 0 )
{
v7 = getpid();
result = sp_log(16LL, "[%d] (%s:%i) assert failed: slots > 0", v7, "hub_set_slots", 87LL);
}
else
{
if ( a2 )
{
v3 = " per hub";
v6 = hub_count_normal();
v2 = a1 * ((unsigned int)hub_count_registered() + v6);
total_slots = v2;
}
else
{
total_slots = a1;
v2 = (unsigned int)a1;
v3 = (const char *)&unk_537;
}
v4 = getpid();
sp_log(32LL, "[%d] (%s:%i) setting slots = %d%s (%i totally)", v4, "hub_set_slots", 93LL, (unsigned int)a1, v3, v2);
configured_slots = a1;
per_hub_flag = a2;
result = hub_set_need_myinfo_update(1LL);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, char a2)
{
__int64 v2; // r12
const char *v3; // r13
unsigned int v4; // eax
__int64 result; // rax
int v6; // er12
unsigned int v7; // eax

if ( a1 <= 0 )
{
v7 = getpid();
result = sp_log(16LL, "[%d] (%s:%i) assert failed: slots > 0", v7, "hub_set_slots", 87LL);
}
else
{
if ( a2 )
{
v3 = " per hub";
v6 = hub_count_normal();
v2 = a1 * ((unsigned int)hub_count_registered() + v6);
total_slots = v2;
}
else
{
total_slots = a1;
v2 = (unsigned int)a1;
v3 = (const char *)&unk_537;
}
v4 = getpid();
sp_log(32LL, "[%d] (%s:%i) setting slots = %d%s (%i totally)", v4, "hub_set_slots", 93LL, (unsigned int)a1, v3, v2);
configured_slots = a1;
per_hub_flag = a2;
result = hub_set_need_myinfo_update(1LL);
}
return result;
}

original_code:
void hub_set_slots(int slots, _Bool per_hub)
{
    do { if(!(slots > 0)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "slots > 0", getpid(), __func__, 87); return; } } while(0);
    if(per_hub)
     total_slots = slots * (hub_count_normal() + hub_count_registered());
    else
     total_slots = slots;
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "setting slots = %d%s (%i totally)", getpid(), __func__, 93, slots, per_hub ? " per hub" : "", total_slots);
    configured_slots = slots;
    per_hub_flag = per_hub;
    hub_set_need_myinfo_update(1);
}

variable_types: slots int

return_type: void


decompiled_code:
__int64 hub_update_slots()
{
return hub_set_slots(configured_slots, per_hub_flag);
}

canonical_decompiled_code:
__int64 func3()
{
return func2(configured_slots, per_hub_flag);
}

original_code:
void hub_update_slots(void)
{
    hub_set_slots(configured_slots, per_hub_flag);
}

canonical_original_code:
void hub_update_slots()
{
    hub_set_slots(configured_slots, per_hub_flag);
}


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

result = (unsigned int)(total_slots - used_slots);
if ( total_slots - used_slots < 0 )
result = 0LL;
return result;
}

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

result = (unsigned int)(total_slots - used_slots);
if ( total_slots - used_slots < 0 )
result = 0LL;
return result;
}

original_code:
int hub_slots_free(void)
{
    int d = total_slots - used_slots;
    if(d < 0)
 d = 0;
    return d;
}

canonical_original_code:
int hub_slots_free()
{
    int d = total_slots - used_slots;
    if(d < 0)
 d = 0;
    return d;
}

variable_types: d int


decompiled_code:
__int64 hub_slots_total()
{
return (unsigned int)total_slots;
}

canonical_decompiled_code:
__int64 func5()
{
return (unsigned int)total_slots;
}

original_code:
int hub_slots_total(void)
{
    return total_slots;
}

canonical_original_code:
int hub_slots_total()
{
    return total_slots;
}


original_code:
int base32_encode_length(int rawLength)
{
    return ((rawLength * 8) / 5) + ((rawLength % 5) != 0) + 1;
}

variable_types: rawLength int


decompiled_code:
__int64 __fastcall base32_decode_length(int a1)
{
int v1; // eax

v1 = 5 * a1 + 7;
if ( 5 * a1 >= 0 )
v1 = 5 * a1;
return (unsigned int)(v1 >> 3);
}

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

v1 = 5 * a1 + 7;
if ( 5 * a1 >= 0 )
v1 = 5 * a1;
return (unsigned int)(v1 >> 3);
}

original_code:
int base32_decode_length(int base32Length)
{
    return ((base32Length * 5) / 8);
}


original_code:
int base32_decode_into(const char *base32Buffer, unsigned int base32BufLen, void *_buffer)
{
    int i, index, max, lookup, offset;
    unsigned char word;
    unsigned char *buffer = _buffer;
    memset(buffer, 0, base32_decode_length(base32BufLen));
    max = strlen(base32Buffer);
    for(i = 0, index = 0, offset = 0; i < max; i++)
    {
        lookup = toupper(base32Buffer[i]) - '0';
        if ( lookup < 0 && lookup >= 43)
            word = 0xFF;
        else
            word = base32Lookup[lookup][1];
        if (word == 0xFF)
            continue;
        if (index <= 3)
        {
            index = (index + 5) % 8;
            if (index == 0)
            {
                buffer[offset] |= word;
                offset++;
            }
            else
                buffer[offset] |= word << (8 - index);
        }
        else
        {
            index = (index + 5) % 8;
            buffer[offset] |= (word >> index);
            offset++;
            buffer[offset] |= word << (8 - index);
        }
    }
    return offset;
}

canonical_original_code:
int base32_decode_into(char *base32Buffer, unsigned int base32BufLen, void *_buffer)
{
    int i; int index; int max; int lookup; int offset;
    unsigned char word;
    unsigned char *buffer = _buffer;
    memset(buffer, 0, base32_decode_length(base32BufLen));
    max = strlen(base32Buffer);
    for(i = 0, index = 0, offset = 0; i < max; i++)
    {
        lookup = toupper(base32Buffer[i]) - '0';
        if ( lookup < 0 && lookup >= 43)
            word = 0xFF;
        else
            word = base32Lookup[lookup][1];
        if (word == 0xFF)
            continue;
        if (index <= 3)
        {
            index = (index + 5) % 8;
            if (index == 0)
            {
                buffer[offset] |= word;
                offset++;
            }
            else
                buffer[offset] |= word << (8 - index);
        }
        else
        {
            index = (index + 5) % 8;
            buffer[offset] |= (word >> index);
            offset++;
            buffer[offset] |= word << (8 - index);
        }
    }
    return offset;
}

variable_types: i int

variable_types: index int

variable_types: max int

variable_types: lookup int

variable_types: offset int

variable_types:
word
unsigned char

variable_types:
buffer
unsigned char *


decompiled_code:
char *__fastcall base32_decode(char *s, _DWORD *a2)
{
int v2; // ebx
int v3; // eax
char *v4; // r12
int v5; // eax

v2 = strlen(s);
v3 = base32_decode_length(v2);
v4 = (char *)malloc(v3);
v5 = base32_decode_into(s, v2, v4);
if ( a2 )
*a2 = v5;
return v4;
}

canonical_decompiled_code:
char *__fastcall func4(char *s, _DWORD *a2)
{
int v2; // ebx
int v3; // eax
char *v4; // r12
int v5; // eax

v2 = strlen(s);
v3 = func1(v2);
v4 = (char *)malloc(v3);
v5 = func3(s, v2, v4);
if ( a2 )
*a2 = v5;
return v4;
}

original_code:
void *base32_decode(const char *buf, unsigned int *outlen)
{
    unsigned int len = strlen(buf);
    char *tmp = malloc(base32_decode_length(len));
    unsigned int x = base32_decode_into(buf, len, tmp);
    if(outlen)
        *outlen = x;
    return tmp;
}

canonical_original_code:
void *base32_decode(char *buf, unsigned int *outlen)
{
    unsigned int len = strlen(buf);
    char *tmp = malloc(base32_decode_length(len));
    unsigned int x = base32_decode_into(buf, len, tmp);
    if(outlen)
        *outlen = x;
    return tmp;
}

variable_types:
buf
char *

variable_types:
outlen
unsigned int *

variable_types:
len
unsigned int

variable_types:
tmp
char *

variable_types:
x
unsigned int

return_type: void *


decompiled_code:
__int64 __fastcall arg_add_token(int *a1, const char *a2, unsigned int a3)
{
size_t v3; // rbp
_QWORD *v4; // rax
_QWORD *v5; // r13
__int64 v6; // rdx
__int64 result; // rax
char *v8; // rax
char **v9; // r13

v3 = a3;
v4 = realloc(*((void **)a1 + 1), 8LL * (*a1 + 1));
*((_QWORD *)a1 + 1) = v4;
v5 = v4;
if ( (_DWORD)v3 )
{
v8 = (char *)malloc((unsigned int)(v3 + 1));
v9 = (char **)&v5[*a1];
*v9 = v8;
strncpy(v8, a2, v3);
(*v9)[v3] = 0;
result = (unsigned int)(*a1 + 1);
}
else
{
v6 = *a1;
v4[v6] = 0LL;
result = (unsigned int)(v6 + 1);
}
*a1 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int *a1, const char *a2, unsigned int a3)
{
size_t v3; // rbp
_QWORD *v4; // rax
_QWORD *v5; // r13
__int64 v6; // rdx
__int64 result; // rax
char *v8; // rax
char **v9; // r13

v3 = a3;
v4 = realloc(*((void **)a1 + 1), 8LL * (*a1 + 1));
*((_QWORD *)a1 + 1) = v4;
v5 = v4;
if ( (_DWORD)v3 )
{
v8 = (char *)malloc((unsigned int)(v3 + 1));
v9 = (char **)&v5[*a1];
*v9 = v8;
strncpy(v8, a2, v3);
(*v9)[v3] = 0;
result = (unsigned int)(*a1 + 1);
}
else
{
v6 = *a1;
v4[v6] = 0LL;
result = (unsigned int)(v6 + 1);
}
*a1 = result;
return result;
}

original_code:
static void arg_add_token(arg_t *args, const char *token, unsigned int len)
{
    args->argv = (char **)realloc(args->argv, (args->argc + 1) * sizeof(char *));
    args->argv[args->argc] = len ? malloc(len + 1) : ((void *)0);
    if(len)
    {
        strncpy(args->argv[args->argc], token, len);
        args->argv[args->argc][len] = 0;
    }
    args->argc++;
}

canonical_original_code:
static void arg_add_token(struct arg_t *args, char *token, unsigned int len)
{
    args->argv = (char **)realloc(args->argv, (args->argc + 1) * sizeof(char *));
    args->argv[args->argc] = len ? malloc(len + 1) : ((void *)0);
    if(len)
    {
        strncpy(args->argv[args->argc], token, len);
        args->argv[args->argc][len] = 0;
    }
    args->argc++;
}

variable_types: struct arg_t { int argc; char **argv; } *

variable_types:
token
char *


decompiled_code:
int *__fastcall arg_create_max(char *s, char *reject, int a3, int a4)
{
char *v4; // rbx
int *v7; // r13
size_t v8; // rax
size_t v10; // [rsp+8h] [rbp-40h]

if ( !reject )
return 0LL;
v4 = s;
if ( !s )
return 0LL;
v7 = (int *)calloc(1uLL, 0x10uLL);
if ( !a3 )
v4 = &s[strspn(s, reject)];
LABEL_5:
if ( a4 < 0 )
goto LABEL_11;
LABEL_6:
if ( *v7 + 1 < a4 )
{
LABEL_11:
while ( 1 )
{
v8 = strcspn(v4, reject);
if ( !v8 )
break;
LABEL_12:
v10 = v8;
arg_add_token(v7, v4, v8);
v4 += v10;
if ( !*v4 )
return v7;
if ( a3 )
{
++v4;
goto LABEL_5;
}
LABEL_10:
v4 += strspn(v4, reject);
if ( a4 >= 0 )
goto LABEL_6;
}
}
else
{
v8 = strlen(v4);
if ( v8 )
goto LABEL_12;
}
if ( a3 )
goto LABEL_12;
if ( *v4 )
goto LABEL_10;
return v7;
}

canonical_decompiled_code:
int *__fastcall func1(char *s, char *reject, int a3, int a4)
{
char *v4; // rbx
int *v7; // r13
size_t v8; // rax
size_t v10; // [rsp+8h] [rbp-40h]

if ( !reject )
return 0LL;
v4 = s;
if ( !s )
return 0LL;
v7 = (int *)calloc(1uLL, 0x10uLL);
if ( !a3 )
v4 = &s[strspn(s, reject)];
LABEL_5:
if ( a4 < 0 )
goto LABEL_11;
LABEL_6:
if ( *v7 + 1 < a4 )
{
LABEL_11:
while ( 1 )
{
v8 = strcspn(v4, reject);
if ( !v8 )
break;
LABEL_12:
v10 = v8;
func0(v7, v4, v8);
v4 += v10;
if ( !*v4 )
return v7;
if ( a3 )
{
++v4;
goto LABEL_5;
}
LABEL_10:
v4 += strspn(v4, reject);
if ( a4 >= 0 )
goto LABEL_6;
}
}
else
{
v8 = strlen(v4);
if ( v8 )
goto LABEL_12;
}
if ( a3 )
goto LABEL_12;
if ( *v4 )
goto LABEL_10;
return v7;
}

original_code:
arg_t *arg_create_max(const char *str, const char *sep,
        int allow_null_fields, int max_args)
{
    const char *token = str;
    if(sep == ((void *)0) || str == ((void *)0))
    {
        return ((void *)0);
    }
    arg_t *args = calloc(1, sizeof(arg_t));
    if(!allow_null_fields)
    {
        token += strspn(token, sep);
    }
    while(token)
    {
        size_t len;
        if(max_args >= 0 && args->argc + 1 >= max_args)
        {
            len = strlen(token);
        }
        else
        {
            len = strcspn(token, sep);
        }
        if(len || allow_null_fields)
        {
            arg_add_token(args, token, len);
            token += len;
        }
        if(*token == 0)
        {
            break;
        }
        if(allow_null_fields)
        {
            ++token;
        }
        else
        {
            token += strspn(token, sep);
        }
    }
    return args;
}

canonical_original_code:
struct arg_t *arg_create_max(char *str, char *sep, int allow_null_fields, int max_args)
{
    char *token = str;
    if(sep == ((void *)0) || str == ((void *)0))
    {
        return ((void *)0);
    }
    struct arg_t *args = calloc(1, sizeof(arg_t));
    if(!allow_null_fields)
    {
        token += strspn(token, sep);
    }
    while(token)
    {
        unsigned long len;
        if(max_args >= 0 && args->argc + 1 >= max_args)
        {
            len = strlen(token);
        }
        else
        {
            len = strcspn(token, sep);
        }
        if(len || allow_null_fields)
        {
            arg_add_token(args, token, len);
            token += len;
        }
        if(*token == 0)
        {
            break;
        }
        if(allow_null_fields)
        {
            ++token;
        }
        else
        {
            token += strspn(token, sep);
        }
    }
    return args;
}

variable_types:
str
char *

variable_types:
sep
char *

variable_types:
len
unsigned long

return_type: struct arg_t { int argc; char **argv; } *


decompiled_code:
int *__fastcall arg_create(char *a1, char *a2, int a3)
{
return arg_create_max(a1, a2, a3, -1);
}

canonical_decompiled_code:
int *__fastcall func2(char *a1, char *a2, int a3)
{
return func1(a1, a2, a3, -1);
}

original_code:
arg_t *arg_create(const char *str, const char *sep, int allow_null_fields)
{
    return arg_create_max(str, sep, allow_null_fields, -1);
}

canonical_original_code:
struct arg_t *arg_create(char *str, char *sep, int allow_null_fields)
{
    return arg_create_max(str, sep, allow_null_fields, -1);
}


decompiled_code:
int *__fastcall arg_create_from_argv(int a1, const char **a2)
{
const char **v2; // rbx
int *v3; // r12
const char *v4; // rbp
unsigned int v5; // eax

v2 = a2;
v3 = (int *)calloc(1uLL, 0x10uLL);
if ( a1 > 0 )
{
do
{
v4 = *v2++;
v5 = strlen(v4);
arg_add_token(v3, v4, v5);
}
while ( v2 != &a2[(unsigned int)(a1 - 1) + 1] );
}
return v3;
}

canonical_decompiled_code:
int *__fastcall func3(int a1, const char **a2)
{
const char **v2; // rbx
int *v3; // r12
const char *v4; // rbp
unsigned int v5; // eax

v2 = a2;
v3 = (int *)calloc(1uLL, 0x10uLL);
if ( a1 > 0 )
{
do
{
v4 = *v2++;
v5 = strlen(v4);
func0(v3, v4, v5);
}
while ( v2 != &a2[(unsigned int)(a1 - 1) + 1] );
}
return v3;
}

original_code:
arg_t *arg_create_from_argv(int argc, char **argv)
{
    arg_t *args = calloc(1, sizeof(arg_t));
    int i;
    for(i = 0; i < argc; i++)
    {
        arg_add_token(args, argv[i], strlen(argv[i]));
    }
    return args;
}

canonical_original_code:
struct arg_t *arg_create_from_argv(int argc, char **argv)
{
    struct arg_t *args = calloc(1, sizeof(arg_t));
    int i;
    for(i = 0; i < argc; i++)
    {
        arg_add_token(args, argv[i], strlen(argv[i]));
    }
    return args;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: i int


decompiled_code:
int *__fastcall arg_dup(__int64 a1)
{
return arg_create_from_argv(*(_DWORD *)a1, *(const char ***)(a1 + 8));
}

canonical_decompiled_code:
int *__fastcall func4(__int64 a1)
{
return func3(*(_DWORD *)a1, *(const char ***)(a1 + 8));
}

original_code:
arg_t *arg_dup(const arg_t *arg)
{
    return arg_create_from_argv(arg->argc, arg->argv);
}

canonical_original_code:
struct arg_t *arg_dup(struct arg_t *arg)
{
    return arg_create_from_argv(arg->argc, arg->argv);
}

variable_types:
arg
struct arg_t *


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

v1 = *s;
if ( !*s )
return 0LL;
v2 = s;
v3 = 0LL;
while ( 1 )
{
while ( 1 )
{
if ( strchr(" \t\n", v1) )
return (unsigned int)v3;
if ( v1 == 92 )
break;
if ( v1 == 39 )
{
v4 = strcspn(v2 + 1, "'") + 2;
}
else if ( v1 == 34 )
{
v4 = strcspn(v2 + 1, "\"") + 2;
}
else
{
v4 = strcspn(v2, " \t\n'\"\\");
}
v2 += v4;
v3 += v4;
v1 = *v2;
if ( !*v2 )
return (unsigned int)v3;
}
if ( !v2[1] )
break;
v2 += 2;
v3 += 2LL;
v1 = *v2;
if ( !*v2 )
return (unsigned int)v3;
}
return (unsigned int)(v3 + 1);
}

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

v1 = *s;
if ( !*s )
return 0LL;
v2 = s;
v3 = 0LL;
while ( 1 )
{
while ( 1 )
{
if ( strchr(" \t\n", v1) )
return (unsigned int)v3;
if ( v1 == 92 )
break;
if ( v1 == 39 )
{
v4 = strcspn(v2 + 1, "'") + 2;
}
else if ( v1 == 34 )
{
v4 = strcspn(v2 + 1, "\"") + 2;
}
else
{
v4 = strcspn(v2, " \t\n'\"\\");
}
v2 += v4;
v3 += v4;
v1 = *v2;
if ( !*v2 )
return (unsigned int)v3;
}
if ( !v2[1] )
break;
v2 += 2;
v3 += 2LL;
v1 = *v2;
if ( !*v2 )
return (unsigned int)v3;
}
return (unsigned int)(v3 + 1);
}

original_code:
int arg_find_token_length(const char *token)
{
    static const char *blank = " \t\n";
    static const char *blank_or_quote = " \t\n'\"\\";
    size_t total_len = 0;
    while(*token)
    {
        size_t len = 0;
        if(strchr(blank, *token) != ((void *)0))
        {
            break;
        }
        else if(*token == '\\')
        {
            if(token[1])
                len = 2;
            else
                return total_len + 1;
        }
        else if(*token == '\'')
        {
            len = strcspn(token + 1, "\'");
            len += 2;
        }
        else if(*token == '\"')
        {
            len = strcspn(token + 1, "\"");
            len += 2;
        }
        else
        {
            len += strcspn(token, blank_or_quote);
        }
        token += len;
        total_len += len;
    }
    return total_len;
}

canonical_original_code:
int arg_find_token_length(char *token)
{
    static char *blank = " \t\n";
    static char *blank_or_quote = " \t\n'\"\\";
    unsigned long total_len = 0;
    while(*token)
    {
        unsigned long len = 0;
        if(strchr(blank, *token) != ((void *)0))
        {
            break;
        }
        else if(*token == '\\')
        {
            if(token[1])
                len = 2;
            else
                return total_len + 1;
        }
        else if(*token == '\'')
        {
            len = strcspn(token + 1, "\'");
            len += 2;
        }
        else if(*token == '\"')
        {
            len = strcspn(token + 1, "\"");
            len += 2;
        }
        else
        {
            len += strcspn(token, blank_or_quote);
        }
        token += len;
        total_len += len;
    }
    return total_len;
}

variable_types:
blank
char *


decompiled_code:
void **__fastcall arg_create_quoted(char *s)
{
void **v2; // r13
int v3; // eax
__int64 v4; // r12
int v6; // er15
_QWORD *v7; // rax
char *v8; // rdi

v2 = (void **)calloc(1uLL, 0x10uLL);
while ( s && *s )
{
s += strspn(s, " \t\n");
v3 = arg_find_token_length(s);
v4 = v3;
if ( v3 )
{
v6 = *(_DWORD *)v2 + 1;
v7 = realloc(v2[1], 8LL * v6);
v8 = s;
*(_DWORD *)v2 = v6;
v2[1] = v7;
s += v4;
v7[v6 - 1] = str_unquote(v8, (unsigned int)v4);
}
}
return v2;
}

canonical_decompiled_code:
void **__fastcall func6(char *s)
{
void **v2; // r13
int v3; // eax
__int64 v4; // r12
int v6; // er15
_QWORD *v7; // rax
char *v8; // rdi

v2 = (void **)calloc(1uLL, 0x10uLL);
while ( s && *s )
{
s += strspn(s, " \t\n");
v3 = func5(s);
v4 = v3;
if ( v3 )
{
v6 = *(_DWORD *)v2 + 1;
v7 = realloc(v2[1], 8LL * v6);
v8 = s;
*(_DWORD *)v2 = v6;
v2[1] = v7;
s += v4;
v7[v6 - 1] = str_unquote(v8, (unsigned int)v4);
}
}
return v2;
}

original_code:
arg_t *arg_create_quoted(const char *str)
{
    const char *sep = " \t\n";
    const char *token = str;
    arg_t *args = calloc(1, sizeof(arg_t));
    while(token && *token)
    {
        token += strspn(token, sep);
        size_t len = arg_find_token_length(token);
        if(len)
        {
            args->argv = (char **)realloc(args->argv, (args->argc + 1) * sizeof(char *));
            args->argv[args->argc++] = str_unquote(token, len);
            token += len;
        }
    }
    return args;
}

canonical_original_code:
struct arg_t *arg_create_quoted(char *str)
{
    char *sep = " \t\n";
    char *token = str;
    struct arg_t *args = calloc(1, sizeof(arg_t));
    while(token && *token)
    {
        token += strspn(token, sep);
        unsigned long len = arg_find_token_length(token);
        if(len)
        {
            args->argv = (char **)realloc(args->argv, (args->argc + 1) * sizeof(char *));
            args->argv[args->argc++] = str_unquote(token, len);
            token += len;
        }
    }
    return args;
}


decompiled_code:
void __fastcall arg_free(void *ptr)
{
_QWORD *v2; // rdi
__int64 v3; // rbx
void *v4; // rdi

if ( ptr )
{
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
if ( v2 )
{
if ( *(int *)ptr > 0 )
{
v3 = 0LL;
do
{
v4 = (void *)v2[v3++];
free(v4);
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
}
while ( *(_DWORD *)ptr > (int)v3 );
}
free(v2);
}
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func7(void *ptr)
{
_QWORD *v2; // rdi
__int64 v3; // rbx
void *v4; // rdi

if ( ptr )
{
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
if ( v2 )
{
if ( *(int *)ptr > 0 )
{
v3 = 0LL;
do
{
v4 = (void *)v2[v3++];
free(v4);
v2 = (_QWORD *)*((_QWORD *)ptr + 1);
}
while ( *(_DWORD *)ptr > (int)v3 );
}
free(v2);
}
free(ptr);
}
}

original_code:
void arg_free(arg_t *args)
{
    int i;
    if(args)
    {
        if(args->argv)
        {
            for(i = 0; i < args->argc; i++)
            {
                free(args->argv[i]);
            }
            free(args->argv);
        }
        free(args);
    }
}

canonical_original_code:
void arg_free(struct arg_t *args)
{
    int i;
    if(args)
    {
        if(args->argv)
        {
            for(i = 0; i < args->argc; i++)
            {
                free(args->argv[i]);
            }
            free(args->argv);
        }
        free(args);
    }
}


decompiled_code:
void *__fastcall arg_join(int *a1, int a2, int a3, const char *a4)
{
int v4; // er13
__int64 v5; // rbp
size_t v6; // r14
__int64 v7; // rbx
size_t v8; // r12
const char **v9; // r15
const char *v10; // rdi
void *v11; // r13
unsigned __int64 v13; // [rsp+8h] [rbp-50h]

v4 = *a1;
if ( a3 != -1 && v4 > a3 )
v4 = a3;
if ( v4 <= a2 )
return malloc(1uLL);
v5 = *((_QWORD *)a1 + 1);
v6 = strlen(a4);
v7 = 8LL * a2;
v8 = 0LL;
v9 = (const char **)(v5 + v7);
v13 = 8 * (a2 + (unsigned __int64)(unsigned int)(~a2 + v4));
do
{
v10 = *v9++;
v8 += v6 + strlen(v10);
}
while ( v9 != (const char **)(v5 + v13 + 8) );
v11 = malloc(v8 + 1);
memset(v11, 0, v8);
while ( 1 )
{
strlcat(v11, *(_QWORD *)(v5 + v7), v8 + 1);
if ( v7 == v13 )
break;
v7 += 8LL;
strlcat(v11, a4, v8 + 1);
v5 = *((_QWORD *)a1 + 1);
}
return v11;
}

canonical_decompiled_code:
void *__fastcall func8(int *a1, int a2, int a3, const char *a4)
{
int v4; // er13
__int64 v5; // rbp
size_t v6; // r14
__int64 v7; // rbx
size_t v8; // r12
const char **v9; // r15
const char *v10; // rdi
void *v11; // r13
unsigned __int64 v13; // [rsp+8h] [rbp-50h]

v4 = *a1;
if ( a3 != -1 && v4 > a3 )
v4 = a3;
if ( v4 <= a2 )
return malloc(1uLL);
v5 = *((_QWORD *)a1 + 1);
v6 = strlen(a4);
v7 = 8LL * a2;
v8 = 0LL;
v9 = (const char **)(v5 + v7);
v13 = 8 * (a2 + (unsigned __int64)(unsigned int)(~a2 + v4));
do
{
v10 = *v9++;
v8 += v6 + strlen(v10);
}
while ( v9 != (const char **)(v5 + v13 + 8) );
v11 = malloc(v8 + 1);
memset(v11, 0, v8);
while ( 1 )
{
strlcat(v11, *(_QWORD *)(v5 + v7), v8 + 1);
if ( v7 == v13 )
break;
v7 += 8LL;
strlcat(v11, a4, v8 + 1);
v5 = *((_QWORD *)a1 + 1);
}
return v11;
}

original_code:
char *arg_join(arg_t *args, int first, int last, const char *sep)
{
    int i;
    char *e;
    size_t s = 0;
    if(last == -1 || last > args->argc)
    {
        last = args->argc;
    }
    for(i = first; i < last; i++)
    {
        s += strlen(args->argv[i]) + strlen(sep);
    }
    e = (char *)malloc(s + 1);
    memset(e, 0, s);
    for(i = first; i < last; i++)
    {
        strlcat(e, args->argv[i], s + 1);
        if(i+1 < last)
        {
            strlcat(e, sep, s + 1);
        }
    }
    return e;
}

canonical_original_code:
char *arg_join(struct arg_t *args, int first, int last, char *sep)
{
    int i;
    char *e;
    unsigned long s = 0;
    if(last == -1 || last > args->argc)
    {
        last = args->argc;
    }
    for(i = first; i < last; i++)
    {
        s += strlen(args->argv[i]) + strlen(sep);
    }
    e = (char *)malloc(s + 1);
    memset(e, 0, s);
    for(i = first; i < last; i++)
    {
        strlcat(e, args->argv[i], s + 1);
        if(i+1 < last)
        {
            strlcat(e, sep, s + 1);
        }
    }
    return e;
}

variable_types: first int

variable_types: last int

variable_types:
e
char *

variable_types:
s
unsigned long


decompiled_code:
char *__fastcall extip_detect_from_buf(__int64 a1)
{
char *v1; // r12
__int64 v2; // rax
__int64 v3; // rbp
unsigned int v5; // eax
unsigned int v6; // eax

if ( a1 )
{
v1 = 0LL;
v2 = rx_search(a1, "(([0-9]{1,3}\\.){3}[0-9]{1,3})");
v3 = v2;
if ( v2 && *(_DWORD *)v2 == 2 )
{
v1 = strdup(**(const char ***)(v2 + 8));
v5 = getpid();
sp_log(64LL, "[%d] (%s:%i) detected external IP %s", v5, "extip_detect_from_buf", 338LL, v1);
}
rx_free_subs(v3);
}
else
{
v6 = getpid();
v1 = 0LL;
sp_log(16LL, "[%d] (%s:%i) assert failed: buf", v6, "extip_detect_from_buf", 330LL);
}
return v1;
}

canonical_decompiled_code:
char *__fastcall func1(__int64 a1)
{
char *v1; // r12
__int64 v2; // rax
__int64 v3; // rbp
unsigned int v5; // eax
unsigned int v6; // eax

if ( a1 )
{
v1 = 0LL;
v2 = rx_search(a1, "(([0-9]{1,3}\\.){3}[0-9]{1,3})");
v3 = v2;
if ( v2 && *(_DWORD *)v2 == 2 )
{
v1 = strdup(**(const char ***)(v2 + 8));
v5 = getpid();
sp_log(64LL, "[%d] (%s:%i) detected external IP %s", v5, "extip_detect_from_buf", 338LL, v1);
}
rx_free_subs(v3);
}
else
{
v6 = getpid();
v1 = 0LL;
sp_log(16LL, "[%d] (%s:%i) assert failed: buf", v6, "extip_detect_from_buf", 330LL);
}
return v1;
}

original_code:
static char *extip_detect_from_buf(const char *buf)
{
    do { if(!(buf)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "buf", getpid(), __func__, 330); return (((void *)0)); } } while(0);
    rx_subs_t *subs = rx_search(buf, "(([0-9]{1,3}\\.){3}[0-9]{1,3})");
    char *ip = ((void *)0);
    if(subs && subs->nsubs == 2)
    {
        ip = strdup(subs->subs[0]);
        sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "detected external IP %s", getpid(), __func__, 338, ip);
    }
    rx_free_subs(subs);
    return ip;
}

canonical_original_code:
static char *extip_detect_from_buf(char *buf)
{
    do { if(!(buf)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "buf", getpid(), __func__, 330); return (((void *)0)); } } while(0);
    struct rx_subs *subs = rx_search(buf, "(([0-9]{1,3}\\.){3}[0-9]{1,3})");
    char *ip = ((void *)0);
    if(subs && subs->nsubs == 2)
    {
        ip = strdup(subs->subs[0]);
        sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "detected external IP %s", getpid(), __func__, 338, ip);
    }
    rx_free_subs(subs);
    return ip;
}

variable_types:
buf
char *

variable_types: struct rx_subs { int nsubs; char **subs; } *

variable_types:
ip
char *


decompiled_code:
__int64 __fastcall extip_run_update(__int64 a1, __int64 a2, _DWORD *a3)
{
return extip_send_lookup_request(a3);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2, _DWORD *a3)
{
return func4(a3);
}

original_code:
static void extip_run_update(int fd, short why, void *data)
{
 extip_send_lookup_request(data);
}

variable_types: fd int

variable_types: why short

variable_types:
data
void *


decompiled_code:
void __fastcall extip_set_static(char *cp)
{
char *v1; // rax
char *v2; // rbp
__int64 v3; // rax
unsigned int v4; // eax
char *v5; // rbp
__int64 v6; // rax
struct in_addr inp; // [rsp+Ch] [rbp-Ch] BYREF

free(static_ip);
static_ip = 0LL;
if ( cp )
{
if ( inet_aton(cp, &inp) )
{
v1 = strdup(cp);
use_static = 1;
v2 = v1;
static_ip = v1;
v3 = nc_default();
nc_send_external_ip_detected_notification(v3, v2);
}
else
{
v4 = getpid();
sp_log(16LL, "[%d] (%s:%i) invalid IP address [%s], ignored", v4, "extip_set_static", 100LL, cp);
use_static = 0;
}
}
else
{
v5 = external_ip;
use_static = 0;
if ( external_ip )
{
v6 = nc_default();
nc_send_external_ip_detected_notification(v6, v5);
}
}
}

canonical_decompiled_code:
void __fastcall func10(char *cp)
{
char *v1; // rax
char *v2; // rbp
__int64 v3; // rax
unsigned int v4; // eax
char *v5; // rbp
__int64 v6; // rax
struct in_addr inp; // [rsp+Ch] [rbp-Ch] BYREF

free(static_ip);
static_ip = 0LL;
if ( cp )
{
if ( inet_aton(cp, &inp) )
{
v1 = strdup(cp);
use_static = 1;
v2 = v1;
static_ip = v1;
v3 = nc_default();
nc_send_external_ip_detected_notification(v3, v2);
}
else
{
v4 = getpid();
sp_log(16LL, "[%d] (%s:%i) invalid IP address [%s], ignored", v4, "extip_set_static", 100LL, cp);
use_static = 0;
}
}
else
{
v5 = external_ip;
use_static = 0;
if ( external_ip )
{
v6 = nc_default();
nc_send_external_ip_detected_notification(v6, v5);
}
}
}

original_code:
void extip_set_static(const char *ip)
{
    free(static_ip);
    static_ip = ((void *)0);
    if(ip == ((void *)0))
    {
        use_static = 0;
 if(external_ip)
     nc_send_external_ip_detected_notification(nc_default(), external_ip);
    }
    else
    {
        struct in_addr tmp;
        if(inet_aton(ip, &tmp) == 0)
        {
            sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "invalid IP address [%s], ignored", getpid(), __func__, 100, ip);
            use_static = 0;
        }
        else
        {
            static_ip = strdup(ip);
            use_static = 1;
     nc_send_external_ip_detected_notification(nc_default(), static_ip);
        }
    }
}

canonical_original_code:
void extip_set_static(char *ip)
{
    free(static_ip);
    static_ip = ((void *)0);
    if(ip == ((void *)0))
    {
        use_static = 0;
 if(external_ip)
     nc_send_external_ip_detected_notification(nc_default(), external_ip);
    }
    else
    {
        struct in_addr tmp;
        if(inet_aton(ip, &tmp) == 0)
        {
            sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "invalid IP address [%s], ignored", getpid(), __func__, 100, ip);
            use_static = 0;
        }
        else
        {
            static_ip = strdup(ip);
            use_static = 1;
     nc_send_external_ip_detected_notification(nc_default(), static_ip);
        }
    }
}

variable_types:
tmp
struct in_addr { unsigned int s_addr; }


decompiled_code:
void __fastcall extip_set_override(char a1)
{
allow_hub_override = a1;
}

canonical_decompiled_code:
void __fastcall func11(char a1)
{
allow_hub_override = a1;
}

original_code:
void extip_set_override(_Bool allow_override)
{
 allow_hub_override = allow_override;
}


decompiled_code:
__int64 extip_get_override()
{
return (unsigned __int8)allow_hub_override;
}

canonical_decompiled_code:
__int64 func12()
{
return (unsigned __int8)allow_hub_override;
}

original_code:
_Bool extip_get_override()
{
 return allow_hub_override;
}


decompiled_code:
int __fastcall get_netmask(_DWORD *a1, _DWORD *a2)
{
int result; // eax
struct ifaddrs *v4; // rdi
struct ifaddrs *v5; // rax
struct sockaddr *v6; // rdx
struct ifaddrs *ifap; // [rsp+8h] [rbp-20h] BYREF

result = getifaddrs(&ifap);
if ( result != -1 )
{
v4 = ifap;
if ( ifap )
{
v5 = ifap;
while ( 1 )
{
v6 = v5->ifa_addr;
if ( v6 )
{
if ( v6->sa_family == 2 && *(_DWORD *)&v6->sa_data[2] == *a1 )
break;
}
v5 = v5->ifa_next;
if ( !v5 )
goto LABEL_9;
}
*a2 = *(_DWORD *)&v5->ifa_netmask->sa_data[2];
}
LABEL_9:
freeifaddrs(v4);
result = 0;
}
return result;
}

canonical_decompiled_code:
int __fastcall func13(_DWORD *a1, _DWORD *a2)
{
int result; // eax
struct ifaddrs *v4; // rdi
struct ifaddrs *v5; // rax
struct sockaddr *v6; // rdx
struct ifaddrs *ifap; // [rsp+8h] [rbp-20h] BYREF

result = getifaddrs(&ifap);
if ( result != -1 )
{
v4 = ifap;
if ( ifap )
{
v5 = ifap;
while ( 1 )
{
v6 = v5->ifa_addr;
if ( v6 )
{
if ( v6->sa_family == 2 && *(_DWORD *)&v6->sa_data[2] == *a1 )
break;
}
v5 = v5->ifa_next;
if ( !v5 )
goto LABEL_9;
}
*a2 = *(_DWORD *)&v5->ifa_netmask->sa_data[2];
}
LABEL_9:
freeifaddrs(v4);
result = 0;
}
return result;
}

original_code:
int get_netmask(struct in_addr *ip, struct in_addr *mask)
{
    struct ifaddrs *ifa, *ifaddrs;
    if(getifaddrs(&ifaddrs) == -1)
        return -1;
    for(ifa = ifaddrs; ifa != ((void *)0); ifa = ifa -> ifa_next)
    {
 if(ifa->ifa_addr && ifa->ifa_addr->sa_family == 2)
        {
            struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr;
            if(memcmp(ip, &sin->sin_addr, sizeof(struct in_addr)) == 0)
            {
                sin = (struct sockaddr_in *)ifa->ifa_netmask;
                memcpy(mask, &sin->sin_addr, sizeof(struct in_addr));
                break;
            }
        }
    }
    freeifaddrs(ifaddrs);
    return 0;
}

canonical_original_code:
int get_netmask(struct in_addr *ip, struct in_addr *mask)
{
    struct ifaddrs *ifa; struct ifaddrs *ifaddrs;
    if(getifaddrs(&ifaddrs) == -1)
        return -1;
    for(ifa = ifaddrs; ifa != ((void *)0); ifa = ifa -> ifa_next)
    {
 if(ifa->ifa_addr && ifa->ifa_addr->sa_family == 2)
        {
            struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr;
            if(memcmp(ip, &sin->sin_addr, sizeof(struct in_addr)) == 0)
            {
                sin = (struct sockaddr_in *)ifa->ifa_netmask;
                memcpy(mask, &sin->sin_addr, sizeof(struct in_addr));
                break;
            }
        }
    }
    freeifaddrs(ifaddrs);
    return 0;
}

variable_types: struct in_addr { unsigned int s_addr; } *

variable_types:
mask
struct in_addr *

variable_types: struct ifaddrs { struct ifaddrs *ifa_next; char *ifa_name; unsigned int ifa_flags; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ifa_addr; struct sockaddr *ifa_netmask; union { struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; void *ifa_data; } *

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

user_defined_types: struct ifaddrs { struct ifaddrs *ifa_next; char *ifa_name; unsigned int ifa_flags; struct sockaddr *ifa_addr; struct sockaddr *ifa_netmask; union { struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; void *ifa_data; }


decompiled_code:
char *__fastcall extip_check_local_hub(struct in_addr *a1, struct in_addr *a2)
{
char *v3; // r12
unsigned int v4; // eax
in_addr_t v5; // edi
char *v6; // rbx
unsigned int v7; // eax
char *result; // rax
char *v9; // rbp
unsigned int v10; // eax
unsigned int v11; // eax
struct in_addr in; // [rsp+Ch] [rbp-1Ch] BYREF

if ( get_netmask(a1, &in) )
{
v11 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: get_netmask(local, &mask) == 0", v11, "extip_check_local_hub", 214LL);
result = 0LL;
}
else
{
v3 = inet_ntoa(in);
v4 = getpid();
sp_log(32LL, "[%d] (%s:%i) detected my local netmask as %s", v4, "extip_check_local_hub", 215LL, v3);
v5 = in.s_addr & a1->s_addr;
if ( v5 == (a2->s_addr & in.s_addr) )
{
v9 = inet_ntoa((struct in_addr)v5);
v10 = getpid();
sp_log(32LL, "[%d] (%s:%i) common subnet [%s], using local IP", v10, "extip_check_local_hub", 223LL, v9);
result = inet_ntoa((struct in_addr)a1->s_addr);
}
else
{
v6 = inet_ntoa((struct in_addr)a2->s_addr);
v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) hub ip [%s] not in local subnet", v7, "extip_check_local_hub", 229LL, v6);
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
char *__fastcall func14(struct in_addr *a1, struct in_addr *a2)
{
char *v3; // r12
unsigned int v4; // eax
in_addr_t v5; // edi
char *v6; // rbx
unsigned int v7; // eax
char *result; // rax
char *v9; // rbp
unsigned int v10; // eax
unsigned int v11; // eax
struct in_addr in; // [rsp+Ch] [rbp-1Ch] BYREF

if ( func13(a1, &in) )
{
v11 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: get_netmask(local, &mask) == 0", v11, "extip_check_local_hub", 214LL);
result = 0LL;
}
else
{
v3 = inet_ntoa(in);
v4 = getpid();
sp_log(32LL, "[%d] (%s:%i) detected my local netmask as %s", v4, "extip_check_local_hub", 215LL, v3);
v5 = in.s_addr & a1->s_addr;
if ( v5 == (a2->s_addr & in.s_addr) )
{
v9 = inet_ntoa((struct in_addr)v5);
v10 = getpid();
sp_log(32LL, "[%d] (%s:%i) common subnet [%s], using local IP", v10, "extip_check_local_hub", 223LL, v9);
result = inet_ntoa((struct in_addr)a1->s_addr);
}
else
{
v6 = inet_ntoa((struct in_addr)a2->s_addr);
v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) hub ip [%s] not in local subnet", v7, "extip_check_local_hub", 229LL, v6);
result = 0LL;
}
}
return result;
}

original_code:
static const char *extip_check_local_hub(struct in_addr *local,
        struct in_addr *remote)
{
    struct in_addr mask;
    do { if(!(get_netmask(local, &mask) == 0)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "get_netmask(local, &mask) == 0", getpid(), __func__, 214); return (((void *)0)); } } while(0);
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "detected my local netmask as %s", getpid(), __func__, 215, inet_ntoa(mask));
    struct in_addr subnet;
    subnet.s_addr = local->s_addr & mask.s_addr;
    if((remote->s_addr & mask.s_addr) == subnet.s_addr)
    {
        sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "common subnet [%s], using local IP", getpid(), __func__, 223, inet_ntoa(subnet));
        return inet_ntoa(*local);
    }
    else
    {
        sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "hub ip [%s] not in local subnet", getpid(), __func__, 229, inet_ntoa(*remote));
    }
    return ((void *)0);
}

canonical_original_code:
static char *extip_check_local_hub(struct in_addr *local, struct in_addr *remote)
{
    struct in_addr mask;
    do { if(!(get_netmask(local, &mask) == 0)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "get_netmask(local, &mask) == 0", getpid(), __func__, 214); return (((void *)0)); } } while(0);
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "detected my local netmask as %s", getpid(), __func__, 215, inet_ntoa(mask));
    struct in_addr subnet;
    subnet.s_addr = local->s_addr & mask.s_addr;
    if((remote->s_addr & mask.s_addr) == subnet.s_addr)
    {
        sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "common subnet [%s], using local IP", getpid(), __func__, 223, inet_ntoa(subnet));
        return inet_ntoa(*local);
    }
    else
    {
        sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "hub ip [%s] not in local subnet", getpid(), __func__, 229, inet_ntoa(*remote));
    }
    return ((void *)0);
}

variable_types:
remote
struct in_addr *

variable_types:
mask
struct in_addr { unsigned int s_addr; }

variable_types:
subnet
struct in_addr { unsigned int s_addr; }


decompiled_code:
char *__fastcall extip_get(int fd, char *cp)
{
char *v2; // rbp
unsigned int v3; // eax
const char *v4; // rbp
char *result; // rax
const char *v6; // rbp
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9; // eax
unsigned int v10; // eax
unsigned int v11; // eax
unsigned int v12; // eax
unsigned int v13; // eax
unsigned int v14; // eax
struct in_addr inp; // [rsp+4h] [rbp-34h] BYREF
socklen_t len; // [rsp+8h] [rbp-30h] BYREF
struct in_addr v17; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

if ( inet_aton(cp, &inp) )
{
if ( fd == -1 )
{
v14 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: fd != -1", v14, "extip_get", 265LL);
result = 0LL;
}
else if ( cp )
{
len = 16;
getsockname(fd, &addr, &len);
v2 = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
v3 = getpid();
sp_log(32LL, "[%d] (%s:%i) detected my local IP as %s", v3, "extip_get", 272LL, v2);
if ( use_static && (v4 = (const char *)static_ip) != 0LL )
{
v8 = getpid();
sp_log(32LL, "[%d] (%s:%i) using static IP %s for hub %s", v8, "extip_get", 278LL, v4, cp);
result = (char *)static_ip;
}
else
{
result = extip_check_local_hub((struct in_addr *)&addr.sa_data[2], &inp);
if ( !result )
{
if ( (unsigned __int8)addr_is_private_isra_0(*(unsigned int *)&addr.sa_data[2])
&& (unsigned __int8)addr_is_private_isra_0(inp.s_addr) )
{
v12 = getpid();
sp_log(32LL, "[%d] (%s:%i) using private local IP for private hub %s", v12, "extip_get", 292LL, cp);
result = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
}
else
{
if ( external_ip )
{
inet_aton(external_ip, &v17);
if ( v17.s_addr == *(_DWORD *)&addr.sa_data[2] )
{
v13 = getpid();
sp_log(32LL, "[%d] (%s:%i) detected use of public IP (ie, no NAT/PAT)", v13, "extip_get", 305LL);
external_ip_lookup_time += 86400LL;
}
}
extip_update_cache();
v6 = external_ip;
if ( external_ip )
{
v7 = getpid();
sp_log(32LL, "[%d] (%s:%i) using external IP %s for hub %s", v7, "extip_get", 318LL, v6, cp);
result = external_ip;
}
else
{
v11 = getpid();
sp_log(16LL, "[%d] (%s:%i) external IP unavailable, using local IP", v11, "extip_get", 314LL);
result = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
}
}
}
}
}
else
{
v10 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: hub_ip", v10, "extip_get", 266LL);
result = 0LL;
}
}
else
{
v9 = getpid();
sp_log(16LL, "[%d] (%s:%i) invalid hub IP [%s]", v9, "extip_get", 261LL, cp);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
char *__fastcall func15(int fd, char *cp)
{
char *v2; // rbp
unsigned int v3; // eax
const char *v4; // rbp
char *result; // rax
const char *v6; // rbp
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9; // eax
unsigned int v10; // eax
unsigned int v11; // eax
unsigned int v12; // eax
unsigned int v13; // eax
unsigned int v14; // eax
struct in_addr inp; // [rsp+4h] [rbp-34h] BYREF
socklen_t len; // [rsp+8h] [rbp-30h] BYREF
struct in_addr v17; // [rsp+Ch] [rbp-2Ch] BYREF
struct sockaddr addr; // [rsp+10h] [rbp-28h] BYREF

if ( inet_aton(cp, &inp) )
{
if ( fd == -1 )
{
v14 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: fd != -1", v14, "extip_get", 265LL);
result = 0LL;
}
else if ( cp )
{
len = 16;
getsockname(fd, &addr, &len);
v2 = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
v3 = getpid();
sp_log(32LL, "[%d] (%s:%i) detected my local IP as %s", v3, "extip_get", 272LL, v2);
if ( use_static && (v4 = (const char *)static_ip) != 0LL )
{
v8 = getpid();
sp_log(32LL, "[%d] (%s:%i) using static IP %s for hub %s", v8, "extip_get", 278LL, v4, cp);
result = (char *)static_ip;
}
else
{
result = func14((struct in_addr *)&addr.sa_data[2], &inp);
if ( !result )
{
if ( (unsigned __int8)func9(*(unsigned int *)&addr.sa_data[2])
&& (unsigned __int8)func9(inp.s_addr) )
{
v12 = getpid();
sp_log(32LL, "[%d] (%s:%i) using private local IP for private hub %s", v12, "extip_get", 292LL, cp);
result = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
}
else
{
if ( external_ip )
{
inet_aton(external_ip, &v17);
if ( v17.s_addr == *(_DWORD *)&addr.sa_data[2] )
{
v13 = getpid();
sp_log(32LL, "[%d] (%s:%i) detected use of public IP (ie, no NAT/PAT)", v13, "extip_get", 305LL);
external_ip_lookup_time += 86400LL;
}
}
func5();
v6 = external_ip;
if ( external_ip )
{
v7 = getpid();
sp_log(32LL, "[%d] (%s:%i) using external IP %s for hub %s", v7, "extip_get", 318LL, v6, cp);
result = external_ip;
}
else
{
v11 = getpid();
sp_log(16LL, "[%d] (%s:%i) external IP unavailable, using local IP", v11, "extip_get", 314LL);
result = inet_ntoa(*(struct in_addr *)&addr.sa_data[2]);
}
}
}
}
}
else
{
v10 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: hub_ip", v10, "extip_get", 266LL);
result = 0LL;
}
}
else
{
v9 = getpid();
sp_log(16LL, "[%d] (%s:%i) invalid hub IP [%s]", v9, "extip_get", 261LL, cp);
result = 0LL;
}
return result;
}

original_code:
const char *extip_get(int fd, const char *hub_ip)
{
    struct in_addr hub_addr;
    if(!inet_aton(hub_ip, &hub_addr))
    {
        sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "invalid hub IP [%s]", getpid(), __func__, 261, hub_ip);
        return ((void *)0);
    }
    do { if(!(fd != -1)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "fd != -1", getpid(), __func__, 265); return (((void *)0)); } } while(0);
    do { if(!(hub_ip)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "hub_ip", getpid(), __func__, 266); return (((void *)0)); } } while(0);
    struct sockaddr_in sin;
    unsigned int namelen = sizeof(sin);
    getsockname(fd, (struct sockaddr *)&sin, &namelen);
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "detected my local IP as %s", getpid(), __func__, 272, inet_ntoa(sin.sin_addr));
    if(use_static && static_ip)
    {
 sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "using static IP %s for hub %s", getpid(), __func__, 278, static_ip, hub_ip);
        return static_ip;
    }
    const char *ip = extip_check_local_hub(&sin.sin_addr, &hub_addr);
    if(ip)
        return ip;
    if(addr_is_private(&sin.sin_addr) && addr_is_private(&hub_addr))
    {
        sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "using private local IP for private hub %s", getpid(), __func__, 292, hub_ip);
        return inet_ntoa(sin.sin_addr);
    }
    if(external_ip)
    {
        struct in_addr external_addr;
        inet_aton(external_ip, &external_addr);
        if(external_addr.s_addr == sin.sin_addr.s_addr)
        {
     sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "detected use of public IP (ie, no NAT/PAT)", getpid(), __func__, 305);
            external_ip_lookup_time += 24*60*60;
        }
    }
    extip_update_cache();
    if(external_ip == ((void *)0))
    {
        sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "external IP unavailable, using local IP", getpid(), __func__, 314);
        return inet_ntoa(sin.sin_addr);
    }
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "using external IP %s for hub %s", getpid(), __func__, 318, external_ip, hub_ip);
    return external_ip;
}

canonical_original_code:
char *extip_get(int fd, char *hub_ip)
{
    struct in_addr hub_addr;
    if(!inet_aton(hub_ip, &hub_addr))
    {
        sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "invalid hub IP [%s]", getpid(), __func__, 261, hub_ip);
        return ((void *)0);
    }
    do { if(!(fd != -1)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "fd != -1", getpid(), __func__, 265); return (((void *)0)); } } while(0);
    do { if(!(hub_ip)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "hub_ip", getpid(), __func__, 266); return (((void *)0)); } } while(0);
    struct sockaddr_in sin;
    unsigned int namelen = sizeof(sin);
    getsockname(fd, (struct sockaddr *)&sin, &namelen);
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "detected my local IP as %s", getpid(), __func__, 272, inet_ntoa(sin.sin_addr));
    if(use_static && static_ip)
    {
 sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "using static IP %s for hub %s", getpid(), __func__, 278, static_ip, hub_ip);
        return static_ip;
    }
    char *ip = extip_check_local_hub(&sin.sin_addr, &hub_addr);
    if(ip)
        return ip;
    if(addr_is_private(&sin.sin_addr) && addr_is_private(&hub_addr))
    {
        sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "using private local IP for private hub %s", getpid(), __func__, 292, hub_ip);
        return inet_ntoa(sin.sin_addr);
    }
    if(external_ip)
    {
        struct in_addr external_addr;
        inet_aton(external_ip, &external_addr);
        if(external_addr.s_addr == sin.sin_addr.s_addr)
        {
     sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "detected use of public IP (ie, no NAT/PAT)", getpid(), __func__, 305);
            external_ip_lookup_time += 24*60*60;
        }
    }
    extip_update_cache();
    if(external_ip == ((void *)0))
    {
        sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "external IP unavailable, using local IP", getpid(), __func__, 314);
        return inet_ntoa(sin.sin_addr);
    }
    sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "using external IP %s for hub %s", getpid(), __func__, 318, external_ip, hub_ip);
    return external_ip;
}

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

variable_types:
namelen
unsigned int

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


decompiled_code:
__int64 extip_init()
{
int v0; // ebx
__pid_t v1; // eax

v0 = time(0LL);
v1 = getpid();
srandom(v0 * v1);
return extip_update_cache();
}

canonical_decompiled_code:
__int64 func16()
{
int v0; // ebx
__pid_t v1; // eax

v0 = time(0LL);
v1 = getpid();
srandom(v0 * v1);
return func5();
}

original_code:
void extip_init(void)
{
    srandom(time(0) * getpid());
    extip_update_cache();
}

canonical_original_code:
void extip_init()
{
    srandom(time(0) * getpid());
    extip_update_cache();
}


decompiled_code:
__int64 __fastcall recently_triggered(char *s2)
{
time_t v1; // rax
__int64 v2; // r12
time_t v3; // rbp

v1 = time(0LL);
v2 = trigger_list_head;
if ( trigger_list_head )
{
v3 = v1;
while ( strcmp(*(const char **)(v2 + 16), s2) )
{
v2 = *(_QWORD *)v2;
if ( !v2 )
return v2;
}
if ( v3 - *(_QWORD *)(v2 + 24) >= queue_connect_interval )
v2 = 0LL;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *s2)
{
time_t v1; // rax
__int64 v2; // r12
time_t v3; // rbp

v1 = time(0LL);
v2 = trigger_list_head;
if ( trigger_list_head )
{
v3 = v1;
while ( strcmp(*(const char **)(v2 + 16), s2) )
{
v2 = *(_QWORD *)v2;
if ( !v2 )
return v2;
}
if ( v3 - *(_QWORD *)(v2 + 24) >= queue_connect_interval )
v2 = 0LL;
}
return v2;
}

original_code:
static struct trigger_entry *recently_triggered(const char *nick)
{
    time_t now = time(0);
    struct trigger_entry *entry;
    for((entry) = ((&trigger_list_head)->lh_first); (entry)!= ((void *)0); (entry) = ((entry)->link.le_next))
    {
        if(strcmp(entry->nick, nick) == 0)
        {
            break;
        }
    }
    if(entry == ((void *)0) || now - entry->when >= queue_connect_interval)
    {
        return ((void *)0);
    }
    return entry;
}

canonical_original_code:
static struct trigger_entry *recently_triggered(char *nick)
{
    long now = time(0);
    struct trigger_entry *entry;
    for((entry) = ((&trigger_list_head)->lh_first); (entry)!= ((void *)0); (entry) = ((entry)->link.le_next))
    {
        if(strcmp(entry->nick, nick) == 0)
        {
            break;
        }
    }
    if(entry == ((void *)0) || now - entry->when >= queue_connect_interval)
    {
        return ((void *)0);
    }
    return entry;
}

variable_types:
nick
char *

variable_types: now long

variable_types: struct trigger_entry { struct { struct trigger_entry *le_next; struct trigger_entry **le_prev; } link; char *nick; long when; } *


decompiled_code:
void __fastcall queue_connect_set_interval(int a1)
{
queue_connect_interval = a1;
}

canonical_decompiled_code:
void __fastcall func2(int a1)
{
queue_connect_interval = a1;
}

original_code:
void queue_connect_set_interval(int seconds)
{
    queue_connect_interval = seconds;
}

variable_types: seconds int


decompiled_code:
__int64 __fastcall queue_trigger_connect_event_func(__int64 a1, __int64 a2, __int64 (__fastcall *a3)(const char *, __int64))
{
queue_trigger_connect(a3, 0LL);
return queue_connect_schedule_trigger((__int64)a3);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, __int64 a2, __int64 (__fastcall *a3)(const char *, __int64))
{
func5(a3, 0LL);
return func6((__int64)a3);
}

original_code:
static void queue_trigger_connect_event_func(int fd, short why, void *data)
{
    queue_connect_callback_t callback_function = data;
    queue_trigger_connect(callback_function, ((void *)0));
    queue_connect_schedule_trigger(callback_function);
}

canonical_original_code:
static void queue_trigger_connect_event_func(int fd, short why, void *data)
{
    int (*callback_function)(char *nick, void *user_data) = data;
    queue_trigger_connect(callback_function, ((void *)0));
    queue_connect_schedule_trigger(callback_function);
}

variable_types: fd int


decompiled_code:
void __fastcall queue_resolve_directory_recursively(__int64 a1, __int64 a2, const char *a3, __int64 a4, _DWORD *a5)
{
__int64 **i; // rbx
__int64 *v10; // rsi
unsigned int v11; // eax
unsigned int v12; // eax
void *ptr; // [rsp+0h] [rbp-48h] BYREF
char *v14; // [rsp+8h] [rbp-40h] BYREF

for ( i = *(__int64 ***)(a2 + 16); i; i = (__int64 **)*i )
{
if ( asprintf((char **)&ptr, "%s/%s", a3, (const char *)i[2]) == -1 )
{
v11 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v11, "queue_resolve_directory_recursively", 48LL);
}
v10 = i[6];
if ( v10 )
{
queue_resolve_directory_recursively(a1, v10, ptr, a4, a5);
}
else
{
if ( asprintf(&v14, "%s\\%s", *(const char **)(a2 + 32), (const char *)i[2]) == -1 )
{
v12 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v12, "queue_resolve_directory_recursively", 60LL);
}
queue_add_internal(a1, v14, i[4], ptr, i[5], 0LL, a4);
++*a5;
free(v14);
}
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1, __int64 a2, const char *a3, __int64 a4, _DWORD *a5)
{
__int64 **i; // rbx
__int64 *v10; // rsi
unsigned int v11; // eax
unsigned int v12; // eax
void *ptr; // [rsp+0h] [rbp-48h] BYREF
char *v14; // [rsp+8h] [rbp-40h] BYREF

for ( i = *(__int64 ***)(a2 + 16); i; i = (__int64 **)*i )
{
if ( asprintf((char **)&ptr, "%s/%s", a3, (const char *)i[2]) == -1 )
{
v11 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v11, "queue_resolve_directory_recursively", 48LL);
}
v10 = i[6];
if ( v10 )
{
func0(a1, v10, ptr, a4, a5);
}
else
{
if ( asprintf(&v14, "%s\\%s", *(const char **)(a2 + 32), (const char *)i[2]) == -1 )
{
v12 = getpid();
sp_log(64LL, "[%d] (%s:%i) asprintf did not return anything", v12, "queue_resolve_directory_recursively", 60LL);
}
queue_add_internal(a1, v14, i[4], ptr, i[5], 0LL, a4);
++*a5;
free(v14);
}
free(ptr);
}
}

original_code:
static void queue_resolve_directory_recursively(const char *nick,
        fl_dir_t *root,
        const char *directory,
        const char *target_directory,
        unsigned *nfiles_p)
{
    fl_file_t *file;
    int num_returned_bytes;
    for((file) = ((&root->files)->tqh_first); (file) != ((void *)0); (file) = ((file)->link.tqe_next))
    {
        char *target;
        num_returned_bytes = asprintf(&target, "%s/%s", directory, file->name);
        if (num_returned_bytes == -1)
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 48);
        if(file->dir)
        {
            queue_resolve_directory_recursively(nick, file->dir,
                    target, target_directory, nfiles_p);
        }
        else
        {
            char *source;
            num_returned_bytes = asprintf(&source, "%s\\%s", root->path, file->name);
            if (num_returned_bytes == -1)
                sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 60);
            queue_add_internal(nick, source, file->size, target,
                    file->tth, 0, target_directory);
            if(nfiles_p)
                (*nfiles_p)++;
            free(source);
        }
        free(target);
    }
}

canonical_original_code:
static void queue_resolve_directory_recursively(char *nick, struct fl_dir *root, char *directory, char *target_directory, unsigned int *nfiles_p)
{
    struct fl_file *file;
    int num_returned_bytes;
    for((file) = ((&root->files)->tqh_first); (file) != ((void *)0); (file) = ((file)->link.tqe_next))
    {
        char *target;
        num_returned_bytes = asprintf(&target, "%s/%s", directory, file->name);
        if (num_returned_bytes == -1)
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 48);
        if(file->dir)
        {
            queue_resolve_directory_recursively(nick, file->dir,
                    target, target_directory, nfiles_p);
        }
        else
        {
            char *source;
            num_returned_bytes = asprintf(&source, "%s\\%s", root->path, file->name);
            if (num_returned_bytes == -1)
                sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "asprintf did not return anything", getpid(), __func__, 60);
            queue_add_internal(nick, source, file->size, target,
                    file->tth, 0, target_directory);
            if(nfiles_p)
                (*nfiles_p)++;
            free(source);
        }
        free(target);
    }
}

variable_types: struct fl_dir { struct { struct fl_dir *le_next; struct fl_dir **le_prev; } link; struct fl_file_list { struct fl_file { struct { struct fl_file *tqe_next; struct fl_file **tqe_prev; } link; char *name; enum share_type { SHARE_TYPE_ANY=1, SHARE_TYPE_AUDIO=2, SHARE_TYPE_COMPRESSED=3, SHARE_TYPE_DOCUMENT=4, SHARE_TYPE_EXECUTABLE=5, SHARE_TYPE_IMAGE=6, SHARE_TYPE_MOVIE=7, SHARE_TYPE_DIRECTORY=8, SHARE_TYPE_TTH=9 } type; unsigned long size; char *tth; struct fl_dir *dir; } *tqh_first; struct fl_file **tqh_last; } files; char *path; unsigned int nfiles; unsigned long size; } *

variable_types:
directory
char *

variable_types: struct fl_file { struct { struct fl_file *tqe_next; struct fl_file **tqe_prev; } link; char *name; enum share_type { SHARE_TYPE_ANY=1, SHARE_TYPE_AUDIO=2, SHARE_TYPE_COMPRESSED=3, SHARE_TYPE_DOCUMENT=4, SHARE_TYPE_EXECUTABLE=5, SHARE_TYPE_IMAGE=6, SHARE_TYPE_MOVIE=7, SHARE_TYPE_DIRECTORY=8, SHARE_TYPE_TTH=9 } type; unsigned long size; char *tth; struct fl_dir { struct { struct fl_dir *le_next; struct fl_dir **le_prev; } link; struct fl_file_list { struct fl_file *tqh_first; struct fl_file **tqh_last; } files; char *path; unsigned int nfiles; unsigned long size; } *dir; } *

variable_types:
target
char *

variable_types:
source
char *

user_defined_types: struct fl_dir { struct { struct fl_dir *le_next; struct fl_dir **le_prev; } link; struct fl_file_list files; char *path; unsigned int nfiles; unsigned long size; }

user_defined_types: struct fl_file { struct { struct fl_file *tqe_next; struct fl_file **tqe_prev; } link; char *name; enum share_type type; unsigned long size; char *tth; struct fl_dir *dir; }


decompiled_code:
__int64 __fastcall queue_remove_directory(char *s1)
{
char *i; // rbp
unsigned int v2; // eax
_QWORD *v3; // rbx
_QWORD *v4; // r12
const char *v5; // rsi
const char *v6; // r13
unsigned int v7; // eax
__int64 result; // rax
unsigned int v9; // eax

if ( s1 )
{
for ( i = s1; *i == 47; ++i )
;
v2 = getpid();
sp_log(64LL, "[%d] (%s:%i) removing targets in directory [%s]", v2, "queue_remove_directory", 177LL, i);
v3 = *(_QWORD **)(q_store + 24LL);
while ( v3 )
{
while ( 1 )
{
v4 = v3;
v3 = (_QWORD *)*v3;
v5 = (const char *)v4[8];
if ( !v5 || strcmp(i, v5) )
break;
queue_remove_sources(v4[2]);
v6 = (const char *)v4[2];
v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) removing target [%s]", v7, "queue_remove_directory", 188LL, v6);
queue_db_remove_target(v4[2]);
if ( !v3 )
goto LABEL_9;
}
}
LABEL_9:
queue_db_remove_directory(i);
result = 0LL;
}
else
{
v9 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: target_directory", v9, "queue_remove_directory", 168LL);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *s1)
{
char *i; // rbp
unsigned int v2; // eax
_QWORD *v3; // rbx
_QWORD *v4; // r12
const char *v5; // rsi
const char *v6; // r13
unsigned int v7; // eax
__int64 result; // rax
unsigned int v9; // eax

if ( s1 )
{
for ( i = s1; *i == 47; ++i )
;
v2 = getpid();
sp_log(64LL, "[%d] (%s:%i) removing targets in directory [%s]", v2, "queue_remove_directory", 177LL, i);
v3 = *(_QWORD **)(q_store + 24LL);
while ( v3 )
{
while ( 1 )
{
v4 = v3;
v3 = (_QWORD *)*v3;
v5 = (const char *)v4[8];
if ( !v5 || strcmp(i, v5) )
break;
queue_remove_sources(v4[2]);
v6 = (const char *)v4[2];
v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) removing target [%s]", v7, "queue_remove_directory", 188LL, v6);
queue_db_remove_target(v4[2]);
if ( !v3 )
goto LABEL_9;
}
}
LABEL_9:
queue_db_remove_directory(i);
result = 0LL;
}
else
{
v9 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: target_directory", v9, "queue_remove_directory", 168LL);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int queue_remove_directory(const char *target_directory)
{
    do { if(!(target_directory)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "target_directory", getpid(), __func__, 168); return (-1); } } while(0);
    while(*target_directory == '/')
        ++target_directory;
    sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "removing targets in directory [%s]", getpid(), __func__, 177, target_directory);
    struct queue_target *qt, *next;
    for(qt = ((&q_store->targets)->tqh_first); qt; qt = next)
    {
 next = ((qt)->link.tqe_next);
        if(qt->target_directory &&
    strcmp(target_directory, qt->target_directory) == 0)
        {
            queue_remove_sources(qt->filename);
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "removing target [%s]", getpid(), __func__, 188, qt->filename);
     queue_db_remove_target(qt->filename);
        }
    }
    queue_db_remove_directory(target_directory);
    return 0;
}

canonical_original_code:
int queue_remove_directory(char *target_directory)
{
    do { if(!(target_directory)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "target_directory", getpid(), __func__, 168); return (-1); } } while(0);
    while(*target_directory == '/')
        ++target_directory;
    sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "removing targets in directory [%s]", getpid(), __func__, 177, target_directory);
    struct queue_target *qt; struct queue_target *next;
    for(qt = ((&q_store->targets)->tqh_first); qt; qt = next)
    {
 next = ((qt)->link.tqe_next);
        if(qt->target_directory &&
    strcmp(target_directory, qt->target_directory) == 0)
        {
            queue_remove_sources(qt->filename);
            sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "removing target [%s]", getpid(), __func__, 188, qt->filename);
     queue_db_remove_target(qt->filename);
        }
    }
    queue_db_remove_directory(target_directory);
    return 0;
}

variable_types: struct queue_target { struct { struct queue_target *tqe_next; struct queue_target **tqe_prev; } link; char *filename; char tth[40]; char *target_directory; unsigned long size; unsigned int flags; long ctime; int priority; unsigned int seq; } *


decompiled_code:
__int64 __fastcall queue_resolve_directory(const char *a1, const char *a2, char *a3, unsigned int *a4)
{
unsigned int v7; // eax
__int64 v8; // rax
char *v9; // r12
unsigned int v10; // eax
const char *v11; // rsi
__int64 v12; // r13
__int64 v13; // rdx
__int64 v14; // rsi
__int64 result; // rax
unsigned int v16; // eax
unsigned int v17; // eax
__int64 v18; // [rsp-8h] [rbp-50h]
unsigned int v19[15]; // [rsp+Ch] [rbp-3Ch] BYREF

v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) resolving directory [%s] for nick [%s]", v7, "queue_resolve_directory", 87LL, a2, a1);
v8 = find_filelist(global_working_directory, a1);
if ( v8 )
{
v9 = (char *)v8;
v10 = getpid();
sp_log(64LL, "[%d] (%s:%i) found filelist for [%s] in [%s]", v10, "queue_resolve_directory", 94LL, a1, v9);
v11 = 0LL;
v12 = fl_parse(v9, 0LL);
v13 = v18;
if ( v12 )
{
v14 = ((__int64 (__fastcall *)(__int64, const char *))fl_find_directory)(v12, a2);
if ( v14 )
{
v19[0] = 0;
queue_resolve_directory_recursively((__int64)a1, v14, a3, (__int64)a3, v19);
v11 = (const char *)v19[0];
if ( a4 )
*a4 = v19[0];
queue_db_set_resolved(a3, v11);
}
else
{
v17 = getpid();
v11 = "[%d] (%s:%i) source directory not found, removing from queue";
sp_log(
32LL,
"[%d] (%s:%i) source directory not found, removing from queue",
v17,
"queue_resolve_directory",
119LL);
queue_remove_directory(a3);
}
}
fl_free_dir(v12, v11, v13);
free(v9);
result = 0LL;
}
else
{
v16 = getpid();
sp_log(64LL, "[%d] (%s:%i) filelist for [%s] not available, queueing", v16, "queue_resolve_directory", 129LL, a1);
queue_add_filelist(a1, 1LL);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1, const char *a2, char *a3, unsigned int *a4)
{
unsigned int v7; // eax
__int64 v8; // rax
char *v9; // r12
unsigned int v10; // eax
const char *v11; // rsi
__int64 v12; // r13
__int64 v13; // rdx
__int64 v14; // rsi
__int64 result; // rax
unsigned int v16; // eax
unsigned int v17; // eax
__int64 v18; // [rsp-8h] [rbp-50h]
unsigned int v19[15]; // [rsp+Ch] [rbp-3Ch] BYREF

v7 = getpid();
sp_log(64LL, "[%d] (%s:%i) resolving directory [%s] for nick [%s]", v7, "queue_resolve_directory", 87LL, a2, a1);
v8 = find_filelist(global_working_directory, a1);
if ( v8 )
{
v9 = (char *)v8;
v10 = getpid();
sp_log(64LL, "[%d] (%s:%i) found filelist for [%s] in [%s]", v10, "queue_resolve_directory", 94LL, a1, v9);
v11 = 0LL;
v12 = fl_parse(v9, 0LL);
v13 = v18;
if ( v12 )
{
v14 = ((__int64 (__fastcall *)(__int64, const char *))fl_find_directory)(v12, a2);
if ( v14 )
{
v19[0] = 0;
func0((__int64)a1, v14, a3, (__int64)a3, v19);
v11 = (const char *)v19[0];
if ( a4 )
*a4 = v19[0];
queue_db_set_resolved(a3, v11);
}
else
{
v17 = getpid();
v11 = "[%d] (%s:%i) source directory not found, removing from queue";
sp_log(
32LL,
"[%d] (%s:%i) source directory not found, removing from queue",
v17,
"queue_resolve_directory",
119LL);
func1(a3);
}
}
fl_free_dir(v12, v11, v13);
free(v9);
result = 0LL;
}
else
{
v16 = getpid();
sp_log(64LL, "[%d] (%s:%i) filelist for [%s] not available, queueing", v16, "queue_resolve_directory", 129LL, a1);
queue_add_filelist(a1, 1LL);
result = 1LL;
}
return result;
}

original_code:
int queue_resolve_directory(const char *nick,
        const char *source_directory,
        const char *target_directory,
        unsigned *nfiles_p)
{
    sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "resolving directory [%s] for nick [%s]", getpid(), __func__, 87, source_directory, nick);
    char *filelist_path = find_filelist(global_working_directory, nick);
    if(filelist_path)
    {
 sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "found filelist for [%s] in [%s]", getpid(), __func__, 94, nick, filelist_path);
        fl_dir_t *root = fl_parse(filelist_path, ((void *)0));
        if(root)
        {
            fl_dir_t *fl = fl_find_directory(root, source_directory);
            if(fl)
            {
                unsigned nfiles = 0;
                queue_resolve_directory_recursively(nick, fl,
                        target_directory, target_directory,
                        &nfiles);
                if(nfiles_p)
                    *nfiles_p = nfiles;
  queue_db_set_resolved(target_directory, nfiles);
            }
            else
            {
                sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "source directory not found, removing from queue", getpid(), __func__, 119);
                queue_remove_directory(target_directory);
            }
        }
        fl_free_dir(root);
        free(filelist_path);
    }
    else
    {
 sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "filelist for [%s] not available, queueing", getpid(), __func__, 129, nick);
        queue_add_filelist(nick, 1 );
        return 1;
    }
    return 0;
}

canonical_original_code:
int queue_resolve_directory(char *nick, char *source_directory, char *target_directory, unsigned int *nfiles_p)
{
    sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "resolving directory [%s] for nick [%s]", getpid(), __func__, 87, source_directory, nick);
    char *filelist_path = find_filelist(global_working_directory, nick);
    if(filelist_path)
    {
 sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "found filelist for [%s] in [%s]", getpid(), __func__, 94, nick, filelist_path);
        struct fl_dir *root = fl_parse(filelist_path, ((void *)0));
        if(root)
        {
            struct fl_dir *fl = fl_find_directory(root, source_directory);
            if(fl)
            {
                unsigned int nfiles = 0;
                queue_resolve_directory_recursively(nick, fl,
                        target_directory, target_directory,
                        &nfiles);
                if(nfiles_p)
                    *nfiles_p = nfiles;
  queue_db_set_resolved(target_directory, nfiles);
            }
            else
            {
                sp_log(LOG_LEVEL_INFO, "[%d] (%s:%i) " "source directory not found, removing from queue", getpid(), __func__, 119);
                queue_remove_directory(target_directory);
            }
        }
        fl_free_dir(root);
        free(filelist_path);
    }
    else
    {
 sp_log(LOG_LEVEL_DEBUG, "[%d] (%s:%i) " "filelist for [%s] not available, queueing", getpid(), __func__, 129, nick);
        queue_add_filelist(nick, 1 );
        return 1;
    }
    return 0;
}

variable_types:
nfiles
unsigned int

user_defined_types: struct fl_file_list { struct fl_file *tqh_first; struct fl_file **tqh_last; }

user_defined_types: enum share_type { SHARE_TYPE_ANY=1, SHARE_TYPE_AUDIO=2, SHARE_TYPE_COMPRESSED=3, SHARE_TYPE_DOCUMENT=4, SHARE_TYPE_EXECUTABLE=5, SHARE_TYPE_IMAGE=6, SHARE_TYPE_MOVIE=7, SHARE_TYPE_DIRECTORY=8, SHARE_TYPE_TTH=9 }


decompiled_code:
__int64 __fastcall queue_add_directory(const char *a1, const char *a2, char *a3)
{
char *v3; // r12
__int64 v4; // rax
__int64 result; // rax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9[7]; // [rsp+Ch] [rbp-1Ch] BYREF

if ( a1 )
{
if ( a2 )
{
v3 = a3;
if ( a3 )
{
if ( *a3 == 47 )
{
do
++v3;
while ( *v3 == 47 );
}
queue_db_add_directory(v3, a1, a2);
v4 = nc_default();
nc_send_queue_directory_added_notification(v4, v3, a1);
v9[0] = 0;
queue_resolve_directory(a1, a2, v3, v9);
result = 0LL;
}
else
{
v7 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: target_directory", v7, "queue_add_directory", 143LL);
result = 0xFFFFFFFFLL;
}
}
else
{
v8 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: source_directory", v8, "queue_add_directory", 142LL);
result = 0xFFFFFFFFLL;
}
}
else
{
v6 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: nick", v6, "queue_add_directory", 141LL);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(const char *a1, const char *a2, char *a3)
{
char *v3; // r12
__int64 v4; // rax
__int64 result; // rax
unsigned int v6; // eax
unsigned int v7; // eax
unsigned int v8; // eax
unsigned int v9[7]; // [rsp+Ch] [rbp-1Ch] BYREF

if ( a1 )
{
if ( a2 )
{
v3 = a3;
if ( a3 )
{
if ( *a3 == 47 )
{
do
++v3;
while ( *v3 == 47 );
}
queue_db_add_directory(v3, a1, a2);
v4 = nc_default();
nc_send_queue_directory_added_notification(v4, v3, a1);
v9[0] = 0;
func2(a1, a2, v3, v9);
result = 0LL;
}
else
{
v7 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: target_directory", v7, "queue_add_directory", 143LL);
result = 0xFFFFFFFFLL;
}
}
else
{
v8 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: source_directory", v8, "queue_add_directory", 142LL);
result = 0xFFFFFFFFLL;
}
}
else
{
v6 = getpid();
sp_log(16LL, "[%d] (%s:%i) assert failed: nick", v6, "queue_add_directory", 141LL);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int queue_add_directory(const char *nick,
        const char *source_directory,
        const char *target_directory)
{
    do { if(!(nick)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "nick", getpid(), __func__, 141); return (-1); } } while(0);
    do { if(!(source_directory)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "source_directory", getpid(), __func__, 142); return (-1); } } while(0);
    do { if(!(target_directory)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "target_directory", getpid(), __func__, 143); return (-1); } } while(0);
    while(*target_directory == '/')
        ++target_directory;
    queue_db_add_directory(target_directory, nick, source_directory);
    nc_send_queue_directory_added_notification(nc_default(),
 target_directory, nick);
    unsigned nfiles = 0;
    queue_resolve_directory(nick, source_directory, target_directory, &nfiles);
    return 0;
}

canonical_original_code:
int queue_add_directory(char *nick, char *source_directory, char *target_directory)
{
    do { if(!(nick)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "nick", getpid(), __func__, 141); return (-1); } } while(0);
    do { if(!(source_directory)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "source_directory", getpid(), __func__, 142); return (-1); } } while(0);
    do { if(!(target_directory)) { sp_log(LOG_LEVEL_WARNING, "[%d] (%s:%i) " "assert failed: " "target_directory", getpid(), __func__, 143); return (-1); } } while(0);
    while(*target_directory == '/')
        ++target_directory;
    queue_db_add_directory(target_directory, nick, source_directory);
    nc_send_queue_directory_added_notification(nc_default(),
 target_directory, nick);
    unsigned int nfiles = 0;
    queue_resolve_directory(nick, source_directory, target_directory, &nfiles);
    return 0;
}


decompiled_code:
void __fastcall xs_free(void *ptr)
{
__int64 v1; // rax
_QWORD *v3; // rdx
void *v4; // rdi

if ( ptr )
{
v1 = *(_QWORD *)ptr;
if ( *(_QWORD *)ptr )
*(_QWORD *)(v1 + 8) = *((_QWORD *)ptr + 1);
v3 = (_QWORD *)*((_QWORD *)ptr + 1);
v4 = (void *)*((_QWORD *)ptr + 2);
*v3 = v1;
free(v4);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func0(void *ptr)
{
__int64 v1; // rax
_QWORD *v3; // rdx
void *v4; // rdi

if ( ptr )
{
v1 = *(_QWORD *)ptr;
if ( *(_QWORD *)ptr )
*(_QWORD *)(v1 + 8) = *((_QWORD *)ptr + 1);
v3 = (_QWORD *)*((_QWORD *)ptr + 1);
v4 = (void *)*((_QWORD *)ptr + 2);
*v3 = v1;
free(v4);
free(ptr);
}
}

original_code:
static void xs_free(struct extra_slot *xs)
{
 if(xs)
 {
  do { if ((xs)->link.le_next != ((void *)0)) (xs)->link.le_next->link.le_prev = (xs)->link.le_prev; *(xs)->link.le_prev = (xs)->link.le_next; } while (0);
  free(xs->nick);
  free(xs);
 }
}

variable_types: struct extra_slot { struct { struct extra_slot *le_next; struct extra_slot **le_prev; } link; char *nick; char *hub_address; int extra_slots; } *