// File: Themaister[P]umusd/tcpcommand.cpp
// Function: TCPCommand::TCPCommand(unsigned short)
TCPCommand::TCPCommand(std::uint16_t port) : remote(nullptr)
{
   struct addrinfo hints{}, *servinfo{nullptr};

   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = AI_PASSIVE;

   if (getaddrinfo(nullptr, stringify(port).c_str(), &hints, &servinfo) < 0)
      throw std::runtime_error("getaddrinfo() failed.\n");

   std::unique_ptr<struct addrinfo, std::function<void (struct addrinfo*)>> holder(servinfo,
         [](struct addrinfo *info) {
            freeaddrinfo(info);
         });

   fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
   if (fd < 0)
      throw std::runtime_error("Failed to create socket.\n");

   int yes = 1;
   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
   if (bind(fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0)
   {
      close(fd);
      throw std::runtime_error("Failed to bind socket. umusd is probably already running.\n");
   }

   if (listen(fd, 10) < 0)
   {
      close(fd);
      throw std::runtime_error("Failed to listen to socket.\n");
   }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movw %si, %ax
movq %rdi, -0x8(%rbp)
movw %ax, -0xa(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0x6bd0
movq -0xd8(%rbp), %rdi
leaq 0x1a374(%rip), %rax     # 0x3abf8
movq %rax, (%rdi)
movq $0x0, 0x20(%rdi)
addq $0x28, %rdi
movq %rdi, -0xd0(%rbp)
callq 0x22710
xorps %xmm0, %xmm0
movaps %xmm0, -0x20(%rbp)
movaps %xmm0, -0x30(%rbp)
movaps %xmm0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x1, -0x38(%rbp)
movl $0x1, -0x40(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0xa(%rbp), %rsi
callq 0x22730
jmp 0x208da
leaq -0x68(%rbp), %rdi
callq 0x5460
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edi
leaq -0x40(%rbp), %rdx
leaq -0x48(%rbp), %rcx
callq 0x5760
movl %eax, -0xdc(%rbp)
jmp 0x208ff
leaq -0x68(%rbp), %rdi
callq 0x5670
movl -0xdc(%rbp), %eax
cmpl $0x0, %eax
jge 0x209a3
movl $0x10, %edi
callq 0x5540
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
leaq 0x6114(%rip), %rsi      # 0x26a49
callq 0x5140
jmp 0x2093c
movq -0xe8(%rbp), %rdi
movq 0x1a646(%rip), %rsi     # 0x3af90
movq 0x1a68f(%rip), %rdx     # 0x3afe0
callq 0x5260
jmp 0x20c11
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x20bf0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5670
jmp 0x20bf0
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
callq 0x56d0
jmp 0x20bf0
movq -0x48(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc1(%rbp), %rsi
callq 0x20c20
movq -0xf0(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x227e0
leaq -0xc0(%rbp), %rdi
callq 0x22820
movq -0x48(%rbp), %rax
movl 0x4(%rax), %edi
movq -0x48(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x48(%rbp), %rax
movl 0xc(%rax), %edx
callq 0x5550
movl %eax, %ecx
movq -0xd8(%rbp), %rax
movl %ecx, 0x18(%rax)
cmpl $0x0, 0x18(%rax)
jge 0x20a85
movl $0x10, %edi
callq 0x5540
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xf8(%rbp)
leaq 0x602f(%rip), %rsi      # 0x26a60
callq 0x5140
jmp 0x20a38
movq -0xf8(%rbp), %rdi
movq 0x1a54a(%rip), %rsi     # 0x3af90
movq 0x1a593(%rip), %rdx     # 0x3afe0
callq 0x5260
jmp 0x20c11
movq -0xf8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
callq 0x56d0
jmp 0x20be4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x20be4
movq -0xd8(%rbp), %rax
movl $0x1, -0xc8(%rbp)
movl 0x18(%rax), %edi
movl $0x1, %esi
movl $0x2, %edx
leaq -0xc8(%rbp), %rcx
movl $0x4, %r8d
callq 0x5470
movq -0xd8(%rbp), %rax
movl 0x18(%rax), %edi
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x48(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x56e0
cmpl $0x0, %eax
jge 0x20b4a
movq -0xd8(%rbp), %rax
movl 0x18(%rax), %edi
callq 0x54c0
jmp 0x20ae9
movl $0x10, %edi
callq 0x5540
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x100(%rbp)
leaq 0x5f73(%rip), %rsi      # 0x26a7a
callq 0x5140
jmp 0x20b0e
movq -0x100(%rbp), %rdi
movq 0x1a474(%rip), %rsi     # 0x3af90
movq 0x1a4bd(%rip), %rdx     # 0x3afe0
callq 0x5260
jmp 0x20c11
movq -0x100(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
callq 0x56d0
jmp 0x20be4
movq -0xd8(%rbp), %rax
movl 0x18(%rax), %edi
movl $0xa, %esi
callq 0x5770
cmpl $0x0, %eax
jge 0x20bcf
movq -0xd8(%rbp), %rax
movl 0x18(%rax), %edi
callq 0x54c0
jmp 0x20b74
movl $0x10, %edi
callq 0x5540
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x108(%rbp)
leaq 0x5f23(%rip), %rsi      # 0x26ab5
callq 0x5140
jmp 0x20b99
movq -0x108(%rbp), %rdi
movq 0x1a3e9(%rip), %rsi     # 0x3af90
movq 0x1a432(%rip), %rdx     # 0x3afe0
callq 0x5260
jmp 0x20c11
movq -0x108(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
callq 0x56d0
jmp 0x20be4
leaq -0xa0(%rbp), %rdi
callq 0x22840
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
leaq -0xa0(%rbp), %rdi
callq 0x22840
movq -0xd0(%rbp), %rdi
callq 0x1ca00
movq -0xd8(%rbp), %rdi
callq 0x6dd0
movq -0x70(%rbp), %rdi
callq 0x52a0
nopw %cs:(%rax,%rax)