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

```asm
<WriteLog>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0xf8,%rsp
  mov    %edi,%ebx
  mov    %rsi,0x8(%rsp)
  mov    %edx,0x14(%rsp)
  mov    %rcx,0x18(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0xe8(%rsp)
  xor    %eax,%eax
  lea    D12(%rip),%rdi
  call   <getenv@plt>
  mov    $0x0,%r13d
  test   %rax,%rax
  je     L150
  mov    %rax,%rdi
  call   <atoi@plt>
  mov    %eax,%r13d
L150:
  lea    D77(%rip),%rdi
  call   <getenv@plt>
  test   %rax,%rax
  je     L71
  mov    %rax,%rdi
  call   <atoi@plt>
L71:
  lea    D132(%rip),%rdi
  call   <getenv@plt>
  test   %rax,%rax
  je     L52
  mov    %rax,%rdi
  call   <atoi@plt>
L52:
  lea    0x60(%rsp),%rdi
  mov    $0x81,%edx
  mov    $0x0,%esi
  call   <memset@plt>
  lea    D90(%rip),%rdi
  call   <getenv@plt>
  mov    %rax,%rsi
  test   %rax,%rax
  je     L155
  lea    0x60(%rsp),%rdi
  mov    $0x80,%edx
  call   <strncpy@plt>
L69:
  lea    0x40(%rsp),%r12
  mov    $0x20,%edx
  mov    $0x0,%esi
  mov    %r12,%rdi
  call   <memset@plt>
  lea    0x30(%rsp),%r14
  mov    $0x10,%edx
  mov    $0x0,%esi
  mov    %r14,%rdi
  call   <memset@plt>
  lea    0x24(%rsp),%rdi
  call   <ftime@plt>
  lea    0x2c(%rsp),%r15
  mov    0x24(%rsp),%ecx
  lea    D148(%rip),%rdx
  mov    $0x4,%esi
  mov    %r15,%rdi
  call   <snprintf@plt>
  lea    0x28(%rsp),%rdi
  call   <localtime@plt>
  mov    %rax,%rbp
  mov    %rax,%rcx
  lea    D45(%rip),%rdx
  mov    $0x20,%esi
  mov    %r12,%rdi
  call   <strftime@plt>
  lea    D41(%rip),%rsi
  mov    %r12,%rdi
  call   <strcat@plt>
  mov    %r15,%rsi
  mov    %r12,%rdi
  call   <strcat@plt>
  mov    %rbp,%rcx
  lea    D142(%rip),%rdx
  mov    $0x10,%esi
  mov    %r14,%rdi
  call   <strftime@plt>
  test   %r13d,%r13d
  je     L118
  cmp    %ebx,%r13d
  jg     L118
  mov    $0x0,%eax
  call   <open_log_file@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  je     L11
  cmp    $0x5,%ebx
  ja     L15
  mov    %ebx,%ebx
  lea    D49(%rip),%rdx
  movslq (%rdx,%rbx,4),%rax
  add    %rdx,%rax
  notrack jmp *%rax
L155:
  lea    0x60(%rsp),%rdi
  mov    $0x80,%edx
  lea    D9(%rip),%rsi
  call   <strncpy@plt>
  jmp    L69
  lea    0x40(%rsp),%rdx
  mov    0x14(%rsp),%r8d
  mov    0x8(%rsp),%rcx
  lea    D149(%rip),%rsi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <fprintf@plt>
L43:
  mov    0x18(%rsp),%r14
  mov    %r14,%rsi
  mov    $0x0,%ebx
  mov    %ebx,%edi
  call   <va_start@plt>
  mov    %ebx,%edx
  mov    %r14,%rsi
  mov    %rbp,%rdi
  call   <vfprintf@plt>
  mov    %ebx,%edi
  call   <va_end@plt>
  mov    %rbp,%rsi
  mov    $0xa,%edi
  call   <fputc@plt>
  mov    %rbp,%rdi
  call   <fflush@plt>
  mov    %rbp,%rdi
  call   <fclose@plt>
  mov    $0x0,%eax
  jmp    L140
  lea    0x40(%rsp),%rdx
  mov    0x14(%rsp),%r8d
  mov    0x8(%rsp),%rcx
  lea    D67(%rip),%rsi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <fprintf@plt>
  jmp    L43
  lea    0x40(%rsp),%rdx
  mov    0x14(%rsp),%r8d
  mov    0x8(%rsp),%rcx
  lea    D6(%rip),%rsi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <fprintf@plt>
  jmp    L43
  lea    0x40(%rsp),%rdx
  mov    0x14(%rsp),%r8d
  mov    0x8(%rsp),%rcx
  lea    D0(%rip),%rsi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <fprintf@plt>
  jmp    L43
  lea    0x40(%rsp),%rdx
  mov    0x14(%rsp),%r8d
  mov    0x8(%rsp),%rcx
  lea    D68(%rip),%rsi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <fprintf@plt>
  jmp    L43
L15:
  lea    0x40(%rsp),%rdx
  mov    0x14(%rsp),%r8d
  mov    0x8(%rsp),%rcx
  lea    D139(%rip),%rsi
  mov    %rbp,%rdi
  mov    $0x0,%eax
  call   <fprintf@plt>
  jmp    L43
L118:
  mov    $0x0,%eax
L140:
  mov    0xe8(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L25
  add    $0xf8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L11:
  mov    $0xffffffff,%eax
  jmp    L140
L25:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: data_tag: D12
type_guessed: string
name: unpack_data
arguments: data_tag: D77
type_guessed: string
name: unpack_data
arguments: data_tag: D132
type_guessed: string
name: unpack_data
arguments: data_tag: D90
type_guessed: string
name: unpack_data
arguments: data_tag: D148
type_guessed: string
name: unpack_data
arguments: data_tag: D45
type_guessed: string
name: unpack_data
arguments: data_tag: D41
type_guessed: string
name: unpack_data
arguments: data_tag: D142
type_guessed: string
name: unpack_data
arguments: data_tag: D9
type_guessed: string
name: unpack_data
arguments: data_tag: D149
type_guessed: string
name: unpack_data
arguments: data_tag: D67
type_guessed: string
name: unpack_data
arguments: data_tag: D6
type_guessed: string
name: unpack_data
arguments: data_tag: D0
type_guessed: string
name: unpack_data
arguments: data_tag: D68
type_guessed: string
name: unpack_data
arguments: data_tag: D139
type_guessed: string

tool: D12: LOG_MODE

tool: D77: LOG_SWITCH_MODE

tool: D132: LOG_SIZE

tool: D90: LOG_FILE_PATH

tool: D148: %03d

tool: D45: %Y-%m-%d %H:%M:%S

tool: D41: :

tool: D142: %Y%m%d%H%M%S

tool: D9: .

tool: D149: [%s][%s][%d][DEBUG]: 

tool: D67: [%s][%s][%d][INFO]: 

tool: D6: [%s][%s][%d][WARNING]: 

tool: D0: [%s][%s][%d][ERROR]: 

tool: D68: [%s][%s][%d][CRITICAL]: 

tool: D139: [%s][%s][%d]: 

assistant: ```c
int WriteLog(int log_mode, char *filename, int line_num, char *fmt, ...) {
  int param_log_mode;
  int param_log_switch_mode;
  int param_log_size;
  char param_log_file_path[128 + 1];
  struct timeb tb;
  char log_time[32];
  char date_time[16];
  char millitm[4];
  struct tm *local_tm;
  char *penv;
  FILE *fp;
  va_list ap;
  penv = getenv("LOG_MODE");
  param_log_mode = penv == NULL ? 0 : atoi(penv);
  if (param_log_mode == 0)
    param_log_mode = 0;
  penv = getenv("LOG_SWITCH_MODE");
  param_log_switch_mode = penv == NULL ? 0 : atoi(penv);
  if (param_log_switch_mode == 0)
    param_log_switch_mode = 1;
  penv = getenv("LOG_SIZE");
  param_log_size = penv == NULL ? 0 : atoi(penv);
  if (param_log_size == 0)
    param_log_size = 5;
  memset(param_log_file_path, 0, sizeof(param_log_file_path));
  penv = getenv("LOG_FILE_PATH");
  if (penv)
    strncpy(param_log_file_path, penv, 128);
  else
    strncpy(param_log_file_path, ".", 128);
  memset(log_time, 0, sizeof(log_time));
  memset(date_time, 0, sizeof(date_time));
  ftime(&tb);
  snprintf(millitm, sizeof(millitm), "%03d", tb.millitm);
  local_tm = localtime(&tb.time);
  strftime(log_time, sizeof(log_time), "%Y-%m-%d %H:%M:%S", local_tm);
  strcat(log_time, ":");
  strcat(log_time, millitm);
  strftime(date_time, sizeof(date_time), "%Y%m%d%H%M%S", local_tm);
  if (param_log_mode == 0 || log_mode < param_log_mode)
    return 0;
  fp = open_log_file();
  if (fp == NULL)
    return -1;
  switch (log_mode) {
  case 1:
    fprintf(fp, "[%s][%s][%d][DEBUG]: ", log_time, filename, line_num);
    break;
  case 2:
    fprintf(fp, "[%s][%s][%d][INFO]: ", log_time, filename, line_num);
    break;
  case 3:
    fprintf(fp, "[%s][%s][%d][WARNING]: ", log_time, filename, line_num);
    break;
  case 4:
    fprintf(fp, "[%s][%s][%d][ERROR]: ", log_time, filename, line_num);
    break;
  case 5:
    fprintf(fp, "[%s][%s][%d][CRITICAL]: ", log_time, filename, line_num);
    break;
  default:
    fprintf(fp, "[%s][%s][%d]: ", log_time, filename, line_num);
    break;
  }
  va_start(ap, fmt);
  vfprintf(fp, fmt, ap);
  va_end(ap);
  fprintf(fp, "\n");
  fflush(fp);
  fclose(fp);
  return 0;
}
```