// File: /workspace/github_cpp_makefile_star2_O2/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, -0x90(%rbp)
andq $0x0, -0x40(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
leaq -0xc8(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x80(%rbp), %rdi
leaq -0xb0(%rbp), %rdx
movq %rcx, %rsi
callq 0x20e0
movq %rbx, -0xb8(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x80(%rbp), %rsi
pushq $0x18
popq %rdx
callq 0x22f0
leaq -0x80(%rbp), %rdi
callq 0x2378
leaq -0x260(%rbp), %r13
leaq -0xd8(%rbp), %r15
leaq -0x50(%rbp), %rbx
movq %r13, %rdi
movq %r15, %rsi
callq 0x2260
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x2785
movq %rbx, %rdi
movq %r15, %rsi
callq 0x308c
jmp 0x275f
movq -0x50(%rbp), %rdi
leaq 0x18c4(%rip), %rsi      # 0x4054
callq 0x20a0
movq -0x50(%rbp), %rdi
testl %eax, %eax
jne 0x27c6
movq -0x48(%rbp), %rax
subq %rdi, %rax
cmpq $0x20, %rax
jne 0x27c6
movq 0x3a5f(%rip), %rsi      # 0x6210
movq 0x3a60(%rip), %rdx      # 0x6218
movl -0x2c(%rbp), %edi
xorl %ecx, %ecx
callq 0x2110
movq -0x50(%rbp), %rdi
leaq 0x188a(%rip), %rsi      # 0x4057
callq 0x20a0
movq -0x50(%rbp), %r13
testl %eax, %eax
jne 0x27eb
movq -0x48(%rbp), %rax
subq %r13, %rax
cmpq $0x40, %rax
je 0x2aa3
leaq 0x186d(%rip), %rsi      # 0x405f
movq %r13, %rdi
callq 0x20a0
movq -0x50(%rbp), %rdi
testl %eax, %eax
jne 0x294d
movq -0x48(%rbp), %rax
subq %rdi, %rax
cmpq $0x60, %rax
jne 0x294d
movl $0x1, -0x8c(%rbp)
xorps %xmm0, %xmm0
leaq -0x80(%rbp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, 0x20(%rdx)
movq 0x20(%rdi), %rax
movq 0x40(%rdi), %rsi
leaq -0x88(%rbp), %rcx
movq %rax, %rdi
callq 0x2250
testl %eax, %eax
jne 0x29d1
movq -0x88(%rbp), %rax
movl 0x4(%rax), %edi
movl 0x8(%rax), %esi
movl 0xc(%rax), %edx
callq 0x2080
movl %eax, %ebx
pushq $0x1
popq %rsi
pushq $0x2
popq %rdx
leaq -0x8c(%rbp), %rcx
pushq $0x4
popq %r8
movl %eax, %edi
callq 0x2320
testl %eax, %eax
js 0x2926
movq -0x88(%rbp), %rax
movq 0x18(%rax), %rsi
movl 0x10(%rax), %edx
movl %ebx, %edi
callq 0x2180
testl %eax, %eax
js 0x29da
movq -0x88(%rbp), %rax
movq 0x18(%rax), %rsi
movzwl 0x2(%rsi), %r14d
addq $0x4, %rsi
pushq $0x2
popq %rdi
leaq -0xb0(%rbp), %r15
pushq $0x10
popq %rcx
movq %r15, %rdx
callq 0x2210
leaq 0x181e(%rip), %rdi      # 0x40f4
movq %r15, %rsi
xorl %eax, %eax
callq 0x2050
leaq 0x183a(%rip), %rdi      # 0x4121
movl %r14d, %esi
xorl %eax, %eax
callq 0x2050
leaq -0x260(%rbp), %rdi
callq 0x2160
leaq -0xd8(%rbp), %rdi
callq 0x2378
leaq -0x50(%rbp), %rdi
callq 0x3152
movl %ebx, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rsi
leaq 0x174d(%rip), %rdi      # 0x4082
xorl %eax, %eax
callq 0x2050
leaq 0x1767(%rip), %rdi      # 0x40aa
callq 0x2190
jmp 0x2889
leaq 0x17fb(%rip), %rsi      # 0x414f
callq 0x20a0
testl %eax, %eax
jne 0x29a6
movq 0x3674(%rip), %rdi      # 0x5fd8
leaq 0x17f0(%rip), %rsi      # 0x415b
callq 0x21e0
movq %rax, %rdi
callq 0x2100
leaq -0x70(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
cmpq $0x0, 0x3878(%rip)      # 0x6208
jne 0x2c12
leaq 0x17da(%rip), %rdi      # 0x4177
xorl %eax, %eax
callq 0x2050
jmp 0x29fc
movq -0x50(%rbp), %rdi
leaq 0x17d8(%rip), %rsi      # 0x4189
callq 0x20a0
testl %eax, %eax
jne 0x2a03
movl -0x2c(%rbp), %edi
movq -0xb8(%rbp), %rsi
movq %r12, %rdx
callq 0x2574
jmp 0x2ce2
leaq 0x1695(%rip), %rdi      # 0x406d
jmp 0x29f7
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rsi
leaq 0x16d5(%rip), %rdi      # 0x40be
xorl %eax, %eax
callq 0x2050
leaq 0x16ec(%rip), %rdi      # 0x40e3
callq 0x2190
xorl %edi, %edi
callq 0x2240
movq -0x50(%rbp), %rdi
leaq 0x1781(%rip), %rsi      # 0x418f
callq 0x20a0
testl %eax, %eax
jne 0x2ace
movq 0x35b6(%rip), %rdi      # 0x5fd8
leaq 0x176a(%rip), %rsi      # 0x4193
callq 0x21e0
movq %rax, %rdi
callq 0x2100
leaq -0x70(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq 0x37ab(%rip), %r12      # 0x61f8
leaq 0x3794(%rip), %rbx      # 0x61e8
leaq 0x172a(%rip), %r14      # 0x4185
leaq -0xb0(%rbp), %r15
leaq -0x80(%rbp), %r13
cmpq %rbx, %r12
je 0x2ce2
movq 0x28(%r12), %rsi
addq $0x8, %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x3119
movq %r13, %rdi
movq %r15, %rsi
callq 0x2350
movq %r15, %rdi
callq 0x2378
movq %r12, %rdi
callq 0x2150
movq %rax, %r12
jmp 0x2a66
leaq 0x3736(%rip), %rdi      # 0x61e0
leaq -0x90(%rbp), %rsi
callq 0x30c8
addq $0x20, %r13
movq (%rax), %rdi
addq $0x8, %rdi
movq %r13, %rsi
callq 0x2040
jmp 0x2ce2
movq -0x50(%rbp), %rdi
leaq 0x16cb(%rip), %rsi      # 0x41a4
callq 0x20a0
testl %eax, %eax
jne 0x2b55
movq -0x50(%rbp), %rdi
addq $0x20, %rdi
leaq 0x16b7(%rip), %rsi      # 0x41a8
callq 0x20a0
testl %eax, %eax
jne 0x2b55
leaq -0x70(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq -0x50(%rbp), %rbx
addq $0x40, %rbx
leaq 0x1567(%rip), %r14      # 0x4080
leaq -0xb0(%rbp), %r15
leaq -0x80(%rbp), %r12
cmpq -0x48(%rbp), %rbx
je 0x2cf9
movq %r15, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3119
movq %r12, %rdi
movq %r15, %rsi
callq 0x2350
movq %r15, %rdi
callq 0x2378
addq $0x20, %rbx
jmp 0x2b24
movq -0x50(%rbp), %rdi
leaq 0x1644(%rip), %rsi      # 0x41a4
callq 0x20a0
testl %eax, %eax
jne 0x2cbc
movq 0x3684(%rip), %rbx      # 0x61f8
leaq -0x80(%rbp), %r14
leaq 0x1501(%rip), %r15      # 0x4080
leaq -0xb0(%rbp), %r12
movq 0x28(%rbx), %rdi
addq $0x8, %rdi
movq -0x50(%rbp), %rsi
addq $0x20, %rsi
callq 0x2030
testl %eax, %eax
jne 0x2c02
leaq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
andq $0x0, -0x78(%rbp)
movb $0x0, -0x70(%rbp)
movq -0x50(%rbp), %r13
addq $0x40, %r13
cmpq -0x48(%rbp), %r13
je 0x2be5
movq %r12, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x3119
movq %r14, %rdi
movq %r12, %rsi
callq 0x2350
movq %r12, %rdi
callq 0x2378
addq $0x20, %r13
jmp 0x2bb8
movq 0x28(%rbx), %rax
movl (%rax), %edi
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
xorl %ecx, %ecx
callq 0x2110
movq %r14, %rdi
callq 0x2378
movq %rbx, %rdi
callq 0x2150
movq %rax, %rbx
jmp 0x2b86
movq 0x35df(%rip), %r12      # 0x61f8
leaq 0x35c8(%rip), %rbx      # 0x61e8
leaq 0x155e(%rip), %r14      # 0x4185
leaq -0xb0(%rbp), %r15
leaq -0x80(%rbp), %r13
cmpq %rbx, %r12
je 0x2d2e
movq 0x28(%r12), %rsi
addq $0x8, %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x3119
movq %r13, %rdi
movq %r15, %rsi
callq 0x2350
movq %r15, %rdi
callq 0x2378
movq 0x28(%r12), %rsi
addq $0x28, %rsi
movq %r15, %rdi
movq %r14, %rdx
callq 0x3119
movq %r13, %rdi
movq %r15, %rsi
callq 0x2350
movq %r15, %rdi
callq 0x2378
movq 0x28(%r12), %rax
movzwl 0x48(%rax), %esi
addq %r14, %rsi
movq %r13, %rdi
callq 0x2330
movq %r13, %rdi
leaq 0x14e0(%rip), %rsi      # 0x4187
callq 0x2330
movq %r12, %rdi
callq 0x2150
movq %rax, %r12
jmp 0x2c32
movq 0x3315(%rip), %rdi      # 0x5fd8
leaq 0x14e2(%rip), %rsi      # 0x41ac
callq 0x21e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x21e0
movq %rax, %rdi
callq 0x2100
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
decq %rdx
movl -0x2c(%rbp), %edi
xorl %ecx, %ecx
callq 0x2110
jmp 0x2d5b
movq 0x34f8(%rip), %rbx      # 0x61f8
leaq 0x34e1(%rip), %r14      # 0x61e8
cmpq %r14, %rbx
je 0x2d5b
movq 0x28(%rbx), %rax
movl (%rax), %edi
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
xorl %ecx, %ecx
callq 0x2110
movq %rbx, %rdi
callq 0x2150
movq %rax, %rbx
jmp 0x2d07
movq 0x32a3(%rip), %rdi      # 0x5fd8
leaq -0x80(%rbp), %rsi
callq 0x21b0
movq %rax, %rdi
callq 0x2100
movq -0x80(%rbp), %rsi
movq -0x78(%rbp), %rdx
decq %rdx
movl -0x2c(%rbp), %edi
xorl %ecx, %ecx
callq 0x2110
leaq -0x80(%rbp), %rdi
callq 0x2378
jmp 0x2d80
jmp 0x2db6
jmp 0x2d85
jmp 0x2d80
jmp 0x2d85
jmp 0x2d80
jmp 0x2d80
jmp 0x2d80
jmp 0x2d85
jmp 0x2d85
jmp 0x2d80
jmp 0x2d80
jmp 0x2d80
jmp 0x2d80
movq %rax, %rbx
jmp 0x2d94
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x2378
leaq -0x80(%rbp), %rdi
callq 0x2378
jmp 0x2db9
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x2378
jmp 0x2dc5
movq %rax, %rbx
jmp 0x2dc5
jmp 0x2db6
jmp 0x2db6
movq %rax, %rbx
leaq -0x260(%rbp), %rdi
callq 0x2160
leaq -0xd8(%rbp), %rdi
callq 0x2378
leaq -0x50(%rbp), %rdi
callq 0x3152
movq %rbx, %rdi
callq 0x2310