~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/local_infile.c

pandora-build v0.71. Added check for avahi.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2004 DRIZZLE 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.
6
 
 
7
 
   There are special exceptions to the terms and conditions of the GPL as it
8
 
   is applied to this software. View the full text of the exception in file
9
 
   EXCEPTIONS-CLIENT in the directory of this software distribution.
10
 
 
11
 
   This program is distributed in the hope that it will be useful,
12
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
   GNU General Public License for more details.
15
 
 
16
 
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, write to the Free Software
18
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19
 
 
20
 
 
21
 
#include <drizzled/global.h>
22
 
#include "my_time.h"
23
 
#include "drizzle.h"
24
 
#include "errmsg.h"
25
 
#include <vio/violite.h>
26
 
#include <sys/stat.h>
27
 
#include <signal.h>
28
 
#include <time.h>
29
 
#ifdef   HAVE_PWD_H
30
 
#include <pwd.h>
31
 
#endif
32
 
 
33
 
#include <sys/socket.h>
34
 
#include <netinet/in.h>
35
 
#include <arpa/inet.h>
36
 
#include <netdb.h>
37
 
#ifdef HAVE_SELECT_H
38
 
#include <select.h>
39
 
#endif
40
 
#ifdef HAVE_SYS_SELECT_H
41
 
#include <sys/select.h>
42
 
#endif
43
 
 
44
 
#ifdef HAVE_POLL
45
 
#include <sys/poll.h>
46
 
#endif
47
 
#ifdef HAVE_SYS_UN_H
48
 
#include <sys/un.h>
49
 
#endif
50
 
#ifndef INADDR_NONE
51
 
#define INADDR_NONE  -1
52
 
#endif
53
 
 
54
 
#include <sql_common.h>
55
 
#include "client_settings.h"
56
 
 
57
 
 
58
 
bool handle_local_infile(DRIZZLE *drizzle, const char *net_filename)
59
 
{
60
 
  bool result= true;
61
 
  uint packet_length=MY_ALIGN(drizzle->net.max_packet-16,IO_SIZE);
62
 
  NET *net= &drizzle->net;
63
 
  int readcount;
64
 
  void *li_ptr;          /* pass state to local_infile functions */
65
 
  char *buf;    /* buffer to be filled by local_infile_read */
66
 
  struct st_drizzle_options *options= &drizzle->options;
67
 
 
68
 
  /* check that we've got valid callback functions */
69
 
  if (!(options->local_infile_init &&
70
 
  options->local_infile_read &&
71
 
  options->local_infile_end &&
72
 
  options->local_infile_error))
73
 
  {
74
 
    /* if any of the functions is invalid, set the default */
75
 
    drizzle_set_local_infile_default(drizzle);
76
 
  }
77
 
 
78
 
  /* copy filename into local memory and allocate read buffer */
79
 
  if (!(buf=malloc(packet_length)))
80
 
  {
81
 
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
82
 
    return(1);
83
 
  }
84
 
 
85
 
  /* initialize local infile (open file, usually) */
86
 
  if ((*options->local_infile_init)(&li_ptr, net_filename,
87
 
    options->local_infile_userdata))
88
 
  {
89
 
    VOID(my_net_write(net,(const uchar*) "",0)); /* Server needs one packet */
90
 
    net_flush(net);
91
 
    strcpy(net->sqlstate, unknown_sqlstate);
92
 
    net->last_errno=
93
 
      (*options->local_infile_error)(li_ptr,
94
 
                                     net->last_error,
95
 
                                     sizeof(net->last_error)-1);
96
 
    goto err;
97
 
  }
98
 
 
99
 
  /* read blocks of data from local infile callback */
100
 
  while ((readcount =
101
 
    (*options->local_infile_read)(li_ptr, buf,
102
 
          packet_length)) > 0)
103
 
  {
104
 
    if (my_net_write(net, (uchar*) buf, readcount))
105
 
    {
106
 
      goto err;
107
 
    }
108
 
  }
109
 
 
110
 
  /* Send empty packet to mark end of file */
111
 
  if (my_net_write(net, (const uchar*) "", 0) || net_flush(net))
112
 
  {
113
 
    set_drizzle_error(drizzle, CR_SERVER_LOST, unknown_sqlstate);
114
 
    goto err;
115
 
  }
116
 
 
117
 
  if (readcount < 0)
118
 
  {
119
 
    net->last_errno=
120
 
      (*options->local_infile_error)(li_ptr,
121
 
                                     net->last_error,
122
 
                                     sizeof(net->last_error)-1);
123
 
    goto err;
124
 
  }
125
 
 
126
 
  result=false;                                 /* Ok */
127
 
 
128
 
err:
129
 
  /* free up memory allocated with _init, usually */
130
 
  (*options->local_infile_end)(li_ptr);
131
 
  if(buf)
132
 
    free(buf);
133
 
  return(result);
134
 
}
135
 
 
136
 
 
137
 
/****************************************************************************
138
 
  Default handlers for LOAD LOCAL INFILE
139
 
****************************************************************************/
140
 
 
141
 
typedef struct st_default_local_infile
142
 
{
143
 
  int fd;
144
 
  int error_num;
145
 
  const char *filename;
146
 
  char error_msg[LOCAL_INFILE_ERROR_LEN];
147
 
} default_local_infile_data;
148
 
 
149
 
 
150
 
/*
151
 
  Open file for LOAD LOCAL INFILE
152
 
 
153
 
  SYNOPSIS
154
 
    default_local_infile_init()
155
 
    ptr      Store pointer to internal data here
156
 
    filename    File name to open. This may be in unix format !
157
 
 
158
 
 
159
 
  NOTES
160
 
    Even if this function returns an error, the load data interface
161
 
    guarantees that default_local_infile_end() is called.
162
 
 
163
 
  RETURN
164
 
    0  ok
165
 
    1  error
166
 
*/
167
 
 
168
 
static int default_local_infile_init(void **ptr, const char *filename,
169
 
             void *userdata __attribute__ ((unused)))
170
 
{
171
 
  default_local_infile_data *data;
172
 
  char tmp_name[FN_REFLEN];
173
 
 
174
 
  if (!(*ptr= data= ((default_local_infile_data *)
175
 
                     malloc(sizeof(default_local_infile_data)))))
176
 
    return 1; /* out of memory */
177
 
 
178
 
  data->error_msg[0]= 0;
179
 
  data->error_num=    0;
180
 
  data->filename= filename;
181
 
 
182
 
  if ((data->fd = open(tmp_name, O_RDONLY)) < 0)
183
 
  {
184
 
    data->error_num= errno;
185
 
    snprintf(data->error_msg, sizeof(data->error_msg)-1,
186
 
             _("File '%s' not found (Errcode: %d)"), tmp_name, data->error_num);
187
 
    return 1;
188
 
  }
189
 
  return 0; /* ok */
190
 
}
191
 
 
192
 
 
193
 
/*
194
 
  Read data for LOAD LOCAL INFILE
195
 
 
196
 
  SYNOPSIS
197
 
    default_local_infile_read()
198
 
    ptr      Points to handle allocated by _init
199
 
    buf      Read data here
200
 
    buf_len    Ammount of data to read
201
 
 
202
 
  RETURN
203
 
    > 0    number of bytes read
204
 
    == 0  End of data
205
 
    < 0    Error
206
 
*/
207
 
 
208
 
static int default_local_infile_read(void *ptr, char *buf, uint buf_len)
209
 
{
210
 
  int count;
211
 
  default_local_infile_data*data = (default_local_infile_data *) ptr;
212
 
 
213
 
  if ((count= (int) read(data->fd, (uchar *) buf, buf_len)) < 0)
214
 
  {
215
 
    data->error_num= 2; /* the errmsg for not entire file read */
216
 
    snprintf(data->error_msg, sizeof(data->error_msg)-1,
217
 
             _("Error reading file '%s' (Errcode: %d)"),
218
 
             data->filename, errno);
219
 
  }
220
 
  return count;
221
 
}
222
 
 
223
 
 
224
 
/*
225
 
  Read data for LOAD LOCAL INFILE
226
 
 
227
 
  SYNOPSIS
228
 
    default_local_infile_end()
229
 
    ptr      Points to handle allocated by _init
230
 
      May be NULL if _init failed!
231
 
 
232
 
  RETURN
233
 
*/
234
 
 
235
 
static void default_local_infile_end(void *ptr)
236
 
{
237
 
  default_local_infile_data *data= (default_local_infile_data *) ptr;
238
 
  if (data)          /* If not error on open */
239
 
  {
240
 
    if (data->fd >= 0)
241
 
      close(data->fd);
242
 
    free(ptr);
243
 
  }
244
 
}
245
 
 
246
 
 
247
 
/*
248
 
  Return error from LOAD LOCAL INFILE
249
 
 
250
 
  SYNOPSIS
251
 
    default_local_infile_end()
252
 
    ptr      Points to handle allocated by _init
253
 
      May be NULL if _init failed!
254
 
    error_msg    Store error text here
255
 
    error_msg_len  Max lenght of error_msg
256
 
 
257
 
  RETURN
258
 
    error message number
259
 
*/
260
 
 
261
 
static int
262
 
default_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
263
 
{
264
 
  default_local_infile_data *data = (default_local_infile_data *) ptr;
265
 
  if (data)          /* If not error on open */
266
 
  {
267
 
    strncpy(error_msg, data->error_msg, error_msg_len);
268
 
    return data->error_num;
269
 
  }
270
 
  /* This can only happen if we got error on malloc of handle */
271
 
  strcpy(error_msg, ER(CR_OUT_OF_MEMORY));
272
 
  return CR_OUT_OF_MEMORY;
273
 
}
274
 
 
275
 
 
276
 
void
277
 
drizzle_set_local_infile_handler(DRIZZLE *drizzle,
278
 
                               int (*local_infile_init)(void **, const char *,
279
 
                               void *),
280
 
                               int (*local_infile_read)(void *, char *, uint),
281
 
                               void (*local_infile_end)(void *),
282
 
                               int (*local_infile_error)(void *, char *, uint),
283
 
                               void *userdata)
284
 
{
285
 
  drizzle->options.local_infile_init=  local_infile_init;
286
 
  drizzle->options.local_infile_read=  local_infile_read;
287
 
  drizzle->options.local_infile_end=   local_infile_end;
288
 
  drizzle->options.local_infile_error= local_infile_error;
289
 
  drizzle->options.local_infile_userdata = userdata;
290
 
}
291
 
 
292
 
 
293
 
void drizzle_set_local_infile_default(DRIZZLE *drizzle)
294
 
{
295
 
  drizzle->options.local_infile_init=  default_local_infile_init;
296
 
  drizzle->options.local_infile_read=  default_local_infile_read;
297
 
  drizzle->options.local_infile_end=   default_local_infile_end;
298
 
  drizzle->options.local_infile_error= default_local_infile_error;
299
 
}