diff options
author | edwin <edwin@FreeBSD.org> | 2010-03-29 06:49:20 +0000 |
---|---|---|
committer | edwin <edwin@FreeBSD.org> | 2010-03-29 06:49:20 +0000 |
commit | 914d5a5c2da11a9119f44c4469b7820a3471ddbb (patch) | |
tree | 3d2119bf9389f55ad0bcafa6f89a7fa4865924d6 /usr.bin/calendar/calendar.c | |
parent | da13321f0367c93e6227866043622792c016f3a2 (diff) | |
download | FreeBSD-src-914d5a5c2da11a9119f44c4469b7820a3471ddbb.zip FreeBSD-src-914d5a5c2da11a9119f44c4469b7820a3471ddbb.tar.gz |
Long awaited update to the calendar system:
- Repeating events which span multiple years (because of -A, -B or
just the three days before the end of the year).
- Support for lunar events (full moon, new moon) and solar events
(equinox and solstice, chinese new year). Because of this, the
options -U (UTC offset) and -l (longitude) are available to
compensate if reality doesn't match the calculated values.
MFC after: 1 month
Diffstat (limited to 'usr.bin/calendar/calendar.c')
-rw-r--r-- | usr.bin/calendar/calendar.c | 106 |
1 files changed, 91 insertions, 15 deletions
diff --git a/usr.bin/calendar/calendar.c b/usr.bin/calendar/calendar.c index 39f2c9c..f5b5e94 100644 --- a/usr.bin/calendar/calendar.c +++ b/usr.bin/calendar/calendar.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -52,29 +52,38 @@ __FBSDID("$FreeBSD$"); #include <pwd.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <time.h> #include <unistd.h> #include "calendar.h" +#define UTCOFFSET_NOTSET 100 /* Expected between -24 and +24 */ +#define LONGITUDE_NOTSET 1000 /* Expected between -360 and +360 */ + struct passwd *pw; int doall = 0; +int debug = 0; +char *DEBUG = NULL; time_t f_time = 0; - -int f_dayAfter = 0; /* days after current date */ -int f_dayBefore = 0; /* days before current date */ -int Friday = 5; /* day before weekend */ +double UTCOffset = UTCOFFSET_NOTSET; +int EastLongitude = LONGITUDE_NOTSET; static void usage(void) __dead2; int main(int argc, char *argv[]) { + int f_dayAfter = 0; /* days after current date */ + int f_dayBefore = 0; /* days before current date */ + int Friday = 5; /* day before weekend */ + int ch; + struct tm tp1, tp2; (void)setlocale(LC_ALL, ""); - while ((ch = getopt(argc, argv, "-A:aB:F:f:t:W:")) != -1) + while ((ch = getopt(argc, argv, "-A:aB:dD:F:f:l:t:U:W:")) != -1) switch (ch) { case '-': /* backward contemptible */ case 'a': @@ -89,14 +98,10 @@ main(int argc, char *argv[]) calendarFile = optarg; break; - case 't': /* other date, undocumented, for tests */ - f_time = Mktime(optarg); - break; - case 'W': /* we don't need no steenking Fridays */ Friday = -1; - /* FALLTHROUGH */ + case 'A': /* days after current date */ f_dayAfter = atoi(optarg); break; @@ -105,9 +110,25 @@ main(int argc, char *argv[]) f_dayBefore = atoi(optarg); break; - case 'F': + case 'F': /* Change the time: When does weekend start? */ Friday = atoi(optarg); break; + case 'l': /* Change longitudal position */ + EastLongitude = strtol(optarg, NULL, 10); + break; + case 'U': /* Change UTC offset */ + UTCOffset = strtod(optarg, NULL); + break; + + case 'd': + debug = 1; + break; + case 'D': + DEBUG = optarg; + break; + case 't': /* other date, undocumented, for tests */ + f_time = Mktime(optarg); + break; case '?': default: @@ -124,7 +145,60 @@ main(int argc, char *argv[]) if (f_time <= 0) (void)time(&f_time); - settime(f_time); + /* if not set, determine where I could be */ + { + if (UTCOffset == UTCOFFSET_NOTSET && + EastLongitude == LONGITUDE_NOTSET) { + /* Calculate on difference between here and UTC */ + time_t t; + struct tm tm; + long utcoffset, hh, mm, ss; + double uo; + + time(&t); + localtime_r(&t, &tm); + utcoffset = tm.tm_gmtoff; + /* seconds -> hh:mm:ss */ + hh = utcoffset / SECSPERHOUR; + utcoffset %= SECSPERHOUR; + mm = utcoffset / SECSPERMINUTE; + utcoffset %= SECSPERMINUTE; + ss = utcoffset; + + /* hh:mm:ss -> hh.mmss */ + uo = mm + (100.0 * (ss / 60.0)); + uo /= 60.0 / 100.0; + uo = hh + uo / 100; + + UTCOffset = uo; + EastLongitude = UTCOffset * 15; + } else if (UTCOffset == UTCOFFSET_NOTSET) { + /* Base on information given */ + UTCOffset = EastLongitude / 15; + } else if (EastLongitude == LONGITUDE_NOTSET) { + /* Base on information given */ + EastLongitude = UTCOffset * 15; + } + } + + settimes(f_time, f_dayBefore, f_dayAfter, Friday, &tp1, &tp2); + generatedates(&tp1, &tp2); + + /* + * FROM now on, we are working in UTC. + * This will only affect moon and sun related events anyway. + */ + if (setenv("TZ", "UTC", 1) != 0) + errx(1, "setenv: %s", strerror(errno)); + tzset(); + + if (debug) + dumpdates(); + + if (DEBUG != NULL) { + dodebug(DEBUG); + exit(0); + } if (doall) while ((pw = getpwent()) != NULL) { @@ -145,9 +219,11 @@ static void __dead2 usage(void) { - fprintf(stderr, "%s\n%s\n", + fprintf(stderr, "%s\n%s\n%s\n", "usage: calendar [-a] [-A days] [-B days] [-F friday] " "[-f calendarfile]", - " [-t dd[.mm[.year]]] [-W days]"); + " [-d] [-t dd[.mm[.year]]] [-W days]", + " [-U utcoffset] [-l longitude]" + ); exit(1); } |