1/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */ 2/* 3 * Copyright (c) 2004, Richard Levitte <richard@levitte.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 26 27#if !defined(_POSIX_C_SOURCE) 28#define _POSIX_C_SOURCE 1 /* for readdir_r */ 29#endif 30 31#include "directory.h" 32 33 34#if !defined(OPENSSL_WINDOWS) 35 36#include <dirent.h> 37#include <errno.h> 38 39#if defined(OPENSSL_PNACL) 40/* pnacl doesn't include readdir_r! So we do the best we can. */ 41int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { 42 errno = 0; 43 *result = readdir(dirp); 44 if (*result != NULL) { 45 return 0; 46 } 47 if (errno) { 48 return 1; 49 } 50 return 0; 51} 52#endif 53 54struct OPENSSL_dir_context_st { 55 DIR *dir; 56 struct dirent dirent; 57}; 58 59const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) { 60 struct dirent *dirent; 61 62 if (ctx == NULL || directory == NULL) { 63 errno = EINVAL; 64 return NULL; 65 } 66 67 errno = 0; 68 if (*ctx == NULL) { 69 *ctx = malloc(sizeof(OPENSSL_DIR_CTX)); 70 if (*ctx == NULL) { 71 errno = ENOMEM; 72 return 0; 73 } 74 memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX)); 75 76 (*ctx)->dir = opendir(directory); 77 if ((*ctx)->dir == NULL) { 78 int save_errno = errno; /* Probably not needed, but I'm paranoid */ 79 free(*ctx); 80 *ctx = NULL; 81 errno = save_errno; 82 return 0; 83 } 84 } 85 86 if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 || 87 dirent == NULL) { 88 return 0; 89 } 90 91 return (*ctx)->dirent.d_name; 92} 93 94int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) { 95 if (ctx != NULL && *ctx != NULL) { 96 int r = closedir((*ctx)->dir); 97 free(*ctx); 98 *ctx = NULL; 99 return r == 0; 100 } 101 102 errno = EINVAL; 103 return 0; 104} 105 106#endif /* !OPENSSL_WINDOWS */ 107