disable gopherproxy for now - www.codemadness.org - www.codemadness.org saait content files
(HTM) git clone git://git.codemadness.org/www.codemadness.org
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 78b5b3b823e8797acce587b943d306bf15b85d81
(DIR) parent b8b1949da72e732d4b0ce18e4b12baf1a9ed9750
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 23 Nov 2025 14:22:46 +0100
disable gopherproxy for now
Diffstat:
M output/atom_content.xml | 2 ++
M output/atom_content_gopher.xml | 2 ++
M output/gopher-proxy.html | 2 ++
M output/gopher-proxy.md | 4 ++++
M output/jsonfeed_content.json | 2 +-
M output/jsonfeed_content_gopher.json | 2 +-
M output/phlog/gopher-proxy | 4 ++++
M output/rss_content.xml | 2 ++
M output/rss_content_gopher.xml | 2 ++
M output/sfeed_content.tsv | 2 +-
M output/sfeed_content_gopher.tsv | 2 +-
M pages/gopher-proxy.md | 4 ++++
12 files changed, 26 insertions(+), 4 deletions(-)
---
(DIR) diff --git a/output/atom_content.xml b/output/atom_content.xml
@@ -1726,6 +1726,8 @@ the basic Gopher types and has some restrictions to prevent some abuse.</p>
<p>For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>
+<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>
+<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>
]]></content>
</entry>
<entry>
(DIR) diff --git a/output/atom_content_gopher.xml b/output/atom_content_gopher.xml
@@ -1726,6 +1726,8 @@ the basic Gopher types and has some restrictions to prevent some abuse.</p>
<p>For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>
+<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>
+<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>
]]></content>
</entry>
<entry>
(DIR) diff --git a/output/gopher-proxy.html b/output/gopher-proxy.html
@@ -65,6 +65,8 @@ the basic Gopher types and has some restrictions to prevent some abuse.</p>
<p>For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>
+<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>
+<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>
</article>
</div>
(DIR) diff --git a/output/gopher-proxy.md b/output/gopher-proxy.md
@@ -27,3 +27,7 @@ You can view it here:
For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<https://codemadness.org/gopherproxy/?q=codemadness.org>
+
+**Due to abuse this service is (temporary) disabled, but of course you can self-host it**
+
+**For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly**
(DIR) diff --git a/output/jsonfeed_content.json b/output/jsonfeed_content.json
@@ -112,7 +112,7 @@
"title": "Gopher HTTP proxy",
"url": "https://www.codemadness.org/gopher-proxy.html",
"authors": [{"name": "Hiltjo"}],
- "content_html": "<h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href=\"https://git.fifth.space/sacc/\">sacc</a>.</p>\n<p>For more information about Gopher check out <a href=\"http://gopherproject.org/\">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href=\"https://git.codemadness.org/gopherproxy-c/\">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href=\"gopher://codemadness.org/1/git/gopherproxy-c\">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href=\"https://codemadness.org/gopherproxy/\">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter \"q\" reads the URI:\n<a href=\"https://codemadness.org/gopherproxy/?q=codemadness.org\">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>"
+ "content_html": "<h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href=\"https://git.fifth.space/sacc/\">sacc</a>.</p>\n<p>For more information about Gopher check out <a href=\"http://gopherproject.org/\">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href=\"https://git.codemadness.org/gopherproxy-c/\">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href=\"gopher://codemadness.org/1/git/gopherproxy-c\">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href=\"https://codemadness.org/gopherproxy/\">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter \"q\" reads the URI:\n<a href=\"https://codemadness.org/gopherproxy/?q=codemadness.org\">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>\n<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>\n<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>"
},
{
"id": "https://www.codemadness.org/paste-service.html",
(DIR) diff --git a/output/jsonfeed_content_gopher.json b/output/jsonfeed_content_gopher.json
@@ -112,7 +112,7 @@
"title": "Gopher HTTP proxy",
"url": "gopher://codemadness.org/1/phlog/gopher-proxy",
"authors": [{"name": "Hiltjo"}],
- "content_html": "<h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href=\"https://git.fifth.space/sacc/\">sacc</a>.</p>\n<p>For more information about Gopher check out <a href=\"http://gopherproject.org/\">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href=\"https://git.codemadness.org/gopherproxy-c/\">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href=\"gopher://codemadness.org/1/git/gopherproxy-c\">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href=\"https://codemadness.org/gopherproxy/\">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter \"q\" reads the URI:\n<a href=\"https://codemadness.org/gopherproxy/?q=codemadness.org\">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>"
+ "content_html": "<h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href=\"https://git.fifth.space/sacc/\">sacc</a>.</p>\n<p>For more information about Gopher check out <a href=\"http://gopherproject.org/\">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href=\"https://git.codemadness.org/gopherproxy-c/\">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href=\"gopher://codemadness.org/1/git/gopherproxy-c\">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href=\"https://codemadness.org/gopherproxy/\">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter \"q\" reads the URI:\n<a href=\"https://codemadness.org/gopherproxy/?q=codemadness.org\">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>\n<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>\n<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>"
},
{
"id": "gopher://codemadness.org/1/phlog/paste-service",
(DIR) diff --git a/output/phlog/gopher-proxy b/output/phlog/gopher-proxy
@@ -34,4 +34,8 @@ i codemadness.org 70
iFor example you can also view my gopherhole using the proxy, the query string codemadness.org 70
iparameter "q" reads the URI: codemadness.org 70
hhttps://codemadness.org/gopherproxy/?q=codemadness.org URL:https://codemadness.org/gopherproxy/?q=codemadness.org codemadness.org 70
+i codemadness.org 70
+i**Due to abuse this service is (temporary) disabled, but of course you can self-host it** codemadness.org 70
+i codemadness.org 70
+i**For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly** codemadness.org 70
.
(DIR) diff --git a/output/rss_content.xml b/output/rss_content.xml
@@ -1656,6 +1656,8 @@ the basic Gopher types and has some restrictions to prevent some abuse.</p>
<p>For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>
+<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>
+<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>
]]></description>
</item>
<item>
(DIR) diff --git a/output/rss_content_gopher.xml b/output/rss_content_gopher.xml
@@ -1656,6 +1656,8 @@ the basic Gopher types and has some restrictions to prevent some abuse.</p>
<p>For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>
+<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>
+<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p>
]]></description>
</item>
<item>
(DIR) diff --git a/output/sfeed_content.tsv b/output/sfeed_content.tsv
@@ -11,7 +11,7 @@
1570924800 json2tsv: a JSON to TSV converter https://www.codemadness.org/json2tsv.html <h1>json2tsv: a JSON to TSV converter</h1>\n\t<p><strong>Last modification on </strong> <time>2021-09-25</time></p>\n\t<p>Convert JSON to TSV or separated output.</p>\n<p>json2tsv reads JSON data from stdin. It outputs each JSON type to a TAB-\nSeparated Value format per line by default.</p>\n<h2>TAB-Separated Value format</h2>\n<p>The output format per line is:</p>\n<pre><code>nodename<TAB>type<TAB>value<LF>\n</code></pre>\n<p>Control-characters such as a newline, TAB and backslash (\\n, \\t and \\) are\nescaped in the nodename and value fields. Other control-characters are\nremoved.</p>\n<p>The type field is a single byte and can be:</p>\n<ul>\n<li>a for array</li>\n<li>b for bool</li>\n<li>n for number</li>\n<li>o for object</li>\n<li>s for string</li>\n<li>? for null</li>\n</ul>\n<p>Filtering on the first field "nodename" is easy using awk for example.</p>\n<h2>Features</h2>\n<ul>\n<li>Accepts all <strong>valid</strong> JSON.</li>\n<li>Designed to work well with existing UNIX programs like awk and grep.</li>\n<li>Straightforward and not much lines of code: about 475 lines of C.</li>\n<li>Few dependencies: C compiler (C99), libc.</li>\n<li>No need to learn a new (meta-)language for processing data.</li>\n<li>The parser supports code point decoding and UTF-16 surrogates to UTF-8.</li>\n<li>It does not output control-characters to the terminal for security reasons by\ndefault (but it has a -r option if needed).</li>\n<li>On OpenBSD it supports <a href="https://man.openbsd.org/pledge">pledge(2)</a> for syscall restriction:\npledge("stdio", NULL).</li>\n<li>Supports setting a different field separator and record separator with the -F\nand -R option.</li>\n</ul>\n<h2>Cons</h2>\n<ul>\n<li>For the tool there is additional overhead by processing and filtering data\nfrom stdin after parsing.</li>\n<li>The parser does not do complete validation on numbers.</li>\n<li>The parser accepts some bad input such as invalid UTF-8\n(see <a href="https://tools.ietf.org/html/rfc8259#section-8.1">RFC8259 - 8.1. Character Encoding</a>).\njson2tsv reads from stdin and does not do assumptions about a "closed\necosystem" as described in the RFC.</li>\n<li>The parser accepts some bad JSON input and "extensions"\n(see <a href="https://tools.ietf.org/html/rfc8259#section-9">RFC8259 - 9. Parsers</a>).</li>\n<li>Encoded NUL bytes (\\u0000) in strings are ignored.\n(see <a href="https://tools.ietf.org/html/rfc8259#section-9">RFC8259 - 9. Parsers</a>).\n"An implementation may set limits on the length and character contents of\nstrings."</li>\n<li>The parser is not the fastest possible JSON parser (but also not the\nslowest). For example: for ease of use, at the cost of performance all\nstrings are decoded, even though they may be unused.</li>\n</ul>\n<h2>Why Yet Another JSON parser?</h2>\n<p>I wanted a tool that makes parsing JSON easier and work well from the shell,\nsimilar to <a href="https://stedolan.github.io/jq/">jq</a>.</p>\n<p>sed and grep often work well enough for matching some value using some regex\npattern, but it is not good enough to parse JSON correctly or to extract all\ninformation: just like parsing HTML/XML using some regex is not good (enough)\nor a good idea :P.</p>\n<p>I didn't want to learn a new specific <a href="https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions">meta-language</a> which jq has and wanted\nsomething simpler.</p>\n<p>While it is more efficient to embed this query language for data aggregation,\nit is also less simple. In my opinion it is simpler to separate this and use\npattern-processing by awk or an other filtering/aggregating program.</p>\n<p>For the parser, there are many JSON parsers out there, like the efficient\n<a href="https://github.com/zserge/jsmn">jsmn parser</a>, however a few parser behaviours I want to have are:</p>\n<ul>\n<li>jsmn buffers data as tokens, which is very efficient, but also a bit\nannoying as an API as it requires another layer of code to interpret the\ntokens.</li>\n<li>jsmn does not handle decoding strings by default. Which is very efficient\nif you don't need parts of the data though.</li>\n<li>jsmn does not keep context of nested structures by default, so may require\nwriting custom utility functions for nested data.</li>\n</ul>\n<p>This is why I went for a parser design that uses a single callback per "node"\ntype and keeps track of the current nested structure in a single array and\nemits that.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/json2tsv\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/json2tsv/">https://git.codemadness.org/json2tsv/</a></li>\n<li><a href="gopher://codemadness.org/1/git/json2tsv">gopher://codemadness.org/1/git/json2tsv</a></li>\n</ul>\n<h2>Download releases</h2>\n<p>Releases are available at:</p>\n<ul>\n<li><a href="https://codemadness.org/releases/json2tsv/">https://codemadness.org/releases/json2tsv/</a></li>\n<li><a href="gopher://codemadness.org/1/releases/json2tsv">gopher://codemadness.org/1/releases/json2tsv</a></li>\n</ul>\n<h2>Build and install</h2>\n<pre><code>$ make\n# make install\n</code></pre>\n<h2>Examples</h2>\n<p>An usage example to parse posts of the JSON API of <a href="https://www.reddit.com/">reddit.com</a> and format them\nto a plain-text list using awk:</p>\n<pre><code>#!/bin/sh\ncurl -s -H 'User-Agent:' 'https://old.reddit.com/.json?raw_json=1&limit=100' | \\\njson2tsv | \\\nawk -F '\\t' '\nfunction show() {\n\tif (length(o["title"]) == 0)\n\t\treturn;\n\tprint n ". " o["title"] " by " o["author"] " in r/" o["subreddit"];\n\tprint o["url"];\n\tprint "";\n}\n$1 == ".data.children[].data" {\n\tshow();\n\tn++;\n\tdelete o;\n}\n$1 ~ /^\\.data\\.children\\[\\]\\.data\\.[a-zA-Z0-9_]*$/ {\n\to[substr($1, 23)] = $3;\n}\nEND {\n\tshow();\n}'\n</code></pre>\n<h2>References</h2>\n<ul>\n<li>Sites:\n<ul>\n<li><a href="http://seriot.ch/parsing_json.php">seriot.ch - Parsing JSON is a Minefield</a></li>\n<li><a href="https://github.com/nst/JSONTestSuite">A comprehensive test suite for RFC 8259 compliant JSON parsers</a></li>\n<li><a href="https://json.org/">json.org</a></li>\n</ul>\n</li>\n<li>Current standard:\n<ul>\n<li><a href="https://tools.ietf.org/html/rfc8259">RFC8259 - The JavaScript Object Notation (JSON) Data Interchange Format</a></li>\n<li><a href="https://www.ecma-international.org/publications/standards/Ecma-404.htm">Standard ECMA-404 - The JSON Data Interchange Syntax (2nd edition (December 2017)</a></li>\n</ul>\n</li>\n<li>Historic standards:\n<ul>\n<li><a href="https://tools.ietf.org/html/rfc7159">RFC7159 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete)</a></li>\n<li><a href="https://tools.ietf.org/html/rfc7158">RFC7158 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete)</a></li>\n<li><a href="https://tools.ietf.org/html/rfc4627">RFC4627 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete, original)</a></li>\n</ul>\n</li>\n</ul> html https://www.codemadness.org/json2tsv.html Hiltjo
1556064000 OpenBSD: setup a local auto-installation server https://www.codemadness.org/openbsd-autoinstall.html <h1>OpenBSD: setup a local auto-installation server</h1>\n\t<p><strong>Last modification on </strong> <time>2020-04-30</time></p>\n\t<p>This guide describes how to setup a local mirror and installation/upgrade\nserver that requires little or no input interaction.</p>\n<h2>Setup a local HTTP mirror</h2>\n<p>The HTTP mirror will be used to fetch the base sets and (optional) custom sets.\nIn this guide we will assume <strong>192.168.0.2</strong> is the local installation server\nand mirror, the CPU architecture is amd64 and the OpenBSD release version is\n6.5. We will store the files in the directory with the structure:</p>\n<pre><code>http://192.168.0.2/pub/OpenBSD/6.5/amd64/\n</code></pre>\n<p>Create the www serve directory and fetch all sets and install files\n(if needed to save space *.iso and install65.fs can be skipped):</p>\n<pre><code>$ cd /var/www/htdocs\n$ mkdir -p pub/OpenBSD/6.5/amd64/\n$ cd pub/OpenBSD/6.5/amd64/\n$ ftp 'ftp://ftp.nluug.nl/pub/OpenBSD/6.5/amd64/*'\n</code></pre>\n<p>Verify signature and check some checksums:</p>\n<pre><code>$ signify -C -p /etc/signify/openbsd-65-base.pub -x SHA256.sig\n</code></pre>\n<p>Setup <a href="https://man.openbsd.org/httpd.8">httpd(8)</a> for simple file serving:</p>\n<pre><code># $FAVORITE_EDITOR /etc/httpd.conf\n</code></pre>\n<p>A minimal example config for <a href="https://man.openbsd.org/httpd.conf.5">httpd.conf(5)</a>:</p>\n<pre><code>server "*" {\n\tlisten on * port 80\n}\n</code></pre>\n<p>The default www root directory is: /var/www/htdocs/</p>\n<p>Enable the httpd daemon to start by default and start it now:</p>\n<pre><code># rcctl enable httpd\n# rcctl start httpd\n</code></pre>\n<h2>Creating an installation response/answer file</h2>\n<p>The installer supports loading responses to the installation/upgrade questions\nfrom a simple text file. We can do a regular installation and copy the answers\nfrom the saved file to make an automated version of it.</p>\n<p>Do a test installation, at the end of the installation or upgrade when asked the\nquestion:</p>\n<pre><code>Exit to (S)hell, (H)alt or (R)eboot?\n</code></pre>\n<p>Type S to go to the shell. Find the response file for an installation and copy\nit to some USB stick or write down the response answers:</p>\n<pre><code>cp /tmp/i/install.resp /mnt/usbstick/\n</code></pre>\n<p>A response file could be for example:</p>\n<pre><code>System hostname = testvm\nWhich network interface do you wish to configure = em0\nIPv4 address for em0 = dhcp\nIPv6 address for em0 = none\nWhich network interface do you wish to configure = done\nPassword for root account = $2b$10$IqI43aXjgD55Q3nLbRakRO/UAG6SAClL9pyk0vIUpHZSAcLx8fWk.\nPassword for user testuser = $2b$10$IqI43aXjgD55Q3nLbRakRO/UAG6SAClL9pyk0vIUpHZSAcLx8fWk.\nStart sshd(8) by default = no\nDo you expect to run the X Window System = no\nSetup a user = testuser\nFull name for user testuser = testuser\nWhat timezone are you in = Europe/Amsterdam\nWhich disk is the root disk = wd0\nUse (W)hole disk MBR, whole disk (G)PT, (O)penBSD area or (E)dit = OpenBSD\nUse (A)uto layout, (E)dit auto layout, or create (C)ustom layout = a\nLocation of sets = http\nHTTP proxy URL = none\nHTTP Server = 192.168.0.2\nServer directory = pub/OpenBSD/6.5/amd64\nUnable to connect using https. Use http instead = yes\nLocation of sets = http\nSet name(s) = done\nLocation of sets = done\nExit to (S)hell, (H)alt or (R)eboot = R\n</code></pre>\n<p>Get custom encrypted password for response file:</p>\n<pre><code>$ printf '%s' 'yourpassword' | encrypt\n</code></pre>\n<h2>Changing the RAMDISK kernel disk image</h2>\n<p><a href="https://man.openbsd.org/rdsetroot.8">rdsetroot(8)</a> is publicly exposed now in base since 6.5. Before 6.5 it is\navailable in the /usr/src/ tree as elfrdsetroot, see also the <a href="https://man.openbsd.org/rd.4">rd(4)</a> man page.</p>\n<pre><code>$ mkdir auto\n$ cd auto\n$ cp pubdir/bsd.rd .\n$ rdsetroot -x bsd.rd disk.fs\n# vnconfig vnd0 disk.fs\n# mkdir mount\n# mount /dev/vnd0a mount\n</code></pre>\n<p>Copy the response file (install.resp) to: mount/auto_install.conf\n(installation) <strong>or</strong> mount/auto_upgrade.conf (upgrade), but not both. In this\nguide we will do an auto-installation.</p>\n<p>Unmount, detach and patch RAMDISK:</p>\n<pre><code># umount mount\n# vnconfig -u vnd0\n$ rdsetroot bsd.rd disk.fs\n</code></pre>\n<p>To test copy bsd.rd to the root of some testmachine like /bsd.test.rd then\n(re)boot and type:</p>\n<pre><code>boot /bsd.test.rd\n</code></pre>\n<p>In the future (6.5+) it will be possible to copy to a file named "/bsd.upgrade"\nin the root of a current system and automatically load the kernel:\n<a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/stand/boot/boot.c?rev=1.46&content-type=text/x-cvsweb-markup">See the script bsd.upgrade in CVS.</a>\nOf course this is possible with PXE boot or some custom USB/ISO also.\nAs explained in the <a href="https://man.openbsd.org/autoinstall.8">autoinstall(8)</a> man page: create either an\nauto_upgrade.conf <strong>or</strong> an auto_install.conf, but not both.</p>\n<h2>Create bootable miniroot</h2>\n<p>In this example the miniroot will boot the custom kernel, but fetch all the\nsets from the local network.</p>\n<p>We will base our miniroot of the official version: miniroot65.fs.</p>\n<p>We will create a 16MB miniroot to boot from (in this guide it is assumed the\noriginal miniroot is about 4MB and the modified kernel image fits in the new\nallocated space):</p>\n<pre><code>$ dd if=/dev/zero of=new.fs bs=512 count=32768\n</code></pre>\n<p>Copy first part of the original image to the new disk (no truncation):</p>\n<pre><code>$ dd conv=notrunc if=miniroot65.fs of=new.fs\n# vnconfig vnd0 new.fs\n</code></pre>\n<p>Expand disk OpenBSD boundaries:</p>\n<pre><code># disklabel -E vnd0\n> b\nStarting sector: [1024]\nSize ('*' for entire disk): [8576] *\n> r\nTotal free sectors: 1168.\n> c a\nPartition a is currently 8576 sectors in size, and can have a maximum\nsize of 9744 sectors.\nsize: [8576] *\n> w\n> q\n</code></pre>\n<p>or:</p>\n<pre><code># printf 'b\\n\\n*\\nc a\\n*\\nw\\n' | disklabel -E vnd0\n</code></pre>\n<p>Grow filesystem and check it and mark as clean:</p>\n<pre><code># growfs -y /dev/vnd0a\n# fsck -y /dev/vnd0a\n</code></pre>\n<p>Mount filesystem:</p>\n<pre><code># mount /dev/vnd0a mount/\n</code></pre>\n<p>The kernel on the miniroot is GZIP compressed. Compress our modified bsd.rd and\noverwrite the original kernel:</p>\n<pre><code># gzip -c9n bsd.rd > mount/bsd\n</code></pre>\n<p>Or to save space (+- 500KB) by stripping debug symbols, taken from bsd.gz target\n<a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/distrib/amd64/iso/Makefile">in this Makefile</a>.</p>\n<pre><code>$ cp bsd.rd bsd.strip\n$ strip bsd.strip\n$ strip -R .comment -R .SUNW_ctf bsd.strip\n$ gzip -c9n bsd.strip > bsd.gz\n$ cp bsd.gz mount/bsd\n</code></pre>\n<p>Now unmount and detach:</p>\n<pre><code># umount mount/\n# vnconfig -u vnd0\n</code></pre>\n<p>Now you can <a href="https://man.openbsd.org/dd.1">dd(1)</a> the image new.fs to your bootable (USB) medium.</p>\n<h2>Adding custom sets (optional)</h2>\n<p>For patching <a href="https://man.openbsd.org/rc.firsttime.8">/etc/rc.firsttime</a> and other system files it is useful to use a\ncustomized installation set like siteVERSION.tgz, for example: site65.tgz. The\nsets can even be specified per host/MAC address like\nsiteVERSION-$(hostname -s).tgz so for example: site65-testvm.tgz</p>\n<p>When the installer checks the base sets of the mirror it looks for a file\nindex.txt. To add custom sets the site entries have to be added.</p>\n<p>For example:</p>\n<pre><code>-rw-r--r-- 1 1001 0 4538975 Oct 11 13:58:26 2018 site65-testvm.tgz\n</code></pre>\n<p>The filesize, permissions etc do not matter and are not checked by the\ninstaller. Only the filename is matched by a regular expression.</p>\n<h2>Sign custom site* tarball sets (optional)</h2>\n<p>If you have custom sets without creating a signed custom release you will be\nprompted for the messages:</p>\n<pre><code>checksum test failed\n</code></pre>\n<p>and:</p>\n<pre><code>unverified sets: continue without verification\n</code></pre>\n<p>OpenBSD uses the program <a href="https://man.openbsd.org/signify.1">signify(1)</a> to cryptographically sign and\nverify filesets.</p>\n<p>To create a custom public/private keypair (ofcourse make sure to store the\nprivate key privately):</p>\n<pre><code>$ signify -G -n -c "Custom 6.5 install" -p custom-65-base.pub -s custom-65-base.sec\n</code></pre>\n<p>Create new checksum file with filelist of the current directory (except SHA256*\nfiles):</p>\n<pre><code>$ printf '%s\\n' * | grep -v SHA256 | xargs sha256 > SHA256\n</code></pre>\n<p>Sign SHA256 and store as SHA256.sig, embed signature:</p>\n<pre><code>$ signify -S -e -s /privatedir/custom-65-base.sec -m SHA256 -x SHA256.sig\n</code></pre>\n<p>Verify the created signature and data is correct:</p>\n<pre><code>$ signify -C -p /somelocation/custom-65-base.pub -x SHA256.sig\n</code></pre>\n<p>Copy <strong>only</strong> the <strong>public</strong> key to the RAMDISK:</p>\n<pre><code>$ cp custom-65-base.pub mount/etc/signify/custom-65-base.pub\n</code></pre>\n<p>Now we have to patch the install.sub file to check our public key. If you know\na better way without having to patch this script, please let me know.</p>\n<p>Change the variable PUB_KEY in the shellscript mount/install.sub from:</p>\n<pre><code>PUB_KEY=/etc/signify/openbsd-${VERSION}-base.pub\n</code></pre>\n<p>To:</p>\n<pre><code>PUB_KEY=/etc/signify/custom-${VERSION}-base.pub\n</code></pre>\n<p>And for upgrades from:</p>\n<pre><code>$UPGRADE_BSDRD &&\n\tPUB_KEY=/mnt/etc/signify/openbsd-$((VERSION + 1))-base.pub\n</code></pre>\n<p>To:</p>\n<pre><code>$UPGRADE_BSDRD &&\n\tPUB_KEY=/mnt/etc/signify/custom-$((VERSION + 1))-base.pub\n</code></pre>\n<h2>Ideas</h2>\n<ul>\n<li>Patch <a href="https://man.openbsd.org/rc.firsttime.8">rc.firsttime(8)</a>: and run syspatch, add ports, setup xenodm etc.</li>\n<li>Custom partitioning scheme, see <a href="https://man.openbsd.org/autoinstall.8">autoinstall(8)</a> "URL to autopartitioning\ntemplate for disklabel = url".</li>\n<li>Setup <a href="https://man.openbsd.org/pxeboot.8">pxeboot(8)</a> to boot and install over the network using\n<a href="https://man.openbsd.org/dhcpd.8">dhcpd(8)</a> and\n<a href="https://man.openbsd.org/tftpd.8">tftpd(8)</a> then not even some USB stick is required.</li>\n</ul>\n<h2>References</h2>\n<ul>\n<li>Main OpenBSD installation and upgrade shellscript:\n<a href="https://cvsweb.openbsd.org/src/distrib/miniroot/install.sub">/usr/src/distrib/miniroot/install.sub</a></li>\n</ul> html https://www.codemadness.org/openbsd-autoinstall.html Hiltjo
1549756800 Idiotbox: Youtube interface https://www.codemadness.org/idiotbox.html <h1>Idiotbox: Youtube interface</h1>\n\t<p><strong>Last modification on </strong> <time>2021-12-25</time></p>\n\t<p>Idiotbox is a less resource-heavy Youtube interface. For viewing videos it is\nrecommended to use it with <a href="https://mpv.io/">mpv</a> or\n<a href="https://mplayerhq.hu/">mplayer</a> with\n<a href="https://youtube-dl.org/">youtube-dl</a> or\n<a href="https://github.com/yt-dlp/yt-dlp">yt-dlp</a>.</p>\n<p>For more (up-to-date) information see the <a href="/git/frontends/file/youtube/README.html">README</a> file.</p>\n<h2>Why</h2>\n<p>In my opinion the standard Youtube web interface is:</p>\n<ul>\n<li>Non-intuitive, too much visual crap.</li>\n<li>Too resource-hungry, both in CPU and bandwidth.</li>\n<li>Doesn't work well on simpler (text-based) browsers such as netsurf and links.</li>\n</ul>\n<h2>Features</h2>\n<ul>\n<li>Doesn't use JavaScript.</li>\n<li>Doesn't use (tracking) cookies.</li>\n<li>CSS is optional.</li>\n<li>Multiple interfaces available: HTTP CGI, command-line, Gopher CGI (gph),\nthis is a work-in-progress.</li>\n<li>Doesn't use or require the Google API.</li>\n<li>CGI interface works nice in most browsers, including text-based ones.</li>\n<li>On OpenBSD it runs "sandboxed" and it can be compiled as a static-linked\nbinary with <a href="https://man.openbsd.org/pledge">pledge(2)</a>,\n<a href="https://man.openbsd.org/unveil">unveil(2)</a> in a chroot.</li>\n</ul>\n<h2>Cons</h2>\n<ul>\n<li>Order by upload date is incorrect (same as on Youtube).</li>\n<li>Some Youtube features are not supported.</li>\n<li>Uses scraping so might break at any point.</li>\n</ul>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/frontends\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/frontends/">https://git.codemadness.org/frontends/</a></li>\n<li><a href="gopher://codemadness.org/1/git/frontends">gopher://codemadness.org/1/git/frontends</a></li>\n</ul>\n<h2>Download releases</h2>\n<p>Releases are available at:</p>\n<ul>\n<li><a href="https://codemadness.org/releases/frontends/">https://codemadness.org/releases/frontends/</a></li>\n<li><a href="gopher://codemadness.org/1/releases/frontends">gopher://codemadness.org/1/releases/frontends</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here: <a href="https://codemadness.org/idiotbox/">https://codemadness.org/idiotbox/</a></p>\n<p>For example you can search using the query string parameter "q":\n<a href="https://codemadness.org/idiotbox/?q=gunther+tralala">https://codemadness.org/idiotbox/?q=gunther+tralala</a></p>\n<p>The gopher version is here: <a href="gopher://codemadness.org/7/idiotbox.cgi">gopher://codemadness.org/7/idiotbox.cgi</a></p> html https://www.codemadness.org/idiotbox.html Hiltjo
-1534464000 Gopher HTTP proxy https://www.codemadness.org/gopher-proxy.html <h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href="https://git.fifth.space/sacc/">sacc</a>.</p>\n<p>For more information about Gopher check out <a href="http://gopherproject.org/">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/gopherproxy-c/">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href="gopher://codemadness.org/1/git/gopherproxy-c">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href="https://codemadness.org/gopherproxy/">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter "q" reads the URI:\n<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p> html https://www.codemadness.org/gopher-proxy.html Hiltjo
+1534464000 Gopher HTTP proxy https://www.codemadness.org/gopher-proxy.html <h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href="https://git.fifth.space/sacc/">sacc</a>.</p>\n<p>For more information about Gopher check out <a href="http://gopherproject.org/">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/gopherproxy-c/">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href="gopher://codemadness.org/1/git/gopherproxy-c">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href="https://codemadness.org/gopherproxy/">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter "q" reads the URI:\n<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>\n<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>\n<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p> html https://www.codemadness.org/gopher-proxy.html Hiltjo
1520640000 Setup your own file paste service https://www.codemadness.org/paste-service.html <h1>Setup your own file paste service</h1>\n\t<p><strong>Last modification on </strong> <time>2018-03-10</time></p>\n\t<h2>Setup SSH authentication</h2>\n<p>Make sure to setup SSH public key authentication so you don't need to enter a\npassword each time and have a more secure authentication.</p>\n<p>For example in the file $HOME/.ssh/config:</p>\n<pre><code>Host codemadness\n\tHostname codemadness.org\n\tPort 22\n\tIdentityFile ~/.ssh/codemadness/id_rsa\n</code></pre>\n<p>Of course also make sure to generate the private and public keys.</p>\n<h2>Shell alias</h2>\n<p>Make an alias or function in your shell config:</p>\n<pre><code>pastesrv() {\n\tssh user@codemadness "cat > /your/www/publicdir/paste/$1"\n\techo "https://codemadness.org/paste/$1"\n}\n</code></pre>\n<p>This function reads any data from stdin and transfers the output securely via\nSSH and writes it to a file at the specified path. This path can be visible via\nHTTP, gopher or an other protocol. Then it writes the absolute URL to stdout,\nthis URL can be copied to the clipboard and pasted anywhere like to an e-mail,\nIRC etc.</p>\n<h2>Usage and examples</h2>\n<p>To use it, here are some examples:</p>\n<p>Create a patch of the last commit in the git repo and store it:</p>\n<pre><code>git format-patch --stdout HEAD^ | pastesrv 'somepatch.diff'\n</code></pre>\n<p>Create a screenshot of your current desktop and paste it:</p>\n<pre><code>xscreenshot | ff2png | pastesrv 'screenshot.png'\n</code></pre>\n<p>There are many other uses of course, use your imagination :)</p> html https://www.codemadness.org/paste-service.html Hiltjo
1519516800 Setup your own git hosting service https://www.codemadness.org/setup-git-hosting.html <h1>Setup your own git hosting service</h1>\n\t<p><strong>Last modification on </strong> <time>2022-08-07</time></p>\n\t<p><strong>This article assumes you use OpenBSD for the service files and OS-specific\nexamples.</strong></p>\n<h2>Why</h2>\n<p>A good reason to host your own git repositories is because of having and\nkeeping control over your own computing infrastructure.</p>\n<p>Some bad examples:</p>\n<ul>\n<li><a href="https://en.wikipedia.org/wiki/SourceForge#Controversies">The SourceForge ads/malware/hijack controversies. Injecting malware into projects</a>.</li>\n<li><a href="https://gitlab.com/gitlab-org/gitaly/issues/2113">As of 2019-10-23 Gitlab added telemetry to their software</a>.</li>\n<li><a href="https://about.gitlab.com/blog/2019/10/10/update-free-software-and-telemetry/">On 2019-10-24 Gitlab reverted it again because many people complained</a>.</li>\n<li><a href="https://github.blog/2020-11-16-standing-up-for-developers-youtube-dl-is-back/">On 2020-11-16 Github reinstated youtube-dl, to reverse a Digital Millennium Copyright Act (DMCA) takedown</a>.</li>\n<li><a href="https://arstechnica.com/gadgets/2021/03/critics-fume-after-github-removes-exploit-code-for-exchange-vulnerabilities/">On 2021-03-11 Github (owned by Microsoft) removes exploit code for Microsoft Exchange vulnerabilities</a>.</li>\n<li><a href="https://www.bleepingcomputer.com/news/security/github-suspends-accounts-of-russian-devs-at-sanctioned-companies/">On 2022-04-16 Russian software developers are reporting that their GitHub accounts are being suspended without warning if they work for or previously worked for companies under US sanctions</a>.</li>\n<li><a href="https://www.theregister.com/2022/08/04/gitlab_data_retention_policy/">On 2022-08-04 GitLab plans to delete dormant projects in free accounts</a>.</li>\n<li><a href="https://www.theregister.com/2022/08/05/gitlab_reverses_deletion_policy/">On 2022-08-05 GitLab U-turns on deleting dormant projects after backlash</a>.</li>\n</ul>\n<p>The same thing can happen with Github, Atlassian Bitbucket or other similar\nservices. After all: they are just a company with commercial interests. These\nonline services also have different pricing plans and various (arbitrary)\nrestrictions. When you host it yourself the restrictions are the resource\nlimits of the system and your connection, therefore it is a much more flexible\nsolution.</p>\n<p>Always make sure you own the software (which is <a href="https://www.gnu.org/philosophy/free-sw.html">Free</a> or open-source) and you\ncan host it yourself, so you will be in control of it.</p>\n<h2>Creating repositories</h2>\n<p>For the hosting it is recommended to use a so-called "bare" repository. A bare\nrepository means no files are checked out in the folder itself. To create a\nbare repository use git init with the --bare argument:</p>\n<pre><code>$ git init --bare\n</code></pre>\n<p>I recommend to create a separate user and group for the source-code\nrepositories. In the examples we will assume the user is called "src".</p>\n<p>Login as the src user and create the files. To create a directory for the\nrepos, in this example /home/src/src:</p>\n<pre><code>$ mkdir -p /home/src/src\n$ cd /home/src/src\n$ git init --bare someproject\n$ $EDITOR someproject/description\n</code></pre>\n<p>Make sure the git-daemon process has access permissions to these repositories.</p>\n<h2>Install git-daemon (optional)</h2>\n<p>Using git-daemon you can clone the repositories publicly using the efficient\ngit:// protocol. An alternative without having to use git-daemon is by using\n(anonymous) SSH, HTTPS or any public shared filesystem.</p>\n<p>When you use a private-only repository I recommend to just use SSH without\ngit-daemon because it is secure.</p>\n<p>Install the git package. The package should contain "git daemon":</p>\n<pre><code># pkg_add git\n</code></pre>\n<p>Enable the daemon:</p>\n<pre><code># rcctl enable gitdaemon\n</code></pre>\n<p>Set the gitdaemon service flags to use the src directory and use all the\navailable repositories in this directory. The command-line flags "--export-all"\nexports all repositories in the base path. Alternatively you can use the\n"git-daemon-export-ok" file (see the git-daemon man page).</p>\n<pre><code># rcctl set gitdaemon flags --export-all --base-path="/home/src/src"\n</code></pre>\n<p>To configure the service to run as the user _gitdaemon:</p>\n<pre><code># rcctl set gitdaemon user _gitdaemon\n</code></pre>\n<p>To run the daemon directly as the user _gitdaemon (without dropping privileges\nfrom root to the user) set the following flags in /etc/rc.d/gitdaemon:</p>\n<pre><code>daemon_flags="--user=_gitdaemon"\n</code></pre>\n<p>Which will also avoid this warning while cloning:</p>\n<pre><code>"can't access /root/.git/config"\n</code></pre>\n<p>Now start the daemon:</p>\n<pre><code># rcctl start gitdaemon\n</code></pre>\n<h2>Cloning and fetching changes</h2>\n<p>To test and clone the repository do:</p>\n<pre><code>$ git clone git://yourdomain/someproject\n</code></pre>\n<p>if you skipped the optional git-daemon installation then just clone via SSH:</p>\n<pre><code>$ git clone ssh://youraccount@yourdomain:/home/src/src/someproject\n</code></pre>\n<p>When cloning via SSH make sure to setup private/public key authentication for\nsecurity and convenience.</p>\n<p>You should also make sure the firewall allows connections to the services like\nthe git daemon, HTTPd or SSH, for example using OpenBSD pf something like this\ncan be set in <a href="https://man.openbsd.org/pf.conf">/etc/pf.conf</a>:</p>\n<pre><code>tcp_services="{ ssh, gopher, http, https, git }"\npass in on egress proto tcp from any to (egress) port $tcp_services\n</code></pre>\n<h2>Pushing changes</h2>\n<p>Add the repository as a remote:</p>\n<pre><code>$ git remote add myremote ssh://youraccount@yourdomain:/home/src/src/someproject\n</code></pre>\n<p>Then push the changes:</p>\n<pre><code>$ git push myremote master:master\n</code></pre>\n<h2>Git history web browsing (optional)</h2>\n<p>Sometimes it's nice to browse the git history log of the repository in a web\nbrowser or some other program without having to look at the local repository.</p>\n<ul>\n<li><a href="stagit.html">Stagit</a> is a static HTML page generator for git.</li>\n<li><a href="stagit-gopher.html">Stagit-gopher</a> is a static page generator for\n<a href="http://gopherproject.org/">gopher</a> and\n<a href="gopher://bitreich.org/1/scm/geomyidae">geomyidae</a>.</li>\n<li>cgit is a CGI-based program which shows HTML views of your repository, see\nalso the page: <a href="openbsd-httpd-and-cgit.html">OpenBSD httpd, slowcgi and cgit</a>.</li>\n</ul>\n<p>It's also possible with these tools to generate an Atom feed and then use a\nRSS/Atom reader to track the git history:</p>\n<ul>\n<li>An example url from cgit: <a href="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/atom/?h=master">Linux kernel tree</a>.</li>\n<li>An example url from stagit for the <a href="/git/stagit/atom.xml">commit log</a>.</li>\n<li>An example url from stagit for the <a href="/git/stagit/tags.xml">releases</a>.</li>\n</ul>\n<p>My <a href="sfeed.html">sfeed</a> program can be used as a RSS/Atom reader.</p>\n<h2>Setting up git hooks (optional)</h2>\n<p>Using git hooks you can setup automated triggers, for example when pushing to a\nrepository. Some useful examples can be:</p>\n<ul>\n<li><a href="/git/stagit/file/example_post-receive.sh.html">For stagit: update the repo files (example post-receive hook).</a></li>\n<li>Send an e-mail with the commit subject and message.</li>\n<li>Log/notify commits and changes to an IRC channel using a fifo: <a href="https://tools.suckless.org/ii/">ii</a>.</li>\n<li>Create a release tarball and checksum file on a tag push/change.</li>\n<li>Checkout files for website content.</li>\n</ul> html https://www.codemadness.org/setup-git-hosting.html Hiltjo
1512950400 Setup an OpenBSD SPARC64 VM in QEMU https://www.codemadness.org/openbsd-sparc64-vm.html <h1>Setup an OpenBSD SPARC64 VM in QEMU</h1>\n\t<p><strong>Last modification on </strong> <time>2020-04-18</time></p>\n\t<p>This describes how to setup an OpenBSD SPARC64 VM in QEMU.</p>\n<h2>Create a disk image</h2>\n<p>To create a 5GB disk image:</p>\n<pre><code>qemu-img create -f qcow2 fs.qcow2 5G\n</code></pre>\n<h2>Install</h2>\n<p>In this guide we'll use the installation ISO to install OpenBSD. Make sure to\ndownload the latest (stable) OpenBSD ISO, for example install62.iso.</p>\n<ul>\n<li>Change -boot c to -boot d to boot from the CD-ROM and do a clean install.</li>\n<li>Change -cdrom install62.iso to the location of your ISO file.</li>\n<li>When the install is done type: halt -p</li>\n<li>Change -boot d back to -boot c.</li>\n</ul>\n<p>Start the VM:</p>\n<pre><code>#!/bin/sh\nLC_ALL=C QEMU_AUDIO_DRV=none \\\nqemu-system-sparc64 \\\n\t-machine sun4u,usb=off \\\n\t-realtime mlock=off \\\n\t-smp 1,sockets=1,cores=1,threads=1 \\\n\t-rtc base=utc \\\n\t-m 1024 \\\n\t-boot c \\\n\t-drive file=fs.qcow2,if=none,id=drive-ide0-0-1,format=qcow2,cache=none \\\n\t-cdrom install62.iso \\\n\t-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-1,id=ide0-0-1 \\\n\t-msg timestamp=on \\\n\t-serial pty -nographic \\\n\t-net nic,model=ne2k_pci -net user\n</code></pre>\n<p>The VM has the following properties:</p>\n<ul>\n<li>No audio.</li>\n<li>No USB.</li>\n<li>No VGA graphics: serial console.</li>\n<li>Netdev is ne0 (Realtek 8029).</li>\n<li>1024MB memory.</li>\n</ul>\n<p>From your host connect to the serial device indicated by QEMU, for example:</p>\n<pre><code>(qemu) 2017-11-19T15:14:20.884312Z qemu-system-sparc64: -serial pty: char device redirected to /dev/ttyp0 (label serial0)\n</code></pre>\n<p>Then you can use the serial terminal emulator <strong>cu</strong> to attach:</p>\n<pre><code>cu -l /dev/ttyp0\n</code></pre>\n<p>Another option could be using the <a href="https://git.suckless.org/st/">simple terminal(st)</a> from suckless.</p>\n<pre><code>st -l /dev/ttyp0\n</code></pre>\n<p>using cu to detach the <a href="https://man.openbsd.org/cu#~^D">cu(1) man page</a> says:</p>\n<pre><code>Typed characters are normally transmitted directly to the remote machine (which\ndoes the echoing as well). A tilde ('~') appearing as the first character of a\nline is an escape signal; the following are recognized:\n\n ~^D or ~. Drop the connection and exit. Only the connection is\n the login session is not terminated.\n</code></pre>\n<p>On boot you have to type:</p>\n<pre><code>root device: wd0a\nfor swap use the default (wd0b) Press enter\n</code></pre>\n<h2>Initial settings on first boot (optional)</h2>\n<p>Automatic network configuration using DHCP</p>\n<pre><code>echo "dhcp" > /etc/hostname.ne0\n</code></pre>\n<p>To bring up the interface (will be automatic on the next boot):</p>\n<pre><code>sh /etc/netstart\n</code></pre>\n<p>Add a mirror to /etc/installurl for package installation. Make sure to lookup\nthe most efficient/nearby mirror site on the OpenBSD mirror page.</p>\n<pre><code>echo "https://ftp.hostserver.de/pub/OpenBSD" > /etc/installurl\n</code></pre> html https://www.codemadness.org/openbsd-sparc64-vm.html Hiltjo
(DIR) diff --git a/output/sfeed_content_gopher.tsv b/output/sfeed_content_gopher.tsv
@@ -11,7 +11,7 @@
1570924800 json2tsv: a JSON to TSV converter gopher://codemadness.org/1/phlog/json2tsv <h1>json2tsv: a JSON to TSV converter</h1>\n\t<p><strong>Last modification on </strong> <time>2021-09-25</time></p>\n\t<p>Convert JSON to TSV or separated output.</p>\n<p>json2tsv reads JSON data from stdin. It outputs each JSON type to a TAB-\nSeparated Value format per line by default.</p>\n<h2>TAB-Separated Value format</h2>\n<p>The output format per line is:</p>\n<pre><code>nodename<TAB>type<TAB>value<LF>\n</code></pre>\n<p>Control-characters such as a newline, TAB and backslash (\\n, \\t and \\) are\nescaped in the nodename and value fields. Other control-characters are\nremoved.</p>\n<p>The type field is a single byte and can be:</p>\n<ul>\n<li>a for array</li>\n<li>b for bool</li>\n<li>n for number</li>\n<li>o for object</li>\n<li>s for string</li>\n<li>? for null</li>\n</ul>\n<p>Filtering on the first field "nodename" is easy using awk for example.</p>\n<h2>Features</h2>\n<ul>\n<li>Accepts all <strong>valid</strong> JSON.</li>\n<li>Designed to work well with existing UNIX programs like awk and grep.</li>\n<li>Straightforward and not much lines of code: about 475 lines of C.</li>\n<li>Few dependencies: C compiler (C99), libc.</li>\n<li>No need to learn a new (meta-)language for processing data.</li>\n<li>The parser supports code point decoding and UTF-16 surrogates to UTF-8.</li>\n<li>It does not output control-characters to the terminal for security reasons by\ndefault (but it has a -r option if needed).</li>\n<li>On OpenBSD it supports <a href="https://man.openbsd.org/pledge">pledge(2)</a> for syscall restriction:\npledge("stdio", NULL).</li>\n<li>Supports setting a different field separator and record separator with the -F\nand -R option.</li>\n</ul>\n<h2>Cons</h2>\n<ul>\n<li>For the tool there is additional overhead by processing and filtering data\nfrom stdin after parsing.</li>\n<li>The parser does not do complete validation on numbers.</li>\n<li>The parser accepts some bad input such as invalid UTF-8\n(see <a href="https://tools.ietf.org/html/rfc8259#section-8.1">RFC8259 - 8.1. Character Encoding</a>).\njson2tsv reads from stdin and does not do assumptions about a "closed\necosystem" as described in the RFC.</li>\n<li>The parser accepts some bad JSON input and "extensions"\n(see <a href="https://tools.ietf.org/html/rfc8259#section-9">RFC8259 - 9. Parsers</a>).</li>\n<li>Encoded NUL bytes (\\u0000) in strings are ignored.\n(see <a href="https://tools.ietf.org/html/rfc8259#section-9">RFC8259 - 9. Parsers</a>).\n"An implementation may set limits on the length and character contents of\nstrings."</li>\n<li>The parser is not the fastest possible JSON parser (but also not the\nslowest). For example: for ease of use, at the cost of performance all\nstrings are decoded, even though they may be unused.</li>\n</ul>\n<h2>Why Yet Another JSON parser?</h2>\n<p>I wanted a tool that makes parsing JSON easier and work well from the shell,\nsimilar to <a href="https://stedolan.github.io/jq/">jq</a>.</p>\n<p>sed and grep often work well enough for matching some value using some regex\npattern, but it is not good enough to parse JSON correctly or to extract all\ninformation: just like parsing HTML/XML using some regex is not good (enough)\nor a good idea :P.</p>\n<p>I didn't want to learn a new specific <a href="https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions">meta-language</a> which jq has and wanted\nsomething simpler.</p>\n<p>While it is more efficient to embed this query language for data aggregation,\nit is also less simple. In my opinion it is simpler to separate this and use\npattern-processing by awk or an other filtering/aggregating program.</p>\n<p>For the parser, there are many JSON parsers out there, like the efficient\n<a href="https://github.com/zserge/jsmn">jsmn parser</a>, however a few parser behaviours I want to have are:</p>\n<ul>\n<li>jsmn buffers data as tokens, which is very efficient, but also a bit\nannoying as an API as it requires another layer of code to interpret the\ntokens.</li>\n<li>jsmn does not handle decoding strings by default. Which is very efficient\nif you don't need parts of the data though.</li>\n<li>jsmn does not keep context of nested structures by default, so may require\nwriting custom utility functions for nested data.</li>\n</ul>\n<p>This is why I went for a parser design that uses a single callback per "node"\ntype and keeps track of the current nested structure in a single array and\nemits that.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/json2tsv\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/json2tsv/">https://git.codemadness.org/json2tsv/</a></li>\n<li><a href="gopher://codemadness.org/1/git/json2tsv">gopher://codemadness.org/1/git/json2tsv</a></li>\n</ul>\n<h2>Download releases</h2>\n<p>Releases are available at:</p>\n<ul>\n<li><a href="https://codemadness.org/releases/json2tsv/">https://codemadness.org/releases/json2tsv/</a></li>\n<li><a href="gopher://codemadness.org/1/releases/json2tsv">gopher://codemadness.org/1/releases/json2tsv</a></li>\n</ul>\n<h2>Build and install</h2>\n<pre><code>$ make\n# make install\n</code></pre>\n<h2>Examples</h2>\n<p>An usage example to parse posts of the JSON API of <a href="https://www.reddit.com/">reddit.com</a> and format them\nto a plain-text list using awk:</p>\n<pre><code>#!/bin/sh\ncurl -s -H 'User-Agent:' 'https://old.reddit.com/.json?raw_json=1&limit=100' | \\\njson2tsv | \\\nawk -F '\\t' '\nfunction show() {\n\tif (length(o["title"]) == 0)\n\t\treturn;\n\tprint n ". " o["title"] " by " o["author"] " in r/" o["subreddit"];\n\tprint o["url"];\n\tprint "";\n}\n$1 == ".data.children[].data" {\n\tshow();\n\tn++;\n\tdelete o;\n}\n$1 ~ /^\\.data\\.children\\[\\]\\.data\\.[a-zA-Z0-9_]*$/ {\n\to[substr($1, 23)] = $3;\n}\nEND {\n\tshow();\n}'\n</code></pre>\n<h2>References</h2>\n<ul>\n<li>Sites:\n<ul>\n<li><a href="http://seriot.ch/parsing_json.php">seriot.ch - Parsing JSON is a Minefield</a></li>\n<li><a href="https://github.com/nst/JSONTestSuite">A comprehensive test suite for RFC 8259 compliant JSON parsers</a></li>\n<li><a href="https://json.org/">json.org</a></li>\n</ul>\n</li>\n<li>Current standard:\n<ul>\n<li><a href="https://tools.ietf.org/html/rfc8259">RFC8259 - The JavaScript Object Notation (JSON) Data Interchange Format</a></li>\n<li><a href="https://www.ecma-international.org/publications/standards/Ecma-404.htm">Standard ECMA-404 - The JSON Data Interchange Syntax (2nd edition (December 2017)</a></li>\n</ul>\n</li>\n<li>Historic standards:\n<ul>\n<li><a href="https://tools.ietf.org/html/rfc7159">RFC7159 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete)</a></li>\n<li><a href="https://tools.ietf.org/html/rfc7158">RFC7158 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete)</a></li>\n<li><a href="https://tools.ietf.org/html/rfc4627">RFC4627 - The JavaScript Object Notation (JSON) Data Interchange Format (obsolete, original)</a></li>\n</ul>\n</li>\n</ul> html gopher://codemadness.org/1/phlog/json2tsv Hiltjo
1556064000 OpenBSD: setup a local auto-installation server gopher://codemadness.org/1/phlog/openbsd-autoinstall <h1>OpenBSD: setup a local auto-installation server</h1>\n\t<p><strong>Last modification on </strong> <time>2020-04-30</time></p>\n\t<p>This guide describes how to setup a local mirror and installation/upgrade\nserver that requires little or no input interaction.</p>\n<h2>Setup a local HTTP mirror</h2>\n<p>The HTTP mirror will be used to fetch the base sets and (optional) custom sets.\nIn this guide we will assume <strong>192.168.0.2</strong> is the local installation server\nand mirror, the CPU architecture is amd64 and the OpenBSD release version is\n6.5. We will store the files in the directory with the structure:</p>\n<pre><code>http://192.168.0.2/pub/OpenBSD/6.5/amd64/\n</code></pre>\n<p>Create the www serve directory and fetch all sets and install files\n(if needed to save space *.iso and install65.fs can be skipped):</p>\n<pre><code>$ cd /var/www/htdocs\n$ mkdir -p pub/OpenBSD/6.5/amd64/\n$ cd pub/OpenBSD/6.5/amd64/\n$ ftp 'ftp://ftp.nluug.nl/pub/OpenBSD/6.5/amd64/*'\n</code></pre>\n<p>Verify signature and check some checksums:</p>\n<pre><code>$ signify -C -p /etc/signify/openbsd-65-base.pub -x SHA256.sig\n</code></pre>\n<p>Setup <a href="https://man.openbsd.org/httpd.8">httpd(8)</a> for simple file serving:</p>\n<pre><code># $FAVORITE_EDITOR /etc/httpd.conf\n</code></pre>\n<p>A minimal example config for <a href="https://man.openbsd.org/httpd.conf.5">httpd.conf(5)</a>:</p>\n<pre><code>server "*" {\n\tlisten on * port 80\n}\n</code></pre>\n<p>The default www root directory is: /var/www/htdocs/</p>\n<p>Enable the httpd daemon to start by default and start it now:</p>\n<pre><code># rcctl enable httpd\n# rcctl start httpd\n</code></pre>\n<h2>Creating an installation response/answer file</h2>\n<p>The installer supports loading responses to the installation/upgrade questions\nfrom a simple text file. We can do a regular installation and copy the answers\nfrom the saved file to make an automated version of it.</p>\n<p>Do a test installation, at the end of the installation or upgrade when asked the\nquestion:</p>\n<pre><code>Exit to (S)hell, (H)alt or (R)eboot?\n</code></pre>\n<p>Type S to go to the shell. Find the response file for an installation and copy\nit to some USB stick or write down the response answers:</p>\n<pre><code>cp /tmp/i/install.resp /mnt/usbstick/\n</code></pre>\n<p>A response file could be for example:</p>\n<pre><code>System hostname = testvm\nWhich network interface do you wish to configure = em0\nIPv4 address for em0 = dhcp\nIPv6 address for em0 = none\nWhich network interface do you wish to configure = done\nPassword for root account = $2b$10$IqI43aXjgD55Q3nLbRakRO/UAG6SAClL9pyk0vIUpHZSAcLx8fWk.\nPassword for user testuser = $2b$10$IqI43aXjgD55Q3nLbRakRO/UAG6SAClL9pyk0vIUpHZSAcLx8fWk.\nStart sshd(8) by default = no\nDo you expect to run the X Window System = no\nSetup a user = testuser\nFull name for user testuser = testuser\nWhat timezone are you in = Europe/Amsterdam\nWhich disk is the root disk = wd0\nUse (W)hole disk MBR, whole disk (G)PT, (O)penBSD area or (E)dit = OpenBSD\nUse (A)uto layout, (E)dit auto layout, or create (C)ustom layout = a\nLocation of sets = http\nHTTP proxy URL = none\nHTTP Server = 192.168.0.2\nServer directory = pub/OpenBSD/6.5/amd64\nUnable to connect using https. Use http instead = yes\nLocation of sets = http\nSet name(s) = done\nLocation of sets = done\nExit to (S)hell, (H)alt or (R)eboot = R\n</code></pre>\n<p>Get custom encrypted password for response file:</p>\n<pre><code>$ printf '%s' 'yourpassword' | encrypt\n</code></pre>\n<h2>Changing the RAMDISK kernel disk image</h2>\n<p><a href="https://man.openbsd.org/rdsetroot.8">rdsetroot(8)</a> is publicly exposed now in base since 6.5. Before 6.5 it is\navailable in the /usr/src/ tree as elfrdsetroot, see also the <a href="https://man.openbsd.org/rd.4">rd(4)</a> man page.</p>\n<pre><code>$ mkdir auto\n$ cd auto\n$ cp pubdir/bsd.rd .\n$ rdsetroot -x bsd.rd disk.fs\n# vnconfig vnd0 disk.fs\n# mkdir mount\n# mount /dev/vnd0a mount\n</code></pre>\n<p>Copy the response file (install.resp) to: mount/auto_install.conf\n(installation) <strong>or</strong> mount/auto_upgrade.conf (upgrade), but not both. In this\nguide we will do an auto-installation.</p>\n<p>Unmount, detach and patch RAMDISK:</p>\n<pre><code># umount mount\n# vnconfig -u vnd0\n$ rdsetroot bsd.rd disk.fs\n</code></pre>\n<p>To test copy bsd.rd to the root of some testmachine like /bsd.test.rd then\n(re)boot and type:</p>\n<pre><code>boot /bsd.test.rd\n</code></pre>\n<p>In the future (6.5+) it will be possible to copy to a file named "/bsd.upgrade"\nin the root of a current system and automatically load the kernel:\n<a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/stand/boot/boot.c?rev=1.46&content-type=text/x-cvsweb-markup">See the script bsd.upgrade in CVS.</a>\nOf course this is possible with PXE boot or some custom USB/ISO also.\nAs explained in the <a href="https://man.openbsd.org/autoinstall.8">autoinstall(8)</a> man page: create either an\nauto_upgrade.conf <strong>or</strong> an auto_install.conf, but not both.</p>\n<h2>Create bootable miniroot</h2>\n<p>In this example the miniroot will boot the custom kernel, but fetch all the\nsets from the local network.</p>\n<p>We will base our miniroot of the official version: miniroot65.fs.</p>\n<p>We will create a 16MB miniroot to boot from (in this guide it is assumed the\noriginal miniroot is about 4MB and the modified kernel image fits in the new\nallocated space):</p>\n<pre><code>$ dd if=/dev/zero of=new.fs bs=512 count=32768\n</code></pre>\n<p>Copy first part of the original image to the new disk (no truncation):</p>\n<pre><code>$ dd conv=notrunc if=miniroot65.fs of=new.fs\n# vnconfig vnd0 new.fs\n</code></pre>\n<p>Expand disk OpenBSD boundaries:</p>\n<pre><code># disklabel -E vnd0\n> b\nStarting sector: [1024]\nSize ('*' for entire disk): [8576] *\n> r\nTotal free sectors: 1168.\n> c a\nPartition a is currently 8576 sectors in size, and can have a maximum\nsize of 9744 sectors.\nsize: [8576] *\n> w\n> q\n</code></pre>\n<p>or:</p>\n<pre><code># printf 'b\\n\\n*\\nc a\\n*\\nw\\n' | disklabel -E vnd0\n</code></pre>\n<p>Grow filesystem and check it and mark as clean:</p>\n<pre><code># growfs -y /dev/vnd0a\n# fsck -y /dev/vnd0a\n</code></pre>\n<p>Mount filesystem:</p>\n<pre><code># mount /dev/vnd0a mount/\n</code></pre>\n<p>The kernel on the miniroot is GZIP compressed. Compress our modified bsd.rd and\noverwrite the original kernel:</p>\n<pre><code># gzip -c9n bsd.rd > mount/bsd\n</code></pre>\n<p>Or to save space (+- 500KB) by stripping debug symbols, taken from bsd.gz target\n<a href="https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/distrib/amd64/iso/Makefile">in this Makefile</a>.</p>\n<pre><code>$ cp bsd.rd bsd.strip\n$ strip bsd.strip\n$ strip -R .comment -R .SUNW_ctf bsd.strip\n$ gzip -c9n bsd.strip > bsd.gz\n$ cp bsd.gz mount/bsd\n</code></pre>\n<p>Now unmount and detach:</p>\n<pre><code># umount mount/\n# vnconfig -u vnd0\n</code></pre>\n<p>Now you can <a href="https://man.openbsd.org/dd.1">dd(1)</a> the image new.fs to your bootable (USB) medium.</p>\n<h2>Adding custom sets (optional)</h2>\n<p>For patching <a href="https://man.openbsd.org/rc.firsttime.8">/etc/rc.firsttime</a> and other system files it is useful to use a\ncustomized installation set like siteVERSION.tgz, for example: site65.tgz. The\nsets can even be specified per host/MAC address like\nsiteVERSION-$(hostname -s).tgz so for example: site65-testvm.tgz</p>\n<p>When the installer checks the base sets of the mirror it looks for a file\nindex.txt. To add custom sets the site entries have to be added.</p>\n<p>For example:</p>\n<pre><code>-rw-r--r-- 1 1001 0 4538975 Oct 11 13:58:26 2018 site65-testvm.tgz\n</code></pre>\n<p>The filesize, permissions etc do not matter and are not checked by the\ninstaller. Only the filename is matched by a regular expression.</p>\n<h2>Sign custom site* tarball sets (optional)</h2>\n<p>If you have custom sets without creating a signed custom release you will be\nprompted for the messages:</p>\n<pre><code>checksum test failed\n</code></pre>\n<p>and:</p>\n<pre><code>unverified sets: continue without verification\n</code></pre>\n<p>OpenBSD uses the program <a href="https://man.openbsd.org/signify.1">signify(1)</a> to cryptographically sign and\nverify filesets.</p>\n<p>To create a custom public/private keypair (ofcourse make sure to store the\nprivate key privately):</p>\n<pre><code>$ signify -G -n -c "Custom 6.5 install" -p custom-65-base.pub -s custom-65-base.sec\n</code></pre>\n<p>Create new checksum file with filelist of the current directory (except SHA256*\nfiles):</p>\n<pre><code>$ printf '%s\\n' * | grep -v SHA256 | xargs sha256 > SHA256\n</code></pre>\n<p>Sign SHA256 and store as SHA256.sig, embed signature:</p>\n<pre><code>$ signify -S -e -s /privatedir/custom-65-base.sec -m SHA256 -x SHA256.sig\n</code></pre>\n<p>Verify the created signature and data is correct:</p>\n<pre><code>$ signify -C -p /somelocation/custom-65-base.pub -x SHA256.sig\n</code></pre>\n<p>Copy <strong>only</strong> the <strong>public</strong> key to the RAMDISK:</p>\n<pre><code>$ cp custom-65-base.pub mount/etc/signify/custom-65-base.pub\n</code></pre>\n<p>Now we have to patch the install.sub file to check our public key. If you know\na better way without having to patch this script, please let me know.</p>\n<p>Change the variable PUB_KEY in the shellscript mount/install.sub from:</p>\n<pre><code>PUB_KEY=/etc/signify/openbsd-${VERSION}-base.pub\n</code></pre>\n<p>To:</p>\n<pre><code>PUB_KEY=/etc/signify/custom-${VERSION}-base.pub\n</code></pre>\n<p>And for upgrades from:</p>\n<pre><code>$UPGRADE_BSDRD &&\n\tPUB_KEY=/mnt/etc/signify/openbsd-$((VERSION + 1))-base.pub\n</code></pre>\n<p>To:</p>\n<pre><code>$UPGRADE_BSDRD &&\n\tPUB_KEY=/mnt/etc/signify/custom-$((VERSION + 1))-base.pub\n</code></pre>\n<h2>Ideas</h2>\n<ul>\n<li>Patch <a href="https://man.openbsd.org/rc.firsttime.8">rc.firsttime(8)</a>: and run syspatch, add ports, setup xenodm etc.</li>\n<li>Custom partitioning scheme, see <a href="https://man.openbsd.org/autoinstall.8">autoinstall(8)</a> "URL to autopartitioning\ntemplate for disklabel = url".</li>\n<li>Setup <a href="https://man.openbsd.org/pxeboot.8">pxeboot(8)</a> to boot and install over the network using\n<a href="https://man.openbsd.org/dhcpd.8">dhcpd(8)</a> and\n<a href="https://man.openbsd.org/tftpd.8">tftpd(8)</a> then not even some USB stick is required.</li>\n</ul>\n<h2>References</h2>\n<ul>\n<li>Main OpenBSD installation and upgrade shellscript:\n<a href="https://cvsweb.openbsd.org/src/distrib/miniroot/install.sub">/usr/src/distrib/miniroot/install.sub</a></li>\n</ul> html gopher://codemadness.org/1/phlog/openbsd-autoinstall Hiltjo
1549756800 Idiotbox: Youtube interface gopher://codemadness.org/1/phlog/idiotbox <h1>Idiotbox: Youtube interface</h1>\n\t<p><strong>Last modification on </strong> <time>2021-12-25</time></p>\n\t<p>Idiotbox is a less resource-heavy Youtube interface. For viewing videos it is\nrecommended to use it with <a href="https://mpv.io/">mpv</a> or\n<a href="https://mplayerhq.hu/">mplayer</a> with\n<a href="https://youtube-dl.org/">youtube-dl</a> or\n<a href="https://github.com/yt-dlp/yt-dlp">yt-dlp</a>.</p>\n<p>For more (up-to-date) information see the <a href="/git/frontends/file/youtube/README.html">README</a> file.</p>\n<h2>Why</h2>\n<p>In my opinion the standard Youtube web interface is:</p>\n<ul>\n<li>Non-intuitive, too much visual crap.</li>\n<li>Too resource-hungry, both in CPU and bandwidth.</li>\n<li>Doesn't work well on simpler (text-based) browsers such as netsurf and links.</li>\n</ul>\n<h2>Features</h2>\n<ul>\n<li>Doesn't use JavaScript.</li>\n<li>Doesn't use (tracking) cookies.</li>\n<li>CSS is optional.</li>\n<li>Multiple interfaces available: HTTP CGI, command-line, Gopher CGI (gph),\nthis is a work-in-progress.</li>\n<li>Doesn't use or require the Google API.</li>\n<li>CGI interface works nice in most browsers, including text-based ones.</li>\n<li>On OpenBSD it runs "sandboxed" and it can be compiled as a static-linked\nbinary with <a href="https://man.openbsd.org/pledge">pledge(2)</a>,\n<a href="https://man.openbsd.org/unveil">unveil(2)</a> in a chroot.</li>\n</ul>\n<h2>Cons</h2>\n<ul>\n<li>Order by upload date is incorrect (same as on Youtube).</li>\n<li>Some Youtube features are not supported.</li>\n<li>Uses scraping so might break at any point.</li>\n</ul>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/frontends\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/frontends/">https://git.codemadness.org/frontends/</a></li>\n<li><a href="gopher://codemadness.org/1/git/frontends">gopher://codemadness.org/1/git/frontends</a></li>\n</ul>\n<h2>Download releases</h2>\n<p>Releases are available at:</p>\n<ul>\n<li><a href="https://codemadness.org/releases/frontends/">https://codemadness.org/releases/frontends/</a></li>\n<li><a href="gopher://codemadness.org/1/releases/frontends">gopher://codemadness.org/1/releases/frontends</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here: <a href="https://codemadness.org/idiotbox/">https://codemadness.org/idiotbox/</a></p>\n<p>For example you can search using the query string parameter "q":\n<a href="https://codemadness.org/idiotbox/?q=gunther+tralala">https://codemadness.org/idiotbox/?q=gunther+tralala</a></p>\n<p>The gopher version is here: <a href="gopher://codemadness.org/7/idiotbox.cgi">gopher://codemadness.org/7/idiotbox.cgi</a></p> html gopher://codemadness.org/1/phlog/idiotbox Hiltjo
-1534464000 Gopher HTTP proxy gopher://codemadness.org/1/phlog/gopher-proxy <h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href="https://git.fifth.space/sacc/">sacc</a>.</p>\n<p>For more information about Gopher check out <a href="http://gopherproject.org/">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/gopherproxy-c/">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href="gopher://codemadness.org/1/git/gopherproxy-c">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href="https://codemadness.org/gopherproxy/">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter "q" reads the URI:\n<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p> html gopher://codemadness.org/1/phlog/gopher-proxy Hiltjo
+1534464000 Gopher HTTP proxy gopher://codemadness.org/1/phlog/gopher-proxy <h1>Gopher HTTP proxy</h1>\n\t<p><strong>Last modification on </strong> <time>2020-08-30</time></p>\n\t<p>For fun I wrote a small HTTP Gopher proxy CGI program in C. It only supports\nthe basic Gopher types and has some restrictions to prevent some abuse.</p>\n<p>For your regular Gopher browsing I recommend the simple Gopher client <a href="https://git.fifth.space/sacc/">sacc</a>.</p>\n<p>For more information about Gopher check out <a href="http://gopherproject.org/">gopherproject.org</a>.</p>\n<h2>Clone</h2>\n<pre><code>git clone git://git.codemadness.org/gopherproxy-c\n</code></pre>\n<h2>Browse</h2>\n<p>You can browse the source-code at:</p>\n<ul>\n<li><a href="https://git.codemadness.org/gopherproxy-c/">https://git.codemadness.org/gopherproxy-c/</a></li>\n<li><a href="gopher://codemadness.org/1/git/gopherproxy-c">gopher://codemadness.org/1/git/gopherproxy-c</a></li>\n</ul>\n<h2>View</h2>\n<p>You can view it here:\n<a href="https://codemadness.org/gopherproxy/">https://codemadness.org/gopherproxy/</a></p>\n<p>For example you can also view my gopherhole using the proxy, the query string\nparameter "q" reads the URI:\n<a href="https://codemadness.org/gopherproxy/?q=codemadness.org">https://codemadness.org/gopherproxy/?q=codemadness.org</a></p>\n<p><strong>Due to abuse this service is (temporary) disabled, but of course you can self-host it</strong></p>\n<p><strong>For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly</strong></p> html gopher://codemadness.org/1/phlog/gopher-proxy Hiltjo
1520640000 Setup your own file paste service gopher://codemadness.org/1/phlog/paste-service <h1>Setup your own file paste service</h1>\n\t<p><strong>Last modification on </strong> <time>2018-03-10</time></p>\n\t<h2>Setup SSH authentication</h2>\n<p>Make sure to setup SSH public key authentication so you don't need to enter a\npassword each time and have a more secure authentication.</p>\n<p>For example in the file $HOME/.ssh/config:</p>\n<pre><code>Host codemadness\n\tHostname codemadness.org\n\tPort 22\n\tIdentityFile ~/.ssh/codemadness/id_rsa\n</code></pre>\n<p>Of course also make sure to generate the private and public keys.</p>\n<h2>Shell alias</h2>\n<p>Make an alias or function in your shell config:</p>\n<pre><code>pastesrv() {\n\tssh user@codemadness "cat > /your/www/publicdir/paste/$1"\n\techo "https://codemadness.org/paste/$1"\n}\n</code></pre>\n<p>This function reads any data from stdin and transfers the output securely via\nSSH and writes it to a file at the specified path. This path can be visible via\nHTTP, gopher or an other protocol. Then it writes the absolute URL to stdout,\nthis URL can be copied to the clipboard and pasted anywhere like to an e-mail,\nIRC etc.</p>\n<h2>Usage and examples</h2>\n<p>To use it, here are some examples:</p>\n<p>Create a patch of the last commit in the git repo and store it:</p>\n<pre><code>git format-patch --stdout HEAD^ | pastesrv 'somepatch.diff'\n</code></pre>\n<p>Create a screenshot of your current desktop and paste it:</p>\n<pre><code>xscreenshot | ff2png | pastesrv 'screenshot.png'\n</code></pre>\n<p>There are many other uses of course, use your imagination :)</p> html gopher://codemadness.org/1/phlog/paste-service Hiltjo
1519516800 Setup your own git hosting service gopher://codemadness.org/1/phlog/setup-git-hosting <h1>Setup your own git hosting service</h1>\n\t<p><strong>Last modification on </strong> <time>2022-08-07</time></p>\n\t<p><strong>This article assumes you use OpenBSD for the service files and OS-specific\nexamples.</strong></p>\n<h2>Why</h2>\n<p>A good reason to host your own git repositories is because of having and\nkeeping control over your own computing infrastructure.</p>\n<p>Some bad examples:</p>\n<ul>\n<li><a href="https://en.wikipedia.org/wiki/SourceForge#Controversies">The SourceForge ads/malware/hijack controversies. Injecting malware into projects</a>.</li>\n<li><a href="https://gitlab.com/gitlab-org/gitaly/issues/2113">As of 2019-10-23 Gitlab added telemetry to their software</a>.</li>\n<li><a href="https://about.gitlab.com/blog/2019/10/10/update-free-software-and-telemetry/">On 2019-10-24 Gitlab reverted it again because many people complained</a>.</li>\n<li><a href="https://github.blog/2020-11-16-standing-up-for-developers-youtube-dl-is-back/">On 2020-11-16 Github reinstated youtube-dl, to reverse a Digital Millennium Copyright Act (DMCA) takedown</a>.</li>\n<li><a href="https://arstechnica.com/gadgets/2021/03/critics-fume-after-github-removes-exploit-code-for-exchange-vulnerabilities/">On 2021-03-11 Github (owned by Microsoft) removes exploit code for Microsoft Exchange vulnerabilities</a>.</li>\n<li><a href="https://www.bleepingcomputer.com/news/security/github-suspends-accounts-of-russian-devs-at-sanctioned-companies/">On 2022-04-16 Russian software developers are reporting that their GitHub accounts are being suspended without warning if they work for or previously worked for companies under US sanctions</a>.</li>\n<li><a href="https://www.theregister.com/2022/08/04/gitlab_data_retention_policy/">On 2022-08-04 GitLab plans to delete dormant projects in free accounts</a>.</li>\n<li><a href="https://www.theregister.com/2022/08/05/gitlab_reverses_deletion_policy/">On 2022-08-05 GitLab U-turns on deleting dormant projects after backlash</a>.</li>\n</ul>\n<p>The same thing can happen with Github, Atlassian Bitbucket or other similar\nservices. After all: they are just a company with commercial interests. These\nonline services also have different pricing plans and various (arbitrary)\nrestrictions. When you host it yourself the restrictions are the resource\nlimits of the system and your connection, therefore it is a much more flexible\nsolution.</p>\n<p>Always make sure you own the software (which is <a href="https://www.gnu.org/philosophy/free-sw.html">Free</a> or open-source) and you\ncan host it yourself, so you will be in control of it.</p>\n<h2>Creating repositories</h2>\n<p>For the hosting it is recommended to use a so-called "bare" repository. A bare\nrepository means no files are checked out in the folder itself. To create a\nbare repository use git init with the --bare argument:</p>\n<pre><code>$ git init --bare\n</code></pre>\n<p>I recommend to create a separate user and group for the source-code\nrepositories. In the examples we will assume the user is called "src".</p>\n<p>Login as the src user and create the files. To create a directory for the\nrepos, in this example /home/src/src:</p>\n<pre><code>$ mkdir -p /home/src/src\n$ cd /home/src/src\n$ git init --bare someproject\n$ $EDITOR someproject/description\n</code></pre>\n<p>Make sure the git-daemon process has access permissions to these repositories.</p>\n<h2>Install git-daemon (optional)</h2>\n<p>Using git-daemon you can clone the repositories publicly using the efficient\ngit:// protocol. An alternative without having to use git-daemon is by using\n(anonymous) SSH, HTTPS or any public shared filesystem.</p>\n<p>When you use a private-only repository I recommend to just use SSH without\ngit-daemon because it is secure.</p>\n<p>Install the git package. The package should contain "git daemon":</p>\n<pre><code># pkg_add git\n</code></pre>\n<p>Enable the daemon:</p>\n<pre><code># rcctl enable gitdaemon\n</code></pre>\n<p>Set the gitdaemon service flags to use the src directory and use all the\navailable repositories in this directory. The command-line flags "--export-all"\nexports all repositories in the base path. Alternatively you can use the\n"git-daemon-export-ok" file (see the git-daemon man page).</p>\n<pre><code># rcctl set gitdaemon flags --export-all --base-path="/home/src/src"\n</code></pre>\n<p>To configure the service to run as the user _gitdaemon:</p>\n<pre><code># rcctl set gitdaemon user _gitdaemon\n</code></pre>\n<p>To run the daemon directly as the user _gitdaemon (without dropping privileges\nfrom root to the user) set the following flags in /etc/rc.d/gitdaemon:</p>\n<pre><code>daemon_flags="--user=_gitdaemon"\n</code></pre>\n<p>Which will also avoid this warning while cloning:</p>\n<pre><code>"can't access /root/.git/config"\n</code></pre>\n<p>Now start the daemon:</p>\n<pre><code># rcctl start gitdaemon\n</code></pre>\n<h2>Cloning and fetching changes</h2>\n<p>To test and clone the repository do:</p>\n<pre><code>$ git clone git://yourdomain/someproject\n</code></pre>\n<p>if you skipped the optional git-daemon installation then just clone via SSH:</p>\n<pre><code>$ git clone ssh://youraccount@yourdomain:/home/src/src/someproject\n</code></pre>\n<p>When cloning via SSH make sure to setup private/public key authentication for\nsecurity and convenience.</p>\n<p>You should also make sure the firewall allows connections to the services like\nthe git daemon, HTTPd or SSH, for example using OpenBSD pf something like this\ncan be set in <a href="https://man.openbsd.org/pf.conf">/etc/pf.conf</a>:</p>\n<pre><code>tcp_services="{ ssh, gopher, http, https, git }"\npass in on egress proto tcp from any to (egress) port $tcp_services\n</code></pre>\n<h2>Pushing changes</h2>\n<p>Add the repository as a remote:</p>\n<pre><code>$ git remote add myremote ssh://youraccount@yourdomain:/home/src/src/someproject\n</code></pre>\n<p>Then push the changes:</p>\n<pre><code>$ git push myremote master:master\n</code></pre>\n<h2>Git history web browsing (optional)</h2>\n<p>Sometimes it's nice to browse the git history log of the repository in a web\nbrowser or some other program without having to look at the local repository.</p>\n<ul>\n<li><a href="stagit.html">Stagit</a> is a static HTML page generator for git.</li>\n<li><a href="stagit-gopher.html">Stagit-gopher</a> is a static page generator for\n<a href="http://gopherproject.org/">gopher</a> and\n<a href="gopher://bitreich.org/1/scm/geomyidae">geomyidae</a>.</li>\n<li>cgit is a CGI-based program which shows HTML views of your repository, see\nalso the page: <a href="openbsd-httpd-and-cgit.html">OpenBSD httpd, slowcgi and cgit</a>.</li>\n</ul>\n<p>It's also possible with these tools to generate an Atom feed and then use a\nRSS/Atom reader to track the git history:</p>\n<ul>\n<li>An example url from cgit: <a href="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/atom/?h=master">Linux kernel tree</a>.</li>\n<li>An example url from stagit for the <a href="/git/stagit/atom.xml">commit log</a>.</li>\n<li>An example url from stagit for the <a href="/git/stagit/tags.xml">releases</a>.</li>\n</ul>\n<p>My <a href="sfeed.html">sfeed</a> program can be used as a RSS/Atom reader.</p>\n<h2>Setting up git hooks (optional)</h2>\n<p>Using git hooks you can setup automated triggers, for example when pushing to a\nrepository. Some useful examples can be:</p>\n<ul>\n<li><a href="/git/stagit/file/example_post-receive.sh.html">For stagit: update the repo files (example post-receive hook).</a></li>\n<li>Send an e-mail with the commit subject and message.</li>\n<li>Log/notify commits and changes to an IRC channel using a fifo: <a href="https://tools.suckless.org/ii/">ii</a>.</li>\n<li>Create a release tarball and checksum file on a tag push/change.</li>\n<li>Checkout files for website content.</li>\n</ul> html gopher://codemadness.org/1/phlog/setup-git-hosting Hiltjo
1512950400 Setup an OpenBSD SPARC64 VM in QEMU gopher://codemadness.org/1/phlog/openbsd-sparc64-vm <h1>Setup an OpenBSD SPARC64 VM in QEMU</h1>\n\t<p><strong>Last modification on </strong> <time>2020-04-18</time></p>\n\t<p>This describes how to setup an OpenBSD SPARC64 VM in QEMU.</p>\n<h2>Create a disk image</h2>\n<p>To create a 5GB disk image:</p>\n<pre><code>qemu-img create -f qcow2 fs.qcow2 5G\n</code></pre>\n<h2>Install</h2>\n<p>In this guide we'll use the installation ISO to install OpenBSD. Make sure to\ndownload the latest (stable) OpenBSD ISO, for example install62.iso.</p>\n<ul>\n<li>Change -boot c to -boot d to boot from the CD-ROM and do a clean install.</li>\n<li>Change -cdrom install62.iso to the location of your ISO file.</li>\n<li>When the install is done type: halt -p</li>\n<li>Change -boot d back to -boot c.</li>\n</ul>\n<p>Start the VM:</p>\n<pre><code>#!/bin/sh\nLC_ALL=C QEMU_AUDIO_DRV=none \\\nqemu-system-sparc64 \\\n\t-machine sun4u,usb=off \\\n\t-realtime mlock=off \\\n\t-smp 1,sockets=1,cores=1,threads=1 \\\n\t-rtc base=utc \\\n\t-m 1024 \\\n\t-boot c \\\n\t-drive file=fs.qcow2,if=none,id=drive-ide0-0-1,format=qcow2,cache=none \\\n\t-cdrom install62.iso \\\n\t-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-1,id=ide0-0-1 \\\n\t-msg timestamp=on \\\n\t-serial pty -nographic \\\n\t-net nic,model=ne2k_pci -net user\n</code></pre>\n<p>The VM has the following properties:</p>\n<ul>\n<li>No audio.</li>\n<li>No USB.</li>\n<li>No VGA graphics: serial console.</li>\n<li>Netdev is ne0 (Realtek 8029).</li>\n<li>1024MB memory.</li>\n</ul>\n<p>From your host connect to the serial device indicated by QEMU, for example:</p>\n<pre><code>(qemu) 2017-11-19T15:14:20.884312Z qemu-system-sparc64: -serial pty: char device redirected to /dev/ttyp0 (label serial0)\n</code></pre>\n<p>Then you can use the serial terminal emulator <strong>cu</strong> to attach:</p>\n<pre><code>cu -l /dev/ttyp0\n</code></pre>\n<p>Another option could be using the <a href="https://git.suckless.org/st/">simple terminal(st)</a> from suckless.</p>\n<pre><code>st -l /dev/ttyp0\n</code></pre>\n<p>using cu to detach the <a href="https://man.openbsd.org/cu#~^D">cu(1) man page</a> says:</p>\n<pre><code>Typed characters are normally transmitted directly to the remote machine (which\ndoes the echoing as well). A tilde ('~') appearing as the first character of a\nline is an escape signal; the following are recognized:\n\n ~^D or ~. Drop the connection and exit. Only the connection is\n the login session is not terminated.\n</code></pre>\n<p>On boot you have to type:</p>\n<pre><code>root device: wd0a\nfor swap use the default (wd0b) Press enter\n</code></pre>\n<h2>Initial settings on first boot (optional)</h2>\n<p>Automatic network configuration using DHCP</p>\n<pre><code>echo "dhcp" > /etc/hostname.ne0\n</code></pre>\n<p>To bring up the interface (will be automatic on the next boot):</p>\n<pre><code>sh /etc/netstart\n</code></pre>\n<p>Add a mirror to /etc/installurl for package installation. Make sure to lookup\nthe most efficient/nearby mirror site on the OpenBSD mirror page.</p>\n<pre><code>echo "https://ftp.hostserver.de/pub/OpenBSD" > /etc/installurl\n</code></pre> html gopher://codemadness.org/1/phlog/openbsd-sparc64-vm Hiltjo
(DIR) diff --git a/pages/gopher-proxy.md b/pages/gopher-proxy.md
@@ -27,3 +27,7 @@ You can view it here:
For example you can also view my gopherhole using the proxy, the query string
parameter "q" reads the URI:
<https://codemadness.org/gopherproxy/?q=codemadness.org>
+
+**Due to abuse this service is (temporary) disabled, but of course you can self-host it**
+
+**For authors writing crawler bots: please respect robots.txt, HTTP status codes and test your code properly**