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
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.
—
Rick
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
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." else echo "Oops, $year wasn't a leapyear, so February only \ had 28 days." fi fi
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 365 $ date -d 12/31/1932 +%j 366
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 ↪<http://gnu.org/licenses/gpl.html>. 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 366 $ date -d 12/31/1810 +%j 365
Hmm...
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. */ #else long int __tm_gmtoff; /* Seconds east of UTC. */ __const char *__tm_zone; /* Timezone abbreviation. */ #endif };
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
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!
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.
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
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!