]> git.pld-linux.org Git - packages/at.git/commitdiff
- added neww patch for at from Debian.
authorkloczek <kloczek@pld-linux.org>
Thu, 29 Jun 2000 17:12:47 +0000 (17:12 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    at-debian.patch -> 1.1

at-debian.patch [new file with mode: 0644]

diff --git a/at-debian.patch b/at-debian.patch
new file mode 100644 (file)
index 0000000..a1d03b8
--- /dev/null
@@ -0,0 +1,2283 @@
+--- at-3.1.8.orig/at.c
++++ at-3.1.8/at.c
+@@ -111,7 +111,7 @@
+ static char rcsid[] = "$Id$";
+ char *no_export[] =
+ {
+-    "TERM", "DISPLAY", "_", "SHELLOPTS"
++    "TERM", "DISPLAY", "_", "SHELLOPTS", "BASH_VERSINFO", "EUID", "GROUPS", "PPID", "UID"
+ };
+ static int send_mail = 0;
+@@ -235,6 +235,7 @@
+ /* Install the signal handler for SIGINT; terminate after removing the
+  * spool file if necessary
+  */
++    memset(&act, 0, sizeof act);
+     act.sa_handler = sigc;
+     sigemptyset(&(act.sa_mask));
+     act.sa_flags = 0;
+@@ -274,8 +275,8 @@
+       if ((jobno = nextjob()) == EOF)
+           perr("Cannot generate job number");
+-      sprintf(ppos, "%c%5lx%8lx", queue,
+-              jobno, (unsigned long) (runtimer / 60));
++      (void)snprintf(ppos, sizeof(atfile) - (ppos - atfile),
++                     "%c%5lx%8lx", queue, jobno, (unsigned long) (runtimer / 60));
+       for (ap = ppos; *ap != '\0'; ap++)
+           if (*ap == ' ')
+@@ -291,7 +292,7 @@
+        * bit.  Yes, this is a kluge.
+        */
+       cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR);
+-      if ((fd = creat(atfile, O_WRONLY)) == -1)
++      if ((fd = open(atfile, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR)) == -1)
+           perr("Cannot create atjob file %.500s", atfile);
+       if ((fd2 = dup(fd)) < 0)
+@@ -461,14 +462,6 @@
+     close(fd2);
+-    /* POSIX.2 allows the shell specified by the user's SHELL environment
+-       variable, the login shell from the user's password database entry,
+-       or /bin/sh to be the command interpreter that processes the at-job.
+-       It also alows a warning diagnostic to be printed.  Because of the
+-       possible variance, we always output the diagnostic. */
+-
+-    fprintf(stderr, "warning: commands will be executed using /bin/sh\n");
+-
+     runtime = localtime(&runtimer);
+     /* We only use the sick POSIX time format if POSIXLY_CORRECT
+@@ -546,6 +539,7 @@
+     long jobno;
+     time_t runtimer;
+     char timestr[TIMESIZE];
++    struct passwd *pwd;
+     PRIV_START
+@@ -581,7 +575,10 @@
+       } else {
+           strftime(timestr, TIMESIZE, TIMEFORMAT_ISO, runtime);
+       }
+-      printf("%ld\t%s %c\n", jobno, timestr, queue);
++      if ((pwd = getpwuid(buf.st_uid)))
++        printf("%ld\t%s %c %s\n", jobno, timestr, queue, pwd->pw_name);
++      else
++        printf("%ld\t%s %c\n", jobno, timestr, queue);
+     }
+     PRIV_END
+ }
+@@ -695,7 +692,7 @@
+     char *pgm;
+     int program = AT;         /* our default program */
+-    char *options = "q:f:mvldVc";     /* default options for at */
++    char *options = "q:f:MmvldhVc";   /* default options for at */
+     int disp_version = 0;
+     time_t timer;
+     struct passwd *pwe;
+@@ -726,16 +723,20 @@
+      */
+     if (strcmp(pgm, "atq") == 0) {
+       program = ATQ;
+-      options = "q:V";
++      options = "hq:V";
+     } else if (strcmp(pgm, "atrm") == 0) {
+       program = ATRM;
+-      options = "V";
++      options = "hV";
+     }
+     /* process whatever options we can process
+      */
+     opterr = 1;
+     while ((c = getopt(argc, argv, options)) != EOF)
+       switch (c) {
++      case 'h':
++          usage();
++          exit (0);
++
+       case 'v':               /* verify time settings */
+           atverify = 1;
+           break;
+@@ -744,6 +745,10 @@
+           send_mail = 1;
+           break;
++      case 'M':               /* don't send mail, even when job failed */
++          send_mail = -1;
++          break;
++
+       case 'f':
+           atinput = optarg;
+           break;
+@@ -753,7 +758,7 @@
+               usage();
+           atqueue = queue = *optarg;
+-          if (!(islower(queue) || isupper(queue)))
++          if (!(islower(queue) || isupper(queue)) & (queue != '='))
+               usage();
+           queue_set = 1;
+@@ -842,6 +847,15 @@
+           struct tm *tm = localtime(&timer);
+           fprintf(stderr, "%s\n", asctime(tm));
+       }
++
++      /* POSIX.2 allows the shell specified by the user's SHELL environment
++         variable, the login shell from the user's password database entry,
++         or /bin/sh to be the command interpreter that processes the at-job.
++         It also alows a warning diagnostic to be printed.  Because of the
++         possible variance, we always output the diagnostic. */
++
++      fprintf(stderr, "warning: commands will be executed using /bin/sh\n");
++
+       writefile(timer, queue);
+       break;
+--- at-3.1.8.orig/atd.c
++++ at-3.1.8/atd.c
+@@ -22,6 +22,18 @@
+ #include "config.h"
+ #endif
++/* 
++ * /usr/bin/mail aka /usr/bin/mailx require the subject to be
++ * specified on the command line instead of reading it from stdin like
++ * /usr/sbin/sendmail does. For now simply disable MAILC and MAILX,
++ *
++ * TODO: Remove tests for MAILC and MAILX from configure.in in the
++ *       next upstream version.
++ */
++#undef MAILC
++#undef MAILX
++
++
+ /* System Headers */
+ #include <sys/types.h>
+@@ -101,6 +113,8 @@
+ static char rcsid[] = "$Id$";
+ static double load_avg = LOADAVG_MX;
+ static time_t now;
++static time_t last_chg;
++static int nothing_to_do;
+ unsigned int batch_interval;
+ static int run_as_daemon = 0;
+@@ -121,6 +135,29 @@
+     return;
+ }
++/* SIGCHLD handler - discards completion status of children */
++RETSIGTYPE
++release_zombie(int dummy)
++{
++  int status;
++  pid_t pid;
++
++  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
++#ifdef DEBUG_ZOMBIE
++    if (WIFEXITED(status))
++      syslog(LOG_INFO, "pid %ld exited with status %d.", pid, WEXITSTATUS(status));
++    else if (WIFSIGNALED(status))
++      syslog(LOG_NOTICE, "pid %ld killed with signal %d.", pid, WTERMSIG(status));
++    else if (WIFSTOPPED(status))
++      syslog(LOG_NOTICE, "pid %ld stopped with signal %d.", pid, WSTOPSIG(status));
++    else
++      syslog(LOG_WARNING, "pid %ld unknown reason for SIGCHLD", pid);
++#endif
++  }
++  return;
++}
++    
++
+ /* Local functions */
+ static int
+@@ -255,6 +292,13 @@
+     fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
++    /*
++     * If the spool directory is mounted via NFS `atd' isn't able to
++     * read from the job file and will bump out here.  The file is
++     * opened as "root" but it is read as "daemon" which fails over
++     * NFS and works with local file systems.  It's not clear where
++     * the bug is located.  -Joey
++     */
+     if (fscanf(stream, "#!/bin/sh\n# atrun uid=%d gid=%d\n# mail %8s %d",
+              &nuid, &ngid, mailbuf, &send_mail) != 4)
+       pabort("File %.500s is in wrong format - aborting",
+@@ -298,6 +342,8 @@
+     write_string(fd_out, "Subject: Output from your job ");
+     write_string(fd_out, jobbuf);
++    write_string(fd_out, "\nTo: ");
++    write_string(fd_out, mailname);    
+     write_string(fd_out, "\n\n");
+     fstat(fd_out, &buf);
+     size = buf.st_size;
+@@ -359,6 +405,11 @@
+      */
+     close(fd_in);
+     close(fd_out);
++
++    /* We inherited the master's SIGCHLD handler, which does a
++       non-blocking waitpid. So this blocking one will eventually
++       return with an ECHILD error. 
++     */
+     waitpid(pid, (int *) NULL, 0);
+     /* Send mail.  Unlink the output file after opening it, so it
+@@ -376,7 +427,7 @@
+     unlink(newname);
+     free(newname);
+-    if ((buf.st_size != size) || send_mail) {
++    if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) {
+       PRIV_START
+@@ -436,34 +487,51 @@
+      * atrun.
+      */
+-    if ((spool = opendir(".")) == NULL)
+-      perr("Cannot read " ATJOB_DIR);
+-
+     next_job = now + CHECK_INTERVAL;
+     if (next_batch == 0)
+       next_batch = now;
++    /* To avoid spinning up the disk unnecessarily, stat the directory and
++     * return immediately if it hasn't changed since the last time we woke
++     * up.
++     */
++
++    if (stat(".", &buf) == -1)
++      perr("Cannot stat " ATJOB_DIR);
++
++    if (nothing_to_do && buf.st_mtime <= last_chg)
++      return next_job;
++    last_chg = buf.st_mtime;
++
++    if ((spool = opendir(".")) == NULL)
++      perr("Cannot read " ATJOB_DIR);
++
+     run_batch = 0;
++    nothing_to_do = 1;
+     batch_uid = (uid_t) - 1;
+     batch_gid = (gid_t) - 1;
+     while ((dirent = readdir(spool)) != NULL) {
+-      if (stat(dirent->d_name, &buf) != 0) {
+-          /* Chances are a '=' file has been deleted from under us.
+-           * Ignore.
+-           */
+-      }
++      /* Avoid the stat if this doesn't look like a job file */
++      if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3)
++          continue;
+-      /* We don't want directories or files which at(1) hasn't yet
+-       * marked executable.
++      /* Chances are a '=' file has been deleted from under us.
++       * Ignore.
+        */
+-      if ((!S_ISREG(buf.st_mode)) || !(buf.st_mode & S_IXUSR))
++      if (stat(dirent->d_name, &buf) != 0)
+           continue;
+-      if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3)
++      if (!S_ISREG(buf.st_mode))
++          continue;
++
++      /* We don't want files which at(1) hasn't yet marked executable. */
++      if (!(buf.st_mode & S_IXUSR)) {
++          nothing_to_do = 0;  /* it will probably become executable soon */
+           continue;
++      }
+       run_time = (time_t) ctm *60;
+@@ -493,9 +561,18 @@
+               lock_name[0] = '=';
+               unlink(lock_name);
+               next_job = now;
++              nothing_to_do = 0;
+           }
+           continue;
+       }
++
++      /* If we got here, then there are jobs of some kind waiting.
++       * We could try to be smarter and leave nothing_to_do set if
++       * we end up processing all the jobs, but that's risky (run_file
++       * might fail and expect the job to be rescheduled), and it doesn't
++       * gain us much. */
++      nothing_to_do = 0;
++
+       /* There's a job for later.  Note its execution time if it's
+        * the earlierst so far.
+        */
+@@ -540,6 +617,7 @@
+         }
+     }
+     if (run_batch && (next_batch < next_job)) {
++      nothing_to_do = 0;
+       next_job = next_batch;
+     }
+     return next_job;
+@@ -631,6 +709,11 @@
+     if (optind < argc)
+       pabort("non-option arguments - not allowed");
++    sigaction(SIGCHLD, NULL, &act);
++    act.sa_handler = release_zombie;
++    act.sa_flags   = SA_NOCLDSTOP;
++    sigaction(SIGCHLD, &act, NULL);
++
+     if (!run_as_daemon) {
+       now = time(NULL);
+       run_loop();
+@@ -646,10 +729,6 @@
+     sigaction(SIGHUP, NULL, &act);
+     act.sa_handler = sdummy;
+     sigaction(SIGHUP, &act, NULL);
+-
+-    sigaction(SIGCHLD, NULL, &act);
+-    act.sa_handler = SIG_IGN;
+-    sigaction(SIGCHLD, &act, NULL);
+     sigaction(SIGTERM, NULL, &act);
+     act.sa_handler = set_term;
+--- at-3.1.8.orig/panic.c
++++ at-3.1.8/panic.c
+@@ -41,6 +41,7 @@
+ /* Local headers */
+ #include "panic.h"
++#include "privs.h"
+ #include "at.h"
+ /* File scope variables */
+@@ -72,12 +73,15 @@
+     va_list args;
+     va_start(args, fmt);
+-    vsprintf(buf, fmt, args);
++    vsnprintf(buf, sizeof(buf), fmt, args);
+     va_end(args);
+     perror(buf);
+-    if (fcreated)
++    if (fcreated) {
++        PRIV_START
+       unlink(atfile);
++        PRIV_END
++    }
+     exit(EXIT_FAILURE);
+ }
+@@ -88,7 +92,7 @@
+ /* Print usage and exit.
+  */
+     fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-m] time\n"
+-          "       atq [-V] [-q x] [-v]\n"
++          "       atq [-V] [-q x]\n"
+           "       atrm [-V] [-q x] job ...\n"
+           "       batch [-V] [-f file] [-m]\n");
+     exit(EXIT_FAILURE);
+--- at-3.1.8.orig/perm.c
++++ at-3.1.8/perm.c
+@@ -43,7 +43,13 @@
+ /* Macros */
+-#define MAXUSERID 10
++#if defined(DEBUG_PERM_C)
++#define ETCDIR "../test/etc"
++#undef PRIV_START
++#define PRIV_START while(0)
++#undef PRIV_END
++#define PRIV_END while(0)
++#endif
+ /* Structures and unions */
+@@ -54,66 +60,87 @@
+ /* Function declarations */
+-static int check_for_user(FILE * fp, const char *name);
++static int user_in_file(const char *path, const char *name);
+ /* Local functions */
++/* 
++ */  
+ static int 
+-check_for_user(FILE * fp, const char *name)
++user_in_file(const char *path, const char *name)
+ {
+-    char *buffer;
+-    size_t len;
+-    int found = 0;
+-
+-    len = strlen(name);
+-    buffer = mymalloc(len + 2);
+-
+-    while (fgets(buffer, len + 2, fp) != NULL) {
+-      if ((strncmp(name, buffer, len) == 0) &&
+-          (buffer[len] == '\n')) {
+-          found = 1;
+-          break;
+-      }
+-    }
+-    fclose(fp);
+-    free(buffer);
+-    return found;
+-}
+-/* Global functions */
+-int 
+-check_permission()
+-{
+-    FILE *fp;
+-    uid_t uid = geteuid();
+-    struct passwd *pentry;
++  FILE *fp;
++  char buffer[256];
++  int found = 0;
++  int c = '\n';
++
++  PRIV_START;
++    fp = fopen( path, "r");
++  PRIV_END;
++
++  if ( fp == NULL )
++    return -1;
++
++
++  while ( !found && fgets(buffer, sizeof(buffer), fp) != NULL) {
++    size_t llen = strlen(buffer);
+-    if (uid == 0)
+-      return 1;
++    c = buffer[llen-1];
+-    if ((pentry = getpwuid(uid)) == NULL) {
+-      perror("Cannot access user database");
+-      exit(EXIT_FAILURE);
+-    }
+-    PRIV_START
++    if (c == '\n')
++      buffer[llen-1] = '\0';
++    while (c != '\n' && c != EOF)
++      c = fgetc(fp);
++    
++    found = (strcmp(buffer, name)==0);
++  }
+-      fp = fopen(ETCDIR "/at.allow", "r");
++  fclose(fp);
+-    PRIV_END
++  if (c == EOF) {
++    fprintf(stderr, "%s: incomplete last line.\n", path);
++  }
++
++  return found;
++}
+-    if (fp != NULL) {
+-      return check_for_user(fp, pentry->pw_name);
+-    } else {
+-      PRIV_START
++/* Global functions */
++int
++check_permission()
++{
++  uid_t uid = geteuid();
++  struct passwd *pentry;
++  int    allow = 0, deny = 1;
++
++  if (uid == 0)
++    return 1;
++
++  if ((pentry = getpwuid(uid)) == NULL) {
++    perror("Cannot access user database");
++    exit(EXIT_FAILURE);
++  }
++
++  allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name);
++  if (allow==0 || allow==1)
++    return allow;
++
++  /* There was an error while looking for pw_name in at.allow.
++   * Check at.deny only when at.allow doesn't exist.
++   */
++ 
++  deny = user_in_file(ETCDIR "/at.deny", pentry->pw_name);
++  return deny == 0;
++}
+-          fp = fopen(ETCDIR "/at.deny", "r");
+-      PRIV_END
++#if defined(DEBUG_PERM_C)
+-      if (fp != NULL) {
+-          return !check_for_user(fp, pentry->pw_name);
+-      }
+-      perror("at.deny");
+-    }
+-    return 0;
++int
++main(int argc, char *argv[])
++{
++  printf("check_permission() ==> %d\n", check_permission());
++  return 0;
+ }
++
++#endif
+--- at-3.1.8.orig/daemon.c
++++ at-3.1.8/daemon.c
+@@ -72,7 +72,7 @@
+     va_list args;
+     va_start(args, fmt);
+-    vsprintf(buf, fmt, args);
++    vsnprintf(buf, sizeof(buf), fmt, args);
+     va_end(args);
+     if (daemon_debug) {
+@@ -90,7 +90,7 @@
+     va_list args;
+     va_start(args, fmt);
+-    vsprintf(buf, fmt, args);
++    vsnprintf(buf, sizeof(buf), fmt, args);
+     va_end(args);
+     if (daemon_debug) {
+@@ -127,6 +127,7 @@
+       }
+     }
+     old_umask = umask(S_IWGRP | S_IWOTH);
++    (void) setsid();
+     PRIV_START
+--- at-3.1.8.orig/y.tab.c
++++ at-3.1.8/y.tab.c
+@@ -1,45 +1,45 @@
+-/*  A Bison parser, made from parsetime.y with Bison version GNU Bison version 1.22
+-  */
++/*  A Bison parser, made from parsetime.y
++    by GNU Bison version 1.28  */
+ #define YYBISON 1  /* Identify Bison output.  */
+-#define       INT     258
+-#define       NOW     259
+-#define       AM      260
+-#define       PM      261
+-#define       NOON    262
+-#define       MIDNIGHT        263
+-#define       TEATIME 264
+-#define       SUN     265
+-#define       MON     266
+-#define       TUE     267
+-#define       WED     268
+-#define       THU     269
+-#define       FRI     270
+-#define       SAT     271
+-#define       TODAY   272
+-#define       TOMORROW        273
+-#define       NEXT    274
+-#define       MINUTE  275
+-#define       HOUR    276
+-#define       DAY     277
+-#define       WEEK    278
+-#define       MONTH   279
+-#define       YEAR    280
+-#define       JAN     281
+-#define       FEB     282
+-#define       MAR     283
+-#define       APR     284
+-#define       MAY     285
+-#define       JUN     286
+-#define       JUL     287
+-#define       AUG     288
+-#define       SEP     289
+-#define       OCT     290
+-#define       NOV     291
+-#define       DEC     292
+-#define       WORD    293
++#define       INT     257
++#define       NOW     258
++#define       AM      259
++#define       PM      260
++#define       NOON    261
++#define       MIDNIGHT        262
++#define       TEATIME 263
++#define       SUN     264
++#define       MON     265
++#define       TUE     266
++#define       WED     267
++#define       THU     268
++#define       FRI     269
++#define       SAT     270
++#define       TODAY   271
++#define       TOMORROW        272
++#define       NEXT    273
++#define       MINUTE  274
++#define       HOUR    275
++#define       DAY     276
++#define       WEEK    277
++#define       MONTH   278
++#define       YEAR    279
++#define       JAN     280
++#define       FEB     281
++#define       MAR     282
++#define       APR     283
++#define       MAY     284
++#define       JUN     285
++#define       JUL     286
++#define       AUG     287
++#define       SEP     288
++#define       OCT     289
++#define       NOV     290
++#define       DEC     291
++#define       WORD    292
+ #line 1 "parsetime.y"
+@@ -55,30 +55,16 @@
+ static int isgmt;
+ static int time_only;
++extern int yyerror(char *s);
++extern int yylex();
++
+ int add_date(int number, int period);
+-#line 17 "parsetime.y"
++#line 20 "parsetime.y"
+ typedef union {
+       char *          charval;
+       int             intval;
+ } YYSTYPE;
+-
+-#ifndef YYLTYPE
+-typedef
+-  struct yyltype
+-    {
+-      int timestamp;
+-      int first_line;
+-      int first_column;
+-      int last_line;
+-      int last_column;
+-      char *text;
+-   }
+-  yyltype;
+-
+-#define YYLTYPE yyltype
+-#endif
+-
+ #include <stdio.h>
+ #ifndef __cplusplus
+@@ -89,11 +75,11 @@
+-#define       YYFINAL         100
++#define       YYFINAL         104
+ #define       YYFLAG          -32768
+ #define       YYNTBASE        47
+-#define YYTRANSLATE(x) ((unsigned)(x) <= 293 ? yytranslate[x] : 67)
++#define YYTRANSLATE(x) ((unsigned)(x) <= 292 ? yytranslate[x] : 69)
+ static const char yytranslate[] = {     0,
+      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+@@ -121,176 +107,203 @@
+      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+-     2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
+-     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+-    16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+-    26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+-    36,    37,    38
++     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
++     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
++    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
++    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
++    37,    38
+ };
+ #if YYDEBUG != 0
+ static const short yyprhs[] = {     0,
+-     0,     2,     5,     8,    12,    15,    19,    21,    23,    26,
+-    29,    31,    33,    36,    40,    45,    48,    52,    57,    63,
+-    65,    67,    69,    72,    77,    79,    81,    83,    89,    95,
+-    99,   102,   106,   112,   116,   119,   122,   126,   128,   130,
+-   132,   134,   136,   138,   140,   142,   144,   146,   148,   150,
+-   152,   154,   156,   158,   160,   162,   164,   166,   168,   170,
+-   172,   174,   176,   178,   180,   182,   184,   186,   188,   190,
+-   192,   194,   196,   198,   200,   202,   204
++     0,     2,     4,     7,    10,    14,    16,    18,    21,    23,
++    25,    27,    28,    30,    33,    37,    42,    45,    49,    54,
++    60,    62,    64,    66,    69,    73,    78,    80,    82,    84,
++    90,    96,   100,   103,   107,   113,   115,   117,   121,   124,
++   127,   131,   133,   135,   137,   139,   141,   143,   145,   147,
++   149,   151,   153,   155,   157,   159,   161,   163,   165,   167,
++   169,   171,   173,   175,   177,   179,   181,   183,   185,   187,
++   189,   191,   193,   195,   197,   199,   201,   203,   205,   207,
++   209
+ };
+-static const short yyrhs[] = {    50,
+-     0,    50,    51,     0,    50,    52,     0,    50,    51,    52,
+-     0,    50,    53,     0,    50,    51,    53,     0,    48,     0,
+-    49,     0,    49,    52,     0,    49,    53,     0,     4,     0,
+-    55,     0,    55,    56,     0,    57,    66,    58,     0,    57,
+-    66,    58,    56,     0,    57,    59,     0,    57,    59,    56,
+-     0,    57,    66,    58,    59,     0,    57,    66,    58,    59,
+-    56,     0,     7,     0,     8,     0,     9,     0,    60,    62,
+-     0,    60,    62,    39,    63,     0,    64,     0,    17,     0,
+-    18,     0,    63,    40,    61,    40,    62,     0,    62,    41,
+-    61,    41,    63,     0,    62,    41,    61,     0,    62,    60,
+-     0,    62,    60,    63,     0,    61,    42,    62,    42,    63,
+-     0,    43,    65,    54,     0,    19,    54,     0,    19,    64,
+-     0,    40,    65,    54,     0,    20,     0,    21,     0,    22,
+-     0,    23,     0,    24,     0,    25,     0,     3,     0,    38,
+-     0,    55,     0,     3,     0,     5,     0,     6,     0,    26,
+-     0,    27,     0,    28,     0,    29,     0,    30,     0,    31,
+-     0,    32,     0,    33,     0,    34,     0,    35,     0,    36,
+-     0,    37,     0,     3,     0,     3,     0,     3,     0,    10,
+-     0,    11,     0,    12,     0,    13,     0,    14,     0,    15,
+-     0,    16,     0,     3,     0,    44,     0,    45,     0,    41,
+-     0,    46,     0,    39,     0
++static const short yyrhs[] = {    52,
++     0,    51,     0,    51,    52,     0,    50,    53,     0,    50,
++    52,    53,     0,    48,     0,    49,     0,    49,    53,     0,
++     4,     0,    18,     0,    51,     0,     0,    57,     0,    57,
++    58,     0,    59,    68,    60,     0,    59,    68,    60,    58,
++     0,    59,    61,     0,    59,    61,    58,     0,    59,    68,
++    60,    61,     0,    59,    68,    60,    61,    58,     0,     7,
++     0,     8,     0,     9,     0,    62,    64,     0,    62,    64,
++    65,     0,    62,    64,    39,    65,     0,    66,     0,    17,
++     0,    18,     0,    65,    40,    63,    40,    64,     0,    64,
++    41,    63,    41,    65,     0,    64,    41,    63,     0,    64,
++    62,     0,    64,    62,    65,     0,    63,    42,    64,    42,
++    65,     0,    54,     0,    55,     0,    43,    67,    56,     0,
++    19,    56,     0,    19,    66,     0,    40,    67,    56,     0,
++    20,     0,    21,     0,    22,     0,    23,     0,    24,     0,
++    25,     0,     3,     0,    38,     0,    57,     0,     3,     0,
++     5,     0,     6,     0,    26,     0,    27,     0,    28,     0,
++    29,     0,    30,     0,    31,     0,    32,     0,    33,     0,
++    34,     0,    35,     0,    36,     0,    37,     0,     3,     0,
++     3,     0,     3,     0,    10,     0,    11,     0,    12,     0,
++    13,     0,    14,     0,    15,     0,    16,     0,     3,     0,
++    44,     0,    45,     0,    41,     0,    46,     0,    39,     0
+ };
+ #endif
+ #if YYDEBUG != 0
+ static const short yyrline[] = { 0,
+-    39,    43,    44,    45,    46,    47,    48,    51,    52,    53,
+-    56,    59,    60,    61,    62,    63,    64,    65,    66,    67,
+-    72,    78,    85,    86,    87,    91,    92,    96,    97,    98,
+-    99,   100,   101,   104,   108,   112,   118,   124,   125,   126,
+-   127,   128,   129,   132,   157,   170,   173,   183,   184,   197,
+-   198,   199,   200,   201,   202,   203,   204,   205,   206,   207,
+-   208,   211,   225,   238,   261,   262,   263,   264,   265,   266,
+-   267,   270,   280,   281,   282,   283,   284
++    42,    43,    47,    48,    49,    50,    53,    54,    57,    58,
++    64,    65,    67,    68,    69,    70,    71,    72,    73,    74,
++    75,    80,    86,    93,    94,    95,    96,   100,   101,   105,
++   106,   107,   108,   109,   110,   113,   114,   116,   120,   124,
++   130,   136,   137,   138,   139,   140,   141,   144,   215,   228,
++   231,   241,   251,   264,   265,   266,   267,   268,   269,   270,
++   271,   272,   273,   274,   275,   278,   292,   305,   328,   329,
++   330,   331,   332,   333,   334,   337,   347,   348,   349,   350,
++   351
+ };
++#endif
++
+-static const char * const yytname[] = {   "$","error","$illegal.","INT","NOW",
++#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
++
++static const char * const yytname[] = {   "$","error","$undefined.","INT","NOW",
+ "AM","PM","NOON","MIDNIGHT","TEATIME","SUN","MON","TUE","WED","THU","FRI","SAT",
+ "TODAY","TOMORROW","NEXT","MINUTE","HOUR","DAY","WEEK","MONTH","YEAR","JAN",
+ "FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC","WORD","','",
+-"'-'","'.'","'/'","'+'","':'","'\\''","'h'","timespec","nowspec","now","time",
+-"date","increment","decrement","inc_period","hr24clock_hr_min","timezone_name",
+-"hr24clock_hour","minute","am_pm","month_name","month_number","day_number","year_number",
+-"day_of_week","inc_number","time_sep",""
++"'-'","'.'","'/'","'+'","':'","'\\''","'h'","timespec","nowspec","now","time_or_not",
++"time","date","inc_or_dec","increment","decrement","inc_period","hr24clock_hr_min",
++"timezone_name","hr24clock_hour","minute","am_pm","month_name","month_number",
++"day_number","year_number","day_of_week","inc_number","time_sep", NULL
+ };
+ #endif
+ static const short yyr1[] = {     0,
+-    47,    47,    47,    47,    47,    47,    47,    48,    48,    48,
+-    49,    50,    50,    50,    50,    50,    50,    50,    50,    50,
++    47,    47,    47,    47,    47,    47,    48,    48,    49,    49,
+     50,    50,    51,    51,    51,    51,    51,    51,    51,    51,
+-    51,    51,    51,    52,    52,    52,    53,    54,    54,    54,
+-    54,    54,    54,    55,    56,    57,    58,    59,    59,    60,
+-    60,    60,    60,    60,    60,    60,    60,    60,    60,    60,
+-    60,    61,    62,    63,    64,    64,    64,    64,    64,    64,
+-    64,    65,    66,    66,    66,    66,    66
++    51,    51,    51,    52,    52,    52,    52,    52,    52,    52,
++    52,    52,    52,    52,    52,    53,    53,    54,    54,    54,
++    55,    56,    56,    56,    56,    56,    56,    57,    58,    59,
++    60,    61,    61,    62,    62,    62,    62,    62,    62,    62,
++    62,    62,    62,    62,    62,    63,    64,    65,    66,    66,
++    66,    66,    66,    66,    66,    67,    68,    68,    68,    68,
++    68
+ };
+ static const short yyr2[] = {     0,
+-     1,     2,     2,     3,     2,     3,     1,     1,     2,     2,
+-     1,     1,     2,     3,     4,     2,     3,     4,     5,     1,
+-     1,     1,     2,     4,     1,     1,     1,     5,     5,     3,
+-     2,     3,     5,     3,     2,     2,     3,     1,     1,     1,
++     1,     1,     2,     2,     3,     1,     1,     2,     1,     1,
++     1,     0,     1,     2,     3,     4,     2,     3,     4,     5,
++     1,     1,     1,     2,     3,     4,     1,     1,     1,     5,
++     5,     3,     2,     3,     5,     1,     1,     3,     2,     2,
++     3,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+      1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+      1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+      1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+-     1,     1,     1,     1,     1,     1,     1
++     1
+ };
+-static const short yydefact[] = {     0,
+-    44,    11,    20,    21,    22,     7,     8,     1,    12,     0,
+-     0,     0,     0,     9,    10,    63,    65,    66,    67,    68,
+-    69,    70,    71,    26,    27,    50,    51,    52,    53,    54,
+-    55,    56,    57,    58,    59,    60,    61,     2,     3,     5,
+-     0,     0,     0,     0,    25,    45,    13,    48,    49,    77,
+-    75,    73,    74,    76,    16,     0,    38,    39,    40,    41,
+-    42,    43,    35,    36,    72,     0,     0,     4,     6,    63,
+-    23,     0,     0,    31,     0,    17,    47,    14,    37,    34,
+-     0,     0,    62,    30,    64,    32,     0,    15,    18,    24,
+-     0,     0,     0,    19,    33,    29,    28,     0,     0,     0
++static const short yydefact[] = {    12,
++    48,     9,    21,    22,    23,    69,    70,    71,    72,    73,
++    74,    75,    28,    10,    54,    55,    56,    57,    58,    59,
++    60,    61,    62,    63,    64,    65,     6,     7,     0,    11,
++     1,    13,     0,     0,     0,     0,     0,    27,     0,     0,
++     0,     8,    36,    37,    67,    29,     0,     4,     3,    49,
++    14,    52,    53,    81,    79,    77,    78,    80,    17,     0,
++    67,    24,     0,     0,    33,     0,    42,    43,    44,    45,
++    46,    47,    39,    40,    76,     0,     0,     5,    18,    51,
++    15,    68,     0,    25,     0,    66,    32,    34,     0,    41,
++    38,    16,    19,    26,     0,     0,     0,    20,    35,    31,
++    30,     0,     0,     0
+ };
+-static const short yydefgoto[] = {    98,
+-     6,     7,     8,    38,    14,    15,    63,     9,    47,    10,
+-    78,    55,    41,    42,    43,    44,    45,    66,    56
++static const short yydefgoto[] = {   102,
++    27,    28,    29,    30,    31,    42,    43,    44,    73,    32,
++    51,    33,    81,    59,    34,    35,    36,    37,    38,    76,
++    60
+ };
+-static const short yypact[] = {     8,
+--32768,-32768,-32768,-32768,-32768,-32768,   -14,    43,    -4,     4,
+-    80,     5,     5,-32768,-32768,   -12,-32768,-32768,-32768,-32768,
++static const short yypact[] = {   114,
++   -21,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+--32768,-32768,-32768,-32768,-32768,-32768,-32768,   -14,-32768,-32768,
+-    10,    -6,    81,    -8,-32768,-32768,-32768,-32768,-32768,-32768,
+--32768,-32768,-32768,-32768,     9,    48,-32768,-32768,-32768,-32768,
+--32768,-32768,-32768,-32768,-32768,    -2,    -2,-32768,-32768,-32768,
+-    25,    10,    63,    64,    63,-32768,-32768,     1,-32768,-32768,
+-    64,    26,-32768,    41,-32768,-32768,    44,-32768,     9,-32768,
+-    64,    64,    10,-32768,-32768,-32768,-32768,    85,    87,-32768
++-32768,-32768,-32768,-32768,-32768,-32768,-32768,   -13,    41,    79,
++-32768,    -4,     4,    22,   -14,   142,    -8,-32768,   174,    33,
++    33,-32768,-32768,-32768,   -18,-32768,   -13,-32768,-32768,-32768,
++-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,     9,    58,
++-32768,     0,    22,    59,    61,    59,-32768,-32768,-32768,-32768,
++-32768,-32768,-32768,-32768,-32768,    -5,    -5,-32768,-32768,-32768,
++     8,-32768,    61,-32768,    23,-32768,    25,-32768,    40,-32768,
++-32768,-32768,     9,-32768,    61,    61,    22,-32768,-32768,-32768,
++-32768,    83,    85,-32768
+ };
+ static const short yypgoto[] = {-32768,
+--32768,-32768,-32768,-32768,    -5,     6,   -42,-32768,   -51,-32768,
+--32768,    11,    54,   -10,   -41,     7,    95,   106,-32768
++-32768,-32768,-32768,-32768,   -22,   -24,-32768,-32768,   -65,-32768,
++   -55,-32768,-32768,     5,    51,   -33,   -34,    71,    49,    57,
++-32768
+ };
+-#define       YYLAST          122
++#define       YYLAST          199
+-static const short yytable[] = {    71,
+-   -46,   -46,    39,    76,    11,    48,    49,    65,    48,    49,
+-     1,     2,    70,    40,     3,     4,     5,    57,    58,    59,
+-    60,    61,    62,    79,    80,    12,    88,   -64,    13,   -62,
+-    82,    75,    68,    46,   -46,    72,   -46,    94,    46,   -46,
+-   -46,   -46,    50,    69,    51,    16,    46,    52,    53,    54,
+-    77,    97,    17,    18,    19,    20,    21,    22,    23,    24,
+-    25,    11,    84,    81,    87,    83,    85,    91,    26,    27,
+-    28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
+-    86,    92,    12,    93,    99,    13,   100,    90,    89,    17,
+-    18,    19,    20,    21,    22,    23,    74,    95,    96,    57,
+-    58,    59,    60,    61,    62,    64,    26,    27,    28,    29,
+-    30,    31,    32,    33,    34,    35,    36,    37,    67,     0,
+-     0,    73
++static const short yytable[] = {    62,
++   -50,   -50,    82,    79,    48,    39,    47,    49,    52,    53,
++    90,    91,    52,    53,    67,    68,    69,    70,    71,    72,
++   -66,   -68,    78,   -66,    61,    92,    40,    63,    85,    41,
++    87,    66,    89,    50,   -50,    75,   -50,    98,    83,   -50,
++   -50,   -50,    54,    45,    55,    50,    50,    56,    57,    58,
++     6,     7,     8,     9,    10,    11,    12,    13,    46,    39,
++    80,    86,   101,    82,    95,    96,    15,    16,    17,    18,
++    19,    20,    21,    22,    23,    24,    25,    26,    -2,    97,
++    40,    45,   103,    41,   104,    93,    65,    74,     6,     7,
++     8,     9,    10,    11,    12,    13,    46,    77,     0,     0,
++     0,     0,     0,     0,    15,    16,    17,    18,    19,    20,
++    21,    22,    23,    24,    25,    26,     1,     2,     0,     0,
++     3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
++    13,    14,    84,     0,     0,    88,     0,     0,     0,    15,
++    16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
++    26,     0,     0,    94,     0,     0,     0,     0,     0,     0,
++     0,     0,     0,     0,     0,    99,   100,    15,    16,    17,
++    18,    19,    20,    21,    22,    23,    24,    25,    26,     0,
++     0,     0,    64,     6,     7,     8,     9,    10,    11,    12,
++     0,     0,     0,    67,    68,    69,    70,    71,    72
+ };
+-static const short yycheck[] = {    41,
+-     5,     6,     8,    55,    19,     5,     6,     3,     5,     6,
+-     3,     4,     3,     8,     7,     8,     9,    20,    21,    22,
+-    23,    24,    25,    66,    67,    40,    78,    40,    43,    42,
+-    72,    40,    38,    38,    39,    42,    41,    89,    38,    44,
+-    45,    46,    39,    38,    41,     3,    38,    44,    45,    46,
+-     3,    93,    10,    11,    12,    13,    14,    15,    16,    17,
+-    18,    19,    73,    39,    75,     3,     3,    42,    26,    27,
+-    28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
+-    74,    41,    40,    40,     0,    43,     0,    81,    78,    10,
+-    11,    12,    13,    14,    15,    16,    43,    91,    92,    20,
+-    21,    22,    23,    24,    25,    11,    26,    27,    28,    29,
+-    30,    31,    32,    33,    34,    35,    36,    37,    13,    -1,
+-    -1,    41
++static const short yycheck[] = {    34,
++     5,     6,     3,    59,    29,    19,    29,    30,     5,     6,
++    76,    77,     5,     6,    20,    21,    22,    23,    24,    25,
++    42,    40,    47,    42,     3,    81,    40,    42,    63,    43,
++    64,    40,    66,    38,    39,     3,    41,    93,    39,    44,
++    45,    46,    39,     3,    41,    38,    38,    44,    45,    46,
++    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
++     3,     3,    97,     3,    42,    41,    26,    27,    28,    29,
++    30,    31,    32,    33,    34,    35,    36,    37,     0,    40,
++    40,     3,     0,    43,     0,    81,    36,    39,    10,    11,
++    12,    13,    14,    15,    16,    17,    18,    41,    -1,    -1,
++    -1,    -1,    -1,    -1,    26,    27,    28,    29,    30,    31,
++    32,    33,    34,    35,    36,    37,     3,     4,    -1,    -1,
++     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
++    17,    18,    62,    -1,    -1,    65,    -1,    -1,    -1,    26,
++    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
++    37,    -1,    -1,    83,    -1,    -1,    -1,    -1,    -1,    -1,
++    -1,    -1,    -1,    -1,    -1,    95,    96,    26,    27,    28,
++    29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
++    -1,    -1,    41,    10,    11,    12,    13,    14,    15,    16,
++    -1,    -1,    -1,    20,    21,    22,    23,    24,    25
+ };
+ /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+-#line 3 "/usr/lib/bison.simple"
++#line 3 "/usr/share/misc/bison.simple"
++/* This file comes from bison-1.28.  */
+ /* Skeleton output parser for bison,
+-   Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
++   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+-   the Free Software Foundation; either version 1, or (at your option)
++   the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+    This program is distributed in the hope that it will be useful,
+@@ -300,42 +313,66 @@
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
++   Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++/* As a special exception, when this file is copied by Bison into a
++   Bison output file, you may use that output file without restriction.
++   This special exception was added by the Free Software Foundation
++   in version 1.24 of Bison.  */
+-#ifndef alloca
++/* This is the parser code that is written into each bison parser
++  when the %semantic_parser declaration is not specified in the grammar.
++  It was written by Richard Stallman by simplifying the hairy parser
++  used when %semantic_parser is specified.  */
++
++#ifndef YYSTACK_USE_ALLOCA
++#ifdef alloca
++#define YYSTACK_USE_ALLOCA
++#else /* alloca not defined */
+ #ifdef __GNUC__
++#define YYSTACK_USE_ALLOCA
+ #define alloca __builtin_alloca
+ #else /* not GNU C.  */
+-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
++#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
++#define YYSTACK_USE_ALLOCA
+ #include <alloca.h>
+ #else /* not sparc */
+-#if defined (MSDOS) && !defined (__TURBOC__)
++/* We think this test detects Watcom and Microsoft C.  */
++/* This used to test MSDOS, but that is a bad idea
++   since that symbol is in the user namespace.  */
++#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
++#if 0 /* No need for malloc.h, which pollutes the namespace;
++       instead, just don't use alloca.  */
+ #include <malloc.h>
++#endif
+ #else /* not MSDOS, or __TURBOC__ */
+ #if defined(_AIX)
+-#include <malloc.h>
++/* I don't know what this was needed for, but it pollutes the namespace.
++   So I turned it off.   rms, 2 May 1997.  */
++/* #include <malloc.h>  */
+  #pragma alloca
+-#else /* not MSDOS, __TURBOC__, or _AIX */
+-#ifdef __hpux
+-#ifdef __cplusplus
+-extern "C" {
+-void *alloca (unsigned int);
+-};
+-#else /* not __cplusplus */
+-void *alloca ();
+-#endif /* not __cplusplus */
++#define YYSTACK_USE_ALLOCA
++#else /* not MSDOS, or __TURBOC__, or _AIX */
++#if 0
++#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
++               and on HPUX 10.  Eventually we can turn this on.  */
++#define YYSTACK_USE_ALLOCA
++#define alloca __builtin_alloca
+ #endif /* __hpux */
++#endif
+ #endif /* not _AIX */
+ #endif /* not MSDOS, or __TURBOC__ */
+-#endif /* not sparc.  */
+-#endif /* not GNU C.  */
+-#endif /* alloca not defined.  */
++#endif /* not sparc */
++#endif /* not GNU C */
++#endif /* alloca not defined */
++#endif /* YYSTACK_USE_ALLOCA not defined */
+-/* This is the parser code that is written into each bison parser
+-  when the %semantic_parser declaration is not specified in the grammar.
+-  It was written by Richard Stallman by simplifying the hairy parser
+-  used when %semantic_parser is specified.  */
++#ifdef YYSTACK_USE_ALLOCA
++#define YYSTACK_ALLOC alloca
++#else
++#define YYSTACK_ALLOC malloc
++#endif
+ /* Note: there must be only one dollar sign in this file.
+    It is replaced by the list of actions, each action
+@@ -345,8 +382,8 @@
+ #define yyclearin     (yychar = YYEMPTY)
+ #define YYEMPTY               -2
+ #define YYEOF         0
+-#define YYACCEPT      return(0)
+-#define YYABORT       return(1)
++#define YYACCEPT      goto yyacceptlab
++#define YYABORT       goto yyabortlab
+ #define YYERROR               goto yyerrlab1
+ /* Like YYERROR except do call yyerror.
+    This remains here temporarily to ease the
+@@ -375,10 +412,18 @@
+ #ifdef YYPURE
+ #ifdef YYLSP_NEEDED
++#ifdef YYLEX_PARAM
++#define YYLEX         yylex(&yylval, &yylloc, YYLEX_PARAM)
++#else
+ #define YYLEX         yylex(&yylval, &yylloc)
++#endif
++#else /* not YYLSP_NEEDED */
++#ifdef YYLEX_PARAM
++#define YYLEX         yylex(&yylval, YYLEX_PARAM)
+ #else
+ #define YYLEX         yylex(&yylval)
+ #endif
++#endif /* not YYLSP_NEEDED */
+ #endif
+ /* If nonreentrant, generate the variables here */
+@@ -419,24 +464,24 @@
+ #ifndef YYMAXDEPTH
+ #define YYMAXDEPTH 10000
+ #endif
+-
+-/* Prevent warning if -Wstrict-prototypes.  */
+-#ifdef __GNUC__
+-int yyparse (void);
+-#endif
\f
++/* Define __yy_memcpy.  Note that the size argument
++   should be passed with type unsigned int, because that is what the non-GCC
++   definitions require.  With GCC, __builtin_memcpy takes an arg
++   of type size_t, but it can handle unsigned int.  */
++
+ #if __GNUC__ > 1              /* GNU C and GNU C++ define this.  */
+-#define __yy_bcopy(FROM,TO,COUNT)     __builtin_memcpy(TO,FROM,COUNT)
++#define __yy_memcpy(TO,FROM,COUNT)    __builtin_memcpy(TO,FROM,COUNT)
+ #else                         /* not GNU C or C++ */
+ #ifndef __cplusplus
+ /* This is the most reliable way to avoid incompatibilities
+    in available built-in functions on various systems.  */
+ static void
+-__yy_bcopy (from, to, count)
+-     char *from;
++__yy_memcpy (to, from, count)
+      char *to;
+-     int count;
++     char *from;
++     unsigned int count;
+ {
+   register char *f = from;
+   register char *t = to;
+@@ -451,10 +496,10 @@
+ /* This is the most reliable way to avoid incompatibilities
+    in available built-in functions on various systems.  */
+ static void
+-__yy_bcopy (char *from, char *to, int count)
++__yy_memcpy (char *to, char *from, unsigned int count)
+ {
+-  register char *f = from;
+   register char *t = to;
++  register char *f = from;
+   register int i = count;
+   while (i-- > 0)
+@@ -464,9 +509,39 @@
+ #endif
+ #endif
\f
+-#line 184 "/usr/lib/bison.simple"
++#line 217 "/usr/share/misc/bison.simple"
++
++/* The user can define YYPARSE_PARAM as the name of an argument to be passed
++   into yyparse.  The argument should have type void *.
++   It should actually point to an object.
++   Grammar actions can access the variable by casting it
++   to the proper pointer type.  */
++
++#ifdef YYPARSE_PARAM
++#ifdef __cplusplus
++#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
++#define YYPARSE_PARAM_DECL
++#else /* not __cplusplus */
++#define YYPARSE_PARAM_ARG YYPARSE_PARAM
++#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
++#endif /* not __cplusplus */
++#else /* not YYPARSE_PARAM */
++#define YYPARSE_PARAM_ARG
++#define YYPARSE_PARAM_DECL
++#endif /* not YYPARSE_PARAM */
++
++/* Prevent warning if -Wstrict-prototypes.  */
++#ifdef __GNUC__
++#ifdef YYPARSE_PARAM
++int yyparse (void *);
++#else
++int yyparse (void);
++#endif
++#endif
++
+ int
+-yyparse()
++yyparse(YYPARSE_PARAM_ARG)
++     YYPARSE_PARAM_DECL
+ {
+   register int yystate;
+   register int yyn;
+@@ -492,6 +567,7 @@
+ #endif
+   int yystacksize = YYINITDEPTH;
++  int yyfree_stacks = 0;
+ #ifdef YYPURE
+   int yychar;
+@@ -576,18 +652,32 @@
+       if (yystacksize >= YYMAXDEPTH)
+       {
+         yyerror("parser stack overflow");
++        if (yyfree_stacks)
++          {
++            free (yyss);
++            free (yyvs);
++#ifdef YYLSP_NEEDED
++            free (yyls);
++#endif
++          }
+         return 2;
+       }
+       yystacksize *= 2;
+       if (yystacksize > YYMAXDEPTH)
+       yystacksize = YYMAXDEPTH;
+-      yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+-      __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+-      yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+-      __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
++#ifndef YYSTACK_USE_ALLOCA
++      yyfree_stacks = 1;
++#endif
++      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
++      __yy_memcpy ((char *)yyss, (char *)yyss1,
++                 size * (unsigned int) sizeof (*yyssp));
++      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
++      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
++                 size * (unsigned int) sizeof (*yyvsp));
+ #ifdef YYLSP_NEEDED
+-      yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+-      __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
++      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
++      __yy_memcpy ((char *)yyls, (char *)yyls1,
++                 size * (unsigned int) sizeof (*yylsp));
+ #endif
+ #endif /* no yyoverflow */
+@@ -747,102 +837,154 @@
+   switch (yyn) {
+-case 1:
+-#line 40 "parsetime.y"
++case 2:
++#line 44 "parsetime.y"
+ {
+                       time_only = 1;
+                   ;
+     break;}
+-case 20:
+-#line 68 "parsetime.y"
++case 10:
++#line 59 "parsetime.y"
++{
++                      add_date(1, DAY);
++                 ;
++    break;}
++case 21:
++#line 76 "parsetime.y"
+ {
+                       exectm.tm_hour = 12;
+                       exectm.tm_min = 0;
+                   ;
+     break;}
+-case 21:
+-#line 73 "parsetime.y"
++case 22:
++#line 81 "parsetime.y"
+ {
+                       exectm.tm_hour = 0;
+                       exectm.tm_min = 0;
+                       add_date(1, DAY);
+                   ;
+     break;}
+-case 22:
+-#line 79 "parsetime.y"
++case 23:
++#line 87 "parsetime.y"
+ {
+                       exectm.tm_hour = 16;
+                       exectm.tm_min = 0;
+                   ;
+     break;}
+-case 25:
+-#line 88 "parsetime.y"
++case 27:
++#line 97 "parsetime.y"
+ {
+-                     add_date ((7 + yyvsp[0].intval - exectm.tm_wday) %7 + 1, DAY);
++                     add_date ((6 + yyvsp[0].intval - exectm.tm_wday) %7 + 1, DAY);
+                  ;
+     break;}
+-case 27:
+-#line 93 "parsetime.y"
++case 29:
++#line 102 "parsetime.y"
+ {
+                       add_date(1, DAY);
+                  ;
+     break;}
+-case 34:
+-#line 105 "parsetime.y"
++case 38:
++#line 117 "parsetime.y"
+ {
+                       add_date(yyvsp[-1].intval, yyvsp[0].intval);
+                   ;
+     break;}
+-case 35:
+-#line 109 "parsetime.y"
++case 39:
++#line 121 "parsetime.y"
+ {
+                       add_date(1, yyvsp[0].intval);
+                   ;
+     break;}
+-case 36:
+-#line 113 "parsetime.y"
++case 40:
++#line 125 "parsetime.y"
+ {
+                       add_date ((6 + yyvsp[0].intval - exectm.tm_wday) %7 +1, DAY);
+                   ;
+     break;}
+-case 37:
+-#line 119 "parsetime.y"
++case 41:
++#line 131 "parsetime.y"
+ {
+                       add_date(-yyvsp[-1].intval, yyvsp[0].intval);
+                   ;
+     break;}
+-case 38:
+-#line 124 "parsetime.y"
++case 42:
++#line 136 "parsetime.y"
+ { yyval.intval = MINUTE ; ;
+     break;}
+-case 39:
+-#line 125 "parsetime.y"
++case 43:
++#line 137 "parsetime.y"
+ { yyval.intval = HOUR ; ;
+     break;}
+-case 40:
+-#line 126 "parsetime.y"
++case 44:
++#line 138 "parsetime.y"
+ { yyval.intval = DAY ; ;
+     break;}
+-case 41:
+-#line 127 "parsetime.y"
++case 45:
++#line 139 "parsetime.y"
+ { yyval.intval = WEEK ; ;
+     break;}
+-case 42:
+-#line 128 "parsetime.y"
++case 46:
++#line 140 "parsetime.y"
+ { yyval.intval = MONTH ; ;
+     break;}
+-case 43:
+-#line 129 "parsetime.y"
++case 47:
++#line 141 "parsetime.y"
+ { yyval.intval = YEAR ; ;
+     break;}
+-case 44:
+-#line 133 "parsetime.y"
++case 48:
++#line 145 "parsetime.y"
+ {
+-                      exectm.tm_min = -1;
+-                      exectm.tm_hour = -1;
+                       if (strlen(yyvsp[0].charval) == 4) {
++                          exectm.tm_min = -1;
++                          exectm.tm_hour = -1;
+                           sscanf(yyvsp[0].charval, "%2d %2d", &exectm.tm_hour,
+                               &exectm.tm_min);
++                      } else if (strlen(yyvsp[0].charval) >= 5 && strlen(yyvsp[0].charval) <= 8) {
++                              /* Ok, this is a kluge.  I hate design errors...  -Joey */
++                              char shallot[5];
++                              char *onion;
++
++                              onion=yyvsp[0].charval;
++                              memset (shallot, 0, sizeof (shallot));
++                              if (strlen(yyvsp[0].charval) == 5 || strlen(yyvsp[0].charval) == 7) {
++                                  strncpy (shallot,onion,1);
++                                  onion++;
++                              } else {
++                                  strncpy (shallot,onion,2);
++                                  onion+=2;
++                              }
++                              sscanf(shallot, "%d", &exectm.tm_mon);
++
++                              if (exectm.tm_mon < 1 || exectm.tm_mon > 12) {
++                                  yyerror("Error in month number");
++                                  YYERROR;
++                              }
++                              exectm.tm_mon--;
++
++                              memset (shallot, 0, sizeof (shallot));
++                              strncpy (shallot,onion,2);
++                              sscanf(shallot, "%d", &exectm.tm_mday);
++                              if (exectm.tm_mday < 0 || exectm.tm_mday > 31)
++                              {
++                                  yyerror("Error in day of month");
++                                  YYERROR;
++                              }
++
++                              onion+=2;
++                              memset (shallot, 0, sizeof (shallot));
++                              strncpy (shallot,onion,4);
++                              if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) {
++                                  yyerror("Error in year");
++                                  YYERROR;
++                              }
++                              if (exectm.tm_year < 70) {
++                                  exectm.tm_year += 100;
++                              }
++                              else if (exectm.tm_year > 1900) {
++                                  exectm.tm_year -= 1900;
++                              }
++
++                              free (yyvsp[0].charval);
+                       }
+                       else {
+                           sscanf(yyvsp[0].charval, "%d", &exectm.tm_hour);
+@@ -855,13 +997,13 @@
+                           YYERROR;
+                       }
+                       if (exectm.tm_hour > 24 || exectm.tm_hour < 0) {
+-                          yyerror("Problem in minutes specification");
++                          yyerror("Problem in hours specification");
+                           YYERROR;
+                       }
+                   ;
+     break;}
+-case 45:
+-#line 158 "parsetime.y"
++case 49:
++#line 216 "parsetime.y"
+ {
+                       if (strcasecmp(yyvsp[0].charval,"utc") == 0) {
+                           isgmt = 1;
+@@ -873,8 +1015,8 @@
+                       free(yyvsp[0].charval);
+                   ;
+     break;}
+-case 47:
+-#line 174 "parsetime.y"
++case 51:
++#line 232 "parsetime.y"
+ {
+                       if (sscanf(yyvsp[0].charval, "%d", &exectm.tm_min) != 1) {
+                           yyerror("Error in minute");
+@@ -883,8 +1025,20 @@
+                       free(yyvsp[0].charval);
+                   ;
+     break;}
+-case 49:
+-#line 185 "parsetime.y"
++case 52:
++#line 242 "parsetime.y"
++{
++                      if (exectm.tm_hour > 12) {
++                          yyerror("Hour too large for AM");
++                          YYERROR;
++                      }
++                      else if (exectm.tm_hour == 12) {
++                          exectm.tm_hour = 0;
++                      }
++                  ;
++    break;}
++case 53:
++#line 252 "parsetime.y"
+ {
+                       if (exectm.tm_hour > 12) {
+                           yyerror("Hour too large for PM");
+@@ -895,56 +1049,56 @@
+                       }
+                   ;
+     break;}
+-case 50:
+-#line 197 "parsetime.y"
++case 54:
++#line 264 "parsetime.y"
+ { exectm.tm_mon = 0; ;
+     break;}
+-case 51:
+-#line 198 "parsetime.y"
++case 55:
++#line 265 "parsetime.y"
+ { exectm.tm_mon = 1; ;
+     break;}
+-case 52:
+-#line 199 "parsetime.y"
++case 56:
++#line 266 "parsetime.y"
+ { exectm.tm_mon = 2; ;
+     break;}
+-case 53:
+-#line 200 "parsetime.y"
++case 57:
++#line 267 "parsetime.y"
+ { exectm.tm_mon = 3; ;
+     break;}
+-case 54:
+-#line 201 "parsetime.y"
++case 58:
++#line 268 "parsetime.y"
+ { exectm.tm_mon = 4; ;
+     break;}
+-case 55:
+-#line 202 "parsetime.y"
++case 59:
++#line 269 "parsetime.y"
+ { exectm.tm_mon = 5; ;
+     break;}
+-case 56:
+-#line 203 "parsetime.y"
++case 60:
++#line 270 "parsetime.y"
+ { exectm.tm_mon = 6; ;
+     break;}
+-case 57:
+-#line 204 "parsetime.y"
++case 61:
++#line 271 "parsetime.y"
+ { exectm.tm_mon = 7; ;
+     break;}
+-case 58:
+-#line 205 "parsetime.y"
++case 62:
++#line 272 "parsetime.y"
+ { exectm.tm_mon = 8; ;
+     break;}
+-case 59:
+-#line 206 "parsetime.y"
++case 63:
++#line 273 "parsetime.y"
+ { exectm.tm_mon = 9; ;
+     break;}
+-case 60:
+-#line 207 "parsetime.y"
++case 64:
++#line 274 "parsetime.y"
+ { exectm.tm_mon =10; ;
+     break;}
+-case 61:
+-#line 208 "parsetime.y"
++case 65:
++#line 275 "parsetime.y"
+ { exectm.tm_mon =11; ;
+     break;}
+-case 62:
+-#line 212 "parsetime.y"
++case 66:
++#line 279 "parsetime.y"
+ {
+                       {
+                           int mnum = -1;
+@@ -959,8 +1113,8 @@
+                       }
+                   ;
+     break;}
+-case 63:
+-#line 226 "parsetime.y"
++case 67:
++#line 293 "parsetime.y"
+ {
+                       exectm.tm_mday = -1;
+                       sscanf(yyvsp[0].charval, "%d", &exectm.tm_mday);
+@@ -972,8 +1126,8 @@
+                       free(yyvsp[0].charval);
+                    ;
+     break;}
+-case 64:
+-#line 239 "parsetime.y"
++case 68:
++#line 306 "parsetime.y"
+ { 
+                       {
+                           int ynum;
+@@ -994,36 +1148,36 @@
+                       }
+                   ;
+     break;}
+-case 65:
+-#line 261 "parsetime.y"
++case 69:
++#line 328 "parsetime.y"
+ { yyval.intval = 0; ;
+     break;}
+-case 66:
+-#line 262 "parsetime.y"
++case 70:
++#line 329 "parsetime.y"
+ { yyval.intval = 1; ;
+     break;}
+-case 67:
+-#line 263 "parsetime.y"
++case 71:
++#line 330 "parsetime.y"
+ { yyval.intval = 2; ;
+     break;}
+-case 68:
+-#line 264 "parsetime.y"
++case 72:
++#line 331 "parsetime.y"
+ { yyval.intval = 3; ;
+     break;}
+-case 69:
+-#line 265 "parsetime.y"
++case 73:
++#line 332 "parsetime.y"
+ { yyval.intval = 4; ;
+     break;}
+-case 70:
+-#line 266 "parsetime.y"
++case 74:
++#line 333 "parsetime.y"
+ { yyval.intval = 5; ;
+     break;}
+-case 71:
+-#line 267 "parsetime.y"
++case 75:
++#line 334 "parsetime.y"
+ { yyval.intval = 6; ;
+     break;}
+-case 72:
+-#line 271 "parsetime.y"
++case 76:
++#line 338 "parsetime.y"
+ {
+                       if (sscanf(yyvsp[0].charval, "%d", &yyval.intval) != 1) {
+                           yyerror("Unknown increment");
+@@ -1034,7 +1188,7 @@
+     break;}
+ }
+    /* the action file gets copied in in place of this dollarsign */
+-#line 465 "/usr/lib/bison.simple"
++#line 543 "/usr/share/misc/bison.simple"
\f
+   yyvsp -= yylen;
+   yyssp -= yylen;
+@@ -1229,8 +1383,32 @@
+   yystate = yyn;
+   goto yynewstate;
++
++ yyacceptlab:
++  /* YYACCEPT comes here.  */
++  if (yyfree_stacks)
++    {
++      free (yyss);
++      free (yyvs);
++#ifdef YYLSP_NEEDED
++      free (yyls);
++#endif
++    }
++  return 0;
++
++ yyabortlab:
++  /* YYABORT comes here.  */
++  if (yyfree_stacks)
++    {
++      free (yyss);
++      free (yyvs);
++#ifdef YYLSP_NEEDED
++      free (yyls);
++#endif
++    }
++  return 1;
+ }
+-#line 287 "parsetime.y"
++#line 354 "parsetime.y"
+@@ -1266,6 +1444,24 @@
+ }
+ #ifdef TEST_PARSER
++/*
++
++Here are some lines to test:
++
++./parsetest 7AM Mar 24 2000
++./parsetest 7AM Mar 24 00
++./parsetest 7AM 032400
++./parsetest 7AM 03/24/00
++./parsetest 7AM 24.03.00
++./parsetest 7AM Mar 24
++
++./parsetest 03242000
++./parsetest noon 03242000
++./parsetest 5:30
++./parsetest 4pm + 3 days
++./parsetest 10am Jul 31
++
++ */
+ int
+ main(int argc, char **argv)
+ {
+--- at-3.1.8.orig/y.tab.h
++++ at-3.1.8/y.tab.h
+@@ -2,42 +2,42 @@
+       char *          charval;
+       int             intval;
+ } YYSTYPE;
+-#define       INT     258
+-#define       NOW     259
+-#define       AM      260
+-#define       PM      261
+-#define       NOON    262
+-#define       MIDNIGHT        263
+-#define       TEATIME 264
+-#define       SUN     265
+-#define       MON     266
+-#define       TUE     267
+-#define       WED     268
+-#define       THU     269
+-#define       FRI     270
+-#define       SAT     271
+-#define       TODAY   272
+-#define       TOMORROW        273
+-#define       NEXT    274
+-#define       MINUTE  275
+-#define       HOUR    276
+-#define       DAY     277
+-#define       WEEK    278
+-#define       MONTH   279
+-#define       YEAR    280
+-#define       JAN     281
+-#define       FEB     282
+-#define       MAR     283
+-#define       APR     284
+-#define       MAY     285
+-#define       JUN     286
+-#define       JUL     287
+-#define       AUG     288
+-#define       SEP     289
+-#define       OCT     290
+-#define       NOV     291
+-#define       DEC     292
+-#define       WORD    293
++#define       INT     257
++#define       NOW     258
++#define       AM      259
++#define       PM      260
++#define       NOON    261
++#define       MIDNIGHT        262
++#define       TEATIME 263
++#define       SUN     264
++#define       MON     265
++#define       TUE     266
++#define       WED     267
++#define       THU     268
++#define       FRI     269
++#define       SAT     270
++#define       TODAY   271
++#define       TOMORROW        272
++#define       NEXT    273
++#define       MINUTE  274
++#define       HOUR    275
++#define       DAY     276
++#define       WEEK    277
++#define       MONTH   278
++#define       YEAR    279
++#define       JAN     280
++#define       FEB     281
++#define       MAR     282
++#define       APR     283
++#define       MAY     284
++#define       JUN     285
++#define       JUL     286
++#define       AUG     287
++#define       SEP     288
++#define       OCT     289
++#define       NOV     290
++#define       DEC     291
++#define       WORD    292
+ extern YYSTYPE yylval;
+--- at-3.1.8.orig/lex.yy.c
++++ at-3.1.8/lex.yy.c
+@@ -1,7 +1,7 @@
+ /* A lexical scanner generated by flex */
+ /* Scanner skeleton version:
+- * $Header$
++ * $Header$
+  */
+ #define FLEX_SCANNER
+@@ -126,6 +126,7 @@
+               { \
+               /* Undo effects of setting up yytext. */ \
+               *yy_cp = yy_hold_char; \
++              YY_RESTORE_YY_MORE_OFFSET \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+@@ -235,7 +236,7 @@
+ #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+ YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+-YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str ));
++YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+ YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+ static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+@@ -456,6 +457,7 @@
+ #define REJECT reject_used_but_not_detected
+ #define yymore() yymore_used_but_not_detected
+ #define YY_MORE_ADJ 0
++#define YY_RESTORE_YY_MORE_OFFSET
+ char *yytext;
+ #line 1 "parsetime.l"
+ #define INITIAL 0
+@@ -491,7 +493,7 @@
+       result = 1; \
+       } \
+     } while(0)
+-#line 495 "lex.yy.c"
++#line 497 "lex.yy.c"
+ /* Macros after this point can all be overridden by user definitions in
+  * section 1.
+@@ -513,6 +515,10 @@
+ static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+ #endif
++#ifdef YY_NEED_STRLEN
++static int yy_flex_strlen YY_PROTO(( yyconst char * ));
++#endif
++
+ #ifndef YY_NO_INPUT
+ #ifdef __cplusplus
+ static int yyinput YY_PROTO(( void ));
+@@ -641,7 +647,7 @@
+ #line 36 "parsetime.l"
+-#line 645 "lex.yy.c"
++#line 651 "lex.yy.c"
+       if ( yy_init )
+               {
+@@ -919,7 +925,7 @@
+ #line 77 "parsetime.l"
+ ECHO;
+       YY_BREAK
+-#line 923 "lex.yy.c"
++#line 929 "lex.yy.c"
+ case YY_STATE_EOF(INITIAL):
+       yyterminate();
+@@ -930,6 +936,7 @@
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = yy_hold_char;
++              YY_RESTORE_YY_MORE_OFFSET
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+@@ -1075,7 +1082,7 @@
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+                       {
+-                      /* We matched a singled characater, the EOB, so
++                      /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+@@ -1102,7 +1109,7 @@
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+-              yy_n_chars = 0;
++              yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+       else
+               {
+@@ -1157,6 +1164,8 @@
+               /* Read in more data. */
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
++
++              yy_current_buffer->yy_n_chars = yy_n_chars;
+               }
+       if ( yy_n_chars == 0 )
+@@ -1281,7 +1290,8 @@
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+-              yy_n_chars = yy_current_buffer->yy_buf_size;
++              yy_current_buffer->yy_n_chars =
++                      yy_n_chars = yy_current_buffer->yy_buf_size;
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+@@ -1319,19 +1329,31 @@
+               else
+                       { /* need more input */
+-                      yytext_ptr = yy_c_buf_p;
++                      int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
+                       switch ( yy_get_next_buffer() )
+                               {
++                              case EOB_ACT_LAST_MATCH:
++                                      /* This happens because yy_g_n_b()
++                                       * sees that we've accumulated a
++                                       * token and flags that we need to
++                                       * try matching the token before
++                                       * proceeding.  But for input(),
++                                       * there's no matching to consider.
++                                       * So convert the EOB_ACT_LAST_MATCH
++                                       * to EOB_ACT_END_OF_FILE.
++                                       */
++
++                                      /* Reset buffer status. */
++                                      yyrestart( yyin );
++
++                                      /* fall through */
++
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap() )
+-                                              {
+-                                              yy_c_buf_p =
+-                                              yytext_ptr + YY_MORE_ADJ;
+                                               return EOF;
+-                                              }
+                                       if ( ! yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+@@ -1343,17 +1365,8 @@
+                                       }
+                               case EOB_ACT_CONTINUE_SCAN:
+-                                      yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
++                                      yy_c_buf_p = yytext_ptr + offset;
+                                       break;
+-
+-                              case EOB_ACT_LAST_MATCH:
+-#ifdef __cplusplus
+-                                      YY_FATAL_ERROR(
+-                                      "unexpected last match in yyinput()" );
+-#else
+-                                      YY_FATAL_ERROR(
+-                                      "unexpected last match in input()" );
+-#endif
+                               }
+                       }
+               }
+@@ -1517,6 +1530,9 @@
+ #endif
+       {
++      if ( ! b )
++              return;
++
+       b->yy_n_chars = 0;
+       /* We always need two end-of-buffer characters.  The first causes
+@@ -1576,17 +1592,17 @@
+ #ifndef YY_NO_SCAN_STRING
+ #ifdef YY_USE_PROTOS
+-YY_BUFFER_STATE yy_scan_string( yyconst char *str )
++YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+ #else
+-YY_BUFFER_STATE yy_scan_string( str )
+-yyconst char *str;
++YY_BUFFER_STATE yy_scan_string( yy_str )
++yyconst char *yy_str;
+ #endif
+       {
+       int len;
+-      for ( len = 0; str[len]; ++len )
++      for ( len = 0; yy_str[len]; ++len )
+               ;
+-      return yy_scan_bytes( str, len );
++      return yy_scan_bytes( yy_str, len );
+       }
+ #endif
+@@ -1707,7 +1723,7 @@
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+-              yy_c_buf_p = yytext + n - YY_MORE_ADJ; \
++              yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+@@ -1730,6 +1746,22 @@
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
++      }
++#endif
++
++#ifdef YY_NEED_STRLEN
++#ifdef YY_USE_PROTOS
++static int yy_flex_strlen( yyconst char *s )
++#else
++static int yy_flex_strlen( s )
++yyconst char *s;
++#endif
++      {
++      register int n;
++      for ( n = 0; s[n]; ++n )
++              ;
++
++      return n;
+       }
+ #endif
+--- at-3.1.8.orig/Makefile.in
++++ at-3.1.8/Makefile.in
+@@ -131,6 +133,7 @@
+ clean:
+       rm -f subs.sed *.o *.s at atd core a.out *~ $(CLONES) *.bak stamp-built
++      rm -f parsetest 
+ distclean: clean 
+       rm -rf at.1 atd.8 atrun.8 config.cache atrun config.h \
+@@ -144,6 +147,9 @@
+ Filelist.asc: Filelist
+       pgp -sba Filelist
++
++parsetest: lex.yy.c y.tab.c
++      $(CC) -o parsetest $(CFLAGS) $(DEFS) -DTEST_PARSER -DNEED_YYWRAP lex.yy.c y.tab.c
+ .depend: $(CSRCS)
+       gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend
+--- at-3.1.8.orig/parsetime.y
++++ at-3.1.8/parsetime.y
+@@ -11,6 +11,9 @@
+ static int isgmt;
+ static int time_only;
++extern int yyerror(char *s);
++extern int yylex();
++
+ int add_date(int number, int period);
+ %}
+@@ -36,26 +39,31 @@
+ %start timespec
+ %%
+-timespec        : time
++timespec        : date
++              | time
+                   {
+                       time_only = 1;
+                   }
+                 | time date
+-                | time increment
+-                | time date increment
+-              | time decrement
+-              | time date decrement
++                | time_or_not inc_or_dec
++                | time_or_not date inc_or_dec
+                 | nowspec
+                 ;
+ nowspec         : now
+-                | now increment
+-              | now decrement
++                | now inc_or_dec
+                 ;
+ now           : NOW 
++                | TOMORROW
++                 {
++                      add_date(1, DAY);
++                 }
+               ;
++time_or_not     : time
++              |
++
+ time            : hr24clock_hr_min
+                 | hr24clock_hr_min timezone_name
+                 | hr24clock_hour time_sep minute
+@@ -83,10 +91,11 @@
+                 ;
+ date            : month_name day_number
++                | month_name day_number year_number
+                 | month_name day_number ',' year_number
+                 | day_of_week
+                  {
+-                     add_date ((7 + $1 - exectm.tm_wday) %7 + 1, DAY);
++                     add_date ((6 + $1 - exectm.tm_wday) %7 + 1, DAY);
+                  }
+                 | TODAY
+                 | TOMORROW
+@@ -101,6 +110,9 @@
+               | month_number '/' day_number '/' year_number
+                 ;
++inc_or_dec    : increment
++              | decrement
++
+ increment       : '+' inc_number inc_period
+                   {
+                       add_date($2, $3);
+@@ -131,11 +143,57 @@
+ hr24clock_hr_min: INT
+                   {
+-                      exectm.tm_min = -1;
+-                      exectm.tm_hour = -1;
+                       if (strlen($1) == 4) {
++                          exectm.tm_min = -1;
++                          exectm.tm_hour = -1;
+                           sscanf($1, "%2d %2d", &exectm.tm_hour,
+                               &exectm.tm_min);
++                      } else if (strlen($1) >= 5 && strlen($1) <= 8) {
++                              /* Ok, this is a kluge.  I hate design errors...  -Joey */
++                              char shallot[5];
++                              char *onion;
++
++                              onion=$1;
++                              memset (shallot, 0, sizeof (shallot));
++                              if (strlen($1) == 5 || strlen($1) == 7) {
++                                  strncpy (shallot,onion,1);
++                                  onion++;
++                              } else {
++                                  strncpy (shallot,onion,2);
++                                  onion+=2;
++                              }
++                              sscanf(shallot, "%d", &exectm.tm_mon);
++
++                              if (exectm.tm_mon < 1 || exectm.tm_mon > 12) {
++                                  yyerror("Error in month number");
++                                  YYERROR;
++                              }
++                              exectm.tm_mon--;
++
++                              memset (shallot, 0, sizeof (shallot));
++                              strncpy (shallot,onion,2);
++                              sscanf(shallot, "%d", &exectm.tm_mday);
++                              if (exectm.tm_mday < 0 || exectm.tm_mday > 31)
++                              {
++                                  yyerror("Error in day of month");
++                                  YYERROR;
++                              }
++
++                              onion+=2;
++                              memset (shallot, 0, sizeof (shallot));
++                              strncpy (shallot,onion,4);
++                              if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) {
++                                  yyerror("Error in year");
++                                  YYERROR;
++                              }
++                              if (exectm.tm_year < 70) {
++                                  exectm.tm_year += 100;
++                              }
++                              else if (exectm.tm_year > 1900) {
++                                  exectm.tm_year -= 1900;
++                              }
++
++                              free ($1);
+                       }
+                       else {
+                           sscanf($1, "%d", &exectm.tm_hour);
+@@ -148,7 +206,7 @@
+                           YYERROR;
+                       }
+                       if (exectm.tm_hour > 24 || exectm.tm_hour < 0) {
+-                          yyerror("Problem in minutes specification");
++                          yyerror("Problem in hours specification");
+                           YYERROR;
+                       }
+                   }
+@@ -181,6 +239,15 @@
+               ;
+ am_pm         : AM
++                  {
++                      if (exectm.tm_hour > 12) {
++                          yyerror("Hour too large for AM");
++                          YYERROR;
++                      }
++                      else if (exectm.tm_hour == 12) {
++                          exectm.tm_hour = 0;
++                      }
++                  }
+               | PM
+                   {
+                       if (exectm.tm_hour > 12) {
+@@ -319,6 +386,24 @@
+ }
+ #ifdef TEST_PARSER
++/*
++
++Here are some lines to test:
++
++./parsetest 7AM Mar 24 2000
++./parsetest 7AM Mar 24 00
++./parsetest 7AM 032400
++./parsetest 7AM 03/24/00
++./parsetest 7AM 24.03.00
++./parsetest 7AM Mar 24
++
++./parsetest 03242000
++./parsetest noon 03242000
++./parsetest 5:30
++./parsetest 4pm + 3 days
++./parsetest 10am Jul 31
++
++ */
+ int
+ main(int argc, char **argv)
+ {
This page took 0.284849 seconds and 4 git commands to generate.