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