commit - fc1c58374955659a8123bc6d4f81cfed4b9fb176
commit + 75241145fb911468749a83c11ee0404710a3c9d8
blob - fb20d8749e70fed1e49f68a1f4c6dfc9dead0cc6 (mode 644)
blob + /dev/null
--- .plan
+++ /dev/null
-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
-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
+*.exclude
+/git/***
+/pub/***
blob - 828bbbb360a5f737c51bbd1453122b189a31c8ef (mode 644)
blob + /dev/null
--- README.txt
+++ /dev/null
-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
-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 <aa@alearx.org>
-Licensed under CC BY (https://creativecommons.org/licenses/by/4.0)
blob - /dev/null
blob + bb25755e08aec6ecbe3a13f95667e04c4a8ff577 (mode 644)
--- /dev/null
+++ art/000.battlestar.txt
+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
-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 <aa@alearx.org>
-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
+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
-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:<hash>,sd1:<hash>,sd2:<hash>
-# echo <hash>.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 <hash>.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 <hash>.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 <hash>.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
- <n> = key expires in n days
- <n>w = key expires in n weeks
- <n>m = key expires in n months
- <n>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 <<x
-datadir=/data/aa/bitcoin
-walletdir=$HOME/.bitcoin/wallets
-x
-$ mv ~/.bitcoin /data/aa/bitcoin
-$ mkdir ~/.bitcoin
-$ mv /data/aa/bitcoin/bitcoin.conf ~/.bitcoin/
-$ mv /data/aa/bitcoin/wallets ~/.bitcoin/
-
-bitcoind is the server and bitcoin-cli is the client. The latter has
-two sets of documentation (and some nonsense *.md files under
-/usr/local/share/doc/bitcoin/ that I refuse to consider such), both
-of which are pretty bad:
-
-1. First is command-line options documentation. Type either
- "bitcoin-cli -?" or "man bitcoin-cli". Most of them are not
- very useful.
-2. The API documentation, accessible by typing
- "bitcoin-cli help [command]".
-
-Considering I don't need to automate it, the actual usage is very
-easy. The subcommands "send", "listunspend" and "getaddress" are
-the majority of what I need.
-
-Let's leave bitcoin-cli for later, and instead just download the
-blockchain.
-
-Firstly I actually opened bitcoin-qt, and disabled pruning -- it's
-been enabled through the GUI originally, so it only made sense to
-disable it this way. Turns out it just changed my
-/data/aa/bitcoin/settings.json to have '"prune": "0"' and
-'"prune-prev": "1907"'.
-
-Afterwards, I closed the GUI, and instead typed "bitcoind -reindex"
-and went to sleep. Wakefully, I made some calculations based on the
-progress thus far, and realised that the entire blockchain is a
-little under 500 GB! Straight after, I killed the daemon and
-restarted it with "prune=131072" in bitcoin.conf. Perhaps I should
-get an HDD just for bitcoin? It could as well be external since I'd
-only use it occasionally.
-
-Regardless, I at last deleted the bitcoin GUI along with the rest of
-qt:
-
-# pkg_delete bitcoin
-# pkg_add bitcoin--no_x11
-# pkg_delete -a
-
-
-Encrypted USB flash drive
-
-Right now my off-site backups rely on the fact that I have access to
-my private key and signer@'s public key. Of course I could just
-publish the latter, but the fact that my disc has my private key on
-it doesn't help at all in the event of its death. To deal with it I
-encrypted a USB flash drive, and used it to store the really
-important files/trees, such as ~/.ssh, ~/.gnupg, and ~/.bitcoin.
-Then the drive could be safely deposited at the office / friend's /
-aunt's / whatever.
-
-For OpenBSD the procedure is described quite well at
-https://www.openbsd.org/faq/faq14.html#softraidCrypto:
-
-# dd if=/dev/urandom of=/dev/rsd3c bs=1m
-# fdisk -iy sd3
-# disklabel -E sd3 # make an "a" partition of type RAID
-# bioctl -c C -l sd3a softraid0
-# dd if=/dev/zero of=/dev/sdc4c bs=1m count=1
-# fdisk -iy sd4
-# disklabel -E sd4 # make a normal "a" partition
-# newfs sd4a
-# mount /dev/sd4a /mnt
-# echo secret >/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 <aa@alearx.org>
-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
+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 <<x
+ cd $HOME
+ xauth -q remove $DISPLAY
+ echo $nlist | xauth -q nmerge -
+ exec fvwm
+x
+
+If you don't want to type the password each time, add the line
+
+permit nopass mainuser as anotheruser cmd /bin/sh args -l
+
+to doas.conf.
+
+Once you successfully execute this script, you'll get an Xephyr
+window with fvwm inside. You can use fvwm to launch xterm, and you
+can use xterm to launch firefox. To see how well things are
+isolated, try copying some text in one X session (either the normal
+one, or the one inside Xephyr), and pasting it in the other -- you
+should fail!
blob - d8be1fbb99686776d9caf795b940258fe83c4c08 (mode 644)
blob + /dev/null
--- art/fallout2.txt
+++ /dev/null
-I am quite partial to the games "fallout" 1 and 2, as I grew up
-playing mostly those and some strategy games. So I was very happy to
-find out one day that the second game has been mostly successfully
-reverse-engineered and ported to sdl as [fallout2-ce]. Whilst the
-memories are still fresh, I will here attempt to summarise my first
-experience with the port.
-
-
-INSTALLATION
-
-So, my first question was "ok, but does it compile on OpenBSD?" Well,
-it does. Quite well in fact. The project uses cmake, for which the
-author gets -15 karma. Initially compilation failed, I suspected some
-lacking linking flags to be the culprit. Googling a bit I found how
-to force cmake to actually print commands it uses, rather than just
-uselessly report errors, and found that just as I suspected the
-command lacked -L/usr/local/lib. It took me a bit more googling after
-which I found out that I can set this flag by running cmake with
--DCMAKE_EXE_LINKER_FLAGS=-L/usr/local/lib. There weren't any
-compilation errors afterwards and the game ran quite well after I put
-the binary into the game's root directory and launched it as
-`./fallout2-ce' (so the pwd is the game's directory).
-
-There turned out to be some problems with the data files then.
-Firstly I had to change f2_res.ini a bit so that the window does as
-little damage to my system as possible: I set WINDOWED to 1, and
-later SCR_WIDTH to 640 and SCR_HEIGHT to 480. There still were some
-problems with the mouse, however, to fix which I had to restart the
-game. Also I noticed that the music sometimes would play, and
-sometimes wouldn't. To fix that I made sure that all files and
-directories mentioned in fallout2.cfg are named exactly as they are
-mentioned there and also made four copies of all files in
-sound/music: all-lowercase, all-uppercase, upper before period and
-upper after period (e.g. 01hub.acm got copied to 01HUB.ACM, 01HUM.acm
-and 01hub.ACM). The reason being, of course that somehow caseless
-fopen is not yet implemented in this program. Also it later turned
-out that one of the maps in addition to mixing case randomly has a
-typo, so I copied 13carvrn.acm to 13carvrvn.acm. I vaguely remember
-there being no music in the area in the original, but I often skip
-Redding anyway, so perhaps its just a local "feature".
-
-
-NEW CHARACTER
-
-I played a jinxed character once on normal difficulty without
-investing much into armour class and ultimately ended up not liking
-it. This time I thought "but what if I play on easy and invest as
-much as possible into AC?" Well, this way it actually turned out to
-be pretty fun up to and including New Reno, but I rushed the rest of
-the game. The character was like this:
-
- age: 33
- gender: male
- name: Dr. Scar (after the lion king character)
- attributes: 1 luck and charisma, the rest is mostly even
- traits: jinxed, heavy bruiser
- tags: doctor (useful), lockpick (less useful), steal (which I
- thought to be funny)
-
-The idea is to get HtH evade and tag unarmed once it can be boosted
-to 300 thus. I decided that my character should be a somewhat chaotic
-force, neither strictly evil, nor very righteous: I'd for instance
-become a slaver, but would then help Modoc instead of slaughtering
-some innocent farmers.
-
-My disappointment was almost immediate, as I noticed that for some
-reason none of the giant ants ever seemed to crit miss, but they did
-crit hit for 0 damage quite a lot. Found the issue pretty quickly and
-spent the weekend reviewing the rest of the file. Fixed some other
-bug, sent the diff to the owner. Now my fixes are part of the engine.
-
-
-THE BEGINNING
-
-After that I decided to actually do Arroyo for once, instead of
-immediately wondering in the general direction of the GECK.
-Slaughtered a more-than-reasonable amount of the templar fauna and
-actually kicked Cameron's butt instead of stealing the key from him.
-I think I might have ended up poisoned with 1 health, however, so my
-next stop was Hakunin's tent. Attempted refusing the main quest, had
-to take it anyway, didn't respect the shaman, completed all local
-quests available to me, went east to Klamath.
-
-At Klamath I talked to Ardin: told her how sad I am about Smiley, but
-didn't offer to help. Instead went straight to "whisky" Bob, agreeing
-to refuel his still; immediately decided it was not worth it and sold
-him out to Sajag. Satisfied with myself I told Torr that I'll help
-him guard his cows. As soon as two suspicious-looking men offered me
-some cash to betray Torr as well, did that. Returning found out that
-Torr ran in the least convenient of directions (for him), so I
-decided to help him for more money; did just that. With my newfound
-wealth I exchanged some of that and half the junk from around the
-town for a suit of leather armour. Well-protected I went straight to
-the rat-infested part of town to one-hit-kill the rat king. I did, of
-course, take the fuel-thingy from the car, but later I decided to
-stash it in a container until I can actually use it. I quickly forgot
-which one, however, and never managed to install it.
-
-With that I went south to reach the Den. Immediately kicked all the
-local children's arses. Took Rebecca's and Lara's quests; tried to
-see what the traders have, but wasn't interested. "Got" Rebecca's
-money out of Fred, by having him promise to make me a rich man
-sometime in the future, but later I had so much money and so little
-to spend it on that I forgot about that completely. Found Rebecca's
-book. Tyler didn't to believe that I come from Metzger, so I put that
-quest off for now. Agreed to destroy Rebecca's still for Frankie. His
-whore demanded 1000$ from me, so instead I took "Mom's" quest and
-listened to Karl's story. In the slaver's guild I delivered the radio
-to Vic. After Metzger still demanded from me as much as that whore at
-the Hole, joined the guild instead. After completing the slave runs I
-bought Vic's freedom only to have the ungrateful bastard refuse to
-follow me. In-between the runs I returned Rebecca her book,
-immediately afterwards destroyed her still, delivered his (rather
-cold now, I think) dinner to Smitty, completed Lara's quests by
-getting Tyler so drunk he told me about his stupid party, and put a
-woman's ghost to rest by beating Joey the local punk to the death.
-With that I headed in the direction of the Vault City, skipping
-Modoc.
-
-I found very few bugs in this section; everything went quite
-smoothly.
-
-
-THE MIDDLE
-
-This is my favourite part of the game. There is quite a lot to do,
-usually with many possible solutions, but unlike some late-game
-locations these feel much more like real places, rather than game
-locations.
-
-Right, so, here is a very deep question to the writers: Valerie the
-mechanic of Vault City is a product of Vic fornicating with one of
-the female citizens of the city. Contrary to that fact, Phylis the
-nurse (or whatever she is) tells us that while the decades
-underground after a nuclear war have indeed made the people of the
-vault 8 devoid of marital morality, it may very well be due to the
-fact that radiation and incest have made them so sterile they are
-only able to procreate artificially. Now which one is it?
-
-Arriving to the city I immediately went to the greetings office in
-order to be very rude to both officers. After they no longer wished
-to talk with me I found a local child's stupid doll so he would tell
-me where I can find a wrench. I let my character internally curse Vic
-after he'd found out how unhelpful Ed is and proceeded to purchase
-advanced leather armour from the trader. I tried to fix the auto-doc,
-but failed.
-
-At the front gate I had attempted to get a day pass as a slaver,
-found out that I need to actually carry some "slaves" around for them
-to believe that, and instead bought a fake citizenship and, extorting
-my money back from the seller immediately after the purchase.
-Entering the city proper I immediately turned to the bar to get
-disappointed that they don't actually sell booze; sold the 20 bottles
-I just so happened to be carrying upon my person. At the repair
-"shop" I told Valerie to shut up because I already have the tools
-she needs. At the library I got some free books, read the declaration
-of the human rights, thought to myself "what sort of nonsense is it",
-told so to "Thomas Moore" (right, and then the king of Vault City
-becomes the head of the church and executes him as part of religious
-genocide) and took some quests from the city's military captain. At
-the council building I told Lynette that she was stupid for refusing
-to inspect my pyjamas, but agreed to do her dirty work so that I can
-get into the vault.
-
-Circling Gecko to complete the quest, I entered the town. At Gecko I
-discussed humour and games with the local tavern owner and spoke to
-Harold, Percy and Skeeter to take their quests. Went back to Vault
-City, took my repair kit from Valerie, reported to the security man
-and went back to Gecko with a hydroelectric magnetosphere regulator.
-Back at Gecko I simply exchanged the repair kit for the car fuel
-thingy and repaired the atomic station using the robot. Returning to
-the city I looted as much as I could from the vault (one of the doors
-got jammed and I decided not to reload) and found out about the vault
-15.
-
-It was somewhere during the previous two paragraphs that I discovered
-my horrible miscalculation. In the original you can delay picking a
-perk for as long as you care: if you don't take one at levels 3, 4
-and 5, you'll have 2 perks to pick at level 6. My plan has been to
-pick both tag and hth evade somewhere at levels 12-15. Well, it turns
-out that the feature got fixed in fallout2-ce: now if you keep
-adamantly refusing to pick a perk for 3 levels, you'll end up not
-receiving an extra pick. Later I also lost 1 perk by accident: I must
-have exited the character menu via the escape key rather than the
-"done" button and never noticed it because I decided to stockpile
-skill points for the next 3 levels.
-
-I turned west for the Den and decided to actually visit Modoc. I took
-Jo's quest, healed Bess' leg, had all of Grisham's cows saved, sold
-Bess to Grisham (of course, I never returned for the actual jerky),
-went down the well to steal a very minor amount of money. I broke
-down all of Rose's doors, bought an over-priced cookie from her, had
-her force-feed me with some cows' bollocks. In retaliation for that
-abuse I killed her "chicken". I told Cornelius I'll find his watch
-and proceeded to descend into the latrine-cave. There I found my
-first major bug: I can't remember ever dropping active dynamite in
-this cave at it not exploding immediately as I exit (in the original).
-Here, however, it would sometimes do the thing, and other times just
-keep being "active" in the unexploded cave. I had to reload several
-times. Finally I was able to tell Cornelius that Farrell stole his
-clock.
-
-At the ghost farm I immediately noticed that the "corpses" are
-dummies; after I have fallen through his floor, Vegeir confirmed the
-peaceful ways of the mole people. I went back to Jo, telling him how
-much of an idiot he and his fellow villagers (the game calls Modoc a
-"town", but I am not Yankee enough to call every settlement with 3
-families in it a "town") are. There was peace between the starving
-people and the mole people. I brought Jonny back to Balthas and
-continued towards the Den. There I found Woody, told Karl his
-compatriots decided to stop bullying him, got the car and got out. I
-must have been planning on returning to Gecko on my way back to
-Arroyo to complete the last quests there, but I never did.
-
-Instead for now I rode in the direction of Broken Hills. I actually
-thought of going to New Reno initially, but decided to actually get a
-power fist in Broken Hills first. It proved to be a prudent decision
-later. I thanked God when the zombie under my car told me that he
-isn't hurt, and just broken a few limbs. A horrible catastrophe
-avoided! I went straight to Eric to tell him the good news. Instead
-of rejoicing for my new friend, Eric kept complaining about cooling.
-I helped in exchange for some pills. According to his advice went to
-Francis. Used my skills acquired during my days as a slaver to offer
-him some "free" amphetamines, waited 10 minutes for the mutant to
-become weak and sluggish from withdrawal and ate doping myself. I
-must have paid the Olympic committee more bribes than Francis because
-they allowed me to walk away with a power fist. Talked to Marcus and
-Jacob, took all their quests, wondering in the meantime what to do
-with all these idiots. Brought a talking plant to the house of the
-old ghouls, did some tasks for Typhon, while outsmarting a very smart
-scorpion. Eventually found Typhon's stash of bottle caps, stole the
-porn mag back from him as a punishment and went into yet another set
-of lavatory-caves. There I discovered corpses of the missing people,
-described the scene in detail to a grieving husband, told Zaius that
-he is a terrible person and ordered Francis to leave the town. With
-my newfound knowledge that mutants *are* a thread of society I
-adopted racialism, rescued Mason and Franc from prison, told Zaius
-that I am going to fix his air purifier, actually blew it up. With
-the knowledge that now free of the international mutantry Broken
-Hills will grow into a great and powerful Broken Reich, colonising
-all the lands to the east, I left the town.
-
-As I arrived to New Reno I initiated dialogue with Jules just to tell
-him to shut up and instead looted Jesus Mordino's casino before
-taking a job from him. Now, here's another question: why does taking
-this job takes the player character straight to the "stables"? Can't
-it just mark those on the map? Anyway, the stables are pretty boring
-this time around. I just told Ramirez what a buffoon he is before
-delivering his poison and stole a few things from Myron. Back at New
-Reno I discovered that somebody stole my car. I'd verbally abused
-Jules until he showed me the place. I solved the situation by buying
-my own car back and getting it upgraded. After I reported back to
-Mordino he told me to get his tribute from the pornographers. The
-issue here is that for some reason those guys refuse to talk to
-slavers, who aren't also adopted by one of the bosses, or have kicked
-enough people at the boxing ring, so instead I took a quest from
-Mordino's rival Salvatore, stole batteries from him and his goons and
-started working on getting a more powerful unarmed weapon. The thing
-about it is that the "mega power" fist is not actually that much
-better than a normal one, but it is very tricky to get normally. So
-instead I decided to do what I don't do normally and get my weapons
-upgraded for free by the madmad beneath the New Reno arms. Once that
-was done I became a boxer, beat up all the other boxers, got the
-tribute from pornographers, delivered it to Mordino, completed all
-the Salvatore's quests, poisoned his air, killed all his goons,
-reported to Mordino and made him choke on nuka cola. After that I was
-still lacking one porn mag for miss Kitty, so I fornicated with mr.
-Bishop's wife, and robbed the family of their possessions.
-Unfortunately I was unable to disarm the trap on mr. Bishop's own
-safe, so I had to hide under his bed. I also wanted to plant my own
-trap on it, but found myself unable to do that either. In the end I
-just walked by Bishop back to his casino.
-
-This is another bug, actually. Walking two tiles past the door is
-supposed to trigger dialogue, out of which there'll be no escape
-other than through dozens of corpses or chickening out of the
-building. Well, it didn't. Another bug that I first noticed at New
-Reno, and which would become more and more annoying as the game
-progressed is that sometimes performing attacks or interacting with
-items would segfault the game (but not the other times, so it
-probably has to do with faulty (re)allocation, or randomness).
-
-At NCR I first and foremost talk to the local punk, who offered me to
-guard my car, in exchange for which I offered him a rude gesture. NCR
-is pretty weird. Entrance to NCR is a bit weird: it seems to be the
-only place in the world with a newly-build parking slot for cars.
-Just one. Actually some dialogue in fallout 2 would suggest that
-there are at least a few car-drivers in the area. How come it's not
-explored further? Anyway, what I gave the local bum 1000$ to work on
-my car, took quests from the slavers and the mafia and entered the
-city in the morning. Entering the city I was a bit surprised that the
-sheriff offered me a job for Westin. Instead of doing this right now,
-I stole some papers from a local researcher, stole maps from the
-rangers, killed a suicidal policeman, killed a cultist (while
-sneaking) and kicked the president's son a few times in the eyes,
-breaking his nose thus, took the quest from the president and
-completed the one for Westin. I didn't invest into outdoorsmanship,
-so failed to discover the vault 13. Returning to NCR I handed the
-papers I acquired earlier to Merk and bought a disc with the fake
-13's location, discovered it's a fake, killed Merk for refusing to
-give me a refund.
-
-I went to the vault 15, one of my least favourite locations (I've
-actually been thinking about just buying the map from the doctor, but
-ended up a little short on money). Rescued a local woman's daughter
-from raiders and went underground. There I sneaked past the guards on
-the first level, which turned out to be pretty useless, as the
-computer room's guards noticed me anyway. I thus learned of the vault
-13's location and retrieved computer parts, but was forced to fight
-my way back through the raiders. I didn't kill Darion because both I
-and probably my character considered him to be too tough.
-
-After giving Tandi her parts (and not exposing the spy because I
-didn't know that there was one) I was finally able to arrive to the
-actual vault 13. I attacked the deathclaws on sight, retrieving the
-GECK at the end, thus proving genocide to be viable solution to any
-problem.
-
-
-THE END
-
-I went back to Arroyo in an almost straight line after the village
--idiot- shaman called me. Then I realised that I still don't have
-HtH evade, so instead of going to San Francisco rode to the
-Experience Town of Redding. This is where I ran out of Salvatore's
-batteries, so my adventures ended rather abruptly after I crashed
-a dozen times fighting Frog Morton's goons, so instead I just
-killed Frog himself and ran away with, like, four batteries left.
-
-The Shi merchants turned out to be on the other level than myself:
-selling all those tiny nuclear reactors and gauss rifles. Well,
-what about small batteries? This is my least favourite location in
-the game anyway. I took the quest from the brotherhood of steel guy,
-arrived to Navarro, killed the guy in the front, went into the
-facility via the tunnel, grabbed all the equipment I could find,
-did the usual, got the commander's guard drunk, killed the commander,
-looted his office, ran away.
-
-Back south I saved a damsel in distress on a tanker, fixed the ship's
-navigation while at it, got the damsel's boyfriend to get the fuel
-from the Shi for me and went for the final dungeon.
-
-Again during this section game seemed commited to not letting me win,
-instead segfaulting on every 5th attack I made. Also the aliens and
-floaters would often fail to initiate combat when I was walking right
-by them.
-
-There I encountered what I am pretty sure was a bug. I first tried to
-get the people around the president drunk, get my sneak skill up and
-kill him silently. I think it should have worked, but it didn't.
-Somewhat disappointed I tried to blow him up: then I discovered that
-somehow neither he, nor I take damage from explosions in our pants.
-At last I was forced to commit murder by superstimpaks. Finished the
-game by stuffing dynamite down the trousers of a researcher near the
-reactor and having the turrets shoot Frank Horrigan to the death.
-Once more the turrets didn't attack Horrigan immediately, though I am
-quite sure they are supposed to.
-
-
-FINAL BUGS?
-
-I am pretty sure I didn't get all the ending slides I was supposed
-to.
-
-
-REFERENCES
-
-[fallout2-ce] https://github.com/alexbatalov/fallout2-ce
-
-
-Copyright (c) 2023 Alexander Arkhipov <aa@alearx.org>
-Licensed under CC BY (https://creativecommons.org/licenses/by/4.0)
blob - /dev/null
blob + 182dd4ddc594a4e6d13b410879e26226fdd64e5b (mode 644)
--- /dev/null
+++ art/003.git.txt
+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 <hash1> file1
+100644 blob <hash2> file2
+040000 tree <hash3> dir
+...
+$ echo "here's file1:"; git cat-file blob <hash1>
+...
+$ echo "here's file2:"; git cat-file blob <hash2>
+...
+$ git ls-tree <hash3>
+...
+# 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 <hash> <hash>"
+
+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
-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 <aa@alearx.org>
-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
+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 <aliases>
+ 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:
+
+ <selector>._domainkey.example.com. 680 IN TXT "v=DKIM1;p=<pub>"
+
+<selector> can be any string and <pub> 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 <selector> \
+ -k /etc/mail/dkim/private.rsa.key" user _dkimsign group _dkimsign
+ listen on socket filter "dkimsign_rsa"
+
+Of, course, make <selector> 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
-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 <hash1> file1
-100644 blob <hash2> file2
-040000 tree <hash3> dir
-...
-$ echo "here's file1:"; git cat-file blob <hash1>
-...
-$ echo "here's file2:"; git cat-file blob <hash2>
-...
-$ git ls-tree <hash3>
-...
-# 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 <hash> <hash>"
-
-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 <aa@alearx.org>
-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
+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
-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 <<x
- cd $HOME
- xauth -q remove $DISPLAY
- echo $nlist | xauth -q nmerge -
- exec fvwm
-x
-
-If you don't want to type the password each time, add the line
-
-permit nopass mainuser as anotheruser cmd /bin/sh args -l
-
-to doas.conf.
-
-Once you successfully execute this script, you'll get an Xephyr (or
-is it an American program, and X is meant to be pronounced as Z? If
-it is, then it's too stupid, I'll just have to keep pronouncing X as
-a letter-name) window with fvwm inside. You can use fvwm to launch
-xterm, and you can use xterm to launch firefox. To see how well
-things are isolated, try copying some text in one X session (either
-the normal one, or the one inside Xephyr), and pasting it in the
-other -- you should fail!
-
-
-Copyright (c) 2023 Alexander Arkhipov <aa@alearx.org>
-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
+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
-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 <aa@alearx.org>
-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
+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:<hash>,sd1:<hash>,sd2:<hash>
+# echo <hash>.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 <hash>.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 <hash>.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 <hash>.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
+ <n> = key expires in n days
+ <n>w = key expires in n weeks
+ <n>m = key expires in n months
+ <n>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 <<x
+datadir=/data/aa/bitcoin
+walletdir=$HOME/.bitcoin/wallets
+x
+$ mv ~/.bitcoin /data/aa/bitcoin
+$ mkdir ~/.bitcoin
+$ mv /data/aa/bitcoin/bitcoin.conf ~/.bitcoin/
+$ mv /data/aa/bitcoin/wallets ~/.bitcoin/
+
+bitcoind is the server and bitcoin-cli is the client. The latter has
+two sets of documentation (and some nonsense *.md files under
+/usr/local/share/doc/bitcoin/ that I refuse to consider such), both
+of which are pretty bad:
+
+1. First is command-line options documentation. Type either
+ "bitcoin-cli -?" or "man bitcoin-cli". Most of them are not
+ very useful.
+2. The API documentation, accessible by typing
+ "bitcoin-cli help [command]".
+
+Considering I don't need to automate it, the actual usage is very
+easy. The subcommands "send", "listunspend" and "getaddress" are
+the majority of what I need.
+
+Let's leave bitcoin-cli for later, and instead just download the
+blockchain.
+
+Firstly I actually opened bitcoin-qt, and disabled pruning -- it's
+been enabled through the GUI originally, so it only made sense to
+disable it this way. Turns out it just changed my
+/data/aa/bitcoin/settings.json to have '"prune": "0"' and
+'"prune-prev": "1907"'.
+
+Afterwards, I closed the GUI, and instead typed "bitcoind -reindex"
+and went to sleep. Wakefully, I made some calculations based on the
+progress thus far, and realised that the entire blockchain is a
+little under 500 GB! Straight after, I killed the daemon and
+restarted it with "prune=131072" in bitcoin.conf. Perhaps I should
+get an HDD just for bitcoin? It could as well be external since I'd
+only use it occasionally.
+
+Regardless, I at last deleted the bitcoin GUI along with the rest of
+qt:
+
+# pkg_delete bitcoin
+# pkg_add bitcoin--no_x11
+# pkg_delete -a
+
+
+Encrypted USB flash drive
+
+Right now my off-site backups rely on the fact that I have access to
+my private key and signer@'s public key. Of course I could just
+publish the latter, but the fact that my disc has my private key on
+it doesn't help at all in the event of its death. To deal with it I
+encrypted a USB flash drive, and used it to store the really
+important files/trees, such as ~/.ssh, ~/.gnupg, and ~/.bitcoin.
+Then the drive could be safely deposited at the office / friend's /
+aunt's / whatever.
+
+For OpenBSD the procedure is described quite well at
+https://www.openbsd.org/faq/faq14.html#softraidCrypto:
+
+# dd if=/dev/urandom of=/dev/rsd3c bs=1m
+# fdisk -iy sd3
+# disklabel -E sd3 # make an "a" partition of type RAID
+# bioctl -c C -l sd3a softraid0
+# dd if=/dev/zero of=/dev/sdc4c bs=1m count=1
+# fdisk -iy sd4
+# disklabel -E sd4 # make a normal "a" partition
+# newfs sd4a
+# mount /dev/sd4a /mnt
+# echo secret >/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
-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 <aliases>
- 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:
-
- <selector>._domainkey.example.com. 680 IN TXT "v=DKIM1;p=<pub>"
-
-<selector> can be any string and <pub> 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 <selector> \
- -k /etc/mail/dkim/private.rsa.key" user _dkimsign group _dkimsign
- listen on socket filter "dkimsign_rsa"
-
-Of, course, make <selector> 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 <aa@alearx.org>
-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
+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
-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 <aa@alearx.org>
-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
+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
-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 <aa@alearx.org>
-Licensed under CC BY (https://creativecommons.org/licenses/by/4.0)
blob - ebc58190ea5364609f252c88cf6de741cb8c0eb7 (mode 644)
blob + /dev/null
--- art/revolution.txt
+++ /dev/null
-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 <aa@alearx.org>
-Licensed under CC BY (https://creativecommons.org/licenses/by/4.0)
blob - /dev/null
blob + bbc3411176c21a917ca5ddda70fc12fc5c8c492a (mode 644)
--- /dev/null
+++ gopher.exclude
+*.html
+*.css
blob - 00282c512bd99ed4fe5860873905628e74ea8775
blob + 07ce61d4932ca360c237c45a3b6603f3e019786f
--- gallery.html
+++ gallery.html
<small><br>my books</small>
</td>
</tr>
+<tr>
+ <td align=center>
+ </td>
+ <td align=center>
+ <img src="pub/photos/xlib.jpeg" width=250 height=187
+ alt="Xlib programming manual"
+ title="Arrived from England, and actually ended up costing a bit more than I'd like -- will try to do it a bit differently next time.">
+ <small><br>2023-07-11</small>
+ </td>
+ <td align=center>
+ </td>
+</tr>
</table>
</body>
blob - c40bf522a15ac00c73cb171c1534a1c237fb1d9e
blob + 4e88fd917e4a35fee503e4beba3dff1c9a77ddbf
--- index.gph
+++ index.gph
-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
<meta charset="UTF-8">
<title>Alexander Arkhipov's</title>
<link rel="icon" type="image/png" href="favicon.png">
+<link rel="stylesheet" type="text/css" href="style.css">
<body>
-<pre>
-I am Alexander, the insane Unix hacker and owner of alearx.org. For
-more information, please see the README file.
+<p>I am Alexander. I write programs.</p>
-<a href="README.txt">README</a>
-
-<a href="art/">articles</a>
-<a href="plan.txt">plan</a>
-<a href="feed.ass">feed</a>
-<a href="news/">news</a>
-<a href="pub/">ftp</a>
-<a href="git/">git</a>
-<a href="gallery.html">gallery</a>
-
-<a href="ln.html">links</a>
-</pre>
+<hr>
+<ul>
+ <li><a href="project.txt">project</a></li>
+</ul>
+<hr>
+<ul>
+ <li><a href="art/">articles</a></li>
+ <li><a href="plan.txt">plan</a></li>
+ <li><a href="feed.ass">feed</a></li>
+ <li><a href="news/">news</a></li>
+ <li><a href="pub/">ftp</a></li>
+ <li><a href="git/">git</a></li>
+ <li><a href="gallery.html">gallery</a></li>
+</ul>
+<hr>
+<ul>
+ <li><a href="ln.html">links</a></li>
+</ul>
+<hr>
</body>
</html>
blob - /dev/null
blob + f60deceac67ecb6d4768a41df474ad32ea1a2080 (mode 644)
--- /dev/null
+++ plan.txt
+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
+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
+ul { list-style: none; }
blob - /dev/null
blob + 77c3fc631241a438e6422e33da7ce0c6f06ee9eb (mode 644)
--- /dev/null
+++ www.exclude
+*.gph