Mercurial > ecos
comparison packages/redboot/current/src/fs/fileio.c @ 2257:467fd46113f3
* src/fs/fileio.c (do_list): Use getcwd for current directory,
rather than "." which may not be implemented in the FS.
* src/parse.c (redboot_exec): Conditionalise use of
__mem_fault_handler to only be when stubs are included.
(error_handler): Ditto for this function.
* src/main.c (cyg_start): Conditionalise use of
__mem_fault_handler to only be when stubs are included.
(do_go): Ditto.
(error_handler): Ditto for this function.
* src/fs/fileio.c (do_mkdir, do_deldir, do_del, do_write): Added
some extra argument checking to these functions.
* src/fs/fileio.c (do_mount): Only support -f with "legacy" flash
block devices.
Clear mount table on failure.
(do_move): Silence rename undefined warning.
(do_write): Silence warnings.
(do_info): Support longer device names.
* src/decompress.c (ZLIB_COMPRESSION_OVERHEAD):
Increase substantially if jffs2 is present.
* src/fs/fileio.c: Fixed some bugs in handling of mounts. The
strings used in the mount table must be copied, otherwise the
mount table is corrupted by later commands. Also toughened up some
error testing.
* doc/redboot_cmds.sgml: Added file mode documentation to load
command.
* doc/redboot_cmds.sgml: Added documentation of filesystem access
commands.
* src/fs/fileio.c (do_write): Added O_TRUNC to the open call to
ensure that the file is resized to fit the new data.
* src/fs/fileio.c: Significantly reorganized to present an
interface similar to the fis commands. Added a variety of command
to manipulate files and directories in a filesystem.
* src/parse.c: Added redboot_exec() to provide an internal
interface for executing RedBoot commands. Added err_printf() which
allows an error message to be printed before longjumping out to an
enclosing call to redboot_exec(). Where redboot_exec() is not
involved, it just behaves like diag_printf().
* src/main.c: Removed unnecessary delay during startup. Changed
diag_printf() in do_go() into err_printf().
* src/load.c: Changed some calls to diag_printf() to err_printf().
* src/net/net_io.c: Changed init priority to RedBoot_INIT_NET.
* include/redboot.h: Added some extra initialization
priorities. Added prototypes for redboot_exec() and err_printf().
| author | jlarmour |
|---|---|
| date | Thu, 20 Jul 2006 20:27:47 +0000 |
| parents | a0d4c606e72d |
| children | 09f5e65f57b1 |
comparison
equal
deleted
inserted
replaced
| 2256:9838a9103c2a | 2257:467fd46113f3 |
|---|---|
| 8 //####ECOSGPLCOPYRIGHTBEGIN#### | 8 //####ECOSGPLCOPYRIGHTBEGIN#### |
| 9 // ------------------------------------------- | 9 // ------------------------------------------- |
| 10 // This file is part of eCos, the Embedded Configurable Operating System. | 10 // This file is part of eCos, the Embedded Configurable Operating System. |
| 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. | 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
| 12 // Copyright (C) 2002, 2003, 2004 Gary Thomas | 12 // Copyright (C) 2002, 2003, 2004 Gary Thomas |
| 13 // Copyright (C) 2004, 2005, 2006 eCosCentric Limited. | |
| 13 // | 14 // |
| 14 // eCos is free software; you can redistribute it and/or modify it under | 15 // 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 // 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 // Software Foundation; either version 2 or (at your option) any later version. |
| 17 // | 18 // |
| 32 // in accordance with section (3) of the GNU General Public License. | 33 // in accordance with section (3) of the GNU General Public License. |
| 33 // | 34 // |
| 34 // This exception does not invalidate any other reasons why a work based on | 35 // 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 // this file might be covered by the GNU General Public License. |
| 36 // | 37 // |
| 37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. | |
| 38 // at http://sources.redhat.com/ecos/ecos-license/ | |
| 39 // ------------------------------------------- | 38 // ------------------------------------------- |
| 40 //####ECOSGPLCOPYRIGHTEND#### | 39 //####ECOSGPLCOPYRIGHTEND#### |
| 41 //========================================================================== | 40 //========================================================================== |
| 42 //#####DESCRIPTIONBEGIN#### | 41 //#####DESCRIPTIONBEGIN#### |
| 43 // | 42 // |
| 44 // Author(s): dwmw2, msalter | 43 // Author(s): nickg |
| 45 // Date: 2003-11-27 | 44 // Contributors: dwmw2, msalter |
| 45 // Date: 2004-11-21 | |
| 46 // Purpose: | 46 // Purpose: |
| 47 // Description: | 47 // Description: |
| 48 // | 48 // |
| 49 // This code is part of RedBoot (tm). | 49 // This code is part of RedBoot (tm). |
| 50 // | 50 // |
| 66 #ifdef CYGPKG_IO_FLASH | 66 #ifdef CYGPKG_IO_FLASH |
| 67 #include <cyg/io/io.h> | 67 #include <cyg/io/io.h> |
| 68 #include <cyg/io/flash.h> | 68 #include <cyg/io/flash.h> |
| 69 #include <cyg/io/config_keys.h> | 69 #include <cyg/io/config_keys.h> |
| 70 #endif | 70 #endif |
| 71 #include <cyg/io/devtab.h> | |
| 71 #include <cyg/fileio/fileio.h> | 72 #include <cyg/fileio/fileio.h> |
| 72 #include <cyg/infra/cyg_ass.h> // assertion macros | 73 #include <cyg/infra/cyg_ass.h> // assertion macros |
| 73 | 74 |
| 75 //========================================================================== | |
| 76 | |
| 77 // Define table boundaries | |
| 78 CYG_HAL_TABLE_BEGIN( __FS_cmds_TAB__, FS_cmds); | |
| 79 CYG_HAL_TABLE_END( __FS_cmds_TAB_END__, FS_cmds); | |
| 80 | |
| 81 extern struct cmd __FS_cmds_TAB__[], __FS_cmds_TAB_END__; | |
| 82 | |
| 83 //========================================================================== | |
| 84 | |
| 85 static void | |
| 86 fs_usage(char *why) | |
| 87 { | |
| 88 diag_printf("*** invalid 'fs' command: %s\n", why); | |
| 89 cmd_usage(__FS_cmds_TAB__, &__FS_cmds_TAB_END__, "fs "); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 //========================================================================== | |
| 94 | |
| 95 #define MAX_MOUNTS 4 | |
| 96 | |
| 97 static int mount_count = 0; | |
| 98 | |
| 99 static struct | |
| 100 { | |
| 101 char dev_str[PATH_MAX]; | |
| 102 char mp_str[PATH_MAX]; | |
| 103 char type_str[PATH_MAX]; | |
| 104 } mounts[MAX_MOUNTS]; | |
| 105 | |
| 106 //========================================================================== | |
| 107 | |
| 74 static void do_mount(int argc, char *argv[]); | 108 static void do_mount(int argc, char *argv[]); |
| 75 static void do_umount(int argc, char *argv[]); | 109 static void do_umount(int argc, char *argv[]); |
| 76 | 110 |
| 77 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE | 111 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY |
| 78 #define FLASHPART "[-f <partition>] " | 112 #define FLASHPART "[-f <partition>] " |
| 79 #else | 113 #else |
| 80 #define FLASHPART | 114 #define FLASHPART |
| 81 #endif | 115 #endif |
| 82 | 116 |
| 83 RedBoot_cmd("mount", | 117 local_cmd_entry("mount", |
| 84 "Mount file system", | 118 "Mount file system", |
| 85 FLASHPART "[-d <device>] -t fstype", | 119 FLASHPART "[-d <device>] -t <fstype> [<mountpoint>]", |
| 86 do_mount | 120 do_mount, |
| 87 ); | 121 FS_cmds |
| 88 RedBoot_cmd("umount", | 122 ); |
| 89 "Unmount file system", | 123 local_cmd_entry("umount", |
| 90 "", | 124 "Unmount file system", |
| 91 do_umount | 125 "<mountpoint>", |
| 92 ); | 126 do_umount, |
| 93 | 127 FS_cmds |
| 94 int fileio_mounted = 0; | 128 ); |
| 129 | |
| 130 //========================================================================== | |
| 95 | 131 |
| 96 // Mount disk/filesystem | 132 // Mount disk/filesystem |
| 97 static void | 133 static void |
| 98 do_mount(int argc, char *argv[]) | 134 do_mount(int argc, char *argv[]) |
| 99 { | 135 { |
| 100 char *part_str, *dev_str, *type_str; | 136 char *dev_str = "<undefined>", *type_str, *mp_str; |
| 101 bool part_set = false, dev_set = false, type_set = false; | 137 bool dev_set = false, type_set = false; |
| 102 struct option_info opts[3]; | 138 struct option_info opts[3]; |
| 103 int err, num_opts = 2; | 139 int err, num_opts = 2; |
| 140 int i,m=0; /* Set to 0 to silence warning */ | |
| 141 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY | |
| 142 char *part_str; | |
| 143 bool part_set = false; | |
| 144 #endif | |
| 104 | 145 |
| 105 init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR, | 146 init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR, |
| 106 (void *)&dev_str, &dev_set, "device"); | 147 (void *)&dev_str, &dev_set, "device"); |
| 107 init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_STR, | 148 init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_STR, |
| 108 (void *)&type_str, &type_set, "fstype"); | 149 (void *)&type_str, &type_set, "fstype"); |
| 109 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE | 150 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY |
| 110 init_opts(&opts[2], 'f', true, OPTION_ARG_TYPE_STR, | 151 init_opts(&opts[2], 'f', true, OPTION_ARG_TYPE_STR, |
| 111 (void *)&part_str, &part_set, "partition"); | 152 (void *)&part_str, &part_set, "partition"); |
| 112 num_opts++; | 153 num_opts++; |
| 113 #endif | 154 #endif |
| 114 | 155 |
| 115 CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options"); | 156 CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options"); |
| 116 | 157 |
| 117 if (!scan_opts(argc, argv, 1, opts, num_opts, NULL, 0, NULL)) | 158 if (!scan_opts(argc, argv, 1, opts, num_opts, &mp_str, OPTION_ARG_TYPE_STR, "mountpoint")) |
| 118 return; | 159 return; |
| 119 | 160 |
| 120 if (!type_set) { | 161 if (!type_set) { |
| 121 diag_printf("Must specify file system type\n"); | 162 err_printf("fs mount: Must specify file system type\n"); |
| 122 return; | 163 return; |
| 123 } | 164 } |
| 124 if (fileio_mounted) { | 165 |
| 125 diag_printf("A file system is already mounted\n"); | 166 if( mp_str == 0 ) |
| 126 return; | 167 mp_str = "/"; |
| 127 } | 168 |
| 128 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE | 169 if( mount_count >= MAX_MOUNTS ) |
| 170 { | |
| 171 err_printf("fs mount: Maximum number of mounts exceeded\n"); | |
| 172 return; | |
| 173 } | |
| 174 | |
| 175 #ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY | |
| 129 if (part_set) { | 176 if (part_set) { |
| 130 int len; | 177 int len; |
| 131 cyg_io_handle_t h; | 178 cyg_io_handle_t h; |
| 132 | 179 |
| 133 if (dev_set && strcmp(dev_str, CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)) { | 180 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"); | 181 err_printf("fs mount: May only set one of <device> or <partition>\n"); |
| 135 return; | 182 return; |
| 136 } | 183 } |
| 137 | 184 |
| 138 dev_str = CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1; | 185 dev_str = CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1; |
| 139 len = strlen(part_str); | 186 len = strlen(part_str); |
| 140 | 187 |
| 141 err = cyg_io_lookup(dev_str, &h); | 188 err = cyg_io_lookup(dev_str, &h); |
| 142 if (err < 0) { | 189 if (err < 0) { |
| 143 diag_printf("cyg_io_lookup of \"%s\" returned %d\n", err); | 190 err_printf("fs mount: cyg_io_lookup of \"%s\" returned %d\n", err); |
| 144 return; | 191 return; |
| 145 } | 192 } |
| 146 err = cyg_io_set_config(h, CYG_IO_SET_CONFIG_FLASH_FIS_NAME, | 193 err = cyg_io_set_config(h, CYG_IO_SET_CONFIG_FLASH_FIS_NAME, |
| 147 part_str, &len); | 194 part_str, &len); |
| 148 if (err < 0) { | 195 if (err < 0) { |
| 149 diag_printf("FIS partition \"%s\" not found\n", | 196 diag_printf("fs mount: FIS partition \"%s\" not found\n", |
| 150 part_str); | 197 part_str); |
| 151 return; | 198 return; |
| 152 } | 199 } |
| 153 } | 200 } |
| 154 #endif | 201 #endif |
| 155 err = mount(dev_str, "/", type_str); | 202 |
| 156 | 203 for( i = 0; i < MAX_MOUNTS; i++ ) |
| 157 if (err) { | 204 { |
| 158 diag_printf("Mount failed %d\n", err); | 205 if( mounts[i].mp_str[0] != '\0' ) |
| 159 } else { | 206 { |
| 160 // diag_printf("Mount %s file system succeeded\n", type_str); | 207 if( strcmp(mounts[i].dev_str, dev_str ) == 0 ) |
| 161 fileio_mounted = 1; | 208 { |
| 162 #ifdef CYGBLD_REDBOOT_FILEIO_WITH_LS | 209 err_printf("fs mount: Device %s already mounted\n",dev_str); |
| 163 chdir("/"); | 210 return; |
| 164 #endif | 211 } |
| 165 } | 212 } |
| 166 } | 213 else |
| 214 m = i; | |
| 215 } | |
| 216 | |
| 217 strcpy( mounts[m].mp_str, mp_str ); | |
| 218 strcpy( mounts[m].dev_str, dev_str ); | |
| 219 strcpy( mounts[m].type_str, type_str ); | |
| 220 | |
| 221 err = mount(mounts[m].dev_str, mounts[m].mp_str, mounts[m].type_str); | |
| 222 | |
| 223 if (err) | |
| 224 { | |
| 225 err_printf("fs mount: mount(%s,%s,%s) failed %d\n", dev_str, mp_str, type_str, errno); | |
| 226 mounts[m].mp_str[0] = '\0'; // mount failed so don't let it appear mounted | |
| 227 } | |
| 228 else | |
| 229 { | |
| 230 if( mount_count == 0 ) | |
| 231 chdir( "/" ); | |
| 232 mount_count++; | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 //========================================================================== | |
| 167 | 237 |
| 168 static void | 238 static void |
| 169 do_umount(int argc, char *argv[]) | 239 do_umount(int argc, char *argv[]) |
| 170 { | 240 { |
| 171 if (!fileio_mounted) { | 241 char *dir_str; |
| 172 return; | 242 int err; |
| 173 } | 243 int i; |
| 174 umount ("/"); | 244 |
| 175 fileio_mounted = 0; | 245 if( mount_count == 0 ) |
| 176 } | 246 { |
| 177 | 247 err_printf("fs: No filesystems mounted\n"); |
| 178 #ifdef CYGBLD_REDBOOT_FILEIO_WITH_LS | 248 return; |
| 249 } | |
| 250 | |
| 251 if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "mountpoint")) | |
| 252 return; | |
| 253 | |
| 254 if( dir_str == 0 ) | |
| 255 dir_str = "/"; | |
| 256 | |
| 257 for( i = 0; i < MAX_MOUNTS; i++ ) | |
| 258 { | |
| 259 if( strcmp(mounts[i].mp_str, dir_str ) == 0 ) | |
| 260 break; | |
| 261 } | |
| 262 | |
| 263 if( i == MAX_MOUNTS ) | |
| 264 { | |
| 265 err_printf("fs unmount: unknown mountpoint %s\n",dir_str); | |
| 266 return; | |
| 267 } | |
| 268 | |
| 269 err = umount (dir_str); | |
| 270 | |
| 271 if (err) | |
| 272 err_printf("fs umount: unmount failed %d\n", errno); | |
| 273 else | |
| 274 { | |
| 275 mounts[i].mp_str[0] = '\0'; | |
| 276 mount_count--; | |
| 277 if( mount_count == 0 ) | |
| 278 chdir( "/" ); | |
| 279 } | |
| 280 | |
| 281 } | |
| 282 | |
| 283 //========================================================================== | |
| 284 | |
| 179 #include <dirent.h> | 285 #include <dirent.h> |
| 180 | 286 |
| 181 static char rwx[8][4] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" }; | 287 static char rwx[8][4] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" }; |
| 182 | 288 |
| 183 static void | 289 static void |
| 184 do_ls(int argc, char * argv[]) | 290 do_list(int argc, char * argv[]) |
| 185 { | 291 { |
| 186 char * dir_str; | 292 char * dir_str; |
| 187 struct option_info opts[1]; | |
| 188 bool dir_set = false; | |
| 189 DIR *dirp; | 293 DIR *dirp; |
| 294 char filename[PATH_MAX]; | |
| 190 char cwd[PATH_MAX]; | 295 char cwd[PATH_MAX]; |
| 191 char filename[PATH_MAX]; | |
| 192 struct stat sbuf; | 296 struct stat sbuf; |
| 193 int err; | 297 int err; |
| 194 | 298 |
| 195 init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR, | 299 if( mount_count == 0 ) |
| 196 (void *)&dir_str, &dir_set, "directory"); | 300 { |
| 197 | 301 err_printf("fs: No filesystems mounted\n"); |
| 198 if (!fileio_mounted) { | 302 return; |
| 199 diag_printf("No filesystem mounted\n"); | 303 } |
| 304 | |
| 305 if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory")) | |
| 200 return; | 306 return; |
| 201 } | 307 |
| 202 | 308 if( dir_str == 0 ) |
| 203 if (!scan_opts(argc, argv, 1, opts, 1, NULL, 0, NULL)) | 309 { |
| 204 return; | 310 dir_str = getcwd(cwd, sizeof(cwd)); |
| 205 | 311 } |
| 206 if (!dir_set) { | 312 |
| 207 getcwd(cwd,sizeof(cwd)); | |
| 208 dir_str = cwd; | |
| 209 } | |
| 210 | |
| 211 diag_printf("directory %s\n",dir_str); | |
| 212 dirp = opendir(dir_str); | 313 dirp = opendir(dir_str); |
| 213 if (dirp==NULL) { | 314 if (dirp==NULL) { |
| 214 diag_printf("no such directory %s\n",dir_str); | 315 err_printf("fs list: no such directory %s\n",dir_str); |
| 215 return; | 316 return; |
| 216 } | 317 } |
| 217 | 318 |
| 218 for (;;) { | 319 for (;;) { |
| 219 struct dirent *entry = readdir(dirp); | 320 struct dirent *entry = readdir(dirp); |
| 247 | 348 |
| 248 closedir(dirp); | 349 closedir(dirp); |
| 249 return; | 350 return; |
| 250 } | 351 } |
| 251 | 352 |
| 252 RedBoot_cmd("ls", | 353 local_cmd_entry("list", |
| 253 "list directory contents", | 354 "list directory contents", |
| 254 "[-d directory]", | 355 "[<directory>]", |
| 255 do_ls | 356 do_list, |
| 256 ); | 357 FS_cmds |
| 257 | 358 ); |
| 258 #endif // CYGBLD_REDBOOT_FILEIO_WITH_LS | 359 |
| 360 | |
| 361 //========================================================================== | |
| 362 | |
| 363 | |
| 364 static void | |
| 365 do_mkdir(int argc, char * argv[]) | |
| 366 { | |
| 367 char *dir_str; | |
| 368 int err; | |
| 369 | |
| 370 if( mount_count == 0 ) | |
| 371 { | |
| 372 err_printf("fs: No filesystems mounted\n"); | |
| 373 return; | |
| 374 } | |
| 375 | |
| 376 if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory") || | |
| 377 dir_str == NULL) | |
| 378 { | |
| 379 fs_usage("invalid arguments"); | |
| 380 return; | |
| 381 } | |
| 382 | |
| 383 err = mkdir( dir_str, 0 ); | |
| 384 | |
| 385 if( err != 0 ) | |
| 386 err_printf("fs mkdir: failed to create directory %s\n",dir_str); | |
| 387 } | |
| 388 | |
| 389 local_cmd_entry("mkdir", | |
| 390 "create directory", | |
| 391 "<directory>", | |
| 392 do_mkdir, | |
| 393 FS_cmds | |
| 394 ); | |
| 395 | |
| 396 //========================================================================== | |
| 397 | |
| 398 static void | |
| 399 do_deldir(int argc, char * argv[]) | |
| 400 { | |
| 401 char *dir_str; | |
| 402 int err; | |
| 403 | |
| 404 if( mount_count == 0 ) | |
| 405 { | |
| 406 err_printf("fs: No filesystems mounted\n"); | |
| 407 return; | |
| 408 } | |
| 409 | |
| 410 if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory") || | |
| 411 dir_str == NULL) | |
| 412 { | |
| 413 fs_usage("invalid arguments"); | |
| 414 return; | |
| 415 } | |
| 416 | |
| 417 err = rmdir( dir_str ); | |
| 418 | |
| 419 if( err != 0 ) | |
| 420 err_printf("fs deldir: failed to remove directory %s\n",dir_str); | |
| 421 } | |
| 422 | |
| 423 local_cmd_entry("deldir", | |
| 424 "delete directory", | |
| 425 "<directory>", | |
| 426 do_deldir, | |
| 427 FS_cmds | |
| 428 ); | |
| 429 | |
| 430 //========================================================================== | |
| 431 | |
| 432 static void | |
| 433 do_del(int argc, char * argv[]) | |
| 434 { | |
| 435 char *name_str = NULL; | |
| 436 int err; | |
| 437 | |
| 438 if( mount_count == 0 ) | |
| 439 { | |
| 440 err_printf("fs: No filesystems mounted\n"); | |
| 441 return; | |
| 442 } | |
| 443 | |
| 444 if (!scan_opts(argc, argv, 1, NULL, 0, &name_str, OPTION_ARG_TYPE_STR, "file") || | |
| 445 name_str == NULL) | |
| 446 { | |
| 447 fs_usage("invalid arguments"); | |
| 448 return; | |
| 449 } | |
| 450 | |
| 451 err = unlink( name_str ); | |
| 452 | |
| 453 if( err != 0 ) | |
| 454 err_printf("fs del: failed to delete file %s\n",name_str); | |
| 455 } | |
| 456 | |
| 457 local_cmd_entry("del", | |
| 458 "delete file", | |
| 459 "<file>", | |
| 460 do_del, | |
| 461 FS_cmds | |
| 462 ); | |
| 463 | |
| 464 //========================================================================== | |
| 465 | |
| 466 static void | |
| 467 do_move(int argc, char * argv[]) | |
| 468 { | |
| 469 int err; | |
| 470 __externC int rename( const char *oldname, const char *newname ); | |
| 471 if( mount_count == 0 ) | |
| 472 { | |
| 473 err_printf("fs: No filesystems mounted\n"); | |
| 474 return; | |
| 475 } | |
| 476 | |
| 477 if( argc != 3 ) | |
| 478 fs_usage("bad arguments to move command\n"); | |
| 479 | |
| 480 err = rename( argv[1], argv[2] ); | |
| 481 | |
| 482 if( err != 0 ) | |
| 483 err_printf("fs move: failed to move file %s to %s\n",argv[1],argv[2]); | |
| 484 } | |
| 485 | |
| 486 local_cmd_entry("move", | |
| 487 "move file", | |
| 488 "<from> <to>", | |
| 489 do_move, | |
| 490 FS_cmds | |
| 491 ); | |
| 492 | |
| 493 //========================================================================== | |
| 494 | |
| 495 static void | |
| 496 do_cd(int argc, char * argv[]) | |
| 497 { | |
| 498 char *dir_str; | |
| 499 int err; | |
| 500 | |
| 501 if( mount_count == 0 ) | |
| 502 { | |
| 503 err_printf("fs: No filesystems mounted\n"); | |
| 504 return; | |
| 505 } | |
| 506 | |
| 507 if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory")) | |
| 508 return; | |
| 509 | |
| 510 if( dir_str == NULL ) | |
| 511 dir_str = "/"; | |
| 512 | |
| 513 err = chdir( dir_str ); | |
| 514 | |
| 515 if( err != 0 ) | |
| 516 err_printf("fs cd: failed to change directory %s\n",dir_str); | |
| 517 } | |
| 518 | |
| 519 local_cmd_entry("cd", | |
| 520 "change directory", | |
| 521 "[<directory>]", | |
| 522 do_cd, | |
| 523 FS_cmds | |
| 524 ); | |
| 525 | |
| 526 //========================================================================== | |
| 527 | |
| 528 static void | |
| 529 do_write(int argc, char * argv[]) | |
| 530 { | |
| 531 char *name_str = NULL; | |
| 532 int err; | |
| 533 struct option_info opts[2]; | |
| 534 CYG_ADDRESS mem_addr = 0; | |
| 535 unsigned long length = 0; | |
| 536 bool mem_addr_set = false; | |
| 537 bool length_set = false; | |
| 538 int fd; | |
| 539 | |
| 540 if( mount_count == 0 ) | |
| 541 { | |
| 542 err_printf("fs: No filesystems mounted\n"); | |
| 543 return; | |
| 544 } | |
| 545 | |
| 546 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | |
| 547 (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); | |
| 548 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, | |
| 549 (void *)&length, (bool *)&length_set, "image length"); | |
| 550 | |
| 551 if (!scan_opts(argc, argv, 1, opts, 2, &name_str, OPTION_ARG_TYPE_STR, "file name") || | |
| 552 name_str == NULL) | |
| 553 { | |
| 554 fs_usage("invalid arguments"); | |
| 555 return; | |
| 556 } | |
| 557 | |
| 558 // diag_printf("load_address %08x %08x\n",load_address,load_address_end); | |
| 559 // diag_printf("ram %08x %08x\n",ram_start, ram_end); | |
| 560 // diag_printf("file name %08x >%s<\n",name_str,name_str); | |
| 561 | |
| 562 if (!mem_addr_set && | |
| 563 (load_address >= (CYG_ADDRESS)ram_start) && | |
| 564 ((load_address_end) < (CYG_ADDRESS)ram_end)) | |
| 565 { | |
| 566 mem_addr = load_address; | |
| 567 mem_addr_set = true; | |
| 568 if (!length_set) | |
| 569 { | |
| 570 length = load_address_end - load_address; | |
| 571 length_set = true; | |
| 572 // maybe get length from existing file size if no loaded | |
| 573 // image? | |
| 574 } | |
| 575 } | |
| 576 | |
| 577 fd = open( name_str, O_WRONLY|O_CREAT|O_TRUNC ); | |
| 578 | |
| 579 if( fd < 0 ) | |
| 580 { | |
| 581 err_printf("fs write: Cannot open %s\n", name_str ); | |
| 582 return; | |
| 583 } | |
| 584 | |
| 585 // diag_printf("write %08x %08x\n",mem_addr, length ); | |
| 586 | |
| 587 err = write( fd, (void *)mem_addr, length ); | |
| 588 | |
| 589 if( err != length ) | |
| 590 { | |
| 591 err_printf("fs write: failed to write to file %d(%d) %d\n",err,length,errno); | |
| 592 } | |
| 593 | |
| 594 err = close( fd ); | |
| 595 | |
| 596 if( err != 0 ) | |
| 597 err_printf("fs write: close failed\n"); | |
| 598 } | |
| 599 | |
| 600 local_cmd_entry("write", | |
| 601 "write data to file", | |
| 602 "-b <mem_base> -l <image_length> <file_name>", | |
| 603 do_write, | |
| 604 FS_cmds | |
| 605 ); | |
| 606 | |
| 607 //========================================================================== | |
| 608 | |
| 609 __externC cyg_fstab_entry cyg_fstab[]; | |
| 610 __externC cyg_fstab_entry cyg_fstab_end; | |
| 611 __externC cyg_mtab_entry cyg_mtab[]; | |
| 612 __externC cyg_mtab_entry cyg_mtab_end; | |
| 613 | |
| 614 static void | |
| 615 do_info(int argc, char * argv[]) | |
| 616 { | |
| 617 cyg_bool found = false; | |
| 618 cyg_fstab_entry *f; | |
| 619 cyg_devtab_entry_t *t; | |
| 620 | |
| 621 for( f = &cyg_fstab[0] ; f != &cyg_fstab_end; f++ ) | |
| 622 { | |
| 623 if( !found ) | |
| 624 { | |
| 625 diag_printf("Filesystems available:\n"); | |
| 626 found = true; | |
| 627 } | |
| 628 diag_printf("%s\n",f->name); | |
| 629 } | |
| 630 | |
| 631 found = false; | |
| 632 for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++) | |
| 633 { | |
| 634 if( (t->status & CYG_DEVTAB_STATUS_BLOCK) == 0 || | |
| 635 (t->status & CYG_DEVTAB_STATUS_AVAIL) == 0 ) | |
| 636 continue; | |
| 637 | |
| 638 if( !found ) | |
| 639 { | |
| 640 diag_printf("\nDevices available:\n"); | |
| 641 found = true; | |
| 642 } | |
| 643 diag_printf("%s\n",t->name); | |
| 644 } | |
| 645 | |
| 646 if( mount_count != 0 ) | |
| 647 { | |
| 648 int i; | |
| 649 | |
| 650 diag_printf("\nMounted filesystems:\n"); | |
| 651 diag_printf(" Device Filesystem Mounted on\n"); | |
| 652 | |
| 653 for( i = 0; i < MAX_MOUNTS; i++ ) | |
| 654 { | |
| 655 if( mounts[i].mp_str[0] != '\0' ) | |
| 656 diag_printf("%32s %10s %s\n", mounts[i].dev_str, mounts[i].type_str, mounts[i].mp_str); | |
| 657 } | |
| 658 } | |
| 659 } | |
| 660 | |
| 661 local_cmd_entry("info", | |
| 662 "filesystem info", | |
| 663 "", | |
| 664 do_info, | |
| 665 FS_cmds | |
| 666 ); | |
| 667 | |
| 668 //========================================================================== | |
| 669 | |
| 670 static void | |
| 671 do_fs(int argc, char *argv[]) | |
| 672 { | |
| 673 struct cmd *cmd; | |
| 674 | |
| 675 if (argc < 2) { | |
| 676 fs_usage("too few arguments"); | |
| 677 return; | |
| 678 } | |
| 679 if ((cmd = cmd_search(__FS_cmds_TAB__, &__FS_cmds_TAB_END__, | |
| 680 argv[1])) != (struct cmd *)0) { | |
| 681 (cmd->fun)(argc-1, argv+1); | |
| 682 return; | |
| 683 } | |
| 684 fs_usage("unrecognized command"); | |
| 685 } | |
| 686 | |
| 687 RedBoot_nested_cmd("fs", | |
| 688 "Manage Filesystem files", | |
| 689 "{cmds}", | |
| 690 do_fs, | |
| 691 __FS_cmds_TAB__, &__FS_cmds_TAB_END__ | |
| 692 ); | |
| 693 | |
| 694 | |
| 695 //========================================================================== | |
| 696 | |
| 259 static int fd; | 697 static int fd; |
| 260 | 698 |
| 261 externC int | 699 externC int |
| 262 fileio_stream_open(connection_info_t *info, int *err) | 700 fileio_stream_open(connection_info_t *info, int *err) |
| 263 { | 701 { |
| 264 char *filename = info->filename; | 702 char *filename = info->filename; |
| 265 | 703 |
| 266 if (!fileio_mounted) { | 704 if( mount_count == 0 ) |
| 267 diag_printf("No file system mounted\n"); | 705 { |
| 268 return -1; | 706 diag_printf("fs: No filesystems mounted\n"); |
| 269 } | 707 return -1; |
| 708 } | |
| 709 | |
| 270 fd = open(filename, O_RDONLY); | 710 fd = open(filename, O_RDONLY); |
| 271 if (fd < 0) { | 711 if (fd < 0) { |
| 272 diag_printf("Open failed, error %d\n", errno); | 712 diag_printf("fs: Open failed, error %d\n", errno); |
| 273 return -1; | 713 return -1; |
| 274 } | 714 } |
| 275 return 0; | 715 return 0; |
| 276 } | 716 } |
| 277 | 717 |
| 296 externC char * | 736 externC char * |
| 297 fileio_error(int err) | 737 fileio_error(int err) |
| 298 { | 738 { |
| 299 static char myerr[10]; | 739 static char myerr[10]; |
| 300 | 740 |
| 301 diag_sprintf(myerr, "error %d\n", err); | 741 diag_sprintf(myerr, "error %d", err); |
| 302 return myerr; | 742 return myerr; |
| 303 } | 743 } |
| 304 | 744 |
| 305 // | 745 // |
| 306 // RedBoot interface | 746 // RedBoot interface |
| 307 // | 747 // |
| 308 GETC_IO_FUNCS(fileio_io, fileio_stream_open, fileio_stream_close, | 748 GETC_IO_FUNCS(fileio_io, fileio_stream_open, fileio_stream_close, |
| 309 0, fileio_stream_read, fileio_error); | 749 0, fileio_stream_read, fileio_error); |
| 310 RedBoot_load(file, fileio_io, true, true, 0); | 750 RedBoot_load(file, fileio_io, true, true, 0); |
| 311 | 751 |
| 752 //========================================================================== | |
| 753 // End of fileio.c | |
| 754 |
