Created
May 10, 2026 15:54
-
-
Save rwmjones/1e5221ab392f24a2edf0476892ad4e27 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Let's see how bad QWEN3 is at a coding task ... | |
| > please write me an nbdkit plugin in C which will serve the poem "the 12 days of christmas" in a disk image | |
| Here is a complete C plugin for `nbdkit` that serves "The 12 Days of Christmas" as a disk image. | |
| ### Overview | |
| * **Disk Size:** The plugin presents a virtual 1 MB block device. | |
| * **Content:** The poem is embedded at the beginning of the disk image. | |
| * **Padding:** Any data requested beyond the length of the poem is returned as null bytes (simulating a sparse disk). | |
| * **Read-Only:** The device is read-only, as per the nature of a disk image. | |
| ### Source Code (`nbdkit-christmas.c`) | |
| ```c | |
| /* nbdkit-christmas.c | |
| * | |
| * An nbdkit plugin that serves "The 12 Days of Christmas" poem. | |
| * It presents the poem as a 1 MB read-only disk image. | |
| * | |
| * Compile with: | |
| * gcc -shared -o nbdkit-christmas.so -fPIC nbdkit-christmas.c $(pkg-config --cflags --libs nbdkit) | |
| * | |
| * Usage: | |
| * nbdkit --plugin ./nbdkit-christmas.so -p 10809 | |
| */ | |
| #include <nbdkit-plugin.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| /* The full text of "The 12 Days of Christmas" */ | |
| static const char *poem_text = | |
| "1. On the first day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " A partridge in a pear tree.\n\n" | |
| "2. On the second day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "3. On the third day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "4. On the fourth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "5. On the fifth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "6. On the sixth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "7. On the seventh day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Seven swans a-swimming,\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "8. On the eighth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Eight maids a-milking,\n" | |
| " Seven swans a-swimming,\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "9. On the ninth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Nine ladies dancing,\n" | |
| " Eight maids a-milking,\n" | |
| " Seven swans a-swimming,\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "10. On the tenth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Ten lords a-leaping,\n" | |
| " Nine ladies dancing,\n" | |
| " Eight maids a-milking,\n" | |
| " Seven swans a-swimming,\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "11. On the eleventh day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Eleven pipers piping,\n" | |
| " Ten lords a-leaping,\n" | |
| " Nine ladies dancing,\n" | |
| " Eight maids a-milking,\n" | |
| " Seven swans a-swimming,\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree.\n\n" | |
| "12. On the twelfth day of Christmas,\n" | |
| " my true love sent to me:\n" | |
| " Twelve drummers drumming,\n" | |
| " Eleven pipers piping,\n" | |
| " Ten lords a-leaping,\n" | |
| " Nine ladies dancing,\n" | |
| " Eight maids a-milking,\n" | |
| " Seven swans a-swimming,\n" | |
| " Six geese a-laying,\n" | |
| " Five golden rings,\n" | |
| " Four calling birds,\n" | |
| " Three French hens,\n" | |
| " Two turtle doves,\n" | |
| " And a partridge in a pear tree."; | |
| /* Calculate size at compile time (strlen of the string) */ | |
| static const uint64_t poem_len = sizeof(poem_text) - 1; /* -1 to exclude null terminator */ | |
| static const uint64_t disk_size = 1024 * 1024; /* 1 MB disk image */ | |
| /* Initialize the plugin */ | |
| static int init(void) | |
| { | |
| printf("Christmas plugin initialized.\n"); | |
| printf("Poem size: %" PRIu64 " bytes\n", poem_len); | |
| printf("Disk image size: %" PRIu64 " bytes\n", disk_size); | |
| return 0; | |
| } | |
| /* Called when a connection is opened */ | |
| static int open(nbd_context *ctx) | |
| { | |
| printf("Connection opened.\n"); | |
| return 0; | |
| } | |
| /* Called when a connection is closed */ | |
| static int close(nbd_context *ctx) | |
| { | |
| printf("Connection closed.\n"); | |
| return 0; | |
| } | |
| /* Return the size of the disk */ | |
| static uint64_t get_size(nbd_context *ctx) | |
| { | |
| return disk_size; | |
| } | |
| /* Read data from the disk */ | |
| static int read_data(nbd_context *ctx, off_t offset, uint32_t count, void *buf, | |
| uint32_t *flags, int *error) | |
| { | |
| /* Sanity check */ | |
| if (offset < 0) { | |
| *error = errno; | |
| return -1; | |
| } | |
| /* Calculate remaining bytes available in the poem */ | |
| uint64_t remaining = poem_len - offset; | |
| /* Determine how much data we actually copy */ | |
| uint32_t copy_count = count; | |
| if (remaining > 0) { | |
| if ((uint64_t)count > remaining) { | |
| copy_count = (uint32_t)remaining; | |
| } | |
| } else { | |
| /* Offset is beyond the poem, we will just pad with zeros */ | |
| copy_count = count; | |
| } | |
| /* Copy poem data if within bounds */ | |
| if (copy_count > 0 && offset < poem_len) { | |
| memcpy(buf, poem_text + offset, copy_count); | |
| } | |
| /* Pad the rest with zeros if needed */ | |
| if (copy_count < count) { | |
| memset((char *)buf + copy_count, 0, count - copy_count); | |
| } | |
| /* Set return values for the plugin framework */ | |
| *flags = 0; | |
| *error = 0; | |
| return 0; | |
| } | |
| /* Export flags (read-only) */ | |
| static uint32_t flags(void) | |
| { | |
| return 0; /* Default flags (read-write), we enforce read-only by not implementing write() */ | |
| } | |
| /* The main plugin structure exported for nbdkit to load */ | |
| struct nbdkit_plugin nbdkit_plugin = { | |
| .name = "christmas", | |
| .init = init, | |
| .get_size = get_size, | |
| .open = open, | |
| .close = close, | |
| .read = read_data, | |
| /* We do not implement write, flush, or preallocate, making it read-only */ | |
| }; | |
| ``` | |
| ### Compilation | |
| To compile this plugin, you need `nbdkit` development files installed. | |
| ```bash | |
| gcc -shared -o nbdkit-christmas.so -fPIC nbdkit-christmas.c $(pkg-config --cflags --libs nbdkit) | |
| ``` | |
| *Note: If `pkg-config` cannot find nbdkit, you may need to specify the library path manually, e.g., `-lnbdkit -L/usr/lib/nbdkit`.* | |
| ### Usage | |
| Run the `nbdkit` server with your new plugin: | |
| ```bash | |
| nbdkit --plugin ./nbdkit-christmas.so -U -p 10809 | |
| ``` | |
| * `--plugin`: Loads your custom `.so` file. | |
| * `-U`: Disables the UDS (Unix Domain Socket) listener for simplicity in this example. | |
| * `-p 10809`: Listens on TCP port 10809. | |
| ### Connecting to the Server | |
| You can test this disk image using `libnbd` (the client library) or standard block tools. | |
| **Using `nbd-client` (if available):** | |
| ```bash | |
| nbd-client -p 10809 <host> /dev/nbd0 | |
| ``` | |
| **Using `dd` to read the poem:** | |
| Once connected (e.g., to `/dev/nbd0`): | |
| ```bash | |
| # Read the first 1000 bytes (should be the start of the poem) | |
| dd if=/dev/nbd0 bs=1000 count=1 | |
| ``` | |
| **Using a hex dump:** | |
| ```bash | |
| hexdump -C /dev/nbd0 | |
| ``` | |
| If you access the data correctly, the first part of the disk will contain the ASCII text of the poem, followed by null bytes until the 1 MB mark. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment