Curdir(3) source (apologies if this is the wrong group)

Scott "The Pseudo-Hacker" Neugroschl abcscnge at csuna.csun.edu
Mon Aug 7 04:12:14 AEST 1989


Several people have mailed and asked for the source to my curdir function,
so (as it is now easier to post than reply), here it is.  I apologize
if this is the wrong news group, please do not flame... I am posting
here because this is where I made the original comment...


---- cut here ----
/*
** if your system does not support the directory(3X) functions, i.e. no
** <dirent.h>, then define _NO_DIRENT_H_ at the top of the file.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _NO_DIRENT_H_
#include <dirent.h>
#else
#include <sys/dir.h>
typedef int DIR;
struct dirent {
	long		d_ino;
	off_t		d_off;
	unsigned short	d_reclen;
	char		d_name[DIRSIZ+2];
};
static DIR		*opendir();
static struct dirent	*readdir();
static long		telldir();
static void		seekdir();
static int		closedir();
#define rewinddir(dirp)	seekdir(dirp,0L);
#endif

curdir(str)
char str[];
{
	static char tmpstr[BUFSIZ];
	static char openpath[BUFSIZ+BUFSIZ];
	static char tmpnam[BUFSIZ+BUFSIZ];
	struct stat buf, rootbuf, tmpstat;
	DIR *dirp;
	struct dirent *dp;
	int l;

	if (stat("/",&rootbuf) == -1)
		return(-1);

	if (stat(".",&buf) == -1)
		return(-1);

	openpath[0] = tmpstr[0] = '\0';
	strcpy(openpath,"..");
	while (buf.st_dev != rootbuf.st_dev ||
	       buf.st_ino != rootbuf.st_ino)
	{
		if ((dirp = opendir(openpath)) == NULL)
			return(-1);
		while ((dp = readdir(dirp)) != NULL)
		{
			sprintf(tmpnam,"%s/%s",openpath,dp->d_name);
			if (stat(tmpnam,&tmpstat) == -1)
			{
				closedir(dirp);
				return(-1);
			}
			if (tmpstat.st_dev == buf.st_dev &&
			    tmpstat.st_ino == buf.st_ino)
				break;
		}
		closedir(dirp);
		if (dp == NULL)
			return(-1);
		append(dp->d_name,tmpstr);
		if (stat(openpath,&buf) == -1)
			return(-1);
		sprintf(openpath,"../%s",openpath);
	}
	strcpy(str,"/");
	strcat(str,tmpstr);
	if (str[l = (strlen(str) - 1)] == '/')
		str[l] = '\0';
	return(0);


}

static append(head,tail)
char *head, *tail;
{
	char tmpbuf[BUFSIZ+BUFSIZ];

	strcpy(tmpbuf,head);
	strcat(tmpbuf,"/");
	strcat(tmpbuf,tail);
	strcpy(tail,tmpbuf);

}

#ifdef _NO_DIRENT_H

static off_t curoff = ((off_t) 0);

static DIR *opendir(name)
int name;
{
	char *malloc();
	DIR *dp;
	struct stat buf;

	/* no file, or not a directory */
	if (stat(name,&buf) == -1 || (buf.st_mode & S_IFMT) != S_IFDIR)
		return(NULL);

	/* no memory? */
	if ((dp = (DIR *)malloc(sizeof(DIR))) == NULL)
		return(NULL);

	/* can't open? */
	if ((*dp = open(name,0)) == -1)
	{
		free(dp);
		return(NULL);
	}
	curoff = (off_t)0;
	return(dp);
}

static struct dirent *readdir(dirp)
register DIR *dirp;
{
	static struct dirent dp;
	struct direct dir;

	if (read(*dirp,&dir,sizeof(dir)) != sizeof(dir))
		return(NULL);
	dp.d_ino = (long) dir.d_ino;
	dp.d_off = curoff;
	curoff += sizeof(dir);
	dp.d_reclen = sizeof(dir);
	strncpy(dp.d_name,dir.d_name,DIRSIZ);
	dp.d_name[DIRSIZ] = '\0';
	return(&dp);
}

static long telldir(dp)
register DIR *dp;
{
	long lseek();
	return((long)(curoff = (off_t) lseek(*dp,0L,1)));
}

static void seekdir(dp,offset)
register DIR *dp;
register long offset;
{
	long lseek();

	curoff = (off_t)lseek(*dp,offset,0);
}

static int closedir(dp)
register DIR *dp;
{
	close(*dp);
	free(dp);
	return(0);
}
#endif

--- cut here ---
-- 
Scott "The Pseudo-Hacker" Neugroschl
UUCP:  ...!sm.unisys.com!csun!csuna.csun.edu!abcscnge
-- Beat me, Whip me, make me code in Ada
-- Disclaimers?  We don't need no stinking disclaimers!!!



More information about the Comp.unix.questions mailing list