What Unix command-line program prints holidays? - calendar

Ages ago, I remember there was a command-line Unix program that
would print out major holidays in the USA. With command-line
options, it could print out Islamic, Discordian, and even Canadian
holidays.
I can't seem to find this program now. The closest I can get is
emacs' "list-holidays" function. It's possible the program I
remember just called an emacs function from the command line or
something.
EDIT: In addition to 'calendar', 'gcal' will do this too.

Are you looking for calendar?
This will show all the upcoming holidays.
$ calendar
Jul 26 Bilbo rescued from Wargs by Eagles
Jul 26 Independence Day in Liberia
Jul 26 National Day in Maldives
This shows all US bank holidays upcoming in the next +1 days.
$ calendar -f /usr/share/calendar/calendar.usholiday -W +1
Nov 11 Veterans' Day
This package is maintained by the BSD community and can be installed in debian and ubuntu from bsdmainutils.

Related

C program delivers only the UTC time as localtime on Linux using GCC

I have a C program that runs on two different RHEL6 servers that are configured with the same timezone. The C program uses the time functions from time.h. On one of the servers the local time is correctly determined, on the other one the UTC (default) time is displayed independent from the configured timezone.
I've tried to see if the link to /etc/localtime is broken but it's a correct softlink to /usr/share/zoneinfo/<timezone> (in this case Europe/Berlin).
I've inspected the timezone file with zdump and the content of the file is correct. The timezone and time of the system is also correctly displayed using date. There is no definition of the $TZ variable in my bash or anywhere else!
As an additional test I have run the follwing code with and without a $TZ variable:
::time_t aclock;
::tm tm_tmp;
::tm *newtime;
setenv("TZ", "Europe/Berlin", 1);
tzset();
::time( &aclock );
newtime = ::localtime_r( &aclock, &tm_tmp );
printf("\nDEBUG TIME: %d ", aclock);
printf("\nDEBUG TIMEZONE: %s \n", newtime->tm_zone);
printf("DEBUG HOUR: %d \n", newtime->tm_hour);
Using the code above and setting TZ parameter differently I get the following outputs on the faulty server, assuming that the server time is Europe/Berlin, CEST at this moment:
without setenv:
DEBUG TIME: 1524241319
DEBUG TIMEZONE: UTC
DEBUG HOUR: 16
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: Europe
DEBUG HOUR: 16
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
So it looks like the "Europe/Berlin" time cannot be found, as the UTC time is displayed and the timezone "Europe" is invalid.
As I said the output / behavior on the other machine is the expected one:
without setenv:
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
P.S. the same gcc version 4.4.7 is used on both machines.
Is it possible that my timezone database is corrupt on the faulty server? Has someone faced similar problem and solve it?
I finally figured out, that the problem was the libc.so library, which was differently compiled for one of the machines and only used for some C applications excepting linux himself. This explains why date delivers the wright output but the C program not.
Using ldd libc.so I've found out that the linker was also set to be at the path /home/mqm/lib as default, which dosn't fit to my server /home/mqm/lib/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2. To resume, here is the full solution:
Problem: Your Linux system is delivering the wright date and time using date or some applications but wrong output using C programs.
Solution: After ensuring that there is no programming error in your code, check with
strace -e trace=open,close,read,write,connect,accept yourCProgram
which path is used to get the time/timezone. You can also check ldd libc.so to see where the default path of the linker is.
If the paths are not corresponding to your linux system configuration, consider recompiling the C library to fit to your system configuration or set $TZ='fullpathtotimezone' as a hotfix / workaround.

Where does the timezone for date and strftime come from?

Im curious because I checked on a linux host in Sydney, Australia and the date command says EST as the timezone, as does strftime(tz, sizeof(tz), "%Z", &time) when running a simple C binary to print that out. However, I know the timezone is AEST. Are timezone abbreviations truncated? Where can I find out more about this?
Australian time zone abbreviations changed in tzdb 2014f, released in August 2014.
You simply need to update your time zone data file to the current version (2015b as of this writing). On linux, this is usually in the tzdata package, which you can update using apt-get, or rpm, or whatever is appropriate for your distro.
the current timezone is typically in an environment variable and/or in a special file in /etc/ in linux

C runtime and date command on cygwin

Background
$ uname -a
CYGWIN_NT-6.1 Owner-PC 1.7.34(0.285/5/3) 2015-02-04 12:14 x86_64 Cygwin
PS: just updated Cygwin 15 days ago. Should be razor close to current.
$ date --version
date (GNU coreutils) 8.23
Packaged by Cygwin (8.23-4)
Copyright (C) 2014 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.
Extracted from man date page on cygwin:
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
output from C runtime (dtime is tiny piece of code):
$ ./dtime -f "%c"
Tue Feb 5 17:04:45 2030
Looks good to me...
To avert questions like: what does the code look like:
strcpy(p->fmt, "%c");
....
strftime(tmp, 80, p->fmt, localtime(&lt));
printf("%s\n", tmp);
dtime and other time routines I wrote in the C library behave as expected per standards. No problem.
On the other hand the date command is not correct AFAICT:
Owner#Owner-PC ~
$ date
Sun, Feb 22, 2015 11:41:44 AM
Owner#Owner-PC ~
$ date +%c
Sun, Feb 22, 2015 11:41:55 AM
The second line of output does not match the man page - or standards, I believe.
Question:
A bug? Something else I am missing?
Edit: per suggestion quote the format string. No. That is only need if there are white spaces in the format
Owner#Owner-PC ~
$ date '+%c'
Sun, Feb 22, 2015 3:13:51 PM
This seems related to the locale settings. Your C program uses the C locale by default, date will behave according to the environment variables LANG, LC_TIME and LC_ALL. What are the values of these variables ? Can you test this:
LC_ALL="C" date '+%c'

Why would PK11_GenerateRandom() return an error -8023?

I am looking through the Internet trying to find the source of the PK11_GenerateRandom() function to see why would the function fail. I have a program that perfectly uses this function but when we moved to a new flavor of Linux, it fails after forking (fork())
Since I do not believe there is a problem with NSS, I suspect that we are doing something incorrectly which was disregarded in the older versions of Linux but with the new one there is an issue.
The OpenSSL package is the same on the 'good' and the 'bad' server:
OpenSSL 0.9.8e-fips-rhel5 01 Jul
NSS rpm differs though.
The 'good' has
nss-3.12.2.0-2.el5
and the bas has this version
nss-3.15.3-4.el5_10
The 'good' server uses quite obsolete Linux:
Linux GOOD 2.6.18-128.el5 #1 SMP Wed Jan 21 08:45:05 EST 2009 x86_64 x86_64 x86_64 GNU/Linux
Enterprise Linux Enterprise Linux Server release 5.3 (Carthage)
Red Hat Enterprise Linux Server release 5.3 (Tikanga)
The 'bad' server is newer:
Linux BAD 2.6.18-371.4.1.el5 #1 SMP Wed Jan 29 11:05:49 PST 2014 x86_64 x86_64 x86_64 GNU/Linux
Oracle Linux Server release 5.10
Red Hat Enterprise Linux Server release 5.10 (Tikanga)
Any clue as to where could I find the source or what could be the reason for failure (like side effect coming from fork()) would be greatly appreciated.
Greg
Edit
Here is the code, which is so simple, that I did not think it is needed.
/* random points to properly allocated memory, let=32 */
SECStatus rv = PK11_GenerateRandom((unsigned char *)random, (int)len);
if ( rv != SECSuccess )
printf( "PK11_GenerateRandom error = %d\n", PR_GetError()) ;
and the output message is, of course:
PK11_GenerateRandom error = -8023
Greg
The source of the PK11_GenerateRandom() function: http://mxr.mozilla.org/mozilla-central/source/security/nss/lib/pk11wrap/pk11slot.c#2285
Based on my calculation the -8023 corresponds error SEC_ERROR_PKCS11_DEVICE_ERROR
The reason (thanks to jariq's hints) is described here: https://bugzilla.mozilla.org/show_bug.cgi?id=331096
It is that in the past, it was okay to fork and continue using PKCS11 functions. They decided that it cannot be like that, and now, conclusion is that the parent should not initialize these functions if a child after forking is expected to use them.
PKCS11 internal functions are checking if there was forking (they use various methods dependently on what platform the code is built.) For example, they stored pid of the process in an internal memory, and in some expensive functions or called not so often they compare this preserved pid with current getpid().
The fix for our problem will require redesigning the code.

DST restoration under Linux in C

I have date/time information from Berlin,Germany.
For example:
2011-05-16 12:24:23,
2011-01-21 17:00:31
Unfortunatly, these times have NO daylight saving information. I know that the first date is CEST and the second time is CET.
I could write a check whether the date/time is daylight saving or not.
The summertime starts at the last sunday in march at 2:00 AM, and ends at the last sunday in october at 3 AM.
Self developing such a check seems error prone to me. Is there something that can be already used under Linux in C?
Thank you for your help.
You can convert the time to a time_t with mktime() and then pass it back in to localtime() which will set tm_isdst. Both mktime() and localtime() utilize your local system's time configuration, so you're really discovering if the timestamp is in DST where you are. The obvious problem here is that you have a timestamp string without geographical information so the best you can do is assume it's for your current location.
You can pass the %Z format argument to the date command to obtain the timezone from a date, then determine if DST was in effect from the timezone's name:
$ date -d '2011-05-16' '+%Z'
CEST
$ date -d '2011-01-21' '+%Z'
CET

Resources