dir.c revision b05363a2b9b01acaa767a5a2f4a2936c276140ac
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer/*
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * Copyright (C) 1999 Internet Software Consortium.
93ca8abdf86dfe69d40c0bc5389151e0672780afTinderbox User *
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * SOFTWARE.
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer */
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt/* $Id: dir.c,v 1.3 1999/09/28 03:37:36 tale Exp $ */
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt/* Principal Authors: DCL */
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#include <stdlib.h>
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#include <string.h>
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#include <errno.h>
ac31adc3b76a3acf61c711d1cd49480a288b1317Mukund Sivaraman
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#include <isc/dir.h>
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#include <isc/assertions.h>
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#define ISC_DIR_MAGIC 0x4449522aU /* DIR*. */
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#define VALID_DIR(dir) ((dir) != NULL && \
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt (dir)->magic == ISC_DIR_MAGIC)
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Huntvoid
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Huntisc_dir_init(isc_dir_t *dir) {
222d38735f97f771054e223b03f84c5858252332Evan Hunt REQUIRE(dir != NULL);
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer dir->entry.name[0] = '\0';
222d38735f97f771054e223b03f84c5858252332Evan Hunt dir->entry.length = 0;
222d38735f97f771054e223b03f84c5858252332Evan Hunt
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer dir->handle = NULL;
222d38735f97f771054e223b03f84c5858252332Evan Hunt
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence dir->magic = ISC_DIR_MAGIC;
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer}
222d38735f97f771054e223b03f84c5858252332Evan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt/*
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * Allocate workspace and open directory stream. If either one fails,
222d38735f97f771054e223b03f84c5858252332Evan Hunt * NULL will be returned.
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence */
222d38735f97f771054e223b03f84c5858252332Evan Huntisc_result_t
222d38735f97f771054e223b03f84c5858252332Evan Huntisc_dir_open(const char *dirname, isc_dir_t *dir) {
222d38735f97f771054e223b03f84c5858252332Evan Hunt isc_result_t result = ISC_R_SUCCESS;
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer
222d38735f97f771054e223b03f84c5858252332Evan Hunt REQUIRE(dirname != NULL);
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence REQUIRE(VALID_DIR(dir));
fdebae839745f79a7550aeb49d15a930523ec483David Lawrence
222d38735f97f771054e223b03f84c5858252332Evan Hunt /*
28002bd7cb4baa0eab9f47e1e51069c5ea7ea5d4Andreas Gustafsson * Open stream.
28002bd7cb4baa0eab9f47e1e51069c5ea7ea5d4Andreas Gustafsson */
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt dir->handle = opendir(dirname);
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt
28002bd7cb4baa0eab9f47e1e51069c5ea7ea5d4Andreas Gustafsson if (dir->handle == NULL) {
28002bd7cb4baa0eab9f47e1e51069c5ea7ea5d4Andreas Gustafsson if (errno == ENOMEM)
222d38735f97f771054e223b03f84c5858252332Evan Hunt result = ISC_R_NOMEMORY;
222d38735f97f771054e223b03f84c5858252332Evan Hunt else if (errno == EPERM)
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt result = ISC_R_NOPERM;
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt else if (errno == ENOENT)
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer result = ISC_R_NOTFOUND;
222d38735f97f771054e223b03f84c5858252332Evan Hunt
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence }
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer
222d38735f97f771054e223b03f84c5858252332Evan Hunt return (result);
222d38735f97f771054e223b03f84c5858252332Evan Hunt}
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer
222d38735f97f771054e223b03f84c5858252332Evan Hunt/*
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence * Return previously retrieved file or get next one. Unix's dirent has
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * separate open and read functions, but the Win32 and DOS interfaces open
222d38735f97f771054e223b03f84c5858252332Evan Hunt * the dir stream and reads the first file in one operation.
222d38735f97f771054e223b03f84c5858252332Evan Hunt */
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyerisc_result_t
222d38735f97f771054e223b03f84c5858252332Evan Huntisc_dir_read(isc_dir_t *dir) {
c634c94d673f1bab17e7f65d332f989b683e712cDavid Lawrence struct dirent *entry;
222d38735f97f771054e223b03f84c5858252332Evan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
222d38735f97f771054e223b03f84c5858252332Evan Hunt
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer /*
222d38735f97f771054e223b03f84c5858252332Evan Hunt * Fetch next file in directory.
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt */
222d38735f97f771054e223b03f84c5858252332Evan Hunt entry = readdir(dir->handle);
222d38735f97f771054e223b03f84c5858252332Evan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt if (entry == NULL)
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt return (ISC_R_NOMORE);
222d38735f97f771054e223b03f84c5858252332Evan Hunt
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt /*
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * Make sure that the space for the name is long enough.
222d38735f97f771054e223b03f84c5858252332Evan Hunt */
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt INSIST(sizeof(dir->entry.name) > strlen(entry->d_name));
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt strcpy(dir->entry.name, entry->d_name);
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt /*
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * Some dirents have d_namlen, but it is not portable.
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt */
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt dir->entry.length = strlen(entry->d_name);
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt return (ISC_R_SUCCESS);
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt}
222d38735f97f771054e223b03f84c5858252332Evan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt/*
222d38735f97f771054e223b03f84c5858252332Evan Hunt * Close directory stream.
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt */
222d38735f97f771054e223b03f84c5858252332Evan Huntvoid
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Huntisc_dir_close(isc_dir_t *dir) {
222d38735f97f771054e223b03f84c5858252332Evan Hunt REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
222d38735f97f771054e223b03f84c5858252332Evan Hunt
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt closedir(dir->handle);
222d38735f97f771054e223b03f84c5858252332Evan Hunt dir->handle = NULL;
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt}
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt
222d38735f97f771054e223b03f84c5858252332Evan Hunt/*
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt * Reposition directory stream at start.
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt */
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Huntisc_result_t
222d38735f97f771054e223b03f84c5858252332Evan Huntisc_dir_reset(isc_dir_t *dir) {
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
222d38735f97f771054e223b03f84c5858252332Evan Hunt
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt rewinddir(dir->handle);
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt return (ISC_R_SUCCESS);
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt}
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt