~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_lib.cc

  • Committer: Jay Pipes
  • Date: 2008-12-18 15:55:03 UTC
  • mto: This revision was merged to the branch mainline in revision 717.
  • Revision ID: jpipes@serialcoder-20081218155503-u45ygyunrdyyvquq
Fix for Bug#308457.  Gave UTF8 enclosure and escape character on LOAD DATA INFILE and changed the error message to be more descriptive

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
#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
 
 
38
#if defined(HAVE_READDIR_R)
 
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
/*
 
45
  We are assuming that directory we are reading is either has less than
 
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
 
 
54
static int comp_names(const struct fileinfo *a, const struct fileinfo *b);
 
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
  {
 
63
    delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
 
64
                                    ALIGN_SIZE(sizeof(MY_DIR))));
 
65
    free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
 
66
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
 
67
    free((unsigned char*) buffer);
 
68
  }
 
69
  return;
 
70
} /* my_dirend */
 
71
 
 
72
 
 
73
        /* Compare in sort of filenames */
 
74
 
 
75
static int comp_names(const struct fileinfo *a, const struct fileinfo *b)
 
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
 
 
93
#if !defined(HAVE_READDIR_R)
 
94
  pthread_mutex_lock(&THR_LOCK_open);
 
95
#endif
 
96
 
 
97
  dirp = opendir(directory_file_name(tmp_path,(char *) path));
 
98
  if (dirp == NULL ||
 
99
      ! (buffer= (char *) malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
 
100
                                 ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
 
101
                                 sizeof(MEM_ROOT))))
 
102
    goto error;
 
103
 
 
104
  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
 
105
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
 
106
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
 
107
 
 
108
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
 
109
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
 
110
  {
 
111
    free((unsigned char*) buffer);
 
112
    goto error;
 
113
  }
 
114
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
 
115
 
 
116
  /* MY_DIR structure is allocated and completly initialized at this point */
 
117
  result= (MY_DIR*)buffer;
 
118
 
 
119
  tmp_file= strchr(tmp_path, '\0');
 
120
 
 
121
  dp= (struct dirent*) dirent_tmp;
 
122
 
 
123
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
 
124
  {
 
125
    if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
 
126
      goto error;
 
127
 
 
128
    if (MyFlags & MY_WANT_STAT)
 
129
    {
 
130
      if (!(finfo.mystat= (struct stat*)alloc_root(names_storage,
 
131
                                               sizeof(struct stat))))
 
132
        goto error;
 
133
 
 
134
      memset(finfo.mystat, 0, sizeof(struct stat));
 
135
      strcpy(tmp_file,dp->d_name);
 
136
      stat(tmp_path, finfo.mystat);
 
137
      if (!(finfo.mystat->st_mode & S_IREAD))
 
138
        continue;
 
139
    }
 
140
    else
 
141
      finfo.mystat= NULL;
 
142
 
 
143
    if (push_dynamic(dir_entries_storage, (unsigned char*)&finfo))
 
144
      goto error;
 
145
  }
 
146
 
 
147
  (void) closedir(dirp);
 
148
#if !defined(HAVE_READDIR_R)
 
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;
 
153
 
 
154
  if (!(MyFlags & MY_DONT_SORT))
 
155
    my_qsort((void *) result->dir_entry, result->number_off_files,
 
156
          sizeof(FILEINFO), (qsort_cmp) comp_names);
 
157
  return(result);
 
158
 
 
159
 error:
 
160
#if !defined(HAVE_READDIR_R)
 
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);
 
169
  return((MY_DIR *) NULL);
 
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 */
 
191
  end= strcpy(dst, src)+strlen(src);
 
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