<commit_before>// +build !windows

package transport

import (
	"fmt"
	"os"
	"os/exec"

	"github.com/scrapli/scrapligo/logging"

	"github.com/creack/pty"
)

// System the "system" (pty subprocess wrapper) transport option for scrapligo.
type System struct {
	BaseTransportArgs   *BaseTransportArgs
	SystemTransportArgs *SystemTransportArgs
	fileObj             *os.File
	openCmd             []string
}

// SystemTransportArgs struct representing attributes required for the System transport.
type SystemTransportArgs struct {
	AuthPrivateKey    string
	AuthStrictKey     bool
	SSHConfigFile     string
	SSHKnownHostsFile string
}

func (t *System) buildOpenCmd() {
	// base ssh arguments; "ssh" itself passed in Open()
	// need to add user arguments could go here at some point
	t.openCmd = append(
		t.openCmd,
		t.BaseTransportArgs.Host,
		"-p",
		fmt.Sprintf("%d", t.BaseTransportArgs.Port),
		"-o",
		fmt.Sprintf("ConnectTimeout=%d", int(t.BaseTransportArgs.TimeoutSocket.Seconds())),
		"-o",
		fmt.Sprintf("ServerAliveInterval=%d", int(t.BaseTransportArgs.TimeoutTransport.Seconds())),
	)

	if t.SystemTransportArgs.AuthPrivateKey != "" {
		t.openCmd = append(
			t.openCmd,
			"-i",
			t.SystemTransportArgs.AuthPrivateKey,
		)
	}

	if t.BaseTransportArgs.AuthUsername != "" {
		t.openCmd = append(
			t.openCmd,
			"-l",
			t.BaseTransportArgs.AuthUsername,
		)
	}

	if !t.SystemTransportArgs.AuthStrictKey {
		t.openCmd = append(
			t.openCmd,
			"-o",
			"StrictHostKeyChecking=no",
			"-o",
			"UserKnownHostsFile=/dev/null",
		)
	} else {
		t.openCmd = append(
			t.openCmd,
			"-o",
			"StrictHostKeyChecking=yes",
		)

		if t.SystemTransportArgs.SSHKnownHostsFile != "" {
			t.openCmd = append(
				t.openCmd,
				"-o",
				fmt.Sprintf("UserKnownHostsFile=%s", t.SystemTransportArgs.SSHKnownHostsFile),
			)
		}
	}

	if t.SystemTransportArgs.SSHConfigFile != "" {
		t.openCmd = append(
			t.openCmd,
			"-F",
			t.SystemTransportArgs.SSHConfigFile,
		)
	} else {
		t.openCmd = append(
			t.openCmd,
			"-F",
			"/dev/null",
		)
	}
}

// Open open a standard ssh connection.
func (t *System) Open() error {
	t.buildOpenCmd()

	logging.LogDebug(
		t.FormatLogMessage(
			"debug",
			fmt.Sprintf(
				"\"attempting to open transport connection with the following command: %s",
				t.openCmd,
			),
		),
	)

	sshCommand := exec.Command("ssh", t.openCmd...)
	fileObj, err := pty.StartWithSize(
		sshCommand,
		&pty.Winsize{
			Rows: uint16(t.BaseTransportArgs.PtyHeight),
			Cols: uint16(t.BaseTransportArgs.PtyWidth),
		},
	)

	if err != nil {
		logging.LogError(t.FormatLogMessage("error", "failed opening transport connection to host"))

		return err
	}

	logging.LogDebug(t.FormatLogMessage("debug", "transport connection to host opened"))

	t.fileObj = fileObj

	return err
}

// OpenNetconf open a netconf connection.
func (t *System) OpenNetconf() error {
	t.buildOpenCmd()

	t.openCmd = append(t.openCmd,
		"-tt",
		"-s",
		"netconf",
	)

	logging.LogDebug(
		t.FormatLogMessage(
			"debug",
			fmt.Sprintf(
				"\"attempting to open netconf transport connection with the following command: %s",
				t.openCmd,
			),
		),
	)

	sshCommand := exec.Command("ssh", t.openCmd...)
	fileObj, err := pty.Start(sshCommand)

	if err != nil {
		logging.LogError(
			t.FormatLogMessage("error", "failed opening netconf transport connection to host"),
		)

		return err
	}

	logging.LogDebug(t.FormatLogMessage("debug", "netconf transport connection to host opened"))

	t.fileObj = fileObj

	return err
}

// Close close the transport connection to the device.
func (t *System) Close() error {
	err := t.fileObj.Close()
	t.fileObj = nil
	logging.LogDebug(t.FormatLogMessage("debug", "transport connection to host closed"))
<commit_msg>playing w/ docker exec w/ system transport<commit_after>// +build !windows

package transport

import (
	"fmt"
	"os"
	"os/exec"

	"github.com/scrapli/scrapligo/logging"

	"github.com/creack/pty"
)

// System the "system" (pty subprocess wrapper) transport option for scrapligo.
type System struct {
	BaseTransportArgs   *BaseTransportArgs
	SystemTransportArgs *SystemTransportArgs
	fileObj             *os.File
	OpenCmd             []string
	ExecCmd             string
}

// SystemTransportArgs struct representing attributes required for the System transport.
type SystemTransportArgs struct {
	AuthPrivateKey    string
	AuthStrictKey     bool
	SSHConfigFile     string
	SSHKnownHostsFile string
}

func (t *System) buildOpenCmd() {
	// base ssh arguments; "ssh" itself passed in Open()
	// need to add user arguments could go here at some point
	t.OpenCmd = append(
		t.OpenCmd,
		t.BaseTransportArgs.Host,
		"-p",
		fmt.Sprintf("%d", t.BaseTransportArgs.Port),
		"-o",
		fmt.Sprintf("ConnectTimeout=%d", int(t.BaseTransportArgs.TimeoutSocket.Seconds())),
		"-o",
		fmt.Sprintf("ServerAliveInterval=%d", int(t.BaseTransportArgs.TimeoutTransport.Seconds())),
	)

	if t.SystemTransportArgs.AuthPrivateKey != "" {
		t.OpenCmd = append(
			t.OpenCmd,
			"-i",
			t.SystemTransportArgs.AuthPrivateKey,
		)
	}

	if t.BaseTransportArgs.AuthUsername != "" {
		t.OpenCmd = append(
			t.OpenCmd,
			"-l",
			t.BaseTransportArgs.AuthUsername,
		)
	}

	if !t.SystemTransportArgs.AuthStrictKey {
		t.OpenCmd = append(
			t.OpenCmd,
			"-o",
			"StrictHostKeyChecking=no",
			"-o",
			"UserKnownHostsFile=/dev/null",
		)
	} else {
		t.OpenCmd = append(
			t.OpenCmd,
			"-o",
			"StrictHostKeyChecking=yes",
		)

		if t.SystemTransportArgs.SSHKnownHostsFile != "" {
			t.OpenCmd = append(
				t.OpenCmd,
				"-o",
				fmt.Sprintf("UserKnownHostsFile=%s", t.SystemTransportArgs.SSHKnownHostsFile),
			)
		}
	}

	if t.SystemTransportArgs.SSHConfigFile != "" {
		t.OpenCmd = append(
			t.OpenCmd,
			"-F",
			t.SystemTransportArgs.SSHConfigFile,
		)
	} else {
		t.OpenCmd = append(
			t.OpenCmd,
			"-F",
			"/dev/null",
		)
	}
}

// Open open a standard ssh connection.
func (t *System) Open() error {
	if t.OpenCmd == nil {
		t.buildOpenCmd()
	}

	if t.ExecCmd == "" {
		t.ExecCmd = "ssh"
	}

	logging.LogDebug(
		t.FormatLogMessage(
			"debug",
			fmt.Sprintf(
				"\"attempting to open transport connection with the following command: %s",
				t.OpenCmd,
			),
		),
	)

	sshCommand := exec.Command(t.ExecCmd, t.OpenCmd...)
	fileObj, err := pty.StartWithSize(
		sshCommand,
		&pty.Winsize{
			Rows: uint16(t.BaseTransportArgs.PtyHeight),
			Cols: uint16(t.BaseTransportArgs.PtyWidth),
		},
	)

	if err != nil {
		logging.LogError(t.FormatLogMessage("error", "failed opening transport connection to host"))

		return err
	}

	logging.LogDebug(t.FormatLogMessage("debug", "transport connection to host opened"))

	t.fileObj = fileObj

	return err
}

// OpenNetconf open a netconf connection.
func (t *System) OpenNetconf() error {
	t.buildOpenCmd()

	t.OpenCmd = append(t.OpenCmd,
		"-tt",
		"-s",
		"netconf",
	)

	logging.LogDebug(
		t.FormatLogMessage(
			"debug",
			fmt.Sprintf(
				"\"attempting to open netconf transport connection with the following command: %s",
				t.OpenCmd,
			),
		),
	)

	sshCommand := exec.Command("ssh", t.OpenCmd...)
	fileObj, err := pty.Start(sshCommand)

	if err != nil {
		logging.LogError(
			t.FormatLogMessage("error", "failed opening netconf transport connection to host"),
		)

		return err
	}

	logging.LogDebug(t.FormatLogMessage("debug", "netconf transport connection to host opened"))

	t.fileObj = fileObj

	return err
}

// Close close the transport connection to the device.
func (t *System) Close() error {
	err := t.fileObj.Close()
	t.fileObj = nil
	logging.LogDebug(t.FormatLogMessage("debug", "transport connection to host closed"))

{'fraction_non_alphanumeric': 0.135742444152431, 'fraction_numerical': 0.0010512483574244415, 'mean_word_length': 3.479693937610359, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4850971', 'n_tokens_mistral': 2975, 'n_tokens_neox': 2627, 'n_words': 585}