decompiled_code:
int process_events()
{
int *v0; // rax
int v1; // eax
int v2; // ebp
void *v3; // rbp
struct timeval v5; // [rsp+0h] [rbp-28h] BYREF

while ( 1 )
{
LODWORD(v0) = count_devices();
if ( (int)v0 <= 0 && cmd_fd == -1 )
break;
memset(&rfds, 0, sizeof(rfds));
max_fd = -1;
for_each_device(add_device_to_fdset);
v1 = cmd_fd;
if ( cmd_fd != -1 )
{
rfds.fds_bits[cmd_fd / 64] |= 1LL << (cmd_fd % 64);
if ( max_fd >= v1 )
v1 = max_fd;
max_fd = v1;
}
v5.tv_sec = 5LL;
v5.tv_usec = 0LL;
LODWORD(v0) = select(max_fd + 1, &rfds, 0LL, 0LL, &v5);
v2 = (int)v0;
if ( (_DWORD)v0 != -1 || (v0 = _errno_location(), *v0 == 4) )
{
if ( exiting )
return (int)v0;
if ( reload_conf )
{
reload_conf = 0;
reload_triggerfile();
}
else if ( v2 )
{
process_devices();
if ( cmd_fd != -1 && (rfds.fds_bits[cmd_fd / 64] & (1LL << (cmd_fd % 64))) != 0 )
{
v3 = (void *)read_command();
obey_command(v3);
free(v3);
}
}
}
else
{
perror("select()");
}
}
return (int)v0;
}

canonical_decompiled_code:
int func5()
{
int *v0; // rax
int v1; // eax
int v2; // ebp
void *v3; // rbp
struct timeval v5; // [rsp+0h] [rbp-28h] BYREF

while ( 1 )
{
LODWORD(v0) = count_devices();
if ( (int)v0 <= 0 && cmd_fd == -1 )
break;
memset(&rfds, 0, sizeof(rfds));
max_fd = -1;
for_each_device(add_device_to_fdset);
v1 = cmd_fd;
if ( cmd_fd != -1 )
{
rfds.fds_bits[cmd_fd / 64] |= 1LL << (cmd_fd % 64);
if ( max_fd >= v1 )
v1 = max_fd;
max_fd = v1;
}
v5.tv_sec = 5LL;
v5.tv_usec = 0LL;
LODWORD(v0) = select(max_fd + 1, &rfds, 0LL, 0LL, &v5);
v2 = (int)v0;
if ( (_DWORD)v0 != -1 || (v0 = _errno_location(), *v0 == 4) )
{
if ( exiting )
return (int)v0;
if ( reload_conf )
{
reload_conf = 0;
func4();
}
else if ( v2 )
{
func3();
if ( cmd_fd != -1 && (rfds.fds_bits[cmd_fd / 64] & (1LL << (cmd_fd % 64))) != 0 )
{
v3 = (void *)read_command();
obey_command(v3);
free(v3);
}
}
}
else
{
perror("select()");
}
}
return (int)v0;
}

original_code:
static void process_events(void) {
 struct timeval tv;
 int retval;
 while ( count_devices() > 0 || cmd_fd != -1 ) {
  do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&rfds)->__fds_bits)[0]) : "memory"); } while (0);
  max_fd = -1;
  for_each_device( &add_device_to_fdset );
  if (cmd_fd != -1) {
   ((void) (((&rfds)->__fds_bits)[((cmd_fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cmd_fd) % (8 * (int) sizeof (__fd_mask)))))));
   max_fd = cmd_fd > max_fd ? cmd_fd : max_fd;
  }
  tv.tv_sec = 5;
  tv.tv_usec = 0;
  retval = select(max_fd+1, &rfds, ((void *)0), ((void *)0), &tv);
  if (retval == -1 && (*__errno_location ()) != 4) {
   perror("select()");
   continue;
  } else if (exiting) {
   break;
  } else if (reload_conf) {
   reload_conf = 0;
   reload_triggerfile();
   continue;
  } else if (retval) {
   process_devices();
   if ( cmd_fd != -1 && ((((&rfds)->__fds_bits)[((cmd_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((cmd_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0) ) {
    struct command *cmd = read_command( cmd_fd );
    obey_command( cmd );
    free(cmd);
   }
  }
 }
}

canonical_original_code:
static void process_events() {
 struct timeval tv;
 int retval;
 while ( count_devices() > 0 || cmd_fd != -1 ) {
  do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&rfds)->__fds_bits)[0]) : "memory"); } while (0);
  max_fd = -1;
  for_each_device( &add_device_to_fdset );
  if (cmd_fd != -1) {
   ((void) (((&rfds)->__fds_bits)[((cmd_fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((cmd_fd) % (8 * (int) sizeof (__fd_mask)))))));
   max_fd = cmd_fd > max_fd ? cmd_fd : max_fd;
  }
  tv.tv_sec = 5;
  tv.tv_usec = 0;
  retval = select(max_fd+1, &rfds, ((void *)0), ((void *)0), &tv);
  if (retval == -1 && (*__errno_location ()) != 4) {
   perror("select()");
   continue;
  } else if (exiting) {
   break;
  } else if (reload_conf) {
   reload_conf = 0;
   reload_triggerfile();
   continue;
  } else if (retval) {
   process_devices();
   if ( cmd_fd != -1 && ((((&rfds)->__fds_bits)[((cmd_fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((cmd_fd) % (8 * (int) sizeof (__fd_mask)))))) != 0) ) {
    struct command *cmd = read_command( cmd_fd );
    obey_command( cmd );
    free(cmd);
   }
  }
 }
}

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

variable_types: retval int

variable_types: struct command { enum command_type { CMD_NOP=0, CMD_ADD=1, CMD_REMOVE=2, CMD_QUIT=3, CMD_DISABLE=4, CMD_ENABLE=5, CMD_PASSFD=6, CMD_CLEARDEVS=7, CMD_CHANGEMODE=8 } type; char param[256]; int fd; int exclusive; char tag[256]; } *


repo: wertarbyte/triggerhappy

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

v1 = *(_DWORD *)a1 + 63;
if ( *(int *)a1 >= 0 )
v1 = *(_DWORD *)a1;
result = v1 >> 6;
if ( (rfds.fds_bits[result] & (1LL << (*(_DWORD *)a1 % 64))) != 0 )
{
result = read_event(a1);
if ( (_DWORD)result )
result = remove_device(*(_QWORD *)(a1 + 8));
}
return result;
}

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

v1 = *(_DWORD *)a1 + 63;
if ( *(int *)a1 >= 0 )
v1 = *(_DWORD *)a1;
result = v1 >> 6;
if ( (rfds.fds_bits[result] & (1LL << (*(_DWORD *)a1 % 64))) != 0 )
{
result = func8(a1);
if ( (_DWORD)result )
result = remove_device(*(_QWORD *)(a1 + 8));
}
return result;
}

original_code:
static void check_device( device *d ) {
 int fd = d->fd;
 if (((((&rfds)->__fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
  if (read_event( d )) {
   remove_device( d->devname );
  }
 }
}

canonical_original_code:
static void check_device(struct device *d) {
 int fd = d->fd;
 if (((((&rfds)->__fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))) != 0)) {
  if (read_event( d )) {
   remove_device( d->devname );
  }
 }
}

variable_types: struct device { int fd; char *devname; int exclusive; char tag[256]; struct device *next; } *

variable_types: fd int

return_type: void


decompiled_code:
void __fastcall list_event_table(unsigned int a1, int a2)
{
int i; // ebx
const char *v3; // rax

if ( a2 >= 0 )
{
for ( i = 0; i <= a2; ++i )
{
v3 = (const char *)lookup_event_name_i(a1, (unsigned int)i);
if ( v3 )
puts(v3);
}
}
}

canonical_decompiled_code:
void __fastcall func10(unsigned int a1, int a2)
{
int i; // ebx
const char *v3; // rax

if ( a2 >= 0 )
{
for ( i = 0; i <= a2; ++i )
{
v3 = (const char *)lookup_event_name_i(a1, (unsigned int)i);
if ( v3 )
puts(v3);
}
}
}

original_code:
static void list_event_table(int type, int max) {
 int n = 0;
 for (n = 0; n <= max; n++) {
  const char *name = lookup_event_name_i(type, n);
  if (name) {
   printf("%s\n", name);
  }
 }
}

canonical_original_code:
static void list_event_table(int type, int max) {
 int n = 0;
 for (n = 0; n <= max; n++) {
  char *name = lookup_event_name_i(type, n);
  if (name) {
   printf("%s\n", name);
  }
 }
}

variable_types: type int

variable_types: max int

variable_types: n int

variable_types:
name
char *


decompiled_code:
void list_events()
{
list_event_table(1u, 767);
list_event_table(5u, 16);
list_event_table(2u, 15);
list_event_table(3u, 15);
}

original_code:
static void list_events(void) {
 list_event_table(0x01, 0x2ff);
 list_event_table(0x05, 0x10);
 list_event_table(0x02, 0x0f);
 list_event_table(0x03, 0x0f);
}

canonical_original_code:
static void list_events() {
 list_event_table(0x01, 0x2ff);
 list_event_table(0x05, 0x10);
 list_event_table(0x02, 0x0f);
 list_event_table(0x03, 0x0f);
}


cleanup

decompiled_code:
int cleanup()
{
int result; // eax

close_uinput();
if ( cmd_file )
{
if ( cmd_fd != -1 )
close(cmd_fd);
unlink(cmd_file);
cmd_fd = -1;
}
result = clear_devices();
if ( pidfile )
result = unlink(pidfile);
return result;
}

canonical_decompiled_code:
int func13()
{
int result; // eax

close_uinput();
if ( cmd_file )
{
if ( cmd_fd != -1 )
close(cmd_fd);
unlink(cmd_file);
cmd_fd = -1;
}
result = clear_devices();
if ( pidfile )
result = unlink(pidfile);
return result;
}

original_code:
void cleanup(void) {
 close_uinput();
 if (cmd_file) {
  if (cmd_fd != -1) {
   close( cmd_fd );
  }
  unlink(cmd_file);
  cmd_fd = -1;
 }
 clear_devices();
 if (pidfile) {
  unlink(pidfile);
 }
}

canonical_original_code:
void cleanup() {
 close_uinput();
 if (cmd_file) {
  if (cmd_fd != -1) {
   close( cmd_fd );
  }
  unlink(cmd_file);
  cmd_fd = -1;
 }
 clear_devices();
 if (pidfile) {
  unlink(pidfile);
 }
}


decompiled_code:
__int64 __fastcall start_readers(int a1, __int64 a2, __int64 a3, const char *a4)
{
int v4; // er12
_QWORD *v6; // rbx
size_t v7; // rbx
struct passwd *v8; // rax
__uid_t v9; // ebp
__gid_t v10; // ebx
glob_t v12; // [rsp+0h] [rbp-78h] BYREF

v4 = a3;
if ( a1 - (int)a3 > 0 || (unsigned __int64)cmd_file | (unsigned __int64)a4 )
{
if ( !cmd_file || (cmd_fd = bind_cmdsocket(), a3 = 1LL, cmd_fd >= 0) )
{
if ( a1 > v4 )
{
v6 = (_QWORD *)(a2 + 8LL * v4);
do
add_device(*v6++, 0xFFFFFFFFLL, 0LL, 0LL);
while ( v6 != (_QWORD *)(a2 + 8 * (v4 + (unsigned __int64)(unsigned int)(a1 - v4 - 1)) + 8) );
}
if ( a4 )
{
glob(a4, 4, 0LL, &v12);
if ( v12.gl_pathc )
{
v7 = 0LL;
do
add_device(v12.gl_pathv[v7++], 0xFFFFFFFFLL, 0LL, 0LL);
while ( v12.gl_pathc > v7 );
}
}
if ( run_as_daemon && daemon(0, 0) )
perror("daemon()");
if ( pidfile )
write_pidfile(pidfile);
if ( user )
{
v8 = getpwnam(user);
if ( !v8 )
{
fprintf(stderr, "Unable to lookup user '%s'.\n", user);
LODWORD(a3) = 1;
return (unsigned int)a3;
}
v9 = v8->pw_uid;
v10 = v8->pw_gid;
if ( initgroups(user, v10) )
{
perror("initgroups");
LODWORD(a3) = 1;
return (unsigned int)a3;
}
if ( setregid(v10, v10) )
{
perror("setregid");
LODWORD(a3) = 1;
return (unsigned int)a3;
}
if ( setreuid(v9, v9) )
{
perror("setreuid");
LODWORD(a3) = 1;
return (unsigned int)a3;
}
}
sd_notify(0LL, "READY=1", a3);
process_events();
LODWORD(a3) = 0;
}
}
else
{
fwrite("No input device files or command pipe specified.\n", 1uLL, 0x31uLL, stderr);
LODWORD(a3) = 1;
}
return (unsigned int)a3;
}

canonical_decompiled_code:
__int64 __fastcall func14(int a1, __int64 a2, __int64 a3, const char *a4)
{
int v4; // er12
_QWORD *v6; // rbx
size_t v7; // rbx
struct passwd *v8; // rax
__uid_t v9; // ebp
__gid_t v10; // ebx
glob_t v12; // [rsp+0h] [rbp-78h] BYREF

v4 = a3;
if ( a1 - (int)a3 > 0 || (unsigned __int64)cmd_file | (unsigned __int64)a4 )
{
if ( !cmd_file || (cmd_fd = bind_cmdsocket(), a3 = 1LL, cmd_fd >= 0) )
{
if ( a1 > v4 )
{
v6 = (_QWORD *)(a2 + 8LL * v4);
do
add_device(*v6++, 0xFFFFFFFFLL, 0LL, 0LL);
while ( v6 != (_QWORD *)(a2 + 8 * (v4 + (unsigned __int64)(unsigned int)(a1 - v4 - 1)) + 8) );
}
if ( a4 )
{
glob(a4, 4, 0LL, &v12);
if ( v12.gl_pathc )
{
v7 = 0LL;
do
add_device(v12.gl_pathv[v7++], 0xFFFFFFFFLL, 0LL, 0LL);
while ( v12.gl_pathc > v7 );
}
}
if ( run_as_daemon && daemon(0, 0) )
perror("daemon()");
if ( pidfile )
func2(pidfile);
if ( user )
{
v8 = getpwnam(user);
if ( !v8 )
{
fprintf(stderr, "Unable to lookup user '%s'.\n", user);
LODWORD(a3) = 1;
return (unsigned int)a3;
}
v9 = v8->pw_uid;
v10 = v8->pw_gid;
if ( initgroups(user, v10) )
{
perror("initgroups");
LODWORD(a3) = 1;
return (unsigned int)a3;
}
if ( setregid(v10, v10) )
{
perror("setregid");
LODWORD(a3) = 1;
return (unsigned int)a3;
}
if ( setreuid(v9, v9) )
{
perror("setreuid");
LODWORD(a3) = 1;
return (unsigned int)a3;
}
}
sd_notify(0LL, "READY=1", a3);
func5();
LODWORD(a3) = 0;
}
}
else
{
fwrite("No input device files or command pipe specified.\n", 1uLL, 0x31uLL, stderr);
LODWORD(a3) = 1;
}
return (unsigned int)a3;
}

original_code:
int start_readers(int argc, char *argv[], int start, char *dev_glob) {
 if (argc-start < 1 && cmd_file == ((void *)0) && dev_glob == ((void *)0)) {
  fprintf(stderr, "No input device files or command pipe specified.\n");
  return 1;
 }
 if (cmd_file) {
  cmd_fd = bind_cmdsocket(cmd_file);
  if (cmd_fd < 0) {
   return 1;
  }
 }
 int i;
 for (i=start; i<argc; i++) {
  char *dev = argv[i];
  int grab_dev = 0;
  char *tag_dev = ((void *)0);
  add_device( dev, -1, grab_dev, tag_dev );
 }
 if (dev_glob) {
  glob_t globbuf;
  glob(dev_glob, (1 << 2), ((void *)0), &globbuf);
  for (i=0; i<globbuf.gl_pathc; i++) {
   int grab_dev = 0;
   char *tag_dev = ((void *)0);
   add_device(globbuf.gl_pathv[i], -1, grab_dev, tag_dev);
  }
 }
 if (run_as_daemon) {
  int err = daemon(0,0);
  if (err) {
   perror("daemon()");
  }
 }
 if (pidfile) {
  write_pidfile( pidfile );
 }
 if (user) {
  struct passwd *pw = getpwnam(user);
  if (pw) {
   int uid = pw->pw_uid;
   int gid = pw->pw_gid;
   if ( initgroups(user, gid) ) {
    perror("initgroups");
    return 1;
   }
   if ( setregid( gid, gid ) ) {
    perror("setregid");
    return 1;
   }
   if ( setreuid( uid, uid ) ) {
    perror("setreuid");
    return 1;
   }
  } else {
   fprintf(stderr, "Unable to lookup user '%s'.\n", user);
   return 1;
  }
 }
 sd_notify(0, "READY=1");
 process_events();
 return 0;
}

canonical_original_code:
int start_readers(int argc, char *argv[], int start, char *dev_glob) {
 if (argc-start < 1 && cmd_file == ((void *)0) && dev_glob == ((void *)0)) {
  fprintf(stderr, "No input device files or command pipe specified.\n");
  return 1;
 }
 if (cmd_file) {
  cmd_fd = bind_cmdsocket(cmd_file);
  if (cmd_fd < 0) {
   return 1;
  }
 }
 int i;
 for (i=start; i<argc; i++) {
  char *dev = argv[i];
  int grab_dev = 0;
  char *tag_dev = ((void *)0);
  add_device( dev, -1, grab_dev, tag_dev );
 }
 if (dev_glob) {
  struct glob_t globbuf;
  glob(dev_glob, (1 << 2), ((void *)0), &globbuf);
  for (i=0; i<globbuf.gl_pathc; i++) {
   int grab_dev = 0;
   char *tag_dev = ((void *)0);
   add_device(globbuf.gl_pathv[i], -1, grab_dev, tag_dev);
  }
 }
 if (run_as_daemon) {
  int err = daemon(0,0);
  if (err) {
   perror("daemon()");
  }
 }
 if (pidfile) {
  write_pidfile( pidfile );
 }
 if (user) {
  struct passwd *pw = getpwnam(user);
  if (pw) {
   int uid = pw->pw_uid;
   int gid = pw->pw_gid;
   if ( initgroups(user, gid) ) {
    perror("initgroups");
    return 1;
   }
   if ( setregid( gid, gid ) ) {
    perror("setregid");
    return 1;
   }
   if ( setreuid( uid, uid ) ) {
    perror("setreuid");
    return 1;
   }
  } else {
   fprintf(stderr, "Unable to lookup user '%s'.\n", user);
   return 1;
  }
 }
 sd_notify(0, "READY=1");
 process_events();
 return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: start int

variable_types: i int

variable_types:
dev
char *

variable_types: struct glob_t { unsigned long gl_pathc; char **gl_pathv; unsigned long gl_offs; int gl_flags; void (*gl_closedir)(void *); void *(*gl_readdir)(void *); void *(*gl_opendir)(char *); int (*gl_lstat)(char *, void *); int (*gl_stat)(char *, void *); }

variable_types: err int

variable_types: struct passwd { char *pw_name; char *pw_passwd; unsigned int pw_uid; unsigned int pw_gid; char *pw_gecos; char *pw_dir; char *pw_shell; } *

variable_types: uid int

variable_types: gid int

return_type: int


decompiled_code:
int show_help()
{
puts("Triggerhappy event daemon 0.5.0\n");
puts("Usage:");
puts(" thd [switches] [devices]\n");
puts("Command line switches:");
puts(" --help Display this help message");
puts(" --daemon Run as daemon process");
puts(" --dump Dump events to console");
puts(" --listevents Print a list of all known events");
puts(" --triggers <file> Load trigger definitions from <file>");
puts(" --socket <socket> Read commands from socket");
puts(" --ignore <event> Ignore key events with name <event>");
puts(" --normalize Normalize relative movement events");
puts(" --user <name> Drop privileges to <name> after opening devices");
return puts(" --deviceglob <p> Open device files matching pattern <p>");
}

canonical_decompiled_code:
int func12()
{
puts("Triggerhappy event daemon 0.5.0\n");
puts("Usage:");
puts(" thd [switches] [devices]\n");
puts("Command line switches:");
puts(" --help Display this help message");
puts(" --daemon Run as daemon process");
puts(" --dump Dump events to console");
puts(" --listevents Print a list of all known events");
puts(" --triggers <file> Load trigger definitions from <file>");
puts(" --socket <socket> Read commands from socket");
puts(" --ignore <event> Ignore key events with name <event>");
puts(" --normalize Normalize relative movement events");
puts(" --user <name> Drop privileges to <name> after opening devices");
return puts(" --deviceglob <p> Open device files matching pattern <p>");
}

original_code:
void show_help(void) {
 printf( "Triggerhappy event daemon " "0.5.0" "\n\n" );
 printf( "Usage:\n" );
 printf( "  thd [switches] [devices]\n\n" );
 printf( "Command line switches:\n" );
 printf( "  --help             Display this help message\n" );
 printf( "  --daemon           Run as daemon process\n" );
 printf( "  --dump             Dump events to console\n" );
 printf( "  --listevents       Print a list of all known events\n" );
 printf( "  --triggers <file>  Load trigger definitions from <file>\n" );
 printf( "  --socket <socket>  Read commands from socket\n" );
 printf( "  --ignore <event>   Ignore key events with name <event>\n" );
 printf( "  --normalize        Normalize relative movement events\n" );
 printf( "  --user <name>      Drop privileges to <name> after opening devices\n" );
 printf( "  --deviceglob <p>   Open device files matching pattern <p>\n" );
}

canonical_original_code:
void show_help() {
 printf( "Triggerhappy event daemon " "0.5.0" "\n\n" );
 printf( "Usage:\n" );
 printf( "  thd [switches] [devices]\n\n" );
 printf( "Command line switches:\n" );
 printf( "  --help             Display this help message\n" );
 printf( "  --daemon           Run as daemon process\n" );
 printf( "  --dump             Dump events to console\n" );
 printf( "  --listevents       Print a list of all known events\n" );
 printf( "  --triggers <file>  Load trigger definitions from <file>\n" );
 printf( "  --socket <socket>  Read commands from socket\n" );
 printf( "  --ignore <event>   Ignore key events with name <event>\n" );
 printf( "  --normalize        Normalize relative movement events\n" );
 printf( "  --user <name>      Drop privileges to <name> after opening devices\n" );
 printf( "  --deviceglob <p>   Open device files matching pattern <p>\n" );
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // er13
struct sigaction v6; // [rsp+0h] [rbp-C8h] BYREF
int longind[11]; // [rsp+9Ch] [rbp-2Ch] BYREF

signal(17, (__sighandler_t)((char *)add_device_to_fdset + 1));
longind[0] = 0;
while ( 1 )
{
v3 = getopt_long(argc, (char *const *)argv, "t:s:dhpni:u:g:", &long_options, longind);
if ( v3 == -1 )
break;
if ( v3 )
return 1;
if ( !*((_QWORD *)&long_options.flag + 4 * longind[0]) )
{
printf("option %s", *(&long_options.name + 4 * longind[0]));
if ( optarg )
printf(" with arg %s", optarg);
putchar(10);
}
}
v4 = 1;
if ( !(unsigned int)reload_triggerfile() )
{
init_keystate_holder(&keystate);
change_trigger_mode(&unk_E4D);
if ( uinput_dev && (unsigned int)open_uinput() == -1 )
{
fwrite("Error setting up uinput support\n", 1uLL, 0x20uLL, stderr);
}
else
{
v6.sa_handler = handle_signal;
sigfillset(&v6.sa_mask);
v6.sa_flags = 0;
sigaction(2, &v6, 0LL);
sigaction(15, &v6, 0LL);
sigaction(1, &v6, 0LL);
v4 = start_readers(argc, (__int64)argv, (unsigned int)optind, 0LL);
cleanup();
}
}
return v4;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // er13
struct sigaction v6; // [rsp+0h] [rbp-C8h] BYREF
int longind[11]; // [rsp+9Ch] [rbp-2Ch] BYREF

signal(17, (__sighandler_t)((char *)add_device_to_fdset + 1));
longind[0] = 0;
while ( 1 )
{
v3 = getopt_long(argc, (char *const *)argv, "t:s:dhpni:u:g:", &long_options, longind);
if ( v3 == -1 )
break;
if ( v3 )
return 1;
if ( !*((_QWORD *)&long_options.flag + 4 * longind[0]) )
{
printf("option %s", *(&long_options.name + 4 * longind[0]));
if ( optarg )
printf(" with arg %s", optarg);
putchar(10);
}
}
v4 = 1;
if ( !(unsigned int)func4() )
{
init_keystate_holder(&keystate);
change_trigger_mode(&unk_E4D);
if ( uinput_dev && (unsigned int)open_uinput() == -1 )
{
fwrite("Error setting up uinput support\n", 1uLL, 0x20uLL, stderr);
}
else
{
v6.sa_handler = handle_signal;
sigfillset(&v6.sa_mask);
v6.sa_flags = 0;
sigaction(2, &v6, 0LL);
sigaction(15, &v6, 0LL);
sigaction(1, &v6, 0LL);
v4 = func14(argc, (__int64)argv, (unsigned int)optind, 0LL);
func13();
}
}
return v4;
}

original_code:
int main(int argc, char *argv[]) {
 signal(17, ((__sighandler_t) 1));
 char *dev_glob = ((void *)0);
 int option_index = 0;
 int c;
 while (1) {
  c = getopt_long (argc, argv, "t:s:dhpni:u:g:", long_options, &option_index);
  if (c == -1) {
   break;
  }
  switch (c) {
   case 0:
    if (long_options[option_index].flag != 0) {
     break;
    }
    printf ("option %s", long_options[option_index].name);
    if (optarg)
     printf (" with arg %s", optarg);
    printf ("\n");
    break;
   case 'd':
    dump_events = 1;
    break;
   case 'p':
    pidfile = optarg;
    break;
   case 't':
    triggerfile = optarg;
    break;
   case 's':
    cmd_file = optarg;
    break;
   case 'i':
    if ( lookup_event_type(optarg) == 0x01 ) {
     ignore_key( lookup_event_code(optarg), &ignored_keys );
    }
    break;
   case 'h':
    show_help();
    return 0;
   case 'l':
    list_events();
    return 0;
   case 'u':
    user = optarg;
    break;
   case '<':
    uinput_dev = optarg;
    break;
   case 'g':
    dev_glob = optarg;
    break;
   case '?':
   default:
    return 1;
  }
 }
 if (reload_triggerfile() != 0) {
  return 1;
 }
 init_keystate_holder(&keystate);
 change_trigger_mode("");
 if (uinput_dev != ((void *)0) && open_uinput(uinput_dev) == -1) {
  fprintf(stderr, "Error setting up uinput support\n");
  return 1;
 }
 struct sigaction handler;
 handler.__sigaction_handler.sa_handler = handle_signal;
 sigfillset(&handler.sa_mask);
 handler.sa_flags=0;
 sigaction(2,&handler,0);
 sigaction(15,&handler,0);
 sigaction(1,&handler,0);
 int status = start_readers(argc, argv, optind, dev_glob);
 cleanup();
 return status;
}

canonical_original_code:
int main(int argc, char *argv[]) {
 signal(17, ((void (*)(int)) 1));
 char *dev_glob = ((void *)0);
 int option_index = 0;
 int c;
 while (1) {
  c = getopt_long (argc, argv, "t:s:dhpni:u:g:", long_options, &option_index);
  if (c == -1) {
   break;
  }
  switch (c) {
   case 0:
    if (long_options[option_index].flag != 0) {
     break;
    }
    printf ("option %s", long_options[option_index].name);
    if (optarg)
     printf (" with arg %s", optarg);
    printf ("\n");
    break;
   case 'd':
    dump_events = 1;
    break;
   case 'p':
    pidfile = optarg;
    break;
   case 't':
    triggerfile = optarg;
    break;
   case 's':
    cmd_file = optarg;
    break;
   case 'i':
    if ( lookup_event_type(optarg) == 0x01 ) {
     ignore_key( lookup_event_code(optarg), &ignored_keys );
    }
    break;
   case 'h':
    show_help();
    return 0;
   case 'l':
    list_events();
    return 0;
   case 'u':
    user = optarg;
    break;
   case '<':
    uinput_dev = optarg;
    break;
   case 'g':
    dev_glob = optarg;
    break;
   case '?':
   default:
    return 1;
  }
 }
 if (reload_triggerfile() != 0) {
  return 1;
 }
 init_keystate_holder(&keystate);
 change_trigger_mode("");
 if (uinput_dev != ((void *)0) && open_uinput(uinput_dev) == -1) {
  fprintf(stderr, "Error setting up uinput support\n");
  return 1;
 }
 struct sigaction handler;
 handler.__sigaction_handler.sa_handler = handle_signal;
 sigfillset(&handler.sa_mask);
 handler.sa_flags=0;
 sigaction(2,&handler,0);
 sigaction(15,&handler,0);
 sigaction(1,&handler,0);
 int status = start_readers(argc, argv, optind, dev_glob);
 cleanup();
 return status;
}

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

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


decompiled_code:
__int64 __fastcall parse_evdef(char *s, __int64 a2)
{
char *v2; // rbx
char *v3; // rax
char *v4; // rax
char *v5; // rbp
char *v6; // r15
int *v7; // rbp
char *v8; // rax
char *v9; // rbx
int v10; // er12
int v11; // eax
int v12; // ebx
int v13; // eax
char *save_ptr[8]; // [rsp+8h] [rbp-40h] BYREF

v2 = s;
v3 = strchr(s, 64);
if ( v3 )
{
*v3 = 0;
v3 = strdup(v3 + 1);
}
*(_QWORD *)(a2 + 32) = v3;
*(_BYTE *)(a2 + 40) = 0;
v4 = strchr(s, 62);
v5 = v4;
if ( v4 && *s == 60 )
{
*v4 = 0;
strncpy((char *)(a2 + 40), s + 1, 0xFFuLL);
*(_BYTE *)(a2 + 295) = 0;
v2 = v5 + 1;
}
save_ptr[0] = 0LL;
v6 = strtok_r(v2, "+", save_ptr);
v7 = (int *)(a2 + 12);
do
{
v8 = strtok_r(0LL, "+", save_ptr);
v9 = v8;
if ( v8 )
{
v10 = lookup_event_type(v8);
v11 = lookup_event_code(v9);
if ( v10 != 1 || v11 < 0 )
return 1LL;
*v7 = v11;
}
else
{
*v7 = -1;
}
++v7;
}
while ( v7 != (int *)(a2 + 32) );
v12 = lookup_event_type(v6);
v13 = lookup_event_code(v6);
if ( v12 < 0 || v13 < 0 )
return 1LL;
*(_DWORD *)a2 = v12;
*(_DWORD *)(a2 + 4) = v13;
return 0LL;
}

original_code:
static int parse_evdef(char *evdef, trigger *t) {
 char *mode = strchr(evdef, '@');
 if (mode) {
  *mode = '\0';
  mode++;
 }
 t->mode = (mode ? strdup(mode) : ((void *)0));
 t->devtag[0] = '\0';
 char *tmp = strchr(evdef, '>');
 if (tmp && evdef[0] == '<') {
  *tmp = '\0';
  strncpy(t->devtag, &evdef[1], 256);
  t->devtag[256 -1] = '\0';
  evdef = tmp+1;
 }
 char *sptr = ((void *)0);
 char *s_trigger = strtok_r(evdef, "+", &sptr);
 int n = 0;
 while (n < 5) {
  char *s_mod = strtok_r(((void *)0), "+", &sptr);
  if (s_mod == ((void *)0)) {
   t->modifiers[n] = -1;
  } else {
   int type = lookup_event_type(s_mod);
   int c = lookup_event_code(s_mod);
   if (type == 0x01 && c >= 0) {
    t->modifiers[n] = c;
   } else {
    return 1;
   }
  }
  n++;
 }
 int type = lookup_event_type( s_trigger );
 int code = lookup_event_code( s_trigger );
 if (type < 0 || code < 0) {
  return 1;
 }
 t->type = type;
 t->code = code;
 return 0;
}

canonical_original_code:
static int parse_evdef(char *evdef, struct trigger *t) {
 char *mode = strchr(evdef, '@');
 if (mode) {
  *mode = '\0';
  mode++;
 }
 t->mode = (mode ? strdup(mode) : ((void *)0));
 t->devtag[0] = '\0';
 char *tmp = strchr(evdef, '>');
 if (tmp && evdef[0] == '<') {
  *tmp = '\0';
  strncpy(t->devtag, &evdef[1], 256);
  t->devtag[256 -1] = '\0';
  evdef = tmp+1;
 }
 char *sptr = ((void *)0);
 char *s_trigger = strtok_r(evdef, "+", &sptr);
 int n = 0;
 while (n < 5) {
  char *s_mod = strtok_r(((void *)0), "+", &sptr);
  if (s_mod == ((void *)0)) {
   t->modifiers[n] = -1;
  } else {
   int type = lookup_event_type(s_mod);
   int c = lookup_event_code(s_mod);
   if (type == 0x01 && c >= 0) {
    t->modifiers[n] = c;
   } else {
    return 1;
   }
  }
  n++;
 }
 int type = lookup_event_type( s_trigger );
 int code = lookup_event_code( s_trigger );
 if (type < 0 || code < 0) {
  return 1;
 }
 t->type = type;
 t->code = code;
 return 0;
}

variable_types:
evdef
char *

variable_types: struct trigger { int type; int code; int value; int modifiers[5]; char *mode; char devtag[256]; char *action; struct trigger *next; } *

variable_types:
mode
char *

variable_types:
tmp
char *

variable_types:
sptr
char *

variable_types: type int

variable_types: code int


decompiled_code:
void **__fastcall parse_trigger(char *s)
{
char *v1; // rax
char *v2; // rbx
char *v3; // r13
char *v4; // rbp
void **v5; // r12
char *v6; // rbx
const unsigned __int16 *v7; // rax
const unsigned __int16 *v8; // rax
char *save_ptr[6]; // [rsp+8h] [rbp-30h] BYREF

v1 = strchr(s, 35);
if ( v1 )
*v1 = 0;
save_ptr[0] = 0LL;
v2 = strtok_r(s, " \t\n", save_ptr);
v3 = strtok_r(0LL, " \t\n", save_ptr);
v4 = strtok_r(0LL, &byte_2C1, save_ptr);
if ( v3 == 0LL || v2 == 0LL || !v4 )
return 0LL;
v5 = (void **)malloc(0x138uLL);
if ( v5 )
{
memset(v5, 0, 0x138uLL);
*((_DWORD *)v5 + 2) = atoi(v3);
if ( (unsigned int)parse_evdef(v2, (__int64)v5) )
{
free(v5[4]);
free(v5[37]);
free(v5);
v5 = 0LL;
}
else
{
v6 = &v4[strlen(v4) - 1];
if ( v4 <= v6 )
{
v7 = *_ctype_b_loc();
do
{
if ( (v7[*v6] & 0x2000) == 0 && *v6 != 10 )
break;
--v6;
}
while ( v4 <= v6 );
}
v6[1] = 0;
v8 = *_ctype_b_loc();
while ( (v8[*v4] & 0x2000) != 0 )
++v4;
v5[37] = strdup(v4);
}
}
else
{
fwrite("Unable to allocate memory for trigger definition!\n", 1uLL, 0x32uLL, stderr);
}
return v5;
}

canonical_decompiled_code:
void **__fastcall func1(char *s)
{
char *v1; // rax
char *v2; // rbx
char *v3; // r13
char *v4; // rbp
void **v5; // r12
char *v6; // rbx
const unsigned __int16 *v7; // rax
const unsigned __int16 *v8; // rax
char *save_ptr[6]; // [rsp+8h] [rbp-30h] BYREF

v1 = strchr(s, 35);
if ( v1 )
*v1 = 0;
save_ptr[0] = 0LL;
v2 = strtok_r(s, " \t\n", save_ptr);
v3 = strtok_r(0LL, " \t\n", save_ptr);
v4 = strtok_r(0LL, &byte_2C1, save_ptr);
if ( v3 == 0LL || v2 == 0LL || !v4 )
return 0LL;
v5 = (void **)malloc(0x138uLL);
if ( v5 )
{
memset(v5, 0, 0x138uLL);
*((_DWORD *)v5 + 2) = atoi(v3);
if ( (unsigned int)func0(v2, (__int64)v5) )
{
free(v5[4]);
free(v5[37]);
free(v5);
v5 = 0LL;
}
else
{
v6 = &v4[strlen(v4) - 1];
if ( v4 <= v6 )
{
v7 = *_ctype_b_loc();
do
{
if ( (v7[*v6] & 0x2000) == 0 && *v6 != 10 )
break;
--v6;
}
while ( v4 <= v6 );
}
v6[1] = 0;
v8 = *_ctype_b_loc();
while ( (v8[*v4] & 0x2000) != 0 )
++v4;
v5[37] = strdup(v4);
}
}
else
{
fwrite("Unable to allocate memory for trigger definition!\n", 1uLL, 0x32uLL, stderr);
}
return v5;
}

original_code:
trigger* parse_trigger(char* line) {
 char *comment = strchr(line, '#');
 if ( comment != ((void *)0) ) {
  *comment = '\0';
 }
 char *delim = " \t\n";
 char *sptr = ((void *)0);
 char *s_evdef = strtok_r(line, delim, &sptr);
 char *s_value = strtok_r(((void *)0), delim, &sptr);
 char *s_action = strtok_r(((void *)0), "", &sptr);
 if (! (s_evdef && s_value && s_action)) {
  return ((void *)0);
 }
 trigger *t = malloc( sizeof(trigger) );
 if (! t) {
  fprintf(stderr, "Unable to allocate memory for trigger definition!\n");
  return ((void *)0);
 }
 memset( t, 0, sizeof(*t) );
 t->next = ((void *)0);
 t->value = atoi(s_value);
 int err = parse_evdef( s_evdef, t );
 if (!err) {
  char *end = s_action + strlen(s_action) - 1;
  while (end >= s_action && (((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short int) _ISspace) || *end == '\n')) {
   end --;
  }
  *(end+1) = '\0';
  while (((*__ctype_b_loc ())[(int) ((*s_action))] & (unsigned short int) _ISspace)) {
   s_action++;
  }
  t->action = strdup(s_action);
 } else {
  free(t->mode);
  free(t->action);
  free(t);
  t = ((void *)0);
 }
 return t;
}

canonical_original_code:
struct trigger *parse_trigger(char *line) {
 char *comment = strchr(line, '#');
 if ( comment != ((void *)0) ) {
  *comment = '\0';
 }
 char *delim = " \t\n";
 char *sptr = ((void *)0);
 char *s_evdef = strtok_r(line, delim, &sptr);
 char *s_value = strtok_r(((void *)0), delim, &sptr);
 char *s_action = strtok_r(((void *)0), "", &sptr);
 if (! (s_evdef && s_value && s_action)) {
  return ((void *)0);
 }
 struct trigger *t = malloc( sizeof(trigger) );
 if (! t) {
  fprintf(stderr, "Unable to allocate memory for trigger definition!\n");
  return ((void *)0);
 }
 memset( t, 0, sizeof(*t) );
 t->next = ((void *)0);
 t->value = atoi(s_value);
 int err = parse_evdef( s_evdef, t );
 if (!err) {
  char *end = s_action + strlen(s_action) - 1;
  while (end >= s_action && (((*__ctype_b_loc ())[(int) ((*end))] & (unsigned short) _ISspace) || *end == '\n')) {
   end --;
  }
  *(end+1) = '\0';
  while (((*__ctype_b_loc ())[(int) ((*s_action))] & (unsigned short) _ISspace)) {
   s_action++;
  }
  t->action = strdup(s_action);
 } else {
  free(t->mode);
  free(t->action);
  free(t);
  t = ((void *)0);
 }
 return t;
}

variable_types:
line
char *

variable_types:
comment
char *

variable_types:
delim
char *

variable_types:
end
char *

return_type: struct trigger { int type; int code; int value; int modifiers[5]; char *mode; char devtag[256]; char *action; struct trigger *next; } *


original_code:
static int mods_equal(keystate_holder ksh, trigger_modifier tm, int ignore_key) {
 int n = 0;
 while ( n < 5 ) {
  int code = tm[n];
  if (code < 0) {
   break;
  } else if (ksh[code] <= 0) {
   return 0;
  }
  n++;
 }
 int x;
 for (x=0; x<=0x2ff; x++) {
  if (x != ignore_key && ksh[x] > 0) {
   n--;
  }
 }
 return (n == 0);
}

canonical_original_code:
static int mods_equal(unsigned short ksh[-1], int tm[5], int ignore_key) {
 int n = 0;
 while ( n < 5 ) {
  int code = tm[n];
  if (code < 0) {
   break;
  } else if (ksh[code] <= 0) {
   return 0;
  }
  n++;
 }
 int x;
 for (x=0; x<=0x2ff; x++) {
  if (x != ignore_key && ksh[x] > 0) {
   n--;
  }
 }
 return (n == 0);
}

variable_types:
ksh
unsigned short [-1]

variable_types:
tm
int [5]

variable_types: n int

variable_types: x int


decompiled_code:
_BOOL8 __fastcall accept_triggerfile(const struct dirent *a1)
{
char *v1; // rax
_BOOL8 result; // rax

v1 = strstr(a1->d_name, ".conf");
if ( v1 )
result = v1[5] == 0;
else
result = 0LL;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(const struct dirent *a1)
{
char *v1; // rax
_BOOL8 result; // rax

v1 = strstr(a1->d_name, ".conf");
if ( v1 )
result = v1[5] == 0;
else
result = 0LL;
return result;
}

original_code:
static int accept_triggerfile(const struct dirent *entry) {
 const char *suffix = ".conf";
 const char *name = entry->d_name;
 char *end = strstr( name, suffix );
 if ( end && end[ strlen(suffix) ] == '\0' ) {
  return 1;
 } else {
  return 0;
 }
}

canonical_original_code:
static int accept_triggerfile(struct dirent *entry) {
 char *suffix = ".conf";
 char *name = entry->d_name;
 char *end = strstr( name, suffix );
 if ( end && end[ strlen(suffix) ] == '\0' ) {
  return 1;
 } else {
  return 0;
 }
}

variable_types: struct dirent { unsigned long d_ino; long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; } *

variable_types:
suffix
char *

variable_types:
name
char *


decompiled_code:
_BOOL8 __fastcall devtag_equal(char *s2, char *s1)
{
_BOOL8 result; // rax

if ( *s1 )
result = strcmp(s1, s2) == 0;
else
result = 1LL;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(char *s2, char *s1)
{
_BOOL8 result; // rax

if ( *s1 )
result = strcmp(s1, s2) == 0;
else
result = 1LL;
return result;
}

original_code:
static int devtag_equal(const char *d_tag, const char *t_tag) {
 if (strlen(t_tag) == 0) {
  return 1;
 }
 if (strcmp(t_tag, d_tag) == 0) {
  return 1;
 }
 return 0;
}

canonical_original_code:
static int devtag_equal(char *d_tag, char *t_tag) {
 if (strlen(t_tag) == 0) {
  return 1;
 }
 if (strcmp(t_tag, d_tag) == 0) {
  return 1;
 }
 return 0;
}


decompiled_code:
void *get_trigger_mode()
{
return trigger_mode;
}

canonical_decompiled_code:
void *func3()
{
return trigger_mode;
}

original_code:
char *get_trigger_mode() {
 return trigger_mode;
}

return_type: char *


decompiled_code:
_BOOL8 __fastcall correct_mode(char *s2)
{
_BOOL8 result; // rax
const char *v2; // rax

result = 1LL;
if ( s2 )
{
v2 = (const char *)get_trigger_mode();
result = strcmp(v2, s2) == 0;
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func4(char *s2)
{
_BOOL8 result; // rax
const char *v2; // rax

result = 1LL;
if ( s2 )
{
v2 = (const char *)func3();
result = strcmp(v2, s2) == 0;
}
return result;
}

original_code:
static int correct_mode( const char *tmode ) {
 return (tmode == ((void *)0)) || (strcmp( get_trigger_mode(), tmode ) == 0);
}

canonical_original_code:
static int correct_mode(char *tmode) {
 return (tmode == ((void *)0)) || (strcmp( get_trigger_mode(), tmode ) == 0);
}

variable_types:
tmode
char *


decompiled_code:
char *__fastcall change_trigger_mode(char *s)
{
char *result; // rax

if ( trigger_mode )
{
free(trigger_mode);
fprintf(stderr, "Changing trigger mode to <%s>\n", s);
}
result = strdup(s);
trigger_mode = result;
return result;
}

canonical_decompiled_code:
char *__fastcall func5(char *s)
{
char *result; // rax

if ( trigger_mode )
{
free(trigger_mode);
fprintf(stderr, "Changing trigger mode to <%s>\n", s);
}
result = strdup(s);
trigger_mode = result;
return result;
}

original_code:
void change_trigger_mode(const char *mode) {
 if (trigger_mode != ((void *)0)) {
  free(trigger_mode);
  fprintf(stderr, "Changing trigger mode to <%s>\n", mode);
 }
 trigger_mode = strdup(mode);
}

canonical_original_code:
void change_trigger_mode(char *mode) {
 if (trigger_mode != ((void *)0)) {
  free(trigger_mode);
  fprintf(stderr, "Changing trigger mode to <%s>\n", mode);
 }
 trigger_mode = strdup(mode);
}

variable_types:
mode
char *


decompiled_code:
void __fastcall triggers_enabled(int a1)
{
triggers_are_enabled = a1;
}

canonical_decompiled_code:
void __fastcall func6(int a1)
{
triggers_are_enabled = a1;
}

original_code:
void triggers_enabled( int status ) {
 triggers_are_enabled = status;
}

canonical_original_code:
void triggers_enabled(int status) {
 triggers_are_enabled = status;
}

variable_types: status int


decompiled_code:
__int64 __fastcall read_triggers(char *src)
{
int v1; // eax
unsigned __int64 v2; // rbx
__int64 result; // rax
char *v4; // r12
size_t v5; // r13
void *v6; // rsp
char v7[8]; // [rsp+0h] [rbp-170h] BYREF
unsigned __int64 v8; // [rsp+8h] [rbp-168h]
struct dirent **namelist; // [rsp+18h] [rbp-158h] BYREF
struct stat v10; // [rsp+20h] [rbp-150h] BYREF
struct stat v11; // [rsp+B0h] [rbp-C0h] BYREF

if ( stat(src, &v11) == -1 )
{
perror("stat");
result = 1LL;
}
else if ( (v11.st_mode & 0xF000) == 0x4000 )
{
v1 = scandir(
src,
&namelist,
(int (*)(const struct dirent *))accept_triggerfile,
(int (*)(const struct dirent **, const struct dirent **))&alphasort);
if ( v1 < 0 )
{
perror("scandir");
result = 1LL;
}
else
{
if ( v1 )
{
v2 = 8LL * (v1 - 1);
v8 = 8 * (v1 - (unsigned __int64)(unsigned int)(v1 - 1)) - 16;
do
{
v4 = namelist[v2 / 8]->d_name;
v5 = strlen(src);
v6 = alloca(16 * ((v5 + strlen(v4) + 17) / 0x10));
strcpy(v7, src);
*(_WORD *)&v7[strlen(v7)] = 47;
strcat(v7, v4);
if ( stat(v7, &v10) == -1 )
perror("stat");
if ( (v10.st_mode & 0xF000) == 0x8000 )
read_triggerfile(v7);
free(namelist[v2 / 8]);
v2 -= 8LL;
}
while ( v2 != v8 );
}
free(namelist);
result = 0LL;
}
}
else
{
result = read_triggerfile(src);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(char *src)
{
int v1; // eax
unsigned __int64 v2; // rbx
__int64 result; // rax
char *v4; // r12
size_t v5; // r13
void *v6; // rsp
char v7[8]; // [rsp+0h] [rbp-170h] BYREF
unsigned __int64 v8; // [rsp+8h] [rbp-168h]
struct dirent **namelist; // [rsp+18h] [rbp-158h] BYREF
struct stat v10; // [rsp+20h] [rbp-150h] BYREF
struct stat v11; // [rsp+B0h] [rbp-C0h] BYREF

if ( stat(src, &v11) == -1 )
{
perror("stat");
result = 1LL;
}
else if ( (v11.st_mode & 0xF000) == 0x4000 )
{
v1 = scandir(
src,
&namelist,
(int (*)(const struct dirent *))accept_triggerfile,
(int (*)(const struct dirent **, const struct dirent **))&alphasort);
if ( v1 < 0 )
{
perror("scandir");
result = 1LL;
}
else
{
if ( v1 )
{
v2 = 8LL * (v1 - 1);
v8 = 8 * (v1 - (unsigned __int64)(unsigned int)(v1 - 1)) - 16;
do
{
v4 = namelist[v2 / 8]->d_name;
v5 = strlen(src);
v6 = alloca(16 * ((v5 + strlen(v4) + 17) / 0x10));
strcpy(v7, src);
*(_WORD *)&v7[strlen(v7)] = 47;
strcat(v7, v4);
if ( stat(v7, &v10) == -1 )
perror("stat");
if ( (v10.st_mode & 0xF000) == 0x8000 )
func7(v7);
free(namelist[v2 / 8]);
v2 -= 8LL;
}
while ( v2 != v8 );
}
free(namelist);
result = 0LL;
}
}
else
{
result = func7(src);
}
return result;
}

original_code:
int read_triggers(const char *path) {
 struct stat sb;
 if (stat(path, &sb) == -1) {
  perror("stat");
  return 1;
 }
 if (((((sb.st_mode)) & 0170000) == (0040000))) {
  struct dirent **namelist;
  int n;
  n = scandir(path, &namelist, accept_triggerfile, alphasort);
  if ( n < 0) {
   perror("scandir");
   return 1;
  } else {
   while (n--) {
    struct stat sf;
    char *file = namelist[n]->d_name;
    char *sep = "/";
    char fpath[strlen(path)+strlen(sep)+strlen(file) + 1];
    strcpy(fpath, path);
    strcat(fpath, sep);
    strcat(fpath, file);
    if (stat(fpath, &sf) == -1) {
     perror("stat");
    }
    if (((((sf.st_mode)) & 0170000) == (0100000))) {
     read_triggerfile(fpath);
    }
    free(namelist[n]);
   }
   free(namelist);
   return 0;
  }
 } else {
  return read_triggerfile( path );
 }
}

canonical_original_code:
int read_triggers(char *path) {
 struct stat sb;
 if (stat(path, &sb) == -1) {
  perror("stat");
  return 1;
 }
 if (((((sb.st_mode)) & 0170000) == (0040000))) {
  struct dirent **namelist;
  int n;
  n = scandir(path, &namelist, accept_triggerfile, alphasort);
  if ( n < 0) {
   perror("scandir");
   return 1;
  } else {
   while (n--) {
    struct stat sf;
    char *file = namelist[n]->d_name;
    char *sep = "/";
    char fpath[-1];
    strcpy(fpath, path);
    strcat(fpath, sep);
    strcat(fpath, file);
    if (stat(fpath, &sf) == -1) {
     perror("stat");
    }
    if (((((sf.st_mode)) & 0170000) == (0100000))) {
     read_triggerfile(fpath);
    }
    free(namelist[n]);
   }
   free(namelist);
   return 0;
  }
 } else {
  return read_triggerfile( path );
 }
}

variable_types:
path
char *

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

variable_types: struct dirent { unsigned long d_ino; long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; } **

variable_types:
file
char *

variable_types:
sep
char *

variable_types:
fpath
char [-1]

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


decompiled_code:
void __fastcall run_triggers(int a1, int a2, int a3, __int64 a4, __int64 a5)
{
unsigned int *v6; // rbx
int v7; // eax
char *v8; // r15
const char *v9; // r14
unsigned int v10; // er14
const char *v11; // r14
_BYTE *v12; // r14
__pid_t v13; // eax
const char *v14; // rax
const char *v15; // rax
int v18; // [rsp+18h] [rbp-50h]
unsigned int v19; // [rsp+1Ch] [rbp-4Ch]
char s[64]; // [rsp+28h] [rbp-40h] BYREF

if ( triggers_are_enabled )
{
v6 = (unsigned int *)trigger_list;
if ( trigger_list )
{
v7 = -1;
if ( a1 == 1 )
v7 = a2;
v18 = v7;
v8 = (char *)(a5 + 20);
do
{
if ( *v6 == a1 && v6[1] == a2 && v6[2] == a3 )
{
v11 = (const char *)*((_QWORD *)v6 + 37);
if ( v11 )
{
if ( correct_mode(*((char **)v6 + 4))
&& devtag_equal(v8, (char *)v6 + 40)
&& mods_equal(a4, (int *)v6 + 3, v18) )
{
fprintf(stderr, "Executing trigger action: %s\n", v11);
v12 = (_BYTE *)*((_QWORD *)v6 + 37);
if ( *v12 == 64 )
{
change_trigger_mode(v12 + 1);
return;
}
if ( *v12 == 60 )
{
v9 = v12 + 1;
fprintf(stderr, "Sending event: %s\n", v9);
v19 = lookup_event_type(v9);
v10 = lookup_event_code(v9);
if ( v19 && v10 )
{
send_event(v19, v10, 1LL);
send_event(v19, v10, 0LL);
send_event(0LL, 0LL, 0LL);
}
}
else
{
v13 = fork();
if ( !v13 )
{
setenv("TH_DEVICE", *(const char **)(a5 + 8), 1);
v14 = (const char *)get_keystate(a4);
setenv("TH_KEYSTATE", v14, 1);
v15 = (const char *)lookup_event_name_i(*v6, v6[1]);
setenv("TH_EVENT", v15, 1);
sprintf(s, "%d", v6[2]);
setenv("TH_VALUE", s, 1);
signal(17, 0LL);
system(*((const char **)v6 + 37));
exit(0);
}
if ( v13 < 0 )
fwrite("Unable to fork!\n", 1uLL, 0x10uLL, stderr);
}
}
}
}
v6 = (unsigned int *)*((_QWORD *)v6 + 38);
}
while ( v6 );
}
}
}

canonical_decompiled_code:
void __fastcall func9(int a1, int a2, int a3, __int64 a4, __int64 a5)
{
unsigned int *v6; // rbx
int v7; // eax
char *v8; // r15
const char *v9; // r14
unsigned int v10; // er14
const char *v11; // r14
_BYTE *v12; // r14
__pid_t v13; // eax
const char *v14; // rax
const char *v15; // rax
int v18; // [rsp+18h] [rbp-50h]
unsigned int v19; // [rsp+1Ch] [rbp-4Ch]
char s[64]; // [rsp+28h] [rbp-40h] BYREF

if ( triggers_are_enabled )
{
v6 = (unsigned int *)trigger_list;
if ( trigger_list )
{
v7 = -1;
if ( a1 == 1 )
v7 = a2;
v18 = v7;
v8 = (char *)(a5 + 20);
do
{
if ( *v6 == a1 && v6[1] == a2 && v6[2] == a3 )
{
v11 = (const char *)*((_QWORD *)v6 + 37);
if ( v11 )
{
if ( func4(*((char **)v6 + 4))
&& func2(v8, (char *)v6 + 40)
&& func0(a4, (int *)v6 + 3, v18) )
{
fprintf(stderr, "Executing trigger action: %s\n", v11);
v12 = (_BYTE *)*((_QWORD *)v6 + 37);
if ( *v12 == 64 )
{
func5(v12 + 1);
return;
}
if ( *v12 == 60 )
{
v9 = v12 + 1;
fprintf(stderr, "Sending event: %s\n", v9);
v19 = lookup_event_type(v9);
v10 = lookup_event_code(v9);
if ( v19 && v10 )
{
send_event(v19, v10, 1LL);
send_event(v19, v10, 0LL);
send_event(0LL, 0LL, 0LL);
}
}
else
{
v13 = fork();
if ( !v13 )
{
setenv("TH_DEVICE", *(const char **)(a5 + 8), 1);
v14 = (const char *)get_keystate(a4);
setenv("TH_KEYSTATE", v14, 1);
v15 = (const char *)lookup_event_name_i(*v6, v6[1]);
setenv("TH_EVENT", v15, 1);
sprintf(s, "%d", v6[2]);
setenv("TH_VALUE", s, 1);
signal(17, 0LL);
system(*((const char **)v6 + 37));
exit(0);
}
if ( v13 < 0 )
fwrite("Unable to fork!\n", 1uLL, 0x10uLL, stderr);
}
}
}
}
v6 = (unsigned int *)*((_QWORD *)v6 + 38);
}
while ( v6 );
}
}
}

original_code:
void run_triggers(int type, int code, int value, keystate_holder ksh, device *dev) {
 if (triggers_are_enabled == 0) {
  return;
 }
 if (dev && dev->tag) {
 }
 trigger *et = trigger_list;
 while (et != ((void *)0)) {
  if ( type == et->type &&
       code == et->code &&
       value == et->value &&
       et->action &&
       correct_mode( et->mode ) &&
       devtag_equal(&(dev->tag[0]), &(et->devtag[0])) &&
       mods_equal(ksh, et->modifiers, (type==0x01?code:-1) )) {
   fprintf(stderr, "Executing trigger action: %s\n", et->action);
   if (et->action[0] == '@') {
    change_trigger_mode( &(et->action)[1] );
    break;
   } else if (et->action[0] == '<' ) {
    char *keyname = &(et->action[1]);
    fprintf(stderr, "Sending event: %s\n", keyname);
    int type = lookup_event_type( keyname );
    int code = lookup_event_code( keyname );
    if (type && code) {
     send_event( type, code, 1 );
     send_event( type, code, 0 );
     send_event( 0x00, 0, 0 );
    }
   } else {
    int pid = fork();
    if (pid == 0 ) {
     setenv( "TH_DEVICE", dev->devname, 1 );
     setenv( "TH_KEYSTATE", get_keystate(ksh), 1 );
     const char *en = lookup_event_name_i( et->type, et->code );
     setenv( "TH_EVENT", en, 1 );
     char ev[8];
     sprintf( &(ev[0]), "%d", et->value );
     setenv( "TH_VALUE", &(ev[0]), 1 );
     signal(17, ((__sighandler_t) 0));
     system(et->action);
     exit(0);
    } else if (pid < 0) {
     fprintf(stderr, "Unable to fork!\n");
    }
   }
  }
  et = et->next;
 }
}

canonical_original_code:
void run_triggers(int type, int code, int value, unsigned short ksh[-1], struct device *dev) {
 if (triggers_are_enabled == 0) {
  return;
 }
 if (dev && dev->tag) {
 }
 struct trigger *et = trigger_list;
 while (et != ((void *)0)) {
  if ( type == et->type &&
       code == et->code &&
       value == et->value &&
       et->action &&
       correct_mode( et->mode ) &&
       devtag_equal(&(dev->tag[0]), &(et->devtag[0])) &&
       mods_equal(ksh, et->modifiers, (type==0x01?code:-1) )) {
   fprintf(stderr, "Executing trigger action: %s\n", et->action);
   if (et->action[0] == '@') {
    change_trigger_mode( &(et->action)[1] );
    break;
   } else if (et->action[0] == '<' ) {
    char *keyname = &(et->action[1]);
    fprintf(stderr, "Sending event: %s\n", keyname);
    int type = lookup_event_type( keyname );
    int code = lookup_event_code( keyname );
    if (type && code) {
     send_event( type, code, 1 );
     send_event( type, code, 0 );
     send_event( 0x00, 0, 0 );
    }
   } else {
    int pid = fork();
    if (pid == 0 ) {
     setenv( "TH_DEVICE", dev->devname, 1 );
     setenv( "TH_KEYSTATE", get_keystate(ksh), 1 );
     char *en = lookup_event_name_i( et->type, et->code );
     setenv( "TH_EVENT", en, 1 );
     char ev[8];
     sprintf( &(ev[0]), "%d", et->value );
     setenv( "TH_VALUE", &(ev[0]), 1 );
     signal(17, ((void (*)(int)) 0));
     system(et->action);
     exit(0);
    } else if (pid < 0) {
     fprintf(stderr, "Unable to fork!\n");
    }
   }
  }
  et = et->next;
 }
}

variable_types: type int

variable_types: code int

variable_types: value int

variable_types: struct device { int fd; char *devname; int exclusive; char tag[256]; struct device *next; } *

variable_types: struct trigger { int type; int code; int value; int modifiers[5]; char *mode; char devtag[256]; char *action; struct trigger *next; } *

variable_types:
keyname
char *

variable_types: pid int

variable_types:
en
char *

variable_types:
ev
char [8]


decompiled_code:
__int64 __fastcall count_triggers(__int64 *a1)
{
__int64 v1; // rax
unsigned int v2; // edx

if ( !a1 )
return 0;
v1 = *a1;
if ( !*a1 )
return 0;
v2 = 0;
do
{
++v2;
v1 = *(_QWORD *)(v1 + 304);
}
while ( v1 );
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 *a1)
{
__int64 v1; // rax
unsigned int v2; // edx

if ( !a1 )
return 0;
v1 = *a1;
if ( !*a1 )
return 0;
v2 = 0;
do
{
++v2;
v1 = *(_QWORD *)(v1 + 304);
}
while ( v1 );
return v2;
}

original_code:
int count_triggers( trigger **list ) {
 int n = 0;
 if(!list)
  return 0;
 trigger *p = *list;
 while ( p != ((void *)0) ) {
  n++;
  p = p->next;
 }
 return n;
}

canonical_original_code:
int count_triggers(struct trigger **list) {
 int n = 0;
 if(!list)
  return 0;
 struct trigger *p = *list;
 while ( p != ((void *)0) ) {
  n++;
  p = p->next;
 }
 return n;
}

variable_types: struct trigger { int type; int code; int value; int modifiers[5]; char *mode; char devtag[256]; char *action; struct trigger *next; } **

variable_types: n int


decompiled_code:
void clear_triggers()
{
void **v0; // rbx
void **v1; // rbp

v0 = (void **)trigger_list;
if ( trigger_list )
{
do
{
v1 = v0;
v0 = (void **)v0[38];
free(v1[37]);
free(v1[4]);
free(v1);
}
while ( v0 );
}
trigger_list = 0LL;
}

canonical_decompiled_code:
void func11()
{
void **v0; // rbx
void **v1; // rbp

v0 = (void **)trigger_list;
if ( trigger_list )
{
do
{
v1 = v0;
v0 = (void **)v0[38];
free(v1[37]);
free(v1[4]);
free(v1);
}
while ( v0 );
}
trigger_list = 0LL;
}

original_code:
void clear_triggers() {
 trigger *p = trigger_list;
 while (p != ((void *)0)) {
  trigger *next = p->next;
  free(p->action);
  free(p->mode);
  free(p);
  p = next;
 }
 trigger_list = ((void *)0);
}

canonical_original_code:
void clear_triggers() {
 struct trigger *p = trigger_list;
 while (p != ((void *)0)) {
  struct trigger *next = p->next;
  free(p->action);
  free(p->mode);
  free(p);
  p = next;
 }
 trigger_list = ((void *)0);
}

user_defined_types: struct trigger { int type; int code; int value; int modifiers[5]; char *mode; char devtag[256]; char *action; struct trigger *next; }


original_code:
static __inline__ int test_bit(int nr, uint32_t * addr) {
 uint32_t mask;
 addr += nr >> 5;
 mask = 1 << (nr & 0x1f);
 return ((mask & *addr) != 0);
}

canonical_original_code:
static __inline__ int test_bit(int nr, unsigned int *addr) {
 unsigned int mask;
 addr += nr >> 5;
 mask = 1 << (nr & 0x1f);
 return ((mask & *addr) != 0);
}

variable_types: nr int

variable_types:
addr
unsigned int *

variable_types:
mask
unsigned int


original_code:
char *get_device_description(int fd) {
 char descr[256] = "Unknown";
 if(ioctl(fd, (((2U) << (((0 +8)+8)+14)) | (('E') << (0 +8)) | ((0x06) << 0) | ((sizeof(descr)) << ((0 +8)+8))), descr) < 0) {
  perror("evdev ioctl");
 }
 return strdup(descr);
}

variable_types: fd int

variable_types:
descr
char [256]


decompiled_code:
_BOOL8 __fastcall device_is_suitable(int a1)
{
int v1; // edx
_BOOL8 result; // rax
_BOOL4 v3; // edx
_BYTE v4[136]; // [rsp+0h] [rbp-88h] BYREF

v1 = ioctl(a1, 0x80804520uLL, v4);
result = 0LL;
if ( v1 > 0 )
{
v3 = test_bit(1, (__int64)v4);
result = 1LL;
if ( !v3 )
result = test_bit(5, (__int64)v4);
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(int a1)
{
int v1; // edx
_BOOL8 result; // rax
_BOOL4 v3; // edx
_BYTE v4[136]; // [rsp+0h] [rbp-88h] BYREF

v1 = ioctl(a1, 0x80804520uLL, v4);
result = 0LL;
if ( v1 > 0 )
{
v3 = func0(1, (__int64)v4);
result = 1LL;
if ( !v3 )
result = func0(5, (__int64)v4);
}
return result;
}

variable_types:
bits
unsigned int [32]

variable_types: rc int


decompiled_code:
void __fastcall add_device(char *file, int fd, int a3, const char *a4)
{
int v4; // ebx
_QWORD *v7; // rax
_QWORD *v8; // rdx
void **v9; // r14
void *v10; // rdx
_QWORD *v11; // r15
int *v12; // rax
char *v13; // rax

v4 = fd;
v7 = device_list;
if ( device_list )
{
do
{
v8 = v7;
v7 = (_QWORD *)v7[35];
}
while ( v7 );
v9 = (void **)(v8 + 35);
}
else
{
v9 = &device_list;
}
if ( fd >= 0 || (v4 = open(file, 0), v4 >= 0) )
{
if ( device_is_suitable(v4) )
{
if ( a3 && ioctl(v4, 0x40044590uLL, 1LL) == -1 )
{
fprintf(stderr, "Device %s cannot be grabbed exclusively.\n", file);
close(v4);
}
else
{
v10 = malloc(0x120uLL);
*v9 = v10;
if ( v10 && (memset(v10, 0, 0x120uLL), v11 = *v9, v11[1] = strdup(file), *((_QWORD *)*v9 + 1)) )
{
*(_DWORD *)*v9 = v4;
*((_DWORD *)*v9 + 4) = a3;
if ( a4 )
{
strncpy((char *)*v9 + 20, a4, 0x100uLL);
*((_BYTE *)*v9 + 275) = 0;
}
*((_QWORD *)*v9 + 35) = 0LL;
}
else
{
fwrite("Unable to allocate memory for new device!\n", 1uLL, 0x2AuLL, stderr);
if ( *v9 )
free(*((void **)*v9 + 1));
free(*v9);
*v9 = 0LL;
}
}
}
else
{
fprintf(stderr, "Device %s not suitable.\n", file);
close(v4);
}
}
else
{
v12 = _errno_location();
v13 = strerror(*v12);
fprintf(stderr, "Error opening '%s': %s\n", file, v13);
}
}

canonical_decompiled_code:
void __fastcall func3(char *file, int fd, int a3, const char *a4)
{
int v4; // ebx
_QWORD *v7; // rax
_QWORD *v8; // rdx
void **v9; // r14
void *v10; // rdx
_QWORD *v11; // r15
int *v12; // rax
char *v13; // rax

v4 = fd;
v7 = device_list;
if ( device_list )
{
do
{
v8 = v7;
v7 = (_QWORD *)v7[35];
}
while ( v7 );
v9 = (void **)(v8 + 35);
}
else
{
v9 = &device_list;
}
if ( fd >= 0 || (v4 = open(file, 0), v4 >= 0) )
{
if ( func2(v4) )
{
if ( a3 && ioctl(v4, 0x40044590uLL, 1LL) == -1 )
{
fprintf(stderr, "Device %s cannot be grabbed exclusively.\n", file);
close(v4);
}
else
{
v10 = malloc(0x120uLL);
*v9 = v10;
if ( v10 && (memset(v10, 0, 0x120uLL), v11 = *v9, v11[1] = strdup(file), *((_QWORD *)*v9 + 1)) )
{
*(_DWORD *)*v9 = v4;
*((_DWORD *)*v9 + 4) = a3;
if ( a4 )
{
strncpy((char *)*v9 + 20, a4, 0x100uLL);
*((_BYTE *)*v9 + 275) = 0;
}
*((_QWORD *)*v9 + 35) = 0LL;
}
else
{
fwrite("Unable to allocate memory for new device!\n", 1uLL, 0x2AuLL, stderr);
if ( *v9 )
free(*((void **)*v9 + 1));
free(*v9);
*v9 = 0LL;
}
}
}
else
{
fprintf(stderr, "Device %s not suitable.\n", file);
close(v4);
}
}
else
{
v12 = _errno_location();
v13 = strerror(*v12);
fprintf(stderr, "Error opening '%s': %s\n", file, v13);
}
}

original_code:
void add_device(char *dev, int fd, int excl, char *tag) {
 device **p = &device_list;
 while (*p != ((void *)0)) {
  p = &( (*p)->next );
 }
 if (fd < 0) {
  fd = open( dev, 00 );
 }
 if (fd >= 0) {
  if (! device_is_suitable(fd) ) {
   fprintf(stderr, "Device %s not suitable.\n", dev);
   close(fd);
   return;
  }
  if (excl) {
   if (ioctl(fd, (((1U) << (((0 +8)+8)+14)) | ((('E')) << (0 +8)) | (((0x90)) << 0) | ((((sizeof(int)))) << ((0 +8)+8))), 1) == -1) {
    fprintf(stderr, "Device %s cannot be grabbed exclusively.\n", dev);
    close(fd);
    return;
   }
  }
  *p = malloc(sizeof(device));
  if (*p == ((void *)0)) goto nomem_cleanup;
  memset(*p, 0, sizeof(device));
  (*p)->devname = strdup(dev);
  if ((*p)->devname == ((void *)0)) goto nomem_cleanup;
  (*p)->fd = fd;
  (*p)->exclusive = excl;
  if (tag) {
   strncpy((*p)->tag, tag, 256);
   (*p)->tag[256 -1] = '\0';
  }
  (*p)->next = ((void *)0);
 } else {
  fprintf( stderr, "Error opening '%s': %s\n", dev, strerror((*__errno_location ())) );
 }
 return;
nomem_cleanup:
 fprintf(stderr, "Unable to allocate memory for new device!\n");
 if (*p) {
  free( (*p)->devname );
 }
 free(*p);
 *p = ((void *)0);
}

canonical_original_code:
void add_device(char *dev, int fd, int excl, char *tag) {
 struct device **p = &device_list;
 while (*p != ((void *)0)) {
  p = &( (*p)->next );
 }
 if (fd < 0) {
  fd = open( dev, 00 );
 }
 if (fd >= 0) {
  if (! device_is_suitable(fd) ) {
   fprintf(stderr, "Device %s not suitable.\n", dev);
   close(fd);
   return;
  }
  if (excl) {
   if (ioctl(fd, (((1U) << (((0 +8)+8)+14)) | ((('E')) << (0 +8)) | (((0x90)) << 0) | ((((sizeof(int)))) << ((0 +8)+8))), 1) == -1) {
    fprintf(stderr, "Device %s cannot be grabbed exclusively.\n", dev);
    close(fd);
    return;
   }
  }
  *p = malloc(sizeof(device));
  if (*p == ((void *)0)) goto nomem_cleanup;
  memset(*p, 0, sizeof(device));
  (*p)->devname = strdup(dev);
  if ((*p)->devname == ((void *)0)) goto nomem_cleanup;
  (*p)->fd = fd;
  (*p)->exclusive = excl;
  if (tag) {
   strncpy((*p)->tag, tag, 256);
   (*p)->tag[256 -1] = '\0';
  }
  (*p)->next = ((void *)0);
 } else {
  fprintf( stderr, "Error opening '%s': %s\n", dev, strerror((*__errno_location ())) );
 }
 return;
nomem_cleanup:
 fprintf(stderr, "Unable to allocate memory for new device!\n");
 if (*p) {
  free( (*p)->devname );
 }
 free(*p);
 *p = ((void *)0);
}

variable_types:
dev
char *

variable_types: excl int

variable_types:
tag
char *

variable_types: struct device { int fd; char *devname; int exclusive; char tag[256]; struct device *next; } **


decompiled_code:
__int64 __fastcall remove_device(char *s2)
{
char *v1; // rbx
void **v2; // r12

v1 = (char *)device_list;
if ( !device_list )
return 0LL;
v2 = &device_list;
while ( strcmp(*((const char **)v1 + 1), s2) )
{
v2 = (void **)(v1 + 280);
v1 = (char *)*((_QWORD *)v1 + 35);
if ( !v1 )
return 0LL;
}
*v2 = (void *)*((_QWORD *)v1 + 35);
close(*(_DWORD *)v1);
free(*((void **)v1 + 1));
free(v1);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *s2)
{
char *v1; // rbx
void **v2; // r12

v1 = (char *)device_list;
if ( !device_list )
return 0LL;
v2 = &device_list;
while ( strcmp(*((const char **)v1 + 1), s2) )
{
v2 = (void **)(v1 + 280);
v1 = (char *)*((_QWORD *)v1 + 35);
if ( !v1 )
return 0LL;
}
*v2 = (void *)*((_QWORD *)v1 + 35);
close(*(_DWORD *)v1);
free(*((void **)v1 + 1));
free(v1);
return 1LL;
}

original_code:
int remove_device(char *dev) {
 device **p = &device_list;
 while (*p != ((void *)0)) {
  if ( strcmp( (*p)->devname, dev ) == 0 ) {
   device *copy = *p;
   *p = copy->next;
   close(copy->fd);
   free(copy->devname);
   free(copy);
   return 1;
  }
  p = &( (*p)->next );
 }
 return 0;
}

canonical_original_code:
int remove_device(char *dev) {
 struct device **p = &device_list;
 while (*p != ((void *)0)) {
  if ( strcmp( (*p)->devname, dev ) == 0 ) {
   struct device *copy = *p;
   *p = copy->next;
   close(copy->fd);
   free(copy->devname);
   free(copy);
   return 1;
  }
  p = &( (*p)->next );
 }
 return 0;
}

variable_types: struct device { int fd; char *devname; int exclusive; char tag[256]; struct device *next; } *


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

v0 = device_list;
if ( device_list )
{
do
{
v1 = v0;
v0 = (_QWORD *)v0[35];
close(*(_DWORD *)v1);
free(*((void **)v1 + 1));
free(v1);
}
while ( v0 );
}
device_list = 0LL;
}

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

v0 = device_list;
if ( device_list )
{
do
{
v1 = v0;
v0 = (_QWORD *)v0[35];
close(*(_DWORD *)v1);
free(*((void **)v1 + 1));
free(v1);
}
while ( v0 );
}
device_list = 0LL;
}

original_code:
void clear_devices(void) {
 device *p = device_list;
 while (p != ((void *)0)) {
  device *next = p->next;
  close(p->fd);
  free(p->devname);
  free(p);
  p = next;
 }
 device_list = ((void *)0);
}

canonical_original_code:
void clear_devices() {
 struct device *p = device_list;
 while (p != ((void *)0)) {
  struct device *next = p->next;
  close(p->fd);
  free(p->devname);
  free(p);
  p = next;
 }
 device_list = ((void *)0);
}

user_defined_types: struct device { int fd; char *devname; int exclusive; char tag[256]; struct device *next; }


decompiled_code:
__int64 count_devices()
{
_QWORD *v0; // rax
unsigned int v1; // edx

v0 = device_list;
if ( !device_list )
return 0;
v1 = 0;
do
{
++v1;
v0 = (_QWORD *)v0[35];
}
while ( v0 );
return v1;
}

canonical_decompiled_code:
__int64 func6()
{
_QWORD *v0; // rax
unsigned int v1; // edx

v0 = device_list;
if ( !device_list )
return 0;
v1 = 0;
do
{
++v1;
v0 = (_QWORD *)v0[35];
}
while ( v0 );
return v1;
}

original_code:
int count_devices(void) {
 int n = 0;
 device *p = device_list;
 while (p != ((void *)0)) {
  n++;
  p = p->next;
 }
 return n;
}

canonical_original_code:
int count_devices() {
 int n = 0;
 struct device *p = device_list;
 while (p != ((void *)0)) {
  n++;
  p = p->next;
 }
 return n;
}


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

v1 = device_list;
if ( device_list )
{
do
{
result = a1(v1);
v1 = (_QWORD *)v1[35];
}
while ( v1 );
}
return result;
}

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

v1 = device_list;
if ( device_list )
{
do
{
result = a1(v1);
v1 = (_QWORD *)v1[35];
}
while ( v1 );
}
return result;
}

original_code:
void for_each_device( void(*func)(device*) ) {
 device *p = device_list;
 while (p != ((void *)0)) {
  func( p );
  p = p->next;
 }
}

canonical_original_code:
void for_each_device(void (*func)(struct device *)) {
 struct device *p = device_list;
 while (p != ((void *)0)) {
  func( p );
  p = p->next;
 }
}

variable_types: void (*)(struct device { int fd; char *devname; int exclusive; char tag[256]; struct device *next; } *)


decompiled_code:
size_t __fastcall init_keystate_holder(_QWORD *a1)
{
size_t result; // rax
void *v2; // rax

if ( !*a1 )
{
v2 = malloc(0x600uLL);
*a1 = v2;
if ( !v2 )
return fwrite("Unable to allocate memory for keystate table!\n", 1uLL, 0x2EuLL, stderr);
}
LODWORD(result) = 0;
do
{
*(_WORD *)(*a1 + 2LL * (int)result) = 0;
result = (unsigned int)(result + 1);
}
while ( (_DWORD)result != 768 );
return result;
}

canonical_decompiled_code:
size_t __fastcall func0(_QWORD *a1)
{
size_t result; // rax
void *v2; // rax

if ( !*a1 )
{
v2 = malloc(0x600uLL);
*a1 = v2;
if ( !v2 )
return fwrite("Unable to allocate memory for keystate table!\n", 1uLL, 0x2EuLL, stderr);
}
LODWORD(result) = 0;
do
{
*(_WORD *)(*a1 + 2LL * (int)result) = 0;
result = (unsigned int)(result + 1);
}
while ( (_DWORD)result != 768 );
return result;
}

original_code:
void init_keystate_holder(keystate_holder **ksh) {
 if (*ksh == ((void *)0)) {
  *ksh = malloc(sizeof(keystate_holder));
 }
 if (*ksh == ((void *)0)) {
  fprintf(stderr, "Unable to allocate memory for keystate table!\n");
  return;
 }
 int i;
 for (i=0; i<=0x2ff; i++) {
  (**ksh)[i] = 0;
 }
}

canonical_original_code:
void init_keystate_holder(unsigned short (**ksh)[-1]) {
 if (*ksh == ((void *)0)) {
  *ksh = malloc(sizeof(keystate_holder));
 }
 if (*ksh == ((void *)0)) {
  fprintf(stderr, "Unable to allocate memory for keystate table!\n");
  return;
 }
 int i;
 for (i=0; i<=0x2ff; i++) {
  (**ksh)[i] = 0;
 }
}

variable_types:
ksh
unsigned short (**)[-1]

variable_types: i int


decompiled_code:
char *__fastcall get_keystate_ignore_key(__int64 a1, int a2)
{
__int64 v2; // rbx
int v3; // er12
size_t v4; // rax
size_t v5; // rax
char *v6; // rax
char *v7; // rbx
char v9[1032]; // [rsp+0h] [rbp-440h] BYREF
char *src; // [rsp+408h] [rbp-38h]

v9[0] = 0;
v2 = 0LL;
v3 = 0;
do
{
LODWORD(src) = v2;
if ( a2 != (_DWORD)v2 && *(_WORD *)(a1 + 2 * v2) )
{
if ( v3 > 0 )
*(_WORD *)&v9[strlen(v9)] = 43;
src = (char *)lookup_event_name_i(1LL, (unsigned int)src);
v4 = strlen(v9);
strncat(v9, src, 1023 - v4);
++v3;
}
++v2;
}
while ( v2 != 768 );
v5 = strlen(v9);
v6 = (char *)malloc(v5 + 1);
v7 = v6;
if ( v6 )
strcpy(v6, v9);
return v7;
}

canonical_decompiled_code:
char *__fastcall func2(__int64 a1, int a2)
{
__int64 v2; // rbx
int v3; // er12
size_t v4; // rax
size_t v5; // rax
char *v6; // rax
char *v7; // rbx
char v9[1032]; // [rsp+0h] [rbp-440h] BYREF
char *src; // [rsp+408h] [rbp-38h]

v9[0] = 0;
v2 = 0LL;
v3 = 0;
do
{
LODWORD(src) = v2;
if ( a2 != (_DWORD)v2 && *(_WORD *)(a1 + 2 * v2) )
{
if ( v3 > 0 )
*(_WORD *)&v9[strlen(v9)] = 43;
src = (char *)lookup_event_name_i(1LL, (unsigned int)src);
v4 = strlen(v9);
strncat(v9, src, 1023 - v4);
++v3;
}
++v2;
}
while ( v2 != 768 );
v5 = strlen(v9);
v6 = (char *)malloc(v5 + 1);
v7 = v6;
if ( v6 )
strcpy(v6, v9);
return v7;
}

original_code:
char *get_keystate_ignore_key(keystate_holder ksh, int ignore_key) {
 const int bsize = 1024;
 char *KS = "+";
 char buf[bsize];
 buf[0] = '\0';
 int i;
 int n = 0;
 for (i=0; i<=0x2ff; i++) {
  if (i != ignore_key && ksh[i] > 0) {
   if (n>0) {
    strncat( buf, KS, bsize-1-strlen(KS) );
   }
   const char *name = lookup_event_name_i(0x01, i);
   strncat( &(buf[0]), name, bsize-1-strlen(buf) );
   n++;
  }
 }
 char *res = malloc( sizeof(char) * (1+strlen(buf)) );
 if (res) {
  strcpy( res, buf );
 }
 return res;
}

canonical_original_code:
char *get_keystate_ignore_key(unsigned short ksh[-1], int ignore_key) {
 int bsize = 1024;
 char *KS = "+";
 char buf[-1];
 buf[0] = '\0';
 int i;
 int n = 0;
 for (i=0; i<=0x2ff; i++) {
  if (i != ignore_key && ksh[i] > 0) {
   if (n>0) {
    strncat( buf, KS, bsize-1-strlen(KS) );
   }
   char *name = lookup_event_name_i(0x01, i);
   strncat( &(buf[0]), name, bsize-1-strlen(buf) );
   n++;
  }
 }
 char *res = malloc( sizeof(char) * (1+strlen(buf)) );
 if (res) {
  strcpy( res, buf );
 }
 return res;
}

variable_types:
ksh
unsigned short [-1]

variable_types: bsize int

variable_types:
KS
char *

variable_types:
buf
char [-1]

variable_types:
name
char *

variable_types:
res
char *


decompiled_code:
char *__fastcall get_keystate(__int64 a1)
{
return get_keystate_ignore_key(a1, -1);
}

canonical_decompiled_code:
char *__fastcall func3(__int64 a1)
{
return func2(a1, -1);
}

original_code:
char *get_keystate(keystate_holder ksh) {
 return get_keystate_ignore_key( ksh, -1 );
}

canonical_original_code:
char *get_keystate(unsigned short ksh[-1]) {
 return get_keystate_ignore_key( ksh, -1 );
}


decompiled_code:
__int64 __fastcall obey_command(int *a1, __int64 a2)
{
int v2; // eax
unsigned int v3; // edx

v2 = *a1;
if ( *a1 == 1 )
{
add_device(a1 + 1, 0xFFFFFFFFLL, (unsigned int)a1[66], a1 + 67);
v3 = 0;
}
else
{
switch ( v2 )
{
case 6:
add_device(a1 + 1, (unsigned int)a1[65], (unsigned int)a1[66], a1 + 67);
v3 = 0;
break;
case 2:
remove_device(a1 + 1);
v3 = 0;
break;
case 3:
cleanup();
v3 = 0;
break;
case 5:
triggers_enabled(1LL);
v3 = 0;
break;
case 4:
triggers_enabled(0LL);
v3 = 0;
break;
case 7:
clear_devices();
v3 = 0;
break;
default:
v3 = 1;
if ( v2 == 8 )
{
change_trigger_mode(a1 + 1, a2, 1LL);
v3 = 0;
}
break;
}
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func0(int *a1, __int64 a2)
{
int v2; // eax
unsigned int v3; // edx

v2 = *a1;
if ( *a1 == 1 )
{
add_device(a1 + 1, 0xFFFFFFFFLL, (unsigned int)a1[66], a1 + 67);
v3 = 0;
}
else
{
switch ( v2 )
{
case 6:
add_device(a1 + 1, (unsigned int)a1[65], (unsigned int)a1[66], a1 + 67);
v3 = 0;
break;
case 2:
remove_device(a1 + 1);
v3 = 0;
break;
case 3:
cleanup();
v3 = 0;
break;
case 5:
triggers_enabled(1LL);
v3 = 0;
break;
case 4:
triggers_enabled(0LL);
v3 = 0;
break;
case 7:
clear_devices();
v3 = 0;
break;
default:
v3 = 1;
if ( v2 == 8 )
{
change_trigger_mode(a1 + 1, a2, 1LL);
v3 = 0;
}
break;
}
}
return v3;
}

original_code:
int obey_command( struct command *cmd ) {
 if (cmd->type == CMD_ADD) {
  add_device( cmd->param, -1, cmd->exclusive, cmd->tag );
  return 0;
 }
 if (cmd->type == CMD_PASSFD) {
  add_device( cmd->param, cmd->fd, cmd->exclusive, cmd->tag );
  return 0;
 }
 if (cmd->type == CMD_REMOVE) {
  remove_device( cmd->param );
  return 0;
 }
 if (cmd->type == CMD_QUIT) {
  cleanup();
  return 0;
 }
 if (cmd->type == CMD_ENABLE) {
  triggers_enabled(1);
  return 0;
 }
 if (cmd->type == CMD_DISABLE) {
  triggers_enabled(0);
  return 0;
 }
 if (cmd->type == CMD_CLEARDEVS) {
  clear_devices();
  return 0;
 }
 if (cmd->type == CMD_CHANGEMODE) {
  change_trigger_mode( cmd->param );
  return 0;
 }
 return 1;
}

canonical_original_code:
int obey_command(struct command *cmd) {
 if (cmd->type == CMD_ADD) {
  add_device( cmd->param, -1, cmd->exclusive, cmd->tag );
  return 0;
 }
 if (cmd->type == CMD_PASSFD) {
  add_device( cmd->param, cmd->fd, cmd->exclusive, cmd->tag );
  return 0;
 }
 if (cmd->type == CMD_REMOVE) {
  remove_device( cmd->param );
  return 0;
 }
 if (cmd->type == CMD_QUIT) {
  cleanup();
  return 0;
 }
 if (cmd->type == CMD_ENABLE) {
  triggers_enabled(1);
  return 0;
 }
 if (cmd->type == CMD_DISABLE) {
  triggers_enabled(0);
  return 0;
 }
 if (cmd->type == CMD_CLEARDEVS) {
  clear_devices();
  return 0;
 }
 if (cmd->type == CMD_CHANGEMODE) {
  change_trigger_mode( cmd->param );
  return 0;
 }
 return 1;
}

variable_types: struct command { enum command_type { CMD_NOP=0, CMD_ADD=1, CMD_REMOVE=2, CMD_QUIT=3, CMD_DISABLE=4, CMD_ENABLE=5, CMD_PASSFD=6, CMD_CLEARDEVS=7, CMD_CHANGEMODE=8 } type; char param[256]; int fd; int exclusive; char tag[256]; } *

user_defined_types: struct command { enum command_type type; char param[256]; int fd; int exclusive; char tag[256]; }


decompiled_code:
size_t __fastcall ignore_key(int a1, size_t *a2)
{
size_t *v2; // rbx
size_t v3; // rax
size_t v4; // rsi
_QWORD *v5; // rax
size_t result; // rax

v2 = a2;
v3 = *a2;
if ( *a2 )
{
do
{
v4 = v3;
v3 = *(_QWORD *)(v3 + 8);
}
while ( v3 );
v2 = (size_t *)(v4 + 8);
}
v5 = malloc(0x10uLL);
*v2 = (size_t)v5;
if ( !v5 )
return fwrite("Unable to allocate memory for ignored key!\n", 1uLL, 0x2BuLL, stderr);
v5[1] = 0LL;
result = *v2;
*(_DWORD *)*v2 = a1;
return result;
}

canonical_decompiled_code:
size_t __fastcall func0(int a1, size_t *a2)
{
size_t *v2; // rbx
size_t v3; // rax
size_t v4; // rsi
_QWORD *v5; // rax
size_t result; // rax

v2 = a2;
v3 = *a2;
if ( *a2 )
{
do
{
v4 = v3;
v3 = *(_QWORD *)(v3 + 8);
}
while ( v3 );
v2 = (size_t *)(v4 + 8);
}
v5 = malloc(0x10uLL);
*v2 = (size_t)v5;
if ( !v5 )
return fwrite("Unable to allocate memory for ignored key!\n", 1uLL, 0x2BuLL, stderr);
v5[1] = 0LL;
result = *v2;
*(_DWORD *)*v2 = a1;
return result;
}

original_code:
void ignore_key( int code, ignore **list ) {
 ignore **p = list;
 while ( *p != ((void *)0) ) {
  p = &( (*p)->next );
 }
 *p = malloc( sizeof(ignore) );
 if (*p) {
  (*p)->next = ((void *)0);
  (*p)->code = code;
 } else {
  fprintf(stderr, "Unable to allocate memory for ignored key!\n");
 }
}

canonical_original_code:
void ignore_key(int code, struct ignore **list) {
 struct ignore **p = list;
 while ( *p != ((void *)0) ) {
  p = &( (*p)->next );
 }
 *p = malloc( sizeof(ignore) );
 if (*p) {
  (*p)->next = ((void *)0);
  (*p)->code = code;
 } else {
  fprintf(stderr, "Unable to allocate memory for ignored key!\n");
 }
}

variable_types: code int

variable_types: struct ignore { int code; struct ignore *next; } **


decompiled_code:
void __fastcall print_ignores(__int64 a1)
{
for ( ; a1; a1 = *(_QWORD *)(a1 + 8) )
;
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1)
{
for ( ; a1; a1 = *(_QWORD *)(a1 + 8) )
;
}

original_code:
void print_ignores( ignore *list ) {
 ignore *p = list;
 while ( p != ((void *)0) ) {
  p = p->next;
 }
}

canonical_original_code:
void print_ignores(struct ignore *list) {
 struct ignore *p = list;
 while ( p != ((void *)0) ) {
  p = p->next;
 }
}

variable_types: struct ignore { int code; struct ignore *next; } *


decompiled_code:
__int64 __fastcall is_ignored(int a1, __int64 a2)
{
if ( !a2 )
return 0LL;
while ( *(_DWORD *)a2 != a1 )
{
a2 = *(_QWORD *)(a2 + 8);
if ( !a2 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, __int64 a2)
{
if ( !a2 )
return 0LL;
while ( *(_DWORD *)a2 != a1 )
{
a2 = *(_QWORD *)(a2 + 8);
if ( !a2 )
return 0LL;
}
return 1LL;
}

original_code:
int is_ignored( int code, ignore *list ) {
 ignore *p = list;
 while ( p != ((void *)0) ) {
  if (p->code == code) {
   return 1;
  }
  p = p->next;
 }
 return 0;
}

canonical_original_code:
int is_ignored(int code, struct ignore *list) {
 struct ignore *p = list;
 while ( p != ((void *)0) ) {
  if (p->code == code) {
   return 1;
  }
  p = p->next;
 }
 return 0;
}

user_defined_types: struct ignore { int code; struct ignore *next; }


decompiled_code:
int close_uinput()
{
int result; // eax

if ( uinput_fd >= 0 )
{
result = close(uinput_fd);
uinput_fd = -1;
}
return result;
}

canonical_decompiled_code:
int func0()
{
int result; // eax

if ( uinput_fd >= 0 )
{
result = close(uinput_fd);
uinput_fd = -1;
}
return result;
}

original_code:
void close_uinput() {
 if (uinput_fd >= 0) {
  close(uinput_fd);
  uinput_fd = -1;
 }
}


repo: wesen/avr-bt-stack

original_code:
bt_peer_t *bt_dev_get_free_peer(bt_dev_t *dev) {
   unsigned int i;
   for (i=0; i<3; i++) {
      if (dev->peers[i].state == 0) {
         dev->peers[i].pkt_type = 0x0008;
         dev->peers[i].clock_offset = 0;
         memset(dev->peers[i].bd_addr, 0, 6);
         memset(dev->peers[i].cod, 0, 3);
         return dev->peers + i;
      }
   }
   return ((void *)0);
}

canonical_original_code:
struct bt_peer_s *bt_dev_get_free_peer(struct bt_dev_s *dev) {
   unsigned int i;
   for (i=0; i<3; i++) {
      if (dev->peers[i].state == 0) {
         dev->peers[i].pkt_type = 0x0008;
         dev->peers[i].clock_offset = 0;
         memset(dev->peers[i].bd_addr, 0, 6);
         memset(dev->peers[i].cod, 0, 3);
         return dev->peers + i;
      }
   }
   return ((void *)0);
}

variable_types: struct bt_dev_s { unsigned char state; unsigned char ncmds; unsigned char buf[256]; char name[32]; unsigned short pkt_type; struct bt_peer_s peers[3]; struct bt_acl_s { unsigned char state; unsigned short handle; unsigned short pkt_types; unsigned char max_slots; unsigned char encrypt_mode; struct bt_peer_s *peer; } acls[3]; char tty[128]; int ttyfd; 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; } save_termios; } *

variable_types:
i
unsigned int

return_type: struct bt_peer_s { unsigned char state; unsigned char bd_addr[6]; unsigned short clock_offset; unsigned char pscan_rep_mode; } *

user_defined_types: struct bt_dev_s { unsigned char state; unsigned char ncmds; unsigned char buf[256]; char name[32]; unsigned short pkt_type; struct bt_peer_s peers[3]; struct bt_acl_s acls[3]; char tty[128]; int ttyfd; struct termios save_termios; }


decompiled_code:
__int64 __fastcall bt_dev_get_peer_by_bd_addr(__int64 a1, const void *a2)
{
char *v2; // rbx
unsigned int i; // ebp

v2 = (char *)(a1 + 307);
for ( i = 0; i != 3; ++i )
{
if ( *(v2 - 1) && !memcmp(v2, a2, 6uLL) )
return a1 + 18LL * i + 306;
v2 += 18;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const void *a2)
{
char *v2; // rbx
unsigned int i; // ebp

v2 = (char *)(a1 + 307);
for ( i = 0; i != 3; ++i )
{
if ( *(v2 - 1) && !memcmp(v2, a2, 6uLL) )
return a1 + 18LL * i + 306;
v2 += 18;
}
return 0LL;
}

original_code:
bt_peer_t *bt_dev_get_peer_by_bd_addr(bt_dev_t *dev, unsigned char *bd_addr){
   unsigned int i;
   for (i=0; i<3; i++) {
      if ((dev->peers[i].state != 0) &&
          !(memcmp(dev->peers[i].bd_addr, bd_addr, 6)))
         return dev->peers + i;
   }
   return ((void *)0);
}

canonical_original_code:
struct bt_peer_s *bt_dev_get_peer_by_bd_addr(struct bt_dev_s *dev, unsigned char *bd_addr){
   unsigned int i;
   for (i=0; i<3; i++) {
      if ((dev->peers[i].state != 0) &&
          !(memcmp(dev->peers[i].bd_addr, bd_addr, 6)))
         return dev->peers + i;
   }
   return ((void *)0);
}

user_defined_types: struct bt_peer_s { unsigned char state; unsigned char bd_addr[6]; unsigned short clock_offset; unsigned char pscan_rep_mode; }

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

user_defined_types: struct bt_acl_s { unsigned char state; unsigned short handle; unsigned short pkt_types; unsigned char max_slots; unsigned char encrypt_mode; struct bt_peer_s *peer; }


decompiled_code:
__int64 __fastcall bt_dev_get_free_acl(_BYTE *a1)
{
__int64 result; // rax
unsigned int v2; // eax

if ( a1[360] )
{
if ( a1[376] )
{
result = 0LL;
if ( a1[392] )
return result;
v2 = 2;
}
else
{
v2 = 1;
}
}
else
{
v2 = 0;
}
return (__int64)&a1[16 * v2 + 360];
}

canonical_decompiled_code:
__int64 __fastcall func3(_BYTE *a1)
{
__int64 result; // rax
unsigned int v2; // eax

if ( a1[360] )
{
if ( a1[376] )
{
result = 0LL;
if ( a1[392] )
return result;
v2 = 2;
}
else
{
v2 = 1;
}
}
else
{
v2 = 0;
}
return (__int64)&a1[16 * v2 + 360];
}

original_code:
bt_acl_t *bt_dev_get_free_acl(bt_dev_t *dev) {
   unsigned int i;
   for (i=0; i<3; i++) {
      if (dev->acls[i].state == 0)
         return dev->acls + i;
   }
   return ((void *)0);
}

canonical_original_code:
struct bt_acl_s *bt_dev_get_free_acl(struct bt_dev_s *dev) {
   unsigned int i;
   for (i=0; i<3; i++) {
      if (dev->acls[i].state == 0)
         return dev->acls + i;
   }
   return ((void *)0);
}

variable_types: struct bt_dev_s { unsigned char state; unsigned char ncmds; unsigned char buf[256]; char name[32]; unsigned short pkt_type; struct bt_peer_s peers[3]; struct bt_acl_s acls[3]; char tty[128]; int ttyfd; 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; } save_termios; } *

return_type: struct bt_acl_s { unsigned char state; unsigned short handle; unsigned short pkt_types; unsigned char max_slots; unsigned char encrypt_mode; struct bt_peer_s { unsigned char state; unsigned char bd_addr[6]; unsigned short clock_offset; unsigned char pscan_rep_mode; } *peer; } *


decompiled_code:
__int64 __fastcall bt_dev_get_acl_by_handle(__int64 a1, __int16 a2)
{
__int64 v2; // rax
unsigned int i; // edx

v2 = a1 + 360;
for ( i = 0; i != 3; ++i )
{
if ( *(_BYTE *)v2 && *(_WORD *)(v2 + 2) == a2 )
return a1 + 16LL * i + 360;
v2 += 16LL;
}
return 0LL;
}

original_code:
bt_acl_t *bt_dev_get_acl_by_handle(bt_dev_t *dev,
                                   unsigned short handle) {
   unsigned int i;
   for (i=0; i<3; i++) {
      if ((dev->acls[i].state != 0) &&
            (dev->acls[i].handle == handle))
         return dev->acls + i;
   }
   return ((void *)0);
}

canonical_original_code:
struct bt_acl_s *bt_dev_get_acl_by_handle(struct bt_dev_s *dev, unsigned short handle) {
   unsigned int i;
   for (i=0; i<3; i++) {
      if ((dev->acls[i].state != 0) &&
            (dev->acls[i].handle == handle))
         return dev->acls + i;
   }
   return ((void *)0);
}

variable_types:
handle
unsigned short


decompiled_code:
__int64 __fastcall bt_dev_flush_hci(__int64 a1)
{
--*(_BYTE *)(a1 + 1);
return bt_serial_send(a1, a1 + 2, *(_QWORD *)(a1 + 264) - (a1 + 2));
}

original_code:
int bt_dev_flush_hci(bt_dev_t *dev) {
   dev->ncmds--;
   return bt_serial_send(dev, dev->buf, dev->ptr - dev->buf);
}

canonical_original_code:
int bt_dev_flush_hci(struct bt_dev_s *dev) {
   dev->ncmds--;
   return bt_serial_send(dev, dev->buf, dev->ptr - dev->buf);
}

variable_types: struct bt_dev_s { unsigned char state; unsigned char ncmds; unsigned char buf[256]; char name[32]; unsigned short pkt_type; struct bt_peer_s { unsigned char state; unsigned char bd_addr[6]; unsigned short clock_offset; unsigned char pscan_rep_mode; } peers[3]; struct bt_acl_s { unsigned char state; unsigned short handle; unsigned short pkt_types; unsigned char max_slots; unsigned char encrypt_mode; struct bt_peer_s *peer; } acls[3]; char tty[128]; int ttyfd; 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; } save_termios; } *


decompiled_code:
__int64 __fastcall bt_dev_read_hci(__int64 a1, __int64 a2)
{
int v2; // edx
__int64 result; // rax

*(_QWORD *)(a1 + 264) = a1 + 2;
v2 = bt_serial_read(a1, a1 + 2, 1LL);
result = 1LL;
if ( v2 == 1 )
result = bt_hci_unpack_hci(a1, a2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
int v2; // edx
__int64 result; // rax

*(_QWORD *)(a1 + 264) = a1 + 2;
v2 = bt_serial_read(a1, a1 + 2, 1LL);
result = 1LL;
if ( v2 == 1 )
result = bt_hci_unpack_hci(a1, a2);
return result;
}

original_code:
bt_dev_evt_e bt_dev_read_hci(bt_dev_t *dev, bt_callbacks_t *cb) {
   dev->ptr = dev->buf;
   if (bt_serial_read(dev, dev->ptr, 1) != 1)
      return dev_evt_timeout;
   return bt_hci_unpack_hci(dev, cb);
}

canonical_original_code:
enum bt_dev_evt_e bt_dev_read_hci(struct bt_dev_s *dev, struct bt_callbacks_s *cb) {
   dev->ptr = dev->buf;
   if (bt_serial_read(dev, dev->ptr, 1) != 1)
      return dev_evt_timeout;
   return bt_hci_unpack_hci(dev, cb);
}

variable_types: struct bt_callbacks_s { void (*cb_ready)(struct bt_dev_s *dev); int (*cb_peer_found)(struct bt_dev_s *dev, struct bt_peer_s *peer); int (*cb_conn_req)(struct bt_dev_s *dev, struct bt_peer_s *peer, unsigned char link_type); void (*cb_conn_succ)(struct bt_dev_s *dev, struct bt_acl_s *acl); void (*cb_conn_unsucc)(struct bt_dev_s *dev, struct bt_peer_s *peer); void (*cb_disconn_succ)(struct bt_dev_s *dev, struct bt_acl_s *acl, unsigned char reason); void (*cb_conn_data)(struct bt_dev_s *dev, struct bt_acl_s *acl); unsigned char *(*cb_pincode_req)(struct bt_dev_s *dev, struct bt_peer_s *peer); unsigned char *(*cb_link_key_req)(struct bt_dev_s *dev, struct bt_peer_s *peer); void (*cb_idle)(struct bt_dev_s *dev); } *

return_type: enum bt_dev_evt_e { dev_evt_none=0, dev_evt_timeout=1, dev_evt_garbage=2, dev_evt_acl=3, dev_evt_sco=4, dev_evt_inquiry_results=5, dev_evt_inquiry_complete_succ=6, dev_evt_inquiry_complete_unsucc=7, dev_evt_conn_request=8, dev_evt_conn_complete_succ=9, dev_evt_conn_complete_unsucc=10, dev_evt_disconn_complete_succ=11, dev_evt_disconn_complete_unsucc=12, dev_evt_auth_complete_succ=13, dev_evt_auth_complete_unsucc=14, dev_evt_pincode_req=15, dev_evt_link_key_not=16, dev_evt_link_key_req=17, dev_evt_link_key_reply_succ=18, dev_evt_link_key_reply_unsucc=19, dev_evt_link_key_reply_neg_succ=20, dev_evt_link_key_reply_neg_unsucc=21, dev_evt_pincode_reply_succ=22, dev_evt_pincode_reply_unsucc=23, dev_evt_pincode_reply_neg_succ=24, dev_evt_pincode_reply_neg_unsucc=25, dev_evt_read_features_succ=26, dev_evt_read_features_unsucc=27, dev_evt_num_comp_pkts=28, dev_evt_max_slots_chg=29, dev_evt_set_evt_flt_succ=30, dev_evt_set_evt_flt_unsucc=31, dev_evt_write_auth_enable_succ=32, dev_evt_write_auth_enable_unsucc=33, dev_evt_write_scan_enable_succ=34, dev_evt_write_scan_enable_unsucc=35, dev_evt_change_name_succ=36, dev_evt_change_name_unsucc=37, dev_evt_read_local_feat_succ=38, dev_evt_read_local_feat_unsucc=39, dev_evt_read_bd_addr_succ=40, dev_evt_read_bd_addr_unsucc=41 }


decompiled_code:
__int64 __fastcall bt_dev_pack_reset(__int64 a1)
{
return bt_hci_pack_cmd(a1, 3LL, 3LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return bt_hci_pack_cmd(a1, 3LL, 3LL, 0LL);
}

original_code:
void bt_dev_pack_reset(bt_dev_t *dev) {
   bt_hci_pack_cmd(dev, 0x03, 0x0003, 0);
}

canonical_original_code:
void bt_dev_pack_reset(struct bt_dev_s *dev) {
   bt_hci_pack_cmd(dev, 0x03, 0x0003, 0);
}


decompiled_code:
char *__fastcall bt_dev_pack_change_local_name(__int64 a1, const char *a2)
{
unsigned __int8 v2; // bp
_QWORD *v3; // rcx
char *result; // rax

v2 = strlen(a2);
bt_hci_pack_cmd(a1, 3LL, 19LL, 248LL);
v3 = *(_QWORD **)(a1 + 264);
*v3 = 0LL;
v3[30] = 0LL;
memset(
(void *)((unsigned __int64)(v3 + 1) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((unsigned int)v3 - (((_DWORD)v3 + 8) & 0xFFFFFFF8) + 248) >> 3));
result = strncpy(*(char **)(a1 + 264), a2, v2);
*(_QWORD *)(a1 + 264) += 248LL;
return result;
}

canonical_decompiled_code:
char *__fastcall func10(__int64 a1, const char *a2)
{
unsigned __int8 v2; // bp
_QWORD *v3; // rcx
char *result; // rax

v2 = strlen(a2);
bt_hci_pack_cmd(a1, 3LL, 19LL, 248LL);
v3 = *(_QWORD **)(a1 + 264);
*v3 = 0LL;
v3[30] = 0LL;
memset(
(void *)((unsigned __int64)(v3 + 1) & 0xFFFFFFFFFFFFFFF8LL),
0,
8LL * (((unsigned int)v3 - (((_DWORD)v3 + 8) & 0xFFFFFFF8) + 248) >> 3));
result = strncpy(*(char **)(a1 + 264), a2, v2);
*(_QWORD *)(a1 + 264) += 248LL;
return result;
}

original_code:
void bt_dev_pack_change_local_name(bt_dev_t *dev, const char *s) {
   unsigned char len = strlen(s);
   bt_hci_pack_cmd(dev, 0x03, 0x0013, 248);
   memset((char *)dev->ptr, 0, 248);
   strncpy((char *)dev->ptr, s, len);
   dev->ptr += 248;
}

canonical_original_code:
void bt_dev_pack_change_local_name(struct bt_dev_s *dev, char *s) {
   unsigned char len = strlen(s);
   bt_hci_pack_cmd(dev, 0x03, 0x0013, 248);
   memset((char *)dev->ptr, 0, 248);
   strncpy((char *)dev->ptr, s, len);
   dev->ptr += 248;
}

variable_types:
s
char *

variable_types:
len
unsigned char


decompiled_code:
__int64 __fastcall bt_dev_pack_inquiry(__int64 a1, char a2, char a3)
{
__int64 result; // rax
int v5; // [rsp+Bh] [rbp-1Dh]

v5 = 10390323;
bt_hci_pack_cmd(a1, 1LL, 1LL, 5LL);
result = *(_QWORD *)(a1 + 264);
HIBYTE(v5) = a2;
*(_DWORD *)result = v5;
*(_BYTE *)(result + 4) = a3;
*(_QWORD *)(a1 + 264) += 5LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, char a2, char a3)
{
__int64 result; // rax
int v5; // [rsp+Bh] [rbp-1Dh]

v5 = 10390323;
bt_hci_pack_cmd(a1, 1LL, 1LL, 5LL);
result = *(_QWORD *)(a1 + 264);
HIBYTE(v5) = a2;
*(_DWORD *)result = v5;
*(_BYTE *)(result + 4) = a3;
*(_QWORD *)(a1 + 264) += 5LL;
return result;
}

original_code:
void bt_dev_pack_inquiry(bt_dev_t *dev,
                         unsigned char len,
                         unsigned char num_peers) {
   unsigned char inq_data[5] = {
      0x33, 0x8B, 0x9E,
      0,
      0
   };
   inq_data[3] = len;
   inq_data[4] = num_peers;
   bt_hci_pack_cmd(dev, 0x01, 0x0001, 5);
   memcpy(dev->ptr, inq_data, 5); dev->ptr += 5;
}

canonical_original_code:
void bt_dev_pack_inquiry(struct bt_dev_s *dev, unsigned char len, unsigned char num_peers) {
   unsigned char inq_data[5] = {
      0x33, 0x8B, 0x9E,
      0,
      0
   };
   inq_data[3] = len;
   inq_data[4] = num_peers;
   bt_hci_pack_cmd(dev, 0x01, 0x0001, 5);
   memcpy(dev->ptr, inq_data, 5); dev->ptr += 5;
}


original_code:
void bt_dev_pack_link_key_reply(bt_dev_t *dev,
                                unsigned char *bd_addr,
                                unsigned char *link_key) {
   bt_hci_pack_cmd(dev, 0x01, 0x000b, 22);
   memcpy(dev->ptr, bd_addr, 6); dev->ptr += 6;
   memcpy(dev->ptr, link_key, 16); dev->ptr += 16;
}

canonical_original_code:
void bt_dev_pack_link_key_reply(struct bt_dev_s *dev, unsigned char *bd_addr, unsigned char *link_key) {
   bt_hci_pack_cmd(dev, 0x01, 0x000b, 22);
   memcpy(dev->ptr, bd_addr, 6); dev->ptr += 6;
   memcpy(dev->ptr, link_key, 16); dev->ptr += 16;
}


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

bt_hci_pack_cmd(a1, 1LL, 12LL, 6LL);
result = *(_QWORD *)(a1 + 264);
*(_DWORD *)result = *(_DWORD *)a2;
*(_WORD *)(result + 4) = *(_WORD *)(a2 + 4);
*(_QWORD *)(a1 + 264) += 6LL;
return result;
}

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

bt_hci_pack_cmd(a1, 1LL, 12LL, 6LL);
result = *(_QWORD *)(a1 + 264);
*(_DWORD *)result = *(_DWORD *)a2;
*(_WORD *)(result + 4) = *(_WORD *)(a2 + 4);
*(_QWORD *)(a1 + 264) += 6LL;
return result;
}

original_code:
void bt_dev_pack_link_key_reply_neg(bt_dev_t *dev,
                                    unsigned char *bd_addr) {
   bt_hci_pack_cmd(dev, 0x01, 0x000c, 6);
   memcpy(dev->ptr, bd_addr, 6); dev->ptr += 6;
}

canonical_original_code:
void bt_dev_pack_link_key_reply_neg(struct bt_dev_s *dev, unsigned char *bd_addr) {
   bt_hci_pack_cmd(dev, 0x01, 0x000c, 6);
   memcpy(dev->ptr, bd_addr, 6); dev->ptr += 6;
}


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

bt_hci_pack_cmd(a1, 1LL, 14LL, 6LL);
result = *(_QWORD *)(a1 + 264);
*(_DWORD *)result = *(_DWORD *)a2;
*(_WORD *)(result + 4) = *(_WORD *)(a2 + 4);
*(_QWORD *)(a1 + 264) += 6LL;
return result;
}

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

bt_hci_pack_cmd(a1, 1LL, 14LL, 6LL);
result = *(_QWORD *)(a1 + 264);
*(_DWORD *)result = *(_DWORD *)a2;
*(_WORD *)(result + 4) = *(_WORD *)(a2 + 4);
*(_QWORD *)(a1 + 264) += 6LL;
return result;
}

original_code:
void bt_dev_pack_pincode_reply_neg(bt_dev_t *dev,
                                    unsigned char *bd_addr) {
   bt_hci_pack_cmd(dev, 0x01, 0x000e, 6);
   memcpy(dev->ptr, bd_addr, 6); dev->ptr += 6;
}

canonical_original_code:
void bt_dev_pack_pincode_reply_neg(struct bt_dev_s *dev, unsigned char *bd_addr) {
   bt_hci_pack_cmd(dev, 0x01, 0x000e, 6);
   memcpy(dev->ptr, bd_addr, 6); dev->ptr += 6;
}


decompiled_code:
__int64 __fastcall bt_dev_pack_read_local_features(__int64 a1)
{
return bt_hci_pack_cmd(a1, 4LL, 3LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1)
{
return bt_hci_pack_cmd(a1, 4LL, 3LL, 0LL);
}

original_code:
void bt_dev_pack_read_local_features(bt_dev_t *dev) {
   bt_hci_pack_cmd(dev, 0x04, 0x0003, 0);
}

canonical_original_code:
void bt_dev_pack_read_local_features(struct bt_dev_s *dev) {
   bt_hci_pack_cmd(dev, 0x04, 0x0003, 0);
}


decompiled_code:
__int64 __fastcall bt_dev_pack_read_buffer_size(__int64 a1)
{
return bt_hci_pack_cmd(a1, 4LL, 5LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1)
{
return bt_hci_pack_cmd(a1, 4LL, 5LL, 0LL);
}

original_code:
void bt_dev_pack_read_buffer_size(bt_dev_t *dev) {
   bt_hci_pack_cmd(dev, 0x04, 0x0005, 0);
}

canonical_original_code:
void bt_dev_pack_read_buffer_size(struct bt_dev_s *dev) {
   bt_hci_pack_cmd(dev, 0x04, 0x0005, 0);
}


decompiled_code:
__int64 __fastcall bt_dev_pack_read_bd_addr(__int64 a1)
{
return bt_hci_pack_cmd(a1, 4LL, 9LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1)
{
return bt_hci_pack_cmd(a1, 4LL, 9LL, 0LL);
}

original_code:
void bt_dev_pack_read_bd_addr(bt_dev_t *dev) {
   bt_hci_pack_cmd(dev, 0x04, 0x0009, 0);
}

canonical_original_code:
void bt_dev_pack_read_bd_addr(struct bt_dev_s *dev) {
   bt_hci_pack_cmd(dev, 0x04, 0x0009, 0);
}


original_code:
void bt_dev_pack_l2cap(bt_dev_t *dev, unsigned short handle,
                       unsigned char *data, int len) {
   bt_hci_pack_acl(dev, handle, 0x02, 0x00, len+4);
   { *(dev->ptr++) = ((len) & 0xFF); *(dev->ptr++) = (((len) >> 8) & 0xFF); };
   { *(dev->ptr++) = ((0x40) & 0xFF); *(dev->ptr++) = (((0x40) >> 8) & 0xFF); };
   memcpy(dev->ptr, data, len);
   dev->ptr += len;
}

canonical_original_code:
void bt_dev_pack_l2cap(struct bt_dev_s *dev, unsigned short handle, unsigned char *data, int len) {
   bt_hci_pack_acl(dev, handle, 0x02, 0x00, len+4);
   { *(dev->ptr++) = ((len) & 0xFF); *(dev->ptr++) = (((len) >> 8) & 0xFF); };
   { *(dev->ptr++) = ((0x40) & 0xFF); *(dev->ptr++) = (((0x40) >> 8) & 0xFF); };
   memcpy(dev->ptr, data, len);
   dev->ptr += len;
}

variable_types:
data
unsigned char *

variable_types: len int


decompiled_code:
__int64 __fastcall bt_serial_init(__int64 a1)
{
int v1; // eax
__m128i v2; // xmm0
int v3; // edx
__int64 result; // rax
struct termios v5; // [rsp+0h] [rbp-58h] BYREF

v1 = open((const char *)(a1 + 408), 258);
*(_DWORD *)(a1 + 536) = v1;
if ( v1 < 0 )
{
error_str("could not open TTY");
result = 0LL;
}
else if ( isatty(v1) && tcgetattr(*(_DWORD *)(a1 + 536), (struct termios *)(a1 + 540)) >= 0 )
{
v2 = _mm_loadu_si128((const __m128i *)(a1 + 540));
*(__m128i *)&v5.c_iflag = v2;
*(__m128i *)&v5.c_line = _mm_loadu_si128((const __m128i *)(a1 + 556));
*(__m128i *)&v5.c_cc[15] = _mm_loadu_si128((const __m128i *)(a1 + 572));
*(_QWORD *)&v5.c_cc[31] = *(_QWORD *)(a1 + 588);
v5.c_ospeed = *(_DWORD *)(a1 + 596);
v5.c_lflag = v2.m128i_i32[3] & 0xFFFF7FB4;
v5.c_iflag = v2.m128i_i32[0] & 0xFFFFFA14;
v5.c_cflag = v2.m128i_i32[2] & 0xFFFFFACF | 0x830;
v5.c_oflag = v2.m128i_i32[1] & 0xFFFFFFFE;
*(_WORD *)&v5.c_cc[5] = 256;
if ( cfsetispeed(&v5, 0x1002u) < 0 || cfsetospeed(&v5, 0x1002u) < 0 )
{
error_str("Could not set 115200 bps baudrate");
tcsetattr(*(_DWORD *)(a1 + 536), 2, (const struct termios *)(a1 + 540));
close(*(_DWORD *)(a1 + 536));
result = 0LL;
}
else
{
v3 = tcsetattr(*(_DWORD *)(a1 + 536), 2, &v5);
result = 1LL;
if ( v3 < 0 )
{
error_str("Could not switch TTY to noncanonical mode");
close(*(_DWORD *)(a1 + 536));
result = 0LL;
}
}
}
else
{
error_str("TTY is not a tty");
close(*(_DWORD *)(a1 + 536));
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
int v1; // eax
__m128i v2; // xmm0
int v3; // edx
__int64 result; // rax
struct termios v5; // [rsp+0h] [rbp-58h] BYREF

v1 = open((const char *)(a1 + 408), 258);
*(_DWORD *)(a1 + 536) = v1;
if ( v1 < 0 )
{
error_str("could not open TTY");
result = 0LL;
}
else if ( isatty(v1) && tcgetattr(*(_DWORD *)(a1 + 536), (struct termios *)(a1 + 540)) >= 0 )
{
v2 = _mm_loadu_si128((const __m128i *)(a1 + 540));
*(__m128i *)&v5.c_iflag = v2;
*(__m128i *)&v5.c_line = _mm_loadu_si128((const __m128i *)(a1 + 556));
*(__m128i *)&v5.c_cc[15] = _mm_loadu_si128((const __m128i *)(a1 + 572));
*(_QWORD *)&v5.c_cc[31] = *(_QWORD *)(a1 + 588);
v5.c_ospeed = *(_DWORD *)(a1 + 596);
v5.c_lflag = v2.m128i_i32[3] & 0xFFFF7FB4;
v5.c_iflag = v2.m128i_i32[0] & 0xFFFFFA14;
v5.c_cflag = v2.m128i_i32[2] & 0xFFFFFACF | 0x830;
v5.c_oflag = v2.m128i_i32[1] & 0xFFFFFFFE;
*(_WORD *)&v5.c_cc[5] = 256;
if ( cfsetispeed(&v5, 0x1002u) < 0 || cfsetospeed(&v5, 0x1002u) < 0 )
{
error_str("Could not set 115200 bps baudrate");
tcsetattr(*(_DWORD *)(a1 + 536), 2, (const struct termios *)(a1 + 540));
close(*(_DWORD *)(a1 + 536));
result = 0LL;
}
else
{
v3 = tcsetattr(*(_DWORD *)(a1 + 536), 2, &v5);
result = 1LL;
if ( v3 < 0 )
{
error_str("Could not switch TTY to noncanonical mode");
close(*(_DWORD *)(a1 + 536));
result = 0LL;
}
}
}
else
{
error_str("TTY is not a tty");
close(*(_DWORD *)(a1 + 536));
result = 0LL;
}
return result;
}

original_code:
int bt_serial_init(bt_dev_t *dev) {
   struct termios term;
   if (((dev->ttyfd = open(dev->tty, 02 | 0400)) < 0)) {
      error_str(("could not open TTY"));
      return 0;
   }
   if (!isatty(dev->ttyfd) ||
       (tcgetattr(dev->ttyfd, &dev->save_termios) < 0)) {
      error_str(("TTY is not a tty"));
      close(dev->ttyfd);
      return 0;
   }
   term = dev->save_termios;
   term.c_lflag &= ~(0000010|0000100|0000002|0000001|0100000);
   term.c_iflag &= ~(0000001|0000002|0000010|0000040|0000100|0000200|0000400|0002000);
   term.c_cflag &= ~(0000060 | 0000400);
  term.c_cflag &= ~(0002000|0000400|0000060);
  term.c_cflag |= (0000060|0004000);
   term.c_oflag &= ~(0000001);
   term.c_cc[6] = 1;
   term.c_cc[5] = 0;
   if ((cfsetispeed(&term, 0010002) < 0) ||
       (cfsetospeed(&term, 0010002) <0 )) {
      error_str(("Could not set 115200 bps baudrate"));
      tcsetattr(dev->ttyfd, 2, &dev->save_termios);
      close(dev->ttyfd);
      return 0;
   }
   if (tcsetattr(dev->ttyfd, 2, &term) < 0) {
      error_str(("Could not switch TTY to noncanonical mode"));
      close(dev->ttyfd);
      return 0;
   }
   return 1;
}

canonical_original_code:
int bt_serial_init(struct bt_dev_s *dev) {
   struct termios term;
   if (((dev->ttyfd = open(dev->tty, 02 | 0400)) < 0)) {
      error_str(("could not open TTY"));
      return 0;
   }
   if (!isatty(dev->ttyfd) ||
       (tcgetattr(dev->ttyfd, &dev->save_termios) < 0)) {
      error_str(("TTY is not a tty"));
      close(dev->ttyfd);
      return 0;
   }
   term = dev->save_termios;
   term.c_lflag &= ~(0000010|0000100|0000002|0000001|0100000);
   term.c_iflag &= ~(0000001|0000002|0000010|0000040|0000100|0000200|0000400|0002000);
   term.c_cflag &= ~(0000060 | 0000400);
  term.c_cflag &= ~(0002000|0000400|0000060);
  term.c_cflag |= (0000060|0004000);
   term.c_oflag &= ~(0000001);
   term.c_cc[6] = 1;
   term.c_cc[5] = 0;
   if ((cfsetispeed(&term, 0010002) < 0) ||
       (cfsetospeed(&term, 0010002) <0 )) {
      error_str(("Could not set 115200 bps baudrate"));
      tcsetattr(dev->ttyfd, 2, &dev->save_termios);
      close(dev->ttyfd);
      return 0;
   }
   if (tcsetattr(dev->ttyfd, 2, &term) < 0) {
      error_str(("Could not switch TTY to noncanonical mode"));
      close(dev->ttyfd);
      return 0;
   }
   return 1;
}

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