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