// File: nilnilnil[P]autocomplete/deps/mongoose/mongoose.c
// Function: prepare_cgi_environment
static void prepare_cgi_environment(struct mg_connection *conn,
                                    const char *prog,
                                    struct cgi_env_block *blk) {
  const char *s, *slash;
  struct vec var_vec, root;
  char *p;
  int  i;

  blk->len = blk->nvars = 0;
  blk->conn = conn;

  get_document_root(conn, &root);

  addenv(blk, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]);
  addenv(blk, "SERVER_ROOT=%.*s", root.len, root.ptr);
  addenv(blk, "DOCUMENT_ROOT=%.*s", root.len, root.ptr);

  // Prepare the environment block
  addenv(blk, "%s", "GATEWAY_INTERFACE=CGI/1.1");
  addenv(blk, "%s", "SERVER_PROTOCOL=HTTP/1.1");
  addenv(blk, "%s", "REDIRECT_STATUS=200"); // For PHP
  addenv(blk, "SERVER_PORT=%d", ntohs(conn->client.lsa.u.sin.sin_port));
  addenv(blk, "REQUEST_METHOD=%s", conn->request_info.request_method);
  addenv(blk, "REMOTE_ADDR=%s",
      inet_ntoa(conn->client.rsa.u.sin.sin_addr));
  addenv(blk, "REMOTE_PORT=%d", conn->request_info.remote_port);
  addenv(blk, "REQUEST_URI=%s", conn->request_info.uri);

  // SCRIPT_NAME
  assert(conn->request_info.uri[0] == '/');
  slash = strrchr(conn->request_info.uri, '/');
  if ((s = strrchr(prog, '/')) == NULL)
    s = prog;
  addenv(blk, "SCRIPT_NAME=%.*s%s", slash - conn->request_info.uri,
         conn->request_info.uri, s);

  addenv(blk, "SCRIPT_FILENAME=%s", prog);
  addenv(blk, "PATH_TRANSLATED=%s", prog);
  addenv(blk, "HTTPS=%s", conn->ssl == NULL ? "off" : "on");

  if ((s = mg_get_header(conn, "Content-Type")) != NULL)
    addenv(blk, "CONTENT_TYPE=%s", s);

  if (conn->request_info.query_string != NULL)
    addenv(blk, "QUERY_STRING=%s", conn->request_info.query_string);

  if ((s = mg_get_header(conn, "Content-Length")) != NULL)
    addenv(blk, "CONTENT_LENGTH=%s", s);

  if ((s = getenv("PATH")) != NULL)
    addenv(blk, "PATH=%s", s);

#if defined(_WIN32)
  if ((s = getenv("COMSPEC")) != NULL)
    addenv(blk, "COMSPEC=%s", s);
  if ((s = getenv("SYSTEMROOT")) != NULL)
    addenv(blk, "SYSTEMROOT=%s", s);
#else
  if ((s = getenv("LD_LIBRARY_PATH")) != NULL)
    addenv(blk, "LD_LIBRARY_PATH=%s", s);
#endif /* _WIN32 */

  if ((s = getenv("PERLLIB")) != NULL)
    addenv(blk, "PERLLIB=%s", s);

  if (conn->request_info.remote_user != NULL) {
    addenv(blk, "REMOTE_USER=%s", conn->request_info.remote_user);
    addenv(blk, "%s", "AUTH_TYPE=Digest");
  }

  // Add all headers as HTTP_* variables
  for (i = 0; i < conn->request_info.num_headers; i++) {
    p = addenv(blk, "HTTP_%s=%s",
        conn->request_info.http_headers[i].name,
        conn->request_info.http_headers[i].value);

    // Convert variable name into uppercase, and change - to _
    for (; *p != '=' && *p != '\0'; p++) {
      if (*p == '-')
        *p = '_';
      *p = (char) toupper(* (unsigned char *) p);
    }
  }

  // Add user-specified variables
  s = conn->ctx->config[CGI_ENVIRONMENT];
  while ((s = next_option(s, &var_vec, NULL)) != NULL) {
    addenv(blk, "%.*s", var_vec.len, var_vec.ptr);
  }

  blk->vars[blk->nvars++] = NULL;
  blk->buf[blk->len++] = '\0';

  assert(blk->nvars < (int) ARRAY_SIZE(blk->vars));
  assert(blk->len > 0);
  assert(blk->len < (int) sizeof(blk->buf));
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movq %rdx, 0x60(%rsp)
movq 0x60(%rsp), %rax
movl $0x0, 0x1210(%rax)
movq 0x60(%rsp), %rax
movl $0x0, 0x1008(%rax)
movq 0x70(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, (%rax)
movq 0x70(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x1efc0
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x458(%rax), %rax
movq 0x38(%rax), %rdx
leaq 0x3649(%rip), %rsi      # 0x235c2
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x38(%rsp), %rdx
movq 0x30(%rsp), %rcx
leaq 0x363b(%rip), %rsi      # 0x235d1
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x38(%rsp), %rdx
movq 0x30(%rsp), %rcx
leaq 0x362f(%rip), %rsi      # 0x235e2
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
leaq 0x37b2(%rip), %rsi      # 0x23778
leaq 0x3628(%rip), %rdx      # 0x235f5
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
leaq 0x3798(%rip), %rsi      # 0x23778
leaq 0x3628(%rip), %rdx      # 0x2360f
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
leaq 0x377e(%rip), %rsi      # 0x23778
leaq 0x3627(%rip), %rdx      # 0x23628
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x70(%rsp), %rax
movzwl 0x47a(%rax), %edi
callq 0x5ad0
movq 0x10(%rsp), %rdi
movzwl %ax, %edx
leaq 0x360a(%rip), %rsi      # 0x2363c
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x10(%rax), %rdx
leaq 0x35fd(%rip), %rsi      # 0x2364b
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x70(%rsp), %rax
movl 0x490(%rax), %edi
callq 0x5240
movq 0x18(%rsp), %rdi
movq %rax, %rdx
leaq 0x35df(%rip), %rsi      # 0x2365d
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movl 0x48(%rax), %edx
leaq 0x35d3(%rip), %rsi      # 0x2366c
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rdx
leaq 0x35c6(%rip), %rsi      # 0x2367b
movb $0x0, %al
callq 0x208a0
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rdi
movl $0x2f, %esi
callq 0x5630
movq %rax, 0x50(%rsp)
movq 0x68(%rsp), %rdi
movl $0x2f, %esi
callq 0x5630
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
jne 0x200f8
movq 0x68(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x60(%rsp), %rdi
movq 0x50(%rsp), %rdx
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rax
subq %rax, %rdx
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rcx
movq 0x58(%rsp), %r8
leaq 0x3567(%rip), %rsi      # 0x2368a
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rdx
leaq 0x3562(%rip), %rsi      # 0x2369d
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rdx
leaq 0x355d(%rip), %rsi      # 0x236b0
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x460(%rax), %rcx
leaq 0x3984(%rip), %rdx      # 0x23af6
leaq 0x3553(%rip), %rax      # 0x236cc
cmpq $0x0, %rcx
cmoveq %rax, %rdx
leaq 0x353b(%rip), %rsi      # 0x236c3
movb $0x0, %al
callq 0x208a0
movq 0x70(%rsp), %rdi
leaq 0x3535(%rip), %rsi      # 0x236d0
callq 0x16b70
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x201c3
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rdx
leaq 0x3521(%rip), %rsi      # 0x236dd
movb $0x0, %al
callq 0x208a0
movq 0x70(%rsp), %rax
cmpq $0x0, 0x28(%rax)
je 0x201eb
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x28(%rax), %rdx
leaq 0x3509(%rip), %rsi      # 0x236ed
movb $0x0, %al
callq 0x208a0
movq 0x70(%rsp), %rdi
leaq 0x2c9c(%rip), %rsi      # 0x22e93
callq 0x16b70
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x2021f
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rdx
leaq 0x34e5(%rip), %rsi      # 0x236fd
movb $0x0, %al
callq 0x208a0
leaq 0x34f4(%rip), %rdi      # 0x2371a
callq 0x5700
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x2024e
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rdx
leaq 0x34e3(%rip), %rsi      # 0x2372a
movb $0x0, %al
callq 0x208a0
leaq 0x34ba(%rip), %rdi      # 0x2370f
callq 0x5700
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x2027d
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rdx
leaq 0x34a9(%rip), %rsi      # 0x2371f
movb $0x0, %al
callq 0x208a0
leaq 0x34ae(%rip), %rdi      # 0x23732
callq 0x5700
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x202ac
movq 0x60(%rsp), %rdi
movq 0x58(%rsp), %rdx
leaq 0x3495(%rip), %rsi      # 0x2373a
movb $0x0, %al
callq 0x208a0
movq 0x70(%rsp), %rax
cmpq $0x0, 0x30(%rax)
je 0x202ee
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x30(%rax), %rdx
leaq 0x3478(%rip), %rsi      # 0x23745
movb $0x0, %al
callq 0x208a0
movq 0x60(%rsp), %rdi
leaq 0x3498(%rip), %rsi      # 0x23778
leaq 0x346d(%rip), %rdx      # 0x23754
movb $0x0, %al
callq 0x208a0
movl $0x0, 0x24(%rsp)
movl 0x24(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl 0x54(%rcx), %eax
jge 0x203d5
movq 0x60(%rsp), %rdi
movq 0x70(%rsp), %rax
addq $0x8, %rax
addq $0x50, %rax
movslq 0x24(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdx
movq 0x70(%rsp), %rax
addq $0x8, %rax
addq $0x50, %rax
movslq 0x24(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
leaq 0x3418(%rip), %rsi      # 0x23765
movb $0x0, %al
callq 0x208a0
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
movsbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x3d, %ecx
movb %al, 0xf(%rsp)
je 0x2037e
movq 0x28(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
setne %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x20388
jmp 0x203c3
movq 0x28(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x2039d
movq 0x28(%rsp), %rax
movb $0x5f, (%rax)
movq 0x28(%rsp), %rax
movzbl (%rax), %edi
callq 0x5af0
movb %al, %cl
movq 0x28(%rsp), %rax
movb %cl, (%rax)
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
jmp 0x20359
jmp 0x203c5
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x202f6
movq 0x70(%rsp), %rax
movq 0x458(%rax), %rax
movq 0x18(%rax), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
leaq 0x40(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x1ab00
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x20427
movq 0x60(%rsp), %rdi
movq 0x48(%rsp), %rdx
movq 0x40(%rsp), %rcx
leaq 0x31bf(%rip), %rsi      # 0x235dd
movb $0x0, %al
callq 0x208a0
jmp 0x203ea
movq 0x60(%rsp), %rax
movq 0x60(%rsp), %rdx
movl 0x1210(%rdx), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x1210(%rdx)
movslq %ecx, %rcx
movq $0x0, 0x1010(%rax,%rcx,8)
movq 0x60(%rsp), %rax
movq 0x60(%rsp), %rdx
movl 0x1008(%rdx), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x1008(%rdx)
movslq %ecx, %rcx
movb $0x0, 0x8(%rax,%rcx)
addq $0x78, %rsp
retq
nopl (%rax)