Doing the Thing that OpenSSH won’t do

On UNIX, the /sbin/agetty program is supposed to read the /etc/issue file and perform a parameter expansion before displaying it as a pre-login banner. Since agetty only runs for LOCAL terminals and an OpenSSH virtual terminal isn’t local, we can’t use agetty to parse the /etc/issue file for OpenSSH. We use a different file – /etc/ – that’s free of the parameters. But what if we /want/ parameters?

Here’s a simple Perl script to perform some of the parameter substitution that would normally be handled by /sbin/agetty. The main problem with this is it still produces static text output so is guaranteed to be at least somewhat out of date (and in the case of tty info, completely wrong).

use strict;
use warnings;

# Makes the /etc/ file from source

my $SOURCE     = "/etc/issue";
my $DEST       = "/etc/";
my $baudrate   = `stty | head -1 | cut -d' ' -f 2`;
my $time       = `date`;
my $name       = `uname -n`;
my $tty        = `tty`;
my $machine    = `uname -m`;
my $os         = `uname -s`;
my $domainname = `dnsdomainname`;
my $release    = `uname -r`;
my $date       = `date +%F`;
my $usercount  = `who -u | wc -l`;
my $version    = `uname -v`;

chomp $baudrate;
chomp $time;
chomp $name;
chomp $tty;
chomp $machine;
chomp $os;
chomp $domainname;
chomp $release;
chomp $date;
chomp $usercount;
chomp $version;

open(SOURCE, '<', $SOURCE) or die $!;
open(DEST,   '>', $DEST)   or die $!;

foreach (<SOURCE>) {
        $_ =~ s/\\b/$baudrate/g;
        $_ =~ s/\\d/$date/g;
        $_ =~ s/\\s/$os/g;
        $_ =~ s/\\l/$tty/g;
        $_ =~ s/\\m/$machine/g;
        $_ =~ s/\\n/$name/g;
        $_ =~ s/\\o/$domainname/g;
        $_ =~ s/\\r/$release/g;
        $_ =~ s/\\u/$usercount/g;
        if ($usercount == 1) {
                $_ =~ s/\\U/1 user/g;

        else {
                $_ =~ s/\\U/$usercount users/g;

        $_ =~ s/\\v/$version/g;

        print DEST $_;

  1. #1 by Joshua on July 13, 2011 - 7:18 PM

    I discovered a potential pitfall of this. For some reason, I had /etc/ hardlinked to /etc/issue on SavageChicken. Every time I ran the script, all it did was reduce the size of /etc/issue to zero bytes. It took me a while to figure out that the two were actually aliases of each other. Once I deleted the /etc/ alias, everything ran fine. 🙂

  2. #2 by Joshua on July 18, 2011 - 6:40 AM

    The other nice thing about this is I can change my $time = `date`; to my $time = `ddate`;. This has the effect of printing the Discordian date instead of Gregorian. 🙂

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: