user: Converte this assembly snippet into its equivalent C code:

```asm
<grabber_local_get>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x488,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x478(%rsp)
  xor    %eax,%eax
  lea    D74(%rip),%rax
  mov    %rax,0x10(%rsp)
  lea    D46(%rip),%rax
  mov    %rax,0x18(%rsp)
  lea    D69(%rip),%rax
  mov    %rax,0x20(%rsp)
  lea    D15(%rip),%rax
  mov    %rax,0x28(%rsp)
  lea    D19(%rip),%rax
  mov    %rax,0x30(%rsp)
  lea    D138(%rip),%rax
  mov    %rax,0x38(%rsp)
  lea    D135(%rip),%rax
  mov    %rax,0x40(%rsp)
  lea    D57(%rip),%rax
  mov    %rax,0x48(%rsp)
  lea    D78(%rip),%rax
  mov    %rax,0x50(%rsp)
  lea    D89(%rip),%rax
  mov    %rax,0x58(%rsp)
  lea    D98(%rip),%rax
  mov    %rax,0x60(%rsp)
  lea    D70(%rip),%rax
  mov    %rax,0x68(%rsp)
  test   %rdi,%rdi
  je     L13
  mov    %rdi,%rbx
  mov    $0x2f,%esi
  call   <strrchr@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L13
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%ebp
  mov    %r12,%rdi
  call   <strlen@plt>
  mov    %ebp,%esi
  sub    %eax,%esi
  mov    %rbx,%rdi
  call   <strndup@plt>
  mov    %rax,%r12
  mov    $0x2e,%esi
  mov    %rbx,%rdi
  call   <strrchr@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L96
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %eax,%ebp
  mov    %r12,%rdi
  call   <strlen@plt>
  sub    %eax,%ebp
  mov    %r13,%rdi
  call   <strlen@plt>
  mov    %eax,%r13d
  mov    %r12,%rdi
  call   <strlen@plt>
  sub    %r13d,%ebp
  lea    -0x1(%rbp),%esi
  cltq
  lea    0x1(%rbx,%rax,1),%rdi
  call   <strndup@plt>
  mov    %rax,%r13
  lea    0x30(%rsp),%r14
  lea    0x70(%rsp),%rax
  mov    %rax,0x8(%rsp)
  mov    %r14,%rbx
  lea    D25(%rip),%r15
L133:
  movq   $0x0,0x70(%rsp)
  movq   $0x0,0x78(%rsp)
  lea    0x80(%rsp),%rdi
  mov    $0x7e,%ecx
  mov    $0x0,%eax
  rep stos %rax,%es:(%rdi)
  lea    0x70(%rsp),%rbp
  mov    (%rbx),%r9
  mov    %r13,%r8
  mov    %r12,%rcx
  mov    %r15,%rdx
  mov    $0x400,%esi
  mov    %rbp,%rdi
  call   <snprintf@plt>
  mov    %rbp,%rdi
  call   <vh_file_exists@plt>
  test   %rax,%rax
  jne    L82
  add    $0x8,%rbx
  cmp    0x8(%rsp),%rbx
  jne    L133
  jmp    L64
L82:
  mov    %rbp,%rdi
  call   <strdup@plt>
  mov    %rax,%rbx
  jmp    L77
L44:
  mov    %rbp,%rdi
  call   <strdup@plt>
  mov    %rax,%rbx
L77:
  test   %r12,%r12
  je     L102
L61:
  mov    %r12,%rdi
  call   <free@plt>
L102:
  test   %r13,%r13
  je     L22
  mov    %r13,%rdi
  call   <free@plt>
L22:
  mov    0x478(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L153
  mov    %rbx,%rax
  add    $0x488,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L140:
  add    $0x8,%r14
  cmp    0x8(%rsp),%r14
  je     L91
L64:
  lea    0x10(%rsp),%rbx
  lea    0x30(%rsp),%r15
L16:
  movq   $0x0,0x70(%rsp)
  movq   $0x0,0x78(%rsp)
  lea    0x80(%rsp),%rdi
  mov    $0x7e,%ecx
  mov    $0x0,%eax
  rep stos %rax,%es:(%rdi)
  lea    0x70(%rsp),%rbp
  mov    (%r14),%r9
  mov    (%rbx),%r8
  mov    %r12,%rcx
  lea    D25(%rip),%rdx
  mov    $0x400,%esi
  mov    %rbp,%rdi
  call   <snprintf@plt>
  mov    %rbp,%rdi
  call   <vh_file_exists@plt>
  test   %rax,%rax
  jne    L44
  add    $0x8,%rbx
  cmp    %r15,%rbx
  jne    L16
  jmp    L140
L91:
  mov    $0x0,%ebx
  jmp    L77
L13:
  mov    $0x0,%ebx
  jmp    L22
L96:
  mov    %rax,%rbx
  test   %r12,%r12
  jne    L61
  mov    %r12,%rbx
  jmp    L22
L153:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: disassemble_data
arguments: tag: D74
type_infered: string
name: disassemble_data
arguments: tag: D46
type_infered: string
name: disassemble_data
arguments: tag: D69
type_infered: string
name: disassemble_data
arguments: tag: D15
type_infered: string
name: disassemble_data
arguments: tag: D19
type_infered: string
name: disassemble_data
arguments: tag: D138
type_infered: string
name: disassemble_data
arguments: tag: D135
type_infered: string
name: disassemble_data
arguments: tag: D57
type_infered: string
name: disassemble_data
arguments: tag: D78
type_infered: string
name: disassemble_data
arguments: tag: D89
type_infered: string
name: disassemble_data
arguments: tag: D98
type_infered: string
name: disassemble_data
arguments: tag: D70
type_infered: string
name: disassemble_data
arguments: tag: D25
type_infered: string

tool: D74: cover

tool: D46: COVER

tool: D69: front

tool: D15: FRONT

tool: D19: jpg

tool: D138: JPG

tool: D135: jpeg

tool: D57: JPEG

tool: D78: png

tool: D89: PNG

tool: D98: tbn

tool: D70: TBN

tool: D25: %s/%s.%s

assistant: ```c
char *grabber_local_get(const char *filename) {
  char *s, *dir = NULL, *file = NULL, *cv = NULL;
  unsigned int i, j;
  const char *known_filenames[] = {"cover", "COVER", "front", "FRONT"};
  const char *known_extensions[] = {"jpg", "JPG", "jpeg", "JPEG", "png", "PNG", "tbn", "TBN"};
  if (!filename)
    goto get_end;
  s = strrchr(filename, '/');
  if (!s)
    goto get_end;
  dir = strndup(filename, strlen(filename) - strlen(s));
  s = strrchr(filename, '.');
  if (!s)
    goto get_end;
  file = strndup(filename + strlen(dir) + 1, strlen(filename) - strlen(dir) - strlen(s) - 1);
  for (i = 0; i < (sizeof(known_extensions) / sizeof(known_extensions[0])); i++) {
    char cover[1024] = {0};
    snprintf(cover, sizeof(cover), "%s/%s.%s", dir, file, known_extensions[i]);
    if (vh_file_exists(cover)) {
      cv = strdup(cover);
      goto get_end;
    }
  }
  for (i = 0; i < (sizeof(known_extensions) / sizeof(known_extensions[0])); i++)
    for (j = 0; j < (sizeof(known_filenames) / sizeof(known_filenames[0])); j++) {
      char cover[1024] = {0};
      snprintf(cover, sizeof(cover), "%s/%s.%s", dir, known_filenames[j], known_extensions[i]);
      if (vh_file_exists(cover)) {
        cv = strdup(cover);
        goto get_end;
      }
    }
get_end:
  if (dir)
    free(dir);
  if (file)
    free(file);
  return cv;
}
```