procmail
[Top] [All Lists]

RE: Sorting Archived Mail by Source Folder and Date

2001-12-21 11:39:14


-----Original Message-----
From: procmail-admin(_at_)Lists(_dot_)RWTH-Aachen(_dot_)DE
[mailto:procmail-admin(_at_)Lists(_dot_)RWTH-Aachen(_dot_)DE]On Behalf Of 
Biju Chacko
Sent: Thursday, December 20, 2001 10:05 PM
To: Procmail-Users
Subject: Sorting Archived Mail by Source Folder and Date


Hello:

I have a fair number of maildir folders of archived mail that
I would like to
sort on a monthly basis. Let me illustrate:

I currently have:

$HOME/mail/foo/
$HOME/mail/foo1/
[...]
I would like to sort them into

$HOME/mail/archive/foo1-jan-2001/
$HOME/mail/archive/foo1-feb-2001/
[...]

The format of name of the output folder is not mandatory. All
that is needed
is that the folders should be distinguishable on the basis of
original folder
and month & year.

Unfortunately, my procmail skills don't extend much beyond
sorting incoming
mail on the basis of sender, so I'd appreciate some pointers.


Biju,
This is likely not a problem to be handled with procmail, but one that
is more easily handled with formail, and other tools.  I needed to solve
a similar problem a while ago, and came up with this solution:

http://www.rosat.mpe-garching.mpg.de/mailing-lists/procmail/1997-02/msg0
0178.html

I developed a simple program called 'mdate', which takes a date in free
form, and tries to convert it into a canonical form. This, combined with
"formail" as the tool of choice for extracting the Date: header
information should get you what you need. "mdate" accepts a date as a
string of tokens on the ccommand line outputs the date/time in the
following format: mmddhhmmCCyy (which happens to be the format accepted
by the "touch" utility). I've included an updated version of mdate, as a
shar archive below, which is more Y2K compliant, and outputs the year in
CCYY (century + year) format. Note: dates "in the wild" in mail messages
can be in many, varied formats, and mdate will not be able to convert
all of them. Sometimes, the dates are just wrong.

Here's a shell script that accepts a list of file names as arguments,
and that uses formail and the mdate utility to extract the date field
from each file (which is presumed to be a single mail message), and to
then copy the file into a directory named as YEAR/MONTH in CCYY/MM
format.  If you want to use month names or some other encoding, the
scipt will need to be modified.

#!/bin/sh -f
for i in $* ; do
  if d=`formail -x Date: < $i` ; then
    if m=`mdate $d` ; then
      Y=`echo $m | sed -e 's/^........//'`
      M=`echo $m | sed -e 's/..........$//'`
      dir="$Y/$M"
      if [ ! -d $dir ] ; then
        mkdir -p $dir
      fi
      cp $i $dir
      touch -t $m $dir/$i
      echo "$i: copied to $dir/$i"
    else
      echo "$i: unrecognized date - $d"
    fi
  else
    echo "$i: no date?"
  fi
done

The updated mdate utility follows, as a shell archive.

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2001-12-21 10:30 PST by <gary(_at_)intrepid(_dot_)com>.
#
# Existing files will *not* be overwritten unless `-c' is specified.
# This format requires very little intelligence at unshar time.
# "if test", "echo", "mkdir", and "sed" may be needed.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    235 -rw-rw-r-- mdate/Makefile
#  16619 -rw-rw-r-- mdate/mdate.y
#
echo=echo
if mkdir _sh1537430; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= mdate/Makefile ==============
if test ! -d 'mdate'; then
  $echo 'x -' 'creating directory' 'mdate'
  mkdir 'mdate'
fi
if test -f 'mdate/Makefile' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'mdate/Makefile' '(file already exists)'
else
  $echo 'x -' extracting 'mdate/Makefile' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'mdate/Makefile' &&
XCOPTS = -O
XCOPTS = -g
XIFLAGS = -I.
XCFLAGS = $(COPTS) $(IFLAGS) $(PROF)
XDBM =
XSHELL = /bin/sh
XOBJS = mdate.o
X
Xall:   mdate
X       chmod +x mdate
X
Xmdate: $(OBJS) $(LIBS)
X       $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
X
Xclean:
X       rm -f *.o mdate
SHAR_EOF
  : || $echo 'restore of' 'mdate/Makefile' 'failed'
fi
# ============= mdate/mdate.y ==============
if test -f 'mdate/mdate.y' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'mdate/mdate.y' '(file already exists)'
else
  $echo 'x -' extracting 'mdate/mdate.y' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'mdate/mdate.y' &&
X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
X%{
X  /*      Steven M. Bellovin (unc!smb)                    */
X  /*      Dept. of Computer Science                       */
X  /*      University of North Carolina at Chapel Hill     */
X  /*      @(#)getdate.y   2.13    9/16/86 */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X
X/* #include <sys/timeb.h> */
X#define        timezone        tmzn    /* ugly hack for obscure name clash */
X/*
X * simulation of unix's <sys/timeb.h> for Uglix.
X */
Xstruct timeb {
X       time_t time;
X       unsigned short millitm;
X       short timezone;
X       short dstflag;
X};
X
X#include <sys/times.h>
X#include <time.h>
X
X#ifndef HZ
X#define HZ 60
X#endif
X
X#define daysec (24L*60L*60L)
X
X  static int timeflag, zoneflag, dateflag, dayflag, relflag;
X  static time_t relsec, relmonth;
X  static int hh, mm, ss, merid, daylight_time;
X  static int dayord, dayreq;
X  static int month, day, year;
X  static int ourzone;
X
X#define AM 1
X#define PM 2
X#define DAYLIGHT 1
X#define STANDARD 2
X#define MAYBE    3
X%}
X
X%%
Xtimedate:                      /* empty */
X|timedate item;
X
Xitem:tspec =
X{
X  timeflag++;
X}
X|zone =
X{
X  zoneflag++;
X}
X|dtspec =
X{
X  dateflag++;
X}
X|dyspec =
X{
X  dayflag++;
X}
X|rspec =
X{
X  relflag++;
X}
X|nspec;
X
Xnspec:NUMBER =
X{
X  if (timeflag && dateflag && !relflag)
X    year = $1;
X  else
X    {
X      timeflag++;
X      hh = $1 / 100;
X      mm = $1 % 100;
X      ss = 0;
X      merid = 24;
X    }
X};
X
Xtspec:NUMBER MERIDIAN =
X{
X  hh = $1;
X  mm = 0;
X  ss = 0;
X  merid = $2;
X}
X|NUMBER ':' NUMBER =
X{
X  hh = $1;
X  mm = $3;
X  merid = 24;
X}
X|NUMBER ':' NUMBER MERIDIAN =
X{
X  hh = $1;
X  mm = $3;
X  merid = $4;
X}
X|NUMBER ':' NUMBER NUMBER =
X{
X  hh = $1;
X  mm = $3;
X  merid = 24;
X  daylight_time = STANDARD;
X  ourzone = $4 % 100 + 60 * $4 / 100;
X}
X|NUMBER ':' NUMBER ',' NUMBER =
X{
X  hh = $1;
X  mm = $3;
X  merid = 24;
X  daylight_time = STANDARD;
X  ourzone = $5 % 100 + 60 * $5 / 100;
X}
X|NUMBER ':' NUMBER ':' NUMBER =
X{
X  hh = $1;
X  mm = $3;
X  ss = $5;
X  merid = 24;
X}
X|NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
X{
X  hh = $1;
X  mm = $3;
X  ss = $5;
X  merid = $6;
X}
X|NUMBER ':' NUMBER ':' NUMBER NUMBER =
X{
X  hh = $1;
X  mm = $3;
X  ss = $5;
X  merid = 24;
X  daylight_time = STANDARD;
X  ourzone = $6 % 100 + 60 * $6 / 100;
X}
X|NUMBER ':' NUMBER ':' NUMBER ',' NUMBER =
X{
X  hh = $1;
X  mm = $3;
X  ss = $5;
X  merid = 24;
X  daylight_time = STANDARD;
X  ourzone = $7 % 100 + 60 * $7 / 100;
X};
X
Xzone:ZONE NUMBER =
X{
X  ourzone = $1;
X  daylight_time = STANDARD;
X}
X    | ZONE
X{
X  ourzone = $1;
X  daylight_time = STANDARD;
X}
X|DAYZONE =
X{
X  ourzone = $1;
X  daylight_time = DAYLIGHT;
X};
X
Xdyspec:DAY =
X{
X  dayord = 1;
X  dayreq = $1;
X}
X|DAY ',' =
X{
X  dayord = 1;
X  dayreq = $1;
X}
X|NUMBER DAY =
X{
X  dayord = $1;
X  dayreq = $2;
X};
X
Xdtspec:NUMBER '/' NUMBER =
X{
X  month = $1;
X  day = $3;
X}
X|NUMBER '/' NUMBER '/' NUMBER =
X{
X  month = $1;
X  day = $3;
X  year = $5;
X}
X|NUMBER /*'-'*/ NUMBER /*'-'*/ NUMBER =
X{
X  /* the scanner strips the minus signs */
X  year = $1;
X  if (year < 0) year = -year;
X  if (year > 1900)
X    {
X      year = (year - 1900) % 100;
X    }
X  month = $2;
X  if (month < 0) month = -month;
X  day = $3;
X  if (day < 0) day = -day;
X}
X|MONTH NUMBER =
X{
X  month = $1;
X  day = $2;
X}
X|MONTH NUMBER ',' NUMBER =
X{
X  month = $1;
X  day = $2;
X  year = $4;
X}
X|NUMBER MONTH =
X{
X  month = $2;
X  day = $1;
X}
X|NUMBER MONTH NUMBER =
X{
X  month = $2;
X  day = $1;
X  year = $3;
X};
X
X
Xrspec:NUMBER UNIT =
X{
X  relsec += 60L * $1 * $2;
X}
X|NUMBER MUNIT =
X{
X  relmonth += $1 * $2;
X}
X|NUMBER SUNIT =
X{
X  relsec += $1;
X}
X|UNIT =
X{
X  relsec += 60L * $1;
X}
X|MUNIT =
X{
X  relmonth += $1;
X}
X|SUNIT =
X{
X  relsec++;
X}
X|rspec AGO =
X{
X  relsec = -relsec;
X  relmonth = -relmonth;
X};
X%%
X
Xstatic int mdays[12] =
X{31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
X#define epoch 1970
X
Xextern struct tm *localtime ();
Xstatic time_t timeconv ();
X
X
X
X/* imports from libc */
Xextern time_t time();
Xextern time_t times();                 /* only true on Uglix */
Xextern char *getenv();
X
X/*
X * Uglix ftime simulation
X */
Xftime(tp)
Xstruct timeb *tp;
X{
X       register char *tz;
X#ifdef SANE
X       /*
X        * Since times() is not required to use the same time base for its
X        * return value as time() uses, we can't easily get sub-second
resolution.
X        */
X       struct tms timesbuf;
X       register int hz = times(&timesbuf) % HZ;        /* hertz beyond time(0) 
*/
X
X       tp->millitm = (hz*1000L)/HZ;
X#else
X       tp->millitm = 0;
X#endif
X       tp->time = time(&tp->time);
X       tz = getenv("TZ");
X       if (tz == NULL)                 /* just pick one */
X               tz = "EST5EDT";
X       while (*tz != '\0' && isascii(*tz) && !isdigit(*tz) && *tz != '-')
X               tz++;                   /* find hrs from greenwich */
X       tp->timezone = atoi(tz) * 60;   /* in minutes */
X       while (*tz != '\0' && isascii(*tz) && (isdigit(*tz) || *tz == '-'))
X               tz++;                   /* find DST, if any */
X       tp->dstflag = (*tz != '\0');
X}
X
Xstatic time_t
Xdateconv (mm, dd, yy, h, m, s, mer, zone, dayflag)
X     int mm, dd, yy, h, m, s, mer, zone, dayflag;
X{
X  time_t tod, jdate;
X  register int i;
X
X  if (yy < 0)
X    yy = -yy;
X  if (yy < 20)
X    yy += 2000;
X  else if (yy < 100)
X    yy += 1900;
X  mdays[1] = 28 + (yy % 4 == 0 && (yy % 100 != 0 || yy % 400 == 0));
X  if (yy < epoch || yy > 2038 || mm < 1 || mm > 12 ||
X      dd < 1 || dd > mdays[--mm])
X    return (-1);
X  jdate = dd - 1;
X  for (i = 0; i < mm; i++)
X    jdate += mdays[i];
X  for (i = epoch; i < yy; i++)
X    jdate += 365 + (i % 4 == 0);
X  jdate *= daysec;
X  jdate += zone * 60L;
X  if ((tod = timeconv (h, m, s, mer)) < 0)
X    return (-1);
X  jdate += tod;
X  if (dayflag == DAYLIGHT || (dayflag == MAYBE && localtime
(&jdate)->tm_isdst))
X    jdate += -1 * 60 * 60;
X  return (jdate);
X}
X
Xstatic time_t daylcorr ();
X
Xstatic time_t
Xdayconv (ord, day, now)
X     int ord, day;
X     time_t now;
X{
X  register struct tm *loctime;
X  time_t tod;
X
X  tod = now;
X  loctime = localtime (&tod);
X  tod += daysec * ((day - loctime->tm_wday + 7) % 7);
X  tod += 7 * daysec * (ord <= 0 ? ord : ord - 1);
X  return daylcorr (tod, now);
X}
X
Xstatic time_t
Xtimeconv (hh, mm, ss, mer)
X     register int hh, mm, ss, mer;
X{
X  if (mm < 0 || mm > 59 || ss < 0 || ss > 59)
X    return (-1);
X  switch (mer)
X    {
X    case AM:
X      if (hh < 0 || hh > 12)
X       return (-1);
X      return (60L * ((hh % 12) * 60L + mm) + ss);
X    case PM:
X      if (hh < 1 || hh > 12)
X       return (-1);
X      return (60L * ((hh % 12 + 12) * 60L + mm) + ss);
X    case 24:
X      if (hh < 0 || hh > 23)
X       return (-1);
X      return (60L * (hh * 60L + mm) + ss);
X    default:
X      return (-1);
X    }
X}
X
Xstatic time_t
Xmonthadd (sdate, relmonth)
X     time_t sdate, relmonth;
X{
X  struct tm *ltime;
X  time_t dateconv ();
X  time_t daylcorr ();
X  int mm, yy;
X
X  if (relmonth == 0)
X    return 0;
X  ltime = localtime (&sdate);
X  mm = 12 * ltime->tm_year + ltime->tm_mon + relmonth;
X  yy = mm / 12;
X  mm = mm % 12 + 1;
X  return daylcorr (dateconv (mm, ltime->tm_mday, yy, ltime->tm_hour,
X                 ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
X}
X
Xstatic time_t
Xdaylcorr (future, now)
X     time_t future, now;
X{
X  int fdayl, nowdayl;
X
X  nowdayl = (localtime (&now)->tm_hour + 1) % 24;
X  fdayl = (localtime (&future)->tm_hour + 1) % 24;
X  return (future - now) + 60L * 60L * (nowdayl - fdayl);
X}
X
Xstatic char *lptr;
Xstatic lookup ();
X
Xyylex ()
X{
X  extern int yylval;
X  int sign;
X  register char c;
X  register char *p;
X  char idbuf[20];
X  int pcnt;
X
X  for (;;)
X    {
X      while (isspace (*lptr))
X       lptr++;
X
X      if (isdigit (c = *lptr) || c == '-' || c == '+')
X       {
X         if (c == '-' || c == '+')
X           {
X             if (c == '-')
X               sign = -1;
X             else
X               sign = 1;
X             if (!isdigit (*++lptr))
X               {
X                 /* yylval = sign; return (NUMBER); */
X                 return yylex ();      /* skip the '-' sign */
X               }
X           }
X         else
X           sign = 1;
X         yylval = 0;
X         while (isdigit (c = *lptr++))
X           yylval = 10 * yylval + c - '0';
X         yylval *= sign;
X         lptr--;
X         return (NUMBER);
X
X       }
X      else if (isalpha (c))
X       {
X         p = idbuf;
X         while (isalpha (c = *lptr++) || c == '.')
X           if (p < &idbuf[sizeof (idbuf) - 1])
X             *p++ = c;
X         *p = '\0';
X         lptr--;
X         return (lookup (idbuf));
X       }
X
X      else if (c == '(')
X       {
X         pcnt = 0;
X         do
X           {
X             c = *lptr++;
X             if (c == '\0')
X               return (c);
X             else if (c == '(')
X               pcnt++;
X             else if (c == ')')
X               pcnt--;
X           }
X         while (pcnt > 0);
X       }
X
X      else
X       return (*lptr++);
X    }
X}
X
Xstruct table
X{
X  char *name;
X  int type, value;
X};
X
Xstatic struct table mdtab[] =
X{
X  {"January", MONTH, 1},
X  {"February", MONTH, 2},
X  {"March", MONTH, 3},
X  {"April", MONTH, 4},
X  {"May", MONTH, 5},
X  {"June", MONTH, 6},
X  {"July", MONTH, 7},
X  {"August", MONTH, 8},
X  {"September", MONTH, 9},
X  {"Sept", MONTH, 9},
X  {"October", MONTH, 10},
X  {"November", MONTH, 11},
X  {"December", MONTH, 12},
X
X  {"Sunday", DAY, 0},
X  {"Monday", DAY, 1},
X  {"Tuesday", DAY, 2},
X  {"Tues", DAY, 2},
X  {"Wednesday", DAY, 3},
X  {"Wednes", DAY, 3},
X  {"Thursday", DAY, 4},
X  {"Thur", DAY, 4},
X  {"Thurs", DAY, 4},
X  {"Friday", DAY, 5},
X  {"Saturday", DAY, 6},
X  {0, 0, 0}};
X
X#define HRS *60
X#define HALFHR 30
Xstatic struct table mztab[] =
X{
X  {"a.m.", MERIDIAN, AM},
X  {"am", MERIDIAN, AM},
X  {"p.m.", MERIDIAN, PM},
X  {"pm", MERIDIAN, PM},
X  {"nst", ZONE, 3 HRS + HALFHR},       /* Newfoundland */
X  {"n.s.t.", ZONE, 3 HRS + HALFHR},
X  {"ast", ZONE, 4 HRS},                /* Atlantic */
X  {"a.s.t.", ZONE, 4 HRS},
X  {"adt", DAYZONE, 4 HRS},
X  {"a.d.t.", DAYZONE, 4 HRS},
X  {"est", ZONE, 5 HRS},                /* Eastern */
X  {"e.s.t.", ZONE, 5 HRS},
X  {"edt", DAYZONE, 5 HRS},
X  {"e.d.t.", DAYZONE, 5 HRS},
X  {"cst", ZONE, 6 HRS},                /* Central */
X  {"c.s.t.", ZONE, 6 HRS},
X  {"cdt", DAYZONE, 6 HRS},
X  {"c.d.t.", DAYZONE, 6 HRS},
X  {"mst", ZONE, 7 HRS},                /* Mountain */
X  {"m.s.t.", ZONE, 7 HRS},
X  {"mdt", DAYZONE, 7 HRS},
X  {"m.d.t.", DAYZONE, 7 HRS},
X  {"pst", ZONE, 8 HRS},                /* Pacific */
X  {"p.s.t.", ZONE, 8 HRS},
X  {"pdt", DAYZONE, 8 HRS},
X  {"p.d.t.", DAYZONE, 8 HRS},
X  {"yst", ZONE, 9 HRS},                /* Yukon */
X  {"y.s.t.", ZONE, 9 HRS},
X  {"ydt", DAYZONE, 9 HRS},
X  {"y.d.t.", DAYZONE, 9 HRS},
X  {"hst", ZONE, 10 HRS},       /* Hawaii */
X  {"h.s.t.", ZONE, 10 HRS},
X  {"hdt", DAYZONE, 10 HRS},
X  {"h.d.t.", DAYZONE, 10 HRS},
X
X  {"gmt", ZONE, 0 HRS},
X  {"g.m.t.", ZONE, 0 HRS},
X  {"ut", ZONE, 0 HRS},
X  {"u.t.", ZONE, 0 HRS},
X  {"bst", DAYZONE, 0 HRS},     /* British Summer Time */
X  {"b.s.t.", DAYZONE, 0 HRS},
X
X  {"ist", DAYZONE, 1 HRS},     /* Irish Summer Time */
X  {"i.s.t.", DAYZONE, 1 HRS},  /* Irish Summer Time */
X
X  {"eet", ZONE, 0 HRS},                /* European Eastern Time */
X  {"e.e.t.", ZONE, 0 HRS},
X  {"eest", DAYZONE, 0 HRS},    /* European Eastern Summer Time */
X  {"e.e.s.t.", DAYZONE, 0 HRS},
X  {"cet", ZONE, -1 HRS},       /* Central European Time */
X  {"c.e.t", ZONE, -1 HRS},
X
X  {"cest", DAYZONE, -2 HRS},   /* Central European Summer Time */
X  {"c.e.s.t", DAYZONE, -2 HRS},        /* Central European Summer Time */
X
X  {"met", ZONE, -1 HRS},       /* Middle European Time */
X  {"m.e.t.", ZONE, -1 HRS},
X  {"metdst", DAYZONE, -1 HRS}, /* Middle European Summer Time */
X  {"mest", DAYZONE, -1 HRS},   /* Middle European Summer Time */
X  {"m.e.s.t.", DAYZONE, -1 HRS},
X
X  {"wet", ZONE, -2 HRS},       /* Western European Time */
X  {"w.e.t.", ZONE, -2 HRS},
X  {"west", DAYZONE, -2 HRS},   /* Western European Summer Time */
X  {"w.e.s.t.", DAYZONE, -2 HRS},
X
X  {"hkt", ZONE, -8 HRS},       /* Japan Standard Time */
X  {"h.k.t", ZONE, -8 HRS},
X  {"j.s.t.", ZONE, -9 HRS},    /* Japan Standard Time */
X  {"jst", ZONE, -9 HRS},
X  {"j.s.t.", ZONE, -9 HRS},
X                                       /* No daylight_time savings time */
X
X  {"aest", ZONE, -10 HRS},     /* Australian Eastern Time */
X  {"a.e.s.t.", ZONE, -10 HRS},
X  {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */
X  {"a.e.s.s.t.", DAYZONE, -10 HRS},
X  {"acst", ZONE, -(9 HRS + HALFHR)},   /* Australian Central Time */
X  {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
X  {"acsst", DAYZONE, -(9 HRS + HALFHR)},       /* Australian Central Summer
*/
X  {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
X  {"awst", ZONE, -8 HRS},      /* Australian Western Time */
X  {"a.w.s.t.", ZONE, -8 HRS},  /* (no daylight_time time there, I'm told
*/
X
X  {"nzst", ZONE, -12 HRS},     /* New Zealand Standard Time */
X  {"nzt", ZONE, -12 HRS},      /* New Zealand Standard Time */
X  {"nzdt", ZONE, -13 HRS},     /* New Zealand Daylight Time */
X
X  {0, 0, 0}};
X
Xstatic struct table unittb[] =
X{
X  {"year", MUNIT, 12},
X  {"month", MUNIT, 1},
X  {"fortnight", UNIT, 14 * 24 * 60},
X  {"week", UNIT, 7 * 24 * 60},
X  {"day", UNIT, 1 * 24 * 60},
X  {"hour", UNIT, 60},
X  {"minute", UNIT, 1},
X  {"min", UNIT, 1},
X  {"second", SUNIT, 1},
X  {"sec", SUNIT, 1},
X  {0, 0, 0}};
X
Xstatic struct table othertb[] =
X{
X  {"tomorrow", UNIT, 1 * 24 * 60},
X  {"yesterday", UNIT, -1 * 24 * 60},
X  {"today", UNIT, 0},
X  {"now", UNIT, 0},
X  {"last", NUMBER, -1},
X  {"this", UNIT, 0},
X  {"next", NUMBER, 2},
X  {"first", NUMBER, 1},
X       /* {"second", NUMBER, 2}, */
X  {"third", NUMBER, 3},
X  {"fourth", NUMBER, 4},
X  {"fifth", NUMBER, 5},
X  {"sixth", NUMBER, 6},
X  {"seventh", NUMBER, 7},
X  {"eigth", NUMBER, 8},
X  {"ninth", NUMBER, 9},
X  {"tenth", NUMBER, 10},
X  {"eleventh", NUMBER, 11},
X  {"twelfth", NUMBER, 12},
X  {"ago", AGO, 1},
X  {0, 0, 0}};
X
Xstatic struct table milzone[] =
X{
X  {"a", ZONE, 1 HRS},
X  {"b", ZONE, 2 HRS},
X  {"c", ZONE, 3 HRS},
X  {"d", ZONE, 4 HRS},
X  {"e", ZONE, 5 HRS},
X  {"f", ZONE, 6 HRS},
X  {"g", ZONE, 7 HRS},
X  {"h", ZONE, 8 HRS},
X  {"i", ZONE, 9 HRS},
X  {"k", ZONE, 10 HRS},
X  {"l", ZONE, 11 HRS},
X  {"m", ZONE, 12 HRS},
X  {"n", ZONE, -1 HRS},
X  {"o", ZONE, -2 HRS},
X  {"p", ZONE, -3 HRS},
X  {"q", ZONE, -4 HRS},
X  {"r", ZONE, -5 HRS},
X  {"s", ZONE, -6 HRS},
X  {"t", ZONE, -7 HRS},
X  {"u", ZONE, -8 HRS},
X  {"v", ZONE, -9 HRS},
X  {"w", ZONE, -10 HRS},
X  {"x", ZONE, -11 HRS},
X  {"y", ZONE, -12 HRS},
X  {"z", ZONE, 0 HRS},
X  {0, 0, 0}};
X
Xstatic
Xlookup (id)
X     char *id;
X{
X#define gotit (yylval=i->value,  i->type)
X#define getid for(j=idvar, k=id; *j++ = *k++; )
X
X  char idvar[20];
X  register char *j, *k;
X  register struct table *i;
X  int abbrev;
X
X  getid;
X  if (strlen (idvar) == 3)
X    abbrev = 1;
X  else if (strlen (idvar) == 4 && idvar[3] == '.')
X    {
X      abbrev = 1;
X      idvar[3] = '\0';
X    }
X  else
X    abbrev = 0;
X
X  if (islower (*idvar))
X    *idvar = toupper (*idvar);
X
X  for (i = mdtab; i->name; i++)
X    {
X      k = idvar;
X      for (j = i->name; *j++ == *k++;)
X       {
X         if (abbrev && j == i->name + 3)
X           return gotit;
X         if (j[-1] == 0)
X           return gotit;
X       }
X    }
X
X  getid;
X  for (i = mztab; i->name; i++) {
X    if (strcmp (i->name, idvar) == 0) {
X      return gotit;
X    }
X  }
X
X  for (j = idvar; *j; j++)
X    if (isupper (*j))
X      *j = tolower (*j);
X  for (i = mztab; i->name; i++)
X    if (strcmp (i->name, idvar) == 0)
X      return gotit;
X
X  getid;
X  for (i = unittb; i->name; i++)
X    if (strcmp (i->name, idvar) == 0)
X      return gotit;
X
X  if (idvar[strlen (idvar) - 1] == 's')
X    idvar[strlen (idvar) - 1] = '\0';
X  for (i = unittb; i->name; i++)
X    if (strcmp (i->name, idvar) == 0)
X      return gotit;
X
X  getid;
X  for (i = othertb; i->name; i++)
X    if (strcmp (i->name, idvar) == 0)
X      return gotit;
X
X  getid;
X  if (strlen (idvar) == 1 && isalpha (*idvar))
X    {
X      if (isupper (*idvar))
X       *idvar = tolower (*idvar);
X      for (i = milzone; i->name; i++)
X       if (strcmp (i->name, idvar) == 0)
X         return gotit;
X    }
X
X  return (ID);
X}
X
Xtime_t
Xmdate (p)
X     char *p;
X{
X#define mcheck(f)      if (f>1) err++
X  time_t monthadd ();
X  int err;
X  struct tm *lt;
X  struct timeb ftz;
X  struct timeb *now = &ftz;
X
X  time_t sdate, tod;
X
X  lptr = p;
X  ftime (now);
X  lt = localtime (&now->time);
X  year = lt->tm_year;
X  month = lt->tm_mon + 1;
X  day = lt->tm_mday;
X  relsec = 0;
X  relmonth = 0;
X  timeflag = zoneflag = dateflag = dayflag = relflag = 0;
X  ourzone = now->timezone;
X  daylight_time = MAYBE;
X  hh = mm = ss = 0;
X  merid = 24;
X
X  if (err = yyparse ())
X    return (-1);
X
X  mcheck (timeflag);
X  mcheck (zoneflag);
X  mcheck (dateflag);
X  mcheck (dayflag);
X
X  if (err)
X    return (-1);
X  if (dateflag || timeflag || dayflag)
X    {
X      sdate = dateconv (month, day, year, hh, mm, ss, merid, ourzone,
daylight_time);
X      if (sdate < 0)
X       return -1;
X    }
X  else
X    {
X      sdate = now->time;
X      if (relflag == 0)
X       sdate -= (lt->tm_sec + lt->tm_min * 60 +
X                 lt->tm_hour * (60L * 60L));
X    }
X
X  sdate += relsec;
X  sdate += monthadd (sdate, relmonth);
X
X  if (dayflag && !dateflag)
X    {
X      tod = dayconv (dayord, dayreq, sdate);
X      sdate += tod;
X    }
X
X  return sdate;
X}
X
Xyyerror (s)
X     char *s;
X{
X}
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X    time_t t;
X    int i;
X    char dbuf[1024];
X    char mbuf[1024];
X    if (argc <= 1) exit(0);
X    strcpy(dbuf, argv[1]);
X    for (i = 2; i < argc; ++i) {
X       strcat(dbuf, " ");
X       strcat(dbuf, argv[i]);
X    }
X    t = mdate(dbuf);
X    if (t < 0) {
X       fprintf(stderr, "%s: invalid date: '%s'\n", argv[0], dbuf);
X       exit(2);
X    }
X    cftime(mbuf, "%m%d%H%M%Y", &t);
X    puts(mbuf);
X    exit(0);
X}
SHAR_EOF
  : || $echo 'restore of' 'mdate/mdate.y' 'failed'
fi
rm -fr _sh1537430
exit 0







_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail

<Prev in Thread] Current Thread [Next in Thread>