decompiled_code:
__int64 __fastcall defilters_from_extensions(const char *a1)
{
__int64 v1; // rbp
char *v2; // r12
void *v3; // rax
char *v4; // rax
char *v5; // rbx
char v7[4120]; // [rsp+0h] [rbp-1018h] BYREF

v1 = 0LL;
v2 = strdup(a1);
while ( 1 )
{
v4 = strrchr(v2, 46);
v5 = v4;
if ( !v4 || !strcmp(v4 + 1, "tar") )
break;
snprintf(v7, 0x1000uLL, "%s -d", v4 + 1);
v3 = append_filter_spaces(v1, v7);
*v5 = 0;
v1 = (__int64)v3;
}
free(v2);
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func7(const char *a1)
{
__int64 v1; // rbp
char *v2; // r12
void *v3; // rax
char *v4; // rax
char *v5; // rbx
char v7[4120]; // [rsp+0h] [rbp-1018h] BYREF

v1 = 0LL;
v2 = strdup(a1);
while ( 1 )
{
v4 = strrchr(v2, 46);
v5 = v4;
if ( !v4 || !strcmp(v4 + 1, "tar") )
break;
snprintf(v7, 0x1000uLL, "%s -d", v4 + 1);
v3 = func5(v1, v7);
*v5 = 0;
v1 = (__int64)v3;
}
free(v2);
return v1;
}

original_code:
struct filter *
defilters_from_extensions(const char *filename)
{
    struct filter *f = 0;
    char *tmp = strdup(filename);
    char *pos = tmp;
    while((pos = strrchr(tmp, '.')) != 0)
    {
        pos = pos+1;
        if (!strcmp(pos, "tar"))
            break;
        else
        {
            char command[4096];
            snprintf(command, sizeof command, "%s -d", pos);
            f = append_filter_spaces(f, command);
        }
        --pos;
        *pos = '\0';
        --pos;
    }
    free(tmp);
    return f;
}

canonical_original_code:
struct filter *defilters_from_extensions(char *filename)
{
    struct filter *f = 0;
    char *tmp = strdup(filename);
    char *pos = tmp;
    while((pos = strrchr(tmp, '.')) != 0)
    {
        pos = pos+1;
        if (!strcmp(pos, "tar"))
            break;
        else
        {
            char command[4096];
            snprintf(command, sizeof command, "%s -d", pos);
            f = append_filter_spaces(f, command);
        }
        --pos;
        *pos = '\0';
        --pos;
    }
    free(tmp);
    return f;
}

variable_types:
filename
char *

variable_types:
command
char [4096]


repo: mwpher/btar-fbsd

decompiled_code:
void __fastcall free_filters(void *ptr)
{
void ***v1; // rbx
void ***v2; // rbp

if ( ptr )
{
v1 = (void ***)ptr;
do
{
v2 = v1;
v1 = (void ***)v1[1];
free(**v2);
free(*v2);
free(v2);
}
while ( v1 );
}
}

canonical_decompiled_code:
void __fastcall func8(void *ptr)
{
void ***v1; // rbx
void ***v2; // rbp

if ( ptr )
{
v1 = (void ***)ptr;
do
{
v2 = v1;
v1 = (void ***)v1[1];
free(**v2);
free(*v2);
free(v2);
}
while ( v1 );
}
}

original_code:
void
free_filters(struct filter *f)
{
    while(f)
    {
        struct filter *next = f->next;
        free(f->args[0]);
        free(f->args);
        free(f);
        f = next;
    }
}

variable_types: struct filter { char **args; struct filter *next; char extensions[4096]; } *

return_type: void


decompiled_code:
__int64 __fastcall block_process_can_read(__int64 *a1)
{
__int64 v1; // rbx
__int64 result; // rax

v1 = a1[3];
if ( filter )
v1 = *a1;
result = block_can_accept(v1);
if ( (_DWORD)result )
result = *(_QWORD *)(v1 + 40) < command_line[1];
return result;
}

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

v1 = a1[3];
if ( filter )
v1 = *a1;
result = block_can_accept(v1);
if ( (_DWORD)result )
result = *(_QWORD *)(v1 + 40) < command_line[1];
return result;
}

original_code:
int
block_process_can_read(const struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    if (block_can_accept(b) &&
            b->total_written < command_line.blocksize)
        return 1;
    return 0;
}

canonical_original_code:
int block_process_can_read(struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    if (block_can_accept(b) &&
            b->total_written < command_line.blocksize)
        return 1;
    return 0;
}

variable_types: struct block_process { struct block { char *data; struct block_reader { struct block *b; unsigned long pos; } **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *bi; struct block_reader *br_to_filter; int fd_filterin; int fd_filterout; struct block *bo; unsigned long left; int closed_in; int block_finished; int nblock; int has_read; int finished_read_ack; } *

return_type: int

user_defined_types: struct block_process { struct block *bi; struct block_reader *br_to_filter; int fd_filterin; int fd_filterout; struct block *bo; unsigned long left; int closed_in; int block_finished; int nblock; int has_read; int finished_read_ack; }

user_defined_types: struct block { char *data; struct block_reader **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; }


decompiled_code:
__int64 __fastcall block_process_total_read(__int64 *a1)
{
__int64 v1; // rax

v1 = a1[3];
if ( filter )
v1 = *a1;
return *(_QWORD *)(v1 + 40);
}

original_code:
size_t
block_process_total_read(const struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    return b->total_written;
}

canonical_original_code:
unsigned long block_process_total_read(struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    return b->total_written;
}

variable_types: struct block { char *data; struct block_reader { struct block *b; unsigned long pos; } **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *

return_type: unsigned long


decompiled_code:
_BOOL8 __fastcall block_process_finished_reading(__int64 *a1)
{
__int64 v1; // rdx
_BOOL8 result; // rax

v1 = a1[3];
if ( filter )
v1 = *a1;
result = 1LL;
if ( !*((_DWORD *)a1 + 10) )
result = *(_QWORD *)(v1 + 40) == command_line[1];
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(__int64 *a1)
{
__int64 v1; // rdx
_BOOL8 result; // rax

v1 = a1[3];
if ( filter )
v1 = *a1;
result = 1LL;
if ( !*((_DWORD *)a1 + 10) )
result = *(_QWORD *)(v1 + 40) == command_line[1];
return result;
}

original_code:
int
block_process_finished_reading(struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    if ((bp->closed_in || b->total_written == command_line.blocksize))
        return 1;
    return 0;
}

user_defined_types: struct block_reader { struct block *b; unsigned long pos; }


decompiled_code:
__int64 __fastcall block_process_finished(__int64 *a1)
{
__int64 v1; // r8
__int64 result; // rax

v1 = a1[3];
if ( filter )
v1 = *a1;
result = *((unsigned int *)a1 + 11);
if ( (_DWORD)result )
result = (unsigned int)block_are_readers_done(v1) != 0;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1)
{
__int64 v1; // r8
__int64 result; // rax

v1 = a1[3];
if ( filter )
v1 = *a1;
result = *((unsigned int *)a1 + 11);
if ( (_DWORD)result )
result = (unsigned int)block_are_readers_done(v1) != 0;
return result;
}

original_code:
int
block_process_finished(struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    return bp->block_finished && block_are_readers_done(b);
}


decompiled_code:
__int64 __fastcall block_process_reset(__int64 a1, int a2)
{
bool v2; // zf
__int64 result; // rax

if ( filter )
{
v2 = *(_QWORD *)(*(_QWORD *)a1 + 24LL) == 0LL;
*(_QWORD *)(*(_QWORD *)a1 + 40LL) = 0LL;
if ( !v2 )
_assert_fail("bp->bi->writer_pos == 0", "blockprocess.c", 0x76u, "block_process_reset");
if ( *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) )
_assert_fail("bp->br_to_filter->pos == 0", "blockprocess.c", 0x77u, "block_process_reset");
}
result = *(_QWORD *)(a1 + 24);
if ( *(_QWORD *)(result + 24) )
_assert_fail("bp->bo->writer_pos == 0", "blockprocess.c", 0x7Au, "block_process_reset");
*(_QWORD *)(result + 40) = 0LL;
*(_DWORD *)(a1 + 48) = a2;
*(_DWORD *)(a1 + 44) = 1;
*(_QWORD *)(a1 + 52) = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, int a2)
{
bool v2; // zf
__int64 result; // rax

if ( filter )
{
v2 = *(_QWORD *)(*(_QWORD *)a1 + 24LL) == 0LL;
*(_QWORD *)(*(_QWORD *)a1 + 40LL) = 0LL;
if ( !v2 )
_assert_fail("bp->bi->writer_pos == 0", "blockprocess.c", 0x76u, "block_process_reset");
if ( *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL) )
_assert_fail("bp->br_to_filter->pos == 0", "blockprocess.c", 0x77u, "block_process_reset");
}
result = *(_QWORD *)(a1 + 24);
if ( *(_QWORD *)(result + 24) )
_assert_fail("bp->bo->writer_pos == 0", "blockprocess.c", 0x7Au, "block_process_reset");
*(_QWORD *)(result + 40) = 0LL;
*(_DWORD *)(a1 + 48) = a2;
*(_DWORD *)(a1 + 44) = 1;
*(_QWORD *)(a1 + 52) = 0LL;
return result;
}

original_code:
void
block_process_reset(struct block_process *bp, int nblock)
{
    if (filter)
    {
        bp->bi->total_written = 0;
        ((void) sizeof ((bp->bi->writer_pos == 0) ? 1 : 0), __extension__ ({ if (bp->bi->writer_pos == 0) ; else __assert_fail ("bp->bi->writer_pos == 0", "blockprocess.c", 118, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((bp->br_to_filter->pos == 0) ? 1 : 0), __extension__ ({ if (bp->br_to_filter->pos == 0) ; else __assert_fail ("bp->br_to_filter->pos == 0", "blockprocess.c", 119, __extension__ __PRETTY_FUNCTION__); }));
    }
    ((void) sizeof ((bp->bo->writer_pos == 0) ? 1 : 0), __extension__ ({ if (bp->bo->writer_pos == 0) ; else __assert_fail ("bp->bo->writer_pos == 0", "blockprocess.c", 122, __extension__ __PRETTY_FUNCTION__); }));
    bp->bo->total_written = 0;
    bp->nblock = nblock;
    bp->block_finished = 1;
    bp->has_read = 0;
    bp->finished_read_ack = 0;
}

variable_types: nblock int


decompiled_code:
void __fastcall prepare_readfds(__int64 a1, __int64 a2, __int64 a3, int a4)
{
if ( filter && *(int *)(a1 + 20) >= 0 && (unsigned int)block_can_accept(*(_QWORD *)(a1 + 24)) )
addfd(a2, *(unsigned int *)(a1 + 20), a3);
if ( a4 && !*(_DWORD *)(a1 + 40) )
{
if ( (unsigned int)block_process_can_read((__int64 *)a1) )
addfd(a2, 0LL, a3);
}
}

canonical_decompiled_code:
void __fastcall func5(__int64 a1, __int64 a2, __int64 a3, int a4)
{
if ( filter && *(int *)(a1 + 20) >= 0 && (unsigned int)block_can_accept(*(_QWORD *)(a1 + 24)) )
addfd(a2, *(unsigned int *)(a1 + 20), a3);
if ( a4 && !*(_DWORD *)(a1 + 40) )
{
if ( (unsigned int)func0((__int64 *)a1) )
addfd(a2, 0LL, a3);
}
}

original_code:
void
prepare_readfds(struct block_process *bp, fd_set *fdset, int *nfds, int should_read)
{
    struct block *b = bp->bo;
    if (filter)
    {
        if (bp->fd_filterout >= 0 && block_can_accept(b))
        {
            addfd(fdset, bp->fd_filterout, nfds);
        }
        b = bp->bi;
    }
    if (should_read && !bp->closed_in && block_process_can_read(bp))
        addfd(fdset, 0, nfds);
}

canonical_original_code:
void prepare_readfds(struct block_process *bp, struct fd_set *fdset, int *nfds, int should_read)
{
    struct block *b = bp->bo;
    if (filter)
    {
        if (bp->fd_filterout >= 0 && block_can_accept(b))
        {
            addfd(fdset, bp->fd_filterout, nfds);
        }
        b = bp->bi;
    }
    if (should_read && !bp->closed_in && block_process_can_read(bp))
        addfd(fdset, 0, nfds);
}

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

variable_types:
nfds
int *


decompiled_code:
__int64 __fastcall prepare_writefds(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 16);
if ( (int)result >= 0 )
{
result = block_reader_can_read(*(_QWORD *)(a1 + 8));
if ( (_DWORD)result )
result = addfd(a2, *(unsigned int *)(a1 + 16), a3);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 16);
if ( (int)result >= 0 )
{
result = block_reader_can_read(*(_QWORD *)(a1 + 8));
if ( (_DWORD)result )
result = addfd(a2, *(unsigned int *)(a1 + 16), a3);
}
return result;
}

original_code:
void
prepare_writefds(struct block_process *bp, fd_set *fdset, int *nfds)
{
    if (bp->fd_filterin >= 0 && block_reader_can_read(bp->br_to_filter))
    {
        addfd(fdset, bp->fd_filterin, nfds);
    }
}

canonical_original_code:
void prepare_writefds(struct block_process *bp, struct fd_set *fdset, int *nfds)
{
    if (bp->fd_filterin >= 0 && block_reader_can_read(bp->br_to_filter))
    {
        addfd(fdset, bp->fd_filterin, nfds);
    }
}


decompiled_code:
void __fastcall check_write_fds(__int64 a1, __int64 a2)
{
int v2; // ecx

v2 = *(_DWORD *)(a1 + 16);
if ( v2 >= 0 && (*(_QWORD *)(a2 + 8LL * (v2 >> 6)) & (1LL << v2)) != 0 )
{
if ( (unsigned int)block_reader_to_fd(*(_QWORD *)(a1 + 8), (unsigned int)v2) == -1 && *_errno_location() != 4 )
fatal_errno("Failed write to filter");
if ( *(_QWORD *)(*(_QWORD *)a1 + 40LL) == command_line[1]
&& !(unsigned int)block_reader_can_read(*(_QWORD *)(a1 + 8))
|| *(_DWORD *)(a1 + 40) && !(unsigned int)block_reader_can_read(*(_QWORD *)(a1 + 8)) )
{
close(*(_DWORD *)(a1 + 16));
*(_DWORD *)(a1 + 16) = -1;
}
}
}

canonical_decompiled_code:
void __fastcall func8(__int64 a1, __int64 a2)
{
int v2; // ecx

v2 = *(_DWORD *)(a1 + 16);
if ( v2 >= 0 && (*(_QWORD *)(a2 + 8LL * (v2 >> 6)) & (1LL << v2)) != 0 )
{
if ( (unsigned int)block_reader_to_fd(*(_QWORD *)(a1 + 8), (unsigned int)v2) == -1 && *_errno_location() != 4 )
fatal_errno("Failed write to filter");
if ( *(_QWORD *)(*(_QWORD *)a1 + 40LL) == command_line[1]
&& !(unsigned int)block_reader_can_read(*(_QWORD *)(a1 + 8))
|| *(_DWORD *)(a1 + 40) && !(unsigned int)block_reader_can_read(*(_QWORD *)(a1 + 8)) )
{
close(*(_DWORD *)(a1 + 16));
*(_DWORD *)(a1 + 16) = -1;
}
}
}

original_code:
void
check_write_fds(struct block_process *bp, fd_set *writefds)
{
    if (bp->fd_filterin >= 0 && ((((writefds)->__fds_bits)[((bp->fd_filterin) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((bp->fd_filterin) % (8 * (int) sizeof (__fd_mask)))))) != 0))
    {
        int nwritten = block_reader_to_fd(bp->br_to_filter, bp->fd_filterin);
        if (nwritten == -1 && (*__errno_location ()) != 4)
            fatal_errno("Failed write to filter");
        if (bp->bi->total_written == command_line.blocksize &&
                !block_reader_can_read(bp->br_to_filter))
        {
            close(bp->fd_filterin);
            bp->fd_filterin = -1;
        }
        else if(bp->closed_in && !block_reader_can_read(bp->br_to_filter))
        {
            close(bp->fd_filterin);
            bp->fd_filterin = -1;
        }
    }
}

canonical_original_code:
void check_write_fds(struct block_process *bp, struct fd_set *writefds)
{
    if (bp->fd_filterin >= 0 && ((((writefds)->__fds_bits)[((bp->fd_filterin) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((bp->fd_filterin) % (8 * (int) sizeof (__fd_mask)))))) != 0))
    {
        int nwritten = block_reader_to_fd(bp->br_to_filter, bp->fd_filterin);
        if (nwritten == -1 && (*__errno_location ()) != 4)
            fatal_errno("Failed write to filter");
        if (bp->bi->total_written == command_line.blocksize &&
                !block_reader_can_read(bp->br_to_filter))
        {
            close(bp->fd_filterin);
            bp->fd_filterin = -1;
        }
        else if(bp->closed_in && !block_reader_can_read(bp->br_to_filter))
        {
            close(bp->fd_filterin);
            bp->fd_filterin = -1;
        }
    }
}

variable_types: nwritten int


decompiled_code:
__int64 __fastcall xor_to_xorblock(__int64 a1, _QWORD *a2)
{
__int64 v2; // r12
__int64 v3; // rax
__int64 result; // rax
_BYTE *v5; // rdx
char v6; // cl

v2 = *(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL);
v3 = a2[4];
if ( !v3 )
_assert_fail("oldsize > 0", "blockprocess.c", 0x115u, "xor_to_xorblock");
result = block_realloc_set(a2, v2 + 1, (unsigned int)*(char *)(*a2 + v3 - 1));
if ( v2 )
{
for ( result = 0LL; result != v2; ++result )
{
v5 = (_BYTE *)(result + *a2);
v6 = *(_BYTE *)(**(_QWORD **)(a1 + 24) + result);
*v5 ^= v6;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, _QWORD *a2)
{
__int64 v2; // r12
__int64 v3; // rax
__int64 result; // rax
_BYTE *v5; // rdx
char v6; // cl

v2 = *(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL);
v3 = a2[4];
if ( !v3 )
_assert_fail("oldsize > 0", "blockprocess.c", 0x115u, "xor_to_xorblock");
result = block_realloc_set(a2, v2 + 1, (unsigned int)*(char *)(*a2 + v3 - 1));
if ( v2 )
{
for ( result = 0LL; result != v2; ++result )
{
v5 = (_BYTE *)(result + *a2);
v6 = *(_BYTE *)(**(_QWORD **)(a1 + 24) + result);
*v5 ^= v6;
}
}
return result;
}

original_code:
void
xor_to_xorblock(struct block_process *bp, struct block *xorblock)
{
    size_t mysize = bp->bo->writer_pos;
    size_t xorsize = mysize + 1 ;
    size_t oldsize = xorblock->allocated;
    size_t i;
    char expand_byte;
    ((void) sizeof ((oldsize > 0) ? 1 : 0), __extension__ ({ if (oldsize > 0) ; else __assert_fail ("oldsize > 0", "blockprocess.c", 277, __extension__ __PRETTY_FUNCTION__); }));
    expand_byte = xorblock->data[oldsize-1];
    block_realloc_set(xorblock, xorsize, expand_byte);
    for(i=0; i < mysize; ++i)
        xorblock->data[i] ^= bp->bo->data[i];
    for(i=mysize; i < xorblock->allocated; ++i)
        xorblock->data[i] ^= 0;
}

canonical_original_code:
void xor_to_xorblock(struct block_process *bp, struct block *xorblock)
{
    unsigned long mysize = bp->bo->writer_pos;
    unsigned long xorsize = mysize + 1;
    unsigned long oldsize = xorblock->allocated;
    unsigned long i;
    char expand_byte;
    ((void) sizeof ((oldsize > 0) ? 1 : 0), __extension__ ({ if (oldsize > 0) ; else __assert_fail ("oldsize > 0", "blockprocess.c", 277, __extension__ __PRETTY_FUNCTION__); }));
    expand_byte = xorblock->data[oldsize-1];
    block_realloc_set(xorblock, xorsize, expand_byte);
    for(i=0; i < mysize; ++i)
        xorblock->data[i] ^= bp->bo->data[i];
    for(i=mysize; i < xorblock->allocated; ++i)
        xorblock->data[i] ^= 0;
}

variable_types:
xorblock
struct block *

variable_types:
mysize
unsigned long

variable_types:
xorsize
unsigned long

variable_types:
oldsize
unsigned long

variable_types:
i
unsigned long


decompiled_code:
int __fastcall dump_block_to_tar(__int64 a1, __int64 a2)
{
const char *v3; // rax
__gid_t v4; // eax
__uid_t v5; // eax
time_t v6; // rax
const char *v7; // rdx
_QWORD *v8; // rax
__int64 v9; // rsi
const char *v10; // rdx
__int64 v11; // r12
const char *v12; // rdx
_QWORD *v13; // rax
__int64 v14; // rdx
__int64 *v15; // rax
__int64 *v16; // rcx
__int64 v17; // rdx
int result; // eax
char v19[4120]; // [rsp+0h] [rbp-1018h] BYREF

if ( HIDWORD(command_line[0]) )
fprintf(stderr, "Writing block %i to the btar stream\n", *(unsigned int *)(a1 + 48));
v3 = (const char *)get_filter_extensions(filter);
snprintf(v19, 0x1000uLL, "block%i.tar%s", *(unsigned int *)(a1 + 48), v3);
mytar_new_file(a2);
mytar_set_filename(a2, v19);
v4 = getgid();
mytar_set_gid(a2, v4);
v5 = getuid();
mytar_set_uid(a2, v5);
mytar_set_size(a2, *(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL));
mytar_set_mode(a2, 33188LL);
v6 = time(0LL);
mytar_set_mtime(a2, v6);
mytar_set_filetype(a2, 0x8000LL);
if ( mytar_write_header(a2) == -1 )
error((int)"Failed to write header", 0x8000, v7);
v8 = *(_QWORD **)(a1 + 24);
v9 = *v8;
v11 = mytar_write_data(a2, *v8, v8[3]);
if ( v11 == -1 )
error((int)"Could not write mytar data", v9, v10);
if ( *(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL) != v11 )
_assert_fail("(size_t) res == bp->bo->writer_pos", "blockprocess.c", 0x147u, "dump_block_to_tar");
if ( mytar_write_end(a2) == -1 )
error((int)"Could not write mytar file end", v9, v12);
v13 = *(_QWORD **)(a1 + 24);
v14 = v13[2];
v13[3] = 0LL;
if ( v14 )
{
v15 = (__int64 *)v13[1];
v16 = &v15[v14];
do
{
v17 = *v15++;
*(_QWORD *)(v17 + 8) = 0LL;
}
while ( v16 != v15 );
}
result = HIDWORD(command_line[0]);
if ( result )
result = fprintf(stderr, "Block %i written to the btar stream\n", *(unsigned int *)(a1 + 48));
return result;
}

canonical_decompiled_code:
int __fastcall func10(__int64 a1, __int64 a2)
{
const char *v3; // rax
__gid_t v4; // eax
__uid_t v5; // eax
time_t v6; // rax
const char *v7; // rdx
_QWORD *v8; // rax
__int64 v9; // rsi
const char *v10; // rdx
__int64 v11; // r12
const char *v12; // rdx
_QWORD *v13; // rax
__int64 v14; // rdx
__int64 *v15; // rax
__int64 *v16; // rcx
__int64 v17; // rdx
int result; // eax
char v19[4120]; // [rsp+0h] [rbp-1018h] BYREF

if ( HIDWORD(command_line[0]) )
fprintf(stderr, "Writing block %i to the btar stream\n", *(unsigned int *)(a1 + 48));
v3 = (const char *)get_filter_extensions(filter);
snprintf(v19, 0x1000uLL, "block%i.tar%s", *(unsigned int *)(a1 + 48), v3);
mytar_new_file(a2);
mytar_set_filename(a2, v19);
v4 = getgid();
mytar_set_gid(a2, v4);
v5 = getuid();
mytar_set_uid(a2, v5);
mytar_set_size(a2, *(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL));
mytar_set_mode(a2, 33188LL);
v6 = time(0LL);
mytar_set_mtime(a2, v6);
mytar_set_filetype(a2, 0x8000LL);
if ( mytar_write_header(a2) == -1 )
error((int)"Failed to write header", 0x8000, v7);
v8 = *(_QWORD **)(a1 + 24);
v9 = *v8;
v11 = mytar_write_data(a2, *v8, v8[3]);
if ( v11 == -1 )
error((int)"Could not write mytar data", v9, v10);
if ( *(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL) != v11 )
_assert_fail("(size_t) res == bp->bo->writer_pos", "blockprocess.c", 0x147u, "dump_block_to_tar");
if ( mytar_write_end(a2) == -1 )
error((int)"Could not write mytar file end", v9, v12);
v13 = *(_QWORD **)(a1 + 24);
v14 = v13[2];
v13[3] = 0LL;
if ( v14 )
{
v15 = (__int64 *)v13[1];
v16 = &v15[v14];
do
{
v17 = *v15++;
*(_QWORD *)(v17 + 8) = 0LL;
}
while ( v16 != v15 );
}
result = HIDWORD(command_line[0]);
if ( result )
result = fprintf(stderr, "Block %i written to the btar stream\n", *(unsigned int *)(a1 + 48));
return result;
}

original_code:
void
dump_block_to_tar(struct block_process *bp, struct mytar *tar)
{
    ssize_t res;
    char filename[4096];
    if (command_line.debug)
        fprintf(stderr, "Writing block %i to the btar stream\n", bp->nblock);
    snprintf(filename, sizeof filename, "block%i.tar%s", bp->nblock,
            get_filter_extensions(filter));
    mytar_new_file(tar);
    mytar_set_filename(tar, filename);
    mytar_set_gid(tar, getgid());
    mytar_set_uid(tar, getuid());
    mytar_set_size(tar, bp->bo->writer_pos);
    mytar_set_mode(tar, 0644 | 0100000);
    mytar_set_mtime(tar, time(((void *)0)));
    mytar_set_filetype(tar, 0100000);
    res = mytar_write_header(tar);
    if (res == -1)
        error("Failed to write header");
    res = mytar_write_data(tar, bp->bo->data, bp->bo->writer_pos);
    if (res == -1)
        error("Could not write mytar data");
    ((void) sizeof (((size_t) res == bp->bo->writer_pos) ? 1 : 0), __extension__ ({ if ((size_t) res == bp->bo->writer_pos) ; else __assert_fail ("(size_t) res == bp->bo->writer_pos", "blockprocess.c", 327, __extension__ __PRETTY_FUNCTION__); }));
    res = mytar_write_end(tar);
    if (res == -1)
        error("Could not write mytar file end");
    bp->bo->writer_pos = 0;
    {
        size_t i;
        for(i=0; i < bp->bo->nreaders; ++i)
            bp->bo->readers[i]->pos = 0;
    }
    if (command_line.debug)
        fprintf(stderr, "Block %i written to the btar stream\n", bp->nblock);
}

canonical_original_code:
void dump_block_to_tar(struct block_process *bp, struct mytar *tar)
{
    long res;
    char filename[4096];
    if (command_line.debug)
        fprintf(stderr, "Writing block %i to the btar stream\n", bp->nblock);
    snprintf(filename, sizeof filename, "block%i.tar%s", bp->nblock,
            get_filter_extensions(filter));
    mytar_new_file(tar);
    mytar_set_filename(tar, filename);
    mytar_set_gid(tar, getgid());
    mytar_set_uid(tar, getuid());
    mytar_set_size(tar, bp->bo->writer_pos);
    mytar_set_mode(tar, 0644 | 0100000);
    mytar_set_mtime(tar, time(((void *)0)));
    mytar_set_filetype(tar, 0100000);
    res = mytar_write_header(tar);
    if (res == -1)
        error("Failed to write header");
    res = mytar_write_data(tar, bp->bo->data, bp->bo->writer_pos);
    if (res == -1)
        error("Could not write mytar data");
    ((void) sizeof (((unsigned long) res == bp->bo->writer_pos) ? 1 : 0), __extension__ ({ if ((unsigned long) res == bp->bo->writer_pos) ; else __assert_fail ("(size_t) res == bp->bo->writer_pos", "blockprocess.c", 327, __extension__ __PRETTY_FUNCTION__); }));
    res = mytar_write_end(tar);
    if (res == -1)
        error("Could not write mytar file end");
    bp->bo->writer_pos = 0;
    {
        unsigned long i;
        for(i=0; i < bp->bo->nreaders; ++i)
            bp->bo->readers[i]->pos = 0;
    }
    if (command_line.debug)
        fprintf(stderr, "Block %i written to the btar stream\n", bp->nblock);
}

variable_types: struct mytar { struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } header; char *longname; char *longlinkname; unsigned long long file_size; unsigned long long file_data_written; int fd; unsigned long long total_written; } *

variable_types: res long

variable_types:
filename
char [4096]

user_defined_types: struct mytar { struct header_gnu_tar header; char *longname; char *longlinkname; unsigned long long file_size; unsigned long long file_data_written; int fd; unsigned long long total_written; }


decompiled_code:
__int64 __fastcall block_process_new_input_reader(__int64 *a1)
{
__int64 v1; // r8

v1 = a1[3];
if ( filter )
v1 = *a1;
return block_reader_new(v1);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 *a1)
{
__int64 v1; // r8

v1 = a1[3];
if ( filter )
v1 = *a1;
return block_reader_new(v1);
}

original_code:
struct block_reader * block_process_new_input_reader(struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    return block_reader_new(b);
}

canonical_original_code:
struct block_reader *block_process_new_input_reader(struct block_process *bp)
{
    struct block *b = bp->bo;
    if (filter)
        b = bp->bi;
    return block_reader_new(b);
}

variable_types: struct block_process { struct block *bi; struct block_reader *br_to_filter; int fd_filterin; int fd_filterout; struct block *bo; unsigned long left; int closed_in; int block_finished; int nblock; int has_read; int finished_read_ack; } *

return_type: struct block_reader { struct block { char *data; struct block_reader **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *b; unsigned long pos; } *


decompiled_code:
__int64 __fastcall block_process_has_read(__int64 a1)
{
return *(unsigned int *)(a1 + 52);
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1)
{
return *(unsigned int *)(a1 + 52);
}

original_code:
int block_process_has_read(struct block_process *bp)
{
    return bp->has_read;
}


decompiled_code:
void __fastcall block_free(void *ptr)
{
void **v1; // rbx
void **v2; // rbp

if ( ptr )
{
v1 = (void **)ptr;
do
{
v2 = v1;
v1 = (void **)v1[6];
free(*v2);
free(v2);
}
while ( v1 );
}
}

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

if ( ptr )
{
v1 = (void **)ptr;
do
{
v2 = v1;
v1 = (void **)v1[6];
free(*v2);
free(v2);
}
while ( v1 );
}
}

original_code:
void
block_free(struct block *b)
{
    while(b)
    {
        struct block *next;
        next = b->nextblock;
        free(b->data);
        free(b);
        b = next;
    }
}


decompiled_code:
void __fastcall block_realloc_set(void **a1, size_t a2, char a3)
{
size_t v3; // r13
char *v5; // rax

v3 = (size_t)a1[4];
if ( v3 < a2 )
{
v5 = (char *)realloc(*a1, a2);
*a1 = v5;
if ( !v5 )
{
fatal_error("Cannot realloc");
v5 = (char *)*a1;
}
a1[4] = (void *)a2;
memset(&v5[v3], a3, a2 - v3);
a1[3] = (void *)a2;
a1[5] = (void *)a2;
}
}

canonical_decompiled_code:
void __fastcall func1(void **a1, size_t a2, char a3)
{
size_t v3; // r13
char *v5; // rax

v3 = (size_t)a1[4];
if ( v3 < a2 )
{
v5 = (char *)realloc(*a1, a2);
*a1 = v5;
if ( !v5 )
{
fatal_error("Cannot realloc");
v5 = (char *)*a1;
}
a1[4] = (void *)a2;
memset(&v5[v3], a3, a2 - v3);
a1[3] = (void *)a2;
a1[5] = (void *)a2;
}
}

original_code:
void
block_realloc_set(struct block *b, size_t len, char c)
{
    size_t lastallocated = b->allocated;
    if (len > b->allocated)
    {
        b->data = realloc(b->data, len);
        if (!b->data)
            fatal_error("Cannot realloc");
        b->allocated = len;
        memset(b->data + lastallocated, c, len - lastallocated);
        b->writer_pos = len;
        b->total_written = len;
    }
}

canonical_original_code:
void block_realloc_set(struct block *b, unsigned long len, char c)
{
    unsigned long lastallocated = b->allocated;
    if (len > b->allocated)
    {
        b->data = realloc(b->data, len);
        if (!b->data)
            fatal_error("Cannot realloc");
        b->allocated = len;
        memset(b->data + lastallocated, c, len - lastallocated);
        b->writer_pos = len;
        b->total_written = len;
    }
}

variable_types:
len
unsigned long

variable_types: c char

variable_types:
lastallocated
unsigned long


decompiled_code:
ssize_t __fastcall block_fill_from_fd(_QWORD *a1, int a2, size_t a3)
{
__int64 v6; // rsi
size_t v7; // rdx
ssize_t result; // rax

v6 = a1[3];
v7 = a1[4] - v6;
if ( v7 > a3 )
v7 = a3;
result = read(a2, (void *)(*a1 + v6), v7);
if ( result > 0 )
{
a1[3] += result;
a1[5] += result;
}
return result;
}

canonical_decompiled_code:
ssize_t __fastcall func2(_QWORD *a1, int a2, size_t a3)
{
__int64 v6; // rsi
size_t v7; // rdx
ssize_t result; // rax

v6 = a1[3];
v7 = a1[4] - v6;
if ( v7 > a3 )
v7 = a3;
result = read(a2, (void *)(*a1 + v6), v7);
if ( result > 0 )
{
a1[3] += result;
a1[5] += result;
}
return result;
}

original_code:
size_t
block_fill_from_fd(struct block *b, int fd, size_t maxbytes)
{
    size_t left = b->allocated - b->writer_pos;
    ssize_t nread;
    if (maxbytes > left)
        maxbytes = left;
    nread = read(fd, b->data + b->writer_pos, maxbytes);
    if (nread > 0)
    {
        b->writer_pos += nread;
        b->total_written += nread;
    }
    return nread;
}

canonical_original_code:
unsigned long block_fill_from_fd(struct block *b, int fd, unsigned long maxbytes)
{
    unsigned long left = b->allocated - b->writer_pos;
    long nread;
    if (maxbytes > left)
        maxbytes = left;
    nread = read(fd, b->data + b->writer_pos, maxbytes);
    if (nread > 0)
    {
        b->writer_pos += nread;
        b->total_written += nread;
    }
    return nread;
}

variable_types: struct block { char *data; struct block_reader { struct block *b; unsigned long pos; } **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *

variable_types: fd int

variable_types:
maxbytes
unsigned long

variable_types:
left
unsigned long

variable_types: nread long


decompiled_code:
size_t __fastcall block_fill_from_memory(_QWORD *a1, const void *a2, size_t a3)
{
__int64 v4; // rdi
size_t v5; // r12

v4 = a1[3];
v5 = a1[4] - v4;
if ( v5 > a3 )
v5 = a3;
memcpy((void *)(*a1 + v4), a2, v5);
a1[3] += v5;
return v5;
}

canonical_decompiled_code:
size_t __fastcall func3(_QWORD *a1, const void *a2, size_t a3)
{
__int64 v4; // rdi
size_t v5; // r12

v4 = a1[3];
v5 = a1[4] - v4;
if ( v5 > a3 )
v5 = a3;
memcpy((void *)(*a1 + v4), a2, v5);
a1[3] += v5;
return v5;
}

original_code:
size_t
block_fill_from_memory(struct block *b, const char *data, size_t len)
{
    size_t left = b->allocated - b->writer_pos;
    if (len > left)
        len = left;
    memcpy(b->data + b->writer_pos, data, len);
    b->writer_pos += len;
    return len;
}

canonical_original_code:
unsigned long block_fill_from_memory(struct block *b, char *data, unsigned long len)
{
    unsigned long left = b->allocated - b->writer_pos;
    if (len > left)
        len = left;
    memcpy(b->data + b->writer_pos, data, len);
    b->writer_pos += len;
    return len;
}

variable_types:
data
char *


original_code:
ssize_t
block_fill_from_fd_multi(struct block *b, int fd, size_t maxbytes)
{
    size_t left = b->lastblock->allocated - b->lastblock->writer_pos;
    ssize_t nread;
    if (left == 0)
    {
        b->lastblock->nextblock = block_new(b->lastblock->allocated);
        b->lastblock = b->lastblock->nextblock;
        left = b->lastblock->allocated;
    }
    if (maxbytes > left)
        maxbytes = left;
    nread = read(fd, b->lastblock->data + b->lastblock->writer_pos, maxbytes);
    if (nread > 0)
    {
        b->lastblock->writer_pos += nread;
        b->total_written += nread;
    }
    return nread;
}

canonical_original_code:
long block_fill_from_fd_multi(struct block *b, int fd, unsigned long maxbytes)
{
    unsigned long left = b->lastblock->allocated - b->lastblock->writer_pos;
    long nread;
    if (left == 0)
    {
        b->lastblock->nextblock = block_new(b->lastblock->allocated);
        b->lastblock = b->lastblock->nextblock;
        left = b->lastblock->allocated;
    }
    if (maxbytes > left)
        maxbytes = left;
    nread = read(fd, b->lastblock->data + b->lastblock->writer_pos, maxbytes);
    if (nread > 0)
    {
        b->lastblock->writer_pos += nread;
        b->total_written += nread;
    }
    return nread;
}

return_type: long


decompiled_code:
_BOOL8 __fastcall block_can_accept(__int64 a1)
{
return *(_QWORD *)(a1 + 24) < *(_QWORD *)(a1 + 32);
}

canonical_decompiled_code:
_BOOL8 __fastcall func5(__int64 a1)
{
return *(_QWORD *)(a1 + 24) < *(_QWORD *)(a1 + 32);
}

original_code:
int
block_can_accept(struct block *b)
{
    return (b->writer_pos < b->allocated);
}


decompiled_code:
void __fastcall block_reader_free(void *ptr)
{
__int64 v1; // r13
__int64 v2; // rdx
void **v3; // r12
unsigned __int64 v4; // rax
__int64 v5; // rbx
void *v6; // rax
bool v7; // zf

v1 = *(_QWORD *)ptr;
v2 = *(_QWORD *)(*(_QWORD *)ptr + 16LL);
if ( !v2 )
LABEL_11:
_assert_fail("i < b->nreaders", "block.c", 0xABu, "block_reader_free");
v3 = *(void ***)(v1 + 8);
v4 = 0LL;
while ( v3[v4] != ptr )
{
if ( ++v4 == v2 )
goto LABEL_11;
}
v5 = v2 - 1;
if ( v2 - 1 > v4 )
memmove(&v3[v4], &v3[v4 + 1], 8 * (v5 - v4));
*(_QWORD *)(v1 + 16) = v5;
v6 = realloc(v3, 8 * v5);
v7 = *(_QWORD *)(v1 + 16) == 0LL;
*(_QWORD *)(v1 + 8) = v6;
if ( !v7 && !v6 )
fatal_error("Cannot realloc");
free(ptr);
}

canonical_decompiled_code:
void __fastcall func6(void *ptr)
{
__int64 v1; // r13
__int64 v2; // rdx
void **v3; // r12
unsigned __int64 v4; // rax
__int64 v5; // rbx
void *v6; // rax
bool v7; // zf

v1 = *(_QWORD *)ptr;
v2 = *(_QWORD *)(*(_QWORD *)ptr + 16LL);
if ( !v2 )
LABEL_11:
_assert_fail("i < b->nreaders", "block.c", 0xABu, "block_reader_free");
v3 = *(void ***)(v1 + 8);
v4 = 0LL;
while ( v3[v4] != ptr )
{
if ( ++v4 == v2 )
goto LABEL_11;
}
v5 = v2 - 1;
if ( v2 - 1 > v4 )
memmove(&v3[v4], &v3[v4 + 1], 8 * (v5 - v4));
*(_QWORD *)(v1 + 16) = v5;
v6 = realloc(v3, 8 * v5);
v7 = *(_QWORD *)(v1 + 16) == 0LL;
*(_QWORD *)(v1 + 8) = v6;
if ( !v7 && !v6 )
fatal_error("Cannot realloc");
free(ptr);
}

original_code:
void
block_reader_free(struct block_reader *br)
{
    size_t i;
    struct block *b = br->b;
    for(i = 0; i < b->nreaders; ++i)
    {
        if (b->readers[i] == br)
            break;
    }
    ((void) sizeof ((i < b->nreaders) ? 1 : 0), __extension__ ({ if (i < b->nreaders) ; else __assert_fail ("i < b->nreaders", "block.c", 171, __extension__ __PRETTY_FUNCTION__); }));
    for(; i < b->nreaders-1; ++i)
    {
        b->readers[i] = b->readers[i+1];
    }
    b->nreaders--;
    b->readers = realloc(b->readers, sizeof(*b->readers)*b->nreaders);
    if (b->nreaders > 0 && !b->readers)
        fatal_error("Cannot realloc");
    free(br);
}

canonical_original_code:
void block_reader_free(struct block_reader *br)
{
    unsigned long i;
    struct block *b = br->b;
    for(i = 0; i < b->nreaders; ++i)
    {
        if (b->readers[i] == br)
            break;
    }
    ((void) sizeof ((i < b->nreaders) ? 1 : 0), __extension__ ({ if (i < b->nreaders) ; else __assert_fail ("i < b->nreaders", "block.c", 171, __extension__ __PRETTY_FUNCTION__); }));
    for(; i < b->nreaders-1; ++i)
    {
        b->readers[i] = b->readers[i+1];
    }
    b->nreaders--;
    b->readers = realloc(b->readers, sizeof(*b->readers)*b->nreaders);
    if (b->nreaders > 0 && !b->readers)
        fatal_error("Cannot realloc");
    free(br);
}

variable_types: struct block_reader { struct block { char *data; struct block_reader **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *b; unsigned long pos; } *


decompiled_code:
_BOOL8 __fastcall block_reader_can_read(_QWORD *a1)
{
return *(_QWORD *)(*a1 + 24LL) != a1[1];
}

canonical_decompiled_code:
_BOOL8 __fastcall func7(_QWORD *a1)
{
return *(_QWORD *)(*a1 + 24LL) != a1[1];
}

original_code:
int
block_reader_can_read(struct block_reader *r)
{
    size_t left = r->b->writer_pos - r->pos;
    if (left > 0)
        return 1;
    return 0;
}

canonical_original_code:
int block_reader_can_read(struct block_reader *r)
{
    unsigned long left = r->b->writer_pos - r->pos;
    if (left > 0)
        return 1;
    return 0;
}


decompiled_code:
__int64 __fastcall block_are_readers_done(_QWORD *a1)
{
__int64 v1; // rcx
__int64 v2; // rsi
__int64 v3; // rdi
__int64 v4; // rax

v1 = a1[2];
if ( !v1 )
return 1LL;
v2 = a1[3];
v3 = a1[1];
v4 = 0LL;
while ( *(_QWORD *)(*(_QWORD *)(v3 + 8 * v4) + 8LL) == v2 )
{
if ( ++v4 == v1 )
return 1LL;
}
return 0LL;
}

original_code:
int
block_are_readers_done(struct block *b)
{
    size_t i;
    int allequal = 1;
    for(i=0; i < b->nreaders; ++i)
        if (b->readers[i]->pos != b->writer_pos)
        {
            allequal = 0;
            break;
        }
    return allequal;
}

canonical_original_code:
int block_are_readers_done(struct block *b)
{
    unsigned long i;
    int allequal = 1;
    for(i=0; i < b->nreaders; ++i)
        if (b->readers[i]->pos != b->writer_pos)
        {
            allequal = 0;
            break;
        }
    return allequal;
}

variable_types: allequal int


decompiled_code:
__int64 __fastcall block_reset_pos_if_possible(__int64 a1)
{
__int64 result; // rax
_QWORD *v2; // r8
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // rdx

result = *(unsigned int *)(a1 + 64);
if ( (_DWORD)result )
{
result = block_are_readers_done((_QWORD *)a1);
if ( (_DWORD)result )
{
v3 = v2[2];
v2[3] = 0LL;
if ( v3 )
{
result = v2[1];
v4 = result + 8 * v3;
do
{
v5 = *(_QWORD *)result;
result += 8LL;
*(_QWORD *)(v5 + 8) = 0LL;
}
while ( result != v4 );
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
__int64 result; // rax
_QWORD *v2; // r8
__int64 v3; // rdx
__int64 v4; // rcx
__int64 v5; // rdx

result = *(unsigned int *)(a1 + 64);
if ( (_DWORD)result )
{
result = func8((_QWORD *)a1);
if ( (_DWORD)result )
{
v3 = v2[2];
v2[3] = 0LL;
if ( v3 )
{
result = v2[1];
v4 = result + 8 * v3;
do
{
v5 = *(_QWORD *)result;
result += 8LL;
*(_QWORD *)(v5 + 8) = 0LL;
}
while ( result != v4 );
}
}
}
return result;
}

original_code:
void
block_reset_pos_if_possible(struct block *b)
{
    size_t i;
    if (!b->go_back)
        return;
    if (block_are_readers_done(b))
    {
        b->writer_pos = 0;
        for(i=0; i < b->nreaders; ++i)
            b->readers[i]->pos = 0;
    }
}

canonical_original_code:
void block_reset_pos_if_possible(struct block *b)
{
    unsigned long i;
    if (!b->go_back)
        return;
    if (block_are_readers_done(b))
    {
        b->writer_pos = 0;
        for(i=0; i < b->nreaders; ++i)
            b->readers[i]->pos = 0;
    }
}


decompiled_code:
__int64 __fastcall block_reader_to_fd(__int64 *a1, int a2)
{
__int64 v4; // rsi
size_t v5; // rdx
ssize_t v7; // rax
unsigned int v8; // er9

v4 = a1[1];
v5 = *(_QWORD *)(*a1 + 24) - v4;
if ( !v5 )
return 0LL;
v7 = write(a2, (const void *)(*(_QWORD *)*a1 + v4), v5);
v8 = v7;
if ( v7 > 0 )
{
a1[1] += v7;
block_reset_pos_if_possible(*a1);
}
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 *a1, int a2)
{
__int64 v4; // rsi
size_t v5; // rdx
ssize_t v7; // rax
unsigned int v8; // er9

v4 = a1[1];
v5 = *(_QWORD *)(*a1 + 24) - v4;
if ( !v5 )
return 0LL;
v7 = write(a2, (const void *)(*(_QWORD *)*a1 + v4), v5);
v8 = v7;
if ( v7 > 0 )
{
a1[1] += v7;
func9(*a1);
}
return v8;
}

original_code:
int
block_reader_to_fd(struct block_reader *r, int fd)
{
    size_t left = r->b->writer_pos - r->pos;
    ssize_t nwritten;
    if (left == 0)
        return 0;
    nwritten = write(fd, r->b->data + r->pos, left);
    if (nwritten > 0)
    {
        r->pos += nwritten;
        block_reset_pos_if_possible(r->b);
    }
    return nwritten;
}

canonical_original_code:
int block_reader_to_fd(struct block_reader *r, int fd)
{
    unsigned long left = r->b->writer_pos - r->pos;
    long nwritten;
    if (left == 0)
        return 0;
    nwritten = write(fd, r->b->data + r->pos, left);
    if (nwritten > 0)
    {
        r->pos += nwritten;
        block_reset_pos_if_possible(r->b);
    }
    return nwritten;
}

variable_types: nwritten long


decompiled_code:
void list_new_data_cb()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
static void
list_new_data_cb(const char *data, size_t len, void *userdata)
{
    data = data;
    len = len;
    userdata = userdata;
}

canonical_original_code:
static void list_new_data_cb(char *data, unsigned long len, void *userdata)
{
    data = data;
    len = len;
    userdata = userdata;
}

variable_types:
userdata
void *


decompiled_code:
void __fastcall list_tar(int fd)
{
int v1; // eax
void *v2; // r12
ssize_t v3; // rax
ssize_t v4; // rbx
__int64 v5; // rax
int *v6; // r13
__int64 v7[4]; // [rsp+0h] [rbp-2A8h] BYREF
char v8[648]; // [rsp+20h] [rbp-288h] BYREF

v1 = command_line[26];
v7[0] = (__int64)list_new_file_cb;
v7[1] = (__int64)list_new_data_cb;
v7[2] = 0LL;
if ( v1 == 5 )
{
init_readtar(v8, v7);
read_full_tar((unsigned int)fd, v8);
return;
}
if ( v1 == 4 )
{
v2 = malloc(0x100000uLL);
if ( !v2 )
fatal_error("Cannot allocate");
while ( 1 )
{
while ( 1 )
{
v3 = read(fd, v2, 0x100000uLL);
v4 = v3;
if ( v3 == -1 )
break;
if ( !v3 )
{
free(v2);
return;
}
v5 = write_all(1LL, v2, v3);
if ( v5 != -1 )
goto LABEL_10;
if ( *_errno_location() == 4 )
goto LABEL_17;
LABEL_15:
fatal_errno("Cannot write to stdout");
v5 = -1LL;
LABEL_10:
if ( v4 != v5 )
goto LABEL_17;
}
v6 = _errno_location();
if ( *v6 != 4 )
{
fatal_errno("Cannot read");
if ( write_all(1LL, v2, -1LL) == -1 )
{
if ( *v6 != 4 )
goto LABEL_15;
}
else
{
LABEL_17:
fatal_error("Cannot write to stdout as much as wanted");
}
}
}
}
}

canonical_decompiled_code:
void __fastcall func1(int fd)
{
int v1; // eax
void *v2; // r12
ssize_t v3; // rax
ssize_t v4; // rbx
__int64 v5; // rax
int *v6; // r13
__int64 v7[4]; // [rsp+0h] [rbp-2A8h] BYREF
char v8[648]; // [rsp+20h] [rbp-288h] BYREF

v1 = command_line[26];
v7[0] = (__int64)list_new_file_cb;
v7[1] = (__int64)list_new_data_cb;
v7[2] = 0LL;
if ( v1 == 5 )
{
init_readtar(v8, v7);
read_full_tar((unsigned int)fd, v8);
return;
}
if ( v1 == 4 )
{
v2 = malloc(0x100000uLL);
if ( !v2 )
fatal_error("Cannot allocate");
while ( 1 )
{
while ( 1 )
{
v3 = read(fd, v2, 0x100000uLL);
v4 = v3;
if ( v3 == -1 )
break;
if ( !v3 )
{
free(v2);
return;
}
v5 = write_all(1LL, v2, v3);
if ( v5 != -1 )
goto LABEL_10;
if ( *_errno_location() == 4 )
goto LABEL_17;
LABEL_15:
fatal_errno("Cannot write to stdout");
v5 = -1LL;
LABEL_10:
if ( v4 != v5 )
goto LABEL_17;
}
v6 = _errno_location();
if ( *v6 != 4 )
{
fatal_errno("Cannot read");
if ( write_all(1LL, v2, -1LL) == -1 )
{
if ( *v6 != 4 )
goto LABEL_15;
}
else
{
LABEL_17:
fatal_error("Cannot write to stdout as much as wanted");
}
}
}
}
}

original_code:
static void
list_tar(int fd)
{
    struct readtar rt;
    struct readtar_callbacks cb = { list_new_file_cb, list_new_data_cb, 0};
    if (command_line.action == LIST_INDEX)
    {
        init_readtar(&rt, &cb);
        read_full_tar(fd, &rt);
    }
    else if (command_line.action == EXTRACT_INDEX)
    {
        char *buffer = malloc(buffersize);
        if (!buffer)
            fatal_error("Cannot allocate");
        while (1)
        {
            ssize_t res;
            ssize_t nread = read(fd, buffer, buffersize);
            if (nread == -1)
            {
               if ((*__errno_location ()) == 4)
                   continue;
               fatal_errno("Cannot read");
            }
            if (nread == 0)
                break;
            res = write_all(1, buffer, nread);
            if (res == -1 && (*__errno_location ()) != 4)
                fatal_errno("Cannot write to stdout");
            if (res != nread)
                fatal_error("Cannot write to stdout as much as wanted");
        }
        free(buffer);
    }
}

canonical_original_code:
static void list_tar(int fd)
{
    struct readtar rt;
    struct readtar_callbacks cb = { list_new_file_cb, list_new_data_cb, 0};
    if (command_line.action == LIST_INDEX)
    {
        init_readtar(&rt, &cb);
        read_full_tar(fd, &rt);
    }
    else if (command_line.action == EXTRACT_INDEX)
    {
        char *buffer = malloc(buffersize);
        if (!buffer)
            fatal_error("Cannot allocate");
        while (1)
        {
            long res;
            long nread = read(fd, buffer, buffersize);
            if (nread == -1)
            {
               if ((*__errno_location ()) == 4)
                   continue;
               fatal_errno("Cannot read");
            }
            if (nread == 0)
                break;
            res = write_all(1, buffer, nread);
            if (res == -1 && (*__errno_location ()) != 4)
                fatal_errno("Cannot write to stdout");
            if (res != nread)
                fatal_error("Cannot write to stdout as much as wanted");
        }
        free(buffer);
    }
}

variable_types: struct readtar { enum { IN_HEADER=0, IN_DATA=1, IN_EXTRA_DATA=2, IN_LONG_FILENAME=3, IN_LONG_LINKNAME=4 } state; char *longfilename; char *longlinkname; struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } header; unsigned long long filedata_left; unsigned long long until_header_left; unsigned long long data_read; unsigned long long total_data_read; struct readtar_callbacks { enum readtar_newfile_result { READTAR_NORMAL=0, READTAR_SKIPDATA=1 } (*new_file)(struct readtar_file { struct header_gnu_tar *header; char *name; char *linkname; unsigned long long size; } *file, void *userdata); void (*new_data)(char *data, unsigned long len, void *userdata); void *userdata; } cb; int good_header; int fd; }

variable_types: struct readtar_callbacks { enum readtar_newfile_result { READTAR_NORMAL=0, READTAR_SKIPDATA=1 } (*new_file)(struct readtar_file { struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } *header; char *name; char *linkname; unsigned long long size; } *file, void *userdata); void (*new_data)(char *data, unsigned long len, void *userdata); void *userdata; }

variable_types:
buffer
char *

user_defined_types: struct readtar { enum { IN_HEADER=0, IN_DATA=1, IN_EXTRA_DATA=2, IN_LONG_FILENAME=3, IN_LONG_LINKNAME=4 } state; char *longfilename; char *longlinkname; struct header_gnu_tar header; unsigned long long filedata_left; unsigned long long until_header_left; unsigned long long data_read; unsigned long long total_data_read; struct readtar_callbacks cb; int good_header; int fd; }

user_defined_types: struct readtar_callbacks { enum readtar_newfile_result (*new_file)(struct readtar_file *file, void *userdata); void (*new_data)(char *data, unsigned long len, void *userdata); void *userdata; }


decompiled_code:
__int64 __fastcall list_new_file_cb(__int64 a1)
{
puts(*(const char **)(a1 + 8));
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
puts(*(const char **)(a1 + 8));
return 1LL;
}

original_code:
static enum readtar_newfile_result
list_new_file_cb(const struct readtar_file *file, void *userdata)
{
    userdata = userdata;
    printf("%s\n", file->name);
    return READTAR_SKIPDATA;
}

canonical_original_code:
static enum readtar_newfile_result list_new_file_cb(struct readtar_file *file, void *userdata)
{
    userdata = userdata;
    printf("%s\n", file->name);
    return READTAR_SKIPDATA;
}

variable_types: struct readtar_file { struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } *header; char *name; char *linkname; unsigned long long size; } *

return_type: enum readtar_newfile_result { READTAR_NORMAL=0, READTAR_SKIPDATA=1 }

user_defined_types: struct readtar_file { struct header_gnu_tar *header; char *name; char *linkname; unsigned long long size; }


listindex

decompiled_code:
void __fastcall listindex(__int64 fd)
{
char *v1; // rbp
char *v2; // r13
size_t i; // rdx
ssize_t v4; // rax
const char *v5; // rdx
int v6; // er15
int v7; // ebp
size_t v8; // r12
__int64 v9; // rbx
ssize_t v10; // rax
const char *v11; // rdx
ssize_t v12; // rax
void *ptr; // [rsp+8h] [rbp-60h]
int fda; // [rsp+1Ch] [rbp-4Ch] BYREF
int v15; // [rsp+20h] [rbp-48h] BYREF
int v16; // [rsp+24h] [rbp-44h] BYREF
size_t v17[8]; // [rsp+28h] [rbp-40h] BYREF

v1 = (char *)index_find_in_tar(fd, v17);
if ( !v1 )
fatal_error_no_core("Cannot find index in btar");
if ( command_line[1] )
fprintf(stderr, "Index file name in main btar: %s\n", v1);
ptr = (void *)defilter;
if ( !defilter )
ptr = (void *)defilters_from_extensions(v1);
free(v1);
run_filters(ptr, &fda, &v15);
run_index_reader(v15, &v16, fda);
v2 = (char *)malloc(0x100000uLL);
if ( !v2 )
fatal_error("Cannot allocate");
for ( i = v17[0]; v17[0]; v17[0] -= v9 )
{
if ( i > 0x100000 )
i = 0x100000LL;
v4 = read(fd, v2, i);
if ( v4 == -1 )
{
v9 = 0LL;
error((int)"Cannot read index file from the btar", (int)v2, v5);
}
else
{
v6 = v4;
if ( (int)v4 <= 0 )
{
v9 = 0LL;
}
else
{
v7 = 0;
v8 = (int)v4;
v9 = 0LL;
while ( 1 )
{
while ( 1 )
{
v10 = write(fda, &v2[v9], v8);
if ( v10 != -1 )
break;
if ( *_errno_location() != 4 )
error((int)"Cannot write", (_DWORD)v2 + v9, v11);
}
v7 += v10;
v6 -= v10;
v9 = v7;
if ( v6 <= 0 )
break;
v8 = v6;
}
}
}
i = v17[0] - v9;
}
close(fda);
if ( (void *)defilter != ptr )
free(ptr);
while ( 1 )
{
v12 = read(v16, v2, 1uLL);
if ( v12 != -1 )
break;
if ( *_errno_location() != 4 )
{
fatal_errno("Failed to read from the wait_fd");
goto LABEL_27;
}
}
if ( v12 )
LABEL_27:
_assert_fail("res == 0", "listindex.c", 0xCEu, "listindex");
free(v2);
}

canonical_decompiled_code:
void __fastcall func4(__int64 fd)
{
char *v1; // rbp
char *v2; // r13
size_t i; // rdx
ssize_t v4; // rax
const char *v5; // rdx
int v6; // er15
int v7; // ebp
size_t v8; // r12
__int64 v9; // rbx
ssize_t v10; // rax
const char *v11; // rdx
ssize_t v12; // rax
void *ptr; // [rsp+8h] [rbp-60h]
int fda; // [rsp+1Ch] [rbp-4Ch] BYREF
int v15; // [rsp+20h] [rbp-48h] BYREF
int v16; // [rsp+24h] [rbp-44h] BYREF
size_t v17[8]; // [rsp+28h] [rbp-40h] BYREF

v1 = (char *)index_find_in_tar(fd, v17);
if ( !v1 )
fatal_error_no_core("Cannot find index in btar");
if ( command_line[1] )
fprintf(stderr, "Index file name in main btar: %s\n", v1);
ptr = (void *)defilter;
if ( !defilter )
ptr = (void *)defilters_from_extensions(v1);
free(v1);
run_filters(ptr, &fda, &v15);
func2(v15, &v16, fda);
v2 = (char *)malloc(0x100000uLL);
if ( !v2 )
fatal_error("Cannot allocate");
for ( i = v17[0]; v17[0]; v17[0] -= v9 )
{
if ( i > 0x100000 )
i = 0x100000LL;
v4 = read(fd, v2, i);
if ( v4 == -1 )
{
v9 = 0LL;
error((int)"Cannot read index file from the btar", (int)v2, v5);
}
else
{
v6 = v4;
if ( (int)v4 <= 0 )
{
v9 = 0LL;
}
else
{
v7 = 0;
v8 = (int)v4;
v9 = 0LL;
while ( 1 )
{
while ( 1 )
{
v10 = write(fda, &v2[v9], v8);
if ( v10 != -1 )
break;
if ( *_errno_location() != 4 )
error((int)"Cannot write", (_DWORD)v2 + v9, v11);
}
v7 += v10;
v6 -= v10;
v9 = v7;
if ( v6 <= 0 )
break;
v8 = v6;
}
}
}
i = v17[0] - v9;
}
close(fda);
if ( (void *)defilter != ptr )
free(ptr);
while ( 1 )
{
v12 = read(v16, v2, 1uLL);
if ( v12 != -1 )
break;
if ( *_errno_location() != 4 )
{
fatal_errno("Failed to read from the wait_fd");
goto LABEL_27;
}
}
if ( v12 )
LABEL_27:
_assert_fail("res == 0", "listindex.c", 0xCEu, "listindex");
free(v2);
}

original_code:
void listindex(int fd)
{
    char *name;
    int filterin, filterout;
    unsigned long long indexsize;
    struct filter *mydefilter;
    char *buffer;
    int wait_fd;
    name = index_find_in_tar(fd, &indexsize);
    if (!name)
    {
        fatal_error_no_core("Cannot find index in btar");
    }
    if (command_line.debug)
        fprintf(stderr, "Index file name in main btar: %s\n", name);
    if (defilter)
        mydefilter = defilter;
    else
        mydefilter = defilters_from_extensions(name);
    free(name);
    run_filters(mydefilter, &filterin, &filterout);
    run_index_reader(filterout, &wait_fd, filterin);
    buffer = malloc(buffersize);
    if (!buffer)
        fatal_error("Cannot allocate");
    while(indexsize > 0)
    {
        ssize_t res;
        unsigned long long toread = indexsize;
        int towrite;
        int written;
        if (toread > buffersize)
            toread = buffersize;
        res = read(fd, buffer, toread);
        if (res == -1)
            error("Cannot read index file from the btar");
        written = 0;
        towrite = res;
        while(towrite > 0)
        {
            res = write(filterin, buffer + written, towrite);
            if (res == -1)
            {
                if ((*__errno_location ()) != 4)
                    error("Cannot write");
                continue;
            }
            towrite -= res;
            written += res;
        }
        indexsize -= written;
    }
    close(filterin);
    if (mydefilter != defilter)
        free(mydefilter);
    do
    {
        ssize_t res;
        res = read(wait_fd, buffer, 1);
        if (res == -1)
        {
            if((*__errno_location ()) == 4)
                continue;
            fatal_errno("Failed to read from the wait_fd");
        }
        ((void) sizeof ((res == 0) ? 1 : 0), __extension__ ({ if (res == 0) ; else __assert_fail ("res == 0", "listindex.c", 206, __extension__ __PRETTY_FUNCTION__); }));
        if (res == 0)
            break;
    } while(1);
    free(buffer);
}

canonical_original_code:
void listindex(int fd)
{
    char *name;
    int filterin; int filterout;
    unsigned long long indexsize;
    struct filter *mydefilter;
    char *buffer;
    int wait_fd;
    name = index_find_in_tar(fd, &indexsize);
    if (!name)
    {
        fatal_error_no_core("Cannot find index in btar");
    }
    if (command_line.debug)
        fprintf(stderr, "Index file name in main btar: %s\n", name);
    if (defilter)
        mydefilter = defilter;
    else
        mydefilter = defilters_from_extensions(name);
    free(name);
    run_filters(mydefilter, &filterin, &filterout);
    run_index_reader(filterout, &wait_fd, filterin);
    buffer = malloc(buffersize);
    if (!buffer)
        fatal_error("Cannot allocate");
    while(indexsize > 0)
    {
        long res;
        unsigned long long toread = indexsize;
        int towrite;
        int written;
        if (toread > buffersize)
            toread = buffersize;
        res = read(fd, buffer, toread);
        if (res == -1)
            error("Cannot read index file from the btar");
        written = 0;
        towrite = res;
        while(towrite > 0)
        {
            res = write(filterin, buffer + written, towrite);
            if (res == -1)
            {
                if ((*__errno_location ()) != 4)
                    error("Cannot write");
                continue;
            }
            towrite -= res;
            written += res;
        }
        indexsize -= written;
    }
    close(filterin);
    if (mydefilter != defilter)
        free(mydefilter);
    do
    {
        long res;
        res = read(wait_fd, buffer, 1);
        if (res == -1)
        {
            if((*__errno_location ()) == 4)
                continue;
            fatal_errno("Failed to read from the wait_fd");
        }
        ((void) sizeof ((res == 0) ? 1 : 0), __extension__ ({ if (res == 0) ; else __assert_fail ("res == 0", "listindex.c", 206, __extension__ __PRETTY_FUNCTION__); }));
        if (res == 0)
            break;
    } while(1);
    free(buffer);
}

variable_types:
name
char *

variable_types: filterin int

variable_types: filterout int

variable_types:
indexsize
unsigned long long

variable_types: struct filter { char **args; struct filter *next; char extensions[4096]; } *

variable_types: res long

variable_types:
toread
unsigned long long

variable_types: towrite int

variable_types: written int


decompiled_code:
int __fastcall run_index_reader(int fd, _DWORD *a2, int a3)
{
const char *v4; // rdx
__pid_t v5; // eax
const char *v6; // rdx
int pipedes[2]; // [rsp+8h] [rbp-20h] BYREF

if ( pipe(pipedes) == -1 )
error((int)"Cannot pipe", (int)a2, v4);
v5 = fork();
if ( v5 == -1 )
{
error((int)"Cannot fork", (int)a2, v6);
}
else if ( !v5 )
{
close(0);
close(pipedes[0]);
close(a3);
list_tar(fd);
exit(0);
}
close(pipedes[1]);
*a2 = pipedes[0];
return close(fd);
}

canonical_decompiled_code:
int __fastcall func2(int fd, _DWORD *a2, int a3)
{
const char *v4; // rdx
__pid_t v5; // eax
const char *v6; // rdx
int pipedes[2]; // [rsp+8h] [rbp-20h] BYREF

if ( pipe(pipedes) == -1 )
error((int)"Cannot pipe", (int)a2, v4);
v5 = fork();
if ( v5 == -1 )
{
error((int)"Cannot fork", (int)a2, v6);
}
else if ( !v5 )
{
close(0);
close(pipedes[0]);
close(a3);
func1(fd);
exit(0);
}
close(pipedes[1]);
*a2 = pipedes[0];
return close(fd);
}

original_code:
static void
run_index_reader(int fdin, int *fdout, int closechild1)
{
    int pid;
    int res;
    int mypipe[2];
    res = pipe(mypipe);
    if (res == -1)
        error("Cannot pipe");
    pid = fork();
    if (pid == -1)
        error("Cannot fork");
    if (pid == 0)
    {
        close(0);
        close(mypipe[0]);
        close(closechild1);
        list_tar(fdin);
        exit(0);
    }
    else
    {
        close(mypipe[1]);
        *fdout = mypipe[0];
        close(fdin);
    }
}

variable_types: fdin int

variable_types:
fdout
int *

variable_types: pid int

variable_types: res int

variable_types:
mypipe
int [2]


decompiled_code:
void __noreturn end_no_core()
{
exit(1);
}

canonical_decompiled_code:
void __noreturn func0()
{
exit(1);
}

original_code:
static void
end_no_core()
{
    exit(1);
}

canonical_original_code:
static void end_no_core()
{
    exit(1);
}


error

decompiled_code:
void __fastcall __noreturn error(const char *a1)
{
perror(a1);
end();
}

canonical_decompiled_code:
void __fastcall __noreturn func1(const char *a1)
{
perror(a1);
func5();
}

original_code:
void
error(const char *str)
{
    perror(str);
    end();
}

canonical_original_code:
void error(char *str)
{
    perror(str);
    end();
}

variable_types:
str
char *


decompiled_code:
void __noreturn fatal_error(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, format);
vfprintf(stderr, format, arg);
fputc(10, stderr);
end();
}

canonical_decompiled_code:
void __noreturn func2(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, format);
vfprintf(stderr, format, arg);
fputc(10, stderr);
func5();
}

original_code:
void
fatal_error(const char *str, ...)
{
    va_list ap;
    __builtin_va_start(ap,str);
    vfprintf(stderr, str, ap);
    fputc('\n', stderr);
    end();
    __builtin_va_end(ap);
}

canonical_original_code:
void fatal_error(char *str, ...)
{
    __builtin_va_list ap;
    __builtin_va_start(ap,str);
    vfprintf(stderr, str, ap);
    fputc('\n', stderr);
    end();
    __builtin_va_end(ap);
}


decompiled_code:
void __noreturn fatal_error_no_core(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, format);
vfprintf(stderr, format, arg);
fputc(10, stderr);
end_no_core();
}

canonical_decompiled_code:
void __noreturn func3(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-D0h] BYREF

va_start(arg, format);
vfprintf(stderr, format, arg);
fputc(10, stderr);
func0();
}

original_code:
void
fatal_error_no_core(const char *str, ...)
{
    va_list ap;
    __builtin_va_start(ap,str);
    vfprintf(stderr, str, ap);
    fputc('\n', stderr);
    end_no_core();
    __builtin_va_end(ap);
}

canonical_original_code:
void fatal_error_no_core(char *str, ...)
{
    __builtin_va_list ap;
    __builtin_va_start(ap,str);
    vfprintf(stderr, str, ap);
    fputc('\n', stderr);
    end_no_core();
    __builtin_va_end(ap);
}


decompiled_code:
void __noreturn fatal_errno(char *format, ...)
{
int v1; // er12
char *v2; // rax
gcc_va_list arg; // [rsp+8h] [rbp-E0h] BYREF

va_start(arg, format);
v1 = *_errno_location();
vfprintf(stderr, format, arg);
v2 = strerror(v1);
fprintf(stderr, ": %s\n", v2);
end();
}

canonical_decompiled_code:
void __noreturn func4(char *format, ...)
{
int v1; // er12
char *v2; // rax
gcc_va_list arg; // [rsp+8h] [rbp-E0h] BYREF

va_start(arg, format);
v1 = *_errno_location();
vfprintf(stderr, format, arg);
v2 = strerror(v1);
fprintf(stderr, ": %s\n", v2);
func5();
}

original_code:
void
fatal_errno(const char *str, ...)
{
    va_list ap;
    int e;
    __builtin_va_start(ap,str);
    e = (*__errno_location ());
    vfprintf(stderr, str, ap);
    fprintf(stderr, ": %s\n", strerror(e));
    end();
    __builtin_va_end(ap);
}

canonical_original_code:
void fatal_errno(char *str, ...)
{
    __builtin_va_list ap;
    int e;
    __builtin_va_start(ap,str);
    e = (*__errno_location ());
    vfprintf(stderr, str, ap);
    fprintf(stderr, ": %s\n", strerror(e));
    end();
    __builtin_va_end(ap);
}

variable_types: e int


end

decompiled_code:
void __noreturn end()
{
abort();
}

canonical_decompiled_code:
void __noreturn func5()
{
abort();
}

original_code:
static void
end()
{
    abort();
}

canonical_original_code:
static void end()
{
    abort();
}


decompiled_code:
__int64 __fastcall file_memory_finished(__int64 a1)
{
return *(_DWORD *)(a1 + 8) >> 31;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return *(_DWORD *)(a1 + 8) >> 31;
}

original_code:
int
file_memory_finished(struct file_memory *im)
{
    if (im->fd >= 0)
        return 0;
    return 1;
}

variable_types: struct file_memory { struct block { char *data; struct block_reader { struct block *b; unsigned long pos; } **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *bo; int fd; } *

user_defined_types: struct file_memory { struct block *bo; int fd; }


decompiled_code:
__int64 __fastcall file_memory_prepare_readfds(__int64 a1, __int64 a2)
{
__int64 result; // rax

if ( *(int *)(a1 + 8) >= 0 )
result = addfd(a2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
__int64 result; // rax

if ( *(int *)(a1 + 8) >= 0 )
result = addfd(a2);
return result;
}

original_code:
void
file_memory_prepare_readfds(struct file_memory *im, fd_set *fdset, int *nfds)
{
    if (im->fd >= 0)
        addfd(fdset, im->fd, nfds);
}

canonical_original_code:
void file_memory_prepare_readfds(struct file_memory *im, struct fd_set *fdset, int *nfds)
{
    if (im->fd >= 0)
        addfd(fdset, im->fd, nfds);
}

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

variable_types:
nfds
int *


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

v2 = a1[2];
if ( v2 >= 0 && (*(_QWORD *)(a2 + 8LL * (v2 >> 6)) & (1LL << v2)) != 0 )
{
v3 = block_fill_from_fd_multi(*(_QWORD *)a1, (unsigned int)v2, *(_QWORD *)(*(_QWORD *)a1 + 32LL));
if ( v3 == -1 )
{
fatal_errno("Failed read from filememory filter, fd %i", (unsigned int)a1[2]);
}
else if ( !v3 )
{
close(a1[2]);
a1[2] = -1;
}
}
}

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

v2 = a1[2];
if ( v2 >= 0 && (*(_QWORD *)(a2 + 8LL * (v2 >> 6)) & (1LL << v2)) != 0 )
{
v3 = block_fill_from_fd_multi(*(_QWORD *)a1, (unsigned int)v2, *(_QWORD *)(*(_QWORD *)a1 + 32LL));
if ( v3 == -1 )
{
fatal_errno("Failed read from filememory filter, fd %i", (unsigned int)a1[2]);
}
else if ( !v3 )
{
close(a1[2]);
a1[2] = -1;
}
}
}

original_code:
void
file_memory_check_readfds(struct file_memory *im, fd_set *fdset)
{
    if (im->fd >= 0 && ((((fdset)->__fds_bits)[((im->fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((im->fd) % (8 * (int) sizeof (__fd_mask)))))) != 0))
    {
        int nread = block_fill_from_fd_multi(im->bo, im->fd,
                im->bo->allocated);
        if (nread == -1)
            fatal_errno("Failed read from filememory filter, fd %i", im->fd);
        else if (nread == 0)
        {
            close(im->fd);
            im->fd = -1;
        }
    }
}

canonical_original_code:
void file_memory_check_readfds(struct file_memory *im, struct fd_set *fdset)
{
    if (im->fd >= 0 && ((((fdset)->__fds_bits)[((im->fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((im->fd) % (8 * (int) sizeof (__fd_mask)))))) != 0))
    {
        int nread = block_fill_from_fd_multi(im->bo, im->fd,
                im->bo->allocated);
        if (nread == -1)
            fatal_errno("Failed read from filememory filter, fd %i", im->fd);
        else if (nread == 0)
        {
            close(im->fd);
            im->fd = -1;
        }
    }
}

variable_types: nread int


decompiled_code:
int __fastcall file_memory_to_tar(__int64 a1, const char *a2, __int64 a3, __int64 a4)
{
__gid_t v7; // eax
__uid_t v8; // eax
time_t v9; // rax
const char *v10; // rdx
_QWORD *v11; // rbp
__int64 v12; // rsi
const char *v13; // rdx
int v14; // ebx
const char *v15; // rdx
int result; // eax
char v17[4136]; // [rsp+0h] [rbp-1028h] BYREF

if ( command_line[1] )
fprintf(stderr, "Writing the %s to the btar stream\n", a2);
snprintf(v17, 0x1000uLL, a2, a3);
mytar_new_file(a4);
mytar_set_filename(a4, v17);
v7 = getgid();
mytar_set_gid(a4, v7);
v8 = getuid();
mytar_set_uid(a4, v8);
mytar_set_size(a4, *(_QWORD *)(*(_QWORD *)a1 + 40LL));
mytar_set_mode(a4, 33188LL);
v9 = time(0LL);
mytar_set_mtime(a4, v9);
mytar_set_filetype(a4, 0x8000LL);
if ( (unsigned int)mytar_write_header(a4) == -1 )
error((int)"Failed to write header", 0x8000, v10);
v11 = *(_QWORD **)a1;
do
{
v12 = *v11;
v14 = mytar_write_data(a4, *v11, v11[3]);
if ( v14 == -1 )
error((int)"Could not write index mytar data", v12, v13);
if ( v14 != v11[3] )
_assert_fail("(size_t) res == indexb->writer_pos", "filememory.c", 0x79u, "file_memory_to_tar");
v11 = (_QWORD *)v11[6];
}
while ( v11 );
if ( (unsigned int)mytar_write_end(a4) == -1 )
error((int)"Could not write mytar file end", v12, v15);
result = command_line[1];
if ( result )
result = fprintf(stderr, "File Memory %s written\n", a2);
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, const char *a2, __int64 a3, __int64 a4)
{
__gid_t v7; // eax
__uid_t v8; // eax
time_t v9; // rax
const char *v10; // rdx
_QWORD *v11; // rbp
__int64 v12; // rsi
const char *v13; // rdx
int v14; // ebx
const char *v15; // rdx
int result; // eax
char v17[4136]; // [rsp+0h] [rbp-1028h] BYREF

if ( command_line[1] )
fprintf(stderr, "Writing the %s to the btar stream\n", a2);
snprintf(v17, 0x1000uLL, a2, a3);
mytar_new_file(a4);
mytar_set_filename(a4, v17);
v7 = getgid();
mytar_set_gid(a4, v7);
v8 = getuid();
mytar_set_uid(a4, v8);
mytar_set_size(a4, *(_QWORD *)(*(_QWORD *)a1 + 40LL));
mytar_set_mode(a4, 33188LL);
v9 = time(0LL);
mytar_set_mtime(a4, v9);
mytar_set_filetype(a4, 0x8000LL);
if ( (unsigned int)mytar_write_header(a4) == -1 )
error((int)"Failed to write header", 0x8000, v10);
v11 = *(_QWORD **)a1;
do
{
v12 = *v11;
v14 = mytar_write_data(a4, *v11, v11[3]);
if ( v14 == -1 )
error((int)"Could not write index mytar data", v12, v13);
if ( v14 != v11[3] )
_assert_fail("(size_t) res == indexb->writer_pos", "filememory.c", 0x79u, "file_memory_to_tar");
v11 = (_QWORD *)v11[6];
}
while ( v11 );
if ( (unsigned int)mytar_write_end(a4) == -1 )
error((int)"Could not write mytar file end", v12, v15);
result = command_line[1];
if ( result )
result = fprintf(stderr, "File Memory %s written\n", a2);
return result;
}

original_code:
void
file_memory_to_tar(struct file_memory *im, const char *namepattern,
        const char *filter_extensions, struct mytar *tar)
{
    int res;
    char filename[4096];
    struct block *indexb;
    if (command_line.debug)
        fprintf(stderr, "Writing the %s to the btar stream\n", namepattern);
    snprintf(filename, sizeof filename, namepattern, filter_extensions);
    mytar_new_file(tar);
    mytar_set_filename(tar, filename);
    mytar_set_gid(tar, getgid());
    mytar_set_uid(tar, getuid());
    mytar_set_size(tar, im->bo->total_written);
    mytar_set_mode(tar, 0644 | 0100000);
    mytar_set_mtime(tar, time(((void *)0)));
    mytar_set_filetype(tar, 0100000);
    res = mytar_write_header(tar);
    if (res == -1)
        error("Failed to write header");
    indexb = im->bo;
    do
    {
        int res;
        res = mytar_write_data(tar, indexb->data, indexb->writer_pos);
        if (res == -1)
            error("Could not write index mytar data");
        ((void) sizeof (((size_t) res == indexb->writer_pos) ? 1 : 0), __extension__ ({ if ((size_t) res == indexb->writer_pos) ; else __assert_fail ("(size_t) res == indexb->writer_pos", "filememory.c", 121, __extension__ __PRETTY_FUNCTION__); }));
    } while((indexb = indexb->nextblock) != 0);
    res = mytar_write_end(tar);
    if (res == -1)
        error("Could not write mytar file end");
    if (command_line.debug)
        fprintf(stderr, "File Memory %s written\n", namepattern);
}

canonical_original_code:
void file_memory_to_tar(struct file_memory *im, char *namepattern, char *filter_extensions, struct mytar *tar)
{
    int res;
    char filename[4096];
    struct block *indexb;
    if (command_line.debug)
        fprintf(stderr, "Writing the %s to the btar stream\n", namepattern);
    snprintf(filename, sizeof filename, namepattern, filter_extensions);
    mytar_new_file(tar);
    mytar_set_filename(tar, filename);
    mytar_set_gid(tar, getgid());
    mytar_set_uid(tar, getuid());
    mytar_set_size(tar, im->bo->total_written);
    mytar_set_mode(tar, 0644 | 0100000);
    mytar_set_mtime(tar, time(((void *)0)));
    mytar_set_filetype(tar, 0100000);
    res = mytar_write_header(tar);
    if (res == -1)
        error("Failed to write header");
    indexb = im->bo;
    do
    {
        int res;
        res = mytar_write_data(tar, indexb->data, indexb->writer_pos);
        if (res == -1)
            error("Could not write index mytar data");
        ((void) sizeof (((unsigned long) res == indexb->writer_pos) ? 1 : 0), __extension__ ({ if ((unsigned long) res == indexb->writer_pos) ; else __assert_fail ("(size_t) res == indexb->writer_pos", "filememory.c", 121, __extension__ __PRETTY_FUNCTION__); }));
    } while((indexb = indexb->nextblock) != 0);
    res = mytar_write_end(tar);
    if (res == -1)
        error("Could not write mytar file end");
    if (command_line.debug)
        fprintf(stderr, "File Memory %s written\n", namepattern);
}

variable_types:
namepattern
char *

variable_types: struct mytar { struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } header; char *longname; char *longlinkname; unsigned long long file_size; unsigned long long file_data_written; int fd; unsigned long long total_written; } *

variable_types:
filename
char [4096]

variable_types: struct block { char *data; struct block_reader { struct block *b; unsigned long pos; } **readers; unsigned long nreaders; unsigned long writer_pos; unsigned long allocated; unsigned long total_written; struct block *nextblock; struct block *lastblock; int go_back; } *


original_code:
static int
process_part(struct readtar *readtar, const char *data, size_t len)
{
    size_t maxlen;
    size_t amount_read = 0;
    switch(readtar->state)
    {
        case IN_HEADER:
            maxlen = (sizeof readtar->header - readtar->data_read);
            if (maxlen > len)
                maxlen = len;
            memcpy(((char *)&readtar->header) + readtar->data_read, data, maxlen);
            readtar->data_read += maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            break;
        case IN_LONG_FILENAME:
            maxlen = readtar->filedata_left;
            if (maxlen > len)
                maxlen = len;
            ((void) sizeof ((readtar->longfilename) ? 1 : 0), __extension__ ({ if (readtar->longfilename) ; else __assert_fail ("readtar->longfilename", "readtar.c", 49, __extension__ __PRETTY_FUNCTION__); }));
            memcpy(readtar->longfilename + readtar->data_read, data, maxlen);
            readtar->data_read += maxlen;
            readtar->filedata_left -= maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            if (readtar->filedata_left == 0)
            {
                readtar->state = IN_EXTRA_DATA;
                readtar->data_read = 0;
            }
            break;
        case IN_LONG_LINKNAME:
            maxlen = readtar->filedata_left;
            if (maxlen > len)
                maxlen = len;
            ((void) sizeof ((readtar->longlinkname) ? 1 : 0), __extension__ ({ if (readtar->longlinkname) ; else __assert_fail ("readtar->longlinkname", "readtar.c", 68, __extension__ __PRETTY_FUNCTION__); }));
            memcpy(readtar->longlinkname + readtar->data_read, data, maxlen);
            readtar->data_read += maxlen;
            readtar->filedata_left -= maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            if (readtar->filedata_left == 0)
            {
                readtar->state = IN_EXTRA_DATA;
                readtar->data_read = 0;
            }
            break;
        case IN_EXTRA_DATA:
            maxlen = readtar->until_header_left;
            if (maxlen > len)
                maxlen = len;
            readtar->data_read += maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            if (readtar->until_header_left == 0)
            {
                readtar->state = IN_HEADER;
                readtar->data_read = 0;
            }
            break;
        case IN_DATA:
            maxlen = readtar->filedata_left;
            if (maxlen > len)
                maxlen = len;
            readtar->data_read += maxlen;
            readtar->filedata_left -= maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->cb.new_data(data, maxlen, readtar->cb.userdata);
            readtar->total_data_read += amount_read;
            if (readtar->filedata_left == 0)
            {
                readtar->data_read = 0;
                if (readtar->until_header_left > 0)
                    readtar->state = IN_EXTRA_DATA;
                else
                    readtar->state = IN_HEADER;
            }
            break;
    }
    if (readtar->state == IN_HEADER && readtar->data_read == sizeof readtar->header)
    {
        const struct header_gnu_tar *sh = &readtar->header;
        int checksum;
        struct readtar_file file;
        readtar->data_read = 0;
        if (sh->checksum[0] == '\0')
        {
            readtar->state = IN_HEADER;
            return amount_read;
        }
        checksum = read_octal_number(sh->checksum, sizeof sh->checksum);
        if (calc_checksum(sh) != checksum || strncmp(sh->magic, "ustar", 5))
        {
            if (command_line.debug && readtar->good_header)
                fprintf(stderr, "readtar: failed checksum interpreting tar, at pos %llu. "
                        "Searching header...\n", readtar->total_data_read);
            readtar->good_header = 0;
            readtar->state = IN_HEADER;
            return amount_read;
        }
        if (!readtar->good_header)
            if (command_line.debug)
                fprintf(stderr, "readtar: found new header at %llu.\n",
                        readtar->total_data_read);
        readtar->good_header = 1;
        file.size = read_size(readtar->header.size);
        readtar->filedata_left = file.size;
        readtar->until_header_left = file.size;
        if (readtar->until_header_left % 512 > 0)
            readtar->until_header_left += 512 - readtar->until_header_left % 512;
        if (sh->typeflag[0] == 'L')
        {
            readtar->longfilename = malloc(readtar->filedata_left + 1);
            if (!readtar->longfilename)
                fatal_error("Cannot allocate");
            readtar->longfilename[readtar->filedata_left] = '\0';
            readtar->state = IN_LONG_FILENAME;
            readtar->data_read = 0;
            return amount_read;
        }
        if (sh->typeflag[0] == 'K')
        {
            readtar->longlinkname = malloc(readtar->filedata_left + 1);
            if (!readtar->longlinkname)
                fatal_error("Cannot allocate");
            readtar->longlinkname[readtar->filedata_left] = '\0';
            readtar->state = IN_LONG_LINKNAME;
            readtar->data_read = 0;
            return amount_read;
        }
        file.name = readtar->longfilename ? readtar->longfilename :
            read_fixed_size_string(readtar->header.name, sizeof readtar->header.name);
        file.linkname = readtar->longlinkname ? readtar->longlinkname :
            read_fixed_size_string(readtar->header.linkname, sizeof readtar->header.linkname);
        file.size = read_size(readtar->header.size);
        file.header = &readtar->header;
        if (command_line.debug > 1)
            fprintf(stderr, "readtar: found header for file %s.\n", file.name);
        if (file.size > 0)
        {
            readtar->filedata_left = file.size;
            readtar->until_header_left = file.size;
            readtar->state = IN_DATA;
        }
        if (readtar->until_header_left % 512 > 0)
            readtar->until_header_left += 512 - readtar->until_header_left % 512;
        {
            enum readtar_newfile_result rres;
            rres = readtar->cb.new_file(&file, readtar->cb.userdata);
            if (rres == READTAR_SKIPDATA && readtar->fd >= 0)
            {
                int res;
                res = lseek(readtar->fd, readtar->until_header_left, 1);
                if (res != -1)
                {
                    readtar->state = IN_HEADER;
                    readtar->filedata_left = 0;
                    readtar->until_header_left = 0;
                }
            }
        }
        free(file.name);
        readtar->longfilename = 0;
        free(file.linkname);
        readtar->longlinkname = 0;
    }
    return amount_read;
}

canonical_original_code:
static int process_part(struct readtar *readtar, char *data, unsigned long len)
{
    unsigned long maxlen;
    unsigned long amount_read = 0;
    switch(readtar->state)
    {
        case IN_HEADER:
            maxlen = (sizeof readtar->header - readtar->data_read);
            if (maxlen > len)
                maxlen = len;
            memcpy(((char *)&readtar->header) + readtar->data_read, data, maxlen);
            readtar->data_read += maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            break;
        case IN_LONG_FILENAME:
            maxlen = readtar->filedata_left;
            if (maxlen > len)
                maxlen = len;
            ((void) sizeof ((readtar->longfilename) ? 1 : 0), __extension__ ({ if (readtar->longfilename) ; else __assert_fail ("readtar->longfilename", "readtar.c", 49, __extension__ __PRETTY_FUNCTION__); }));
            memcpy(readtar->longfilename + readtar->data_read, data, maxlen);
            readtar->data_read += maxlen;
            readtar->filedata_left -= maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            if (readtar->filedata_left == 0)
            {
                readtar->state = IN_EXTRA_DATA;
                readtar->data_read = 0;
            }
            break;
        case IN_LONG_LINKNAME:
            maxlen = readtar->filedata_left;
            if (maxlen > len)
                maxlen = len;
            ((void) sizeof ((readtar->longlinkname) ? 1 : 0), __extension__ ({ if (readtar->longlinkname) ; else __assert_fail ("readtar->longlinkname", "readtar.c", 68, __extension__ __PRETTY_FUNCTION__); }));
            memcpy(readtar->longlinkname + readtar->data_read, data, maxlen);
            readtar->data_read += maxlen;
            readtar->filedata_left -= maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            if (readtar->filedata_left == 0)
            {
                readtar->state = IN_EXTRA_DATA;
                readtar->data_read = 0;
            }
            break;
        case IN_EXTRA_DATA:
            maxlen = readtar->until_header_left;
            if (maxlen > len)
                maxlen = len;
            readtar->data_read += maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->total_data_read += amount_read;
            if (readtar->until_header_left == 0)
            {
                readtar->state = IN_HEADER;
                readtar->data_read = 0;
            }
            break;
        case IN_DATA:
            maxlen = readtar->filedata_left;
            if (maxlen > len)
                maxlen = len;
            readtar->data_read += maxlen;
            readtar->filedata_left -= maxlen;
            readtar->until_header_left -= maxlen;
            amount_read = maxlen;
            readtar->cb.new_data(data, maxlen, readtar->cb.userdata);
            readtar->total_data_read += amount_read;
            if (readtar->filedata_left == 0)
            {
                readtar->data_read = 0;
                if (readtar->until_header_left > 0)
                    readtar->state = IN_EXTRA_DATA;
                else
                    readtar->state = IN_HEADER;
            }
            break;
    }
    if (readtar->state == IN_HEADER && readtar->data_read == sizeof readtar->header)
    {
        struct header_gnu_tar *sh = &readtar->header;
        int checksum;
        struct readtar_file file;
        readtar->data_read = 0;
        if (sh->checksum[0] == '\0')
        {
            readtar->state = IN_HEADER;
            return amount_read;
        }
        checksum = read_octal_number(sh->checksum, sizeof sh->checksum);
        if (calc_checksum(sh) != checksum || strncmp(sh->magic, "ustar", 5))
        {
            if (command_line.debug && readtar->good_header)
                fprintf(stderr, "readtar: failed checksum interpreting tar, at pos %llu. "
                        "Searching header...\n", readtar->total_data_read);
            readtar->good_header = 0;
            readtar->state = IN_HEADER;
            return amount_read;
        }
        if (!readtar->good_header)
            if (command_line.debug)
                fprintf(stderr, "readtar: found new header at %llu.\n",
                        readtar->total_data_read);
        readtar->good_header = 1;
        file.size = read_size(readtar->header.size);
        readtar->filedata_left = file.size;
        readtar->until_header_left = file.size;
        if (readtar->until_header_left % 512 > 0)
            readtar->until_header_left += 512 - readtar->until_header_left % 512;
        if (sh->typeflag[0] == 'L')
        {
            readtar->longfilename = malloc(readtar->filedata_left + 1);
            if (!readtar->longfilename)
                fatal_error("Cannot allocate");
            readtar->longfilename[readtar->filedata_left] = '\0';
            readtar->state = IN_LONG_FILENAME;
            readtar->data_read = 0;
            return amount_read;
        }
        if (sh->typeflag[0] == 'K')
        {
            readtar->longlinkname = malloc(readtar->filedata_left + 1);
            if (!readtar->longlinkname)
                fatal_error("Cannot allocate");
            readtar->longlinkname[readtar->filedata_left] = '\0';
            readtar->state = IN_LONG_LINKNAME;
            readtar->data_read = 0;
            return amount_read;
        }
        file.name = readtar->longfilename ? readtar->longfilename :
            read_fixed_size_string(readtar->header.name, sizeof readtar->header.name);
        file.linkname = readtar->longlinkname ? readtar->longlinkname :
            read_fixed_size_string(readtar->header.linkname, sizeof readtar->header.linkname);
        file.size = read_size(readtar->header.size);
        file.header = &readtar->header;
        if (command_line.debug > 1)
            fprintf(stderr, "readtar: found header for file %s.\n", file.name);
        if (file.size > 0)
        {
            readtar->filedata_left = file.size;
            readtar->until_header_left = file.size;
            readtar->state = IN_DATA;
        }
        if (readtar->until_header_left % 512 > 0)
            readtar->until_header_left += 512 - readtar->until_header_left % 512;
        {
            enum readtar_newfile_result rres;
            rres = readtar->cb.new_file(&file, readtar->cb.userdata);
            if (rres == READTAR_SKIPDATA && readtar->fd >= 0)
            {
                int res;
                res = lseek(readtar->fd, readtar->until_header_left, 1);
                if (res != -1)
                {
                    readtar->state = IN_HEADER;
                    readtar->filedata_left = 0;
                    readtar->until_header_left = 0;
                }
            }
        }
        free(file.name);
        readtar->longfilename = 0;
        free(file.linkname);
        readtar->longlinkname = 0;
    }
    return amount_read;
}

variable_types: struct readtar { enum { IN_HEADER=0, IN_DATA=1, IN_EXTRA_DATA=2, IN_LONG_FILENAME=3, IN_LONG_LINKNAME=4 } state; char *longfilename; char *longlinkname; struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } header; unsigned long long filedata_left; unsigned long long until_header_left; unsigned long long data_read; unsigned long long total_data_read; struct readtar_callbacks { enum readtar_newfile_result { READTAR_NORMAL=0, READTAR_SKIPDATA=1 } (*new_file)(struct readtar_file { struct header_gnu_tar *header; char *name; char *linkname; unsigned long long size; } *file, void *userdata); void (*new_data)(char *data, unsigned long len, void *userdata); void *userdata; } cb; int good_header; int fd; } *

variable_types:
data
char *

variable_types:
len
unsigned long

variable_types:
maxlen
unsigned long

variable_types: checksum int

variable_types: struct readtar_file { struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; } *header; char *name; char *linkname; unsigned long long size; }


decompiled_code:
__int64 __fastcall readtar_bytes_to_next_change(__int64 a1)
{
unsigned int v1; // eax
__int64 result; // rax

v1 = *(_DWORD *)a1;
if ( *(_DWORD *)a1 == 2 )
return *(_QWORD *)(a1 + 544);
if ( v1 > 2 )
{
if ( v1 - 3 <= 1 )
return *(_QWORD *)(a1 + 536);
fatal_error("Unknown readtar state");
result = 0LL;
}
else
{
if ( v1 )
return *(_QWORD *)(a1 + 536);
result = 512LL - *(_QWORD *)(a1 + 552);
}
return result;
}

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

v1 = *(_DWORD *)a1;
if ( *(_DWORD *)a1 == 2 )
return *(_QWORD *)(a1 + 544);
if ( v1 > 2 )
{
if ( v1 - 3 <= 1 )
return *(_QWORD *)(a1 + 536);
fatal_error("Unknown readtar state");
result = 0LL;
}
else
{
if ( v1 )
return *(_QWORD *)(a1 + 536);
result = 512LL - *(_QWORD *)(a1 + 552);
}
return result;
}

original_code:
size_t
readtar_bytes_to_next_change(const struct readtar *readtar)
{
    size_t maxlen;
    switch(readtar->state)
    {
        case IN_HEADER:
            maxlen = (sizeof readtar->header - readtar->data_read);
            break;
        case IN_LONG_FILENAME:
            maxlen = readtar->filedata_left;
            break;
        case IN_LONG_LINKNAME:
            maxlen = readtar->filedata_left;
            break;
        case IN_EXTRA_DATA:
            maxlen = readtar->until_header_left;
            break;
        case IN_DATA:
            maxlen = readtar->filedata_left;
            break;
        default:
            fatal_error("Unknown readtar state");
            maxlen = 0;
            break;
    }
    return maxlen;
}

canonical_original_code:
unsigned long readtar_bytes_to_next_change(struct readtar *readtar)
{
    unsigned long maxlen;
    switch(readtar->state)
    {
        case IN_HEADER:
            maxlen = (sizeof readtar->header - readtar->data_read);
            break;
        case IN_LONG_FILENAME:
            maxlen = readtar->filedata_left;
            break;
        case IN_LONG_LINKNAME:
            maxlen = readtar->filedata_left;
            break;
        case IN_EXTRA_DATA:
            maxlen = readtar->until_header_left;
            break;
        case IN_DATA:
            maxlen = readtar->filedata_left;
            break;
        default:
            fatal_error("Unknown readtar state");
            maxlen = 0;
            break;
    }
    return maxlen;
}

user_defined_types: struct header_gnu_tar { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char checksum[8]; char typeflag[1]; char linkname[100]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; char atime[12]; char ctime[12]; char offset[12]; char longnames[4]; char unused[1]; struct { char offset[12]; char numbytes[12]; } sparse[4]; char isextended[1]; char realsize[12]; char pad[17]; }

user_defined_types: enum readtar_newfile_result { READTAR_NORMAL=0, READTAR_SKIPDATA=1 }


decompiled_code:
void __fastcall process_this_tar_data(int *a1, char *a2, size_t a3)
{
size_t v4; // rbp
int v5; // eax
__int64 v6; // rbx

if ( a3 )
{
v4 = a3;
do
{
while ( 1 )
{
v5 = process_part(a1, a2, v4);
v6 = v5;
if ( (int)command_line[1] > 2 )
break;
a2 += v5;
v4 -= v5;
if ( !v4 )
return;
}
a2 += v5;
fprintf(stderr, "readtar, processed %zu bytes\n", v5);
v4 -= v6;
}
while ( v4 );
}
}

canonical_decompiled_code:
void __fastcall func2(int *a1, char *a2, size_t a3)
{
size_t v4; // rbp
int v5; // eax
__int64 v6; // rbx

if ( a3 )
{
v4 = a3;
do
{
while ( 1 )
{
v5 = func0(a1, a2, v4);
v6 = v5;
if ( (int)command_line[1] > 2 )
break;
a2 += v5;
v4 -= v5;
if ( !v4 )
return;
}
a2 += v5;
fprintf(stderr, "readtar, processed %zu bytes\n", v5);
v4 -= v6;
}
while ( v4 );
}
}

original_code:
void
process_this_tar_data(struct readtar *readtar, const char *data, size_t len)
{
    const char *p = data;
    while(len > 0)
    {
        size_t res;
        res = process_part(readtar, p, len);
        if (command_line.debug > 2)
            fprintf(stderr, "readtar, processed %zu bytes\n", res);
        len -= res;
        p += res;
    }
}

canonical_original_code:
void process_this_tar_data(struct readtar *readtar, char *data, unsigned long len)
{
    char *p = data;
    while(len > 0)
    {
        unsigned long res;
        res = process_part(readtar, p, len);
        if (command_line.debug > 2)
            fprintf(stderr, "readtar, processed %zu bytes\n", res);
        len -= res;
        p += res;
    }
}

variable_types:
p
char *

variable_types:
res
unsigned long


original_code:
void
init_readtar(struct readtar *readtar, const struct readtar_callbacks *cb)
{
    readtar->cb = *cb;
    readtar->longfilename = 0;
    readtar->longlinkname = 0;
    readtar->filedata_left = 0;
    readtar->until_header_left = 0;
    readtar->data_read = 0;
    readtar->total_data_read = 0;
    readtar->state = IN_HEADER;
    readtar->good_header = 1;
    readtar->fd = -1;
}

canonical_original_code:
void init_readtar(struct readtar *readtar, struct readtar_callbacks *cb)
{
    readtar->cb = *cb;
    readtar->longfilename = 0;
    readtar->longlinkname = 0;
    readtar->filedata_left = 0;
    readtar->until_header_left = 0;
    readtar->data_read = 0;
    readtar->total_data_read = 0;
    readtar->state = IN_HEADER;
    readtar->good_header = 1;
    readtar->fd = -1;
}

variable_types:
cb
struct readtar_callbacks *


decompiled_code:
void __fastcall read_full_tar(int fd, int *a2)
{
void *v2; // rbp
unsigned int v3; // eax
unsigned int v4; // ebx
const char *v5; // rdx

v2 = malloc(0x100000uLL);
if ( !v2 )
fatal_error("Cannot allocate memory");
while ( 1 )
{
while ( 1 )
{
v3 = read(fd, v2, 0x100000uLL);
v4 = v3;
if ( v3 != -1 )
break;
if ( *_errno_location() != 4 )
{
error((int)"Error reading while readtar", (int)v2, v5);
if ( (int)command_line[1] <= 2 )
goto LABEL_5;
goto LABEL_9;
}
}
if ( !v3 )
break;
if ( (int)command_line[1] <= 2 )
goto LABEL_5;
LABEL_9:
fprintf(stderr, "readtar, read %i bytes\n", v4);
LABEL_5:
process_this_tar_data(a2, (char *)v2, (int)v4);
}
if ( (int)command_line[1] > 1 )
fwrite("readtar: finishing tar\n", 1uLL, 0x17uLL, stderr);
free(v2);
}

canonical_decompiled_code:
void __fastcall func4(int fd, int *a2)
{
void *v2; // rbp
unsigned int v3; // eax
unsigned int v4; // ebx
const char *v5; // rdx

v2 = malloc(0x100000uLL);
if ( !v2 )
fatal_error("Cannot allocate memory");
while ( 1 )
{
while ( 1 )
{
v3 = read(fd, v2, 0x100000uLL);
v4 = v3;
if ( v3 != -1 )
break;
if ( *_errno_location() != 4 )
{
error((int)"Error reading while readtar", (int)v2, v5);
if ( (int)command_line[1] <= 2 )
goto LABEL_5;
goto LABEL_9;
}
}
if ( !v3 )
break;
if ( (int)command_line[1] <= 2 )
goto LABEL_5;
LABEL_9:
fprintf(stderr, "readtar, read %i bytes\n", v4);
LABEL_5:
func2(a2, (char *)v2, (int)v4);
}
if ( (int)command_line[1] > 1 )
fwrite("readtar: finishing tar\n", 1uLL, 0x17uLL, stderr);
free(v2);
}

original_code:
void
read_full_tar(int infd, struct readtar *readtar)
{
    const int buffersize = 1*1024*1024;
    char *buffer = malloc(buffersize);
    if (!buffer)
        fatal_error("Cannot allocate memory");
    while(1)
    {
        int res;
        res = read(infd, buffer, buffersize);
        if (res == -1 && (*__errno_location ()) == 4)
            continue;
        if (res == -1)
            error("Error reading while readtar");
        if (res == 0)
            break;
        if (command_line.debug > 2)
            fprintf(stderr, "readtar, read %i bytes\n", res);
        process_this_tar_data(readtar, buffer, res);
    }
    if (command_line.debug > 1)
        fprintf(stderr, "readtar: finishing tar\n");
    free(buffer);
}

canonical_original_code:
void read_full_tar(int infd, struct readtar *readtar)
{
    int buffersize = 1*1024*1024;
    char *buffer = malloc(buffersize);
    if (!buffer)
        fatal_error("Cannot allocate memory");
    while(1)
    {
        int res;
        res = read(infd, buffer, buffersize);
        if (res == -1 && (*__errno_location ()) == 4)
            continue;
        if (res == -1)
            error("Error reading while readtar");
        if (res == 0)
            break;
        if (command_line.debug > 2)
            fprintf(stderr, "readtar, read %i bytes\n", res);
        process_this_tar_data(readtar, buffer, res);
    }
    if (command_line.debug > 1)
        fprintf(stderr, "readtar: finishing tar\n");
    free(buffer);
}

variable_types: infd int

variable_types: buffersize int

variable_types:
buffer
char *

variable_types: res int


SetConst

repo: mxcube/pychooch

decompiled_code:
int __fastcall SetConst(int a1, double *a2, double a3)
{
__int64 v3; // rax

LODWORD(v3) = printf("Warning: Insufficient data - assuming constant value of %f in normalisation\n", a3);
if ( a1 > 0 )
{
v3 = (__int64)&a2[(unsigned int)(a1 - 1) + 1];
do
*a2++ = a3;
while ( a2 != (double *)v3 );
}
return v3;
}

canonical_decompiled_code:
int __fastcall func0(int a1, double *a2, double a3)
{
__int64 v3; // rax

LODWORD(v3) = printf("Warning: Insufficient data - assuming constant value of %f in normalisation\n", a3);
if ( a1 > 0 )
{
v3 = (__int64)&a2[(unsigned int)(a1 - 1) + 1];
do
*a2++ = a3;
while ( a2 != (double *)v3 );
}
return v3;
}

original_code:
void SetConst(int n, double f, double *Array)
{
   int i;
   printf("Warning: Insufficient data - assuming constant value of %f in normalisation\n", f);
   for (i = 0; i < n; i++) {
      Array[i] = f;
   }
}

variable_types: n int

variable_types: f double

variable_types:
Array
double *

variable_types: i int