commit 75241145fb911468749a83c11ee0404710a3c9d8 from: Alexander Arkhipov date: Mon Nov 6 11:40:40 2023 UTC Huge November 2023 update This update implements most of the changes I've been thinking about for the last half-a-year: - I wish to serve files over many protocols: http, gopher, ftp, rsync and finger, and maybe even things like gemini in future. - I wish to maintain a history of changes as a git repository. - Maintaining the above, I don't want to do more things manually than necessary. - Maintaining a sensible news feed is something I've been struggling with since beginning -- I wish to minimise that. - I've written a lot of things here while angry at the entire world. I am a much calmer person now, and wish my former frustrations gone. commit - fc1c58374955659a8123bc6d4f81cfed4b9fb176 commit + 75241145fb911468749a83c11ee0404710a3c9d8 blob - fb20d8749e70fed1e49f68a1f4c6dfc9dead0cc6 (mode 644) blob + /dev/null --- .plan +++ /dev/null @@ -1,13 +0,0 @@ -I reinstituted (again...) the links page. This time the number of -links is very small, and the web page leads to different sites than -the gopher menu. Hopefully this time I'll keep that. [links] - -I also recently bought a cheap diginal photo camera. I was (from -description) expecting it to have a microusb interface, but -unfortunately I had to lift the ban on usb-c in my room after less -than a year. I made a few [photos] already and uploaded them to ftp. -Perhaps later I'll organise them somehow on the web site. - -[links] gopher://alearx.org/1/ln.gph - https://alearx.org/ln.html -[photos] ftp://alearx.org/pub/photos/ blob - 307c0e5ae3317e1327daec5be863ba0081f599da (mode 644) blob + /dev/null --- .project +++ /dev/null @@ -1,2 +0,0 @@ -Currently reading "Moby Dick" by Herman Melville and -"the cashflow quadrant" by Robert Kiyosaki. blob - /dev/null blob + 48532a401e7aefbafe3f30e78a74b2ce336ea5fa (mode 644) --- /dev/null +++ common.exclude @@ -0,0 +1,3 @@ +*.exclude +/git/*** +/pub/*** blob - 828bbbb360a5f737c51bbd1453122b189a31c8ef (mode 644) blob + /dev/null --- README.txt +++ /dev/null @@ -1,134 +0,0 @@ -I find that it's easier to organise this README in a -"question-answer" format. Questions are marked with "Q:", and answers -with "A:". People usually call such documents "FAQs", however there -are some interesting questions asked infrequently. - -Q: Who are you? -A: I am Alexander Arkhipov, a Unix hacker from Moscow. - -Q: How can I contact you? -A: h=alearx.org; finger arkhipov@$h | grep -o '^Login: aa ' | - head -1 | sed "s/Login: \([^ ]*\) /\1@$h/" - - You can use the output for both finger(1) and mail. - -Q: Do you have a PGP key? -A: Yes, it's at ftp://alearx.org/pub/pgp/ -- pick the latest one. - The pub directory is also mirrored on http and gopher. - -Q: What services does alearx.org provide? -A: Most services are at alearx.org. - - There is a mail server running. I publish news via finger (but - also http and gopher). I publish some files to ftp and rsync (but - also http and gopher). The http and gopher sites are almost - identical. You can clone my git repositories via anongit (see the - git/ directory on www or gopher site). - - I also maintain a boring site with a blog and a resume at - pro.alearx.org. - -Q: What language(s) do you speak? -A: Russian is my native language, but I speak English fluently. I - generally don't read email in Russian -- English is the language - of computing. I also speak a little bit of German. - -Q: Do you maintain any "public" accounts elsewhere? -A: I am called alearkh on github. The rest that you might be able to - see either exist for stupid reason, or not needed anymore. - -Q: What's up with news/* filenames? -A: The oldest file is called 9999.YYYY-mm-dd, and the latter ones - reduce the first number by one. This way they can be sorted - alphabetically, and I am very unlikely to ever run out of - numbers (and even if I do, I can archive them and restart). - -Q: What's up with your domain names? -A: I got my first domain name, and started my first open-source - projects when I was finishing my university. At the time I allowed - another student to convince me that a good "internet identity" - would be a unique, easy to pronounce string (even if meaningless), - such as those people from reddit or whatever would use. I ended - up making a website at the domain mcflexy.net. In a short while, - however, I decided that I should instead allow my (real) name to - speak for itself, but still didn't want to embed my name into a - domain name because: - - 1) I've got a pretty long name - 2) Most shorter versions I could think of at the time were taken - - So instead I decided to register something that'd read as an - English word or phrase, and finally came up with mineeyes.cyou. - I would regret the decision almost immediately, as I discovered a - lot of spam filters had no trust in .cyous. - - At the time I didn't have a lot of money to begin with, and - transferring them was becoming a huge problem (it was 2022, and my - "benevolent" government forbids me from naming the Ukrainian event - that broke out then). It wasn't too long, however, before I - graduated from my slave camp, and was hired into another, at which - point I at least managed to get my bitcoins together and start - thinking. I registered manpager.net (named after the environment - variable MANPAGER), and put a notice that mineeyes.cyou is going. - I also realised at later point that I transferred way too much - bitcoin (unless I just wanted to renew one domain for the next 20 - years), so I registered a few I thought may be useful later. - - I was happy with the situation for a while, but then I had to - register on github to participate in a project. Github required me - to give my user a name (and not just a mail address), but all my - favourite names for Unix users were already taken, and I didn't - want to name my user "manpager"! I came up with "drjfaust", as in - "doctor Johann Faust", but I wasn't happy with it. - - Eventually the idea of catenating first X letters of my first name - with first Y letters of my surname occurred to me. The method also - has some flexibility, and can produce funny results. 3 for both X - and Y seemed to be a good number, so I registered alearx.org (.net - was a mistake -- it's a TLD for ISPs and the like), and changed my - github user name to alearkh. The x in alearx is substitute for - Greek chi. - - That pretty much concludes the story up until now. - -Q: What do you call your Unix users? -A: I usually name my main user aa for my initials. Most of the other - users, that I might maintain to drop some privileges for certain - tasks, are usually given short names like "tim" or "jean". - -Q: What do you call your hosts? -A: I distinguish between the name(s) by which the host is known on the - local network, or among friends via /etc/hosts, and the - publicly-known FQDNs, which are set up via DNS, but also matter - with web and smtp servers. - - The "local" names are short Unix "words", such as "manpager", - "cflags", "ex", &c. The FQDNs are just whatever makes sense, while - being short and memorable. - -Q: What about copying your work? -A: When I first began programming (and I mean actually programming - rathern than doing tasks at school/university), I was perplexed - by copyright. ("license my program!? it's not a book, or - something, you know") Then there was a period during which I was - extremely confused, and now I am just mildly confused. - - Inspecting existing licences I stumbled upon BSD0, which removes - the attribution clause from the normal BSD licence. So I decided - to deal with the issue by just putting that into COPYING for each - of my projects. Many still are distributed this way. - - Later I discovered that the copyright laws don't allow me to - reject my right to sue people who'd forgotten to attribute my work - to me, so from that point I decided to instead use OpenBSD's ISC - licence. I also discovered that further complications arise when a - project includes files from different sources, so instead I now - have a licence-comment at the top of each source file. - - Now I believe that some of the text files I publish via gopher may - be subjects of copyright, so I also have a small notice at the - bottom of such files. - -Q: What sort of Unix do you run? -A: Mostly OpenBSD, though I'd like to get Linux on a separate - machine. blob - 8aee431249d30c65c4808ce6433ad778f3417e88 (mode 644) blob + /dev/null --- art/battlestar.txt +++ /dev/null @@ -1,442 +0,0 @@ -battlestar(6) is an game written by "His Lordship, Admiral David W. -Horatio Riggle." It is an adventure game not unlike adventure(6) -(yes, that's a pun). His Lordship claims it to be less of a puzzle -and more of an exploration-game. Apparently he wrote it to learn C -better (the game was written in 1979, however, so we are still -talking about pre-ANSI C with its weird function declarations and the -like). It also has some interesting verbs like "fuck" (unfortunately -performing that on corpses and general population does not lead to -results all that interesting). But that's not all! battlestar(6) is -not "just" an adventure game: It also has what I can only describe as -"action segments!" - -All that sounds pretty neat. Considering that adventure(6) has a small -collective that managed through a lot of research and collaboration -find every one of the game's secrets, so should battlestar(6)... -Except it doesn't! The game is actually worse at teaching the player -how to play than adventure(6) is, and there don't appear to be any -walkthroughs on the internets. The only way I managed to complete the -game was by consulting the source code. So, for the first time ever -I am writing a walkthrough. - -For a bit of clarification: I started playing battlestar(6) on Void -Linux and consulted the same sources as the ones from which the games -are compiled on Void (which, I think, are *not* Debian's and are -written in bronze-age (pre-ANSI) C (but I might be mis-remembering)). -Later my life returned to normal somewhat and I continued playing on -OpenBSD. For that purpose I downloaded the source tree via CVS and -observed that the games have been rewritten somewhat, mostly -stylistically, however: adventure(6)'s main.c still is written in the -kind of style that used to infuriate Dijkstra etc. - -Oh, but what even is a battlestar? Well, I was wondering that as -well. Apparently at about the same time (1978) there used to exist -one of those very cheap, uninspired and horribly dull American -television-space-shows called "battlestar Galactica". By "battlestar" -the authors, of course, meant a sort of space-carrier-ship because -the meaning is so "obvious". The premise of the series, as far as -there is one, is that a very advanced human civilisation lives on -some far-away planets, waging war against some robots called -"cylons", whose dearest wish it seems to be to murder every man alive -for no reason at all. Of course, the character I shall refer to as -"Judas Iscariot" assists the robots in doing so on the condition that -they spare his home-planet Guatemala (not what they called it, but I -have bad memory for things that are somehow nonsensical, yet -uninspired) and install him as its president. Genocide is something a -lot of very resourceful people have failed to achieve on a lesser -scale after decades of constant work, yet the robots desecrate 99% of -human population in just a few hours. The other 1% is divided in -half: 0.5% is left to starve to death, while the lucky few fly in the -general direction of the earth, where we, their very primitive -brethren live. Naturally, the robots at first try to execute Judas -Iscariot after killing every single other Guatemalan, but then decide -to instead put him in command of an entire fleet with the sole -purpose of pursuing these space-gypsies. It's much more boring than -it sounds like. - -And what does any of it has to do with the game? Well, not much. The -player starts on a "battlestar" that features smaller spacecrafts -called "vipers", and then goes into space where there are a bunch of -"cylons" to kill, but that's about it. - - -WALKTHROUGH - -So, first thing to do is to open the file words.c in the source code -and find all the VERBS. Now actually start the game. - -The game starts at a LUXURIOUS STATEROOM. We check our inventory and -see the following: - - >-: i - You aren't carrying anything. - - You are wearing: - - pajamas - - You are in perfect health. - >-: - -(Some time after my first session I noticed that the prompt looks a -bit like a sad face.) - -Oh, and, yes, we'll be completing most of the game in a pyjama, so I -suggest making an alias like `alias hitchhiker=battlestar'. - -If we go back we will discover some royal robes, which we can -put on instead, however they don't appear to have any effect -whatsoever (no, really, "grep 'ROBE|PIJAMA' *.c" yourself), so -instead we shall go right. - -From the EXECUTIVE SUITES we can go in all six directions. - -Ahead is the MAID'S UTILITY ROOM. Unfortunately, the maid has -accidentally stabbed herself to the death with a knife! We take the -knife, leaving the body for the police, and go back. - -To the right is the PRESIDENTIAL SUITE. It has a laser pistol just -lying on the floor, so we take that. If we go ahead we can discover -that the president too has accidentally shot himself to death, so -instead we go back. - -Down at the FIRST CLASS LOUNGE we discover some rubble and matches. -There is not much to see at the back, so we go up. - -We could go up to get another knife and a cleaver, but we already -have a knife! So instead we go ahead to the bridal suite. - -In the BRIDAL SUITE we put on a strange amulet that we found lying on -the floor and go down. - -In the HALLWAY there area a bunch of coins, which we take and go -right and ahead. - -From the MAIN HANGAR we can go left, up or right. - -The only thing of interest on the left is a nuclear warhead. -Unfortunately, all possible interactions with it may or may not -result in the player's death, so we won't be going left. - -Up and right actually lead to the same locations. We go right twice. -There are two guards "guarding" something called "Viper," but they -don't seem to mind us launching too much. - -At this point the game prints a very helpful message: - - >-: launch - You climb into the viper and prepare for launch. - With a touch of your thumb the turbo engines ignite, thrusting you back into - your seat. - - You are in space. - - - >-: - -So, what is "space" exactly? Well... - - ... - /* 32 */ - {"You are in space.", - {33, 34, 35, 36, 37, 1, 33, 1}, - "****\n", {0} }, - /* 33 */ - {"You are in space.", - {38, 32, 39, 40, 41, 1, 42, 1}, - "****\n", {0} }, - /* 34 */ - {"You are in space.", - {32, 44, 45, 46, 47, 1, 48, 1}, - "****\n", {0} }, - /* 35 */ - {"You are in space.", - {40, 45, 49, 32, 50, 1, 51, 1}, - "****\n", {0} }, - ... - -This is all part of a struct room (two of them technically), which is -defined in extern.h: - - struct room { - const char *name; - int link[8]; - #define north link[0] - #define south link[1] - #define east link[2] - #define west link[3] - #define up link[4] - #define access link[5] - #define down link[6] - #define flyhere link[7] - const char *desc; - unsigned int objects[NUMOFWORDS]; - }; - -So, right off, flyhere and access are useless when trying to draw -some sort of a map. Miraculously there are north, south, east and -west in space, but we are yet to invent a space-proof compass. But -first of all: which point of space are we even in? Well... - - $ grep ^launch\( * - command6.c:launch() - $ less command6.c - ... - -Oh, but of course, we are at location[position].up! Also known as 32. -So, knowing that rooms 32-66 are all space, it appears that other -options include: 67 and 68, corresponding to the orbits of a small -blue planet and a tropical planet. The first leads to 69, and while -it is, as the user of an internet forum would put it, "nice," I -wouldn't go somewhere described as: - - ... - {69, 69, 69, 69, 69, 1, 69, 1}, - ... - -So instead we'll try to navigate to the tropical planet. This, -thankfully is much more straightforward than the labyrinths of -adventure(6) our path is 32-34-44-64-66-68, or s-s-s-s-s-s -- -basically, we just need to find that mysterious "space south." -Throughout these space rooms there are also some objects called -CYLON, being in one cell with a CYLON triggers the function visual(), -which produces a visual fight with the alien. I know that on this -path the only CYLON is in the room 64, which we can use to determine -which direction is south (it's right because by typing `r' once and -`a' twice I arrive at a CYLON). - -So, how about defeating the CYLON? Well, turns out that this is a -curses game as well (of course it is!), and I don't really know how -to use curses. Anyway, before starting the fight, I'd make sure that -the terminal being fought on is 80x24, because that will make things -much simpler. Right, I don't think I can put off reading fly.c any -more because the in-game prompts are most unhelpful. - -So, the first thing to do is to press plus (`+'). This will draw a -target in the middle of the screen. Our objective is to bring the -enemy (looks like `/-\') there and press `f' or space to fire. Of -course we can't move the enemy, but we can move ourselves by pressing -h/r, l, j/u and k/d along with their capitalised versions for greater -effect. This is the hardest part of the game! - -Save once the game says "You are orbiting a tropical planet." Go -down, approaching an island. This is the main part of the game. - -At this point you are free to explore the island, which is the main -part of the game. Completing it is very tricky, however. A sequence -that seems to work: - -1. Firstly, it is very important to find the goddess. If not found, -she will disappear after the first day. Once the goddess is found you -need to kiss her, follow her, kiss her a few more times and finally -love her. She will drop a medallion. DON'T take it (now at least). - -2. Find a woman who'll tell you that she wants to meet you in the -gardens at midnight. Once there and then, accept a rope from her. - -3. Otherwise explore the island. You should at least find the potion -before the rendezvous. - -4. Quickly go to the catacombs. They are only open at night, so there -is no time to lose. - -5. There are mainly three points of interest here: the sepulchre, the -room with the dark lord (a.k.a. darth vader) and a storage room. The -latter contains a grenade, which is quite honestly not that -interesting of an item. The sepulchre is more interesting: it -contains a mail shirt, an armoured helmet and a sword. It is vital to -go into the final fight wearing (not carrying) mail, the helmet, the -rope and carrying (not wearing) the sword, the laser, the potion -and the amulet. - -6. In the last room before Darth Vader make sure to sleep and eat if -carrying food and a knife. Enter with the aforementioned items and -smite the enemy until you deal him 34 points of damage (see below on -the explanation of the fight mechanic). Then retreat by typing `b'. -He'll take your amulet and retreat. Follow him. Now smite him until -you deal him 25 points of damage and finish him off by shooting. At -this point you will most likely have so many injuries you won't be -able to do anything, which is why we brought the potion. Drink it to -restore your health. There'll be some treasures lying around. We just -want to take the amulet, the talisman and throw the rope up to -escape. Once on the surface (you'll need to climb there with command -`u') use amulet -- that'll teleport you outside of the canyon. - -7. Finally return to the nymph and give her the amulet and the -talisman. Follow some further instructions. - - -COMBAT - -I already touched the space-combat briefly and there is not much more -to explain. Ground-combat is a bit stranger. There are three types of -enemies: woodsmen, elves and Darth Vader. All that should be known -about the first two is that carrying a laser and typing `shoot' puts -a swift end to the affair. The dark lord is more complicated than -that. - -There are several things to keep in mind when a fight starts: the -type of enemy, his strength, your tiredness, your injuries, the sort -of weapon carried, wearing one or several of the medallion, the -amulet and the talisman, and wearing mail and helmet and carrying -the shield. - -There are several things that can be done on each turn: smiting, -shooting going back and managing inventory. I advise to go into -fights with the inventory already managed. - -The enemy's strength determines two things: how many times will he -have to be smitten before he dies and how many times will he have to -be smitten before he may be killed through shooting instead of having -your laser deflected and destroyed. It is, essentially "health -points" and they are opposed to the value of lifeline, which -indicates how many "damage points" has the enemy suffered. The dark -lord starts with 100 strength the first time and 75 the second time. - -With each round of the fight you become more tired. If you are -sufficiently tired, the enemy simply kills you. - -injuries is an array of 13, that determines what parts of your body -are injured and how much. Each turn a number between 0 and 12 is -generated in order to determine which part of your body the enemy -will try to injure. The following items each reduce that number by -1: helmet (worn), mail (worn) and shield (held). Similarly for -each of the amulet, the medallion and the talisman being worn the -number is increased by 1. Should the number be less than 0 it becomes -0, equally it won't exceed 12. The injuries 10, 11 and 12 are -particularly important: they correspond to the deep incisions, -fractured skull and broken neck. Should these three injuries happen -at the same time you'll die, which is why it is so important to wear -at least some protective gear, which can make one or several of these -injuries impossible. - -Aside from the laser there are three kinds of weapons in this game -the first is the two-handed sword, the second is the normal sword and -the broadsword, the third is everything else. The two-handed sword is -the most damaging, however it is impossible to carry almost anything -else together with it (laser, importantly), so I am avoiding it. A -sword is lying not far from Darth Vader together with mail and a helmet, -so we'll use that. - -The damage dealt is calculated slightly differently depending on the -type of weapon. For sword it is: - - rnd(50) % (WEIGHT - carrying) - card(injuries, NUMOFINJURIES) - - encumber - exhaustion. - -It's mostly self-explanatory. Depending on how much damage was dealt -one of the following messages will be displayed: - -0: - You swung wide and missed. - He checked your blow. CLASH! CLANG! - His filthy tunic hangs by one less thread. -1: - He's bleeding. - A trickle of blood runs down his face. - A huge purple bruise is forming on the side of his face. -5: - He staggers back quavering. - He jumps back with his hand over the wound. - His shirt falls open with a swath across the chest. -10: - A bloody gash opens up on his left side. - A bloody gash opens up on his right side. - The steel bites home and scrapes along his ribs. - You pierce him, and his breath hisses through clenched teeth. -20: - You smite him to the ground. - The force of your blow sends him to his knees. - Clutching his blood-drenched shirt, he collapses, stunned. -30: - His ribs crack under your powerful swing, flooding his ... -55: - You shatter his upheld arm in a spray of blood. The blade ... - With a mighty lunge the steel slides in, and gasping, he ... - -Shooting the enemy will instantly kill him if his strength minus the -damage you've dealt already is less than or equal to 50. Otherwise -he will deflect and destroy your laser. - -Going back is quite interesting. Normally it prints how far you've -got in the fight and you retreat back. Of course, the next time the -fight starts none of the displayed stats will matter. It is, however, -necessary to retreat during the first fight with Darth Vader. If -you've managed to deal him 34 (or maybe 33 since it involves -floating-point arithmetic) points of damage, while wearing or -carrying the amulet and try to go back he will either: - -1. Trigger a game-over in case you also have the medallion on you. -2. Fracture your skull and retreat with your amulet. Afterwards you -can follow him, which is the only way to get into the room with the -talisman. - -Hopefully that explains the combat system. - - -FINAL BUG/FEATURE - -Now one would think that this plan I've outlined of defeating the -dark lord and saving the day would be some sort of a guarantee. Well, -no, it still relies quite heavily on random numbers being in the -player's favour. I have, however, found a -bug- feature thanks to -which completing this game doesn't even require a laser, or a -two-handed sword. You see, you've got to follow the dark lord after -he cowardly retreats and then fall back yourself. The author seems -to have "forgotten" (actually he's probably just left cheats for -himself!) to account for that final fight in the fight() function. -The logic there depends somewhat on your previous position, so there -are two ways it may go: either you and all the items remain in the -same room, or you, the amulet and the talisman are transported -somewhere else. Either way, all that remains to do is to navigate to -the nymph. - - -OTHER TIPS - -While flying, it is easy to return back to the original location on -the island by simply following a `u' with a `d'. It is, however, -somewhat dangerous at night, as yet another cylon will be spawned -just above the planet. - -After you return to the goddess, collect the medallion and go to -another room. You will become a wizard! (If you still have the other -two on you.) This gives you the ability to type the magic word `su' -and to fly without an aeroplane. - - -ENDING - -So, I realise not all people consider such feats of exploration worth -their time, therefore I finally leave the game's ending here. - ->-: give amulet to goddess -amulet: -Given. ->-: give talisman to goddess -talisman: -Given. ->-: give medallion to goddess -medallion: -Given. -The powers of the earth are now legitimate. You have destroyed the Darkness -and restored the goddess to her throne. The entire island celebrates with -dancing and spring feasts. As a measure of her gratitude, the goddess weds you -in the late summer and crowns you Prince Liverwort, Lord of Fungus. - -But, as the year wears on and autumn comes along, you become restless and -yearn for adventure. The goddess, too, realises that the marriage can't last. -She becomes bored and takes several more natives as husbands. One evening, -after having been out drinking with the girls, she kicks the throne particularly -hard and wakes you up. (If you want to win this game, you're going to have to -shoot her!) ->-: shoot goddess -The blast catches the goddess in the stomach, knocking her to the ground. -She writhes in the dirt as the agony of death taunts her. -She has stopped moving. - -You win! - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + bb25755e08aec6ecbe3a13f95667e04c4a8ff577 (mode 644) --- /dev/null +++ art/000.battlestar.txt @@ -0,0 +1,438 @@ +battlestar(6) is an game written by "His Lordship, Admiral David W. +Horatio Riggle." It is an adventure game not unlike adventure(6) +(yes, that's a pun). His Lordship claims it to be less of a puzzle +and more of an exploration-game. Apparently he wrote it to learn C +better (the game was written in 1979, however, so we are still +talking about pre-ANSI C with its weird function declarations and the +like). It also has some interesting verbs like "fuck" (unfortunately +performing that on corpses and general population does not lead to +results all that interesting). But that's not all! battlestar(6) is +not "just" an adventure game: It also has what I can only describe as +"action segments!" + +All that sounds pretty neat. Considering that adventure(6) has a small +collective that managed through a lot of research and collaboration +find every one of the game's secrets, so should battlestar(6)... +Except it doesn't! The game is actually worse at teaching the player +how to play than adventure(6) is, and there don't appear to be any +walkthroughs on the internets. The only way I managed to complete the +game was by consulting the source code. So, for the first time ever +I am writing a walkthrough. + +For a bit of clarification: I started playing battlestar(6) on Void +Linux and consulted the same sources as the ones from which the games +are compiled on Void (which, I think, are *not* Debian's and are +written in bronze-age (pre-ANSI) C (but I might be mis-remembering)). +Later my life returned to normal somewhat and I continued playing on +OpenBSD. For that purpose I downloaded the source tree via CVS and +observed that the games have been rewritten somewhat, mostly +stylistically, however: adventure(6)'s main.c still is written in the +kind of style that used to infuriate Dijkstra etc. + +Oh, but what even is a battlestar? Well, I was wondering that as +well. Apparently at about the same time (1978) there used to exist +one of those very cheap, uninspired and horribly dull American +television-space-shows called "battlestar Galactica". By "battlestar" +the authors, of course, meant a sort of space-carrier-ship because +the meaning is so "obvious". The premise of the series, as far as +there is one, is that a very advanced human civilisation lives on +some far-away planets, waging war against some robots called +"cylons", whose dearest wish it seems to be to murder every man alive +for no reason at all. Of course, the character I shall refer to as +"Judas Iscariot" assists the robots in doing so on the condition that +they spare his home-planet Guatemala (not what they called it, but I +have bad memory for things that are somehow nonsensical, yet +uninspired) and install him as its president. Genocide is something a +lot of very resourceful people have failed to achieve on a lesser +scale after decades of constant work, yet the robots desecrate 99% of +human population in just a few hours. The other 1% is divided in +half: 0.5% is left to starve to death, while the lucky few fly in the +general direction of the earth, where we, their very primitive +brethren live. Naturally, the robots at first try to execute Judas +Iscariot after killing every single other Guatemalan, but then decide +to instead put him in command of an entire fleet with the sole +purpose of pursuing these space-gypsies. It's much more boring than +it sounds like. + +And what does any of it has to do with the game? Well, not much. The +player starts on a "battlestar" that features smaller spacecrafts +called "vipers", and then goes into space where there are a bunch of +"cylons" to kill, but that's about it. + + +WALKTHROUGH + +So, first thing to do is to open the file words.c in the source code +and find all the VERBS. Now actually start the game. + +The game starts at a LUXURIOUS STATEROOM. We check our inventory and +see the following: + + >-: i + You aren't carrying anything. + + You are wearing: + + pajamas + + You are in perfect health. + >-: + +(Some time after my first session I noticed that the prompt looks a +bit like a sad face.) + +Oh, and, yes, we'll be completing most of the game in a pyjama, so I +suggest making an alias like `alias hitchhiker=battlestar'. + +If we go back we will discover some royal robes, which we can +put on instead, however they don't appear to have any effect +whatsoever (no, really, "grep 'ROBE|PIJAMA' *.c" yourself), so +instead we shall go right. + +From the EXECUTIVE SUITES we can go in all six directions. + +Ahead is the MAID'S UTILITY ROOM. Unfortunately, the maid has +accidentally stabbed herself to the death with a knife! We take the +knife, leaving the body for the police, and go back. + +To the right is the PRESIDENTIAL SUITE. It has a laser pistol just +lying on the floor, so we take that. If we go ahead we can discover +that the president too has accidentally shot himself to death, so +instead we go back. + +Down at the FIRST CLASS LOUNGE we discover some rubble and matches. +There is not much to see at the back, so we go up. + +We could go up to get another knife and a cleaver, but we already +have a knife! So instead we go ahead to the bridal suite. + +In the BRIDAL SUITE we put on a strange amulet that we found lying on +the floor and go down. + +In the HALLWAY there area a bunch of coins, which we take and go +right and ahead. + +From the MAIN HANGAR we can go left, up or right. + +The only thing of interest on the left is a nuclear warhead. +Unfortunately, all possible interactions with it may or may not +result in the player's death, so we won't be going left. + +Up and right actually lead to the same locations. We go right twice. +There are two guards "guarding" something called "Viper," but they +don't seem to mind us launching too much. + +At this point the game prints a very helpful message: + + >-: launch + You climb into the viper and prepare for launch. + With a touch of your thumb the turbo engines ignite, thrusting you back into + your seat. + + You are in space. + + + >-: + +So, what is "space" exactly? Well... + + ... + /* 32 */ + {"You are in space.", + {33, 34, 35, 36, 37, 1, 33, 1}, + "****\n", {0} }, + /* 33 */ + {"You are in space.", + {38, 32, 39, 40, 41, 1, 42, 1}, + "****\n", {0} }, + /* 34 */ + {"You are in space.", + {32, 44, 45, 46, 47, 1, 48, 1}, + "****\n", {0} }, + /* 35 */ + {"You are in space.", + {40, 45, 49, 32, 50, 1, 51, 1}, + "****\n", {0} }, + ... + +This is all part of a struct room (two of them technically), which is +defined in extern.h: + + struct room { + const char *name; + int link[8]; + #define north link[0] + #define south link[1] + #define east link[2] + #define west link[3] + #define up link[4] + #define access link[5] + #define down link[6] + #define flyhere link[7] + const char *desc; + unsigned int objects[NUMOFWORDS]; + }; + +So, right off, flyhere and access are useless when trying to draw +some sort of a map. Miraculously there are north, south, east and +west in space, but we are yet to invent a space-proof compass. But +first of all: which point of space are we even in? Well... + + $ grep ^launch\( * + command6.c:launch() + $ less command6.c + ... + +Oh, but of course, we are at location[position].up! Also known as 32. +So, knowing that rooms 32-66 are all space, it appears that other +options include: 67 and 68, corresponding to the orbits of a small +blue planet and a tropical planet. The first leads to 69, and while +it is, as the user of an internet forum would put it, "nice," I +wouldn't go somewhere described as: + + ... + {69, 69, 69, 69, 69, 1, 69, 1}, + ... + +So instead we'll try to navigate to the tropical planet. This, +thankfully is much more straightforward than the labyrinths of +adventure(6) our path is 32-34-44-64-66-68, or s-s-s-s-s-s -- +basically, we just need to find that mysterious "space south." +Throughout these space rooms there are also some objects called +CYLON, being in one cell with a CYLON triggers the function visual(), +which produces a visual fight with the alien. I know that on this +path the only CYLON is in the room 64, which we can use to determine +which direction is south (it's right because by typing `r' once and +`a' twice I arrive at a CYLON). + +So, how about defeating the CYLON? Well, turns out that this is a +curses game as well (of course it is!), and I don't really know how +to use curses. Anyway, before starting the fight, I'd make sure that +the terminal being fought on is 80x24, because that will make things +much simpler. Right, I don't think I can put off reading fly.c any +more because the in-game prompts are most unhelpful. + +So, the first thing to do is to press plus (`+'). This will draw a +target in the middle of the screen. Our objective is to bring the +enemy (looks like `/-\') there and press `f' or space to fire. Of +course we can't move the enemy, but we can move ourselves by pressing +h/r, l, j/u and k/d along with their capitalised versions for greater +effect. This is the hardest part of the game! + +Save once the game says "You are orbiting a tropical planet." Go +down, approaching an island. This is the main part of the game. + +At this point you are free to explore the island, which is the main +part of the game. Completing it is very tricky, however. A sequence +that seems to work: + +1. Firstly, it is very important to find the goddess. If not found, +she will disappear after the first day. Once the goddess is found you +need to kiss her, follow her, kiss her a few more times and finally +love her. She will drop a medallion. DON'T take it (now at least). + +2. Find a woman who'll tell you that she wants to meet you in the +gardens at midnight. Once there and then, accept a rope from her. + +3. Otherwise explore the island. You should at least find the potion +before the rendezvous. + +4. Quickly go to the catacombs. They are only open at night, so there +is no time to lose. + +5. There are mainly three points of interest here: the sepulchre, the +room with the dark lord (a.k.a. darth vader) and a storage room. The +latter contains a grenade, which is quite honestly not that +interesting of an item. The sepulchre is more interesting: it +contains a mail shirt, an armoured helmet and a sword. It is vital to +go into the final fight wearing (not carrying) mail, the helmet, the +rope and carrying (not wearing) the sword, the laser, the potion +and the amulet. + +6. In the last room before Darth Vader make sure to sleep and eat if +carrying food and a knife. Enter with the aforementioned items and +smite the enemy until you deal him 34 points of damage (see below on +the explanation of the fight mechanic). Then retreat by typing `b'. +He'll take your amulet and retreat. Follow him. Now smite him until +you deal him 25 points of damage and finish him off by shooting. At +this point you will most likely have so many injuries you won't be +able to do anything, which is why we brought the potion. Drink it to +restore your health. There'll be some treasures lying around. We just +want to take the amulet, the talisman and throw the rope up to +escape. Once on the surface (you'll need to climb there with command +`u') use amulet -- that'll teleport you outside of the canyon. + +7. Finally return to the nymph and give her the amulet and the +talisman. Follow some further instructions. + + +COMBAT + +I already touched the space-combat briefly and there is not much more +to explain. Ground-combat is a bit stranger. There are three types of +enemies: woodsmen, elves and Darth Vader. All that should be known +about the first two is that carrying a laser and typing `shoot' puts +a swift end to the affair. The dark lord is more complicated than +that. + +There are several things to keep in mind when a fight starts: the +type of enemy, his strength, your tiredness, your injuries, the sort +of weapon carried, wearing one or several of the medallion, the +amulet and the talisman, and wearing mail and helmet and carrying +the shield. + +There are several things that can be done on each turn: smiting, +shooting going back and managing inventory. I advise to go into +fights with the inventory already managed. + +The enemy's strength determines two things: how many times will he +have to be smitten before he dies and how many times will he have to +be smitten before he may be killed through shooting instead of having +your laser deflected and destroyed. It is, essentially "health +points" and they are opposed to the value of lifeline, which +indicates how many "damage points" has the enemy suffered. The dark +lord starts with 100 strength the first time and 75 the second time. + +With each round of the fight you become more tired. If you are +sufficiently tired, the enemy simply kills you. + +injuries is an array of 13, that determines what parts of your body +are injured and how much. Each turn a number between 0 and 12 is +generated in order to determine which part of your body the enemy +will try to injure. The following items each reduce that number by +1: helmet (worn), mail (worn) and shield (held). Similarly for +each of the amulet, the medallion and the talisman being worn the +number is increased by 1. Should the number be less than 0 it becomes +0, equally it won't exceed 12. The injuries 10, 11 and 12 are +particularly important: they correspond to the deep incisions, +fractured skull and broken neck. Should these three injuries happen +at the same time you'll die, which is why it is so important to wear +at least some protective gear, which can make one or several of these +injuries impossible. + +Aside from the laser there are three kinds of weapons in this game +the first is the two-handed sword, the second is the normal sword and +the broadsword, the third is everything else. The two-handed sword is +the most damaging, however it is impossible to carry almost anything +else together with it (laser, importantly), so I am avoiding it. A +sword is lying not far from Darth Vader together with mail and a helmet, +so we'll use that. + +The damage dealt is calculated slightly differently depending on the +type of weapon. For sword it is: + + rnd(50) % (WEIGHT - carrying) - card(injuries, NUMOFINJURIES) + - encumber - exhaustion. + +It's mostly self-explanatory. Depending on how much damage was dealt +one of the following messages will be displayed: + +0: + You swung wide and missed. + He checked your blow. CLASH! CLANG! + His filthy tunic hangs by one less thread. +1: + He's bleeding. + A trickle of blood runs down his face. + A huge purple bruise is forming on the side of his face. +5: + He staggers back quavering. + He jumps back with his hand over the wound. + His shirt falls open with a swath across the chest. +10: + A bloody gash opens up on his left side. + A bloody gash opens up on his right side. + The steel bites home and scrapes along his ribs. + You pierce him, and his breath hisses through clenched teeth. +20: + You smite him to the ground. + The force of your blow sends him to his knees. + Clutching his blood-drenched shirt, he collapses, stunned. +30: + His ribs crack under your powerful swing, flooding his ... +55: + You shatter his upheld arm in a spray of blood. The blade ... + With a mighty lunge the steel slides in, and gasping, he ... + +Shooting the enemy will instantly kill him if his strength minus the +damage you've dealt already is less than or equal to 50. Otherwise +he will deflect and destroy your laser. + +Going back is quite interesting. Normally it prints how far you've +got in the fight and you retreat back. Of course, the next time the +fight starts none of the displayed stats will matter. It is, however, +necessary to retreat during the first fight with Darth Vader. If +you've managed to deal him 34 (or maybe 33 since it involves +floating-point arithmetic) points of damage, while wearing or +carrying the amulet and try to go back he will either: + +1. Trigger a game-over in case you also have the medallion on you. +2. Fracture your skull and retreat with your amulet. Afterwards you +can follow him, which is the only way to get into the room with the +talisman. + +Hopefully that explains the combat system. + + +FINAL BUG/FEATURE + +Now one would think that this plan I've outlined of defeating the +dark lord and saving the day would be some sort of a guarantee. Well, +no, it still relies quite heavily on random numbers being in the +player's favour. I have, however, found a -bug- feature thanks to +which completing this game doesn't even require a laser, or a +two-handed sword. You see, you've got to follow the dark lord after +he cowardly retreats and then fall back yourself. The author seems +to have "forgotten" (actually he's probably just left cheats for +himself!) to account for that final fight in the fight() function. +The logic there depends somewhat on your previous position, so there +are two ways it may go: either you and all the items remain in the +same room, or you, the amulet and the talisman are transported +somewhere else. Either way, all that remains to do is to navigate to +the nymph. + + +OTHER TIPS + +While flying, it is easy to return back to the original location on +the island by simply following a `u' with a `d'. It is, however, +somewhat dangerous at night, as yet another cylon will be spawned +just above the planet. + +After you return to the goddess, collect the medallion and go to +another room. You will become a wizard! (If you still have the other +two on you.) This gives you the ability to type the magic word `su' +and to fly without an aeroplane. + + +ENDING + +So, I realise not all people consider such feats of exploration worth +their time, therefore I finally leave the game's ending here. + +>-: give amulet to goddess +amulet: +Given. +>-: give talisman to goddess +talisman: +Given. +>-: give medallion to goddess +medallion: +Given. +The powers of the earth are now legitimate. You have destroyed the Darkness +and restored the goddess to her throne. The entire island celebrates with +dancing and spring feasts. As a measure of her gratitude, the goddess weds you +in the late summer and crowns you Prince Liverwort, Lord of Fungus. + +But, as the year wears on and autumn comes along, you become restless and +yearn for adventure. The goddess, too, realises that the marriage can't last. +She becomes bored and takes several more natives as husbands. One evening, +after having been out drinking with the girls, she kicks the throne particularly +hard and wakes you up. (If you want to win this game, you're going to have to +shoot her!) +>-: shoot goddess +The blast catches the goddess in the stomach, knocking her to the ground. +She writhes in the dirt as the agony of death taunts her. +She has stopped moving. + +You win! blob - 54f36a830e1337a2003572fdfc7a7c408dc8bfc7 (mode 644) blob + /dev/null --- art/comppractice.txt +++ /dev/null @@ -1,394 +0,0 @@ -A very sad thing about modern man is that computers are ubiquitous to -everyone's life, yet there are very few people (even among -programmers!), who have any idea how to use them. This text will -contain a quick overview of several topics on the practice of -computing from "how to set up your shell" and "how to get -documentation" to "how to write better programs". Most of such -subjects, of course, require much more than a quick overview, so -when possible I'll try to describe how to get proper introduction -and reference manual to each subject. - - -FILE HIERARCHIES - -This document focuses on maintaining good file hierarchies under -Unices, and so many consequent presumptions and opinions are taken. - -File hierarchies are hard. What makes it worse is that we've all been -damaged from childhood with all those graphical file-managing tools -that are both slower than the command line and promote some very bad -habits. Natural consequences of such damage are even getting -standardised: there are a lot of programs that create weirdly-named -dirs like ~/Downloads and ~/Documents, and there is the XDG base dir -specification. It is my opinion that file hierarchies should -facilitate three things primarily: - -1. It should be easy to navigate to the file by typing its name. -2. It should be easy to manipulate files via scripts. -3. It should be easy to perform similar operations on a group of -closely-related files, e.g. with only one or two commands all my -configs for $program should be able to be archived, copied, change -permissions and ownership etc. - -Generally I assume that the user is not an idiot and knows where -most of his files are and can find the rest with find(1) or locate(1) -or something. - -Firstly if you are reading this document, you probably aren't a -secretary, are you? Well, don't name your files like one! Use only -[A-Za-z0-9_.-]. Avoid minuses (dashes/whatever) as the first -character (or at all, really): they cause all sorts of problems like -"rm -i *" becoming "rm -i -f file1 file2", and there seems to be a -correlation between people who put a lot of dashes in their names and -the ones that end up unwieldily-named files. Minuses are OK for -semantic purposes, however, such as naming files after dates -("2013-05-05.photo.jpg" (though depending on how it will be used it -might be fine to name it "20130505.photo.jpg")), or versioning them -("prog-0.4.tar"). If you use them for separating "fields" in -filenames, consider using periods instead. There are also some -characters, which are not mandated by posix, but which are still -commonly used by some programs: comma (,) and colon (:) are used in -maildirs, I believe some GNU utilities like tilde (~), I think -systemd uses at (@), Linux's filesystems like pluses (+) for special -files/dirs and test(1) can often be invoked as `['. I'd advise -against using those for normal files, however. Be conservative with -numbers and underscores and only capitalise letters with VERY -IMPROTANT files that should be sorted first like README, Makefile, -CHANGES, INSTALL etc. That is not to name directories in your ~ so: -they already are sorted because the "unimportant" files have a period -as the first character. - -Naturally, keep the names short. Of course if you have some, e.g., -photo saved on your disc, but you only open it once a decade, it's -fine to give it a longer, more descriptive name like -"1998.tortoise_on_red_sea_beach.png" (do tortoises live on the Red -sea?). On the other hand if you have a copy of "the brave soldier -Schweik" on the disc, there is no need to name it -"the_fateful_adventures_of_the_brave_soldier_schweik_during_the_world_war_by_jaroslav_hashek.pdf" -that doesn't even fit the line! Instead, Name it "schweik.pdf" and be -done with it. - -Also, unless you are serving these files with a web-server or -something, avoid putting the `.txt' suffix there like some people -like to do. When one sees a file without a suffix (eh, extension) one -should ask the operating system: is this file executable? If it -isn't, well, it's probably plain text isn't it? These extra 4 bytes -at the end are superfluous, annoying and don't impress anyone. - -Another thing is don't spread your files around. The reason there is -a separation between /etc/ and /usr/share/ is because people are -unlikely to copy the latter between hosts. On the other hand if you -install a, say, dictionary program, download some custom dictionaries -for it and decide that you want this program somewhere else, well, -you'll want to copy both your configs and the extra data files you've -downloaded. And now with the XDG directory specification this -operation no more as simple as `scp -r ~/.dict user@host:'! So, thank -you, XDG! - -There are a several of reasons for separating closely-related files -into several directories: - -1. It may help avoid naming collisions. For example, if I were to -make a note-taking program, I'd store all the notes in their own -directory and all the helper files in the directory above. - -2. There may be other technical reasons. For the same program may -load different configs depending on a directory. git(1) is one -example of that. - -3. You *actually* only want to have a subset of files visible at a -time. For instance, it may be good idea to keep old mail, however, -in the vast majority of cases one is only interested in the very -recent mail, so there is no need to load one's mailing program and -own brain with the old stuff, except when explicitly asked. One -solution is to move each prior year's mail into its own directory, -and only keep the current year's mail in the actual inbox. - -Another thing people seem to like to do that is even worse than -creating those weird single-file directories is creating unreasonably -short files. I see this manifested primarily in two ways: - -1. People decide that foo.conf is not enough somehow and instead -create foo.conf.d/ putting dozens of single-line files there. - -2. There is this "style" of programming where people create separate -files for each function. - -Now, firstly this sort of behaviour is very rude to your disc: I am -yet to encounter one with 20-byte-long sectors. Secondly, the only -purpose it serves is creating more busywork. Beforehand I had -everything I needed in the place where it logically should reside. -Now I have to jump from file to file just to figure out the meaning -of a single line. This, by the way, also relates to programming in -general. - -Another issue is symlinks. Don't use them, unless there is some -strong reason to do so. There are several kinds of symlinks: those -between directories, which mostly just cause confusion. Those between -files on different filesystems, which don't even always work. And -there are symlinks between normal files on the same filesystem. These -should be hardlinks. The only "benefit" there is to be had from using -symlinks instead lies in confusing some poor program once the actual -file has been deleted, and the symlink it depended upon is no longer -pointing to some useful location. - - -For some more particular advice, here are directories in my ~: - - bin/ games/ lit/ mail/ misc/ src/ sync/ tmp/ vid/ - -~/bin/ is part of my PATH. This is where I put all my "permanent" -scripts. - -~/misc/ and ~/tmp/ are both for files of varying degree of -temporariness. The first is where I put files when I either don't -know where else to put them yet, know where to put them, but don't -want to do that just yet, or intend to remove them later, yet would -like to hold on to them for now. ~/tmp/ is more temporal than that, -yet less so than /tmp/. This is where downloaded files and -screenshots land initially. This is also where I conduct experiments -that for whatever reason cannot be conducted in /tmp/. - -The inner structure of ~/games/ is very much ad-hoc. You can guess -the rest. - -~/lit/ is composed entirely of pdf files as of right now. A bit -surprisingly, getting untranslated foreign fiction on some dead-tree -paper is much, much simpler in Moscow, than getting untranslated -technical literature, even though one would think the translations of -the latter would be mostly useless. An interesting thing about -technical literature is that it's mostly reasonably self-contained, -and so there are hardly any book series I keep in this directory. The -ones that are there are put into their own subdirectory and -structured like so: - - ~/lit/bookname/ - |-- bookname1.pdf - |-- bookname2.pdf - ... - `-- booknameN.pdf - -Most of them, however, don't get their own directories, of course. - -~/mail/ houses two kinds of maildirs: ones named -~/mail/{2021,2022,...}/ and ~/mail/in/. Stuff arrives into ~/mail/in/ -and moves on to a newly-created maildir once a year has passed. - -~/src/ is where I put the source code of various projects. Because I -commited to some projects using github, but I don't want the site to -expose my mail address, there is also the subdirectory ~/src/gh/, -which is pretty much the same, except that it has its own gitconfig. - -~/sync/ contains files I sync between my local machine and my server. -I might change the hierarchy there slightly if I start maintaining -more systems on a regular basis. The internal hierarchy mostly -corresponds to that of the server's root, though there are a lot of -extra files in ~/sync/ itself like plan, profile, kshrc, sync.sh etc. -Hopefully the names are revealing enough. - -~/vid/ contains Monty Python mostly. Somewhat similar in structure to -~/lit/, excepting that there are more subdirectories. - - -PROGRAMMING - -There are already a lot of good stylistic references for C (and -probably for other languages, but we'll stick with C here). Good ones -in particular are OpenBSD's style(9) (google it on -http://man.openbsd.org) and the style employed by K&R in their book -"the C programming language". A lot of good advice is offered in -"the practice of programming" by Brian Kernighan and Rob Pike. Do -read those for a more complete overview of good style. Here I shall -instead go over some techniques that are critically underemployed -and some mistakes that - -I find it very helpful to compile with flags -`-std=c99 -Wall -Wextra -pedantic -O0 -g'. Of course, this is just -for the debugging purposes, for "real" compilation you'd probably -remove at least the `-O0 -g'. Other than that, I don't find linters -to be particularly helpful -- they misreport all but too often. For -instance, I used to employ LLVM's scan-build(1) until discovering -that it complains about such code: - - void - err(int eval, char *fmt, ...) - { - ... - exit(eval); - } - - void - somefunc(void) - { - char *ptr; - if (!(ptr = malloc(n))) - err(1, "bad malloc"); - *ptr = '\0'; - } - -but not with this modification of somefunc: - - void - somefunc(void) - { - char *ptr; - if (!(ptr = malloc(n))) { - err(1, "bad malloc"); - exit(1); - } - *ptr = '\0'; - } - -So, the moral is: compile with -std=c99 -Wall -Wextra -pedantic, fix -warnings, test thoroughly, fix bugs as soon as they are found, avoid -common missteps, and don't rely on external linters. - -Portable programs tend to not only cause much less pain, but to also -be better written in general, so try to stay within mainstream, only -using local extensions when necessary. Definitely do not rely on a -particular compiler's or standard library's quirk. - -In the vast majority of cases code alignment (except indentation) is -a huge waste of effort that doesn't even pay off, so I avoid that. - -When possible I position my functions starting on their own line like -so: - - int - foo(void) - ... - -this makes the code very easily grep(1)pable (grep ^foo\( *.c)). And -no need for ctags! Generally it is worth writing in a way that'll -make moving around simpler. - -Side effects should generally be avoided, except for some -well-understood idioms like *a++ = *b++. - -There are many programs whose portability depends upon preprocessor -instructions like #if and #ifdef. It is easily observed that even -in small number they can bring much confusion. Avoid such constructs -when at all possible. Even the debug macros are often not really -necessary. Compare the two: - - #define DEBUG - - #ifdef DEBUG - printf("this is a debug statement\n"); - #endif /* DEBUG */ - -and - - enum = { DEBUG = 1 }; - - if (DEBUG) - printf("this is a debug statement\n"); - -If we set DEBUG to 0 in the second case, the compiler will optimise -the statement away in any case, but it'll warn us if we mess up the -actual debug code. - -Comments are often used in silly ways. In fact some people even have -their editors configured to make the comments dimmer. In fact they -should have them configured to make comments brighter and/or bolder. -Comments are very powerful and should therefore be used with much -discretion. Good comments include the ones that go briefly over -functions and global data, and the ones which help the reader to -understand a complicated algorithm used in code. They should -definitely not, state the obvious, or be seen as a compensation for -bad code, which should be rewritten instead. Such comments have a -tendency of eventually contradicting the code, which is the great -danger of comments. - -There are many examples of not just bad, but moronic comments: - - /******************************************************* - * * - * * - * MY HELLO WORLD ROUTINE * - * * - * * - *******************************************************/ - - do_stuff() //!!! - - /**** Maybe I should draw more asterisks... ****/ - -Don't laugh, I actually get paid for working with these! - -And another thing is to definitely not just leave code commented out, -at least not after debugging. Though if you do write a debugging -function, leave it there, for you might need it in the future. - -There are a lot of reasons to divide programs into multiple files. Do -create as many as are needed, especially for portability, and when -compilation becomes too long. Do not, however put things into new files -just for the sake of it. Many programmers seem to think that if they put -every single function into its own file it'll somehow make things -better. In fact it only makes their code a navigational nightmare. - -Speaking of multiple files, don't include files in your included files. -There is, of course a "protection" often employ to avoid cycles: - - #ifndef THISFILE_H - #define THISFILE_H - #include "a.h" - #include "b.h" - /* file contents... */ - #endif /* THISFILE_H */ - -which does not, however, protect your preprocessor from processing -this rubbish over and over again, ensuring the program doesn't -actually finish compiling for a stupid multiplied by long amount of -time. Instead simply comment what files should be included before that -one and let the actual includer worry about what to include: - - /* - * Description of what the file is for. - * - * #include "a.h" - * #include "b.h" - * #include "thisfile.h" - */ - -A thing that I, thankfully, see more rarely, but still do sometimes -is variables getting burdened with as many qualifiers as the -programmer managed to come up with. In truth, there should be as -*few* qualifiers as possible. In particular many people seem to make -variables unsigned for no reason other than that they should never be -negative. That not only encourages integer overflow errors, but can -make the code much more complicated. Observe, for instance, this -piece of code, which calculates the column, corresponding to nth -character in some line: - - ... - for (off = 0, col = -1; off <= n; off++) - if (s[off] == '\t') - col = ((col+1)/8 + 1) * 8 - 1; - else if (isprint(s[off])) - col++; - ... - -col here should never end up negative, however it is still useful to -assign it to -1 initially to simplify the program, and possibly to -indicate an error. - -For the last I'll leave you with this bit of bad code that I've seen -too often: - - if (bad) - return 0; - else { - /* The rest of the function's code here. */ - } - -If you do that people will laugh at you. Instead write normally: - - if (bad) - return 0; - - /* The rest of the function's code here. */ - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + e9f714457dfee677f993c50c08bf6c1084d99d07 (mode 644) --- /dev/null +++ art/001.practice_of_computing.txt @@ -0,0 +1,284 @@ +In this small text I discuss the choice of software, file +hierarchies, and programming style. I find that these two topics are +among the ones where our various educators (themselves influenced by +similar misdesign and misdirection) cripple us the most, perhaps +never even explicitly, or intentionally. + + +SOFTWARE CHOICE + +In the year of 2023 people shouldn't have to use proprietary operating +systems, or any other proprietary software. The few cases where the +use of proprietary software is justified that I can think of are: + +- You are trying to reverse-engineer something. +- You are being forced to -- that usually occurs when some "boss-man" + tries to get everyone to some lowest common denominator. If you are + reading this, you are probably better than that, and may wish to + leave this organisation (or whatever it is) soon. +- You are forced to use weird hardware that requires weird software. + This one really sucks because it often has to do with international + politics, and lacks a common-sense solution. + +In the latter two situation you can often get somewhat around the +restriction by running the untrusted-proprietary bits in a virtual +machine. + +Even if you can't use a VM for everything, there's usually still +nothing stopping you from running mostly-free software on your +hardware. When I first started using free software, I used to play +a lot of computer games, and had to run Micro$oft's office software +(bloody university didn't accept my LaTeX reports!). I kept the +latter mostrosity on a VM, and played to my heart's content using +wine. + +Later, I stopped using the office because I graduated, and I stopped +playing games because I found them so terribly boring compared to all +the things that I could do now. + + +FILE HIERARCHIES + +This document focuses on maintaining good file hierarchies under +Unices, and so many consequent presumptions and opinions are taken. + +File hierarchies are hard. What makes it worse is that we've all been +damaged from childhood with all those graphical file-managing tools +that are both slower than the command line and promote some very bad +habits. Natural consequences of such damage are even getting +standardised: there are a lot of programs that create weirdly-named +dirs like ~/Downloads and ~/Documents, and there is the XDG base dir +specification. It is my opinion that file hierarchies should +facilitate three things primarily: + +1. It should be easy to navigate to the file by typing its name. +2. It should be easy to manipulate files via scripts. +3. It should be easy to perform similar operations on a group of + closely-related files, e.g. with only one or two commands all my + configs for $program should be able to get archived, be copied, + change permissions and ownership, etc. + +Generally I assume that the user knows where most of his (important) +files are and can find the rest with find(1) or locate(1) or +something. + +Firstly, please limit your file names to [A-Za-z0-9_.-]. Avoid +minuses (dashes/whatever) as the first character (or at all, +really): they cause all sorts of problems like "rm -i *" becoming +"rm -i -f file1 file2". Minuses are OK for semantic purposes, +however, such as naming files after dates ("2013-05-05.photo.jpg" +(though depending on how it will be used it might be fine to name it +"20130505.photo.jpg")), or versioning them ("prog-0.4.tar"). If you +use them for separating "fields" in filenames, consider using periods +instead. There are also some characters, which are not mandated by +POSIX, but which are still commonly used by some programs: comma (,) +and colon (:) are used in maildirs, I believe some GNU utilities like +tilde (~), I think systemd uses at (@), and there's lost+found on +many (most?) Unix filesystems, and test(1) can often be invoked as +`[', or more specifically, `/bin/['. I'd advise against using those +for normal files, however. Be conservative with numbers and +underscores and only capitalise letters with VERY IMPROTANT files +that should be sorted first like README, Makefile, CHANGES, INSTALL +etc. That is not to name directories in your ~ so: they already are +sorted because the "unimportant" files have a period as the first +character. + +Naturally, keep the names short. Of course if you have some, e.g., +photo saved on your disc, but you only open it once a decade, it's +fine to give it a longer, more descriptive name like +"1998.tortoise_on_red_sea_beach.png" (do tortoises live on the Red +sea?). On the other hand if you have a copy of "the brave soldier +Schweik" on the disc, there is no need to name it +"the_fateful_adventures_of_the_brave_soldier_schweik_during_the_world_war_by_jaroslav_hashek.pdf" +that doesn't even fit the line! Instead, Name it "schweik.pdf" and be +done with it. + +Also, people coming from the Micro Soft-Disasterous Operating System +(MS-DOS) and its successors tend to name files like `foo.txt' rather +than just `foo'. On Unix this is usually unnecessary, except for web +servers and similar, which can quickly evaluate content-type based on +the filename, rather than magic numbers. + +Another thing to avoid is not to create too many separate +files/directories just for the purpose of doing so. In particular, I +sometimes see the following: + +- People abuse the directories like foo.conf.d/, by putting each small + $thing into a separate file, without any real logical reason to do so. +- People write programs, where each single function is its own file. + +I'd avoid symlinks: they are sometimes necessary between files, but +directory symlinks are evil. Just imagine how many files have been +wrongly `rm -rf'ed since the introduction of symlinks! + + +PROGRAMMING + +This advice mostly relates to C. I am very inconsistant with my +sh, awk and perl styles, and I don't have one for other programming +languages. + +There are already a lot of good stylistic references for C (and +probably for other languages, but we'll stick with C here). Good ones +in particular are OpenBSD's style(9) (google it on +http://man.openbsd.org) and the style employed by K&R in their book +"the C programming language". A lot of good advice is offered in +"the practice of programming" by Brian Kernighan and Rob Pike. Do +read those for a more complete overview of good style. Here I shall +instead go over some techniques that are critically underemployed +and some mistakes that + +I find it very helpful to compile with flags +`-std=c99 -Wall -Wextra -pedantic -O0 -g'. Of course, this is just +for the debugging purposes, for "real" compilation you'd probably +remove at least the `-O0 -g'. + +A common advice is to use linters. I use them *sometimes*. I often +ignore them, however, because they tend to misreport more than find +actual issues. + +Portable programs tend to not only cause much less pain, but to also +be better written in general, so try to stay within mainstream, only +using local extensions when necessary. Definitely do not rely on a +particular compiler's or standard library's quirk. + +In the vast majority of cases code alignment (except indentation) is +a huge waste of effort that doesn't even pay off, so I usually avoid +that. + +When possible I position my functions starting on their own line like +so: + + int + foo(void) + ... + +this makes the code very easily grep(1)pable (grep ^foo\( *.c)). And +no need for ctags! Generally it is worth writing in a way that'll +make moving around simpler. + +Side effects should generally be avoided, except for some +well-understood idioms like *a++ = *b++. + +There are many programs whose portability depends upon preprocessor +instructions like #if and #ifdef. It is easily observed that even +in small number they can bring much confusion. Avoid such constructs +when at all possible. Even the debug macros are often not really +necessary. Compare the two: + + #define DEBUG + + #ifdef DEBUG + printf("this is a debug statement\n"); + #endif /* DEBUG */ + +and + + enum = { DEBUG = 1 }; + + if (DEBUG) + printf("this is a debug statement\n"); + +If we set DEBUG to 0 in the second case, the compiler will optimise +the statement away, but it'll warn us if we mess up the actual debug +code. + +Comments are often used in silly ways. In fact some people even have +their editors configured to make the comments dimmer because so many +of them are useless. In fact they should have them configured to make +comments brighter and/or bolder. Comments are very powerful and +should therefore be used with much discretion. Good comments include +the ones that go briefly over functions and global data, and the ones +which help the reader to understand a complicated algorithm used in +code. They should definitely not state the obvious, or be seen as a +compensation for bad code, which should be rewritten instead. Such +comments have a tendency of eventually contradicting the code, which +is the great danger of comments. + +Here are examples of really bad comments that I've actually seen +(actual text changed): + + /******************************************************* + * * + * * + * MY HELLO WORLD ROUTINE * + * * + * * + *******************************************************/ + + do_stuff() //!!! + + /**** Maybe I should draw more asterisks... ****/ + +And another thing is to definitely not just leave code commented out, +at least not after debugging. Though if you do write a debugging +function, leave it there, for you might need it in the future. + +There are a lot of reasons to divide programs into multiple files. Do +create as many as are needed, especially for portability, and when +compilation becomes too long. Do not, however put things into new files +just for the sake of it. Many programmers seem to think that if they put +every single function into its own file it'll somehow make things +better. In fact it only makes their code a navigational nightmare. + +Speaking of multiple files, don't include files in your included files. +There is, of course a "protection" often employ to avoid cycles: + + #ifndef THISFILE_H + #define THISFILE_H + #include "a.h" + #include "b.h" + /* file contents... */ + #endif /* THISFILE_H */ + +which does not, however, protect your preprocessor from processing +it over and over again Instead simply comment what files should be +included before that one and let the actual includer worry about +what to include: + + /* + * Description of what the file is for. + * + * #include "a.h" + * #include "b.h" + * #include "thisfile.h" + */ + +A thing that I, thankfully, see more rarely, but still do sometimes +is variables getting burdened with as many qualifiers as the +programmer managed to come up with. In truth, there should be as +*few* qualifiers as possible. In particular many people seem to make +variables unsigned for no reason other than that they should never be +negative. That not only encourages integer overflow errors, but can +make the code much more complicated. Observe, for instance, this +piece of code, which calculates the column, corresponding to nth +character in some line: + + ... + for (off = 0, col = -1; off <= n; off++) + if (s[off] == '\t') + col = ((col+1)/8 + 1) * 8 - 1; + else if (isprint(s[off])) + col++; + ... + +col here should never end up negative, however it is still useful to +assign it to -1 initially to simplify the program, and possibly to +indicate an error. + +Lastly there's a construct I rarely see talked about: + + if (bad) + return 0; + else { + /* The rest of the function's code here. */ + } + +Are such constructs the reason why people insist on two (or one +ultrawide) monitors, and writing lines hundreds of columns wide? A +much better version is very simple: + + if (bad) + return 0; + + /* The rest of the function's code here. */ blob - 272750ae5d4a4f5f6e988c0b2e29fb46fff1c931 (mode 644) blob + /dev/null --- art/drive.txt +++ /dev/null @@ -1,429 +0,0 @@ -My new backup system - -Until recently my backups relied on connecting an HDD externally ever -so often. Very manual and quite dangerous. Lately, however, I thought -that since I am dealing with a hard drive this way, I might as well -just install it inside my PC and use it for good -- I have two (or -three even, if you count that second SSD I no longer use) SATA ports -just hanging there! - -Well, I was partly correct to fear slightly the months before: my -motherboard has been showing its age (especially after a small fire -a few centimetres away), and as I was trying to attach the drive, one -of the two ports fell off! To be more precise, the plastic did, and -the important part followed, but thankfully the other three seem to -hold on much better. - -Now, with 1 TB of extra space I went on with partly realising the -things I always wanted to do. - - -Initial setup - -I decided have one 500 GB general partition, and then see how large -the others may need to be. I did the normal OpenBSD disc setup -otherwise. - -# fdisk -iy sd2 -# disklabel -E sd2 -a -partition to add: a -offset: -size: 500g -FS type: 4.2BSD -q -# newfs sd2a -# sysctl hw.disknames -hw.disknames=sd0:,sd1:,sd2: -# echo .a /data ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab -# mkdir -p /data && mount -o rw,nodev,nosuid,softdep /dev/sd2a /data -# mkdir -p /data/aa && chown aa:aa /data/aa - - -CVS - -I already had reposync (though it was on /var/cvs instead of the -usual /cvs) set up, so I knew that 50 GB will be plenty: - -# disklabel -E sd2 -sd2> a -partition to add: b -offset: -size: 50g -FS type: 4.2BSD -sd2*> q -# newfs sd2b -# mkdir -p /cvs && mount -o rw,nodev,nosuid,softdep /dev/sd2b /cvs -# echo .b /packages ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab -# chown cvs:wsrc /cvs -# chmod g+w /cvs -# doas -u cvs crontab -e -(stop the reposync cronjob) -# rm /var/db/reposync/reposync.hash -# doas -u cvs crontab -e -... -~ */2 * * * reposync -q rsync://ftp.somemirror.tld/cvs - -This sets the OpenBSD cvs changes to be synced to /cvs at a random -minute of every second hour. Also I set CVSROOT to /cvs. - - -Packages - -First I estimated how much space do I need for everything: - -$ cd /data/aa -$ mkdir -p packages/snapshots/amd64 -$ rsync -aq --delete-delay --delete-updates \ - rsync://ftp.somemirror.tld/OpenBSD/snapshots/packages/amd64/ \ - packages/snapshots/amd64/ -$ du -hs packages - -Turns out, currently it's a little under 60 GB, so I set up a 150 GB -partition: - -# disklabel -E sd2 -sd2> a -partition to add: d -offset: -size: 150g -FS type: 4.2BSD -sd2*> q -# newfs sd2d -# mkdir -p /packages && mount -o rw,nodev,nosuid,softdep /dev/sd2d /packages -# echo .d /packages ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab -# useradd -s/sbin/nologin -d/var/empty packages -# chown packages:packages /packages -# doas -u packages mkdir -p /packages/snapshots/amd64 -# doas -u packages crontab -e -~ 0 * * * rsync -aq --delete-delay --delete-updates rsync://ftp.somemirror.tld/OpenBSD/snapshots/packages/amd64/ /packages/snapshots/amd64/ - -Sorry for the last line's length! - -I also ran this command once manually, and set my PKG_PATH to -/packages/snapshots/amd64. - - -Local backups - -I decided to manage my local backups with rsnapshot: - -# cp /etc/rsnapshot.conf /etc/rsnapshot.conf.default -# # I actually edited this in vi(1), of course. -# # Also, some parts of it was provided by default, but heavily commented. -# cat >/etc/rsnapshot.conf <<'x' -config_version 1.2 - -snapshot_root /data/snapshots/ - -sync_first 1 - -cmd_rm /bin/rm -cmd_rsync /usr/local/bin/rsync -cmd_ssh /usr/bin/ssh -cmd_logger /usr/bin/logger - -retain quadhourly 6 -retain daily 3 -retain weekly 2 -retain monthly 1 - -# verbose 1 = quiet -verbose 1 -loglevel 3 -logfile /var/log/rsnapshot - -lockfile /var/run/rsnapshot.pid - -one_fs 1 - -link_dest 1 - -exclude '/home/*/tmp/**' -exclude '/home/*/Downloads/**' - -backup /etc/ localshot/ -backup /home/ localhost/ -backup /usr/share/ localshot/ -backup /usr/local/share/ localshot/ -backup /var/ localshot/ -x - -# disklabel -E sd2 -sd2> a -partition to add: e -offset: -size: -FS type: 4.2BSD -sd2*> q -# newfs sd2e -# mkdir -p /snapshots && mount -o rw,nodev,nosuid,softdep /dev/sd2a /snapshots -# echo .e /snapshots ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab -# ed /etc/rsnapshot.conf <<'x' -,s, /data, , -wq -x -# crontab -e -... -0 */4 * * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly -50 23 * * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly -40 23 1,8,15,22,29 * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly -30 23 1 * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly - - -Server backups - -I don't want to ssh into the root account on my server, so instead -we created a new user and modified the server's doas.conf to allow -him executing "rsync" with no password. - -$ ssh alearx.org -# su - -# useradd -m snapshot -# exit -$ exit -$ su - -# # make sure to generate it passwordless -# ssh-keygen -f /root/.ssh/id_rsa.snapshot -# cp /root/.ssh/id_rsa.snapshot.pub /tmp/ -# chmod 744 /tmp/id_rsa.snapshot.pub -# exit -$ scp /tmp/id_rsa.snapshot.pub alearx.org:/tmp/ -$ ssh alearx.org -$ su - -# cat /tmp/id_rsa.snapshot.pub >>~snapshot/.ssh/authorized_keys -# chown -R snapshot:snapshot ~snapshot -# echo "permit nopass snapshot cmd rsync" >>/etc/doas.conf - -After that I wrote extra lines to rsnapshot.conf, mostly mimicing -the old ones, but for the remote server, and using "doas rsync" -instead of "rsync": - -cat >>/etc/rsnapshot.conf <<'x' - -backup snapshot@alearx.org:/etc/ alearx.org/ - +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" -backup snapshot@alearx.org:/home/ alearx.org/ - +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" -backup snapshot@alearx.org:/root/ alearx.org/ - +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" -backup snapshot@alearx.org:/usr/share/ alearx.org/ - +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" -backup snapshot@alearx.org:/usr/local/share/ alearx.org/ - +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" -backup snapshot@alearx.org:/var/ alearx.org/ - +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" -x - - -Off-site backups - -Ideally you should have a machine I'd own in another building, then -rsync(1) /snapshots/quadhourly.0 to it, and use rsnapshot(1) on -that. Unfortunately, I have to satisfy myself with paying for some -"cloud" storage, and uploading encrypted and signed tarballs there. - -Firstly, I allowed myself to archive quadhourly.0 without password: - -# cat >/etc/rsnapshot.mktar <<'x' -#!/bin/sh - -[ $(id -u) = 0 ] || exit 1 -cd /snapshots/daily.0 || exit 1 -tar cf - . -exit 0 -x -# echo "permit nopass aa cmd /etc/rsnapshot.mktar" - -And then I created a special PGP keypair for passwordless signing: - -$ gpg --full-gen-key -gpg (GnuPG) 2.2.41; Copyright (C) 2022 g10 Code GmbH -This is free software: you are free to change and redistribute it. -There is NO WARRANTY, to the extent permitted by law. - -Please select what kind of key you want: - (1) RSA and RSA (default) - (2) DSA and Elgamal - (3) DSA (sign only) - (4) RSA (sign only) - (14) Existing key from card -Your selection? 4 -RSA keys may be between 1024 and 4096 bits long. -What keysize do you want? (3072) 4096 -Requested keysize is 4096 bits -Please specify how long the key should be valid. - 0 = key does not expire - = key expires in n days - w = key expires in n weeks - m = key expires in n months - y = key expires in n years -Key is valid for? (0) -Key does not expire at all -Is this correct? (y/N) y - -GnuPG needs to construct a user ID to identify your key. - -Real name: Signer Sam -Email address: signer@alearx.org -... - -The main thing is to leave the password empty. - -The tarballs will be created via a makefile. To ensure that the -makefile itself gets archived, I create it as a symlink to -~/src/makefile.snap: - -$ cat >~/src/makefile.snap <<'x' -all: snap - -REMOTE = remote - -snap: /snapshots/quadhourly.0 - $(MAKE) clean - mkdir -p snap.d - doas /etc/rsnapshot.mktar 2>/dev/null | gzip |\ - gpg -er aa@manpager.net -su signer@alearx.org |\ - split -b3072m - snap.d/snap.tar.gz.gpg - touch snap - -rclone: snap - -if [ `rclone -q size $(REMOTE): | grep -o '[0-9]* Byte' |\ - grep -o '[0-9]*'` -gt $$((500 * 2^30)) ]; then\ - rclone -q purge $(REMOTE):snap/old;\ - rclone -q move --delete-empty-src-dirs $(REMOTE):snap/new\ - $(REMOTE):snap/old;\ - fi 2>/dev/null - rclone -q --transfers 6 copy snap.d/\ - $(REMOTE):snap/new/snap`date +%Y%m%dt%H%M%S`/ 2>/dev/null - touch rclone - -clean: - -rm -rf snap.d - -distclean: clean - -rm -f snap rclone - -.PHONY: clean distclean -x -$ mkdir -p /data/aa/snap -$ ln -sf ~/src/snap.mk /data/aa/snap/Makefile - -You might be wondering why exactly do I split the tarballs into 3 GB -files. Two reasons: - -1. They can fit on FAT32 (so, flash drives usually) without further - actions; -2. Some "cloud" storages seem to have a problem with large files; - -And after all that, I set up yet another cronjob: - -$ crontab -e -... -30 2 * * * cd /data/aa/snap && make clean rclone - - -Bitcoin - -I've been using bitcoin since 2022, when I was banned from paying for -my domain name and my server via a bank card as a punishment for -other people's crimes. All this time I did so through bitcoin-qt -without much understanding what it actually does. After trying to -read the documentation I am still not entirely sure. Bitcoin, I -should note, is more of business software that good software. -Consider for instance that several initial releases were for -microsoft only. Unfortunately, the alternatives are less usable. - -The bitcoind configuration is in the following format: - -# comment -cli-option-without-initial-dash=value - -We only really need to modify datadir to be somewhere under /data/: - -$ cat >~/.bitcoin/bitcoin.conf </mnt/secret -# umount /mnt -# bioctl -d sd4 -# # to make sure it works, plug the stick out and in again -# bioctl -c C -l sd3a softraid0 -# mount /dev/sd4a /mnt -# cat /mnt/secret -secret - -It worked! The rest is a simple matter of "cp -r". - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + 806155b1b752c0644667d89a596aa582fdd6adc3 (mode 644) --- /dev/null +++ art/002.x11_isolation.txt @@ -0,0 +1,102 @@ +Nowadays it is often necessary to use either firefox, or chromium for +tasks that you'd think to be basic enough not to require anything +special. These programs are so huge that they tower over the Linux +kernel like Goliath did over David, and even worse they are meant to +do the stupidest thing since the dawn of networks -- connect to +untrusted hosts and interpret arbitrary scripts supplied by them. +Truly we live in a dark time! + +Anyway, it is actually pretty simple to isolate this great evil from +the parts of your system that you probably don't want it to touch, or +even see. The method consists of launching the offender inside a +nested X session under a different user. There are particular +benefits to doing that on OpenBSD because both browsers are further +limited with unveil(2) and pledge(2), meaning that their visibility +of the file system is limited even further, and the amount of +available syscalls is much less crazy too. + +Of course, you can get much better results by using a virtual +machine, but it takes more time to set up, and everyone knows how +to do it anyway. + +As you may have guessed, I am writing with OpenBSD in mind. On other +Unices, you may have to research how to: + +- setting up sudo; +- setting up disc quotas; +- setting up other limits (CPU time, memory, &c.); + +On OpenBSD read at least the following man pages: Xephyr(1), +xauth(1), useradd(1), doas.conf(5); and the FAQ 14: +https://www.openbsd.org/faq/faq14.html . + +For the basic set-up we change permissions for our own home directory +to 750 because we are paranoid and create a new user: + +# chmod 750 /home/mainuser +# useradd -m anotheruser + +A nice thing about OpenBSD is that the resources that any process, or +user may employ are already pretty limited, with some allowances made +for the staff login class (naturally, we'll be keeping anotheruser +outside of staff). For setting up a disc quota, consult the FAQ, +however. You may also put some other restrictions, for instance +limiting printer access to users inside the printer group: + +lp|someprinter:\ + ...\ + :rg=printer + +Of course, if you do stuff like this, it only makes sense to +have your firewall limit anotheruser's access to either most of the +local network, or at least some addresses. And you don't have to stop +there, but I will for now. + +As for giving anotheruser an environment, where he may be *allowed* +to do some things, you can use a simple script: + +#!/bin/sh + +umask 077 + +[ $# -lt 1 ] && set -- :10 -screen 1280x720 -no-host-grab +Xephyr "$@" & +xephyrp=$! +ps -p$xephyrp >/dev/null || exit 1 +while ps o stat -p$! | grep -Fq R; do :; done +ps -p$xephyrp >/dev/null || exit 1 +trap 'rm -f $tmpfile; kill $xephyrp 2>/dev/null' EXIT INT HUP + +for e in $(export); do unset $e; done +export PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin +export DISPLAY="$1" + +tmpfile=/tmp/$$ +[ -f $tmpfile ] && { + echo "ERROR: temporary file $tmpfile already exists" >&2 + exit 1 +} +: >$tmpfile +xauth -qf $tmpfile generate $DISPLAY . trusted +nlist=$(xauth -f $tmpfile nlist $DISPLAY) +rm -f $tmpfile + +doas -u anotheruser /bin/sh -l < -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + 182dd4ddc594a4e6d13b410879e26226fdd64e5b (mode 644) --- /dev/null +++ art/003.git.txt @@ -0,0 +1,101 @@ +Using git + +Most tutorials are pretty bad because they can only attempt to give +you some surface-level overview, and scarcely any give you leads on +further research. Git seems to be one of the worst examples of the +trend, and yet the irony is that git is very simple. All you really +have to do to understand git is type `man gittutorial'. The command +is very deceptively named: by the time I started using Unix, and so +have learned of the great blessing that is actually having your +operating system, and most software under it come with a manual, I +already knew a bit of git, so I thought "I don't need yet another +tutorial, I need a manual!" Well, more than a year later it turned +out that although gittutorial(7) indeed is a tutorial, not very +useful by itself, manuals it references are. Particularly, +gittutorial-2(7) and gitcore-tutorial(7) contain an actual +explanation of how git works. + +So, my biggest suggestion is to read gittutorial(7), and some of the +further pages it reference. Do it now, and return if you want to +read the rest of the article for some reason later. + +OK, you should have read or skimmed through at least gittutorial(7), +gittutorial-2(7), gitcore-tutorial(7), gitglossary(7) and +giteveryday(7). You should be able to say what things like "HEAD^^^", +"refs", "objects", "branches" and "tags" are (and not merely what +they might mean). In the next section I will tell why I think git +(both porcelain and plumbing) is quite good, actually, and how to +really appreciate the system. + + +BACKEND (PLUMBING) + +Git's backend is awesome! This should be obvious to anyone who've +read gitcore-tutorial(7), and to whom Unix is more than just "that +server OS I have to deal with at work". + +The git repository is just a dumb filesystem. It stores two things: + +1. Every bit of content ever to be recorded as an object (a blob or a + tree). The objects' format accounts for the deficiencies of some + filesystem, so you may even store your git repository on a + FAT32-formatted flash drive (though why would one do that I am + uncertain) +2. A bunch of references so that you don't have to memorise each + object's hash. In lieu of not all filesystems supporting actual + links, these are just text files. + +Unfortunately, the objects' binary format makes them less immediately +useful because you can't use normal Unix commands with them (though +you can with references). Instead git repositories should be treated +somewhat like an archive, except instead of tar/cpio/whatever you +type `git'. With that in mind it becomes simple (if not exactly +convenient -- that's what the frontend is for) to, e.g., print each +"file" (object) "below", e.g. master: + +$ git ls-tree .git/refs/heads/master +100644 blob file1 +100644 blob file2 +040000 tree dir +... +$ echo "here's file1:"; git cat-file blob +... +$ echo "here's file2:"; git cat-file blob +... +$ git ls-tree +... +# repeat with each object + +With commands like these it becomes very much possible to implement +some convenient frontend via scripts. In fact, that's how git used +to be, but now they have the entire front-end in C as well (for +speed, presumably). + + +FRONTEND (PORCELAIN) + +Git's frontend is, perhaps, its most chided part. Some of the +criticism is true. Personally I dislike how many commands use such +long and hard-to-type options. When I complain people often answer +that I should use tab-completion. My counter is usually that +tab-completion should not be needed in the first place, and instead +we ought to do better more when designing interfaces. + +A lot of complaints, however, comes from the people who never took +their time to understand the system, and now don't understand what is +it they are interfacing. Such is often the way. + +The important points for ergonomic use of git are: + +1. Understand the backend -- much in the frontend's man pages is + written from the backend's point of view +2. Read git-rev-parse(1), which will allow you to type things like + "@^" instead of "HEAD^" +3. Use branches and, perhaps, tags to mark the immediately important + commits -- you can then type "git diff master mybranch" instead + of first scanning "git log" and then "git diff " + +Once you've got that, read giteveryday(7), and whatever frontend +man pages you are likely to need. Some of them are quite a bit longer +than they should be, but only some of that is of immediate +importance. The rest can be referenced as needed. blob - 0f2bd637ab9046d2917a0f2cbd5cc019dbc49952 (mode 644) blob + /dev/null --- art/freegames.txt +++ /dev/null @@ -1,392 +0,0 @@ -Even if I didn't know how to vocalise it, I considered the human -civilisation to be in a great decline since I was in the middle -school. Barbarians are very much at the gates, except this time -we who consider ourselves civilised are the barbarians. - -There are quite a few things so important to the civilised society -that they precede even the formation of formal hierarchies. Chief -among them is, of course, agriculture. I don't think I am very well -qualified to judge the state of that, I will just say that only Islam -preserved that relatively intact in some places for the Moslems have -a need of the halal food. Then on his road to civilisation man also -needs to form a spirituality, for how else is he do be guided in his -decisions? In spite of that, the fact that we somehow managed to kill -Him within ourselves has been noted a couple of centuries before, and -things are even worse now. Civilised man also has a need for science, -as a civilisation without knowledge ceases to be civilised. The fact -that science is dead should be obvious to any graduate of a -university: we killed it with patents, standards and so-called -"antiplagiarism." Finally, a civilised man has a need for culture: -art and games, that which makes him satisfied intellectually. I am -very much convinced that we are on the road of replacing all art with -commerce and politics. - -If we are to somehow slow down, or even reverse that process, I -believe that we need more art unburdened by propriety, licences and -cheap political messages. In particular that concerns computer games, -which at first weren't really considered an object of culture and -received instead the same terrible treatment that software -development did outside of the very few places, and which later -largely transformed into a monster similar to the BBC and Hollywood. -(Or Netflix and HBO, or whoever produces that rubbish nowadays.) - -Unfortunately, even the people who understand the importance of being -free to have a culture usually concentrate so much on the -software-related aspects (DRM, freedom to inspect/modify the code, -etc.) that they forget completely that this artificial legalese -surrounds all other aspects of art as well. In computer games it is -now common to refer to all the more "traditional" (not programming) -art involved as mere "assets." In fact, it is somewhat common even to -allow the copying of the code, yet forbid that of the "assets." I -say, however that the assets are equally as important! There already -are countless programs we've lost due to the human greed and -commercialisation of art (yes, the art of computer programming), I do -not think that anyone reading this will need much convincing to -accept that statement. Yet there are also countless of "assets" we've -already lost due to the same stubbornness and vanity. Just look up -what happened to the early episodes of Doctor Who! - -With my philosophy clearly stated I will proceed to list the games I -managed to play that were free completely -- i.e. neither the code, -nor the "assets" were burdened too much. Expect many more to appear -in the future. - - -ENDLESS SKY - -https://endless-sky.github.io/ - -This must have been the first completely libre game that I have ever -played. At the time I was writing my baccalaurean diploma, and -whenever I do such projects I find it to be a good practice to take -short breaks and do something that is neither very mentally taxing -instead, nor allows my brain to retreat into the automatic state -completely. So far, nothing has been able to fit this description -entirely, but Endless Sky did come closer than some other things I'd -tried. - -The game is pretty typical of the other top-down exploration/trading/ -combating games. For the most part it consists of going to planets -and taking missions, considering one's travel route against the time -it'd take in order to maximise the profits. It also has quite a few -special missions, which make it all much more interesting. Overall, -the game really is quite impressive, however it is also not hard to -notice that many things in it are unfinished. In particular that -relates to these campaign-missions and the areas of the map that -become explorable afterwards. The former, it feels like, should have -much more branchings that should have a much bigger impact, while the -latter feels a bit too empty. - -In conclusion, Endless Sky is a fantastic game that I can recommend -to anyone, and I wish the people working on it the best of luck. - - -BSD GAMES - -Historically there've been a lot of games written for BSD that are -now usually available on most modern BSDs in /usr/games/, and can be -installed on Linuces from packages like bsd-games and similar. Most -famous of these games is probably rogue(6), which had many -descendants. I managed to play most that come with OpenBSD. - -- adventure(6) is a bit of a classic. The later "adventure games" get -this label from it. The manual is very brief stating that part of the -game is figuring out the rules, and only stating that "quit" is for -quitting and "suspend" is for quitting but saving. Thankfully, when -launched, the game does provide a little bit of help and says that -further help is provided by commands "help" and "info." Otherwise the -game is played very much like the latter text-based adventures it -inspired: the player types one, or two words per command, consisting -of a verb and a noun, though one of the two can be omitted if it can -be inferred from the other. In order to play this game I also had to -draw the map on paper, which I wish more games would have forced me -to do. Another interesting feature of adventure(6) is that saving the -game involves quitting it, and then waiting at least 45 minutes -before continuing. It probably made quite a lot of sense when it was -originally written, and many people would connect to the same -mainframe from a terminal for a limited time, and even now I wish the -games would do that so that the player may also spend his free time -doing other things. Oh, well, at least most new games aren't as -insistent on the player not quitting as Id's games. - -Unfortunately, adventure(6) would also lead to the issues that still -trouble similar games, namely that they are impossible to complete -while playing in any other way than through the players' collective -wisdom: really, how on Earth was I supposed to know that spooking a -giant snake is a matter as simple as releasing a small bird onto it -for some reason? Somehow I did manage to complete the thing through a -combination of my own wits, googling and backing up my saves, but in -the end I only received 330 out of 350 points, becoming an annoying -single point short of achieving the next rank. - -- arithmetic(6) prints rather simple expressions like "6 + 5" and -"14 - 9" and waits for the user to input the answer. Occasionally it -also prints out the score. Not the most challenging, or creative -game. - -- atc(6) is a brutal game. The man page states: Suspending a game is -not permitted. If you get a talk message, tough. When was the last -time an Air Traffic Controller got called away to the phone? Neither -the rest of the man page, nor the game's UI were very telling: just -like a certain Monty Python character the only thing I know about -planes is that I flew some (and that the only worse travelling -experience I've had was in cars -- even metro at peak hours is -somehow better.) The controls are also quite hostile except for the -majority that types on QWERTY. Even for a player that managed to get -through all these things nothing but stress awaits -- and no wonder, -it puts the player into control of air traffic. Personally, I gained -a new appreciation of just how relaxed Doom is through atc(6). - -- backgammon(6) is what it sounds like. It also includes the tutorial -invoked as teachgammon. Unfortunately, I have never had the pleasure -of playing actual backgammon, but I can recall trying to play nards, -which is a very similar games of Persian (I think) origin, mostly -known among the various Caucasian and Russian (and maybe Iranian, but -I wouldn't know) peoples. I've heard it's particularly popular among -the Armenians. Like most users of Unix I don't have a single friend -that understands a single sentence coming from my mouth even when I -merely quote, so in I went against the computer. I was, however, -rather worried. Strangely enough it was when I was writing my -diploma, which ended up having nothing to do with backgammon anyway, -that I discovered that backgammond is among those games, which -computers can't play effectively using only classical game theory. -Rather the only known more-or-less efficient backgammon-playing -programs so far have used some learning algorithm, or as they are -known among the proogers, the neural networks. - -In any case, in I went typing "teachgammon" into my terminal. A bit -of surprise was that a lone piece (called "man" in this version) does -not deny the opponent's moves to the same position, but rather -becomes vulnerable, as the opposing man can land on him (it?), -sending the unfortunate man to the bar (position 0). On the next -turn the player will first have to bring all his men from the bar -before he or she is able to perform any other moves. I *think* this -is not the case in nards, where a piece cannot land on another, no -matter how many are there. Also, I think that in nards all pieces -start at the first position, rather than begin somewhat scattered -already. - -Moments later I played a couple of parties as red because additions -are easier that subtractions. As I discovered, however, either this -is one of the good AIs, or I am completely, or I am completely -untrained myself. - -- banner(6) and banner(1) are actually two different programs, though -their purpose is identical -- the printing of huge letters out of -number signs (#). Example output: - - $ /usr/games/banner .. - ###### - ########## - ############ - ############## - ############## - ############## - ############ - ########## - ###### - - - ###### - ########## - ############ - ############## - ############## - ############## - ############ - ########## - ###### - - - $ /usr/bin/banner Unix - # # - # # # # # # # - # # ## # # # # - # # # # # # ## - # # # # # # ## - # # # ## # # # - ##### # # # # # - -- bcd(6) transforms input into an ASCII art representation of punched -cards and back. Sorry, but I am born too recently to know what it -means. - -- boggle(6) -- I don't even know. - -- bs(6) means "battleship". In real life the game is only slightly -better than naughts-and-crosses and is thus only played on the -especially boring occasions. Here it's not even multiplayer. - -- caesar(6) also invoked as rot13 attempts to decypher Caesar's -cypher. There is probably a reason for this utility to exist... - -- canfield(6) & cfscores(6). Although I am often critical of windows, -I don't think it's a completely terrible operating system. No OS that -features minesweeper can be such. Solitaire, however, is most -definitely a mistake. What even is solitaire? And you know what -canfield(6) is? Solitaire for Unix! - -- cribbage(6) -- another card game. - -- factor(6) and primes(6) work with the prime numbers. factor(6) -prints all prime factors of a number and primes(6) lists all primes in -a range. - -- fortune(6) prints silly messages. - -- gomoku(6) is a sort of naughts-and-crosses-on-19x19 board. The AI -is terribly slow as well: it may take dozens of seconds to think its -move. - -- grdc(6) turns the terminal screen into a huge clock. Better than -xclock(1)! (which doesn't even seem to ever find an appropriate font -to use). - -- hack(6) is like rogue(6) but full of bugs... - -- hangman(6) is pretty much what one would have expected. - -- hunt(6) is among the multiplayer BSD games that work on OpenBSD. -Unfortunately, I don't really know a lot of people that'd be willing -to try that out with me. - -- mille(6) -- yet another product of Ken Arnold's overactiveness. -Seems to be a multi-player clone of some existing board game. I -did't go too much into details. - -- monop(6) -- ah, yes, monopoly on my terminal. - -- morse(6). Let me demonstrate: - - $ echo morse | morse - dow daw - daw daw daw - dit daw dit - dit dit dit - dit - - dit dit dit daw dit daw - -- number(6) reads number and converts it to English like so: - - $ number 129 - one hundred twenty-nine. - -Of course, 129 as read as "one hundred *and* twenty nine," but oh -well... - -- phantasia(6) unfortunately requires some other human beings to play -with and doesn't work on OpenBSD anyway. - -- pig(6) translates sentences from English to pig Latin. Shame -bsdgames are usually not installed by default with most Linuces, -otherwise it'd be useful at work... - -- pom(6) displays the phase of the moon similarly to how date(1) -does something useful. - -- ppt(6) is a close relative of bcd(6), so I don't know what it means -either. - -- quiz(6) the player some questions on a topic. Funnily there have -been quite a few very simple women that tried to convince me that the -quiz TV programmes are somehow educational. Well, sorry, but both the -quiz programmes and programs are the opposite of educational. - -- rain(6) plays a nice animation. - -- random(6) can either print random lines from input, or random -numbers, e.g.: - - $ man random | random - RANDOM(6) Games Manual RANDOM(6) - - NAME - random – random lines from a file or random numbers - SYNOPSIS - random [-er] [denominator] - - DESCRIPTION - must be at least 1, its default value is 2. - The options are as follows: - -r The -r option guarantees that the output is unbuffered. - - SEE ALSO - OpenBSD 7.2 August 23, 2022 OpenBSD 7.2 - -- robots(6) is quite a lot of fun, actually! It's very simple as -well, so I'll finish that at that. - -- sail(6) is currently same as phantasia(6), unfortunately. - -- snake(6) is pretty similar to robots(6). - -- I'd probably be more surprised were I to not find tetris(6). - -- trek(6) is in somewhere between adventrue(6) and hack(6). It is -pretty complex, but pretty fun nonetheless and can be played without -first having to find anyone interested. Unfortunately the -documentation is rather weird. The man page only gives a brief -overview explanation of some commands, while the actual doc is not -distributed with OpenBSD. Oh, well, I do have the sources: - - $ tbl /usr/src/games/trek/USD.doc/trek.me | groff -Tascii | - less -r - -Basically, the player is given a space-ship that responds to a number -of commands. A limited space is shared with several enemies friendly -planets etc. All enemies have to be destroyed before time runs out. -Personally I found the game to be very well-made and would argue that -it is a great example of how games should me made. - -- wargames(6) is a very strange game indeed. My version is -implemented as a small shell script. Here is the code: - - echo -n "Would you like to play a game? " - read x a - x=`/usr/bin/basename $x` - - if [ -f /usr/games/$x ] ; then - tput cl - exec /usr/games/$x $a - else - echo "A strange game." - echo "The only winning move is not to play." - fi - exit 0 - -- worm(6) is of the variety where apples make the worm bigger, not -the one where worms from the team A drown the ones from the team B -by exploding the ground they stand on. - -- worms(6) is another nice animation. - -- wump(6) is mostly a luck-based game. Like adventure(6) it features -a non-Euclidian cave. One room in this cave contains an evil wumpus -that has to be killed by guessing, which cave he is in, while some -others contain bottomless pits and bats. Fortunately, the player is -told which room he's in, which rooms are nearby and if there are any -bats/wumpuses/pits closely. Unfortunately, the player is never told -which ones are the dangerous rooms before it is too late, so really -there is no way to win other than by guessing. - - -ANARCH - -https://gitlab.com/drummyfish/anarch - -The game's made by one Miroslav Chizh of Moravia, quite an -interesting man (though personally I disagree with a lot that he -claims to believe). It mostly plays like a generic Doom clone. The -achievement here is mostly technical. Being a programmer myself I am -at a disadvantage when actually trying to describe any code. It is -also further complicated by the fact that Miroslav is one of those -annoying people who think that placing two extra spaces at the start -of a line indents it by one extra level. An interesting part here is -that the game has quite clearly defined back- and front-end, which is -most unlike other games, which rather only divide data, state and -logic. - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + a3617d5a95fc8154930884ceec77de1b8c24fedc (mode 644) --- /dev/null +++ art/004.mail_server.txt @@ -0,0 +1,206 @@ +Over what must have been more than a year I've read a lot of RFCs, +had a lot of experience and put a lot of thought into mailing. This +is the third version of this article. Most articles on setting up a +mail system have their readers do a lot of work with the latter +ending up with a complex monstrosity they do not understand. My +system is dead-simple and easy to extend within limitations of a +small server. + +The entire mailing system of ours shall consist of the following: +OpenBSD (though we only *really* need OpenSMTPD, which I hear has +been ported), ssh and your favourite mail client & operating system. +That's it! Not even a POP server! + +One thing I didn't bother doing this time is dkim. At the bottom are +my old instructions on setting dkim up (section DKIM): they shall not +be maintained too much. + + +BLACKLISTS + +In the world of email, and spam, and housewife-targeting +bitcoin-miners there are a lot of blacklists that many servers adhere +to. Most of those are run by crooks, however it is still important to +check if your IP address is in one. So, before anything else, paste +it into a [blacklist checker], and request a different address should +that one be spoiled. + + +DNS + +We are interested in the following: A, AAAA, MX, PTR (i.e. rDNS), and +a couple of TXT ones (spf and dmarc). PTR is set up by the network +block owner (usually same as ISP) and should be the same as HELO that +the server will send (the server's FQDN). Virtual host providers +usually have a web-form for setting up PTR. Otherwise you'll have to +actually request it being changed by talking to people. + +Others are set up as usual. In the end something like this should +suffice: + + example.com. 600 IN A 1.2.3.4 + example.com. 600 IN MX 0 example.com + example.com. 600 IN TXT "v=spf1 a mx ip4:1.2.3.4 ~all" + _dmarc.example.com. 600 IN TXT "v=DMARC1; p=none" + +Add ipv6 if you can as well. + + +SMTPD + +Firstly we shall get a key and a cert (which will be self-signed): + + openssl genrsa -out /etc/ssl/private/example.com.key 4096 + openssl req -new -x509 -key /etc/ssl/private/example.com.key \ + -out /etc/ssl/example.com.crt -days 365 + chmod 600 /etc/ssl/example.com.crt + chmod 600 /etc/ssl/private/example.com.key + +And automatically renew it with the following crontab: + + 0 0 1 */6 * opnssl x509 -in /etc/ssl/example.com.crt -signkey /etc/ssl/private/example.com.key -out /etc/ssl/example.com.crt -days 365 && chmod 600 /etc/ssl/manpager.com.crt + +And, yes, the certificate is 600, please refer to smtpd.conf(5) for +actual docs, this is just a small example. + +Some people might also say that I should here use a CA-signed cert. +Well, no, not really, there are unlikely to be any problems: I +haven't experienced any and I force tls. Funny thing about mail is +that there are all sorts of crazy set-ups, where it bounces between +ten different not-really-trusted servers in-between the sender and +the actual target. In the end who knows if there'll be an appropriate +cert at the penultimate hop? So, we are lucky to have any encryption +at all! This is why the validity of the certs is usually only checked +in the purely-internal scenarios by the vast majority of SMTP servers +out there (and the ones that are more strict are probably +misconfigured!). + +Speaking of which, here's /etc/mail/smtpd.conf itself: + + pki example.com cert "/etc/ssl/example.com.crt" + pki example.com key "/etc/ssl/private/example.com.key" + + table aliases file:/etc/mail/aliases + + smtp sub-addr-delim "_" + + listen on lo + listen on egress tls-require pki example.com + + action "local" maildir "%{user.directory}/mail" alias + action "in" maildir "%{user.directory}/mail" + action "out" relay tls no-verify pki example.com + + match from local for local action "local" + match from any for domain example.com ! rcpt-to root action "in" + match from local for any action "out" + +Do, by the way take a look at aliases: you might, for instance, want +local mail to root to arrive to another user instead. + +Set up thus, our server will refuse to talk with others over +plain-text, meaning less spam. If that bothers you, read the mans (or +just remove "tls-require"). And no, the server doesn't handle +authentication: that is done with ssh below. + + +SPAM? + +You might have noticed that we are not running any spam-filters on +the server itself (other that denying external mail to root). You +might have also noticed that I introduced the mysterious line +`smtp sub-addr-delim "_"'. This line is responsible for the vast +majority of spam-filtering anyone will ever need. With this mail to +alexander@example.com, alexander_smith@example.com and +alexander_alexander@example.com arrive to the same user alexander, +while the assholes of the internets are none the wiser because +underscore is a character commonly used for actual usernames, but not +subaddresses. Now, simply use different subaddresses for different +purposes, and perhaps employ some subaddress-based whitelist with +procmail or something like that. + +Beyond that, however, there is spamd and rspamd, which also contain +interesting stuff like spam traps, or denying mail with bad helo &c. +Just don't use those horrible blacklists, please! + + +CLIENT + +This section used to contain my set-up for the set of maildir +utilities mblaze, but that proved to be too much of a moving target. +I therefore leave most of the MUA set-up up to the reader, and only +describe the way of emulating an MDA and MTA with ssh. + +To get mail, create a script, say, "msync": + + #!/bin/sh + + while :; do + cd $HOME && + scp -r user@example.com:mail/new/ mail/ 2>/dev/null && + find mail/new -type f -exec \ + ssh user@example.com rm {} + 2>/dev/null + sleep 3600 + done + +It may be called automatically from, e.g., ~/.profile: + + while :; do + ps xo args | grep -q msync$ || msync + sleep 10 + done >/dev/null 2>&1 & + +Some shells know what a maildir is, and if you set the variable $MAIL +to the path to you maildir, they will notify of your mail. Otherwise +you may put something like this in you, e.g., ~/.kshrc: + + ls $HOME/mail/new/* >/dev/null 2>&1 && echo You have mail. + +And sending mail is as simple as creating this script: + + #!/bin/sh + + ssh user@example.com sendmail "$@" + +Now either call it "sendmail" and put it in your $PATH so that it is +found before the actual sendmail (if any), or configure your MUA to +use this script instead of sendmail. + + +DKIM + +If you take this set-up and go to mail-tester.com, you are likely to +get 9/10 with -1 being for DKIM. It means that the absolute vast +majority of mail servers in the entire world will accept you mail. If +you still want dkim, do the following on your server: + + pkg_add opensmtpd-filter-dkimsign + mkdir -p /etc/mail/dkim + doas -u _dkimsign openssl genrsa -out /etc/mail/dkim/private.rsa.key 1024 + openssl rsa -in /etc/mail/dkim/private.rsa.key -pubout + +Add the following DNS record: + + ._domainkey.example.com. 680 IN TXT "v=DKIM1;p=" + + can be any string and is the one that we just +printed printed (it'll be over several lines, make sure to paste +it all without whitespace). + +Finally, add this to /etc/smtpd.conf + + filter "dkimsign_rsa" proc-exec "filter-dkimsign -d example.com -s \ + -k /etc/mail/dkim/private.rsa.key" user _dkimsign group _dkimsign + listen on socket filter "dkimsign_rsa" + +Of, course, make same here as it is in the records. + +This *should* do it, but I give no promises. If you want the key to +have more than 1024 bits, you'll also need to spread the selector +across several strings in the DNS records. And even with 1024 you +might have to do it. I don't even know. + + +REFERENCES + +[blacklist checker] https://mxtoolbox.com/blacklists.aspx blob - 1f719bbe55d1f365ef3f642fcb7e385b4dec5dcb (mode 644) blob + /dev/null --- art/git.txt +++ /dev/null @@ -1,105 +0,0 @@ -Using git - -Most tutorials are pretty bad because they can only attempt to give -you some surface-level overview, and scarcely any give you leads on -further research. Git seems to be one of the worst examples of the -trend, and yet the irony is that git is very simple. All you really -have to do to understand git is type `man gittutorial'. The command -is very deceptively named: by the time I started using Unix, and so -have learned of the great blessing that is actually having your -operating system, and most software under it come with a manual, I -already knew a bit of git, so I thought "I don't need yet another -tutorial, I need a manual!" Well, more than a year later it turned -out that although gittutorial(7) indeed is a tutorial, not very -useful by itself, manuals it references are. Particularly, -gittutorial-2(7) and gitcore-tutorial(7) contain an actual -explanation of how git works. - -So, my biggest suggestion is to read gittutorial(7), and some of the -further pages it reference. Do it now, and return if you want to -read the rest of the article for some reason later. - -OK, you should have read or skimmed through at least gittutorial(7), -gittutorial-2(7), gitcore-tutorial(7), gitglossary(7) and -giteveryday(7). You should be able to say what things like "HEAD^^^", -"refs", "objects", "branches" and "tags" are (and not merely what -they might mean). In the next section I will tell why I think git -(both porcelain and plumbing) is quite good, actually, and how to -really appreciate the system. - - -BACKEND (PLUMBING) - -Git's backend is awesome! This should be obvious to anyone who've -read gitcore-tutorial(7), and to whom Unix is more than just "that -server OS I have to deal with at work". - -The git repository is just a dumb filesystem. It stores two things: - -1. Every bit of content ever to be recorded as an object (a blob or a - tree). The objects' format accounts for the deficiencies of some - filesystem, so you may even store your git repository on a - FAT32-formatted flash drive (though why would one do that I am - uncertain) -2. A bunch of references so that you don't have to memorise each - object's hash. In lieu of not all filesystems supporting actual - links, these are just text files. - -Unfortunately, the objects' binary format makes them less immediately -useful because you can't use normal Unix commands with them (though -you can with references). Instead git repositories should be treated -somewhat like an archive, except instead of tar/cpio/whatever you -type `git'. With that in mind it becomes simple (if not exactly -convenient -- that's what the frontend is for) to, e.g., print each -"file" (object) "below", e.g. master: - -$ git ls-tree .git/refs/heads/master -100644 blob file1 -100644 blob file2 -040000 tree dir -... -$ echo "here's file1:"; git cat-file blob -... -$ echo "here's file2:"; git cat-file blob -... -$ git ls-tree -... -# repeat with each object - -With commands like these it becomes very much possible to implement -some convenient frontend via scripts. In fact, that's how git used -to be, but now they have the entire front-end in C as well (for -speed, presumably). - - -FRONTEND (PORCELAIN) - -Git's frontend is, perhaps, its most chided part. Some of the -criticism is true. Personally I dislike how many commands use such -long and hard-to-type options. When I complain people often answer -that I should use tab-completion. My counter is usually that -tab-completion should not be needed in the first place, and instead -we ought to do better more when designing interfaces. - -A lot of complaints, however, comes from the people who never took -their time to understand the system, and now don't understand what is -it they are interfacing. Such is often the way. - -The important points for ergonomic use of git are: - -1. Understand the backend -- much in the frontend's man pages is - written from the backend's point of view -2. Read git-rev-parse(1), which will allow you to type things like - "@^" instead of "HEAD^" -3. Use branches and, perhaps, tags to mark the immediately important - commits -- you can then type "git diff master mybranch" instead - of first scanning "git log" and then "git diff " - -Once you've got that, read giteveryday(7), and whatever frontend -man pages you are likely to need. Some of them are quite a bit longer -than they should be, but only some of that is of immediate -importance. The rest can be referenced as needed. - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + ecd68505544a32f7cd159e363aeff4d5bd19faf5 (mode 644) --- /dev/null +++ art/005.books_recommendations.txt @@ -0,0 +1,93 @@ +There used to be two larger lists: one programming books and the +second for other literature, where I put pretty much anything that'd +come to mind, while trying to avoid things that people would have +read anyway. I have since merged the two lists, and rewritten them to +list the books that left their mark on my brain: the sort of books I +sometimes re-read, or at least consider doing so. + + +PROGRAMMING + +- The C Programming Language - + +*The* book to learn C. + +- The AWK Programming Language - + +The name is very deceptive. awk(1) is known for being a very solid +tool for working with strings. There's a lot of that in the book. And +then there are implementations of some more known programs, +algorithms and little languages, including an assembly for a +fictional computer. + +- The Practice of Programming - + +Advice on programming pragmatically and effectively. + +- Learning Perl - + +It is what it says it is -- a decent introduction to Perl. + +- Programming in Haskell, 2nd ed. - + +Introductory Haskell book. Clear, concise and has good exercises. + + +FICTION + +- H.P. Lovecraft - + +Somehow everyone I recommend Lovecraft to seems to dislike his work. +I blame the translations. Lovecraft's use of the Engilsh language is, +perhaps, the most unique I've seen or heard. To anyone who, like me, +desperately looks for exactly that sort of things in his fiction, I +recommend Lovecraft wholeheartedly. + +- The Flashman papers - + +I think the book series is popular in Great Britain (at least), but +no one I've spoken to has ever heard of it. The series follows the +misadventures of an "anti-Arthurian" British cavalryman through some +significant (and some made-up) events of the Victorian era, German +unification, American civil war and other events of the period. +Probably only of much interest to people at least mildly interested +in history. + +- The Divine Comedy - + +On one hand, the divine comedy could be viewed as the worst kind of +political satire -- one written by members of one party to slander +the members of the other. On the other hand, there is genuine +religious concern for the health of one's soul: sin is condemned for +what it is, while virtue is rewarded. The divine comedy is a book of +great historic and philosophical significance. + +- 1984 - + +1984 is a "satire without humour". If Ingsoc satirises +social/political movements, Winston satirises such +"counter-movements". Orwell brings the us to hold contempt to +everyone involved: the party for its senseless totalitarianism, +Winston for his hatefulness, the proles for their ignorance. The +book reminds us of what we become when we accept madness as normalcy. + + +MISC + +- Bible - + +People who haven't read at least the Gospels are doing themselves a +huge disfavour. Especially those that identify themselves as +"atheists". + +- gittutorial(7), gittutorial-2(7) & gitcore-tutorial(7) - + +For years I couldn't understand Git, and somewhat hated it for that. +I tried to learn from the git(1) man page, man pages for individual +utilities, the official Web site, some books, even the +Internet-tutorials -- to no avail. Then I read gittutorial(7) and +some other pages it suggested, and it all "clicked" immediately. + +- /usr/share/doc directory in 4.4BSD-lite2 (and earlier) - + +Important things modern Unices fail to mention. blob - f1684bd487d183d1ea4f70d29f9e691f02ba04d8 (mode 644) blob + /dev/null --- art/isolated_wwwbrowser.txt +++ /dev/null @@ -1,104 +0,0 @@ -Nowadays it is often necessary to use either firefox, or chromium for -tasks that you'd think to be basic enough not to require anything -special. These programs are so huge that they tower over the Linux -kernel like Goliath did over David, and even worse they are meant to -do the stupidest thing since the dawn of networks -- connect to -untrusted hosts and interpret arbitrary scripts supplied by them. -Truly we live in a dark time! - -Anyway, it is actually pretty simple to isolate this great evil from -the parts of your system that you probably don't want it to touch, or -even see. The method consists of launching the offender inside a -nested X session under a different user. There are particular -benefits to doing that on OpenBSD because both browsers are further -limited with unveil(2) and pledge(2), meaning that their visibility -of the file system is limited even further, and the amount of -available syscalls is much less crazy too. - -Nevertheless, it should work on other Unices, just as long as X is -available. There you might, however, have to do your own research on: - -- setting up sudo; -- setting up disc quotas; -- setting up other limits (CPU time, memory, &c.); - -On OpenBSD read at least the following man pages: Xephyr(1), -xauth(1), useradd(1), doas.conf(5); and the FAQ 14: -https://www.openbsd.org/faq/faq14.html . - -For the basic set-up we change permissions for our own home directory -to 750 because we are paranoid and create a new user: - -# chmod 750 /home/mainuser -# useradd -m anotheruser - -A nice thing about OpenBSD is that the resources that any process, or -user may employ are already pretty limited, with some allowances made -for the staff login class (naturally, we'll be keeping anotheruser -outside of staff). For setting up a disc quota, consult the FAQ, -however. You may also put some other restrictions, for instance -limiting printer access to users inside the printer group: - -lp|someprinter:\ - ...\ - :rg=printer - -Of course, if you do stuff like this, it only makes sense to -have your firewall limit anotheruser's access to either most of the -local network, or at least some addresses. And you don't have to stop -there, but I will just for the moment. - -As for giving anotheruser an environment, where he may be *allowed* -to do some things, you can use a simple script: - -#!/bin/sh - -umask 077 - -[ $# -lt 1 ] && set -- :10 -screen 1280x720 -no-host-grab -Xephyr "$@" & -xephyrp=$! -ps -p$xephyrp >/dev/null || exit 1 -while ps o stat -p$! | grep -Fq R; do :; done -ps -p$xephyrp >/dev/null || exit 1 -trap 'rm -f $tmpfile; kill $xephyrp 2>/dev/null' EXIT INT HUP - -for e in $(export); do unset $e; done -export PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin -export DISPLAY="$1" - -tmpfile=/tmp/$$ -[ -f $tmpfile ] && { - echo "ERROR: temporary file $tmpfile already exists" >&2 - exit 1 -} -: >$tmpfile -xauth -qf $tmpfile generate $DISPLAY . trusted -nlist=$(xauth -f $tmpfile nlist $DISPLAY) -rm -f $tmpfile - -doas -u anotheruser /bin/sh -l < -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + e9dc2ef469029e2467953043ca3cdfb8c31c1def (mode 644) --- /dev/null +++ art/006.on_passwords.txt @@ -0,0 +1,81 @@ +Most of this document is a long version of the +"correct horse battery staple" [comic]. There are some more +interesting observations towards the end. + +The strength of a passphrase does not derive from it having at least +one letter, one digit and one special character, but from something +called "entropy". "Entropy" is this mysterious concept that my +professors kept telling me about, all the while I would wonder "what +is an entropy?". In our case we are dealing with "more is better" and +the formula + + E = log_2(R^L) + +where E is entropy, R is the size of the dictionary (a rather +offputting term, see below) and L is the length of the password. I +won't be telling how much entropy is needed for a good password: +calculate that yourself. That formula works if passphrases are +generated by taking random words from the dictionary. If your +password is your birthday, the entropy is 1 because the passphrase is +cracked by answering the question "is it the owner's birthday?". + +"Word" here is simply the smallest unit we are dealing with, while a +dictionary is a list of unique words. English alphabet is a +dictionary of single-byte words. + +There are several ways the vast majority of people make passwords in +practice: they either use something very simple like their birthday, +or they use something very hard to remember, yet easy to crack. This +is further promoted by many sites refusing to take passwords with +more than e.g. 20 characters &c. The readers may be surprised to read +from me that the issue lies not with the fact of using such weak +passwords on its own: unless the attacker has physical access to a +device, he is usually limited to "n tries per t time". The real +issues begin with man's faulty memory. Firstly such lack of +methodology leads to passwords being easily forgotten, which is just +horrible; secondly, people like this tend to use the same password +for everything. This means that should one service's security turn +out to be less-than-optimal (it usually is), all of the other +accounts become compromised as well. + +And quite simply because I am quite tired of hearing stuff like "They +wouldn't get anything important anyway": no, "they" bloody will, +unless you consider your bank information, personal information and +the ability to be the only one to write messages from your name to be +unimportant. + +The solution is to randomly generate passwords, and then store and +retrieve them using a password manager. There are generally two kinds +of such passwords: strings of randomly-generated bytes from something +like [A-Za-z0-9] and sequences of randomly-generated words. I +strongly prefer the latter, as they may be typed by looking at them +even when clipboard is unavailable. + +Then there is of course the issue of setting up one or more "master" +passwords. Generally the following _have_ to be memorised: password +to a normal user on the system, password to the root user, the +password to the password-manager and passphrases to ssh &c. Since it +all really ought to be done entirely locally on a single-user system +(if it isn't, start panicking), there is not much danger in setting +them to be the same thing. It does, however, have to be something +strong, memorable and not too complicated to type. One option is to +generate a passphrase via a normal method and simply memorise it (or +write it down, unless you live with people you don't trust +unconditionally). Another method is to make up a few words, not tell +anyone about the fact and use those. + +And now since I mentioned the ssh passphrases, I'd like to also state +that yes, ssh keys should have passphrases. A possible exception are +the keys used for things like backups. This should instead be +restricted to certain users and/or commands. A concern some people +might have is that it could hurt automation. I say not nearly as much +as people think. Executing ssh-agent and ssh-add at every login does +mean typing password twice, but it also means that all those scripts +could still be run, provided they are started afterwards in the same +session. OpenBSD's xenodm is already set to run the necessary. On +platforms that use startx, a wrapper would be simple to write. Other +DMs should have such functionality (or they should be avoided +otherwise). If not starting X at all, then executing it from +~/.profile or similar file is even simpler. + +[comic] https://xkcd.com/936/ blob - d42b545c8d07a16d6a2f0009f3c8ce6920a04c43 (mode 644) blob + /dev/null --- art/lit.txt +++ /dev/null @@ -1,97 +0,0 @@ -There used to be two larger lists: one programming books and the -second for other literature, where I put pretty much anything that'd -come to mind, while trying to avoid things that people would have -read anyway. I have since merged the two lists, and rewritten them to -list the books that left their mark on my brain: the sort of books I -sometimes re-read, or at least consider doing so. - - -PROGRAMMING - -- The C programming language, 2nd ed. - - -*The* book to learn C. - -- The AWK programming language - - -The name is very deceptive. awk(1) is known for being a very solid -tool for working with strings. There's a lot of that in the book. And -then there are implementations of some more known programs, -algorithms and little languages, including an assembly for a -fictional computer. - -- The practice of programming - - -Advice on programming pragmatically and effectively. - -- Learning Perl - - -It is what it says it is -- a decent introduction to Perl. - -- Programming in Haskell, 2nd ed. - - -Introductory Haskell book. Clear, concise and has good exercises. - - -FICTION - -- H.P. Lovecraft - - -Somehow everyone I recommend Lovecraft to seems to dislike his work. -I blame the translations. Lovecraft's use of the Engilsh language is, -perhaps, the most unique I've seen or heard. To anyone who, like me, -desperately looks for exactly that sort of things in his fiction, I -recommend Lovecraft wholeheartedly. - -- The Flashman papers - - -I think the book series is popular in Great Britain (at least), but -no one I've spoken to has ever heard of it. The series follows the -misadventures of an "anti-Arthurian" British cavalryman through some -significant (and some made-up) events of the Victorian era, German -unification, American civil war and other events of the period. -Probably only of much interest to people at least mildly interested -in history. - -- The divine comedy - - -On one hand, the divine comedy could be viewed as the worst kind of -political satire -- one written by members of one party to slander -the members of the other. On the other hand, there is genuine -religious concern for the health of one's soul: sin is condemned for -what it is, while virtue is rewarded. The divine comedy is a book of -great historic and philosophical significance. - -- 1984 - - -1984 is a "satire without humour". If Ingsoc satirises -social/political movements, Winston satirises such -"counter-movements". Orwell brings the us to hold contempt to -everyone involved: the party for its senseless totalitarianism, -Winston for his hatefulness, the proles for their ignorance. The -book reminds us of what we become when we accept madness as normalcy. - - -MISC - -- Bible - - -People who haven't read at least the Gospels are doing themselves a -huge disfavour. Especially those that identify themselves as -"atheists". - -- gittutorial(7), gittutorial-2(7) & gitcore-tutorial(7) - - -For years I couldn't understand Git, and somewhat hated it for that. -I tried to learn from the git(1) man page, man pages for individual -utilities, the official Web site, some books, even the -Internet-tutorials -- to no avail. Then I read gittutorial(7) and -some other pages it suggested, and it all "clicked" immediately. - -- /usr/share/doc directory in 4.4BSD-lite2 (and earlier) - - -Important things modern Unices fail to mention. - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + 60f4f238537fb4d5541a926c8a3caa2b37d31cfd (mode 644) --- /dev/null +++ art/007.fun_with_new_hdd.txt @@ -0,0 +1,425 @@ +My new backup system + +Until recently my backups relied on connecting an HDD externally ever +so often. Very manual and quite dangerous. Lately, however, I thought +that since I am dealing with a hard drive this way, I might as well +just install it inside my PC and use it for good -- I have two (or +three even, if you count that second SSD I no longer use) SATA ports +just hanging there! + +Well, I was partly correct to fear slightly the months before: my +motherboard has been showing its age (especially after a small fire +a few centimetres away), and as I was trying to attach the drive, one +of the two ports fell off! To be more precise, the plastic did, and +the important part followed, but thankfully the other three seem to +hold on much better. + +Now, with 1 TB of extra space I went on with partly realising the +things I always wanted to do. + + +Initial setup + +I decided have one 500 GB general partition, and then see how large +the others may need to be. I did the normal OpenBSD disc setup +otherwise. + +# fdisk -iy sd2 +# disklabel -E sd2 +a +partition to add: a +offset: +size: 500g +FS type: 4.2BSD +q +# newfs sd2a +# sysctl hw.disknames +hw.disknames=sd0:,sd1:,sd2: +# echo .a /data ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab +# mkdir -p /data && mount -o rw,nodev,nosuid,softdep /dev/sd2a /data +# mkdir -p /data/aa && chown aa:aa /data/aa + + +CVS + +I already had reposync (though it was on /var/cvs instead of the +usual /cvs) set up, so I knew that 50 GB will be plenty: + +# disklabel -E sd2 +sd2> a +partition to add: b +offset: +size: 50g +FS type: 4.2BSD +sd2*> q +# newfs sd2b +# mkdir -p /cvs && mount -o rw,nodev,nosuid,softdep /dev/sd2b /cvs +# echo .b /packages ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab +# chown cvs:wsrc /cvs +# chmod g+w /cvs +# doas -u cvs crontab -e +(stop the reposync cronjob) +# rm /var/db/reposync/reposync.hash +# doas -u cvs crontab -e +... +~ */2 * * * reposync -q rsync://ftp.somemirror.tld/cvs + +This sets the OpenBSD cvs changes to be synced to /cvs at a random +minute of every second hour. Also I set CVSROOT to /cvs. + + +Packages + +First I estimated how much space do I need for everything: + +$ cd /data/aa +$ mkdir -p packages/snapshots/amd64 +$ rsync -aq --delete-delay --delete-updates \ + rsync://ftp.somemirror.tld/OpenBSD/snapshots/packages/amd64/ \ + packages/snapshots/amd64/ +$ du -hs packages + +Turns out, currently it's a little under 60 GB, so I set up a 150 GB +partition: + +# disklabel -E sd2 +sd2> a +partition to add: d +offset: +size: 150g +FS type: 4.2BSD +sd2*> q +# newfs sd2d +# mkdir -p /packages && mount -o rw,nodev,nosuid,softdep /dev/sd2d /packages +# echo .d /packages ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab +# useradd -s/sbin/nologin -d/var/empty packages +# chown packages:packages /packages +# doas -u packages mkdir -p /packages/snapshots/amd64 +# doas -u packages crontab -e +~ 0 * * * rsync -aq --delete-delay --delete-updates rsync://ftp.somemirror.tld/OpenBSD/snapshots/packages/amd64/ /packages/snapshots/amd64/ + +Sorry for the last line's length! + +I also ran this command once manually, and set my PKG_PATH to +/packages/snapshots/amd64. + + +Local backups + +I decided to manage my local backups with rsnapshot: + +# cp /etc/rsnapshot.conf /etc/rsnapshot.conf.default +# # I actually edited this in vi(1), of course. +# # Also, some parts of it was provided by default, but heavily commented. +# cat >/etc/rsnapshot.conf <<'x' +config_version 1.2 + +snapshot_root /data/snapshots/ + +sync_first 1 + +cmd_rm /bin/rm +cmd_rsync /usr/local/bin/rsync +cmd_ssh /usr/bin/ssh +cmd_logger /usr/bin/logger + +retain quadhourly 6 +retain daily 3 +retain weekly 2 +retain monthly 1 + +# verbose 1 = quiet +verbose 1 +loglevel 3 +logfile /var/log/rsnapshot + +lockfile /var/run/rsnapshot.pid + +one_fs 1 + +link_dest 1 + +exclude '/home/*/tmp/**' +exclude '/home/*/Downloads/**' + +backup /etc/ localshot/ +backup /home/ localhost/ +backup /usr/share/ localshot/ +backup /usr/local/share/ localshot/ +backup /var/ localshot/ +x + +# disklabel -E sd2 +sd2> a +partition to add: e +offset: +size: +FS type: 4.2BSD +sd2*> q +# newfs sd2e +# mkdir -p /snapshots && mount -o rw,nodev,nosuid,softdep /dev/sd2a /snapshots +# echo .e /snapshots ffs rw,nodev,nosuid,softdep 1 2 >>/etc/fstab +# ed /etc/rsnapshot.conf <<'x' +,s, /data, , +wq +x +# crontab -e +... +0 */4 * * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly +50 23 * * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly +40 23 1,8,15,22,29 * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly +30 23 1 * * /usr/local/bin/rsnapshot sync && /usr/local/bin/rsnapshot quadhourly + + +Server backups + +I don't want to ssh into the root account on my server, so instead +we created a new user and modified the server's doas.conf to allow +him executing "rsync" with no password. + +$ ssh alearx.org +# su - +# useradd -m snapshot +# exit +$ exit +$ su - +# # make sure to generate it passwordless +# ssh-keygen -f /root/.ssh/id_rsa.snapshot +# cp /root/.ssh/id_rsa.snapshot.pub /tmp/ +# chmod 744 /tmp/id_rsa.snapshot.pub +# exit +$ scp /tmp/id_rsa.snapshot.pub alearx.org:/tmp/ +$ ssh alearx.org +$ su - +# cat /tmp/id_rsa.snapshot.pub >>~snapshot/.ssh/authorized_keys +# chown -R snapshot:snapshot ~snapshot +# echo "permit nopass snapshot cmd rsync" >>/etc/doas.conf + +After that I wrote extra lines to rsnapshot.conf, mostly mimicing +the old ones, but for the remote server, and using "doas rsync" +instead of "rsync": + +cat >>/etc/rsnapshot.conf <<'x' + +backup snapshot@alearx.org:/etc/ alearx.org/ + +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" +backup snapshot@alearx.org:/home/ alearx.org/ + +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" +backup snapshot@alearx.org:/root/ alearx.org/ + +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" +backup snapshot@alearx.org:/usr/share/ alearx.org/ + +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" +backup snapshot@alearx.org:/usr/local/share/ alearx.org/ + +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" +backup snapshot@alearx.org:/var/ alearx.org/ + +rsync_long_args=--rsync-path="doas /usr/local/bin/rsync" +x + + +Off-site backups + +Ideally you should have a machine I'd own in another building, then +rsync(1) /snapshots/quadhourly.0 to it, and use rsnapshot(1) on +that. Unfortunately, I have to satisfy myself with paying for some +"cloud" storage, and uploading encrypted and signed tarballs there. + +Firstly, I allowed myself to archive quadhourly.0 without password: + +# cat >/etc/rsnapshot.mktar <<'x' +#!/bin/sh + +[ $(id -u) = 0 ] || exit 1 +cd /snapshots/daily.0 || exit 1 +tar cf - . +exit 0 +x +# echo "permit nopass aa cmd /etc/rsnapshot.mktar" + +And then I created a special PGP keypair for passwordless signing: + +$ gpg --full-gen-key +gpg (GnuPG) 2.2.41; Copyright (C) 2022 g10 Code GmbH +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Please select what kind of key you want: + (1) RSA and RSA (default) + (2) DSA and Elgamal + (3) DSA (sign only) + (4) RSA (sign only) + (14) Existing key from card +Your selection? 4 +RSA keys may be between 1024 and 4096 bits long. +What keysize do you want? (3072) 4096 +Requested keysize is 4096 bits +Please specify how long the key should be valid. + 0 = key does not expire + = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years +Key is valid for? (0) +Key does not expire at all +Is this correct? (y/N) y + +GnuPG needs to construct a user ID to identify your key. + +Real name: Signer Sam +Email address: signer@alearx.org +... + +The main thing is to leave the password empty. + +The tarballs will be created via a makefile. To ensure that the +makefile itself gets archived, I create it as a symlink to +~/src/makefile.snap: + +$ cat >~/src/makefile.snap <<'x' +all: snap + +REMOTE = remote + +snap: /snapshots/quadhourly.0 + $(MAKE) clean + mkdir -p snap.d + doas /etc/rsnapshot.mktar 2>/dev/null | gzip |\ + gpg -er aa@manpager.net -su signer@alearx.org |\ + split -b3072m - snap.d/snap.tar.gz.gpg + touch snap + +rclone: snap + -if [ `rclone -q size $(REMOTE): | grep -o '[0-9]* Byte' |\ + grep -o '[0-9]*'` -gt $$((500 * 2^30)) ]; then\ + rclone -q purge $(REMOTE):snap/old;\ + rclone -q move --delete-empty-src-dirs $(REMOTE):snap/new\ + $(REMOTE):snap/old;\ + fi 2>/dev/null + rclone -q --transfers 6 copy snap.d/\ + $(REMOTE):snap/new/snap`date +%Y%m%dt%H%M%S`/ 2>/dev/null + touch rclone + +clean: + -rm -rf snap.d + +distclean: clean + -rm -f snap rclone + +.PHONY: clean distclean +x +$ mkdir -p /data/aa/snap +$ ln -sf ~/src/snap.mk /data/aa/snap/Makefile + +You might be wondering why exactly do I split the tarballs into 3 GB +files. Two reasons: + +1. They can fit on FAT32 (so, flash drives usually) without further + actions; +2. Some "cloud" storages seem to have a problem with large files; + +And after all that, I set up yet another cronjob: + +$ crontab -e +... +30 2 * * * cd /data/aa/snap && make clean rclone + + +Bitcoin + +I've been using bitcoin since 2022, when I was banned from paying for +my domain name and my server via a bank card as a punishment for +other people's crimes. All this time I did so through bitcoin-qt +without much understanding what it actually does. After trying to +read the documentation I am still not entirely sure. Bitcoin, I +should note, is more of business software that good software. +Consider for instance that several initial releases were for +microsoft only. Unfortunately, the alternatives are less usable. + +The bitcoind configuration is in the following format: + +# comment +cli-option-without-initial-dash=value + +We only really need to modify datadir to be somewhere under /data/: + +$ cat >~/.bitcoin/bitcoin.conf </mnt/secret +# umount /mnt +# bioctl -d sd4 +# # to make sure it works, plug the stick out and in again +# bioctl -c C -l sd3a softraid0 +# mount /dev/sd4a /mnt +# cat /mnt/secret +secret + +It worked! The rest is a simple matter of "cp -r". blob - 795c5dfc76e6d2906727de3d24e139ebb21dfb81 (mode 644) blob + /dev/null --- art/mail.txt +++ /dev/null @@ -1,210 +0,0 @@ -Over what must have been more than a year I've read a lot of RFCs, -had a lot of experience and put a lot of thought into mailing. This -is the third version of this article. Most articles on setting up a -mail system have their readers do a lot of work with the latter -ending up with a complex monstrosity they do not understand. My -system is dead-simple and easy to extend within limitations of a -small server. - -The entire mailing system of ours shall consist of the following: -OpenBSD (though we only *really* need OpenSMTPD, which I hear has -been ported), ssh and your favourite mail client & operating system. -That's it! Not even a POP server! - -One thing I didn't bother doing this time is dkim. At the bottom are -my old instructions on setting dkim up (section DKIM): they shall not -be maintained too much. - - -BLACKLISTS - -In the world of email, and spam, and housewife-targeting -bitcoin-miners there are a lot of blacklists that many servers adhere -to. Most of those are run by crooks, however it is still important to -check if your IP address is in one. So, before anything else, paste -it into a [blacklist checker], and request a different address should -that one be spoiled. - - -DNS - -We are interested in the following: A, AAAA, MX, PTR (i.e. rDNS), and -a couple of TXT ones (spf and dmarc). PTR is set up by the network -block owner (usually same as ISP) and should be the same as HELO that -the server will send (the server's FQDN). Virtual host providers -usually have a web-form for setting up PTR. Otherwise you'll have to -actually request it being changed by talking to people. - -Others are set up as usual. In the end something like this should -suffice: - - example.com. 600 IN A 1.2.3.4 - example.com. 600 IN MX 0 example.com - example.com. 600 IN TXT "v=spf1 a mx ip4:1.2.3.4 ~all" - _dmarc.example.com. 600 IN TXT "v=DMARC1; p=none" - -Add ipv6 if you can as well. - - -SMTPD - -Firstly we shall get a key and a cert (which will be self-signed): - - openssl genrsa -out /etc/ssl/private/example.com.key 4096 - openssl req -new -x509 -key /etc/ssl/private/example.com.key \ - -out /etc/ssl/example.com.crt -days 365 - chmod 600 /etc/ssl/example.com.crt - chmod 600 /etc/ssl/private/example.com.key - -And automatically renew it with the following crontab: - - 0 0 1 */6 * opnssl x509 -in /etc/ssl/example.com.crt -signkey /etc/ssl/private/example.com.key -out /etc/ssl/example.com.crt -days 365 && chmod 600 /etc/ssl/manpager.com.crt - -And, yes, the certificate is 600, please refer to smtpd.conf(5) for -actual docs, this is just a small example. - -Some people might also say that I should here use a CA-signed cert. -Well, no, not really, there are unlikely to be any problems: I -haven't experienced any and I force tls. Funny thing about mail is -that there are all sorts of crazy set-ups, where it bounces between -ten different not-really-trusted servers in-between the sender and -the actual target. In the end who knows if there'll be an appropriate -cert at the penultimate hop? So, we are lucky to have any encryption -at all! This is why the validity of the certs is usually only checked -in the purely-internal scenarios by the vast majority of SMTP servers -out there (and the ones that are more strict are probably -misconfigured!). - -Speaking of which, here's /etc/mail/smtpd.conf itself: - - pki example.com cert "/etc/ssl/example.com.crt" - pki example.com key "/etc/ssl/private/example.com.key" - - table aliases file:/etc/mail/aliases - - smtp sub-addr-delim "_" - - listen on lo - listen on egress tls-require pki example.com - - action "local" maildir "%{user.directory}/mail" alias - action "in" maildir "%{user.directory}/mail" - action "out" relay tls no-verify pki example.com - - match from local for local action "local" - match from any for domain example.com ! rcpt-to root action "in" - match from local for any action "out" - -Do, by the way take a look at aliases: you might, for instance, want -local mail to root to arrive to another user instead. - -Set up thus, our server will refuse to talk with others over -plain-text, meaning less spam. If that bothers you, read the mans (or -just remove "tls-require"). And no, the server doesn't handle -authentication: that is done with ssh below. - - -SPAM? - -You might have noticed that we are not running any spam-filters on -the server itself (other that denying external mail to root). You -might have also noticed that I introduced the mysterious line -`smtp sub-addr-delim "_"'. This line is responsible for the vast -majority of spam-filtering anyone will ever need. With this mail to -alexander@example.com, alexander_smith@example.com and -alexander_alexander@example.com arrive to the same user alexander, -while the assholes of the internets are none the wiser because -underscore is a character commonly used for actual usernames, but not -subaddresses. Now, simply use different subaddresses for different -purposes, and perhaps employ some subaddress-based whitelist with -procmail or something like that. - -Beyond that, however, there is spamd and rspamd, which also contain -interesting stuff like spam traps, or denying mail with bad helo &c. -Just don't use those horrible blacklists, please! - - -CLIENT - -This section used to contain my set-up for the set of maildir -utilities mblaze, but that proved to be too much of a moving target. -I therefore leave most of the MUA set-up up to the reader, and only -describe the way of emulating an MDA and MTA with ssh. - -To get mail, create a script, say, "msync": - - #!/bin/sh - - while :; do - cd $HOME && - scp -r user@example.com:mail/new/ mail/ 2>/dev/null && - find mail/new -type f -exec \ - ssh user@example.com rm {} + 2>/dev/null - sleep 3600 - done - -It may be called automatically from, e.g., ~/.profile: - - while :; do - ps xo args | grep -q msync$ || msync - sleep 10 - done >/dev/null 2>&1 & - -Some shells know what a maildir is, and if you set the variable $MAIL -to the path to you maildir, they will notify of your mail. Otherwise -you may put something like this in you, e.g., ~/.kshrc: - - ls $HOME/mail/new/* >/dev/null 2>&1 && echo You have mail. - -And sending mail is as simple as creating this script: - - #!/bin/sh - - ssh user@example.com sendmail "$@" - -Now either call it "sendmail" and put it in your $PATH so that it is -found before the actual sendmail (if any), or configure your MUA to -use this script instead of sendmail. - - -DKIM - -If you take this set-up and go to mail-tester.com, you are likely to -get 9/10 with -1 being for DKIM. It means that the absolute vast -majority of mail servers in the entire world will accept you mail. If -you still want dkim, do the following on your server: - - pkg_add opensmtpd-filter-dkimsign - mkdir -p /etc/mail/dkim - doas -u _dkimsign openssl genrsa -out /etc/mail/dkim/private.rsa.key 1024 - openssl rsa -in /etc/mail/dkim/private.rsa.key -pubout - -Add the following DNS record: - - ._domainkey.example.com. 680 IN TXT "v=DKIM1;p=" - - can be any string and is the one that we just -printed printed (it'll be over several lines, make sure to paste -it all without whitespace). - -Finally, add this to /etc/smtpd.conf - - filter "dkimsign_rsa" proc-exec "filter-dkimsign -d example.com -s \ - -k /etc/mail/dkim/private.rsa.key" user _dkimsign group _dkimsign - listen on socket filter "dkimsign_rsa" - -Of, course, make same here as it is in the records. - -This *should* do it, but I give no promises. If you want the key to -have more than 1024 bits, you'll also need to spread the selector -across several strings in the DNS records. And even with 1024 you -might have to do it. I don't even know. - - -REFERENCES - -[blacklist checker] https://mxtoolbox.com/blacklists.aspx - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + 9dd9eda4fd2a4f90bd278852e6246ec488baa553 (mode 644) --- /dev/null +++ art/008.use_rrsync.txt @@ -0,0 +1,71 @@ +Recently (perhaps 2-3 months before writing this) I automated my +backups, replacing the previous manual arrangement. Some of the files +I need to backup are on a remote server, so there's been a small +challenge of setting up ssh in a way that is restricted, yet usable +to automated tools. + +My initial solution was the obvious one: set up a special user, who +is permitted to "doas rsync" without a password. That's still a bit +dangerous, however, since it gives that user write access to the +entire file system. + +Well, it turns out that a more correct solution is already +distributed with rsync! rrsync is a python script, which: + +1. sanitises the rsync server command, according to options; +2. changes directory before running the command; + +So, for instance, if you want a certain key to only be able to read +the /var directory via rsync, all you need to do is add the following +to your authorized_keys: + +rescrict,command="/usr/bin/doas /usr/local/bin/rsync -ro /var" KEYTYPE KEY COMMENT + +and the following to doas.conf: + +permin nopass setenv { SSH_ORIGINAL_COMMAND } :backup cmd /usr/local/bin/rrsync args -ro /var + +Of course, your remote user will need to be in the backup group, and +if you use sudo instead of doas, you'll need to configure it +differently. + +Also note, that to, e.g., list files under host:/var with that key, +you now need to invoke rsync as + +$ rsync -e 'ssh -i /path/to/key' host:./ + +If instead of host:./ you write host:/var/, rrsync will simply refuse +to serve you. For instance, in rsnapshot.conf you may now have a line +like this: + +backup host:./ host/var/ +ssh_args=-i/root/.ssh/id_rsa.host:var + + +WARNING ABOUT SSH-AGENT + +There is a huge caveat with ssh-agent and such setup (I may have had +to restore one of my backups after realising it :). Imagine you have +a script like this: + +#!/bin/sh + +rsync -rpt --remove-source-files \ + -e "ssh -i $HOME/.ssh/id_rsa.nopass" "$@" host:./ /some/path/ + +Now imagine that this script is usually invoked via cron, but +occasionally you invoke it by hand. Imagine further that one time as +you do, ssh-agent has already cached your normal password-protected +key for running arbitrary commands. Well, you just nuked your remote +~! Even in spite of -i! + +Maybe there's something in ssh_config to prevent it, but it's also +simple to fix by unsetting SSH_AGENT_PID and SSH_AUTH_SOCK like so: + +#!/bin/sh + +unset SSH_AGENT_PID SSH_AUTH_SOCK + +rsync -rpt --remove-source-files \ + -e "ssh -i $HOME/.ssh/id_rsa.nopass" "$@" host:./ /some/path/ + +Now this script will get restricted with rrsync every time. blob - 08d87aed534e4ddc9cc6fd72edccee4ef02c6929 (mode 644) blob + /dev/null --- art/oldgames.txt +++ /dev/null @@ -1,255 +0,0 @@ -I can name a few modern games that I thought were quite good. Most of -them, however, aren't. I have, however, played of quite a lot of -older games that are way better than anything that's being spat out -into Steam nowadays. The best way to play most of these games would -be by getting them from GOG, or sailing the Seven Seas should that -option no longer be available, as it is in some cases. Note that this -list will only contain games that I still regard to be commercial. -For the free games see my other article [free]. - -Just as the [free] list, this one will most likely be expanded in -the future, as I find that I play a lot less games now than I used -to, but when I do, it is usually something classical or libre. - - -FALLOUT 1 & 2 - -Once my sole two favourite games. They still hold a very special -place for me. - -Before we go further, I should note that I am far from the only -person that noticed the two games' genius, which in the world of -commercial games unfortunately means that the thing became a -"franchise." "Franchise" is one of these strange words like -"commerce," whose literal definitions are completely neutral, but -whose responsibility for the sorry state of the world we live in -becomes apparent, once we examine how it is used in the context of -pseudo-propriety -- one that is immaterial, and only exists due to -the spread of some silly legal notions from Victorian Britain. And -in the context the meaning is following: a great many of -barely-related mediocre products are being inhumanly overprice -through the tactic of putting the word "Fallout" in the name and -changing the font. - -As far as Fallout goes, I however, am interested mostly in the real -thing -- the first and second games. Of course, that is not to say -that there weren't any other games unfortunate enough to find -themselves part of a franchise that weren't all that bad. I actually -quite enjoyed Tactics and 3 the first time through, and completed -New Vegas many times, as it does constitute a bit more that some -surface relation with the thing it's named after combined with the -desire to sell. However, even the latter fails to bring the same -feelings as I have about the originals. - -Now to my mind, Fallout is one of the few games that I became -attached to for reasons other than interesting gameplay. Rather I -have to say that the gameplay is not marvellous safe for one or two -qualities. Rather it is unique because every time I play I find -myself sucked into the illusion of controlling a character living in -a real world. That's not to say it at all makes sense! the plots for -both the main quest and the side-quests are rather basic, even the -most well-understood areas of physics are constantly contradicted and -there is quite a bit of paranormal along with the fourth wall breaks. -(and no, the second game is not the only one that suffers from it!) -However, once those things are dismissed, one does begin to -appreciate how this world functions: visiting each settlement, the -player discovers that just like the human settlements it does have -an economy, law, crime, science, culture, infrastructure and all the -other features of human settlements, however brutal and primitive at -times. The player further discovers that all those settlements are -interconnected: in the first game there is already a lot of trade and -some warfare going on, and in the second many settlements form -polities, and so often establish the more political relationships. -In all that, the player's character is not a mere observant, but a -participant: the fate of many such societies depends on the player's -actions, and sometimes the same decision alters the history of -several. - -The gameplay, as I alluded, is not crazy, but it's not all that -terrible either. It all starts with building the character. When I -first played I was probably very impressed by the amount of different -specialisations my character could take. Now, however, I know that -there is a large part of these choices that is completely useless and -never comes up. Still, what does come up does so frequently and -allows the player to solve the quests he or she is given in many new -ways, usually the expected ones. There are also some things that -don't require any special input of in-game experience points, but -rather that of the player's attention. There are many options for -instance where wearing different clothes might result in different -reactions from the characters, or there are quite a few things that -can be solved with explosives. - -And then there is also combat, which many people seem to not enjoy -that much, but in spite of it being clunky on the surface, I do think -that it is a bit more nuanced than people give it due. Largely this -is because Fallout might be the only game I've played where missing -is made fun. Misfired shots have a great possibility of landing on -another target. Allies are often killed by accident. There are the -critical misses where the unfortunate character may drop his weapon, -hit himself (to the death, possibly), or maim one of his limbs. -Overall, combat in Fallout is not very technically impressive, but -it is definitely not boring. - - -DEUS EX - -Deus Ex is yet another game that had the misfortune of becoming a -franchise. I think only of the first two games to be much enjoyable -(even though many will disagree with me on the second), and only the -original to be worth returning to. - -I consider Deus Ex to be one of the best designed games I've ever -played. It differs from most games -- even the other "immersive sims" -I've played in that instead of presenting the player with a set of -options on how to solve a particular problem, but instead presents -him or her with a set of instruments and asks the player to instead -figure just it out, whichever way seems to be the best. What's even -more interesting is that each time this set of tools will be -different not only because the player will find different general -items and invest into different skills, but also because unlike with -most such games, levelling is not done entirely through the experience -points. That is, in addition to the more traditional skills, there -are also nano-augmentations (i.e. with nanites), which are much more -interesting than normal skills, as they essentially give the -protagonist super-powers. There is, however, a catch: the set of -augmentations that the player will be able to take depends entirely -on the augmentation-canisters that he will be able to find. Many such -canisters are also applied to the same part of body, limiting the set -still further. All of it makes each playthrough actually unique even -in spite the seemingly linear plot and set of missions. - - -ARCANUM: OF STEAMWORKS AND MAGICK OBSCURA - -After the first Fallout was released, some of the main people that -worked on it had some disagreements on what Fallout 2 should be like, -so they left to create their own studio named "Troika Games," and -quite aptly proceeded to make three games before running out of -money. The other two are somewhat interesting as well, but their -first project Arcanum is what really impressed me. If I were to -describe the game in one sentence, I'd say something along the lines -of "A bigger Fallout in a different setting and without the -misfortune of becoming a franchise." - -So, the first point is that the game is much bigger than Fallout. By -that I mean that the world-map is huge and has more than a few -locations that are never pointed out, which the player can only find -by randomly coming across them. Another thing that I mean is that the -local maps are now so great that there is even a special mechanic that -allows the player to place waypoints and allow the character to -automatically follow them. I should say that normally I would -consider this to be a sign of bad things to come, as such huge maps -are usually only so huge because they are filled with void. Somehow, -however, Troika has managed to avoid this trap, and instead make the -world both grand and interesting at the same time. - -Then there is the setting. I usually don't talk much about settings -in anything, as there is mostly not much to talk about. And I -specifically dislike that vile notion of "lores." I mean, supposedly -the word used to mean something, and if one opens a dictionary, one -could probably still find a sensible definition, but at this point -the mere utterance of the word makes my brain go into the automatic -mode for half an hour. In spite of that, I do think that what Arcanum -presents is a rather unique setting, not found elsewhere, and is -worth at least mentioning. Like the name suggests, the game is set in -a Tolkienite world during an industrial revolution. Even in real life -the industrial revolution was a strange time: technological marvels -and definite improvements in some areas of life went side-by-side -with pseudoscience, destruction and radicalism that plague mankind -to this very day. Strangely enough, a fantasy setting seems to be -ideal for highlighting those issues: our pseudoscience actually has -some backing in Arcanum, but is it right to act on it? Entire -civilisations are being destroyed in pursuit of questionable goals. -Senseless bickering between the traditional magicians and the more -progressive technologist leaves no room for cooperation and -co-existence. - -Finally there is the gameplay. It's mostly fine. The -character-building shows that the game is made by the same people -that made Fallout, and it works very well. Combat on the other hand -is pretty terrible. And there are also a lot of things that can only -be done through some badly-thought-out keyboard shortcuts that cannot -be reassigned to something more sensible. - - -THE WITCHER 1 - -When people talk about the witcher games, it's usually about the -second or the third game (or the fourth one, which I hear is being -developed). Neither of those, however ever interested me too much. -The Witcher 1 on the other hand seems to be a game that people have -to "force" themselves to play. I never experienced such problems, but -my idea of a good game is quite different. - -And the game really is very strange. I've heard once it being -described as a game that can be completed with one toe on the -keyboard, and that is not too far from the truth either. Gameplay, -however, is not what attracted me to this game so much. Strangely -enough, it was the writing. I do say that it is strange, and that is -because I found that most people who spend their time "seriously" -discussing the quality of writing in games are mostly the sort of -ignoramuses that don't ever take time to read a book. Thus in most -cases when I discuss writing in a game, I merely say that it is good -for a game, and proceed to the more important parts. The Witcher 1, -however, is the only game about which I can say that I found the -writing to be pretty solid in the general sense -- definitely more -solid than 90% of film-writing, and people are somehow enjoying that! -Indeed, the writing was so more than passable that it was much thanks -to the game that I actually looked into the books, which were to this -day the only piece of literature that I didn't regret reading in -translation. - - -TOMB RAIDER 1-5 - -Tomb Raider is another game I liked mostly due to the very good -gameplay. And it did manage to produce 5 good games, which is pretty -impressive. Unfortunately, the games beyond that are barely at all -related and aren't very much worth playing. - -The games' gameplay consists primarily of the three activities: -solving puzzles, jumping around places and shooting things. I'll -start with the jumping around because platforming is not what I -generally enjoy in games: usually the activity is either very -RNG-dependant, which makes it very frustrating, or very automated -to the point where it feels that the player's input almost doesn't -matter at all. Tomb Raiders avoid that by making every move Lara (the -protagonist is one lady Lara Croft for those that lived in the woods -for the past several decades) makes extremely predictable. -Platforming in Tomb Raider does require careful planning, attention, -precision and timing, but no luck, which is how I grew to like it. - -Puzzles are, I'd say, mostly pretty decent. There were a few that -were simpler to brute-force than to come up with a "real" solution, -a few whose logic didn't make much sense, and a few rather -frustrating ones where Lara has to escape some labyrinth by pushing -blocks, while being completely blind to the maze's general structure, -but those were in the minority. - -Shooting is quite honestly pretty bad. For me at least most of the -shooting involved holding down control (shoot) and alt (jump), while -pressing left and right alternatively so that Lara would sideflip -instead of jumping vertically, still facing the enemy, but avoiding -some of the attacks. There were, however, some improvements in the -fourth and fifth games, as they presented both some weapons and some -enemies with the more unique behaviour that required a different -approach. - -Of all the five the first was probably the best game: just the right -amount of platforming and puzzling with being assaulted by -(near-)extinct animals in-between. Unfortunately, of the remaining -only the fourth once again capitalised on that idea with the fifth -consisting of rather diverse "mini-campaigns," which are also very -enjoyable. My opinion on the second and third is a bit more mixed: -both are very well made, but still shift the focus away from puzzling -and platforming in the direction of shooting various mafiosos and the -like. And shooting is by far the worst of the three chief activities! - - -REFERENCES - -[free] gopher://manpager.net/0/art/free.txt - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + a7b7bfa15cc9f1acded702cb097423844f4bc3a8 (mode 644) --- /dev/null +++ art/009.keyboard_setup.txt @@ -0,0 +1,77 @@ +Ever since I installed Unix for the first time I've been on a +constant quest to configure my keyboard as I wanted it, namely: + +- set up the Dvorak layout; +- make super/menu/whatever useless bottom keys additional + alts/controls; +- make caps an additional escape; +- make the extra ISO key do something useful; +- switch between English and Russian on scroll lock; + +Well, I'd still like to get a better board one day, but at least I +now have the software where I want it to be, and there is no xmodmap +trickery! I also managed to configure it like that on the TTY, but +that's OpenBSD-specific, and on different systems you'll have to +configure the TTY differently. Sorry! + + +COMPOSE + +Have you ever wondered how do you input all those weird post-Romance +letters like ö, ç and ñ? Or fancy unicode characters like ° (as in +°C)? For a long time my method has been to simply copy-paste them +from somewhere. Then I discovered the "compose" key: you press +"compose", and two or more other keys in sequence, and get just some +such characters. For instance: + +compose + ` + e = è + +The precice table of compose sequences will depend on the program. +For instance there are such tables for X11, the TTY, and, for +whatever reason, GTK. For X11 at least you can look them up in a path +like /usr/X11R6/share/X11/locale/en_US.UTF-8/Compose. The initial +part of this path will differ between systems, but I am sure you'll +find something if you just type `find / -name Compose 2>/dev/null'. + +This is the perfect keysym to put on the extra ISO key. + + +X11 + +First type `man xkeyboard-config setxkbmap'. xkeyboard-config(7) is +rather badly formatted, so you may have to expand your xterm a bit. + +Well, it's pretty simple beyond that, just use the options you need, +for instance: + +setxkbmap -option # reset options +setxkbmap -layout 'us(dvorak),ru' \ + -option grp:sclk_toggle \ + -option grp_led:scroll \ + -option caps:escape + -option altwin:alt_win \ + -option ctrl:menu_rctrl \ + -option terminate:ctrl_alt_cksp \ + -option compose:102 + +In my particular case, the usual layout-switching via the grp:* +option seems to work poorly for some reason, so I use the [xrus] +program. It says it's for Russian-English switching specifically, +but I think it should work with other languages as well. + + +TTY (OpenBSD) + +The definitions are in the file /usr/include/dev/wscons/wsksymdef.h. +And the manuals are wsconsctl(8) and wsconsctl.conf(5). For instance, +here's what I have in /etc/wsconsctl.conf: + +keyboard1.encoding=us.dvorak +keyboard1.map+='keycode 100 = Multi_key' +keyboard1.map+='keysym Caps_Lock = Escape' +keyboard1.map+='keysym Menu = Control_R' +keyboard1.map+='keysym Meta_L = Alt_L' +keyboard1.map+='keysym Meta_R = Alt_R' + + +[xrus] http://lav.yar.ru/download/xruskb/ blob - a6c15b8f507312f48e403fb0512debe7937833c6 (mode 644) blob + /dev/null --- art/passwd.txt +++ /dev/null @@ -1,85 +0,0 @@ -Most of this document is a long version of the -"correct horse battery staple" [comic]. There are some more -interesting observations towards the end. - -The strength of a passphrase does not derive from it having at least -one letter, one digit and one special character, but from something -called "entropy". "Entropy" is this mysterious concept that my -professors kept telling me about, all the while I would wonder "what -is an entropy?". In our case we are dealing with "more is better" and -the formula - - E = log_2(R^L) - -where E is entropy, R is the size of the dictionary (a rather -offputting term, see below) and L is the length of the password. I -won't be telling how much entropy is needed for a good password: -calculate that yourself. That formula works if passphrases are -generated by taking random words from the dictionary. If your -password is your birthday, the entropy is 1 because the passphrase is -cracked by answering the question "is it the owner's birthday?". - -"Word" here is simply the smallest unit we are dealing with, while a -dictionary is a list of unique words. English alphabet is a -dictionary of single-byte words. - -There are several ways the vast majority of people make passwords in -practice: they either use something very simple like their birthday, -or they use something very hard to remember, yet easy to crack. This -is further promoted by many sites refusing to take passwords with -more than e.g. 20 characters &c. The readers may be surprised to read -from me that the issue lies not with the fact of using such weak -passwords on its own: unless the attacker has physical access to a -device, he is usually limited to "n tries per t time". The real -issues begin with man's faulty memory. Firstly such lack of -methodology leads to passwords being easily forgotten, which is just -horrible; secondly, people like this tend to use the same password -for everything. This means that should one service's security turn -out to be less-than-optimal (it usually is), all of the other -accounts become compromised as well. - -And quite simply because I am quite tired of hearing stuff like "They -wouldn't get anything important anyway": no, "they" bloody will, -unless you consider your bank information, personal information and -the ability to be the only one to write messages from your name to be -unimportant. - -The solution is to randomly generate passwords, and then store and -retrieve them using a password manager. There are generally two kinds -of such passwords: strings of randomly-generated bytes from something -like [A-Za-z0-9] and sequences of randomly-generated words. I -strongly prefer the latter, as they may be typed by looking at them -even when clipboard is unavailable. - -Then there is of course the issue of setting up one or more "master" -passwords. Generally the following _have_ to be memorised: password -to a normal user on the system, password to the root user, the -password to the password-manager and passphrases to ssh &c. Since it -all really ought to be done entirely locally on a single-user system -(if it isn't, start panicking), there is not much danger in setting -them to be the same thing. It does, however, have to be something -strong, memorable and not too complicated to type. One option is to -generate a passphrase via a normal method and simply memorise it (or -write it down, unless you live with people you don't trust -unconditionally). Another method is to make up a few words, not tell -anyone about the fact and use those. - -And now since I mentioned the ssh passphrases, I'd like to also state -that yes, ssh keys should have passphrases. A possible exception are -the keys used for things like backups. This should instead be -restricted to certain users and/or commands. A concern some people -might have is that it could hurt automation. I say not nearly as much -as people think. Executing ssh-agent and ssh-add at every login does -mean typing password twice, but it also means that all those scripts -could still be run, provided they are started afterwards in the same -session. OpenBSD's xenodm is already set to run the necessary. On -platforms that use startx, a wrapper would be simple to write. Other -DMs should have such functionality (or they should be avoided -otherwise). If not starting X at all, then executing it from -~/.profile or similar file is even simpler. - -[comic] https://xkcd.com/936/ - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - ebc58190ea5364609f252c88cf6de741cb8c0eb7 (mode 644) blob + /dev/null --- art/revolution.txt +++ /dev/null @@ -1,89 +0,0 @@ -Revolution Software has made a few interesting games, some of which -I played. I think I might have played Broken Sword once as a child, -but more thoroughly I familiarised myself with them only much later -beginning a bit before I started writing my bachelor's diploma and -ending some time later (I think at least). My recollections of them -are a bit hazy now that some months have passed, but I'll try to give -at least a brief overview of my thoughts about the games. - -So, what's so interesting about these games? Well, not they -themselves: I found them to be rather forgettable, actually. What's -more interesting is that four of them: Lure of the Temptress, Beneath -a Steel Sky & Broken Sword 1 & 2 can be played via ScummVM, which is -an open-source engine for many adventure games. More interestingly, -the first two (not "Swords" unfortunately) have their data files -distributed gratis for non-commercial purposes as well. It's a shame -the original engines never got open-sourced, but from the other angle -this can be viewed as "better than Doom", which still can't be played -without either buying the necessary data, or sharing it. - -As for the reason why they are so forgettable, consider that there -are generally two types of games: the more classical ones not unlike -adventure(6) itself, which give the player some game rules and set -him loose to figure it all out for himself, and the games which try -to be films. Most of the latter adventure-games, including the ones -by Revolution are in the latter category. I very rarely watch films, -and when I do it's mostly Monty Python or something. The reason is -that unlike books or any "interactive" activities films do not -require intellectual involvement, instead they promote staleness of -the mind: they are very much like sleeping without actually getting -the benefits of doing so. The "game-films" are slightly better in -this aspect, as they do require at least some involvement from the -player. Furthermore the "adventure-games" are even better off in this -aspect, as the player is usually required to perform some creative -thinking in order to solve the game's puzzles, rather than to do -something mechanical. Still, the majority of it has been arranged by -the "director" and the player is the "audience". - -Oh, well, here go the games themselves. - - -LURE OF THE TEMPTRESS - -I don't really think much of this game and the reasons I dislike it -seem to align exactly with the features it was marketed for, which is -hilarious. - -So, firstly, almost none of the characters ever remain in a -predictable position, instead they go around the entire map in a -randomised manner. This makes it an unnecessarily hard job to find -the one, which has to be talked to in order to progress the -storyline. This is worsened further by the fact that at times the -player is not given so much as a clue on what to do next, and so he -has to talk to every character in the game in order to find out. That -last deficiency is also combined with the fact several times -throughout the game things simply happen without the player being -given a hint, like a door that was closed the majority of the time -suddenly opening for no reason in particular. - -My last grudge is the UI. "Temptress" was one of the earliest games -to use an entirely mouse-based interface, yet just like all those -graphical file-managers it did so relying on the textual idioms. -Basically the player often has to find-and-click a single verb from -a couple dozen and then do the same with nouns. The vast majority are -quite simply unused. - -Oh, well, I suppose the characters and graphics are charming. - - -BENEATH A STEEL SKY - -Now, this is a much better game. I'll say as much: of all the -adventure games I've played only this one made any sense. Clues are -simple enough to come by and the solution that follows mostly makes -sense. Things don't just happen off-screen and there aren't many -one-off mechanics. Very solid. - - -BROKEN SWORD 1 & 2 - -These games people are probably more familiar with than the other -two. Personally, I liked "Sky" more. It seems that people generally -find more problems with the game's puzzles than I did, which is as -much as can be said for the gameplay. They did make some good work on -the animations, so well done there. Other than that, however, I found -the games to be pretty average. - - -Copyright (c) 2023 Alexander Arkhipov -Licensed under CC BY (https://creativecommons.org/licenses/by/4.0) blob - /dev/null blob + bbc3411176c21a917ca5ddda70fc12fc5c8c492a (mode 644) --- /dev/null +++ gopher.exclude @@ -0,0 +1,2 @@ +*.html +*.css blob - 00282c512bd99ed4fe5860873905628e74ea8775 blob + 07ce61d4932ca360c237c45a3b6603f3e019786f --- gallery.html +++ gallery.html @@ -31,6 +31,18 @@
my books
+ + + + + Xlib programming manual +
2023-07-11
+ + + + blob - c40bf522a15ac00c73cb171c1534a1c237fb1d9e blob + 4e88fd917e4a35fee503e4beba3dff1c9a77ddbf --- index.gph +++ index.gph @@ -1,7 +1,6 @@ -I am Alexander, the insane Unix hacker and owner of alearx.org. For -more information, please see the README file. +I am Alexander. I write programs. -[0|README|/README.txt|server|port] +[0|project|/project.txt|server|port] [1|articles|/art/|server|port] [0|plan|/plan.txt|server|port] blob - 3f4bc7b9caf10fdbdf7aa8a216d9106a71c33db4 blob + 487175f7ac6ca57e210a870d56f589b64d21b618 --- index.html +++ index.html @@ -3,22 +3,28 @@ Alexander Arkhipov's + -
-I am Alexander, the insane Unix hacker and owner of alearx.org. For
-more information, please see the README file.
+

I am Alexander. I write programs.

-README - -articles -plan -feed -news -ftp -git -gallery - -links -
+
+ +
+ +
+ +
blob - /dev/null blob + f60deceac67ecb6d4768a41df474ad32ea1a2080 (mode 644) --- /dev/null +++ plan.txt @@ -0,0 +1,20 @@ +Entry: 2023-11-06 + +Given the error margin of 24 hours, it's been precicely 3 months since I +last wrote here. You can't really tell, however, because among other +things I nuked the news/ directory and feed.ass file. The only news +source here now is .plan (and plan.txt). To see if I made any changes +you can do something like this: + +$ $some_cool_network_client "$@" | grep '^Entry: ' + +The art/ directory has been changed as well: I've updated and removed +some old articles, and changed the file names like so: + +000.the_first_file.txt +001.the_second_file.txt + +The ordering is somewhat arbitrary now, because I don't remember what +order I actually wrote them in. Also, this scheme totally fails if I +end up writing more than 1000 of those, but in such case I will have +to start using several directories anyway. blob - /dev/null blob + bc5fbef2307b9ea1d7d87e54bad2118b44d95f6a (mode 644) --- /dev/null +++ project.txt @@ -0,0 +1,19 @@ +You can send mail to aa at this domain. The PGP key is at +ftp://alearx.org/pub/pgp/ (and equivalent http, gopher and rsync +locations). + +Files are served via http, gopher, ftp, rsync and finger (try +`finger aa@alearx.org'). + +I live in Moscow. + +I speak Russian and English. I also speak some German, French and +Esperanto. + +Currently I am spending most of my free time learning French. When I +think I speak sufficiently well, I think of either continuing with +some other human language, or learning lisp. + +In my enslaved time (that's 6 to 17 from Monday to Friday) I'm working +as a researcher for the information security company Infotecs. I will +consider changing for some remote employment. blob - /dev/null blob + df4ce1014b47410d060669053240414cdb200c3a (mode 644) --- /dev/null +++ style.css @@ -0,0 +1 @@ +ul { list-style: none; } blob - /dev/null blob + 77c3fc631241a438e6422e33da7ce0c6f06ee9eb (mode 644) --- /dev/null +++ www.exclude @@ -0,0 +1 @@ +*.gph