]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/redboot/v2_0/src/fs/fileio.c
98d6576e54968bf1fbfe4115a86e6ca29056a68b
[karo-tx-redboot.git] / packages / redboot / v2_0 / src / fs / fileio.c
1 //==========================================================================
2 //
3 //      fileio.c
4 //
5 //      RedBoot fileio support
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2002, 2003, 2004 Gary Thomas
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    dwmw2, msalter
45 // Date:         2003-11-27
46 // Purpose:      
47 // Description:  
48 //              
49 // This code is part of RedBoot (tm).
50 //
51 //####DESCRIPTIONEND####
52 //
53 //==========================================================================
54
55 // Shoot me. But I don't want struct timeval because redboot provides it.
56 #define _POSIX_SOURCE
57 #include <time.h>
58 #undef _POSIX_SOURCE
59
60 #include <redboot.h>
61 #include <errno.h>
62 #include <stdio.h>
63 #include <fcntl.h>
64 #include <unistd.h>
65 #include <string.h>
66 #ifdef CYGPKG_IO_FLASH
67 #include <cyg/io/io.h>
68 #include <cyg/io/flash.h>
69 #include <cyg/io/config_keys.h>
70 #endif
71 #include <cyg/fileio/fileio.h>
72 #include <cyg/infra/cyg_ass.h>         // assertion macros
73
74 static void do_mount(int argc, char *argv[]);
75 static void do_umount(int argc, char *argv[]);
76
77 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE
78 #define FLASHPART "[-f <partition>] "
79 #else
80 #define FLASHPART
81 #endif
82
83 RedBoot_cmd("mount", 
84             "Mount file system",
85             FLASHPART "[-d <device>] -t fstype",
86             do_mount
87     );
88 RedBoot_cmd("umount", 
89             "Unmount file system",
90             "",
91             do_umount
92     );
93
94 int fileio_mounted = 0;
95
96 // Mount disk/filesystem
97 static void
98 do_mount(int argc, char *argv[])
99 {
100     char *part_str, *dev_str, *type_str;
101     bool part_set = false, dev_set = false, type_set = false;
102     struct option_info opts[3];
103     int err, num_opts = 2;
104
105     init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR,
106               (void *)&dev_str, &dev_set, "device");
107     init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_STR,
108               (void *)&type_str, &type_set, "fstype");
109 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE
110     init_opts(&opts[2], 'f', true, OPTION_ARG_TYPE_STR,
111               (void *)&part_str, &part_set, "partition");
112     num_opts++;
113 #endif
114
115     CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
116
117     if (!scan_opts(argc, argv, 1, opts, num_opts, NULL, 0, NULL))
118         return;
119
120     if (!type_set) {
121         diag_printf("Must specify file system type\n");
122         return;
123     }
124     if (fileio_mounted) {
125         diag_printf("A file system is already mounted\n");
126         return;
127     }
128 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE
129     if (part_set) {
130         int len;
131         cyg_io_handle_t h;
132
133         if (dev_set && strcmp(dev_str, CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)) {
134             diag_printf("May only set one of <device> or <partition>\n");
135             return;
136         }
137
138         dev_str = CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1;
139         len = strlen(part_str);
140
141         err = cyg_io_lookup(dev_str, &h);
142         if (err < 0) {
143             diag_printf("cyg_io_lookup of \"%s\" returned %d\n", err);
144             return;
145         }
146         err = cyg_io_set_config(h, CYG_IO_SET_CONFIG_FLASH_FIS_NAME,
147                                 part_str, &len);
148         if (err < 0) {
149             diag_printf("FIS partition \"%s\" not found\n",
150                         part_str);
151             return;
152         }
153     }
154 #endif
155     err = mount(dev_str, "/", type_str);
156
157     if (err) {
158         diag_printf("Mount failed %d\n", err);
159     } else {
160 //        diag_printf("Mount %s file system succeeded\n", type_str);
161         fileio_mounted = 1;
162 #ifdef CYGBLD_REDBOOT_FILEIO_WITH_LS
163         chdir("/");
164 #endif        
165     }
166 }
167
168 static void
169 do_umount(int argc, char *argv[])
170 {
171     if (!fileio_mounted) {
172         return;
173     }
174     umount ("/");
175     fileio_mounted = 0;
176 }
177
178 #ifdef CYGBLD_REDBOOT_FILEIO_WITH_LS
179 #include <dirent.h>
180
181 static char rwx[8][4] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" }; 
182
183 static void 
184 do_ls(int argc, char * argv[])
185 {
186      char * dir_str;
187      struct option_info opts[1];
188      bool dir_set = false;
189      DIR *dirp;
190      char cwd[PATH_MAX];
191      char filename[PATH_MAX];
192      struct stat sbuf;
193      int err;
194      
195      init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR,
196                (void *)&dir_str, &dir_set, "directory");
197      
198      if (!fileio_mounted) {
199           diag_printf("No filesystem mounted\n");
200           return;
201      }
202      
203      if (!scan_opts(argc, argv, 1, opts, 1, NULL, 0, NULL))
204           return;
205
206      if (!dir_set) {
207           getcwd(cwd,sizeof(cwd));
208           dir_str = cwd;
209      }
210      
211      diag_printf("directory %s\n",dir_str);
212      dirp = opendir(dir_str);
213      if (dirp==NULL) {
214           diag_printf("no such directory %s\n",dir_str);
215           return;
216      }
217      
218      for (;;) {
219           struct dirent *entry = readdir(dirp);
220           
221           if( entry == NULL )
222                break;
223     
224           strcpy(filename, dir_str);
225           strcat(filename, "/");
226           strcat(filename, entry->d_name);
227           
228           err = stat(filename, &sbuf);
229           if (err < 0) {
230                diag_printf("Unable to stat file %s\n", filename);
231                continue;
232           }
233           diag_printf("%4d ", sbuf.st_ino);
234           if (S_ISDIR(sbuf.st_mode)) diag_printf("d");
235           if (S_ISCHR(sbuf.st_mode)) diag_printf("c");
236           if (S_ISBLK(sbuf.st_mode)) diag_printf("b");
237           if (S_ISREG(sbuf.st_mode)) diag_printf("-");
238           if (S_ISLNK(sbuf.st_mode)) diag_printf("l");
239           diag_printf("%s%s%s",    // Ho, humm, have to hard code the shifts
240                       rwx[(sbuf.st_mode & S_IRWXU) >> 16],
241                       rwx[(sbuf.st_mode & S_IRWXG) >> 19],
242                       rwx[(sbuf.st_mode & S_IRWXO) >> 22]);
243           diag_printf(" %2d size %6d %s\n",
244                       sbuf.st_nlink,sbuf.st_size, 
245                       entry->d_name);
246      }
247      
248      closedir(dirp);
249      return;
250 }
251
252 RedBoot_cmd("ls", 
253             "list directory contents",
254             "[-d directory]",
255             do_ls
256     );
257
258 #endif // CYGBLD_REDBOOT_FILEIO_WITH_LS
259 static int fd;
260
261 externC int 
262 fileio_stream_open(connection_info_t *info, int *err)
263 {
264     char *filename = info->filename;
265
266     if (!fileio_mounted) {
267         diag_printf("No file system mounted\n");
268         return -1;
269     }
270     fd = open(filename, O_RDONLY);
271     if (fd < 0) {
272         diag_printf("Open failed, error %d\n", errno);
273         return -1;
274     }
275     return 0;
276 }
277
278 externC int 
279 fileio_stream_read(char *buf, int size, int *err)
280 {
281     int nread;
282
283     if ((nread = read(fd, buf, size)) < 0) {
284         *err = errno;
285         return -1;
286     }
287     return nread;
288 }
289
290 externC void
291 fileio_stream_close(int *err)
292 {
293     close(fd);
294 }
295
296 externC char *
297 fileio_error(int err)
298 {
299     static char myerr[10];
300
301     diag_sprintf(myerr, "error %d\n", err);
302     return myerr;
303 }
304
305 //
306 // RedBoot interface
307 //
308 GETC_IO_FUNCS(fileio_io, fileio_stream_open, fileio_stream_close,
309               0, fileio_stream_read, fileio_error);
310 RedBoot_load(file, fileio_io, true, true, 0);
311