diff --git a/usr.bin/whereis/whereis.1 b/usr.bin/whereis/whereis.1 --- a/usr.bin/whereis/whereis.1 +++ b/usr.bin/whereis/whereis.1 @@ -74,6 +74,10 @@ .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 --- a/usr.bin/whereis/whereis.c +++ b/usr.bin/whereis/whereis.c @@ -312,23 +312,35 @@ abort(); nele = 0; decolonify(b, &sourcedirs, &nele); - - if (stat(PATH_PORTS, &sb) == -1) { + ccharp path_ports; + if ((cp = getenv("PORTSDIR")) != NULL) { + b = strdup(cp); + if (b == NULL) + abort(); + } + 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 (stat(path_ports, &sb) == -1) { if (errno == ENOENT) /* no /usr/ports, we are done */ - return; - err(EX_OSERR, "stat(" PATH_PORTS ")"); + continue; + err(EX_OSERR, "stat(%s)", path_ports); } 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 ")"); + /* 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 + * 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 @@ -350,10 +362,10 @@ (dirp->d_name[0] >= 'A' && dirp->d_name[0] <= 'Z') || strcmp(dirp->d_name, "distfiles") == 0) continue; - if ((b = malloc(sizeof PATH_PORTS + 1 + dirp->d_namlen)) + if ((b = malloc(strlen(path_ports) + 1 + dirp->d_namlen)) == NULL) abort(); - strcpy(b, PATH_PORTS); + strcpy(b, path_ports); strcat(b, "/"); strcat(b, dirp->d_name); if (stat(b, &sb) == -1 || @@ -366,10 +378,12 @@ (nele + 2) * sizeof(char *)); if (sourcedirs == NULL) abort(); - sourcedirs[nele++] = b; + sourcedirs[nele++] = strdup(b); + free(b); sourcedirs[nele] = NULL; } closedir(dir); + } } }