This page is a short introduction to numeric and symbolic mathematics in Maxima on FreeBSD.
What is Maxima?
Maxima is an interactive environment for numeric and symbolic mathematics. It does differentiation, integration and solutions of equations. It plots 2 and 3 dimensional graphics.
Define 2 functions y1 and y2, where y2 is of 2nd order. Set decimal precision. Solve their intersections and display in decimal number. Differentiate y2. Reference the result with % and evaluate it for x at -1. Plot their intersections.
$ maxima (%i1) y1(x) := 2*x-9; (%o1) y1(x) := 2 x - 9 (%i2) y2(x) := -2*x^2-x+15; 2 (%o2) y2(x) := - 2 x - x + 15 (%i3) fpprintprec: 2; (%o3) 2 (%i4) float(solve( y1(x) = y2(x), x )); (%o4) [x = - 4.3, x = 2.8] (%i5) diff( y2(x), x ); (%o5) - 4 x - 1 (%i6) ev( %, x=-1 ); (%o6) 3 (%i7) plot2d( [ y1(x), y2(x) ], [ x, -5, 5 ] ); (%i8) quit();
This is the procedure for documenting input commands and output on the console, terminal or in shell to a text file with the default typescript utility SCRIPT.
What is SCRIPT?
SCRIPT is a default FreeBSD and UNIX utility, that makes a typescript of a terminal session. It works on the console, on terminals and in a shell. The typescript is stored in a text file, that serves as documentation later.
Make typescript with SCRIPT.
In this example, input and output is written to the script text file test.txt for later documentation.
$ script test.txt Script started, output file is test.txt $ date Fri Sep 5 13:52:51 CEST 2025 $ freebsd-version 14.3-RELEASE-p2 $ exit Script done, output file is test.txt
Additional input and output can be appended to the script. This avoids overwriting the initial script.
$ script -a test.txt Script started, output file is test.txt
Review typescript from SCRIPT.
The script can later be reviewed with default utilities or even replayed by SCRIPT itself.
$ cat test.txt Script started on Fri Sep 5 13:52:48 2025 $ date Fri Sep 5 13:52:51 CEST 2025 $ freebsd-version 14.3-RELEASE-p2 $ exit Script done on Fri Sep 5 13:53:13 2025
Manual for SCRIPT.
See the manual for features, such as realtime playback and similar features.
This is the procedure for changing the GEOM ELI (GELI) password on encrypted disks. This includes multiple disks in stripe or RAID with FreeBSD and ZFS-on-Root.
GELI password and encryption.
The default install of FreeBSD offers full disk encryption of one or more disks with GELI. The full disk encryption is seamless and simple to use. The user simply needs to type in the password on boot. If the password is correct, then the computer boots FreeBSD.
During the installation of FreeBSD, GELI generates a random master key for each disk. The master key is different on each disk. The master key is not written anywhere else than on the disk. The master key is used to encrypt data.
The GELI password is not used directly for encryption. The password is used to derive a key-encryption key (KEK) for each disk. This is also known as a user key. The user key is an encrypted copy of the master key for the disk. The same password is by default used for each user key. This is why the same password can decrypt several disks at boot.
The FreeBSD implementation of GELI support the use of an additional user key for each disk. This means, that 2 different passwords could be used. The user key does not have to be assigned to a password. It can also be assigned to a key file or both.
Backup before attempting to change password.
As always, it is adviced to have a backup of the file system, before attempting to change the password for an encrypted file system. It is also important to be certain, that the file system can be restored. Any mistake can brick the computer in an instant.
Choosing a new password.
The GELI password prompt does not in itself protect the system against brute force attacks with delay, rate limiting, lock-out nor similar protection. Instead, when the password is given, GELI applies a large number of hash iterations. This is by default tuned, so it takes an amount of time, that slows brute force down by several orders of magnitude.
For this reason, the password should meet a good balance between being a strong password, a human-friendly password and a keyboard safe password. It is important to know, that a simple password from a dictionary, such as “Pencil” in the famous movie War Games, is not a strong password and could be cracked by an offline GPU cluster.
The strengh of a password is measured in entropy, which is the amount of predictable possiblities. Low entropy can be hacked in minutes. High entropy could be impossible to hack with current and future computer power. I suggest an entropy of 100 bits or more for a GELI password. 100 bits of entropy is astronomically strong.
A strong password includes non-dictionary letters, numbers and special characters, that can be memorized. The password should also be safe, so it can be typed on a default keyboard layout. The following examples include non-dictionary letters, numbers and special characters, that can be memorized, while also being keyboard safe.
Changing the GELI password, that is used to decrypt each disk, is done by using the GELI utility.
In this example, the machine has a Root-on-ZFS file system, that is stored on 2 disk partition components in stripe and registered as ada0p3 and ada1p3. The new password is written to the file newpassword.txt. The new password is then used to generate a new user key for each disk.
# geli status # vi newpassword.txt # geli setkey -J newpassword.txt ada0p3 # geli setkey -J newpassword.txt ada1p3
The GELI password has now been changed. The old password can no longer be used to decrypt the file system.
Adding an extra GELI password.
I would generally not advice using several GELI passwords, but on critical systems, a GELI password change could be performed without deleting the original key, until the new key is tested to work. This is also true, if the new password also requires a keyfile.
In this example, the machine has 1 disk partition, that is registered as ada0p3. The extra password is written to the file extrapassword.txt. The extra password is then used to generate a new user key in slot 1 for the disk. The password and user key in slot 0 remains unchanged.
# geli status # vi extrapassword.txt # geli setkey -J extrapassword.txt -n 1 ada0p3
The extra GELI password has now been added. The extra password in slot 1, and the password in slot 0, can be used to decrypt the file system.
Warning: GELI metadata backup files can decrypt.
It is important to know, that a backup of GELI metadata for a disk, can be used to decrypt that disk. This is even true, if the password was changed on the disk. The reason is, that the master key never changes. Only the key-encrypted copy changes.
I do not recommend the use of GELI metadata backup files. Instead, I recommend, that an external file system backup is always available. There is a reason, that metadata corrupts. It usually means a new disk. And that means a fresh install and a restore.
As a part of my general interest in time management, I wanted to take a look into the UNIX utility CALENDAR, which is a reminder service, that is used on the console.
What is CALENDAR?
CALENDAR is a reminder service and default system utility on FreeBSD and UNIX operating systems. CALENDAR offers simple, effective and secure time management for systems administrators and users. CALENDAR is based on text files, which makes it easy to update, synchronize and backup.
$ calendar Aug 20 Weather forecast says 11-17 °C 💧 Aug 20* Daily coffee meeting with David Lightman at 15:00 Aug 20 Patch WOPR mainframe in data center Aug 20 Simulate first-strike on WOPR Aug 20 Change password for listing games on WOPR
Calendar files
The CALENDAR reminder service uses one or more calendar files. Much like the good old days, when you would have one or more calendars. You might have a private one for personal events, one for recurring birthdays, a shared one for family events and a shared one for project events. Each calendar can hold tasks, recurring events.
By default, CALENDAR will search for a calendar file in the user home. If that is not found, then it will look for a calendar file in the hidden dot calendar directory and the following shared directories. The default name for a calendar is “calendar”.
I recommend, that the hidden calendar directory is used. This protect the calendars from accidental deletion. In this example, a calender for one-time events and a calendar for recurring events is created.
The calendar file format is text based and consist of a list of dates and description. These are separated by a tab. Other calendars can be included.
$ nano -T 12 ~/calendar/calendar #include <calender.recurring> #include <calendar.freebsd> #include <calendar.weather> 15 * Every 15th 10/2 2nd of October July Every 1st of July Thursday Every Thursday 2025/9/15 15th of September 2025 04/TueLast Every last Tuesday in April
Using CALENDAR
If you want to see todays calendar events, then run CALENDAR without any arguments. CALENDAR will read the calendar, and any included calendars, and output todays events. You might want to format the date to your local preference in the shell configuration or on the command line.
$ calendar Aug 20* Daily coffee meeting with David Lightman at 15:00 Aug 20 Patch WOPR mainframe in data center
You can also output todays time and day and only list todays events, just like a good old physcal calendar. By default, the weekend is shown as one, but by using the argument -W, weekends can be treated as any other day.
$ date "+%H:%M %A %d %B %Y"; calendar -W 0 08:21 Wednesday 20 August 2025 Aug 20* Daily coffee meeting with David Lightman at 15:00 Aug 20 Patch WOPR mainframe in data center
And you can take a look at tomorrow, or any day, just like a good old physical calendar, by using the argument -t.
$ date -v+1d "+%A %d %B %Y"; calendar -t $(date -v+1d +%d.%m.%Y) -W 0 Thursday 21 August 2025 Aug 21* Daily coffee meeting with David Lightman at 15:00 Aug 21 Test Tic-Tac-Toe game on WOPR
If you want to see all events, that is planned days ahead in time, or happened days back in time, you can use the ahead argument -A and back argument -B. They can be also combined.
$ calendar -B 1 -A 3
The UNIX calendar reminder service is highly fleksible and easy to combine with other default UNIX utilities. You might even find it to be superior to modern calendars.
The manual is very well written.
$ man calendar
The FreeBSD calendar
On FreeBSD systems, there is a calendar file, that has birthdays of FreeBSD contributers.
$ cat /usr/share/calendar/calendar.freebsd | grep Percival 02/24 Colin Percival <> born in Burnaby, Canada, 1981
Todays events at login
If you would like, that each user gets todays events at the login console, then configure it in the global shell configuration. In this example, the SH is configured.
# nano /etc/profile events=$(calendar -W 0 2> /dev/null) if [ -n "$events" ]; then echo "$events" fi
Todays events via email
If you want an automatic daily email with todays events, you can configure CRON to do this. In the following example, CRON on a FreeBSD server is configured to automatically send todays events to each system user.
If you want to include todays weather forecast, for today and the next days, you can use an online service, that generate ICS calendar files and convert them to CALENDAR format.
In this example, a special URL to the weather forecast was generated on the brilliant website of Meteomatics, which is a free service. The weather forecast comes as a file in ICS format. This file contains the weather forecast for each day through 15 days. Python is used to convert it to CALENDAR format and saved as an optional calender, that local users can include in their calendars.
# nano ~/bin/meteomatics #!/usr/bin/env python3.11 from icalendar import Calendar from datetime import datetime import re with open("/tmp/meteomat.ics", "rb") as f: cal = Calendar.from_ical(f.read()) for component in cal.walk("vevent"): dtstart = component.decoded("dtstart") if isinstance(dtstart, datetime): dt = dtstart.date() else: dt = dtstart desc = component.get("description") if not desc: continue temps = [int(x) for x in re.findall(r"([-]?\d+)°C", desc)] if not temps: continue tmin, tmax = min(temps), max(temps) rain = "💧" if "💧" in desc else "" print(f"{dt.month}/{dt.day}\tWeather forecast says {tmin}-{tmax} °C {rain}")
CRON is used to update the weather forecast calendar automatically. In this example, it happens daily at 13:37.
Synchronizing CALENDAR a cross devices with Unison
The calendar can be synchronized a cross devices and systems with a synchronization utility, such as RSYNC or Unison.
In the following example, Unison is installed and configured for synchronizing the calender via SSH to a remote UNIX system, that also has Unison installed. The options prefer, auto and batch are used, so conflicts are solved automatically. An example of a conflict could be, that local and remote calendars were changed. Unison can not merge changes.
In the following example, the events for the next 21 days are sent via SCP to a remote device, such as an SSH server on port 1337 on an Android phone, and stored as a text file. The directory on the remote device is the default, which can be configured on the SSH server on the remote device.
This is a real-world test of how well (or how bad) the Fujifilm X100VI camera performs versus a mobile phone camera.
Challenges
Will the dynamic range of the Fujifilm X100VI perform better than a mobile phone? Will the colors of the Fujifilm X100VI be more accurate than a mobile phone? Will sharpness and skin tone in portraits of the Fujifilm X100VI be more pleasing than a mobile phone? Will the Fujifilm X100VI perform better than a mobile phone? Will the Fujifilm X100VI live up to the marketing hype?
Conditions
The pictures were taken as snapshots (no fiddling with special deep settings for each picture) on a common sunny day with harsh light at the beach of Hellerup in Denmark. A challenging scene with contrast and reflecting light. The Fujifilm X100VI and the mobile phone, an older inexpensive Samsung Galaxy A54, were both using default settings. The pictures are straight out of camera (SOOC) JPEGs. There has not been done any editing. The pictures has been automatically cropped to 1:1 aspect ratio and formatted for this web page.
Sample Pictures
Fujifilm X100VI
Samsung Galaxy A54
Fujifilm X100VI
Samsung Galaxy A54
Fujifilm X100VI
Samsung Galaxy A54
Fujifilm X100VI
Samsung Galaxy A54
Fujifilm X100VI
Samsung Galaxy A54
Samsung Galaxy A54 Front
Conclusion
The dynamic range of the Fujifilm X100VI does not outperform a mobile phone. Despite the insane price, the engineers were not able to make the internal computer automatically detect a sunny day and then enable all of its dynamic range, shadow and highlight special tweaks.
The colors of the Fujifilm X100VI are not more accurate than a mobile phone. The colors come out close to accurate, but tends to get muddy from bad contrast or too dark from bad dynamic range.
The sharpness and skin tone in portraits of the Fujifilm X100VI are slightly warmer and more pleasing than a mobile phone, if there is some distance to the subject (not selfie), but the Fujifilm X100VI is, however, unable to capture eyes. In my test, the blue eyes became black and so did facial features! This renders subjects worse than they actual are on scene. The sharpness tends to appear out-of-focus, despite automatic focus enabled, and skin color a bit sluggish red, when taking a selfie.
The Fujifilm X100VI does not perform better than a mobile phone. This sad result is probably not because of hardware limits, but because the Fujifilm X100VI is unable to automatically detect and apply its best settings for the picture. A feature, you would rightfully expect for such an expensive fixed lens camera, with powerful internal computing, for casual fun snapshot photography. Just like a less expensive mobile phone does. It is also worth mentioning, that none of the film simulations is of any help. The resulting images remain worse than a mobile phone. If you really want to get peak performance, you would have to spend a lot of fiddling in and out of deep settings, before each shot. Your friends – and the motive – would be long gone by then. You could also shoot in RAW and spend a huge amount of time in expensive AI driven color grading and editing software, but that would take away the fun casual photography.
The Fujifilm X100VI does not live up to the marketing hype by Fujifilm and the associated influencers. Fujifilm describes the X100VI as “Using a timeless dial-based design, passed down from model to model, the stunning 6th-generation X100VI offers an indulgent, tactile image-making experience that delivers unforgettable content in every creative moment”. The words must be well-thought out, because the “unforgettable” could describe the bad feeling, when you come home and watch the disappointing pictures, that falls behind a less expensive mobile phone. The theory and datasheets (megapixel marketing hype) might be “stunning”, but the actual performance – on the street – is not.
Comments
I have requested Fujifilm and influencers for comments. I am always happy learn, if there are things, I have missed. If you have comments, I will be very happy to read them.
Today is international system administrator appreciation day. Take some time to thank all those people, who work behind the scenes and screens to maintain the advanced UNIX computer systems, that keeps us all online, while keeping our data available, secure and recoverable, when disaster strikes. Thanks.
WOPR
The WOPR mainframe, that stages a massive Soviet first strike, in the movie WarGames from 1983 with Matthew Broderick as David Lightman.
This is the procedure for configuring Apache HTTP Server and Let’s Encrypt to use the alias-based webroot method for the ACME challenge by Let’s Encrypt. The benefit of this over stop of Apache is no downtime.
Be aware, that this method does not work, if some virtual hosts redirects port 80.
Create the webroot directory for the ACME challenge by Let’s Encrypt.
Add the global alias to the webroot directory for the ACME challenge by Let’s Encrypt. If the Apache server is hosting HTTP as well as HTTPS sites, then a global alias is best.
Alias /.well-known/acme-challenge/ "/usr/local/www/letsencrypt/.well-known/acme-challenge/" <Directory "/usr/local/www/letsencrypt/.well-known/acme-challenge/"> AllowOverride None Options None Require all granted </Directory>
Perform a sanity check of the configuration file and restart Apache.
# service apache24 configtest # service apache24 restart
Switch to webroot method for domains. This can be automated with a script.
#!/bin/sh for f in /usr/local/etc/letsencrypt/renewal/*.conf; do sed -i '' \ -e '/^authenticator =/d' \ -e '/^webroot_path =/d' \ -e '/^pre_hook *=/d' \ -e '/^post_hook *=/d' \ "$f" echo "authenticator = webroot" >> "$f" echo "webroot_path = /usr/local/www/letsencrypt" >> "$f" done
Edit the crontab file.
# nano /etc/crontab
Configure automatic renew by Let’s Encrypt. In this example, every Monday at 13:13.
The is the procedure for creating a quick backup of a directory, and the files in it, by creating an archive with TAR on FreeBSD.
What is TAR on FreeBSD?
TAR is an archive utility, that can be used to archive directories and files into a single archive file. TAR is a fast, safe and native utililty on FreeBSD. TAR works much like ZIP, which is not a native utility on FreeBSD. The benefit of no compression is faster speed and less risc of data corruption.
Creating a backup of a directory with TAR.
In the following example, the BIND DNS directory /usr/local/etc/namedb, and the directories and files in it, will be archived with TAR. The file name for the archive will be named after the ISO 8601 date and the directory. This naming convension is a good practice for quick backup archives. The archive will be stored in current directory, which by default is the home directory. It is a good practice to not leave archives in the active system directories, despite being convenient.
# tar -cf 2025-06-24-namedb.tar /usr/local/etc/namedb
The directory, and the directories and files in it, has now been archived and stored in current directory.
# ls *.tar 2025-06-24-namedb.tar
Listing files in a TAR archive.
In the following example, the contents of the archive is listed to standard out. The archived directories and files are relative to the current directory by default.
# tar -tf 2025-06-24-namedb.tar usr/local/etc/namedb/ usr/local/etc/namedb/named.conf
Reading (extracting) a file in a TAR archive.
Reading a file in a TAR archive, which means extracting it to default out, can be used for inspecting without extracting to file system first. In the following example, the named.conf is extracted from the archive to standard out. This will show the contents of the file and the output can be piped to utilities, such as GREP, MORE, LESS and TAIL.
# tar -xOf 2025-06-24-namedb.tar usr/local/etc/namedb/named.conf
Extracting from a TAR archive.
In the following example, the directory, and its directories and files, is extracted from the archive. The directory will be extracted to the current directory by default.
# tar -xf 2025-06-24-namedb.tar
In the following example, the directory, and its directories and files, is extracted from the archive to an optional temporary directory.
# tar -xf 2025-06-24-namedb.tar -C tmp/
In the following example, the directory, and its directories and files, is extracted from the archive to the root directory. The will restore the backup to original location. Warning! This will overwrite the original files.
# tar -xf 2025-06-24-namedb.tar -C /
Encrypting a TAR archive with GPG.
The TAR archive, or any file, can be encrypted with a password by using GPG. In the following example, the an encrypted copy of the TAR archive is created with GPG.
# tar -cf - /usr/local/etc/namedb | gpg --symmetric --pinentry-mode loopback > 2025-06-24-namedb.tar.gpg" Enter passphrase: Pencil
This will create an encrypted copy, that can only be decrypted with the same password. No GPG keys will be needed.
# ls *.gpg 2025-06-24-namedb.tar.gpg
The encrypted TAR archive can be decrypted with GPG and extracted with TAR.
# gpg --decrypt 2025-06-24-namedb.tar.gpg | tar -xf - Please enter the passphrase for decryption. Passphrase: Pencil
Zero padding or random padding is the practice of secure wiping of removable storage devices, such as USB sticks, SD cards and external SSDs, so they can be safely re-used within an organization. Zero padding or random padding fills the storage device with zeroes or random bytes. This over-writes existing documents and files on the storage device.
If the storage devices was just quickly re-formatted, then documents and files would be recoverable by forensic software or basic operating system utilities, because modern storage devices distribute data to new places on the storage device to ensure optimal life time.
# dd if=/dev/da0 bs=1 skip=1048576 count=512 status=none | hexdump -C 00000000 4e 1e 40 db 85 ab 9f 63 48 9d 51 e2 8f ef 6f a8 |.Pass.is.Pencil.|
Modern SSDs and larger storage devices might require specialized commands or vendor utilities. In such cases, or when the storage device was used to store highly classified documents, consider physically schredding or destroying the storage device instead.
Identifying storage device to be zero padded.
Identify the storage device. In this example, an external 32 GB USB 3.0 stick was attached and identified as da0.
$ dmesg da0: <Generic Flash Disk 8.13> Removable Direct Access SPC-4 SCSI device da0: Serial Number 42011337510013 da0: 40.000MB/s transfers da0: 29600MB (60620800 512 byte sectors) da0: quirks=0x2<NO_6_BYTE>
Unmounting file systems on storage device.
Make sure, that none of its file systems are mounted.
# umount /dev/da0*
Zero padding a storage device.
Zero padding will fill the entire storage device with zeroes and thereby defeat any attempts of casual recovery of documents of files on it. If you require an even more secure erasure, you can use random padding instead.
# dd if=/dev/zero of=/dev/da0 bs=1M status=progress dd: /dev/da0: end of device 29 GiB) transferred 2207.307s, 14 MB/s 29601+0 records in 29600+0 records out
In this example, the zero padding of a 32 GB USB 3.0 stick took 37 min. Low write speeds are not uncommon for lower quality USB sticks, despite labeled as USB 3.0.
Random padding a storage device.
Random padding will fill the entire storage device with random data and thereby not only defeat any attempts of casual recovery of documents of files on it, but also provide stronger protection by preventing pattern detection from hardware residue. Random padding takes slightly longer time to complete.
# dd if=/dev/urandom of=/dev/da0 bs=1M status=progress dd: /dev/da0: end of device 29 GiB) transferred 2450.009s, 13 MB/s bytes (25 GB, 24 GiB) transferred 2008.177s, 13 MB/s 29601+0 records in 29600+0 records out 31037849600 bytes transferred in 2450.640376 secs (12665200 bytes/sec)
In this example, the random padding of a 32 GB USB 3.0 stick took 41 min. This is only 4 min longer than zero padding.
If the storage medium is of magnetic type or you require an even more secure erase, you can perform the random padding several times. However, multiple passes on modern storage media has dimishing returns. In this example, the storage device is random padded 3 times. This is, however, not necessary on modern drivess.
# for i in 1 2 3; do dd if=/dev/urandom of=/dev/da0 bs=1M status=progress; done
Formatting an USB stick with EXFAT.
The storage device has now been safely erased and it can be formatted with a new file system, so it can be used again. In this example, the USB stick is formatted with the well-supported EXFAT file system. The EXFAT file system willl not have a partition scheme. This ensures compatibility.
# mkexfatfs /dev/da0 mkexfatfs 1.4.0 Creating... done. Flushing... done. File system created successfully.
If you will be transferring a secret file from one file system to another, you might want to protect the file from theft or exposure during the transfer. This could be an encryption key file for decrypting a multi-challenge encrypted file system or similar secret file, that are to be transferred on an unencrypted storage medium, such as an USB stick with EXFAT, NTFS or MSDOS file system on it. If you will be using the GNU Privacy Guard (GPG) without GPG key pairs, then you can encrypt with a symmetric cipher by specifying a pass phrase.
Encrypting with symmetric cipher
If you will be using GPG without GPG key pairs, then you can encrypt with a symmetric cipher by specifying a pass phrase. In cryptography, this means, that the same pass phrase will be used to encrypt and decrypt. The user, who will encrypt the file, will choose a pass phrase, which will be used to write a new encrypted file, that contain the secret file. The pass phrase should be as long and non-dictionairy complex as possible. The default cipher is AES-128.
$ gpg --symmetric keyfile.bin
The encrypted file can now be transferred safely.
$ ls keyfile.bin.gpg
You can test, that the file can be decrypted and compare it to the original file.
The encrypted file can be decrypted on the target file system by anyone, who know the pass phrase, that was used to encrypt the file. It is not required, that the target user has a GPG key pair.