1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
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; either version 2 of the License, or
9
* (at your option) any later version.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1
/* Copyright (C) 2000 MySQL AB
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.
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.
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 */
17
HFTODO this must be hidden if we don't want client capabilities in
22
#include "libdrizzle.h"
23
#include "libdrizzle_priv.h"
24
#include <libdrizzle/errmsg.h>
20
#include <drizzled/global.h>
22
#include <drizzled/error.h>
23
#include <mysys/my_sys.h>
25
24
#include <vio/violite.h>
30
25
#include <signal.h>
32
#include <sys/socket.h>
33
27
#include <sys/poll.h>
37
30
The following handles the differences when this is linked between the
70
if (vio != 0) /* If real connection */
68
if (vio != 0) /* If real connection */
72
net->fd = vio_fd(vio); /* For perl DBI/DBD */
70
net->fd = vio_fd(vio); /* For perl DBI/DBD */
78
bool net_init_sock(NET * net, int sock, int flags)
81
Vio *vio_tmp= vio_new(sock, VIO_TYPE_TCPIP, flags);
85
if (my_net_init(net, vio_tmp))
87
/* Only delete the temporary vio if we didn't already attach it to the
90
if (vio_tmp && (net->vio != vio_tmp))
94
(void) shutdown(sock, SHUT_RDWR);
102
77
void net_end(NET *net)
104
if (net->buff != NULL)
79
my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
110
void net_close(NET *net)
112
if (net->vio != NULL)
114
vio_delete(net->vio);
119
bool net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
121
return vio_peer_addr(net->vio, buf, port, buflen);
124
void net_keepalive(NET *net, bool flag)
126
vio_keepalive(net->vio, flag);
129
int net_get_sd(NET *net)
134
bool net_should_close(NET *net)
136
return net->error || (net->vio == 0);
139
bool net_more_data(NET *net)
141
return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
144
85
/** Realloc the packet buffer. */
146
87
bool net_realloc(NET *net, size_t length)
149
90
size_t pkt_length;
151
92
if (length >= net->max_packet_size)
153
94
/* @todo: 1 and 2 codes are identical. */
155
net->last_errno= CR_NET_PACKET_TOO_LARGE;
96
net->last_errno= ER_NET_PACKET_TOO_LARGE;
158
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
99
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
160
101
We must allocate some extra bytes for the end 0 and to be able to
161
102
read big compressed blocks
163
if (!(buff= (unsigned char*) realloc((char*) net->buff, pkt_length +
164
NET_HEADER_SIZE + COMP_HEADER_SIZE)))
104
if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
105
NET_HEADER_SIZE + COMP_HEADER_SIZE,
166
108
/* @todo: 1 and 2 codes are identical. */
168
net->last_errno= CR_OUT_OF_MEMORY;
110
net->last_errno= ER_OUT_OF_RESOURCES;
169
111
/* In the server the error is reported by MY_WME flag. */
206
Remove unwanted characters from connection
207
and check if disconnected.
209
Read from socket until there is nothing more to read. Discard
212
If there is anything when to read 'net_clear' is called this
213
normally indicates an error in the protocol.
215
When connection is properly closed (for TCP it means with
216
a FIN packet), then select() considers a socket "ready to read",
217
in the sense that there's EOF to read, but read() returns 0.
219
@param net NET handler
220
@param clear_buffer if <> 0, then clear all data from comm buff
148
Remove unwanted characters from connection
149
and check if disconnected.
151
Read from socket until there is nothing more to read. Discard
154
If there is anything when to read 'net_clear' is called this
155
normally indicates an error in the protocol.
157
When connection is properly closed (for TCP it means with
158
a FIN packet), then select() considers a socket "ready to read",
159
in the sense that there's EOF to read, but read() returns 0.
161
@param net NET handler
162
@param clear_buffer if <> 0, then clear all data from comm buff
223
165
void net_clear(NET *net, bool clear_buffer)
262
204
/*****************************************************************************
263
** Write something to server/client buffer
264
*****************************************************************************/
205
** Write something to server/client buffer
206
*****************************************************************************/
267
Write a logical packet with packet header.
269
Format: Packet length (3 bytes), packet number(1 byte)
270
When compression is used a 3 byte compression length is added
273
If compression is used the original package is modified!
209
Write a logical packet with packet header.
211
Format: Packet length (3 bytes), packet number(1 byte)
212
When compression is used a 3 byte compression length is added
215
If compression is used the original package is modified!
277
my_net_write(NET *net,const unsigned char *packet,size_t len)
219
my_net_write(NET *net,const uchar *packet,size_t len)
279
unsigned char buff[NET_HEADER_SIZE];
221
uchar buff[NET_HEADER_SIZE];
280
222
if (unlikely(!net->vio)) /* nowhere to write */
289
231
const uint32_t z_size = MAX_PACKET_LENGTH;
290
232
int3store(buff, z_size);
291
buff[3]= (unsigned char) net->pkt_nr++;
233
buff[3]= (uchar) net->pkt_nr++;
292
234
if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
293
net_write_buff(net, packet, z_size))
235
net_write_buff(net, packet, z_size))
295
237
packet += z_size;
298
240
/* Write last packet */
299
241
int3store(buff,len);
300
buff[3]= (unsigned char) net->pkt_nr++;
242
buff[3]= (uchar) net->pkt_nr++;
301
243
if (net_write_buff(net, buff, NET_HEADER_SIZE))
303
return net_write_buff(net,packet,len) ? 1 : 0;
245
return test(net_write_buff(net,packet,len));
307
Send a command to the server.
309
The reason for having both header and packet is so that libdrizzle
310
can easy add a header to a special command (like prepared statements)
311
without having to re-alloc the string.
313
As the command is part of the first data packet, we have to do some data
314
juggling to put the command in there, without having to create a new
317
This function will split big packets into sub-packets if needed.
318
(Each sub packet can only be 2^24 bytes)
320
@param net NET handler
321
@param command Command in MySQL server (enum enum_server_command)
322
@param header Header to write after command
323
@param head_len Length of header
324
@param packet Query or parameter to query
325
@param len Length of packet
249
Send a command to the server.
251
The reason for having both header and packet is so that libdrizzle
252
can easy add a header to a special command (like prepared statements)
253
without having to re-alloc the string.
255
As the command is part of the first data packet, we have to do some data
256
juggling to put the command in there, without having to create a new
259
This function will split big packets into sub-packets if needed.
260
(Each sub packet can only be 2^24 bytes)
262
@param net NET handler
263
@param command Command in MySQL server (enum enum_server_command)
264
@param header Header to write after command
265
@param head_len Length of header
266
@param packet Query or parameter to query
267
@param len Length of packet
334
net_write_command(NET *net,unsigned char command,
335
const unsigned char *header, size_t head_len,
336
const unsigned char *packet, size_t len)
276
net_write_command(NET *net,uchar command,
277
const uchar *header, size_t head_len,
278
const uchar *packet, size_t len)
338
uint32_t length=len+1+head_len; /* 1 extra byte for command */
339
unsigned char buff[NET_HEADER_SIZE+1];
340
uint32_t header_size=NET_HEADER_SIZE+1;
280
uint32_t length=len+1+head_len; /* 1 extra byte for command */
281
uchar buff[NET_HEADER_SIZE+1];
282
uint header_size=NET_HEADER_SIZE+1;
342
buff[4]=command; /* For first packet */
284
buff[4]=command; /* For first packet */
344
286
if (length >= MAX_PACKET_LENGTH)
350
292
int3store(buff, MAX_PACKET_LENGTH);
351
buff[3]= (unsigned char) net->pkt_nr++;
293
buff[3]= (uchar) net->pkt_nr++;
352
294
if (net_write_buff(net, buff, header_size) ||
353
net_write_buff(net, header, head_len) ||
354
net_write_buff(net, packet, len))
295
net_write_buff(net, header, head_len) ||
296
net_write_buff(net, packet, len))
357
299
length-= MAX_PACKET_LENGTH;
358
300
len= MAX_PACKET_LENGTH;
360
302
header_size= NET_HEADER_SIZE;
361
303
} while (length >= MAX_PACKET_LENGTH);
362
len=length; /* Data left to be written */
304
len=length; /* Data left to be written */
364
306
int3store(buff,length);
365
buff[3]= (unsigned char) net->pkt_nr++;
366
return((net_write_buff(net, buff, header_size) ||
367
(head_len && net_write_buff(net, header, head_len)) ||
368
net_write_buff(net, packet, len) || net_flush(net)) ? 1 : 0 );
307
buff[3]= (uchar) net->pkt_nr++;
308
return(test(net_write_buff(net, buff, header_size) ||
309
(head_len && net_write_buff(net, header, head_len)) ||
310
net_write_buff(net, packet, len) || net_flush(net)));
372
Caching the data in a local buffer before sending it.
314
Caching the data in a local buffer before sending it.
374
316
Fill up net->buffer and send it to the client when full.
376
If the rest of the to-be-sent-packet is bigger than buffer,
377
send it in one big block (to avoid copying to internal buffer).
378
If not, copy the rest of the data to the buffer and return without
381
@param net Network handler
382
@param packet Packet to send
383
@param len Length of packet
386
The cached buffer can be sent as it is with 'net_flush()'.
387
In this code we have to be careful to not send a packet longer than
388
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
389
protocol as we store the length of the compressed packet in 3 bytes.
318
If the rest of the to-be-sent-packet is bigger than buffer,
319
send it in one big block (to avoid copying to internal buffer).
320
If not, copy the rest of the data to the buffer and return without
323
@param net Network handler
324
@param packet Packet to send
325
@param len Length of packet
328
The cached buffer can be sent as it is with 'net_flush()'.
329
In this code we have to be careful to not send a packet longer than
330
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
331
protocol as we store the length of the compressed packet in 3 bytes.
454
396
in the server, yield to another process and come back later.
457
net_real_write(NET *net,const unsigned char *packet, size_t len)
399
net_real_write(NET *net,const uchar *packet, size_t len)
460
const unsigned char *pos,*end;
461
uint32_t retry_count= 0;
402
const uchar *pos,*end;
463
405
/* Backup of the original SO_RCVTIMEO timeout */
465
struct timespec backtime;
406
struct timeval backtime;
469
409
if (net->error == 2)
470
return(-1); /* socket can't be used */
410
return(-1); /* socket can't be used */
472
412
net->reading_or_writing=2;
473
413
if (net->compress)
477
const uint32_t header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
478
if (!(b= (unsigned char*) malloc(len + NET_HEADER_SIZE +
417
const uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
418
if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
419
COMP_HEADER_SIZE, MYF(MY_WME))))
482
net->last_errno= CR_OUT_OF_MEMORY;
422
net->last_errno= ER_OUT_OF_RESOURCES;
483
423
/* In the server, the error is reported by MY_WME flag. */
484
424
net->reading_or_writing= 0;
487
427
memcpy(b+header_length,packet,len);
489
complen= len * 120 / 100 + 12;
490
unsigned char * compbuf= (unsigned char *) malloc(complen);
493
uLongf tmp_complen= complen;
494
int res= compress((Bytef*) compbuf, &tmp_complen,
495
(Bytef*) (b+header_length),
497
complen= tmp_complen;
501
if ((res != Z_OK) || (complen >= len))
505
size_t tmplen= complen;
429
if (my_compress(b+header_length, &len, &complen))
514
431
int3store(&b[NET_HEADER_SIZE],complen);
515
432
int3store(b,len);
516
b[3]=(unsigned char) (net->compress_pkt_nr++);
433
b[3]=(uchar) (net->compress_pkt_nr++);
517
434
len+= header_length;
522
438
/* Check for error, currently assert */
523
439
if (net->write_timeout)
525
struct timespec waittime;
441
struct timeval waittime;
526
442
socklen_t length;
528
444
waittime.tv_sec= net->write_timeout;
531
memset(&backtime, 0, sizeof(struct timespec));
532
length= sizeof(struct timespec);
533
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
447
memset(&backtime, 0, sizeof(struct timeval));
448
length= sizeof(struct timeval);
449
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
534
450
&backtime, &length);
537
453
perror("getsockopt");
538
454
assert(error == 0);
540
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
541
&waittime, (socklen_t)sizeof(struct timespec));
456
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
457
&waittime, (socklen_t)sizeof(struct timeval));
542
458
assert(error == 0);
548
462
/* Loop until we have read everything */
576
490
if (retry_count++ < net->retry_count)
580
if (vio_errno(net->vio) == EINTR)
494
if (vio_errno(net->vio) == SOCKET_EINTR)
584
net->error= 2; /* Close socket */
585
net->last_errno= (interrupted ? CR_NET_WRITE_INTERRUPTED :
586
CR_NET_ERROR_ON_WRITE);
498
net->error= 2; /* Close socket */
499
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
500
ER_NET_ERROR_ON_WRITE);
504
update_statistics(thd_increment_bytes_sent(length));
592
if ((net->compress) && (packet != NULL))
593
free((char*) packet);
508
my_free((char*) packet,MYF(0));
594
509
net->reading_or_writing=0;
597
511
if (net->write_timeout)
598
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
599
&backtime, (socklen_t)sizeof(struct timespec));
512
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
513
&backtime, (socklen_t)sizeof(struct timeval));
602
515
return(((int) (pos != end)));
607
Reads one packet to net->buff + net->where_b.
608
Long packets are handled by my_net_read().
609
This function reallocates the net->buff buffer if necessary.
520
Reads one packet to net->buff + net->where_b.
521
Long packets are handled by my_net_read().
522
This function reallocates the net->buff buffer if necessary.
612
Returns length of packet.
525
Returns length of packet.
616
529
my_real_read(NET *net, size_t *complen)
620
uint32_t i,retry_count=0;
533
uint i,retry_count=0;
621
534
uint32_t len=packet_error;
622
535
uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
626
537
/* Backup of the original SO_RCVTIMEO timeout */
627
struct timespec backtime;
538
struct timeval backtime;
633
543
net->reading_or_writing= 1;
634
544
/* Read timeout is set in my_net_set_read_timeout */
636
pos = net->buff + net->where_b; /* net->packet -4 */
546
pos = net->buff + net->where_b; /* net->packet -4 */
640
549
/* Check for error, currently assert */
641
550
if (net->read_timeout)
643
struct timespec waittime;
552
struct timeval waittime;
644
553
socklen_t length;
646
555
waittime.tv_sec= net->read_timeout;
649
memset(&backtime, 0, sizeof(struct timespec));
650
length= sizeof(struct timespec);
651
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
558
memset(&backtime, 0, sizeof(struct timeval));
559
length= sizeof(struct timeval);
560
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
652
561
&backtime, &length);
655
564
perror("getsockopt");
656
565
assert(error == 0);
658
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
659
&waittime, (socklen_t)sizeof(struct timespec));
567
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
568
&waittime, (socklen_t)sizeof(struct timeval));
660
569
assert(error == 0);
664
572
for (i= 0; i < 2 ; i++)
671
579
const bool interrupted = vio_should_retry(net->vio);
674
{ /* Probably in MIT threads */
582
{ /* Probably in MIT threads */
675
583
if (retry_count++ < net->retry_count)
678
if (vio_errno(net->vio) == EINTR)
586
if (vio_errno(net->vio) == SOCKET_EINTR)
682
590
len= packet_error;
683
net->error= 2; /* Close socket */
591
net->error= 2; /* Close socket */
684
592
net->last_errno= (vio_was_interrupted(net->vio) ?
685
CR_NET_READ_INTERRUPTED :
593
ER_NET_READ_INTERRUPTED :
595
my_error(net->last_errno, MYF(0));
690
598
remain -= (uint32_t) length;
600
update_statistics(thd_increment_bytes_received(length));
694
{ /* First parts is packet length */
603
{ /* First parts is packet length */
695
604
uint32_t helping;
697
if (net->buff[net->where_b + 3] != (unsigned char) net->pkt_nr)
606
if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
699
608
len= packet_error;
700
609
/* Not a NET error on the client. XXX: why? */
745
Read a packet from the client/server and return it without the internal
748
If the packet is the first packet of a multi-packet packet
749
(which is indicated by the length of the packet = 0xffffff) then
750
all sub packets are read and concatenated.
752
If the packet was compressed, its uncompressed and the length of the
753
uncompressed packet is returned.
756
The function returns the length of the found packet or packet_error.
757
net->read_pos points to the read data.
652
Read a packet from the client/server and return it without the internal
655
If the packet is the first packet of a multi-packet packet
656
(which is indicated by the length of the packet = 0xffffff) then
657
all sub packets are read and concatenated.
659
If the packet was compressed, its uncompressed and the length of the
660
uncompressed packet is returned.
663
The function returns the length of the found packet or packet_error.
664
net->read_pos points to the read data.
814
721
if (buf_length - start_of_packet >= NET_HEADER_SIZE)
816
read_length = uint3korr(net->buff+start_of_packet);
819
/* End of multi-byte packet */
820
start_of_packet += NET_HEADER_SIZE;
823
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
825
if (multi_byte_packet)
827
/* Remove packet header for second packet */
828
memmove(net->buff + first_packet_offset + start_of_packet,
829
net->buff + first_packet_offset + start_of_packet +
831
buf_length - start_of_packet);
832
start_of_packet += read_length;
833
buf_length -= NET_HEADER_SIZE;
836
start_of_packet+= read_length + NET_HEADER_SIZE;
723
read_length = uint3korr(net->buff+start_of_packet);
726
/* End of multi-byte packet */
727
start_of_packet += NET_HEADER_SIZE;
730
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
732
if (multi_byte_packet)
734
/* Remove packet header for second packet */
735
memmove(net->buff + first_packet_offset + start_of_packet,
736
net->buff + first_packet_offset + start_of_packet +
738
buf_length - start_of_packet);
739
start_of_packet += read_length;
740
buf_length -= NET_HEADER_SIZE;
743
start_of_packet+= read_length + NET_HEADER_SIZE;
838
if (read_length != MAX_PACKET_LENGTH) /* last package */
840
multi_byte_packet= 0; /* No last zero len packet */
843
multi_byte_packet= NET_HEADER_SIZE;
844
/* Move data down to read next data packet after current one */
845
if (first_packet_offset)
847
memmove(net->buff,net->buff+first_packet_offset,
848
buf_length-first_packet_offset);
849
buf_length-=first_packet_offset;
850
start_of_packet -= first_packet_offset;
851
first_packet_offset=0;
745
if (read_length != MAX_PACKET_LENGTH) /* last package */
747
multi_byte_packet= 0; /* No last zero len packet */
750
multi_byte_packet= NET_HEADER_SIZE;
751
/* Move data down to read next data packet after current one */
752
if (first_packet_offset)
754
memmove(net->buff,net->buff+first_packet_offset,
755
buf_length-first_packet_offset);
756
buf_length-=first_packet_offset;
757
start_of_packet -= first_packet_offset;
758
first_packet_offset=0;
856
763
/* Move data down to read next data packet after current one */
857
764
if (first_packet_offset)
859
memmove(net->buff,net->buff+first_packet_offset,
860
buf_length-first_packet_offset);
861
buf_length-=first_packet_offset;
862
start_of_packet -= first_packet_offset;
863
first_packet_offset=0;
766
memmove(net->buff,net->buff+first_packet_offset,
767
buf_length-first_packet_offset);
768
buf_length-=first_packet_offset;
769
start_of_packet -= first_packet_offset;
770
first_packet_offset=0;
866
773
net->where_b=buf_length;
867
774
if ((packet_len = my_real_read(net,&complen)) == packet_error)
776
if (my_uncompress(net->buff + net->where_b, packet_len,
872
unsigned char * compbuf= (unsigned char *) malloc(complen);
875
uLongf tmp_complen= complen;
876
int error= uncompress((Bytef*) compbuf, &tmp_complen,
877
(Bytef*) (net->buff + net->where_b),
879
complen= tmp_complen;
883
net->error= 2; /* caller will close socket */
884
net->last_errno= CR_NET_UNCOMPRESS_ERROR;
888
memcpy((net->buff + net->where_b), compbuf, complen);
779
net->error= 2; /* caller will close socket */
780
net->last_errno= ER_NET_UNCOMPRESS_ERROR;
783
buf_length+= complen;
897
buf_length+= complen;
899
786
net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
900
787
net->buf_length= buf_length;
901
788
net->remain_in_buf= (uint32_t) (buf_length - start_of_packet);
902
789
len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
903
790
multi_byte_packet);
904
net->save_char= net->read_pos[len]; /* Must be saved */
905
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
791
net->save_char= net->read_pos[len]; /* Must be saved */
792
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
911
void my_net_set_read_timeout(NET *net, uint32_t timeout)
798
void my_net_set_read_timeout(NET *net, uint timeout)
913
800
net->read_timeout= timeout;
916
802
vio_timeout(net->vio, 0, timeout);
922
void my_net_set_write_timeout(NET *net, uint32_t timeout)
807
void my_net_set_write_timeout(NET *net, uint timeout)
924
809
net->write_timeout= timeout;
927
811
vio_timeout(net->vio, 1, timeout);
932
Clear possible error state of struct NET
934
@param net clear the state of the argument
937
void net_clear_error(NET *net)
940
net->last_error[0]= '\0';
941
strcpy(net->sqlstate, sqlstate_get_not_error());