Hello, I'd like to send a patch that adds support for pretty printing of current RTC's alarms. The thing it actually does is convert RTC time to local time. To do this (pseudocode): rtc=get rtc alarm's time from rtc dev; time_diff= (-timezone+daylight*3600); -where timezone and daylight are extern constants from time.h; now just add the time_diff to time_t representation of rtc, make *localtime(&rtc) and print result with ctime(). Please see/test if the thing with time_diff= (-timezone+daylight*3600) is correct. (works for me, timezone GMT+1, daylight:+1). Thank you. Change log: Support for 'show' action/mode (rtcwake -m <mode>) * show: print information on current alarms Signed-off-by: Marek Otahal <markotahal@xxxxxxxxx> Regards, Marek Patch: --- ../../util-linux-ng/sys-utils/rtcwake.c 2010-04-23 15:09:35.018363727 +0200 +++ rtcwake.c 2010-05-11 11:33:42.476897796 +0200 @@ -61,8 +61,8 @@ CM_LOCAL }; -static unsigned verbose; -static unsigned dryrun; +static unsigned verbose = 0; +static unsigned dryrun = 0; enum ClockMode clock_mode = CM_AUTO; static struct option long_options[] = { @@ -297,6 +297,72 @@ return 0; } +/** + * print basic alarm settings + */ +static int print_alarm_info(int fd) +{ + struct rtc_wkalrm wake; + + /* First try the preferred RTC_WKALM_RD */ + if (!dryrun && ioctl(fd, RTC_WKALM_RD, &wake) < 0) { + /* Fall back on the non-preferred way of reading wakeups; only + * works for alarms < 24 hours from now */ + wake.enabled=1; // set this to 1 and determine from value of the year -1 means disabled + if (ioctl(fd, RTC_ALM_READ, &wake.time) < 0) { + perror(_("read rtc alarm\n")); + return -1; + } + } + + if (verbose) + printf(_("alarm: status(on/off) [time(hh:mm:ss) date(yyyy-mm- dd)]\n")); + + // seconds from UTC to local time representation + int time_diff = (-timezone+daylight*3600); + + struct rtc_time rtc = wake.time; + struct tm tm; + time_t rtc_t; + + if (wake.enabled!=1 || wake.time.tm_year==-1) { // alarm is not set + printf(_("alarm: off\n")); + return 0; + } + + memset(&tm, 0, sizeof tm); + tm.tm_sec = rtc.tm_sec; + tm.tm_min = rtc.tm_min; + tm.tm_hour = rtc.tm_hour; + tm.tm_mday = rtc.tm_mday; + tm.tm_mon = rtc.tm_mon; + tm.tm_year = rtc.tm_year; + tm.tm_isdst = -1; /* assume the system knows better than the RTC */ + + rtc_t = mktime(&tm); + if (rtc_t == (time_t)-1) { + perror(_("convert time failed.\n")); + return -1; + } + rtc_t+=time_diff; + + // handle over/under-flows in hours + tm=*localtime(&rtc_t); + rtc.tm_sec = tm.tm_sec; + rtc.tm_min = tm.tm_min; + rtc.tm_hour = tm.tm_hour; + rtc.tm_mday = tm.tm_mday; + rtc.tm_mon = tm.tm_mon; + rtc.tm_year = tm.tm_year; + rtc.tm_isdst = -1; + wake.time=rtc; + + printf(_("alarm: on %02d:%02d:%02d %d-%02d-%02d\n"), + wake.time.tm_hour,wake.time.tm_min,wake.time.tm_sec, + wake.time.tm_year + 1900, wake.time.tm_mon + 1, wake.time.tm_mday); + return 0; +} + int main(int argc, char **argv) { char *devname = DEFAULT_DEVICE; @@ -345,6 +411,7 @@ || strcmp(optarg, "no") == 0 || strcmp(optarg, "off") == 0 || strcmp(optarg, "disable") == 0 + || strcmp(optarg, "show") == 0 ) { suspend = strdup(optarg); break; @@ -404,6 +471,9 @@ } } + if (strcmp(suspend, "show") == 0) { + clock_mode = CM_LOCAL; + } if (clock_mode == CM_AUTO) { if (read_clock_mode() < 0) { printf(_("%s: assuming RTC uses UTC ...\n"), progname); @@ -414,7 +484,7 @@ printf(clock_mode == CM_UTC ? _("Using UTC time.\n") : _("Using local time.\n")); - if (!alarm && !seconds && strcmp(suspend,"disable")) { + if (!alarm && !seconds && strcmp(suspend,"disable") && strcmp(suspend,"show")) { fprintf(stderr, _("%s: must provide wake time\n"), progname); usage(EXIT_FAILURE); } @@ -470,7 +540,7 @@ } else alarm = rtc_time + seconds + 1; - if (setup_alarm(fd, &alarm) < 0) + if (strcmp(suspend,"show")!=0 && setup_alarm(fd, &alarm) < 0) exit(EXIT_FAILURE); printf(_("%s: wakeup from \"%s\" using %s at %s\n"), @@ -482,8 +552,7 @@ if (strcmp(suspend, "no") == 0) { if (verbose) printf(_("suspend mode: no; leaving\n")); - close(fd); - exit(EXIT_SUCCESS); + dryrun=1; // to skip disabling alarm at the end } else if (strcmp(suspend, "off") == 0) { char *arg[4]; @@ -527,6 +596,14 @@ /* just break, alarm gets disabled in the end */ if (verbose) printf(_("suspend mode: disable; disabling alarm\n")); + + } else if(strcmp(suspend,"show") == 0) { + if (verbose) + printf(_("suspend mode: show; printing alarm info\n")); + if(print_alarm_info(fd) != 0) + rc = EXIT_FAILURE; + dryrun = 1; // don't really disable alarm in the end + } else { if (verbose) printf(_("suspend mode: %s; suspending system\n"), suspend); -- Marek Otahal :o)
--- ../../util-linux-ng/sys-utils/rtcwake.c 2010-04-23 15:09:35.018363727 +0200 +++ rtcwake.c 2010-05-11 11:33:42.476897796 +0200 @@ -61,8 +61,8 @@ CM_LOCAL }; -static unsigned verbose; -static unsigned dryrun; +static unsigned verbose = 0; +static unsigned dryrun = 0; enum ClockMode clock_mode = CM_AUTO; static struct option long_options[] = { @@ -297,6 +297,72 @@ return 0; } +/** + * print basic alarm settings + */ +static int print_alarm_info(int fd) +{ + struct rtc_wkalrm wake; + + /* First try the preferred RTC_WKALM_RD */ + if (!dryrun && ioctl(fd, RTC_WKALM_RD, &wake) < 0) { + /* Fall back on the non-preferred way of reading wakeups; only + * works for alarms < 24 hours from now */ + wake.enabled=1; // set this to 1 and determine from value of the year -1 means disabled + if (ioctl(fd, RTC_ALM_READ, &wake.time) < 0) { + perror(_("read rtc alarm\n")); + return -1; + } + } + + if (verbose) + printf(_("alarm: status(on/off) [time(hh:mm:ss) date(yyyy-mm-dd)]\n")); + + // seconds from UTC to local time representation + int time_diff = (-timezone+daylight*3600); + + struct rtc_time rtc = wake.time; + struct tm tm; + time_t rtc_t; + + if (wake.enabled!=1 || wake.time.tm_year==-1) { // alarm is not set + printf(_("alarm: off\n")); + return 0; + } + + memset(&tm, 0, sizeof tm); + tm.tm_sec = rtc.tm_sec; + tm.tm_min = rtc.tm_min; + tm.tm_hour = rtc.tm_hour; + tm.tm_mday = rtc.tm_mday; + tm.tm_mon = rtc.tm_mon; + tm.tm_year = rtc.tm_year; + tm.tm_isdst = -1; /* assume the system knows better than the RTC */ + + rtc_t = mktime(&tm); + if (rtc_t == (time_t)-1) { + perror(_("convert time failed.\n")); + return -1; + } + rtc_t+=time_diff; + + // handle over/under-flows in hours + tm=*localtime(&rtc_t); + rtc.tm_sec = tm.tm_sec; + rtc.tm_min = tm.tm_min; + rtc.tm_hour = tm.tm_hour; + rtc.tm_mday = tm.tm_mday; + rtc.tm_mon = tm.tm_mon; + rtc.tm_year = tm.tm_year; + rtc.tm_isdst = -1; + wake.time=rtc; + + printf(_("alarm: on %02d:%02d:%02d %d-%02d-%02d\n"), + wake.time.tm_hour,wake.time.tm_min,wake.time.tm_sec, + wake.time.tm_year + 1900, wake.time.tm_mon + 1, wake.time.tm_mday); + return 0; +} + int main(int argc, char **argv) { char *devname = DEFAULT_DEVICE; @@ -345,6 +411,7 @@ || strcmp(optarg, "no") == 0 || strcmp(optarg, "off") == 0 || strcmp(optarg, "disable") == 0 + || strcmp(optarg, "show") == 0 ) { suspend = strdup(optarg); break; @@ -404,6 +471,9 @@ } } + if (strcmp(suspend, "show") == 0) { + clock_mode = CM_LOCAL; + } if (clock_mode == CM_AUTO) { if (read_clock_mode() < 0) { printf(_("%s: assuming RTC uses UTC ...\n"), progname); @@ -414,7 +484,7 @@ printf(clock_mode == CM_UTC ? _("Using UTC time.\n") : _("Using local time.\n")); - if (!alarm && !seconds && strcmp(suspend,"disable")) { + if (!alarm && !seconds && strcmp(suspend,"disable") && strcmp(suspend,"show")) { fprintf(stderr, _("%s: must provide wake time\n"), progname); usage(EXIT_FAILURE); } @@ -470,7 +540,7 @@ } else alarm = rtc_time + seconds + 1; - if (setup_alarm(fd, &alarm) < 0) + if (strcmp(suspend,"show")!=0 && setup_alarm(fd, &alarm) < 0) exit(EXIT_FAILURE); printf(_("%s: wakeup from \"%s\" using %s at %s\n"), @@ -482,8 +552,7 @@ if (strcmp(suspend, "no") == 0) { if (verbose) printf(_("suspend mode: no; leaving\n")); - close(fd); - exit(EXIT_SUCCESS); + dryrun=1; // to skip disabling alarm at the end } else if (strcmp(suspend, "off") == 0) { char *arg[4]; @@ -527,6 +596,14 @@ /* just break, alarm gets disabled in the end */ if (verbose) printf(_("suspend mode: disable; disabling alarm\n")); + + } else if(strcmp(suspend,"show") == 0) { + if (verbose) + printf(_("suspend mode: show; printing alarm info\n")); + if(print_alarm_info(fd) != 0) + rc = EXIT_FAILURE; + dryrun = 1; // don't really disable alarm in the end + } else { if (verbose) printf(_("suspend mode: %s; suspending system\n"), suspend);