// File: /workspace/github_cpp_makefile_star2_O3/dmonaldo[P]simple-network-file-system/server.cpp
// Function: main
int main(int argc, char* argv[]) {
  const int BACKLOG = 5;
  const int BUFFER_LENGTH = 2048;
  int sockfd, newsockfd, port, clilen;
  char buffer[BUFFER_LENGTH];
  struct sockaddr_in serv_addr, cli_addr;
  struct sockaddr_storage their_addr;

  // connector's address information
  socklen_t sin_size;
  if (argc < 2) {
    cout << "Usage: ./nfsserver port#\n";
    return -1;
  }

  port = atoi(argv[1]);
  cout << "Connecting to port " << port << endl;

  // create socket
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0)
    error((char*)"ERROR opening socket");

  // bind socket to address and port number
  bzero((char *) &serv_addr, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(port);
  if (::bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    error((char*)"ERROR on bind");

  // listen for client to make a connection
  if (::listen(sockfd, BACKLOG) < 0)
    error((char*)"ERROR on listen");

  // accept a request from client
  newsockfd = ::accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
  if (newsockfd < 0)
    error((char*)"ERROR on accept");

  // mount the file system
  FileSys fs;
  fs.mount(newsockfd);

  // get the command from the client and invoke the file system operation
	// which returns the results or error messages back to the client until
	// the client closes the TCP connection.
  int n;
  while (1) {
		bzero(buffer, BUFFER_LENGTH);
    n = recv(newsockfd, buffer, sizeof(buffer), 0);

    fs.execute_command(buffer);

    if (n == 0) {
      perror("Connection closed");
			break;
    }
  }
  close(newsockfd);

  // close the listening socket
  close(sockfd);

  // unmount the file system
  fs.unmount();

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x868, %rsp            # imm = 0x868
cmpl $0x1, %edi
jg 0x5e66
movq 0x718a(%rip), %rdi      # 0xcfc8
leaq 0x4624(%rip), %rsi      # 0xa469
movl $0x19, %edx
callq 0x3310
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x868, %rsp            # imm = 0x868
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rsi), %rdi
callq 0x33e0
movl %eax, %ebp
movq 0x7150(%rip), %rbx      # 0xcfc8
leaq 0x4604(%rip), %rsi      # 0xa483
movl $0x13, %edx
movq %rbx, %rdi
callq 0x3310
movq %rbx, %rdi
movl %ebp, %esi
callq 0x3430
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x31e0
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x30a0
testl %eax, %eax
js 0x5ff8
movl %eax, %ebx
leaq 0x50(%rsp), %rsi
movq $0x0, 0x8(%rsi)
movw $0x2, (%rsi)
movl $0x0, 0x4(%rsi)
rolw $0x8, %bp
movw %bp, 0x2(%rsi)
movl %eax, %edi
movl $0x10, %edx
callq 0x3070
testl %eax, %eax
js 0x5ffd
movl %ebx, %edi
movl $0x5, %esi
callq 0x32e0
testl %eax, %eax
js 0x6002
leaq 0x40(%rsp), %rsi
leaq 0xc(%rsp), %rdx
movl %ebx, 0x8(%rsp)
movl %ebx, %edi
callq 0x30f0
testl %eax, %eax
js 0x6007
movl %eax, %ebp
leaq 0x34(%rsp), %r14
movq %r14, %rdi
movl %eax, %esi
callq 0x3af8
leaq 0x20(%rsp), %rbx
leaq 0x60(%rsp), %r15
leaq 0x10(%rsp), %r12
movl $0x800, %edx            # imm = 0x800
movq %r15, %rdi
xorl %esi, %esi
callq 0x31a0
movl $0x800, %edx            # imm = 0x800
movl %ebp, %edi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x3110
movq %rax, %r13
movq %rbx, 0x10(%rsp)
movq %r15, %rdi
callq 0x3160
leaq (%rsp,%rax), %rdx
addq $0x60, %rdx
movq %r12, %rdi
movq %r15, %rsi
callq 0x5d7e
movq %r14, %rdi
movq %r12, %rsi
callq 0x4a26
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0x5fc6
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x32c0
testl %r13d, %r13d
jne 0x5f61
leaq 0x4508(%rip), %rdi      # 0xa4da
callq 0x3250
movl %ebp, %edi
callq 0x34a0
movl 0x8(%rsp), %edi
callq 0x34a0
leaq 0x34(%rsp), %rdi
callq 0x3b1a
xorl %eax, %eax
jmp 0x5e54
callq 0x34fc
callq 0x34e8
callq 0x34d4
callq 0x34c0
movq %rax, %r14
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6026
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x32c0
movq %r14, %rdi
callq 0x3440
nop