~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_lib.c

  • Committer: Stewart Smith
  • Date: 2008-07-13 06:56:15 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713065615-vzok75kgnnviokl9
Move MD5() into a UDF

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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"
 
20
#include        <m_string.h>
 
21
#include        <my_dir.h>      /* Structs used by my_dir,includes sys/types */
 
22
#include        "mysys_err.h"
 
23
#if defined(HAVE_DIRENT_H)
 
24
# include <dirent.h>
 
25
# define NAMLEN(dirent) strlen((dirent)->d_name)
 
26
#else
 
27
# define dirent direct
 
28
# define NAMLEN(dirent) (dirent)->d_namlen
 
29
# if defined(HAVE_SYS_NDIR_H)
 
30
#  include <sys/ndir.h>
 
31
# endif
 
32
# if defined(HAVE_SYS_DIR_H)
 
33
#  include <sys/dir.h>
 
34
# endif
 
35
# if defined(HAVE_NDIR_H)
 
36
#  include <ndir.h>
 
37
# endif
 
38
#endif
 
39
 
 
40
#if defined(HAVE_READDIR_R)
 
41
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
 
42
#else
 
43
#define READDIR(A,B,C) (!(C=readdir(A)))
 
44
#endif
 
45
 
 
46
/*
 
47
  We are assuming that directory we are reading is either has less than 
 
48
  100 files and so can be read in one initial chunk or has more than 1000
 
49
  files and so big increment are suitable.
 
50
*/
 
51
#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO))
 
52
#define ENTRIES_INCREMENT  (65536/sizeof(FILEINFO))
 
53
#define NAMES_START_SIZE   32768
 
54
 
 
55
 
 
56
static int      comp_names(struct fileinfo *a,struct fileinfo *b);
 
57
 
 
58
 
 
59
        /* We need this because program don't know with malloc we used */
 
60
 
 
61
void my_dirend(MY_DIR *buffer)
 
62
{
 
63
  DBUG_ENTER("my_dirend");
 
64
  if (buffer)
 
65
  {
 
66
    delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer + 
 
67
                                    ALIGN_SIZE(sizeof(MY_DIR))));
 
68
    free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) + 
 
69
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
 
70
    my_free((uchar*) buffer,MYF(0));
 
71
  }
 
72
  DBUG_VOID_RETURN;
 
73
} /* my_dirend */
 
74
 
 
75
 
 
76
        /* Compare in sort of filenames */
 
77
 
 
78
static int comp_names(struct fileinfo *a, struct fileinfo *b)
 
79
{
 
80
  return (strcmp(a->name,b->name));
 
81
} /* comp_names */
 
82
 
 
83
 
 
84
MY_DIR  *my_dir(const char *path, myf MyFlags)
 
85
{
 
86
  char          *buffer;
 
87
  MY_DIR        *result= 0;
 
88
  FILEINFO      finfo;
 
89
  DYNAMIC_ARRAY *dir_entries_storage;
 
90
  MEM_ROOT      *names_storage;
 
91
  DIR           *dirp;
 
92
  struct dirent *dp;
 
93
  char          tmp_path[FN_REFLEN+1],*tmp_file;
 
94
  char  dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
 
95
  DBUG_ENTER("my_dir");
 
96
  DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));
 
97
 
 
98
#if !defined(HAVE_READDIR_R)
 
99
  pthread_mutex_lock(&THR_LOCK_open);
 
100
#endif
 
101
 
 
102
  dirp = opendir(directory_file_name(tmp_path,(char *) path));
 
103
  if (dirp == NULL || 
 
104
      ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
 
105
                           ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
 
106
                           sizeof(MEM_ROOT), MyFlags)))
 
107
    goto error;
 
108
 
 
109
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
 
110
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
 
111
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
 
112
  
 
113
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
 
114
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
 
115
  {
 
116
    my_free((uchar*) buffer,MYF(0));
 
117
    goto error;
 
118
  }
 
119
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
 
120
  
 
121
  /* MY_DIR structure is allocated and completly initialized at this point */
 
122
  result= (MY_DIR*)buffer;
 
123
 
 
124
  tmp_file=strend(tmp_path);
 
125
 
 
126
  dp= (struct dirent*) dirent_tmp;
 
127
  
 
128
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
 
129
  {
 
130
    if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
 
131
      goto error;
 
132
    
 
133
    if (MyFlags & MY_WANT_STAT)
 
134
    {
 
135
      if (!(finfo.mystat= (struct stat*)alloc_root(names_storage, 
 
136
                                               sizeof(struct stat))))
 
137
        goto error;
 
138
      
 
139
      bzero(finfo.mystat, sizeof(struct stat));
 
140
      VOID(strmov(tmp_file,dp->d_name));
 
141
      VOID(stat(tmp_path, finfo.mystat));
 
142
      if (!(finfo.mystat->st_mode & MY_S_IREAD))
 
143
        continue;
 
144
    }
 
145
    else
 
146
      finfo.mystat= NULL;
 
147
 
 
148
    if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
 
149
      goto error;
 
150
  }
 
151
 
 
152
  (void) closedir(dirp);
 
153
#if !defined(HAVE_READDIR_R)
 
154
  pthread_mutex_unlock(&THR_LOCK_open);
 
155
#endif
 
156
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
 
157
  result->number_off_files= dir_entries_storage->elements;
 
158
  
 
159
  if (!(MyFlags & MY_DONT_SORT))
 
160
    my_qsort((void *) result->dir_entry, result->number_off_files,
 
161
          sizeof(FILEINFO), (qsort_cmp) comp_names);
 
162
  DBUG_RETURN(result);
 
163
 
 
164
 error:
 
165
#if !defined(HAVE_READDIR_R)
 
166
  pthread_mutex_unlock(&THR_LOCK_open);
 
167
#endif
 
168
  my_errno=errno;
 
169
  if (dirp)
 
170
    (void) closedir(dirp);
 
171
  my_dirend(result);
 
172
  if (MyFlags & (MY_FAE | MY_WME))
 
173
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
 
174
  DBUG_RETURN((MY_DIR *) NULL);
 
175
} /* my_dir */
 
176
 
 
177
 
 
178
/*
 
179
 * Convert from directory name to filename.
 
180
 * On VMS:
 
181
 *       xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
 
182
 *       xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
 
183
 * On UNIX, it's simple: just make sure there is a terminating /
 
184
 
 
185
 * Returns pointer to dst;
 
186
 */
 
187
 
 
188
char * directory_file_name (char * dst, const char *src)
 
189
{
 
190
  /* Process as Unix format: just remove test the final slash. */
 
191
 
 
192
  char * end;
 
193
 
 
194
  if (src[0] == 0)
 
195
    src= (char*) ".";                           /* Use empty as current */
 
196
  end=strmov(dst, src);
 
197
  if (end[-1] != FN_LIBCHAR)
 
198
  {
 
199
    end[0]=FN_LIBCHAR;                          /* Add last '/' */
 
200
    end[1]='\0';
 
201
  }
 
202
  return dst;
 
203
} /* directory_file_name */
 
204