/* 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 "internal.h"
#define BB_DECLARE_EXTERN
#define bb_need_invalid_date
#define bb_need_memory_exhausted
#include "messages.c"
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <time.h>
#include <stdio.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 */

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) {
		fatalError(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 */

struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)
{
	struct tm itm_time, jtm_time, ktm_time, ltm_time, mtm_time, ntm_time;

	itm_time = *tm_time;
	jtm_time = *tm_time;
	ktm_time = *tm_time;
	ltm_time = *tm_time;
	mtm_time = *tm_time;
	ntm_time = *tm_time;

	/* Parse input and assign appropriately to tm_time */

	if (sscanf(t_string, "%d:%d:%d",
			   &itm_time.tm_hour, &itm_time.tm_min, &itm_time.tm_sec) == 3) {

		*tm_time = itm_time;
		return (tm_time);

	} else if (sscanf(t_string, "%d:%d",
					  &jtm_time.tm_hour, &jtm_time.tm_min) == 2) {

		*tm_time = jtm_time;
		return (tm_time);

	} else if (sscanf(t_string, "%d.%d-%d:%d:%d",
					  &ktm_time.tm_mon,
					  &ktm_time.tm_mday,
					  &ktm_time.tm_hour,
					  &ktm_time.tm_min, &ktm_time.tm_sec) == 5) {

		ktm_time.tm_mon -= 1;	/* Adjust dates from 1-12 to 0-11 */
		*tm_time = ktm_time;
		return (tm_time);

	} else if (sscanf(t_string, "%d.%d-%d:%d",
					  &ltm_time.tm_mon,
					  &ltm_time.tm_mday,
					  &ltm_time.tm_hour, &ltm_time.tm_min) == 4) {

		ltm_time.tm_mon -= 1;	/* Adjust dates from 1-12 to 0-11 */
		*tm_time = ltm_time;
		return (tm_time);

	} else if (sscanf(t_string, "%d.%d.%d-%d:%d:%d",
					  &mtm_time.tm_year,
					  &mtm_time.tm_mon,
					  &mtm_time.tm_mday,
					  &mtm_time.tm_hour,
					  &mtm_time.tm_min, &mtm_time.tm_sec) == 6) {

		mtm_time.tm_year -= 1900;	/* Adjust years */
		mtm_time.tm_mon -= 1;	/* Adjust dates from 1-12 to 0-11 */
		*tm_time = mtm_time;
		return (tm_time);

	} else if (sscanf(t_string, "%d.%d.%d-%d:%d",
					  &ntm_time.tm_year,
					  &ntm_time.tm_mon,
					  &ntm_time.tm_mday,
					  &ntm_time.tm_hour, &ntm_time.tm_min) == 5) {
		ntm_time.tm_year -= 1900;	/* Adjust years */
		ntm_time.tm_mon -= 1;	/* Adjust dates from 1-12 to 0-11 */
		*tm_time = ntm_time;
		return (tm_time);

	}

	fatalError(invalid_date, t_string); 
}


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))
				usage(date_usage);
			break;
		case 'u':
			utc = 1;
			if (putenv("TZ=UTC0") != 0) 
				fatalError(memory_exhausted);
			break;
		case 'd':
			use_arg = 1;
			if ((date_str != NULL) || ((date_str = optarg) == NULL))
				usage(date_usage);
			break;
		default:
			usage(date_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];
	} else {
		usage(date_usage);
	}

	/* 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)
			fatalError(invalid_date, date_str); 

		/* if setting time, set it */
		if (set_time) {
			if (stime(&tm) < 0) {
				fatalError("can't set date.\n");
			}
		}
	}

	/* 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");
		exit(TRUE);
	}

	/* 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);
	printf("%s\n", t_buff);

	return(TRUE);
}
