Listing 3 mapdir — maps its argument onto all the files in the hierarchy below the command-line directory argument.

#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/param.h>

#define LASTCHR(s) s[strlen(s)-1]
int do_nothing(name)
char *name;
{       return 0; }

int printfile(name)
char *name;
{       printf("%s\n", name);
       return 0;
}

int suidfile(name)
char *name;
{       struct stat stbuf;
       stat(name, &stbuf);
       return (stbuf.st_mode & S_ISUID);
}

int mapdir(name, predfn, thenfn, elsefn)
char *name;
int (*predfn)(), (*thenfn)(), (*elsefn)();
{
       DIR *dirp;
       struct dirent *entry;
       struct stat stbuf;
       char olddir[MAXPATHLEN];
       char cname[MAXPATHLEN];

       getwd(olddir);
       strcpy(cname, name);
       if (chdir(name)) {
              printf("Couldn't change to directory %s\n", name);
              return -1;
       }
       if ((dirp = opendir(name)) == NULL){
              printf("Unable tto open DIR %s\n", name);
              chdir(olddir);
              return -1;
       }
       for (entry=readdir(dirp); entry != NULL; entry=readdir(dirp)) {
              if (0 != stat(entry->d_name, &stbuf))
                     printf("Can't read file information %s\n",
                            entry->d_name);
              else if (strcmp(entry->d_name, ".") == 0 ||
                 strcmp(entry->d_name, "..") == 0)
                     /* don't pursue these entries */ ;
              else if (S_ISLNK(stbuf.st_mode))
                     /* don't pursue links */ ;
              else if (S_ISDIR(stbuf.st_mode)) {
                     if (LASTCHR(cname) != '/') strcat(cname, "/");
                     strcat(cname, entry->d_name);
                     mapdir(cname, predfn, thenfn, elsefn);
                     strcpy(cname,name);
              } else
                     if ((*predfn) (entry->d_name))
                            (*thenfn) (entry->d_name);
                     else (*elsefn) (entry->d_name);
       }
       closedir(dirp);
       chdir(olddir);
       return 0;
}

char *setupdir(buf, name)
char *name;
char *buf;
{
       char curdir[MAXPATHLEN];

       getwd(curdir);
       if (name[0] == '/')
              strcpy(buf, name);
       else {  strcpy(buf, curdir);
              if (buf[strlen(buf)-1] != '/') strcat(buf, "/");
                                                     /* may be at root */
              strcat(buf, name);
       }
       return buf;
}

int main(argc, argv)
int argc;
char **argv;
{
       char *predfn, *thenfn, *elsefn;
       char name[MAXPATHLEN];

       if (argc < 2) {
              printf("Usage: %s <directory>",argv[0]);
              return -1;
       }
       setupdir(name, argv[1]);
       predfn = (char *) suidfile;
       thenfn = (char *) printfile;
       elsefn = (char *) do_nothing;
       return mapdir(name, predfn, thenfn, elsefn);
}

/* End of File */