示例#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)
	}
}
示例#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
}
示例#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
}
示例#4
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
}
示例#5
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
}
示例#6
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
}