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

```asm
<sh>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    %edi,%r14d
  mov    %esi,%r13d
  lea    D31(%rip),%r15
  jmp    L3
L103:
  lea    D69(%rip),%rsi
  mov    $0x1,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  jmp    L99
L154:
  lea    D62(%rip),%rsi
  mov    $0x2,%edi
  call   <writestr@plt>
L53:
  mov    %rbx,%rdi
  call   <free@plt>
  mov    %rbp,%rdi
  call   <free@plt>
L3:
  test   %r13d,%r13d
  jne    L103
L99:
  mov    %r14d,%edi
  mov    $0x0,%eax
  call   <readline@plt>
  movslq %eax,%rbx
  test   %eax,%eax
  je     L15
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %rax,%rsi
  mov    %rbx,%rdi
  mov    $0x0,%eax
  call   <tokenize@plt>
  movslq %eax,%rbp
  test   %eax,%eax
  je     L154
  mov    0x0(%rbp),%r12
  test   %r12,%r12
  je     L53
  mov    %r15,%rsi
  mov    %r12,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  je     L57
  lea    D34(%rip),%rsi
  mov    %r12,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  jne    L83
  mov    0x8(%rbp),%rdi
  test   %rdi,%rdi
  je     L79
  mov    $0x0,%eax
  call   <chdir@plt>
  jmp    L53
L57:
  mov    0x8(%rbp),%rdi
  test   %rdi,%rdi
  je     L15
  call   <atoi@plt>
L15:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L79:
  lea    D22(%rip),%rdi
  call   <getenv@plt>
  test   %eax,%eax
  jne    L123
  lea    D24(%rip),%rdi
  call   <chdir@plt>
  jmp    L53
L123:
  movslq %eax,%rdi
  mov    $0x0,%eax
  call   <chdir@plt>
  jmp    L53
L83:
  call   <fork@plt>
  test   %eax,%eax
  je     L67
  mov    $0x0,%edi
  mov    $0x0,%eax
  call   <wait@plt>
  jmp    L53
L67:
  mov    %rbp,%rsi
  mov    0x0(%rbp),%rdi
  call   <execvp@plt>
  lea    D66(%rip),%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  mov    0x0(%rbp),%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  lea    D55(%rip),%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  mov    $0xff,%edi
  call   <_exit@plt>
```

tool_calls: name: disassemble_data
arguments: data_label: D31
data_type: string
name: disassemble_data
arguments: data_label: D69
data_type: string
name: disassemble_data
arguments: data_label: D62
data_type: string
name: disassemble_data
arguments: data_label: D34
data_type: string
name: disassemble_data
arguments: data_label: D22
data_type: string
name: disassemble_data
arguments: data_label: D24
data_type: string
name: disassemble_data
arguments: data_label: D66
data_type: string
name: disassemble_data
arguments: data_label: D55
data_type: string

tool: D31: exit

tool: D69: $ 

tool: D62: sh: Syntax error


tool: D34: cd

tool: D22: HOME

tool: D24: /

tool: D66: sh: 

tool: D55: : Not found


assistant: ```c
int sh(int f, int interactive) {
  char *line, **newargv, *tmpstr;
  for (;;) {
    if (interactive)
      writestr(1, "$ ");
    if ((line = readline(f)) == 0)
      return 0;
    if ((newargv = tokenize(line, strlen(line))) == 0)
      writestr(2, "sh: Syntax error\n");
    else if (*newargv != 0) {
      if (!strcmp(newargv[0], "exit")) {
        if (newargv[1] == 0)
          return 0;
        else
          return atoi(newargv[1]);
      } else if (!strcmp(newargv[0], "cd")) {
        if (newargv[1] == 0) {
          if ((tmpstr = getenv("HOME")) == 0)
            chdir("/");
          else
            chdir(tmpstr);
        } else
          chdir(newargv[1]);
      } else {
        if (fork())
          wait(0);
        else {
          execvp(newargv[0], newargv);
          writestr(2, "sh: ");
          writestr(2, newargv[0]);
          writestr(2, ": Not found\n");
          _exit(255);
        }
      }
    }
    free(line);
    line = 0;
    free(newargv);
    newargv = 0;
  }
  return 0;
}
```