tag:blogger.com,1999:blog-81859507509588008152024-03-12T21:16:49.855-07:00DangerRuss Things<strong>[software. firmware. hardware. crazy hair.]</strong>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.comBlogger31125tag:blogger.com,1999:blog-8185950750958800815.post-43312820285451365592024-03-04T20:56:00.000-08:002024-03-04T21:39:57.253-08:00New Not-Not AI-based Web Service Anti-DDoS Code Project: Visit-At-Your-Peril™<p> Preventing Web Crawlers From Disrupting My Self-Hosted Web Services<br /><br />I've found that a few major web crawl bots, none of which honour robots.txt, keep crawling my Gogs repos as well as my bacillus CI server wasting all sorts of bandwidth (and accidentally clicking links that activate things on some of my test projects! Well, that is, until I started blocking certain UserAgents...)</p><p><br /></p><p>I've automated adding them to my iptables ban list: If you're NOT not an evil web bot, don't NOT visit my wonderful new code project at <a href="https://gogs.blitter.com/RLabs/visit-this-at-your-peril">https://gogs.blitter.com/RLabs/visit-this-at-your-peril</a>! This innovative program, using the latest AI techniques based on ChatGPT and Gemini, is a new model that intelligently not-unblocks all not-not-web bots based on their not-staying-away from it.</p><p>You have NOT been not warned. :P</p><p><br /></p>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com1tag:blogger.com,1999:blog-8185950750958800815.post-78765680179705564642022-02-17T22:07:00.004-08:002022-02-17T22:09:45.966-08:00An APL Translation of 'Square Joy: Trapped Rainwater' J Posting<p> I saw an interesting post entitled "Square Joy: Trapped Rainwater" on the <a href="https://mmapped.blog/posts/04-square-joy-trapped-rain-water.html" target="_blank">mmapped blog</a>, describing how to approach the problem of computing water levels in a 2D Flatland cityscape.</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://mmapped.blog/images/04-viewmat-2d.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="200" data-original-width="360" height="200" src="https://mmapped.blog/images/04-viewmat-2d.png" width="360" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><span style="background-color: black; text-align: start;"><span style="color: #cccccc;">The configuration of bars with heights 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1, and the water trapped by this configuration.</span></span></td></tr></tbody></table><br /><br /><p><br /></p><p>The author uses J, so I thought I'd take a quick look at converting the basic computation into its parent language, APL. Turns out it's quite simple (minus the graphic representation which I haven't yet looked at doing in GNU APL).</p><p>J has the /\. adverb ('suffix'), here applied to the 'insert' (/) which it shares with APL. APL must simulate it via two applications of the reversal (⌽) function:</p><div style="text-align: left;"><span style="font-family: courier;">
<pre> H ← 0 1 0 2 1 0 1 3 2 1 2 1
⌈\H
0 1 1 2 2 2 2 3 3 3 3 3
⌽⌈\⌽H ⍝ Note the use of 'reversal' here (⌽) with insert (/) to match J's 'suffix scan'
3 3 3 3 3 3 3 3 2 2 2 1
(⌈\H) ⌊ (⌽⌈\⌽H)
0 1 1 2 2 2 2 3 2 2 2 1
</pre>
</span></div><p><br /></p><p>Maybe later I'll try to create the visual renderings in GNU APL to match what the J solution does.</p>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-14064816819505999972022-01-13T22:53:00.004-08:002022-01-13T22:56:59.950-08:00String Interpolation in APL -- Formatted string output ala printf()<div style="text-align: left;">This is not as sophisticated as C's printf() of course, but it's enough for many uses.</div><p><br /></p><pre> ∇r ← s sInterp sv
⍝⍝ Interpolate items in sv into s (string field substitution)
⍝ s: string - format string, '∆' used for interpolation points
⍝ sv: vector - vector of items to interpolate into s
⍝ r: interpolated string
s[('∆'=s)/⍳⍴s] ← ⊃¨(⍕¨sv)
r ← ∊s
∇
'Mary had a ∆ lamb, its fleece was ∆ as ∆.' sInterp 'little' 'black' 'night'
Mary had a little lamb, its fleece was black as night.
'Mary had a ∆ lamb, its fleece was ∆ as ∆.' sInterp 'little' 'large' 42
Mary had a little lamb, its fleece was large as 42.
</pre>
<p><br /></p>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-48968632647425708902022-01-07T22:01:00.004-08:002022-01-13T22:57:18.374-08:00A Recursive Depth-First Maze Generator in GNU APL<div style="text-align: left;"><a href="http://Rosettacode.org">Rosettacode.org</a> is a great place to grab little ideas and apply them to learning a new language; especially if there isn't a solution there yet in the language you're learning! This past week I took some spare time in the evenings to implement the classic maze generator problem, in <a href="https://www.gnu.org/software/apl/" target="_blank">GNU APL</a>.</div><p>Takeaways:</p><p></p><ul style="text-align: left;"><li>Sometimes just manipulating the string representation of a maze is easier than trying to come up with a clever binary representation (I started with the idea that each maze cell's walls could be a 4-bit field, eg. nsew = [3210], but the shared walls between cells made it too messy);</li><li>GNU APL's ? (shuffle) operator appears to have a static seed and the docs don't clearly state how to seed it: the ⎕RL system variable has the shuffle op's internal state so assigning to it will seed the PRNG, eg:</li></ul><p></p>⎕RL ← +/ ⎕TS ⍝⍝ Seed ⎕RL (?) PRNG with sum of timestamp Y, M, D, H, M, S, ms<br /><br /><div><br /></div>
<pre>#!/usr/local/bin/apl --script --
⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝
⍝ ⍝
⍝ mazeGen.apl 2022-01-07 19:47:35 (GMT-8) ⍝
⍝ ⍝
⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝
∇initPRNG
⍝⍝ Seed the internal PRNG used by APL ? operator
⎕RL ← +/ ⎕TS ⍝⍝ Not great... but good enough
∇
∇offs ← cellTo dir
⍝⍝ Return the offset (row col) to cell which lies in compass (dir)
offs ← ∊((¯1 0)(0 1)(1 0)(0 ¯1))[('nesw'⍳dir)]
∇
∇doMaze rc
⍝⍝ Main function
0 0 mazeGen rc ⍝⍝ Do the maze gen
m ⍝⍝ output result
∇
∇b ← m isVisited coord;mr;mc
→( ∨/ (coord[1] < 1) (coord[2] < 1) )/yes
→( ∨/ (coord > ⌊(⍴m)÷2) )/yes
b ← ' ' ∊ m[2×coord[1];2×coord[2]]
→0
yes:
b←1
∇
∇c mazeGen sz ;dirs;c;dir;cell;next
→(c≠(0 0))/gen
init:
c ← ?sz[1],?sz[2]
m ← mazeInit sz
gen:
cell ← c
dirs ← 'nesw'[4?4]
m[2×c[1];2×c[2]] ← ' ' ⍝ mark cell as visited
dir1:
dir ← dirs[1]
next ← cell + cellTo dir
→(m isVisited next)/dir2
m ← m openWall cell dir
next mazeGen sz
dir2:
dir ← dirs[2]
next ← cell + cellTo dir
→(m isVisited next)/dir3
m ← m openWall cell dir
next mazeGen sz
dir3:
dir ← dirs[3]
next ← cell + cellTo dir
→(m isVisited next)/dir4
m ← m openWall cell dir
next mazeGen sz
dir4:
dir ← dirs[4]
next ← cell + cellTo dir
→(m isVisited next)/done
m ← m openWall cell dir
next mazeGen sz
done:
∇
∇m ← mazeInit sz;rows;cols;r
⍝⍝ Init an ASCII grid of size (rows cols) which
⍝⍝ has all closed and unvisited cells:
⍝⍝
⍝⍝ +-+
⍝⍝ |.|
⍝⍝ +-+
⍝⍝
⍝⍝ @param sz - tuple (rows cols)
⍝⍝ @return m - a (rows × cols) ASCII matrix
⍝⍝⍝⍝
initPRNG
(rows cols) ← sz
r ← ∊ (cols ⍴ ⊂"+-" ),"+"
r ← r,∊ (cols ⍴ ⊂"|." ),"|"
r ← (rows,(⍴r))⍴r
r ← ((2×rows),(1+2×cols))⍴r
r ← r⍪ (∊ (cols ⍴ ⊂"+-" ),"+")
m ← r
∇
∇r ← m openWall cellAndDir ;ri;ci;rw;cw;row;col;dir
(row col dir) ← ∊cellAndDir
ri ← 2×row
ci ← 2×col
(rw cw) ← (ri ci) + cellTo dir
m[rw;cw] ← ' ' ⍝ open wall in (dir)
r ← m
∇
⎕IO←1
doMaze 9 9
)OFF
russtopia@rlm-devuan:~/GNUAPL$ workspaces/mazeGen.apl
+-+-+-+-+-+-+-+-+-+
| | | |
+-+ + +-+-+ + +-+ +
| | | | |
+ +-+-+-+-+-+-+ + +
| | | | | |
+-+-+ +-+ + + + + +
| | | | | |
+ + +-+-+ +-+-+-+ +
| | | | | |
+ +-+ + + +-+ +-+ +
| | | | | |
+ + +-+-+-+ + + +-+
| | | | | | | |
+ +-+ + +-+ +-+ + +
| | | | | | |
+ +-+ + + +-+ +-+ +
| | |
+-+-+-+-+-+-+-+-+-+
</pre>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-67017108182800664452021-11-28T13:34:00.004-08:002021-11-29T22:59:03.970-08:00Parsing script arguments in GNU APL (⎕ARG)<p>In scripting languages one often wants to run the overall script like a standalone program, with a top 'main' function, yet also allow the script to be read into the REPL for editing, testing interactively and so on.</p><p>In Python a common way to do this is by checking the __main__ variable to determine execution scope.</p><p>GNU APL has the --script switch to enable invoking a .APL file and immediately executing it. In standard UNIX fashion the -- switch is also useful to divide GNU APL arguments (those for the interpreter itself) from those intended for the script. Using these two bits of information one can do the same thing in APL:</p><p><br /></p><p><span style="font-family: courier;"></span></p><p><span style="font-family: courier;"><span></span></span></p><span style="font-family: Ubuntu Mono;">#!/usr/bin/env apl --script -- <br /><br />∇scriptFunction <br /><span> </span>⍝⍝ Whatever the script should do by default when run from shell <br /><span> </span>⎕←'This is an APL script'<br />∇<br /><br /> <br />⍝ Parse args & run 'main' if not in REPL mode<br />⍝ in REPL mode, ⎕ARG[1] is the script path itself<br />⍝ (Recalling that by default, ⎕IO = 1)<br />∇checkMode;args<br /><span> </span>args←(⎕ARG⍳⊂"--")↓⎕ARG ⍝ Drop all args up to and including "--"<br /> <span> </span>→(~(⊂'--script')∊⎕ARG)/0 ⍝ If "--script" not present, quit to allow REPL<br /> <span> </span>⍝⍝ ⎕←"[",args[1],"]" ⍝ (just debugging to see args)<br /> <span> </span>scriptFunction ⍎∊args[2] ⍝ in --script mode, so run default func<br />∇<br /><br /></span><div><span style="font-family: Ubuntu Mono;">checkMode ⍝⍝ check the ⎕ARG vector for --script mode</span><br /><br /></div>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-16631381902561501782021-09-12T17:42:00.002-07:002023-01-03T21:21:24.234-08:00<h2 style="text-align: left;">A Hexadecimal Pronunciation Guide, by Robert A. Magnuson - Datamation Vol. 14, No. 1, Jan 1968</h2><p><br /></p><p>I recall discussing with a fellow CS student many years ago the topic of how speaking hexadecimal values seemed to be.. well, clunky. We both thought it strange no one had standardized a set of word stems like we have for the base ten numerals, 'teens', 'fortieth', and so on. All these years later I discovered, as it turns out, someone <i>did</i>. It just didn't catch on, for some reason.</p><p><a href="https://www.blitter.com/nextcloud/index.php/s/7Yc3pmbbpni5D3t" rel="nofollow" target="_blank">An obscure article in <i>Datamation, Vol. 14, No. 1</i> dated January, 1968</a> (<a href="https://archive.org/details/bitsavers_datamation_24921095/page/n7/mode/2up" rel="nofollow" target="_blank">alternate link, archive.org</a>) contains an article by one Robert A. Magnuson, proposing an extension to English number pronunciation for hexadecimal:</p><p><br /></p><blockquote><p><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Table 2. New Names for Hexadecimal Digits </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">A ann </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">B bet </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">C chris </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">D dot </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">E ernest </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">F frost </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">The pronunciation of the -teen's and -ty's for the new </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">digits is shown in Table 3. Note that the analog of the decimal pronunciation system has been used. The new name for each new digit has been chosen so that at least one of the -teen and -ty modifications is familiar sounding.</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;"> </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Table 3. -Teen and -Ty Pronunciation for the New Digits</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1 A annteen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1 B betteen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1 C christeen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1 D dotteen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1 E ernesteen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1 F frosteen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">A0 annty </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">B0 betty </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">C0 christy </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">D0 dotty </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">E0 ernesty </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">F0 frosty</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Now 29's successor 2A can be pronounced "twenty-</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">ann" without the slightest tendency to confuse it with 28. </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">The pronunciation of C4 is "christy-four," and that of A4 </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">is "annty-four." There is no problem in distinguishing </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">between 1A, "annteen" and 18, "eighteen." And 88, 8A, </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">A8, and AA are easily distinguished when pronounced </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">"eighty-eight," "eighty-ann," "annty-eight," and "annty-</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">ann."</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Some two-digit hex numbers, each representing one byte, appear with their new pronunciations in Table 4.</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Table 4. One-Byte Strings with Pronunciation </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">2F twenty-frost </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">F2 frosty-two </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">5B fifty-bet </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">3E thirty-ernest </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">AF annty-frost</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Some four-digit hex numbers, each representing two </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">bytes, appear with their new pronunciations in Table 5.</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">Table 5. Two-Byte Strings with Pronunciation </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">A01C annty christeen </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">1ED0 ernesteen dotty </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">A007 annty oh-seven </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">DEAF dotty-ernest annty-frost </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">3A7D thirty·ann seventy-dot </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">47F0 forty-seven frosty</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">The problem of the values of the added digits being off </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">by one is now easily solved. Merely remember the "ages" </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">of these new-found friends. Learn that ann is 10, bet is </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">11, etc. without becoming confused with the fact that A </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">is associated with 1, B with 2, etc.</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">The problems of some of the hex digits being NUMERIC </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">and the others ALPHA on the model 29 keypunch is solved </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">in the following fashion. Select a particular finger of the </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">left hand, say, the little finger. No other finger of the left </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">hand is to be used. The home position of that left little </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">finger is on the NUMERIC key. The right hand is used for </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">typing 0-9 and the (numeric) comma while the left little </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">finger holds down the NUMERIC key. When· A - F arise, </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">they are typed with the left little finger-thus ensuring </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">that the NUMERIC key is not depressed. Return the left </span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">finger to the home position on the NUMERIC key imme-</span><br style="background-color: #202124; color: #e8eaed; font-family: Roboto, Arial, sans-serif; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;" /><span face="Roboto, Arial, sans-serif" style="background-color: #202124; color: #e8eaed; font-size: 16px; font-variant-ligatures: none; letter-spacing: 0.1px; white-space: pre-wrap;">diately upon finishing A-F.</span></p></blockquote><p><br /></p><p> </p>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-42593306652376610752021-08-17T21:28:00.006-07:002021-11-29T22:59:41.139-08:00APL Keyboard Sticker Set<h2 style="text-align: left;">APL Keyboard Stickers for Laptop or Desktop</h2><div style="text-align: left;">APL uses a special symbol set, which presents a barrier to entry for new users. Furthermore, there don't seem to be many options to get a keyboard with APL symbols, other than expensive specialty ones (<a href="https://www.dyalog.com/apl-font-keyboard.htm" target="_blank">here</a> or <a href="https://www.pckeyboard.com/page/product/USAPLSET" target="_blank">here</a>), and they're for PC desktops only; so what's a laptop user to do?</div><div style="text-align: left;"><br /></div><div style="text-align: left;">I figured I'd take matters into my own hands, and produce a run of APL keyboard stickers. These match the standard APL keyboard map used by historical APL implementations as well as <a href="https://www.gnu.org/software/apl/" target="_blank">GNU APL</a> and <a href="https://www.dyalog.com" target="_blank">Dyalog APL</a>. I got the shipment at end of August, 2021, and they look pretty good on my laptop. Now available on my <a href="https://www.tindie.com/products/russtopia/apl-keyboard-symbol-sticker-set/" target="_blank">Tindie</a> store. Check it out!</div><div style="text-align: left;"><br /></div><div style="text-align: left;">Black vinyl keycap stickers, suitable for any standard laptop or PC desktop keyboard.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">To use these you'll need to set a custom keymap. For Linux, See my post <a href="https://dangerruss-things.blogspot.com/2021/03/getting-started-with-apl-keyboard.html">here</a>. For Windows, see <a href="https://help.dyalog.com/13.1/Content/RelNotes12.0/APL%20Keyboard.htm" target="_blank">here</a>, <a href="https://www.dyalog.com/apl-font-keyboard.htm" target="_blank">here</a> and finally <a href="https://github.com/abrudz/Kbd" target="_blank">here</a>.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">With some trivial setup, modern systems have no issue at all supporting APL symbols. I wonder if its successor, <a href="https://www.jsoftware.com/" target="_blank">J</a>, would have even come to be if the APL character set wasn't seen as an impediment prior to the 2000s. As a newcomer to APL and J, comparing the two, J just seems so much harder to parse as it uses ASCII exclusively; it looks a lot more like line noise to me whereas APL encourages seeing a unique <i>notation.</i></div><div style="text-align: left;"><br /></div><div style="text-align: left;"><br /></div><div style="text-align: left;"><div class="separator" style="clear: both; text-align: center;"><a href="https://lh3.googleusercontent.com/-7B7bQRMzwFY/YR1rl3teBoI/AAAAAAABHTI/y71pyZ5nhYwugic9LhIueWuTBZE3izjMwCLcBGAsYHQ/image.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="684" data-original-width="1678" height="261" src="https://lh3.googleusercontent.com/-7B7bQRMzwFY/YR1rl3teBoI/AAAAAAABHTI/y71pyZ5nhYwugic9LhIueWuTBZE3izjMwCLcBGAsYHQ/w640-h261/image.png" width="640" /></a></div><br /><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-2KK2FA-bepY/YTP1wtl4c6I/AAAAAAABHvg/cBoS0l1FM2gWuP8QH_HgHGpo_P08p5JSgCLcBGAsYHQ/s4096/P_20210902_214602.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2304" data-original-width="4096" height="360" src="https://1.bp.blogspot.com/-2KK2FA-bepY/YTP1wtl4c6I/AAAAAAABHvg/cBoS0l1FM2gWuP8QH_HgHGpo_P08p5JSgCLcBGAsYHQ/w640-h360/P_20210902_214602.jpg" width="640" /></a></div><br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-38655822964688011052021-03-02T22:21:00.013-08:002022-02-08T19:33:45.248-08:00Getting Started with APL: Keyboard Mapping and Using GNU APL on Android with TermUX<p>APL is an under-appreciated language, pioneering many concepts that have re-appeared in almost every language since. <a href="https://analyzethedatanotthedrivel.org/2018/03/31/numpy-another-iverson-ghost/" target="_blank">Iverson Ghosts!</a> Boo.</p><p>A huge hurdle for new users is those funny symbols. How does one enter them on a modern keyboard?</p><p>Wonder no longer! It's not so tough, just not documented that well on the web today. APL has its own Unicode point so all the symbols are already inside your box waiting to be used. One can even use GNU APL on an Android phone or tablet with the Hacker's Keyboard (fork for APL layout, see bottom)</p><p>One would think APL enthusiasts would have keymaps with an easy setup script to run, to encourage newcomers, but I guess not since I didn't run across any... so here's my attempt to help out any other APL-curious people out there.</p><p><br /></p><p>BONUS: Hard-to-find APL book links. These books are out of print and <i>insanely</i> expensive on the used market. I manually scanned in <i>APL2 At A Glance</i> to save it for posterity. It really is the best introductory text for APL2.</p><p><a href="https://archive.org/details/apl-2-at-a-glance-brown-pakin-polivka/mode/2up" target="_blank">APL2 At a Glance (English)</a></p><p><a href="https://www.blitter.com/nextcloud/index.php/s/8cj5JMAxsrCc4Wd" rel="nofollow" target="_blank">APL2 Ein erster Einblick (APL2 At A Glance, German)</a></p><p><a href="https://www.blitter.com/nextcloud/index.php/s/2Wg3HNWHRiYb5K7" rel="nofollow" target="_blank">APL2 In Depth</a></p><p><br /></p><h3 style="text-align: left;">Adding an APL Keymap to X terminals</h3><p>From X (any windowed terminal, eg. Konsole, xfce4-terminal etc.)</p><p>--</p><p>My preferred setup uses CAPS LOCK as the APL key:</p><p><span style="font-family: courier;">setxkbmap us,apl -option grp:caps_switch</span></p><div><br /></div><div>Try the above interactively, then put it into your .bashrc and you're good to go. If you *really* need CAPS LOCK for some reason, ALT+CAPS works.</div><div><br /></div><div>One might also be able to define it system-wide via an xorg.conf.d/ file such as the following snippet, but I haven't rebooted yet to test it:</div><div><br /></div><div><div><span style="font-family: courier;">Section "InputClass"</span></div><div><span style="font-family: courier;"><span style="white-space: pre;"> </span>Identifier<span style="white-space: pre;"> </span>"system-keyboard"</span></div><div><span style="font-family: courier;"><span style="white-space: pre;"> </span>MatchIsKeyboard<span style="white-space: pre;"> </span>"on"</span></div><div><span style="font-family: courier;"><span style="white-space: pre;"> </span>Option "XkbLayout"<span style="white-space: pre;"> </span>"us,apl"</span></div><div><span style="font-family: courier;"><span style="white-space: pre;"> </span>Option "XkbModel"<span style="white-space: pre;"> </span>"pc104"</span></div><div><span style="font-family: courier;"><span style="white-space: pre;"> </span>#Option "XkbVariant"<span style="white-space: pre;"> </span>",dvorak"</span></div><div><span style="font-family: courier;"><span style="white-space: pre;"> </span>Option "XkbOptions"<span style="white-space: pre;"> </span>"grp:caps_switch"</span></div><div><span style="font-family: courier;">EndSection</span></div></div><div><br /></div><h3 style="text-align: left;">APL Keys For 'dfns' (lambdas)</h3><div><br /></div><div>Dyalog APL and GNU APL both use the ⍺ and ⍵ symbols for the unbound left- and right-hand variables of 'dfns' (basically lambda functions). These are standard for both APL dialects, but GNU APL also recognizes <i>APL Functional Symbol alpha-underber</i>, ⍶:U+2376, <i>APL Functional Symbol omega-underbar</i>, ⍹:U+2379 and lowercase Greek <i>chi</i>, χ<i>:</i>U+03C7.</div><div><br /></div><div>On my Dell XPS 15 laptop, it seems using the CAPS key as the APL COMPOSE in combination with the SHIFT key does not work for the W/S/X key column. So I chose the U and C keys as alternates to yield <i>omega-underbar</i> and <i>chi</i>, respectively, instead, as Dyalog and GNU APL don't appear to have anything assigned to those with SHIFT. Modifications to my .Xmodmap are thus as follows:</div><div><br /></div><div><span style="font-family: courier;">keycode 25 = w W U2375 U2379</span></div><div><span style="font-family: courier;">keycode 38 = a A U237A U2376</span></div><div><span style="font-family: courier;">keycode 30 = u U U2193 U2379</span></div><div><span style="font-family: courier;">keycode 53 = x X U2283 U03C7</span></div><div><span style="font-family: courier;">keycode 54 = c C U2229 U03C7</span></div><div><br /></div><div>.. and yet on my Acer Aspire, keys W and X work just fine. Weird.</div><div><br /></div><div>To customize your X modmap (be sure you've already added the ,apl to your xkbmap above):</div><div><span style="font-family: courier;">$ xmodmap -pke >~/.Xmodmap</span></div><div><span style="font-family: courier;">$ vi .Xmodmap ## editing the above</span></div><div><span style="font-family: courier;">$ xmodmap ~/.Xmodmap # To reload</span></div><div><br /></div><div>Download my .Xmodmap keymap file here:</div><div><br /></div><div><a href="https://www.blitter.com/nextcloud/index.php/s/bPz2NxpKyAPosqN">https://www.blitter.com/nextcloud/index.php/s/bPz2NxpKyAPosqN</a></div><h3 style="text-align: left;">APL Linux Console Key Map</h3><p><br /></p><p>Download my console keymap file here: </p><p><a href="https://www.blitter.com/nextcloud/index.php/s/9oY7pEbDZeiZNfq">https://www.blitter.com/nextcloud/index.php/s/9oY7pEbDZeiZNfq</a></p><p><br /></p><p>As root,</p><p><span style="font-family: courier;"># loadkeys APL.kmap</span></p><p><br /></p><p>Almost the same as the X mapping -- CAPS LOCK and shift+CAPS LOCK are combo keys with any other key in the GNU APL mapping for APL symbols; right-ALT is APL-mode lock.</p><p>APL fonts require running within an 'fbterm' on virtual consoles, so install that first, and if you want to use APL from the console often, start 'fbterm' and 'loadkeys' from startup.</p><h3 style="text-align: left;">GNU APL on Android with TermUX</h3><h3 style="text-align: left;"><span style="background-color: inherit; font-family: inherit; font-size: small; font-weight: normal;">* open TermUX.</span></h3><h3 style="text-align: left;"><span style="background-color: inherit; font-family: inherit; font-size: small; font-weight: normal;">* Make sure you have lots of free space on your phone, as you're going to be building GNU APL from source using g++</span></h3><h3 style="text-align: left;"><span style="background-color: inherit; font-family: inherit; font-size: small; font-weight: normal;">$ apt-get install subversion</span></h3><h3 style="text-align: left;"><span style="background-color: inherit; font-family: inherit; font-size: small; font-weight: normal;">$ apt-get install g++</span></h3><h3 style="text-align: left;"><span style="background-color: inherit; font-family: inherit; font-size: small; font-weight: normal;">## might need autotools and other things as well (automake, autoconf, etc.)</span></h3><h3 style="text-align: left;"><span style="background-color: inherit; font-family: inherit; font-size: small; font-weight: normal;">$ svn checkout svn://savannah.gnu.org/apl $ cd apl/trunk</span></h3><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;">You may have issues with network timeouts checking out the repo. If so, retry after running an svn cleanup. if you keep having trouble, fetch it on a PC Linux machine, tar+gzip the whole svn/trunk dir and then use 'scp' to just copy it to your TermUX home dir (either by installing openssh in TermUX or using an Android ssh program... but you'll have to hunt around in your phone's filesystem to find your TermUX home dir in that case...)</span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;"><br /></span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;">[Again, within TermUX]:</span></p><pre style="border-radius: 2px; border: 1px solid rgb(230, 230, 222); margin-bottom: 0.357143em; margin-top: 0.357143em; overflow: auto; padding: 4px 9px;"><code style="border-radius: 2px; border: 0px; display: block; line-height: 1.42857em; margin: 0px 2px; padding: 0px; word-break: normal;"><span style="background-color: inherit; font-family: inherit;">$ apt-get install ncurses pcre pcre2
$ cd trunk/ # wherever gnu apl source from svn was fetched
$ ./configure
$ make
$ mkdir $HOME/bin
$ cp src/apl $HOME/bin
$ export PATH=$HOME/bin:$PATH ## or set up a .bashrc or .profile with this to make it permanent
</span></code></pre><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;"><br /></span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;">.. I might have missed a few apt-get calls required for some libraries but otherwise it did build just fine right on the phone!</span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;"><br /></span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;">Oh, and remove the svn/trunk afterwards because you'll probably be low on space :)</span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;"><br /></span></p><p style="line-height: 1.42857em; margin: 0.357143em 0px; padding: 0px;"><span style="background-color: inherit; font-family: inherit;">Finally, install the fork of Hacker's Keyboard with APL layout/language available <a href="https://github.com/dzaima/hackerskeyboard/blob/master/java/java.apk" target="_blank">here</a>!</span></p>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-44501181778945586262021-01-16T13:18:00.006-08:002021-01-16T13:29:26.678-08:00Locking Linux X Sessions without XScreensaver<p> I'm currenlty using Funtoo Linux on my main laptop, and XScreenSaver was displaying a big scary warning "This version of XScreenSaver is very old! Please upgrade!". It turns out the author of XScreenSaver is, shall we say, <i>very opinionated</i> about downstream distros modifying this warning in any way -- though the codebase itself is allegedly free for downstream to modify, if this particular warning is touched by downstream the XScreenSaver author has <a href="https://groups.google.com/g/linux.debian.bugs.dist/c/ItL6xJm5nNc" target="_blank">insisted the program be removed entirely</a>, said author even protesting a commonsense modification to the warning to redirect users first to the specific distribution for bug reports.</p><p>Normally I don't care so much about OSS drama, but this warning timebomb just seems antisocial. I don't care much about screensaver functionality, I just want simple session locking and the warning was bugging me. So I went searching and surprisingly there are not many other options for X session locking that aren't tightly bound to specific widget families. There's Gnome-screensaver, some built-in lock with KDE, and then there's the most neutral setup I found so far: <a href="https://i3wm.org/i3lock/" target="_blank">i3lock</a> launched from <a href="https://www.freshports.org/x11/xautolock/" target="_blank">xautolock</a>.</p><p>Depending on your desktop it takes a bit of manual setup but it's not too hard. For my XFCE4 setup, what worked for me is:</p><p><br /></p><p>1. Create a script (remember to <span style="font-family: courier;">chmod u+x</span>) named <span style="font-family: courier;">autolock.sh</span> in <span style="font-family: courier;">~/.config/autostart-scripts/</span></p><p style="text-align: left;"><span style="font-family: courier;">#!/bin/bash<br /></span><span style="font-family: courier;">/usr/bin/xautolock -time 10 -locker "/usr/bin/i3lock -c 303030" &<br /></span><span style="font-family: courier;">sleep 1<br /></span><span style="font-family: courier;">pgrep xautolock && notify-send -u normal -t 4000 "xautolock active"</span></p><div><br /><div>2. Now set that script to auto-run on login, by creating a new entry called in the <span style="font-family: courier;">XFCE4 Settings > Session and Startup</span>, <span style="font-family: courier;">Application Autostart</span> tab.</div><div><br /></div><div>3. Set a keyboard shortcut eg., for Super-L, in <span style="font-family: courier;">XFCE4 Settings > Keyboard</span>, <span style="font-family: courier;">Application Shortcuts</span> tab, calling <span style="font-family: courier;">i3lock</span> (use the -c option for a custom colour if you don't like the default white screen).</div><div><br /></div><div>Log out and log in, and verify <span style="font-family: courier;">xautolock</span> is running -- that's it!</div><div><br /></div></div>DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-83718610359595258622019-03-26T19:58:00.002-07:002021-11-29T23:51:48.221-08:00Using HTTP Basic Auth (with Logout!) in a Go ApplicationHTTP Basic Auth (<a href="https://en.wikipedia.org/wiki/Basic_access_authentication">Wikipedia</a>) is a thing that is actually still quite useful despite its neglect in modern web standards. By neglect, I mean that it hasn't been updated since its introduction in <a href="https://tools.ietf.org/html/rfc7617" target="_blank">RFC7617</a> and as such the logout mechanism hasn't been improved to take into account modern browsers' tendency to aggressively cache session data within the HTTP headers, which is where the login state is stored. However, with some tricks it still can reliably be used in modern browsers. But some Javascript is required, sorry :(<br />
<div>
<br /></div>
<div><b>
First, a note: don't even consider using HTTP basic auth in your public-facing page unless you have it served behind an HTTPS reverse proxy!</b> The username and password sent to and fro from client to server is in plaintext by default, and only HTTPS with TLS will guarantee that the entire request including the critical HTTP headers are encrypted.</div>
<div>
<br /></div>
<div>
Given that caveat, here is a complete minimal example of using HTTP basic auth to gate access to a Go http app.</div>
<div>
<br /></div>
<div>
<a href="https://play.golang.org/p/2rRaQY3Iu3f" target="_blank">Go Playground Example</a> <-- this won't work in the Playground -- copy and build locally</div>
<div>
<br /></div>
<div>
FAQ</div>
<div>
<br /></div>
<div>
Q: <i>Go's http lib supports TLS to serve out endpoints. Why didn't you just do that instead of serving out an HTTP app behind a reverse proxy?</i></div>
<div>
A: HTTP basic auth seems to be mutually exclusive with the HTTPS protocol. Perhaps I missed something. Let me know if I'm wrong, and how to do it. Thanks.</div>
<div>
<br /></div>
<div>
Q: <i>How do I support multiple users/roles using the example you give?</i></div>
<div>
A: No idea. I think it could be done, with auxiliary logic to track separate session users/passwords, but this is left as an exercise for the reader. [<i>Meaning, like all my college profs ... I forget/I can't be arsed to work it out right now.</i>]</div>
<div>
<br /></div>
<div>
-R.</div>
<div>
<br /></div>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-32764986972357004202019-03-06T17:17:00.006-08:002021-11-30T00:00:52.809-08:00bacillμs - a simple build automation server written in GoMost non-trivial software projects that do rapid releases use a build automation server. One of the most popular solutions for this is Jenkins. There are many others.<br />
<br />
<div>
While Jenkins is easy to install and use in my experience, I wanted to learn some others to broaden my expertise, like Concourse <a href="https://concourse-ci.org/">https://concourse-ci.org/</a> or buildbot <a href="https://github.com/buildbot">https://github.com/buildbot</a>. The former turned out to be hellish to install and I burned a few evenings hitting many head-scratching dead-ends in the start up config; forums were filled with users asking the dev team for updated installation instructions, met with brusk dismissals if one wanted to use it outside of the dev-blessed containers (ie., use our black box, never mind how it really works). The latter, while easier to get up and running in a 'hello world' configuration, seemed difficult to configure further into a real-world setup. It seemed to me that these things, in general, are overly complicated.<br />
<br /></div>
<div>
So, in a fit of insanity I wrote my own simple build automation server in Go. No containers, java VM, or dependencies.. Use whatever scripting language you want. Total line count is under 1k.</div>
<div>
<br />
Of course, it's nowhere near production quality, and probably violates every go coding standard there is, but it does the essential things one might expect: responding to git triggers or webhooks from web-based systems like <a href="http://gogs.io/">gogs.io</a> or <a href="https://gitlab.com/">gitlab</a>, a web dashboard, viewing of running and completed jobs and their artifacts. Jobs may be scheduled (externally via cron), or launched manually from the dashboard. Jobs can be parameterized, with a simple but powerful form notation to allow int, string, and boolean job parameters. Build artifacts are archived and browseable from the dashboard. There's even a simple way to display stages of a job's run in the live view, aka a simple 'pipeline' status.</div>
<div>
<br />
<a href="https://gogs.blitter.com/Russtopia/bacillus/src/master/README.md">https://gogs.blitter.com/Russtopia/bacillus/src/master/README.md</a></div>
<div>
<br />
Suggestions welcome.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-g-Rv-vCKOWo/XzdUwGqjp-I/AAAAAAAA_U4/j864s1En80EGVHjhOA1GmRbHccESDiU2ACLcBGAsYHQ/s1118/20200814-bacillus1.png" style="margin-left: 1em; margin-right: 1em;"><img alt="bacillus main dashboard" border="0" data-original-height="820" data-original-width="1118" height="293" src="https://1.bp.blogspot.com/-g-Rv-vCKOWo/XzdUwGqjp-I/AAAAAAAA_U4/j864s1En80EGVHjhOA1GmRbHccESDiU2ACLcBGAsYHQ/w400-h293/20200814-bacillus1.png" title="Bacillus minimalist build/CI server" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div dir="ltr" style="background-color: white; color: #222222; font-family: arial, helvetica, sans-serif; font-size: small;">
<br /></div>
</div>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-76609154533728214592018-06-08T21:14:00.001-07:002018-06-08T21:14:55.065-07:00Obscure git issue: git push hangs silently on un-writeable reposMaking this blog post as a note mostly to myself; but since I couldn't find a posted solution elsewhere, this might also help someone else encountering a 'git push hangs' issue...<br />
<br />
<u>Situation</u>: Recently installed Gogs (<a href="https://gogs.io/">https://gogs.io</a>), an <b>awesome</b> github-style self-hosted web service, written in Go. I have a bunch of repos already in <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/var/git/</span>, and didn't want to move them (or make it appear they hadn't moved) to preserve the ability to use <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">go get</span> (<a href="https://dangerruss-things.blogspot.com/2018/04/export-go-packages-via-go-get-from-your.html" target="_blank">see this post about setting that up</a>) and raw command-line git without changing the repo URIs everywhere they were already checked out on remote systems.<br />
<br />
To put some of these repos under the purview of Gogs, yet keep them visible in <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/var/git/</span><span style="font-family: inherit;">,</span> I made soft symlinks in <span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">/var/git/</span>, moving the actual repos in question to<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/home/git/gogs-repositories/<user>/<repo>.git</span>. By default, these will have permissions allowing git (and the Gogs web app) to manage the repo, eg:<br />
<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">drwxrwxr-x 6 git git 4096 Jun 8 20:48 go_login.git</span><br />
<div>
<br /></div>
<div>
However, since these were my legacy repos, for the above reasons the symlink at the location in <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/var/git/</span> is owned by another user and I didn't want the git user dedicated to Gogs owning things there, outside of the git user's home tree.</div>
<div>
<br /></div>
<div>
As it turns out, if the owner of the symlink in <span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">/var/git/</span> pointing to the moved repo within <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/home/git/gogs-repositories/</span> doesn't have write permissions to the repo, <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">git push</span> will just silently hang after one supplies ssh:// credentials.</div>
<div>
<br /></div>
<div>
<u>Solution</u>: Add the legacy user to group <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">git</span>, and add group write permissions to all repos linked to in this way in <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/home/git/gogs-repositories/</span> .</div>
<div>
<br /></div>
<div>
This was a head-scratcher, since <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">git-daemon</span> writes <i>nothing</i> to <span style="font-family: Courier New, Courier, monospace; font-size: x-small;">/var/log/daemon.log</span> indicating an issue, at least on my setup -- perhaps <span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">git-daemon</span> can be made to be more verbose?</div>
<div>
<br /></div>
<div>
-R.</div>
<div>
<br /></div>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-22106757358717381252018-04-24T10:36:00.000-07:002018-06-08T23:58:44.172-07:00Export Go Packages via 'go get' From Your Own Server<h2>
Self-Hosting Go Packages With Support For <i>go get</i></h2>
<br />
<blockquote class="tr_bq">
[NOTE: Since originally posting I've clued in that what's documented here is only one way of achieving what's commonly referred to as 'vanity URLs' or 'vanity imports'. Adding this note here just to help anyone searching find this post more easily. -R.]</blockquote>
<br />
Go has a really neat package import tool, <i>go get</i>, to fetch packages from upstream sources into one's own local $GOPATH package tree. The 'big' sites like github.com, gitlab.io and others support use of <i>go get</i> from their project hosting spaces, which is cool, but they charge extra for hosting private code repos, or having more than a small fixed number of contributors, or other annoying limitations. Understandably these sites need some way to monetize their cloud offerings but for individuals or those with their own infrastructure there should be other ways that don't depend on the 'cloud' (ie., someone else's servers).<br />
<br />
While the collaborative aspects of these sites and web-based features are their main draw (encouraging public pull requests for distributed development), perhaps you or your company want the convenience of using <i>go get</i> for your own repositories, but don't want to entrust your code repositories to one of these external entities.<br />
<br />
<blockquote class="tr_bq">
Note: If you're considering moving off of github and self-hosting your repos, consider <a href="https://gogs.io/" target="_blank">Gogs.io</a>. It's really easy to set up and feels very familiar if you're used to github. Also, see my <a href="https://dangerruss-things.blogspot.com/2018/06/obscure-git-issue-git-push-hangs.html" target="_blank">other post</a> for notes on how to let Gogs.io refer to your legacy repos whilst preserving traditional access to your old repos in their original locations. </blockquote>
<br />
The <i><a href="https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies" target="_blank">go get</a></i> command and its <a href="https://golang.org/cmd/go/#hdr-Remote_import_paths" target="_blank">import mechanism</a> is described in the go command documentation, but to be frank, the docs for the go import mechanism aren't too clear on exactly how to set up one's own server to support it. One can't just <i>go get</i> a repo that is available via <i>git clone</i> without a lot of setup first.<br />
<br />
<h3>
Basic requirements:</h3>
<ul>
<li>Proper DNS 'A' record info for your package server</li>
<li>A common webserver (ie., apache v2 is used here but others are supported)</li>
<li>HTTPS enabled (ie., a properly-configured, authority-signed server cert -- sorry, self-signed won't work)</li>
<li>The git-http-backend helper tool (included with most git distributions)</li>
<li>Properly configured web server rewrite rules for calling git-http-backend when requests from <i>go get</i> are seen by your server</li>
</ul>
<br />
<br />
All these bits need to be set up 'just so' for the <i>go get</i> command to work smoothly, and the go docs don't really spell out the full setup, probably due to the myriad platforms and web servers out there.<br />
<br />
I'll show here my setup, which isn't the most common, but should with ease adapt to other systems: Funtoo Linux + Apache v2. With some path adjustments this should apply to Ubuntu and other popular Linux distros.<br />
<br />
I pieced together this tutorial from the following sources:<br />
<br />
<a href="https://askjong.com/howto/automatically-enable-https-on-your-website-with-effs-certbot-deploying-lets-encrypt-certificates">https://askjong.com/howto/automatically-enable-https-on-your-website-with-effs-certbot-deploying-lets-encrypt-certificates</a><br />
<a href="https://kasunh.wordpress.com/2011/01/15/git-over-https/">https://kasunh.wordpress.com/2011/01/15/git-over-https/</a><br />
<a href="https://www.creang.com/howtoforge/howto_set_up_git_over_https_with_apache_on_ubuntu/">https://www.creang.com/howtoforge/howto_set_up_git_over_https_with_apache_on_ubuntu/</a><br />
<br />
I also studied the verbose output of <i>go get -d -v</i> to see just what the command was assuming when it tried to fetch things.<br />
<br />
<h3>
Basic Theory of 'go get'</h3>
<br />
The <i>go get</i> command works over SSH, HTTP or HTTPS, though it refuses to use plain HTTP unless one specifies the -insecure flag. This means generally you'll want to get your server's HTTPS cert setup working to avoid having to specify this every time, and, in the case of private repositories, to protect your proprietary source code from travelling over the open internet whenever <i>go get</i> is run.<br />
<br />
The tool looks for files with special <meta> tags, which specify where to redirect the partial URI given by the <i>go get</i> command to the <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">git-http-backend</span> tool. In this way, one can store the actual repositories nearly anywhere on the system and move them around, without breaking the package URI published to users.<br />
<br />
<i>go get</i> can fetch packages contained in each <meta> tag via either the ssh:// or https:// protocols. The ssh:// protocol will require a shell account on the hosting server for each of your contributors -- they'll be prompted for their password before <i>go get</i> will proceed to pull anything. This is good for private groups wishing to share both read (pull) and commit (push) access. For public repos or projects where you want team members to submit patches via other means like email or an external review tool, the https:// method is appropriate -- however it will require a web server with valid authority-signed cert to allow HTTPS.<br />
<br />
<h3>
Proper DNS 'A' record setup</h3>
<br />
You'll need to ensure your domain allows proper HTTP/HTTPS access with the bare domain (ie., foo.com should redirect to www.foo.com). <i>go get</i> and package imports in go source code expect just a domain name, not a host.domain syntax, eg. the Go source import statement<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">import "example.org/go/mylib"</span><br />
<br />
... implies one has previously performed<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$ go get example.org/go/mylib</span><br />
<br />
... which expects the server at <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">example.org</span> to resolve web requests with no host prefix. If you serve regular web content from the same server, you'll probably already have an 'A' record for <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">www.example.org</span>, but <i>go get</i> will require an 'A' record also for plain <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">example.org</span>. While you're doing this you might as well add a permanent redirect from example.org to <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">www.e</span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">xample.org</span> if you don't already have it.<br />
<br />
Check your DNS configuration (if you control it yourself) or ask your admin to ensure there's an 'A' record for <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">example.org</span> which maps to the same IP address as <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">www.e</span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">xample.org</span>. Sometimes this is named the '@' entry.<br />
<br />
<h3>
Apache modules required: mod_rewrite, mod_cgi, mod_alias, mod_env</h3>
<br />
The web server needs to do some URL rewriting and CGI operations in order to send <i>go get</i> requests to <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">git-http-backend</span> (ie., fetching git repos with the http:// or https:// prefix). For this you'll need to ensure the following Apache modules are enabled:<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">mod_rewrite, mod_cgi, mod_alias, mod_env.</span><br />
<br />
Enable the above modules by adding LoadModule directives in whatever manner your server expects, eg., /etc/apache2/httpd.conf; then add the following <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">.htaccess</span> rule to your web root (mine, using apache2, is in <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/var/www/localhost/htdocs/.htaccess</span>):<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteEngine on</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteBase /</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteCond %{HTTP_HOST} !^www\. [NC]</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]</span><br />
<br />
This rule rewrites requests of the form<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">http://example.org/foo</span><br />
<br />
to<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">http://www.example.org/foo</span><br />
<br />
<br />
<h3>
Configuring RewriteRule to allow proper <meta> tags per-repo</h3>
<br />
Now you need to somehow let Apache distinguish regular web traffic from 'go get' queries, which implicitly look for files served with a <meta> tag that is unique per package.<br />
<br />
I experimented for a while without success, adding multiple <meta> tags, one for each repo, to my webroot's index.html <head> section, until I realized that 'go get' was only looking at the <b>first</b> <meta> tag it found. It turns out 'go get' expects there to be only one <meta> tag in a file, so each exported go package must have its own file with its own <meta> tag.<br />
<br />
The solution is not to put <meta> tags into the webroot index.html at all, but rather to use another mod_rewrite rule to distinguish 'go get' requests by the repo name and point them to a unique URL for each. These URLs should reside within a subfolder of the webroot.<br />
<br />
Add this line to the .htaccess file in your webroot (see 1. above, mine was <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/var/www/localhost/htdocs/.htaccess</span>):<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteRule ^go/(.*)$ pkg/$1 [QSA]</span><br />
<br />
The [QSA] means (I think) 'Query String Append', which keeps any CGI-style GET<br />
params in the original URL and puts them back onto the end of the re-written<br />
URL, which may be important for 'go get' as it sends a '?go-get=1' param for its own purposes.<br />
<br />
Now, with the above rule, let's say you have a file structure like this in your webroot:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/var/www/localhost/htdocs/pkg/</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/var/www/localhost/htdocs/pkg/foo</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/var/www/localhost/htdocs/pkg/bar</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/var/www/localhost/htdocs/pkg/private-baz</span><br />
<div>
<br /></div>
.. and git repositories served by your git-daemon in /var/git/foo.git, /var/git/bar.git, and /var/git/private-baz.git. You can set up files in the webroot that contain <meta> tags pointing to each:<br />
<br />
[/var/www/localhost/htdocs/pkg/foo]<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><meta name="go-import" content="example.com/go/foo git https://example.com/git/foo"></span><br />
<br />
[/var/www/localhost/htdocs/pkg/bar]<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><meta name="go-import" content="example.com/go/bar git https://example.com/git/bar"></span><br />
<br />
[/var/www/localhost/htdocs/pkg/private-baz]<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><meta name="go-import" content="example.com/go/private-baz git ssh://example.com/var/git/private-baz"></span><br />
<div>
<br />
The files themselves don't need to be html files. They can be text files with just the <meta> tag.<br />
<br />
NOTE 1: In the examples above, each <i>go get</i> exported repo is within a go/ subdirectory. This is required to give the apache2 server a pathname root to 'hook onto' for its RewriteRule, otherwise there's no way to tell other requests within your web server's URI space apart from ones specifically meant for <i>go get</i>. The sub-directory doesn't need to be named 'go', it could be anything; just as github places repos under your username, eg. github.com/ThisUser/that-repo.<br />
<br />
NOTE 2: make sure your git-daemon has --export-all, or a file named <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">git-daemon-export-ok</span> in each public git repo. Test with regular git clone commands to verify each is fetchable before trying to use <i>go get</i> with <meta> tags. Repositories exported with ssh:// appear to use the <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">git-daemon-export-ok</span> file when determining whether a repo is available via <i>go get</i>, whilst ones exported in the <meta> tag via https:// listen to the Apache SetEnv statements (see below) which set the export permissions, since they're being served via the <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">git-http-backend</span> helper rather than via ssh.</div>
<br />
<h3>
More on Public vs. Private Package Repos</h3>
If you have some private packages that are not yet ready for the public eye, make note of the above example: the repo named 'private-baz' was exported in the <meta> tag via ssh://, not https://, so it will ask for authentication via ssh (password, phrase or host-key).<br />
<br />
Exporting via <meta> tags, but using ssh:// in the git repo URI, doesn't require your webserver to have HTTPS set up, but will require the -insecure flag to 'go get' to convince it to even fetch the <meta> redirection info so it's still annoying and worth going full HTTPS on your webserver even if you're not publishing anonymous read (pull) go packages.<br />
<br />
Finally, note the ssh:// URI for git repos usually has a slightly different path than git:// or https:// read-only URIs (note the /var/git/ path component in the third private-baz repo).<br />
<br />
You can even serve out multiple users' repos via 'go get' this way, since using git with the ssh:// (git+ssh) URI syntax lets a git-daemon otherwise configured to serve public repos from /var/git or wherever, to also serve out individual users' private repos from their home dirs. For example I have<br />
public repos in my /var/git/ and private repos in ~user/git/, and both can be served to the 'go get' command via appropriate <meta> tags defined as above, with private ones doing authentication as expected.<br />
<br />
<h3>
git-http-backend Setup</h3>
<br />
In your main apache2 config (eg., httpd.conf or similar) add this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SetEnv GIT_PROJECT_ROOT /var/git</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SetEnv GIT_HTTP_EXPORT_ALL</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteCond %{QUERY_STRING} service=git-receive-pack</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">#[OR]</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">#RewriteCond %{REQUEST_URI} /git-receive-pack$</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><LocationMatch "^/git/"></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> #apache 1.x# Deny from env=AUTHREQUIRED</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> AuthType Basic</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> AuthName "Git Access"</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Require all granted</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> #apache 1.x# Require group committers</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> #apache 1.x# Satisfy Any</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"></LocationMatch></span><br />
<br />
<br />
<h3>
LetsEncrypt</h3>
<br />
Now, after all of the above, I discovered <i>go get</i> refuses to import packages with a self-signed<br />
cert! What a pain.<br />
<br />
If you don't already have HTTPS with a certificate-authority signed cert on your server, you'll need to get one. Either consult your business IT department for the server hosting all of this, or set up EFF's <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">certbot</span> utility. Thankfully the EFF has made it relatively easy for regular people to get a free certificate with valid signing for personal servers.<br />
<br />
On Gentoo or Funtoo, the steps to install a LetsEncrypt cert are (as root):<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># emerge app-crypt/certbot app-crypt/certbot-apache</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">#</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># certbot certonly --webroot -w /var/www/localhost/htdocs/ -d example.com -w /var/www/localhost/htdocs/ -d www.example.com</span><br />
<br />
Now, verify the Apache configuration from all previous steps and restart the web server:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># apache2ctl configtest</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># rc-config restart apache2</span><br />
<br />
Now test out your fancy <i>go get</i>-able package server!<br />
<br />
[from some other host or account]<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$ go get example.com/go/foo</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$ ls $GOPATH/src/example.com/go/foo</span><br />
<br />
This is the minimum setup just to get HTTPS working with Apache v2 for your primary domain, to make <i>go get</i> happy. If you have multiple 'vhost' domains or other complex requirements, you're on your own.. I'm still trying to get my server to server full HTTPS for all of the domains it hosts.<br />
<br />
<h3>
</h3>
<h3>
Conclusion</h3>
While the <i>go get</i> command is the preferred way for golang programmers to fetch external packages into their working $GOPATH tree, the documentation is not extremely helpful in setting up all of the server-side bits that are required to support it. Individuals or organizations may want a mixture of public (read-only) as well as private/group read/write (pull/push) repos exported via <i>go get</i> without the risks or costs associated with hosting via an external party.<br />
<br />
A self-hosted golang package server supporting the standard <i>go get</i> command can be implemented by configuring a webserver with proper type 'A' domain records, HTTPS plus a valid authority-signed certificate, proper git-http-backend tool configuration, URL rewrite rules and package export <meta> tags placed within the webroot on a per-package basis.<br />
<div>
<br /></div>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-36994483344970002152017-05-28T22:54:00.000-07:002018-05-06T21:36:17.192-07:00Avoiding Mysterious "Permission denied" Errors During Windows Development: Check Your Services!This is a short post to answer a question I've seen go un-answered, or incorrectly answered, on at least three major programming forums.<br />
<br />
If, while developing on Windows (regardless of IDE or programming tool), you can compile your program the 'first time' -- in Eclipse, mingw, golang, whatever -- and run it, but the next compile/run cycle you get "Permission denied" from the linker -- check that you don't have the "Application Experience" service disabled. It must be set to Manual, Automatic, or Automated (delayed start)... just <i>not</i> Disabled. Otherwise you'll experience this issue, regardless of language, compiler, or IDE, at least on Windows 7.<br />
<br />
If you're like me you might be in the habit of turning off all sorts of Windows Services on your personal machines to minimize the background crap going on. It's always a matter of tuning to determine what's <i>really</i> required and what isn't. For programming with rapid edit/build/run/debug cycles, it's common to run into the permission issue described above.<br />
<br />
I have no idea (nor does anyone else, it would seem --Microsoft isn't telling on its own forums) exactly <i>why</i> this service must be enabled to prevent the OS from locking a recently-terminated program executable on disk.<br />
<br />
Perhaps (and this is a wild-ass guess), due to the way Application Experience monitors programs, to report if they crash, there's some other OS component in Windows that is waiting for a handshake from the Application Experience service before letting the executable be removed. This might make sense if one needs to send dumps of the .exe or something as part of a crash report.<br />
<br />
Anyways... no one elsewhere has reported a definitive answer to this, so I'm noting it here mostly for myself, for posterity. I've run into it at least 3 times on various Windows systems doing development and it's highly annoying. Usually it's been a few years since I set up my box and I've forgotten how I solved it the last time...<br />
<br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-41408404202325663932015-11-26T19:30:00.000-08:002018-11-09T10:19:49.788-08:00ZINK hAppy Printer Setup on Windows 7ZINK Imaging Inc. makes some neat devices, the hAppy and hAppy+, which are basically super-fancy labelmakers. From what I understand the company was founded by refugees from Kodak after they shut down the Polaroid division, just after they had developed a cool new digital version of the Polaroid process.<br />
<br />
I picked up a hAppy printer on eBay a while ago, thinking it might be neat as an alternative way of producing my c@rd password gen/recall cards. The fact the device can print directly onto shiny peel 'n stick labels, in multiple widths, is quite nifty. The widest roll is 2" (50mm) which just so happens to be nearly the width of a credit card.<br />
<br />
While it's marketed at the craft market (think soccer moms and kids' birthday parties), it could be put to use in so many other ways. The manufacturer's site and installation instructions are focused completely on its AirPrint capabilities: printing from a smartphone via iOS or Android over WiFi, using their proprietary apps (which, to be honest, are pretty good for the craft market -- easy to use and lots of neat clip art to get designs done quick for those birthday parties, weddings and craft parties).<br />
<br />
However, I want to use it to print my own stuff, from a laptop at a mobile kiosk, using my own algorithmically-generated security cards.. I can do it from the smartphone but it requires a lot of manual fiddling with resizing/cropping in their phone app, even though my c@rd generator app spits out fully-specified, sized images ready for printing. I even encode the exact print size in the EXIF data so it should really be 100% automated.<br />
<br />
The only issue was that ZINK doesn't officially ship or publish *any* Windows USB drivers! The hAppy printer has a microUSB port, so I wondered if it could just act as a regular printer.<br />
<br />
Turns out, the answer is YES. ZINK didn't help one iota, though. Multiple emails to their tech support just went into a black hole. They've either already moved onto the next product line, or just have no real humans watching their emails. Perhaps they're already going bankrupt, who knows. Bad customer support anyways.<br />
<br />
Lots of info on the 'net about using the ZINK range with Apple's AirPrint is out there; which leads one to believe that the ugly Apple iTunes software (which for some gawd-awful reason is the only official way to obtain AirPrint capability on Windows!?) is the path to printing bliss here.. but it is NOT the right solution. Don't put that crap on your machine, it's a dead end for this device; I managed to get my Windows 7 PC to 'see' the hAppy via Wifi, but it wouldn't print anything, just giving obscure errors in the print spool manager.<br />
<br />
So... this device shows up in Windows 7 (64-bit) upon initial plug-in via USB as a generic 'Unspecified' entry in Control Panel\All Control Panel Items\Devices and Printers. You'll see a blank box labelled just 'hAppy Printer', in the 'Unspecified' Section below 'Printers and Faxes'. That means it's showing up as a USB device, but Windows doesn't yet know how to print to it.<br />
<br />
Right-clicking into Properties, you'll see the usual device Properties dialog, with the usual buttons -- except that 'Update Driver', 'Disable', 'Uninstall', etc. are greyed out. The only one available is 'Driver Details', so click that and you'll also see it says no drivers have been installed for the device. Not promising.<br />
<br />
<a href="http://4.bp.blogspot.com/-Rh0TZi4mOyA/VlfLyaPMeDI/AAAAAAAAW30/xIZ6G8tOzDc/s1600/shot0-0.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-Rh0TZi4mOyA/VlfLyaPMeDI/AAAAAAAAW30/xIZ6G8tOzDc/s320/shot0-0.jpg" width="260" /></a>However, Windows has a little-known class of support drivers, 'USB Printing', which sit beneath more specific vendor printer drivers. And, it turns out, ZINK does in fact have a Windows USB driver for this printer! It's just not published anywhere outside of Microsoft's Windows Driver database. So... the only way to get this installed is to go through the Control Panel:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-nVnNrkek8mc/VlfLyhzURtI/AAAAAAAAW38/NQmMjHuwG7g/s1600/shot1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="258" src="https://4.bp.blogspot.com/-nVnNrkek8mc/VlfLyhzURtI/AAAAAAAAW38/NQmMjHuwG7g/s320/shot1.jpg" width="320" /></a></div>
<a href="http://4.bp.blogspot.com/-0y9-5Q6GYFo/VlfLyuL_SzI/AAAAAAAAW34/FseUd9xNGy4/s1600/shot0-1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="226" src="https://4.bp.blogspot.com/-0y9-5Q6GYFo/VlfLyuL_SzI/AAAAAAAAW34/FseUd9xNGy4/s320/shot0-1.jpg" width="320" /></a><br />
1. In Control Panel -> Devices and Printers, choose 'Add a Printer'.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
2. Choose 'Local Printer', and change the dropdown beside 'Use and Existing Port' from LPT1: to USB00x: (whichever one is there; if you have an existing printer it might be USB002: or USB003: or higher.. )<br />
<br />
3. Click Next. If the next dialog doesn't have a
manufacturer named 'ZINK' in the left pane, you need to click 'Windows
Update' and wait about 5 minutes (or longer!). It eventually will come
back, and ZINK will be hopefully new in the left pane's list of
manufacturers.<br />
<br />
<br />
<br />
<br />
4. Choose 'hAppy' from the printer list on the
right pane. DO NOT choose 'hAppy XPS', (not that I've tried it, but XPS
is a virtual printer driver, which we don't want -- unless you want to
print to files for later physical printing.)<br />
5. Complete the
wizard and now in the Control Panel -> Devices and Printers, you
should now see your new 'ZINK hAppy' in the Printers and Faxes Section.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-HC1qe34Sq5Q/VlfLy2SoFkI/AAAAAAAAW4I/-HxL89lRlYk/s1600/shot2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://1.bp.blogspot.com/-HC1qe34Sq5Q/VlfLy2SoFkI/AAAAAAAAW4I/-HxL89lRlYk/s320/shot2.jpg" width="320" /></a></div>
Now,
printing to labels using Windows Explorer's default right-click ->
Print will work. You'll have to fiddle with setting default Printer
Preferences, setting a Custom paper size preset to match the width of
your roll, and so on (I'll write details of that later if anyone cares
-- it's a bit fidgety, but relatively straightforward). Be mindful of
the print dialog's 'Scale to Fit' settings etc. which will affect the
printout size. With two or three tries I was able to come up with
presets that printed out at my expected size. The 'Kiss Cut' vs. 'Full
Cut' setting didn't seem to make any difference, however -- the hAppy
always auto-chopped my print after it was done, which was a bit
annoying, but no biggie.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-nmXJ-pP1YMg/VlfLzKnfUHI/AAAAAAAAW4E/3AksdaQlNwg/s1600/shot3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://1.bp.blogspot.com/-nmXJ-pP1YMg/VlfLzKnfUHI/AAAAAAAAW4E/3AksdaQlNwg/s320/shot3.jpg" width="320" /></a></div>
Strange that ZINK hasn't
officially published that this driver is available; it seems to be
relatively complete, enough so that they submitted it to Microsoft's
official driver database. It seems aware of all of the device's settings
(normal vs. Vivid print mode, roll widths, etc.). It even reports the
remaining roll length, so it seems to be the real deal.<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-sa75mMBGbNc/VlfLzHySAjI/AAAAAAAAW4M/uWST5L2lO30/s1600/shot4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://1.bp.blogspot.com/-sa75mMBGbNc/VlfLzHySAjI/AAAAAAAAW4M/uWST5L2lO30/s320/shot4.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-XVVK1vq_ylc/VlfLznNdfCI/AAAAAAAAW4k/bk5lyYjaCOY/s1600/shot5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://4.bp.blogspot.com/-XVVK1vq_ylc/VlfLznNdfCI/AAAAAAAAW4k/bk5lyYjaCOY/s320/shot5.jpg" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-8duW69uRiuE/VlfLzl3W_dI/AAAAAAAAW4g/PmqBch70GSo/s1600/shot6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="234" src="https://3.bp.blogspot.com/-8duW69uRiuE/VlfLzl3W_dI/AAAAAAAAW4g/PmqBch70GSo/s320/shot6.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-PH-QTOgu4I4/VlfLzj6bbyI/AAAAAAAAW4c/AyXsRsmE9ng/s1600/shot7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://2.bp.blogspot.com/-PH-QTOgu4I4/VlfLzj6bbyI/AAAAAAAAW4c/AyXsRsmE9ng/s320/shot7.jpg" width="320" /></a></div>
<br />
Finally... <a href="https://drive.google.com/open?id=18PXSkUGdc2i_f8fq9mTMU8OwYz6OQCRo" target="_blank">here's the driver (7zip archive) for windows 7 x64.</a>. As Admin, extract to C:\Windows\System32\DriverStore\FileRepository.<br />
<br />
[Link updated 2018-11-09]<br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com29tag:blogger.com,1999:blog-8185950750958800815.post-38596444131198539942014-07-18T09:23:00.003-07:002014-07-21T10:37:47.076-07:00Google Yanks Yet Another Useful Feature with No Warning: Labs "Add any gadget by URL"Boo Google, boo.<br />
<br />
Well, if anyone needed another example of why it's just a bad idea to rely on Google APIs for anything important, here's another one. Today I saw a teensy note appear at the top of my gmail announcing the Labs "Add any gadget by URL" gadget is being deprecated.<br />
<br />
I used this feature to developer my "Hashcash mint" gadget, and it's the easiest way to add such gadgets to the sidebar in one's gmail. <br />
<br />
I've sent them feedback asking what migration strategy one should use and how exactly someone is supposed to embed gadgets in their gmail page now.. I hopefully will hear back within the next few days.<br />
<br />
Perhaps I need to look further into the OAuth2 system or something; but I fear the response will be something like "Port it to a Chrome extension" (which I've already done, but that's not cross-browser is it?).<br />
Anyone else know of APIs which allow embedding of one's custom gadgets into pages like GMail, Calendar etc. without using some kind of Google walled-garden to host them?<br />
<br />
---<br />
<br />
EDIT: No response yet.. the entire Google Developers section on
gadgets is woefully out-of-date. I submitted about 4 support requests
relating to dead links, missing sections, and just plain <b>wrong</b> info. Sigh. I get the feeling the entire gadget API has been left out to die, at least for people outside of Google.<br />
<br />
Well if so, I'm glad I've only written one Google gadget and chrome extension, rather than investing more effort. Google just drives away devs by constantly deprecating things willy-nilly.DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-74720127300616500682014-01-11T21:52:00.000-08:002015-05-21T18:48:51.892-07:00mt-crypt - a simple stream cipher based on the Mersenne Twister PRNGIt's often said: "Anyone can write a crypto algorithm they can't break themselves". True enough, but that doesn't mean it should be forbidden to study or write crypto software because, well, one isn't an expert in studying or writing crypto software -- that would be a Catch-22 of sorts.<br />
<br />
What's the entry point then, for someone who wants to understand? One learns by doing.<br />
<br />
In light of the Snowden leaks of 2013 I think it's time that writing crypto became something to be encouraged rather than discouraged. Treating crypto software as a 'read-only' institution can't work -- <a href="http://blog.cryptographyengineering.com/2013/09/the-many-flaws-of-dualecdrbg.html">we simply cannot trust a few blessed experts</a> to write <a href="http://blog.0xbadc0de.be/archives/155">our crypto libraries and utilities for us</a>. People outside of the shadowed halls of three-letter agencies must gain their own expertise, or at least become familiar enough with the concepts to ask intelligent questions, look for backdoors and weaknesses, try to apply new defenses to what should be private data, and just generally not be passive victims.<br />
<div>
<br />
It has become more important than ever that there be a diversity of implementation, and that programmers who might have been hesitant before to write crypto programs <i>start doing so</i>.</div>
<div>
<br />
I'm not saying one should apply any ol' system to important data. Algorithms must be carefully examined by many eyes to look for problems and determine the real security of any new system. But if everyone's afraid to write new systems, there won't be very much to examine, and not enough alternatives to keep those who would spy on us off-balance.<br />
<br /></div>
<div>
<b>If the NSA's goal was/is to subvert the most prevalent cryptosystems, it makes sense to ensure there are no prevalent cryptosystems</b>. We need to take the side of the mythical Hydra, whose winning strategy is to grow two heads for each one cut off, making things even harder for the attacker.<br />
<br />
To do this, we all need to better understand just what strong crypto is and how to implement it so there are more choices for everyone to use, and <b>no 'master key'</b> -- <b>no 'most popular solution'</b> -- for those that would spy indiscriminately on us all by exploiting a single weakness. If the haystack cannot adequately hide the needle, we need to throw on a lot more hay, and add a few million more needles in there. If the opponent's resources are superior, an open battlefield no longer is tenable and we must use guerilla tactics -- divide and conquer, stay in small groups, change routines constantly.<br />
<br />
[<i>OK I'm done with the metaphors... and I'm probably on all the watch lists now :/</i>]</div>
<div>
<br /></div>
<div>
With the above in mind, I started reading about alternative, non-NIST algorithms to see what's out there and how I might implement my own crypto utilities. I started out trying to implement a standard block cipher along the lines of DES or AES, trying to understand what S-boxes (substitution) and P-boxes (permutation/confusion) did, and how to use them.<br />
<br />
Most block ciphers use multiple rounds of (<a href="http://en.wikipedia.org/wiki/S-box" target="_blank">S-box</a>, <a href="http://en.wikipedia.org/wiki/Permutation_box" target="_blank">P-box</a>) manipulations, one followed by the other applied in multiple rounds with some sort of <a href="http://en.wikipedia.org/wiki/Key_schedule" target="_blank">key schedule</a>, to achieve an invertible transformation. Lots of arcane math goes into S-box design which made me a bit queasy.. I still need to learn a lot about that before I'm confident about designing such a thing.</div>
<div>
<br /></div>
<div>
Another big worry with block ciphers is the problem of padding. If you're trying to use a block cipher on files, or when encapsulating packets, the file as a whole, or each packet's payload, may not be a multiple of the blocksize; so the ciphertext must be padded somehow to be a multiple of the blocksize. There are 'padding oracle' attacks that make it dangerous to use block ciphers unless one understands the block padding issues completely. See <a href="http://www.limited-entropy.com/padding-oracle-attacks/">here</a> or <a href="http://robertheaton.com/2013/07/29/padding-oracle-attack/">here</a> for some good explanations on how one can 'unzip' an encrypted CBC-mode block train if the padding scheme is known. Indeed, having <i>any</i> predetermined format or structure outside of the ciphertext itself can open things up to oracle attacks it seems.</div>
<div>
<br /></div>
<div>
So a stream cipher seems to be a safer entry point for learning and research for a would-be crypto programmer. A stream cipher doesn't encrypt a block at a time, rather it's a byte- or bit-oriented system that can handle arbitrary-length data. There is no concept of a blocksize, and thus no opportunity or temptation to introduce 'meta-data'. Usually this requires a 'cryptographically-secure PRNG' (pseudo-random number generator); that is, one that is very hard to predict so long as the seed (which is mathematically derived from the key) isn't known.<br />
<br />
A cryptographic PRNG must meet a much higher standard for randomness and non-predictability than the 'usual' PRNGs used in standard libraries and games...</div>
<div>
<br /></div>
<div>
I knew of the <a href="https://en.wikipedia.org/wiki/Mersenne_Twister">Mersenne Twister</a> (MT), a really good PRNG with an astoundingly huge period (2^19937-1). That sounded like a good candidate, but the literature says even that isn't cryptographically-secure enough, since despite a long period it still is subject to prediction attacks given enough PRNG output. The authors of MT wrote a paper addressing this, with an ingenious and simple scheme to harden the use of MT -- this consists of two things: a) a non-linear transformation on the PRNG output, and b) throwing away most bits of the PRNG output before combining with the plaintext. It would seem this makes it very hard indeed to know the state of the PRNG and to predict its output as used with a stream cipher.<br />
<br />
A distinguisher is still plausible (see <a href="http://cr.yp.to/streamciphers/cryptmt/080.pdf">here</a>), but no one has published a full-on key recovery attack as of yet and the researchers make no assertion that this is even possible from the distinguisher. The so-far-theoretical attack lets one determine that a stream of ciphertext likely is using Mersenne Twister as its underlying PRNG by observing 2^50 bits of contiguous ciphertext.<br />
<br />
Now that's still a lot of data -- 2^47 bytes. Though some claim this cipher is 'broken' in the pure cryptographic sense, it seems it would be perfectly salvageable if one were to re-seed conservatively.<br />
<br />The idea would essentially be to re-seed on some interval between
every 2^8 and 2^24 bits (2^16 to 2^32 bytes), based on the PRNG stream
itself; thus a sort of (perfect-?)forward secrecy on the reseed schedule
would be maintained (an attacker would need to first predict the MT
output itself to know when the next re-seed would occur; but they shouldn't be able to do that, since the re-seeding
would always occur at much less than 2^50 output bits).<br />
<br />
The simplicity of the cryptMT stream cipher seems compelling unless someone proves otherwise and the authors' follow-up algorithm, crypMTv3, is much more complex from a design and code perspective (they focused on speed-ups for SIMD instruction sets, which is nice but I'd rather have a simpler algorithm). Crypto designers want security, but as we've learned from the recent Heartbleed fiasco, we also want <i>simplicity</i> of design. Complexity introduces the very real possibility of flaws that undo all other efforts.<br />
<br />
[Note to self: the attack described in the above paper talks about LSBs of the 8 MSBs of the accum output. Perhaps some kind of xor-with-parity of the internal cryptMT accum value could further obfuscate the LSB to harden against this attack, or using multiple MT generators with divergent seeds and states, combining them via XOR, could make it infeasible to predict a single MT stream state?]<br />
<br />
<br />
<a name='more'></a><br /><br />
<br />
<br />
<br />
<h2>
UPDATE: More attacks on mt19937</h2>
<br />
<a href="http://b10l.com/reversing-the-mersenne-twister-rng-temper-function/">http://b10l.com/reversing-the-mersenne-twister-rng-temper-function/</a><br />
<br />
If
624 consecutive output values can be obtained unmodified from the PRNG,
its state can be reconstructed by 'inverting the temper function'.<br />
<br />
<a href="http://www.math.sci.hiroshima-u.ac.jp/%7Em-mat/MT/efaq.html">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/efaq.html</a><br />
<br />
The
mt19937 author suggests combining 8 or more output values using some
sort of secure hashing algorithm in order to throw away some info to
thwart such attacks when using as a CSPRNG.<br />
<br />
<br />
<br />
<a href="https://code.google.com/p/mt-crypt/">I have published a very simple implementation on google code named mt-crypt</a> (no re-seeding yet -- I'll be adding that shortly). Since the original paper doesn't specify details to an RFC level (or at least for mere mortals like myself it wasn't obvious) it would seem that things like how a key is expanded (when required) to initialize the MT state buffer are left up to the implementer. If there are other implementations of cryptMT out there, I claim absolutely no compatibility with them.<br />
<br />
<span style="color: #cc0000;"><b>Again,do not use this for sensitive data!</b></span> If you are really daring, use it but re-encrypt with AES, Blowfish or some other algorithm before or after. You might as well just use those by themselves though at that point, unless you just enjoy teasing your hopefully-imaginary stalkers by wasting their time a bit more :p.<br />
<br />
When testing any cipher algorithm it's important to analyse the randomness and entropy of the resulting ciphertext output. Such analysis can be done using various tools such as:<br />
<br />
<br />
<ul>
<li><a href="http://sourceforge.net/projects/randstdev" target="_blank">Randstdev</a></li>
<li><a href="http://www.google.ca/url?sa=t&rct=j&q=ent%20random&source=web&cd=1&ved=0CCgQFjAA&url=http%3A%2F%2Fwww.fourmilab.ch%2Frandom%2F&ei=Gp32Uq3NDaH7yAGSt4CQCw&usg=AFQjCNH-2sicFHTUKXNfARkvspFS2JkhYA&sig2=glQzDBaJGBb5kQDiSQe1kw&bvm=bv.60983673,d.aWc" target="_blank">John Walker's Ent</a></li>
</ul>
<div>
<br /></div>
<br />
Edit: Another paper by the MT authors about possible attacks: <a href="http://www.ecrypt.eu.org/stream/papersdir/083.pdf">www.ecrypt.eu.org/stream/papersdir/083.pdf</a><br />
<br />
Edit: A description of a 'version 3': of MT: <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/cryptMT3-book1.pdf">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/cryptMT3-book1.pdf</a><br />
<br />
They also mention a replacement for MT, "Hearty Twister" from 2005, but all I could find is a paper from 2006, with mention of replacing MT with "Pulmonary MT" [Aha, I get it. Japanese translation: 'Hearty' == 'Pulmonary']: <a href="http://www.ecrypt.eu.org/stream/papersdir/2006/023.pdf">http://www.ecrypt.eu.org/stream/papersdir/2006/023.pdf</a><br />
<br /></div>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-90859919888896989212013-11-27T09:17:00.003-08:002013-11-27T09:18:22.904-08:00Gmail Hashcash Notifications To Your PhoneGmail Inbox Setup for Hashcash Notifications To Your Phone<br />
<br />
If you install my <a href="http://dangerruss-things.blogspot.ca/2013/06/hashcash-for-gmail.html" target="_blank">Hashcash for Gmail</a> google script to scan & validate your incoming email according to the presence or absence of hashcash stamps, and you just want notifications for verified emails coming in, you can tweak how the inbox notifies you on your mobile phone. Here's one possible setup:<br />
<br />
It's quickest to set this up from the desktop:<br />
<br />
<ol>
<li>From the gmail web interface Gear->Settings</li>
<li>Inbox tab</li>
<li>Inbox type 'Priority'</li>
<li>For Inbox sections 1-4, Options->Remove Section</li>
<li>Redefine Inbox section 1. Options->More Options...->Show All From Label [#$]</li>
<li>Save Changes</li>
</ol>
<br />
Then on your Android phone, configure Gmail:<br />
<ol>
<li>Menu->More->Settings</li>
<li>Account Settings->[your email address]</li>
<li>-Check Priority Inbox (make default for this account)</li>
<li>-Labels to Notify</li>
<li> ->Inbox: off</li>
<li> ->Priority Inbox: off (was: [subtle, always, notify for every msg])</li>
<li> -> [#$]: [subtle, always, notify for every msg]</li>
</ol>
<span style="color: #cc0000;"><b>NOTE:</b> This is a pretty strict set-up in the respect that you won't get notifications for anything that doesn't have a valid Hashcash stamp.</span> Not too useful until most people in your local network also are using Hashcash. That's the problem with network effects.. the usefulness of a thing only becomes apparent once many people are using it together.<br />
<br />
If you look into Gmail's Priority inbox rules it's a pretty powerful way to tailor how/when you get notifications.<br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-48905555337451562582013-11-18T23:15:00.004-08:002021-11-29T23:47:28.385-08:00Tugging at the chains 'twixt myself and The Cloud[Otherwise, less poetically-entitled: <a href="http://www.salon.com/2013/11/04/googles_nsa_outrage_correct_and_hypocritical/" target="_blank">Screw you, NSAGoogle</a>. I'll make my own damn webmail, with blackjack and hookers. Thing is, I actually -want- the webmail too. Really.]<br />
<br />
2013-11-18: experiments setting up my own webmail server with IMAP and (eventually) OSS webmail client access<br />
<br />
Part I: The MTA and IMAP service (<a href="http://www.dovecot.org/" target="_blank">dovecot</a>), plus <a href="http://www.mozilla.org/products/thunderbird" target="_blank">Thunderbird</a> client access [DONE]<br />
Part II: Webmail client for easy access anywhere (TODO)<br />
Part III: End-to-end encryption using clients in (I) and (II), for anyone (TODO.. and non-trivial, I know)<br />
<br />
1. Exim4:<br />
* just install using debian defaults<br />
* edit /etc/exim4/update-exim4.conf.conf for your smarthost<br />
(a smarthost is an SMTP server that will relay mail for you; usually<br />
smtp.<your_isp> -- note many ISPs these days don't allow any outgoing email<br />
even from their own customers' IP blocks. Complain bitterly to them that they're<br />
breaking the internet, not that it will do any good... other than some cathartic anger on your part. Then go find another provider, if you can.)<br />
<br />
2. Get an IMAP server:<br />
apt-get install dovecot-imapd dovecot-sqlite dovecot-pop3d<br />
<br />
* Nice! Top of /etc/dovecot/dovecot.conf:<br />
"If you're in a hurry, see<a href="http://wiki2.dovecot.org/QuickConfiguration" target="_blank"> http://wiki2.dovecot.org/QuickConfiguration</a>"<br />
<br />
2.1. Configuring dovecot<br />
2.1.1 Authentication<br />
* [Further research here is required. I ended up using the default 'passwd-file'<br />
accounts rather than 'passwd' account auth which would use PAM to match against<br />
the system user accounts. It's safer to use 'passwd-file' anyways since that<br />
means users' email accounts don't have to use their shell accounts.]<br />
<br />
2.1.2 Mailbox setup/privileges<br />
* My deb system appears to use 'mail' group for /var/mail, so I set<br />
mail_privileged_group = mail,<br />
#! mbox_very_dirty_syncs = yes<br />
#! maildir_very_dirty_syncs = yes<br />
.. in /etc/dovecot/conf.d/10-mail.conf<br />
<br />
2.1.3 IMAP Compatibility Options<br />
* Since I like Thunderbird, enable the following IMAP workarounds<br />
in 20-imap.conf:<br />
imap_client_workarounds = tb-extra-mailbox-sep tb-lsub-flags<br />
<br />
2.1.4 SSL setup<br />
* Consider after getting things going, enabling SSL. Generate a self-signed cert<br />
using Dovecot's doc/mkcert.sh script (see _SSL_ link)<br />
** NOTE SSL is required by default, you have to set disabled_plaintext_auth = no<br />
otherwise!<br />
<br />
i) Go to http://wiki2.dovecot.org/SSL/CertificateCreation<br />
ii) Download the two files doc/mkcert.sh (or find in the downloaded dist files),<br />
and doc/dovecot-openssl.cnf<br />
iii) Edit dovecot-openssl.cnf to match your site install; also edit mkcert.sh<br />
itself if you want to lengthen/shorten cert expiry and/or the name of the<br />
generated cert (default: /etc/ssl/private/dovecot.pem)<br />
<br />
2.1.5 IMAP account (server-side): see http://wiki2.dovecot.org/AuthDatabase/Passwd<br />
Default appears to be 'passwd-file' which sets up a separate username/pass DB for<br />
IMAP access. One could set up 'driver = passwd' to use the server's local user<br />
accounts, but that would also grant shell access (usually). Probably a good idea<br />
if setting up a public server to use the default.<br />
<br />
i) edit /etc/dovecot/conf.d/auth-passwdfile.conf.ext<br />
Set scheme=SHA512-CRYPT<br />
ii) $ doveadm pw -s SHA512-CRYPT -u <username><br />
iii) cut and paste the resulting string into /etc/dovecot/users<br />
iv) edit /etc/dovecot/conf.d/10-auth.conf<br />
auth_mechanisms = plain login (? Not required apparently)<br />
(default install only has 'plain')<br />
<br />
3. Get a desktop or web-based mail client. I went through a few here:<br />
x IlohaMail - obsolete, the whole domain is gone, even though it's still a package in<br />
Debian repos and written in PHP4. So, no docs. Doesn't support POP-over-SSL or other<br />
encrypted auth schemes due to its age; too bad, it was easy to install. -REJECTED-<br />
x <lots of other webmail clients, too complicated to get going> -REJECTED-<br />
x <RoundCube? Still need to evaluate><br />
x <MailPile? Looks promising, actively developed but very incomplete. They are working<br />
on integrated PGP/GPG support, perhaps a post-Snowden emphasis on e2e-crypto? Hope!><br />
x .. or a desktop mail client such as Thunderbird.<br />
Thunderbird Account Settings:<br />
Server Settings: Server Type: IMAP Mail Server<br />
Server Name: <server hostname><br />
User Name: <username> (without @domain.tld)<br />
Security Settings: Connection security: SSL/TLS<br />
Authentication method: Normal password (?)<br />
Outgoing Server (SMTP): Description: (your choice)<br />
Server Name: <smtp smarthost server hostname><br />
Port: 25 (** NOTE default is 587, won't work!)<br />
Sec. and Authentication:<br />
Connection security: None<br />
Authentication method: No authentication<br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-42270305428137728262013-09-23T19:29:00.008-07:002020-12-18T02:48:52.655-08:00Hello World Blinky for ezSBC2 LPC1347 in AssemblerDoing things the hard way sometimes is the best way to learn. I've been meaning to learn some embedded ARM-fu for years, and just never got around to it since AVRs are just so darn easy (or familiar, in my case).<br />
<br />
I like using a simple text editor and command-line toolchain but since most ARM vendors have wrapped up all the details of their chip startup in wizards within their huge IDEs, it's a pain to figure out just what's happening and what is required to bootstrap a given chip.<br />
<br />
For my experiment, I chose the LPC1347 microcontroller from NXP, on a simple board called the <a href="https://www.ezsbc.com/product/ezsbc2/" target="_blank">ezSBC2</a>. This chip has a neat built-in ROM that makes the chip virtually unbrickable -- pull a certain pin on power-up and the chip appears as a USB flash drive, and you just paste in a new 'firmware.bin' file with your code, reset and it's reprogrammed. Couldn't be simpler.<br />
<br />
However, it took me two full nights' worth of searching online to find any kind of 'Hello World' reset startup code for the LPC134x chips. The best I could find was some for the related LPC1766, which was close enough for me to eventually figure it out. See below for download. I had to modify the startup.S, main.S and linker script to fit the LPC1347 memory map and peripheral registers.<br />
<br />
One thing that isn't spelled out anywhere is that the Cortex-M chips are <i>very</i> different from traditional ARM chips in a lot of ways; for instance, the vector table isn't composed of branch instructions -- it's just a list of absolute addresses, like the old 68000 (and at vector 0x0, just like the 68000, is the initial system stack pointer value). They also don't have nearly as many contexts as traditional ARM (IRQ, FIQ, etc.). I'm still reading up on all the differences but it makes bootstrap code for 'standard' ARM totally inapplicable.<br />
<br />
As for NXP-specific differences: not mentioned explicitly on ezSBC's website, but buried in the lpc1347 user manual, is the fact that one must put a 32-bit checksum in the first reserved vector 0x1C to validate the code. Otherwise the USB programmer won't accept the firmware.bin file. I've included a quick and dirty C program in the ZIP file below to patch up the binary after linking.<br />
<br />
<a href="https://drive.google.com/open?id=1BaB8t_2H9Tva_JK44Cu6Rv3uKzlDOTSu" target="_blank">Hello World Blinky in Assembler for ARM Cortex-M3 NXP lpc1347</a><br />
<br />
<a href="https://www.ezsbc.com/product/ezsbc2/" target="_blank">ezSBC2 ARM board</a><br />
<br />
<a href="https://www.nxp.com/docs/en/user-guide/UM10524.pdf" target="_blank">NXP lpc13xx User Manual</a><br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-32733387422267194902013-08-23T00:09:00.002-07:002022-10-20T20:32:15.107-07:00Resurrecting the OS-9/68K (OSK) kernel using the FAME 68K Emulator<div class="tr_bq">
<span style="color: #cc0000;">** NOTE ***</span><br />
<span style="color: #cc0000;"><br /></span>
<span style="color: #cc0000;">I know the code linked here has been broken for some time. Apparently the FAME emu, or (more likely) my abstraction on top of it, does not boot OS-9 properly on x86_64 Windows. I do intend to look into the issue (really!) but have been swamped by 'real life' the last while. I appreciate your patience; please check back periodically to see if I've finally fixed this to work on modern x86_64 Windoze installations and hopefully Linux, where I'm spending more time nowadays. -rlm</span><br />
<br />
The Motorola 68000, sadly, is mostly a relic nowadays. It had a beautiful instruction set and a clean architecture, from software all the way down to the bus protocols. Alas, all good things must pass...</div>
<br />
However, there was a <i>damn good</i> operating system written for this CPU which I <i>just can't stand</i> to see die slowly, rotting on lost floppy discs and SCSI drives. The OS of which I speak is the OS-9 RTOS by Microware: a microkernel which was originally written for the Motorola 6809 CPU as a contract from Motorola to showcase their new CPU (most famously used on the <a href="https://en.wikipedia.org/wiki/Tandy_Color_Computer" target="_blank">Tandy Color Computer</a>, various <a href="https://en.wikipedia.org/wiki/UniFLEX" target="_blank">GIMIX</a> systems, the <a href="https://en.wikipedia.org/wiki/Sharp_X68000" target="_blank">Sharp X68000</a> series in Japan, and the <a href="https://en.wikipedia.org/wiki/Fairlight_CMI" target="_blank">Fairlight/CMI</a> synthesizers of the early 80s), then ported to the Motorola 68k series of processors, the x86, ARM and Hitachi SH series, amongst others.<br />
<br />
This operating system has been really short-changed by history. Ask most programmers which consumer (non-mainframe/UNIX/'big-iron') system was able to do multitasking and/or timesharing; you'll usually get answers of the Commodore Amiga, or the PC, or the Mac. They're all wrong. OS-9 was doing this in 1979, before the Commodore 64 <i>even existed</i>, with a full-fledged UNIX-style shell environment and all of the flexibility that philosophy brought with it, in less than 64 kilobytes!<br />
<br />
The folks at Microware really should be legends in the industry for their forward-thinking software. Applications, device drivers, the kernel, and even instances of devices were all <i>modules</i> using an object-based structure that could be configured at boot time, then subsequently reconfigured at run-time, as modules were added or removed, with <i>no</i> reboots. Hmm, it only took, what, twenty-plus years, for other mainstream desktop operating systems to achieve this (and imperfectly)?<br />
<br />
With that in mind, I now place here a small lifeline for this amazing operating system in the hopes it will be preserved (and perhaps improved...)<br />
<br />
OS-9/68k 'RUSSBOX' Emulator Proof of Concept<br />
<br />
This uses the FAME/68K emulation library under Cygwin to boot an OS-9 68000 'idealized' abstract system of my own design (by 'abstract', I mean a system which doesn't correspond to any 'real' historical system and is as simple as possible for the purpose of booting OS-9).<br />
<br />
--<br />
<span style="font-family: "courier new" , "courier" , monospace;">BUILDING AND RUNNING THE RUSSBOX OS-9/68K (TEST EMULATION):</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">Requirements</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">--</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Windows XP or Win7_x86 (32-bit)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">cygwin (32-bit)</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">From the cygwin prompt in your home directory: </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$ git clone git://tripe.blitter.com/os9_68k_sdk_v12.git MWOS</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">$ cd MWOS</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[This gives the pristine MWOS OS-9/68k port dev tree, sans Hawk UI cruft, etc.]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">$ git checkout origin/rlm-sys-1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[This switches to a branch which adds the virtual 'RUSSBOX' support files:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> MWOS/OS9/68000/PORTS/RUSSBOX - plus some .d/.a files to support the virtual</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> hardware in higher directories within MWOS/...]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$ git submodule add git://tripe.blitter.com/rlm-sys-1.git \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> MWOS/OS9/68000/PORTS/RUSSBOX/rlm-sys-1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[This is the emulator itself, using FAME 68k library]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$ cd OS9/68000/PORTS/RUSSBOX</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$ . ./mwos_env.sh</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">[open a second cygwin terminal]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">$ cd MWOS/OS9/68000/PORTS/RUSSBOX/rlm-sys-1/</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">$ stty -echo -icanon -icrnl -inlcr min 1 && nc -u 127.0.0.1 8800</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">[return to first cygwin terminal]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">./run.sh</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">[switch to second cygwin terminal]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[press ENTER]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[You should see a RomBug: prompt.]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[Type [.],[ENTER] to see 68k registers]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[Type [g],[ENTER] to start boot]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[After a few seconds you should see the OS-9 '$' prompt.]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">[Type some common OS-9 commands, eg 'devs', 'free', 'mdir', 'dir']</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">NOTES</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">The backspace/del key doesn't work.. the terminal via UDP is primitive and the exact setup for 'stty' above can probably be improved to at least let through delete properly.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">Typing CTRL-C on the OS-9 terminal also terminates the stty connection, rather than transmitting CTRL-C through to the OS-9 target.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">** NOTE after typing CTRL-C to interrupt the UDP terminal, one must type blindly:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">stty echo</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">.. to turn on echo for the cygwin shell again.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">Eventually I would like to write a dedicated UDP terminal + emulator 'front panel' that can pass all ascii codes through properly, and integrate in other ways with the virtual target (such as some way to show the virtual framebuffer, I/O, etc.)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">While rudimentary this serves as a demonstration that the FAME/68k emulation library is sufficiently accurate to fully bootstrap and run the OS-9 68000 kernel and as such we can preserve the OS-9/68k operating system in an environment which will never be subject to the ravages of time, dying hardware etc. :)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">rlm-2013-08-22<br /></span><br /><br />UPDATE<br /><br /><br />
<div>
For posterity and my own records, I am adding below the notes I made years ago on how to backup an RBF (disk) device from an OS-9/68000 machine to a Windows box over serial line via Kermit or ZModem. This was the best solution in my experience for imaging OS-9 disks, with the minor drawback that it requires a working OS-9/68000 box. Linux (and AFAIK Windows/DOS) really don't like 256-byte sector formats, so it's difficult to do from 'the other side'.</div><div><br /></div><div>---</div><pre data-pm-slice="0 0 []"><code>HOWTO: Transfer OS-9/68k disk images to a remote system
This HOWTO describes the procedure for transferring raw disk images from an
OS-9/68k system to another computer over serial port.
Hardware Required:
1. OS-9/68k target with one functioning serial port
2. Remote system with a terminal program and zmodem capability (I used
Windows XP and ‘teraterm pro’)
Gathering information
First you must know the format of your OS-9 target’s disks.
[TODO: Quote microware /u0, /d0, /pc0 formats common to many systems]
A utility not included with OS-9 distributions officially, but essential
for managing different disk formats, is ‘dmode’. It can be found on
os9archive.rtsi.com
[http://os9archive.rtsi.com/index.php/os-9-archive-new/file/3913-os-9-archive]
Example for the WCP306:
wcp:dir /hs0
Directory of /hs0 00:13:10
CMDS MODS OS9Boot SYS USR
WCP306.readme init.ramdisk startup
wcp:dmode /hs0
name=hs0
drv=0 stp=3 typ=$27 dns=$03 cyl=80 sid=2 vfy=0 (on) sct=32 t0s=32
sas=8 ilv=2 tfm=0 toffs=0 soffs=0 ssize=256 cntl=$0000 trys=0 lun=0
wpc=0 rwr=0 park=0 lsnoffs=0 totcyls=80 ctrlrid=0 rates=$30
scsiopt=$0000 maxcount=65535
wcp:
Transferring the raw disk image
On the OS-9/68k side, the ‘sz’ utility is used to send the output of the
disk’s raw data (using the OS-9 ‘@’ suffix on a device name to indicate raw
mode) via ZMODEM protocol.
Eg., from the OS-9 shell:
$ sz /hs0@
[OS-9 size will wait for connection from remote side]
Then in TeraTerm Pro, choose File->Transfer->ZMODEM->Receive.
The resulting file will be called ‘hs0@’ on the receiving side. That isn’t
ideal, so one can also use OS-9 pipes effectively to give the data stream
a more meaningful name:
$ list /hs0@ >/pipe/wcp306_os9v3.0_disk1of5_hs0.dsk &
$ sz /pipe/wcp306_os9v3.0_disk1of5_hs0.dsk
Or, using kermit in server mode on the OS-9 side and TeraTerm to get files
(bear in mind KERMIT is much slower than ZMODEM):
$ kermit -x -i
Then in TeraTerm, choose File->Transfer->KERMIT->Get...
and enter the raw filename of the disk (eg., /hs0@)
Here again, one would have to rename the downloaded file to something
meaningful before transferring another disk so as not to overwrite the last
transferred image.
One could also use the stock OS-9 ‘copy’ command with named pipes and tar to
send over serial, then use untar on the other end, or similar methods, to
transfer raw disk images. But ZMODEM has error correction, which is desirable
since serial comms can have errors that would otherwise go undetected.
To do a file-level (rather than sector level) copy of a disk device, one
could use tar on both ends to transfer the disk’s contents:
[From OS-9 side]
$ gtar cf /pipe/hs0.tar /hs0 #128k &
$ sz /pipe/hs0.tar
[On PC side, using TeraTerm Pro]
File->Transfer->ZMODEM->Receive</code></pre><div>---</div><div><br /></div>
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com56tag:blogger.com,1999:blog-8185950750958800815.post-89865387439594923432013-06-23T13:11:00.003-07:002021-02-14T12:28:15.355-08:00Hashcash for Gmail<br />
<div>
For more information about Hashcash, please see <a href="http://www.hashcash.org/" target="_blank">http://www.hashcash.org/</a></div>
<div>
<br />
For issues<a href="http://dangerruss-things.blogspot.ca/2013_06_01_archive.html#support"> see here</a>.</div><div><br />
<a href="http://www.blogger.com/null" name="privacy"></a>
Privacy Policy: This app uses GMail App APIs to access to your gmail inbox, to tag, filter and re-file emails. It does not store or save any personal information, nor send any info to external sources.<br />
<a href="http://www.blogger.com/null" name="tos"></a>
<br /></div><div>Terms of Service: This app offers NO WARRANTY or GUARANTEE OF FITNESS. USE AT OWN RISK. The author assumes NO responsibility for any effects, intentional or otherwise, on contents of your gmail inbox.</div><div><br /></div>
This page is for information on my experimental HashCash for GMail -- a combination of a Chrome extension (or google gadget plugin for gmail, blogspot or any other OAuth gadget hosting page) that generates Hashcash stamps for inclusion into emails you send. For maximum usefulness it should be paired with my nearly-ready google app script (which will also be published as a Chrome App) that scans incoming gmail messages and flags them accordingly by detecting these stamps.<br />
<div>
<br /></div>
<div>
The solution consists of two parts:</div>
<div>
<ul>
<li>The Hashcash Mint Chrome extension/google-gadget, which lets one generate a valid hashcash stamp from within the gmail web interface or from anywhere while running Chrome; and</li>
<li>The Hashcash for Gmail google app script, which runs periodically on your gmail inbox to scan for valid hashcash stamps and flag the emails accordingly.</li>
</ul>
</div>
<div>
Some readers may say: 'Doesn't gmail do an awesome job of detecting spam already? I used to think so, but their filters really started breaking down for me a few months ago. If someone can explain why that may be occurring, I'd appreciate an explanation. I'm sick of spam.</div>
<div>
<br />
<span style="font-size: large;">1. Installing the Hashcash Mint Google Gadget</span><br />
<br /></div>
<div>
<span style="font-size: small;">1a. For Non-Chrome Browsers [Firefox etc.]</span></div>
<div>
<ul>
<li><span style="font-family: inherit;">Enable 'Labs' in your gmail account (Gear icon->Settings->Labs) if it isn't already;</span></li>
<li><span style="font-family: inherit;">Enable the</span> 'Add any gadget by URL' feature;</li>
<li><span style="font-family: inherit;">Add the <a href="http://www.blitter.com/~russtopia/googlegadgets/hcgen.xml" target="_blank">Hashcash Mint gadget</a> </span>(url: http://www.blitter.com/~russtopia/googlegadgets/hcgen.xml)</li>
</ul>
You may have to reload gmail to see the gadget appear in your sidebar on the left. Google talk may mask the google gadgets area; in that case click on the ellipsis button at bottom left to switch to google gadget view.</div>
<div>
<br />
1b. For Chrome Browsers<br />
<br />
<ul>
<li>Just <a href="https://chrome.google.com/webstore/detail/hashcash-mint/jmhonnhjcgnalcfccloeiboaonkipmgi?hl=en-US" target="_blank">click here to install the extension</a>.</li>
</ul>
<br />
After clicking 'Mint' and the Hashcash stamp has been generated, you just hit CTRL-V in an email while composing to paste the just-generated stamp (the extension has the 'copy-to-clipboard' permission so it should do the 'copy' CTRL-C for you.)<br />
<br />
<span style="font-size: large;">2. Installing the Hashcash for Gmail App Script</span><br />
<br />
2a. For Non-Chrome Browsers [Firefox etc.]<br />
<br />
<ul>
<li><a href="https://script.google.com/macros/s/AKfycbwSMJLHgFH3Nc2CrUxtG3EtzLFw0jLMawox-2Tk88QunhJdeBk/exec">Visit this link and approve the app script</a>.</li>
</ul>
You likely require a Google account for this, but since this is intended for gmail you already have that, right? :)<br />
<br />
2b. For Chrome users: Installing the Hashcash for Gmail App<br />
<ul>
<li>Just <a href="https://chrome.google.com/webstore/detail/hashcash-for-gmail/hebebondpbkmimbfoffbbakdlaafjdge?authuser=0" target="_blank">click here to install the Chrome app</a>.</li>
</ul>
<br /></div>
<div>
<br />
Hashcash is an idea that really should have taken off by now.. but email servers and clients have never seemed willing to agree to implement it, which is a shame as it really could make spam nearly disappear -- if enough people would just use it!</div>
<div>
<br /></div>
<div>
So I hope to make this as easy to use as possible -- if you like it, please tell those you know to try using it too. If you're someone who knows how to write Outlook, Thunderbird or other email plugins, consider writing an equivalent to my Hashcash for Gmail inbox scanner for those mail hosts, so others can easily start using Hashcash!<br />
<br />
<br />
<a href="http://www.blogger.com/null" name="support"></a>
<br />
<h2>
Hashcash for Gmail -Support & Issues</h2>
</div>
<br />
Version 4 [2013-11-27]:<br />
<br />
<br />
<h3>
Issue</h3>
There appears to be a bug in the auto-registration of the
timed trigger in the mail scanner. The trigger is supposed to run once a
minute to scan for incoming mail with hashcash stamps.<br />
<br />
<br />
<h3>
Solution</h3>
<ul>
<li>Open chrome://apps and click on the "Hashcash for Gmail" icon;</li>
<li>Click on the "Disable" button which should change to "Enable";</li>
<li>Click on "Enable" again and it should change to "Disable"</li>
<li>Close the app.</li>
</ul>
<br />
The per-minute trigger should now be active and emails recently placed in your Inbox will be scanned and tagged accordingly.
DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-41619784902442487082012-03-05T20:13:00.001-08:002013-09-24T09:47:33.001-07:00More Useful References for SMD Package CodesI'd posted a while back about the subtleties of choosing SMD parts and the voodoo involved in interpreting those packages.. just thought I'd post some links here to some documents I found that might be worth saving and/or referring to in the future.<br />
<br />
<a href="http://elektronik.googlecode.com/files/SMD_Catalog222.pdf" target="_blank">The SMD Codebook</a> [<a href="https://docs.google.com/open?id=0ByNvoX1GE59_ZEtoRFBzSDBSOGlPbElNTmUyZW00Zw" target="_blank">cached copy</a>]: a good explanation of various packages and many, many tables of codes...<br />
<br />
<a href="http://www.marsport.org.uk/smd/mainframe.htm" target="_blank">The SMD Code Book</a>: not the same, note that space :) A nice HTML page with some diagrams and codes.<br />
<br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-19196671238950827962012-03-02T23:21:00.001-08:002023-03-18T03:09:21.555-07:00Dealing With Peak I/OAll right, it's been a while.. design blog fail. Mea culpa. But I'm finally getting around to doing some real work on this wireless AVR transceiver thingie and I had to solve a problem which is often encountered, but seldom well-discussed, so I thought it merited a new post.<br />
<br />
<b>Some background:</b> I'm designing a wireless transceiver, using a <a href="http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01P" target="_blank">way-cool chip</a> from Nordic Semiconductor. If I get this going, it'll be a much cheaper interface than any of the equivalent devices out there (I'm purposely being a bit coy about the exact application... who knows who's listening on the tubez).<br />
<br />
Anyway, I was reading through the datasheet for the above device, and suddenly <b><i>the doubt</i></b> crept into my mind. If you've designed boards before, you know what I mean: am I <i>really</i> hooked up to this thing correctly?<br />
<br />
I'm using an <a href="http://www.atmel.com/Images/doc2586.pdf" target="_blank">ATtiny85</a> for this project -- where I/O pins are at a premium -- so understanding the exact requirements of connectivity is essential.<br />
<br />
The <a href="http://www.nordicsemi.com/eng/content/download/2726/34069/file/nRF24L01P_Product_Specification_1_0.pdf" target="_blank">nRF24L01+ datasheet</a> has a nice state diagram that suggests that the CE line can be safely left high during operation, but some vague statements elsewhere in the document allude to the need for a low-high edge transition on CE to enter TX or RX mode from standby.<br />
<br />
So, with great trepidation I opened a support request to nordicsemi.com's experts and they replied that, yes, sadly, one MUST be able to toggle CE in order to properly transition to active TX or RX state from config or standby mode. Gyarrrrrrr. So what to do, with a measly ATTiny85 and only 5 I/O pins to allocate between CS/, SCK, MISO, MOSI, CE and a UART pin (that's 6 if you're counting along)?<br />
<br />
<i>Well, I thunk, and I thunk</i><br />
<i>And I thunk some more</i><br />
<i>Then I thunk until my thunker was sore.</i><br />
<br />
I wanted to introduce as little extra hardware and logic as possible, and <a href="http://dangerruss-things.blogspot.com/2011/11/dual-rate-uart-implemented-in-software.html" target="_blank">I'd already verified my split-rate software UART on the tiny 25/45/85</a> range -- and software UARTs are pretty tricky. I didn't want to do that <i>again</i> just for this project, on a different variety. AVRs vary quite a bit in their exact timer and IRQ configurations going between the tiny/classic/mega/etc. and while they're all capable, the devil is in the details.<br />
<br />
In situations like this, one must look at the signals and control-lines one has at one's disposal, and consider if there are mutually-exclusive conditions amongst those that can be taken advantage of. At certain times of operation, some control lines may be quiescent -- for instance, my system only occasionally needs to communicate using SPI, and the slave device will ignore any SPI line activity while the CSN line is de-asserted. The CE line needs to be kept asserted during at least the start of a TX operation and during an entire RX operation.<br />
<br />
My first idea was that the nRF24L01+ CSN (chip-select, negative logic) line and the CE (chip-enable, positive) could simply be the same line. The CSN line is only asserted during SPI read/write commands, and the CE is only asserted while one wants to transmit or receive. However, my board needs to be available, if possible, at all times while in receive mode, and that would mean keeping CE asserted at the same time as accessing the received Rx queue via SPI! As well, the nRF24L01+ requires that CE be asserted for some time prior to asserting CSN (2tdStby, around 150us). Darn.<br />
<br />
Alternatives that seemed viable:<br />
<br />
<u>1. Multiplex SPI MISO/MOSI lines into a single bidir DI/DO using 2 resistors (3-wire to 4-wire SPI)</u><br />
<br />
I considered making my SPI interface half-duplex, by using one of the MISO/MOSI pins of the AVR as GPIO and bit-banging SPI in both directions as two distinct phases; the first, as an output writing SPI command bits, then switching mid-transfer to an input to read the response. The other pin would be re-assigned to a dedicated CE control pin:<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-mrGxGHd3vzQ/T1G_m_PsWMI/AAAAAAAACAs/t4AHUNXOuL0/s1600/IMAG0098.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="183" src="http://3.bp.blogspot.com/-mrGxGHd3vzQ/T1G_m_PsWMI/AAAAAAAACAs/t4AHUNXOuL0/s320/IMAG0098.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">For theory see Nordic Semi's <a href="https://blitter.com/~russtopia/WP_Interface_SPI_nRF2401.pdf" target="_blank">app note for the older nRF2401</a></td></tr>
</tbody></table>
<br />
<br />
I think this would actually work rather well: in regular command transactions the nRF24L01+ STATUS register is returned simultaneously with the SPI master's sending of the command byte, which would not be readable in a single-duplex SPI setup, but the there is a discrete command to read the STATUS register itself as a regular config register.<br />
<br />
However, this setup would have the minor drawbacks of doing a separate SPI transaction just to get that status byte, and the major drawback of falling back to bit-banging rather than using the AVR's hardware SPI interface (slower SPI clock rate, more code). Finally, the hardware cost of two high-value resisters to interface the bit-banged half-duplex SPI data line to the nRF24L01+ full-duplex MISO/MOSI pair.<br />
<br />
Pros:<br />
- one pin released to be dedicated CE signal;<br />
<br />
Cons: <br />
- Loss of hardware SPI, reversion to bit-banging at a lower SPI rate<br />
- Larger codesize due to bit-banged SPI<br />
- Extra SPI transactions to retrieve nRF24L01+ STATUS register<br />
- two extra resistors to convert between 3-wire and 4-wire SPI <br />
<br />
OK, perhaps there is something else I could do...<br />
<br />
<u>2. Utilize SPI SCK line's IDLE state as CE Assert Signal Using Low-Pass Filter to Ignore SPI Activity</u><br />
<br />
In this scheme, the MISO/MOSI lines are left as-is, full-duplex SPI communication is maintained, and the CE line is controlled by keeping the SCK line high while idle. What about the SCK's frantic activity during actual SPI transfers? Wouldn't that cause the CE line to toggle as well, messing things up? Well, the difference in time scales for the two signals saves my arse here. If one thinks of the SPI activity as a high-frequency, AC-type phenomenon (rapid hi-low transitions of short duration), and the CE signal as a low-frequency, DC-style signal (it's high 99.9% of the time, only requiring a high-low-high transition when changing from power-down to power-up and RX/TX modes, remaining high while RX/TX ops occur), the two signals are 'different' enough that they can be successfully multiplexed on a single line. With a suitably-designed RC lowpass filter, the SCK activity, in short bursts and at a high enough clock rate, will be mostly filtered out of the level seen by the CE pin, so it can be held high even during SPI communication.<br />
<br />
Pros:<br />
- no pin need be dedicated to the CE signal;<br />
- Bidirectional, hardware SPI capability preserved;<br />
- no dedicated SPI transfer required to read nRF24L01+ STATUS register <br />
- no codesize increase due to bit-banged SPI operations<br />
<br />
Cons: <br />
- two extra components (440ohm resistor + .1uF cap) to implement passive LPF for CE line from SCK<br />
<br />
Solution 1. above (single-duplex 3-wire SPI) requires two resistors, so this isn't any worse for board component count or cost; and we retain the faster, full-duplex hardware SPI capability. Win!<br />
<br />
<br />
<u>Bus Analysis</u><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-J0ZB7PHLiPY/T1GoBtLx8yI/AAAAAAAACAE/ZUnAbUX-9D8/s1600/IMAG0096.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="191" src="http://2.bp.blogspot.com/-J0ZB7PHLiPY/T1GoBtLx8yI/AAAAAAAACAE/ZUnAbUX-9D8/s320/IMAG0096.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Back-of-the-business-card visualization. Patent Pending(tm).</td></tr>
</tbody></table>
<br />
CE, being a digital input to an IC going through one or more transistors, has very high resistance -- 10Kohm or more, and so does not significantly affect the drain time of the cap, my EEng co-workers promised me. I also ran a sim of the idealized circuit on the <a href="https://www.circuitlab.com/" target="_blank">CircuitLab online circuit simulator</a>. Highly recommended for checking out cockamamey ideas like this prior to breaking out the parts bin!<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-cIVEHEgXsbE/T1GsUugwTZI/AAAAAAAACAU/EeiPKAOyPWU/s1600/IMAG0091.jpg" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="240" src="http://3.bp.blogspot.com/-cIVEHEgXsbE/T1GsUugwTZI/AAAAAAAACAU/EeiPKAOyPWU/s320/IMAG0091.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Idealized SCK thru RC filter to generate CE control signal.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-luScS6WUrSY/T1GsSr9tXzI/AAAAAAAACAM/tZ3v60cobRU/s1600/IMAG0089.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="http://1.bp.blogspot.com/-luScS6WUrSY/T1GsSr9tXzI/AAAAAAAACAM/tZ3v60cobRU/s320/IMAG0089.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Simulating SCK sitting high and low for long periods. CircuitLab.com
only has a simple function generator, so I just set the frequency down
to the KHz range. Note rise/fall time of the CE signal is approx.
125us into logic 1/0 ranges.</td></tr>
</tbody></table>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-_w1ur5cpRDI/T1GsVNsJ9FI/AAAAAAAACAc/uHJ-fRGuO1Y/s1600/SCK-4MHz-440ohm-100nF-sag.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="149" src="http://4.bp.blogspot.com/-_w1ur5cpRDI/T1GsVNsJ9FI/AAAAAAAACAc/uHJ-fRGuO1Y/s320/SCK-4MHz-440ohm-100nF-sag.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Simulating SPI activity at 4MHz for data transfer. Assuming SCK is idle high, the CE signal would sag only slightly during transfers, staying within logic 1 range for well over 32 bit times. So long as SCK idles HIGH the CE signal will return to full Vdd.</td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<br />
<br />
For thoroughness, I also simulated the resistor and capacitor being +-10% from spec to ensure the voltage sag during SPI activity didn't change much -- and it didn't, not more than .05V or so over the 32 SCK cycles, so component tolerances shouldn't be a problem.<br />
<br />
This hack is nothing much compared to <a href="http://hackaday.com/2011/11/23/reading-inputs-from-shift-registers-using-just-one-single-pin/" target="_blank">some of the hacks out there that make pins do double-duty (or worse)</a>, but I'm proud of my little workaround such as it is. I managed to eke out a critical control signal that otherwise would have been impossible to generate without moving to a 14- or 20-pin AVR part!<br />
<br />
<br />
<u>Summary</u><br />
<br />
The important lesson here, I think, is that signals in any system can be grouped into at least two major classes:<br />
<br />
<ul>
<li>High-frequency, 'AC' type signals <i>communicating data</i>; versus</li>
<li>Low-frequency, 'DC' type signals <i>managing protocol</i> </li>
</ul>
<br />
It is possible to multiplex two signals together on a single control line if they are each from the above two differing classes, as the time-frequency characteristics of each class are different enough to distinguish via a simple high/low pass filter. I know it's possible to multiplex much more than two things in a single physical channel but that's not something I need to know for this project right now :)<br />
<br />
<br />DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0tag:blogger.com,1999:blog-8185950750958800815.post-45394814857368143242011-12-03T20:21:00.001-08:002011-12-04T20:59:20.544-08:00Nobody Move. I've Got A BOM.<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-qT_RmkODo64/Ttr-U0pY0TI/AAAAAAAAAFQ/pkrQxoeFdFw/s1600/nuke.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="133" src="http://2.bp.blogspot.com/-qT_RmkODo64/Ttr-U0pY0TI/AAAAAAAAAFQ/pkrQxoeFdFw/s200/nuke.jpg" width="200" /></a></div>
One of the most annoying things about getting a project ready for prototyping or production is compiling your parts list -- the dreaded BOM. You design a circuit using whatever parts/libraries are there in your PCB tool, sometimes with full knowledge that you need to substitute something that wasn't defined there 'cuz you're lazy and don't want to design a custom footprint/part/whatever...<br />
<br />
Then, of course, you need to eventually compile the order for your prototype. I had no idea that SMD diodes, for instance, don't use the same footprint codes as SMD LEDs (light-emitting diodes). Who'd a thunk the light-emitting part made a difference? You must check these things <i>very</i> carefully when compiling your order.<br />
<br />
For the SMD-impaired, like myself, here are some good pages discussing the mysterious world of packaging in that teensy world:<br />
<br />
<ul>
<li><a href="http://www.microbuilder.eu/Tutorials/Fundamentals/SMDPackages.aspx" target="_blank">Common Surface-Mount Packages</a></li>
<li><a href="http://electronics.stackexchange.com/questions/13072/the-right-0805-footprint-land-pattern">The "right" 0805 footprint land pattern</a></li>
</ul>
Double, nay, <i>triple</i> check your BOM before you order.. I could have <i>sworn</i> I added those optoisolators to my order but whaddya know, they were missing. Back to the order page!<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-ZFmUXGO31nE/TtsAVnm2ilI/AAAAAAAAAFY/FBZxuxVCvOE/s1600/happy-shoe-shopper.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="132" src="http://4.bp.blogspot.com/-ZFmUXGO31nE/TtsAVnm2ilI/AAAAAAAAAFY/FBZxuxVCvOE/s200/happy-shoe-shopper.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">terrorist.</td></tr>
</tbody></table>
<br />
Then there's that voice in the back of your head: <i>Aren't there some other parts you might need for other projects? Better order them too while you're at it.</i> Maybe that's the geek equivalent to shoe-shopping. Sigh.DangerRusshttp://www.blogger.com/profile/14858121043978828905noreply@blogger.com0