user: Translate the below assembly code into C programming language:

```asm
<host_is_host_with_port>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %rdx,-0x58(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x30(%rbp)
  movl   $0xffffffff,-0x3c(%rbp)
  movl   $0x0,-0x38(%rbp)
  mov    -0x48(%rbp),%rax
  mov    %rax,%rdi
  call   <assert@plt>
  mov    -0x58(%rbp),%rdx
  mov    -0x50(%rbp),%rcx
  mov    -0x48(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <host_is_ipv6_with_port@plt>
  mov    %eax,-0x34(%rbp)
  cmpl   $0x0,-0x34(%rbp)
  js     L5
  cmpl   $0x0,-0x34(%rbp)
  je     L12
  mov    -0x34(%rbp),%eax
  mov    %eax,-0x3c(%rbp)
  jmp    L76
L12:
  mov    -0x48(%rbp),%rax
  mov    $0x3a,%esi
  mov    %rax,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L219
  movq   $0x0,-0x20(%rbp)
  mov    D5(%rip),%rax
  mov    (%rax),%eax
  lea    -0x40(%rbp),%rdx
  mov    -0x48(%rbp),%rcx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <inet_pton@plt>
  cmp    $0x1,%eax
  je     L182
  mov    -0x48(%rbp),%rax
  mov    %rax,%rdi
  call   <strdup@plt>
  mov    %rax,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  je     L105
  mov    -0x30(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  jmp    L23
L54:
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x28(%rbp)
L23:
  mov    -0x28(%rbp),%rax
  mov    $0x3a,%esi
  mov    %rax,%rdi
  call   <strchr@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  jne    L54
  mov    -0x20(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L69
L152:
  addq   $0x1,-0x18(%rbp)
L69:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L152
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L98
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L98
  movl   $0x1,-0x38(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  je     L80
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <strdup@plt>
  mov    %rax,%rdx
  mov    -0x50(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  je     L22
L80:
  cmpq   $0x0,-0x58(%rbp)
  je     L98
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <strdup@plt>
  mov    %rax,%rdx
  mov    -0x58(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x58(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L98
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  call   <free@plt>
  jmp    L76
L219:
  nop
  jmp    L98
L182:
  nop
L98:
  mov    -0x38(%rbp),%eax
  mov    %eax,-0x3c(%rbp)
  jmp    L76
L5:
  nop
  jmp    L76
L105:
  nop
  jmp    L76
L22:
  nop
L76:
  mov    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x3c(%rbp),%eax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L79
  call   <__stack_chk_fail@plt>
L79:
  leave
  ret
```

assistant: ```c
int host_is_host_with_port(const char *host, char **addr, char **port) {
  char *str = NULL;
  int rv = -1;
  int is_host_with_port = 0;
  int ret;
  assert(host);
  if ((ret = host_is_ipv6_with_port(host, addr, port)) < 0)
    goto cleanup;
  if (ret) {
    rv = ret;
    goto cleanup;
  }
  if (strchr(host, ':')) {
    struct sockaddr_in6 saddr;
    char *addrptr;
    char *portptr;
    char *lastcolonptr = NULL;
    char *tmp;
    if (inet_pton(AF_INET6, host, &saddr) == 1)
      goto out;
    if (!(str = strdup(host)))
      goto cleanup;
    addrptr = str;
    portptr = addrptr;
    while ((tmp = strchr(portptr, ':'))) {
      lastcolonptr = tmp;
      portptr = tmp + 1;
    }
    *lastcolonptr = '\0';
    tmp = portptr;
    while (isdigit(*tmp))
      tmp++;
    if (*tmp == '\0' && strlen(portptr)) {
      is_host_with_port = 1;
      if (addr) {
        if (!(*addr = strdup(addrptr)))
          goto cleanup;
      }
      if (port) {
        if (!(*port = strdup(portptr))) {
          free(*addr);
          goto cleanup;
        }
      }
    }
  }
out:
  rv = is_host_with_port;
cleanup:
  free(str);
  return (rv);
}
```