// File: /workspace/github_cpp_makefile_star2_O3/hinrikHelga[P]Botnet/server.cpp
// Function: inputCommand(int, fd_set*, int*, char*)
int inputCommand(int clientSocket, fd_set *openSockets, int *maxfds,
                  char *buffer)
{
  std::vector<std::string> tokens;
  std::string token;

  // Split command from client into tokens for parsing
  std::stringstream stream(buffer);

  while(stream >> token)
      tokens.push_back(token);

  if((tokens[0].compare("ID") == 0) && (tokens.size() == 1))
  {
      send(clientSocket, myName.c_str(), myName.length(), 0);
  }

  if((tokens[0].compare("CONNECT") == 0) && (tokens.size() == 2))
  {
     connectedServers[clientSocket]->name = tokens[1];
  }

  else if((tokens[0].compare("CONNECT_OTHER") == 0) && (tokens.size() == 3))
  {
      int sock, set = 1, count = 1;
      struct addrinfo sk_addr, *svr;


      /* Create the socket. */
      sk_addr.ai_family   = AF_INET;            // IPv4 only addresses
      sk_addr.ai_socktype = SOCK_STREAM;
      sk_addr.ai_flags    = AI_PASSIVE;

      memset(&sk_addr,   0, sizeof(sk_addr));

      if(getaddrinfo(tokens[1].c_str(), tokens[2].c_str(), &sk_addr, &svr) != 0)
      {
          perror("getaddrinfo failed: ");
          exit(0);
      }

      sock = socket(svr->ai_family, svr->ai_socktype, svr->ai_protocol);

      // Connect to the other server.
      if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set)) < 0)
      {
          printf("Failed to set SO_REUSEADDR for port %s\n", tokens[2].c_str());
          perror("setsockopt failed: ");
      }

      if(connect(sock, svr->ai_addr, svr->ai_addrlen )< 0)
      {
          printf("Failed to open socket to server: %s\n", tokens[1].c_str());
          perror("Connect failed: ");
          exit(0);
      }

      else
      {
          // Extracting ip address and port number from sk_addr
          u_short portNo;
          struct sockaddr_in *sin = (struct sockaddr_in *) svr-> ai_addr;
          char ipAddress[INET_ADDRSTRLEN];
          portNo = sin->sin_port;
          inet_ntop(AF_INET, &(sin->sin_addr), ipAddress, INET_ADDRSTRLEN);

          printf("The ip address of the new connection is: %s\n", ipAddress);
          printf("The port number of the new connection is: %d\n", portNo);

          return(sock);
      }
  }

  else if(tokens[0].compare("LISTSERVERS") == 0)
  {
      std::cout << "The connected servers are: " << std::endl;
      std::string msg;
      if(connectedServers.empty())
      {
          printf("List is empty");
          exit(0);
      }
      else
      {
        for(auto const& names : connectedServers)
        {
           msg += names.second->name + ",";
           msg += names.second->host_ip + ",";
           msg += names.second->port + ",";
           msg += ";";
        }
        std::cout << msg << std::endl;
        send(clientSocket, msg.c_str(), msg.length()-1, 0);
      }
  }
  else if(tokens[0].compare("LEAVE") == 0)
  {
      // Close the socket, and leave the socket handling
      // code to deal with tidying up connectedServers etc. when
      // select() detects the OS has torn down the connection.

      closeClient(clientSocket, openSockets, maxfds);
  }
  else if(tokens[0].compare("WHO") == 0)
  {
     std::cout << "Who is logged on" << std::endl;
     std::string msg;

     for(auto const& names : connectedServers)
     {
        msg += names.second->name + ",";
     }
     // Reducing the msg length by 1 loses the excess "," - which
     // granted is totally cheating.
     send(clientSocket, msg.c_str(), msg.length()-1, 0);

  }
  // This is slightly fragile, since it's relying on the order
  // of evaluation of the if statement.
  else if((tokens[0].compare("MSG") == 0) && (tokens[1].compare("ALL") == 0))
  {
      std::string msg;
      for(auto i = tokens.begin()+2;i != tokens.end();i++)
      {
          msg += *i + " ";
      }

      for(auto const& pair : connectedServers)
      {
          send(pair.second->sock, msg.c_str(), msg.length(),0);
      }
  }
  else if(tokens[0].compare("MSG") == 0)
  {
      for(auto const& pair : connectedServers)
      {
          if(pair.second->name.compare(tokens[1]) == 0)
          {
              std::string msg;
              for(auto i = tokens.begin()+2;i != tokens.end();i++)
              {
                  msg += *i + " ";
              }
              send(pair.second->sock, msg.c_str(), msg.length(),0);
          }
      }
  }
  else
  {
      std::cout << "Unknown command from client:" << buffer << std::endl;
  }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %rcx, %r14
movq %rdx, %r12
movq %rsi, %rbx
movl %edi, -0x2c(%rbp)
movl %edi, -0xb0(%rbp)
xorl %eax, %eax
movq %rax, -0x60(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
leaq -0xc8(%rbp), %rcx
movq %rcx, -0x10(%rcx)
movq %rax, -0x8(%rcx)
movb $0x0, (%rcx)
leaq -0xa0(%rbp), %rdi
leaq -0x50(%rbp), %rdx
movq %r14, %rsi
callq 0x2110
leaq -0x260(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
movl $0x18, %edx
callq 0x2360
movq %rbx, -0xb8(%rbp)
leaq -0x90(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x289b
callq 0x2220
leaq -0x260(%rbp), %r13
leaq -0xd8(%rbp), %rbx
leaq -0x70(%rbp), %r15
movq %r13, %rdi
movq %rbx, %rsi
callq 0x22e0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x28d3
movq %r15, %rdi
movq %rbx, %rsi
callq 0x33c0
jmp 0x28ad
movq -0x70(%rbp), %rdi
leaq 0x1776(%rip), %rsi      # 0x4054
callq 0x20b0
movq -0x70(%rbp), %rdi
testl %eax, %eax
jne 0x2914
movq -0x68(%rbp), %rax
subq %rdi, %rax
cmpq $0x20, %rax
jne 0x2914
movq 0x3941(%rip), %rsi      # 0x6240
movq 0x3942(%rip), %rdx      # 0x6248
movl -0x2c(%rbp), %edi
xorl %ecx, %ecx
callq 0x2150
movq -0x70(%rbp), %rdi
leaq 0x173c(%rip), %rsi      # 0x4057
callq 0x20b0
movq -0x70(%rbp), %r13
testl %eax, %eax
jne 0x2939
movq -0x68(%rbp), %rax
subq %r13, %rax
cmpq $0x40, %rax
je 0x2bd0
leaq 0x171f(%rip), %rsi      # 0x405f
movq %r13, %rdi
callq 0x20b0
movq -0x70(%rbp), %rdi
testl %eax, %eax
jne 0x2aab
movq -0x68(%rbp), %rax
subq %rdi, %rax
cmpq $0x60, %rax
jne 0x2aab
movl $0x1, -0xac(%rbp)
xorps %xmm0, %xmm0
leaq -0xa0(%rbp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, 0x20(%rdx)
movq 0x20(%rdi), %rax
movq 0x40(%rdi), %rsi
leaq -0xa8(%rbp), %rcx
movq %rax, %rdi
callq 0x22d0
testl %eax, %eax
jne 0x2b43
movq -0xa8(%rbp), %rax
movl 0x4(%rax), %edi
movl 0x8(%rax), %esi
movl 0xc(%rax), %edx
callq 0x2090
movl %eax, %ebx
leaq -0xac(%rbp), %rcx
movl %eax, %edi
movl $0x1, %esi
movl $0x2, %edx
movl $0x4, %r8d
callq 0x2390
testl %eax, %eax
js 0x2a9d
movq -0xa8(%rbp), %rax
movq 0x18(%rax), %rsi
movl 0x10(%rax), %edx
movl %ebx, %edi
callq 0x21f0
testl %eax, %eax
js 0x2b48
movq -0xa8(%rbp), %rax
movq 0x18(%rax), %rsi
movzwl 0x2(%rsi), %r14d
addq $0x4, %rsi
leaq -0x50(%rbp), %r15
movl $0x2, %edi
movq %r15, %rdx
movl $0x10, %ecx
callq 0x2280
leaq 0x16c6(%rip), %rdi      # 0x40f4
movq %r15, %rsi
xorl %eax, %eax
callq 0x2060
leaq 0x16e2(%rip), %rdi      # 0x4121
movl %r14d, %esi
xorl %eax, %eax
callq 0x2060
movq 0x3568(%rip), %rsi      # 0x5fb8
leaq -0x260(%rbp), %rdi
callq 0x21c0
leaq -0x1e0(%rbp), %rdi
callq 0x20f0
movq -0xd8(%rbp), %rdi
leaq -0xc8(%rbp), %rax
cmpq %rax, %rdi
je 0x2a80
callq 0x2220
leaq -0x70(%rbp), %rdi
callq 0x34ce
movl %ebx, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x70(%rbp), %rdi
callq 0x23f7
jmp 0x29e0
leaq 0x169d(%rip), %rsi      # 0x414f
callq 0x20b0
testl %eax, %eax
jne 0x2b18
movq 0x3516(%rip), %rdi      # 0x5fd8
leaq 0x1692(%rip), %rsi      # 0x415b
movl $0x1b, %edx
callq 0x22a0
movq 0x34fe(%rip), %rdi      # 0x5fd8
callq 0x2140
leaq -0x90(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
cmpq $0x0, 0x373b(%rip)      # 0x6238
jne 0x2db1
leaq 0x166d(%rip), %rdi      # 0x4177
xorl %eax, %eax
callq 0x2060
xorl %edi, %edi
callq 0x22c0
movq -0x70(%rbp), %rdi
leaq 0x1666(%rip), %rsi      # 0x4189
callq 0x20b0
testl %eax, %eax
jne 0x2b51
movl -0x2c(%rbp), %edi
movq -0xb8(%rbp), %rsi
movq %r12, %rdx
callq 0x2656
jmp 0x2e37
callq 0x23e0
leaq -0x70(%rbp), %rdi
callq 0x241e
movq -0x70(%rbp), %rdi
leaq 0x1633(%rip), %rsi      # 0x418f
callq 0x20b0
testl %eax, %eax
jne 0x2bfb
movq 0x3468(%rip), %rdi      # 0x5fd8
leaq 0x161c(%rip), %rsi      # 0x4193
movl $0x10, %edx
callq 0x22a0
movq 0x3450(%rip), %rdi      # 0x5fd8
callq 0x2140
leaq -0x90(%rbp), %rsi
movq %rsi, -0x10(%rsi)
movq $0x0, -0x8(%rsi)
movb $0x0, (%rsi)
movq 0x367e(%rip), %r14      # 0x6228
movq $-0x1, %rdx
leaq 0x3660(%rip), %rax      # 0x6218
cmpq %rax, %r14
jne 0x2eff
movl -0x2c(%rbp), %edi
xorl %ecx, %ecx
callq 0x2150
jmp 0x2dfc
leaq 0x3639(%rip), %rdi      # 0x6210
leaq -0xb0(%rbp), %rsi
callq 0x340c
addq $0x20, %r13
movq (%rax), %rdi
addq $0x8, %rdi
movq %r13, %rsi
callq 0x2050
jmp 0x2e37
movq -0x70(%rbp), %rdi
leaq 0x159e(%rip), %rsi      # 0x41a4
callq 0x20b0
testl %eax, %eax
jne 0x2c9a
movq -0x70(%rbp), %rdi
addq $0x20, %rdi
leaq 0x1586(%rip), %rsi      # 0x41a8
callq 0x20b0
testl %eax, %eax
jne 0x2c9a
leaq -0x90(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq -0x70(%rbp), %r12
addq $0x40, %r12
cmpq -0x68(%rbp), %r12
jne 0x2f86
movq 0x35ce(%rip), %rbx      # 0x6228
leaq 0x35b7(%rip), %r14      # 0x6218
cmpq %r14, %rbx
je 0x2dfc
movq 0x28(%rbx), %rax
movl (%rax), %edi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
xorl %ecx, %ecx
callq 0x2150
movq %rbx, %rdi
callq 0x21a0
movq %rax, %rbx
cmpq %r14, %rax
jne 0x2c6a
jmp 0x2dfc
movq -0x70(%rbp), %rdi
leaq 0x14ff(%rip), %rsi      # 0x41a4
callq 0x20b0
testl %eax, %eax
jne 0x2e08
movq 0x356f(%rip), %rax      # 0x6228
leaq -0x40(%rbp), %r13
leaq -0x50(%rbp), %r14
leaq -0xa0(%rbp), %r12
leaq -0x90(%rbp), %rbx
movq %rax, %r15
movq 0x28(%rax), %rdi
addq $0x8, %rdi
movq -0x70(%rbp), %rsi
addq $0x20, %rsi
callq 0x2040
testl %eax, %eax
jne 0x2da4
movq %rbx, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
movb $0x0, -0x90(%rbp)
movq -0x70(%rbp), %rbx
addq $0x40, %rbx
cmpq -0x68(%rbp), %rbx
je 0x2d7a
movq %r13, -0x50(%rbp)
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdx
movq %r14, %rdi
callq 0x358c
movq %r14, %rdi
leaq 0x134a(%rip), %rsi      # 0x4080
callq 0x23b0
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %r12, %rdi
callq 0x20c0
movq -0x50(%rbp), %rdi
cmpq %r13, %rdi
je 0x2d59
callq 0x2220
addq $0x20, %rbx
cmpq -0x68(%rbp), %rbx
jne 0x2d16
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
leaq -0x90(%rbp), %rbx
jmp 0x2d86
xorl %edx, %edx
leaq -0x90(%rbp), %rbx
movq %rbx, %rsi
movq 0x28(%r15), %rax
movl (%rax), %edi
xorl %ecx, %ecx
callq 0x2150
movq -0xa0(%rbp), %rdi
cmpq %rbx, %rdi
je 0x2da4
callq 0x2220
movq %r15, %rdi
callq 0x21a0
jmp 0x2ccf
movq 0x3470(%rip), %r14      # 0x6228
leaq 0x3459(%rip), %rax      # 0x6218
cmpq %rax, %r14
jne 0x2e37
xorl %edx, %edx
leaq -0x90(%rbp), %rsi
movq 0x3204(%rip), %rdi      # 0x5fd8
callq 0x22a0
movq %rax, %rdi
callq 0x2140
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
decq %rdx
movl -0x2c(%rbp), %edi
xorl %ecx, %ecx
callq 0x2150
leaq -0xa0(%rbp), %rdi
callq 0x23d8
movq 0x31c9(%rip), %rdi      # 0x5fd8
leaq 0x1396(%rip), %rsi      # 0x41ac
movl $0x1c, %edx
callq 0x22a0
movq 0x31b1(%rip), %rdi      # 0x5fd8
movq %r14, %rsi
callq 0x2250
movq %rax, %rdi
callq 0x2140
leaq -0x40(%rbp), %rbx
leaq 0x1343(%rip), %r15      # 0x4185
leaq -0x50(%rbp), %r12
leaq -0xa0(%rbp), %r13
movq 0x28(%r14), %rsi
addq $0x8, %rsi
movq %r12, %rdi
movq %r15, %rdx
callq 0x3474
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %r13, %rdi
callq 0x20c0
movq -0x50(%rbp), %rdi
cmpq %rbx, %rdi
je 0x2e7e
callq 0x2220
movq 0x28(%r14), %rsi
addq $0x28, %rsi
movq %r12, %rdi
movq %r15, %rdx
callq 0x3474
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %r13, %rdi
callq 0x20c0
movq -0x50(%rbp), %rdi
cmpq %rbx, %rdi
je 0x2eaf
callq 0x2220
movq 0x28(%r14), %rax
movzwl 0x48(%rax), %esi
addq %r15, %rsi
movq %r13, %rdi
callq 0x23b0
movq %r13, %rdi
leaq 0x12bb(%rip), %rsi      # 0x4187
callq 0x23b0
movq %r14, %rdi
callq 0x21a0
movq %rax, %r14
leaq 0x3335(%rip), %rax      # 0x6218
cmpq %rax, %r14
jne 0x2e4d
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
jmp 0x2dcd
leaq -0x40(%rbp), %rbx
leaq -0x50(%rbp), %r15
leaq 0x1277(%rip), %r12      # 0x4185
leaq -0xa0(%rbp), %r13
movq 0x28(%r14), %rax
movq %rbx, -0x50(%rbp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
movq %r15, %rdi
callq 0x358c
movq %r15, %rdi
movq %r12, %rsi
callq 0x23b0
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %r13, %rdi
callq 0x20c0
movq -0x50(%rbp), %rdi
cmpq %rbx, %rdi
je 0x2f59
callq 0x2220
movq %r14, %rdi
callq 0x21a0
movq %rax, %r14
leaq 0x32ad(%rip), %rax      # 0x6218
cmpq %rax, %r14
jne 0x2f15
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
decq %rdx
jmp 0x2bc1
leaq -0x40(%rbp), %r13
leaq -0x50(%rbp), %rbx
leaq 0x10eb(%rip), %r14      # 0x4080
leaq -0xa0(%rbp), %r15
movq %r13, -0x50(%rbp)
movq (%r12), %rsi
movq 0x8(%r12), %rdx
addq %rsi, %rdx
movq %rbx, %rdi
callq 0x358c
movq %rbx, %rdi
movq %r14, %rsi
callq 0x23b0
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %r15, %rdi
callq 0x20c0
movq -0x50(%rbp), %rdi
cmpq %r13, %rdi
je 0x2fdd
callq 0x2220
addq $0x20, %r12
cmpq -0x68(%rbp), %r12
jne 0x2f9c
jmp 0x2c53
jmp 0x302d
jmp 0x306d
jmp 0x3016
jmp 0x3000
jmp 0x3016
jmp 0x3000
jmp 0x302d
jmp 0x302d
jmp 0x3000
jmp 0x302d
movq %rax, %r14
movq -0x50(%rbp), %rdi
cmpq %rbx, %rdi
jne 0x3022
jmp 0x3030
jmp 0x302d
jmp 0x302d
jmp 0x302d
jmp 0x3016
movq %rax, %r14
movq -0x50(%rbp), %rdi
cmpq %r13, %rdi
je 0x3030
callq 0x2220
jmp 0x3030
jmp 0x302d
jmp 0x302d
movq %rax, %r14
movq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rax
cmpq %rax, %rdi
je 0x3070
callq 0x2220
jmp 0x3070
movq %rax, %r14
leaq -0x90(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x308f
callq 0x2220
jmp 0x308f
movq %rax, %r14
jmp 0x308f
jmp 0x306d
jmp 0x306d
movq %rax, %r14
movq 0x2f41(%rip), %rsi      # 0x5fb8
leaq -0x260(%rbp), %rdi
callq 0x21c0
leaq -0x1e0(%rbp), %rdi
callq 0x20f0
movq -0xd8(%rbp), %rdi
leaq -0xc8(%rbp), %rax
cmpq %rax, %rdi
je 0x30a7
callq 0x2220
leaq -0x70(%rbp), %rdi
callq 0x34ce
movq %r14, %rdi
callq 0x2380