A
download dirent.c
Language: C
LOC: 152
Project Info
QuakeForge(quake)
Server: SourceForge
Type: cvs
...ake\quake\newtree32\source\
   .cvsignore
   .gdbinit
   .indent.pro
   buildnum.c
   cd_dos.c
   cd_linux.c
   cd_null.c
   cd_sdl.c
   cd_sgi.c
   cd_win.c
   checksum.c
   cl_cam.c
   cl_cmd.c
   cl_cvar.c
   cl_demo.c
   cl_ents.c
   cl_input.c
   cl_main.c
   cl_misc.c
   cl_parse.c
   cl_pred.c
   cl_slist.c
   cl_sys_sdl.c
   cl_sys_unix.c
   cl_sys_win.c
   cl_tent.c
   cmd.c
   com.c
   console.c
   context_x11.c
   crc.c
   cvar.c
   d_edge.c
   d_fill.c
   d_init.c
   d_modech.c
   d_part.c
   d_polyse.c
   d_scan.c
   d_sky.c
   d_sprite.c
   d_surf.c
   d_vars.c
   d_zpoint.c
   dga_check.c
   dirent.c
   draw.c
   fbset.c
   fbset_modes_y.y
   fnmatch.c
   fractalnoise.c
   gl_draw.c
   gl_dyn_fires.c
   gl_dyn_part.c
   gl_dyn_textures.c
   gl_mesh.c
   gl_model_alias.c
   gl_model_brush.c
   gl_model_fullbright.c
   gl_model_sprite.c
   gl_ngraph.c
   gl_rlight.c
   gl_rmain.c
   gl_rmisc.c
   gl_rsurf.c
   gl_screen.c
   gl_skin.c
   gl_sky.c
   gl_sky_clip.c
   gl_view.c
   gl_warp.c
   hash.c
   in_fbdev.c
   in_ggi.c
   in_null.c
   in_sdl.c
   in_svgalib.c
   in_win.c
   in_x11.c
   info.c
   joy_linux.c
   joy_null.c
   joy_win.c
   keys.c
   link.c
   locs.c
   Makefile.am
   makefile.mgw
   makefile.win
   mathlib.c
   mdfour.c
   menu.c
   model.c
   model_alias.c
   model_brush.c
   model_sprite.c
   msg.c
   net_chan.c
   net_com.c
   net_packetlog.c
   net_udp.c
   net_udp6.c
   nonintel.c
   pcx.c
   pmove.c
   pmovetst.c
   pr_edict.c
   pr_exec.c
   pr_offs.c
   qargs.c
   qendian.c
   qfgl_ext.c
   quakefs.c
   quakeio.c
   r_aclip.c
   r_alias.c
   r_bsp.c
   r_draw.c
   r_edge.c
   r_efrag.c
   r_light.c
   r_main.c
   r_misc.c
   r_part.c
   r_sky.c
   r_sprite.c
   r_surf.c
   r_vars.c
   r_view.c
   sbar.c
   screen.c
   sizebuf.c
   skin.c
   snd_alsa_0_5.c
   snd_alsa_0_6.c
   snd_disk.c
   snd_dma.c
   snd_mem.c
   snd_mix.c
   snd_null.c
   snd_oss.c
   snd_sdl.c
   snd_sgi.c
   snd_sun.c
   snd_win.c
   sv_ccmds.c
   sv_cvar.c
   sv_ents.c
   sv_init.c
   sv_main.c
   sv_misc.c
   sv_model.c
   sv_move.c
   sv_nchan.c
   sv_phys.c
   sv_pr_cmds.c
   sv_progs.c
   sv_send.c
   sv_sys_unix.c
   sv_sys_win.c
   sv_user.c
   sw_model_alias.c
   sw_model_brush.c
   sw_model_sprite.c
   sw_skin.c
   sw_view.c
   sys_null.c
   sys_unix.c
   sys_win.c
   teamplay.c
   tga.c
   va.c
   ver_check.c
   vid.c
   vid_3dfxsvga.c
   vid_common_gl.c
   vid_fbdev.c
   vid_ggi.c
   vid_glx.c
   vid_mgl.c
   vid_null.c
   vid_sdl.c
   vid_sgl.c
   vid_svgalib.c
   vid_wgl.c
   vid_win.c
   vid_x11.c
   wad.c
   world.c
   zone.c

/*
 * dirent.c
 *
 * Derived from DIRLIB.C by Matt J. Weinstein 
 * This note appears in the DIRLIB.H
 * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
 *
 * Updated by Jeremy Bettis <jeremy@hksys.com>
 * Significantly revised and rewinddir, seekdir and telldir added by Colin
 * Peters <colin@fu.is.saga-u.ac.jp>
 *
 * $Id: dirent.c,v 1.1.1.1 2001/03/06 09:33:17 lordhavoc Exp $
 *
 */

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <io.h>
#include <direct.h>
#include <sys/stat.h>

#include <dirent.h>

#define SUFFIX	"*"
#define	SLASH	"\\"

#ifndef S_ISDIR
#define S_ISDIR(m)	((m & S_IFMT) == S_IFDIR)	/* is a directory */
#endif S_ISDIR

/*
 * opendir
 *
 * Returns a pointer to a DIR structure appropriately filled in to begin
 * searching a directory.
 */
DIR        *
opendir (const char *szPath)
{
	DIR        *nd;
	struct _stat statDir;

	errno = 0;

	if (!szPath) {
		errno = EFAULT;
		return (DIR *) 0;
	}

	if (szPath[0] == '\0') {
		errno = ENOTDIR;
		return (DIR *) 0;
	}

	/* Attempt to determine if the given path really is a directory. */
	if (_stat (szPath, &statDir)) {
		/* Error, stat should have set an error value. */
		return (DIR *) 0;
	}

	if (!S_ISDIR (statDir.st_mode)) {
		/* Error, stat reports not a directory. */
		errno = ENOTDIR;
		return (DIR *) 0;
	}

	/* Allocate enough space to store DIR structure and the complete *
	   directory path given. */
	nd = (DIR *) calloc (1, sizeof (DIR) + strlen (szPath) + strlen (SLASH) +
						 strlen (SUFFIX));

	if (!nd) {
		/* Error, out of memory. */
		errno = ENOMEM;
		return (DIR *) 0;
	}

	/* Create the search expression. */
	strcpy (nd->dd_name, szPath);

	/* Add on a slash if the path does not end with one. */
	if (nd->dd_name[0] != '\0' &&
		nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
		nd->dd_name[strlen (nd->dd_name) - 1] != '\\') {
		strcat (nd->dd_name, SLASH);
	}

	/* Add on the search pattern */
	strcat (nd->dd_name, SUFFIX);

	/* Initialize handle to -1 so that a premature closedir doesn't try * to
	   call _findclose on it. */
	nd->dd_handle = -1;

	/* Initialize the status. */
	nd->dd_stat = 0;

	/* Initialize the dirent structure. ino and reclen are invalid under *
	   Win32, and name simply points at the appropriate part of the *
	   findfirst_t structure. */
	nd->dd_dir.d_ino = 0;
	nd->dd_dir.d_reclen = 0;
	nd->dd_dir.d_namlen = 0;
	nd->dd_dir.d_name = nd->dd_dta.name;

	return nd;
}


/*
 * readdir
 *
 * Return a pointer to a dirent structure filled with the information on the
 * next entry in the directory.
 */
struct dirent *
readdir (DIR * dirp)
{
	errno = 0;

	/* Check for valid DIR struct. */
	if (!dirp) {
		errno = EFAULT;
		return (struct dirent *) 0;
	}

	if (dirp->dd_dir.d_name != dirp->dd_dta.name) {
		/* The structure does not seem to be set up correctly. */
		errno = EINVAL;
		return (struct dirent *) 0;
	}

	if (dirp->dd_stat < 0) {
		/* We have already returned all files in the directory * (or the
		   structure has an invalid dd_stat). */
		return (struct dirent *) 0;
	} else if (dirp->dd_stat == 0) {
		/* We haven't started the search yet. */
		/* Start the search */
		dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));

		if (dirp->dd_handle == -1) {
			/* Whoops! Seems there are no files in that * directory. */
			dirp->dd_stat = -1;
		} else {
			dirp->dd_stat = 1;
		}
	} else {
		/* Get the next search entry. */
		if (_findnext (dirp->dd_handle, &(dirp->dd_dta))) {
			/* We are off the end or otherwise error. */
			_findclose (dirp->dd_handle);
			dirp->dd_handle = -1;
			dirp->dd_stat = -1;
		} else {
			/* Update the status to indicate the correct * number. */
			dirp->dd_stat++;
		}
	}

	if (dirp->dd_stat > 0) {
		/* Successfully got an entry. Everything about the file is * already
		   appropriately filled in except the length of the * file name. */
		dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
		return &dirp->dd_dir;
	}

	return (struct dirent *) 0;
}


/*
 * closedir
 *
 * Frees up resources allocated by opendir.
 */
int
closedir (DIR * dirp)
{
	int         rc;

	errno = 0;
	rc = 0;

	if (!dirp) {
		errno = EFAULT;
		return -1;
	}

	if (dirp->dd_handle != -1) {
		rc = _findclose (dirp->dd_handle);
	}

	/* Delete the dir structure. */
	free (dirp);

	return rc;
}

/*
 * rewinddir
 *
 * Return to the beginning of the directory "stream". We simply call findclose
 * and then reset things like an opendir.
 */
void
rewinddir (DIR * dirp)
{
	errno = 0;

	if (!dirp) {
		errno = EFAULT;
		return;
	}

	if (dirp->dd_handle != -1) {
		_findclose (dirp->dd_handle);
	}

	dirp->dd_handle = -1;
	dirp->dd_stat = 0;
}

/*
 * telldir
 *
 * Returns the "position" in the "directory stream" which can be used with
 * seekdir to go back to an old entry. We simply return the value in stat.
 */
long
telldir (DIR * dirp)
{
	errno = 0;

	if (!dirp) {
		errno = EFAULT;
		return -1;
	}
	return dirp->dd_stat;
}

/*
 * seekdir
 *
 * Seek to an entry previously returned by telldir. We rewind the directory
 * and call readdir repeatedly until either dd_stat is the position number
 * or -1 (off the end). This is not perfect, in that the directory may
 * have changed while we weren't looking. But that is probably the case with
 * any such system.
 */
void
seekdir (DIR * dirp, long lPos)
{
	errno = 0;

	if (!dirp) {
		errno = EFAULT;
		return;
	}

	if (lPos < -1) {
		/* Seeking to an invalid position. */
		errno = EINVAL;
		return;
	} else if (lPos == -1) {
		/* Seek past end. */
		if (dirp->dd_handle != -1) {
			_findclose (dirp->dd_handle);
		}
		dirp->dd_handle = -1;
		dirp->dd_stat = -1;
	} else {
		/* Rewind and read forward to the appropriate index. */
		rewinddir (dirp);

		while ((dirp->dd_stat < lPos) && readdir (dirp));
	}
}

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us