text: #include <stdio.h>
  #include <sys/stat.h>
  #include <stdbool.h>
  #include <stdlib.h>
  #include <dirent.h>
  #include <unistd.h>
  #include <string.h>
  
  static int num_dirs, num_regular;
  
  bool is_dir(const char* path) {
    struct stat *buf;
    buf = malloc(sizeof(struct stat));
    int status = stat(path, buf);
    if(status == 0) {
      if (S_ISDIR(buf->st_mode)) {
        free(buf);
        return true;
      } else {
        free(buf);
        return false;
      }
    } else {
      free(buf);
      return false;
    }
  }
  
  /* 
   * I needed this because the multiple recursion means there's no way to
   * order them so that the definitions all precede the cause.
   */
  void process_path(const char*);
  
  void process_directory(const char* basePath) {
    char path[1000];
    struct dirent *dp;
    int directories = 0;
    DIR *dir = opendir(basePath);
  
    while ((dp = readdir(dir)) != NULL) {
      if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
  
        // Construct new path from our base path
        strcpy(path, basePath);
        strcat(path, "/");
        strcat(path, dp->d_name);
  
        process_path(path);
      }
    }
    num_dirs++;
  
    closedir(dir);
  }
  
  void process_file(const char* path) {
    num_regular++;
  }
  
  void process_path(const char* path) {
    if (is_dir(path)) {
      process_directory(path);
    } else {
      process_file(path);
    }
  }
  
  int main (int argc, char *argv[]) {
    // Ensure an argument was provided.
    if (argc != 2) {
      printf ("Usage: %s <path>\n", argv[0]);
      printf ("       where <path> is the file or root of the tree you want to summarize.\n");
      return 1;
    }
  
    num_dirs = 0;
    num_regular = 0;
  
    process_path(argv[1]);
  
    printf("There were %d directories.\n", num_dirs);
    printf("There were %d regular files.\n", num_regular);
  
    return 0;
  }
  