(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 '$@'))}) ] )