summaryrefslogtreecommitdiff
path: root/sites/pmikkelsen.com
diff options
context:
space:
mode:
Diffstat (limited to 'sites/pmikkelsen.com')
-rw-r--r--sites/pmikkelsen.com/_files/djv.tarbin0 -> 1822720 bytes
-rw-r--r--sites/pmikkelsen.com/_files/djvmono.tarbin0 -> 993280 bytes
-rw-r--r--sites/pmikkelsen.com/_werc/config3
-rw-r--r--sites/pmikkelsen.com/_werc/lib/footer.inc1
-rw-r--r--sites/pmikkelsen.com/_werc/lib/top_bar.inc10
-rw-r--r--sites/pmikkelsen.com/_werc/pub/style.css67
-rw-r--r--sites/pmikkelsen.com/contact.md3
-rw-r--r--sites/pmikkelsen.com/haskell/quine.md94
-rw-r--r--sites/pmikkelsen.com/images/2048.gifbin0 -> 4157248 bytes
-rw-r--r--sites/pmikkelsen.com/images/acme-in-action.pngbin0 -> 286658 bytes
-rw-r--r--sites/pmikkelsen.com/images/cdude.pngbin0 -> 20432 bytes
-rw-r--r--sites/pmikkelsen.com/images/cursed.pngbin0 -> 18433 bytes
-rw-r--r--sites/pmikkelsen.com/images/discordgif.gifbin0 -> 9196759 bytes
-rw-r--r--sites/pmikkelsen.com/images/djvfonts.pngbin0 -> 138021 bytes
-rw-r--r--sites/pmikkelsen.com/images/linuxreverse.gifbin0 -> 201797 bytes
-rw-r--r--sites/pmikkelsen.com/images/mordor.gifbin0 -> 1620703 bytes
-rw-r--r--sites/pmikkelsen.com/index.md28
-rw-r--r--sites/pmikkelsen.com/linux/eduroam.md15
-rw-r--r--sites/pmikkelsen.com/linux/wifi.md12
-rw-r--r--sites/pmikkelsen.com/me/how-i-started-using-acme.md117
-rw-r--r--sites/pmikkelsen.com/me/stuff-i-use.md46
-rw-r--r--sites/pmikkelsen.com/opinions/favourite-programming-languages.md1
-rw-r--r--sites/pmikkelsen.com/plan9/basic_9p_server.md58
-rw-r--r--sites/pmikkelsen.com/plan9/discord.md83
-rw-r--r--sites/pmikkelsen.com/plan9/dns.md41
-rw-r--r--sites/pmikkelsen.com/plan9/fonts.md29
-rw-r--r--sites/pmikkelsen.com/plan9/lets_encrypt.md59
-rw-r--r--sites/pmikkelsen.com/plan9/mounting-9p-over-drawterm.md58
-rw-r--r--sites/pmikkelsen.com/plan9/network_booting.md30
-rw-r--r--sites/pmikkelsen.com/plan9/trellofs.md347
-rw-r--r--sites/pmikkelsen.com/plan9/using_irc.md48
-rw-r--r--sites/pmikkelsen.com/web/the-setup-of-this-site.md3
32 files changed, 1153 insertions, 0 deletions
diff --git a/sites/pmikkelsen.com/_files/djv.tar b/sites/pmikkelsen.com/_files/djv.tar
new file mode 100644
index 0000000..5d60262
--- /dev/null
+++ b/sites/pmikkelsen.com/_files/djv.tar
Binary files differ
diff --git a/sites/pmikkelsen.com/_files/djvmono.tar b/sites/pmikkelsen.com/_files/djvmono.tar
new file mode 100644
index 0000000..1fb0c7d
--- /dev/null
+++ b/sites/pmikkelsen.com/_files/djvmono.tar
Binary files differ
diff --git a/sites/pmikkelsen.com/_werc/config b/sites/pmikkelsen.com/_werc/config
new file mode 100644
index 0000000..85a49d9
--- /dev/null
+++ b/sites/pmikkelsen.com/_werc/config
@@ -0,0 +1,3 @@
+masterSite=pmikkelsen.com
+siteTitle='Peter's website'
+siteSubTitle='random notes'
diff --git a/sites/pmikkelsen.com/_werc/lib/footer.inc b/sites/pmikkelsen.com/_werc/lib/footer.inc
new file mode 100644
index 0000000..4cabbb1
--- /dev/null
+++ b/sites/pmikkelsen.com/_werc/lib/footer.inc
@@ -0,0 +1 @@
+<a href="http://werc.cat-v.org">Powered by werc</a> © Peter Mikkelsen 2019-2020 \ No newline at end of file
diff --git a/sites/pmikkelsen.com/_werc/lib/top_bar.inc b/sites/pmikkelsen.com/_werc/lib/top_bar.inc
new file mode 100644
index 0000000..976c8b0
--- /dev/null
+++ b/sites/pmikkelsen.com/_werc/lib/top_bar.inc
@@ -0,0 +1,10 @@
+ <div class="left">
+ <a href="https://git.sr.ht/~pmikkelsen">sourcehut git</a> |
+ <a href="https://hg.sr.ht/~pmikkelsen">sourcehut hg</a> |
+ <a href="https://gitlab.com/pmikkelsen">gitlab</a> |
+ <a href="http://9front.org">9front</a>
+ </div>
+
+ <div class="right">
+ </div>
+
diff --git a/sites/pmikkelsen.com/_werc/pub/style.css b/sites/pmikkelsen.com/_werc/pub/style.css
new file mode 100644
index 0000000..10935fb
--- /dev/null
+++ b/sites/pmikkelsen.com/_werc/pub/style.css
@@ -0,0 +1,67 @@
+body { display: flex; flex-wrap: wrap; font-family: sans;}
+header { flex-basis: 100%; flex-shrink: 0; }
+article { flex-basis: 60%; padding-left: 1em; }
+footer { flex-basis: 100%; flex-shrink: 0; }
+header nav { display: flex; justify-content: space-between; }
+nav a, header a { text-decoration: none ; color: inherit; }
+header h1 span { margin-left: 1em; font-size: 50%; font-style: italic; }
+body > nav { flex-basis: content; padding-right: 1vw; min-width: 16em; }
+nav ul { display: flex; flex-direction: column; list-style-type: none; list-style-position: outside; padding-left: 0; }
+nav li ul { padding-left: 0.6em }
+footer { display: flex; justify-content: space-between; }
+
+/* cut here to leave vanity behind */
+
+body { margin:0; padding: 0; font-size: 84%; font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; }
+a { text-decoration: none; color: }
+a:hover { text-decoration: underline; }
+.thisPage { color: black; }
+
+/* header and top bar */
+header nav { background-color: rgb(100,135,220); color: white; padding: 0.3em; border-bottom: 2px solid black; font-size: 91%; }
+header h1 { background-color: #ff6d06; color: black; margin: 0; border-bottom: 2px solid black; font-weight: normal; padding: 0.25ex; font-size: 233%; }
+header a:hover { text-decoration: none; }
+
+/* sidebar */
+body > nav { border-right: 1px solid #ddd; padding: 0; }
+body > nav > div { border-bottom: 1px solid #ddd; }
+body > nav > div a { color: rgb(0, 102, 204); display: block; text-transform: capitalize; font-weight: bold; padding: 0.25em 1ex 0.25em 2mm; font-size: 102%}
+body > nav > div a:hover { color: white; background-color: rgb(100,135,220); border-left: black solid 0.2em; text-decoration: none; }
+body > nav > div p { font-weight: bold; margin: 0 0 0.5em 2mm; padding: 1em 0 0 0; }
+
+/* main copy */
+article { padding: 0.5ex 0 5vh 1vw; }
+article h1, article h2 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; border-bottom: 2px solid rgb(0,102,204); }
+article h3, article h4, article h5 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; }
+article h6, article h7, article h8 { color: rgb(0,102,204); font-weight: bold; margin: 2em 0 0 0; }
+article a { color: rgb(0,102,204); }
+article a:hover { color: rgb(100,135,220); }
+article pre { font-size: 1.2em; }
+
+/* footer */
+footer { color: white; background-color: rgb(100,135,220); }
+footer a { color: inherit; }
+footer div { padding: 1em; }
+
+/* tables */
+table { border: 1px solid rgba(128,128,128,0.5); padding: 0; }
+th { color: white; background-color: rgb(100,135,220); }
+tr:nth-child(odd) { background-color: rgba(128,128,128,0.1) }
+
+/* Modifications for pmikkelsen.com */
+img {
+ max-width: 100%;
+ border: 1px solid black;
+}
+
+body {
+ background-color: #ffffea;
+}
+
+header h1 {
+ background-color: #eaffea;
+}
+
+html {
+ font-size: 1.2em;
+} \ No newline at end of file
diff --git a/sites/pmikkelsen.com/contact.md b/sites/pmikkelsen.com/contact.md
new file mode 100644
index 0000000..c4dd043
--- /dev/null
+++ b/sites/pmikkelsen.com/contact.md
@@ -0,0 +1,3 @@
+You can reach me on email via **petermikkelsen10@gmail.com**
+
+On github, gitlab and most other places, my name is **pmikkelsen**. \ No newline at end of file
diff --git a/sites/pmikkelsen.com/haskell/quine.md b/sites/pmikkelsen.com/haskell/quine.md
new file mode 100644
index 0000000..09a3dcd
--- /dev/null
+++ b/sites/pmikkelsen.com/haskell/quine.md
@@ -0,0 +1,94 @@
+Today I am going to go through the process of writing a small program
+which prints it's own source when executed. These kinds of programs are
+also called quines, and I suggest that you try it out on your own if you
+haven't already done so, as it is a very fun little problem! So if you
+don't want any spoilers, please leave this page now and come back later.
+
+
+## First attempt
+
+Okay, so first of let's just write a small hello world program to get
+things going. All our code will be in a file called `quine.hs`. The code
+for hello world looks like this
+
+
+ main = putStrLn "Hello world!"
+
+
+When this is run using runhaskell quine.hs, it produces the output
+
+
+ Hello world!
+
+
+Well, not quite a quine yet but we are getting something to the screen
+at least ;)
+
+## Second attempt
+
+Now we get the idea that we copy the entire program's source into a
+string and print that string instead. To do this, the code could look
+something like this
+
+
+ main = putStrLn code
+ where code = "main = putStrLn code\n where code = ???"
+
+
+Here we run into a problem, since we can't include the entire code into
+the string. Copying everything we can into the string just increases
+the size of the string itself, which means that there is now even more
+to copy! We start by only copying all the code upto the string and see
+how it looks when executed. The code is now
+
+
+ main = putStrLn code
+ where code = "main = putStrLn code\n where code = "
+
+
+And it outputs
+
+ main = putStrLn code
+ where code =
+
+Quite good! Now if we could only include the string itself in its printed form, with the quotes and all, and not the interpreted form with `\n` shown as newlines.
+
+## Third attempt
+
+After looking through the haskell standard libraries for a bit, we find
+a function that looks promising for what we want to do. This function is
+`print`, which prints the output using the `show` function instead of
+interpreting the string. We would want to both print it as before, and
+to print it using `print`, so we change our main to be `main = putStrLn
+code >> print code`, and update our string to include the print. The
+code then becomes
+
+ main = putStrLn code >> print code
+ where code = "main = putStrLn code >> print code\n where code = "
+
+And it outputs
+
+
+ main = putStrLn code >> print code
+ where code =
+ "main = putStrLn code >> print code\n where code = "
+
+
+So close! The only problem is that the `putStrLn` append a newline after
+the output, which we don't want in this case.
+
+## Final attempt
+
+The simple fix is just to use `putStrLn`'s little brother `putStr`
+which doesn't print that newline. The final program is then
+
+
+ main = putStr code >> print code
+ where code = "main = putStr code >> print code\n where code = "
+
+And luckily it outputs exactly itself
+
+
+ main = putStr code >> print code
+ where code = "main = putStr code >> print code\n where code = "
+
diff --git a/sites/pmikkelsen.com/images/2048.gif b/sites/pmikkelsen.com/images/2048.gif
new file mode 100644
index 0000000..19dd98f
--- /dev/null
+++ b/sites/pmikkelsen.com/images/2048.gif
Binary files differ
diff --git a/sites/pmikkelsen.com/images/acme-in-action.png b/sites/pmikkelsen.com/images/acme-in-action.png
new file mode 100644
index 0000000..b74d9dc
--- /dev/null
+++ b/sites/pmikkelsen.com/images/acme-in-action.png
Binary files differ
diff --git a/sites/pmikkelsen.com/images/cdude.png b/sites/pmikkelsen.com/images/cdude.png
new file mode 100644
index 0000000..66ee18d
--- /dev/null
+++ b/sites/pmikkelsen.com/images/cdude.png
Binary files differ
diff --git a/sites/pmikkelsen.com/images/cursed.png b/sites/pmikkelsen.com/images/cursed.png
new file mode 100644
index 0000000..f92e06e
--- /dev/null
+++ b/sites/pmikkelsen.com/images/cursed.png
Binary files differ
diff --git a/sites/pmikkelsen.com/images/discordgif.gif b/sites/pmikkelsen.com/images/discordgif.gif
new file mode 100644
index 0000000..207af41
--- /dev/null
+++ b/sites/pmikkelsen.com/images/discordgif.gif
Binary files differ
diff --git a/sites/pmikkelsen.com/images/djvfonts.png b/sites/pmikkelsen.com/images/djvfonts.png
new file mode 100644
index 0000000..86d58a4
--- /dev/null
+++ b/sites/pmikkelsen.com/images/djvfonts.png
Binary files differ
diff --git a/sites/pmikkelsen.com/images/linuxreverse.gif b/sites/pmikkelsen.com/images/linuxreverse.gif
new file mode 100644
index 0000000..6684116
--- /dev/null
+++ b/sites/pmikkelsen.com/images/linuxreverse.gif
Binary files differ
diff --git a/sites/pmikkelsen.com/images/mordor.gif b/sites/pmikkelsen.com/images/mordor.gif
new file mode 100644
index 0000000..fe13c09
--- /dev/null
+++ b/sites/pmikkelsen.com/images/mordor.gif
Binary files differ
diff --git a/sites/pmikkelsen.com/index.md b/sites/pmikkelsen.com/index.md
new file mode 100644
index 0000000..2713ad4
--- /dev/null
+++ b/sites/pmikkelsen.com/index.md
@@ -0,0 +1,28 @@
+
+## This website
+
+My intention with this website it to share some ideas and thoughts on
+programming and other computer related subjects. The things I care
+about and find interesting at the moment are written below, and are
+updated sometimes. Hopefully, most of the content will be about one of
+those things.
+
+- Functional programming (Haskell, Erlang, Scheme)
+- Concurrent programming (Erlang, Go)
+- Plan 9 (both the 9front fork and plan9port)
+
+For information about how the website it setup, see
+[this](/web/the-setup-of-this-site) post.
+
+## Me
+
+My name is Peter Mikkelsen and I am a computer science student at Aalborg University, Denmark.
+
+The following list contains other facts and links
+
+- *Age*: 22
+- *Favourite programming language*: See [this](/opinions/favourite-programming-languages) post
+- *Current job*: None :)
+- *Stuff I use*: See [this](/me/stuff-i-use) post.
+- *Tabs vs spaces*: Tabs.
+- *Emacs* vs *Vi* [None of them](/me/how-i-started-using-acme)
diff --git a/sites/pmikkelsen.com/linux/eduroam.md b/sites/pmikkelsen.com/linux/eduroam.md
new file mode 100644
index 0000000..1cdc830
--- /dev/null
+++ b/sites/pmikkelsen.com/linux/eduroam.md
@@ -0,0 +1,15 @@
+# Connecting to the eduroam network on AAU
+
+Goto net.aau.dk and create a new device.
+
+Connect to the eduroam network and set the correct wifi-security settings:
+
+ security: WPA & WPA2 Enterprise
+ Authentication: PEAP
+ CA Cert: no CA certificate is required
+ PEAP Version: Automatic
+ Inner authentication: MSCHAPv2
+
+And fill out the username and password from the website.
+
+No need for the stupid script.
diff --git a/sites/pmikkelsen.com/linux/wifi.md b/sites/pmikkelsen.com/linux/wifi.md
new file mode 100644
index 0000000..be3b1cc
--- /dev/null
+++ b/sites/pmikkelsen.com/linux/wifi.md
@@ -0,0 +1,12 @@
+# Connecting to wifi on linux
+
+What I have to do:
+
+ wpa_passphrase NameOfNetwork NetworkKey >> /etc/wpa_supplicant/wpa_supplicant-wlp4s0.conf
+
+The network card name might be different.
+
+Then reboot aaaand done :)
+
+This is on void linux, so it might not be the same for you.
+
diff --git a/sites/pmikkelsen.com/me/how-i-started-using-acme.md b/sites/pmikkelsen.com/me/how-i-started-using-acme.md
new file mode 100644
index 0000000..9e37dd7
--- /dev/null
+++ b/sites/pmikkelsen.com/me/how-i-started-using-acme.md
@@ -0,0 +1,117 @@
+## The beginning
+
+My very first code editor was visual studio 2010 for windows 7. This was
+when I didn't know what programming was, and a teacher I had suggested
+that we used that, so we could start learning some C#. It was very fun and
+all, but soon after, I decided that I wanted to learn another language,
+and the whole idea of using an IDE which is specialized for a specific
+programming language or environment just seemed very odd to me. Surely
+there had to be better options, where I as a user could decide by myself
+what languages I wanted support for. I tried out multiple different
+small editors but didn't really like any of them.
+
+After some time, I decided that I wanted to try linux, and I installed
+fedora or linux mint (don't remember at this point), and I liked it very
+much. Comming from windows where it is normal just to go to a random
+website and download the tools I needed, it was a great joy to be able
+to just type a command in the terminal and watch my program get installed.
+
+## First try: vim
+
+After reading online for some time, it seemed that the editor which
+all the cool linux users used was vim, so I decided to learn that. The
+experience was very different from what I was used to, but I liked the
+keyboard shortcuts and that it looked very cool. Of course I installed
+every plugin that I had read about online and it all became a mess,
+but I stuck with it for around 3-4 years. The things I liked the most
+was that I felt it was very fast to do what I wanted, but unfortunately
+the flow with multiple files was never something I could get used to,
+and all the plugins made me sick.
+
+## Second try: emacs
+
+Just to give another very popular editor a try, I installed emacs sometime
+2-3 years ago. Comming from vim, the keyboard shortcuts in emacs sucks,
+but the editor itself is just so much more powerful, because plugins and
+customisations could be written in a real programming language. I started,
+as many other emacs users do, to use emacs for everything i could. I read
+my mails, watched PDFs, managed my system, and even used it as my window
+manager for a period. Around the same time that I started using emacs,
+I also started using OpenBSD as a secondary operating system. I noticed
+that many very good tools are available in unix, but emacs almost has
+everything implemented again in elisp, which seemed stupid to me. But hey,
+it works so I stuck with it. Until late 2019.
+
+## Now acme
+
+One day in school when one of my group mates asked if I could look at
+something for him, I saw that he was using visual studio code, which
+made it natural to use a mouse to click around in the file. Of course
+this was also possible in emacs, but since I came from vim, it was never
+something that I did. He argued that it was much faster to just click in
+the file where he wanted to edit, than to navigate using the keyboard, and
+I thought that maybe he was right, so I started digging. After some time
+looking though the internet for some editors which made much use of the
+mouse, I found acme and decided to install it. And wow it was different.
+
+[![A picture of acme in action][1]][1]
+
+Acme uses the mouse for everything, since there are very few keyboard
+shortcuts (not even copy and paste). As shown on the picture, there are no
+menus and no icons; everything is just text, and the different buttons on
+the mouse can interpret that text in different ways. For example, middle
+clicking on the text `New` wil create a new text frame, and right clicking
+on the text `example` will search the file for the word. Actually, it is
+more advanced than that since the right click will first send the selected
+text to something called the plumber, which might do something fun like
+opening the file which has that name. I suggest interrested readers to
+read the page [here](http://acme.cat-v.org/) and some of the documents
+linked from that site to learn more about acme. The video introduction
+from Russ Cox [here](https://www.youtube.com/watch?v=dP1xVpMPn8M) is
+also great.
+
+
+## What I like about acme
+
+* **The colours**: they cannot be changed without modifying the source,
+but luckily for me, I love those pale bright colours. In fact, there
+are the very reason this website has the colours that it has.
+
+* **Writing commands**: since acme allows users to control it via the 9P
+protocol (if you don't understand, read the links above), it is possible
+to write "plugins" or commands in whatever language I want. After
+just creating a program with the needed functionality, it is possible
+to write the name somewhere and middle click on it, just like it was
+always there. Not may editors makes it possible to use the environment
+as much as acme does, which was also one of my wonders about emacs back
+then. It allows me to turn it into *my* IDE using whatever tools I see fit,
+instead of depending on support directly in the editor.
+
+* **Everything as text**: this means that if I run a gdb session via
+the `win` command, it is totally possible for me to just scroll up in the
+history and delete lines which are not important, and to write notes
+as I debug. Also, since commands are just text which is clicked, it is
+possible to have a document with commands which are useful in a given
+project, which I can then open and click.
+
+* **Lack of customisation**: while this might seem strange, comming from
+a vim and emacs background, it surely is wonderful to have an editor
+which does *not* encourage the user to customise the hell out of it. I
+have spent way too much time doing this in the past and it had to stop.
+
+* **Lack of syntax highlighting and auto completion**: some people love
+it and can't live without it, but I very much prefer to learn the syntax
+of the language based on the contents, not based on some colours an
+editor throws at me. Also I feel like I learn and remember much better
+when there is no auto completion.
+
+## Other editors I use sometimes
+
+Sometimes I have to do very small editing tasks, and sometimes as root,
+in which case it is just simpler to open the file in vi. Note that this
+is the small vi, and not the "improved" vim. I also sometimes edit my
+text in sam with is another editor written by Rob Pike, and I quite like
+that one too for smaller projects. You can read more about sam
+[here](http://sam.cat-v.org/).
+
+[1]: /images/acme-in-action.png \ No newline at end of file
diff --git a/sites/pmikkelsen.com/me/stuff-i-use.md b/sites/pmikkelsen.com/me/stuff-i-use.md
new file mode 100644
index 0000000..08aa7e7
--- /dev/null
+++ b/sites/pmikkelsen.com/me/stuff-i-use.md
@@ -0,0 +1,46 @@
+* Note: Last updated on 2020/05/28
+
+# Operating system
+
+I mostly use [guix][1] but sometimes I need software that is not yet
+ported, and then I use [fedora][2]. If I could, I would use [9front][3]
+alot more, since the system is much better and different in my opinion. I
+also like [OpenBSD][4] alot.
+
+# Text editor
+
+Acme from plan9port. Sometimes I use emacs if I have to edit scheme code, since automatic closing of matching `(` and `)` makes life much easier.
+
+# Shell
+
+I use the [rc shell][5] since it works nicely in both acme and 9term from plan9port. Also I like its syntax alot more than the syntax of bash.
+
+# Web browser
+
+Mainy firefox (this page is only tested on firefox, so please let me
+know if you have problems on other browsers).
+
+# Laptop
+
+I use a Lenovo Thinkpad E495 with an AMD ryzen 3700U and 16 gigabytes
+of ram. It is a fairly good computer for the price, and OpenBSD is
+supported out of the box with the exception of wifi. For this reason, I
+have small usb wifi dongle that is constantly plugged in, which performs a
+lot worse than what some people would like, but for me it is no big deal.
+
+
+# Mouse and keyboard
+
+Since I have never been a fan of touchpads on laptops, I use an external
+mouse which is a Logitech MX Master 3. I also have a keyboard that I
+sometimes plug in if I have to do more writing than what I can comfortably
+do on my laptop. The keyboard is from the coolermaster masterkeys lite L
+bundle. Clicking in acme using the scroll wheel instead of using a true
+3-button mouse is sometimes a bit annoying, but its OK.
+
+
+[1]: https://guix.gnu.org/
+[2]: https://getfedora.org/
+[3]: http://9front.org/
+[4]: https://openbsd.org/
+[5]: https://plan9.io/sys/doc/rc.html \ No newline at end of file
diff --git a/sites/pmikkelsen.com/opinions/favourite-programming-languages.md b/sites/pmikkelsen.com/opinions/favourite-programming-languages.md
new file mode 100644
index 0000000..f80131c
--- /dev/null
+++ b/sites/pmikkelsen.com/opinions/favourite-programming-languages.md
@@ -0,0 +1 @@
+To be written \ No newline at end of file
diff --git a/sites/pmikkelsen.com/plan9/basic_9p_server.md b/sites/pmikkelsen.com/plan9/basic_9p_server.md
new file mode 100644
index 0000000..7c1c514
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/basic_9p_server.md
@@ -0,0 +1,58 @@
+## Writing a basic 9P server
+
+On plan 9 the entire system is build around the idea of namespaces
+and that _"everything is a file"_. For this reason it is very easy to write
+a new 9P fileserver in C since all the boring tasks are implemented in
+libraries. This note describes a minimal program which serves a folder to
+`/mnt/hello9p` containing a single synthetic file with the contents "Hello from 9P!".
+
+## The code
+
+ #include <u.h>
+ #include <libc.h>
+ #include <fcall.h>
+ #include <thread.h>
+ #include <9p.h>
+
+ void
+ fsread(Req *r)
+ {
+ readstr(r, "Hello from 9P!\n");
+ respond(r, nil);
+ }
+
+ Srv fs = {
+ .read = fsread,
+ };
+
+ void
+ main(void)
+ {
+ Tree *tree;
+
+ tree = alloctree(nil, nil, DMDIR|0555, nil);
+ fs.tree = tree;
+ createfile(tree->root, "hello", nil, 0555, nil);
+
+ postmountsrv(&fs, nil, "/mnt/hello9p", MREPL | MCREATE);
+ }
+
+## Explanation
+
+The global variable `fs` is a structure which contains function pointers
+to all the 9P handlers, but since I only plan on reading from the file,
+only the `read` field is set. The fsread function calls two helper functions
+from the 9p(2) library which will create a response with the given string as
+the file contents.
+
+In `main` I start by allocating a new file tree, since this 9P server deals with
+a fileserver that has a tree structure, and therefore I don't have to worry
+about how directories are handled for example. A file is added with `createfile`
+to the root of the tree.
+
+The call to `postmountsrv` will mount the 9P server under `/mnt/hello9p`.
+
+## Thats it
+
+This is not very complicated, but see the manpages at 9p(2) and 9pfile(2)
+and intro(5) for more information about the libraries and 9P itself.
diff --git a/sites/pmikkelsen.com/plan9/discord.md b/sites/pmikkelsen.com/plan9/discord.md
new file mode 100644
index 0000000..8a9815f
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/discord.md
@@ -0,0 +1,83 @@
+# Chatting on discord from 9front
+
+Sometimes you work with people who doesn't want to use the same communication
+tools as you do. A sad example is when your team members wants to use discord,
+and not something simpler like IRC. Oh well, gotta deal with it.
+
+This is the reason I wrote a "discord bot" (ugh) which can run on your 9front
+system and allow you to chat on discord anyways.
+
+## Example gif
+
+The example below just opens two chat windows with different channels in each.
+While it works both in acme and in the terminal, I like having everything
+together inside acme.
+
+[![An animated gif showing discord chats from 9front][1]][1]
+
+## The code
+
+The project is made of a few scripts and a go program. The only thing that
+actually communicates with discord is the go program, and the scripts just
+makes it easier to send and recieve on the correct channels. The code is
+available [here](https://git.sr.ht/~pmikkelsen/discordfront), and there is
+a precompiled version of the go program included (compiled for 9front amd64).
+
+## Usage
+
+To use the service, you must first create a bot on discord and get the
+access token. I personally found this step much more confusing then the
+actual coding itself, which either tells you something about my google
+skills, or about discord.. Oh, and then you must invite the bot to your
+discord server..
+
+Next, the server part of the bot must be started:
+
+ `discordsrv YOURTOKEN`
+
+This will post a pipe in /srv/discordfront, where messages can be send
+and recieved from, but you should not read from it directly. The
+`discordsrv` script does this for you as well, and it takes each line
+and dumps it in a nice readable format into
+`$home/lib/discord/logs/$serverName/$channelName`
+where the server name is the name of a discord server (or guild?), and
+the channel name is, well, the name of the channel.
+
+Now that the server is started, you can either run `discordacme` which
+opens an acme with the file `$home/lib/discord/channels` open. This file
+is not handled by any of the scripts, so it is just a handy text file to
+keep shortcuts to various channels (see the gif for an example).
+Inside `discordacme`, the `openChat` command will open a new chat window,
+using the simpler `discord` script.
+
+The `discord` script simply runs `tail -f` on the given channel's logfile
+while it reads messages from standard input and sends them to
+/srv/discordfront at the same time.
+
+## Using remotely
+
+Since this program does not fetch previous messages, it might be a good
+idea to run the server part `discordsrv` on a machine that is always online,
+so that all messages gets logged. Since this is plan9, it is almost trivial
+to still use the client on your local machine, just by using `rimport` to
+import the relevant file trees from the server.
+
+Here is what I do (in a seperate script which is run at startup):
+
+ #!/bin/rc
+
+ rfork
+ rimport -ac -p $serverhost /srv
+ rimport -c -p $serverhost /usr/glenda/lib/discord
+ discordacme
+
+I don't even notice it is not running locally.
+
+## Notes
+
+* Yes, the names of the scripts suck.
+* Yes, there is a lot of missing functionality.
+* No, this has not been tested very much, it just seems to do the job
+well enough for now.
+
+[1]: /images/discordgif.gif
diff --git a/sites/pmikkelsen.com/plan9/dns.md b/sites/pmikkelsen.com/plan9/dns.md
new file mode 100644
index 0000000..04bd7b5
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/dns.md
@@ -0,0 +1,41 @@
+# Using 9front as an authoritative DNS server
+
+This note describes the steps I took to make the 9front server
+at pmikkelsen.com the authoritative dns server for itself.
+
+First, I logged into my domain name registrar and changed the dns servers for
+my domain to `ns1.pmikkelsen.com` and `ns2.pmikkelsen.com` (It would not let me have
+just one, but I choose to live dangerously and point both of those domains at
+the same server).
+
+To let the world know _where_ `ns1` and `ns2` can be found,
+I added their ip on the registrar's website (since my own dns server cannot serve
+them for good reasons). Anyways, this might not be the same for you since you
+may not use the same provider.
+
+## Starting the dns server in "serve mode"
+
+First I added 1 line to the `/cfg/$sysname/cpurc` file to enable the dns server.
+
+ ndb/dns -s
+
+After that I added a few lines in `/lib/ndb/local` to setup all the dns records I needed:
+
+ dom=pmikkelsen.com soa=
+ ip=80.240.16.196
+ mx=vps1.pmikkelsen.com pref=1
+ txtrr="v=spf1 a mx ip:80.240.16.196 ~all"
+
+ dom=p9auth.pmikkelsen.com soa=
+ ip=80.240.16.196
+
+ dom=vps1.pmikkelsen.com soa=
+ ip=80.240.16.196
+
+ dom=_dmarc.pmikkelsen.com soa=
+ txtrr="v=DMARC1; p=none"
+
+With this done, I now have A records, mx records and txt records in place, so my website,
+mail and rcpu works as expected.
+
+Bye. \ No newline at end of file
diff --git a/sites/pmikkelsen.com/plan9/fonts.md b/sites/pmikkelsen.com/plan9/fonts.md
new file mode 100644
index 0000000..6cd6780
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/fonts.md
@@ -0,0 +1,29 @@
+# Fonts on 9front
+
+By default 9front uses a font called VGA but its too small for my eyes.
+
+The fonts I use (dejavu) look like this[![an image showing the fonts][1]][1] and are attached below:
+
+[proportional font](/_files/djv.tar)
+
+[monospace font](/_files/djvmono.tar)
+
+They can be recreated by having them installed on linux and doing the following from
+linux with plan9port installed.
+
+ fontsrv -m /tmp/fonts
+ cp -r /tmp/fonts/DejaVuSomeThing/14a/ /tmp/djv
+
+You can try a different font or font size if you want.
+
+Then connect to 9front via drawterm and run:
+
+ mkdir /lib/font/bit/djv
+ dircp /mnt/term/tmp/djv /lib/font/bit/djv
+
+Finally change your `lib/profile` to use `/lib/font/bit/djv/font` :)
+
+Note that 9front includes truetypefs which allows you to use `.ttf` files
+directly, but I find the results are better looking this way.
+
+[1]: /images/djvfonts.png \ No newline at end of file
diff --git a/sites/pmikkelsen.com/plan9/lets_encrypt.md b/sites/pmikkelsen.com/plan9/lets_encrypt.md
new file mode 100644
index 0000000..f0b1c07
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/lets_encrypt.md
@@ -0,0 +1,59 @@
+## How I get tls certificates for 9front
+
+First of all, I use linux and drawterm for this for now, but
+I would like to be able to do it all from 9front at some point.
+
+## Generate the certificate
+
+Install certbot on linux and run the following command
+
+ certbot certonly --manual -d pmikkelsen.com -d vps1.pmikkelsen.com
+
+and do the challenges, they should be easy.
+
+## Importing the cert and private key
+
+Start drawterm and login as the hostowner. After this, the filesystem of the linux
+system is available at `/mnt/term`. Run the following:
+
+ cd /sys/lib/tls/
+ cp /mnt/term/etc/letsencrypt/live/pmikkelsen.com/privkey.pem ./
+ cp /mnt/term/etc/letsencrypt/live/pmikkelsen.com/fullchain.pem ./cert
+
+Now the private key must be converted to one that can be loaded into factotum
+
+ auth/pemdecode 'PRIVATE KEY' privkey.pem | auth/asn12rsa -t 'service=tls role=client' > key
+ rm privkey.pem
+ chmod 400 key
+
+Add the following to `/cfg/$sysname/cpurc` to load the private key on boot.
+
+ cat /sys/lib/tls/key >> /mnt/factotum/ctl
+
+Done.
+
+## SMTP over TLS
+
+I have the following in `/bin/service.auth/tcp25`
+
+ #!/bin/rc
+
+ user=`{cat /dev/user}
+ exec upas/smtpd -c /sys/lib/tls/cert -n $3
+
+Notice I had to put it in the `/bin/service.auth` folder so that it could find the private key.
+
+## Https with rc-httpd
+
+I have the following in `/bin/service.auth/tcp443`
+
+ #!/bin/rc
+
+ exec tlssrv -c /sys/lib/tls/cert -l /sys/log/https /bin/service/tcp80 $*
+
+Again, in the `/bin/service.auth` folder. It simply wraps the plain http service
+in a tls wrapper which looks like this for me
+
+ #!/bin/rc
+ PLAN9=/
+ exec /rc/bin/rc-httpd/rc-httpd >>[2]/sys/log/www
diff --git a/sites/pmikkelsen.com/plan9/mounting-9p-over-drawterm.md b/sites/pmikkelsen.com/plan9/mounting-9p-over-drawterm.md
new file mode 100644
index 0000000..414b9f2
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/mounting-9p-over-drawterm.md
@@ -0,0 +1,58 @@
+# Mounting a 9P connection over drawterm
+
+I sometimes use drawterm on linux to connect to my 9front server.
+While it is possible to access the host system's files under `/mnt/term`, there is no builtin way to access the remote system's file under linux.
+Now, why would anybody want to do this?
+In my case, I often want to write some code under 9front, but for languages which aren't supported such as prolog in this case, so there are three options as I see it:
+
+* Store the files on the host machine, and access them under `/mnt/term`.
+* Store the files on the server and somehow mount the server's filesystem on the host.
+* Store the files on a third machine that both the host and server can access.
+
+Option number two seems best for me, so I asked around and it seems like the best tool to mount a 9P connection on linux is [9pfs](https://github.com/bunny351/9pfs).
+
+## How it works
+
+Before I could mount the connection, I had to serve it somehow. Normally I already serve 9P directly from my server's filesystem, but that requires some
+authentication that 9pfs does not support, so I had to serve it without authentication.
+Serving directly to the internet without authentication is of course pretty dumb since everyone can then access my files, so thanks to a hint from hiro, I figured
+out that it is actually possible to use the host's network stack on the server by binding `/mnt/term/net` over `/net`.
+
+I'll just show the final script below and explain it afterwards:
+
+ #!/bin/rc
+
+ rfork n
+ bind /mnt/term/net /net
+ aux/listen1 -t tcp!*!12335 /bin/exportfs -r / &
+ os mkdir -p /tmp/drawterm
+ os 9pfs localhost -p 12335 /tmp/drawterm
+
+So the first thing that happens is that I bind the host's network in, and from that point on, every network connection in this namespace actually goes out
+from the host instead of from the server!
+
+Then `exportfs` is started and it is serving the `/` directory over 9P at port 12335.
+The `os` command runs a command on the host, so it just creates the folder that the system will be mounted to, and then uses `9pfs` to actually mount it.
+The nice thing here is that `9pfs` just connects to localhost.
+
+## Using it
+
+As I said in the beginning, I did this to be able to edit files on the 9front server, and run compilers/interpreters on linux.
+The `os` command goes a long way, but the following script makes it even easier (I have this installed as `linux`):
+
+ #!/bin/rc
+
+ dir=/tmp/drawterm/`{pwd}
+ os -d $dir $*
+
+This means I can just go into any directory on the server, type `linux ghci` and I get a haskell repl running in the correct directory, as seen in the gif below.
+
+[![An animated gif showing ghci loading a file on the 9front server][1]][1]
+
+
+## Final notes
+
+The bind net trick still blows my mind a bit, since it is so trivial, yet so powerful. It is also fun to think about how one would do this
+on other systems than plan9, which I can't even imagine.
+
+[1]: /images/linuxreverse.gif
diff --git a/sites/pmikkelsen.com/plan9/network_booting.md b/sites/pmikkelsen.com/plan9/network_booting.md
new file mode 100644
index 0000000..3bb51b9
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/network_booting.md
@@ -0,0 +1,30 @@
+## Network booting into the server at pmikkelsen.com
+
+Sometimes it is nice to be able to connect directly to a remote server
+from my laptop and have the same root filesystem available.
+This is possible by typing `tls` at the boot prompt and then
+typing `pmikkelsen.com` for the fs and auth server.
+
+## Speed
+
+On my internet connection some things can be very slow
+(such as compiling the entire system), because of fs access now happens
+over the network. The easy fix is to just start a cpu connection to the server
+where the fs access can happen fast since it is on the same machine. This is
+done by typing
+
+ rcpu -h pmikkelsen.com
+
+Of course the server has a pretty slow cpu..
+
+## Server settings
+
+Some steps are needed to make this work:
+
+1. The user must be added to the fileserver and auth server.
+2. The fileserver must be listening for remote connections.
+3. The correct ndb entries must be set (in the beginning I forgot `fs` and I could
+only connect via tcp, not tls)
+
+More information about all those steps can be found in section 7 of [the 9front FQA](http://fqa.9front.org/fqa7.html).
+
diff --git a/sites/pmikkelsen.com/plan9/trellofs.md b/sites/pmikkelsen.com/plan9/trellofs.md
new file mode 100644
index 0000000..42e2cfd
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/trellofs.md
@@ -0,0 +1,347 @@
+## A filesystem for viewing trello
+
+Since my last note [here](http://pmikkelsen.com/plan9/basic_9p_server)
+was very simple, here comes
+a small program (around 250 lines of C), which makes it
+possible to view trello as a read-only filesystem.
+
+## Usage example
+
+First set the `trellokey` and `trellotoken` environment
+variables to the API key and token from the trello website.
+
+ term% trellokey=1298791723987937123.....
+ term% trellotoken=923748237497ab798798999999.....
+
+Then `webfs` must be started so the program can make
+requests to the trello REST api.
+
+ term% webfs
+
+Then `trellofs` itself must be started. It mounts the filesystem under `/mnt/trello`.
+
+ term% trellofs
+
+If I now go and see which boards I have, I get the following
+
+ term% cd /mnt/trello
+ term% ls
+ Beaglebone_Black
+ Fly
+ Fysik_Rapport
+ Guld_kobber
+ Ideer_til_2._produkt
+ Lektier
+ P0
+ P1
+ P2
+ Projekt_Materialer
+ Spil
+ Welcome_Board
+
+The names of the folders are almost like the original board names, except
+that that some characters have been replaced by `_`. Lets look at `P1`
+
+ term% cd P1
+ term% ls
+ Backlog
+ Done
+ Estimat
+ In-progress
+ Info
+ Master.C_Top_Down_Ting
+ Sprint_1
+ Test
+ Test_sprint_1
+ Todo
+
+Todo must have something worth looking at
+
+ term% ls
+ Færdig_rapport_aflevering
+ Korrekturlæsning
+
+Those two items are the actual trello "cards", which I think of as tasks. The first
+one means "Final report hand in", so let's have a look at that.
+
+ term% cd Færdig_rapport_aflevering
+ term% ls
+ description
+ duedate
+ url
+
+There are always three files inside each card folder, but since the information in them
+is not mandatory on trello, some of them will be empty.
+
+ term% cat description
+
+ term% cat duedate
+ 2019-12-18T13:00:00.000Z
+ term% cat url
+ https://trello.com/c/u23ZcNAm/9-f%C3%A6rdig-rapport-aflevering
+
+## Limitations
+
+The key and token are right now in environment variables, which is somewhat
+awkward. Also I would like to be able to actually create and move cards directly
+from the filesystem just by creating files, but that is not something I will implement
+right now.
+
+## The code
+
+The code for the `trellofs` program is listed below.
+
+ #include <u.h>
+ #include <libc.h>
+ #include <fcall.h>
+ #include <thread.h>
+ #include <9p.h>
+ #include <json.h>
+
+ #define MAX_RESPONSE_SIZE (1024 * 1024 * 8)
+
+ char *key;
+ char *token;
+
+ void
+ fsread(Req *r)
+ {
+ char *str;
+
+ if (r->fid->file->aux == nil) {
+ readstr(r, "");
+ } else {
+ str = malloc(strlen(r->fid->file->aux) + 2);
+ sprint(str, "%s\n", r->fid->file->aux);
+ readstr(r, str);
+ }
+ respond(r, nil);
+ }
+
+ Srv fs = {
+ .read = fsread,
+ };
+
+ JSON *
+ trelloget(char *endpoint, char *params)
+ {
+ int ctlfd, bodyfd;
+ int n;
+ int err;
+ char *buf;
+ JSON *res;
+
+ res = nil;
+ bodyfd = -1;
+
+ buf = malloc(MAX_RESPONSE_SIZE + 1);
+ if(buf == nil) {
+ perror("malloc");
+ return nil;
+ }
+
+ ctlfd = open("/mnt/web/clone", ORDWR);
+ if(ctlfd < 0) {
+ perror("open");
+ goto fail;
+ }
+
+ if(read(ctlfd, buf, 32) < 0) {
+ perror("read");
+ goto fail;
+ }
+
+ n = atoi(buf);
+
+ sprint(buf, "url https://api.trello.com/%s?key=%s&token=%s", endpoint, key, token);
+ if(params)
+ sprint(buf + strlen(buf), "\&%s\n", params);
+ else
+ sprint(buf + strlen(buf), "\n");
+
+ err = write(ctlfd, buf, strlen(buf));
+ if(err < 0){
+ perror("write");
+ goto fail;
+ }
+
+ sprint(buf, "/mnt/web/%d/body", n);
+ bodyfd = open(buf, OREAD);
+ if(bodyfd < 0){
+ perror("open");
+ goto fail;
+ }
+
+ err = readn(bodyfd, buf, MAX_RESPONSE_SIZE);
+ if (err < 0) {
+ perror("read");
+ goto fail;
+ }
+
+ res = jsonparse(buf);
+
+ fail:
+ close(ctlfd);
+ close(bodyfd);
+ free(buf);
+
+ return res;
+ }
+
+ char *
+ escapename(char *str)
+ {
+ char *new;
+ int i, len;
+
+ len = strlen(str);
+
+ new = malloc(len + 1);
+ for(i = 0; i <= len; i++){
+ switch(str[i]){
+ case '/':
+ case ' ':
+ case ',':
+ case ':':
+ case '"':
+ case '\'':
+ new[i] = '_';
+ break;
+ default:
+ new[i] = str[i];
+ }
+ }
+ return new;
+ }
+
+ void
+ addcard(File *dir, JSON *card)
+ {
+ JSON *element;
+ char *filename;
+ File *carddir;
+ char *description;
+ char *url;
+ char *duedate;
+
+ element = jsonbyname(card, "name");
+ filename = escapename(element->s);
+ carddir = createfile(dir, filename, nil, DMDIR|0555, nil);
+ if(carddir == nil){
+ perror("createfile");
+ return;
+ } else {
+ element = jsonbyname(card, "desc");
+ description = strdup(element->s);
+ element = jsonbyname(card, "url");
+ url = strdup(element->s);
+ element = jsonbyname(card, "due");
+ if (element->t == JSONString)
+ duedate = strdup(element->s);
+ else
+ duedate = nil;
+ createfile(carddir, "description", nil, 0444, description);
+ createfile(carddir, "url", nil, 0444, url);
+ createfile(carddir, "duedate", nil, 0444, duedate);
+ }
+ free(filename);
+ }
+
+ void
+ addlist(File *dir, JSON *list)
+ {
+ JSON *element;
+ char *filename;
+ JSON *cards;
+ JSONEl *card;
+ char cardsEndpoint[128];
+ File *listdir;
+
+ element = jsonbyname(list, "name");
+
+ filename = escapename(element->s);
+ listdir = createfile(dir, filename, nil, DMDIR|0555, nil);
+ if(listdir == nil){
+ perror("createfile");
+ return;
+ } else {
+ element = jsonbyname(list, "id");
+ sprint(cardsEndpoint, "1/lists/%s/cards", element->s);
+ cards = trelloget(cardsEndpoint, "fields=desc,name,url,due");
+ if(cards == nil)
+ return;
+
+ for(card = cards->first; card != nil; card = card->next){
+ addcard(listdir, card->val);
+ }
+ }
+ jsonfree(cards);
+ free(filename);
+ }
+
+ void
+ addboard(File *root, JSON *board)
+ {
+ JSON *element;
+ JSONEl *list;
+ char *filename;
+ File *boarddir;
+
+ element = jsonbyname(board, "name");
+ filename = escapename(element->s);
+ boarddir = createfile(root, filename, nil, DMDIR|0555, nil);
+ if(boarddir == nil) {
+ perror("createfile");
+ return;
+ }
+
+ element = jsonbyname(board, "lists");
+ for(list = element->first; list != nil; list = list->next){
+ addlist(boarddir, list->val);
+ }
+
+ free(filename);
+ }
+
+ void
+ trelloinit(File *root)
+ {
+ JSON *result;
+ JSONEl *board;
+
+ result = trelloget("1/members/me/boards", "fields=name,lists&lists=open");
+
+ for(board = result->first; board != nil; board = board->next){
+ addboard(root, board->val);
+ }
+ jsonfree(result);
+ }
+
+ void
+ main(void)
+ {
+ JSONfmtinstall();
+
+ key = getenv("trellokey");
+ token = getenv("trellotoken");
+
+ Tree *tree;
+
+ tree = alloctree(nil, nil, DMDIR|0555, nil);
+
+ fs.tree = tree;
+ trelloinit(tree->root);
+
+ postmountsrv(&fs, nil, "/mnt/trello", MREPL | MCREATE);
+ }
+
+The program can be compiled by hand or by using the following `mkfile`.
+
+ BIN=/usr/glenda/bin/amd64
+
+ TARG=trellofs
+
+ OFILES=\
+ main.$O\
+
+ </sys/src/cmd/mkone
diff --git a/sites/pmikkelsen.com/plan9/using_irc.md b/sites/pmikkelsen.com/plan9/using_irc.md
new file mode 100644
index 0000000..0c3622c
--- /dev/null
+++ b/sites/pmikkelsen.com/plan9/using_irc.md
@@ -0,0 +1,48 @@
+_Last updated: 2020-07-30_
+
+# Using IRC on 9front
+
+While 9front comes with an irc client called `ircrc`, it can be quite annoying that it does not
+keep a persistent connection.
+
+A different program `irc7` provides a server part which keeps a connection open to an irc server,
+and a client part which allows for connecting to the server. This works great since it makes it possible to
+get all the messages on a channel without being online all the time.
+
+## Setup
+
+Download the irc7 code via `hg`:
+
+ hg clone https://code.9front.org/hg/irc7/
+
+Build and install
+
+ cd irc7
+ mk install
+
+## Usage
+
+First the server program `ircsrv` must be started, so I would run
+
+ ircsrv -e -p VerySecretPassword pmikkelsen net!irc.freenode.net!7000
+
+to connect as `pmikkelsen` to freenode over tls and with password for my nickname.
+After this, it is possible to connect to different channels by opening new rio windows
+and running
+
+ irc -t '#cat-v' -b
+
+to connect to the cat-v channel. The `-b` option without any extra arguments
+prints the entire conversation since the ircsrv was started,
+so it might not always be desirable.
+
+To see all the messages sent directly to me, I would run
+
+ irc -t MSGS
+
+and maybe start a conversation with user 'mousehater' by running
+
+ irc -t mousehater
+
+I run this on a remote cpu server that is rarely powered off, and then I just connect via
+drawterm from linux to chat, or via rcpu from other 9front machines.
diff --git a/sites/pmikkelsen.com/web/the-setup-of-this-site.md b/sites/pmikkelsen.com/web/the-setup-of-this-site.md
new file mode 100644
index 0000000..a834d77
--- /dev/null
+++ b/sites/pmikkelsen.com/web/the-setup-of-this-site.md
@@ -0,0 +1,3 @@
+This site is hosted on a 9front VPS, using werc. I will write more about this in the future perhaps.
+
+It was created by downloading werc and adding my page. Werc + my page can be found at [https://hg.sr.ht/~pmikkelsen/website](https://hg.sr.ht/~pmikkelsen/website).