/* 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 <string.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;
}
