<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blogs on Andrew's Memory Blog</title><link>https://andrewmemory.acornwall.net/blog/</link><description>Recent content in Blogs on Andrew's Memory Blog</description><generator>Hugo -- gohugo.io</generator><image><url>https://andrewmemory.acornwall.net/img/rss_image.png</url><title>Blogs on Andrew's Memory Blog</title><link>https://andrewmemory.acornwall.net/</link></image><language>en</language><managingEditor>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</managingEditor><webMaster>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</webMaster><copyright>Copyright 2009--2025</copyright><lastBuildDate>Wed, 08 Apr 2026 23:14:09 -0700</lastBuildDate><atom:link href="https://andrewmemory.acornwall.net/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Uploading to the webserver from Forgejo</title><link>https://andrewmemory.acornwall.net/blog/2026-04-08-uploading-from-forgejo-to-the-webserver/</link><pubDate>Wed, 08 Apr 2026 23:14:09 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2026-04-08-uploading-from-forgejo-to-the-webserver/</guid><description>&lt;p&gt;To get Hugo up to the webserver, I had to scp the files up there using my keyfile. For that, I started with the image that I gave the &lt;code&gt;docker&lt;/code&gt; tag, which is one of the default Forgejo images.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Setting up variables
&lt;div id="setting-up-variables" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-up-variables" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;First I set up a bunch of variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;WEBSERVER_SSH_USERNAME&lt;/code&gt;: my username on the webserver&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WEBSERVER_SSH_HOST&lt;/code&gt;: the hostname of the webserver I upload to&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WEBSERVER_HTML_DIR&lt;/code&gt;: the directory where the webserver files get sent&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Setting up secrets
&lt;div id="setting-up-secrets" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-up-secrets" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I ended up with two secrets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SSH_PRIV_KEY&lt;/code&gt;: my private key&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SSH_KNOWN_HOSTS&lt;/code&gt;: I also needed to set up my &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt; so that I wouldn&amp;rsquo;t get errors when connecting via scp. I temporarily threw away my existing &lt;code&gt;deploy.yaml&lt;/code&gt; and built a new one that did a little (very little) ssh using sftp:&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;.forgejo/workflows/deploy.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-YAML" data-lang="YAML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;push]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deployscp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo dir &amp;gt; ftpbatch
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo bye &amp;gt;&amp;gt; ftpbatch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;setup ssh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; mkdir -p ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0700 ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;${{ secrets.SSH_PRIV_KEY }}&amp;#34; &amp;gt; ~/.ssh/id_rsa_webserver
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0600 ~/.ssh/id_rsa_webserver
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ssh-keyscan ${{ vars.WEBSERVER_SSH_HOST }} &amp;gt;&amp;gt; ~/.ssh/known_hosts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; cat ~/.ssh/known_hosts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;push public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo about to sftp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; sftp -i ~/.ssh/id_rsa_webserver -b ./ftpbatch ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo did sftp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The first time I ran that, I copied the output of the &lt;code&gt;cat ~/.ssh/known_hosts&lt;/code&gt; line into the secret &lt;code&gt;SSH_KNOWN_HOSTS&lt;/code&gt;. Then I updated &lt;code&gt;deploy.yaml&lt;/code&gt; to use the secret instead:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;.forgejo/workflows/deploy.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-YAML" data-lang="YAML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;push]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deployscp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo dir &amp;gt; ftpbatch
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo bye &amp;gt;&amp;gt; ftpbatch&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;setup ssh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; mkdir -p ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0700 ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;${{ secrets.SSH_PRIV_KEY }}&amp;#34; &amp;gt; ~/.ssh/id_rsa_webserver
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0600 ~/.ssh/id_rsa_webserver
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;${{ secrets.SSH_KNOWN_HOST }}&amp;#34; &amp;gt; ~/.ssh/known_hosts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0600 ~/.ssh/known_hosts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;push public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo about to sftp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; sftp -i ~/.ssh/id_rsa_webserver -b ./ftpbatch ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo did sftp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I was hoping that Forgejo would preserve the line separators that I pasted into the secret dialog. It did! Nice!&lt;/p&gt;
&lt;h2 class="relative group"&gt;Add Hugo back to the build and really upload
&lt;div id="add-hugo-back-to-the-build-and-really-upload" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#add-hugo-back-to-the-build-and-really-upload" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;With a working sftp (and presumably a working ssh) and a good private key, I could add the &lt;code&gt;hugo&lt;/code&gt; step back. It packages up the build, then the &lt;code&gt;docker&lt;/code&gt; image retrieves the build and uploads the important bit. Here&amp;rsquo;s the whole enchilada:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;.forgejo/workflows/deploy.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-YAML" data-lang="YAML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;push]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;buildhugo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;submodules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;recursive&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;run hugo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo --gc --minify&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fix up RSS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cp ./public/index.xml ./public/rss.xml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;stash public files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://code.forgejo.org/forgejo/upload-artifact@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./public/ &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deployscp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;docker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;needs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;buildhugo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;grab public files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://code.forgejo.org/forgejo/download-artifact@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;setup ssh&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; mkdir -p ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0700 ~/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;${{ secrets.SSH_PRIV_KEY }}&amp;#34; &amp;gt; ~/.ssh/id_rsa_webserver
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0600 ~/.ssh/id_rsa_webserver
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;${{ secrets.SSH_KNOWN_HOST }}&amp;#34; &amp;gt; ~/.ssh/known_hosts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; chmod 0600 ~/.ssh/known_hosts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;push public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ssh -i ~/.ssh/id_rsa_webserver ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }} &amp;#39;rm -rf /home/${{ vars.WEBSERVER_SSH_USERNAME }}/${{ vars.WEBSERVER_HTML_DIR }}/*&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; scp -r -i ~/.ssh/id_rsa_webserver ./public/* ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }}:/home/${{ vars.WEBSERVER_SSH_USERNAME }}/${{ vars.WEBSERVER_HTML_DIR }}/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This makes it look easy. It wasn&amp;rsquo;t. I was nervous about the process, and started with &lt;code&gt;echo ssh -i ~/...&lt;/code&gt; and &lt;code&gt;echo scp -r -i ~/...&lt;/code&gt; instead of actually running the ssh and scp commands. I made sure things looked right in the Actions window on the Forgejo server before I did the scp for real, and it took me a couple more deep breaths before I did the ssh (which does a &lt;code&gt;rm -rf&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Ultimately, I had to run things 70 times — I counted — before I got a working deploy. Lots of &lt;code&gt;echo&lt;/code&gt; and &lt;code&gt;ls -al&lt;/code&gt; to make sure I was oriented. And probably a third of the commits were fixes for this error:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Workflow was not executed due to an error that blocked the execution attempt.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Unable to parse supported events in workflow: yaml: line 25: found a tab character where an indentation space is expected&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I really need to set my Emacs up so it uses only spaces for yaml files. Esc-X untabify was my best friend.&lt;/p&gt;
&lt;p&gt;Now, I have a website that updates automatically when I push the code. Not when I commit — I&amp;rsquo;m still trying to remember that &lt;code&gt;git push origin&lt;/code&gt; after publishing. I think I&amp;rsquo;ll commit this and do that now.&lt;/p&gt;</description></item><item><title>Running Hugo from the runner on Forgejo</title><link>https://andrewmemory.acornwall.net/blog/2026-04-08-running-hugo-from-the-runner/</link><pubDate>Wed, 08 Apr 2026 22:33:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2026-04-08-running-hugo-from-the-runner/</guid><description>&lt;p&gt;I&amp;rsquo;m taking a shortcut here. With the benefit of foresight which is really hindsight, I &lt;a href="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/" &gt;set my runner up to run Hugo already&lt;/a&gt; with the label &lt;code&gt;hugo&lt;/code&gt;. So this is really about the automation I used to do the build. I started with attempts to install Hugo using &lt;code&gt;apk add&lt;/code&gt; with the Docker image. That was a side quest that led nowhere.&lt;/p&gt;
&lt;p&gt;Then when I decided to split things up, it took me a while to find the right image. The &lt;a href="https://hub.docker.com/r/gohugoio/hugo" target="_blank" rel="noreferrer"&gt;official Hugo Docker image&lt;/a&gt; luckily it includes Node.js so it can run the &lt;code&gt;checkout&lt;/code&gt; and &lt;code&gt;upload-artifact&lt;/code&gt; actions.&lt;/p&gt;
&lt;p&gt;However, you can&amp;rsquo;t do everything on the Hugo image. That means the build has to be split up into two parts. This part is only for running Hugo. Luckily, when it runs, Hugo can store the files it built (&lt;code&gt;./public/&lt;/code&gt;) in an artifact, so it&amp;rsquo;s not &lt;em&gt;too&lt;/em&gt; hard to get them later for uploading.&lt;/p&gt;
&lt;p&gt;You also need to check out the right thing. For Hugo with Blowfish installed, that means checking out submodules.&lt;/p&gt;
&lt;p&gt;If you want to avoid the shortcut and do what I really did, check out the &lt;a href="https://forgejo.org/docs/latest/user/actions/quick-start/" target="_blank" rel="noreferrer"&gt;Forgejo Actions quick start guide&lt;/a&gt; and build a &amp;ldquo;hello world&amp;rdquo; action first.&lt;/p&gt;
&lt;p&gt;This is the file I ended up creating in my local repo:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;.forgejo/workflows/deploy.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-YAML" data-lang="YAML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;push]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;buildhugo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;submodules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;recursive&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;run hugo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo --gc --minify&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fix up RSS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cp ./public/index.xml ./public/rss.xml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;stash public files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://code.forgejo.org/forgejo/upload-artifact@v4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;public&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./public/ &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This checks out the git repo with submodules, runs &lt;code&gt;hugo --gc --minify&lt;/code&gt; on that, copies index.xml to rss.xml because I started with Astro and didn&amp;rsquo;t want to have to migrate everyone&amp;rsquo;s links, then uploads the &lt;code&gt;./public/&lt;/code&gt; directory with the name &lt;code&gt;public&lt;/code&gt; to &lt;a href="https://forgejo.org/docs/next/user/actions/advanced-features/#artifacts" target="_blank" rel="noreferrer"&gt;Forgejo&amp;rsquo;s artifact repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;ve done that, you can:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .forgejo/workflows/deploy.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That triggers the automation that will (first time) download the Hugo image, then build the website, then stash it in an artifact called &lt;code&gt;public&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But that&amp;rsquo;s only half the story for &lt;code&gt;deploy.yaml&lt;/code&gt;. &lt;a href="https://andrewmemory.acornwall.net/blog/2026-04-08-uploading-from-forgejo-to-the-webserver/" &gt;Read about uploading to the webserver here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Setting up a Forgejo runner for Hugo and others</title><link>https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/</link><pubDate>Thu, 02 Apr 2026 22:16:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/</guid><description>&lt;p&gt;I spent a lot of time messing around because I thought the runner was the thing that ran my actions. Nope, it&amp;rsquo;s the thing that runs the Docker image that builds your images. That makes life easier. Here&amp;rsquo;s how I set up mine:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Get the runner token
&lt;div id="get-the-runner-token" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#get-the-runner-token" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;You need the runner token to configure a runner. So do that first. You need to be an admin to set up the runner.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Under the profile menu on the far right, click on &amp;ldquo;Site administration.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under &amp;ldquo;Admin settings&amp;rdquo; expand Actions to click on &amp;ldquo;Runners&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The Admin settings panel. Actions has been expanded so you can see Runners"
width="255"
height="467"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/admin-runner.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/admin-runner.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/admin-runner.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/admin-runner.webp"&gt;&lt;/figure&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Over on the right, click the &amp;ldquo;Create a new runner&amp;rdquo; button. This opens a dialog with a token in it. Copy that token to a text editor.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A dialog titled &amp;ldquo;How to start a runner&amp;rdquo;. The registration token text field has a copy button to the right of it"
width="282"
height="243"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/create-runner.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/create-runner.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/create-runner.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/create-runner.webp"&gt;&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Setting up a runner
&lt;div id="setting-up-a-runner" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-up-a-runner" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I spent a lot of time messing around because I thought the runner was the thing that ran my actions. Nope, it&amp;rsquo;s the thing that runs the Docker image that builds your images. That makes life easier.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make a directory for the runner, put the Dockerfile in it, and grab the image. These instructions look at lot like the ones at the &lt;a href="https://forgejo.org/docs/latest/admin/actions/runner-installation/#oci-image-installation" target="_blank" rel="noreferrer"&gt;OCI image installation&lt;/a&gt; instructions on the Forgejo website.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /data/shared/forgejo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://code.forgejo.org/forgejo/runner/raw/branch/main/Dockerfile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm data.forgejo.org/forgejo/runner:11 forgejo-runner --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Create a &lt;code&gt;setup.sh&lt;/code&gt; in &lt;code&gt;runner/&lt;/code&gt; that looks like this. (Make sure to update the chown line to use the UID and GID you specified in the Forgejo docker-compose.yaml):&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;setup.sh&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /data/shared/forgejo/runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -e
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p data/.cache
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown -R 2000:2000 data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;775&lt;/span&gt; data/.cache
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod g+s data/.cache&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Edit the Dockerfile to use your user info. Look for the USER line and put in your UID and GID:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Docker" data-lang="Docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;2000:2000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Run setup.sh&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash ./setup.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Create a docker-compose.yaml. Based on the Forgejo instructions, it should look like this (but remember to change the user: to your UID and GID). Yeah, I know it should be a different UID and GID but I&amp;rsquo;m lazy:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;docker-compose.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Docker" data-lang="Docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;version: &lt;span class="s1"&gt;&amp;#39;3.8&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt;services:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; docker-in-docker:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; image: docker:dind&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; container_name: &lt;span class="s1"&gt;&amp;#39;docker_dind&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; privileged: &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; command: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dockerd&amp;#39;&lt;/span&gt;, &lt;span class="s1"&gt;&amp;#39;-H&amp;#39;&lt;/span&gt;, &lt;span class="s1"&gt;&amp;#39;tcp://0.0.0.0:2375&amp;#39;&lt;/span&gt;, &lt;span class="s1"&gt;&amp;#39;--tls=false&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; restart: &lt;span class="s1"&gt;&amp;#39;unless-stopped&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; runner:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; image: &lt;span class="s1"&gt;&amp;#39;data.forgejo.org/forgejo/runner:11&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; links:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - docker-in-docker&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; depends_on:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; docker-in-docker:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; condition: service_started&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; container_name: &lt;span class="s1"&gt;&amp;#39;runner&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; environment:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; DOCKER_HOST: tcp://docker-in-docker:2375&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; &lt;span class="c1"&gt;# User without root privileges, but with access to `./data`.&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; user: 2000:2000&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; volumes:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - ./data:/data&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; restart: &lt;span class="s1"&gt;&amp;#39;unless-stopped&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; command: &lt;span class="s1"&gt;&amp;#39;/bin/sh -c &amp;#34;while : ; do sleep 1 ; done ;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt;&lt;span class="c"&gt;# command: &amp;#39;/bin/sh -c &amp;#34;sleep 5; forgejo-runner daemon --config config.yml&amp;#34;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Fire up the runner and attach to the shell in the runner image.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; -it runner /bin/sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="7"&gt;
&lt;li&gt;From within the Docker image shell, run:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;forgejo-runner generate-config &amp;gt; config.yml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;forgejo-runner register&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="8"&gt;
&lt;li&gt;This will run a script. I used the following values. For the runner labels, what they really want is the label followed by a colon followed by the URL of the docker image, with each entry separated by commas. Since I wanted my runner to run Hugo, I added a label for hugo and a pointer to the Hugo image as well as a &amp;ldquo;docker&amp;rdquo; label which is one of the defaults:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFO Enter the Forgejo instance URL &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; example, https://next.forgejo.org/&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;http://myforgejoserver.acornwall.net:3000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFO Enter the runner token:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;d41d8cd98f00b204e9800998ecf8427e32d6c11747e037155210
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFO Enter the runner name &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; empty, use hostname: 3b586057879f&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;INFO Enter the runner labels, leave blank to use the default labels &lt;span class="o"&gt;(&lt;/span&gt;comma-separated, &lt;span class="k"&gt;for&lt;/span&gt; example, ubuntu-20.04:docker://node:20-bookworm,ubuntu-18.04:docker://node:20-bookworm&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo:docker://ghcr.io/gohugoio/hugo:v0.152.2,docker:docker://data.forgejo.org/oci/node:20-bullseye&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="8"&gt;
&lt;li&gt;
&lt;p&gt;All that creates a &lt;code&gt;.runner&lt;/code&gt; file in the Docker image, which gets mapped to the &lt;code&gt;data&lt;/code&gt; directory that &lt;code&gt;setup.sh&lt;/code&gt; created.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now, shut the image down.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose down&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="10"&gt;
&lt;li&gt;Next, edit the docker-compose.yaml. Comment out the command that just spins, and uncomment the command that does the thing:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;docker-compose.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Docker" data-lang="Docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt;&lt;span class="c"&gt;# command: &amp;#39;/bin/sh -c &amp;#34;while : ; do sleep 1 ; done ;&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; command: &lt;span class="s1"&gt;&amp;#39;/bin/sh -c &amp;#34;sleep 5; forgejo-runner daemon --config config.yml&amp;#34;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="11"&gt;
&lt;li&gt;Bring the runner back up:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="12"&gt;
&lt;li&gt;If you did everything right, you should see a runner show up under Admin settings - Actions - Runners.
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A runner with status Idle, ID 9, name runner, version v11.3.1, type Global, labels hugo and docker, last online time 1 minute ago, and an edit button"
width="800"
height="174"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/runner.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/runner.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/runner.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/images/runner.webp"&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Getting the runner to restart on reboot
&lt;div id="getting-the-runner-to-restart-on-reboot" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#getting-the-runner-to-restart-on-reboot" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Another bout with systemd, &amp;lsquo;cause we&amp;rsquo;d like this to start on reboot as well.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;/etc/systemd/system/forgejo-runner.service&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SYSTEMD" data-lang="SYSTEMD"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Forgejo Runner&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;forgejo.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;forgejo.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;oneshot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RemainAfterExit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/bin/bash -c &amp;#34;/usr/bin/docker compose -f /data/shared/forgejo/runner/docker-compose.yaml up --detach&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/bin/bash -c &amp;#34;/usr/bin/docker compose -f /data/shared/forgejo/runner/docker-compose.yaml down&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;And then the requisite:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/usr/bin/docker compose -f /data/shared/forgejo/runner/docker-compose.yaml down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start forgejo-runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status forgejo-runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl stop forgejo-runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; forgejo-runner
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start forgejo-runner&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Installing a minimal Forgejo via Docker on Ubuntu 24.04</title><link>https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/</link><pubDate>Thu, 02 Apr 2026 20:54:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/</guid><description>&lt;p&gt;I&amp;rsquo;ve been wanting to play with &lt;a href="https://forgejo.org/" target="_blank" rel="noreferrer"&gt;Forgejo&lt;/a&gt; for a while. It&amp;rsquo;s the open source DevOps platform behind Codeberg and I like the idea of self-hosted automation. I wanted a minimal one — I didn&amp;rsquo;t need mail but I wanted automation on push.&lt;/p&gt;
&lt;p&gt;If you know Docker (the current version of Docker) you&amp;rsquo;ll find it pretty easy to install. Here&amp;rsquo;s how to do it.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Pull Forgejo from Docker
&lt;div id="pull-forgejo-from-docker" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#pull-forgejo-from-docker" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Ubuntu 24.04 doesn&amp;rsquo;t come with the new Docker, or sqlite3. So:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install docker-compose-v2 sqlite3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Grab the Docker image:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull codeberg.org/forgejo/forgejo:14&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Create a docker-compose.yaml based on the one at &lt;a href="https://forgejo.org/docs/next/admin/installation/docker/" target="_blank" rel="noreferrer"&gt;forgejo.org/docs/next/admin/installation/docker/&lt;/a&gt;. I changed three places the &lt;code&gt;USER_UID&lt;/code&gt;, &lt;code&gt;USER_GID&lt;/code&gt;, and the path to the volume (I used a hard-coded one rather than &lt;code&gt;./forgejo&lt;/code&gt;. The file I ended up with was:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;docker-compose.yaml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Docker" data-lang="Docker"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;networks:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; forgejo:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; external: false&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt;services:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; server:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; image: codeberg.org/forgejo/forgejo:14&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; container_name: forgejo&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; environment:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - &lt;span class="nv"&gt;USER_UID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - &lt;span class="nv"&gt;USER_GID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; restart: always&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; networks:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - forgejo&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; volumes:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - /data/shared/forgejo/forjego:/data ← was ./forgejo:/data&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - /etc/localtime:/etc/localtime:ro&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; ports:&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - &lt;span class="s1"&gt;&amp;#39;3000:3000&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&lt;/span&gt; - &lt;span class="s1"&gt;&amp;#39;222:22&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Bring the image up:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="5"&gt;
&lt;li&gt;
&lt;p&gt;Open a browser on the host&amp;rsquo;s port 3000 (which I&amp;rsquo;ll call myforgejoserver.acornwall.net:3000) to initialize Forgejo.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the browser, leave everything as default except the server domain and base URL. That means I&amp;rsquo;m using the default sqlite&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The onboarding screen. All the defaults are checked except the server domain, which is masked, and the base URL, which is masked except you can see it starts with http and ends with :3000/"
width="800"
height="702"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-1.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-1.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-1.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-1.webp"&gt;&lt;/figure&gt;
&lt;ol start="7"&gt;
&lt;li&gt;I skipped email settings and server/third-party service settings, and entered the administrator account settings, then clicked Install Forgejo:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="More of the onboarding screen. Email settings and server/third party settings are collapsed. The administrator username is andrew, the email address is andrewmemoryblog@gmail.com, and the password is masked. A button at the bottom reads &amp;ldquo;Install Forgejo&amp;rdquo;."
width="800"
height="503"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-2.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-2.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-2.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/onboarding-2.webp"&gt;&lt;/figure&gt;
&lt;ol start="8"&gt;
&lt;li&gt;Next I restarted Forgejo and made sure that the settings stuck. If you have the storage volume wrong in the docker-compose.yaml, as I did the first time, you get to enter everything again after fixing it.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker compose up -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Creating a Git Repo Into Forgejo
&lt;div id="creating-a-git-repo-into-forgejo" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#creating-a-git-repo-into-forgejo" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Once things were set up, I could log in and create a repo in Forgejo. Here&amp;rsquo;s what I did.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the + dropdown and click &amp;ldquo;New repository&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fill out the form. I called my repo &amp;ldquo;andrewmemory&amp;rdquo; and set my user as the owner. I checked &amp;ldquo;Make repostitory private.&amp;rdquo; I also checked &amp;ldquo;Initialize repository&amp;rdquo; which lead to some issues later, but hey, it looked good at the time. I added both &amp;ldquo;Emacs&amp;rdquo; and &amp;ldquo;Hugo&amp;rdquo; to .gitignore — I didn&amp;rsquo;t realize I could do both the first time I tried. I went with CC-BY-NC-ND-4.0 for the license. Then I clicked &amp;ldquo;Create repository.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The repository creation screen. Owner is andrew, repo name is andrewmemory. Make repository private and initialize repository are checked. .gitignore has both Emacs and Hugo, and the license is CC-BY-NC-ND-4.0. A button at the bottom reads &amp;ldquo;Create repository&amp;rdquo;."
width="800"
height="939"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/new-repo.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/new-repo.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/new-repo.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/new-repo.webp"&gt;&lt;/figure&gt;
&lt;p&gt;There, the repo is created!&lt;/p&gt;
&lt;h2 class="relative group"&gt;Verifying your public key
&lt;div id="verifying-your-public-key" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#verifying-your-public-key" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Once the repo was created on Forgejo, I needed to add my private cert to Forgejo. That meant clicking the dropdown on the right with my avatar, clicking &amp;ldquo;Settings,&amp;rdquo; then navigating to &amp;ldquo;SSH / GPG keys&amp;rdquo;. From there I could click &amp;ldquo;Add key&amp;rdquo; under SSH Keys. I pasted my public key in there. Then click &amp;ldquo;Add key.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you&amp;rsquo;ve done that, you&amp;rsquo;ve got something like this. Click &amp;ldquo;Verify&amp;rdquo;:
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A key called Test key. Two buttons are on the right: &amp;ldquo;Remove&amp;rdquo; and &amp;ldquo;Verify&amp;rdquo;"
width="800"
height="73"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/verify-button.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/verify-button.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/verify-button.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/verify-button.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After clicking verify, you&amp;rsquo;re presented with a token and a string to paste into a terminal. Copy the string, paste it into the terminal, but edit the filename if your private key is not &lt;code&gt;id_ed25519&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -n &lt;span class="s1"&gt;&amp;#39;ee2cd80b5f8f4e95800ddca4d92053998bc3f8e7a9cc1dd60fe30e7ad83b87d6&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; ssh-keygen -Y sign -n myforgejoserver.acornwall.net -f ~/.ssh/id_rsa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Running that command will dump a wad into your terminal that looks like this:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;-----BEGIN SSH SIGNATURE-----
U1mIU0lHAAAAAQA
...
&amp;#43;wrNHO9W
-----END SSH SIGNATURE-----&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="5"&gt;
&lt;li&gt;
&lt;p&gt;Copy the whole wad including the BEGIN and END parts, then paste that into the section that says &amp;ldquo;Armored SSH signature&amp;rdquo; and press the &amp;ldquo;Verify&amp;rdquo; button.
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A text field that is labeled Armored SSH signature. The text field begins with &amp;mdash;&amp;ndash;BEGIN SSH SIGNATURE&amp;mdash;&amp;ndash; and has random looking characters until the end, where it says &amp;mdash;&amp;ndash;END SSH SIGNATURE&amp;mdash;&amp;ndash;. Below that are Verify and Cancel buttons."
width="800"
height="203"
src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/armored-signature.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/armored-signature.webp 800w, https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/armored-signature.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/images/armored-signature.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you&amp;rsquo;ve done everything right your key is now verified.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Connecting the old repo
&lt;div id="connecting-the-old-repo" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#connecting-the-old-repo" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Finally, I could start moving my website (which is in a git repo on disk) into Forgejo. That wasn&amp;rsquo;t terrible, although it took me a couple of tries because I wasn&amp;rsquo;t sure how to do it. Here&amp;rsquo;s what I did.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; andrewmemory-hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote rm origin &lt;span class="c1"&gt;# It took me a couple of tries, so I had to remove the old origin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote add origin ssh://git@myforgejoserver.acornwall.net:222/andrew/andrewmemory
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull --allow-unrelated origin main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This resulted in a bunch of merge conflicts in .gitignore that I manually took care of. Once that was done, I could:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push --set-upstream origin main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Setting Forgejo to restart after reboot
&lt;div id="setting-forgejo-to-restart-after-reboot" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-forgejo-to-restart-after-reboot" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;This is all groovy, but next time I install Linux patches, I&amp;rsquo;m going to have to reboot my machine. So I created a systemd (&lt;a href="https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/" &gt;boo&lt;/a&gt;) service to do that.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;/etc/systemd/system/forgejo.service&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SYSTEMD" data-lang="SYSTEMD"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Forgejo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;docker.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;docker.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;oneshot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RemainAfterExit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/bin/bash -c &amp;#34;/usr/bin/docker-compose -f /data/shared/forgejo/docker-compose.yaml up --detach&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/bin/bash -c &amp;#34;/usr/bin/docker-compose -f /data/shared/forgejo/docker-compose.yaml down&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then, I made sure it worked and enabled it on boot:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start forgejo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status forgejo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl stop forgejo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; forgejo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start forgejo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Ok, Forgejo is set up!&lt;/p&gt;</description></item><item><title>Website automation with Forgejo</title><link>https://andrewmemory.acornwall.net/blog/2026-03-29-website-automation-with-forgejo/</link><pubDate>Sun, 29 Mar 2026 21:54:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2026-03-29-website-automation-with-forgejo/</guid><description>&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The Forgejo word mark"
width="300"
height="113"
src="https://andrewmemory.acornwall.net/blog/2026-03-29-website-automation-with-forgejo/images/forgejo-wordmark.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-03-29-website-automation-with-forgejo/images/forgejo-wordmark.webp 800w, https://andrewmemory.acornwall.net/blog/2026-03-29-website-automation-with-forgejo/images/forgejo-wordmark.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-03-29-website-automation-with-forgejo/images/forgejo-wordmark.webp"&gt;&lt;/figure&gt;
&lt;p&gt;If you see this, then my Forgejo web automation is working.&lt;/p&gt;
&lt;p&gt;It took a few steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2026-04-02-installing-forgejo/" &gt;Installing Forgejo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2026-04-02-setting-up-a-forgejo-runner-for-hugo-and-others/" &gt;Setting up the Forgejo runner for Hugo and others&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2026-04-08-running-hugo-from-the-runner/" &gt;Figuring out how to run Hugo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2026-04-08-uploading-from-forgejo-to-the-webserver/" &gt;Figuring out how to upload&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Setting up systemd resolv.conf</title><link>https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/</link><pubDate>Sun, 15 Feb 2026 23:08:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/</guid><description>&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A meme from Scooby Doo. Fred is taking the mask off a ghost labelled systemd, to discover it&amp;rsquo;s really svchost.exe"
width="300"
height="400"
src="https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/images/systemd.webp"
srcset="https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/images/systemd.webp 800w, https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/images/systemd.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2026-02-15-setting-up-systemd-resolv-conf/images/systemd.webp"&gt;&lt;/figure&gt;
&lt;p&gt;Like every intelligent person, I hate systemd. But Linux seems determined to undo all good things, and Debian has adopted it.&lt;/p&gt;
&lt;p&gt;In my Ubuntu 22.04 install, I&amp;rsquo;d disabled it and gone back to normal resolv.conf resolution. That didn&amp;rsquo;t work for 24.04. So I had to figure out the stupid resolution the systemd way.&lt;/p&gt;
&lt;p&gt;To fix DNS on Ubuntu 24.04 — which, I will note, works perfectly for every other system that gets provisioned from my DHCP server — I had to go into /etc/systemd/resolved.conf and uncomment a bunch of stupid crap.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;/etc/systemd/resolved.conf&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-systemd" data-lang="systemd"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Resolve]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;DNS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;(my DNS server IP address)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Domains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;(my local domain)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;DNSSEC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;DNSStubListener&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Migrating from Astro to Hugo</title><link>https://andrewmemory.acornwall.net/blog/2025-12-14-migrating-from-astro-to-hugo/</link><pubDate>Sun, 14 Dec 2025 00:08:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-12-14-migrating-from-astro-to-hugo/</guid><description>&lt;p&gt;For a while, I&amp;rsquo;ve been uncomfortable with Astro. I&amp;rsquo;m not a big fan of npm&amp;rsquo;s &lt;a href="https://docs.npmjs.com/creating-and-publishing-scoped-public-packages" target="_blank" rel="noreferrer"&gt;policy on security&lt;/a&gt; which is basically &amp;ldquo;yeah, just upload it here.&amp;rdquo; Every time I upgrade npm packages, they break. There are workarounds to some security issues with configurations like &lt;a href="https://supergeekery.com/blog/containerizing-npm-and-package-managers-for-security" target="_blank" rel="noreferrer"&gt;npm in a box&lt;/a&gt; but the developer experience for npm is still kind of like having a rash.&lt;/p&gt;
&lt;p&gt;So I decided to give Hugo a shot.
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="An image of the Hugo logo superimposed on the Astro logo"
width="330"
height="140"
src="https://andrewmemory.acornwall.net/blog/2025-12-14-migrating-from-astro-to-hugo/images/astro-to-hugo.webp"
srcset="https://andrewmemory.acornwall.net/blog/2025-12-14-migrating-from-astro-to-hugo/images/astro-to-hugo.webp 800w, https://andrewmemory.acornwall.net/blog/2025-12-14-migrating-from-astro-to-hugo/images/astro-to-hugo.webp 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2025-12-14-migrating-from-astro-to-hugo/images/astro-to-hugo.webp"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Moving there was surprisingly easy. There were a few quirks. Here&amp;rsquo;s what I ended up doing:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Set up Hugo
&lt;div id="set-up-hugo" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#set-up-hugo" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I installed Hugo from the .deb that&amp;rsquo;s linked from &lt;a href="https://gohugo.io/installation/linux/" target="_blank" rel="noreferrer"&gt;gohugo.io/installation/linux&lt;/a&gt;. I&amp;rsquo;d have preferred to have installed from the Ubuntu package manager, but its version was&amp;hellip; less than recent. I&amp;rsquo;ll have to rememer to update this manually.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hugo doesn&amp;rsquo;t come with a default theme, so I had to pick one (from &lt;a href="https://themes.gohugo.io/" target="_blank" rel="noreferrer"&gt;themes.gohugo.io/&lt;/a&gt;) or roll my own. I picked &lt;a href="https://themes.gohugo.io/themes/blowfish/" target="_blank" rel="noreferrer"&gt;Blowfish&lt;/a&gt; because it has light and dark modes, has good docs, tags, and search.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I walked through the Blowfish &lt;a href="https://blowfish.page/docs/" target="_blank" rel="noreferrer"&gt;installation instructions&lt;/a&gt;. I was very careful to avoid the npm tools that they provided — my whole reason for doing this was to get away from that.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Incidentally, I get a warning:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;WARN Module &amp;#34;blowfish&amp;#34; is not compatible with this Hugo version: 0.141.0/0.152.2 extended; run &amp;#34;hugo mod graph&amp;#34; for more information.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;It doesn&amp;rsquo;t seem to affect things.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Copy the old posts over
&lt;div id="copy-the-old-posts-over" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#copy-the-old-posts-over" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Next, I needed to copy my old posts into the new structure. That wasn&amp;rsquo;t too bad:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp -R ~/andrewmemory-astromicroacademic/src/content/blog/ ~/andrewmemory-hugo/content/posts/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Fix the posts
&lt;div id="fix-the-posts" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fix-the-posts" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Fix the time. After copying the posts over, I started to get errors left and right. Hugo is pickier about time formats than Astro. By default, Hugo uses &lt;code&gt;2025-12-14T00:08:05-0700&lt;/code&gt;. Astro was OK with &lt;code&gt;2025-12-14 00:08:05 GMT-7&lt;/code&gt;. Hugo doesn&amp;rsquo;t really care about the &lt;code&gt;T&lt;/code&gt;, I discovered, so all I had to do was:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find . -name index.md -print0 &lt;span class="p"&gt;|&lt;/span&gt; xargs -0 sed -i &lt;span class="s1"&gt;&amp;#39;s/ GMT-7/-0700/1&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Change from description to summary. I discovered that Hugo uses &lt;code&gt;summary:&lt;/code&gt; where Astro uses &lt;code&gt;description:&lt;/code&gt; in the front matter. So&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find . -name index.md -print0 &lt;span class="p"&gt;|&lt;/span&gt; xargs -0 sed -i &lt;span class="s1"&gt;&amp;#39;s/description:/summary:/1&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Update internal links. Since Astro wants its blog posts in /blog/ and Hugo wants them in /posts/, I needed to update. I could probably have renamed posts to blog, but I figured, let&amp;rsquo;s go with the Hugo way. &lt;strong&gt;You might not want to do this.&lt;/strong&gt; I had to undo it. Scroll down a few sections to see why.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find . -name index.md -print0 &lt;span class="p"&gt;|&lt;/span&gt; xargs -0 sed -i &lt;span class="s1"&gt;&amp;#39;s|/blog/|/posts/|g&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Fix links to static files. Astro requires that you put static files in /public for them to be visible. Hugo apparently lets you keep them in their associated directories! So my &lt;a href="https://andrewmemory.acornwall.net/blog/2011-10-01-converting-yaps-to-keepassdroid/" &gt;post with a Perl script&lt;/a&gt; can just say &lt;code&gt;[convertcsv.pl](convertcsv.pl)&lt;/code&gt;. Nice! I copied the static assets into their appropriate directories.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Tweak code blocks to allow filenames
&lt;div id="tweak-code-blocks-to-allow-filenames" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#tweak-code-blocks-to-allow-filenames" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I had &lt;a href="https://andrewmemory.acornwall.net/posts/2024-11-17-adding-code-titles-to-astro-micro-academic/" &gt;modified Astro&lt;/a&gt; to enable filenames on code blocks. I needed to do the same thing for Hugo. I found a few good references, particularly &lt;a href="https://write.rog.gr/writing/labeling-code-blocks-in-hugo/" target="_blank" rel="noreferrer"&gt;Roger Steve Ruiz&amp;rsquo;s blog&lt;/a&gt;. There were a few steps here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create directories &lt;code&gt;~/andrewmemory-hugo/layouts/_default&lt;/code&gt; and &lt;code&gt;~/andrewmemory-hugo/layouts/_default/_markup/&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a &lt;code&gt;render-codeblock.html&lt;/code&gt; file there. I wanted the titles to stick out a little more, so I abused the &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; tag. I also decided to set &lt;code&gt;isVerbatim&lt;/code&gt; to false because I prefer it that way. I ended up with:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;layouts/_default/_markup/render-codeblock.html&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="cm"&gt;/* this file is exists at `layouts/_default/_markup/` in your Hugo project */&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;$isVerbatim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;isset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Attributes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;verbatim&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;$isVerbatim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;verbatim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="err"&gt;=&amp;#34;&lt;/span&gt;&lt;span class="nc"&gt;highlight&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- with .Attributes.title }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;figcaption&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- if $isVerbatim -}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;span&amp;gt;&amp;lt;mark&amp;gt;{{ . }}&amp;lt;/mark&amp;gt;&amp;lt;/span&amp;gt; {{/* As a file name */}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- else -}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;span&amp;gt;&amp;lt;mark&amp;gt;{{ . | markdownify }}&amp;lt;/mark&amp;gt;&amp;lt;/span&amp;gt; {{/* As a code description */}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/figcaption&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- end }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- if transform.CanHighlight .Type }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;pre tabindex=&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; class=&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;chroma&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;gt;&amp;lt;code class=&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; data-lang=&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- with transform.HighlightCodeBlock . -}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{ .Inner }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- else }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;lt;pre tabindex=&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;gt;&amp;lt;code class=&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34; data-lang=&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;gt;{{ .Inner }}&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; {{- end }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;&amp;lt;/figure&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Finally, I needed to change the references from the old Astro syntax:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;``&lt;span class="sb"&gt;`bash:/usr/local/bin/file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;My file contents
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;`&lt;/span&gt;``&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;``&lt;span class="sb"&gt;`bash {title = &amp;#34;/usr/local/bin/file&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;My file contents
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;`&lt;/span&gt;``&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I didn&amp;rsquo;t have enough code blocks with filenames to script this, so I this by hand. I used this one-liner to find out where I needed to make changes:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find . -name index.md -print0 | xargs -0 grep &amp;#39;``&lt;span class="sb"&gt;`&amp;#39; | grep &amp;#39;`&lt;/span&gt;.*:&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Move things to match the old site
&lt;div id="move-things-to-match-the-old-site" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#move-things-to-match-the-old-site" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Ok, it looks as if Hugo doesn&amp;rsquo;t have an easy way to alias a section, so I can&amp;rsquo;t define a global /blog/ that redirects to /posts/. If I put everything in /posts/ it will break existing links. I have to undo it. So much for the Hugo way&amp;hellip;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Undo the sed that I did above:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;find . -name index.md -print0 &lt;span class="p"&gt;|&lt;/span&gt; xargs -0 sed -i &lt;span class="s1"&gt;&amp;#39;s|/posts/|/blog/|g&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Move the posts/ directory under content/ to blog/:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mv posts blog&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Update the Blog link&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;./config/_default/menus.en.toml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Blog&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;pageRef&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;blog&amp;#34;&lt;/span&gt; &lt;span class="c"&gt;# was posts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;weight&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="4"&gt;
&lt;li&gt;I&amp;rsquo;d love to add a link for the old RSS. But I can&amp;rsquo;t figure out how to rename it. Boo. I guess I can add that when I build the site.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Prettify the RSS feed
&lt;div id="prettify-the-rss-feed" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prettify-the-rss-feed" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;By default, the RSS that Hugo/Blowfish has is pretty spartan. I found a great blog post called &lt;a href="https://justingarrison.com/blog/2022-11-22-hugo-rss-improvements/" target="_blank" rel="noreferrer"&gt;Hugo RSS Improvements&lt;/a&gt; that got me started. Here&amp;rsquo;s what I did:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a file in /assets/img/ called &lt;code&gt;rss_image.png&lt;/code&gt;. Mine is 475 by 475 pixels. I read on &lt;a href="https://help.rss.com/en/support/solutions/articles/44000492924-cover-art-formatting-requirements" target="_blank" rel="noreferrer"&gt;rss.com&lt;/a&gt; that Apple wants a minimum of 3000 by 3000. 🙄&lt;/li&gt;
&lt;li&gt;Copy the theme&amp;rsquo;s XML from &lt;code&gt;themes/blowfish/layouts/_default/rss.xml&lt;/code&gt; into &lt;code&gt;layouts/_default/rss.xml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Change the RSS to include the image under the &lt;code&gt;&amp;lt;generator&amp;gt;&lt;/code&gt; line:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;layouts/_default/rss.xml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;image&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;{{ $.Site.BaseURL }}img/rss_image.png&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;link&amp;gt;&lt;/span&gt;{{ $.Site.BaseURL }}&lt;span class="nt"&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/image&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Change the RSS &lt;code&gt;&amp;lt;description&amp;gt;&lt;/code&gt; to include content rather than summaries:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;layouts/_default/rss.xml&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;{{ .Content | html }}&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now my RSS feed is 600 K and only going to grow, but I can read the blog from the RSS feed in AntennaPod.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Build the static site
&lt;div id="build-the-static-site" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#build-the-static-site" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;On to building and testing. That&amp;rsquo;s easy:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;killall hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/andrewmemory-hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf public resources
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo --gc --minify
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; public
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp index.xml rss.xml &lt;span class="c1"&gt;# Yuck&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python3 -m http.server &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Hey, it looks good! Everything works&amp;hellip; except search. Hmm&amp;hellip; there&amp;rsquo;s a lot of questions in the Hugo community about that. The RSS file is just copied, which means I&amp;rsquo;ll have to do that every time.&lt;/p&gt;
&lt;p&gt;Is it possible that search isn&amp;rsquo;t working because I&amp;rsquo;m not under my domain? Close your eyes, take a breath, and try it out.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Install the static site
&lt;div id="install-the-static-site" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#install-the-static-site" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Blow away the existing site.&lt;/li&gt;
&lt;li&gt;Upload everything in the new public/ to the site.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Images are broken
&lt;div id="images-are-broken" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#images-are-broken" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Hmm&amp;hellip; that appears to be something weird with HostGator. I changed Hotlink Protection Management to block links to .png, but allowed direct URL requests. Don&amp;rsquo;t ask, that just has to happen. Websites -&amp;gt; Settings -&amp;gt; Hotlink Protection -&amp;gt; Manage -&amp;gt; Click .png, Click Allow direct requests&lt;/p&gt;</description></item><item><title>Fixing Van Heusen Shirt Pockets</title><link>https://andrewmemory.acornwall.net/blog/2025-12-10-fixing-van-heusen-shirt-pockets/</link><pubDate>Wed, 10 Dec 2025 19:53:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-12-10-fixing-van-heusen-shirt-pockets/</guid><description>&lt;p&gt;I like Van Heusen Men&amp;rsquo;s fitted poplin dress shirts. They&amp;rsquo;re one of the few that still has a left shirt pocket — and that&amp;rsquo;s where my cell phone goes. But the shirts have a problem: after you put your phone in the pocket a few times, the stitching on the pocket lets go.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A shirt pocket. The left and right top corners have detached from the shirt"
width="400"
height="533"
src="https://andrewmemory.acornwall.net/blog/2025-12-10-fixing-van-heusen-shirt-pockets/images/bad-shirt.png"
srcset="https://andrewmemory.acornwall.net/blog/2025-12-10-fixing-van-heusen-shirt-pockets/images/bad-shirt.png 800w, https://andrewmemory.acornwall.net/blog/2025-12-10-fixing-van-heusen-shirt-pockets/images/bad-shirt.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2025-12-10-fixing-van-heusen-shirt-pockets/images/bad-shirt.png"&gt;&lt;/figure&gt;
&lt;p&gt;As they break, I&amp;rsquo;ve been fixing them by machine sewing the pockets back together. To do that, I need to match the new thread to the fabric. Here&amp;rsquo;s what I&amp;rsquo;ve used so far:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Shirt Colour&lt;/th&gt;
&lt;th style="text-align: center"&gt;Matching Thread&lt;/th&gt;
&lt;th style="text-align: left"&gt;Comments&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Black&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Cameo Blue&lt;/td&gt;
&lt;td style="text-align: center"&gt;tbd&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Dark Leaf&lt;/td&gt;
&lt;td style="text-align: center"&gt;tbd&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Deep Sea&lt;/td&gt;
&lt;td style="text-align: center"&gt;tbd&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Desert Rose&lt;/td&gt;
&lt;td style="text-align: center"&gt;tbd&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Flame&lt;/td&gt;
&lt;td style="text-align: center"&gt;Coats &amp;amp; Clark 2160 Atom Red&lt;/td&gt;
&lt;td style="text-align: left"&gt;Need to verify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Grey&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Greystone&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Lavender&lt;/td&gt;
&lt;td style="text-align: center"&gt;Coats &amp;amp; Clark 3340 Light Violet&lt;/td&gt;
&lt;td style="text-align: left"&gt;Good match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Leaf&lt;/td&gt;
&lt;td style="text-align: center"&gt;Coats &amp;amp; Clark 6050 Powder Green&lt;/td&gt;
&lt;td style="text-align: left"&gt;Thread is just a little light&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Lemon Glaze&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Light Grey&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Magenta&lt;/td&gt;
&lt;td style="text-align: center"&gt;Coats &amp;amp; Clark 2820 Barberry Red&lt;/td&gt;
&lt;td style="text-align: left"&gt;Good match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Mist&lt;/td&gt;
&lt;td style="text-align: center"&gt;tbd&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Ocean Mist&lt;/td&gt;
&lt;td style="text-align: center"&gt;Amann Mettler 2105 Vintage Blue&lt;/td&gt;
&lt;td style="text-align: left"&gt;Good match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Pacifico&lt;/td&gt;
&lt;td style="text-align: center"&gt;Coats &amp;amp; Clark 4450 Pilot Blue&lt;/td&gt;
&lt;td style="text-align: left"&gt;Good match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Persian Blue&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Persimmon&lt;/td&gt;
&lt;td style="text-align: center"&gt;tbd&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Purple Velvet&lt;/td&gt;
&lt;td style="text-align: center"&gt;Coats &amp;amp; Clark 3660 Deep Violet&lt;/td&gt;
&lt;td style="text-align: left"&gt;Good match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Scallop&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Stone&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;White&lt;/td&gt;
&lt;td style="text-align: center"&gt;don&amp;rsquo;t own&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As usual, nothing says they have to keep the same colour, dye lots may vary, they may change the stitch thread and not the shirt colour, you know the drill.&lt;/p&gt;</description></item><item><title>Shrinking files on AntennaPod</title><link>https://andrewmemory.acornwall.net/blog/2025-09-12-shrinking-files-on-antennapod/</link><pubDate>Fri, 12 Sep 2025 22:32:08 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-09-12-shrinking-files-on-antennapod/</guid><description>&lt;p&gt;I like to listen to podcasts, and my favourite podcast app for Android is &lt;a href="https://antennapod.org/" target="_blank" rel="noreferrer"&gt;AntennaPod&lt;/a&gt;. I like the control it gives me, the fact that it deals reasonably with non-audio RSS feeds, the wide range of speed controls, and the searchability.&lt;/p&gt;
&lt;p&gt;But I download a &lt;em&gt;lot&lt;/em&gt; of podcasts. That means there&amp;rsquo;s a lot of stuff ready for me when I go on flights and things like that, but otherwise it&amp;rsquo;s, you know, waiting. Some podcast feeds think I want really high quality audio. Like 256 or 320 k/second. Nope, don&amp;rsquo;t need that.&lt;/p&gt;
&lt;p&gt;Finally I figured out that it might be smart to recode some of the podcasts to free up space on my chronically overfilled phone. That&amp;rsquo;s what I did. Here&amp;rsquo;s how I did it. First, you have to be in &lt;a href="https://www.howtogeek.com/129728/how-to-enable-developer-options-menu-and-enable-and-usb-debugging-on-android/" target="_blank" rel="noreferrer"&gt;developer mode&lt;/a&gt; and be able to connect over adb. Then:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;adb shell &amp;#34;ls /storage/emulated/0/Android/data/de.danoeh.antennapod.debug/files/media/&amp;#34;
adb pull &amp;#34;/storage/emulated/0/Android/data/de.danoeh.antennapod.debug/files/media/your-podcast-directory-name&amp;#34;
cd your-podcast-directory-name
mkdir recoded
for i in *.mp3; do echo $i; lame -V6 &amp;#34;$i&amp;#34; &amp;#34;recoded/$i&amp;#34;; done
cd recoded
for i in *.mp3; do echo $i; adb push &amp;#34;$i&amp;#34; &amp;#34;/storage/emulated/0/Android/data/de.danoeh.antennapod.debug/files/media/your-podcast-directory-name/$i&amp;#34;; done&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(Replace &lt;em&gt;your-podcast-directory-name&lt;/em&gt; with something that exists. Oh, and I&amp;rsquo;m running the debug version &amp;lsquo;cause I build it from source&amp;hellip; you&amp;rsquo;ll probably just want de.danoeh.antennapod instad of de.danoeh.antennapod.debug.)&lt;/p&gt;
&lt;p&gt;By doing this on my two fattest podcast directories, I was able to save 4+ G. Nice!&lt;/p&gt;</description></item><item><title>Fixing OpenBSD console mode for a new HDMI monitor</title><link>https://andrewmemory.acornwall.net/blog/2025-07-04-fixing-openbsd-console-mode-for-a-new-hdmi-monitor/</link><pubDate>Fri, 04 Jul 2025 22:56:08 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-07-04-fixing-openbsd-console-mode-for-a-new-hdmi-monitor/</guid><description>&lt;p&gt;My old monitor recently lost the magic smoke. I think it&amp;rsquo;s probably repairable with a new capacitor or two, but I took the opportunity to upgrade to an Acer SA272UE QHD monitor instead. It&amp;rsquo;s been good with one minor nit: when I switch to my OpenBSD firewall, I don&amp;rsquo;t get video.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s not quite true: I get video when the device (a &lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/" target="_blank" rel="noreferrer"&gt;HUNSN Micro Firewall Appliance, Mini PC, VPN, Router PC, Intel N5105, HUNSN RJ03, AES-NI, 4 x Intel 2.5GbE I226-V LAN, Type-C, TF, M.2 WiFi 6 Slot, Barebone, NO RAM, NO Storage, NO System&lt;/a&gt;) starts up in VGA mode. But once OpenBSD switches over to the framebuffer console, the monitor goes black and tells me &lt;code&gt;Cable Not Connected&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://www.openbsd.org/faq/faq7.html#Size80x50" target="_blank" rel="noreferrer"&gt;OpenBSD FAQ&lt;/a&gt; was not much help — it still references the old 80x50 text mode console rather than a framebuffer console. The BSD site &lt;a href="https://daemonforums.org/showthread.php?p=76147" target="_blank" rel="noreferrer"&gt;daemonforums.org&lt;/a&gt;, however, had a wealth of information.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ dmesg | grep wsdisplay
wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0
wsdisplay0: screen 1-5 added (std, vt100 emulation)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The recommended action was to boot to UKC — the kernel configurator — and disable the Intel DRM driver. I tried that, but wasn&amp;rsquo;t able to use it because of a &lt;a href="https://www.reddit.com/r/openbsd/comments/irtu8l/external_usb_keyboard_not_working_at_ukc_prompt/" target="_blank" rel="noreferrer"&gt;five-year-old problem&lt;/a&gt; with USB keyboards.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; I created /etc/bsd.reconfig and added the line:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;/etc/bsd.reconfig&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;disable inteldrm0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;After reboot, I saw&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ dmesg | grep wsdisplay
wsdisplay0 at efifb0 mux 1: console (std, vt100 emulation)
wsdisplay0: screen 1-5 added (std, vt100 emulation)
$ stty size
160 45&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m still using the framebuffer console, but now with the EFI driver instead of the Intel driver. That&amp;rsquo;s cool — I can still run X if I need to, and I still get a 160x45 console.&lt;/p&gt;
&lt;p&gt;I did run into one problem after doing this, which I&amp;rsquo;m not sure is related or not. When I installed patch 77_008, I saw:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Relinking to create unique kernel... failed!
!!! &amp;#34;/usr/libexec/reorder_kernel&amp;#34; must be run manually to install the new kernel&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I typed in the magic command — that appeared to fix it. If that doesn&amp;rsquo;t persist, I might need to &lt;a href="https://blog.narf.ssji.net/2020/11/10/relinking-to-create-unique-kernel-failed/" target="_blank" rel="noreferrer"&gt;regenerate &lt;code&gt;/var/db/kernel.SHA256&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Jackery Explorer 2000v2 Specifications</title><link>https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/</link><pubDate>Tue, 10 Jun 2025 21:53:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/</guid><description>&lt;p&gt;In June of 2025, I bought a Jackery Explorer 2000 v2. Finding specifications for it has been a pain — I think Jackery makes them difficult to discover because they want you to buy their accessories.&lt;/p&gt;
&lt;p&gt;But I already had a couple of 100 W panels that had Anderson Powerpoles on them so I needed to build a few cables. Here&amp;rsquo;s the result:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A short cable with a DC8020 connector on one end and two Anderson Powerpole connectors on the other. The black connector is connected to the black wire. A yellow connector is connected to the red wire"
width="800"
height="412"
src="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/cable.png"
srcset="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/cable.png 800w, https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/cable.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/cable.png"&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Specifications&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Solar panel input connector&lt;/strong&gt;: DC8020.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connector polarity&lt;/strong&gt;: center positive.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voltage&lt;/strong&gt;: 11.0–60 V DC. According to the manual, if you&amp;rsquo;re below 16 V you&amp;rsquo;ll get 8 A maximum no matter how many panels you have plugged in; if you&amp;rsquo;re over 16 V you&amp;rsquo;ll get up to 12 A with one panel and 21 A with two panels.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MPPT&lt;/strong&gt;: one.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The right side of a Jackery Explorer 2000 v2. A cable that ends in Anderson Powerpole connectors is plugged into the bottom solar panel input."
width="400"
height="476"
src="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/jackery.png"
srcset="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/jackery.png 800w, https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/jackery.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/jackery.png"&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Undocumented Button Presses&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Soft reset?&lt;/strong&gt; With the power turned on, hold Power and DC/USB simultaneously for 3 seconds. Resets WiFi and Bluetooth.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Another soft reset&lt;/strong&gt; Hold Power for 10 seconds?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hard reset?&lt;/strong&gt; Hold Power and DC/USB for 13 seconds. Enters BMS recalibration mode? (Discharge to 0%, then charge back to 100%)?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Switch AC frequency&lt;/strong&gt; Hold AC for 3 seconds to switch between 50 Hz and 60 Hz power. (Difference between EU and US models?)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Error Codes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most of these and their solutions are from an &lt;a href="https://faq.jackery.com/hc/en-us/articles/10495951339931-Error-code-stand-for-on-E1000-Pro-E2000-Pro" target="_blank" rel="noreferrer"&gt;troubleshooting article about the E2000&lt;/a&gt;, the &lt;a href="https://nz.jackery.com/content/dam/jackery/nz/user-manual/pps/Jackery_Explorer_2000_Pro_User_Manual.pdf" target="_blank" rel="noreferrer"&gt;Explorer 2000 Pro manual&lt;/a&gt;, and the &lt;a href="https://helpcenter.eu.jackery.com/hc/en-us/categories/20030841452315-Product-Related" target="_blank" rel="noreferrer"&gt;European Jackery Helpcenter&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;F0&lt;/td&gt;
&lt;td&gt;BMS communications error&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F1&lt;/td&gt;
&lt;td&gt;inverter communications error&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;charging module communication error&lt;/td&gt;
&lt;td&gt;Try unplugging/replugging 8 mm charging cables?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F3&lt;/td&gt;
&lt;td&gt;battery failure&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F4&lt;/td&gt;
&lt;td&gt;battery overvoltage&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;td&gt;battery undervoltage&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F6&lt;/td&gt;
&lt;td&gt;inverter error&lt;/td&gt;
&lt;td&gt;Load power more than that of the power supply? Unplug the load and reset the Jackery. Could also be internal hardware failure if a reset doesn&amp;rsquo;t fix it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F7&lt;/td&gt;
&lt;td&gt;power supply module error&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F8&lt;/td&gt;
&lt;td&gt;battery overcurrent/short&lt;/td&gt;
&lt;td&gt;Unplug everything (all charging and load cables).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F9&lt;/td&gt;
&lt;td&gt;DC output overcurrent/short&lt;/td&gt;
&lt;td&gt;Unplug all the load cables.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FA&lt;/td&gt;
&lt;td&gt;power mismatch?&lt;/td&gt;
&lt;td&gt;Happens when two Jackerys are ganged and one is 60 Hz while the other is 50 Hz. Possibly not applicable to the 2000 v2.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FB&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FD&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FE&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Comments&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The DC8020 is an 8 mm outer diameter connector with a 2 mm center pin. I used the &lt;a href="https://www.amazon.com/dp/B0BNHWX2VS" target="_blank" rel="noreferrer"&gt;GINTOOYUN pigtail from Amazon&lt;/a&gt; which helpfully provides two cables.
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="An 8 mm barrel connector with a 2 mm pin in it"
width="200"
height="302"
src="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/dc8020-pin.png"
srcset="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/dc8020-pin.png 800w, https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/dc8020-pin.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2025-06-10-jackery-2000v2-specs/images/dc8020-pin.png"&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;Avoid the 7909 connector, which looks similar but is 7.9 mm and the pin is smaller (0.9 mm).&lt;/li&gt;
&lt;li&gt;Even if you ordered a DC8020 connector, measure the pin. I&amp;rsquo;d first ordered from a different manufacturer and they shipped a DC7909. It will still plug in (7.9 mm is almost 8 mm), but the pin won&amp;rsquo;t make contact.&lt;/li&gt;
&lt;li&gt;Half the vendors on Amazon think the 7909 is the &amp;ldquo;Jackery connector&amp;rdquo; while the other half think the 8020 is. They&amp;rsquo;re both half right.&lt;/li&gt;
&lt;li&gt;Both 8 mm jacks are connected to the single MPPT controller in the Jackery. The 12 A maximum is a limit of the connector. This also means you&amp;rsquo;ll need balanced voltages on two panels if you connect each one into an 8 mm connector. Alternately, you can plug them in series as long as you&amp;rsquo;re under 60 V total, and then can connect to both connectors using a Y cable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Frequently Asked Questions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Q: My panel isn&amp;rsquo;t charging the battery. Why not?&lt;br&gt;
A: Any of a number of reasons:&lt;br&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make sure you&amp;rsquo;ve got a DC8020 connector (&amp;ldquo;thick pin&amp;rdquo;) and not a DC7909. The pin size should be 2 mm (about 5/64&amp;quot;) and not 0.9 mm (about 9/256&amp;quot;).&lt;/li&gt;
&lt;li&gt;Verify you&amp;rsquo;re getting at least 11 V from the panel.&lt;/li&gt;
&lt;li&gt;Verify you&amp;rsquo;re not getting more than 60 V from the panel.&lt;/li&gt;
&lt;li&gt;Make sure the power to the Jackery is turned on.&lt;/li&gt;
&lt;li&gt;Make sure the DC8020 is pushed all the way in. It takes some force to do this, and you might bend the plastic shell of the Jackery a little. Be careful not to snap it.&lt;/li&gt;
&lt;li&gt;Make sure you&amp;rsquo;re not in battery saver mode if your charge is already near 85%. I discovered that if you are at 84%, the solar panel won&amp;rsquo;t charge the battery in battery saver mode.&lt;/li&gt;
&lt;li&gt;Make sure it&amp;rsquo;s not colder than 0 C (32 F) or warmer than 45 C (113 F).&lt;/li&gt;
&lt;li&gt;If all else fails, make sure you can still charge from the wall socket.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Q: Is the solar panel connector (DC8020) center positive or center negative?&lt;br&gt;
A: Center positive.&lt;/p&gt;
&lt;p&gt;Q: I have an older Jackery and the DC8020 doesn&amp;rsquo;t fit. Why?&lt;br&gt;
A: Older models used the DC7909. If you have an older Jackery, you&amp;rsquo;ll need the 0.9 mm &amp;ldquo;thin pin&amp;rdquo; connector.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Something wrong?&lt;/strong&gt;
Get in touch with me. My username is andrewmemoryblog (no &amp;ldquo;s&amp;rdquo;) on a well-known Google email provider.&lt;/p&gt;</description></item><item><title>More on using Uniden Sentinel BCDx36HP on Ubuntu 24.04 under Wine</title><link>https://andrewmemory.acornwall.net/blog/2025-04-16-more-on-uniden-sentinel-bcdx36hp-on-ubuntu-24.04-under-wine/</link><pubDate>Wed, 16 Apr 2025 22:45:00 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-04-16-more-on-uniden-sentinel-bcdx36hp-on-ubuntu-24.04-under-wine/</guid><description>&lt;p&gt;Running the Uniden Sentinel (BCD436HP/BCD536HP) programming software didn&amp;rsquo;t work on Wine when I was running on X on Ubuntu 24.04. After installing several versions of Wine with no joy, winetricksing random things, switching to the Intel non-free graphics driver, and more reinstalls than I want to remember, I finally hit upon success.&lt;/p&gt;
&lt;p&gt;My problem was that, after I&amp;rsquo;d started the BCDx36HP.exe, I&amp;rsquo;d see a dialog box. Then the editor window would come up. And then&amp;hellip; the editor window would disappear.&lt;/p&gt;
&lt;p&gt;The breakthrough came when I realized I could drag the editor window as it was drawing, and it would redraw correctly and stay on the screen. However, it would redecorate from the classic look to a more modern look.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; I turned that setting off under the Graphics tab of &lt;code&gt;winecfg&lt;/code&gt;:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The winecfg dialog with the Graphics tab selected and &amp;lsquo;Allow the window manager to decorate the windows&amp;rsquo; unchecked, but &amp;lsquo;Allow the window manager to control the windows&amp;rsquo; checked"
width="418"
height="479"
src="https://andrewmemory.acornwall.net/blog/2025-04-16-more-on-uniden-sentinel-bcdx36hp-on-ubuntu-24.04-under-wine/images/winecfg-uncheck-window-manager-decorations.png"
srcset="https://andrewmemory.acornwall.net/blog/2025-04-16-more-on-uniden-sentinel-bcdx36hp-on-ubuntu-24.04-under-wine/images/winecfg-uncheck-window-manager-decorations.png 800w, https://andrewmemory.acornwall.net/blog/2025-04-16-more-on-uniden-sentinel-bcdx36hp-on-ubuntu-24.04-under-wine/images/winecfg-uncheck-window-manager-decorations.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2025-04-16-more-on-uniden-sentinel-bcdx36hp-on-ubuntu-24.04-under-wine/images/winecfg-uncheck-window-manager-decorations.png"&gt;&lt;/figure&gt;
&lt;p&gt;Once I&amp;rsquo;d done that, the &lt;a href="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/" &gt;usual instructions for using Sentinel&lt;/a&gt; worked.&lt;/p&gt;</description></item><item><title>Downloading an APK from Android</title><link>https://andrewmemory.acornwall.net/blog/2025-04-08-downloading-an-apk-from-android/</link><pubDate>Tue, 08 Apr 2025 21:34:29 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-04-08-downloading-an-apk-from-android/</guid><description>&lt;p&gt;I keep needing to search to find this, so I&amp;rsquo;ll write it down.&lt;/p&gt;
&lt;p&gt;To download an APK from Android, you need to do the following:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;adb shell pm list packages --user 0
adb shell pm path your.package.name
adb pull /data/app/your/path/to/package/foo.apk&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;If there are multiple APKs (&lt;code&gt;base.apk&lt;/code&gt;, &lt;code&gt;arm64_v8a.apk&lt;/code&gt;, etc.) it&amp;rsquo;s an Android app bundle (AAB). You get only the APKs specific to your device.&lt;/p&gt;
&lt;p&gt;Incidentally, the publicly accessible data directory for Android apps is in &lt;code&gt;/shared/Android/data/your.package.name/&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Fixing buffer bloat on OpenBSD 7.2</title><link>https://andrewmemory.acornwall.net/blog/2025-02-01-fixing-bufferbloat-on-openbsd/</link><pubDate>Sat, 01 Feb 2025 01:28:19 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2025-02-01-fixing-bufferbloat-on-openbsd/</guid><description>&lt;p&gt;I learned a little today about buffer bloat, which is latency introduced when uploading/downloading. After that, I headed straight over to &lt;a href="https:///www.waveform.com/tools/bufferbloat" target="_blank" rel="noreferrer"&gt;WaveForm&amp;rsquo;s buffer bloat test&lt;/a&gt; and got a D.&lt;/p&gt;
&lt;p&gt;Luckily, the WaveForm page pointed me to a solution, which I found at &lt;a href="https://www.pauladamsmith.com/blog/2018/07/fixing-bufferbloat-on-your-home-network-with-openbsd-6.2-or-newer.html" target="_blank" rel="noreferrer"&gt;Paul Smith&amp;rsquo;s blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Following Paul&amp;rsquo;s instructions, I added a Queue section to my /etc/pf.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#---------------------------------#
# Queues
#---------------------------------#
queue outq on $ext_if flows 1024 bandwidth 10M max 10M qlimit 1024 default
queue inq on $lan_if flows 1024 bandwidth 225M max 225M qlimit 1024 default&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;then reloaded the rules:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;doas pfctl -n -f /etc/pf.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; doas pfctl -f /etc/pf.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I didn&amp;rsquo;t get an A, but I did move up to a C, which means I&amp;rsquo;ve at least halved the latency problem. There&amp;rsquo;s a warning in a comment on Paul Smith&amp;rsquo;s page:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;This works well if you have OpenBSD acting as a firewall/NAT appliance only, but doesn&amp;rsquo;t work if you have multiple downstream interfaces, or run any services on the OpenBSD server at all (facing either the LAN &lt;del&gt;or&lt;/del&gt; the internet).&amp;rdquo; The commenter suggests an explict parent queue with the whole LAN bandwidth and subqueues for internet and everything else.&lt;/p&gt;
&lt;p&gt;Anyway, I went to &lt;a href="https://speed.cloudflare.com/" target="_blank" rel="noreferrer"&gt;CloudFlare&amp;rsquo;s speed test&lt;/a&gt; and I&amp;rsquo;m &amp;ldquo;great.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Converting ePub to PDF</title><link>https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/</link><pubDate>Sat, 07 Dec 2024 15:18:19 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/</guid><description>&lt;p&gt;I bought the Michael w Lucas book &lt;a href="https://www.kickstarter.com/projects/mwlucas/dear-abyss-the-freebsd-journal-letters-column-years-1-6" target="_blank" rel="noreferrer"&gt;Dear Abyss&lt;/a&gt; through the Kickstarter. When it arrived in my email inbox, Bookfunnel didn&amp;rsquo;t have an option to download it as PDF. It did, however, have an EPUB option.&lt;/p&gt;
&lt;p&gt;Luckily, I know how to do the conversion. It took me a minute or two to remember, so this time I&amp;rsquo;m writing it down.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Calibre with &lt;code&gt;sudo apt install calibre&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run Calibre from the command line &lt;code&gt;calibre&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click the &amp;ldquo;Add books&amp;rdquo; button. &lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="a green button with a plus symbol on it and the words Add books below it"
width="103"
height="79"
src="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/add-books.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/add-books.png 800w, https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/add-books.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/add-books.png"&gt;&lt;/figure&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the ePub file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click the &amp;ldquo;Convert books&amp;rdquo; button. &lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="a brown button with two curving arrows on it and the words Convert books below it"
width="126"
height="78"
src="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/convert-books.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/convert-books.png 800w, https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/convert-books.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/convert-books.png"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the Output format to PDF in the dialog that pops up. &lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A text widget called Output format with an underscore under the O in output, to the right of which is a drop-down. PDF is selected in the dropdown."
width="213"
height="34"
src="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/output-format-pdf.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/output-format-pdf.png 800w, https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/output-format-pdf.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-12-07-converting-epub-to-pdf/images/output-format-pdf.png"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click &amp;ldquo;OK&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Calibre spins for a bit and then deposits the PDF in the library directory. In my case that was &amp;ldquo;~/Calibre Library/(author)/(title) (n)&amp;rdquo;, where n is the number of the book in the library.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And there you go — next time I&amp;rsquo;ll remember this.&lt;/p&gt;</description></item><item><title>Removing Copilot from Windows 10 (at least today)</title><link>https://andrewmemory.acornwall.net/blog/2024-12-02-removing-copilot-from-windows-10/</link><pubDate>Mon, 02 Dec 2024 22:05:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-12-02-removing-copilot-from-windows-10/</guid><description>&lt;p&gt;It finally happened — after my latest Windows update, I had a Copilot button on my desktop. I didn&amp;rsquo;t ask for it, didn&amp;rsquo;t want it, but Microsoft knows better than you do. Here&amp;rsquo;s my best attempt to kill it with fire.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Remove it from Edge. Open Edge, go to Settings, type Copilot, click on that and turn off &amp;ldquo;Show Copilot&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove it from the task bar by clicking &amp;ldquo;Unpin from Taskbar&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run gpedit.msc and go to User Configuration -&amp;gt; Administrative Templates -&amp;gt; Windows Components -&amp;gt; Windows Copilot. Open that and double-click on &amp;ldquo;Turn off Windows Copilot.&amp;rdquo; Select &amp;ldquo;Enabled&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure you have TurnOffWindowsCopilot set to 1 (DWORD 32-bit) under HKCU\Software\Policies\Microsoft\Windows\WindowsCopilot.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Uninstall the Windows Copilot component under Add/Remove Software.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Block copilot.microsoft.com connections at DNS.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;local-zone: &amp;#34;copilot.microsoft.com&amp;#34; redirect
local-data: &amp;#34;copilot.mircosoft.com A 127.0.0.1&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Odds are good that won&amp;rsquo;t be sufficient, but maybe that will last until Microsoft gives up on Windows 10 updates.&lt;/p&gt;</description></item><item><title>Adding code titles (filenames) to astro-micro-academic</title><link>https://andrewmemory.acornwall.net/blog/2024-11-17-adding-code-titles-to-astro-micro-academic/</link><pubDate>Sun, 17 Nov 2024 18:53:29 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-11-17-adding-code-titles-to-astro-micro-academic/</guid><description>&lt;p&gt;I wanted to add code titles to astro-micro-academic. I&amp;rsquo;m brand new at this so here&amp;rsquo;s instructions that a newbie can use. I&amp;rsquo;m using &lt;a href="https://medium.com/@hrishikeshb2pathak/how-to-add-filename-to-a-code-block-in-astro-blog-e0e91a4928e" target="_blank" rel="noreferrer"&gt;How to add filename to a code block in Astro blog&lt;/a&gt; as my guide.&lt;/p&gt;
&lt;p&gt;First, install the &lt;code&gt;remark-code-titles&lt;/code&gt; plugin:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ cd ~/myblogdirectory
$ npm install remark-code-titles&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, edit &lt;code&gt;astro.config.mjs&lt;/code&gt;. I added this line:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;import remarkCodeTitles from &amp;#34;remark-code-titles&amp;#34;;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and also added&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; remarkPlugins: [remarkCodeTitles],&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to the markdown: section. Ultimately, my astro.config.mjs ended up looking like this:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;./astro.config.mjs&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@astrojs/tailwind&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;astro/config&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rehypeHeadingIds&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@astrojs/markdown-remark&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;remarkToc&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;remark-toc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rehypeAccessibleEmojis&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;rehype-accessible-emojis&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;rehypeKatex&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;rehype-katex&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;remarkMath&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;remark-math&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;remarkEmoji&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;remark-emoji&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;remarkCodeTitles&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;remark-code-titles&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mdx&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@astrojs/mdx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;sitemap&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@astrojs/sitemap&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;pagefind&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;astro-pagefind&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// https://astro.build/config
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://astro-micro-academic.vercel.app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;integrations&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tailwind&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;sitemap&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;mdx&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;pagefind&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;markdown&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;shikiConfig&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;css-variables&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;rehypePlugins&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;rehypeHeadingIds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rehypeAccessibleEmojis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rehypeKatex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;remarkPlugins&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;remarkToc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;remarkMath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;remarkEmoji&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;remarkPlugins&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;remarkCodeTitles&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, I needed to do something in CSS to make the headers look good. Here&amp;rsquo;s what I came up with to add to the end of global.css:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;./src/styles/global.css&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;remark-code-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@apply&lt;/span&gt; &lt;span class="err"&gt;border-dashed&lt;/span&gt; &lt;span class="err"&gt;border-2&lt;/span&gt; &lt;span class="err"&gt;border-indigo-600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@apply&lt;/span&gt; &lt;span class="err"&gt;bg-neutral-300&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bg-slate-800&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;astro-code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;@apply&lt;/span&gt; &lt;span class="err"&gt;mt-0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Here&amp;rsquo;s how to use them:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;``&lt;span class="sb"&gt;`bash:/usr/local/bin/file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;My file contents
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;`&lt;/span&gt;``&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;or if you don&amp;rsquo;t have a file type:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;``&lt;span class="sb"&gt;`:/tmp/file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;My file contents
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;`&lt;/span&gt;``&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Incidentally, the file types appear to be listed at &lt;a href="https://github.com/jincheng9/markdown_supported_languages" target="_blank" rel="noreferrer"&gt;github.com/jincheng9/markdown_supported_languages&lt;/a&gt;. (Hey, Smalltalk is a supported language! Cool!)&lt;/p&gt;
&lt;p&gt;Some day I&amp;rsquo;ll need to look into what that &lt;code&gt;site: &amp;quot;https://astro-micro-academic.vercel.app&amp;quot;,&lt;/code&gt; implies. I think I&amp;rsquo;ll have to change it to my site when I go live.&lt;/p&gt;</description></item><item><title>Installing VNC on Ubuntu 24.04 with X</title><link>https://andrewmemory.acornwall.net/blog/2024-11-17-installing-x11vnc-on-ubuntu-24.04/</link><pubDate>Sun, 17 Nov 2024 16:51:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-11-17-installing-x11vnc-on-ubuntu-24.04/</guid><description>&lt;p&gt;After I &amp;ldquo;upgraded&amp;rdquo; to Ubuntu 24.04, I had to install X in order to use xscreensaver, since Wayland is way too immature. This meant I couldn&amp;rsquo;t use the integrated VNC, so I had to install another one. I found a good starting point at &lt;a href="https://forums.bunsenlabs.org/viewtopic.php?id=2154" target="_blank" rel="noreferrer"&gt;forums.bunselnabs.org&lt;/a&gt;. I ended up making a few changes. First, I needed VNC and xscreensaver and needed to add it to the autostart:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install x11vnc xscreensaver
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir ~/.x11vnc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;x11vnc -storepassword mySecretPassword ~/.x11vnc/passwd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir ~/.config/autostart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then I created files much like those from BunsenLabs. I made a few changes to get things to work and to secure them.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;~/.config/autostart/x11vnc.desktop&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=X11VNC
Comment=Start the X11 VNC server
Exec=/usr/local/bin/x11vnc-start
StartupNotify=false
Terminal=false
Hidden=false&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;~/.config/autostart/xscreensaver-desktop&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=XSSVR
Comment=Start the X screensaver
Exec=/usr/local/bin/xscreensaver-start
StartupNotify=false
Terminal=false
Hidden=false&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;/usr/local/bin/xscreensaver-start&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash -
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&lt;/span&gt;/usr/bin/xscreensaver -no-splash &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;figure class="highlight"&gt;
&lt;figcaption&gt;&lt;span&gt;&lt;mark&gt;/usr/local/bin/x11vnc-start&lt;/mark&gt;&lt;/span&gt; &lt;/figcaption&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash -
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&lt;/span&gt;/usr/bin/x11vnc -forever -display &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$DISPLAY&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -rfbauth /home/&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$USER&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;/.x11vnc/passwd &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Set up some good permissions:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;600&lt;/span&gt; ~/.x11vnc/passwd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;700&lt;/span&gt; ~/.x11vnc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;755&lt;/span&gt; /usr/local/bin/xscreensaver-start
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;755&lt;/span&gt; /usr/local/bin/x11vnc-start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Disable Automatic Screen Lock in Gnome&amp;rsquo;s Privacy settings. Configure xscreensaver with &lt;code&gt;xscreensaver-settings&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Shutdown and restart to make sure it works — that you can VNC in, that VNC requires the right password, and that the screensaver comes on when expected. The autostart commands show up in Startup Applications, which is nice. I can also type capital letters on this VNC — I couldn&amp;rsquo;t do that on the 22.04 integrated VNC.&lt;/p&gt;</description></item><item><title>Building Emacs 29.4 on Ubuntu 22.04</title><link>https://andrewmemory.acornwall.net/blog/2024-08-24-building-emacs-29-4-on-ubuntu-22-04/</link><pubDate>Sat, 24 Aug 2024 20:10:15 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-08-24-building-emacs-29-4-on-ubuntu-22-04/</guid><description>&lt;p&gt;I recently had to rebuild Emacs to &lt;a href="https://andrewmemory.acornwall.net/blog/2024-08-24-locking-weirdness-between-ubuntu-cifs-and-emacs/" &gt;diagnose a problem&lt;/a&gt;. It turned out the problem wasn&amp;rsquo;t the Ubuntu Emacs build, but since I had to figure it out, I&amp;rsquo;m writing it down so I will remember next time.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Grab the GNU public keys
&lt;div id="grab-the-gnu-public-keys" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#grab-the-gnu-public-keys" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;GNU has to be different. Rather than signing with some sane thing, they sign their files with gpg. 🙄 Anyway, here&amp;rsquo;s how to do that:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ curl https://ftp.gnu.org/gnu/gnu-keyring.gpg --output gnu-keyring.gpg$ gpg --import gnu-keyring.gpg
# Yes, it just imported 552 keys.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Download Emacs and validate the signature
&lt;div id="download-emacs-and-validate-the-signature" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#download-emacs-and-validate-the-signature" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Feel free to substitute your favorite &lt;a href="https://www.gnu.org/prep/ftp.en.html#gnu_mirror_list" target="_blank" rel="noreferrer"&gt;mirror&lt;/a&gt; for ftp.gnu.org&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ curl https://ftp.gnu.org/gnu/emacs/emacs-29.4.tar.gz.sig --output emacs-29.4.tar.gz.sig
$ curl https://ftp.gnu.org/gnu/emacs/emacs-29.4.tar.gz --output emacs-29.4.tar.gz
$ gpg --verify emacs-29.4.tar.gz.sig
emacs-29.4.tar.gz
gpg: Signature made Sat 22 Jun 2024 08:04:31 AM MST
gpg: using RSA key BB02E407AE9EAA87C9E72A1D2D4E1FE95957135D
gpg: issuer &amp;#34;stefankangas@gmail.com&amp;#34;gpg: Good signature from &amp;#34;Stefan Kangas &amp;lt;stefan@marxist.se&amp;gt;&amp;#34; [expired]
gpg: aka &amp;#34;Stefan Kangas &amp;lt;skangas@skangas.se&amp;gt;&amp;#34; [expired]
gpg: Note: This key has expired!
Primary key fingerprint: CEA1 DE21 AB10 8493 CC9C 6574 2E82 323B 8F43 53EE
Subkey fingerprint: BB02 E407 AE9E AA87 C9E7 2A1D 2D4E 1FE9 5957 135D&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I guess? that means it&amp;rsquo;s trustworthy?&lt;/p&gt;
&lt;h2 class="relative group"&gt;Install dependencies
&lt;div id="install-dependencies" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#install-dependencies" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;In order to build you&amp;rsquo;ll need some dependencies, so install those using apt.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt install libgtk-3-dev libgif-dev libgnutls28-dev texinfo&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Extract, build and install Emacs
&lt;div id="extract-build-and-install-emacs" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#extract-build-and-install-emacs" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Next, extract the files. Then configure Emacs for your environment, build it and finally install it.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ tar xzvf emacs-29.4.tar.gz
$ cd emacs-29.4/
$ ./configure (or use ./configure --with-x-toolkit=no if you don&amp;#39;t want X support)
$ make clean; make
$ sudo make install (this installs emacs in /usr/local/bin)
$ /usr/local/bin/emacs
(if you want to uninstall)
$ sudo make uninstall&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This build installed Emacs in /usr/local/bin, which is ahead of /usr/bin in my path, so I can have both the version I built and the package version installed at the same time. Either change your path, alias emacs=/usr/local/bin/emacs, or uninstall the Ubuntu emacs package.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Clean up
&lt;div id="clean-up" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#clean-up" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Once you&amp;rsquo;re done, you can remove libgtk-3-dev, libgif-dev, libgnutls28-dev and texinfo. Or keep &amp;rsquo;em around, they won&amp;rsquo;t hurt anything.&lt;/p&gt;</description></item><item><title>Locking weirdness between Ubuntu, CIFS and Emacs</title><link>https://andrewmemory.acornwall.net/blog/2024-08-24-locking-weirdness-between-ubuntu-cifs-and-emacs/</link><pubDate>Sat, 24 Aug 2024 01:37:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-08-24-locking-weirdness-between-ubuntu-cifs-and-emacs/</guid><description>&lt;p&gt;I&amp;rsquo;d run into a strange problem that made working with Emacs really painful. Any time I edited a file with Emacs on my CIFS mounted drive on Ubuntu 22.04, I&amp;rsquo;d see:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Unlocking file: Invalid argument&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;hellip; when I opened it. Then, when I tried to save, I&amp;rsquo;d get a message that the save failed. I couldn&amp;rsquo;t exit Emacs, even when I said to abandon changes. (The changes themselves got saved successfully.) I could kill with a SIGTERM, but that left the file locked so I couldn&amp;rsquo;t edit it again.&lt;/p&gt;
&lt;p&gt;I tried rebuilding Emacs from source. Same issue. I suspect there&amp;rsquo;s a problem with CIFS file locking everywhere on Ubuntu, not just Emacs. Some day I&amp;rsquo;ll turf the Ubuntu built-in CIFS and go back to Samba. In the meantime, sometimes all you have is a rock when you want to pound in a nail. Adding:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;;; Something weird going on with file locking on CIFS. Disable it.
(setq create-lockfiles nil)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to my ~/.emacs solved the problem.&lt;/p&gt;</description></item><item><title>Changing the MTA's maximum message size (postfix)</title><link>https://andrewmemory.acornwall.net/blog/2024-06-13-changing-the-mtas-maximum-message-size-postfix/</link><pubDate>Thu, 13 Jun 2024 23:36:45 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-06-13-changing-the-mtas-maximum-message-size-postfix/</guid><description>&lt;p&gt;I have a local machine that I use for backup. For the past week I haven&amp;rsquo;t been seeing status messages. Looking into my /var/log/syslog, I saw:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Jun 13 04:37:07 foureyes postfix/postdrop[138227]: warning: uid=0: File too large
Jun 13 04:37:08 foureyes postfix/sendmail[138226]: warning: mail_stream_cleanup: close error
Jun 13 04:37:08 foureyes postfix/sendmail[138226]: fatal: root(0): message file too big
Jun 13 04:37:08 foureyes CRON[138018]: (root) MAIL (mailed 12798406 bytes of output but got status 0x004b from MTA#012)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I guess that means what I&amp;rsquo;m printing out for the backup is bigger than the ~10M that the Postfix default allows. Time to do something about that:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ postconf | grep message_size_limitmessage_size_limit = 10240000
$ sudo postconf message_size_limit=0
$ postconf | grep message_size_limitmessage_size_limit = 0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Hopefully that did it.&lt;/p&gt;</description></item><item><title>Setting up and using Uniden Sentinel BCDx36HP on Ubuntu 22.04 under Wine</title><link>https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/</link><pubDate>Mon, 15 Jan 2024 22:37:00 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/</guid><description>&lt;p&gt;I finally have had success in programming my Uniden BCD436 (and would probably succeed with the Uniden BCD586 if I owned one) under Wine! This has been a problem that has persisted for ages, and now it appears that things have advanced enough that it&amp;rsquo;s possible.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Installation
&lt;div id="installation" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#installation" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;First, uninstall Wine: (&lt;strong&gt;warning&lt;/strong&gt;: this will blow away all your Wine configs, so if you use it for more than just Sentinel, save everything first)&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt remove wine
$ sudo apt autoremove&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, install Wine from the WineHQ repo by adding the winehq key, adding it to your list of repos, and instaling the package (these instructions come from &lt;a href="https://wiki.winehq.org/Ubuntu" target="_blank" rel="noreferrer"&gt;https://wiki.winehq.org/Ubuntu&lt;/a&gt;):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key
$ sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources$ wine --versionwine-8.0.2&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Install Sentinel. Download it from &lt;a href="https://info.uniden.com/" target="_blank" rel="noreferrer"&gt;info.uniden.com&lt;/a&gt; and you&amp;rsquo;ll have a zip file with a name like: BCDx36HP_Sentinel_Version_2_&lt;em&gt;xx&lt;/em&gt;_&lt;em&gt;yy&lt;/em&gt;.zip&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ unzip BCDx36HP_Sentinel_Version_2_xx_yy.zip$ cd BCDx36HP_Sentinel_Version_2_xx_yy$ wine setup.exe&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Welcome to the BCDx36HP Sentinel Setup Wizard"
width="486"
height="112"
src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/sentinel-install.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/sentinel-install.png 800w, https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/sentinel-install.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/sentinel-install.png"&gt;&lt;/figure&gt;
&lt;p&gt;Follow the normal Sentinel setup procedure.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got Sentinel data files stored on my shared drive. Because of this, I had to do the following to get it reading my shared config. You probably won&amp;rsquo;t do this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Start Sentinel and download the master database.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exit Sentinel&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;cd ~/.wine/drive_c/users/_myuser_/Documents/Uniden&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;mv BCDx36HP BCDx36HP-old&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ln -s /my/shared/uniden/data-directory BCDx36HP&lt;/code&gt; (this is the directory on the SMB share that contains ActivityLog, DiscoveryLog, FavoriteLists and Profile)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start Sentinel again and confirm you can read it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exit Sentinel&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Using Sentinel
&lt;div id="using-sentinel" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#using-sentinel" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I adapted these instructions from &lt;a href="https://wiki.radioreference.com/index.php/Sentinel_%5C%28Uniden_software%5C%29#Using_Sentinel_Under_Wine" target="_blank" rel="noreferrer"&gt;https://wiki.radioreference.com/index.php/Sentinel_(Uniden_software)#Using_Sentinel_Under_Wine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Step 1: Connect the BCD436 to your Linux device by turning it on and selecting &amp;ldquo;Mass Storage Mode&amp;rdquo; (press the E/yes key). You&amp;rsquo;ll see it automount on Linux.&lt;/p&gt;
&lt;p&gt;Step 2: Start Sentinel by clicking on Activities in the upper left and typing bcd, then clicking on the icon:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Typing bcd in Activities"
width="395"
height="225"
src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/start-sentinel.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/start-sentinel.png 800w, https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/start-sentinel.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/start-sentinel.png"&gt;&lt;/figure&gt;
&lt;p&gt;Step 3: Cancel out of the &amp;ldquo;Run updates&amp;rdquo; dialog. Instead, run &lt;code&gt;winecfg&lt;/code&gt; from the terminal.&lt;/p&gt;
&lt;p&gt;Step 4: In the dialog that comes up, click the Drives tab and then use cursor down to highlight the drive letter of the /media/ path that Ubuntu used when it automounted the drive.&lt;/p&gt;
&lt;p&gt;Step 5: Click &amp;ldquo;Show Advanced&amp;rdquo; and change the Type from &amp;ldquo;Autodetect&amp;rdquo; to &amp;ldquo;Floppy Disk&amp;rdquo;. Press &amp;ldquo;Apply&amp;rdquo; and then &amp;ldquo;OK&amp;rdquo;.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Selecting Floppy disk under the Type field of the Drives tab of the Wine Config dialog"
width="406"
height="482"
src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/winecfg.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/winecfg.png 800w, https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/winecfg.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/winecfg.png"&gt;&lt;/figure&gt;
&lt;p&gt;Step 6: In Sentinel, Update -&amp;gt; Update Firmware&amp;hellip;&lt;/p&gt;
&lt;p&gt;If all went well, you should see:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The Sentinel utility with an option to mapped a microSD drive to a drive letter for the scanner"
width="450"
height="290"
src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/readfromscanner.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/readfromscanner.png 800w, https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/readfromscanner.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/readfromscanner.png"&gt;&lt;/figure&gt;
&lt;p&gt;Step 7. Click OK. Your firmware just got updated.&lt;/p&gt;
&lt;p&gt;At this point you should be able to Update -&amp;gt; Update Master Database(HPDB). You can also make changes. Once you&amp;rsquo;ve made your changes, Scanner -&amp;gt; Write to Scanner&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the Linux driver that talks to the scanner can be very slow when writing. You&amp;rsquo;ll have plenty of time to get a coffee, especially if you select &amp;ldquo;Force Write Full Database&amp;rdquo;. Just remember to come back in time to tell Sentinel how to handle conflicts.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A dialog box titled BCDx36HP Sentinel with the text &amp;ldquo;Finished writing to the scanner&amp;rdquo;"
width="519"
height="189"
src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/completed-1.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/completed-1.png 800w, https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/completed-1.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/completed-1.png"&gt;&lt;/figure&gt;
&lt;p&gt;Step 8: When you&amp;rsquo;re done, shut down Sentinel and then unmount the device, then eject it:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The USB unmount/eject icon with Unmount selected"
width="198"
height="101"
src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/unmount.png"
srcset="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/unmount.png 800w, https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/unmount.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2024-01-15-setting-up-and-using-uniden-sentinel-bcdx36hp-on-ubuntu-22-04-under-wine/images/unmount.png"&gt;&lt;/figure&gt;
&lt;p&gt;Turn the radio off. Then unplug the cable. Congratulations, you&amp;rsquo;re done.&lt;/p&gt;</description></item><item><title>Stop "[Application]" Is Not Responding on Ubuntu 22.04/Gnome</title><link>https://andrewmemory.acornwall.net/blog/2023-10-28-stop-application-is-not-responding-on-ubuntu-22-04-gnome/</link><pubDate>Sat, 28 Oct 2023 14:17:41 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-28-stop-application-is-not-responding-on-ubuntu-22-04-gnome/</guid><description>&lt;p&gt;Since upgrading to Ubuntu 22.04, I&amp;rsquo;ve been seeing a lot more of those messages from Gnome that say:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;/p&gt;
\[Some Application\]&lt;p&gt;&amp;rdquo; is not responding. You may choose to wait a short while for it to continue or force the application to quit entirely.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A dialog that reads &amp;ldquo;Thunderbird Mail&amp;rdquo; is not responding. You may choose to wait a short while for it to continue or force the application to quit entirely. There are two buttons, &amp;ldquo;Force Quit&amp;rdquo; and &amp;ldquo;Wait&amp;rdquo;"
width="494"
height="163"
src="https://andrewmemory.acornwall.net/blog/2023-10-28-stop-application-is-not-responding-on-ubuntu-22-04-gnome/images/not-responding.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-28-stop-application-is-not-responding-on-ubuntu-22-04-gnome/images/not-responding.png 800w, https://andrewmemory.acornwall.net/blog/2023-10-28-stop-application-is-not-responding-on-ubuntu-22-04-gnome/images/not-responding.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-28-stop-application-is-not-responding-on-ubuntu-22-04-gnome/images/not-responding.png"&gt;&lt;/figure&gt;
&lt;p&gt;Probably Ubuntu 22.04 takes up more resources on my underpowered mini PC. This error pops up when an app is not responsive for more than 5 seconds.&lt;/p&gt;
&lt;p&gt;Luckily, that timeout is configurable. I&amp;rsquo;m not as impatient as the Gnome developers, so I adjusted mine to 15 seconds. In theory this gets stored so you don&amp;rsquo;t need to do anything to make it permanent:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ gsettings get org.gnome.mutter check-alive-timeout uint32 5000
$ gsettings set org.gnome.mutter check-alive-timeout 15000&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;You probably don&amp;rsquo;t want to set this much below 1000 or you&amp;rsquo;re going to be dealing with lots of dialogs that block the rest of the UI.&lt;/p&gt;</description></item><item><title>Block Ad Sites and Nasties on OpenBSD 7.4</title><link>https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/</link><pubDate>Sun, 22 Oct 2023 22:03:47 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/</guid><description>&lt;p&gt;One of the benefits of building your own firewall is that you get to decide what you want to block. I&amp;rsquo;d been using a list from &lt;a href="https://pgl.yoyo.org/adservers" target="_blank" rel="noreferrer"&gt;pgl.yoyo.org/adservers&lt;/a&gt;. There&amp;rsquo;s a utility called &lt;a href="https://www.geoghegan.ca/pfbadhost.html" target="_blank" rel="noreferrer"&gt;Pf-badhost&lt;/a&gt; that blocks evil hosts. I wanted to do a little more: block bad IPs (sorry, Cloudflare, I know you hate that) and have better control over when things get updated.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A virus/malware hazard icon"
width="335"
height="334"
src="https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/images/virus_malware_hazard_icon.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/images/virus_malware_hazard_icon.png 800w, https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/images/virus_malware_hazard_icon.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/images/virus_malware_hazard_icon.png"&gt;&lt;/figure&gt;
&lt;p&gt;So I ultimately decided to adapt some of Pf-badhost to a few scripts I created. First, a script to get the latest list of bad hostnames from pgl.yoyo.org — grab-bad-hosts.sh:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Grabbing Bad Hostnames
&lt;div id="grabbing-bad-hostnames" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#grabbing-bad-hostnames" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#! /bin/sh
/usr/local/bin/wget -O ./pgl-adhosts.conf &amp;#39;https://pgl.yoyo.org/adservers/serverlist.php?hostformat=unbound&amp;amp;showintro=1&amp;amp;mimetype=plaintext&amp;#39;
grep -v -f /var/unbound/etc/unbound-whitelist-ads.txt pgl-adhosts.conf &amp;gt; unbound-adhosts.conf
grep -f /var/unbound/etc/unbound-whitelist-ads.txt pgl-adhosts.conf &amp;gt; unbound-adhosts-whitelist.conf
echo &amp;#34;In a root shell, run:&amp;#34;
echo &amp;#34;cat unbound-adhosts.conf &amp;gt; /var/unbound/etc/unbound-adhosts.conf&amp;#34;
echo &amp;#34;cat unbound-adhosts-whitelist.conf &amp;gt; /var/unbound/etc/unbound-adhosts-whitelist.conf&amp;#34;
echo &amp;#34;rcctl restart unbound&amp;#34;
echo &amp;#34;(or run root-update-hosts.sh as root)&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This builds two files: /var/unbound/etc/unbound-adhosts.conf and /var/unbound/etc/unbound-adhosts-whitelists.conf based on a file I created, /var/unbound/etc/unbound-whitelist-ads.txt, which I had to add to make other users happy. /var/unbound/etc/unbound-whitelist-ads.txt looks like this:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;adservice.google.com[^.]
googleadservices.com[^.]&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;hellip; and I&amp;rsquo;m going to set up unbound to allow one host to have the whitelisted ads.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Grabbing &lt;strong&gt;B&lt;/strong&gt;ad IPs
&lt;div id="grabbing-bad-ips" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#grabbing-bad-ips" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I used Pf-badhost as a source of places to grab bad IP addresses from. I ended up with this script, grab-bad-ips.sh:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#! /bin/sh
/usr/local/bin/wget -O ./banlist_firehol_level1 https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset
/usr/local/bin/wget -O ./banlist_firehol_level2 https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level2.netset
/usr/local/bin/wget -O ./banlist_binarydefence https://www.binarydefense.com/banlist.txt
/usr/local/bin/wget -O ./banlist_emergingthreats https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt
cat ./banlist_firehol_level1 &amp;gt; pf-badguys.table
printf &amp;#34;\n&amp;#34;&amp;gt;&amp;gt; pf-badguys.table
cat ./banlist_firehol_level2 &amp;gt;&amp;gt; pf-badguys.table
printf &amp;#34;\n&amp;#34;&amp;gt;&amp;gt; pf-badguys.table
cat ./banlist_binarydefence &amp;gt;&amp;gt; pf-badguys.table
printf &amp;#34;\n&amp;#34;&amp;gt;&amp;gt; pf-badguys.table
cat ./banlist_emergingthreats &amp;gt;&amp;gt; pf-badguys.table
printf &amp;#34;\n&amp;#34;&amp;gt;&amp;gt; pf-badguys.table
grep &amp;#39;^[0-9]&amp;#39; pf-badguys.table | sort | uniq &amp;gt; pf-badguys.table.sort.uniq
mv pf-badguys.table.sort.uniq pf-badguys.table
echo &amp;#34;In a root shell, run:&amp;#34;
echo &amp;#34; cat pf-badguys.table &amp;gt; /etc/pf-badguys.table&amp;#34;
echo &amp;#34; pfctl -F Tables -f /etc/pf.conf&amp;#34;
echo &amp;#34;(or run root-update-ips.sh as root)&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This script creates /etc/pf-badguys.table, which I&amp;rsquo;ll plug into my PF configuration.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Configuring unbound to use the bad hosts lists
&lt;div id="configuring-unbound-to-use-the-bad-hosts-lists" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configuring-unbound-to-use-the-bad-hosts-lists" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s not hard to have unbound import the bad hosts, which are already formatted to redirect to 127.0.0.1. Here&amp;rsquo;s a sample from /var/unbound/etc/unbound-adhosts.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;local-zone: &amp;#34;1-1ads.com&amp;#34; redirect
local-data: &amp;#34;1-1ads.com A 127.0.0.1&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;unbound-adhosts-whitelist.conf looks the same, but only contains the whitelisted ad servers. After the last local-data:/local-data-ptr: pair for my network, I added the following:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; # open a hole for ad servers
# 192.168.150.180 is unblocked desktop
access-control-view: 192.168.150.180/32 adview&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;After my access-control: directives, I added:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Host addresses - spam to block
#
include: /var/unbound/etc/unbound-adhosts.conf
include: /var/unbound/etc/unbound-adhosts-whitelist.conf
include: /var/unbound/etc/unbound-adhosts-local.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;At the end of the unbound.conf file I added:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;view:
name: &amp;#34;adview&amp;#34;
include: /var/unbound/etc/unbound-adhosts.conf
include: /var/unbound/etc/unbound-adhosts-local.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then a quick:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# unbound-checkconf
# rcctl restart unbound&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;hellip; and I was blocking ad servers. I could update this in cron, but I prefer to do it manually every week or so.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Configuring PF to block the bad IP addresses
&lt;div id="configuring-pf-to-block-the-bad-ip-addresses" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configuring-pf-to-block-the-bad-ip-addresses" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I know there&amp;rsquo;s an argument for not blocking bad IP addresses. After all, there may be legitimate sites that are hosted on the same IP address. But&amp;hellip; so far I&amp;rsquo;ve only run into one. So I&amp;rsquo;m happy to continue blocking them. In my pf.conf, after the &lt;martians&gt; table, I added a &lt;badguys&gt; table:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;table &amp;lt;badguys&amp;gt; persist file &amp;#34;/etc/pf-badguys.table&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then after the block for martians, I added an equivalent for badguys:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Block addresses in the badguys table
# We use the &amp;#34;quick&amp;#34; parameter here to make this rule the last.
# Note that badguys might contain martians, but they get handled before
# this rule.
block in quick on $ext_if from &amp;lt;badguys&amp;gt; to any
block return out quick on $ext_if from any to &amp;lt;badguys&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then &lt;code&gt;pfctl -F Tables -f /etc/pf.conf&lt;/code&gt; to reread the table.&lt;/p&gt;
&lt;p&gt;This post is part of a series on &lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/" &gt;setting up an OpenBSD 7.4 firewall device&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Setting up Wireguard on an OpenBSD 7.4 firewall device</title><link>https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/</link><pubDate>Sun, 22 Oct 2023 21:09:01 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/</guid><description>&lt;p&gt;It took me a little while after I set up my firewall device to set up Wireguard as a VPN. It&amp;rsquo;s probably something I should have done right away — the benefits of being able to log in from home (and block ads) while on the road is really nice.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The Wireguard logo"
width="300"
height="300"
src="https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/images/wireguard_logo-1.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/images/wireguard_logo-1.png 800w, https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/images/wireguard_logo-1.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/images/wireguard_logo-1.png"&gt;&lt;/figure&gt;
&lt;p&gt;Wireguard needs a publicly available IP or domain name. I used DuckDNS. I &lt;a href="https://andrewmemory.acornwall.net/blog/2023-05-20-setting-up-duckdns-on-openbsd/" &gt;posted about that&lt;/a&gt; a while back so I won&amp;rsquo;t do it again here, but you&amp;rsquo;ll need to do that first.&lt;/p&gt;
&lt;p&gt;Wireguard is in the kernel in 7.4. Prior releases required you to &lt;code&gt;pkg_add wireguard_tools&lt;/code&gt;, but these days you don&amp;rsquo;t need to.&lt;/p&gt;
&lt;p&gt;The way Wireguard works is that you generate public and private keys. Each device gets its own private key, and you share the public keys. Wireguard has tools to do that. On the OpenBSD firewall side:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# mkdir /etc/wireguard
# chmod 700 /etc/wireguard
# wg genkey &amp;gt; /etc/wireguard/private.key
# chmod 600 /etc/wireguard/private.key
# wg pubkey &amp;lt; private.key &amp;gt; public.key&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, you need to generate private and public keys on each of your clients. Then set up /etc/wireguard/wg0.conf to contain the firewall&amp;rsquo;s private key and also the public keys of the client. I decided to do this on a completely different network — 172.16. I assigned individual IP addresses for each device. It&amp;rsquo;s a little more management headache, but makes it easy to delete something if I lose a device. The /etc/wireguard/wg0.conf looks like this:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;[Interface]
PrivateKey = the private key from /etc/wireguard/private.key
ListenPort = 51820
[Peer]
# My first peer - a laptop
PublicKey = the public key from the laptop
AllowedIPs = 172.16.0.2
[Peer]
# My second peer - an Android device running Wireguard from F-Droid
PublicKey = the public key from the device
AllowedIPs = 172.16.0.3
# ... etc...&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Obviously, on each device you have to do the reverse: specify the private key generated on device, and put the firewall&amp;rsquo;s public key in as the peer. Next, you need an /etc/hostname.wg0 to bring the network up:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;inet 172.16.0.1 255.255.255.0 NONE up
!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Before you can go further, you need to unblock the Wireguard interface in /etc/pf.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;(after the lan_if macro)
vpn_if=&amp;#34;wg0&amp;#34;
vpn_port=&amp;#34;51820&amp;#34;
(at the end after the NAT rules)
#---------------------------------#
# WireGuard
#---------------------------------#
pass in on $vpn_if
pass in inet proto udp from any to any port $vpn_port
pass out on egress inet from ($vpn_if:network) nat-to ($ext_if:0)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;From there, you can restart pf and reload the new rules and &lt;code&gt;sh /etc/netstart wg0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This post is part of a series on &lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/" &gt;setting up an OpenBSD 7.4 firewall device&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Set up networking for an OpenBSD 7.4 firewall device</title><link>https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/</link><pubDate>Sat, 21 Oct 2023 17:14:44 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/</guid><description>&lt;p&gt;I had a few wrinkles because I&amp;rsquo;d already set up networking, and I didn&amp;rsquo;t want to have to go through and redo all my static IPs. But I wanted to make my network more rational. I had devices on 192.168.150.*/24 and I wanted something bigger, so I decided to go with /20. That gave me a range of 92.168.144.1–192.168.159.254. (I admit I used an &lt;a href="https://www.calculator.net/ip-subnet-calculator.html" target="_blank" rel="noreferrer"&gt;IP subnet calculator&lt;/a&gt; for that.) My ISP gives me IPv4, so I&amp;rsquo;m using that and not worrying about IPv6.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt=""
width="221"
height="172"
src="https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/images/wafiz14.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/images/wafiz14.jpg 800w, https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/images/wafiz14.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/images/wafiz14.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;First things first: let&amp;rsquo;s make the box forward packets:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# sysctl net.inet.ip.forwarding=1
# echo &amp;#39;net.inet.ip.forwarding=1&amp;#39; &amp;gt;&amp;gt; /etc/sysctl.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Configure Network Adapters
&lt;div id="configure-network-adapters" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configure-network-adapters" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I have two Intel NICs. I&amp;rsquo;m connecting igc0 to my cable modem. I&amp;rsquo;m connecting igc1 to a 16-port switch which is my internal network. I&amp;rsquo;ve got another network port that was autodetected, but I&amp;rsquo;m not using it yet, so I&amp;rsquo;ll remove it.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# echo &amp;#34;inet autoconf&amp;#34; &amp;gt; /etc/hostname.igc0
# echo &amp;#34;inet 192.168.144.1 255.255.240.0 NONE&amp;#34; &amp;gt; /etc/hostname.igc1
# rm /etc/hostname.igc2
# sh /etc/netstart.sh&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Setting up the PF packet filter
&lt;div id="setting-up-the-pf-packet-filter" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-up-the-pf-packet-filter" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Now, set up PF. I got my instructions for this mostly from &lt;a href="https://home.nuug.no/~peter/pf/en/ftpproblem.html" target="_blank" rel="noreferrer"&gt;home.nuug.no/~peter/pf/en/ftpproblem.html&lt;/a&gt;. Here&amp;rsquo;s how I edited /etc/pf.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#---------------------------------#
# Macros
#---------------------------------#
ext_if=&amp;#34;igc0&amp;#34;
lan_if=&amp;#34;igc1&amp;#34;
ftpproxy=&amp;#34;127.0.0.1&amp;#34;
ftpproxyport=&amp;#34;8021&amp;#34;
#---------------------------------#
# Tables
#---------------------------------#
table &amp;lt;localonly&amp;gt; { \
# Addresses that can talk to the local network but not to the rest of the world
\
# Local printer
192.168.158.1/32 \
}
# This is a table of non-routable private addresses.
table &amp;lt;martians&amp;gt; { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 }
#---------------------------------#
# Protect and block by default
#---------------------------------#
set skip on lo0
set block-policy drop
# Spoofing protection for all NICs.
block in from no-route
block in quick from urpf-failed
# Block non-routable private addresses.
# We use the &amp;#34;quick&amp;#34; parameter here to make this rule the last.
block in quick on $ext_if from &amp;lt;martians&amp;gt; to any
block return out quick on $ext_if from any to &amp;lt;martians&amp;gt;
# Default blocking all traffic in on all LAN NICs from any computer or device
# attached.
block return in on { $lan_if }
# Default blocking all traffic in on the external NIC from the Internet/ISP,
# we&amp;#39;ll log that too.
block drop in log on $ext_if
# Don&amp;#39;t allow ICMP from outside. Commented out this section.
# Yeah, I know people hate that.
#
#match in on $ext_if inet proto icmp icmp-type {echoreq } tag ICMP_IN
#block drop in on $ext_if proto icmp
#pass in proto icmp tagged ICMP_IN max-pkt-rate 100/10
# We need the router to have access to the Internet, so we&amp;#39;ll default allow
# packets to pass out from our router through the external NIC to the Internet.
pass out inet from $ext_if
#---------------------------------#
# LAN Setup
#---------------------------------#
# Allow any computer or device on the LAN to send data packets in through the NIC.
# This means any computer attached to this network interface can pass in data
# reaching anywhere, i.e. the Internet or any of the computers attached to the
# router.
pass in on $lan_if
# Always block DNS queries not addressed to our DNS server.
block return in quick on $lan_if proto { udp tcp } to ! $lan_if port { 53 853 }
# Block localonly from seeing the internet
block in quick on lan_if from &amp;lt;localonly&amp;gt;
# Allow data packets to pass from the router out through the NIC to the
# computers or devices attached to it on the lan NIC.
# Without this we can&amp;#39;t even ping computers attached to the lan NIC from
# the router itself.
pass out on $lan_if inet keep state
#---------------------------------#
# FTP
#---------------------------------#
# allow ftp clients to work
anchor &amp;#34;ftp-proxy/*&amp;#34;
pass in quick on $lan_if inet proto tcp to port ftp divert-to $ftpproxy port $ftpproxyport
# no ftp servers so don&amp;#39;t pass out
# pass out proto tcp from $ftpproxy to any port ftp
#---------------------------------#
# NAT
#---------------------------------#
pass out on $ext_if inet from $lan_if:network to any nat-to ($ext_if)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then you can test things out and restart pf. I think my network connection dropped at this point:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# pfctl -n -f /etc/pf.conf
# pfctl -F all
# pfctl -f /etc/pf.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Configure dhcpd
&lt;div id="configure-dhcpd" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configure-dhcpd" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Now I need to configure serving IPs from this machine. (My old firewall is still on the network at this point and serving real IPs as well as doing DNS, but I need to get the new firewall enabled.) So time to edit /etc/dhcpd.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# $OpenBSD: dhcpd.conf,v 1.1 1998/08/19 04:25:45 form Exp $
#
# DHCP server options.
# See dhcpd.conf(5) and dhcpd(8) for more information.
#
# This is for 192.168.144.* to 192.168.159.*
subnet 192.168.144.0 netmask 255.255.240.0 {
option domain-name &amp;#34;lan.example.net&amp;#34;;
option domain-name-servers 192.168.144.1;
option routers 192.168.144.1;
########################################
# Dynamic IP addresses
########################################
range 192.168.145.1 192.168.149.254;
########################################
# Fixed IP machines that humans don&amp;#39;t
# (normally) see - WAPs etc.
########################################
host wap {
hardware ethernet dc:9f:44:11:22:33;
fixed-address 192.168.144.13;
}
########################################
# Fixed IP machines that humans see.
########################################
# These are machines I normally ssh
# or telnet to, or run servers on.
#
host fileserver {
hardware ethernet 22:33:44:55:66:77;
fixed-address 192.168.150.171;
option host-name &amp;#34;fileserver&amp;#34;;
}
host weather {
hardware ethernet 88:99:00:AA:BB:CC;
fixed-address 192.168.150.177;
option host-name &amp;#34;weather&amp;#34;;
}
#... etc...
# I&amp;#39;m putting my laptop on a non-150 address for testing purposes.
# That way I can plug it into the server and get a DHCP address that
# should route on to the internet.
host laptop {
hardware ethernet 00:22:44:66:88:ff;
fixed-address 192.168.161.2;
}
} # subnet&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, start serving DHCP:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;rcctl enable dhcpd
rcctl start dhcpd&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;At this point I could plug my laptop into the new firewall and get an IP address.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Start Unbound for DNS
&lt;div id="start-unbound-for-dns" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#start-unbound-for-dns" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;On my old firewall I was using bind. That was heavyweight, so I decided to do something different here. Originally I thought I needed NSD and Unbound for DNS (I was looking at some instructions at &lt;a href="https://jamsek.dev/blog/2019/Jul/28/openbsd-dns-server-with-unbound-and-nsd/" target="_blank" rel="noreferrer"&gt;jamsek.dev/blog/2019/Jul/28/openbsd-dns-server-with-unbound-and-nsd/&lt;/a&gt;) but eventually realized I could get away with just unbound.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# rcctl enable unbound
# rcctl start unbound&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, I changed my DNS server so the new firewall was getting it locally instead of going to the old firewall. In /etc/resolv.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;nameserver 127.0.0.1
lookup file bind&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;After that, configure DNSSEC:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# unbound-anchor -a &amp;#34;/var/unbound/db/root.key&amp;#34;
# ftp -S do -o /var/unbound/db/root.hints https://www.internic.net/domain/named.root&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;With root.key downloaded, I could set up my /var/unbound/etc/unbound.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# $OpenBSD: unbound.conf,v 1.21 2020/10/28 11:35:58 sthen Exp $
server:
interface: 192.168.144.1
interface: ::1
# override the default &amp;#34;any&amp;#34; address to send queries; if multiple
# addresses are available, they are used randomly to counter spoofing
access-control: 0.0.0.0/0 refuse
access-control: ::0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: 192.168.144.0/20 allow
access-control: ::1 allow
hide-identity: yes
hide-version: yes
# Perform DNSSEC validation.
#
auto-trust-anchor-file: &amp;#34;/var/unbound/db/root.key&amp;#34;
root-hints: &amp;#34;/var/unbound/db/root.hints&amp;#34;
qname-minimisation: yes
val-log-level: 2
# Synthesize NXDOMAINs from DNSSEC NSEC chains.
# https://tools.ietf.org/html/rfc8198
#
aggressive-nsec: yes
# Serve zones authoritatively from Unbound to resolver clients.
# Not for external service.
#
local-zone: &amp;#34;lan.example.net.&amp;#34; static
#
# Host addresses - infrastructure
#
local-data: &amp;#34;firewall.lan.example.net. IN A 192.168.144.1&amp;#34;
local-data-ptr: &amp;#34;192.168.144.1 firewall.lan.example.net&amp;#34;
#
# Host addresses - named servers
#
local-data: &amp;#34;fileserver.lan.example.net. IN A 192.168.150.171&amp;#34;
local-data-ptr: &amp;#34;192.168.150.171 fileserver.lan.example.net&amp;#34;
local-data: &amp;#34;weather.lan.example.net. IN A 192.168.150.177&amp;#34;
local-data-ptr: &amp;#34;192.168.150.177 weather.lan.example.net&amp;#34;
# ... etc...
remote-control:
control-enable: yes
control-interface: /var/run/unbound.sock&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;With all that set up, I could make sure I didn&amp;rsquo;t have any syntax errors and restart unbound:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# unbound-checkconf
# rcctl restart unbound&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I think it was at this point that I made the switch from using the old firewall to the new firewall. I changed the new firewall to have the same MAC as the old one (my ISP wanted to see a specific MAC) and then put the new one in place:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# echo &amp;#34;inet autoconf lladdr 11:22:33:44:55:66&amp;#34; &amp;gt; /etc/hostname.igc0
# sh /etc/netstart&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Having two devices with the same MAC is a Bad Thing, and I had a lot of weirdness on my network until I unplugged the old firewall.&lt;/p&gt;
&lt;p&gt;This post is part of a series on &lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/" &gt;setting up an OpenBSD 7.4 firewall device&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Setting up an OpenBSD 7.4 Firewall Device</title><link>https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/</link><pubDate>Sun, 15 Oct 2023 23:59:39 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/</guid><description>&lt;p&gt;My &lt;a href="https://www.pcengines.ch/alix.htm" target="_blank" rel="noreferrer"&gt;PC Engines ALIX&lt;/a&gt; running the (mumble) version of OpenBSD has been a great firewall. But now that it looks like PC Engines is &lt;a href="https://www.pcengines.ch/eol.htm" target="_blank" rel="noreferrer"&gt;wrapping up&lt;/a&gt;, it&amp;rsquo;s time to find something new. For a while I&amp;rsquo;ve suspected that the ALIX is a little underpowered. It&amp;rsquo;s harder to find 4G CF cards these days. Plus I want something with a HDMI port so I can put it on a KVM switch and don&amp;rsquo;t need to worry about serial port speeds.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The OpenBSD Puffy logo"
width="300"
height="300"
src="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/images/puffy-firewall-sticker.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/images/puffy-firewall-sticker.png 800w, https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/images/puffy-firewall-sticker.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/images/puffy-firewall-sticker.png"&gt;&lt;/figure&gt;
&lt;p&gt;So&amp;hellip; here&amp;rsquo;s the order of operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/" &gt;Buy new hardware&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/" &gt;Get OpenBSD running on the new hardware&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-21-set-up-networking-for-an-openbsd-7-4-firewall-device/" &gt;Reorganize my network while it&amp;rsquo;s running&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-22-block-ad-sites-and-nasties-on-openbsd-7-4/" &gt;Block ad sites and nasties&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-22-setting-up-wireguard-on-an-openbsd-7-4-firewall-device/" &gt;Add a Wireguard VPN&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here goes!&lt;/p&gt;</description></item><item><title>Installing OpenBSD 7.4 for a Firewall</title><link>https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/</link><pubDate>Sun, 15 Oct 2023 23:45:00 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/</guid><description>&lt;p&gt;Installing OpenBSD 7.4 was pretty simple. I followed the &lt;a href="https://www.openbsd.org/faq/faq4.html" target="_blank" rel="noreferrer"&gt;OpenBSD installation guide&lt;/a&gt; and used dd on a Linux box to write install74.img to a USB stick. Don&amp;rsquo;t use the .iso, it doesn&amp;rsquo;t boot. Then I booted off the USB stick. (You don&amp;rsquo;t have to disable UEFI.) I used a standard layout&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A picture of Puffy, the OpenBSD puffer fish logo"
width="500"
height="500"
src="https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/images/puffy-firewall-sticker-1.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/images/puffy-firewall-sticker-1.png 800w, https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/images/puffy-firewall-sticker-1.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-15-installing-openbsd-7-3-for-a-firewall/images/puffy-firewall-sticker-1.png"&gt;&lt;/figure&gt;
&lt;p&gt;At the time I wondered if I should install all the packages or not. I decided that maintenance would be simpler if I just went for everything, so I added all the packages including X. That turned out to be the right decision.&lt;/p&gt;
&lt;p&gt;I used a relatively standard partitioning scheme, although I think I bumped up a few of the sizes. I probably should have bumped up X11R6 more, right now it&amp;rsquo;s at 41%:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/dev/sd0a 986M /
/dev/sd0l 295G /home
/dev/sd0d 291M /tmp
/dev/sd0f 5.8G /usr
/dev/sd0g 986M /usr/X11R6
/dev/sd0h 19.4G /usr/local
/dev/sd0k 5.8G /usr/obj
/dev/sd0j 2.9G /usr/src
/dev/sd0e 34.4G /var&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Set up doas
&lt;div id="set-up-doas" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#set-up-doas" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;After installing, I set up doas &amp;lsquo;cause I like seatbelts:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ su
# vi /etc/doas.conf
permit persist andrewmemory as root
permit persist keepenv root as root&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Install patches and packages
&lt;div id="install-patches-and-packages" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#install-patches-and-packages" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;After that I installed patches:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ doas syspatch
$ doas shutdown -r now&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next I installed a few useful packages:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ doas pkg_add -i emacs mutt firefox wget &lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I picked the -no_x11 version for emacs, and the normal (not gpge, not sasl, not slang) version for mutt. I&amp;rsquo;m not going to be mailing to the world from this box, just looking at local emails. I also installed Firefox, which turned out to be another good idea. It&amp;rsquo;s a lot easier to search for doc on the firewall box itself than to ssh in.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Set up mfs for /tmp
&lt;div id="set-up-mfs-for-tmp" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#set-up-mfs-for-tmp" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Finally, I&amp;rsquo;m paranoid about wearing out my SSD, so I set up /tmp to be mfs in /etc/fstab using the useful &lt;a href="https://dataswamp.org/~solene/2018-05-08-mfs-tmp.html" target="_blank" rel="noreferrer"&gt;instructions from Solene Rapenne&lt;/a&gt;:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ doas vi /etc/fstab
#f1ea06b71e2dca43.d /tmp ffs rw,nodev,nosuid 1 2
swap /tmp mfs rw,nodev,nosuid,-s=300m 0 0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;hellip; and I had to boot to single-user mode to fix up permissions for /tmp:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ doas umount /tmp
$ doas chmod 1777 /tmp
$ doas mount /tmp&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Apparently &lt;a href="http://undeadly.org/cgi?action=article&amp;amp;sid=20160812011743" target="_blank" rel="noreferrer"&gt;tmpfs has been removed&lt;/a&gt; because it&amp;rsquo;s not supported, so mfs it is. I&amp;rsquo;ve got plenty of RAM for a /tmp file system, but I have delusions of putting most of /var in its own mfs file system, so I restricted /tmp to 300M.&lt;/p&gt;
&lt;p&gt;Once that was done, I could log into a few other machines on my network to establish fingerprints for them. I also tested X by running startx, and then firefox, and it worked.&lt;/p&gt;
&lt;h2 class="relative group"&gt;There were some noisy beeps
&lt;div id="there-were-some-noisy-beeps" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#there-were-some-noisy-beeps" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;By default, OpenBSD rings the bell when you mistype certain things. That was annoying other people in the house, so I had to shut those up. That took two things. In ~/.login I added:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/sbin/wsconsctl keyboard.bell.volume=0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then, I created ~/.xsession and added:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/usr/X11R6/bin/xset b off&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This post is part of a series on &lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/" &gt;setting up an OpenBSD 7.4 firewall device&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Buying new hardware for an OpenBSD firewall</title><link>https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/</link><pubDate>Sun, 15 Oct 2023 23:30:53 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/</guid><description>&lt;p&gt;I knew going in that I wanted more than two ethernet ports for my OpenBSD firewall device. I had visions of multiple networks and/or a spare port that I could use when I screwed up my pf configuration. I also knew that I wanted HDMI so I could pop the firewall on my KVM switch - I&amp;rsquo;d used serial to the APU2 and that was not always wonderful. The Linux box would sometimes forget about the serial ports when they were plugged in for a while.&lt;/p&gt;
&lt;p&gt;In the end, I got a random Intel N5105 mini-PC with four Intel ethernet ports. The &lt;a href="https://www.amazon.com/gp/product/B0B53MKZBX/" target="_blank" rel="noreferrer"&gt;HUNSN Micro Firewall Appliance, Mini PC, VPN, Router PC, Intel N5105, HUNSN RJ03, AES-NI, 4 x Intel 2.5GbE I226-V LAN, Type-C, TF, M.2 WiFi 6 Slot, Barebone, NO RAM, NO Storage, NO System&lt;/a&gt; was around $250 US. Add a Western Digital NVMe &lt;a href="https://www.amazon.com/gp/product/B09HKG6SDF/" target="_blank" rel="noreferrer"&gt;500G drive&lt;/a&gt; and 16G of &lt;a href="https://www.amazon.com/gp/product/B08C4WV6FT/" target="_blank" rel="noreferrer"&gt;Cruical laptop RAM&lt;/a&gt; and I had something on which I could install a system. It&amp;rsquo;s low-powered enough that I don&amp;rsquo;t mind keeping it running 24/7, and high-powered enough that I&amp;rsquo;m not worried about it being a bottleneck.&lt;/p&gt;
&lt;p&gt;[&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The HUNSN Micro Firewall Appliance from the front"
width="359"
height="211"
src="https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/images/hunsn.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/images/hunsn.png 800w, https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/images/hunsn.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-10-15-buying-new-hardware-for-an-openbsd-firewall/images/hunsn.png"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;I learned afterwards that the I226-V might &lt;a href="https://www.reddit.com/r/openbsd/comments/12g637u/experience_with_problematic_intel_i225_25_gbps/" target="_blank" rel="noreferrer"&gt;potentially have a problem&lt;/a&gt; if you want to do 2.5G ethernet. So far, I haven&amp;rsquo;t experienced any network instability because of that.&lt;/p&gt;
&lt;p&gt;As a belt-and-suspenders kind of thing, I bought a &amp;ldquo;silent&amp;rdquo; USB fan that sits on top of the case, just because the server room can get a little warm.&lt;/p&gt;
&lt;p&gt;This post is part of a series on &lt;a href="https://andrewmemory.acornwall.net/blog/2023-10-15-setting-up-an-openbsd-7-4-firewall-device/" &gt;setting up an OpenBSD 7.4 firewall device&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Setting up DuckDNS on OpenBSD</title><link>https://andrewmemory.acornwall.net/blog/2023-05-20-setting-up-duckdns-on-openbsd/</link><pubDate>Sat, 20 May 2023 15:59:54 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-05-20-setting-up-duckdns-on-openbsd/</guid><description>&lt;p&gt;Well, that was easy. I&amp;rsquo;ve been thinking about setting up WireGuard on my firewall. That will give me ad blocking by default as well as a way into my system when I want to do something. But&amp;hellip; that means I need a way to know what my external IP is. Dynamic DNS to the rescue!&lt;/p&gt;
&lt;p&gt;I looked around at the providers, and &lt;a href="http://duckdns.org" target="_blank" rel="noreferrer"&gt;DuckDNS&lt;/a&gt; appears to be the one whose ideology aligns most closely to mine. I went to their &amp;ldquo;Install&amp;rdquo; page and they don&amp;rsquo;t have OpenBSD. But they have something close — linux bsd cron. So I adapted their script to use OpenBSD&amp;rsquo;s ftp (which, despite its name, does https as well) instead of curl, which isn&amp;rsquo;t in the base OpenBSD distribution.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#!/bin/sh -
# Update the DNS at duckdns.org with my IP
DOMAINS=&amp;#34;mydnshost&amp;#34; # comma-separated, just the hostnames, not the FQDNs
TOKEN=&amp;#34;badcafe-dead-beef-b001-fa11ca2eba3e&amp;#34; # from DuckDNS
tmpfile=`/usr/bin/mktemp /tmp/duckdns.XXXXXXXXXX`
if [ $? -ne 0 ]; then
/usr/bin/logger -i -p daemon.err &amp;#34;duckdns update failed, couldn&amp;#39;t create temp file&amp;#34;
exit 1
fi
/usr/bin/ftp -d -o $tmpfile &amp;#34;https://www.duckdns.org/update?domains=${DOMAINS}&amp;amp;token=${TOKEN}&amp;#34;
return_val=$?
url_out=`/bin/cat $tmpfile`
/bin/rm $tmpfile
if [ $return_val -eq 0 ]; then
if [ $url_out == &amp;#34;OK&amp;#34; ]; then
/usr/bin/logger -i -p daemon.info &amp;#34;duckdns update ok&amp;#34;
else
/usr/bin/logger -i -p daemon.info &amp;#34;duckdns update failed: $url_out&amp;#34;
fi
else
/usr/bin/logger -i -p daemon.err &amp;#34;duckdns update failed, returned: $return_val&amp;#34;
fi&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Note that this doesn&amp;rsquo;t account for multiple external WANs, something I want to do in the future. It also requires IPv4. There are ip= and ipv6= parameters if you want IPv6 or a different address for different WANs.&lt;/p&gt;
&lt;p&gt;Then all I had to do was chmod 700 and stick it in a cron file:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;crontab -e
~/15 * * * * ~/duckdns/duckdns &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now I can get my IP anywhere. (I&amp;rsquo;m using ~/15 instead of */15 so I don&amp;rsquo;t get 503s when everyone else decides it&amp;rsquo;s time to update.)&lt;/p&gt;</description></item><item><title>Logging into Ubuntu 22.04 Remote Desktop</title><link>https://andrewmemory.acornwall.net/blog/2023-01-16-logging-into-ubuntu-22-04-remote-desktop/</link><pubDate>Mon, 16 Jan 2023 16:54:36 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2023-01-16-logging-into-ubuntu-22-04-remote-desktop/</guid><description>&lt;p&gt;I&amp;rsquo;d set up and configured remote desktop on my Ubuntu desktop machine, but when I tried logging in from Windows I always saw an error (&amp;ldquo;An authentication error has occurred. The token supplied to the function is invalid&amp;rdquo;):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;mstsc&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Error dialog reading: An authentication error has occurred. The token supplied to the function is invalid."
width="438"
height="111"
src="https://andrewmemory.acornwall.net/blog/2023-01-16-logging-into-ubuntu-22-04-remote-desktop/images/token-invalid.png"
srcset="https://andrewmemory.acornwall.net/blog/2023-01-16-logging-into-ubuntu-22-04-remote-desktop/images/token-invalid.png 800w, https://andrewmemory.acornwall.net/blog/2023-01-16-logging-into-ubuntu-22-04-remote-desktop/images/token-invalid.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2023-01-16-logging-into-ubuntu-22-04-remote-desktop/images/token-invalid.png"&gt;&lt;/figure&gt;
&lt;p&gt;Luckily I found this &lt;a href="https://bugs.launchpad.net/ubuntu/&amp;#43;bug/1970924" target="_blank" rel="noreferrer"&gt;Ubuntu bug&lt;/a&gt; with the workaround: use .\username instead of username because Microsoft is defaulting to something stupid.&lt;/p&gt;
&lt;p&gt;Update: That was interesting. It works until the screen locks. Luckily there&amp;rsquo;s an &lt;a href="https://askubuntu.com/questions/1411504/connect-when-remote-desktop-is-on-login-screen-or-screen-locked-without-autolog" target="_blank" rel="noreferrer"&gt;extension&lt;/a&gt; for Gnome that lets you set up remote desktop to allow you to log in when the screen&amp;rsquo;s locked.&lt;/p&gt;</description></item><item><title>Ubuntu 22.04 logs not rotating</title><link>https://andrewmemory.acornwall.net/blog/2022-11-26-ubuntu-22-04-logs-not-rotating/</link><pubDate>Sat, 26 Nov 2022 15:56:40 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2022-11-26-ubuntu-22-04-logs-not-rotating/</guid><description>&lt;p&gt;I happened to look at my /var/log and discovered that it was completely full! How&amp;rsquo;d that happen?&lt;/p&gt;
&lt;p&gt;It looks as if 22.04 broke log rotation. So the log files just keep growing until they max out the device and then stop. Yay Ubuntu!&lt;/p&gt;
&lt;p&gt;I did a couple of things - first was to expand the size of my log device (I&amp;rsquo;m using log2ram)&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# sudo emacs /etc/log2ram.conf
SIZE=120M&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, change how much the journal keeps:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# sudo emacs /etc/systemd/jourlnald.conf
SystemMaxUse=40M&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Clear out the journal:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# sudo journalctl --vacuum-size 40M&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then I went looking for the problem. Luckily, two other people had run into this and &lt;a href="https://askubuntu.com/questions/1429612/ubuntu-22-04-logrotate-not-working-after-upgrade-to-ubuntu-22-04/" target="_blank" rel="noreferrer"&gt;documented it on StackOverflow&lt;/a&gt;. I tried the same test:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# sudo logrotate /etc/logrotate.d/rsyslog --debug&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and saw the same results:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;error: skipping &amp;#34;/var/log/syslog&amp;#34; because parent directory has insecure permissions (It&amp;#39;s world writable or writable by group which is not &amp;#34;root&amp;#34;)
Set &amp;#34;su&amp;#34; directive in config file to tell logrotate which user/group should be used for rotation.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;And then made the same change to almost everything in /etc/logrotate.d (alternatives apport bootlog btmp dpkg log2ram ppp sane-utils ufw wtmp) and to each I added to the config file (before the monthly, weekly, daily - right at the top):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# sudo emacs (one of the following: alternatives apport bootlog btmp dpkg log2ram ppp sane-utils ufw wtmp)
su syslog syslog&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then make sure they all work:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo logrotate /etc/logrotate.d/alternatives --debug
sudo logrotate /etc/logrotate.d/apport --debug
sudo logrotate /etc/logrotate.d/bootlog --debug
sudo logrotate /etc/logrotate.d/btmp --debug
sudo logrotate /etc/logrotate.d/dpkg --debug
sudo logrotate /etc/logrotate.d/log2ram --debug
sudo logrotate /etc/logrotate.d/ppp --debug
sudo logrotate /etc/logrotate.d/sane-utils --debug
sudo logrotate /etc/logrotate.d/ufw --debug
sudo logrotate /etc/logrotate.d/wtmp --debug&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, clear out all the emacs droppings because otherwise logrotate will still try to run them:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo rm /etc/logrotate.d/*~
sudo rm /etc/logrotate.d/\#*
sudo rm /etc/systemd/journald.conf~
sudo rm /etc/log2ram.conf~&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;And&amp;hellip; that&amp;rsquo;s it, I hope!&lt;/p&gt;</description></item><item><title>ssh unable to negotiate</title><link>https://andrewmemory.acornwall.net/blog/2022-08-28-ssh-unable-to-negotiate/</link><pubDate>Sun, 28 Aug 2022 22:24:49 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2022-08-28-ssh-unable-to-negotiate/</guid><description>&lt;p&gt;My upgrade to Ubuntu LTS 22.04.1 from 20.04 was pretty smooth, but I ran into one issue. When I tried to ssh to a few other boxes around the network, I saw:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Unable to negotiate with 192.168.1.x port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Looks like I need to upgrade my ssh server on some machines. But I can&amp;rsquo;t do that if I can&amp;rsquo;t ssh to them! So I added a couple of lines to my /etc/ssh/ssh_config instead:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;HostKeyAlgorithms ssh-rsa,rsa-sha2-512,rsa-sha2-256
PubkeyAcceptedKeyTypes ssh-rsa,rsa-sha2-512,rsa-sha2-256&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;ll need to undo that once I fix the server, but until then I can log into it.&lt;/p&gt;</description></item><item><title>Merging multiple PDFs</title><link>https://andrewmemory.acornwall.net/blog/2022-07-24-merging-multiple-pdfs/</link><pubDate>Sun, 24 Jul 2022 17:25:34 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2022-07-24-merging-multiple-pdfs/</guid><description>&lt;p&gt;I&amp;rsquo;d recently downloaded a bunch of separate PDFs that I wanted to turn into a handy file that I could carry around. After grabbing the PDFs, I merged them with:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ pdfunite *.pdf really-big-output.pdf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;PDFUnite is part of Poppler, so be sure to:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt install poppler-utils&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;hellip; if you don&amp;rsquo;t have it already. That&amp;rsquo;s it!&lt;/p&gt;</description></item><item><title>Building TQSL 2.6.4 for Ubuntu 20.04 (or TQSL 2.6.5 for Ubuntu 22.04)</title><link>https://andrewmemory.acornwall.net/blog/2022-06-26-building-tqsl-2-6-4-for-ubuntu-20-04/</link><pubDate>Sun, 26 Jun 2022 23:28:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2022-06-26-building-tqsl-2-6-4-for-ubuntu-20-04/</guid><description>&lt;p&gt;It&amp;rsquo;s the day after Field Day, and I&amp;rsquo;m too lazy to grab my old laptop that has TQSL and FLDigi on it to enter my logs. So I decided to install FLDigi and TQSL on my desktop machine instead.&lt;/p&gt;
&lt;p&gt;Bad news, though: Ubuntu has an outdated version of TQSL, and the ARRL doesn&amp;rsquo;t provide a package for Ubuntu. Boo. However, building it was pretty painless, with only a few attempts. The result:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A working TQSL"
width="572"
height="445"
src="https://andrewmemory.acornwall.net/blog/2022-06-26-building-tqsl-2-6-4-for-ubuntu-20-04/images/tqsl.png"
srcset="https://andrewmemory.acornwall.net/blog/2022-06-26-building-tqsl-2-6-4-for-ubuntu-20-04/images/tqsl.png 800w, https://andrewmemory.acornwall.net/blog/2022-06-26-building-tqsl-2-6-4-for-ubuntu-20-04/images/tqsl.png 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2022-06-26-building-tqsl-2-6-4-for-ubuntu-20-04/images/tqsl.png"&gt;&lt;/figure&gt;
&lt;p&gt;The machine I started with already had a basic development environment. But if yours doesn&amp;rsquo;t, you&amp;rsquo;ll probably need to grab a few things first:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt install make cmake gcc libappimage-dev&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next you need to download the latest file from &lt;a href="http://www.arrl.org/tqsl-download" target="_blank" rel="noreferrer"&gt;arrl.org/tqsl-download&lt;/a&gt; and stash it somewhere on your filesystem. The day I tried it, the latest was tqsl-2.6.4.tar.gz. So&amp;hellip;&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ tar xzvf tqsl-2.6.4.tar.gz
$ cd tqsl-2.6.4&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I was happy to see a nice linux-make-appimage.sh script ready for consumption. If you look at the INSTALL file (which I didn&amp;rsquo;t) you&amp;rsquo;ll see you need to install a few prerequisites. I didn&amp;rsquo;t bother downloading them, but just used the ones that were already built for Ubuntu:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt-get install libssl-dev liblmdb-dev libdb-dev libexpat1-dev libcurl4-openssl-dev libwxgtk-media3.0-gtk3-dev libzlcore-dev
$ sh ./linux-make-appimage.sh&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;After a few false starts (yes, it clones the repo every time you try to build) I ended up with a pretty TQSL-x86_64.AppImage in my build directory. I wanted to run that from the command line, so I did the following:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt remove trustedqsl # need to make sure the old package isn&amp;#39;t there
$ sudo cp TQSL-x86_64.AppImage /usr/local/bin/TQSL_2.6.4-x86_64.AppImage
$ sudo chmod 555 /usr/local/bin/TQSL_2.6.4-x86_64.AppImage
$ sudo ln -s /usr/local/bin/TQSL_2.6.4-x86_64.AppImage /usr/local/bin/tqsl&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That left me with a tqsl symbolic link pointing to /usr/local/bin/TQSL_2.6.4-x86_64.AppImage in /usr/local/bin (which is on my $PATH). That&amp;rsquo;s it!&lt;/p&gt;
&lt;p&gt;Oh yeah, after all that I ended up having to boot the old laptop anyway. I needed to extract my old TQSL config (exported to tqslconfig.tbk) in order to import it to this version. When importing the preferences I got an error message about an unknown token, but it worked anyway&amp;hellip; and I got the same message when importing into a Windows build that the ARRL created. Go figure.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t need to re-import my certs - they were already there.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Changes for TQSL 2.6.5
&lt;div id="changes-for-tqsl-265" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#changes-for-tqsl-265" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Looks like they broke the AppImage build in TQSL 2.6.5. If I try it on Ubunutu 22.04, I get:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;ERROR: Icon entry missing in desktop file: AppDir/usr/share/applications/tqsl.desktop &lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;So instead of the &lt;code&gt;sh ./linux-make-appimage.sh&lt;/code&gt; above, I did the following:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ cd /wherever you put it/tqsl-2.6.5
$ cmake .
$ make&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;And then created a shell script &lt;code&gt;/usr/local/bin/tqsl&lt;/code&gt; to run tqsl from where I&amp;rsquo;d built it:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#!/bin/bash -
cd /wherever you put it/tqsl-2.6.5/apps
./tqsl&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;You can&amp;rsquo;t just copy the binary because it needs some libraries that it builds as well. I tried &lt;code&gt;make install&lt;/code&gt; but that&amp;rsquo;s broken on Ubuntu 22.04 as well. Don&amp;rsquo;t forget:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo chmod 550 /usr/local/bin/tqsl&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Setting up Ubuntu 20.04 LTS</title><link>https://andrewmemory.acornwall.net/blog/2021-10-30-setting-up-ubuntu-20-04-lts/</link><pubDate>Sat, 30 Oct 2021 02:07:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2021-10-30-setting-up-ubuntu-20-04-lts/</guid><description>&lt;p&gt;I recently had the chance to set up Ubuntu on several different hard drives I iterated through. I&amp;rsquo;ve come up with a procedure that seems to work for me to set up my environment the way I like it.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Get started
sudo apt install emacs meld cifs-utils samba-common nfs-client hardinfo default-jre
### Done
# Configure git
git config --global user.email &amp;#34;andrewmemory@example.com&amp;#34;
git config --global user.name &amp;#34;Doctor Memory&amp;#34;
git config --global core.autocrlf input
git config --global credential.helper cache --timeout=36000
git config --global diff.tool meld
### Done
# Swizzle userids
# as andrewmemory
sudo adduser andrewmemorybackup
# edit /etc/group and replace andrewmemory with andrewmemory,andrewmemorybackup
# change andrewmemory to 3000
# change sambashare to 3001
# as andrewmemorybackup
sudo vipw
cd /home/
sudo chown -R andrewmemory.andrewmemory andrewmemory
# while we&amp;#39;re here, let&amp;#39;s put us in dialout
sudo usermod -a -G dialout andrewmemory
sudo usermod -a -G dialout andrewmemorybackup
### Done
# Set up CIFS credentials
credentials directory in /etc/samba/credentials
700
file in /etc/samba/credentials/server
user=andrewmemory
password=secret
### Done
# Add to /etc/fstab:
tmpfs /tmp tmpfs size=512m 0 0
tmpfs /var/tmp tmpfs size=512m 0 0
//server.example.com/music /music cifs x-systemd.automount,uid=3000,gid=3001,credentials=/etc/samba/credentials/server,sec=ntlmssp 0 2
server.example.com:/shared /shared nfs4 defaults,user,exec 0 2
server.example.com:/shared /nfsshared nfs4 defaults,user,exec 0 2
### Done
# Get most of the packages
sudo apt install \
emacs \
git \
nfs-client \
cifs-utils \
samba-common \
hardinfo \
default-jre \
gnucash \
gcc \
abcde \
audacity \
imagemagick \
bind9-dnsutils \
net-tools \
brasero \
bsdutils \
bzip2 \
cdparanoia \
default-jdk-headless \
dnsutils \
dos2unix \
dosfstools \
e2fsprogs \
easytag \
evince \
exfat-fuse exfat-utils \
ffmpeg \
filezilla \
flac \
toilet \
toilet-fonts \
flatpak \
font-manager \
fontmatrix \
ftp \
g&amp;#43;&amp;#43; \
gawk \
gdb \
genisoimage \
ghostscript \
gnuplot \
growisofs \
icc-profiles-free \
icc-profiles \
keepassx \
lame \
make \
meld \
ntpdate \
ntp \
obs-studio \
openscad \
patch patchutils \
ps2eps psmisc pstoedit psutils \
python3 \
rsync \
sharutils \
sntp \
splat \
tcl tk \
unrar unzip zip \
vice \
vorbis-tools \
wget \
wine-stable \
whois \
xz-utils
### Done
sudo apt remove rhythmbox; sudo apt autoremove
### Done
# TeXlive
sudo mkdir /usr/local/texlive
sudo chown andrewmemory.andrewmemory /usr/local/texlive
cd /shared/archive/apps/TeX/TeX2021/TEXCOL2021/texlive
./install-tl --gui
# default paper size Letter
### Done
# TeXstudio
sudo apt --no-install-recommends install texstudio
### Done
# Gimp
flatpak install https://flathub.org/repo/appstream/org.gimp.GIMP.flatpakref
cp /shared/backup-home/usr.bin.gimp ~
# Where usr.bin.gimp is just a call to
# flatpak run org.gimp.GIMP//stable &amp;#34;$@&amp;#34;
sudo cp ~/usr.bin.gimp /usr/bin/gimp
sudo chmod 755 /usr/bin/gimp
cp /shared/gimp/*.scm ~/.var/app/org.gimp.GIMP/config/GIMP/2.10/scripts
### Done
# KiCAD
sudo add-apt-repository --yes ppa:kicad/kicad-5.1-releases
sudo apt update
sudo apt install --install-recommends kicad
# If you want demo projects
sudo apt install kicad-demos
### Done
# Firefox
# Disable sharing info
# Under Downloads, &amp;#34;Always ask where to save files&amp;#34;
# Under Startup, &amp;#34;Restore previous session&amp;#34;
# Under Data Collection, uncheck all
### Done
# any crontabs? - no
### Done
# ltspice - executable called LTspice.exe - install under wine
# there are links on the desktop, some config under /home/andrewmemory/andrewmemory/.wine/drive_c/Program Files/LTC/
# FontForge
# Go to https://fontforge.org/en-US/downloads/gnulinux-dl/
# See if there&amp;#39;s anything newer than 2020-11-07
# if there is, get it, otherwise copy from /shared/backup-home/home/andrewmemory/andrewmemory
cp /shared/backup-home/home/andrewmemory/andrewmemory/FontForge-2020-11-07-21ad4a1-x86_64.AppImage ~
### Done
# the AppImages: under /home/andrewmemory/andrewmemory (or get the latest)
FreeCAD_0.18-16146-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage
# Android Studio
sudo apt-get install libc6:i386 libncurses5:i386 libstdc&amp;#43;&amp;#43;6:i386 lib32z1 libbz2-1.0:i386 openjdk-11-jdk
sudo add-apt-repository ppa:maarten-fonville/android-studio
sudo apt update
sudo apt install android-studio
# Install KVM
sudo apt install cpu-checker
kvm-ok
# Assuming it&amp;#39;s OK:
sudo apt-get install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
sudo adduser andrewmemory libvirt
sudo adduser andrewmemory kvm
sudo adduser andrewmemorybackup libvirt
sudo adduser andrewmemorybackup kvm
sudo chmod u&amp;#43;x /var/run/libvirt/libvirt-sock
sudo chmod g&amp;#43;x /var/run/libvirt/libvirt-sock
# Reboot
sudo chmod 755 /opt
cd /opt/android-studio/bin
./studio.sh
# Update everything...
# Open project /shared/development/AndroidStudioProjects/
# Tools -&amp;gt; Create Desktop Entry
# File -&amp;gt; Settings
# Install Android SDK Command-line Tools, Google Play services
# Accept licenses
yes | ~/Android/Sdk/cmdline-tools/latest/bin/sdkmanager --licenses
# Build -&amp;gt; Rebuild Project
# ... go away for 30 minutes (!)
# Click &amp;#34;Select a JDK&amp;#34; in the event log and pick /opt/android-studio/jre
# Tools -&amp;gt; AVD Manager
# Create Pixel 4a, Download Android 30
# Settings -&amp;gt; Memory Settings, choose IDE Max Heap 2048M
#
# Just so I can build projects with the shared keys I used before:
cd ~
cp /shared/backup-home/debug.keystore ~/.android/
### Done
# Arduino
# Download from https://www.arduino.cc/en/software
# Extract the .tar.gz (currently in Downloads)
tar xf arduino-1.8.16-linux64.tar.xz
cd arduino-1.8.16/
sudo ./install.sh
# Need to install libraries as well...
# Set up environment
# /home/andrewmemory (with VISUAL, EDITOR, etc...)
# at the end of ~/.bashrc put:
export VISUAL=/usr/bin/emacs
export EDITOR=$VISUAL
export PATH=/usr/local/texlive/2021/bin/x86_64-linux:$PATH
# Log out and back in
### Done
# Set up log2ram (I probably should have done this earlier)
echo &amp;#34;deb http://packages.azlux.fr/debian/ buster main&amp;#34; | sudo tee /etc/apt/sources.list.d/azlux.list
wget -qO - https://azlux.fr/repo.gpg.key | sudo apt-key add -
sudo apt update
sudo apt install log2ram
# To control: sudo systemctl stop log2ram
# To uninstall: sudo apt purge --remove log2ram
### Done
# Don&amp;#39;t forget the udev rules for things I did...
# Fonts
sudo apt install fonts-noto fonts-noto-extra fonts-noto-mono
# Manually install:
# /shared/fonts/*.?tf
### Done
# Also manually install brscan / brother stuff
# go to https://www.brother-usa.com/support/mfcl2750dw
# Download linux-brprinter-installer-2.2.3-1.gz
gunzip -d linux-brprinter-installer-2.2.3-1.gz
sudo bash ./linux-brprinter-installer-2.2.3-1 MFC-L2750DW
# Specify DeviceURI? I said &amp;#34;No&amp;#34;, although it says to say &amp;#34;Yes&amp;#34; for network.
### Done
# Thunderbird
thunderbird -ProfileManager
# create a &amp;#34;Default User&amp;#34; profile and an &amp;#34;andrewmemory network&amp;#34; profile
# exit Thunderbird
# edit ~/.thunderbird/profiles.ini and set the andrewmemory network profile to:
Name=andrewmemory network
IsRelative=0
Path=/shared/thunderbird/andrewmemory
# I also set Default=/shared/thunderbird/andrewmemory
thunderbird -ProfileManager
# Set to open andrewmemory network by default
### Done
# GnuCash
# Start GnuCash
# Click Cancel
# Open /shared/accounts/accounts.gnucash
# Expand Accounts and click on Checking Account
# View -&amp;gt; Transaction Journal
### Done
# Set up my static IP
ifconfig
# eno1 says ether 00:01:02:03:04:05
ssh root@firewall
# delete the lease from /var/db/dhcpd.leases
ps -aux | grep dhcp
# Kill /usr/sbin/dhcpd
rw
emacs /etc/dhcpd.conf
host newhost {
hardware ethernet 00:01:02:03:04:05;
fixed-address 192.168.1.2;
option host-name &amp;#34;newhost&amp;#34;;
}
# save
cd /var.named/named/etc/namedb
emacs db.example
newhost.example.com. IN A 192.168.1.2
# update serial number
# save
emacs db.example.rev
2.1.168.192.in-addr.arpa. IN PTR newhost.example.com.
# update serial number
# save
reboot ### On firewall, not on the desktop!
# wait a bit until you can ssh into firewall again
# reboot the desktop
ifconfig
# verify that the IP address is right
sudo apt install openssh-server
### Done
# Cura
# Install latest Cura .appImage in ~ from
# https://ultimaker.com/software/ultimaker-cura
# Create (non-networked) Creality Ender 3 with default options
# Open Marketplace, go to Plugins, install OctoPrint Connection
# Quit and restart Cura ~/Ultimaker*
# Load a model and slice
# Settings -&amp;gt; Extruder 1 -&amp;gt; Materials -&amp;gt; Manage Materials
# Create 3D Solutech PLA as a copy of Generic PLA, set cost, weight
# I just used 1000g because... that&amp;#39;s what it started out as
# Set Print Settings build plate temp to 60 C
# Create Hatchbox PLA as a copy of 3D Solutech PLA
# Settings -&amp;gt; Printers -&amp;gt; Creality 3 -&amp;gt; Manage Printers
# Turn on octopi.example.com
# Connect Ocotoprint
# Add octopi - octopi.example.com - 80 - /
# Request API key
# Log into OctoPrint
# Select &amp;#34;Start print job after uploading&amp;#34; and &amp;#34;Connect to printer before sending&amp;#34;. Deselect the rest.
# Uncheck &amp;#34;Automatically discover local OctoPrint instances&amp;#34;
# Settings -&amp;gt; Setting Visibility -&amp;gt; Check All
# For each profile: Profiles -&amp;gt; Customize
# Z Seam Alignment = Randomize
# Preferences -&amp;gt; General -&amp;gt; Currency ($)
# Opening and saving files -&amp;gt; Unselect &amp;#34;Add machine prefix to job name&amp;#34;
# Uncheck &amp;#34;Send anonymous print information&amp;#34;
### Done
# OpenSCAD
# There&amp;#39;s a setting under &amp;#34;Advanced&amp;#34; that lets you undock. Enable that.
### Done
- &amp;#34;rss-feed&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Setting up NFS on Ubuntu 20.04</title><link>https://andrewmemory.acornwall.net/blog/2021-05-30-setting-up-nfs-on-ubuntu-20-04/</link><pubDate>Sun, 30 May 2021 14:11:18 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2021-05-30-setting-up-nfs-on-ubuntu-20-04/</guid><description>&lt;p&gt;I have been experiencing random weirdness with CIFS on Ubuntu 20.04. Every now and then the current working directory will disappear. I can usually get things back to normal by &amp;ldquo;cd ..; cd &lt;em&gt;myDir&lt;/em&gt;&amp;rdquo; but that&amp;rsquo;s a pain - more of a pain when a build has failed because the current directory evaporated on the Gradle script.&lt;/p&gt;
&lt;p&gt;So I decided to try NFS. Setting up NFS is not too hard. I found a &lt;a href="https://linuxconfig.org/how-to-configure-nfs-on-linux" target="_blank" rel="noreferrer"&gt;very useful page on LinuxConfig.org&lt;/a&gt; that got me 90% of the way there.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Server setup&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In short, on the server:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt install nfs-kernel-server
$ sudo systemctl enable --now nfs-server&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then edit /etc/exports on the server to include the line:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/myshareddisk 192.168.1.0/8(rw,sync,no_subtree_check)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;It looks as if there&amp;rsquo;s no easy way for NFS to handle DHCP unless the file server can look up the IP. Boo. Going onward and knowing my network is now less protected:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo exportfs -arv&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;At this point, the LinuxConfig.org instructions start pointing you to server configuration. However, there&amp;rsquo;s a vital step omitted - pretty much every sane app will fail with &amp;ldquo;no locks available.&amp;rdquo; Why? &lt;a href="https://askubuntu.com/questions/837962/nfs-error-no-locks-available-after-update-to-16-10" target="_blank" rel="noreferrer"&gt;StackExchange&lt;/a&gt; to the rescue. Enabling NFS doesn&amp;rsquo;t enable rpc-statd.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo systemctl enable rpc-statd
$ sudo systemctl start rpc-statd &lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;As the StackExchage article says, &amp;ldquo;Thanks, systemd!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Client setup&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Next you can set up the client:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo mount -t nfs4 my-server-fqdn:/myshareddisk /localmnt&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Hey, it mounted, and it looks like a file system. Now anyone on my network can mount my NFS server! Exposing it to ransomware and all sorts of excellent things like that. Err&amp;hellip; good?&lt;/p&gt;
&lt;p&gt;Last step is to make it automount on the client by editing /etc/fstab:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;my-server-fqdn:/myshareddisk /localmnt nfs4 defaults,user,exec 0 2&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m really unsure about this, and may need to undo it or at least find a way to stop it advertising to everyone. But it&amp;rsquo;s that way for now.&lt;/p&gt;</description></item><item><title>Mounting a partition from a raw disk image</title><link>https://andrewmemory.acornwall.net/blog/2020-11-28-mounting-a-partition-from-a-raw-disk-image/</link><pubDate>Sat, 28 Nov 2020 15:20:55 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2020-11-28-mounting-a-partition-from-a-raw-disk-image/</guid><description>&lt;p&gt;In the past I&amp;rsquo;d backed up an SD card with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dd if=/dev/sdc of=mydisk.img&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now I wanted to get something off of it. However, the SD card had two partitions on it. I wondered if there was a more elegant way to get data out than just writing it to another SD card. Turns out, there is! There&amp;rsquo;s a great post at &lt;a href="https://dustymabe.com/2012/12/15/mounting-a-partition-within-a-disk-image/" target="_blank" rel="noreferrer"&gt;dustymabe.com/2012/12/15/mounting-a-partition-within-a-disk-image&lt;/a&gt; that explains how to do it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo losetup -v -f mydisk.img sudo losetup -a&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This gives me the /dev/loop* device that my image is mounted as. In my case, it was /dev/loop18. Next, I could use partx to create loop devices for the partitions:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo partx -v --add /dev/loop18&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This created /dev/loop18p1 through /dev/loop18p(however many partitions I had). Once those partitions have been created, you can mount them like any other partition on a regular block device. Once you&amp;rsquo;re done,&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo partx -v --delete /dev/loop18&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;will get rid of both the device and its partitions.&lt;/p&gt;</description></item><item><title>Annealing PLA in powdered salt using sous vide</title><link>https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/</link><pubDate>Sat, 31 Oct 2020 03:53:26 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/</guid><description>&lt;p&gt;Stefan of &lt;a href="https://www.cnckitchen.com/" target="_blank" rel="noreferrer"&gt;CNC Kitchen&lt;/a&gt; recently posted about annealing (and later re-melting) PLA prints to improve their strength and temperature resistance. I decided to do some experiments of my own.&lt;/p&gt;
&lt;p&gt;My method was to print out some PLA objects, pack them in a salt powder that gets vacuum-sealed, and then toss that in the sous vide for 18 hours. The sous vide doesn&amp;rsquo;t get hot enough to re-melt PLA, so it doesn&amp;rsquo;t have exactly the same characteristics, but it does gain some benefit. The advantage to the sous vide method is that it&amp;rsquo;s more available than a constant-temperature oven.&lt;/p&gt;
&lt;p&gt;I did informal tests on the annealed prints for a few characteristics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Smoothing - did the texture of the print change?&lt;/li&gt;
&lt;li&gt;Strength between layers - was the print any stronger between layers?&lt;/li&gt;
&lt;li&gt;Waterproofing - did the print eventually get waterlogged when placed in water?&lt;/li&gt;
&lt;li&gt;Temperature resistance - did the print get as flexible when subjected to increased temperatures as a non-annealed print?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Procedure
&lt;div id="procedure" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#procedure" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I used four objects: a hollow spheroid, a 30x5x5 mm bar, a calibration cube, and a box with tabs that were oriented perpendicular to the layers. I ground up plain (uniodized) salt in a spice mill, and put that into a FoodSaver bag that was double-sealed at the bottom. Relative humidity when I sealed the bag was around 33%.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A bag of salt powder"
width="400"
height="192"
src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/salt.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/salt.jpg 800w, https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/salt.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/salt.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;I nestled my prints in the salt, then vacuum-sealed the bag and double-sealed the top.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A sealed bag containing prints surrounded by salt powder"
width="400"
height="250"
src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/sealed.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/sealed.jpg 800w, https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/sealed.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/sealed.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Sealed in the bag. The salt prevented sharp edges from poking holes.&lt;/p&gt;
&lt;p&gt;Next, I tossed the bag in a pot of water along with an Anova Nano sous vide stick. I set the temperature for 80 C (176 F) and left it that way for 18 hours.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Cooking the bag at 80 C"
width="300"
height="400"
src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/cooking.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/cooking.jpg 800w, https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/cooking.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/cooking.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Cooking at 80 C&lt;/p&gt;
&lt;p&gt;After that, I turned the sous vide stick off and let the pot come to room temperature.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Observations
&lt;div id="observations" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#observations" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;When I removed the salt from the bag, it had formed a solid mass that could be broken apart by hand. I carefully extracted the printed objects. The box lid and letters on the calibration cube letters were packed with salt, but that could be washed out easily.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Prints partially extracted from salt"
width="400"
height="221"
src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/annealed-prints.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/annealed-prints.jpg 800w, https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/annealed-prints.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/annealed-prints.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;I measured most of the objects, and found that they had indeed changed size - all were a few percent smaller than before annealing. So I knew annealing did &lt;em&gt;something&lt;/em&gt;:&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Print&lt;/strong&gt;&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;&lt;strong&gt;Original dimension (mm)&lt;/strong&gt;&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;&lt;strong&gt;After annealing (mm)&lt;/strong&gt;&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;&lt;strong&gt;Change (as % of original)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Calibration cube X&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;20.13&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;19.98&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;99.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Calibration cube Y&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;20.08&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;19.89&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;99.1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Calibration cube Z&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;20.15&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;19.98&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;99.2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Spheroid diameter&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;20.08&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;19.78&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;98.5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Spheroid height (Z)&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;24.82&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;24.72&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;99.6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bar length (X)&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;30.23&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;30.06&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;99.4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bar width (Y)&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;5.14&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;5.06&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;98.4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Bar height (Z)&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;5.00&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;4.95&lt;/td&gt;&lt;td class="has-text-align-center" data-align="center"&gt;99.0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 class="relative group"&gt;Results
&lt;div id="results" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#results" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Broken tabs on the box print"
width="400"
height="215"
src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/broken-tabs.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/broken-tabs.jpg 800w, https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/broken-tabs.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/broken-tabs.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Tabs broke off just as easily after annealing&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Smoothing: unlike Stefan&amp;rsquo;s experiments with PLA re-melting, the annealed objects did not change texture. The plastic still showed the same layer lines and other 3D printer artifacts that non-annealed prints did. I attribute that to the fact that the plastic never flowed - the annealing temperature was always below the melting point.&lt;/li&gt;
&lt;li&gt;Strength: when I assembled the box, the tabs broke off exactly as they had when I printed non-annealed PLA using the &amp;ldquo;wrong&amp;rdquo; orientation. I couldn&amp;rsquo;t measure it, but I don&amp;rsquo;t think annealed PLA was any stronger between layers.&lt;/li&gt;
&lt;li&gt;Waterproofing: after immersing the spheroid in water for a week, it seemed to sink a little lower, but then stop. I don&amp;rsquo;t think I&amp;rsquo;d want to claim that annealing changed the waterproofing of the prints.&lt;/li&gt;
&lt;li&gt;Temperature resistance: this did appear to change. I put both the annealed and non-annealed bar prints on the printer bed at 73 C (163 F). After a few minutes, the non-annealed bar was flexible enough that it could be bent between my fingers. In contrast, the annealed print remained solid, and in fact snapped when I applied more pressure.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="A non-annealed bar (bent) and an annealed bar (broken)."
width="400"
height="356"
src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/temp-resist.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/temp-resist.jpg 800w, https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/temp-resist.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2020-10-31-annealing-pla-in-powdered-salt-using-sous-vide/images/temp-resist.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;The non-annealed part was flexible after heating to 73 C. The annealed part was not.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Conclusion
&lt;div id="conclusion" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#conclusion" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Annealing sous vide is useful for imparting temperature resistance to PLA, and may be a valuable technique for PLA objects that need to live in a hot environment (such as a car in the summertime). Sous vide annealing is easier and more reliable than trying to anneal in a kitchen oven. Annealing alone does not change texture, strength between layers or waterproofing characteristics.&lt;/p&gt;</description></item><item><title>Persistent serial ports on Ubuntu</title><link>https://andrewmemory.acornwall.net/blog/2020-06-30-persistent-serial-ports-on-ubuntu/</link><pubDate>Tue, 30 Jun 2020 01:12:11 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2020-06-30-persistent-serial-ports-on-ubuntu/</guid><description>&lt;p&gt;Last time I rebooted my file server (which has a couple of serial devices attached), it picked the wrong ones for /dev/ttyUSB0 and /dev/ttyUSB1. That meant the speeds (which I&amp;rsquo;d configured in minicomrc files) were wrong.&lt;/p&gt;
&lt;p&gt;I needed to make the serial ports persistent. Again with the udev rules!&lt;/p&gt;
&lt;p&gt;Luckily, there was a handy page at: &lt;a href="https://indilib.org/support/tutorials/157-persistent-serial-port-mapping.html" target="_blank" rel="noreferrer"&gt;indilib.org/support/tutorials/157-persistent-serial-port-mapping.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;with what I needed to know. I ended up adding two rules in /lib/udev/rules.d/99-serial-aliases.rules: &lt;code&gt;# portal SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;0403&amp;quot;, ATTRS{idProduct}==&amp;quot;6001&amp;quot;, ATTRS{serial}==&amp;quot;AM00NPHK&amp;quot;, MODE=&amp;quot;0666&amp;quot;, SYMLINK+=&amp;quot;ttyPortal&amp;quot; # wally SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;10c4&amp;quot;, ATTRS{idProduct}==&amp;quot;ea60&amp;quot;, ATTRS{serial}==&amp;quot;0130D901&amp;quot;, MODE=&amp;quot;0666&amp;quot;, SYMLINK+=&amp;quot;ttyWally&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I got these values by running lsusb -v (which in truth gives you everything you need to know) and: &lt;code&gt;udevadm info -a -n /dev/ttyUSB0 | grep serial | head -1&lt;/code&gt; and &lt;code&gt;udevadm info -a -n /dev/ttyUSB1 | grep serial | head -1&lt;/code&gt; on my two serial ports. (I could also grep idProduct and idVendor, but lsusb gave me the right ones already.)&lt;/p&gt;
&lt;p&gt;Then delete (sigh) /lib/udev/rules.d/99-serial-aliases.rules~ that Emacs left over. Cause it gets read if you don&amp;rsquo;t. Sigh. I always forget.&lt;/p&gt;
&lt;p&gt;After that a quick: &lt;code&gt;sudo udevadm control --reload-rules sudo udevadm trigger&lt;/code&gt; and I had my /dev/ttyPortal and /dev/ttyWally. Now to fix up those minicom configs&amp;hellip;&lt;/p&gt;</description></item><item><title>Finding the characteristic impedance of an antenna cable</title><link>https://andrewmemory.acornwall.net/blog/2020-05-24-finding-the-characteristic-impedance-of-an-antenna-cable/</link><pubDate>Sun, 24 May 2020 16:29:11 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2020-05-24-finding-the-characteristic-impedance-of-an-antenna-cable/</guid><description>&lt;p&gt;I recently stumbled on a &lt;a href="https://www.youtube.com/watch?v=afDSE_ejTNk" target="_blank" rel="noreferrer"&gt;cool video&lt;/a&gt; that showed how to compute the impedance of an antenna cable. Unfortunately it&amp;rsquo;s almost five minutes long, so I thought I&amp;rsquo;d summarize:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Measure the capacitance of the cable when it&amp;rsquo;s open (C) in farads (F).&lt;/li&gt;
&lt;li&gt;Short one end.&lt;/li&gt;
&lt;li&gt;Measure the inductance of the cable from the non-shorted end (L) in henrys (H).&lt;/li&gt;
&lt;li&gt;Impedance (Z) = √(L/C) in ohms (Ω).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It works for both coaxial cables and ladder line. Neat trick!&lt;/p&gt;</description></item><item><title>Fixing a busy CP210x serial device on Ubuntu</title><link>https://andrewmemory.acornwall.net/blog/2020-04-05-fixing-a-busy-cp210x-serial-device-on-ubuntu/</link><pubDate>Sun, 05 Apr 2020 21:04:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2020-04-05-fixing-a-busy-cp210x-serial-device-on-ubuntu/</guid><description>&lt;p&gt;I had the opportunity to reorganize my local machines. As part of that, I wanted to plug my firewall&amp;rsquo;s serial port into USB serial and pop that into my server. I have a &lt;a href="https://www.pcengines.ch/usbcom1a.htm" target="_blank" rel="noreferrer"&gt;CP2104 serial device&lt;/a&gt; that I bought with my &lt;a href="https://www.pcengines.ch/apu2.htm" target="_blank" rel="noreferrer"&gt;PC Engines apu2&lt;/a&gt; which I use for a firewall.&lt;/p&gt;
&lt;p&gt;The USB serial device worked fine when plugged into my Windows 8 laptop, but I want my server to be able to connect to my firewall even when the network is down. Because the apu2 is headless, it&amp;rsquo;s nice to have something that&amp;rsquo;s plugged into a monitor when I need to fix things.&lt;/p&gt;
&lt;p&gt;I plugged the USB serial port in, and tried to connect to my firewall with minicom. I got this instead:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ minicom
minicom: cannot open /dev/ttyUSB0: Device or resource busy&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;So, time to look at who has /dev/ttyUSB0 open:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo lsof | grep ttyUSB0
gpsd 416 root 3u CHR 188,0 0t0 176 /dev/ttyUSB0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Ok, why is gpsd holding /dev/ttyUSB0 open? It&amp;rsquo;s true I have a GPS attached to my server, but that runs as /dev/ttyACM0 and has nothing to do with /dev/ttyUSB0. Hmm&amp;hellip; time to search and find this in the gpsd FAQ: &lt;a href="https://gpsd.gitlab.io/gpsd/faq.html#conflict" target="_blank" rel="noreferrer"&gt;Why does GPSD open non-GPS USB devices?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That made me suspicious. See, gpsd is trying to be too friendly - and to do that, it opens a whole bunch of possibly GPS devices even if they&amp;rsquo;re not GPS devices! Could that be my problem?&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 008 Device 003: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 040: ID 1546:01a7 U-Blox AG
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Hmm&amp;hellip; let&amp;rsquo;s take a peek in /lib/udev/rules.d/60-gpsd.rules:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;... blah blah blah...
# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) [linux module: cp210x]
ATTRS{idVendor}==&amp;#34;10c4&amp;#34;, ATTRS{idProduct}==&amp;#34;ea60&amp;#34;, SYMLINK&amp;#43;=&amp;#34;gps%n&amp;#34;, TAG&amp;#43;=&amp;#34;systemd&amp;#34;, ENV{SYSTEMD_WANTS}=&amp;#34;gpsdctl@%k.service&amp;#34;
... more blah...&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;So in an effort to detect the Holux m241 and Wintec grays2 wbt-201, it&amp;rsquo;s matching the vendor and product ID of my CP2104 serial device as well! Luckily, I don&amp;rsquo;t have any of those GPS devices, so a quick snip:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) [linux module: cp210x]
# commented out because it interferes with Andrew&amp;#39;s PC Engines 2104 USB serial cable
#ATTRS{idVendor}==&amp;#34;10c4&amp;#34;, ATTRS{idProduct}==&amp;#34;ea60&amp;#34;, SYMLINK&amp;#43;=&amp;#34;gps%n&amp;#34;, TAG&amp;#43;=&amp;#34;systemd&amp;#34;, ENV{SYSTEMD_WANTS}=&amp;#34;gpsdctl@%k.service&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;was all it took. Now my USB serial device shows up as a serial device, and is not held open by a GPS daemon.&lt;/p&gt;
&lt;p&gt;I have to disagree with the GPSD FAQ&amp;rsquo;s statement, &amp;ldquo;It&amp;rsquo;s not a problem we can solve with clever programming, the devices simply don&amp;rsquo;t yield enough information about themselves to avoid conflicts.&amp;rdquo; Err, no&amp;hellip; clever programming would have the user run through an install procedure which involved plugging the device in, and detecting the device. Then they could update the udev rules so that only the device that a user owned was stolen by gpsd, and not all serial devices on the planet that happened to match a vendor/product ID that they knew about.&lt;/p&gt;</description></item><item><title>Programing with a PICkit 2 on Linux</title><link>https://andrewmemory.acornwall.net/blog/2020-01-08-programing-with-a-pickit-2-on-linux/</link><pubDate>Wed, 08 Jan 2020 23:17:28 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2020-01-08-programing-with-a-pickit-2-on-linux/</guid><description>&lt;p&gt;I recently bought a PICkit 2 clone (the &lt;a href="https://www.piccircuit.com/shop/pic-programmer/56-ica03-usb-pic-programmer-set.html" target="_blank" rel="noreferrer"&gt;ICA03&lt;/a&gt;) from PICCircuit.com. Programming it has been something of a challenge, mostly because Microchip no longer really supports Linux programming of PIC chips.&lt;/p&gt;
&lt;p&gt;First, I needed to get pk2cmd. There are lots of pointers to Microchip&amp;rsquo;s website, but all of them go to 404s. What I ended up using is a github repo: &lt;a href="https://github.com/psmay/pk2cmd" target="_blank" rel="noreferrer"&gt;https://github.com/psmay/pk2cmd&lt;/a&gt;. After reading the threatening license agreement, I cloned the repo and built it with make then sudo make install.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;git clone https://github.com/psmay/pk2cmd
cd pk2cmd/pk2cmd
make linux
sudo make install&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Even after installing PK2DeviceFile.dat in /usr/share and including /usr/share/pk2 on the path (ugh) per the instructions, I still wasn&amp;rsquo;t able to use it from anywhere except the directory I built it from. At some point I&amp;rsquo;ll need to look into that.&lt;/p&gt;
&lt;p&gt;I plugged the PIC into the ZIF socket with the marking near the top, and made sure the selection switch was on 28-40.&lt;/p&gt;
&lt;p&gt;Next, I took my .hex file and stuffed it in ~/pk2cmd/pk2cmd/. Then:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;~/pk2cmd/pk2cmd$ sudo pk2cmd -P
Auto-Detect: Found part PIC16F886.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Yay! Let&amp;rsquo;s try writing the file:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;~/pk2cmd/pk2cmd$ sudo ./pk2cmd -PPIC16F886 \
-f my_hex_file.hex -MPC -Y&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(I didn&amp;rsquo;t include IE on the -M switch because I think my hex file has ID and EEPROM memory in it. -Y does the verification.)&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;PICkit 2 Program Report
8-1-2020, 23:12:12
Device Type: PIC16F886
Program Succeeded.
PICkit 2 Verify Report
8-1-2020, 23:12:12
Device Type: PIC16F886
Verify Succeeded.
Operation Succeeded&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Yay!&lt;/p&gt;</description></item><item><title>Mapping a USB volume knob into a keyboard on Linux for SDR</title><link>https://andrewmemory.acornwall.net/blog/2019-12-16-mapping-a-usb-volume-knob-into-a-keyboard-on-linux-for-sdr/</link><pubDate>Mon, 16 Dec 2019 00:21:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2019-12-16-mapping-a-usb-volume-knob-into-a-keyboard-on-linux-for-sdr/</guid><description>&lt;p&gt;I recently discovered the existence of USB volume knobs. A Reddit user posted an &lt;a href="https://www.reddit.com/r/amateurradio/comments/e8v30z/en_subs_vfo_knob_for_sdrs_from_a_volume_control/" target="_blank" rel="noreferrer"&gt;article about reflashing the firmware&lt;/a&gt; on one to convert it to a keyboard.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="IMG_20191216_010138"
width="400"
height="362"
src="https://andrewmemory.acornwall.net/blog/2019-12-16-mapping-a-usb-volume-knob-into-a-keyboard-on-linux-for-sdr/images/img_20191216_010138.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2019-12-16-mapping-a-usb-volume-knob-into-a-keyboard-on-linux-for-sdr/images/img_20191216_010138.jpg 800w, https://andrewmemory.acornwall.net/blog/2019-12-16-mapping-a-usb-volume-knob-into-a-keyboard-on-linux-for-sdr/images/img_20191216_010138.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2019-12-16-mapping-a-usb-volume-knob-into-a-keyboard-on-linux-for-sdr/images/img_20191216_010138.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Inspired, I picked one up for $18 on eBay (&amp;quot;&lt;a href="https://www.ebay.com/sch/i.html?_nkw=USB&amp;#43;Volume&amp;#43;Controller&amp;#43;Knob&amp;#43;Adjuster&amp;#43;Switcher&amp;#43;for&amp;#43;Tablet&amp;#43;PC&amp;#43;Speaker&amp;#43;Audio" target="_blank" rel="noreferrer"&gt;USB Volume Controller Knob Adjuster Switcher for Tablet PC Speaker Audio&lt;/a&gt;&amp;quot;) and thought that I might be able to do something similar.&lt;/p&gt;
&lt;p&gt;It turns out, under Linux, this is pretty easy.&lt;/p&gt;
&lt;p&gt;First, I plugged in the volume knob and saw that Linux detected it correctly and used it to adjust the volume. That was a promising start. I could see it show the &amp;ldquo;HDMI / DisplayPort&amp;rdquo; volume - and it went up when I turned the knob to the right, down when I turned the knob to the left, and muted when I pressed the knob.&lt;/p&gt;
&lt;p&gt;Next, I wanted to see what events were being generated. I found some very useful instructions at &lt;a href="https://yulistic.gitlab.io/2017/12/linux-keymapping-with-udev-hwdb/" target="_blank" rel="noreferrer"&gt;https://yulistic.gitlab.io/2017/12/linux-keymapping-with-udev-hwdb/&lt;/a&gt; and did them:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ cat /proc/bus/input/devices
...
I: Bus=0003 Vendor=0483 Product=572d Version=0111
N: Name=&amp;#34;STMicroelectronics USB Volume Control&amp;#34;
P: Phys=usb-0000:00:1d.0-1.7.2.4.3.1/input0
S: Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.7/2-1.7.2/2-1.7.2.4/2-1.7.2.4.3/2-1.7.2.4.3.1/2-1.7.2.4.3.1:1.0/0003:0483:572D.0008/input/input14
U: Uniq=2070363C4250
H: Handlers=kbd event8
B: PROP=0
B: EV=13
B: KEY=3800000000 e000000000000 0
B: MSC=10
...&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This showed me a few useful things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The device vendor for my device is 0483 (the &amp;ldquo;I:&amp;rdquo; line)&lt;/li&gt;
&lt;li&gt;The product ID for my device is 572d (also on the &amp;ldquo;I:&amp;rdquo; line)&lt;/li&gt;
&lt;li&gt;The device is attached on /dev/input/event8 (on the &amp;ldquo;H:&amp;rdquo; line)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So now I could scan the events that came across when I moved the knob:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo evtest /dev/input/event8
Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x483 product 0x572d version 0x111
Input device name: &amp;#34;STMicroelectronics USB Volume Control&amp;#34;
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 113 (KEY_MUTE)
Event code 114 (KEY_VOLUMEDOWN)
Event code 115 (KEY_VOLUMEUP)
Event code 163 (KEY_NEXTSONG)
Event code 164 (KEY_PLAYPAUSE)
Event code 165 (KEY_PREVIOUSSONG)
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)
Properties:
Testing ... (interrupt to exit)
Event: time 1576479720.245227, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1576479720.245227, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
Event: time 1576479720.245227, -------------- SYN_REPORT ------------
Event: time 1576479720.253248, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e9
Event: time 1576479720.253248, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0
Event: time 1576479720.253248, -------------- SYN_REPORT ------------
Event: time 1576479722.325231, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1576479722.325231, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1
Event: time 1576479722.325231, -------------- SYN_REPORT ------------
Event: time 1576479722.333224, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00ea
Event: time 1576479722.333224, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0
Event: time 1576479722.333224, -------------- SYN_REPORT ------------
Event: time 1576479724.381251, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e2
Event: time 1576479724.381251, type 1 (EV_KEY), code 113 (KEY_MUTE), value 1
Event: time 1576479724.381251, -------------- SYN_REPORT ------------
Event: time 1576479724.389251, type 4 (EV_MSC), code 4 (MSC_SCAN), value c00e2
Event: time 1576479724.389251, type 1 (EV_KEY), code 113 (KEY_MUTE), value 0
Event: time 1576479724.389251, -------------- SYN_REPORT ------------&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Neat, even more useful things. In particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When I turn the knob to the right, I get an MSC_SCAN event of type c00e9 (along with a KEY_VOLUMEUP event)&lt;/li&gt;
&lt;li&gt;When I turn the knob to the left, I get an MSC_SCAN event of type c00ea (along with a KEY_VOLUMEDOWN event)&lt;/li&gt;
&lt;li&gt;When I push on the knob, I get an MSC_SCAN event of type c00e2 (along with a KEY_MUTE event)&lt;/li&gt;
&lt;li&gt;Apparently the firmware supports KEY_NEXTSONG, KEY_PREVIOUSSONG and KEY_PLAYPAUSE as well. Huh.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I want to map those MSC_SCAN events to different key codes. In particular, I want a cursor-left key when I turn the knob to the left, a cursor-right key when I turn the knob to the right, and something useful (say, pressing the &amp;ldquo;m&amp;rdquo; key) when I press the knob. So I created a hwdb file for my device:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ cat /etc/udev/hwdb.d/99-usb-knob.hwdb
evdev:input:b*v0483p572D*
KEYBOARD_KEY_c00ea=left
KEYBOARD_KEY_c00e9=right
KEYBOARD_KEY_c00e2=m&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;You&amp;rsquo;ll recognize the vendor (0483) and the device (572d) that I found earlier. It&amp;rsquo;s important to use uppercase hex codes for vendor and product in the hwdb file - but &lt;em&gt;not&lt;/em&gt; for the scan codes, which should be lowercase. The values on the right have to be lowercase, and correspond to the KEY_LEFT, KEY_RIGHT and KEY_M values from &lt;a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h" target="_blank" rel="noreferrer"&gt;/usr/include/linux/input-event-codes.h&lt;/a&gt;. (You can pick any of the KEY_ values from there.) Then a quick bit of Linux magic to update the hardware database:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo systemd-hwdb update
$ sudo udevadm trigger&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;hellip;and&amp;hellip; exactly the same as before. I got the volume control displayed when I turned the knob.&lt;/p&gt;
&lt;p&gt;After scratching my head and doing some searching, I happened on &lt;a href="https://catswhisker.xyz/log/2018/8/27/use_vecinfinity_usb_foot_pedal_as_a_keyboard_under_linux/" target="_blank" rel="noreferrer"&gt;https://catswhisker.xyz/log/2018/8/27/use_vecinfinity_usb_foot_pedal_as_a_keyboard_under_linux/&lt;/a&gt; which gave me the clue I needed. My knob was being detected, but not as a keyboard - so it wasn&amp;rsquo;t being used as a keyboard input device.&lt;/p&gt;
&lt;p&gt;So I created this file:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ cat /etc/udev/rules.d/99-usb-knob.rules
ACTION==&amp;#34;add|change&amp;#34;, KERNEL==&amp;#34;event[0-9]*&amp;#34;,
ATTRS{idVendor}==&amp;#34;0483&amp;#34;, ATTRS{idProduct}==&amp;#34;572d&amp;#34;,
ENV{ID_INPUT_KEYBOARD}=&amp;#34;1&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(That&amp;rsquo;s all on one line on my machine.) You&amp;rsquo;ll recognize the vendor and product ID from earlier, using lowercase for the hex this time. I added ID_INPUT_KEYBOARD to the list of attributes for this device. Unplug the device, plug it back in, and hooray! I&amp;rsquo;m doing what I wanted to! When I turn the knob left, I go left. When I turn the knob right, I go right. When I press the knob, &amp;ldquo;m&amp;rdquo; shows up on the screen.&lt;/p&gt;
&lt;p&gt;Now I just need to install an SDR program&amp;hellip; and an SDR&amp;hellip;.&lt;/p&gt;</description></item><item><title>Updating OpenBSD</title><link>https://andrewmemory.acornwall.net/blog/2019-08-12-updating-openbsd/</link><pubDate>Mon, 12 Aug 2019 01:56:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2019-08-12-updating-openbsd/</guid><description>&lt;p&gt;OpenBSD has a few different mechanism to update, depending on what the update is for.&lt;/p&gt;
&lt;p&gt;For packages: &lt;code&gt;pkg_add -u&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For the kernel and base system: &lt;code&gt;syspatch&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For firmware: &lt;code&gt;fw_update&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;All of these need to get run with doas if you&amp;rsquo;re not root.&lt;/p&gt;
&lt;p&gt;Finally, if you&amp;rsquo;re moving from one version to another: &lt;code&gt;sysupgrade sysmerge pkg_add -u&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Using an esp32 as an iBeacon</title><link>https://andrewmemory.acornwall.net/blog/2019-08-04-using-an-esp32-as-an-ibeacon/</link><pubDate>Sun, 04 Aug 2019 17:07:31 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2019-08-04-using-an-esp32-as-an-ibeacon/</guid><description>&lt;p&gt;I recently discovered the esp32, which is an interesting device that has Bluetooth as well as wifi built in. That got me thinking about setting one up as an iBeacon.&lt;/p&gt;
&lt;p&gt;First, I added my board in the File-&amp;gt;Preferences-&amp;gt;Additional Boards Manager URLs: &lt;a href="https://dl.espressif.com/dl/package" target="_blank" rel="noreferrer"&gt;https://dl.espressif.com/dl/package&lt;/a&gt;_esp32_index.json was what I needed.&lt;/p&gt;
&lt;p&gt;My next move was to install the 1.0.1 version of ESP32 BLE Arduino by Neil Kolban. Tools-&amp;gt;Manage Libraries-&amp;gt; Select 1.0.1 and click Install.&lt;/p&gt;
&lt;p&gt;From there, the BLE iBeacon example should be available. Under &amp;ldquo;Examples from Custom Libraries&amp;rdquo; you&amp;rsquo;ll  File-&amp;gt;Examples and under &amp;ldquo;Examples from Custom Libraries&amp;rdquo; you&amp;rsquo;ll see ESP32 BLE Arduino-&amp;gt;BLE_iBeacon.&lt;/p&gt;
&lt;p&gt;Strangely, this example gets the BLE ID backwards according to my scanner app. It looks as if there might be a fix in the latest (1.0.1-dev) source, but for now I just enter my UUID backwards. On the line&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#define BEACON_UUID &amp;#34;00112233-4455-6677-8899-aabbccddeeff&amp;#34; // UUID 1 128-Bit&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I use instead:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#define BEACON_UUID &amp;#34;ffeeccdd-bbaa-9988-7766-554433221100&amp;#34; // UUID 1 128-Bit&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Thanks to C, I didn&amp;rsquo;t need to do the two&amp;rsquo;s complement of the signal power myself:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; oBeacon.setSignalPower(-58);&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, I was getting advertising packets for multiple things (including an old test I&amp;rsquo;d tried). I had to erase the flash:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and then re-download in order to have only my iBeacon transmitting.&lt;/p&gt;</description></item><item><title>Changing the search bar text outside of Thunderbird</title><link>https://andrewmemory.acornwall.net/blog/2019-06-29-changing-the-search-bar-text-outside-of-thunderbird/</link><pubDate>Sat, 29 Jun 2019 00:22:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2019-06-29-changing-the-search-bar-text-outside-of-thunderbird/</guid><description>&lt;p&gt;I run Thunderbird on a shared Samba drive. Because of that, it crashes. I know, it&amp;rsquo;s not supported. But I want to be able to load the profile from multiple clients - one at a time - and can live with it.&lt;/p&gt;
&lt;p&gt;Frustratingly, sometimes it doesn&amp;rsquo;t crash. That means every time I start Thunderbird, the text in the search bar is the thing I searched for back in 2018. I finally got annoyed enough at that to figure out how to change it.&lt;/p&gt;
&lt;p&gt;In the Thunderbird profile is a file called session.json which includes what the last session state was. Inside that is the &amp;ldquo;quickFilter&amp;rdquo;, which determines what the filter shows. Mine was:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;{&amp;quot;quickFilter&amp;quot;:{&amp;quot;filterValues&amp;quot; : {&amp;quot;text&amp;quot; : {&amp;quot;text&amp;quot; : &amp;quot;thing I didn't want to search for anymore&amp;quot;, &amp;quot;states&amp;quot; : {&amp;quot;sender&amp;quot; : true, &amp;quot;recipients&amp;quot; : true, &amp;quot;subject&amp;quot; : true, &amp;quot;body&amp;quot; : false}}, &amp;quot;results&amp;quot; : 8}, &amp;quot;visible&amp;quot; : true}}&lt;/code&gt; I replaced &amp;ldquo;thing I didn&amp;rsquo;t want to search for anymore&amp;rdquo; with &amp;quot;&amp;quot; and life was good. Incidentally, I usually want to quick filter by sender, recipients, subject but not body - you can set all those with the appropriate booleans.&lt;/p&gt;
&lt;p&gt;If you never want to see the quick filter, &amp;ldquo;visible&amp;rdquo; : false is your friend.&lt;/p&gt;</description></item><item><title>Finding out which disk is which on Ubuntu</title><link>https://andrewmemory.acornwall.net/blog/2019-06-09-finding-out-which-disk-is-which-on-ubuntu/</link><pubDate>Sun, 09 Jun 2019 00:44:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2019-06-09-finding-out-which-disk-is-which-on-ubuntu/</guid><description>&lt;p&gt;My file server often has various disks swapped in and out. It can get confusing which /dev/sd? corresponds to which drive. While reading the man page of findfs, I stumbled on this:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The complete overview about filesystems and partitions you can get for example by:&lt;br&gt;
  lsblk &amp;ndash;fs&lt;br&gt;
  partx &amp;ndash;show&lt;br&gt;
  blkid&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;These three things (along with judicious use of e2label and the other *label commands) is going to make my life a lot easier!&lt;/p&gt;</description></item><item><title>Fixing Brother printing on Ubuntu</title><link>https://andrewmemory.acornwall.net/blog/2019-03-15-fixing-brother-printing-on-ubuntu/</link><pubDate>Fri, 15 Mar 2019 18:14:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2019-03-15-fixing-brother-printing-on-ubuntu/</guid><description>&lt;p&gt;Since moving to Ubuntu 16.04.3, printing to my Brother MFC-J650DW printer has been broken. I can print fine, but it&amp;rsquo;s always offset by a bit, never where it should be on the page.&lt;/p&gt;
&lt;p&gt;Turns out this is &lt;a href="https://bugs.launchpad.net/ubuntu/&amp;#43;source/cups/&amp;#43;bug/1184663" target="_blank" rel="noreferrer"&gt;a bug&lt;/a&gt; and there&amp;rsquo;s &lt;a href="https://askubuntu.com/questions/284441/hl-2240-brother-not-printing-at-margins?rq=1" target="_blank" rel="noreferrer"&gt;a workaround&lt;/a&gt;. So I don&amp;rsquo;t forget next time I set up printers:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lpadmin -p &amp;quot;Brother_MFC_J650DW&amp;quot; -o pdftops-renderer-default=pdftops&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Changing AllStar screen resolution</title><link>https://andrewmemory.acornwall.net/blog/2018-12-25-changing-allstar-screen-resolution/</link><pubDate>Tue, 25 Dec 2018 20:20:17 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2018-12-25-changing-allstar-screen-resolution/</guid><description>
&lt;h2 class="relative group"&gt;The Problem
&lt;div id="the-problem" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I recently became interested in &lt;a href="https://wiki.allstarlink.org/wiki/Main_Page" target="_blank" rel="noreferrer"&gt;AllStarLink&lt;/a&gt;, and had a &lt;a href="https://hamvoip.org/#download" target="_blank" rel="noreferrer"&gt;HamVoip image&lt;/a&gt; installed on a Raspberry Pi. (I was using &amp;ldquo;RPi2-3 includes 3B+ Image Version 1.5rc19&amp;rdquo;.)&lt;/p&gt;
&lt;p&gt;The AllStarLink image booted to 1366x768, which was the screen&amp;rsquo;s default resolution. However, the screen itself was a 7 inch HDMI screen. That was hard to read.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Things that didn&amp;rsquo;t work
&lt;div id="things-that-didnt-work" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#things-that-didnt-work" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I decided to change the resolution by editing /boot/cmdline.txt. My first attempt was to add:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;framebuffer_width=720
framebuffer_height=400&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;before the root= line at the beginning of the file. That resulted in a kernel panic:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Kernel Panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;After a while, I realized that root= had to come first. Then I tried:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;root=/dev/mmcblk0p2 rw rootwait bcm2708_fb.fbwidth=720 bcm2708_fb.fbheight=400
console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0
smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop
hdmi_safe=1
hdmi_group=1
hdmi_mode=1&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;but my cmdline.txt values seemed to be ignored.&lt;/p&gt;
&lt;p&gt;Finally I wised up: apparently when the Pi reads the root line it starts booting, ignoring everything after it in cmdline.txt. So, I had to pass the video size as a kernel parameter instead.&lt;/p&gt;
&lt;p&gt;I did:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;cat /proc/cmdline&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and saw:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;8250.nr_uarts=0 bcm2708_fb.fbwidth=1366 bcm2708_fb.fbheight=768
bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000
root=/dev/mmcblk0p2 rw rootwait console=ttyS0,115200 console=tty1 selinux=0
plymouth.enable=0 smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyS0,115200 elevator=noop&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;The Solution
&lt;div id="the-solution" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-solution" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;(For Linux / AllStarLink newbies: in order to get to the terminal, I picked menu item 9 - open a bash shell.)&lt;/p&gt;
&lt;p&gt;I went into /boot/cmdline.txt with a text editor:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;nano /boot/cmdline.txt&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and inserted the following two parameters on the existing line that begins with &amp;ldquo;root=&amp;rdquo;:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;bcm2708_fb.fbwidth=720 bcm2708_fb.fbheight=400&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I put these right after the &lt;strong&gt;rootwait&lt;/strong&gt; parameter, so in /boot/cmdline.txt I now had:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;root=/dev/mmcblk0p2 rw rootwait bcm2708_fb.fbwidth=720 bcm2708_fb.fbheight=400
console=ttyAMA0,115200 console=tty1 selinux=0 plymouth.enable=0
smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=ttyAMA0,115200 elevator=noop&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(Note that root line is all one long line - not broken up with line separators!)&lt;/p&gt;
&lt;p&gt;Once I did that and saved it, the Raspberry Pi booted up in glorious 80x25 text. Now we could read it!&lt;/p&gt;</description></item><item><title>Let me know (mail me) when there's an error</title><link>https://andrewmemory.acornwall.net/blog/2018-09-05-let-me-know-when-theres-an-error/</link><pubDate>Wed, 05 Sep 2018 23:42:04 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2018-09-05-let-me-know-when-theres-an-error/</guid><description>&lt;p&gt;I&amp;rsquo;ve got a shell script where I&amp;rsquo;d like to know when an error happens. Typically when that happens, something gets written to stdout or stderr - and I&amp;rsquo;d like to see that. But when things are just peachy, I don&amp;rsquo;t want to be bothered.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an easy way to achieve that. At the beginning of my script, I have:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;WEATHEROUT=`/bin/mktemp`
WEATHERERR=`/bin/mktemp`&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(Did I mention this is a script for a weather station? Yep.)&lt;/p&gt;
&lt;p&gt;Then in the body of the script, I have:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/usr/local/bin/do-the-thing &amp;gt; ${WEATHEROUT} 2&amp;gt; ${WEATHERERR}
/usr/local/bin/do-the-other-thing &amp;gt;&amp;gt; ${WEATHEROUT} 2&amp;gt;&amp;gt; ${WEATHERERR}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, at the end of the script, there&amp;rsquo;s:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;if [ -s ${WEATHERERR} -o -s ${WEATHEROUT} ]; then
cat ${WEATHEROUT} ${WEATHERERR} | /usr/bin/mail -s &amp;#34;Weather command error&amp;#34; me@myaddr
fi&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That&amp;rsquo;s all!&lt;/p&gt;</description></item><item><title>Ubiquiti AP enters reset state but never leaves</title><link>https://andrewmemory.acornwall.net/blog/2018-07-20-ubiquiti-ap-enters-reset-state-but-never-leaves/</link><pubDate>Fri, 20 Jul 2018 13:11:31 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2018-07-20-ubiquiti-ap-enters-reset-state-but-never-leaves/</guid><description>&lt;p&gt;I did something dumb recently. I had a network failure at my ISP, so I had to kill my dhclient and restart it. After restarting, everything seemed cool - until I reset my Ubiquiti AP. At that point, the AP entered the &amp;ldquo;Restarting&amp;rdquo; state and never came out.&lt;/p&gt;
&lt;p&gt;After a few minutes of poking around on the Ubiquiti management screen, I saw this:&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Screenshot from 2018-07-20 13:11:31-0700 13-09-11"
width="376"
height="139"
src="https://andrewmemory.acornwall.net/blog/2018-07-20-ubiquiti-ap-enters-reset-state-but-never-leaves/images/screenshot-from-2018-07-20-13-09-11.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2018-07-20-ubiquiti-ap-enters-reset-state-but-never-leaves/images/screenshot-from-2018-07-20-13-09-11.jpg 800w, https://andrewmemory.acornwall.net/blog/2018-07-20-ubiquiti-ap-enters-reset-state-but-never-leaves/images/screenshot-from-2018-07-20-13-09-11.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2018-07-20-ubiquiti-ap-enters-reset-state-but-never-leaves/images/screenshot-from-2018-07-20-13-09-11.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Apparently I killed off my DHCP server too. Oops.&lt;/p&gt;
&lt;p&gt;One restart of the DHCP server later, my AP was back online (it detected when the DHCP server started). Some day I really should put the AP on its own static IP. That&amp;rsquo;s what I get for being lazy&amp;hellip;&lt;/p&gt;</description></item><item><title>What's up with mod_security and User-Agent? (406 Not Acceptable)</title><link>https://andrewmemory.acornwall.net/blog/2018-05-01-whats-up-with-mod_security-and-user-agent-406-not-acceptable/</link><pubDate>Tue, 01 May 2018 21:25:32 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2018-05-01-whats-up-with-mod_security-and-user-agent-406-not-acceptable/</guid><description>&lt;p&gt;So&amp;hellip; what&amp;rsquo;s the deal with mod_security and User-Agent? I tried to browse to &lt;a href="http://handheldradio.net" target="_blank" rel="noreferrer"&gt;HandheldRadio.net&lt;/a&gt; using Lynx, and was greeted with this 406 error:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; Not Acceptable
An appropriate representation of the requested resource / could not be
found on this server.
Additionally, a 406 Not Acceptable error was encountered while trying
to use an ErrorDocument to handle the request.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;A few searches and I discovered this was due to Apache mod_security.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t get it. Why would you exclude based on User-Agent? That&amp;rsquo;s something that can be changed at will by any program that decides to be nefarious. This seems like security theatre rather than real security.&lt;/p&gt;
&lt;p&gt;Even in the &lt;a href="https://flameeyes.posts/2009/02/16/my-idea-works-filtering-by-user-agent-that-is/" target="_blank" rel="noreferrer"&gt;best case&lt;/a&gt;, this kind of &amp;ldquo;security&amp;rdquo; just turns into a red queen&amp;rsquo;s race to the bottom where everything will now lie about what it is because someone screwed up a config file somewhere.&lt;/p&gt;
&lt;p&gt;And so I&amp;rsquo;ve started lying (in my .bashrc):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;alias lynx=&amp;#39;lynx -useragent=&amp;#34;Mozilla/5.0 (X11; Ubuntu Lynx; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0&amp;#34;&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Damn, that&amp;rsquo;s stupid.&lt;/p&gt;</description></item><item><title>Setting a user and group for Samba drives</title><link>https://andrewmemory.acornwall.net/blog/2018-04-14-setting-a-user-and-group-for-samba-drives/</link><pubDate>Sat, 14 Apr 2018 21:06:43 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2018-04-14-setting-a-user-and-group-for-samba-drives/</guid><description>&lt;p&gt;The last time I tried to set a user and password on my Samba drive, I ran into a strange problem: even though my credentials were correct, I was still using the user and group I was logged in as, rather than the one I&amp;rsquo;d stored with the Samba config.&lt;/p&gt;
&lt;p&gt;Luckily, these days there&amp;rsquo;s an easy way around it in /etc/fstab:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;//mysvr/music /music cifs uid=1000,gid=1000,credentials=/etc/samba/credentials/mysvr&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Simply adding the uid= and gid= lines fixed up the problem for me.&lt;/p&gt;</description></item><item><title>What the hell, Gnome? Canonical?</title><link>https://andrewmemory.acornwall.net/blog/2018-01-01-what-the-hell-gnome-canonical/</link><pubDate>Mon, 01 Jan 2018 23:00:29 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2018-01-01-what-the-hell-gnome-canonical/</guid><description>&lt;p&gt;Today when I started working on my desktop, I saw a crash in gom-media-tracker. What? Why is there a media tracker on my desktop?&lt;/p&gt;
&lt;p&gt;I learned this is part of Gnome (what? Why is there a media tracker in Gnome?) and it&amp;rsquo;s included in Ubuntu 16.04 LTS (why is Canonical including tracking software in Ubuntu?)&lt;/p&gt;
&lt;p&gt;Screw that. I removed it.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo apt remove gnome-online-miners
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
gnome-documents gnome-online-miners gnome-photos ubuntu-gnome-desktop
0 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
After this operation, 6,472 kB disk space will be freed.
Do you want to continue? [Y/n] y
dpkg: warning: files list file for package &amp;#39;fonts-gfs-complutum&amp;#39; missing; assuming package has no files currently installed
(Reading database ... 493027 files and directories currently installed.)
Removing ubuntu-gnome-desktop (0.58.3) ...
Removing gnome-documents (3.18.3-0ubuntu0.16.04.1) ...
Removing gnome-photos (3.18.2-1) ...
Removing gnome-online-miners (3.14.3-1ubuntu2) ...
Processing triggers for libglib2.0-0:amd64 (2.48.2-0ubuntu1) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for hicolor-icon-theme (0.15-0ubuntu1) ...
Processing triggers for gnome-menus (3.13.3-6ubuntu3.1) ...
Processing triggers for desktop-file-utils (0.22-1ubuntu5.1) ...
Processing triggers for bamfdaemon (0.5.3~bzr0&amp;#43;16.04.20160824-0ubuntu1) ...
Rebuilding /usr/share/applications/bamf-2.index...
Processing triggers for mime-support (3.59ubuntu1) ...
$ &lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now that I&amp;rsquo;ve done that, I don&amp;rsquo;t appear to have lost anything I use. (Why is an optional packages forcing other packages out?)&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t want random tracking software on my machine.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://wiki.gnome.org/Projects/Tracker" target="_blank" rel="noreferrer"&gt;wiki.gnome.org/Projects/Tracker&lt;/a&gt;, you suck. Gnome, you suck. Canonical, you suck.&lt;/p&gt;</description></item><item><title>Updating to the latest TeX on Ubuntu 16.04</title><link>https://andrewmemory.acornwall.net/blog/2017-11-20-updating-to-the-latest-tex-on-ubuntu-16-04/</link><pubDate>Mon, 20 Nov 2017 16:42:26 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-11-20-updating-to-the-latest-tex-on-ubuntu-16-04/</guid><description>&lt;p&gt;I had problems running the TeXLive package manager tlmgr on my Ubuntu 16.04 LTS install. Apparently the package manager changed formats in 2016, so the version that is included with Ubuntu is out of date (and presumably so is TeX/LaTeX).&lt;/p&gt;
&lt;p&gt;Luckily, there&amp;rsquo;s a repo with the latest TeX as described here: &lt;a href="http://tipsonubuntu.com/2016/09/16/install-tex-live-2016-ubuntu-16-04-14-04/" target="_blank" rel="noreferrer"&gt;tipsonubuntu.com/2016/09/16/install-tex-live-2016-ubuntu-16-04-14-04/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short, if you have TeX already installed, do this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo add-apt-repository ppa:jonathonf/texlive sudo apt update; sudo apt upgrade&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After that you&amp;rsquo;ll run into the following bug: &lt;a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=824137" target="_blank" rel="noreferrer"&gt;bugs.debian.org/cgi-bin/bugreport.cgi?bug=824137&lt;/a&gt;   You&amp;rsquo;ll need to do the following to get around it: &lt;code&gt;sudo apt -f remove texlive-base texlive-fonts-recommended texlive-latex-extra texlive-latex-recommended texlive-pictures texlive-pstricks texlive-base-bin prosper texlive-fonts-recommended-doc texlive-fonts-extra-doc texlive-latex-base texlive-generic-recommended texlive-latex-base-doc texlive-latex-extra-doc texlive-latex-recommended-doc texlive-pictures-doc texlive-pstricks-doc tipa sudo apt install texlive-base texlive-fonts-recommended texlive-latex-extra texlive-latex-recommended texlive-pictures texlive-pstricks texlive-base-bin prosper texlive-fonts-recommended-doc texlive-fonts-extra-doc texlive-latex-base texlive-generic-recommended texlive-latex-base-doc texlive-latex-extra-doc texlive-latex-recommended-doc texlive-pictures-doc texlive-pstricks-doc tipa&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After that, you should be running the latest TexLive.&lt;/p&gt;</description></item><item><title>Upgrading Mythbuntu from Trusty to Xenial</title><link>https://andrewmemory.acornwall.net/blog/2017-06-25-upgrading-mythbuntu-from-trusty-to-xenial/</link><pubDate>Sun, 25 Jun 2017 16:35:29 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-06-25-upgrading-mythbuntu-from-trusty-to-xenial/</guid><description>&lt;p&gt;Yesterday I took the plunge and upgraded my Mythbuntu install from Trusty to Xenial. Except for a few heart-stopping moments, it went smoothly.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Things I wish I&amp;rsquo;d known about the upgrade
&lt;div id="things-i-wish-id-known-about-the-upgrade" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#things-i-wish-id-known-about-the-upgrade" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There&amp;rsquo;s a bug with upgrading MySQL when you have the Mythbuntu tweaks installed. As a result, the upgrade fails to install MySQL properly - and then everything looks broken. Ouch. &lt;a href="https://bugs.launchpad.net/ubuntu/&amp;#43;source/mythbuntu-common/&amp;#43;bug/1576767" target="_blank" rel="noreferrer"&gt;You can find out more about the defect here&lt;/a&gt;. The symptom is the message &amp;ldquo;\[ERROR\] unknown variable &amp;rsquo;table_cache=128&amp;rsquo; &amp;quot; which scrolls off the screen when you do an upgrade (or dpkg &amp;ndash;configure -a). The fix is to change&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;table_cache = 128&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;table_open_cache = 128&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;in /etc/mysql/conf.d/mythtv-tweaks.cnf.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;During the upgrade, I got prompted for which user to use for the database. (With the recommendation to use &amp;ldquo;root&amp;rdquo; if you don&amp;rsquo;t thoroughly understand the permissions models.) But of course &amp;ldquo;root&amp;rdquo; didn&amp;rsquo;t work. What did work was the default, debian-sys-maint.&lt;/li&gt;
&lt;li&gt;After install, lirc didn&amp;rsquo;t work. I uninstalled lirc using Mythbuntu Control Center and rebooted; that appeared to fix things and now my Streamzap remote is being detected as a keyboard device with the appropriate mappings. (I get a warning about a plugin using MCC, but hey, it seems to work.)&lt;/li&gt;
&lt;li&gt;Next, I got warnings using apt. Probably due to the upgrade failure, I had a file called 50unattended-upgrades.ucf-old left over in /etc/apt/apt.conf.d. Nuking that fixed things.&lt;/li&gt;
&lt;li&gt;It looks as if mythfrontend and mythbackend are using different users now. I&amp;rsquo;m not sure why, but some day I&amp;rsquo;ll need to go through and fix permissions / unify those two users.&lt;/li&gt;
&lt;li&gt;I had to go into mythtv-setup and assign directories for music and music art. (Since I didn&amp;rsquo;t have an art directory, I created one under my music directory. That seems to work.)&lt;/li&gt;
&lt;li&gt;Probably as a result of the botched upgrade, mythweb was broken. I installed php7.0-mysql, then removed/installed mythweb and it was working again.&lt;/li&gt;
&lt;li&gt;Finally, I tried to look into mythconverg. In this release the admin user is debian-sys-maint, and the password for that user is stored in /etc/mysql/debian.cnf.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>US coin values by weight</title><link>https://andrewmemory.acornwall.net/blog/2017-02-06-us-coin-values-by-weight/</link><pubDate>Mon, 06 Feb 2017 23:57:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-02-06-us-coin-values-by-weight/</guid><description>&lt;p&gt;One thing that it&amp;rsquo;s often wise to have for emergencies is a handful of change. If you&amp;rsquo;re stuck somewhere where there&amp;rsquo;s nothing to eat but vending machine goodness, it might mean the difference between having a meal or not.&lt;/p&gt;
&lt;p&gt;But if you bring change, what sort of change should you bring? Going strictly by weight, the $1 coin is the best value for weight right now. But there&amp;rsquo;s one drawback to that: some vending machines don&amp;rsquo;t take $1 coins. So what should you carry if you want to get maximum snacks?&lt;/p&gt;
&lt;p&gt;The US Mint has a list of US coin weights as part of their &lt;a href="https://www.usmint.gov/about_the_mint/index583f.html?action=coin_specifications" target="_blank" rel="noreferrer"&gt;specifications&lt;/a&gt;. That tells you what you need to know. Here&amp;rsquo;s a table based on the weight of mint condition coins (coins lose mass as they get used):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;Coin Value ($)&lt;/th&gt;
&lt;th style="text-align: center"&gt;Coin Weight (g)&lt;/th&gt;
&lt;th style="text-align: center"&gt;Weight (g) for $1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.01&lt;/td&gt;
&lt;td style="text-align: center"&gt;2.5&lt;/td&gt;
&lt;td style="text-align: center"&gt;250.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.05&lt;/td&gt;
&lt;td style="text-align: center"&gt;5.0&lt;/td&gt;
&lt;td style="text-align: center"&gt;100.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.10&lt;/td&gt;
&lt;td style="text-align: center"&gt;2.268&lt;/td&gt;
&lt;td style="text-align: center"&gt;22.68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;0.25&lt;/td&gt;
&lt;td style="text-align: center"&gt;5.670&lt;/td&gt;
&lt;td style="text-align: center"&gt;22.68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;1.00&lt;/td&gt;
&lt;td style="text-align: center"&gt;11.34&lt;/td&gt;
&lt;td style="text-align: center"&gt;11.34&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That reveals some interesting facts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nickles weigh exactly 5 g each&lt;/li&gt;
&lt;li&gt;Two pennies weigh the same as one nickle&lt;/li&gt;
&lt;li&gt;$10 in nickels or $4 in pennies weigh 1 kg&lt;/li&gt;
&lt;li&gt;Quarters and dimes have the same value by weight&lt;/li&gt;
&lt;li&gt;Dollar coins are twice as valuable as quarters and dimes by weight&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So if you&amp;rsquo;re on a road trip and plan to dine at the automat, grab your dollar coins first, then your dimes and quarters. Skip the nickles (unless you think that you&amp;rsquo;ll have to weigh something — it might be handy to have a few 5g weights around). And there&amp;rsquo;s a reason that only zinc producers like pennies.&lt;/p&gt;</description></item><item><title>Dockerizing TicketsCAD</title><link>https://andrewmemory.acornwall.net/blog/2017-01-04-dockerizing-ticketscad/</link><pubDate>Wed, 04 Jan 2017 23:10:52 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-01-04-dockerizing-ticketscad/</guid><description>&lt;p&gt;Over the recent holiday, I decided to teach myself about Docker by using it to build a running &lt;a href="http://www.ticketscad.org/" target="_blank" rel="noreferrer"&gt;TicketsCAD&lt;/a&gt; system. It turned out to be pretty slick. Here&amp;rsquo;s what I did.&lt;/p&gt;
&lt;p&gt;TicketsCAD is a PHP application that requires an SQL backend. It does computer dispatching for public safety answering points (PSAPs). Yes, I have weird hobbies.&lt;/p&gt;
&lt;p&gt;When I first started, I grabbed the official Docker PHP image, then tried to customize it by installing a MariaDB server. But that turned out to be a bad idea. (It&amp;rsquo;s certainly possible, but not the right thing to do.) After a little while, I did a search for &amp;ldquo;Docker philosophy&amp;rdquo;, which brought me to this page: &lt;a href="http://techblog.constantcontact.com/devops/a-tale-of-three-docker-anti-patterns" target="_blank" rel="noreferrer"&gt;techblog.constantcontact.com/devops/a-tale-of-three-docker-anti-patterns&lt;/a&gt; which set me straight. The right way to do what I wanted to do was to have two separate (but linked) Docker container instances - one with the web server and PHP (customized the way I wanted) and the other with the SQL database. So here&amp;rsquo;s what I came up with.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Grab TicketsCAD
&lt;div id="grab-ticketscad" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#grab-ticketscad" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I grabbed the files from the TicketsCAD download area: &lt;a href="http://www.ticketscad.org/downloads/" target="_blank" rel="noreferrer"&gt;tickets_3.12A_082516&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next I created a directory for everything. In that, I put a directory for the ticketscad server (I cleverly called it ticketscad) and another directory for the ticketscad SQL server (even more cleverly called ticketscadmariadb). Then I created var-www-html in ticketscad, and untarred the TicketsCAD files into it.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Dockerfile for TicketsCAD
&lt;div id="dockerfile-for-ticketscad" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dockerfile-for-ticketscad" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s the first Docker file (named Dockerfile in the ticketscad directory).&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;FROM php:7.0-apache
# Set the timezone
RUN echo Canada/Eastern &amp;gt; /etc/timezone &amp;amp;&amp;amp; dpkg-reconfigure -f \
noninteractive tzdata
# get PHP GD libraries
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
&amp;amp;&amp;amp; docker-php-ext-install -j$(nproc) iconv mcrypt \
&amp;amp;&amp;amp; docker-php-ext-configure gd \
--with-freetype-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ \
&amp;amp;&amp;amp; docker-php-ext-install -j$(nproc) gd
# Install Mariadb client
RUN apt-get install mariadb-client -y
RUN docker-php-ext-install mysqli pdo pdo_mysql
# Fix permissions for ticketscad
RUN chown -R www-data.www-data /var/www/html
RUN chmod -R u&amp;#43;w /var/www/html&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;From top to bottom, here&amp;rsquo;s the explanation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I used the official &lt;a href="https://hub.docker.com/_/php/" target="_blank" rel="noreferrer"&gt;PHP Docker build&lt;/a&gt; with Apache from hub.docker.com. There were some issues with TicketsCAD and PHP 7.1, so I went down to PHP 7.0. (Docker made this very easy to do.)&lt;/li&gt;
&lt;li&gt;I set the timezone. This is a bit of Docker weirdness - there&amp;rsquo;s no standard way in Linux to set timezones, so you need to know how to do it in the distribution you&amp;rsquo;re using. This is how to do it in the PHP distribution. More details about timezones are at &lt;a href="https://www.ivankrizsan.se/2015/10/31/time-in-docker-containers/" target="_blank" rel="noreferrer"&gt;www.ivankrizsan.se/2015/10/31/time-in-docker-containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I installed the PHP GD libraries. This is stolen from the PHP Core Extensions section of PHP on hubs.docker.com, and it installs a few other things I probably don&amp;rsquo;t need (mcrypt, etc.) I just copied and pasted.&lt;/li&gt;
&lt;li&gt;I installed the MariaDB client and PHP SQL extensions.&lt;/li&gt;
&lt;li&gt;TicketsCAD wants to write to /var/www/html and its subdirectories, so I made them rw. (I&amp;rsquo;m not sure how that makes me feel about security - I&amp;rsquo;d kind of prefer it not to do that and to store configuration somewhere not visible to the world. But that&amp;rsquo;s how it works.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that I had that running, I needed a SQL backend. Luckily, there&amp;rsquo;s an official &lt;a href="https://hub.docker.com/_/mariadb/" target="_blank" rel="noreferrer"&gt;MariaDB Docker build&lt;/a&gt; as well. The Dockerfile for this is so simple that I almost don&amp;rsquo;t need it, but hey, I had a directory created already, so here it is:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Dockerfile for MariaDB
&lt;div id="dockerfile-for-mariadb" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#dockerfile-for-mariadb" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;FROM mariadb:10.1
RUN echo Canada/Eastern &amp;gt; /etc/timezone &amp;amp;&amp;amp; dpkg-reconfigure -f \
noninteractive tzdata
RUN chown -R mysql.mysql /var/lib/mysql&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Pretty self-explanatory. I don&amp;rsquo;t know for sure that I need that chown, but it doesn&amp;rsquo;t hurt.&lt;/p&gt;
&lt;h2 class="relative group"&gt;docker-compose.yml
&lt;div id="docker-composeyml" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#docker-composeyml" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I built a docker-compose.yml in my parent directory. This is a way to start both instances at the same time.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;version: &amp;#39;2&amp;#39;
services:
ticketscadmariadb:
build: ./ticketscadmariadb
image: ticketscadmariadb:1.0
volumes:
- ./ticketscadmariadb/var-lib-mysql:/var/lib/mysql
ports:
- &amp;#34;3306:3306&amp;#34;
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=ticketscaddb
- MYSQL_USER=ticketscaduser
- MYSQL_PASSWORD=ticketscadpassword
ticketscad:
build: ./ticketscad
image: ticketscad:1.0
volumes:
- ./ticketscad/var-www-html:/var/www/html
ports:
- &amp;#34;8080:80&amp;#34;
links:
- ticketscadmariadb&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s a lot in there. I&amp;rsquo;ll break it down.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;m using version 2 of the docker-compose.yml file format. Gotta say so.&lt;/li&gt;
&lt;li&gt;First I specified the way to build ticketscadmariadb. I pointed to the subdirectory that holds the Dockerfile and gave it an image name.&lt;/li&gt;
&lt;li&gt;I exposed the directory on my local machine that will hold the MariaDB database. (It&amp;rsquo;s /var/lib/mysql on the Docker instance; I called it var-lib-mysql in the ticketscadmariadb directory on my local machine.) Why did I do this? So the SQL database would persist across Docker rebuilds. Needless to say, I created an empty var-lib-mysql under ticketscadmariadb on my local system.&lt;/li&gt;
&lt;li&gt;I exposed the MariaDB SQL port (3306) and mapped it to 3306 on my local machine. If you have SQL running on your local machine already, you&amp;rsquo;ll need a different local port.&lt;/li&gt;
&lt;li&gt;I specified a bunch of environment variables for MariaDB. The MariaDB Docker image is smart enough to know that if it sees those variables, it creates a database with the specified name / user / password / root user. Thanks, MariaDB Docker image! (You&amp;rsquo;ll probably want different passwords than I used.)&lt;/li&gt;
&lt;li&gt;Now it&amp;rsquo;s time for the TicketsCAD image (PHP/Apache server). I pointed to the ticketscad subdirectory (which holds the Dockerfile) and gave it an image name.&lt;/li&gt;
&lt;li&gt;I mapped the /var/www/html directory on my Docker image to ./ticketscad/var-www-html on my local machine. Why not just COPY? Because TicketsCAD writes to /var/www/html and /var/www/html/incs, and I want that to persist across builds.&lt;/li&gt;
&lt;li&gt;I exposed port 80 on the Docker image as port 8080 on my local machine.&lt;/li&gt;
&lt;li&gt;Finally, I told Docker that I want to be able to have the ticketscad image talk to the ticketscadmariadb image using the links: command. (If I didn&amp;rsquo;t do this, the two images wouldn&amp;rsquo;t be able to communicate.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Building and running
&lt;div id="building-and-running" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#building-and-running" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;So now everything&amp;rsquo;s set up. At this point, I can go to the parent directory and type:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker-compose up&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That reads docker-compose.yml by default, downloads the files that are needed and creates my images. And voilà, a working TicketsCAD install is ready to go.&lt;/p&gt;
&lt;p&gt;Well, almost ready to go. Because Docker assigns IP addresses for each build, I had to interrogate the running images in order to figure out what they were. First I used docker ps to find out that the container ID of the ticketscadmariadb instance was 2e13d01384ac, then I used docker inspect to discover its IP address. I needed to know the IP address for the TicketsCAD configuration screen.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker ps
docker inspect 2e13d01384ac | grep IPAddress&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;For me it was 172.17.0.2.&lt;/p&gt;
&lt;p&gt;Because I have the TicketsCAD port 80 exposed on my local machine as 8080, I can now go to localhost:8080 to run TicketsCAD.&lt;/p&gt;
&lt;h2 class="relative group"&gt;What next?
&lt;div id="what-next" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-next" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;This is enough to get TicketsCAD up and running in a &amp;ldquo;play&amp;rdquo; environment. In a real environment, you&amp;rsquo;d want to harden things. In particular, remove the install.php script and save the Docker image after installation, and make sure that random yahoos on the Internet can&amp;rsquo;t write to /var/www/html. Give the machines real hostnames. Set up real certificates and put them on the network. Run something to prevent DDOS attacks. All them devops things.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Hey TicketsCAD guys!
&lt;div id="hey-ticketscad-guys" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#hey-ticketscad-guys" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve got some cool software. If possible, it would be nice for TicketsCAD to have a check box to delete install.php for you after running it - then it would be more compatible with Docker.&lt;/p&gt;
&lt;h2 class="relative group"&gt;A few more more useful things
&lt;div id="a-few-more-more-useful-things" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#a-few-more-more-useful-things" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;1. If you want to look into a running Docker instance, this is nice to know:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker exec -it containerID bash&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;It brings you to a root shell running bash on the instance.&lt;/p&gt;
&lt;p&gt;2. I ran into problems after I removed some images with docker -rmi. &lt;a href="http://stackoverflow.com/questions/37454548/docker-compose-no-such-image" target="_blank" rel="noreferrer"&gt;stackoverflow.com/questions/37454548/docker-compose-no-such-image&lt;/a&gt; solved my problem (in short: docker-compose down).&lt;/p&gt;
&lt;p&gt;3. Sometimes you&amp;rsquo;ll need to rebuild.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker-compose up --build&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;is a handy way to do that.&lt;/p&gt;
&lt;h2 class="relative group"&gt;My directory structure
&lt;div id="my-directory-structure" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#my-directory-structure" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;docker-ticketscad/
docker-compose.yml
ticketscad/
Dockerfile
  var-www-html/
(all the TicketsCAD files go here)
ticketscadmariadb/
Dockerfile
var-lib-mysql/&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Tracking and blocking BRW70188B</title><link>https://andrewmemory.acornwall.net/blog/2017-01-02-tracking-and-blocking-brw70188b/</link><pubDate>Mon, 02 Jan 2017 03:00:00 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2017-01-02-tracking-and-blocking-brw70188b/</guid><description>&lt;p&gt;I&amp;rsquo;ve been monitoring wifi traffic on my network. I&amp;rsquo;ve seen a large amount sent up by one device, which was reported as starting with BR70188B (mac address 70:18:8b) with manufacturer HonHaiPr.&lt;/p&gt;
&lt;p&gt;HonHaiPr is Hon Hai Precision Industry, which makes network devices. The one in question (with the name BRW70188Bxxyyzz) was from a Brother MFC-650DW that is on the network.&lt;/p&gt;
&lt;p&gt;Now that I&amp;rsquo;ve identified the printer, what to do about it? It was spewing lots of uploaded data - perhaps just to the clients that printed from it, but I&amp;rsquo;m perhaps a little paranoid. (It seems strange that it&amp;rsquo;s uploading almost as much as gets downloaded to the printer, though.) So I decided to knock it off the Internet to see what happened.&lt;/p&gt;
&lt;p&gt;First, I gave it a static IP address in my dhcpd.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;host mfc650dw {
hardware ethernet 70:18:8B:xx:yy:zz;
fixed-address 192.168.1.253;
option host-name &amp;#34;mfc650dw&amp;#34;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, I updated it in DNS (db and db.rev files) just &amp;lsquo;cause now that it&amp;rsquo;s static it&amp;rsquo;s handy to have a name to deal with.&lt;/p&gt;
&lt;p&gt;Finally, I added a rule to my pf.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;block out log quick from 192.168.1.253/32 to ! 192.168.1/24&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now if the printer&amp;rsquo;s trying to send data up to the Internet, it&amp;rsquo;s not going to make it through the firewall.&lt;/p&gt;
&lt;p&gt;After I did all this, the printer wouldn&amp;rsquo;t work - Brother apparently stores the IP address but doesn&amp;rsquo;t refresh if it can&amp;rsquo;t find it. So I needed to download the &lt;a href="https://help.brother-usa.com/app/answers/detail/a_id/55914/~/download-the-network-connection-repair-tool---windows" target="_blank" rel="noreferrer"&gt;Brother Network Connection Repair Tool&lt;/a&gt; to tell the Windows printer driver to look for the printer again. Sheesh.&lt;/p&gt;</description></item><item><title>Translation of Evangeline Acadian Queen</title><link>https://andrewmemory.acornwall.net/blog/2016-12-03-translation-of-evangeline-acadian-queen/</link><pubDate>Sat, 03 Dec 2016 19:50:07 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-12-03-translation-of-evangeline-acadian-queen/</guid><description>&lt;p&gt;Angèle Arsenault wrote this back in 1977, and I haven&amp;rsquo;t been able to find a translation that I really liked. So I had to do it myself. It&amp;rsquo;s from her album &lt;em&gt;Libre&lt;/em&gt; (SPPS Disques, PS-19903) and was my first introduction to Acadia.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to talk to you of someone that you know Yes but don&amp;rsquo;t deceive yourself, she did not come from the States Even if a certain fellow who was called Longfellow Popularized her two hundred years ago She was called Évangéline, she was very very fine She loved Gabriel on earth as if in heaven They lived in Acadia, they were damned rich1 But one day the English were no longer satisfied So they deported them, Gabriel disappeared Discouraged2 Évangéline searched for him as long as she could She searched for him in Acadia in Quebec in Ontario Then in the United States in Florida in Idaho Arriving in Louisiana with her cousin Diane She said I have lost my time3 She was 75 years old4 Working a the hospital, she cared for the sick Then she saw her Gabriel who was leaving for heaven She jumped on his neck And said thank you very much At the hour that you&amp;rsquo;re interred I will be able to return I&amp;rsquo;m going to invest in the companies of the future So that the name of Évangéline will be bloody well known5&lt;/p&gt;
&lt;p&gt;Évangéline Fried Clams Évangéline Salon Bar Évangéline Sexy Ladies Wear Évangéline Comfortable Running Shoes Évangéline Automobile Springs Évangéline Regional High School Évangéline Savings Mortgage and Loans Évangéline The only French Newspaper in New Brunswick Évangéline Acadian Queen&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;This is &amp;ldquo;riches en maudit&amp;rdquo; in the original.&lt;/li&gt;
&lt;li&gt;This is &amp;ldquo;déconfortée&amp;quot;in the original.&lt;/li&gt;
&lt;li&gt;This proves that Angèle didn&amp;rsquo;t come from Clare, since she wrote &amp;ldquo;soixante et quinze&amp;rdquo; instead of &amp;ldquo;septante-cinq.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;This is &amp;ldquo;A dit là j&amp;rsquo;perdrai pu mon temps.&amp;rdquo; It seems to indicate both past and future.&lt;/li&gt;
&lt;li&gt;This was the hardest to translate, &amp;ldquo;soit connu en câline.&amp;rdquo; Literally, &amp;ldquo;will be known in cuddly&amp;rdquo; but &lt;em&gt;câline&lt;/em&gt; is a milder form of the &lt;em&gt;sacre&lt;/em&gt; (expletive) &lt;em&gt;câlisse&lt;/em&gt; or chalice.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Ubuntu 16.04.1 - cron mail not working</title><link>https://andrewmemory.acornwall.net/blog/2016-09-19-ubuntu-16-04-1-cron-mail-not-working/</link><pubDate>Mon, 19 Sep 2016 00:08:08 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-09-19-ubuntu-16-04-1-cron-mail-not-working/</guid><description>&lt;p&gt;I recently ran into a strange issue. I wasn&amp;rsquo;t getting mail from cron - even though I could mail myself locally without incident. My cron daemon was running fine, and I had MAILTO=user specified in the crontab.&lt;/p&gt;
&lt;p&gt;The first piece of advice everyone says when you search about this is &amp;ldquo;make sure you can send mail to yourself.&amp;rdquo; And I could - using mail or mailx and sending to andrew. And if you try searching for help after that, you get lost in the weeds of people trying to send mail to Gmail, and setting up postfix, and going insane.&lt;/p&gt;
&lt;p&gt;After a little poking around, I noticed this in my /var/log/mail.log:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Sep 12 04:28:01 myserver postfix/qmgr[2902]: A292710059B:
from=&amp;lt;root@myserver.mydomain.com&amp;gt;, size=800, nrcpt=1 (queue active)
Sep 12 04:28:01 myserver postfix/error[20839]: A292710059B:
to=&amp;lt;andrew@myserver.mydomain.com&amp;gt;, orig_to=&amp;lt;andrew&amp;gt;, relay=none, delay=1.4,
delays=1/0.12/0/0.25, dsn=5.0.0, status=bounced (myserver.mydomain.com)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;ve been faking my domain name and it looks like when I upgraded to Ubuntu 16.04.1 things stopped working. (I have a sneaking suspicion that the upgrade process yanked the domain address out of /etc/hosts. But maybe cron changed and started using my FQDN instead of my local mail address.)&lt;/p&gt;
&lt;p&gt;But even after changing my hosts file from:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;127.0.1.1 myserver&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;127.0.1.1 myserver myserver.mydomain.com&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;things weren&amp;rsquo;t mailing again. I finally changed my crontab to MAILTO=andrew@localhost instead. But that seems kind of bogus. If you&amp;rsquo;ve got better ideas (/etc/mailname maybe?) let me know.&lt;/p&gt;</description></item><item><title>Making use of GIMP plugins</title><link>https://andrewmemory.acornwall.net/blog/2016-09-01-making-use-of-gimp-plugins/</link><pubDate>Thu, 01 Sep 2016 22:03:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-09-01-making-use-of-gimp-plugins/</guid><description>
&lt;h2 class="relative group"&gt;(or how to draw an arrow with an outline)
&lt;div id="or-how-to-draw-an-arrow-with-an-outline" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#or-how-to-draw-an-arrow-with-an-outline" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;As part of a project that I&amp;rsquo;m working on, I found myself drawing lots of red arrows with yellow outlines. To do this I was using the GIMP image editor.&lt;/p&gt;
&lt;p&gt;This was tedious. I would draw a yellow arrow for the outline, then draw a red arrow slightly smaller, then merge down so I had one layer. I started wondering about scripting it.&lt;/p&gt;
&lt;p&gt;First I started by just calling the FU_arrow.scm script with my values. It wasn&amp;rsquo;t hard to write a script that did that. In my case, I did:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;    (FU-arrow image drawable
            80.0
            25
            TRUE
            75
            500 ; brush thickness
            FALSE ; use forst point as head
            FALSE ; delete path after arrow was drawn
            TRUE ; use new layer for arrow
            FALSE ; draw double headed arrow
            FALSE ; useless
            )&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;In other words, my plugin just called the FU-arrow plugin. Next I added a little bit of code around that:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;    (gimp-image-undo-group-start image)
    (gimp-context-push)
(gimp-palette-set-foreground &amp;#39;(255 255 0)) ; yellow
(FU_arrow image drawable 80.0 ...) ; draw outer (bottom) layer
(gimp-palette-set-foreground &amp;#39;(255 0 0)) ; red
(FU_arrow image drawable 80.0 ...) ; draw inner (top) layer
(gimp-context-pop)
(gimp-image-undo-group-end image)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This saved the state and set the foreground colours appropriately so I didn&amp;rsquo;t have to, and also made it easy to undo in a single action.&lt;/p&gt;
&lt;p&gt;You can see that I called FU_arrow twice. Next I needed to merge them down. For that, I used the facility in the arrow plugin that lets you create the arrow as a new layer. New layers are added at the top of the layer stack, so it&amp;rsquo;s fairly easy to grab that and work with it. The interesting code is:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;    (set! current-layers (cadr (gimp-image-get-layers image)))
    (set! arrow-foreground-layer
      (vector-ref current-layers 0))&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Once I have a handle on the foreground layer, I can use gimp-image-merge-down with CLIP-TO-BOTTOM-LAYER to merge the two layers:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;(gimp-image-merge-down image arrow-foreground-layer CLIP-TO-BOTTOM-LAYER)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Because I know nobody else created a layer between the two layers I created, it&amp;rsquo;s easy to get a handle on the new layers the FU-arrow plugin made.&lt;/p&gt;
&lt;p&gt;On Gimp 2.10, I noticed that the thickness of my arrow was tracking the thickness of the currently-selected paintbrush. To fix that, I chose the brush width explicitly using:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;(gimp-context-set-brush-size 30)
(gimp-context-set-brush-hardness 1.00)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;for the outer brush, and 20 for the inner brush.&lt;/p&gt;
&lt;p&gt;My total plugin is:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;(define
(script-fu-quick-arrow image drawable)
(let *
(
(arrow-background-layer -1)
(arrow-foreground-layer -1)
(current-layers -1)
)
(gimp-image-undo-group-start image)
(gimp-context-push)
(gimp-context-set-brush-size 30)
(gimp-context-set-brush-hardness 1.00)
(gimp-palette-set-foreground &amp;#39;(255 255 0))
(FU-arrow image drawable
80.0
25
TRUE
75
500 ; brush thickness
FALSE ; use forst point as head
FALSE ; delete path after arrow was drawn
TRUE ; use new layer for arrow
FALSE ; draw double headed arrow
FALSE ; useless
)
(set! current-layers (cadr (gimp-image-get-layers image)))
(set! arrow-background-layer
(vector-ref current-layers 0))
(gimp-context-set-brush-size 20)
(gimp-palette-set-foreground &amp;#39;(255 0 0))
(FU-arrow image drawable
80.0
25
TRUE
75
1 ; brush thickness
FALSE ; use first path as head
TRUE ; delete path after arrow was drawn
TRUE ; use new layer for arrow
FALSE ; draw double headed arrow
FALSE ; useless
) ;script-fu-draw-arrow function call
(set! current-layers (cadr (gimp-image-get-layers image)))
(set! arrow-foreground-layer
(vector-ref current-layers 0))
(if (= -1 arrow-foreground-layer) (gimp-message &amp;#34;Foreground is -1&amp;#34;))
(if (= -1 arrow-background-layer) (gimp-message &amp;#34;Background is -1&amp;#34;))
(gimp-image-merge-down image arrow-foreground-layer
CLIP-TO-BOTTOM-LAYER )
(gimp-context-pop)
(gimp-image-undo-group-end image)
) ; let
) ;define
; Register with GIMP:
(script-fu-register &amp;#34;script-fu-quick-arrow&amp;#34;
_&amp;#34;Quick Arrow&amp;#34;
_&amp;#34;Draw a nearly arbitrary arrow in your image in red with a yellow outline. Arrow will be created in a separate layer. Needs FU_arrow.scm&amp;#34;
&amp;#34;Andrew&amp;#34;
&amp;#34;2016, Andrew&amp;#34;
&amp;#34;2016-09-01&amp;#34;
&amp;#34;*&amp;#34;
SF-IMAGE &amp;#34;The image&amp;#34; 0
SF-DRAWABLE &amp;#34;The drawable&amp;#34; 0
)
(script-fu-menu-register &amp;#34;script-fu-quick-arrow&amp;#34; &amp;#34;/Script-Fu/&amp;#34;)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Quick edit: to install the script, copy it to the scripts directory. You can find that with Edit -&amp;gt; Preferences -&amp;gt; Folders -&amp;gt; Scripts (I used the user folder rather than the system folder). Then Filters -&amp;gt; Script-Fu -&amp;gt; Refresh Scripts. Et voilà!&lt;/p&gt;</description></item><item><title>Building Signalink Cables</title><link>https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/</link><pubDate>Sun, 12 Jun 2016 23:58:18 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/</guid><description>&lt;p&gt;Many of us have sound card interfaces for our radios that use the standard RJ-45 plug on one end and a custom connector for the radio on the other. If you&amp;rsquo;ve got more than one radio, it&amp;rsquo;s sometimes possible to buy additional interface cables. That can get pricey, though – and depending on the connector on your radio, an interface cable might no longer be available.&lt;/p&gt;
&lt;p&gt;For many rigs it&amp;rsquo;s possible to buy a connector that ends in bare wire fairly cheaply. I hit eBay and found a cheapie Kenwood connector for $2.49 (&amp;ldquo;4 Wire Speaker Mic Cable for Baofeng UV5R Kenwood TK-240&amp;rdquo;).&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Kenwood style connector with bare ends"
width="2552"
height="1836"
src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300045_cable_alone_hu_6c8c4f61fc5c9bff.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300045_cable_alone_hu_6c8c4f61fc5c9bff.jpg 800w, https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300045_cable_alone_hu_fb536cf533473c3a.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300045_cable_alone.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;While holding one of these in my hand, I noticed that the individual wires in the radio cable were roughly the same diameter as the wires in cat-5 network cable.&lt;/p&gt;
&lt;p&gt;Before doing anything else I wrote down which wires connected to which pins on the radio. All of the wires in my cable had different colors, which made identification a lot easier. Next, I determined which pin in the RJ-45 plug should be connected to which wire. This varies depending on the radio connector and sound card interface you use. In my case, green went to the 2.5mm plug tip aka speaker, red went to the 3.5mm ring aka mic, black went to the 3.5mm sleeve aka PTT, and white went to the 2.5mm sleeve aka ground. I found &lt;a href="http://www.tigertronics.com/sl_wireht_sep.htm" target="_blank" rel="noreferrer"&gt;this Tigertronics page&lt;/a&gt; useful.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Close-up of connector and wire"
width="948"
height="616"
src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300049_wires_apart_hu_bf8fc9ccd58b5d53.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300049_wires_apart_hu_bf8fc9ccd58b5d53.jpg 800w, https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300049_wires_apart.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300049_wires_apart.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;After that, I cut the interface cable straight across with diagonal cutters. My cable came with an integrated strain relief, and I cut that off as well. Then I carefully removed a little more than half an inch (about 13mm) of the cable jacket, being careful not to nick the wires inside.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Cable together but before crimping"
width="1668"
height="1440"
src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300051_pre-crimp_hu_540bcb9f72e35be7.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300051_pre-crimp_hu_540bcb9f72e35be7.jpg 800w, https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300051_pre-crimp_hu_5a6a34d0d983265d.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/p4300051_pre-crimp.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;I arranged the wires in the correct order they&amp;rsquo;d need to be into the RJ-45 plug. The wires were solid core, so I was able to spread them more or less into position. Next I inserted the cable into the RJ-45 plug, being careful to slip each wire into the appropriate channel. One or two recalcitrant wires needed persuasion with a pin to find the right home.&lt;/p&gt;
&lt;p&gt;Once all the wires were in their channels, I pushed hard on the cable to ensure all the wires were as far forward in the plug as they would go. At this point I crimped the RJ-45 plug. There are two nice things about an RJ-45 crimp: there&amp;rsquo;s no need to strip the wires (the plug bites down on them to make the connection), and the crimp forces part of the plug&amp;rsquo;s shell against the cable, which keeps it in place.&lt;/p&gt;
&lt;p&gt;Then came the moment of truth: I tested continuity of each pin on the connector. Success!&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Completed cable"
width="1038"
height="752"
src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/complete_hu_3b0ec02f062ed2b2.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/complete_hu_3b0ec02f062ed2b2.jpg 800w, https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/complete.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2016-06-12-building-signalink-cables/images/complete.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;The radio&amp;rsquo;s connectors were in the right place, and I had a professional-looking interface cable for a radio that needed it.&lt;/p&gt;</description></item><item><title>Mounting a Pi with Wheezy read-only</title><link>https://andrewmemory.acornwall.net/blog/2016-04-06-mounting-a-pi-with-wheezy-read-only/</link><pubDate>Wed, 06 Apr 2016 23:08:22 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-04-06-mounting-a-pi-with-wheezy-read-only/</guid><description>&lt;p&gt;A while back, I had a need to make a Raspberry Pi have a read-only filesystem. I used the instructions at: &lt;a href="https://github.com/tvdzwan/hyperion/wiki/Make-Raspbian-Read-Only" target="_blank" rel="noreferrer"&gt;github.com/tvdzwan/hyperion/wiki/Make-Raspbian-Read-Only&lt;/a&gt; to do so.&lt;/p&gt;
&lt;p&gt;Just in case that goes away or changes, here&amp;rsquo;s what I did:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;dphys-swapfile swapoff
dphys-swapfile uninstall
update-rc.d dphys-swapfile disable
aptitude install unionfs-fuse&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then create an executable script as follows in /usr/local/bin/mount_unionfs:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#!/bin/sh
DIR=$1
ROOT_MOUNT=$(awk &amp;#39;$2==&amp;#34;/&amp;#34; {print substr($4,1,2)}&amp;#39; &amp;lt; /etc/fstab)
if [ $ROOT_MOUNT = &amp;#34;rw&amp;#34; ]
then
/bin/mount --bind ${DIR}_org ${DIR}
else
/bin/mount -t tmpfs ramdisk ${DIR}_rw
/usr/bin/unionfs-fuse -o cow,allow_other,suid,dev,nonempty ${DIR}_rw=RW:${DIR}_org=RO ${DIR}
fi&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, make / read-only and mount /etc and /var as ramdisk in /etc/fstab:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/dev/mmcblk0p1 /boot vfat ro 0 2
/dev/mmcblk0p2 / ext4 ro,noatime 0 1
mount_unionfs /etc fuse defaults 0 0
mount_unionfs /var fuse defaults 0 0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, make the magic directories:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;cp -al /etc /etc_org
mv /var /var_org
mkdir /etc_rw
mkdir /var /var_rw
reboot&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Recently, I had to add a user to a group. To do that, I used:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;umount /etc
mount -o remount,rw /&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to make /etc/ writable again.&lt;/p&gt;</description></item><item><title>Turning a Raspberry Pi 2 into a packet station</title><link>https://andrewmemory.acornwall.net/blog/2016-03-31-turning-a-raspberry-pi-2-into-a-packet-station/</link><pubDate>Thu, 31 Mar 2016 23:25:27 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-03-31-turning-a-raspberry-pi-2-into-a-packet-station/</guid><description>&lt;p&gt;I keep thinking it&amp;rsquo;s a good idea for emergency communications to have a packet station. Since I&amp;rsquo;m cheap, I didn&amp;rsquo;t want to get extra hardware - instead I wanted to use what I had. Luckily, Dire Wolf is better than any hardware packet decoder out there. Here&amp;rsquo;s how I got a working packet station on a Pi 2 running Raspbian Jessie Lite.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Connect the radio to the Pi. In my case, I had a spare Signalink SL1+ hanging around which made things easier. I  bought a &lt;a href="http://www.amazon.com/external-Adapter-Windows-Microphone-SD-CM-UAUD/dp/B001MSS6CS" target="_blank" rel="noreferrer"&gt;Syba CMedia USB sound card&lt;/a&gt; to talk from the Pi to the Signalink, and a &lt;a href="http://www.ebay.com/itm/371536438103" target="_blank" rel="noreferrer"&gt;Kenwood speaker mic cable&lt;/a&gt; to talk from the Signalink to the radio. Here&amp;rsquo;s a useful hint: the diameter of the wires in the speaker mic cable are roughly the same as the diameter of the wires in regular Ethernet cable - meaning that you can (if you&amp;rsquo;re careful) strip the outer jacket, put the inner wires in the right places of an RJ-45 connector and crimp direct to them with no soldering at all.&lt;/li&gt;
&lt;li&gt;Download and build Dire Wolf. Instructions for doing so on a Pi are &lt;a href="https://github.com/wb2osz/direwolf/blob/master/doc/Raspberry-Pi-APRS.pdf" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;. I mounted my home directory on a networked drive to make life easier.&lt;/li&gt;
&lt;li&gt;Configure Dire Wolf with your callsign (I used the SSID -15 after my call) and sound card. Be sure to avoid the &amp;ldquo;# ADEVICE - plughw:1,0&amp;rdquo; line - it looks a lot like the correct &amp;ldquo;ADEVICE  plughw:1,0&amp;rdquo; line, but takes input from stdin instead of the sound card.&lt;/li&gt;
&lt;li&gt;Run &amp;ldquo;direwolf&amp;rdquo; and tune the radio to 144.390 (APRS). Make sure you&amp;rsquo;re decoding packets. You might have to go to alsamixer and adjust input/output. Mine ended up being 51 for speaker, 29 and 12 for mic. Also adjust the radio volume so it&amp;rsquo;s not too high or too low. (Hit F6 to get your sound card, then F5 to see all devices. I&amp;rsquo;m not sure which mic I was using; I had two - a stereo and a mono one. The mono one was 29, the stereo one was 12.) It&amp;rsquo;s probably a good idea to turn off the squelch on the radio as well.&lt;/li&gt;
&lt;li&gt;sudo apt-get install ax25-tools ax25-apps&lt;/li&gt;
&lt;li&gt;Edit /etc/ax25/axports and set one line to: vhf   &lt;em&gt;mycall&lt;/em&gt;-15 1200 255 2 VHF link (1200 bps)&lt;/li&gt;
&lt;li&gt;Make sure all the other lines in axports have # in front of them (it doesn&amp;rsquo;t like blank lines).&lt;/li&gt;
&lt;li&gt;Run &amp;ldquo;direwolf -p&amp;rdquo; to get the KISS port. It will show up as something like /dev/pts/2. Once it&amp;rsquo;s running, move to another terminal window.&lt;/li&gt;
&lt;li&gt;Change frequency to the freq that you&amp;rsquo;re going to use.&lt;/li&gt;
&lt;li&gt;sudo /usr/sbin/kissattach /dev/pts/2 vhf &lt;em&gt;(your IP address in AMPR 44.0.0.0)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;sudo /usr/sbin/kissparms -p vhf -t 200 -s 20 -r 64 -l 50 -f n These parameters took a little tweaking. If the transmit delay (-t) was too big, things timed out. If it was too small, things stepped on each other. I had to adjust transmit tail delay as well (-l). I found &lt;a href="http://www.choisser.com/packet/part14.html" target="_blank" rel="noreferrer"&gt;this page&lt;/a&gt; useful for some values.&lt;/li&gt;
&lt;li&gt;sudo route del -net 44.0.0.0 netmask 255.0.0.0 (because I&amp;rsquo;d set up a route beforehand and needed to nuke it)&lt;/li&gt;
&lt;li&gt;sudo /sbin/route add -net 44.0.0.0 netmask 255.0.0.0 dev ax0&lt;/li&gt;
&lt;li&gt;ping -i 10 &lt;em&gt;(someone else&amp;rsquo;s IP who also has a machine on the AMPR 44.0.0.0 net)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Assuming that works, you might want to apt-get install telnet telnetd talk talkd and try to log into your friend&amp;rsquo;s machine or have your friend log into yours.&lt;/li&gt;
&lt;li&gt;Last but not least: I ran into problems with arp. I increased the arp timeout in /etc/sysctl.d/local.conf:&lt;code&gt;net.ipv4.neigh.default.base_reachable_time_ms=1200000&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Turning a Raspberry Pi 3 into an iBeacon</title><link>https://andrewmemory.acornwall.net/blog/2016-03-29-turning-a-raspberry-pi-3-into-an-ibeacon/</link><pubDate>Tue, 29 Mar 2016 23:31:23 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-03-29-turning-a-raspberry-pi-3-into-an-ibeacon/</guid><description>&lt;p&gt;Wow, that was easy. Straight out of the box, you can turn your Raspberry Pi 3 into an iBeacon. All you need is Raspbian Jessie - it&amp;rsquo;s got hcitool installed.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to do it. First, decide on your iBeacon UUID and major/minor. For instance, I picked at random:&lt;/p&gt;
&lt;p&gt;UUID: c9407f30-f5f8-466e-aff9-25556b57fe6d Major: 179 Minor: 3&lt;/p&gt;
&lt;p&gt;Next, convert the UUID to 16 byte big-endian hex, and convert major/minor to 4 byte big-endian hex:&lt;/p&gt;
&lt;p&gt;UUID: C9 40 7F 30 F5 F8 46 6E AF F9 25 55 6B 57 FE 6D Major: 00 B3 Minor: 00 03&lt;/p&gt;
&lt;p&gt;Plug those numbers into the magic command:&lt;/p&gt;
&lt;p&gt;sudo hcitool cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 &lt;em&gt;UUID&lt;/em&gt; &lt;em&gt;Major&lt;/em&gt; &lt;em&gt;Minor&lt;/em&gt; C8&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;sudo hcitool cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 C9 40 7F 30 F5 F8 46 6E AF F9 25 55 6B 57 FE 6D 00 B3 00 03 C8&lt;/p&gt;
&lt;p&gt;Finally, turn advertising on with:&lt;/p&gt;
&lt;p&gt;sudo hcitool cmd 0x08 0x000A 01&lt;/p&gt;
&lt;p&gt;or turn it off with&lt;/p&gt;
&lt;p&gt;sudo hcitool cmd 0x08 0x000A 00&lt;/p&gt;
&lt;p&gt;That was too easy!&lt;/p&gt;
&lt;p&gt;Incidentally, the 4C 00 is the magic bit that says it&amp;rsquo;s an Apple product, 02 means iBeacon, 15 is the (hex) length of the remaining data. The trailing C8 is the two&amp;rsquo;s complement of the transmit power at 1m, so c8 is -56. More details can be found at: &lt;a href="https://stackoverflow.com/questions/18906988/what-is-the-ibeacon-bluetooth-profile" target="_blank" rel="noreferrer"&gt;https://stackoverflow.com/questions/18906988/what-is-the-ibeacon-bluetooth-profile&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Increasing Netbook Screen Size</title><link>https://andrewmemory.acornwall.net/blog/2016-03-21-increasing-netbook-screen-size/</link><pubDate>Mon, 21 Mar 2016 22:32:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-03-21-increasing-netbook-screen-size/</guid><description>&lt;p&gt;I&amp;rsquo;ve got an old Acer Aspire One 521 netbook that I&amp;rsquo;ve had for ages. One of the downsides of netbooks is that their screen resolution is 1024x600 - which is too low for a lot of programs. In particular, all the interesting buttons of the MFJ-226 control program &amp;ldquo;T-Series Vector Impedance Analyzer&amp;rdquo; are below the bottom of the screen.&lt;/p&gt;
&lt;p&gt;I found a workaround that appears to work on Windows 7 and higher. I found it here: &lt;a href="http://www.tlbhd.com/how-to-get-better-resolution-on-your-standard-10-inch-netbook-2772/" target="_blank" rel="noreferrer"&gt;http://www.tlbhd.com/how-to-get-better-resolution-on-your-standard-10-inch-netbook-2772/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The solution: use regedit to search for all instances of &amp;ldquo;Display1_DownScalingSupported&amp;rdquo; and change the value 0 to 1. (According to various things I&amp;rsquo;ve read, you&amp;rsquo;ll need to do that for all instances, not just one.) Then reboot. When I did this, I ended up in 1024x768 (which looks strange).&lt;/p&gt;
&lt;p&gt;Strange isn&amp;rsquo;t bad, though. Now I can change resolutions to 1024x768 or 1152x864 if an inconsiderate programmer decides he wants to use more than my screen.&lt;/p&gt;</description></item><item><title>Controlling T-Series Vector Impedance Analyzer from a netbook</title><link>https://andrewmemory.acornwall.net/blog/2016-03-21-controlling-t-series-vector-impedance-analyzer-from-a-netbook/</link><pubDate>Mon, 21 Mar 2016 22:22:58 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-03-21-controlling-t-series-vector-impedance-analyzer-from-a-netbook/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using the T-Series Vector Impedance Analyzer program from Times Technology Company to control my dad&amp;rsquo;s MFJ-226 antenna analyzer (aka Times Technology T200). Both he and I ran into problems with it on a netbook with a screen size of 1024x600. Most of the &amp;ldquo;interesting&amp;rdquo; buttons were off screen!&lt;/p&gt;
&lt;p&gt;The right solution for Windows 7 and higher appears to be to allow scaling of the netbook&amp;rsquo;s screen. That&amp;rsquo;s documented &lt;a href="https://andrewmemory.acornwall.net/blog/2016-03-21-increasing-netbook-screen-size/" &gt;here&lt;/a&gt;. But for those unfortunates who are stuck on Windows XP or for some other reason can&amp;rsquo;t increase the screen size, here&amp;rsquo;s what I ended up doing.&lt;/p&gt;
&lt;p&gt;To start/stop the connection to the analyzer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click the &amp;ldquo;SWR&amp;rdquo; button&lt;/li&gt;
&lt;li&gt;Press \[Tab\] \[Tab\] \[Cursor back &lt;-\] \[Space\]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To load a file from the analyzer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click the &amp;ldquo;Save to File&amp;rdquo; button&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;Cancel&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Press \[Tab\] \[Tab\] \[Tab\] - you are now on the file to load&lt;/li&gt;
&lt;li&gt;Press \[Backspace\] \[Backspace\] \[Backspace\] \[Del\] \[Del\] \[Del\]&lt;/li&gt;
&lt;li&gt;Enter the file you want to load from the analyzer (1, 3, 12, etc.)&lt;/li&gt;
&lt;li&gt;Press \[Shift-Tab\]&lt;/li&gt;
&lt;li&gt;Press \[Enter\]&lt;/li&gt;
&lt;li&gt;Now you can click the &amp;ldquo;Save to file&amp;rdquo; button and save the data.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Setting up Raspian Jessie on a Pi</title><link>https://andrewmemory.acornwall.net/blog/2016-03-15-setting-up-raspian-jessie-on-a-pi/</link><pubDate>Tue, 15 Mar 2016 21:29:27 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2016-03-15-setting-up-raspian-jessie-on-a-pi/</guid><description>&lt;p&gt;There are a few changes to setting up Raspian Jessie on a Pi. Here&amp;rsquo;s what I do:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Burn the image
&lt;div id="burn-the-image" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#burn-the-image" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Get the Raspbian image from the &lt;a href="http://www.raspberrypi.org/downloads/" target="_blank" rel="noreferrer"&gt;Raspberry Pi downloads page&lt;/a&gt;. I&amp;rsquo;ve been using Jessie Lite, since I don&amp;rsquo;t need the full package.&lt;/li&gt;
&lt;li&gt;Unzip it on a Linux box (mine saw the SD card as /dev/sdb, use your SD card device and don&amp;rsquo;t wipe your hard drive)&lt;/li&gt;
&lt;li&gt;Pop the card out of the Linux box and into the Pi&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The command to write that I used:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo dd if=2015-01-31-raspbian.img of=/dev/sdb bs=4M&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Configure the Pi
&lt;div id="configure-the-pi" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configure-the-pi" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;When the Pi boots into raspi-config, do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Expand Filesystem&lt;/li&gt;
&lt;li&gt;Change User Password&lt;/li&gt;
&lt;li&gt;Internationalisation Options / Change Locale, pick en_US UTF-8&lt;/li&gt;
&lt;li&gt;Internationalisation Options / Change timezones, pick yours&lt;/li&gt;
&lt;li&gt;Internationalisation Options / Change Keyboard Layout, pick US PC 104, accept defaults&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Set up the network
&lt;div id="set-up-the-network" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#set-up-the-network" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I have my Pi configured with a static IP. The first time I boot I attach a network cable.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Edit /etc/dhcpcd.conf (&lt;strong&gt;not&lt;/strong&gt; /etc/network/interfaces) so the wired interface is static&lt;/li&gt;
&lt;li&gt;My /etc/resolv.conf was configured automatically by dhcp and was mostly right (missing domain and search, but I guess I can live with that)&lt;/li&gt;
&lt;li&gt;Now would be a good time to edit /etc/hostname as well&lt;/li&gt;
&lt;li&gt;Edit /etc/hosts to use the new hostname and hostname.domainname&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(Thanks to &lt;a href="https://pi-hole.net/faq/how-do-i-set-a-static-ip-address-in-raspbian-jessie-using-etcdhcpcd-conf/" target="_blank" rel="noreferrer"&gt;https://pi-hole.net/faq/how-do-i-set-a-static-ip-address-in-raspbian-jessie-using-etcdhcpcd-conf/&lt;/a&gt; for the revised instructions for a static IP.)&lt;/p&gt;
&lt;p&gt;I added the following to the end of my /etc/dhcpcd.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Configure eth0 to be static
interface eth0
static ip_address=192.168.17.5
static routers=192.168.17.1
static domain_name_servers=192.168.17.1
static domain_name=mydomain.foo&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Install an editor
&lt;div id="install-an-editor" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#install-an-editor" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I can do a few things like adding users while updates are happening. So:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude update
sudo aptitude install zile&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Update the OS
&lt;div id="update-the-os" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#update-the-os" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;This takes a while, but you can continue on while this is happening.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo apt-get install rpi-update
sudo aptitude dist-upgrade&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Add my user
&lt;div id="add-my-user" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#add-my-user" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t like to use the default user, so I add my own.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;sudo addgroup &amp;ndash;gid 3009 myshare&lt;/li&gt;
&lt;li&gt;sudo adduser &amp;ndash;uid 3000 myuser&lt;/li&gt;
&lt;li&gt;sudo usermod -a &amp;ndash;groups adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio,myshare myuser log out, log in - make sure I can sudo with the new user&lt;/li&gt;
&lt;li&gt;prevent login as pi&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To prevent the pi login, I do:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo vipw -s&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and replace the password for pi with *.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Update everything else
&lt;div id="update-everything-else" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#update-everything-else" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Once the dist-upgrade has completed and it&amp;rsquo;s time to reboot:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo /sbin/shutdown -r now&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now you can log in again and upgrade the firmware:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo rpi-update
sudo /sbin/shutdown -r now&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Get things I know I&amp;rsquo;ll need
&lt;div id="get-things-i-know-ill-need" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#get-things-i-know-ill-need" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I like to have an emacs clone:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;zile ~/.bash_aliases
alias emacs=&amp;#39;zile&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I also like tightvncserver on non-Lite images:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude install tightvncserver
tightvncserver
(set password)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, make emacs the default editor by appending this to ~/.bashrc:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;export EDITOR=/usr/bin/zile&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Mounting a CIFS drive
&lt;div id="mounting-a-cifs-drive" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#mounting-a-cifs-drive" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t like to do more writing than I have to, so:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo mkdir /etc/samba/credentials
sudo chmod 700 /etc/samba/credentials
sudo chown root.root /etc/samba/credentials
sudo mkdir /shared
sudo zile /etc/fstab
sudo zile /etc/samba/credentials/myserver&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;In /etc/fstab, I add:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;//myserver/shared /shared cifs credentials=/etc/samba/credentials/myserver 0 0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;While in /etc/fstab, I change the following to reduce wear on the SD card:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;/dev/mmcblk0p1 /boot vfat noatime 0 0
/dev/mmcblk0p2 / ext4 defaults,noatime 0 2&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;{Edit} I used to have ro,noatime on /boot but the Pi gets really unhappy when you try to upgrade the OS if /boot isn&amp;rsquo;t writable. So out it came.&lt;/p&gt;
&lt;p&gt;In /etc/samba/credentials/myserver, I add:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;username=myuser
password=mypass&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;rss-feed&amp;rdquo;
That&amp;rsquo;s about it.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Formatting an SD card as exfat</title><link>https://andrewmemory.acornwall.net/blog/2015-12-17-formatting-an-sd-card-as-exfat/</link><pubDate>Thu, 17 Dec 2015 22:32:07 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-12-17-formatting-an-sd-card-as-exfat/</guid><description>&lt;p&gt;On Android, by default SD cards with 64M or more on them are formatted as exfat, while smaller cards are formatted as fat32. But what if you want to force an SD card to be exfat? Here&amp;rsquo;s how to do it. You&amp;rsquo;ll need a Linux box.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;sudo apt-get install fuse-exfat exfat-utils&lt;/li&gt;
&lt;li&gt;Partition the card if it&amp;rsquo;s not already partitioned&lt;/li&gt;
&lt;li&gt;sudo mkfs -texfat /dev/sdf1&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Mostly this post is to remind me that the new format is called exfat, since I keep forgetting that.&lt;/p&gt;</description></item><item><title>Rescuing a hard drive with ddrescue</title><link>https://andrewmemory.acornwall.net/blog/2015-11-05-rescuing-a-hard-drive-with-ddrescue/</link><pubDate>Thu, 05 Nov 2015 23:13:45 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-11-05-rescuing-a-hard-drive-with-ddrescue/</guid><description>&lt;p&gt;A while ago, one of my Windows hard drives gave up the ghost. Unfortunately, the last backup I&amp;rsquo;d done on it was a while ago. Lesson #1: Don&amp;rsquo;t forget to back things up.&lt;/p&gt;
&lt;p&gt;The hard drive had been staring at me on my desk for a while, so I decided to see what I could do about it. My searches led me to CGSecurity and two pages on their website: &lt;a href="http://www.cgsecurity.org/wiki/TestDisk" target="_blank" rel="noreferrer"&gt;TestDisk&lt;/a&gt; and the &lt;a href="http://www.cgsecurity.org/wiki/Damaged_Hard_Disk" target="_blank" rel="noreferrer"&gt;Damaged Hard Disk&lt;/a&gt; page. They in turn led me to &lt;a href="https://www.gnu.org/software/ddrescue/" target="_blank" rel="noreferrer"&gt;ddrescue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I&amp;rsquo;ve done so far:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Have a nice server that has a motherboard advanced enough to hot-mount SATA drives. This is very useful if the disk disappears now and then and needs to be remounted.&lt;/li&gt;
&lt;li&gt;Mount the drive in a spare slot in the server.&lt;/li&gt;
&lt;li&gt;sudo apt-get install lzip because ddrescue is stored in lzip archives&lt;/li&gt;
&lt;li&gt;Grab the latest stable build from the &lt;a href="http://ftpmirror.gnu.org/ddrescue/" target="_blank" rel="noreferrer"&gt;ddrescue download directory&lt;/a&gt;. (I used version 1.20.)&lt;/li&gt;
&lt;li&gt;lzip -d then extract the ddrescue tar file.&lt;/li&gt;
&lt;li&gt;cd into the ddrescue directory and configure; make&lt;/li&gt;
&lt;li&gt;Next I tried plain ddrescue: sudo ./ddrescue -n /dev/sde /data/sde_rescue sde_map&lt;/li&gt;
&lt;li&gt;That seemed to be having trouble, so I reversed direction: sudo ./ddrescue -n -R /dev/sde /data/sde_rescue sde_map&lt;/li&gt;
&lt;li&gt;That whirred for a few days. Next I decided to try mounting as a raw device, on the theory that the kernel cache might be obscuring things.&lt;/li&gt;
&lt;li&gt;sudo /sbin/modprobe raw&lt;/li&gt;
&lt;li&gt;sudo raw /dev/raw/raw1 /dev/sde&lt;/li&gt;
&lt;li&gt;sudo ./ddrescue -n -R /dev/raw/raw1 /data/sde_rescue sde_map&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So far I&amp;rsquo;ve theoretically recovered 130M of my 500M disk. When reading the raw device, I don&amp;rsquo;t get an estimate of time remaining (which was about a year). It will be interesting to see if this actually gets recovered, or if I&amp;rsquo;m just grabbing random numbers at this point.&lt;/p&gt;</description></item><item><title>Unlocking a Windows 8.1 machine with MSN password</title><link>https://andrewmemory.acornwall.net/blog/2015-09-20-unlocking-a-windows-8-1-machine-with-msn-password/</link><pubDate>Sun, 20 Sep 2015 15:39:31 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-09-20-unlocking-a-windows-8-1-machine-with-msn-password/</guid><description>&lt;p&gt;Recently, I inherited a laptop that came with Windows 8.1 installed. The previous owner had forgotten the login password, and no longer had the phones/accounts that were associated with the machine either. (If you have the choice, I&amp;rsquo;d recommend you avoid Alzheimer&amp;rsquo;s disease. It sucks.) I wanted to get the user information off before wiping it and reinstalling. Unfortunately, this machine had a Windows Live / MSN password, rather than a local password.&lt;/p&gt;
&lt;p&gt;I started with &lt;a href="http://pcsupport.about.com/od/windows-8/a/reset-password-windows-8.htm" target="_blank" rel="noreferrer"&gt;these instructions&lt;/a&gt;. They take advantage of an exploit to enable a command shell from the login screen. In short:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go into Advanced Startup Options and Troubleshoot -&amp;gt; Advanced Options -&amp;gt; Command Prompt&lt;/li&gt;
&lt;li&gt;copy c:\windows\system32\utilman.exe c:\&lt;/li&gt;
&lt;li&gt;copy c:\windows\system32\cmd.exe c:\windows\system32\utilman.exe&lt;/li&gt;
&lt;li&gt;Reboot&lt;/li&gt;
&lt;li&gt;Click the &amp;ldquo;Ease of Access&amp;rdquo; icon at the bottom left of the login screen. Now this will open a command shell.&lt;/li&gt;
&lt;li&gt;If the user had a local account, you&amp;rsquo;d be home free now. (net user &amp;ldquo;username&amp;rdquo; new-password and then copy the original utilman.exe back). But I wasn&amp;rsquo;t - instead I saw &amp;ldquo;System error 8646 : The system is not authoritative for the specified account&amp;rdquo;. That was because the machine had a MSN login / Microsoft Live password. So instead&amp;hellip;&lt;/li&gt;
&lt;li&gt;net user brandnewuser secretpassword&lt;/li&gt;
&lt;li&gt;Reboot again (probably not necessary, but I did this)&lt;/li&gt;
&lt;li&gt;Get back into the &amp;ldquo;Ease of Access&amp;rdquo; shell&lt;/li&gt;
&lt;li&gt;net localgroup Administrators brandnewuser /add&lt;/li&gt;
&lt;li&gt;Reboot&lt;/li&gt;
&lt;li&gt;Log in as brandnewuser rather than the original user.&lt;/li&gt;
&lt;li&gt;Wait a really really long time (10 minutes or so) for Windows to rebuild the desktop for the new user.&lt;/li&gt;
&lt;li&gt;At this point, you can navigate to C:\Users and copy the files from the original user to somewhere else. You will probably have to run the Explorer as Adminstrator in order to do this. I recall being prompted with &amp;ldquo;You don&amp;rsquo;t have access to this directory, do you want to get it permanently&amp;rdquo; once or twice. I said &amp;ldquo;Yes&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;And that&amp;rsquo;s it - the pictures can now be copied to CD for preservation (except the ones that were stored in Windows Live, of course). After that you can create restore media and wipe/reinstall.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Changing user and group ID on Unix</title><link>https://andrewmemory.acornwall.net/blog/2015-05-02-changing-user-and-group-id-on-unix/</link><pubDate>Sat, 02 May 2015 21:05:32 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-05-02-changing-user-and-group-id-on-unix/</guid><description>&lt;p&gt;Recently I&amp;rsquo;ve set up a file server for both Windows and Linux. When I went to mount the file system on Linux, things were broken - because I hadn&amp;rsquo;t paid attention to user ID and group ID when I created users on my different Unix machines.&lt;/p&gt;
&lt;p&gt;So I needed to change the UID and GID of a user, then update the files. Luckily, someone had already done the work:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://muffinresearch.co.uk/linux-changing-uids-and-gids-for-user/" target="_blank" rel="noreferrer"&gt;https://muffinresearch.co.uk/linux-changing-uids-and-gids-for-user/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;usermod -u &amp;lt;NEWUID&amp;gt; &amp;lt;LOGIN&amp;gt;    
groupmod -g &amp;lt;NEWGID&amp;gt; &amp;lt;GROUP&amp;gt;
find / -user &amp;lt;OLDUID&amp;gt; -exec chown -h &amp;lt;NEWUID&amp;gt; {} \;
find / -group &amp;lt;OLDGID&amp;gt; -exec chgrp -h &amp;lt;NEWGID&amp;gt; {} \;
usermod -g &amp;lt;NEWGID&amp;gt; &amp;lt;LOGIN&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;One wrinkle that I wasn&amp;rsquo;t expecting: you can&amp;rsquo;t change the user ID of a user who has a running process. So I had to create a second user with adduser, add that user as in /etc/groups for sudo, log in as that user, and then change the user ID of the original user.&lt;/p&gt;
&lt;p&gt;When I ran this on Ubuntu and Raspbian, I saw about 4 errors in /proc which I ignored. There&amp;rsquo;s probably a faster way to do to this using xargs rather than running -exec each time, but I was a little worried I might exceed what I could pass in on a command line (I had hundreds of thousands of files) so I let it do its thing.&lt;/p&gt;</description></item><item><title>Setting up a static IP for a Raspberry Pi over wifi using OpenBSD dhcpd</title><link>https://andrewmemory.acornwall.net/blog/2015-05-01-setting-up-a-static-ip-for-a-raspberry-pi-over-wifi-using-openbsd-dhcpd/</link><pubDate>Fri, 01 May 2015 00:54:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-05-01-setting-up-a-static-ip-for-a-raspberry-pi-over-wifi-using-openbsd-dhcpd/</guid><description>&lt;p&gt;Like the rest of the world, I wanted to have a static IP for a Raspberry Pi that was on a wifi network. Like the rest of the world, I couldn&amp;rsquo;t figure out how to do it after three attempts. At that point, like the rest of the world I gave up and decided to make my DHCP server do the work instead of the Pi.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how I did it:&lt;/p&gt;
&lt;p&gt;1. On the Pi, edit /etc/wpa_supplicant.conf and add:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;network={
    ssid=&amp;#34;My_SSID&amp;#34;
    psk=&amp;#34;My_wifi_password&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;2. Reboot and get an IP address through DHCP.&lt;/p&gt;
&lt;p&gt;3. Confirm that I can see the world with the DHCP address.&lt;/p&gt;
&lt;p&gt;4. ifconfig wlan0 and copy down the hardware Ethernet address for wlan0 (let&amp;rsquo;s pretend it was 00:11:22:33:44:56).&lt;/p&gt;
&lt;p&gt;5. Go to the box running DHCP, and add a stanza inside my shared-network:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;       host myserver {
               hardware ethernet 00:11:22:33:44:56;
               fixed-address 192.168.1.17;
               option host-name &amp;#34;myserver&amp;#34;;
       }&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;6. Kill and restart the DHCP daemon.&lt;/p&gt;
&lt;p&gt;7. Reboot the pi and confirm it&amp;rsquo;s getting the right static IP address now.&lt;/p&gt;</description></item><item><title>Samba - let Windows execute even if execute bit not set</title><link>https://andrewmemory.acornwall.net/blog/2015-04-23-samba-let-windows-execute-even-if-execute-bit-not-set/</link><pubDate>Thu, 23 Apr 2015 23:24:54 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-04-23-samba-let-windows-execute-even-if-execute-bit-not-set/</guid><description>&lt;p&gt;I&amp;rsquo;ve set up Samba once again, and it&amp;rsquo;s still not easy, especially with Cygwin in the mix. I still haven&amp;rsquo;t figured out Cygwin, but I did get the magic phrase that lets Windows machines run exe files without having to set the execute bit.&lt;/p&gt;
&lt;p&gt;This is an option that&amp;rsquo;s not documented in the /etc/samba/smb.conf file, but that&amp;rsquo;s where it goes: &lt;code&gt;# Allow Windows machines to execute things that don't have # the execute bit set acl allow execute always = True&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://forge.univention.org/bugzilla/show_bug.cgi?id=33785" target="_blank" rel="noreferrer"&gt;forge.univention.org/bugzilla/show_bug.cgi?id=33785&lt;/a&gt; for the info!&lt;/p&gt;</description></item><item><title>Setting up a WD Red drive for use in a NAS</title><link>https://andrewmemory.acornwall.net/blog/2015-04-12-setting-up-a-wd-red-drive-for-use-in-a-nas/</link><pubDate>Sun, 12 Apr 2015 13:56:55 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-04-12-setting-up-a-wd-red-drive-for-use-in-a-nas/</guid><description>&lt;p&gt;It&amp;rsquo;s in bits and pieces all over the net, but I haven&amp;rsquo;t seen it all in one place yet. Western Digital Red drives have 4k (4096 byte) sectors rather than the old 512 byte sectors. In order to use them optimally, you need to format them aligned on those sectors.&lt;/p&gt;
&lt;p&gt;The first trick is to use parted rather than fdisk/cfdisk to define the partitions, and parted version 2.2 or higher, as described on this &lt;a href="https://wdc.custhelp.com/app/answers/detail/a_id/5655/~/how-to-install-a-wd-advanced-format-drive-on-a-non-windows-operating-system" target="_blank" rel="noreferrer"&gt;Western Digital support article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, you need to decide what your partition table should look like. For maximum compatibility, use msdos. But if you have drives larger than 2G, you will probably want to use gpt instead.&lt;/p&gt;
&lt;p&gt;Assuming you&amp;rsquo;re using /dev/sdd as your drive:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# parted -a optimal /dev/sdd
(parted) mklabel msdos
(parted) q&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, you will want to add the partition. In my case, I wanted to create an ext4 partition that took up the whole disk. Here&amp;rsquo;s how:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# parted -a optimal /dev/sdd
(parted) mkpart primary ext4 0% 100%
(parted) p
Model: ATA WDC WD20EFRX-68A (scsi)
Disk /dev/sdd: 2000GB
Sector size (logical/physical): 512B/4096B
Partition Table: msdos
Number  Start   End     Size    Type     File system  Flags
 1      1049kB  2000GB  2000GB  primary  ext3
(parted) q&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The -a optimal is the magic bit that tells parted to partition on 4k boundaries for a 4k drive. My ext4 partition actually got created as an ext3 partition, since those are the same partition type.&lt;/p&gt;
&lt;p&gt;Then you need to create a file system on the partition you just created. I add a label afterwards so I can mount it via label in /etc/fstab. (There&amp;rsquo;s a way to add a label in the mkfs command, but I can never remember it, so I do it in two steps.)&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# mkfs -t ext4 /dev/sdd1
# e2label /dev/sdd1 mynewdrive&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then edit /etc/fstab to add the new drive to it:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;LABEL=mynewdrive /newdrivemountpoint ext4 defaults 0 2&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The label matches the label I specified on e2label, and the /newdrivemountpoint is the directory in the Unix file system that I want the drive to be mounted on. The last two numbers say &amp;ldquo;don&amp;rsquo;t dump&amp;rdquo; (0) and &amp;ldquo;do fsck after the root drive&amp;rdquo; (2). See the man page or the &lt;a href="https://help.ubuntu.com/community/Fstab" target="_blank" rel="noreferrer"&gt;Ubuntu fstab page&lt;/a&gt; for more details on that.&lt;/p&gt;</description></item><item><title>Setting up Direwolf/Xastir on a Raspberry Pi</title><link>https://andrewmemory.acornwall.net/blog/2015-03-22-setting-up-direwolfxastir-on-a-raspberry-pi/</link><pubDate>Sun, 22 Mar 2015 19:55:50 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-03-22-setting-up-direwolfxastir-on-a-raspberry-pi/</guid><description>&lt;p&gt;A long time ago I &lt;a href="https://andrewmemory.acornwall.net/tags/soundmodem/" &gt;set up Soundmodem&lt;/a&gt; for Ubuntu. Recently, I tried setting up an igate using WB2OSZ&amp;rsquo;s &lt;a href="https://github.com/wb2osz/direwolf/" target="_blank" rel="noreferrer"&gt;Direwolf&lt;/a&gt; instead. Things are much nicer these days.&lt;/p&gt;
&lt;p&gt;The Direwolf site includes a very nice guide to &lt;a href="https://github.com/wb2osz/direwolf/blob/master/doc/Raspberry-Pi-APRS.pdf" target="_blank" rel="noreferrer"&gt;setting up a Raspberry Pi as an igate&lt;/a&gt;, so I won&amp;rsquo;t go over it here. Instead, this is just to record the steps I took to set up my Raspberry Pi v2 as an igate server.&lt;/p&gt;
&lt;p&gt;1. &lt;a href="https://andrewmemory.acornwall.net/blog/2015-02-26-setting-up-raspbian-on-a-pi/" &gt;Set up the Raspberry Pi to run Raspbian&lt;/a&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Follow along with the setup guide:&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo apt-get remove --purge pulseaudio # I didn&amp;#39;t need to do this since it wasn&amp;#39;t installed, but better safe than sorry
sudo apt-get install libasound2-dev xastir # Note that I&amp;#39;m installing xastir at the same time - this is different from the direwolf guide
cd ~
git clone https://www.github.com/wb2osz/direwolf
cd direwolf
git checkout 1.2
make
sudo make install
make install-rpi
make install-conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, make sure the sound card is plugged into USB (I used the bottom slot). When I plugged it in, the system rebooted, so it&amp;rsquo;s probably smart to shut down before plugging the sound card in. For a sound card, I used the &lt;a href="www.amazon.com/Syba-SD-CM-UAUD-Adapter-C-Media-Chipset/dp/B001MSS6CS" &gt;Syba SD-CM-UAUD USB Stereo Audio Adapter, C-Media Chipset from Amazon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From there, run &lt;code&gt;aplay -l&lt;/code&gt; to see: &lt;code&gt;card 1: Device [C-Media USB Audio Device], device 0: USB Audio [USB Audio]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now I know the device is card 1 device 0. We&amp;rsquo;re almost ready to edit direwolf.conf. First, though - something that wasn&amp;rsquo;t documented on the Direwolf site. Igates need a secret code so they can log into the tier 2 servers. It&amp;rsquo;s based on your callsign, and there&amp;rsquo;s a utility called callpass in Xastir that will compute it for you. &lt;code&gt;callpass {my-real-call}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This gives you a 5 or 6 digit integer that you should remember. I&amp;rsquo;ll call it {my-code}.&lt;/p&gt;
&lt;p&gt;Now edit direwolf.conf:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;uncomment ADEVICE plughw:1,0 - if you got a different number from aplay above, you might have to modify it.&lt;/li&gt;
&lt;li&gt;change MYCALL NOCALL to MYCALL {my-real-call}-10. I used -10 because that&amp;rsquo;s the APRS SSID for igates. (&lt;a href="http://aprs.org/aprs11/SSIDs.txt" target="_blank" rel="noreferrer"&gt;APRS SSIDs are documented here&lt;/a&gt;.) In the direwolf.conf that I got, the NOCALL had a ^J after it; I had to take that out&lt;/li&gt;
&lt;li&gt;uncomment IGSERVER noam.aprs2.net (maybe use a different server if you&amp;rsquo;re not in North America)&lt;/li&gt;
&lt;li&gt;uncomment IGLOGIN and change it to IGLOGIN {my-real-call} {my code}&lt;/li&gt;
&lt;li&gt;direwolf&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Yay, you&amp;rsquo;re igating. But what&amp;rsquo;s around? Set up Xastir for that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;xastir&lt;/li&gt;
&lt;li&gt;In the first menu that comes up, set your callsign to {my-real-call}-10 and (if desired) set your lat/long/position ambiguity&lt;/li&gt;
&lt;li&gt;Interface -&amp;gt; Interface Control, Add, Networked AGWPE, Add. Leave Pass-code blank, save and Start. Now you&amp;rsquo;re getting APRS from over the air displayed on your Xastir maps.&lt;/li&gt;
&lt;li&gt;Not enough for you? Interface -&amp;gt; Interface Control, Add, Internet Server, Add. Set Pass-code to {my-code}, save and Start. Now you&amp;rsquo;re getting APRS from the network as well.&lt;/li&gt;
&lt;li&gt;Want to see it on maps? I wasn&amp;rsquo;t able to get all the maps going, but things worked when I picked Maps -&amp;gt; Map Chooser and selected only Online/osm_tiled_mapnik.geo and worldhi.map.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Adding ATtiny support to Arduino IDE 1.6.1</title><link>https://andrewmemory.acornwall.net/blog/2015-03-22-adding-attiny-support-to-arduino-ide-1-6-1/</link><pubDate>Sun, 22 Mar 2015 19:28:04 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-03-22-adding-attiny-support-to-arduino-ide-1-6-1/</guid><description>&lt;p&gt;I recently upgrade from the 1.0.5 version of the Arduino IDE to 1.6.1. Things aren&amp;rsquo;t completely smooth - in particular, I was using &lt;a href="https://code.google.com/p/arduino-tiny/" target="_blank" rel="noreferrer"&gt;Coding Badly&amp;rsquo;s cores&lt;/a&gt; for ATtiny85, ATtiny84 and ATtiny2313.&lt;/p&gt;
&lt;p&gt;Unfortunately, those haven&amp;rsquo;t yet been updated for the new layout specified in the 1.6.x IDE. So instead I switched for now at least to the &lt;a href="https://github.com/damellis/attiny/" target="_blank" rel="noreferrer"&gt;damellis cores&lt;/a&gt; (which support ATtiny85 and ATtiny84, but not ATtiny2313/4313).&lt;/p&gt;
&lt;p&gt;Installing this is a matter of unzipping it in the sketchbook/hardware folder (on my Windows box in C:\Users\{my user}\Documents\Arduino).&lt;/p&gt;
&lt;p&gt;In Windows cmd shell: &lt;code&gt;cd &amp;quot;C:\Users\{my user}\Documents\Arduino&amp;quot; mkdir hardware unzip c:\{whatever}\attiny-ide-1.6.x.zip cd hardware move ..\attiny-ide-1.6.x\attiny . cd .. rmdir attiny-ide-1.6.x&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;At some point in the future either the Coding Badly cores will support IDE 1.6 (hopefully with the nice variants structure that the damellis cores use) or the damellis cores will do ATtinyX313s.&lt;/p&gt;</description></item><item><title>Setting up Raspbian on a Pi</title><link>https://andrewmemory.acornwall.net/blog/2015-02-26-setting-up-raspbian-on-a-pi/</link><pubDate>Thu, 26 Feb 2015 01:56:39 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2015-02-26-setting-up-raspbian-on-a-pi/</guid><description>&lt;p&gt;These instructions are for Wheezy. &lt;a href="https://andrewmemory.acornwall.net/blog/2016-03-16-setting-up-raspian-jessie-on-a-pi" &gt;You can find updated instructions for Jessie here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been working on setting up a Raspberry Pi to do &lt;a href="http://www.aprs.org/" target="_blank" rel="noreferrer"&gt;APRS&lt;/a&gt; using &lt;a href="https://home.comcast.net/~wb2osz/site/" target="_blank" rel="noreferrer"&gt;Dire Wolf&lt;/a&gt; and &lt;a href="http://xastir.org/" target="_blank" rel="noreferrer"&gt;Xastir&lt;/a&gt;. That actually works fairly well, and I&amp;rsquo;ll write something about it later - this post is because I was using a flaky SD card, which decided to croak at an inopportune moment. Consequently, I had to reinstall Raspian again.&lt;/p&gt;
&lt;p&gt;Since it&amp;rsquo;s easier to write it down than to remember, here&amp;rsquo;s what I did:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Burn the image
&lt;div id="burn-the-image" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#burn-the-image" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Get the Raspbian image from the &lt;a href="http://www.raspberrypi.org/downloads/" target="_blank" rel="noreferrer"&gt;Raspberry Pi downloads page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Unzip it on a Linux box (mine saw the SD card as /dev/sdb, use your SD card device and don&amp;rsquo;t wipe your hard drive)&lt;/li&gt;
&lt;li&gt;Pop the card out of the Linux box and into the Pi&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The command to write that I used:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo dd if=2015-01-31-raspbian.img of=/dev/sdb bs=4M&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Configure the Pi
&lt;div id="configure-the-pi" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#configure-the-pi" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;When the Pi boots into raspi-config, do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Expand Filesystem&lt;/li&gt;
&lt;li&gt;Change User Password&lt;/li&gt;
&lt;li&gt;Internationalisation Options / Change Locale, pick en_US UTF-8&lt;/li&gt;
&lt;li&gt;Internationalisation Options / Change timezones, pick yours&lt;/li&gt;
&lt;li&gt;Internationalisation Options / Change Keyboard Layout, pick US PC 104, accept defaults&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class="relative group"&gt;Set up the network
&lt;div id="set-up-the-network" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#set-up-the-network" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I have my Pi configured with a static IP. The first time I boot I attach a network cable.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Edit /etc/network/interfaces so the wired interface is static&lt;/li&gt;
&lt;li&gt;My /etc/resolv.conf was configured automatically by dhcp and was right&lt;/li&gt;
&lt;li&gt;Now would be a good time to edit /etc/hostname as well&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The iface eth0 stanza in my interfaces file looks like:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;iface eth0 inet static
address 192.168.17.15
netmask 255.255.255.0
gateway 192.168.17.1&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Update the OS
&lt;div id="update-the-os" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#update-the-os" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;This takes a while, but you can continue on while this is happening.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude update
sudo aptitude dist-upgrade&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Add my user
&lt;div id="add-my-user" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#add-my-user" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t like to use the default user, so I add my own.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;sudo adduser myuser&lt;/li&gt;
&lt;li&gt;edit /etc/group to add my user to all the pi groups (including sudo)&lt;/li&gt;
&lt;li&gt;log out, log in - make sure I can sudo with the new user&lt;/li&gt;
&lt;li&gt;prevent login as pi&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To prevent the pi login, I do:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo vipw -s&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and replace the password for pi with *.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Update everything else
&lt;div id="update-everything-else" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#update-everything-else" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Once the dist-upgrade has completed and it&amp;rsquo;s time to reboot:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo /sbin/shutdown -r now&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now you can log in again and upgrade the firmware:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo rpi-update
sudo /sbin/shutdown -r now&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;h2 class="relative group"&gt;Get things I know I&amp;rsquo;ll need
&lt;div id="get-things-i-know-ill-need" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#get-things-i-know-ill-need" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I like to have an emacs clone:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude install zile
zile ~/.bash_aliases
alias emacs=&amp;#39;zile&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I also like tightvncserver:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude install tightvncserver
tightvncserver
(set password)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, make emacs the default editor by appending this to ~/.bashrc:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;export EDITOR=/usr/bin/zile&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That&amp;rsquo;s about it.&lt;/p&gt;</description></item><item><title>Foot Switch for the Insane</title><link>https://andrewmemory.acornwall.net/blog/2014-12-28-foot-switch-for-the-insane/</link><pubDate>Sun, 28 Dec 2014 15:28:28 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-12-28-foot-switch-for-the-insane/</guid><description>&lt;p&gt;I&amp;rsquo;ve been looking for a foot switch for a while now to act as a PTT for a radio. Yesterday at a thrift store, I came across the Koino KH-8012: [&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="SPST Foot switch with NEMA 1-15 plug"
width="500"
height="375"
src="https://andrewmemory.acornwall.net/blog/2014-12-28-foot-switch-for-the-insane/images/pc270226-small1.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2014-12-28-foot-switch-for-the-insane/images/pc270226-small1.jpg 800w, https://andrewmemory.acornwall.net/blog/2014-12-28-foot-switch-for-the-insane/images/pc270226-small1.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2014-12-28-foot-switch-for-the-insane/images/pc270226-small1.jpg"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Do you see anything wrong with this picture? That is indeed a SPST foot switch with a &lt;a href="https://en.wikipedia.org/wiki/NEMA_connector#NEMA_1" target="_blank" rel="noreferrer"&gt;NEMA 1-15 plug&lt;/a&gt; on the end. I can&amp;rsquo;t think of any reason that you would want to do that - the switch is rated at 15 A / 125 V AC (as well as 14 V DC), so it&amp;rsquo;s not like it was meant for a European destination where the corresponding socket wouldn&amp;rsquo;t be found in the wild.&lt;/p&gt;
&lt;p&gt;The label is a lie too - it&amp;rsquo;s normally open, and conducts when closed. It is not SPDT: there are only two conductors coming out of the switch.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve since rendered it safe and unable to short out household wiring by cutting off the NEMA 1-15 and adding a &lt;a href="https://en.wikipedia.org/wiki/Phone_connector_%28audio%29" target="_blank" rel="noreferrer"&gt;1/4 inch jack&lt;/a&gt; instead.&lt;/p&gt;
&lt;p&gt;All I can find about this switch is that it&amp;rsquo;s available from China and Vietnam, and costs USD $6.49 each when bought in large lots. Any idea what this was originally used for, or why on earth anyone would want to terminate it in a way that seems designed to blow fuses? Leave a comment.&lt;/p&gt;</description></item><item><title>Using Cygwin git on Samba</title><link>https://andrewmemory.acornwall.net/blog/2014-12-23-using-cygwin-git-on-samba/</link><pubDate>Tue, 23 Dec 2014 14:02:39 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-12-23-using-cygwin-git-on-samba/</guid><description>&lt;p&gt;When I last updated the Cygwin git, it stopped working on my Samba drive. Normally running git on a network drive is not recommended, but I do it anyway. After a git upgrade, I started seeing:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;error: invalid object
error: Error building trees&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;when I did a commit. After a little searching, I discovered &lt;a href="https://stackoverflow.com/questions/6866913/git-commit-on-windows-cygwin-is-broken" target="_blank" rel="noreferrer"&gt;this Stack Overflow post&lt;/a&gt; which suggested one answer:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config --add &amp;quot;core.createobject&amp;quot; rename&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This appears to have solved the problem for me.&lt;/p&gt;</description></item><item><title>Repairing a MFJ-259B Antenna Analyzer</title><link>https://andrewmemory.acornwall.net/blog/2014-11-29-repairing-a-mfj-259b-antenna-analyzer/</link><pubDate>Sat, 29 Nov 2014 21:48:24 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-11-29-repairing-a-mfj-259b-antenna-analyzer/</guid><description>&lt;p&gt;I&amp;rsquo;ve had an MFJ-259B antenna analyzer for a while, and for the most part it&amp;rsquo;s been pretty good. However, in the last few months I&amp;rsquo;ve seen it intermittently give me really high SWR as opposed to normal SWR.&lt;/p&gt;
&lt;p&gt;Usually, that means there&amp;rsquo;s a break in a transmission line somewhere, but I kept seeing it on different lines. Curiously, it usually went away when I touched the antenna connector.&lt;/p&gt;
&lt;p&gt;I wondered if I was adding capacitance or something to the system, but finally I realized it happened when the feedline cable pulled down on the analyzer. It was just a break between the antenna connector and the analyzer.&lt;/p&gt;
&lt;p&gt;I took the analyzer apart, re-soldered the SO-239 and I was back in business.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I learned when I took the antenna analyzer apart:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Take the battery cover off first (two screws on the bottom)&lt;/li&gt;
&lt;li&gt;Next, unscrew both sides (four screws on each side)&lt;/li&gt;
&lt;li&gt;At this point, you&amp;rsquo;ll have access to the battery compartment. Take out the two top batteries and the two bottom batteries (don&amp;rsquo;t need to take out the rest).&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;ll see four screws that hold the battery compartment to the analyzer. Actually, that&amp;rsquo;s a lie - only the two right-side screws hold the battery compartment to the analyzer. The left screws are screwed into Delrin insulators. Don&amp;rsquo;t unscrew the left screws or the insulators will drop off and you&amp;rsquo;ll have to look under the table for them. Just unscrew the right screws (top and bottom).&lt;/li&gt;
&lt;li&gt;At this point you can move the battery compartment to the side, and get easy access to the SO-239 connector. Don&amp;rsquo;t lose the lock washers that are under the screws.&lt;/li&gt;
&lt;li&gt;I suspect they used lead-free solder to solder the connector, which is more prone to cracking than 60/40. I upped the heat a little and mixed in some 60/40 solder to make it more durable.&lt;/li&gt;
&lt;li&gt;At this point you can put the 4 batteries back in and test with a dummy load and a good cable. I did this and verified my problems with mystery SWR were gone.&lt;/li&gt;
&lt;li&gt;Put things back together in the reverse order that you took them apart.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Signal out of range on Soyo Topaz S</title><link>https://andrewmemory.acornwall.net/blog/2014-11-25-signal-out-of-range-on-soyo-topaz-s/</link><pubDate>Tue, 25 Nov 2014 00:01:51 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-11-25-signal-out-of-range-on-soyo-topaz-s/</guid><description>&lt;p&gt;I recently upgraded my monitor from an old Sharp 12&amp;quot; to a Soyo Topaz S. Things seemed to be going well with the new monitor until I rebooted my Ubuntu Server (which was on 12.04 LTS). When I did that, I got the message &amp;ldquo;Signal Out of Range&amp;rdquo; from the monitor, and I couldn&amp;rsquo;t see what was being displayed.&lt;/p&gt;
&lt;p&gt;According to a number of sources, this was because my monitor was being detected incorrectly and choosing the wrong resolution or colour depth. Lots of articles explained that you can change the mode in the config file /etc/default/grub.&lt;/p&gt;
&lt;p&gt;To start with, I booted &lt;a href="http://www.sysresccd.org/" title="SystemRescueCD homepage" target="_blank" rel="noreferrer"&gt;SysRescCD&lt;/a&gt; with the option &lt;a href="https://www.gnu.org/software/grub/manual/html_node/gfxpayload.html#gfxpayload" title="gfxpayload page from grub" target="_blank" rel="noreferrer"&gt;gfxpayload=640x480&lt;/a&gt;. This got me to the point where I could see the file system, do an fsck (I&amp;rsquo;d gone 327 days without one) and mount my root drive in /mnt.&lt;/p&gt;
&lt;p&gt;Naturally, when I did that, I discovered the file /mnt/etc/default/grub didn&amp;rsquo;t exist. That&amp;rsquo;s because I had upgraded originally from 8.04 LTS and that had never upgraded my grub to grub2.&lt;/p&gt;
&lt;p&gt;But at least now I could ssh into my server again. I updated, then upgraded to 14.04.1 LTS because hey, the server needed it anyway. Immediately after doing that, I saw an error with every command, &amp;ldquo;no talloc stackframe at ../source3/param/loadparm.c, leaking memory&amp;rdquo;. The quick fix for that (as described in &lt;a href="http://ubuntuforums.org/showthread.php?t=2214042" title="forum thread" target="_blank" rel="noreferrer"&gt;this ubuntuforums thread&lt;/a&gt;) was to run pam-auth-update and remove &amp;ldquo;SMB password synchronization&amp;rdquo;. As far as I can tell, that hasn&amp;rsquo;t changed anything with respect to what passwords are used for my shares.&lt;/p&gt;
&lt;p&gt;Then I followed the &lt;a href="https://help.ubuntu.com/community/Grub2/Upgrading" title="upgrading grub instructions" target="_blank" rel="noreferrer"&gt;instructions to upgrade from grub to grub2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After that, I still couldn&amp;rsquo;t see my screen when I booted&amp;hellip; but I had an /etc/default/grub. So I edited it, uncommented the line:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;GRUB_GFXMODE=640x480&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and had a booting system again. Yay! Eventually I figured out that I could go up to 1024x768 with no problems.&lt;/p&gt;
&lt;p&gt;After that I realized I couldn&amp;rsquo;t do anything with the grub menu. I booted into the system, but couldn&amp;rsquo;t choose the OS to load with my USB keyboard.&lt;/p&gt;
&lt;p&gt;So the next time I booted, I had to switch &amp;ldquo;USB Keyboard Support&amp;rdquo; in my BIOS from &amp;ldquo;OS&amp;rdquo; to &amp;ldquo;BIOS&amp;rdquo;. That fixed the grub menu problem.&lt;/p&gt;</description></item><item><title>Trying to resurrect a dead Linksys WRT54GS router</title><link>https://andrewmemory.acornwall.net/blog/2014-09-01-trying-to-resurrect-a-dead-linksys-wrt54gs-router/</link><pubDate>Mon, 01 Sep 2014 01:47:09 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-09-01-trying-to-resurrect-a-dead-linksys-wrt54gs-router/</guid><description>&lt;p&gt;I recently went through heroic efforts to bring a dead Linksys WRT54GS router back to life. These routers are great for &lt;a href="http://www.broadband-hamnet.org/%20" target="_blank" rel="noreferrer"&gt;Broadband Hamnet&lt;/a&gt; so I really wanted to get it working, but no dice.&lt;/p&gt;
&lt;p&gt;But I don&amp;rsquo;t want to forget what I did, so I&amp;rsquo;m documenting it here.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Fix the hardware
&lt;div id="fix-the-hardware" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#fix-the-hardware" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;The first problem was that the router made a strange buzzing sound. I &lt;a href="http://www.skifactz.com/wifi/disassemble_WRT54G.htm" target="_blank" rel="noreferrer"&gt;opened the router&lt;/a&gt; and discovered that LX2 in particular, but also LX1 (two chokes at the power supply input) were actually vibrating when I put my finger on them. In addition, the capacitors near it were hot to the touch.&lt;/p&gt;
&lt;p&gt;This was described &lt;a href="http://hardforum.com/showthread.php?t=1591910" target="_blank" rel="noreferrer"&gt;in this post as an electrolytic capacitor problem&lt;/a&gt;. Sure enough, when I replaced CX2 with a new 220 uF 25 V electrolytic capacitor, the device settled down. At this point, the power LED was flashing (a bad sign) but at least it was now flashing at a regular speed. While I was soldering, I took the time to add a 12-pin header to the &lt;a href="http://www.tiaowiki.com/w/Debrick_Routers_Using_JTAG_Cable#Locate_the_JTAG_Pins.2FPads_on_the_Router" target="_blank" rel="noreferrer"&gt;router&amp;rsquo;s JTAG port&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Reflash the Firmware
&lt;div id="reflash-the-firmware" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#reflash-the-firmware" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Following the &lt;a href="http://www.dd-wrt.com/phpBB2/viewtopic.php?t=51486" target="_blank" rel="noreferrer"&gt;unbrick article here&lt;/a&gt;, I wasn&amp;rsquo;t able to ping the router. No matter what, I&amp;rsquo;d get &amp;ldquo;destination host unreachable&amp;rdquo; - even though my IP was the same as the router, ostensibly. So I figured flashing was required.&lt;/p&gt;
&lt;p&gt;I started out by trying to get a SEGGER J-Link talking to the JTAG port. I used the &lt;a href="http://www.jtagtest.com/pinouts/wrt54" target="_blank" rel="noreferrer"&gt;pinouts for the WRT54G described here&lt;/a&gt; for the WRT54GS, and the &lt;a href="http://www.segger.com/interface-description.html" target="_blank" rel="noreferrer"&gt;pinouts for the J-Link described here&lt;/a&gt;. Note that RESET on the J-Link is nSRST on the WRT54GS.&lt;/p&gt;
&lt;p&gt;After I&amp;rsquo;d done that, I wasn&amp;rsquo;t able to get the J-Link talking. It looks as if the J-Link software wants to talk only to devices it knows about - or at least, that&amp;rsquo;s all I could figure out about it. Trying to set it to MIPS mode to impersonate EJTAG didn&amp;rsquo;t yield any success either.&lt;/p&gt;
&lt;p&gt;So it was time for a different option. I didn&amp;rsquo;t have a parallel port handy, but I did have a Raspberry Pi. And a wonderful individual has taken the time to &lt;a href="https://github.com/oxplot/tjtag-pi" target="_blank" rel="noreferrer"&gt;port tjtag to the Raspberry Pi&lt;/a&gt;. I cloned the Git repo to my Pi and built it. I had to use:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;git clone git://github.com/oxplot/tjtag-pi.git&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to grab the Git repo, since https wants an auth key and I don&amp;rsquo;t have one. After that I followed the &lt;a href="https://github.com/oxplot/tjtag-pi" target="_blank" rel="noreferrer"&gt;Setup instructions&lt;/a&gt; and got tjtag built.&lt;/p&gt;
&lt;p&gt;I connected things up as described in the wiring diagram, and had success! I was able to probe the router. (I had to run sudo ./tjtag -probeonly instead of just ./tjtag.)&lt;/p&gt;
&lt;p&gt;Then I went off to the &lt;a href="http://www.tiaowiki.com/w/Debrick_Routers_Using_JTAG_Cable#Debrick_it.21" target="_blank" rel="noreferrer"&gt;tjtag instructions here&lt;/a&gt;. The first few times I did:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo ./tjtag -backup:cfe&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I got different results. It appears that tjtag on the Pi spends so much time sending output to the console that it messes up its timing. So I redirected the output to /dev/null, and after that I got consistent backups.&lt;/p&gt;
&lt;p&gt;Once I had an nvram backup, I tried erasing the nvram:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo ./tjtag -erase:nvram&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This worked, but didn&amp;rsquo;t solve my problem. So I thought I might have had a corrupted CFE. I located the &lt;a href="http://mirror.debrick.nl/index.php?dir=cfe%20collection%20project/Linksys/G/WRT54GS/&amp;amp;sort=size&amp;amp;sort_mode=dhttp://" target="_blank" rel="noreferrer"&gt;CFE for my router here&lt;/a&gt; and modified it to have my IP addresses using &lt;a href="http://www.bitsum.com/files/imgtool_nvram.zip" target="_blank" rel="noreferrer"&gt;imgtool_nvram&lt;/a&gt;. I used the following command:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;imgtool_nvram.exe wrt54gs1.0-CFE.
BIN et0macaddr=00:11:22:33:44:55 il0macaddr=00:11:22:33:44:56&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(substituting my real MAC address and one higher than it.) Then I dumped that back on the Pi as CFE.BIN, and did:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo ./tjtag -flash:cfe &amp;gt; /tmp/out&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That worked, but still no joy in Mudville after I did the flash. No matter what, when I pinged I got destination unreachable. I wondered if it was Windows messing with me, so I booted to Kali to see what happened there. Still no dice.&lt;/p&gt;
&lt;p&gt;Finally, I thought it might be a bad kernel, so I nuked it:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo ./tjtag -erase:kernel&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Even with that, the router&amp;rsquo;s still not responding. Other than re-reflashing the CFE on the assumption that the bad kernel corrupted it, I&amp;rsquo;m out of ideas.&lt;/p&gt;
&lt;p&gt;Drat, I thought I had it when I saw the instructions about &lt;a href="http://www.dd-wrt.com/wiki/index.php/Recover_from_a_Bad_Flash" target="_blank" rel="noreferrer"&gt;setting the address with arp&lt;/a&gt;. (arp -s 192.168.1.1 aa-bb-cc-dd-ee-ff if you&amp;rsquo;re on Windows.) But even when I did that (using the MAC address that I flashed), I still had nothing. I even stuffed Wireshark on the end to listen for any packets. He&amp;rsquo;s dead, Jim.&lt;/p&gt;</description></item><item><title>Making the Netgear WGR614 a bridge</title><link>https://andrewmemory.acornwall.net/blog/2014-08-16-making-the-netgear-wgr614-a-bridge/</link><pubDate>Sat, 16 Aug 2014 20:51:55 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-08-16-making-the-netgear-wgr614-a-bridge/</guid><description>&lt;p&gt;For the longest time, I&amp;rsquo;ve had a Netgear WGR614 acting as a NAT for my wifi traffic. That meant I had a separate network for wifi traffic, rather than sharing traffic with my wired network.&lt;/p&gt;
&lt;p&gt;Eventually this lead to problems. Some phone apps want to search the network for printers or set top boxes, for instance - and because the wireless devices were on a different network, they&amp;rsquo;d never find the wired devices.&lt;/p&gt;
&lt;p&gt;After a long time thinking about this, I decided to see what it would take to turn my wifi router into a bridge. Turns out the Netgear WGR614 is very nicely suited to that. All it takes is one plug change and a few settings changes, and now my wireless and wired traffic is all on the same IP address range.&lt;/p&gt;
&lt;p&gt;I found a few useful posts for this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.fieldsnet.com/2009/10/how-to-use-a-netgear-wgr614-wireless-router-as-a-bridge/" target="_blank" rel="noreferrer"&gt;http://www.fieldsnet.com/2009/10/how-to-use-a-netgear-wgr614-wireless-router-as-a-bridge/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://puzzling.org/uncategorized/2006/08/netgear-wgr614/" target="_blank" rel="noreferrer"&gt;http://puzzling.org/uncategorized/2006/08/netgear-wgr614/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kb.netgear.com/app/answers/detail/a" target="_blank" rel="noreferrer"&gt;http://kb.netgear.com/app/answers/detail/a&lt;/a&gt;_id/19852&lt;/p&gt;
&lt;p&gt;Note that this assumes you&amp;rsquo;ve got something else on the network that&amp;rsquo;s going to serve IP addresses for you. If you don&amp;rsquo;t know, you probably shouldn&amp;rsquo;t do this.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to do it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Unplug the Netgear WGR614 from everything except one laptop. Make sure the laptop is plugged into a regular port, not the WAN port.&lt;/li&gt;
&lt;li&gt;Hard-reset the Netgear WGR614 (push the button that&amp;rsquo;s inset next to the WAN port for 10 seconds).&lt;/li&gt;
&lt;li&gt;After the router reboots, connect to http://192.168.0.1 from the laptop. After a reset, the account is &amp;ldquo;admin&amp;rdquo; and the password is &amp;ldquo;password&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;ll be asked if you want to step through the configuration. Select &amp;ldquo;No, I know what I&amp;rsquo;m doing&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;First off, change that password. Choose the &amp;ldquo;Set Password&amp;rdquo; tab on the left and make it something better.&lt;/li&gt;
&lt;li&gt;Next, go into the Wireless Settings tab. Set the SSID, security to WPA2-PSK and passphrase for WPA2.&lt;/li&gt;
&lt;li&gt;If you know what channels other routers in your neighbourhood use, now is a good time to set the wifi channel as well.&lt;/li&gt;
&lt;li&gt;Go to the LAN Setup tab and unclick &amp;ldquo;Use Router as DHCP Server&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Next, on the LAN Setup tab set the IP address for the router to something in your static address range.&lt;/li&gt;
&lt;li&gt;Now unplug the laptop and plug what was the WAN uplink cable into a regular port (non-WAN) on the router.&lt;/li&gt;
&lt;li&gt;Unplug and re-plug the router.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once you&amp;rsquo;ve done all that, your router will be acting as a bridge for traffic between the wifi and wired networks.&lt;/p&gt;
&lt;p&gt;One warning: I originally didn&amp;rsquo;t hard-reset the router. This left it with an IP address of my internal wired network on the WAN port. Once I&amp;rsquo;d done that, I couldn&amp;rsquo;t connect to it over the LAN interface, since it saw that as an address conflict. So just hard-reset it.&lt;/p&gt;
&lt;p&gt;Incidentally - this isn&amp;rsquo;t strictly a bridge, since the router has an IP address on the LAN. But it&amp;rsquo;s routing the packets from wifi to wired and back.&lt;/p&gt;</description></item><item><title>Hacking the APC Smart-UPS 1000</title><link>https://andrewmemory.acornwall.net/blog/2014-05-18-hacking-the-apc-smart-ups-1000/</link><pubDate>Sun, 18 May 2014 12:31:28 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-05-18-hacking-the-apc-smart-ups-1000/</guid><description>&lt;p&gt;I have an old APC Smart-UPS 1000 (SU1000NET) that recently started giving me bad battery warning beeps. I&amp;rsquo;ve had that in the past, and replacing the battery has always solved it. This time it didn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;First I read that sometimes the battery constant for these UPS devices can get confused. (I read that at: &lt;a href="http://www.conetrix.com/Blog/post/Manually-esetting-an-APC-Smart-UPS-battery-constant-after-new-battery-replacement.aspx%29" target="_blank" rel="noreferrer"&gt;http://www.conetrix.com/Blog/post/Manually-esetting-an-APC-Smart-UPS-battery-constant-after-new-battery-replacement.aspx)&lt;/a&gt;. So I did the reset procedure described there.&lt;/p&gt;
&lt;p&gt;A few things to keep in mind before you do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You need an APC cable, not a plain serial cable. In my case I had one that I hooked up to an FTDI USB serial cable.&lt;/li&gt;
&lt;li&gt;The instructions from the site above aren&amp;rsquo;t exact - they make reference to pressing **1** but they really mean press 1&lt;/li&gt;
&lt;li&gt;There is no need to type any keys other than the ones specified. No returns, etc.&lt;/li&gt;
&lt;li&gt;The keys are case-sensitive. Y is not y.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I hooked the cable up, connected a terminal at 2400/8/N/1 Xon and changed the value of the battery constant from 79 back up to A0, which I&amp;rsquo;d read was the correct value for the SU1000NET. Here are the keys I entered:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Y&lt;/strong&gt; &lt;em&gt;(you see SM)&lt;/em&gt; &lt;strong&gt;1&lt;/strong&gt; &lt;em&gt;(then wait 1 second)&lt;/em&gt; &lt;strong&gt;1&lt;/strong&gt; &lt;em&gt;(you see PROG)&lt;/em&gt; &lt;strong&gt;0&lt;/strong&gt; &lt;em&gt;(I saw 79)&lt;/em&gt; &lt;strong&gt;+++++++&lt;/strong&gt; &lt;em&gt;(and kept on pressing + slowly until I saw A0)&lt;/em&gt; &lt;strong&gt;R&lt;/strong&gt; &lt;em&gt;(you see BYE)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I pressed Y0R to see that it had been properly set. Then I pressed the self-test button and&amp;hellip; more beeps and another battery failure indication. Boo.&lt;/p&gt;
&lt;p&gt;So I figure something has gone awry with this UPS. I wanted to shut off the beeps at least. That led me to this wonderful site: &lt;a href="http://www.networkupstools.org/ups-protocols/apcsmart.html" target="_blank" rel="noreferrer"&gt;http://www.networkupstools.org/ups-protocols/apcsmart.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That describes the entire PowerChute protocol. So I decided to turn off the weekly self-test. I did: &lt;strong&gt;Y&lt;/strong&gt; &lt;em&gt;(see SM)&lt;/em&gt; &lt;strong&gt;E&lt;/strong&gt; &lt;em&gt;(see 336)&lt;/em&gt; &lt;strong&gt;+&lt;/strong&gt; &lt;em&gt;(see OK)&lt;/em&gt; &lt;strong&gt;E&lt;/strong&gt; &lt;em&gt;(see 168)&lt;/em&gt; &lt;strong&gt;+&lt;/strong&gt; &lt;em&gt;(see OK)&lt;/em&gt; &lt;strong&gt;E&lt;/strong&gt; &lt;em&gt;(see ON)&lt;/em&gt; &lt;strong&gt;+&lt;/strong&gt; &lt;em&gt;(see OK)&lt;/em&gt; &lt;strong&gt;E&lt;/strong&gt; &lt;em&gt;(see OFF)&lt;/em&gt; &lt;strong&gt;R&lt;/strong&gt; &lt;em&gt;(see BYE)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hopefully that will turn the annoying beeps at 3am off. In the meantime, my UPS still tells me that the new batteries are bad. But when it loses power, it still does the right thing&amp;hellip; so hopefully this will work.&lt;/p&gt;</description></item><item><title>Renaming an Android shortcut in TouchWiz (the hard way)</title><link>https://andrewmemory.acornwall.net/blog/2014-02-23-renaming-an-android-shortcut-in-touchwiz-the-hard-way/</link><pubDate>Sun, 23 Feb 2014 22:14:47 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-02-23-renaming-an-android-shortcut-in-touchwiz-the-hard-way/</guid><description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Warning&lt;/strong&gt;: the information presented below might &lt;strong&gt;break your phone&lt;/strong&gt;. It&amp;rsquo;s quite easy to make a typo and delete all your shortcuts&amp;hellip; which will leave you pretty much up the creek. I probably should have backed up launcher.db before I did all this, but I didn&amp;rsquo;t. Shame on me. So don&amp;rsquo;t do this unless you know what you&amp;rsquo;re doing. If you break things it&amp;rsquo;s not my fault.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I recently switched from using Astro File Manager to &lt;a href="https://play.google.com/store/apps/details?id=com.estrongs.android.pop" target="_blank" rel="noreferrer"&gt;ES File Explorer&lt;/a&gt;. In almost all respects, ES File Explorer is a better file manager - but it has one significant shortcoming. In Astro, you can create a shortcut and specify its name at create time; in ES File Explorer your shortcut is named whatever the file was originally named.&lt;/p&gt;
&lt;p&gt;This left me with ugly file names (including extension) on the home screen. I needed a way to rename. Lots of articles on the web pointed to apps that would do it, but it seemed unnecessary to have to download a whole other app just to rename something. In the end I figured out how to do it.&lt;/p&gt;
&lt;p&gt;To start with, you&amp;rsquo;ll need the following (all of which I had installed on my phone already):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root access&lt;/li&gt;
&lt;li&gt;an sqlite3 shell (I got mine from &lt;a href="https://play.google.com/store/apps/details?id=com.keramidas.TitaniumBackupPro" target="_blank" rel="noreferrer"&gt;Titanium Backup Pro&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=jackpal.androidterm" target="_blank" rel="noreferrer"&gt;Android Terminal Emulator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Incidentally, my phone is a Samsung Infuse running Froyo&amp;hellip; other phones may be different, and I don&amp;rsquo;t think you&amp;rsquo;ll find TouchWiz on non-Samsung phones.&lt;/p&gt;
&lt;p&gt;First, I had to locate where the TouchWiz database was on my phone. &lt;a href="http://forum.xda-developers.com/showthread.php?t=867543" target="_blank" rel="noreferrer"&gt;This thread on xda-developers&lt;/a&gt; pointed me to /dbdata/databases/com.sec.android.app.twlauncher/launcher.db.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; start up Terminal Emulator and do: &lt;code&gt;$ su # cd /dbdata/databases/com.*twlaunch* # pwd pwd /dbdata/databases/com.sec.android.app.twlauncher # ls shared_prefs launcher.db&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Groovy, there&amp;rsquo;s the launcher.db in the right place. Next I inspected it with sqlite3: &lt;code&gt;# sqlite3 launcher.db SQLite version 3.7.6.3-Titanium Enter &amp;quot;.help&amp;quot; for instructions Enter SQL statements terminated with a &amp;quot;;&amp;quot; sqlite&amp;gt; .schema CREATE TABLE android_metadata (locale TEXT); CREATE TABLE apps (_id INTEGER PRIMARY KEY,componentname TEXT,top_number INTEGER NOT NULL DEFAULT 65535,page_number INTEGER NOT NULL DEFAULT 65535,cell_number INTEGER NOT NULL DEFAULT 65535); CREATE TABLE favorites (_id INTEGER PRIMARY KEY,title TEXT,intent TEXT,container INTEGER,screen INTEGER,cellX INTEGER,cellY,INTEGER,spanX INTEGER,spanY INTEGER,itemType INTEGER,appWidgetId INTEGER NOT NULL DEFAULT -1,isShortcut INTEGER,iconType INTEGER,iconPackage TEXT,iconResource TEXT,icon BLOB,uri TEXT,displayMode INTEGER); CREATE TABLE gestures (_id INTEGER PRIMARY KEY,title TEXT,intent TEXT,itemType INTEGER,iconType INTEGER,iconPackage TEXT,iconResource TEXT,icon BLOB); sqlite&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;My educated guess based on the tables and what was in them was that the table &amp;ldquo;favorites&amp;rdquo; would be useful. Not only did it have a title and an intent, but cellX, cellY, spanX and spanY looked like things that might be used for shortcuts.&lt;/p&gt;
&lt;p&gt;From there it was simple to look at what was in the table: &lt;code&gt;sqlite&amp;gt; select * from favorites; ... 149|VE_Manual_Web_FINAL_2013.pdf|file:///mnt/sdcard/saved-pdf/VE_Manual_Web_FINAL_2013.pdf#Intent;action=android.intent.action.VIEW;type=application/pdf;launchFlags=0x10000000;end|-100|1|1|2|1|1|1|-1||0|com.estrongs.android.pop|com.estrongs.android.pop:drawable/format_pdf|||&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Luckily, it looks like shortcuts are added by _id, and the number for _id increases as new shortcuts are added. That means the latest shortcut added is probably going to be at or near the end.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; update the record and see what happens: &lt;code&gt;sqlite&amp;gt; update favorites set title=&amp;quot;VE Manual&amp;quot; where _id=149; sqlite&amp;gt; .quit #&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then go back to the launcher and look at my shortcut. Boo, it&amp;rsquo;s still the same as it was. So then kill TouchWiz by holding &amp;ldquo;Home&amp;rdquo;, clicking the &amp;ldquo;Ram Manager&amp;rdquo; tab, pressing the &amp;ldquo;Level 2&amp;rdquo; button and then the &amp;ldquo;Clear Memory&amp;rdquo; button&amp;hellip; success! The shortcut is renamed. Tapping it causes the same behaviour as before&amp;hellip; in all respects it&amp;rsquo;s the same shortcut, just the title has changed.&lt;/p&gt;
&lt;p&gt;Incidentally, I ran into what looks like a problem with doing this. If I rename the shortcut then reboot, the shortcut loses its icon information. I think this has something to do with ES File Explorer being stored on SD. Strangely, it doesn&amp;rsquo;t happen when I don&amp;rsquo;t rename the file. Astro fills in the icon BLOB, but ES File Explorer doesn&amp;rsquo;t.&lt;/p&gt;</description></item><item><title>Editions of ARRL Hints and Kinks Books</title><link>https://andrewmemory.acornwall.net/blog/2014-02-14-editions-of-arrl-hints-and-kinks-books/</link><pubDate>Fri, 14 Feb 2014 21:51:02 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-02-14-editions-of-arrl-hints-and-kinks-books/</guid><description>&lt;p&gt;I&amp;rsquo;ve been looking around the web for a list of the ARRL &amp;ldquo;Hints &amp;amp; Kinks for the Radio Amateur&amp;rdquo; editions. I wasn&amp;rsquo;t able to find one, so here&amp;rsquo;s what I know:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Edition&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Orig Price&lt;/th&gt;
&lt;th&gt;Preface&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First volume (unlabeled)&lt;/td&gt;
&lt;td&gt;1933&lt;/td&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume Two&lt;/td&gt;
&lt;td&gt;1937&lt;/td&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;Ross A. Hull (VK3JU operating as ARRL station W1MK/W1AW?)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume Three&lt;/td&gt;
&lt;td&gt;1945&lt;/td&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;unsigned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume Four&lt;/td&gt;
&lt;td&gt;1949&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;A. L. Budlong (W1BUD)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume Five&lt;/td&gt;
&lt;td&gt;1954&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;A. L. Budlong (W1BUD)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume Six&lt;/td&gt;
&lt;td&gt;1959&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;A. L. Budlong (W1BUD)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume Seven&lt;/td&gt;
&lt;td&gt;1965&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;John Huntoon W1LVQ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8th Edition&lt;/td&gt;
&lt;td&gt;1968&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;John Huntoon W1LVQ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9th Edition&lt;/td&gt;
&lt;td&gt;1973? 1974?&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edition&lt;/td&gt;
&lt;td&gt;Year&lt;/td&gt;
&lt;td&gt;Orig Price&lt;/td&gt;
&lt;td&gt;Editor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10th Edition&lt;/td&gt;
&lt;td&gt;1978&lt;/td&gt;
&lt;td&gt;4.00&lt;/td&gt;
&lt;td&gt;Stuart Leland W1JEC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11th Edition&lt;/td&gt;
&lt;td&gt;1982&lt;/td&gt;
&lt;td&gt;4.00&lt;/td&gt;
&lt;td&gt;Charles L. Hutchinson K8CH, Stuart B. Leland W1JEC, Larry D. Wolfgang WA3VIL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12th Edition&lt;/td&gt;
&lt;td&gt;1989&lt;/td&gt;
&lt;td&gt;5.00&lt;/td&gt;
&lt;td&gt;Charles L. Hutchinson K8CH, David Newkirk AK7M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13th Edition&lt;/td&gt;
&lt;td&gt;1992&lt;/td&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;td&gt;David Newkirk WJ1Z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14th Edition&lt;/td&gt;
&lt;td&gt;1997&lt;/td&gt;
&lt;td&gt;12.00&lt;/td&gt;
&lt;td&gt;Robert Schetgen KU7G, David Newkirk W9VES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15th Edition&lt;/td&gt;
&lt;td&gt;2000&lt;/td&gt;
&lt;td&gt;12.00&lt;/td&gt;
&lt;td&gt;Larry Wolfgang WR1B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16th Edition&lt;/td&gt;
&lt;td&gt;2003&lt;/td&gt;
&lt;td&gt;15.95&lt;/td&gt;
&lt;td&gt;Steve Ford WB8IMY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17th Edition&lt;/td&gt;
&lt;td&gt;2004&lt;/td&gt;
&lt;td&gt;17.95&lt;/td&gt;
&lt;td&gt;Dana G. Reed W1LC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18th Edition&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;22.95&lt;/td&gt;
&lt;td&gt;Steve Ford WB8IMY&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All the editions from 10 on are the large format (8 x 11 inches) and have an editor; the editions from 1 through 9 are 6 x 9 inch and sometimes have the writer of the preface/forward listed. &lt;a href="http://www.n4mw.com/ARRL/arrl10.htm" target="_blank" rel="noreferrer"&gt;N4MW has info about the earlier editions&lt;/a&gt; as well as &lt;a href="http://www.n4mw.com/ARRL/arrlpubs.htm" target="_blank" rel="noreferrer"&gt;other classic ARRL publications&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks also to James Smith for clarifications about three of the earlier editions.&lt;/p&gt;</description></item><item><title>Optoelectronics Cub battery replacement</title><link>https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/</link><pubDate>Sun, 05 Jan 2014 18:46:31 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/</guid><description>&lt;p&gt;I&amp;rsquo;m in the process of replacing the battery in an Optoelectronics Cub frequency counter I recently inherited. Unfortunately, the battery pack for this frequency counter (and the Optoelectronics Scout and apparently a bunch of others) is fixed in the device with double-stick tape and not really intended to be removed. A new one is available here: &lt;a href="http://www.optoelectronics.com/#!batteries/c1myo" target="_blank" rel="noreferrer"&gt;www.optoelectronics.com&lt;/a&gt; but that costs more than I want to pay, especially since it wears out after a while.&lt;/p&gt;
&lt;p&gt;Instead, I decided to replace the battery pack with a battery holder that could hold NiMH batteries. The connector on the main board was about 5.3 mm wide and 4.4 mm high, with connectors about 2.5 mm apart. I think it&amp;rsquo;s a &lt;a href="http://www.jst-mfg.com/product/detail_e.php?series=277" target="_blank" rel="noreferrer"&gt;JST XH&lt;/a&gt; 2-pin connector.&lt;/p&gt;
&lt;p&gt;According to the multimeter, the left pin is ground facing the socket. Unfortunately, this means the wires on my connector are the wrong colour - so I trimmed them short and soldered them to the correct wires on the battery holder with a quick bit of heat shrink.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Heat shrink on battery wires and JST connector"
width="600"
height="307"
src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/heatshrink-plug.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/heatshrink-plug.jpg 800w, https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/heatshrink-plug.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/heatshrink-plug.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;The no-load voltage across the connector is 10 V. Since the battery claims to have 4 NiCd cells, I&amp;rsquo;m guessing (hoping?) it&amp;rsquo;s 4 * 1.2 V cells in series. Because the battery pack is designed to be charged fairly continuously, I also hope that it&amp;rsquo;s a slow charger &lt;a href="http://www.greenbatteries.com/nimh-battery-charger-faq/#NiCD%20charger%20for%20NiMH%20batteries" target="_blank" rel="noreferrer"&gt;as described here&lt;/a&gt; so I can use NiMH without danger.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Battery pack connected for testing"
width="500"
height="364"
src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/testing-with-power.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/testing-with-power.jpg 800w, https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/testing-with-power.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/testing-with-power.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Fitting the battery connector into the frequency counter requires a little work. First, it needs to go face down, so the curvature of the batteries matches the curvature of the case. Next, at least with the one I have, there&amp;rsquo;s a wire that goes across the connector from one side to the other. This needs to be at the bottom&amp;hellip; which means the wires have to be run down the middle of the connector. Finally, the components on the PCB stick a little too far down. I had to remove some of the plastic on the left and right.&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="I cut too many notches in the battery pack"
width="500"
height="180"
src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/notching-battery-case.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/notching-battery-case.jpg 800w, https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/notching-battery-case.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/notching-battery-case.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;I used a Dremel with a sanding bit to make room down the back:
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Using a Dremel to grind down the back"
width="500"
height="433"
src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/back-trimmed.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/back-trimmed.jpg 800w, https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/back-trimmed.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/back-trimmed.jpg"&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="Battery pack trimmed and in position"
width="500"
height="439"
src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/case-trimmed.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/case-trimmed.jpg 800w, https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/case-trimmed.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2014-01-05-optoelectronics-cub-battery-replacement/images/case-trimmed.jpg"&gt;&lt;/figure&gt;
&lt;p&gt;Putting back together required a little squishing, and I didn&amp;rsquo;t feel comfortable tightening the screws at the bottom that held the board down all the way. For now they&amp;rsquo;re just a little loose&amp;hellip; a better option might be to get a few small washers under the board.&lt;/p&gt;
&lt;p&gt;Useful parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Battery holder Radio Shack 2700391 ($2.49)&lt;/li&gt;
&lt;li&gt;Connector pins eBay Micro JST 2.5 XH 2-Pin Connector with Wire Male Female x 10 set ($6)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Using the TinyLoadr to program ATtiny84s</title><link>https://andrewmemory.acornwall.net/blog/2013-11-27-using-the-tinyloadr-to-program-attiny84s/</link><pubDate>Wed, 27 Nov 2013 20:51:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-11-27-using-the-tinyloadr-to-program-attiny84s/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using the excellent &lt;a href="https://www.tindie.com/products/jeffmurchison/arduinoisp-deluxe-shield-kit/" target="_blank" rel="noreferrer"&gt;TinyLoadr Shield&lt;/a&gt; to program a bunch of ATtiny2313 chips I&amp;rsquo;ve got. Doing so was easy.&lt;/p&gt;
&lt;p&gt;But when I moved over to program ATtiny84s, I ran into a bunch of problems. First, I&amp;rsquo;d get an error when burning the bootloader:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;configuration file for part ATtiny84
avrdude: Yikes! Invalid device signature.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This was because, although I&amp;rsquo;d switched all the switches on in the second bank (and off in the first and third banks), I&amp;rsquo;d neglected to move the three jumpers below them from ATtinyx313 to Other.&lt;/p&gt;
&lt;p&gt;Once I did that, I started getting different errors:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
avrdude: stk500_cmd(): protocol error&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
avrdude: stk500_cmd(): programmer is out of sync&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This is due to a defect in Arduino 1.0. Luckily, more information about the problem is here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/p/arduino/issues/detail?id=661" target="_blank" rel="noreferrer"&gt;http://code.google.com/p/arduino/issues/detail?id=661&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The upshot: I went into c:\Program Files\Arduino\hardware\arduino\cores\arduino and edited HardwareSerial.cpp to have the following:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#if (RAMEND &amp;lt; 1000)
#define SERIAL_BUFFER_SIZE 16
#else
// Was 64; changed to 128 for serial buffer overflow problem
// http://code.google.com/p/arduino/issues/detail?id=661
#define SERIAL_BUFFER_SIZE 128
#endif&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I then reburned ArduinoISP on my Uno, then plugged the TinyLoadr back in. After that, I was able to burn ATtiny84s with no problem.&lt;/p&gt;</description></item><item><title>Upgrading Mythbuntu from Lucid to Precise</title><link>https://andrewmemory.acornwall.net/blog/2013-09-22-upgrading-mythbuntu-from-lucid-to-precise/</link><pubDate>Sun, 22 Sep 2013 00:30:28 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-09-22-upgrading-mythbuntu-from-lucid-to-precise/</guid><description>&lt;p&gt;Recently I decided to finally take the plunge and upgrade my Mythbuntu installation from Lucid (10.04) to Precise (12.04). I&amp;rsquo;d been getting prompts to do the release upgrade for a while, and I knew if I put it off too long then the upgrade path would disappear and I&amp;rsquo;d have to do a full reinstall.&lt;/p&gt;
&lt;p&gt;The upgrade process was mostly painless. I did: &lt;code&gt;sudo do-release-upgrade&lt;/code&gt; and walked away for quite a while. I had to kill X, and while churning the upgrade noticed that I&amp;rsquo;d modified /etc/sysctl.conf for the HDHomeRun: &lt;code&gt;net.core.rmem_max=2097152&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The big issue was lirc - the StreamZap remote has been turned into a devinput device by default, meaning it behaves like a keyboard. I decided that I would rather have the old lircd behaviour where different apps could have different keys. Here&amp;rsquo;s what I had to do:&lt;/p&gt;
&lt;p&gt;1. Add a file /usr/share/X11/xorg.conf.d/90-streamzap.conf with the following contents: &lt;code&gt;Section &amp;quot;InputClass&amp;quot;  Identifier &amp;quot;Ignore Streamzap IR&amp;quot;  MatchProduct &amp;quot;Streamzap&amp;quot;  MatchIsKeyboard &amp;quot;true&amp;quot;  Option &amp;quot;Ignore&amp;quot; &amp;quot;true&amp;quot; EndSection&lt;/code&gt; This tells X not to treat the StreamZap remote as a keyboard. That means lirc has a shot at getting the keystrokes, and means that only one keystroke will be generated (rather than 2 - one from lirc and one from the devinput driver).&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t do this first, which led me to problems. (I ended up pushing the Mute button, which muted a bunch of my audio devices which I then had to undo.)&lt;/p&gt;
&lt;p&gt;2. sudo dpkg-reconfigure lirc&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sure how often I did this (I did it more than once). I also made sure to select the Streamzap remote in the Mythbuntu Control Centre. At the end, here&amp;rsquo;s what my /etc/lirc/lircd.conf looked like:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#This configuration has been automatically generated via
#the Ubuntu LIRC package maintainer scripts.
#
#It includes the default configuration for the remote and/or
#transmitter that you have selected during package installation.
#
#Feel free to add any custom remotes to the configuration
#via additional include directives or below the existing
#Ubuntu include directives from your selected remote and/or
#transmitter.
#Configuration for the Streamzap PC Remote remote:
include &amp;#34;/usr/share/lirc/remotes/streamzap/lircd.conf.streamzap&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Here&amp;rsquo;s what the first stanza of my /etc/lirc/hardware.conf looked like:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# /etc/lirc/hardware.conf
#
#Chosen Remote Control
REMOTE=&amp;#34;Streamzap PC Remote&amp;#34;
REMOTE_MODULES=&amp;#34;lirc_dev streamzap&amp;#34;
REMOTE_DRIVER=&amp;#34;&amp;#34;
REMOTE_DEVICE=&amp;#34;/dev/lirc0&amp;#34;
REMOTE_SOCKET=&amp;#34;&amp;#34;
REMOTE_LIRCD_CONF=&amp;#34;streamzap/lircd.conf.streamzap&amp;#34;
REMOTE_LIRCD_ARGS=&amp;#34;&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;3. Save your existing ~/.lirc/mythtv files, and any others you don&amp;rsquo;t want to lose. (I didn&amp;rsquo;t do this, and regretted it later.)&lt;/p&gt;
&lt;p&gt;4. Run the following two lines:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;mythbuntu-lirc-generator
mythbuntu-lircrc-generator&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This nukes your exsisting ~/.lirc/mythtv (and ~/.lircrc) and creates new ones based on Mythbuntu defaults.&lt;/p&gt;
&lt;p&gt;5. My mythtv file in the end (after putting my modifications back) looked like this:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# LIRCRC Auto Generated by Mythbuntu Lirc Generator
# Author(s): Mario Limonciello, Nick Fox, John Baab
# Created for use with Mythbuntu
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_0
config = 0
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_1
config = 1
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_2
config = 2
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_3
config = 3
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_4
config = 4
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_5
config = 5
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_6
config = 6
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_7
config = 7
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_8
config = 8
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_9
config = 9
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_MUTE
config = |
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_CHANNELUP
config = Up
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_VOLUMEUP
config = ]
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_CHANNELDOWN
config = Down
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_VOLUMEDOWN
config = [
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_UP
config = Up
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_LEFT
config = Left
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_OK
config = Return
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_RIGHT
config = Right
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_DOWN
config = Down
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_MENU
config = M
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_EXIT
config = Escape
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_PLAY
config = P
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_PAUSE
config = P
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_STOP
config = Escape
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_PREVIOUS
config = Q
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_NEXT
config = Z
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_RECORD
config = R
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_REWIND
config = PgUp
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_FORWARD
config = PgDown
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_POWER
config = Escape
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_BLUE
config = I
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_RED
config = D
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_YELLOW
config = A
repeat = 0
delay = 0
end
begin
remote = Streamzap_PC_Remote
prog = mythtv
button = KEY_GREEN
config = W
repeat = 0
delay = 0
end&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;ve got the blue button pushing I (for info), the red button pushing D (for delete), the green button pushing W (for width) and the yellow button pushing A (for playback speed).&lt;/p&gt;
&lt;p&gt;I also set the power button to be another Escape, and Forward to PgDown and Backwards to PgUp.&lt;/p&gt;
&lt;p&gt;You want to make sure the remote = Streamzap_PC_Remote, not the devinput remote.&lt;/p&gt;
&lt;p&gt;Edit: Ha, I spoke too soon. I&amp;rsquo;m troubled by endless &amp;ldquo;Sorry, Ubuntu 12.04 has experienced an internal error&amp;rdquo; passwords. Luckily, &lt;a href="http://www.webupd8.org/2012/06/how-to-get-rid-of-internal-system-error.html" target="_blank" rel="noreferrer"&gt;this post&lt;/a&gt; explains how to at least turn them off, if not fix the problems.&lt;/p&gt;</description></item><item><title>Standard for 12 volt DC Edison sockets</title><link>https://andrewmemory.acornwall.net/blog/2013-09-02-standard-for-12-volt-dc-edison-sockets/</link><pubDate>Mon, 02 Sep 2013 18:15:21 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-09-02-standard-for-12-volt-dc-edison-sockets/</guid><description>&lt;p&gt;I recently decided to create a 12 V DC lamp for emergency lighting. I started with a 120 V AC desk lamp from a big box store ($5.99) and added one of the 2W 12V DC bulbs that use the &lt;a href="https://en.wikipedia.org/wiki/Edison_screw#Types" target="_blank" rel="noreferrer"&gt;Edison E26/E27&lt;/a&gt; socket.&lt;/p&gt;
&lt;p&gt;Of course, I needed to remove the existing &lt;a href="https://en.wikipedia.org/wiki/NEMA_connector#NEMA_1" target="_blank" rel="noreferrer"&gt;NEMA 1&lt;/a&gt; plug and replace it with something that can&amp;rsquo;t be plugged into household current. I chose PowerPole connectors. That brought up the question: what should be the positive terminal and what should be the negative?&lt;/p&gt;
&lt;p&gt;I did a lot of searching in RV and boat wiring, but couldn&amp;rsquo;t find anything regarding polarity of Edison E26 / E27 sockets. So in the end I just went with what seemed sensible. I wired what used to be connected to the wide blade of the 120 V plug (neutral) to negative, and what used to be connected to the narrow blade to the positive terminal.&lt;/p&gt;
&lt;p&gt;This means that in the E26 / E27 socket, the brass projection ends up connected to the + terminal and the shell ends up connected to the - terminal.&lt;/p&gt;
&lt;p&gt;That seems to make sense to me - but if anyone knows a better standard I&amp;rsquo;d love to hear about it.&lt;/p&gt;</description></item><item><title>Connecting to HSMM-Mesh and the Internet from a laptop</title><link>https://andrewmemory.acornwall.net/blog/2013-08-03-connecting-to-hsmm-mesh-and-the-internet/</link><pubDate>Sat, 03 Aug 2013 17:39:03 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-08-03-connecting-to-hsmm-mesh-and-the-internet/</guid><description>&lt;p&gt;Note: This page does not discuss connecting HSMM mesh to the Internet. It&amp;rsquo;s just about talking to the mesh and the Internet from the same client device.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been playing with &lt;a href="http://hsmm-mesh.org" target="_blank" rel="noreferrer"&gt;hsmm-mesh&lt;/a&gt; lately on my laptop. Up until now, when I&amp;rsquo;ve done this I could either view the HSMM mesh or the Internet, but not both. There were a couple of reasons:&lt;/p&gt;
&lt;p&gt;1. My routing tables didn&amp;rsquo;t know how to direct traffic to the HSMM mesh network.&lt;/p&gt;
&lt;p&gt;To solve this, I needed to tell the laptop to send traffic in the 10.*.*.* range to the HSMM mesh rather than to the default gateway:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;ip route add 10.0.0.0/8 via 172.27.0.1 dev eth0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;2. I had to make sure things were resolving right for DNS (in my /etc/resolv.conf):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;domain austin.tx.us.mesh
search austin.tx.us.mesh
nameserver 172.27.0.1
nameserver 192.168.1.1&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;DNS is still a bit of an issue. 172.27.0.1 resolves anything in *.austin.tx.us.mesh, so my local network is never found. But at least I can browse the web and HSMM.&lt;/p&gt;</description></item><item><title>Android superuser not coming up</title><link>https://andrewmemory.acornwall.net/blog/2013-06-17-android-superuser-not-coming-up/</link><pubDate>Mon, 17 Jun 2013 23:54:25 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-06-17-android-superuser-not-coming-up/</guid><description>&lt;p&gt;I ran into a weird problem on an Android 2.2 (Froyo) phone that I had. Although it was rooted, and Superuser was installed, su wouldn&amp;rsquo;t come up. Trying to root it again with SuperOneClick didn&amp;rsquo;t seem to work either. Starting Titanium Backup (which worked in the past) yielded &amp;ldquo;asking for root rights&amp;rdquo;, and trying to run Terminal Emulator and su just hung.&lt;/p&gt;
&lt;p&gt;Finally, I stumbled my way to something working. I ran SuperOneClick 2.3.1 first. I turned off the &amp;ldquo;automatically start&amp;rdquo; option of LBE Privacy Guard. I rebooted, then ran ADB shell and was able to get root from there:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;C:\super1click\adb\adb shell
$ su
#&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;From there, I figured out what device /system was:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# cat /proc/mounts&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;From this I determined that /system was mounted on /dev/block/stl9, so:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# mount -ro remount,rw /dev/block/stl9 /system
# chown root.root /system/bin/su
# chmod 6777 /system/bin/su&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;At this point, I was able to start su and do the &amp;ldquo;check for update&amp;rdquo;. su determined that it was out of date, and downloaded a new version, fixing the permissions as it did so. (6777 is a little lax, but I couldn&amp;rsquo;t remember what su was supposed to be.)&lt;/p&gt;
&lt;p&gt;I have no explanation as to why su would break. I have no explanation why this would fix it, but it did for me. Maybe it will for you as well.&lt;/p&gt;</description></item><item><title>Solving Firefox "window sent to back" when opening new window</title><link>https://andrewmemory.acornwall.net/blog/2013-06-17-solving-firefox-window-sent-to-back-when-opening-new-window/</link><pubDate>Mon, 17 Jun 2013 23:54:25 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-06-17-solving-firefox-window-sent-to-back-when-opening-new-window/</guid><description>&lt;p&gt;Since I&amp;rsquo;ve had Firefox on my Windows 7 machine, I&amp;rsquo;ve noticed that with certain websites when you open a new window, it will be opened, but then moved behind the current window. Not life-threatening, but an annoying quirk. Tonight I finally was annoyed enough to find the solution.&lt;/p&gt;
&lt;p&gt;I found an answer on &lt;a href="https://support.mozilla.org/en-US/questions/938033" target="_blank" rel="noreferrer"&gt;this post at the support forum for Mozilla&lt;/a&gt; - which in turn pointed me to &lt;a href="http://forums.adobe.com/thread/1018071" target="_blank" rel="noreferrer"&gt;this article from Adobe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Short answer: disable &amp;ldquo;protected mode&amp;rdquo; on Flash to prevent this behaviour. It&amp;rsquo;s frustrating to have to make Flash less secure to solve this, but I rationalize it by saying it&amp;rsquo;s no less secure than Flash on XP.&lt;/p&gt;
&lt;p&gt;How to do this? From the Explorer, navigate to c:\windows\system32\notepad.exe and select &amp;ldquo;Run as Administrator&amp;rdquo;, then open:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;C:\windows\system32\macromed\flash\mms.cfg&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(or c:\windows\system64\flash\mms.cfg if you&amp;rsquo;re on Windows 64 bit). Add the following to the end of the file:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;ProtectedMode=0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Save the file and you&amp;rsquo;re done.&lt;/p&gt;</description></item><item><title>Useful resources for filter design</title><link>https://andrewmemory.acornwall.net/blog/2013-03-30-useful-resources-for-filter-design/</link><pubDate>Sat, 30 Mar 2013 01:58:45 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-03-30-useful-resources-for-filter-design/</guid><description>&lt;p&gt;Some useful links I&amp;rsquo;ve found for designing passive RF filters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.daycounter.com/Calculators/LC-Resonance-Calculator.phtml" target="_blank" rel="noreferrer"&gt;LC resonance calculator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.coilcraft.com/kits/c320.html" target="_blank" rel="noreferrer"&gt;Coilcraft 1206CS SMT designer kit contents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/North_American_broadcast_television_frequencies" target="_blank" rel="noreferrer"&gt;North American broadcast TV frequencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hamuniverse.com/vhfuhfbands.html" target="_blank" rel="noreferrer"&gt;Ham Bands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tonnesoftware.com/svcfilter.html" target="_blank" rel="noreferrer"&gt;Standard Value Filter (SVC) Filter Designer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.linear.com/designtools/software/#LTspice" target="_blank" rel="noreferrer"&gt;LTSpice IV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://forum.allaboutcircuits.com/showthread.php?t=52617" target="_blank" rel="noreferrer"&gt;Setting up LTSpice with an AC voltage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://kom.aau.dk/~hmi/Teaching/LTspice/restrict/LTspicedoc/LTspice_guide.pdf" target="_blank" rel="noreferrer"&gt;Intro to LTSpice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pages.suddenlink.net/wa5bdu/ltguide.pdf" target="_blank" rel="noreferrer"&gt;Another quick guide to LTSpice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Migrating from Lotus Approach to LibreOffice Base</title><link>https://andrewmemory.acornwall.net/blog/2013-03-10-migrating-from-lotus-approach-to-libreoffice-base/</link><pubDate>Sun, 10 Mar 2013 15:02:44 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-03-10-migrating-from-lotus-approach-to-libreoffice-base/</guid><description>&lt;p&gt;I had a number of databases in Lotus Approach. Luckily, I&amp;rsquo;d had the foresight to make them dBASE databases, which LibreOffice knows a little about.&lt;/p&gt;
&lt;p&gt;However, it doesn&amp;rsquo;t look as if LibreOffice knows much about Lotus Approach, which means all my existing forms were history. I started migrating them to LibreOffice forms. The form designer is a little rustic in LibreOffice (shift to multiselect on Windows, still can&amp;rsquo;t figure snap to grid out), but it&amp;rsquo;s enough to do what I need.&lt;/p&gt;
&lt;p&gt;I used the automated form wizard to create forms from the fields first. That was enough to get started.&lt;/p&gt;
&lt;p&gt;Next, I had a couple of fields that were combo boxes in Approach. To change the text field in LibreOffice Base to a combo box, I followed the instructions here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://listarchives.libreoffice.org/global/users/msg12693.html" title="listarchives.libreoffice.org/global/users/msg12693.html" target="_blank" rel="noreferrer"&gt;listarchives.libreoffice.org/global/users/msg12693.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In case that goes away, here&amp;rsquo;s the summary of what I did:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click on the text field that the wizard created&lt;/li&gt;
&lt;li&gt;Since that field is actually a group, pop up the context menu and say Group-&amp;gt;Ungroup&lt;/li&gt;
&lt;li&gt;Click on the text field rather than the label&lt;/li&gt;
&lt;li&gt;Pop up the context menu and say Replace With-&amp;gt;Combo Box&lt;/li&gt;
&lt;li&gt;Pop up the context menu and select &amp;ldquo;Control&amp;hellip;&amp;rdquo; to open control properties&lt;/li&gt;
&lt;li&gt;All my combo boxes were populated from the database. To do that, choose the Data tab&lt;/li&gt;
&lt;li&gt;Change &amp;ldquo;Type of list contents&amp;rdquo; from &amp;ldquo;Table&amp;rdquo; to &amp;ldquo;Sql&amp;rdquo;&lt;/li&gt;
&lt;li&gt;For &amp;ldquo;List content&amp;rdquo;, enter SELECT DISTINCT &amp;ldquo;field&amp;rdquo; FROM &amp;ldquo;table&amp;rdquo; (e.g., SELECT &amp;ldquo;ARTIST&amp;rdquo; FROM &amp;ldquo;CD&amp;rdquo; for my CD database)&lt;/li&gt;
&lt;li&gt;Close the Properties dialog&lt;/li&gt;
&lt;li&gt;Re-group the field with its label&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The same thing worked for dropdown lists - Replace With-&amp;gt;List Box, change &amp;ldquo;Type of list contents&amp;rdquo; from &amp;ldquo;Valuelist&amp;rdquo; to &amp;ldquo;Sql&amp;rdquo; and use similar SQL to generate the list. I used &amp;ldquo;SELECT DISTINCT&amp;rdquo; rather than just &amp;ldquo;SELECT&amp;rdquo; because I didn&amp;rsquo;t want multiple copies showing up in my list box.&lt;/p&gt;</description></item><item><title>Creating headers in LibreOffice</title><link>https://andrewmemory.acornwall.net/blog/2013-02-20-creating-headers-in-libreoffice/</link><pubDate>Wed, 20 Feb 2013 23:57:10 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2013-02-20-creating-headers-in-libreoffice/</guid><description>&lt;p&gt;Recently I had to create headers in LibreOffice. It&amp;rsquo;s not hard, but neither is it obvious. Here&amp;rsquo;s how I did it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Insert-&amp;gt;Header-&amp;gt;Default&lt;/li&gt;
&lt;li&gt;Format-&amp;gt;Page-&amp;gt;Header and unclick &amp;ldquo;Same page left/right&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Edit the header to have all the text you want (sans fields)&lt;/li&gt;
&lt;li&gt;Insert the fields in the right places. I wanted Chapter and Page Number, so I did Insert-&amp;gt;Fields-&amp;gt;Page Number and Insert-&amp;gt;Fields-&amp;gt;Other-&amp;gt;Chapter. I used tab to space them out. (In general, page number goes on the left for even pages and on the right for odd pages.)&lt;/li&gt;
&lt;li&gt;That was cool and all, but left me with a page number on page one, which I didn&amp;rsquo;t want. Luckily, I found &lt;a href="http://chrismlindsey.com/2007/11/30/how-to-remove-header-from-first-page-in-openoffice/" target="_blank" rel="noreferrer"&gt;this site&lt;/a&gt; which explained the magic. Go to the first page, then click Format-&amp;gt;Styles and Formatting. Pick the fourth box (Page Styles) and double-click on &amp;ldquo;First Page&amp;rdquo;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Done! Now I have headers that look like books or magazines.&lt;/p&gt;</description></item><item><title>Migrating from Pegasus to Thunderbird</title><link>https://andrewmemory.acornwall.net/blog/2012-12-20-migrating-from-pegasus-to-thunderbird/</link><pubDate>Thu, 20 Dec 2012 16:32:07 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-12-20-migrating-from-pegasus-to-thunderbird/</guid><description>&lt;p&gt;I&amp;rsquo;ve been on Pegasus Mail for ages. It&amp;rsquo;s OK, but not open source, and I&amp;rsquo;ve always had the vague fear that some day my email will be locked away due to a format change. In addition, its HTML handling is not the best, and the way it does multiple accounts is a little weird. Finally, it was getting slow on my Windows XP PC due to the file system - and migrating it from one PC to another is a pain, especially if you&amp;rsquo;re changing the drive the data lives on.&lt;/p&gt;
&lt;p&gt;So I resolved to move to Thunderbird. I started from here: &lt;a href="http://www.techspot.com/community/topics/how-to-convert-emails-from-pegasus-to-thunderbird-format.17806/" target="_blank" rel="noreferrer"&gt;www.techspot.com/community/topics/how-to-convert-emails-from-pegasus-to-thunderbird-format.17806/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and here: &lt;a href="http://fixunix.com/mozilla/420484-pegasus-thunderbird-import-problems.html" target="_blank" rel="noreferrer"&gt;fixunix.com/mozilla/420484-pegasus-thunderbird-import-problems.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and when I did the MBox method, it seemed to work fine. Until I looked at the folder on Thunderbird and saw more messages than I&amp;rsquo;d counted on.&lt;/p&gt;
&lt;p&gt;It appears that Thunderbird uses &amp;ldquo;\n\nFrom .*\n&amp;rdquo; to filter its messages. Ok, but Pegaus doesn&amp;rsquo;t quote the From in &amp;ldquo;From the editor:&amp;rdquo; which appears at the start of the line in some of my messages. Argh! This left me with lots of messages split in half, with weird dates and strange subjects / from / to lines.&lt;/p&gt;
&lt;p&gt;I hacked up the following awk script, which I put in a file called peg2tbird: &lt;code&gt;/^From / &amp;amp;&amp;amp; ! /\?\?\?\@\?\?\?/ { printf &amp;quot;&amp;gt;%s\n&amp;quot;, $0 } !(/^From / &amp;amp;&amp;amp; ! /\?\?\?\@\?\?\?/ ) { printf &amp;quot;%s\n&amp;quot;, $0 }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This takes any line that matches &amp;ldquo;From &amp;quot; but doesn&amp;rsquo;t match &amp;ldquo;From ???@???&amp;rdquo; and puts a &amp;gt; in front of the From. All other lines it leaves as-is.&lt;/p&gt;
&lt;p&gt;Then I ran: &lt;code&gt;\cygwin\bin\gawk -f peg2tbird &amp;lt; unx01234.mbx &amp;gt; tbird-mbox-file&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then I copied tbird-mbox-file to my Thunderbird Profile directory (in Mail\Local Folders).&lt;/p&gt;
&lt;p&gt;This makes the messages look a little strange in Thunderbird - they look like &amp;ldquo;&amp;gt;From the editor:&amp;rdquo;. Also, some messages ended up showing with today&amp;rsquo;s date - inserted by Pegasus. (I think it was just those generated by a virus checker, so they were probably less well-formed than real messages.) Sigh. Oh well, that&amp;rsquo;s good enough for me to get my old messages migrated.&lt;/p&gt;</description></item><item><title>Repairing a Samsung LN32A450</title><link>https://andrewmemory.acornwall.net/blog/2012-12-12-repairing-a-samsung-ln32a450/</link><pubDate>Wed, 12 Dec 2012 22:33:21 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-12-12-repairing-a-samsung-ln32a450/</guid><description>&lt;p&gt;I own a Samsung LN32A450 TV set, which has been fairly good so far&amp;hellip; until last weekend, when it didn&amp;rsquo;t turn on. Instead, the power LED flashed steadily at about one flash every 500 ms.&lt;/p&gt;
&lt;p&gt;It seems that my TV set suffered from the capacitor plague. A bunch of the Samwha capacitors swelled up and were no longer to spec. I could order a replacement board (the board is &lt;a href="http://www.findparts4you.com/store/p/716-BN44-00214A-SMPS-Power-PCB-LCD-TV-Board.aspx" target="_blank" rel="noreferrer"&gt;BN44-00214A&lt;/a&gt; available from findparts4you.com). A little searching showed that others had successfully revived their power boards just by replacing the capacitors.&lt;/p&gt;
&lt;p&gt;First, I had to open the TV set. This involved removing 16 screws (all the same size) from the back. I discoverd I had to be careful with the ones marked &amp;ldquo;S&amp;rdquo; - those four also hold the TV stand in place, so I wanted to remove them last. Also, there&amp;rsquo;s a screw on the back panel below the &amp;ldquo;EX-Link&amp;rdquo; connector, and another one on the back underneath the A/V 2 inputs.&lt;/p&gt;
&lt;p&gt;Once I did that I could slide the back off (face down, since the support was unscrewed). The power board is the one in the middle. There are five connectors to disconnect from there: two at the upper left, one at the upper right, and two power connectors that go to the lower right. In my case they stayed in the right position once I removed them because there was tape holding them to the flat panel.&lt;/p&gt;
&lt;p&gt;After that, I removed 6 small screws that held the power board in. I didn&amp;rsquo;t need to remove any of the standoffs - they&amp;rsquo;re just there to push the board away from the flat panel.&lt;/p&gt;
&lt;p&gt;When I investigated the board, I could see the telltale swelling of capacitors that indicated problems. I saw problems with four capacitors:&lt;/p&gt;
&lt;p&gt;CB852 in the middle right of the board: 2200 uF 10V CW856 near the top left: 470 uF 25V CW858 right below CW856: 680 uF 25V CM868 right below CW858: 680 uF 35V&lt;/p&gt;
&lt;p&gt;Some people reported success with using Radio Shack replacement capacitors. I was a little nervous about that - these caps are all rated to 105 degrees C and have high ripple current tolerance, and I didn&amp;rsquo;t want to swap in something I&amp;rsquo;d just have to replace later. I ended up getting replacements from &lt;a href="http://www.digikey.com/" target="_blank" rel="noreferrer"&gt;Digi-Key&lt;/a&gt;. They have a minimum $25 order (otherwise they charge you $5 for handling). Luckily I had some other stuff to buy at the same time.&lt;/p&gt;
&lt;p&gt;I replaced them with the following:&lt;/p&gt;
&lt;p&gt;CB852: Panasonic EEU-FC1A222L (Digi-Key part P11189-ND) CW856: Panasonic EEU-FM1E471 (Digi-Key part P12388-ND) CW858: Panasonic EEU-FM1E681 (Digi-Key part P12390-ND) CM868: Panasonic EEU-FM1V681 (Digi-Key part P12417-ND)&lt;/p&gt;
&lt;p&gt;The replacement for CB852 was about 1 cm taller than the original part, and that made it the tallest part on the board. I was a little worried about that, but there seemed to be enough clearance that it didn&amp;rsquo;t cause a problem.&lt;/p&gt;
&lt;p&gt;These capacitors are electrolytic and have a polarity, so I had to replace them the same way &amp;lsquo;round that the originals were. Luckily, on my circuit board all the negative terminals were marked with a white semicircle underneath the capacitor.&lt;/p&gt;
&lt;p&gt;After that, I plugged the cables back into the board (not forgetting the single-pin green ground cable). Then I put the 6 screws back.&lt;/p&gt;
&lt;p&gt;Next I put the cover back on and put the 16 screws back in. I started with the base &amp;ldquo;S&amp;rdquo; screws, then the top three, then kind of haphazardly put the rest in the right places.&lt;/p&gt;
&lt;p&gt;Then I powered up. Success! The TV came on and was as good as it was before this happened.&lt;/p&gt;
&lt;p&gt;A few links I found useful: &lt;a href="http://forums.cnet.com/7723-13973_102-334836/samsung-ln32a450-died/" target="_blank" rel="noreferrer"&gt;forums.cnet.com/7723-13973_102-334836/samsung-ln32a450-died/&lt;/a&gt; &lt;a href="http://forums.cnet.com/7723-13973_102-401147/samsung-ln32a450-power-light-blinking-but-does-not-power-up/" target="_blank" rel="noreferrer"&gt;forums.cnet.com/7723-13973_102-401147/samsung-ln32a450-power-light-blinking-but-does-not-power-up/&lt;/a&gt; &lt;a href="http://forums.cnet.com/7723-13973_102-359389/samsung-lcd-tv-ln-t5265f-black-screen-diagnosis-help/" target="_blank" rel="noreferrer"&gt;forums.cnet.com/7723-13973_102-359389/samsung-lcd-tv-ln-t5265f-black-screen-diagnosis-help/&lt;/a&gt; &lt;a href="http://www.samsung.com/us/capacitorsettlement/" target="_blank" rel="noreferrer"&gt;www.samsung.com/us/capacitorsettlement/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Maxtor Shared Storage II 320 G power supply</title><link>https://andrewmemory.acornwall.net/blog/2012-12-09-maxtor-shared-storage-ii-320-g-power-supply/</link><pubDate>Sun, 09 Dec 2012 13:29:39 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-12-09-maxtor-shared-storage-ii-320-g-power-supply/</guid><description>&lt;p&gt;Since I have recently moved, I&amp;rsquo;ve discovered how much I hate devices that don&amp;rsquo;t clearly label their power supplies. All my wall warts got detached from their devices in the move, and I&amp;rsquo;m gradually re-unifying them.&lt;/p&gt;
&lt;p&gt;Today&amp;rsquo;s example: the Maxtor Shared Storage II 320 G external drive. It takes 12 volts DC, 3A, centre positive, and a brick I had from Goodwill with a 5.5mm outer barrel connector seemed to fit well.&lt;/p&gt;</description></item><item><title>Changing MAC address on OpenBSD</title><link>https://andrewmemory.acornwall.net/blog/2012-12-06-changing-mac-address-on-openbsd/</link><pubDate>Thu, 06 Dec 2012 00:49:03 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-12-06-changing-mac-address-on-openbsd/</guid><description>&lt;p&gt;A little while ago, I needed to change my MAC address on the OpenBSD firewall I&amp;rsquo;ve got running. (My ISP kept feeding me a bad IP address from an old lease and I wanted a new one.)&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s easy to do this on OpenBSD:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ifconfig vr1 down ifconfig vr1 lladdr 00:11:22:33:44:55 ifconfig vr1 up&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The question is, where&amp;rsquo;s the right place to put this to make it permanent? A few web searches revealed that a bunch of people had modified /etc/netstart by putting the ifconfig vr1 lladdr line somewhere near the beginning. I&amp;rsquo;d rather not sully my pristine /etc scripts with changes if I don&amp;rsquo;t have to.&lt;/p&gt;
&lt;p&gt;Linux has /etc/network/interfaces, and OpenBSD has /etc/hostname.if. I just changed my /etc/hostname.vr1 to:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dhcp lladdr 00:11:22:33:44:55&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and I was requesting an IP address using my new MAC address.&lt;/p&gt;</description></item><item><title>Repairing a Dell Inspiron N4010</title><link>https://andrewmemory.acornwall.net/blog/2012-12-01-repairing-a-dell-inspiron-n4010/</link><pubDate>Sat, 01 Dec 2012 01:26:32 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-12-01-repairing-a-dell-inspiron-n4010/</guid><description>&lt;p&gt;I recently had a friend bring me a Dell Inspiron N4010. The laptop wouldn&amp;rsquo;t boot up, and the friend wanted to get the data off the hard drive.&lt;/p&gt;
&lt;p&gt;I figured that would be a fairly easy task. Little did I know&amp;hellip;. I started by looking at Youtube videos about taking apart the N4010. Here&amp;rsquo;s the &lt;a href="http://www.youtube.com/watch?v=mtC7rFZ3z40" title="Start of the nightmare" target="_blank" rel="noreferrer"&gt;best Inspiron N4010 video&lt;/a&gt; - or rather, first in a series of three for over 30 minutes total time.&lt;/p&gt;
&lt;p&gt;Turns out, Dell in their infinite wisdom decided not to put a door on the case to allow access to the hard drive. Instead, you have to &lt;em&gt;remove the keyboard and motherboard&lt;/em&gt; to swap it out. This proves that Dell&amp;rsquo;s engineering department is willing to hire the insane.&lt;/p&gt;
&lt;p&gt;Luckily, the video showed disassembly as well as assembly. I knew my friend had taken the laptop to Best Buy a few weeks before it stopped working to put a new hard drive in. (And again after it stopped: that time the Geek Squad claimed &amp;ldquo;no fix was possible&amp;rdquo; because there were no BIOS beeps.) The video showed a stick-on plastic piece that wasn&amp;rsquo;t present (any more) on my friend&amp;rsquo;s laptop between the keyboard and the motherboard.&lt;/p&gt;
&lt;p&gt;With the laptop disassembled, I said &amp;ldquo;why not&amp;rdquo; and tried to boot. It came up. I connected the laptop up to the network and backed up the hard drive.&lt;/p&gt;
&lt;p&gt;The stick-on plastic piece appeared to keep the keyboard from shorting the motherboard. More of that Dell quality. I&amp;rsquo;m guessing the Geek Squad just tossed it. I fabricated a quick replacement from some polyester film I had hanging around. Who knows if it will last, but at least the machine boots now.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m really glad I did this. It made me 100% sure I would never buy a Dell laptop. Ever.&lt;/p&gt;</description></item><item><title>Error 1303 upgrading LibreOffice 3.5.3 to 3.5.6</title><link>https://andrewmemory.acornwall.net/blog/2012-09-30-error-1303-upgrading-libreoffice-3-5-3-to-3-5-6/</link><pubDate>Sun, 30 Sep 2012 21:36:58 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-09-30-error-1303-upgrading-libreoffice-3-5-3-to-3-5-6/</guid><description>&lt;p&gt;It looks like LibreOffice prompts you now when there&amp;rsquo;s an upgrade. I ran into a problem, though, when trying to upgrade on Windows 7.&lt;/p&gt;
&lt;p&gt;When I tried the upgrade, I was told that I didn&amp;rsquo;t have enough permissions - even when I was running as administrator. I&amp;rsquo;d get an &amp;ldquo;error 1303: Installer has insufficient privileges to access C:\Program Files\&amp;hellip;&amp;rdquo; and the install would always fail.&lt;/p&gt;
&lt;p&gt;Even when I tried to take ownership of the files in that directory, I couldn&amp;rsquo;t. It was a puzzle. After a while messing about, I decided to nuke the whole thing from orbit. Finally that gave me a clue: when I tried to delete the files, some were left because a process was holding them open. (There were a couple of files - under share\config\soffice.cfg\modules\sglobal\toolbar) and whatever was running must have restarted at boot because it survived a reboot.)&lt;/p&gt;
&lt;p&gt;That gave me the hints I needed. I booted into safe mode and deleted &amp;ldquo;C:\Program Files\LibreOffice 3.5&amp;rdquo; and its subdirectories. That worked, then I rebooted into normal mode and installed the 3.5.6 installer files. Now LibreOffice is upgraded and working again.&lt;/p&gt;</description></item><item><title>Final cleanup for the ALIX firewall</title><link>https://andrewmemory.acornwall.net/blog/2012-07-06-final-cleanup-for-the-alix-firewall/</link><pubDate>Fri, 06 Jul 2012 22:38:45 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-07-06-final-cleanup-for-the-alix-firewall/</guid><description>&lt;p&gt;Finally, there are a few things that I either forgot to do or that make life easier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setting up localtime&lt;/strong&gt; By defaut, /etc/localtime is set to Alberta, where OpenBSD has its home. I need to set it to somewhere closer.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;rm /etc/localtime; ln -s /usr/share/zoneinfo/US/Mountain /etc/localtime&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Now date shows the correct time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blinkenlights&lt;/strong&gt; I wrote a script to make the LEDs move back and forth. I start this at boot. (In an earlier version of the firewall, I edited /etc/rc to turn LEDs on when certain thresholds had been passed in the boot process. But now I don&amp;rsquo;t want to muck up /etc/rc so much.)&lt;/p&gt;
&lt;p&gt;First of all, you need to allow the ports to be written before OpenBSD gets all secure on you. Edit /etc/rc.securelevel and add:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#
# Place local actions here.
#
echo -n &amp;#39;enabling LED pins&amp;#39;
gpioctl -q /dev/gpio0 6 set out iout
gpioctl -q /dev/gpio0 25 set out iout
gpioctl -q /dev/gpio0 27 set out iout&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I got these numbers from the Status LEDs section of the &lt;a href="http://www.pcengines.ch/pdf/alix2.pdf" target="_blank" rel="noreferrer"&gt;ALIX manual&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then create /usr/local/bin/cylon:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#!/bin/ksh -
led3on(){
gpioctl -q /dev/gpio0 6 0
gpioctl -q /dev/gpio0 25 0
gpioctl -q /dev/gpio0 27 1
}
led2on(){
gpioctl -q /dev/gpio0 6 0
gpioctl -q /dev/gpio0 25 1
gpioctl -q /dev/gpio0 27 0
}
led1on(){
gpioctl -q /dev/gpio0 6 1
gpioctl -q /dev/gpio0 25 0
gpioctl -q /dev/gpio0 27 0
}
ledsoff(){
gpioctl -q /dev/gpio0 6 0
gpioctl -q /dev/gpio0 25 0
gpioctl -q /dev/gpio0 27 0
}
while [ true ] ; do
led1on
sleep 1
led2on
sleep 1
led3on
sleep 1
led2on
sleep 1
done&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, start it from /etc/rc.local:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Add your local startup actions here.
echo -n &amp;#39;cylon&amp;#39;
sh /usr/local/bin/cylon &amp;amp;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;On reboot, yay, blinky! That at least tells you the kernel hasn&amp;rsquo;t crashed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reducing the mail&lt;/strong&gt; Because flashrd is really OpenBSD, it sends mail more suited to a server than a firewall with limited disk.&lt;/p&gt;
&lt;p&gt;First thing I noticed:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Running security(8):
Checking special files and directories.
Output format is:
filename:
criteria (shouldbe, reallyis)
etc/rc.conf.local:
permissions (0644, 0755)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I fixed that with a chmod 0644 /etc/rc.conf.local. So now /usr/libexec/security shows no problems. Good.&lt;/p&gt;
&lt;p&gt;Once that&amp;rsquo;s done, make things complain less:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;crontab -uroot -e&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and comment out:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#30 1 * * * /bin/sh /etc/daily
#30 3 * * 6 /bin/sh /etc/weekly&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This prevents the daily and weekly reports, leaving just the monthly one.&lt;/p&gt;
&lt;p&gt;Next, I noticed that sendmail gets run from root&amp;rsquo;s crontab, so it doesn&amp;rsquo;t need to run at boot:&lt;/p&gt;
&lt;p&gt;/etc/rc.conf:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sendmail_flags=NO # &amp;#34;-L sm-mta -C/etc/mail/localhost.cf -bd -q30m&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That should keep the thing running a little longer without running out of disk. Actually, /var/mail is on the MFS, so it will keep it from running out of ramdisk.&lt;/p&gt;
&lt;p&gt;(This post is part of &lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-21-building-an-alix-firewall" &gt;Building an ALIX firewall&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>Setting up BIND on the ALIX firewall</title><link>https://andrewmemory.acornwall.net/blog/2012-06-27-setting-up-bind-on-the-alix-firewall/</link><pubDate>Wed, 27 Jun 2012 23:23:07 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-06-27-setting-up-bind-on-the-alix-firewall/</guid><description>&lt;p&gt;Setting up BIND is probably the part that took more thought than any other when building the firewall. This is not because of any particular technical challenges; rather, BIND is managed by a consortium and its doc is&amp;hellip; &lt;a href="http://www.isc.org/files/Bv9.4ARM.pdf" target="_blank" rel="noreferrer"&gt;voluminous&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the end, I went with the default /var/named/etc/named.conf on the assumption that it would do the right thing. According to its comment, it does both &amp;ldquo;recursive and authoritative queries using one cache,&amp;rdquo; which is what I want.&lt;/p&gt;
&lt;p&gt;There are four files that need to change:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;/etc/rc.conf&lt;/li&gt;
&lt;li&gt;/var/named/etc/named.conf&lt;/li&gt;
&lt;li&gt;/var/named/master/mydomain.net&lt;/li&gt;
&lt;li&gt;/var/name/master/mydomain.net.rev&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The last two can be named anything, but I stuck with conventions as I saw them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt; Unlike everything up to now, the BIND files live on /var/. In flashrd, /var gets unpacked at boot time into a RAM disk. So you need to save any changes you make somewhere else. &lt;strong&gt;Do not reboot&lt;/strong&gt; until you&amp;rsquo;ve saved your changes! Ultimately, we&amp;rsquo;ll put these changes in /flash/var.tar so they get re-created when the device reboots.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;/etc/rc.conf&lt;/strong&gt; To enable named, change: &lt;code&gt;named_flags=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;/var/named/etc/named.conf&lt;/strong&gt; I used the default named.conf, which is really just a copy of named-simple.conf.&lt;/p&gt;
&lt;p&gt;I made one addition in the options section:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; forwarders { 8.8.8.8; };&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This tells DNS to look for answers at the Google DNS server if it can&amp;rsquo;t find the answer on the local DNS server. (Actually, I put a few DNS servers that were specific to my ISP, but the Google server will work too.)&lt;/p&gt;
&lt;p&gt;I also made a few changes near the end:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;// Master zones
//
zone &amp;#34;mydomain.net&amp;#34; {
type master;
file &amp;#34;master/mydomain.net&amp;#34;;
};
// Reverse mappings for mydomain.net domain
zone &amp;#34;150.168.192.in-addr.arpa&amp;#34; in {
type master;
file &amp;#34;master/mydomain.net.rev&amp;#34;;
};&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This tells named to look in /var/named/master/mydomain.net for mappings of mydomain.net, and to look in /var/named/master/mydomain.net.rev for mappings of 192.168.150.*.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;/var/named/master/mydomain.net&lt;/strong&gt; Here&amp;rsquo;s my mydomain.net:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;mydomain.net. IN SOA firewall.mydomain.net. myemail.yahoo.com. (
1 ; Serial
10800 ; Refresh after 3 hours
3600 ; Retry after 1 hour
604800 ; Expire after 1 week
86400 ) ; Minimum TTL of 1 day
;
; Name Servers
;
mydomain.net. IN NS firewall.mydomain.net.
;
; Host addresses
;
localhost.mydomain.net. IN A 127.0.0.1
firewall.mydomain.net. IN A 192.168.150.1
firesign.mydomain.net. IN A 192.168.150.170
frantics.mydomain.net. IN A 192.168.150.171
bundolo.mydomain.net. IN A 192.168.150.172&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The first bit says my domain is called mydomain.net. I&amp;rsquo;ve published my email as &lt;a href="mailto:myemail@yahoo.com" &gt;myemail@yahoo.com&lt;/a&gt; (but note the dot instead of the at sign there).&lt;/p&gt;
&lt;p&gt;The next bit is serial number / expiration times. You&amp;rsquo;re supposed to bump up the serial number every time you edit, but I usually just kill and restart named.&lt;/p&gt;
&lt;p&gt;After that, I say that the firewall will be the nameserver for the domain.&lt;/p&gt;
&lt;p&gt;Next is the interesting bit: the mapping of host names to host addresses. They must all end in . because BIND requires it. It&amp;rsquo;s very easy to miss a . in your config file and be confused about why things aren&amp;rsquo;t working.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;/var/name/master/mydomain.net.rev&lt;/strong&gt; In addition to DNS doing lookup for names, it usually also does lookup for IP addresses. This is what you get when you do nslookup 192.168.150.1, for instance. The reverse domain name file holds that:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;
150.168.192.in-addr.arpa. IN SOA firewall.mydomain.net. myemail.yahoo.com. (
1 ; Serial
10800 ; Refresh after 3 hours
3600 ; Retry after 1 hour
604800 ; Expire after 1 week
86400 ) ; Minimum TTL of 1 day
;
; Name Servers
;
150.168.192.in-addr.arpa. IN NS firewall.mydomain.net.
;
; Addresses point to canonical name
;
1.150.168.192.in-addr.arpa. IN PTR firewall.mydomain.net.
170.150.168.192.in-addr.arpa. IN PTR firesign.mydomain.net.
171.150.168.192.in-addr.arpa. IN PTR frantics.mydomain.net.
172.150.168.192.in-addr.arpa. IN PTR bundolo.mydomain.net.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Once again, watch for . characters at the end of .arpa. and .net.&lt;/p&gt;
&lt;p&gt;At this point, you can kill and restart named, then: &lt;code&gt;nslookup server localhost frantics&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You should see something like:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Server: localhost
Address: 127.0.0.1#53
Name: frantics.mydomain.net
Address: 192.168.150.171&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;/etc/resolv.conf.tail&lt;/strong&gt; The DHCP client overwrites /etc/resolv.conf, but then appends whatever/s in /etc/resolv.conf.tail to that. So let&amp;rsquo;s tell OpenBSD that Change /etc/resolv.conf to point to the running nameserver:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;nameserver 192.168.150.1
domain mydomain.net
search mydomain.net
lookup bind file&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This sets up the firewall as the nameserver to look for, tells what my domain is, says to search foo.mydomain.net when looking for foo, and to look up via bind first and then /etc/hosts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;/etc/dhcpd.conf&lt;/strong&gt; Now is a good time to change dhcpd.conf to point to your nameserver instead of someone else:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;option domain-name-servers 192.168.150.1;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Save those changes&lt;/strong&gt; To save the changes that are in /var, use the following command: &lt;code&gt;tar cf /flash/var.tar -C /var .&lt;/code&gt; Might as well save a copy somewhere else too: &lt;code&gt;tar cf /root/named.tar /var/named&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Things are saved away as well as they&amp;rsquo;re going to be; time to reboot and hope you didn&amp;rsquo;t miss anything!&lt;/p&gt;
&lt;p&gt;(This post is part of &lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-21-building-an-alix-firewall" &gt;Building an ALIX firewall&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>Setting up PF for the ALIX firewall</title><link>https://andrewmemory.acornwall.net/blog/2012-06-26-setting-up-pf-for-the-alix-firewall/</link><pubDate>Tue, 26 Jun 2012 23:09:49 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-06-26-setting-up-pf-for-the-alix-firewall/</guid><description>&lt;p&gt;The next step on the firewall is to set up the packet filter PF. Most of what I do here comes from the &lt;a href="http://www.openbsd.org/faq/pf/" target="_blank" rel="noreferrer"&gt;OpenBSD PF FAQ&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setting up PF itself&lt;/strong&gt; The file to edit is /etc/pf.conf. Here&amp;rsquo;s mine:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# macros
int_if=&amp;#34;vr0&amp;#34;
ext_if=&amp;#34;vr1&amp;#34;
# FTP Proxy rules
anchor &amp;#34;ftp-proxy/*&amp;#34;
pass in quick on $int_if inet proto tcp to any port ftp \
divert-to 127.0.0.1 port 8021
# options
set block-policy return
set loginterface $ext_if
set skip on lo
# match rules
match out on egress inet from !(egress) to any nat-to (egress:0)
# filter rules
block in log
pass out quick
antispoof quick for { lo $int_if }
# uncomment this to respond to pings
# pass in inet proto icmp all icmp-type echoreq
pass in on $int_if&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s basically the example config file for home or small office, with a couple of changes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I define an int_if and ext_if for internal network and external network&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t have any port forwarding from outside through to the inside network except ftp-proxy&lt;/li&gt;
&lt;li&gt;I block all incoming ICMP traffic (which is broken according to spec, but might keep me safer from denial of service attacks).&lt;/li&gt;
&lt;li&gt;I keep port 22 closed on the firewall machine.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Basically, I present a blank wall to the Internet. Traffic I initiate can get out, but outside doesn&amp;rsquo;t get in except via ftp-proxy.&lt;/p&gt;
&lt;p&gt;One thing to note is that if you mess up pf, you can get into a state where you can&amp;rsquo;t talk to your ALIX over the network. So make sure you have a serial port handy to talk to it. I&amp;rsquo;d recommend making changes to pf.conf over serial, and then testing with the network.&lt;/p&gt;
&lt;p&gt;To test, run:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;pfctl -F all
pfctl -f /etc/pf.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The first command flushes whatever existing PF config is there; the second command loads your new pf config.&lt;/p&gt;
&lt;p&gt;Next, hook up a machine to the switch that&amp;rsquo;s connected to the LAN side of the firewall, and see if you have Internet. If you do, life is good!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Getting FTP running&lt;/strong&gt; You might have noticed I use ftp-proxy in my pf.conf. That&amp;rsquo;s a daemon that needs to be enabled in /etc/rc.conf: &lt;code&gt;ftpproxy_flags=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;According to the &lt;a href="http://www.openbsd.org/faq/pf/ftp.html#client" target="_blank" rel="noreferrer"&gt;PF FAQ&lt;/a&gt;, you can run ftp-proxy to get the daemon going, but I rebooted instead after changing /etc/rc.conf. Also according to the FAQ, some (fussy) clients may need &amp;ldquo;-r&amp;rdquo; on ftpproxy_flags.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blocking IP addresses using PF&lt;/strong&gt; I haven&amp;rsquo;t done this before, but I wanted to try blocking ad servers by IP address using PF. Some instructions are &lt;a href="http://www.cyberciti.biz/faq/opebsd-pf-firewall-block-subnets-ip-address/" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My list of IP addresses came from the excellent &lt;a href="http://pgl.yoyo.org/adservers/" target="_blank" rel="noreferrer"&gt;pgl.yoyo.org/adservers&lt;/a&gt; site. I picked &amp;ldquo;list ad server IP addresses&amp;rdquo; as plain HTML text, checked the &amp;ldquo;view list as plain text&amp;rdquo; button, and pressed &amp;ldquo;go&amp;rdquo;. This gave me a URL that I copied.&lt;/p&gt;
&lt;p&gt;I wanted a semi-automatic way to download this list. Luckily, OpenBSD&amp;rsquo;s ftp is a lot more than plain FTP. You can use it instead of wget/curl/etc. Here&amp;rsquo;s the command I used:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;ftp -o /etc/pf.blocked.ip.conf &amp;#34;http://pgl.yoyo.org\
/adservers/iplist.php?ipformat=plain&amp;amp;;showintro=1&amp;amp;\
mimetype=plaintext&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then I updated my pf.conf to account for that:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# macros
int_if=&amp;#34;vr0&amp;#34;
ext_if=&amp;#34;vr1&amp;#34;
# Table of IP addresses to block
table &amp;lt;blockedips&amp;gt; persist file &amp;#34;/etc/pf.blocked.ip.conf&amp;#34;
# FTP Proxy rules
anchor &amp;#34;ftp-proxy/*&amp;#34;
pass in quick on $int_if inet proto tcp to any port ftp \
divert-to 127.0.0.1 port 8021
# options
set block-policy return
set loginterface $ext_if
set skip on lo
# match rules
match out on egress inet from !(egress) to any nat-to (egress:0)
# filter rules
# These two rules block traffic from blacklisted IP addresses
block drop in quick on $ext_if from &amp;lt;blockedips&amp;gt; to any
block return out quick from any to &amp;lt;blockedips&amp;gt;
block in log
pass out quick
antispoof quick for { lo $int_if }
# pass in inet proto icmp all icmp-type $icmp_types
pass in on $int_if&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;m not sure if this strategy will work long term. Previously I excluded ad servers in named instead. Excluding by IP address seems to take less RAM (I&amp;rsquo;ve got about 163M free of my 256M RAM with this table loaded) and has the advantage of blocking sneaky servers that use IP address URLs. The downside is that if another server uses the same IP address, I won&amp;rsquo;t get the content, and I have no real way to unblock by name if I need to.&lt;/p&gt;
&lt;p&gt;At any rate, to update, I just need to do the ftp command again, and then: &lt;code&gt;pfctl -t blockedips -T replace -f /etc/pf.blocked.ip.conf&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;(This post is part of &lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-21-building-an-alix-firewall" &gt;Building an ALIX firewall&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>Setting up networking for the ALIX firewall</title><link>https://andrewmemory.acornwall.net/blog/2012-06-24-setting-up-networking-for-the-alix-firewall/</link><pubDate>Sun, 24 Jun 2012 17:41:36 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-06-24-setting-up-networking-for-the-alix-firewall/</guid><description>&lt;p&gt;The next step in &lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-21-building-an-alix-firewall" &gt;building an ALIX firewall&lt;/a&gt; is to set up networking.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setting the hostname&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Edit the file /etc/myname to be the hostname you want (don&amp;rsquo;t forget to rw first if you need to).&lt;/li&gt;
&lt;li&gt;Run: &lt;code&gt;hostname `cat /etc/myname`&lt;/code&gt; to set the hostname in lieu of rebooting.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Figuring out which port is which&lt;/strong&gt; On my ALIX, Ethernet port vr1 is the port nearest to the serial port and vr0 is the one nearest to the power cable. I figured this out by plugging one port into the network and running ifconfig. In my case I saw:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;vr1: flags=8802 mtu 1500
lladdr 00:0d:ba:36:d9:30
priority: 0
media: Ethernet autoselect (none)
status: active&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;whereas vr0 had status: no carrier. That told me that vr1 was the one on the network. I labelled the ports so I wouldn&amp;rsquo;t forget. (Since my plan is to have a firewall with one port for the internal LAN and another for the world, I used labels vr0:lan and vr1:world.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setting up the DHCP client on vr1&lt;/strong&gt; My ISP assigns me an IP address using DHCP. In the older flashdist, you had to edit /etc/rc to start up dhclient to get this address. With flashrd, it&amp;rsquo;s easier once again: &lt;code&gt;echo dhcp &amp;gt; /etc/hostname.vr1 sh /etc/netstart&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;At this point the ALIX will go to your local network and request an IP address via dhclient. Hopefully you have a DHCP server somewhere on your network; otherwise you&amp;rsquo;ll need to read &lt;a href="http://www.openbsd.org/faq/faq6.html" target="_blank" rel="noreferrer"&gt;Section 6 of the OpenBSD FAQ&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setting up the LAN interface&lt;/strong&gt; I decided that I wouldn&amp;rsquo;t mess around with IPv6 just yet&amp;hellip; I want to set up a NAT firewall using IPv4. To start with, I had to pick an IP address for my internal network. I&amp;rsquo;m going to use my ALIX box for DHCP, name resolution, and as a gateway. (Yes, I know this is bad practice&amp;hellip; but I&amp;rsquo;m on a limited budget!)&lt;/p&gt;
&lt;p&gt;I picked address 192.168.150.* for my network. This means my firewall will be 192.168.150.1, and I&amp;rsquo;ll use that as the gateway address of other machines which are its DHCP clients.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo inet 192.168.150.1 255.255.255.0 NONE &amp;gt; /etc/hostname.vr0 sh /etc/netstart&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Run the dhcpd server&lt;/strong&gt; So that the firewall can serve IP addresses, it needs to have dhcpd enabled. The right place to do this is in a section of rc.conf.local, but I got lazy and edited it in /etc/rc.conf. If I had to do this over, I&amp;rsquo;d use /etc/rc.conf.local. The code I changed was: &lt;code&gt;dhcpd_flags=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Next we need to tell it what the subnet is that it will serve DHCP addresses to. This is defined in /etc/dhcpd.conf: &lt;code&gt;option domain-name &amp;quot;mydomain.net&amp;quot;; option domain-name-servers 8.8.8.8; subnet 192.168.150.0 netmask 255.255.255.0 { option routers 192.168.150.1; range 192.168.150.32 192.168.150.127; # host static-client { # hardware ethernet 22:33:44:55:66:77; # fixed-address 192.168.1.200; # } # host pxe-client { # hardware ethernet 02:03:04:05:06:07; # filename &amp;quot;pxeboot&amp;quot;; # next-server 192.168.1.1; # }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In my case for absolutely arbitrary reasons, I said to serve from 192.168.150.32 to 192.168.150.63. I left the pxe-client and static-client things in case I needed them later.&lt;/p&gt;
&lt;p&gt;Also note that right now I&amp;rsquo;m using Google&amp;rsquo;s 8.8.8.8 as the DNS server. I could have used my ISP&amp;rsquo;s instead - either way, it&amp;rsquo;s going to change once I get BIND running on the firewall.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Add myself to hosts&lt;/strong&gt; This is a good time to add myself to the /etc/hosts file (both under the short name and fully-qualified domain name): &lt;code&gt;192.168.150.1 myname myname.mydomain.net&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enabling port forwarding&lt;/strong&gt; Next we need to allow the firewall to forward IPv4 traffic. To do this, edit /etc/sysctl.conf: &lt;code&gt;net.inet.ip.forwarding=1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update the time from the network&lt;/strong&gt; Since the ALIX doesn&amp;rsquo;t have a real time clock that stores the time, we need to update it from the network every time we reboot. This is in /etc/rc.conf: &lt;code&gt;ntpd_flags=&amp;quot;-s&amp;quot;&lt;/code&gt; The -s says &amp;ldquo;update the time now to the server time and don&amp;rsquo;t try to adjust it slowly.&amp;rdquo; That&amp;rsquo;s the right thing to do when the box thinks the time is way in the past.&lt;/p&gt;
&lt;p&gt;At this point, I figured it was time to reboot the device and see if everything came up as expected. &lt;code&gt;/sbin/shutdown -r now&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now plug a switch into the vr0:lan port, a computer into the switch, and see if you can get an IP address. You&amp;rsquo;re not doing enough yet to have an Internet connection, but ipconfig /all on a Windows laptop should show a correct IPv4 address, subnet mask, gateway, dhcp server and DNS server. Groovy, you&amp;rsquo;ve got a network!&lt;/p&gt;
&lt;p&gt;(This post is part of &lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-21-building-an-alix-firewall" &gt;Building an ALIX firewall&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>Getting OpenBSD 5.1 on the ALIX firewall</title><link>https://andrewmemory.acornwall.net/blog/2012-06-20-getting-openbsd-5-1-on-the-alix-firewall/</link><pubDate>Wed, 20 Jun 2012 23:11:44 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-06-20-getting-openbsd-5-1-on-the-alix-firewall/</guid><description>&lt;p&gt;Getting OpenBSD on the ALIX used to be quite an effort. You had to figure out what your CF card looked like, enter the right drive parameters, and hope. Now it&amp;rsquo;s dead easy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download the &lt;a href="http://www.nmedia.net/flashrd/images/" target="_blank" rel="noreferrer"&gt;flashrd binary image&lt;/a&gt;. I used flashimg.i386.wd0.com0-20120531.gz, which is root wd0, com0 38400 console. This matches the Alix BIOS default, which also spits out 38400 serial.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unzip the image with gzip -d&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write the image to the CF card. I have Cygwin installed, so I was able to use dd. Since I&amp;rsquo;m running this on Windows 7, I had to open my Cygwin shell as Administrator. The command I used:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;dd if=flashdist.i386.wd0.com0-20120531 of=/dev/sdd bs=128k&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I was pleasantly surprised that dd worked. (I found the device by doing sfdisk -l /dev/sda, then sdb, then sdc, until I found a partition table that looked like my 4 GB flash drive.) I picked 128k as the block size because the image was evenly divisible by that. I don&amp;rsquo;t know if it makes a difference, but I figured why risk it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next I hooked up a DB9 F/F mini null modem to my PC serial port, connected that to the Alix serial port, ran hypertrm (which I had to get from an earlier Windows release) and was talking to OpenBSD. Root password was &amp;ldquo;root&amp;rdquo; (no quotes).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this point I reset the password: &lt;code&gt;rw passwd root ro&lt;/code&gt; rw is the flashrd way to say &amp;ldquo;mount the file system read/write&amp;rdquo;, and ro says &amp;ldquo;mount the file system read-only&amp;rdquo;. flashrd boots up read-only (which saves wear on the flash card) so you need to set it to read/write if you want to do pretty much anything.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s all there is to it!&lt;/p&gt;
&lt;p&gt;(This post is part of &lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-20-building-an-alix-firewall/" &gt;Building an ALIX firewall&lt;/a&gt;)&lt;/p&gt;</description></item><item><title>Building an ALIX firewall</title><link>https://andrewmemory.acornwall.net/blog/2012-06-20-building-an-alix-firewall/</link><pubDate>Wed, 20 Jun 2012 23:02:03 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-06-20-building-an-alix-firewall/</guid><description>&lt;p&gt;It&amp;rsquo;s been a long time since I updated my firewall. Right now it&amp;rsquo;s a &lt;a href="http://www.pcengines.ch/alix2c2.htm" target="_blank" rel="noreferrer"&gt;PC Engines ALIX 2c2&lt;/a&gt; that I&amp;rsquo;ve been really happy with. I used &lt;a href="http://www.nmedia.net/flashdist/" target="_blank" rel="noreferrer"&gt;flashdist&lt;/a&gt; and put &lt;a href="http://openbsd.org/44.html" target="_blank" rel="noreferrer"&gt;OpenBSD 4.4&lt;/a&gt; on it.&lt;/p&gt;
&lt;p&gt;I think that&amp;rsquo;s a winning combination, but it&amp;rsquo;s time to upgrade. First, I want to go to &lt;a href="http://openbsd.org/51.html" target="_blank" rel="noreferrer"&gt;OpenBSD 5.1&lt;/a&gt;. Next, flashdist has been replaced with &lt;a href="http://www.nmedia.net/flashrd/" target="_blank" rel="noreferrer"&gt;flashrd&lt;/a&gt;, which is easier to install and use, and more appropriate for larger CF cards.&lt;/p&gt;
&lt;p&gt;I started by getting an &lt;a href="http://www.pcengines.ch/alix2d2.htm" target="_blank" rel="noreferrer"&gt;ALIX 2d2&lt;/a&gt; (just one more IDE header than the 2c2, not much change). I bought it from &lt;a href="http://www.mini-box.com/s.nl/sc.8/category.19/.f" target="_blank" rel="noreferrer"&gt;mini-box.com&lt;/a&gt;, and I also picked up the custom enclosure for it and a power supply.&lt;/p&gt;
&lt;p&gt;I already had a 4 GB CF card: a Kingston 4GB elite pro 133X, which was new when I built the original firewall. Make sure you have a good CF writer. I&amp;rsquo;ve had failures with cheapies, but got a Kingston FCR-HS219/1 and that worked.&lt;/p&gt;
&lt;p&gt;There are a number of steps to get a working firewall. They are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-20-getting-openbsd-5-1-on-the-alix-firewall/" &gt;Getting OpenBSD 5.1 on the ALIX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-25-setting-up-networking-for-the-alix-firewall" &gt;Setting up networking for the ALIX firewall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-27-setting-up-pf-for-the-alix-firewall" &gt;Setting up PF for the ALIX firewall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2012-06-28-setting-up-bind-on-the-alix-firewall" &gt;Setting up BIND on the ALIX firewall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2012-07-07-final-cleanup-for-the-alix-firewall" &gt;Final cleanup for the ALIX firewall&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Solving Youtube "Cannot Play Video" on Android</title><link>https://andrewmemory.acornwall.net/blog/2012-06-20-solving-youtube-cannot-play-video-on-android/</link><pubDate>Wed, 20 Jun 2012 00:36:48 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-06-20-solving-youtube-cannot-play-video-on-android/</guid><description>&lt;p&gt;Recently, my phone entered a state where it would &amp;ldquo;sort of crash&amp;rdquo; when I tried to play Youtube links using the internal Youtube app. I could play in Flash fine, but if I opened the same link with the Youtube app, it would:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;vibrate twice&lt;/li&gt;
&lt;li&gt;vibrate again&lt;/li&gt;
&lt;li&gt;open a dialog titled &amp;ldquo;Cannot play video&amp;rdquo; with the text &amp;ldquo;Sorry, this video cannot be played&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Lots of users have seen this, but there weren&amp;rsquo;t too many solutions. I started out by uninstalling and reinstalling the Youtube app. No luck there. Then I found &lt;a href="http://forums.androidcentral.com/t-samsung-infuse/107476-cannot-play-video-sorry-video-cannot-played-2.html" title="this AndroidCentral thread" target="_blank" rel="noreferrer"&gt;this AndroidCentral thread&lt;/a&gt; and in particular Sumabot&amp;rsquo;s post.&lt;/p&gt;
&lt;p&gt;That set me down the right path. I didn&amp;rsquo;t want to wipe out as much as he did, but I did do this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the web browser&lt;/li&gt;
&lt;li&gt;Menu -&amp;gt; More -&amp;gt; Settings&lt;/li&gt;
&lt;li&gt;Clear Cache&lt;/li&gt;
&lt;li&gt;Clear history&lt;/li&gt;
&lt;li&gt;Clear all cookie data&lt;/li&gt;
&lt;li&gt;Clear location access&lt;/li&gt;
&lt;li&gt;Reset to default&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I might just have needed to &amp;ldquo;Reset to default&amp;rdquo; - if it happens again that&amp;rsquo;s what I&amp;rsquo;ll try next.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I&amp;rsquo;ve figured out that opening a Youtube video in another window (regardless of cache state) will cause the browser to crash. In my case, just clicking on the link (as opposed to long-pressing and saying &amp;ldquo;Open&amp;rdquo;) seems to work.&lt;/p&gt;</description></item><item><title>Installing new certificates on Android</title><link>https://andrewmemory.acornwall.net/blog/2012-05-12-installing-new-certificates-on-android/</link><pubDate>Sat, 12 May 2012 12:46:02 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-05-12-installing-new-certificates-on-android/</guid><description>&lt;p&gt;Recently I&amp;rsquo;ve encountered a website that is using the certificate &amp;ldquo;Verisign Class 3 Secure Server CA - G3&amp;rdquo;. Unfortunately, my Android device (Samsung Infuse running Froyo 2.2.1) doesn&amp;rsquo;t know about that certificate, so I get a warning.&lt;/p&gt;
&lt;p&gt;Installing a certificate on this device is not hard, but there are one or two tricks.&lt;/p&gt;
&lt;p&gt;First, download the certificate. For me it was a Verisign certificate. I did a search on the certificate title and determined it corresponded to the Verisign cert SVRSecureG3.cer, so I went to &lt;a href="http://crl.verisign.com" target="_blank" rel="noreferrer"&gt;crl.verisign.com&lt;/a&gt; and grabbed it. (Note that .cer is the certificate and .crl is the certificate revocation list.)&lt;/p&gt;
&lt;p&gt;Once you have the .cer, it&amp;rsquo;s unfortunately in binary mode. Use openssl (which is included as part of Cygwin for Windows users) to convert it to a .crt:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ openssl x509 -in SVRSecureG3.cer -inform DER -out SVRSecureG3.crt -outform PEM&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Install that .crt on the root of the removable SD card. For Samsung devices, this means it will have to be in /mnt/sdcard/external_sd/.&lt;/p&gt;
&lt;p&gt;Go to the Settings app, and select &amp;ldquo;Location and security&amp;rdquo;, then &amp;ldquo;Install encrypted certificates&amp;rdquo;. You will be prompted with a dialog for the Certificate name; I just took the default. Click &amp;ldquo;OK&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll be prompted to enter a password for credential storage. &lt;strong&gt;Do not&lt;/strong&gt; forget this password.&lt;/p&gt;
&lt;p&gt;At this point, the credential has been imported. Next time you visit the website, you should not get a bad certificate.&lt;/p&gt;</description></item><item><title>Rooting the Samsung Infuse with SuperOneClick</title><link>https://andrewmemory.acornwall.net/blog/2012-05-06-rooting-the-samsung-infuse-with-superoneclick/</link><pubDate>Sun, 06 May 2012 20:39:07 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-05-06-rooting-the-samsung-infuse-with-superoneclick/</guid><description>&lt;p&gt;After spending ages trying to root my Samsung Infuse (i997) running Android 2.2 with SuperOneClick on my Windows XP box, I finally did the right thing: blew it away and installed Windows 7. With that, I was able to root the Infuse this afternoon.&lt;/p&gt;
&lt;p&gt;I used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.multiupload.com/VGCN3ZTFM8" title="SuperOneClick v2.3.1" target="_blank" rel="noreferrer"&gt;SuperOneClick 2.3.1&lt;/a&gt; (or get it from &lt;a href="http://shortfuse.org/" target="_blank" rel="noreferrer"&gt;shortfuse.org&lt;/a&gt; if you don&amp;rsquo;t trust random links from a blog)&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.samsung.com/us/support/owners/product/SGH-I997ZKAATT#content2" target="_blank" rel="noreferrer"&gt;Samsung i997 driver version 5_2_0_2&lt;/a&gt; from the Samsung US website&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After rooting, I rebooted the device. It worked with no problems. I shot the developer of SuperOneClick a donation &amp;lsquo;cause why not.&lt;/p&gt;
&lt;p&gt;Later I installed TitaniumBackup, which gave me a warning message about the access rights to su and offered to correct it. I said to go ahead and it did:&lt;/p&gt;
&lt;p&gt;Access rights on the &amp;ldquo;su&amp;rdquo; binary were successfully correced from &amp;ldquo;0:2000 &lt;/p&gt;
\[6755\]&lt;p&gt;&amp;rdquo; to &amp;ldquo;0:0 &lt;/p&gt;
\[6755\]&lt;p&gt;&amp;rdquo;. Please reboot your device for the changes to apply.&lt;/p&gt;
&lt;p&gt;I think that changed it from root.shell to root.root.&lt;/p&gt;
&lt;p&gt;At any rate, now I know I can root the Infuse.&lt;/p&gt;
&lt;p&gt;I wasn&amp;rsquo;t able to root an Infuse running 2.3.5 Gingerbread. Instead I had to use &lt;a href="http://forum.xda-developers.com/showthread.php?t=1613523" target="_blank" rel="noreferrer"&gt;this XDA pos&lt;/a&gt;t, Odin, and reflash a new ROM.&lt;/p&gt;</description></item><item><title>Building a quiet MythTV box - selecting a case</title><link>https://andrewmemory.acornwall.net/blog/2012-04-20-building-a-quiet-mythtv-box-selecting-a-case/</link><pubDate>Fri, 20 Apr 2012 23:34:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-04-20-building-a-quiet-mythtv-box-selecting-a-case/</guid><description>&lt;p&gt;I&amp;rsquo;ve started looking around for a quiet but thermally good case for a MythTV box. My first thought was to do an HTPC case - the &lt;a href="http://www.lian-li.com/v2/en/product/product06.php?pr_index=580&amp;amp;cl_index=1&amp;amp;sc_index=26&amp;amp;ss_index=68" target="_blank" rel="noreferrer"&gt;Lian Li HTPC C60&lt;/a&gt; looked good.&lt;/p&gt;
&lt;p&gt;But then I started worrying about airflow around the case. I&amp;rsquo;ve got a fairly narrow spot to put it in - about 46 cm - so a PC that&amp;rsquo;s 44 cm wide doesn&amp;rsquo;t leave a lot of room for cooling.&lt;/p&gt;
&lt;p&gt;I decided to look into mini towers instead. The &lt;a href="http://www.lian-li.com/v2/en/product/product06.php?pr_index=567&amp;amp;cl_index=1&amp;amp;sc_index=25&amp;amp;ss_index=63" target="_blank" rel="noreferrer"&gt;Lian Li V600F&lt;/a&gt; looks like it would be nice, but it has these ugly blue fans.&lt;/p&gt;
&lt;p&gt;I also looked into the &lt;a href="http://www.quietpcusa.com/NZXT-H2-Classic-Silent-Midtower-Chassis-P800C80.aspx" target="_blank" rel="noreferrer"&gt;NZXT H2&lt;/a&gt; (some were saying it was too flimsy), &lt;a href="http://www.antec.com/Believe_it/product.php?id=MTgwOA==&amp;amp;lan=us" target="_blank" rel="noreferrer"&gt;Antec P183&lt;/a&gt; (too tall, not a mini tower) and &lt;a href="http://www.silverstonetek.com/product.php?pid=303" target="_blank" rel="noreferrer"&gt;Silverstone TJ-8e&lt;/a&gt; (an 18 inch fan in front, but only that. How hard to get a replacement when it dies?)&lt;/p&gt;
&lt;p&gt;Now I&amp;rsquo;m leaning towards the L&lt;a href="http://www.lian-li.com/v2/en/product/product06.php?pr_index=314&amp;amp;cl_index=1&amp;amp;sc_index=25&amp;amp;ss_index=62" target="_blank" rel="noreferrer"&gt;ian Li B10&lt;/a&gt;. It&amp;rsquo;s too bad that &lt;a href="http://www.silentpcreview.com/" target="_blank" rel="noreferrer"&gt;SPCR&lt;/a&gt; hasn&amp;rsquo;t reviewed it - they seem to know a thing or two about quiet and heat.&lt;/p&gt;</description></item><item><title>Airnet AES108P power supply</title><link>https://andrewmemory.acornwall.net/blog/2012-04-03-airnet-aes108p-power-supply/</link><pubDate>Tue, 03 Apr 2012 22:05:30 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-04-03-airnet-aes108p-power-supply/</guid><description>&lt;p&gt;I have recently moved, which means I&amp;rsquo;ve disconnected all my wall warts and had to reconnect them.&lt;/p&gt;
&lt;p&gt;Normally, this isn&amp;rsquo;t a problem - but for one ethernet switch, it was. The box is labelled &amp;ldquo;Fast Ethernet Switch&amp;rdquo; with no other markings on the front.&lt;/p&gt;
&lt;p&gt;The back has 8 ethernet jacks (ok so far) and a DC tip connector labelled &amp;ldquo;AC IN&amp;rdquo;. Great. The DC connector looked like a standard 5.5 mm outside / 2.1 or 2.5mm inside connector.&lt;/p&gt;
&lt;p&gt;Markings on the bottom of the box: ES3108CH3 and AES108P. That appears to mean it was an Airnet AES108P, also known as a Pro-Nets ES3108CH3. Airnet appears to be out of business, and Pro-Nets is a Chinese exporter who lists it as &amp;ldquo;Power: 1w&amp;rdquo; (but no voltage).&lt;/p&gt;
&lt;p&gt;So I cracked the box. The circuit board had a marking I took to indicate centre positive (which would mean &lt;em&gt;not&lt;/em&gt; AC in), so I attached the bench supply and worked my way up from 0.&lt;/p&gt;
&lt;p&gt;The device needs slightly more than 5v to turn on. I was getting it booting up at around 5.6 v, drawing about 520 ma with 3 network cables attached. I suspect it came with a non-switching wall wart rated for 5v. I tried with a 6v transformer I had handy, and that was too much. (Incidentally, if it&amp;rsquo;s nominally 5v, that&amp;rsquo;s more like 2.5w than 1w.)&lt;/p&gt;
&lt;p&gt;I fear I have let the magic smoke out now&amp;hellip; I had it running and moving packets at a little higher than 5.5 v, but now it boots up partway and croaks. Sigh.&lt;/p&gt;
&lt;p&gt;Perhaps this will be helpful to someone else who&amp;rsquo;s not sure what to use. Seems like a non-switching 5v 1a transformer would be about right. A 1500ma switching 5v transformer I had did not work.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not taking responsibility if this smokes your switch&amp;hellip; or burns down your house. &lt;strong&gt;Use this info at your own risk&lt;/strong&gt;. Let me know in the comments if it worked or didn&amp;rsquo;t.&lt;/p&gt;</description></item><item><title>Building a quiet MythTV box - step 1 - thinking aloud</title><link>https://andrewmemory.acornwall.net/blog/2012-04-01-building-a-quiet-mythtv-box-step-1-thinking-aloud/</link><pubDate>Sun, 01 Apr 2012 01:32:13 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2012-04-01-building-a-quiet-mythtv-box-step-1-thinking-aloud/</guid><description>&lt;p&gt;Due to decreased WAF for the old MythTV box, I&amp;rsquo;m looking into building a quieter one. I&amp;rsquo;ve decided to do a couple of things differently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use HDHomeRun for capture cards. That way, I won&amp;rsquo;t be stuck to a particular bus architecture. It also means the capture cards won&amp;rsquo;t be generating heat in the case.&lt;/li&gt;
&lt;li&gt;Use a pair of 5400 RPM hard drives (maybe a 2.5&amp;quot; one for the OS, and a 3.5&amp;quot; one for the recordings? Need to have fans on all of them to cool them down.&lt;/li&gt;
&lt;li&gt;Replace all the fans with FDB or maglev bearing fans&lt;/li&gt;
&lt;li&gt;Use an external PSU like the &lt;a href="http://www.mini-box.com/picoPSU-192-XT-192W-Adapter-Power-Kit" target="_blank" rel="noreferrer"&gt;PicoPSU&lt;/a&gt; or something like that. &lt;a href="http://outsidethestb.blogspot.com/2011/02/dc-psu-mouting-plate-prototype.html" target="_blank" rel="noreferrer"&gt;Here&amp;rsquo;s an adapter&lt;/a&gt; to make it fit in a standard fan bay. (This might also be a good idea for ham radio PSUs&amp;hellip;)&lt;/li&gt;
&lt;li&gt;Use an HTPC case or at least a quiet PC case&lt;/li&gt;
&lt;li&gt;Probably end up with an nVidia video card.&lt;/li&gt;
&lt;li&gt;I think I want a core2 duo 3.1 MHz or so motherboard/ processor combo&lt;/li&gt;
&lt;li&gt;Does the Pico PSU mean I won&amp;rsquo;t be able to drive a DVD player? Maybe another external one (eSATA?) Am I going to end up with a bunch of individual set top boxes?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The CPU cooling fans, video card and hard drives should generate most of the heat (and noise). Need to figure out how much power a video card uses.&lt;/p&gt;</description></item><item><title>Migrating from Palm to Android: essential apps</title><link>https://andrewmemory.acornwall.net/blog/2011-11-30-migrating-from-palm-to-android-essential-apps/</link><pubDate>Wed, 30 Nov 2011 14:43:13 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-11-30-migrating-from-palm-to-android-essential-apps/</guid><description>&lt;p&gt;I&amp;rsquo;ve been gradually moving from Palm to Android. In some ways this is a step back, because Android is a lot less polished than Palm. On the other hand, it&amp;rsquo;s a platform where people are actually writing code.&lt;/p&gt;
&lt;p&gt;My perspective is a little different from most: I didn&amp;rsquo;t want to rely on Google to sync my calendar, contacts, etc. I wanted to do that myself. Palm makes it easy; Android makes it hard.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m running a Samsung Infuse with Android 2.2.1 currently. Here are the apps I&amp;rsquo;ve discovered so far to make the Android experience easier. Because I&amp;rsquo;m cheap, they&amp;rsquo;re all free unless otherwise noted:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The calendar app is the most obvious place where Android flunks. I&amp;rsquo;ve been able to get by with &lt;a href="https://market.android.com/details?id=org.withouthat.acalendar" title="aCalendar" target="_blank" rel="noreferrer"&gt;aCalendar&lt;/a&gt; for calendar display. It is a lot like the Palm app, and is actively supported. Android also sucks with alarms, so I use &lt;a href="https://market.android.com/details?id=de.foobarsoft.calendareventreminder" title="Calendar Event Reminder" target="_blank" rel="noreferrer"&gt;Calendar Event Reminder&lt;/a&gt; (paid app, around USD 2.50) so I get more than a single &amp;ldquo;ding&amp;rdquo; when the alarm goes off. Finally, I use &lt;a href="https://market.android.com/details?id=at.aichbauer.ical" title="iCal Import/Export" target="_blank" rel="noreferrer"&gt;iCal Import/Export&lt;/a&gt; to get my calendar events out to the SD card. This is no longer supported by its author unfortunately. It relies on unsupported API as well to get calendar data - but so far that&amp;rsquo;s the only one. (I heard from the author of aCalendar that he&amp;rsquo;s thinking about adding export code, though, so there may be hope there. He&amp;rsquo;s got a Pro verison due out soon, and I&amp;rsquo;m hopeful. I&amp;rsquo;ll definitely pay for it when it comes out.)&lt;/li&gt;
&lt;li&gt;To see a percentage representation of battery life (similar to what you&amp;rsquo;d get on a Palm when you tap the battery icon) I use &lt;a href="https://market.android.com/details?id=com.darshancomputing.BatteryIndicator" title="Battery Indicator" target="_blank" rel="noreferrer"&gt;Battery Indicator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I had Noah Pro on my Palm, so I wanted a good dictionary app. &lt;a href="https://market.android.com/details?id=com.socialnmobile.colordict" title="ColorDict Dictionary Wikipedia" target="_blank" rel="noreferrer"&gt;ColorDict Dictionary Wikipedia&lt;/a&gt; includes all of Noah Pro, and additional files and the ability to do web searches if you&amp;rsquo;re online. Very nice. (One hint: you need to install dictionary files separately, then run them before you can use them. Looks like a lot of Android users can&amp;rsquo;t figure that one out.)&lt;/li&gt;
&lt;li&gt;Of course, you&amp;rsquo;ll need &lt;a href="https://market.android.com/details?id=com.access_company.graffiti" title="Graffiti" target="_blank" rel="noreferrer"&gt;Graffiti&lt;/a&gt; for the real experience. I was happy enough with it that I went to the paid version, &lt;a href="https://market.android.com/details?id=com.access_company.graffiti_pro" title="Graffiti Pro" target="_blank" rel="noreferrer"&gt;Graffiti Pro&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I had Yaps for password storage on the Palm. I eventually migrated to &lt;a href="https://market.android.com/details?id=com.android.keepass" title="KeePassDroid" target="_blank" rel="noreferrer"&gt;KeePassDroid&lt;/a&gt;. Here are more details about &lt;a href="https://andrewmemory.acornwall.net/blog/2011-10-01-converting-yaps-to-keepassdroid/" &gt;migrating from Yaps to KeePassDroid&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Android search is also pretty lame, especially in contacts. I use &lt;a href="https://market.android.com/details?id=com.xphonesoftware.android.asearch" title="Power Search" target="_blank" rel="noreferrer"&gt;Power Search&lt;/a&gt; when I really want to find something.&lt;/li&gt;
&lt;li&gt;On Palm, I loved EasyCalc. The best calculator I&amp;rsquo;ve found so far is &lt;a href="https://market.android.com/details?id=uk.co.nickfines.RealCalc" title="RealCalc scientific calculator" target="_blank" rel="noreferrer"&gt;RealCalc Scientific Calculator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For games, I installed the Ken Magic &lt;a href="https://market.android.com/details?id=com.kmagic.solitaire" title="Solitaire" target="_blank" rel="noreferrer"&gt;Solitaire&lt;/a&gt;, since it seemed least likely to want to leak my info all over the world.&lt;/li&gt;
&lt;li&gt;To back up applications themselves, I use &lt;a href="https://market.android.com/details?id=com.metago.astro" title="ASTRO File Manager" target="_blank" rel="noreferrer"&gt;ASTRO File Manager&lt;/a&gt;. This app is able to copy existing apps that don&amp;rsquo;t have the copy-prevent bit set onto the SD card.&lt;/li&gt;
&lt;li&gt;Finally, to copy all the files up to a server, I use the SAMBA client &lt;a href="https://market.android.com/details?id=lysesoft.andsmb" title="AndSMB" target="_blank" rel="noreferrer"&gt;AndSMB&lt;/a&gt; rather than messing around with USB or swapping out SD cards.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ve installed &lt;a href="https://market.android.com/details?id=com.luckydroid.droidbase" title="Memento Database" target="_blank" rel="noreferrer"&gt;Memento Database&lt;/a&gt; as a replacement for JFile, but so far have not transferred my data over, so I can&amp;rsquo;t say how good it is.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The most surprising thing is the app I haven&amp;rsquo;t found a replacement for yet - the Notepad! All the apps I have seen so far want to sync to the cloud, rather than letting me export to SD. Bummer. I did use &lt;a href="https://market.android.com/details?id=com.srb.app.wfdp" title="What&amp;#39;s for Dinner Premium" target="_blank" rel="noreferrer"&gt;What&amp;rsquo;s for Dinner Premium&lt;/a&gt; for my notes which are recipes, and I think it&amp;rsquo;s great. (I got this free on the Amazon app store for their free app of the day; normally it&amp;rsquo;s about USD 2.00.) Right now I&amp;rsquo;m using the Samsung Memo app (installed with their Android builds) for the rest, but it can&amp;rsquo;t export so I&amp;rsquo;m not using it for much. If you know of a Notepad app that doesn&amp;rsquo;t want network access, please let me know in the comments.&lt;/p&gt;</description></item><item><title>Converting YAPS to KeePassDroid</title><link>https://andrewmemory.acornwall.net/blog/2011-10-01-converting-yaps-to-keepassdroid/</link><pubDate>Sat, 01 Oct 2011 01:19:56 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-10-01-converting-yaps-to-keepassdroid/</guid><description>&lt;p&gt;When moving from Palm to Android, one of my big concerns was password management. I had about a hundred passwords stored in &lt;a href="http://www.msbsoftware.ch/yaps.html" title="YAPS website" target="_blank" rel="noreferrer"&gt;YAPS&lt;/a&gt;, which is a great Palm password store.&lt;/p&gt;
&lt;p&gt;I looked around and decided that &lt;a href="http://www.keepassdroid.com/" target="_blank" rel="noreferrer"&gt;KeePassDroid&lt;/a&gt; would suit nicely. It&amp;rsquo;s open source, does decent encryption, and is free.&lt;/p&gt;
&lt;p&gt;That brought up the question: how do I convert from YAPS to KeePassDroid? I didn&amp;rsquo;t want to retype everything - and I eventually did manage to get things working. It was a bit of an effort, though - here&amp;rsquo;s what I did.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, get the required components. I used &lt;a href="http://www.palmgear.com/software/showsoftware.cfm?prodID=15490" target="_blank" rel="noreferrer"&gt;YapsView&lt;/a&gt; (not strictly necessary, but it makes things easier), &lt;a href="http://www.cygwin.com/" target="_blank" rel="noreferrer"&gt;cygwin&lt;/a&gt; perl, GNU &lt;a href="#ZgotmplZ" &gt;emacs&lt;/a&gt;, and &lt;a href="http://keepass.info/" target="_blank" rel="noreferrer"&gt;KeePass 2.16&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Export the Palm database into a file called Yaps.txt. I used YapsView to do this, but in theory you could use Yaps to export it to the Palm notepad and then cut &amp;amp; paste that to a file on your desktop.&lt;/li&gt;
&lt;li&gt;Once the file has been exported, convert all instances of \ to \\. I used emacs to do this.&lt;/li&gt;
&lt;li&gt;Convert all instances of &amp;quot; to \&amp;quot; using emacs as well. (Do this after doing \ so you don&amp;rsquo;t expand the \ in \&amp;quot;.)&lt;/li&gt;
&lt;li&gt;Save the modified Yaps.txt.&lt;/li&gt;
&lt;li&gt;Next, I found a perl script that converted Yaps to KeePassX &lt;a href="http://opticalgarbage.com/yaps2keepassx/convert.perl" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;. I hacked that up to create a script I called convertcsv.perl that convertes Yaps to CSV in the KeePass 1.0 format. It is &lt;a href="https://andrewmemory.acornwall.net/blog/2011-10-01-converting-yaps-to-keepassdroid/convertcsv.pl" &gt;convertcsv.pl&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Run &amp;ldquo;perl convertcsv.perl&amp;rdquo; in the same directory as Yaps.txt. This will create yaps.csv.&lt;/li&gt;
&lt;li&gt;Create a new databse in KeePass 2.0. I set it to encrypt notes (under the &amp;ldquo;Protection&amp;rdquo; tab) and used defaults for the rest.&lt;/li&gt;
&lt;li&gt;Import yaps.csv into the database you just created. File -&amp;gt; Import&amp;hellip; KeePass 1.x CSV. I said &amp;ldquo;Overwrite existing&amp;rdquo; but I don&amp;rsquo;t think it makes a difference at this point.&lt;/li&gt;
&lt;li&gt;Now move all the passwords to the proper categories in KeePass. This is dull. If you exported only a category at a time, this might be easier.&lt;/li&gt;
&lt;li&gt;Finally, export the 2.0 database into a KeePass 1.x file. Although KeePassDroid can read KeePass 2.x files, it can&amp;rsquo;t write them. I usually update passwords on my device, so I needed to be able to edit. I use KeePass 2.0 as the master on my desktop, but import from the 1.0 file from the device whenever I update a password.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;rsquo;s it. Your mileage may vary - especially if you have strange characters in your Yaps password file. I did have a few passwords with &amp;quot; marks in them, and they appeared to migrate OK. A few minor edits was way better than retyping everything!&lt;/p&gt;</description></item><item><title>Palm to Android - missing contacts</title><link>https://andrewmemory.acornwall.net/blog/2011-09-02-palm-to-android-missing-contacts/</link><pubDate>Fri, 02 Sep 2011 21:06:00 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-09-02-palm-to-android-missing-contacts/</guid><description>&lt;p&gt;I started moving from an ancient Palm handheld to Android. Moving the contacts over without putting them all in the cloud was pretty straightforward. I just used the Palm Desktop to export as VCard.&lt;/p&gt;
&lt;p&gt;After doing that, I went through the VCard file and changed Palm-CustomN fields into NOTE;ENCODING=QUOTED-PRINTABLE: fields (or appended to an existing note). This is described in more detail at: &lt;a href="http://www.deepwave.net/articles/palm/palm_ctctvcard/" target="_blank" rel="noreferrer"&gt;www.deepwave.net/articles/palm/palm_ctctvcard/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After doing all this, I noticed that some of my contacts didn&amp;rsquo;t get moved over. In fact, they didn&amp;rsquo;t show up on the Palm Desktop either!&lt;/p&gt;
&lt;p&gt;It took me a while before I realized that the records that were missing were the hidden records. Duh! I then set the Palm Desktop to show hidden records, exported them to VCard, hacked out the custom fields, and was off and running.&lt;/p&gt;
&lt;p&gt;After doing the imports, I realized I should have exported one category at a time - this would have saved me recategorizing the whole wad on Android.&lt;/p&gt;</description></item><item><title>Ubuntu number key weirdness</title><link>https://andrewmemory.acornwall.net/blog/2011-06-30-ubuntu-number-key-weirdness/</link><pubDate>Thu, 30 Jun 2011 21:54:43 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-06-30-ubuntu-number-key-weirdness/</guid><description>&lt;p&gt;My Ubuntu 10.04 install was behaving weirdly when I used the numeric keypad. The keys would never generate numbers; rather, they would move the mouse cursor.&lt;/p&gt;
&lt;p&gt;Luckily, I found this post: &lt;a href="http://eric.biven.us/2009/02/03/ubuntu-and-the-number-pad-that-wont-work/" target="_blank" rel="noreferrer"&gt;eric.biven.us/2009/02/03/ubuntu-and-the-number-pad-that-wont-work/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short, the solution to turning off this feature is to go into System-&amp;gt;Preferences-&amp;gt;Assistive Technologies, press &amp;ldquo;Keyboard Accessibility&amp;rdquo;, then under &amp;ldquo;Mouse Keys&amp;rdquo; uncheck &amp;ldquo;Pointer can be controlled using the keypad.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;My KVM switch often leaves the shift state down - and the keyboard shortcut for this is Shift + NumLock.&lt;/p&gt;</description></item><item><title>Setting up soundmodem on Ubuntu 10.04</title><link>https://andrewmemory.acornwall.net/blog/2011-06-29-setting-up-soundmodem-on-ubuntu-10-04/</link><pubDate>Wed, 29 Jun 2011 22:23:42 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-06-29-setting-up-soundmodem-on-ubuntu-10-04/</guid><description>&lt;p&gt;After a long delay, I finally decided to upgrade to 10.04 LTS and get soundmodem running again.&lt;/p&gt;
&lt;p&gt;Luckily, there was help this time. I started with my config, and merged with this post: &lt;a href="http://ubuntuforums.org/showthread.php?p=10864691" target="_blank" rel="noreferrer"&gt;ubuntuforums.org/showthread.php?p=10864691&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the config I ended up using:&lt;/p&gt;
&lt;p&gt;Configuration: AX.25 IO: Mode: soundcard Audio Driver: /dev/dsp Half Duplex: selected PTT Driver: none&lt;/p&gt;
&lt;p&gt;Channel Access: TxDelay: 150 Slot Time: 100 P-Persistence: 40 Full Duplex: not selected TxTail: 10&lt;/p&gt;
&lt;p&gt;Channel 0: Modulator: Mode: afsk Bits/s: 1200 Freq 0: 1200 Freq 1: 2200 Differential: selected&lt;/p&gt;
&lt;p&gt;Demodulator: Mode: afsk Bits/s: 1200 Freq 0: 1200 Freq 1: 2200 Differential: selected&lt;/p&gt;
&lt;p&gt;Packet IO: Mode: MKISS Interface: sm0 Callsign: mycall IP address: 10.0.0.1 Network mask: 255.255.255.0 Broadcast addr: 10.0.0.255&lt;/p&gt;
&lt;p&gt;I also set up /etc/ax25/axports to have:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sm0 mycall 1200 255 7 144.39 APRS (1200 bps)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, I made sure Avahi was set to ignore sm0. This is easier than it was &lt;a href="https://andrewmemory.acornwall.net/blog/2009-10-17-radio-packet-soundmodem-losing-the-squeaks/" &gt;prevously&lt;/a&gt; - now you just add:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;deny-interfaces=sm0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to /etc/avahi/avahi-daemon.conf&lt;/p&gt;
&lt;p&gt;Once that&amp;rsquo;s done, don&amp;rsquo;t forget to chmod 4755 /usr/bin/xastir so it can open sm0 and things are good.&lt;/p&gt;</description></item><item><title>Intel can't do video</title><link>https://andrewmemory.acornwall.net/blog/2011-06-12-intel-cant-do-video/</link><pubDate>Sun, 12 Jun 2011 03:35:44 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-06-12-intel-cant-do-video/</guid><description>&lt;p&gt;I recently upgraded my Ubuntu installation from 9.10 (with the old 8.10 video drivers that didn&amp;rsquo;t crash) to 10.04. I immediately began seeing the video crash, especially when there was a lot of activity.&lt;/p&gt;
&lt;p&gt;It turns out I have an Intel Corporation 82845G/GL&lt;/p&gt;
\[Brookdale-G\]&lt;p&gt;/GE Chipset Integrated Graphics Device (rev 01). This is one of the many Intel video cards that have trouble.&lt;/p&gt;
&lt;p&gt;I applied workaround F from here: &lt;a href="https://wiki.ubuntu.com/X/Bugs/Lucidi8xxFreezes" target="_blank" rel="noreferrer"&gt;https://wiki.ubuntu.com/X/Bugs/Lucidi8xxFreezes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That led me to here: &lt;a href="http://www.ubuntugeek.com/intel-graphics-performance-guide-for-ubuntu-904-jaunty-users.html" target="_blank" rel="noreferrer"&gt;http://www.ubuntugeek.com/intel-graphics-performance-guide-for-ubuntu-904-jaunty-users.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After applying the Method 2 fix from there, things seem to be a little more stable. Time will tell.&lt;/p&gt;</description></item><item><title>Brother printer disappeared</title><link>https://andrewmemory.acornwall.net/blog/2011-05-31-brother-printer-disappeared/</link><pubDate>Tue, 31 May 2011 23:21:42 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-05-31-brother-printer-disappeared/</guid><description>&lt;p&gt;After a while, my Brother MVC 9840 CDW printer (which I installed using &lt;a href="https://andrewmemory.acornwall.net/blog/2011-01-02-installing-the-brother-mfc-9840cdw-driver-on-ubuntu" &gt;this method&lt;/a&gt;) disappeared.&lt;/p&gt;
&lt;p&gt;No idea why. So I deleted it and reinstalled it. When I went to reinstall it, the original IP-address method wasn&amp;rsquo;t available. Instead I picked: Network Printer -&amp;gt; Brother MFC-9840CDW and accepted the host and queue as filled in by the configuration dialog. When I did that, no luck.&lt;/p&gt;
&lt;p&gt;Instead, I selected AppleTalk/HP Jet Direct since I knew the printer supported that protocol as well. Then I had to enter the IP address of the printer and accepted the default port (9100). Once that was done, I could again print a test page and use up all my ink.&lt;/p&gt;</description></item><item><title>Fixing the Firefox 4 open tab / open window nonsense</title><link>https://andrewmemory.acornwall.net/blog/2011-04-15-fixing-the-firefox-4-open-tab-open-window-nonsense/</link><pubDate>Fri, 15 Apr 2011 22:19:17 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-04-15-fixing-the-firefox-4-open-tab-open-window-nonsense/</guid><description>&lt;p&gt;Firefox 4 has got it into its head that tabs are better than windows, despite the fact that tabs use up more UI and look ugly, while windows are nice and clean.&lt;/p&gt;
&lt;p&gt;In order to promote their tab agenda, they&amp;rsquo;ve changed the order of the context menu so your muscle memory for &amp;ldquo;Open Link in New Window&amp;rdquo; now brings you &amp;ldquo;Open Link in New Tab&amp;rdquo;. Ugh.&lt;/p&gt;
&lt;p&gt;Luckily, there is an &lt;a href="http://forums.mozillazine.org/viewtopic.php?f=23&amp;amp;t=1954619&amp;amp;start=15" target="_blank" rel="noreferrer"&gt;answer for this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Create a userChrome.css file in your profile/chrome directory (on Windows, C:\Documents and Settings\&lt;em&gt;user&lt;/em&gt;\Application Data\Mozilla\Firefox\Profiles\&lt;em&gt;somethingrandom&lt;/em&gt;.default\chrome\):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;#contentAreaContextMenu &amp;gt; * { -moz-box-ordinal-group: 2; } #context-openlink { -moz-box-ordinal-group: 1 !important; }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This doesn&amp;rsquo;t change the order under the file menu, but at least when you&amp;rsquo;re using the context menu it will work right.&lt;/p&gt;</description></item><item><title>Upgrading the Arduino Uno 8U2 using Fli</title><link>https://andrewmemory.acornwall.net/blog/2011-04-14-upgrading-the-arduino-uno-8u2-using-flip/</link><pubDate>Thu, 14 Apr 2011 00:38:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-04-14-upgrading-the-arduino-uno-8u2-using-flip/</guid><description>&lt;p&gt;The instructions on the &lt;a href="http://arduino.cc/en/Hacking/DFUProgramming8U2" target="_blank" rel="noreferrer"&gt;Arduino DFU update page&lt;/a&gt; are pretty vague when it comes to updating to the latest firmware using the Atmel Flip utility. Here&amp;rsquo;s what I did to get my Uno 8U2 firmware updated using Windows XP:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Flip from the &lt;a href="http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3886" target="_blank" rel="noreferrer"&gt;Atmel webpage&lt;/a&gt;. If you don&amp;rsquo;t already have a JRE, you probably want the 20 megabyte package that includes one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the &lt;a href="https://github.com/arduino/Arduino/blob/master/hardware/arduino/firmwares/arduino-usbserial/Arduino-usbserial-uno.hex" target="_blank" rel="noreferrer"&gt;8U2 firmware&lt;/a&gt;. That&amp;rsquo;s the &amp;ldquo;Arduino-usbserial-uno.hex&amp;rdquo; file. The &amp;ldquo;UNO-dfu_and_usbserial_combined.hex&amp;rdquo; is the Arduino Uno bootloader firmware for the 328p. If you try installing the 328p firmware onto the 8U2 in Flip, you&amp;rsquo;ll get an error dialog:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;class com.atmel.flipGui.FileMenuHandler
Address is out of range.&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I ended up cutting &amp;amp; pasting the hex file contents into a text editor because I couldn&amp;rsquo;t figure out how to download a single file from github, and I didn&amp;rsquo;t want the whole 200 megabyte wad.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hook up wires and touch them to the right spots on the Uno at the right time as described in this &lt;a href="http://arduino.cc/forum/index.php/topic,53290.msg380874.html#msg380874" target="_blank" rel="noreferrer"&gt;Arduino forum post by pluggy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Update: Pluggy&amp;rsquo;s image has disappeared. Here it is:
&lt;figure&gt;&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="auto"
alt="The image"
width="300"
height="216"
src="https://andrewmemory.acornwall.net/blog/2011-04-14-upgrading-the-arduino-uno-8u2-using-flip/images/flasheo8u2-1-300x216.jpg"
srcset="https://andrewmemory.acornwall.net/blog/2011-04-14-upgrading-the-arduino-uno-8u2-using-flip/images/flasheo8u2-1-300x216.jpg 800w, https://andrewmemory.acornwall.net/blog/2011-04-14-upgrading-the-arduino-uno-8u2-using-flip/images/flasheo8u2-1-300x216.jpg 1280w"
sizes="(min-width: 768px) 50vw, 65vw"
data-zoom-src="https://andrewmemory.acornwall.net/blog/2011-04-14-upgrading-the-arduino-uno-8u2-using-flip/images/flasheo8u2-1-300x216.jpg"&gt;&lt;/figure&gt;
I found it at &lt;a href="http://www.ardumania.es/reflashear-el-8u2/" target="_blank" rel="noreferrer"&gt;www.ardumania.es/reflashear-el-8u2/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll know you did it right when Windows detects a new device. It took me a few tries to keep the first wire steady enough when touching the second wire. Make sure you&amp;rsquo;re going to the right pads - you could short out your Uno if you touch the wrong place!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After Windows detects the new device, you don&amp;rsquo;t have to hold the wires in place any more. Move them to the side so you don&amp;rsquo;t accidentally short out something.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When the Windows device installer comes up, select &amp;ldquo;have disk&amp;rdquo; and install the Atmel USB driver. By default the Atmel USB driver is installed in C:\Program Files\Atmel\Flip 3.4.2\usb\atmel_usb_dfu.inf&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Notice that the driver is AT90USB82, not ATmega8U2&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Although it tells you that you have to reboot XP when you install the driver, I didn&amp;rsquo;t bother.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start Flip from the Program menu&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;File-&amp;gt;Load HEX file-&amp;gt;Arduino-usbserial-uno.hex&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Device-&amp;gt;Select-&amp;gt;AT90USB82&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Settings-&amp;gt;Communication-&amp;gt;USB and press Open&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this point, you should be ready to program. Press the &amp;ldquo;Run&amp;rdquo; button on the main screen.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Programming is quick, taking about 4 seconds. After it&amp;rsquo;s done, remove the two wires you put in earlier, then unplug the USB cord and reinsert it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once you&amp;rsquo;ve done that, your Uno should be out of DFU mode and back into normal mode.&lt;/p&gt;
&lt;p&gt;You can go to My Computer-&amp;gt;Manage-&amp;gt;Device Manager-&amp;gt;Ports (COM &amp;amp; LPT), right-click on &amp;ldquo;Arduino UNO&amp;rdquo; and select &amp;ldquo;Properties&amp;rdquo;. Under the Details tab, Firmware Revision should now be 00.01.&lt;/p&gt;
&lt;p&gt;Update: Someone mentioned they couldn&amp;rsquo;t find the atmel_usb_dfu.inf file. Looks like there&amp;rsquo;s a copy &lt;a href="https://github.com/diydrones/ardupilot/blob/master/Tools/ArduPPM/ATMega32U2/Drivers/atmel_usb_dfu.inf" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Testing the USBtinyISP on Arudino Uno</title><link>https://andrewmemory.acornwall.net/blog/2011-04-09-testing-usbtinyisp-on-arduino-uno/</link><pubDate>Sat, 09 Apr 2011 13:29:53 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-04-09-testing-usbtinyisp-on-arduino-uno/</guid><description>&lt;p&gt;After building a &lt;a href="http://www.ladyada.net/make/usbtinyisp/index.html" target="_blank" rel="noreferrer"&gt;USBtinyISP&lt;/a&gt; programmer to burn new bootloaders to my Uno (and other devices) I wanted to test it before putting it in the case.&lt;/p&gt;
&lt;p&gt;Unfortunately, the &lt;a href="http://www.ladyada.net/make/usbtinyisp/use.html" target="_blank" rel="noreferrer"&gt;obvious place&lt;/a&gt; talks about programming with WinAVR and other random things that you don&amp;rsquo;t care about when you&amp;rsquo;re hot to see if the thing actually works.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I did instead (using a Windows XP machine, since that is what&amp;rsquo;s claimed to cause the least trouble):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I downloaded the &lt;a href="http://www.ladyada.net/make/usbtinyisp/download.html" target="_blank" rel="noreferrer"&gt;USBtinyISP drivers&lt;/a&gt; and unzipped them into a directory.&lt;/li&gt;
&lt;li&gt;I plugged the USBtinyISP in (before putting the programming cables / case on yet). It was recognized as a USB device, and I installed usbtinyisp.inf from the unzipped driver.&lt;/li&gt;
&lt;li&gt;I immediately tried to talk to the device using the Arduino 022 IDE and &amp;ldquo;Burn Bootloader -&amp;gt; w/USBtinyISP&amp;rdquo;. It failed with the error message &amp;ldquo;Could not find USB device 0x1781/0xc9f&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;So I unplugged the device and plugged it back in. This time I got &amp;ldquo;Initialization failed, rc=-1&amp;rdquo; which is correct.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Whew, that meant my device was talking - in other words, I&amp;rsquo;d probably put it together correctly. Next was to see if it actually could program my Uno.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I plugged the 6-connector programming cable in. The red stripe went on pin 1 of the silkscreen of the USBtinyISP, and the pin with a dot on it on the programming header of the Uno. (At first it looked wrong, but when I turned the cable around it was fine. The cable goes across the whole length of the Uno.)&lt;/li&gt;
&lt;li&gt;Then I made sure the jumper on the USBtinyISP was off (not supplying voltage).&lt;/li&gt;
&lt;li&gt;Next, I plugged the USBtinyISP into my USB port and verified that the green light came on.&lt;/li&gt;
&lt;li&gt;After that, I plugged in my Uno (to a different USB port) so it was getting power and was recognized.&lt;/li&gt;
&lt;li&gt;Finally, I went to the Arduino IDE and did Tools -&amp;gt; Burn Bootloader -&amp;gt; w/USBtinyISP.&lt;/li&gt;
&lt;li&gt;The red light came on for about two minutes to program my chip. After it turned off, I uploaded a sketch to make sure it worked - and it did. &amp;ldquo;Done burning bootloader.&amp;rdquo; Yay!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, I put the 10-pin programming cable in and the case on. I had to push the LEDs around a little (the green one was getting pretty close to the USB header). Then I was able to snap the case on and catch my finger in there as well, removing a little skin I didn&amp;rsquo;t need.&lt;/p&gt;
&lt;p&gt;That was it - I now had a good programmer. I did another program with the case on to make sure it worked and I hadn&amp;rsquo;t broken anything.&lt;/p&gt;
&lt;p&gt;Next I&amp;rsquo;ll look on the &lt;a href="https://github.com/arduino/Arduino/tree/master/hardware/arduino/firmwares/" target="_blank" rel="noreferrer"&gt;Arduino firmware&lt;/a&gt; github page to see if there&amp;rsquo;s any newer boot firmware.&lt;/p&gt;</description></item><item><title>Should I malloc on Arduino?</title><link>https://andrewmemory.acornwall.net/blog/2011-03-29-should-i-malloc-on-arduino/</link><pubDate>Tue, 29 Mar 2011 21:34:48 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-03-29-should-i-malloc-on-arduino/</guid><description>&lt;p&gt;I&amp;rsquo;ve been defining an Event class for Arduino processing so I don&amp;rsquo;t have to think quite so hard about timing loops myself. In the process of doing this, I got the following error:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;undefined reference to `operator delete(void*)'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I discovered that the Arduino C++ doesn&amp;rsquo;t include new() or delete(). (Ok, I guess I shouldn&amp;rsquo;t be calling it C++&amp;hellip;.)&lt;/p&gt;
&lt;p&gt;I did a quick web search and discovered &lt;a href="http://arduinoetcetera.blogspot.com/2010/04/implementing-new-and-delete-c.html" target="_blank" rel="noreferrer"&gt;replacement functions&lt;/a&gt;&amp;hellip; but then I started thinking.&lt;/p&gt;
&lt;p&gt;Why did these get removed from the Arduino C++ variant? On a device as limited as the ATmega328, it makes no sense to malloc() from a pool. Might as well just allocate the variables you want. (Or in my case, allocate an array of variables up front). That way, you know you don&amp;rsquo;t have a pointer leak that will hose you as you run.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; I think the answer is &lt;em&gt;no, I shouldn&amp;rsquo;t malloc on Arduino&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;(Edit) Unless, of course, I&amp;rsquo;m writing a library.&lt;/p&gt;</description></item><item><title>Making git ignore file mode</title><link>https://andrewmemory.acornwall.net/blog/2011-03-24-making-git-ignore-file-mode/</link><pubDate>Thu, 24 Mar 2011 00:45:39 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-03-24-making-git-ignore-file-mode/</guid><description>&lt;p&gt;I have recently had to run git on Windows, and things there get all weird because by default git uses file mode as part of its comparison. Because of this, files whose mode have changed show up as different.&lt;/p&gt;
&lt;p&gt;Luckily, git has a way around this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config core.filemode false&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Nice!&lt;/p&gt;</description></item><item><title>Failed while running mythtranscode to cut commercials</title><link>https://andrewmemory.acornwall.net/blog/2011-02-27-failed-while-running-mythtranscode-to-cut-commercials/</link><pubDate>Sun, 27 Feb 2011 16:50:51 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-02-27-failed-while-running-mythtranscode-to-cut-commercials/</guid><description>&lt;p&gt;For a long time I&amp;rsquo;ve had the error message &amp;ldquo;failed while running mythtranscode to cut commercials&amp;rdquo; on my MythTV box. Today I did some searching to find out more about it.&lt;/p&gt;
&lt;p&gt;It turns out the error is caused by the existence or permissions of .ICEauthority.&lt;/p&gt;
&lt;p&gt;I nuked ~/.ICEauthority and was able to mythtranscode. Apparently this file is recreated occasionally, so if I see this again I&amp;rsquo;ll check permissions.&lt;/p&gt;</description></item><item><title>Using an Arduino Serial USB board with an Ardweeny</title><link>https://andrewmemory.acornwall.net/blog/2011-01-30-using-an-arduino-serial-usb-board-with-an-ardweeny/</link><pubDate>Sun, 30 Jan 2011 17:47:35 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-30-using-an-arduino-serial-usb-board-with-an-ardweeny/</guid><description>&lt;p&gt;This afternoon I joined the world of Arduino hacking. I put together an &lt;a href="http://www.solarbotics.com/products/kardw/" target="_blank" rel="noreferrer"&gt;Ardweeny&lt;/a&gt; and hooked it up to an &lt;a href="http://www.solarbotics.com/products/50520/" target="_blank" rel="noreferrer"&gt;Arduino Serial USB Board&lt;/a&gt;. I probably should have used a newer &lt;a href="http://www.solarbotics.com/products/50512/" target="_blank" rel="noreferrer"&gt;FTDI basic breakout board&lt;/a&gt; which supports auto-reset, but I didn&amp;rsquo;t.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Assembly and Power Up
&lt;div id="assembly-and-power-up" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#assembly-and-power-up" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Putting the Ardweeny together was pretty simple. One word of advice: you do &lt;strong&gt;not&lt;/strong&gt; want to do this without a third hand tool. Even that won&amp;rsquo;t be enough for soldering the chip onto the headers - you&amp;rsquo;ll need a friend or some good gentle alligator clips to hold the chip while you do the first tack solders.&lt;/p&gt;
&lt;p&gt;I powered it up by connecting +5v of the Ardweeny to +5v of the Serial USB board, and then connecting Gnd on the Ardweeny to Gnd on the Serial USB board. It started blinking right away - always a good sign.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Connecting to USB Serial
&lt;div id="connecting-to-usb-serial" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#connecting-to-usb-serial" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Connecting the Ardweeny to the Serial USB board was a little trickier. I used a pair of &lt;a href="http://www.solarbotics.com/products/45030/" target="_blank" rel="noreferrer"&gt;jumper wires&lt;/a&gt;. In one end of each one I stuffed a little clipping of 22 awg bell wire, so I had a female connector at one end and a male connector at the other.&lt;/p&gt;
&lt;p&gt;Next, the big (and as far as I can tell undocumented) question: does TX on the Serial USB board go to RX on the Ardweeny and vice versa, or does TX on the Serial USB board go straight to TX on the Ardweeny? The answer:&lt;/p&gt;
&lt;p&gt;TX on the Serial USB board (the pin furthest from Gnd on the left side) goes to RXI (the pin above A4 on the Ardweeny v1.1a)&lt;/p&gt;
&lt;p&gt;RX on the Serial USB board (the pin just above +5v on the left side) goes to TXO (the pin above A3 on the Ardweeny v1.1a)&lt;/p&gt;
&lt;p&gt;I hooked those up backwards and my USB port stopped recognizing the Serial USB board. I had to pull the Serial USB board from the USB hub and plug it back in to continue. (I&amp;rsquo;m doing all of this through a powered USB hub just to avoid burning out my motherboard&amp;rsquo;s USB if I make a mistake.)&lt;/p&gt;
&lt;h2 class="relative group"&gt;Downloading Code
&lt;div id="downloading-code" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#downloading-code" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Once I&amp;rsquo;d done that, I sent a program down. The first program went with no problems after I set my COM port and chose the &amp;ldquo;Arudino Duemilanove or Nano w/ATmega 328&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Subsequent programs wouldn&amp;rsquo;t write - I got the following error:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;avrdude: stk500_getsync(): not in sync: resp=0x00
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;It turns out the Ardweeny is pretty particular about when things get uploaded to it. (This is where the auto-reset function of the &lt;a href="http://www.solarbotics.com/products/50512/" target="_blank" rel="noreferrer"&gt;FTDI basic breakout board&lt;/a&gt; shines, but I didn&amp;rsquo;t know that since I&amp;rsquo;d never done Arduino programming before.) So the magic trick to upload is to wait until you see:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Binary sketch size: 1018 bytes (of a 30720 byte maximum)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;in the IDE, then immediately hit the reset button on the Ardweeny. At that point, you&amp;rsquo;ll see the TX and RX LEDs flash on the USB Serial board, and your code should be uploaded.&lt;/p&gt;</description></item><item><title>Configuring a website on Apache2 with server-side includes</title><link>https://andrewmemory.acornwall.net/blog/2011-01-22-configuring-a-website-on-apache2-with-server-side-includes/</link><pubDate>Sat, 22 Jan 2011 14:37:23 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-22-configuring-a-website-on-apache2-with-server-side-includes/</guid><description>&lt;p&gt;I recently got myself involved in helping with a website for a local club. In order to maintain it, I wanted to set up an Apache instance at home as well.&lt;/p&gt;
&lt;p&gt;Luckily, in Ubuntu 9.10, it&amp;rsquo;s almost all set up by default. The only changes I had to make were to change the DocumentRoot directory and enable server-side includes. Here&amp;rsquo;s what I did:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Changing the document root
&lt;div id="changing-the-document-root" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#changing-the-document-root" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;First I edited /etc/apache2/sites-available/default to put my document root in DocumentRoot, and also changed the two directory references that did point to /var/www to my new document root. Then I made sure all the parents of my document root had r+x permission for the Apache user.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Turning on server-side includes
&lt;div id="turning-on-server-side-includes" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#turning-on-server-side-includes" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;My hosting facility has server-side includes turned on for .html. This is not the best use of resources, but this website doesn&amp;rsquo;t get enough traffic to make a difference. So I added: &lt;code&gt;AddType text/html .html AddHandler server-parsed .html Option Include (plus whatever options were there before)&lt;/code&gt; to the two directories that used to be /var/www and /. After that, I had to enable mod_include with: &lt;code&gt;cd /etc/apache2/mods-enabled sudo ln -s ../mods-available/include.load include.load&lt;/code&gt; Then restart apache with sudo /etc/init.d/apache2 restart&lt;/p&gt;</description></item><item><title>Resolving git error: unable to create temporary sha1 filename</title><link>https://andrewmemory.acornwall.net/blog/2011-01-11-resolving-git-error-unable-to-create-temporary-sha1-filename/</link><pubDate>Tue, 11 Jan 2011 22:59:22 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-11-resolving-git-error-unable-to-create-temporary-sha1-filename/</guid><description>&lt;p&gt;I&amp;rsquo;m just starting to use git for source control. Tonight I got an error when I tried to commit:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ git add ./foo/bar/
error: unable to create temporary sha1 filename .git/objects/95: File exists
error: foo/bar/baz: failed to insert into database&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Luckily, &lt;a href="http://ariejan.net/2009/10/15/git-problem-error-unable-to-create-temporary-sha1-filename/" target="_blank" rel="noreferrer"&gt;someone else&lt;/a&gt; ran into this before me. The magic incantation:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;git fsck
git prune
git repack
git fsck&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and then I was able to add my files.&lt;/p&gt;
&lt;p&gt;I ran into another case where this didn&amp;rsquo;t help. In that instance,&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;git gc&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;was able to get me committing again.&lt;/p&gt;</description></item><item><title>Inserting current date and time with EMACS</title><link>https://andrewmemory.acornwall.net/blog/2011-01-02-inserting-current-date-and-time-with-emacs/</link><pubDate>Sun, 02 Jan 2011 00:16:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-02-inserting-current-date-and-time-with-emacs/</guid><description>&lt;p&gt;I was recently involved in an activity that required keeping track of notes with timestamps. I decided to do it in EMACS. Here&amp;rsquo;s what I stuffed in my .emacs init file:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;;; Insert the current time in the current buffer
(defun
timestamp()
(interactive)
; If you want to insert date and time, you can use:
(insert(format-time-string &amp;#34;%Y-%m-%d %H:%M:%S &amp;#34;)))
;; Bind Ctrl-T (&amp;#34;transpose&amp;#34;) to the timestamp function - need a better key binding
(global-set-key (kbd &amp;#34;C-t&amp;#34;) &amp;#39;timestamp)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Incidentally, I also needed to save the file to DOS format instead of Unix format. To do that:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;M-x set-buffer-file-coding-system&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;then use &amp;ldquo;dos&amp;rdquo; (or &amp;ldquo;mac&amp;rdquo; or &amp;ldquo;unix&amp;rdquo;).&lt;/p&gt;</description></item><item><title>Creating thumbnail images with convert</title><link>https://andrewmemory.acornwall.net/blog/2011-01-02-creating-thumbnail-images-with-convert/</link><pubDate>Sat, 01 Jan 2011 17:32:26 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-02-creating-thumbnail-images-with-convert/</guid><description>&lt;p&gt;A little while ago, I found I had a bunch of images that needed thumbnails that were 100×75. This isn&amp;rsquo;t hard to do - I used convert and a pair of bash for loops.&lt;/p&gt;
&lt;p&gt;The core was a call to convert, which is part of ImageMagick.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;convert -thumbnail 100x75 input.jpg thumbnail.jpg&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;All of my images happened to be 4:3 - if they hadn&amp;rsquo;t, I might have used &lt;code&gt;100x75!&lt;/code&gt; or rotated/resized them.&lt;/p&gt;
&lt;p&gt;Next, all my files had numbers of the form file01..file09 file10 file11&amp;hellip; etc. If you&amp;rsquo;re nuts, you try to figure out how to do this in a single for-loop with a condition for the first 9 elements that start with 0.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re lazy like me, you use two loops, with a cursor-up in bash so you don&amp;rsquo;t have to type as much:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;export INFILEPREFIX=file
export OUTFILEPREFIX=file
for i in {1..9}; do convert -thumbnail 100x75 ${INFILEPREFIX}0${i}.jpg ${OUTFILEPREFIX}0${i}t.jpg; done
for i in {10..25}; do convert -thumbnail 100x75 ${INFILEPREFIX}${i}.jpg ${OUTFILEPREFIX}${i}t.jpg; done&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;For the non-thumbnails, I resized as well, using -resize 800x600.&lt;/p&gt;</description></item><item><title>Scale your website images</title><link>https://andrewmemory.acornwall.net/blog/2011-01-01-scale-your-website-images/</link><pubDate>Sat, 01 Jan 2011 17:32:26 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-01-scale-your-website-images/</guid><description>&lt;p&gt;I just noticed that if you scale an image using width= and height= attributes of the img tag, Firefox 3.6 will (sometimes) put a thin border on the top and left of the image - something that you can&amp;rsquo;t get rid of with CSS/styling.&lt;/p&gt;
&lt;p&gt;Weird - but a good rule seems to be scale your images to the correct size before using them in HTML.&lt;/p&gt;
&lt;p&gt;This is different from the &amp;ldquo;border around link images&amp;rdquo; issue - which is easy enough to get around by using &lt;code&gt;border-style: none&lt;/code&gt; in CSS.&lt;/p&gt;</description></item><item><title>Installing the Brother MFC 9840cdw driver on Ubuntu</title><link>https://andrewmemory.acornwall.net/blog/2011-01-01-installing-the-brother-mfc-9840cdw-driver-on-ubuntu/</link><pubDate>Sat, 01 Jan 2011 17:13:51 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2011-01-01-installing-the-brother-mfc-9840cdw-driver-on-ubuntu/</guid><description>&lt;p&gt;When I had Ubuntu 8.04, I&amp;rsquo;d struggled my way through installing the official Brother driver from the &lt;a href="http://welcome.solutions.brother.com/bsc/public_s/id/linux/en/index.html" target="_blank" rel="noreferrer"&gt;Brother Linux site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since then I&amp;rsquo;ve upgraded a couple of times to 9.10, and had not reinstalled my printer. It turns out Ubuntu has made life much easier for us Brother printer owners - so these days there&amp;rsquo;s no reason not to install the printer driver, especially if the printer is networked.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to do it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open Synaptic Package Manager&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for 9840. You should see two packages:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;brother-cups-wrapper-ac
brother-lpr-driver-ac&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select those for installation (along with their required packages).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to System-&amp;gt;Administration-&amp;gt;Printing and press the &amp;ldquo;New Printer&amp;rdquo; button.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After a &amp;ldquo;Search for new printers&amp;rdquo; message comes up and goes away, expand &amp;ldquo;Network Printers&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you&amp;rsquo;re lucky like me, you&amp;rsquo;ll see your printer there. I chose to use the one that was found by IP address (LPD Network Printer via DNS-SD).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then I printed a test page, which shot a bunch of colour toner out. (If I had to do it over again, I would have just printed from Firefox to save toner.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, I did System-&amp;gt;Preferences-&amp;gt;Default Printer to set the new printer as the default.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That does the printer; next you&amp;rsquo;ll want the scanner. This isn&amp;rsquo;t quite as straightforward, since the scanner stuff isn&amp;rsquo;t in Synaptic. Again I&amp;rsquo;m assuming it&amp;rsquo;s set up on a network:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Make sure you&amp;rsquo;ve already installed xsane and its requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the .deb for brscan3 from the &lt;a href="http://welcome.solutions.brother.com/bsc/public_s/id/linux/en/download_scn.html#brscan3" target="_blank" rel="noreferrer"&gt;Brother web site&lt;/a&gt;. If you&amp;rsquo;re like me, you want the 32-bit version.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the driver with:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo dpkg -i --force-all brscan3-0.2.11-2.i386.deb&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure the scanner:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ brsaneconfig3 -a name=SCANNER model=MFC-9840CDW ip=aaa.bbb.ccc.ddd&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;(where aaa.bbb.ccc.ddd is your MFC-9840&amp;rsquo;s IP address).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the driver installed:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ brsaneconfig3 -q | grep SCANNER
0 SCANNER &amp;#34;MFC-9840CDW&amp;#34; I:aaa.bbb.ccc.ddd&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run xsane and it should find the scanner.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Converting audio files under Linux</title><link>https://andrewmemory.acornwall.net/blog/2010-12-29-converting-audio-files-under-linux/</link><pubDate>Wed, 29 Dec 2010 23:14:27 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-12-29-converting-audio-files-under-linux/</guid><description>&lt;p&gt;Linux has mplayer, an excellent audio player. It&amp;rsquo;s also handy when you want to convert a sound file from one format to another. The secret is to use .wav as an intermediate conversion, since most audio converters know how to handle that.&lt;/p&gt;
&lt;p&gt;Here is the magic incantation for mplayer:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;mplayer -quiet -vo null -vc dummy -ao pcm:waveheader:file=&amp;#34;output.wav&amp;#34; input.rm&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This takes the input file and creates output.wav from it. Once you have that, it&amp;rsquo;s a simple matter of&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;oggenc output.wav&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to get output.ogg (don&amp;rsquo;t forget to install vorbis-tools) or&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;lame output.wav&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;if MP3s are your bag.&lt;/p&gt;
&lt;p&gt;Linux Review has a good &lt;a href="http://en.linuxreviews.org/HOWTO_Convert_audio_files" target="_blank" rel="noreferrer"&gt;article on converting&lt;/a&gt; using this technique&lt;/p&gt;</description></item><item><title>Speed up those boring meeting replays with mplayer</title><link>https://andrewmemory.acornwall.net/blog/2010-12-29-speed-up-those-boring-meeting-replays-with-mplayer/</link><pubDate>Wed, 29 Dec 2010 23:14:27 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-12-29-speed-up-those-boring-meeting-replays-with-mplayer/</guid><description>&lt;p&gt;It&amp;rsquo;s been a while since I looked at the man page for mplayer. Ubuntu has finally included something I&amp;rsquo;ve wanted for a long time.&lt;/p&gt;
&lt;p&gt;Every now and then I have to listen to pre-recorded meetings. Since I usually think faster than the speakers can talk (&amp;ldquo;umm, uhh&amp;hellip; could you go to the next slide please?&amp;rdquo;) I like to speed things up.&lt;/p&gt;
&lt;p&gt;I used to have to use sox to change the playback speed without changing the pitch, but now it appears it&amp;rsquo;s built into mplayer, which makes it much easier.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to do it:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;mplayer -af scaletempo -speed 1.3 boringmeeting.mp3&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This plays back at 1.3 times the usual speed, which is good for most speakers. Really slow ones will benefit from -speed 1.5.&lt;/p&gt;
&lt;p&gt;When I was young, I had an LP with the song &amp;ldquo;Twilight Zone&amp;rdquo; by Golden Earring on it. I used to listen to that at 45 rpm instead of 33 rpm because it made it sound more urgent. That would be -speed 1.363 if you&amp;rsquo;re playing at home.&lt;/p&gt;</description></item><item><title>Creating directories under Program Files on Windows 7</title><link>https://andrewmemory.acornwall.net/blog/2010-11-25-creating-directories-under-program-files-on-windows-7/</link><pubDate>Thu, 25 Nov 2010 23:26:11 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-11-25-creating-directories-under-program-files-on-windows-7/</guid><description>&lt;p&gt;Windows 7 has locked down the &amp;ldquo;Program Files&amp;rdquo; directory so that regular users can no longer create subdirectories. This presents a problem if you have an executable but no installer, and you want that executable to live under &amp;ldquo;Program Files&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The way around that is pretty simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the Explorer&lt;/li&gt;
&lt;li&gt;Navigate to C:\Windows and select explorer&lt;/li&gt;
&lt;li&gt;Right-click and select &amp;ldquo;Run as Administrator&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Give permission to make changes to your system&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, the new Explorer that opens has enough rights to create subdirectories under Program Files (and also to hose your system in a number of interesting ways, so be careful).&lt;/p&gt;
&lt;p&gt;Naturally, if you&amp;rsquo;re more command-line oriented, you could navigate to cmd.exe or sh.exe (assuming you&amp;rsquo;ve got Cygwin installed). If you&amp;rsquo;ve &lt;a href="https://andrewmemory.acornwall.net/blog/2010-11-25-enabling-the-administrator-account-on-windows-7/" &gt;enabled the Administrator account&lt;/a&gt;, it&amp;rsquo;s possible to do all this using the RUNAS command: &lt;code&gt;runas /user:Administrator cmd&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Enabling the Administrator account on Windows 7</title><link>https://andrewmemory.acornwall.net/blog/2010-11-25-enabling-the-administrator-account-on-windows-7/</link><pubDate>Thu, 25 Nov 2010 23:26:11 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-11-25-enabling-the-administrator-account-on-windows-7/</guid><description>&lt;p&gt;By default, the Windows 7 Administrator user is disabled. This prevents you from doing interesting things like using the RUNAS command to start shells with extra permissions.&lt;/p&gt;
&lt;p&gt;To enable the Administrator user, do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the Explorer&lt;/li&gt;
&lt;li&gt;Navigate to C:\Windows\System32 and select cmd&lt;/li&gt;
&lt;li&gt;Right-click and select &amp;ldquo;Run as Administrator&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Give permission to make changes to your system. This will open an elevated permission command prompt.&lt;/li&gt;
&lt;li&gt;In the elevated permission command prompt, enter &amp;ldquo;net user Administrator /active:yes&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Go to Control Panel -&amp;gt; User Accounts and Family Safety -&amp;gt; User Accounts -&amp;gt; Manage Another Account&lt;/li&gt;
&lt;li&gt;Select Administrator&lt;/li&gt;
&lt;li&gt;Create a Password (or Change the Password if you&amp;rsquo;ve already set one).&lt;/li&gt;
&lt;li&gt;Enter the password twice to set/change it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It&amp;rsquo;s probably wise to have a fairly strong password on the Administrator account.&lt;/p&gt;</description></item><item><title>Echo when playing back MythTV</title><link>https://andrewmemory.acornwall.net/blog/2010-10-26-echo-when-playing-back-mythtv/</link><pubDate>Tue, 26 Oct 2010 00:09:57 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-10-26-echo-when-playing-back-mythtv/</guid><description>&lt;p&gt;I recently ran into an interesting problem with my MythTV audio. When I played back a program, it would play back with varying degrees of echo in the audio. Usually the echo would be around 100 ms behind, but if I skipped forward or back I could get it up to 3 seconds behind. This problem did not happen outside of MythTV.&lt;/p&gt;
&lt;p&gt;First I started with alsa-mixer. There I determined that there was no level I could change to affect the echo. Changing the level always changed both the first audio and the echo.&lt;/p&gt;
&lt;p&gt;Next I tried reinstalling the AC97 sound driver, because I saw a website that noted when the driver was corrupt you could get an echo. No dice.&lt;/p&gt;
&lt;p&gt;Finally, I happened to be running top, and I saw this:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; PID USER PR NI VIRT RES SHR S %CPU %MEM TIME&amp;#43; COMMAND
4273 myth 20 0 220m 85m 3588 S 12 8.5 11:55.43 mythfrontend.re
4257 myth 20 0 245m 85m 3700 S 12 8.5 10:20.79 mythfrontend.re&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I had two copies of mythfrontend.real running! Both were getting the lirc keypresses and acting on them. This meant everything (including the player) was being run twice&amp;hellip; hence an echo slightly behind the main audio.&lt;/p&gt;
&lt;p&gt;Somehow the Gnome session state had been saved with a mythfrontend.real running, and when it was restored it would restore with that mythfrontend.real as well as start a new one. I made sure the session state wasn&amp;rsquo;t being saved (under Settings), killed all the running mythfrontend.real instances, and then logged out saving the session. Next I logged in and out but unchecked the button to save session on logout. That seems to have done the trick.&lt;/p&gt;</description></item><item><title>Disabling the Ubuntu auto update dialog</title><link>https://andrewmemory.acornwall.net/blog/2010-10-21-disabling-the-ubuntu-auto-update-dialog/</link><pubDate>Thu, 21 Oct 2010 01:41:03 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-10-21-disabling-the-ubuntu-auto-update-dialog/</guid><description>&lt;p&gt;I&amp;rsquo;ve lived with the Ubuntu auto-update dialog on my MythTV box for quite a while. Tonight I did a quick search to see how to disable it.&lt;/p&gt;
&lt;p&gt;Thanks to this link: &lt;a href="http://maketecheasier.com/remove-the-annoying-update-manager-pop-up-in-ubuntu-jaunty" target="_blank" rel="noreferrer"&gt;maketecheasier.com/remove-the-annoying-update-manager-pop-up-in-ubuntu-jaunty&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip; I discovered that turning off the update dialog was quick and easy. Just do:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;gconftool -s --type bool /apps/update-notifier/auto_launch false&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;You don&amp;rsquo;t even need a sudo, since it&amp;rsquo;s just changing your user&amp;rsquo;s config.&lt;/p&gt;
&lt;p&gt;No more popups obscuring MythTV! When something is annoying, a ten second web search can be a good thing.&lt;/p&gt;</description></item><item><title>Brother MFC-9840 Toner Reset</title><link>https://andrewmemory.acornwall.net/blog/2010-09-16-brother-mfc-9840-toner-reset/</link><pubDate>Thu, 16 Sep 2010 23:48:30 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-09-16-brother-mfc-9840-toner-reset/</guid><description>&lt;p&gt;I like the Brother MFC-9840 printer, but it&amp;rsquo;s got a really irritating problem: it gives up way to easily when it comes to toner. Often there&amp;rsquo;s still around 33% of the toner left in the cartridge when the printer comes up with the dreaded &amp;ldquo;Toner Life End&amp;rdquo; message.&lt;/p&gt;
&lt;p&gt;It appears there are two solutions: #1 (which didn&amp;rsquo;t work for me) is to tape a bit of black tape over the window of the toner cartridge, or over the hole for the sensor in the toner tray. I left the tape on just in case it would do good in the future.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an article with a picture of the toner hole: &lt;a href="http://www.kineticcomputer.com/tips/1107-excessive-low-toner-warnings-on-brother-laser-printers-and-copiers.htm" title="/www.kineticcomputer.com/tips/1107-excessive-low-toner-warnings-on-brother-laser-printers-and-copiers.htm" target="_blank" rel="noreferrer"&gt;www.kineticcomputer.com/tips/1107-excessive-low-toner-warnings-on-brother-laser-printers-and-copiers.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;#2, which I found at &lt;a href="http://www.fixyourownprinter.com/forums/laser/39806" target="_blank" rel="noreferrer"&gt;www.fixyourownprinter.com/forums/laser/39806&lt;/a&gt; proved to solve my problem. Here it is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;With power on, open the toner access main door. You will get a &amp;ldquo;Cover is Open&amp;rdquo; message on the LCD.&lt;/li&gt;
&lt;li&gt;Press the &amp;ldquo;Clear/Back&amp;rdquo; button and you will be taken to the toner &amp;ldquo;Reset Menu&amp;rdquo;&lt;/li&gt;
&lt;li&gt;You can then scroll through the reset options for the printer&amp;rsquo;s toner cartridges:
&lt;ol&gt;
&lt;li&gt;B.TNR-S - Black toner small cartridge (TN-110)&lt;/li&gt;
&lt;li&gt;B.TNR-H - Black toner high-capacity cartridge (TN-115)&lt;/li&gt;
&lt;li&gt;C.TNR-S - Cyan toner small cartridge (TN-110)&lt;/li&gt;
&lt;li&gt;C.TNR-H - Cyan toner high-capacity cartridge (TN-115)&lt;/li&gt;
&lt;li&gt;M.TNR-S - Magenta toner small cartridge (TN-110)&lt;/li&gt;
&lt;li&gt;M.TNR-H - Magenta toner high-capacity cartridge (TN-115)&lt;/li&gt;
&lt;li&gt;Y.TNR-S - Yellow toner small cartridge (TN-110)&lt;/li&gt;
&lt;li&gt;Y.TNR-H - Yellow toner high-capacity cartridge (TN-115)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Select the cartridge size you have and the colour you want to reset, and press OK. Since I had small cartridges, I used the S options for all three colours.&lt;/li&gt;
&lt;li&gt;Each cartridge must be reset individually. Press &amp;ldquo;1&amp;rdquo; to reset.&lt;/li&gt;
&lt;li&gt;Press &amp;ldquo;Clear/Back&amp;rdquo; to get out of the menu, then close the door.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;According to the link at fixyourownprinter.com, this works on the Brother MFC 9440 as well.&lt;/p&gt;
&lt;p&gt;I wish I&amp;rsquo;d found this before I replaced my black toner cartridge!&lt;/p&gt;
&lt;p&gt;Update: 2013-12-12 - I just learned that it&amp;rsquo;s possible to reset the values for other consumables on the printer as well. Hold down both 3 and 9 at the same time, and you&amp;rsquo;ll get a menu to reset: Drum Belt Unit PF Kit MP PF Kit 1 PF Kit 2 Fuser Laser&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t had to do any of these yet, but will remember it for when the time comes!&lt;/p&gt;</description></item><item><title>Installing ntpd on Ubuntu</title><link>https://andrewmemory.acornwall.net/blog/2010-09-01-installing-ntpd-on-ubuntu/</link><pubDate>Wed, 01 Sep 2010 02:29:28 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-09-01-installing-ntpd-on-ubuntu/</guid><description>&lt;p&gt;I was surprised to see that my installs of Ubuntu 9.10 and Ubuntu 10.04 server didn&amp;rsquo;t have ntpd in them. This meant that nothing was correcting my drifting time. One machine was off by five minutes.&lt;/p&gt;
&lt;p&gt;So I installed OpenBSD&amp;rsquo;s ntpd: &lt;code&gt;sudo aptitude install openntpd&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And then started it: &lt;code&gt;sudo service openntpd start&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The /etc/openntpd/ntpd.conf shows that I&amp;rsquo;m polling from the Debian NTP server pool. I guess that&amp;rsquo;s good enough. When I need an NTP server and can&amp;rsquo;t remember, I use time-a.timefreq.bldrdoc.gov.&lt;/p&gt;</description></item><item><title>Hiding a user in GDM</title><link>https://andrewmemory.acornwall.net/blog/2010-09-01-hiding-a-user-in-gdm/</link><pubDate>Wed, 01 Sep 2010 02:14:06 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-09-01-hiding-a-user-in-gdm/</guid><description>&lt;p&gt;A while back, I was playing with Joomla, and I created a joomla user. That was fine, but then I noticed that GDM (the login screen) was offering me the chance to select that user to log in. That was not my intent.&lt;/p&gt;
&lt;p&gt;A quick search revealed this useful post: &lt;a href="http://ubuntuforums.org/showthread.php?t=1321845" target="_blank" rel="noreferrer"&gt;http://ubuntuforums.org/showthread.php?t=1321845&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GDM will show you every user with a user ID of 1000 or higher. I changed my joomla user&amp;rsquo;s user ID to 987, and voilà - no more prompt.&lt;/p&gt;
&lt;p&gt;Luckily, the user I modified didn&amp;rsquo;t own much - and everything it did own was in a group that also owned the files. If that hadn&amp;rsquo;t been the case, I would have had to change ownership of the files as well.&lt;/p&gt;</description></item><item><title>Reading fonts from a Mac CDROM and converting them to TrueType</title><link>https://andrewmemory.acornwall.net/blog/2010-08-06-reading-fonts-from-a-mac-cdrom-and-converting-them-to-truetype/</link><pubDate>Fri, 06 Aug 2010 23:13:11 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-08-06-reading-fonts-from-a-mac-cdrom-and-converting-them-to-truetype/</guid><description>&lt;p&gt;A few years back, I bought a bunch of Macintosh fonts on a CD-ROM. Recently, I decided I wanted to use them with Ubuntu. Since the Mac CD was HPFS only and very scratched, here&amp;rsquo;s what I ended up doing.&lt;/p&gt;
&lt;p&gt;First, I installed the Ubuntu utilities for Mac HPFS: &lt;code&gt;sudo aptitude install macutils hfs&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then I tried just mounting the file system: &lt;code&gt;sudo mount -thfs /dev/cdrom /mnt/cdrom/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That probably would have worked, but my CD was so scratched that it kept dying. (Also, I don&amp;rsquo;t know if copying from a mounted HFS file system copies both forks of the Apple file.)&lt;/p&gt;
&lt;p&gt;Luckily, I was able to use the mounted file system to get a ls -lR listing of the files on the disk. That made it easier to use the excellent hfs utils:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo aptitude install hftutils&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then I could: &lt;code&gt;hmount /dev/cdrom hcd TRUETYPE hcopy -b MyFont.suit /tmp/MyFont.hqx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I wrote a script to copy the files over. Once I had the files over, I could convert them manually using fontforge (from &lt;a href="http://fontforge.sourceforge.net/" target="_blank" rel="noreferrer"&gt;fontforge.sourceforge.net&lt;/a&gt;). Basically, you do: &lt;code&gt;sudo aptitude install fontforge fontforge MyFont.hqx&lt;/code&gt; and then File -&amp;gt; Generate Fonts -&amp;gt; Save (after making sure TTF is selected).&lt;/p&gt;
&lt;p&gt;It turns out fontforge is overkill - and also harder to script - than fondu.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo aptitude install fondu fondu *.hqx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here are some useful sources of information:&lt;/p&gt;
&lt;p&gt;A discussion of font utilities: &lt;a href="http://ubuntuforums.org/showthread.php?t=314837" target="_blank" rel="noreferrer"&gt;ubuntuforums.org/showthread.php?t=314837&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The easy way: using fondu: &lt;a href="http://ubuntu-tutorials.com/2006/12/13/convert-mac-based-fonts-for-use-on-ubuntu-ubuntu-6061-610/" target="_blank" rel="noreferrer"&gt;ubuntu-tutorials.com/2006/12/13/convert-mac-based-fonts-for-use-on-ubuntu-ubuntu-6061-610/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Converting from one outline font (e.g. PostScript) to another (e.g. TrueType): &lt;a href="http://fontforge.sourceforge.net/faq.html#outline-conversion" target="_blank" rel="noreferrer"&gt;fontforge.sourceforge.net/faq.html#outline-conversion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once you have the fonts in TTF format, you can copy them to ~/.fonts/ (or use the File Browser to open the Font Viewer and then press the Install button if you&amp;rsquo;re GUI) to install on Ubuntu.&lt;/p&gt;
&lt;p&gt;For Windows, just drag &amp;amp; drop the font to C:\WINNT\Fonts or C:\WINDOWS\Fonts depending on your system.&lt;/p&gt;
&lt;p&gt;Incidentally, if you&amp;rsquo;re looking for a particular font or lookalike, you&amp;rsquo;ll probably find it here: &lt;a href="http://www.fonts101.com/" target="_blank" rel="noreferrer"&gt;www.fonts101.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Roku Netflix player - secret screens</title><link>https://andrewmemory.acornwall.net/blog/2010-07-29-roku-netflix-player-secret-screens/</link><pubDate>Thu, 29 Jul 2010 21:03:05 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-07-29-roku-netflix-player-secret-screens/</guid><description>&lt;p&gt;Lately I&amp;rsquo;ve been exploring the Roku Netflix player. It&amp;rsquo;s got a number of &amp;ldquo;secret&amp;rdquo; screens - not really secret, since they seem to announce them regularly in the Roku forums, but I didn&amp;rsquo;t spot a place that had them all together. So here they are:&lt;/p&gt;
&lt;h2 class="relative group"&gt;Installed software versions screen
&lt;div id="installed-software-versions-screen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#installed-software-versions-screen" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Shows what versions of software (channels, screen savers, etc) are installed on your Roku.&lt;/p&gt;
&lt;p&gt;To get there: Home Home Home Up Up Left Right Left Right Left (That&amp;rsquo;s Home:3x, Up:2x, Left, Right, Left, Right, Left)&lt;/p&gt;
&lt;p&gt;Version menu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next/Prev&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Enable developer mode
&lt;div id="enable-developer-mode" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#enable-developer-mode" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Turns on a web server and opens at least one port on the Roku. Allows you to upload new channels, and download logfiles if you turn them on.&lt;/p&gt;
&lt;p&gt;To get there:&lt;/p&gt;
&lt;p&gt;Home Home Home Up Up Right Left Right Left Right (That&amp;rsquo;s Home:3x, Up:2x, Right, Left, Right, Left, Right)&lt;/p&gt;
&lt;p&gt;Developer mode menu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable/Disable installer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This reboots the Roku. Once enabled, you can go to http://&lt;em&gt;roku-ip-address&lt;/em&gt; and install packages. There is also some utility software. http://&lt;em&gt;roku-ip-address&lt;/em&gt;/plugin_inspect http://&lt;em&gt;roku-ip-address&lt;/em&gt;/plugin_install http://&lt;em&gt;roku-ip-address&lt;/em&gt;/plugin_package Once a package is built, it gets put in: http://&lt;em&gt;roku-ip-address&lt;/em&gt;/pkgs&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a post about &lt;a href="http://forums.roku.com/viewtopic.php?p=262081&amp;amp;sid=2e21e195d679694615144a0e6ec242c1" target="_blank" rel="noreferrer"&gt;bash utilities for building Roku packages&lt;/a&gt;.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Debug options screen
&lt;div id="debug-options-screen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#debug-options-screen" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Enables logging, lets you download beta releases, etc.&lt;/p&gt;
&lt;p&gt;To get there: Home Home Home Home Home FF FF FF Rewind Rewind (Home:5x, FF:3x, Rewind:2x)&lt;/p&gt;
&lt;p&gt;Debug options menu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Factory reset&lt;/li&gt;
&lt;li&gt;Cycle channel store server&lt;/li&gt;
&lt;li&gt;Cycle software update server&lt;/li&gt;
&lt;li&gt;Update software&lt;/li&gt;
&lt;li&gt;Enable/Disable debug logging&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you enable logging, you can then go to http://&lt;em&gt;roku-ip-address&lt;/em&gt;/pkgs and download tcpdump files (called log0, log1&amp;hellip; etc). You need to have Developer mode turned on as well in order to get these. Developer mode enables the http server. Turn Developer mode on first, then enable debug logging.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Quality settings screen
&lt;div id="quality-settings-screen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#quality-settings-screen" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Lets you set the bitrate of downloads from the Roku (this is not the bandwidth - the Roku uses full bandwidth until its buffer is full).&lt;/p&gt;
&lt;p&gt;To get there: Home Home Home Home Home Rewind Rewind Rewind FF FF (Home:5x, Rewind:3x, FF:2x)&lt;/p&gt;
&lt;p&gt;Quality options menu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatic&lt;/li&gt;
&lt;li&gt;3.5&lt;/li&gt;
&lt;li&gt;2.5&lt;/li&gt;
&lt;li&gt;2.0&lt;/li&gt;
&lt;li&gt;1.5&lt;/li&gt;
&lt;li&gt;1.0&lt;/li&gt;
&lt;li&gt;0.6&lt;/li&gt;
&lt;li&gt;0.3&lt;/li&gt;
&lt;li&gt;Enable/Disable playback debugging&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Reboot
&lt;div id="reboot" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#reboot" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;(thanks to G Whizz): reboots the Roku&lt;/p&gt;
&lt;p&gt;To get there: Home, Home, Home, Home, Home, Up, Rewind, Rewind, FF, FF (Home:5x, Up, Rewind:2x, FF:2x)&lt;/p&gt;
&lt;h2 class="relative group"&gt;Platform Secret Screen
&lt;div id="platform-secret-screen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#platform-secret-screen" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m not able to see this one on my Roku 2, but I found it documented at &lt;a href="http://streamfree.tv/roku/roku-remote-option-commands/" target="_blank" rel="noreferrer"&gt;streamfree.tv/roku/roku-remote-option-commands/&lt;/a&gt;. It&amp;rsquo;s available on the Roku 3500R Streaming Stick. Home, Home, Home, Home, Home, FF, Play, Rewind, Play, FF (Home:5x, FF, Play, Rewind, Play, FF)&lt;/p&gt;
&lt;p&gt;Platform menu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System Reboot&lt;/li&gt;
&lt;li&gt;Disable Network Pings&lt;/li&gt;
&lt;li&gt;Wi-Fi Remote Menu&lt;/li&gt;
&lt;li&gt;Wi-Fi Secret Screen&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class="relative group"&gt;Antenna Secret Screen
&lt;div id="antenna-secret-screen" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#antenna-secret-screen" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m not able to see this one on my Roku 2, but I found it documented on Richard LLoyd&amp;rsquo;s Youtube video. It&amp;rsquo;s available on the Roku 3500R Streaming Stick. Home, Home, Home, Home, Home, FF, Down, Rewind, Down, FF (Home:5x, FF, Down, Rewind, Down, FF)&lt;/p&gt;
&lt;p&gt;This screen just shows status, no options here.&lt;/p&gt;
&lt;h2 class="relative group"&gt;General notes
&lt;div id="general-notes" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#general-notes" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;That the Rewind button is the one to the left of the Pause/Play button; the FF button is the one to the right of the Pause/Play button. Start all sequences from the Home screen.&lt;/p&gt;
&lt;p&gt;I guess someone was a Konami fan. Some people have trouble entering these codes - I didn&amp;rsquo;t, but I see on the forums that you should enter the keypresses with a regular cadence and about half a second between presses.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know if any of these will cause trouble in the long run. I &lt;em&gt;think&lt;/em&gt; none of them survive a reset, but I&amp;rsquo;m not going to guarantee you won&amp;rsquo;t brick your Roku. Use at your own risk.&lt;/p&gt;
&lt;h2 class="relative group"&gt;Secret channels
&lt;div id="secret-channels" class="anchor"&gt;&lt;/div&gt;
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
&lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#secret-channels" aria-label="Anchor"&gt;#&lt;/a&gt;
&lt;/span&gt;
&lt;/h2&gt;
&lt;p&gt;Roku also has &amp;ldquo;secret channels&amp;rdquo; - channels you need to add to your account with a code in order for them to show up. A good list seems to be available at &lt;a href="http://streamfree.tv/apps/" target="_blank" rel="noreferrer"&gt;streamfree.tv/apps/&lt;/a&gt;, along with directions on how to add them.&lt;/p&gt;
&lt;p&gt;Know of any other secrets? Leave a comment.&lt;/p&gt;</description></item><item><title>Batch-converting images</title><link>https://andrewmemory.acornwall.net/blog/2010-06-29-batch-converting-images/</link><pubDate>Tue, 29 Jun 2010 19:15:53 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-06-29-batch-converting-images/</guid><description>&lt;p&gt;I had a wad of images that I needed to resize from 300dpi and high-resolution jpg to 4.5x6 (or 6x4.5) low resolution at 72 dpi.&lt;/p&gt;
&lt;p&gt;First, I installed ImageMagick: &lt;code&gt;sudo aptitude install imagemagick&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then I opened GIMP and determined the pixel width and height of one image. (Image -&amp;gt; Canvas Size). In my case, it was 3264x2448.&lt;/p&gt;
&lt;p&gt;Next, I resized the image to the size I wanted. That turned out to be 432x324.&lt;/p&gt;
&lt;p&gt;In other words, I wanted my new images to be 0.132352941 of the original image. A quick test told me I was on the right track: &lt;code&gt;convert P4250049.JPG -resize 13.2352941% test.jpg&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The first time I did this I forgot the % sign and got a 13x10 pixel image - not exactly what I wanted.&lt;/p&gt;
&lt;p&gt;So, on to batch-converting everything in a directory: &lt;code&gt;mkdir ./resized for i in *.JPG; do echo $i convert $i -resize 13.235941% -quality 20 ./resized/$i done&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And all my resized images were in the resized directory below the image directory. (Did I mention I wanted to reduce the quality so my images would be smaller too? Yep, that&amp;rsquo;s what the -quality line does.)&lt;/p&gt;</description></item><item><title>Backing up a disk with SysRescCD</title><link>https://andrewmemory.acornwall.net/blog/2010-06-20-backing-up-a-disk-with-sysresccd/</link><pubDate>Sun, 20 Jun 2010 16:51:00 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-06-20-backing-up-a-disk-with-sysresccd/</guid><description>&lt;p&gt;The documentation for the very good &lt;a href="http://www.sysresccd.org" target="_blank" rel="noreferrer"&gt;SysRescCD&lt;/a&gt; has changed, so I can&amp;rsquo;t find the standard &amp;ldquo;here&amp;rsquo;s how to back up a disk&amp;rdquo; using sfdisk and partimage anymore.&lt;/p&gt;
&lt;p&gt;Luckily, it got saved here: &lt;a href="http://www.hackadmin.com/2009/05/31/disk-imaging-with-partimage/" target="_blank" rel="noreferrer"&gt;www.hackadmin.com/2009/05/31/disk-imaging-with-partimage/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For future reference, this is a good way to back up a disk.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Boot the machine with the disk using SysRescCD.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mount a big NFS/CIFS drive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy the MBR:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;dd if=/dev/sda of=/cifs/sda.mbr count=1 bs=512&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy the partition table from the drive:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; sfdisk -d /dev/sda &amp;gt; /cifs/sda.sfdisk&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run partimage on each partition on the drive&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, for good measure,&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;dd if=/dev/sda | gzip &amp;gt; /cifs/sda.dd.gz&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can use kill -USR1 &lt;em&gt;pid&lt;/em&gt; on the dd process id (not the gzip process id) to see progress.&lt;/p&gt;
&lt;p&gt;Most of the restore is straightforward. sfdisk can take its output as input; partimage has restore built in. To decompress the gzip dd image, use:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;gzip -dc /cifs/sda.dd.gz | dd of=/dev/sda&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Incidentally, a good site for dd information is here: &lt;a href="http://www.softpanorama.org/Tools/dd.shtml" target="_blank" rel="noreferrer"&gt;www.softpanorama.org/Tools/dd.shtml&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Setting disk labels in Linux</title><link>https://andrewmemory.acornwall.net/blog/2010-06-05-setting-disk-labels-in-linux/</link><pubDate>Sat, 05 Jun 2010 22:00:16 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-06-05-setting-disk-labels-in-linux/</guid><description>&lt;p&gt;&lt;a href="https://andrewmemory.acornwall.net/blog/2009-12-15-setting-disk-uuids" &gt;Back in December&lt;/a&gt;, I wrote about setting UUIDs so multiple disks could be mounted in the same place using /etc/fstab.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve since decided that was dumb. Disks should have unique UUIDs - Linux may use that for more than just mounting the file system. Luckily, there is a better option: the disk label.&lt;/p&gt;
&lt;p&gt;Mounting a disk using the disk label is very similar to mounting using UUIDs. First, you need to give the disk a label. I think you can do that when you mkfs, but it&amp;rsquo;s pretty cheap to do it after you&amp;rsquo;ve already bulit the file system using: &lt;code&gt;e2label /dev/sdb1 mylabel&lt;/code&gt; (substituting whatever device you want for /dev/sdb1 and whatever label you want for mylabel. This will work for ext2, ext3 and ext4 - if you&amp;rsquo;re using another file system, it should have its own label utility.)&lt;/p&gt;
&lt;p&gt;Then, rather than specifying UUID= in /etc/fstab, specify: &lt;code&gt;LABEL=mylabel&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Your disk will mount automatically, but still have a unique ID. Sounds better to me.&lt;/p&gt;
&lt;p&gt;Sun has a useful tutorial at: &lt;a href="http://wikis.sun.com/display/BigAdmin/Using&amp;#43;Disk&amp;#43;Labels&amp;#43;on&amp;#43;Linux&amp;#43;File&amp;#43;Systems" target="_blank" rel="noreferrer"&gt;http://wikis.sun.com/display/BigAdmin/Using+Disk+Labels+on+Linux+File+Systems&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Straightening pictures with Gimp</title><link>https://andrewmemory.acornwall.net/blog/2010-04-15-straightening-pictures-with-gimp/</link><pubDate>Thu, 15 Apr 2010 22:17:34 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-04-15-straightening-pictures-with-gimp/</guid><description>&lt;p&gt;A while back, I discovered a very useful tool in Gimp to straighten images. This is useful if you have a bunch of scanned text (its advertised usage) or if you have what I have: a group of pictures that were scanned in on a flatbed scanner and all 2-3 degrees off of horizontal.&lt;/p&gt;
&lt;p&gt;Since upgrading Ubuntu, I&amp;rsquo;d lost track of that plugin. I started by searching for &amp;ldquo;straighten picture&amp;rdquo; and that led me to the Straighten and Crop plugin: &lt;a href="http://registry.gimp.org/node/18821" target="_blank" rel="noreferrer"&gt;http://registry.gimp.org/node/18821&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a useful tool, but not what I wanted. (It lets you pick two points on an image&amp;ndash;say, the leftmost and rightmost horizon lines&amp;ndash;and rotate the image so those two points are even.)&lt;/p&gt;
&lt;p&gt;Eventually I figured out the tool I wanted was Deskew (aka auto-straighten). It can be found here: &lt;a href="http://registry.gimp.org/node/2958" target="_blank" rel="noreferrer"&gt;http://registry.gimp.org/node/2958&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I downloaded the .deb for 1.1 and installed it in my Ubuntu 9.10 with:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo dpkg -i gimp-deskew-plugin_1.1_i386.deb &lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Once it&amp;rsquo;s installed, it&amp;rsquo;s not immediately obvious where in Gimp it goes. (And of course the web page is no help.) The secret location is:&lt;/p&gt;
&lt;p&gt;Filters -&amp;gt; Misc -&amp;gt; Deskew&lt;/p&gt;
&lt;p&gt;Load an image, select that, and the image will be straightened. Then you can crop it and save it; nobody will ever know it wasn&amp;rsquo;t straight on your scanner.&lt;/p&gt;</description></item><item><title>A minimal xorg.conf with modeline</title><link>https://andrewmemory.acornwall.net/blog/2010-03-25-a-minimal-xorg-conf-with-modeline/</link><pubDate>Thu, 25 Mar 2010 22:18:57 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-03-25-a-minimal-xorg-conf-with-modeline/</guid><description>&lt;p&gt;Back in the Bad Old Days, the X configuration file was miles long and you had to get it all right. Nowadays, X guesses at most things pretty accurately. This means you might not have &lt;em&gt;anything&lt;/em&gt; in your xorg.conf file. This makes changing the Monitor section trickier.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a default xorg.conf file with a modeline. (This is for a Sharp LL-172C-B monitor; your modeline will probably differ.)&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Section &amp;#34;Device&amp;#34;
Identifier &amp;#34;Configured Video Device&amp;#34;
EndSection
Section &amp;#34;Monitor&amp;#34;
Identifier &amp;#34;Configured Monitor&amp;#34;
# Modeline &amp;#34;1280x1024&amp;#34; MHz HSize HTotal HSyncEnd HSyncDelay VSize VSyncStart VSyncEnd VTotal -hsync &amp;#43;vsync
Modeline &amp;#34;1280x1024&amp;#34; 109.00 1280 1322 1450 1700 1024 1027 1034 1066 -hsync &amp;#43;vsync
EndSection
Section &amp;#34;Screen&amp;#34;
Identifier &amp;#34;Default Screen&amp;#34;
Monitor &amp;#34;Configured Monitor&amp;#34;
Device &amp;#34;Configured Video Device&amp;#34;
EndSection&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Exposing the Firefox Location Bar behaviour</title><link>https://andrewmemory.acornwall.net/blog/2010-02-19-exposing-the-firefox-location-bar-behaviour/</link><pubDate>Fri, 19 Feb 2010 00:13:42 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-02-19-exposing-the-firefox-location-bar-behaviour/</guid><description>&lt;p&gt;On several machines, I&amp;rsquo;ve got Seamonkey 2.0.2 installed. It has some very nice fine-grained preferences to control what shows up in the location bar.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve also got a netbook where I put Firefox 3.6 because I didn&amp;rsquo;t need everything that&amp;rsquo;s in Seamonkey. Firefox has really limited preferences to control what shows up in the location bar.&lt;/p&gt;
&lt;p&gt;Luckily, both browsers behave the same way using about:config. So it&amp;rsquo;s possible to get Seamonkey&amp;rsquo;s fine-grained control on Firefox, as long as you don&amp;rsquo;t care about a UI to do it.&lt;/p&gt;
&lt;p&gt;A very useful article can be found here: &lt;a href="http://kb.mozillazine.org/Browser.urlbar.default.behavior" target="_blank" rel="noreferrer"&gt;http://kb.mozillazine.org/Browser.urlbar.default.behavior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I read that article, and was about to calculate the value I wanted, when I realized the simplest way to do it is to go to the Seamonkey install, set up the preferences the way you want (&amp;ldquo;Autocomplete from your browsing history as you type&amp;rdquo;, &amp;ldquo;Match only websites you&amp;rsquo;ve typed previously&amp;rdquo;, &amp;ldquo;Only match locations, not website titles&amp;rdquo;, &amp;ldquo;Match anywhere but preferring word boundaries&amp;rdquo;, &amp;ldquo;Automatically prefill the best match&amp;rdquo;, &amp;ldquo;Show list of matching results&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Then look at the values on Seamonkey for&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;browser.urlbar.default.behavior&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;using about:config, and enter that value (and any others you care about) in Firefox using about:config on that browser.&lt;/p&gt;
&lt;p&gt;In my case, I set browser.urlbar.default.behavior to 49 to get what I wanted.&lt;/p&gt;</description></item><item><title>Monitoring hard disk health with smartmontools</title><link>https://andrewmemory.acornwall.net/blog/2010-01-23-monitoring-hard-disk-health-with-smartmontools/</link><pubDate>Sat, 23 Jan 2010 23:50:21 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-01-23-monitoring-hard-disk-health-with-smartmontools/</guid><description>&lt;p&gt;I always install smartmontools when I use SMART-enabled hard drives. It wasn&amp;rsquo;t until recently, though, that I started automating the tests.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a link that explains it: &lt;a href="http://www.captain.at/howto-linux-smartmontools-smartctl.php" target="_blank" rel="noreferrer"&gt;http://www.captain.at/howto-linux-smartmontools-smartctl.php&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Based on that, here&amp;rsquo;s the code I added to my /etc/smartd.conf: &lt;code&gt;# Per http://www.captain.at/howto-linux-smartmontools-smartctl.php DEVICESCAN -d sat -a -o on -S on -s (S/../.././19|L/../../3/21|C/../.././20) -m root # -d sat because /dev/sdX doesn't seem to run without it # S/../.././19 = short test every day at 19:00 # C/../.././20 = conveyance test every day at 20:00 # L/../../3/21 = long test every wednesday (3) at 21:00 # -m root = root will be emailed if anything strange occurs&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Note that this has to come before any other DEVICESCAN (apparently the first one takes priority). Don&amp;rsquo;t forget to kill -HUP the smartd process so the new config will take effect, and make sure /etc/default/smartmontools has uncommented: &lt;code&gt;start_smartd=yes&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After this, you can get useful info with: &lt;code&gt;sudo smartctl -l selftest /dev/sda&lt;/code&gt; (or whatever drive you care about).&lt;/p&gt;
&lt;p&gt;A very good description of the output of smartctl can be found at: &lt;a href="http://www.cyberciti.biz/tips/linux-find-out-if-harddisk-failing.html" target="_blank" rel="noreferrer"&gt;www.cyberciti.biz/tips/linux-find-out-if-harddisk-failing.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Adding fldigi from the Berlios repository</title><link>https://andrewmemory.acornwall.net/blog/2010-01-15-adding-fldigi-from-the-berlios-repository/</link><pubDate>Fri, 15 Jan 2010 00:32:30 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2010-01-15-adding-fldigi-from-the-berlios-repository/</guid><description>&lt;p&gt;The version of fldigi that&amp;rsquo;s built for Ubuntu 9.10 is a bit out of date. Luckily, the Berlios repository has a more recent version, and you can install that.&lt;/p&gt;
&lt;p&gt;The instructions are &lt;a href="https://fedorahosted.org/fldigi/wiki/Packages" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;. In short form (specific to Ubuntu 9.10):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Edit /etc/apt/sources.list and add the following lines:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Berlios repository for updated FLDigi
deb http://download2.berlios.de/pub/fldigi/binaries karmic main&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Get the key for fldigi&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo apt-key adv --recv-keys --keyserver http://fldigi.berlios.de/binaries/fldigi-pkg-key.asc 8E7306F5&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install fldigi&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude update; sudo aptitude install fldigi&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Setting disk UUIDs</title><link>https://andrewmemory.acornwall.net/blog/2009-12-14-setting-disk-uuids/</link><pubDate>Mon, 14 Dec 2009 20:41:03 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-12-14-setting-disk-uuids/</guid><description>&lt;p&gt;After setting up mounting by UUID as described &lt;a href="https://andrewmemory.acornwall.net/blog/2009-12-07-automatically-mounting-drives-with-uuids" &gt;here&lt;/a&gt;, I realized I had a problem.&lt;/p&gt;
&lt;p&gt;I wanted to swap disks out (that is, have multiple versions of my backup drive). However, since the drives are being mounted by UUID, I wanted to have only one entry in /etc/fstab for all my &amp;ldquo;backup&amp;rdquo; drives.&lt;/p&gt;
&lt;p&gt;It appears that dd would work, but that seemed inelegant, especially if future drives are different sizes. So I did a bit of searching and found the discussion &lt;a href="http://nixcraft.com/shell-scripting/948-change-uuid-ext3-partition.html" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In short, I could use &lt;code&gt;sudo tune2fs /dev/sdb1 -U new-uuid-number&lt;/code&gt; to set the UUID of a file system to whatever I want.&lt;/p&gt;
&lt;p&gt;After I&amp;rsquo;d done that, I couldn&amp;rsquo;t figure out how to refresh the UUID in /dev/disk/by-uuid/ - even after ejecting and re-inserting the SATA disk, the old UUID still showed up. I ended up rebooting (sigh) and now I can swap drives out with abandon. I probably should have specified the UUID when I did the mkfs. This looks like &lt;a href="https://bugs.launchpad.net/ubuntu/&amp;#43;source/debian-installer/&amp;#43;bug/234920" target="_blank" rel="noreferrer"&gt;this bug&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t tried it, but I would guess having two disks with the same UUID in the machine at the same time would be a Bad Thing.&lt;/p&gt;
&lt;p&gt;In retrospect, it would probably have been better if I&amp;rsquo;d used disk labels instead of UUIDs.&lt;/p&gt;</description></item><item><title>Changing Unix/Linux filenames to handle DOS conventions</title><link>https://andrewmemory.acornwall.net/blog/2009-12-12-changing-unixlinux-filenames-to-handle-dos-conventions/</link><pubDate>Sat, 12 Dec 2009 15:24:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-12-12-changing-unixlinux-filenames-to-handle-dos-conventions/</guid><description>&lt;p&gt;Recently, I had a bunch of files with characters in their names that made them hard to handle under Windows. Although Unix has no problems with :, ? and others, DOS / Windows doesn&amp;rsquo;t handle them well. This made using them on my CIFS share a bit of a pain.&lt;/p&gt;
&lt;p&gt;To rename them, I hacked up a quick Groovy script. It maps all &amp;ldquo;weird&amp;rdquo; characters to _, which is pretty much universal.&lt;/p&gt;
&lt;p&gt;Note that this script doesn&amp;rsquo;t currently handle the case where two files map to the same name. If you have :foo and ?foo, they&amp;rsquo;ll both get mapped to _foo and you&amp;rsquo;ll lose one of them.&lt;/p&gt;
&lt;p&gt;I called it dosname because it was late and I wasn&amp;rsquo;t feeling creative.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#!/usr/bin/groovy -
if(args.length == 0) {
printArgs()
System.exit(0);
}
dirName = args[0];
new File(dirName).eachFile() { file -&amp;gt;
def matcher = (file.getName() =~ /[\?\:\&amp;#34;\\]/)
def newName = matcher.replaceAll(&amp;#34;_&amp;#34;)
File newFile = new File(dirName &amp;#43; &amp;#34;/&amp;#34; &amp;#43; newName.toString())
println file.getName() &amp;#43; &amp;#34; -&amp;gt; &amp;#34; &amp;#43; newFile.getName()
file.renameTo(newFile)
}
System.exit(0);
def printArgs() {
println(&amp;#34;Usage: dosname [dirname]&amp;#34;)
println(&amp;#34; Note: I don&amp;#39;t handle the case where two files map to the same filename yet!&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;The interesting bit is in the line&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;def matcher = (file.getName() =~ /[\?\:\&amp;#34;\\]/)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;That line defines the regular expression which contains a group of characters which will be replaced by _. Right now it&amp;rsquo;s &lt;/p&gt;
\[?:"\\\]&lt;p&gt; (all quoted with \ because that&amp;rsquo;s what you have to do in regex).&lt;/p&gt;
&lt;p&gt;Run it with &amp;ldquo;dosname &lt;em&gt;directoryname&lt;/em&gt;&amp;rdquo;. There&amp;rsquo;s no way to reverse its effects, so try not to use it on useful directories like /etc/.&lt;/p&gt;
&lt;p&gt;Also, I needed to install OpenJDK6 JDK (not just the runtime) in order to run Groovy on Ubuntu 9.04. Go figure.&lt;/p&gt;
&lt;p&gt;Since I don&amp;rsquo;t know Groovy, I stole most of this code from &lt;a href="http://www.rossenstoyanchev.org/write/prog/java/groovy1.html" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Using rsync to back up a Windows box to Ubuntu Server 8.04</title><link>https://andrewmemory.acornwall.net/blog/2009-12-10-using-rsync-to-back-up-a-windows-box-to-ubuntu-server-8-04/</link><pubDate>Thu, 10 Dec 2009 23:49:53 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-12-10-using-rsync-to-back-up-a-windows-box-to-ubuntu-server-8-04/</guid><description>&lt;p&gt;After getting rsync working so well for backing up hard drive to hard drive, I naturally wanted to back up from my Windows box to my Ubuntu server. Luckily, &lt;a href="http://www.cygwin.com" target="_blank" rel="noreferrer"&gt;Cygwin&lt;/a&gt; has an rsync for Windows - so I started by installing that. (I actually already had it installed - Cygwin is nice.)&lt;/p&gt;
&lt;p&gt;I found some good instructions &lt;a href="http://a1979shakedown.wordpress.com/2009/01/19/set-up-an-rsync-server-in-ubuntu-for-file-syncing-between-machines/" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;, and used them as the basis for what I did.&lt;/p&gt;
&lt;p&gt;The steps I went through:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First I created /etc/rsyncd.conf. I wanted to share a single directory called shared, so I had just one entry:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;[shared]
path=/data/shared
comment=Shared directory
uid=andrew
gid=sambashare
read only=false
auth users=rsyncuser
secrets file=/etc/rsyncd.secret&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I picked group sambashare just to be consistent with my Samba configuration. rsyncuser does not exist on the machine; it is instead mapped to andrew (uid)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next I created /etc/rsyncd.secret:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;rsyncuser:secretrsyncpassword&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After that, I needed to enable rsync (both right now and after reboot). First, I edited /etc/default/rsync and changed RSYNC_ENABLE to true:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;RSYNC_ENABLE=true&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next I started the rsync daemon:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo /etc/init.d/rsync restart&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The /etc/inetd.conf of a plain Ubuntu 8.04 Server install was empty, which was a surprise to me. There appears to be a utility called &amp;ldquo;update-inetd&amp;rdquo; to update the file and then restart inetd. Because I couldn&amp;rsquo;t be bothered to find out the syntax, I just edited /etc/inetd.conf and put in:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;rsync stream tcp nowait root /usr/local/bin/rsync rsyncd --daemon&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then I used update-inetd from the command line to restart inetd for me:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo update-inetd --disable rsync
sudo update-inetd --enable rsync&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this point, I could telnet to port 873 (the rsync port) and see a connection, but rsync itself still didn&amp;rsquo;t want to run. Instead, it failed (even when I entered the correct password) with this message:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;@ERROR: auth failed on module shared
rsync error: error starting client-server protocol (code 5) at main.c(1383)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Andrew Tridgell has awesome utilities, but he really has a problem with displaying meaningful messages.&lt;/p&gt;
&lt;p&gt;It turns out that rsync really wants the secrets file (in my case /etc/rsyncd.secret) to be readable only by the rsync user. There is a global option &amp;ldquo;strict modes&amp;rdquo; that can be set to false to allow you to get around this, but I decided why not just do the right thing:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo chown root.root /etc/rsyncd.secret
sudo chmod 400 /etc/rsyncd.secret&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, I needed a command for the rsync on my Windows box. Here was one I came up with: &lt;code&gt;@echo off set RSYNC_PASSWORD=secretrsyncpassword rsync -vrtz --delete --delete-excluded --exclude &amp;quot;Temp/&amp;quot; --exclude &amp;quot;*.tmp&amp;quot; --exclude &amp;quot;parent.lock&amp;quot; --exclude &amp;quot;UsrClass.dat*&amp;quot; --exclude &amp;quot;NTUSER.DAT&amp;quot; --exclude &amp;quot;ntuser.dat.LOG&amp;quot; --exclude &amp;quot;Cache/&amp;quot; &amp;quot;/cygdrive/c/Documents and Settings/&amp;quot; &amp;quot;rsyncuser@myserver::shared/win2k-backup/Documents and Settings&amp;quot;&lt;/code&gt; This command preserves timestamps (t) and prints out what it&amp;rsquo;s doing (v) as it recursively (r) goes through Documents and Settings and backs up the files, using compression so it&amp;rsquo;s faster over the net (z). It excludes a bunch of things.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I should probably have used a file to specify what&amp;rsquo;s excluded (&amp;ndash;exclude-from), but I was lazy and just kept adding to the command line. I&amp;rsquo;m excluding cache files, as well as lock/log files that are kept open by Windows 2000 (they report as errors if you try to back them up).&lt;/p&gt;
&lt;p&gt;At some point I&amp;rsquo;ll probably add a &amp;ldquo;hosts allow&amp;rdquo; line to my /etc/rsyncd.conf, as soon as I decide which machines I want to let backup to the server.&lt;/p&gt;</description></item><item><title>Automatically mounting drives with UUIDs</title><link>https://andrewmemory.acornwall.net/blog/2009-12-06-automatically-mounting-drives-with-uuids/</link><pubDate>Sun, 06 Dec 2009 21:28:42 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-12-06-automatically-mounting-drives-with-uuids/</guid><description>&lt;p&gt;Until now, I&amp;rsquo;ve always mounted drives by accessing their devices. However, I ran into a situation where this wouldn&amp;rsquo;t work. Luckily, Ubuntu has the ablility to access drives by UUID - which solved my problem.&lt;/p&gt;
&lt;p&gt;I have a drive that holds networked data, which I mount on Ubuntu 8.04 Server as /data/. I also back that drive up to a drive which is normally read-only as /databackup/.&lt;/p&gt;
&lt;p&gt;Both of these drives are SATA - meaning they could be unplugged at any time. If both are unplugged, whichever drive gets plugged in first becomes /dev/sda1 - and the other becomes /dev/sdb1. This means I can&amp;rsquo;t rely on mounting /dev/sda1 on /data and /dev/sdb1 on /databackup.&lt;/p&gt;
&lt;p&gt;To get around this, I mounted the drives using UUID in /etc/fstab. First, I had to figure out what the UUIDs of the drives were. To start with, I killed Samba and unmounted both - I knew /dev/sda1 was /data and /dev/sdb1 was /databackup. Then I obtained the UUIDs of both drives:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo vol_id --uuid /dev/sda1
7b932326-717b-4ba6-bef2-fedfbafcabe6
$ sudo vol_id --uuid /dev/sdb1
94efd7bd-8498-46f3-ab6d-cb706c413567&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Next, I replaced the device mounts (/dev/sda1 and /dev/sdb1) in /etc/fstab with:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;UUID=7b932326-717b-4ba6-bef2-fedfbafcabe6 /data ext3...
UUID=94efd7bd-8498-46f3-ab6d-cb706c413567 /databackup ext3...&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Under Ubuntu 9.10, it appears that vol_id has merged into blkid - so now you would use:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo blkid /dev/sda1
/dev/sda1: UUID=&amp;#34;f30ba2a3-9da6-48b1-8ab5-75952ef26cc4&amp;#34; TYPE=&amp;#34;ext3&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to determine the UUID, and then update /etc/fstab as you&amp;rsquo;d do for 8.04.&lt;/p&gt;</description></item><item><title>Simple backup using rsync</title><link>https://andrewmemory.acornwall.net/blog/2009-12-03-simple-backup-using-rsync/</link><pubDate>Thu, 03 Dec 2009 23:46:20 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-12-03-simple-backup-using-rsync/</guid><description>&lt;p&gt;A simple way to back up your data from one drive to another is rsync. The magical incantation (assuming the data drive is /dev/sda1 mounted on /data and the backup drive is /dev/sdb1 mounted on /databackup, and you normally keep the backup drive mounted read-only):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo mount -o remount,rw /dev/sdb1 /databackup
sudo rsync -a --delete --progress /data/ /databackup
sudo mount -o remount,ro /dev/sdb /databackup&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item><item><title>Setting up Samba on Ubuntu Server 8.04</title><link>https://andrewmemory.acornwall.net/blog/2009-11-27-setting-up-samba-on-ubuntu-server-8-04/</link><pubDate>Fri, 27 Nov 2009 00:43:59 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-11-27-setting-up-samba-on-ubuntu-server-8-04/</guid><description>&lt;p&gt;It&amp;rsquo;s been a few years since I last set up a Samba system, and the process is still as painful as ever. A lot of this pain comes from multiple authentication systems, which all have to be in sync for things to work.&lt;/p&gt;
&lt;p&gt;I started out with the link here: &lt;a href="http://ubuntuforums.org/showthread.php?t=202605" target="_blank" rel="noreferrer"&gt;http://ubuntuforums.org/showthread.php?t=202605&lt;/a&gt; and pretty much ignored all of it. In the end, I took the default 8.04.3 /etc/samba/smb.conf, and made the following changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Set the workgroup in the global stanza&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Added stanzas like the following:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;[music]
path = /music
browseable = yes
read only = no
guest ok = no
create mask = 0644
directory mask = 0755
force user = andrew
force group = sambashare&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that I&amp;rsquo;m using user permissions, not share permissions. So I had to add and enable the Samba user:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo smbpasswd -L -a andrew
sudo smbpasswd -L -e andrew&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Originally, I had force group = andrew. When I tried to mount using this option, I&amp;rsquo;d see:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ sudo mount -a
mount error(5): Input/output error
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;What lovely error messages. I found a semi-useful diagnostic tool, smbclient:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;smbclient //server/music -U andrew
Enter andrew&amp;#39;s password:
Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.28a]
tree connect failed: NT_STATUS_NO_SUCH_GROUP&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I did have an andrew group, but the user andrew wasn&amp;rsquo;t in that group according to /etc/group, so I switched to sambashare (which does have andrew as a member). Then it worked. Just adding andrew as a member of the group andrew in /etc/group was not sufficient. No idea why, but probably Samba has some concept of groups that needs to be set up too.&lt;/p&gt;
&lt;p&gt;Next, I tried to connect again:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;smbclient //server/music -U andrew
Enter andrew&amp;#39;s password:
Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.28a]
tree connect failed: NT_STATUS_BAD_NETWORK_NAME &lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;This let me search on NT_STATUS_BAD_NETWORK_NAME and discover that, gee, that means permissons are bad for the directory that is being shared. Nothing better than helpful error messages.&lt;/p&gt;
&lt;p&gt;A final /etc/init.d/samba restart and I could connect.&lt;/p&gt;</description></item><item><title>Creating credential files for automatic Samba mounts in /etc/fstab</title><link>https://andrewmemory.acornwall.net/blog/2009-11-26-creating-credential-files-for-automatic-samba-mounts-in-etcfstab/</link><pubDate>Thu, 26 Nov 2009 23:55:28 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-11-26-creating-credential-files-for-automatic-samba-mounts-in-etcfstab/</guid><description>&lt;p&gt;It&amp;rsquo;s handy to have credentials for each Samba server so you don&amp;rsquo;t have public passwords in /etc/fstab for the Samba file systems you want to mount on boot. Here&amp;rsquo;s how I do it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a directory /etc/samba/credentials&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a file /etc/samba/credentials/myserver&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the myserver file, put the credentials for that server:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;username=myusername
password=mypassword&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; spaces are important here - don&amp;rsquo;t use “ = ”, use &amp;ldquo;=&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;chown -R root.root /etc/samba/credentials&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;chmod 700 /etc/samba/credentials&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;chmod 600 /etc/samba/credentials/myserver&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once this is done, you can add lines for each mount of that server to your /etc/fstab:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;//myserver/music /music smbfs credentials=/etc/samba/credentials/myserver 0 0
//myserver/shared /shared smbfs credentials=/etc/samba/credentials/myserver 0 0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Note that the file in /etc/samba/credentials doesn&amp;rsquo;t have to be named the same thing as the server name - it just makes it easier.&lt;/p&gt;
&lt;p&gt;This also survives the Ubuntu upgrade process, so you just have to update /etc/fstab if you upgrade to a new release, and can keep the same credentials files.&lt;/p&gt;</description></item><item><title>Compiling soundmodem-0.14 on Ubuntu 9.10</title><link>https://andrewmemory.acornwall.net/blog/2009-11-21-compiling-soundmodem-0-14-on-ubuntu-9-10/</link><pubDate>Sat, 21 Nov 2009 00:00:47 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-11-21-compiling-soundmodem-0-14-on-ubuntu-9-10/</guid><description>&lt;p&gt;The soundmodem that ships with Ubuntu 9.10 is not the latest. The latest is available here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.baycom.org/~tom/ham/soundmodem/" target="_blank" rel="noreferrer"&gt;http://www.baycom.org/~tom/ham/soundmodem/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In order to compile it, you need to install a bunch of development packages. Here&amp;rsquo;s what I did:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude install libasound2-dev
sudo aptitude install libxml2-dev
sudo aptitude install libgtk2.0-dev
sudo aptitude install libaudiofile-dev&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Also, if you don&amp;rsquo;t have the compiler already you&amp;rsquo;ll need:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo aptitude install g&amp;#43;&amp;#43;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;tar xzvf soundmodem-0.14.tar.gz
cd soundmodem-0.14
sh ./configure
make&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;To test it, go to the configapp/src directory and run&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo ./soundmodemconfig&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;to set up the configuration. Finally, go to the soundcard directory and run:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo ./soundmodem -v5&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Assuming you&amp;rsquo;ve configured everything correctly, you should see something like:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sm[10093]: mkiss: ifname sm0 mtu 256 hwaddr CALLSIGN-0 ipaddr 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255
sm[10093]: unknown node &amp;#34;text&amp;#34;
ALSA: Using sample rate 9600, sample format 2, significant bits 16, buffer size 4800, period size 150
ALSA: Using sample rate 9600, sample format 2, significant bits 16, buffer size 4800, period size 150
sm[10093]: audio: starting &amp;#34;plughw:0,0&amp;#34;&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;In a different terminal, you can then ifconfig sm0 to see that it&amp;rsquo;s there.&lt;/p&gt;</description></item><item><title>Tuning X video with modeline</title><link>https://andrewmemory.acornwall.net/blog/2009-10-30-tuning-x-video-with-modeline/</link><pubDate>Fri, 30 Oct 2009 14:40:09 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-10-30-tuning-x-video-with-modeline/</guid><description>&lt;p&gt;After setting my monitor up, I found it didn&amp;rsquo;t exactly match the other devices on my kvm switch. I could get around this by pressing the &amp;ldquo;Auto Adjust&amp;rdquo; button on the monitor, but that meant I&amp;rsquo;d have to adjust again when I switched to a different machine.&lt;/p&gt;
&lt;p&gt;Usually, what I do in these cases is to use xvidtune to fine-tune things. Unfortunately, that didn&amp;rsquo;t work - it would always fail with &amp;ldquo;Unable to query monitor info&amp;rdquo; even when I disconnected the kvm switch and went directly into the monitor.&lt;/p&gt;
&lt;p&gt;What that meant is that I&amp;rsquo;d have to hack the modeline manually. I found a good discussion of modelines &lt;a href="http://howto-pages.org/ModeLines/" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A modeline has the following format:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;name dotclock hsize hsyncstart hsyncend htotal vsize vsyncstart vsyncend vtotal hsyncpol vsyncpol&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;I needed to move the image on my monitor to the right (I had a black bar on the right hand side, and the left hand side was clipped off). To move the monitor right, I needed to DECREASE hsyncstart and hsyncend by the same amount. (Then I logged out and logged back in to restart X so the new settings were being used.)&lt;/p&gt;
&lt;p&gt;Once the screen was more or less centred, I DECREASED htotal to make the display wider. (And then logged out and logged in again&amp;hellip;.)&lt;/p&gt;
&lt;p&gt;After that, the image was still a little further right than I wanted, so I DECREASED hsyncstart and hsyncend again to get the wider display centered again. One more restart of X and things were groovy.&lt;/p&gt;
&lt;p&gt;My current modeline is: &lt;code&gt;Section &amp;quot;Monitor&amp;quot; Identifier &amp;quot;Configured Monitor&amp;quot; # 1280x1024 59.89 Hz (CVT 1.31M4) hsync: 63.67 kHz; pclk: 109.00 MHz # Modeline &amp;quot;1280x1024_60.00&amp;quot; MHz HSize HTotal HSyncEnd HSyncDelay VSize VSyncStart VSyncEnd VTotal HSyncPol VSyncPol Modeline &amp;quot;1280x1024_60.00&amp;quot; 109.00 1280 1322 1450 1700 1024 1027 1034 1066 -hsync +vsync EndSection&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now things are automatically adjusted when I switch from one box to another.&lt;/p&gt;
&lt;p&gt;Note: This won&amp;rsquo;t work if you aren&amp;rsquo;t currently displaying &lt;em&gt;something&lt;/em&gt; in the mode you want to use. Also, keep a copy of your original values in your xorg.conf file just in case things go awry - it&amp;rsquo;s possible to put all your controls offscreen, which can make things challenging.&lt;/p&gt;</description></item><item><title>Modeline for Samsung LN32A450C</title><link>https://andrewmemory.acornwall.net/blog/2009-10-25-modeline-for-samsung-ln32a450c/</link><pubDate>Sun, 25 Oct 2009 14:28:51 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-10-25-modeline-for-samsung-ln32a450c/</guid><description>&lt;p&gt;When I switched my video card after the capacitors burnt out on the old one, I found I could no longer do 1366x768 video on a Samsung LN32A450C. Most frustrating was the fact that I&amp;rsquo;d see the video for about four seconds, before the TV decided it didn&amp;rsquo;t want to display it and showed &amp;ldquo;Mode not supported&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Apparently, this is a common problem with Samsung TVs - and cvt was no help.&lt;/p&gt;
&lt;p&gt;Luckily, I found &lt;a href="http://thecosmotron.com/2008/11/05/samsung-ln32a450-nvidia-drivers-and-ubuntu/" target="_blank" rel="noreferrer"&gt;this post&lt;/a&gt; - so here is the modeline for the Samsung LN32A450C&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Modeline &amp;quot;1360x768&amp;quot; 85.500 1360 1440 1552 1792 768 771 777 795 +hsync +vsync&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I just had to add that to my Monitor section of /etc/X11/xorg.conf and the autodetection on Ubuntu 9.04 did the rest. This is actually 1360x768, not the specified 1366x768 that Samsung is supposed to support - but I don&amp;rsquo;t miss the few pixels on either side.&lt;/p&gt;</description></item><item><title>Ubuntu 9.04 setup - fixing the scroll wheel</title><link>https://andrewmemory.acornwall.net/blog/2009-10-21-ubuntu-9-04-setup-fixing-the-scroll-wheel/</link><pubDate>Wed, 21 Oct 2009 23:00:41 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-10-21-ubuntu-9-04-setup-fixing-the-scroll-wheel/</guid><description>&lt;p&gt;In Ubuntu with a PS/2 mouse, the scroll wheel stops working when you switch away with a KVM switch. I found some good instructions for fixing the problem on 8.04 &lt;a href="http://ramblings.gibberishcode.net/archives/getting-mouse-wheel-to-work-with-kvm-and-ubuntu/20" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are a few minor changes for 9.04. Here are the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following to /etc/modules&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;psmouse&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create /etc/modprobe.d/psmouse.conf and give it the following contents:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; # Make my mouse work with KVM
options psmouse proto=imps&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, reload the mouse module:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt; # sudo modprobe -r psmouse
# sudo modprobe -a psmouse&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Setting up the Sharp LL-172C-B Monitor on Ubuntu 9.04</title><link>https://andrewmemory.acornwall.net/blog/2009-10-21-setting-up-the-sharp-ll-172c-b-monitor-on-ubuntu-9-04/</link><pubDate>Wed, 21 Oct 2009 22:51:36 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-10-21-setting-up-the-sharp-ll-172c-b-monitor-on-ubuntu-9-04/</guid><description>&lt;p&gt;Here&amp;rsquo;s the magic to get the video mode set right for the Sharp LL-172C-B monitor (1280x1024) on Ubuntu 9.04:&lt;/p&gt;
&lt;p&gt;First, run CVT to get the modeline:&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;$ cvt 1280 1024&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Copy the output from that into the Screen section of /etc/X11/xorg.conf&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;Section &amp;#34;Monitor&amp;#34;
Identifier      &amp;#34;Configured Monitor&amp;#34;
# 1280x1024 59.89 Hz (CVT 1.31M4) hsync: 63.67 kHz; pclk: 109.00 MHz
Modeline &amp;#34;1280x1024_60.00&amp;#34;  109.00  1280 1368 1496 1712  1024 1027 1034 1063 -hsync &amp;#43;vsync
EndSection&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;Restart X and you&amp;rsquo;re in business.&lt;/p&gt;
&lt;p&gt;Update: I found I needed to tune the values a little bit. See the post &lt;a href="https://andrewmemory.acornwall.net/blog/2009-10-30-tuning-x-video-with-modeline/" &gt;here&lt;/a&gt; for more details.&lt;/p&gt;</description></item><item><title>Stopping the squeaks with soundmodem as ax.25</title><link>https://andrewmemory.acornwall.net/blog/2009-10-17-radio-packet-soundmodem-losing-the-squeaks/</link><pubDate>Sat, 17 Oct 2009 07:23:59 -0700</pubDate><author>andrewmemoryblog@gmail.com (Andrew's Memory Blog)</author><guid>https://andrewmemory.acornwall.net/blog/2009-10-17-radio-packet-soundmodem-losing-the-squeaks/</guid><description>&lt;p&gt;I tried to set up soundmodem as an AX.25 device in order to run xastir on my machine. Unfortunately, Ubuntu by default has a bunch of services installed that prevent this. (Not so much prevent it as try to shove 100k of data through the 1200-baud soundmodem, which kills it and drives you nutty if the audio is turned up.)&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I did to get around this:&lt;/p&gt;
&lt;p&gt;1. Change /etc/samba/smb.conf to include only the eth0 interface.&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;interface = eth0&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;2. Go into /etc/cups/cupsd.conf and turn off broadcasting (instructions &lt;a href="http://lists.pdxlinux.org/pipermail/plug/2007-February/052881.html" target="_blank" rel="noreferrer"&gt;here&lt;/a&gt;):&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;# Browsing was on.
#Browsing On
Browsing Off
BrowseInterval 0
# end trying to get around sm0 problem&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;3. Stop the AVAHI daemon by moving /etc/rc5.d/S18avahi-daemon to /etc/rc5.d/K18avahi-daemon and running /etc/rc5.d/K18avahi-daemon stop&lt;/p&gt;
&lt;p&gt;Note that on Ubuntu 9.10, avahi has been moved into Upstart. Stop it with&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;sudo stop avahi-daemon&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;then edit /etc/init/avahi-daemon.conf and comment out the&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#start on (filesystem
# and started dbus)&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;figure class="highlight"&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-" data-lang=""&gt;#respawn&lt;/code&gt;&lt;/pre&gt;
&lt;/figure&gt;</description></item></channel></rss>