user: Demonstrate the C code that generates the assembly output below:

```asm
<write_utmp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xa0,%rsp
  mov    %rdi,-0x78(%rbp)
  mov    %rsi,-0x80(%rbp)
  mov    %edx,-0x84(%rbp)
  mov    %ecx,-0x88(%rbp)
  mov    %r8,-0x90(%rbp)
  mov    %r9,-0x98(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    D17(%rip),%rax
  mov    (%rax),%edx
  mov    D49(%rip),%rax
  mov    (%rax),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <access@plt>
  test   %rax,%rax
  js     L62
  lea    -0x60(%rbp),%rax
  mov    $0x28,%edx
  mov    $0x0,%esi
  mov    %rax,%rdi
  call   <memset@plt>
  mov    -0x88(%rbp),%eax
  mov    %eax,-0x60(%rbp)
  mov    -0x84(%rbp),%eax
  mov    %eax,-0x5c(%rbp)
  mov    -0x58(%rbp),%rax
  mov    -0x80(%rbp),%rcx
  mov    $0x8,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  lea    -0x60(%rbp),%rax
  add    $0x20,%rax
  mov    %rax,%rdi
  call   <time@plt>
  mov    D16(%rip),%rax
  mov    (%rax),%edx
  mov    -0x50(%rbp),%rax
  mov    -0x78(%rbp),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  cmpq   $0x0,-0x90(%rbp)
  je     L68
  mov    D29(%rip),%rax
  mov    (%rax),%edx
  mov    -0x48(%rbp),%rax
  mov    -0x90(%rbp),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
L68:
  mov    D12(%rip),%rax
  mov    (%rax),%eax
  cmp    %eax,-0x88(%rbp)
  jne    L57
  mov    $0x0,%eax
  call   <setutent@plt>
  mov    -0x60(%rbp),%rax
  mov    -0x58(%rbp),%rdx
  mov    %rax,-0x30(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    -0x50(%rbp),%rax
  mov    -0x48(%rbp),%rdx
  mov    %rax,-0x20(%rbp)
  mov    %rdx,-0x18(%rbp)
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  lea    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <getutid@plt>
  mov    %rax,-0x68(%rbp)
  cmpq   $0x0,-0x68(%rbp)
  je     L57
  mov    D29(%rip),%rax
  mov    (%rax),%edx
  mov    -0x68(%rbp),%rax
  mov    0x18(%rax),%rcx
  mov    -0x48(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  cmpq   $0x0,-0x98(%rbp)
  je     L57
  mov    D29(%rip),%rax
  mov    (%rax),%edx
  mov    -0x68(%rbp),%rax
  mov    0x18(%rax),%rcx
  mov    -0x98(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
L57:
  mov    $0x0,%eax
  call   <setutent@plt>
  lea    -0x60(%rbp),%rax
  mov    %rax,%rdi
  call   <pututline@plt>
  mov    $0x0,%eax
  call   <endutent@plt>
  jmp    L37
L62:
  nop
L37:
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L20
  call   <__stack_chk_fail@plt>
L20:
  leave
  ret
```

assistant: ```c
void write_utmp(char *user, char *id, int pid, int type, char *line, char *oldline) {
  struct utmp utmp;
  struct utmp tmp;
  struct utmp *utmptr;
  struct timeval tv;
  if (access(UTMP_FILE, W_OK) < 0)
    return;
  memset(&utmp, 0, sizeof(utmp));
  utmp.ut_type = type;
  utmp.ut_pid = pid;
  strncpy(utmp.ut_id, id, sizeof(utmp.ut_id));
  time(&utmp.ut_time);
  strncpy(utmp.ut_user, user, UT_NAMESIZE);
  if (line)
    strncpy(utmp.ut_line, line, UT_LINESIZE);
  if (type == DEAD_PROCESS) {
    setutent();
    tmp = utmp;
    if ((utmptr = getutid(&tmp)) != NULL) {
      strncpy(utmp.ut_line, utmptr->ut_line, UT_LINESIZE);
      if (oldline)
        strncpy(oldline, utmptr->ut_line, UT_LINESIZE);
    }
  }
  setutent();
  pututline(&utmp);
  endutent();
}
```