/* dir.cc - directory access
 * Copyright 2006 Bas Wijnen <wijnen@debian.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "dir.hh"
#include "error.hh"
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>

namespace shevek
{
  bool dir::file::operator< (file const &that) const
  {
    // directories are sorted before other files
    if (is_dir ^ that.is_dir)
      return is_dir;
    return name < that.name;
  }

  dir::dir ()
  {
  }

  dir::dir (std::string const &path)
  {
    load (path);
  }

  void dir::load (std::string const &path)
  {
    DIR *dir = opendir (path.c_str ());
    if (!dir)
      {
	shevek_error_errno (rostring ("unable to open directory %s", path));
	return;
      }
    struct dirent *de;
    for (de = readdir (dir); de; de = readdir (dir))
      {
	struct stat s;
	std::string p = path + '/' + de->d_name;
	if (stat (p.c_str (), &s) < 0)
	  continue;
	file f;
	f.name = de->d_name;
	f.is_dir = S_ISDIR (s.st_mode);
	f.uid = s.st_uid;
	f.gid = s.st_gid;
	f.size = s.st_size;
	data.insert (f);
      }
    closedir (dir);
  }

  dir::const_iterator dir::begin () const
  {
    return data.begin ();
  }

  dir::const_iterator dir::end () const
  {
    return data.end ();
  }

  unsigned dir::size () const
  {
    return data.size ();
  }
}
