The unborn are a convenient group of people to advocate for

"The unborn are a convenient group of people to advocate for. They never make demands of you; they are morally uncomplicated, unlike the incarcerated, addicted, or the chronically poor; they don’t resent your condescension or complain that you are not politically correct; unlike widows, they don’t ask you to question patriarchy; unlike orphans, they don’t need money, education, or childcare; unlike aliens, they don’t bring all that racial, cultural, and religious baggage that you dislike; they allow you to feel good about yourself without any work at creating or maintaining relationships; and when they are born, you can forget about them, because they cease to be unborn. You can love the unborn and advocate for them without substantially challenging your own wealth, power, or privilege, without re-imagining social structures, apologizing, or making reparations to anyone. They are, in short, the perfect people to love if you want to claim you love Jesus, but actually dislike people who breathe. Prisoners? Immigrants? The sick? The poor? Widows? Orphans? All the groups that are specifically mentioned in the Bible? They all get thrown under the bus for the unborn."

Methodist Pastor David Barnhart

Leave A Reply

PHP: Using __halt_compiler()

PHP has a mechanism that allows you stop the compiler on a given line. This allows you to put non-PHP code after that line without affecting your code. You can put data, JSON, HTML, etc after the __halt_compiler() line and then read it with your script. Here is a simple function that reads the text after your __halt_compiler()

// Borrowed from https://gist.github.com/ziadoz/5286233
function get_halt_str() {
    return file_get_contents(__FILE__, false, null, __COMPILER_HALT_OFFSET__ + 1);
}

See also: Perl version

Leave A Reply

Perl: The __DATA__ construct

Perl has a unique feature where if it sees a line that contains __DATA__ the parser will stop there as if the file ended. This allows you put non-perl code after your __DATA__ line: text, json, HTML, etc. Perl will even allow you to read the text after the __DATA__ like it's a normal file handle. This function will read all the text after your __DATA__ block.

sub get_data_str {
    local $/ = undef; # Slurp mode
    return readline(DATA);
}

Note: Perl also recognizes __END__ but that text is not readable.

See also: PHP version

Leave A Reply

Vim encryption

Vim has simple built in encryption. If you have a text file you want to encrypt you can run the commands:

:set cryptmethod=blowfish2
:X

Vim will prompt you for a password, and then the next time you save the file it will be encrypted automatically. When you open the file it will prompt you for the password. If you enter the wrong password you'll see a bunch of gibberish.

Leave A Reply

Perl: hash to ini

I'm a big fan of .ini files because they're human readable, and also very machine readable. I wrote a quick function to convert a hashref to a simple .ini string.

my $str = hash_to_ini({ data => { 'name' => 'scott', animal => 'dog' }});
sub hash_to_ini {
    my $x   = $_[0];
    my $ret = '';

    foreach my $key (sort(keys(%$x))) {
        my $val = $x->{$key};

        if (ref($val) eq "HASH") {
            $ret .= "[$key]\n";
            foreach my $k (sort(keys(%$val))) { $ret .= "$k = " . $val->{$k} . "\n"; }
        } else { $ret .= "$key = $val\n" }
    }

    $ret =~ s/\n\[/\n\n[/; # Add a space between sections
    return $ret;
}

I also wrote a version in PHP

function hash_to_ini($x) {
    $ret = '';

    foreach (array_keys($x) as $key) {
        $val = $x[$key];

        if (is_array($val)) {
            $ret .= "[$key]\n";
            foreach (array_keys($val) as $k) { $ret .= "$k = " . $val[$k] . "\n"; }
        } else { $ret .= "$key = $val\n"; }
    }

    $ret = preg_replace("/\n\[/", "\n\n[", $ret);
    return $ret;
}

Note: see also parse_ini()

Leave A Reply

Perl: Method to send a simple SMTP message

This is a quick method to send an SMTP email message using on core Perl modules.

use Net::SMTP;
use Time::Piece;

my $smtp_server = "mail.server.com";
my $smtp        = Net::SMTP->new($smtp_server, Timeout => 3, Hello => 'hostname.server.com');

my $err;
my $ok = send_email('to@domain.com', 'from@domain2.com', 'Test subject', '<b>HTML</b> body', \$err);

if (!$ok) { print "Error: $err" }
sub send_email {
    my ($to, $from, $subject, $html_body, $err) = @_;

    $smtp->mail($from);
    my $ok = $smtp->to($to);

    if ($ok) {
        # Ghetto strip tags
        my $text_body = $html_body =~ s/<[^>]*>//rgs;
        my $sep       = time() . "-$smtp_server";

        my $headers  = "To: $to\n";
        $headers    .= "From: $from\n";
        $headers    .= "Subject: $subject\n";
        $headers    .= "Date: " . localtime->strftime() . "\n";
        $headers    .= "Message-ID: <" . time() . "\@$smtp_server>\n";
        $headers    .= "Content-type: multipart/alternative; boundary=\"$sep\"\n\n";
        $headers    .= "This is a multi-part message in MIME format\n\n";

        # Text version
        $headers .= "--$sep\n";
        $headers .= "Content-Type: text/plain\n\n";
        $headers .= "$text_body\n\n";

        # HTML version
        $headers .= "--$sep\n";
        $headers .= "Content-Type: text/html\n\n";
        $headers .= "$html_body\n\n";

        # Closing separator
        $headers .= "--$sep--\n";

        $smtp->data();
        $smtp->datasend($headers);
        $smtp->dataend();
    } else {
        $$err = $smtp->message();
    }

    return $ok;
}
Leave A Reply

Bash: Quick backup

Often I will need to take a quick backup of a directory or file before I make some changes. Sometimes I will need multiple backups, so I include the date/time in the output filename. After doing it manually enough I wrote a quick bash function that will handle creating the backup file, and naming it appropriately. Put these in your ~/.bashrc or copy and paste to your terminal

# Quick tar/file commands
qtar() { C=$(basename $1); O=/var/tmp/quicktar-$C-$(date +%F_%H-%M).tar.gz; tar -cvpaf $O $*; echo; ls -sh $O; }
qfb()  { C=$(basename $1); O=/var/tmp/quickfile-$C-$(date +%F_%H-%M).gz; gzip $1 -c > $O; ls -sh $O; }

Then to run it simply invoke it like this:

# Multiple files or directories
qtar file1.txt file2.txt
qtar /path/to/dir
qtar files/

# One file
qfb /etc/dhcp/dhcpd.conf
qfb /etc/php.ini

This will make an appropriately named file in /var/tmp/ with the files/dirs you listed tarred and gzipped up. It's not perfect, there are some corner cases that will break it, but I needed something super simple to drop on remote servers for quicky backups.

Update: Less common, but I also whipped up a zip option.

qzip() { C=$(basename $1); O=/var/tmp/quickzip-$C-$(date +%F_%H-%M).zip; zip -9vr $O $*; ls -sh $O; }
Leave A Reply

Subway: Sub of the Day

Sub of the day for my local Subway.

Day Sandwich
Monday Sweet Onion Teriyaki
Tuesday Spicy Italian
Wednesday Oven Roasted Turkey
Thursday Italian BMT
Friday Tuna
Saturday Black Forest Ham
Sunday Meatball
Leave A Reply

Characters and places in Heretics of Dune

Notes I took while reading Heretics of Dune. Information augmented with data from Dune Wiki.

Item Description
Hedley Tuek High Priest, titular ruler of Rakis
Miles Teg Mentat
Taraza Mother Superior
Sheena Young girl, can command worms, family dies
Darwi Odrade Bene Gessirit, tries to seduce Teg
Gammu Name by which the planet Giedi Prime went after the fall of House Harkonnen
Rakis Renamed Arrakis
Bashar Military rank of the Sardukar
Leave A Reply

Linux: Regenerate SSH host keys

Fedora and CentOS automatically regenerate SSH host keys on bootup if the key files are missing. This makes it easy to trigger regeneration as you simply remove the keys, and reboot the server. Other distributions are not quite as forgiving and require manual intervention. These are the steps I've used on Debian to get updated host keys.

rm /etc/ssh/ssh_host_*
ssh-keygen -f /etc/ssh/ssh_host_rsa_key     -N '' -q -t rsa
ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key   -N '' -q -t ecdsa
ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -q -t ed25519

ls /etc/ssh/*key* -lsh

systemctl restart sshd
Leave A Reply

Updated my Javascript Unixtime tool

I updated and modernized my Javascript Unixtime tool. If you have to work with Unixtimes it's a really handy tool to process them in a more human friendly fashion.

Leave A Reply

Books of 2022

List of books I read in 2022. Also see the list of 2021. The date indicated denotes the date I started reading the book.

2022-01-03 - A Spell for Chameleon - Xanth #1 by Piers Anthony - 344 pages
2022-01-08 - Raise the Titanic! by Clive Cussler - 373 pages
2022-01-14 - The Hike by Drew Magary - 278 pages
2022-01-18 - Grave Peril - Dresden Files #3 by Jim Butcher - 378 pages
2022-01-24 - The Cat Who Ate Danish Modern by Lilian Jackson Braun - 191 pages
2022-01-27 - Snow Crash by Neal Stephenson - 468 pages
2022-02-03 - The Source of Magic - Xanth #2 by Piers Anthony - 326 pages
2022-02-08 - On the Road by Jack Kerouac - 310 pages
2022-02-12 - Summer Knight - Dresden Files #4 by Jim Butcher - 371 pages
2022-02-18 - James and The Giant Peach by Roald Dahl - 126 pages
2022-02-19 - Heretics Of Dune by Frank Herbert - 542 pages
2022-02-28 - Lost Souls by Dean R. Koontz - 350 pages
2022-03-05 - Castle Roogna - Xanth #3 by Piers Anthony - 329 pages
2022-03-09 - The Complete Aliens Omnibus: Volume One - Earth Hive by Steve Perry - 266 pages
2022-03-13 - Joyland by Stephen King - 272 pages
2022-03-18 - Death Masks - Dresden Files #5 by Jim Butcher - 378 pages
2022-03-24 - The Cat Who Could Read Backwards by Lilian Jackson Braun - 251 pages
2022-03-28 - Bachman Books - Running Man by Stephen King - 212 pages
2022-03-31 - About A Boy by Nick Hornby - 307 pages
2022-04-04 - Centaur Aisle - Xanth #4 by Piers Anthony - 294 pages
2022-04-09 - Skeleton Crew by Stephen King - 499 pages
2022-04-17 - Death on the Nile by Agatha Christie - 259 pages
2022-04-20 - Blood Rites - Dresden Files #6 by Jim Butcher - 372 pages
2022-04-26 - Murder on the Orient Express by Agatha Christie - 208 pages
2022-04-29 - The Complete Aliens Omnibus: Volume One - Nightmare Asylum by Steve Perry - 271 pages
2022-05-03 - Ogre, Ogre - Xanth #5 by Piers Anthony - 307 pages
2022-05-07 - Old Man’s War by John Scalzi - 362 pages
2022-05-13 - Me and Bobby McGee by John Scalzi - 268 pages
2022-05-17 - The Haunting Of Hill House by Shirley Jackson - 182 pages
2022-05-20 - Blood Rites by Jim Butcher - 435 pages

2022-xx-xx - The Last Colony by John Scalzi - 320 pages
2022-xx-xx - The Ghost Brigades by John Scalzi - 374 pages

Leave A Reply

Perl: Find unique items in an array

I need to extract all the unique elements from an array. There is no built-in way to do this, but there are several user functions you can use.

my @x = qw(one two one three one four);
my @y = array_unique(@x); # ("one", "two", "three", "four")
# Borrowed from: https://perlmaven.com/unique-values-in-an-array-in-perl
sub array_unique {
    my %seen;
    return grep { !$seen{$_}++ } @_;
}

I stand corrected, List::Util includes a uniq() function to do exactly this, is a core module, and is included with all Perl installations.

Leave A Reply

Perl: Calculate time difference in human readable way

Perl function to return a human readable string for a time duration in seconds.

my $str = human_time_diff(320);  # "5 minutes"
my $str = human_time_diff(3700); # "1 hour"
sub human_time_diff {
    my $seconds = int(shift());
    my $num     = 0;
    my $unit    = "";
    my $ret     = "";

    if ($seconds < 120) {
        $ret = "just now";
    } elsif ($seconds < 3600) {
        $num  = int($seconds / 60);
        $unit = "minute";
    } elsif ($seconds < 86400) {
        $num  = int($seconds / 3600);
        $unit = "hour";
    } elsif ($seconds < 86400 * 30) {
        $num  = int($seconds / 86400);
        $unit = "day";
    } elsif ($seconds < (86400 * 365)) {
        $num  = int($seconds / (86400 * 30));
        $unit = "month";
    } else {
        $num  = int($seconds / (86400 * 365));
        $unit = "year";
    }

    if ($num > 1) { $unit .= "s"; }
    if ($unit) { $ret = "$num $unit"; }

    return $ret;
}

See also: PHP version

Leave A Reply

PHP: Calculate time difference in human readable way

function human_time_diff(int $seconds) {
    $num  = 0;
    $unit = "";

    if ($seconds < 300) {
        $ret = "just now";
    } elseif ($seconds < 3600) {
        $num  = intval($seconds / 60);
        $unit = "minute";
    } elseif ($seconds < 86400) {
        $num  = intval($seconds / 3600);
        $unit = "hour";
    } elseif ($seconds < 86400 * 30) {
        $num  = intval($seconds / 86400);
        $unit = "day";
    } elseif ($seconds < (86400 * 365)) {
        $num  = intval($seconds / (86400 * 30));
        $unit = "month";
    } else {
        $num  = intval($seconds / (86400 * 365));
        $unit = "year";
    }

    if ($num > 1) {
        $unit .= "s";
    }

    if ($unit) {
        $ret = "$num $unit";
    }

    return $ret;
}

See also: Perl version

Leave A Reply