dir.c revision d9edfd56422af0e709d4548ce838f2167d1ea115
1633838b8255282d10af15c5c84cee5a51466712Bob Halley/*
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1999-2001 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * purpose with or without fee is hereby granted, provided that the above
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley */
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id: dir.c,v 1.16 2008/11/02 23:47:01 tbox Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/* Principal Authors: DCL */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley#include <config.h>
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#include <string.h>
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews#include <direct.h>
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#include <process.h>
ddfe394c061049bbd71125ad41c3dd3092b2bbfdAndreas Gustafsson#include <io.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <sys/stat.h>
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
fca5f81ad69098ea8abba130c7f841c951ef91c2Bob Halley#include <isc/dir.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/magic.h>
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#include <isc/assertions.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley#include "errno2result.h"
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*')
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystart_directory(isc_dir_t *p);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyvoid
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyisc_dir_init(isc_dir_t *dir) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(dir != NULL);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley dir->dirname[0] = '\0';
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
cee7525336d4710a64368875d92eb439d4d3efb1Mark Andrews dir->entry.name[0] = '\0';
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley dir->entry.length = 0;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley memset(&(dir->entry.find_data), 0, sizeof(dir->entry.find_data));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley dir->entry_filled = ISC_FALSE;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley dir->search_handle = INVALID_HANDLE_VALUE;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence dir->magic = ISC_DIR_MAGIC;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley/*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Allocate workspace and open directory stream. If either one fails,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * NULL will be returned.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyisc_result_t
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyisc_dir_open(isc_dir_t *dir, const char *dirname) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley char *p;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley isc_result_t result;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(dirname != NULL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_DIR(dir) && dir->search_handle == INVALID_HANDLE_VALUE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Copy directory name. Need to have enough space for the name,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * a possible path separator, the wildcard, and the final NUL.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (strlen(dirname) + 3 > sizeof(dir->dirname))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* XXXDCL ? */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (ISC_R_NOSPACE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley strcpy(dir->dirname, dirname);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Append path separator, if needed, and "*".
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley p = dir->dirname + strlen(dir->dirname);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (dir->dirname < p && *(p - 1) != '\\' && *(p - 1) != ':')
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *p++ = '\\';
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *p++ = '*';
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *p++ = '\0';
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Open stream.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = start_directory(dir);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (result);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley/*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Return previously retrieved file or get next one. Unix's dirent has
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * separate open and read functions, but the Win32 and DOS interfaces open
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * the dir stream and reads the first file in one operation.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyisc_result_t
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyisc_dir_read(isc_dir_t *dir) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (dir->entry_filled)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * start_directory() already filled in the first entry.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley dir->entry_filled = ISC_FALSE;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley else {
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley /*
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley * Fetch next file in directory.
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley */
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley if (FindNextFile(dir->search_handle,
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley &dir->entry.find_data) == FALSE)
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley /*
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * Either the last file has been processed or
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * an error has occured. The former is not
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley * really an error, but the latter is.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley */
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley if (GetLastError() == ERROR_NO_MORE_FILES)
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley return (ISC_R_NOMORE);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley else
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley return (ISC_R_UNEXPECTED);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence }
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley /*
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Make sure that the space for the name is long enough.
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley */
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley strcpy(dir->entry.name, dir->entry.find_data.cFileName);
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley dir->entry.length = strlen(dir->entry.name);
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley return (ISC_R_SUCCESS);
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley}
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley/*
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Close directory stream.
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley */
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halleyvoid
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinisc_dir_close(isc_dir_t *dir) {
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE);
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley FindClose(dir->search_handle);
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley dir->search_handle = INVALID_HANDLE_VALUE;
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley}
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley/*
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Reposition directory stream at start.
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson */
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonisc_result_t
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonisc_dir_reset(isc_dir_t *dir) {
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_result_t result;
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson REQUIRE(VALID_DIR(dir) && dir->search_handle != INVALID_HANDLE_VALUE);
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson REQUIRE(dir->dirname != NULL);
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson /*
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * NT cannot reposition the seek pointer to the beginning of the
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * the directory stream, but rather the directory needs to be
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * closed and reopened. The latter might fail.
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson */
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson isc_dir_close(dir);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley result = start_directory(dir);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny Mayer return (result);
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson}
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson/*
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * Initialize isc_dir_t structure with new directory. The function
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * returns 0 on failure and nonzero on success.
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson *
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * Note:
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * - Be sure to close previous stream before opening new one
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson */
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstatic isc_result_t
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstart_directory(isc_dir_t *dir)
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson{
5f120ce962b03e4dcf6f1974b9b896f0fa7cacb0Bob Halley REQUIRE(VALID_DIR(dir));
5f120ce962b03e4dcf6f1974b9b896f0fa7cacb0Bob Halley REQUIRE(dir->search_handle == INVALID_HANDLE_VALUE);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny Mayer dir->entry_filled = ISC_FALSE;
5f120ce962b03e4dcf6f1974b9b896f0fa7cacb0Bob Halley
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews /*
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews * Open stream and retrieve first file.
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews */
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dir->search_handle = FindFirstFile(dir->dirname,
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews &dir->entry.find_data);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (dir->search_handle == INVALID_HANDLE_VALUE) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews /*
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews * Something went wrong but we don't know what. GetLastError()
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews * could give us more information about the error, but the
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * MSDN documentation is frustratingly thin about what
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews * possible errors could have resulted. (Score one for
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * the Unix manual pages.) So there is just this lame error
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * instead of being able to differentiate ISC_R_NOTFOUND
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * from ISC_R_UNEXPECTED.
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence return (ISC_R_FAILURE);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence }
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make sure that the space for the name is long enough.
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(sizeof(dir->entry.name) >
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley strlen(dir->entry.find_data.cFileName));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Fill in the data for the first entry of the directory.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
da527e4ff6a013364826637963e7ac372e024f33David Lawrence strcpy(dir->entry.name, dir->entry.find_data.cFileName);
da527e4ff6a013364826637963e7ac372e024f33David Lawrence dir->entry.length = strlen(dir->entry.name);
da527e4ff6a013364826637963e7ac372e024f33David Lawrence
da527e4ff6a013364826637963e7ac372e024f33David Lawrence dir->entry_filled = ISC_TRUE;
da527e4ff6a013364826637963e7ac372e024f33David Lawrence
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington return (ISC_R_SUCCESS);
da527e4ff6a013364826637963e7ac372e024f33David Lawrence}
da527e4ff6a013364826637963e7ac372e024f33David Lawrence
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyisc_result_t
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyisc_dir_chdir(const char *dirname) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Change the current directory to 'dirname'.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(dirname != NULL);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (chdir(dirname) < 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (isc__errno2result(errno));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (ISC_R_SUCCESS);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley}
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halleyisc_result_t
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleyisc_dir_chroot(const char *dirname) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (ISC_R_NOTIMPLEMENTED);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halleyisc_result_t
ce3761f64d3d734cc94605026985898900ecc474Bob Halleyisc_dir_createunique(char *templet) {
ee03a00244edc6c823ea11bed16437865b395d5dAndreas Gustafsson isc_result_t result;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley char *x;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley char *p;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley int i;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence int pid;
5fc1b54cc6134bd70f4e22df90a2e5631aaea77aBob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley REQUIRE(templet != NULL);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
ce3761f64d3d734cc94605026985898900ecc474Bob Halley * mkdtemp is not portable, so this emulates it.
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
ce3761f64d3d734cc94605026985898900ecc474Bob Halley pid = getpid();
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
ce3761f64d3d734cc94605026985898900ecc474Bob Halley * Replace trailing Xs with the process-id, zero-filled.
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
ce3761f64d3d734cc94605026985898900ecc474Bob Halley for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley x--, pid /= 10)
ce3761f64d3d734cc94605026985898900ecc474Bob Halley *x = pid % 10 + '0';
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley x++; /* Set x to start of ex-Xs. */
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley do {
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley i = mkdir(templet);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence i = chmod(templet, 0700);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (i == 0 || errno != EEXIST)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * The BSD algorithm.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley p = x;
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley while (*p != '\0') {
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley if (isdigit(*p & 0xff))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *p = 'a';
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley else if (*p != 'z')
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ++*p;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews else {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Reset character and move to next.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews *p++ = 'a';
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews continue;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews break;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (*p == '\0') {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Tried all combinations. errno should already
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * be EEXIST, but ensure it is anyway for
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * isc__errno2result().
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews errno = EEXIST;
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater break;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews } while (1);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (i == -1)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews result = isc__errno2result(errno);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews else
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews result = ISC_R_SUCCESS;
86548554f6180bbe051c8cd8f03c93fc9b6a7825Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (result);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews}
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews