stime.c revision 1.3
11.3Sagc/*	$NetBSD: stime.c,v 1.3 2003/08/07 11:13:08 agc Exp $	*/
21.1Skleink
31.1Skleink/*
41.1Skleink * Copyright (c) 1993
51.1Skleink *	The Regents of the University of California.  All rights reserved.
61.1Skleink *
71.1Skleink * Redistribution and use in source and binary forms, with or without
81.1Skleink * modification, are permitted provided that the following conditions
91.1Skleink * are met:
101.1Skleink * 1. Redistributions of source code must retain the above copyright
111.1Skleink *    notice, this list of conditions and the following disclaimer.
121.1Skleink * 2. Redistributions in binary form must reproduce the above copyright
131.1Skleink *    notice, this list of conditions and the following disclaimer in the
141.1Skleink *    documentation and/or other materials provided with the distribution.
151.3Sagc * 3. Neither the name of the University nor the names of its contributors
161.1Skleink *    may be used to endorse or promote products derived from this software
171.1Skleink *    without specific prior written permission.
181.1Skleink *
191.1Skleink * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
201.1Skleink * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
211.1Skleink * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
221.1Skleink * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
231.1Skleink * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
241.1Skleink * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
251.1Skleink * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
261.1Skleink * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
271.1Skleink * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
281.1Skleink * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
291.1Skleink * SUCH DAMAGE.
301.1Skleink */
311.1Skleink
321.1Skleink#include <sys/cdefs.h>
331.1Skleink#ifndef lint
341.1Skleink__COPYRIGHT("@(#) Copyright (c) 1993\n\
351.1Skleink	The Regents of the University of California.  All rights reserved.\n");
361.1Skleink#endif /* not lint */
371.1Skleink
381.1Skleink#ifndef lint
391.1Skleink#if 0
401.1Skleinkstatic char sccsid[] = "from: @(#)touch.c	8.2 (Berkeley) 4/28/95";
411.1Skleink#endif
421.3Sagc__RCSID("$NetBSD: stime.c,v 1.3 2003/08/07 11:13:08 agc Exp $");
431.1Skleink#endif /* not lint */
441.1Skleink
451.1Skleink
461.1Skleink#include <err.h>
471.1Skleink#include <string.h>
481.1Skleink#include <time.h>
491.1Skleink#include <tzfile.h>
501.1Skleink
511.1Skleink#include "stime.h"
521.1Skleink
531.1Skleink#define	ATOI2(s)	((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
541.1Skleink
551.1Skleinktime_t
561.1Skleinkstime(arg)
571.1Skleink	char *arg;
581.1Skleink{
591.1Skleink	struct tm *t;
601.1Skleink	time_t tmptime;
611.1Skleink	int yearset;
621.1Skleink	char *p;
631.1Skleink					/* Start with the current time. */
641.1Skleink	if (time(&tmptime) == (time_t)-1)
651.1Skleink		err(1, "time");
661.1Skleink
671.1Skleink	if ((t = localtime(&tmptime)) == NULL)
681.1Skleink		err(1, "localtime");
691.1Skleink					/* [[CC]YY]MMDDhhmm[.SS] */
701.1Skleink	if ((p = strchr(arg, '.')) == NULL)
711.1Skleink		t->tm_sec = 0;		/* Seconds defaults to 0. */
721.1Skleink	else {
731.1Skleink		if (strlen(p + 1) != 2)
741.1Skleink			goto terr;
751.1Skleink		*p++ = '\0';
761.1Skleink		t->tm_sec = ATOI2(p);
771.1Skleink	}
781.1Skleink
791.1Skleink	yearset = 0;
801.1Skleink	switch (strlen(arg)) {
811.1Skleink	case 12:			/* CCYYMMDDhhmm */
821.1Skleink		t->tm_year = ATOI2(arg) * 100 - TM_YEAR_BASE;
831.1Skleink		yearset = 1;
841.1Skleink		/* FALLTHOUGH */
851.1Skleink	case 10:			/* YYMMDDhhmm */
861.1Skleink		if (yearset) {
871.1Skleink			t->tm_year += ATOI2(arg);
881.1Skleink		} else {
891.1Skleink			yearset = ATOI2(arg);
901.1Skleink			if (yearset < 69)
911.1Skleink				t->tm_year = yearset + 2000 - TM_YEAR_BASE;
921.1Skleink			else
931.1Skleink				t->tm_year = yearset + 1900 - TM_YEAR_BASE;
941.1Skleink		}
951.1Skleink		/* FALLTHROUGH */
961.1Skleink	case 8:				/* MMDDhhmm */
971.1Skleink		t->tm_mon = ATOI2(arg);
981.1Skleink		--t->tm_mon;		/* Convert from 01-12 to 00-11 */
991.1Skleink		/* FALLTHROUGH */
1001.1Skleink	case 6:
1011.1Skleink		t->tm_mday = ATOI2(arg);
1021.1Skleink		/* FALLTHROUGH */
1031.1Skleink	case 4:
1041.1Skleink		t->tm_hour = ATOI2(arg);
1051.1Skleink		/* FALLTHROUGH */
1061.1Skleink	case 2:
1071.1Skleink		t->tm_min = ATOI2(arg);
1081.1Skleink		break;
1091.1Skleink	default:
1101.1Skleink		goto terr;
1111.1Skleink	}
1121.1Skleink
1131.1Skleink	t->tm_isdst = -1;		/* Figure out DST. */
1141.1Skleink	tmptime = mktime(t);
1151.1Skleink	if (tmptime == (time_t)-1)
1161.1Skleinkterr:		errx(1,
1171.1Skleink	"out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]");
1181.1Skleink
1191.1Skleink	return (tmptime);
1201.1Skleink}
121