Index: stage2/builtins.c =================================================================== --- stage2/builtins.c (revision 57) +++ stage2/builtins.c (working copy) @@ -2908,6 +2908,146 @@ #endif /* SUPPORT_GRAPHICS */ +#ifndef GRUB_UTIL +/* checktime */ +static int +checktime_func(char *arg, int flags) +{ + unsigned long date,time; + int day, month, year, sec, min, hour, dow, ii; + 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; + } + + 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 (! arg[0]) + { + grub_printf ("%d-%02d-%02d %02d:%02d:%02d %d\n", year, month, day, hour, min, sec, dow); + return 1; + } + + for (ii = 0; ii < 5; ii++) + { + char *p; + int ok = 0; + + if (! arg[0]) + break; + + p = arg; + while (1) + { + int m1, m2, m3, j; + + if (*p == '*') + { + m1 = limit[ii][0]; + m2 = limit[ii][1]; + p++; + } + else + { + if (! safe_parse_maxint (&p, &m1)) + return 0; + + if (*p == '-') + { + p++; + if (! safe_parse_maxint (&p, &m2)) + return 0; + } + else + m2 = m1; + } + + if ((m1 < limit[ii][0]) || (m2 > limit[ii][1]) || (m1 > m2)) + return 0; + + if (*p == '/') + { + p++; + if (! safe_parse_maxint (&p, &m3)) + return 0; + } + else + m3 = 1; + + for (j = m1; j <= m2; j+= m3) + { + if (j == field[ii]) + { + ok = 1; + break; + } + } + + if (ok) + break; + + if (*p == ',') + p++; + else + break; + } + + if (! ok) + break; + + arg = skip_to (0, arg); + } + + return (ii == 5); +} + +static struct builtin builtin_checktime = +{ + "checktime", + checktime_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "checktime min hour dom month dow", + "Check time." +}; +#endif + /* clear */ static int clear_func() @@ -10180,6 +10320,9 @@ &builtin_cdrom, #endif &builtin_chainloader, +#ifndef GRUB_UTIL + &builtin_checktime, +#endif &builtin_clear, &builtin_cmp, &builtin_color, Index: stage2/asm.S =================================================================== --- stage2/asm.S (revision 57) +++ stage2/asm.S (working copy) @@ -9959,6 +9959,54 @@ ret +/* + * void get_datetime(unsigned long *date, unsigned long *time); + */ +ENTRY(get_datetime) + pushl %ebp + call EXT_C(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 EXT_C(real_to_prot) + .code32 + + movl %esp, %ebp + movl 8(%ebp), %eax + movl %edx, (%eax) + movl 12(%ebp), %eax + movl %ecx, (%eax) + + popl %ebp + ret + #if 0 /* This BIOS call should NOT be called since it will clear the byte at 0040:0070. */ Index: stage2/shared.h =================================================================== --- stage2/shared.h (revision 57) +++ stage2/shared.h (working copy) @@ -909,6 +909,10 @@ /* low-level timing info */ int getrtsecs (void); + +/* Get current date and time */ +void get_datetime(unsigned long *date, unsigned long *time); + #ifdef GRUB_UTIL int currticks (void); #else