1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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. *
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. *
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 ***************************************************************************/
25 #include "replacements.h"
34 #include <sys/types.h>
39 int fileio_close(fileio_t *fileio);
40 int fileio_dispatch_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read);
42 int fileio_open_local(fileio_t *fileio)
44 fileio_local_t *fileio_local = malloc(sizeof(fileio_local_t));
47 switch (fileio->access)
55 case FILEIO_READWRITE:
61 case FILEIO_APPENDREAD:
66 ERROR("BUG: access neither read, write nor readwrite");
67 return ERROR_INVALID_ARGUMENTS;
70 /* win32 always opens in binary mode */
72 if (fileio->type == FILEIO_BINARY)
78 if (!(fileio_local->file = fopen(fileio->url, access)))
81 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't open %s", fileio->url);
82 return ERROR_FILEIO_OPERATION_FAILED;
85 if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE))
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 */
92 result = fseek(fileio_local->file, 0, SEEK_END);
94 fileio->size = ftell(fileio_local->file);
96 result2 = fseek(fileio_local->file, 0, SEEK_SET);
98 if ((fileio->size < 0) || (result < 0) || (result2 < 0))
100 fileio_close(fileio);
101 return ERROR_FILEIO_OPERATION_FAILED;
109 fileio->location_private = fileio_local;
114 int fileio_open(fileio_t *fileio, char *url, enum fileio_access access, enum fileio_type type)
116 int retval = ERROR_OK;
117 char *resource_identifier = NULL;
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.
122 if ((resource_identifier = strstr(url, "bootp://")) && (resource_identifier == url))
124 ERROR("bootp resource location isn't supported yet");
125 return ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN;
129 /* default to local files */
130 fileio->location = FILEIO_LOCAL;
134 fileio->access = access;
135 fileio->url = strdup(url);
137 switch (fileio->location)
140 retval = fileio_open_local(fileio);
143 ERROR("BUG: should never get here");
147 if (retval != ERROR_OK)
153 int fileio_close_local(fileio_t *fileio)
156 fileio_local_t *fileio_local = fileio->location_private;
158 if (fileio->location_private == NULL)
160 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't close %s: ", fileio->url);
161 return ERROR_FILEIO_OPERATION_FAILED;
164 if ((retval = fclose(fileio_local->file)) != 0)
168 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "BUG: fileio_local->file not a valid file descriptor");
172 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't close %s: %s", fileio->url, strerror(errno));
175 return ERROR_FILEIO_OPERATION_FAILED;
178 free(fileio->location_private);
179 fileio->location_private = NULL;
184 int fileio_close(fileio_t *fileio)
188 switch (fileio->location)
191 retval = fileio_close_local(fileio);
194 ERROR("BUG: should never get here");
195 retval = ERROR_FILEIO_OPERATION_FAILED;
198 if (retval != ERROR_OK)
207 int fileio_seek_local(fileio_t *fileio, u32 position)
210 fileio_local_t *fileio_local = fileio->location_private;
212 if ((retval = fseek(fileio_local->file, position, SEEK_SET)) != 0)
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;
221 int fileio_seek(fileio_t *fileio, u32 position)
223 switch (fileio->location)
226 return fileio_seek_local(fileio, position);
229 ERROR("BUG: should never get here");
235 int fileio_local_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
237 fileio_local_t *fileio_local = fileio->location_private;
239 *size_read = fread(buffer, 1, size, fileio_local->file);
244 int fileio_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
246 switch (fileio->location)
249 return fileio_local_read(fileio, size, buffer, size_read);
252 ERROR("BUG: should never get here");
257 int fileio_read_u32(fileio_t *fileio, u32 *data)
263 switch (fileio->location)
266 if ((retval = fileio_local_read(fileio, 4, buf, &size_read)) != ERROR_OK)
268 *data = be_to_h_u32(buf);
271 ERROR("BUG: should never get here");
278 int fileio_local_fgets(fileio_t *fileio, u32 size, u8 *buffer)
280 fileio_local_t *fileio_local = fileio->location_private;
282 if( fgets(buffer, size, fileio_local->file) == NULL)
283 return ERROR_FILEIO_OPERATION_FAILED;
288 int fileio_fgets(fileio_t *fileio, u32 size, u8 *buffer)
290 switch (fileio->location)
293 return fileio_local_fgets(fileio, size, buffer);
296 ERROR("BUG: should never get here");
301 int fileio_local_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
303 fileio_local_t *fileio_local = fileio->location_private;
305 *size_written = fwrite(buffer, 1, size, fileio_local->file);
310 int fileio_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
314 switch (fileio->location)
317 retval = fileio_local_write(fileio, size, buffer, size_written);
320 ERROR("BUG: should never get here");
324 if (retval == ERROR_OK)
325 fileio->size += *size_written;
330 int fileio_write_u32(fileio_t *fileio, u32 data)
336 h_u32_to_be(buf, data);
338 switch (fileio->location)
341 if ((retval = fileio_local_write(fileio, 4, buf, &size_written)) != ERROR_OK)
345 ERROR("BUG: should never get here");