summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2022-02-03 14:39:21 +0100
committerMarc Vertes <mvertes@free.fr>2022-02-03 14:39:21 +0100
commit70375b4962152133c0423115427d7eaa006822d6 (patch)
treed5608c6638f202ff17566fce60b5460da1d26304 /bin
parent053556962bb2d29ac76bcca51cabd1df238f80e3 (diff)
parente200c8d78ca1d3388c25c1cef8892b1dd015bbf7 (diff)
update
Diffstat (limited to 'bin')
-rwxr-xr-xbin/fv6
-rwxr-xr-xbin/gemini132
-rwxr-xr-xbin/icat2
-rwxr-xr-xbin/md136
-rwxr-xr-xbin/migrate_vimki58
-rwxr-xr-xbin/open11
-rwxr-xr-xbin/rdate11
-rwxr-xr-xbin/start_godoc3
-rwxr-xr-xbin/update_hosts26
-rwxr-xr-xbin/update_kernel_host8
-rwxr-xr-xbin/vimki56
-rwxr-xr-xbin/xt3
12 files changed, 440 insertions, 12 deletions
diff --git a/bin/fv b/bin/fv
new file mode 100755
index 0000000..5662ed3
--- /dev/null
+++ b/bin/fv
@@ -0,0 +1,6 @@
+#!/bin/sh
+# quick file viewer
+#exec fzf --multi --preview-window=right:66% --preview 'cat {1}'
+exec fzf --ansi --multi --preview-window=right:75% \
+ --bind=left:preview-page-up --bind=right:preview-page-down \
+ --preview 'cat {1}'
diff --git a/bin/gemini b/bin/gemini
new file mode 100755
index 0000000..1bc3d57
--- /dev/null
+++ b/bin/gemini
@@ -0,0 +1,132 @@
+#!/usr/bin/env yaegi
+package main
+
+import (
+ "bufio"
+ "crypto/tls"
+ "fmt"
+ "io/ioutil"
+ "net/url"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func main() {
+ stdinReader := bufio.NewReader(os.Stdin)
+ var u string // URL
+ links := make([]string, 0, 100)
+ history := make([]string, 0, 100)
+ for {
+ fmt.Print("> ")
+ cmd, _ := stdinReader.ReadString('\n')
+ cmd = strings.TrimSpace(cmd)
+ // Command dispatch
+ switch strings.ToLower(cmd) {
+ case "": // Nothing
+ continue
+ case "q": // Quit
+ fmt.Println("Bye!")
+ os.Exit(0)
+ case "b": // Back
+ if len(history) < 2 {
+ fmt.Println("No history yet!")
+ continue
+ }
+ u = history[len(history)-2]
+ history = history[0 : len(history)-2]
+ default:
+ index, err := strconv.Atoi(cmd)
+ if err != nil {
+ // Treat this as a URL
+ u = cmd
+ if !strings.HasPrefix(u, "gemini://") {
+ u = "gemini://" + u
+ }
+ } else {
+ // Treat this as a menu lookup
+ u = links[index-1]
+ }
+ }
+ // Parse URL
+ parsed, err := url.Parse(u)
+ if err != nil {
+ fmt.Println("Error parsing URL!")
+ continue
+ }
+ // Connect to server
+ conn, err := tls.Dial("tcp", parsed.Host+":1965", &tls.Config{InsecureSkipVerify: true})
+ if err != nil {
+ fmt.Println("Failed to connect: " + err.Error())
+ continue
+ }
+ defer conn.Close()
+ // Send request
+ conn.Write([]byte(u + "\r\n"))
+ // Receive and parse response header
+ reader := bufio.NewReader(conn)
+ responseHeader, err := reader.ReadString('\n')
+ parts := strings.Fields(responseHeader)
+ status, err := strconv.Atoi(parts[0][0:1])
+ meta := parts[1]
+ // Switch on status code
+ switch status {
+ case 1, 3, 6:
+ // No input, redirects or client certs
+ fmt.Println("Unsupported feature!")
+ case 2:
+ // Successful transaction
+ // text/* content only
+ if !strings.HasPrefix(meta, "text/") {
+ fmt.Println("Unsupported type " + meta)
+ continue
+ }
+ // Read everything
+ bodyBytes, err := ioutil.ReadAll(reader)
+ if err != nil {
+ fmt.Println("Error reading body")
+ continue
+ }
+ body := string(bodyBytes)
+ if meta == "text/gemini" {
+ // Handle Gemini map
+ links = make([]string, 0, 100)
+ preformatted := false
+ for _, line := range strings.Split(body, "\n") {
+ if strings.HasPrefix(line, "```") {
+ preformatted = !preformatted
+ } else if preformatted {
+ fmt.Println(line)
+ } else if strings.HasPrefix(line, "=>") {
+ line = line[2:]
+ bits := strings.Fields(line)
+ parsedLink, err := url.Parse(bits[0])
+ if err != nil {
+ continue
+ }
+ link := parsed.ResolveReference(parsedLink).String()
+ var label string
+ if len(bits) == 1 {
+ label = link
+ } else {
+ label = strings.Join(bits[1:], " ")
+ }
+ links = append(links, link)
+ fmt.Printf("[%d] %s\n", len(links), label)
+ } else {
+ // This should really be wrapped, but there's
+ // no easy support for this in Go's standard
+ // library
+ fmt.Println(line)
+ }
+ }
+ } else {
+ // Just print any other kind of text
+ fmt.Print(body)
+ }
+ history = append(history, u)
+ case 4, 5:
+ fmt.Println("ERROR: " + meta)
+ }
+ }
+}
diff --git a/bin/icat b/bin/icat
index 0170513..d363e09 100755
--- a/bin/icat
+++ b/bin/icat
@@ -2,6 +2,8 @@
# Display images directly in terminal.
# Tested with xterm v361. Depends on imagemagick convert(1).
+[ "$LC_TERMINAL" = iTerm2 ] && [ -x "$HOME/.iterm2/imgcat" ] && exec "$HOME/.iterm2/imgcat" "$@"
+
# maxsize prints the geomtry size of terminal window, with
# a maximum value of 1000 pixels for width and height, or
# 640x480 if terminal size can not be probed.
diff --git a/bin/md b/bin/md
new file mode 100755
index 0000000..ca08090
--- /dev/null
+++ b/bin/md
@@ -0,0 +1,136 @@
+#!/bin/sh
+
+# See https://spec.commonmark.org for reference
+md2html() {
+ awk '
+ function newblock(nb) {
+ if (text) print "<" block ">" text "</" block ">"
+ text = ""
+ block = nb ? nb : "p"
+ }
+
+ function subinline(tgl, inl) {
+ while (match($0, tgl)) {
+ if (inline[ni] == inl)
+ ni -= sub(tgl, "</" inl ">")
+ else if (sub(tgl, "<" inl ">"))
+ inline[++ni] = inl
+ }
+ }
+
+ function dolink(href, lnk) {
+ # Undo escaped html in uris
+ gsub(/&amp;/, "\\&", href)
+ gsub(/&lt;/, "<", href)
+ gsub(/&gt;/, ">", href)
+ # & can be tricky, and not standard:
+ gsub(/&/, "\\\\\\&", href)
+ gsub(/&/, "\\\\\\&", lnk)
+ return "<a href=\"" href "\">" lnk "</a>"
+ }
+
+ BEGIN { ni = 0; nl = 0; text = ""; block = "p" }
+
+ # Escape html
+ esc != "false" { gsub("&", "\\&amp;"); gsub("<", "\\&lt;"); gsub(">", "\\&gt;") }
+
+ # Horizontal rules (_ is not in markdown)
+ /^[ ]*([-*_] ?)+[ ]*$/ && text == "" { print "<hr>"; next }
+
+ # Tables (not in markdown)
+ # Syntax:
+ # Right Align| Center Align |Left Align
+ /([ ]\|)|(\|[ ])/ {
+ if (block != "table") newblock("table")
+ nc = split($0, cells, "|")
+ $0 = "<tr>\n"
+ for (i = 1; i <= nc; i++) {
+ align = "left"
+ if (sub(/^[ ]+/, "", cells[i])) {
+ if (sub(/[ ]+$/, "", cells[i]))
+ align = "center"
+ else
+ align = "right"
+ }
+ sub(/[ ]+$/, "", cells[i])
+ $0 = $0 "<td align=\"" align "\">" cells[i] "</td>\n"
+ }
+ $0 = $0 "</tr>"
+ }
+
+ # Ordered and unordered (possibly nested) lists
+ /^[ ]*([*+-]|(([0-9]+[\.-]?)+))[ ]/ {
+ newblock("li")
+ nnl = 1
+ while (match($0, /^[ ]/)) { sub(/^[ ]/,""); nnl++ }
+ while (nl > nnl) print "</" list[nl--] ">"
+ while (nl < nnl) {
+ list[++nl] = "ol"
+ if (match($0, /^[*+-]/)) list[nl] = "ul"
+ print "<" list[nl] ">"
+ }
+ sub(/^([*+-]|(([0-9]+[\.-]?)+))[ ]/,"")
+ }
+
+ # Multi line list items
+ block == "li" { sub(/^( *)|( *)/,"") }
+
+ # Code blocks
+ /^( | )/ {
+ if (block != "code") newblock("code")
+ sub(/^( | )/, "")
+ text = text $0 "\n"
+ next
+ }
+
+ # Paragraph
+ /^$/ { newblock(); while(nl > 0) print "</" list[nl--] ">" }
+
+ # Setex-style Headers (plus h3 with underscores)
+ /^=+$/ { block = "h" 1; next }
+ /^-+$/ { block = "h" 2; next }
+ /^_+$/ { block = "h" 3; next }
+
+ # Atx-style headers
+ /^#/ {
+ newblock()
+ match($0, /#+/)
+ n = RLENGTH
+ if (n > 6) n = 6
+ sub(/# */, "#")
+ text = substr($0, RLENGTH + 1)
+ block = "h" n
+ next
+ }
+
+ {
+ # Images
+ while (match($0, /!\[[^\]]+\]\([^\)]+\)/)) {
+ split(substr($0, RSTART, RLENGTH), a, /(!\[)|\)|(\]\()/)
+ sub(/!\[[^\]]+\]\([^\)]+\)/, "<img src=\"" a[3] "\" alt=\"" a[2] "\">")
+ }
+ # Links
+ while (match($0, /\[[^\]]+\]\([^\)]+\)/)) {
+ split(substr($0, RSTART, RLENGTH), a, /[\[\)]|(\]\()/)
+ sub(/\[[^\]]+\]\([^\)]+\)/, dolink(a[3], a[2]))
+ }
+ # Auto links (uri matching is poor)
+ na = split($0, a, /(^\()|[ ]|([,\.\)]([ ]|$))/)
+ for (i = 1; i <= na; i++)
+ if (match(a[i], /^(((https?|ftp|file|news|irc):\/\/)|(mailto:)).+$/))
+ sub(a[i], dolink(a[i], a[i]))
+ # Inline
+ subinline("(\\*\\*)|(__)", "strong")
+ subinline("\\*", "em")
+ subinline("`", "code")
+ text = text (text ? " " : "") $0
+ }
+
+ END {
+ while(ni > 0) text = text "</" inline[ni--] ">"
+ newblock()
+ while(nl > 0) print "</" list[nl--] ">"
+ }' "$1"
+}
+
+md2html "$1"
diff --git a/bin/migrate_vimki b/bin/migrate_vimki
new file mode 100755
index 0000000..15242e6
--- /dev/null
+++ b/bin/migrate_vimki
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Migrate Wiki content from vimki to vimki2 format.
+
+fixfile() {
+ awk '
+ {
+ for (i = 1; i <= NR; i++) {
+ if (match($i, /^[A-Z][A-Z_0-9]*[a-z][a-z0-9]*[_A-Z]/) == 0) continue
+ s = $i
+ l = ""
+ while (match(s, /^[A-Z][A-Z_0-9]*[a-z]+/) != 0) {
+ l = l substr(s, 1, RLENGTH) " "
+ s = substr(s, RLENGTH+1)
+ }
+ p = match(s, /[^A-Za-z0-9_]/)
+ if (p != 0) {
+ s2 = substr(s, 1, p-1) "]" substr(s, p)
+ s = s2
+ } else s = s "]"
+ l = "[" l s
+ gsub(/[ \t_]+/, " ", l)
+ sub(/ *]/, "]", l)
+ $i = tolower(l)
+ }
+ print
+ }
+ ' "${1:-HomePage}"
+}
+
+fixname() {
+ echo "$1" | awk '{
+ s = $0
+ l = ""
+ while (match(s, /^[A-Z][A-Z_0-9]*[a-z]+/) != 0) {
+ l = l substr(s, 1, RLENGTH) " "
+ s = substr(s, RLENGTH+1)
+ }
+ p = match(s, /[^A-Za-z0-9_]/)
+ if (p != 0) {
+ s2 = substr(s, 1, p-1) "]" substr(s, p)
+ s = s2
+ }
+ l = l s
+ gsub(/[ \t_]+/, " ", l)
+ sub(/ *$/, "", l)
+ print tolower(l)
+
+ }'
+}
+
+mkdir -p $HOME/Wiki2
+cd $HOME/Wiki
+for file in *; do
+ new=$(fixname "$file")
+ echo "$new"
+ fixfile "$file" > "$HOME/Wiki2/$new"
+done
diff --git a/bin/open b/bin/open
deleted file mode 100755
index 0fa97a7..0000000
--- a/bin/open
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-exec >/tmp/open.out 2>&1
-set -x
-
-cmd=xdg-open
-case $1 in
-(*.mkv|*.mp4) cmd=vlc;;
-esac
-
-exec $cmd "$@"
diff --git a/bin/rdate b/bin/rdate
new file mode 100755
index 0000000..a69d137
--- /dev/null
+++ b/bin/rdate
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Set date on remote machine from local one. This version works
+# from MacOS to AlpineLinux. It is intended to re-sync clock of a
+# virtual machine after host wakeup.
+
+# TODO: option to display the time difference between host and remote.
+# hint: use 'date +%s' to get timestamp in seconds since epoch.
+
+ssh "$1" "sudo date $(date +%m%d%H%M%Y.%S)"
+
diff --git a/bin/start_godoc b/bin/start_godoc
new file mode 100755
index 0000000..15bb70a
--- /dev/null
+++ b/bin/start_godoc
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+/Users/marc/go/bin/godoc >/tmp/godoc.out 2>&1 &
diff --git a/bin/update_hosts b/bin/update_hosts
new file mode 100755
index 0000000..40ec470
--- /dev/null
+++ b/bin/update_hosts
@@ -0,0 +1,26 @@
+#!/bin/sh -e
+
+# Update /etc/hosts with a well curated blacklist of malware, ads, porn, etc.
+# Custom hosts are preserved.
+
+[ "$USER" = root ] || exec sudo "$0" "$@"
+
+echo 'Checking from https://github.com/StevenBlack/hosts:'
+lsd=$(curl -s 'https://api.github.com/repos/StevenBlack/hosts/commits?path=hosts&page=1&per_page=1' | jq -r '.[0].commit.committer.date')
+echo "last source update: $(date -j -f "%FT%TZ" "$lsd")"
+echo "last local update: $(date -r /etc/hosts)"
+[ $(date -j -f "%FT%TZ" "$lsd" +%s) -lt $(date -r /etc/hosts +%s) ] && echo 'Nothing to do' && exit
+
+cd /etc
+cp -p hosts hosts.old
+hosts=$(awk '/^# Custom host/, /^# End of custom host/' hosts.old)
+curl -s 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' | awk '
+ BEGIN { hosts = ARGV[1]; ARGV[1] = "" }
+ /^# Custom host/ { print hosts; next }
+ /^# End of custom host/ { next }
+ { print }
+' "$hosts" > hosts.new
+
+mv hosts.new hosts
+[ "$(uname -s)" != Darwin ] || { dscacheutil -flushcache; killall -HUP mDNSResponder; }
+diff -u /etc/hosts.old /etc/hosts | diffstat
diff --git a/bin/update_kernel_host b/bin/update_kernel_host
new file mode 100755
index 0000000..6180921
--- /dev/null
+++ b/bin/update_kernel_host
@@ -0,0 +1,8 @@
+#!/bin/sh -ex
+
+# After 'apk upgrade', update kernel and initrd on VM host
+
+sudo cp /boot/initramfs-virt /tmp
+sudo chmod a+r /tmp/initramfs-virt
+gunzip < /boot/vmlinuz-virt > /tmp/vmlinux
+scp /tmp/initramfs-virt /tmp/vmlinux marc@m1:.vm/vm1/
diff --git a/bin/vimki b/bin/vimki
new file mode 100755
index 0000000..e3e0f4d
--- /dev/null
+++ b/bin/vimki
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# Batch operations on vimki
+
+# rename changes the link name and propagates the change in the wiki
+rename1() {
+ [ "$(head -c 8 "$3")" = VimCrypt ] && return
+ gawk -v old="$1" -v new="$2" -v IGNORECASE=1 '
+ {
+ gsub("[[]" old "[]]", "[" new "]")
+ print
+ }
+ ' "$3" > "$3.$$" && mv "$3.$$" "$3"
+}
+
+link2rx() {
+ gawk -v rx="$1" -v IGNORECASE=1 '
+ BEGIN {
+ gsub(/_/, "\\W+", rx)
+ gsub(/a/, "[aåäáàâã]", rx)
+ gsub(/c/, "[cç]", rx)
+ gsub(/e/, "[eéèêë]", rx)
+ gsub(/i/, "[iîíìï]", rx)
+ gsub(/o/, "[oôöóõò]", rx)
+ gsub(/u/, "[uùûüú]", rx)
+ gsub(/y/, "[yÿ]", rx)
+ gsub(/n/, "[nñ]", rx)
+ print rx
+ }'
+}
+
+#shellcheck disable=SC2020
+
+linkfile() {
+ echo "$1" |
+ tr '[:upper:]' '[:lower:]' |
+ tr 'åäáàâãçéèêëîíìïôöóõòùûüúÿñ' 'aaaaaaceeeeiiiiooooouuuuyn' |
+ awk '{gsub(/\W+/, "_"); print}'
+}
+
+rename() {
+ rx=$(link2rx "$1")
+ # Parallelize renaming
+ echo *.md | xargs -n 1 -P 8 "$0" rename1 "$rx" "$2"
+ oldf="$(linkfile "$1").md"
+ [ -f "$oldf" ] && mv "$oldf" "$(linkfile "$2").md"
+}
+
+fixfiles() {
+ for f in *; do
+ mv "$f" "$(linkfile "$f")"
+ done
+}
+
+cd ~/Wiki || exit
+"$@"
diff --git a/bin/xt b/bin/xt
index f14954c..98f6ac6 100755
--- a/bin/xt
+++ b/bin/xt
@@ -1,5 +1,6 @@
#!/bin/sh
-exec xterm -sl 500 -j -cr red "$@" &
+#exec xterm -sl 500 -j -cr red "$@" &
+exec xterm "$@" &
#cmd="urxvtc ${@:--T $HOSTNAME}"
#cmd="urxvtc $@"
#eval "$cmd" || { [ $? = 2 ] && urxvtd -q -o -f && eval "$cmd"; }