The branch main has been updated by fernape:

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

commit edadc3f9051595a9c2e693d8ab666a50b9e7a21a
Author:     Fernando Apesteguía <[email protected]>
AuthorDate: 2026-08-23 15:46:18 +0000
Commit:     Fernando Apesteguía <[email protected]>
CommitDate: 2026-08-29 15:15:43 +0000

    whereis(1): Respect PORTSDIR variable
    
    PORTSDIR is a very common variable that points to the location of a ports
    directory. Make whereis(1) respect this variable too.
    
    Reviewed by:    arrowd@, christos@
    Approved by:    christos@
    Differential Revision:  https://reviews.freebsd.org/D56845
---
 usr.bin/whereis/whereis.1 |   4 ++
 usr.bin/whereis/whereis.c | 118 +++++++++++++++++++++++++---------------------
 2 files changed, 69 insertions(+), 53 deletions(-)

diff --git a/usr.bin/whereis/whereis.1 b/usr.bin/whereis/whereis.1
index 90922ce61db5..1b6adaeaf077 100644
--- a/usr.bin/whereis/whereis.1
+++ b/usr.bin/whereis/whereis.1
@@ -72,6 +72,10 @@ including all the subdirectories of
 .Pa /usr/src
 and
 .Pa /usr/ports .
+If the environment variable
+.Ev PORTSDIR
+is defined and points to a directory then all its subdirectories
+are included in the search of program sources.
 .Pp
 The following options are available:
 .Bl -tag -width indent
diff --git a/usr.bin/whereis/whereis.c b/usr.bin/whereis/whereis.c
index 8de56b9cf654..afc099276dfe 100644
--- a/usr.bin/whereis/whereis.c
+++ b/usr.bin/whereis/whereis.c
@@ -312,64 +312,76 @@ defaults(void)
                        abort();
                nele = 0;
                decolonify(b, &sourcedirs, &nele);
-
-               if (stat(PATH_PORTS, &sb) == -1) {
-                       if (errno == ENOENT)
-                               /* no /usr/ports, we are done */
-                               return;
-                       err(EX_OSERR, "stat(" PATH_PORTS ")");
+               ccharp path_ports;
+               if ((cp = getenv("PORTSDIR")) != NULL) {
+                       b = strdup(cp);
+                       if (b == NULL)
+                               abort();
                }
-               if ((sb.st_mode & S_IFMT) != S_IFDIR)
-                       /* /usr/ports is not a directory, ignore */
-                       return;
-               if (access(PATH_PORTS, R_OK | X_OK) != 0)
-                       return;
-               if ((dir = opendir(PATH_PORTS)) == NULL)
-                       err(EX_OSERR, "opendir" PATH_PORTS ")");
-               while ((dirp = readdir(dir)) != NULL) {
-                       /*
-                        * Not everything below PATH_PORTS is of
-                        * interest.  First, all dot files and
-                        * directories (e. g. .snap) can be ignored.
-                        * Also, all subdirectories starting with a
-                        * capital letter are not going to be
-                        * examined, as they are used for internal
-                        * purposes (Mk, Tools, ...).  This also
-                        * matches a possible CVS subdirectory.
-                        * Finally, the distfiles subdirectory is also
-                        * special, and should not be considered to
-                        * avoid false matches.
-                        */
-                       if (dirp->d_name[0] == '.' ||
-                           /*
-                            * isupper() not used on purpose: the
-                            * check is supposed to default to the C
-                            * locale instead of the current user's
-                            * locale.
-                            */
-                           (dirp->d_name[0] >= 'A' && dirp->d_name[0] <= 'Z') 
||
-                           strcmp(dirp->d_name, "distfiles") == 0)
+               ccharp ports_locations[2] = {PATH_PORTS, cp};
+               int i;
+               for (i = 0; i < 2; i++) {
+                       path_ports = ports_locations[i];
+                       if (!path_ports)
                                continue;
-                       if ((b = malloc(sizeof PATH_PORTS + 1 + dirp->d_namlen))
-                           == NULL)
-                               abort();
-                       strcpy(b, PATH_PORTS);
-                       strcat(b, "/");
-                       strcat(b, dirp->d_name);
-                       if (stat(b, &sb) == -1 ||
-                           (sb.st_mode & S_IFMT) != S_IFDIR ||
-                           access(b, R_OK | X_OK) != 0) {
-                               free(b);
+                       if (stat(path_ports, &sb) == -1) {
+                               if (errno == ENOENT)
+                                       /* no /usr/ports, we are done */
+                                       continue;
+                               err(EX_OSERR, "stat(%s)", path_ports);
+                       }
+                       if ((sb.st_mode & S_IFMT) != S_IFDIR)
+                               /* This is not a directory, ignore */
+                               continue;
+                       if (access(path_ports, R_OK | X_OK) != 0)
                                continue;
+                       if ((dir = opendir(path_ports)) == NULL)
+                               err(EX_OSERR, "opendir %s)", path_ports);
+                       while ((dirp = readdir(dir)) != NULL) {
+                               /*
+                                * Not everything below path_ports is of
+                                * interest.  First, all dot files and
+                                * directories (e. g. .snap) can be ignored.
+                                * Also, all subdirectories starting with a
+                                * capital letter are not going to be
+                                * examined, as they are used for internal
+                                * purposes (Mk, Tools, ...).  This also
+                                * matches a possible CVS subdirectory.
+                                * Finally, the distfiles subdirectory is also
+                                * special, and should not be considered to
+                                * avoid false matches.
+                                */
+                               if (dirp->d_name[0] == '.' ||
+                                   /*
+                                    * isupper() not used on purpose: the
+                                    * check is supposed to default to the C
+                                    * locale instead of the current user's
+                                    * locale.
+                                    */
+                                   (dirp->d_name[0] >= 'A' && dirp->d_name[0] 
<= 'Z') ||
+                                   strcmp(dirp->d_name, "distfiles") == 0)
+                                       continue;
+                               if ((b = malloc(strlen(path_ports) + 1 + 
dirp->d_namlen))
+                                   == NULL)
+                                       abort();
+                               strcpy(b, path_ports);
+                               strcat(b, "/");
+                               strcat(b, dirp->d_name);
+                               if (stat(b, &sb) == -1 ||
+                                   (sb.st_mode & S_IFMT) != S_IFDIR ||
+                                   access(b, R_OK | X_OK) != 0) {
+                                       free(b);
+                                       continue;
+                               }
+                               sourcedirs = realloc(sourcedirs,
+                                                    (nele + 2) * sizeof(char 
*));
+                               if (sourcedirs == NULL)
+                                       abort();
+                               sourcedirs[nele++] = b;
+                               sourcedirs[nele] = NULL;
                        }
-                       sourcedirs = realloc(sourcedirs,
-                                            (nele + 2) * sizeof(char *));
-                       if (sourcedirs == NULL)
-                               abort();
-                       sourcedirs[nele++] = b;
-                       sourcedirs[nele] = NULL;
+                       closedir(dir);
                }
-               closedir(dir);
        }
 }
 

Reply via email to