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

```asm
<packet_buildtext>:
  endbr64
  push   %r14
  mov    %rdi,%r14
  push   %r13
  mov    %r8,%r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x20,%rsp
  mov    %sil,0xc(%rsp)
  mov    %dl,0x8(%rsp)
  mov    %cl,0x4(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  movb   $0x41,0x15(%rsp)
  movb   $0x1b,0x16(%rsp)
  movb   $0x30,0x17(%rsp)
  test   %r8,%r8
  je     L37
  mov    %r8,%rdi
  call   <strlen@plt>
  mov    %rax,%r12
  lea    0x5(%rax),%rbp
  cmp    $0x1000,%rax
  ja     L87
L26:
  cmpb   $0x0,0x4(%rsp)
  je     L70
  lea    0x6(%r12),%rbp
L70:
  mov    $0x1,%esi
  mov    %rbp,%rdi
  call   <calloc@plt>
  lea    0x15(%rsp),%rsi
  mov    $0x1,%edx
  mov    %rax,%rbx
  mov    %rax,%rdi
  call   <memcpy@plt>
  lea    0xc(%rsp),%rsi
  lea    0x1(%rbx),%rdi
  mov    $0x1,%edx
  call   <memcpy@plt>
  lea    0x16(%rsp),%rsi
  lea    0x2(%rbx),%rdi
  mov    $0x1,%edx
  call   <memcpy@plt>
  lea    0x17(%rsp),%rsi
  lea    0x3(%rbx),%rdi
  mov    $0x1,%edx
  call   <memcpy@plt>
  lea    0x4(%rbx),%rdi
  lea    0x8(%rsp),%rsi
  mov    $0x1,%edx
  call   <memcpy@plt>
  cmpb   $0x0,0x4(%rsp)
  mov    $0x5,%edi
  jne    L41
L5:
  test   %r12,%r12
  jne    L30
L39:
  mov    %rbx,(%r14)
  mov    %ebp,%eax
  mov    0x18(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L27
  add    $0x20,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
  nopl   0x0(%rax,%rax,1)
L87:
  mov    $0x1000,%esi
  lea    D9(%rip),%rdi
  mov    $0x1005,%ebp
  mov    $0x1000,%r12d
  call   <config_error@plt>
  jmp    L26
  nopl   0x0(%rax)
L30:
  add    %rbx,%rdi
  mov    %r12,%rdx
  mov    %r13,%rsi
  call   <memcpy@plt>
  jmp    L39
L41:
  lea    0x5(%rbx),%rdi
  lea    0x4(%rsp),%rsi
  mov    $0x1,%edx
  call   <memcpy@plt>
  mov    $0x6,%edi
  jmp    L5
  nopw   0x0(%rax,%rax,1)
L37:
  mov    $0x5,%ebp
  xor    %r12d,%r12d
  jmp    L26
L27:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: parse_data
arguments: data_tag: D9
data_type: string

tool: D9: Warning: shrank a text frame to fit %d bytes.

assistant: ```c
int packet_buildtext(char **outputptr, char filename, char mode, char special, char *text) {
  const char cmdcode = 'A', modedivider = 0x1b, position = 0x30;
  size_t textlen = 0;
  if (text != NULL) {
    textlen = strlen(text);
  }
  if (textlen > 4096) {
    config_error("Warning: shrank a text frame to fit %d bytes.", 4096);
    textlen = 4096;
  }
  size_t pktsize = sizeof(cmdcode) + sizeof(filename) + sizeof(modedivider) + sizeof(position) + sizeof(mode) + textlen;
  if (special != 0) {
    pktsize += sizeof(special);
  }
  char *data = (char *)calloc(pktsize, sizeof(char));
  size_t offset = 0;
  memcpy(&data[offset], &cmdcode, sizeof(cmdcode));
  offset = sizeof(cmdcode);
  memcpy(&data[offset], &filename, sizeof(filename));
  offset += sizeof(filename);
  memcpy(&data[offset], &modedivider, sizeof(modedivider));
  offset += sizeof(modedivider);
  memcpy(&data[offset], &position, sizeof(position));
  offset += sizeof(position);
  memcpy(&data[offset], &mode, sizeof(mode));
  offset += sizeof(mode);
  if (special != 0) {
    memcpy(&data[offset], &special, sizeof(special));
    offset += sizeof(special);
  }
  if (textlen > 0) {
    memcpy(&data[offset], text, textlen);
  }
  *outputptr = data;
  return pktsize;
}
```