/* ensure-dir.c: 
 *
 ****************************************************************
 * Copyright (C) 2003 Tom Lord
 * 
 * See the file "COPYING" for further information about
 * the copyright and warranty status of this work.
 */


#include "hackerlab/char/str.h"
#include "hackerlab/hash/hashtree.h"
#include "hackerlab/hash/hash-utils.h"
#include "hackerlab/vu/safe.h"
#include "hackerlab/fs/file-names.h"
#include "file-utils/libfsutils/ensure-dir.h"


/* __STDC__ prototypes for static functions */
static int hashtree_str_eq (void * va, void * vb, struct hashtree_rules * r);



int
ensure_directory_exists (t_uchar * name)
{
  static struct hashtree_rules rules = { hashtree_str_eq, 0, };
  static struct hashtree * tree = 0;
  t_ulong hash;

  if (!tree)
    {
      tree = hashtree_alloc (&rules);
    }

  hash = hash_mem (name, str_length (name));

  if (hashtree_find (tree, hash, name, &rules))
    return 0;

  if (safe_file_is_directory (name))
    return 0;

  {
    t_uchar * tmp;
    t_uchar * parent;

    tmp = file_name_directory (0, name);
    if (tmp)
      {
	parent = file_name_from_directory (0, tmp);
	lim_free (0, tmp);

	if (ensure_directory_exists (parent))
	  {
	    lim_free (0, parent);
	    return -1;
	  }
      }

    if (!safe_file_is_directory (name))
      safe_mkdir (name, 0777);

    hashtree_store (tree, hash, str_save (0, name), &rules);

    return 0;
  }
}



static int
hashtree_str_eq (void * va, void * vb, struct hashtree_rules * r)
{
  t_uchar * a;
  t_uchar * b;

  a = (t_uchar *)va;
  b = (t_uchar *)vb;

  return !str_cmp (a, b);
}





/* tag: Tom Lord Mon May 12 15:29:46 2003 (ensure-dir.c)
 */
