ADDED clipserv/ansi.b Index: clipserv/ansi.b ================================================================== --- clipserv/ansi.b +++ clipserv/ansi.b @@ -0,0 +1,105 @@ +; [ʞ] ansi.b +; ~ lexi hale +; © AGPLv3 +; ? a terminal text formatter for boron +; > do read/text %ansi.b +; @ vim: ft=rebol + +stdin: open 0 +stdout: open 1 +stderr: open 2 + +fmt-code-stack: [] + +in-list: func [i lst] [ either (find lst i) [true] [false] ] + +ansi: context [ + escape: to-string #{1B5B} + fmt: "m" with: ";" + style: context [ + hl: "1" ul: "4" rv: "7" sl: "3" dim: "2" + ] + color: context [ + red: "1" green: "2" + yellow: "3" blue: "4" + purple: "5" cyan: "6" + white: "7" black: "0" + ] + fg: color bg: color + + frame: context [ + kind: none + value: none + ] +] + +fmt-push: func[k v] [ any [ + all [ + f-kind: in ansi k + f-val: in (do f-kind) v + + frame: make ansi/frame [ + kind: f-kind + value: f-val + ] + + append fmt-code-stack frame + ] throw 'bad-argument +]] + +fmt-pop: does [ pop fmt-code-stack ] + +fmt-seq: func[/local] [ + active-styles: [] + active-colors: context [ + fg: none + bg: none + ] + + foreach frame fmt-code-stack [ + either eq? frame/kind 'style [ + ifn in-list frame/value active-styles [ + append active-styles frame/value + ] + ] /* or */ [ + ck: in active-colors (unbind frame/kind) + set ck frame/value + ] + ] + + style-string: rejoin (map i active-styles [join ";" (do i)]) + + key: context [ + plain: context [ fg: "3" bg: "4" ] + bright: context [ fg: "9" bg: "10" ] + ] + foreach i [fg bg] [ + code: do (in key/plain i) + color: do (in active-colors i) + if color [ + style-string: join style-string rejoin + [";" code do color] + ] + ] + + free active-styles + + rejoin [ ansi/escape style-string ansi/fmt ] +] + +fmt: func [lst] [ + depth: 0 + evaluated: map term (join lst fmt-seq) [ + case [ + paren? term [ + fmt-push (first term) (second term) + ++ depth fmt-seq + ] + word? term [ do term ] + block? term [ fmt term ] + string? term [ term ] + ] + ] + loop depth [fmt-pop] + rejoin evaluated +] ADDED clipserv/clip.b Index: clipserv/clip.b ================================================================== --- clipserv/clip.b +++ clipserv/clip.b @@ -0,0 +1,149 @@ +#!/usr/bin/env -S boron -sp +; [ʞ] clipserv.b +; ~ lexi hale +; # boron +; @ vim: ft=rebol +; ? a tool for transmitting clipboard from one +; host to another over the network. WARNING: +; simple nonce authentication is used but the +; clipboard is sent IN THE CLEAR + +do read/text %ansi.b + +verbose: no +readonly: no +port: "42069" +key: #{981A7879} + +proto: context [ + writecb: #{3E} + readcb: #{C5} +] + +debug: func [x] [ + if verbose [ + x: either block? x [rejoin x] [x] + + write stderr fmt [ + [(fg red) "["] [(style hl) "debug"] " " x [(fg red) "]"] "^/" + ] + ] +] + +entropy-sink: open %/dev/urandom +rand-block: func[sz] [ read/part entropy-sink sz ] +key-hash: func[k z /local] [ + cksum: checksum join k z + slice cksum 0,4 +] + +debug "parsing arguments" + +usage: does [ + write stderr fmt [[(style hl)"usage:"] + " ./clip.b get | send " ] +] + +flag: func [f /extern verbose readonly] [ + debug ["found flag " i] + do select [ + "-v" [ verbose: yes ] + "-q" [ verbose: no ] + "-r" [ readonly: yes ] + ] f +] + +set-clipboard: func[c] [ execute/in "xsel -bi" c ] + +get-clipboard: func[/local] [ + clip-out: "" + execute/out "xsel -bo" clip-out + clip-out +] + +start-server: func[/local] [ + debug ["serving clipboard from " hostname none ] + sock: open join "tcp://:" port + forever [ + connection: read wait sock + nonce: rand-block 4 + expect-key: (key-hash nonce key) + write connection nonce + debug [ "sent nonce " nonce ";" + "expecting password " expect-key ";"] + + client-message: read wait connection + client-key: slice client-message 0,4 + client-command: slice client-message 4,1 + client-body: slice client-message 5,-1 + + debug [ "received pw " client-key ] + either eq? client-key expect-key [ + debug [ "admitted access" ] + debug [ "got command " client-command ] + case [ + eq? client-command proto/readcb [ + debug {sending clipboard to client} + write connection get-clipboard + ] + eq? client-command proto/writecb [ + new-clipboard: to-string client-body + debug ["got cb " new-clipboard] + set-clipboard new-clipboard + ] + true [ write connection "bad command" ] + ] + ] [ + debug "denied access" + write connection "access denied" + ] + close connection + debug [ "closed connection" ] + ] +] + +send-clip: func[host] [ + debug ["sending clipboard to " host ] + sock: open rejoin ["tcp://" host ":" port] + nonce: read wait sock + debug [ "got nonce " nonce ] + client-key: key-hash nonce key + debug [ "sending password " client-key ] + msg: rejoin [ + client-key + proto/writecb + get-clipboard #{00} + ] + write sock msg +] +get-clip: func[host] [ + debug ["getting clipboard from " host ] + sock: open rejoin ["tcp://" host ":" port] + nonce: read wait sock + debug [ "got nonce " nonce ] + client-key: key-hash nonce key + debug [ "sending password " client-key ] + msg: rejoin [ client-key proto/readcb ] + write sock msg + clipboard: read wait sock + print ["server response: " to-string clipboard] +] + +main: func [argv checked-flags] [ + case [ + none? argv [ usage ] + parse argv ["get" host: string!] [ get-clip host ] + parse argv ["send" host: string!] [ send-clip host ] + parse argv ["serve"] [ start-server ] + not checked-flags [ + new-args: [] + foreach i argv [ + either eq? first i '-' [ flag i ] [ + new-args: join new-args i ] ] + main new-args yes + ] + true [ usage ] + ] +] + +main args no