r2671: we're getting too many errors caused by the talloc_realloc() API not
[Samba/gebeck_regimport.git] / source4 / ntvfs / posix / pvfs_dirlist.c
blob85c307a1b287485e26215892379aa9493957b915
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2004
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 directory listing functions for posix backend
24 #include "includes.h"
25 #include "vfs_posix.h"
28 a special directory listing case where the pattern has no wildcard. We can just do a single stat()
29 thus avoiding the more expensive directory scan
31 static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filename *name,
32 const char *pattern, struct pvfs_dir *dir)
34 if (!name->exists) {
35 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
38 dir->count = 0;
39 dir->unix_path = talloc_strdup(dir, name->full_name);
40 if (!dir->unix_path) {
41 return NT_STATUS_NO_MEMORY;
44 dir->names = talloc_array_p(dir, const char *, 1);
45 if (!dir->names) {
46 return NT_STATUS_NO_MEMORY;
49 dir->names[0] = talloc_strdup(dir, pattern);
50 if (!dir->names[0]) {
51 return NT_STATUS_NO_MEMORY;
54 dir->count = 1;
56 return NT_STATUS_OK;
60 read a directory and find all matching file names, returning them in
61 the structure *dir. The returned names are relative to the directory
63 if the pattern matches no files then we return NT_STATUS_OK, with dir->count = 0
65 NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct pvfs_dir *dir)
67 DIR *odir;
68 struct dirent *dent;
69 uint_t allocated = 0;
70 char *pattern;
72 /* split the unix path into a directory + pattern */
73 pattern = strrchr(name->full_name, '/');
74 if (!pattern) {
75 /* this should not happen, as pvfs_unix_path is supposed to
76 return an absolute path */
77 return NT_STATUS_UNSUCCESSFUL;
80 *pattern++ = 0;
82 if (!name->has_wildcard) {
83 return pvfs_list_no_wildcard(pvfs, name, pattern, dir);
86 dir->count = 0;
87 dir->unix_path = talloc_strdup(dir, name->full_name);
88 if (!dir->unix_path) {
89 return NT_STATUS_NO_MEMORY;
92 odir = opendir(name->full_name);
93 if (!odir) {
94 return pvfs_map_errno(pvfs, errno);
97 while ((dent = readdir(odir))) {
98 uint_t i = dir->count;
99 const char *dname = dent->d_name;
101 /* check it matches the wildcard pattern */
102 if (ms_fnmatch(pattern, dname, PROTOCOL_NT1) != 0) {
103 continue;
106 if (dir->count >= allocated) {
107 allocated = (allocated + 100) * 1.2;
108 dir->names = talloc_realloc_p(dir, dir->names, const char *, allocated);
109 if (!dir->names) {
110 closedir(odir);
111 return NT_STATUS_NO_MEMORY;
115 dir->names[i] = talloc_strdup(dir, dname);
116 if (!dir->names[i]) {
117 closedir(odir);
118 return NT_STATUS_NO_MEMORY;
121 dir->count++;
124 closedir(odir);
126 return NT_STATUS_OK;