github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/redirection.go (about)

     1  package lang
     2  
     3  import (
     4  	"crypto/md5"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/lmorg/murex/lang/types"
     9  )
    10  
    11  func parseRedirection(p *Process) {
    12  	//p.NamedPipeOut = "out"
    13  	//p.NamedPipeErr = "err"
    14  
    15  	for _, name := range p.namedPipes {
    16  		switch {
    17  		case len(name) > 5 && name[:5] == "test_":
    18  			if p.NamedPipeTest == "" {
    19  				testEnabled, err := p.Config.Get("test", "enabled", types.Boolean)
    20  				if err == nil && testEnabled.(bool) {
    21  					p.NamedPipeTest = name[5:]
    22  				}
    23  			} else {
    24  				pipeErr(p, "you specified test multiple times")
    25  			}
    26  
    27  		case len(name) > 6 && name[:6] == "state_":
    28  			if p.NamedPipeTest == "" {
    29  				testEnabled, err := p.Config.Get("test", "enabled", types.Boolean)
    30  				if err == nil && testEnabled.(bool) {
    31  					p.testState = append(p.testState, name[6:])
    32  				}
    33  			}
    34  
    35  		case len(name) > 4 && name[:4] == "env:":
    36  			p.Exec.Env = append(p.Exec.Env, name[4:])
    37  
    38  		case len(name) > 4 && name[:4] == "fid:":
    39  			varName := name[4:]
    40  			err := p.Variables.Set(p, varName, p.Id, types.Integer)
    41  			if err != nil {
    42  				ShellProcess.Stderr.Writeln([]byte(
    43  					fmt.Sprintf("Cannot write variable '%s': %s", varName, err.Error()),
    44  				))
    45  			}
    46  
    47  		case len(name) > 4 && name[:4] == "pid:":
    48  			varName := name[4:]
    49  			p.Exec.Callback = func(pid int) {
    50  				err := p.Variables.Set(p, varName, pid, types.Integer)
    51  				if err != nil {
    52  					ShellProcess.Stderr.Writeln([]byte(
    53  						fmt.Sprintf("Cannot write variable '%s': %s", varName, err.Error()),
    54  					))
    55  				}
    56  			}
    57  
    58  		case name[0] == '!':
    59  			if p.NamedPipeErr == "" {
    60  				p.NamedPipeErr = name[1:]
    61  			} else {
    62  				pipeErr(p, "you specified stderr multiple times")
    63  			}
    64  
    65  		case strings.Contains(name, ":"):
    66  			err := parseRedirectionTemp(p, name)
    67  			if err != nil {
    68  				pipeErr(p, err.Error())
    69  			}
    70  
    71  		default:
    72  			if p.NamedPipeOut == "" {
    73  				p.NamedPipeOut = name
    74  			} else {
    75  				pipeErr(p, "you specified stdout multiple times")
    76  			}
    77  		}
    78  	}
    79  }
    80  
    81  func parseRedirectionTemp(p *Process, namedPipe string) error {
    82  	split := strings.SplitN(namedPipe, ":", 2)
    83  	if len(split) != 2 {
    84  		return fmt.Errorf("invalid format used: '%s'", namedPipe)
    85  	}
    86  
    87  	name := fmt.Sprintf("tmp:%d/%.3x", p.Id, md5.Sum([]byte(namedPipe)))
    88  
    89  	err := GlobalPipes.CreatePipe(name, split[0], split[1])
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	p.NamedPipeOut = name
    95  
    96  	return nil
    97  }
    98  
    99  func pipeErr(p *Process, msg string) {
   100  	p.Stderr.Writeln([]byte("Invalid usage of named pipes: " + msg))
   101  }