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

Reply via email to