Compare commits

...

8 Commits

14 changed files with 279 additions and 166 deletions
+2 -2
View File
@@ -16,7 +16,7 @@
// The optional 'workspaceFolder' property is the path VS Code should open by default when
// connected. This is typically a file mount in .devcontainer/docker-compose.yml
"workspaceFolder": "/src"
"workspaceFolder": "/project",
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
@@ -37,5 +37,5 @@
// "customizations": {},
// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "devcontainer"
"remoteUser": "root"
}
+1 -1
View File
@@ -13,7 +13,7 @@ services:
volumes:
# Update this to wherever you want VS Code to mount the folder of your project
# - ..:/src:cached
# - ..:/project:cached
# Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust.
# cap_add:
@@ -1,25 +1,3 @@
// Colors
$theme: hsl(172, 99%, 26%);
$text: hsl(204, 28%, 93%);
$light-grey: #292e32; // #494f5c;
$dark-grey: #3B3E48;
$highlight-grey: #7d828a;
$typewriter: hsl(172, 100%, 36%);
$codebackground: #1c2023 !default;
$midnightblue: $codebackground;
// Scroll to Top Default colors
$stt-stroke:#CCC;
$stt-circle:#3b3e48;
$stt-arrow:#018574;
kbd {
font-size: 0.9em !important;
color: inherit;
background-color: $midnightblue;
}
// Fonts
$fonts: "IBM Plex Sans Light", "Segoe UI", Candara, sans-serif;
$code-fonts: "IBM Plex Mono Light", Consolas, "Andale Mono WT", "Andale Mono", Menlo, Monaco, monospace;
@@ -96,46 +74,3 @@ $code-fonts: "IBM Plex Mono Light", Consolas, "Andale Mono WT", "Andale Mono",
url('/fonts/IBMPlexMono-MediumItalic.woff2') format('woff2');
}
//Admonition
$admonition-background: (
'note': rgba(68, 138, 255, 0.1),
'info': rgba(0, 184, 212, 0.1),
'tip': rgba(0, 191, 165, 0.1),
'success': rgba(0, 200, 83, 0.1),
'warning': rgba(255, 145, 0, 0.1),
'failure': rgba(255, 82, 82, 0.1),
'danger': rgba(255, 23, 68, 0.1),
'bug': rgba(245, 0, 87, 0.1),
) !default;
$admonition-color: (
'note': #448aff,
'info': #00b8d4,
'tip': #00bfa5,
'success': #00c853,
'warning': #ff9100,
'failure': #ff5252,
'danger': #ff1744,
'bug': #f50057,
) !default;
// Mixins
@mixin dimmed {
opacity: .6;
}
@mixin aTag {
a {
word-wrap: break-word;
border: none;
box-shadow: inset 0 -4px 0 $theme;
transition-property: box-shadow;
transition-duration: .1s;
&:hover {
box-shadow: inset 0 -1em 0 $theme;
}
}
}
+9
View File
@@ -0,0 +1,9 @@
// Typography configuration for typewriter text display
$font-size-desktop: 1.5rem; // Base font size for desktop viewports
$font-size-mobile: 1.2rem; // Reduced font size for mobile devices
$line-height: 1.6; // Line height multiplier for optimal readability
// Responsive container width settings across device breakpoints
$width-desktop: 50vw; // Container width for desktop screens (60% viewport width)
$width-tablet: 70vw; // Container width for tablet screens (70% viewport width)
$width-mobile: 80vw; // Container width for mobile screens (80% viewport width)
+8 -9
View File
@@ -9,13 +9,12 @@ Mail: <bovender@bovender.de>
{{< orcid >}}
Ladungsfähige Anschrift bei meinem Arbeitgeber: Universitätsklinikum
Heidelberg, Im Neuenheimer Feld 162, 69120 Heidelberg.
Dies ist eine rein private Homepage und in keiner Weise von
meinem Arbeitgeber beworben oder unterstützt. Meine Privatanschrift ist zu
meinem persönlichen Schutz und dem Schutz meiner Familie hier nicht
veröffentlicht. **Ich bitte, von Anrufen abzusehen.** Über Mail oder die
verlinkten sozialen Netzwerke (siehe Icons) bin ich i.d.R. kurzfristig
Ladungsfähige Anschrift bei meinem Arbeitgeber: Universitätsklinikum Heidelberg,
Im Neuenheimer Feld 162, 69120 Heidelberg. **Dies ist eine rein private Homepage
und in keiner Weise von meinem Arbeitgeber beworben oder unterstützt.** Meine
Privatanschrift ist zu meinem persönlichen Schutz und dem Schutz meiner Familie
hier nicht veröffentlicht. **Ich bitte, von Anrufen abzusehen.** Über Mail oder
die verlinkten sozialen Netzwerke (siehe Icons) bin ich i.d.R. kurzfristig
erreichbar.
## Mailserver bovender.de
@@ -35,8 +34,8 @@ Der Mailserver bovender.de ist zuständig für die Domains:
## Datenschutz
Diese Website erfasst keine personenbezogenen Daten, und es werden keine
Dienste von Drittfirmen in Anspruch genommen.
Diese Website erfasst keine personenbezogenen Daten, und es werden keine Dienste
von Drittfirmen in Anspruch genommen.
Es findet eine anonymisierte Erfassung von Seitenbesuchen statt, die keine
Rückverfolgung zu einzelnen Personen/Geräten ermöglicht.
@@ -211,5 +211,37 @@ Query TLSA records:
more useful for me than all the websites and blog and forum posts that I had
previously read.
---
# Addendum 2026-04-22
## How to produce the certificate-associated data for the TLSA record?
The certificate associated data is a SHA-256 or SHA-512 checksum, depending
on the third number.
```plain
2 1 1 cbbc559b44d524d6a132bdac672744da3407f12aae5d5f722c5f6c7913871c75 # E7
# ^^^ this is the certificate-associated data in the TLSA record
```
```bash
openssl x509 -in E7.der -pubkey -noout | openssl ec -pubin -outform der | openssl sha256
```
### Obtain the hash for the certificate itself (DANE-EE)
Given a ECDSA key in `cert.pem`:
```bash
openssl x509 -in cert.pem -pubkey -noout | openssl ec -pubin -outform der | openssl sha256
```
Use the resulting hash in
```plain
3 1 1 HASH
```
[dane]: https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities
[isi]: https://dnssec-stats.ant.isi.edu/~viktor/x3hosts.html
Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

+18
View File
@@ -14,6 +14,8 @@ tags:
- photography
---
{{< figure src="cfexpress_type_b_card.jpg" >}}
I've been looking for a card reader for my CFexpress Type B cards that I use in
my camera. There are not very many devices on the market, but they have a large
price span: around 10x.
@@ -41,6 +43,21 @@ I did not want to overcomplicate things, just get an impression if there are any
differences between card readers or not. Therefore I decided to perform
sequential read and write tests using `dd` as described at [Baeldung.com][].
These are the commands that I used in [Fish][] shell; Bash has slightly
different syntax.
```fish
#!/usr/bin/fish
echo "*** Sequential write test ***"
for i in (seq 1 5); dd if=/dev/zero of=/run/media/daniel/NIKON\ Z6_3/tempfile bs=1M count=1024 conv=fdatasync; end
echo
echo "*** Sequential read test ***"
for in in (seq 1 5); sudo sh -c "/usr/bin/echo 3 > /proc/sys/vm/drop_caches" && dd if=/run/media/daniel/NIKON\ Z6_3/tempfile of=/dev/null bs=1M count=1024; end
rm /run/media/daniel/NIKON\ Z6_3/tempfile
```
## Results
The graph below shows the means and standard deviations of 5 tests for each
device. The "direct" label denotes tests with the card reader attached directly
to a USB-C/USB 3.2 Gen 2 port of my [Thinkpad P14s][] laptop, rather than via
@@ -105,6 +122,7 @@ build, and the UGREEN reader is a strong contender when it comes to small size.
[baeldung.com]: https://www.baeldung.com/linux/disk-performance-test
[darktable]: https://darktable.org
[Fish]: https://fishshell.com
[local-copies]: https://docs.darktable.org/usermanual/development/en/overview/sidecar-files/local-copies/
[Thinkpad P14s]: {{< relref "p14s" >}}
[Wikipedia article on USB 3.2]: https://en.wikipedia.org/wiki/USB_3.0#3.2
+80 -80
View File
@@ -29,109 +29,109 @@
<rect x='0.00' y='0.000000000000057' width='576.00' height='432.00' style='stroke-width: 1.07; stroke: none; fill: #303030;' />
</g>
<defs>
<clipPath id='cpMTQ2LjQ2fDU3MC41Mnw2MC43N3wyMTYuMDE='>
<rect x='146.46' y='60.77' width='424.06' height='155.24' />
<clipPath id='cpMTUwLjk0fDU2Ni4wNHw3NS4yMXwyMTYuMDE='>
<rect x='150.94' y='75.21' width='415.10' height='140.80' />
</clipPath>
</defs>
<g clip-path='url(#cpMTQ2LjQ2fDU3MC41Mnw2MC43N3wyMTYuMDE=)'>
<polyline points='164.20,113.01 164.20,104.06 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='164.20,108.53 163.34,108.53 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='163.34,113.01 163.34,104.06 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='177.29,172.72 177.29,163.76 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='177.29,168.24 176.73,168.24 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='176.73,172.72 176.73,163.76 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='457.85,202.57 457.85,193.62 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='457.85,198.10 372.76,198.10 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='372.76,202.57 372.76,193.62 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='183.93,142.87 183.93,133.91 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='183.93,138.39 183.76,138.39 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='183.76,142.87 183.76,133.91 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='183.86,83.16 183.86,74.20 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='183.86,78.68 183.54,78.68 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='183.54,83.16 183.54,74.20 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<rect x='146.46' y='95.10' width='17.31' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='154.81' width='30.56' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='184.66' width='268.85' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='124.95' width='37.39' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='65.24' width='37.25' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<text x='176.24' y='112.84' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.307 GB/s</text>
<text x='189.33' y='172.55' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.542 GB/s</text>
<text x='469.89' y='202.40' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>4.772 GB/s</text>
<text x='195.97' y='142.69' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.664 GB/s</text>
<text x='195.90' y='82.98' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.661 GB/s</text>
<g clip-path='url(#cpMTUwLjk0fDU2Ni4wNHw3NS4yMXwyMTYuMDE=)'>
<polyline points='168.31,122.60 168.31,114.47 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='168.31,118.53 167.47,118.53 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='167.47,122.60 167.47,114.47 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='181.12,176.75 181.12,168.63 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='181.12,172.69 180.58,172.69 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='180.58,176.75 180.58,168.63 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='455.75,203.82 455.75,195.70 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='455.75,199.76 372.46,199.76 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='372.46,203.82 372.46,195.70 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='187.62,149.67 187.62,141.55 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='187.62,145.61 187.45,145.61 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='187.45,149.67 187.45,141.55 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='187.55,95.52 187.55,87.40 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='187.55,91.46 187.24,91.46 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='187.24,95.52 187.24,87.40 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<rect x='150.94' y='106.35' width='16.95' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='160.50' width='29.91' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='187.58' width='263.16' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='133.43' width='36.60' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='79.27' width='36.46' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<text x='180.35' y='122.84' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.307 GB/s</text>
<text x='193.16' y='176.99' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.542 GB/s</text>
<text x='467.79' y='204.07' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>4.772 GB/s</text>
<text x='199.66' y='149.92' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.664 GB/s</text>
<text x='199.59' y='95.76' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.661 GB/s</text>
</g>
<g clip-path='url(#cpMC4wMHw1NzYuMDB8MC4wMHw0MzIuMDA=)'>
</g>
<defs>
<clipPath id='cpMTQ2LjQ2fDU3MC41MnwyNDEuMzd8Mzk2LjYy'>
<rect x='146.46' y='241.37' width='424.06' height='155.24' />
<clipPath id='cpMTUwLjk0fDU2Ni4wNHwyNDEuMzd8MzgyLjE3'>
<rect x='150.94' y='241.37' width='415.10' height='140.80' />
</clipPath>
</defs>
<g clip-path='url(#cpMTQ2LjQ2fDU3MC41MnwyNDEuMzd8Mzk2LjYy)'>
<polyline points='164.66,293.62 164.66,284.66 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='164.66,289.14 163.26,289.14 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='163.26,293.62 163.26,284.66 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='167.26,353.33 167.26,344.37 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='167.26,348.85 164.30,348.85 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='164.30,353.33 164.30,344.37 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='317.66,383.18 317.66,374.22 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='317.66,378.70 312.46,378.70 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='312.46,383.18 312.46,374.22 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='178.59,323.47 178.59,314.52 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='178.59,318.99 168.97,318.99 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='168.97,323.47 168.97,314.52 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='175.23,263.76 175.23,254.81 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='175.23,259.29 163.48,259.29 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='163.48,263.76 163.48,254.81 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<rect x='146.46' y='275.71' width='17.51' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='335.41' width='19.32' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='365.27' width='168.60' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='305.56' width='27.32' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='146.46' y='245.85' width='22.89' height='26.87' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<text x='176.52' y='293.45' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='59.30px' lengthAdjust='spacingAndGlyphs'>0.311 GB/s</text>
<text x='179.30' y='353.15' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.343 GB/s</text>
<text x='329.70' y='383.01' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>2.993 GB/s</text>
<text x='190.63' y='323.30' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.485 GB/s</text>
<text x='187.26' y='263.59' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.406 GB/s</text>
<g clip-path='url(#cpMTUwLjk0fDU2Ni4wNHwyNDEuMzd8MzgyLjE3)'>
<polyline points='168.76,288.76 168.76,280.63 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='168.76,284.69 167.39,284.69 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='167.39,288.76 167.39,280.63 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='171.30,342.91 171.30,334.79 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='171.30,338.85 168.41,338.85 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='168.41,342.91 168.41,334.79 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='318.53,369.99 318.53,361.86 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='318.53,365.92 313.43,365.92 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='313.43,369.99 313.43,361.86 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='182.40,315.83 182.40,307.71 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='182.40,311.77 172.97,311.77 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='172.97,315.83 172.97,307.71 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='179.10,261.68 179.10,253.56 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='179.10,257.62 167.60,257.62 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<polyline points='167.60,261.68 167.60,253.56 ' style='stroke-width: 1.07; stroke: #505090; stroke-linecap: butt;' />
<rect x='150.94' y='272.51' width='17.14' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='326.66' width='18.91' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='353.74' width='165.04' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='299.59' width='26.74' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<rect x='150.94' y='245.43' width='22.41' height='24.37' style='stroke-width: 1.07; stroke: none; stroke-linecap: butt; stroke-linejoin: miter; fill: #505090;' />
<text x='180.62' y='289.00' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='59.30px' lengthAdjust='spacingAndGlyphs'>0.311 GB/s</text>
<text x='183.34' y='343.15' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.343 GB/s</text>
<text x='330.56' y='370.23' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>2.993 GB/s</text>
<text x='194.43' y='316.08' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.485 GB/s</text>
<text x='191.14' y='261.92' style='font-size: 12.04px;fill: #C0C0C0; font-family: "Arial";' textLength='60.19px' lengthAdjust='spacingAndGlyphs'>0.406 GB/s</text>
</g>
<g clip-path='url(#cpMC4wMHw1NzYuMDB8MC4wMHw0MzIuMDA=)'>
</g>
<defs>
<clipPath id='cpMTQ2LjQ2fDU3MC41MnwyMjEuNDl8MjQxLjM3'>
<rect x='146.46' y='221.49' width='424.06' height='19.88' />
<clipPath id='cpMTUwLjk0fDU2Ni4wNHwyMjEuNDl8MjQxLjM3'>
<rect x='150.94' y='221.49' width='415.10' height='19.88' />
</clipPath>
</defs>
<g clip-path='url(#cpMTQ2LjQ2fDU3MC41MnwyMjEuNDl8MjQxLjM3)'>
<g clip-path='url(#cpMTUwLjk0fDU2Ni4wNHwyMjEuNDl8MjQxLjM3)'>
<text x='358.49' y='235.73' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='25.34px' lengthAdjust='spacingAndGlyphs'>write</text>
</g>
<g clip-path='url(#cpMC4wMHw1NzYuMDB8MC4wMHw0MzIuMDA=)'>
</g>
<defs>
<clipPath id='cpMTQ2LjQ2fDU3MC41Mnw0MC44OHw2MC43Nw=='>
<rect x='146.46' y='40.88' width='424.06' height='19.88' />
<clipPath id='cpMTUwLjk0fDU2Ni4wNHw1NS4zM3w3NS4yMQ=='>
<rect x='150.94' y='55.33' width='415.10' height='19.88' />
</clipPath>
</defs>
<g clip-path='url(#cpMTQ2LjQ2fDU3MC41Mnw0MC44OHw2MC43Nw==)'>
<text x='358.49' y='55.12' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='24.02px' lengthAdjust='spacingAndGlyphs'>read</text>
<g clip-path='url(#cpMTUwLjk0fDU2Ni4wNHw1NS4zM3w3NS4yMQ==)'>
<text x='358.49' y='69.57' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='24.02px' lengthAdjust='spacingAndGlyphs'>read</text>
</g>
<g clip-path='url(#cpMC4wMHw1NzYuMDB8MC4wMHw0MzIuMDA=)'>
<text x='146.46' y='410.14' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>0</text>
<text x='259.13' y='410.14' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>2</text>
<text x='371.80' y='410.14' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>4</text>
<text x='484.47' y='410.14' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>6</text>
<text x='141.53' y='202.40' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='64.70px' lengthAdjust='spacingAndGlyphs'>internal_ssd</text>
<text x='141.53' y='172.54' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='100.03px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress</text>
<text x='141.53' y='142.69' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='136.05px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress_direct</text>
<text x='141.53' y='112.83' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='95.38px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress</text>
<text x='141.53' y='82.98' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='131.39px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress_direct</text>
<text x='141.53' y='383.00' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='64.70px' lengthAdjust='spacingAndGlyphs'>internal_ssd</text>
<text x='141.53' y='353.15' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='100.03px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress</text>
<text x='141.53' y='323.29' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='136.05px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress_direct</text>
<text x='141.53' y='293.44' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='95.38px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress</text>
<text x='141.53' y='263.58' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='131.39px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress_direct</text>
<text x='358.49' y='424.00' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='72.67px' lengthAdjust='spacingAndGlyphs'>Speed (GB/s)</text>
<text x='146.46' y='32.88' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='78.00px' lengthAdjust='spacingAndGlyphs'>File size: 1 GB</text>
<text x='146.46' y='15.78' style='font-size: 14.40px;fill: #C0C0C0; font-family: "Arial";' textLength='213.59px' lengthAdjust='spacingAndGlyphs'>Sequential read and write speeds</text>
<text x='150.94' y='395.70' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>0</text>
<text x='261.23' y='395.70' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>2</text>
<text x='371.52' y='395.70' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>4</text>
<text x='481.81' y='395.70' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='6.67px' lengthAdjust='spacingAndGlyphs'>6</text>
<text x='146.01' y='204.06' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='64.70px' lengthAdjust='spacingAndGlyphs'>internal_ssd</text>
<text x='146.01' y='176.99' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='100.03px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress</text>
<text x='146.01' y='149.91' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='136.05px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress_direct</text>
<text x='146.01' y='122.83' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='95.38px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress</text>
<text x='146.01' y='95.76' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='131.39px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress_direct</text>
<text x='146.01' y='370.22' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='64.70px' lengthAdjust='spacingAndGlyphs'>internal_ssd</text>
<text x='146.01' y='343.15' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='100.03px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress</text>
<text x='146.01' y='316.07' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='136.05px' lengthAdjust='spacingAndGlyphs'>pgytech_cfexpress_direct</text>
<text x='146.01' y='288.99' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='95.38px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress</text>
<text x='146.01' y='261.92' text-anchor='end' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='131.39px' lengthAdjust='spacingAndGlyphs'>ugreen_cfexpress_direct</text>
<text x='358.49' y='409.55' text-anchor='middle' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='72.67px' lengthAdjust='spacingAndGlyphs'>Speed (GB/s)</text>
<text x='150.94' y='47.33' style='font-size: 12.00px;fill: #C0C0C0; font-family: "Arial";' textLength='78.00px' lengthAdjust='spacingAndGlyphs'>File size: 1 GB</text>
<text x='150.94' y='30.23' style='font-size: 14.40px;fill: #C0C0C0; font-family: "Arial";' textLength='213.59px' lengthAdjust='spacingAndGlyphs'>Sequential read and write speeds</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,116 @@
---
title: How to import emails from a .pst file into KMail
description: >
Using a tool called "readst" you can transfer emails from an Outlook
account into any other email client, for example KMail.
date: 2026-05-15T17:30:00+02:00
draft: false
# ShowLastmod: true
scrolltotop: true
images: []
tags:
- email
- KDE
- Linux
---
Here I describe how I imported an email archive from Outlook to KDE's
[KMail][]. This turned out to be harder than expected.
My machine is a Fedora 44 KDE box, but the procedure should be the same or at
least very similar on other Linux systems.
## Prerequisites
Let's assume the following:
1. An Outlook archive file named `archive.pst`.
2. Inside this archive file: An email folder structure with first-level folders
in the style of `MyFolder1`, `MyFolder2` etc. and subfolder
`MyFolder1/MyFolder1Subfolder1` and so on.
I use the venerable [readpst][] tool to extract folders and emails from the
archive file. It's included in common Linux distributions, but at least on
Fedora you don't install it directly, but rather the `libpst` package:
```fish
sudo dnf install libpst
```
```fish
# dnf info libpst
Updating and loading repositories:
Repositories loaded.
Installed packages
Name : libpst
Epoch : 0
Version : 0.6.76
Release : 28.fc44
Architecture : x86_64
Installed size : 192.7 KiB
Source : libpst-0.6.76-28.fc44.src.rpm
From repository : <unknown>
Summary : Utilities to convert Outlook .pst files to other formats
URL : http://www.five-ten-sg.com/libpst/
License : GPL-2.0-or-later
Description : The Libpst utilities include readpst which can convert email messages
: to both mbox and MH mailbox formats, pst2ldif which can convert the
: contacts to .ldif format for import into ldap databases, and pst2dii
: which can convert email messages to the DII load file format used by
: Summation.
Vendor : Fedora Project
```
## Working solution as of 2026
Modern [KMail] does not store emails in the traditional storage formats such
as [Maildir] or [Mbox]. It uses KDE's Akonadi database system. Therefore,
we need to first export all folders and emails from the Outlook data file,
then import these into KMail's database using the `File > Import Messages...`
command.
At first, I struggled a bit to find the correct output format option to make
it work. `readpst` offers a number of different formats -- basically various
flavors of the [MH][]/[maildir][] and the [mbox][] structures. It did _not_ work
with the `-k` option that is meant to produce a dedicated KMail format. I ended
up using the simple `-e` option that produces a directory structure according
to the folders in the Outlook archive, with one separate file for each email
message.
1. Export folders and emails from the Outlook data file:
```fish
readpst -e archive.pst
```
There is no need to create and specifiy a dedicated directory, because
`readpst` will create a directory structure with a generic top-level
directory (in German, this directory is called "Outlook-Datendatei",
Outlook data file).
2. Import the folder structure and emails into KMail:
a. In the `File` menu, choose `Import Messages...`.
b. In the Import dialog that appears, choose "Import KMail Maildirs and
Folder Structure".
{{< figure src="kmail-import-dialog.png" >}}
c. At the bottom of the dialog where it says "Please select the folder to
import to", click on the folder icon. Choose the existing "Local Folders".
There is no need to create an extra folder for the import because KMail
will create folder "KMail-Import" just for you.
d. Click on "Next" and choose your `.pst` file.
e. Start the import process.
3. All imported messages are marked as unread at first, but this will go away
after a while.
[KMail]: https://apps.kde.org/kmail2
[maildir]: https://en.wikipedia.org/wiki/Maildir
[MH]: https://en.wikipedia.org/wiki/MH_Message_Handling_System
[mbox]: https://en.wikipedia.org/wiki/Mbox
[readpst]: https://www.five-ten-sg.com/libpst/rn01re01.html
Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

+11 -7
View File
@@ -1,17 +1,21 @@
services:
build:
image: hugomods/hugo:ci
command: hugo
# image: hugomods/hugo:ci
image: ghcr.io/gohugoio/hugo
command: build
volumes:
- ".:/src"
- ".:/project"
user: 1000:1000
server:
image: hugomods/hugo:ci
command: server --buildDrafts --buildFuture
# image: hugomods/hugo:exts
image: ghcr.io/gohugoio/hugo
command: server --bind 0.0.0.0 --buildDrafts --buildFuture
volumes:
- ".:/src"
# - ".:/src"
- ".:/project"
ports:
- "127.0.0.1:1313:1313"
user: 1000:1000
environment:
- TZ=Europe/Berlin
ENVIRONMENT: development
TZ: Europe/Berlin
+1 -1
View File
@@ -4,6 +4,6 @@ set -e
# https://stackoverflow.com/a/1482133/270712
MYDIR=`dirname -- "$( readlink -f -- "$0"; )";`
pushd "$MYDIR"
git pull
git pull --recurse-submodules
docker compose -f docker-compose.yml up build
popd
+1 -1
View File
@@ -1,5 +1,5 @@
#!/bin/bash
pushd /home/daniel/local/Code/blog
docker compose up build && rsync -av --delete public/* bovender.de:/var/docker-data/nginx/www/bovender/
docker compose up build && rsync -e "ssh -i /home/daniel/.ssh/id_rsa" -av --delete public/* bovender.de:/var/docker-data/nginx/www/bovender/
popd