synchronatord

decompiled_code:
__int64 __fastcall synchronatord(const char *a1)
{
__int64 v1; // rbx
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // ebx
unsigned int v5; // eax
const char *v7; // rbp
unsigned int v8; // ebx
unsigned int v9; // ebx
pthread_attr_t v10; // [rsp+0h] [rbp-F8h] BYREF
sigset_t set; // [rsp+40h] [rbp-B8h] BYREF
__int64 v12[7]; // [rsp+C0h] [rbp-38h]

v12[0] = (__int64)a1;
v12[1] = (__int64)"/usr/local/etc/synchronator.conf";
v12[2] = (__int64)"/etc/synchronator.conf";
v1 = a1 == 0LL;
while ( 1 )
{
config_init(&config);
v7 = (const char *)v12[v1];
if ( (unsigned int)config_read_file(&config, v7) )
break;
if ( (v1 & 0xFFFFFFFD) == 0 )
{
syslog(
4,
"Configuration file was not found or is invalid: %s\n%s:%d - %s",
v7,
*((const char **)&config + 5),
*((unsigned int *)&config + 12),
*((const char **)&config + 4));
raise(15);
}
if ( (int)++v1 > 2 )
goto LABEL_3;
}
syslog(5, "Configuration file has been read: %s", a1);
LABEL_3:
if ( init() == 1 )
{
syslog(3, "Initialisation failed: %i", 1LL);
raise(15);
}
sigemptyset(&set);
sigaddset(&set, 2);
sigaddset(&set, 15);
v2 = pthread_mutex_init(&lockProcess, 0LL);
if ( v2 )
{
syslog(3, "Failed to create process mutex: %i", v2);
raise(15);
}
v3 = pthread_attr_init(&v10);
if ( v3 )
{
syslog(3, "Failed to initialize thread attributes: %i", v3);
raise(15);
}
pthread_attr_setdetachstate(&v10, 0);
v4 = pthread_create(&watchMixerThread, &v10, (void *(*)(void *))&watchMixer, &set);
if ( v4 )
{
pthread_attr_destroy(&v10);
syslog(3, "Failed to open mixer thread: %i", v4);
raise(15);
}
if ( common_data )
{
v8 = pthread_create(
&interfaceListenThread,
&v10,
*(void *(**)(void *))(*((_QWORD *)&common_data + 17) + 48LL),
&set);
if ( v8 )
{
pthread_attr_destroy(&v10);
syslog(3, "Failed to open interface listen thread: %i", v8);
raise(15);
}
}
if ( *(&common_data + 3) )
{
v9 = pthread_create(&statusQueryThread, &v10, (void *(*)(void *))queryStatus, &set);
if ( v9 )
{
pthread_attr_destroy(&v10);
syslog(3, "Failed to open interface query thread: %i", v9);
raise(15);
}
}
pthread_attr_destroy(&v10);
v5 = watchMsQ();
if ( v5 )
{
syslog(3, "Message queue failure: %i", v5);
raise(15);
}
raise(15);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(const char *a1)
{
__int64 v1; // rbx
unsigned int v2; // eax
unsigned int v3; // eax
unsigned int v4; // ebx
unsigned int v5; // eax
const char *v7; // rbp
unsigned int v8; // ebx
unsigned int v9; // ebx
pthread_attr_t v10; // [rsp+0h] [rbp-F8h] BYREF
sigset_t set; // [rsp+40h] [rbp-B8h] BYREF
__int64 v12[7]; // [rsp+C0h] [rbp-38h]

v12[0] = (__int64)a1;
v12[1] = (__int64)"/usr/local/etc/synchronator.conf";
v12[2] = (__int64)"/etc/synchronator.conf";
v1 = a1 == 0LL;
while ( 1 )
{
config_init(&config);
v7 = (const char *)v12[v1];
if ( (unsigned int)config_read_file(&config, v7) )
break;
if ( (v1 & 0xFFFFFFFD) == 0 )
{
syslog(
4,
"Configuration file was not found or is invalid: %s\n%s:%d - %s",
v7,
*((const char **)&config + 5),
*((unsigned int *)&config + 12),
*((const char **)&config + 4));
raise(15);
}
if ( (int)++v1 > 2 )
goto LABEL_3;
}
syslog(5, "Configuration file has been read: %s", a1);
LABEL_3:
if ( func3() == 1 )
{
syslog(3, "Initialisation failed: %i", 1LL);
raise(15);
}
sigemptyset(&set);
sigaddset(&set, 2);
sigaddset(&set, 15);
v2 = pthread_mutex_init(&lockProcess, 0LL);
if ( v2 )
{
syslog(3, "Failed to create process mutex: %i", v2);
raise(15);
}
v3 = pthread_attr_init(&v10);
if ( v3 )
{
syslog(3, "Failed to initialize thread attributes: %i", v3);
raise(15);
}
pthread_attr_setdetachstate(&v10, 0);
v4 = pthread_create(&watchMixerThread, &v10, (void *(*)(void *))&watchMixer, &set);
if ( v4 )
{
pthread_attr_destroy(&v10);
syslog(3, "Failed to open mixer thread: %i", v4);
raise(15);
}
if ( common_data )
{
v8 = pthread_create(
&interfaceListenThread,
&v10,
*(void *(**)(void *))(*((_QWORD *)&common_data + 17) + 48LL),
&set);
if ( v8 )
{
pthread_attr_destroy(&v10);
syslog(3, "Failed to open interface listen thread: %i", v8);
raise(15);
}
}
if ( *(&common_data + 3) )
{
v9 = pthread_create(&statusQueryThread, &v10, (void *(*)(void *))queryStatus, &set);
if ( v9 )
{
pthread_attr_destroy(&v10);
syslog(3, "Failed to open interface query thread: %i", v9);
raise(15);
}
}
pthread_attr_destroy(&v10);
v5 = watchMsQ();
if ( v5 )
{
syslog(3, "Message queue failure: %i", v5);
raise(15);
}
raise(15);
return 1LL;
}

original_code:
static int synchronatord(char *customConfigLocation) {
    int status = 0;
    int count = 0;
    char *configLocations[] = {customConfigLocation, "/usr/local" "/etc/" "synchronator" ".conf", "/etc/" "synchronator" ".conf"};
    for(count = (configLocations[0] == ((void *)0)) ? 1:0; count < 3; count++) {
        config_init(&config);
        if(!config_read_file(&config, configLocations[count])) {
            if(count == 2 || count == 0) {
                syslog(4, "Configuration file was not found or is invalid: %s\n%s:%d - %s",
                    configLocations[count], ((&config)->error_file), ((&config)->error_line),
                    ((&config)->error_text));
                raise(15);
            }
        }
        else {
            syslog(5, "Configuration file has been read: %s", configLocations[0]);
            break;
        }
    }
    if((status = init()) == 1) {
        syslog(3, "Initialisation failed: %i", status);
        raise(15);
    }
    sigset_t thread_sigmask;
    sigemptyset(&thread_sigmask);
    sigaddset(&thread_sigmask, 2);
    sigaddset(&thread_sigmask, 15);
    if((status = pthread_mutex_init(&lockProcess, ((void *)0))) != 0) {
        syslog(3, "Failed to create process mutex: %i", status);
        raise(15);
    }
    pthread_attr_t thread_attr;
    if((status = pthread_attr_init(&thread_attr)) != 0) {
        syslog(3, "Failed to initialize thread attributes: %i", status);
        raise(15);
    }
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
    if(status = pthread_create(&watchMixerThread, &thread_attr, watchMixer, &thread_sigmask)) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open mixer thread: %i", status);
        raise(15);
    }
    if(common_data.sync_2way && (status = pthread_create(&interfaceListenThread, &thread_attr,
                                    common_data.interface->listen, &thread_sigmask))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open interface listen thread: %i", status);
        raise(15);
    }
    if(common_data.send_query && (status = pthread_create(&statusQueryThread, &thread_attr,
    queryStatus, &thread_sigmask))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open interface query thread: %i", status);
        raise(15);
    }
    pthread_attr_destroy(&thread_attr);
        if(status = watchMsQ()) {
            syslog(3, "Message queue failure: %i", status);
            raise(15);
        }
    raise(15);
    return 1;
}

canonical_original_code:
static int synchronatord(char *customConfigLocation) {
    int status = 0;
    int count = 0;
    char *configLocations[] = {customConfigLocation, "/usr/local" "/etc/" "synchronator" ".conf", "/etc/" "synchronator" ".conf"};
    for(count = (configLocations[0] == ((void *)0)) ? 1:0; count < 3; count++) {
        config_init(&config);
        if(!config_read_file(&config, configLocations[count])) {
            if(count == 2 || count == 0) {
                syslog(4, "Configuration file was not found or is invalid: %s\n%s:%d - %s",
                    configLocations[count], ((&config)->error_file), ((&config)->error_line),
                    ((&config)->error_text));
                raise(15);
            }
        }
        else {
            syslog(5, "Configuration file has been read: %s", configLocations[0]);
            break;
        }
    }
    if((status = init()) == 1) {
        syslog(3, "Initialisation failed: %i", status);
        raise(15);
    }
    struct __sigset_t thread_sigmask;
    sigemptyset(&thread_sigmask);
    sigaddset(&thread_sigmask, 2);
    sigaddset(&thread_sigmask, 15);
    if((status = pthread_mutex_init(&lockProcess, ((void *)0))) != 0) {
        syslog(3, "Failed to create process mutex: %i", status);
        raise(15);
    }
    union pthread_attr_t thread_attr;
    if((status = pthread_attr_init(&thread_attr)) != 0) {
        syslog(3, "Failed to initialize thread attributes: %i", status);
        raise(15);
    }
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
    if(status = pthread_create(&watchMixerThread, &thread_attr, watchMixer, &thread_sigmask)) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open mixer thread: %i", status);
        raise(15);
    }
    if(common_data.sync_2way && (status = pthread_create(&interfaceListenThread, &thread_attr,
                                    common_data.interface->listen, &thread_sigmask))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open interface listen thread: %i", status);
        raise(15);
    }
    if(common_data.send_query && (status = pthread_create(&statusQueryThread, &thread_attr,
    queryStatus, &thread_sigmask))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open interface query thread: %i", status);
        raise(15);
    }
    pthread_attr_destroy(&thread_attr);
        if(status = watchMsQ()) {
            syslog(3, "Message queue failure: %i", status);
            raise(15);
        }
    raise(15);
    return 1;
}

variable_types:
customConfigLocation
char *

variable_types: status int

variable_types:
configLocations
char *[]

variable_types: struct __sigset_t { unsigned long __val[-1]; }

variable_types: union pthread_attr_t { char __size[56]; long __align; }


main

canonical_name: main

repo: therealmuffin/synchronator

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
unsigned int v4; // ebx
__uid_t v5; // eax
int v6; // eax
int v7; // ebx
unsigned int v8; // eax
int *v9; // rax
char *v10; // rax
int *v11; // rax
char *v12; // rax
int *v13; // rax
char *v14; // rax
__int64 v15; // rbx
struct sigaction v17; // [rsp+0h] [rbp-D8h] BYREF

setlogmask(63);
opterr = 0;
v3 = getopt(argc, (char *const *)argv, "v:Vhdi:");
if ( v3 != -1 )
{
if ( v3 != 63 )
exit(1);
v4 = optopt;
if ( optopt == 105 )
{
fprintf(stderr, "You forgot to include a path with option '-%c'.\n", 105LL);
}
else if ( optopt == 118 )
{
setlogmask(127);
}
else if ( ((*_ctype_b_loc())[v4] & 0x4000) != 0 )
{
fprintf(stderr, "Unknown option `-%c'.\n", v4);
}
else
{
fprintf(stderr, "Unknown option character `\\x%x'.\n", v4);
}
exit(1);
}
umask(0);
openlog("synchronator", 41, 24);
v5 = getuid();
syslog(5, "Program started by User %d", v5);
v6 = open("/var/run/synchronator/synchronator.pid", 524354, 420LL);
lock_file = v6;
if ( v6 >= 0 )
{
if ( lockf(v6, 2, 0LL) >= 0 )
{
v7 = lock_file;
ftruncate(lock_file, 0LL);
v8 = getpid();
dprintf(v7, "%d\n", v8);
interfaceListenThread = pthread_self();
watchMixerThread = interfaceListenThread;
statusQueryThread = interfaceListenThread;
mainThread = interfaceListenThread;
*((_QWORD *)&common_data + 16) = 0LL;
*((_QWORD *)&common_data + 17) = 0LL;
*((_QWORD *)&common_data + 18) = 0LL;
*((_QWORD *)&common_data + 19) = 0LL;
v17.sa_handler = (__sighandler_t)terminate;
sigfillset(&v17.sa_mask);
v17.sa_flags = 0;
if ( sigaction(2, &v17, 0LL) < 0 || sigaction(15, &v17, 0LL) < 0 )
{
v9 = _errno_location();
v10 = strerror(*v9);
syslog(3, "Failed to ignore signals: %s", v10);
closelog();
exit(1);
}
v15 = (unsigned int)synchronatord(0LL);
syslog(3, "Exiting: %i", v15);
closelog();
exit(v15);
}
v13 = _errno_location();
v14 = strerror(*v13);
syslog(4, "Exiting: only one instance of this application can run: %s", v14);
closelog();
exit(0);
}
v11 = _errno_location();
v12 = strerror(*v11);
syslog(3, "Failed to open lock file: %s (%s)", "/var/run/synchronator/synchronator.pid", v12);
closelog();
exit(1);
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
unsigned int v4; // ebx
__uid_t v5; // eax
int v6; // eax
int v7; // ebx
unsigned int v8; // eax
int *v9; // rax
char *v10; // rax
int *v11; // rax
char *v12; // rax
int *v13; // rax
char *v14; // rax
__int64 v15; // rbx
struct sigaction v17; // [rsp+0h] [rbp-D8h] BYREF

setlogmask(63);
opterr = 0;
v3 = getopt(argc, (char *const *)argv, "v:Vhdi:");
if ( v3 != -1 )
{
if ( v3 != 63 )
exit(1);
v4 = optopt;
if ( optopt == 105 )
{
fprintf(stderr, "You forgot to include a path with option '-%c'.\n", 105LL);
}
else if ( optopt == 118 )
{
setlogmask(127);
}
else if ( ((*_ctype_b_loc())[v4] & 0x4000) != 0 )
{
fprintf(stderr, "Unknown option `-%c'.\n", v4);
}
else
{
fprintf(stderr, "Unknown option character `\\x%x'.\n", v4);
}
exit(1);
}
umask(0);
openlog("synchronator", 41, 24);
v5 = getuid();
syslog(5, "Program started by User %d", v5);
v6 = open("/var/run/synchronator/synchronator.pid", 524354, 420LL);
lock_file = v6;
if ( v6 >= 0 )
{
if ( lockf(v6, 2, 0LL) >= 0 )
{
v7 = lock_file;
ftruncate(lock_file, 0LL);
v8 = getpid();
dprintf(v7, "%d\n", v8);
interfaceListenThread = pthread_self();
watchMixerThread = interfaceListenThread;
statusQueryThread = interfaceListenThread;
mainThread = interfaceListenThread;
*((_QWORD *)&common_data + 16) = 0LL;
*((_QWORD *)&common_data + 17) = 0LL;
*((_QWORD *)&common_data + 18) = 0LL;
*((_QWORD *)&common_data + 19) = 0LL;
v17.sa_handler = (__sighandler_t)terminate;
sigfillset(&v17.sa_mask);
v17.sa_flags = 0;
if ( sigaction(2, &v17, 0LL) < 0 || sigaction(15, &v17, 0LL) < 0 )
{
v9 = _errno_location();
v10 = strerror(*v9);
syslog(3, "Failed to ignore signals: %s", v10);
closelog();
exit(1);
}
v15 = (unsigned int)func4(0LL);
syslog(3, "Exiting: %i", v15);
closelog();
exit(v15);
}
v13 = _errno_location();
v14 = strerror(*v13);
syslog(4, "Exiting: only one instance of this application can run: %s", v14);
closelog();
exit(0);
}
v11 = _errno_location();
v12 = strerror(*v11);
syslog(3, "Failed to open lock file: %s (%s)", "/var/run/synchronator/synchronator.pid", v12);
closelog();
exit(1);
}

original_code:
int main(int argc, char *argv[]) {
    int status = 0;
    int daemon = 0;
    char *customConfigLocation = ((void *)0);
    setlogmask(((1 << ((5)+1)) - 1));
    int option = 0;
    opterr = 0;
    while((option = getopt(argc, argv, "v:Vhdi:")) != -1)
        switch(option) {
            case 'v':
                if(strcmp(optarg, "0") == 0)
                    setlogmask(((1 << ((3)+1)) - 1));
                else if(strcmp(optarg, "1") == 0)
                    setlogmask(((1 << ((6)+1)) - 1));
                else if(strcmp(optarg, "2") == 0)
                    setlogmask(((1 << ((7)+1)) - 1));
                break;
            case 'V':
                fprintf(stdout, "%s %s\n\n%s\n", "synchronator" , " (5762e34)", "Copyright (C) 2013-2017 Muffinman <synchronator.hifi@gmail.com>\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
                exit(0);
            case 'h':
                fprintf(stdout, "Usage: %s %s", argv[0], "[options...]\n" "   -V          print version information\n" "   -h          print this help message\n" "   -d          daemonize application\n" "   -v0         set level of verbose to a minimum\n" "   -v1         set level of verbose to include informational messages\n" "   -v2         set level of verbose to include debug messages\n" "   -i          specify path to a configuration file\n\n" "If no location for the configuration file is given, the application will look in:\n" "   primary     ""/usr/local" "/etc/" "synchronator" ".conf""\n" "   secondary   ""/etc/" "synchronator" ".conf""\n" "\n" "Synchronator is compiled with support for:\n" " Serial interface\n" " Message Queue (basic local control)\n");
                exit(0);
            case 'd':
                daemon = 1;
                break;
            case 'i':
                customConfigLocation = optarg;
                break;
            case '?':
                if(optopt == 'i')
                    fprintf(stderr, "You forgot to include a path with option '-%c'.\n", optopt);
                else if(optopt == 'v')
                    setlogmask(((1 << ((6)+1)) - 1));
                else if(((*__ctype_b_loc ())[(int) ((optopt))] & (unsigned short int) _ISprint))
                    fprintf(stderr, "Unknown option `-%c'.\n", optopt);
                else
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                exit(1);
            default:
                exit(1);
        }
    umask(0);
    if(daemon) {
        if((status = daemonize()) == 1)
            exit(1);
    }
    else {
        openlog( "synchronator" , 0x08 | 0x01 | 0x20, (3<<3));
        syslog(5, "Program started by User %d", getuid());
    }
    if((lock_file = open("/var/run/synchronator/" "synchronator" ".pid", 02|0100|02000000, (0400|0200|(0400 >> 3)|((0400 >> 3) >> 3)))) < 0) {
        syslog(3, "Failed to open lock file: %s (%s)", "/var/run/synchronator/" "synchronator" ".pid", strerror((*__errno_location ())));
        closelog();
        exit(1);
    }
    if(lockf(lock_file, 2, 0) < 0) {
        syslog(4, "Exiting: only one instance of this application can run: %s", strerror((*__errno_location ())));
        closelog();
        exit(0);
    }
    ftruncate(lock_file, 0);
    dprintf(lock_file, "%d\n", getpid());
    mainThread = statusQueryThread = watchMixerThread = interfaceListenThread = pthread_self();
    common_data.process = ((void *)0);
    common_data.interface = ((void *)0);
    common_data.volume = ((void *)0);
    common_data.mod = ((void *)0);
    struct sigaction signal_action;
    signal_action.__sigaction_handler.sa_handler = terminate;
    sigfillset(&signal_action.sa_mask);
    signal_action.sa_flags = 0;
    if(sigaction(2, &signal_action, ((void *)0)) < 0 || sigaction(15, &signal_action, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals: %s", strerror((*__errno_location ())));
        closelog();
        exit(1);
    }
    status = synchronatord(customConfigLocation);
    syslog(3, "Exiting: %i", status);
    closelog();
    exit(status);
}

canonical_original_code:
int main(int argc, char *argv[]) {
    int status = 0;
    int daemon = 0;
    char *customConfigLocation = ((void *)0);
    setlogmask(((1 << ((5)+1)) - 1));
    int option = 0;
    opterr = 0;
    while((option = getopt(argc, argv, "v:Vhdi:")) != -1)
        switch(option) {
            case 'v':
                if(strcmp(optarg, "0") == 0)
                    setlogmask(((1 << ((3)+1)) - 1));
                else if(strcmp(optarg, "1") == 0)
                    setlogmask(((1 << ((6)+1)) - 1));
                else if(strcmp(optarg, "2") == 0)
                    setlogmask(((1 << ((7)+1)) - 1));
                break;
            case 'V':
                fprintf(stdout, "%s %s\n\n%s\n", "synchronator" , " (5762e34)", "Copyright (C) 2013-2017 Muffinman <synchronator.hifi@gmail.com>\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
                exit(0);
            case 'h':
                fprintf(stdout, "Usage: %s %s", argv[0], "[options...]\n" "   -V          print version information\n" "   -h          print this help message\n" "   -d          daemonize application\n" "   -v0         set level of verbose to a minimum\n" "   -v1         set level of verbose to include informational messages\n" "   -v2         set level of verbose to include debug messages\n" "   -i          specify path to a configuration file\n\n" "If no location for the configuration file is given, the application will look in:\n" "   primary     ""/usr/local" "/etc/" "synchronator" ".conf""\n" "   secondary   ""/etc/" "synchronator" ".conf""\n" "\n" "Synchronator is compiled with support for:\n" " Serial interface\n" " Message Queue (basic local control)\n");
                exit(0);
            case 'd':
                daemon = 1;
                break;
            case 'i':
                customConfigLocation = optarg;
                break;
            case '?':
                if(optopt == 'i')
                    fprintf(stderr, "You forgot to include a path with option '-%c'.\n", optopt);
                else if(optopt == 'v')
                    setlogmask(((1 << ((6)+1)) - 1));
                else if(((*__ctype_b_loc ())[(int) ((optopt))] & (unsigned short) _ISprint))
                    fprintf(stderr, "Unknown option `-%c'.\n", optopt);
                else
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                exit(1);
            default:
                exit(1);
        }
    umask(0);
    if(daemon) {
        if((status = daemonize()) == 1)
            exit(1);
    }
    else {
        openlog( "synchronator" , 0x08 | 0x01 | 0x20, (3<<3));
        syslog(5, "Program started by User %d", getuid());
    }
    if((lock_file = open("/var/run/synchronator/" "synchronator" ".pid", 02|0100|02000000, (0400|0200|(0400 >> 3)|((0400 >> 3) >> 3)))) < 0) {
        syslog(3, "Failed to open lock file: %s (%s)", "/var/run/synchronator/" "synchronator" ".pid", strerror((*__errno_location ())));
        closelog();
        exit(1);
    }
    if(lockf(lock_file, 2, 0) < 0) {
        syslog(4, "Exiting: only one instance of this application can run: %s", strerror((*__errno_location ())));
        closelog();
        exit(0);
    }
    ftruncate(lock_file, 0);
    dprintf(lock_file, "%d\n", getpid());
    mainThread = statusQueryThread = watchMixerThread = interfaceListenThread = pthread_self();
    common_data.process = ((void *)0);
    common_data.interface = ((void *)0);
    common_data.volume = ((void *)0);
    common_data.mod = ((void *)0);
    struct sigaction signal_action;
    signal_action.__sigaction_handler.sa_handler = terminate;
    sigfillset(&signal_action.sa_mask);
    signal_action.sa_flags = 0;
    if(sigaction(2, &signal_action, ((void *)0)) < 0 || sigaction(15, &signal_action, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals: %s", strerror((*__errno_location ())));
        closelog();
        exit(1);
    }
    status = synchronatord(customConfigLocation);
    syslog(3, "Exiting: %i", status);
    closelog();
    exit(status);
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: daemon int

variable_types: option int

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

return_type: int

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

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


init

decompiled_code:
unsigned int init()
{
__int64 v0; // rax
unsigned int result; // eax
__int64 v2; // rax
__int64 v3; // rax
__int64 v4; // rax
int *v5; // rax
char *v6; // rax
__int64 v7; // rax
int v8; // eax
const char *v9[2]; // [rsp+8h] [rbp-10h] BYREF

v9[0] = 0LL;
if ( chdir("/") < 0 )
{
v5 = _errno_location();
v6 = strerror(*v5);
syslog(3, "Unable to change working directory to root: %s", v6);
result = 1;
}
else
{
syslog(6, "Checking presence and validity of required variables:");
config_lookup_string(&config, "data_type", (unsigned int)((_DWORD)&common_data + 16));
validateConfigBool(&config, "sync_2way", &common_data, 0LL);
validateConfigBool(&config, "diff_commands", (unsigned int)((_DWORD)&common_data + 8), 0LL);
v0 = config_lookup(&config, "query");
*(&common_data + 3) = v0 != 0;
if ( !v0 )
goto LABEL_3;
v7 = config_lookup(&config, "query.trigger");
if ( !v7 || *(_WORD *)(v7 + 8) != 7 || (v8 = config_setting_length(v7), (*(&common_data + 28) = v8) == 0) )
{
syslog(3, "[ERROR] Setting is not present or not formatted as array: query.trigger");
return 1;
}
if ( !*(&common_data + 3)
|| (result = validateConfigInt(
&config,
"query.interval",
(unsigned int)((_DWORD)&common_data + 116),
0xFFFFFFFFLL,
0LL,
300LL,
-1LL),
result != 1) )
{
LABEL_3:
*((_QWORD *)&common_data + 19) = &mod;
result = mod();
if ( result != 1 )
{
v9[0] = 0LL;
config_lookup_string(&config, "volume.curve", v9);
v2 = getVolume(v9);
*((_QWORD *)&common_data + 18) = v2;
if ( v2 )
{
syslog(6, "[OK] volume.curve: %s", v9[0]);
result = (**((__int64 (***)(void))&common_data + 18))();
if ( result != 1 )
{
v9[0] = 0LL;
config_lookup_string(&config, "interface", v9);
v3 = getInterface(v9);
*((_QWORD *)&common_data + 17) = v3;
if ( v3 )
{
syslog(6, "[OK] interface: %s", v9[0]);
result = (*(__int64 (**)(void))(*((_QWORD *)&common_data + 17) + 16LL))();
if ( result != 1 )
{
result = initMixer();
if ( result != 1 )
{
v4 = getProcessMethod((unsigned int)((_DWORD)&common_data + 16));
*((_QWORD *)&common_data + 16) = v4;
if ( v4 )
{
syslog(6, "[OK] data_type: %s", v9[0]);
result = (*(__int64 (**)(void))(*((_QWORD *)&common_data + 16) + 16LL))();
if ( result != 1 )
{
(*(void (**)(void))(*((_QWORD *)&common_data + 18) + 32LL))();
result = initMsQ();
if ( result != 1 )
{
result = pthread_mutex_init(&lockConfig, 0LL);
if ( result )
{
syslog(3, "Failed to create config mutex: %i", result);
result = 1;
}
}
}
}
else
{
syslog(3, "[Error] Setting 'data_type' is not recognised: %s", *((const char **)&common_data + 2));
result = 1;
}
}
}
}
else
{
syslog(3, "[Error] Setting 'interface' is not recognised: %s", v9[0]);
result = 1;
}
}
}
else
{
syslog(3, "[Error] Volume curve is not recognised: %s", v9[0]);
result = 1;
}
}
}
}
return result;
}

canonical_decompiled_code:
unsigned int func3()
{
__int64 v0; // rax
unsigned int result; // eax
__int64 v2; // rax
__int64 v3; // rax
__int64 v4; // rax
int *v5; // rax
char *v6; // rax
__int64 v7; // rax
int v8; // eax
const char *v9[2]; // [rsp+8h] [rbp-10h] BYREF

v9[0] = 0LL;
if ( chdir("/") < 0 )
{
v5 = _errno_location();
v6 = strerror(*v5);
syslog(3, "Unable to change working directory to root: %s", v6);
result = 1;
}
else
{
syslog(6, "Checking presence and validity of required variables:");
config_lookup_string(&config, "data_type", (unsigned int)((_DWORD)&common_data + 16));
validateConfigBool(&config, "sync_2way", &common_data, 0LL);
validateConfigBool(&config, "diff_commands", (unsigned int)((_DWORD)&common_data + 8), 0LL);
v0 = config_lookup(&config, "query");
*(&common_data + 3) = v0 != 0;
if ( !v0 )
goto LABEL_3;
v7 = config_lookup(&config, "query.trigger");
if ( !v7 || *(_WORD *)(v7 + 8) != 7 || (v8 = config_setting_length(v7), (*(&common_data + 28) = v8) == 0) )
{
syslog(3, "[ERROR] Setting is not present or not formatted as array: query.trigger");
return 1;
}
if ( !*(&common_data + 3)
|| (result = validateConfigInt(
&config,
"query.interval",
(unsigned int)((_DWORD)&common_data + 116),
0xFFFFFFFFLL,
0LL,
300LL,
-1LL),
result != 1) )
{
LABEL_3:
*((_QWORD *)&common_data + 19) = &mod;
result = mod();
if ( result != 1 )
{
v9[0] = 0LL;
config_lookup_string(&config, "volume.curve", v9);
v2 = getVolume(v9);
*((_QWORD *)&common_data + 18) = v2;
if ( v2 )
{
syslog(6, "[OK] volume.curve: %s", v9[0]);
result = (**((__int64 (***)(void))&common_data + 18))();
if ( result != 1 )
{
v9[0] = 0LL;
config_lookup_string(&config, "interface", v9);
v3 = getInterface(v9);
*((_QWORD *)&common_data + 17) = v3;
if ( v3 )
{
syslog(6, "[OK] interface: %s", v9[0]);
result = (*(__int64 (**)(void))(*((_QWORD *)&common_data + 17) + 16LL))();
if ( result != 1 )
{
result = initMixer();
if ( result != 1 )
{
v4 = getProcessMethod((unsigned int)((_DWORD)&common_data + 16));
*((_QWORD *)&common_data + 16) = v4;
if ( v4 )
{
syslog(6, "[OK] data_type: %s", v9[0]);
result = (*(__int64 (**)(void))(*((_QWORD *)&common_data + 16) + 16LL))();
if ( result != 1 )
{
(*(void (**)(void))(*((_QWORD *)&common_data + 18) + 32LL))();
result = initMsQ();
if ( result != 1 )
{
result = pthread_mutex_init(&lockConfig, 0LL);
if ( result )
{
syslog(3, "Failed to create config mutex: %i", result);
result = 1;
}
}
}
}
else
{
syslog(3, "[Error] Setting 'data_type' is not recognised: %s", *((const char **)&common_data + 2));
result = 1;
}
}
}
}
else
{
syslog(3, "[Error] Setting 'interface' is not recognised: %s", v9[0]);
result = 1;
}
}
}
else
{
syslog(3, "[Error] Volume curve is not recognised: %s", v9[0]);
result = 1;
}
}
}
}
return result;
}

original_code:
static int init(void) {
    int status;
    config_setting_t *conf_setting = ((void *)0);
    const char *conf_value = ((void *)0);
    if(chdir("/") < 0) {
        syslog(3, "Unable to change working directory to root: %s", strerror((*__errno_location ())));
        return 1;
    }
    syslog(6, "Checking presence and validity of required variables:");
    config_lookup_string(&config, "data_type", &common_data.dataType);
    validateConfigBool(&config, "sync_2way", &common_data.sync_2way, 0);
    validateConfigBool(&config, "diff_commands", &common_data.diff_commands, 0);
    common_data.send_query = config_lookup(&config, "query") ? 1:0;
    if(common_data.send_query && ((conf_setting = config_lookup(&config, "query.trigger")) == ((void *)0) ||
    ((conf_setting)->type == 7) == (0) || (common_data.statusQueryLength =
    config_setting_length(conf_setting)) == 0)) {
        syslog(3, "[ERROR] Setting is not present or not formatted as array: query.trigger");
        return 1;
    }
    if(common_data.send_query && validateConfigInt(&config, "query.interval",
    &common_data.statusQueryInterval, -1, 0, 300, -1) == 1)
        return 1;
    common_data.mod = &mod;
    if(common_data.mod->init() == 1)
        return 1;
    conf_value = ((void *)0);
    config_lookup_string(&config, "volume.curve", &conf_value);
    if(!(common_data.volume = getVolume(&conf_value))) {
        syslog(3, "[Error] Volume curve is not recognised: %s", conf_value);
        return 1;
    }
    else {
        syslog(6, "[OK] volume.curve: %s", conf_value);
    }
    if(common_data.volume->init() == 1)
        return 1;
    conf_value = ((void *)0);
    config_lookup_string(&config, "interface", &conf_value);
    if(!(common_data.interface = getInterface(&conf_value))) {
        syslog(3, "[Error] Setting 'interface' is not recognised: %s", conf_value);
        return 1;
    }
    else {
        syslog(6, "[OK] interface: %s", conf_value);
    }
    if(common_data.interface->init() == 1)
        return 1;
    if(initMixer() == 1)
        return 1;
    if(!(common_data.process = getProcessMethod(&common_data.dataType))) {
        syslog(3, "[Error] Setting 'data_type' is not recognised: %s", common_data.dataType);
        return 1;
    }
    else {
        syslog(6, "[OK] data_type: %s", conf_value);
    }
    if(common_data.process->init() == 1)
        return 1;
    common_data.volume->regenerateMultipliers();
    if(initMsQ() == 1)
        return 1;
    if((status = pthread_mutex_init(&lockConfig, ((void *)0))) != 0) {
        syslog(3, "Failed to create config mutex: %i", status);
        return 1;
    }
    return 0;
}

canonical_original_code:
static int init() {
    int status;
    struct config_setting_t *conf_setting = ((void *)0);
    char *conf_value = ((void *)0);
    if(chdir("/") < 0) {
        syslog(3, "Unable to change working directory to root: %s", strerror((*__errno_location ())));
        return 1;
    }
    syslog(6, "Checking presence and validity of required variables:");
    config_lookup_string(&config, "data_type", &common_data.dataType);
    validateConfigBool(&config, "sync_2way", &common_data.sync_2way, 0);
    validateConfigBool(&config, "diff_commands", &common_data.diff_commands, 0);
    common_data.send_query = config_lookup(&config, "query") ? 1:0;
    if(common_data.send_query && ((conf_setting = config_lookup(&config, "query.trigger")) == ((void *)0) ||
    ((conf_setting)->type == 7) == (0) || (common_data.statusQueryLength =
    config_setting_length(conf_setting)) == 0)) {
        syslog(3, "[ERROR] Setting is not present or not formatted as array: query.trigger");
        return 1;
    }
    if(common_data.send_query && validateConfigInt(&config, "query.interval",
    &common_data.statusQueryInterval, -1, 0, 300, -1) == 1)
        return 1;
    common_data.mod = &mod;
    if(common_data.mod->init() == 1)
        return 1;
    conf_value = ((void *)0);
    config_lookup_string(&config, "volume.curve", &conf_value);
    if(!(common_data.volume = getVolume(&conf_value))) {
        syslog(3, "[Error] Volume curve is not recognised: %s", conf_value);
        return 1;
    }
    else {
        syslog(6, "[OK] volume.curve: %s", conf_value);
    }
    if(common_data.volume->init() == 1)
        return 1;
    conf_value = ((void *)0);
    config_lookup_string(&config, "interface", &conf_value);
    if(!(common_data.interface = getInterface(&conf_value))) {
        syslog(3, "[Error] Setting 'interface' is not recognised: %s", conf_value);
        return 1;
    }
    else {
        syslog(6, "[OK] interface: %s", conf_value);
    }
    if(common_data.interface->init() == 1)
        return 1;
    if(initMixer() == 1)
        return 1;
    if(!(common_data.process = getProcessMethod(&common_data.dataType))) {
        syslog(3, "[Error] Setting 'data_type' is not recognised: %s", common_data.dataType);
        return 1;
    }
    else {
        syslog(6, "[OK] data_type: %s", conf_value);
    }
    if(common_data.process->init() == 1)
        return 1;
    common_data.volume->regenerateMultipliers();
    if(initMsQ() == 1)
        return 1;
    if((status = pthread_mutex_init(&lockConfig, ((void *)0))) != 0) {
        syslog(3, "Failed to create config mutex: %i", status);
        return 1;
    }
    return 0;
}

variable_types: struct config_setting_t { char *name; short type; short format; union config_value_t { int ival; long long llval; double fval; char *sval; struct config_list_t { unsigned int length; struct config_setting_t **elements; } *list; } value; struct config_setting_t *parent; struct config_t { struct config_setting_t *root; void (*destructor)(void *); int options; unsigned short tab_width; short default_format; char *include_dir; char *error_text; char *error_file; int error_line; enum config_error_t { CONFIG_ERR_NONE=0, CONFIG_ERR_FILE_IO=1, CONFIG_ERR_PARSE=2 } error_type; char **filenames; unsigned int num_filenames; } *config; void *hook; unsigned int line; char *file; } *

user_defined_types: struct config_setting_t { char *name; short type; short format; union config_value_t value; struct config_setting_t *parent; struct config_t *config; void *hook; unsigned int line; char *file; }

user_defined_types: union config_value_t { int ival; long long llval; double fval; char *sval; struct config_list_t *list; }

user_defined_types: struct config_t { struct config_setting_t *root; void (*destructor)(void *); int options; unsigned short tab_width; short default_format; char *include_dir; char *error_text; char *error_file; int error_line; enum config_error_t error_type; char **filenames; unsigned int num_filenames; }


getModVolumeResponse

decompiled_code:
const char **__fastcall getModVolumeResponse(char *s1)
{
const char **v1; // rbx
const char ***v2; // rbp

if ( !s1 )
return 0LL;
v1 = (const char **)modVolumeResponseList;
if ( modVolumeResponseList )
{
v2 = (const char ***)&modVolumeResponseList;
while ( strcasecmp(s1, *v1) )
{
v1 = *++v2;
if ( !*v2 )
goto LABEL_6;
}
}
else
{
LABEL_6:
syslog(4, "[NOTICE] Setting 'volume.response.mode' is not recognised, ignoring: %s", s1);
v1 = 0LL;
}
return v1;
}

canonical_decompiled_code:
const char **__fastcall func1(char *s1)
{
const char **v1; // rbx
const char ***v2; // rbp

if ( !s1 )
return 0LL;
v1 = (const char **)modVolumeResponseList;
if ( modVolumeResponseList )
{
v2 = (const char ***)&modVolumeResponseList;
while ( strcasecmp(s1, *v1) )
{
v1 = *++v2;
if ( !*v2 )
goto LABEL_6;
}
}
else
{
LABEL_6:
syslog(4, "[NOTICE] Setting 'volume.response.mode' is not recognised, ignoring: %s", s1);
v1 = 0LL;
}
return v1;
}

original_code:
static modVolumeResponse_t *getModVolumeResponse(const char *name) {
    modVolumeResponse_t **modVolumeResponse;
    if (!name)
        return ((void *)0);
    for (modVolumeResponse=modVolumeResponseList; *modVolumeResponse; modVolumeResponse++)
        if (!strcasecmp(name, (*modVolumeResponse)->name))
            return *modVolumeResponse;
    syslog(4, "[NOTICE] Setting 'volume.response.mode' is not recognised, ignoring: %s", name);
    return ((void *)0);
}

canonical_original_code:
static struct modVolumeResponse_t *getModVolumeResponse(char *name) {
    struct modVolumeResponse_t **modVolumeResponse;
    if (!name)
        return ((void *)0);
    for (modVolumeResponse=modVolumeResponseList; *modVolumeResponse; modVolumeResponse++)
        if (!strcasecmp(name, (*modVolumeResponse)->name))
            return *modVolumeResponse;
    syslog(4, "[NOTICE] Setting 'volume.response.mode' is not recognised, ignoring: %s", name);
    return ((void *)0);
}

variable_types:
name
char *

variable_types: struct modVolumeResponse_t { char *name; void (*help)(); int (*init)(); void (*process)(double *volume_level); void (*deinit)(); } **


getmodCommand

decompiled_code:
const char **__fastcall getmodCommand(char *s1)
{
const char **v1; // rbx
const char ***v2; // rbp

if ( !s1 )
return 0LL;
v1 = (const char **)modCommandList;
if ( modCommandList )
{
v2 = (const char ***)&modCommandList;
while ( strcasecmp(s1, *v1) )
{
v1 = *++v2;
if ( !*v2 )
goto LABEL_6;
}
}
else
{
LABEL_6:
syslog(4, "[NOTICE] Setting 'command_mod.type' is not recognised, ignoring: %s", s1);
v1 = 0LL;
}
return v1;
}

canonical_decompiled_code:
const char **__fastcall func2(char *s1)
{
const char **v1; // rbx
const char ***v2; // rbp

if ( !s1 )
return 0LL;
v1 = (const char **)modCommandList;
if ( modCommandList )
{
v2 = (const char ***)&modCommandList;
while ( strcasecmp(s1, *v1) )
{
v1 = *++v2;
if ( !*v2 )
goto LABEL_6;
}
}
else
{
LABEL_6:
syslog(4, "[NOTICE] Setting 'command_mod.type' is not recognised, ignoring: %s", s1);
v1 = 0LL;
}
return v1;
}

original_code:
static modCommand_t *getmodCommand(const char *name) {
    modCommand_t **modCommand;
    if (!name)
        return ((void *)0);
    for (modCommand=modCommandList; *modCommand; modCommand++)
        if (!strcasecmp(name, (*modCommand)->name))
            return *modCommand;
    syslog(4, "[NOTICE] Setting 'command_mod.type' is not recognised, ignoring: %s", name);
    return ((void *)0);
}

canonical_original_code:
static struct modCommand_t *getmodCommand(char *name) {
    struct modCommand_t **modCommand;
    if (!name)
        return ((void *)0);
    for (modCommand=modCommandList; *modCommand; modCommand++)
        if (!strcasecmp(name, (*modCommand)->name))
            return *modCommand;
    syslog(4, "[NOTICE] Setting 'command_mod.type' is not recognised, ignoring: %s", name);
    return ((void *)0);
}

variable_types: struct modCommand_t { char *name; void (*help)(); int (*init)(int x, ...); void (*produce)(void *message); int (*process)(void *command, int command_length); void (*deinit)(); } **


deinit

decompiled_code:
void deinit()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
static void deinit(void) {
}

canonical_original_code:
static void deinit() {
}

return_type: void


init

decompiled_code:
__int64 init()
{
__int64 v1; // rbx
const char **v2; // rax
__int64 v3; // rbx
const char **v4; // rax
char *s1[2]; // [rsp+8h] [rbp-10h] BYREF

s1[0] = 0LL;
if ( (unsigned int)config_lookup_string(&config, "volume.response.mode", s1) )
{
v1 = common_data[19];
v2 = getModVolumeResponse(s1[0]);
*(_QWORD *)(v1 + 8) = v2;
if ( v2 )
syslog(6, "[OK] volume.response.mode: %s", s1[0]);
}
if ( (unsigned int)config_lookup_string(&config, "command_mod.type", s1) )
{
v3 = common_data[19];
v4 = getmodCommand(s1[0]);
*(_QWORD *)(v3 + 16) = v4;
if ( v4 )
syslog(6, "[OK] command_mod.type: %s", s1[0]);
}
return 0LL;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 v1; // rbx
const char **v2; // rax
__int64 v3; // rbx
const char **v4; // rax
char *s1[2]; // [rsp+8h] [rbp-10h] BYREF

s1[0] = 0LL;
if ( (unsigned int)config_lookup_string(&config, "volume.response.mode", s1) )
{
v1 = common_data[19];
v2 = func1(s1[0]);
*(_QWORD *)(v1 + 8) = v2;
if ( v2 )
syslog(6, "[OK] volume.response.mode: %s", s1[0]);
}
if ( (unsigned int)config_lookup_string(&config, "command_mod.type", s1) )
{
v3 = common_data[19];
v4 = func2(s1[0]);
*(_QWORD *)(v3 + 16) = v4;
if ( v4 )
syslog(6, "[OK] command_mod.type: %s", s1[0]);
}
return 0LL;
}

original_code:
static int init(void) {
    const char* conf_value = ((void *)0);
    if(config_lookup_string(&config, "volume.response.mode", &conf_value) != (0) &&
    (common_data.mod->volumeResponse = getModVolumeResponse(conf_value))) {
        syslog(6, "[OK] volume.response.mode: %s", conf_value);
    }
    if(config_lookup_string(&config, "command_mod.type", &conf_value) != (0) &&
    (common_data.mod->command = getmodCommand(conf_value))) {
        syslog(6, "[OK] command_mod.type: %s", conf_value);
    }
    return 0;
}

canonical_original_code:
static int init() {
    char *conf_value = ((void *)0);
    if(config_lookup_string(&config, "volume.response.mode", &conf_value) != (0) &&
    (common_data.mod->volumeResponse = getModVolumeResponse(conf_value))) {
        syslog(6, "[OK] volume.response.mode: %s", conf_value);
    }
    if(config_lookup_string(&config, "command_mod.type", &conf_value) != (0) &&
    (common_data.mod->command = getmodCommand(conf_value))) {
        syslog(6, "[OK] command_mod.type: %s", conf_value);
    }
    return 0;
}


listen

decompiled_code:
void __fastcall __noreturn listen(__sigset_t *newmask)
{
__int64 v1; // rbx
int *v2; // rax
int v3; // eax
ssize_t v4; // rax
ssize_t v5; // rbp
int *v6; // rax
char *v7; // rax
char buf[104]; // [rsp+0h] [rbp-88h] BYREF
struct pollfd fds; // [rsp+68h] [rbp-20h] BYREF

if ( pthread_sigmask(0, newmask, 0LL) < 0 )
{
v2 = _errno_location();
syslog(3, "Failed to ignore signals in listen: %i", (unsigned int)*v2);
pthread_kill(mainThread, 15);
pause();
}
fds.fd = interfaceFD;
fds.events = 1;
LODWORD(v1) = 0;
while ( 1 )
{
v3 = poll(&fds, 1uLL, -1);
if ( v3 < 0 )
{
v6 = _errno_location();
v7 = strerror(*v6);
syslog(3, "Failed to poll serial interface: %s", v7);
pthread_kill(mainThread, 15);
pause();
}
else if ( !v3 )
{
goto LABEL_4;
}
if ( (fds.revents & 1) != 0 )
{
v4 = read(interfaceFD, &buf[(int)v1], 99 - (int)v1);
v5 = v4;
if ( v4 > 0 )
{
buf[v4 + (int)v1] = 0;
v1 = (*(unsigned int (__fastcall **)(char *))(common_data[16] + 56LL))(buf);
syslog(7, "Leftovers in buffer (bytes read, #leftovers): %s (%i, %i)", buf, v5, v1);
}
}
LABEL_4:
if ( (int)v1 >= 50 )
LODWORD(v1) = 0;
}
}

canonical_decompiled_code:
void __fastcall __noreturn func0(__sigset_t *newmask)
{
__int64 v1; // rbx
int *v2; // rax
int v3; // eax
ssize_t v4; // rax
ssize_t v5; // rbp
int *v6; // rax
char *v7; // rax
char buf[104]; // [rsp+0h] [rbp-88h] BYREF
struct pollfd fds; // [rsp+68h] [rbp-20h] BYREF

if ( pthread_sigmask(0, newmask, 0LL) < 0 )
{
v2 = _errno_location();
syslog(3, "Failed to ignore signals in listen: %i", (unsigned int)*v2);
pthread_kill(mainThread, 15);
pause();
}
fds.fd = interfaceFD;
fds.events = 1;
LODWORD(v1) = 0;
while ( 1 )
{
v3 = poll(&fds, 1uLL, -1);
if ( v3 < 0 )
{
v6 = _errno_location();
v7 = strerror(*v6);
syslog(3, "Failed to poll serial interface: %s", v7);
pthread_kill(mainThread, 15);
pause();
}
else if ( !v3 )
{
goto LABEL_4;
}
if ( (fds.revents & 1) != 0 )
{
v4 = read(interfaceFD, &buf[(int)v1], 99 - (int)v1);
v5 = v4;
if ( v4 > 0 )
{
buf[v4 + (int)v1] = 0;
v1 = (*(unsigned int (__fastcall **)(char *))(common_data[16] + 56LL))(buf);
syslog(7, "Leftovers in buffer (bytes read, #leftovers): %s (%i, %i)", buf, v5, v1);
}
}
LABEL_4:
if ( (int)v1 >= 50 )
LODWORD(v1) = 0;
}
}

original_code:
static void *listen(void *arg) {
    sigset_t *thread_sigmask = (sigset_t *)arg;
    if(pthread_sigmask(0, thread_sigmask, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals in listen: %i", (*__errno_location ()));
        pthread_kill(mainThread, 15);
        pause();
    }
    struct pollfd pollFD[1];
    pollFD[0].fd = interfaceFD;
    pollFD[0].events = 0x001;
    ssize_t bytesRead;
    unsigned char interfaceRxBuffer[100];
    unsigned char *interfaceRxPtr;
    int leftovers = 0;
    int status = 0;
    while(1) {
        interfaceRxPtr = interfaceRxBuffer;
        if(leftovers >= (100/2))
            leftovers = 0;
        interfaceRxPtr += leftovers;
        status = poll(pollFD, 1, -1);
        if(status < 0) {
            syslog(3, "Failed to poll serial interface: %s", strerror((*__errno_location ())));
            pthread_kill(mainThread, 15);
            pause();
        }
        else if(status == 0)
            continue;
        if(pollFD[0].revents & 0x001) {
            bytesRead = read(interfaceFD, interfaceRxPtr, 100 -1-leftovers);
            if(bytesRead <= 0)
                continue;
            interfaceRxBuffer[bytesRead+leftovers] = '\0';
            leftovers = common_data.process->strip_raw_input(interfaceRxBuffer, bytesRead+leftovers);
            syslog(7, "Leftovers in buffer (bytes read, #leftovers): %s (%i, %i)", interfaceRxBuffer, bytesRead, leftovers);
        }
    }
}

canonical_original_code:
static void *listen(void *arg) {
    struct __sigset_t *thread_sigmask = (sigset_t *)arg;
    if(pthread_sigmask(0, thread_sigmask, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals in listen: %i", (*__errno_location ()));
        pthread_kill(mainThread, 15);
        pause();
    }
    struct pollfd pollFD[1];
    pollFD[0].fd = interfaceFD;
    pollFD[0].events = 0x001;
    long bytesRead;
    unsigned char interfaceRxBuffer[100];
    unsigned char *interfaceRxPtr;
    int leftovers = 0;
    int status = 0;
    while(1) {
        interfaceRxPtr = interfaceRxBuffer;
        if(leftovers >= (100/2))
            leftovers = 0;
        interfaceRxPtr += leftovers;
        status = poll(pollFD, 1, -1);
        if(status < 0) {
            syslog(3, "Failed to poll serial interface: %s", strerror((*__errno_location ())));
            pthread_kill(mainThread, 15);
            pause();
        }
        else if(status == 0)
            continue;
        if(pollFD[0].revents & 0x001) {
            bytesRead = read(interfaceFD, interfaceRxPtr, 100 -1-leftovers);
            if(bytesRead <= 0)
                continue;
            interfaceRxBuffer[bytesRead+leftovers] = '\0';
            leftovers = common_data.process->strip_raw_input(interfaceRxBuffer, bytesRead+leftovers);
            syslog(7, "Leftovers in buffer (bytes read, #leftovers): %s (%i, %i)", interfaceRxBuffer, bytesRead, leftovers);
        }
    }
}

variable_types:
arg
void *

variable_types: struct __sigset_t { unsigned long __val[-1]; } *

variable_types: struct pollfd { int fd; short events; short revents; } [1]

variable_types: bytesRead long

variable_types:
interfaceRxBuffer
unsigned char [100]

variable_types:
interfaceRxPtr
unsigned char *

variable_types: leftovers int

return_type: void *


send

decompiled_code:
__int64 __fastcall send(void *buf, size_t n)
{
__int64 result; // rax
int *v3; // rax
char *v4; // rax

pthread_setcancelstate(1, 0LL);
pthread_mutex_lock(&interfaceLock);
if ( write(interfaceFD, buf, n) == -1 )
{
pthread_mutex_unlock(&interfaceLock);
pthread_setcancelstate(0, 0LL);
v3 = _errno_location();
v4 = strerror(*v3);
syslog(3, "Failed to write to serial port: %s", v4);
result = 1LL;
}
else
{
pthread_mutex_unlock(&interfaceLock);
pthread_setcancelstate(0, 0LL);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *buf, size_t n)
{
__int64 result; // rax
int *v3; // rax
char *v4; // rax

pthread_setcancelstate(1, 0LL);
pthread_mutex_lock(&interfaceLock);
if ( write(interfaceFD, buf, n) == -1 )
{
pthread_mutex_unlock(&interfaceLock);
pthread_setcancelstate(0, 0LL);
v3 = _errno_location();
v4 = strerror(*v3);
syslog(3, "Failed to write to serial port: %s", v4);
result = 1LL;
}
else
{
pthread_mutex_unlock(&interfaceLock);
pthread_setcancelstate(0, 0LL);
result = 0LL;
}
return result;
}

original_code:
static int send(const void *message, size_t messageLength) {
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, ((void *)0));
    pthread_mutex_lock(&interfaceLock);
    if(write(interfaceFD, message, messageLength) == -1) {
        pthread_mutex_unlock(&interfaceLock);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
        syslog(3, "Failed to write to serial port: %s", strerror((*__errno_location ())));
        return 1;
    }
    pthread_mutex_unlock(&interfaceLock);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
    return 0;
}

canonical_original_code:
static int send(void *message, unsigned long messageLength) {
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, ((void *)0));
    pthread_mutex_lock(&interfaceLock);
    if(write(interfaceFD, message, messageLength) == -1) {
        pthread_mutex_unlock(&interfaceLock);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
        syslog(3, "Failed to write to serial port: %s", strerror((*__errno_location ())));
        return 1;
    }
    pthread_mutex_unlock(&interfaceLock);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
    return 0;
}

variable_types:
message
void *

variable_types:
messageLength
unsigned long


deinit

decompiled_code:
__int64 deinit()
{
int v0; // ebx

v0 = interfaceFD;
if ( interfaceFD > 0 )
{
tcsetattr(interfaceFD, 0, &termiosOriginalAttr);
close(v0);
}
pthread_mutex_destroy(&interfaceLock);
return 0LL;
}

canonical_decompiled_code:
__int64 func2()
{
int v0; // ebx

v0 = interfaceFD;
if ( interfaceFD > 0 )
{
tcsetattr(interfaceFD, 0, &termiosOriginalAttr);
close(v0);
}
pthread_mutex_destroy(&interfaceLock);
return 0LL;
}

original_code:
static int deinit(void) {
    if(interfaceFD > 0) {
        tcsetattr(interfaceFD, 0, &termiosOriginalAttr);
        close(interfaceFD);
    }
    pthread_mutex_destroy(&interfaceLock);
    return 0;
}

canonical_original_code:
static int deinit() {
    if(interfaceFD > 0) {
        tcsetattr(interfaceFD, 0, &termiosOriginalAttr);
        close(interfaceFD);
    }
    pthread_mutex_destroy(&interfaceLock);
    return 0;
}


init

decompiled_code:
unsigned int init()
{
unsigned int result; // eax
int v1; // eax
int v2; // ebx
speed_t v3; // ebx
unsigned int v4; // ebx
char *v5; // rax
int v6; // ecx
tcflag_t v7; // edx
tcflag_t v8; // eax
unsigned int v9; // ebx
char *v10; // rax
int v11; // [rsp+8h] [rbp-60h] BYREF
int v12; // [rsp+Ch] [rbp-5Ch] BYREF
int v13; // [rsp+10h] [rbp-58h] BYREF
int v14; // [rsp+14h] [rbp-54h] BYREF
char *file; // [rsp+18h] [rbp-50h] BYREF
struct termios termios_p; // [rsp+20h] [rbp-48h] BYREF

result = validateConfigString(&config, "serial_port", &file, 0xFFFFFFFFLL);
if ( result == 1 )
return result;
v1 = open(file, 526594);
v2 = v1;
interfaceFD = v1;
if ( v1 < 0 )
{
v4 = *_errno_location();
v5 = strerror(v4);
syslog(3, "Failed to open serial device %s: %s (%i)", file, v5, v4);
return 1;
}
tcgetattr(v1, &termiosOriginalAttr);
tcgetattr(v2, &termios_p);
validateConfigBool(&config, "serial_parity", &v14, 0LL);
validateConfigBool(&config, "serial_even", &v13, 0LL);
validateConfigBool(&config, "serial_2stop", &v12, 0LL);
result = validateConfigInt(&config, "serial_baud", &v11, 0xFFFFFFFFLL, 0LL, 0LL, -1LL);
if ( result == 1 )
return result;
if ( v11 == 9600 )
{
v3 = 13;
goto LABEL_19;
}
if ( v11 <= 9600 )
{
if ( v11 == 2400 )
{
v3 = 11;
goto LABEL_19;
}
if ( v11 <= 2400 )
{
if ( v11 == 1200 )
{
v3 = 9;
goto LABEL_19;
}
if ( v11 == 1800 )
{
v3 = 10;
goto LABEL_19;
}
}
else
{
v3 = 12;
if ( v11 == 4800 )
goto LABEL_19;
}
goto LABEL_15;
}
if ( v11 == 57600 )
{
v3 = 4097;
goto LABEL_19;
}
if ( v11 <= 57600 )
{
if ( v11 == 19200 )
{
v3 = 14;
goto LABEL_19;
}
if ( v11 == 38400 )
{
v3 = 15;
goto LABEL_19;
}
LABEL_15:
syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", (unsigned int)v11);
return 1;
}
v3 = 4098;
if ( v11 != 115200 )
goto LABEL_15;
LABEL_19:
result = validateConfigInt(&config, "serial_bits", &v11, 0xFFFFFFFFLL, 0LL, 0LL, 8LL);
if ( result == 1 )
return result;
if ( v11 == 7 )
{
v6 = 32;
goto LABEL_25;
}
if ( v11 > 7 )
{
v6 = 48;
if ( v11 == 8 )
goto LABEL_25;
LABEL_43:
syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", (unsigned int)v11);
return 1;
}
if ( v11 == 5 )
{
v6 = 0;
goto LABEL_25;
}
if ( v11 != 6 )
goto LABEL_43;
v6 = 16;
LABEL_25:
v7 = termios_p.c_cflag;
if ( v14 )
{
termios_p.c_iflag |= 0x30u;
if ( v13 )
{
BYTE1(v7) = BYTE1(termios_p.c_cflag) & 0xFD;
termios_p.c_cflag = v7 | 0x980;
}
else
{
termios_p.c_cflag |= 0xB80u;
}
}
else
{
BYTE1(v7) = BYTE1(termios_p.c_cflag) & 0xFE;
termios_p.c_cflag = v7 | 0x880;
}
if ( v12 )
v8 = termios_p.c_cflag | 0x40;
else
v8 = termios_p.c_cflag & 0xFFFFFFBF;
termios_p.c_lflag &= 0xFFFFFFE4;
termios_p.c_cflag = v6 | v8 & 0x7FFFFFCF;
termios_p.c_iflag &= 0xFFFFE23F;
termios_p.c_oflag &= 0xFFFFFFFE;
termios_p.c_cc[6] = 1;
termios_p.c_cc[5] = 0;
if ( cfsetospeed(&termios_p, v3) < 0 )
{
syslog(3, "Failed to set serial output baud rate");
result = 1;
}
else if ( cfsetispeed(&termios_p, v3) < 0 )
{
syslog(3, "Failed to set serial input baud rate");
result = 1;
}
else if ( tcsetattr(interfaceFD, 0, &termios_p) == -1 )
{
v9 = *_errno_location();
v10 = strerror(v9);
syslog(3, "Failed to set attributes for serial device %s: %s (%i)", file, v10, v9);
result = 1;
}
else
{
result = pthread_mutex_init(&interfaceLock, 0LL);
if ( result )
{
syslog(3, "Failed to create interface mutex: %i", result);
result = 1;
}
}
return result;
}

canonical_decompiled_code:
unsigned int func3()
{
unsigned int result; // eax
int v1; // eax
int v2; // ebx
speed_t v3; // ebx
unsigned int v4; // ebx
char *v5; // rax
int v6; // ecx
tcflag_t v7; // edx
tcflag_t v8; // eax
unsigned int v9; // ebx
char *v10; // rax
int v11; // [rsp+8h] [rbp-60h] BYREF
int v12; // [rsp+Ch] [rbp-5Ch] BYREF
int v13; // [rsp+10h] [rbp-58h] BYREF
int v14; // [rsp+14h] [rbp-54h] BYREF
char *file; // [rsp+18h] [rbp-50h] BYREF
struct termios termios_p; // [rsp+20h] [rbp-48h] BYREF

result = validateConfigString(&config, "serial_port", &file, 0xFFFFFFFFLL);
if ( result == 1 )
return result;
v1 = open(file, 526594);
v2 = v1;
interfaceFD = v1;
if ( v1 < 0 )
{
v4 = *_errno_location();
v5 = strerror(v4);
syslog(3, "Failed to open serial device %s: %s (%i)", file, v5, v4);
return 1;
}
tcgetattr(v1, &termiosOriginalAttr);
tcgetattr(v2, &termios_p);
validateConfigBool(&config, "serial_parity", &v14, 0LL);
validateConfigBool(&config, "serial_even", &v13, 0LL);
validateConfigBool(&config, "serial_2stop", &v12, 0LL);
result = validateConfigInt(&config, "serial_baud", &v11, 0xFFFFFFFFLL, 0LL, 0LL, -1LL);
if ( result == 1 )
return result;
if ( v11 == 9600 )
{
v3 = 13;
goto LABEL_19;
}
if ( v11 <= 9600 )
{
if ( v11 == 2400 )
{
v3 = 11;
goto LABEL_19;
}
if ( v11 <= 2400 )
{
if ( v11 == 1200 )
{
v3 = 9;
goto LABEL_19;
}
if ( v11 == 1800 )
{
v3 = 10;
goto LABEL_19;
}
}
else
{
v3 = 12;
if ( v11 == 4800 )
goto LABEL_19;
}
goto LABEL_15;
}
if ( v11 == 57600 )
{
v3 = 4097;
goto LABEL_19;
}
if ( v11 <= 57600 )
{
if ( v11 == 19200 )
{
v3 = 14;
goto LABEL_19;
}
if ( v11 == 38400 )
{
v3 = 15;
goto LABEL_19;
}
LABEL_15:
syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", (unsigned int)v11);
return 1;
}
v3 = 4098;
if ( v11 != 115200 )
goto LABEL_15;
LABEL_19:
result = validateConfigInt(&config, "serial_bits", &v11, 0xFFFFFFFFLL, 0LL, 0LL, 8LL);
if ( result == 1 )
return result;
if ( v11 == 7 )
{
v6 = 32;
goto LABEL_25;
}
if ( v11 > 7 )
{
v6 = 48;
if ( v11 == 8 )
goto LABEL_25;
LABEL_43:
syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", (unsigned int)v11);
return 1;
}
if ( v11 == 5 )
{
v6 = 0;
goto LABEL_25;
}
if ( v11 != 6 )
goto LABEL_43;
v6 = 16;
LABEL_25:
v7 = termios_p.c_cflag;
if ( v14 )
{
termios_p.c_iflag |= 0x30u;
if ( v13 )
{
BYTE1(v7) = BYTE1(termios_p.c_cflag) & 0xFD;
termios_p.c_cflag = v7 | 0x980;
}
else
{
termios_p.c_cflag |= 0xB80u;
}
}
else
{
BYTE1(v7) = BYTE1(termios_p.c_cflag) & 0xFE;
termios_p.c_cflag = v7 | 0x880;
}
if ( v12 )
v8 = termios_p.c_cflag | 0x40;
else
v8 = termios_p.c_cflag & 0xFFFFFFBF;
termios_p.c_lflag &= 0xFFFFFFE4;
termios_p.c_cflag = v6 | v8 & 0x7FFFFFCF;
termios_p.c_iflag &= 0xFFFFE23F;
termios_p.c_oflag &= 0xFFFFFFFE;
termios_p.c_cc[6] = 1;
termios_p.c_cc[5] = 0;
if ( cfsetospeed(&termios_p, v3) < 0 )
{
syslog(3, "Failed to set serial output baud rate");
result = 1;
}
else if ( cfsetispeed(&termios_p, v3) < 0 )
{
syslog(3, "Failed to set serial input baud rate");
result = 1;
}
else if ( tcsetattr(interfaceFD, 0, &termios_p) == -1 )
{
v9 = *_errno_location();
v10 = strerror(v9);
syslog(3, "Failed to set attributes for serial device %s: %s (%i)", file, v10, v9);
result = 1;
}
else
{
result = pthread_mutex_init(&interfaceLock, 0LL);
if ( result )
{
syslog(3, "Failed to create interface mutex: %i", result);
result = 1;
}
}
return result;
}

original_code:
static int init(void) {
    struct termios termiosNewAttr;
    const char *serialDevice;
    speed_t serialSpeed;
    tcflag_t serialBits;
    int serialParity, serialEven, serial2Stop, intSetting, status;
    if(validateConfigString(&config, "serial_port", &serialDevice, -1) == 1)
        return 1;
    interfaceFD = open(serialDevice, 02| 0400 | 04000 | 02000000);
    if(interfaceFD < 0) {
        syslog(3, "Failed to open serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    tcgetattr(interfaceFD, &termiosOriginalAttr);
    tcgetattr(interfaceFD, &termiosNewAttr);
    validateConfigBool(&config, "serial_parity", &serialParity, 0);
    validateConfigBool(&config, "serial_even", &serialEven, 0);
    validateConfigBool(&config, "serial_2stop", &serial2Stop, 0);
    if(validateConfigInt(&config, "serial_baud", &intSetting, -1, 0, 0, -1) == 1)
        return 1;
    else
        switch(intSetting) {
            case 1200:
                serialSpeed = 0000011;
                break;
            case 1800:
                serialSpeed = 0000012;
                break;
            case 2400:
                serialSpeed = 0000013;
                break;
            case 4800:
                serialSpeed = 0000014;
                break;
            case 9600:
                serialSpeed = 0000015;
                break;
            case 19200:
                serialSpeed = 0000016;
                break;
            case 38400:
                serialSpeed = 0000017;
                break;
            case 57600:
                serialSpeed = 0010001;
                break;
            case 115200:
                serialSpeed = 0010002;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", intSetting);
                return 1;
        }
    if(validateConfigInt(&config, "serial_bits", &intSetting, -1, 0, 0, 8) == 1)
        return 1;
    else
        switch(intSetting) {
            case 5:
                serialBits = 0000000;
                break;
            case 6:
                serialBits = 0000020;
                break;
            case 7:
                serialBits = 0000040;
                break;
            case 8:
                serialBits = 0000060;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", intSetting);
                return 1;
        }
    termiosNewAttr.c_cflag |= (0004000 | 0000200);
    if(serialParity == 0)
        termiosNewAttr.c_cflag &= ~0000400;
    else {
        termiosNewAttr.c_cflag |= 0000400;
        termiosNewAttr.c_iflag |= (0000020 | 0000040);
        if(serialEven == 0)
            termiosNewAttr.c_cflag |= 0001000;
        else
            termiosNewAttr.c_cflag &= ~0001000;
    }
    if(serial2Stop == 0)
        termiosNewAttr.c_cflag &= ~0000100;
    else
        termiosNewAttr.c_cflag |= 0000100;
    termiosNewAttr.c_cflag &= ~0000060;
    termiosNewAttr.c_cflag |= serialBits;
    termiosNewAttr.c_lflag &= ~(0000002 | 0000010 | 0000020 | 0000001);
    termiosNewAttr.c_cflag &= ~020000000000;
    termiosNewAttr.c_iflag &= ~(0002000 | 0010000 | 0004000);
    termiosNewAttr.c_iflag &= ~(0000400 | 0000200 | 0000100);
    termiosNewAttr.c_oflag &= ~0000001;
    termiosNewAttr.c_cc[6] = 1;
    termiosNewAttr.c_cc[5] = 0;
    if((cfsetospeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial output baud rate");
        return 1;
    }
    if((cfsetispeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial input baud rate");
        return 1;
    }
    if(tcsetattr(interfaceFD, 0, &termiosNewAttr) == -1) {
        syslog(3, "Failed to set attributes for serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    if((status = pthread_mutex_init(&interfaceLock, ((void *)0))) != 0) {
        syslog(3, "Failed to create interface mutex: %i", status);
        return 1;
    }
    return 0;
}

canonical_original_code:
static int init() {
    struct termios termiosNewAttr;
    char *serialDevice;
    unsigned int serialSpeed;
    unsigned int serialBits;
    int serialParity; int serialEven; int serial2Stop; int intSetting; int status;
    if(validateConfigString(&config, "serial_port", &serialDevice, -1) == 1)
        return 1;
    interfaceFD = open(serialDevice, 02| 0400 | 04000 | 02000000);
    if(interfaceFD < 0) {
        syslog(3, "Failed to open serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    tcgetattr(interfaceFD, &termiosOriginalAttr);
    tcgetattr(interfaceFD, &termiosNewAttr);
    validateConfigBool(&config, "serial_parity", &serialParity, 0);
    validateConfigBool(&config, "serial_even", &serialEven, 0);
    validateConfigBool(&config, "serial_2stop", &serial2Stop, 0);
    if(validateConfigInt(&config, "serial_baud", &intSetting, -1, 0, 0, -1) == 1)
        return 1;
    else
        switch(intSetting) {
            case 1200:
                serialSpeed = 0000011;
                break;
            case 1800:
                serialSpeed = 0000012;
                break;
            case 2400:
                serialSpeed = 0000013;
                break;
            case 4800:
                serialSpeed = 0000014;
                break;
            case 9600:
                serialSpeed = 0000015;
                break;
            case 19200:
                serialSpeed = 0000016;
                break;
            case 38400:
                serialSpeed = 0000017;
                break;
            case 57600:
                serialSpeed = 0010001;
                break;
            case 115200:
                serialSpeed = 0010002;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", intSetting);
                return 1;
        }
    if(validateConfigInt(&config, "serial_bits", &intSetting, -1, 0, 0, 8) == 1)
        return 1;
    else
        switch(intSetting) {
            case 5:
                serialBits = 0000000;
                break;
            case 6:
                serialBits = 0000020;
                break;
            case 7:
                serialBits = 0000040;
                break;
            case 8:
                serialBits = 0000060;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", intSetting);
                return 1;
        }
    termiosNewAttr.c_cflag |= (0004000 | 0000200);
    if(serialParity == 0)
        termiosNewAttr.c_cflag &= ~0000400;
    else {
        termiosNewAttr.c_cflag |= 0000400;
        termiosNewAttr.c_iflag |= (0000020 | 0000040);
        if(serialEven == 0)
            termiosNewAttr.c_cflag |= 0001000;
        else
            termiosNewAttr.c_cflag &= ~0001000;
    }
    if(serial2Stop == 0)
        termiosNewAttr.c_cflag &= ~0000100;
    else
        termiosNewAttr.c_cflag |= 0000100;
    termiosNewAttr.c_cflag &= ~0000060;
    termiosNewAttr.c_cflag |= serialBits;
    termiosNewAttr.c_lflag &= ~(0000002 | 0000010 | 0000020 | 0000001);
    termiosNewAttr.c_cflag &= ~020000000000;
    termiosNewAttr.c_iflag &= ~(0002000 | 0010000 | 0004000);
    termiosNewAttr.c_iflag &= ~(0000400 | 0000200 | 0000100);
    termiosNewAttr.c_oflag &= ~0000001;
    termiosNewAttr.c_cc[6] = 1;
    termiosNewAttr.c_cc[5] = 0;
    if((cfsetospeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial output baud rate");
        return 1;
    }
    if((cfsetispeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial input baud rate");
        return 1;
    }
    if(tcsetattr(interfaceFD, 0, &termiosNewAttr) == -1) {
        syslog(3, "Failed to set attributes for serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    if((status = pthread_mutex_init(&interfaceLock, ((void *)0))) != 0) {
        syslog(3, "Failed to create interface mutex: %i", status);
        return 1;
    }
    return 0;
}

variable_types: struct termios { unsigned int c_iflag; unsigned int c_oflag; unsigned int c_cflag; unsigned int c_lflag; unsigned char c_line; unsigned char c_cc[32]; unsigned int c_ispeed; unsigned int c_ospeed; }

variable_types:
serialDevice
char *

variable_types:
serialSpeed
unsigned int

variable_types:
serialBits
unsigned int

variable_types: serialParity int

variable_types: serialEven int

variable_types: intSetting int

variable_types: status int


help

decompiled_code:
int help()
{
return puts("Serial");
}

canonical_decompiled_code:
int func4()
{
return puts("Serial");
}

original_code:
static void help(void) {
    printf("Serial\n"
          );
}

canonical_original_code:
static void help() {
    printf("Serial\n"
          );
}


setExternalVolume

decompiled_code:
void __fastcall __noreturn setExternalVolume(void *a1)
{
double v1; // xmm0_8
__int64 i; // xmm1_8
int *v3; // rax
__int64 v4; // rdx
__int64 v5; // rdi
int v6; // esi
double v7; // xmm0_8
__int64 v8; // [rsp+0h] [rbp-18h] BYREF
__int64 v9[2]; // [rsp+8h] [rbp-10h] BYREF

if ( pthread_sigmask(0, &thread_sigmask, 0LL) < 0 )
{
v3 = _errno_location();
syslog(3, "Failed to ignore signals in smoothVolume: %i", (unsigned int)*v3);
pthread_kill(mainThread, 15);
pause();
}
if ( resetInProgress == 1 )
resetVolume();
v1 = *(double *)&actualVolume;
for ( i = requestedVolume; *(double *)&actualVolume != *(double *)&requestedVolume; i = requestedVolume )
{
if ( *((_DWORD *)&common_data + 1) )
{
if ( v1 <= *(double *)&i )
{
if ( *(double *)&i - v1 <= *(float *)&dword_C40 )
actualVolume = i;
else
*(double *)&actualVolume = v1 + *(float *)&dword_C40;
}
else if ( v1 - *(double *)&i <= *(float *)&dword_C40 )
{
actualVolume = i;
}
else
{
*(double *)&actualVolume = v1 - *(float *)&dword_C40;
}
v4 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v4 + 24), "log") )
{
v8 = (unsigned int)(int)*(double *)&actualVolume;
(*(void (__fastcall **)(__int64 *, __int64 *))(v4 + 56))(&v8, v9);
}
else
{
v9[0] = actualVolume;
}
qword_C38(v9);
}
else
{
if ( v1 <= *(double *)&i )
{
v5 = qword_C28;
v6 = dword_C34;
v7 = v1 + 1.0;
}
else
{
v5 = localSettings;
v6 = dword_C30;
v7 = v1 - 1.0;
}
actualVolume = *(_QWORD *)&v7;
if ( (*(unsigned int (__fastcall **)(__int64, _QWORD))(*((_QWORD *)&common_data + 17) + 40LL))(v5, v6) == 1 )
{
syslog(3, "Failed to send volume command");
pthread_kill(mainThread, 15);
pause();
}
}
syslog(
7,
"Smooth volume level status: current (requested): %.2f (%.2f)",
*(double *)&actualVolume,
*(double *)&requestedVolume);
clock_nanosleep(1, 0, &req, 0LL);
v1 = *(double *)&actualVolume;
}
pthread_exit(0LL);
}

canonical_decompiled_code:
void __fastcall __noreturn func4(void *a1)
{
double v1; // xmm0_8
__int64 i; // xmm1_8
int *v3; // rax
__int64 v4; // rdx
__int64 v5; // rdi
int v6; // esi
double v7; // xmm0_8
__int64 v8; // [rsp+0h] [rbp-18h] BYREF
__int64 v9[2]; // [rsp+8h] [rbp-10h] BYREF

if ( pthread_sigmask(0, &thread_sigmask, 0LL) < 0 )
{
v3 = _errno_location();
syslog(3, "Failed to ignore signals in smoothVolume: %i", (unsigned int)*v3);
pthread_kill(mainThread, 15);
pause();
}
if ( resetInProgress == 1 )
func3();
v1 = *(double *)&actualVolume;
for ( i = requestedVolume; *(double *)&actualVolume != *(double *)&requestedVolume; i = requestedVolume )
{
if ( *((_DWORD *)&common_data + 1) )
{
if ( v1 <= *(double *)&i )
{
if ( *(double *)&i - v1 <= *(float *)&dword_C40 )
actualVolume = i;
else
*(double *)&actualVolume = v1 + *(float *)&dword_C40;
}
else if ( v1 - *(double *)&i <= *(float *)&dword_C40 )
{
actualVolume = i;
}
else
{
*(double *)&actualVolume = v1 - *(float *)&dword_C40;
}
v4 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v4 + 24), "log") )
{
v8 = (unsigned int)(int)*(double *)&actualVolume;
(*(void (__fastcall **)(__int64 *, __int64 *))(v4 + 56))(&v8, v9);
}
else
{
v9[0] = actualVolume;
}
qword_C38(v9);
}
else
{
if ( v1 <= *(double *)&i )
{
v5 = qword_C28;
v6 = dword_C34;
v7 = v1 + 1.0;
}
else
{
v5 = localSettings;
v6 = dword_C30;
v7 = v1 - 1.0;
}
actualVolume = *(_QWORD *)&v7;
if ( (*(unsigned int (__fastcall **)(__int64, _QWORD))(*((_QWORD *)&common_data + 17) + 40LL))(v5, v6) == 1 )
{
syslog(3, "Failed to send volume command");
pthread_kill(mainThread, 15);
pause();
}
}
syslog(
7,
"Smooth volume level status: current (requested): %.2f (%.2f)",
*(double *)&actualVolume,
*(double *)&requestedVolume);
clock_nanosleep(1, 0, &req, 0LL);
v1 = *(double *)&actualVolume;
}
pthread_exit(0LL);
}

original_code:
static void *setExternalVolume(void *unused) {
    double actualExternalVolume;
    if(pthread_sigmask(0, &thread_sigmask, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals in smoothVolume: %i", (*__errno_location ()));
        pthread_kill(mainThread, 15);
        pause();
    }
    if(resetInProgress == 1)
        resetVolume();
    while(actualVolume != requestedVolume) {
        if(common_data.discrete_volume) {
            if(actualVolume > requestedVolume) {
                if((actualVolume - requestedVolume) > localSettings.volumeMutation) {
                    actualVolume -= localSettings.volumeMutation;
                }
                else {
                    actualVolume = requestedVolume;
                }
            }
            else {
                if((requestedVolume - actualVolume) > localSettings.volumeMutation) {
                    actualVolume += localSettings.volumeMutation;
                }
                else {
                    actualVolume = requestedVolume;
                }
            }
            if(strcmp(common_data.volume->curve, "log") == 0) {
                long x = (long)actualVolume;
                common_data.volume->convertInternal2External(&x, &actualExternalVolume);
            }
            else
                actualExternalVolume = actualVolume;
            localSettings.setDescreteVolume(&actualExternalVolume);
        }
        else {
            char *volCurrent;
            int volLenCurrent = 0;
            if(actualVolume > requestedVolume) {
                volCurrent = localSettings.volMin;
                volLenCurrent = localSettings.volMinLen;
                actualVolume--;
            }
            else {
                volCurrent = localSettings.volPlus;
                volLenCurrent = localSettings.volPlusLen;
                actualVolume++;
            }
            if(common_data.interface->send(volCurrent, volLenCurrent) == 1) {
                syslog(3, "Failed to send volume command");
                pthread_kill(mainThread, 15);
                pause();
            }
        }
        syslog(7, "Smooth volume level status: current (requested): %.2f (%.2f)", actualVolume, requestedVolume);
        clock_nanosleep(1, 0, &localSettings.timeout, ((void *)0));
    }
    pthread_exit(((void *)0));
}

variable_types:
unused
void *

variable_types: actualExternalVolume double

variable_types: x long

variable_types:
volCurrent
char *

variable_types: volLenCurrent int


deinit

decompiled_code:
int deinit()
{
pthread_t v0; // rbx
int *v2; // rbx
int v3; // eax
int *v4; // rax
char *v5; // rax
char *v6; // rax

v0 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( !pthread_kill(v0, 0) && pthread_cancel(setExternalVolumeThread) )
{
v4 = _errno_location();
v5 = strerror(*v4);
syslog(4, "Unable request cancelation for smoothVolume thread: %s", v5);
}
v2 = _errno_location();
v3 = pthread_join(setExternalVolumeThread, 0LL);
*v2 = v3;
if ( v3 )
{
v6 = strerror(v3);
syslog(4, "Unable to join smoothVolume thread: %s\n", v6);
}
setExternalVolumeThread = thisThread;
}
return pthread_attr_destroy(&thread_attr);
}

canonical_decompiled_code:
int func0()
{
pthread_t v0; // rbx
int *v2; // rbx
int v3; // eax
int *v4; // rax
char *v5; // rax
char *v6; // rax

v0 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( !pthread_kill(v0, 0) && pthread_cancel(setExternalVolumeThread) )
{
v4 = _errno_location();
v5 = strerror(*v4);
syslog(4, "Unable request cancelation for smoothVolume thread: %s", v5);
}
v2 = _errno_location();
v3 = pthread_join(setExternalVolumeThread, 0LL);
*v2 = v3;
if ( v3 )
{
v6 = strerror(v3);
syslog(4, "Unable to join smoothVolume thread: %s\n", v6);
}
setExternalVolumeThread = thisThread;
}
return pthread_attr_destroy(&thread_attr);
}

original_code:
static void deinit(void) {
    if(!pthread_equal(setExternalVolumeThread, thisThread)) {
        if(pthread_kill(setExternalVolumeThread, 0) == 0 && pthread_cancel(setExternalVolumeThread) != 0)
            syslog(4, "Unable request cancelation for smoothVolume thread: %s", strerror((*__errno_location ())));
        if(((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
            syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
        setExternalVolumeThread = thisThread;
    }
    pthread_attr_destroy(&thread_attr);
}

canonical_original_code:
static void deinit() {
    if(!pthread_equal(setExternalVolumeThread, thisThread)) {
        if(pthread_kill(setExternalVolumeThread, 0) == 0 && pthread_cancel(setExternalVolumeThread) != 0)
            syslog(4, "Unable request cancelation for smoothVolume thread: %s", strerror((*__errno_location ())));
        if(((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
            syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
        setExternalVolumeThread = thisThread;
    }
    pthread_attr_destroy(&thread_attr);
}


process

decompiled_code:
__int64 __fastcall process(_QWORD *a1)
{
__int64 v1; // rdx
int v2; // ebx
pthread_t v3; // rbp
unsigned int v4; // ebx
__int64 v6; // rdx
pthread_t v7; // rbx
int *v8; // rbp
int v9; // eax
char *v10; // rax
__int64 v11[4]; // [rsp+0h] [rbp-20h] BYREF

if ( !resetInProgress )
{
if ( !*((_DWORD *)&common_data + 1) && !*a1 )
{
clock_gettime(1, &timestampCurrent);
if ( dword_C48 && timestampCurrent.tv_sec - (__int64)timestampLastMute > dword_C48 )
{
timestampLastMute = (__int128)_mm_load_si128((const __m128i *)&timestampCurrent);
}
else
{
syslog(7, "Initiating volume reset");
resetInProgress = 1;
pthread_cancel(setExternalVolumeThread);
}
}
v1 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v1 + 24), "log") )
*(double *)&requestedVolume = (double)(int)*a1;
else
(*(void (__fastcall **)(_QWORD *, __int64 *))(v1 + 56))(a1, &requestedVolume);
v2 = *((_DWORD *)&common_data + 1);
if ( v2 )
{
v3 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( v2 != 1 )
{
LABEL_8:
v4 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( v4 )
{
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v4);
pthread_kill(mainThread, 15);
pause();
}
return 0LL;
}
LABEL_18:
v6 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v6 + 24), "log") )
{
(*(void (__fastcall **)(_QWORD, __int64 *))(v6 + 64))((unsigned int)((_DWORD)&common_data + 64), v11);
*(double *)&actualVolume = (double)SLODWORD(v11[0]);
}
else
{
actualVolume = *((_QWORD *)&common_data + 8);
}
LABEL_22:
v7 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
{
v8 = _errno_location();
v9 = pthread_join(v7, 0LL);
*v8 = v9;
if ( v9 )
{
v10 = strerror(v9);
syslog(4, "Unable to join smoothVolume thread: %s\n", v10);
}
}
goto LABEL_8;
}
}
else
{
*(double *)&requestedVolume = (double)(int)*(double *)&requestedVolume;
v3 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
goto LABEL_8;
}
if ( !(resetInProgress | pthread_kill(v3, 0)) )
return 0LL;
if ( *((_DWORD *)&common_data + 1) != 1 )
goto LABEL_22;
goto LABEL_18;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1)
{
__int64 v1; // rdx
int v2; // ebx
pthread_t v3; // rbp
unsigned int v4; // ebx
__int64 v6; // rdx
pthread_t v7; // rbx
int *v8; // rbp
int v9; // eax
char *v10; // rax
__int64 v11[4]; // [rsp+0h] [rbp-20h] BYREF

if ( !resetInProgress )
{
if ( !*((_DWORD *)&common_data + 1) && !*a1 )
{
clock_gettime(1, &timestampCurrent);
if ( dword_C48 && timestampCurrent.tv_sec - (__int64)timestampLastMute > dword_C48 )
{
timestampLastMute = (__int128)_mm_load_si128((const __m128i *)&timestampCurrent);
}
else
{
syslog(7, "Initiating volume reset");
resetInProgress = 1;
pthread_cancel(setExternalVolumeThread);
}
}
v1 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v1 + 24), "log") )
*(double *)&requestedVolume = (double)(int)*a1;
else
(*(void (__fastcall **)(_QWORD *, __int64 *))(v1 + 56))(a1, &requestedVolume);
v2 = *((_DWORD *)&common_data + 1);
if ( v2 )
{
v3 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( v2 != 1 )
{
LABEL_8:
v4 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( v4 )
{
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v4);
pthread_kill(mainThread, 15);
pause();
}
return 0LL;
}
LABEL_18:
v6 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v6 + 24), "log") )
{
(*(void (__fastcall **)(_QWORD, __int64 *))(v6 + 64))((unsigned int)((_DWORD)&common_data + 64), v11);
*(double *)&actualVolume = (double)SLODWORD(v11[0]);
}
else
{
actualVolume = *((_QWORD *)&common_data + 8);
}
LABEL_22:
v7 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
{
v8 = _errno_location();
v9 = pthread_join(v7, 0LL);
*v8 = v9;
if ( v9 )
{
v10 = strerror(v9);
syslog(4, "Unable to join smoothVolume thread: %s\n", v10);
}
}
goto LABEL_8;
}
}
else
{
*(double *)&requestedVolume = (double)(int)*(double *)&requestedVolume;
v3 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
goto LABEL_8;
}
if ( !(resetInProgress | pthread_kill(v3, 0)) )
return 0LL;
if ( *((_DWORD *)&common_data + 1) != 1 )
goto LABEL_22;
goto LABEL_18;
}
return 0LL;
}

original_code:
static int process(long *volumeInternal) {
    int status;
    if(resetInProgress)
        return 0;
    if(!common_data.discrete_volume && *volumeInternal == 0) {
        clock_gettime(1 , &timestampCurrent);
        if(!localSettings.resetInterval || (timestampCurrent.tv_sec - timestampLastMute.tv_sec) <= localSettings.resetInterval) {
            syslog(7, "Initiating volume reset");
            resetInProgress = 1;
            pthread_cancel(setExternalVolumeThread);
        }
        else
            timestampLastMute = timestampCurrent;
    }
    if(strcmp(common_data.volume->curve, "log") == 0) {
        requestedVolume = *volumeInternal;
    }
    else {
        common_data.volume->convertInternal2External(volumeInternal, &requestedVolume);
    }
    if(common_data.discrete_volume == 0) {
        requestedVolume = (int)requestedVolume;
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    pthread_kill(setExternalVolumeThread, 0) == 0 && !resetInProgress)
        return 0;
    if(common_data.discrete_volume == 1) {
        if(strcmp(common_data.volume->curve, "log") == 0) {
            long actualInternalVolume;
            common_data.volume->convertExternal2Internal(&common_data.volume_level_status, &actualInternalVolume);
            actualVolume = (double)actualInternalVolume;
        }
        else
            actualVolume = common_data.volume_level_status;
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    ((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
        syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
    if(status = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, ((void *)0))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open smoothVolume thread: %i", status);
        pthread_kill(mainThread, 15);
        pause();
    }
    return 0;
}

variable_types:
volumeInternal
long *

variable_types: actualInternalVolume long


reinit

decompiled_code:
__int64 reinit()
{
int v1; // eax
pthread_t v2; // rbp
pthread_t v3; // rbx
unsigned int v4; // ebx
pthread_t v5; // r12
int *v6; // rbx
int v7; // eax
char *v8; // rax

if ( resetInProgress )
return 0LL;
resetInProgress = 1;
reinitInProgress = 1;
pthread_cancel(setExternalVolumeThread);
syslog(7, "Initiating volume reinitialisation");
v1 = *((_DWORD *)&common_data + 42);
if ( v1 >= *((_DWORD *)&common_data + 8) )
{
*(double *)&defaultVolume = (double)v1;
(*(void (__fastcall **)(__int64 *))(*((_QWORD *)&common_data + 18) + 40LL))(&defaultVolume);
}
v2 = thisThread;
v3 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
goto LABEL_6;
if ( resetInProgress | pthread_kill(v3, 0) )
{
v5 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, v2) )
{
v6 = _errno_location();
v7 = pthread_join(v5, 0LL);
*v6 = v7;
if ( v7 )
{
v8 = strerror(v7);
syslog(4, "Unable to join smoothVolume thread: %s\n", v8);
}
}
LABEL_6:
v4 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( v4 )
{
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v4);
pthread_kill(mainThread, 15);
pause();
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 func2()
{
int v1; // eax
pthread_t v2; // rbp
pthread_t v3; // rbx
unsigned int v4; // ebx
pthread_t v5; // r12
int *v6; // rbx
int v7; // eax
char *v8; // rax

if ( resetInProgress )
return 0LL;
resetInProgress = 1;
reinitInProgress = 1;
pthread_cancel(setExternalVolumeThread);
syslog(7, "Initiating volume reinitialisation");
v1 = *((_DWORD *)&common_data + 42);
if ( v1 >= *((_DWORD *)&common_data + 8) )
{
*(double *)&defaultVolume = (double)v1;
(*(void (__fastcall **)(__int64 *))(*((_QWORD *)&common_data + 18) + 40LL))(&defaultVolume);
}
v2 = thisThread;
v3 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
goto LABEL_6;
if ( resetInProgress | pthread_kill(v3, 0) )
{
v5 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, v2) )
{
v6 = _errno_location();
v7 = pthread_join(v5, 0LL);
*v6 = v7;
if ( v7 )
{
v8 = strerror(v7);
syslog(4, "Unable to join smoothVolume thread: %s\n", v8);
}
}
LABEL_6:
v4 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( v4 )
{
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v4);
pthread_kill(mainThread, 15);
pause();
}
}
return 0LL;
}

original_code:
static int reinit(void) {
    if(resetInProgress)
        return 0;
    reinitInProgress = resetInProgress = 1;
    pthread_cancel(setExternalVolumeThread);
    syslog(7, "Initiating volume reinitialisation");
    int status;
    if(common_data.defaultExternalVolume >= common_data.initial_volume_min) {
        defaultVolume = common_data.defaultExternalVolume;
        common_data.volume->convertExternal2Mixer(&defaultVolume);
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    pthread_kill(setExternalVolumeThread, 0) == 0 && !resetInProgress)
        return 0;
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    ((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
        syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
    if(status = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, ((void *)0))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open smoothVolume thread: %i", status);
        pthread_kill(mainThread, 15);
        pause();
    }
    return 0;
}

canonical_original_code:
static int reinit() {
    if(resetInProgress)
        return 0;
    reinitInProgress = resetInProgress = 1;
    pthread_cancel(setExternalVolumeThread);
    syslog(7, "Initiating volume reinitialisation");
    int status;
    if(common_data.defaultExternalVolume >= common_data.initial_volume_min) {
        defaultVolume = common_data.defaultExternalVolume;
        common_data.volume->convertExternal2Mixer(&defaultVolume);
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    pthread_kill(setExternalVolumeThread, 0) == 0 && !resetInProgress)
        return 0;
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    ((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
        syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
    if(status = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, ((void *)0))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open smoothVolume thread: %i", status);
        pthread_kill(mainThread, 15);
        pause();
    }
    return 0;
}


init

decompiled_code:
_BOOL8 __fastcall init(__int64 (__fastcall *a1)(_QWORD), const char *a2, const char *a3)
{
unsigned int v4; // eax
_BOOL4 v5; // ebx
float v6; // xmm0_4
int v8; // eax
__int64 v9; // [rsp+0h] [rbp-48h]
__int64 v10; // [rsp+0h] [rbp-48h]
int v11; // [rsp+18h] [rbp-30h] BYREF
int v12[11]; // [rsp+1Ch] [rbp-2Ch] BYREF

timestampLastMute = 0uLL;
reinitInProgress = 0;
resetInProgress = 0;
req.tv_sec = 0LL;
req.tv_nsec = 1000000 * *((_DWORD *)&common_data + 18);
sigemptyset(&thread_sigmask);
sigaddset(&thread_sigmask, 2);
sigaddset(&thread_sigmask, 15);
v4 = pthread_attr_init(&thread_attr);
v5 = v4;
if ( v4 )
{
syslog(3, "Failed to initialize thread attributes: %i", v4);
v5 = 1;
}
else
{
pthread_attr_setdetachstate(&thread_attr, 0);
thisThread = pthread_self();
setExternalVolumeThread = thisThread;
if ( *((_DWORD *)&common_data + 1) )
{
qword_C38 = a1;
v11 = 0;
validateConfigInt(&config, "volume.mutation", v12, 0xFFFFFFFFLL, 1LL, 1000LL, 100LL);
if ( !strcmp(*(const char **)(*((_QWORD *)&common_data + 16) + 8LL), "ascii") )
config_lookup_int(&config, "volume.precision", &v11);
v6 = (float)(v12[0] / 100);
*(float *)&dword_C40 = v6;
if ( v11 && strcmp(*(const char **)(*((_QWORD *)&common_data + 18) + 24LL), "log") )
{
if ( v11 == 1 )
{
v8 = (int)(float)(v6 * 10.0) / 10;
if ( (float)v8 == 0.0 )
dword_C40 = 1036831949;
else
*(float *)&dword_C40 = (float)v8;
}
}
else if ( (float)(int)v6 == 0.0 )
{
dword_C40 = 1065353216;
}
else
{
*(float *)&dword_C40 = (float)(int)v6;
}
}
else
{
*((_QWORD *)&common_data + 20) = reinit;
localSettings = (__int64)a2;
qword_C28 = (__int64)a3;
dword_C30 = strlen(a2);
dword_C34 = strlen(a3);
validateConfigInt(&config, "volume.range", &dword_C44, 0xFFFFFFFFLL, 1LL, 1000LL, -1LL);
LODWORD(v9) = 2;
validateConfigInt(&config, "volume.double_zero_interval", &dword_C48, 0xFFFFFFFFLL, 0LL, 30LL, v9);
resetVolume();
LODWORD(v10) = dword_C44;
v5 = validateConfigInt(
&config,
"volume.max",
(unsigned int)((_DWORD)&common_data + 28),
0xFFFFFFFFLL,
1LL,
(unsigned int)dword_C44,
v10) == 1;
}
}
return v5;
}

canonical_decompiled_code:
_BOOL8 __fastcall func5(__int64 (__fastcall *a1)(_QWORD), const char *a2, const char *a3)
{
unsigned int v4; // eax
_BOOL4 v5; // ebx
float v6; // xmm0_4
int v8; // eax
__int64 v9; // [rsp+0h] [rbp-48h]
__int64 v10; // [rsp+0h] [rbp-48h]
int v11; // [rsp+18h] [rbp-30h] BYREF
int v12[11]; // [rsp+1Ch] [rbp-2Ch] BYREF

timestampLastMute = 0uLL;
reinitInProgress = 0;
resetInProgress = 0;
req.tv_sec = 0LL;
req.tv_nsec = 1000000 * *((_DWORD *)&common_data + 18);
sigemptyset(&thread_sigmask);
sigaddset(&thread_sigmask, 2);
sigaddset(&thread_sigmask, 15);
v4 = pthread_attr_init(&thread_attr);
v5 = v4;
if ( v4 )
{
syslog(3, "Failed to initialize thread attributes: %i", v4);
v5 = 1;
}
else
{
pthread_attr_setdetachstate(&thread_attr, 0);
thisThread = pthread_self();
setExternalVolumeThread = thisThread;
if ( *((_DWORD *)&common_data + 1) )
{
qword_C38 = a1;
v11 = 0;
validateConfigInt(&config, "volume.mutation", v12, 0xFFFFFFFFLL, 1LL, 1000LL, 100LL);
if ( !strcmp(*(const char **)(*((_QWORD *)&common_data + 16) + 8LL), "ascii") )
config_lookup_int(&config, "volume.precision", &v11);
v6 = (float)(v12[0] / 100);
*(float *)&dword_C40 = v6;
if ( v11 && strcmp(*(const char **)(*((_QWORD *)&common_data + 18) + 24LL), "log") )
{
if ( v11 == 1 )
{
v8 = (int)(float)(v6 * 10.0) / 10;
if ( (float)v8 == 0.0 )
dword_C40 = 1036831949;
else
*(float *)&dword_C40 = (float)v8;
}
}
else if ( (float)(int)v6 == 0.0 )
{
dword_C40 = 1065353216;
}
else
{
*(float *)&dword_C40 = (float)(int)v6;
}
}
else
{
*((_QWORD *)&common_data + 20) = reinit;
localSettings = (__int64)a2;
qword_C28 = (__int64)a3;
dword_C30 = strlen(a2);
dword_C34 = strlen(a3);
validateConfigInt(&config, "volume.range", &dword_C44, 0xFFFFFFFFLL, 1LL, 1000LL, -1LL);
LODWORD(v9) = 2;
validateConfigInt(&config, "volume.double_zero_interval", &dword_C48, 0xFFFFFFFFLL, 0LL, 30LL, v9);
func3();
LODWORD(v10) = dword_C44;
v5 = validateConfigInt(
&config,
"volume.max",
(unsigned int)((_DWORD)&common_data + 28),
0xFFFFFFFFLL,
1LL,
(unsigned int)dword_C44,
v10) == 1;
}
}
return v5;
}

original_code:
static int init(int (*setDescreteVolume)(double *externalVolume), char *volMin, char *volPlus) {
    timestampLastMute = (struct timespec) { 0, 0 };
    resetInProgress = reinitInProgress = 0;
    localSettings.timeout.tv_sec = 0;
    localSettings.timeout.tv_nsec = common_data.volume_timeout*1000000;
    sigemptyset(&thread_sigmask);
    sigaddset(&thread_sigmask, 2);
    sigaddset(&thread_sigmask, 15);
    int tempInt = -1;
    if((tempInt = pthread_attr_init(&thread_attr)) != 0) {
        syslog(3, "Failed to initialize thread attributes: %i", tempInt);
        return 1;
    }
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
    setExternalVolumeThread = thisThread = pthread_self();
    if(common_data.discrete_volume) {
        localSettings.setDescreteVolume = setDescreteVolume;
        int precision = 0;
        int tempInt;
        validateConfigInt(&config, "volume.mutation", &tempInt, -1, 1, 1000, 100);
        if(strcmp(common_data.process->name, "ascii") == 0) {
            config_lookup_int(&config, "volume.precision", &precision);
        }
        localSettings.volumeMutation = (tempInt / 100);
        if(precision == 0 || strcmp(common_data.volume->curve, "log") == 0) {
            localSettings.volumeMutation = (int)localSettings.volumeMutation;
            if(localSettings.volumeMutation == 0) localSettings.volumeMutation = 1;
        }
        else if(precision == 1) {
            localSettings.volumeMutation = (int)(10*localSettings.volumeMutation)/10;
            if(localSettings.volumeMutation == 0) localSettings.volumeMutation = 0.1;
        }
    }
    else {
        common_data.reinitVolume = &reinit;
        localSettings.volMin = volMin;
        localSettings.volPlus = volPlus;
        localSettings.volMinLen = strlen(localSettings.volMin);
        localSettings.volPlusLen = strlen(localSettings.volPlus);
        validateConfigInt(&config, "volume.range", &localSettings.volumeMutationRange, -1, 1, 1000, -1);
        validateConfigInt(&config, "volume.double_zero_interval", &localSettings.resetInterval, -1, 0, 30, 2);
        resetVolume();
        if(validateConfigInt(&config, "volume.max", &common_data.volume_max, -1, 1,
        localSettings.volumeMutationRange, localSettings.volumeMutationRange) == 1)
            return 1;
    }
    return 0;
}

variable_types:
setDescreteVolume
int (*)(double *externalVolume)

variable_types:
volMin
char *

variable_types:
volPlus
char *

variable_types: tempInt int

variable_types: precision int

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


deinitStatus

decompiled_code:
void deinitStatus()
{
const char **v0; // rbx
const char **v1; // rbp

v0 = (const char **)statusRoot;
if ( statusRoot )
{
do
{
v1 = v0;
v0 = (const char **)v0[2];
syslog(7, "Deleted status: %s", *v1);
free(v1);
}
while ( v0 );
}
}

canonical_decompiled_code:
void func0()
{
const char **v0; // rbx
const char **v1; // rbp

v0 = (const char **)statusRoot;
if ( statusRoot )
{
do
{
v1 = v0;
v0 = (const char **)v0[2];
syslog(7, "Deleted status: %s", *v1);
free(v1);
}
while ( v0 );
}
}

original_code:
static void deinitStatus(void) {
    status_t *statusCurrent = statusRoot;
    status_t *statusBackup;
    while(statusCurrent != ((void *)0)) {
        statusBackup = statusCurrent->nextStatus;
        syslog(7, "Deleted status: %s", statusCurrent->name);
        free(statusCurrent);
        statusCurrent = statusBackup;
    }
}

canonical_original_code:
static void deinitStatus() {
    struct status_t *statusCurrent = statusRoot;
    struct status_t *statusBackup;
    while(statusCurrent != ((void *)0)) {
        statusBackup = statusCurrent->nextStatus;
        syslog(7, "Deleted status: %s", statusCurrent->name);
        free(statusCurrent);
        statusCurrent = statusBackup;
    }
}

variable_types: struct status_t { char *name; char *value; struct status_t *nextStatus; } *


processStatus

decompiled_code:
__int64 __fastcall processStatus(char *s1, const char *a2)
{
const char *v3; // [rsp+8h] [rbp-20h] BYREF

if ( !strcmp(s1, "power") && !strcmp(a2, "deviceon") )
{
retrieveStatus(s1, &v3);
if ( v3 != a2 )
{
sleep(1u);
common_data[20]();
}
}
updateStatus(s1, a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s1, const char *a2)
{
const char *v3; // [rsp+8h] [rbp-20h] BYREF

if ( !strcmp(s1, "power") && !strcmp(a2, "deviceon") )
{
func1(s1, &v3);
if ( v3 != a2 )
{
sleep(1u);
common_data[20]();
}
}
func2(s1, a2);
return 0LL;
}

original_code:
static int processStatus(const char *name, const char *value) {
    const char *storedValue;
    if(strcmp(name, "power") == 0 && strcmp(value, "deviceon") == 0) {
        retrieveStatus(name, &storedValue);
        if(storedValue != value) {
            sleep(1);
            common_data.reinitVolume();
        }
    }
    updateStatus(name, value);
    return 0;
}

canonical_original_code:
static int processStatus(char *name, char *value) {
    char *storedValue;
    if(strcmp(name, "power") == 0 && strcmp(value, "deviceon") == 0) {
        retrieveStatus(name, &storedValue);
        if(storedValue != value) {
            sleep(1);
            common_data.reinitVolume();
        }
    }
    updateStatus(name, value);
    return 0;
}

variable_types:
name
char *

variable_types:
value
char *

variable_types:
storedValue
char *


getProcessMethod

decompiled_code:
const char **__fastcall getProcessMethod(const char **a1)
{
const char **v1; // rbx
const char *v2; // r12
void **v3; // rbp

if ( !*a1 )
*a1 = (const char *)*((_QWORD *)processMethods + 1);
v1 = (const char **)processMethods;
if ( processMethods )
{
v2 = *a1;
v3 = &processMethods;
do
{
if ( !strcasecmp(v2, v1[1]) )
break;
v1 = (const char **)*++v3;
}
while ( *v3 );
}
return v1;
}

canonical_decompiled_code:
const char **__fastcall func4(const char **a1)
{
const char **v1; // rbx
const char *v2; // r12
void **v3; // rbp

if ( !*a1 )
*a1 = (const char *)*((_QWORD *)processMethods + 1);
v1 = (const char **)processMethods;
if ( processMethods )
{
v2 = *a1;
v3 = &processMethods;
do
{
if ( !strcasecmp(v2, v1[1]) )
break;
v1 = (const char **)*++v3;
}
while ( *v3 );
}
return v1;
}

original_code:
process_method_t *getProcessMethod(const char **name) {
    process_method_t **process_type;
    if (!*name)
        *name = processMethods[0]->name;
    for (process_type=processMethods; *process_type; process_type++)
        if (!strcasecmp(*name, (*process_type)->name))
            return *process_type;
    return ((void *)0);
}

canonical_original_code:
struct process_method_t *getProcessMethod(char **name) {
    struct process_method_t **process_type;
    if (!*name)
        *name = processMethods[0]->name;
    for (process_type=processMethods; *process_type; process_type++)
        if (!strcasecmp(*name, (*process_type)->name))
            return *process_type;
    return ((void *)0);
}

variable_types:
name
char **

variable_types: struct process_method_t { void (*help)(); char *name; int (*init)(); void (*deinit)(); int (*compileVolumeCommand)(long *volumeLevel); int (*compileDeviceCommand)(char *header, char *action); int (*processCommand)(void *event_header, void *event); int (*strip_raw_input)(unsigned char *device_status_message, long bytes_read); } **