git: bcfe05c6b683 - stable/14 - calendar: correct the search order for files

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Wed, 03 Jan 2024 04:48:23 UTC
The branch stable/14 has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=bcfe05c6b6835d359025fb27f064c6aab537e7b4

commit bcfe05c6b6835d359025fb27f064c6aab537e7b4
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2023-12-18 05:53:03 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-01-03 04:47:22 +0000

    calendar: correct the search order for files
    
    Include files that don't begin with a '/' are documented to search the
    current directory, then /usr/share/calendar.  This hasn't been accurate
    for years, since e061f95e7b9b ("Rework calendar(1) parser") rewrote a
    lot of this.
    
    Stash off the cwd before we do any chdir()ing around and use that to
    honor the same order we'll follow for the -f flag.  This may result in
    an extra lookup that will fail for the initial calendar file, but I
    don't think it's worth the complexity to avoid it.
    
    While we're here, fix the documentation to just reference the order
    described in FILES so that we only need to keep it up to date in one
    place.
    
    Reviewed by:    bapt
    Sponsored by:   Klara, Inc.
    
    (cherry picked from commit 0a82cd4f101c5eb8533a0049aaa3f06f005cf8af)
---
 usr.bin/calendar/calendar.1 |  7 +++----
 usr.bin/calendar/io.c       | 31 +++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/usr.bin/calendar/calendar.1 b/usr.bin/calendar/calendar.1
index 898ef8fb4a3d..3b1e6a420d15 100644
--- a/usr.bin/calendar/calendar.1
+++ b/usr.bin/calendar/calendar.1
@@ -27,7 +27,7 @@
 .\"
 .\"     @(#)calendar.1  8.1 (Berkeley) 6/29/93
 .\"
-.Dd July 31, 2022
+.Dd December 17, 2023
 .Dt CALENDAR 1
 .Os
 .Sh NAME
@@ -215,9 +215,8 @@ succeeding lines.
 .Pp
 If the shared file is not referenced by a full pathname,
 .Nm
-searches in the current (or home) directory first, and then in the
-directory
-.Pa /usr/share/calendar .
+searches in the same order of precedence described in
+.Sx FILES .
 .Pp
 Blank lines and text protected by the C comment syntax
 .Ql /* ... */
diff --git a/usr.bin/calendar/io.c b/usr.bin/calendar/io.c
index 5390882305a0..d407addd9b89 100644
--- a/usr.bin/calendar/io.c
+++ b/usr.bin/calendar/io.c
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)calendar.c  8.3 (Berkeley) 3/25/94";
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <libutil.h>
 #include <locale.h>
 #include <pwd.h>
@@ -115,9 +116,11 @@ trimlr(char **buf)
 static FILE *
 cal_fopen(const char *file)
 {
+	static int cwdfd = -1;
 	FILE *fp;
 	char *home = getenv("HOME");
 	unsigned int i;
+	int fd;
 	struct stat sb;
 	static bool warned = false;
 	static char calendarhome[MAXPATHLEN];
@@ -127,6 +130,34 @@ cal_fopen(const char *file)
 		return (NULL);
 	}
 
+	/*
+	 * On -a runs, we would have done a chdir() earlier on, but we also
+	 * shouldn't have used the initial cwd anyways lest we bring
+	 * unpredictable behavior upon us.
+	 */
+	if (!doall && cwdfd == -1) {
+		cwdfd = open(".", O_DIRECTORY | O_PATH);
+		if (cwdfd == -1)
+			err(1, "open(cwd)");
+	}
+
+	/*
+	 * Check $PWD first as documented.
+	 */
+	if (cwdfd != -1) {
+		if ((fd = openat(cwdfd, file, O_RDONLY)) != -1) {
+			if ((fp = fdopen(fd, "r")) == NULL)
+				err(1, "fdopen(%s)", file);
+
+			cal_home = NULL;
+			cal_dir = NULL;
+			cal_file = file;
+			return (fp);
+		} else if (errno != ENOENT && errno != ENAMETOOLONG) {
+			err(1, "open(%s)", file);
+		}
+	}
+
 	if (chdir(home) != 0) {
 		warnx("Cannot enter home directory \"%s\"", home);
 		return (NULL);