// File: 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
movq %rsp, %rbp
subq $0x940, %rsp            # imm = 0x940
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x5, -0x14(%rbp)
movl $0x800, -0x18(%rbp)     # imm = 0x800
cmpl $0x2, -0x8(%rbp)
jge 0x714c
movq 0x8e8c(%rip), %rdi      # 0xffc0
leaq 0x52de(%rip), %rsi      # 0xc419
callq 0x3340
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7385
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x34e0
movl %eax, -0x24(%rbp)
movq 0x8e5d(%rip), %rdi      # 0xffc0
leaq 0x52c9(%rip), %rsi      # 0xc433
callq 0x3340
movq %rax, %rdi
movl -0x24(%rbp), %esi
callq 0x3550
movq %rax, %rdi
movq 0x8e24(%rip), %rsi      # 0xffa8
callq 0x3390
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x30e0
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jge 0x71af
leaq 0x529d(%rip), %rdi      # 0xc447
callq 0x70e0
leaq -0x840(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x31f0
movw $0x2, -0x840(%rbp)
movl $0x0, -0x83c(%rbp)
movl -0x24(%rbp), %eax
movzwl %ax, %edi
callq 0x3070
movw %ax, -0x83e(%rbp)
movl -0x1c(%rbp), %edi
leaq -0x840(%rbp), %rsi
movl $0x10, %edx
callq 0x3090
cmpl $0x0, %eax
jge 0x720c
leaq 0x5255(%rip), %rdi      # 0xc45c
callq 0x70e0
movl -0x1c(%rbp), %edi
movl $0x5, %esi
callq 0x33e0
cmpl $0x0, %eax
jge 0x722a
leaq 0x5245(%rip), %rdi      # 0xc46a
callq 0x70e0
movl -0x1c(%rbp), %edi
leaq -0x850(%rbp), %rsi
leaq -0x28(%rbp), %rdx
callq 0x3120
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0x7252
leaq 0x522d(%rip), %rdi      # 0xc47a
callq 0x70e0
movl -0x20(%rbp), %esi
leaq -0x8e0(%rbp), %rdi
callq 0x3f60
leaq -0x830(%rbp), %rdi
movq %rdi, -0x930(%rbp)
xorl %esi, %esi
movl %esi, -0x934(%rbp)
movl $0x800, %edx            # imm = 0x800
movq %rdx, -0x940(%rbp)
callq 0x31f0
movq -0x940(%rbp), %rdx
movl -0x934(%rbp), %ecx
movq -0x930(%rbp), %rsi
movl -0x20(%rbp), %edi
callq 0x3140
movl %eax, -0x8e4(%rbp)
leaq -0x909(%rbp), %rdi
movq %rdi, -0x928(%rbp)
callq 0x3570
movq -0x930(%rbp), %rsi
movq -0x928(%rbp), %rdx
leaq -0x908(%rbp), %rdi
callq 0x69b0
jmp 0x72d9
leaq -0x8e0(%rbp), %rdi
leaq -0x908(%rbp), %rsi
callq 0x5500
jmp 0x72ee
leaq -0x908(%rbp), %rdi
callq 0x3628
leaq -0x909(%rbp), %rdi
callq 0x33b0
cmpl $0x0, -0x8e4(%rbp)
jne 0x735d
leaq 0x5174(%rip), %rdi      # 0xc48a
callq 0x32e0
jmp 0x7362
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x918(%rbp)
movl %eax, -0x91c(%rbp)
jmp 0x734f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x918(%rbp)
movl %eax, -0x91c(%rbp)
leaq -0x908(%rbp), %rdi
callq 0x3628
leaq -0x909(%rbp), %rdi
callq 0x33b0
jmp 0x7391
jmp 0x7261
movl -0x20(%rbp), %edi
callq 0x35f0
movl -0x1c(%rbp), %edi
callq 0x35f0
leaq -0x8e0(%rbp), %rdi
callq 0x3fa0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x940, %rsp            # imm = 0x940
popq %rbp
retq
movq -0x918(%rbp), %rdi
callq 0x3560
nopl (%rax)