/* 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 "busybox.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>
#include <getopt.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) {
		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 */

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)) {
					usage(date_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))
					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];
	} 
#if 0
	else {
		error_msg("date_str='%s'  date_fmt='%s'\n", date_str, date_fmt);
		usage(date_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);
	printf("%s\n", t_buff);

	return EXIT_SUCCESS;
}
