SUMMARY: Date utility/script (somewhat long)

From: Jay Morgan (
Date: Fri Jan 07 2000 - 08:30:25 CST

Hello once again,

a few days ago, I wrote the following message.

>I have been tasked with sending notifications to users when their
>account passwords are about to expire. I have been trying to
>determine the best way of determining this based upon the "passwd
>-sa" command which lists the following attributes for all accounts
>on the machine (white-space delimited):
>account_name status date_changed minimum_change maximum_change grace_period
>For example:
>sysadmin PS 11/13/99 1 60 7
>which means the sysadmin account is active, the password was changed
>on 11/13/99, passwords must remain for at least a day, it must be
>changed within 60 days, and there is a 7 day grace period.
>While trying to tackle the problem, I thought it might be best to do
>calculations based upon "seconds from the epoch" However, I can not
>find any bourne shell level utilities to do conversions from date to
>"seconds from the epoch" and back. I know there are C libraries
>that could be used, but I would rather not have to worry about
>compiling code, and I am hesitant to do perl, as not all of our
>machines are loaded with it.
>Does anyone have any good ideas?

I got feedback from a number of people, including:

Marcos Assis Silva, Jonathan Loh, Karl Vogel, Jim lewinson, Daniel
Lorenzini, Brad Young, Rick Caldwell, Keith Willenson, Mark Anderson,
Renny Koshy, and Vince Merrell.

I thank you all for your input in my dilemma.

Marcos Assis Silva was nice enough to provide me with binaries and
source code of two utilities: cftime and mktime. They convert times
back and forth between normal "date" output and "seconds from epoch".
I almost used this, but decided on another utility (more info later).
- Thanks Marcos!

I got some recommendations to use the GNU date utility (gdate?)

Rick Caldwell sent me some scripts that perform a similar function to
what I was trying to do, but for temporary license keys. It mainly
uses awk for parsing license files. He even sent me a patch for Y2K
fixes. Thanks Rick.

I also got some recommendations to do Time Zone modifications to do
my date math.

And the winner is (drumroll please :-):

Jonathan Loh made me aware of a date utility called mktime (not the
same one as Marcos') put out by John R. Macmillan. It can be had at I
compiled this snippet of code, followed the included man page, and
was able to complete my script quickly. I have included my script
below for anyone who is interested. It calls mktime, and uses it to
return a list of accounts that are about to expire. Thanks Jonathan!
(and of course John Macmillan)

My script:

# Copyright (c) 2000, by TKC Solutions, LLC
# Distributed as Freeware
# This script uses an executable compiled from the mktime source code from
# John R MacMillan ( The source of mktime can be had at
# This script uses the "passwd -sa" command to get the list of accounts on the
# system, do some simple checking for accounts with expiration, and list those
# accounts that are due for changing soon. All commands are based upon syntax
# used in Sun Solaris 2.x as of January 2000.

#Modify as necessary for the path to the mktime, passwd, and grep binaries
PSWD="/usr/bin/passwd -sa"

# The following command parses the password file and singles out the accounts
# with exipiration.
$PSWD | $GREP PS | $GREP -v "00/00/00" > /tmp/passexp.dat

# This script assumes output of the passwd -sa command to have the following
# columns:
# account_name status pw_chg_date [min_change] max_change warn_days
# min_change is optional, but all other arguments must be there.

while read nm st dt v1 v2 v3
   # Today's date in seconds from the epoch
   todaytime=`$MKTIME -F '%t' -z`

   # Checking for minimum arguments
   if [ "abc$v1" = "abc" -o "abc$v2" = "abc" ]
   # if v3 is empty, then there was no min_change argument. Shift variables
   # as if there were.
   if [ "abc$v3" = "abc" ]

   # get month date and year, convert 2 digit date to 4 digit date. I am using
   # a 100 year window from 1991 through 2090.
   # This Script is NOT Y2.091K compliant :-)
   mo=`echo $dt | cut -b 1-2`
   da=`echo $dt | cut -b 4-5`
   yr=`echo $dt | cut -b 7-8`
   if [ $yr -le 90 ]
     yr=`expr $yr + 2000`
     yr=`expr $yr + 1900`

   # use mktime to calculate seconds since the epoch
   chgtime=`$MKTIME -F '%t' -z -D "$yr-$mo-$da"`

   # calculate password expiration date
   duetime=`expr $chgtime + $v2 \* 86400 `

   # convert expiration date back to normal date form
   duedate=`$MKTIME -t $duetime`

   # calculate how far we are from expiration and compare to warning value
   difftime=`expr $duetime \- $todaytime`
   diffday=`expr $difftime \/ 86400`
   if [ $diffday -le $v3 ]
     echo "account $nm has $diffday days left to change password.
grace period is
     echo "account $nm expires on $duedate"
done < /tmp/passexp.dat
rm /tmp/passexp.dat
exit 0

Jay Morgan Work E-Mail:
Managing Partner Personal E-Mail:
TKC Solutions LLC Phone: 770-671-8084 (use Mobile)
3380 Villa Robleda Dr. FAX: 650.618.1460
Mountain View, CA 94040
5125 Foxwood Ct. Home: 770-522-8611
Atlanta, GA 30360 Mobile: 770-329-4477
The surest way to corrupt a youth is to instruct him to hold in
higher regard those who think alike than those who think differently.
-- Unknown

This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:14:01 CDT