~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/* TODO: check for overun of memory for names. */
17
994.2.4 by Monty Taylor
Blast. Fixed some make distcheck issues.
18
#include	"mysys/mysys_priv.h"
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
19
#include	<mystrings/m_string.h>
994.2.4 by Monty Taylor
Blast. Fixed some make distcheck issues.
20
#include	"mysys/mysys_err.h"
685.1.3 by Monty Taylor
Turned off stdinc - and then fixed the carnage.
21
#include	"my_dir.h"	/* Structs used by my_dir,includes sys/types */
1 by brian
clean slate
22
#if defined(HAVE_DIRENT_H)
23
# include <dirent.h>
24
#else
25
# define dirent direct
26
# if defined(HAVE_SYS_NDIR_H)
27
#  include <sys/ndir.h>
28
# endif
29
# if defined(HAVE_SYS_DIR_H)
30
#  include <sys/dir.h>
31
# endif
32
# if defined(HAVE_NDIR_H)
33
#  include <ndir.h>
34
# endif
35
#endif
36
28.1.35 by Monty Taylor
Removed all references to THREAD.
37
#if defined(HAVE_READDIR_R)
1 by brian
clean slate
38
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
1034.1.8 by Brian Aker
Remove locks around my_open(). Open file counts are now "best effort" (not
39
#else 
40
#error You must have a thread safe readdir() 
1 by brian
clean slate
41
#endif
42
43
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
44
  We are assuming that directory we are reading is either has less than
1 by brian
clean slate
45
  100 files and so can be read in one initial chunk or has more than 1000
46
  files and so big increment are suitable.
47
*/
48
#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO))
49
#define ENTRIES_INCREMENT  (65536/sizeof(FILEINFO))
50
#define NAMES_START_SIZE   32768
51
52
266.7.12 by Andy Lester
putting in proper const qualifiers
53
static int comp_names(const struct fileinfo *a, const struct fileinfo *b);
1 by brian
clean slate
54
55
56
	/* We need this because program don't know with malloc we used */
57
58
void my_dirend(MY_DIR *buffer)
59
{
60
  if (buffer)
61
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
62
    delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
1 by brian
clean slate
63
                                    ALIGN_SIZE(sizeof(MY_DIR))));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
64
    free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
1 by brian
clean slate
65
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
481 by Brian Aker
Remove all of uchar.
66
    free((unsigned char*) buffer);
1 by brian
clean slate
67
  }
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
68
  return;
1 by brian
clean slate
69
} /* my_dirend */
70
71
72
	/* Compare in sort of filenames */
73
266.7.12 by Andy Lester
putting in proper const qualifiers
74
static int comp_names(const struct fileinfo *a, const struct fileinfo *b)
1 by brian
clean slate
75
{
76
  return (strcmp(a->name,b->name));
77
} /* comp_names */
78
79
80
MY_DIR	*my_dir(const char *path, myf MyFlags)
81
{
82
  char          *buffer;
83
  MY_DIR        *result= 0;
84
  FILEINFO      finfo;
85
  DYNAMIC_ARRAY *dir_entries_storage;
86
  MEM_ROOT      *names_storage;
87
  DIR		*dirp;
88
  struct dirent *dp;
89
  char		tmp_path[FN_REFLEN+1],*tmp_file;
90
  char	dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
91
92
  dirp = opendir(directory_file_name(tmp_path,(char *) path));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
93
  if (dirp == NULL ||
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
94
      ! (buffer= (char *) malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
95
                                 ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
96
                                 sizeof(MEM_ROOT))))
1 by brian
clean slate
97
    goto error;
98
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
99
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
1 by brian
clean slate
100
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
101
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
102
1 by brian
clean slate
103
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
104
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
105
  {
481 by Brian Aker
Remove all of uchar.
106
    free((unsigned char*) buffer);
1 by brian
clean slate
107
    goto error;
108
  }
109
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
110
1 by brian
clean slate
111
  /* MY_DIR structure is allocated and completly initialized at this point */
112
  result= (MY_DIR*)buffer;
113
376 by Brian Aker
strend remove
114
  tmp_file= strchr(tmp_path, '\0');
1 by brian
clean slate
115
116
  dp= (struct dirent*) dirent_tmp;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
117
1 by brian
clean slate
118
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
119
  {
120
    if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
121
      goto error;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
122
1 by brian
clean slate
123
    if (MyFlags & MY_WANT_STAT)
124
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
125
      if (!(finfo.mystat= (struct stat*)alloc_root(names_storage,
15 by brian
Fix for stat, NETWARE removal
126
                                               sizeof(struct stat))))
1 by brian
clean slate
127
        goto error;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
128
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
129
      memset(finfo.mystat, 0, sizeof(struct stat));
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
130
      strcpy(tmp_file,dp->d_name);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
131
      stat(tmp_path, finfo.mystat);
212.5.37 by Monty Taylor
Removed my_stat.
132
      if (!(finfo.mystat->st_mode & S_IREAD))
1 by brian
clean slate
133
        continue;
134
    }
135
    else
136
      finfo.mystat= NULL;
137
481 by Brian Aker
Remove all of uchar.
138
    if (push_dynamic(dir_entries_storage, (unsigned char*)&finfo))
1 by brian
clean slate
139
      goto error;
140
  }
141
142
  (void) closedir(dirp);
1034.1.8 by Brian Aker
Remove locks around my_open(). Open file counts are now "best effort" (not
143
1 by brian
clean slate
144
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
145
  result->number_off_files= dir_entries_storage->elements;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
146
1 by brian
clean slate
147
  if (!(MyFlags & MY_DONT_SORT))
148
    my_qsort((void *) result->dir_entry, result->number_off_files,
149
          sizeof(FILEINFO), (qsort_cmp) comp_names);
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
150
  return(result);
1 by brian
clean slate
151
152
 error:
1034.1.8 by Brian Aker
Remove locks around my_open(). Open file counts are now "best effort" (not
153
1 by brian
clean slate
154
  my_errno=errno;
155
  if (dirp)
156
    (void) closedir(dirp);
157
  my_dirend(result);
158
  if (MyFlags & (MY_FAE | MY_WME))
159
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
1034.1.8 by Brian Aker
Remove locks around my_open(). Open file counts are now "best effort" (not
160
51.3.13 by Jay Pipes
Phase 1 removal of DBUG in mysys
161
  return((MY_DIR *) NULL);
1 by brian
clean slate
162
} /* my_dir */
163
164
165
/*
166
 * Convert from directory name to filename.
167
 * On VMS:
168
 *	 xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
169
 *	 xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
170
 * On UNIX, it's simple: just make sure there is a terminating /
171
172
 * Returns pointer to dst;
173
 */
174
175
char * directory_file_name (char * dst, const char *src)
176
{
177
  /* Process as Unix format: just remove test the final slash. */
178
179
  char * end;
180
181
  if (src[0] == 0)
182
    src= (char*) ".";				/* Use empty as current */
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
183
  end= strcpy(dst, src)+strlen(src);
1 by brian
clean slate
184
  if (end[-1] != FN_LIBCHAR)
185
  {
186
    end[0]=FN_LIBCHAR;				/* Add last '/' */
187
    end[1]='\0';
188
  }
189
  return dst;
190
} /* directory_file_name */
191