Happy "21th" birthday, Nmap!

David Fifield <[email protected]> Sat, 1 Sep 2018 10:29:58 -0600
Newsgroups gmane.comp.security.nmap.devel
Message-ID <[email protected]>
On Sat, Sep 01, 2018 at 08:28:01AM +1000, Dave Horsfall wrote:
> My records show that NMAP was released on this day in 1997.  It's a
> wonderful network scanner, which just keeps better and better.

This reminds me of a bug that I thought I reported before, but now I
cannot find. COBOL had Y2K, Unix has its year 2038, and Nmap has its
year 2018 problem--its "21th" birthday.

$ ./nmap -v
Starting Nmap 7.70SVN ( https://nmap.org ) at 2018-09-01 10:22 MDT
Happy 21th Birthday to Nmap, may it live to be 121!

Here's a patch that will instead give the correct "21st", "22nd",
"23rd", and so on into the future. You can test it with the faketime
program.

$ faketime 1997-09-01 ./nmap -v
Happy 0th Birthday to Nmap, may it live to be 100!
$ faketime 1998-09-01 ./nmap -v
Happy 1st Birthday to Nmap, may it live to be 101!
$ faketime 2018-09-01 ./nmap -v
Happy 21st Birthday to Nmap, may it live to be 121!
$ faketime 2019-09-01 ./nmap -v
Happy 22nd Birthday to Nmap, may it live to be 122!
$ faketime 2020-09-01 ./nmap -v
Happy 23rd Birthday to Nmap, may it live to be 123!
$ faketime 2118-09-01 ./nmap -v
Happy 121st Birthday to Nmap, may it live to be 221!

_______________________________________________
Sent through the dev mailing list
https://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/
0001-Fix-ordinal-numbers-in-birthday-announcement-21st-no.patch (text/x-diff, 2.2 KB)
From c90c70a8851a747c679fb5fc7f84064e31f8e256 Mon Sep 17 00:00:00 2001
From: David Fifield <[email protected]>
Date: Sat, 1 Sep 2018 10:09:52 -0600
Subject: [PATCH] Fix ordinal numbers in birthday announcement ("21st" not
 "21th").
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Hardcoding a "th" suffix worked fine for the 4th through 20th birthdays
(2001–2017). But it's 2018 now, and "21th" just ain't right.
---
 nmap.cc | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/nmap.cc b/nmap.cc
index 117d3d8fb..ad6d5ebdd 100644
--- a/nmap.cc
+++ b/nmap.cc
@@ -1399,6 +1399,29 @@ void parse_options(int argc, char **argv) {
 
 }
 
+// Convert integers 0, 1, 2, 3, 4, ... into English ordinals "0th", "1st",
+// "2nd", "3rd", "4th", .... Returns a pointer into a static buffer.
+static const char *ordinal(int n) {
+  static char buf[32];
+  int p;
+
+  p = n;
+  if (n < 0)
+    p = -n; // Fails for INT_MIN.
+  if ((p / 10) % 10 == 1)
+    Snprintf(buf, sizeof(buf), "%dth", n);
+  else if (p % 10 == 1)
+    Snprintf(buf, sizeof(buf), "%dst", n);
+  else if (p % 10 == 2)
+    Snprintf(buf, sizeof(buf), "%dnd", n);
+  else if (p % 10 == 3)
+    Snprintf(buf, sizeof(buf), "%drd", n);
+  else
+    Snprintf(buf, sizeof(buf), "%dth", n);
+
+  return buf;
+}
+
 void  apply_delayed_options() {
   int i;
   char tbuf[128];
@@ -1522,7 +1545,7 @@ void  apply_delayed_options() {
   log_write(LOG_STDOUT | LOG_SKID, "Starting %s %s ( %s ) at %s\n", NMAP_NAME, NMAP_VERSION, NMAP_URL, tbuf);
   if (o.verbose) {
     if (local_time->tm_mon == 8 && local_time->tm_mday == 1) {
-      log_write(LOG_STDOUT | LOG_SKID, "Happy %dth Birthday to Nmap, may it live to be %d!\n", local_time->tm_year - 97, local_time->tm_year + 3);
+      log_write(LOG_STDOUT | LOG_SKID, "Happy %s Birthday to Nmap, may it live to be %d!\n", ordinal(local_time->tm_year - 97), local_time->tm_year + 3);
     } else if (local_time->tm_mon == 11 && local_time->tm_mday == 25) {
       log_write(LOG_STDOUT | LOG_SKID, "Nmap wishes you a merry Christmas! Specify -sX for Xmas Scan (https://nmap.org/book/man-port-scanning-techniques.html).\n");
     }
-- 
2.18.0