LJ Archive


Linux Journal—NSA's “Extremist Forum”

Just came across: “If you visit the forum page for the popular Linux Journal, dedicated to the open-source operating system Linux, you could be fingerprinted regardless of where you live because the XKEYSCORE source code designates the Linux Journal as an 'extremist forum'” (www.defenseone.com/technology/2014/07/if-you-do-nsa-will-spy-you/88054/?oref=govexec_today_nl).

Andy Bach

Crazy, isn't it? Although it's frustrating to draw the attention of the NSA, we don't plan on changing how we do things. We're advocates of freedom, and if anything, this makes us more so!—Shawn Powers

Vim Macros

Regarding Kyle Rankin's “The Only Mac I Use” article in the July 2014 issue: I knew all about macros. What I didn't know was what <ctrl>-a did. That is going to save me so much time in the future.


Extremist Bonus Points?

After the latest news regarding the XKEYSCORE program, I felt it was a great time to subscribe. Now that I subscribed, do I get a free upgrade to extremist financier?

Chris at jupiterbroadcasting.com brought me—LAS ep320.

Sean Rodriguez

Although we haven't seen any “upgrades” yet ourselves, I must admit I'm a little more nervous than usual when I go through airport security now!—Shawn Powers

Leap Year Problems

Regarding Dave Taylor's “Days Between Dates” article in the July 2014 issue, I think he has a big problem with the valid_date.sh way of checking for leap year:

harrie@v1:~> ./lj243_valid_date.sh 2 29 1776
checking for feb 29 : was 1776 a leap year?
Yes, 1776 was a leapyear, so February 29, 1776 is a valid date.
harrie@v1:~> ./lj243_valid_date.sh 2 29 1929
checking for feb 29 : was 1929 a leap year?
Yes, 1929 was a leapyear, so February 29, 1929 is a valid date.

Well, 1929 was not a leap year. Using grep -w solves this:

harrie@v1:~> ./lj243_valid_date-w.sh 2 29 1929
checking for feb 29 : was 1929 a leap year?
Oops, 1929 wasn't a leapyear, so February only had 28 days.
harrie@v1:~> cat lj243_valid_date-w.sh
mon=$1; day=$2; year=$3
if [ $mon -eq 2 -a $day -eq 29 ] ; then
echo checking for feb 29 : was $3 a leap year?
leapyear=$(cal 2 $year | grep -w 29)
if [ ! -z "$leapyear" ] ; then
echo "Yes, $year was a leapyear, so February 29, $year \
is a valid date."
echo "Oops, $year wasn't a leapyear, so February only \
had 28 days."

Harrie Wijnans

Dave Taylor replies: Yup, someone else also pointed out the flaw in my leap year test. Got a much better one in the next column. Thanks for writing in, Harrie!

Harrie Wijnans replies: Yeah, my solution, of course, fails for the year 29. Adding tail solves that (and the -w flag for grep has no real meaning anymore):

leapyear=$(cal 2 $year | tail +3 | grep -w 29)

Dave Taylor replies: Nah, the solution is to take a sharp left turn and think about it differently. The question isn't “is there a Feb 29”, but “how many days are in the yearâ” So, with help from GNU date:

$ date -d 12/31/1929 +%j
$ date -d 12/31/1932 +%j

With this test, you can see that 1932 was a leap year, but 1929 wasn't.

Harrie Wijnans replies: That one fails for years < 1901:

harrie@v1:~> date -d 1901/12/31
Tue Dec 31 00:00:00 AMT 1901
harrie@v1:~> date -d 1900/12/31
date: invalid date `1900/12/31'

That is, for the date on my Linux (openSUSE 12.1), and it also fails for 12/31/1900:

harrie@v1:~> date --version
date (GNU coreutils) 8.14
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David MacKenzie.

Dave Taylor replies: Actually, here's the cleanest version of all of this:

function isleap
  # If you have GNU date on your Linux system, this is superior:
  #   leapyear=$(date -d 12/31/$1 +%j | grep 366)

  # If you don't have GNU date (Mac OS X doesn't, for example), 
  # use this:

  leapyear=$(cal -j 12 $1 | grep -E '[^12]366')

But, there's something else going on then, because I also have date 8.4, and it works fine:

$ date -d 12/31/1844 +%j
$ date -d 12/31/1810 +%j


Harrie Wijnans replies: The date.c from the 18.4 that I got from rpmfind.net/linux/sourceforge/m/ma/magiclinux-plus/Source26/coreutils-8.14-1mgc25.src.rpm uses parse_datetime to fill a struct tm, which has:

/* Used by other time functions.  */
struct tm
  int tm_sec;           /* Seconds.     [0-60] (1 leap second) */
  int tm_min;           /* Minutes.     [0-59] */
  int tm_hour;          /* Hours.       [0-23] */
  int tm_mday;          /* Day.         [1-31] */
  int tm_mon;           /* Month.       [0-11] */
  int tm_year;          /* Year - 1900.  */
  int tm_wday;          /* Day of week. [0-6] */
  int tm_yday;          /* Days in year.[0-365] */
  int tm_isdst;         /* DST.         [-1/0/1]*/

#ifdef  __USE_BSD
  long int tm_gmtoff;       /* Seconds east of UTC.  */
  __const char *tm_zone;    /* Timezone abbreviation.  */
  long int __tm_gmtoff;     /* Seconds east of UTC.  */
  __const char *__tm_zone;  /* Timezone abbreviation.  */

Apparently, openSUSE library does not accept the year field to be <= 0. Sorry, I'm lost here. I'm not that experienced in Linux C programming, and lib/parse-datetime.y even uses bison, which I hardly ever used.

Beware of the cal -j you gave as an example. Try it for 2000, which is missed as a leap year. (Are we lucky it was a leap year? Otherwise, the “millennium-bug” would have been much more severe.)

This is because there, 366 is at the start of the line, so there are no characters in front of it, hence it does not match [^12]366. An extra -e ^366 would solve that and still not see 1366 or 2366 as leap years; 366 still would be considered a leap year.

I thought about the cal 2 $year, and grep -v February, but that is language-dependent. (Try LANG=nl_NL.UTF8 cal 2 2012 or fr_FR.UTF8—no February in there.)

I'd say, the person who claims creating scripts for everyone and every environment is simple, never tried it.

Looking forward to reading your next column.


It is 19.48 GMT on 9 July 2014. I only say this in case at this point in time there is a problem with your system. Reading my LJ, I followed the link to the new letters “page” to find just two letters there. There always were more when they were included in the magazine (print and of course digital). Only two! I cannot believe that LJ readers have been that quiet.

Roy Read

The past couple months, we've been experimenting with moving Letters to the Editor to the Web, or at least partially to the Web. We received a lot of feedback, and so we have put things back the way they used to be. We appreciate the feedback, and really do listen!—Shawn Powers

Dave Taylor's June 2014 Work the Shell Column

The first attempt at running Dave's script on Solaris 8 failed because the default Solaris shell in Solaris 10 and before does not support the $() syntax.

The issue after switching to /bin/bash appears to be likely a cut-and-paste error. The script works as is for me, but if you modify the first sed replacement so that the space is removed:

myPATH="$(echo $PATH | sed -e 's//~~/g' -e 's/:/ /g')"

Then the output is a sed error, which matches your published results:

First RE may not be null
0 commands, and 0 entries that weren't marked executable


Dave Taylor replies: thanks for the update. It's been a while since I had access to a Solaris system!

Bug in Dave Taylor's Days Between Dates Script

Dave's leap year test in the July 2014 issue contains a little bug. He uses:

leapyear=$(cal 2 $year | grep '29')

which looks for 29 in a calendar output. If 29 is present, it is supposed to be a leap year. However, if the user tries to find out if 2029 is a leap year, the script will fail, because it does contain 29 in the output, even though it can never be a leap year. A better version of this test would be:

leapyear=$(cal -h 2 $year | tail -n 2 | grep '29')

This will look for 29 only in the last 2 lines of the calendar. And, it also will omit the highlighting of today's date, just in case it is February 29 today. A highlighted 29 would not be found by grep.

San Bergmans

Dave Taylor replies: Another good solution to a problem that a number of people have pointed out, San!

Here's my latest solution to that problem, one requiring GNU date:

leapyear=$(date -d 12/31/$1 +%j | grep 366)

A different approach, for sure! Thanks for writing.

Digital Encryption and a Random Bit Generator

A printable poster of an unbreakable encryption algorithm declassified by the NSA can be downloaded from www.tag.md/public.

In addition, there is a POSIX C implementation of a digital non-deterministic random bit generator.

Mark Knight

Cool stuff, thanks Mark!—Shawn Powers

Comments on Dave Taylor's June 2014 Work the Shell Column

Solaris 8 was actually released in 2000, not 2004.

Peter Schow

Dave Taylor replies: Bah, and I looked it up on-line too. Thanks for the update. Now for the real question: are you still running it, Peter?

Peter Schow replies: No, I run the latest-and-greatest Solaris, but there are stories about Solaris 7 (~1998) still in production out there.

Enjoy your column!

LJ Archive