Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/profiles2' into v24docs
Browse files Browse the repository at this point in the history
  • Loading branch information
gcla committed Jul 3, 2022
2 parents 4621aae + a96779e commit 006bca5
Show file tree
Hide file tree
Showing 23 changed files with 1,812 additions and 349 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
### Changed

- Now you can build and install termshark with one command: `go install github.com/gcla/termshark/v2/cmd/termshark`
- Dark-mode is now the default in the absence of a specific user-setting.
- Fixed a bug that caused mouse-clicks within the hex view to not function correctly if the viewport was not
at the top of the data to be displayed.
- When focus is in the packet hex view, the mouse wheel will no longer move the cursor - instead it will move
Expand Down
4 changes: 3 additions & 1 deletion cli/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import "github.com/jessevdk/go-flags"
// Used to determine if we should run tshark instead e.g. stdout is not a tty
type Tshark struct {
PassThru string `long:"pass-thru" default:"auto" optional:"true" optional-value:"true" choice:"yes" choice:"no" choice:"auto" choice:"true" choice:"false" description:"Run tshark instead (auto => if stdout is not a tty)."`
Profile string `long:"profile" short:"C" description:"Start with this configuration profile." value-name:"<profile>"`
PrintIfaces bool `short:"D" optional:"true" optional-value:"true" description:"Print a list of the interfaces on which termshark can capture."`
TailSwitch
}
Expand All @@ -27,6 +28,7 @@ type Termshark struct {
CaptureFilter string `short:"f" description:"Apply capture filter." value-name:"<capture filter>"`
TimestampFormat string `short:"t" description:"Set the format of the packet timestamp printed in summary lines." choice:"a" choice:"ad" choice:"adoy" choice:"d" choice:"dd" choice:"e" choice:"r" choice:"u" choice:"ud" choice:"udoy" value-name:"<timestamp format>"`
PlatformSwitches
Profile string `long:"profile" short:"C" description:"Start with this configuration profile." value-name:"<profile>"`
PassThru string `long:"pass-thru" default:"auto" optional:"true" optional-value:"true" choice:"auto" choice:"true" choice:"false" description:"Run tshark instead (auto => if stdout is not a tty)."`
LogTty bool `long:"log-tty" optional:"true" optional-value:"true" choice:"true" choice:"false" description:"Log to the terminal."`
Debug TriState `long:"debug" default:"unset" hidden:"true" optional:"true" optional-value:"true" description:"Enable termshark debugging. See https://termshark.io/userguide."`
Expand All @@ -40,7 +42,7 @@ type Termshark struct {

// If args are passed through to tshark (e.g. stdout not a tty), then
// strip these out so tshark doesn't fail.
var TermsharkOnly = []string{"--pass-thru", "--log-tty", "--debug", "--tail"}
var TermsharkOnly = []string{"--pass-thru", "--profile", "--log-tty", "--debug", "--tail"}

func FlagIsTrue(val string) bool {
return val == "true" || val == "yes"
Expand Down
112 changes: 52 additions & 60 deletions cmd/termshark/termshark.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (
"github.com/gcla/termshark/v2"
"github.com/gcla/termshark/v2/capinfo"
"github.com/gcla/termshark/v2/cli"
"github.com/gcla/termshark/v2/configs/profiles"
"github.com/gcla/termshark/v2/convs"
"github.com/gcla/termshark/v2/pcap"
"github.com/gcla/termshark/v2/shark"
"github.com/gcla/termshark/v2/streams"
"github.com/gcla/termshark/v2/system"
"github.com/gcla/termshark/v2/theme"
"github.com/gcla/termshark/v2/tty"
"github.com/gcla/termshark/v2/ui"
"github.com/gcla/termshark/v2/widgets/filter"
Expand Down Expand Up @@ -133,8 +133,6 @@ func cmain() int {
// processes start running, they use the same tty line discipline.
system.RegisterForSignals(sigChan)

viper.SetConfigName("termshark") // no need to include file extension - looks for file called termshark.ini for example

stdConf := configdir.New("", "termshark")
dirs := stdConf.QueryFolders(configdir.Cache)
if err := dirs[0].CreateParentDir("dummy"); err != nil {
Expand All @@ -143,27 +141,15 @@ func cmain() int {
dirs = stdConf.QueryFolders(configdir.Global)
if err := dirs[0].CreateParentDir("dummy"); err != nil {
fmt.Fprintf(os.Stderr, "Warning: could not create config dir: %v\n", err)
}
viper.AddConfigPath(dirs[0].Path)

if f, err := os.OpenFile(filepath.Join(dirs[0].Path, "termshark.toml"), os.O_RDONLY|os.O_CREATE, 0666); err != nil {
fmt.Fprintf(os.Stderr, "Warning: could not create initial config file: %v\n", err)
} else {
f.Close()
if err = os.MkdirAll(filepath.Join(dirs[0].Path, "profiles"), 0755); err != nil {
fmt.Fprintf(os.Stderr, "Warning: could not create profiles dir: %v\n", err)
}
}

err := viper.ReadInConfig()
err := profiles.ReadDefaultConfig(dirs[0].Path)
if err != nil {
fmt.Println("Config file not found...")
}

if os.Getenv("TERMSHARK_CAPTURE_MODE") == "1" {
err = system.DumpcapExt(termshark.DumpcapBin(), termshark.TSharkBin(), os.Args[1:]...)
if err != nil {
return 1
} else {
return 0
}
fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", err.Error()))
}

// Used to determine if we should run tshark instead e.g. stdout is not a tty
Expand Down Expand Up @@ -201,6 +187,29 @@ func cmain() int {
}
}

// From here, the current profile is referenced. So load it up prior to first use. If the user
// provides a non-existent profile name, it should be an error, just as for Wireshark.
if tsopts.Profile != "" {
if err = profiles.Use(tsopts.Profile); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return 1
}
}

// If this variable is set, it's set by termshark internally, and termshark is guaranteed to
// construct a valid command-line invocation. So it doesn't matter if I do this after the CLI
// parsing logic because there's no risk of an error causing a short-circuit and this command
// not being run. The reason to do it after the CLI parsing logic is so that I have the correct
// config profile loaded, needed for the tshark command.
if os.Getenv("TERMSHARK_CAPTURE_MODE") == "1" {
err = system.DumpcapExt(termshark.DumpcapBin(), termshark.TSharkBin(), os.Args[1:]...)
if err != nil {
return 1
} else {
return 0
}
}

// Run after accessing the config so I can use the configured tshark binary, if there is one. I need that
// binary in the case that termshark is run where stdout is not a tty, in which case I exec tshark - but
// it makes sense to use the one in termshark.toml
Expand Down Expand Up @@ -311,7 +320,7 @@ func cmain() int {
// Allow the user to override the shell's TERM variable this way. Perhaps the user runs
// under screen/tmux, and the TERM variable doesn't reflect the fact their preferred
// terminal emumlator supports 256 colors.
termVar := termshark.ConfString("main.term", "")
termVar := profiles.ConfString("main.term", "")
if termVar != "" {
fmt.Fprintf(os.Stderr, "Configuration file overrides TERM setting, using TERM=%s\n", termVar)
os.Setenv("TERM", termVar)
Expand Down Expand Up @@ -532,7 +541,7 @@ func cmain() int {
}

debug := false
if (opts.Debug.Set && opts.Debug.Val == true) || (!opts.Debug.Set && termshark.ConfBool("main.debug", false)) {
if (opts.Debug.Set && opts.Debug.Val == true) || (!opts.Debug.Set && profiles.ConfBool("main.debug", false)) {
debug = true
}

Expand Down Expand Up @@ -574,7 +583,7 @@ func cmain() int {
// Here, tsharkBin is a fully-qualified tshark binary that exists on the fs (absent race
// conditions...)

valids := termshark.ConfStrings("main.validated-tsharks")
valids := profiles.ConfStrings("main.validated-tsharks")

if !termshark.StringInSlice(tsharkBin, valids) {
tver, err := termshark.TSharkVersion(tsharkBin)
Expand All @@ -591,32 +600,32 @@ func cmain() int {
}

valids = append(valids, tsharkBin)
termshark.SetConf("main.validated-tsharks", valids)
profiles.SetConf("main.validated-tsharks", valids)
}

// If the last tshark we used isn't the same as the current one, then remove the cached fields
// data structure so it can be regenerated.
if tsharkBin != termshark.ConfString("main.last-used-tshark", "") {
if tsharkBin != profiles.ConfString("main.last-used-tshark", "") {
termshark.DeleteCachedFields()
}

// Write out the last-used tshark path. We do this to make the above fields cache be consistent
// with the tshark binary we're using.
termshark.SetConf("main.last-used-tshark", tsharkBin)
profiles.SetConf("main.last-used-tshark", tsharkBin)

// Determine if the current binary supports color. Tshark will fail with an error if it's too old
// and you supply the --color flag. Assume true, and check if our current binary is not in the
// validate list.
ui.PacketColorsSupported = true
colorTsharks := termshark.ConfStrings("main.color-tsharks")
colorTsharks := profiles.ConfStrings("main.color-tsharks")

if !termshark.StringInSlice(tsharkBin, colorTsharks) {
ui.PacketColorsSupported, err = termshark.TSharkSupportsColor(tsharkBin)
if err != nil {
ui.PacketColorsSupported = false
} else {
colorTsharks = append(colorTsharks, tsharkBin)
termshark.SetConf("main.color-tsharks", colorTsharks)
profiles.SetConf("main.color-tsharks", colorTsharks)
}
}

Expand Down Expand Up @@ -731,24 +740,24 @@ func cmain() int {
}()

// Initialize application state for dark mode and auto-scroll
ui.DarkMode = termshark.ConfBool("main.dark-mode", false)
ui.AutoScroll = termshark.ConfBool("main.auto-scroll", true)
ui.PacketColors = termshark.ConfBool("main.packet-colors", true)
ui.DarkMode = profiles.ConfBool("main.dark-mode", true)
ui.AutoScroll = profiles.ConfBool("main.auto-scroll", true)
ui.PacketColors = profiles.ConfBool("main.packet-colors", true)

// Set them up here so they have access to any command-line flags that
// need to be passed to the tshark commands used
pdmlArgs := termshark.ConfStringSlice("main.pdml-args", []string{})
psmlArgs := termshark.ConfStringSlice("main.psml-args", []string{})
pdmlArgs := profiles.ConfStringSlice("main.pdml-args", []string{})
psmlArgs := profiles.ConfStringSlice("main.psml-args", []string{})
if opts.TimestampFormat != "" {
psmlArgs = append(psmlArgs, "-t", opts.TimestampFormat)
}
tsharkArgs := termshark.ConfStringSlice("main.tshark-args", []string{})
tsharkArgs := profiles.ConfStringSlice("main.tshark-args", []string{})
if ui.PacketColors && !ui.PacketColorsSupported {
log.Warnf("Packet coloring is enabled, but %s does not support --color", tsharkBin)
ui.PacketColors = false
}
cacheSize := termshark.ConfInt("main.pcap-cache-size", 64)
bundleSize := termshark.ConfInt("main.pcap-bundle-size", 1000)
cacheSize := profiles.ConfInt("main.pcap-cache-size", 64)
bundleSize := profiles.ConfInt("main.pcap-bundle-size", 1000)
if bundleSize <= 0 {
maxBundleSize := 100000
log.Infof("Config specifies pcap-bundle-size as %d - setting to max (%d)", bundleSize, maxBundleSize)
Expand Down Expand Up @@ -794,8 +803,8 @@ func cmain() int {
// 0-21 are set up normally, and not remapped. If the closest match is one of those
// colors, then the theme won't look as expected. A workaround is to tell
// gowid not to use colors 0-21 when finding the closest match.
if termshark.ConfKeyExists("main.ignore-base16-colors") {
gowid.IgnoreBase16 = termshark.ConfBool("main.ignore-base16-colors", false)
if profiles.ConfKeyExists("main.ignore-base16-colors") {
gowid.IgnoreBase16 = profiles.ConfBool("main.ignore-base16-colors", false)
} else {
// Try to auto-detect whether or not base16-shell is installed and in-use
gowid.IgnoreBase16 = (os.Getenv("BASE16_SHELL") != "")
Expand All @@ -809,7 +818,7 @@ func cmain() int {
// just an implementation snafu, or if something else is going on... In any case,
// termshark will fall back to 256-colors if base16 is detected because I can
// programmatically avoid choosing colors 0-21 for anything termshark needs.
if os.Getenv("COLORTERM") != "" && !termshark.ConfBool("main.respect-colorterm", false) {
if os.Getenv("COLORTERM") != "" && !profiles.ConfBool("main.respect-colorterm", false) {
log.Infof("Pessimistically disabling 24-bit color to avoid conflicts with base16")
os.Unsetenv("COLORTERM")
}
Expand Down Expand Up @@ -1128,7 +1137,7 @@ Loop:
case <-checkPcapCacheChan:
// Only check the cache dir if we own it; don't want to delete pcap files
// that might be shared with wireshark
if termshark.ConfBool("main.use-tshark-temp-for-pcap-cache", false) {
if profiles.ConfBool("main.use-tshark-temp-for-pcap-cache", false) {
log.Infof("Termshark does not own the pcap temp dir %s; skipping size check", termshark.PcapDir())
} else {
termshark.PrunePcapCache()
Expand Down Expand Up @@ -1157,24 +1166,7 @@ Loop:
// Need to do that here because the app won't know how many colors the screen
// has (and therefore which variant of the theme to load) until the screen is
// activated.
mode := app.GetColorMode()
modeStr := theme.Mode(mode) // more concise
themeName := termshark.ConfString(fmt.Sprintf("main.theme-%s", modeStr), "default")
loaded := false
if themeName != "" {
err = theme.Load(themeName, app)
if err != nil {
log.Warnf("Theme %s could not be loaded: %v", themeName, err)
} else {
loaded = true
}
}
if !loaded && themeName != "default" {
err = theme.Load("default", app)
if err != nil {
log.Warnf("Theme %s could not be loaded: %v", themeName, err)
}
}
ui.ApplyCurrentTheme(app)

// This needs to run after the toml config file is loaded.
ui.SetupColors()
Expand All @@ -1193,11 +1185,11 @@ Loop:
ui.StartUIChan = nil // make sure it's not triggered again

if runtime.GOOS != "windows" {
if mode == gowid.Mode8Colors {
if app.GetColorMode() == gowid.Mode8Colors {
// If exists is true, it means we already tried and then reverted back, so
// just load up termshark normally with no further interruption.
if _, exists := os.LookupEnv("TERMSHARK_ORIGINAL_TERM"); !exists {
if !termshark.ConfBool("main.disable-term-helper", false) {
if !profiles.ConfBool("main.disable-term-helper", false) {
err = termshark.Does256ColorTermExist()
if err != nil {
log.Infof("Must use 8-color mode because 256-color version of TERM=%s unavailable - %v.", os.Getenv("TERM"), err)
Expand Down
Loading

0 comments on commit 006bca5

Please sign in to comment.