Example #1
0
func RunModule(module Module) {
	var output types.Value = nil
	defer func() {
		var result = 0
		if r := recover(); r != nil {
			result = 1
			if output == nil {
				output = types.Map{
					types.Keyword("success"): types.Bool(false),
					types.Keyword("error"):   types.String(fmt.Sprint(r)),
				}
			}
		}
		if output == nil {
			output = types.Map{
				types.Keyword("success"): types.Bool(true),
			}
		}
		fmt.Println(edn.DumpString(output))
		os.Exit(result)
	}()
	var input types.Value = nil
	var err error = nil
	if module.TakesInput() {
		input, err = edn.ParseReader(bufio.NewReader(os.Stdin))
	}
	if err != nil {
		panic(err)
	}
	output, err = module.Exec(input)
	if err != nil {
		panic(err)
	}
}
Example #2
0
func (self GatherFacts) Exec(_ types.Value) (types.Value, error) {
	var result types.Map = make(types.Map)
	result[types.Keyword("os")] = types.String(runtime.GOOS)
	result[types.Keyword("arch")] = types.String(runtime.GOARCH)
	var interfaces, err = net.Interfaces()
	if err != nil {
		return nil, err
	}
	var netifs = make(types.Vector, len(interfaces))
	for i, iface := range interfaces {
		var facemap = make(types.Map)
		facemap[types.Keyword("name")] = types.String(iface.Name)
		facemap[types.Keyword("mac-address")] = types.String(iface.HardwareAddr.String())
		facemap[types.Keyword("loopback?")] = types.Bool(iface.Flags&net.FlagLoopback != 0)
		var addrs, err = iface.Addrs()
		if err != nil {
			return nil, err
		}
		var v4list = (*types.List)(list.New())
		var v6list = (*types.List)(list.New())
		for _, addr := range addrs {
			var addrmap = make(types.Map)
			switch ip := addr.(type) {
			case *net.IPAddr:
				var v4 = ip.IP.To4()
				addrmap[types.Keyword("address")] = types.String(ip.IP.String())
				if v4 != nil {
					v4list.Insert(addrmap)
				} else {
					v6list.Insert(addrmap)
				}
				break

			case *net.IPNet:
				var v4 = ip.IP.To4()
				addrmap[types.Keyword("address")] = types.String(ip.IP.String())
				size, bits := ip.Mask.Size()
				addrmap[types.Keyword("prefix-length")] = types.Int(size)
				addrmap[types.Keyword("bit-length")] = types.Int(bits)
				if v4 != nil {
					v4list.Insert(addrmap)
				} else {
					v6list.Insert(addrmap)
				}
				break

			}
		}
		facemap[types.Keyword("ipv4-addresses")] = v4list
		facemap[types.Keyword("ipv6-addresses")] = v6list
		netifs[i] = facemap
	}
	result[types.Keyword("network-interfaces")] = netifs
	return result, nil
}
Example #3
0
func (this HashFile) Exec(input types.Value) (out types.Value, err error) {
	var inputMap types.Map
	if i, ok := input.(types.Map); ok {
		inputMap = i
	} else {
		err = errors.New(fmt.Sprintf("expected a map as input, got a %T", input))
		return
	}

	var hashName string
	var hashNameElement = inputMap[types.Keyword("hash")]
	if hashNameElement == nil {
		hashName = "sha256"
	} else if h, ok := hashNameElement.(types.String); ok {
		hashName = string(h)
	} else if k, ok := hashNameElement.(types.Keyword); ok {
		hashName = string(k)
	} else if s, ok := hashNameElement.(types.Symbol); ok {
		hashName = string(s)
	} else {
		err = errors.New(":hash must be a string, keyword, or symbol if specified")
		return
	}
	hashName = strings.ToLower(hashName)

	var hash hash.Hash
	if hashName == "md5" {
		hash = md5.New()
	} else if hashName == "sha" || hashName == "sha1" || hashName == "sha-1" {
		hash = sha1.New()
	} else if hashName == "sha224" || hashName == "sha-224" {
		hash = sha256.New224()
	} else if hashName == "sha256" || hashName == "sha-256" {
		hash = sha256.New()
	} else if hashName == "sha384" || hashName == "sha-384" {
		hash = sha512.New384()
	} else if hashName == "sha512/224" || hashName == "sha-512/224" {
		hash = sha512.New512_224()
	} else if hashName == "sha512/256" || hashName == "sha-512/256" {
		hash = sha512.New512_256()
	} else if hashName == "sha512" || hashName == "sha-512" {
		hash = sha512.New()
	} else {
		err = errors.New(fmt.Sprint("unknown hash name: ", hashName))
		return
	}

	var fileName string
	var fileElem = inputMap[types.Keyword("file")]
	if fileElem == nil {
		err = errors.New(":file argument is required")
		return
	} else if f, ok := fileElem.(types.String); ok {
		fileName = string(f)
	} else {
		err = errors.New(":file argument must be a string")
		return
	}

	file, err := os.Open(fileName)
	if err != nil {
		return
	}
	hashOut := bufio.NewWriterSize(hash, hash.BlockSize())
	wrote, err := io.Copy(hashOut, file)
	hashOut.Flush()
	if err != nil {
		return
	}
	out = types.Map{
		types.Keyword("success"): types.Bool(true),
		types.Keyword("size"):    types.Int(wrote),
		types.Keyword("file"):    types.String(fileName),
		types.Keyword("hash"):    types.Keyword(hashName),
		types.Keyword("digest"):  types.String(fmt.Sprintf("%x", hash.Sum(nil))),
	}
	return
}
Example #4
0
func (yyrcvr *yyParserImpl) Parse(yylex yyLexer, result *yySymType) int {
	var yyn int
	var yylval yySymType
	var yyVAL yySymType
	var yyDollar []yySymType
	_ = yyDollar // silence set and not used
	yyS := make([]yySymType, yyMaxDepth)

	Nerrs := 0   /* number of errors */
	Errflag := 0 /* error recovery flag */
	yystate := 0
	yychar := -1
	yytoken := -1 // yychar translated into internal numbering
	yyrcvr.lookahead = func() int { return yychar }
	defer func() {
		// Make sure we report no lookahead when not parsing.
		yystate = -1
		yychar = -1
		yytoken = -1
	}()
	yyp := -1
	goto yystack

ret0:
	return 0

ret1:
	return 1

yystack:
	/* put a state and value onto the stack */
	if yyDebug >= 4 {
		__yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate))
	}

	yyp++
	if yyp >= len(yyS) {
		nyys := make([]yySymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
	}
	yyS[yyp] = yyVAL
	yyS[yyp].yys = yystate

yynewstate:
	yyn = yyPact[yystate]
	if yyn <= yyFlag {
		goto yydefault /* simple state */
	}
	if yychar < 0 {
		yychar, yytoken = yylex1(yylex, &yylval)
	}
	yyn += yytoken
	if yyn < 0 || yyn >= yyLast {
		goto yydefault
	}
	yyn = yyAct[yyn]
	if yyChk[yyn] == yytoken { /* valid shift */
		yychar = -1
		yytoken = -1
		yyVAL = yylval
		yystate = yyn
		if Errflag > 0 {
			Errflag--
		}
		goto yystack
	}

yydefault:
	/* default state action */
	yyn = yyDef[yystate]
	if yyn == -2 {
		if yychar < 0 {
			yychar, yytoken = yylex1(yylex, &yylval)
		}

		/* look through exception table */
		xi := 0
		for {
			if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
				break
			}
			xi += 2
		}
		for xi += 2; ; xi += 2 {
			yyn = yyExca[xi+0]
			if yyn < 0 || yyn == yytoken {
				break
			}
		}
		yyn = yyExca[xi+1]
		if yyn < 0 {
			goto ret0
		}
	}
	if yyn == 0 {
		/* error ... attempt to resume parsing */
		switch Errflag {
		case 0: /* brand new error */
			yylex.Error(yyErrorMessage(yystate, yytoken))
			Nerrs++
			if yyDebug >= 1 {
				__yyfmt__.Printf("%s", yyStatname(yystate))
				__yyfmt__.Printf(" saw %s\n", yyTokname(yytoken))
			}
			fallthrough

		case 1, 2: /* incompletely recovered error ... try again */
			Errflag = 3

			/* find a state where "error" is a legal shift action */
			for yyp >= 0 {
				yyn = yyPact[yyS[yyp].yys] + yyErrCode
				if yyn >= 0 && yyn < yyLast {
					yystate = yyAct[yyn] /* simulate a shift of "error" */
					if yyChk[yystate] == yyErrCode {
						goto yystack
					}
				}

				/* the current p has no shift on "error", pop stack */
				if yyDebug >= 2 {
					__yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
				}
				yyp--
			}
			/* there is no state on the stack with an error shift ... abort */
			goto ret1

		case 3: /* no shift yet; clobber input char */
			if yyDebug >= 2 {
				__yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken))
			}
			if yytoken == yyEofCode {
				goto ret1
			}
			yychar = -1
			yytoken = -1
			goto yynewstate /* try again in the same state */
		}
	}

	/* reduction by production yyn */
	if yyDebug >= 2 {
		__yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
	}

	yynt := yyn
	yypt := yyp
	_ = yypt // guard against "declared and not used"

	yyp -= yyR2[yyn]
	// yyp is now the index of $0. Perform the default action. Iff the
	// reduced production is ε, $1 is possibly out of range.
	if yyp+1 >= len(yyS) {
		nyys := make([]yySymType, len(yyS)*2)
		copy(nyys, yyS)
		yyS = nyys
	}
	yyVAL = yyS[yyp+1]

	/* consult goto table to find next state */
	yyn = yyR1[yyn]
	yyg := yyPgo[yyn]
	yyj := yyg + yyS[yyp].yys + 1

	if yyj >= yyLast {
		yystate = yyAct[yyg]
	} else {
		yystate = yyAct[yyj]
		if yyChk[yystate] != -yyn {
			yystate = yyAct[yyg]
		}
	}
	// dummy call; replaced with literal code
	switch yynt {

	case 1:
		yyDollar = yyS[yypt-3 : yypt+1]
		//line parser.y:41
		{
			result.v = yyDollar[2].v
		}
	case 2:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:42
		{
			yylex.Error("empty input")
		}
	case 4:
		yyDollar = yyS[yypt-4 : yypt+1]
		//line parser.y:47
		{
			yyVAL.v = types.TaggedValue{string(yyDollar[2].v.(types.Symbol)), yyDollar[4].v}
		}
	case 24:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:80
		{
			yyVAL.v = types.Value(new(types.List))
		}
	case 25:
		yyDollar = yyS[yypt-4 : yypt+1]
		//line parser.y:81
		{
			yyDollar[1].v.(*types.List).Insert(yyDollar[3].v)
		}
	case 26:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:87
		{
			yyVAL.v = types.Bool(true)
		}
	case 27:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:88
		{
			yyVAL.v = types.Bool(false)
		}
	case 28:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:92
		{
			yyVAL.v = types.Value(nil)
		}
	case 37:
		yyDollar = yyS[yypt-4 : yypt+1]
		//line parser.y:129
		{
			set := types.Sequence(types.Set{})
			values := types.Sequence(yyDollar[3].v.(*types.List))
			yyVAL.v = set.Into(values)
		}
	case 38:
		yyDollar = yyS[yypt-3 : yypt+1]
		//line parser.y:137
		{
			yyVAL.k = yyDollar[1].v
			yyVAL.v = yyDollar[3].v
		}
	case 39:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:138
		{
			yylex.Error("Map literal must contain an even number of forms")
		}
	case 40:
		yyDollar = yyS[yypt-1 : yypt+1]
		//line parser.y:142
		{
			yyVAL.v = types.Map{}
		}
	case 41:
		yyDollar = yyS[yypt-3 : yypt+1]
		//line parser.y:144
		{
			yyDollar[1].v.(types.Map)[yyDollar[2].k] = yyDollar[2].v
		}
	case 42:
		yyDollar = yyS[yypt-3 : yypt+1]
		//line parser.y:150
		{
			yyVAL = yyDollar[2]
		}
	case 43:
		yyDollar = yyS[yypt-3 : yypt+1]
		//line parser.y:154
		{
			yyVAL = yyDollar[2]
		}
	case 44:
		yyDollar = yyS[yypt-3 : yypt+1]
		//line parser.y:159
		{
			vec := types.Sequence(types.Vector{})
			values := types.Sequence(yyDollar[2].v.(*types.List))
			yyVAL.v = vec.Into(values)
		}
	}
	goto yystack /* stack new state and value */
}
Example #5
0
// The command module takes as input a map, and runs that command.
//
// Parameters in the input map are:
//   :command, a list or vector, giving the command to run. Required.
//   :env, a map of names to values; if specified, these are added to the environment when running the command; optional
//   :input, a string to pass to the command's stdin; optional
func (this Command) Exec(input types.Value) (output types.Value, err error) {
	var command []string
	var commandMap types.Map
	if m, ok := input.(types.Map); ok {
		commandMap = m
	} else {
		err = errors.New("input must be a map")
		return
	}

	var commandEntry = commandMap[types.Keyword("command")]
	if commandEntry == nil {
		err = errors.New("require at least :command in input")
		return
	} else if l, ok := commandEntry.(*types.List); ok {
		var list = (*list.List)(l)
		command = make([]string, list.Len())
		var i = 0
		for e := list.Front(); e != nil; e = e.Next() {
			if elem, ok := e.Value.(types.String); ok {
				command[i] = string(elem)
				i++
			} else {
				err = errors.New(":command must be a list of strings")
				return
			}
		}
	} else if v, ok := commandEntry.(types.Vector); ok {
		var vect = ([]types.Value)(v)
		command = make([]string, len(vect))
		for i, e := range vect {
			if elem, ok := e.(types.String); ok {
				command[i] = string(elem)
			} else {
				err = errors.New(":command must be a vector of strings")
				return
			}
		}
	} else {
		err = errors.New("expected a list or vector as :command")
		return
	}
	var cmd = exec.Command(command[0], command[1:]...)

	var envEntry = commandMap[types.Keyword("env")]
	if envEntry != nil {
		if e, ok := envEntry.(types.Map); ok {
			var env = make([]string, len(e))
			var i = 0
			for k := range e {
				v := e[k]
				if kk, ok := k.(types.String); ok && len(kk) > 0 {
					if vv, ok := v.(types.String); ok && len(vv) > 0 {
						env[i] = fmt.Sprint(string(kk), "=", string(vv))
					} else {
						err = errors.New(":env values must be nonempty strings")
						return
					}
				} else {
					err = errors.New(":env keys must be nonempty strings")
					return
				}
				i++
			}
			cmd.Env = env
		} else {
			err = errors.New(":env must be a map if specified")
			return
		}
	}

	var stdinEntry = commandMap[types.Keyword("input")]
	if stdinEntry != nil {
		if stdin, ok := stdinEntry.(types.String); ok {
			cmd.Stdin = strings.NewReader(string(stdin))
		} else {
			err = errors.New(":input must be a string if specified")
			return
		}
	}

	var stderr = new(bytes.Buffer)
	var stdout = new(bytes.Buffer)
	cmd.Stderr = stderr
	cmd.Stdout = stdout
	err = cmd.Run()
	if err != nil {
		output = types.Map{
			types.Keyword("success"):     types.Bool(false),
			types.Keyword("err"):         types.String(stderr.String()),
			types.Keyword("out"):         types.String(stdout.String()),
			types.Keyword("system-time"): types.Float(cmd.ProcessState.SystemTime().Seconds()),
			types.Keyword("user-time"):   types.Float(cmd.ProcessState.UserTime().Seconds()),
		}
		return
	}

	output = types.Map{
		types.Keyword("success"):     types.Bool(true),
		types.Keyword("err"):         types.String(stderr.String()),
		types.Keyword("out"):         types.String(stdout.String()),
		types.Keyword("system-time"): types.Float(cmd.ProcessState.SystemTime().Seconds()),
		types.Keyword("user-time"):   types.Float(cmd.ProcessState.UserTime().Seconds()),
	}
	return
}
Example #6
0
func (this Shell) Exec(input types.Value) (output types.Value, err error) {
	var commandMap types.Map
	if m, ok := input.(types.Map); ok {
		commandMap = m
	} else {
		err = errors.New("input must be a map")
		return
	}

	var command string
	var commandEntry = commandMap[types.Keyword("command")]
	if commandEntry == nil {
		err = errors.New(":command argument is required")
		return
	} else if c, ok := commandEntry.(types.String); ok {
		command = string(c)
	} else {
		err = errors.New(":command must be a string")
		return
	}

	var shell = "/bin/sh"
	shellEntry := commandMap[types.Keyword("shell")]
	if shellEntry != nil {
		if s, ok := shellEntry.(types.String); ok {
			shell = string(s)
		} else {
			err = errors.New(":shell must be a string if specified")
			return
		}
	}

	cmd := exec.Command(shell, "-c", command)

	var envEntry = commandMap[types.Keyword("env")]
	if envEntry != nil {
		if e, ok := envEntry.(types.Map); ok {
			var env = make([]string, len(e))
			var i = 0
			for k := range e {
				v := e[k]
				if kk, ok := k.(types.String); ok && len(kk) > 0 {
					if vv, ok := v.(types.String); ok && len(vv) > 0 {
						env[i] = fmt.Sprint(string(kk), "=", string(vv))
					} else {
						err = errors.New(":env values must be nonempty strings")
						return
					}
				} else {
					err = errors.New(":env keys must be nonempty strings")
					return
				}
				i++
			}
			cmd.Env = env
		} else {
			err = errors.New(":env must be a map if specified")
			return
		}
	}

	inputEntry := commandMap[types.Keyword("input")]
	if inputEntry != nil {
		if i, ok := inputEntry.(types.String); ok {
			cmd.Stdin = strings.NewReader(string(i))
		} else {
			err = errors.New(":input must be a string if specified")
		}
	}

	var stderr = new(bytes.Buffer)
	var stdout = new(bytes.Buffer)
	cmd.Stderr = stderr
	cmd.Stdout = stdout
	err = cmd.Run()
	if err != nil {
		output = types.Map{
			types.Keyword("success"):     types.Bool(false),
			types.Keyword("err"):         types.String(stderr.String()),
			types.Keyword("out"):         types.String(stdout.String()),
			types.Keyword("system-time"): types.Float(cmd.ProcessState.SystemTime().Seconds()),
			types.Keyword("user-time"):   types.Float(cmd.ProcessState.UserTime().Seconds()),
		}
		return
	}

	output = types.Map{
		types.Keyword("success"):     types.Bool(true),
		types.Keyword("err"):         types.String(stderr.String()),
		types.Keyword("out"):         types.String(stdout.String()),
		types.Keyword("system-time"): types.Float(cmd.ProcessState.SystemTime().Seconds()),
		types.Keyword("user-time"):   types.Float(cmd.ProcessState.UserTime().Seconds()),
	}
	return
}
Example #7
0
// Lex runs the lexer. Always returns 0.
// When the -s option is given, this function is not generated;
// instead, the NN_FUN macro runs the lexer.
func (yylex *lexer) Lex(lval *yySymType) int {
OUTER0:
	for {
		switch yylex.next(0) {
		case 0:
			{
				return tWhitespace
			}
		case 1:
			{
				return tOpenBracket
			}
		case 2:
			{
				return tCloseBracket
			}
		case 3:
			{
				return tOpenBrace
			}
		case 4:
			{
				return tCloseBrace
			}
		case 5:
			{
				return tOpenParen
			}
		case 6:
			{
				return tCloseParen
			}
		case 7:
			{
				return tOctothorpe
			}
		case 8:
			{
				return tNil
			}
		case 9:
			{
				lval.v = types.Bool(true)
				return tTrue
			}
		case 10:
			{
				lval.v = types.Bool(false)
				return tFalse
			}
		case 11:
			{
				lval.v = types.Character('\n')
				return tCharacter
			}
		case 12:
			{
				lval.v = types.Character('\r')
				return tCharacter
			}
		case 13:
			{
				lval.v = types.Character('\t')
				return tCharacter
			}
		case 14:
			{
				lval.v = types.Character(' ')
				return tCharacter
			}
		case 15:
			{
				panic("Unicode characters are currently unimplemented")
			}
		case 16:
			{
				s := yylex.Text()[1:]
				ch, _, _ := strings.NewReader(s).ReadRune()
				lval.v = types.Character(ch)
				return tCharacter
			}
		case 17:
			{
				lval.v = types.Keyword(yylex.Text()[1:])
				return tKeyword
			}
		case 18:
			{
				s := yylex.Text()
				lval.v = types.String(s[1 : len(s)-1])
				return tString
			}
		case 19:
			{
				lval.v = types.Symbol(yylex.Text())
				return tSymbol
			}
		case 20:
			{
				lval.v = types.ParseBigInt(yylex.Text())
				return tBigInteger
			}
		case 21:
			{
				lval.v = types.ParseFloat(yylex.Text())
				return tFloat
			}
		case 22:
			{
				lval.v = types.ParseInt(yylex.Text())
				return tInteger
			}
		case 23:
			{
				lval.v = types.ParseFloat(yylex.Text())
				return tFloat
			}
		case 24:
			{
				lval.v = types.ParseFloat(yylex.Text())
				return tFloat
			}
		case 25:
			{
				lval.v = types.ParseFloat(yylex.Text())
				return tFloat
			}
		case 26:
			{
				lval.v = types.ParseRational(yylex.Text())
				return tRational
			}
		case 27:
			{ // (This rule must be last)
				// Unmatched token...
				return -1
			}
		default:
			break OUTER0
		}
		continue
	}
	yylex.pop()

	return 0
}