1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2004, Richard Levitte <richard@levitte.org> 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved. 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in the 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * documentation and/or other materials provided with the distribution. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stddef.h> 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h> 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <limits.h> 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h> 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <sys/types.h> 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <dirent.h> 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h> 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef LPDIR_H 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "LPdir.h" 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The POSIXly macro for the maximum number of characters in a file path 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project is NAME_MAX. However, some operating systems use PATH_MAX instead. 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Therefore, it seems natural to first check for PATH_MAX and use that, 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project and if it doesn't exist, use NAME_MAX. */ 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(PATH_MAX) 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define LP_ENTRY_SIZE PATH_MAX 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#elif defined(NAME_MAX) 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define LP_ENTRY_SIZE NAME_MAX 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Of course, there's the possibility that neither PATH_MAX nor NAME_MAX 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project exist. It's also possible that NAME_MAX exists but is define to a 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project very small value (HP-UX offers 14), so we need to check if we got a 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project result, and if it meets a minimum standard, and create or change it 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if not. */ 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# undef LP_ENTRY_SIZE 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define LP_ENTRY_SIZE 255 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct LP_dir_context_st 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project DIR *dir; 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char entry_name[LP_ENTRY_SIZE+1]; 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}; 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project struct dirent *direntry = NULL; 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL || directory == NULL) 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project errno = EINVAL; 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project errno = 0; 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*ctx == NULL) 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (*ctx == NULL) 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project errno = ENOMEM; 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memset(*ctx, '\0', sizeof(LP_DIR_CTX)); 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (*ctx)->dir = opendir(directory); 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((*ctx)->dir == NULL) 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int save_errno = errno; /* Probably not needed, but I'm paranoid */ 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project free(*ctx); 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *ctx = NULL; 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project errno = save_errno; 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project direntry = readdir((*ctx)->dir); 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (direntry == NULL) 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project strncpy((*ctx)->entry_name, direntry->d_name, sizeof((*ctx)->entry_name) - 1); 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (*ctx)->entry_name; 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint LP_find_file_end(LP_DIR_CTX **ctx) 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx != NULL && *ctx != NULL) 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = closedir((*ctx)->dir); 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project free(*ctx); 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (ret) 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0: 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case -1: 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project errno = EINVAL; 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 128