|
rpm-build |
3ee90c |
/* scandir: Scan a directory, collecting all (selected) items into a an array.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* This code borrowed from 'libit', which can be found here:
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* The original author put this code in the public domain.
|
|
rpm-build |
3ee90c |
* It has been modified slightly to get rid of warnings, etc.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Below is the email I received from pinard@iro.umontreal.ca (François Pinard)
|
|
rpm-build |
3ee90c |
* when I sent him an email asking him about the license, etc. of this
|
|
rpm-build |
3ee90c |
* code which I obtained from his site.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* I think the correct spelling of his name is Rich Salz. I think he's now
|
|
rpm-build |
3ee90c |
* rsalz@datapower.com...
|
|
rpm-build |
3ee90c |
* --
|
|
rpm-build |
3ee90c |
* Rich Salz, Chief Security Architect
|
|
rpm-build |
3ee90c |
* DataPower Technology http://www.datapower.com
|
|
rpm-build |
3ee90c |
* XS40 XML Security Gateway http://www.datapower.com/products/xs40.html
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Copyright(C): none (public domain)
|
|
rpm-build |
3ee90c |
* License: none (public domain)
|
|
rpm-build |
3ee90c |
* Author: Rich Salz <rsalz@datapower.com>
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* -- Alan Robertson
|
|
rpm-build |
3ee90c |
* alanr@unix.sh
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
**************************************************************************
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Subject: Re: Scandir replacement function
|
|
rpm-build |
3ee90c |
* Date: 18 May 2001 12:00:48 -0400
|
|
rpm-build |
3ee90c |
* From: pinard@iro.umontreal.ca (François Pinard)
|
|
rpm-build |
3ee90c |
* To: Alan Robertson <alanr@unix.sh>
|
|
rpm-build |
3ee90c |
* References: 1
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* [Alan Robertson]
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* > Hi, I'd like to use your scandir replacement function found here:
|
|
rpm-build |
3ee90c |
* > http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/ But, it does
|
|
rpm-build |
3ee90c |
* > not indicate authorship or licensing terms in it. Could you tell me
|
|
rpm-build |
3ee90c |
* > who wrote this code, under what license you distribute it, and whether
|
|
rpm-build |
3ee90c |
* > and under what terms I may further distribute it?
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Hello, Alan. These are (somewhat) explained in UNSHAR.HDR found in the
|
|
rpm-build |
3ee90c |
* same directory. The routines have been written by Rick Saltz (I'm not
|
|
rpm-build |
3ee90c |
* completely sure of the spelling) a long while ago. I think that nowadays,
|
|
rpm-build |
3ee90c |
* Rick is better known as the main author of the nice INN package.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
**************************************************************************
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* I spent a little time verifying this with Rick Salz.
|
|
rpm-build |
3ee90c |
* The results are below:
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
**************************************************************************
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Date: Tue, 20 Sep 2005 21:52:09 -0400 (EDT)
|
|
rpm-build |
3ee90c |
* From: Rich Salz <rsalz@datapower.com>
|
|
rpm-build |
3ee90c |
* To: Alan Robertson <alanr@unix.sh>
|
|
rpm-build |
3ee90c |
* Subject: Re: Verifying permissions/licenses/etc on some old code of yours -
|
|
rpm-build |
3ee90c |
* scandir.c
|
|
rpm-build |
3ee90c |
* In-Reply-To: <433071CA.8000107@unix.sh>
|
|
rpm-build |
3ee90c |
* Message-ID: <Pine.LNX.4.44L0.0509202151270.9198-100000@smtp.datapower.com>
|
|
rpm-build |
3ee90c |
* Content-Type: TEXT/PLAIN; charset=US-ASCII
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* yes, it's most definitely in the public domain.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* I'm glad you find it useful. I'm surprised it hasn't been replaced by,
|
|
rpm-build |
3ee90c |
* e.g,. something in GLibC. Ii'm impressed you tracked me down.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* /r$
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* --
|
|
rpm-build |
3ee90c |
* Rich Salz Chief Security Architect
|
|
rpm-build |
3ee90c |
* DataPower Technology http://www.datapower.com
|
|
rpm-build |
3ee90c |
* XS40 XML Security Gateway http://www.datapower.com/products/xs40.html
|
|
rpm-build |
3ee90c |
* ---------------------------------------------------------------------->
|
|
rpm-build |
3ee90c |
* Subject: scandir, ftw REDUX
|
|
rpm-build |
3ee90c |
* Date: 1 Jan 88 00:47:01 GMT
|
|
rpm-build |
3ee90c |
* From: rsalz@pebbles.bbn.com
|
|
rpm-build |
3ee90c |
* Newsgroups: comp.sources.misc
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Forget my previous message -- I just decided for completeness's sake to
|
|
rpm-build |
3ee90c |
* implement the SysV ftw(3) routine, too.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* To repeat, these are public-domain implementations of the SystemV ftw()
|
|
rpm-build |
3ee90c |
* routine, the BSD scandir() and alphasort() routines, and documentation for
|
|
rpm-build |
3ee90c |
* same. The FTW manpage could be more readable, but so it goes.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Anyhow, feel free to post these, and incorporate them into your existing
|
|
rpm-build |
3ee90c |
* packages. I have readdir() routiens for MSDOS and the Amiga if anyone
|
|
rpm-build |
3ee90c |
* wants them, and should have them for VMS by the end of January; let me
|
|
rpm-build |
3ee90c |
* know if you want copies.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Yours in filesystems,
|
|
rpm-build |
3ee90c |
* /r$
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Anyhow, feel free to post
|
|
rpm-build |
3ee90c |
* ----------------------------------------------------------------------<
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm_internal.h>
|
|
rpm-build |
3ee90c |
#include <sys/types.h>
|
|
rpm-build |
3ee90c |
#include <dirent.h>
|
|
rpm-build |
3ee90c |
#include <stdlib.h>
|
|
rpm-build |
3ee90c |
#include <stddef.h>
|
|
rpm-build |
3ee90c |
#include <string.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#ifndef NULL
|
|
rpm-build |
3ee90c |
# define NULL ((void *) 0)
|
|
rpm-build |
3ee90c |
#endif
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Initial guess at directory allocated. */
|
|
rpm-build |
3ee90c |
#define INITIAL_ALLOCATION 20
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
scandir(const char *directory_name,
|
|
rpm-build |
3ee90c |
struct dirent ***array_pointer, int (*select_function) (const struct dirent *),
|
|
rpm-build |
3ee90c |
#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT
|
|
rpm-build |
3ee90c |
/* This is what the Linux man page says */
|
|
rpm-build |
3ee90c |
int (*compare_function) (const struct dirent **, const struct dirent **)
|
|
rpm-build |
3ee90c |
#else
|
|
rpm-build |
3ee90c |
/* This is what the Linux header file says ... */
|
|
rpm-build |
3ee90c |
int (*compare_function) (const void *, const void *)
|
|
rpm-build |
3ee90c |
#endif
|
|
rpm-build |
3ee90c |
);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int
|
|
rpm-build |
3ee90c |
scandir(const char *directory_name,
|
|
rpm-build |
3ee90c |
struct dirent ***array_pointer, int (*select_function) (const struct dirent *),
|
|
rpm-build |
3ee90c |
#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT
|
|
rpm-build |
3ee90c |
/* This is what the linux man page says */
|
|
rpm-build |
3ee90c |
int (*compare_function) (const struct dirent **, const struct dirent **)
|
|
rpm-build |
3ee90c |
#else
|
|
rpm-build |
3ee90c |
/* This is what the linux header file says ... */
|
|
rpm-build |
3ee90c |
int (*compare_function) (const void *, const void *)
|
|
rpm-build |
3ee90c |
#endif
|
|
rpm-build |
3ee90c |
)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
DIR *directory;
|
|
rpm-build |
3ee90c |
struct dirent **array;
|
|
rpm-build |
3ee90c |
struct dirent *entry;
|
|
rpm-build |
3ee90c |
struct dirent *copy;
|
|
rpm-build |
3ee90c |
int allocated = INITIAL_ALLOCATION;
|
|
rpm-build |
3ee90c |
int counter = 0;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Get initial list space and open directory. */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (directory = opendir(directory_name), directory == NULL)
|
|
rpm-build |
3ee90c |
return -1;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if ((array = (struct dirent **)malloc(allocated * sizeof(struct dirent *))) == NULL)
|
|
rpm-build |
3ee90c |
return -1;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Read entries in the directory. */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
while (entry = readdir(directory), entry)
|
|
rpm-build |
3ee90c |
if (select_function == NULL || (*select_function) (entry)) {
|
|
rpm-build |
3ee90c |
/* User wants them all, or he wants this one. Copy the entry. */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* On some OSes the declaration of "entry->d_name" is a minimal-length
|
|
rpm-build |
3ee90c |
* placeholder. Example: Solaris:
|
|
rpm-build |
3ee90c |
* /usr/include/sys/dirent.h:
|
|
rpm-build |
3ee90c |
* "char d_name[1];"
|
|
rpm-build |
3ee90c |
* man page "dirent(3)":
|
|
rpm-build |
3ee90c |
* The field d_name is the beginning of the character array
|
|
rpm-build |
3ee90c |
* giving the name of the directory entry. This name is
|
|
rpm-build |
3ee90c |
* null terminated and may have at most MAXNAMLEN chars.
|
|
rpm-build |
3ee90c |
* So our malloc length may need to be increased accordingly.
|
|
rpm-build |
3ee90c |
* sizeof(entry->d_name): space (possibly minimal) in struct.
|
|
rpm-build |
3ee90c |
* strlen(entry->d_name): actual length of the entry.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* John Kavadias <john_kavadias@hotmail.com>
|
|
rpm-build |
3ee90c |
* David Lee <t.d.lee@durham.ac.uk>
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
int namelength = strlen(entry->d_name) + 1; /* length with NULL */
|
|
rpm-build |
3ee90c |
int extra = 0;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (sizeof(entry->d_name) <= namelength) {
|
|
rpm-build |
3ee90c |
/* allocated space <= required space */
|
|
rpm-build |
3ee90c |
extra += namelength - sizeof(entry->d_name);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if ((copy = (struct dirent *)malloc(sizeof(struct dirent) + extra)) == NULL) {
|
|
rpm-build |
3ee90c |
closedir(directory);
|
|
rpm-build |
3ee90c |
free(array);
|
|
rpm-build |
3ee90c |
return -1;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
copy->d_ino = entry->d_ino;
|
|
rpm-build |
3ee90c |
copy->d_reclen = entry->d_reclen;
|
|
rpm-build |
3ee90c |
strcpy(copy->d_name, entry->d_name);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Save the copy. */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (counter + 1 == allocated) {
|
|
rpm-build |
3ee90c |
allocated <<= 1;
|
|
rpm-build |
3ee90c |
array = (struct dirent **)
|
|
rpm-build |
3ee90c |
realloc_safe((char *)array, allocated * sizeof(struct dirent *));
|
|
rpm-build |
3ee90c |
if (array == NULL) {
|
|
rpm-build |
3ee90c |
closedir(directory);
|
|
rpm-build |
3ee90c |
free(array);
|
|
rpm-build |
3ee90c |
free(copy);
|
|
rpm-build |
3ee90c |
return -1;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
array[counter++] = copy;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Close things off. */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
array[counter] = NULL;
|
|
rpm-build |
3ee90c |
*array_pointer = array;
|
|
rpm-build |
3ee90c |
closedir(directory);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Sort? */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (counter > 1 && compare_function)
|
|
rpm-build |
3ee90c |
qsort((char *)array, counter, sizeof(struct dirent *)
|
|
rpm-build |
3ee90c |
, (int (*)(const void *, const void *))(compare_function));
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
return counter;
|
|
rpm-build |
3ee90c |
}
|