~ubuntu-branches/ubuntu/quantal/mysql-workbench/quantal

« back to all changes in this revision

Viewing changes to library/sql-parser/source/my_lib.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-03-01 21:57:30 UTC
  • Revision ID: package-import@ubuntu.com-20120301215730-o7y8av8y38n162ro
Tags: upstream-5.2.38+dfsg
ImportĀ upstreamĀ versionĀ 5.2.38+dfsg

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; either version 2 of the License, or
 
6
   (at your option) any later version.
 
7
 
 
8
   This program is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
   GNU General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; if not, write to the Free Software
 
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
16
 
 
17
/* TODO: check for overun of memory for names. */
 
18
/*       Convert MSDOS-TIME to standar time_t */
 
19
 
 
20
#define USES_TYPES              /* sys/types is included */
 
21
#include        "mysys_priv.h"
 
22
#include        <m_string.h>
 
23
#include        <my_dir.h>      /* Structs used by my_dir,includes sys/types */
 
24
#include        "mysys_err.h"
 
25
#if defined(HAVE_DIRENT_H)
 
26
# include <dirent.h>
 
27
# define NAMLEN(dirent) strlen((dirent)->d_name)
 
28
#else
 
29
#ifndef OS2
 
30
# define dirent direct
 
31
#endif
 
32
# define NAMLEN(dirent) (dirent)->d_namlen
 
33
# if defined(HAVE_SYS_NDIR_H)
 
34
#  include <sys/ndir.h>
 
35
# endif
 
36
# if defined(HAVE_SYS_DIR_H)
 
37
#  include <sys/dir.h>
 
38
# endif
 
39
# if defined(HAVE_NDIR_H)
 
40
#  include <ndir.h>
 
41
# endif
 
42
# if defined(MSDOS) || defined(__WIN__)
 
43
# include <dos.h>
 
44
# ifdef __BORLANDC__
 
45
# include <dir.h>
 
46
# endif
 
47
# endif
 
48
#endif
 
49
#ifdef VMS
 
50
#include <rms.h>
 
51
#include <iodef.h>
 
52
#include <descrip.h>
 
53
#endif
 
54
 
 
55
#ifdef OS2
 
56
#include "my_os2dirsrch.h"
 
57
#endif
 
58
 
 
59
#if defined(THREAD) && defined(HAVE_READDIR_R)
 
60
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
 
61
#else
 
62
#define READDIR(A,B,C) (!(C=readdir(A)))
 
63
#endif
 
64
 
 
65
/*
 
66
  We are assuming that directory we are reading is either has less than 
 
67
  100 files and so can be read in one initial chunk or has more than 1000
 
68
  files and so big increment are suitable.
 
69
*/
 
70
#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO))
 
71
#define ENTRIES_INCREMENT  (65536/sizeof(FILEINFO))
 
72
#define NAMES_START_SIZE   32768
 
73
 
 
74
namespace mysql_parser
 
75
{
 
76
 
 
77
#if 0
 
78
 
 
79
static int      comp_names(struct fileinfo *a,struct fileinfo *b);
 
80
 
 
81
 
 
82
        /* We need this because program don't know with malloc we used */
 
83
 
 
84
#if 0
 
85
void my_dirend(MY_DIR *buffer)
 
86
{
 
87
  DBUG_ENTER("my_dirend");
 
88
  if (buffer)
 
89
  {
 
90
    delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer + 
 
91
                                    ALIGN_SIZE(sizeof(MY_DIR))));
 
92
    free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) + 
 
93
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
 
94
    my_free((gptr) buffer,MYF(0));
 
95
  }
 
96
  DBUG_VOID_RETURN;
 
97
} /* my_dirend */
 
98
#endif
 
99
 
 
100
        /* Compare in sort of filenames */
 
101
 
 
102
static int comp_names(struct fileinfo *a, struct fileinfo *b)
 
103
{
 
104
  return (strcmp(a->name,b->name));
 
105
} /* comp_names */
 
106
 
 
107
 
 
108
#if !defined(MSDOS) && !defined(__WIN__)
 
109
 
 
110
MY_DIR  *my_dir(const char *path, myf MyFlags)
 
111
{
 
112
  char          *buffer;
 
113
  MY_DIR        *result= 0;
 
114
  FILEINFO      finfo;
 
115
  DYNAMIC_ARRAY *dir_entries_storage;
 
116
  DIR           *dirp;
 
117
  struct dirent *dp;
 
118
  char          tmp_path[FN_REFLEN+1],*tmp_file;
 
119
#ifdef THREAD
 
120
  char  dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
 
121
#endif
 
122
  DBUG_ENTER("my_dir");
 
123
  DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));
 
124
 
 
125
#if defined(THREAD) && !defined(HAVE_READDIR_R)
 
126
  pthread_mutex_lock(&THR_LOCK_open);
 
127
#endif
 
128
 
 
129
  dirp = opendir(directory_file_name(tmp_path,(my_string) path));
 
130
#if defined(__amiga__)
 
131
  if ((dirp->dd_fd) < 0)                        /* Directory doesn't exists */
 
132
    goto error;
 
133
#endif
 
134
  if (dirp == NULL || 
 
135
      ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
 
136
                           ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)),
 
137
                           MyFlags)))
 
138
    goto error;
 
139
 
 
140
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
 
141
  
 
142
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
 
143
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
 
144
  {
 
145
    my_free((gptr) buffer,MYF(0));
 
146
    goto error;
 
147
  }
 
148
  
 
149
  /* MY_DIR structure is allocated and completly initialized at this point */
 
150
  result= (MY_DIR*)buffer;
 
151
 
 
152
  tmp_file=strend(tmp_path);
 
153
 
 
154
#ifdef THREAD
 
155
  dp= (struct dirent*) dirent_tmp;
 
156
#else
 
157
  dp=0;
 
158
#endif
 
159
  
 
160
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
 
161
  {
 
162
    if (!(finfo.name= strdup_root(dp->d_name)))
 
163
      goto error;
 
164
    
 
165
    if (MyFlags & MY_WANT_STAT)
 
166
    {
 
167
      if (!(finfo.mystat= (MY_STAT*)alloc_root(sizeof(MY_STAT))))
 
168
        goto error;
 
169
      
 
170
      bzero(finfo.mystat, sizeof(MY_STAT));
 
171
      VOID(strmov(tmp_file,dp->d_name));
 
172
      VOID(my_stat(tmp_path, finfo.mystat, MyFlags));
 
173
      if (!(finfo.mystat->st_mode & MY_S_IREAD))
 
174
        continue;
 
175
    }
 
176
    else
 
177
      finfo.mystat= NULL;
 
178
 
 
179
    if (push_dynamic(dir_entries_storage, (gptr)&finfo))
 
180
      goto error;
 
181
  }
 
182
 
 
183
  (void) closedir(dirp);
 
184
#if defined(THREAD) && !defined(HAVE_READDIR_R)
 
185
  pthread_mutex_unlock(&THR_LOCK_open);
 
186
#endif
 
187
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
 
188
  result->number_off_files= dir_entries_storage->elements;
 
189
  
 
190
  if (!(MyFlags & MY_DONT_SORT))
 
191
    qsort((void *) result->dir_entry, result->number_off_files,
 
192
          sizeof(FILEINFO), (qsort_cmp) comp_names);
 
193
  DBUG_RETURN(result);
 
194
 
 
195
 error:
 
196
#if defined(THREAD) && !defined(HAVE_READDIR_R)
 
197
  pthread_mutex_unlock(&THR_LOCK_open);
 
198
#endif
 
199
  my_errno=errno;
 
200
  if (dirp)
 
201
    (void) closedir(dirp);
 
202
  my_dirend(result);
 
203
  if (MyFlags & (MY_FAE | MY_WME))
 
204
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
 
205
  DBUG_RETURN((MY_DIR *) NULL);
 
206
} /* my_dir */
 
207
 
 
208
 
 
209
/*
 
210
 * Convert from directory name to filename.
 
211
 * On VMS:
 
212
 *       xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
 
213
 *       xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
 
214
 * On UNIX, it's simple: just make sure there is a terminating /
 
215
 
 
216
 * Returns pointer to dst;
 
217
 */
 
218
 
 
219
my_string directory_file_name (my_string dst, const char *src)
 
220
{
 
221
#ifndef VMS
 
222
 
 
223
  /* Process as Unix format: just remove test the final slash. */
 
224
 
 
225
  my_string end;
 
226
 
 
227
  if (src[0] == 0)
 
228
    src= (char*) ".";                           /* Use empty as current */
 
229
  end=strmov(dst, src);
 
230
  if (end[-1] != FN_LIBCHAR)
 
231
  {
 
232
    end[0]=FN_LIBCHAR;                          /* Add last '/' */
 
233
    end[1]='\0';
 
234
  }
 
235
  return dst;
 
236
 
 
237
#else   /* VMS */
 
238
 
 
239
  long slen;
 
240
  long rlen;
 
241
  my_string ptr, rptr;
 
242
  char bracket;
 
243
  struct FAB fab = cc$rms_fab;
 
244
  struct NAM nam = cc$rms_nam;
 
245
  char esa[NAM$C_MAXRSS];
 
246
 
 
247
  if (! src[0])
 
248
    src="[.]";                                  /* Empty is == current dir */
 
249
 
 
250
  slen = strlen (src) - 1;
 
251
  if (src[slen] == FN_C_AFTER_DIR || src[slen] == FN_C_AFTER_DIR_2 ||
 
252
      src[slen] == FN_DEVCHAR)
 
253
  {
 
254
        /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
 
255
    fab.fab$l_fna = src;
 
256
    fab.fab$b_fns = slen + 1;
 
257
    fab.fab$l_nam = &nam;
 
258
    fab.fab$l_fop = FAB$M_NAM;
 
259
 
 
260
    nam.nam$l_esa = esa;
 
261
    nam.nam$b_ess = sizeof esa;
 
262
    nam.nam$b_nop |= NAM$M_SYNCHK;
 
263
 
 
264
    /* We call SYS$PARSE to handle such things as [--] for us. */
 
265
    if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL)
 
266
    {
 
267
      slen = nam.nam$b_esl - 1;
 
268
      if (esa[slen] == ';' && esa[slen - 1] == '.')
 
269
        slen -= 2;
 
270
      esa[slen + 1] = '\0';
 
271
      src = esa;
 
272
    }
 
273
    if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2)
 
274
    {
 
275
        /* what about when we have logical_name:???? */
 
276
      if (src[slen] == FN_DEVCHAR)
 
277
      {                         /* Xlate logical name and see what we get */
 
278
        VOID(strmov(dst,src));
 
279
        dst[slen] = 0;                          /* remove colon */
 
280
        if (!(src = getenv (dst)))
 
281
          return dst;                           /* Can't translate */
 
282
 
 
283
        /* should we jump to the beginning of this procedure?
 
284
           Good points: allows us to use logical names that xlate
 
285
           to Unix names,
 
286
           Bad points: can be a problem if we just translated to a device
 
287
           name...
 
288
           For now, I'll punt and always expect VMS names, and hope for
 
289
           the best! */
 
290
 
 
291
        slen = strlen (src) - 1;
 
292
        if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2)
 
293
        {                                       /* no recursion here! */
 
294
          VOID(strmov(dst, src));
 
295
          return(dst);
 
296
        }
 
297
      }
 
298
      else
 
299
      {                                         /* not a directory spec */
 
300
        VOID(strmov(dst, src));
 
301
        return(dst);
 
302
      }
 
303
    }
 
304
 
 
305
    bracket = src[slen];                        /* End char */
 
306
    if (!(ptr = strchr (src, bracket - 2)))
 
307
    {                                           /* no opening bracket */
 
308
      VOID(strmov (dst, src));
 
309
      return dst;
 
310
    }
 
311
    if (!(rptr = strrchr (src, '.')))
 
312
      rptr = ptr;
 
313
    slen = rptr - src;
 
314
    VOID(strmake (dst, src, slen));
 
315
 
 
316
    if (*rptr == '.')
 
317
    {                                           /* Put bracket and add */
 
318
      dst[slen++] = bracket;                    /* (rptr+1) after this */
 
319
    }
 
320
    else
 
321
    {
 
322
      /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
 
323
         then translate the device and recurse. */
 
324
 
 
325
      if (dst[slen - 1] == ':'
 
326
          && dst[slen - 2] != ':'       /* skip decnet nodes */
 
327
          && strcmp(src + slen, "[000000]") == 0)
 
328
      {
 
329
        dst[slen - 1] = '\0';
 
330
        if ((ptr = getenv (dst))
 
331
            && (rlen = strlen (ptr) - 1) > 0
 
332
            && (ptr[rlen] == FN_C_AFTER_DIR || ptr[rlen] == FN_C_AFTER_DIR_2)
 
333
            && ptr[rlen - 1] == '.')
 
334
        {
 
335
          VOID(strmov(esa,ptr));
 
336
          esa[rlen - 1] = FN_C_AFTER_DIR;
 
337
          esa[rlen] = '\0';
 
338
          return (directory_file_name (dst, esa));
 
339
        }
 
340
        else
 
341
          dst[slen - 1] = ':';
 
342
      }
 
343
      VOID(strmov(dst+slen,"[000000]"));
 
344
      slen += 8;
 
345
    }
 
346
    VOID(strmov(strmov(dst+slen,rptr+1)-1,".DIR.1"));
 
347
    return dst;
 
348
  }
 
349
  VOID(strmov(dst, src));
 
350
  if (dst[slen] == '/' && slen > 1)
 
351
    dst[slen] = 0;
 
352
  return dst;
 
353
#endif  /* VMS */
 
354
} /* directory_file_name */
 
355
 
 
356
#elif defined(WIN32)
 
357
 
 
358
/*
 
359
*****************************************************************************
 
360
** Read long filename using windows rutines
 
361
*****************************************************************************
 
362
*/
 
363
 
 
364
#if 0
 
365
MY_DIR  *my_dir(const char *path, myf MyFlags)
 
366
{
 
367
  char          *buffer;
 
368
  MY_DIR        *result= 0;
 
369
  FILEINFO      finfo;
 
370
  DYNAMIC_ARRAY *dir_entries_storage;
 
371
  MEM_ROOT      *names_storage;
 
372
#ifdef __BORLANDC__
 
373
  struct ffblk       find;
 
374
#else
 
375
  struct _finddata_t find;
 
376
#endif
 
377
  ushort        mode;
 
378
  char          tmp_path[FN_REFLEN],*tmp_file,attrib;
 
379
#ifdef _WIN64
 
380
  __int64       handle;
 
381
#else
 
382
  long          handle;
 
383
#endif
 
384
  DBUG_ENTER("my_dir");
 
385
  DBUG_PRINT("my",("path: '%s' stat: %d  MyFlags: %d",path,MyFlags));
 
386
 
 
387
  /* Put LIB-CHAR as last path-character if not there */
 
388
 
 
389
  tmp_file=tmp_path;
 
390
  if (!*path)
 
391
    *tmp_file++ ='.';                           /* From current dir */
 
392
  tmp_file= strmov(tmp_file,path);
 
393
  if (tmp_file[-1] == FN_DEVCHAR)
 
394
    *tmp_file++= '.';                           /* From current dev-dir */
 
395
  if (tmp_file[-1] != FN_LIBCHAR)
 
396
    *tmp_file++ =FN_LIBCHAR;
 
397
  tmp_file[0]='*';                              /* MSDOS needs this !??? */
 
398
  tmp_file[1]='.';
 
399
  tmp_file[2]='*';
 
400
  tmp_file[3]='\0';
 
401
 
 
402
  if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
 
403
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
 
404
                          sizeof(MEM_ROOT), MyFlags)))
 
405
    goto error;
 
406
 
 
407
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
 
408
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
 
409
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
 
410
  
 
411
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
 
412
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
 
413
  {
 
414
    my_free((gptr) buffer,MYF(0));
 
415
    goto error;
 
416
  }
 
417
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
 
418
  
 
419
  /* MY_DIR structure is allocated and completly initialized at this point */
 
420
  result= (MY_DIR*)buffer;
 
421
 
 
422
#ifdef __BORLANDC__
 
423
  if ((handle= findfirst(tmp_path,&find,0)) == -1L)
 
424
#else
 
425
  if ((handle=_findfirst(tmp_path,&find)) == -1L)
 
426
#endif
 
427
  {
 
428
    DBUG_PRINT("info", ("find_first returned error"));
 
429
    if  (errno != EINVAL)
 
430
      goto error;
 
431
    /*
 
432
      Could not read the directory, no read access.
 
433
      Probably because by "chmod -r".
 
434
      continue and return zero files in dir
 
435
    */
 
436
  }
 
437
 
 
438
  do
 
439
  {
 
440
#ifdef __BORLANDC__
 
441
    attrib= find.ff_attrib;
 
442
#else
 
443
    attrib= find.attrib;
 
444
    /*
 
445
      Do not show hidden and system files which Windows sometimes create.
 
446
      Note. Because Borland's findfirst() is called with the third
 
447
      argument = 0 hidden/system files are excluded from the search.
 
448
    */
 
449
    if (attrib & (_A_HIDDEN | _A_SYSTEM))
 
450
      continue;
 
451
#endif    
 
452
#ifdef __BORLANDC__
 
453
    if (!(finfo.name= strdup_root(names_storage, find.ff_name)))
 
454
      goto error;
 
455
#else
 
456
    if (!(finfo.name= strdup_root(names_storage, find.name)))
 
457
      goto error;
 
458
#endif    
 
459
    if (MyFlags & MY_WANT_STAT)
 
460
    {
 
461
      if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, 
 
462
                                               sizeof(MY_STAT))))
 
463
        goto error;
 
464
      
 
465
      bzero(finfo.mystat, sizeof(MY_STAT));
 
466
#ifdef __BORLANDC__
 
467
      finfo.mystat->st_size=find.ff_fsize;
 
468
#else
 
469
      finfo.mystat->st_size=find.size;
 
470
#endif
 
471
      mode=MY_S_IREAD;
 
472
      if (!(attrib & _A_RDONLY))
 
473
        mode|=MY_S_IWRITE;
 
474
      if (attrib & _A_SUBDIR)
 
475
        mode|=MY_S_IFDIR;
 
476
      finfo.mystat->st_mode=mode;
 
477
#ifdef __BORLANDC__
 
478
      finfo.mystat->st_mtime=((uint32) find.ff_ftime);
 
479
#else
 
480
      finfo.mystat->st_mtime=((uint32) find.time_write);
 
481
#endif
 
482
    }
 
483
    else
 
484
      finfo.mystat= NULL;
 
485
 
 
486
    if (push_dynamic(dir_entries_storage, (gptr)&finfo))
 
487
      goto error;
 
488
    
 
489
#ifdef __BORLANDC__
 
490
  } while (findnext(&find) == 0);
 
491
#else
 
492
  } while (_findnext(handle,&find) == 0);
 
493
  
 
494
  _findclose(handle);
 
495
#endif
 
496
 
 
497
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
 
498
  result->number_off_files= dir_entries_storage->elements;
 
499
  
 
500
  if (!(MyFlags & MY_DONT_SORT))
 
501
    qsort((void *) result->dir_entry, result->number_off_files,
 
502
          sizeof(FILEINFO), (qsort_cmp) comp_names);
 
503
  DBUG_RETURN(result);
 
504
error:
 
505
  my_errno=errno;
 
506
#ifndef __BORLANDC__
 
507
  if (handle != -1)
 
508
      _findclose(handle);
 
509
#endif
 
510
  my_dirend(result);
 
511
  if (MyFlags & MY_FAE+MY_WME)
 
512
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
 
513
  DBUG_RETURN((MY_DIR *) NULL);
 
514
} /* my_dir */
 
515
 
 
516
#endif // #if 0
 
517
 
 
518
#else /* MSDOS and not WIN32 */
 
519
 
 
520
 
 
521
/******************************************************************************
 
522
** At MSDOS you always get stat of files, but time is in packed MSDOS-format
 
523
******************************************************************************/
 
524
 
 
525
MY_DIR  *my_dir(const char* path, myf MyFlags)
 
526
{
 
527
  char          *buffer;
 
528
  MY_DIR        *result= 0;
 
529
  FILEINFO      finfo;
 
530
  DYNAMIC_ARRAY *dir_entries_storage;
 
531
  MEM_ROOT      *names_storage;
 
532
  struct find_t find;
 
533
  ushort        mode;
 
534
  char          tmp_path[FN_REFLEN],*tmp_file,attrib;
 
535
  DBUG_ENTER("my_dir");
 
536
  DBUG_PRINT("my",("path: '%s' stat: %d  MyFlags: %d",path,MyFlags));
 
537
 
 
538
  /* Put LIB-CHAR as last path-character if not there */
 
539
 
 
540
  tmp_file=tmp_path;
 
541
  if (!*path)
 
542
    *tmp_file++ ='.';                           /* From current dir */
 
543
  tmp_file= strmov(tmp_file,path);
 
544
  if (tmp_file[-1] == FN_DEVCHAR)
 
545
    *tmp_file++= '.';                           /* From current dev-dir */
 
546
  if (tmp_file[-1] != FN_LIBCHAR)
 
547
    *tmp_file++ =FN_LIBCHAR;
 
548
  tmp_file[0]='*';                              /* MSDOS needs this !??? */
 
549
  tmp_file[1]='.';
 
550
  tmp_file[2]='*';
 
551
  tmp_file[3]='\0';
 
552
 
 
553
  if (_dos_findfirst(tmp_path,_A_NORMAL | _A_SUBDIR, &find))
 
554
    goto error;
 
555
 
 
556
  if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
 
557
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
 
558
                          sizeof(MEM_ROOT), MyFlags)))
 
559
    goto error;
 
560
 
 
561
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
 
562
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
 
563
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
 
564
  
 
565
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
 
566
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
 
567
  {
 
568
    my_free((gptr) buffer,MYF(0));
 
569
    goto error;
 
570
  }
 
571
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
 
572
  
 
573
  /* MY_DIR structure is allocated and completly initialized at this point */
 
574
  result= (MY_DIR*)buffer;
 
575
 
 
576
  do
 
577
  {
 
578
    if (!(finfo.name= strdup_root(names_storage, find.name)))
 
579
      goto error;
 
580
    
 
581
    if (MyFlags & MY_WANT_STAT)
 
582
    {
 
583
      if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, 
 
584
                                               sizeof(MY_STAT))))
 
585
        goto error;
 
586
      
 
587
      bzero(finfo.mystat, sizeof(MY_STAT));
 
588
      finfo.mystat->st_size= find.size;
 
589
      mode= MY_S_IREAD; attrib= find.attrib;
 
590
      if (!(attrib & _A_RDONLY))
 
591
        mode|= MY_S_IWRITE;
 
592
      if (attrib & _A_SUBDIR)
 
593
        mode|= MY_S_IFDIR;
 
594
      finfo.mystat->st_mode= mode;
 
595
      finfo.mystat->st_mtime= ((uint32) find.wr_date << 16) + find.wr_time;
 
596
    }
 
597
    else
 
598
      finfo.mystat= NULL;
 
599
 
 
600
    if (push_dynamic(dir_entries_storage, (gptr)&finfo))
 
601
      goto error;
 
602
  
 
603
  } while (_dos_findnext(&find) == 0);
 
604
  
 
605
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
 
606
  result->number_off_files= dir_entries_storage->elements;
 
607
  
 
608
  if (!(MyFlags & MY_DONT_SORT))
 
609
    qsort((void *) result->dir_entry, result->number_off_files,
 
610
          sizeof(FILEINFO), (qsort_cmp) comp_names);
 
611
  DBUG_RETURN(result);
 
612
 
 
613
error:
 
614
  my_dirend(result);
 
615
  if (MyFlags & MY_FAE+MY_WME)
 
616
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
 
617
  DBUG_RETURN((MY_DIR *) NULL);
 
618
} /* my_dir */
 
619
 
 
620
#endif /* WIN32 && MSDOS */
 
621
 
 
622
/****************************************************************************
 
623
** File status
 
624
** Note that MY_STAT is assumed to be same as struct stat
 
625
****************************************************************************/ 
 
626
 
 
627
int my_fstat(int Filedes, MY_STAT *stat_area,
 
628
             myf MyFlags __attribute__((unused)))
 
629
{
 
630
  DBUG_ENTER("my_fstat");
 
631
  DBUG_PRINT("my",("fd: %d MyFlags: %d",Filedes,MyFlags));
 
632
  DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
 
633
}
 
634
#endif
 
635
 
 
636
MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
 
637
{
 
638
  int m_used;
 
639
  DBUG_ENTER("my_stat");
 
640
  DBUG_PRINT("my", ("path: '%s', stat_area: 0x%lx, MyFlags: %d", path,
 
641
             (byte *) stat_area, my_flags));
 
642
 
 
643
  if ((m_used= (stat_area == NULL)))
 
644
    if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
 
645
      goto error;
 
646
  if (! stat((my_string) path, (struct stat *) stat_area) )
 
647
    DBUG_RETURN(stat_area);
 
648
 
 
649
  DBUG_PRINT("error",("Got errno: %d from stat", errno));
 
650
//  my_errno= errno;
 
651
  if (m_used)                                   /* Free if new area */
 
652
    my_free((gptr) stat_area,MYF(0));
 
653
 
 
654
error:
 
655
  if (my_flags & (MY_FAE+MY_WME))
 
656
  {
 
657
//    my_error(EE_STAT, MYF(ME_BELL+ME_WAITTANG),path,my_errno);
 
658
    DBUG_RETURN((MY_STAT *) NULL);
 
659
  }
 
660
  DBUG_RETURN((MY_STAT *) NULL);
 
661
} /* my_stat */
 
662
 
 
663
} // namespace mysql_parser