/* This file was generated by the Hex-Rays decompiler version 8.3.0.230608.
   Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>

   Detected compiler: GNU C++
*/

#include <defs.h>


//-------------------------------------------------------------------------
// Function declarations

__int64 (**init_proc())(void);
void sub_16B0();
// __int64 __fastcall ssh_set_channel_callbacks(_QWORD, _QWORD); weak
// __int64 __fastcall ssh_bind_accept(_QWORD, _QWORD); weak
// __int64 ssh_event_new(void); weak
// __int64 __fastcall ssh_channel_send_eof(_QWORD); weak
// int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
// ssize_t write(int fd, const void *buf, size_t n);
// __int64 __fastcall ssh_disconnect(_QWORD); weak
// __int64 __fastcall ssh_set_server_callbacks(_QWORD, _QWORD); weak
// __int64 __fastcall ssh_get_status(_QWORD); weak
// __int64 ssh_bind_new(void); weak
// int dup2(int fd, int fd2);
// void argp_usage(const struct argp_state *state);
// __int64 __fastcall ssh_channel_request_send_exit_status(_QWORD, _QWORD); weak
// __int64 ssh_new(void); weak
// int ioctl(int fd, unsigned __int64 request, ...);
// int close(int fd);
// __int64 __fastcall ssh_bind_free(_QWORD); weak
// int pipe(int pipedes[2]);
// __int64 __fastcall ssh_event_add_session(_QWORD, _QWORD); weak
// error_t argp_parse(const struct argp *argp, int argc, char **argv, unsigned int flags, int *arg_index, void *input);
// __int64 __fastcall ssh_event_add_fd(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD); weak
// int strcmp(const char *s1, const char *s2);
// int fprintf(FILE *stream, const char *format, ...);
// __int64 __fastcall ssh_channel_is_open(_QWORD); weak
// int sigemptyset(sigset_t *set);
// int kill(__pid_t pid, int sig);
// int openpty(int *amaster, int *aslave, char *name, const struct termios *termp, const struct winsize *winp);
// __int64 __fastcall ssh_channel_close(_QWORD); weak
// __int64 __fastcall ssh_bind_listen(_QWORD); weak
// __int64 __fastcall ssh_channel_new(_QWORD); weak
// int login_tty(int fd);
// __int64 __fastcall ssh_event_dopoll(_QWORD, _QWORD); weak
// __int64 __fastcall ssh_get_error(_QWORD); weak
// __int64 __fastcall ssh_event_free(_QWORD); weak
// __pid_t waitpid(__pid_t pid, int *stat_loc, int options);
// __int64 __fastcall ssh_free(_QWORD); weak
// __int64 __fastcall ssh_bind_options_set(_QWORD, _QWORD, _QWORD); weak
// __int64 __fastcall ssh_set_auth_methods(_QWORD, _QWORD); weak
// __int64 __fastcall ssh_event_remove_fd(_QWORD, _QWORD); weak
// __int64 __fastcall ssh_handle_key_exchange(_QWORD); weak
// __int64 ssh_init(void); weak
// void __noreturn exit(int status);
// size_t fwrite(const void *ptr, size_t size, size_t n, FILE *s);
// int execl(const char *path, const char *arg, ...);
// __pid_t fork(void);
// int __fastcall _cxa_finalize(void *);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
__int64 (**deregister_tm_clones())(void);
__int64 register_tm_clones(void); // weak
__int64 (**_do_global_dtors_aux())(void);
__int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD); // weak
__int64 __fastcall set_default_keys(__int64 a1, int a2, int a3, int a4);
__int64 __fastcall parse_opt(int a1, __int64 a2, const struct argp_state *a3);
ssize_t __fastcall data_function(__int64 a1, __int64 a2, const void *a3, unsigned int a4, __int64 a5, __pid_t *a6);
__int64 __fastcall pty_request(__int64 a1, __int64 a2, __int64 a3, __int16 a4, __int16 a5, __int16 a6, __int16 a7, __int64 a8);
int __fastcall pty_resize(__int64 a1, __int64 a2, __int16 a3, __int16 a4, __int16 a5, __int16 a6, __int64 a7);
__int64 __fastcall exec_pty(__int64 a1, __int64 a2, __pid_t *a3);
__int64 __fastcall exec_nopty(__int64 a1, __pid_t *a2);
__int64 __fastcall exec_request(__int64 a1, __int64 a2, __int64 a3, __pid_t *a4);
__int64 __fastcall shell_request(__int64 a1, __int64 a2, __pid_t *a3);
__int64 __fastcall subsystem_request(__int64 a1, __int64 a2, const char *a3, __pid_t *a4);
__int64 __fastcall auth_password(__int64 a1, const char *a2, const char *a3, __int64 a4);
__int64 __fastcall channel_open(__int64 a1, __int64 a2);
__int64 __fastcall process_stdout(); // weak
__int64 __fastcall process_stderr(); // weak
int __fastcall handle_session(__int64 a1, __int64 a2);
__pid_t sigchld_handler();
int __fastcall main(int argc, const char **argv, const char **envp);
void _libc_csu_fini(void); // idb
void term_proc();
// int __fastcall _libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// int __fastcall __cxa_finalize(void *);
// __int64 ITM_deregisterTMCloneTable(void); weak
// __int64 _gmon_start__(void); weak
// __int64 Jv_RegisterClasses(void); weak

//-------------------------------------------------------------------------
// Data declarations

_UNKNOWN _libc_csu_init;
__int64 (__fastcall *_frame_dummy_init_array_entry[2])() = { &frame_dummy, &_do_global_dtors_aux }; // weak
__int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)() = &_do_global_dtors_aux; // weak
_UNKNOWN _JCR_LIST__; // weak
void *_dso_handle = &_dso_handle; // idb
struct argp argp =
{
  &options,
  &parse_opt,
  "BINDADDR",
  "libssh -- a Secure Shell protocol implementation",
  &dword_0,
  &dword_0,
  &dword_0
}; // idb
char _bss_start; // weak
int no_default_keys_6547; // weak
int dsa_already_set_6549; // weak
int rsa_already_set_6548; // weak
int ecdsa_already_set_6550; // weak
// extern struct _IO_FILE *stderr;


//----- (0000000000001698) ----------------------------------------------------
__int64 (**init_proc())(void)
{
  __int64 (**result)(void); // rax

  result = &_gmon_start__;
  if ( &_gmon_start__ )
    return (__int64 (**)(void))_gmon_start__();
  return result;
}
// 2045C0: using guessed type __int64 _gmon_start__(void);

//----- (00000000000016B0) ----------------------------------------------------
void sub_16B0()
{
  JUMPOUT(0LL);
}
// 16B6: control flows out of bounds to 0

//----- (00000000000019E0) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
  __int64 v3; // rax
  int v4; // esi
  __int64 v5; // [rsp-8h] [rbp-8h] BYREF
  char *retaddr; // [rsp+0h] [rbp+0h] BYREF

  v4 = v5;
  v5 = v3;
  _libc_start_main(
    (int (__fastcall *)(int, char **, char **))main,
    v4,
    &retaddr,
    (void (*)(void))_libc_csu_init,
    _libc_csu_fini,
    a3,
    &v5);
  __halt();
}
// 19E6: positive sp value 8 has been found
// 19ED: variable 'v3' is possibly undefined

//----- (0000000000001A10) ----------------------------------------------------
__int64 (**deregister_tm_clones())(void)
{
  __int64 (**result)(void); // rax

  result = (__int64 (**)(void))((char *)&no_default_keys_6547 + 3 - &_bss_start);
  if ( (unsigned __int64)((char *)&no_default_keys_6547 + 3 - &_bss_start) > 0xE )
  {
    result = &ITM_deregisterTMCloneTable;
    if ( &ITM_deregisterTMCloneTable )
      return (__int64 (**)(void))ITM_deregisterTMCloneTable();
  }
  return result;
}
// 2043F8: using guessed type char _bss_start;
// 2043FC: using guessed type int no_default_keys_6547;
// 2045B8: using guessed type __int64 ITM_deregisterTMCloneTable(void);

//----- (0000000000001A50) ----------------------------------------------------
__int64 register_tm_clones()
{
  return 0LL;
}
// 1A50: using guessed type __int64 register_tm_clones();

//----- (0000000000001AA0) ----------------------------------------------------
__int64 (**_do_global_dtors_aux())(void)
{
  __int64 (**result)(void); // rax

  if ( !_bss_start )
  {
    if ( &__cxa_finalize )
      _cxa_finalize(_dso_handle);
    result = deregister_tm_clones();
    _bss_start = 1;
  }
  return result;
}
// 2043F8: using guessed type char _bss_start;

//----- (0000000000001AE0) ----------------------------------------------------
__int64 frame_dummy()
{
  if ( _JCR_LIST__ && &Jv_RegisterClasses )
    Jv_RegisterClasses();
  return register_tm_clones();
}
// 1A50: using guessed type __int64 register_tm_clones(void);
// 1AE0: using guessed type __int64 frame_dummy();
// 2045C8: using guessed type __int64 Jv_RegisterClasses(void);

//----- (0000000000001B10) ----------------------------------------------------
__int64 __fastcall set_default_keys(__int64 a1, int a2, int a3, int a4)
{
  __int64 result; // rax

  if ( !a2 )
    result = ssh_bind_options_set(a1, 5LL, "/etc/ssh/ssh_host_rsa_key");
  if ( !a3 )
    result = ssh_bind_options_set(a1, 4LL, "/etc/ssh/ssh_host_dsa_key");
  if ( !a4 )
    return ssh_bind_options_set(a1, 9LL, "/etc/ssh/ssh_host_ecdsa_key");
  return result;
}
// 1940: using guessed type __int64 __fastcall ssh_bind_options_set(_QWORD, _QWORD, _QWORD);

//----- (0000000000001B82) ----------------------------------------------------
__int64 __fastcall parse_opt(int a1, __int64 a2, const struct argp_state *a3)
{
  __int64 input; // [rsp+28h] [rbp-8h]

  input = (__int64)a3->input;
  if ( a1 == 110 )
  {
    no_default_keys_6547 = 1;
  }
  else if ( a1 > 110 )
  {
    if ( a1 == 114 )
    {
      ssh_bind_options_set(input, 5LL, a2);
      rsa_already_set_6548 = 1;
    }
    else if ( a1 > 114 )
    {
      if ( a1 == 118 )
      {
        ssh_bind_options_set(input, 8LL, "3");
      }
      else
      {
        if ( a1 != 16777217 )
          return 7LL;
        if ( !a3->arg_num )
          argp_usage(a3);
        if ( !no_default_keys_6547 )
          set_default_keys(input, rsa_already_set_6548, dsa_already_set_6549, ecdsa_already_set_6550);
      }
    }
    else
    {
      if ( a1 != 112 )
        return 7LL;
      ssh_bind_options_set(input, 2LL, a2);
    }
  }
  else if ( a1 == 100 )
  {
    ssh_bind_options_set(input, 4LL, a2);
    dsa_already_set_6549 = 1;
  }
  else if ( a1 > 100 )
  {
    if ( a1 == 101 )
    {
      ssh_bind_options_set(input, 9LL, a2);
      ecdsa_already_set_6550 = 1;
    }
    else
    {
      if ( a1 != 107 )
        return 7LL;
      ssh_bind_options_set(input, 3LL, a2);
      no_default_keys_6547 = 1;
    }
  }
  else
  {
    if ( a1 )
      return 7LL;
    if ( a3->arg_num )
      argp_usage(a3);
    ssh_bind_options_set(input, 0LL, a2);
  }
  return 0LL;
}
// 1940: using guessed type __int64 __fastcall ssh_bind_options_set(_QWORD, _QWORD, _QWORD);
// 2043FC: using guessed type int no_default_keys_6547;
// 204400: using guessed type int dsa_already_set_6549;
// 204404: using guessed type int rsa_already_set_6548;
// 204408: using guessed type int ecdsa_already_set_6550;

//----- (0000000000001D62) ----------------------------------------------------
ssize_t __fastcall data_function(__int64 a1, __int64 a2, const void *a3, unsigned int a4, __int64 a5, __pid_t *a6)
{
  if ( a4 && *a6 > 0 && kill(*a6, 0) >= 0 )
    return write(a6[3], a3, a4);
  else
    return 0LL;
}

//----- (0000000000001DD0) ----------------------------------------------------
__int64 __fastcall pty_request(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int16 a4,
        __int16 a5,
        __int16 a6,
        __int16 a7,
        __int64 a8)
{
  **(_WORD **)(a8 + 32) = a5;
  *(_WORD *)(*(_QWORD *)(a8 + 32) + 2LL) = a4;
  *(_WORD *)(*(_QWORD *)(a8 + 32) + 4LL) = a7;
  *(_WORD *)(*(_QWORD *)(a8 + 32) + 6LL) = a6;
  if ( !openpty((int *)(a8 + 4), (int *)(a8 + 8), 0LL, 0LL, *(const struct winsize **)(a8 + 32)) )
    return 0LL;
  fwrite("Failed to open pty\n", 1uLL, 0x13uLL, stderr);
  return 0xFFFFFFFFLL;
}

//----- (0000000000001E94) ----------------------------------------------------
int __fastcall pty_resize(__int64 a1, __int64 a2, __int16 a3, __int16 a4, __int16 a5, __int16 a6, __int64 a7)
{
  **(_WORD **)(a7 + 32) = a4;
  *(_WORD *)(*(_QWORD *)(a7 + 32) + 2LL) = a3;
  *(_WORD *)(*(_QWORD *)(a7 + 32) + 4LL) = a6;
  *(_WORD *)(*(_QWORD *)(a7 + 32) + 6LL) = a5;
  if ( *(_DWORD *)(a7 + 4) == -1 )
    return -1;
  else
    return ioctl(*(_DWORD *)(a7 + 4), 0x5414uLL, *(_QWORD *)(a7 + 32));
}

//----- (0000000000001F2A) ----------------------------------------------------
__int64 __fastcall exec_pty(__int64 a1, __int64 a2, __pid_t *a3)
{
  *a3 = fork();
  if ( *a3 == -1 )
  {
    close(a3[1]);
    close(a3[2]);
    fwrite("Failed to fork\n", 1uLL, 0xFuLL, stderr);
    return 0xFFFFFFFFLL;
  }
  else
  {
    if ( !*a3 )
    {
      close(a3[1]);
      if ( login_tty(a3[2]) )
        exit(1);
      execl("/bin/sh", "sh", a1, a2, 0LL);
      exit(0);
    }
    close(a3[2]);
    a3[3] = a3[1];
    a3[4] = a3[3];
    return 0LL;
  }
}

//----- (0000000000002039) ----------------------------------------------------
__int64 __fastcall exec_nopty(__int64 a1, __pid_t *a2)
{
  int pipedes[2]; // [rsp+18h] [rbp-18h] BYREF
  int v4[2]; // [rsp+20h] [rbp-10h] BYREF
  int v5[2]; // [rsp+28h] [rbp-8h] BYREF

  if ( pipe(pipedes) )
    return 0xFFFFFFFFLL;
  if ( pipe(v4) )
  {
LABEL_10:
    close(pipedes[0]);
    close(pipedes[1]);
    return 0xFFFFFFFFLL;
  }
  if ( pipe(v5) )
  {
LABEL_9:
    close(v4[0]);
    close(v4[1]);
    goto LABEL_10;
  }
  *a2 = fork();
  if ( *a2 == -1 )
  {
    close(v5[0]);
    close(v5[1]);
    goto LABEL_9;
  }
  if ( !*a2 )
  {
    close(pipedes[1]);
    close(v4[0]);
    close(v5[0]);
    dup2(pipedes[0], 0);
    dup2(v4[1], 1);
    dup2(v5[1], 2);
    close(pipedes[0]);
    close(v4[1]);
    close(v5[1]);
    execl("/bin/sh", "sh", "-c", a1, 0LL);
    exit(0);
  }
  close(pipedes[0]);
  close(v4[1]);
  close(v5[1]);
  a2[3] = pipedes[1];
  a2[4] = v4[0];
  a2[5] = v5[0];
  return 0LL;
}

//----- (00000000000021D8) ----------------------------------------------------
__int64 __fastcall exec_request(__int64 a1, __int64 a2, __int64 a3, __pid_t *a4)
{
  if ( *a4 > 0 )
    return 0xFFFFFFFFLL;
  if ( a4[1] == -1 || a4[2] == -1 )
    return exec_nopty(a3, a4);
  return exec_pty((__int64)"-c", a3, a4);
}

//----- (000000000000224F) ----------------------------------------------------
__int64 __fastcall shell_request(__int64 a1, __int64 a2, __pid_t *a3)
{
  if ( *a3 > 0 )
    return 0xFFFFFFFFLL;
  if ( a3[1] == -1 || a3[2] == -1 )
    return 0LL;
  return exec_pty((__int64)"-l", 0LL, a3);
}

//----- (00000000000022B5) ----------------------------------------------------
__int64 __fastcall subsystem_request(__int64 a1, __int64 a2, const char *a3, __pid_t *a4)
{
  if ( !strcmp(a3, "sftp") )
    return exec_request(a1, a2, (__int64)"/usr/lib/sftp-server", a4);
  else
    return 0xFFFFFFFFLL;
}

//----- (000000000000230B) ----------------------------------------------------
__int64 __fastcall auth_password(__int64 a1, const char *a2, const char *a3, __int64 a4)
{
  if ( !strcmp(a2, "myuser") && !strcmp(a3, "mypassword") )
  {
    *(_DWORD *)(a4 + 12) = 1;
    return 0LL;
  }
  else
  {
    ++*(_DWORD *)(a4 + 8);
    return 1LL;
  }
}

//----- (0000000000002383) ----------------------------------------------------
__int64 __fastcall channel_open(__int64 a1, __int64 a2)
{
  *(_QWORD *)a2 = ssh_channel_new(a1);
  return *(_QWORD *)a2;
}
// 18D0: using guessed type __int64 __fastcall ssh_channel_new(_QWORD);

//----- (00000000000023BA) ----------------------------------------------------
#error "23BA: stack frame is too big (funcsize=0)"

//----- (000000000000247C) ----------------------------------------------------
#error "247C: stack frame is too big (funcsize=0)"

//----- (000000000000253E) ----------------------------------------------------
int __fastcall handle_session(__int64 a1, __int64 a2)
{
  const char *error; // rax
  __int64 v3; // rax
  int stat_loc; // [rsp+10h] [rbp-140h] BYREF
  int i; // [rsp+14h] [rbp-13Ch]
  __int16 v7[4]; // [rsp+18h] [rbp-138h] BYREF
  __int64 v8; // [rsp+20h] [rbp-130h] BYREF
  int v9; // [rsp+28h] [rbp-128h]
  int v10; // [rsp+2Ch] [rbp-124h]
  __pid_t pid; // [rsp+30h] [rbp-120h] BYREF
  int fd; // [rsp+34h] [rbp-11Ch]
  int v13; // [rsp+38h] [rbp-118h]
  int v14; // [rsp+3Ch] [rbp-114h]
  int v15; // [rsp+40h] [rbp-110h]
  int v16; // [rsp+44h] [rbp-10Ch]
  __int64 v17; // [rsp+48h] [rbp-108h]
  __int16 *v18; // [rsp+50h] [rbp-100h]
  __int64 v19[12]; // [rsp+60h] [rbp-F0h] BYREF
  __int64 v20[18]; // [rsp+C0h] [rbp-90h] BYREF

  v7[0] = 0;
  v7[1] = 0;
  v7[2] = 0;
  v7[3] = 0;
  pid = 0;
  fd = -1;
  v13 = -1;
  v14 = -1;
  v15 = -1;
  v16 = -1;
  v17 = 0LL;
  v18 = v7;
  v8 = 0LL;
  v9 = 0;
  v10 = 0;
  memset(v20, 0, 0x88uLL);
  v20[1] = (__int64)&pid;
  v20[2] = (__int64)data_function;
  v20[8] = (__int64)pty_request;
  v20[9] = (__int64)shell_request;
  v20[12] = (__int64)pty_resize;
  v20[13] = (__int64)exec_request;
  v20[15] = (__int64)subsystem_request;
  memset(v19, 0, 0x58uLL);
  v19[1] = (__int64)&v8;
  v19[2] = (__int64)auth_password;
  v19[7] = (__int64)channel_open;
  v19[0] = 88LL;
  v20[0] = 136LL;
  ssh_set_server_callbacks(a2, v19);
  if ( (unsigned int)ssh_handle_key_exchange(a2) )
  {
LABEL_2:
    error = (const char *)ssh_get_error(a2);
    LODWORD(v3) = fprintf(stderr, "%s\n", error);
  }
  else
  {
    ssh_set_auth_methods(a2, 2LL);
    ssh_event_add_session(a1, a2);
    i = 0;
    while ( !v8 )
    {
      LODWORD(v3) = v9;
      if ( v9 > 2 || i > 99 )
        return v3;
      if ( (unsigned int)ssh_event_dopoll(a1, 100LL) == -1 )
        goto LABEL_2;
      ++i;
    }
    ssh_set_channel_callbacks(v8, v20);
    do
    {
      if ( (unsigned int)ssh_event_dopoll(a1, 0xFFFFFFFFLL) == -1 )
        ssh_channel_close(v8);
      if ( !v17 && pid )
      {
        v17 = a1;
        if ( v15 != -1 && (unsigned int)ssh_event_add_fd(a1, (unsigned int)v15, 1LL, process_stdout, v8) )
        {
          fwrite("Failed to register stdout to poll context\n", 1uLL, 0x2AuLL, stderr);
          ssh_channel_close(v8);
        }
        if ( v16 != -1 && (unsigned int)ssh_event_add_fd(a1, (unsigned int)v16, 1LL, process_stderr, v8) )
        {
          fwrite("Failed to register stderr to poll context\n", 1uLL, 0x2AuLL, stderr);
          ssh_channel_close(v8);
        }
      }
    }
    while ( (unsigned int)ssh_channel_is_open(v8) && (!pid || !waitpid(pid, &stat_loc, 1)) );
    close(fd);
    close(v14);
    close(v15);
    close(v16);
    ssh_event_remove_fd(a1, (unsigned int)v15);
    ssh_event_remove_fd(a1, (unsigned int)v16);
    if ( kill(pid, 0) >= 0 || (stat_loc & 0x7F) != 0 )
    {
      if ( pid > 0 )
        kill(pid, 9);
    }
    else
    {
      stat_loc = BYTE1(stat_loc);
      ssh_channel_request_send_exit_status(v8, (unsigned int)stat_loc);
    }
    ssh_channel_send_eof(v8);
    LODWORD(v3) = ssh_channel_close(v8);
    for ( i = 0; i <= 49; ++i )
    {
      v3 = ssh_get_status(a2) & 5;
      if ( (_DWORD)v3 )
        break;
      LODWORD(v3) = ssh_event_dopoll(a1, 100LL);
    }
  }
  return v3;
}
// 16C0: using guessed type __int64 __fastcall ssh_set_channel_callbacks(_QWORD, _QWORD);
// 16F0: using guessed type __int64 __fastcall ssh_channel_send_eof(_QWORD);
// 1740: using guessed type __int64 __fastcall ssh_set_server_callbacks(_QWORD, _QWORD);
// 1750: using guessed type __int64 __fastcall ssh_get_status(_QWORD);
// 17A0: using guessed type __int64 __fastcall ssh_channel_request_send_exit_status(_QWORD, _QWORD);
// 1810: using guessed type __int64 __fastcall ssh_event_add_session(_QWORD, _QWORD);
// 1840: using guessed type __int64 __fastcall ssh_event_add_fd(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD);
// 1870: using guessed type __int64 __fastcall ssh_channel_is_open(_QWORD);
// 18B0: using guessed type __int64 __fastcall ssh_channel_close(_QWORD);
// 18F0: using guessed type __int64 __fastcall ssh_event_dopoll(_QWORD, _QWORD);
// 1900: using guessed type __int64 __fastcall ssh_get_error(_QWORD);
// 1950: using guessed type __int64 __fastcall ssh_set_auth_methods(_QWORD, _QWORD);
// 1960: using guessed type __int64 __fastcall ssh_event_remove_fd(_QWORD, _QWORD);
// 1970: using guessed type __int64 __fastcall ssh_handle_key_exchange(_QWORD);
// 23BA: using guessed type __int64 __fastcall process_stdout();
// 247C: using guessed type __int64 __fastcall process_stderr();

//----- (0000000000002A86) ----------------------------------------------------
__pid_t sigchld_handler()
{
  __pid_t result; // eax

  do
    result = waitpid(-1, 0LL, 1);
  while ( result > 0 );
  return result;
}

//----- (0000000000002AAD) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{
  const char *v4; // rax
  __pid_t v5; // eax
  const char *error; // rax
  void *input; // [rsp+18h] [rbp-B8h]
  __int64 v8; // [rsp+20h] [rbp-B0h]
  __int64 v9; // [rsp+28h] [rbp-A8h]
  struct sigaction v10; // [rsp+30h] [rbp-A0h] BYREF

  v10.sa_handler = (__sighandler_t)sigchld_handler;
  sigemptyset(&v10.sa_mask);
  v10.sa_flags = 268435457;
  if ( sigaction(17, &v10, 0LL) )
  {
    fwrite("Failed to register SIGCHLD handler\n", 1uLL, 0x23uLL, stderr);
    return 1;
  }
  else if ( (int)ssh_init() >= 0 )
  {
    input = (void *)ssh_bind_new();
    if ( input )
    {
      argp_parse(&argp, argc, (char **)argv, 0, 0LL, input);
      if ( (int)ssh_bind_listen(input) >= 0 )
      {
        while ( 1 )
        {
          while ( 1 )
          {
            v8 = ssh_new();
            if ( v8 )
              break;
            fwrite("Failed to allocate session\n", 1uLL, 0x1BuLL, stderr);
          }
          if ( (unsigned int)ssh_bind_accept(input, v8) == -1 )
          {
            error = (const char *)ssh_get_error(input);
            fprintf(stderr, "%s\n", error);
          }
          else
          {
            v5 = fork();
            if ( v5 == -1 )
            {
              fwrite("Failed to fork\n", 1uLL, 0xFuLL, stderr);
            }
            else if ( !v5 )
            {
              v10.sa_handler = 0LL;
              sigaction(17, &v10, 0LL);
              ssh_bind_free(input);
              v9 = ssh_event_new();
              if ( v9 )
              {
                handle_session(v9, v8);
                ssh_event_free(v9);
              }
              else
              {
                fwrite("Could not create polling context\n", 1uLL, 0x21uLL, stderr);
              }
              ssh_disconnect(v8);
              ssh_free(v8);
              exit(0);
            }
          }
          ssh_disconnect(v8);
          ssh_free(v8);
        }
      }
      v4 = (const char *)ssh_get_error(input);
      fprintf(stderr, "%s\n", v4);
      return 1;
    }
    else
    {
      fwrite("ssh_bind_new failed\n", 1uLL, 0x14uLL, stderr);
      return 1;
    }
  }
  else
  {
    fwrite("ssh_init failed\n", 1uLL, 0x10uLL, stderr);
    return 1;
  }
}
// 16D0: using guessed type __int64 __fastcall ssh_bind_accept(_QWORD, _QWORD);
// 16E0: using guessed type __int64 ssh_event_new(void);
// 1730: using guessed type __int64 __fastcall ssh_disconnect(_QWORD);
// 1760: using guessed type __int64 ssh_bind_new(void);
// 17C0: using guessed type __int64 ssh_new(void);
// 17F0: using guessed type __int64 __fastcall ssh_bind_free(_QWORD);
// 18C0: using guessed type __int64 __fastcall ssh_bind_listen(_QWORD);
// 1900: using guessed type __int64 __fastcall ssh_get_error(_QWORD);
// 1910: using guessed type __int64 __fastcall ssh_event_free(_QWORD);
// 1930: using guessed type __int64 __fastcall ssh_free(_QWORD);
// 1980: using guessed type __int64 ssh_init(void);
// 253E: using guessed type __int64 __fastcall handle_session(_QWORD, _QWORD);
// 2A86: using guessed type __int64 __fastcall sigchld_handler();

//----- (0000000000002DF0) ----------------------------------------------------
void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{
  signed __int64 v4; // rbp
  __int64 i; // rbx

  v4 = &_do_global_dtors_aux_fini_array_entry - _frame_dummy_init_array_entry;
  init_proc();
  if ( v4 )
  {
    for ( i = 0LL; i != v4; ++i )
      ((void (__fastcall *)(_QWORD, __int64, __int64))_frame_dummy_init_array_entry[i])(a1, a2, a3);
  }
}
// 1AE0: using guessed type __int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD);
// 203D70: using guessed type __int64 (__fastcall *_frame_dummy_init_array_entry[2])();
// 203D78: using guessed type __int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)();

//----- (0000000000002E64) ----------------------------------------------------
void term_proc()
{
  ;
}

// nfuncs=130 queued=26 decompiled=26 lumina nreq=0 worse=0 better=0
#error "There were 2 decompilation failure(s) on 26 function(s)"
