~drizzle-trunk/drizzle/development

390.1.4 by Monty Taylor
More copyright header file fixes.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
19
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
20
#include <config.h>
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
21
383.1.44 by Monty Taylor
Renamed drizzle.h to libdrizzle.h.
22
#include "libdrizzle.h"
390.1.5 by Monty Taylor
Moved more functions into drizzle.c as part of the split of code.
23
#include "libdrizzle_priv.h"
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
24
#include "errmsg.h"
25
#include <sys/stat.h>
26
#include <signal.h>
27
#include <time.h>
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
28
#include <fcntl.h>
29
#include <stdio.h>
30
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
31
#ifdef   HAVE_PWD_H
32
#include <pwd.h>
33
#endif
34
35
#include <sys/socket.h>
36
#include <netinet/in.h>
37
#include <arpa/inet.h>
38
#include <netdb.h>
39
#ifdef HAVE_SELECT_H
40
#include <select.h>
41
#endif
42
#ifdef HAVE_SYS_SELECT_H
43
#include <sys/select.h>
44
#endif
45
46
#ifdef HAVE_POLL
47
#include <sys/poll.h>
48
#endif
49
#ifdef HAVE_SYS_UN_H
50
#include <sys/un.h>
51
#endif
52
#ifndef INADDR_NONE
53
#define INADDR_NONE  -1
54
#endif
55
383.1.49 by Monty Taylor
Got rid of client_settings.h
56
#include "local_infile.h"
538 by Monty Taylor
Moved gettext.h into drizzled in anticipation of the new client lib.
57
#include <drizzled/gettext.h>
383.1.49 by Monty Taylor
Got rid of client_settings.h
58
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
59
#define MY_ALIGN(A,L)	(((A) + (L) - 1) & ~((L) - 1))
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
60
61
bool handle_local_infile(DRIZZLE *drizzle, const char *net_filename)
62
{
63
  bool result= true;
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
64
  uint32_t packet_length=MY_ALIGN(drizzle->net.max_packet-16,IO_SIZE);
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
65
  NET *net= &drizzle->net;
66
  int readcount;
67
  void *li_ptr;          /* pass state to local_infile functions */
68
  char *buf;    /* buffer to be filled by local_infile_read */
69
  struct st_drizzle_options *options= &drizzle->options;
70
71
  /* check that we've got valid callback functions */
72
  if (!(options->local_infile_init &&
73
  options->local_infile_read &&
74
  options->local_infile_end &&
75
  options->local_infile_error))
76
  {
77
    /* if any of the functions is invalid, set the default */
78
    drizzle_set_local_infile_default(drizzle);
79
  }
80
81
  /* copy filename into local memory and allocate read buffer */
82
  if (!(buf=malloc(packet_length)))
83
  {
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
84
    drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
85
    return(1);
86
  }
87
88
  /* initialize local infile (open file, usually) */
89
  if ((*options->local_infile_init)(&li_ptr, net_filename,
90
    options->local_infile_userdata))
91
  {
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
92
    (void)my_net_write(net,(const unsigned char*) "",0); /* Server needs one packet */
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
93
    net_flush(net);
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
94
    strcpy(net->sqlstate, sqlstate_get_unknown());
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
95
    net->last_errno=
96
      (*options->local_infile_error)(li_ptr,
97
                                     net->last_error,
98
                                     sizeof(net->last_error)-1);
99
    goto err;
100
  }
101
102
  /* read blocks of data from local infile callback */
103
  while ((readcount =
104
    (*options->local_infile_read)(li_ptr, buf,
105
          packet_length)) > 0)
106
  {
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
107
    if (my_net_write(net, (unsigned char*) buf, readcount))
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
108
    {
109
      goto err;
110
    }
111
  }
112
113
  /* Send empty packet to mark end of file */
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
114
  if (my_net_write(net, (const unsigned char*) "", 0) || net_flush(net))
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
115
  {
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
116
    drizzle_set_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown());
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
117
    goto err;
118
  }
119
120
  if (readcount < 0)
121
  {
122
    net->last_errno=
123
      (*options->local_infile_error)(li_ptr,
124
                                     net->last_error,
125
                                     sizeof(net->last_error)-1);
126
    goto err;
127
  }
128
129
  result=false;					/* Ok */
130
131
err:
132
  /* free up memory allocated with _init, usually */
133
  (*options->local_infile_end)(li_ptr);
134
  if(buf)
135
    free(buf);
136
  return(result);
137
}
138
139
140
/****************************************************************************
141
  Default handlers for LOAD LOCAL INFILE
142
****************************************************************************/
143
144
typedef struct st_default_local_infile
145
{
146
  int fd;
147
  int error_num;
148
  const char *filename;
149
  char error_msg[LOCAL_INFILE_ERROR_LEN];
150
} default_local_infile_data;
151
152
153
/*
154
  Open file for LOAD LOCAL INFILE
155
156
  SYNOPSIS
157
    default_local_infile_init()
158
    ptr      Store pointer to internal data here
159
    filename    File name to open. This may be in unix format !
160
161
162
  NOTES
163
    Even if this function returns an error, the load data interface
164
    guarantees that default_local_infile_end() is called.
165
166
  RETURN
167
    0  ok
168
    1  error
169
*/
170
171
static int default_local_infile_init(void **ptr, const char *filename,
172
             void *userdata __attribute__ ((unused)))
173
{
174
  default_local_infile_data *data;
175
  char tmp_name[FN_REFLEN];
176
177
  if (!(*ptr= data= ((default_local_infile_data *)
178
		     malloc(sizeof(default_local_infile_data)))))
179
    return 1; /* out of memory */
180
181
  data->error_msg[0]= 0;
182
  data->error_num=    0;
183
  data->filename= filename;
184
333 by Monty Taylor
More mysys removes.
185
  if ((data->fd = open(tmp_name, O_RDONLY)) < 0)
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
186
  {
333 by Monty Taylor
More mysys removes.
187
    data->error_num= errno;
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
188
    snprintf(data->error_msg, sizeof(data->error_msg)-1,
331 by Monty Taylor
Removed more mysys errmsg links.
189
             _("File '%s' not found (Errcode: %d)"), tmp_name, data->error_num);
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
190
    return 1;
191
  }
192
  return 0; /* ok */
193
}
194
195
196
/*
197
  Read data for LOAD LOCAL INFILE
198
199
  SYNOPSIS
200
    default_local_infile_read()
201
    ptr      Points to handle allocated by _init
202
    buf      Read data here
203
    buf_len    Ammount of data to read
204
205
  RETURN
206
    > 0    number of bytes read
207
    == 0  End of data
208
    < 0    Error
209
*/
210
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
211
static int default_local_infile_read(void *ptr, char *buf, uint32_t buf_len)
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
212
{
213
  int count;
214
  default_local_infile_data*data = (default_local_infile_data *) ptr;
215
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
216
  if ((count= (int) read(data->fd, (unsigned char *) buf, buf_len)) < 0)
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
217
  {
331 by Monty Taylor
Removed more mysys errmsg links.
218
    data->error_num= 2; /* the errmsg for not entire file read */
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
219
    snprintf(data->error_msg, sizeof(data->error_msg)-1,
331 by Monty Taylor
Removed more mysys errmsg links.
220
             _("Error reading file '%s' (Errcode: %d)"),
333 by Monty Taylor
More mysys removes.
221
             data->filename, errno);
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
222
  }
223
  return count;
224
}
225
226
227
/*
228
  Read data for LOAD LOCAL INFILE
229
230
  SYNOPSIS
231
    default_local_infile_end()
232
    ptr      Points to handle allocated by _init
233
      May be NULL if _init failed!
234
235
  RETURN
236
*/
237
238
static void default_local_infile_end(void *ptr)
239
{
240
  default_local_infile_data *data= (default_local_infile_data *) ptr;
241
  if (data)          /* If not error on open */
242
  {
243
    if (data->fd >= 0)
333 by Monty Taylor
More mysys removes.
244
      close(data->fd);
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
245
    free(ptr);
246
  }
247
}
248
249
250
/*
251
  Return error from LOAD LOCAL INFILE
252
253
  SYNOPSIS
254
    default_local_infile_end()
255
    ptr      Points to handle allocated by _init
256
      May be NULL if _init failed!
257
    error_msg    Store error text here
258
    error_msg_len  Max lenght of error_msg
259
260
  RETURN
261
    error message number
262
*/
263
264
static int
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
265
default_local_infile_error(void *ptr, char *error_msg, uint32_t error_msg_len)
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
266
{
267
  default_local_infile_data *data = (default_local_infile_data *) ptr;
268
  if (data)          /* If not error on open */
269
  {
240.1.5 by Toru Maesaka
Merge with head and conflicts resolved
270
    strncpy(error_msg, data->error_msg, error_msg_len);
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
271
    return data->error_num;
272
  }
273
  /* This can only happen if we got error on malloc of handle */
240.1.5 by Toru Maesaka
Merge with head and conflicts resolved
274
  strcpy(error_msg, ER(CR_OUT_OF_MEMORY));
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
275
  return CR_OUT_OF_MEMORY;
276
}
277
278
279
void
280
drizzle_set_local_infile_handler(DRIZZLE *drizzle,
281
                               int (*local_infile_init)(void **, const char *,
282
                               void *),
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
283
                               int (*local_infile_read)(void *, char *, uint32_t),
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
284
                               void (*local_infile_end)(void *),
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
285
                               int (*local_infile_error)(void *, char *, uint32_t),
236.3.8 by Andrey Hristov
Move local infile handling to a separate file
286
                               void *userdata)
287
{
288
  drizzle->options.local_infile_init=  local_infile_init;
289
  drizzle->options.local_infile_read=  local_infile_read;
290
  drizzle->options.local_infile_end=   local_infile_end;
291
  drizzle->options.local_infile_error= local_infile_error;
292
  drizzle->options.local_infile_userdata = userdata;
293
}
294
295
296
void drizzle_set_local_infile_default(DRIZZLE *drizzle)
297
{
298
  drizzle->options.local_infile_init=  default_local_infile_init;
299
  drizzle->options.local_infile_read=  default_local_infile_read;
300
  drizzle->options.local_infile_end=   default_local_infile_end;
301
  drizzle->options.local_infile_error= default_local_infile_error;
302
}