user: What is the c source code of the assembly code below?

```asm
<_atob>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %edx,-0x54(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x30,%al
  jne    L285
  mov    -0x50(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x78,%al
  je     L201
  mov    -0x50(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x58,%al
  jne    L285
L201:
  movl   $0x10,-0x54(%rbp)
  addq   $0x2,-0x50(%rbp)
L285:
  cmpl   $0x10,-0x54(%rbp)
  jne    L181
  mov    -0x50(%rbp),%rax
  mov    $0x2e,%esi
  mov    %rax,%rdi
  call   <strchr@plt>
  mov    %rax,-0x28(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  je     L181
  mov    -0x28(%rbp),%rax
  sub    -0x50(%rbp),%rax
  cmp    $0x13,%rax
  jbe    L59
  mov    $0x0,%eax
  jmp    L29
L59:
  mov    -0x28(%rbp),%rax
  sub    -0x50(%rbp),%rax
  mov    %eax,%edx
  mov    -0x50(%rbp),%rcx
  lea    -0x20(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  mov    -0x28(%rbp),%rax
  sub    -0x50(%rbp),%rax
  movb   $0x0,-0x20(%rbp,%rax,1)
  lea    -0x20(%rbp),%rcx
  lea    -0x38(%rbp),%rax
  mov    $0x10,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <_atob>
  test   %eax,%eax
  jne    L241
  mov    $0x0,%eax
  jmp    L29
L241:
  addq   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%rax
  mov    $0x2e,%esi
  mov    %rax,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L103
  mov    $0x0,%eax
  jmp    L29
L103:
  mov    -0x28(%rbp),%rcx
  lea    -0x34(%rbp),%rax
  mov    $0x10,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <_atob>
  test   %eax,%eax
  jne    L283
  mov    $0x0,%eax
  jmp    L29
L283:
  mov    -0x38(%rbp),%eax
  shl    $0x10,%eax
  mov    %eax,%edx
  mov    -0x34(%rbp),%eax
  add    %eax,%edx
  mov    -0x48(%rbp),%rax
  mov    %edx,(%rax)
  mov    $0x1,%eax
  jmp    L29
L181:
  mov    -0x48(%rbp),%rax
  movl   $0x0,(%rax)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x30(%rbp)
  jmp    L44
L227:
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jle    L269
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jg     L269
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sub    $0x30,%eax
  mov    %eax,-0x2c(%rbp)
  jmp    L124
L269:
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x60,%al
  jle    L26
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x66,%al
  jg     L26
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sub    $0x57,%eax
  mov    %eax,-0x2c(%rbp)
  jmp    L124
L26:
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x40,%al
  jle    L172
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x46,%al
  jg     L172
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sub    $0x37,%eax
  mov    %eax,-0x2c(%rbp)
  jmp    L124
L172:
  mov    $0x0,%eax
  jmp    L29
L124:
  mov    -0x2c(%rbp),%eax
  cmp    -0x54(%rbp),%eax
  jl     L122
  mov    $0x0,%eax
  jmp    L29
L122:
  mov    -0x30(%rbp),%eax
  imul   -0x54(%rbp),%eax
  mov    %eax,-0x30(%rbp)
  mov    -0x2c(%rbp),%eax
  add    %eax,-0x30(%rbp)
  addq   $0x1,-0x50(%rbp)
L44:
  mov    -0x50(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L227
  mov    -0x48(%rbp),%rax
  mov    -0x30(%rbp),%edx
  mov    %edx,(%rax)
  mov    $0x1,%eax
L29:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L35
  call   <__stack_chk_fail@plt>
L35:
  leave
  ret
```

assistant: ```c
int _atob(uint64_t *vp, char *p, int base) {
  uint64_t value, v1, v2;
  char *q, tmp[20];
  int digit;
  if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
    base = 16;
    p += 2;
  }
  if (base == 16 && (q = strchr(p, '.')) != 0) {
    if (q - p > sizeof(tmp) - 1)
      return (0);
    strncpy(tmp, p, q - p);
    tmp[q - p] = '\0';
    if (!_atob(&v1, tmp, 16))
      return (0);
    q++;
    if (strchr(q, '.'))
      return (0);
    if (!_atob(&v2, q, 16))
      return (0);
    *vp = (v1 << 16) + v2;
    return (1);
  }
  value = *vp = 0;
  for (; *p; p++) {
    if (*p >= '0' && *p <= '9')
      digit = *p - '0';
    else if (*p >= 'a' && *p <= 'f')
      digit = *p - 'a' + 10;
    else if (*p >= 'A' && *p <= 'F')
      digit = *p - 'A' + 10;
    else
      return (0);
    if (digit >= base)
      return (0);
    value *= base;
    value += digit;
  }
  *vp = value;
  return (1);
}
```