Enumerating executable files in C

386 views Asked by At

I am trying to enumerate only files with the execute (+x) bit set. My code seems to list all files. It also seems to enumerate directory and the above directory which I do not want. Example:

..
should_not_be_executable.sh
.

Is there a way to filter '..' and '.' without strstr()? Here is my code

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>


int
main (void)
{
DIR *dp;
struct dirent *ep;

dp = opendir ("/tmp/hi");
if (dp != NULL)
{
  while (ep = readdir (dp))
  {
    struct stat sb;
    if ((stat(ep->d_name, &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC & sb.st_mode));
                    puts(ep->d_name);
      }
  (void) closedir (dp);
}
else
  perror ("Couldn't open the directory");
return 0;
}

Thanks in advance

1

There are 1 answers

0
unix_newbie_programmer223 On BEST ANSWER

ep->d_name contains only relative pathname of the directory entry. So you should change the Current Working Directory to /tmp/hi before calling stat(2)

if (chdir("/bin") != 0)
{
    perror("chdir()");
    exit(EXIT_FAILURE);
}

/* ... */

if (stat(ep->d_name, &sb) == -1)
{
    perror("stat()");
    exit(EXIT_FAILURE);
}

As noted in the comments by @Andrew Medico, remove that extra ; at the end of your if line to avoid unnecessary printing of that puts() line.

readdir() returns a NULL pointer when it reaches at the end of directory, so you should rewrite your while loop as follows in order to suppress a compiler warning:

while (NULL != (ep = readdir(dp)))
{
     /* loop */
}

In order to avoid printing . and .., use an if condition like this in the while body:

if ((strcmp(ep->d_name, ".") == 0) || (strcmp(ep->d_name, "..") == 0))
    continue;

if ((stat(ep->d_name, &sb) >= 0) && (sb.st_mode > 0) && (S_IEXEC & sb.st_mode))
    if (!S_ISDIR(sb.st_mode))
            puts(ep->d_name);

Similarly, you can use S_ISDIR(m) macro to find out if the current entry is a directory and choose to not printing it.