Listing 2 Mapping functions applied to a repeating structure — in this case a UNIX file system

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

#define LASTCHR(s) s[strlen(s)-1]

int suidfile(name)
char *name;
{
       struct stat stbuf;
       stat(name, &stbuf);
       if (stbuf.st_mode & S_ISUID) printf("%s\n", name);
       return 0;
}

int mapdir(name, filefn)
char *name;
int (*filefn) ();
{
       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, filefn);
                     strcpy(cname, name);
              } else
                     (*filefn) (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] == '/')     /* absolute pathname */
              strcpy(buf, name);
       else {                  /* relative pathname*/
              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 *filefn;
       char name[MAXPATHLEN];

       if (argc < 2) {
              printf("Usage: %s <directory>",argv[0]);
              return -1;
       }
       setupdir(name, argv[1]);
       filefn = (char *) suidfile;
       return mapdir(name, filefn);
}
/* End of File */