4 static char rcsid[] = "$Id$";
7 - "TERM", "DISPLAY", "_", "SHELLOPTS"
8 + "TERM", "DISPLAY", "_", "SHELLOPTS", "BASH_VERSINFO", "EUID", "GROUPS", "PPID", "UID"
10 static int send_mail = 0;
13 /* Install the signal handler for SIGINT; terminate after removing the
14 * spool file if necessary
16 + memset(&act, 0, sizeof act);
17 act.sa_handler = sigc;
18 sigemptyset(&(act.sa_mask));
21 if ((jobno = nextjob()) == EOF)
22 perr("Cannot generate job number");
24 - sprintf(ppos, "%c%5lx%8lx", queue,
25 - jobno, (unsigned long) (runtimer / 60));
26 + (void)snprintf(ppos, sizeof(atfile) - (ppos - atfile),
27 + "%c%5lx%8lx", queue, jobno, (unsigned long) (runtimer / 60));
29 for (ap = ppos; *ap != '\0'; ap++)
32 * bit. Yes, this is a kluge.
34 cmask = umask(S_IRUSR | S_IWUSR | S_IXUSR);
35 - if ((fd = creat(atfile, O_WRONLY)) == -1)
36 + if ((fd = open(atfile, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR)) == -1)
37 perr("Cannot create atjob file %.500s", atfile);
39 if ((fd2 = dup(fd)) < 0)
44 - /* POSIX.2 allows the shell specified by the user's SHELL environment
45 - variable, the login shell from the user's password database entry,
46 - or /bin/sh to be the command interpreter that processes the at-job.
47 - It also alows a warning diagnostic to be printed. Because of the
48 - possible variance, we always output the diagnostic. */
50 - fprintf(stderr, "warning: commands will be executed using /bin/sh\n");
52 runtime = localtime(&runtimer);
54 /* We only use the sick POSIX time format if POSIXLY_CORRECT
58 char timestr[TIMESIZE];
65 strftime(timestr, TIMESIZE, TIMEFORMAT_ISO, runtime);
67 - printf("%ld\t%s %c\n", jobno, timestr, queue);
68 + if ((pwd = getpwuid(buf.st_uid)))
69 + printf("%ld\t%s %c %s\n", jobno, timestr, queue, pwd->pw_name);
71 + printf("%ld\t%s %c\n", jobno, timestr, queue);
78 int program = AT; /* our default program */
79 - char *options = "q:f:mvldVc"; /* default options for at */
80 + char *options = "q:f:MmvldhVc"; /* default options for at */
86 if (strcmp(pgm, "atq") == 0) {
90 } else if (strcmp(pgm, "atrm") == 0) {
95 /* process whatever options we can process
98 while ((c = getopt(argc, argv, options)) != EOF)
104 case 'v': /* verify time settings */
111 + case 'M': /* don't send mail, even when job failed */
121 atqueue = queue = *optarg;
122 - if (!(islower(queue) || isupper(queue)))
123 + if (!(islower(queue) || isupper(queue)) & (queue != '='))
128 struct tm *tm = localtime(&timer);
129 fprintf(stderr, "%s\n", asctime(tm));
132 + /* POSIX.2 allows the shell specified by the user's SHELL environment
133 + variable, the login shell from the user's password database entry,
134 + or /bin/sh to be the command interpreter that processes the at-job.
135 + It also alows a warning diagnostic to be printed. Because of the
136 + possible variance, we always output the diagnostic. */
138 + fprintf(stderr, "warning: commands will be executed using /bin/sh\n");
140 writefile(timer, queue);
143 --- at-3.1.8.orig/atd.c
150 + * /usr/bin/mail aka /usr/bin/mailx require the subject to be
151 + * specified on the command line instead of reading it from stdin like
152 + * /usr/sbin/sendmail does. For now simply disable MAILC and MAILX,
154 + * TODO: Remove tests for MAILC and MAILX from configure.in in the
155 + * next upstream version.
163 #include <sys/types.h>
165 static char rcsid[] = "$Id$";
166 static double load_avg = LOADAVG_MX;
168 +static time_t last_chg;
169 +static int nothing_to_do;
170 unsigned int batch_interval;
171 static int run_as_daemon = 0;
177 +/* SIGCHLD handler - discards completion status of children */
179 +release_zombie(int dummy)
184 + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
186 + if (WIFEXITED(status))
187 + syslog(LOG_INFO, "pid %ld exited with status %d.", pid, WEXITSTATUS(status));
188 + else if (WIFSIGNALED(status))
189 + syslog(LOG_NOTICE, "pid %ld killed with signal %d.", pid, WTERMSIG(status));
190 + else if (WIFSTOPPED(status))
191 + syslog(LOG_NOTICE, "pid %ld stopped with signal %d.", pid, WSTOPSIG(status));
193 + syslog(LOG_WARNING, "pid %ld unknown reason for SIGCHLD", pid);
200 /* Local functions */
205 fcntl(fd_in, F_SETFD, fflags & ~FD_CLOEXEC);
208 + * If the spool directory is mounted via NFS `atd' isn't able to
209 + * read from the job file and will bump out here. The file is
210 + * opened as "root" but it is read as "daemon" which fails over
211 + * NFS and works with local file systems. It's not clear where
212 + * the bug is located. -Joey
214 if (fscanf(stream, "#!/bin/sh\n# atrun uid=%d gid=%d\n# mail %8s %d",
215 &nuid, &ngid, mailbuf, &send_mail) != 4)
216 pabort("File %.500s is in wrong format - aborting",
219 write_string(fd_out, "Subject: Output from your job ");
220 write_string(fd_out, jobbuf);
221 + write_string(fd_out, "\nTo: ");
222 + write_string(fd_out, mailname);
223 write_string(fd_out, "\n\n");
231 + /* We inherited the master's SIGCHLD handler, which does a
232 + non-blocking waitpid. So this blocking one will eventually
233 + return with an ECHILD error.
235 waitpid(pid, (int *) NULL, 0);
237 /* Send mail. Unlink the output file after opening it, so it
242 - if ((buf.st_size != size) || send_mail) {
243 + if (((send_mail != -1) && (buf.st_size != size)) || (send_mail == 1)) {
247 @@ -436,34 +487,51 @@
251 - if ((spool = opendir(".")) == NULL)
252 - perr("Cannot read " ATJOB_DIR);
254 next_job = now + CHECK_INTERVAL;
258 + /* To avoid spinning up the disk unnecessarily, stat the directory and
259 + * return immediately if it hasn't changed since the last time we woke
263 + if (stat(".", &buf) == -1)
264 + perr("Cannot stat " ATJOB_DIR);
266 + if (nothing_to_do && buf.st_mtime <= last_chg)
268 + last_chg = buf.st_mtime;
270 + if ((spool = opendir(".")) == NULL)
271 + perr("Cannot read " ATJOB_DIR);
276 batch_uid = (uid_t) - 1;
277 batch_gid = (gid_t) - 1;
279 while ((dirent = readdir(spool)) != NULL) {
281 - if (stat(dirent->d_name, &buf) != 0) {
282 - /* Chances are a '=' file has been deleted from under us.
286 + /* Avoid the stat if this doesn't look like a job file */
287 + if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3)
290 - /* We don't want directories or files which at(1) hasn't yet
291 - * marked executable.
292 + /* Chances are a '=' file has been deleted from under us.
295 - if ((!S_ISREG(buf.st_mode)) || !(buf.st_mode & S_IXUSR))
296 + if (stat(dirent->d_name, &buf) != 0)
299 - if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3)
300 + if (!S_ISREG(buf.st_mode))
303 + /* We don't want files which at(1) hasn't yet marked executable. */
304 + if (!(buf.st_mode & S_IXUSR)) {
305 + nothing_to_do = 0; /* it will probably become executable soon */
309 run_time = (time_t) ctm *60;
320 + /* If we got here, then there are jobs of some kind waiting.
321 + * We could try to be smarter and leave nothing_to_do set if
322 + * we end up processing all the jobs, but that's risky (run_file
323 + * might fail and expect the job to be rescheduled), and it doesn't
327 /* There's a job for later. Note its execution time if it's
328 * the earlierst so far.
333 if (run_batch && (next_batch < next_job)) {
335 next_job = next_batch;
340 pabort("non-option arguments - not allowed");
342 + sigaction(SIGCHLD, NULL, &act);
343 + act.sa_handler = release_zombie;
344 + act.sa_flags = SA_NOCLDSTOP;
345 + sigaction(SIGCHLD, &act, NULL);
347 if (!run_as_daemon) {
351 sigaction(SIGHUP, NULL, &act);
352 act.sa_handler = sdummy;
353 sigaction(SIGHUP, &act, NULL);
355 - sigaction(SIGCHLD, NULL, &act);
356 - act.sa_handler = SIG_IGN;
357 - sigaction(SIGCHLD, &act, NULL);
359 sigaction(SIGTERM, NULL, &act);
360 act.sa_handler = set_term;
361 --- at-3.1.8.orig/panic.c
370 /* File scope variables */
375 - vsprintf(buf, fmt, args);
376 + vsnprintf(buf, sizeof(buf), fmt, args);
390 /* Print usage and exit.
392 fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-m] time\n"
393 - " atq [-V] [-q x] [-v]\n"
394 + " atq [-V] [-q x]\n"
395 " atrm [-V] [-q x] job ...\n"
396 " batch [-V] [-f file] [-m]\n");
398 --- at-3.1.8.orig/perm.c
404 -#define MAXUSERID 10
405 +#if defined(DEBUG_PERM_C)
406 +#define ETCDIR "../test/etc"
408 +#define PRIV_START while(0)
410 +#define PRIV_END while(0)
413 /* Structures and unions */
417 /* Function declarations */
419 -static int check_for_user(FILE * fp, const char *name);
420 +static int user_in_file(const char *path, const char *name);
422 /* Local functions */
427 -check_for_user(FILE * fp, const char *name)
428 +user_in_file(const char *path, const char *name)
434 - len = strlen(name);
435 - buffer = mymalloc(len + 2);
437 - while (fgets(buffer, len + 2, fp) != NULL) {
438 - if ((strncmp(name, buffer, len) == 0) &&
439 - (buffer[len] == '\n')) {
448 -/* Global functions */
453 - uid_t uid = geteuid();
454 - struct passwd *pentry;
461 + fp = fopen( path, "r");
468 + while ( !found && fgets(buffer, sizeof(buffer), fp) != NULL) {
469 + size_t llen = strlen(buffer);
473 + c = buffer[llen-1];
475 - if ((pentry = getpwuid(uid)) == NULL) {
476 - perror("Cannot access user database");
477 - exit(EXIT_FAILURE);
481 + buffer[llen-1] = '\0';
482 + while (c != '\n' && c != EOF)
485 + found = (strcmp(buffer, name)==0);
488 - fp = fopen(ETCDIR "/at.allow", "r");
493 + fprintf(stderr, "%s: incomplete last line.\n", path);
500 - return check_for_user(fp, pentry->pw_name);
504 +/* Global functions */
508 + uid_t uid = geteuid();
509 + struct passwd *pentry;
510 + int allow = 0, deny = 1;
515 + if ((pentry = getpwuid(uid)) == NULL) {
516 + perror("Cannot access user database");
517 + exit(EXIT_FAILURE);
520 + allow = user_in_file(ETCDIR "/at.allow", pentry->pw_name);
521 + if (allow==0 || allow==1)
524 + /* There was an error while looking for pw_name in at.allow.
525 + * Check at.deny only when at.allow doesn't exist.
528 + deny = user_in_file(ETCDIR "/at.deny", pentry->pw_name);
532 - fp = fopen(ETCDIR "/at.deny", "r");
535 +#if defined(DEBUG_PERM_C)
538 - return !check_for_user(fp, pentry->pw_name);
544 +main(int argc, char *argv[])
546 + printf("check_permission() ==> %d\n", check_permission());
551 --- at-3.1.8.orig/daemon.c
552 +++ at-3.1.8/daemon.c
557 - vsprintf(buf, fmt, args);
558 + vsnprintf(buf, sizeof(buf), fmt, args);
566 - vsprintf(buf, fmt, args);
567 + vsnprintf(buf, sizeof(buf), fmt, args);
574 old_umask = umask(S_IWGRP | S_IWOTH);
579 --- at-3.1.8.orig/y.tab.c
583 -/* A Bison parser, made from parsetime.y with Bison version GNU Bison version 1.22
585 +/* A Bison parser, made from parsetime.y
586 + by GNU Bison version 1.28 */
588 #define YYBISON 1 /* Identify Bison output. */
595 -#define MIDNIGHT 263
605 -#define TOMORROW 273
631 +#define MIDNIGHT 262
641 +#define TOMORROW 272
663 #line 1 "parsetime.y"
667 static int time_only;
669 +extern int yyerror(char *s);
672 int add_date(int number, int period);
674 -#line 17 "parsetime.y"
675 +#line 20 "parsetime.y"
694 -#define YYLTYPE yyltype
706 #define YYFLAG -32768
709 -#define YYTRANSLATE(x) ((unsigned)(x) <= 293 ? yytranslate[x] : 67)
710 +#define YYTRANSLATE(x) ((unsigned)(x) <= 292 ? yytranslate[x] : 69)
712 static const char yytranslate[] = { 0,
713 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
714 @@ -121,176 +107,203 @@
715 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
716 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
717 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
718 - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
719 - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
720 - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
721 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
723 + 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
724 + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
725 + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
726 + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
731 static const short yyprhs[] = { 0,
732 - 0, 2, 5, 8, 12, 15, 19, 21, 23, 26,
733 - 29, 31, 33, 36, 40, 45, 48, 52, 57, 63,
734 - 65, 67, 69, 72, 77, 79, 81, 83, 89, 95,
735 - 99, 102, 106, 112, 116, 119, 122, 126, 128, 130,
736 - 132, 134, 136, 138, 140, 142, 144, 146, 148, 150,
737 - 152, 154, 156, 158, 160, 162, 164, 166, 168, 170,
738 - 172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
739 - 192, 194, 196, 198, 200, 202, 204
740 + 0, 2, 4, 7, 10, 14, 16, 18, 21, 23,
741 + 25, 27, 28, 30, 33, 37, 42, 45, 49, 54,
742 + 60, 62, 64, 66, 69, 73, 78, 80, 82, 84,
743 + 90, 96, 100, 103, 107, 113, 115, 117, 121, 124,
744 + 127, 131, 133, 135, 137, 139, 141, 143, 145, 147,
745 + 149, 151, 153, 155, 157, 159, 161, 163, 165, 167,
746 + 169, 171, 173, 175, 177, 179, 181, 183, 185, 187,
747 + 189, 191, 193, 195, 197, 199, 201, 203, 205, 207,
751 -static const short yyrhs[] = { 50,
752 - 0, 50, 51, 0, 50, 52, 0, 50, 51, 52,
753 - 0, 50, 53, 0, 50, 51, 53, 0, 48, 0,
754 - 49, 0, 49, 52, 0, 49, 53, 0, 4, 0,
755 - 55, 0, 55, 56, 0, 57, 66, 58, 0, 57,
756 - 66, 58, 56, 0, 57, 59, 0, 57, 59, 56,
757 - 0, 57, 66, 58, 59, 0, 57, 66, 58, 59,
758 - 56, 0, 7, 0, 8, 0, 9, 0, 60, 62,
759 - 0, 60, 62, 39, 63, 0, 64, 0, 17, 0,
760 - 18, 0, 63, 40, 61, 40, 62, 0, 62, 41,
761 - 61, 41, 63, 0, 62, 41, 61, 0, 62, 60,
762 - 0, 62, 60, 63, 0, 61, 42, 62, 42, 63,
763 - 0, 43, 65, 54, 0, 19, 54, 0, 19, 64,
764 - 0, 40, 65, 54, 0, 20, 0, 21, 0, 22,
765 - 0, 23, 0, 24, 0, 25, 0, 3, 0, 38,
766 - 0, 55, 0, 3, 0, 5, 0, 6, 0, 26,
767 - 0, 27, 0, 28, 0, 29, 0, 30, 0, 31,
768 - 0, 32, 0, 33, 0, 34, 0, 35, 0, 36,
769 - 0, 37, 0, 3, 0, 3, 0, 3, 0, 10,
770 - 0, 11, 0, 12, 0, 13, 0, 14, 0, 15,
771 - 0, 16, 0, 3, 0, 44, 0, 45, 0, 41,
773 +static const short yyrhs[] = { 52,
774 + 0, 51, 0, 51, 52, 0, 50, 53, 0, 50,
775 + 52, 53, 0, 48, 0, 49, 0, 49, 53, 0,
776 + 4, 0, 18, 0, 51, 0, 0, 57, 0, 57,
777 + 58, 0, 59, 68, 60, 0, 59, 68, 60, 58,
778 + 0, 59, 61, 0, 59, 61, 58, 0, 59, 68,
779 + 60, 61, 0, 59, 68, 60, 61, 58, 0, 7,
780 + 0, 8, 0, 9, 0, 62, 64, 0, 62, 64,
781 + 65, 0, 62, 64, 39, 65, 0, 66, 0, 17,
782 + 0, 18, 0, 65, 40, 63, 40, 64, 0, 64,
783 + 41, 63, 41, 65, 0, 64, 41, 63, 0, 64,
784 + 62, 0, 64, 62, 65, 0, 63, 42, 64, 42,
785 + 65, 0, 54, 0, 55, 0, 43, 67, 56, 0,
786 + 19, 56, 0, 19, 66, 0, 40, 67, 56, 0,
787 + 20, 0, 21, 0, 22, 0, 23, 0, 24, 0,
788 + 25, 0, 3, 0, 38, 0, 57, 0, 3, 0,
789 + 5, 0, 6, 0, 26, 0, 27, 0, 28, 0,
790 + 29, 0, 30, 0, 31, 0, 32, 0, 33, 0,
791 + 34, 0, 35, 0, 36, 0, 37, 0, 3, 0,
792 + 3, 0, 3, 0, 10, 0, 11, 0, 12, 0,
793 + 13, 0, 14, 0, 15, 0, 16, 0, 3, 0,
794 + 44, 0, 45, 0, 41, 0, 46, 0, 39, 0
800 static const short yyrline[] = { 0,
801 - 39, 43, 44, 45, 46, 47, 48, 51, 52, 53,
802 - 56, 59, 60, 61, 62, 63, 64, 65, 66, 67,
803 - 72, 78, 85, 86, 87, 91, 92, 96, 97, 98,
804 - 99, 100, 101, 104, 108, 112, 118, 124, 125, 126,
805 - 127, 128, 129, 132, 157, 170, 173, 183, 184, 197,
806 - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
807 - 208, 211, 225, 238, 261, 262, 263, 264, 265, 266,
808 - 267, 270, 280, 281, 282, 283, 284
809 + 42, 43, 47, 48, 49, 50, 53, 54, 57, 58,
810 + 64, 65, 67, 68, 69, 70, 71, 72, 73, 74,
811 + 75, 80, 86, 93, 94, 95, 96, 100, 101, 105,
812 + 106, 107, 108, 109, 110, 113, 114, 116, 120, 124,
813 + 130, 136, 137, 138, 139, 140, 141, 144, 215, 228,
814 + 231, 241, 251, 264, 265, 266, 267, 268, 269, 270,
815 + 271, 272, 273, 274, 275, 278, 292, 305, 328, 329,
816 + 330, 331, 332, 333, 334, 337, 347, 348, 349, 350,
822 -static const char * const yytname[] = { "$","error","$illegal.","INT","NOW",
823 +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
825 +static const char * const yytname[] = { "$","error","$undefined.","INT","NOW",
826 "AM","PM","NOON","MIDNIGHT","TEATIME","SUN","MON","TUE","WED","THU","FRI","SAT",
827 "TODAY","TOMORROW","NEXT","MINUTE","HOUR","DAY","WEEK","MONTH","YEAR","JAN",
828 "FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC","WORD","','",
829 -"'-'","'.'","'/'","'+'","':'","'\\''","'h'","timespec","nowspec","now","time",
830 -"date","increment","decrement","inc_period","hr24clock_hr_min","timezone_name",
831 -"hr24clock_hour","minute","am_pm","month_name","month_number","day_number","year_number",
832 -"day_of_week","inc_number","time_sep",""
833 +"'-'","'.'","'/'","'+'","':'","'\\''","'h'","timespec","nowspec","now","time_or_not",
834 +"time","date","inc_or_dec","increment","decrement","inc_period","hr24clock_hr_min",
835 +"timezone_name","hr24clock_hour","minute","am_pm","month_name","month_number",
836 +"day_number","year_number","day_of_week","inc_number","time_sep", NULL
840 static const short yyr1[] = { 0,
841 - 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
842 - 49, 50, 50, 50, 50, 50, 50, 50, 50, 50,
843 + 47, 47, 47, 47, 47, 47, 48, 48, 49, 49,
844 50, 50, 51, 51, 51, 51, 51, 51, 51, 51,
845 - 51, 51, 51, 52, 52, 52, 53, 54, 54, 54,
846 - 54, 54, 54, 55, 56, 57, 58, 59, 59, 60,
847 - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
848 - 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
849 - 64, 65, 66, 66, 66, 66, 66
850 + 51, 51, 51, 52, 52, 52, 52, 52, 52, 52,
851 + 52, 52, 52, 52, 52, 53, 53, 54, 54, 54,
852 + 55, 56, 56, 56, 56, 56, 56, 57, 58, 59,
853 + 60, 61, 61, 62, 62, 62, 62, 62, 62, 62,
854 + 62, 62, 62, 62, 62, 63, 64, 65, 66, 66,
855 + 66, 66, 66, 66, 66, 67, 68, 68, 68, 68,
859 static const short yyr2[] = { 0,
860 - 1, 2, 2, 3, 2, 3, 1, 1, 2, 2,
861 - 1, 1, 2, 3, 4, 2, 3, 4, 5, 1,
862 - 1, 1, 2, 4, 1, 1, 1, 5, 5, 3,
863 - 2, 3, 5, 3, 2, 2, 3, 1, 1, 1,
864 + 1, 1, 2, 2, 3, 1, 1, 2, 1, 1,
865 + 1, 0, 1, 2, 3, 4, 2, 3, 4, 5,
866 + 1, 1, 1, 2, 3, 4, 1, 1, 1, 5,
867 + 5, 3, 2, 3, 5, 1, 1, 3, 2, 2,
868 + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
869 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
870 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
871 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
872 - 1, 1, 1, 1, 1, 1, 1
876 -static const short yydefact[] = { 0,
877 - 44, 11, 20, 21, 22, 7, 8, 1, 12, 0,
878 - 0, 0, 0, 9, 10, 63, 65, 66, 67, 68,
879 - 69, 70, 71, 26, 27, 50, 51, 52, 53, 54,
880 - 55, 56, 57, 58, 59, 60, 61, 2, 3, 5,
881 - 0, 0, 0, 0, 25, 45, 13, 48, 49, 77,
882 - 75, 73, 74, 76, 16, 0, 38, 39, 40, 41,
883 - 42, 43, 35, 36, 72, 0, 0, 4, 6, 63,
884 - 23, 0, 0, 31, 0, 17, 47, 14, 37, 34,
885 - 0, 0, 62, 30, 64, 32, 0, 15, 18, 24,
886 - 0, 0, 0, 19, 33, 29, 28, 0, 0, 0
887 +static const short yydefact[] = { 12,
888 + 48, 9, 21, 22, 23, 69, 70, 71, 72, 73,
889 + 74, 75, 28, 10, 54, 55, 56, 57, 58, 59,
890 + 60, 61, 62, 63, 64, 65, 6, 7, 0, 11,
891 + 1, 13, 0, 0, 0, 0, 0, 27, 0, 0,
892 + 0, 8, 36, 37, 67, 29, 0, 4, 3, 49,
893 + 14, 52, 53, 81, 79, 77, 78, 80, 17, 0,
894 + 67, 24, 0, 0, 33, 0, 42, 43, 44, 45,
895 + 46, 47, 39, 40, 76, 0, 0, 5, 18, 51,
896 + 15, 68, 0, 25, 0, 66, 32, 34, 0, 41,
897 + 38, 16, 19, 26, 0, 0, 0, 20, 35, 31,
901 -static const short yydefgoto[] = { 98,
902 - 6, 7, 8, 38, 14, 15, 63, 9, 47, 10,
903 - 78, 55, 41, 42, 43, 44, 45, 66, 56
904 +static const short yydefgoto[] = { 102,
905 + 27, 28, 29, 30, 31, 42, 43, 44, 73, 32,
906 + 51, 33, 81, 59, 34, 35, 36, 37, 38, 76,
910 -static const short yypact[] = { 8,
911 --32768,-32768,-32768,-32768,-32768,-32768, -14, 43, -4, 4,
912 - 80, 5, 5,-32768,-32768, -12,-32768,-32768,-32768,-32768,
913 +static const short yypact[] = { 114,
914 + -21,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
915 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
916 --32768,-32768,-32768,-32768,-32768,-32768,-32768, -14,-32768,-32768,
917 - 10, -6, 81, -8,-32768,-32768,-32768,-32768,-32768,-32768,
918 --32768,-32768,-32768,-32768, 9, 48,-32768,-32768,-32768,-32768,
919 --32768,-32768,-32768,-32768,-32768, -2, -2,-32768,-32768,-32768,
920 - 25, 10, 63, 64, 63,-32768,-32768, 1,-32768,-32768,
921 - 64, 26,-32768, 41,-32768,-32768, 44,-32768, 9,-32768,
922 - 64, 64, 10,-32768,-32768,-32768,-32768, 85, 87,-32768
923 +-32768,-32768,-32768,-32768,-32768,-32768,-32768, -13, 41, 79,
924 +-32768, -4, 4, 22, -14, 142, -8,-32768, 174, 33,
925 + 33,-32768,-32768,-32768, -18,-32768, -13,-32768,-32768,-32768,
926 +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 9, 58,
927 +-32768, 0, 22, 59, 61, 59,-32768,-32768,-32768,-32768,
928 +-32768,-32768,-32768,-32768,-32768, -5, -5,-32768,-32768,-32768,
929 + 8,-32768, 61,-32768, 23,-32768, 25,-32768, 40,-32768,
930 +-32768,-32768, 9,-32768, 61, 61, 22,-32768,-32768,-32768,
931 +-32768, 83, 85,-32768
934 static const short yypgoto[] = {-32768,
935 --32768,-32768,-32768,-32768, -5, 6, -42,-32768, -51,-32768,
936 --32768, 11, 54, -10, -41, 7, 95, 106,-32768
937 +-32768,-32768,-32768,-32768, -22, -24,-32768,-32768, -65,-32768,
938 + -55,-32768,-32768, 5, 51, -33, -34, 71, 49, 57,
947 -static const short yytable[] = { 71,
948 - -46, -46, 39, 76, 11, 48, 49, 65, 48, 49,
949 - 1, 2, 70, 40, 3, 4, 5, 57, 58, 59,
950 - 60, 61, 62, 79, 80, 12, 88, -64, 13, -62,
951 - 82, 75, 68, 46, -46, 72, -46, 94, 46, -46,
952 - -46, -46, 50, 69, 51, 16, 46, 52, 53, 54,
953 - 77, 97, 17, 18, 19, 20, 21, 22, 23, 24,
954 - 25, 11, 84, 81, 87, 83, 85, 91, 26, 27,
955 - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
956 - 86, 92, 12, 93, 99, 13, 100, 90, 89, 17,
957 - 18, 19, 20, 21, 22, 23, 74, 95, 96, 57,
958 - 58, 59, 60, 61, 62, 64, 26, 27, 28, 29,
959 - 30, 31, 32, 33, 34, 35, 36, 37, 67, 0,
961 +static const short yytable[] = { 62,
962 + -50, -50, 82, 79, 48, 39, 47, 49, 52, 53,
963 + 90, 91, 52, 53, 67, 68, 69, 70, 71, 72,
964 + -66, -68, 78, -66, 61, 92, 40, 63, 85, 41,
965 + 87, 66, 89, 50, -50, 75, -50, 98, 83, -50,
966 + -50, -50, 54, 45, 55, 50, 50, 56, 57, 58,
967 + 6, 7, 8, 9, 10, 11, 12, 13, 46, 39,
968 + 80, 86, 101, 82, 95, 96, 15, 16, 17, 18,
969 + 19, 20, 21, 22, 23, 24, 25, 26, -2, 97,
970 + 40, 45, 103, 41, 104, 93, 65, 74, 6, 7,
971 + 8, 9, 10, 11, 12, 13, 46, 77, 0, 0,
972 + 0, 0, 0, 0, 15, 16, 17, 18, 19, 20,
973 + 21, 22, 23, 24, 25, 26, 1, 2, 0, 0,
974 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
975 + 13, 14, 84, 0, 0, 88, 0, 0, 0, 15,
976 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
977 + 26, 0, 0, 94, 0, 0, 0, 0, 0, 0,
978 + 0, 0, 0, 0, 0, 99, 100, 15, 16, 17,
979 + 18, 19, 20, 21, 22, 23, 24, 25, 26, 0,
980 + 0, 0, 64, 6, 7, 8, 9, 10, 11, 12,
981 + 0, 0, 0, 67, 68, 69, 70, 71, 72
984 -static const short yycheck[] = { 41,
985 - 5, 6, 8, 55, 19, 5, 6, 3, 5, 6,
986 - 3, 4, 3, 8, 7, 8, 9, 20, 21, 22,
987 - 23, 24, 25, 66, 67, 40, 78, 40, 43, 42,
988 - 72, 40, 38, 38, 39, 42, 41, 89, 38, 44,
989 - 45, 46, 39, 38, 41, 3, 38, 44, 45, 46,
990 - 3, 93, 10, 11, 12, 13, 14, 15, 16, 17,
991 - 18, 19, 73, 39, 75, 3, 3, 42, 26, 27,
992 - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
993 - 74, 41, 40, 40, 0, 43, 0, 81, 78, 10,
994 - 11, 12, 13, 14, 15, 16, 43, 91, 92, 20,
995 - 21, 22, 23, 24, 25, 11, 26, 27, 28, 29,
996 - 30, 31, 32, 33, 34, 35, 36, 37, 13, -1,
998 +static const short yycheck[] = { 34,
999 + 5, 6, 3, 59, 29, 19, 29, 30, 5, 6,
1000 + 76, 77, 5, 6, 20, 21, 22, 23, 24, 25,
1001 + 42, 40, 47, 42, 3, 81, 40, 42, 63, 43,
1002 + 64, 40, 66, 38, 39, 3, 41, 93, 39, 44,
1003 + 45, 46, 39, 3, 41, 38, 38, 44, 45, 46,
1004 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1005 + 3, 3, 97, 3, 42, 41, 26, 27, 28, 29,
1006 + 30, 31, 32, 33, 34, 35, 36, 37, 0, 40,
1007 + 40, 3, 0, 43, 0, 81, 36, 39, 10, 11,
1008 + 12, 13, 14, 15, 16, 17, 18, 41, -1, -1,
1009 + -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
1010 + 32, 33, 34, 35, 36, 37, 3, 4, -1, -1,
1011 + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1012 + 17, 18, 62, -1, -1, 65, -1, -1, -1, 26,
1013 + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1014 + 37, -1, -1, 83, -1, -1, -1, -1, -1, -1,
1015 + -1, -1, -1, -1, -1, 95, 96, 26, 27, 28,
1016 + 29, 30, 31, 32, 33, 34, 35, 36, 37, -1,
1017 + -1, -1, 41, 10, 11, 12, 13, 14, 15, 16,
1018 + -1, -1, -1, 20, 21, 22, 23, 24, 25
1020 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
1021 -#line 3 "/usr/lib/bison.simple"
1022 +#line 3 "/usr/share/misc/bison.simple"
1023 +/* This file comes from bison-1.28. */
1025 /* Skeleton output parser for bison,
1026 - Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
1027 + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
1029 This program is free software; you can redistribute it and/or modify
1030 it under the terms of the GNU General Public License as published by
1031 - the Free Software Foundation; either version 1, or (at your option)
1032 + the Free Software Foundation; either version 2, or (at your option)
1035 This program is distributed in the hope that it will be useful,
1036 @@ -300,42 +313,66 @@
1038 You should have received a copy of the GNU General Public License
1039 along with this program; if not, write to the Free Software
1040 - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
1041 + Foundation, Inc., 59 Temple Place - Suite 330,
1042 + Boston, MA 02111-1307, USA. */
1044 +/* As a special exception, when this file is copied by Bison into a
1045 + Bison output file, you may use that output file without restriction.
1046 + This special exception was added by the Free Software Foundation
1047 + in version 1.24 of Bison. */
1050 +/* This is the parser code that is written into each bison parser
1051 + when the %semantic_parser declaration is not specified in the grammar.
1052 + It was written by Richard Stallman by simplifying the hairy parser
1053 + used when %semantic_parser is specified. */
1055 +#ifndef YYSTACK_USE_ALLOCA
1057 +#define YYSTACK_USE_ALLOCA
1058 +#else /* alloca not defined */
1060 +#define YYSTACK_USE_ALLOCA
1061 #define alloca __builtin_alloca
1062 #else /* not GNU C. */
1063 -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
1064 +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
1065 +#define YYSTACK_USE_ALLOCA
1067 #else /* not sparc */
1068 -#if defined (MSDOS) && !defined (__TURBOC__)
1069 +/* We think this test detects Watcom and Microsoft C. */
1070 +/* This used to test MSDOS, but that is a bad idea
1071 + since that symbol is in the user namespace. */
1072 +#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
1073 +#if 0 /* No need for malloc.h, which pollutes the namespace;
1074 + instead, just don't use alloca. */
1077 #else /* not MSDOS, or __TURBOC__ */
1079 -#include <malloc.h>
1080 +/* I don't know what this was needed for, but it pollutes the namespace.
1081 + So I turned it off. rms, 2 May 1997. */
1082 +/* #include <malloc.h> */
1084 -#else /* not MSDOS, __TURBOC__, or _AIX */
1088 -void *alloca (unsigned int);
1090 -#else /* not __cplusplus */
1092 -#endif /* not __cplusplus */
1093 +#define YYSTACK_USE_ALLOCA
1094 +#else /* not MSDOS, or __TURBOC__, or _AIX */
1096 +#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
1097 + and on HPUX 10. Eventually we can turn this on. */
1098 +#define YYSTACK_USE_ALLOCA
1099 +#define alloca __builtin_alloca
1102 #endif /* not _AIX */
1103 #endif /* not MSDOS, or __TURBOC__ */
1104 -#endif /* not sparc. */
1105 -#endif /* not GNU C. */
1106 -#endif /* alloca not defined. */
1107 +#endif /* not sparc */
1108 +#endif /* not GNU C */
1109 +#endif /* alloca not defined */
1110 +#endif /* YYSTACK_USE_ALLOCA not defined */
1112 -/* This is the parser code that is written into each bison parser
1113 - when the %semantic_parser declaration is not specified in the grammar.
1114 - It was written by Richard Stallman by simplifying the hairy parser
1115 - used when %semantic_parser is specified. */
1116 +#ifdef YYSTACK_USE_ALLOCA
1117 +#define YYSTACK_ALLOC alloca
1119 +#define YYSTACK_ALLOC malloc
1122 /* Note: there must be only one dollar sign in this file.
1123 It is replaced by the list of actions, each action
1125 #define yyclearin (yychar = YYEMPTY)
1128 -#define YYACCEPT return(0)
1129 -#define YYABORT return(1)
1130 +#define YYACCEPT goto yyacceptlab
1131 +#define YYABORT goto yyabortlab
1132 #define YYERROR goto yyerrlab1
1133 /* Like YYERROR except do call yyerror.
1134 This remains here temporarily to ease the
1135 @@ -375,10 +412,18 @@
1140 +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
1142 #define YYLEX yylex(&yylval, &yylloc)
1144 +#else /* not YYLSP_NEEDED */
1146 +#define YYLEX yylex(&yylval, YYLEX_PARAM)
1148 #define YYLEX yylex(&yylval)
1150 +#endif /* not YYLSP_NEEDED */
1153 /* If nonreentrant, generate the variables here */
1154 @@ -419,24 +464,24 @@
1156 #define YYMAXDEPTH 10000
1159 -/* Prevent warning if -Wstrict-prototypes. */
1161 -int yyparse (void);
1164 +/* Define __yy_memcpy. Note that the size argument
1165 + should be passed with type unsigned int, because that is what the non-GCC
1166 + definitions require. With GCC, __builtin_memcpy takes an arg
1167 + of type size_t, but it can handle unsigned int. */
1169 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
1170 -#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
1171 +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
1172 #else /* not GNU C or C++ */
1175 /* This is the most reliable way to avoid incompatibilities
1176 in available built-in functions on various systems. */
1178 -__yy_bcopy (from, to, count)
1180 +__yy_memcpy (to, from, count)
1184 + unsigned int count;
1186 register char *f = from;
1187 register char *t = to;
1188 @@ -451,10 +496,10 @@
1189 /* This is the most reliable way to avoid incompatibilities
1190 in available built-in functions on various systems. */
1192 -__yy_bcopy (char *from, char *to, int count)
1193 +__yy_memcpy (char *to, char *from, unsigned int count)
1195 - register char *f = from;
1196 register char *t = to;
1197 + register char *f = from;
1198 register int i = count;
1201 @@ -464,9 +509,39 @@
1205 -#line 184 "/usr/lib/bison.simple"
1206 +#line 217 "/usr/share/misc/bison.simple"
1208 +/* The user can define YYPARSE_PARAM as the name of an argument to be passed
1209 + into yyparse. The argument should have type void *.
1210 + It should actually point to an object.
1211 + Grammar actions can access the variable by casting it
1212 + to the proper pointer type. */
1214 +#ifdef YYPARSE_PARAM
1216 +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
1217 +#define YYPARSE_PARAM_DECL
1218 +#else /* not __cplusplus */
1219 +#define YYPARSE_PARAM_ARG YYPARSE_PARAM
1220 +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
1221 +#endif /* not __cplusplus */
1222 +#else /* not YYPARSE_PARAM */
1223 +#define YYPARSE_PARAM_ARG
1224 +#define YYPARSE_PARAM_DECL
1225 +#endif /* not YYPARSE_PARAM */
1227 +/* Prevent warning if -Wstrict-prototypes. */
1229 +#ifdef YYPARSE_PARAM
1230 +int yyparse (void *);
1232 +int yyparse (void);
1238 +yyparse(YYPARSE_PARAM_ARG)
1239 + YYPARSE_PARAM_DECL
1241 register int yystate;
1246 int yystacksize = YYINITDEPTH;
1247 + int yyfree_stacks = 0;
1251 @@ -576,18 +652,32 @@
1252 if (yystacksize >= YYMAXDEPTH)
1254 yyerror("parser stack overflow");
1255 + if (yyfree_stacks)
1259 +#ifdef YYLSP_NEEDED
1266 if (yystacksize > YYMAXDEPTH)
1267 yystacksize = YYMAXDEPTH;
1268 - yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
1269 - __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
1270 - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
1271 - __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
1272 +#ifndef YYSTACK_USE_ALLOCA
1273 + yyfree_stacks = 1;
1275 + yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
1276 + __yy_memcpy ((char *)yyss, (char *)yyss1,
1277 + size * (unsigned int) sizeof (*yyssp));
1278 + yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
1279 + __yy_memcpy ((char *)yyvs, (char *)yyvs1,
1280 + size * (unsigned int) sizeof (*yyvsp));
1282 - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
1283 - __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
1284 + yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
1285 + __yy_memcpy ((char *)yyls, (char *)yyls1,
1286 + size * (unsigned int) sizeof (*yylsp));
1288 #endif /* no yyoverflow */
1290 @@ -747,102 +837,154 @@
1295 -#line 40 "parsetime.y"
1297 +#line 44 "parsetime.y"
1303 -#line 68 "parsetime.y"
1305 +#line 59 "parsetime.y"
1311 +#line 76 "parsetime.y"
1313 exectm.tm_hour = 12;
1318 -#line 73 "parsetime.y"
1320 +#line 81 "parsetime.y"
1328 -#line 79 "parsetime.y"
1330 +#line 87 "parsetime.y"
1332 exectm.tm_hour = 16;
1337 -#line 88 "parsetime.y"
1339 +#line 97 "parsetime.y"
1341 - add_date ((7 + yyvsp[0].intval - exectm.tm_wday) %7 + 1, DAY);
1342 + add_date ((6 + yyvsp[0].intval - exectm.tm_wday) %7 + 1, DAY);
1346 -#line 93 "parsetime.y"
1348 +#line 102 "parsetime.y"
1354 -#line 105 "parsetime.y"
1356 +#line 117 "parsetime.y"
1358 add_date(yyvsp[-1].intval, yyvsp[0].intval);
1362 -#line 109 "parsetime.y"
1364 +#line 121 "parsetime.y"
1366 add_date(1, yyvsp[0].intval);
1370 -#line 113 "parsetime.y"
1372 +#line 125 "parsetime.y"
1374 add_date ((6 + yyvsp[0].intval - exectm.tm_wday) %7 +1, DAY);
1378 -#line 119 "parsetime.y"
1380 +#line 131 "parsetime.y"
1382 add_date(-yyvsp[-1].intval, yyvsp[0].intval);
1386 -#line 124 "parsetime.y"
1388 +#line 136 "parsetime.y"
1389 { yyval.intval = MINUTE ; ;
1392 -#line 125 "parsetime.y"
1394 +#line 137 "parsetime.y"
1395 { yyval.intval = HOUR ; ;
1398 -#line 126 "parsetime.y"
1400 +#line 138 "parsetime.y"
1401 { yyval.intval = DAY ; ;
1404 -#line 127 "parsetime.y"
1406 +#line 139 "parsetime.y"
1407 { yyval.intval = WEEK ; ;
1410 -#line 128 "parsetime.y"
1412 +#line 140 "parsetime.y"
1413 { yyval.intval = MONTH ; ;
1416 -#line 129 "parsetime.y"
1418 +#line 141 "parsetime.y"
1419 { yyval.intval = YEAR ; ;
1422 -#line 133 "parsetime.y"
1424 +#line 145 "parsetime.y"
1426 - exectm.tm_min = -1;
1427 - exectm.tm_hour = -1;
1428 if (strlen(yyvsp[0].charval) == 4) {
1429 + exectm.tm_min = -1;
1430 + exectm.tm_hour = -1;
1431 sscanf(yyvsp[0].charval, "%2d %2d", &exectm.tm_hour,
1433 + } else if (strlen(yyvsp[0].charval) >= 5 && strlen(yyvsp[0].charval) <= 8) {
1434 + /* Ok, this is a kluge. I hate design errors... -Joey */
1438 + onion=yyvsp[0].charval;
1439 + memset (shallot, 0, sizeof (shallot));
1440 + if (strlen(yyvsp[0].charval) == 5 || strlen(yyvsp[0].charval) == 7) {
1441 + strncpy (shallot,onion,1);
1444 + strncpy (shallot,onion,2);
1447 + sscanf(shallot, "%d", &exectm.tm_mon);
1449 + if (exectm.tm_mon < 1 || exectm.tm_mon > 12) {
1450 + yyerror("Error in month number");
1455 + memset (shallot, 0, sizeof (shallot));
1456 + strncpy (shallot,onion,2);
1457 + sscanf(shallot, "%d", &exectm.tm_mday);
1458 + if (exectm.tm_mday < 0 || exectm.tm_mday > 31)
1460 + yyerror("Error in day of month");
1465 + memset (shallot, 0, sizeof (shallot));
1466 + strncpy (shallot,onion,4);
1467 + if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) {
1468 + yyerror("Error in year");
1471 + if (exectm.tm_year < 70) {
1472 + exectm.tm_year += 100;
1474 + else if (exectm.tm_year > 1900) {
1475 + exectm.tm_year -= 1900;
1478 + free (yyvsp[0].charval);
1481 sscanf(yyvsp[0].charval, "%d", &exectm.tm_hour);
1482 @@ -855,13 +997,13 @@
1485 if (exectm.tm_hour > 24 || exectm.tm_hour < 0) {
1486 - yyerror("Problem in minutes specification");
1487 + yyerror("Problem in hours specification");
1493 -#line 158 "parsetime.y"
1495 +#line 216 "parsetime.y"
1497 if (strcasecmp(yyvsp[0].charval,"utc") == 0) {
1499 @@ -873,8 +1015,8 @@
1500 free(yyvsp[0].charval);
1504 -#line 174 "parsetime.y"
1506 +#line 232 "parsetime.y"
1508 if (sscanf(yyvsp[0].charval, "%d", &exectm.tm_min) != 1) {
1509 yyerror("Error in minute");
1510 @@ -883,8 +1025,20 @@
1511 free(yyvsp[0].charval);
1515 -#line 185 "parsetime.y"
1517 +#line 242 "parsetime.y"
1519 + if (exectm.tm_hour > 12) {
1520 + yyerror("Hour too large for AM");
1523 + else if (exectm.tm_hour == 12) {
1524 + exectm.tm_hour = 0;
1529 +#line 252 "parsetime.y"
1531 if (exectm.tm_hour > 12) {
1532 yyerror("Hour too large for PM");
1533 @@ -895,56 +1049,56 @@
1538 -#line 197 "parsetime.y"
1540 +#line 264 "parsetime.y"
1541 { exectm.tm_mon = 0; ;
1544 -#line 198 "parsetime.y"
1546 +#line 265 "parsetime.y"
1547 { exectm.tm_mon = 1; ;
1550 -#line 199 "parsetime.y"
1552 +#line 266 "parsetime.y"
1553 { exectm.tm_mon = 2; ;
1556 -#line 200 "parsetime.y"
1558 +#line 267 "parsetime.y"
1559 { exectm.tm_mon = 3; ;
1562 -#line 201 "parsetime.y"
1564 +#line 268 "parsetime.y"
1565 { exectm.tm_mon = 4; ;
1568 -#line 202 "parsetime.y"
1570 +#line 269 "parsetime.y"
1571 { exectm.tm_mon = 5; ;
1574 -#line 203 "parsetime.y"
1576 +#line 270 "parsetime.y"
1577 { exectm.tm_mon = 6; ;
1580 -#line 204 "parsetime.y"
1582 +#line 271 "parsetime.y"
1583 { exectm.tm_mon = 7; ;
1586 -#line 205 "parsetime.y"
1588 +#line 272 "parsetime.y"
1589 { exectm.tm_mon = 8; ;
1592 -#line 206 "parsetime.y"
1594 +#line 273 "parsetime.y"
1595 { exectm.tm_mon = 9; ;
1598 -#line 207 "parsetime.y"
1600 +#line 274 "parsetime.y"
1601 { exectm.tm_mon =10; ;
1604 -#line 208 "parsetime.y"
1606 +#line 275 "parsetime.y"
1607 { exectm.tm_mon =11; ;
1610 -#line 212 "parsetime.y"
1612 +#line 279 "parsetime.y"
1616 @@ -959,8 +1113,8 @@
1621 -#line 226 "parsetime.y"
1623 +#line 293 "parsetime.y"
1625 exectm.tm_mday = -1;
1626 sscanf(yyvsp[0].charval, "%d", &exectm.tm_mday);
1627 @@ -972,8 +1126,8 @@
1628 free(yyvsp[0].charval);
1632 -#line 239 "parsetime.y"
1634 +#line 306 "parsetime.y"
1638 @@ -994,36 +1148,36 @@
1643 -#line 261 "parsetime.y"
1645 +#line 328 "parsetime.y"
1646 { yyval.intval = 0; ;
1649 -#line 262 "parsetime.y"
1651 +#line 329 "parsetime.y"
1652 { yyval.intval = 1; ;
1655 -#line 263 "parsetime.y"
1657 +#line 330 "parsetime.y"
1658 { yyval.intval = 2; ;
1661 -#line 264 "parsetime.y"
1663 +#line 331 "parsetime.y"
1664 { yyval.intval = 3; ;
1667 -#line 265 "parsetime.y"
1669 +#line 332 "parsetime.y"
1670 { yyval.intval = 4; ;
1673 -#line 266 "parsetime.y"
1675 +#line 333 "parsetime.y"
1676 { yyval.intval = 5; ;
1679 -#line 267 "parsetime.y"
1681 +#line 334 "parsetime.y"
1682 { yyval.intval = 6; ;
1685 -#line 271 "parsetime.y"
1687 +#line 338 "parsetime.y"
1689 if (sscanf(yyvsp[0].charval, "%d", &yyval.intval) != 1) {
1690 yyerror("Unknown increment");
1691 @@ -1034,7 +1188,7 @@
1694 /* the action file gets copied in in place of this dollarsign */
1695 -#line 465 "/usr/lib/bison.simple"
1696 +#line 543 "/usr/share/misc/bison.simple"
1700 @@ -1229,8 +1383,32 @@
1706 + /* YYACCEPT comes here. */
1707 + if (yyfree_stacks)
1711 +#ifdef YYLSP_NEEDED
1718 + /* YYABORT comes here. */
1719 + if (yyfree_stacks)
1723 +#ifdef YYLSP_NEEDED
1729 -#line 287 "parsetime.y"
1730 +#line 354 "parsetime.y"
1734 @@ -1266,6 +1444,24 @@
1740 +Here are some lines to test:
1742 +./parsetest 7AM Mar 24 2000
1743 +./parsetest 7AM Mar 24 00
1744 +./parsetest 7AM 032400
1745 +./parsetest 7AM 03/24/00
1746 +./parsetest 7AM 24.03.00
1747 +./parsetest 7AM Mar 24
1749 +./parsetest 03242000
1750 +./parsetest noon 03242000
1752 +./parsetest 4pm + 3 days
1753 +./parsetest 10am Jul 31
1757 main(int argc, char **argv)
1759 --- at-3.1.8.orig/y.tab.h
1760 +++ at-3.1.8/y.tab.h
1770 -#define MIDNIGHT 263
1771 -#define TEATIME 264
1780 -#define TOMORROW 273
1806 +#define MIDNIGHT 262
1807 +#define TEATIME 263
1816 +#define TOMORROW 272
1839 extern YYSTYPE yylval;
1840 --- at-3.1.8.orig/lex.yy.c
1841 +++ at-3.1.8/lex.yy.c
1843 /* A lexical scanner generated by flex */
1845 /* Scanner skeleton version:
1850 #define FLEX_SCANNER
1853 /* Undo effects of setting up yytext. */ \
1854 *yy_cp = yy_hold_char; \
1855 + YY_RESTORE_YY_MORE_OFFSET \
1856 yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
1857 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
1860 #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
1862 YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
1863 -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str ));
1864 +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
1865 YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
1867 static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
1869 #define REJECT reject_used_but_not_detected
1870 #define yymore() yymore_used_but_not_detected
1871 #define YY_MORE_ADJ 0
1872 +#define YY_RESTORE_YY_MORE_OFFSET
1874 #line 1 "parsetime.l"
1880 -#line 495 "lex.yy.c"
1881 +#line 497 "lex.yy.c"
1883 /* Macros after this point can all be overridden by user definitions in
1885 @@ -513,6 +515,10 @@
1886 static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
1889 +#ifdef YY_NEED_STRLEN
1890 +static int yy_flex_strlen YY_PROTO(( yyconst char * ));
1895 static int yyinput YY_PROTO(( void ));
1897 #line 36 "parsetime.l"
1900 -#line 645 "lex.yy.c"
1901 +#line 651 "lex.yy.c"
1906 #line 77 "parsetime.l"
1909 -#line 923 "lex.yy.c"
1910 +#line 929 "lex.yy.c"
1911 case YY_STATE_EOF(INITIAL):
1916 /* Undo the effects of YY_DO_BEFORE_ACTION. */
1917 *yy_cp = yy_hold_char;
1918 + YY_RESTORE_YY_MORE_OFFSET
1920 if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
1922 @@ -1075,7 +1082,7 @@
1923 { /* Don't try to fill the buffer, so this is an EOF. */
1924 if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
1926 - /* We matched a singled characater, the EOB, so
1927 + /* We matched a single character, the EOB, so
1928 * treat this as a final EOF.
1930 return EOB_ACT_END_OF_FILE;
1931 @@ -1102,7 +1109,7 @@
1932 /* don't do the read, it's not guaranteed to return an EOF,
1936 + yy_current_buffer->yy_n_chars = yy_n_chars = 0;
1940 @@ -1157,6 +1164,8 @@
1941 /* Read in more data. */
1942 YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
1943 yy_n_chars, num_to_read );
1945 + yy_current_buffer->yy_n_chars = yy_n_chars;
1948 if ( yy_n_chars == 0 )
1949 @@ -1281,7 +1290,8 @@
1951 yy_cp += (int) (dest - source);
1952 yy_bp += (int) (dest - source);
1953 - yy_n_chars = yy_current_buffer->yy_buf_size;
1954 + yy_current_buffer->yy_n_chars =
1955 + yy_n_chars = yy_current_buffer->yy_buf_size;
1957 if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
1958 YY_FATAL_ERROR( "flex scanner push-back overflow" );
1959 @@ -1319,19 +1329,31 @@
1962 { /* need more input */
1963 - yytext_ptr = yy_c_buf_p;
1964 + int offset = yy_c_buf_p - yytext_ptr;
1967 switch ( yy_get_next_buffer() )
1969 + case EOB_ACT_LAST_MATCH:
1970 + /* This happens because yy_g_n_b()
1971 + * sees that we've accumulated a
1972 + * token and flags that we need to
1973 + * try matching the token before
1974 + * proceeding. But for input(),
1975 + * there's no matching to consider.
1976 + * So convert the EOB_ACT_LAST_MATCH
1977 + * to EOB_ACT_END_OF_FILE.
1980 + /* Reset buffer status. */
1981 + yyrestart( yyin );
1983 + /* fall through */
1985 case EOB_ACT_END_OF_FILE:
1990 - yytext_ptr + YY_MORE_ADJ;
1994 if ( ! yy_did_buffer_switch_on_eof )
1996 @@ -1343,17 +1365,8 @@
1999 case EOB_ACT_CONTINUE_SCAN:
2000 - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
2001 + yy_c_buf_p = yytext_ptr + offset;
2004 - case EOB_ACT_LAST_MATCH:
2007 - "unexpected last match in yyinput()" );
2010 - "unexpected last match in input()" );
2015 @@ -1517,6 +1530,9 @@
2024 /* We always need two end-of-buffer characters. The first causes
2025 @@ -1576,17 +1592,17 @@
2027 #ifndef YY_NO_SCAN_STRING
2028 #ifdef YY_USE_PROTOS
2029 -YY_BUFFER_STATE yy_scan_string( yyconst char *str )
2030 +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
2032 -YY_BUFFER_STATE yy_scan_string( str )
2034 +YY_BUFFER_STATE yy_scan_string( yy_str )
2035 +yyconst char *yy_str;
2039 - for ( len = 0; str[len]; ++len )
2040 + for ( len = 0; yy_str[len]; ++len )
2043 - return yy_scan_bytes( str, len );
2044 + return yy_scan_bytes( yy_str, len );
2048 @@ -1707,7 +1723,7 @@
2050 /* Undo effects of setting up yytext. */ \
2051 yytext[yyleng] = yy_hold_char; \
2052 - yy_c_buf_p = yytext + n - YY_MORE_ADJ; \
2053 + yy_c_buf_p = yytext + n; \
2054 yy_hold_char = *yy_c_buf_p; \
2055 *yy_c_buf_p = '\0'; \
2057 @@ -1730,6 +1746,22 @@
2059 for ( i = 0; i < n; ++i )
2064 +#ifdef YY_NEED_STRLEN
2065 +#ifdef YY_USE_PROTOS
2066 +static int yy_flex_strlen( yyconst char *s )
2068 +static int yy_flex_strlen( s )
2073 + for ( n = 0; s[n]; ++n )
2080 --- at-3.1.8.orig/Makefile.in
2081 +++ at-3.1.8/Makefile.in
2085 rm -f subs.sed *.o *.s at atd core a.out *~ $(CLONES) *.bak stamp-built
2089 rm -rf at.1 atd.8 atrun.8 config.cache atrun config.h \
2092 Filelist.asc: Filelist
2095 +parsetest: lex.yy.c y.tab.c
2096 + $(CC) -o parsetest $(CFLAGS) $(DEFS) -DTEST_PARSER -DNEED_YYWRAP lex.yy.c y.tab.c
2099 gcc $(CFLAGS) $(DEFS) -MM $(CSRCS) > .depend
2100 --- at-3.1.8.orig/parsetime.y
2101 +++ at-3.1.8/parsetime.y
2104 static int time_only;
2106 +extern int yyerror(char *s);
2107 +extern int yylex();
2109 int add_date(int number, int period);
2124 - | time date increment
2126 - | time date decrement
2127 + | time_or_not inc_or_dec
2128 + | time_or_not date inc_or_dec
2148 time : hr24clock_hr_min
2149 | hr24clock_hr_min timezone_name
2150 | hr24clock_hour time_sep minute
2154 date : month_name day_number
2155 + | month_name day_number year_number
2156 | month_name day_number ',' year_number
2159 - add_date ((7 + $1 - exectm.tm_wday) %7 + 1, DAY);
2160 + add_date ((6 + $1 - exectm.tm_wday) %7 + 1, DAY);
2165 | month_number '/' day_number '/' year_number
2168 +inc_or_dec : increment
2171 increment : '+' inc_number inc_period
2174 @@ -131,11 +143,57 @@
2176 hr24clock_hr_min: INT
2178 - exectm.tm_min = -1;
2179 - exectm.tm_hour = -1;
2180 if (strlen($1) == 4) {
2181 + exectm.tm_min = -1;
2182 + exectm.tm_hour = -1;
2183 sscanf($1, "%2d %2d", &exectm.tm_hour,
2185 + } else if (strlen($1) >= 5 && strlen($1) <= 8) {
2186 + /* Ok, this is a kluge. I hate design errors... -Joey */
2191 + memset (shallot, 0, sizeof (shallot));
2192 + if (strlen($1) == 5 || strlen($1) == 7) {
2193 + strncpy (shallot,onion,1);
2196 + strncpy (shallot,onion,2);
2199 + sscanf(shallot, "%d", &exectm.tm_mon);
2201 + if (exectm.tm_mon < 1 || exectm.tm_mon > 12) {
2202 + yyerror("Error in month number");
2207 + memset (shallot, 0, sizeof (shallot));
2208 + strncpy (shallot,onion,2);
2209 + sscanf(shallot, "%d", &exectm.tm_mday);
2210 + if (exectm.tm_mday < 0 || exectm.tm_mday > 31)
2212 + yyerror("Error in day of month");
2217 + memset (shallot, 0, sizeof (shallot));
2218 + strncpy (shallot,onion,4);
2219 + if ( sscanf(shallot, "%d", &exectm.tm_year) != 1) {
2220 + yyerror("Error in year");
2223 + if (exectm.tm_year < 70) {
2224 + exectm.tm_year += 100;
2226 + else if (exectm.tm_year > 1900) {
2227 + exectm.tm_year -= 1900;
2233 sscanf($1, "%d", &exectm.tm_hour);
2237 if (exectm.tm_hour > 24 || exectm.tm_hour < 0) {
2238 - yyerror("Problem in minutes specification");
2239 + yyerror("Problem in hours specification");
2243 @@ -181,6 +239,15 @@
2248 + if (exectm.tm_hour > 12) {
2249 + yyerror("Hour too large for AM");
2252 + else if (exectm.tm_hour == 12) {
2253 + exectm.tm_hour = 0;
2258 if (exectm.tm_hour > 12) {
2259 @@ -319,6 +386,24 @@
2265 +Here are some lines to test:
2267 +./parsetest 7AM Mar 24 2000
2268 +./parsetest 7AM Mar 24 00
2269 +./parsetest 7AM 032400
2270 +./parsetest 7AM 03/24/00
2271 +./parsetest 7AM 24.03.00
2272 +./parsetest 7AM Mar 24
2274 +./parsetest 03242000
2275 +./parsetest noon 03242000
2277 +./parsetest 4pm + 3 days
2278 +./parsetest 10am Jul 31
2282 main(int argc, char **argv)