main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er14
char *v4; // r12
const char *v5; // rax
int v6; // er15
int v7; // ebx
int v8; // edi
int v9; // ebp
const char *v10; // rax
__int64 i; // rbx
__uid_t v12; // eax
int v13; // ebx
unsigned int v14; // eax
size_t v15; // rax
unsigned int v17; // [rsp+4h] [rbp-64h]
const char *v18; // [rsp+8h] [rbp-60h]
char s[10]; // [rsp+16h] [rbp-52h] BYREF
struct rlimit rlimits; // [rsp+20h] [rbp-48h] BYREF

v3 = 0;
v4 = 0LL;
v17 = 0;
my_pid = getpid();
v5 = *argv;
am_daemon = 1;
v18 = v5;
progname = (__int64)v5;
while ( 1 )
{
v6 = getopt(argc, (char *const *)argv, "ndvf:t");
if ( v6 == -1 )
break;
switch ( v6 )
{
case 'd':
debug = 1;
break;
case 'f':
if ( v4 )
die(0LL, "You may not specify more than one configuration file.");
v4 = optarg;
break;
case 'n':
am_daemon = 0;
break;
case 't':
v17 = 1;
break;
case 'v':
v3 = 1;
break;
default:
die(0LL, "usage: %s [ -ndvt ] [ -f configuration_file ]", v18);
}
}
if ( v3 )
{
v3 = 0;
fprintf(stderr, "%s\n", "Mathopd/1.6b15");
return v3;
}
if ( getrlimit(RLIMIT_NOFILE, &rlimits) == -1 )
LABEL_79:
die("getrlimit", 0LL);
rlimits.rlim_cur = rlimits.rlim_max;
nfiles = rlimits.rlim_max;
setrlimit(RLIMIT_NOFILE, &rlimits);
if ( am_daemon && nfiles > 3 )
{
v7 = 3;
do
{
v8 = v7++;
close(v8);
}
while ( nfiles > v7 );
}
v9 = open("/dev/null", 2);
if ( v9 == -1 )
die("open", "Cannot open %s", "/dev/null");
while ( v9 <= 2 )
{
v9 = dup(v9);
if ( v9 == -1 )
die("dup", 0LL);
}
v10 = (const char *)config(v4);
if ( v10 )
die(0LL, "%s", v10);
for ( i = servers; i; i = *(_QWORD *)(i + 40) )
startup_server(i);
if ( rootdir )
{
if ( chroot(rootdir) == -1 )
die("chroot", 0LL);
if ( chdir("/") == -1 )
goto LABEL_65;
}
v12 = geteuid();
if ( setuid(v12) == -1 )
goto LABEL_63;
if ( geteuid() )
goto LABEL_34;
if ( !server_uid )
die(0LL, "No user specified.");
if ( setgroups(0LL, 0LL) == -1 && setgroups(1uLL, &server_gid) == -1 )
die("setgroups", 0LL);
if ( setgid(server_gid) == -1 )
die("setgid", 0LL);
if ( !stayroot )
{
if ( setuid(server_uid) != -1 )
goto LABEL_34;
LABEL_63:
die("setuid", 0LL);
}
if ( seteuid(server_uid) == -1 )
die("seteuid", 0LL);
amroot = 1;
LABEL_34:
if ( getrlimit(RLIMIT_CORE, &rlimits) == -1 )
goto LABEL_79;
if ( !coredir )
{
rlimits.rlim_cur = 0LL;
if ( chdir("/") != -1 )
goto LABEL_37;
LABEL_65:
die("chdir", 0LL);
}
rlimits.rlim_cur = rlimits.rlim_max;
if ( chdir(coredir) == -1 )
goto LABEL_65;
LABEL_37:
setrlimit(RLIMIT_CORE, &rlimits);
umask(fcm);
if ( pid_filename )
{
v6 = open(pid_filename, 65, 438LL);
if ( v6 == -1 )
die("open", "Cannot open PID file");
}
current_time = time(0LL);
if ( (unsigned int)init_logs(v17) == -1 )
die("open", "Cannot open log files");
dup2(v9, 0);
dup2(v9, 1);
dup2(v9, 2);
close(v9);
if ( !am_daemon )
goto LABEL_53;
if ( fork() || (setsid(), fork()) )
exit(0);
if ( tuning[20] > 1 )
{
v13 = 1;
while ( fork() )
{
if ( tuning[20] <= ++v13 )
goto LABEL_53;
}
if ( v6 != -1 )
close(v6);
mysignal_isra_0(17, sighandler);
mysignal_isra_0(1, sighandler);
mysignal_isra_0(15, sighandler);
mysignal_isra_0(2, sighandler);
mysignal_isra_0(3, sighandler);
mysignal_isra_0(10, sighandler);
mysignal_isra_0(12, sighandler);
mysignal_isra_0(13, (void (__fastcall *)(int))((char *)sighandler + 1));
mysignal_isra_0(28, sighandler);
my_pid = getpid();
}
else
{
LABEL_53:
mysignal_isra_0(17, sighandler);
mysignal_isra_0(1, sighandler);
mysignal_isra_0(15, sighandler);
mysignal_isra_0(2, sighandler);
mysignal_isra_0(3, sighandler);
mysignal_isra_0(10, sighandler);
mysignal_isra_0(12, sighandler);
mysignal_isra_0(13, (void (__fastcall *)(int))((char *)sighandler + 1));
mysignal_isra_0(28, sighandler);
my_pid = getpid();
if ( v6 != -1 )
{
if ( ftruncate(v6, 0LL) == -1 )
return 1;
if ( tuning[20] <= 1 )
{
sprintf(s, "%d\n", (unsigned int)my_pid);
}
else
{
v14 = getpgrp();
sprintf(s, "-%d\n", v14);
}
v15 = strlen(s);
if ( write(v6, s, v15) == -1 )
return 1;
close(v6);
}
}
if ( (unsigned int)init_buffers() == -1 )
return 1;
httpd_main();
return v3;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er14
char *v4; // r12
const char *v5; // rax
int v6; // er15
int v7; // ebx
int v8; // edi
int v9; // ebp
const char *v10; // rax
__int64 i; // rbx
__uid_t v12; // eax
int v13; // ebx
unsigned int v14; // eax
size_t v15; // rax
unsigned int v17; // [rsp+4h] [rbp-64h]
const char *v18; // [rsp+8h] [rbp-60h]
char s[10]; // [rsp+16h] [rbp-52h] BYREF
struct rlimit rlimits; // [rsp+20h] [rbp-48h] BYREF

v3 = 0;
v4 = 0LL;
v17 = 0;
my_pid = getpid();
v5 = *argv;
am_daemon = 1;
v18 = v5;
progname = (__int64)v5;
while ( 1 )
{
v6 = getopt(argc, (char *const *)argv, "ndvf:t");
if ( v6 == -1 )
break;
switch ( v6 )
{
case 'd':
debug = 1;
break;
case 'f':
if ( v4 )
func1(0LL, "You may not specify more than one configuration file.");
v4 = optarg;
break;
case 'n':
am_daemon = 0;
break;
case 't':
v17 = 1;
break;
case 'v':
v3 = 1;
break;
default:
func1(0LL, "usage: %s [ -ndvt ] [ -f configuration_file ]", v18);
}
}
if ( v3 )
{
v3 = 0;
fprintf(stderr, "%s\n", "Mathopd/1.6b15");
return v3;
}
if ( getrlimit(RLIMIT_NOFILE, &rlimits) == -1 )
LABEL_79:
func1("getrlimit", 0LL);
rlimits.rlim_cur = rlimits.rlim_max;
nfiles = rlimits.rlim_max;
setrlimit(RLIMIT_NOFILE, &rlimits);
if ( am_daemon && nfiles > 3 )
{
v7 = 3;
do
{
v8 = v7++;
close(v8);
}
while ( nfiles > v7 );
}
v9 = open("/dev/null", 2);
if ( v9 == -1 )
func1("open", "Cannot open %s", "/dev/null");
while ( v9 <= 2 )
{
v9 = dup(v9);
if ( v9 == -1 )
func1("dup", 0LL);
}
v10 = (const char *)config(v4);
if ( v10 )
func1(0LL, "%s", v10);
for ( i = servers; i; i = *(_QWORD *)(i + 40) )
func2(i);
if ( rootdir )
{
if ( chroot(rootdir) == -1 )
func1("chroot", 0LL);
if ( chdir("/") == -1 )
goto LABEL_65;
}
v12 = geteuid();
if ( setuid(v12) == -1 )
goto LABEL_63;
if ( geteuid() )
goto LABEL_34;
if ( !server_uid )
func1(0LL, "No user specified.");
if ( setgroups(0LL, 0LL) == -1 && setgroups(1uLL, &server_gid) == -1 )
func1("setgroups", 0LL);
if ( setgid(server_gid) == -1 )
func1("setgid", 0LL);
if ( !stayroot )
{
if ( setuid(server_uid) != -1 )
goto LABEL_34;
LABEL_63:
func1("setuid", 0LL);
}
if ( seteuid(server_uid) == -1 )
func1("seteuid", 0LL);
amroot = 1;
LABEL_34:
if ( getrlimit(RLIMIT_CORE, &rlimits) == -1 )
goto LABEL_79;
if ( !coredir )
{
rlimits.rlim_cur = 0LL;
if ( chdir("/") != -1 )
goto LABEL_37;
LABEL_65:
func1("chdir", 0LL);
}
rlimits.rlim_cur = rlimits.rlim_max;
if ( chdir(coredir) == -1 )
goto LABEL_65;
LABEL_37:
setrlimit(RLIMIT_CORE, &rlimits);
umask(fcm);
if ( pid_filename )
{
v6 = open(pid_filename, 65, 438LL);
if ( v6 == -1 )
func1("open", "Cannot open PID file");
}
current_time = time(0LL);
if ( (unsigned int)init_logs(v17) == -1 )
func1("open", "Cannot open log files");
dup2(v9, 0);
dup2(v9, 1);
dup2(v9, 2);
close(v9);
if ( !am_daemon )
goto LABEL_53;
if ( fork() || (setsid(), fork()) )
exit(0);
if ( tuning[20] > 1 )
{
v13 = 1;
while ( fork() )
{
if ( tuning[20] <= ++v13 )
goto LABEL_53;
}
if ( v6 != -1 )
close(v6);
func3(17, sighandler);
func3(1, sighandler);
func3(15, sighandler);
func3(2, sighandler);
func3(3, sighandler);
func3(10, sighandler);
func3(12, sighandler);
func3(13, (void (__fastcall *)(int))((char *)sighandler + 1));
func3(28, sighandler);
my_pid = getpid();
}
else
{
LABEL_53:
func3(17, sighandler);
func3(1, sighandler);
func3(15, sighandler);
func3(2, sighandler);
func3(3, sighandler);
func3(10, sighandler);
func3(12, sighandler);
func3(13, (void (__fastcall *)(int))((char *)sighandler + 1));
func3(28, sighandler);
my_pid = getpid();
if ( v6 != -1 )
{
if ( ftruncate(v6, 0LL) == -1 )
return 1;
if ( tuning[20] <= 1 )
{
sprintf(s, "%d\n", (unsigned int)my_pid);
}
else
{
v14 = getpgrp();
sprintf(s, "-%d\n", v14);
}
v15 = strlen(s);
if ( write(v6, s, v15) == -1 )
return 1;
close(v6);
}
}
if ( (unsigned int)init_buffers() == -1 )
return 1;
httpd_main();
return v3;
}

original_code:
int main(int argc, char *argv[])
{
 int c, i, version, pid_fd, null_fd, tee;
 struct server *s;
 char buf[10];
 struct rlimit rl;
 const char *message;
 const char *config_filename;
 my_pid = getpid();
 progname = argv[0];
 am_daemon = 1;
 version = 0;
 config_filename = 0;
 tee = 0;
 while ((c = getopt(argc, argv, "ndvf:t")) != -1) {
  switch(c) {
  case 'n':
   am_daemon = 0;
   break;
  case 'd':
   debug = 1;
   break;
  case 'v':
   version = 1;
   break;
  case 'f':
   if (config_filename == 0)
    config_filename = optarg;
   else
    die(0, "You may not specify more than one configuration file.");
   break;
  case 't':
   tee = 1;
   break;
  default:
   die(0, "usage: %s [ -ndvt ] [ -f configuration_file ]", progname);
   break;
  }
 }
 if (version) {
  fprintf(stderr, "%s\n", server_version);
  return 0;
 }
 if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
  die("getrlimit", 0);
 nfiles = rl.rlim_cur = rl.rlim_max;
 setrlimit(RLIMIT_NOFILE, &rl);
 if (am_daemon)
  for (i = 3; i < nfiles; i++)
   close(i);
 null_fd = open(devnull, 02);
 if (null_fd == -1)
  die("open", "Cannot open %s", devnull);
 while (null_fd < 3) {
  null_fd = dup(null_fd);
  if (null_fd == -1)
   die("dup", 0);
 }
 message = config(config_filename);
 if (message)
  die(0, "%s", message);
 s = servers;
 while (s) {
  startup_server(s);
  s = s->next;
 }
 if (rootdir) {
  if (chroot(rootdir) == -1)
   die("chroot", 0);
  if (chdir("/") == -1)
   die("chdir", 0);
 }
 if (setuid(geteuid()) == -1) {
  die("setuid", 0);
 }
 if (geteuid() == 0) {
  if (server_uid == 0)
   die(0, "No user specified.");
  if (setgroups(0, 0) == -1)
   if (setgroups(1, &server_gid) == -1)
    die("setgroups", 0);
  if (setgid(server_gid) == -1)
   die("setgid", 0);
  if (stayroot) {
   if (seteuid(server_uid) == -1)
    die("seteuid", 0);
   amroot = 1;
  } else {
   if (setuid(server_uid) == -1)
    die("setuid", 0);
  }
 }
 if (getrlimit(RLIMIT_CORE, &rl) == -1)
  die("getrlimit", 0);
 if (coredir) {
  rl.rlim_cur = rl.rlim_max;
  if (chdir(coredir) == -1)
   die("chdir", 0);
 } else {
  rl.rlim_cur = 0;
  if (chdir("/") == -1)
   die("chdir", 0);
 }
 setrlimit(RLIMIT_CORE, &rl);
 umask(fcm);
 if (pid_filename) {
  pid_fd = open(pid_filename, 01 | 0100, 0666);
  if (pid_fd == -1)
   die("open", "Cannot open PID file");
 } else
  pid_fd = -1;
 current_time = time(0);
 if (init_logs(tee) == -1)
  die("open", "Cannot open log files");
 dup2(null_fd, 0);
 dup2(null_fd, 1);
 dup2(null_fd, 2);
 close(null_fd);
 if (am_daemon) {
  if (fork())
   _exit(0);
  setsid();
  if (fork())
   _exit(0);
  for (i = 1; i < tuning.num_processes; i++) {
   if (fork() == 0) {
    if (pid_fd != -1) {
     close(pid_fd);
     pid_fd = -1;
    }
    break;
   }
  }
 }
 mysignal(17, sighandler);
 mysignal(1, sighandler);
 mysignal(15, sighandler);
 mysignal(2, sighandler);
 mysignal(3, sighandler);
 mysignal(10, sighandler);
 mysignal(12, sighandler);
 mysignal(13, ((__sighandler_t) 1));
 mysignal(28, sighandler);
 my_pid = getpid();
 if (pid_fd != -1) {
  if (ftruncate(pid_fd, 0) == -1)
   return 1;
  if (tuning.num_processes > 1)
   sprintf(buf, "-%d\n", (int) getpgrp());
  else
   sprintf(buf, "%d\n", my_pid);
  if (write(pid_fd, buf, strlen(buf)) == -1)
   return 1;
  close(pid_fd);
 }
 if (init_buffers() == -1)
  return 1;
 httpd_main();
 return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
 int c; int i; int version; int pid_fd; int null_fd; int tee;
 struct server *s;
 char buf[10];
 struct rlimit rl;
 char *message;
 char *config_filename;
 my_pid = getpid();
 progname = argv[0];
 am_daemon = 1;
 version = 0;
 config_filename = 0;
 tee = 0;
 while ((c = getopt(argc, argv, "ndvf:t")) != -1) {
  switch(c) {
  case 'n':
   am_daemon = 0;
   break;
  case 'd':
   debug = 1;
   break;
  case 'v':
   version = 1;
   break;
  case 'f':
   if (config_filename == 0)
    config_filename = optarg;
   else
    die(0, "You may not specify more than one configuration file.");
   break;
  case 't':
   tee = 1;
   break;
  default:
   die(0, "usage: %s [ -ndvt ] [ -f configuration_file ]", progname);
   break;
  }
 }
 if (version) {
  fprintf(stderr, "%s\n", server_version);
  return 0;
 }
 if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
  die("getrlimit", 0);
 nfiles = rl.rlim_cur = rl.rlim_max;
 setrlimit(RLIMIT_NOFILE, &rl);
 if (am_daemon)
  for (i = 3; i < nfiles; i++)
   close(i);
 null_fd = open(devnull, 02);
 if (null_fd == -1)
  die("open", "Cannot open %s", devnull);
 while (null_fd < 3) {
  null_fd = dup(null_fd);
  if (null_fd == -1)
   die("dup", 0);
 }
 message = config(config_filename);
 if (message)
  die(0, "%s", message);
 s = servers;
 while (s) {
  startup_server(s);
  s = s->next;
 }
 if (rootdir) {
  if (chroot(rootdir) == -1)
   die("chroot", 0);
  if (chdir("/") == -1)
   die("chdir", 0);
 }
 if (setuid(geteuid()) == -1) {
  die("setuid", 0);
 }
 if (geteuid() == 0) {
  if (server_uid == 0)
   die(0, "No user specified.");
  if (setgroups(0, 0) == -1)
   if (setgroups(1, &server_gid) == -1)
    die("setgroups", 0);
  if (setgid(server_gid) == -1)
   die("setgid", 0);
  if (stayroot) {
   if (seteuid(server_uid) == -1)
    die("seteuid", 0);
   amroot = 1;
  } else {
   if (setuid(server_uid) == -1)
    die("setuid", 0);
  }
 }
 if (getrlimit(RLIMIT_CORE, &rl) == -1)
  die("getrlimit", 0);
 if (coredir) {
  rl.rlim_cur = rl.rlim_max;
  if (chdir(coredir) == -1)
   die("chdir", 0);
 } else {
  rl.rlim_cur = 0;
  if (chdir("/") == -1)
   die("chdir", 0);
 }
 setrlimit(RLIMIT_CORE, &rl);
 umask(fcm);
 if (pid_filename) {
  pid_fd = open(pid_filename, 01 | 0100, 0666);
  if (pid_fd == -1)
   die("open", "Cannot open PID file");
 } else
  pid_fd = -1;
 current_time = time(0);
 if (init_logs(tee) == -1)
  die("open", "Cannot open log files");
 dup2(null_fd, 0);
 dup2(null_fd, 1);
 dup2(null_fd, 2);
 close(null_fd);
 if (am_daemon) {
  if (fork())
   _exit(0);
  setsid();
  if (fork())
   _exit(0);
  for (i = 1; i < tuning.num_processes; i++) {
   if (fork() == 0) {
    if (pid_fd != -1) {
     close(pid_fd);
     pid_fd = -1;
    }
    break;
   }
  }
 }
 mysignal(17, sighandler);
 mysignal(1, sighandler);
 mysignal(15, sighandler);
 mysignal(2, sighandler);
 mysignal(3, sighandler);
 mysignal(10, sighandler);
 mysignal(12, sighandler);
 mysignal(13, ((void (*)(int)) 1));
 mysignal(28, sighandler);
 my_pid = getpid();
 if (pid_fd != -1) {
  if (ftruncate(pid_fd, 0) == -1)
   return 1;
  if (tuning.num_processes > 1)
   sprintf(buf, "-%d\n", (int) getpgrp());
  else
   sprintf(buf, "%d\n", my_pid);
  if (write(pid_fd, buf, strlen(buf)) == -1)
   return 1;
  close(pid_fd);
 }
 if (init_buffers() == -1)
  return 1;
 httpd_main();
 return 0;
}

variable_types: argc int

variable_types: c int

variable_types: version int

variable_types: tee int

variable_types:
buf
char [10]

variable_types:
message
char *

user_defined_types: struct rlimit { unsigned long rlim_cur; unsigned long rlim_max; }

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

user_defined_types: struct server_sockopts { int ss_level; int ss_optname; void *ss_optval; unsigned int ss_optlen; struct server_sockopts *next; }

user_defined_types: struct simple_list { char *name; struct simple_list *next; }

user_defined_types: struct mime { int class; char *ext; char *name; struct mime *next; }

user_defined_types: struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; }


pointinrect

repo: michielboland/mathopd

decompiled_code:
_BOOL8 __fastcall pointinrect(__int64 a1, __int64 a2, _QWORD *a3)
{
_BOOL8 result; // rax

result = 0LL;
if ( *a3 >= a1 != a3[2] >= a1 )
result = a3[1] >= a2 != a2 <= a3[3];
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(__int64 a1, __int64 a2, _QWORD *a3)
{
_BOOL8 result; // rax

result = 0LL;
if ( *a3 >= a1 != a3[2] >= a1 )
result = a3[1] >= a2 != a2 <= a3[3];
return result;
}

canonical_original_code:
static int pointinrect(struct point p, struct point c[])
{
 return (((c[0].x >= p.x) != (c[1].x >= p.x)) && ((c[0].y >= p.y) != (c[1].y >= p.y)));
}

variable_types:
p
struct point { long x; long y; }

variable_types:
c
struct point []

return_type: int


sqr

decompiled_code:
__int64 __fastcall sqr(__int64 a1)
{
return a1 * a1;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return a1 * a1;
}

original_code:
static long sqr(long x)
{
 return x * x;
}

variable_types: x long

return_type: long


pointincircle

original_code:
static int pointincircle(point p, point c[])
{
 return (sqr(c[0].x - p.x) + sqr(c[0].y - p.y) <= sqr(c[0].x - c[1].x) + sqr(c[0].y - c[1].y));
}

canonical_original_code:
static int pointincircle(struct point p, struct point c[])
{
 return (sqr(c[0].x - p.x) + sqr(c[0].y - p.y) <= sqr(c[0].x - c[1].x) + sqr(c[0].y - c[1].y));
}


pointinpoly

original_code:
static int pointinpoly(point t, point a[], int n)
{
 int xflag, yflag, ysign, idx;
 point *p, *q, *stop;
 if (n < 3)
  return 0;
 idx = 0;
 q = a;
 stop = a + n;
 p = stop - 1;
 while (q < stop) {
  yflag = p->y >= t.y;
  if (yflag != (q->y >= t.y)) {
   ysign = yflag ? -1 : 1;
   xflag = p->x >= t.x;
   if (xflag == (q->x >= t.x)) {
    if (xflag)
     idx += ysign;
   } else if (ysign * ((p->x - t.x) * (q->y - p->y) - (p->y - t.y) * (q->x - p->x)) >= 0)
    idx += ysign;
  }
  ++q;
  if (++p == stop)
   p = a;
 }
 return idx;
}

canonical_original_code:
static int pointinpoly(struct point t, struct point a[], int n)
{
 int xflag; int yflag; int ysign; int idx;
 struct point *p; struct point *q; struct point *stop;
 if (n < 3)
  return 0;
 idx = 0;
 q = a;
 stop = a + n;
 p = stop - 1;
 while (q < stop) {
  yflag = p->y >= t.y;
  if (yflag != (q->y >= t.y)) {
   ysign = yflag ? -1 : 1;
   xflag = p->x >= t.x;
   if (xflag == (q->x >= t.x)) {
    if (xflag)
     idx += ysign;
   } else if (ysign * ((p->x - t.x) * (q->y - p->y) - (p->y - t.y) * (q->x - p->x)) >= 0)
    idx += ysign;
  }
  ++q;
  if (++p == stop)
   p = a;
 }
 return idx;
}

variable_types:
t
struct point { long x; long y; }

variable_types:
a
struct point []

variable_types: n int

variable_types: xflag int

variable_types: yflag int

variable_types: ysign int

variable_types: idx int

variable_types:
p
struct point { long x; long y; } *

variable_types:
q
struct point { long x; long y; } *

variable_types:
stop
struct point { long x; long y; } *


variable_types:
encoded
char *

variable_types:
decoded
char *

variable_types: c char


pwok

decompiled_code:
_BOOL8 __fastcall pwok(char *salt, char *key, int a3)
{
_BOOL8 result; // rax

if ( !a3 || (key = crypt(key, salt), result = 0LL, key) )
result = strcmp(salt, key) == 0;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(char *salt, char *key, int a3)
{
_BOOL8 result; // rax

if ( !a3 || (key = crypt(key, salt), result = 0LL, key) )
result = strcmp(salt, key) == 0;
return result;
}

original_code:
static int pwok(const char *good, const char *guess, int do_crypt)
{
 char *cs;
 if (do_crypt == 0)
  return strcmp(good, guess) == 0;
 cs = crypt(guess, good);
 if (cs)
  return strcmp(good, cs) == 0;
 return 0;
}

canonical_original_code:
static int pwok(char *good, char *guess, int do_crypt)
{
 char *cs;
 if (do_crypt == 0)
  return strcmp(good, guess) == 0;
 cs = crypt(guess, good);
 if (cs)
  return strcmp(good, cs) == 0;
 return 0;
}

variable_types:
good
char *

variable_types:
guess
char *

variable_types:
cs
char *


original_code:
static void destroy_parameters(struct cgi_parameters *cp)
{
 int i;
 if (cp->cgi_envp) {
  for (i = 0; i < cp->cgi_envc; i++)
   if (cp->cgi_envp[i])
    free(cp->cgi_envp[i]);
  free(cp->cgi_envp);
 }
 if (cp->cgi_argv) {
  for (i = 0; i < cp->cgi_argc; i++)
   if (cp->cgi_argv[i])
    free(cp->cgi_argv[i]);
  free(cp->cgi_argv);
 }
}

variable_types: struct cgi_parameters { char **cgi_envp; char **cgi_argv; int cgi_envc; int cgi_argc; } *

variable_types: i int

return_type: void


add

decompiled_code:
__int64 __fastcall add(void *src, char *s, size_t a3, __int64 a4)
{
__int64 result; // rax
char *v7; // rax
__int64 v8; // rdx
char **v9; // rax
size_t v10; // r14
size_t v11; // rax
size_t v12; // r8
size_t v13; // r12
char *v14; // rax
char *v15; // r15
char *v16; // rax
int v17; // [rsp+Ch] [rbp-4Ch]
char **v18; // [rsp+10h] [rbp-48h]
size_t n; // [rsp+18h] [rbp-40h]

if ( !src || (result = 0LL, s) )
{
v7 = (char *)realloc(*(void **)a4, 8LL * (*(_DWORD *)(a4 + 16) + 1));
if ( !v7 )
return 0xFFFFFFFFLL;
v8 = *(int *)(a4 + 16);
*(_QWORD *)a4 = v7;
v9 = (char **)&v7[8 * v8];
v17 = v8;
v18 = v9;
if ( !src )
{
if ( !s )
{
*v9 = 0LL;
goto LABEL_9;
}
v16 = strdup(s);
*v18 = v16;
if ( v16 )
{
LABEL_9:
result = 0LL;
*(_DWORD *)(a4 + 16) = v17 + 1;
return result;
}
return 0xFFFFFFFFLL;
}
v10 = strlen((const char *)src);
v11 = strlen(s);
v12 = v11;
if ( a3 )
{
if ( v11 <= a3 )
{
v13 = v10;
v12 = 0LL;
goto LABEL_7;
}
v12 = v11 - a3;
}
v13 = v10 + v12;
LABEL_7:
n = v12;
v14 = (char *)malloc(v13 + 2);
v15 = v14;
if ( v14 )
{
memcpy(v14, src, v10);
v15[v10] = 61;
memcpy(&v15[v10 + 1], s, n);
v15[v13 + 1] = 0;
*v18 = v15;
goto LABEL_9;
}
*v18 = 0LL;
return 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *src, char *s, size_t a3, __int64 a4)
{
__int64 result; // rax
char *v7; // rax
__int64 v8; // rdx
char **v9; // rax
size_t v10; // r14
size_t v11; // rax
size_t v12; // r8
size_t v13; // r12
char *v14; // rax
char *v15; // r15
char *v16; // rax
int v17; // [rsp+Ch] [rbp-4Ch]
char **v18; // [rsp+10h] [rbp-48h]
size_t n; // [rsp+18h] [rbp-40h]

if ( !src || (result = 0LL, s) )
{
v7 = (char *)realloc(*(void **)a4, 8LL * (*(_DWORD *)(a4 + 16) + 1));
if ( !v7 )
return 0xFFFFFFFFLL;
v8 = *(int *)(a4 + 16);
*(_QWORD *)a4 = v7;
v9 = (char **)&v7[8 * v8];
v17 = v8;
v18 = v9;
if ( !src )
{
if ( !s )
{
*v9 = 0LL;
goto LABEL_9;
}
v16 = strdup(s);
*v18 = v16;
if ( v16 )
{
LABEL_9:
result = 0LL;
*(_DWORD *)(a4 + 16) = v17 + 1;
return result;
}
return 0xFFFFFFFFLL;
}
v10 = strlen((const char *)src);
v11 = strlen(s);
v12 = v11;
if ( a3 )
{
if ( v11 <= a3 )
{
v13 = v10;
v12 = 0LL;
goto LABEL_7;
}
v12 = v11 - a3;
}
v13 = v10 + v12;
LABEL_7:
n = v12;
v14 = (char *)malloc(v13 + 2);
v15 = v14;
if ( v14 )
{
memcpy(v14, src, v10);
v15[v10] = 61;
memcpy(&v15[v10 + 1], s, n);
v15[v13 + 1] = 0;
*v18 = v15;
goto LABEL_9;
}
*v18 = 0LL;
return 0xFFFFFFFFLL;
}
return result;
}

original_code:
static int add(const char *name, const char *value, size_t choplen, struct cgi_parameters *cp)
{
 char *tmp;
 size_t namelen, valuelen;
 char **e;
 if (name && value == 0)
  return 0;
 e = realloc(cp->cgi_envp, (cp->cgi_envc + 1) * sizeof *cp->cgi_envp);
 if (e == 0)
  return -1;
 cp->cgi_envp = e;
 if (name == 0) {
  if (value == 0)
   cp->cgi_envp[cp->cgi_envc] = 0;
  else if ((cp->cgi_envp[cp->cgi_envc] = strdup(value)) == 0)
   return -1;
 } else {
  namelen = strlen(name);
  valuelen = strlen(value);
  if (choplen) {
   if (choplen < valuelen)
    valuelen -= choplen;
   else
    valuelen = 0;
  }
  tmp = malloc(namelen + valuelen + 2);
  if (tmp == 0) {
   cp->cgi_envp[cp->cgi_envc] = 0;
   return -1;
  }
  memcpy(tmp, name, namelen);
  tmp[namelen] = '=';
  memcpy(tmp + namelen + 1, value, valuelen);
  tmp[namelen + valuelen + 1] = 0;
  cp->cgi_envp[cp->cgi_envc] = tmp;
 }
 ++cp->cgi_envc;
 return 0;
}

canonical_original_code:
static int add(char *name, char *value, unsigned long choplen, struct cgi_parameters *cp)
{
 char *tmp;
 unsigned long namelen; unsigned long valuelen;
 char **e;
 if (name && value == 0)
  return 0;
 e = realloc(cp->cgi_envp, (cp->cgi_envc + 1) * sizeof *cp->cgi_envp);
 if (e == 0)
  return -1;
 cp->cgi_envp = e;
 if (name == 0) {
  if (value == 0)
   cp->cgi_envp[cp->cgi_envc] = 0;
  else if ((cp->cgi_envp[cp->cgi_envc] = strdup(value)) == 0)
   return -1;
 } else {
  namelen = strlen(name);
  valuelen = strlen(value);
  if (choplen) {
   if (choplen < valuelen)
    valuelen -= choplen;
   else
    valuelen = 0;
  }
  tmp = malloc(namelen + valuelen + 2);
  if (tmp == 0) {
   cp->cgi_envp[cp->cgi_envc] = 0;
   return -1;
  }
  memcpy(tmp, name, namelen);
  tmp[namelen] = '=';
  memcpy(tmp + namelen + 1, value, valuelen);
  tmp[namelen + valuelen + 1] = 0;
  cp->cgi_envp[cp->cgi_envc] = tmp;
 }
 ++cp->cgi_envc;
 return 0;
}

variable_types:
name
char *

variable_types:
value
char *

variable_types:
choplen
unsigned long

variable_types:
tmp
char *

variable_types:
namelen
unsigned long

variable_types:
valuelen
unsigned long

variable_types:
e
char **

user_defined_types: struct cgi_parameters { char **cgi_envp; char **cgi_argv; int cgi_envc; int cgi_argc; }


decompiled_code:
__int64 __fastcall add_argv(void *src, __int64 a2, int a3, __int64 a4)
{
_QWORD *v6; // rax
_QWORD *v7; // rbp
size_t v8; // r13
_BYTE *v9; // rax
_BYTE *v10; // r15
__int64 v11; // rdx
int v12; // eax
__int64 result; // rax
__int64 v14; // rdx

v6 = realloc(*(void **)(a4 + 8), 8LL * (*(_DWORD *)(a4 + 20) + 1));
if ( !v6 )
return 0xFFFFFFFFLL;
*(_QWORD *)(a4 + 8) = v6;
v7 = v6;
if ( !src )
{
v14 = *(int *)(a4 + 20);
v6[v14] = 0LL;
v12 = v14;
goto LABEL_10;
}
if ( a2 )
v8 = a2 - (_QWORD)src;
else
v8 = strlen((const char *)src);
v9 = malloc(v8 + 1);
v10 = v9;
if ( v9 )
{
if ( !a3 )
{
memcpy(v9, src, v8);
v10[v8] = 0;
goto LABEL_9;
}
if ( !(unsigned int)unescape_url_n(src, v9, v8) )
{
v7 = *(_QWORD **)(a4 + 8);
LABEL_9:
v11 = *(int *)(a4 + 20);
v7[v11] = v10;
v12 = v11;
LABEL_10:
*(_DWORD *)(a4 + 20) = v12 + 1;
return 0LL;
}
free(v10);
*(_QWORD *)(*(_QWORD *)(a4 + 8) + 8LL * *(int *)(a4 + 20)) = 0LL;
result = 0xFFFFFFFFLL;
}
else
{
v7[*(int *)(a4 + 20)] = 0LL;
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(void *src, __int64 a2, int a3, __int64 a4)
{
_QWORD *v6; // rax
_QWORD *v7; // rbp
size_t v8; // r13
_BYTE *v9; // rax
_BYTE *v10; // r15
__int64 v11; // rdx
int v12; // eax
__int64 result; // rax
__int64 v14; // rdx

v6 = realloc(*(void **)(a4 + 8), 8LL * (*(_DWORD *)(a4 + 20) + 1));
if ( !v6 )
return 0xFFFFFFFFLL;
*(_QWORD *)(a4 + 8) = v6;
v7 = v6;
if ( !src )
{
v14 = *(int *)(a4 + 20);
v6[v14] = 0LL;
v12 = v14;
goto LABEL_10;
}
if ( a2 )
v8 = a2 - (_QWORD)src;
else
v8 = strlen((const char *)src);
v9 = malloc(v8 + 1);
v10 = v9;
if ( v9 )
{
if ( !a3 )
{
memcpy(v9, src, v8);
v10[v8] = 0;
goto LABEL_9;
}
if ( !(unsigned int)unescape_url_n(src, v9, v8) )
{
v7 = *(_QWORD **)(a4 + 8);
LABEL_9:
v11 = *(int *)(a4 + 20);
v7[v11] = v10;
v12 = v11;
LABEL_10:
*(_DWORD *)(a4 + 20) = v12 + 1;
return 0LL;
}
free(v10);
*(_QWORD *)(*(_QWORD *)(a4 + 8) + 8LL * *(int *)(a4 + 20)) = 0LL;
result = 0xFFFFFFFFLL;
}
else
{
v7[*(int *)(a4 + 20)] = 0LL;
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
static int add_argv(const char *a, const char *b, int decode, struct cgi_parameters *cp)
{
 char *tmp;
 size_t s;
 char **e;
 e = realloc(cp->cgi_argv, (cp->cgi_argc + 1) * sizeof *cp->cgi_argv);
 if (e == 0)
  return -1;
 cp->cgi_argv = e;
 if (a == 0)
  cp->cgi_argv[cp->cgi_argc] = 0;
 else {
  s = b ? (size_t) (b - a) : strlen(a);
  tmp = malloc(s + 1);
  if (tmp == 0) {
   cp->cgi_argv[cp->cgi_argc] = 0;
   return -1;
  }
  if (decode) {
   if (unescape_url_n(a, tmp, s)) {
    free(tmp);
    cp->cgi_argv[cp->cgi_argc] = 0;
    return -1;
   }
  } else {
   memcpy(tmp, a, s);
   tmp[s] = 0;
  }
  cp->cgi_argv[cp->cgi_argc] = tmp;
 }
 ++cp->cgi_argc;
 return 0;
}

canonical_original_code:
static int add_argv(char *a, char *b, int decode, struct cgi_parameters *cp)
{
 char *tmp;
 unsigned long s;
 char **e;
 e = realloc(cp->cgi_argv, (cp->cgi_argc + 1) * sizeof *cp->cgi_argv);
 if (e == 0)
  return -1;
 cp->cgi_argv = e;
 if (a == 0)
  cp->cgi_argv[cp->cgi_argc] = 0;
 else {
  s = b ? (unsigned long) (b - a) : strlen(a);
  tmp = malloc(s + 1);
  if (tmp == 0) {
   cp->cgi_argv[cp->cgi_argc] = 0;
   return -1;
  }
  if (decode) {
   if (unescape_url_n(a, tmp, s)) {
    free(tmp);
    cp->cgi_argv[cp->cgi_argc] = 0;
    return -1;
   }
  } else {
   memcpy(tmp, a, s);
   tmp[s] = 0;
  }
  cp->cgi_argv[cp->cgi_argc] = tmp;
 }
 ++cp->cgi_argc;
 return 0;
}

variable_types:
a
char *

variable_types:
b
char *

variable_types: decode int

variable_types:
s
unsigned long


decompiled_code:
__int64 __fastcall make_cgi_argv(__int64 a1, __int64 a2)
{
char *i; // rbp
char *v3; // rbx
char *v4; // rbp
char *v6; // rbx

if ( *(_DWORD *)(a1 + 2484) == 3 )
{
for ( i = *(char **)(a1 + 2472); ; i = v3 + 1 )
{
v3 = strchr(i, 32);
if ( (unsigned int)add_argv(i, (__int64)v3, 0, a2) == -1 )
break;
if ( !v3 )
goto LABEL_6;
}
}
else
{
LABEL_6:
if ( (unsigned int)add_argv((void *)(a1 + 872), 0LL, 0, a2) != -1 )
{
v4 = *(char **)(a1 + 2536);
if ( !v4 || strchr(*(const char **)(a1 + 2536), 61) )
return (unsigned int)-((unsigned int)add_argv(0LL, 0LL, 0, a2) == -1);
while ( 1 )
{
v6 = strchr(v4, 43);
if ( (unsigned int)add_argv(v4, (__int64)v6, 1, a2) == -1 )
break;
if ( !v6 )
return (unsigned int)-((unsigned int)add_argv(0LL, 0LL, 0, a2) == -1);
v4 = v6 + 1;
}
}
}
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
char *i; // rbp
char *v3; // rbx
char *v4; // rbp
char *v6; // rbx

if ( *(_DWORD *)(a1 + 2484) == 3 )
{
for ( i = *(char **)(a1 + 2472); ; i = v3 + 1 )
{
v3 = strchr(i, 32);
if ( (unsigned int)func2(i, (__int64)v3, 0, a2) == -1 )
break;
if ( !v3 )
goto LABEL_6;
}
}
else
{
LABEL_6:
if ( (unsigned int)func2((void *)(a1 + 872), 0LL, 0, a2) != -1 )
{
v4 = *(char **)(a1 + 2536);
if ( !v4 || strchr(*(const char **)(a1 + 2536), 61) )
return (unsigned int)-((unsigned int)func2(0LL, 0LL, 0, a2) == -1);
while ( 1 )
{
v6 = strchr(v4, 43);
if ( (unsigned int)func2(v4, (__int64)v6, 1, a2) == -1 )
break;
if ( !v6 )
return (unsigned int)-((unsigned int)func2(0LL, 0LL, 0, a2) == -1);
v4 = v6 + 1;
}
}
}
return 0xFFFFFFFFLL;
}

original_code:
static int make_cgi_argv(struct request *r, struct cgi_parameters *cp)
{
 const char *a, *w;
 if (r->class == CLASS_EXTERNAL) {
  a = r->content_type;
  do {
   w = strchr(a, ' ');
   if (add_argv(a, w, 0, cp) == -1)
    return -1;
   if (w)
    a = w + 1;
  } while (w);
 }
 if (add_argv(r->path_translated, 0, 0, cp) == -1)
  return -1;
 a = r->args;
 if (a && strchr(a, '=') == 0)
  do {
   w = strchr(a, '+');
   if (add_argv(a, w, 1, cp) == -1)
    return -1;
   if (w)
    a = w + 1;
  } while (w);
 if (add_argv(0, 0, 0, cp) == -1)
  return -1;
 return 0;
}

canonical_original_code:
static int make_cgi_argv(struct request *r, struct cgi_parameters *cp)
{
 char *a; char *w;
 if (r->class == CLASS_EXTERNAL) {
  a = r->content_type;
  do {
   w = strchr(a, ' ');
   if (add_argv(a, w, 0, cp) == -1)
    return -1;
   if (w)
    a = w + 1;
  } while (w);
 }
 if (add_argv(r->path_translated, 0, 0, cp) == -1)
  return -1;
 a = r->args;
 if (a && strchr(a, '=') == 0)
  do {
   w = strchr(a, '+');
   if (add_argv(a, w, 1, cp) == -1)
    return -1;
   if (w)
    a = w + 1;
  } while (w);
 if (add_argv(0, 0, 0, cp) == -1)
  return -1;
 return 0;
}

variable_types: struct request { struct connection { struct connection *next; struct connection *prev; enum connection_state { HC_UNATTACHED=0, HC_FREE=1, HC_FORKED=2, HC_READING=3, HC_WRITING=4, HC_WAITING=5 } connection_state; struct request *r; struct server { int fd; unsigned long server_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *server_addr; struct virtual { char *host; struct virtual *next; struct vserver { struct control { char *alias; int path_args_ok; int exact_match; struct simple_list { char *name; struct simple_list *next; } *index_names; struct access { int type; struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; } addr; unsigned int prefixlen; struct access *next; } *accesses; struct mime { int class; char *ext; char *name; struct mime *next; } *mimes; struct control *next; struct simple_list *locations; struct access *clients; char *admin; char *realm; char *userfile; char *error_401_file; char *error_403_file; char *error_404_file; int do_crypt; char *child_filename; struct simple_list *exports; int script_identity; unsigned int script_uid; unsigned int script_gid; int allow_dotfiles; int user_directory; struct simple_list *putenvs; struct simple_list *extra_headers; int path_info_ok; char *auto_index_command; unsigned long expire_interval; int sanitize_path; } *controls; struct vserver *next; } *vserver; int anyhost; } *children; struct control *controls; struct server *next; int pollno; struct vserver *vservers; unsigned long backlog; char *addr; char *port; int family; int socktype; int protocol; struct server_sockopts { int ss_level; int ss_optname; void *ss_optval; unsigned int ss_optlen; struct server_sockopts *next; } *options; } *s; int fd; int rfd; struct sockaddr_storage peer; struct sockaddr_storage sock; long t; struct pool { char *floor; char *ceiling; char *start; char *middle; char *end; char state; unsigned long size; } header_input; struct pool output; struct pool client_input; struct pool script_input; int keepalive; int pollno; int rpollno; unsigned long long nread; unsigned long long nwritten; long long left; int logged; struct timeval { long tv_sec; long tv_usec; } itv; struct pipe_params { int state; unsigned long imax; int chunkit; int nocontent; int haslen; unsigned long pmax; } pipe_params; long file_offset; int havefile; } *cn; struct virtual *vs; char *user_agent; char *referer; char *authorization; char *host; char *in_content_type; char *in_content_length; char *ims_s; char path[-1]; char path_translated[-1]; char path_args[-1]; char *content_type; int num_content; int class; long long content_length; long last_modified; long ims; char *location; char *method_s; char *url; char *args; char *version; int protocol_major; int protocol_minor; int method; int status; struct control *c; 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]; } finfo; int isindex; char *error_file; char user[16]; char newloc[-1]; unsigned long location_length; unsigned long nheaders; struct request_header { char *rh_name; char *rh_value; } *headers; char *range_s; char *if_range_s; long if_range; int range; unsigned long long range_floor; unsigned long long range_ceiling; unsigned long long range_suffix; unsigned long long range_total; char *ius_s; long ius; char rhost[400]; char *in_transfer_encoding; unsigned long in_mblen; char curdir[-1]; int send_continue; int forked; } *

variable_types:
w
char *

user_defined_types: struct request { struct connection *cn; struct virtual *vs; char *user_agent; char *referer; char *authorization; char *host; char *in_content_type; char *in_content_length; char *ims_s; char path[-1]; char path_translated[-1]; char path_args[-1]; char *content_type; int num_content; int class; long long content_length; long last_modified; long ims; char *location; char *method_s; char *url; char *args; char *version; int protocol_major; int protocol_minor; int method; int status; struct control *c; struct stat finfo; int isindex; char *error_file; char user[16]; char newloc[-1]; unsigned long location_length; unsigned long nheaders; struct request_header *headers; char *range_s; char *if_range_s; long if_range; int range; unsigned long long range_floor; unsigned long long range_ceiling; unsigned long long range_suffix; unsigned long long range_total; char *ius_s; long ius; char rhost[400]; char *in_transfer_encoding; unsigned long in_mblen; char curdir[-1]; int send_continue; int forked; }

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

user_defined_types: struct connection { struct connection *next; struct connection *prev; enum connection_state connection_state; struct request *r; struct server *s; int fd; int rfd; struct sockaddr_storage peer; struct sockaddr_storage sock; long t; struct pool header_input; struct pool output; struct pool client_input; struct pool script_input; int keepalive; int pollno; int rpollno; unsigned long long nread; unsigned long long nwritten; long long left; int logged; struct timeval itv; struct pipe_params pipe_params; long file_offset; int havefile; }

user_defined_types: struct server { int fd; unsigned long server_addrlen; struct sockaddr *server_addr; struct virtual *children; struct control *controls; struct server *next; int pollno; struct vserver *vservers; unsigned long backlog; char *addr; char *port; int family; int socktype; int protocol; struct server_sockopts *options; }

user_defined_types: struct virtual { char *host; struct virtual *next; struct vserver *vserver; int anyhost; }

user_defined_types: struct vserver { struct control *controls; struct vserver *next; }

user_defined_types: struct control { char *alias; int path_args_ok; int exact_match; struct simple_list *index_names; struct access *accesses; struct mime *mimes; struct control *next; struct simple_list *locations; struct access *clients; char *admin; char *realm; char *userfile; char *error_401_file; char *error_403_file; char *error_404_file; int do_crypt; char *child_filename; struct simple_list *exports; int script_identity; unsigned int script_uid; unsigned int script_gid; int allow_dotfiles; int user_directory; struct simple_list *putenvs; struct simple_list *extra_headers; int path_info_ok; char *auto_index_command; unsigned long expire_interval; int sanitize_path; }

user_defined_types: struct access { int type; struct sockaddr_storage addr; unsigned int prefixlen; struct access *next; }


decompiled_code:
__int64 __fastcall process_cgi(_QWORD *a1)
{
_DWORD *v1; // rdx
unsigned int v2; // er12
int v3; // eax
unsigned int v4; // ebp
__int64 v5; // r13
int v6; // eax
unsigned int v7; // er12
int v8; // ebp
__int64 result; // rax
int fds[2]; // [rsp+8h] [rbp-50h] BYREF
__int64 v11; // [rsp+10h] [rbp-48h] BYREF
_QWORD *v12; // [rsp+18h] [rbp-40h]
__int64 v13; // [rsp+20h] [rbp-38h]

if ( !*((_BYTE *)a1 + 4072) )
{
LABEL_21:
*((_DWORD *)a1 + 641) = 500;
return 0;
}
v1 = (_DWORD *)a1[321];
v2 = amroot;
v3 = v1[34];
if ( v3 == 1 )
{
v4 = v1[35];
v5 = (unsigned int)v1[36];
if ( amroot )
{
LABEL_5:
if ( server_uid != v4 )
{
if ( v4 )
goto LABEL_7;
goto LABEL_16;
}
goto LABEL_27;
}
goto LABEL_18;
}
if ( v3 == 2 )
{
v4 = *((_DWORD *)a1 + 651);
v5 = *((unsigned int *)a1 + 652);
if ( amroot )
goto LABEL_5;
LABEL_18:
if ( v4 )
{
log_d("root privileges are required to change identity");
*((_DWORD *)a1 + 641) = 500;
return v2;
}
goto LABEL_7;
}
if ( amroot )
{
if ( server_uid )
{
LABEL_16:
v2 = 0;
log_d("ScriptUser or RunScriptsAsOwner must be set");
*((_DWORD *)a1 + 641) = 500;
return v2;
}
LABEL_27:
v2 = 0;
log_d("cannot run scripts without changing identity");
*((_DWORD *)a1 + 641) = 500;
return v2;
}
v5 = 0LL;
v4 = 0;
LABEL_7:
v11 = 0LL;
v12 = 0LL;
v13 = 0LL;
if ( (unsigned int)init_cgi_env_constprop_0((__int64)a1, (__int64)&v11) != -1 )
{
if ( socketpair(1, 1, 0, fds) == -1 )
{
v2 = 0;
lerror("socketpair");
destroy_parameters((__int64)&v11);
*((_DWORD *)a1 + 641) = 500;
return v2;
}
fcntl(fds[0], 2, 1LL);
fcntl(fds[1], 2, 1LL);
if ( !*(_QWORD *)(a1[321] + 120LL) )
{
v8 = spawn(*v12, v12, v11, (unsigned int)fds[1], 0xFFFFFFFFLL, v4, v5, a1 + 509);
goto LABEL_12;
}
v6 = open_log();
v7 = v6;
if ( v6 != -1 )
{
fcntl(v6, 2, 1LL);
v8 = spawn(*v12, v12, v11, (unsigned int)fds[1], v7, v4, v5, a1 + 509);
close(v7);
LABEL_12:
close(fds[1]);
if ( v8 == -1 )
{
close(fds[0]);
destroy_parameters((__int64)&v11);
*(_DWORD *)(*a1 + 536LL) = 0;
result = 0LL;
*((_DWORD *)a1 + 641) = 503;
return result;
}
fcntl(fds[0], 4, 2048LL);
init_child(*a1, (unsigned int)fds[0]);
destroy_parameters((__int64)&v11);
if ( debug )
log_d("process_cgi: %d", (unsigned int)fds[0]);
*((_DWORD *)a1 + 1219) = 1;
return (unsigned int)-1;
}
close(fds[0]);
close(fds[1]);
destroy_parameters((__int64)&v11);
goto LABEL_21;
}
log_d("process_cgi: out of memory");
destroy_parameters((__int64)&v11);
result = 0LL;
*((_DWORD *)a1 + 641) = 500;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(_QWORD *a1)
{
_DWORD *v1; // rdx
unsigned int v2; // er12
int v3; // eax
unsigned int v4; // ebp
__int64 v5; // r13
int v6; // eax
unsigned int v7; // er12
int v8; // ebp
__int64 result; // rax
int fds[2]; // [rsp+8h] [rbp-50h] BYREF
__int64 v11; // [rsp+10h] [rbp-48h] BYREF
_QWORD *v12; // [rsp+18h] [rbp-40h]
__int64 v13; // [rsp+20h] [rbp-38h]

if ( !*((_BYTE *)a1 + 4072) )
{
LABEL_21:
*((_DWORD *)a1 + 641) = 500;
return 0;
}
v1 = (_DWORD *)a1[321];
v2 = amroot;
v3 = v1[34];
if ( v3 == 1 )
{
v4 = v1[35];
v5 = (unsigned int)v1[36];
if ( amroot )
{
LABEL_5:
if ( server_uid != v4 )
{
if ( v4 )
goto LABEL_7;
goto LABEL_16;
}
goto LABEL_27;
}
goto LABEL_18;
}
if ( v3 == 2 )
{
v4 = *((_DWORD *)a1 + 651);
v5 = *((unsigned int *)a1 + 652);
if ( amroot )
goto LABEL_5;
LABEL_18:
if ( v4 )
{
log_d("root privileges are required to change identity");
*((_DWORD *)a1 + 641) = 500;
return v2;
}
goto LABEL_7;
}
if ( amroot )
{
if ( server_uid )
{
LABEL_16:
v2 = 0;
log_d("ScriptUser or RunScriptsAsOwner must be set");
*((_DWORD *)a1 + 641) = 500;
return v2;
}
LABEL_27:
v2 = 0;
log_d("cannot run scripts without changing identity");
*((_DWORD *)a1 + 641) = 500;
return v2;
}
v5 = 0LL;
v4 = 0;
LABEL_7:
v11 = 0LL;
v12 = 0LL;
v13 = 0LL;
if ( (unsigned int)func6((__int64)a1, (__int64)&v11) != -1 )
{
if ( socketpair(1, 1, 0, fds) == -1 )
{
v2 = 0;
lerror("socketpair");
func0((__int64)&v11);
*((_DWORD *)a1 + 641) = 500;
return v2;
}
fcntl(fds[0], 2, 1LL);
fcntl(fds[1], 2, 1LL);
if ( !*(_QWORD *)(a1[321] + 120LL) )
{
v8 = spawn(*v12, v12, v11, (unsigned int)fds[1], 0xFFFFFFFFLL, v4, v5, a1 + 509);
goto LABEL_12;
}
v6 = open_log();
v7 = v6;
if ( v6 != -1 )
{
fcntl(v6, 2, 1LL);
v8 = spawn(*v12, v12, v11, (unsigned int)fds[1], v7, v4, v5, a1 + 509);
close(v7);
LABEL_12:
close(fds[1]);
if ( v8 == -1 )
{
close(fds[0]);
func0((__int64)&v11);
*(_DWORD *)(*a1 + 536LL) = 0;
result = 0LL;
*((_DWORD *)a1 + 641) = 503;
return result;
}
fcntl(fds[0], 4, 2048LL);
init_child(*a1, (unsigned int)fds[0]);
func0((__int64)&v11);
if ( debug )
log_d("process_cgi: %d", (unsigned int)fds[0]);
*((_DWORD *)a1 + 1219) = 1;
return (unsigned int)-1;
}
close(fds[0]);
close(fds[1]);
func0((__int64)&v11);
goto LABEL_21;
}
log_d("process_cgi: out of memory");
func0((__int64)&v11);
result = 0LL;
*((_DWORD *)a1 + 641) = 500;
return result;
}

original_code:
int process_cgi(struct request *r)
{
 struct cgi_parameters c;
 uid_t u;
 gid_t g;
 int p[2], efd;
 pid_t pid;
 if (r->curdir[0] == 0) {
  r->status = 500;
  return 0;
 }
 switch (r->c->script_identity) {
 case SI_CHANGETOFIXED:
  u = r->c->script_uid;
  g = r->c->script_gid;
  break;
 case SI_CHANGETOOWNER:
  u = r->finfo.st_uid;
  g = r->finfo.st_gid;
  break;
 default:
  u = 0;
  g = 0;
  break;
 }
 if (amroot) {
  if (u == server_uid) {
   log_d("cannot run scripts without changing identity");
   r->status = 500;
   return 0;
  }
  if (u == 0) {
   log_d("ScriptUser or RunScriptsAsOwner must be set");
   r->status = 500;
   return 0;
  }
 } else if (u) {
  log_d("root privileges are required to change identity");
  r->status = 500;
  return 0;
 }
 c.cgi_envc = 0;
 c.cgi_envp = 0;
 c.cgi_argc = 0;
 c.cgi_argv = 0;
 if (init_cgi_env(r, &c) == -1) {
  log_d("process_cgi: out of memory");
  destroy_parameters(&c);
  r->status = 500;
  return 0;
 }
 if (socketpair(1, SOCK_STREAM, 0, p) == -1) {
  lerror("socketpair");
  destroy_parameters(&c);
  r->status = 500;
  return 0;
 }
 fcntl(p[0], 2, 1);
 fcntl(p[1], 2, 1);
 if (r->c->child_filename) {
  efd = open_log(r->c->child_filename);
  if (efd == -1) {
   close(p[0]);
   close(p[1]);
   destroy_parameters(&c);
   r->status = 500;
   return 0;
  }
  fcntl(efd, 2, 1);
 } else
  efd = -1;
 pid = spawn(c.cgi_argv[0], c.cgi_argv, c.cgi_envp, p[1], efd, u, g, r->curdir);
 if (efd != -1)
  close(efd);
 close(p[1]);
 if (pid == -1) {
  close(p[0]);
  destroy_parameters(&c);
  r->cn->keepalive = 0;
  r->status = 503;
  return 0;
 }
 fcntl(p[0], 4, 04000);
 init_child(r->cn, p[0]);
 destroy_parameters(&c);
 if (debug)
  log_d("process_cgi: %d", p[0]);
 r->forked = 1;
 return -1;
}

canonical_original_code:
int process_cgi(struct request *r)
{
 struct cgi_parameters c;
 unsigned int u;
 unsigned int g;
 int p[2]; int efd;
 int pid;
 if (r->curdir[0] == 0) {
  r->status = 500;
  return 0;
 }
 switch (r->c->script_identity) {
 case SI_CHANGETOFIXED:
  u = r->c->script_uid;
  g = r->c->script_gid;
  break;
 case SI_CHANGETOOWNER:
  u = r->finfo.st_uid;
  g = r->finfo.st_gid;
  break;
 default:
  u = 0;
  g = 0;
  break;
 }
 if (amroot) {
  if (u == server_uid) {
   log_d("cannot run scripts without changing identity");
   r->status = 500;
   return 0;
  }
  if (u == 0) {
   log_d("ScriptUser or RunScriptsAsOwner must be set");
   r->status = 500;
   return 0;
  }
 } else if (u) {
  log_d("root privileges are required to change identity");
  r->status = 500;
  return 0;
 }
 c.cgi_envc = 0;
 c.cgi_envp = 0;
 c.cgi_argc = 0;
 c.cgi_argv = 0;
 if (init_cgi_env(r, &c) == -1) {
  log_d("process_cgi: out of memory");
  destroy_parameters(&c);
  r->status = 500;
  return 0;
 }
 if (socketpair(1, SOCK_STREAM, 0, p) == -1) {
  lerror("socketpair");
  destroy_parameters(&c);
  r->status = 500;
  return 0;
 }
 fcntl(p[0], 2, 1);
 fcntl(p[1], 2, 1);
 if (r->c->child_filename) {
  efd = open_log(r->c->child_filename);
  if (efd == -1) {
   close(p[0]);
   close(p[1]);
   destroy_parameters(&c);
   r->status = 500;
   return 0;
  }
  fcntl(efd, 2, 1);
 } else
  efd = -1;
 pid = spawn(c.cgi_argv[0], c.cgi_argv, c.cgi_envp, p[1], efd, u, g, r->curdir);
 if (efd != -1)
  close(efd);
 close(p[1]);
 if (pid == -1) {
  close(p[0]);
  destroy_parameters(&c);
  r->cn->keepalive = 0;
  r->status = 503;
  return 0;
 }
 fcntl(p[0], 4, 04000);
 init_child(r->cn, p[0]);
 destroy_parameters(&c);
 if (debug)
  log_d("process_cgi: %d", p[0]);
 r->forked = 1;
 return -1;
}

variable_types: struct cgi_parameters { char **cgi_envp; char **cgi_argv; int cgi_envc; int cgi_argc; }

variable_types:
u
unsigned int

variable_types:
g
unsigned int

variable_types:
p
int [2]

variable_types: efd int

variable_types: pid int

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

user_defined_types: struct request_header { char *rh_name; char *rh_value; }

user_defined_types: enum connection_state { HC_UNATTACHED=0, HC_FREE=1, HC_FORKED=2, HC_READING=3, HC_WRITING=4, HC_WAITING=5 }

user_defined_types: struct pool { char *floor; char *ceiling; char *start; char *middle; char *end; char state; unsigned long size; }

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

user_defined_types: struct pipe_params { int state; unsigned long imax; int chunkit; int nocontent; int haslen; unsigned long pmax; }


decompiled_code:
int __fastcall sockaddr_to_addrport(const struct sockaddr *a1, char *a2)
{
socklen_t v3; // esi
int result; // eax

v3 = 16;
if ( a1->sa_family != 2 )
{
v3 = 0;
if ( a1->sa_family == 10 )
v3 = 28;
}
result = getnameinfo(a1, v3, a2, 0x3Au, a2 + 58, 6u, 3);
if ( result )
{
result = 63;
*(_WORD *)a2 = 63;
*((_WORD *)a2 + 29) = 63;
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(const struct sockaddr *a1, char *a2)
{
socklen_t v3; // esi
int result; // eax

v3 = 16;
if ( a1->sa_family != 2 )
{
v3 = 0;
if ( a1->sa_family == 10 )
v3 = 28;
}
result = getnameinfo(a1, v3, a2, 0x3Au, a2 + 58, 6u, 3);
if ( result )
{
result = 63;
*(_WORD *)a2 = 63;
*((_WORD *)a2 + 29) = 63;
}
return result;
}

original_code:
void sockaddr_to_addrport(struct sockaddr *sa, struct addrport *ap)
{
 int l;
 switch (sa->sa_family) {
 case 2:
  l = sizeof (struct sockaddr_in);
  break;
 case 10:
  l = sizeof (struct sockaddr_in6);
  break;
 default:
  l = 0;
  break;
 }
 if (getnameinfo(sa, l, ap->ap_address, sizeof ap->ap_address, ap->ap_port, sizeof ap->ap_port, 1 | 2)) {
  strcpy(ap->ap_address, "?");
  strcpy(ap->ap_port, "?");
 }
}

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

variable_types: struct addrport { char ap_address[58]; char ap_port[6]; } *

variable_types: l int

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

user_defined_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr sin6_addr; unsigned int sin6_scope_id; }

user_defined_types: struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; }


original_code:
int match_address(struct sockaddr *a, struct sockaddr *b, unsigned prefixlen)
{
 unsigned char *abits, *bbits;
 if (a->sa_family != b->sa_family) {
  return 0;
 }
 switch (a->sa_family) {
 case 2:
  abits = (unsigned char *) &((struct sockaddr_in *) a)->sin_addr;
  bbits = (unsigned char *) &((struct sockaddr_in *) b)->sin_addr;
  break;
 case 10:
  abits = (unsigned char *) &((struct sockaddr_in6 *) a)->sin6_addr;
  bbits = (unsigned char *) &((struct sockaddr_in6 *) b)->sin6_addr;
  break;
 default:
  return 0;
 }
 if (prefixlen >= 8) {
  if (memcmp(abits, bbits, prefixlen >> 3)) {
   return 0;
  }
 }
 if ((prefixlen & 7) == 0) {
  return 1;
 }
 return ((abits[prefixlen >> 3] ^ bbits[prefixlen >> 3]) & (0xff00 >> (prefixlen & 7))) == 0;
}

canonical_original_code:
int match_address(struct sockaddr *a, struct sockaddr *b, unsigned int prefixlen)
{
 unsigned char *abits; unsigned char *bbits;
 if (a->sa_family != b->sa_family) {
  return 0;
 }
 switch (a->sa_family) {
 case 2:
  abits = (unsigned char *) &((struct sockaddr_in *) a)->sin_addr;
  bbits = (unsigned char *) &((struct sockaddr_in *) b)->sin_addr;
  break;
 case 10:
  abits = (unsigned char *) &((struct sockaddr_in6 *) a)->sin6_addr;
  bbits = (unsigned char *) &((struct sockaddr_in6 *) b)->sin6_addr;
  break;
 default:
  return 0;
 }
 if (prefixlen >= 8) {
  if (memcmp(abits, bbits, prefixlen >> 3)) {
   return 0;
  }
 }
 if ((prefixlen & 7) == 0) {
  return 1;
 }
 return ((abits[prefixlen >> 3] ^ bbits[prefixlen >> 3]) & (0xff00 >> (prefixlen & 7))) == 0;
}

variable_types:
b
struct sockaddr *

variable_types:
prefixlen
unsigned int

variable_types:
abits
unsigned char *

variable_types:
bbits
unsigned char *

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


decompiled_code:
int log_d(char *format, ...)
{
ssize_t v2; // rax
int *v3; // rax
int v4; // ebp
int *v5; // rbx
struct tm *v6; // rdi
char *v7; // rax
int v8; // eax
__int64 v9; // r15
int v10; // er13
__int64 v11; // rax
int v12; // edi
size_t v13; // r12
gcc_va_list arg; // [rsp+8h] [rbp-4F0h] BYREF
char s[1008]; // [rsp+20h] [rbp-4D8h] BYREF

LODWORD(v2) = tee_fd & error_fd;
if ( (tee_fd & error_fd) != -1 )
{
va_start(arg, format);
v3 = _errno_location();
v4 = *v3;
v5 = v3;
if ( log_gmt )
v6 = gmtime(&current_time);
else
v6 = localtime(&current_time);
v7 = asctime(v6);
v8 = sprintf(s, "%.24s [%d] ", v7, my_pid);
v9 = v8;
v10 = 999 - v8;
LODWORD(v11) = vsnprintf(&s[v8], (unsigned int)(999 - v8), format, arg);
if ( v10 <= (int)v11 )
v11 = (unsigned int)(998 - v9);
else
v11 = (int)v11;
v12 = error_fd;
v2 = v9 + v11;
s[v2] = 10;
v13 = v2 + 1;
if ( v12 != -1 )
{
v2 = write(v12, s, v2 + 1);
if ( v2 == -1 )
gotsigterm = 1;
}
if ( tee_fd != -1 && (v2 = write(tee_fd, s, v13), v2 == -1) )
{
LODWORD(v2) = close(tee_fd);
*v5 = v4;
tee_fd = -1;
}
else
{
*v5 = v4;
}
}
return v2;
}

canonical_decompiled_code:
int func1(char *format, ...)
{
ssize_t v2; // rax
int *v3; // rax
int v4; // ebp
int *v5; // rbx
struct tm *v6; // rdi
char *v7; // rax
int v8; // eax
__int64 v9; // r15
int v10; // er13
__int64 v11; // rax
int v12; // edi
size_t v13; // r12
gcc_va_list arg; // [rsp+8h] [rbp-4F0h] BYREF
char s[1008]; // [rsp+20h] [rbp-4D8h] BYREF

LODWORD(v2) = tee_fd & error_fd;
if ( (tee_fd & error_fd) != -1 )
{
va_start(arg, format);
v3 = _errno_location();
v4 = *v3;
v5 = v3;
if ( log_gmt )
v6 = gmtime(&current_time);
else
v6 = localtime(&current_time);
v7 = asctime(v6);
v8 = sprintf(s, "%.24s [%d] ", v7, my_pid);
v9 = v8;
v10 = 999 - v8;
LODWORD(v11) = vsnprintf(&s[v8], (unsigned int)(999 - v8), format, arg);
if ( v10 <= (int)v11 )
v11 = (unsigned int)(998 - v9);
else
v11 = (int)v11;
v12 = error_fd;
v2 = v9 + v11;
s[v2] = 10;
v13 = v2 + 1;
if ( v12 != -1 )
{
v2 = write(v12, s, v2 + 1);
if ( v2 == -1 )
gotsigterm = 1;
}
if ( tee_fd != -1 && (v2 = write(tee_fd, s, v13), v2 == -1) )
{
LODWORD(v2) = close(tee_fd);
*v5 = v4;
tee_fd = -1;
}
else
{
*v5 = v4;
}
}
return v2;
}

original_code:
void log_d(const char *fmt, ...)
{
 va_list ap;
 char log_line[1000];
 int m, n, saved_errno;
 char *ti;
 size_t l;
 struct tm *tp;
 if (error_fd == -1 && tee_fd == -1)
  return;
 __builtin_va_start(ap,fmt);
 saved_errno = (*__errno_location ());
 if (log_gmt)
  tp = gmtime(&current_time);
 else
  tp = localtime(&current_time);
 ti = asctime(tp);
 l = sprintf(log_line, "%.24s [%d] ", ti, my_pid);
 m = sizeof log_line - l - 1;
 n = vsnprintf(log_line + l, m, fmt, ap);
 l += n < m ? n : m - 1;
 log_line[l++] = '\n';
 if (error_fd != -1 && write(error_fd, log_line, l) == -1)
  gotsigterm = 1;
 if (tee_fd != -1 && write(tee_fd, log_line, l) == -1) {
  close(tee_fd);
  tee_fd = -1;
 }
 (*__errno_location ()) = saved_errno;
 __builtin_va_end(ap);
}

canonical_original_code:
void log_d(char *fmt, ...)
{
 __builtin_va_list ap;
 char log_line[1000];
 int m; int n; int saved_errno;
 char *ti;
 unsigned long l;
 struct tm *tp;
 if (error_fd == -1 && tee_fd == -1)
  return;
 __builtin_va_start(ap,fmt);
 saved_errno = (*__errno_location ());
 if (log_gmt)
  tp = gmtime(&current_time);
 else
  tp = localtime(&current_time);
 ti = asctime(tp);
 l = sprintf(log_line, "%.24s [%d] ", ti, my_pid);
 m = sizeof log_line - l - 1;
 n = vsnprintf(log_line + l, m, fmt, ap);
 l += n < m ? n : m - 1;
 log_line[l++] = '\n';
 if (error_fd != -1 && write(error_fd, log_line, l) == -1)
  gotsigterm = 1;
 if (tee_fd != -1 && write(tee_fd, log_line, l) == -1) {
  close(tee_fd);
  tee_fd = -1;
 }
 (*__errno_location ()) = saved_errno;
 __builtin_va_end(ap);
}

variable_types:
fmt
char *

variable_types: m int

variable_types: n int

variable_types:
ti
char *

variable_types:
l
unsigned long

variable_types: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long tm_gmtoff; char *tm_zone; } *


decompiled_code:
__int64 __fastcall init_log_buffer(size_t a1)
{
log_buffer_size = a1;
if ( !a1 )
return 0LL;
log_buffer = malloc(a1);
if ( log_buffer )
return 0LL;
log_d("init_log_buffer: out of memory");
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func2(size_t a1)
{
log_buffer_size = a1;
if ( !a1 )
return 0LL;
log_buffer = malloc(a1);
if ( log_buffer )
return 0LL;
func1("init_log_buffer: out of memory");
return 0xFFFFFFFFLL;
}

original_code:
int init_log_buffer(size_t size)
{
 log_buffer_size = size;
 if (size == 0)
  return 0;
 log_buffer = malloc(size);
 if (log_buffer == 0) {
  log_d("init_log_buffer: out of memory");
  return -1;
 }
 return 0;
}

canonical_original_code:
int init_log_buffer(unsigned long size)
{
 log_buffer_size = size;
 if (size == 0)
  return 0;
 log_buffer = malloc(size);
 if (log_buffer == 0) {
  log_d("init_log_buffer: out of memory");
  return -1;
 }
 return 0;
}

variable_types:
size
unsigned long


lerror

decompiled_code:
int __fastcall lerror(const char *a1)
{
int *v1; // rax
int v2; // er12
int *v3; // rbx
char *v4; // rsi
int result; // eax

v1 = _errno_location();
v2 = *v1;
v3 = v1;
v4 = strerror(*v1);
if ( !v4 )
v4 = "???";
if ( a1 && *a1 )
{
result = log_d("%s: %s", a1, v4);
*v3 = v2;
}
else
{
result = log_d("%s", v4);
*v3 = v2;
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(const char *a1)
{
int *v1; // rax
int v2; // er12
int *v3; // rbx
char *v4; // rsi
int result; // eax

v1 = _errno_location();
v2 = *v1;
v3 = v1;
v4 = strerror(*v1);
if ( !v4 )
v4 = "???";
if ( a1 && *a1 )
{
result = func1("%s: %s", a1, v4);
*v3 = v2;
}
else
{
result = func1("%s", v4);
*v3 = v2;
}
return result;
}

original_code:
void lerror(const char *s)
{
 int saved_errno;
 char *errmsg;
 saved_errno = (*__errno_location ());
 errmsg = strerror((*__errno_location ()));
 if (s && *s)
  log_d("%s: %s", s, errmsg ? errmsg : "???");
 else
  log_d("%s", errmsg ? errmsg : "???");
 (*__errno_location ()) = saved_errno;
}

canonical_original_code:
void lerror(char *s)
{
 int saved_errno;
 char *errmsg;
 saved_errno = (*__errno_location ());
 errmsg = strerror((*__errno_location ()));
 if (s && *s)
  log_d("%s: %s", s, errmsg ? errmsg : "???");
 else
  log_d("%s", errmsg ? errmsg : "???");
 (*__errno_location ()) = saved_errno;
}

variable_types:
s
char *

variable_types:
errmsg
char *


decompiled_code:
void __fastcall log_request(__int64 a1)
{
int v1; // er14
_BYTE *v3; // r15
__int64 v4; // rbx
int v5; // ebp
char *v6; // r12
_BYTE *v7; // rax
int v8; // eax
int v9; // ecx
__int64 v10; // rbp
struct tm *v11; // rdi
__int64 v12; // rdx
__suseconds_t v13; // rcx
__time_t v14; // rdx
__int64 v15; // rdx
__int64 v16; // rdx
int v17; // [rsp+0h] [rbp-10Ch]
time_t timer; // [rsp+Ch] [rbp-100h] BYREF
struct timeval tv; // [rsp+14h] [rbp-F8h] BYREF
__int64 v20[2]; // [rsp+24h] [rbp-E8h] BYREF
char v21[32]; // [rsp+34h] [rbp-D8h] BYREF
char v22[58]; // [rsp+54h] [rbp-B8h] BYREF
char v23; // [rsp+8Eh] [rbp-7Eh] BYREF
char s[58]; // [rsp+94h] [rbp-78h] BYREF
char v25; // [rsp+CEh] [rbp-3Eh] BYREF

if ( log_fd != -1 )
{
if ( log_columns <= 0 )
{
if ( !l1_1 )
{
l1_1 = 1;
log_d("log_request: nothing to log!");
}
}
else
{
v1 = log_buffer_size - log_columns;
if ( (int)log_buffer_size - log_columns < 0 )
{
if ( !l2_0 )
{
l2_0 = 1;
log_d("log_request: buffer too small!?!?");
}
}
else
{
v3 = log_buffer;
gettimeofday(&tv, 0LL);
timer = tv.tv_sec;
sockaddr_to_addrport(*(_QWORD *)a1 + 48LL, s);
sockaddr_to_addrport(*(_QWORD *)a1 + 176LL, v22);
if ( log_columns > 0 )
{
v4 = 0LL;
do
{
v5 = log_buffer_size;
switch ( *(_DWORD *)(log_column + 4 * v4) )
{
case 0:
if ( log_gmt )
v11 = gmtime(&timer);
else
v11 = localtime(&timer);
v5 = 24;
v6 = asctime(v11);
goto LABEL_10;
case 1:
v6 = (char *)(a1 + 2736);
goto LABEL_19;
case 2:
v6 = s;
goto LABEL_10;
case 3:
v6 = &v25;
goto LABEL_19;
case 4:
v6 = v22;
goto LABEL_19;
case 5:
v6 = &v23;
goto LABEL_19;
case 6:
v6 = *(char **)(a1 + 40);
goto LABEL_10;
case 7:
v6 = *(char **)(a1 + 2520);
goto LABEL_10;
case 8:
v6 = *(char **)(a1 + 2528);
goto LABEL_10;
case 9:
v6 = *(char **)(a1 + 2544);
goto LABEL_10;
case 0xA:
v12 = *(unsigned int *)(a1 + 2564);
goto LABEL_32;
case 0xB:
v16 = *(int *)(a1 + 2480);
if ( v16 >= 0 )
v16 = *(_QWORD *)(a1 + 2488);
if ( v16 < 0 )
v16 = 0LL;
v6 = v21;
sprintf(v21, "%ld", v16);
goto LABEL_19;
case 0xC:
v6 = *(char **)(a1 + 24);
goto LABEL_10;
case 0xD:
v6 = *(char **)(a1 + 16);
goto LABEL_10;
case 0xE:
v15 = *(_QWORD *)(*(_QWORD *)a1 + 552LL);
goto LABEL_38;
case 0xF:
v15 = *(_QWORD *)(*(_QWORD *)a1 + 560LL);
LABEL_38:
sprintf(v21, "%llu", v15);
v6 = v21;
goto LABEL_19;
case 0x10:
v6 = *(char **)(a1 + 2536);
LABEL_10:
if ( !v6 )
goto LABEL_11;
goto LABEL_19;
case 0x11:
tvdiff_isra_0(
tv.tv_sec,
tv.tv_usec,
*(_QWORD *)(*(_QWORD *)a1 + 584LL),
*(_QWORD *)(*(_QWORD *)a1 + 592LL),
v20);
v13 = v20[1];
v14 = v20[0];
goto LABEL_34;
case 0x12:
v13 = tv.tv_usec;
v14 = tv.tv_sec;
LABEL_34:
sprintf(v21, "%ld.%06ld", v14, v13);
v6 = v21;
goto LABEL_19;
case 0x13:
v12 = my_pid;
LABEL_32:
sprintf(v21, "%d", v12);
v6 = v21;
LABEL_19:
if ( !*v6 )
goto LABEL_11;
v8 = strlen(v6);
if ( v1 <= v5 )
v5 = v1;
v9 = v8;
if ( v5 <= v8 )
v9 = v5;
v10 = v9;
v17 = v9;
memcpy(v3, v6, v9);
v7 = &v3[v10];
v1 -= v17;
break;
default:
LABEL_11:
v7 = v3;
if ( v1 )
{
*v3 = 45;
v7 = v3 + 1;
--v1;
}
break;
}
*v7 = 9;
++v4;
v3 = v7 + 1;
}
while ( log_columns > (int)v4 );
}
*(v3 - 1) = 10;
if ( write(log_fd, log_buffer, v3 - (_BYTE *)log_buffer) == -1 )
{
gotsigterm = 1;
log_d("log_request: cannot write to log file");
lerror("write");
}
}
}
}
}

canonical_decompiled_code:
void __fastcall func4(__int64 a1)
{
int v1; // er14
_BYTE *v3; // r15
__int64 v4; // rbx
int v5; // ebp
char *v6; // r12
_BYTE *v7; // rax
int v8; // eax
int v9; // ecx
__int64 v10; // rbp
struct tm *v11; // rdi
__int64 v12; // rdx
__suseconds_t v13; // rcx
__time_t v14; // rdx
__int64 v15; // rdx
__int64 v16; // rdx
int v17; // [rsp+0h] [rbp-10Ch]
time_t timer; // [rsp+Ch] [rbp-100h] BYREF
struct timeval tv; // [rsp+14h] [rbp-F8h] BYREF
__int64 v20[2]; // [rsp+24h] [rbp-E8h] BYREF
char v21[32]; // [rsp+34h] [rbp-D8h] BYREF
char v22[58]; // [rsp+54h] [rbp-B8h] BYREF
char v23; // [rsp+8Eh] [rbp-7Eh] BYREF
char s[58]; // [rsp+94h] [rbp-78h] BYREF
char v25; // [rsp+CEh] [rbp-3Eh] BYREF

if ( log_fd != -1 )
{
if ( log_columns <= 0 )
{
if ( !l1_1 )
{
l1_1 = 1;
func1("log_request: nothing to log!");
}
}
else
{
v1 = log_buffer_size - log_columns;
if ( (int)log_buffer_size - log_columns < 0 )
{
if ( !l2_0 )
{
l2_0 = 1;
func1("log_request: buffer too small!?!?");
}
}
else
{
v3 = log_buffer;
gettimeofday(&tv, 0LL);
timer = tv.tv_sec;
sockaddr_to_addrport(*(_QWORD *)a1 + 48LL, s);
sockaddr_to_addrport(*(_QWORD *)a1 + 176LL, v22);
if ( log_columns > 0 )
{
v4 = 0LL;
do
{
v5 = log_buffer_size;
switch ( *(_DWORD *)(log_column + 4 * v4) )
{
case 0:
if ( log_gmt )
v11 = gmtime(&timer);
else
v11 = localtime(&timer);
v5 = 24;
v6 = asctime(v11);
goto LABEL_10;
case 1:
v6 = (char *)(a1 + 2736);
goto LABEL_19;
case 2:
v6 = s;
goto LABEL_10;
case 3:
v6 = &v25;
goto LABEL_19;
case 4:
v6 = v22;
goto LABEL_19;
case 5:
v6 = &v23;
goto LABEL_19;
case 6:
v6 = *(char **)(a1 + 40);
goto LABEL_10;
case 7:
v6 = *(char **)(a1 + 2520);
goto LABEL_10;
case 8:
v6 = *(char **)(a1 + 2528);
goto LABEL_10;
case 9:
v6 = *(char **)(a1 + 2544);
goto LABEL_10;
case 0xA:
v12 = *(unsigned int *)(a1 + 2564);
goto LABEL_32;
case 0xB:
v16 = *(int *)(a1 + 2480);
if ( v16 >= 0 )
v16 = *(_QWORD *)(a1 + 2488);
if ( v16 < 0 )
v16 = 0LL;
v6 = v21;
sprintf(v21, "%ld", v16);
goto LABEL_19;
case 0xC:
v6 = *(char **)(a1 + 24);
goto LABEL_10;
case 0xD:
v6 = *(char **)(a1 + 16);
goto LABEL_10;
case 0xE:
v15 = *(_QWORD *)(*(_QWORD *)a1 + 552LL);
goto LABEL_38;
case 0xF:
v15 = *(_QWORD *)(*(_QWORD *)a1 + 560LL);
LABEL_38:
sprintf(v21, "%llu", v15);
v6 = v21;
goto LABEL_19;
case 0x10:
v6 = *(char **)(a1 + 2536);
LABEL_10:
if ( !v6 )
goto LABEL_11;
goto LABEL_19;
case 0x11:
func0(
tv.tv_sec,
tv.tv_usec,
*(_QWORD *)(*(_QWORD *)a1 + 584LL),
*(_QWORD *)(*(_QWORD *)a1 + 592LL),
v20);
v13 = v20[1];
v14 = v20[0];
goto LABEL_34;
case 0x12:
v13 = tv.tv_usec;
v14 = tv.tv_sec;
LABEL_34:
sprintf(v21, "%ld.%06ld", v14, v13);
v6 = v21;
goto LABEL_19;
case 0x13:
v12 = my_pid;
LABEL_32:
sprintf(v21, "%d", v12);
v6 = v21;
LABEL_19:
if ( !*v6 )
goto LABEL_11;
v8 = strlen(v6);
if ( v1 <= v5 )
v5 = v1;
v9 = v8;
if ( v5 <= v8 )
v9 = v5;
v10 = v9;
v17 = v9;
memcpy(v3, v6, v9);
v7 = &v3[v10];
v1 -= v17;
break;
default:
LABEL_11:
v7 = v3;
if ( v1 )
{
*v3 = 45;
v7 = v3 + 1;
--v1;
}
break;
}
*v7 = 9;
++v4;
v3 = v7 + 1;
}
while ( log_columns > (int)v4 );
}
*(v3 - 1) = 10;
if ( write(log_fd, log_buffer, v3 - (_BYTE *)log_buffer) == -1 )
{
gotsigterm = 1;
func1("log_request: cannot write to log file");
func3("write");
}
}
}
}
}

original_code:
void log_request(struct request *r)
{
 const char *s;
 char tmp[20];
 long cl;
 int i, l, n;
 int left;
 char *b;
 static int l1, l2;
 struct tm *tp;
 struct timeval tv, dtv;
 time_t rounded_time;
 struct addrport local, remote;
 if (log_fd == -1)
  return;
 if (log_columns <= 0) {
  if (l1 == 0) {
   l1 = 1;
   log_d("log_request: nothing to log!");
  }
  return;
 }
 left = log_buffer_size - log_columns;
 if (left < 0) {
  if (l2 == 0) {
   l2 = 1;
   log_d("log_request: buffer too small!?!?");
  }
  return;
 }
 b = log_buffer;
 gettimeofday(&tv, 0);
 rounded_time = tv.tv_sec;
 sockaddr_to_addrport((struct sockaddr *) &r->cn->peer, &remote);
 sockaddr_to_addrport((struct sockaddr *) &r->cn->sock, &local);
 for (i = 0; i < log_columns; i++) {
  l = log_buffer_size;
  s = 0;
  switch (log_column[i]) {
  case ML_CTIME:
   tp = log_gmt ? gmtime(&rounded_time) : localtime(&rounded_time);
   s = asctime(tp);
   l = 24;
   break;
  case ML_USERNAME:
   s = r->user;
   break;
  case ML_REMOTE_ADDRESS:
   s = remote.ap_address;
   break;
  case ML_REMOTE_PORT:
   s = remote.ap_port;
   break;
  case ML_LOCAL_ADDRESS:
   s = local.ap_address;
   break;
  case ML_LOCAL_PORT:
   s = local.ap_port;
   break;
  case ML_SERVERNAME:
   s = r->host;
   break;
  case ML_METHOD:
   s = r->method_s;
   break;
  case ML_URI:
   s = r->url;
   break;
  case ML_VERSION:
   s = r->version;
   break;
  case ML_STATUS:
   sprintf(tmp, "%d", r->status);
   s = tmp;
   break;
  case ML_CONTENT_LENGTH:
   cl = r->num_content;
   if (cl >= 0)
    cl = r->content_length;
   if (cl < 0)
    cl = 0;
   sprintf(tmp, "%ld", cl);
   s = tmp;
   break;
  case ML_REFERER:
   s = r->referer;
   break;
  case ML_USER_AGENT:
   s = r->user_agent;
   break;
  case ML_BYTES_READ:
   sprintf(tmp, "%llu", r->cn->nread);
   s = tmp;
   break;
  case ML_BYTES_WRITTEN:
   sprintf(tmp, "%llu", r->cn->nwritten);
   s = tmp;
   break;
  case ML_QUERY_STRING:
   s = r->args;
   break;
  case ML_TIME_TAKEN:
   tvdiff(&tv, &r->cn->itv, &dtv);
   sprintf(tmp, "%ld.%06ld", (long) dtv.tv_sec, dtv.tv_usec);
   s = tmp;
   break;
  case ML_MICRO_TIME:
   sprintf(tmp, "%ld.%06ld", (long) tv.tv_sec, tv.tv_usec);
   s = tmp;
   break;
  case ML_PID:
   sprintf(tmp, "%d", my_pid);
   s = tmp;
   break;
  }
  if (s == 0 || *s == 0) {
   if (left) {
    *b++ = '-';
    --left;
   }
  } else {
   n = strlen(s);
   if (n > l)
    n = l;
   if (n > left)
    n = left;
   memcpy(b, s, n);
   left -= n;
   b += n;
  }
  *b++ = '\t';
 }
 b[-1] = '\n';
 if (write(log_fd, log_buffer, b - log_buffer) == -1) {
  gotsigterm = 1;
  log_d("log_request: cannot write to log file");
  lerror("write");
 }
 return;
}

canonical_original_code:
void log_request(struct request *r)
{
 char *s;
 char tmp[20];
 long cl;
 int i; int l; int n;
 int left;
 char *b;
 static int l1; static int l2;
 struct tm *tp;
 struct timeval tv; struct timeval dtv;
 long rounded_time;
 struct addrport local; struct addrport remote;
 if (log_fd == -1)
  return;
 if (log_columns <= 0) {
  if (l1 == 0) {
   l1 = 1;
   log_d("log_request: nothing to log!");
  }
  return;
 }
 left = log_buffer_size - log_columns;
 if (left < 0) {
  if (l2 == 0) {
   l2 = 1;
   log_d("log_request: buffer too small!?!?");
  }
  return;
 }
 b = log_buffer;
 gettimeofday(&tv, 0);
 rounded_time = tv.tv_sec;
 sockaddr_to_addrport((struct sockaddr *) &r->cn->peer, &remote);
 sockaddr_to_addrport((struct sockaddr *) &r->cn->sock, &local);
 for (i = 0; i < log_columns; i++) {
  l = log_buffer_size;
  s = 0;
  switch (log_column[i]) {
  case ML_CTIME:
   tp = log_gmt ? gmtime(&rounded_time) : localtime(&rounded_time);
   s = asctime(tp);
   l = 24;
   break;
  case ML_USERNAME:
   s = r->user;
   break;
  case ML_REMOTE_ADDRESS:
   s = remote.ap_address;
   break;
  case ML_REMOTE_PORT:
   s = remote.ap_port;
   break;
  case ML_LOCAL_ADDRESS:
   s = local.ap_address;
   break;
  case ML_LOCAL_PORT:
   s = local.ap_port;
   break;
  case ML_SERVERNAME:
   s = r->host;
   break;
  case ML_METHOD:
   s = r->method_s;
   break;
  case ML_URI:
   s = r->url;
   break;
  case ML_VERSION:
   s = r->version;
   break;
  case ML_STATUS:
   sprintf(tmp, "%d", r->status);
   s = tmp;
   break;
  case ML_CONTENT_LENGTH:
   cl = r->num_content;
   if (cl >= 0)
    cl = r->content_length;
   if (cl < 0)
    cl = 0;
   sprintf(tmp, "%ld", cl);
   s = tmp;
   break;
  case ML_REFERER:
   s = r->referer;
   break;
  case ML_USER_AGENT:
   s = r->user_agent;
   break;
  case ML_BYTES_READ:
   sprintf(tmp, "%llu", r->cn->nread);
   s = tmp;
   break;
  case ML_BYTES_WRITTEN:
   sprintf(tmp, "%llu", r->cn->nwritten);
   s = tmp;
   break;
  case ML_QUERY_STRING:
   s = r->args;
   break;
  case ML_TIME_TAKEN:
   tvdiff(&tv, &r->cn->itv, &dtv);
   sprintf(tmp, "%ld.%06ld", (long) dtv.tv_sec, dtv.tv_usec);
   s = tmp;
   break;
  case ML_MICRO_TIME:
   sprintf(tmp, "%ld.%06ld", (long) tv.tv_sec, tv.tv_usec);
   s = tmp;
   break;
  case ML_PID:
   sprintf(tmp, "%d", my_pid);
   s = tmp;
   break;
  }
  if (s == 0 || *s == 0) {
   if (left) {
    *b++ = '-';
    --left;
   }
  } else {
   n = strlen(s);
   if (n > l)
    n = l;
   if (n > left)
    n = left;
   memcpy(b, s, n);
   left -= n;
   b += n;
  }
  *b++ = '\t';
 }
 b[-1] = '\n';
 if (write(log_fd, log_buffer, b - log_buffer) == -1) {
  gotsigterm = 1;
  log_d("log_request: cannot write to log file");
  lerror("write");
 }
 return;
}

variable_types: struct request { struct connection { struct connection *next; struct connection *prev; enum connection_state { HC_UNATTACHED=0, HC_FREE=1, HC_FORKED=2, HC_READING=3, HC_WRITING=4, HC_WAITING=5 } connection_state; struct request *r; struct server { int fd; unsigned long server_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *server_addr; struct virtual { char *host; struct virtual *next; struct vserver { struct control { char *alias; int path_args_ok; int exact_match; struct simple_list { char *name; struct simple_list *next; } *index_names; struct access { int type; struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; } addr; unsigned int prefixlen; struct access *next; } *accesses; struct mime { int class; char *ext; char *name; struct mime *next; } *mimes; struct control *next; struct simple_list *locations; struct access *clients; char *admin; char *realm; char *userfile; char *error_401_file; char *error_403_file; char *error_404_file; int do_crypt; char *child_filename; struct simple_list *exports; int script_identity; unsigned int script_uid; unsigned int script_gid; int allow_dotfiles; int user_directory; struct simple_list *putenvs; struct simple_list *extra_headers; int path_info_ok; char *auto_index_command; unsigned long expire_interval; int sanitize_path; } *controls; struct vserver *next; } *vserver; int anyhost; } *children; struct control *controls; struct server *next; int pollno; struct vserver *vservers; unsigned long backlog; char *addr; char *port; int family; int socktype; int protocol; struct server_sockopts { int ss_level; int ss_optname; void *ss_optval; unsigned int ss_optlen; struct server_sockopts *next; } *options; } *s; int fd; int rfd; struct sockaddr_storage peer; struct sockaddr_storage sock; long t; struct pool { char *floor; char *ceiling; char *start; char *middle; char *end; char state; unsigned long size; } header_input; struct pool output; struct pool client_input; struct pool script_input; int keepalive; int pollno; int rpollno; unsigned long long nread; unsigned long long nwritten; long long left; int logged; struct timeval { long tv_sec; long tv_usec; } itv; struct pipe_params { int state; unsigned long imax; int chunkit; int nocontent; int haslen; unsigned long pmax; } pipe_params; long file_offset; int havefile; } *cn; struct virtual *vs; char *user_agent; char *referer; char *authorization; char *host; char *in_content_type; char *in_content_length; char *ims_s; char path[-1]; char path_translated[-1]; char path_args[-1]; char *content_type; int num_content; int class; long long content_length; long last_modified; long ims; char *location; char *method_s; char *url; char *args; char *version; int protocol_major; int protocol_minor; int method; int status; struct control *c; 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]; } finfo; int isindex; char *error_file; char user[16]; char newloc[-1]; unsigned long location_length; unsigned long nheaders; struct request_header { char *rh_name; char *rh_value; } *headers; char *range_s; char *if_range_s; long if_range; int range; unsigned long long range_floor; unsigned long long range_ceiling; unsigned long long range_suffix; unsigned long long range_total; char *ius_s; long ius; char rhost[400]; char *in_transfer_encoding; unsigned long in_mblen; char curdir[-1]; int send_continue; int forked; } *

variable_types:
tmp
char [20]

variable_types: cl long

variable_types: i int

variable_types: left int

variable_types:
b
char *

variable_types: struct addrport { char ap_address[58]; char ap_port[6]; }

user_defined_types: struct request { struct connection *cn; struct virtual *vs; char *user_agent; char *referer; char *authorization; char *host; char *in_content_type; char *in_content_length; char *ims_s; char path[-1]; char path_translated[-1]; char path_args[-1]; char *content_type; int num_content; int class; long long content_length; long last_modified; long ims; char *location; char *method_s; char *url; char *args; char *version; int protocol_major; int protocol_minor; int method; int status; struct control *c; struct stat finfo; int isindex; char *error_file; char user[16]; char newloc[-1]; unsigned long location_length; unsigned long nheaders; struct request_header *headers; char *range_s; char *if_range_s; long if_range; int range; unsigned long long range_floor; unsigned long long range_ceiling; unsigned long long range_suffix; unsigned long long range_total; char *ius_s; long ius; char rhost[400]; char *in_transfer_encoding; unsigned long in_mblen; char curdir[-1]; int send_continue; int forked; }

user_defined_types: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; long tm_gmtoff; char *tm_zone; }

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:
__int64 __fastcall open_log(char *file)
{
char *v1; // rbp
const struct tm *v2; // rcx
unsigned int v3; // er12
char v5[824]; // [rsp+0h] [rbp-338h] BYREF

v1 = file;
if ( strchr(file, 37) )
{
current_time = time(0LL);
v2 = log_gmt ? gmtime(&current_time) : localtime(&current_time);
if ( v2 && strftime(v5, 0x31FuLL, file, v2) )
v1 = v5;
}
v3 = open(v1, 1089, 438LL);
if ( v3 == -1 )
{
log_d("cannot open %s", v1);
lerror("open");
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *file)
{
char *v1; // rbp
const struct tm *v2; // rcx
unsigned int v3; // er12
char v5[824]; // [rsp+0h] [rbp-338h] BYREF

v1 = file;
if ( strchr(file, 37) )
{
current_time = time(0LL);
v2 = log_gmt ? gmtime(&current_time) : localtime(&current_time);
if ( v2 && strftime(v5, 0x31FuLL, file, v2) )
v1 = v5;
}
v3 = open(v1, 1089, 438LL);
if ( v3 == -1 )
{
func1("cannot open %s", v1);
func3("open");
}
return v3;
}

original_code:
int open_log(const char *name)
{
 char converted_name[(2 * 400)];
 const char *n;
 struct tm *tp;
 int rv;
 n = name;
 if (strchr(name, '%')) {
  current_time = time(0);
  if (log_gmt)
   tp = gmtime(&current_time);
  else
   tp = localtime(&current_time);
  if (tp) {
   if (strftime(converted_name, (2 * 400) - 1, name, tp))
    n = converted_name;
  }
 }
 rv = open(n, 01 | 0100 | 02000, 0666);
 if (rv == -1) {
  log_d("cannot open %s", n);
  lerror("open");
 }
 return rv;
}

canonical_original_code:
int open_log(char *name)
{
 char converted_name[-1];
 char *n;
 struct tm *tp;
 int rv;
 n = name;
 if (strchr(name, '%')) {
  current_time = time(0);
  if (log_gmt)
   tp = gmtime(&current_time);
  else
   tp = localtime(&current_time);
  if (tp) {
   if (strftime(converted_name, (2 * 400) - 1, name, tp))
    n = converted_name;
  }
 }
 rv = open(n, 01 | 0100 | 02000, 0666);
 if (rv == -1) {
  log_d("cannot open %s", n);
  lerror("open");
 }
 return rv;
}

variable_types:
name
char *

variable_types:
n
char *

variable_types: rv int


decompiled_code:
__int64 __fastcall init_log_d(char *file, int *a2)
{
unsigned int v2; // er12
int v3; // ebp
bool v4; // zf
int v6; // eax

v2 = 0;
if ( !file )
return v2;
v3 = *a2;
v4 = strcmp(file, "/dev/stdout") == 0;
v2 = !v4;
if ( v4 )
{
if ( v3 != -1 )
return v2;
v2 = dup(1);
if ( v2 != -1 )
goto LABEL_8;
return (unsigned int)-(v3 == -1);
}
v4 = strcmp(file, "/dev/stderr") == 0;
v2 = !v4;
if ( v4 )
{
if ( v3 != -1 )
return v2;
v2 = dup(2);
if ( v2 == -1 )
return v2;
goto LABEL_8;
}
v6 = open_log(file);
v2 = v6;
if ( v6 == -1 )
return (unsigned int)-(v3 == -1);
if ( v3 != -1 )
{
if ( v3 != v6 )
{
dup2(v6, v3);
close(v2);
}
goto LABEL_9;
}
LABEL_8:
*a2 = v2;
v3 = v2;
LABEL_9:
fcntl(v3, 2, 1LL);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(char *file, int *a2)
{
unsigned int v2; // er12
int v3; // ebp
bool v4; // zf
int v6; // eax

v2 = 0;
if ( !file )
return v2;
v3 = *a2;
v4 = strcmp(file, "/dev/stdout") == 0;
v2 = !v4;
if ( v4 )
{
if ( v3 != -1 )
return v2;
v2 = dup(1);
if ( v2 != -1 )
goto LABEL_8;
return (unsigned int)-(v3 == -1);
}
v4 = strcmp(file, "/dev/stderr") == 0;
v2 = !v4;
if ( v4 )
{
if ( v3 != -1 )
return v2;
v2 = dup(2);
if ( v2 == -1 )
return v2;
goto LABEL_8;
}
v6 = func5(file);
v2 = v6;
if ( v6 == -1 )
return (unsigned int)-(v3 == -1);
if ( v3 != -1 )
{
if ( v3 != v6 )
{
dup2(v6, v3);
close(v2);
}
goto LABEL_9;
}
LABEL_8:
*a2 = v2;
v3 = v2;
LABEL_9:
fcntl(v3, 2, 1LL);
return 0LL;
}

original_code:
static int init_log_d(char *name, int *fdp)
{
 int fd, nfd;
 if (name) {
  fd = *fdp;
  if (strcmp(name, "/dev/stdout") == 0) {
   if (fd != -1)
    return 0;
   nfd = dup(1);
  } else if (strcmp(name, "/dev/stderr") == 0) {
   if (fd != -1)
    return 0;
   nfd = dup(2);
  } else
   nfd = open_log(name);
  if (nfd == -1)
   return fd == -1 ? -1 : 0;
  if (fd == -1)
   *fdp = nfd;
  else if (nfd != fd) {
   dup2(nfd, fd);
   close(nfd);
   nfd = fd;
  }
  fcntl(nfd, 2, 1);
 }
 return 0;
}

canonical_original_code:
static int init_log_d(char *name, int *fdp)
{
 int fd; int nfd;
 if (name) {
  fd = *fdp;
  if (strcmp(name, "/dev/stdout") == 0) {
   if (fd != -1)
    return 0;
   nfd = dup(1);
  } else if (strcmp(name, "/dev/stderr") == 0) {
   if (fd != -1)
    return 0;
   nfd = dup(2);
  } else
   nfd = open_log(name);
  if (nfd == -1)
   return fd == -1 ? -1 : 0;
  if (fd == -1)
   *fdp = nfd;
  else if (nfd != fd) {
   dup2(nfd, fd);
   close(nfd);
   nfd = fd;
  }
  fcntl(nfd, 2, 1);
 }
 return 0;
}

variable_types:
fdp
int *

variable_types: fd int

variable_types: nfd int


decompiled_code:
__int64 __fastcall init_logs(int a1)
{
__int64 result; // rax

if ( a1 && tee_fd == -1 && (tee_fd = dup(2), tee_fd == -1)
|| (unsigned int)init_log_d(error_filename, &error_fd) == -1 )
{
result = 0xFFFFFFFFLL;
}
else
{
result = (unsigned int)-((unsigned int)init_log_d(log_filename, &log_fd) == -1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(int a1)
{
__int64 result; // rax

if ( a1 && tee_fd == -1 && (tee_fd = dup(2), tee_fd == -1)
|| (unsigned int)func6(error_filename, &error_fd) == -1 )
{
result = 0xFFFFFFFFLL;
}
else
{
result = (unsigned int)-((unsigned int)func6(log_filename, &log_fd) == -1);
}
return result;
}

original_code:
int init_logs(int tee)
{
 if (tee && tee_fd == -1) {
  tee_fd = dup(2);
  if (tee_fd == -1)
   return -1;
 }
 return init_log_d(error_filename, &error_fd) == -1 || init_log_d(log_filename, &log_fd) == -1 ? -1 : 0;
}

variable_types: tee int


decompiled_code:
__int64 __fastcall process_redirect(__int64 a1)
{
__int64 result; // rax
const char *v2; // r12
int v3; // eax
int v4; // ebp
unsigned __int64 v5; // r13
ssize_t v6; // rax
char *v7; // rax

if ( (unsigned int)(*(_DWORD *)(a1 + 2560) - 1) > 1 )
{
*(_DWORD *)(a1 + 2564) = 405;
return 0LL;
}
v2 = (const char *)(a1 + 872);
v3 = open((const char *)(a1 + 872), 2048);
v4 = v3;
if ( v3 == -1 )
{
log_d("process_redirect: cannot open %s", v2);
lerror("open");
*(_DWORD *)(a1 + 2564) = 500;
return 0LL;
}
v5 = a1 + 2752;
v6 = read(v3, (void *)(a1 + 2752), 0x31FuLL);
if ( v6 == -1 )
{
log_d("process_redirect: cannot read %s", v2);
lerror("read");
close(v4);
*(_DWORD *)(a1 + 2564) = 500;
return 0LL;
}
*(_BYTE *)(a1 + v6 + 2752) = 0;
close(v4);
v7 = strchr((const char *)(a1 + 2752), 10);
if ( !v7 )
{
log_d("process_redirect: no newline in %s", v2);
*(_DWORD *)(a1 + 2564) = 500;
return 0LL;
}
if ( v5 < (unsigned __int64)v7 )
v7 -= *(v7 - 1) == 13;
*v7 = 0;
result = 0LL;
*(_QWORD *)(a1 + 2512) = v5;
*(_DWORD *)(a1 + 2564) = 302;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 result; // rax
const char *v2; // r12
int v3; // eax
int v4; // ebp
unsigned __int64 v5; // r13
ssize_t v6; // rax
char *v7; // rax

if ( (unsigned int)(*(_DWORD *)(a1 + 2560) - 1) > 1 )
{
*(_DWORD *)(a1 + 2564) = 405;
return 0LL;
}
v2 = (const char *)(a1 + 872);
v3 = open((const char *)(a1 + 872), 2048);
v4 = v3;
if ( v3 == -1 )
{
log_d("process_redirect: cannot open %s", v2);
lerror("open");
*(_DWORD *)(a1 + 2564) = 500;
return 0LL;
}
v5 = a1 + 2752;
v6 = read(v3, (void *)(a1 + 2752), 0x31FuLL);
if ( v6 == -1 )
{
log_d("process_redirect: cannot read %s", v2);
lerror("read");
close(v4);
*(_DWORD *)(a1 + 2564) = 500;
return 0LL;
}
*(_BYTE *)(a1 + v6 + 2752) = 0;
close(v4);
v7 = strchr((const char *)(a1 + 2752), 10);
if ( !v7 )
{
log_d("process_redirect: no newline in %s", v2);
*(_DWORD *)(a1 + 2564) = 500;
return 0LL;
}
if ( v5 < (unsigned __int64)v7 )
v7 -= *(v7 - 1) == 13;
*v7 = 0;
result = 0LL;
*(_QWORD *)(a1 + 2512) = v5;
*(_DWORD *)(a1 + 2564) = 302;
return result;
}

original_code:
int process_redirect(struct request *r)
{
 char *c;
 int fd;
 ssize_t l;
 if (r->method != M_GET && r->method != M_HEAD) {
  r->status = 405;
  return 0;
 }
 fd = open(r->path_translated, 00 | 04000);
 if (fd == -1) {
  log_d("process_redirect: cannot open %s", r->path_translated);
  lerror("open");
  r->status = 500;
  return 0;
 }
 l = read(fd, r->newloc, (2 * 400) - 1);
 if (l == -1) {
  log_d("process_redirect: cannot read %s", r->path_translated);
  lerror("read");
  close(fd);
  r->status = 500;
  return 0;
 }
 r->newloc[l] = 0;
 close(fd);
 c = strchr(r->newloc, '\n');
 if (c == 0) {
  log_d("process_redirect: no newline in %s", r->path_translated);
  r->status = 500;
  return 0;
 }
 if (c > r->newloc && c[-1] == '\r')
  --c;
 *c = 0;
 r->location = r->newloc;
 r->status = 302;
 return 0;
}

canonical_original_code:
int process_redirect(struct request *r)
{
 char *c;
 int fd;
 long l;
 if (r->method != M_GET && r->method != M_HEAD) {
  r->status = 405;
  return 0;
 }
 fd = open(r->path_translated, 00 | 04000);
 if (fd == -1) {
  log_d("process_redirect: cannot open %s", r->path_translated);
  lerror("open");
  r->status = 500;
  return 0;
 }
 l = read(fd, r->newloc, (2 * 400) - 1);
 if (l == -1) {
  log_d("process_redirect: cannot read %s", r->path_translated);
  lerror("read");
  close(fd);
  r->status = 500;
  return 0;
 }
 r->newloc[l] = 0;
 close(fd);
 c = strchr(r->newloc, '\n');
 if (c == 0) {
  log_d("process_redirect: no newline in %s", r->path_translated);
  r->status = 500;
  return 0;
 }
 if (c > r->newloc && c[-1] == '\r')
  --c;
 *c = 0;
 r->location = r->newloc;
 r->status = 302;
 return 0;
}

variable_types:
c
char *

variable_types: l long

user_defined_types: struct connection { struct connection *next; struct connection *prev; enum connection_state connection_state; struct request *r; struct server *s; int fd; int rfd; struct sockaddr_storage peer; struct sockaddr_storage sock; long t; struct pool header_input; struct pool output; struct pool client_input; struct pool script_input; int keepalive; int pollno; int rpollno; unsigned long long nread; unsigned long long nwritten; long long left; int logged; struct timeval itv; struct pipe_params pipe_params; long file_offset; int havefile; }

user_defined_types: struct server { int fd; unsigned long server_addrlen; struct sockaddr *server_addr; struct virtual *children; struct control *controls; struct server *next; int pollno; struct vserver *vservers; unsigned long backlog; char *addr; char *port; int family; int socktype; int protocol; struct server_sockopts *options; }

user_defined_types: struct virtual { char *host; struct virtual *next; struct vserver *vserver; int anyhost; }

user_defined_types: struct server_sockopts { int ss_level; int ss_optname; void *ss_optval; unsigned int ss_optlen; struct server_sockopts *next; }

user_defined_types: struct simple_list { char *name; struct simple_list *next; }

user_defined_types: struct mime { int class; char *ext; char *name; struct mime *next; }

user_defined_types: struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; }


variable_types:
from
char *

variable_types:
to
char *

variable_types: c char


variable_types:
n
unsigned long


original_code:
void sanitize_host(char *s)
{
 int c, l;
 int inside_ipv6_literal = 0;
 l = 0;
 if (s[0] == '[') {
  inside_ipv6_literal = 1;
 }
 while ((c = *s) != 0) {
  if (c == ':' && inside_ipv6_literal == 0) {
   *s = 0;
   break;
  }
  if (c == ']') {
   inside_ipv6_literal = 0;
  }
  *s++ = tolower(c);
  l = c;
 }
 if (l == '.')
  s[-1] = 0;
}

canonical_original_code:
void sanitize_host(char *s)
{
 int c; int l;
 int inside_ipv6_literal = 0;
 l = 0;
 if (s[0] == '[') {
  inside_ipv6_literal = 1;
 }
 while ((c = *s) != 0) {
  if (c == ':' && inside_ipv6_literal == 0) {
   *s = 0;
   break;
  }
  if (c == ']') {
   inside_ipv6_literal = 0;
  }
  *s++ = tolower(c);
  l = c;
 }
 if (l == '.')
  s[-1] = 0;
}

variable_types:
s
char *

variable_types: c int

variable_types: l int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
parserFile("data/config.txt", argv, envp);
return 0;
}

original_code:
int main(int argc, char **argv)
{
    parserFile("data/config.txt");
    return 0;
}

variable_types: argc int

variable_types:
argv
char **


calculateSize

decompiled_code:
char *__fastcall calculateSize(unsigned __int64 a1)
{
char *v1; // rax
const char *v2; // r8
unsigned __int64 v3; // rcx
char *v4; // r12
float v5; // xmm0_4
char *result; // rax
int i; // eax

v1 = (char *)malloc(0x14uLL);
v2 = (const char *)&unk_228;
v3 = 0x1000000000000000LL;
v4 = v1;
if ( a1 <= 0xFFFFFFFFFFFFFFFLL )
{
v3 = 0x4000000000000LL;
for ( i = 1; i != 7; ++i )
{
if ( a1 >= v3 )
{
v2 = (const char *)*(&sizes + i);
goto LABEL_2;
}
v3 >>= 10;
}
*(_WORD *)v4 = 48;
result = v4;
}
else
{
LABEL_2:
if ( a1 % v3 )
{
if ( (a1 & 0x8000000000000000LL) != 0LL )
v5 = (float)(int)(a1 & 1 | (a1 >> 1)) + (float)(int)(a1 & 1 | (a1 >> 1));
else
v5 = (float)(int)a1;
sprintf(v4, "%.1f %s", (float)(v5 / (float)(int)v3), v2);
result = v4;
}
else
{
sprintf(v4, "%lu %s", a1 / v3, v2);
result = v4;
}
}
return result;
}

canonical_decompiled_code:
char *__fastcall func0(unsigned __int64 a1)
{
char *v1; // rax
const char *v2; // r8
unsigned __int64 v3; // rcx
char *v4; // r12
float v5; // xmm0_4
char *result; // rax
int i; // eax

v1 = (char *)malloc(0x14uLL);
v2 = (const char *)&unk_228;
v3 = 0x1000000000000000LL;
v4 = v1;
if ( a1 <= 0xFFFFFFFFFFFFFFFLL )
{
v3 = 0x4000000000000LL;
for ( i = 1; i != 7; ++i )
{
if ( a1 >= v3 )
{
v2 = (const char *)*(&sizes + i);
goto LABEL_2;
}
v3 >>= 10;
}
*(_WORD *)v4 = 48;
result = v4;
}
else
{
LABEL_2:
if ( a1 % v3 )
{
if ( (a1 & 0x8000000000000000LL) != 0LL )
v5 = (float)(int)(a1 & 1 | (a1 >> 1)) + (float)(int)(a1 & 1 | (a1 >> 1));
else
v5 = (float)(int)a1;
sprintf(v4, "%.1f %s", (float)(v5 / (float)(int)v3), v2);
result = v4;
}
else
{
sprintf(v4, "%lu %s", a1 / v3, v2);
result = v4;
}
}
return result;
}

original_code:
char * calculateSize(uint64_t size)
{
    char* result = (char *) malloc(sizeof(char) * 20);
    uint64_t multiplier = exbibytes;
    int i;
    for (i = 0; i < (sizeof(sizes)/sizeof(*(sizes))); i++, multiplier /= 1024)
    {
        if (size < multiplier)
            continue;
        if (size % multiplier == 0)
            sprintf(result, "%" "l" "u" " %s", size / multiplier, sizes[i]);
        else
            sprintf(result, "%.1f %s", (float) size / multiplier, sizes[i]);
        return result;
    }
    strcpy(result, "0");
    return result;
}

canonical_original_code:
char *calculateSize(unsigned long size)
{
    char *result = (char *) malloc(sizeof(char) * 20);
    unsigned long multiplier = exbibytes;
    int i;
    for (i = 0; i < (sizeof(sizes)/sizeof(*(sizes))); i++, multiplier /= 1024)
    {
        if (size < multiplier)
            continue;
        if (size % multiplier == 0)
            sprintf(result, "%" "l" "u" " %s", size / multiplier, sizes[i]);
        else
            sprintf(result, "%.1f %s", (float) size / multiplier, sizes[i]);
        return result;
    }
    strcpy(result, "0");
    return result;
}

variable_types:
size
unsigned long

variable_types:
result
char *

variable_types:
multiplier
unsigned long

variable_types: i int

return_type: char *


usage

decompiled_code:
int usage()
{
puts("USAGE:");
puts("\t-f<filename>");
puts("\t-p<portname>");
puts("\t-s<blockFileSize>");
puts("\t-r<maxRetransmissions>");
puts("\t-t<timeoutTime>");
puts("\t-b<baudrate>");
puts("\t-d (debug mode ON)");
return puts("\t-w<wrongBCC2rate>");
}

canonical_decompiled_code:
int func1()
{
puts("USAGE:");
puts("\t-f<filename>");
puts("\t-p<portname>");
puts("\t-s<blockFileSize>");
puts("\t-r<maxRetransmissions>");
puts("\t-t<timeoutTime>");
puts("\t-b<baudrate>");
puts("\t-d (debug mode ON)");
return puts("\t-w<wrongBCC2rate>");
}

original_code:
void usage() {
    printf("USAGE:\n");
    printf("\t-f<filename>\n");
    printf("\t-p<portname>\n");
    printf("\t-s<blockFileSize>\n");
    printf("\t-r<maxRetransmissions>\n");
    printf("\t-t<timeoutTime>\n");
    printf("\t-b<baudrate>\n");
    printf("\t-d (debug mode ON)\n");
    printf("\t-w<wrongBCC2rate>\n");
}


repo: miguelvps/c

decompiled_code:
__int64 __fastcall match_compare(const void *a1, const void *a2)
{
return (*(double *)(*(_QWORD *)a1 + 8LL) > *(double *)(*(_QWORD *)a2 + 8LL))
- (unsigned int)(*(double *)(*(_QWORD *)a2 + 8LL) > *(double *)(*(_QWORD *)a1 + 8LL));
}

canonical_decompiled_code:
__int64 __fastcall func0(const void *a1, const void *a2)
{
return (*(double *)(*(_QWORD *)a1 + 8LL) > *(double *)(*(_QWORD *)a2 + 8LL))
- (unsigned int)(*(double *)(*(_QWORD *)a2 + 8LL) > *(double *)(*(_QWORD *)a1 + 8LL));
}

original_code:
int match_compare(const void *a, const void *b) {
    struct match **m1 = (struct match **)a;
    struct match **m2 = (struct match **)b;
    return ((*m1)->score > (*m2)->score) - ((*m1)->score < (*m2)->score);
}

canonical_original_code:
int match_compare(void *a, void *b) {
    struct match **m1 = (struct match **)a;
    struct match **m2 = (struct match **)b;
    return ((*m1)->score > (*m2)->score) - ((*m1)->score < (*m2)->score);
}

variable_types:
a
void *

variable_types:
b
void *

variable_types: struct match { char *dir; double score; } **


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

result = s_malloc(16LL);
*(_QWORD *)result = a1;
*(double *)(result + 8) = a2;
return result;
}

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

result = s_malloc(16LL);
*(_QWORD *)result = a1;
*(double *)(result + 8) = a2;
return result;
}

original_code:
struct match *match_new(char *dir, double score) {
    struct match *match = s_malloc(sizeof(*match));
    match->dir = dir;
    match->score = score;
    return match;
}

variable_types:
dir
char *

variable_types: score double

variable_types: struct match { char *dir; double score; } *


decompiled_code:
void __fastcall match_free(void *ptr)
{
free(*(void **)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
free(*(void **)ptr);
free(ptr);
}

original_code:
void match_free(struct match *match) {
    free(match->dir);
    free(match);
}

user_defined_types: struct match { char *dir; double score; }


complete

decompiled_code:
void __fastcall complete(char *src)
{
int v1; // eax
int v2; // ebx
char *v3; // r14
char *v4; // rbp
char *v5; // rax
char *v6; // r13
_QWORD *v7; // rbp
__int64 v8; // rbx
const char **v9; // rax
int v10; // eax
__int64 v11; // rbx
void *v12; // rdi
__int64 v13; // rbx
char **v14; // rax
struct stat v15; // [rsp+0h] [rbp-B8h] BYREF

v1 = strlen(src);
if ( !v1 )
{
print_dir_complete((char *)&s, &s, 0);
return;
}
v2 = v1;
v3 = (char *)s_malloc(v1 + 1);
strcpy(v3, src);
v4 = v3;
v5 = strrchr(v3, 47);
v6 = v5;
if ( !v5 )
{
if ( (unsigned int)print_dir_complete((char *)&s, v3, 0) )
return;
LABEL_7:
free(v3);
v7 = aprox_path_match(src);
qsort((void *)*v7, *((int *)v7 + 2), 8uLL, (__compar_fn_t)match_compare);
if ( src[v2 - 1] == 47 )
{
if ( *((int *)v7 + 2) > 0 )
{
v13 = 0LL;
do
{
v14 = *(char ***)(*v7 + 8 * v13++);
print_dir_complete(*v14, &s, 1);
v10 = *((_DWORD *)v7 + 2);
}
while ( v10 > (int)v13 );
LABEL_10:
if ( v10 > 0 )
{
v11 = 0LL;
do
{
v12 = *(void **)(*v7 + 8 * v11++);
match_free(v12);
}
while ( *((_DWORD *)v7 + 2) > (int)v11 );
}
goto LABEL_13;
}
}
else
{
v8 = 0LL;
if ( *((int *)v7 + 2) > 0 )
{
do
{
v9 = *(const char ***)(*v7 + 8 * v8++);
puts(*v9);
v10 = *((_DWORD *)v7 + 2);
}
while ( v10 > (int)v8 );
goto LABEL_10;
}
}
LABEL_13:
free((void *)*v7);
free(v7);
return;
}
*v5 = 0;
if ( v5 == v3 )
v4 = "/";
if ( stat(v4, &v15) || (v15.st_mode & 0xF000) != 0x4000 || !(unsigned int)print_dir_complete(v4, v6 + 1, 1) )
goto LABEL_7;
}

canonical_decompiled_code:
void __fastcall func5(char *src)
{
int v1; // eax
int v2; // ebx
char *v3; // r14
char *v4; // rbp
char *v5; // rax
char *v6; // r13
_QWORD *v7; // rbp
__int64 v8; // rbx
const char **v9; // rax
int v10; // eax
__int64 v11; // rbx
void *v12; // rdi
__int64 v13; // rbx
char **v14; // rax
struct stat v15; // [rsp+0h] [rbp-B8h] BYREF

v1 = strlen(src);
if ( !v1 )
{
func4((char *)&s, &s, 0);
return;
}
v2 = v1;
v3 = (char *)s_malloc(v1 + 1);
strcpy(v3, src);
v4 = v3;
v5 = strrchr(v3, 47);
v6 = v5;
if ( !v5 )
{
if ( (unsigned int)func4((char *)&s, v3, 0) )
return;
LABEL_7:
free(v3);
v7 = aprox_path_match(src);
qsort((void *)*v7, *((int *)v7 + 2), 8uLL, (__compar_fn_t)match_compare);
if ( src[v2 - 1] == 47 )
{
if ( *((int *)v7 + 2) > 0 )
{
v13 = 0LL;
do
{
v14 = *(char ***)(*v7 + 8 * v13++);
func4(*v14, &s, 1);
v10 = *((_DWORD *)v7 + 2);
}
while ( v10 > (int)v13 );
LABEL_10:
if ( v10 > 0 )
{
v11 = 0LL;
do
{
v12 = *(void **)(*v7 + 8 * v11++);
func2(v12);
}
while ( *((_DWORD *)v7 + 2) > (int)v11 );
}
goto LABEL_13;
}
}
else
{
v8 = 0LL;
if ( *((int *)v7 + 2) > 0 )
{
do
{
v9 = *(const char ***)(*v7 + 8 * v8++);
puts(*v9);
v10 = *((_DWORD *)v7 + 2);
}
while ( v10 > (int)v8 );
goto LABEL_10;
}
}
LABEL_13:
free((void *)*v7);
free(v7);
return;
}
*v5 = 0;
if ( v5 == v3 )
v4 = "/";
if ( stat(v4, &v15) || (v15.st_mode & 0xF000) != 0x4000 || !(unsigned int)func4(v4, v6 + 1, 1) )
goto LABEL_7;
}

original_code:
void complete(const char *path) {
    int i, path_len;
    char *p, *c, *dname;
    struct stat buf;
    struct darray_match *matches;
    path_len = strlen(path);
    if (path_len == 0) {
        print_dir_complete("", "", 0);
        return;
    }
    p = c = s_malloc((path_len + 1) * sizeof(*p));
    p = strcpy(p, path);
    dname = strrchr(p, '/');
    if (dname == ((void *)0)) {
        if (print_dir_complete("", p, 0))
            return;
    }
    else {
        if (dname == p)
            p = "/";
        dname[0] = '\0';
        dname++;
        if (stat(p, &buf) == 0 && ((((buf.st_mode)) & 0170000) == (0040000))) {
            if (print_dir_complete(p, dname, 1))
                return;
        }
    }
    free(c);
    matches = aprox_path_match(path);
    qsort(matches->items, matches->size, sizeof(*matches->items),
          match_compare);
    if (path[path_len - 1] == '/')
        for (i = 0; i < matches->size; i++)
            print_dir_complete(matches->items[i]->dir, "", 1);
    else
        for (i = 0; i < matches->size; i++)
            printf("%s\n", matches->items[i]->dir);
    do { for (i=0; i<(matches)->size; i++) match_free((matches)->items[i]); free((matches)->items); } while (0);
    free(matches);
}

canonical_original_code:
void complete(char *path) {
    int i; int path_len;
    char *p; char *c; char *dname;
    struct stat buf;
    struct darray_match *matches;
    path_len = strlen(path);
    if (path_len == 0) {
        print_dir_complete("", "", 0);
        return;
    }
    p = c = s_malloc((path_len + 1) * sizeof(*p));
    p = strcpy(p, path);
    dname = strrchr(p, '/');
    if (dname == ((void *)0)) {
        if (print_dir_complete("", p, 0))
            return;
    }
    else {
        if (dname == p)
            p = "/";
        dname[0] = '\0';
        dname++;
        if (stat(p, &buf) == 0 && ((((buf.st_mode)) & 0170000) == (0040000))) {
            if (print_dir_complete(p, dname, 1))
                return;
        }
    }
    free(c);
    matches = aprox_path_match(path);
    qsort(matches->items, matches->size, sizeof(*matches->items),
          match_compare);
    if (path[path_len - 1] == '/')
        for (i = 0; i < matches->size; i++)
            print_dir_complete(matches->items[i]->dir, "", 1);
    else
        for (i = 0; i < matches->size; i++)
            printf("%s\n", matches->items[i]->dir);
    do { for (i=0; i<(matches)->size; i++) match_free((matches)->items[i]); free((matches)->items); } while (0);
    free(matches);
}

variable_types:
path
char *

variable_types:
p
char *

variable_types:
c
char *

variable_types:
dname
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 darray_match { struct match { char *dir; double score; } **items; int size; int alloc; } *

user_defined_types: struct darray_match { struct match **items; int size; int alloc; }