Hi,

I implement this command for grub4dos some time ago, now it's ported to grub2.

Usage:

  checktime min hour day_of_month month day_of_week

The five parameters for checktime is the same as in crontab: minute,
hour, day, month and day of week. This command check if the current
daytime is within the range specified by the parameters, and return
true or false accordingly. Combined this with the script support for
grub2, you can perform some operation in a selected time range.

The range of the five parameters are:
minute: 0-59
hour: 0-23
day of month: 1-31
month 1-12
day of week 0-6 (0 is Sunday)

checktime * 12-15 * 1,3-5 *
Return true on afternoon of Jan, March, April and May.

checktime * * * */2 *
Return true on Month 1,3,5,7,9,11

For example, you can use a different background image according to the
current season:

if checktime * * * 3-5 *; then
  background_image /spring.png
fi

if checktime * * * 6-8 *; then
  background_image /summer.png
fi

if checktime * * * 9-11 *; then
  background_image /fall.png
fi

if checktime * * * 1-2,12 *; then
  background_image /winter.png
fi

Or boot a different item in the morning, afternoon and evening.

2008-08-06  Bean  <[EMAIL PROTECTED]>

        * conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/time.h.
        (pkglib_MODULES): Add chktime.mod.
        (chktime_mod_SOURCES): New macro.
        (chktime_mod_CFLAGS): Likewise.
        (chktime_mod_LDFLAGS): Likewise.

        * include/grub/i386/pc/time.h: Add function grub_get_datetime.

        * kern/i386/pc/startup.S: Add function grub_get_datetime.

        * commands/i386/pc/checktime.c: New file.

-- 
Bean
diff --git a/commands/i386/pc/checktime.c b/commands/i386/pc/checktime.c
new file mode 100644
index 0000000..a9d015c
--- /dev/null
+++ b/commands/i386/pc/checktime.c
@@ -0,0 +1,165 @@
+/* checktime.c - command to test current date/time.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/machine/time.h>
+
+static int
+grub_cmd_checktime (struct grub_arg_list *state __attribute__ ((unused)),
+                    int argc, char **args)
+{
+  grub_uint32_t date, time;
+  int day, month, year, sec, min, hour, dow, i;
+  int limit[5][2] = {{0, 59}, {0, 23}, {1, 31}, {1, 12}, {0, 7}};
+  int field[5];
+
+  auto int get_day_of_week (void);
+  int get_day_of_week (void)
+    {
+      int a, y, m;
+
+      a = (14 - month) / 12;
+      y = year - a;
+      m = month + 12 * a - 2;
+      return (day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
+    }
+
+  grub_get_datetime (&date, &time);
+
+  day = ((date >> 4) & 0xF) * 10 + (date & 0xF);
+  date >>= 8;
+
+  month = ((date >> 4) & 0xF) * 10 + (date & 0xF);
+  date >>= 8;
+
+  year = ((date >> 4) & 0xF) * 10 + (date & 0xF);
+  date >>= 8;
+  year += (((date >> 4) & 0xF) * 10 + (date & 0xF)) * 100;
+
+  time >>= 8;
+
+  sec = ((time >> 4) & 0xF) * 10 + (time & 0xF);
+  time >>= 8;
+
+  min = ((time >> 4) & 0xF) * 10 + (time & 0xF);
+  time >>= 8;
+
+  hour = ((time >> 4) & 0xF) * 10 + (time & 0xF);
+
+  dow = get_day_of_week ();
+
+  field[0] = min;
+  field[1] = hour;
+  field[2] = day;
+  field[3] = month;
+  field[4] = dow;
+
+  if (argc == 0)
+    {
+      grub_printf ("%d-%02d-%02d %02d:%02d:%02d %d\n",
+                   year, month, day, hour, min, sec, dow);
+
+      return 0;
+    }
+
+  for (i = 0; i < 5; i++)
+    {
+      char *p;
+      int ok = 0;
+
+      if (i >= argc)
+        return 0;
+
+      p = args[i];
+      while (1)
+        {
+          int m1, m2, m3, j;
+
+          if (*p == '*')
+            {
+              m1 = limit[i][0];
+              m2 = limit[i][1];
+              p++;
+            }
+          else
+            {
+              m1 = grub_strtoul (p, &p, 0);
+
+              if (*p == '-')
+                {
+                  p++;
+                  m2 = grub_strtoul (p, &p, 0);
+                }
+              else
+                m2 = m1;
+            }
+
+          if ((m1 < limit[i][0]) || (m2 > limit[i][1]) || (m1 > m2))
+            break;
+
+          if (*p == '/')
+            {
+              p++;
+              m3 = grub_strtoul (p, &p, 0);
+            }
+          else
+            m3 = 1;
+
+          for (j = m1; j <= m2; j+= m3)
+            {
+              if (j == field[i])
+                {
+                  ok = 1;
+                  break;
+                }
+            }
+
+          if (ok)
+            break;
+
+          if (*p == ',')
+            p++;
+          else
+            break;
+        }
+
+      if (! ok)
+        break;
+    }
+
+  return (i == 5) ? 0 : grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+GRUB_MOD_INIT(checktime)
+{
+  (void) mod;			/* To stop warning. */
+  grub_register_command ("checktime", grub_cmd_checktime,
+                         GRUB_COMMAND_FLAG_BOTH,
+			 "checktime min hour day_of_month month day_of_week",
+                         "Command to test current date/time.", 0);
+}
+
+GRUB_MOD_FINI(checktime)
+{
+  grub_unregister_command ("checktime");
+}
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index c1e4ac4..b9c8f35 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -55,7 +55,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
 	partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
 	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
 	machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
-	machine/kernel.h machine/pxe.h
+	machine/kernel.h machine/pxe.h machine/time.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -163,7 +163,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
 	vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
 	videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod	\
 	ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod \
-	aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod
+	aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod chktime.mod
 
 # For biosdisk.mod.
 biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -340,4 +340,9 @@ pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
 pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
 pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For chktime.mod
+chktime_mod_SOURCES = commands/i386/pc/checktime.c
+chktime_mod_CFLAGS = $(COMMON_CFLAGS)
+chktime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 include $(srcdir)/conf/common.mk
diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h
index 98399b6..f41cc1d 100644
--- a/include/grub/i386/pc/time.h
+++ b/include/grub/i386/pc/time.h
@@ -26,4 +26,6 @@
 /* Return the real time in ticks.  */
 grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
 
+void EXPORT_FUNC(grub_get_datetime) (grub_uint32_t *date, grub_uint32_t *time);
+
 #endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S
index 197c447..0aecedd 100644
--- a/kern/i386/pc/startup.S
+++ b/kern/i386/pc/startup.S
@@ -2153,3 +2153,57 @@ FUNCTION(grub_pxe_call)
 	popl	%esi
 	popl	%ebp
 	ret
+
+/*
+ *  void grub_get_datetime (grub_uint32_t *date,
+ *                          grub_uint32_t *time);
+ */
+FUNCTION(grub_get_datetime)
+	pushl	%ebp
+	pushl	%ebx
+
+	pushl	%eax
+	pushl	%edx
+
+	call	prot_to_real
+	.code16
+
+	movb	$2, %ah
+	clc
+	int	$0x1a
+	jc	2f
+
+	pushw	%cx
+	pushw	%dx
+
+	movb	$4, %ah
+	clc
+	int	$0x1a
+	jc	3f
+
+	pushw	%cx
+	pushw	%dx
+	popl	%edx
+	popl	%ecx
+	jmp	1f
+
+3:
+	popl	%eax
+
+2:
+	xorl	%ecx, %ecx
+	xorl	%edx, %edx
+
+1:
+	DATA32  call	real_to_prot
+	.code32
+
+	popl	%eax
+	movl	%ecx, (%eax)
+
+	popl	%eax
+	movl	%edx, (%eax)
+
+	popl	%ebx
+	popl	%ebp
+	ret
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to