/* IglooFTP - Graphical and User Friendly FTP Client.
 * Copyright (c) 1998-1999 Jean-Marc Jacquet. 
 * All rights reserved.
 * 
 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE
 *
 * IglooFTP Original Packages, information and support,  
 * can be obtained at :
 *                              http://www.littleigloo.org
 * 
 *
 */

#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include "protos.h"


static char dir_recurse_delete_file (char *filename);
static char dir_recurse_delete_dir (char *filename);








/* RECURSE DIR function */

/* call files_func on files
 * call diirs_func on dirs
 * typedef char (*DirRecurseFunc) (char *filename);
 */

char
recurse_dir (char *this_pathname, DirRecurseFunc files_func, DirRecurseFunc dirs_func)
{
  DIR *this_dir;
  struct dirent *dirlist;
  struct stat stat_buf;
  char *pathname = strdup (this_pathname);
  char path_buf[MPLEN];
  char SUCCESS_FLAG = TRUE;

  stat (this_pathname, &stat_buf);
  if ((stat_buf.st_mode & S_IFMT) != S_IFDIR)
    {
      printf ("not a dir : %s\n", pathname);
      return 0;
    }

  if (!strcmp (pathname, "/"))	/* a  little security check */
    return 0;

  this_dir = opendir (pathname);
  while ((dirlist = readdir (this_dir)))
    {

      if (strcmp (dirlist->d_name, ".") && strcmp (dirlist->d_name, ".."))
	{
	  sprintf (path_buf, "%s/%s", pathname, dirlist->d_name);
	  stat (path_buf, &stat_buf);

	  if ((stat_buf.st_mode & S_IFMT) == S_IFDIR)
	    {
	      recurse_dir (path_buf, files_func, dirs_func);
	      if (!dirs_func (path_buf))
		SUCCESS_FLAG = FALSE;
	    }
	  else
	    {
	      if (!files_func (path_buf))
		SUCCESS_FLAG = FALSE;
	    }
	}
    }

  if (this_dir != NULL)
    closedir (this_dir);
  free (pathname);
  return SUCCESS_FLAG;
}






/* RECURSIVE CREATE/DELETE DIRECTORY */

/* * PUBLIC :
   * create_dir
   * delete_dir
   * STATIC :
   * dir_recurse_delete_file
   * dir_recurse_delete_dir
 */

/* CREATE */

void
create_dir (char *dirname, mode_t this_mode)
{
  const char slash = '/';
  char *dir_ptr = strdup (dirname);
  char *this_pathname = strdup (dirname);
  char *ptr_deb = this_pathname;
  char *ptr_end;

  strcpy (dir_ptr, "");
  while (ptr_deb != NULL)
    {
      ptr_deb = strchr (ptr_deb, slash);
      ptr_end = strchr (++ptr_deb, slash);
      strcat (dir_ptr, "/");
      if (ptr_end != NULL)
	strncat (dir_ptr, ptr_deb, (char *) ptr_end - (char *) ptr_deb);
      else
	strcat (dir_ptr, ptr_deb);
      ptr_deb = ptr_end;

      if (access (dir_ptr, F_OK))
	if (mkdir (dir_ptr, this_mode))
	  {
	    printf ("Can't create %s directory ... Abording.\n", dir_ptr);
	    exit (1);
	  }
    }

  free (dir_ptr);
  free (this_pathname);
}

/* DELETE */

static char
dir_recurse_delete_file (char *filename)
{
  return (unlink (filename) == -1);
}

static char
dir_recurse_delete_dir (char *filename)
{
  rmdir (filename);
  return TRUE;
}

int
delete_dir (char *dirname)
{
  return recurse_dir (dirname, dir_recurse_delete_file, dir_recurse_delete_dir);
}




/* MISC FUNCTIONS */

/* PUBLIC :
 * is_a_dir
 */

char
is_a_dir (char *filename)
{
  struct stat file_mode;
  stat (filename, &file_mode);
  return ((file_mode.st_mode & S_IFMT) == S_IFDIR);
}


/* EOF */
