diff options
Diffstat (limited to 'date.c')
-rw-r--r-- | date.c | 247 |
1 files changed, 0 insertions, 247 deletions
@@ -1,247 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Mini date implementation for busybox - * - * by Matthew Grant <grantma@anathoth.gen.nz> - * - * 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 2 of the License, or - * (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ - -#include <stdlib.h> -#include <errno.h> -#include <sys/time.h> -#include <unistd.h> -#include <time.h> -#include <stdio.h> -#include <string.h> -#include <getopt.h> -#include "busybox.h" - - -/* This 'date' command supports only 2 time setting formats, - all the GNU strftime stuff (its in libc, lets use it), - setting time using UTC and displaying int, as well as - an RFC 822 complient date output for shell scripting - mail commands */ - -/* Input parsing code is always bulky - used heavy duty libc stuff as - much as possible, missed out a lot of bounds checking */ - -/* Default input handling to save suprising some people */ - -static struct tm *date_conv_time(struct tm *tm_time, const char *t_string) -{ - int nr; - - nr = sscanf(t_string, "%2d%2d%2d%2d%d", - &(tm_time->tm_mon), - &(tm_time->tm_mday), - &(tm_time->tm_hour), - &(tm_time->tm_min), &(tm_time->tm_year)); - - if (nr < 4 || nr > 5) { - error_msg_and_die(invalid_date, t_string); - } - - /* correct for century - minor Y2K problem here? */ - if (tm_time->tm_year >= 1900) - tm_time->tm_year -= 1900; - /* adjust date */ - tm_time->tm_mon -= 1; - - return (tm_time); - -} - - -/* The new stuff for LRP */ - -static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string) -{ - struct tm t; - - /* Parse input and assign appropriately to tm_time */ - - if (t=*tm_time,sscanf(t_string, "%d:%d:%d", - &t.tm_hour, &t.tm_min, &t.tm_sec) == 3) { - /* no adjustments needed */ - - } else if (t=*tm_time,sscanf(t_string, "%d:%d", - &t.tm_hour, &t.tm_min) == 2) { - /* no adjustments needed */ - - - } else if (t=*tm_time,sscanf(t_string, "%d.%d-%d:%d:%d", - &t.tm_mon, - &t.tm_mday, - &t.tm_hour, - &t.tm_min, &t.tm_sec) == 5) { - - t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ - - } else if (t=*tm_time,sscanf(t_string, "%d.%d-%d:%d", - &t.tm_mon, - &t.tm_mday, - &t.tm_hour, &t.tm_min) == 4) { - - t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ - - } else if (t=*tm_time,sscanf(t_string, "%d.%d.%d-%d:%d:%d", - &t.tm_year, - &t.tm_mon, - &t.tm_mday, - &t.tm_hour, - &t.tm_min, &t.tm_sec) == 6) { - - t.tm_year -= 1900; /* Adjust years */ - t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ - - } else if (t=*tm_time,sscanf(t_string, "%d.%d.%d-%d:%d", - &t.tm_year, - &t.tm_mon, - &t.tm_mday, - &t.tm_hour, &t.tm_min) == 5) { - t.tm_year -= 1900; /* Adjust years */ - t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ - - } else { - error_msg_and_die(invalid_date, t_string); - } - *tm_time = t; - return (tm_time); -} - - -int date_main(int argc, char **argv) -{ - char *date_str = NULL; - char *date_fmt = NULL; - char *t_buff; - int c; - int set_time = 0; - int rfc822 = 0; - int utc = 0; - int use_arg = 0; - time_t tm; - struct tm tm_time; - - /* Interpret command line args */ - while ((c = getopt(argc, argv, "Rs:ud:")) != EOF) { - switch (c) { - case 'R': - rfc822 = 1; - break; - case 's': - set_time = 1; - if ((date_str != NULL) || ((date_str = optarg) == NULL)) { - show_usage(); - } - break; - case 'u': - utc = 1; - if (putenv("TZ=UTC0") != 0) - error_msg_and_die(memory_exhausted); - break; - case 'd': - use_arg = 1; - if ((date_str != NULL) || ((date_str = optarg) == NULL)) - show_usage(); - break; - default: - show_usage(); - } - } - - if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) - date_fmt = &argv[optind][1]; /* Skip over the '+' */ - else if (date_str == NULL) { - set_time = 1; - date_str = argv[optind]; - } -#if 0 - else { - error_msg("date_str='%s' date_fmt='%s'\n", date_str, date_fmt); - show_usage(); - } -#endif - - /* Now we have parsed all the information except the date format - which depends on whether the clock is being set or read */ - - time(&tm); - memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); - /* Zero out fields - take her back to midnight! */ - if (date_str != NULL) { - tm_time.tm_sec = 0; - tm_time.tm_min = 0; - tm_time.tm_hour = 0; - } - - /* Process any date input to UNIX time since 1 Jan 1970 */ - if (date_str != NULL) { - - if (strchr(date_str, ':') != NULL) { - date_conv_ftime(&tm_time, date_str); - } else { - date_conv_time(&tm_time, date_str); - } - - /* Correct any day of week and day of year etc. fields */ - tm = mktime(&tm_time); - if (tm < 0) - error_msg_and_die(invalid_date, date_str); - if ( utc ) { - if (putenv("TZ=UTC0") != 0) - error_msg_and_die(memory_exhausted); - } - - /* if setting time, set it */ - if (set_time) { - if (stime(&tm) < 0) { - perror_msg("cannot set date"); - } - } - } - - /* Display output */ - - /* Deal with format string */ - if (date_fmt == NULL) { - date_fmt = (rfc822 - ? (utc - ? "%a, %_d %b %Y %H:%M:%S GMT" - : "%a, %_d %b %Y %H:%M:%S %z") - : "%a %b %e %H:%M:%S %Z %Y"); - - } else if (*date_fmt == '\0') { - /* Imitate what GNU 'date' does with NO format string! */ - printf("\n"); - return EXIT_SUCCESS; - } - - /* Handle special conversions */ - - if (strncmp(date_fmt, "%f", 2) == 0) { - date_fmt = "%Y.%m.%d-%H:%M:%S"; - } - - /* Print OUTPUT (after ALL that!) */ - t_buff = xmalloc(201); - strftime(t_buff, 200, date_fmt, &tm_time); - puts(t_buff); - - return EXIT_SUCCESS; -} |