(command.CommandList
  children: [
    (command.If
      arms: [
        (if_arm
          cond: [
            (command.Sentence
              child: (C {(test)} {(-z)} {(DQ ($ VSub_DollarName '$BASH_VERSION'))})
              terminator: <Op_Semi ';'>
            )
          ]
          action: [
            (command.Simple
              words: [{(echo)} {(DQ ('Please run this script using bash, not sh or any other shell.'))}]
              redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
            )
            (command.ControlFlow token:<ControlFlow_Exit exit> arg_word:{(1)})
          ]
        )
      ]
    )
    (command.ShFunction
      name: _
      body: 
        (command.BraceGroup
          children: [
            (C {(KW_Set set)} {(-euo)} {(pipefail)})
            (C {(declare)} {(-a)} {(ORIGINAL_ARGS)})
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:CURL_USER_AGENT)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name CURL_USER_AGENT>
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: VTest_ColonHyphen
                              arg_word: {(sandstorm-install-script)}
                            )
                        )
                      )
                    }
                )
              ]
            )
            (command.ShFunction
              name: error
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {($ VSub_Pound '$#')} 
                                  {(KW_Bang '!') (Lit_Equals '=')} {(0)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(echo)} {(-en)} {(SQ <'\\e[0;31m'>)}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_GreatAnd '>&'>
                                  fd: 16777215
                                  arg_word: {(2)}
                                )
                              ]
                            )
                            (command.Pipeline
                              children: [
                                (C {(echo)} {(DQ ($ VSub_At '$@'))})
                                (command.Subshell
                                  command_list: 
                                    (command.CommandList
                                      children: [
                                        (command.AndOr
                                          ops: [Op_DPipe]
                                          children: [(C {(fold)} {(-s)}) (C {(cat)})]
                                        )
                                      ]
                                    )
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_GreatAnd '>&'>
                                      fd: 16777215
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                              ]
                              negated: F
                            )
                            (command.Simple
                              words: [{(echo)} {(-en)} {(SQ <'\\e[0m'>)}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_GreatAnd '>&'>
                                  fd: 16777215
                                  arg_word: {(2)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: fail
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Lit_VarLike 'error_code=') (DQ ($ VSub_Number '$1'))})
                    (C {(shift)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name SHOW_FAILURE_MSG>
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: VTest_ColonHyphen
                                            arg_word: {(yes)}
                                          )
                                      )
                                    )
                                  } {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(echo)} {(DQ ('*** INSTALLATION FAILED ***'))}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_GreatAnd '>&'>
                                  fd: 16777215
                                  arg_word: {(2)}
                                )
                              ]
                            )
                            (C {(echo)} {(DQ )})
                          ]
                        )
                      ]
                    )
                    (C {(error)} {(DQ ($ VSub_At '$@'))})
                    (command.Simple
                      words: [{(echo)} {(DQ )}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name REPORT>
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: VTest_ColonHyphen
                                            arg_word: {(yes)}
                                          )
                                      )
                                    )
                                  } {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Simple
                                          words: [
                                            {(prompt-yesno)}
                                            {
                                              (DQ 
                                                (
'Hmm, installation failed. Would it be OK to send an anonymous error report to the sandstorm.io team so we know something is wrong?\n'
                                                ) ('It would only contain this error code: ') ($ VSub_DollarName '$error_code')
                                              )
                                            }
                                            {(DQ (yes))}
                                          ]
                                          more_env: [(env_pair name:USE_DEFAULTS val:{(no)})]
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.Simple
                                      words: [{(echo)} {(DQ ('Sending problem report...'))}]
                                      redirects: [
                                        (redir.Redir
                                          op: <Redir_GreatAnd '>&'>
                                          fd: 16777215
                                          arg_word: {(2)}
                                        )
                                      ]
                                    )
                                    (C {(local)} 
                                      {(Lit_VarLike 'BEARER_TOKEN=') 
                                        (DQ (ZiV1jbwHBPfpIjF3LNFv9-glp53F7KcsvVvljgKxQAL))
                                      }
                                    )
                                    (C {(local)} 
                                      {(Lit_VarLike 'API_ENDPOINT=') 
                                        (DQ ('https://api.oasis.sandstorm.io/api'))
                                      }
                                    )
                                    (C {(local)} 
                                      {(Lit_VarLike 'HTTP_STATUS=') 
                                        (command_sub
                                          left_token: <Left_DollarParen '$('>
                                          command_list: 
                                            (command.CommandList
                                              children: [
                                                (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                                  {(--data-binary)} 
                                                  {
                                                    (DQ ('{') 
                                                      (word_part.EscapedLiteral
                                                        token: <Lit_EscapedChar '\\"'>
                                                      ) (error_code) (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) (':') 
                                                      (word_part.EscapedLiteral
                                                        token: <Lit_EscapedChar '\\"'>
                                                      ) ($ VSub_DollarName '$error_code') (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) (',') 
                                                      (word_part.EscapedLiteral
                                                        token: <Lit_EscapedChar '\\"'>
                                                      ) (user-agent) (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) (':') 
                                                      (word_part.EscapedLiteral
                                                        token: <Lit_EscapedChar '\\"'>
                                                      ) ($ VSub_DollarName '$CURL_USER_AGENT') (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) ('}')
                                                    )
                                                  } {(-H)} {(DQ ('Authorization: Bearer ') ($ VSub_DollarName '$BEARER_TOKEN'))} {(-X)} {(POST)} {(--output)} 
                                                  {(DQ (/dev/null))} {(-w)} {(SQ <'%{http_code}'>)} {(DQ ($ VSub_DollarName '$API_ENDPOINT'))}
                                                )
                                              ]
                                            )
                                        )
                                      }
                                    )
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (C {(Lit_LBracket '[')} {(DQ (200))} 
                                                  {(Lit_Equals '=') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                                                )
                                              terminator: <Op_Semi ';'>
                                            )
                                          ]
                                          action: [
                                            (command.Simple
                                              words: [
                                                {(echo)}
                                                {
                                                  (DQ 
                                                    (
'... problem reported successfully. Your installation did not succeed.'
                                                    )
                                                  )
                                                }
                                              ]
                                              redirects: [
                                                (redir.Redir
                                                  op: <Redir_GreatAnd '>&'>
                                                  fd: 16777215
                                                  arg_word: {(2)}
                                                )
                                              ]
                                            )
                                          ]
                                        )
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (C {(Lit_LBracket '[')} {(DQ (000))} 
                                                  {(Lit_Equals '=') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                                                )
                                              terminator: <Op_Semi ';'>
                                            )
                                          ]
                                          action: [
                                            (C {(error)} 
                                              {
                                                (DQ 
                                                  (
'Submitting error report failed. Maybe there is a connectivity problem.'
                                                  )
                                                )
                                              }
                                            )
                                          ]
                                        )
                                      ]
                                      else_action: [
                                        (C {(error)} 
                                          {
                                            (DQ 
                                              (
'Submitting error report resulted in strange HTTP status: '
                                              ) ($ VSub_DollarName '$HTTP_STATUS')
                                            )
                                          }
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.Simple
                                  words: [{(echo)} {(DQ ('Not sending report.'))}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_GreatAnd '>&'>
                                      fd: 16777215
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(echo)} {(DQ )})
                          ]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {(DQ ('You can report bugs at: http://github.com/sandstorm-io/sandstorm'))}
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.ControlFlow
                      token: <ControlFlow_Exit exit>
                      arg_word: {(1)}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: retryable_curl
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Lit_VarLike 'CURL_FAILED=') (DQ (no))})
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (command.Simple
                          words: [
                            {(curl)}
                            {(-A)}
                            {(DQ (${ VSub_Name CURL_USER_AGENT))}
                            {(-f)}
                            {(DQ ($ VSub_Number '$1'))}
                          ]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(DQ ($ VSub_Number '$2'))}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:CURL_FAILED)
                              op: Equal
                              rhs: {(DQ (yes))}
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name CURL_FAILED))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ ('Downloading ') ($ VSub_Number '$1') 
                                              (' failed. OK to retry?')
                                            )
                                          } {(DQ (yes))}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.Simple
                                      words: [{(echo)} {(DQ )}]
                                      redirects: [
                                        (redir.Redir
                                          op: <Redir_GreatAnd '>&'>
                                          fd: 16777215
                                          arg_word: {(2)}
                                        )
                                      ]
                                    )
                                    (command.Simple
                                      words: [
                                        {(echo)}
                                        {
                                          (DQ 
                                            (
'Download failed. Waiting one second before retrying...'
                                            )
                                          )
                                        }
                                      ]
                                      redirects: [
                                        (redir.Redir
                                          op: <Redir_GreatAnd '>&'>
                                          fd: 16777215
                                          arg_word: {(2)}
                                        )
                                      ]
                                    )
                                    (C {(sleep)} {(1)})
                                    (C {(retryable_curl)} {(DQ ($ VSub_Number '$1'))} 
                                      {(DQ ($ VSub_Number '$2'))}
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: dotdotdot_curl
              body: 
                (command.BraceGroup
                  children: [
                    (command.Simple
                      words: [{(echo)} {(-n)} {(SQ <...>)}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (C {(curl)} {(DQ ($ VSub_At '$@'))})
                    (command.Simple
                      words: [{(echo)} {(-ne)} {(SQ <'\\r'>)}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: is_port_bound
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Lit_VarLike 'SCAN_HOST=') (DQ ($ VSub_Number '$1'))})
                    (C {(local)} {(Lit_VarLike 'SCAN_PORT=') (DQ ($ VSub_Number '$2'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (${ VSub_Name DEV_TCP_USABLE))} 
                                  {(Lit_Equals '=')} {(DQ (unchecked))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_DEV_TCP_UNCHECKED))}
                                {
                                  (DQ 
                                    (
'Programmer error. The author of install.sh used an uninitialized variable.'
                                    )
                                  )
                                }
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)})]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (${ VSub_Name DEV_TCP_USABLE))} 
                                  {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Simple
                                          words: [
                                            {(timeout)}
                                            {(1)}
                                            {(bash)}
                                            {(-c)}
                                            {
                                              (DQ (': < /dev/tcp/') (${ VSub_Name SCAN_HOST) (/) 
                                                (${ VSub_Name SCAN_PORT)
                                              )
                                            }
                                          ]
                                          redirects: [
                                            (redir.Redir
                                              op: <Redir_Great '2>'>
                                              fd: 2
                                              arg_word: {(/dev/null)}
                                            )
                                          ]
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ControlFlow
                                      token: <ControlFlow_Return return>
                                      arg_word: {(0)}
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.ControlFlow
                                  token: <ControlFlow_Return return>
                                  arg_word: {(1)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'DEBIAN_STYLE_INDICATED_BOUND=') (DQ (no))})
                    (command.AndOr
                      ops: [Op_DAmp]
                      children: [
                        (command.Simple
                          words: [
                            {(${ VSub_Name NC_PATH)}
                            {(-z)}
                            {(DQ ($ VSub_DollarName '$SCAN_HOST'))}
                            {(DQ ($ VSub_DollarName '$SCAN_PORT'))}
                          ]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(/dev/null)}
                            )
                            (redir.Redir
                              op: <Redir_Great '2>'>
                              fd: 2
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:DEBIAN_STYLE_INDICATED_BOUND)
                              op: Equal
                              rhs: {(yes)}
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {(DQ ($ VSub_DollarName '$DEBIAN_STYLE_INDICATED_BOUND'))} {(Lit_Equals '=') (Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                              arg_word: {(0)}
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'NMAP_STYLE_INDICATED_BOUND=') (DQ (no))})
                    (command.AndOr
                      ops: [Op_DAmp]
                      children: [
                        (command.Simple
                          words: [
                            {(${ VSub_Name NC_PATH)}
                            {(--wait)}
                            {(1)}
                            {(--recv-only)}
                            {(--send-only)}
                            {(DQ ($ VSub_DollarName '$SCAN_HOST'))}
                            {(DQ ($ VSub_DollarName '$SCAN_PORT'))}
                          ]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(/dev/null)}
                            )
                            (redir.Redir
                              op: <Redir_Great '2>'>
                              fd: 2
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:NMAP_STYLE_INDICATED_BOUND)
                              op: Equal
                              rhs: {(yes)}
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {(DQ ($ VSub_DollarName '$NMAP_STYLE_INDICATED_BOUND'))} {(Lit_Equals '=') (Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                              arg_word: {(0)}
                            )
                          ]
                        )
                      ]
                    )
                    (command.ControlFlow
                      token: <ControlFlow_Return return>
                      arg_word: {(1)}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: writeConfig
              body: 
                (command.BraceGroup
                  children: [
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Lit_LBracket '[')} {($ VSub_Pound '$#')} {(-gt)} {(0)} 
                              {(Lit_RBracket ']')}
                            )
                          terminator: <Op_Semi ';'>
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(eval)} {(echo)} 
                              {
                                (DQ ($ VSub_Number '$1') ('=') 
                                  (word_part.EscapedLiteral
                                    token: <Lit_EscapedChar '\\$'>
                                  ) ($ VSub_Number '$1')
                                )
                              }
                            )
                            (C {(shift)})
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: prompt
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(VALUE)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ($ VSub_Number '$2'))})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(echo)} {(-en)} {(SQ <'\\e[1m'>)}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(3)})]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {(-n)}
                        {(DQ ($ VSub_Number '$1') (' [') ($ VSub_Number '$2') (']'))}
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(3)})]
                    )
                    (command.Simple
                      words: [{(echo)} {(-en)} {(SQ <'\\e[0m '>)}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(3)})]
                    )
                    (C {(read)} {(-u)} {(3)} {(VALUE)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} {(DQ ($ VSub_DollarName '$VALUE'))} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:VALUE)
                                  op: Equal
                                  rhs: {($ VSub_Number '$2')}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ($ VSub_DollarName '$VALUE'))})
                  ]
                )
            )
            (command.ShFunction
              name: prompt-numeric
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Lit_VarLike 'NUMERIC_REGEX=') (DQ ('^[0-9]+') (Lit_Other '$'))})
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [(command.Sentence child:(C {(true)}) terminator:<Op_Semi ';'>)]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(local)} 
                              {(Lit_VarLike 'VALUE=') 
                                (command_sub
                                  left_token: <Left_DollarParen '$('>
                                  command_list: 
                                    (command.CommandList
                                      children: [(C {(prompt)} {(DQ ($ VSub_At '$@'))})]
                                    )
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Pipeline
                                          children: [
                                            (command.DBracket
                                              expr: 
                                                (bool_expr.Binary
                                                  op_id: BoolBinary_EqualTilde
                                                  left: {(DQ ($ VSub_DollarName '$VALUE'))}
                                                  right: {($ VSub_DollarName '$NUMERIC_REGEX')}
                                                )
                                            )
                                          ]
                                          negated: T
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.Simple
                                      words: [
                                        {(echo)}
                                        {
                                          (DQ ("You entered '") ($ VSub_DollarName '$VALUE') 
                                            ("'. Please enter a number.")
                                          )
                                        }
                                      ]
                                      redirects: [
                                        (redir.Redir
                                          op: <Redir_GreatAnd '>&'>
                                          fd: 16777215
                                          arg_word: {(3)}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (C {(echo)} {(DQ ($ VSub_DollarName '$VALUE'))})
                                (command.ControlFlow
                                  token: <ControlFlow_Return return>
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: prompt-yesno
              body: 
                (command.BraceGroup
                  children: [
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [(command.Sentence child:(C {(true)}) terminator:<Op_Semi ';'>)]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(local)} 
                              {(Lit_VarLike 'VALUE=') 
                                (command_sub
                                  left_token: <Left_DollarParen '$('>
                                  command_list: 
                                    (command.CommandList
                                      children: [(C {(prompt)} {(DQ ($ VSub_At '$@'))})]
                                    )
                                )
                              }
                            )
                            (command.Case
                              to_match: {($ VSub_DollarName '$VALUE')}
                              arms: [
                                (case_arm
                                  pat_list: [{(y)} {(Y)} {(yes)} {(YES)} {(Yes)}]
                                  action: [
                                    (command.ControlFlow
                                      token: <ControlFlow_Return return>
                                      arg_word: {(0)}
                                    )
                                  ]
                                )
                                (case_arm
                                  pat_list: [{(n)} {(N)} {(no)} {(NO)} {(No)}]
                                  action: [
                                    (command.ControlFlow
                                      token: <ControlFlow_Return return>
                                      arg_word: {(1)}
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('*** Please answer ') 
                                  (word_part.EscapedLiteral
                                    token: <Lit_EscapedChar '\\"'>
                                  ) (yes) (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) (' or ') 
                                  (word_part.EscapedLiteral
                                    token: <Lit_EscapedChar '\\"'>
                                  ) (no) (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) (.)
                                )
                              }
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShAssignment
              pairs: [(assign_pair lhs:(sh_lhs_expr.Name name:USE_DEFAULTS) op:Equal rhs:{(DQ (no))})]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                  op: Equal
                  rhs: {(DQ (no))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [(assign_pair lhs:(sh_lhs_expr.Name name:USE_SANDCATS) op:Equal rhs:{(DQ (no))})]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                  op: Equal
                  rhs: {(DQ (no))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_HTTPS_SUCCESSFUL)
                  op: Equal
                  rhs: {(DQ (no))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:CURRENTLY_UID_ZERO)
                  op: Equal
                  rhs: {(DQ (no))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [(assign_pair lhs:(sh_lhs_expr.Name name:PREFER_ROOT) op:Equal rhs:{(DQ (yes))})]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN)
                  op: Equal
                  rhs: {(DQ (no))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM)
                  op: Equal
                  rhs: {(DQ (no))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:NC_PATH)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name OVERRIDE_NC_PATH>
                          suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:{(nc)})
                        )
                      )
                    }
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE)
                  op: Equal
                  rhs: {(DQ (unchecked))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_DIR_FOR_ROOT)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name OVERRIDE_SANDSTORM_DEFAULT_DIR>
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: VTest_ColonHyphen
                              arg_word: {(Lit_Slash /) (opt) (Lit_Slash /) (sandstorm)}
                            )
                        )
                      )
                    }
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_DIR_FOR_NON_ROOT)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name OVERRIDE_SANDSTORM_DEFAULT_DIR>
                          suffix_op: 
                            (suffix_op.Unary
                              op_id: VTest_ColonHyphen
                              arg_word: 
                                {
                                  (braced_var_sub
                                    token: <VSub_Name HOME>
                                    suffix_op: 
                                      (suffix_op.Unary
                                        op_id: VTest_ColonHyphen
                                        arg_word: {(opt)}
                                      )
                                  ) (Lit_Slash /) (sandstorm)
                                }
                            )
                        )
                      )
                    }
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_SMTP_PORT)
                  op: Equal
                  rhs: {(DQ (30025))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_UPDATE_CHANNEL)
                  op: Equal
                  rhs: {(DQ (dev))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:DEFAULT_SERVER_USER)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name OVERRIDE_SANDSTORM_DEFAULT_SERVER_USER>
                          suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:{(sandstorm)})
                        )
                      )
                    }
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_BASE_DOMAIN)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name OVERRIDE_SANDCATS_BASE_DOMAIN>
                          suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:{(sandcats.io)})
                        )
                      )
                    }
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS)
                  op: Equal
                  rhs: {(DQ (false))}
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE)
                  op: Equal
                  rhs: 
                    {
                      (DQ 
                        (braced_var_sub
                          token: <VSub_Name OVERRIDE_SANDCATS_GETCERTIFICATE>
                          suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:{(yes)})
                        )
                      )
                    }
                )
              ]
            )
            (command.ShFunction
              name: usage
              body: 
                (command.BraceGroup
                  children: [
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (DQ ('usage: ') ($ VSub_DollarName '$SCRIPT_NAME') 
                            (' [-d] [-e] [-p PORT_NUMBER] [-u] [<bundle>]')
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (DQ 
                            (
'If <bundle> is provided, it must be the name of a Sandstorm bundle file,'
                            )
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (DQ 
                            (
"like 'sandstorm-123.tar.xz', which will be installed. Otherwise, the script"
                            )
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [{(echo)} {(DQ ('downloads a bundle from the internet via HTTP.'))}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [{(echo)} {(SQ )}]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            <
'If -d is specified, the auto-installs with defaults suitable for app development.'
                            >
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            <
'If -e is specified, default to listening on an external interface, not merely loopback.'
                            >
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            <
'If -i is specified, default to (i)nsecure mode where we do not request a HTTPS certificate.'
                            >
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (C {(echo)} 
                      {
                        (SQ 
                          <
'If -p is specified, use its argument (PORT_NUMBER) as the default port for HTTP. Otherwise, use 6080. Note that if the install script enables HTTPS via sandcats.io, it will use 443 instead!'
                          >
                        )
                      }
                    )
                    (command.Simple
                      words: [
                        {(echo)}
                        {
                          (SQ 
                            <
'If -u is specified, default to avoiding root priviliges. Note that the dev tools only work if the server as root privileges.'
                            >
                          )
                        }
                      ]
                      redirects: [(redir.Redir op:<Redir_GreatAnd '>&'> fd:16777215 arg_word:{(2)})]
                    )
                    (command.ControlFlow
                      token: <ControlFlow_Exit exit>
                      arg_word: {(1)}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: detect_current_uid
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (command_sub
                                      left_token: <Left_DollarParen '$('>
                                      command_list: 
                                        (command.CommandList
                                          children: [(C {(id)} {(-u)})]
                                        )
                                    )
                                  } {(Lit_Equals '=')} {(0)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CURRENTLY_UID_ZERO)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: disable_smtp_port_25_if_port_unavailable
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:PORT_25_AVAILABLE)
                          op: Equal
                          rhs: {(DQ (no))}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(is_port_bound)} {(0.0.0.0)} {(25)})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(is_port_bound)} {(127.0.0.1)} {(25)})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:PORT_25_AVAILABLE)
                          op: Equal
                          rhs: {(DQ (yes))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: disable_https_if_ports_unavailable
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Lit_VarLike 'PORT_80_AVAILABLE=') (DQ (no))})
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (C {(is_port_bound)} {(0.0.0.0)} {(80)})
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:PORT_80_AVAILABLE)
                              op: Equal
                              rhs: {(DQ (yes))}
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'PORT_443_AVAILABLE=') (DQ (no))})
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (C {(is_port_bound)} {(0.0.0.0)} {(443)})
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:PORT_443_AVAILABLE)
                              op: Equal
                              rhs: {(DQ (yes))}
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$PORT_443_AVAILABLE'))} 
                                  {(Lit_Equals '=') (Lit_Equals '=')} {(DQ (no))} {(-o)} {(DQ ($ VSub_DollarName '$PORT_80_AVAILABLE'))} {(Lit_Equals '=') (Lit_Equals '=')} 
                                  {(DQ (no))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE)
                                  op: Equal
                                  rhs: {(DQ (no))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: handle_args
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SCRIPT_NAME)
                          op: Equal
                          rhs: {($ VSub_Number '$1')}
                        )
                      ]
                    )
                    (C {(shift)})
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [
                        (command.Sentence
                          child: (C {(getopts)} {(DQ (':deiup:'))} {(opt)})
                          terminator: <Op_Semi ';'>
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (command.Case
                              to_match: {($ VSub_DollarName '$opt')}
                              arms: [
                                (case_arm
                                  pat_list: [{(d)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_DEFAULTS)
                                          op: Equal
                                          rhs: {(DQ (yes))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                                (case_arm
                                  pat_list: [{(e)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                          op: Equal
                                          rhs: {(DQ (yes))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                                (case_arm
                                  pat_list: [{(i)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE)
                                          op: Equal
                                          rhs: {(DQ (no))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                                (case_arm
                                  pat_list: [{(u)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:PREFER_ROOT)
                                          op: Equal
                                          rhs: {(no)}
                                        )
                                      ]
                                    )
                                  ]
                                )
                                (case_arm
                                  pat_list: [{(p)}]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:DEFAULT_PORT)
                                          op: Equal
                                          rhs: {(DQ (${ VSub_Name OPTARG))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                                (case_arm
                                  pat_list: [{(Lit_Star '*')}]
                                  action: [(C {(usage)})]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DEFAULT_PORT)
                          op: Equal
                          rhs: 
                            {
                              (DQ 
                                (braced_var_sub
                                  token: <VSub_Name DEFAULT_PORT>
                                  suffix_op: 
                                    (suffix_op.Unary
                                      op_id: VTest_ColonHyphen
                                      arg_word: {(6080)}
                                    )
                                )
                              )
                            }
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:ORIGINAL_ARGS)
                          op: Equal
                          rhs: 
                            {(sh_array_literal left:<Op_LParen '('> words:[{(DQ ($ VSub_At '$@'))}])}
                        )
                      ]
                    )
                    (C {(shift)} 
                      {
                        (DQ 
                          (word_part.ArithSub
                            anode: 
                              (arith_expr.Binary
                                op_id: Arith_Minus
                                left: (arith_expr.VarRef token:<Lit_ArithVarLike OPTIND>)
                                right: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                              )
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Op_DAmp]
                                  children: [
                                    (C {(Lit_LBracket '[')} {($ VSub_Pound '$#')} {(Lit_Equals '=')} 
                                      {(1)} {(Lit_RBracket ']')}
                                    )
                                    (command.DBracket
                                      expr: 
                                        (bool_expr.LogicalNot
                                          child: 
                                            (bool_expr.Binary
                                              op_id: BoolBinary_EqualTilde
                                              left: {($ VSub_Number '$1')}
                                              right: {(Lit_Other '^') (-)}
                                            )
                                        )
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUNDLE_FILE)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_Number '$1'))}
                                )
                              ]
                            )
                          ]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {($ VSub_Pound '$#')} 
                                  {(KW_Bang '!') (Lit_Equals '=')} {(0)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(C {(usage)})]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: rerun_script_as_root
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} 
                      {(Lit_VarLike 'ENVVARS=') 
                        (command_sub
                          left_token: <Left_DollarParen '$('>
                          command_list: 
                            (command.CommandList
                              children: [(C {(echo)} {($ VSub_At '$@')})]
                            )
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:ENVVARS)
                          op: Equal
                          rhs: 
                            {
                              (DQ ($ VSub_DollarName '$ENVVARS') (' CURL_USER_AGENT=') 
                                ($ VSub_DollarName '$CURL_USER_AGENT')
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(basename)} {($ VSub_DollarName '$SCRIPT_NAME')})
                                            ]
                                          )
                                      )
                                    )
                                  } {(Lit_Equals '=') (Lit_Equals '=')} {(bash)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Re-running script as root...'))})
                            (C {(exec)} {(sudo)} {(bash)} {(-euo)} {(pipefail)} {(-c)} 
                              {
                                (DQ ('curl -fs -A ') ($ VSub_DollarName '$CURL_USER_AGENT') 
                                  (' https://install.sandstorm.io | ') ($ VSub_DollarName '$ENVVARS') (' bash')
                                )
                              }
                            )
                          ]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Op_DAmp]
                                  children: [
                                    (C {(Lit_LBracket '[')} 
                                      {
                                        (DQ 
                                          (command_sub
                                            left_token: <Left_DollarParen '$('>
                                            command_list: 
                                              (command.CommandList
                                                children: [
                                                  (C {(basename)} {($ VSub_DollarName '$SCRIPT_NAME')})
                                                ]
                                              )
                                          )
                                        )
                                      } {(Lit_Equals '=') (Lit_Equals '=')} {(install.sh)} {(Lit_RBracket ']')}
                                    )
                                    (C {(Lit_LBracket '[')} {(-e)} {(DQ ($ VSub_Number '$0'))} 
                                      {(Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Re-running script as root...'))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} 
                                          {
                                            (braced_var_sub
                                              token: <VSub_Name ORIGINAL_ARGS>
                                              prefix_op: VSub_Pound
                                              bracket_op: (bracket_op.WholeArray op_id:Lit_At)
                                            )
                                          } {(Lit_Equals '=')} {(0)} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(exec)} {(sudo)} {($ VSub_DollarName '$ENVVARS')} {(bash)} 
                                      {(DQ ($ VSub_DollarName '$SCRIPT_NAME'))}
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (C {(exec)} {(sudo)} {($ VSub_DollarName '$ENVVARS')} {(bash)} 
                                  {(DQ ($ VSub_DollarName '$SCRIPT_NAME'))} {(DQ (braced_var_sub token:<VSub_Name ORIGINAL_ARGS> bracket_op:(bracket_op.WholeArray op_id:Lit_At)))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(fail)}
                        {(DQ (E_CANT_SWITCH_TO_ROOT))}
                        {
                          (DQ 
                            (
'ERROR: This script could not detect its own filename, so could not switch to root. '
                            ) ("Please download a copy and name it 'install.sh' and run that as root, perhaps using sudo. ") 
                            ('Try this command:\n') ('\n') ('curl https://install.sandstorm.io/ > install.sh && sudo bash install.sh')
                          )
                        }
                      ]
                      more_env: [(env_pair name:REPORT val:{(no)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: set_umask
              body: (command.BraceGroup children:[(C {(umask)} {(0022)})])
            )
            (command.ShFunction
              name: assert_on_terminal
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Op_DAmp]
                                  children: [
                                    (C {(Lit_LBracket '[')} {(DQ (no))} {(Lit_Equals '=')} 
                                      {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                    )
                                    (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-t)} {(1)} 
                                      {(Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_NO_TTY))}
                                {(DQ ('This script is interactive. Please run it on a terminal.'))}
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)})]
                            )
                          ]
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(exec)}]
                      redirects: [(redir.Redir op:<Redir_LessAnd '3<&'> fd:3 arg_word:{(1)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_linux_x86_64
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: (command.CommandList children:[(C {(uname)})])
                                      )
                                    )
                                  } {(KW_Bang '!') (Lit_Equals '=')} {(Linux)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_NON_LINUX))} 
                              {
                                (DQ 
                                  (
'Sandstorm requires Linux. If you want to run Sandstorm on a Windows or\n'
                                  ) ('Mac system, you can use Vagrant or another virtualization tool. See our install documentation:\n') 
                                  ('\n') ('- https://docs.sandstorm.io/en/latest/install/')
                                )
                              }
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(uname)} {(-m)})]
                                          )
                                      )
                                    )
                                  } {(KW_Bang '!') (Lit_Equals '=')} {(x86_64)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_NON_X86_64))} 
                              {
                                (DQ 
                                  (
'Sorry, the Sandstorm server currently only runs on x86_64 machines.'
                                  )
                                )
                              }
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_usable_kernel
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:KVERSION)
                          op: Equal
                          rhs: 
                            {
                              (sh_array_literal
                                left: <Op_LParen '('>
                                words: [
                                  {
                                    (command_sub
                                      left_token: <Left_DollarParen '$('>
                                      command_list: 
                                        (command.CommandList
                                          children: [
                                            (command.Pipeline
                                              children: [
                                                (C {(uname)} {(-r)})
                                                (C {(grep)} {(-o)} {(SQ <'^[0-9.]*'>)})
                                                (C {(tr)} {(.)} {(SQ <' '>)})
                                              ]
                                              negated: F
                                            )
                                          ]
                                        )
                                    )
                                  }
                                ]
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DParen
                                  child: 
                                    (arith_expr.Binary
                                      op_id: Arith_DPipe
                                      left: 
                                        (arith_expr.Binary
                                          op_id: Arith_Less
                                          left: 
                                            (arith_expr.Binary
                                              op_id: Arith_LBracket
                                              left: 
                                                (arith_expr.VarRef
                                                  token: <Lit_ArithVarLike KVERSION>
                                                )
                                              right: (arith_expr.ArithWord w:{(Lit_Digits 0)})
                                            )
                                          right: (arith_expr.ArithWord w:{(Lit_Digits 3)})
                                        )
                                      right: 
                                        (arith_expr.Binary
                                          op_id: Arith_DAmp
                                          left: 
                                            (arith_expr.Binary
                                              op_id: Arith_DEqual
                                              left: 
                                                (arith_expr.Binary
                                                  op_id: Arith_LBracket
                                                  left: 
                                                    (arith_expr.VarRef
                                                      token: <Lit_ArithVarLike KVERSION>
                                                    )
                                                  right: (arith_expr.ArithWord w:{(Lit_Digits 0)})
                                                )
                                              right: (arith_expr.ArithWord w:{(Lit_Digits 3)})
                                            )
                                          right: 
                                            (arith_expr.Binary
                                              op_id: Arith_Less
                                              left: 
                                                (arith_expr.Binary
                                                  op_id: Arith_LBracket
                                                  left: 
                                                    (arith_expr.VarRef
                                                      token: <Lit_ArithVarLike KVERSION>
                                                    )
                                                  right: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                                                )
                                              right: (arith_expr.ArithWord w:{(Lit_Digits 10)})
                                            )
                                        )
                                    )
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ ('Detected Linux kernel version: ') 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(uname)} {(-r)})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(fail)} {(DQ (E_KERNEL_OLDER_THAN_310))} 
                              {
                                (DQ 
                                  (
'Sorry, your kernel is too old to run Sandstorm. We require kernel'
                                  )
                                )
                              } {(DQ ('version 3.10 or newer.'))}
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: maybe_enable_userns_sysctl
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} 
                                  {(KW_Bang '!') (Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (no))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-e)} 
                                  {(/proc/sys/kernel/unprivileged_userns_clone)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Lit_VarLike 'OLD_VALUE=') 
                        (DQ 
                          (command_sub
                            left_token: <Left_DollarParen '$('>
                            command_list: 
                              (command.CommandList
                                children: [
                                  (command.Simple
                                    redirects: [
                                      (redir.Redir
                                        op: <Redir_Less '<'>
                                        fd: 16777215
                                        arg_word: {(/proc/sys/kernel/unprivileged_userns_clone)}
                                      )
                                    ]
                                  )
                                ]
                              )
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$OLD_VALUE'))} 
                                  {(Lit_Equals '=')} {(DQ (1))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Simple
                                  words: [
                                    {(sysctl)}
                                    {(-wq)}
                                    {(kernel.unprivileged_userns_clone) (Lit_Equals '=') (1)}
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_Great '2>'>
                                      fd: 2
                                      arg_word: {(/dev/null)}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'NOTE: Enabled unprivileged user namespaces because you passed -d.'
                                  )
                                )
                              }
                            )
                          ]
                        )
                      ]
                      else_action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                    )
                    (C {(local)} {(Lit_VarLike 'SYSCTL_FILENAME=') (DQ (/etc/sysctl.conf))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-d)} {(/etc/sysctl.d)} {(Lit_RBracket ']')})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SYSCTL_FILENAME)
                                  op: Equal
                                  rhs: {(DQ (/etc/sysctl.d/50-sandstorm.conf))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Pipeline
                              children: [
                                (command.Simple
                                  words: [{(cat)}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_DGreat '>>'>
                                      fd: 16777215
                                      arg_word: {(DQ ($ VSub_DollarName '$SYSCTL_FILENAME'))}
                                    )
                                    (redir.HereDoc
                                      op: <Redir_DLess '<<'>
                                      fd: 16777215
                                      here_begin: {(__EOF__)}
                                      here_end_span_id: 3228
                                      stdin_parts: [
                                        ('\n')
                                        (
'# Enable non-root users to create sandboxes (needed by Sandstorm).\n'
                                        )
                                        ('kernel.unprivileged_userns_clone = 1\n')
                                      ]
                                    )
                                  ]
                                )
                              ]
                              negated: T
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
"NOTE: Never mind, not enabling userns because can't write /etc/sysctl.d."
                                  )
                                )
                              }
                            )
                            (command.AndOr
                              ops: [Op_DPipe]
                              children: [
                                (C {(sysctl)} {(-wq)} 
                                  {
                                    (DQ ('kernel.unprivileged_userns_clone=') 
                                      ($ VSub_DollarName '$OLD_VALUE')
                                    )
                                  }
                                )
                                (C {(true)})
                              ]
                            )
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: test_if_dev_tcp_works
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.Subshell
                                      command_list: 
                                        (command.CommandList
                                          children: [
                                            (command.AndOr
                                              ops: [Op_DPipe]
                                              children: [
                                                (command.Simple
                                                  words: [
                                                    {(timeout)}
                                                    {(1)}
                                                    {(bash)}
                                                    {(-c)}
                                                    {(SQ <': < /dev/tcp/localhost/0'>)}
                                                  ]
                                                  redirects: [
                                                    (redir.Redir
                                                      op: <Redir_GreatAnd '2>&'>
                                                      fd: 2
                                                      arg_word: {(1)}
                                                    )
                                                  ]
                                                )
                                                (C {(true)})
                                              ]
                                            )
                                          ]
                                        )
                                    )
                                    (C {(grep)} {(-q)} {(SQ <'connect:'>)})
                                  ]
                                  negated: F
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE)
                              op: Equal
                              rhs: {(DQ (no))}
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_dependencies
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name BUNDLE_FILE>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Op_DPipe]
                              children: [
                                (command.Simple
                                  words: [{(which)} {(curl)}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_Great '>'>
                                      fd: 16777215
                                      arg_word: {(/dev/null)}
                                    )
                                  ]
                                )
                                (C {(fail)} {(DQ (E_CURL_MISSING))} 
                                  {
                                    (DQ 
                                      (
'Please install curl(1). Sandstorm uses it to download updates.'
                                      )
                                    )
                                  }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (${ VSub_Name DEV_TCP_USABLE))} 
                                  {(Lit_Equals '=')} {(DQ (unchecked))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(C {(test_if_dev_tcp_works)})]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (${ VSub_Name DEV_TCP_USABLE))} 
                                  {(Lit_Equals '=')} {(DQ (no))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Op_DPipe]
                              children: [
                                (command.Simple
                                  words: [{(which)} {(nc)}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_Great '>'>
                                      fd: 16777215
                                      arg_word: {(/dev/null)}
                                    )
                                  ]
                                )
                                (C {(fail)} {(DQ (E_NC_MISSING))} 
                                  {
                                    (DQ 
                                      (
"Please install nc(1). (Package may be called 'netcat-traditional' or 'netcat-openbsd'.)"
                                      )
                                    )
                                  }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (command.Simple
                          words: [{(which)} {(tar)}]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (C {(fail)} {(DQ (E_TAR_MISSING))} {(DQ ('Please install tar(1).'))})
                      ]
                    )
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (command.Simple
                          words: [{(which)} {(xz)}]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (C {(fail)} {(DQ (E_XZ_MISSING))} 
                          {(DQ ("Please install xz(1). (Package may be called 'xz-utils'.)"))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_valid_bundle_file
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name BUNDLE_FILE>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUNDLE_DIR)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (command.Pipeline
                                                children: [
                                                  (command.Subshell
                                                    command_list: 
                                                      (command.CommandList
                                                        children: [
                                                          (command.AndOr
                                                            ops: [Op_DPipe]
                                                            children: [
                                                              (C {(tar)} {(Jtf)} 
                                                                {
                                                                  (DQ 
                                                                    ($ VSub_DollarName '$BUNDLE_FILE')
                                                                  )
                                                                }
                                                              )
                                                              (C {(true)})
                                                            ]
                                                          )
                                                        ]
                                                      )
                                                  )
                                                  (C {(head)} {(-n)} {(1)})
                                                ]
                                                negated: F
                                              )
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.DBracket
                                          expr: 
                                            (bool_expr.LogicalNot
                                              child: 
                                                (bool_expr.Binary
                                                  op_id: BoolBinary_EqualTilde
                                                  left: {(DQ ($ VSub_DollarName '$BUNDLE_DIR'))}
                                                  right: 
                                                    {(sandstorm-) (Lit_Other '(') (Lit_Other '[') (0-9) 
                                                      (Lit_Other ']') (Lit_Other '+') (Lit_Other ')') (/)
                                                    }
                                                )
                                            )
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(fail)} {(DQ (E_INVALID_BUNDLE))} 
                                      {
                                        (DQ ($ VSub_DollarName '$BUNDLE_FILE') 
                                          (': Not a valid Sandstorm bundle')
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUILD)
                                  op: Equal
                                  rhs: 
                                    {
                                      (braced_var_sub
                                        token: <VSub_Name BASH_REMATCH>
                                        bracket_op: 
                                          (bracket_op.ArrayIndex
                                            expr: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUNDLE_FILE)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(readlink)} {(-f)} 
                                                {(DQ ($ VSub_DollarName '$BUNDLE_FILE'))}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: detect_init_system
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:INIT_SYSTEM)
                          op: Equal
                          rhs: {(DQ (unknown))}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(grep)} {(-q)} {(systemd)} {(/proc/1/comm)})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:INIT_SYSTEM)
                                  op: Equal
                                  rhs: {(DQ (systemd))}
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-e)} {(/etc/init.d)} {(Lit_RBracket ']')})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:INIT_SYSTEM)
                                  op: Equal
                                  rhs: {(DQ (sysvinit))}
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_install_mode
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(-n)} 
                      {(SQ <'Sandstorm makes it easy to run web apps on your own server. '>)}
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: <VSub_Name CHOSEN_INSTALL_MODE>
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: VTest_ColonHyphen
                                              arg_word: {(2)}
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (no))} {(Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name PREFER_ROOT>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'NOTE: Showing you all options, including development options, but omitting '
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'      init script automation, because you chose to install without using root.'
                                  )
                                )
                              }
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: <VSub_Name CHOSEN_INSTALL_MODE>
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: VTest_ColonHyphen
                                              arg_word: {(2)}
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name CHOSEN_INSTALL_MODE>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('You can have:'))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'1. A typical install, to use Sandstorm (press enter to accept this default)'
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'2. A development server, for working on Sandstorm itself or localhost-based app development'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt-numeric)} 
                                                {
                                                  (DQ 
                                                    (
'How are you going to use this Sandstorm install?'
                                                    )
                                                  )
                                                } {(DQ (1))}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (1))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CHOSEN_INSTALL_MODE'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(C {(assert_full_server_dependencies)}) (C {(full_server_install)})]
                        )
                      ]
                      else_action: [(C {(dev_server_install)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: assert_full_server_dependencies
              body: 
                (command.BraceGroup
                  children: [
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (command.Simple
                          words: [{(which)} {(openssl)}]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(/dev/null)}
                            )
                          ]
                        )
                        (C {(fail)} {(DQ (E_OPENSSL_MISSING))} 
                          {
                            (DQ 
                              (
'Please install openssl(1). Sandstorm uses it for the Sandcats.io dynamic DNS service.'
                              )
                            )
                          }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: dev_server_install
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Op_DAmp]
                                  children: [
                                    (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                      {(DQ ($ VSub_DollarName '$PREFER_ROOT'))} {(Lit_RBracket ']')}
                                    )
                                    (C {(Lit_LBracket '[')} {(DQ (no))} {(Lit_Equals '=')} 
                                      {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'If you want app developer mode for a Sandstorm install, you need root'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('due to limitations in the Linux kernel.'))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {(DQ ('To set up Sandstorm, we will use sudo to switch to root, then'))}
                            )
                            (C {(echo)} {(DQ ('provide further information before doing the install.'))})
                            (C {(echo)} 
                              {(DQ ("Sandstorm's database and web interface won't run as root."))}
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                          {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:ACCEPTED_SUDO_FOR_DEV_SERVER)
                                          op: Equal
                                          rhs: {(DQ (no))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.If
                                  arms: [
                                    (if_arm
                                      cond: [
                                        (command.Sentence
                                          child: 
                                            (C {(prompt-yesno)} {(DQ ('OK to continue?'))} {(DQ (yes))})
                                          terminator: <Op_Semi ';'>
                                        )
                                      ]
                                      action: [
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: 
                                                (sh_lhs_expr.Name
                                                  name: ACCEPTED_SUDO_FOR_DEV_SERVER
                                                )
                                              op: Equal
                                              rhs: {(DQ (yes))}
                                            )
                                          ]
                                        )
                                      ]
                                    )
                                  ]
                                  else_action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:ACCEPTED_SUDO_FOR_DEV_SERVER)
                                          op: Equal
                                          rhs: {(DQ (no))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                          {(DQ ($ VSub_DollarName '$ACCEPTED_SUDO_FOR_DEV_SERVER'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(rerun_script_as_root)} 
                                      {(Lit_VarLike 'CHOSEN_INSTALL_MODE=') (2)}
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.Simple
                                  words: [
                                    {(fail)}
                                    {(DQ (E_NEED_ROOT))}
                                    {
                                      (DQ ('\n') 
                                        (
'One development feature does require root. To install anyway, run:\n'
                                        ) ('\n') ('install.sh -u\n') ('\n') 
                                        (
"to install without using root access. In that case, Sandstorm will operate OK but package tracing ('spk dev') will not work."
                                        )
                                      )
                                    }
                                  ]
                                  more_env: [
                                    (env_pair
                                      name: SHOW_FAILURE_MSG
                                      val: {(no)}
                                    )
                                    (env_pair
                                      name: REPORT
                                      val: {(no)}
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Op_DAmp]
                                  children: [
                                    (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                      {(KW_Bang '!') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                    )
                                    (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                      {(DQ ($ VSub_DollarName '$PREFER_ROOT'))} {(Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ("We're going to:"))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ ('* Install Sandstorm in ') (${ VSub_Name DEFAULT_DIR_FOR_ROOT) (.))
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'* Automatically keep Sandstorm up-to-date (with signed updates).'
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Create a service user (') 
                                  ($ VSub_DollarName '$DEFAULT_SERVER_USER') (") that owns Sandstorm's files.")
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(-n)} 
                                          {
                                            (DQ 
                                              (braced_var_sub
                                                token: <VSub_Name SUDO_USER>
                                                suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                              )
                                            )
                                          } {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ ('* Add you (') ($ VSub_DollarName '$SUDO_USER') 
                                          (') to the ') ($ VSub_DollarName '$DEFAULT_SERVER_USER') (' group so you can read/write app data.')
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'* Expose the service only on localhost aka local.sandstorm.io, not the public Internet.'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ("* Enable 'dev accounts', for easy developer login."))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (unknown))} 
                                          {(Lit_Equals '=') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$INIT_SYSTEM'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'*** WARNING: Could not detect how to run Sandstorm at startup on your system. ***'
                                          )
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (C {(echo)} 
                                  {
                                    (DQ ('* Configure Sandstorm to start on system boot (with ') 
                                      ($ VSub_DollarName '$INIT_SYSTEM') (').')
                                    )
                                  }
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Listen for inbound email on port ') 
                                  (${ VSub_Name DEFAULT_SMTP_PORT) (.)
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ 
                                              (
"Press enter to accept defaults. Type 'no' to customize."
                                              )
                                            )
                                          } {(DQ (yes))}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_DEFAULTS)
                                          op: Equal
                                          rhs: {(DQ (yes))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (C {(echo)} {(DQ )})
                                (C {(echo)} {(DQ ('OK. We will prompt you with every question.'))})
                                (C {(echo)} {(DQ )})
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DEFAULT_UPDATE_CHANNEL'))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: <VSub_Name USE_EXTERNAL_INTERFACE>
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: VTest_ColonHyphen
                                              arg_word: {(no)}
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: <VSub_Name SS_HOSTNAME>
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: VTest_ColonHyphen
                                              arg_word: {(local.sandstorm.io)}
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT)
                                  op: Equal
                                  rhs: {(DQ (${ VSub_Name DEFAULT_SMTP_PORT))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_SANDCATS)
                                  op: Equal
                                  rhs: {(DQ (no))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: Equal
                                  rhs: {(DQ (${ VSub_Name DEFAULT_PORT))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: full_server_install
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name PREFER_ROOT))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_AUTO_NEEDS_SUDO))}
                                {
                                  (DQ 
                                    (
'The automatic setup process requires sudo. Try again with option 2, development server, to customize.'
                                    )
                                  )
                                }
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)})]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(-z)} 
                                          {
                                            (DQ 
                                              (braced_var_sub
                                                token: <VSub_Name DESIRED_SANDCATS_NAME>
                                                suffix_op: (suffix_op.Unary op_id:VTest_Hyphen arg_word:(word.Empty))
                                              )
                                            )
                                          } {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(local)} 
                                      {(Lit_VarLike 'MSG=') 
                                        (DQ 
                                          (
'For now, USE_DEFAULTS for full server installs requires a DESIRED_SANDCATS_NAME variable.'
                                          )
                                        )
                                      }
                                    )
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:MSG)
                                          op: Equal
                                          rhs: 
                                            {
                                              (DQ ($ VSub_DollarName '$MSG') 
                                                (
' If you need support for non-sandcats full-server unattended installs, please file a bug.'
                                                )
                                              )
                                            }
                                        )
                                      ]
                                    )
                                    (C {(fail)} {(DQ (E_USE_DEFAULTS_NEEDS_DESIRED_SANDCATS_NAME))} 
                                      {(DQ ($ VSub_DollarName '$MSG'))}
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.If
                                  arms: [
                                    (if_arm
                                      cond: [
                                        (command.Sentence
                                          child: 
                                            (C {(Lit_LBracket '[')} {(-z)} 
                                              {
                                                (DQ 
                                                  (braced_var_sub
                                                    token: 
                                                      <VSub_Name SANDCATS_DOMAIN_RESERVATION_TOKEN>
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } {(Lit_RBracket ']')}
                                            )
                                          terminator: <Op_Semi ';'>
                                        )
                                      ]
                                      action: [
                                        (C {(local)} 
                                          {(Lit_VarLike 'MSG=') 
                                            (DQ 
                                              (
'When operating in USE_DEFAULTS mode, if you want a sandcats.io domain,'
                                              )
                                            )
                                          }
                                        )
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: (sh_lhs_expr.Name name:MSG)
                                              op: Equal
                                              rhs: 
                                                {
                                                  (DQ ($ VSub_DollarName '$MSG') 
                                                    (
' you must pre-reserve it before running this script. Specify it via the'
                                                    )
                                                  )
                                                }
                                            )
                                          ]
                                        )
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: (sh_lhs_expr.Name name:MSG)
                                              op: Equal
                                              rhs: 
                                                {
                                                  (DQ ($ VSub_DollarName '$MSG') 
                                                    (
' SANDCATS_DOMAIN_RESERVATION_TOKEN environment variable.'
                                                    )
                                                  )
                                                }
                                            )
                                          ]
                                        )
                                        (C {(fail)} {(DQ (E_USE_DEFAULTS_NEEDS_DESIRED_SANDCATS_NAME))} 
                                          {(DQ ($ VSub_DollarName '$MSG'))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(disable_smtp_port_25_if_port_unavailable)})
                    (C {(local)} {(Lit_VarLike 'PLANNED_SMTP_PORT=') (DQ (30025))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$PORT_25_AVAILABLE'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PLANNED_SMTP_PORT)
                                  op: Equal
                                  rhs: {(DQ (25))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name ACCEPTED_FULL_SERVER_INSTALL>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(disable_https_if_ports_unavailable)})
                            (C {(echo)} {(DQ ("We're going to:"))})
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ ('* Install Sandstorm in ') 
                                  ($ VSub_DollarName '$DEFAULT_DIR_FOR_ROOT')
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('* Automatically keep Sandstorm up-to-date'))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                          {(Lit_Equals '=') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$SANDCATS_GETCERTIFICATE'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'* Configure auto-renewing HTTPS if you use a subdomain of sandcats.io'
                                          )
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Create a service user (') 
                                  ($ VSub_DollarName '$DEFAULT_SERVER_USER') (") that owns Sandstorm's files")
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (unknown))} 
                                          {(Lit_Equals '=') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$INIT_SYSTEM'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'*** WARNING: Could not detect how to run Sandstorm at startup on your system. ***'
                                          )
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (C {(echo)} 
                                  {
                                    (DQ ('* Configure Sandstorm to start on system boot (with ') 
                                      ($ VSub_DollarName '$INIT_SYSTEM') (')')
                                    )
                                  }
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('* Listen for inbound email on port ') 
                                  (${ VSub_Name PLANNED_SMTP_PORT) (.)
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                          {(KW_Bang '!') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} 
                                      {(DQ ('To set up Sandstorm, we will need to use sudo.'))}
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (C {(echo)} 
                                  {(DQ ("Rest assured that Sandstorm itself won't run as root."))}
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} {(DQ ('OK to continue?'))} {(DQ (yes))})
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL)
                                          op: Equal
                                          rhs: {(yes)}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL)
                                      op: Equal
                                      rhs: {(no)}
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                          {
                                            (DQ 
                                              ($ VSub_DollarName 
'$SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN'
                                              )
                                            )
                                          } {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'NOTE: It looks like your system already has some other web server installed'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      (port 80 and/or 443 are taken), so Sandstorm cannot act as your main'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} {(DQ ('      web server.'))})
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          ('      This script can set up Sandstorm to run on port ') ($ VSub_DollarName '$DEFAULT_PORT') (' instead,')
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
"      without HTTPS. This makes sense if you're OK with typing the port number"
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
"      into your browser whenever you access Sandstorm and you don't need"
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      security. This also makes sense if you are going to set up a reverse proxy;'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      if so, see https://docs.sandstorm.io/en/latest/administering/reverse-proxy/'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      If you want, you can quit this script with Ctrl-C now, and go uninstall'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
'      your other web server, and then run this script again. It is also OK to'
                                          )
                                        )
                                      }
                                    )
                                    (C {(echo)} {(DQ ('      proceed if you want.'))})
                                    (C {(echo)} {(DQ )})
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (command.Pipeline
                                                  children: [
                                                    (C {(prompt-yesno)} 
                                                      {
                                                        (DQ 
                                                          (
'OK to skip automatic HTTPS setup & bind to port '
                                                          ) ($ VSub_DollarName '$DEFAULT_PORT') (' instead?')
                                                        )
                                                      } {(DQ (yes))}
                                                    )
                                                  ]
                                                  negated: T
                                                )
                                              terminator: <Op_Semi ';'>
                                            )
                                          ]
                                          action: [
                                            (C {(fail)} {(DQ (E_USER_REFUSED_DEFAULT_PORT))} 
                                              {
                                                (DQ 
                                                  (
'Exiting now. You can re-run the installer whenever you are ready.'
                                                  )
                                                )
                                              }
                                            )
                                          ]
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                          {(KW_Bang '!') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                                  {
                                                    (DQ 
                                                      ($ VSub_DollarName 
'$ACCEPTED_FULL_SERVER_INSTALL'
                                                      )
                                                    )
                                                  } {(Lit_RBracket ']')}
                                                )
                                              terminator: <Op_Semi ';'>
                                            )
                                          ]
                                          action: [
                                            (C {(rerun_script_as_root)} 
                                              {(Lit_VarLike 'CHOSEN_INSTALL_MODE=') (1)} {(Lit_VarLike 'ACCEPTED_FULL_SERVER_INSTALL=') (yes)} 
                                              {(Lit_VarLike 'OVERRIDE_SANDCATS_BASE_DOMAIN=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: <VSub_Name OVERRIDE_SANDCATS_BASE_DOMAIN>
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } 
                                              {(Lit_VarLike 'OVERRIDE_SANDCATS_API_BASE=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: <VSub_Name OVERRIDE_SANDCATS_API_BASE>
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } {(Lit_VarLike 'OVERRIDE_SANDCATS_GETCERTIFICATE=') (DQ (${ VSub_Name SANDCATS_GETCERTIFICATE))} 
                                              {(Lit_VarLike 'OVERRIDE_NC_PATH=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: <VSub_Name OVERRIDE_NC_PATH>
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              } 
                                              {(Lit_VarLike 'OVERRIDE_SANDCATS_CURL_PARAMS=') 
                                                (DQ 
                                                  (braced_var_sub
                                                    token: <VSub_Name OVERRIDE_SANDCATS_CURL_PARAMS>
                                                    suffix_op: 
                                                      (suffix_op.Unary
                                                        op_id: VTest_ColonHyphen
                                                        arg_word: (word.Empty)
                                                      )
                                                  )
                                                )
                                              }
                                            )
                                          ]
                                        )
                                      ]
                                    )
                                    (C {(echo)} {(DQ )})
                                    (C {(echo)} 
                                      {(DQ ('The automatic setup script needs root in order to:'))}
                                    )
                                    (C {(echo)} 
                                      {(DQ ('* Create a separate user to run Sandstorm as, and'))}
                                    )
                                    (C {(echo)} {(DQ ('* Set up Sandstorm to start on system boot.'))})
                                    (C {(fail)} {(DQ (E_DECLINED_AUTO_SETUP_DETAILS))} 
                                      {
                                        (DQ 
                                          (
'For a customized install, please re-run install.sh, and choose option (2) '
                                          )
                                        )
                                      } {(DQ ('to do a development install.'))}
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name ACCEPTED_FULL_SERVER_INSTALL))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DEFAULT_UPDATE_CHANNEL'))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DIR)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DEFAULT_DIR_FOR_ROOT'))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_SANDCATS)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DESIRED_SERVER_USER)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DEFAULT_SERVER_USER'))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: Equal
                                  rhs: {(DQ (${ VSub_Name DEFAULT_PORT))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:MONGO_PORT)
                                  op: Equal
                                  rhs: {(DQ (6081))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT)
                                  op: Equal
                                  rhs: {(DQ (${ VSub_Name PLANNED_SMTP_PORT))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.Simple
                          words: [
                            {(fail)}
                            {(DQ (E_USER_WANTS_CUSTOM_SETTINGS))}
                            {
                              (DQ 
                                (
'If you prefer a more manual setup experience, try installing in development mode.'
                                )
                              )
                            }
                          ]
                          more_env: [(env_pair name:REPORT val:{(no)})]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_configure
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(-n)} 
                      {(DQ ('As a Sandstorm user, you are invited to use a free Internet hostname '))}
                    )
                    (C {(echo)} {(DQ ('as a subdomain of sandcats.io,'))})
                    (C {(echo)} {(DQ ('a service operated by the Sandstorm development team.'))})
                    (C {(sandcats_generate_keys)})
                    (C {(echo)} {(DQ )})
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'Sandcats.io protects your privacy and is subject to terms of use. By using it,'
                          )
                        )
                      }
                    )
                    (C {(echo)} 
                      {(DQ ('you agree to the terms of service & privacy policy available here:'))}
                    )
                    (C {(echo)} {(DQ ('https://sandcats.io/terms https://sandcats.io/privacy'))})
                    (C {(echo)} {(DQ )})
                    (C {(sandcats_register_name)})
                    (C {(sandcats_configure_https)})
                  ]
                )
            )
            (command.ShFunction
              name: configure_hostnames
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_SANDCATS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(C {(sandcats_configure)})]
                        )
                      ]
                    )
                    (C {(choose_port)})
                    (C {(choose_mongo_port)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_EXTERNAL_INTERFACE'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BIND_IP)
                                  op: Equal
                                  rhs: {(0.0.0.0)}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: <VSub_Name SS_HOSTNAME>
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: VTest_ColonHyphen
                                              arg_word: 
                                                {
                                                  (command_sub
                                                    left_token: <Left_DollarParen '$('>
                                                    command_list: 
                                                      (command.CommandList
                                                        children: [
                                                          (command.AndOr
                                                            ops: [Op_DPipe]
                                                            children: [
                                                              (command.Simple
                                                                words: [{(hostname)} {(-f)}]
                                                                redirects: [
                                                                  (redir.Redir
                                                                    op: <Redir_Great '2>'>
                                                                    fd: 2
                                                                    arg_word: {(/dev/null)}
                                                                  )
                                                                ]
                                                              )
                                                              (C {(hostname)})
                                                            ]
                                                          )
                                                        ]
                                                      )
                                                  )
                                                }
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:BIND_IP)
                              op: Equal
                              rhs: {(127.0.0.1)}
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                              op: Equal
                              rhs: {(local.sandstorm.io)}
                            )
                          ]
                        )
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                      {(KW_Bang '!') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                    )
                                  terminator: <Op_Semi ';'>
                                )
                              ]
                              action: [
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'Note: local.sandstorm.io maps to 127.0.0.1, i.e. your local machine.'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'For reasons that will become clear in the next step, you should use this'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} {(DQ ("instead of 'localhost'."))})
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'PORT_SUFFIX=') (DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$PORT'))} 
                                  {(Lit_Equals '=')} {(DQ (80))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [(assign_pair lhs:(sh_lhs_expr.Name name:PORT_SUFFIX) op:Equal rhs:{(DQ )})]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:PORT_SUFFIX)
                              op: Equal
                              rhs: {(DQ (':') (${ VSub_Name PORT))}
                            )
                          ]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DEFAULT_BASE_URL)
                          op: Equal
                          rhs: {(DQ ('http://') (${ VSub_Name SS_HOSTNAME) (${ VSub_Name PORT_SUFFIX))}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_HTTPS_SUCCESSFUL'))} {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_BASE_URL)
                                  op: Equal
                                  rhs: {(DQ ('https://') ($ VSub_DollarName '$SS_HOSTNAME'))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:HTTPS_PORT)
                                  op: Equal
                                  rhs: {(443)}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: Equal
                                  rhs: {(80)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BASE_URL)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DEFAULT_BASE_URL'))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:BASE_URL)
                              op: Equal
                              rhs: 
                                {
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [
                                          (C {(prompt)} {(DQ ('URL users will enter in browser:'))} 
                                            {(DQ ($ VSub_DollarName '$DEFAULT_BASE_URL'))}
                                          )
                                        ]
                                      )
                                  )
                                }
                            )
                          ]
                        )
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (command.Pipeline
                                      children: [
                                        (command.DBracket
                                          expr: 
                                            (bool_expr.Binary
                                              op_id: BoolBinary_EqualTilde
                                              left: {(DQ ($ VSub_DollarName '$BASE_URL'))}
                                              right: 
                                                {(Lit_Other '^') (http) (Lit_Other '(') (s) 
                                                  (Lit_Other '?') (Lit_Other ')') (Lit_Other ':') (//)
                                                }
                                            )
                                        )
                                      ]
                                      negated: T
                                    )
                                  terminator: <Op_Semi ';'>
                                )
                              ]
                              action: [
                                (C {(local)} 
                                  {(Lit_VarLike 'PROPOSED_BASE_URL=') 
                                    (DQ ('http://') (${ VSub_Name BASE_URL))
                                  }
                                )
                                (command.Simple
                                  words: [
                                    {(echo)}
                                    {
                                      (DQ ('** You entered ') (${ VSub_Name BASE_URL) 
                                        (', which needs http:// at the front. I can use:')
                                      )
                                    }
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_GreatAnd '>&'>
                                      fd: 16777215
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                                (command.Simple
                                  words: [{(echo)} {(DQ ('        ') (${ VSub_Name PROPOSED_BASE_URL))}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_GreatAnd '>&'>
                                      fd: 16777215
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                                (command.If
                                  arms: [
                                    (if_arm
                                      cond: [
                                        (command.Sentence
                                          child: (C {(prompt-yesno)} {(DQ ('Is this OK?'))} {(yes)})
                                          terminator: <Op_Semi ';'>
                                        )
                                      ]
                                      action: [
                                        (command.ShAssignment
                                          pairs: [
                                            (assign_pair
                                              lhs: (sh_lhs_expr.Name name:BASE_URL)
                                              op: Equal
                                              rhs: {(DQ (${ VSub_Name PROPOSED_BASE_URL))}
                                            )
                                          ]
                                        )
                                      ]
                                    )
                                  ]
                                  else_action: [(C {(configure_hostnames)})]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: BoolBinary_EqualTilde
                                      left: {(DQ ($ VSub_DollarName '$BASE_URL'))}
                                      right: 
                                        {(Lit_Other '^') (http) (Lit_Other ':') (//localhost) 
                                          (Lit_Other '(') (Lit_Other '|') (Lit_Other ':') (Lit_Other '[') (0-9) (Lit_Other ']') (Lit_Other '*') (Lit_Other ')') 
                                          (Lit_Other '(') (/) (Lit_Other .) (Lit_Other '*') (Lit_Other ')') (Lit_Other '?') (Lit_Other '$')
                                        }
                                    )
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD)
                                  op: Equal
                                  rhs: 
                                    {(Lit_Star '*') (.local.sandstorm.io) 
                                      (braced_var_sub
                                        token: <VSub_Name BASH_REMATCH>
                                        bracket_op: 
                                          (bracket_op.ArrayIndex
                                            expr: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: BoolBinary_EqualTilde
                                      left: {(DQ ($ VSub_DollarName '$BASE_URL'))}
                                      right: 
                                        {(Lit_Other '^') (Lit_Other '[') (Lit_Other '^') 
                                          (Lit_Other ':') (/) (Lit_Other ']') (Lit_Other '*') (Lit_Other ':') (//) (Lit_Other '(') (Lit_Other '[') (Lit_Other '^') (/) 
                                          (Lit_Other ']') (Lit_Other '*') (Lit_Other ')') (/) (Lit_Other '?') (Lit_Other '$')
                                        }
                                    )
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (braced_var_sub
                                          token: <VSub_Name DEFAULT_WILDCARD>
                                          suffix_op: 
                                            (suffix_op.Unary
                                              op_id: VTest_ColonHyphen
                                              arg_word: 
                                                {('*.') 
                                                  (braced_var_sub
                                                    token: <VSub_Name BASH_REMATCH>
                                                    bracket_op: 
                                                      (bracket_op.ArrayIndex
                                                        expr: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                                                      )
                                                  )
                                                }
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [(assign_pair lhs:(sh_lhs_expr.Name name:DEFAULT_WILDCARD) op:Equal rhs:(word.Empty))]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:WILDCARD_HOST)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DEFAULT_WILDCARD'))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                      {(KW_Bang '!') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$USE_DEFAULTS'))} {(Lit_RBracket ']')}
                                    )
                                  terminator: <Op_Semi ';'>
                                )
                              ]
                              action: [
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'Sandstorm requires you to set up a wildcard DNS entry pointing at the server.'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'This allows Sandstorm to allocate new hosts on-the-fly for sandboxing purposes.'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
"Please enter a DNS hostname containing a '*' which maps to your server. For "
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'example, if you have mapped *.foo.example.com to your server, you could enter'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) 
                                      ('*.foo.example.com') (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) 
                                      ('. You can also specify that hosts should have a special')
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ ('prefix, like ') 
                                      (word_part.EscapedLiteral
                                        token: <Lit_EscapedChar '\\"'>
                                      ) ('ss-*.foo.example.com') (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) 
                                      (". Note that if your server's main page")
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'is served over SSL, the wildcard address must support SSL as well, which'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'implies that you must have a wildcard certificate. For local-machine servers,'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ 
                                      (
'we have mapped *.local.sandstorm.io to 127.0.0.1 for your convenience, so you'
                                      )
                                    )
                                  }
                                )
                                (C {(echo)} 
                                  {
                                    (DQ ('can use ') 
                                      (word_part.EscapedLiteral
                                        token: <Lit_EscapedChar '\\"'>
                                      ) ('*.local.sandstorm.io') (word_part.EscapedLiteral token:<Lit_EscapedChar '\\"'>) 
                                      (' here. If you are serving off a non-standard')
                                    )
                                  }
                                )
                                (C {(echo)} {(DQ ('port, you must include it here as well.'))})
                              ]
                            )
                          ]
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:WILDCARD_HOST)
                              op: Equal
                              rhs: 
                                {
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [
                                          (C {(prompt)} {(DQ ('Wildcard host:'))} 
                                            {(DQ ($ VSub_DollarName '$DEFAULT_WILDCARD'))}
                                          )
                                        ]
                                      )
                                  )
                                }
                            )
                          ]
                        )
                        (command.WhileUntil
                          keyword: <KW_While while>
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.DBracket
                                      expr: 
                                        (bool_expr.Binary
                                          op_id: BoolBinary_EqualTilde
                                          left: {(DQ ($ VSub_DollarName '$WILDCARD_HOST'))}
                                          right: 
                                            {(Lit_Other '^') (Lit_Other '[') (Lit_Other '^') 
                                              (Lit_Other '*') (Lit_Other ']') (Lit_Other '*') (Lit_Other '[') (Lit_Other '*') (Lit_Other ']') (Lit_Other '[') 
                                              (Lit_Other '^') (Lit_Other '*') (Lit_Other ']') (Lit_Other '*') (Lit_Other '$')
                                            }
                                        )
                                    )
                                  ]
                                  negated: T
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          body: 
                            (command.DoGroup
                              children: [
                                (C {(error)} 
                                  {
                                    (DQ 
                                      (
'Invalid wildcard host. It must contain exactly one asterisk.'
                                      )
                                    )
                                  }
                                )
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:WILDCARD_HOST)
                                      op: Equal
                                      rhs: 
                                        {
                                          (command_sub
                                            left_token: <Left_DollarParen '$('>
                                            command_list: 
                                              (command.CommandList
                                                children: [
                                                  (C {(prompt)} {(DQ ('Wildcard host:'))} 
                                                    {(DQ ($ VSub_DollarName '$DEFAULT_WILDCARD'))}
                                                  )
                                                ]
                                              )
                                          )
                                        }
                                    )
                                  ]
                                )
                              ]
                            )
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_install_dir
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name DIR>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(local)} 
                              {(Lit_VarLike 'DEFAULT_DIR=') 
                                (DQ ($ VSub_DollarName '$DEFAULT_DIR_FOR_ROOT'))
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ (yes))} 
                                          {(KW_Bang '!') (Lit_Equals '=')} {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:DEFAULT_DIR)
                                          op: Equal
                                          rhs: {(DQ ($ VSub_DollarName '$DEFAULT_DIR_FOR_NON_ROOT'))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DIR)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt)} 
                                                {(DQ ('Where would you like to put Sandstorm?'))} {(DQ ($ VSub_DollarName '$DEFAULT_DIR'))}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.AndOr
                                  ops: [Op_DPipe Op_DPipe]
                                  children: [
                                    (C {(Lit_LBracket '[')} {(-e)} 
                                      {(DQ ($ VSub_DollarName '$DIR') (/sandstorm.conf))} {(Lit_RBracket ']')}
                                    )
                                    (C {(Lit_LBracket '[')} {(-e)} 
                                      {(DQ ($ VSub_DollarName '$DIR') (/var))} {(Lit_RBracket ']')}
                                    )
                                    (C {(Lit_LBracket '[')} {(-e)} 
                                      {(DQ ($ VSub_DollarName '$DIR') (/sandstorm))} {(Lit_RBracket ']')}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {(DQ ('This script is trying to install to ') (${ VSub_Name DIR) (.))}
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ ('You seem to already have a ') (${ VSub_Name DIR) 
                                  (
' directory with a Sandstorm installation inside. You should either:'
                                  )
                                )
                              }
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'1. Reconfigure that Sandstorm install using its configuration file -- '
                                  ) (${ VSub_Name DIR) ('/sandstorm.conf -- or the admin interface. See docs at:')
                                )
                              }
                            )
                            (C {(error)} {(DQ ('https://docs.sandstorm.io/en/latest/administering/'))})
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'2. Uninstall Sandstorm before attempting to perform a new install. Even if you created a sandcats.io hostname, it is safe to uninstall so long as you do not need the data in your Sandstorm install. When you re-install Sandstorm, you can follow a process to use the old hostname with the new install. See uninstall docs at:'
                                  )
                                )
                              }
                            )
                            (C {(error)} 
                              {(DQ ('https://docs.sandstorm.io/en/latest/install/#uninstall'))}
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'3. Use a different target directory for the new Sandstorm install. Try running install.sh with the -d option.'
                                  )
                                )
                              }
                            )
                            (C {(error)} {(DQ )})
                            (C {(error)} 
                              {
                                (DQ 
                                  (
'4. Retain your data, but restore your Sandstorm code and configuration to a fresh copy. To do that, keep a backup  of '
                                  ) (${ VSub_Name DIR) 
                                  (
'/var and then do a fresh install; stop the Sandstorm service, and restore your backup of '
                                  ) (${ VSub_Name DIR) ('/var. You may need to adjust permissions after doing that.')
                                )
                              }
                            )
                            (command.Simple
                              words: [
                                {(fail)}
                                {(DQ (E_DIR_ALREADY_EXISTS))}
                                {
                                  (DQ 
                                    (
'Please try one of the above. Contact https://groups.google.com/d/forum/sandstorm-dev for further help.'
                                    )
                                  )
                                }
                              ]
                              more_env: [(env_pair name:REPORT val:{(no)})]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(mkdir)} {(-p)} {(DQ ($ VSub_DollarName '$DIR'))})
                    (C {(cd)} {(DQ ($ VSub_DollarName '$DIR'))})
                  ]
                )
            )
            (command.ShFunction
              name: choose_smtp_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name SMTP_LISTEN_PORT>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Lit_VarLike 'REQUESTED_SMTP_PORT=') 
                        (command_sub
                          left_token: <Left_DollarParen '$('>
                          command_list: 
                            (command.CommandList
                              children: [
                                (C {(prompt-numeric)} 
                                  {
                                    (DQ 
                                      (
'Sandstorm grains can receive email. What port should Sandstorm listen on, for inbound SMTP?'
                                      )
                                    )
                                  } {(DQ (${ VSub_Name DEFAULT_SMTP_PORT))}
                                )
                              ]
                            )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} {(DQ (${ VSub_Name REQUESTED_SMTP_PORT))} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(C {(choose_smtp_port)})]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT)
                              op: Equal
                              rhs: {(DQ (${ VSub_Name REQUESTED_SMTP_PORT))}
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: load_existing_settings
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-e)} {(sandstorm.conf)} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ('Found existing sandstorm.conf. Using it.'))})
                    (C {(.)} {(sandstorm.conf)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name SERVER_USER>
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: VTest_ColonPlus
                                            arg_word: {(set)}
                                          )
                                      )
                                    )
                                  } {(KW_Bang '!') (Lit_Equals '=')} {(KW_Set set)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_CONF_DOES_NOT_SET_SERVER_USER))} 
                              {
                                (DQ 
                                  (
'Existing config does not set SERVER_USER. Please fix or delete it.'
                                  )
                                )
                              }
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name UPDATE_CHANNEL>
                                        suffix_op: 
                                          (suffix_op.Unary
                                            op_id: VTest_ColonHyphen
                                            arg_word: {(none)}
                                          )
                                      )
                                    )
                                  } {(KW_Bang '!') (Lit_Equals '=')} {(none)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_UPDATE_CHANNEL)
                                  op: Equal
                                  rhs: {($ VSub_DollarName '$UPDATE_CHANNEL')}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_server_user_if_needed
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-e)} {(sandstorm.conf)} {(Lit_RBracket ']')})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SERVER_USER)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(id)} {(-un)})]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name DESIRED_SERVER_USER>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SERVER_USER)
                                  op: Equal
                                  rhs: {(DQ ($ VSub_DollarName '$DESIRED_SERVER_USER'))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:CREATE_SERVER_USER)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ADD_SUDO_USER_TO_SERVER_GROUP)
                                  op: Equal
                                  rhs: {(DQ (no))}
                                )
                              ]
                            )
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SERVER_USER)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} {(DQ ('Local user account to run server under:'))} 
                                        {(sandstorm)}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$SERVER_USER'))} 
                              {(Lit_Equals '=')} {(root)} {(Lit_RBracket ']')}
                            )
                          terminator: <Op_Semi ';'>
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(echo)} {(DQ ('Sandstorm cannot run as root!'))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SERVER_USER)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt)} 
                                                {(DQ ('Local user account to run server under:'))} {(sandstorm)}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: create_server_user_if_needed
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Simple
                                  words: [{(id)} {(DQ ($ VSub_DollarName '$SERVER_USER'))}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_Great '>'>
                                      fd: 16777215
                                      arg_word: {(/dev/null)}
                                    )
                                    (redir.Redir
                                      op: <Redir_GreatAnd '2>&'>
                                      fd: 2
                                      arg_word: {(1)}
                                    )
                                  ]
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name CREATE_SERVER_USER>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ ("User account '") ($ VSub_DollarName '$SERVER_USER') 
                                              ("' doesn't exist. Create it?")
                                            )
                                          } {(yes)}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:CREATE_SERVER_USER)
                                          op: Equal
                                          rhs: {(yes)}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name CREATE_SERVER_USER>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(useradd)} {(--system)} {(--user-group)} {(DQ ($ VSub_DollarName '$SERVER_USER'))})
                    (C {(echo)} 
                      {
                        (DQ ("Note: Sandstorm's storage will only be accessible to the group '") 
                          ($ VSub_DollarName '$SERVER_USER') ("'.")
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (no))} {(Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name ADD_SUDO_USER_TO_SERVER_GROUP>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name SUDO_USER>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} 
                                          {
                                            (DQ ("Add user '") ($ VSub_DollarName '$SUDO_USER') 
                                              ("' to group '") ($ VSub_DollarName '$SERVER_USER') ("'?")
                                            )
                                          } {(no)}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(usermod)} {(-a)} {(-G)} {(DQ ($ VSub_DollarName '$SERVER_USER'))} 
                                      {(DQ ($ VSub_DollarName '$SUDO_USER'))}
                                    )
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (
"Added. Don't forget that group changes only apply at next login."
                                          )
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name PORT>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:PORT)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt-numeric)} {(DQ ('Server main HTTP port:'))} 
                                        {($ VSub_DollarName '$DEFAULT_PORT')}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$PORT'))} {(-lt)} {(1024)} 
                              {(Lit_RBracket ']')}
                            )
                          terminator: <Op_Semi ';'>
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'Ports below 1024 require root privileges. Sandstorm does not run as root.'
                                  )
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('To use port ') ($ VSub_DollarName '$PORT') 
                                  (", you'll need to set up a reverse proxy like nginx that ")
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'forwards to the internal higher-numbered port. The Sandstorm git repo '
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('contains an example nginx config for this.'))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:PORT)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt-numeric)} {(DQ ('Server main HTTP port:'))} 
                                                {($ VSub_DollarName '$DEFAULT_PORT')}
                                              )
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_mongo_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name MONGO_PORT>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Lit_VarLike 'DEFAULT_MONGO_PORT=') 
                        (DQ 
                          (word_part.ArithSub
                            anode: 
                              (arith_expr.Binary
                                op_id: Arith_Plus
                                left: (arith_expr.VarRef token:<Lit_ArithVarLike PORT>)
                                right: (arith_expr.ArithWord w:{(Lit_Digits 1)})
                              )
                          )
                        )
                      }
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$PORT'))} {(-lt)} 
                                  {(1024)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:DEFAULT_MONGO_PORT)
                                  op: Equal
                                  rhs: {(DQ (6081))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:MONGO_PORT)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt-numeric)} 
                                        {(DQ ('Database port (choose any unused port):'))} {(DQ (${ VSub_Name DEFAULT_MONGO_PORT))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: choose_external_or_internal
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$USE_EXTERNAL_INTERFACE'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(prompt-yesno)} {(DQ ('Expose to localhost only?'))} {(yes)})
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (command.ShAssignment
                                      pairs: [
                                        (assign_pair
                                          lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                          op: Equal
                                          rhs: {(DQ (no))}
                                        )
                                      ]
                                    )
                                  ]
                                )
                              ]
                              else_action: [
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                      op: Equal
                                      rhs: {(DQ (yes))}
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_auto_updates
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name UPDATE_CHANNEL>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(prompt-yesno)} {(DQ ('Automatically keep Sandstorm updated?'))} 
                                  {(yes)}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                                  op: Equal
                                  rhs: {($ VSub_DollarName '$DEFAULT_UPDATE_CHANNEL')}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL)
                              op: Equal
                              rhs: {(none)}
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_dev_accounts
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name ALLOW_DEV_ACCOUNTS))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name USE_EXTERNAL_INTERFACE))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {(DQ ("Sandstorm supports 'dev accounts', a feature that lets anyone log in"))}
                    )
                    (C {(echo)} 
                      {(DQ ('as admin and other sample users to a Sandstorm server. We recommend'))}
                    )
                    (C {(echo)} 
                      {(DQ ('it for app development, and absolutely do not recommend it for'))}
                    )
                    (C {(echo)} {(DQ ('a server on the public Internet.'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: (C {(prompt-yesno)} {(DQ ('Enable dev accounts?'))} {(DQ (yes))})
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS)
                                  op: Equal
                                  rhs: {(yes)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: save_config
              body: 
                (command.BraceGroup
                  children: [
                    (command.Simple
                      words: [
                        {(writeConfig)}
                        {(SERVER_USER)}
                        {(PORT)}
                        {(MONGO_PORT)}
                        {(BIND_IP)}
                        {(BASE_URL)}
                        {(WILDCARD_HOST)}
                        {(UPDATE_CHANNEL)}
                        {(ALLOW_DEV_ACCOUNTS)}
                        {(SMTP_LISTEN_PORT)}
                      ]
                      redirects: [
                        (redir.Redir
                          op: <Redir_Great '>'>
                          fd: 16777215
                          arg_word: {(sandstorm.conf)}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(writeConfig)} {(SANDCATS_BASE_DOMAIN)}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(sandstorm.conf)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_HTTPS_SUCCESSFUL'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.Simple
                              words: [{(writeConfig)} {(HTTPS_PORT)}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(sandstorm.conf)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)})
                    (C {(echo)} 
                      {(DQ ('Config written to ') ($ VSub_DollarName '$PWD') (/sandstorm.conf.))}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: download_latest_bundle_and_extract_if_needed
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-n)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name BUNDLE_FILE>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ ('Finding latest build for ') 
                          ($ VSub_DollarName '$DEFAULT_UPDATE_CHANNEL') (' channel...')
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:BUILD)
                          op: Equal
                          rhs: 
                            {
                              (DQ 
                                (command_sub
                                  left_token: <Left_DollarParen '$('>
                                  command_list: 
                                    (command.CommandList
                                      children: [
                                        (C {(curl)} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} 
                                          {(-fs)} 
                                          {
                                            (DQ ('https://install.sandstorm.io/') 
                                              ($ VSub_DollarName '$DEFAULT_UPDATE_CHANNEL') ('?from=0&type=install_v2')
                                            )
                                          }
                                        )
                                      ]
                                    )
                                )
                              )
                            }
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:BUILD_DIR)
                          op: Equal
                          rhs: {(DQ (sandstorm-) (${ VSub_Name BUILD))}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.LogicalNot
                                      child: 
                                        (bool_expr.Binary
                                          op_id: BoolBinary_EqualTilde
                                          left: {(DQ ($ VSub_DollarName '$BUILD'))}
                                          right: 
                                            {(Lit_Other '^') (Lit_Other '[') (0-9) (Lit_Other ']') 
                                              (Lit_Other '+') (Lit_Other '$')
                                            }
                                        )
                                    )
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(fail)} {(DQ (E_INVALID_BUILD_NUM))} 
                              {
                                (DQ ('Server returned invalid build number: ') 
                                  ($ VSub_DollarName '$BUILD')
                                )
                              }
                            )
                          ]
                        )
                      ]
                    )
                    (command.ShFunction
                      name: do-download
                      body: 
                        (command.BraceGroup
                          children: [
                            (C {(rm)} {(-rf)} {(DQ (${ VSub_Name BUILD_DIR))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:WORK_DIR)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ 
                                        (command_sub
                                          left_token: <Left_DollarParen '$('>
                                          command_list: 
                                            (command.CommandList
                                              children: [
                                                (C {(mktemp)} {(-d)} 
                                                  {(./sandstorm-installer.XXXXXXXXXX)}
                                                )
                                              ]
                                            )
                                        )
                                      )
                                    }
                                )
                              ]
                            )
                            (C {(local)} 
                              {(Lit_VarLike 'URL=') 
                                (DQ ('https://dl.sandstorm.io/sandstorm-') 
                                  ($ VSub_DollarName '$BUILD') (.tar.xz)
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('Downloading: ') ($ VSub_DollarName '$URL'))})
                            (C {(retryable_curl)} {(DQ ($ VSub_DollarName '$URL'))} 
                              {
                                (DQ ($ VSub_DollarName '$WORK_DIR') (/sandstorm-) 
                                  ($ VSub_DollarName '$BUILD') (.tar.xz)
                                )
                              }
                            )
                            (C {(retryable_curl)} {(DQ ($ VSub_DollarName '$URL') (.sig))} 
                              {
                                (DQ ($ VSub_DollarName '$WORK_DIR') (/sandstorm-) 
                                  ($ VSub_DollarName '$BUILD') (.tar.xz.sig)
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Simple
                                          words: [{(which)} {(gpg)}]
                                          redirects: [
                                            (redir.Redir
                                              op: <Redir_Great '>'>
                                              fd: 16777215
                                              arg_word: {(/dev/null)}
                                            )
                                          ]
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(export)} 
                                      {(Lit_VarLike 'GNUPGHOME=') 
                                        (DQ ($ VSub_DollarName '$WORK_DIR') (/.gnupg))
                                      }
                                    )
                                    (C {(mkdir)} {(-m)} {(0700)} {(-p)} 
                                      {(DQ ($ VSub_DollarName '$GNUPGHOME'))}
                                    )
                                    (command.Simple
                                      words: [{(gpg)} {(--dearmor)}]
                                      redirects: [
                                        (redir.Redir
                                          op: <Redir_Great '>'>
                                          fd: 16777215
                                          arg_word: 
                                            {
                                              (DQ ($ VSub_DollarName '$WORK_DIR') 
                                                (/sandstorm-keyring.gpg)
                                              )
                                            }
                                        )
                                        (redir.HereDoc
                                          op: <Redir_DLess '<<'>
                                          fd: 16777215
                                          here_begin: {(__EOF__)}
                                          here_end_span_id: 8580
                                          stdin_parts: [
                                            ('-----BEGIN PGP PUBLIC KEY BLOCK-----\n')
                                            ('Version: GnuPG v1\n')
                                            ('\n')
                                            (
'mQENBFX8ypkBCAC8sjX5yZqKdW8nY7aE/GpVeS+qSCbpYSJwixYNFXbz3MQihR3S\n'
                                            )
                                            (
'suvg5uw1KyuQb23c0LwirfxazVf7txKhQNaNU3ek62LG3wcGeBrvQGsIUMbkatay\n'
                                            )
                                            (
'/163CLeVWfSK1Z4pFc4dhdjXYSOz0oZxd7Mp78crBbGKmyn7PtzdAqt+XfEXNuee\n'
                                            )
                                            (
'cDbx++P57n5s5xc5fQWznt333IMgmgTREGUROfh4kL376rFAS208XIywJlUVkoKM\n'
                                            )
                                            (
'kIzgcjevFGwYKdsLigHXCDp9toQHl8oPjFV+RE8Br8ciJlMp9CqCfHGwj0Orxasc\n'
                                            )
                                            (
'e9moLqqUc+iKdg9bQfuAbJ/jFNhGmV/CVv9tABEBAAG0LlNhbmRzdG9ybS5pbyAo\n'
                                            )
                                            (
'cmVsZWFzZXMpIDxzdXBwb3J0QHNhbmRzdG9ybS5pbz6JATgEEwECACIFAlX8ypkC\n'
                                            )
                                            (
'GwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGPyJ0mdqMy91bYH/iTg9qbw\n'
                                            )
                                            (
'G3th57Yf70NtyMJE3UBFDYDNAgT45UBEHoHhQM5cdFu/EIHggOKl/A2zL19Nh555\n'
                                            )
                                            (
'5F5o3jiJChQ0cvpoVnDdA5lRKD9iK6hzAba9fCVAx/od1PULQP7KV+uHTQuclSFO\n'
                                            )
                                            (
'DBvpgT8bMY9LmlpTl+l2lvYd+c50w3jZMFwh8JrJYAc3X0kBfVEywVZkjH8Nw5nD\n'
                                            )
                                            (
'v/j5Of3XXfEg84tNyWSYUMrYVORJyfHtA9e3JXNv5BMxH73AVLnyCJhCaodQsC6Z\n'
                                            )
                                            (
'hFkHUvvRb58ZqKXMtLYTd/8XLIvpkgRNX6EHWDslJh3BaBwHSuqDNssh1TW5xPjA\n'
                                            )
                                            (
'9vkPDzeZfLkuxpy5AQ0EVfzKmQEIANyi22M/3KhkghsPA6Rpha1lx6JJCb4p7E21\n'
                                            )
                                            (
'y82OGFUwcMpZkSgh1lARgp/Mvc2CHhAXi6NkGbgYc1q5rgARSvim2EMZNQOEqRb9\n'
                                            )
                                            (
'teEeI3w7Nz8Q/WoWck9WaXg8EdELtBOXYgVEirVddUl6ftUvCeBh3hE2Y/CLQSXL\n'
                                            )
                                            (
'CYXdQ2/MN6xV8tepuWOu0aPxxPUNea9ceDNZ8/CXEL32pzv9SUX/3KgSnFTzmxNP\n'
                                            )
                                            (
'thzXGuaAQGMZRu3cdTSeK9UUX4L3lxv7p0nE/2K18MU3FayTJqspfUCc4BgHZRMN\n'
                                            )
                                            (
'sh+2/YNfJgi0uWex1WnU94ZIp4A0uic54bU1ZECSwxg81KHaEEkAEQEAAYkBHwQY\n'
                                            )
                                            (
'AQIACQUCVfzKmQIbDAAKCRBj8idJnajMvZgPB/0THpTPnfsYNkwQrBsrTq413ZTF\n'
                                            )
                                            (
'JmVyeZ9xnGDImOdyHhGLlnLC1YEnaNUVEyMKifya4TF2utrLrsMT9TC/dWvFsYlJ\n'
                                            )
                                            (
'oMcUpaSlrFoAoPp3pdOGCIRYNhWGHoxy0Ti1WAa/6A+GoHJpUEz85/jD4vjgYlCX\n'
                                            )
                                            (
'ZFW1Pji9PbdIZFZQR4FyYBkkZOUq6yyTNR0syQPVy3EsPVvXzszm2zV/1YjGymgj\n'
                                            )
                                            (
'MKeYR9+VU+PlFAY9wwLWLTFeSzxTyVjbPwF5bWHV32GM8g0/NgA6a1JLL40v7pqf\n'
                                            )
                                            (
'uYvFk2KJpo3gZNGJ72gLkSzie7Eu1/V67JIG9TwfrJUEj8Uwd5zPv1MOqfWl\n'
                                            )
                                            ('=OiS5\n')
                                            ('-----END PGP PUBLIC KEY BLOCK-----\n')
                                          ]
                                        )
                                      ]
                                    )
                                    (command.If
                                      arms: [
                                        (if_arm
                                          cond: [
                                            (command.Sentence
                                              child: 
                                                (command.Pipeline
                                                  children: [
                                                    (command.Simple
                                                      words: [
                                                        {(gpg)}
                                                        {(--no-default-keyring)}
                                                        {(--keyring)}
                                                        {($ VSub_DollarName '$WORK_DIR') 
                                                          (/sandstorm-keyring.gpg)
                                                        }
                                                        {(--status-fd)}
                                                        {(1)}
                                                        {(--verify)}
                                                        (word.BracedTree
                                                          parts: [
                                                            ($ VSub_DollarName '$WORK_DIR')
                                                            (/sandstorm-)
                                                            ($ VSub_DollarName '$BUILD')
                                                            (.tar.xz)
                                                            (word_part.BracedTuple
                                                              words: [{(.sig)} {}]
                                                            )
                                                          ]
                                                        )
                                                      ]
                                                      redirects: [
                                                        (redir.Redir
                                                          op: <Redir_Great '2>'>
                                                          fd: 2
                                                          arg_word: {(/dev/null)}
                                                        )
                                                      ]
                                                    )
                                                    (C {(grep)} {(-q)} 
                                                      {
                                                        (SQ 
                                                          <
'^\\[GNUPG:\\] VALIDSIG 160D2D577518B58D94C9800B63F227499DA8CCBD '
                                                          >
                                                        )
                                                      }
                                                    )
                                                  ]
                                                  negated: F
                                                )
                                              terminator: <Op_Semi ';'>
                                            )
                                          ]
                                          action: [(C {(echo)} {(DQ ('GPG signature is valid.'))})]
                                        )
                                      ]
                                      else_action: [
                                        (C {(rm)} {(-rf)} {(sandstorm-) ($ VSub_DollarName '$BUILD')})
                                        (C {(fail)} {(DQ (E_INVALID_GPG_SIG))} 
                                          {
                                            (DQ 
                                              (
'GPG signature is NOT valid! Please report to security@sandstorm.io immediately!'
                                              )
                                            )
                                          }
                                        )
                                      ]
                                    )
                                    (C {(unset)} {(GNUPGHOME)})
                                  ]
                                )
                              ]
                              else_action: [
                                (command.Simple
                                  words: [
                                    {(echo)}
                                    {
                                      (DQ 
                                        (
"WARNING: gpg not installed; not verifying signatures (but it's HTTPS so you're probably fine)"
                                        )
                                      )
                                    }
                                  ]
                                  redirects: [
                                    (redir.Redir
                                      op: <Redir_GreatAnd '>&'>
                                      fd: 16777215
                                      arg_word: {(2)}
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(tar)} {(Jxof)} 
                              {
                                (DQ ($ VSub_DollarName '$WORK_DIR') (/sandstorm-) 
                                  ($ VSub_DollarName '$BUILD') (.tar.xz)
                                )
                              }
                            )
                            (C {(rm)} {(-rf)} {(DQ ($ VSub_DollarName '$WORK_DIR'))})
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-e)} 
                                          {(DQ ($ VSub_DollarName '$BUILD_DIR'))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(fail)} {(DQ (E_BAD_PACKAGE))} 
                                      {
                                        (DQ ('Bad package -- did not contain ') 
                                          ($ VSub_DollarName '$BUILD_DIR') (' directory.')
                                        )
                                      }
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.AndOr
                                          ops: [Op_DPipe]
                                          children: [
                                            (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-e)} 
                                              {(DQ ($ VSub_DollarName '$BUILD_DIR') (/buildstamp))} {(Lit_RBracket ']')}
                                            )
                                            (C {(Lit_LBracket '[')} 
                                              {
                                                (command_sub
                                                  left_token: <Left_DollarParen '$('>
                                                  command_list: 
                                                    (command.CommandList
                                                      children: [
                                                        (C {(stat)} {(-c)} {(Lit_Other '%') (Y)} 
                                                          {
                                                            (DQ ($ VSub_DollarName '$BUILD_DIR') 
                                                              (/buildstamp)
                                                            )
                                                          }
                                                        )
                                                      ]
                                                    )
                                                )
                                              } {(-lt)} 
                                              {
                                                (word_part.ArithSub
                                                  anode: 
                                                    (arith_expr.Binary
                                                      op_id: Arith_Minus
                                                      left: 
                                                        (arith_expr.ArithWord
                                                          w: 
                                                            {
                                                              (command_sub
                                                                left_token: <Left_DollarParen '$('>
                                                                command_list: 
                                                                  (command.CommandList
                                                                    children: [
                                                                      (C {(date)} 
                                                                        {(Lit_Other '+') 
                                                                          (Lit_Other '%') (s)
                                                                        }
                                                                      )
                                                                    ]
                                                                  )
                                                              )
                                                            }
                                                        )
                                                      right: 
                                                        (arith_expr.Binary
                                                          op_id: Arith_Star
                                                          left: 
                                                            (arith_expr.Binary
                                                              op_id: Arith_Star
                                                              left: 
                                                                (arith_expr.Binary
                                                                  op_id: Arith_Star
                                                                  left: 
                                                                    (arith_expr.ArithWord
                                                                      w: {(Lit_Digits 30)}
                                                                    )
                                                                  right: 
                                                                    (arith_expr.ArithWord
                                                                      w: {(Lit_Digits 24)}
                                                                    )
                                                                )
                                                              right: 
                                                                (arith_expr.ArithWord
                                                                  w: {(Lit_Digits 60)}
                                                                )
                                                            )
                                                          right: 
                                                            (arith_expr.ArithWord
                                                              w: {(Lit_Digits 60)}
                                                            )
                                                        )
                                                    )
                                                )
                                              } {(Lit_RBracket ']')}
                                            )
                                          ]
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(rm)} {(-rf)} {(DQ ($ VSub_DollarName '$BUILD_DIR'))})
                                    (C {(fail)} {(DQ (E_PKG_STALE))} 
                                      {
                                        (DQ 
                                          (
'The downloaded package seems to be more than a month old. Please verify that your'
                                          )
                                        )
                                      } {(DQ ("computer's clock is correct and try again. It could also be that an attacker is"))} 
                                      {
                                        (DQ 
                                          (
'trying to trick you into installing an old version. Please contact'
                                          )
                                        )
                                      } {(DQ ('security@sandstorm.io if the problem persists.'))}
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-e)} {($ VSub_DollarName '$BUILD_DIR')} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ ($ VSub_DollarName '$BUILD_DIR') 
                                  (' is already present. Should I use it or re-download?')
                                )
                              }
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (command.Pipeline
                                          children: [
                                            (C {(prompt-yesno)} {(DQ ('Use existing copy?'))} {(yes)})
                                          ]
                                          negated: T
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [(C {(do-download)})]
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [(C {(do-download)})]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: extract_bundle_if_provided
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name BUNDLE_FILE>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {($ VSub_DollarName '$BUILD')} 
                                  {(Lit_Equals '=')} {(0)} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:BUILD_DIR)
                                  op: Equal
                                  rhs: 
                                    {(sandstorm-custom.) 
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(date)} {(Lit_Other '+') (SQ <'%Y-%m-%d_%H-%M-%S'>)})
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:BUILD_DIR)
                              op: Equal
                              rhs: {(sandstorm-) ($ VSub_DollarName '$BUILD')}
                            )
                          ]
                        )
                      ]
                    )
                    (C {(rm)} {(-rf)} {(DQ ($ VSub_DollarName '$BUILD_DIR'))})
                    (C {(mkdir)} {(DQ ($ VSub_DollarName '$BUILD_DIR'))})
                    (command.Subshell
                      command_list: 
                        (command.CommandList
                          children: [
                            (command.AndOr
                              ops: [Op_DAmp]
                              children: [
                                (C {(cd)} {(DQ ($ VSub_DollarName '$BUILD_DIR'))})
                                (C {(tar)} {(Jxof)} {(DQ ($ VSub_DollarName '$BUNDLE_FILE'))} 
                                  {(--strip) (Lit_Equals '=') (1)}
                                )
                              ]
                            )
                          ]
                        )
                    )
                  ]
                )
            )
            (command.ShFunction
              name: make_runtime_directories
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:GROUP)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(id)} {(-g)} {($ VSub_DollarName '$SERVER_USER')})]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (C {(mkdir)} {(-p)} 
                      (word.BracedTree
                        parts: [(var/) (word_part.BracedTuple words:[{(log)} {(pid)} {(mongo)}])]
                      ) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      )
                    )
                    (C {(ln)} {(-sfT)} {($ VSub_DollarName '$BUILD_DIR')} {(latest)})
                    (C {(ln)} {(-sfT)} {(latest/sandstorm)} {(sandstorm)})
                  ]
                )
            )
            (command.ShFunction
              name: set_permissions
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'ADMIN_TOKEN_PATH=')})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-e)} {(DQ (${ VSub_Name ADMIN_TOKEN_PATH))} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:ADMIN_TOKEN_PATH)
                                  op: Equal
                                  rhs: {(DQ (var/sandstorm/adminToken))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (C {(chown)} {(-R)} 
                      {($ VSub_DollarName '$SERVER_USER') (Lit_Other ':') ($ VSub_DollarName '$GROUP')} (word.BracedTree parts:[(var/) (word_part.BracedTuple words:[{(log)} {(pid)} {(mongo)}])]) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      ) {($ VSub_DollarName '$ADMIN_TOKEN_PATH')}
                    )
                    (C {(chown)} {(root) (Lit_Other ':') ($ VSub_DollarName '$GROUP')} 
                      (word.BracedTree
                        parts: [
                          (var/)
                          (word_part.BracedTuple
                            words: [{(log)} {(pid)} {(mongo)} {(sandstorm)}]
                          )
                        ]
                      ) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      ) {($ VSub_DollarName '$ADMIN_TOKEN_PATH')}
                    )
                    (C {(chmod)} {(-R)} {(Lit_VarLike 'g=') (rwX) (Lit_Comma ',') (Lit_VarLike 'o=')} 
                      (word.BracedTree
                        parts: [
                          (var/)
                          (word_part.BracedTuple
                            words: [{(log)} {(pid)} {(mongo)} {(sandstorm)}]
                          )
                        ]
                      ) 
                      (word.BracedTree
                        parts: [
                          (var/sandstorm/)
                          (word_part.BracedTuple
                            words: [{(apps)} {(grains)} {(downloads)}]
                          )
                        ]
                      ) {($ VSub_DollarName '$ADMIN_TOKEN_PATH')}
                    )
                  ]
                )
            )
            (command.ShFunction
              name: install_sandstorm_symlinks
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'FAILED_TO_WRITE_SYMLINK=') (DQ (no))})
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (C {(ln)} {(-sfT)} {($ VSub_DollarName '$PWD') (/sandstorm)} 
                          {(/usr/local/bin/sandstorm)}
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:FAILED_TO_WRITE_SYMLINK)
                              op: Equal
                              rhs: {(yes)}
                            )
                          ]
                        )
                      ]
                    )
                    (command.AndOr
                      ops: [Op_DPipe]
                      children: [
                        (C {(ln)} {(-sfT)} {($ VSub_DollarName '$PWD') (/sandstorm)} 
                          {(/usr/local/bin/spk)}
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:FAILED_TO_WRITE_SYMLINK)
                              op: Equal
                              rhs: {(yes)}
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (${ VSub_Name FAILED_TO_WRITE_SYMLINK))} 
                                  {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'*** WARNING: /usr/local/bin was not writeable. To run sandstorm or spk manually, use:'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ (' - ') ($ VSub_DollarName '$PWD') (/sandstorm))})
                            (C {(echo)} {(DQ (' - ') ($ VSub_DollarName '$PWD') ('/sandstorm spk'))})
                            (C {(echo)} {(DQ )})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: ask_about_starting_at_boot
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} 
                                  {(KW_Bang '!') (Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: Equal
                                  rhs: {(DQ (no))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name START_AT_BOOT>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(prompt-yesno)} 
                                  {
                                    (DQ ('Start sandstorm at system boot (using ') 
                                      ($ VSub_DollarName '$INIT_SYSTEM') (')?')
                                    )
                                  } {(yes)}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:START_AT_BOOT)
                                  op: Equal
                                  rhs: {(yes)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_start_at_boot_if_desired
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED)
                          op: Equal
                          rhs: {(DQ (yes))}
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name START_AT_BOOT>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (systemd))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name INIT_SYSTEM))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(configure_systemd_init_system)})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED)
                                  op: Equal
                                  rhs: {(no)}
                                )
                              ]
                            )
                          ]
                        )
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (sysvinit))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name INIT_SYSTEM))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(configure_sysvinit_init_system)})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED)
                                  op: Equal
                                  rhs: {(no)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (C {(echo)} 
                          {
                            (DQ 
                              (
"Note: I don't know how to set up sandstorm to auto-run at startup on"
                              )
                            )
                          }
                        )
                        (C {(echo)} {(DQ ('  your system. :('))})
                        (C {(echo)})
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_systemd_init_system
              body: 
                (command.BraceGroup
                  children: [
                    (C {(local)} {(Lit_VarLike 'SYSTEMD_UNIT=') (DQ (sandstorm.service))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (C {(systemctl)} {(list-unit-files)})
                                    (C {(grep)} {(-q)} {($ VSub_DollarName '$SYSTEMD_UNIT')})
                                  ]
                                  negated: F
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Op_DPipe]
                              children: [(C {(systemctl)} {(stop)} {(sandstorm)}) (C {(true)})]
                            )
                          ]
                        )
                      ]
                    )
                    (command.ForEach
                      iter_name: SYSTEMD_UNIT_PATH
                      iter_words: [
                        {(/etc/systemd/system)}
                        {(/run/systemd/system)}
                        {(/usr/lib/systemd/system)}
                      ]
                      do_arg_iter: F
                      body: 
                        (command.DoGroup
                          children: [
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(-e)} 
                                          {($ VSub_DollarName '$SYSTEMD_UNIT_PATH') (/) 
                                            ($ VSub_DollarName '$SYSTEMD_UNIT')
                                          } {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(rm)} 
                                      {($ VSub_DollarName '$SYSTEMD_UNIT_PATH') (/) 
                                        ($ VSub_DollarName '$SYSTEMD_UNIT')
                                      }
                                    )
                                  ]
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (command.Simple
                      words: [{(cat)}]
                      redirects: [
                        (redir.Redir
                          op: <Redir_Great '>'>
                          fd: 16777215
                          arg_word: {(/etc/systemd/system/) ($ VSub_DollarName '$SYSTEMD_UNIT')}
                        )
                        (redir.HereDoc
                          op: <Redir_DLess '<<'>
                          fd: 16777215
                          here_begin: {(__EOF__)}
                          here_end_span_id: 9835
                          stdin_parts: [
                            ('[Unit]\n')
                            ('Description=Sandstorm server\n')
                            ('After=local-fs.target remote-fs.target network.target\n')
                            ('Requires=local-fs.target remote-fs.target network.target\n')
                            ('\n')
                            ('[Service]\n')
                            ('Type=forking\n')
                            ('ExecStart=')
                            ($ VSub_DollarName '$PWD')
                            ('/sandstorm start\n')
                            ('ExecStop=')
                            ($ VSub_DollarName '$PWD')
                            ('/sandstorm stop\n')
                            ('\n')
                            ('[Install]\n')
                            ('WantedBy=multi-user.target\n')
                          ]
                        )
                      ]
                    )
                    (C {(systemctl)} {(enable)} {(sandstorm)})
                    (C {(systemctl)} {(start)} {(sandstorm)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM)
                          op: Equal
                          rhs: {(DQ (yes))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: configure_sysvinit_init_system
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-e)} {(/etc/init.d/sandstorm)} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (command.AndOr
                              ops: [Op_DPipe]
                              children: [(C {(service)} {(sandstorm)} {(stop)}) (C {(true)})]
                            )
                          ]
                        )
                      ]
                    )
                    (command.Simple
                      words: [{(cat)}]
                      redirects: [
                        (redir.Redir
                          op: <Redir_Great '>'>
                          fd: 16777215
                          arg_word: {(/etc/init.d/sandstorm)}
                        )
                        (redir.HereDoc
                          op: <Redir_DLess '<<'>
                          fd: 16777215
                          here_begin: {(__EOF__)}
                          here_end_span_id: 9983
                          stdin_parts: [
                            ('#! /bin/bash\n')
                            ('### BEGIN INIT INFO\n')
                            ('# Provides:          sandstorm\n')
                            ('# Required-Start:    ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('local_fs ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('remote_fs ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('networking ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('syslog\n')
                            ('# Required-Stop:     ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('local_fs ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('remote_fs ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('networking ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('syslog\n')
                            ('# Default-Start:     2 3 4 5\n')
                            ('# Default-Stop:      0 1 6\n')
                            ('# Short-Description: starts Sandstorm personal cloud server\n')
                            ('### END INIT INFO\n')
                            ('\n')
                            ('DESC=')
                            (Right_DoubleQuote '"')
                            ('Sandstorm server')
                            (Right_DoubleQuote '"')
                            ('\n')
                            ('DAEMON=')
                            ($ VSub_DollarName '$PWD')
                            ('/sandstorm\n')
                            ('\n')
                            (
'# The Sandstorm runner supports all the common init commands directly.\n'
                            )
                            ('# We use -a to set the program name to make help text look nicer.\n')
                            ('# This requires bash, though.\n')
                            ('exec -a ')
                            (Right_DoubleQuote '"')
                            ('service sandstorm')
                            (Right_DoubleQuote '"')
                            (' ')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('DAEMON ')
                            (Right_DoubleQuote '"')
                            (word_part.EscapedLiteral
                              token: <Lit_EscapedChar '\\$'>
                            )
                            ('@')
                            (Right_DoubleQuote '"')
                            ('\n')
                          ]
                        )
                      ]
                    )
                    (C {(chmod)} {(Lit_Other '+') (x)} {(/etc/init.d/sandstorm)})
                    (C {(update-rc.d)} {(sandstorm)} {(defaults)})
                    (C {(service)} {(sandstorm)} {(start)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM)
                          op: Equal
                          rhs: {(DQ (yes))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: generate_admin_token
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name ALLOW_DEV_ACCOUNTS))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name ADMIN_TOKEN>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(local)} 
                              {(Lit_VarLike 'TMPFILENAME=') 
                                (DQ 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [
                                          (C {(mktemp)} {(./var/sandstorm/adminTokenTmp.XXXXXXXXXX)})
                                        ]
                                      )
                                  )
                                )
                              }
                            )
                            (command.Simple
                              words: [{(echo)} {(-n)} {(DQ ($ VSub_DollarName '$ADMIN_TOKEN'))}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_Great '>'>
                                  fd: 16777215
                                  arg_word: {(DQ ($ VSub_DollarName '$TMPFILENAME'))}
                                )
                              ]
                            )
                            (C {(local)} {(Lit_VarLike 'FILENAME=') (DQ (./var/sandstorm/adminToken))})
                            (C {(mv)} {(DQ ($ VSub_DollarName '$TMPFILENAME'))} 
                              {(DQ ($ VSub_DollarName '$FILENAME'))}
                            )
                            (C {(chmod)} {(0640)} {(DQ ($ VSub_DollarName '$FILENAME'))})
                            (C {(chgrp)} {(DQ ($ VSub_DollarName '$SERVER_USER'))} 
                              {(DQ ($ VSub_DollarName '$FILENAME'))}
                            )
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:ADMIN_TOKEN)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(./sandstorm)} {(admin-token)} {(--quiet)})]
                                  )
                              )
                            }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: print_success
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDSTORM_NEEDS_TO_BE_STARTED'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Installation complete. To start your server now, run:'))})
                            (C {(echo)} {(DQ ('  ') ($ VSub_DollarName '$DIR') ('/sandstorm start'))})
                            (C {(echo)} {(DQ ("Once that's done, visit this link to start using it:"))})
                          ]
                        )
                      ]
                      else_action: [
                        (C {(echo)} {(-n)} {(DQ ('Your server is now online! '))})
                        (command.If
                          arms: [
                            (if_arm
                              cond: [
                                (command.Sentence
                                  child: 
                                    (C {(Lit_LBracket '[')} 
                                      {(DQ (${ VSub_Name SANDCATS_HTTPS_SUCCESSFUL))} {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                    )
                                  terminator: <Op_Semi ';'>
                                )
                              ]
                              action: [
                                (C {(echo)} {(DQ ('It should work immediately if you use Chrome.'))})
                              ]
                            )
                          ]
                        )
                        (C {(echo)} {(DQ ('Visit this link to start using it:'))})
                      ]
                    )
                    (C {(echo)} {(DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name ADMIN_TOKEN>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {
                                (DQ ('  ') 
                                  (braced_var_sub
                                    token: <VSub_Name BASE_URL>
                                    suffix_op: 
                                      (suffix_op.Unary
                                        op_id: VTest_ColonHyphen
                                        arg_word: {('(unknown; bad config)')}
                                      )
                                  ) (/setup/token/) ($ VSub_DollarName '$ADMIN_TOKEN')
                                )
                              }
                            )
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'NOTE: This URL expires in 15 minutes. You can generate a new setup URL by running'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ("'sudo sandstorm admin-token' from the command line."))})
                          ]
                        )
                      ]
                      else_action: [
                        (C {(echo)} 
                          {
                            (DQ ('  ') 
                              (braced_var_sub
                                token: <VSub_Name BASE_URL>
                                suffix_op: 
                                  (suffix_op.Unary
                                    op_id: VTest_ColonHyphen
                                    arg_word: {('(unknown; bad config)')}
                                  )
                              ) (/)
                            )
                          }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name ALLOW_DEV_ACCOUNTS))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
"NOTE: Use the passwordless admin account called Alice for convenient dev login (since you have 'dev accounts' enabled)."
                                  )
                                )
                              }
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ )})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (${ VSub_Name SANDCATS_HTTPS_SUCCESSFUL))} 
                                  {(Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'(If your browser shows you an OCSP error, wait 10 minutes for it to auto-resolve'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('and try Chrome until then.)'))})
                          ]
                        )
                      ]
                    )
                    (C {(echo)})
                    (C {(echo)} {(DQ ('To learn how to control the server, run:'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(C {(echo)} {(DQ ('  sandstorm help'))})]
                        )
                      ]
                      else_action: [
                        (C {(echo)} {(DQ ('  ') ($ VSub_DollarName '$DIR') ('/sandstorm help'))})
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_provide_help
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'Sandcats.io is a free dynamic DNS service run by the Sandstorm development team.'
                          )
                        )
                      }
                    )
                    (C {(echo)} {(DQ )})
                    (C {(echo)} {(DQ ('You can:'))})
                    (C {(echo)} {(DQ )})
                    (C {(echo)} {(DQ ('* Read more about it at:'))})
                    (C {(echo)} 
                      {(DQ ('  https://github.com/sandstorm-io/sandstorm/wiki/Sandcats-dynamic-DNS'))}
                    )
                    (C {(echo)} {(DQ )})
                    (C {(echo)} 
                      {(DQ ('* Recover access to a domain you once registered with sandcats'))}
                    )
                    (C {(echo)} {(DQ )})
                    (C {(echo)} {(DQ ('* Just press enter to go to the previous question.'))})
                    (C {(sandcats_recover_domain)})
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_recover_domain
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DESIRED_SANDCATS_NAME)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} 
                                        {(DQ ('What Sandcats subdomain do you want to recover?'))} {(DQ (none))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (none))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: BoolBinary_EqualTilde
                                      left: {($ VSub_DollarName '$DESIRED_SANDCATS_NAME')}
                                      right: {(Lit_Other '[') (Lit_Other .) (Lit_Other ']')}
                                    )
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {(DQ ('You entered: ') ($ VSub_DollarName '$DESIRED_SANDCATS_NAME'))}
                            )
                            (C {(echo)} {(DQ )})
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'but this function just wants the name of your subdomain, not including any dot characters.'
                                  )
                                )
                              }
                            )
                            (C {(echo)} {(DQ ('Please try again.'))})
                            (C {(echo)} {(DQ )})
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'OK. We will send a recovery token to the email address on file. Type no to abort.'
                          )
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:OK_TO_CONTINUE)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(prompt)} {(DQ ('OK to continue?'))} {(DQ (yes))})]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (no))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$OK_TO_CONTINUE'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'LOG_PATH=') (DQ (var/sandcats/sendrecoverytoken-log))})
                    (C {(touch)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--output)} {(DQ ($ VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ <'%{http_code}'>)} {(-H)} 
                                        {(SQ <'X-Sand: cats'>)} {(-H)} {(DQ ('Accept: text/plain'))} {(DQ (${ VSub_Name SANDCATS_API_BASE) (/sendrecoverytoken))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (200))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(cat)} {($ VSub_DollarName '$LOG_PATH')})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(echo)} {(SQ )})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:TOKEN)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} 
                                        {
                                          (DQ 
                                            ('Please enter the token that we sent to you by email.')
                                          )
                                        } {(SQ )}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} {(DQ ($ VSub_DollarName '$TOKEN'))} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(error)} {(DQ ('Empty tokens are not valid.'))})
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(local)} {(Lit_VarLike 'LOG_PATH=') (DQ (var/sandcats/recover-log))})
                    (C {(touch)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--data-urlencode)} {(DQ ('recoveryToken=') ($ VSub_DollarName '$TOKEN'))} {(--output)} 
                                        {(DQ ($ VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ <'%{http_code}'>)} {(-H)} {(SQ <'X-Sand: cats'>)} {(-H)} {(DQ ('Accept: text/plain'))} 
                                        {(--cert)} {(var/sandcats/id_rsa.private_combined)} {(DQ (${ VSub_Name SANDCATS_API_BASE) (/recover))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (200))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(cat)} {($ VSub_DollarName '$LOG_PATH')})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(echo)} {(SQ )})
                    (C {(local)} {(Lit_VarLike 'LOG_PATH=') (DQ (var/sandcats/update-log))})
                    (C {(touch)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--output)} {(DQ ($ VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ <'%{http_code}'>)} {(-H)} 
                                        {(SQ <'X-Sand: cats'>)} {(-H)} {(DQ ('Accept: text/plain'))} {(--cert)} {(var/sandcats/id_rsa.private_combined)} 
                                        {(DQ (${ VSub_Name SANDCATS_API_BASE) (/update))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (200))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(error)} 
                              {
                                (DQ 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(cat)} {($ VSub_DollarName '$LOG_PATH')})]
                                      )
                                  )
                                )
                              }
                            )
                            (C {(sandcats_recover_domain)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(echo)} {(SQ )})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                          op: Equal
                          rhs: {(DQ (yes))}
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                          op: Equal
                          rhs: 
                            {
                              (DQ (${ VSub_Name DESIRED_SANDCATS_NAME) (.) 
                                (${ VSub_Name SANDCATS_BASE_DOMAIN)
                              )
                            }
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                          op: Equal
                          rhs: {(DQ (yes))}
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ ("Congratulations! You're all configured to use ") 
                          (${ VSub_Name DESIRED_SANDCATS_NAME) (.) (${ VSub_Name SANDCATS_BASE_DOMAIN) (.)
                        )
                      }
                    )
                    (C {(echo)} 
                      {
                        (DQ ('Your credentials to use it are in ') 
                          (command_sub
                            left_token: <Left_DollarParen '$('>
                            command_list: 
                              (command.CommandList
                                children: [(C {(readlink)} {(-f)} {(var/sandcats)})]
                              )
                          ) ('; consider making a backup.')
                        )
                      }
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_registerreserved
              body: 
                (command.BraceGroup
                  children: [
                    (C {(echo)} {(DQ ('Registering your pre-reserved domain.'))})
                    (C {(local)} {(LOG_PATH)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:LOG_PATH)
                          op: Equal
                          rhs: {(DQ (var/sandcats/registerreserved-log))}
                        )
                      ]
                    )
                    (C {(touch)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('domainReservationToken=') 
                                            ($ VSub_DollarName '$SANDCATS_DOMAIN_RESERVATION_TOKEN')
                                          )
                                        } {(--data-urlencode)} {(DQ ('rawHostname=') ($ VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(--output)} 
                                        {(DQ ($ VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ <'%{http_code}'>)} {(-H)} {(SQ <'X-Sand: cats'>)} {(-H)} {(DQ ('Accept: text/plain'))} 
                                        {(--cert)} {(var/sandcats/id_rsa.private_combined)} {(DQ (${ VSub_Name SANDCATS_API_BASE) (/registerreserved))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(Lit_LBracket '[')} {(DQ (200))} {(Lit_Equals '=')} 
                              {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                            )
                          ]
                          action: [
                            (C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                            (C {(echo)} {(SQ )})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ (${ VSub_Name DESIRED_SANDCATS_NAME) (.) 
                                        (${ VSub_Name SANDCATS_BASE_DOMAIN)
                                      )
                                    }
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Congratulations! We have registered your ') 
                                  (${ VSub_Name DESIRED_SANDCATS_NAME) (.) (${ VSub_Name SANDCATS_BASE_DOMAIN) (' name.')
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Your credentials to use it are in ') 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(readlink)} {(-f)} {(var/sandcats)})]
                                      )
                                  ) ('; consider making a backup.')
                                )
                              }
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (C {(fail)} {(DQ (E_SANDCATS_REGISTER_RESERVED_SRV_FAIL))} 
                          {
                            (DQ 
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})]
                                  )
                              )
                            )
                          }
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_register_name
              body: 
                (command.BraceGroup
                  children: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_API_BASE)
                          op: Equal
                          rhs: 
                            {
                              (DQ 
                                (braced_var_sub
                                  token: <VSub_Name OVERRIDE_SANDCATS_API_BASE>
                                  suffix_op: 
                                    (suffix_op.Unary
                                      op_id: VTest_ColonHyphen
                                      arg_word: {('https:') (Lit_Slash /) (Lit_Slash /) (sandcats.io)}
                                    )
                                )
                              )
                            }
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_CURL_PARAMS)
                          op: Equal
                          rhs: 
                            {
                              (DQ 
                                (braced_var_sub
                                  token: <VSub_Name OVERRIDE_SANDCATS_CURL_PARAMS>
                                  suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(KW_Bang '!')} {(-z)} 
                                  {
                                    (DQ 
                                      (braced_var_sub
                                        token: <VSub_Name SANDCATS_DOMAIN_RESERVATION_TOKEN>
                                        suffix_op: (suffix_op.Unary op_id:VTest_ColonHyphen arg_word:(word.Empty))
                                      )
                                    )
                                  } {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(sandcats_registerreserved)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'Choose your desired Sandcats subdomain (alphanumeric, max 20 characters).'
                          )
                        )
                      }
                    )
                    (C {(echo)} {(DQ ('Type the word none to skip this step, or help for help.'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DESIRED_SANDCATS_NAME)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(prompt)} 
                                        {
                                          (DQ ('What *.') (${ VSub_Name SANDCATS_BASE_DOMAIN) 
                                            (' subdomain would you like?')
                                          )
                                        } {(SQ )}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-z)} 
                                  {(DQ ($ VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (none))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (help))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(sandcats_provide_help)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Pipeline
                                  children: [
                                    (command.DBracket
                                      expr: 
                                        (bool_expr.Binary
                                          op_id: BoolBinary_EqualTilde
                                          left: {($ VSub_DollarName '$DESIRED_SANDCATS_NAME')}
                                          right: 
                                            {(Lit_Other '^') (Lit_Other '[') (0-9a-zA-Z-) 
                                              (Lit_Other ']') (Lit_Other '{') (1) (Lit_Other ',') (20) (Lit_Other '}') (Lit_Other '$')
                                            }
                                        )
                                    )
                                  ]
                                  negated: T
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(sandcats_register_name)})
                            (command.ControlFlow
                              token: <ControlFlow_Return return>
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} 
                      {
                        (DQ 
                          (
'We need your email on file so we can help you recover your domain if you lose access. No spam.'
                          )
                        )
                      }
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:SANDCATS_REGISTRATION_EMAIL)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(prompt)} {(DQ ('Enter your email address:'))} {(DQ )})]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.WhileUntil
                      keyword: <KW_While while>
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Lit_LBracket '[')} {(DQ )} {(Lit_Equals '=')} 
                              {(DQ ($ VSub_DollarName '$SANDCATS_REGISTRATION_EMAIL'))} {(Lit_RBracket ']')}
                            )
                          terminator: <Op_Semi ';'>
                        )
                      ]
                      body: 
                        (command.DoGroup
                          children: [
                            (C {(echo)} 
                              {
                                (DQ 
                                  (
'For the DNS service, we really do need an email address. To cancel, type: Ctrl-C.'
                                  )
                                )
                              }
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_REGISTRATION_EMAIL)
                                  op: Equal
                                  rhs: 
                                    {
                                      (command_sub
                                        left_token: <Left_DollarParen '$('>
                                        command_list: 
                                          (command.CommandList
                                            children: [
                                              (C {(prompt)} {(DQ ('Enter your email address:'))} {(DQ )})
                                            ]
                                          )
                                      )
                                    }
                                )
                              ]
                            )
                          ]
                        )
                    )
                    (C {(echo)} {(DQ ('Registering your domain.'))})
                    (C {(local)} {(LOG_PATH)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:LOG_PATH)
                          op: Equal
                          rhs: {(DQ (var/sandcats/register-log))}
                        )
                      ]
                    )
                    (C {(touch)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(chmod)} {(0640)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(20)} 
                                        {($ VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--data-urlencode)} {(DQ ('email=') ($ VSub_DollarName '$SANDCATS_REGISTRATION_EMAIL'))} {(--output)} 
                                        {(DQ ($ VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ <'%{http_code}'>)} {(-H)} {(SQ <'X-Sand: cats'>)} {(-H)} {(DQ ('Accept: text/plain'))} 
                                        {(--cert)} {(var/sandcats/id_rsa.private_combined)} {(DQ (${ VSub_Name SANDCATS_API_BASE) (/register))}
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(Lit_LBracket '[')} {(DQ (200))} {(Lit_Equals '=')} 
                              {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                            )
                          ]
                          action: [
                            (C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                            (C {(echo)} {(SQ )})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SS_HOSTNAME)
                                  op: Equal
                                  rhs: 
                                    {
                                      (DQ (${ VSub_Name DESIRED_SANDCATS_NAME) (.) 
                                        (${ VSub_Name SANDCATS_BASE_DOMAIN)
                                      )
                                    }
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Congratulations! We have registered your ') 
                                  (${ VSub_Name DESIRED_SANDCATS_NAME) (.) (${ VSub_Name SANDCATS_BASE_DOMAIN) (' name.')
                                )
                              }
                            )
                            (C {(echo)} 
                              {
                                (DQ ('Your credentials to use it are in ') 
                                  (command_sub
                                    left_token: <Left_DollarParen '$('>
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(readlink)} {(-f)} {(var/sandcats)})]
                                      )
                                  ) ('; consider making a backup.')
                                )
                              }
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (C {(error)} 
                          {
                            (DQ 
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(cat)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})]
                                  )
                              )
                            )
                          }
                        )
                        (C {(sandcats_register_name)})
                        (command.ControlFlow
                          token: <ControlFlow_Return return>
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_configure_https
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_GETCERTIFICATE'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ("Now we're going to auto-configure HTTPS for your server."))})
                    (C {(echo)} {(DQ )})
                    (C {(echo)} 
                      {(DQ ('* This will take about 30 seconds, and needs no input from you.'))}
                    )
                    (C {(echo)} {(DQ ('* Thanks to GlobalSign for their help making this happen.'))})
                    (C {(echo)} {(DQ )})
                    (C {(local)} {(Lit_VarLike 'HTTPS_BASE_DIR=') (DQ (var/sandcats/https))})
                    (C {(local)} 
                      {(Lit_VarLike 'HTTPS_CONFIG_DIR=') 
                        (DQ ($ VSub_DollarName '$HTTPS_BASE_DIR') (/) 
                          ($ VSub_DollarName '$SS_HOSTNAME')
                        )
                      }
                    )
                    (C {(mkdir)} {(-p)} {(-m)} {(0700)} {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR'))})
                    (C {(chmod)} {(0700)} {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR'))})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(chown)} {(-R)} 
                              {(DQ ($ VSub_DollarName '$SERVER_USER')) (Lit_Other ':') 
                                (DQ ($ VSub_DollarName '$SERVER_USER'))
                              } {(DQ ($ VSub_DollarName '$HTTPS_BASE_DIR'))}
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} {(DQ ('Generating certificate request...'))})
                    (command.Simple
                      words: [
                        {(openssl)}
                        {(req)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-nodes)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-newkey)}
                        {(rsa) (Lit_Other ':') (4096)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-subj)}
                        {(DQ ('/CN=*.') (${ VSub_Name SS_HOSTNAME) (/))}
                        {(-keyout)}
                        {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-out)}
                        {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0.csr)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                      ]
                      redirects: [(redir.Redir op:<Redir_Great '2>'> fd:2 arg_word:{(/dev/null)})]
                    )
                    (C {(chmod)} {(0600)} {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0)})
                    (C {(chmod)} {(0600)} {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR')) (/0.csr)})
                    (C {(echo)} {(DQ ('Requesting certificate (BE PATIENT)...'))})
                    (C {(local)} {(LOG_PATH)})
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:LOG_PATH)
                          op: Equal
                          rhs: {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR') (/0.response-json))}
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:HTTP_STATUS)
                          op: Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: <Left_DollarParen '$('>
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (C {(dotdotdot_curl)} {(--silent)} {(--max-time)} {(60)} 
                                        {($ VSub_DollarName '$SANDCATS_CURL_PARAMS')} {(-A)} {(DQ ($ VSub_DollarName '$CURL_USER_AGENT'))} {(-X)} {(POST)} {(--data-urlencode)} 
                                        {
                                          (DQ ('rawHostname=') 
                                            ($ VSub_DollarName '$DESIRED_SANDCATS_NAME')
                                          )
                                        } {(--data-urlencode)} 
                                        {
                                          (DQ ('certificateSigningRequest=') 
                                            (command_sub
                                              left_token: <Left_DollarParen '$('>
                                              command_list: 
                                                (command.CommandList
                                                  children: [
                                                    (C {(cat)} 
                                                      {
                                                        (DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR') 
                                                          (/0.csr)
                                                        )
                                                      }
                                                    )
                                                  ]
                                                )
                                            )
                                          )
                                        } {(--output)} {(DQ ($ VSub_DollarName '$LOG_PATH'))} {(-w)} {(SQ <'%{http_code}'>)} {(-H)} 
                                        {(SQ <'X-Sand: cats'>)} {(--cert)} {(var/sandcats/id_rsa.private_combined)} 
                                        {
                                          (DQ (${ VSub_Name SANDCATS_API_BASE) (/) 
                                            (braced_var_sub
                                              token: 
                                                <VSub_Name OVERRIDE_SANDCATS_GETCERTIFICATE_API_PATH>
                                              suffix_op: 
                                                (suffix_op.Unary
                                                  op_id: VTest_ColonHyphen
                                                  arg_word: {(getcertificate)}
                                                )
                                            )
                                          )
                                        }
                                      )
                                    ]
                                  )
                              )
                            }
                        )
                      ]
                    )
                    (C {(chmod)} {(0600)} {(DQ ($ VSub_DollarName '$LOG_PATH'))})
                    (C {(chown)} 
                      {(DQ ($ VSub_DollarName '$SERVER_USER')) (Lit_Other ':') 
                        (DQ ($ VSub_DollarName '$SERVER_USER'))
                      } {(DQ ($ VSub_DollarName '$HTTPS_CONFIG_DIR') (/)) (Lit_Star '*')}
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(Lit_LBracket '[')} {(DQ (200))} {(Lit_Equals '=')} 
                              {(DQ ($ VSub_DollarName '$HTTP_STATUS'))} {(Lit_RBracket ']')}
                            )
                          ]
                          action: [
                            (C {(echo)} {(DQ ('Successfully auto-configured HTTPS!'))})
                            (command.ShAssignment
                              pairs: [
                                (assign_pair
                                  lhs: (sh_lhs_expr.Name name:SANDCATS_HTTPS_SUCCESSFUL)
                                  op: Equal
                                  rhs: {(DQ (yes))}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                      else_action: [
                        (C {(error)} 
                          {
                            (DQ 
                              (
'Some part of HTTPS autoconfiguration failed. Log data available in '
                              ) ($ VSub_DollarName '$LOG_PATH')
                            )
                          }
                        )
                        (command.ControlFlow
                          token: <ControlFlow_Return return>
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: wait_for_server_bind_to_its_port
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(KW_Bang '!') (Lit_Equals '=')} 
                                  {(DQ (${ VSub_Name STARTED_SANDSTORM))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(local)} 
                      {(Lit_VarLike 'PORT_TO_CHECK=') 
                        (DQ 
                          (braced_var_sub
                            token: <VSub_Name HTTPS_PORT>
                            suffix_op: 
                              (suffix_op.Unary
                                op_id: VTest_ColonHyphen
                                arg_word: {($ VSub_DollarName '$PORT')}
                              )
                          )
                        )
                      }
                    )
                    (C {(echo)} {(-n)} 
                      {(DQ ('Your server is coming online. Waiting up to 90 seconds...'))}
                    )
                    (C {(local)} {(Lit_VarLike 'ONLINE_YET=') (DQ (no))})
                    (command.ForEach
                      iter_name: waited_n_seconds
                      iter_words: [
                        {
                          (command_sub
                            left_token: <Left_DollarParen '$('>
                            command_list: (command.CommandList children:[(C {(seq)} {(0)} {(89)})])
                          )
                        }
                      ]
                      do_arg_iter: F
                      body: 
                        (command.DoGroup
                          children: [
                            (command.AndOr
                              ops: [Op_DAmp]
                              children: [
                                (C {(is_port_bound)} {(DQ (${ VSub_Name BIND_IP))} 
                                  {(DQ (${ VSub_Name PORT_TO_CHECK))}
                                )
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:ONLINE_YET)
                                      op: Equal
                                      rhs: {(DQ (yes))}
                                    )
                                  ]
                                )
                              ]
                            )
                            (command.If
                              arms: [
                                (if_arm
                                  cond: [
                                    (command.Sentence
                                      child: 
                                        (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$ONLINE_YET'))} 
                                          {(Lit_Equals '=') (Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                        )
                                      terminator: <Op_Semi ';'>
                                    )
                                  ]
                                  action: [
                                    (C {(echo)} {(SQ )})
                                    (command.ControlFlow
                                      token: <ControlFlow_Break break>
                                    )
                                  ]
                                )
                              ]
                            )
                            (C {(echo)} {(-n)} {(DQ (.))})
                            (C {(sleep)} {(1)})
                          ]
                        )
                    )
                    (command.AndOr
                      ops: [Op_DAmp]
                      children: [
                        (C {(is_port_bound)} {(DQ (${ VSub_Name BIND_IP))} 
                          {(DQ (${ VSub_Name PORT_TO_CHECK))}
                        )
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:ONLINE_YET)
                              op: Equal
                              rhs: {(DQ (yes))}
                            )
                          ]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ ($ VSub_DollarName '$ONLINE_YET'))} 
                                  {(Lit_Equals '=') (Lit_Equals '=')} {(DQ (yes))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                      else_action: [
                        (C {(fail)} {(DQ (E_NEVER_LISTENED))} 
                          {(DQ ('Your server never started listening.'))}
                        )
                      ]
                    )
                  ]
                )
            )
            (command.ShFunction
              name: sandcats_generate_keys
              body: 
                (command.BraceGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(-f)} {(var/sandcats/id_rsa.private_combined)} 
                                  {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [(command.ControlFlow token:<ControlFlow_Return return>)]
                        )
                      ]
                    )
                    (C {(echo)} {(-n)} {(SQ <...>)})
                    (C {(mkdir)} {(-p)} {(-m)} {(0700)} {(var/sandcats)})
                    (C {(chmod)} {(0700)} {(var/sandcats)})
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(chown)} 
                              {(DQ ($ VSub_DollarName '$SERVER_USER')) (Lit_Other ':') 
                                (DQ ($ VSub_DollarName '$SERVER_USER'))
                              } {(var/sandcats)}
                            )
                          ]
                        )
                      ]
                    )
                    (command.Simple
                      words: [
                        {(openssl)}
                        {(req)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-new)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-newkey)}
                        {(rsa) (Lit_Other ':') (4096)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-days)}
                        {(3650)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-nodes)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-x509)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-subj)}
                        {(DQ ('/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd'))}
                        {(-keyout)}
                        {(var/sandcats/id_rsa)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(-out)}
                        {(var/sandcats/id_rsa.pub)}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                        {(command_sub left_token:<Left_Backtick '`'> command_list:(command.NoOp))}
                      ]
                      redirects: [(redir.Redir op:<Redir_Great '2>'> fd:2 arg_word:{(/dev/null)})]
                    )
                    (command.Simple
                      words: [{(cat)} {(var/sandcats/id_rsa)} {(var/sandcats/id_rsa.pub)}]
                      redirects: [
                        (redir.Redir
                          op: <Redir_Great '>'>
                          fd: 16777215
                          arg_word: {(var/sandcats/id_rsa.private_combined)}
                        )
                      ]
                    )
                    (C {(chmod)} {(0640)} {(var/sandcats/id_rsa)} {(var/sandcats/id_rsa.pub)} 
                      {(var/sandcats/id_rsa.private_combined)}
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Lit_LBracket '[')} {(DQ (yes))} {(Lit_Equals '=')} 
                                  {(DQ ($ VSub_DollarName '$CURRENTLY_UID_ZERO'))} {(Lit_RBracket ']')}
                                )
                              terminator: <Op_Semi ';'>
                            )
                          ]
                          action: [
                            (C {(chown)} 
                              {(DQ ($ VSub_DollarName '$SERVER_USER')) (Lit_Other ':') 
                                (DQ ($ VSub_DollarName '$SERVER_USER'))
                              } 
                              (word.BracedTree
                                parts: [
                                  (var/sandcats/id_rsa)
                                  (word_part.BracedTuple
                                    words: [{} {(.pub)} {(.private_combined)}]
                                  )
                                ]
                              )
                            )
                          ]
                        )
                      ]
                    )
                    (C {(echo)} {(-ne)} {(SQ <'\\r'>)})
                  ]
                )
            )
            (C {(handle_args)} {(DQ ($ VSub_At '$@'))})
            (C {(set_umask)})
            (C {(assert_on_terminal)})
            (C {(assert_linux_x86_64)})
            (C {(assert_usable_kernel)})
            (C {(detect_current_uid)})
            (C {(assert_dependencies)})
            (C {(assert_valid_bundle_file)})
            (C {(detect_init_system)})
            (C {(choose_install_mode)})
            (C {(maybe_enable_userns_sysctl)})
            (C {(choose_external_or_internal)})
            (C {(choose_install_dir)})
            (C {(choose_smtp_port)})
            (C {(load_existing_settings)})
            (C {(choose_server_user_if_needed)})
            (C {(create_server_user_if_needed)})
            (C {(configure_auto_updates)})
            (C {(configure_dev_accounts)})
            (C {(configure_hostnames)})
            (C {(save_config)})
            (C {(download_latest_bundle_and_extract_if_needed)})
            (C {(extract_bundle_if_provided)})
            (C {(make_runtime_directories)})
            (C {(generate_admin_token)})
            (C {(set_permissions)})
            (C {(install_sandstorm_symlinks)})
            (C {(ask_about_starting_at_boot)})
            (C {(configure_start_at_boot_if_desired)})
            (C {(wait_for_server_bind_to_its_port)})
            (C {(print_success)})
          ]
        )
    )
    (C {(_)} {(DQ ($ VSub_Number '$0'))} {(DQ ($ VSub_At '$@'))})
  ]
)