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

#include "recurs.h"

/**
 * Find all subdirectories in the input directory, and call the Fortran
 * callback function on each of them.
 *
 * @param[in] dirname is the directory name,
 * @param[in] data is some data (NOT A STRING!),
 * @param[in] fct is the callback function,
 * @param[out] gag_directory_exedir function value on return is the error status.
 */
int CFC_API gag_directory_exedir( CFC_FString dirname,
                                  void *data,
                                  void (*fct)(CFC_FString subdir, void *patter, int *ier CFC_DECLARE_STRING_LENGTH(subdir))
                                  CFC_DECLARE_STRING_LENGTH( dirname) )
{
  DIR *dir;
  struct dirent *entry;
  int ier;
  char tmp[GAG_MAX_PATH_LENGTH+1];
  CFC_DECLARE_LOCAL_STRING(f_subdir);
  char c_subdir[GAG_MAX_PATH_LENGTH+1];
  char f_subdir_buf[GAG_MAX_PATH_LENGTH+1];

  CFC_f2c_strcpy( tmp, dirname, CFC_STRING_LENGTH_MIN( dirname, GAG_MAX_PATH_LENGTH));

  ier = 0;
  if ((dir = opendir(tmp)) == NULL)
    ier = 1;
  else {
    while ((entry = readdir(dir)) != NULL) {
#if defined(_DIRENT_HAVE_D_TYPE)
      if (entry->d_type == DT_DIR
#else
      struct stat fstat;
      if (!stat(entry->d_name, &fstat) && S_ISDIR(fstat.st_mode)
#endif
      && strcmp(entry->d_name,"..") && strcmp(entry->d_name,".")) {
        strcpy(c_subdir,tmp);
        strcat(c_subdir,"/");
        strcat(c_subdir,entry->d_name);

        CFC_STRING_VALUE(f_subdir) = f_subdir_buf;
        CFC_STRING_LENGTH(f_subdir) = GAG_MAX_PATH_LENGTH;
        CFC_c2f_strcpy(f_subdir,GAG_MAX_PATH_LENGTH,c_subdir);
        fct(f_subdir, data, &ier CFC_PASS_STRING_LENGTH(f_subdir));
        if (ier != 0) {
          return ier;
        }
      }
    }
    closedir(dir);
  }

  return ier;
}
