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 (at) 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 201409 /* 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 #include <stdlib.h> 39 #include <string.h> 40 41 #if defined(OPENSSL_PNACL) 42 /* pnacl doesn't include readdir_r! So we do the best we can. */ 43 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { 44 errno = 0; 45 *result = readdir(dirp); 46 if (*result != NULL) { 47 return 0; 48 } 49 if (errno) { 50 return 1; 51 } 52 return 0; 53 } 54 #endif 55 56 struct OPENSSL_dir_context_st { 57 DIR *dir; 58 struct dirent dirent; 59 }; 60 61 const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) { 62 struct dirent *dirent; 63 64 if (ctx == NULL || directory == NULL) { 65 errno = EINVAL; 66 return NULL; 67 } 68 69 errno = 0; 70 if (*ctx == NULL) { 71 *ctx = malloc(sizeof(OPENSSL_DIR_CTX)); 72 if (*ctx == NULL) { 73 errno = ENOMEM; 74 return 0; 75 } 76 memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX)); 77 78 (*ctx)->dir = opendir(directory); 79 if ((*ctx)->dir == NULL) { 80 int save_errno = errno; /* Probably not needed, but I'm paranoid */ 81 free(*ctx); 82 *ctx = NULL; 83 errno = save_errno; 84 return 0; 85 } 86 } 87 88 if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 || 89 dirent == NULL) { 90 return 0; 91 } 92 93 return (*ctx)->dirent.d_name; 94 } 95 96 int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) { 97 if (ctx != NULL && *ctx != NULL) { 98 int r = closedir((*ctx)->dir); 99 free(*ctx); 100 *ctx = NULL; 101 return r == 0; 102 } 103 104 errno = EINVAL; 105 return 0; 106 } 107 108 #endif /* !OPENSSL_WINDOWS */ 109