From fb6bb3a8ab54e1bfd1f7a953d1f5f1f272a889f8 Mon Sep 17 00:00:00 2001 From: Simon Let Date: Thu, 23 May 2019 02:02:13 +0200 Subject: [PATCH] macOS and zsh compatibility, sessionId --- Makefile | 11 ++-- collect/resh-collect.go | 33 +++++----- common/resh-common.go | 14 +++-- shellrc.sh | 134 ++++++++++++++++++++++++++++------------ 4 files changed, 125 insertions(+), 67 deletions(-) diff --git a/Makefile b/Makefile index 3bbc6db..9119cac 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,11 @@ build: submodules resh-collect resh-daemon install: build | $(HOME)/.resh $(HOME)/.resh/bin $(HOME)/.config $(HOME)/.resh/resh-uuid - cp submodules/bash-preexec/bash-preexec.sh ~/.bash-preexec.sh -f - cp config.toml ~/.config/resh.toml -f - cp shellrc.sh ~/.resh/shellrc -f - cp resh-* ~/.resh/bin/ -f + cp -f submodules/bash-preexec/bash-preexec.sh ~/.bash-preexec.sh + cp -f config.toml ~/.config/resh.toml + cp -f shellrc.sh ~/.resh/shellrc + cp -f uuid.sh ~/.resh/bin/resh-uuid + cp -f resh-* ~/.resh/bin/ [ ! -f ~/resh-history.json ] || mv ~/resh-history.json ~/.resh/history.json grep '[[ -f ~/.resh/shellrc ]] && source ~/.resh/shellrc' ~/.bashrc ||\ echo '[[ -f ~/.resh/shellrc ]] && source ~/.resh/shellrc' >> ~/.bashrc @@ -34,7 +35,7 @@ $(HOME)/.resh $(HOME)/.resh/bin $(HOME)/.config: mkdir -p $@ $(HOME)/.resh/resh-uuid: - cat /proc/sys/kernel/random/uuid > $@ + cat /proc/sys/kernel/random/uuid > $@ 2>/dev/null || ./uuid.sh .PHONY: submodules build install diff --git a/collect/resh-collect.go b/collect/resh-collect.go index 920dde2..24ce8f6 100644 --- a/collect/resh-collect.go +++ b/collect/resh-collect.go @@ -33,11 +33,12 @@ func main() { cmdLine := flag.String("cmdLine", "", "command line") exitCode := flag.Int("exitCode", -1, "exit code") shell := flag.String("shell", "", "actual shell") + uname := flag.String("uname", "", "uname") + sessionId := flag.String("sessionId", "", "resh generated session id") // posix variables - cols := flag.Int("cols", -1, "$COLUMNS") - lines := flag.Int("lines", -1, "$LINES") - + cols := flag.String("cols", "-1", "$COLUMNS") + lines := flag.String("lines", "-1", "$LINES") home := flag.String("home", "", "$HOME") lang := flag.String("lang", "", "$LANG") lcAll := flag.String("lcAll", "", "$LC_ALL") @@ -50,9 +51,7 @@ func main() { // non-posix pid := flag.Int("pid", -1, "$PID") - shellPid := flag.Int("shellPid", -1, - "$$ (pid but subshells don't affect it)") - windowId := flag.Int("windowId", -1, "$WINDOWID - session id") + sessionPid := flag.Int("sessionPid", -1, "$$ at session start") shlvl := flag.Int("shlvl", -1, "$SHLVL") host := flag.String("host", "", "$HOSTNAME") @@ -138,9 +137,11 @@ func main() { rec := common.Record{ // core - CmdLine: *cmdLine, - ExitCode: *exitCode, - Shell: *shell, + CmdLine: *cmdLine, + ExitCode: *exitCode, + Shell: *shell, + Uname: *uname, + SessionId: *sessionId, // posix Cols: *cols, @@ -160,8 +161,7 @@ func main() { RealPwd: realPwd, RealPwdAfter: realPwdAfter, Pid: *pid, - ShellPid: *shellPid, - WindowId: *windowId, + SessionPid: *sessionPid, Host: *host, Hosttype: *hosttype, Ostype: *ostype, @@ -219,7 +219,8 @@ func sendRecord(r common.Record, port string) { func readFileContent(path string) string { dat, err := ioutil.ReadFile(path) if err != nil { - log.Fatal("failed to open " + path) + return "" + //log.Fatal("failed to open " + path) } return strings.TrimSuffix(string(dat), "\n") } @@ -238,13 +239,15 @@ func getGitDirs(cdup string, exitCode int, pwd string) (string, string) { } func getTimezoneOffsetInSeconds(zone string) float64 { - hours_mins := strings.Split(zone, ":") - hours, err := strconv.Atoi(hours_mins[0]) + // date +%z -> "+0200" + hours_str := zone[:3] + mins_str := zone[3:] + hours, err := strconv.Atoi(hours_str) if err != nil { log.Println("err while parsing hours in timezone offset:", err) return -1 } - mins, err := strconv.Atoi(hours_mins[1]) + mins, err := strconv.Atoi(mins_str) if err != nil { log.Println("err while parsing mins in timezone offset:", err) return -1 diff --git a/common/resh-common.go b/common/resh-common.go index a9ba1a9..32d701f 100644 --- a/common/resh-common.go +++ b/common/resh-common.go @@ -2,13 +2,15 @@ package common type Record struct { // core - CmdLine string `json:"cmdLine"` - ExitCode int `json:"exitCode"` - Shell string `json:"shell"` + CmdLine string `json:"cmdLine"` + ExitCode int `json:"exitCode"` + Shell string `json:"shell"` + Uname string `json:"uname"` + SessionId string `json:"sessionId"` // posix - Cols int `json:"cols"` - Lines int `json:"lines"` + Cols string `json:"cols"` + Lines string `json:"lines"` Home string `json:"home"` Lang string `json:"lang"` LcAll string `json:"lcAll"` @@ -23,7 +25,7 @@ type Record struct { RealPwd string `json:"realPwd"` RealPwdAfter string `json:"realPwdAfter"` Pid int `json:"pid"` - ShellPid int `json:"shellPid"` + SessionPid int `json:"sessionPid"` WindowId int `json:"windowId"` Host string `json:"host"` Hosttype string `json:"hosttype"` diff --git a/shellrc.sh b/shellrc.sh index eca16ab..75be7c1 100644 --- a/shellrc.sh +++ b/shellrc.sh @@ -4,24 +4,92 @@ PATH=$PATH:~/.resh/bin # zmodload zsh/datetime # fi -# export __RESH_RT_SESSION=$EPOCHREALTIME -export __RESH_RT_SESSION=$(date +%s.%N) -export __RESH_RT_SESS_SINCE_BOOT=$(cat /proc/uptime | cut -d' ' -f1) -export __RESH_SESSION_ID=$(cat /proc/sys/kernel/random/uuid) - -if [ $(uname) == "Darvin" ]; then - export __RESH_OS_RELEASE_ID="macos" - export __RESH_OS_RELEASE_VERSION_ID=$(sw_vers -productVersion 2>/dev/null) - export __RESH_OS_RELEASE_NAME="macOS" - export __RESH_OS_RELEASE_PRETTY_NAME="Mac OS X" +get_uuid() { + cat /proc/sys/kernel/random/uuid 2>/dev/null || resh-uuid +} + +get_epochrealtime() { + if date +%s.%N | grep -vq 'N'; then + # GNU date + date +%s.%N + elif gdate --version >/dev/null && gdate +%s.%N | grep -vq 'N'; then + # GNU date take 2 + gdate +%s.%N + elif [ -n "$ZSH_VERSION" ]; then + # zsh fallback using $EPOCHREALTIME + if [ -z "${__RESH_ZSH_LOADED_DATETIME+x}" ]; then + zmodload zsh/datetime + __RESH_ZSH_LOADED_DATETIME=1 + fi + echo $EPOCHREALTIME + else + # dumb date + # XXX: we lost precison beyond seconds + date +%s + if [ -z "${__RESH_DATE_WARN+x}" ]; then + echo "resh WARN: can't get precise time - consider installing GNU date!" + __RESH_DATE_WARN=1 + fi + fi +} + +__RESH_MACOS=0 +__RESH_LINUX=0 +__RESH_UNAME=$(uname) + +if [ $__RESH_UNAME = "Darwin" ]; then + __RESH_MACOS=1 +elif [ $__RESH_UNAME = "Linux" ]; then + __RESH_LINUX=1 +else + echo "resh PANIC unrecognized OS" +fi + +if [ -n "$ZSH_VERSION" ]; then + __RESH_SHELL="zsh" + __RESH_HOST="$HOST" + __RESH_HOSTTYPE="$CPUTYPE" +elif [ -n "$BASH_VERSION" ]; then + __RESH_SHELL="bash" + __RESH_HOST="$HOSTNAME" + __RESH_HOSTTYPE="$HOSTTYPE" else - export __RESH_OS_RELEASE_ID=$(source /etc/os-release; echo $ID) - export __RESH_OS_RELEASE_VERSION_ID=$(source /etc/os-release; echo $VERSION_ID) - export __RESH_OS_RELEASE_ID_LIKE=$(source /etc/os-release; echo $ID_LIKE) - export __RESH_OS_RELEASE_NAME=$(source /etc/os-release; echo $NAME) - export __RESH_OS_RELEASE_PRETTY_NAME=$(source /etc/os-release; echo $PRETTY_NAME) + echo "resh PANIC unrecognized shell" +fi + +if [ -z "${__RESH_SESSION_ID+x}" ]; then + export __RESH_SESSION_ID=$(get_uuid) + export __RESH_SESSION_PID="$$" + # TODO add sesson time fi +# posix +__RESH_HOME="$HOME" +__RESH_LOGIN="$LOGNAME" +__RESH_SHELL_ENV="$SHELL" +__RESH_TERM="$TERM" + +# non-posix +__RESH_RT_SESSION=$(get_epochrealtime) +__RESH_OSTYPE="$OSTYPE" +__RESH_MACHTYPE="$MACHTYPE" + +if [ $__RESH_LINUX -eq 1 ]; then + __RESH_OS_RELEASE_ID=$(source /etc/os-release; echo $ID) + __RESH_OS_RELEASE_VERSION_ID=$(source /etc/os-release; echo $VERSION_ID) + __RESH_OS_RELEASE_ID_LIKE=$(source /etc/os-release; echo $ID_LIKE) + __RESH_OS_RELEASE_NAME=$(source /etc/os-release; echo $NAME) + __RESH_OS_RELEASE_PRETTY_NAME=$(source /etc/os-release; echo $PRETTY_NAME) + __RESH_RT_SESS_SINCE_BOOT=$(cat /proc/uptime | cut -d' ' -f1) +elif [ $__RESH_MACOS -eq 1 ]; then + __RESH_OS_RELEASE_ID="macos" + __RESH_OS_RELEASE_VERSION_ID=$(sw_vers -productVersion 2>/dev/null) + __RESH_OS_RELEASE_NAME="macOS" + __RESH_OS_RELEASE_PRETTY_NAME="Mac OS X" + __RESH_RT_SESS_SINCE_BOOT=$(sysctl -n kern.boottime | awk '{print $4}' | sed 's/,//g') +fi + + nohup resh-daemon &>/dev/null & disown __resh_preexec() { @@ -31,22 +99,14 @@ __resh_preexec() { # posix __RESH_COLS="$COLUMNS" - __RESH_HOME="$HOME" __RESH_LANG="$LANG" __RESH_LC_ALL="$LC_ALL" # other LC ? __RESH_LINES="$LINES" - __RESH_LOGIN="$LOGNAME" __RESH_PATH="$PATH" __RESH_PWD="$PWD" - __RESH_SHELL_ENV="$SHELL" - __RESH_TERM="$TERM" # non-posix - __RESH_SHELL_PID="$$" # pid (subshells don't affect it) - __RESH_WINDOWID="$WINDOWID" # session - __RESH_OSTYPE="$OSTYPE" - __RESH_MACHTYPE="$MACHTYPE" __RESH_SHLVL="$SHLVL" __RESH_GIT_CDUP="$(git rev-parse --show-cdup 2>/dev/null)" __RESH_GIT_CDUP_EXIT_CODE=$? @@ -57,24 +117,15 @@ __resh_preexec() { if [ -n "$ZSH_VERSION" ]; then # assume Zsh - __RESH_PID="$$" - __RESH_HOST="$HOST" - __RESH_HOSTTYPE="$CPUTYPE" - __RESH_SHELL="zsh" + __RESH_PID="$$" # current pid elif [ -n "$BASH_VERSION" ]; then # assume Bash __RESH_PID="$BASHPID" # current pid - __RESH_HOST="$HOSTNAME" - __RESH_HOSTTYPE="$HOSTTYPE" - __RESH_SHELL="bash" - else - # asume something else - echo "resh PANIC unrecognized shell" fi # time - __RESH_TZ_BEFORE=$(date +%:z) + __RESH_TZ_BEFORE=$(date +%z) # __RESH_RT_BEFORE="$EPOCHREALTIME" - __RESH_RT_BEFORE="$(date +%s.%N)" + __RESH_RT_BEFORE=$(get_epochrealtime) # TODO: we should evaluate symlinks in preexec # -> maybe create resh-precollect that could handle most of preexec @@ -88,13 +139,14 @@ __resh_preexec() { __resh_precmd() { __RESH_EXIT_CODE=$? - # __RESH_RT_AFTER=$EPOCHREALTIME - __RESH_RT_AFTER="$(date +%s.%N)" - __RESH_TZ_AFTER=$(date +%:z) + __RESH_RT_AFTER=$(get_epochrealtime) + __RESH_TZ_AFTER=$(date +%z) __RESH_PWD_AFTER="$PWD" - if [ ! -z ${__RESH_COLLECT+x} ]; then + if [ -n "${__RESH_COLLECT}" ]; then resh-collect -cmdLine "$__RESH_CMDLINE" -exitCode "$__RESH_EXIT_CODE" \ -shell "$__RESH_SHELL" \ + -uname "$__RESH_UNAME" \ + -sessionId "$__RESH_SESSION_ID" \ -cols "$__RESH_COLS" \ -home "$__RESH_HOME" \ -lang "$__RESH_LANG" \ @@ -106,8 +158,8 @@ __resh_precmd() { -pwdAfter "$__RESH_PWD_AFTER" \ -shellEnv "$__RESH_SHELL_ENV" \ -term "$__RESH_TERM" \ - -pid "$__RESH_PID" -shellPid "$__RESH_SHELL_PID" \ - -windowId "$__RESH_WINDOWID" \ + -pid "$__RESH_PID" \ + -sessionPid "$__RESH_SESSION_PID" \ -host "$__RESH_HOST" \ -hosttype "$__RESH_HOSTTYPE" \ -ostype "$__RESH_OSTYPE" \