/* 
   Unix SMB/CIFS implementation.

   Copyright (C) Andrew Tridgell 2005

     ** NOTE! The following LGPL license applies to the replace
     ** library. This does NOT imply that all of Samba is released
     ** under the LGPL
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
  a replacement for opendir/readdir/telldir/seekdir/closedir for BSD
  systems using getdirentries

  This is needed because the existing directory handling in FreeBSD
  and OpenBSD (and possibly NetBSD) doesn't correctly handle unlink()
  on files in a directory where telldir() has been used. On a block
  boundary it will occasionally miss a file when seekdir() is used to
  return to a position previously recorded with telldir().

  This also fixes a severe performance and memory usage problem with
  telldir() on BSD systems. Each call to telldir() in BSD adds an
  entry to a linked list, and those entries are cleaned up on
  closedir(). This means with a large directory closedir() can take an
  arbitrary amount of time, causing network timeouts as millions of
  telldir() entries are freed

  Note! This replacement code is not portable. It relies on
  getdirentries() always leaving the file descriptor at a seek offset
  that is a multiple of DIR_BUF_SIZE. If the code detects that this
  doesn't happen then it will abort(). It also does not handle
  directories with offsets larger than can be stored in a long,

  This code is available under other free software licenses as
  well. Contact the author.
*/

#include "replace.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>

#define DIR_BUF_BITS 9
#define DIR_BUF_SIZE (1<<DIR_BUF_BITS)

struct dir_buf {
	int fd;
	int nbytes, ofs;
	off_t seekpos;
	char buf[DIR_BUF_SIZE];
};

DIR *opendir(const char *dname)
{
	struct dir_buf *d;
	struct stat sb;
	d = malloc(sizeof(*d));
	if (d == NULL) {
		errno = ENOMEM;
		return NULL;
	}
	d->fd = open(dname, O_RDONLY);
	if (d->fd == -1) {
		free(d);
		return NULL;
	}
	if (fstat(d->fd, &sb) < 0) {
		close(d->fd);
		free(d);
		return NULL;
	}
	if (!S_ISDIR(sb.st_mode)) {
		close(d->fd);
		free(d);   
		errno = ENOTDIR;
		return NULL;
	}
	d->ofs = 0;
	d->seekpos = 0;
	d->nbytes = 0;
	return (DIR *)d;
}

struct dirent *readdir(DIR *dir)
{
	struct dir_buf *d = (struct dir_buf *)dir;
	struct dirent *de;

	if (d->ofs >= d->nbytes) {
		long pos;
		d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos);
		d->seekpos = pos;
		d->ofs = 0;
	}
	if (d->ofs >= d->nbytes) {
		return NULL;
	}
	de = (struct dirent *)&d->buf[d->ofs];
	d->ofs += de->d_reclen;
	return de;
}

#ifdef TELLDIR_TAKES_CONST_DIR
long telldir(const DIR *dir)
#else
long telldir(DIR *dir)
#endif
{
	struct dir_buf *d = (struct dir_buf *)dir;
	if (d->ofs >= d->nbytes) {
		d->seekpos = lseek(d->fd, 0, SEEK_CUR);
		d->ofs = 0;
		d->nbytes = 0;
	}
	/* this relies on seekpos always being a multiple of
	   DIR_BUF_SIZE. Is that always true on BSD systems? */
	if (d->seekpos & (DIR_BUF_SIZE-1)) {
		abort();
	}
	return d->seekpos + d->ofs;
}

#ifdef SEEKDIR_RETURNS_INT
int seekdir(DIR *dir, long ofs)
#else
void seekdir(DIR *dir, long ofs)
#endif
{
	struct dir_buf *d = (struct dir_buf *)dir;
	long pos;
	d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET);
	d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos);
	d->ofs = 0;
	while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) {
		if (readdir(dir) == NULL) break;
	}
#ifdef SEEKDIR_RETURNS_INT
	return -1;
#endif
}

void rewinddir(DIR *dir)
{
	seekdir(dir, 0);
}

int closedir(DIR *dir)
{
	struct dir_buf *d = (struct dir_buf *)dir;
	int r = close(d->fd);
	if (r != 0) {
		return r;
	}
	free(d);
	return 0;
}

#ifndef dirfd
/* darn, this is a macro on some systems. */
int dirfd(DIR *dir)
{
	struct dir_buf *d = (struct dir_buf *)dir;
	return d->fd;
}
#endif


