// File: /workspace/github_cpp_makefile_star2_O1/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, %rbx
movq %rdx, %r15
movq %rsi, %r14
movl %edi, -0x2c(%rbp)
xorl %eax, %eax
movq %rax, -0x40(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
leaq -0xc8(%rbp), %rcx
movq %rcx, -0x10(%rcx)
movq %rax, -0x8(%rcx)
movb $0x0, (%rcx)
leaq -0xa0(%rbp), %rdi
leaq -0x70(%rbp), %rdx
movq %rbx, %rsi
callq 0x2110
leaq -0x260(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
movl $0x18, %edx
callq 0x2360
movq %r14, -0xa8(%rbp)
leaq -0x90(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x288b
callq 0x2220
leaq -0x260(%rbp), %r12
leaq -0xd8(%rbp), %r13
leaq -0x50(%rbp), %r14
movq %r12, %rdi
movq %r13, %rsi
callq 0x22e0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x28c3
movq %r14, %rdi
movq %r13, %rsi
callq 0x33bc
jmp 0x289d
movq -0x50(%rbp), %rdi
leaq 0x1786(%rip), %rsi      # 0x4054
callq 0x20b0
testl %eax, %eax
jne 0x28fd
movq -0x48(%rbp), %rax
subq -0x50(%rbp), %rax
cmpq $0x20, %rax
jne 0x28fd
movl -0x2c(%rbp), %edi
movq 0x3951(%rip), %rsi      # 0x6240
movq 0x3952(%rip), %rdx      # 0x6248
xorl %ecx, %ecx
callq 0x2150
movq -0x50(%rbp), %rdi
leaq 0x174f(%rip), %rsi      # 0x4057
callq 0x20b0
testl %eax, %eax
jne 0x2926
movq -0x50(%rbp), %r12
movq -0x48(%rbp), %rax
subq %r12, %rax
cmpq $0x40, %rax
je 0x2bdd
movq -0x50(%rbp), %rdi
leaq 0x172e(%rip), %rsi      # 0x405f
callq 0x20b0
testl %eax, %eax
jne 0x2a96
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
subq %rax, %rcx
cmpq $0x60, %rcx
jne 0x2a96
movl $0x1, -0xb4(%rbp)
xorps %xmm0, %xmm0
leaq -0xa0(%rbp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, 0x20(%rdx)
movq 0x20(%rax), %rdi
movq 0x40(%rax), %rsi
leaq -0xb0(%rbp), %rcx
callq 0x22d0
testl %eax, %eax
jne 0x2b3c
movq -0xb0(%rbp), %rax
movl 0x4(%rax), %edi
movl 0x8(%rax), %esi
movl 0xc(%rax), %edx
callq 0x2090
movl %eax, %ebx
leaq -0xb4(%rbp), %rcx
movl %eax, %edi
movl $0x1, %esi
movl $0x2, %edx
movl $0x4, %r8d
callq 0x2390
testl %eax, %eax
js 0x2a88
movq -0xb0(%rbp), %rax
movq 0x18(%rax), %rsi
movl 0x10(%rax), %edx
movl %ebx, %edi
callq 0x21f0
testl %eax, %eax
js 0x2b41
movq -0xb0(%rbp), %rax
movq 0x18(%rax), %rsi
movzwl 0x2(%rsi), %r14d
addq $0x4, %rsi
leaq -0x70(%rbp), %r15
movl $0x2, %edi
movq %r15, %rdx
movl $0x10, %ecx
callq 0x2280
leaq 0x16db(%rip), %rdi      # 0x40f4
movq %r15, %rsi
xorl %eax, %eax
callq 0x2060
leaq 0x16f7(%rip), %rdi      # 0x4121
movl %r14d, %esi
xorl %eax, %eax
callq 0x2060
movq 0x357d(%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 0x2a6b
callq 0x2220
leaq -0x50(%rbp), %rdi
callq 0x34ca
movl %ebx, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x50(%rbp), %rdi
callq 0x23f7
jmp 0x29cb
movq -0x50(%rbp), %rdi
leaq 0x16ae(%rip), %rsi      # 0x414f
callq 0x20b0
testl %eax, %eax
jne 0x2b11
movq 0x3527(%rip), %rdi      # 0x5fd8
leaq 0x16a3(%rip), %rsi      # 0x415b
movl $0x1b, %edx
callq 0x22a0
movq 0x350f(%rip), %rdi      # 0x5fd8
callq 0x2140
leaq -0x90(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
movb $0x0, -0x90(%rbp)
cmpq $0x0, 0x3742(%rip)      # 0x6238
jne 0x2dc4
leaq 0x1674(%rip), %rdi      # 0x4177
xorl %eax, %eax
callq 0x2060
xorl %edi, %edi
callq 0x22c0
movq -0x50(%rbp), %rdi
leaq 0x166d(%rip), %rsi      # 0x4189
callq 0x20b0
testl %eax, %eax
jne 0x2b4a
movl -0x2c(%rbp), %edi
movq -0xa8(%rbp), %rsi
movq %r15, %rdx
callq 0x2656
jmp 0x2e4f
callq 0x23e0
leaq -0x50(%rbp), %rdi
callq 0x241e
movq -0x50(%rbp), %rdi
leaq 0x163a(%rip), %rsi      # 0x418f
callq 0x20b0
testl %eax, %eax
jne 0x2c05
movq 0x346f(%rip), %rdi      # 0x5fd8
leaq 0x1623(%rip), %rsi      # 0x4193
movl $0x10, %edx
callq 0x22a0
movq 0x3457(%rip), %rdi      # 0x5fd8
callq 0x2140
leaq -0x90(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
movb $0x0, -0x90(%rbp)
movq 0x367b(%rip), %rbx      # 0x6228
leaq 0x3664(%rip), %rax      # 0x6218
cmpq %rax, %rbx
jne 0x2f09
movl -0x2c(%rbp), %edi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
decq %rdx
xorl %ecx, %ecx
callq 0x2150
jmp 0x2e14
leaq 0x362c(%rip), %rdi      # 0x6210
leaq -0x2c(%rbp), %rsi
callq 0x3408
addq $0x20, %r12
movq (%rax), %rdi
addq $0x8, %rdi
movq %r12, %rsi
callq 0x2050
jmp 0x2e4f
movq -0x50(%rbp), %rdi
leaq 0x1594(%rip), %rsi      # 0x41a4
callq 0x20b0
testl %eax, %eax
jne 0x2cae
movq -0x50(%rbp), %rdi
addq $0x20, %rdi
leaq 0x157c(%rip), %rsi      # 0x41a8
callq 0x20b0
testl %eax, %eax
jne 0x2cae
leaq -0x90(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
movb $0x0, -0x90(%rbp)
movq -0x50(%rbp), %r13
addq $0x40, %r13
cmpq -0x48(%rbp), %r13
jne 0x2f7f
movq 0x35ba(%rip), %rbx      # 0x6228
leaq 0x35a3(%rip), %r14      # 0x6218
cmpq %r14, %rbx
je 0x2e14
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 0x2c7e
jmp 0x2e14
movq -0x50(%rbp), %rdi
leaq 0x14eb(%rip), %rsi      # 0x41a4
callq 0x20b0
testl %eax, %eax
jne 0x2e20
movq 0x355b(%rip), %rbx      # 0x6228
leaq -0x60(%rbp), %r13
leaq -0x70(%rbp), %r14
leaq 0x13a4(%rip), %r15      # 0x4080
leaq -0xa0(%rbp), %r12
movq 0x28(%rbx), %rdi
addq $0x8, %rdi
movq -0x50(%rbp), %rsi
addq $0x20, %rsi
callq 0x2040
testl %eax, %eax
jne 0x2db4
movq %rbx, -0xa8(%rbp)
leaq -0x90(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0x98(%rbp)
movb $0x0, -0x90(%rbp)
movq -0x50(%rbp), %rbx
addq $0x40, %rbx
cmpq -0x48(%rbp), %rbx
je 0x2d7a
movq %r13, -0x70(%rbp)
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdx
movq %r14, %rdi
callq 0x357e
movq %r14, %rdi
movq %r15, %rsi
callq 0x23b0
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq %r12, %rdi
callq 0x20c0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x2d74
callq 0x2220
addq $0x20, %rbx
jmp 0x2d2f
movq -0xa8(%rbp), %rbx
movq 0x28(%rbx), %rax
movl (%rax), %edi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
xorl %ecx, %ecx
callq 0x2150
movq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rax
cmpq %rax, %rdi
je 0x2db4
callq 0x2220
movq %rbx, %rdi
callq 0x21a0
movq %rax, %rbx
jmp 0x2ce3
movq 0x345d(%rip), %rbx      # 0x6228
leaq 0x3446(%rip), %rax      # 0x6218
cmpq %rax, %rbx
jne 0x2e4f
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
movq 0x31ec(%rip), %rdi      # 0x5fd8
callq 0x22a0
movq %rax, %rdi
callq 0x2140
movl -0x2c(%rbp), %edi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
decq %rdx
xorl %ecx, %ecx
callq 0x2150
leaq -0xa0(%rbp), %rdi
callq 0x23d8
movq 0x31b1(%rip), %rdi      # 0x5fd8
leaq 0x137e(%rip), %rsi      # 0x41ac
movl $0x1c, %edx
callq 0x22a0
movq 0x3199(%rip), %rdi      # 0x5fd8
movq %rbx, %rsi
callq 0x2250
movq %rax, %rdi
callq 0x2140
leaq -0x60(%rbp), %r13
leaq 0x132b(%rip), %r14      # 0x4185
leaq -0x70(%rbp), %r15
leaq -0xa0(%rbp), %r12
movq 0x28(%rbx), %rsi
addq $0x8, %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x346f
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq %r12, %rdi
callq 0x20c0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x2e96
callq 0x2220
movq 0x28(%rbx), %rsi
addq $0x28, %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x346f
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq %r12, %rdi
callq 0x20c0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x2ec7
callq 0x2220
movq 0x28(%rbx), %rax
movzwl 0x48(%rax), %esi
addq %r14, %rsi
movq %r12, %rdi
callq 0x23b0
movq %r12, %rdi
leaq 0x12a3(%rip), %rsi      # 0x4187
callq 0x23b0
movq %rbx, %rdi
callq 0x21a0
movq %rax, %rbx
leaq 0x331d(%rip), %rax      # 0x6218
cmpq %rax, %rbx
jne 0x2e65
jmp 0x2dd7
leaq -0x60(%rbp), %r13
leaq -0x70(%rbp), %r14
leaq 0x126d(%rip), %r15      # 0x4185
leaq -0xa0(%rbp), %r12
movq 0x28(%rbx), %rax
movq %r13, -0x70(%rbp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
movq %r14, %rdi
callq 0x357e
movq %r14, %rdi
movq %r15, %rsi
callq 0x23b0
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq %r12, %rdi
callq 0x20c0
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x2f63
callq 0x2220
movq %rbx, %rdi
callq 0x21a0
movq %rax, %rbx
leaq 0x32a3(%rip), %rax      # 0x6218
cmpq %rax, %rbx
jne 0x2f1f
jmp 0x2bbd
leaq -0x60(%rbp), %r12
leaq -0x70(%rbp), %rbx
leaq 0x10f2(%rip), %r14      # 0x4080
leaq -0xa0(%rbp), %r15
movq %r12, -0x70(%rbp)
movq (%r13), %rsi
movq 0x8(%r13), %rdx
addq %rsi, %rdx
movq %rbx, %rdi
callq 0x357e
movq %rbx, %rdi
movq %r14, %rsi
callq 0x23b0
movq -0x70(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq %r15, %rdi
callq 0x20c0
movq -0x70(%rbp), %rdi
cmpq %r12, %rdi
je 0x2fd5
callq 0x2220
addq $0x20, %r13
cmpq -0x48(%rbp), %r13
jne 0x2f95
jmp 0x2c67
jmp 0x3025
jmp 0x3065
jmp 0x2fec
jmp 0x300e
movq %rax, %rbx
movq -0x70(%rbp), %rdi
cmpq %r12, %rdi
jne 0x301a
jmp 0x3028
jmp 0x300e
jmp 0x3025
jmp 0x3025
jmp 0x300e
jmp 0x3025
jmp 0x300e
jmp 0x3025
jmp 0x3025
jmp 0x300e
jmp 0x3025
movq %rax, %rbx
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0x3028
callq 0x2220
jmp 0x3028
jmp 0x3025
jmp 0x3025
movq %rax, %rbx
movq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rax
cmpq %rax, %rdi
je 0x3068
callq 0x2220
jmp 0x3068
movq %rax, %rbx
leaq -0x90(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3087
callq 0x2220
jmp 0x3087
movq %rax, %rbx
jmp 0x3087
jmp 0x3065
jmp 0x3065
movq %rax, %rbx
movq 0x2f49(%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 0x309f
callq 0x2220
leaq -0x50(%rbp), %rdi
callq 0x34ca
movq %rbx, %rdi
callq 0x2380