(command.CommandList children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<test>} {<-z>} {(DQ ($ Id.VSub_DollarName '$BASH_VERSION'))}) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<echo>} {(DQ <'Please run this script using bash, not sh or any other shell.'>)}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.ControlFlow token:<Id.ControlFlow_Exit exit> arg_word:{<1>}) ] spids: [104 115] ) ] ) (command.ShFunction name: _ body: (BraceGroup children: [ (C {<Id.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: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name CURL_USER_AGENT> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<sandstorm-install-script>} ) ) ) } spids: [183] ) ] ) (command.ShFunction name: error body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {($ Id.VSub_Pound '$#')} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {<0>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<echo>} {<-en>} {(SQ <'\\e[0;31m'>)}] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (command.Pipeline children: [ (C {<echo>} {(DQ ($ Id.VSub_At '$@'))}) (command.Subshell child: (command.AndOr ops: [Id.Op_DPipe] children: [(C {<fold>} {<-s>}) (C {<cat>})] ) redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] ) ] negated: F ) (command.Simple words: [{<echo>} {<-en>} {(SQ <'\\e[0m'>)}] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) ] spids: [203 217] ) ] ) ] ) ) (command.ShFunction name: fail body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'error_code='> (DQ ($ Id.VSub_Number '$1'))}) (C {<shift>}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (braced_var_sub token: <Id.VSub_Name SHOW_FAILURE_MSG> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<yes>} ) ) ) } {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<echo>} {(DQ <'*** INSTALLATION FAILED ***'>)}] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (C {<echo>} {(DQ )}) ] spids: [289 311] ) ] ) (C {<error>} {(DQ ($ Id.VSub_At '$@'))}) (command.Simple words: [{<echo>} {(DQ )}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (braced_var_sub token: <Id.VSub_Name REPORT> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<yes>} ) ) ) } {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: '> ($ Id.VSub_DollarName '$error_code') ) } {(DQ <yes>)} ] more_env: [ (env_pair name: USE_DEFAULTS val: {<no>} spids: [380] ) ] do_fork: T ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<echo>} {(DQ <'Sending problem report...'>)}] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (C {<local>} {<Id.Lit_VarLike 'BEARER_TOKEN='> (DQ <ZiV1jbwHBPfpIjF3LNFv9-glp53F7KcsvVvljgKxQAL>) } ) (C {<local>} {<Id.Lit_VarLike 'API_ENDPOINT='> (DQ <'https://api.oasis.sandstorm.io/api'>) } ) (C {<local>} {<Id.Lit_VarLike 'HTTP_STATUS='> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<20>} {<--data-binary>} { (DQ <'{'> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) <error_code> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <':'> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) ($ Id.VSub_DollarName '$error_code') (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <','> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) <user-agent> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <':'> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) ($ Id.VSub_DollarName '$CURL_USER_AGENT') (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <'}'> ) } {<-H>} {(DQ <'Authorization: Bearer '> ($ Id.VSub_DollarName '$BEARER_TOKEN'))} {<-X>} {<POST>} {<--output>} {(DQ <'/dev/null'>)} {<-w>} {(SQ <'%{http_code}'>)} {(DQ ($ Id.VSub_DollarName '$API_ENDPOINT'))} ) ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [ {<echo>} { (DQ < '... problem reported successfully. Your installation did not succeed.' > ) } ] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) ] spids: [507 526] ) (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <000>)} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} { (DQ < 'Submitting error report failed. Maybe there is a connectivity problem.' > ) } ) ] spids: [539 558] ) ] else_action: [ (C {<error>} { (DQ < 'Submitting error report resulted in strange HTTP status: ' > ($ Id.VSub_DollarName '$HTTP_STATUS') ) } ) ] ) ] spids: [378 397] ) ] else_action: [ (command.Simple words: [{<echo>} {(DQ <'Not sending report.'>)}] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) ] ) (C {<echo>} {(DQ )}) ] spids: [353 375] ) ] ) (command.Simple words: [ {<echo>} {(DQ <'You can report bugs at: http://github.com/sandstorm-io/sandstorm'>)} ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.ControlFlow token: <Id.ControlFlow_Exit exit> arg_word: {<1>} ) ] ) ) (command.ShFunction name: retryable_curl body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'CURL_FAILED='> (DQ <no>)}) (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [ {<curl>} {<-A>} {(DQ (${ Id.VSub_Name CURL_USER_AGENT))} {<-f>} {(DQ ($ Id.VSub_Number '$1'))} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_Number '$2'))} ) ] do_fork: T ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CURL_FAILED) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [671] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name CURL_FAILED))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} { (DQ <'Downloading '> ($ Id.VSub_Number '$1') <' failed. OK to retry?'> ) } {(DQ <yes>)} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<echo>} {(DQ )}] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (command.Simple words: [ {<echo>} { (DQ < 'Download failed. Waiting one second before retrying...' > ) } ] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (C {<sleep>} {<1>}) (C {<retryable_curl>} {(DQ ($ Id.VSub_Number '$1'))} {(DQ ($ Id.VSub_Number '$2'))} ) ] spids: [700 716] ) ] ) ] spids: [677 697] ) ] ) ] ) ) (command.ShFunction name: dotdotdot_curl body: (BraceGroup children: [ (command.Simple words: [{<echo>} {<-n>} {(SQ <...>)}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (C {<curl>} {(DQ ($ Id.VSub_At '$@'))}) (command.Simple words: [{<echo>} {<-ne>} {(SQ <'\\r'>)}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) ] ) ) (command.ShFunction name: is_port_bound body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'SCAN_HOST='> (DQ ($ Id.VSub_Number '$1'))}) (C {<local>} {<Id.Lit_VarLike 'SCAN_PORT='> (DQ ($ Id.VSub_Number '$2'))}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} {<Id.Lit_Equals '='>} {(DQ <unchecked>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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>} spids:[905])] do_fork: T ) ] spids: [882 902] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Simple words: [ {<timeout>} {<1>} {<bash>} {<-c>} { (DQ <': < /dev/tcp/'> (${ Id.VSub_Name SCAN_HOST) <'/'> (${ Id.VSub_Name SCAN_PORT) ) } ] redirects: [ (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<0>} ) ] spids: [954 979] ) ] else_action: [ (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<1>} ) ] ) ] spids: [931 951] ) ] ) (C {<local>} {<Id.Lit_VarLike 'DEBIAN_STYLE_INDICATED_BOUND='> (DQ <no>)}) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [ {(${ Id.VSub_Name NC_PATH)} {<-z>} {(DQ ($ Id.VSub_DollarName '$SCAN_HOST'))} {(DQ ($ Id.VSub_DollarName '$SCAN_PORT'))} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEBIAN_STYLE_INDICATED_BOUND) op: assign_op.Equal rhs: {<yes>} spids: [1100] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$DEBIAN_STYLE_INDICATED_BOUND'))} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<0>} ) ] spids: [1105 1124] ) ] ) (C {<local>} {<Id.Lit_VarLike 'NMAP_STYLE_INDICATED_BOUND='> (DQ <no>)}) (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [ {(${ Id.VSub_Name NC_PATH)} {<--wait>} {<1>} {<--recv-only>} {<--send-only>} {(DQ ($ Id.VSub_DollarName '$SCAN_HOST'))} {(DQ ($ Id.VSub_DollarName '$SCAN_PORT'))} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:NMAP_STYLE_INDICATED_BOUND) op: assign_op.Equal rhs: {<yes>} spids: [1178] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$NMAP_STYLE_INDICATED_BOUND'))} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<0>} ) ] spids: [1183 1202] ) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<1>} ) ] ) ) (command.ShFunction name: writeConfig body: (BraceGroup children: [ (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {($ Id.VSub_Pound '$#')} {<-gt>} {<0>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] body: (command.DoGroup children: [ (C {<eval>} {<echo>} { (DQ ($ Id.VSub_Number '$1') <'='> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) ($ Id.VSub_Number '$1') ) } ) (C {<shift>}) ] ) ) ] ) ) (command.ShFunction name: prompt body: (BraceGroup children: [ (C {<local>} {<VALUE>}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ ($ Id.VSub_Number '$2'))}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [1306 1324] ) ] ) (command.Simple words: [{<echo>} {<-en>} {(SQ <'\\e[1m'>)}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<3>})] do_fork: T ) (command.Simple words: [ {<echo>} {<-n>} {(DQ ($ Id.VSub_Number '$1') <' ['> ($ Id.VSub_Number '$2') <']'>)} ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<3>})] do_fork: T ) (command.Simple words: [{<echo>} {<-en>} {(SQ <'\\e[0m '>)}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<3>})] do_fork: T ) (C {<read>} {<-u>} {<3>} {<VALUE>}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ ($ Id.VSub_DollarName '$VALUE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:VALUE) op: assign_op.Equal rhs: {($ Id.VSub_Number '$2')} spids: [1413] ) ] ) ] spids: [1397 1410] ) ] ) (C {<echo>} {(DQ ($ Id.VSub_DollarName '$VALUE'))}) ] ) ) (command.ShFunction name: prompt-numeric body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'NUMERIC_REGEX='> (DQ <'^[0-9]+'> <Id.Lit_Other '$'>)}) (command.WhileUntil keyword: <Id.KW_While while> cond: [(command.Sentence child:(C {<true>}) terminator:<Id.Op_Semi _>)] body: (command.DoGroup children: [ (C {<local>} {<Id.Lit_VarLike 'VALUE='> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ ($ Id.VSub_At '$@'))}) ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Pipeline children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$VALUE'))} right: {($ Id.VSub_DollarName '$NUMERIC_REGEX')} ) ) ] negated: T ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [ {<echo>} { (DQ <'You entered \''> ($ Id.VSub_DollarName '$VALUE') <'\'. Please enter a number.'> ) } ] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<3>} ) ] do_fork: T ) ] spids: [1466 1484] ) ] else_action: [ (C {<echo>} {(DQ ($ Id.VSub_DollarName '$VALUE'))}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] ) ] ) ) ] ) ) (command.ShFunction name: prompt-yesno body: (BraceGroup children: [ (command.WhileUntil keyword: <Id.KW_While while> cond: [(command.Sentence child:(C {<true>}) terminator:<Id.Op_Semi _>)] body: (command.DoGroup children: [ (C {<local>} {<Id.Lit_VarLike 'VALUE='> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ ($ Id.VSub_At '$@'))}) ) } ) (command.Case to_match: {($ Id.VSub_DollarName '$VALUE')} arms: [ (case_arm pat_list: [{<y>} {<Y>} {<yes>} {<YES>} {<Yes>}] action: [ (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<0>} ) ] spids: [1555 1573 1581 -1] ) (case_arm pat_list: [{<n>} {<N>} {<no>} {<NO>} {<No>}] action: [ (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<1>} ) ] spids: [1584 1602 1610 -1] ) ] ) (C {<echo>} { (DQ <'*** Please answer '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) <yes> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <' or '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) <no> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <.> ) } ) ] ) ) ] ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_DEFAULTS) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1644] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1649] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_SANDCATS) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1654] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1659] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_HTTPS_SUCCESSFUL) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1664] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CURRENTLY_UID_ZERO) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1669] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PREFER_ROOT) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [1674] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1679] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1684] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:NC_PATH) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_NC_PATH> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{<nc>}) ) ) } spids: [1696] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE) op: assign_op.Equal rhs: {(DQ <unchecked>)} spids: [1709] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_DIR_FOR_ROOT) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDSTORM_DEFAULT_DIR> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<Id.Lit_Slash '/'> <opt> <Id.Lit_Slash '/'> <sandstorm>} ) ) ) } spids: [1721] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_DIR_FOR_NON_ROOT) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDSTORM_DEFAULT_DIR> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: { (braced_var_sub token: <Id.VSub_Name HOME> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<opt>} ) ) <Id.Lit_Slash '/'> <sandstorm> } ) ) ) } spids: [1733] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_SMTP_PORT) op: assign_op.Equal rhs: {(DQ <30025>)} spids: [1748] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_UPDATE_CHANNEL) op: assign_op.Equal rhs: {(DQ <dev>)} spids: [1753] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_SERVER_USER) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDSTORM_DEFAULT_SERVER_USER> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<sandstorm>} ) ) ) } spids: [1758] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_BASE_DOMAIN) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_BASE_DOMAIN> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<sandcats.io>} ) ) ) } spids: [1767] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS) op: assign_op.Equal rhs: {(DQ <false>)} spids: [1776] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_GETCERTIFICATE> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{<yes>}) ) ) } spids: [1781] ) ] ) (command.ShFunction name: usage body: (BraceGroup children: [ (command.Simple words: [ {<echo>} { (DQ <'usage: '> ($ Id.VSub_DollarName '$SCRIPT_NAME') <' [-d] [-e] [-p PORT_NUMBER] [-u] [<bundle>]'> ) } ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [ {<echo>} { (DQ < 'If <bundle> is provided, it must be the name of a Sandstorm bundle file,' > ) } ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [ {<echo>} { (DQ < 'like \'sandstorm-123.tar.xz\', which will be installed. Otherwise, the script' > ) } ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [{<echo>} {(DQ <'downloads a bundle from the internet via HTTP.'>)}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [{<echo>} {(SQ )}] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [ {<echo>} { (SQ < 'If -d is specified, the auto-installs with defaults suitable for app development.' > ) } ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [ {<echo>} { (SQ < 'If -e is specified, default to listening on an external interface, not merely loopback.' > ) } ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.Simple words: [ {<echo>} { (SQ < 'If -i is specified, default to (i)nsecure mode where we do not request a HTTPS certificate.' > ) } ] redirects: [(redir op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (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 op:<Id.Redir_GreatAnd '>&'> loc:(redir_loc.Fd fd:1) arg:{<2>})] do_fork: T ) (command.ControlFlow token: <Id.ControlFlow_Exit exit> arg_word: {<1>} ) ] ) ) (command.ShFunction name: detect_current_uid body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<id>} {<-u>}) ) } {<Id.Lit_Equals '='>} {<0>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CURRENTLY_UID_ZERO) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [1934] ) ] ) ] spids: [1914 1931] ) ] ) ] ) ) (command.ShFunction name: disable_smtp_port_25_if_port_unavailable body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT_25_AVAILABLE) op: assign_op.Equal rhs: {(DQ <no>)} spids: [1952] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<is_port_bound>} {<0.0.0.0>} {<25>}) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [1958 1967] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<is_port_bound>} {<127.0.0.1>} {<25>}) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [1976 1985] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT_25_AVAILABLE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [1994] ) ] ) ] ) ) (command.ShFunction name: disable_https_if_ports_unavailable body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'PORT_80_AVAILABLE='> (DQ <no>)}) (command.AndOr ops: [Id.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: assign_op.Equal rhs: {(DQ <yes>)} spids: [2073] ) ] ) ] ) (C {<local>} {<Id.Lit_VarLike 'PORT_443_AVAILABLE='> (DQ <no>)}) (command.AndOr ops: [Id.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: assign_op.Equal rhs: {(DQ <yes>)} spids: [2096] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$PORT_443_AVAILABLE'))} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ <no>)} {<-o>} {(DQ ($ Id.VSub_DollarName '$PORT_80_AVAILABLE'))} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ <no>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE) op: assign_op.Equal rhs: {(DQ <no>)} spids: [2138] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [2144] ) ] ) ] spids: [2103 2135] ) ] ) ] ) ) (command.ShFunction name: handle_args body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SCRIPT_NAME) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [2163] ) ] ) (C {<shift>}) (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (C {<getopts>} {(DQ <':deiup:'>)} {<opt>}) terminator: <Id.Op_Semi _> ) ] body: (command.DoGroup children: [ (command.Case to_match: {($ Id.VSub_DollarName '$opt')} arms: [ (case_arm pat_list: [{<d>}] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_DEFAULTS) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [2196] ) ] ) ] spids: [2192 2193 2202 -1] ) (case_arm pat_list: [{<e>}] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [2209] ) ] ) ] spids: [2205 2206 2215 -1] ) (case_arm pat_list: [{<i>}] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_GETCERTIFICATE) op: assign_op.Equal rhs: {(DQ <no>)} spids: [2222] ) ] ) ] spids: [2218 2219 2228 -1] ) (case_arm pat_list: [{<u>}] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PREFER_ROOT) op: assign_op.Equal rhs: {<no>} spids: [2235] ) ] ) ] spids: [2231 2232 2239 -1] ) (case_arm pat_list: [{<p>}] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_PORT) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name OPTARG))} spids: [2246] ) ] ) ] spids: [2242 2243 2254 -1] ) (case_arm pat_list: [{<Id.Lit_Star '*'>}] action: [(C {<usage>})] spids: [2257 2258 2264 -1] ) ] ) ] ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_PORT) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name DEFAULT_PORT> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<6080>} ) ) ) } spids: [2278] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ORIGINAL_ARGS) op: assign_op.Equal rhs: { (sh_array_literal left: <Id.Op_LParen _> words: [{(DQ ($ Id.VSub_At '$@'))}] ) } spids: [2297] ) ] ) (C {<shift>} { (DQ (word_part.ArithSub anode: (arith_expr.Binary op_id: Id.Arith_Minus left: <Id.Lit_ArithVarLike OPTIND> right: {<Id.Lit_Digits 1>} ) ) ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<Id.Lit_LBracket '['>} {($ Id.VSub_Pound '$#')} {<Id.Lit_Equals '='>} {<1>} {<Id.Lit_RBracket ']'>} ) (command.DBracket expr: (bool_expr.LogicalNot child: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {($ Id.VSub_Number '$1')} right: {<Id.Lit_Other '^'> <->} ) ) ) ] ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUNDLE_FILE) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_Number '$1'))} spids: [2356] ) ] ) ] spids: [2325 2353] ) (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {($ Id.VSub_Pound '$#')} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {<0>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(C {<usage>})] spids: [2362 2376] ) ] ) ] ) ) (command.ShFunction name: rerun_script_as_root body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'ENVVARS='> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<echo>} {($ Id.VSub_At '$@')}) ) } ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ENVVARS) op: assign_op.Equal rhs: { (DQ ($ Id.VSub_DollarName '$ENVVARS') <' CURL_USER_AGENT='> ($ Id.VSub_DollarName '$CURL_USER_AGENT') ) } spids: [2447] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<basename>} {($ Id.VSub_DollarName '$SCRIPT_NAME')}) ) ) } {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {<bash>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ <'Re-running script as root...'>)}) (C {<exec>} {<sudo>} {<bash>} {<-euo>} {<pipefail>} {<-c>} { (DQ <'curl -fs -A '> ($ Id.VSub_DollarName '$CURL_USER_AGENT') <' https://install.sandstorm.io | '> ($ Id.VSub_DollarName '$ENVVARS') <' bash'> ) } ) ] spids: [2456 2476] ) (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<Id.Lit_LBracket '['>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<basename>} {($ Id.VSub_DollarName '$SCRIPT_NAME')}) ) ) } {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {<install.sh>} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {<-e>} {(DQ ($ Id.VSub_Number '$0'))} {<Id.Lit_RBracket ']'>} ) ] ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ <'Re-running script as root...'>)}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (braced_var_sub token: <Id.VSub_Name ORIGINAL_ARGS> prefix_op: (Id.VSub_Pound) bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) ) } {<Id.Lit_Equals '='>} {<0>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<exec>} {<sudo>} {($ Id.VSub_DollarName '$ENVVARS')} {<bash>} {(DQ ($ Id.VSub_DollarName '$SCRIPT_NAME'))} ) ] spids: [2558 2577] ) ] else_action: [ (C {<exec>} {<sudo>} {($ Id.VSub_DollarName '$ENVVARS')} {<bash>} {(DQ ($ Id.VSub_DollarName '$SCRIPT_NAME'))} { (DQ (braced_var_sub token: <Id.VSub_Name ORIGINAL_ARGS> bracket_op: (bracket_op.WholeArray op_id:Id.Lit_At) ) ) } ) ] ) ] spids: [2512 2544] ) ] ) (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>} spids:[2629])] do_fork: T ) ] ) ) (command.ShFunction name: set_umask body: (BraceGroup children:[(C {<umask>} {<0022>})]) ) (command.ShFunction name: assert_on_terminal body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<Id.Lit_LBracket '['>} {(DQ <no>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-t>} {<1>} {<Id.Lit_RBracket ']'>} ) ] ) terminator: <Id.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>} spids:[2708])] do_fork: T ) ] spids: [2676 2705] ) ] ) (command.Simple words: [{<exec>}] redirects: [(redir op:<Id.Redir_LessAnd '3<&'> loc:(redir_loc.Fd fd:3) arg:{<1>})] do_fork: T ) ] ) ) (command.ShFunction name: assert_linux_x86_64 body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<uname>}) ) ) } {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {<Linux>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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/'> ) } ) ] spids: [2765 2783] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<uname>} {<-m>}) ) ) } {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {<x86_64>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<fail>} {(DQ <E_NON_X86_64>)} { (DQ < 'Sorry, the Sandstorm server currently only runs on x86_64 machines.' > ) } ) ] spids: [2804 2824] ) ] ) ] ) ) (command.ShFunction name: assert_usable_kernel body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:KVERSION) op: assign_op.Equal rhs: { (sh_array_literal left: <Id.Op_LParen _> words: [ { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [ (C {<uname>} {<-r>}) (C {<grep>} {<-o>} {(SQ <'^[0-9.]*'>)}) (C {<tr>} {<.>} {(SQ <' '>)}) ] negated: F ) ) } ] ) } spids: [2850] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.DParen child: (arith_expr.Binary op_id: Id.Arith_DPipe left: (arith_expr.Binary op_id: Id.Arith_Less left: (arith_expr.Binary op_id: Id.Arith_LBracket left: <Id.Lit_ArithVarLike KVERSION> right: {<Id.Lit_Digits 0>} ) right: {<Id.Lit_Digits 3>} ) right: (arith_expr.Binary op_id: Id.Arith_DAmp left: (arith_expr.Binary op_id: Id.Arith_DEqual left: (arith_expr.Binary op_id: Id.Arith_LBracket left: <Id.Lit_ArithVarLike KVERSION> right: {<Id.Lit_Digits 0>} ) right: {<Id.Lit_Digits 3>} ) right: (arith_expr.Binary op_id: Id.Arith_Less left: (arith_expr.Binary op_id: Id.Arith_LBracket left: <Id.Lit_ArithVarLike KVERSION> right: {<Id.Lit_Digits 1>} ) right: {<Id.Lit_Digits 10>} ) ) ) ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} { (DQ <'Detected Linux kernel version: '> (command_sub left_token: <Id.Left_DollarParen '$('> child: (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.'>)} ) ] spids: [2883 2924] ) ] ) ] ) ) (command.ShFunction name: maybe_enable_userns_sysctl body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [2977 2996] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <no>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [3022 3040] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-e>} {<'/proc/sys/kernel/unprivileged_userns_clone'>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [3054 3067] ) ] ) (C {<local>} {<Id.Lit_VarLike 'OLD_VALUE='> (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Simple redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {<'/proc/sys/kernel/unprivileged_userns_clone'>} ) ] do_fork: F ) ) ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$OLD_VALUE'))} {<Id.Lit_Equals '='>} {(DQ <1>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [3094 3111] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Simple words: [ {<sysctl>} {<-wq>} {<kernel.unprivileged_userns_clone> <Id.Lit_Equals '='> <1>} ] redirects: [ (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ < 'NOTE: Enabled unprivileged user namespaces because you passed -d.' > ) } ) ] spids: [3129 3143] ) ] else_action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] ) (C {<local>} {<Id.Lit_VarLike 'SYSCTL_FILENAME='> (DQ <'/etc/sysctl.conf'>)}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-d>} {<'/etc/sysctl.d'>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SYSCTL_FILENAME) op: assign_op.Equal rhs: {(DQ <'/etc/sysctl.d/50-sandstorm.conf'>)} spids: [3198] ) ] ) ] spids: [3183 3195] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Pipeline children: [ (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_DGreat '>>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$SYSCTL_FILENAME'))} ) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine 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'> ] ) ) ] do_fork: T ) ] negated: T ) ] action: [ (C {<echo>} { (DQ < 'NOTE: Never mind, not enabling userns because can\'t write /etc/sysctl.d.' > ) } ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<sysctl>} {<-wq>} { (DQ <'kernel.unprivileged_userns_clone='> ($ Id.VSub_DollarName '$OLD_VALUE') ) } ) (C {<true>}) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [3208 3230] ) ] ) ] ) ) (command.ShFunction name: test_if_dev_tcp_works body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Pipeline children: [ (command.Subshell child: (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [ {<timeout>} {<1>} {<bash>} {<-c>} {(SQ <': < /dev/tcp/localhost/0'>)} ] redirects: [ (redir op: <Id.Redir_GreatAnd '2>&'> loc: (redir_loc.Fd fd:2) arg: {<1>} ) ] do_fork: T ) (C {<true>}) ] ) ) (C {<grep>} {<-q>} {(SQ <'connect:'>)}) ] negated: F ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [3355] ) ] ) ] spids: [3309 3344] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEV_TCP_USABLE) op: assign_op.Equal rhs: {(DQ <no>)} spids: [3364] ) ] ) ] ) ] ) ) (command.ShFunction name: assert_dependencies body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name BUNDLE_FILE> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [{<which>} {<curl>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<fail>} {(DQ <E_CURL_MISSING>)} { (DQ < 'Please install curl(1). Sandstorm uses it to download updates.' > ) } ) ] ) ] spids: [3382 3398] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} {<Id.Lit_Equals '='>} {(DQ <unchecked>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(C {<test_if_dev_tcp_works>})] spids: [3433 3453] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name DEV_TCP_USABLE))} {<Id.Lit_Equals '='>} {(DQ <no>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [{<which>} {<nc>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<fail>} {(DQ <E_NC_MISSING>)} { (DQ < 'Please install nc(1). (Package may be called \'netcat-traditional\' or \'netcat-openbsd\'.)' > ) } ) ] ) ] spids: [3462 3482] ) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [{<which>} {<tar>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<fail>} {(DQ <E_TAR_MISSING>)} {(DQ <'Please install tar(1).'>)}) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [{<which>} {<xz>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) (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: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-n>} { (DQ (braced_var_sub token: <Id.VSub_Name BUNDLE_FILE> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUNDLE_DIR) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [ (command.Subshell child: (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<tar>} {<Jtf>} {(DQ ($ Id.VSub_DollarName '$BUNDLE_FILE'))} ) (C {<true>}) ] ) ) (C {<head>} {<-n>} {<1>}) ] negated: F ) ) } spids: [3597] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.DBracket expr: (bool_expr.LogicalNot child: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$BUNDLE_DIR'))} right: {<sandstorm-> <Id.Lit_Other '('> <Id.Lit_Other '['> <0-9> <Id.Lit_Other ']'> <Id.Lit_Other '+'> <Id.Lit_Other ')'> <'/'> } ) ) ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<fail>} {(DQ <E_INVALID_BUNDLE>)} { (DQ ($ Id.VSub_DollarName '$BUNDLE_FILE') <': Not a valid Sandstorm bundle'> ) } ) ] spids: [3624 3648] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUILD) op: assign_op.Equal rhs: { (braced_var_sub token: <Id.VSub_Name BASH_REMATCH> bracket_op: (bracket_op.ArrayIndex expr:{<Id.Lit_Digits 1>}) ) } spids: [3667] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUNDLE_FILE) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<readlink>} {<-f>} {(DQ ($ Id.VSub_DollarName '$BUNDLE_FILE'))} ) ) } spids: [3681] ) ] ) ] spids: [3570 3586] ) ] ) ] ) ) (command.ShFunction name: detect_init_system body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:INIT_SYSTEM) op: assign_op.Equal rhs: {(DQ <unknown>)} spids: [3709] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<grep>} {<-q>} {<systemd>} {<'/proc/1/comm'>}) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:INIT_SYSTEM) op: assign_op.Equal rhs: {(DQ <systemd>)} spids: [3734] ) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [3720 3731] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-e>} {<'/etc/init.d'>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:INIT_SYSTEM) op: assign_op.Equal rhs: {(DQ <sysvinit>)} spids: [3769] ) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [3755 3766] ) ] ) ] ) ) (command.ShFunction name: choose_install_mode body: (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 {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CHOSEN_INSTALL_MODE) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name CHOSEN_INSTALL_MODE> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<2>} ) ) ) } spids: [3830] ) ] ) ] spids: [3809 3827] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <no>)} {<Id.Lit_Equals '='>} { (DQ (braced_var_sub token: <Id.VSub_Name PREFER_ROOT> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name CHOSEN_INSTALL_MODE> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<2>} ) ) ) } spids: [3891] ) ] ) ] spids: [3847 3868] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name CHOSEN_INSTALL_MODE> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt-numeric>} { (DQ <'How are you going to use this Sandstorm install?'> ) } {(DQ <1>)} ) ) } spids: [3960] ) ] ) ] spids: [3908 3924] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <1>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CHOSEN_INSTALL_MODE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(C {<assert_full_server_dependencies>}) (C {<full_server_install>})] spids: [3978 3996] ) ] else_action: [(C {<dev_server_install>})] ) ] ) ) (command.ShFunction name: assert_full_server_dependencies body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [{<which>} {<openssl>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) (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: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$PREFER_ROOT'))} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {(DQ <no>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) ] ) terminator: <Id.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 {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ACCEPTED_SUDO_FOR_DEV_SERVER) op: assign_op.Equal rhs: {(DQ <no>)} spids: [4218] ) ] ) ] spids: [4197 4215] ) ] else_action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} {(DQ <'OK to continue?'>)} {(DQ <yes>)}) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name: ACCEPTED_SUDO_FOR_DEV_SERVER ) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [4244] ) ] ) ] spids: [4227 4241] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ACCEPTED_SUDO_FOR_DEV_SERVER) op: assign_op.Equal rhs: {(DQ <no>)} spids: [4253] ) ] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} { (DQ ($ Id.VSub_DollarName '$ACCEPTED_SUDO_FOR_DEV_SERVER') ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<rerun_script_as_root>} {<Id.Lit_VarLike 'CHOSEN_INSTALL_MODE='> <2>} ) ] spids: [4266 4284] ) ] 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>} spids: [4300] ) (env_pair name: REPORT val: {<no>} spids: [4303] ) ] do_fork: T ) ] ) ] spids: [4105 4139] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$PREFER_ROOT'))} {<Id.Lit_RBracket ']'>} ) ] ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ <'We\'re going to:'>)}) (C {<echo>} {(DQ )}) (C {<echo>} { (DQ <'* Install Sandstorm in '> (${ Id.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 ('> ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER') <') that owns Sandstorm\'s files.'> ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-n>} { (DQ (braced_var_sub token: <Id.VSub_Name SUDO_USER> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: (word.Empty) ) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ <'* Add you ('> ($ Id.VSub_DollarName '$SUDO_USER') <') to the '> ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER') <' group so you can read/write app data.'> ) } ) ] spids: [4427 4443] ) ] ) (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 {<Id.Lit_LBracket '['>} {(DQ <unknown>)} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$INIT_SYSTEM'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ < '*** WARNING: Could not detect how to run Sandstorm at startup on your system. ***' > ) } ) ] spids: [4474 4492] ) ] else_action: [ (C {<echo>} { (DQ <'* Configure Sandstorm to start on system boot (with '> ($ Id.VSub_DollarName '$INIT_SYSTEM') <').'> ) } ) ] ) (C {<echo>} { (DQ <'* Listen for inbound email on port '> (${ Id.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: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_DEFAULTS) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [4552] ) ] ) ] spids: [4535 4549] ) ] else_action: [ (C {<echo>} {(DQ )}) (C {<echo>} {(DQ <'OK. We will prompt you with every question.'>)}) (C {<echo>} {(DQ )}) ] ) ] spids: [4349 4384] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL'))} spids: [4613] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name USE_EXTERNAL_INTERFACE> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<no>} ) ) ) } spids: [4624] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SS_HOSTNAME) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name SS_HOSTNAME> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<local.sandstorm.io>} ) ) ) } spids: [4647] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name DEFAULT_SMTP_PORT))} spids: [4662] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:START_AT_BOOT) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [4675] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_SANDCATS) op: assign_op.Equal rhs: {(DQ <no>)} spids: [4686] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name DEFAULT_PORT))} spids: [4697] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [4719] ) ] ) ] spids: [4588 4606] ) ] ) ] ) ) (command.ShFunction name: full_server_install body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name PREFER_ROOT))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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>} spids:[4807])] do_fork: T ) ] spids: [4783 4804] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name DESIRED_SANDCATS_NAME> suffix_op: (suffix_op.Unary op_id:Id.VTest_Hyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<local>} {<Id.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: assign_op.Equal rhs: { (DQ ($ Id.VSub_DollarName '$MSG') < ' If you need support for non-sandcats full-server unattended installs, please file a bug.' > ) } spids: [4874] ) ] ) (C {<fail>} {(DQ <E_USE_DEFAULTS_NEEDS_DESIRED_SANDCATS_NAME>)} {(DQ ($ Id.VSub_DollarName '$MSG'))} ) ] spids: [4846 4863] ) ] else_action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name SANDCATS_DOMAIN_RESERVATION_TOKEN > suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: (word.Empty) ) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<local>} {<Id.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: assign_op.Equal rhs: { (DQ ($ Id.VSub_DollarName '$MSG') < ' you must pre-reserve it before running this script. Specify it via the' > ) } spids: [4923] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:MSG) op: assign_op.Equal rhs: { (DQ ($ Id.VSub_DollarName '$MSG') < ' SANDCATS_DOMAIN_RESERVATION_TOKEN environment variable.' > ) } spids: [4930] ) ] ) (C {<fail>} {(DQ <E_USE_DEFAULTS_NEEDS_DESIRED_SANDCATS_NAME>)} {(DQ ($ Id.VSub_DollarName '$MSG'))} ) ] spids: [4895 4912] ) ] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [4959] ) ] ) ] spids: [4825 4843] ) ] ) (C {<disable_smtp_port_25_if_port_unavailable>}) (C {<local>} {<Id.Lit_VarLike 'PLANNED_SMTP_PORT='> (DQ <30025>)}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$PORT_25_AVAILABLE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PLANNED_SMTP_PORT) op: assign_op.Equal rhs: {(DQ <25>)} spids: [5005] ) ] ) ] spids: [4984 5002] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} { (DQ (braced_var_sub token: <Id.VSub_Name ACCEPTED_FULL_SERVER_INSTALL> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.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 '> ($ Id.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 {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_GETCERTIFICATE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ < '* Configure auto-renewing HTTPS if you use a subdomain of sandcats.io' > ) } ) ] spids: [5075 5094] ) ] ) (C {<echo>} { (DQ <'* Create a service user ('> ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER') <') that owns Sandstorm\'s files'> ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <unknown>)} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$INIT_SYSTEM'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ < '*** WARNING: Could not detect how to run Sandstorm at startup on your system. ***' > ) } ) ] spids: [5116 5134] ) ] else_action: [ (C {<echo>} { (DQ <'* Configure Sandstorm to start on system boot (with '> ($ Id.VSub_DollarName '$INIT_SYSTEM') <')'> ) } ) ] ) (C {<echo>} { (DQ <'* Listen for inbound email on port '> (${ Id.VSub_Name PLANNED_SMTP_PORT) <.> ) } ) (C {<echo>} {(DQ )}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ <'To set up Sandstorm, we will need to use sudo.'>)} ) ] spids: [5181 5199] ) ] 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: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL) op: assign_op.Equal rhs: {<yes>} spids: [5239] ) ] ) ] spids: [5223 5236] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ACCEPTED_FULL_SERVER_INSTALL) op: assign_op.Equal rhs: {<no>} spids: [5246] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} { (DQ ($ Id.VSub_DollarName '$SHOW_MESSAGE_ABOUT_NEEDING_PORTS_OPEN' ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.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 '> ($ Id.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 ' > ($ Id.VSub_DollarName '$DEFAULT_PORT') <' instead?'> ) } {(DQ <yes>)} ) ] negated: T ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<fail>} {(DQ <E_USER_REFUSED_DEFAULT_PORT>)} { (DQ < 'Exiting now. You can re-run the installer whenever you are ready.' > ) } ) ] spids: [5378 5396] ) ] ) ] spids: [5254 5272] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$ACCEPTED_FULL_SERVER_INSTALL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<rerun_script_as_root>} {<Id.Lit_VarLike 'CHOSEN_INSTALL_MODE='> <1>} {<Id.Lit_VarLike 'ACCEPTED_FULL_SERVER_INSTALL='> <yes>} {<Id.Lit_VarLike 'OVERRIDE_SANDCATS_BASE_DOMAIN='> (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_BASE_DOMAIN> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: (word.Empty) ) ) ) } {<Id.Lit_VarLike 'OVERRIDE_SANDCATS_API_BASE='> (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_API_BASE> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: (word.Empty) ) ) ) } {<Id.Lit_VarLike 'OVERRIDE_SANDCATS_GETCERTIFICATE='> (DQ (${ Id.VSub_Name SANDCATS_GETCERTIFICATE))} {<Id.Lit_VarLike 'OVERRIDE_NC_PATH='> (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_NC_PATH> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: (word.Empty) ) ) ) } {<Id.Lit_VarLike 'OVERRIDE_SANDCATS_CURL_PARAMS='> (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_CURL_PARAMS> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: (word.Empty) ) ) ) } ) ] spids: [5463 5481] ) ] ) (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.'>)} ) ] spids: [5441 5460] ) ] ) ] spids: [5015 5036] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name ACCEPTED_FULL_SERVER_INSTALL))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL'))} spids: [5628] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DIR) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_ROOT'))} spids: [5634] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [5640] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_SANDCATS) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [5646] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:START_AT_BOOT) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [5652] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DESIRED_SERVER_USER) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_SERVER_USER'))} spids: [5658] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name DEFAULT_PORT))} spids: [5664] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:MONGO_PORT) op: assign_op.Equal rhs: {(DQ <6081>)} spids: [5672] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name PLANNED_SMTP_PORT))} spids: [5678] ) ] ) ] spids: [5606 5625] ) ] 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>} spids:[5689])] do_fork: T ) ] ) ] ) ) (command.ShFunction name: sandcats_configure body: (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: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_SANDCATS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(C {<sandcats_configure>})] spids: [5833 5851] ) ] ) (C {<choose_port>}) (C {<choose_mongo_port>}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_EXTERNAL_INTERFACE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BIND_IP) op: assign_op.Equal rhs: {<0.0.0.0>} spids: [5920] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SS_HOSTNAME) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name SS_HOSTNAME> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [{<hostname>} {<-f>}] redirects: [ (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<hostname>}) ] ) ) } ) ) ) } spids: [5924] ) ] ) ] spids: [5900 5917] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BIND_IP) op: assign_op.Equal rhs: {<127.0.0.1>} spids: [5948] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SS_HOSTNAME) op: assign_op.Equal rhs: {<local.sandstorm.io>} spids: [5952] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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\'.'>)}) ] spids: [5956 5975] ) ] ) ] ) (C {<local>} {<Id.Lit_VarLike 'PORT_SUFFIX='> (DQ )}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$PORT'))} {<Id.Lit_Equals '='>} {(DQ <80>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT_SUFFIX) op: assign_op.Equal rhs: {(DQ )} spids: [6046] ) ] ) ] spids: [6025 6043] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT_SUFFIX) op: assign_op.Equal rhs: {(DQ <':'> (${ Id.VSub_Name PORT))} spids: [6054] ) ] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_BASE_URL) op: assign_op.Equal rhs: { (DQ <'http://'> (${ Id.VSub_Name SS_HOSTNAME) (${ Id.VSub_Name PORT_SUFFIX) ) } spids: [6067] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_HTTPS_SUCCESSFUL'))} {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_BASE_URL) op: assign_op.Equal rhs: {(DQ <'https://'> ($ Id.VSub_DollarName '$SS_HOSTNAME'))} spids: [6104] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTPS_PORT) op: assign_op.Equal rhs: {<443>} spids: [6111] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT) op: assign_op.Equal rhs: {<80>} spids: [6115] ) ] ) ] spids: [6084 6101] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BASE_URL) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_BASE_URL'))} spids: [6152] ) ] ) ] spids: [6123 6141] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BASE_URL) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'URL users will enter in browser:'>)} {(DQ ($ Id.VSub_DollarName '$DEFAULT_BASE_URL'))} ) ) } spids: [6161] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Pipeline children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$BASE_URL'))} right: {<Id.Lit_Other '^'> <http> <Id.Lit_Other '('> <s> <Id.Lit_Other '?'> <Id.Lit_Other ')'> <Id.Lit_Other ':'> <'//'> } ) ) ] negated: T ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<local>} {<Id.Lit_VarLike 'PROPOSED_BASE_URL='> (DQ <'http://'> (${ Id.VSub_Name BASE_URL)) } ) (command.Simple words: [ {<echo>} { (DQ <'** You entered '> (${ Id.VSub_Name BASE_URL) <', which needs http:// at the front. I can use:'> ) } ] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (command.Simple words: [ {<echo>} {(DQ <' '> (${ Id.VSub_Name PROPOSED_BASE_URL))} ] redirects: [ (redir op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} {(DQ <'Is this OK?'>)} {<yes>}) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BASE_URL) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name PROPOSED_BASE_URL))} spids: [6255] ) ] ) ] spids: [6241 6252] ) ] else_action: [(C {<configure_hostnames>})] ) ] spids: [6175 6200] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$BASE_URL'))} right: {<Id.Lit_Other '^'> <http> <Id.Lit_Other ':'> <'//localhost'> <Id.Lit_Other '('> <Id.Lit_Other '|'> <Id.Lit_Other ':'> <Id.Lit_Other '['> <0-9> <Id.Lit_Other ']'> <Id.Lit_Other '*'> <Id.Lit_Other ')'> <Id.Lit_Other '('> <'/'> <Id.Lit_Other .> <Id.Lit_Other '*'> <Id.Lit_Other ')'> <Id.Lit_Other '?'> <Id.Lit_Other '$'> } ) ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD) op: assign_op.Equal rhs: {<Id.Lit_Star '*'> <.local.sandstorm.io> (braced_var_sub token: <Id.VSub_Name BASH_REMATCH> bracket_op: (bracket_op.ArrayIndex expr:{<Id.Lit_Digits 1>}) ) } spids: [6323] ) ] ) ] spids: [6287 6320] ) (if_arm cond: [ (command.Sentence child: (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$BASE_URL'))} right: {<Id.Lit_Other '^'> <Id.Lit_Other '['> <Id.Lit_Other '^'> <Id.Lit_Other ':'> <'/'> <Id.Lit_Other ']'> <Id.Lit_Other '*'> <Id.Lit_Other ':'> <'//'> <Id.Lit_Other '('> <Id.Lit_Other '['> <Id.Lit_Other '^'> <'/'> <Id.Lit_Other ']'> <Id.Lit_Other '*'> <Id.Lit_Other ')'> <'/'> <Id.Lit_Other '?'> <Id.Lit_Other '$'> } ) ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name DEFAULT_WILDCARD> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<'*.'> (braced_var_sub token: <Id.VSub_Name BASH_REMATCH> bracket_op: (bracket_op.ArrayIndex expr: {<Id.Lit_Digits 1>} ) ) } ) ) ) } spids: [6370] ) ] ) ] spids: [6334 6367] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_WILDCARD) op: assign_op.Equal rhs: (word.Empty) spids: [6389] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:WILDCARD_HOST) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_WILDCARD'))} spids: [6425] ) ] ) ] spids: [6404 6422] ) ] else_action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_DEFAULTS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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:<Id.Lit_EscapedChar '\\"'>) <'*.foo.example.com'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <'. You can also specify that hosts should have a special'> ) } ) (C {<echo>} { (DQ <'prefix, like '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\"'> ) <'ss-*.foo.example.com'> (word_part.EscapedLiteral token:<Id.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: <Id.Lit_EscapedChar '\\"'> ) <'*.local.sandstorm.io'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <' here. If you are serving off a non-standard'> ) } ) (C {<echo>} {(DQ <'port, you must include it here as well.'>)}) ] spids: [6434 6453] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:WILDCARD_HOST) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Wildcard host:'>)} {(DQ ($ Id.VSub_DollarName '$DEFAULT_WILDCARD'))} ) ) } spids: [6547] ) ] ) (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (command.Pipeline children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$WILDCARD_HOST'))} right: {<Id.Lit_Other '^'> <Id.Lit_Other '['> <Id.Lit_Other '^'> <Id.Lit_Other '*'> <Id.Lit_Other ']'> <Id.Lit_Other '*'> <Id.Lit_Other '['> <Id.Lit_Other '*'> <Id.Lit_Other ']'> <Id.Lit_Other '['> <Id.Lit_Other '^'> <Id.Lit_Other '*'> <Id.Lit_Other ']'> <Id.Lit_Other '*'> <Id.Lit_Other '$'> } ) ) ] negated: T ) terminator: <Id.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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Wildcard host:'>)} {(DQ ($ Id.VSub_DollarName '$DEFAULT_WILDCARD'))} ) ) } spids: [6603] ) ] ) ] ) ) ] ) ] ) ) (command.ShFunction name: choose_install_dir body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name DIR> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<local>} {<Id.Lit_VarLike 'DEFAULT_DIR='> (DQ ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_ROOT')) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_DIR) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DEFAULT_DIR_FOR_NON_ROOT'))} spids: [6682] ) ] ) ] spids: [6660 6679] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DIR) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Where would you like to put Sandstorm?'>)} {(DQ ($ Id.VSub_DollarName '$DEFAULT_DIR'))} ) ) } spids: [6692] ) ] ) ] spids: [6632 6649] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DPipe Id.Op_DPipe] children: [ (C {<Id.Lit_LBracket '['>} {<-e>} {(DQ ($ Id.VSub_DollarName '$DIR') <'/sandstorm.conf'>)} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {<-e>} {(DQ ($ Id.VSub_DollarName '$DIR') <'/var'>)} {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} {<-e>} {(DQ ($ Id.VSub_DollarName '$DIR') <'/sandstorm'>)} {<Id.Lit_RBracket ']'>} ) ] ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} {(DQ )}) (C {<error>} { (DQ <'This script is trying to install to '> (${ Id.VSub_Name DIR) <.>) } ) (C {<error>} {(DQ )}) (C {<error>} { (DQ <'You seem to already have a '> (${ Id.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 -- ' > (${ Id.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 ' > (${ Id.VSub_Name DIR) < '/var and then do a fresh install; stop the Sandstorm service, and restore your backup of ' > (${ Id.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>} spids:[6886])] do_fork: T ) ] spids: [6726 6767] ) ] ) (C {<mkdir>} {<-p>} {(DQ ($ Id.VSub_DollarName '$DIR'))}) (C {<cd>} {(DQ ($ Id.VSub_DollarName '$DIR'))}) ] ) ) (command.ShFunction name: choose_smtp_port body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name SMTP_LISTEN_PORT> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [6933 6952] ) ] ) (C {<local>} {<Id.Lit_VarLike 'REQUESTED_SMTP_PORT='> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt-numeric>} { (DQ < 'Sandstorm grains can receive email. What port should Sandstorm listen on, for inbound SMTP?' > ) } {(DQ (${ Id.VSub_Name DEFAULT_SMTP_PORT))} ) ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ (${ Id.VSub_Name REQUESTED_SMTP_PORT))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(C {<choose_smtp_port>})] spids: [6980 6996] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SMTP_LISTEN_PORT) op: assign_op.Equal rhs: {(DQ (${ Id.VSub_Name REQUESTED_SMTP_PORT))} spids: [7005] ) ] ) ] ) ] ) ) (command.ShFunction name: load_existing_settings body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-e>} {<sandstorm.conf>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7033 7046] ) ] ) (C {<echo>} {(DQ <'Found existing sandstorm.conf. Using it.'>)}) (C {<.>} {<sandstorm.conf>}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (braced_var_sub token: <Id.VSub_Name SERVER_USER> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonPlus arg_word: {<set>} ) ) ) } {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {<Id.KW_Set set>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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.' > ) } ) ] spids: [7068 7088] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} { (DQ (braced_var_sub token: <Id.VSub_Name UPDATE_CHANNEL> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<none>} ) ) ) } {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {<none>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_UPDATE_CHANNEL) op: assign_op.Equal rhs: {($ Id.VSub_DollarName '$UPDATE_CHANNEL')} spids: [7145] ) ] ) ] spids: [7122 7142] ) ] ) ] ) ) (command.ShFunction name: choose_server_user_if_needed body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-e>} {<sandstorm.conf>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7177 7189] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SERVER_USER) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<id>} {<-un>}) ) } spids: [7228] ) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [7207 7225] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name DESIRED_SERVER_USER> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SERVER_USER) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$DESIRED_SERVER_USER'))} spids: [7273] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CREATE_SERVER_USER) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [7279] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ADD_SUDO_USER_TO_SERVER_GROUP) op: assign_op.Equal rhs: {(DQ <no>)} spids: [7285] ) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [7251 7270] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SERVER_USER) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Local user account to run server under:'>)} {<sandstorm>} ) ) } spids: [7302] ) ] ) (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} {<Id.Lit_Equals '='>} {<root>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Local user account to run server under:'>)} {<sandstorm>} ) ) } spids: [7340] ) ] ) ] ) ) ] ) ) (command.ShFunction name: create_server_user_if_needed body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Simple words: [{<id>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) (redir op: <Id.Redir_GreatAnd '2>&'> loc: (redir_loc.Fd fd:2) arg: {<1>} ) ] do_fork: T ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7368 7384] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} { (DQ (braced_var_sub token: <Id.VSub_Name CREATE_SERVER_USER> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} { (DQ <'User account \''> ($ Id.VSub_DollarName '$SERVER_USER') <'\' doesn\'t exist. Create it?'> ) } {<yes>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:CREATE_SERVER_USER) op: assign_op.Equal rhs: {<yes>} spids: [7444] ) ] ) ] spids: [7427 7441] ) ] ) ] spids: [7402 7424] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} { (DQ (braced_var_sub token: <Id.VSub_Name CREATE_SERVER_USER> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7459 7481] ) ] ) (C {<useradd>} {<--system>} {<--user-group>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} ) (C {<echo>} { (DQ <'Note: Sandstorm\'s storage will only be accessible to the group \''> ($ Id.VSub_DollarName '$SERVER_USER') <'\'.'> ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <no>)} {<Id.Lit_Equals '='>} { (DQ (braced_var_sub token: <Id.VSub_Name ADD_SUDO_USER_TO_SERVER_GROUP> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7562 7583] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-n>} { (DQ (braced_var_sub token: <Id.VSub_Name SUDO_USER> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} { (DQ <'Add user \''> ($ Id.VSub_DollarName '$SUDO_USER') <'\' to group \''> ($ Id.VSub_DollarName '$SERVER_USER') <'\'?'> ) } {<no>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<usermod>} {<-a>} {<-G>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} {(DQ ($ Id.VSub_DollarName '$SUDO_USER'))} ) (C {<echo>} { (DQ < 'Added. Don\'t forget that group changes only apply at next login.' > ) } ) ] spids: [7612 7628] ) ] ) ] spids: [7593 7609] ) ] ) ] ) ) (command.ShFunction name: choose_port body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name PORT> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7672 7691] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:PORT) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt-numeric>} {(DQ <'Server main HTTP port:'>)} {($ Id.VSub_DollarName '$DEFAULT_PORT')} ) ) } spids: [7701] ) ] ) (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$PORT'))} {<-lt>} {<1024>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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 '> ($ Id.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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt-numeric>} {(DQ <'Server main HTTP port:'>)} {($ Id.VSub_DollarName '$DEFAULT_PORT')} ) ) } spids: [7762] ) ] ) ] ) ) ] ) ) (command.ShFunction name: choose_mongo_port body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name MONGO_PORT> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7790 7809] ) ] ) (C {<local>} {<Id.Lit_VarLike 'DEFAULT_MONGO_PORT='> (DQ (word_part.ArithSub anode: (arith_expr.Binary op_id: Id.Arith_Plus left: <Id.Lit_ArithVarLike PORT> right: {<Id.Lit_Digits 1>} ) ) ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$PORT'))} {<-lt>} {<1024>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DEFAULT_MONGO_PORT) op: assign_op.Equal rhs: {(DQ <6081>)} spids: [7861] ) ] ) ] spids: [7842 7858] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:MONGO_PORT) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt-numeric>} {(DQ <'Database port (choose any unused port):'>)} {(DQ (${ Id.VSub_Name DEFAULT_MONGO_PORT))} ) ) } spids: [7871] ) ] ) ] ) ) (command.ShFunction name: choose_external_or_internal body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$USE_EXTERNAL_INTERFACE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} {(DQ <'Expose to localhost only?'>)} {<yes>}) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <no>)} spids: [7936] ) ] ) ] spids: [7921 7933] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [7945] ) ] ) ] ) ] spids: [7900 7918] ) ] ) ] ) ) (command.ShFunction name: configure_auto_updates body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-n>} { (DQ (braced_var_sub token: <Id.VSub_Name UPDATE_CHANNEL> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [7970 7986] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} {(DQ <'Automatically keep Sandstorm updated?'>)} {<yes>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL) op: assign_op.Equal rhs: {($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL')} spids: [8014] ) ] ) ] spids: [8000 8011] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:UPDATE_CHANNEL) op: assign_op.Equal rhs: {<none>} spids: [8021] ) ] ) ] ) ] ) ) (command.ShFunction name: configure_dev_accounts body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name ALLOW_DEV_ACCOUNTS))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [8041 8060] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name USE_EXTERNAL_INTERFACE))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [8078 8098] ) ] ) (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: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ALLOW_DEV_ACCOUNTS) op: assign_op.Equal rhs: {<yes>} spids: [8154] ) ] ) ] spids: [8137 8151] ) ] ) ] ) ) (command.ShFunction name: save_config body: (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 op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<sandstorm.conf>} ) ] do_fork: T ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<writeConfig>} {<SANDCATS_BASE_DOMAIN>}] redirects: [ (redir op: <Id.Redir_DGreat '>>'> loc: (redir_loc.Fd fd:1) arg: {<sandstorm.conf>} ) ] do_fork: T ) ] spids: [8195 8213] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_HTTPS_SUCCESSFUL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.Simple words: [{<writeConfig>} {<HTTPS_PORT>}] redirects: [ (redir op: <Id.Redir_DGreat '>>'> loc: (redir_loc.Fd fd:1) arg: {<sandstorm.conf>} ) ] do_fork: T ) ] spids: [8228 8246] ) ] ) (C {<echo>}) (C {<echo>} {(DQ <'Config written to '> ($ Id.VSub_DollarName '$PWD') <'/sandstorm.conf.'>)} ) ] ) ) (command.ShFunction name: download_latest_bundle_and_extract_if_needed body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-n>} { (DQ (braced_var_sub token: <Id.VSub_Name BUNDLE_FILE> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [8291 8307] ) ] ) (C {<echo>} { (DQ <'Finding latest build for '> ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL') <' channel...'> ) } ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUILD) op: assign_op.Equal rhs: { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<curl>} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-fs>} { (DQ <'https://install.sandstorm.io/'> ($ Id.VSub_DollarName '$DEFAULT_UPDATE_CHANNEL') <'?from=0&type=install_v2'> ) } ) ) ) } spids: [8342] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUILD_DIR) op: assign_op.Equal rhs: {(DQ <sandstorm-> (${ Id.VSub_Name BUILD))} spids: [8364] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.DBracket expr: (bool_expr.LogicalNot child: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {(DQ ($ Id.VSub_DollarName '$BUILD'))} right: {<Id.Lit_Other '^'> <Id.Lit_Other '['> <0-9> <Id.Lit_Other ']'> <Id.Lit_Other '+'> <Id.Lit_Other '$'> } ) ) ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<fail>} {(DQ <E_INVALID_BUILD_NUM>)} { (DQ <'Server returned invalid build number: '> ($ Id.VSub_DollarName '$BUILD') ) } ) ] spids: [8374 8396] ) ] ) (command.ShFunction name: do-download body: (BraceGroup children: [ (C {<rm>} {<-rf>} {(DQ (${ Id.VSub_Name BUILD_DIR))}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:WORK_DIR) op: assign_op.Equal rhs: { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<mktemp>} {<-d>} {<'./sandstorm-installer.XXXXXXXXXX'>}) ) ) } spids: [8433] ) ] ) (C {<local>} {<Id.Lit_VarLike 'URL='> (DQ <'https://dl.sandstorm.io/sandstorm-'> ($ Id.VSub_DollarName '$BUILD') <.tar.xz> ) } ) (C {<echo>} {(DQ <'Downloading: '> ($ Id.VSub_DollarName '$URL'))}) (C {<retryable_curl>} {(DQ ($ Id.VSub_DollarName '$URL'))} { (DQ ($ Id.VSub_DollarName '$WORK_DIR') <'/sandstorm-'> ($ Id.VSub_DollarName '$BUILD') <.tar.xz> ) } ) (C {<retryable_curl>} {(DQ ($ Id.VSub_DollarName '$URL') <.sig>)} { (DQ ($ Id.VSub_DollarName '$WORK_DIR') <'/sandstorm-'> ($ Id.VSub_DollarName '$BUILD') <.tar.xz.sig> ) } ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Simple words: [{<which>} {<gpg>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/dev/null'>} ) ] do_fork: T ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<export>} {<Id.Lit_VarLike 'GNUPGHOME='> (DQ ($ Id.VSub_DollarName '$WORK_DIR') <'/.gnupg'>) } ) (C {<mkdir>} {<-m>} {<0700>} {<-p>} {(DQ ($ Id.VSub_DollarName '$GNUPGHOME'))} ) (command.Simple words: [{<gpg>} {<--dearmor>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: { (DQ ($ Id.VSub_DollarName '$WORK_DIR') <'/sandstorm-keyring.gpg'> ) } ) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine 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'> ] ) ) ] do_fork: T ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Pipeline children: [ (command.Simple words: [ {<gpg>} {<--no-default-keyring>} {<--keyring>} {($ Id.VSub_DollarName '$WORK_DIR') <'/sandstorm-keyring.gpg'> } {<--status-fd>} {<1>} {<--verify>} (word.BracedTree parts: [ ($ Id.VSub_DollarName '$WORK_DIR') <'/sandstorm-'> ($ Id.VSub_DollarName '$BUILD') <.tar.xz> (word_part.BracedTuple words: [{<.sig>} {}] ) ] ) ] redirects: [ (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<grep>} {<-q>} { (SQ < '^\\[GNUPG:\\] VALIDSIG 160D2D577518B58D94C9800B63F227499DA8CCBD ' > ) } ) ] negated: F ) terminator: <Id.Op_Semi _> ) ] action: [(C {<echo>} {(DQ <'GPG signature is valid.'>)})] spids: [8583 8627] ) ] else_action: [ (C {<rm>} {<-rf>} {<sandstorm-> ($ Id.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>}) ] spids: [8493 8504] ) ] 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 op: <Id.Redir_GreatAnd '>&'> loc: (redir_loc.Fd fd:1) arg: {<2>} ) ] do_fork: T ) ] ) (C {<tar>} {<Jxof>} { (DQ ($ Id.VSub_DollarName '$WORK_DIR') <'/sandstorm-'> ($ Id.VSub_DollarName '$BUILD') <.tar.xz> ) } ) (C {<rm>} {<-rf>} {(DQ ($ Id.VSub_DollarName '$WORK_DIR'))}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-e>} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<fail>} {(DQ <E_BAD_PACKAGE>)} { (DQ <'Bad package -- did not contain '> ($ Id.VSub_DollarName '$BUILD_DIR') <' directory.'> ) } ) ] spids: [8707 8722] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-e>} { (DQ ($ Id.VSub_DollarName '$BUILD_DIR') <'/buildstamp'> ) } {<Id.Lit_RBracket ']'>} ) (C {<Id.Lit_LBracket '['>} { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<stat>} {<-c>} {<Id.Lit_Other '%'> <Y>} { (DQ ($ Id.VSub_DollarName '$BUILD_DIR') <'/buildstamp'> ) } ) ) } {<-lt>} { (word_part.ArithSub anode: (arith_expr.Binary op_id: Id.Arith_Minus left: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<date>} {<Id.Lit_Other '+'> <Id.Lit_Other '%'> <s> } ) ) } right: (arith_expr.Binary op_id: Id.Arith_Star left: (arith_expr.Binary op_id: Id.Arith_Star left: (arith_expr.Binary op_id: Id.Arith_Star left: {<Id.Lit_Digits 30>} right: {<Id.Lit_Digits 24>} ) right: {<Id.Lit_Digits 60>} ) right: {<Id.Lit_Digits 60>} ) ) ) } {<Id.Lit_RBracket ']'>} ) ] ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<rm>} {<-rf>} {(DQ ($ Id.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.'>)} ) ] spids: [8742 8805] ) ] ) ] ) ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-e>} {($ Id.VSub_DollarName '$BUILD_DIR')} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ ($ Id.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: <Id.Op_Semi _> ) ] action: [(C {<do-download>})] spids: [8875 8888] ) ] ) ] spids: [8853 8864] ) ] else_action: [(C {<do-download>})] ) ] ) ) (command.ShFunction name: extract_bundle_if_provided body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name BUNDLE_FILE> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [8923 8939] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {($ Id.VSub_DollarName '$BUILD')} {<Id.Lit_Equals '='>} {<0>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUILD_DIR) op: assign_op.Equal rhs: {<sandstorm-custom.> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<date>} {<Id.Lit_Other '+'> (SQ <'%Y-%m-%d_%H-%M-%S'>)}) ) } spids: [8970] ) ] ) ] spids: [8954 8967] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:BUILD_DIR) op: assign_op.Equal rhs: {<sandstorm-> ($ Id.VSub_DollarName '$BUILD')} spids: [8985] ) ] ) ] ) (C {<rm>} {<-rf>} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))}) (C {<mkdir>} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))}) (command.Subshell child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<cd>} {(DQ ($ Id.VSub_DollarName '$BUILD_DIR'))}) (C {<tar>} {<Jxof>} {(DQ ($ Id.VSub_DollarName '$BUNDLE_FILE'))} {<--strip> <Id.Lit_Equals '='> <1>} ) ] ) ) ] ) ) (command.ShFunction name: make_runtime_directories body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:GROUP) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<id>} {<-g>} {($ Id.VSub_DollarName '$SERVER_USER')}) ) } spids: [9042] ) ] ) (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>} {($ Id.VSub_DollarName '$BUILD_DIR')} {<latest>}) (C {<ln>} {<-sfT>} {<'latest/sandstorm'>} {<sandstorm>}) ] ) ) (command.ShFunction name: set_permissions body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [9120 9138] ) ] ) (C {<local>} {<Id.Lit_VarLike 'ADMIN_TOKEN_PATH='>}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-e>} {(DQ (${ Id.VSub_Name ADMIN_TOKEN_PATH))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ADMIN_TOKEN_PATH) op: assign_op.Equal rhs: {(DQ <'var/sandstorm/adminToken'>)} spids: [9172] ) ] ) ] spids: [9153 9169] ) ] ) (C {<chown>} {<-R>} {($ Id.VSub_DollarName '$SERVER_USER') <Id.Lit_Colon ':'> ($ Id.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>}] ) ] ) {($ Id.VSub_DollarName '$ADMIN_TOKEN_PATH')} ) (C {<chown>} {<root> <Id.Lit_Colon ':'> ($ Id.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>}] ) ] ) {($ Id.VSub_DollarName '$ADMIN_TOKEN_PATH')} ) (C {<chmod>} {<-R>} {<Id.Lit_VarLike 'g='> <rwX> <Id.Lit_Comma ','> <Id.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>}] ) ] ) {($ Id.VSub_DollarName '$ADMIN_TOKEN_PATH')} ) ] ) ) (command.ShFunction name: install_sandstorm_symlinks body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [9297 9315] ) ] ) (C {<local>} {<Id.Lit_VarLike 'FAILED_TO_WRITE_SYMLINK='> (DQ <no>)}) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<ln>} {<-sfT>} {($ Id.VSub_DollarName '$PWD') <'/sandstorm'>} {<'/usr/local/bin/sandstorm'>} ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:FAILED_TO_WRITE_SYMLINK) op: assign_op.Equal rhs: {<yes>} spids: [9349] ) ] ) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<ln>} {<-sfT>} {($ Id.VSub_DollarName '$PWD') <'/sandstorm'>} {<'/usr/local/bin/spk'>} ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:FAILED_TO_WRITE_SYMLINK) op: assign_op.Equal rhs: {<yes>} spids: [9364] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name FAILED_TO_WRITE_SYMLINK))} {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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 <' - '> ($ Id.VSub_DollarName '$PWD') <'/sandstorm'>)}) (C {<echo>} {(DQ <' - '> ($ Id.VSub_DollarName '$PWD') <'/sandstorm spk'>)}) (C {<echo>} {(DQ )}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [9381 9401] ) ] ) ] ) ) (command.ShFunction name: ask_about_starting_at_boot body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:START_AT_BOOT) op: assign_op.Equal rhs: {(DQ <no>)} spids: [9483] ) ] ) ] spids: [9461 9480] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name START_AT_BOOT> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [9497 9516] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<prompt-yesno>} { (DQ <'Start sandstorm at system boot (using '> ($ Id.VSub_DollarName '$INIT_SYSTEM') <')?'> ) } {<yes>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:START_AT_BOOT) op: assign_op.Equal rhs: {<yes>} spids: [9542] ) ] ) ] spids: [9526 9539] ) ] ) ] ) ) (command.ShFunction name: configure_start_at_boot_if_desired body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDSTORM_NEEDS_TO_BE_STARTED) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [9558] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} { (DQ (braced_var_sub token: <Id.VSub_Name START_AT_BOOT> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [9573 9595] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <systemd>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name INIT_SYSTEM))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: assign_op.Equal rhs: {<no>} spids: [9631] ) ] ) ] spids: [9605 9625] ) (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <sysvinit>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name INIT_SYSTEM))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: assign_op.Equal rhs: {<no>} spids: [9661] ) ] ) ] spids: [9635 9655] ) ] 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: (BraceGroup children: [ (C {<local>} {<Id.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>} {($ Id.VSub_DollarName '$SYSTEMD_UNIT')}) ] negated: F ) terminator: <Id.Op_Semi _> ) ] action: [ (command.AndOr ops: [Id.Op_DPipe] children: [(C {<systemctl>} {<stop>} {<sandstorm>}) (C {<true>})] ) ] spids: [9723 9738] ) ] ) (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 {<Id.Lit_LBracket '['>} {<-e>} {($ Id.VSub_DollarName '$SYSTEMD_UNIT_PATH') <'/'> ($ Id.VSub_DollarName '$SYSTEMD_UNIT') } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<rm>} {($ Id.VSub_DollarName '$SYSTEMD_UNIT_PATH') <'/'> ($ Id.VSub_DollarName '$SYSTEMD_UNIT') } ) ] spids: [9776 9790] ) ] ) ] ) ) (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/etc/systemd/system/'> ($ Id.VSub_DollarName '$SYSTEMD_UNIT')} ) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine 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='> ($ Id.VSub_DollarName '$PWD') <'/sandstorm start\n'> <'ExecStop='> ($ Id.VSub_DollarName '$PWD') <'/sandstorm stop\n'> <'\n'> <'[Install]\n'> <'WantedBy=multi-user.target\n'> ] ) ) ] do_fork: T ) (C {<systemctl>} {<enable>} {<sandstorm>}) (C {<systemctl>} {<start>} {<sandstorm>}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:STARTED_SANDSTORM) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [9851] ) ] ) ] ) ) (command.ShFunction name: configure_sysvinit_init_system body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-e>} {<'/etc/init.d/sandstorm'>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (command.AndOr ops: [Id.Op_DPipe] children: [(C {<service>} {<sandstorm>} {<stop>}) (C {<true>})] ) ] spids: [9883 9895] ) ] ) (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'/etc/init.d/sandstorm'>} ) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine 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: <Id.Lit_EscapedChar '\\$'> ) <'local_fs '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'remote_fs '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'networking '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'syslog\n'> <'# Required-Stop: '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'local_fs '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'remote_fs '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'networking '> (word_part.EscapedLiteral token: <Id.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='> <Id.Right_DoubleQuote '"'> <'Sandstorm server'> <Id.Right_DoubleQuote '"'> <'\n'> <'DAEMON='> ($ Id.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 '> <Id.Right_DoubleQuote '"'> <'service sandstorm'> <Id.Right_DoubleQuote '"'> <' '> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'DAEMON '> <Id.Right_DoubleQuote '"'> (word_part.EscapedLiteral token: <Id.Lit_EscapedChar '\\$'> ) <'@'> <Id.Right_DoubleQuote '"'> <'\n'> ] ) ) ] do_fork: T ) (C {<chmod>} {<Id.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: assign_op.Equal rhs: {(DQ <yes>)} spids: [10017] ) ] ) ] ) ) (command.ShFunction name: generate_admin_token body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name ALLOW_DEV_ACCOUNTS))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [10036 10056] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name ADMIN_TOKEN> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<local>} {<Id.Lit_VarLike 'TMPFILENAME='> (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<mktemp>} {<'./var/sandstorm/adminTokenTmp.XXXXXXXXXX'>}) ) ) } ) (command.Simple words: [{<echo>} {<-n>} {(DQ ($ Id.VSub_DollarName '$ADMIN_TOKEN'))}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$TMPFILENAME'))} ) ] do_fork: T ) (C {<local>} {<Id.Lit_VarLike 'FILENAME='> (DQ <'./var/sandstorm/adminToken'>)} ) (C {<mv>} {(DQ ($ Id.VSub_DollarName '$TMPFILENAME'))} {(DQ ($ Id.VSub_DollarName '$FILENAME'))} ) (C {<chmod>} {<0640>} {(DQ ($ Id.VSub_DollarName '$FILENAME'))}) (C {<chgrp>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER'))} {(DQ ($ Id.VSub_DollarName '$FILENAME'))} ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [10074 10093] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ADMIN_TOKEN) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<'./sandstorm'>} {<admin-token>} {<--quiet>}) ) } spids: [10169] ) ] ) ] ) ) (command.ShFunction name: print_success body: (BraceGroup children: [ (C {<echo>} {(DQ )}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDSTORM_NEEDS_TO_BE_STARTED'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ <'Installation complete. To start your server now, run:'>)}) (C {<echo>} {(DQ <' '> ($ Id.VSub_DollarName '$DIR') <'/sandstorm start'>)}) (C {<echo>} {(DQ <'Once that\'s done, visit this link to start using it:'>)}) ] spids: [10194 10212] ) ] else_action: [ (C {<echo>} {<-n>} {(DQ <'Your server is now online! '>)}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name SANDCATS_HTTPS_SUCCESSFUL))} {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ <'It should work immediately if you use Chrome.'>)}) ] spids: [10250 10270] ) ] ) (C {<echo>} {(DQ <'Visit this link to start using it:'>)}) ] ) (C {<echo>} {(DQ )}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name ADMIN_TOKEN> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} { (DQ <' '> (braced_var_sub token: <Id.VSub_Name BASE_URL> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<'(unknown; bad config)'>} ) ) <'/setup/token/'> ($ Id.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.'>)}) ] spids: [10309 10328] ) ] else_action: [ (C {<echo>} { (DQ <' '> (braced_var_sub token: <Id.VSub_Name BASE_URL> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<'(unknown; bad config)'>} ) ) <'/'> ) } ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name ALLOW_DEV_ACCOUNTS))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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).' > ) } ) ] spids: [10384 10404] ) ] ) (C {<echo>} {(DQ )}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ (${ Id.VSub_Name SANDCATS_HTTPS_SUCCESSFUL))} {<Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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.)'>)}) ] spids: [10430 10450] ) ] ) (C {<echo>}) (C {<echo>} {(DQ <'To learn how to control the server, run:'>)}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(C {<echo>} {(DQ <' sandstorm help'>)})] spids: [10486 10504] ) ] else_action: [ (C {<echo>} {(DQ <' '> ($ Id.VSub_DollarName '$DIR') <'/sandstorm help'>)}) ] ) ] ) ) (command.ShFunction name: sandcats_provide_help body: (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: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:DESIRED_SANDCATS_NAME) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'What Sandcats subdomain do you want to recover?'>)} {(DQ <none>)} ) ) } spids: [10616] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <none>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<sandcats_register_name>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [10635 10653] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')} right: {<Id.Lit_Other '['> <Id.Lit_Other .> <Id.Lit_Other ']'>} ) ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(DQ )}) (C {<echo>} {(DQ <'You entered: '> ($ Id.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: <Id.ControlFlow_Return return> ) ] spids: [10670 10686] ) ] ) (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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'OK to continue?'>)} {(DQ <yes>)}) ) } spids: [10746] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <no>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$OK_TO_CONTINUE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<sandcats_register_name>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [10760 10778] ) ] ) (C {<local>} {<Id.Lit_VarLike 'LOG_PATH='> (DQ <'var/sandcats/sendrecoverytoken-log'>)} ) (C {<touch>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<chmod>} {<0640>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTP_STATUS) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<20>} {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-X>} {<POST>} {<--data-urlencode>} { (DQ <'rawHostname='> ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME') ) } {<--output>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {<-w>} {(SQ <'%{http_code}'>)} {<-H>} {(SQ <'X-Sand: cats'>)} {<-H>} {(DQ <'Accept: text/plain'>)} {(DQ (${ Id.VSub_Name SANDCATS_API_BASE) <'/sendrecoverytoken'>)} ) ) } spids: [10819] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} {($ Id.VSub_DollarName '$LOG_PATH')}) ) ) } ) (C {<sandcats_recover_domain>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [10906 10925] ) ] ) (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<echo>} {(SQ )}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:TOKEN) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Please enter the token that we sent to you by email.'>)} {(SQ )} ) ) } spids: [10974] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ ($ Id.VSub_DollarName '$TOKEN'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} {(DQ <'Empty tokens are not valid.'>)}) (C {<sandcats_recover_domain>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [10992 11006] ) ] ) (C {<local>} {<Id.Lit_VarLike 'LOG_PATH='> (DQ <'var/sandcats/recover-log'>)}) (C {<touch>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<chmod>} {<0640>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTP_STATUS) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<20>} {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-X>} {<POST>} {<--data-urlencode>} { (DQ <'rawHostname='> ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME') ) } {<--data-urlencode>} {(DQ <'recoveryToken='> ($ Id.VSub_DollarName '$TOKEN'))} {<--output>} {(DQ ($ Id.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 (${ Id.VSub_Name SANDCATS_API_BASE) <'/recover'>)} ) ) } spids: [11070] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} {($ Id.VSub_DollarName '$LOG_PATH')}) ) ) } ) (C {<sandcats_recover_domain>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [11172 11191] ) ] ) (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<echo>} {(SQ )}) (C {<local>} {<Id.Lit_VarLike 'LOG_PATH='> (DQ <'var/sandcats/update-log'>)}) (C {<touch>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<chmod>} {<0640>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTP_STATUS) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<20>} {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-X>} {<POST>} {<--data-urlencode>} { (DQ <'rawHostname='> ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME') ) } {<--output>} {(DQ ($ Id.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 (${ Id.VSub_Name SANDCATS_API_BASE) <'/update'>)} ) ) } spids: [11281] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<error>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} {($ Id.VSub_DollarName '$LOG_PATH')}) ) ) } ) (C {<sandcats_recover_domain>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [11374 11393] ) ] ) (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<echo>} {(SQ )}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [11439] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SS_HOSTNAME) op: assign_op.Equal rhs: { (DQ (${ Id.VSub_Name DESIRED_SANDCATS_NAME) <.> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) ) } spids: [11445] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [11457] ) ] ) (C {<echo>} { (DQ <'Congratulations! You\'re all configured to use '> (${ Id.VSub_Name DESIRED_SANDCATS_NAME) <.> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) <.> ) } ) (C {<echo>} { (DQ <'Your credentials to use it are in '> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<readlink>} {<-f>} {<'var/sandcats'>}) ) <'; consider making a backup.'> ) } ) ] ) ) (command.ShFunction name: sandcats_registerreserved body: (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: assign_op.Equal rhs: {(DQ <'var/sandcats/registerreserved-log'>)} spids: [11514] ) ] ) (C {<touch>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<chmod>} {<0640>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTP_STATUS) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<20>} {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-X>} {<POST>} {<--data-urlencode>} { (DQ <'domainReservationToken='> ($ Id.VSub_DollarName '$SANDCATS_DOMAIN_RESERVATION_TOKEN') ) } {<--data-urlencode>} {(DQ <'rawHostname='> ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {<--output>} {(DQ ($ Id.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 (${ Id.VSub_Name SANDCATS_API_BASE) <'/registerreserved'>)} ) ) } spids: [11536] ) ] ) (command.If arms: [ (if_arm cond: [ (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) ] action: [ (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<echo>} {(SQ )}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SS_HOSTNAME) op: assign_op.Equal rhs: { (DQ (${ Id.VSub_Name DESIRED_SANDCATS_NAME) <.> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) ) } spids: [11691] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [11703] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [11709] ) ] ) (C {<echo>} { (DQ <'Congratulations! We have registered your '> (${ Id.VSub_Name DESIRED_SANDCATS_NAME) <.> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) <' name.'> ) } ) (C {<echo>} { (DQ <'Your credentials to use it are in '> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<readlink>} {<-f>} {<'var/sandcats'>}) ) <'; consider making a backup.'> ) } ) ] spids: [11638 11655] ) ] else_action: [ (C {<fail>} {(DQ <E_SANDCATS_REGISTER_RESERVED_SRV_FAIL>)} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) ) ) } ) ] ) ] ) ) (command.ShFunction name: sandcats_register_name body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_API_BASE) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_API_BASE> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<'https:'> <Id.Lit_Slash '/'> <Id.Lit_Slash '/'> <sandcats.io>} ) ) ) } spids: [11805] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_CURL_PARAMS) op: assign_op.Equal rhs: { (DQ (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_CURL_PARAMS> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } spids: [11818] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<Id.KW_Bang '!'>} {<-z>} { (DQ (braced_var_sub token: <Id.VSub_Name SANDCATS_DOMAIN_RESERVATION_TOKEN> suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:(word.Empty)) ) ) } {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<sandcats_registerreserved>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [11836 11855] ) ] ) (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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} { (DQ <'What *.'> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) <' subdomain would you like?'> ) } {(SQ )} ) ) } spids: [11882] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<sandcats_register_name>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [11908 11922] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <none>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [11939 11957] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <help>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<sandcats_provide_help>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [11971 11989] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (command.Pipeline children: [ (command.DBracket expr: (bool_expr.Binary op_id: Id.BoolBinary_EqualTilde left: {($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME')} right: {<Id.Lit_Other '^'> <Id.Lit_Other '['> <0-9a-zA-Z-> <Id.Lit_Other ']'> <Id.Lit_Other '{'> <1> <Id.Lit_Other ','> <20> <Id.Lit_Other '}'> <Id.Lit_Other '$'> } ) ) ] negated: T ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<sandcats_register_name>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] spids: [12010 12035] ) ] ) (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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Enter your email address:'>)} {(DQ )}) ) } spids: [12063] ) ] ) (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ )} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_REGISTRATION_EMAIL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.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: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<prompt>} {(DQ <'Enter your email address:'>)} {(DQ )}) ) } spids: [12108] ) ] ) ] ) ) (C {<echo>} {(DQ <'Registering your domain.'>)}) (C {<local>} {<LOG_PATH>}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:LOG_PATH) op: assign_op.Equal rhs: {(DQ <'var/sandcats/register-log'>)} spids: [12137] ) ] ) (C {<touch>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<chmod>} {<0640>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTP_STATUS) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<20>} {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-X>} {<POST>} {<--data-urlencode>} { (DQ <'rawHostname='> ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME') ) } {<--data-urlencode>} {(DQ <'email='> ($ Id.VSub_DollarName '$SANDCATS_REGISTRATION_EMAIL'))} {<--output>} {(DQ ($ Id.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 (${ Id.VSub_Name SANDCATS_API_BASE) <'/register'>)} ) ) } spids: [12159] ) ] ) (command.If arms: [ (if_arm cond: [ (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.Lit_RBracket ']'>} ) ] action: [ (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<echo>} {(SQ )}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SS_HOSTNAME) op: assign_op.Equal rhs: { (DQ (${ Id.VSub_Name DESIRED_SANDCATS_NAME) <.> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) ) } spids: [12314] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:USE_EXTERNAL_INTERFACE) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [12326] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:SANDCATS_SUCCESSFUL) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [12332] ) ] ) (C {<echo>} { (DQ <'Congratulations! We have registered your '> (${ Id.VSub_Name DESIRED_SANDCATS_NAME) <.> (${ Id.VSub_Name SANDCATS_BASE_DOMAIN) <' name.'> ) } ) (C {<echo>} { (DQ <'Your credentials to use it are in '> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<readlink>} {<-f>} {<'var/sandcats'>}) ) <'; consider making a backup.'> ) } ) ] spids: [12261 12278] ) ] else_action: [ (C {<error>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) ) ) } ) (C {<sandcats_register_name>}) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] ) ] ) ) (command.ShFunction name: sandcats_configure_https body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_GETCERTIFICATE'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [12414 12433] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$SANDCATS_SUCCESSFUL'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [12447 12466] ) ] ) (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>} {<Id.Lit_VarLike 'HTTPS_BASE_DIR='> (DQ <'var/sandcats/https'>)}) (C {<local>} {<Id.Lit_VarLike 'HTTPS_CONFIG_DIR='> (DQ ($ Id.VSub_DollarName '$HTTPS_BASE_DIR') <'/'> ($ Id.VSub_DollarName '$SS_HOSTNAME') ) } ) (C {<mkdir>} {<-p>} {<-m>} {<0700>} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR'))}) (C {<chmod>} {<0700>} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR'))}) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<chown>} {<-R>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) <Id.Lit_Colon ':'> (DQ ($ Id.VSub_DollarName '$SERVER_USER')) } {(DQ ($ Id.VSub_DollarName '$HTTPS_BASE_DIR'))} ) ] spids: [12599 12617] ) ] ) (C {<echo>} {(DQ <'Generating certificate request...'>)}) (command.Simple words: [ {<openssl>} {<req>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-nodes>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-newkey>} {<rsa> <Id.Lit_Colon ':'> <4096>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-subj>} {(DQ <'/CN=*.'> (${ Id.VSub_Name SS_HOSTNAME) <'/'>)} {<-keyout>} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) <'/0'>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-out>} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) <'/0.csr'>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} ] redirects: [ (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) (C {<chmod>} {<0600>} {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR')) <'/0'>}) (C {<chmod>} {<0600>} {(DQ ($ Id.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: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR') <'/0.response-json'>)} spids: [12835] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HTTP_STATUS) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dotdotdot_curl>} {<--silent>} {<--max-time>} {<60>} {($ Id.VSub_DollarName '$SANDCATS_CURL_PARAMS')} {<-A>} {(DQ ($ Id.VSub_DollarName '$CURL_USER_AGENT'))} {<-X>} {<POST>} {<--data-urlencode>} { (DQ <'rawHostname='> ($ Id.VSub_DollarName '$DESIRED_SANDCATS_NAME') ) } {<--data-urlencode>} { (DQ <'certificateSigningRequest='> (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} { (DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR') <'/0.csr'> ) } ) ) ) } {<--output>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))} {<-w>} {(SQ <'%{http_code}'>)} {<-H>} {(SQ <'X-Sand: cats'>)} {<--cert>} {<'var/sandcats/id_rsa.private_combined'>} { (DQ (${ Id.VSub_Name SANDCATS_API_BASE) <'/'> (braced_var_sub token: <Id.VSub_Name OVERRIDE_SANDCATS_GETCERTIFICATE_API_PATH> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {<getcertificate>} ) ) ) } ) ) } spids: [12842] ) ] ) (C {<chmod>} {<0600>} {(DQ ($ Id.VSub_DollarName '$LOG_PATH'))}) (C {<chown>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) <Id.Lit_Colon ':'> (DQ ($ Id.VSub_DollarName '$SERVER_USER')) } {(DQ ($ Id.VSub_DollarName '$HTTPS_CONFIG_DIR') <'/'>) <Id.Lit_Star '*'>} ) (command.If arms: [ (if_arm cond: [ (C {<Id.Lit_LBracket '['>} {(DQ <200>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$HTTP_STATUS'))} {<Id.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: assign_op.Equal rhs: {(DQ <yes>)} spids: [13019] ) ] ) ] spids: [12980 12997] ) ] else_action: [ (C {<error>} { (DQ < 'Some part of HTTPS autoconfiguration failed. Log data available in ' > ($ Id.VSub_DollarName '$LOG_PATH') ) } ) (command.ControlFlow token: <Id.ControlFlow_Return return> ) ] ) ] ) ) (command.ShFunction name: wait_for_server_bind_to_its_port body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.KW_Bang '!'> <Id.Lit_Equals '='>} {(DQ (${ Id.VSub_Name STARTED_SANDSTORM))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [13059 13080] ) ] ) (C {<local>} {<Id.Lit_VarLike 'PORT_TO_CHECK='> (DQ (braced_var_sub token: <Id.VSub_Name HTTPS_PORT> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonHyphen arg_word: {($ Id.VSub_DollarName '$PORT')} ) ) ) } ) (C {<echo>} {<-n>} {(DQ <'Your server is coming online. Waiting up to 90 seconds...'>)} ) (C {<local>} {<Id.Lit_VarLike 'ONLINE_YET='> (DQ <no>)}) (command.ForEach iter_name: waited_n_seconds iter_words: [ { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<seq>} {<0>} {<89>}) ) } ] do_arg_iter: F body: (command.DoGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<is_port_bound>} {(DQ (${ Id.VSub_Name BIND_IP))} {(DQ (${ Id.VSub_Name PORT_TO_CHECK))} ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ONLINE_YET) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [13165] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$ONLINE_YET'))} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<echo>} {(SQ )}) (command.ControlFlow token: <Id.ControlFlow_Break break> ) ] spids: [13171 13190] ) ] ) (C {<echo>} {<-n>} {(DQ <.>)}) (C {<sleep>} {<1>}) ] ) ) (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<is_port_bound>} {(DQ (${ Id.VSub_Name BIND_IP))} {(DQ (${ Id.VSub_Name PORT_TO_CHECK))} ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ONLINE_YET) op: assign_op.Equal rhs: {(DQ <yes>)} spids: [13243] ) ] ) ] ) (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$ONLINE_YET'))} {<Id.Lit_Equals '='> <Id.Lit_Equals '='>} {(DQ <yes>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [13250 13268] ) ] else_action: [ (C {<fail>} {(DQ <E_NEVER_LISTENED>)} {(DQ <'Your server never started listening.'>)} ) ] ) ] ) ) (command.ShFunction name: sandcats_generate_keys body: (BraceGroup children: [ (command.If arms: [ (if_arm cond: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-f>} {<'var/sandcats/id_rsa.private_combined'>} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [(command.ControlFlow token:<Id.ControlFlow_Return return>)] spids: [13304 13316] ) ] ) (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 {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<chown>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) <Id.Lit_Colon ':'> (DQ ($ Id.VSub_DollarName '$SERVER_USER')) } {<'var/sandcats'>} ) ] spids: [13379 13397] ) ] ) (command.Simple words: [ {<openssl>} {<req>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-new>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-newkey>} {<rsa> <Id.Lit_Colon ':'> <4096>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-days>} {<3650>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-nodes>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-x509>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-subj>} {(DQ <'/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd'>)} {<-keyout>} {<'var/sandcats/id_rsa'>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {<-out>} {<'var/sandcats/id_rsa.pub'>} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} {(command_sub left_token:<Id.Left_Backtick '`'> child:(command.NoOp))} ] redirects: [ (redir op: <Id.Redir_Great '2>'> loc: (redir_loc.Fd fd:2) arg: {<'/dev/null'>} ) ] do_fork: T ) (command.Simple words: [{<cat>} {<'var/sandcats/id_rsa'>} {<'var/sandcats/id_rsa.pub'>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'var/sandcats/id_rsa.private_combined'>} ) ] do_fork: T ) (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 {<Id.Lit_LBracket '['>} {(DQ <yes>)} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$CURRENTLY_UID_ZERO'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] action: [ (C {<chown>} {(DQ ($ Id.VSub_DollarName '$SERVER_USER')) <Id.Lit_Colon ':'> (DQ ($ Id.VSub_DollarName '$SERVER_USER')) } (word.BracedTree parts: [ <'var/sandcats/id_rsa'> (word_part.BracedTuple words: [{} {<.pub>} {<.private_combined>}] ) ] ) ) ] spids: [13617 13635] ) ] ) (C {<echo>} {<-ne>} {(SQ <'\\r'>)}) ] ) ) (C {<handle_args>} {(DQ ($ Id.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 ($ Id.VSub_Number '$0'))} {(DQ ($ Id.VSub_At '$@'))}) ] )