1 | /* |
2 | Copyright (C) 2015 MariaDB Corporation AB |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public |
15 | License along with this library; if not, write to the Free |
16 | Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
17 | MA 02111-1301, USA |
18 | */ |
19 | |
20 | #include <ma_global.h> |
21 | #include <ma_sys.h> |
22 | #include <errmsg.h> |
23 | #include <mysql.h> |
24 | #include <mysql/client_plugin.h> |
25 | #include <mariadb/ma_io.h> |
26 | #include <stdio.h> |
27 | #include <string.h> |
28 | |
29 | #ifdef HAVE_REMOTEIO |
30 | struct st_mysql_client_plugin_REMOTEIO *rio_plugin= NULL; |
31 | #endif |
32 | |
33 | /* {{{ ma_open */ |
34 | MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql) |
35 | { |
36 | int CodePage= -1; |
37 | FILE *fp= NULL; |
38 | MA_FILE *ma_file= NULL; |
39 | |
40 | if (!location || !location[0]) |
41 | return NULL; |
42 | #ifdef HAVE_REMOTEIO |
43 | if (strstr(location, "://" )) |
44 | goto remote; |
45 | #endif |
46 | |
47 | #ifdef _WIN32 |
48 | if (mysql && mysql->charset) |
49 | CodePage= madb_get_windows_cp(mysql->charset->csname); |
50 | #endif |
51 | if (CodePage == -1) |
52 | { |
53 | if (!(fp= fopen(location, mode))) |
54 | { |
55 | return NULL; |
56 | } |
57 | } |
58 | #ifdef _WIN32 |
59 | /* See CONC-44: we need to support non ascii filenames too, so we convert |
60 | current character set to wchar_t and try to open the file via _wsopen */ |
61 | else |
62 | { |
63 | wchar_t *w_filename= NULL; |
64 | wchar_t *w_mode= NULL; |
65 | int len; |
66 | DWORD Length; |
67 | |
68 | len= MultiByteToWideChar(CodePage, 0, location, (int)strlen(location), NULL, 0); |
69 | if (!len) |
70 | return NULL; |
71 | if (!(w_filename= (wchar_t *)calloc(1, (len + 1) * sizeof(wchar_t)))) |
72 | { |
73 | my_set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); |
74 | return NULL; |
75 | } |
76 | Length= len; |
77 | len= MultiByteToWideChar(CodePage, 0, location, (int)strlen(location), w_filename, (int)Length); |
78 | if (!len) |
79 | { |
80 | /* todo: error handling */ |
81 | free(w_filename); |
82 | return NULL; |
83 | } |
84 | len= (int)strlen(mode); |
85 | if (!(w_mode= (wchar_t *)calloc(1, (len + 1) * sizeof(wchar_t)))) |
86 | { |
87 | my_set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); |
88 | free(w_filename); |
89 | return NULL; |
90 | } |
91 | Length= len; |
92 | len= MultiByteToWideChar(CodePage, 0, mode, (int)strlen(mode), w_mode, (int)Length); |
93 | if (!len) |
94 | { |
95 | /* todo: error handling */ |
96 | free(w_filename); |
97 | free(w_mode); |
98 | return NULL; |
99 | } |
100 | fp= _wfopen(w_filename, w_mode); |
101 | free(w_filename); |
102 | free(w_mode); |
103 | } |
104 | |
105 | #endif |
106 | if (fp) |
107 | { |
108 | ma_file= (MA_FILE *)malloc(sizeof(MA_FILE)); |
109 | if (!ma_file) |
110 | { |
111 | my_set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); |
112 | return NULL; |
113 | } |
114 | ma_file->type= MA_FILE_LOCAL; |
115 | ma_file->ptr= (void *)fp; |
116 | } |
117 | return ma_file; |
118 | #ifdef HAVE_REMOTEIO |
119 | remote: |
120 | /* check if plugin for remote io is available and try |
121 | * to open location */ |
122 | { |
123 | MYSQL mysql; |
124 | if (rio_plugin ||(rio_plugin= (struct st_mysql_client_plugin_REMOTEIO *) |
125 | mysql_client_find_plugin(&mysql, NULL, MARIADB_CLIENT_REMOTEIO_PLUGIN))) |
126 | return rio_plugin->methods->mopen(location, mode); |
127 | return NULL; |
128 | } |
129 | #endif |
130 | } |
131 | /* }}} */ |
132 | |
133 | /* {{{ ma_close */ |
134 | int ma_close(MA_FILE *file) |
135 | { |
136 | int rc; |
137 | if (!file) |
138 | return -1; |
139 | |
140 | switch (file->type) { |
141 | case MA_FILE_LOCAL: |
142 | rc= fclose((FILE *)file->ptr); |
143 | free(file); |
144 | break; |
145 | #ifdef HAVE_REMOTEIO |
146 | case MA_FILE_REMOTE: |
147 | rc= rio_plugin->methods->mclose(file); |
148 | break; |
149 | #endif |
150 | default: |
151 | return -1; |
152 | } |
153 | return rc; |
154 | } |
155 | /* }}} */ |
156 | |
157 | |
158 | /* {{{ ma_feof */ |
159 | int ma_feof(MA_FILE *file) |
160 | { |
161 | if (!file) |
162 | return -1; |
163 | |
164 | switch (file->type) { |
165 | case MA_FILE_LOCAL: |
166 | return feof((FILE *)file->ptr); |
167 | break; |
168 | #ifdef HAVE_REMOTEIO |
169 | case MA_FILE_REMOTE: |
170 | return rio_plugin->methods->mfeof(file); |
171 | break; |
172 | #endif |
173 | default: |
174 | return -1; |
175 | } |
176 | } |
177 | /* }}} */ |
178 | |
179 | /* {{{ ma_read */ |
180 | size_t ma_read(void *ptr, size_t size, size_t nmemb, MA_FILE *file) |
181 | { |
182 | size_t s= 0; |
183 | if (!file) |
184 | return -1; |
185 | |
186 | switch (file->type) { |
187 | case MA_FILE_LOCAL: |
188 | s= fread(ptr, size, nmemb, (FILE *)file->ptr); |
189 | return s; |
190 | break; |
191 | #ifdef HAVE_REMOTEIO |
192 | case MA_FILE_REMOTE: |
193 | return rio_plugin->methods->mread(ptr, size, nmemb, file); |
194 | break; |
195 | #endif |
196 | default: |
197 | return -1; |
198 | } |
199 | } |
200 | /* }}} */ |
201 | |
202 | /* {{{ ma_gets */ |
203 | char *ma_gets(char *ptr, size_t size, MA_FILE *file) |
204 | { |
205 | if (!file) |
206 | return NULL; |
207 | |
208 | switch (file->type) { |
209 | case MA_FILE_LOCAL: |
210 | return fgets(ptr, (int)size, (FILE *)file->ptr); |
211 | break; |
212 | #ifdef HAVE_REMOTEIO |
213 | case MA_FILE_REMOTE: |
214 | return rio_plugin->methods->mgets(ptr, size, file); |
215 | break; |
216 | #endif |
217 | default: |
218 | return NULL; |
219 | } |
220 | } |
221 | /* }}} */ |
222 | |
223 | |
224 | |