summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2010-04-28 05:33:59 +0000
committermckusick <mckusick@FreeBSD.org>2010-04-28 05:33:59 +0000
commit3a0f5972a0de87aebef1af257922515700da4217 (patch)
treea65d36ab57a1e076de7e7a1d78add642fbd7062e /usr.bin
parentf40c3a9dc50f808e512fcc9f9f738717013b483b (diff)
parenta768cbcadec7189b9947e9f3cde39fe806bbc1d7 (diff)
downloadFreeBSD-src-3a0f5972a0de87aebef1af257922515700da4217.zip
FreeBSD-src-3a0f5972a0de87aebef1af257922515700da4217.tar.gz
Update to current version of head.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/alias/Makefile3
-rw-r--r--usr.bin/apply/Makefile2
-rw-r--r--usr.bin/apply/apply.c67
-rw-r--r--usr.bin/ar/ar.12
-rw-r--r--usr.bin/biff/biff.14
-rw-r--r--usr.bin/c89/c89.12
-rw-r--r--usr.bin/c99/c99.12
-rw-r--r--usr.bin/calendar/Makefile6
-rw-r--r--usr.bin/calendar/calendar.186
-rw-r--r--usr.bin/calendar/calendar.c110
-rw-r--r--usr.bin/calendar/calendar.h182
-rw-r--r--usr.bin/calendar/calendars/calendar.australia74
-rw-r--r--usr.bin/calendar/calendars/calendar.dutch90
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd3
-rw-r--r--usr.bin/calendar/dates.c452
-rw-r--r--usr.bin/calendar/day.c416
-rw-r--r--usr.bin/calendar/events.c126
-rw-r--r--usr.bin/calendar/io.c372
-rw-r--r--usr.bin/calendar/locale.c164
-rw-r--r--usr.bin/calendar/ostern.c46
-rw-r--r--usr.bin/calendar/parsedata.c1009
-rw-r--r--usr.bin/calendar/paskha.c43
-rw-r--r--usr.bin/calendar/pathnames.h6
-rw-r--r--usr.bin/calendar/pom.c276
-rw-r--r--usr.bin/calendar/sunpos.c448
-rw-r--r--usr.bin/chpass/Makefile2
-rw-r--r--usr.bin/column/column.12
-rw-r--r--usr.bin/comm/comm.12
-rw-r--r--usr.bin/comm/comm.c178
-rw-r--r--usr.bin/compress/compress.c4
-rw-r--r--usr.bin/cpio/Makefile2
-rw-r--r--usr.bin/csup/Makefile46
-rw-r--r--usr.bin/csup/auth.c2
-rw-r--r--usr.bin/csup/cpasswd.14
-rw-r--r--usr.bin/csup/csup.12
-rw-r--r--usr.bin/enigma/enigma.12
-rw-r--r--usr.bin/find/find.110
-rw-r--r--usr.bin/getent/getent.c14
-rw-r--r--usr.bin/gzip/gzip.111
-rw-r--r--usr.bin/gzip/gzip.c43
-rw-r--r--usr.bin/gzip/unbzip2.c2
-rw-r--r--usr.bin/hexdump/od.12
-rw-r--r--usr.bin/indent/args.c1
-rw-r--r--usr.bin/indent/indent.14
-rw-r--r--usr.bin/indent/indent.c2
-rw-r--r--usr.bin/indent/indent_globs.h2
-rw-r--r--usr.bin/indent/lexi.c13
-rw-r--r--usr.bin/kdump/kdump.c32
-rw-r--r--usr.bin/killall/killall.12
-rw-r--r--usr.bin/locale/Makefile6
-rw-r--r--usr.bin/lockf/lockf.12
-rw-r--r--usr.bin/mail/util.c2
-rw-r--r--usr.bin/make/main.c2
-rw-r--r--usr.bin/minigzip/Makefile9
-rw-r--r--usr.bin/ncal/Makefile1
-rw-r--r--usr.bin/ncal/ncal.172
-rw-r--r--usr.bin/ncal/ncal.c731
-rw-r--r--usr.bin/netstat/netgraph.c6
-rw-r--r--usr.bin/perror/perror.12
-rw-r--r--usr.bin/procstat/Makefile1
-rw-r--r--usr.bin/procstat/procstat.161
-rw-r--r--usr.bin/procstat/procstat.c26
-rw-r--r--usr.bin/procstat/procstat.h4
-rw-r--r--usr.bin/procstat/procstat_sigs.c139
-rw-r--r--usr.bin/script/script.c1
-rw-r--r--usr.bin/sed/main.c3
-rw-r--r--usr.bin/sed/sed.18
-rw-r--r--usr.bin/sockstat/sockstat.c2
-rw-r--r--usr.bin/stat/stat.17
-rw-r--r--usr.bin/stat/stat.c29
-rw-r--r--usr.bin/tar/bsdtar.135
-rw-r--r--usr.bin/tar/bsdtar.c3
-rw-r--r--usr.bin/tar/bsdtar_platform.h4
-rw-r--r--usr.bin/tar/matching.c53
-rw-r--r--usr.bin/tar/subst.c3
-rw-r--r--usr.bin/tar/tree.h36
-rw-r--r--usr.bin/tar/write.c14
-rw-r--r--usr.bin/touch/touch.c12
-rw-r--r--usr.bin/truncate/Makefile2
-rw-r--r--usr.bin/truncate/truncate.c67
-rw-r--r--usr.bin/truss/amd64-fbsd.c2
-rw-r--r--usr.bin/truss/amd64-fbsd32.c2
-rw-r--r--usr.bin/truss/amd64-linux32.c2
-rw-r--r--usr.bin/truss/extern.h2
-rw-r--r--usr.bin/truss/i386-fbsd.c2
-rw-r--r--usr.bin/truss/i386-linux.c2
-rw-r--r--usr.bin/truss/ia64-fbsd.c2
-rw-r--r--usr.bin/truss/main.c2
-rw-r--r--usr.bin/truss/mips-fbsd.c2
-rw-r--r--usr.bin/truss/powerpc-fbsd.c4
-rw-r--r--usr.bin/truss/setup.c2
-rw-r--r--usr.bin/truss/sparc64-fbsd.c2
-rw-r--r--usr.bin/truss/syscalls.c2
-rw-r--r--usr.bin/truss/truss.h2
-rw-r--r--usr.bin/unifdef/unifdef.128
-rw-r--r--usr.bin/unifdef/unifdef.c83
-rw-r--r--usr.bin/unifdef/unifdefall.sh21
-rw-r--r--usr.bin/uniq/uniq.c193
-rw-r--r--usr.bin/wtmpcvt/wtmpcvt.12
-rw-r--r--usr.bin/xlint/lint1/decl.c8
-rw-r--r--usr.bin/xlint/lint1/lint1.h4
-rw-r--r--usr.bin/xlint/lint1/mem1.c2
-rw-r--r--usr.bin/xlint/lint1/scan.l2
103 files changed, 4370 insertions, 1721 deletions
diff --git a/usr.bin/alias/Makefile b/usr.bin/alias/Makefile
index 53df717..474499f 100644
--- a/usr.bin/alias/Makefile
+++ b/usr.bin/alias/Makefile
@@ -10,8 +10,11 @@ LINKS= ${BINDIR}/alias ${BINDIR}/bg \
${BINDIR}/alias ${BINDIR}/fc \
${BINDIR}/alias ${BINDIR}/fg \
${BINDIR}/alias ${BINDIR}/getopts \
+ ${BINDIR}/alias ${BINDIR}/hash \
${BINDIR}/alias ${BINDIR}/jobs \
${BINDIR}/alias ${BINDIR}/read \
+ ${BINDIR}/alias ${BINDIR}/type \
+ ${BINDIR}/alias ${BINDIR}/ulimit \
${BINDIR}/alias ${BINDIR}/umask \
${BINDIR}/alias ${BINDIR}/unalias \
${BINDIR}/alias ${BINDIR}/wait
diff --git a/usr.bin/apply/Makefile b/usr.bin/apply/Makefile
index ca0f10a..c23d928 100644
--- a/usr.bin/apply/Makefile
+++ b/usr.bin/apply/Makefile
@@ -2,5 +2,7 @@
# $FreeBSD$
PROG= apply
+DPADD= ${LIBSBUF}
+LDADD= -lsbuf
.include <bsd.prog.mk>
diff --git a/usr.bin/apply/apply.c b/usr.bin/apply/apply.c
index 25ba374..9c83126 100644
--- a/usr.bin/apply/apply.c
+++ b/usr.bin/apply/apply.c
@@ -44,10 +44,12 @@ static char sccsid[] = "@(#)apply.c 8.4 (Berkeley) 4/4/94";
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/sbuf.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
@@ -61,10 +63,13 @@ static int exec_shell(const char *, char *, char *);
static void usage(void);
int
-main(int argc, char *argv[]) {
+main(int argc, char *argv[])
+{
+ struct sbuf *cmdbuf;
+ long arg_max;
int ch, debug, i, magic, n, nargs, offset, rval;
- size_t clen, cmdsize, l;
- char *c, *cmd, *name, *p, *q, *shell, *slashp, *tmpshell;
+ size_t cmdsize;
+ char *cmd, *name, *p, *shell, *slashp, *tmpshell;
debug = 0;
magic = '%'; /* Default magic char is `%'. */
@@ -144,13 +149,13 @@ main(int argc, char *argv[]) {
p = cmd;
offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
if ((size_t)offset >= cmdsize)
- err(1, "snprintf() failed");
+ errx(1, "snprintf() failed");
p += offset;
cmdsize -= offset;
for (i = 1; i <= nargs; i++) {
offset = snprintf(p, cmdsize, " %c%d", magic, i);
if ((size_t)offset >= cmdsize)
- err(1, "snprintf() failed");
+ errx(1, "snprintf() failed");
p += offset;
cmdsize -= offset;
}
@@ -164,61 +169,53 @@ main(int argc, char *argv[]) {
} else {
offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
if ((size_t)offset >= cmdsize)
- err(1, "snprintf() failed");
+ errx(1, "snprintf() failed");
nargs = n;
}
- /*
- * Grab some space in which to build the command. Allocate
- * as necessary later, but no reason to build it up slowly
- * for the normal case.
- */
- if ((c = malloc(clen = 1024)) == NULL)
+ cmdbuf = sbuf_new(NULL, NULL, 1024, SBUF_AUTOEXTEND);
+ if (cmdbuf == NULL)
err(1, NULL);
+ arg_max = sysconf(_SC_ARG_MAX);
+
/*
* (argc) and (argv) are still offset by one to make it simpler to
* expand %digit references. At the end of the loop check for (argc)
* equals 1 means that all the (argv) has been consumed.
*/
for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
- /*
- * Find a max value for the command length, and ensure
- * there's enough space to build it.
- */
- for (l = strlen(cmd), i = 0; i < nargs; i++)
- l += strlen(argv[i+1]);
- if (l > clen && (c = realloc(c, clen = l)) == NULL)
- err(1, NULL);
-
+ sbuf_clear(cmdbuf);
/* Expand command argv references. */
- for (p = cmd, q = c; *p != '\0'; ++p)
+ for (p = cmd; *p != '\0'; ++p) {
if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
- offset = snprintf(q, l, "%s",
- argv[(++p)[0] - '0']);
- if ((size_t)offset >= l)
- err(1, "snprintf() failed");
- q += offset;
- l -= offset;
- } else
- *q++ = *p;
+ if (sbuf_cat(cmdbuf, argv[(++p)[0] - '0'])
+ == -1)
+ errc(1, ENOMEM, "sbuf");
+ } else {
+ if (sbuf_putc(cmdbuf, *p) == -1)
+ errc(1, ENOMEM, "sbuf");
+ }
+ if (sbuf_len(cmdbuf) > arg_max)
+ errc(1, E2BIG, NULL);
+ }
/* Terminate the command string. */
- *q = '\0';
+ sbuf_finish(cmdbuf);
/* Run the command. */
if (debug)
- (void)printf("%s\n", c);
+ (void)printf("%s\n", sbuf_data(cmdbuf));
else
- if (exec_shell(c, shell, name))
+ if (exec_shell(sbuf_data(cmdbuf), shell, name))
rval = 1;
}
if (argc != 1)
errx(1, "expecting additional argument%s after \"%s\"",
- (nargs - argc) ? "s" : "", argv[argc - 1]);
+ (nargs - argc) ? "s" : "", argv[argc - 1]);
free(cmd);
- free(c);
+ sbuf_delete(cmdbuf);
free(shell);
exit(rval);
}
diff --git a/usr.bin/ar/ar.1 b/usr.bin/ar/ar.1
index cb9414e..250cd20 100644
--- a/usr.bin/ar/ar.1
+++ b/usr.bin/ar/ar.1
@@ -24,8 +24,8 @@
.\" $FreeBSD$
.\"
.Dd August 31, 2007
-.Os
.Dt AR 1
+.Os
.Sh NAME
.Nm ar ,
.Nm ranlib
diff --git a/usr.bin/biff/biff.1 b/usr.bin/biff/biff.1
index 8484faa..45d0fad 100644
--- a/usr.bin/biff/biff.1
+++ b/usr.bin/biff/biff.1
@@ -32,7 +32,7 @@
.\" @(#)biff.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd July 9, 2002
+.Dd March 20, 2010
.Dt BIFF 1
.Os
.Sh NAME
@@ -67,7 +67,7 @@ Enable bell notification.
When header notification is enabled, the header and first few lines of
the message will be printed on your terminal whenever mail arrives.
A
-.Dq "Li biff y"
+.Dq "biff y"
command is often included in the file
.Pa .login
or
diff --git a/usr.bin/c89/c89.1 b/usr.bin/c89/c89.1
index 302aa32..82acf37 100644
--- a/usr.bin/c89/c89.1
+++ b/usr.bin/c89/c89.1
@@ -26,8 +26,8 @@
.\" $FreeBSD$
.\"
.Dd September 17, 1997
-.Os
.Dt C89 1
+.Os
.Sh NAME
.Nm c89
.Nd POSIX.2 C language compiler
diff --git a/usr.bin/c99/c99.1 b/usr.bin/c99/c99.1
index c56e585..e5207e5 100644
--- a/usr.bin/c99/c99.1
+++ b/usr.bin/c99/c99.1
@@ -27,8 +27,8 @@
.\" $FreeBSD$
.\"
.Dd October 7, 2002
-.Os
.Dt C99 1
+.Os
.Sh NAME
.Nm c99
.Nd standard C language compiler
diff --git a/usr.bin/calendar/Makefile b/usr.bin/calendar/Makefile
index 27df8b6..e5d1c6a 100644
--- a/usr.bin/calendar/Makefile
+++ b/usr.bin/calendar/Makefile
@@ -2,14 +2,16 @@
# $FreeBSD$
PROG= calendar
-SRCS= calendar.c io.c day.c ostern.c paskha.c
+SRCS= calendar.c locale.c events.c dates.c parsedata.c io.c day.c \
+ ostern.c paskha.c pom.c sunpos.c
+LDADD= -lm
INTER= de_AT.ISO_8859-15 de_DE.ISO8859-1 fr_FR.ISO8859-1 \
hr_HR.ISO8859-2 hu_HU.ISO8859-2 ru_RU.KOI8-R uk_UA.KOI8-U
DE_LINKS= de_DE.ISO8859-15
FR_LINKS= fr_FR.ISO8859-15
TEXTMODE?= 444
-WARNS?= 3
+WARNS?= 7
beforeinstall:
${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \
diff --git a/usr.bin/calendar/calendar.1 b/usr.bin/calendar/calendar.1
index 404f44c..8f8fb5c 100644
--- a/usr.bin/calendar/calendar.1
+++ b/usr.bin/calendar/calendar.1
@@ -9,10 +9,6 @@
.\" 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. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
.\" 4. 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.
@@ -54,6 +50,8 @@
.Ek
.Oc
.Op Fl W Ar num
+.Op Fl U Ar UTC-offset
+.Op Fl l Ar longitude
.Sh DESCRIPTION
The
.Nm
@@ -93,6 +91,12 @@ as the default calendar file.
.Sm on
.Xc
For test purposes only: set date directly to argument values.
+.It Fl l Ar longitude , Fl U Ar UTC-offset
+Only one is needed:
+Perform lunar and solar calculations from this longitude or from
+this UTC offset.
+If neither is specified, the calculations will be based on the
+difference between UTC time and localtime.
.It Fl W Ar num
Print lines from today and the next
.Ar num
@@ -103,12 +107,36 @@ Ignore weekends when calculating the number of days.
To handle calendars in your national code table you can specify
.Dq LANG=<locale_name>
in the calendar file as early as possible.
-To handle national Easter
-names in the calendars
-.Dq Easter=<national_name>
-(for Catholic Easter) or
-.Dq Paskha=<national_name>
-(for Orthodox Easter) can be used.
+.Pp
+To handle the local name of sequences, you can specify them as:
+.Dq SEQUENCE=<first> <second> <third> <fourth> <fifth> <last>
+in the calendar file as early as possible.
+.Pp
+The names of the following special days are recognized:
+.Bl -tag -width 123456789012345 -compact
+.It Easter
+Catholic Easter.
+.It Paskha
+Orthodox Easter.
+.It NewMoon
+The lunar New Moon.
+.It FullMoon
+The lunar Full Moon.
+.It MarEquinox
+The solar equinox in March.
+.It JunSolstice
+The solar solstice in June.
+.It SepEquinox
+The solar equinox in March.
+.It DecSolstice
+The solar solstice in December.
+.It ChineseNewYear
+The first day of the Chinese year.
+.El
+These names may be reassigned to their local names via an assignment
+like
+.Dq Easter=Pasen
+in the calendar file.
.Pp
Other lines should begin with a month and day.
They may be entered in almost any format, either numeric or as character
@@ -122,11 +150,11 @@ Two numbers default to the month followed by the day.
Lines with leading tabs default to the last entered date, allowing
multiple line specifications for a single date.
.Pp
-``Easter'', is Easter for this year, and may be followed by a positive
-or negative integer.
-.Pp
-``Paskha'', is Orthodox Easter for this year, and may be followed by a
-positive or negative integer.
+The names of the recognized special days may be followed by a
+positive or negative integer, like:
+.Dq Easter+3
+or
+.Dq Pashka-4 .
.Pp
Weekdays may be followed by ``-4'' ...\& ``+5'' (aliases for
last, first, second, third, fourth) for moving events like
@@ -191,7 +219,8 @@ calendar file to use if no calendar file exists in the current directory.
do not send mail if this file exists.
.El
.Pp
-The following default calendar files are provided:
+The following default calendar files are provided in
+.Pa /usr/share/calendars:
.Pp
.Bl -tag -width calendar.southafrica -compact
.It Pa calendar.all
@@ -208,6 +237,8 @@ so that roving holidays are set correctly for the current year.
Days of special significance to computer people.
.It Pa calendar.croatian
Calendar of events in Croatia.
+.It Pa calendar.dutch
+Calendar of events in the Netherlands.
.It Pa calendar.freebsd
Birthdays of
.Fx
@@ -259,7 +290,28 @@ A
.Nm
command appeared in
.At v7 .
+.Sh NOTES
+Chinese New Year is calculated at 120 degrees east of Greenwich,
+which roughly corresponds with the east coast of China.
+For people west of China, this might result that the start of Chinese
+New Year and the day of the related new moon might differ.
+.Pp
+The phases of the moon and the longitude of the sun are calculated
+against the local position which corresponds with 30 degrees times
+the time-difference towards Greenwich.
+.Pp
+The new and full moons are happening on the day indicated: They
+might happen in the time period in the early night or in the late
+evening.
+It doesn't indicate that they are starting in the night on that date.
+.Pp
+Because of minor differences between the output of the formulas
+used and other sources on the Internet, Druids and Werewolves should
+double-check the start and end time of solar and lunar events.
.Sh BUGS
The
.Nm
-utility does not handle Jewish holidays and moon phases.
+utility does not handle Jewish holidays.
+.Pp
+There is no possibility to properly specify the local position
+needed for solar and lunar calculations.
diff --git a/usr.bin/calendar/calendar.c b/usr.bin/calendar/calendar.c
index 39f2c9c..29ac174 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.
*
@@ -10,10 +10,6 @@
* 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. 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.
@@ -52,29 +48,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 +94,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 +106,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 +141,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 +215,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);
}
diff --git a/usr.bin/calendar/calendar.h b/usr.bin/calendar/calendar.h
index ff67ca6..634c278 100644
--- a/usr.bin/calendar/calendar.h
+++ b/usr.bin/calendar/calendar.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. 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.
@@ -36,43 +32,163 @@
#include <sys/types.h>
#include <sys/uio.h>
+#define SECSPERDAY (24 * 60 * 60)
+#define SECSPERHOUR (60 * 60)
+#define SECSPERMINUTE (60)
+#define MINSPERHOUR (60)
+#define HOURSPERDAY (24)
+#define FSECSPERDAY (24.0 * 60.0 * 60.0)
+#define FSECSPERHOUR (60.0 * 60.0)
+#define FSECSPERMINUTE (60.0)
+#define FMINSPERHOUR (60.0)
+#define FHOURSPERDAY (24.0)
+
+#define DAYSPERYEAR 365
+#define DAYSPERLEAPYEAR 366
+
+/* Not yet categorized */
+
extern struct passwd *pw;
extern int doall;
-extern struct iovec header[];
-extern struct tm *tp;
+extern time_t t1, t2;
extern const char *calendarFile;
-extern int *cumdays;
extern int yrdays;
-extern struct fixs neaster, npaskha;
-
-void cal(void);
-void closecal(FILE *);
-int getday(char *);
-int getdayvar(char *);
-int getfield(char *, char **, int *);
-int getmonth(char *);
-int geteaster(char *, int);
-int getpaskha(char *, int);
-int easter(int);
-int isnow(char *, int *, int *, int *);
-FILE *opencal(void);
-void settime(time_t);
-time_t Mktime(char *);
-void setnnames(void);
+extern struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon;
+extern struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice;
+extern double UTCOffset;
+extern int EastLongitude;
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-/* some flags */
-#define F_ISMONTH 0x01 /* month (January ...) */
-#define F_ISDAY 0x02 /* day of week (Sun, Mon, ...) */
-#define F_ISDAYVAR 0x04 /* variables day of week, like SundayLast */
-#define F_EASTER 0x08 /* Easter or easter depending days */
+/* Flags to determine the returned values by determinestyle() in parsedata.c */
+#define F_NONE 0x00000
+#define F_MONTH 0x00001
+#define F_DAYOFWEEK 0x00002
+#define F_DAYOFMONTH 0x00004
+#define F_MODIFIERINDEX 0x00008
+#define F_MODIFIEROFFSET 0x00010
+#define F_SPECIALDAY 0x00020
+#define F_ALLMONTH 0x00040
+#define F_ALLDAY 0x00080
+#define F_VARIABLE 0x00100
+#define F_EASTER 0x00200
+#define F_CNY 0x00400
+#define F_PASKHA 0x00800
+#define F_NEWMOON 0x01000
+#define F_FULLMOON 0x02000
+#define F_MAREQUINOX 0x04000
+#define F_SEPEQUINOX 0x08000
+#define F_JUNSOLSTICE 0x10000
+#define F_DECSOLSTICE 0x20000
+
+#define STRING_EASTER "Easter"
+#define STRING_PASKHA "Paskha"
+#define STRING_CNY "ChineseNewYear"
+#define STRING_NEWMOON "NewMoon"
+#define STRING_FULLMOON "FullMoon"
+#define STRING_MAREQUINOX "MarEquinox"
+#define STRING_SEPEQUINOX "SepEquinox"
+#define STRING_JUNSOLSTICE "JunSolstice"
+#define STRING_DECSOLSTICE "DecSolstice"
-extern int f_dayAfter; /* days after current date */
-extern int f_dayBefore; /* days before current date */
-extern int Friday; /* day before weekend */
+#define MAXCOUNT 125 /* Random number of maximum number of
+ * repeats of an event. Should be 52
+ * (number of weeks per year), if you
+ * want to show two years then it
+ * should be 104. If you are seeing
+ * more than this you are using this
+ * program wrong.
+ */
+
+/*
+ * All the astronomical calculations are carried out for the meridian 120
+ * degrees east of Greenwich.
+ */
+#define UTCOFFSET_CNY 8.0
+
+extern int debug; /* show parsing of the input */
+extern int year1, year2;
+
+/* events.c */
+/*
+ * Event sorting related functions:
+ * - Use event_add() to create a new event
+ * - Use event_continue() to add more text to the last added event
+ * - Use event_print_all() to display them in time chronological order
+ */
+struct event *event_add(int, int, int, char *, int, char *, char *);
+void event_continue(struct event *events, char *txt);
+void event_print_all(FILE *fp);
+struct event {
+ int year;
+ int month;
+ int day;
+ int var;
+ char *date;
+ char *text;
+ char *extra;
+ struct event *next;
+};
+
+/* locale.c */
struct fixs {
char *name;
- int len;
+ size_t len;
};
+
+extern const char *days[];
+extern const char *fdays[];
+extern const char *fmonths[];
+extern const char *months[];
+extern const char *sequences[];
+extern struct fixs fndays[8]; /* full national days names */
+extern struct fixs fnmonths[13]; /* full national months names */
+extern struct fixs ndays[8]; /* short national days names */
+extern struct fixs nmonths[13]; /* short national month names */
+extern struct fixs nsequences[10];
+
+void setnnames(void);
+void setnsequences(char *);
+
+/* day.c */
+extern const struct tm tm0;
+extern char dayname[];
+void settimes(time_t,int before, int after, int friday, struct tm *tp1, struct tm *tp2);
+time_t Mktime(char *);
+
+/* parsedata.c */
+int parsedaymonth(char *, int *, int *, int *, int *, char **);
+void dodebug(char *type);
+
+/* io.c */
+void cal(void);
+void closecal(FILE *);
+FILE *opencal(void);
+
+/* ostern.c / pashka.c */
+int paskha(int);
+int easter(int);
+
+/* dates.c */
+extern int cumdaytab[][14];
+extern int mondaytab[][14];
+extern int debug_remember;
+void generatedates(struct tm *tp1, struct tm *tp2);
+void dumpdates(void);
+int remember_ymd(int y, int m, int d);
+int remember_yd(int y, int d, int *rm, int *rd);
+int first_dayofweek_of_year(int y);
+int first_dayofweek_of_month(int y, int m);
+int walkthrough_dates(struct event **e);
+void addtodate(struct event *e, int year, int month, int day);
+
+/* pom.c */
+#define MAXMOONS 18
+void pom(int year, double UTCoffset, int *fms, int *nms);
+void fpom(int year, double utcoffset, double *ffms, double *fnms);
+
+/* sunpos.c */
+void equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays);
+void fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays);
+int calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths);
diff --git a/usr.bin/calendar/calendars/calendar.australia b/usr.bin/calendar/calendars/calendar.australia
index 323e7ee..daa07ff 100644
--- a/usr.bin/calendar/calendars/calendar.australia
+++ b/usr.bin/calendar/calendars/calendar.australia
@@ -10,49 +10,63 @@
LANG=en_AU.ISO8859-1
/* Australia */
-Jan 26 Australia Day
-Mar/SunLast Daylight Savings Time ends in ACT, NSW, SA, TAS and VIC.
-Apr 25 Anzac Day
+Jan 26 Australia Day
+Apr/SunFirst Daylight Savings Time ends in ACT, NSW, SA, TAS and VIC.
+Apr 25 Anzac Day
Jun/MonSecond Queen's Birthday Holiday (Australia, except WA)
-Oct/SunLast Daylight Savings Time starts in ACT, NSW, SA and VIC.
+Oct/SunFirst Daylight Savings Time starts in ACT, NSW, SA and VIC.
/* ACT, NSW, common */
-Mar 18 Canberra Day (ACT)
-8/MonFirst Bank Holiday (ACT, NSW)
-10/MonFirst Labour Day (ACT, NSW, SA)
+Mar 18 Canberra Day (ACT)
+Sep/MonLast Family & Community Day (ACT)
+Aug/MonFirst Bank Holiday (ACT, NSW)
+Oct/MonFirst Labour Day (ACT, NSW, SA)
/* Victoria */
-3/MonSecond Labour Day (Vic)
-Nov/TueFirst Melbourne Cup (Vic)
-
-/* Tasmania */
-Feb 11 Regatta Day (Tas)
-Feb 27 Launceston Cup (Tas)
-Mar 11 Eight Hours Day (Tas)
-Oct/SunFirst Daylight Savings Time starts in TAS.
-Oct 10 Launceston Show Day (Tas)
-Oct 24 Hobart Show Day (Tas)
-Nov 04 Recreation Day (N Tas)
+Mar/MonSecond Labour Day (VIC)
+Nov/TueFirst Melbourne Cup (VIC)
+
+/* Tasmania
+ * http://www.wst.tas.gov.au/employment_info/public_holidays/html/2010
+ */
+Feb/MonSecond Regatta Day (TAS)
+Feb/WedLast Launceston Cup (TAS)
+Mar/TueFirst King Island show (TAS)
+Mar/MonSecond Eight Hours Day (TAS)
+Oct 10 Launceston Show Day (TAS) /* Thursday preceding second Saturday in October */
+Oct 24 Hobart Show Day (TAS) /* Thursday preceding fourth Saturday in October */
+Nov/MonFirst Recreation Day (N TAS)
+
+/*
+Oct/SatSecond-2 Launceston Show Day (TAS) // Thursday preceding second Sat in October
+Oct/SatFourth-2 Hobart Show Day (TAS) // Thursday preceding fourth Sat in October
+May/ThuFirst+1 Agfest (Circular Head only) // Friday following the first Thursday in May
+Oct/SatFirst-1 Burnie Show // Friday preceding first Saturday in October
+Oct/SatThird-1 Flinders Island Show // Friday preceding third Saturday in October
+
+DEVONPORT CUP Wednesday not earlier than fifth and not later than eleventh day of January
+DEVONPORT SHOW Friday nearest last day in November, but not later than first day of December
+*/
/* South Australia */
May/MonThird Adelaide Cup (SA)
-Dec 26 Proclamation Day holiday (SA)
+Dec 26 Proclamation Day holiday (SA)
/* Western Australia */
-3/MonFirst Labour Day (WA)
-6/MonFirst Foundation Day (WA)
-Sep 30 Queen's Birthday (WA)
+Mar/MonFirst Labour Day (WA)
+Jun/MonFirst Foundation Day (WA)
+Sep 30 Queen's Birthday (WA)
/* Northern Territory */
-5/MonFirst May Day (NT)
-7/FriFirst Alice Springs Show Day (NT)
-7/FriSecond Tennant Creek Show Day (NT)
-7/FriThird Katherine Show Day (NT)
-7/FriLast Darwin Show Day (NT)
-8/MonFirst Picnic Day (NT)
+May/MonFirst May Day (NT)
+Jul/FriFirst Alice Springs Show Day (NT)
+Jul/FriSecond Tennant Creek Show Day (NT)
+Jul/FriThird Katherine Show Day (NT)
+Jul/FriLast Darwin Show Day (NT)
+Aug/MonFirst Picnic Day (NT)
/* Queensland */
-5/MonFirst Labour Day (Qld)
-Aug 14 RNA Show Day (Brisbane metro)
+May/MonFirst Labour Day (QLD)
+Aug/WedSecond RNA Show Day (Brisbane metro) /* Second Last Wednesday */
#endif
diff --git a/usr.bin/calendar/calendars/calendar.dutch b/usr.bin/calendar/calendars/calendar.dutch
index 47b1bf5..fab1793 100644
--- a/usr.bin/calendar/calendars/calendar.dutch
+++ b/usr.bin/calendar/calendars/calendar.dutch
@@ -10,25 +10,25 @@ Easter=Pasen
/*
* Feestdagen
*/
-01/01 Nieuwjaar
-01/06 Driekoningen
-04/01 Een April
-04/30 Koninginendag
-05/01 Dag van de Arbeid
-05/04 Dodenherdenking
-05/05 Bevrijdingsdag
-10/04 Dierendag
-11/01 Allerheilingen
-11/02 Allerzielen
-11/11 Sint Maarten
-11/11 Elfde-van-de-elfde
-12/05 Sinterklaas avond
-12/15 Koninkrijksdag
-12/24 Kerstavond
-12/25 Eerste kerstdag
-12/26 Tweede kerstdag
-12/28 Feest der Onnozele Kinderen
-12/31 Oudjaar
+jan/01 Nieuwjaar
+jan/06 Driekoningen
+apr/01 1 april
+apr/30 Koninginnedag
+mei/01 Dag van de Arbeid
+mei/04 Dodenherdenking
+mei/05 Bevrijdingsdag
+okt/04 Dierendag
+nov/01 Allerheiligen
+nov/02 Allerzielen
+nov/11 Sint Maarten
+nov/11 Elfde-van-de-elfde
+dec/05 Sinterklaas avond
+dec/15 Koninkrijksdag
+dec/24 Kerstavond
+dec/25 Eerste kerstdag
+dec/26 Tweede kerstdag
+dec/28 Feest der Onnozele Kinderen
+dec/31 Oudjaar
/*
* Pasen gerelateerd
@@ -38,12 +38,12 @@ Pasen-49 Carnaval
Pasen-48 Carnaval
Pasen-47 Carnaval (Vastenavond)
Pasen-46 Aswoensdag
-Pasen-7 Palmzondag
-Pasen-3 Witte Donderdag
-Pasen-2 Goede vrijdag
-Pasen-1 Stille zaterdag
+Pasen-7 Palmzondag
+Pasen-3 Witte Donderdag
+Pasen-2 Goede vrijdag
+Pasen-1 Stille zaterdag
Pasen Eerste paasdag
-Pasen+1 Tweede paasdag
+Pasen+1 Tweede paasdag
Pasen+39 Hemelvaartsdag
Pasen+49 Eerste Pinksterdag
Pasen+50 Tweede Pinksterdag
@@ -52,28 +52,28 @@ Pasen+56 Trinitatis
/*
* Misc
*/
-05/SunSecond Moederdag
-06/SunThird Vaderdag
-09/TueThird Prinsjesdag
+mei/SunSecond Moederdag
+jun/SunThird Vaderdag
+sep/TueThird Prinsjesdag
/*
* Het koningshuis
*/
-01/19 Prinses Margriet (1943)
-01/31 Koningin Beatrix (1938)
-02/17 Prins Willem III (1817 - 1890)
-02/18 Prinses Christina (1947)
-04/10 Prinses Ariane (2007)
-04/19 Prins Hendrik (1876 - 1934)
-04/27 Kroonprins Willem Alexander (1967)
-04/30 Koningin Juliana (1909 - 2004)
-04/30 Mr. Pieter van Vollenhoven (1939)
-05/17 Prinses Maxima (1971)
-06/26 Prinses Alexia (2005)
-06/29 Prins Bernhard (1911 - 2004)
-08/05 Prinses Irene (1939)
-08/31 Prinses Wilhelmina (1880 - 1962)
-09/06 Prins Claus (1925 - 2002)
-09/25 Prins Johan Friso (1968)
-10/11 Prins Constantijn (1969)
-12/07 Prinses Catharina-Amalia (2003)
+jan/19 Prinses Margriet (1943)
+jan/31 Koningin Beatrix (1938)
+feb/17 Prins Willem III (1817 - 1890)
+feb/18 Prinses Christina (1947)
+apr/10 Prinses Ariane (2007)
+apr/19 Prins Hendrik (1876 - 1934)
+apr/27 Kroonprins Willem Alexander (1967)
+apr/30 Koningin Juliana (1909 - 2004)
+apr/30 Mr. Pieter van Vollenhoven (1939)
+mei/17 Prinses Maxima (1971)
+jun/26 Prinses Alexia (2005)
+jun/29 Prins Bernhard (1911 - 2004)
+aug/05 Prinses Irene (1939)
+aug/31 Prinses Wilhelmina (1880 - 1962)
+sep/06 Prins Claus (1925 - 2002)
+sep/25 Prins Johan Friso (1968)
+okt/11 Prins Constantijn (1969)
+dec/07 Prinses Catharina-Amalia (2003)
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index 3c7d71d..cfebc36 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -82,6 +82,7 @@
03/12 Greg Lewis <glewis@FreeBSD.org> born in Adelaide, South Australia, Australia, 1969
03/13 Alexander Leidinger <netchild@FreeBSD.org> born in Neunkirchen, Saarland, Germany, 1976
03/13 Will Andrews <will@FreeBSD.org> born in Pontiac, Michigan, United States, 1982
+03/14 Bernhard Froehlich <decke@FreeBSD.org> born in Graz, Styria, Austria, 1985
03/15 Paolo Pisati <piso@FreeBSD.org> born in Lodi, Italy, 1977
03/15 Brian Fundakowski Feldman <green@FreeBSD.org> born in Alexandria, Virginia, United States, 1983
03/17 Michael Smith <msmith@FreeBSD.org> born in Bankstown, New South Wales, Australia, 1971
@@ -107,6 +108,7 @@
04/03 Tong Liu <nemoliu@FreeBSD.org> born in Beijing, People's Republic of China, 1981
04/03 Gabor Pali <pgj@FreeBSD.org> born in Kunhegyes, Hungary, 1982
04/05 Stacey Son <sson@FreeBSD.org> born in Burley, Idaho, United States. 1967
+04/07 Edward Tomasz Napierala <trasz@FreeBSD.org> born in Wolsztyn, Poland, 1981
04/08 Jordan K. Hubbard <jkh@FreeBSD.org> born in Honolulu, Hawaii, United States, 1963
04/09 Ceri Davies <ceri@FreeBSD.org> born in Haverfordwest, Pembrokeshire, United Kingdom, 1976
04/11 Bruce A. Mah <bmah@FreeBSD.org> born in Fresno, California, United States, 1969
@@ -206,6 +208,7 @@
07/23 Sergey A. Osokin <osa@FreeBSD.org> born in Krasnogorsky, Stepnogorsk, Akmolinskaya region, Kazakhstan, 1972
07/24 Alexander Nedotsukov <bland@FreeBSD.org> born in Ulyanovsk, Russian Federation, 1974
07/24 Alberto Villa <avilla@FreeBSD.org> born in Vercelli, Italy, 1987
+07/27 Andriy Gapon <avg@FreeBSD.org> born in Kyrykivka, Sumy region, Ukraine, 1976
07/28 Jim Mock <jim@FreeBSD.org> born in Bethlehem, Pennsylvania, United States, 1974
07/28 Tom Hukins <tom@FreeBSD.org> born in Manchester, United Kingdom, 1976
07/29 Dirk Meyer <dinoex@FreeBSD.org> born in Kassel, Hessen, Germany, 1965
diff --git a/usr.bin/calendar/dates.c b/usr.bin/calendar/dates.c
new file mode 100644
index 0000000..3f8b89f
--- /dev/null
+++ b/usr.bin/calendar/dates.c
@@ -0,0 +1,452 @@
+/*-
+ * Copyright (c) 1992-2009 Edwin Groothuis <edwin@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <time.h>
+
+#include "calendar.h"
+
+struct cal_year {
+ int year; /* 19xx, 20xx, 21xx */
+ int easter; /* Julian day */
+ int paskha; /* Julian day */
+ int cny; /* Julian day */
+ int firstdayofweek; /* 0 .. 6 */
+ struct cal_month *months;
+ struct cal_year *nextyear;
+} cal_year;
+
+struct cal_month {
+ int month; /* 01 .. 12 */
+ int firstdayjulian; /* 000 .. 366 */
+ int firstdayofweek; /* 0 .. 6 */
+ struct cal_year *year; /* points back */
+ struct cal_day *days;
+ struct cal_month *nextmonth;
+} cal_month;
+
+struct cal_day {
+ int dayofmonth; /* 01 .. 31 */
+ int julianday; /* 000 .. 366 */
+ int dayofweek; /* 0 .. 6 */
+ struct cal_day *nextday;
+ struct cal_month *month; /* points back */
+ struct cal_year *year; /* points back */
+ struct event *events;
+} cal_day;
+
+int debug_remember = 0;
+struct cal_year *hyear = NULL;
+
+/* 1-based month, 0-based days, cumulative */
+int *cumdays;
+int cumdaytab[][14] = {
+ {0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},
+ {0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
+};
+/* 1-based month, individual */
+int *mondays;
+int mondaytab[][14] = {
+ {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 30},
+ {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 30},
+};
+
+static struct cal_day * find_day(int yy, int mm, int dd);
+
+static void
+createdate(int y, int m, int d)
+{
+ struct cal_year *py, *pyp;
+ struct cal_month *pm, *pmp;
+ struct cal_day *pd, *pdp;
+ int *cumday;
+
+ pyp = NULL;
+ py = hyear;
+ while (py != NULL) {
+ if (py->year == y + 1900)
+ break;
+ pyp = py;
+ py = py->nextyear;
+ }
+
+ if (py == NULL) {
+ struct tm td;
+ time_t t;
+ py = (struct cal_year *)calloc(1, sizeof(struct cal_year));
+ py->year = y + 1900;
+ py->easter = easter(y);
+ py->paskha = paskha(y);
+
+ td = tm0;
+ td.tm_year = y;
+ td.tm_mday = 1;
+ t = mktime(&td);
+ localtime_r(&t, &td);
+ py->firstdayofweek = td.tm_wday;
+
+ if (pyp != NULL)
+ pyp->nextyear = py;
+ }
+ if (pyp == NULL) {
+ /* The very very very first one */
+ hyear = py;
+ }
+
+ pmp = NULL;
+ pm = py->months;
+ while (pm != NULL) {
+ if (pm->month == m)
+ break;
+ pmp = pm;
+ pm = pm->nextmonth;
+ }
+
+ if (pm == NULL) {
+ pm = (struct cal_month *)calloc(1, sizeof(struct cal_month));
+ pm->year = py;
+ pm->month = m;
+ cumday = cumdaytab[isleap(y)];
+ pm->firstdayjulian = cumday[m] + 2;
+ pm->firstdayofweek =
+ (py->firstdayofweek + pm->firstdayjulian -1) % 7;
+ if (pmp != NULL)
+ pmp->nextmonth = pm;
+ }
+ if (pmp == NULL)
+ py->months = pm;
+
+ pdp = NULL;
+ pd = pm->days;
+ while (pd != NULL) {
+ pdp = pd;
+ pd = pd->nextday;
+ }
+
+ if (pd == NULL) { /* Always true */
+ pd = (struct cal_day *)calloc(1, sizeof(struct cal_day));
+ pd->month = pm;
+ pd->year = py;
+ pd->dayofmonth = d;
+ pd->julianday = pm->firstdayjulian + d - 1;
+ pd->dayofweek = (pm->firstdayofweek + d - 1) % 7;
+ if (pdp != NULL)
+ pdp->nextday = pd;
+ }
+ if (pdp == NULL)
+ pm->days = pd;
+}
+
+void
+generatedates(struct tm *tp1, struct tm *tp2)
+{
+ int y1, m1, d1;
+ int y2, m2, d2;
+ int y, m, d;
+
+ y1 = tp1->tm_year;
+ m1 = tp1->tm_mon + 1;
+ d1 = tp1->tm_mday;
+ y2 = tp2->tm_year;
+ m2 = tp2->tm_mon + 1;
+ d2 = tp2->tm_mday;
+
+ if (y1 == y2) {
+ if (m1 == m2) {
+ /* Same year, same month. Easy! */
+ for (d = d1; d <= d2; d++)
+ createdate(y1, m1, d);
+ return;
+ }
+ /*
+ * Same year, different month.
+ * - Take the leftover days from m1
+ * - Take all days from <m1 .. m2>
+ * - Take the first days from m2
+ */
+ mondays = mondaytab[isleap(y1)];
+ for (d = d1; d <= mondays[m1]; d++)
+ createdate(y1, m1, d);
+ for (m = m1 + 1; m < m2; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y1, m, d);
+ for (d = 1; d <= d2; d++)
+ createdate(y1, m2, d);
+ return;
+ }
+ /*
+ * Different year, different month.
+ * - Take the leftover days from y1-m1
+ * - Take all days from y1-<m1 .. 12]
+ * - Take all days from <y1 .. y2>
+ * - Take all days from y2-[1 .. m2>
+ * - Take the first days of y2-m2
+ */
+ mondays = mondaytab[isleap(y1)];
+ for (d = d1; d <= mondays[m1]; d++)
+ createdate(y1, m1, d);
+ for (m = m1 + 1; m <= 12; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y1, m, d);
+ for (y = y1 + 1; y < y2; y++) {
+ mondays = mondaytab[isleap(y)];
+ for (m = 1; m <= 12; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y, m, d);
+ }
+ mondays = mondaytab[isleap(y2)];
+ for (m = 1; m < m2; m++)
+ for (d = 1; d <= mondays[m]; d++)
+ createdate(y2, m, d);
+ for (d = 1; d <= d2; d++)
+ createdate(y2, m2, d);
+}
+
+void
+dumpdates(void)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ y = hyear;
+ while (y != NULL) {
+ printf("%-5d (wday:%d)\n", y->year, y->firstdayofweek);
+ m = y->months;
+ while (m != NULL) {
+ printf("-- %-5d (julian:%d, dow:%d)\n", m->month,
+ m->firstdayjulian, m->firstdayofweek);
+ d = m->days;
+ while (d != NULL) {
+ printf(" -- %-5d (julian:%d, dow:%d)\n",
+ d->dayofmonth, d->julianday, d->dayofweek);
+ d = d->nextday;
+ }
+ m = m->nextmonth;
+ }
+ y = y->nextyear;
+ }
+}
+
+int
+remember_ymd(int yy, int mm, int dd)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ if (debug_remember)
+ printf("remember_ymd: %d - %d - %d\n", yy, mm, dd);
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ if (m->month != mm) {
+ m = m->nextmonth;
+ continue;
+ }
+ d = m->days;
+ while (d != NULL) {
+ if (d->dayofmonth == dd)
+ return (1);
+ d = d->nextday;
+ continue;
+ }
+ return (0);
+ }
+ return (0);
+ }
+ return (0);
+}
+
+int
+remember_yd(int yy, int dd, int *rm, int *rd)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ if (debug_remember)
+ printf("remember_yd: %d - %d\n", yy, dd);
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ d = m->days;
+ while (d != NULL) {
+ if (d->julianday == dd) {
+ *rm = m->month;
+ *rd = d->dayofmonth;
+ return (1);
+ }
+ d = d->nextday;
+ }
+ m = m->nextmonth;
+ }
+ return (0);
+ }
+ return (0);
+}
+
+int
+first_dayofweek_of_year(int yy)
+{
+ struct cal_year *y;
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year == yy)
+ return (y->firstdayofweek);
+ y = y->nextyear;
+ }
+
+ /* Should not happen */
+ return (-1);
+}
+
+int
+first_dayofweek_of_month(int yy, int mm)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ if (m->month == mm)
+ return (m->firstdayofweek);
+ m = m->nextmonth;
+ }
+ /* Should not happen */
+ return (-1);
+ }
+
+ /* Should not happen */
+ return (-1);
+}
+
+int
+walkthrough_dates(struct event **e)
+{
+ static struct cal_year *y = NULL;
+ static struct cal_month *m = NULL;
+ static struct cal_day *d = NULL;
+
+ if (y == NULL) {
+ y = hyear;
+ m = y->months;
+ d = m->days;
+ *e = d->events;
+ return (1);
+ };
+ if (d->nextday != NULL) {
+ d = d->nextday;
+ *e = d->events;
+ return (1);
+ }
+ if (m->nextmonth != NULL) {
+ m = m->nextmonth;
+ d = m->days;
+ *e = d->events;
+ return (1);
+ }
+ if (y->nextyear != NULL) {
+ y = y->nextyear;
+ m = y->months;
+ d = m->days;
+ *e = d->events;
+ return (1);
+ }
+
+ return (0);
+}
+
+static struct cal_day *
+find_day(int yy, int mm, int dd)
+{
+ struct cal_year *y;
+ struct cal_month *m;
+ struct cal_day *d;
+
+ if (debug_remember)
+ printf("remember_ymd: %d - %d - %d\n", yy, mm, dd);
+
+ y = hyear;
+ while (y != NULL) {
+ if (y->year != yy) {
+ y = y->nextyear;
+ continue;
+ }
+ m = y->months;
+ while (m != NULL) {
+ if (m->month != mm) {
+ m = m->nextmonth;
+ continue;
+ }
+ d = m->days;
+ while (d != NULL) {
+ if (d->dayofmonth == dd)
+ return (d);
+ d = d->nextday;
+ continue;
+ }
+ return (NULL);
+ }
+ return (NULL);
+ }
+ return (NULL);
+}
+
+void
+addtodate(struct event *e, int year, int month, int day)
+{
+ struct cal_day *d;
+
+ d = find_day(year, month, day);
+ e->next = d->events;
+ d->events = e;
+}
diff --git a/usr.bin/calendar/day.c b/usr.bin/calendar/day.c
index e40481e..237b6b5 100644
--- a/usr.bin/calendar/day.c
+++ b/usr.bin/calendar/day.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. 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.
@@ -34,9 +30,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <ctype.h>
#include <err.h>
#include <locale.h>
#include <stdio.h>
@@ -46,120 +39,38 @@ __FBSDID("$FreeBSD$");
#include "calendar.h"
-struct tm *tp;
-static const struct tm tm0;
-int *cumdays, yrdays;
-char dayname[10];
-
-
-/* 1-based month, 0-based days, cumulative */
-int daytab[][14] = {
- {0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},
- {0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
-};
-
-static char const *days[] = {
- "sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL,
-};
-
-static const char *months[] = {
- "jan", "feb", "mar", "apr", "may", "jun",
- "jul", "aug", "sep", "oct", "nov", "dec", NULL,
-};
-
-static struct fixs fndays[8]; /* full national days names */
-static struct fixs ndays[8]; /* short national days names */
-
-static struct fixs fnmonths[13]; /* full national months names */
-static struct fixs nmonths[13]; /* short national month names */
+time_t time1, time2;
+const struct tm tm0;
+char dayname[100];
+int year1, year2;
void
-setnnames(void)
+settimes(time_t now, int before, int after, int friday, struct tm *tp1, struct tm *tp2)
{
- char buf[80];
- int i, l;
- struct tm tm;
-
- for (i = 0; i < 7; i++) {
- tm.tm_wday = i;
- strftime(buf, sizeof(buf), "%a", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (ndays[i].name != NULL)
- free(ndays[i].name);
- if ((ndays[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- ndays[i].len = strlen(buf);
-
- strftime(buf, sizeof(buf), "%A", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (fndays[i].name != NULL)
- free(fndays[i].name);
- if ((fndays[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- fndays[i].len = strlen(buf);
- }
+ char *oldl, *lbufp;
+ struct tm tp;
- for (i = 0; i < 12; i++) {
- tm.tm_mon = i;
- strftime(buf, sizeof(buf), "%b", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (nmonths[i].name != NULL)
- free(nmonths[i].name);
- if ((nmonths[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- nmonths[i].len = strlen(buf);
+ localtime_r(&now, &tp);
- strftime(buf, sizeof(buf), "%B", &tm);
- for (l = strlen(buf);
- l > 0 && isspace((unsigned char)buf[l - 1]);
- l--)
- ;
- buf[l] = '\0';
- if (fnmonths[i].name != NULL)
- free(fnmonths[i].name);
- if ((fnmonths[i].name = strdup(buf)) == NULL)
- errx(1, "cannot allocate memory");
- fnmonths[i].len = strlen(buf);
- }
-}
+ /* Friday displays Monday's events */
+ if (after == 0 && before == 0 && friday != -1)
+ after = tp.tm_wday == friday ? 3 : 1;
-void
-settime(time_t now)
-{
- char *oldl, *lbufp;
+ time1 = now - SECSPERDAY * before;
+ localtime_r(&time1, tp1);
+ year1 = 1900 + tp1->tm_year;
+ time2 = now + SECSPERDAY * after;
+ localtime_r(&time2, tp2);
+ year2 = 1900 + tp2->tm_year;
- tp = localtime(&now);
- if (isleap(tp->tm_year + 1900)) {
- yrdays = 366;
- cumdays = daytab[1];
- } else {
- yrdays = 365;
- cumdays = daytab[0];
- }
- /* Friday displays Monday's events */
- if (f_dayAfter == 0 && f_dayBefore == 0 && Friday != -1)
- f_dayAfter = tp->tm_wday == Friday ? 3 : 1;
- header[5].iov_base = dayname;
+ strftime(dayname, sizeof(dayname) - 1, "%A, %d %B %Y", tp1);
oldl = NULL;
lbufp = setlocale(LC_TIME, NULL);
if (lbufp != NULL && (oldl = strdup(lbufp)) == NULL)
errx(1, "cannot allocate memory");
(void)setlocale(LC_TIME, "C");
- header[5].iov_len = strftime(dayname, sizeof(dayname), "%A", tp);
(void)setlocale(LC_TIME, (oldl != NULL ? oldl : ""));
if (oldl != NULL)
free(oldl);
@@ -175,15 +86,15 @@ Mktime(char *dp)
{
time_t t;
int d, m, y;
- struct tm tm;
+ struct tm tm, tp;
(void)time(&t);
- tp = localtime(&t);
+ localtime_r(&t, &tp);
tm = tm0;
- tm.tm_mday = tp->tm_mday;
- tm.tm_mon = tp->tm_mon;
- tm.tm_year = tp->tm_year;
+ tm.tm_mday = tp.tm_mday;
+ tm.tm_mon = tp.tm_mon;
+ tm.tm_year = tp.tm_year;
switch (sscanf(dp, "%d.%d.%d", &d, &m, &y)) {
case 3:
@@ -204,282 +115,3 @@ Mktime(char *dp)
#endif
return (mktime(&tm));
}
-
-/*
- * Possible date formats include any combination of:
- * 3-charmonth (January, Jan, Jan)
- * 3-charweekday (Friday, Monday, mon.)
- * numeric month or day (1, 2, 04)
- *
- * Any character may separate them, or they may not be separated. Any line,
- * following a line that is matched, that starts with "whitespace", is shown
- * along with the matched line.
- */
-int
-isnow(char *endp, int *monthp, int *dayp, int *varp)
-{
- int day, flags, month = 0, v1, v2;
-
- /*
- * CONVENTION
- *
- * Month: 1-12
- * Monthname: Jan .. Dec
- * Day: 1-31
- * Weekday: Mon-Sun
- *
- */
-
- flags = 0;
-
- /* read first field */
- /* didn't recognize anything, skip it */
- if (!(v1 = getfield(endp, &endp, &flags)))
- return (0);
-
- /* Easter or Easter depending days */
- if (flags & F_EASTER)
- day = v1 - 1; /* days since January 1 [0-365] */
-
- /*
- * 1. {Weekday,Day} XYZ ...
- *
- * where Day is > 12
- */
- else if (flags & F_ISDAY || v1 > 12) {
-
- /* found a day; day: 1-31 or weekday: 1-7 */
- day = v1;
-
- /* {Day,Weekday} {Month,Monthname} ... */
- /* if no recognizable month, assume just a day alone
- * in other words, find month or use current month */
- if (!(month = getfield(endp, &endp, &flags)))
- month = tp->tm_mon + 1;
- }
-
- /* 2. {Monthname} XYZ ... */
- else if (flags & F_ISMONTH) {
- month = v1;
-
- /* Monthname {day,weekday} */
- /* if no recognizable day, assume the first day in month */
- if (!(day = getfield(endp, &endp, &flags)))
- day = 1;
- }
-
- /* Hm ... */
- else {
- v2 = getfield(endp, &endp, &flags);
-
- /*
- * {Day} {Monthname} ...
- * where Day <= 12
- */
- if (flags & F_ISMONTH) {
- day = v1;
- month = v2;
- *varp = 0;
- }
-
- /* {Month} {Weekday,Day} ... */
- else {
- /* F_ISDAY set, v2 > 12, or no way to tell */
- month = v1;
- /* if no recognizable day, assume the first */
- day = v2 ? v2 : 1;
- *varp = 0;
- }
- }
-
- /* convert Weekday into *next* Day,
- * e.g.: 'Sunday' -> 22
- * 'SundayLast' -> ??
- */
- if (flags & F_ISDAY) {
-#ifdef DEBUG
- fprintf(stderr, "\nday: %d %s month %d\n", day, endp, month);
-#endif
-
- *varp = 1;
- /* variable weekday, SundayLast, MondayFirst ... */
- if (day < 0 || day >= 10) {
-
- /* negative offset; last, -4 .. -1 */
- if (day < 0) {
- v1 = day / 10 - 1; /* offset -4 ... -1 */
- day = 10 + (day % 10); /* day 1 ... 7 */
-
- /* day, eg '22nd' */
- v2 = tp->tm_mday +
- (((day - 1) - tp->tm_wday + 7) % 7);
-
- /* (month length - day) / 7 + 1 */
- if (cumdays[month + 1] - cumdays[month] >= v2
- && ((int)((cumdays[month + 1] -
- cumdays[month] - v2) / 7) + 1) == -v1)
- day = v2; /* bingo ! */
-
- /* set to yesterday */
- else {
- day = tp->tm_mday - 1;
- if (day == 0)
- return (0);
- }
- }
-
- /* first, second ... +1 ... +5 */
- else {
- /* offset: +1 (first Sunday) ... */
- v1 = day / 10;
- day = day % 10;
-
- /* day, eg '22th' */
- v2 = tp->tm_mday +
- (((day - 1) - tp->tm_wday + 7) % 7);
-
- /* Hurrah! matched */
- if (((v2 - 1 + 7) / 7) == v1 )
- day = v2;
-
- else {
- /* set to yesterday */
- day = tp->tm_mday - 1;
- if (day == 0)
- return (0);
- }
- }
- } else {
- /* wired */
- day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7);
- *varp = 1;
- }
- }
-
- if (!(flags & F_EASTER)) {
- if (day + cumdays[month] > cumdays[month + 1]) {
- /* off end of month, adjust */
- day -= (cumdays[month + 1] - cumdays[month]);
- /* next year */
- if (++month > 12)
- month = 1;
- }
- *monthp = month;
- *dayp = day;
- day = cumdays[month] + day;
- } else {
- for (v1 = 0; day > cumdays[v1]; v1++)
- ;
- *monthp = v1 - 1;
- *dayp = day - cumdays[v1 - 1];
- *varp = 1;
- }
-
-#ifdef DEBUG
- fprintf(stderr, "day2: day %d(%d-%d) yday %d\n",
- *dayp, day, cumdays[month], tp->tm_yday);
-#endif
-
- /* When days before or days after is specified */
- /* no year rollover */
- if (day >= tp->tm_yday - f_dayBefore &&
- day <= tp->tm_yday + f_dayAfter)
- return (1);
-
- /* next year */
- if (tp->tm_yday + f_dayAfter >= yrdays) {
- int end = tp->tm_yday + f_dayAfter - yrdays;
- if (day <= end)
- return (1);
- }
-
- /* previous year */
- if (tp->tm_yday - f_dayBefore < 0) {
- int before = yrdays + (tp->tm_yday - f_dayBefore);
- if (day >= before)
- return (1);
- }
-
- return (0);
-}
-
-
-int
-getmonth(char *s)
-{
- const char **p;
- struct fixs *n;
-
- for (n = fnmonths; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - fnmonths) + 1);
- for (n = nmonths; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - nmonths) + 1);
- for (p = months; *p; ++p)
- if (!strncasecmp(s, *p, 3))
- return ((p - months) + 1);
- return (0);
-}
-
-
-int
-getday(char *s)
-{
- const char **p;
- struct fixs *n;
-
- for (n = fndays; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - fndays) + 1);
- for (n = ndays; n->name; ++n)
- if (!strncasecmp(s, n->name, n->len))
- return ((n - ndays) + 1);
- for (p = days; *p; ++p)
- if (!strncasecmp(s, *p, 3))
- return ((p - days) + 1);
- return (0);
-}
-
-/* return offset for variable weekdays
- * -1 -> last weekday in month
- * +1 -> first weekday in month
- * ... etc ...
- */
-int
-getdayvar(char *s)
-{
- int offs;
-
- offs = strlen(s);
-
- /* Sun+1 or Wednesday-2
- * ^ ^ */
-
- /* fprintf(stderr, "x: %s %s %d\n", s, s + offs - 2, offs); */
- switch (*(s + offs - 2)) {
- case '-':
- return (-(atoi(s + offs - 1)));
- case '+':
- return (atoi(s + offs - 1));
- }
-
- /*
- * some aliases: last, first, second, third, fourth
- */
-
- /* last */
- if (offs > 4 && !strcasecmp(s + offs - 4, "last"))
- return (-1);
- else if (offs > 5 && !strcasecmp(s + offs - 5, "first"))
- return (+1);
- else if (offs > 6 && !strcasecmp(s + offs - 6, "second"))
- return (+2);
- else if (offs > 5 && !strcasecmp(s + offs - 5, "third"))
- return (+3);
- else if (offs > 6 && !strcasecmp(s + offs - 6, "fourth"))
- return (+4);
-
- /* no offset detected */
- return (0);
-}
diff --git a/usr.bin/calendar/events.c b/usr.bin/calendar/events.c
new file mode 100644
index 0000000..d6f358a
--- /dev/null
+++ b/usr.bin/calendar/events.c
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 1992-2009 Edwin Groothuis <edwin@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/time.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pathnames.h"
+#include "calendar.h"
+
+struct event *
+event_add(int year, int month, int day, char *date, int var, char *txt,
+ char *extra)
+{
+ struct event *e;
+
+ /*
+ * Creating a new event:
+ * - Create a new event
+ * - Copy the machine readable day and month
+ * - Copy the human readable and language specific date
+ * - Copy the text of the event
+ */
+ e = (struct event *)calloc(1, sizeof(struct event));
+ if (e == NULL)
+ errx(1, "event_add: cannot allocate memory");
+ e->month = month;
+ e->day = day;
+ e->var = var;
+ e->date = strdup(date);
+ if (e->date == NULL)
+ errx(1, "event_add: cannot allocate memory");
+ e->text = strdup(txt);
+ if (e->text == NULL)
+ errx(1, "event_add: cannot allocate memory");
+ e->extra = NULL;
+ if (extra != NULL && extra[0] != '\0')
+ e->extra = strdup(extra);
+ addtodate(e, year, month, day);
+ return (e);
+}
+
+void
+event_continue(struct event *e, char *txt)
+{
+ char *text;
+
+ /*
+ * Adding text to the event:
+ * - Save a copy of the old text (unknown length, so strdup())
+ * - Allocate enough space for old text + \n + new text + 0
+ * - Store the old text + \n + new text
+ * - Destroy the saved copy.
+ */
+ text = strdup(e->text);
+ if (text == NULL)
+ errx(1, "event_continue: cannot allocate memory");
+
+ free(e->text);
+ e->text = (char *)malloc(strlen(text) + strlen(txt) + 3);
+ if (e->text == NULL)
+ errx(1, "event_continue: cannot allocate memory");
+ strcpy(e->text, text);
+ strcat(e->text, "\n");
+ strcat(e->text, txt);
+ free(text);
+
+ return;
+}
+
+void
+event_print_all(FILE *fp)
+{
+ struct event *e;
+
+ while (walkthrough_dates(&e) != 0) {
+#ifdef DEBUG
+ fprintf(stderr, "event_print_allmonth: %d, day: %d\n",
+ month, day);
+#endif
+
+ /*
+ * Go through all events and print the text of the matching
+ * dates
+ */
+ while (e != NULL) {
+ (void)fprintf(fp, "%s%c%s%s%s%s\n", e->date,
+ e->var ? '*' : ' ', e->text,
+ e->extra != NULL ? " (" : "",
+ e->extra != NULL ? e->extra : "",
+ e->extra != NULL ? ")" : ""
+ );
+
+ e = e->next;
+ }
+ }
+}
diff --git a/usr.bin/calendar/io.c b/usr.bin/calendar/io.c
index 03f28fe..42abca6 100644
--- a/usr.bin/calendar/io.c
+++ b/usr.bin/calendar/io.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. 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.
@@ -46,11 +42,8 @@ static char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
@@ -66,62 +59,61 @@ __FBSDID("$FreeBSD$");
#include "pathnames.h"
#include "calendar.h"
-/*
- * Event sorting related functions:
- * - Use event_add() to create a new event
- * - Use event_continue() to add more text to the last added event
- * - Use event_print_all() to display them in time chronological order
- */
-static struct event *event_add(struct event *, int, int, char *, int, char *);
-static void event_continue(struct event *events, char *txt);
-static void event_print_all(FILE *fp, struct event *events);
-struct event {
- int month;
- int day;
- int var;
- char *date;
- char *text;
- struct event *next;
-};
-
const char *calendarFile = "calendar"; /* default calendar file */
const char *calendarHomes[] = {".calendar", _PATH_INCLUDE}; /* HOME */
const char *calendarNoMail = "nomail"; /* don't sent mail if this file exist */
char path[MAXPATHLEN];
-struct fixs neaster, npaskha;
-
-struct iovec header[] = {
- {"From: ", 6},
- {NULL, 0},
- {" (Reminder Service)\nTo: ", 24},
- {NULL, 0},
- {"\nSubject: ", 10},
- {NULL, 0},
- {"'s Calendar\nPrecedence: bulk\n\n", 30},
-};
-
+struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon;
+struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice;
+
+#define REPLACE(string, slen, struct_) \
+ if (strncasecmp(buf, (string), (slen)) == 0 && buf[(slen)]) { \
+ if (struct_.name != NULL) \
+ free(struct_.name); \
+ if ((struct_.name = strdup(buf + (slen))) == NULL) \
+ errx(1, "cannot allocate memory"); \
+ struct_.len = strlen(buf + (slen)); \
+ continue; \
+ }
void
cal(void)
{
- int printing;
- char *p;
+ char *pp, p;
FILE *fp;
int ch, l;
- int month;
- int day;
- int var;
+ int count, i;
+ int month[MAXCOUNT];
+ int day[MAXCOUNT];
+ int year[MAXCOUNT];
+ char **extradata; /* strings of 20 length */
+ int flags;
static int d_first = -1;
char buf[2048 + 1];
- struct event *events = NULL;
+ struct event *events[MAXCOUNT];
+ struct tm tm;
+ char dbuf[80];
+
+ extradata = (char **)calloc(MAXCOUNT, sizeof(char *));
+ for (i = 0; i < MAXCOUNT; i++) {
+ extradata[i] = (char *)calloc(1, 20);
+ }
+
+ /* Unused */
+ tm.tm_sec = 0;
+ tm.tm_min = 0;
+ tm.tm_hour = 0;
+ tm.tm_wday = 0;
+ count = 0;
if ((fp = opencal()) == NULL)
return;
- for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) {
- if ((p = strchr(buf, '\n')) != NULL)
- *p = '\0';
+ while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ if ((pp = strchr(buf, '\n')) != NULL)
+ *pp = '\0';
else
+ /* Flush this line */
while ((ch = getchar()) != '\n' && ch != EOF);
for (l = strlen(buf);
l > 0 && isspace((unsigned char)buf[l - 1]);
@@ -130,246 +122,87 @@ cal(void)
buf[l] = '\0';
if (buf[0] == '\0')
continue;
+
+ /* Parse special definitions: LANG, Easter, Paskha etc */
if (strncmp(buf, "LANG=", 5) == 0) {
(void)setlocale(LC_ALL, buf + 5);
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
setnnames();
continue;
}
- if (strncasecmp(buf, "Easter=", 7) == 0 && buf[7]) {
- if (neaster.name != NULL)
- free(neaster.name);
- if ((neaster.name = strdup(buf + 7)) == NULL)
- errx(1, "cannot allocate memory");
- neaster.len = strlen(buf + 7);
- continue;
- }
- if (strncasecmp(buf, "Paskha=", 7) == 0 && buf[7]) {
- if (npaskha.name != NULL)
- free(npaskha.name);
- if ((npaskha.name = strdup(buf + 7)) == NULL)
- errx(1, "cannot allocate memory");
- npaskha.len = strlen(buf + 7);
+ REPLACE("Easter=", 7, neaster);
+ REPLACE("Paskha=", 7, npaskha);
+ REPLACE("ChineseNewYear=", 15, ncny);
+ REPLACE("NewMoon=", 8, nnewmoon);
+ REPLACE("FullMoon=", 9, nfullmoon);
+ REPLACE("MarEquinox=", 11, nmarequinox);
+ REPLACE("SepEquinox=", 11, nsepequinox);
+ REPLACE("JunSolstice=", 12, njunsolstice);
+ REPLACE("DecSolstice=", 12, ndecsolstice);
+ if (strncmp(buf, "SEQUENCE=", 9) == 0) {
+ setnsequences(buf + 9);
continue;
}
- if (buf[0] != '\t') {
- printing = isnow(buf, &month, &day, &var) ? 1 : 0;
- if ((p = strchr(buf, '\t')) == NULL)
- continue;
- if (p > buf && p[-1] == '*')
- var = 1;
- if (printing) {
- struct tm tm;
- char dbuf[80];
-
- if (d_first < 0)
- d_first =
- (*nl_langinfo(D_MD_ORDER) == 'd');
- tm.tm_sec = 0; /* unused */
- tm.tm_min = 0; /* unused */
- tm.tm_hour = 0; /* unused */
- tm.tm_wday = 0; /* unused */
- tm.tm_mon = month - 1;
- tm.tm_mday = day;
- tm.tm_year = tp->tm_year; /* unused */
- (void)strftime(dbuf, sizeof(dbuf),
- d_first ? "%e %b" : "%b %e", &tm);
- events = event_add(events, month, day, dbuf,
- var, p);
- }
- } else {
- if (printing)
- event_continue(events, buf);
- }
- }
-
- event_print_all(fp, events);
- closecal(fp);
-}
-
-static struct event *
-event_add(struct event *events, int month, int day,
- char *date, int var, char *txt)
-{
- struct event *e;
-
- /*
- * Creating a new event:
- * - Create a new event
- * - Copy the machine readable day and month
- * - Copy the human readable and language specific date
- * - Copy the text of the event
- */
- e = (struct event *)calloc(1, sizeof(struct event));
- if (e == NULL)
- errx(1, "event_add: cannot allocate memory");
- e->month = month;
- e->day = day;
- e->var = var;
- e->date = strdup(date);
- if (e->date == NULL)
- errx(1, "event_add: cannot allocate memory");
- e->text = strdup(txt);
- if (e->text == NULL)
- errx(1, "event_add: cannot allocate memory");
- e->next = events;
-
- return e;
-}
-
-static void
-event_continue(struct event *e, char *txt)
-{
- char *text;
-
- /*
- * Adding text to the event:
- * - Save a copy of the old text (unknown length, so strdup())
- * - Allocate enough space for old text + \n + new text + 0
- * - Store the old text + \n + new text
- * - Destroy the saved copy.
- */
- text = strdup(e->text);
- if (text == NULL)
- errx(1, "event_continue: cannot allocate memory");
-
- free(e->text);
- e->text = (char *)malloc(strlen(text) + strlen(txt) + 3);
- if (e->text == NULL)
- errx(1, "event_continue: cannot allocate memory");
- strcpy(e->text, text);
- strcat(e->text, "\n");
- strcat(e->text, txt);
- free(text);
-
- return;
-}
-
-static void
-event_print_all(FILE *fp, struct event *events)
-{
- struct event *e, *e_next;
- int daycounter;
- int day, month;
-
- /*
- * Print all events:
- * - We know the number of days to be counted (f_dayAfter + f_dayBefore)
- * - We know the current day of the year ("now" - f_dayBefore + counter)
- * - We know the number of days in the year (yrdays, set in settime())
- * - So we know the date on which the current daycounter is on the
- * calendar in days and months.
- * - Go through the list of events, and print all matching dates
- */
- for (daycounter = 0; daycounter <= f_dayAfter + f_dayBefore;
- daycounter++) {
- day = tp->tm_yday - f_dayBefore + daycounter;
- if (day < 0)
- day += yrdays;
- if (day >= yrdays)
- day -= yrdays;
/*
- * When we know the day of the year, we can determine the day
- * of the month and the month.
+ * If the line starts with a tab, the data has to be
+ * added to the previous line
*/
- month = 1;
- while (month <= 12) {
- if (day <= cumdays[month])
- break;
- month++;
+ if (buf[0] == '\t') {
+ for (i = 0; i < count; i++)
+ event_continue(events[i], buf);
+ continue;
}
- month--;
- day -= cumdays[month];
-#ifdef DEBUG
- fprintf(stderr, "event_print_allmonth: %d, day: %d\n",
- month, day);
-#endif
+ /* Get rid of leading spaces (non-standard) */
+ while (isspace(buf[0]))
+ memcpy(buf, buf + 1, strlen(buf) - 1);
- /*
- * Go through all events and print the text of the matching
- * dates
- */
- for (e = events; e != NULL; e = e_next) {
- e_next = e->next;
+ /* No tab in the line, then not a valid line */
+ if ((pp = strchr(buf, '\t')) == NULL)
+ continue;
- if (month != e->month || day != e->day)
- continue;
+ /* Trim spaces in front of the tab */
+ while (isspace(pp[-1]))
+ pp--;
- (void)fprintf(fp, "%s%c%s\n", e->date,
- e->var ? '*' : ' ', e->text);
+ p = *pp;
+ *pp = '\0';
+ if ((count = parsedaymonth(buf, year, month, day, &flags,
+ extradata)) == 0)
+ continue;
+ *pp = p;
+ if (count < 0) {
+ /* Show error status based on return value */
+ fprintf(stderr, "Ignored: %s\n", buf);
+ if (count == -1)
+ continue;
+ count = -count + 1;
}
- }
-}
-int
-getfield(char *p, char **endp, int *flags)
-{
- int val, var;
- char *start, savech;
+ /* Find the last tab */
+ while (pp[1] == '\t')
+ pp++;
- for (; !isdigit((unsigned char)*p) && !isalpha((unsigned char)*p)
- && *p != '*'; ++p)
- ;
- if (*p == '*') { /* `*' is current month */
- *flags |= F_ISMONTH;
- *endp = p + 1;
- return (tp->tm_mon + 1);
- }
- if (isdigit((unsigned char)*p)) {
- val = strtol(p, &p, 10); /* if 0, it's failure */
- for (; !isdigit((unsigned char)*p)
- && !isalpha((unsigned char)*p) && *p != '*'; ++p);
- *endp = p;
- return (val);
- }
- for (start = p; isalpha((unsigned char)*++p););
-
- /* Sunday-1 */
- if (*p == '+' || *p == '-')
- for(; isdigit((unsigned char)*++p);)
- ;
-
- savech = *p;
- *p = '\0';
-
- /* Month */
- if ((val = getmonth(start)) != 0)
- *flags |= F_ISMONTH;
-
- /* Day */
- else if ((val = getday(start)) != 0) {
- *flags |= F_ISDAY;
+ if (d_first < 0)
+ d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
- /* variable weekday */
- if ((var = getdayvar(start)) != 0) {
- if (var <= 5 && var >= -4)
- val += var * 10;
-#ifdef DEBUG
- printf("var: %d\n", var);
-#endif
+ for (i = 0; i < count; i++) {
+ tm.tm_mon = month[i] - 1;
+ tm.tm_mday = day[i];
+ tm.tm_year = year[i] - 1900;
+ (void)strftime(dbuf, sizeof(dbuf),
+ d_first ? "%e %b" : "%b %e", &tm);
+ if (debug)
+ fprintf(stderr, "got %s\n", pp);
+ events[i] = event_add(year[i], month[i], day[i], dbuf,
+ ((flags &= F_VARIABLE) != 0) ? 1 : 0, pp,
+ extradata[i]);
}
}
- /* Easter */
- else if ((val = geteaster(start, tp->tm_year + 1900)) != 0)
- *flags |= F_EASTER;
-
- /* Paskha */
- else if ((val = getpaskha(start, tp->tm_year + 1900)) != 0)
- *flags |= F_EASTER;
-
- /* undefined rest */
- else {
- *p = savech;
- return (0);
- }
- for (*p = savech; !isdigit((unsigned char)*p)
- && !isalpha((unsigned char)*p) && *p != '*'; ++p)
- ;
- *endp = p;
- return (val);
+ event_print_all(fp);
+ closecal(fp);
}
FILE *
@@ -505,9 +338,14 @@ closecal(FILE *fp)
/* parent -- write to pipe input */
(void)close(pdes[0]);
- header[1].iov_base = header[3].iov_base = pw->pw_name;
- header[1].iov_len = header[3].iov_len = strlen(pw->pw_name);
- writev(pdes[1], header, 7);
+ write(pdes[1], "From: \"Reminder Service\" <", 26);
+ write(pdes[1], pw->pw_name, strlen(pw->pw_name));
+ write(pdes[1], ">\nTo: <", 7);
+ write(pdes[1], pw->pw_name, strlen(pw->pw_name));
+ write(pdes[1], ">\nSubject: ", 12);
+ write(pdes[1], dayname, strlen(dayname));
+ write(pdes[1], "'s Calendar\nPrecedence: bulk\n\n", 30);
+
while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0)
(void)write(pdes[1], buf, nread);
(void)close(pdes[1]);
diff --git a/usr.bin/calendar/locale.c b/usr.bin/calendar/locale.c
new file mode 100644
index 0000000..57839ac
--- /dev/null
+++ b/usr.bin/calendar/locale.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ * 4. 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ctype.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "calendar.h"
+
+const char *fdays[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
+ "Saturday", NULL,
+};
+
+const char *days[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL,
+};
+
+const char *fmonths[] = {
+ "January", "February", "March", "April", "May", "June", "Juli",
+ "August", "September", "October", "November", "December", NULL,
+};
+
+const char *months[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL,
+};
+
+const char *sequences[] = {
+ "First", "Second", "Third", "Fourth", "Fifth", "Last"
+};
+
+struct fixs fndays[8]; /* full national days names */
+struct fixs ndays[8]; /* short national days names */
+struct fixs fnmonths[13]; /* full national months names */
+struct fixs nmonths[13]; /* short national month names */
+struct fixs nsequences[10]; /* national sequence names */
+
+
+void
+setnnames(void)
+{
+ char buf[80];
+ int i, l;
+ struct tm tm;
+
+ for (i = 0; i < 7; i++) {
+ tm.tm_wday = i;
+ strftime(buf, sizeof(buf), "%a", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (ndays[i].name != NULL)
+ free(ndays[i].name);
+ if ((ndays[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ ndays[i].len = strlen(buf);
+
+ strftime(buf, sizeof(buf), "%A", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (fndays[i].name != NULL)
+ free(fndays[i].name);
+ if ((fndays[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ fndays[i].len = strlen(buf);
+ }
+
+ for (i = 0; i < 12; i++) {
+ tm.tm_mon = i;
+ strftime(buf, sizeof(buf), "%b", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (nmonths[i].name != NULL)
+ free(nmonths[i].name);
+ if ((nmonths[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ nmonths[i].len = strlen(buf);
+
+ strftime(buf, sizeof(buf), "%B", &tm);
+ for (l = strlen(buf);
+ l > 0 && isspace((unsigned char)buf[l - 1]);
+ l--)
+ ;
+ buf[l] = '\0';
+ if (fnmonths[i].name != NULL)
+ free(fnmonths[i].name);
+ if ((fnmonths[i].name = strdup(buf)) == NULL)
+ errx(1, "cannot allocate memory");
+ fnmonths[i].len = strlen(buf);
+ }
+}
+
+void
+setnsequences(char *seq)
+{
+ int i;
+ char *p;
+
+ p = seq;
+ for (i = 0; i < 5; i++) {
+ nsequences[i].name = p;
+ if ((p = strchr(p, ' ')) == NULL) {
+ for (i = 0; i < 5; i++) {
+ nsequences[i].name = NULL;
+ nsequences[i].len = 0;
+ return;
+ }
+
+ }
+ *p = '\0';
+ p++;
+ }
+ nsequences[i].name = p;
+
+ for (i = 0; i < 5; i++) {
+ nsequences[i].name = strdup(nsequences[i].name);
+ nsequences[i].len = nsequences[i + 1].name - nsequences[i].name;
+ }
+ nsequences[i].name = strdup(nsequences[i].name);
+ nsequences[i].len = strlen(nsequences[i].name);
+
+ return;
+}
diff --git a/usr.bin/calendar/ostern.c b/usr.bin/calendar/ostern.c
index 89e7b1c..3cce299 100644
--- a/usr.bin/calendar/ostern.c
+++ b/usr.bin/calendar/ostern.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
* All rights reserved.
*
@@ -60,50 +60,8 @@ easter(int year) /* 0 ... abcd, NOT since 1900 */
L = I - J;
- if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
+ if (isleap(year))
return 31 + 29 + 21 + L + 7;
else
return 31 + 28 + 21 + L + 7;
}
-
-/* return year day for Easter or easter depending days
- * Match: Easter([+-][0-9]+)?
- * e.g: Easter-2 is Good Friday (2 days before Easter)
- */
-
-int
-geteaster(char *s, int year)
-{
- int offset = 0;
-
-#define EASTER "easter"
-#define EASTERNAMELEN (sizeof(EASTER) - 1)
-
- if (strncasecmp(s, EASTER, EASTERNAMELEN) == 0)
- s += EASTERNAMELEN;
- else if (neaster.name != NULL
- && strncasecmp(s, neaster.name, neaster.len) == 0)
- s += neaster.len;
- else
- return (0);
-
-#ifdef DEBUG
- printf("%s %d %d\n", s, year, EASTERNAMELEN);
-#endif
-
- /* Easter+1 or Easter-2
- * ^ ^ */
-
- switch (*s) {
-
- case '-':
- case '+':
- offset = atoi(s);
- break;
-
- default:
- offset = 0;
- }
-
- return (easter(year) + offset);
-}
diff --git a/usr.bin/calendar/parsedata.c b/usr.bin/calendar/parsedata.c
new file mode 100644
index 0000000..4fab640
--- /dev/null
+++ b/usr.bin/calendar/parsedata.c
@@ -0,0 +1,1009 @@
+/*-
+ * Copyright (c) 1992-2009 Edwin Groothuis <edwin@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+
+#include "calendar.h"
+
+static char *showflags(int flags);
+static int isonlydigits(char *s, int nostar);
+static const char *getmonthname(int i);
+static int checkmonth(char *s, size_t *len, size_t *offset, const char **month);
+static const char *getdayofweekname(int i);
+static int checkdayofweek(char *s, size_t *len, size_t *offset, const char **dow);
+static int indextooffset(char *s);
+static int parseoffset(char *s);
+static char *floattoday(int year, double f);
+static char *floattotime(double f);
+
+/*
+ * Expected styles:
+ *
+ * Date ::= Month . ' ' . DayOfMonth |
+ * Month . ' ' . DayOfWeek . ModifierIndex |
+ * Month . '/' . DayOfMonth |
+ * Month . '/' . DayOfWeek . ModifierIndex |
+ * DayOfMonth . ' ' . Month |
+ * DayOfMonth . '/' . Month |
+ * DayOfWeek . ModifierIndex . ' ' .Month |
+ * DayOfWeek . ModifierIndex . '/' .Month |
+ * DayOfWeek . ModifierIndex |
+ * SpecialDay . ModifierOffset
+ *
+ * Month ::= MonthName | MonthNumber | '*'
+ * MonthNumber ::= '0' ... '9' | '00' ... '09' | '10' ... '12'
+ * MonthName ::= MonthNameShort | MonthNameLong
+ * MonthNameLong ::= 'January' ... 'December'
+ * MonthNameShort ::= 'Jan' ... 'Dec' | 'Jan.' ... 'Dec.'
+ *
+ * DayOfWeek ::= DayOfWeekShort | DayOfWeekLong
+ * DayOfWeekShort ::= 'Mon' .. 'Sun'
+ * DayOfWeekLong ::= 'Monday' .. 'Sunday'
+ * DayOfMonth ::= '0' ... '9' | '00' ... '09' | '10' ... '29' |
+ * '30' ... '31' | '*'
+ *
+ * ModifierOffset ::= '' | '+' . ModifierNumber | '-' . ModifierNumber
+ * ModifierNumber ::= '0' ... '9' | '00' ... '99' | '000' ... '299' |
+ * '300' ... '359' | '360' ... '365'
+ * ModifierIndex ::= 'Second' | 'Third' | 'Fourth' | 'Fifth' |
+ * 'First' | 'Last'
+ *
+ * SpecialDay ::= 'Easter' | 'Pashka' | 'ChineseNewYear'
+ *
+ */
+static int
+determinestyle(char *date, int *flags,
+ char *month, int *imonth, char *dayofmonth, int *idayofmonth,
+ char *dayofweek, int *idayofweek, char *modifieroffset,
+ char *modifierindex, char *specialday)
+{
+ char *p, *p1, *p2;
+ const char *dow, *pmonth;
+ char pold;
+ size_t len, offset;
+
+ *flags = F_NONE;
+ *month = '\0';
+ *imonth = 0;
+ *dayofmonth = '\0';
+ *idayofmonth = 0;
+ *dayofweek = '\0';
+ *idayofweek = 0;
+ *modifieroffset = '\0';
+ *modifierindex = '\0';
+ *specialday = '\0';
+
+#define CHECKSPECIAL(s1, s2, lens2, type) \
+ if (s2 != NULL && strncmp(s1, s2, lens2) == 0) { \
+ *flags |= F_SPECIALDAY; \
+ *flags |= type; \
+ *flags |= F_VARIABLE; \
+ if (strlen(s1) == lens2) { \
+ strcpy(specialday, s1); \
+ return (1); \
+ } \
+ strncpy(specialday, s1, lens2); \
+ specialday[lens2] = '\0'; \
+ strcpy(modifieroffset, s1 + lens2); \
+ *flags |= F_MODIFIEROFFSET; \
+ return (1); \
+ }
+
+ if ((p = strchr(date, ' ')) == NULL) {
+ if ((p = strchr(date, '/')) == NULL) {
+ CHECKSPECIAL(date, STRING_CNY, strlen(STRING_CNY),
+ F_CNY);
+ CHECKSPECIAL(date, ncny.name, ncny.len, F_CNY);
+ CHECKSPECIAL(date, STRING_NEWMOON,
+ strlen(STRING_NEWMOON), F_NEWMOON);
+ CHECKSPECIAL(date, nnewmoon.name, nnewmoon.len,
+ F_NEWMOON);
+ CHECKSPECIAL(date, STRING_FULLMOON,
+ strlen(STRING_FULLMOON), F_FULLMOON);
+ CHECKSPECIAL(date, nfullmoon.name, nfullmoon.len,
+ F_FULLMOON);
+ CHECKSPECIAL(date, STRING_PASKHA,
+ strlen(STRING_PASKHA), F_PASKHA);
+ CHECKSPECIAL(date, npaskha.name, npaskha.len, F_PASKHA);
+ CHECKSPECIAL(date, STRING_EASTER,
+ strlen(STRING_EASTER), F_EASTER);
+ CHECKSPECIAL(date, neaster.name, neaster.len, F_EASTER);
+ CHECKSPECIAL(date, STRING_MAREQUINOX,
+ strlen(STRING_MAREQUINOX), F_MAREQUINOX);
+ CHECKSPECIAL(date, nmarequinox.name, nmarequinox.len,
+ F_SEPEQUINOX);
+ CHECKSPECIAL(date, STRING_SEPEQUINOX,
+ strlen(STRING_SEPEQUINOX), F_SEPEQUINOX);
+ CHECKSPECIAL(date, nsepequinox.name, nsepequinox.len,
+ F_SEPEQUINOX);
+ CHECKSPECIAL(date, STRING_JUNSOLSTICE,
+ strlen(STRING_JUNSOLSTICE), F_JUNSOLSTICE);
+ CHECKSPECIAL(date, njunsolstice.name, njunsolstice.len,
+ F_JUNSOLSTICE);
+ CHECKSPECIAL(date, STRING_DECSOLSTICE,
+ strlen(STRING_DECSOLSTICE), F_DECSOLSTICE);
+ CHECKSPECIAL(date, ndecsolstice.name, ndecsolstice.len,
+ F_DECSOLSTICE);
+ if (checkdayofweek(date, &len, &offset, &dow) != 0) {
+ *flags |= F_DAYOFWEEK;
+ *flags |= F_VARIABLE;
+ *idayofweek = offset;
+ if (strlen(date) == len) {
+ strcpy(dayofweek, date);
+ return (1);
+ }
+ strncpy(dayofweek, date, len);
+ dayofweek[len] = '\0';
+ strcpy(modifierindex, date + len);
+ *flags |= F_MODIFIERINDEX;
+ return (1);
+ }
+ if (isonlydigits(date, 1)) {
+ /* Assume month number only */
+ *flags |= F_MONTH;
+ *imonth = (int)strtol(date, (char **)NULL, 10);
+ strcpy(month, getmonthname(*imonth));
+ return(1);
+ }
+ return (0);
+ }
+ }
+
+ /*
+ * AFTER this, leave by goto-ing to "allfine" or "fail" to restore the
+ * original data in `date'.
+ */
+ pold = *p;
+ *p = 0;
+ p1 = date;
+ p2 = p + 1;
+ /* Now p2 points to the next field and p1 to the first field */
+
+ /* Check if there is a month-string in the date */
+ if ((checkmonth(p1, &len, &offset, &pmonth) != 0)
+ || (checkmonth(p2, &len, &offset, &pmonth) != 0 && (p2 = p1))) {
+ /* p2 is the non-month part */
+ *flags |= F_MONTH;
+ *imonth = offset;
+
+ strcpy(month, getmonthname(offset));
+ if (isonlydigits(p2, 1)) {
+ strcpy(dayofmonth, p2);
+ *idayofmonth = (int)strtol(p2, (char **)NULL, 10);
+ *flags |= F_DAYOFMONTH;
+ goto allfine;
+ }
+ if (strcmp(p2, "*") == 0) {
+ *flags |= F_ALLDAY;
+ goto allfine;
+ }
+
+ if (checkdayofweek(p2, &len, &offset, &dow) != 0) {
+ *flags |= F_DAYOFWEEK;
+ *flags |= F_VARIABLE;
+ *idayofweek = offset;
+ strcpy(dayofweek, getdayofweekname(offset));
+ if (strlen(p2) == len)
+ goto allfine;
+ strcpy(modifierindex, p2 + len);
+ *flags |= F_MODIFIERINDEX;
+ goto allfine;
+ }
+
+ goto fail;
+ }
+
+ /* Check if there is an every-day or every-month in the string */
+ if ((strcmp(p1, "*") == 0 && isonlydigits(p2, 1))
+ || (strcmp(p2, "*") == 0 && isonlydigits(p1, 1) && (p2 = p1))) {
+ int d;
+
+ *flags |= F_ALLMONTH;
+ *flags |= F_DAYOFMONTH;
+ d = (int)strtol(p2, (char **)NULL, 10);
+ *idayofmonth = d;
+ sprintf(dayofmonth, "%d", d);
+ goto allfine;
+ }
+
+ /* Month as a number, then a weekday */
+ if (isonlydigits(p1, 1)
+ && checkdayofweek(p2, &len, &offset, &dow) != 0) {
+ int d;
+
+ *flags |= F_MONTH;
+ *flags |= F_DAYOFWEEK;
+ *flags |= F_VARIABLE;
+
+ *idayofweek = offset;
+ d = (int)strtol(p1, (char **)NULL, 10);
+ *imonth = d;
+ strcpy(month, getmonthname(d));
+
+ strcpy(dayofweek, getdayofweekname(offset));
+ if (strlen(p2) == len)
+ goto allfine;
+ strcpy(modifierindex, p2 + len);
+ *flags |= F_MODIFIERINDEX;
+ goto allfine;
+ }
+
+ /* If both the month and date are specified as numbers */
+ if (isonlydigits(p1, 1) && isonlydigits(p2, 0)) {
+ /* Now who wants to be this ambigious? :-( */
+ int m, d;
+
+ if (strchr(p2, '*') != NULL)
+ *flags |= F_VARIABLE;
+
+ m = (int)strtol(p1, (char **)NULL, 10);
+ d = (int)strtol(p2, (char **)NULL, 10);
+
+ *flags |= F_MONTH;
+ *flags |= F_DAYOFMONTH;
+
+ if (m > 12) {
+ *imonth = d;
+ *idayofmonth = m;
+ strcpy(month, getmonthname(d));
+ sprintf(dayofmonth, "%d", m);
+ } else {
+ *imonth = m;
+ *idayofmonth = d;
+ strcpy(month, getmonthname(m));
+ sprintf(dayofmonth, "%d", d);
+ }
+ goto allfine;
+ }
+
+ /* FALLTHROUGH */
+fail:
+ *p = pold;
+ return (0);
+allfine:
+ *p = pold;
+ return (1);
+
+}
+
+static void
+remember(int *rememberindex, int *y, int *m, int *d, char **ed, int yy, int mm,
+ int dd, char *extra)
+{
+ static int warned = 0;
+
+ if (*rememberindex >= MAXCOUNT - 1) {
+ if (warned == 0)
+ warnx("Index > %d, ignored", MAXCOUNT);
+ warned++;
+ return;
+ }
+ y[*rememberindex] = yy;
+ m[*rememberindex] = mm;
+ d[*rememberindex] = dd;
+ if (extra != NULL)
+ strcpy(ed[*rememberindex], extra);
+ else
+ ed[*rememberindex][0] = '\0';
+ *rememberindex += 1;
+}
+
+static void
+debug_determinestyle(int dateonly, char *date, int flags, char *month,
+ int imonth, char *dayofmonth, int idayofmonth, char *dayofweek,
+ int idayofweek, char *modifieroffset, char *modifierindex, char *specialday)
+{
+
+ if (dateonly != 0) {
+ printf("-------\ndate: |%s|\n", date);
+ if (dateonly == 1)
+ return;
+ }
+ printf("flags: %x - %s\n", flags, showflags(flags));
+ if (modifieroffset[0] != '\0')
+ printf("modifieroffset: |%s|\n", modifieroffset);
+ if (modifierindex[0] != '\0')
+ printf("modifierindex: |%s|\n", modifierindex);
+ if (month[0] != '\0')
+ printf("month: |%s| (%d)\n", month, imonth);
+ if (dayofmonth[0] != '\0')
+ printf("dayofmonth: |%s| (%d)\n", dayofmonth, idayofmonth);
+ if (dayofweek[0] != '\0')
+ printf("dayofweek: |%s| (%d)\n", dayofweek, idayofweek);
+ if (specialday[0] != '\0')
+ printf("specialday: |%s|\n", specialday);
+}
+
+struct yearinfo {
+ int year;
+ int ieaster, ipaskha, firstcnyday;
+ double ffullmoon[MAXMOONS], fnewmoon[MAXMOONS];
+ double ffullmooncny[MAXMOONS], fnewmooncny[MAXMOONS];
+ int ichinesemonths[MAXMOONS];
+ double equinoxdays[2], solsticedays[2];
+ int *mondays;
+ struct yearinfo *next;
+};
+/*
+ * Possible date formats include any combination of:
+ * 3-charmonth (January, Jan, Jan)
+ * 3-charweekday (Friday, Monday, mon.)
+ * numeric month or day (1, 2, 04)
+ *
+ * Any character may separate them, or they may not be separated. Any line,
+ * following a line that is matched, that starts with "whitespace", is shown
+ * along with the matched line.
+ */
+int
+parsedaymonth(char *date, int *yearp, int *monthp, int *dayp, int *flags,
+ char **edp)
+{
+ char month[100], dayofmonth[100], dayofweek[100], modifieroffset[100];
+ char modifierindex[100], specialday[100];
+ int idayofweek = -1, imonth = -1, idayofmonth = -1, year, remindex;
+ int d, m, dow, rm, rd, offset;
+ char *ed;
+ int retvalsign = 1;
+
+ static struct yearinfo *years, *yearinfo;
+
+ /*
+ * CONVENTION
+ *
+ * Month: 1-12
+ * Monthname: Jan .. Dec
+ * Day: 1-31
+ * Weekday: Mon .. Sun
+ *
+ */
+
+ *flags = 0;
+
+ if (debug)
+ debug_determinestyle(1, date, *flags, month, imonth,
+ dayofmonth, idayofmonth, dayofweek, idayofweek,
+ modifieroffset, modifierindex, specialday);
+ if (determinestyle(date, flags, month, &imonth, dayofmonth,
+ &idayofmonth, dayofweek, &idayofweek, modifieroffset,
+ modifierindex, specialday) == 0) {
+ if (debug)
+ printf("Failed!\n");
+ return (0);
+ }
+
+ if (debug)
+ debug_determinestyle(0, date, *flags, month, imonth,
+ dayofmonth, idayofmonth, dayofweek, idayofweek,
+ modifieroffset, modifierindex, specialday);
+
+ remindex = 0;
+ for (year = year1; year <= year2; year++) {
+ /* Get important dates for this year */
+ yearinfo = years;
+ while (yearinfo != NULL) {
+ if (yearinfo->year == year)
+ break;
+ yearinfo = yearinfo -> next;
+ }
+ if (yearinfo == NULL) {
+ yearinfo = (struct yearinfo *)calloc(1,
+ sizeof(struct yearinfo));
+ if (yearinfo == NULL)
+ errx(1, "Unable to allocate more years");
+ yearinfo->year = year;
+ yearinfo->next = years;
+ years = yearinfo;
+
+ yearinfo->mondays = mondaytab[isleap(year)];
+ yearinfo->ieaster = easter(year);
+ fpom(year, UTCOffset, yearinfo->ffullmoon,
+ yearinfo->fnewmoon);
+ fpom(year, UTCOFFSET_CNY, yearinfo->ffullmooncny,
+ yearinfo->fnewmooncny);
+ fequinoxsolstice(year, UTCOffset,
+ yearinfo->equinoxdays, yearinfo->solsticedays);
+
+ /*
+ * CNY: Match day with sun longitude at 330` with new
+ * moon
+ */
+ yearinfo->firstcnyday = calculatesunlongitude30(year,
+ UTCOFFSET_CNY, yearinfo->ichinesemonths);
+ for (m = 0; yearinfo->fnewmooncny[m] >= 0; m++) {
+ if (yearinfo->fnewmooncny[m] >
+ yearinfo->firstcnyday) {
+ yearinfo->firstcnyday =
+ floor(yearinfo->fnewmooncny[m - 1]);
+ break;
+ }
+ }
+ }
+
+ /* Same day every year */
+ if (*flags == (F_MONTH | F_DAYOFMONTH)) {
+ if (!remember_ymd(year, imonth, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, imonth, idayofmonth, NULL);
+ continue;
+ }
+
+ /* XXX Same day every year, but variable */
+ if (*flags == (F_MONTH | F_DAYOFMONTH | F_VARIABLE)) {
+ if (!remember_ymd(year, imonth, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, imonth, idayofmonth, NULL);
+ continue;
+ }
+
+ /* Same day every month */
+ if (*flags == (F_ALLMONTH | F_DAYOFMONTH)) {
+ for (m = 1; m <= 12; m++) {
+ if (!remember_ymd(year, m, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, m, idayofmonth, NULL);
+ }
+ continue;
+ }
+
+ /* Every day of a month */
+ if (*flags == (F_ALLDAY | F_MONTH)) {
+ for (d = 1; d <= yearinfo->mondays[imonth]; d++) {
+ if (!remember_ymd(year, imonth, d))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ }
+ continue;
+ }
+
+ /* One day of every month */
+ if (*flags == (F_ALLMONTH | F_DAYOFWEEK)) {
+ for (m = 1; m <= 12; m++) {
+ if (!remember_ymd(year, m, idayofmonth))
+ continue;
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, m, idayofmonth, NULL);
+ }
+ continue;
+ }
+
+ /* Every dayofweek of the year */
+ if (*flags == (F_DAYOFWEEK | F_VARIABLE)) {
+ dow = first_dayofweek_of_year(year);
+ d = (idayofweek - dow + 8) % 7;
+ while (d <= 366) {
+ if (remember_yd(year, d, &rm, &rd))
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ d += 7;
+ }
+ continue;
+ }
+
+ /* A certain dayofweek of a month */
+ if (*flags ==
+ (F_MONTH | F_DAYOFWEEK | F_MODIFIERINDEX | F_VARIABLE)) {
+ offset = indextooffset(modifierindex);
+ dow = first_dayofweek_of_month(year, imonth);
+ d = (idayofweek - dow + 8) % 7;
+
+ if (offset > 0) {
+ while (d <= yearinfo->mondays[imonth]) {
+ if (--offset == 0
+ && remember_ymd(year, imonth, d)) {
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ continue;
+ }
+ d += 7;
+ }
+ continue;
+ }
+ if (offset < 0) {
+ while (d <= yearinfo->mondays[imonth])
+ d += 7;
+ while (offset != 0) {
+ offset++;
+ d -= 7;
+ }
+ if (remember_ymd(year, imonth, d))
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ continue;
+ }
+ continue;
+ }
+
+ /* Every dayofweek of the month */
+ if (*flags == (F_DAYOFWEEK | F_MONTH | F_VARIABLE)) {
+ dow = first_dayofweek_of_month(year, imonth);
+ d = (idayofweek - dow + 8) % 7;
+ while (d <= yearinfo->mondays[imonth]) {
+ if (remember_ymd(year, imonth, d))
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, imonth, d, NULL);
+ d += 7;
+ }
+ continue;
+ }
+
+ /* Easter */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_EASTER)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->ieaster + offset,
+ &rm, &rd))
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ continue;
+ }
+
+ /* Paskha */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_PASKHA)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->ipaskha + offset,
+ &rm, &rd))
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ continue;
+ }
+
+ /* Chinese New Year */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_CNY)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->firstcnyday + offset,
+ &rm, &rd))
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, NULL);
+ continue;
+ }
+
+ /* FullMoon */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_FULLMOON)) {
+ int i;
+
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ for (i = 0; yearinfo->ffullmoon[i] > 0; i++) {
+ if (remember_yd(year,
+ floor(yearinfo->ffullmoon[i]) + offset,
+ &rm, &rd)) {
+ ed = floattotime(
+ yearinfo->ffullmoon[i]);
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ }
+ continue;
+ }
+
+ /* NewMoon */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_NEWMOON)) {
+ int i;
+
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ for (i = 0; yearinfo->ffullmoon[i] > 0; i++) {
+ if (remember_yd(year,
+ floor(yearinfo->fnewmoon[i]) + offset,
+ &rm, &rd)) {
+ ed = floattotime(yearinfo->fnewmoon[i]);
+ remember(&remindex,
+ yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ }
+ continue;
+ }
+
+ /* (Mar|Sep)Equinox */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_MAREQUINOX)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->equinoxdays[0] + offset,
+ &rm, &rd)) {
+ ed = floattotime(yearinfo->equinoxdays[0]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_SEPEQUINOX)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year, yearinfo->equinoxdays[1] + offset,
+ &rm, &rd)) {
+ ed = floattotime(yearinfo->equinoxdays[1]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+
+ /* (Jun|Dec)Solstice */
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_JUNSOLSTICE)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year,
+ yearinfo->solsticedays[0] + offset, &rm, &rd)) {
+ ed = floattotime(yearinfo->solsticedays[0]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+ if ((*flags & ~F_MODIFIEROFFSET) ==
+ (F_SPECIALDAY | F_VARIABLE | F_DECSOLSTICE)) {
+ offset = 0;
+ if ((*flags & F_MODIFIEROFFSET) != 0)
+ offset = parseoffset(modifieroffset);
+ if (remember_yd(year,
+ yearinfo->solsticedays[1] + offset, &rm, &rd)) {
+ ed = floattotime(yearinfo->solsticedays[1]);
+ remember(&remindex, yearp, monthp, dayp, edp,
+ year, rm, rd, ed);
+ }
+ continue;
+ }
+
+ printf("Unprocessed:\n");
+ debug_determinestyle(2, date, *flags, month, imonth,
+ dayofmonth, idayofmonth, dayofweek, idayofweek,
+ modifieroffset, modifierindex, specialday);
+ retvalsign = -1;
+ }
+
+ if (retvalsign == -1)
+ return (-remindex - 1);
+ else
+ return (remindex);
+}
+
+static char *
+showflags(int flags)
+{
+ static char s[1000];
+ s[0] = '\0';
+
+ if ((flags & F_MONTH) != 0)
+ strcat(s, "month ");
+ if ((flags & F_DAYOFWEEK) != 0)
+ strcat(s, "dayofweek ");
+ if ((flags & F_DAYOFMONTH) != 0)
+ strcat(s, "dayofmonth ");
+ if ((flags & F_MODIFIERINDEX) != 0)
+ strcat(s, "modifierindex ");
+ if ((flags & F_MODIFIEROFFSET) != 0)
+ strcat(s, "modifieroffset ");
+ if ((flags & F_SPECIALDAY) != 0)
+ strcat(s, "specialday ");
+ if ((flags & F_ALLMONTH) != 0)
+ strcat(s, "allmonth ");
+ if ((flags & F_ALLDAY) != 0)
+ strcat(s, "allday ");
+ if ((flags & F_VARIABLE) != 0)
+ strcat(s, "variable ");
+ if ((flags & F_CNY) != 0)
+ strcat(s, "chinesenewyear ");
+ if ((flags & F_PASKHA) != 0)
+ strcat(s, "paskha ");
+ if ((flags & F_EASTER) != 0)
+ strcat(s, "easter ");
+ if ((flags & F_FULLMOON) != 0)
+ strcat(s, "fullmoon ");
+ if ((flags & F_NEWMOON) != 0)
+ strcat(s, "newmoon ");
+ if ((flags & F_MAREQUINOX) != 0)
+ strcat(s, "marequinox ");
+ if ((flags & F_SEPEQUINOX) != 0)
+ strcat(s, "sepequinox ");
+ if ((flags & F_JUNSOLSTICE) != 0)
+ strcat(s, "junsolstice ");
+ if ((flags & F_DECSOLSTICE) != 0)
+ strcat(s, "decsolstice ");
+
+ return s;
+}
+
+static const char *
+getmonthname(int i)
+{
+ if (nmonths[i - 1].len != 0 && nmonths[i - 1].name != NULL)
+ return (nmonths[i - 1].name);
+ return (months[i - 1]);
+}
+
+static int
+checkmonth(char *s, size_t *len, size_t *offset, const char **month)
+{
+ struct fixs *n;
+ int i;
+
+ for (i = 0; fnmonths[i].name != NULL; i++) {
+ n = fnmonths + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *month = n->name;
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ for (i = 0; nmonths[i].name != NULL; i++) {
+ n = nmonths + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *month = n->name;
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ for (i = 0; fmonths[i] != NULL; i++) {
+ *len = strlen(fmonths[i]);
+ if (strncasecmp(s, fmonths[i], *len) == 0) {
+ *month = fmonths[i];
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ for (i = 0; months[i] != NULL; i++) {
+ if (strncasecmp(s, months[i], 3) == 0) {
+ *len = 3;
+ *month = months[i];
+ *offset = i + 1;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static const char *
+getdayofweekname(int i)
+{
+ if (ndays[i].len != 0 && ndays[i].name != NULL)
+ return (ndays[i].name);
+ return (days[i]);
+}
+
+static int
+checkdayofweek(char *s, size_t *len, size_t *offset, const char **dow)
+{
+ struct fixs *n;
+ int i;
+
+ for (i = 0; fndays[i].name != NULL; i++) {
+ n = fndays + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *dow = n->name;
+ *offset = i;
+ return (1);
+ }
+ }
+ for (i = 0; ndays[i].name != NULL; i++) {
+ n = ndays + i;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ *len = n->len;
+ *dow = n->name;
+ *offset = i;
+ return (1);
+ }
+ }
+ for (i = 0; fdays[i] != NULL; i++) {
+ *len = strlen(fdays[i]);
+ if (strncasecmp(s, fdays[i], *len) == 0) {
+ *dow = fdays[i];
+ *offset = i;
+ return (1);
+ }
+ }
+ for (i = 0; days[i] != NULL; i++) {
+ if (strncasecmp(s, days[i], 3) == 0) {
+ *len = 3;
+ *dow = days[i];
+ *offset = i;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+static int
+isonlydigits(char *s, int nostar)
+{
+ int i;
+ for (i = 0; s[i] != '\0'; i++) {
+ if (nostar == 0 && s[i] == '*' && s[i + 1] == '\0')
+ return 1;
+ if (!isdigit(s[i]))
+ return (0);
+ }
+ return (1);
+}
+
+static int
+indextooffset(char *s)
+{
+ int i;
+ struct fixs *n;
+
+ for (i = 0; i < 6; i++) {
+ if (strcasecmp(s, sequences[i]) == 0) {
+ if (i == 5)
+ return (-1);
+ return (i + 1);
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ n = nsequences + i;
+ if (n->len == 0)
+ continue;
+ if (strncasecmp(s, n->name, n->len) == 0) {
+ if (i == 5)
+ return (-1);
+ return (i + 1);
+ }
+ }
+ return (0);
+}
+
+static int
+parseoffset(char *s)
+{
+
+ return strtol(s, NULL, 10);
+}
+
+static char *
+floattotime(double f)
+{
+ static char buf[100];
+ int hh, mm, ss, i;
+
+ f -= floor(f);
+ i = f * SECSPERDAY;
+
+ hh = i / SECSPERHOUR;
+ i %= SECSPERHOUR;
+ mm = i / SECSPERMINUTE;
+ i %= SECSPERMINUTE;
+ ss = i;
+
+ sprintf(buf, "%02d:%02d:%02d", hh, mm, ss);
+ return (buf);
+}
+
+static char *
+floattoday(int year, double f)
+{
+ static char buf[100];
+ int i, m, d, hh, mm, ss;
+ int *cumdays = cumdaytab[isleap(year)];
+
+ for (i = 0; 1 + cumdays[i] < f; i++)
+ ;;
+ m = --i;
+ d = floor(f - 1 - cumdays[i]);
+ f -= floor(f);
+ i = f * SECSPERDAY;
+
+ hh = i / SECSPERHOUR;
+ i %= SECSPERHOUR;
+ mm = i / SECSPERMINUTE;
+ i %= SECSPERMINUTE;
+ ss = i;
+
+ sprintf(buf, "%02d-%02d %02d:%02d:%02d", m, d, hh, mm, ss);
+ return (buf);
+}
+
+void
+dodebug(char *what)
+{
+ int year;
+
+ printf("UTCOffset: %g\n", UTCOffset);
+ printf("eastlongitude: %d\n", EastLongitude);
+
+ if (strcmp(what, "moon") == 0) {
+ double ffullmoon[MAXMOONS], fnewmoon[MAXMOONS];
+ int i;
+
+ for (year = year1; year <= year2; year++) {
+ fpom(year, UTCOffset, ffullmoon, fnewmoon);
+ printf("Full moon %d:\t", year);
+ for (i = 0; ffullmoon[i] >= 0; i++) {
+ printf("%g (%s) ", ffullmoon[i],
+ floattoday(year, ffullmoon[i]));
+ }
+ printf("\nNew moon %d:\t", year);
+ for (i = 0; fnewmoon[i] >= 0; i++) {
+ printf("%g (%s) ", fnewmoon[i],
+ floattoday(year, fnewmoon[i]));
+ }
+ printf("\n");
+
+ }
+
+ return;
+ }
+
+ if (strcmp(what, "sun") == 0) {
+ double equinoxdays[2], solsticedays[2];
+ for (year = year1; year <= year2; year++) {
+ printf("Sun in %d:\n", year);
+ fequinoxsolstice(year, UTCOffset, equinoxdays,
+ solsticedays);
+ printf("e[0] - %g (%s)\n",
+ equinoxdays[0],
+ floattoday(year, equinoxdays[0]));
+ printf("e[1] - %g (%s)\n",
+ equinoxdays[1],
+ floattoday(year, equinoxdays[1]));
+ printf("s[0] - %g (%s)\n",
+ solsticedays[0],
+ floattoday(year, solsticedays[0]));
+ printf("s[1] - %g (%s)\n",
+ solsticedays[1],
+ floattoday(year, solsticedays[1]));
+ }
+ return;
+ }
+}
diff --git a/usr.bin/calendar/paskha.c b/usr.bin/calendar/paskha.c
index e713f5f..373ee5d 100644
--- a/usr.bin/calendar/paskha.c
+++ b/usr.bin/calendar/paskha.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (C) 1993-1996 by Andrey A. Chernov, Moscow, Russia.
* All rights reserved.
*
@@ -36,55 +36,22 @@ __FBSDID("$FreeBSD$");
#define PASKHA "paskha"
#define PASKHALEN (sizeof(PASKHA) - 1)
-static int paskha(int);
-
/* return year day for Orthodox Easter using Gauss formula */
/* (old style result) */
-static int
+int
paskha(int R) /*year*/
{
int a, b, c, d, e;
static int x = 15;
static int y = 6;
+ int *cumday;
a = R % 19;
b = R % 4;
c = R % 7;
d = (19 * a + x) % 30;
e = (2 * b + 4 * c + 6 * d + y) % 7;
- return (((cumdays[3] + 1) + 22) + (d + e));
-}
-
-/* return year day for Orthodox Easter depending days */
-
-int
-getpaskha(char *s, int year)
-{
- int offset;
-
- if (strncasecmp(s, PASKHA, PASKHALEN) == 0)
- s += PASKHALEN;
- else if (npaskha.name != NULL
- && strncasecmp(s, npaskha.name, npaskha.len) == 0)
- s += npaskha.len;
- else
- return 0;
-
- /* Paskha+1 or Paskha-2
- * ^ ^ */
-
- switch (*s) {
-
- case '-':
- case '+':
- offset = atoi(s);
- break;
-
- default:
- offset = 0;
- break;
- }
-
- return (paskha(year) + offset + 13 /* new style */);
+ cumday = cumdaytab[isleap(R)];
+ return (((cumday[3] + 1) + 22) + (d + e));
}
diff --git a/usr.bin/calendar/pathnames.h b/usr.bin/calendar/pathnames.h
index cacbd25..ea76948 100644
--- a/usr.bin/calendar/pathnames.h
+++ b/usr.bin/calendar/pathnames.h
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -10,10 +10,6 @@
* 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. 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.
diff --git a/usr.bin/calendar/pom.c b/usr.bin/calendar/pom.c
new file mode 100644
index 0000000..89d06a2
--- /dev/null
+++ b/usr.bin/calendar/pom.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software posted to USENET.
+ *
+ * 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.
+ * 4. 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.
+ */
+
+#if 0
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static const char sccsid[] = "@(#)pom.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Phase of the Moon. Calculates the current phase of the moon.
+ * Based on routines from `Practical Astronomy with Your Calculator',
+ * by Duffett-Smith. Comments give the section from the book that
+ * particular piece of code was adapted from.
+ *
+ * -- Keith E. Brandt VIII 1984
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "calendar.h"
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+#define EPOCH 85
+#define EPSILONg 279.611371 /* solar ecliptic long at EPOCH */
+#define RHOg 282.680403 /* solar ecliptic long of perigee at EPOCH */
+#define ECCEN 0.01671542 /* solar orbit eccentricity */
+#define lzero 18.251907 /* lunar mean long at EPOCH */
+#define Pzero 192.917585 /* lunar mean long of perigee at EPOCH */
+#define Nzero 55.204723 /* lunar mean long of node at EPOCH */
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+static void adj360(double *);
+static double dtor(double);
+static double potm(double onday);
+static double potm_minute(double onday, int olddir);
+
+void
+pom(int year, double utcoffset, int *fms, int *nms)
+{
+ double ffms[MAXMOONS];
+ double fnms[MAXMOONS];
+ int i, j;
+
+ fpom(year, utcoffset, ffms, fnms);
+
+ j = 0;
+ for (i = 0; ffms[i] != 0; i++)
+ fms[j++] = round(ffms[i]);
+ fms[i] = -1;
+ for (i = 0; fnms[i] != 0; i++)
+ nms[i] = round(fnms[i]);
+ nms[i] = -1;
+}
+
+void
+fpom(int year, double utcoffset, double *ffms, double *fnms)
+{
+ time_t tt;
+ struct tm GMT, tmd_today, tmd_tomorrow;
+ double days_today, days_tomorrow, today, tomorrow;
+ int cnt, d;
+ int yeardays;
+ int olddir, newdir;
+ double *pfnms, *pffms, t;
+
+ pfnms = fnms;
+ pffms = ffms;
+
+ /*
+ * We take the phase of the moon one second before and one second
+ * after midnight.
+ */
+ memset(&tmd_today, 0, sizeof(tmd_today));
+ tmd_today.tm_year = year - 1900;
+ tmd_today.tm_mon = 0;
+ tmd_today.tm_mday = -1; /* 31 December */
+ tmd_today.tm_hour = 23;
+ tmd_today.tm_min = 59;
+ tmd_today.tm_sec = 59;
+ memset(&tmd_tomorrow, 0, sizeof(tmd_tomorrow));
+ tmd_tomorrow.tm_year = year - 1900;
+ tmd_tomorrow.tm_mon = 0;
+ tmd_tomorrow.tm_mday = 0; /* 01 January */
+ tmd_tomorrow.tm_hour = 0;
+ tmd_tomorrow.tm_min = 0;
+ tmd_tomorrow.tm_sec = 1;
+
+ tt = mktime(&tmd_today);
+ gmtime_r(&tt, &GMT);
+ yeardays = 0;
+ for (cnt = EPOCH; cnt < GMT.tm_year; ++cnt)
+ yeardays += isleap(1900 + cnt) ? DAYSPERLEAPYEAR : DAYSPERYEAR;
+ days_today = (GMT.tm_yday + 1) + ((GMT.tm_hour +
+ (GMT.tm_min / FSECSPERMINUTE) + (GMT.tm_sec / FSECSPERHOUR)) /
+ FHOURSPERDAY);
+ days_today += yeardays;
+
+ tt = mktime(&tmd_tomorrow);
+ gmtime_r(&tt, &GMT);
+ yeardays = 0;
+ for (cnt = EPOCH; cnt < GMT.tm_year; ++cnt)
+ yeardays += isleap(1900 + cnt) ? DAYSPERLEAPYEAR : DAYSPERYEAR;
+ days_tomorrow = (GMT.tm_yday + 1) + ((GMT.tm_hour +
+ (GMT.tm_min / FSECSPERMINUTE) + (GMT.tm_sec / FSECSPERHOUR)) /
+ FHOURSPERDAY);
+ days_tomorrow += yeardays;
+
+ today = potm(days_today); /* 30 December 23:59:59 */
+ tomorrow = potm(days_tomorrow); /* 31 December 00:00:01 */
+ olddir = today > tomorrow ? -1 : +1;
+
+ yeardays = 1 + isleap(year) ? DAYSPERLEAPYEAR : DAYSPERYEAR; /* reuse */
+ for (d = 0; d <= yeardays; d++) {
+ today = potm(days_today);
+ tomorrow = potm(days_tomorrow);
+ newdir = today > tomorrow ? -1 : +1;
+ if (olddir != newdir) {
+ t = potm_minute(days_today - 1, olddir) +
+ utcoffset / FHOURSPERDAY;
+ if (olddir == -1 && newdir == +1) {
+ *pfnms = d - 1 + t;
+ pfnms++;
+ } else if (olddir == +1 && newdir == -1) {
+ *pffms = d - 1 + t;
+ pffms++;
+ }
+ }
+ olddir = newdir;
+ days_today++;
+ days_tomorrow++;
+ }
+ *pffms = -1;
+ *pfnms = -1;
+}
+
+static double
+potm_minute(double onday, int olddir) {
+ double period = FSECSPERDAY / 2.0;
+ double p1, p2;
+ double before, after;
+ int newdir;
+
+// printf("---> days:%g olddir:%d\n", days, olddir);
+
+ p1 = onday + (period / SECSPERDAY);
+ period /= 2;
+
+ while (period > 30) { /* half a minute */
+// printf("period:%g - p1:%g - ", period, p1);
+ p2 = p1 + (2.0 / SECSPERDAY);
+ before = potm(p1);
+ after = potm(p2);
+// printf("before:%10.10g - after:%10.10g\n", before, after);
+ newdir = before < after ? -1 : +1;
+ if (olddir != newdir)
+ p1 += (period / SECSPERDAY);
+ else
+ p1 -= (period / SECSPERDAY);
+ period /= 2;
+// printf("newdir:%d - p1:%10.10f - period:%g\n",
+// newdir, p1, period);
+ }
+ p1 -= floor(p1);
+ //exit(0);
+ return (p1);
+}
+
+/*
+ * potm --
+ * return phase of the moon, as a percentage [0 ... 100]
+ */
+static double
+potm(double onday)
+{
+ double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
+ double A4, lprime, V, ldprime, D, Nm;
+
+ N = 360 * onday / 365.2422; /* sec 42 #3 */
+ adj360(&N);
+ Msol = N + EPSILONg - RHOg; /* sec 42 #4 */
+ adj360(&Msol);
+ Ec = 360 / PI * ECCEN * sin(dtor(Msol)); /* sec 42 #5 */
+ LambdaSol = N + Ec + EPSILONg; /* sec 42 #6 */
+ adj360(&LambdaSol);
+ l = 13.1763966 * onday + lzero; /* sec 61 #4 */
+ adj360(&l);
+ Mm = l - (0.1114041 * onday) - Pzero; /* sec 61 #5 */
+ adj360(&Mm);
+ Nm = Nzero - (0.0529539 * onday); /* sec 61 #6 */
+ adj360(&Nm);
+ Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 61 #7 */
+ Ac = 0.1858 * sin(dtor(Msol)); /* sec 61 #8 */
+ A3 = 0.37 * sin(dtor(Msol));
+ Mmprime = Mm + Ev - Ac - A3; /* sec 61 #9 */
+ Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 61 #10 */
+ A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 61 #11 */
+ lprime = l + Ev + Ec - Ac + A4; /* sec 61 #12 */
+ V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 61 #13 */
+ ldprime = lprime + V; /* sec 61 #14 */
+ D = ldprime - LambdaSol; /* sec 63 #2 */
+ return(50 * (1 - cos(dtor(D)))); /* sec 63 #3 */
+}
+
+/*
+ * dtor --
+ * convert degrees to radians
+ */
+static double
+dtor(double deg)
+{
+
+ return(deg * PI / 180);
+}
+
+/*
+ * adj360 --
+ * adjust value so 0 <= deg <= 360
+ */
+static void
+adj360(double *deg)
+{
+
+ for (;;)
+ if (*deg < 0)
+ *deg += 360;
+ else if (*deg > 360)
+ *deg -= 360;
+ else
+ break;
+}
diff --git a/usr.bin/calendar/sunpos.c b/usr.bin/calendar/sunpos.c
new file mode 100644
index 0000000..a0546e5
--- /dev/null
+++ b/usr.bin/calendar/sunpos.c
@@ -0,0 +1,448 @@
+/*-
+ * Copyright (c) 2009-2010 Edwin Groothuis <edwin@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * This code is created to match the formulas available at:
+ * Formula and examples obtained from "How to Calculate alt/az: SAAO" at
+ * http://www.saao.ac.za/public-info/sun-moon-stars/sun-index/how-to-calculate-altaz/
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+#include <time.h>
+#include "calendar.h"
+
+#define D2R(m) ((m) / 180 * M_PI)
+#define R2D(m) ((m) * 180 / M_PI)
+
+#define SIN(x) (sin(D2R(x)))
+#define COS(x) (cos(D2R(x)))
+#define TAN(x) (tan(D2R(x)))
+#define ASIN(x) (R2D(asin(x)))
+#define ATAN(x) (R2D(atan(x)))
+
+#ifdef NOTDEF
+static void
+comp(char *s, double v, double c)
+{
+
+ printf("%-*s %*g %*g %*g\n", 15, s, 15, v, 15, c, 15, v - c);
+}
+
+int expY;
+double expZJ = 30.5;
+double expUTHM = 8.5;
+double expD = 34743.854;
+double expT = 0.9512349;
+double expL = 324.885;
+double expM = 42.029;
+double expepsilon = 23.4396;
+double explambda = 326.186;
+double expalpha = 328.428;
+double expDEC = -12.789;
+double expeastlongitude = 17.10;
+double explatitude = -22.57;
+double expHA = -37.673;
+double expALT = 49.822;
+double expAZ = 67.49;
+#endif
+
+static double
+fixup(double *d)
+{
+
+ if (*d < 0) {
+ while (*d < 0)
+ *d += 360;
+ } else {
+ while (*d > 360)
+ *d -= 360;
+ }
+
+ return (*d);
+}
+
+static double ZJtable[] = {
+ 0, -0.5, 30.5, 58.5, 89.5, 119.5, 150.5, 180.5, 211.5, 242.5, 272.5, 303.5, 333.5 };
+
+static void
+sunpos(int inYY, int inMM, int inDD, double UTCOFFSET, int inHOUR, int inMIN,
+ int inSEC, double eastlongitude, double latitude, double *L, double *DEC)
+{
+ int Y;
+ double ZJ, D, T, M, epsilon, lambda, alpha, HA, UTHM;
+
+ ZJ = ZJtable[inMM];
+ if (inMM <= 2 && isleap(inYY))
+ ZJ -= 1.0;
+
+ UTHM = inHOUR + inMIN / FMINSPERHOUR + inSEC / FSECSPERHOUR - UTCOFFSET;
+ Y = inYY - 1900; /* 1 */
+ D = floor(365.25 * Y) + ZJ + inDD + UTHM / FHOURSPERDAY; /* 3 */
+ T = D / 36525.0; /* 4 */
+ *L = 279.697 + 36000.769 * T; /* 5 */
+ fixup(L);
+ M = 358.476 + 35999.050 * T; /* 6 */
+ fixup(&M);
+ epsilon = 23.452 - 0.013 * T; /* 7 */
+ fixup(&epsilon);
+
+ lambda = *L + (1.919 - 0.005 * T) * SIN(M) + 0.020 * SIN(2 * M);/* 8 */
+ fixup(&lambda);
+ alpha = ATAN(TAN(lambda) * COS(epsilon)); /* 9 */
+
+ /* Alpha should be in the same quadrant as lamba */
+ {
+ int lssign = sin(D2R(lambda)) < 0 ? -1 : 1;
+ int lcsign = cos(D2R(lambda)) < 0 ? -1 : 1;
+ while (((sin(D2R(alpha)) < 0) ? -1 : 1) != lssign
+ || ((cos(D2R(alpha)) < 0) ? -1 : 1) != lcsign)
+ alpha += 90.0;
+ }
+ fixup(&alpha);
+
+ *DEC = ASIN(SIN(lambda) * SIN(epsilon)); /* 10 */
+ fixup(DEC);
+ fixup(&eastlongitude);
+ HA = *L - alpha + 180 + 15 * UTHM + eastlongitude; /* 12 */
+ fixup(&HA);
+ fixup(&latitude);
+#ifdef NOTDEF
+ printf("%02d/%02d %02d:%02d:%02d l:%g d:%g h:%g\n",
+ inMM, inDD, inHOUR, inMIN, inSEC, latitude, *DEC, HA);
+#endif
+ return;
+
+ /*
+ * The following calculations are not used, so to save time
+ * they are not calculated.
+ */
+#ifdef NOTDEF
+ *ALT = ASIN(SIN(latitude) * SIN(*DEC) +
+ COS(latitude) * COS(*DEC) * COS(HA)); /* 13 */
+ fixup(ALT);
+ *AZ = ATAN(SIN(HA) /
+ (COS(HA) * SIN(latitude) - TAN(*DEC) * COS(latitude))); /* 14 */
+
+ if (*ALT > 180)
+ *ALT -= 360;
+ if (*ALT < -180)
+ *ALT += 360;
+ printf("a:%g a:%g\n", *ALT, *AZ);
+#endif
+
+#ifdef NOTDEF
+ printf("Y:\t\t\t %d\t\t %d\t\t %d\n", Y, expY, Y - expY);
+ comp("ZJ", ZJ, expZJ);
+ comp("UTHM", UTHM, expUTHM);
+ comp("D", D, expD);
+ comp("T", T, expT);
+ comp("L", L, fixup(&expL));
+ comp("M", M, fixup(&expM));
+ comp("epsilon", epsilon, fixup(&expepsilon));
+ comp("lambda", lambda, fixup(&explambda));
+ comp("alpha", alpha, fixup(&expalpha));
+ comp("DEC", DEC, fixup(&expDEC));
+ comp("eastlongitude", eastlongitude, fixup(&expeastlongitude));
+ comp("latitude", latitude, fixup(&explatitude));
+ comp("HA", HA, fixup(&expHA));
+ comp("ALT", ALT, fixup(&expALT));
+ comp("AZ", AZ, fixup(&expAZ));
+#endif
+}
+
+
+#define SIGN(a) (((a) > 180) ? -1 : 1)
+#define ANGLE(a, b) (((a) < (b)) ? 1 : -1)
+#define SHOUR(s) ((s) / 3600)
+#define SMIN(s) (((s) % 3600) / 60)
+#define SSEC(s) ((s) % 60)
+#define HOUR(h) ((h) / 4)
+#define MIN(h) (15 * ((h) % 4))
+#define SEC(h) 0
+#define DEBUG1(y, m, d, hh, mm, pdec, dec) \
+ printf("%4d-%02d-%02d %02d:%02d:00 - %7.7g -> %7.7g\n", \
+ y, m, d, hh, mm, pdec, dec)
+#define DEBUG2(y, m, d, hh, mm, pdec, dec, pang, ang) \
+ printf("%4d-%02d-%02d %02d:%02d:00 - %7.7g -> %7.7g - %d -> %d\n", \
+ y, m, d, hh, mm, pdec, dec, pang, ang)
+void
+equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays)
+{
+ double fe[2], fs[2];
+
+ fequinoxsolstice(year, UTCoffset, fe, fs);
+ equinoxdays[0] = round(fe[0]);
+ equinoxdays[1] = round(fe[1]);
+ solsticedays[0] = round(fs[0]);
+ solsticedays[1] = round(fs[1]);
+}
+
+void
+fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays)
+{
+ double dec, prevdec, L;
+ int h, d, prevangle, angle;
+ int found = 0;
+
+ double decleft, decright, decmiddle;
+ int dial, s;
+
+ int *cumdays;
+ cumdays = cumdaytab[isleap(year)];
+
+ /*
+ * Find the first equinox, somewhere in March:
+ * It happens when the returned value "dec" goes from
+ * [350 ... 360> -> [0 ... 10]
+ */
+ found = 0;
+ prevdec = 350;
+ for (d = 18; d < 31; d++) {
+// printf("Comparing day %d to %d.\n", d, d+1);
+ sunpos(year, 3, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
+ sunpos(year, 3, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
+ &L, &decright);
+// printf("Found %g and %g.\n", decleft, decright);
+ if (SIGN(decleft) == SIGN(decright))
+ continue;
+
+ dial = SECSPERDAY;
+ s = SECSPERDAY / 2;
+ while (s > 0) {
+// printf("Obtaining %d (%02d:%02d)\n",
+// dial, SHOUR(dial), SMIN(dial));
+ sunpos(year, 3, d, UTCoffset,
+ SHOUR(dial), SMIN(dial), SSEC(dial),
+ 0.0, 0.0, &L, &decmiddle);
+// printf("Found %g\n", decmiddle);
+ if (SIGN(decleft) == SIGN(decmiddle)) {
+ decleft = decmiddle;
+ dial += s;
+ } else {
+ decright = decmiddle;
+ dial -= s;
+ }
+// printf("New boundaries: %g - %g\n", decleft, decright);
+
+ s /= 2;
+ }
+ equinoxdays[0] = 1 + cumdays[3] + d + (dial / FSECSPERDAY);
+ break;
+ }
+
+ /* Find the second equinox, somewhere in September:
+ * It happens when the returned value "dec" goes from
+ * [10 ... 0] -> <360 ... 350]
+ */
+ found = 0;
+ prevdec = 10;
+ for (d = 18; d < 31; d++) {
+// printf("Comparing day %d to %d.\n", d, d+1);
+ sunpos(year, 9, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
+ sunpos(year, 9, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
+ &L, &decright);
+// printf("Found %g and %g.\n", decleft, decright);
+ if (SIGN(decleft) == SIGN(decright))
+ continue;
+
+ dial = SECSPERDAY;
+ s = SECSPERDAY / 2;
+ while (s > 0) {
+// printf("Obtaining %d (%02d:%02d)\n",
+// dial, SHOUR(dial), SMIN(dial));
+ sunpos(year, 9, d, UTCoffset,
+ SHOUR(dial), SMIN(dial), SSEC(dial),
+ 0.0, 0.0, &L, &decmiddle);
+// printf("Found %g\n", decmiddle);
+ if (SIGN(decleft) == SIGN(decmiddle)) {
+ decleft = decmiddle;
+ dial += s;
+ } else {
+ decright = decmiddle;
+ dial -= s;
+ }
+// printf("New boundaries: %g - %g\n", decleft, decright);
+
+ s /= 2;
+ }
+ equinoxdays[1] = 1 + cumdays[9] + d + (dial / FSECSPERDAY);
+ break;
+ }
+
+ /*
+ * Find the first solstice, somewhere in June:
+ * It happens when the returned value "dec" peaks
+ * [40 ... 45] -> [45 ... 40]
+ */
+ found = 0;
+ prevdec = 0;
+ prevangle = 1;
+ for (d = 18; d < 31; d++) {
+ for (h = 0; h < 4 * HOURSPERDAY; h++) {
+ sunpos(year, 6, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
+ 0.0, 0.0, &L, &dec);
+ angle = ANGLE(prevdec, dec);
+ if (prevangle != angle) {
+#ifdef NOTDEF
+ DEBUG2(year, 6, d, HOUR(h), MIN(h),
+ prevdec, dec, prevangle, angle);
+#endif
+ solsticedays[0] = 1 + cumdays[6] + d +
+ ((h / 4.0) / 24.0);
+ found = 1;
+ break;
+ }
+ prevdec = dec;
+ prevangle = angle;
+ }
+ if (found)
+ break;
+ }
+
+ /*
+ * Find the second solstice, somewhere in December:
+ * It happens when the returned value "dec" peaks
+ * [315 ... 310] -> [310 ... 315]
+ */
+ found = 0;
+ prevdec = 360;
+ prevangle = -1;
+ for (d = 18; d < 31; d++) {
+ for (h = 0; h < 4 * HOURSPERDAY; h++) {
+ sunpos(year, 12, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
+ 0.0, 0.0, &L, &dec);
+ angle = ANGLE(prevdec, dec);
+ if (prevangle != angle) {
+#ifdef NOTDEF
+ DEBUG2(year, 12, d, HOUR(h), MIN(h),
+ prevdec, dec, prevangle, angle);
+#endif
+ solsticedays[1] = 1 + cumdays[12] + d +
+ ((h / 4.0) / 24.0);
+ found = 1;
+ break;
+ }
+ prevdec = dec;
+ prevangle = angle;
+ }
+ if (found)
+ break;
+ }
+
+ return;
+}
+
+int
+calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths)
+{
+ int m, d, h;
+ double dec;
+ double curL, prevL;
+ int *pichinesemonths, *monthdays, *cumdays, i;
+ int firstmonth330 = -1;
+
+ cumdays = cumdaytab[isleap(year)];
+ monthdays = mondaytab[isleap(year)];
+ pichinesemonths = ichinesemonths;
+
+ h = 0;
+ sunpos(year - 1, 12, 31,
+ -24 * (degreeGMToffset / 360.0),
+ HOUR(h), MIN(h), SEC(h), 0.0, 0.0, &prevL, &dec);
+
+ for (m = 1; m <= 12; m++) {
+ for (d = 1; d <= monthdays[m]; d++) {
+ for (h = 0; h < 4 * HOURSPERDAY; h++) {
+ sunpos(year, m, d,
+ -24 * (degreeGMToffset / 360.0),
+ HOUR(h), MIN(h), SEC(h),
+ 0.0, 0.0, &curL, &dec);
+ if (curL < 180 && prevL > 180) {
+ *pichinesemonths = cumdays[m] + d;
+#ifdef DEBUG
+printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
+ year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
+#endif
+ pichinesemonths++;
+ } else {
+ for (i = 0; i <= 360; i += 30)
+ if (curL > i && prevL < i) {
+ *pichinesemonths =
+ cumdays[m] + d;
+#ifdef DEBUG
+printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
+ year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
+#endif
+ if (i == 330)
+ firstmonth330 = *pichinesemonths;
+ pichinesemonths++;
+ }
+ }
+ prevL = curL;
+ }
+ }
+ }
+ *pichinesemonths = -1;
+ return (firstmonth330);
+}
+
+#ifdef NOTDEF
+int
+main(int argc, char **argv)
+{
+/*
+ year Mar June Sept Dec
+ day time day time day time day time
+ 2004 20 06:49 21 00:57 22 16:30 21 12:42
+ 2005 20 12:33 21 06:46 22 22:23 21 18:35
+ 2006 20 18:26 21 12:26 23 04:03 22 00:22
+ 2007 21 00:07 21 18:06 23 09:51 22 06:08
+ 2008 20 05:48 20 23:59 22 15:44 21 12:04
+ 2009 20 11:44 21 05:45 22 21:18 21 17:47
+ 2010 20 17:32 21 11:28 23 03:09 21 23:38
+ 2011 20 23:21 21 17:16 23 09:04 22 05:30
+ 2012 20 05:14 20 23:09 22 14:49 21 11:11
+ 2013 20 11:02 21 05:04 22 20:44 21 17:11
+ 2014 20 16:57 21 10:51 23 02:29 21 23:03
+ 2015 20 22:45 21 16:38 23 08:20 22 04:48
+ 2016 20 04:30 20 22:34 22 14:21 21 10:44
+ 2017 20 10:28 21 04:24 22 20:02 21 16:28
+*/
+
+ int eq[2], sol[2];
+ equinoxsolstice(strtol(argv[1], NULL, 10), 0.0, eq, sol);
+ printf("%d - %d - %d - %d\n", eq[0], sol[0], eq[1], sol[1]);
+ return(0);
+}
+#endif
diff --git a/usr.bin/chpass/Makefile b/usr.bin/chpass/Makefile
index 7f7ac51..a5571d7 100644
--- a/usr.bin/chpass/Makefile
+++ b/usr.bin/chpass/Makefile
@@ -43,7 +43,7 @@ beforeinstall:
.if !defined(NO_FSCHG)
afterinstall:
- chflags schg ${DESTDIR}${BINDIR}/chpass
+ -chflags schg ${DESTDIR}${BINDIR}/chpass
.endif
.include <bsd.prog.mk>
diff --git a/usr.bin/column/column.1 b/usr.bin/column/column.1
index 5c5a100..d4418c5 100644
--- a/usr.bin/column/column.1
+++ b/usr.bin/column/column.1
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd July 29, 2004
-.Os
.Dt COLUMN 1
+.Os
.Sh NAME
.Nm column
.Nd columnate lists
diff --git a/usr.bin/comm/comm.1 b/usr.bin/comm/comm.1
index 02b508c..67b5eec 100644
--- a/usr.bin/comm/comm.1
+++ b/usr.bin/comm/comm.1
@@ -36,8 +36,8 @@
.\" $FreeBSD$
.\"
.Dd December 12, 2009
-.Os
.Dt COMM 1
+.Os
.Sh NAME
.Nm comm
.Nd select or reject lines common to two files
diff --git a/usr.bin/comm/comm.c b/usr.bin/comm/comm.c
index afda0e7..ddad5dc 100644
--- a/usr.bin/comm/comm.c
+++ b/usr.bin/comm/comm.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <locale.h>
#include <stdint.h>
+#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -60,40 +61,31 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
#include <wctype.h>
-#define INITLINELEN (LINE_MAX + 1)
-#define MAXLINELEN ((SIZE_MAX / sizeof(wchar_t)) / 2)
-
-const wchar_t *tabs[] = { L"", L"\t", L"\t\t" };
+int iflag;
+const char *tabs[] = { "", "\t", "\t\t" };
FILE *file(const char *);
-wchar_t *getline(wchar_t *, size_t *, FILE *);
-void show(FILE *, const char *, const wchar_t *, wchar_t *, size_t *);
-int wcsicoll(const wchar_t *, const wchar_t *);
+wchar_t *convert(const char *);
+void show(FILE *, const char *, const char *, char **, size_t *);
static void usage(void);
int
main(int argc, char *argv[])
{
int comp, read1, read2;
- int ch, flag1, flag2, flag3, iflag;
+ int ch, flag1, flag2, flag3;
FILE *fp1, *fp2;
- const wchar_t *col1, *col2, *col3;
+ const char *col1, *col2, *col3;
size_t line1len, line2len;
- wchar_t *line1, *line2;
- const wchar_t **p;
-
- flag1 = flag2 = flag3 = 1;
- iflag = 0;
-
- line1len = INITLINELEN;
- line2len = INITLINELEN;
- line1 = malloc(line1len * sizeof(*line1));
- line2 = malloc(line2len * sizeof(*line2));
- if (line1 == NULL || line2 == NULL)
- err(1, "malloc");
+ char *line1, *line2;
+ ssize_t n1, n2;
+ wchar_t *tline1, *tline2;
+ const char **p;
(void) setlocale(LC_ALL, "");
+ flag1 = flag2 = flag3 = 1;
+
while ((ch = getopt(argc, argv, "123i")) != -1)
switch(ch) {
case '1':
@@ -131,41 +123,57 @@ main(int argc, char *argv[])
if (flag3)
col3 = *p;
+ line1len = line2len = 0;
+ line1 = line2 = NULL;
+ n1 = n2 = -1;
+
for (read1 = read2 = 1;;) {
/* read next line, check for EOF */
if (read1) {
- line1 = getline(line1, &line1len, fp1);
- if (line1 == NULL && ferror(fp1))
+ n1 = getline(&line1, &line1len, fp1);
+ if (n1 < 0 && ferror(fp1))
err(1, "%s", argv[0]);
+ if (n1 > 0 && line1[n1 - 1] == '\n')
+ line1[n1 - 1] = '\0';
+
}
if (read2) {
- line2 = getline(line2, &line2len, fp2);
- if (line2 == NULL && ferror(fp2))
+ n2 = getline(&line2, &line2len, fp2);
+ if (n2 < 0 && ferror(fp2))
err(1, "%s", argv[1]);
+ if (n2 > 0 && line2[n2 - 1] == '\n')
+ line2[n2 - 1] = '\0';
}
/* if one file done, display the rest of the other file */
- if (line1 == NULL) {
- if (line2 != NULL && col2 != NULL)
- show(fp2, argv[1], col2, line2, &line2len);
+ if (n1 < 0) {
+ if (n2 >= 0 && col2 != NULL)
+ show(fp2, argv[1], col2, &line2, &line2len);
break;
}
- if (line2 == NULL) {
- if (line1 != NULL && col1 != NULL)
- show(fp1, argv[0], col1, line1, &line1len);
+ if (n2 < 0) {
+ if (n1 >= 0 && col1 != NULL)
+ show(fp1, argv[0], col1, &line1, &line1len);
break;
}
- /* lines are the same */
- if(iflag)
- comp = wcsicoll(line1, line2);
+ tline2 = NULL;
+ if ((tline1 = convert(line1)) != NULL)
+ tline2 = convert(line2);
+ if (tline1 == NULL || tline2 == NULL)
+ comp = strcmp(line1, line2);
else
- comp = wcscoll(line1, line2);
+ comp = wcscoll(tline1, tline2);
+ if (tline1 != NULL)
+ free(tline1);
+ if (tline2 != NULL)
+ free(tline2);
+ /* lines are the same */
if (!comp) {
read1 = read2 = 1;
if (col3 != NULL)
- (void)printf("%ls%ls\n", col3, line1);
+ (void)printf("%s%s\n", col3, line1);
continue;
}
@@ -174,49 +182,52 @@ main(int argc, char *argv[])
read1 = 1;
read2 = 0;
if (col1 != NULL)
- (void)printf("%ls%ls\n", col1, line1);
+ (void)printf("%s%s\n", col1, line1);
} else {
read1 = 0;
read2 = 1;
if (col2 != NULL)
- (void)printf("%ls%ls\n", col2, line2);
+ (void)printf("%s%s\n", col2, line2);
}
}
exit(0);
}
wchar_t *
-getline(wchar_t *buf, size_t *buflen, FILE *fp)
+convert(const char *str)
{
- size_t bufpos;
- wint_t ch;
+ size_t n;
+ wchar_t *buf, *p;
+
+ if ((n = mbstowcs(NULL, str, 0)) == (size_t)-1)
+ return (NULL);
+ if (SIZE_MAX / sizeof(*buf) < n + 1)
+ errx(1, "conversion buffer length overflow");
+ if ((buf = malloc((n + 1) * sizeof(*buf))) == NULL)
+ err(1, "malloc");
+ if (mbstowcs(buf, str, n + 1) != n)
+ errx(1, "internal mbstowcs() error");
- bufpos = 0;
- while ((ch = getwc(fp)) != WEOF && ch != '\n') {
- if (bufpos + 1 >= *buflen) {
- *buflen = *buflen * 2;
- if (*buflen > MAXLINELEN)
- errx(1,
- "Maximum line buffer length (%zu) exceeded",
- MAXLINELEN);
- buf = reallocf(buf, *buflen * sizeof(*buf));
- if (buf == NULL)
- err(1, "reallocf");
- }
- buf[bufpos++] = ch;
+ if (iflag) {
+ for (p = buf; *p != L'\0'; p++)
+ *p = towlower(*p);
}
- buf[bufpos] = '\0';
- return (bufpos != 0 || ch == '\n' ? buf : NULL);
+ return (buf);
}
void
-show(FILE *fp, const char *fn, const wchar_t *offset, wchar_t *buf, size_t *buflen)
+show(FILE *fp, const char *fn, const char *offset, char **bufp, size_t *buflenp)
{
+ ssize_t n;
do {
- (void)printf("%ls%ls\n", offset, buf);
- } while ((buf = getline(buf, buflen, fp)) != NULL);
+ (void)printf("%s%s\n", offset, *bufp);
+ if ((n = getline(bufp, buflenp, fp)) < 0)
+ break;
+ if (n > 0 && (*bufp)[n - 1] == '\n')
+ (*bufp)[n - 1] = '\0';
+ } while (1);
if (ferror(fp))
err(1, "%s", fn);
}
@@ -240,52 +251,3 @@ usage(void)
(void)fprintf(stderr, "usage: comm [-123i] file1 file2\n");
exit(1);
}
-
-static size_t wcsicoll_l1_buflen = 0, wcsicoll_l2_buflen = 0;
-static wchar_t *wcsicoll_l1_buf = NULL, *wcsicoll_l2_buf = NULL;
-
-int
-wcsicoll(const wchar_t *s1, const wchar_t *s2)
-{
- wchar_t *p;
- size_t l1, l2;
- size_t new_l1_buflen, new_l2_buflen;
-
- l1 = wcslen(s1) + 1;
- l2 = wcslen(s2) + 1;
- new_l1_buflen = wcsicoll_l1_buflen;
- new_l2_buflen = wcsicoll_l2_buflen;
- while (new_l1_buflen < l1) {
- if (new_l1_buflen == 0)
- new_l1_buflen = INITLINELEN;
- else
- new_l1_buflen *= 2;
- }
- while (new_l2_buflen < l2) {
- if (new_l2_buflen == 0)
- new_l2_buflen = INITLINELEN;
- else
- new_l2_buflen *= 2;
- }
- if (new_l1_buflen > wcsicoll_l1_buflen) {
- wcsicoll_l1_buf = reallocf(wcsicoll_l1_buf, new_l1_buflen * sizeof(*wcsicoll_l1_buf));
- if (wcsicoll_l1_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l1_buflen = new_l1_buflen;
- }
- if (new_l2_buflen > wcsicoll_l2_buflen) {
- wcsicoll_l2_buf = reallocf(wcsicoll_l2_buf, new_l2_buflen * sizeof(*wcsicoll_l2_buf));
- if (wcsicoll_l2_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l2_buflen = new_l2_buflen;
- }
-
- for (p = wcsicoll_l1_buf; *s1; s1++)
- *p++ = towlower(*s1);
- *p = '\0';
- for (p = wcsicoll_l2_buf; *s2; s2++)
- *p++ = towlower(*s2);
- *p = '\0';
-
- return (wcscoll(wcsicoll_l1_buf, wcsicoll_l2_buf));
-}
diff --git a/usr.bin/compress/compress.c b/usr.bin/compress/compress.c
index 584f283..6f674c2 100644
--- a/usr.bin/compress/compress.c
+++ b/usr.bin/compress/compress.c
@@ -368,8 +368,8 @@ setfile(const char *name, struct stat *fs)
fs->st_mode &= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
- TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atim);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtim);
if (utimes(name, tv))
cwarn("utimes: %s", name);
diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile
index bfcbe97..499b173 100644
--- a/usr.bin/cpio/Makefile
+++ b/usr.bin/cpio/Makefile
@@ -19,10 +19,8 @@ DPADD+= ${LIBCRYPTO}
LDADD+= -lcrypto
.endif
-.if ${MK_GNU_CPIO} != "yes"
SYMLINKS=bsdcpio ${BINDIR}/cpio
MLINKS= bsdcpio.1 cpio.1
-.endif
.PHONY: check test
diff --git a/usr.bin/csup/Makefile b/usr.bin/csup/Makefile
index af1815c..7fda5b0 100644
--- a/usr.bin/csup/Makefile
+++ b/usr.bin/csup/Makefile
@@ -1,22 +1,40 @@
# $FreeBSD$
-PREFIX?= /usr/local
-BINDIR?= ${PREFIX}/bin
-MANDIR?= ${PREFIX}/man/man
-
-UNAME!= /usr/bin/uname -s
-
PROG= csup
-SRCS= attrstack.c auth.c config.c detailer.c diff.c fattr.c fixups.c fnmatch.c \
- globtree.c idcache.c keyword.c lister.c main.c misc.c mux.c parse.y \
- pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
- rcsfile.c rcsparse.c lex.rcs.c rsyncfile.c
+SRCS= attrstack.c \
+ auth.c \
+ config.c \
+ detailer.c \
+ diff.c \
+ fattr.c \
+ fixups.c \
+ fnmatch.c \
+ globtree.c \
+ idcache.c \
+ keyword.c \
+ lex.rcs.c \
+ lister.c \
+ main.c \
+ misc.c \
+ mux.c \
+ parse.y \
+ pathcomp.c \
+ proto.c \
+ rcsfile.c \
+ rcsparse.c \
+ rsyncfile.c \
+ status.c \
+ stream.c \
+ threads.c \
+ token.l \
+ updater.c
-CFLAGS+= -I. -I${.CURDIR} -g -pthread -DHAVE_FFLAGS -DNDEBUG
-WARNS?= 1
+CFLAGS+= -I. -I${.CURDIR}
+CFLAGS+= -DHAVE_FFLAGS -DNDEBUG
+WARNS?= 1
-DPADD= ${LIBCRYPTO} ${LIBZ}
-LDADD= -lcrypto -lz
+DPADD= ${LIBCRYPTO} ${LIBZ} ${LIBPTHREAD}
+LDADD= -lcrypto -lz -lpthread
SCRIPTS= cpasswd.sh
MAN= csup.1 cpasswd.1
diff --git a/usr.bin/csup/auth.c b/usr.bin/csup/auth.c
index 4e79bc5..7a84aca 100644
--- a/usr.bin/csup/auth.c
+++ b/usr.bin/csup/auth.c
@@ -147,7 +147,7 @@ auth_domd5auth(struct config *config)
lprintf(-1, "Server failed to authenticate itself to client\n");
return (STATUS_FAILURE);
}
- lprintf(2, "MD5 authentication successfull\n");
+ lprintf(2, "MD5 authentication successful\n");
return (STATUS_SUCCESS);
}
if (strcmp(cmd, "!") == 0) {
diff --git a/usr.bin/csup/cpasswd.1 b/usr.bin/csup/cpasswd.1
index 946783f..1f486d1 100644
--- a/usr.bin/csup/cpasswd.1
+++ b/usr.bin/csup/cpasswd.1
@@ -27,11 +27,11 @@
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $Id: cvpasswd.1,v 1.4 2003/03/04 18:24:42 jdp Exp $
-.\" $FreeBSD $
+.\" $FreeBSD$
.\"
.Dd June 27, 2007
-.Os FreeBSD
.Dt CPASSWD 1
+.Os FreeBSD
.Sh NAME
.Nm cpasswd
.Nd scramble passwords for csup authentication
diff --git a/usr.bin/csup/csup.1 b/usr.bin/csup/csup.1
index 2690863..02e2edb 100644
--- a/usr.bin/csup/csup.1
+++ b/usr.bin/csup/csup.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd February 1, 2006
-.Os FreeBSD
.Dt CSUP 1
+.Os FreeBSD
.Sh NAME
.Nm csup
.Nd network distribution package for CVS repositories
diff --git a/usr.bin/enigma/enigma.1 b/usr.bin/enigma/enigma.1
index 4fc0b20..e5f65ac 100644
--- a/usr.bin/enigma/enigma.1
+++ b/usr.bin/enigma/enigma.1
@@ -7,8 +7,8 @@
.\" $FreeBSD$
.\" "
.Dd May 14, 2004
-.Os
.Dt ENIGMA 1
+.Os
.Sh NAME
.Nm enigma ,
.Nm crypt
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index dee5e04..4890d37 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -35,7 +35,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
-.Dd February 24, 2008
+.Dd March 17, 2010
.Dt FIND 1
.Os
.Sh NAME
@@ -429,12 +429,9 @@ bits match those of
True if the file is contained in a file system of type
.Ar type .
The
-.Xr sysctl 8
+.Xr lsvfs 1
command can be used to find out the types of file systems
-that are available on the system:
-.Pp
-.Dl "sysctl vfs"
-.Pp
+that are available on the system.
In addition, there are two pseudo-types,
.Dq Li local
and
@@ -947,6 +944,7 @@ section below for details.
.Xr chmod 1 ,
.Xr cvs 1 ,
.Xr locate 1 ,
+.Xr lsvfs 1 ,
.Xr whereis 1 ,
.Xr which 1 ,
.Xr xargs 1 ,
diff --git a/usr.bin/getent/getent.c b/usr.bin/getent/getent.c
index e958665..0459cca 100644
--- a/usr.bin/getent/getent.c
+++ b/usr.bin/getent/getent.c
@@ -615,14 +615,13 @@ static int
utmpx(int argc, char *argv[])
{
const struct utmpx *ut;
- int rv = RV_OK, db;
+ const char *file = NULL;
+ int rv = RV_OK, db = 0;
assert(argc > 1);
assert(argv != NULL);
- if (argc == 2) {
- db = UTXDB_ACTIVE;
- } else if (argc == 3) {
+ if (argc == 3 || argc == 4) {
if (strcmp(argv[2], "active") == 0)
db = UTXDB_ACTIVE;
else if (strcmp(argv[2], "lastlogin") == 0)
@@ -631,15 +630,18 @@ utmpx(int argc, char *argv[])
db = UTXDB_LOG;
else
rv = RV_USAGE;
+ if (argc == 4)
+ file = argv[3];
} else {
rv = RV_USAGE;
}
if (rv == RV_USAGE) {
- fprintf(stderr, "Usage: %s utmpx [active | lastlogin | log]\n",
+ fprintf(stderr,
+ "Usage: %s utmpx active | lastlogin | log [filename]\n",
getprogname());
} else if (rv == RV_OK) {
- if (setutxdb(db, NULL) != 0)
+ if (setutxdb(db, file) != 0)
return (RV_NOTFOUND);
while ((ut = getutxent()) != NULL)
utmpxprint(ut);
diff --git a/usr.bin/gzip/gzip.1 b/usr.bin/gzip/gzip.1
index 20d0250..bb1fadd 100644
--- a/usr.bin/gzip/gzip.1
+++ b/usr.bin/gzip/gzip.1
@@ -25,7 +25,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
-.Dd June 24, 2009
+.Dd April 7, 2010
.Dt GZIP 1
.Os
.Sh NAME
@@ -205,14 +205,17 @@ This implementation of
.Nm
was ported based on the
.Nx
-.Nm
-20090412, and first appeared in
+.Nm ,
+and first appeared in
.Fx 7.0 .
.Sh AUTHORS
+.An -nosplit
This implementation of
.Nm
was written by
-.An Matthew R. Green Aq mrg@eterna.com.au .
+.An Matthew R. Green Aq mrg@eterna.com.au
+with unpack support written by
+.An Xin LI Aq delphij@FreeBSD.org .
.Sh BUGS
According to RFC 1952, the recorded file size is stored in a 32-bit
integer and therefore it can not represent files that is bigger than
diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c
index e9371d2..9503762 100644
--- a/usr.bin/gzip/gzip.c
+++ b/usr.bin/gzip/gzip.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gzip.c,v 1.94 2009/04/12 10:31:14 lukem Exp $ */
+/* $NetBSD: gzip.c,v 1.97 2009/10/11 09:17:21 mrg Exp $ */
/*-
* Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
@@ -43,7 +43,6 @@ __RCSID("$FreeBSD$");
*
* TODO:
* - use mmap where possible
- * - handle some signals better (remove outfile?)
* - make bzip2/compress -v/-t/-l support work as well as possible
*/
@@ -149,10 +148,9 @@ static suffixes_t suffixes[] = {
#undef SUFFIX
};
#define NUM_SUFFIXES (sizeof suffixes / sizeof suffixes[0])
-
#define SUFFIX_MAXLEN 30
-static const char gzip_version[] = "FreeBSD gzip 20090621";
+static const char gzip_version[] = "FreeBSD gzip 20100407";
#ifndef SMALL
static const char gzip_copyright[] = \
@@ -195,6 +193,7 @@ static int qflag; /* quiet mode */
static int rflag; /* recursive mode */
static int tflag; /* test */
static int vflag; /* verbose mode */
+static const char *remove_file = NULL; /* file to be removed upon SIGINT */
#else
#define qflag 0
#define tflag 0
@@ -206,7 +205,7 @@ static char *infile; /* name of file coming in */
static void maybe_err(const char *fmt, ...) __dead2
__attribute__((__format__(__printf__, 1, 2)));
-#ifndef NO_BZIP2_SUPPORT
+#if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT)
static void maybe_errx(const char *fmt, ...) __dead2
__attribute__((__format__(__printf__, 1, 2)));
#endif
@@ -232,6 +231,7 @@ static void usage(void);
static void display_version(void);
#ifndef SMALL
static void display_license(void);
+static void sigint_handler(int);
#endif
static const suffixes_t *check_suffix(char *, int);
static ssize_t read_retry(int, void *, size_t);
@@ -301,11 +301,10 @@ main(int argc, char **argv)
#endif
int ch;
- /* XXX set up signals */
-
#ifndef SMALL
if ((gzip = getenv("GZIP")) != NULL)
prepend_gzip(gzip, &argc, &argv);
+ signal(SIGINT, sigint_handler);
#endif
/*
@@ -461,7 +460,7 @@ maybe_err(const char *fmt, ...)
exit(2);
}
-#ifndef NO_BZIP2_SUPPORT
+#if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT)
/* ... without an errno. */
void
maybe_errx(const char *fmt, ...)
@@ -1088,8 +1087,8 @@ copymodes(int fd, const struct stat *sbp, const char *file)
if (fchmod(fd, sb.st_mode) < 0)
maybe_warn("couldn't fchmod: %s", file);
- TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atimespec);
- TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atim);
+ TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtim);
if (futimes(fd, times) < 0)
maybe_warn("couldn't utimes: %s", file);
@@ -1172,6 +1171,15 @@ unlink_input(const char *file, const struct stat *sb)
return;
unlink(file);
}
+
+static void
+sigint_handler(int signo __unused)
+{
+
+ if (remove_file != NULL)
+ unlink(remove_file);
+ exit(2);
+}
#endif
static const suffixes_t *
@@ -1258,6 +1266,9 @@ file_compress(char *file, char *outfile, size_t outsize)
fclose(stdin);
return -1;
}
+#ifndef SMALL
+ remove_file = outfile;
+#endif
} else
out = STDOUT_FILENO;
@@ -1289,6 +1300,7 @@ file_compress(char *file, char *outfile, size_t outsize)
}
copymodes(out, &isb, outfile);
+ remove_file = NULL;
#endif
if (close(out) == -1)
maybe_warn("couldn't close output");
@@ -1319,6 +1331,7 @@ file_uncompress(char *file, char *outfile, size_t outsize)
enum filetype method;
int fd, ofd, zfd = -1;
#ifndef SMALL
+ ssize_t rv;
time_t timestamp = 0;
unsigned char name[PATH_MAX + 1];
#endif
@@ -1364,7 +1377,6 @@ file_uncompress(char *file, char *outfile, size_t outsize)
#ifndef SMALL
if (method == FT_GZIP && Nflag) {
unsigned char ts[4]; /* timestamp */
- ssize_t rv;
rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP);
if (rv >= 0 && rv < (ssize_t)(sizeof ts))
@@ -1425,6 +1437,9 @@ file_uncompress(char *file, char *outfile, size_t outsize)
maybe_warn("can't open %s", outfile);
goto lose;
}
+#ifndef SMALL
+ remove_file = outfile;
+#endif
} else
zfd = STDOUT_FILENO;
@@ -1556,11 +1571,12 @@ file_uncompress(char *file, char *outfile, size_t outsize)
unlink(outfile);
return -1;
}
- unlink_input(file, &isb);
#ifndef SMALL
copymodes(ofd, &isb, outfile);
+ remove_file = NULL;
#endif
close(ofd);
+ unlink_input(file, &isb);
return size;
unexpected_EOF:
@@ -2054,7 +2070,7 @@ static void
display_license(void)
{
- fprintf(stderr, "%s (based on NetBSD gzip 20060927)\n", gzip_version);
+ fprintf(stderr, "%s (based on NetBSD gzip 20091011)\n", gzip_version);
fprintf(stderr, "%s\n", gzip_copyright);
exit(0);
}
@@ -2100,4 +2116,3 @@ read_retry(int fd, void *buf, size_t sz)
return sz - left;
}
-
diff --git a/usr.bin/gzip/unbzip2.c b/usr.bin/gzip/unbzip2.c
index c744e56..a5cd1be 100644
--- a/usr.bin/gzip/unbzip2.c
+++ b/usr.bin/gzip/unbzip2.c
@@ -1,4 +1,4 @@
-/* $NetBSD: unbzip2.c,v 1.12 2009/10/11 05:17:20 mrg Exp $ */
+/* $NetBSD: unbzip2.c,v 1.13 2009/12/05 03:23:37 mrg Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
diff --git a/usr.bin/hexdump/od.1 b/usr.bin/hexdump/od.1
index dd67ff5..b5b5494 100644
--- a/usr.bin/hexdump/od.1
+++ b/usr.bin/hexdump/od.1
@@ -33,8 +33,8 @@
.\" $FreeBSD$
.\"
.Dd February 18, 2010
-.Os
.Dt OD 1
+.Os
.Sh NAME
.Nm od
.Nd octal, decimal, hex, ASCII dump
diff --git a/usr.bin/indent/args.c b/usr.bin/indent/args.c
index f139de5..cab0f7d 100644
--- a/usr.bin/indent/args.c
+++ b/usr.bin/indent/args.c
@@ -157,6 +157,7 @@ struct pro {
{"sc", PRO_BOOL, true, ON, &star_comment_cont},
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines},
{"st", PRO_SPECIAL, 0, STDIN, 0},
+ {"ta", PRO_BOOL, false, ON, &auto_typedefs},
{"troff", PRO_BOOL, false, ON, &troff},
{"ut", PRO_BOOL, true, ON, &use_tabs},
{"v", PRO_BOOL, false, ON, &verbose},
diff --git a/usr.bin/indent/indent.1 b/usr.bin/indent/indent.1
index f04e13d..1a7c789 100644
--- a/usr.bin/indent/indent.1
+++ b/usr.bin/indent/indent.1
@@ -80,6 +80,7 @@
.Op Fl sob | Fl nsob
.Ek
.Op Fl \&st
+.Op Fl \&ta
.Op Fl troff
.Op Fl ut | Fl nut
.Op Fl v | Fl \&nv
@@ -377,6 +378,9 @@ Default:
Causes
.Nm
to take its input from stdin and put its output to stdout.
+.It Fl ta
+Automatically add all identifiers ending in "_t" to the list
+of type keywords.
.It Fl T Ns Ar typename
Adds
.Ar typename
diff --git a/usr.bin/indent/indent.c b/usr.bin/indent/indent.c
index 9917960..7820ebe 100644
--- a/usr.bin/indent/indent.c
+++ b/usr.bin/indent/indent.c
@@ -675,7 +675,7 @@ check_type:
ps.want_blank = true;
break;
}
- if (ps.in_decl) {
+ if (ps.in_or_st) {
*e_code++ = ':';
ps.want_blank = false;
break;
diff --git a/usr.bin/indent/indent_globs.h b/usr.bin/indent/indent_globs.h
index 11ea239..087f41c 100644
--- a/usr.bin/indent/indent_globs.h
+++ b/usr.bin/indent/indent_globs.h
@@ -204,6 +204,8 @@ int function_brace_split; /* split function declaration and
* brace onto separate lines */
int use_tabs; /* set true to use tabs for spacing,
* false uses all spaces */
+int auto_typedefs; /* set true to recognize identifiers
+ * ending in "_t" like typedefs */
/* -troff font state information */
diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c
index 60fc1ae..b3604c6 100644
--- a/usr.bin/indent/lexi.c
+++ b/usr.bin/indent/lexi.c
@@ -249,6 +249,18 @@ lexi(void)
last_code = ident; /* Remember that this is the code we will
* return */
+ if (auto_typedefs) {
+ const char *q = s_token;
+ size_t q_len = strlen(q);
+ /* Check if we have an "_t" in the end */
+ if (q_len > 2 &&
+ (strcmp(q + q_len - 2, "_t") == 0)) {
+ ps.its_a_keyword = true;
+ ps.last_u_d = true;
+ goto found_auto_typedef;
+ }
+ }
+
/*
* This loop will check if the token is a keyword.
*/
@@ -285,6 +297,7 @@ lexi(void)
/* FALLTHROUGH */
case 4: /* one of the declaration keywords */
+ found_auto_typedef:
if (ps.p_l_follow) {
ps.cast_mask |= (1 << ps.p_l_follow) & ~ps.sizeof_mask;
break; /* inside parens: cast, param list or sizeof */
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 9c86fff..ec32ee7 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -1270,50 +1270,50 @@ ktrstat(struct stat *statp)
printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
printf("atime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_atimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_atim.tv_sec);
else {
- tm = localtime(&statp->st_atimespec.tv_sec);
+ tm = localtime(&statp->st_atim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_atimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_atimespec.tv_nsec);
+ if (statp->st_atim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_atim.tv_nsec);
else
printf(", ");
printf("stime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_mtimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
else {
- tm = localtime(&statp->st_mtimespec.tv_sec);
+ tm = localtime(&statp->st_mtim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_mtimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_mtimespec.tv_nsec);
+ if (statp->st_mtim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_mtim.tv_nsec);
else
printf(", ");
printf("ctime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_ctimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
else {
- tm = localtime(&statp->st_ctimespec.tv_sec);
+ tm = localtime(&statp->st_ctim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_ctimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_ctimespec.tv_nsec);
+ if (statp->st_ctim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_ctim.tv_nsec);
else
printf(", ");
printf("birthtime=");
if (resolv == 0)
- printf("%jd", (intmax_t)statp->st_birthtimespec.tv_sec);
+ printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
else {
- tm = localtime(&statp->st_birthtimespec.tv_sec);
+ tm = localtime(&statp->st_birthtim.tv_sec);
(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
printf("\"%s\"", timestr);
}
- if (statp->st_birthtimespec.tv_nsec != 0)
- printf(".%09ld, ", statp->st_birthtimespec.tv_nsec);
+ if (statp->st_birthtim.tv_nsec != 0)
+ printf(".%09ld, ", statp->st_birthtim.tv_nsec);
else
printf(", ");
printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
diff --git a/usr.bin/killall/killall.1 b/usr.bin/killall/killall.1
index 19362bc..58ffa06 100644
--- a/usr.bin/killall/killall.1
+++ b/usr.bin/killall/killall.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd December 25, 2009
-.Os
.Dt KILLALL 1
+.Os
.Sh NAME
.Nm killall
.Nd kill processes by name
diff --git a/usr.bin/locale/Makefile b/usr.bin/locale/Makefile
index 5b8932c..96c18bc 100644
--- a/usr.bin/locale/Makefile
+++ b/usr.bin/locale/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
-PROG = locale
-CFLAGS += -I${.CURDIR}/../../lib/libc/locale
-WARNS ?= 3
+PROG= locale
+WARNS?= 3
+CFLAGS+= -I${.CURDIR}/../../lib/libc/locale
.include <bsd.prog.mk>
diff --git a/usr.bin/lockf/lockf.1 b/usr.bin/lockf/lockf.1
index 6e2e06e..255a828 100644
--- a/usr.bin/lockf/lockf.1
+++ b/usr.bin/lockf/lockf.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd July 7, 1998
-.Os
.Dt LOCKF 1
+.Os
.Sh NAME
.Nm lockf
.Nd execute a command while holding a file lock
diff --git a/usr.bin/mail/util.c b/usr.bin/mail/util.c
index e764aac..df2d840 100644
--- a/usr.bin/mail/util.c
+++ b/usr.bin/mail/util.c
@@ -349,7 +349,7 @@ alter(name)
return;
(void)gettimeofday(&tv[0], (struct timezone *)NULL);
tv[0].tv_sec++;
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
(void)utimes(name, tv);
}
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 91638d4..3b091fd 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -983,8 +983,6 @@ main(int argc, char **argv)
if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
if (!strcmp(machine_arch, "i386"))
machine_cpu = "i386";
- else if (!strcmp(machine_arch, "alpha"))
- machine_cpu = "ev4";
else
machine_cpu = "unknown";
}
diff --git a/usr.bin/minigzip/Makefile b/usr.bin/minigzip/Makefile
index 9a0ab95..21b0924 100644
--- a/usr.bin/minigzip/Makefile
+++ b/usr.bin/minigzip/Makefile
@@ -1,10 +1,13 @@
# $FreeBSD$
+SRCDIR= ${.CURDIR}/../../lib/libz
+.PATH: ${SRCDIR}
+
PROG= minigzip
-LDADD= -lz
-DPADD= ${LIBZ}
-.PATH: ${.CURDIR}/../../lib/libz
WARNS?= 5
+CFLAGS+=-DUSE_MMAP
+DPADD= ${LIBZ}
+LDADD= -lz
.include <bsd.prog.mk>
diff --git a/usr.bin/ncal/Makefile b/usr.bin/ncal/Makefile
index 343e8cd..7d42921 100644
--- a/usr.bin/ncal/Makefile
+++ b/usr.bin/ncal/Makefile
@@ -4,7 +4,6 @@ PROG= ncal
DPADD= ${LIBCALENDAR} ${LIBTERMCAP}
LDADD= -lcalendar -ltermcap
-WARNS?= 1
LINKS= ${BINDIR}/ncal ${BINDIR}/cal
MLINKS= ncal.1 cal.1
diff --git a/usr.bin/ncal/ncal.1 b/usr.bin/ncal/ncal.1
index 1c93a84..8429906 100644
--- a/usr.bin/ncal/ncal.1
+++ b/usr.bin/ncal/ncal.1
@@ -33,25 +33,37 @@
.Nd displays a calendar and the date of Easter
.Sh SYNOPSIS
.Nm
-.Op Fl hjy
+.Op Fl 3hjy
+.Op Fl A Ar number
+.Op Fl B Ar number
.Oo
.Op Ar month
.Ar year
.Oc
.Nm
-.Op Fl hj
+.Op Fl 3hj
+.Op Fl A Ar number
+.Op Fl B Ar number
.Fl m Ar month
.Op Ar year
.Nm ncal
-.Op Fl hjJpwy
+.Op Fl 3hjJpwy
+.Op Fl A Ar number
+.Op Fl B Ar number
.Op Fl s Ar country_code
.Oo
.Op Ar month
.Ar year
.Oc
.Nm ncal
-.Op Fl hJeo
+.Op Fl 3hJeo
+.Op Fl A Ar number
+.Op Fl B Ar number
.Op Ar year
+.Nm ncal
+.Op Fl CN
+.Op Fl H Ar yyyy-mm-dd
+.Op Fl d Ar yyyy-mm
.Sh DESCRIPTION
The
.Nm
@@ -109,6 +121,32 @@ Britain and her colonies switched to the Gregorian Calendar.
Print the number of the week below each week column.
.It Fl y
Display a calendar for the specified year.
+.It Fl 3
+Display the previous, current and next month surrounding today.
+.It Fl A Ar number
+Display the
+.Ar number
+of months after the current month.
+.It Fl B Ar number
+Display the
+.Ar number
+of months before the current month.
+.It Fl C
+Switch to
+.Nm cal
+mode.
+.It Fl N
+Switch to
+.Nm ncal
+mode.
+.It Fl d Ar yyyy-mm
+Use
+.Ar yyyy-mm
+as the current date (for debugging of date selection).
+.It Fl H Ar yyyy-mm-dd
+Use
+.Ar yyyy-mm-dd
+as the current date (for debugging of highlighting).
.El
.Pp
A single parameter specifies the year (1\(en9999) to be displayed;
@@ -116,12 +154,21 @@ note the year must be fully specified:
.Dq Li cal 89
will
.Em not
-display a calendar for 1989.
-Two parameters denote the month and year; the month is either a number between
-1 and 12, or a full or abbreviated name as specified by the current locale.
-Month and year default to those of the current system clock and time zone (so
+display a calendar for 1989. Two parameters denote the month and
+year; the month is either a number between 1 and 12, or a full or
+abbreviated name as specified by the current locale. Month and
+year default to those of the current system clock and time zone (so
.Dq Li cal -m 8
-will display a calendar for the month of August in the current year).
+will display a calendar for the month of August in the current
+year).
+.Pp
+Not all options can be used together. For example
+.Dq Li -3 -A 2 -B 3 -y -m 7
+would mean:
+show me the three months around the seventh month, three before
+that, two after that and the whole year.
+.Nm ncal
+will warn about these combinations.
.Pp
A year starts on January 1.
.Sh SEE ALSO
@@ -142,5 +189,8 @@ The
command and manual were written by
.An Wolfgang Helbig Aq helbig@FreeBSD.org .
.Sh BUGS
-The assignment of Julian\(enGregorian switching dates to
-country codes is historically naive for many countries.
+The assignment of Julian\(enGregorian switching dates to country
+codes is historically naive for many countries.
+.Pp
+Not all options are compatible and using them in different orders
+will give varying results.
diff --git a/usr.bin/ncal/ncal.c b/usr.bin/ncal/ncal.c
index a65a2fc..5ab9a21 100644
--- a/usr.bin/ncal/ncal.c
+++ b/usr.bin/ncal/ncal.c
@@ -45,12 +45,12 @@ static const char rcsid[] =
#include <term.h>
#undef lines /* term.h defines this */
-/* Width of one month with backward compatibility */
+/* Width of one month with backward compatibility and in regular mode*/
#define MONTH_WIDTH_B_J 27
#define MONTH_WIDTH_B 20
-#define MONTH_WIDTH_J 24
-#define MONTH_WIDTH 18
+#define MONTH_WIDTH_R_J 24
+#define MONTH_WIDTH_R 18
#define MAX_WIDTH 64
@@ -60,6 +60,7 @@ struct monthlines {
wchar_t name[MAX_WIDTH + 1];
char lines[7][MAX_WIDTH + 1];
char weeks[MAX_WIDTH + 1];
+ unsigned int extralen[7];
};
struct weekdays {
@@ -158,31 +159,29 @@ char jdaystr[] = " 1 2 3 4 5 6 7 8 9"
" 350 351 352 353 354 355 356 357 358 359"
" 360 361 362 363 364 365 366";
+int flag_nohighlight; /* user doesn't want a highlighted today */
int flag_weeks; /* user wants number of week */
int nswitch; /* user defined switch date */
int nswitchb; /* switch date for backward compatibility */
-const char *term_so, *term_se;
-int today;
+int highlightdate;
-char *center(char *s, char *t, int w);
+char *center(char *s, char *t, int w);
wchar_t *wcenter(wchar_t *s, wchar_t *t, int w);
-void mkmonth(int year, int month, int jd_flag, struct monthlines * monthl);
-void mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
-void mkweekdays(struct weekdays * wds);
-int parsemonth(const char *s, int *m, int *y);
-void printcc(void);
-void printeaster(int year, int julian, int orthodox);
-void printmonth(int year, int month, int jd_flag);
-void printmonthb(int year, int month, int jd_flag);
-void printyear(int year, int jd_flag);
-void printyearb(int year, int jd_flag);
int firstday(int y, int m);
-date *sdate(int ndays, struct date * d);
-date *sdateb(int ndays, struct date * d);
-int sndays(struct date * d);
-int sndaysb(struct date * d);
-static void usage(void);
-int weekdayb(int nd);
+void highlight(char *dst, char *src, int len, int *extraletters);
+void mkmonthr(int year, int month, int jd_flag, struct monthlines * monthl);
+void mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
+void mkweekdays(struct weekdays * wds);
+void monthranger(int year, int m, int jd_flag, int before, int after);
+void monthrangeb(int year, int m, int jd_flag, int before, int after);
+int parsemonth(const char *s, int *m, int *y);
+void printcc(void);
+void printeaster(int year, int julian, int orthodox);
+date *sdater(int ndays, struct date * d);
+date *sdateb(int ndays, struct date * d);
+int sndaysr(struct date * d);
+int sndaysb(struct date * d);
+static void usage(void);
int
main(int argc, char *argv[])
@@ -190,39 +189,31 @@ main(int argc, char *argv[])
struct djswitch *p, *q; /* to search user defined switch date */
date never = {10000, 1, 1}; /* outside valid range of dates */
date ukswitch = {1752, 9, 2};/* switch date for Great Britain */
+ date dt;
int ch; /* holds the option character */
int m = 0; /* month */
int y = 0; /* year */
int flag_backward = 0; /* user called cal--backward compat. */
- int flag_hole_year = 0; /* user wants the whole year */
+ int flag_wholeyear = 0; /* user wants the whole year */
int flag_julian_cal = 0; /* user wants Julian Calendar */
- int flag_julian_day = 0; /* user wants the Julian day
- * numbers */
- int flag_orthodox = 0; /* use wants Orthodox easter */
- int flag_easter = 0; /* use wants easter date */
+ int flag_julian_day = 0; /* user wants the Julian day numbers */
+ int flag_orthodox = 0; /* user wants Orthodox easter */
+ int flag_easter = 0; /* user wants easter date */
+ int flag_3months = 0; /* user wants 3 month display (-3) */
+ int flag_after = 0; /* user wants to see months after */
+ int flag_before = 0; /* user wants to see months before */
+ int flag_specifiedmonth = 0;/* user wants to see this month (-m) */
+ int flag_givenmonth = 0; /* user has specified month [n] */
+ int flag_givenyear = 0; /* user has specified year [n] */
char *cp; /* character pointer */
+ char *flag_today = NULL; /* debug: use date as being today */
char *flag_month = NULL; /* requested month as string */
+ char *flag_highlightdate = NULL; /* debug: date to highlight */
+ int before, after;
const char *locale; /* locale to get country code */
- char tbuf[1024], cbuf[512], *b;
- time_t t;
- struct tm *tm1;
-
- term_se = term_so = NULL;
- today = 0;
- if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
- date dt; /* handy date */
-
- b = cbuf;
- term_so = tgetstr("so", &b);
- term_se = tgetstr("se", &b);
- t = time(NULL);
- tm1 = localtime(&t);
- dt.y = tm1->tm_year + 1900;
- dt.m = tm1->tm_mon + 1;
- dt.d = tm1->tm_mday;
- today = sndaysb(&dt);
- }
+ flag_nohighlight = 0;
+ flag_weeks = 0;
/*
* Use locale to determine the country code,
@@ -263,16 +254,49 @@ main(int argc, char *argv[])
if (flag_backward)
nswitchb = ndaysj(&ukswitch);
- while ((ch = getopt(argc, argv, "Jehjm:ops:wy")) != -1)
+ before = after = -1;
+
+ while ((ch = getopt(argc, argv, "3A:B:Cd:eH:hjJm:Nops:wy")) != -1)
switch (ch) {
+ case '3':
+ flag_3months = 1;
+ break;
+ case 'A':
+ if (flag_after > 0)
+ errx(EX_USAGE, "Double -A specified");
+ flag_after = strtol(optarg, NULL, 10);
+ if (flag_after <= 0)
+ errx(EX_USAGE,
+ "Argument to -A must be positive");
+ break;
+ case 'B':
+ if (flag_before > 0)
+ errx(EX_USAGE, "Double -A specified");
+ flag_before = strtol(optarg, NULL, 10);
+ if (flag_before <= 0)
+ errx(EX_USAGE,
+ "Argument to -B must be positive");
+ break;
case 'J':
if (flag_backward)
usage();
nswitch = ndaysj(&never);
flag_julian_cal = 1;
break;
+ case 'C':
+ flag_backward = 1;
+ break;
+ case 'N':
+ flag_backward = 0;
+ break;
+ case 'd':
+ flag_today = optarg;
+ break;
+ case 'H':
+ flag_highlightdate = optarg;
+ break;
case 'h':
- term_so = term_se = NULL;
+ flag_nohighlight = 1;
break;
case 'e':
if (flag_backward)
@@ -283,7 +307,10 @@ main(int argc, char *argv[])
flag_julian_day = 1;
break;
case 'm':
+ if (flag_specifiedmonth)
+ errx(EX_USAGE, "Double -m specified");
flag_month = optarg;
+ flag_specifiedmonth = 1;
break;
case 'o':
if (flag_backward)
@@ -316,7 +343,7 @@ main(int argc, char *argv[])
flag_weeks = 1;
break;
case 'y':
- flag_hole_year = 1;
+ flag_wholeyear = 1;
break;
default:
usage();
@@ -330,14 +357,21 @@ main(int argc, char *argv[])
if (flag_easter)
usage();
flag_month = *argv++;
+ flag_givenmonth = 1;
+ m = strtol(flag_month, NULL, 10);
/* FALLTHROUGH */
case 1:
- y = atoi(*argv++);
+ y = atoi(*argv);
if (y < 1 || y > 9999)
- errx(EX_USAGE, "year %d not in range 1..9999", y);
+ errx(EX_USAGE, "year `%s' not in range 1..9999", *argv);
+ argv++;
+ flag_givenyear = 1;
break;
case 0:
- {
+ if (flag_today != NULL) {
+ y = strtol(flag_today, NULL, 10);
+ m = strtol(flag_today + 5, NULL, 10);
+ } else {
time_t t;
struct tm *tm;
@@ -359,21 +393,108 @@ main(int argc, char *argv[])
}
}
+ /*
+ * What is not supported:
+ * -3 with -A or -B
+ * -3 displays 3 months, -A and -B change that behaviour.
+ * -3 with -y
+ * -3 displays 3 months, -y says display a whole year.
+ * -3 with a given year but no given month or without -m
+ * -3 displays 3 months, no month specified doesn't make clear
+ * which three months.
+ * -m with a given month
+ * conflicting arguments, both specify the same field.
+ * -y with -m
+ * -y displays the whole year, -m displays a single month.
+ * -y with a given month
+ * -y displays the whole year, the given month displays a single
+ * month.
+ * -y with -A or -B
+ * -y displays the whole year, -A and -B display extra months.
+ */
+
+ /* -3 together with -A or -B. */
+ if (flag_3months && (flag_after || flag_before))
+ errx(EX_USAGE, "-3 together with -A and -B is not supported.");
+ /* -3 together with -y. */
+ if (flag_3months && flag_wholeyear)
+ errx(EX_USAGE, "-3 together with -y is not supported.");
+ /* -3 together with givenyear but no givenmonth. */
+ if (flag_3months && flag_givenyear &&
+ !(flag_givenmonth || flag_specifiedmonth))
+ errx(EX_USAGE,
+ "-3 together with a given year but no given month is "
+ "not supported.");
+ /* -m together with xx xxxx. */
+ if (flag_specifiedmonth && flag_givenmonth)
+ errx(EX_USAGE,
+ "-m together with a given month is not supported.");
+ /* -y together with -m. */
+ if (flag_wholeyear && flag_specifiedmonth)
+ errx(EX_USAGE, "-y together with -m is not supported.");
+ /* -y together with xx xxxx. */
+ if (flag_wholeyear && flag_givenmonth)
+ errx(EX_USAGE, "-y together a given month is not supported.");
+ /* -y together with -A or -B. */
+ if (flag_wholeyear && (flag_before > 0 || flag_after > 0))
+ errx(EX_USAGE, "-y together a -A or -B is not supported.");
+ /* The rest should be fine. */
+
+ /* Select the period to display, in order of increasing priority .*/
+ if (flag_wholeyear ||
+ (flag_givenyear && !(flag_givenmonth || flag_specifiedmonth))) {
+ m = 1;
+ before = 0;
+ after = 11;
+ }
+ if (flag_givenyear && flag_givenmonth) {
+ before = 0;
+ after = 0;
+ }
+ if (flag_specifiedmonth) {
+ before = 0;
+ after = 0;
+ }
+ if (flag_before) {
+ before = flag_before;
+ }
+ if (flag_after) {
+ after = flag_after;
+ }
+ if (flag_3months) {
+ before = 1;
+ after = 1;
+ }
+ if (after == -1)
+ after = 0;
+ if (before == -1)
+ before = 0;
+
+ /* Highlight a specified day or today .*/
+ if (flag_highlightdate != NULL) {
+ dt.y = strtol(flag_highlightdate, NULL, 10);
+ dt.m = strtol(flag_highlightdate + 5, NULL, 10);
+ dt.d = strtol(flag_highlightdate + 8, NULL, 10);
+ } else {
+ time_t t;
+ struct tm *tm1;
+
+ t = time(NULL);
+ tm1 = localtime(&t);
+ dt.y = tm1->tm_year + 1900;
+ dt.m = tm1->tm_mon + 1;
+ dt.d = tm1->tm_mday;
+ }
+ highlightdate = sndaysb(&dt);
+
+ /* And now we finally start to calculate and output calendars. */
if (flag_easter)
printeaster(y, flag_julian_cal, flag_orthodox);
- else if (argc == 1 || flag_hole_year) {
- /* disable the highlight for now */
- today = 0;
- if (flag_backward)
- printyearb(y, flag_julian_day);
- else
- printyear(y, flag_julian_day);
- } else
+ else
if (flag_backward)
- printmonthb(y, m, flag_julian_day);
+ monthrangeb(y, m, flag_julian_day, before, after);
else
- printmonth(y, m, flag_julian_day);
-
+ monthranger(y, m, flag_julian_day, before, after);
return (0);
}
@@ -382,14 +503,17 @@ usage(void)
{
fputs(
- "usage: cal [-hjy] [[month] year]\n"
- " cal [-hj] [-m month] [year]\n"
- " ncal [-hJjpwy] [-s country_code] [[month] year]\n"
- " ncal [-hJeo] [year]\n", stderr);
+"Usage: cal [general options] [-hjy] [[month] year]\n"
+" cal [general options] [-hj] [-m month] [year]\n"
+" ncal [general options] [-hJjpwy] [-s country_code] [[month] year]\n"
+" ncal [general options] [-hJeo] [year]\n"
+"General options: [-NC3] [-A months] [-B months]\n"
+"For debug the highlighting: [-H yyyy-mm-dd] [-d yyyy-mm]\n",
+ stderr);
exit(EX_USAGE);
}
-/* print the assumed switches for all countries */
+/* Print the assumed switches for all countries. */
void
printcc(void)
{
@@ -410,13 +534,13 @@ printcc(void)
printf(FSTR"\n", FSTRARG(p));
}
-/* print the date of easter sunday */
+/* Print the date of easter sunday. */
void
printeaster(int y, int julian, int orthodox)
{
date dt;
struct tm tm;
- char buf[80];
+ char buf[MAX_WIDTH];
static int d_first = -1;
if (d_first < 0)
@@ -441,183 +565,201 @@ printeaster(int y, int julian, int orthodox)
printf("%s\n", buf);
}
-void
-printmonth(int y, int m, int jd_flag)
-{
- struct monthlines month;
- struct weekdays wds;
- int i, len;
-
- mkmonth(y, m - 1, jd_flag, &month);
- mkweekdays(&wds);
- printf(" %ls %d\n", month.name, y);
- for (i = 0; i != 7; i++) {
- len = wcslen(wds.names[i]);
- if (wcswidth(wds.names[i], len) == len)
- wprintf(L"%.2ls%s\n", wds.names[i], month.lines[i]);
- else
- wprintf(L"%.1ls%s\n", wds.names[i], month.lines[i]);
- }
- if (flag_weeks)
- printf(" %s\n", month.weeks);
-}
-
-void
-printmonthb(int y, int m, int jd_flag)
-{
- struct monthlines month;
- struct weekdays wds;
- wchar_t s[MAX_WIDTH], t[MAX_WIDTH];
- int i;
- int mw;
-
- mkmonthb(y, m - 1, jd_flag, &month);
- mkweekdays(&wds);
-
- mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
-
- swprintf(s, MAX_WIDTH, L"%ls %d", month.name, y);
- wprintf(L"%ls\n", wcenter(t, s, mw));
-
- if (jd_flag)
- wprintf(L" %ls %ls %ls %ls %ls %ls %.2ls\n",
- wds.names[6], wds.names[0],
- wds.names[1], wds.names[2], wds.names[3],
- wds.names[4], wds.names[5]);
- else
- wprintf(L"%ls%ls%ls%ls%ls%ls%.2ls\n", wds.names[6],
- wds.names[0], wds.names[1], wds.names[2], wds.names[3],
- wds.names[4], wds.names[5]);
-
- for (i = 0; i != 6; i++)
- printf("%s\n", month.lines[i]+1);
-}
+#define MW(mw, me) ((mw) + me)
+#define DECREASEMONTH(m, y) \
+ if (--m == 0) { \
+ m = 12; \
+ y--; \
+ }
+#define INCREASEMONTH(m, y) \
+ if (++(m) == 13) { \
+ (m) = 1; \
+ (y)++; \
+ }
+#define M2Y(m) ((m) / 12)
+#define M2M(m) (1 + (m) % 12)
+/* Print all months for the period in the range [ before .. y-m .. after ]. */
void
-printyear(int y, int jd_flag)
+monthrangeb(int y, int m, int jd_flag, int before, int after)
{
struct monthlines year[12];
struct weekdays wds;
- char s[80], t[80];
+ char s[MAX_WIDTH], t[MAX_WIDTH];
+ wchar_t ws[MAX_WIDTH], ws1[MAX_WIDTH];
+ const char *wdss;
int i, j;
int mpl;
int mw;
+ int m1, m2;
+ int printyearheader;
+ int prevyear = -1;
+
+ mpl = jd_flag ? 2 : 3;
+ mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
+ wdss = (mpl == 2) ? " " : "";
+
+ while (before != 0) {
+ DECREASEMONTH(m, y);
+ before--;
+ after++;
+ }
+ m1 = y * 12 + m - 1;
+ m2 = m1 + after;
- for (i = 0; i != 12; i++)
- mkmonth(y, i, jd_flag, year + i);
mkweekdays(&wds);
- mpl = jd_flag ? 3 : 4;
- mw = jd_flag ? MONTH_WIDTH_J : MONTH_WIDTH;
- sprintf(s, "%d", y);
- printf("%s\n", center(t, s, mpl * mw));
+ /*
+ * The year header is printed when there are more than 'mpl' months
+ * and if the first month is a multitude of 'mpl'.
+ * If not, it will print the year behind every month.
+ */
+ printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0;
+
+ m = m1;
+ while (m <= m2) {
+ int count = 0;
+ for (i = 0; i != mpl && m + i <= m2; i++) {
+ mkmonthb(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i);
+ count++;
+ }
- for (j = 0; j != 12; j += mpl) {
- wprintf(L" %-*ls%-*ls",
- mw, year[j].name,
- mw, year[j + 1].name);
- if (mpl == 3)
- printf("%ls\n", year[j + 2].name);
- else
- wprintf(L"%-*ls%ls\n",
- mw, year[j + 2].name,
- year[j + 3].name);
- for (i = 0; i != 7; i++) {
- wprintf(L"%.2ls%-*s%-*s",
- wds.names[i],
- mw, year[j].lines[i],
- mw, year[j + 1].lines[i]);
- if (mpl == 3)
- printf("%s\n", year[j + 2].lines[i]);
- else
- printf("%-*s%s\n",
- mw, year[j + 2].lines[i],
- year[j + 3].lines[i]);
+ /* Empty line between two rows of months */
+ if (m != m1)
+ printf("\n");
+
+ /* Year at the top. */
+ if (printyearheader && M2Y(m) != prevyear) {
+ sprintf(s, "%d", M2Y(m));
+ printf("%s\n", center(t, s, mpl * mw));
+ prevyear = M2Y(m);
}
- if (flag_weeks) {
- if (mpl == 3)
- printf(" %-*s%-*s%-s\n",
- mw, year[j].weeks,
- mw, year[j + 1].weeks,
- year[j + 2].weeks);
- else
- printf(" %-*s%-*s%-*s%-s\n",
- mw, year[j].weeks,
- mw, year[j + 1].weeks,
- mw, year[j + 2].weeks,
- year[j + 3].weeks);
+
+ /* Month names. */
+ for (i = 0; i < count; i++)
+ if (printyearheader)
+ wprintf(L"%-*ls ",
+ mw, wcenter(ws, year[i].name, mw));
+ else {
+ swprintf(ws, sizeof(ws), L"%-ls %d",
+ year[i].name, M2Y(m + i));
+ wprintf(L"%-*ls ", mw, wcenter(ws1, ws, mw));
+ }
+ printf("\n");
+
+ /* Day of the week names. */
+ for (i = 0; i < count; i++) {
+ wprintf(L"%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls ",
+ wdss, wds.names[6], wdss, wds.names[0],
+ wdss, wds.names[1], wdss, wds.names[2],
+ wdss, wds.names[3], wdss, wds.names[4],
+ wdss, wds.names[5]);
}
+ printf("\n");
+
+ /* And the days of the month. */
+ for (i = 0; i != 6; i++) {
+ for (j = 0; j < count; j++)
+ printf("%-*s ",
+ MW(mw, year[j].extralen[i]),
+ year[j].lines[i]+1);
+ printf("\n");
+ }
+
+ m += mpl;
}
}
void
-printyearb(int y, int jd_flag)
+monthranger(int y, int m, int jd_flag, int before, int after)
{
struct monthlines year[12];
struct weekdays wds;
- char s[80], t[80];
- wchar_t ws[80], wt[80];
+ char s[MAX_WIDTH], t[MAX_WIDTH];
int i, j;
int mpl;
int mw;
+ int m1, m2;
+ int prevyear = -1;
+ int printyearheader;
+
+ mpl = jd_flag ? 3 : 4;
+ mw = jd_flag ? MONTH_WIDTH_R_J : MONTH_WIDTH_R;
+
+ while (before != 0) {
+ DECREASEMONTH(m, y);
+ before--;
+ after++;
+ }
+ m1 = y * 12 + m - 1;
+ m2 = m1 + after;
- for (i = 0; i != 12; i++)
- mkmonthb(y, i, jd_flag, year + i);
mkweekdays(&wds);
- mpl = jd_flag ? 2 : 3;
- mw = jd_flag ? MONTH_WIDTH_B_J : MONTH_WIDTH_B;
- sprintf(s, "%d", y);
- printf("%s\n\n", center(t, s, mw * mpl + mpl));
+ /*
+ * The year header is printed when there are more than 'mpl' months
+ * and if the first month is a multitude of 'mpl'.
+ * If not, it will print the year behind every month.
+ */
+ printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0;
+
+ m = m1;
+ while (m <= m2) {
+ int count = 0;
+ for (i = 0; i != mpl && m + i <= m2; i++) {
+ mkmonthr(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i);
+ count++;
+ }
- for (j = 0; j != 12; j += mpl) {
- wprintf(L"%-*ls ", mw, wcenter(ws, year[j].name, mw));
- if (mpl == 2)
- printf("%ls\n", wcenter(ws, year[j + 1].name, mw));
- else
- wprintf(L"%-*ls %ls\n", mw,
- wcenter(ws, year[j + 1].name, mw),
- wcenter(wt, year[j + 2].name, mw));
-
- if (mpl == 2)
- wprintf(L" %ls %ls %ls %ls %ls %ls %ls "
- " %ls %ls %ls %ls %ls %ls %.2ls\n",
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5],
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5]);
- else
- wprintf(L"%ls%ls%ls%ls%ls%ls%ls "
- "%ls%ls%ls%ls%ls%ls%ls "
- "%ls%ls%ls%ls%ls%ls%.2ls\n",
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5],
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5],
- wds.names[6], wds.names[0], wds.names[1],
- wds.names[2], wds.names[3], wds.names[4],
- wds.names[5]);
- for (i = 0; i != 6; i++) {
- if (mpl == 2)
- printf("%-*s %s\n",
- mw, year[j].lines[i]+1,
- year[j + 1].lines[i]+1);
+ /* Empty line between two rows of months. */
+ if (m != m1)
+ printf("\n");
+
+ /* Year at the top. */
+ if (printyearheader && M2Y(m) != prevyear) {
+ sprintf(s, "%d", M2Y(m));
+ printf("%s\n", center(t, s, mpl * mw));
+ prevyear = M2Y(m);
+ }
+
+ /* Month names. */
+ wprintf(L" ");
+ for (i = 0; i < count; i++)
+ if (printyearheader)
+ wprintf(L"%-*ls", mw, year[i].name);
else
- printf("%-*s %-*s %s\n",
- mw, year[j].lines[i]+1,
- mw, year[j + 1].lines[i]+1,
- year[j + 2].lines[i]+1);
+ wprintf(L"%-ls %-*d", year[i].name,
+ mw - wcslen(year[i].name) - 1, M2Y(m + i));
+ printf("\n");
+
+ /* And the days of the month. */
+ for (i = 0; i != 7; i++) {
+ /* Week day */
+ wprintf(L"%.2ls", wds.names[i]);
+
+ /* Full months */
+ for (j = 0; j < count; j++)
+ printf("%-*s",
+ MW(mw, year[j].extralen[i]),
+ year[j].lines[i]);
+ printf("\n");
+ }
+ /* Week numbers. */
+ if (flag_weeks) {
+ printf(" ");
+ for (i = 0; i < count; i++)
+ printf("%-*s", mw, year[i].weeks);
+ printf("\n");
}
+
+ m += mpl;
}
+ return;
}
void
-mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
+mkmonthr(int y, int m, int jd_flag, struct monthlines *mlines)
{
struct tm tm; /* for strftime printing local names of
@@ -659,7 +801,7 @@ mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
*/
firstm = first - weekday(first);
- /* Set ds (daystring) and dw (daywidth) according to the jd_flag */
+ /* Set ds (daystring) and dw (daywidth) according to the jd_flag. */
if (jd_flag) {
ds = jdaystr;
dw = 4;
@@ -676,40 +818,25 @@ mkmonth(int y, int m, int jd_flag, struct monthlines *mlines)
for (i = 0; i != 7; i++) {
l = 0;
for (j = firstm + i, k = 0; j < last; j += 7, k += dw) {
- if (j == today && (term_so != NULL && term_se != NULL)) {
- l = strlen(term_so);
- if (jd_flag)
- dt.d = j - jan1 + 1;
- else
- sdateb(j, &dt);
- /* separator */
- mlines->lines[i][k] = ' ';
- /* the actual text */
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
- /* highlight on */
- memcpy(mlines->lines[i] + k + 1, term_so, l);
- /* highlight off */
- memcpy(mlines->lines[i] + k + l + dw, term_se,
- strlen(term_se));
- l = strlen(term_se) + strlen(term_so);
- continue;
- }
if (j >= first) {
if (jd_flag)
dt.d = j - jan1 + 1;
else
- sdate(j, &dt);
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
+ sdater(j, &dt);
+ if (j == highlightdate && !flag_nohighlight)
+ highlight(mlines->lines[i] + k,
+ ds + dt.d * dw, dw, &l);
+ else
+ memcpy(mlines->lines[i] + k + l,
+ ds + dt.d * dw, dw);
} else
memcpy(mlines->lines[i] + k + l, " ", dw);
}
mlines->lines[i][k + l] = '\0';
-
+ mlines->extralen[i] = l;
}
- /* fill the weeknumbers */
+ /* fill the weeknumbers. */
if (flag_weeks) {
for (j = firstm, k = 0; j < last; k += dw, j += 7)
if (j <= nswitch)
@@ -746,7 +873,7 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
dw = 3;
}
- /* Set name of month centered */
+ /* Set name of month centered. */
memset(&tm, 0, sizeof(tm));
tm.tm_mon = m;
wcsftime(mlines->name, sizeof(mlines->name) / sizeof(mlines->name[0]),
@@ -795,32 +922,17 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
l = 0;
for (j = firsts + 7 * i, k = 0; j < last && k != dw * 7;
j++, k += dw) {
- if (j == today && (term_so != NULL && term_se != NULL)) {
- l = strlen(term_so);
- if (jd_flag)
- dt.d = j - jan1 + 1;
- else
- sdateb(j, &dt);
- /* separator */
- mlines->lines[i][k] = ' ';
- /* the actual text */
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
- /* highlight on */
- memcpy(mlines->lines[i] + k + 1, term_so, l);
- /* highlight off */
- memcpy(mlines->lines[i] + k + l + dw, term_se,
- strlen(term_se));
- l = strlen(term_se) + strlen(term_so);
- continue;
- }
if (j >= first) {
if (jd_flag)
dt.d = j - jan1 + 1;
else
sdateb(j, &dt);
- memcpy(mlines->lines[i] + k + l,
- ds + dt.d * dw, dw);
+ if (j == highlightdate && !flag_nohighlight)
+ highlight(mlines->lines[i] + k,
+ ds + dt.d * dw, dw, &l);
+ else
+ memcpy(mlines->lines[i] + k + l,
+ ds + dt.d * dw, dw);
} else
memcpy(mlines->lines[i] + k + l, " ", dw);
}
@@ -828,10 +940,11 @@ mkmonthb(int y, int m, int jd_flag, struct monthlines *mlines)
mlines->lines[i][1] = '\0';
else
mlines->lines[i][k + l] = '\0';
+ mlines->extralen[i] = l;
}
}
-/* Put the local names of weekdays into the wds */
+/* Put the local names of weekdays into the wds. */
void
mkweekdays(struct weekdays *wds)
{
@@ -857,9 +970,8 @@ mkweekdays(struct weekdays *wds)
}
/*
- * Compute the day number of the first
- * existing date after the first day in month.
- * (the first day in month and even the month might not exist!)
+ * Compute the day number of the first existing date after the first day in
+ * month. (the first day in month and even the month might not exist!)
*/
int
firstday(int y, int m)
@@ -870,9 +982,9 @@ firstday(int y, int m)
dt.y = y;
dt.m = m;
dt.d = 1;
- nd = sndays(&dt);
+ nd = sndaysr(&dt);
for (;;) {
- sdate(nd, &dt);
+ sdater(nd, &dt);
if ((dt.m >= m && dt.y == y) || dt.y > y)
return (nd);
else
@@ -886,7 +998,7 @@ firstday(int y, int m)
* Julian to Gregorian if specified by the user.
*/
int
-sndays(struct date *d)
+sndaysr(struct date *d)
{
if (nswitch != 0)
@@ -912,9 +1024,9 @@ sndaysb(struct date *d)
return (ndaysj(d));
}
-/* Inverse of sndays */
+/* Inverse of sndays. */
struct date *
-sdate(int nd, struct date *d)
+sdater(int nd, struct date *d)
{
if (nswitch < nd)
@@ -923,7 +1035,7 @@ sdate(int nd, struct date *d)
return (jdate(nd, d));
}
-/* Inverse of sndaysb */
+/* Inverse of sndaysb. */
struct date *
sdateb(int nd, struct date *d)
{
@@ -934,22 +1046,22 @@ sdateb(int nd, struct date *d)
return (jdate(nd, d));
}
-/* Center string t in string s of length w by putting enough leading blanks */
+/* Center string t in string s of length w by putting enough leading blanks. */
char *
center(char *s, char *t, int w)
{
- char blanks[80];
+ char blanks[MAX_WIDTH];
memset(blanks, ' ', sizeof(blanks));
sprintf(s, "%.*s%s", (int)(w - strlen(t)) / 2, blanks, t);
return (s);
}
-/* Center string t in string s of length w by putting enough leading blanks */
+/* Center string t in string s of length w by putting enough leading blanks. */
wchar_t *
wcenter(wchar_t *s, wchar_t *t, int w)
{
- char blanks[80];
+ char blanks[MAX_WIDTH];
memset(blanks, ' ', sizeof(blanks));
swprintf(s, MAX_WIDTH, L"%.*s%ls", (int)(w - wcslen(t)) / 2, blanks, t);
@@ -988,3 +1100,76 @@ parsemonth(const char *s, int *m, int *y)
}
return (1);
}
+
+void
+highlight(char *dst, char *src, int len, int *extralen)
+{
+ static int first = 1;
+ static const char *term_so, *term_se;
+
+ if (first) {
+ char tbuf[1024], cbuf[512], *b;
+
+ term_se = term_so = NULL;
+
+ /* On how to highlight on this type of terminal (if any). */
+ if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
+ b = cbuf;
+ term_so = tgetstr("so", &b);
+ term_se = tgetstr("se", &b);
+ }
+
+ first = 0;
+ }
+
+ /*
+ * This check is not necessary, should have been handled before calling
+ * this function.
+ */
+ if (flag_nohighlight) {
+ memcpy(dst, src, len);
+ return;
+ }
+
+ /*
+ * If it is a real terminal, use the data from the termcap database.
+ */
+ if (term_so != NULL && term_se != NULL) {
+ /* separator. */
+ dst[0] = ' ';
+ dst++;
+ /* highlight on. */
+ memcpy(dst, term_so, strlen(term_so));
+ dst += strlen(term_so);
+ /* the actual text. (minus leading space) */
+ len--;
+ src++;
+ memcpy(dst, src, len);
+ dst += len;
+ /* highlight off. */
+ memcpy(dst, term_se, strlen(term_se));
+ *extralen = strlen(term_so) + strlen(term_se);
+ return;
+ }
+
+ /*
+ * Otherwise, print a _, backspace and the letter.
+ */
+ *extralen = 0;
+ /* skip leading space. */
+ src++;
+ len--;
+ /* separator. */
+ dst[0] = ' ';
+ dst++;
+ while (len > 0) {
+ /* _ and backspace. */
+ memcpy(dst, "_\010", 2);
+ dst += 2;
+ *extralen += 2;
+ /* the character. */
+ *dst++ = *src++;
+ len--;
+ }
+ return;
+}
diff --git a/usr.bin/netstat/netgraph.c b/usr.bin/netstat/netgraph.c
index c4dd647..d510414 100644
--- a/usr.bin/netstat/netgraph.c
+++ b/usr.bin/netstat/netgraph.c
@@ -166,14 +166,14 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused,
name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
/* Get ngsock structure */
- if (ngpcb.sockdata == 0) /* unconnected data socket */
+ if (ngpcb.sockdata == NULL) /* unconnected data socket */
goto finish;
kread((u_long)ngpcb.sockdata, (char *)&info, sizeof(info));
/* Get info on associated node */
- if (info.node == 0 || csock == -1)
+ if (info.node_id == 0 || csock == -1)
goto finish;
- snprintf(path, sizeof(path), "[%lx]:", (u_long) info.node);
+ snprintf(path, sizeof(path), "[%x]:", info.node_id);
if (NgSendMsg(csock, path,
NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0)
goto finish;
diff --git a/usr.bin/perror/perror.1 b/usr.bin/perror/perror.1
index 7faf77f..0b724b1 100644
--- a/usr.bin/perror/perror.1
+++ b/usr.bin/perror/perror.1
@@ -34,7 +34,7 @@
.Nd "print an error number as a string"
.Sh SYNOPSIS
.Nm
-.Op Ar number
+.Ar number
.Sh DESCRIPTION
The
.Nm
diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile
index 1c187b0..fa1c3b4 100644
--- a/usr.bin/procstat/Makefile
+++ b/usr.bin/procstat/Makefile
@@ -9,6 +9,7 @@ SRCS= procstat.c \
procstat_cred.c \
procstat_files.c \
procstat_kstack.c \
+ procstat_sigs.c \
procstat_threads.c \
procstat_vm.c
diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1
index f4dc731..0113e37 100644
--- a/usr.bin/procstat/procstat.1
+++ b/usr.bin/procstat/procstat.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 20, 2008
+.Dd March 7, 2010
.Dt PROCSTAT 1
.Os
.Sh NAME
@@ -34,8 +34,9 @@
.Sh SYNOPSIS
.Nm
.Op Fl h
+.Op Fl n
.Op Fl w Ar interval
-.Op Fl b | c | f | k | s | t | v
+.Op Fl b | c | f | i | j | k | s | t | v
.Op Fl a | Ar pid ...
.Sh DESCRIPTION
The
@@ -56,6 +57,10 @@ Display binary information for the process.
Display command line arguments for the process.
.It Fl f
Display file descriptor information for the process.
+.It Fl i
+Display signal pending and disposition information for the process.
+.It Fl j
+Display signal pending and blocked information for the process threads.
.It Fl k
Display the stacks of kernel threads in the process, excluding stacks of
threads currently running on a CPU and threads with stacks swapped to disk.
@@ -204,6 +209,58 @@ direct I/O
.It l
lock held
.El
+.Ss Signal Disposition Information
+Display signal pending and disposition for a process:
+.Pp
+.Bl -tag -width ident -compact
+.It PID
+process ID
+.It COMM
+command
+.It SIG
+signal name
+.It FLAGS
+process signal disposition details, three symbols
+.Bl -tag -width X -compact
+.It P
+if signal is pending in the global process queue, - otherwise
+.It I
+if signal delivery disposition is SIGIGN, - otherwise
+.It C
+if signal delivery is to catch it, - otherwise
+.El
+.El
+.Pp
+If
+.Fl n
+switch is given, the signal numbers are shown instead of signal names.
+.Ss Thread Signal Information
+Display signal pending and blocked for a process threads:
+.Pp
+.Bl -tag -width ident -compact
+.It PID
+process ID
+.It COMM
+command
+.It TID
+thread ID
+.It SIG
+signal name
+.It FLAGS
+thread signal delivery status, two symbols
+.Bl -tag -width X -compact
+.It P
+if signal is pending for the thread, - otherwise
+.It B
+if signal is blocked in the thread signal mask, - if not blocked
+.El
+.El
+.Pp
+The
+.Fl n
+switch has the same effect as for the
+.Fl i
+switch, the signals numbers are shown instead of signal names.
.Ss Kernel Thread Stacks
Display kernel thread stacks for a process, allowing further interpretation
of thread wait channels.
diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c
index bc02682..ee95ae2 100644
--- a/usr.bin/procstat/procstat.c
+++ b/usr.bin/procstat/procstat.c
@@ -38,15 +38,15 @@
#include "procstat.h"
-static int aflag, bflag, cflag, fflag, kflag, sflag, tflag, vflag;
-int hflag;
+static int aflag, bflag, cflag, fflag, iflag, jflag, kflag, sflag, tflag, vflag;
+int hflag, nflag;
static void
usage(void)
{
- fprintf(stderr, "usage: procstat [-h] [-w interval] [-b | -c | -f | "
- "-k | -s | -t | -v]\n");
+ fprintf(stderr, "usage: procstat [-h] [-n] [-w interval] [-b | -c | -f | "
+ "-i | -j | -k | -s | -t | -v]\n");
fprintf(stderr, " [-a | pid ...]\n");
exit(EX_USAGE);
}
@@ -61,6 +61,10 @@ procstat(pid_t pid, struct kinfo_proc *kipp)
procstat_args(pid, kipp);
else if (fflag)
procstat_files(pid, kipp);
+ else if (iflag)
+ procstat_sigs(pid, kipp);
+ else if (jflag)
+ procstat_threads_sigs(pid, kipp);
else if (kflag)
procstat_kstack(pid, kipp, kflag);
else if (sflag)
@@ -109,7 +113,7 @@ main(int argc, char *argv[])
char *dummy;
interval = 0;
- while ((ch = getopt(argc, argv, "abcfkhstvw:")) != -1) {
+ while ((ch = getopt(argc, argv, "abcfijknhstvw:")) != -1) {
switch (ch) {
case 'a':
aflag++;
@@ -127,10 +131,22 @@ main(int argc, char *argv[])
fflag++;
break;
+ case 'i':
+ iflag++;
+ break;
+
+ case 'j':
+ jflag++;
+ break;
+
case 'k':
kflag++;
break;
+ case 'n':
+ nflag++;
+ break;
+
case 'h':
hflag++;
break;
diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h
index 8bacab7..d73a203 100644
--- a/usr.bin/procstat/procstat.h
+++ b/usr.bin/procstat/procstat.h
@@ -29,7 +29,7 @@
#ifndef PROCSTAT_H
#define PROCSTAT_H
-extern int hflag;
+extern int hflag, nflag;
struct kinfo_proc;
void kinfo_proc_sort(struct kinfo_proc *kipp, int count);
@@ -40,7 +40,9 @@ void procstat_bin(pid_t pid, struct kinfo_proc *kipp);
void procstat_cred(pid_t pid, struct kinfo_proc *kipp);
void procstat_files(pid_t pid, struct kinfo_proc *kipp);
void procstat_kstack(pid_t pid, struct kinfo_proc *kipp, int kflag);
+void procstat_sigs(pid_t pid, struct kinfo_proc *kipp);
void procstat_threads(pid_t pid, struct kinfo_proc *kipp);
+void procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp);
void procstat_vm(pid_t pid, struct kinfo_proc *kipp);
#endif /* !PROCSTAT_H */
diff --git a/usr.bin/procstat/procstat_sigs.c b/usr.bin/procstat/procstat_sigs.c
new file mode 100644
index 0000000..b1f5e35
--- /dev/null
+++ b/usr.bin/procstat/procstat_sigs.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2010 Konstantin Belousov
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "procstat.h"
+
+static void
+procstat_print_signame(int sig)
+{
+ char name[12];
+ int i;
+
+ if (!nflag && sig < sys_nsig) {
+ strlcpy(name, sys_signame[sig], sizeof(name));
+ for (i = 0; name[i] != 0; i++)
+ name[i] = toupper(name[i]);
+ printf("%-7s ", name);
+ } else
+ printf("%-7d ", sig);
+}
+
+static void
+procstat_print_sig(const sigset_t *set, int sig, char flag)
+{
+
+ printf("%c", sigismember(set, sig) ? flag : '-');
+}
+
+void
+procstat_sigs(pid_t pid, struct kinfo_proc *kipp)
+{
+ int j;
+
+ if (!hflag)
+ printf("%5s %-16s %-7s %4s\n", "PID", "COMM", "SIG", "FLAGS");
+
+ for (j = 1; j <= _SIG_MAXSIG; j++) {
+ printf("%5d ", pid);
+ printf("%-16s ", kipp->ki_comm);
+ procstat_print_signame(j);
+ printf(" ");
+ procstat_print_sig(&kipp->ki_siglist, j, 'P');
+ procstat_print_sig(&kipp->ki_sigignore, j, 'I');
+ procstat_print_sig(&kipp->ki_sigcatch, j, 'C');
+ printf("\n");
+ }
+}
+
+void
+procstat_threads_sigs(pid_t pid, struct kinfo_proc *kipp)
+{
+ struct kinfo_proc *kip;
+ int error, name[4], j;
+ unsigned int i;
+ size_t len;
+
+ if (!hflag)
+ printf("%5s %6s %-16s %-7s %4s\n", "PID", "TID", "COMM",
+ "SIG", "FLAGS");
+
+ /*
+ * We need to re-query for thread information, so don't use *kipp.
+ */
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
+ name[3] = pid;
+
+ len = 0;
+ error = sysctl(name, 4, NULL, &len, NULL, 0);
+ if (error < 0 && errno != ESRCH) {
+ warn("sysctl: kern.proc.pid: %d", pid);
+ return;
+ }
+ if (error < 0)
+ return;
+
+ kip = malloc(len);
+ if (kip == NULL)
+ err(-1, "malloc");
+
+ if (sysctl(name, 4, kip, &len, NULL, 0) < 0) {
+ warn("sysctl: kern.proc.pid: %d", pid);
+ free(kip);
+ return;
+ }
+
+ kinfo_proc_sort(kip, len / sizeof(*kipp));
+ for (i = 0; i < len / sizeof(*kipp); i++) {
+ kipp = &kip[i];
+ for (j = 1; j <= _SIG_MAXSIG; j++) {
+ printf("%5d ", pid);
+ printf("%6d ", kipp->ki_tid);
+ printf("%-16s ", kipp->ki_comm);
+ procstat_print_signame(j);
+ printf(" ");
+ procstat_print_sig(&kipp->ki_siglist, j, 'P');
+ procstat_print_sig(&kipp->ki_sigmask, j, 'B');
+ printf("\n");
+ }
+ }
+ free(kip);
+}
diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c
index bd2de28..6c4e0ee 100644
--- a/usr.bin/script/script.c
+++ b/usr.bin/script/script.c
@@ -158,6 +158,7 @@ main(int argc, char *argv[])
}
if (child == 0)
doshell(argv);
+ close(slave);
if (flushtime > 0)
tvp = &tv;
diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index 1a140b1..8d4fe95 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -130,8 +130,9 @@ main(int argc, char *argv[])
fflag = 0;
inplace = NULL;
- while ((c = getopt(argc, argv, "EI:ae:f:i:ln")) != -1)
+ while ((c = getopt(argc, argv, "EI:ae:f:i:lnr")) != -1)
switch (c) {
+ case 'r': /* Gnu sed compat */
case 'E':
rflags = REG_EXTENDED;
break;
diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1
index d5858ff..0744630 100644
--- a/usr.bin/sed/sed.1
+++ b/usr.bin/sed/sed.1
@@ -39,11 +39,11 @@
.Nd stream editor
.Sh SYNOPSIS
.Nm
-.Op Fl Ealn
+.Op Fl Ealnr
.Ar command
.Op Ar
.Nm
-.Op Fl Ealn
+.Op Fl Ealnr
.Op Fl e Ar command
.Op Fl f Ar command_file
.Op Fl I Ar extension
@@ -144,6 +144,10 @@ all of the commands have been applied to it.
The
.Fl n
option suppresses this behavior.
+.It Fl r
+Same as
+.Fl E
+for compatibility with GNU sed.
.El
.Pp
The form of a
diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c
index 1a5af42..2242c4e 100644
--- a/usr.bin/sockstat/sockstat.c
+++ b/usr.bin/sockstat/sockstat.c
@@ -621,6 +621,8 @@ display(void)
case AF_INET:
case AF_INET6:
pos += printaddr(s->family, &s->laddr);
+ if (s->family == AF_INET6 && pos >= 58)
+ pos += xprintf(" ");
while (pos < 58)
pos += xprintf(" ");
pos += printaddr(s->family, &s->faddr);
diff --git a/usr.bin/stat/stat.1 b/usr.bin/stat/stat.1
index 6856efa..8bbdda4 100644
--- a/usr.bin/stat/stat.1
+++ b/usr.bin/stat/stat.1
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 27, 2007
+.Dd April 24, 2010
.Dt STAT 1
.Os
.Sh NAME
@@ -232,6 +232,11 @@ Display date in
format.
.It Cm dr
Display actual device name.
+.It Cm f
+Display the flags of
+.Ar file
+as in
+.Nm ls Fl lTdo .
.It Cm gu
Display group or user name.
.It Cm p
diff --git a/usr.bin/stat/stat.c b/usr.bin/stat/stat.c
index 83d389b..1ab10ea 100644
--- a/usr.bin/stat/stat.c
+++ b/usr.bin/stat/stat.c
@@ -182,6 +182,9 @@ int format1(const struct stat *, /* stat info */
char *, size_t, /* a place to put the output */
int, int, int, int, /* the parsed format */
int, int);
+#if HAVE_STRUCT_STAT_ST_FLAGS
+char *xfflagstostr(unsigned long);
+#endif
char *timefmt;
int linkfail;
@@ -333,6 +336,25 @@ main(int argc, char *argv[])
return (am_readlink ? linkfail : errs);
}
+#if HAVE_STRUCT_STAT_ST_FLAGS
+/*
+ * fflagstostr() wrapper that leaks only once
+ */
+char *
+xfflagstostr(unsigned long fflags)
+{
+ static char *str = NULL;
+
+ if (str != NULL)
+ free(str);
+
+ str = fflagstostr(fflags);
+ if (str == NULL)
+ err(1, "fflagstostr");
+ return (str);
+}
+#endif /* HAVE_STRUCT_STAT_ST_FLAGS */
+
void
usage(const char *synopsis)
{
@@ -725,8 +747,11 @@ format1(const struct stat *st,
case SHOW_st_flags:
small = (sizeof(st->st_flags) == 4);
data = st->st_flags;
- sdata = NULL;
- formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX;
+ sdata = xfflagstostr(st->st_flags);
+ if (*sdata == '\0')
+ sdata = "-";
+ formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
+ FMTF_STRING;
if (ofmt == 0)
ofmt = FMTF_UNSIGNED;
break;
diff --git a/usr.bin/tar/bsdtar.1 b/usr.bin/tar/bsdtar.1
index 8baab7a..ac9afbb 100644
--- a/usr.bin/tar/bsdtar.1
+++ b/usr.bin/tar/bsdtar.1
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 25, 2009
+.Dd Oct 12, 2009
.Dt BSDTAR 1
.Os
.Sh NAME
@@ -336,6 +336,13 @@ This is enabled by default, use
or
.Cm iso9660:!joliet
to disable.
+.It Cm iso9660:rockridge
+Support Rock Ridge extensions.
+This is enabled by default, use
+.Cm !rockridge
+or
+.Cm iso9660:!rockridge
+to disable.
.It Cm gzip:compression-level
A decimal integer from 0 to 9 specifying the gzip compression level.
.It Cm xz:compression-level
@@ -359,7 +366,13 @@ Enable generation of
.Cm /set
lines in the output.
.It Cm mtree:indent
-XXX need explanation XXX
+Produce human-readable output by indenting options and splitting lines
+to fit into 80 columns.
+.It Cm zip:compression Ns = Ns Ar type
+Use
+.Ar type
+as compression method.
+Supported values are store (uncompressed) and deflate (gzip algorithm).
.El
If a provided option is not supported by any module, that
is a fatal error.
@@ -412,10 +425,20 @@ but before security checks.
.It Fl s Ar pattern
Modify file or archive member names according to
.Pa pattern .
-The pattern has the format /old/new/[gps].
-old is a basic regular expression.
-If it doesn't apply, the pattern is skipped.
-new is the replacement string of the matched part.
+The pattern has the format
+.Ar /old/new/ Ns Op gps
+where
+.Ar old
+is a basic regular expression,
+.Ar new
+is the replacement string of the matched part,
+and the optional trailing letters modify
+how the replacement is handled.
+If
+.Ar old
+is not matched, the pattern is skipped.
+Within
+.Ar new ,
~ is substituted with the match, \1 to \9 with the content of
the corresponding captured group.
The optional trailing g specifies that matching should continue
diff --git a/usr.bin/tar/bsdtar.c b/usr.bin/tar/bsdtar.c
index c858ba3..00c6f45 100644
--- a/usr.bin/tar/bsdtar.c
+++ b/usr.bin/tar/bsdtar.c
@@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
#include "bsdtar.h"
#include "err.h"
-#include "matching.h"
/*
* Per POSIX.1-1988, tar defaults to reading/writing archives to/from
@@ -180,8 +179,10 @@ main(int argc, char **argv)
time(&now);
+#if HAVE_SETLOCALE
if (setlocale(LC_ALL, "") == NULL)
bsdtar_warnc(0, "Failed to set default locale");
+#endif
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_D_MD_ORDER)
bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd');
#endif
diff --git a/usr.bin/tar/bsdtar_platform.h b/usr.bin/tar/bsdtar_platform.h
index 5ad8d30..c9b9dd6 100644
--- a/usr.bin/tar/bsdtar_platform.h
+++ b/usr.bin/tar/bsdtar_platform.h
@@ -62,6 +62,10 @@
#include "archive_entry.h"
#endif
+#ifdef HAVE_LIBACL
+#include <acl/libacl.h>
+#endif
+
/*
* Include "dirent.h" (or it's equivalent on several different platforms).
*
diff --git a/usr.bin/tar/matching.c b/usr.bin/tar/matching.c
index 184d29a..dc316b1 100644
--- a/usr.bin/tar/matching.c
+++ b/usr.bin/tar/matching.c
@@ -89,7 +89,7 @@ lafe_exclude_from_file(struct lafe_matching **matching, const char *pathname)
const char *p;
int ret = 0;
- lr = lafe_line_reader(pathname, '\n');
+ lr = lafe_line_reader(pathname, 0);
while ((p = lafe_line_reader_next(lr)) != NULL) {
if (lafe_exclude(matching, p) != 0)
ret = -1;
@@ -156,40 +156,41 @@ lafe_excluded(struct lafe_matching *matching, const char *pathname)
if (matching == NULL)
return (0);
+ /* Mark off any unmatched inclusions. */
+ /* In particular, if a filename does appear in the archive and
+ * is explicitly included and excluded, then we don't report
+ * it as missing even though we don't extract it.
+ */
+ matched = NULL;
+ for (match = matching->inclusions; match != NULL; match = match->next){
+ if (match->matches == 0
+ && match_inclusion(match, pathname)) {
+ matching->inclusions_unmatched_count--;
+ match->matches++;
+ matched = match;
+ }
+ }
+
/* Exclusions take priority */
for (match = matching->exclusions; match != NULL; match = match->next){
if (match_exclusion(match, pathname))
return (1);
}
- /* Then check for inclusions */
- matched = NULL;
+ /* It's not excluded and we found an inclusion above, so it's included. */
+ if (matched != NULL)
+ return (0);
+
+
+ /* We didn't find an unmatched inclusion, check the remaining ones. */
for (match = matching->inclusions; match != NULL; match = match->next){
- if (match_inclusion(match, pathname)) {
- /*
- * If this pattern has never been matched,
- * then we're done.
- */
- if (match->matches == 0) {
- match->matches++;
- matching->inclusions_unmatched_count--;
- return (0);
- }
- /*
- * Otherwise, remember the match but keep checking
- * in case we can tick off an unmatched pattern.
- */
- matched = match;
+ /* We looked at previously-unmatched inclusions already. */
+ if (match->matches > 0
+ && match_inclusion(match, pathname)) {
+ match->matches++;
+ return (0);
}
}
- /*
- * We didn't find a pattern that had never been matched, but
- * we did find a match, so count it and exit.
- */
- if (matched != NULL) {
- matched->matches++;
- return (0);
- }
/* If there were inclusions, default is to exclude. */
if (matching->inclusions != NULL)
diff --git a/usr.bin/tar/subst.c b/usr.bin/tar/subst.c
index 44fd87b..a217293 100644
--- a/usr.bin/tar/subst.c
+++ b/usr.bin/tar/subst.c
@@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
#if HAVE_REGEX_H
#include "bsdtar.h"
-#include "err.h"
#include <errno.h>
#include <regex.h>
@@ -39,6 +38,8 @@ __FBSDID("$FreeBSD$");
#define REG_BASIC 0
#endif
+#include "err.h"
+
struct subst_rule {
struct subst_rule *next;
regex_t re;
diff --git a/usr.bin/tar/tree.h b/usr.bin/tar/tree.h
index 09e36e4..3ae74fd 100644
--- a/usr.bin/tar/tree.h
+++ b/usr.bin/tar/tree.h
@@ -53,16 +53,17 @@ void tree_close(struct tree *);
/*
* tree_next() returns Zero if there is no next entry, non-zero if
- * there is. Note that directories are potentially visited three
- * times. Directories are always visited first as part of enumerating
- * their parent. If tree_descend() is invoked at that time, the
- * directory is added to a work list and will subsequently be visited
- * two more times: once just after descending into the directory and
- * again just after ascending back to the parent.
+ * there is. Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
*
* TREE_ERROR_DIR is returned if the descent failed (because the
* directory couldn't be opened, for instance). This is returned
- * instead of TREE_PREVISIT/TREE_POSTVISIT. TREE_ERROR_DIR is not a
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
* fatal error, but it does imply that the relevant subtree won't be
* visited. TREE_ERROR_FATAL is returned for an error that left the
* traversal completely hosed. Right now, this is only returned for
@@ -96,10 +97,23 @@ void tree_descend(struct tree *);
int tree_current_depth(struct tree *);
/*
- * The current full pathname, length of the full pathname,
- * and a name that can be used to access the file.
- * Because tree does use chdir extensively, the access path is
- * almost never the same as the full current path.
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file. Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ * TODO: Flesh out this interface to provide other information. In
+ * particular, Windows can provide file size, mode, and some permission
+ * information without invoking stat() at all.
+ *
+ * TODO: On platforms that support it, use openat()-style operations
+ * to eliminate the chdir() operations entirely while still supporting
+ * arbitrarily deep traversals. This makes access_path troublesome to
+ * support, of course, which means we'll need a rich enough interface
+ * that clients can function without it. (In particular, we'll need
+ * tree_current_open() that returns an open file descriptor.)
+ *
+ * TODO: Provide tree_current_archive_entry().
*/
const char *tree_current_path(struct tree *);
size_t tree_current_pathlen(struct tree *);
diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c
index 31005eb..207122e 100644
--- a/usr.bin/tar/write.c
+++ b/usr.bin/tar/write.c
@@ -95,6 +95,10 @@ __FBSDID("$FreeBSD$");
/* Fixed size of uname/gname caches. */
#define name_cache_size 101
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
static const char * const NO_NAME = "(noname)";
struct archive_dir_entry {
@@ -256,9 +260,9 @@ tar_mode_r(struct bsdtar *bsdtar)
format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
#if defined(__BORLANDC__)
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT);
+ bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY);
#else
- bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666);
+ bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666);
#endif
if (bsdtar->fd < 0)
bsdtar_errc(1, errno,
@@ -353,7 +357,7 @@ tar_mode_u(struct bsdtar *bsdtar)
/* Sanity-test some arguments and the file. */
test_for_append(bsdtar);
- bsdtar->fd = open(bsdtar->filename, O_RDWR);
+ bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY);
if (bsdtar->fd < 0)
bsdtar_errc(1, errno,
"Cannot open %s", bsdtar->filename);
@@ -843,7 +847,7 @@ write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path)
#if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL)
/* Linux uses ioctl to read flags. */
if (bsdtar->option_honor_nodump) {
- int fd = open(name, O_RDONLY | O_NONBLOCK);
+ int fd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY);
if (fd >= 0) {
unsigned long fflags;
int r = ioctl(fd, EXT2_IOC_GETFLAGS, &fflags);
@@ -913,7 +917,7 @@ write_entry_backend(struct bsdtar *bsdtar, struct archive *a,
if (archive_entry_size(entry) > 0) {
const char *pathname = archive_entry_sourcepath(entry);
- fd = open(pathname, O_RDONLY);
+ fd = open(pathname, O_RDONLY | O_BINARY);
if (fd == -1) {
if (!bsdtar->verbose)
bsdtar_warnc(errno,
diff --git a/usr.bin/touch/touch.c b/usr.bin/touch/touch.c
index 5ceb175..2148939 100644
--- a/usr.bin/touch/touch.c
+++ b/usr.bin/touch/touch.c
@@ -187,9 +187,9 @@ main(int argc, char *argv[])
}
if (!aflag)
- TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atim);
if (!mflag)
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
/*
* We're adjusting the times based on the file times, not a
@@ -197,11 +197,11 @@ main(int argc, char *argv[])
*/
if (Aflag) {
if (aflag) {
- TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atim);
tv[0].tv_sec += Aflag;
}
if (mflag) {
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
tv[1].tv_sec += Aflag;
}
}
@@ -368,8 +368,8 @@ stime_file(char *fname, struct timeval *tvp)
if (stat(fname, &sb))
err(1, "%s", fname);
- TIMESPEC_TO_TIMEVAL(tvp, &sb.st_atimespec);
- TIMESPEC_TO_TIMEVAL(tvp + 1, &sb.st_mtimespec);
+ TIMESPEC_TO_TIMEVAL(tvp, &sb.st_atim);
+ TIMESPEC_TO_TIMEVAL(tvp + 1, &sb.st_mtim);
}
int
diff --git a/usr.bin/truncate/Makefile b/usr.bin/truncate/Makefile
index 4752c5c..1b24d35 100644
--- a/usr.bin/truncate/Makefile
+++ b/usr.bin/truncate/Makefile
@@ -1,5 +1,7 @@
# $FreeBSD$
PROG= truncate
+DPADD= ${LIBUTIL}
+LDADD= -lutil
.include <bsd.prog.mk>
diff --git a/usr.bin/truncate/truncate.c b/usr.bin/truncate/truncate.c
index 3ab068b..12b81af 100644
--- a/usr.bin/truncate/truncate.c
+++ b/usr.bin/truncate/truncate.c
@@ -40,7 +40,8 @@ static const char rcsid[] =
#include <stdlib.h>
#include <unistd.h>
-static int parselength(char *, off_t *);
+#include <libutil.h>
+
static void usage(void);
static int no_create;
@@ -53,7 +54,8 @@ main(int argc, char **argv)
{
struct stat sb;
mode_t omode;
- off_t oflow, rsize, sz, tsize;
+ off_t oflow, rsize, tsize;
+ int64_t sz;
int ch, error, fd, oflags;
char *fname, *rname;
@@ -71,7 +73,7 @@ main(int argc, char **argv)
rname = optarg;
break;
case 's':
- if (parselength(optarg, &sz) == -1)
+ if (expand_number(optarg, &sz) == -1)
errx(EXIT_FAILURE,
"invalid size argument `%s'", optarg);
if (*optarg == '+' || *optarg == '-')
@@ -148,65 +150,6 @@ main(int argc, char **argv)
return error ? EXIT_FAILURE : EXIT_SUCCESS;
}
-/*
- * Return the numeric value of a string given in the form [+-][0-9]+[GMKT]
- * or -1 on format error or overflow.
- */
-static int
-parselength(char *ls, off_t *sz)
-{
- off_t length, oflow;
- int lsign;
-
- length = 0;
- lsign = 1;
-
- switch (*ls) {
- case '-':
- lsign = -1;
- case '+':
- ls++;
- }
-
-#define ASSIGN_CHK_OFLOW(x, y) if (x < y) return -1; y = x
- /*
- * Calculate the value of the decimal digit string, failing
- * on overflow.
- */
- while (isdigit(*ls)) {
- oflow = length * 10 + *ls++ - '0';
- ASSIGN_CHK_OFLOW(oflow, length);
- }
-
- switch (*ls) {
- case 'T':
- case 't':
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case 'G':
- case 'g':
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case 'M':
- case 'm':
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case 'K':
- case 'k':
- if (ls[1] != '\0')
- return -1;
- oflow = length * 1024;
- ASSIGN_CHK_OFLOW(oflow, length);
- case '\0':
- break;
- default:
- return -1;
- }
-
- *sz = length * lsign;
- return 0;
-}
-
static void
usage(void)
{
diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c
index bfd39c2..b6a5195 100644
--- a/usr.bin/truss/amd64-fbsd.c
+++ b/usr.bin/truss/amd64-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c
index 3b1b882..ec8b406 100644
--- a/usr.bin/truss/amd64-fbsd32.c
+++ b/usr.bin/truss/amd64-fbsd32.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c
index 5e9d012..f392a4b 100644
--- a/usr.bin/truss/amd64-linux32.c
+++ b/usr.bin/truss/amd64-linux32.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/extern.h b/usr.bin/truss/extern.h
index fc3b038..322e291 100644
--- a/usr.bin/truss/extern.h
+++ b/usr.bin/truss/extern.h
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c
index 3a81392..9c20eb5 100644
--- a/usr.bin/truss/i386-fbsd.c
+++ b/usr.bin/truss/i386-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c
index cf4c1c0..8e0aa04 100644
--- a/usr.bin/truss/i386-linux.c
+++ b/usr.bin/truss/i386-linux.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/ia64-fbsd.c b/usr.bin/truss/ia64-fbsd.c
index dae1116..e631707 100644
--- a/usr.bin/truss/ia64-fbsd.c
+++ b/usr.bin/truss/ia64-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c
index 586fcd6..5c7da1d 100644
--- a/usr.bin/truss/main.c
+++ b/usr.bin/truss/main.c
@@ -1,5 +1,5 @@
/*-
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c
index cf5e2e1..55cbdb1 100644
--- a/usr.bin/truss/mips-fbsd.c
+++ b/usr.bin/truss/mips-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1998 Sean Eric Fagan
+ * Copyright 1998 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c
index 8de66ee..ab5b9a4 100644
--- a/usr.bin/truss/powerpc-fbsd.c
+++ b/usr.bin/truss/powerpc-fbsd.c
@@ -1,7 +1,7 @@
/*
* Copyright 2006 Peter Grehan <grehan@freebsd.org>
- * Copryight 2005 Orlando Bassotto <orlando@break.net>
- * Copryight 1998 Sean Eric Fagan
+ * Copyright 2005 Orlando Bassotto <orlando@break.net>
+ * Copyright 1998 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
index 53a6fe1..ce18f98 100644
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -1,5 +1,5 @@
/*-
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c
index d06e6b0..2eb21bd 100644
--- a/usr.bin/truss/sparc64-fbsd.c
+++ b/usr.bin/truss/sparc64-fbsd.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1998 Sean Eric Fagan
+ * Copyright 1998 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index f927e1e..7ef8e19 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -1,5 +1,5 @@
/*
- * Copryight 1997 Sean Eric Fagan
+ * Copyright 1997 Sean Eric Fagan
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h
index 89198c9..4bf5a55 100644
--- a/usr.bin/truss/truss.h
+++ b/usr.bin/truss/truss.h
@@ -1,5 +1,5 @@
/*
- * Copryight 2001 Jamey Wood
+ * Copyright 2001 Jamey Wood
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/usr.bin/unifdef/unifdef.1 b/usr.bin/unifdef/unifdef.1
index da7cde8..0803d72 100644
--- a/usr.bin/unifdef/unifdef.1
+++ b/usr.bin/unifdef/unifdef.1
@@ -29,11 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94
-.\" $dotat: unifdef/unifdef.1,v 1.63 2010/02/19 16:41:15 fanf2 Exp $
.\" $FreeBSD$
.\"
-.Dd January 19, 2010
+.Dd March 11, 2010
.Dt UNIFDEF 1
.Os
.Sh NAME
@@ -41,7 +39,7 @@
.Nd remove preprocessor conditionals from code
.Sh SYNOPSIS
.Nm
-.Op Fl BbcdeKknst
+.Op Fl bBcdeKknsStV
.Op Fl I Ns Ar path
.Op Fl D Ns Ar sym Ns Op = Ns Ar val
.Op Fl U Ns Ar sym
@@ -184,12 +182,6 @@ Specify that a symbol is undefined.
If the same symbol appears in more than one argument,
the last occurrence dominates.
.Pp
-.It Fl B
-Compress blank lines around a deleted section.
-Mutually exclusive with the
-.Fl b
-option.
-.Pp
.It Fl b
Replace removed lines with blank lines
instead of deleting them.
@@ -197,6 +189,12 @@ Mutually exclusive with the
.Fl B
option.
.Pp
+.It Fl B
+Compress blank lines around a deleted section.
+Mutually exclusive with the
+.Fl b
+option.
+.Pp
.It Fl c
If the
.Fl c
@@ -285,6 +283,13 @@ for creating
.Nm
command lines.
.Pp
+.It Fl S
+Like the
+.Fl s
+option, but the nesting depth of each symbol is also printed.
+This is useful for working out the number of possible combinations
+of interdependent defined/undefined symbols.
+.Pp
.It Fl t
Disables parsing for C comments
and line continuations,
@@ -329,6 +334,9 @@ for compatibility with
.Xr cpp 1
and to simplify the implementation of
.Nm unifdefall .
+.Pp
+.It Fl V
+Print version details.
.El
.Pp
The
diff --git a/usr.bin/unifdef/unifdef.c b/usr.bin/unifdef/unifdef.c
index cdcc403..b8f99f8 100644
--- a/usr.bin/unifdef/unifdef.c
+++ b/usr.bin/unifdef/unifdef.c
@@ -56,12 +56,12 @@
#include <string.h>
#include <unistd.h>
-#ifdef __IDSTRING
-__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.198 2010/02/19 16:37:05 fanf2 Exp $");
-#endif
-#ifdef __FBSDID
-__FBSDID("$FreeBSD$");
-#endif
+const char copyright[] =
+ "@(#) $Version: unifdef-2.3 $\n"
+ "@(#) $FreeBSD$\n"
+ "@(#) $Author: Tony Finch (dot@dotat.at) $\n"
+ "@(#) $URL: http://dotat.at/prog/unifdef $\n"
+;
/* types of input lines: */
typedef enum {
@@ -172,6 +172,7 @@ static bool strictlogic; /* -K: keep ambiguous #ifs */
static bool killconsts; /* -k: eval constant #ifs */
static bool lnnum; /* -n: add #line directives */
static bool symlist; /* -s: output symbol list */
+static bool symdepth; /* -S: output symbol depth */
static bool text; /* -t: this is a text file */
static const char *symname[MAXSYMS]; /* symbol name */
@@ -204,6 +205,8 @@ static int delcount; /* count of deleted lines */
static unsigned blankcount; /* count of blank lines */
static unsigned blankmax; /* maximum recent blankcount */
static bool constexpr; /* constant #if expression */
+static bool zerosyms = true; /* to format symdepth output */
+static bool firstsym; /* ditto */
static int exitstat; /* program exit status */
@@ -228,6 +231,7 @@ static void state(Ifstate);
static int strlcmp(const char *, const char *, size_t);
static void unnest(void);
static void usage(void);
+static void version(void);
#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
@@ -239,7 +243,7 @@ main(int argc, char *argv[])
{
int opt;
- while ((opt = getopt(argc, argv, "i:D:U:I:o:BbcdeKklnst")) != -1)
+ while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1)
switch (opt) {
case 'i': /* treat stuff controlled by these symbols as text */
/*
@@ -261,16 +265,15 @@ main(int argc, char *argv[])
case 'U': /* undef a symbol */
addsym(false, false, optarg);
break;
- case 'I':
- /* no-op for compatibility with cpp */
- break;
- case 'B': /* compress blank lines around removed section */
- compblank = true;
+ case 'I': /* no-op for compatibility with cpp */
break;
case 'b': /* blank deleted lines instead of omitting them */
case 'l': /* backwards compatibility */
lnblank = true;
break;
+ case 'B': /* compress blank lines around removed section */
+ compblank = true;
+ break;
case 'c': /* treat -D as -U and vice versa */
complement = true;
break;
@@ -295,9 +298,14 @@ main(int argc, char *argv[])
case 's': /* only output list of symbols that control #ifs */
symlist = true;
break;
+ case 'S': /* list symbols with their nesting depth */
+ symlist = symdepth = true;
+ break;
case 't': /* don't parse C comments */
text = true;
break;
+ case 'V': /* print version */
+ version();
default:
usage();
}
@@ -309,7 +317,7 @@ main(int argc, char *argv[])
errx(2, "can only do one file");
} else if (argc == 1 && strcmp(*argv, "-") != 0) {
filename = *argv;
- input = fopen(filename, "r");
+ input = fopen(filename, "rb");
if (input == NULL)
err(2, "can't open %s", filename);
} else {
@@ -345,12 +353,12 @@ main(int argc, char *argv[])
TEMPLATE);
ofd = mkstemp(tempname);
if (ofd != -1)
- output = fdopen(ofd, "w+");
+ output = fdopen(ofd, "wb+");
if (output == NULL)
err(2, "can't create temporary file");
- fchmod(ofd, ist.st_mode & ACCESSPERMS);
+ fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
} else {
- output = fopen(ofilename, "w");
+ output = fopen(ofilename, "wb");
if (output == NULL)
err(2, "can't open %s", ofilename);
}
@@ -360,9 +368,23 @@ main(int argc, char *argv[])
}
static void
+version(void)
+{
+ const char *c = copyright;
+ for (;;) {
+ while (*++c != '$')
+ if (*c == '\0')
+ exit(0);
+ while (*++c != '$')
+ putc(*c, stderr);
+ putc('\n', stderr);
+ }
+}
+
+static void
usage(void)
{
- fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]"
+ fprintf(stderr, "usage: unifdef [-bBcdeKknsStV] [-Ipath]"
" [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
exit(2);
}
@@ -557,6 +579,8 @@ flushline(bool keep)
delcount += 1;
blankcount = 0;
}
+ if (debugging)
+ fflush(output);
}
/*
@@ -565,17 +589,14 @@ flushline(bool keep)
static void
process(void)
{
- Linetype lineval;
-
/* When compressing blank lines, act as if the file
is preceded by a large number of blank lines. */
blankmax = blankcount = 1000;
for (;;) {
- linenum++;
- lineval = parseline();
+ Linetype lineval = parseline();
trans_table[ifstate[depth]][lineval]();
- debug("process %s -> %s depth %d",
- linetype_name[lineval],
+ debug("process line %d %s -> %s depth %d",
+ linenum, linetype_name[lineval],
ifstate_name[ifstate[depth]], depth);
}
}
@@ -586,6 +607,8 @@ process(void)
static void
closeout(void)
{
+ if (symdepth && !zerosyms)
+ printf("\n");
if (fclose(output) == EOF) {
warn("couldn't write to %s", ofilename);
if (overwriting) {
@@ -628,6 +651,7 @@ parseline(void)
Linetype retval;
Comment_state wascomment;
+ linenum++;
if (fgets(tline, MAXLINE, input) == NULL)
return (LT_EOF);
if (newline == NULL) {
@@ -642,6 +666,7 @@ parseline(void)
if (linestate == LS_START) {
if (*cp == '#') {
linestate = LS_HASH;
+ firstsym = true;
cp = skipcomment(cp + 1);
} else if (*cp != '\0')
linestate = LS_DIRTY;
@@ -715,7 +740,7 @@ parseline(void)
while (*cp != '\0')
cp = skipcomment(cp + 1);
}
- debug("parser %s comment %s line",
+ debug("parser line %d state %s comment %s line", linenum,
comment_name[incomment], linestate_name[linestate]);
return (retval);
}
@@ -1108,7 +1133,13 @@ findsym(const char *str)
if (cp == str)
return (-1);
if (symlist) {
- printf("%.*s\n", (int)(cp-str), str);
+ if (symdepth && firstsym)
+ printf("%s%3d", zerosyms ? "" : "\n", depth);
+ firstsym = zerosyms = false;
+ printf("%s%.*s%s",
+ symdepth ? " " : "",
+ (int)(cp-str), str,
+ symdepth ? "" : "\n");
/* we don't care about the value of the symbol */
return (0);
}
@@ -1153,6 +1184,8 @@ addsym(bool ignorethis, bool definethis, char *sym)
usage();
value[symind] = NULL;
}
+ debug("addsym %s=%s", symname[symind],
+ value[symind] ? value[symind] : "undef");
}
/*
diff --git a/usr.bin/unifdef/unifdefall.sh b/usr.bin/unifdef/unifdefall.sh
index 179fc93..c9a04cc 100644
--- a/usr.bin/unifdef/unifdefall.sh
+++ b/usr.bin/unifdef/unifdefall.sh
@@ -26,7 +26,6 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $dotat: unifdef/unifdefall.sh,v 1.27 2010/01/19 16:09:50 fanf2 Exp $
# $FreeBSD$
set -e
@@ -36,17 +35,21 @@ if [ ! -e "$unifdef" ]
then
unifdef=unifdef
fi
-# export to the final shell command
-export unifdef
+
+case "$@" in
+"-d "*) echo DEBUGGING 1>&2
+ debug=-d
+ shift
+esac
basename=$(basename "$0")
tmp=$(mktemp -d "${TMPDIR:-/tmp}/$basename.XXXXXXXXXX") || exit 2
-trap 'rm -r "$tmp" || exit 1' EXIT
+trap 'rm -r "$tmp" || exit 2' EXIT
export LC_ALL=C
# list of all controlling macros
-"$unifdef" -s "$@" | sort | uniq >"$tmp/ctrl"
+"$unifdef" $debug -s "$@" | sort | uniq >"$tmp/ctrl"
# list of all macro definitions
cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs"
# list of defined macro names
@@ -58,7 +61,7 @@ comm -12 "$tmp/ctrl" "$tmp/alldef" >"$tmp/def"
# and converts them to unifdef command-line arguments
sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
# create the final unifdef command
-{ echo '"$unifdef" -k \'
+{ echo "$unifdef" $debug -k '\'
# convert the controlling undefined macros to -U arguments
sed 's/.*/-U& \\/' <"$tmp/undef"
# convert the controlling defined macros to quoted -D arguments
@@ -66,5 +69,11 @@ sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
sed "s/'/'\\\\''/g;s/.*/'&' \\\\/"
echo '"$@"'
} >"$tmp/cmd"
+case $debug in
+-d) for i in ctrl hashdefs alldef undef def script cmd
+ do echo ==== $i
+ cat "$tmp/$i"
+ done 1>&2
+esac
# run the command we just created
sh "$tmp/cmd" "$@"
diff --git a/usr.bin/uniq/uniq.c b/usr.bin/uniq/uniq.c
index 2b11fe4..605bd00 100644
--- a/usr.bin/uniq/uniq.c
+++ b/usr.bin/uniq/uniq.c
@@ -53,6 +53,7 @@ static const char rcsid[] =
#include <limits.h>
#include <locale.h>
#include <stdint.h>
+#define _WITH_GETLINE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -60,31 +61,26 @@ static const char rcsid[] =
#include <wchar.h>
#include <wctype.h>
-#define INITLINELEN (LINE_MAX + 1)
-#define MAXLINELEN ((SIZE_MAX / sizeof(wchar_t)) / 2)
-
-int cflag, dflag, uflag;
+int cflag, dflag, uflag, iflag;
int numchars, numfields, repeats;
FILE *file(const char *, const char *);
-wchar_t *getline(wchar_t *, size_t *, FILE *);
-void show(FILE *, wchar_t *);
+wchar_t *convert(const char *);
+int inlcmp(const char *, const char *);
+void show(FILE *, const char *);
wchar_t *skip(wchar_t *);
void obsolete(char *[]);
static void usage(void);
-int wcsicoll(wchar_t *, wchar_t *);
int
main (int argc, char *argv[])
{
- wchar_t *t1, *t2;
+ wchar_t *tprev, *tthis;
FILE *ifp, *ofp;
- int ch, b1;
- size_t prevbuflen, thisbuflen;
- wchar_t *prevline, *thisline;
- char *p;
+ int ch, comp;
+ size_t prevbuflen, thisbuflen, b1;
+ char *prevline, *thisline, *p;
const char *ifn;
- int iflag = 0, comp;
(void) setlocale(LC_ALL, "");
@@ -139,48 +135,48 @@ main (int argc, char *argv[])
if (argc > 1)
ofp = file(argv[1], "w");
- prevbuflen = INITLINELEN;
- thisbuflen = INITLINELEN;
- prevline = malloc(prevbuflen * sizeof(*prevline));
- thisline = malloc(thisbuflen * sizeof(*thisline));
- if (prevline == NULL || thisline == NULL)
- err(1, "malloc");
+ prevbuflen = thisbuflen = 0;
+ prevline = thisline = NULL;
- if ((prevline = getline(prevline, &prevbuflen, ifp)) == NULL) {
+ if (getline(&prevline, &prevbuflen, ifp) < 0) {
if (ferror(ifp))
err(1, "%s", ifn);
exit(0);
}
+ tprev = convert(prevline);
+
if (!cflag && uflag && dflag)
show(ofp, prevline);
- while ((thisline = getline(thisline, &thisbuflen, ifp)) != NULL) {
- /* If requested get the chosen fields + character offsets. */
- if (numfields || numchars) {
- t1 = skip(thisline);
- t2 = skip(prevline);
- } else {
- t1 = thisline;
- t2 = prevline;
- }
+ tthis = NULL;
+ while (getline(&thisline, &thisbuflen, ifp) >= 0) {
+ if (tthis != NULL)
+ free(tthis);
+ tthis = convert(thisline);
- /* If different, print; set previous to new value. */
- if (iflag)
- comp = wcsicoll(t1, t2);
+ if (tthis == NULL && tprev == NULL)
+ comp = inlcmp(thisline, prevline);
+ else if (tthis == NULL || tprev == NULL)
+ comp = 1;
else
- comp = wcscoll(t1, t2);
+ comp = wcscoll(tthis, tprev);
if (comp) {
+ /* If different, print; set previous to new value. */
if (cflag || !dflag || !uflag)
show(ofp, prevline);
- t1 = prevline;
+ p = prevline;
b1 = prevbuflen;
prevline = thisline;
prevbuflen = thisbuflen;
+ if (tprev != NULL)
+ free(tprev);
+ tprev = tthis;
if (!cflag && uflag && dflag)
show(ofp, prevline);
- thisline = t1;
+ thisline = p;
thisbuflen = b1;
+ tthis = NULL;
repeats = 0;
} else
++repeats;
@@ -193,28 +189,55 @@ main (int argc, char *argv[])
}
wchar_t *
-getline(wchar_t *buf, size_t *buflen, FILE *fp)
+convert(const char *str)
{
- size_t bufpos;
- wint_t ch;
-
- bufpos = 0;
- while ((ch = getwc(fp)) != WEOF && ch != '\n') {
- if (bufpos + 1 >= *buflen) {
- *buflen = *buflen * 2;
- if (*buflen > MAXLINELEN)
- errx(1,
- "Maximum line buffer length (%zu) exceeded",
- MAXLINELEN);
- buf = reallocf(buf, *buflen * sizeof(*buf));
- if (buf == NULL)
- err(1, "reallocf");
- }
- buf[bufpos++] = ch;
+ size_t n;
+ wchar_t *buf, *ret, *p;
+
+ if ((n = mbstowcs(NULL, str, 0)) == (size_t)-1)
+ return (NULL);
+ if (SIZE_MAX / sizeof(*buf) < n + 1)
+ errx(1, "conversion buffer length overflow");
+ if ((buf = malloc((n + 1) * sizeof(*buf))) == NULL)
+ err(1, "malloc");
+ if (mbstowcs(buf, str, n + 1) != n)
+ errx(1, "internal mbstowcs() error");
+ /* The last line may not end with \n. */
+ if (n > 0 && buf[n - 1] == L'\n')
+ buf[n - 1] = L'\0';
+
+ /* If requested get the chosen fields + character offsets. */
+ if (numfields || numchars) {
+ if ((ret = wcsdup(skip(buf))) == NULL)
+ err(1, "wcsdup");
+ free(buf);
+ } else
+ ret = buf;
+
+ if (iflag) {
+ for (p = ret; *p != L'\0'; p++)
+ *p = towlower(*p);
}
- buf[bufpos] = '\0';
- return (bufpos != 0 || ch == '\n' ? buf : NULL);
+ return (ret);
+}
+
+int
+inlcmp(const char *s1, const char *s2)
+{
+ int c1, c2;
+
+ while (*s1 == *s2++)
+ if (*s1++ == '\0')
+ return (0);
+ c1 = (unsigned char)*s1;
+ c2 = (unsigned char)*(s2 - 1);
+ /* The last line may not end with \n. */
+ if (c1 == '\n')
+ c1 = '\0';
+ if (c2 == '\n')
+ c2 = '\0';
+ return (c1 - c2);
}
/*
@@ -223,13 +246,13 @@ getline(wchar_t *buf, size_t *buflen, FILE *fp)
* of the line.
*/
void
-show(FILE *ofp, wchar_t *str)
+show(FILE *ofp, const char *str)
{
if (cflag)
- (void)fprintf(ofp, "%4d %ls\n", repeats + 1, str);
+ (void)fprintf(ofp, "%4d %s", repeats + 1, str);
if ((dflag && repeats) || (uflag && !repeats))
- (void)fprintf(ofp, "%ls\n", str);
+ (void)fprintf(ofp, "%s", str);
}
wchar_t *
@@ -237,13 +260,14 @@ skip(wchar_t *str)
{
int nchars, nfields;
- for (nfields = 0; *str != '\0' && nfields++ != numfields; ) {
+ for (nfields = 0; *str != L'\0' && nfields++ != numfields; ) {
while (iswblank(*str))
str++;
- while (*str != '\0' && !iswblank(*str))
+ while (*str != L'\0' && !iswblank(*str))
str++;
}
- for (nchars = numchars; nchars-- && *str; ++str);
+ for (nchars = numchars; nchars-- && *str != L'\0'; ++str)
+ ;
return(str);
}
@@ -293,52 +317,3 @@ usage(void)
"usage: uniq [-c | -d | -u] [-i] [-f fields] [-s chars] [input [output]]\n");
exit(1);
}
-
-static size_t wcsicoll_l1_buflen = 0, wcsicoll_l2_buflen = 0;
-static wchar_t *wcsicoll_l1_buf = NULL, *wcsicoll_l2_buf = NULL;
-
-int
-wcsicoll(wchar_t *s1, wchar_t *s2)
-{
- wchar_t *p;
- size_t l1, l2;
- size_t new_l1_buflen, new_l2_buflen;
-
- l1 = wcslen(s1) + 1;
- l2 = wcslen(s2) + 1;
- new_l1_buflen = wcsicoll_l1_buflen;
- new_l2_buflen = wcsicoll_l2_buflen;
- while (new_l1_buflen < l1) {
- if (new_l1_buflen == 0)
- new_l1_buflen = INITLINELEN;
- else
- new_l1_buflen *= 2;
- }
- while (new_l2_buflen < l2) {
- if (new_l2_buflen == 0)
- new_l2_buflen = INITLINELEN;
- else
- new_l2_buflen *= 2;
- }
- if (new_l1_buflen > wcsicoll_l1_buflen) {
- wcsicoll_l1_buf = reallocf(wcsicoll_l1_buf, new_l1_buflen * sizeof(*wcsicoll_l1_buf));
- if (wcsicoll_l1_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l1_buflen = new_l1_buflen;
- }
- if (new_l2_buflen > wcsicoll_l2_buflen) {
- wcsicoll_l2_buf = reallocf(wcsicoll_l2_buf, new_l2_buflen * sizeof(*wcsicoll_l2_buf));
- if (wcsicoll_l2_buf == NULL)
- err(1, "reallocf");
- wcsicoll_l2_buflen = new_l2_buflen;
- }
-
- for (p = wcsicoll_l1_buf; *s1; s1++)
- *p++ = towlower(*s1);
- *p = '\0';
- for (p = wcsicoll_l2_buf; *s2; s2++)
- *p++ = towlower(*s2);
- *p = '\0';
-
- return (wcscoll(wcsicoll_l1_buf, wcsicoll_l2_buf));
-}
diff --git a/usr.bin/wtmpcvt/wtmpcvt.1 b/usr.bin/wtmpcvt/wtmpcvt.1
index fdc995b..50f89ee 100644
--- a/usr.bin/wtmpcvt/wtmpcvt.1
+++ b/usr.bin/wtmpcvt/wtmpcvt.1
@@ -25,8 +25,8 @@
.\" $FreeBSD$
.\"
.Dd January 14, 2010
-.Os
.Dt WTMPCVT 1
+.Os
.Sh NAME
.Nm wtmpcvt
.Nd convert wtmp files to the utmpx format
diff --git a/usr.bin/xlint/lint1/decl.c b/usr.bin/xlint/lint1/decl.c
index 69c7cda..41492cf 100644
--- a/usr.bin/xlint/lint1/decl.c
+++ b/usr.bin/xlint/lint1/decl.c
@@ -825,15 +825,15 @@ getbound(type_t *tp)
} else if (t == FUNC) {
/* compiler takes alignment of function */
error(14);
- a = ALIGN(1) * CHAR_BIT;
+ a = LINT_ALIGN(1) * CHAR_BIT;
} else {
if ((a = size(t)) == 0) {
a = CHAR_BIT;
- } else if (a > ALIGN(1) * CHAR_BIT) {
- a = ALIGN(1) * CHAR_BIT;
+ } else if (a > LINT_ALIGN(1) * CHAR_BIT) {
+ a = LINT_ALIGN(1) * CHAR_BIT;
}
}
- if (a < CHAR_BIT || a > ALIGN(1) * CHAR_BIT)
+ if (a < CHAR_BIT || a > LINT_ALIGN(1) * CHAR_BIT)
lerror("getbound() 1");
return (a);
}
diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h
index fe1a524..6cfcbb7 100644
--- a/usr.bin/xlint/lint1/lint1.h
+++ b/usr.bin/xlint/lint1/lint1.h
@@ -38,8 +38,8 @@ __FBSDID("$FreeBSD$");
#include "op.h"
/* XXX - works for most systems, but the whole ALIGN thing needs to go away */
-#ifndef ALIGN
-#define ALIGN(x) (((x) + 7) & ~7)
+#ifndef LINT_ALIGN
+#define LINT_ALIGN(x) (((x) + 15) & ~15)
#endif
/*
diff --git a/usr.bin/xlint/lint1/mem1.c b/usr.bin/xlint/lint1/mem1.c
index 24e911e..280a63c 100644
--- a/usr.bin/xlint/lint1/mem1.c
+++ b/usr.bin/xlint/lint1/mem1.c
@@ -203,7 +203,7 @@ xgetblk(mbl_t **mbp, size_t s)
void *p;
size_t t = 0;
- s = ALIGN(s);
+ s = LINT_ALIGN(s);
if ((mb = *mbp) == NULL || mb->nfree < s) {
if ((mb = frmblks) == NULL) {
if (s > mblklen) {
diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l
index ea5a2c5..05f4ed7 100644
--- a/usr.bin/xlint/lint1/scan.l
+++ b/usr.bin/xlint/lint1/scan.l
@@ -319,7 +319,7 @@ allocsb(void)
if ((sb = malloc(sizeof (sbuf_t))) == NULL)
nomem();
}
- (void)memset(sb, 0, sizeof (sb));
+ (void)memset(sb, 0, sizeof (*sb));
return (sb);
}
OpenPOWER on IntegriCloud