// File: /workspace/github_c_makefile_star2_O0/sfeakes[P]unifi-motion/mongoose.c
// Function: mg_uri_to_local_path
MG_INTERNAL int mg_uri_to_local_path(struct http_message *hm,
                                     const struct mg_serve_http_opts *opts,
                                     char **local_path,
                                     struct mg_str *remainder) {
  int ok = 1;
  const char *cp = hm->uri.p, *cp_end = hm->uri.p + hm->uri.len;
  struct mg_str root = {NULL, 0};
  const char *file_uri_start = cp;
  *local_path = NULL;
  remainder->p = NULL;
  remainder->len = 0;

  { /* 1. Determine which root to use. */

#if MG_ENABLE_HTTP_URL_REWRITES
    const char *rewrites = opts->url_rewrites;
#else
    const char *rewrites = "";
#endif
    struct mg_str *hh = mg_get_http_header(hm, "Host");
    struct mg_str a, b;
    /* Check rewrites first. */
    while ((rewrites = mg_next_comma_list_entry(rewrites, &a, &b)) != NULL) {
      if (a.len > 1 && a.p[0] == '@') {
        /* Host rewrite. */
        if (hh != NULL && hh->len == a.len - 1 &&
            mg_ncasecmp(a.p + 1, hh->p, a.len - 1) == 0) {
          root = b;
          break;
        }
      } else {
        /* Regular rewrite, URI=directory */
        int match_len = mg_match_prefix_n(a, hm->uri);
        if (match_len > 0) {
          file_uri_start = hm->uri.p + match_len;
          if (*file_uri_start == '/' || file_uri_start == cp_end) {
            /* Match ended at component boundary, ok. */
          } else if (*(file_uri_start - 1) == '/') {
            /* Pattern ends with '/', backtrack. */
            file_uri_start--;
          } else {
            /* No match: must fall on the component boundary. */
            continue;
          }
          root = b;
          break;
        }
      }
    }
    /* If no rewrite rules matched, use DAV or regular document root. */
    if (root.p == NULL) {
#if MG_ENABLE_HTTP_WEBDAV
      if (opts->dav_document_root != NULL && mg_is_dav_request(&hm->method)) {
        root.p = opts->dav_document_root;
        root.len = strlen(opts->dav_document_root);
      } else
#endif
      {
        root.p = opts->document_root;
        root.len = strlen(opts->document_root);
      }
    }
    assert(root.p != NULL && root.len > 0);
  }

  { /* 2. Find where in the canonical URI path the local path ends. */
    const char *u = file_uri_start + 1;
    char *lp = (char *) MG_MALLOC(root.len + hm->uri.len + 1);
    char *lp_end = lp + root.len + hm->uri.len + 1;
    char *p = lp, *ps;
    int exists = 1;
    if (lp == NULL) {
      ok = 0;
      goto out;
    }
    memcpy(p, root.p, root.len);
    p += root.len;
    if (*(p - 1) == DIRSEP) p--;
    *p = '\0';
    ps = p;

    /* Chop off URI path components one by one and build local path. */
    while (u <= cp_end) {
      const char *next = u;
      struct mg_str component;
      if (exists) {
        cs_stat_t st;
        exists = (mg_stat(lp, &st) == 0);
        if (exists && S_ISREG(st.st_mode)) {
          /* We found the terminal, the rest of the URI (if any) is path_info.
           */
          if (*(u - 1) == '/') u--;
          break;
        }
      }
      if (u >= cp_end) break;
      parse_uri_component((const char **) &next, cp_end, "/", &component);
      if (component.len > 0) {
        int len;
        memmove(p + 1, component.p, component.len);
        len = mg_url_decode(p + 1, component.len, p + 1, lp_end - p - 1, 0);
        if (len <= 0) {
          ok = 0;
          break;
        }
        component.p = p + 1;
        component.len = len;
        if (mg_vcmp(&component, ".") == 0) {
          /* Yum. */
        } else if (mg_vcmp(&component, "..") == 0) {
          while (p > ps && *p != DIRSEP) p--;
          *p = '\0';
        } else {
          size_t i;
#ifdef _WIN32
          /* On Windows, make sure it's valid Unicode (no funny stuff). */
          wchar_t buf[MG_MAX_PATH * 2];
          if (to_wchar(component.p, buf, MG_MAX_PATH) == 0) {
            DBG(("[%.*s] smells funny", (int) component.len, component.p));
            ok = 0;
            break;
          }
#endif
          *p++ = DIRSEP;
          /* No NULs and DIRSEPs in the component (percent-encoded). */
          for (i = 0; i < component.len; i++, p++) {
            if (*p == '\0' || *p == DIRSEP
#ifdef _WIN32
                /* On Windows, "/" is also accepted, so check for that too. */
                ||
                *p == '/'
#endif
                ) {
              ok = 0;
              break;
            }
          }
        }
      }
      u = next;
    }
    if (ok) {
      *local_path = lp;
      if (u > cp_end) u = cp_end;
      remainder->p = u;
      remainder->len = cp_end - u;
    } else {
      MG_FREE(lp);
    }
  }

out:
  LOG(LL_DEBUG,
      ("'%.*s' -> '%s' + '%.*s'", (int) hm->uri.len, hm->uri.p,
       *local_path ? *local_path : "", (int) remainder->len, remainder->p));
  return ok;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x1, -0x24(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x8(%rbp), %rcx
addq 0x38(%rcx), %rax
movq %rax, -0x38(%rbp)
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x3260
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
leaq 0xb3ba(%rip), %rsi      # 0x1fe4d
callq 0x10830
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0x80(%rbp), %rdx
callq 0xa320
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
je 0x14bb6
cmpq $0x1, -0x68(%rbp)
jbe 0x14b25
movq -0x70(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x40, %eax
jne 0x14b25
cmpq $0x0, -0x60(%rbp)
je 0x14b20
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x68(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0x14b20
movq -0x70(%rbp), %rdi
addq $0x1, %rdi
movq -0x60(%rbp), %rax
movq (%rax), %rsi
movq -0x68(%rbp), %rdx
subq $0x1, %rdx
callq 0x8bf0
cmpl $0x0, %eax
jne 0x14b20
movq -0x80(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x14bb6
jmp 0x14bb1
movq -0x8(%rbp), %rax
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq 0x30(%rax), %rdx
movq 0x38(%rax), %rcx
callq 0xa510
movl %eax, -0x84(%rbp)
cmpl $0x0, -0x84(%rbp)
jle 0x14baf
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x84(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2f, %eax
je 0x14b79
movq -0x50(%rbp), %rax
cmpq -0x38(%rbp), %rax
jne 0x14b7b
jmp 0x14b9d
movq -0x50(%rbp), %rax
movsbl -0x1(%rax), %eax
cmpl $0x2f, %eax
jne 0x14b96
movq -0x50(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x14b9b
jmp 0x14a9c
jmp 0x14b9d
movq -0x80(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x14bb6
jmp 0x14bb1
jmp 0x14a9c
cmpq $0x0, -0x48(%rbp)
jne 0x14bd8
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x3180
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x14be8
cmpq $0x0, -0x40(%rbp)
jbe 0x14be8
jmp 0x14c07
leaq 0xb9a2(%rip), %rdi      # 0x20591
leaq 0xa954(%rip), %rsi      # 0x1f54a
movl $0x1e73, %edx           # imm = 0x1E73
leaq 0xb9ae(%rip), %rcx      # 0x205b0
callq 0x3230
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
movq -0x40(%rbp), %rdi
movq -0x8(%rbp), %rax
addq 0x38(%rax), %rdi
addq $0x1, %rdi
callq 0x3420
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
addq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
addq 0x38(%rcx), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xa8(%rbp)
movl $0x1, -0xb4(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0x14c7e
movl $0x0, -0x24(%rbp)
jmp 0x14fd2
movq -0xa8(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x33b0
movq -0x40(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movsbl -0x1(%rax), %eax
cmpl $0x2f, %eax
jne 0x14cc6
movq -0xa8(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movb $0x0, (%rax)
movq -0xa8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x38(%rbp), %rax
ja 0x14f72
movq -0x90(%rbp), %rax
movq %rax, -0xc0(%rbp)
cmpl $0x0, -0xb4(%rbp)
je 0x14d6e
movq -0x98(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x12330
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0xb4(%rbp)
cmpl $0x0, -0xb4(%rbp)
je 0x14d6c
movl -0x148(%rbp), %eax
andl $0xf000, %eax           # imm = 0xF000
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x14d6c
movq -0x90(%rbp), %rax
movsbl -0x1(%rax), %eax
cmpl $0x2f, %eax
jne 0x14d67
movq -0x90(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x14f72
jmp 0x14d6e
movq -0x90(%rbp), %rax
cmpq -0x38(%rbp), %rax
jb 0x14d80
jmp 0x14f72
movq -0x38(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
leaq 0xb306(%rip), %rdx      # 0x20098
leaq -0xd0(%rbp), %rcx
callq 0xfc10
cmpq $0x0, -0xc8(%rbp)
jbe 0x14f5f
movq -0xa8(%rbp), %rdi
addq $0x1, %rdi
movq -0xd0(%rbp), %rsi
movq -0xc8(%rbp), %rdx
callq 0x3540
movq -0xa8(%rbp), %rdi
addq $0x1, %rdi
movq -0xc8(%rbp), %rax
movl %eax, %esi
movq -0xa8(%rbp), %rdx
addq $0x1, %rdx
movq -0xa0(%rbp), %rax
movq -0xa8(%rbp), %rcx
subq %rcx, %rax
subq $0x1, %rax
movl %eax, %ecx
xorl %r8d, %r8d
callq 0x124c0
movl %eax, -0x164(%rbp)
cmpl $0x0, -0x164(%rbp)
jg 0x14e23
movl $0x0, -0x24(%rbp)
jmp 0x14f72
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd0(%rbp)
movslq -0x164(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq -0xd0(%rbp), %rdi
leaq 0xab3a(%rip), %rsi      # 0x1f98b
callq 0x8ad0
cmpl $0x0, %eax
jne 0x14e60
jmp 0x14f5d
leaq -0xd0(%rbp), %rdi
leaq 0xab1c(%rip), %rsi      # 0x1f98a
callq 0x8ad0
cmpl $0x0, %eax
jne 0x14ed7
jmp 0x14e7a
movq -0xa8(%rbp), %rcx
xorl %eax, %eax
cmpq -0xb0(%rbp), %rcx
movb %al, -0x171(%rbp)
jbe 0x14ea8
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2f, %eax
setne %al
movb %al, -0x171(%rbp)
movb -0x171(%rbp), %al
testb $0x1, %al
jne 0x14eb4
jmp 0x14ec8
movq -0xa8(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x14e7a
movq -0xa8(%rbp), %rax
movb $0x0, (%rax)
jmp 0x14f5b
movq -0xa8(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0xa8(%rbp)
movb $0x2f, (%rax)
movq $0x0, -0x170(%rbp)
movq -0x170(%rbp), %rax
cmpq -0xc8(%rbp), %rax
jae 0x14f59
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x14f28
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2f, %eax
jne 0x14f31
movl $0x0, -0x24(%rbp)
jmp 0x14f59
jmp 0x14f33
movq -0x170(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x170(%rbp)
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x14efa
jmp 0x14f5b
jmp 0x14f5d
jmp 0x14f5f
movq -0xc0(%rbp), %rax
movq %rax, -0x90(%rbp)
jmp 0x14cde
cmpl $0x0, -0x24(%rbp)
je 0x14fc4
movq -0x98(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x90(%rbp), %rax
cmpq -0x38(%rbp), %rax
jbe 0x14f9e
movq -0x38(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
movq -0x90(%rbp), %rax
subq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x14fd0
movq -0x98(%rbp), %rdi
callq 0x3050
jmp 0x14fd2
jmp 0x14fd4
movl $0x3, %edi
leaq 0xb63d(%rip), %rsi      # 0x2061d
leaq 0xa563(%rip), %rdx      # 0x1f54a
callq 0x4650
cmpl $0x0, %eax
je 0x1506c
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movl %eax, -0x184(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x180(%rbp)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
je 0x15028
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x190(%rbp)
jmp 0x15038
leaq 0xb77c(%rip), %rax      # 0x207ab
movq %rax, -0x190(%rbp)
jmp 0x15038
movq -0x180(%rbp), %rdx
movl -0x184(%rbp), %esi
movq -0x190(%rbp), %rcx
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl %eax, %r8d
movq -0x20(%rbp), %rax
movq (%rax), %r9
leaq 0xb5cd(%rip), %rdi      # 0x20632
movb $0x0, %al
callq 0x47a0
jmp 0x1506e
movl -0x24(%rbp), %eax
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
nopw (%rax,%rax)