Hello, all.
This allows fortune(6) to open fortune files via symlinks.
Maybe this is a stupid idea, I dunno, but it seems inconsistent
that I can't put a symlink to my fortunes collection in
/usr/share/games/fortune and then simply call "fortune foo"
instead of "fortune /usr/local/share/games/fortune/ru/foo".
I decided to call readlink(2) explicitly rather than adding
check of file type being open, since that resulted in less code.
Ah, and yes, I have a port of Russian fortune files pending,
but that's for another list and another day.
So... okay/notokay anyone? :)
--
WBR,
Vadim Zhukov
Index: fortune.c
===================================================================
RCS file: /cvs/src/games/fortune/fortune/fortune.c,v
retrieving revision 1.60
diff -u -p -r1.60 fortune.c
--- fortune.c 10 Aug 2017 17:00:08 -0000 1.60
+++ fortune.c 14 Dec 2020 22:05:33 -0000
@@ -39,6 +39,7 @@
#include <ctype.h>
#include <dirent.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <locale.h>
@@ -388,8 +389,9 @@ add_file(int percent, char *file, char *
FILEDESC *parent)
{
FILEDESC *fp;
+ ssize_t lnklen;
int fd;
- char *path, *offensive;
+ char *path, *offensive, lnkpath[PATH_MAX];
bool was_malloc;
bool isdir;
@@ -420,8 +422,22 @@ add_file(int percent, char *file, char *
}
DPRINTF(1, (stderr, "adding file \"%s\"\n", path));
+
over:
+ lnklen = readlink(path, lnkpath, PATH_MAX);
+ if (lnklen == -1) {
+ if (errno != EINVAL)
+ goto openfailed;
+ } else {
+ lnkpath[lnklen] = '\0';
+ if (was_malloc)
+ free(path);
+ path = strdup(lnkpath);
+ was_malloc = 1;
+ }
+
if ((fd = open(path, O_RDONLY)) < 0) {
+openfailed:
/*
* This is a sneak. If the user said -a, and if the
* file we're given isn't a file, we check to see if