- removed flash write_image - binary compare function has been moved to verify_image...
[openocd.git] / src / helper / fileio.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
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 *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "types.h"
25 #include "replacements.h"
26 #include "log.h"
27
28 #include "fileio.h"
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <errno.h>
37 #include <ctype.h>
38
39 int fileio_close(fileio_t *fileio);
40 int fileio_dispatch_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read);
41
42 int fileio_open_local(fileio_t *fileio)
43 {
44 fileio_local_t *fileio_local = malloc(sizeof(fileio_local_t));
45 char access[4];
46
47 switch (fileio->access)
48 {
49 case FILEIO_READ:
50 strcpy(access, "r");
51 break;
52 case FILEIO_WRITE:
53 strcpy(access, "w");
54 break;
55 case FILEIO_READWRITE:
56 strcpy(access, "w+");
57 break;
58 case FILEIO_APPEND:
59 strcpy(access, "a");
60 break;
61 case FILEIO_APPENDREAD:
62 strcpy(access, "a+");
63 break;
64 default:
65 free(fileio_local);
66 ERROR("BUG: access neither read, write nor readwrite");
67 return ERROR_INVALID_ARGUMENTS;
68 }
69
70 /* win32 always opens in binary mode */
71 #ifndef _WIN32
72 if (fileio->type == FILEIO_BINARY)
73 #endif
74 {
75 strcat(access, "b");
76 }
77
78 if (!(fileio_local->file = fopen(fileio->url, access)))
79 {
80 free(fileio_local);
81 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't open %s", fileio->url);
82 return ERROR_FILEIO_OPERATION_FAILED;
83 }
84
85 if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE))
86 {
87 /* NB! Here we use fseek() instead of stat(), since stat is a
88 * more advanced operation that might not apply to e.g. a disk path
89 * that refers to e.g. a tftp client */
90 int result, result2;
91
92 result = fseek(fileio_local->file, 0, SEEK_END);
93
94 fileio->size = ftell(fileio_local->file);
95
96 result2 = fseek(fileio_local->file, 0, SEEK_SET);
97
98 if ((fileio->size < 0) || (result < 0) || (result2 < 0))
99 {
100 fileio_close(fileio);
101 return ERROR_FILEIO_OPERATION_FAILED;
102 }
103 }
104 else
105 {
106 fileio->size = 0x0;
107 }
108
109 fileio->location_private = fileio_local;
110
111 return ERROR_OK;
112 }
113
114 int fileio_open(fileio_t *fileio, char *url, enum fileio_access access, enum fileio_type type)
115 {
116 int retval = ERROR_OK;
117 char *resource_identifier = NULL;
118
119 /* try to identify file location. We only hijack the file paths we understand, the rest is
120 * passed on to the OS which might implement e.g. tftp via a mounted tftp device.
121 */
122 if ((resource_identifier = strstr(url, "bootp://")) && (resource_identifier == url))
123 {
124 ERROR("bootp resource location isn't supported yet");
125 return ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN;
126 }
127 else
128 {
129 /* default to local files */
130 fileio->location = FILEIO_LOCAL;
131 }
132
133 fileio->type = type;
134 fileio->access = access;
135 fileio->url = strdup(url);
136
137 switch (fileio->location)
138 {
139 case FILEIO_LOCAL:
140 retval = fileio_open_local(fileio);
141 break;
142 default:
143 ERROR("BUG: should never get here");
144 exit(-1);
145 }
146
147 if (retval != ERROR_OK)
148 return retval;
149
150 return ERROR_OK;
151 }
152
153 int fileio_close_local(fileio_t *fileio)
154 {
155 int retval;
156 fileio_local_t *fileio_local = fileio->location_private;
157
158 if (fileio->location_private == NULL)
159 {
160 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't close %s: ", fileio->url);
161 return ERROR_FILEIO_OPERATION_FAILED;
162 }
163
164 if ((retval = fclose(fileio_local->file)) != 0)
165 {
166 if (retval == EBADF)
167 {
168 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "BUG: fileio_local->file not a valid file descriptor");
169 }
170 else
171 {
172 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't close %s: %s", fileio->url, strerror(errno));
173 }
174
175 return ERROR_FILEIO_OPERATION_FAILED;
176 }
177
178 free(fileio->location_private);
179 fileio->location_private = NULL;
180
181 return ERROR_OK;
182 }
183
184 int fileio_close(fileio_t *fileio)
185 {
186 int retval;
187
188 switch (fileio->location)
189 {
190 case FILEIO_LOCAL:
191 retval = fileio_close_local(fileio);
192 break;
193 default:
194 ERROR("BUG: should never get here");
195 retval = ERROR_FILEIO_OPERATION_FAILED;
196 }
197
198 if (retval != ERROR_OK)
199 return retval;
200
201 free(fileio->url);
202 fileio->url = NULL;
203
204 return ERROR_OK;
205 }
206
207 int fileio_seek_local(fileio_t *fileio, u32 position)
208 {
209 int retval;
210 fileio_local_t *fileio_local = fileio->location_private;
211
212 if ((retval = fseek(fileio_local->file, position, SEEK_SET)) != 0)
213 {
214 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't seek file %s: %s", fileio->url, strerror(errno));
215 return ERROR_FILEIO_OPERATION_FAILED;
216 }
217
218 return ERROR_OK;
219 }
220
221 int fileio_seek(fileio_t *fileio, u32 position)
222 {
223 switch (fileio->location)
224 {
225 case FILEIO_LOCAL:
226 return fileio_seek_local(fileio, position);
227 break;
228 default:
229 ERROR("BUG: should never get here");
230 }
231
232 return ERROR_OK;
233 }
234
235 int fileio_local_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
236 {
237 fileio_local_t *fileio_local = fileio->location_private;
238
239 *size_read = fread(buffer, 1, size, fileio_local->file);
240
241 return ERROR_OK;
242 }
243
244 int fileio_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
245 {
246 switch (fileio->location)
247 {
248 case FILEIO_LOCAL:
249 return fileio_local_read(fileio, size, buffer, size_read);
250 break;
251 default:
252 ERROR("BUG: should never get here");
253 exit(-1);
254 }
255 }
256
257 int fileio_read_u32(fileio_t *fileio, u32 *data)
258 {
259 u8 buf[4];
260 u32 size_read;
261 int retval;
262
263 switch (fileio->location)
264 {
265 case FILEIO_LOCAL:
266 if ((retval = fileio_local_read(fileio, 4, buf, &size_read)) != ERROR_OK)
267 return retval;
268 *data = be_to_h_u32(buf);
269 break;
270 default:
271 ERROR("BUG: should never get here");
272 exit(-1);
273 }
274
275 return ERROR_OK;
276 }
277
278 int fileio_local_fgets(fileio_t *fileio, u32 size, u8 *buffer)
279 {
280 fileio_local_t *fileio_local = fileio->location_private;
281
282 if( fgets(buffer, size, fileio_local->file) == NULL)
283 return ERROR_FILEIO_OPERATION_FAILED;
284
285 return ERROR_OK;
286 }
287
288 int fileio_fgets(fileio_t *fileio, u32 size, u8 *buffer)
289 {
290 switch (fileio->location)
291 {
292 case FILEIO_LOCAL:
293 return fileio_local_fgets(fileio, size, buffer);
294 break;
295 default:
296 ERROR("BUG: should never get here");
297 exit(-1);
298 }
299 }
300
301 int fileio_local_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
302 {
303 fileio_local_t *fileio_local = fileio->location_private;
304
305 *size_written = fwrite(buffer, 1, size, fileio_local->file);
306
307 return ERROR_OK;
308 }
309
310 int fileio_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
311 {
312 int retval;
313
314 switch (fileio->location)
315 {
316 case FILEIO_LOCAL:
317 retval = fileio_local_write(fileio, size, buffer, size_written);
318 break;
319 default:
320 ERROR("BUG: should never get here");
321 exit(-1);
322 }
323
324 if (retval == ERROR_OK)
325 fileio->size += *size_written;
326
327 return retval;;
328 }
329
330 int fileio_write_u32(fileio_t *fileio, u32 data)
331 {
332 u8 buf[4];
333 u32 size_written;
334 int retval;
335
336 h_u32_to_be(buf, data);
337
338 switch (fileio->location)
339 {
340 case FILEIO_LOCAL:
341 if ((retval = fileio_local_write(fileio, 4, buf, &size_written)) != ERROR_OK)
342 return retval;
343 break;
344 default:
345 ERROR("BUG: should never get here");
346 }
347
348 return ERROR_OK;
349 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)