/* utime -- set the file modification time of the given file
 * according to the time given; a time of 0 means the current
 * time.
 *
 * stime -- set the current time to the value given.
 *
 * All times are in Unix format, i.e. seconds since to
 * midnight, January 1, 1970 GMT
 *
 * written by Eric R. Smith, and placed in the public domain.
 *
 */

#include <limits.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <osbind.h>
#include <assert.h>
#include "lib.h"

/* convert a Unix time into a DOS time. The longword returned contains
   the time word first, then the date word */

time_t dostime(t)
	time_t t;
{
        time_t time, date;
	struct tm *ctm;

	if (!(ctm = localtime(&t)))
		return 0;
	time = (ctm->tm_hour << 11) | (ctm->tm_min << 5) | (ctm->tm_sec >> 1);
	date = ((ctm->tm_year - 80) & 0x7f) << 9;
	date |= ((ctm->tm_mon+1) << 5) | (ctm->tm_mday);
	return (time << 16) | date;
}

int
utime(_filename, tset)
      const char *_filename;
      const struct utimbuf *tset;
{
	int fh;
	time_t settime;
	unsigned long dtime;	/* dos time equivalent */
	char filename[PATH_MAX];

	if (tset)
		settime = tset->modtime;
	else
		time(&settime);

	(void)_unx2dos(_filename, filename);
	dtime = dostime(settime);	/* convert unix time to dos */
	fh = Fopen(filename, 2);
	if (fh < 0) {
		errno = -fh;
		return -1;
	}
	(void)Fdatime(&dtime, fh, 1);
	if (fh = Fclose(fh)) {
		errno = -fh;
		return -1;
	}
	return 0;
}

int stime(t)
	time_t *t;
{
	unsigned long dtime;
	unsigned date, time;
	int r;

	assert(t != 0);
	dtime = dostime(*t);
	date = (dtime & 0xffff);
	time = (dtime >> 16) & 0xffff;

	if ((r = Tsetdate(date)) || (r = Tsettime(time))) {
		errno = -r;
		return -1;
	}
	return 0;
}
