1/* 2 * $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp 3 * $ 4 */ 5/* 6 * Copyright (c) 2004, Richard Levitte <richard@levitte.org> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <stddef.h> 32#include <stdlib.h> 33#include <limits.h> 34#include <string.h> 35#include <sys/types.h> 36#include <dirent.h> 37#include <errno.h> 38#ifndef LPDIR_H 39# include "LPdir.h" 40#endif 41 42/* 43 * The POSIXly macro for the maximum number of characters in a file path is 44 * NAME_MAX. However, some operating systems use PATH_MAX instead. 45 * Therefore, it seems natural to first check for PATH_MAX and use that, and 46 * if it doesn't exist, use NAME_MAX. 47 */ 48#if defined(PATH_MAX) 49# define LP_ENTRY_SIZE PATH_MAX 50#elif defined(NAME_MAX) 51# define LP_ENTRY_SIZE NAME_MAX 52#endif 53 54/* 55 * Of course, there's the possibility that neither PATH_MAX nor NAME_MAX 56 * exist. It's also possible that NAME_MAX exists but is define to a very 57 * small value (HP-UX offers 14), so we need to check if we got a result, and 58 * if it meets a minimum standard, and create or change it if not. 59 */ 60#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255 61# undef LP_ENTRY_SIZE 62# define LP_ENTRY_SIZE 255 63#endif 64 65struct LP_dir_context_st { 66 DIR *dir; 67 char entry_name[LP_ENTRY_SIZE + 1]; 68}; 69 70const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) 71{ 72 struct dirent *direntry = NULL; 73 74 if (ctx == NULL || directory == NULL) { 75 errno = EINVAL; 76 return 0; 77 } 78 79 errno = 0; 80 if (*ctx == NULL) { 81 *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); 82 if (*ctx == NULL) { 83 errno = ENOMEM; 84 return 0; 85 } 86 memset(*ctx, '\0', sizeof(LP_DIR_CTX)); 87 88 (*ctx)->dir = opendir(directory); 89 if ((*ctx)->dir == NULL) { 90 int save_errno = errno; /* Probably not needed, but I'm paranoid */ 91 free(*ctx); 92 *ctx = NULL; 93 errno = save_errno; 94 return 0; 95 } 96 } 97 98 direntry = readdir((*ctx)->dir); 99 if (direntry == NULL) { 100 return 0; 101 } 102 103 strncpy((*ctx)->entry_name, direntry->d_name, 104 sizeof((*ctx)->entry_name) - 1); 105 (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; 106 return (*ctx)->entry_name; 107} 108 109int LP_find_file_end(LP_DIR_CTX **ctx) 110{ 111 if (ctx != NULL && *ctx != NULL) { 112 int ret = closedir((*ctx)->dir); 113 114 free(*ctx); 115 switch (ret) { 116 case 0: 117 return 1; 118 case -1: 119 return 0; 120 default: 121 break; 122 } 123 } 124 errno = EINVAL; 125 return 0; 126} 127