Index: mkpw.c ================================================================== --- mkpw.c +++ mkpw.c @@ -24,10 +24,12 @@ #include #include #include #define sz(a) ( sizeof (a) / sizeof (a) [0] ) #define say(x) (write(2, (x), sizeof (x))) + +long syscall(long, ...); #ifdef _CLIPBOARD # include # include # include Index: ord.c ================================================================== --- ord.c +++ ord.c @@ -41,14 +41,11 @@ #include #include #include #define sz(x) ( sizeof (x) / sizeof (x) [0] ) - -enum /* constants */ { - null = 0, -}; +#define null ((void*)0) typedef unsigned long long word; typedef _Bool bool; enum { false = 0, true = 1 }; DELETED rich-ascii.ct Index: rich-ascii.ct ================================================================== --- rich-ascii.ct +++ rich-ascii.ct @@ -1,66 +0,0 @@ -# rich ascii -[*rich ascii] is a file format that adds very basic organizational and structural data to a text file using only ASCII control codes. even though it is called [*rich ascii], it is fully compatible with UTF-8. - -##s document structure - def: : [*[#1]] ::= [#2] - ctl: [#1][,[#2]] - ref: [U+27E8][*[#1]][U+27E9] -%% nested macro ident interpolation is currently broken; it seems to always use the arguments of the top(?)-level invocation, so we have to use this ugly fucking hack instead. fuck me - SOH: {ctl [&q-SOH SOH]|1} - STX: {ctl [&q-STX STX]|2} - ETX: {ctl [&q-ETX ETX]|3} - HT: {ctl [&q-HT HT]|9} - NL: {ctl [&q-NL NL]|10} - FF: {ctl [&q-FF FF]|12} - DLE: {ctl [&q-DLE DLE]|16} - - q-SOH: start of heading - q-STX: start of text - q-ETX: end of text - q-FF: form feed - q-HT: horizontal tab - q-NL: newline - q-DLE: data link escape - -a rich ascii document consists of a series of UTF-8 or ASCII codepoints. - -$def doc|{ref title} {ref block}* -$def title|{SOH} {ref span} {ETX} -$def block|{SOH} {ref span} {STX} {ref body} {ETX} -$def block|{STX} {ref body} {ETX} -$def block|{ref table-row} -$def block|{ref metadata} -$def table-row|{ref table-cell}* -$def table-cell|{HT}+ {STX} {ref span} {ETX} -$def table-cell|{HT}+ {SOH} {ref span} {ETX} -$def metadata|{DLE} {ref text} {STX} {ref body} {ETX} -$def text|[!(any valid sequence of ASCII or UTF-8 characters of codepoint [=0x20] or higher)] -$def span|{ref text} -$def body|{ref span}* -$def body|{ref block}* - -here is a structurally annotated document with several levels of headings. - -> {SOH} worldgov expropriation notice {ETX} -> {s.DLE} author {s.STX} eudavia wobblebotch, esq. {s.ETX} -> {s.STX} please read this missive with the utmost care and attention to detail. failure to comply may result in liquidation without prior notice. {s.ETX} -> {s.SOH} demands {s.STX} ->> {s.STX} you are by the splendid munificence of EUDAVIA MILLWEED WOBBLEBOTCH, ESQ. hereby ordered, commanded, and impelled to collect posthaste the following objects, thought processes, bureaucratic minutia, and/or thumotic residuals, immediately thereupon to deliver them to the WORLDGOV OFFICE OF REQUISITIONS, IMPOSITIONS, & INQUISITIONS. failure to comply may result in liquidation without prior notice. ->> {s.SOH} carapace of a WALLOWING SLIMETOOTLER {s.STX} ->>> {s.STX} easily located by application of a rigorously dour pataphor when dawns the witching hour {s.ETX} ->>> {s.SOH} mandatory qualia {s.STX} ->>>> {STX} pulchritude {ETX} ->>> {s.ETX} ->> {s.ETX} ->> {s.SOH} verse of cultivation {s.STX} ->>> woe on thee, unit {NL} ->>> of fungible labor {NL} ->>> your productivity {NL} ->>> has diminished {NL} ->>> and your soul {NL} ->>> has been requisitioned {NL} ->>> by THE SMILING MAN {NL} ->>> for Project {NL} ->>> Scowling Lizard. ->> {s.ETX} -> {s.ETX} ADDED spec/rasuir.ct Index: spec/rasuir.ct ================================================================== --- spec/rasuir.ct +++ spec/rasuir.ct @@ -0,0 +1,150 @@ +# rasuir protocol spec +rasuir is a simple protocol for semi-dumb remotes to retrieve menus and informational displays from a server. it is a stateless protocol; connections are ephemeral + +%author lexi hale +%toc + +## client and server state +a client uses two state variables when communicating with a server. these are [$mode] and [$ref]. [$mode] is an [!int<16>] menu number, where 0 is the root menu. [$ref] is an [!int<64>] opaque value. +a server is not required to store any state, but may do so in order to implement sessions if complex behavior is absolutely required + +## definitions + +an italicized form indicates a formally specified sequence of bytes. parameters (e.g. the length of an integer form) are placed in angle brackets after the identifier. if the form is bound to a name in context, it is followed by a [`:] and a name in variable notation. +* [*byte], [*byte<1>] ==> one octet +* [*byte<[$N]>] ==> [!byte] [!byte<[=N-1]>] +* [*int<[$N]>] ==> [!byte<[=N / 8]>] interpreted as a little-endian unsigned integer (e.g. [!int<32>] represents an unsigned little-endian 32-bit integer) +* [*sigint<[$N]>] ==> like the above, but interpreted as a two's-complement signed integer +* [*byte-sequence<[$L]>] ==> [!int<[$L]>:[$N]] [!byte<[$N]>], with no specific semantics. that is, a variable-length byte sequence whose size prefix is [$L] bits long +* [*string] ==> [!byte-sequence<8>] interpreted as a UTF-8 string +* [*text] ==> [!byte-sequence<16>] interpreted as a UTF-8 string +* [*bitmap] ==> [!int<16>:[$pxl-width]] [!byte-sequence<8>:[$map]] +* [*state] ==> +*: if on the root menu: [`0x00] +*: if on a menu with an ID between [`1]-[`127] and the opaque [$ref] value is [`0] ("null"): the menu number cast to [!int<8>] (e.g. [`0x00 4A] --> [`0x4A]) +*: if on a menu between [`128]-[`383] with a null [$ref] value: [`0x80] [!int<8>:[=mode - 128]] +*: if on a menu greater than [`383] with a null [$ref]: [`0x81] [!int<16>:[$mode]]. this form is also valid if the number is lower than [`383], and can be used where logical simplicity is more important than compact signalling +*: otherwise: +*:: let [$ref-len] be the length in bytes of the [$ref] value, maximum 8 (0 is valid, in which case no [$ref] sequence is sent) +*:: let [$mode-range] be [`0] if [$mode] is between [`0] and [`255], [`1] otherwise +*:: let [$signal-byte] be [`([$ref-len] << 1) | [$mode]-[$range]] +*:: send [!int<8>:[$signal-byte]] [!int<[=8 + 8*mode-range]>:[$mode]] [!int<[$ref-len*8]>:[$ref]] +* [*link] ==> [!int<8>:[$role]] [!state:[$target]] + +## outline + +: client connects to server +: client transmits {m.n con-ack} +: client authenticates by one of the following +:: to authenticate anonymously, client transmits byte [`0x00]. +:: to authenticate by shortname, client transmits byte [`0x01] followed by a [!byte-sequence<8>]. this may be a PSK, a URI, a literal text name, an OID, or anything else depending on what the server is configured to recognize. +:: to authenticate by longname, client transmits byte [`0x01] followed by a [!byte-sequence<16>]. this is identical to the above but allows to longer values. technically these are different forms of the "name" authentication method; the difference is relevant only at the byte-level +:: other authentication methods may be defined later. a server that encounters an unknown authentication method must transmit an error and close the connection, as it cannot know how to interpret any further communications from the client +: server reports authentication status +:: if the authentication failed, xmit {m.n status-fail} and close the connection +:: if the authentication succeeded, xmit {m.n status-ok} +: client transmits a command +:: {m.n cmd-get} retrieves a menu. it takes the form [!state] [!action] +:: {m.n cmd-hint} transmits a hint to the server. it takes the form [!int<8>:[$hint]] [!byte-sequence<16>] +:: {m.n cmd-meta} requests metadata from the server. it takes the form [!int<16>] +:: {m.n cmd-end} closes the connection. it takes no arguments +: server issues [>rep reply] +: while command was not {m.n cmd-end}, previous two steps repeat +: peers disconnect + +##rep server replies +all replies begin with a one-byte status code. + +### cmd-get reply +the hint reply code may be: +* {m.n status-ok}: the request was valid but the current display should not be changed +* {m.n status-fail}: the request was not valid +* {m.n status-ignore}: the action did nothing +* {m.n status-data}: the request was valid and a form is being returned to display. + +if the reply is {m.n status-data}, it is followed by the header [!byte:[$flags]] [!int<16>:[$widget-count]] +* [$flags] is a bitmask +** [`0x01] = [*passthrough]: all actions should be passed through raw, instead of being used to select a choice in a device-dependent way +** [`0x02] = [*refresh]: client should poll the server for periodic updates on this screen. the header should be followed by an additional parameter [!int<16>:[$refresh]] where refresh time is [=10ms * refresh] + +[$widget-count] widgets then follow. a widget takes the form [!byte:[$wid]] [!byte-sequence<18>:[$data]]. [$wid] identifies the widget type. [$data] holds the widget contents. it is widget-dependent; this value is given as sequence so it can be skipped over by clients that don't implement [$wid]; e.g. images on text displays (though a hint should be sent to disable images instead, in order to save bandwidth). + +### cmd-hint reply +the hint reply code may be: +* {m.n status-ok}: the hint was understood and applied +* {m.n status-fail}: the hint was invalid +* {m.n status-ignore}: the hint was not understood and was ignored +* {m.n status-data}: the hint was understood, and metadata is being returned +if the reply is {m.n status-data}, the code must be followed by a [!byte-sequence<16>]. the meaning of this sequence is hint-dependent. + +### cmd-meta reply +the meta reply code may be: +* {m.n status-ok}: the metadata request was understood but the field is empty/blank +* {m.n status-fail}: the data requested could not be retrieved +* {m.n status-ignore}: the request was not understood and was ignored +* {m.n status-data}: the request was understood, and metadata is being returned +if the reply is {m.n status-data}, the code must be followed by a [!byte-sequence<16>]. the meaning of this sequence is hint-dependent. + + +## widgets +the special notation [!tail] refers to the remainder of entry data body, which is wrapped in a sequence header, so the final element does not need an explicit length or termination marker. [!tail] indicates a type [$T] modified such that any length marker for the final value is removed; for instance [!tail] means ([!int<16>:[$pxl-width]] [!tail:[$map]]). +* {m.n w-paragraph} = [`0x00] [!tail] / shows a block of text +* {m.n w-section} = [`0x02] [!tail] / inserts a heading +* {m.n w-rule} = [`0x07] / inserts a horizontal line that stretches across the screen +* {m.n w-define} = [`0x03] [!string:[$name]] [!tail:[$val]] / shows a definition (e.g. [`[*Name]: Value]); sequential definitions may be arranged into a table +* {m.n w-pbar} = [`0x04] [!int<8>:[$progress]] / shows a progress bar; [`0] means empty, [`255] means full +* {m.n w-bitmap} = [`0x05] [!tail] / shows an image +* {m.n wi-bitmap} = [`0x06] [!link] [!string] [!tail] / shows an image that can be activated as an option, along with caption that may be displayed in vertical layout or as a substitute for the image in text-only displays +* {m.n wi-choice} = [`0x01] [!link:[$target]] [!tail:[$label]] / adds an option that can be selected from the menu, causing the client for query for [$target]. +* {m.n wl-horiz} = [`0x80] [!int<8>:[$N]] / the next [$N] widgets will be arranged horizontally into a grid if possible + +## roles +a role is a small piece of metadata that alters the appearance of an object, for example by changing color or applying an icon. defined roles consist of: +: generic +: accept +: abort +: cancel +: next +: back +: delete +: pause +: play +: stop + +## hints +* {m.n device-kind}: [!int<8>:[$kind]] where [$kind] denotes the kind of device the client is running on. can be repeated to add additional characteristics +*: miniscreen: tiny embedded screen +*: midscreen: phone-sized screen +*: bigscreen: tablet- or larger-sized screen +*: e-ink: the display device uses e-ink (implies bw unless color is also sent) +*: bw: display is black and white +*: color: display supports color +*: slow: device refreshes slowly +*: no-img: do not send bitmap images + +## meta requests +* {m.n server-name} = [`0x00 00]: returns the hostname of the server as a UTF-8 string, or {m.n status-fail} if the hostname is not known +* {m.n server-desc} = [`0x00 01]: returns a textual description of the server, or {m.n status-ok} if no description is set + +##m magic numbers + n: ‹[*[#1]]› + ++ ID + value + +| con-ack | [`0x7A] | +| status-ok | [`0xFF] | +| status-data | [`0xF0] | +| status-ignore | [`0x0F] | +| status-fail | [`0x00] | +| cmd-get | [`0x01] | +| cmd-hint | [`0x02] | +| cmd-meta | [`0x03] | +| cmd-end | [`0x00] | +| w-paragraph | [`0x00] | +| w-section | [`0x02] | +| w-pbar | [`0x04] | +| w-define | [`0x03] | +| w-rule | [`0x07] | +| w-bitmap | [`0x05] | +| wi-bitmap | [`0x06] | +| wi-choice | [`0x01] | +| wl-horiz | [`0x80] | ADDED spec/rich-ascii.ct Index: spec/rich-ascii.ct ================================================================== --- spec/rich-ascii.ct +++ spec/rich-ascii.ct @@ -0,0 +1,66 @@ +# rich ascii +[*rich ascii] is a file format that adds very basic organizational and structural data to a text file using only ASCII control codes. even though it is called [*rich ascii], it is fully compatible with UTF-8. + +##s document structure + def: : [*[#1]] ::= [#2] + ctl: [#1][,[#2]] + ref: [U+27E8][*[#1]][U+27E9] +%% nested macro ident interpolation is currently broken; it seems to always use the arguments of the top(?)-level invocation, so we have to use this ugly fucking hack instead. fuck me + SOH: {ctl [&q-SOH SOH]|1} + STX: {ctl [&q-STX STX]|2} + ETX: {ctl [&q-ETX ETX]|3} + HT: {ctl [&q-HT HT]|9} + NL: {ctl [&q-NL NL]|10} + FF: {ctl [&q-FF FF]|12} + DLE: {ctl [&q-DLE DLE]|16} + + q-SOH: start of heading + q-STX: start of text + q-ETX: end of text + q-FF: form feed + q-HT: horizontal tab + q-NL: newline + q-DLE: data link escape + +a rich ascii document consists of a series of UTF-8 or ASCII codepoints. + +$def doc|{ref title} {ref block}* +$def title|{SOH} {ref span} {ETX} +$def block|{SOH} {ref span} {STX} {ref body} {ETX} +$def block|{STX} {ref body} {ETX} +$def block|{ref table-row} +$def block|{ref metadata} +$def table-row|{ref table-cell}* +$def table-cell|{HT}+ {STX} {ref span} {ETX} +$def table-cell|{HT}+ {SOH} {ref span} {ETX} +$def metadata|{DLE} {ref text} {STX} {ref body} {ETX} +$def text|[!(any valid sequence of ASCII or UTF-8 characters of codepoint [=0x20] or higher)] +$def span|{ref text} +$def body|{ref span}* +$def body|{ref block}* + +here is a structurally annotated document with several levels of headings. + +> {SOH} worldgov expropriation notice {ETX} +> {s.DLE} author {s.STX} eudavia wobblebotch, esq. {s.ETX} +> {s.STX} please read this missive with the utmost care and attention to detail. failure to comply may result in liquidation without prior notice. {s.ETX} +> {s.SOH} demands {s.STX} +>> {s.STX} you are by the splendid munificence of EUDAVIA MILLWEED WOBBLEBOTCH, ESQ. hereby ordered, commanded, and impelled to collect posthaste the following objects, thought processes, bureaucratic minutia, and/or thumotic residuals, immediately thereupon to deliver them to the WORLDGOV OFFICE OF REQUISITIONS, IMPOSITIONS, & INQUISITIONS. failure to comply may result in liquidation without prior notice. +>> {s.SOH} carapace of a WALLOWING SLIMETOOTLER {s.STX} +>>> {s.STX} easily located by application of a rigorously dour pataphor when dawns the witching hour {s.ETX} +>>> {s.SOH} mandatory qualia {s.STX} +>>>> {STX} pulchritude {ETX} +>>> {s.ETX} +>> {s.ETX} +>> {s.SOH} verse of cultivation {s.STX} +>>> woe on thee, unit {NL} +>>> of fungible labor {NL} +>>> your productivity {NL} +>>> has diminished {NL} +>>> and your soul {NL} +>>> has been requisitioned {NL} +>>> by THE SMILING MAN {NL} +>>> for Project {NL} +>>> Scowling Lizard. +>> {s.ETX} +> {s.ETX}