[comp.os.minix] Scandir

ncpascal@ndsuvax.UUCP (Freeman Pascal) (12/17/87)

Hello,

     Well here's another MINIX library call I needed when porting the
BSD version of "arc".  My version performs just like the BSD 4.3 scandir(3)
(I only have one set of manuals).  My version relies on directoy(3) routines
and they will be following this posting.  Although, I would only suggest 
using my directory(3) routines as a last resort.  I wasn't sure on some of
the values passed and returned by telldir() and seekdir().  I treated what
was passed and returned by lseek().

    Just unshar and follow the instructions in the "INSTALL" file.

				Freeman P Pascal IV
				ncpascal@ndsuvax


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  INSTALL Makefile dir.h makelibc scandir.c tst.c
# Wrapped by ncpascal@ndsuvax on Wed Dec 16 22:27:09 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f INSTALL -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"INSTALL\"
else
echo shar: Extracting \"INSTALL\" \(807 characters\)
sed "s/^X//" >INSTALL <<'END_OF_INSTALL'
XManifest:
X--------
X	INSTALL		this file
X	Makefile	makefile for tty
X	makelibc	shell script to make C library
X	tst.c		test file for scandir(3)
X	scandir.c	library function to return tty name (see scandir(3))
X
XInstallation instructions:
X-------------------------
X
X1.  install dir.h in /usr/include/sys.
X
X2.  Add "typedef unshort ino_t" or "#define ino_t inode_nr" to
X    /usr/include/sys/types.h depending on your thinking how this
X    declaration should be handled.
X
X3.  Compile scandir.c as a library routine and place in /usr/lib/libc.a.
X    If you are using the makelibc shell script that was posted quite 
X    awhile back just append "ar av scandir.s" to the beginning and run.
X    I am including my version if you don't have it.
X
X4.  Run makefile to compile tst.c and run it to test scandir(3).
X
X5.  Enjoy
END_OF_INSTALL
if test 807 -ne `wc -c <INSTALL`; then
    echo shar: \"INSTALL\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(198 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X#	scandir()
X#
XCFLAGS=-w -T. -LIB -DDIR_DEBUG
X
Xall:		tst
X
Xtst:		tst.s	scandir.s dir.s
X	cc -o tst $(CFLAGS) tst.s scandir.s dir.s
X	@echo "Done."
X
Xtst.s:		tst.c
X
Xscandir.s:	scandir.c
X
Xdir.s:		dir.c
X
END_OF_Makefile
if test 198 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dir.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dir.h\"
else
echo shar: Extracting \"dir.h\" \(741 characters\)
sed "s/^X//" >dir.h <<'END_OF_dir.h'
X/*
X *  dir.h
X *
X *  Minix directory structures
X *
X */
X/*
X *  History:
X *
X *	16 Dec  87	fpp	Changed type of d_ino in direct structure
X *				from "inode_nr" (from orginal types.h)
X *				to "ino_t" (added to types.h for compatibl-
X *				ity)
X *	29 July 87	fpp	Creation
X */
X#define	DIRSIZ		14
X#define	DIRBLKSIZ	512		/* read this much in at a time	*/
X 
Xstruct	direct {
X  ino_t		d_ino;			/* inode of file		*/
X  char		d_name[ DIRSIZ ];	/* file name			*/
X};
X
Xtypedef struct _dirdesc
X{
X  int		dd_fd;			/* directory file descriptor	*/
X  long		dd_loc;			/* current location in dd_buf	*/
X  long		dd_size;		/* size of last read		*/
X  char		dd_buf[ DIRBLKSIZ ];	/* read buffer 			*/
X  
X} DIR;
X
XDIR		*opendir();
Xstruct direct	*readdir();
Xlong		telldir();
X
END_OF_dir.h
if test 741 -ne `wc -c <dir.h`; then
    echo shar: \"dir.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f makelibc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"makelibc\"
else
echo shar: Extracting \"makelibc\" \(2138 characters\)
sed "s/^X//" >makelibc <<'END_OF_makelibc'
X#
X#  makelibc - Make C library
X#
X#				- NOTE -
X#
X#  This shell script will -REMOVE- the old version of libc.a if it
X#  exists in the current directory.  It will also -REPLACE- the old
X#  /usr/lib/libc.a with version just packaged.
X#
Xif (test -f ./libc.a)		# remove old libc.a if it exists
X	then rm ./libc.a
Xfi
Xar av libc.a getwd.s rename.s			# getwd(3) rename(2)
Xar av libc.a dir.s scandir.s			# directory(3), scandir(3)
Xar av libc.a getgrp.s				# process groups
Xar av libc.a termcap.s gtty.s stty.s		# v1.2 update
Xar av libc.a popen.s ctime.s system.s qsort.s	# v1.2 upgrade
Xar av libc.a regexp.s regsub.s
Xar av libc.a getopt.s getgrent.s getpwent.s crypt.s
Xar av libc.a fdopen.s
Xar av libc.a fgets.s fprintf.s fputs.s fread.s freopen.s fclose.s
Xar av libc.a fopen.s fseek.s ftell.s fwrite.s gets.s scanf.s getc.s printdat.s
Xar av libc.a fflush.s setbuf.s sprintf.s doprintf.s putc.s ungetc.s strcmp.s
Xar av libc.a access.s chdir.s chmod.s chown.s chroot.s creat.s dup.s dup2.s
Xar av libc.a exec.s exit.s cleanup.s fork.s isatty.s fstat.s getegid.s getenv.s
Xar av libc.a geteuid.s getgid.s getpass.s close.s getuid.s ioctl.s kill.s
Xar av libc.a link.s lseek.s malloc.s brk.s brk2.s brksize.s mknod.s mktemp.s
Xar av libc.a getpid.s mount.s open.s perror.s pipe.s prints.s read.s setgid.s
Xar av libc.a setuid.s sleep.s alarm.s pause.s signal.s catchsig.s stat.s
Xar av libc.a stime.s strcat.s strcpy.s strlen.s strncat.s strncmp.s strncpy.s
Xar av libc.a ftime.s
Xar av libc.a sync.s time.s times.s umask.s umount.s unlink.s utime.s wait.s
Xar av libc.a stderr.s write.s syslib.s call.s atoi.s message.s sendrec.s
Xar av libc.a printk.s abort.s itoa.s stb.s abs.s atol.s ctype.s index.s bcopy.s
Xar av libc.a getutil.s rand.s rindex.s adi.s and.s cii.s cms.s cmu4.s com.s
Xar av libc.a csa2.s csb2.s cuu.s .dup.s dvi.s dvi4.s dvu.s dvu4.s exg.s fakfp.s
Xar av libc.a gto.s iaar.s ilar.s inn.s ior.s isar.s lar2.s loi.s mli.s mli4.s
Xar av libc.a ngi.s nop.s rck.s rmi.s rmi4.s rmu.s rmu4.s rol.s ror.s sar2.s
Xar av libc.a sbi.s set.s sli.s sri.s sti.s xor.s error.s unknown.s trp.s
Xar av libc.a setjmp.s
X
Xcp libc.a /usr/lib
Xecho
Xecho "Done."
Xecho
X
END_OF_makelibc
if test 2138 -ne `wc -c <makelibc`; then
    echo shar: \"makelibc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f scandir.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"scandir.c\"
else
echo shar: Extracting \"scandir.c\" \(2466 characters\)
sed "s/^X//" >scandir.c <<'END_OF_scandir.c'
X/*
X *	scandir.c - scandir() for MINIX
X *
X *	Requires directory(3) routines.
X *
X *	Also includes freedir(), and alphasort(3).
X */
X/*
X *  History:
X *
X *	04 Dec 87	fpp	Creation
X */
X#include	<sys/types.h>
X#include	<sys/dir.h>
X#include	<errno.h>
X
X#ifndef	PUBLIC
X#define	PUBLIC
X#endif
X
Xextern int		errno;
X
Xextern char	*calloc(), *malloc(), *realloc();
X
X/*========================================================================*\
X**				scandir()				  **
X\*========================================================================*/
XPUBLIC int
Xscandir( dirname, namelist, select, compar )
Xchar		*dirname;
Xstruct direct	*(*namelist[]);
Xint		(*select)();
Xint		(*compar)();
X{
X  register DIR			*dirp;
X  register struct direct	*dp;
X  struct direct			**dirs;
X  int				dirno = 0;
X
X  if (( dirp = opendir( dirname )) == 0 ) {
X	perror( dirname );
X	closedir( dirp );
X	return( -1 );
X  }
X  if (( dirs = (struct direct **) calloc( 1, sizeof( struct direct * ))) == 0 ) {
X	closedir( dirp );
X	errno = ENOMEM;
X	return( -1 );
X  }
X  dirno = 0;
X  while(( dp = readdir( dirp )) != 0 )  {
X	if (select == (int(*)()) 0 || (*select)(dp)) {
X		dirs = (struct direct **) realloc((char *) dirs,(dirno + 2) * sizeof(struct direct * ));
X		if (dirs == 0) {
X			closedir( dirp );
X			errno = ENOMEM;
X			return( -1 );
X		}
X		dirs[ dirno ] = ( struct direct *) malloc(sizeof( struct direct ));
X		if ( dirs[ dirno ] == 0 ) {
X			closedir( dirp );
X			errno = ENOMEM;
X			return( -1 );
X		}
X		dirs[ dirno ]->d_ino = dp->d_ino;
X		strcpy( dirs[ dirno ]->d_name, dp->d_name );
X		dirs[ ++dirno ] = (struct direct*) 0;
X	}
X  }
X  closedir( dirp );
X
X  if (compar != (int (*)()) 0 ) {
X	qsort((char *) dirs, dirno, sizeof( char *), compar );
X  }
X  *namelist = dirs; 
X  return( dirno-1 );
X}
X
X/*========================================================================*\
X**				freedir()				  **
X\*========================================================================*/
XPUBLIC freedir( dirs )
Xregister struct direct **dirs;
X{
X/*
X *	Release memory used by 'dirs'
X */
X	register int i;
X
X	if ( dirs == (struct direct **) 0 )
X		return(-1);
X	for(i = 0; dirs[ i ] != (struct direct *) 0; i++)
X		free( dirs[ i ] );
X	free( dirs );
X	return( 0 );
X}
X
X/*========================================================================*\
X**				alphasort()				  **
X\*========================================================================*/
XPUBLIC 
Xint alphasort( d1, d2)
Xstruct direct	**d1, **d2;
X{
X	return(strcmp((*d1)->d_name, (*d2)->d_name));
X}
X
END_OF_scandir.c
if test 2466 -ne `wc -c <scandir.c`; then
    echo shar: \"scandir.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tst.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tst.c\"
else
echo shar: Extracting \"tst.c\" \(363 characters\)
sed "s/^X//" >tst.c <<'END_OF_tst.c'
X#include	<sys/types.h>
X#include	<sys/dir.h>
X
X#define	NULL	0
X
Xmain()
X{
X  struct direct		**dirs, *dp;
X  int			n, i;
X
X  if ((i = scandir( ".", &dirs, (int *) NULL, (int *) NULL)) < 0 ) {
X	perror( "\".\"" );
X	exit( 1 );
X  }
X  for( n = 0; n != i; n++)
X	printf( "%d)  name = \"%14s\", inode = 0x%x\n",
X		n, dirs[n]->d_name, dirs[n]->d_ino );
X  freedir( dirs, i );
X}
X  
END_OF_tst.c
if test 363 -ne `wc -c <tst.c`; then
    echo shar: \"tst.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 1 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0