1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/* Copyright (c) 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include "mariadb.h"
#include <ctype.h>
#include <string.h>
#include "sql_bootstrap.h"
int read_bootstrap_query(char *query, int *query_length,
fgets_input_t input, fgets_fn_t fgets_fn, int *error)
{
char line_buffer[MAX_BOOTSTRAP_LINE_SIZE];
const char *line;
size_t len;
size_t query_len= 0;
int fgets_error= 0;
*error= 0;
*query_length= 0;
for ( ; ; )
{
line= (*fgets_fn)(line_buffer, sizeof(line_buffer), input, &fgets_error);
if (error)
*error= fgets_error;
if (fgets_error != 0)
return READ_BOOTSTRAP_ERROR;
if (line == NULL)
return (query_len == 0) ? READ_BOOTSTRAP_EOF : READ_BOOTSTRAP_ERROR;
len= strlen(line);
/*
Remove trailing whitespace characters.
This assumes:
- no multibyte encoded character can be found at the very end of a line,
- whitespace characters from the "C" locale only.
which is sufficient for the kind of queries found
in the bootstrap scripts.
*/
while (len && (isspace(line[len - 1])))
len--;
/*
Cleanly end the string, so we don't have to test len > x
all the time before reading line[x], in the code below.
*/
line_buffer[len]= '\0';
/* Skip blank lines */
if (len == 0)
continue;
/* Skip # comments */
if (line[0] == '#')
continue;
/* Skip -- comments */
if ((line[0] == '-') && (line[1] == '-'))
continue;
/* Skip delimiter, ignored. */
if (strncmp(line, "delimiter", 9) == 0)
continue;
/* Append the current line to a multi line query. If the new line will make
the query too long, preserve the partial line to provide context for the
error message.
*/
if (query_len + len + 1 >= MAX_BOOTSTRAP_QUERY_SIZE)
{
size_t new_len= MAX_BOOTSTRAP_QUERY_SIZE - query_len - 1;
if ((new_len > 0) && (query_len < MAX_BOOTSTRAP_QUERY_SIZE))
{
memcpy(query + query_len, line, new_len);
query_len+= new_len;
}
query[query_len]= '\0';
*query_length= (int)query_len;
return READ_BOOTSTRAP_QUERY_SIZE;
}
if (query_len != 0)
{
/*
Append a \n to the current line, if any,
to preserve the intended presentation.
*/
query[query_len++]= '\n';
}
memcpy(query + query_len, line, len);
query_len+= len;
if (line[len - 1] == ';')
{
/*
The last line is terminated by ';'.
Return the query found.
*/
query[query_len]= '\0';
*query_length= (int)query_len;
return READ_BOOTSTRAP_SUCCESS;
}
}
}
|