user: Translate the below assembly code into C programming language:

```asm
<sh>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %edi,-0x24(%rbp)
  mov    %esi,-0x28(%rbp)
L86:
  cmpl   $0x0,-0x28(%rbp)
  je     L90
  lea    D23(%rip),%rax
  mov    %rax,%rsi
  mov    $0x1,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
L90:
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  mov    $0x0,%eax
  call   <readline@plt>
  cltq
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  jne    L91
  mov    $0x0,%eax
  jmp    L96
L91:
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <tokenize@plt>
  cltq
  mov    %rax,-0x10(%rbp)
  cmpq   $0x0,-0x10(%rbp)
  jne    L161
  lea    D59(%rip),%rax
  mov    %rax,%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  jmp    L103
L161:
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  je     L103
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  lea    D8(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  jne    L181
  mov    -0x10(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L41
  mov    $0x0,%eax
  jmp    L96
L41:
  mov    -0x10(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <atoi@plt>
  jmp    L96
L181:
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  lea    D31(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  jne    L11
  mov    -0x10(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L101
  lea    D58(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <getenv@plt>
  cltq
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  jne    L37
  lea    D54(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <chdir@plt>
  jmp    L103
L37:
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <chdir@plt>
  jmp    L103
L101:
  mov    -0x10(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <chdir@plt>
  jmp    L103
L11:
  call   <fork@plt>
  test   %eax,%eax
  je     L3
  mov    $0x0,%edi
  mov    $0x0,%eax
  call   <wait@plt>
  jmp    L103
L3:
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  mov    -0x10(%rbp),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <execvp@plt>
  lea    D28(%rip),%rax
  mov    %rax,%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  lea    D25(%rip),%rax
  mov    %rax,%rsi
  mov    $0x2,%edi
  mov    $0x0,%eax
  call   <writestr@plt>
  mov    $0xff,%edi
  call   <_exit@plt>
L103:
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  movq   $0x0,-0x18(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  movq   $0x0,-0x10(%rbp)
  jmp    L86
L96:
  leave
  ret
```

tool_calls: name: disassemble_data
arguments: tag: D23
type_guessed: string
name: disassemble_data
arguments: tag: D59
type_guessed: string
name: disassemble_data
arguments: tag: D8
type_guessed: string
name: disassemble_data
arguments: tag: D31
type_guessed: string
name: disassemble_data
arguments: tag: D58
type_guessed: string
name: disassemble_data
arguments: tag: D54
type_guessed: string
name: disassemble_data
arguments: tag: D28
type_guessed: string
name: disassemble_data
arguments: tag: D25
type_guessed: string

tool: D23: $ 

tool: D59: sh: Syntax error


tool: D8: exit

tool: D31: cd

tool: D58: HOME

tool: D54: /

tool: D28: sh: 

tool: D25: : 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;
}
```