decompiled_code:
__int64 __fastcall fwsim_transmit(void *buf, size_t n)
{
size_t v3; // rbx
ssize_t v4; // rax

v3 = n;
if ( !n )
return 0LL;
while ( 1 )
{
v4 = write(dword_284, buf, v3);
if ( v4 < 0 )
break;
buf = (char *)buf + v4;
v3 -= v4;
if ( !v3 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(void *buf, size_t n)
{
size_t v3; // rbx
ssize_t v4; // rax

v3 = n;
if ( !n )
return 0LL;
while ( 1 )
{
v4 = write(dword_284, buf, v3);
if ( v4 < 0 )
break;
buf = (char *)buf + v4;
v3 -= v4;
if ( !v3 )
return 0LL;
}
return 1LL;
}

original_code:
int fwsim_transmit(const char *buf, size_t count)
{
    while (count) {
        ssize_t nw = write(send_pipe[1], buf, count);
        if (nw < 0)
            return 1;
        buf += nw;
        count -= nw;
    }
    return 0;
}

canonical_original_code:
int fwsim_transmit(char *buf, unsigned long count)
{
    while (count) {
        long nw = write(send_pipe[1], buf, count);
        if (nw < 0)
            return 1;
        buf += nw;
        count -= nw;
    }
    return 0;
}

variable_types:
count
unsigned long

variable_types: nw long


repo: kbob/kerfburn

decompiled_code:
ssize_t __fastcall fwsim_receive(void *buf, size_t nbytes)
{
ssize_t v2; // rbx

v2 = read(recv_pipe[0], buf, nbytes);
if ( v2 < 0 )
perror("fwsim read failed");
return v2;
}

canonical_decompiled_code:
ssize_t __fastcall func4(void *buf, size_t nbytes)
{
ssize_t v2; // rbx

v2 = read(recv_pipe[0], buf, nbytes);
if ( v2 < 0 )
perror("fwsim read failed");
return v2;
}

original_code:
ssize_t fwsim_receive(char *buf, size_t max)
{
    ssize_t nr = read(recv_pipe[0], buf, max);
    if (nr < 0)
        perror("fwsim read failed");
    return nr;
}

canonical_original_code:
long fwsim_receive(char *buf, unsigned long max)
{
    long nr = read(recv_pipe[0], buf, max);
    if (nr < 0)
        perror("fwsim read failed");
    return nr;
}

variable_types:
buf
char *

variable_types:
max
unsigned long

variable_types: nr long

return_type: long


decompiled_code:
void __fastcall set_port(char *s)
{
char *v1; // rbx

v1 = s;
free(pc);
free(ptr);
free(qword_2D0);
free(qword_2D8);
free(qword_2E0);
qword_2E0 = 0LL;
qword_2D8 = 0LL;
qword_2D0 = 0LL;
ptr = 0LL;
if ( s )
v1 = strdup(s);
pc = v1;
}

canonical_decompiled_code:
void __fastcall func1(char *s)
{
char *v1; // rbx

v1 = s;
free(pc);
free(ptr);
free(qword_2D0);
free(qword_2D8);
free(qword_2E0);
qword_2E0 = 0LL;
qword_2D8 = 0LL;
qword_2D0 = 0LL;
ptr = 0LL;
if ( s )
v1 = strdup(s);
pc = v1;
}

original_code:
void set_port(const char *port)
{
    free(pc.pc_port);
    free(pc.pc_sock_dir);
    free(pc.pc_sock_path);
    free(pc.pc_dev_path);
    free(pc.pc_lck_path);
    pc.pc_sock_dir = pc.pc_sock_path = pc.pc_dev_path = pc.pc_lck_path = ((void *)0);
    pc.pc_port = port ? strdup(port) : ((void *)0);
}

canonical_original_code:
void set_port(char *port)
{
    free(pc.pc_port);
    free(pc.pc_sock_dir);
    free(pc.pc_sock_path);
    free(pc.pc_dev_path);
    free(pc.pc_lck_path);
    pc.pc_sock_dir = pc.pc_sock_path = pc.pc_dev_path = pc.pc_lck_path = ((void *)0);
    pc.pc_port = port ? strdup(port) : ((void *)0);
}

variable_types:
port
char *

return_type: void


decompiled_code:
char *get_device()
{
char *v0; // rbx
char *v2; // rbp
unsigned int v3; // ebx
char v4[16]; // [rsp+0h] [rbp-B8h] BYREF
struct stat v5; // [rsp+10h] [rbp-A8h] BYREF

v0 = (char *)qword_2D8;
if ( !qword_2D8 )
{
v2 = pc;
if ( pc )
{
if ( stat(pc, &v5) < 0 )
{
perror(pc);
}
else if ( (v5.st_mode & 0xF000) == 0x2000 )
{
v0 = pc;
}
else
{
fprintf(stderr, "%s: not a character device", pc);
}
}
else
{
v3 = 0;
while ( 1 )
{
snprintf(v4, 0x10uLL, "/dev/ttyUSB%d", v3);
if ( stat(v4, &v5) >= 0 )
break;
if ( *_errno_location() != 2 )
{
perror(v4);
return v2;
}
if ( ++v3 == 10 )
{
fwrite("No USB serial device found\n", 1uLL, 0x1BuLL, stderr);
return v2;
}
}
v0 = strdup(v4);
qword_2D8 = v0;
}
}
return v0;
}

canonical_decompiled_code:
char *func2()
{
char *v0; // rbx
char *v2; // rbp
unsigned int v3; // ebx
char v4[16]; // [rsp+0h] [rbp-B8h] BYREF
struct stat v5; // [rsp+10h] [rbp-A8h] BYREF

v0 = (char *)qword_2D8;
if ( !qword_2D8 )
{
v2 = pc;
if ( pc )
{
if ( stat(pc, &v5) < 0 )
{
perror(pc);
}
else if ( (v5.st_mode & 0xF000) == 0x2000 )
{
v0 = pc;
}
else
{
fprintf(stderr, "%s: not a character device", pc);
}
}
else
{
v3 = 0;
while ( 1 )
{
snprintf(v4, 0x10uLL, "/dev/ttyUSB%d", v3);
if ( stat(v4, &v5) >= 0 )
break;
if ( *_errno_location() != 2 )
{
perror(v4);
return v2;
}
if ( ++v3 == 10 )
{
fwrite("No USB serial device found\n", 1uLL, 0x1BuLL, stderr);
return v2;
}
}
v0 = strdup(v4);
qword_2D8 = v0;
}
}
return v0;
}

original_code:
const char *get_device(void)
{
    if (pc.pc_dev_path)
        return pc.pc_dev_path;
    struct stat s;
    if (pc.pc_port) {
        if (stat(pc.pc_port, &s) < 0) {
            perror(pc.pc_port);
            return ((void *)0);
        }
        if (!((((s.st_mode)) & 0170000) == (0020000))) {
            fprintf(stderr, "%s: not a character device", pc.pc_port);
            return ((void *)0);
        }
        return pc.pc_port;
    }
    for (int i = 0; i < 10; i++) {
        char path[16];
        snprintf(path, sizeof path, "/dev/ttyUSB%d", i);
        if (stat(path, &s) < 0) {
            if ((*__errno_location ()) == 2)
                continue;
            perror(path);
            return ((void *)0);
        }
        pc.pc_dev_path = strdup(path);
        return pc.pc_dev_path;
    }
    fprintf(stderr, "No USB serial device found\n");
    return ((void *)0);
}

canonical_original_code:
char *get_device()
{
    if (pc.pc_dev_path)
        return pc.pc_dev_path;
    struct stat s;
    if (pc.pc_port) {
        if (stat(pc.pc_port, &s) < 0) {
            perror(pc.pc_port);
            return ((void *)0);
        }
        if (!((((s.st_mode)) & 0170000) == (0020000))) {
            fprintf(stderr, "%s: not a character device", pc.pc_port);
            return ((void *)0);
        }
        return pc.pc_port;
    }
    for (int i = 0; i < 10; i++) {
        char path[16];
        snprintf(path, sizeof path, "/dev/ttyUSB%d", i);
        if (stat(path, &s) < 0) {
            if ((*__errno_location ()) == 2)
                continue;
            perror(path);
            return ((void *)0);
        }
        pc.pc_dev_path = strdup(path);
        return pc.pc_dev_path;
    }
    fprintf(stderr, "No USB serial device found\n");
    return ((void *)0);
}

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

variable_types: i int

variable_types:
path
char [16]

return_type: char *

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


decompiled_code:
const char *get_socket_dir()
{
const char *result; // rax
char *v1; // rax

result = "/tmp/thruport";
if ( pc )
{
if ( !ptr )
{
v1 = kb_basename(pc);
asprintf(&ptr, "/tmp/thruport-%s", v1);
}
result = ptr;
}
return result;
}

canonical_decompiled_code:
const char *func3()
{
const char *result; // rax
char *v1; // rax

result = "/tmp/thruport";
if ( pc )
{
if ( !ptr )
{
v1 = func0(pc);
asprintf(&ptr, "/tmp/thruport-%s", v1);
}
result = ptr;
}
return result;
}

original_code:
const char *get_socket_dir(void)
{
    if (pc.pc_port) {
        if (!pc.pc_sock_dir)
            asprintf(&pc.pc_sock_dir, "/tmp/thruport-%s",
                     kb_basename(pc.pc_port));
        return pc.pc_sock_dir;
    }
    return "/tmp/thruport";
}

canonical_original_code:
char *get_socket_dir()
{
    if (pc.pc_port) {
        if (!pc.pc_sock_dir)
            asprintf(&pc.pc_sock_dir, "/tmp/thruport-%s",
                     kb_basename(pc.pc_port));
        return pc.pc_sock_dir;
    }
    return "/tmp/thruport";
}


decompiled_code:
char *get_socket_path()
{
const char *v1; // rax

if ( !qword_2D0 )
{
v1 = get_socket_dir();
asprintf(&qword_2D0, "%s/socket", v1);
}
return qword_2D0;
}

canonical_decompiled_code:
char *func4()
{
const char *v1; // rax

if ( !qword_2D0 )
{
v1 = func3();
asprintf(&qword_2D0, "%s/socket", v1);
}
return qword_2D0;
}

original_code:
const char *get_socket_path(void)
{
    if (!pc.pc_sock_path)
        asprintf(&pc.pc_sock_path, "%s/socket", get_socket_dir());
    return pc.pc_sock_path;
}

canonical_original_code:
char *get_socket_path()
{
    if (!pc.pc_sock_path)
        asprintf(&pc.pc_sock_path, "%s/socket", get_socket_dir());
    return pc.pc_sock_path;
}


decompiled_code:
const char *get_lock_dir()
{
return "/var/lock";
}

canonical_decompiled_code:
const char *func5()
{
return "/var/lock";
}

original_code:
const char *get_lock_dir(void)
{
    return "/var/lock";
}


decompiled_code:
char *get_lock_path()
{
char *result; // rax
char *v1; // rbx
const char *v2; // rax

if ( qword_2E0 )
return qword_2E0;
result = get_device();
if ( result )
{
v1 = kb_basename(result);
v2 = get_lock_dir();
asprintf(&qword_2E0, "%s/LCK..%s", v2, v1);
result = qword_2E0;
}
return result;
}

canonical_decompiled_code:
char *func6()
{
char *result; // rax
char *v1; // rbx
const char *v2; // rax

if ( qword_2E0 )
return qword_2E0;
result = func2();
if ( result )
{
v1 = func0(result);
v2 = func5();
asprintf(&qword_2E0, "%s/LCK..%s", v2, v1);
result = qword_2E0;
}
return result;
}

original_code:
const char *get_lock_path(void)
{
    if (!pc.pc_lck_path) {
        const char *dev = get_device();
        if (!dev)
            return ((void *)0);
        asprintf(&pc.pc_lck_path, "%s/LCK..%s",
                 get_lock_dir(), kb_basename(dev));
    }
    return pc.pc_lck_path;
}

canonical_original_code:
char *get_lock_path()
{
    if (!pc.pc_lck_path) {
        char *dev = get_device();
        if (!dev)
            return ((void *)0);
        asprintf(&pc.pc_lck_path, "%s/LCK..%s",
                 get_lock_dir(), kb_basename(dev));
    }
    return pc.pc_lck_path;
}

variable_types:
dev
char *


decompiled_code:
int send_stdin()
{
return send_stream(stdin);
}

canonical_decompiled_code:
int func1()
{
return func0(stdin);
}

original_code:
static int send_stdin(void)
{
    return send_stream(stdin, "Standard input");
}

canonical_original_code:
static int send_stdin()
{
    return send_stream(stdin, "Standard input");
}

return_type: int


decompiled_code:
void *__fastcall sender_thread_main(void *a1)
{
int v1; // eax

send_files((char **)a1);
v1 = fileno(sockwf);
if ( shutdown(v1, 1) )
{
perror("shutdown");
exit(1);
}
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func4(void *a1)
{
int v1; // eax

func3((char **)a1);
v1 = fileno(sockwf);
if ( shutdown(v1, 1) )
{
perror("shutdown");
exit(1);
}
return 0LL;
}

original_code:
static void *sender_thread_main(void *arg)
{
    send_files(arg);
    if (shutdown(fileno(sockwf), SHUT_WR)) {
        perror("shutdown");
        exit(1);
    }
    return ((void *)0);
}

variable_types:
arg
void *

return_type: void *


decompiled_code:
__int64 __fastcall be_sender(void *arg)
{
int v2; // eax
unsigned int v3; // er12
int v4; // ebx
int v5; // er12
FILE *v6; // rdi
int v7; // eax
char *v9; // rax
pthread_t newthread[4]; // [rsp+8h] [rbp-20h] BYREF

signal(13, handler);
v2 = connect_or_start_daemon(83LL);
v3 = 1;
if ( v2 >= 0 )
{
v4 = v2;
v5 = dup(v2);
if ( v5 < 0 )
{
perror("socket dup failed");
v3 = 1;
}
else
{
sockrf = fdopen(v4, "r+");
if ( sockrf )
{
v6 = fdopen(v5, "w");
sockwf = v6;
if ( v6 )
{
setbuf(v6, 0LL);
v7 = pthread_create(newthread, 0LL, sender_thread_main, arg);
if ( v7 )
{
v9 = strerror(v7);
fprintf(stderr, "can't create thread: %s", v9);
v3 = 1;
}
else
{
v3 = copy_errors(sockrf);
pthread_cancel(newthread[0]);
pthread_join(newthread[0], 0LL);
fclose(sockwf);
fclose(sockrf);
}
}
else
{
perror("can't create stream");
fclose(sockrf);
close(v5);
close(v4);
v3 = 1;
}
}
else
{
perror("can't create stream");
close(v5);
close(v4);
v3 = 1;
}
}
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func6(void *arg)
{
int v2; // eax
unsigned int v3; // er12
int v4; // ebx
int v5; // er12
FILE *v6; // rdi
int v7; // eax
char *v9; // rax
pthread_t newthread[4]; // [rsp+8h] [rbp-20h] BYREF

signal(13, handler);
v2 = connect_or_start_daemon(83LL);
v3 = 1;
if ( v2 >= 0 )
{
v4 = v2;
v5 = dup(v2);
if ( v5 < 0 )
{
perror("socket dup failed");
v3 = 1;
}
else
{
sockrf = fdopen(v4, "r+");
if ( sockrf )
{
v6 = fdopen(v5, "w");
sockwf = v6;
if ( v6 )
{
setbuf(v6, 0LL);
v7 = pthread_create(newthread, 0LL, sender_thread_main, arg);
if ( v7 )
{
v9 = strerror(v7);
fprintf(stderr, "can't create thread: %s", v9);
v3 = 1;
}
else
{
v3 = func5(sockrf);
pthread_cancel(newthread[0]);
pthread_join(newthread[0], 0LL);
fclose(sockwf);
fclose(sockrf);
}
}
else
{
perror("can't create stream");
fclose(sockrf);
close(v5);
close(v4);
v3 = 1;
}
}
else
{
perror("can't create stream");
close(v5);
close(v4);
v3 = 1;
}
}
}
return v3;
}

original_code:
int be_sender(const char *const *files)
{
    signal(13, ((__sighandler_t) 1));
    int sock = connect_or_start_daemon(CT_SENDER);
    if (sock < 0)
        return 1;
    int sock2 = dup(sock);
    if (sock2 < 0) {
        perror("socket dup failed");
        return 1;
    }
    sockrf = fdopen(sock, "r+");
    if (!sockrf) {
        perror("can't create stream");
        close(sock2);
        close(sock);
        return 1;
    }
    sockwf = fdopen(sock2, "w");
    if (!sockwf) {
        perror("can't create stream");
        fclose(sockrf);
        close(sock2);
        close(sock);
        return 1;
    }
    setbuf(sockwf, ((void *)0));
    pthread_t sender_thread;
    int r = pthread_create(&sender_thread, ((void *)0),
                           sender_thread_main, (void *)files);
    if (r) {
        fprintf(stderr, "can't create thread: %s", strerror(r));
        return 1;
    }
    int status = copy_errors(sockrf);
    (void)pthread_cancel(sender_thread);
    (void)pthread_join(sender_thread, ((void *)0));
    fclose(sockwf);
    fclose(sockrf);
    return status;
}

canonical_original_code:
int be_sender(char **files)
{
    signal(13, ((void (*)(int)) 1));
    int sock = connect_or_start_daemon(CT_SENDER);
    if (sock < 0)
        return 1;
    int sock2 = dup(sock);
    if (sock2 < 0) {
        perror("socket dup failed");
        return 1;
    }
    sockrf = fdopen(sock, "r+");
    if (!sockrf) {
        perror("can't create stream");
        close(sock2);
        close(sock);
        return 1;
    }
    sockwf = fdopen(sock2, "w");
    if (!sockwf) {
        perror("can't create stream");
        fclose(sockrf);
        close(sock2);
        close(sock);
        return 1;
    }
    setbuf(sockwf, ((void *)0));
    unsigned long sender_thread;
    int r = pthread_create(&sender_thread, ((void *)0),
                           sender_thread_main, (void *)files);
    if (r) {
        fprintf(stderr, "can't create thread: %s", strerror(r));
        return 1;
    }
    int status = copy_errors(sockrf);
    (void)pthread_cancel(sender_thread);
    (void)pthread_join(sender_thread, ((void *)0));
    fclose(sockwf);
    fclose(sockrf);
    return status;
}

variable_types:
files
char **

variable_types: sock int

variable_types: r int

variable_types: status int


decompiled_code:
__blksize_t __fastcall fd_blksize(int a1)
{
int v1; // edx
__blksize_t result; // rax
struct stat v3; // [rsp+0h] [rbp-98h] BYREF

v1 = fstat(a1, &v3);
result = v3.st_blksize;
if ( v1 < 0 )
{
syslog(4, "fstat failed: %m");
result = 0x2000LL;
}
return result;
}

canonical_decompiled_code:
__blksize_t __fastcall func0(int a1)
{
int v1; // edx
__blksize_t result; // rax
struct stat v3; // [rsp+0h] [rbp-98h] BYREF

v1 = fstat(a1, &v3);
result = v3.st_blksize;
if ( v1 < 0 )
{
syslog(4, "fstat failed: %m");
result = 0x2000LL;
}
return result;
}

original_code:
size_t fd_blksize(int fd)
{
    struct stat s;
    if (fstat(fd, &s) < 0) {
        syslog(4, "fstat failed: %m");
        return 8192;
    } else
        return (size_t)s.st_blksize;
}

canonical_original_code:
unsigned long fd_blksize(int fd)
{
    struct stat s;
    if (fstat(fd, &s) < 0) {
        syslog(4, "fstat failed: %m");
        return 8192;
    } else
        return (unsigned long)s.st_blksize;
}

variable_types: fd int

return_type: unsigned long

user_defined_types: struct timespec { long tv_sec; long tv_nsec; }


decompiled_code:
ssize_t __fastcall read_line(int fd, __int64 a2, __int64 a3)
{
__int64 v3; // r12
__int64 v4; // rbx
ssize_t result; // rax

v3 = a3 - 1;
if ( a3 == 1 )
{
LABEL_10:
*(_BYTE *)(a2 + v3 + 1) = 0;
result = v3 + 1;
}
else
{
v4 = 0LL;
while ( 1 )
{
result = read(fd, (void *)(a2 + v4), 1uLL);
if ( result < 0 )
break;
if ( !result )
return v4;
if ( *(_BYTE *)(a2 + v4) == 10 )
{
v3 = v4;
goto LABEL_10;
}
if ( ++v4 == v3 )
goto LABEL_10;
}
}
return result;
}

canonical_decompiled_code:
ssize_t __fastcall func1(int fd, __int64 a2, __int64 a3)
{
__int64 v3; // r12
__int64 v4; // rbx
ssize_t result; // rax

v3 = a3 - 1;
if ( a3 == 1 )
{
LABEL_10:
*(_BYTE *)(a2 + v3 + 1) = 0;
result = v3 + 1;
}
else
{
v4 = 0LL;
while ( 1 )
{
result = read(fd, (void *)(a2 + v4), 1uLL);
if ( result < 0 )
break;
if ( !result )
return v4;
if ( *(_BYTE *)(a2 + v4) == 10 )
{
v3 = v4;
goto LABEL_10;
}
if ( ++v4 == v3 )
goto LABEL_10;
}
}
return result;
}

original_code:
ssize_t read_line(int fd, char *buf, size_t max)
{
    size_t i;
    for (i = 0; i < max - 1; i++) {
        ssize_t nr = read(fd, buf + i, 1);
        if (nr < 0)
            return nr;
        if (nr == 0)
            return i;
        if (buf[i] == '\n')
            break;
    }
    buf[++i] = '\0';
    return i;
}

canonical_original_code:
long read_line(int fd, char *buf, unsigned long max)
{
    unsigned long i;
    for (i = 0; i < max - 1; i++) {
        long nr = read(fd, buf + i, 1);
        if (nr < 0)
            return nr;
        if (nr == 0)
            return i;
        if (buf[i] == '\n')
            break;
    }
    buf[++i] = '\0';
    return i;
}

variable_types:
i
unsigned long


decompiled_code:
char *__fastcall char_repr(unsigned int a1)
{
if ( a1 - 32 <= 0x5E )
{
snprintf(rep_1, 0xAuLL, "%c", a1);
}
else if ( (a1 & 0x80u) == 0 )
{
snprintf(rep_1, 0xAuLL, "\\%o", a1);
}
else
{
snprintf(rep_1, 0xAuLL, "\\x%02x", (unsigned __int8)a1);
}
return rep_1;
}

canonical_decompiled_code:
char *__fastcall func2(unsigned int a1)
{
if ( a1 - 32 <= 0x5E )
{
snprintf(rep_1, 0xAuLL, "%c", a1);
}
else if ( (a1 & 0x80u) == 0 )
{
snprintf(rep_1, 0xAuLL, "\\%o", a1);
}
else
{
snprintf(rep_1, 0xAuLL, "\\x%02x", (unsigned __int8)a1);
}
return rep_1;
}

original_code:
const char *char_repr(int c, _Bool highlighted)
{
    static char rep[10];
    if (c >= ' ' && c < '\177')
        snprintf(rep, sizeof rep, "%c", c);
    else if (c & 0x80)
        snprintf(rep, sizeof rep, "\\x%02x", c & 0xFF);
    else
        snprintf(rep, sizeof rep, "\\%o", c);
    return rep;
}

variable_types: c int

variable_types:
rep
char [10]


decompiled_code:
char *__fastcall str_repr(char *a1, __int64 a2)
{
char *v2; // r12
char *v3; // r13
unsigned __int64 v4; // rbp
char *v5; // rbx
unsigned __int64 v6; // rdi
size_t v8; // rax

strcpy(buf_0, "\"");
if ( a2 )
{
v2 = a1;
v3 = &a1[a2];
v4 = 1LL;
while ( 1 )
{
v5 = char_repr(*v2);
v6 = v4;
v4 += strlen(v5);
if ( v4 > 0x2D )
break;
strcpy(&buf_0[v6], v5);
if ( ++v2 == v3 )
goto LABEL_5;
}
v8 = strlen(buf_0);
*(_DWORD *)&buf_0[v8] = 774778402;
byte_1C4[v8] = 0;
}
else
{
LABEL_5:
*(_WORD *)&buf_0[strlen(buf_0)] = 34;
}
return buf_0;
}

canonical_decompiled_code:
char *__fastcall func3(char *a1, __int64 a2)
{
char *v2; // r12
char *v3; // r13
unsigned __int64 v4; // rbp
char *v5; // rbx
unsigned __int64 v6; // rdi
size_t v8; // rax

strcpy(buf_0, "\"");
if ( a2 )
{
v2 = a1;
v3 = &a1[a2];
v4 = 1LL;
while ( 1 )
{
v5 = func2(*v2);
v6 = v4;
v4 += strlen(v5);
if ( v4 > 0x2D )
break;
strcpy(&buf_0[v6], v5);
if ( ++v2 == v3 )
goto LABEL_5;
}
v8 = strlen(buf_0);
*(_DWORD *)&buf_0[v8] = 774778402;
byte_1C4[v8] = 0;
}
else
{
LABEL_5:
*(_WORD *)&buf_0[strlen(buf_0)] = 34;
}
return buf_0;
}

original_code:
const char *str_repr(const char *s, size_t n, _Bool highlighted)
{
    static char buf[50];
    const size_t max = sizeof buf - 4;
    strcpy(buf, "\"");
    for (size_t i = 0, j = 1; i < n; i++) {
        const char *p = char_repr(s[i], highlighted);
        size_t nn = strlen(p);
        if (j + nn >= max) {
            strcat(buf, "\"...");
            return buf;
        }
        strcpy(buf + j, p);
        j += nn;
    }
    strcat(buf, "\"");
    return buf;
}

canonical_original_code:
char *str_repr(char *s, unsigned long n, _Bool highlighted)
{
    static char buf[50];
    unsigned long max = sizeof buf - 4;
    strcpy(buf, "\"");
    for (unsigned long i = 0; unsigned long j = 1; i < n; i++) {
        char *p = char_repr(s[i], highlighted);
        unsigned long nn = strlen(p);
        if (j + nn >= max) {
            strcat(buf, "\"...");
            return buf;
        }
        strcpy(buf + j, p);
        j += nn;
    }
    strcat(buf, "\"");
    return buf;
}

variable_types:
s
char *

variable_types:
n
unsigned long

variable_types:
buf
char [50]

variable_types:
j
unsigned long

variable_types:
p
char *

variable_types:
nn
unsigned long


decompiled_code:
void close_serial(void)
{
int v0; // ebx

v0 = ttyfd;
if ( ttyfd != -1 )
{
tcsetattr(ttyfd, 0, &orig_termios);
close(v0);
unlock_serial_port();
ttyfd = -1;
free(tty_rawbuf);
tty_rawbuf = 0LL;
}
}

canonical_decompiled_code:
void func1(void)
{
int v0; // ebx

v0 = ttyfd;
if ( ttyfd != -1 )
{
tcsetattr(ttyfd, 0, &orig_termios);
close(v0);
unlock_serial_port();
ttyfd = -1;
free(tty_rawbuf);
tty_rawbuf = 0LL;
}
}

original_code:
void close_serial(void)
{
    if (ttyfd != -1) {
        (void)tcsetattr(ttyfd, 0, &orig_termios);
        (void)close(ttyfd);
        (void)unlock_serial_port();
        ttyfd = -1;
        free(tty_rawbuf);
        tty_rawbuf = ((void *)0);
        tty_bufsize = 0;
    }
}

canonical_original_code:
void close_serial()
{
    if (ttyfd != -1) {
        (void)tcsetattr(ttyfd, 0, &orig_termios);
        (void)close(ttyfd);
        (void)unlock_serial_port();
        ttyfd = -1;
        free(tty_rawbuf);
        tty_rawbuf = ((void *)0);
        tty_bufsize = 0;
    }
}


decompiled_code:
__int64 __fastcall eat_flow_char(char a1)
{
__int64 result; // rax
__int64 v2; // rax
unsigned __int64 v3; // rbx
__int64 v4; // rbx

result = 0LL;
if ( (a1 & 0xF0) == 240 )
{
pthread_mutex_lock(&serial_lock);
v2 = tx_received;
LOBYTE(v2) = 0;
v3 = (unsigned __int8)(16 * a1);
if ( (unsigned __int8)tx_received > v3 )
v2 += 256LL;
tx_received = v2 | v3;
v4 = (v2 | v3) - tx_sent;
tx_space = v4 + 255;
if ( v4 != -255 )
pthread_cond_signal(&serial_cond);
pthread_mutex_unlock(&serial_lock);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(char a1)
{
__int64 result; // rax
__int64 v2; // rax
unsigned __int64 v3; // rbx
__int64 v4; // rbx

result = 0LL;
if ( (a1 & 0xF0) == 240 )
{
pthread_mutex_lock(&serial_lock);
v2 = tx_received;
LOBYTE(v2) = 0;
v3 = (unsigned __int8)(16 * a1);
if ( (unsigned __int8)tx_received > v3 )
v2 += 256LL;
tx_received = v2 | v3;
v4 = (v2 | v3) - tx_sent;
tx_space = v4 + 255;
if ( v4 != -255 )
pthread_cond_signal(&serial_cond);
pthread_mutex_unlock(&serial_lock);
result = 1LL;
}
return result;
}

original_code:
static inline _Bool eat_flow_char(char c)
{
    if ((c & 0xF0) == 0xF0) {
        pthread_mutex_lock(&serial_lock);
        size_t olo = tx_received & 0xFF;
        size_t ohi = tx_received & ~0xFF;
        size_t nlo = (size_t)(c & 0x0F) << 4;
        size_t nhi = ohi;
        if (nlo < olo)
            nhi += 0x100;
        tx_received = nhi | nlo;
        tx_space = tx_received + 0xFF - tx_sent;
        if (tx_space) {
            pthread_cond_signal(&serial_cond);
        }
        pthread_mutex_unlock(&serial_lock);
        return 1;
    }
    else
        return 0;
}

canonical_original_code:
static inline _Bool eat_flow_char(char c)
{
    if ((c & 0xF0) == 0xF0) {
        pthread_mutex_lock(&serial_lock);
        unsigned long olo = tx_received & 0xFF;
        unsigned long ohi = tx_received & ~0xFF;
        unsigned long nlo = (size_t)(c & 0x0F) << 4;
        unsigned long nhi = ohi;
        if (nlo < olo)
            nhi += 0x100;
        tx_received = nhi | nlo;
        tx_space = tx_received + 0xFF - tx_sent;
        if (tx_space) {
            pthread_cond_signal(&serial_cond);
        }
        pthread_mutex_unlock(&serial_lock);
        return 1;
    }
    else
        return 0;
}

variable_types: c char

variable_types:
olo
unsigned long

variable_types:
ohi
unsigned long

variable_types:
nlo
unsigned long

variable_types:
nhi
unsigned long


decompiled_code:
__int64 __fastcall cook_chars(__int64 a1, char *a2, __int64 a3)
{
char *v3; // rbx
char *v4; // r13
__int64 v5; // r12
char v6; // bp

if ( !a3 )
return 0LL;
v3 = a2;
v4 = &a2[a3];
v5 = 0LL;
do
{
v6 = *v3;
if ( !(unsigned __int8)eat_flow_char(*v3) )
*(_BYTE *)(a1 + v5++) = v6;
++v3;
}
while ( v3 != v4 );
return v5;
}

original_code:
static size_t cook_chars(char *canon, const char *raw, size_t raw_count)
{
    size_t ncanon = 0;
    for (size_t i = 0; i < raw_count; i++) {
        char c = raw[i];
        if (!eat_flow_char(c))
            canon[ncanon++] = c;
    }
    return ncanon;
}

canonical_original_code:
static unsigned long cook_chars(char *canon, char *raw, unsigned long raw_count)
{
    unsigned long ncanon = 0;
    for (unsigned long i = 0; i < raw_count; i++) {
        char c = raw[i];
        if (!eat_flow_char(c))
            canon[ncanon++] = c;
    }
    return ncanon;
}

variable_types:
canon
char *

variable_types:
raw
char *

variable_types:
ncanon
unsigned long


decompiled_code:
__int64 init_serial()
{
atexit(close_serial);
return 0LL;
}

canonical_decompiled_code:
__int64 func4()
{
atexit(close_serial);
return 0LL;
}

original_code:
int init_serial(void)
{
    atexit(close_serial);
    return 0;
}

canonical_original_code:
int init_serial()
{
    atexit(close_serial);
    return 0;
}


decompiled_code:
__int64 open_serial()
{
int v0; // ebx
const char *v1; // rbx
int v2; // edi
unsigned int v3; // ebp
size_t v4; // rax

v0 = lock_serial_port();
if ( v0 >= 0 )
{
v1 = (const char *)get_device();
v2 = open(v1, 258, 438LL);
ttyfd = v2;
if ( v2 < 0 )
{
syslog(3, "can't open %s: %m", v1);
unlock_serial_port();
v0 = -1;
}
else if ( tcgetattr(v2, &orig_termios) )
{
syslog(3, "tcgetattr failed: %m");
close(ttyfd);
unlock_serial_port();
v0 = -1;
}
else
{
*(__m128i *)&raw_termios.c_iflag = _mm_load_si128((const __m128i *)&orig_termios);
*(__m128i *)&raw_termios.c_line = _mm_load_si128((const __m128i *)&orig_termios.c_line);
*(__m128i *)&raw_termios.c_cc[15] = _mm_load_si128((const __m128i *)&orig_termios.c_cc[15]);
*(_QWORD *)&raw_termios.c_cc[31] = *(_QWORD *)&orig_termios.c_cc[31];
raw_termios.c_ospeed = orig_termios.c_ospeed;
make_raw(&raw_termios);
v3 = ttyfd;
v0 = tcsetattr(ttyfd, 2, &raw_termios);
if ( v0 )
{
syslog(3, "tcsetattr failed: %m");
close(ttyfd);
unlock_serial_port();
v0 = -1;
}
else
{
v4 = fd_blksize(v3);
tty_rawbuf = malloc(v4);
if ( !tty_rawbuf )
{
syslog(2, "out of memory: %m");
exit(1);
}
tx_space = 0LL;
tx_received = 0LL;
tx_sent = 0LL;
}
}
}
return (unsigned int)v0;
}

canonical_decompiled_code:
__int64 func5()
{
int v0; // ebx
const char *v1; // rbx
int v2; // edi
unsigned int v3; // ebp
size_t v4; // rax

v0 = lock_serial_port();
if ( v0 >= 0 )
{
v1 = (const char *)get_device();
v2 = open(v1, 258, 438LL);
ttyfd = v2;
if ( v2 < 0 )
{
syslog(3, "can't open %s: %m", v1);
unlock_serial_port();
v0 = -1;
}
else if ( tcgetattr(v2, &orig_termios) )
{
syslog(3, "tcgetattr failed: %m");
close(ttyfd);
unlock_serial_port();
v0 = -1;
}
else
{
*(__m128i *)&raw_termios.c_iflag = _mm_load_si128((const __m128i *)&orig_termios);
*(__m128i *)&raw_termios.c_line = _mm_load_si128((const __m128i *)&orig_termios.c_line);
*(__m128i *)&raw_termios.c_cc[15] = _mm_load_si128((const __m128i *)&orig_termios.c_cc[15]);
*(_QWORD *)&raw_termios.c_cc[31] = *(_QWORD *)&orig_termios.c_cc[31];
raw_termios.c_ospeed = orig_termios.c_ospeed;
func0(&raw_termios);
v3 = ttyfd;
v0 = tcsetattr(ttyfd, 2, &raw_termios);
if ( v0 )
{
syslog(3, "tcsetattr failed: %m");
close(ttyfd);
unlock_serial_port();
v0 = -1;
}
else
{
v4 = fd_blksize(v3);
tty_rawbuf = malloc(v4);
if ( !tty_rawbuf )
{
syslog(2, "out of memory: %m");
exit(1);
}
tx_space = 0LL;
tx_received = 0LL;
tx_sent = 0LL;
}
}
}
return (unsigned int)v0;
}

original_code:
int open_serial(void)
{
    int r = lock_serial_port();
    if (r < 0)
        return r;
    const char *dev = get_device();
    ttyfd = open(dev, 02 | 0400, 0666);
    if (ttyfd < 0) {
        syslog(3, "can't open %s: %m", dev);
        (void)unlock_serial_port();
        return -1;
    }
    if (tcgetattr(ttyfd, &orig_termios)) {
        syslog(3, "tcgetattr failed: %m");
        (void)close(ttyfd);
        (void)unlock_serial_port();
        return -1;
    }
    raw_termios = orig_termios;
    make_raw(&raw_termios);
    if (tcsetattr(ttyfd, 2, &raw_termios)) {
        syslog(3, "tcsetattr failed: %m");
        (void)close(ttyfd);
        (void)unlock_serial_port();
        return -1;
    }
    tty_bufsize = fd_blksize(ttyfd);
    tty_rawbuf = malloc(tty_bufsize);
    if (!tty_rawbuf) {
        syslog(2, "out of memory: %m");
        exit(1);
    }
    tx_sent = tx_received = tx_space = 0;
    return 0;
}

canonical_original_code:
int open_serial()
{
    int r = lock_serial_port();
    if (r < 0)
        return r;
    char *dev = get_device();
    ttyfd = open(dev, 02 | 0400, 0666);
    if (ttyfd < 0) {
        syslog(3, "can't open %s: %m", dev);
        (void)unlock_serial_port();
        return -1;
    }
    if (tcgetattr(ttyfd, &orig_termios)) {
        syslog(3, "tcgetattr failed: %m");
        (void)close(ttyfd);
        (void)unlock_serial_port();
        return -1;
    }
    raw_termios = orig_termios;
    make_raw(&raw_termios);
    if (tcsetattr(ttyfd, 2, &raw_termios)) {
        syslog(3, "tcsetattr failed: %m");
        (void)close(ttyfd);
        (void)unlock_serial_port();
        return -1;
    }
    tty_bufsize = fd_blksize(ttyfd);
    tty_rawbuf = malloc(tty_bufsize);
    if (!tty_rawbuf) {
        syslog(2, "out of memory: %m");
        exit(1);
    }
    tx_sent = tx_received = tx_space = 0;
    return 0;
}

variable_types: r int

variable_types:
dev
char *


decompiled_code:
__int64 __fastcall serial_transmit(void *buf, size_t a2)
{
size_t v3; // r13
size_t i; // rax
size_t v5; // rbp
ssize_t v6; // rbx
__int64 result; // rax

v3 = a2;
pthread_mutex_lock(&serial_lock);
if ( a2 )
{
while ( 1 )
{
for ( i = tx_space; !tx_space; i = tx_space )
pthread_cond_wait(&serial_cond, &serial_lock);
v5 = v3;
if ( i <= v3 )
v5 = i;
tx_sent += v5;
tx_space = i - v5;
if ( v5 )
break;
LABEL_9:
if ( !v3 )
goto LABEL_10;
}
while ( 1 )
{
pthread_mutex_unlock(&serial_lock);
v6 = write(ttyfd, buf, v5);
pthread_mutex_lock(&serial_lock);
if ( v6 < 0 )
break;
v3 -= v6;
buf = (char *)buf + v6;
v5 -= v6;
if ( !v5 )
goto LABEL_9;
}
tx_sent -= v5;
tx_space += v5;
pthread_mutex_unlock(&serial_lock);
result = 1LL;
}
else
{
LABEL_10:
pthread_mutex_unlock(&serial_lock);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(void *buf, size_t a2)
{
size_t v3; // r13
size_t i; // rax
size_t v5; // rbp
ssize_t v6; // rbx
__int64 result; // rax

v3 = a2;
pthread_mutex_lock(&serial_lock);
if ( a2 )
{
while ( 1 )
{
for ( i = tx_space; !tx_space; i = tx_space )
pthread_cond_wait(&serial_cond, &serial_lock);
v5 = v3;
if ( i <= v3 )
v5 = i;
tx_sent += v5;
tx_space = i - v5;
if ( v5 )
break;
LABEL_9:
if ( !v3 )
goto LABEL_10;
}
while ( 1 )
{
pthread_mutex_unlock(&serial_lock);
v6 = write(ttyfd, buf, v5);
pthread_mutex_lock(&serial_lock);
if ( v6 < 0 )
break;
v3 -= v6;
buf = (char *)buf + v6;
v5 -= v6;
if ( !v5 )
goto LABEL_9;
}
tx_sent -= v5;
tx_space += v5;
pthread_mutex_unlock(&serial_lock);
result = 1LL;
}
else
{
LABEL_10:
pthread_mutex_unlock(&serial_lock);
result = 0LL;
}
return result;
}

original_code:
int serial_transmit(const char *buf, size_t size)
{
    pthread_mutex_lock(&serial_lock);
    while (size) {
        while (!tx_space)
            pthread_cond_wait(&serial_cond, &serial_lock);
        size_t ntw = tx_space;
        if (ntw > size)
            ntw = size;
        tx_sent += ntw;
        tx_space -= ntw;
        while (ntw) {
            pthread_mutex_unlock(&serial_lock);
            ssize_t nw = write(ttyfd, buf, ntw);
            pthread_mutex_lock(&serial_lock);
            if (nw < 0) {
                tx_sent -= ntw;
                tx_space += ntw;
                pthread_mutex_unlock(&serial_lock);
                return 1;
            }
            ntw -= nw;
            size -= nw;
            buf += nw;
        }
    }
    pthread_mutex_unlock(&serial_lock);
    return 0;
}

canonical_original_code:
int serial_transmit(char *buf, unsigned long size)
{
    pthread_mutex_lock(&serial_lock);
    while (size) {
        while (!tx_space)
            pthread_cond_wait(&serial_cond, &serial_lock);
        unsigned long ntw = tx_space;
        if (ntw > size)
            ntw = size;
        tx_sent += ntw;
        tx_space -= ntw;
        while (ntw) {
            pthread_mutex_unlock(&serial_lock);
            long nw = write(ttyfd, buf, ntw);
            pthread_mutex_lock(&serial_lock);
            if (nw < 0) {
                tx_sent -= ntw;
                tx_space += ntw;
                pthread_mutex_unlock(&serial_lock);
                return 1;
            }
            ntw -= nw;
            size -= nw;
            buf += nw;
        }
    }
    pthread_mutex_unlock(&serial_lock);
    return 0;
}

variable_types:
buf
char *

variable_types:
size
unsigned long

variable_types:
ntw
unsigned long

variable_types: nw long


decompiled_code:
__int64 __fastcall serial_receive(__int64 a1, size_t a2)
{
__int64 v2; // rax
__int64 v3; // rbx
__int64 v4; // rax

while ( 1 )
{
v2 = read(ttyfd, tty_rawbuf, a2);
v3 = v2;
if ( v2 < 0 )
break;
if ( !v2 )
return v3;
v4 = cook_chars(a1, (char *)tty_rawbuf, v2);
raw_tot_1 += v3;
can_tot_0 += v4;
if ( v4 )
return v4;
}
syslog(3, "tty read failed: %m");
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, size_t a2)
{
__int64 v2; // rax
__int64 v3; // rbx
__int64 v4; // rax

while ( 1 )
{
v2 = read(ttyfd, tty_rawbuf, a2);
v3 = v2;
if ( v2 < 0 )
break;
if ( !v2 )
return v3;
v4 = func3(a1, (char *)tty_rawbuf, v2);
raw_tot_1 += v3;
can_tot_0 += v4;
if ( v4 )
return v4;
}
syslog(3, "tty read failed: %m");
return v3;
}

original_code:
ssize_t serial_receive(char *buf, size_t max)
{
    while (1) {
        ssize_t nread;
        nread = read(ttyfd, tty_rawbuf, max);
        if (nread < 0) {
            syslog(3, "tty read failed: %m");
            return nread;
        } else if (nread == 0) {
            return nread;
        } else {
            size_t ncanon = cook_chars(buf, tty_rawbuf, nread);
            static size_t raw_tot = 0, can_tot = 0;
            raw_tot += nread; can_tot += ncanon;
            if (ncanon > 0)
                return ncanon;
        }
    }
}

canonical_original_code:
long serial_receive(char *buf, unsigned long max)
{
    while (1) {
        long nread;
        nread = read(ttyfd, tty_rawbuf, max);
        if (nread < 0) {
            syslog(3, "tty read failed: %m");
            return nread;
        } else if (nread == 0) {
            return nread;
        } else {
            unsigned long ncanon = cook_chars(buf, tty_rawbuf, nread);
            static unsigned long raw_tot = 0; static unsigned long can_tot = 0;
            raw_tot += nread; can_tot += ncanon;
            if (ncanon > 0)
                return ncanon;
        }
    }
}

variable_types:
max
unsigned long

variable_types: nread long


decompiled_code:
__int64 __fastcall connect_to_daemon(unsigned int a1)
{
int v1; // eax
unsigned int v2; // ebx
const char *v3; // rax
char v5[32]; // [rsp+0h] [rbp-A8h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-88h] BYREF
int v7; // [rsp+88h] [rbp-20h]
__int16 v8; // [rsp+8Ch] [rbp-1Ch]

v1 = socket(1, 1, 0);
if ( v1 < 0 )
{
perror("can't create socket");
v2 = -1;
}
else
{
v2 = v1;
memset(&addr, 0, 0x68uLL);
v7 = 0;
v8 = 0;
addr.sa_family = 1;
v3 = (const char *)get_socket_path();
strncpy(addr.sa_data, v3, 0x6CuLL);
if ( connect(v2, &addr, 0x6Eu) )
{
v2 = -1;
}
else
{
snprintf(v5, 0x14uLL, "Client Type %c\n", a1);
if ( send(v2, v5, 0xEuLL, 0x4000) < 0 )
{
perror("first message to daemon failed");
close(v2);
v2 = -1;
}
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1)
{
int v1; // eax
unsigned int v2; // ebx
const char *v3; // rax
char v5[32]; // [rsp+0h] [rbp-A8h] BYREF
struct sockaddr addr; // [rsp+20h] [rbp-88h] BYREF
int v7; // [rsp+88h] [rbp-20h]
__int16 v8; // [rsp+8Ch] [rbp-1Ch]

v1 = socket(1, 1, 0);
if ( v1 < 0 )
{
perror("can't create socket");
v2 = -1;
}
else
{
v2 = v1;
memset(&addr, 0, 0x68uLL);
v7 = 0;
v8 = 0;
addr.sa_family = 1;
v3 = (const char *)get_socket_path();
strncpy(addr.sa_data, v3, 0x6CuLL);
if ( connect(v2, &addr, 0x6Eu) )
{
v2 = -1;
}
else
{
snprintf(v5, 0x14uLL, "Client Type %c\n", a1);
if ( send(v2, v5, 0xEuLL, 0x4000) < 0 )
{
perror("first message to daemon failed");
close(v2);
v2 = -1;
}
}
}
return v2;
}

original_code:
int connect_to_daemon(client_type ct)
{
    int sock = socket(1, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("can't create socket");
        return -1;
    }
    struct sockaddr_un sun;
    memset(&sun, 0, sizeof sun);
    sun.sun_family = 1;
    strncpy(sun.sun_path, get_socket_path(), sizeof sun.sun_path);
    if (connect(sock, (const struct sockaddr *)&sun, sizeof sun))
        return -1;
    char msg0[20];
    int nb = snprintf(msg0, sizeof msg0, "Client Type %c\n", ct);
    ((nb > 0) ? (void) (0) : __assert_fail ("nb > 0", "front/thruport/client.c", 42, __extension__ __PRETTY_FUNCTION__));
    int flags = 0;
    flags += MSG_NOSIGNAL;
    ssize_t nw = send(sock, msg0, nb, flags);
    if (nw < 0) {
        perror("first message to daemon failed");
        (void)close(sock);
        return -1;
    }
    return sock;
}

canonical_original_code:
int connect_to_daemon(enum client_type ct)
{
    int sock = socket(1, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("can't create socket");
        return -1;
    }
    struct sockaddr_un sun;
    memset(&sun, 0, sizeof sun);
    sun.sun_family = 1;
    strncpy(sun.sun_path, get_socket_path(), sizeof sun.sun_path);
    if (connect(sock, (struct sockaddr *)&sun, sizeof sun))
        return -1;
    char msg0[20];
    int nb = snprintf(msg0, sizeof msg0, "Client Type %c\n", ct);
    ((nb > 0) ? (void) (0) : __assert_fail ("nb > 0", "front/thruport/client.c", 42, __extension__ __PRETTY_FUNCTION__));
    int flags = 0;
    flags += MSG_NOSIGNAL;
    long nw = send(sock, msg0, nb, flags);
    if (nw < 0) {
        perror("first message to daemon failed");
        (void)close(sock);
        return -1;
    }
    return sock;
}

variable_types: enum client_type { CT_CONTROLLER=expr, CT_SENDER=expr, CT_RECEIVER=expr, CT_SUSPENDER=expr }

variable_types: sock int

variable_types: struct sockaddr_un { unsigned short sun_family; char sun_path[108]; }

variable_types: nb int

variable_types: flags int

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


decompiled_code:
__int64 __fastcall connect_or_start_daemon(unsigned int a1)
{
int v1; // ebx
int v3; // eax

v1 = connect_to_daemon(a1);
if ( v1 < 0 )
{
v3 = *_errno_location();
if ( v3 != 2 && v3 != 111 )
goto LABEL_5;
if ( (int)spawn_daemon() < 0 )
{
perror("can't spawn daemon");
return (unsigned int)-1;
}
v1 = connect_to_daemon(a1);
if ( v1 < 0 )
LABEL_5:
perror("can't connect to daemon");
}
return (unsigned int)v1;
}

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

v1 = func0(a1);
if ( v1 < 0 )
{
v3 = *_errno_location();
if ( v3 != 2 && v3 != 111 )
goto LABEL_5;
if ( (int)spawn_daemon() < 0 )
{
perror("can't spawn daemon");
return (unsigned int)-1;
}
v1 = func0(a1);
if ( v1 < 0 )
LABEL_5:
perror("can't connect to daemon");
}
return (unsigned int)v1;
}

original_code:
int connect_or_start_daemon(client_type ct)
{
    int sock = connect_to_daemon(ct);
    if (sock < 0 && ((*__errno_location ()) == 2 || (*__errno_location ()) == 111)) {
        int pid = spawn_daemon();
        if (pid < 0) {
            perror("can't spawn daemon");
            return -1;
        }
        sock = connect_to_daemon(ct);
    }
    if (sock < 0)
        perror("can't connect to daemon");
    return sock;
}

canonical_original_code:
int connect_or_start_daemon(enum client_type ct)
{
    int sock = connect_to_daemon(ct);
    if (sock < 0 && ((*__errno_location ()) == 2 || (*__errno_location ()) == 111)) {
        int pid = spawn_daemon();
        if (pid < 0) {
            perror("can't spawn daemon");
            return -1;
        }
        sock = connect_to_daemon(ct);
    }
    if (sock < 0)
        perror("can't connect to daemon");
    return sock;
}

variable_types: pid int

user_defined_types: enum client_type { CT_CONTROLLER=expr, CT_SENDER=expr, CT_RECEIVER=expr, CT_SUSPENDER=expr }


decompiled_code:
int __fastcall create_tempfile(char *name, struct stat *buf)
{
unsigned int v2; // eax
unsigned int v3; // eax
int v4; // eax
int v5; // ebx
int result; // eax
char s[36]; // [rsp+4h] [rbp-24h] BYREF

v2 = getpid();
v3 = snprintf(s, 0xCuLL, "%10d\n", v2);
if ( v3 == 11 )
{
v4 = mkstemp(name);
v5 = v4;
if ( v4 < 0 )
{
syslog(3, "Could not create temp file %s: %m", name);
result = -1;
}
else if ( write(v4, s, 0xBuLL) == 11 )
{
if ( fchmod(v5, 0x124u) )
{
syslog(3, "fchmod failed: %m");
result = -1;
}
else if ( fstat(v5, buf) )
{
syslog(3, "fstat failed: %m");
result = -1;
}
else
{
result = close(v5);
if ( result )
{
syslog(3, "close failed: %m");
result = -1;
}
}
}
else
{
close(v5);
unlink(name);
result = -1;
}
}
else
{
syslog(3, "snprintf: expected 11, get %d: %m", v3);
result = -1;
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(char *name, struct stat *buf)
{
unsigned int v2; // eax
unsigned int v3; // eax
int v4; // eax
int v5; // ebx
int result; // eax
char s[36]; // [rsp+4h] [rbp-24h] BYREF

v2 = getpid();
v3 = snprintf(s, 0xCuLL, "%10d\n", v2);
if ( v3 == 11 )
{
v4 = mkstemp(name);
v5 = v4;
if ( v4 < 0 )
{
syslog(3, "Could not create temp file %s: %m", name);
result = -1;
}
else if ( write(v4, s, 0xBuLL) == 11 )
{
if ( fchmod(v5, 0x124u) )
{
syslog(3, "fchmod failed: %m");
result = -1;
}
else if ( fstat(v5, buf) )
{
syslog(3, "fstat failed: %m");
result = -1;
}
else
{
result = close(v5);
if ( result )
{
syslog(3, "close failed: %m");
result = -1;
}
}
}
else
{
close(v5);
unlink(name);
result = -1;
}
}
else
{
syslog(3, "snprintf: expected 11, get %d: %m", v3);
result = -1;
}
return result;
}

original_code:
static int create_tempfile(char *template, struct stat *stat_out)
{
    char pidbuf[12];
    int n = snprintf(pidbuf, sizeof pidbuf, "%10d\n", getpid());
    if (n != 11) {
        syslog(3, "snprintf: expected 11, get %d: %m", n);
        return -1;
    }
    int tmpfd = mkstemp(template);
    if (tmpfd < 0) {
        syslog(3, "Could not create temp file %s: %m", template);
        return -1;
    }
    if (write(tmpfd, pidbuf, n) != n) {
        (void)close(tmpfd);
        (void)unlink(template);
        return -1;
    }
    if (fchmod(tmpfd, 0444)) {
        syslog(3, "fchmod failed: %m");
        return -1;
    }
    if (fstat(tmpfd, stat_out)) {
        syslog(3, "fstat failed: %m");
        return -1;
    }
    if (close(tmpfd)) {
        syslog(3, "close failed: %m");
        return -1;
    }
    return 0;
}

variable_types:
template
char *

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

variable_types:
pidbuf
char [12]

variable_types: n int

variable_types: tmpfd int


decompiled_code:
__int64 lock_serial_port()
{
const char *v0; // r12
__int64 v1; // rax
const char *v2; // rbx
int v3; // er13
__int64 result; // rax
__pid_t v5; // edi
size_t v6; // rax
void *v7; // rsp
char v8[8]; // [rsp+0h] [rbp-160h] BYREF
const char *v9; // [rsp+8h] [rbp-158h]
struct stat buf; // [rsp+10h] [rbp-150h] BYREF
struct stat v11; // [rsp+A0h] [rbp-C0h] BYREF

v0 = (const char *)get_lock_dir();
v1 = get_lock_path();
if ( v1 )
{
v2 = (const char *)v1;
v9 = (const char *)get_device();
v3 = 3;
while ( 1 )
{
v6 = strlen(v0);
v7 = alloca(16 * ((v6 + 35) / 0x10));
snprintf(v8, v6 + 20, "%s/templock.XXXXXX", v0);
if ( create_tempfile(v8, &v11) < 0 )
return 0xFFFFFFFFLL;
link(v8, v2);
unlink(v8);
if ( lstat(v2, &buf) < 0 )
{
syslog(3, "can't stat %s: %m", v2);
return 0xFFFFFFFFLL;
}
if ( buf.st_dev == v11.st_dev && buf.st_ino == v11.st_ino )
break;
v5 = read_pid(v2);
if ( v5 == -1 )
{
syslog(3, "device %s is locked. No PID in lock file %s", v9, v2);
return 0xFFFFFFFFLL;
}
if ( kill(v5, 0) < 0 && *_errno_location() == 3 )
{
syslog(6, "Lock file %s is stale. Removing it.", v2);
unlink(v2);
}
if ( !--v3 )
{
syslog(3, "device %s is locked by lock file %s.", v9, v2);
return 0xFFFFFFFFLL;
}
}
result = 0LL;
}
else
{
syslog(3, "No USB serial device found");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func2()
{
const char *v0; // r12
__int64 v1; // rax
const char *v2; // rbx
int v3; // er13
__int64 result; // rax
__pid_t v5; // edi
size_t v6; // rax
void *v7; // rsp
char v8[8]; // [rsp+0h] [rbp-160h] BYREF
const char *v9; // [rsp+8h] [rbp-158h]
struct stat buf; // [rsp+10h] [rbp-150h] BYREF
struct stat v11; // [rsp+A0h] [rbp-C0h] BYREF

v0 = (const char *)get_lock_dir();
v1 = get_lock_path();
if ( v1 )
{
v2 = (const char *)v1;
v9 = (const char *)get_device();
v3 = 3;
while ( 1 )
{
v6 = strlen(v0);
v7 = alloca(16 * ((v6 + 35) / 0x10));
snprintf(v8, v6 + 20, "%s/templock.XXXXXX", v0);
if ( func0(v8, &v11) < 0 )
return 0xFFFFFFFFLL;
link(v8, v2);
unlink(v8);
if ( lstat(v2, &buf) < 0 )
{
syslog(3, "can't stat %s: %m", v2);
return 0xFFFFFFFFLL;
}
if ( buf.st_dev == v11.st_dev && buf.st_ino == v11.st_ino )
break;
v5 = func1(v2);
if ( v5 == -1 )
{
syslog(3, "device %s is locked. No PID in lock file %s", v9, v2);
return 0xFFFFFFFFLL;
}
if ( kill(v5, 0) < 0 && *_errno_location() == 3 )
{
syslog(6, "Lock file %s is stale. Removing it.", v2);
unlink(v2);
}
if ( !--v3 )
{
syslog(3, "device %s is locked by lock file %s.", v9, v2);
return 0xFFFFFFFFLL;
}
}
result = 0LL;
}
else
{
syslog(3, "No USB serial device found");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int lock_serial_port(void)
{
    const char *lck_dir = get_lock_dir();
    const char *lck_file = get_lock_path();
    if (!lck_file) {
        syslog(3, "No USB serial device found");
        return -1;
    }
    const char *device = get_device();
    struct stat temp_stat, lck_stat;
    for (int i = 0; ; i++) {
        if (i == 3) {
            syslog(3, "device %s is locked by lock file %s.",
                   device, lck_file);
            return -1;
        }
        char template[strlen(lck_dir) + 20];
        snprintf(template, sizeof template, "%s/templock.XXXXXX", lck_dir);
        if (create_tempfile(template, &temp_stat) < 0)
            return -1;
        (void)link(template, lck_file);
        (void)unlink(template);
        if (lstat(lck_file, &lck_stat) < 0) {
            syslog(3, "can't stat %s: %m", lck_file);
            return -1;
        }
        if (lck_stat.st_dev == temp_stat.st_dev &&
            lck_stat.st_ino == temp_stat.st_ino) {
            break;
        }
        pid_t lockholder_pid = read_pid(lck_file);
        if (lockholder_pid == -1) {
            syslog(3, "device %s is locked.  No PID in lock file %s",
                   device, lck_file);
            return -1;
        }
        if (kill(lockholder_pid, 0) < 0 && (*__errno_location ()) == 3) {
            syslog(6, "Lock file %s is stale.  Removing it.", lck_file);
            (void)unlink(lck_file);
        }
    }
    return 0;
}

canonical_original_code:
int lock_serial_port()
{
    char *lck_dir = get_lock_dir();
    char *lck_file = get_lock_path();
    if (!lck_file) {
        syslog(3, "No USB serial device found");
        return -1;
    }
    char *device = get_device();
    struct stat temp_stat; struct stat lck_stat;
    for (int i = 0; ; i++) {
        if (i == 3) {
            syslog(3, "device %s is locked by lock file %s.",
                   device, lck_file);
            return -1;
        }
        char template[-1];
        snprintf(template, sizeof template, "%s/templock.XXXXXX", lck_dir);
        if (create_tempfile(template, &temp_stat) < 0)
            return -1;
        (void)link(template, lck_file);
        (void)unlink(template);
        if (lstat(lck_file, &lck_stat) < 0) {
            syslog(3, "can't stat %s: %m", lck_file);
            return -1;
        }
        if (lck_stat.st_dev == temp_stat.st_dev &&
            lck_stat.st_ino == temp_stat.st_ino) {
            break;
        }
        int lockholder_pid = read_pid(lck_file);
        if (lockholder_pid == -1) {
            syslog(3, "device %s is locked.  No PID in lock file %s",
                   device, lck_file);
            return -1;
        }
        if (kill(lockholder_pid, 0) < 0 && (*__errno_location ()) == 3) {
            syslog(6, "Lock file %s is stale.  Removing it.", lck_file);
            (void)unlink(lck_file);
        }
    }
    return 0;
}

variable_types:
device
char *

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

variable_types: i int

variable_types:
template
char [-1]


decompiled_code:
__int64 unlock_serial_port()
{
const char *v0; // rax

v0 = (const char *)get_lock_path();
unlink(v0);
return 0LL;
}

canonical_decompiled_code:
__int64 func3()
{
const char *v0; // rax

v0 = (const char *)get_lock_path();
unlink(v0);
return 0LL;
}

original_code:
int unlock_serial_port(void)
{
    const char *lck_path = get_lock_path();
    (void)unlink(lck_path);
    return 0;
}

canonical_original_code:
int unlock_serial_port()
{
    char *lck_path = get_lock_path();
    (void)unlink(lck_path);
    return 0;
}


decompiled_code:
void *__fastcall susp_thread_main(void *a1)
{
int *v2; // rbx
ssize_t v3; // rax
char buf[18]; // [rsp+6h] [rbp-12h] BYREF

while ( 1 )
{
pthread_mutex_lock(&sus_lock);
v2 = (int *)suspenders;
if ( !suspenders )
break;
suspenders = (void *)*((_QWORD *)suspenders + 1);
pthread_mutex_unlock(&sus_lock);
write(*v2, &unk_2A8, 3uLL);
while ( 1 )
{
v3 = read(*v2, buf, 0xAuLL);
if ( !v3 )
break;
if ( v3 < 0 )
{
syslog(3, "suspender read: %m");
sleep(1u);
}
}
if ( close(*v2) )
syslog(3, "suspender close failed: %m");
syslog(6, "EOF on suspender");
free(v2);
}
if ( (unsigned int)resume_daemon() )
{
syslog(3, "resume failed: %m");
exit(1);
}
pthread_mutex_unlock(&sus_lock);
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func0(void *a1)
{
int *v2; // rbx
ssize_t v3; // rax
char buf[18]; // [rsp+6h] [rbp-12h] BYREF

while ( 1 )
{
pthread_mutex_lock(&sus_lock);
v2 = (int *)suspenders;
if ( !suspenders )
break;
suspenders = (void *)*((_QWORD *)suspenders + 1);
pthread_mutex_unlock(&sus_lock);
write(*v2, &unk_2A8, 3uLL);
while ( 1 )
{
v3 = read(*v2, buf, 0xAuLL);
if ( !v3 )
break;
if ( v3 < 0 )
{
syslog(3, "suspender read: %m");
sleep(1u);
}
}
if ( close(*v2) )
syslog(3, "suspender close failed: %m");
syslog(6, "EOF on suspender");
free(v2);
}
if ( (unsigned int)resume_daemon() )
{
syslog(3, "resume failed: %m");
exit(1);
}
pthread_mutex_unlock(&sus_lock);
return 0LL;
}

original_code:
void *susp_thread_main(void *closure)
{
    while (1) {
        pthread_mutex_lock(&sus_lock);
        suspender *sp = suspenders;
        if (sp)
            suspenders = sp->s_next;
        else {
            int r = resume_daemon();
            if (r) {
                syslog(3, "resume failed: %m");
                exit(1);
            }
        }
        pthread_mutex_unlock(&sus_lock);
        if (!sp)
            break;
        (void)write(sp->s_sock, "OK\n", 3);
        char junk[10];
        for (ssize_t nr = 0; (nr = read(sp->s_sock, &junk, sizeof junk)); ) {
            if (nr < 0) {
                syslog(3, "suspender read: %m");
                sleep(1);
            }
        }
        if (close(sp->s_sock))
            syslog(3, "suspender close failed: %m");
        syslog(6, "EOF on suspender");
        free(sp);
    }
    return ((void *)0);
}

canonical_original_code:
void *susp_thread_main(void *closure)
{
    while (1) {
        pthread_mutex_lock(&sus_lock);
        struct suspender *sp = suspenders;
        if (sp)
            suspenders = sp->s_next;
        else {
            int r = resume_daemon();
            if (r) {
                syslog(3, "resume failed: %m");
                exit(1);
            }
        }
        pthread_mutex_unlock(&sus_lock);
        if (!sp)
            break;
        (void)write(sp->s_sock, "OK\n", 3);
        char junk[10];
        for (long nr = 0; (nr = read(sp->s_sock, &junk, sizeof junk)); ) {
            if (nr < 0) {
                syslog(3, "suspender read: %m");
                sleep(1);
            }
        }
        if (close(sp->s_sock))
            syslog(3, "suspender close failed: %m");
        syslog(6, "EOF on suspender");
        free(sp);
    }
    return ((void *)0);
}

variable_types:
closure
void *

variable_types: struct suspender { int s_sock; struct suspender *s_next; } *

variable_types: r int

variable_types:
junk
char [10]

variable_types: nr long


decompiled_code:
__int64 create_suspension_thread()
{
int v0; // eax
unsigned int v1; // ebx
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

v0 = pthread_create(newthread, 0LL, susp_thread_main, 0LL);
if ( v0 )
{
v1 = v0;
syslog(3, "Can't create thread: %m");
}
else
{
v1 = pthread_detach(newthread[0]);
if ( v1 )
syslog(3, "Can't detach thread: %m");
}
return v1;
}

canonical_decompiled_code:
__int64 func1()
{
int v0; // eax
unsigned int v1; // ebx
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

v0 = pthread_create(newthread, 0LL, susp_thread_main, 0LL);
if ( v0 )
{
v1 = v0;
syslog(3, "Can't create thread: %m");
}
else
{
v1 = pthread_detach(newthread[0]);
if ( v1 )
syslog(3, "Can't detach thread: %m");
}
return v1;
}

original_code:
static int create_suspension_thread(void)
{
    pthread_t susp_thread;
    int r = pthread_create(&susp_thread, ((void *)0), susp_thread_main, ((void *)0));
    if (r) {
        syslog(3, "Can't create thread: %m");
        return r;
    }
    r = pthread_detach(susp_thread);
    if (r) {
        syslog(3, "Can't detach thread: %m");
        return r;
    }
    return 0;
}

canonical_original_code:
static int create_suspension_thread()
{
    unsigned long susp_thread;
    int r = pthread_create(&susp_thread, ((void *)0), susp_thread_main, ((void *)0));
    if (r) {
        syslog(3, "Can't create thread: %m");
        return r;
    }
    r = pthread_detach(susp_thread);
    if (r) {
        syslog(3, "Can't detach thread: %m");
        return r;
    }
    return 0;
}


decompiled_code:
int __fastcall instantiate_suspender_service(int fd)
{
_DWORD *v1; // rax
_QWORD *v2; // rbx
void *v3; // r12
int result; // eax

v1 = calloc(1uLL, 0x10uLL);
if ( !v1 )
{
syslog(2, "out of memory: %m");
write(fd, "thruport daemon: out of memory\n", 0x1FuLL);
exit(1);
}
v2 = v1;
*v1 = fd;
pthread_mutex_lock(&sus_lock);
v3 = suspenders;
v2[1] = suspenders;
suspenders = v2;
result = pthread_mutex_unlock(&sus_lock);
if ( !v3 )
{
if ( (unsigned int)suspend_daemon() )
{
syslog(2, "failed to suspend daemon: %m");
write(fd, "thruport: failed to suspend daemon\n", 0x23uLL);
exit(1);
}
result = create_suspension_thread();
if ( result )
{
syslog(2, "failed to suspend daemon: %m");
write(fd, "thruport: failed to suspend daemon\n", 0x23uLL);
result = close(fd);
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(int fd)
{
_DWORD *v1; // rax
_QWORD *v2; // rbx
void *v3; // r12
int result; // eax

v1 = calloc(1uLL, 0x10uLL);
if ( !v1 )
{
syslog(2, "out of memory: %m");
write(fd, "thruport daemon: out of memory\n", 0x1FuLL);
exit(1);
}
v2 = v1;
*v1 = fd;
pthread_mutex_lock(&sus_lock);
v3 = suspenders;
v2[1] = suspenders;
suspenders = v2;
result = pthread_mutex_unlock(&sus_lock);
if ( !v3 )
{
if ( (unsigned int)suspend_daemon() )
{
syslog(2, "failed to suspend daemon: %m");
write(fd, "thruport: failed to suspend daemon\n", 0x23uLL);
exit(1);
}
result = func1();
if ( result )
{
syslog(2, "failed to suspend daemon: %m");
write(fd, "thruport: failed to suspend daemon\n", 0x23uLL);
result = close(fd);
}
}
return result;
}

original_code:
void instantiate_suspender_service(int sock)
{
    suspender *sp = calloc(1, sizeof *sp);
    if (!sp) {
        syslog(2, "out of memory: %m");
        static const char oom_msg[] = "thruport daemon: out of memory\n";
        (void)write(sock, oom_msg, sizeof oom_msg - 1);
        exit(1);
    }
    sp->s_sock = sock;
    pthread_mutex_lock(&sus_lock);
    suspender *rest = suspenders;
    sp->s_next = rest;
    suspenders = sp;
    pthread_mutex_unlock(&sus_lock);
    if (!rest) {
        int r = suspend_daemon();
        if (r) {
            syslog(2, "failed to suspend daemon: %m");
            static const char msg[] = "thruport: failed to suspend daemon\n";
            (void)write(sock, msg, sizeof msg - 1);
            exit(1);
        }
        r = create_suspension_thread();
        if (r) {
            syslog(2, "failed to suspend daemon: %m");
            static const char msg[] = "thruport: failed to suspend daemon\n";
            (void)write(sock, msg, sizeof msg - 1);
            (void)close(sock);
        }
    }
}

canonical_original_code:
void instantiate_suspender_service(int sock)
{
    struct suspender *sp = calloc(1, sizeof *sp);
    if (!sp) {
        syslog(2, "out of memory: %m");
        static char oom_msg[] = "thruport daemon: out of memory\n";
        (void)write(sock, oom_msg, sizeof oom_msg - 1);
        exit(1);
    }
    sp->s_sock = sock;
    pthread_mutex_lock(&sus_lock);
    struct suspender *rest = suspenders;
    sp->s_next = rest;
    suspenders = sp;
    pthread_mutex_unlock(&sus_lock);
    if (!rest) {
        int r = suspend_daemon();
        if (r) {
            syslog(2, "failed to suspend daemon: %m");
            static char msg[] = "thruport: failed to suspend daemon\n";
            (void)write(sock, msg, sizeof msg - 1);
            exit(1);
        }
        r = create_suspension_thread();
        if (r) {
            syslog(2, "failed to suspend daemon: %m");
            static char msg[] = "thruport: failed to suspend daemon\n";
            (void)write(sock, msg, sizeof msg - 1);
            (void)close(sock);
        }
    }
}

variable_types: sock int

variable_types:
msg
char []

user_defined_types: struct suspender { int s_sock; struct suspender *s_next; }


decompiled_code:
char *alloc_receiver()
{
__int64 v0; // rbx
__int64 v2; // rbp
void *v3; // rax

v0 = receiver_count;
if ( receiver_count >= (unsigned __int64)receiver_max )
{
v2 = 10LL;
if ( (unsigned __int64)(2 * receiver_max) >= 0xA )
v2 = 2 * receiver_max;
v3 = realloc(receivers, 4 * v2);
if ( !v3 )
{
syslog(2, "out of memory: %m");
exit(1);
}
receivers = v3;
receiver_max = v2;
}
receiver_count = v0 + 1;
return (char *)receivers + 4 * v0;
}

canonical_decompiled_code:
char *func0()
{
__int64 v0; // rbx
__int64 v2; // rbp
void *v3; // rax

v0 = receiver_count;
if ( receiver_count >= (unsigned __int64)receiver_max )
{
v2 = 10LL;
if ( (unsigned __int64)(2 * receiver_max) >= 0xA )
v2 = 2 * receiver_max;
v3 = realloc(receivers, 4 * v2);
if ( !v3 )
{
syslog(2, "out of memory: %m");
exit(1);
}
receivers = v3;
receiver_max = v2;
}
receiver_count = v0 + 1;
return (char *)receivers + 4 * v0;
}

original_code:
static receiver *alloc_receiver(void)
{
    if (receiver_count >= receiver_max) {
        size_t new_max = receiver_max * 2;
        if (new_max < 10)
            new_max = 10;
        receiver *p = realloc(receivers, new_max * sizeof *p);
        if (!p) {
            syslog(2, "out of memory: %m");
            exit(1);
        }
        receivers = p;
        receiver_max = new_max;
    }
    return receivers + receiver_count++;
}

canonical_original_code:
static struct receiver *alloc_receiver()
{
    if (receiver_count >= receiver_max) {
        unsigned long new_max = receiver_max * 2;
        if (new_max < 10)
            new_max = 10;
        struct receiver *p = realloc(receivers, new_max * sizeof *p);
        if (!p) {
            syslog(2, "out of memory: %m");
            exit(1);
        }
        receivers = p;
        receiver_max = new_max;
    }
    return receivers + receiver_count++;
}

variable_types:
p
struct receiver { int r_fd; } *

return_type: struct receiver { int r_fd; } *


decompiled_code:
__int64 __fastcall send_to_receiver(int *a1, char *a2, size_t a3)
{
size_t v4; // rbp
ssize_t v5; // rax
unsigned int v6; // ebx

v4 = a3;
if ( !a3 )
return 0LL;
while ( 1 )
{
v5 = send(*a1, a2, v4, 16448);
v6 = v5;
if ( v5 < 0 )
break;
a2 += v5;
v4 -= v5;
if ( !v4 )
return 0LL;
}
syslog(4, "receiver send failed: %m");
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func1(int *a1, char *a2, size_t a3)
{
size_t v4; // rbp
ssize_t v5; // rax
unsigned int v6; // ebx

v4 = a3;
if ( !a3 )
return 0LL;
while ( 1 )
{
v5 = send(*a1, a2, v4, 16448);
v6 = v5;
if ( v5 < 0 )
break;
a2 += v5;
v4 -= v5;
if ( !v4 )
return 0LL;
}
syslog(4, "receiver send failed: %m");
return v6;
}

original_code:
static int send_to_receiver(receiver *r, const char *data, size_t count)
{
    while (count) {
        int flags = MSG_DONTWAIT;
        flags |= MSG_NOSIGNAL;
        ssize_t nw = send(r->r_fd, data, count, flags);
        if (nw < 0) {
            syslog(4, "receiver send failed: %m");
            return nw;
        }
        data += nw;
        count -= nw;
    }
    return 0;
}

canonical_original_code:
static int send_to_receiver(struct receiver *r, char *data, unsigned long count)
{
    while (count) {
        int flags = MSG_DONTWAIT;
        flags |= MSG_NOSIGNAL;
        long nw = send(r->r_fd, data, count, flags);
        if (nw < 0) {
            syslog(4, "receiver send failed: %m");
            return nw;
        }
        data += nw;
        count -= nw;
    }
    return 0;
}

variable_types:
r
struct receiver { int r_fd; } *

variable_types:
data
char *

variable_types:
count
unsigned long

variable_types: flags int

variable_types: nw long


decompiled_code:
void *__fastcall free_receiver(__int64 a1)
{
unsigned __int64 v1; // rax
__int64 v2; // rdx

v1 = (a1 - (__int64)receivers) >> 2;
v2 = receiver_count;
if ( receiver_count <= v1 )
_assert_fail("0 <= i && i < receiver_count", "front/thruport/receiver_service.c", 0x2Du, "free_receiver");
--receiver_count;
return memmove((void *)a1, (const void *)(a1 + 4), 4 * (v2 - 1 - v1));
}

canonical_decompiled_code:
void *__fastcall func2(__int64 a1)
{
unsigned __int64 v1; // rax
__int64 v2; // rdx

v1 = (a1 - (__int64)receivers) >> 2;
v2 = receiver_count;
if ( receiver_count <= v1 )
_assert_fail("0 <= i && i < receiver_count", "front/thruport/receiver_service.c", 0x2Du, "free_receiver");
--receiver_count;
return memmove((void *)a1, (const void *)(a1 + 4), 4 * (v2 - 1 - v1));
}

original_code:
static void free_receiver(receiver *r)
{
    size_t i = r - receivers;
    ((0 <= i && i < receiver_count) ? (void) (0) : __assert_fail ("0 <= i && i < receiver_count", "front/thruport/receiver_service.c", 45, __extension__ __PRETTY_FUNCTION__));
    memmove(r, r + 1, (--receiver_count - i) * sizeof *r);
}

canonical_original_code:
static void free_receiver(struct receiver *r)
{
    unsigned long i = r - receivers;
    ((0 <= i && i < receiver_count) ? (void) (0) : __assert_fail ("0 <= i && i < receiver_count", "front/thruport/receiver_service.c", 45, __extension__ __PRETTY_FUNCTION__));
    memmove(r, r + 1, (--receiver_count - i) * sizeof *r);
}

variable_types:
i
unsigned long


decompiled_code:
char *__fastcall instantiate_receiver_service(int a1)
{
char *result; // rax

result = alloc_receiver();
*(_DWORD *)result = a1;
return result;
}

canonical_decompiled_code:
char *__fastcall func3(int a1)
{
char *result; // rax

result = func0();
*(_DWORD *)result = a1;
return result;
}

original_code:
void instantiate_receiver_service(int sock)
{
    receiver *r = alloc_receiver();
    r->r_fd = sock;
}

canonical_original_code:
void instantiate_receiver_service(int sock)
{
    struct receiver *r = alloc_receiver();
    r->r_fd = sock;
}


decompiled_code:
int *__fastcall broadcast_to_receivers(char *a1, size_t a2)
{
int *v2; // rbx
int *result; // rax

v2 = (int *)receivers;
result = (int *)((char *)receivers + 4 * receiver_count);
if ( receivers < result )
{
do
{
if ( (unsigned int)send_to_receiver(v2, a1, a2) )
{
close(*v2);
free_receiver((__int64)v2);
}
else
{
++v2;
}
result = (int *)((char *)receivers + 4 * receiver_count);
}
while ( v2 < result );
}
return result;
}

canonical_decompiled_code:
int *__fastcall func4(char *a1, size_t a2)
{
int *v2; // rbx
int *result; // rax

v2 = (int *)receivers;
result = (int *)((char *)receivers + 4 * receiver_count);
if ( receivers < result )
{
do
{
if ( (unsigned int)func1(v2, a1, a2) )
{
close(*v2);
func2((__int64)v2);
}
else
{
++v2;
}
result = (int *)((char *)receivers + 4 * receiver_count);
}
while ( v2 < result );
}
return result;
}

original_code:
void broadcast_to_receivers(const char *data, size_t count)
{
    receiver *r = receivers;
    while (r < receivers + receiver_count) {
        if (send_to_receiver(r, data, count)) {
            (void)close(r->r_fd);
            free_receiver(r);
        } else
            r++;
    }
}

canonical_original_code:
void broadcast_to_receivers(char *data, unsigned long count)
{
    struct receiver *r = receivers;
    while (r < receivers + receiver_count) {
        if (send_to_receiver(r, data, count)) {
            (void)close(r->r_fd);
            free_receiver(r);
        } else
            r++;
    }
}


unlock

decompiled_code:
int __fastcall unlock(pthread_mutex_t *a1)
{
return pthread_mutex_unlock(a1);
}

canonical_decompiled_code:
int __fastcall func0(pthread_mutex_t *a1)
{
return pthread_mutex_unlock(a1);
}

original_code:
static void unlock(void *arg)
{
    pthread_mutex_t *mutex = arg;
    pthread_mutex_unlock(mutex);
}

canonical_original_code:
static void unlock(void *arg)
{
    union pthread_mutex_t *mutex = arg;
    pthread_mutex_unlock(mutex);
}

variable_types:
arg
void *

variable_types: union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } *

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


decompiled_code:
int __fastcall disconnect_sender(const char *a1)
{
pthread_mutex_lock(&sslock);
if ( sender_active )
{
if ( a1 )
fprintf(sender_fout, "thruport: %s\n", a1);
fclose(sender_fout);
close(sender_sock);
sender_sock = -1;
sender_fout = 0LL;
sender_active = 0;
}
return pthread_mutex_unlock(&sslock);
}

canonical_decompiled_code:
int __fastcall func3(const char *a1)
{
pthread_mutex_lock(&sslock);
if ( sender_active )
{
if ( a1 )
fprintf(sender_fout, "thruport: %s\n", a1);
fclose(sender_fout);
close(sender_sock);
sender_sock = -1;
sender_fout = 0LL;
sender_active = 0;
}
return pthread_mutex_unlock(&sslock);
}

original_code:
void disconnect_sender(const char *reason)
{
    pthread_mutex_lock(&sslock);
    if (sender_active) {
        if (reason)
            fprintf(sender_fout, "thruport: %s\n", reason);
        fclose(sender_fout);
        close(sender_sock);
        sender_sock = -1;
        sender_fout = ((void *)0);
        sender_active = 0;
    }
    pthread_mutex_unlock(&sslock);
}

canonical_original_code:
void disconnect_sender(char *reason)
{
    pthread_mutex_lock(&sslock);
    if (sender_active) {
        if (reason)
            fprintf(sender_fout, "thruport: %s\n", reason);
        fclose(sender_fout);
        close(sender_sock);
        sender_sock = -1;
        sender_fout = ((void *)0);
        sender_active = 0;
    }
    pthread_mutex_unlock(&sslock);
}

variable_types:
reason
char *


decompiled_code:
__int64 await_sender_socket()
{
unsigned int v0; // ebx
__pthread_unwind_buf_t v2; // [rsp+0h] [rbp-78h] BYREF

pthread_mutex_lock(&sslock);
if ( _sigsetjmp((struct __jmp_buf_tag *)&v2, 0) )
{
unlock(&sslock);
_pthread_unwind_next(&v2);
}
_pthread_register_cancel(&v2);
while ( !sender_active )
pthread_cond_wait(&sscond, &sslock);
v0 = sender_sock;
_pthread_unregister_cancel(&v2);
unlock(&sslock);
return v0;
}

canonical_decompiled_code:
__int64 func4()
{
unsigned int v0; // ebx
__pthread_unwind_buf_t v2; // [rsp+0h] [rbp-78h] BYREF

pthread_mutex_lock(&sslock);
if ( _sigsetjmp((struct __jmp_buf_tag *)&v2, 0) )
{
func0(&sslock);
_pthread_unwind_next(&v2);
}
_pthread_register_cancel(&v2);
while ( !sender_active )
pthread_cond_wait(&sscond, &sslock);
v0 = sender_sock;
_pthread_unregister_cancel(&v2);
func0(&sslock);
return v0;
}

original_code:
int await_sender_socket(void)
{
    int sock;
    pthread_mutex_lock(&sslock);
    do { __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine) (void *) = (unlock); void *__cancel_arg = (&sslock); int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf, 0); if (__builtin_expect ((__not_first_call), 0)) { __cancel_routine (__cancel_arg); __pthread_unwind_next (&__cancel_buf); } __pthread_register_cancel (&__cancel_buf); do {; {
        while (!sender_active)
            pthread_cond_wait(&sscond, &sslock);
        sock = sender_sock;
    } do { } while (0); } while (0); __pthread_unregister_cancel (&__cancel_buf); if (1) __cancel_routine (__cancel_arg); } while (0);
    return sock;
}

canonical_original_code:
int await_sender_socket()
{
    int sock;
    pthread_mutex_lock(&sslock);
    do { struct __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine)(void *) = (unlock); void *__cancel_arg = (&sslock); int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf, 0); if (__builtin_expect ((__not_first_call), 0)) { __cancel_routine (__cancel_arg); __pthread_unwind_next (&__cancel_buf); } __pthread_register_cancel (&__cancel_buf); do {; {
        while (!sender_active)
            pthread_cond_wait(&sscond, &sslock);
        sock = sender_sock;
    } do { } while (0); } while (0); __pthread_unregister_cancel (&__cancel_buf); if (1) __cancel_routine (__cancel_arg); } while (0);
    return sock;
}

variable_types: struct __pthread_unwind_buf_t { struct { long __cancel_jmp_buf[8]; int __mask_was_saved; } __cancel_jmp_buf[1]; void *__pad[4]; }


decompiled_code:
int debug_printf(char *path, unsigned int a2, const char *a3, const char *a4, ...)
{
char *v6; // rax
gcc_va_list arg; // [rsp+8h] [rbp-F0h] BYREF

pthread_mutex_lock(&dbg_lock);
v6 = _xpg_basename(path);
fprintf(stderr, "%s:%d %s", v6, a2, a3);
if ( a4 )
{
va_start(arg, a4);
fwrite(": ", 1uLL, 2uLL, stderr);
vfprintf(stderr, a4, arg);
}
putc(10, stderr);
fflush(stderr);
return pthread_mutex_unlock(&dbg_lock);
}

canonical_decompiled_code:
int func0(char *path, unsigned int a2, const char *a3, const char *a4, ...)
{
char *v6; // rax
gcc_va_list arg; // [rsp+8h] [rbp-F0h] BYREF

pthread_mutex_lock(&dbg_lock);
v6 = _xpg_basename(path);
fprintf(stderr, "%s:%d %s", v6, a2, a3);
if ( a4 )
{
va_start(arg, a4);
fwrite(": ", 1uLL, 2uLL, stderr);
vfprintf(stderr, a4, arg);
}
putc(10, stderr);
fflush(stderr);
return pthread_mutex_unlock(&dbg_lock);
}

original_code:
extern void debug_printf(const char *file, int line, const char *func,
                         const char *fmt, ...)
{
    pthread_mutex_lock(&dbg_lock);
    fprintf(stderr, "%s:%d %s", __xpg_basename((char *)file), line, func);
    if (fmt) {
        va_list ap;
        __builtin_va_start(ap,fmt);
        fputs(": ", stderr);
        vfprintf(stderr, fmt, ap);
        __builtin_va_end(ap);
    }
    putc('\n', stderr);
    fflush(stderr);
    pthread_mutex_unlock(&dbg_lock);
}

canonical_original_code:
extern void debug_printf(char *file, int line, char *func, char *fmt, ...)
{
    pthread_mutex_lock(&dbg_lock);
    fprintf(stderr, "%s:%d %s", __xpg_basename((char *)file), line, func);
    if (fmt) {
        __builtin_va_list ap;
        __builtin_va_start(ap,fmt);
        fputs(": ", stderr);
        vfprintf(stderr, fmt, ap);
        __builtin_va_end(ap);
    }
    putc('\n', stderr);
    fflush(stderr);
    pthread_mutex_unlock(&dbg_lock);
}

variable_types:
file
char *

variable_types: line int

variable_types:
func
char *

variable_types:
fmt
char *


spawn

decompiled_code:
__int64 __fastcall spawn(char **argv)
{
int v1; // eax
unsigned int v2; // edx
const char *v3; // rbp
char *v4; // rax
int stat_loc; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = fork();
if ( v1 < 0 )
{
perror("fork failed: %m");
exit(1);
}
if ( v1 <= 0 )
{
execvp(*argv, argv);
perror("execvp");
v2 = 1;
}
else if ( waitpid(v1, &stat_loc, 0) < 0 )
{
perror("waitpid");
v2 = -1;
}
else
{
v2 = BYTE1(stat_loc);
if ( !__OFSUB__((stat_loc & 0x7F) + 1, 1) && (stat_loc & 0x7F) != 0 )
{
v3 = " (core dumped)";
if ( (stat_loc & 0x80u) == 0 )
v3 = (const char *)&unk_18D;
v4 = strsignal(stat_loc & 0x7F);
fprintf(stderr, "%s: %s%s\n", *argv, v4, v3);
v2 = -1;
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func0(char **argv)
{
int v1; // eax
unsigned int v2; // edx
const char *v3; // rbp
char *v4; // rax
int stat_loc; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = fork();
if ( v1 < 0 )
{
perror("fork failed: %m");
exit(1);
}
if ( v1 <= 0 )
{
execvp(*argv, argv);
perror("execvp");
v2 = 1;
}
else if ( waitpid(v1, &stat_loc, 0) < 0 )
{
perror("waitpid");
v2 = -1;
}
else
{
v2 = BYTE1(stat_loc);
if ( !__OFSUB__((stat_loc & 0x7F) + 1, 1) && (stat_loc & 0x7F) != 0 )
{
v3 = " (core dumped)";
if ( (stat_loc & 0x80u) == 0 )
v3 = (const char *)&unk_18D;
v4 = strsignal(stat_loc & 0x7F);
fprintf(stderr, "%s: %s%s\n", *argv, v4, v3);
v2 = -1;
}
}
return v2;
}

original_code:
static int spawn(const char **argv)
{
    pid_t child = fork();
    if (child < 0) {
        perror("fork failed: %m");
        exit(1);
    }
    if (child > 0) {
        int status;
        pid_t pid = waitpid(child, &status, 0);
        if (pid < 0) {
            perror("waitpid");
            return -1;
        }
        if ((((signed char) (((status) & 0x7f) + 1) >> 1) > 0)) {
            fprintf(stderr, "%s: %s%s\n",
                    argv[0],
                    strsignal(((status) & 0x7f)),
                    ((status) & 0x80) ? " (core dumped)" : "");
            return -1;
        }
        return (((status) & 0xff00) >> 8);
    }
    execvp(argv[0], (char *const *)argv);
    perror("execvp");
    return 1;
}

canonical_original_code:
static int spawn(char **argv)
{
    int child = fork();
    if (child < 0) {
        perror("fork failed: %m");
        exit(1);
    }
    if (child > 0) {
        int status;
        int pid = waitpid(child, &status, 0);
        if (pid < 0) {
            perror("waitpid");
            return -1;
        }
        if ((((char) (((status) & 0x7f) + 1) >> 1) > 0)) {
            fprintf(stderr, "%s: %s%s\n",
                    argv[0],
                    strsignal(((status) & 0x7f)),
                    ((status) & 0x80) ? " (core dumped)" : "");
            return -1;
        }
        return (((status) & 0xff00) >> 8);
    }
    execvp(argv[0], (char **)argv);
    perror("execvp");
    return 1;
}

variable_types:
argv
char **

variable_types: child int

variable_types: status int

variable_types: pid int


decompiled_code:
__int64 __fastcall be_suspender(char **argv)
{
int v2; // eax
int v3; // eax
unsigned int v4; // ebx
char v6[120]; // [rsp+0h] [rbp-78h] BYREF

v2 = connect_to_daemon(90LL);
if ( v2 >= 0 )
{
if ( read(v2, v6, 0x64uLL) < 0 )
{
perror("daemon not responding");
v4 = 1;
}
else if ( !memcmp(v6, "OK\n", 3uLL) )
{
v4 = spawn(argv);
}
else
{
fputs(v6, stderr);
v4 = 1;
}
}
else
{
v3 = *_errno_location();
if ( v3 == 2 || v3 == 111 )
{
lock_serial_port();
v4 = spawn(argv);
unlock_serial_port();
}
else
{
perror("can't connect to daemon");
v4 = 1;
}
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func1(char **argv)
{
int v2; // eax
int v3; // eax
unsigned int v4; // ebx
char v6[120]; // [rsp+0h] [rbp-78h] BYREF

v2 = connect_to_daemon(90LL);
if ( v2 >= 0 )
{
if ( read(v2, v6, 0x64uLL) < 0 )
{
perror("daemon not responding");
v4 = 1;
}
else if ( !memcmp(v6, "OK\n", 3uLL) )
{
v4 = func0(argv);
}
else
{
fputs(v6, stderr);
v4 = 1;
}
}
else
{
v3 = *_errno_location();
if ( v3 == 2 || v3 == 111 )
{
lock_serial_port();
v4 = func0(argv);
unlock_serial_port();
}
else
{
perror("can't connect to daemon");
v4 = 1;
}
}
return v4;
}

original_code:
int be_suspender(const char **argv)
{
    int sock = connect_to_daemon(CT_SUSPENDER);
    if (sock < 0) {
        if ((*__errno_location ()) == 2 || (*__errno_location ()) == 111) {
            lock_serial_port();
            int status = spawn(argv);
            unlock_serial_port();
            return status;
        }
        perror("can't connect to daemon");
        return 1;
    }
    char response[100];
    ssize_t nr = read(sock, response, sizeof response);
    if (nr < 0) {
        perror("daemon not responding");
        return 1;
    }
    if (strncmp(response, "OK\n", 3) != 0) {
        fputs(response, stderr);
        return 1;
    }
    return spawn(argv);
}

canonical_original_code:
int be_suspender(char **argv)
{
    int sock = connect_to_daemon(CT_SUSPENDER);
    if (sock < 0) {
        if ((*__errno_location ()) == 2 || (*__errno_location ()) == 111) {
            lock_serial_port();
            int status = spawn(argv);
            unlock_serial_port();
            return status;
        }
        perror("can't connect to daemon");
        return 1;
    }
    char response[100];
    long nr = read(sock, response, sizeof response);
    if (nr < 0) {
        perror("daemon not responding");
        return 1;
    }
    if (strncmp(response, "OK\n", 3) != 0) {
        fputs(response, stderr);
        return 1;
    }
    return spawn(argv);
}

variable_types: sock int

variable_types:
response
char [100]

variable_types: nr long


stripslash

repo: kcburge/pptpclient

decompiled_code:
const char *__fastcall stripslash(const char *a1)
{
int v1; // eax
int v2; // ecx
__int64 v3; // rdx
const char *v4; // rax
__int64 v5; // rdx

v1 = strlen(a1);
if ( v1 > 1 )
{
v2 = v1;
v3 = v1;
v4 = &a1[v1 - 1];
v5 = (__int64)&a1[v3 - 2 - (unsigned int)(v2 - 2)];
do
{
if ( *v4 != 47 )
break;
*v4-- = 0;
}
while ( v4 != (const char *)v5 );
}
return a1;
}

canonical_decompiled_code:
const char *__fastcall func0(const char *a1)
{
int v1; // eax
int v2; // ecx
__int64 v3; // rdx
const char *v4; // rax
__int64 v5; // rdx

v1 = strlen(a1);
if ( v1 > 1 )
{
v2 = v1;
v3 = v1;
v4 = &a1[v1 - 1];
v5 = (__int64)&a1[v3 - 2 - (unsigned int)(v2 - 2)];
do
{
if ( *v4 != 47 )
break;
*v4-- = 0;
}
while ( v4 != (const char *)v5 );
}
return a1;
}

original_code:
char *stripslash(char *pathname) {
    int len = strlen(pathname);
    while (len > 1 && pathname[len - 1] == '/')
        pathname[--len] = '\0';
    return pathname;
}

variable_types:
pathname
char *

variable_types: len int


basenamex

decompiled_code:
char *__fastcall basenamex(const char *a1)
{
char *v1; // rbx
const char *v2; // rax
char *v3; // rax
char *v4; // rbp

v1 = strdup(a1);
v2 = stripslash(v1);
v3 = strrchr(v2, 47);
v4 = v1;
if ( v3 )
{
v4 = strdup(v3 + 1);
free(v1);
}
return v4;
}

canonical_decompiled_code:
char *__fastcall func1(const char *a1)
{
char *v1; // rbx
const char *v2; // rax
char *v3; // rax
char *v4; // rbp

v1 = strdup(a1);
v2 = func0(v1);
v3 = strrchr(v2, 47);
v4 = v1;
if ( v3 )
{
v4 = strdup(v3 + 1);
free(v1);
}
return v4;
}

original_code:
char *basenamex(char *pathname)
{
    char *dup = strdup(pathname);
    char *ptr = strrchr(stripslash(dup), '/');
    if (ptr == ((void *)0)) return dup;
    ptr = strdup(ptr+1);
    free(dup);
    return ptr;
}

variable_types:
dup
char *

variable_types:
ptr
char *


dirname

decompiled_code:
char *__fastcall dirname(const char *a1)
{
char *v1; // rbx
const char *v2; // rax
char *v3; // rax

v1 = strdup(a1);
v2 = stripslash(v1);
v3 = strrchr(v2, 47);
if ( v3 )
{
if ( v1 == v3 )
v3 += *v3 == 47;
*v3 = 0;
}
else
{
free(v1);
v1 = strdup(".");
}
return v1;
}

canonical_decompiled_code:
char *__fastcall func2(const char *a1)
{
char *v1; // rbx
const char *v2; // rax
char *v3; // rax

v1 = strdup(a1);
v2 = func0(v1);
v3 = strrchr(v2, 47);
if ( v3 )
{
if ( v1 == v3 )
v3 += *v3 == 47;
*v3 = 0;
}
else
{
free(v1);
v1 = strdup(".");
}
return v1;
}

original_code:
char *dirname(char *pathname)
{
    char *dup = strdup(pathname);
    char *ptr = strrchr(stripslash(dup), '/');
    if (ptr == ((void *)0)) { free(dup); return strdup("."); }
    if (ptr == dup && dup[0] == '/') ptr++;
    *ptr = '\0';
    return dup;
}


decompiled_code:
__int64 __fastcall make_valid_path(const char *a1, __mode_t a2)
{
char *v2; // rax
char *v3; // rbx
unsigned int v4; // ebp
char *v6; // r13
struct stat v7; // [rsp+0h] [rbp-B8h] BYREF

v2 = strdup(a1);
v3 = (char *)stripslash(v2);
if ( stat(v3, &v7) )
{
v6 = dirname(v3);
v4 = make_valid_path(v6, a2);
if ( v4 )
v4 = mkdir(v3, a2) >= 0;
if ( v6 )
free(v6);
}
else
{
v4 = (v7.st_mode & 0xF000) == 0x4000;
}
free(v3);
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func3(const char *a1, __mode_t a2)
{
char *v2; // rax
char *v3; // rbx
unsigned int v4; // ebp
char *v6; // r13
struct stat v7; // [rsp+0h] [rbp-B8h] BYREF

v2 = strdup(a1);
v3 = (char *)func0(v2);
if ( stat(v3, &v7) )
{
v6 = func2(v3);
v4 = func3(v6, a2);
if ( v4 )
v4 = mkdir(v3, a2) >= 0;
if ( v6 )
free(v6);
}
else
{
v4 = (v7.st_mode & 0xF000) == 0x4000;
}
free(v3);
return v4;
}

original_code:
int make_valid_path(char *dir, mode_t mode)
{
    struct stat st;
    char *tmp = ((void *)0), *path = stripslash(strdup(dir));
    int retval;
    if (stat(path, &st) == 0) {
        if (((((st.st_mode)) & 0170000) == (0040000))) { retval = 1; goto end; }
        else { retval = 0; goto end; }
    }
    if (!make_valid_path(tmp = dirname(path), mode)) { retval = 0; goto end; }
    if (mkdir(path, mode) < 0) { retval = 0; goto end; }
    retval = 1;
end:
    if (tmp != ((void *)0)) free(tmp);
    if (path != ((void *)0)) free(path);
    return retval;
}

canonical_original_code:
int make_valid_path(char *dir, unsigned int mode)
{
    struct stat st;
    char *tmp = ((void *)0); char *path = stripslash(strdup(dir));
    int retval;
    if (stat(path, &st) == 0) {
        if (((((st.st_mode)) & 0170000) == (0040000))) { retval = 1; goto end; }
        else { retval = 0; goto end; }
    }
    if (!make_valid_path(tmp = dirname(path), mode)) { retval = 0; goto end; }
    if (mkdir(path, mode) < 0) { retval = 0; goto end; }
    retval = 1;
end:
    if (tmp != ((void *)0)) free(tmp);
    if (path != ((void *)0)) free(path);
    return retval;
}

variable_types:
dir
char *

variable_types:
mode
unsigned int

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

variable_types:
tmp
char *

variable_types:
path
char *

variable_types: retval int


decompiled_code:
void __fastcall do_nothing(int a1)
{
signaled = a1;
}

canonical_decompiled_code:
void __fastcall func0(int a1)
{
signaled = a1;
}

original_code:
void do_nothing(int sig)
{
    signaled = sig;
}

variable_types: sig int


sigstats

decompiled_code:
void sigstats()
{
syslog(5, "GRE statistics:\n");
syslog(5, "rx accepted = %d\n", stats[0]);
syslog(5, "rx lost = %d\n", stats[1]);
syslog(5, "rx under win = %d\n", stats[2]);
syslog(5, "rx over win = %d\n", stats[3]);
syslog(5, "rx buffered = %d\n", stats[4]);
syslog(5, "rx OS errors = %d\n", stats[5]);
syslog(5, "rx truncated = %d\n", stats[6]);
syslog(5, "rx invalid = %d\n", stats[7]);
syslog(5, "rx acks = %d\n", stats[8]);
syslog(5, "tx sent = %d\n", stats[9]);
syslog(5, "tx failed = %d\n", stats[10]);
syslog(5, "tx short = %d\n", stats[11]);
syslog(5, "tx acks = %d\n", stats[12]);
syslog(5, "tx oversize = %d\n", stats[13]);
syslog(5, "round trip = %d usecs\n", stats[18]);
}

canonical_decompiled_code:
void func2()
{
syslog(5, "GRE statistics:\n");
syslog(5, "rx accepted = %d\n", stats[0]);
syslog(5, "rx lost = %d\n", stats[1]);
syslog(5, "rx under win = %d\n", stats[2]);
syslog(5, "rx over win = %d\n", stats[3]);
syslog(5, "rx buffered = %d\n", stats[4]);
syslog(5, "rx OS errors = %d\n", stats[5]);
syslog(5, "rx truncated = %d\n", stats[6]);
syslog(5, "rx invalid = %d\n", stats[7]);
syslog(5, "rx acks = %d\n", stats[8]);
syslog(5, "tx sent = %d\n", stats[9]);
syslog(5, "tx failed = %d\n", stats[10]);
syslog(5, "tx short = %d\n", stats[11]);
syslog(5, "tx acks = %d\n", stats[12]);
syslog(5, "tx oversize = %d\n", stats[13]);
syslog(5, "round trip = %d usecs\n", stats[18]);
}

original_code:
void sigstats(int sig)
{
    syslog(5, "GRE statistics:\n");
    syslog(5, "rx accepted  = %d" "\n", stats .rx_accepted);
    syslog(5, "rx lost      = %d" "\n", stats .rx_lost);
    syslog(5, "rx under win = %d" "\n", stats .rx_underwin);
    syslog(5, "rx over  win = %d" "\n", stats .rx_overwin);
    syslog(5, "rx buffered  = %d" "\n", stats .rx_buffered);
    syslog(5, "rx OS errors = %d" "\n", stats .rx_errors);
    syslog(5, "rx truncated = %d" "\n", stats .rx_truncated);
    syslog(5, "rx invalid   = %d" "\n", stats .rx_invalid);
    syslog(5, "rx acks      = %d" "\n", stats .rx_acks);
    syslog(5, "tx sent      = %d" "\n", stats .tx_sent);
    syslog(5, "tx failed    = %d" "\n", stats .tx_failed);
    syslog(5, "tx short     = %d" "\n", stats .tx_short);
    syslog(5, "tx acks      = %d" "\n", stats .tx_acks);
    syslog(5, "tx oversize  = %d" "\n", stats .tx_oversize);
    syslog(5, "round trip   = %d usecs" "\n", stats .rtt);
}


usage

decompiled_code:
void __fastcall __noreturn usage(const char *a1, double a2)
{
fprintf(
stderr,
"%s\n"
"Copyright (C) 2000 Free Software Foundation\n"
"\n"
"This program comes with ABSOLUTELY NO WARRANTY; for details see source.\n"
"This is free software, and you are welcome to redistribute it under certain\n"
"conditions; see source for details.\n"
"\n"
"Usage:\n"
" %s <hostname> [<pptp options>] [[--] <pppd options>]\n"
"\n"
"Or using pppd's pty option: \n"
" pppd pty \"%s <hostname> --nolaunchpppd <pptp options>\"\n"
"\n"
"Available pptp options:\n"
" --version Display version number and exit\n"
" --phone <number>\tPass <number> to remote host as phone number\n"
" --nolaunchpppd\tDo not launch pppd, for use as a pppd pty\n"
" --quirks <quirk>\tWork around a buggy PPTP implementation\n"
"\t\t\tCurrently recognised values are BEZEQ_ISRAEL only\n"
" --debug\t\tRun in foreground (for debugging with gdb)\n"
" --sync\t\tEnable Synchronous HDLC (pppd must use it too)\n"
" --timeout <secs>\tTime to wait for reordered packets (0.01 to 10 secs)\n"
" --nobuffer\t\tDisable packet buffering and reordering completely\n"
" --idle-wait\t\tTime to wait before sending echo request\n"
" --max-echo-wait Time to wait before giving up on lack of reply\n"
" --logstring <name>\tUse <name> instead of 'anon' in syslog messages\n"
" --localbind <addr>\tBind to specified IP address instead of wildcard\n"
" --loglevel <level>\tSets the debugging level (0=low, 1=default, 2=high)\n"
" --test-type <type>\tDamage the packet stream by reordering\n"
" --test-rate <n> Do the test every n packets\n"
" --missing-window <n> Activate 'missing window' validation and set tolerance to <n> packages (300=default, 6000=recommended)\n",
version,
a1,
a1);
log(a2);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func3(const char *a1, double a2)
{
fprintf(
stderr,
"%s\n"
"Copyright (C) 2000 Free Software Foundation\n"
"\n"
"This program comes with ABSOLUTELY NO WARRANTY; for details see source.\n"
"This is free software, and you are welcome to redistribute it under certain\n"
"conditions; see source for details.\n"
"\n"
"Usage:\n"
" %s <hostname> [<pptp options>] [[--] <pppd options>]\n"
"\n"
"Or using pppd's pty option: \n"
" pppd pty \"%s <hostname> --nolaunchpppd <pptp options>\"\n"
"\n"
"Available pptp options:\n"
" --version Display version number and exit\n"
" --phone <number>\tPass <number> to remote host as phone number\n"
" --nolaunchpppd\tDo not launch pppd, for use as a pppd pty\n"
" --quirks <quirk>\tWork around a buggy PPTP implementation\n"
"\t\t\tCurrently recognised values are BEZEQ_ISRAEL only\n"
" --debug\t\tRun in foreground (for debugging with gdb)\n"
" --sync\t\tEnable Synchronous HDLC (pppd must use it too)\n"
" --timeout <secs>\tTime to wait for reordered packets (0.01 to 10 secs)\n"
" --nobuffer\t\tDisable packet buffering and reordering completely\n"
" --idle-wait\t\tTime to wait before sending echo request\n"
" --max-echo-wait Time to wait before giving up on lack of reply\n"
" --logstring <name>\tUse <name> instead of 'anon' in syslog messages\n"
" --localbind <addr>\tBind to specified IP address instead of wildcard\n"
" --loglevel <level>\tSets the debugging level (0=low, 1=default, 2=high)\n"
" --test-type <type>\tDamage the packet stream by reordering\n"
" --test-rate <n> Do the test every n packets\n"
" --missing-window <n> Activate 'missing window' validation and set tolerance to <n> packages (300=default, 6000=recommended)\n",
version,
a1,
a1);
log(a2);
exit(1);
}

original_code:
void usage(char *progname)
{
    fprintf(stderr,
            "%s\n"
"Copyright (C) 2000  Free Software Foundation\n\n"
"This program comes with ABSOLUTELY NO WARRANTY; for details see source.\n"
"This is free software, and you are welcome to redistribute it under certain\n"
"conditions; see source for details.\n\n"
            "Usage:\n"
            "  %s <hostname> [<pptp options>] [[--] <pppd options>]\n"
            "\n"
            "Or using pppd's pty option: \n"
            "  pppd pty \"%s <hostname> --nolaunchpppd <pptp options>\"\n"
            "\n"
            "Available pptp options:\n"
            "  --version        Display version number and exit\n"
            "  --phone <number>	Pass <number> to remote host as phone number\n"
            "  --nolaunchpppd	Do not launch pppd, for use as a pppd pty\n"
            "  --quirks <quirk>	Work around a buggy PPTP implementation\n"
            "			Currently recognised values are BEZEQ_ISRAEL only\n"
            "  --debug		Run in foreground (for debugging with gdb)\n"
            "  --sync		Enable Synchronous HDLC (pppd must use it too)\n"
            "  --timeout <secs>	Time to wait for reordered packets (0.01 to 10 secs)\n"
     "  --nobuffer		Disable packet buffering and reordering completely\n"
     "  --idle-wait		Time to wait before sending echo request\n"
            "  --max-echo-wait       Time to wait before giving up on lack of reply\n"
            "  --logstring <name>	Use <name> instead of 'anon' in syslog messages\n"
            "  --localbind <addr>	Bind to specified IP address instead of wildcard\n"
            "  --loglevel <level>	Sets the debugging level (0=low, 1=default, 2=high)\n"
            "  --test-type <type>	Damage the packet stream by reordering\n"
            "  --test-rate <n>       Do the test every n packets\n"
            "  --missing-window <n>  Activate 'missing window' validation and set tolerance to <n> packages (300=default, 6000=recommended)\n",
            version, progname, progname);
    _log(__FUNCTION__,"pptp.c",129, "%s called with wrong arguments, program not started." , progname);
    exit(1);
}

variable_types:
progname
char *


decompiled_code:
__int64 __fastcall get_ip_address(const char *a1)
{
struct hostent *v1; // rax
int v3; // eax

v1 = gethostbyname(a1);
if ( !v1 )
{
v3 = *_h_errno_location();
if ( v3 != 1 )
{
if ( v3 == 4 )
{
LABEL_8:
fatal("get_ip_address", "pptp.c", 449LL, "gethostbyname '%s': NO IP ADDRESS", a1);
LABEL_9:
fatal("get_ip_address", "pptp.c", 454LL, "Host '%s' has non-internet address", a1);
launch_callmgr();
}
fatal("get_ip_address", "pptp.c", 451LL, "gethostbyname '%s': name server error", a1);
}
fatal("get_ip_address", "pptp.c", 447LL, "gethostbyname '%s': HOST NOT FOUND", a1);
goto LABEL_8;
}
if ( v1->h_addrtype != 2 )
goto LABEL_9;
return **(unsigned int **)v1->h_addr_list;
}

canonical_decompiled_code:
__int64 __fastcall func4(const char *a1)
{
struct hostent *v1; // rax
int v3; // eax

v1 = gethostbyname(a1);
if ( !v1 )
{
v3 = *_h_errno_location();
if ( v3 != 1 )
{
if ( v3 == 4 )
{
LABEL_8:
fatal("get_ip_address", "pptp.c", 449LL, "gethostbyname '%s': NO IP ADDRESS", a1);
LABEL_9:
fatal("get_ip_address", "pptp.c", 454LL, "Host '%s' has non-internet address", a1);
func5();
}
fatal("get_ip_address", "pptp.c", 451LL, "gethostbyname '%s': name server error", a1);
}
fatal("get_ip_address", "pptp.c", 447LL, "gethostbyname '%s': HOST NOT FOUND", a1);
goto LABEL_8;
}
if ( v1->h_addrtype != 2 )
goto LABEL_9;
return **(unsigned int **)v1->h_addr_list;
}

original_code:
struct in_addr get_ip_address(char *name)
{
    struct in_addr retval;
    struct hostent *host = gethostbyname(name);
    if (host == ((void *)0)) {
        if ((*__h_errno_location ()) == 1)
            _fatal(__FUNCTION__,"pptp.c",447, "gethostbyname '%s': HOST NOT FOUND" , name);
        else if ((*__h_errno_location ()) == 4)
            _fatal(__FUNCTION__,"pptp.c",449, "gethostbyname '%s': NO IP ADDRESS" , name);
        else
            _fatal(__FUNCTION__,"pptp.c",451, "gethostbyname '%s': name server error" , name);
    }
    if (host->h_addrtype != 2)
        _fatal(__FUNCTION__,"pptp.c",454, "Host '%s' has non-internet address" , name);
    memcpy(&retval.s_addr, host->h_addr_list[0], sizeof(retval.s_addr));
    return retval;
}

variable_types:
name
char *

variable_types:
retval
struct in_addr { unsigned int s_addr; }

variable_types: struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; } *

return_type: struct in_addr { unsigned int s_addr; }


decompiled_code:
void __fastcall __noreturn launch_callmgr(struct in_addr a1, __int64 a2, __int64 a3, __int64 *a4, __int64 a5)
{
int v6; // eax
char v7[128]; // [rsp+0h] [rbp-B8h] BYREF
__int64 v8; // [rsp+80h] [rbp-38h] BYREF
char *v9; // [rsp+88h] [rbp-30h]
__int64 v10; // [rsp+90h] [rbp-28h]

v8 = *a4;
v9 = inet_ntoa(a1);
v10 = a2;
snprintf(v7, 0x80uLL, "pptp: call manager for %s", v9);
if ( prctl(15, "pptpcm", 0LL, 0LL, 0LL) )
perror("prctl");
v6 = callmgr_main(3LL, &v8, a5);
exit(v6);
}

canonical_decompiled_code:
void __fastcall __noreturn func5(struct in_addr a1, __int64 a2, __int64 a3, __int64 *a4, __int64 a5)
{
int v6; // eax
char v7[128]; // [rsp+0h] [rbp-B8h] BYREF
__int64 v8; // [rsp+80h] [rbp-38h] BYREF
char *v9; // [rsp+88h] [rbp-30h]
__int64 v10; // [rsp+90h] [rbp-28h]

v8 = *a4;
v9 = inet_ntoa(a1);
v10 = a2;
snprintf(v7, 0x80uLL, "pptp: call manager for %s", v9);
if ( prctl(15, "pptpcm", 0LL, 0LL, 0LL) )
perror("prctl");
v6 = callmgr_main(3LL, &v8, a5);
exit(v6);
}

original_code:
void launch_callmgr(struct in_addr inetaddr, char *phonenr, int argc,
        char**argv,char**envp)
{
      char *my_argv[3] = { argv[0], inet_ntoa(inetaddr), phonenr };
      char buf[128];
      snprintf(buf, sizeof(buf), "pptp: call manager for %s", my_argv[1]);
      int rc;
      rc = prctl(15, "pptpcm", 0, 0, 0);
      if (rc != 0) perror("prctl");
      exit(callmgr_main(3, my_argv, envp));
}

canonical_original_code:
void launch_callmgr(struct in_addr inetaddr, char *phonenr, int argc, char **argv, char **envp)
{
      char *my_argv[3] = { argv[0], inet_ntoa(inetaddr), phonenr };
      char buf[128];
      snprintf(buf, sizeof(buf), "pptp: call manager for %s", my_argv[1]);
      int rc;
      rc = prctl(15, "pptpcm", 0, 0, 0);
      if (rc != 0) perror("prctl");
      exit(callmgr_main(3, my_argv, envp));
}

variable_types:
inetaddr
struct in_addr { unsigned int s_addr; }

variable_types:
phonenr
char *

variable_types: argc int

variable_types:
argv
char **

variable_types:
envp
char **

variable_types:
buf
char [128]

variable_types: rc int