diff options
author | glenda <glenda@9front.local> | 2020-11-15 15:13:27 +0000 |
---|---|---|
committer | glenda <glenda@9front.local> | 2020-11-15 15:13:27 +0000 |
commit | 39318169e0b50551db511851829f9337c5fa6313 (patch) | |
tree | 65a0ef5c1da9677532fa8105293d017919473057 /sites |
Import site to git
Diffstat (limited to 'sites')
32 files changed, 1153 insertions, 0 deletions
diff --git a/sites/pmikkelsen.com/_files/djv.tar b/sites/pmikkelsen.com/_files/djv.tar Binary files differnew file mode 100644 index 0000000..5d60262 --- /dev/null +++ b/sites/pmikkelsen.com/_files/djv.tar diff --git a/sites/pmikkelsen.com/_files/djvmono.tar b/sites/pmikkelsen.com/_files/djvmono.tar Binary files differnew file mode 100644 index 0000000..1fb0c7d --- /dev/null +++ b/sites/pmikkelsen.com/_files/djvmono.tar 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 Binary files differnew file mode 100644 index 0000000..19dd98f --- /dev/null +++ b/sites/pmikkelsen.com/images/2048.gif diff --git a/sites/pmikkelsen.com/images/acme-in-action.png b/sites/pmikkelsen.com/images/acme-in-action.png Binary files differnew file mode 100644 index 0000000..b74d9dc --- /dev/null +++ b/sites/pmikkelsen.com/images/acme-in-action.png diff --git a/sites/pmikkelsen.com/images/cdude.png b/sites/pmikkelsen.com/images/cdude.png Binary files differnew file mode 100644 index 0000000..66ee18d --- /dev/null +++ b/sites/pmikkelsen.com/images/cdude.png diff --git a/sites/pmikkelsen.com/images/cursed.png b/sites/pmikkelsen.com/images/cursed.png Binary files differnew file mode 100644 index 0000000..f92e06e --- /dev/null +++ b/sites/pmikkelsen.com/images/cursed.png diff --git a/sites/pmikkelsen.com/images/discordgif.gif b/sites/pmikkelsen.com/images/discordgif.gif Binary files differnew file mode 100644 index 0000000..207af41 --- /dev/null +++ b/sites/pmikkelsen.com/images/discordgif.gif diff --git a/sites/pmikkelsen.com/images/djvfonts.png b/sites/pmikkelsen.com/images/djvfonts.png Binary files differnew file mode 100644 index 0000000..86d58a4 --- /dev/null +++ b/sites/pmikkelsen.com/images/djvfonts.png diff --git a/sites/pmikkelsen.com/images/linuxreverse.gif b/sites/pmikkelsen.com/images/linuxreverse.gif Binary files differnew file mode 100644 index 0000000..6684116 --- /dev/null +++ b/sites/pmikkelsen.com/images/linuxreverse.gif diff --git a/sites/pmikkelsen.com/images/mordor.gif b/sites/pmikkelsen.com/images/mordor.gif Binary files differnew file mode 100644 index 0000000..fe13c09 --- /dev/null +++ b/sites/pmikkelsen.com/images/mordor.gif 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). |