~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_lib.c

  • Committer: Monty Taylor
  • Date: 2010-10-02 05:07:25 UTC
  • mto: (1817.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 1818.
  • Revision ID: mordred@inaugust.com-20101002050725-h1b30b0nr3leeoh1
Embed a modified version of parse_config_file. There are several more bugs
that we'll want to fix in it, and then submit upstream. Eventually we should
be able to remove this- but for now the version on lucid is completely
broken.

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        <mystrings/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(const struct fileinfo *a, const 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
 
  if (buffer)
64
 
  {
65
 
    delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer + 
66
 
                                    ALIGN_SIZE(sizeof(MY_DIR))));
67
 
    free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) + 
68
 
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
69
 
    my_free((uchar*) buffer,MYF(0));
70
 
  }
71
 
  return;
72
 
} /* my_dirend */
73
 
 
74
 
 
75
 
        /* Compare in sort of filenames */
76
 
 
77
 
static int comp_names(const struct fileinfo *a, const struct fileinfo *b)
78
 
{
79
 
  return (strcmp(a->name,b->name));
80
 
} /* comp_names */
81
 
 
82
 
 
83
 
MY_DIR  *my_dir(const char *path, myf MyFlags)
84
 
{
85
 
  char          *buffer;
86
 
  MY_DIR        *result= 0;
87
 
  FILEINFO      finfo;
88
 
  DYNAMIC_ARRAY *dir_entries_storage;
89
 
  MEM_ROOT      *names_storage;
90
 
  DIR           *dirp;
91
 
  struct dirent *dp;
92
 
  char          tmp_path[FN_REFLEN+1],*tmp_file;
93
 
  char  dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
94
 
 
95
 
#if !defined(HAVE_READDIR_R)
96
 
  pthread_mutex_lock(&THR_LOCK_open);
97
 
#endif
98
 
 
99
 
  dirp = opendir(directory_file_name(tmp_path,(char *) path));
100
 
  if (dirp == NULL || 
101
 
      ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
102
 
                           ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
103
 
                           sizeof(MEM_ROOT), MyFlags)))
104
 
    goto error;
105
 
 
106
 
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
107
 
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
108
 
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
109
 
  
110
 
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
111
 
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
112
 
  {
113
 
    my_free((uchar*) buffer,MYF(0));
114
 
    goto error;
115
 
  }
116
 
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
117
 
  
118
 
  /* MY_DIR structure is allocated and completly initialized at this point */
119
 
  result= (MY_DIR*)buffer;
120
 
 
121
 
  tmp_file=strend(tmp_path);
122
 
 
123
 
  dp= (struct dirent*) dirent_tmp;
124
 
  
125
 
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
126
 
  {
127
 
    if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
128
 
      goto error;
129
 
    
130
 
    if (MyFlags & MY_WANT_STAT)
131
 
    {
132
 
      if (!(finfo.mystat= (struct stat*)alloc_root(names_storage, 
133
 
                                               sizeof(struct stat))))
134
 
        goto error;
135
 
      
136
 
      memset(finfo.mystat, 0, sizeof(struct stat));
137
 
      VOID(stpcpy(tmp_file,dp->d_name));
138
 
      VOID(stat(tmp_path, finfo.mystat));
139
 
      if (!(finfo.mystat->st_mode & S_IREAD))
140
 
        continue;
141
 
    }
142
 
    else
143
 
      finfo.mystat= NULL;
144
 
 
145
 
    if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
146
 
      goto error;
147
 
  }
148
 
 
149
 
  (void) closedir(dirp);
150
 
#if !defined(HAVE_READDIR_R)
151
 
  pthread_mutex_unlock(&THR_LOCK_open);
152
 
#endif
153
 
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
154
 
  result->number_off_files= dir_entries_storage->elements;
155
 
  
156
 
  if (!(MyFlags & MY_DONT_SORT))
157
 
    my_qsort((void *) result->dir_entry, result->number_off_files,
158
 
          sizeof(FILEINFO), (qsort_cmp) comp_names);
159
 
  return(result);
160
 
 
161
 
 error:
162
 
#if !defined(HAVE_READDIR_R)
163
 
  pthread_mutex_unlock(&THR_LOCK_open);
164
 
#endif
165
 
  my_errno=errno;
166
 
  if (dirp)
167
 
    (void) closedir(dirp);
168
 
  my_dirend(result);
169
 
  if (MyFlags & (MY_FAE | MY_WME))
170
 
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
171
 
  return((MY_DIR *) NULL);
172
 
} /* my_dir */
173
 
 
174
 
 
175
 
/*
176
 
 * Convert from directory name to filename.
177
 
 * On VMS:
178
 
 *       xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
179
 
 *       xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
180
 
 * On UNIX, it's simple: just make sure there is a terminating /
181
 
 
182
 
 * Returns pointer to dst;
183
 
 */
184
 
 
185
 
char * directory_file_name (char * dst, const char *src)
186
 
{
187
 
  /* Process as Unix format: just remove test the final slash. */
188
 
 
189
 
  char * end;
190
 
 
191
 
  if (src[0] == 0)
192
 
    src= (char*) ".";                           /* Use empty as current */
193
 
  end=stpcpy(dst, src);
194
 
  if (end[-1] != FN_LIBCHAR)
195
 
  {
196
 
    end[0]=FN_LIBCHAR;                          /* Add last '/' */
197
 
    end[1]='\0';
198
 
  }
199
 
  return dst;
200
 
} /* directory_file_name */
201