// File: /workspace/github_cpp_makefile_star2_O2/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 0x54ef
movq 0x5af2(%rip), %rdi      # 0xafc0
leaq 0x2f44(%rip), %rsi      # 0x8419
callq 0x3270
pushq $-0x1
popq %rax
addq $0x868, %rsp            # imm = 0x868
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rsi), %rdi
callq 0x33a0
movl %eax, %ebp
movq 0x5abf(%rip), %rdi      # 0xafc0
leaq 0x2f2b(%rip), %rsi      # 0x8433
callq 0x3270
movq %rax, %rdi
movl %ebp, %esi
callq 0x3400
movq %rax, %rdi
callq 0x3160
pushq $0x2
popq %rdi
pushq $0x1
popq %rsi
xorl %edx, %edx
callq 0x30a0
testl %eax, %eax
js 0x5627
movl %eax, %ebx
leaq 0x50(%rsp), %rsi
andq $0x0, 0x8(%rsi)
movw $0x2, (%rsi)
andl $0x0, 0x4(%rsi)
rolw $0x8, %bp
movw %bp, 0x2(%rsi)
pushq $0x10
popq %rdx
movl %eax, %edi
callq 0x3060
testl %eax, %eax
js 0x5633
pushq $0x5
popq %rsi
movl %ebx, %edi
callq 0x32c0
testl %eax, %eax
js 0x563f
leaq 0x40(%rsp), %rsi
leaq 0x10(%rsp), %rdx
movl %ebx, 0xc(%rsp)
movl %ebx, %edi
callq 0x30e0
testl %eax, %eax
js 0x564b
movl %eax, %ebp
leaq 0x14(%rsp), %r14
movq %r14, %rdi
movl %eax, %esi
callq 0x39a8
leaq 0x60(%rsp), %r15
leaq 0x20(%rsp), %r12
leaq 0xb(%rsp), %r13
movl $0x800, %edx            # imm = 0x800
movq %r15, %rdi
xorl %esi, %esi
callq 0x3190
movl $0x800, %edx            # imm = 0x800
movl %ebp, %edi
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x3100
movq %rax, %rbx
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x5296
movq %r14, %rdi
movq %r12, %rsi
callq 0x47fa
movq %r12, %rdi
callq 0x3498
testl %ebx, %ebx
jne 0x55b2
leaq 0x2e89(%rip), %rdi      # 0x848a
callq 0x3230
movl %ebp, %edi
callq 0x3480
movl 0xc(%rsp), %edi
callq 0x3480
leaq 0x14(%rsp), %rdi
callq 0x39ca
xorl %eax, %eax
jmp 0x54dd
leaq 0x2e19(%rip), %rdi      # 0x8447
callq 0x54a4
leaq 0x2e22(%rip), %rdi      # 0x845c
callq 0x54a4
leaq 0x2e24(%rip), %rdi      # 0x846a
callq 0x54a4
leaq 0x2e28(%rip), %rdi      # 0x847a
callq 0x54a4
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3498
movq %rbx, %rdi
callq 0x3410