Module Name:    othersrc
Committed By:   simonb
Date:           Thu Feb 25 07:03:57 UTC 2021

Added Files:
        othersrc/usr.bin/sleepto: Makefile parsetime.c parsetime.h sleepto.c
            tzfile.h

Log Message:
Jared's sleepto command from Dec 2007 - sleep to an at(1) style time
specification.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 othersrc/usr.bin/sleepto/Makefile \
    othersrc/usr.bin/sleepto/parsetime.c othersrc/usr.bin/sleepto/parsetime.h \
    othersrc/usr.bin/sleepto/sleepto.c othersrc/usr.bin/sleepto/tzfile.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: othersrc/usr.bin/sleepto/Makefile
diff -u /dev/null othersrc/usr.bin/sleepto/Makefile:1.1
--- /dev/null	Thu Feb 25 07:03:57 2021
+++ othersrc/usr.bin/sleepto/Makefile	Thu Feb 25 07:03:57 2021
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1 2021/02/25 07:03:57 simonb Exp $
+
+PROG=	sleepto
+SRCS=	sleepto.c parsetime.c
+NOMAN=	# defined
+WARNS?=	4
+
+.include <bsd.prog.mk>
Index: othersrc/usr.bin/sleepto/parsetime.c
diff -u /dev/null othersrc/usr.bin/sleepto/parsetime.c:1.1
--- /dev/null	Thu Feb 25 07:03:57 2021
+++ othersrc/usr.bin/sleepto/parsetime.c	Thu Feb 25 07:03:57 2021
@@ -0,0 +1,673 @@
+/*	$NetBSD: parsetime.c,v 1.1 2021/02/25 07:03:57 simonb Exp $	*/
+
+/* 
+ * parsetime.c - parse time for at(1)
+ * Copyright (C) 1993, 1994  Thomas Koenig
+ *
+ * modifications for english-language times
+ * Copyright (C) 1993  David Parsons
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author(s) may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  at [NOW] PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS
+ *     /NUMBER [DOT NUMBER] [AM|PM]\ /[MONTH NUMBER [NUMBER]]             \
+ *     |NOON                       | |[TOMORROW]                          |
+ *     |MIDNIGHT                   | |[DAY OF WEEK]                       |
+ *     \TEATIME                    / |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
+ *                                   \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
+ */
+
+/* System Headers */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+
+#include "parsetime.h"
+
+/* Structures and unions */
+
+enum {	/* symbols */
+	MIDNIGHT, NOON, TEATIME,
+	PM, AM, TOMORROW, TODAY, NOW,
+	MINUTES, HOURS, DAYS, WEEKS,
+	NUMBER, PLUS, DOT, SLASH, ID, JUNK,
+	JAN, FEB, MAR, APR, MAY, JUN,
+	JUL, AUG, SEP, OCT, NOV, DEC,
+	SUN, MON, TUE, WED, THU, FRI, SAT
+};
+
+/*
+ * parse translation table - table driven parsers can be your FRIEND!
+ */
+struct {
+	const char *name;	/* token name */
+	int value;		/* token id */
+	int plural;		/* is this plural? */
+} Specials[] = {
+	{ "midnight", MIDNIGHT, 0 },	/* 00:00:00 of today or tomorrow */
+	{ "noon", NOON, 0 },		/* 12:00:00 of today or tomorrow */
+	{ "teatime", TEATIME, 0 },	/* 16:00:00 of today or tomorrow */
+	{ "am", AM, 0 },		/* morning times for 0-12 clock */
+	{ "pm", PM, 0 },		/* evening times for 0-12 clock */
+	{ "tomorrow", TOMORROW, 0 },	/* execute 24 hours from time */
+	{ "today", TODAY, 0 },		/* execute today - don't advance time */
+	{ "now", NOW, 0 },		/* opt prefix for PLUS */
+
+	{ "minute", MINUTES, 0 },	/* minutes multiplier */
+	{ "min", MINUTES, 0 },
+	{ "m", MINUTES, 0 },
+	{ "minutes", MINUTES, 1 },	/* (pluralized) */
+	{ "hour", HOURS, 0 },		/* hours ... */
+	{ "hr", HOURS, 0 },		/* abbreviated */
+	{ "h", HOURS, 0 },
+	{ "hours", HOURS, 1 },		/* (pluralized) */
+	{ "day", DAYS, 0 },		/* days ... */
+	{ "d", DAYS, 0 },
+	{ "days", DAYS, 1 },		/* (pluralized) */
+	{ "week", WEEKS, 0 },		/* week ... */
+	{ "w", WEEKS, 0 },
+	{ "weeks", WEEKS, 1 },		/* (pluralized) */
+	{ "jan", JAN, 0 },
+	{ "feb", FEB, 0 },
+	{ "mar", MAR, 0 },
+	{ "apr", APR, 0 },
+	{ "may", MAY, 0 },
+	{ "jun", JUN, 0 },
+	{ "jul", JUL, 0 },
+	{ "aug", AUG, 0 },
+	{ "sep", SEP, 0 },
+	{ "oct", OCT, 0 },
+	{ "nov", NOV, 0 },
+	{ "dec", DEC, 0 },
+	{ "sunday", SUN, 0 },
+	{ "sun", SUN, 0 },
+	{ "monday", MON, 0 },
+	{ "mon", MON, 0 },
+	{ "tuesday", TUE, 0 },
+	{ "tue", TUE, 0 },
+	{ "wednesday", WED, 0 },
+	{ "wed", WED, 0 },
+	{ "thursday", THU, 0 },
+	{ "thu", THU, 0 },
+	{ "friday", FRI, 0 },
+	{ "fri", FRI, 0 },
+	{ "saturday", SAT, 0 },
+	{ "sat", SAT, 0 },
+};
+
+/* File scope variables */
+
+static char **scp;	/* scanner - pointer at arglist */
+static char scc;	/* scanner - count of remaining arguments */
+static char *sct;	/* scanner - next char pointer in current argument */
+static int need;	/* scanner - need to advance to next argument */
+
+static char *sc_token;	/* scanner - token buffer */
+static size_t sc_len;   /* scanner - length of token buffer */
+static int sc_tokid;	/* scanner - token id */
+static int sc_tokplur;	/* scanner - is token plural? */
+
+#ifndef lint
+#if 0
+static char rcsid[] = "$OpenBSD: parsetime.c,v 1.4 1997/03/01 23:40:10 millert Exp $";
+#else
+__RCSID("$NetBSD: parsetime.c,v 1.1 2021/02/25 07:03:57 simonb Exp $");
+#endif
+#endif
+
+/* Local functions */
+static void	assign_date (struct tm *, long, long, long);
+static void	dateadd (int, struct tm *);
+static void	expect (int);
+static void	init_scanner (int, char **);
+static void	month (struct tm *);
+static int	parse_token (char *);
+static void	plonk (int);
+static void	plus (struct tm *);
+static void	tod (struct tm *);
+static int	token (void);
+static void	panic (const char *);
+
+static void
+panic(const char *s)
+{
+	(void)fprintf(stderr, "FATAL: %s\n", s);
+	exit (EXIT_FAILURE);
+}
+
+/*
+ * parse a token, checking if it's something special to us
+ */
+static int
+parse_token(char *arg)
+{
+	int i;
+
+	for (i=0; i < sizeof(Specials) / sizeof(Specials[0]); i++) {
+		if (strcasecmp(Specials[i].name, arg) == 0) {
+			sc_tokplur = Specials[i].plural;
+		    	return (sc_tokid = Specials[i].value);
+		}
+	}
+
+	/* not special - must be some random id */
+	return (ID);
+} /* parse_token */
+
+
+/*
+ * init_scanner() sets up the scanner to eat arguments
+ */
+static void
+init_scanner(int argc, char **argv)
+{
+	scp = argv;
+	scc = argc;
+	need = 1;
+	sc_len = 1;
+	while (argc-- > 0)
+		sc_len += strlen(*argv++);
+
+	if ((sc_token = (char *) malloc(sc_len)) == NULL)
+		panic("Insufficient virtual memory");
+} /* init_scanner */
+
+/*
+ * token() fetches a token from the input stream
+ */
+static int
+token(void)
+{
+	int idx;
+
+	while (1) {
+		(void)memset(sc_token, 0, sc_len);
+		sc_tokid = EOF;
+		sc_tokplur = 0;
+		idx = 0;
+
+		/*
+		 * if we need to read another argument, walk along the
+		 * argument list; when we fall off the arglist, we'll
+		 * just return EOF forever
+		 */
+		if (need) {
+			if (scc < 1)
+				return (sc_tokid);
+			sct = *scp;
+			scp++;
+			scc--;
+			need = 0;
+		}
+		/*
+		 * eat whitespace now - if we walk off the end of the argument,
+		 * we'll continue, which puts us up at the top of the while loop
+		 * to fetch the next argument in
+		 */
+		while (isspace((unsigned char)*sct))
+			++sct;
+		if (!*sct) {
+			need = 1;
+			continue;
+		}
+
+		/*
+		 * preserve the first character of the new token
+		 */
+		sc_token[0] = *sct++;
+
+		/*
+		 * then see what it is
+		 */
+		if (isdigit((unsigned char)sc_token[0])) {
+			while (isdigit((unsigned char)*sct))
+				sc_token[++idx] = *sct++;
+			sc_token[++idx] = 0;
+			return ((sc_tokid = NUMBER));
+		} else if (isalpha((unsigned char)sc_token[0])) {
+			while (isalpha((unsigned char)*sct))
+				sc_token[++idx] = *sct++;
+			sc_token[++idx] = 0;
+			return (parse_token(sc_token));
+		}
+		else if (sc_token[0] == ':' || sc_token[0] == '.')
+			return ((sc_tokid = DOT));
+		else if (sc_token[0] == '+')
+			return ((sc_tokid = PLUS));
+		else if (sc_token[0] == '/')
+			return ((sc_tokid = SLASH));
+		else
+			return ((sc_tokid = JUNK));
+	} /* while (1) */
+} /* token */
+
+
+/*
+ * plonk() gives an appropriate error message if a token is incorrect
+ */
+static void
+plonk(int tok)
+{
+	panic((tok == EOF) ? "incomplete time" : "garbled time");
+} /* plonk */
+
+
+/* 
+ * expect() gets a token and dies most horribly if it's not the token we want
+ */
+static void
+expect(int desired)
+{
+	if (token() != desired)
+		plonk(sc_tokid);	/* and we die here... */
+} /* expect */
+
+
+/*
+ * dateadd() adds a number of minutes to a date.  It is extraordinarily
+ * stupid regarding day-of-month overflow, and will most likely not
+ * work properly
+ */
+static void
+dateadd(int minutes, struct tm *tm)
+{
+	/* increment days */
+
+	while (minutes > 24*60) {
+		minutes -= 24*60;
+		tm->tm_mday++;
+	}
+
+	/* increment hours */
+	while (minutes > 60) {
+		minutes -= 60;
+		tm->tm_hour++;
+		if (tm->tm_hour > 23) {
+			tm->tm_mday++;
+			tm->tm_hour = 0;
+		}
+	}
+
+	/* increment minutes */
+	tm->tm_min += minutes;
+
+	if (tm->tm_min > 59) {
+		tm->tm_hour++;
+		tm->tm_min -= 60;
+
+		if (tm->tm_hour > 23) {
+			tm->tm_mday++;
+			tm->tm_hour = 0;
+		}
+	}
+} /* dateadd */
+
+
+/*
+ * plus() parses a now + time
+ *
+ *  at [NOW] PLUS NUMBER [MINUTES|HOURS|DAYS|WEEKS]
+ *
+ */
+static void
+plus(struct tm *tm)
+{
+	int delay;
+	int expectplur;
+
+	expect(NUMBER);
+
+	delay = atoi(sc_token);
+	expectplur = (delay != 1) ? 1 : 0;
+
+	switch (token()) {
+	case WEEKS:
+		delay *= 7;
+	case DAYS:
+		delay *= 24;
+	case HOURS:
+		delay *= 60;
+	case MINUTES:
+		if (expectplur != sc_tokplur)
+			(void)fprintf(stderr, "at: pluralization is wrong\n");
+		dateadd(delay, tm);
+		return;
+	}
+
+	plonk(sc_tokid);
+} /* plus */
+
+
+/*
+ * tod() computes the time of day
+ *     [NUMBER [DOT NUMBER] [AM|PM]]
+ */
+static void
+tod(struct tm *tm)
+{
+	int hour, minute = 0;
+	size_t tlen;
+
+	hour = atoi(sc_token);
+	tlen = strlen(sc_token);
+
+	/*
+	 * first pick out the time of day - if it's 4 digits, we assume
+	 * a HHMM time, otherwise it's HH DOT MM time
+	 */
+	if (token() == DOT) {
+		expect(NUMBER);
+		minute = atoi(sc_token);
+		token();
+	} else if (tlen == 4) {
+		minute = hour % 100;
+		hour = hour / 100;
+	}
+
+	if (minute > 59)
+		panic("garbled time");
+
+	/*
+	 * check if an AM or PM specifier was given
+	 */
+	if (sc_tokid == AM || sc_tokid == PM) {
+		if (hour > 12)
+			panic("garbled time");
+
+		if (sc_tokid == PM) {
+			if (hour != 12)	/* 12:xx PM is 12:xx, not 24:xx */
+				hour += 12;
+		} else {
+			if (hour == 12)	/* 12:xx AM is 00:xx, not 12:xx */
+				hour = 0;
+		}
+		token();
+	} else if (hour > 23)
+		panic("garbled time");
+
+	/*
+	 * if we specify an absolute time, we don't want to bump the day even
+	 * if we've gone past that time - but if we're specifying a time plus
+	 * a relative offset, it's okay to bump things
+	 */
+	if ((sc_tokid == EOF || sc_tokid == PLUS) && tm->tm_hour > hour) {
+		tm->tm_mday++;
+		tm->tm_wday++;
+	}
+
+	tm->tm_hour = hour;
+	tm->tm_min = minute;
+} /* tod */
+
+
+/*
+ * assign_date() assigns a date, wrapping to next year if needed
+ */
+static void
+assign_date(struct tm *tm, long mday, long mon, long year)
+{
+	if (year > 99) {
+	    if (year >= TM_YEAR_BASE)
+		    year -= TM_YEAR_BASE;
+	    else
+		    panic("garbled time");
+	}
+
+	if (year >= 0) {
+		if (year < 70)
+			tm->tm_year = year + 2000 - TM_YEAR_BASE;
+		else
+			tm->tm_year = year + 1900 - TM_YEAR_BASE;
+	}
+	else { /* year < 0 */
+		if (tm->tm_mon > mon ||
+		    (tm->tm_mon == mon && tm->tm_mday > mday))
+			tm->tm_year++;
+	}
+
+	tm->tm_mday = mday;
+	tm->tm_mon = mon;
+} /* assign_date */
+
+
+/* 
+ * month() picks apart a month specification
+ *
+ *  /[<month> NUMBER [NUMBER]]           \
+ *  |[TOMORROW]                          |
+ *  |[DAY OF WEEK]                       |
+ *  |NUMBER [SLASH NUMBER [SLASH NUMBER]]|
+ *  \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/
+ */
+static void
+month(struct tm *tm)
+{
+	int year = (-1);
+	int mday, wday, mon;
+	size_t tlen;
+
+	mday = 0;
+	switch (sc_tokid) {
+	case PLUS:
+		plus(tm);
+		break;
+
+	case TOMORROW:
+		/* do something tomorrow */
+		tm->tm_mday++;
+		tm->tm_wday++;
+	case TODAY:
+		/* force ourselves to stay in today - no further processing */
+		token();
+		break;
+
+	case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
+	case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
+		/*
+		 * do month mday [year]
+		 */
+		mon = sc_tokid - JAN;
+		expect(NUMBER);
+		mday = atoi(sc_token);
+		if (token() == NUMBER) {
+			year = atoi(sc_token);
+			token();
+		}
+		assign_date(tm, mday, mon, year);
+		break;
+
+	case SUN: case MON: case TUE:
+	case WED: case THU: case FRI:
+	case SAT:
+		/* do a particular day of the week */
+		wday = sc_tokid - SUN;
+
+		mday = tm->tm_mday;
+
+		/* if this day is < today, then roll to next week */
+		if (wday < tm->tm_wday)
+			mday += 7 - (tm->tm_wday - wday);
+		else
+			mday += (wday - tm->tm_wday);
+
+		tm->tm_wday = wday;
+
+		assign_date(tm, mday, tm->tm_mon, tm->tm_year + TM_YEAR_BASE);
+		break;
+
+	case NUMBER:
+		/*
+		 * get numeric MMDDYY, mm/dd/yy, or dd.mm.yy
+		 */
+		tlen = strlen(sc_token);
+		mon = atoi(sc_token);
+		token();
+
+		if (sc_tokid == SLASH || sc_tokid == DOT) {
+			int sep;
+
+			sep = sc_tokid;
+			expect(NUMBER);
+			mday = atoi(sc_token);
+			if (token() == sep) {
+				expect(NUMBER);
+				year = atoi(sc_token);
+				token();
+			}
+
+			/*
+			 * flip months and days for european timing
+			 */
+			if (sep == DOT) {
+				int x = mday;
+				mday = mon;
+				mon = x;
+			}
+		} else if (tlen == 6 || tlen == 8) {
+			if (tlen == 8) {
+				year = (mon % 10000) - 1900;
+				mon /= 10000;
+			} else {
+				year = mon % 100;
+				mon /= 100;
+			}
+			mday = mon % 100;
+			mon /= 100;
+		} else
+			panic("garbled time");
+
+		mon--;
+		if (mon < 0 || mon > 11 || mday < 1 || mday > 31)
+			panic("garbled time");
+
+		assign_date(tm, mday, mon, year);
+		break;
+	} /* case */
+} /* month */
+
+
+/* Global functions */
+
+time_t
+parsetime(int argc, char **argv)
+{
+	/*
+	 * Do the argument parsing, die if necessary, and return the
+	 * time the job should be run.
+	 */
+	time_t nowtimer, runtimer;
+	struct tm nowtime, runtime;
+	int hr = 0; /* this MUST be initialized to zero for
+	               midnight/noon/teatime */
+	int fulltime = 0;
+
+	nowtimer = time(NULL);
+	nowtime = *localtime(&nowtimer);
+
+	runtime = nowtime;
+
+	if (argc <= optind)
+		panic("bad arguments");
+
+	init_scanner(argc - optind, argv + optind);
+
+	switch (token()) {
+	case NOW:
+		/* now is optional prefix for PLUS tree
+		   in this case the PLUS tree is optional. */
+		switch (token()) {
+		case PLUS:
+			plus(&runtime);
+			break;
+		case EOF:
+			break;
+		default:
+			plonk(sc_tokid);
+			break;
+		}
+		fulltime = 1;
+		break;
+	case PLUS:
+		plus(&runtime);
+		break;
+
+	case NUMBER:
+		tod(&runtime);
+		month(&runtime);
+		break;
+
+		/*
+		 * evil coding for TEATIME|NOON|MIDNIGHT - we've initialised
+		 * hr to zero up above, then fall into this case in such a
+		 * way so we add +12 +4 hours to it for teatime, +12 hours
+		 * to it for noon, and nothing at all for midnight, then
+		 * set our runtime to that hour before leaping into the
+		 * month scanner
+		 */
+	case TEATIME:
+		hr += 4;
+	case NOON:
+		hr += 12;
+	case MIDNIGHT:
+		if (runtime.tm_hour >= hr) {
+			runtime.tm_mday++;
+			runtime.tm_wday++;
+		}
+		runtime.tm_hour = hr;
+		runtime.tm_min = 0;
+		token();
+		/* fall through to month setting */
+	default:
+		month(&runtime);
+		break;
+	} /* ugly case statement */
+	expect(EOF);
+
+	if (!fulltime) {
+		runtime.tm_sec = 0;
+		runtime.tm_isdst = 0;
+	}
+
+	/*
+	 * adjust for daylight savings time
+	 */
+	runtime.tm_isdst = -1;
+	runtimer = mktime(&runtime);
+	if (runtime.tm_isdst > 0) {
+		runtimer -= 3600;
+		runtimer = mktime(&runtime);
+	}
+
+	if (runtimer < 0)
+		panic("Time not valid (possibly due to daylight saving time)");
+
+	if (nowtimer > runtimer)
+		panic("Trying to travel back in time");
+
+	return (runtimer);
+} /* parsetime */
Index: othersrc/usr.bin/sleepto/parsetime.h
diff -u /dev/null othersrc/usr.bin/sleepto/parsetime.h:1.1
--- /dev/null	Thu Feb 25 07:03:57 2021
+++ othersrc/usr.bin/sleepto/parsetime.h	Thu Feb 25 07:03:57 2021
@@ -0,0 +1 @@
+time_t parsetime(int, char **);
Index: othersrc/usr.bin/sleepto/sleepto.c
diff -u /dev/null othersrc/usr.bin/sleepto/sleepto.c:1.1
--- /dev/null	Thu Feb 25 07:03:57 2021
+++ othersrc/usr.bin/sleepto/sleepto.c	Thu Feb 25 07:03:57 2021
@@ -0,0 +1,44 @@
+/* $NetBSD: sleepto.c,v 1.1 2021/02/25 07:03:57 simonb Exp $ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+#define TIMEFMT	"%R"
+
+static void	usage(void);
+
+extern time_t	parsetime(int, char **);
+
+int
+main(int argc, char *argv[])
+{
+	struct timeval tv;
+	time_t when, now;
+
+	if (argc < 2)
+		usage();
+		/* NOTREACHED */
+
+	if (gettimeofday(&tv, NULL) == -1) {
+		perror("gettimeofday");
+		return EXIT_FAILURE;
+	}
+
+	when = parsetime(argc, argv);
+	now = tv.tv_sec;
+
+	printf("sleeping for %ld seconds...\n", when - now);
+	sleep(when - now);
+
+	return EXIT_SUCCESS;
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr, "%s: usage: %s date\n",
+	    getprogname(), getprogname());
+	exit(EXIT_FAILURE);
+}
Index: othersrc/usr.bin/sleepto/tzfile.h
diff -u /dev/null othersrc/usr.bin/sleepto/tzfile.h:1.1
--- /dev/null	Thu Feb 25 07:03:57 2021
+++ othersrc/usr.bin/sleepto/tzfile.h	Thu Feb 25 07:03:57 2021
@@ -0,0 +1,158 @@
+/*	$NetBSD: tzfile.h,v 1.1 2021/02/25 07:03:57 simonb Exp $	*/
+
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Arthur David Olson of the National Cancer Institute.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)tzfile.h	8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _TZFILE_H_
+#define	_TZFILE_H_
+
+/*
+ * Information about time zone files.
+ */
+			/* Time zone object file directory */
+#define TZDIR		"/usr/share/zoneinfo"
+#define TZDEFAULT	"/etc/localtime"
+#define TZDEFRULES	"posixrules"
+
+/*
+** Each file begins with. . .
+*/
+
+#define TZ_MAGIC	"TZif"
+
+struct tzhead {
+	char	tzh_magic[4];		/* TZ_MAGIC */
+	char	tzh_reserved[16];	/* reserved for future use */
+	char	tzh_ttisgmtcnt[4];	/* coded number of trans. time flags */
+	char	tzh_ttisstdcnt[4];	/* coded number of trans. time flags */
+	char	tzh_leapcnt[4];		/* coded number of leap seconds */
+	char	tzh_timecnt[4];		/* coded number of transition times */
+	char	tzh_typecnt[4];		/* coded number of local time types */
+	char	tzh_charcnt[4];		/* coded number of abbr. chars */
+};
+
+/*
+** . . .followed by. . .
+**
+**	tzh_timecnt (char [4])s		coded transition times a la time(2)
+**	tzh_timecnt (unsigned char)s	types of local time starting at above
+**	tzh_typecnt repetitions of
+**		one (char [4])		coded UTC offset in seconds
+**		one (unsigned char)	used to set tm_isdst
+**		one (unsigned char)	that's an abbreviation list index
+**	tzh_charcnt (char)s		'\0'-terminated zone abbreviations
+**	tzh_leapcnt repetitions of
+**		one (char [4])		coded leap second transition times
+**		one (char [4])		total correction after above
+**	tzh_ttisstdcnt (char)s		indexed by type; if TRUE, transition
+**					time is standard time, if FALSE,
+**					transition time is wall clock time
+**					if absent, transition times are
+**					assumed to be wall clock time
+**	tzh_ttisgmtcnt (char)s		indexed by type; if TRUE, transition
+**					time is UTC, if FALSE,
+**					transition time is wall clock time
+**					if absent, transition times are
+**					assumed to be local time
+*/
+
+/*
+** In the current implementation, "tzset()" refuses to deal with files that
+** exceed any of the limits below.
+*/
+
+/*
+** The TZ_MAX_TIMES value below is enough to handle a bit more than a
+** year's worth of solar time (corrected daily to the nearest second) or
+** 138 years of Pacific Presidential Election time
+** (where there are three time zone transitions every fourth year).
+*/
+#define TZ_MAX_TIMES	370
+
+#define NOSOLAR			/* 4BSD doesn't currently handle solar time */
+
+#ifndef NOSOLAR
+#define TZ_MAX_TYPES	256	/* Limited by what (unsigned char)'s can hold */
+#else
+#define TZ_MAX_TYPES	10	/* Maximum number of local time types */
+#endif
+
+#define TZ_MAX_CHARS	50	/* Maximum number of abbreviation characters */
+
+#define	TZ_MAX_LEAPS	50	/* Maximum number of leap second corrections */
+
+#define SECSPERMIN	60
+#define MINSPERHOUR	60
+#define HOURSPERDAY	24
+#define DAYSPERWEEK	7
+#define DAYSPERNYEAR	365
+#define DAYSPERLYEAR	366
+#define SECSPERHOUR	(SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY	((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR	12
+
+#define TM_SUNDAY	0
+#define TM_MONDAY	1
+#define TM_TUESDAY	2
+#define TM_WEDNESDAY	3
+#define TM_THURSDAY	4
+#define TM_FRIDAY	5
+#define TM_SATURDAY	6
+
+#define TM_JANUARY	0
+#define TM_FEBRUARY	1
+#define TM_MARCH	2
+#define TM_APRIL	3
+#define TM_MAY		4
+#define TM_JUNE		5
+#define TM_JULY		6
+#define TM_AUGUST	7
+#define TM_SEPTEMBER	8
+#define TM_OCTOBER	9
+#define TM_NOVEMBER	10
+#define TM_DECEMBER	11
+
+#define TM_YEAR_BASE	1900
+
+#define EPOCH_YEAR	1970
+#define EPOCH_WDAY	TM_THURSDAY
+
+/*
+** Accurate only for the past couple of centuries;
+** that will probably do.
+*/
+
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+#endif /* !_TZFILE_H_ */

Reply via email to