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 |
}
|