]> git.sur5r.net Git - openocd/blob - src/helper/fileio.c
- added manpage for OpenOCD (thanks to Uwe Hermann)
[openocd] / 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         fileio->location_private = fileio_local;
48         
49         if ((fileio->access != FILEIO_WRITE) && (fileio->access != FILEIO_READWRITE))
50         {
51                 if (stat(fileio->url, &fileio_local->file_stat) == -1)
52                 {
53                         free(fileio_local);
54                         snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING,
55                                 "couldn't stat() %s: %s", fileio->url, strerror(errno));
56                         return ERROR_FILEIO_NOT_FOUND;
57                 }
58         
59                 if (S_ISDIR(fileio_local->file_stat.st_mode))
60                 {
61                         free(fileio_local);
62                         snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "%s is a directory", fileio->url);
63                         return ERROR_FILEIO_NOT_FOUND;
64                 }
65         }
66         
67         switch (fileio->access)
68         {
69                 case FILEIO_READ:
70                         strcpy(access, "r");
71                         break;
72                 case FILEIO_WRITE:
73                         strcpy(access, "w");
74                         break;
75                 case FILEIO_READWRITE:
76                         strcpy(access, "w+");
77                         break;
78                 case FILEIO_APPEND:
79                         strcpy(access, "a");    
80                         break;
81                 case FILEIO_APPENDREAD:
82                         strcpy(access, "a+");   
83                         break;
84                 default:
85                         free(fileio_local);
86                         ERROR("BUG: access neither read, write nor readwrite");
87                         return ERROR_INVALID_ARGUMENTS;
88         }
89         
90         if (fileio->access == FILEIO_READ)
91         {
92                 if (fileio_local->file_stat.st_size == 0)
93                 {
94                         /* tried to open an empty file for reading */
95                         free(fileio_local);
96                         snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "empty file %s", fileio->url);
97                         return ERROR_FILEIO_OPERATION_FAILED;
98                 }
99         }
100         
101         if (fileio->type == FILEIO_BINARY)
102                 strcat(access, "b");
103         
104         if (!(fileio_local->file = fopen(fileio->url, access)))
105         {
106                 free(fileio_local);
107                 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't open %s", fileio->url);
108                 return ERROR_FILEIO_OPERATION_FAILED;
109         }
110         
111         if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE))
112         {
113                 fileio->size = fileio_local->file_stat.st_size;
114         }
115         else
116         {
117                 fileio->size = 0x0;
118         }
119         
120         return ERROR_OK;
121 }
122
123 int fileio_open(fileio_t *fileio, char *url, enum fileio_access access, enum fileio_type type)
124 {
125         int retval = ERROR_OK;
126         char *resource_identifier = NULL;
127
128         /* try to identify file location */
129         if ((resource_identifier = strstr(url, "bootp://")) && (resource_identifier == url))
130         {
131                 ERROR("bootp resource location isn't supported yet");
132                 return ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN;
133         }
134         else if ((resource_identifier = strstr(url, "tftp://")) && (resource_identifier == url))
135         {
136                 ERROR("tftp resource location isn't supported yet");
137                 return ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN;
138         }
139         else
140         {
141                 /* default to local files */
142                 fileio->location = FILEIO_LOCAL;
143         }
144         
145         fileio->type = type;
146         fileio->access = access;
147         fileio->url = strdup(url);
148         
149         switch (fileio->location)
150         {
151                 case FILEIO_LOCAL:
152                         retval = fileio_open_local(fileio);
153                         break;
154                 default:
155                         ERROR("BUG: should never get here");
156                         exit(-1);
157         }
158         
159         if (retval != ERROR_OK)
160                 return retval;
161         
162         return ERROR_OK;
163 }
164
165 int fileio_close_local(fileio_t *fileio)
166 {
167         int retval;
168         fileio_local_t *fileio_local = fileio->location_private;
169         
170         if ((retval = fclose(fileio_local->file)) != 0)
171         {
172                 if (retval == EBADF)
173                 {
174                         snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "BUG: fileio_local->file not a valid file descriptor");
175                 }
176                 else
177                 {
178                         snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't close %s: %s", fileio->url, strerror(errno));
179                 }
180
181                 return ERROR_FILEIO_OPERATION_FAILED;
182         }
183         
184         free(fileio->location_private);
185         
186         return ERROR_OK;
187 }
188
189 int fileio_close(fileio_t *fileio)
190 {
191         int retval;
192         
193         switch (fileio->location)
194         {
195                 case FILEIO_LOCAL:
196                         retval = fileio_close_local(fileio);
197                         break;
198                 default:
199                         ERROR("BUG: should never get here");
200                         retval = ERROR_FILEIO_OPERATION_FAILED;
201         }
202         
203         if (retval != ERROR_OK)
204                 return retval;
205         
206         free(fileio->url);
207         
208         return ERROR_OK;
209 }
210
211 int fileio_seek_local(fileio_t *fileio, u32 position)
212 {
213         int retval;
214         fileio_local_t *fileio_local = fileio->location_private;
215         
216         if ((retval = fseek(fileio_local->file, position, SEEK_SET)) != 0)
217         {
218                 snprintf(fileio->error_str, FILEIO_MAX_ERROR_STRING, "couldn't seek file %s: %s", fileio->url, strerror(errno));
219                 return ERROR_FILEIO_OPERATION_FAILED;
220         }
221         
222         return ERROR_OK;
223 }
224
225 int fileio_seek(fileio_t *fileio, u32 position)
226 {
227         switch (fileio->location)
228         {
229                 case FILEIO_LOCAL:
230                         return fileio_seek_local(fileio, position);
231                         break;
232                 default:
233                         ERROR("BUG: should never get here");
234         }
235         
236         return ERROR_OK;
237 }
238
239 int fileio_local_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
240 {
241         fileio_local_t *fileio_local = fileio->location_private;
242         
243         *size_read = fread(buffer, 1, size, fileio_local->file);
244         
245         return ERROR_OK;
246 }
247
248 int fileio_read(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_read)
249 {
250         switch (fileio->location)
251         {
252                 case FILEIO_LOCAL:
253                         return fileio_local_read(fileio, size, buffer, size_read);
254                         break;
255                 default:
256                         ERROR("BUG: should never get here");
257                         exit(-1);
258         }
259 }
260
261 int fileio_read_u32(fileio_t *fileio, u32 *data)
262 {
263         u8 buf[4];
264         u32 size_read;
265         int retval;
266         
267         switch (fileio->location)
268         {
269                 case FILEIO_LOCAL:
270                         if ((retval = fileio_local_read(fileio, 4, buf, &size_read)) != ERROR_OK)
271                                 return retval;
272                         *data = be_to_h_u32(buf);
273                         break;
274                 default:
275                         ERROR("BUG: should never get here");
276                         exit(-1);
277         }
278         
279         return ERROR_OK;
280 }
281
282 int fileio_local_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
283 {
284         fileio_local_t *fileio_local = fileio->location_private;
285         
286         *size_written = fwrite(buffer, 1, size, fileio_local->file);
287         
288         return ERROR_OK;
289 }
290
291 int fileio_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written)
292 {
293         switch (fileio->location)
294         {
295                 case FILEIO_LOCAL:
296                         return fileio_local_write(fileio, size, buffer, size_written);
297                         break;
298                 default:
299                         ERROR("BUG: should never get here");
300         }
301         
302         return ERROR_OK;
303 }
304
305 int fileio_write_u32(fileio_t *fileio, u32 data)
306 {
307         u8 buf[4];
308         u32 size_written;
309         int retval;
310         
311         h_u32_to_be(buf, data);
312         
313         switch (fileio->location)
314         {
315                 case FILEIO_LOCAL:
316                         if ((retval = fileio_local_write(fileio, 4, buf, &size_written)) != ERROR_OK)
317                                 return retval;
318                         break;
319                 default:
320                         ERROR("BUG: should never get here");
321         }
322         
323         return ERROR_OK;
324 }