1*10465441SEvalZero /*
2*10465441SEvalZero This file is part of UFFS, the Ultra-low-cost Flash File System.
3*10465441SEvalZero
4*10465441SEvalZero Copyright (C) 2005-2009 Ricky Zheng <[email protected]>
5*10465441SEvalZero
6*10465441SEvalZero UFFS is free software; you can redistribute it and/or modify it under
7*10465441SEvalZero the GNU Library General Public License as published by the Free Software
8*10465441SEvalZero Foundation; either version 2 of the License, or (at your option) any
9*10465441SEvalZero later version.
10*10465441SEvalZero
11*10465441SEvalZero UFFS is distributed in the hope that it will be useful, but WITHOUT
12*10465441SEvalZero ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*10465441SEvalZero FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*10465441SEvalZero or GNU Library General Public License, as applicable, for more details.
15*10465441SEvalZero
16*10465441SEvalZero You should have received a copy of the GNU General Public License
17*10465441SEvalZero and GNU Library General Public License along with UFFS; if not, write
18*10465441SEvalZero to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19*10465441SEvalZero Boston, MA 02110-1301, USA.
20*10465441SEvalZero
21*10465441SEvalZero As a special exception, if other files instantiate templates or use
22*10465441SEvalZero macros or inline functions from this file, or you compile this file
23*10465441SEvalZero and link it with other works to produce a work based on this file,
24*10465441SEvalZero this file does not by itself cause the resulting work to be covered
25*10465441SEvalZero by the GNU General Public License. However the source code for this
26*10465441SEvalZero file must still be made available in accordance with section (3) of
27*10465441SEvalZero the GNU General Public License v2.
28*10465441SEvalZero
29*10465441SEvalZero This exception does not invalidate any other reasons why a work based
30*10465441SEvalZero on this file might be covered by the GNU General Public License.
31*10465441SEvalZero */
32*10465441SEvalZero
33*10465441SEvalZero /**
34*10465441SEvalZero * \file helper_cmds.c
35*10465441SEvalZero * \brief helper commands for test uffs
36*10465441SEvalZero * \author Ricky Zheng
37*10465441SEvalZero */
38*10465441SEvalZero #include <stdio.h>
39*10465441SEvalZero #include <string.h>
40*10465441SEvalZero #include <stdarg.h>
41*10465441SEvalZero #include <stdlib.h>
42*10465441SEvalZero #include "uffs_config.h"
43*10465441SEvalZero #include "uffs/uffs_public.h"
44*10465441SEvalZero #include "uffs/uffs_fs.h"
45*10465441SEvalZero #include "uffs/uffs_utils.h"
46*10465441SEvalZero #include "uffs/uffs_core.h"
47*10465441SEvalZero #include "uffs/uffs_mtb.h"
48*10465441SEvalZero #include "uffs/uffs_find.h"
49*10465441SEvalZero #include "cmdline.h"
50*10465441SEvalZero #include "uffs/uffs_fd.h"
51*10465441SEvalZero #include "uffs/uffs_mtb.h"
52*10465441SEvalZero #include "uffs_fileem.h"
53*10465441SEvalZero
54*10465441SEvalZero #define PFX "cmd : "
55*10465441SEvalZero
56*10465441SEvalZero #define MAX_PATH_LENGTH 128
57*10465441SEvalZero
58*10465441SEvalZero #define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
59*10465441SEvalZero #define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
60*10465441SEvalZero
61*10465441SEvalZero /** format [<mount>] */
cmd_format(int argc,char * argv[])62*10465441SEvalZero static int cmd_format(int argc, char *argv[])
63*10465441SEvalZero {
64*10465441SEvalZero URET ret;
65*10465441SEvalZero const char *mount = "/";
66*10465441SEvalZero uffs_Device *dev;
67*10465441SEvalZero UBOOL force = U_FALSE;
68*10465441SEvalZero
69*10465441SEvalZero if (argc > 1) {
70*10465441SEvalZero mount = argv[1];
71*10465441SEvalZero if (argc > 2 && strcmp(argv[2], "-f") == 0)
72*10465441SEvalZero force = U_TRUE;
73*10465441SEvalZero }
74*10465441SEvalZero MSGLN("Formating %s ... ", mount);
75*10465441SEvalZero
76*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
77*10465441SEvalZero if (dev == NULL) {
78*10465441SEvalZero MSGLN("Can't get device from mount point.");
79*10465441SEvalZero return -1;
80*10465441SEvalZero }
81*10465441SEvalZero else {
82*10465441SEvalZero ret = uffs_FormatDevice(dev, force);
83*10465441SEvalZero if (ret != U_SUCC) {
84*10465441SEvalZero MSGLN("Format fail.");
85*10465441SEvalZero return -1;
86*10465441SEvalZero }
87*10465441SEvalZero else {
88*10465441SEvalZero MSGLN("Format succ.");
89*10465441SEvalZero }
90*10465441SEvalZero uffs_PutDevice(dev);
91*10465441SEvalZero }
92*10465441SEvalZero
93*10465441SEvalZero return 0;
94*10465441SEvalZero }
95*10465441SEvalZero
96*10465441SEvalZero /** mkf <file> */
cmd_mkf(int argc,char * argv[])97*10465441SEvalZero static int cmd_mkf(int argc, char *argv[])
98*10465441SEvalZero {
99*10465441SEvalZero int fd;
100*10465441SEvalZero const char *name;
101*10465441SEvalZero int oflags = UO_RDWR | UO_CREATE;
102*10465441SEvalZero
103*10465441SEvalZero CHK_ARGC(2, 2);
104*10465441SEvalZero
105*10465441SEvalZero name = argv[1];
106*10465441SEvalZero fd = uffs_open(name, oflags);
107*10465441SEvalZero if (fd < 0) {
108*10465441SEvalZero MSGLN("Create %s fail, err: %d", name, uffs_get_error());
109*10465441SEvalZero return -1;
110*10465441SEvalZero }
111*10465441SEvalZero else {
112*10465441SEvalZero MSGLN("Create %s succ.", name);
113*10465441SEvalZero uffs_close(fd);
114*10465441SEvalZero }
115*10465441SEvalZero
116*10465441SEvalZero return 0;
117*10465441SEvalZero }
118*10465441SEvalZero
119*10465441SEvalZero /** mkdir <dir> */
cmd_mkdir(int argc,char * argv[])120*10465441SEvalZero static int cmd_mkdir(int argc, char *argv[])
121*10465441SEvalZero {
122*10465441SEvalZero const char *name;
123*10465441SEvalZero
124*10465441SEvalZero CHK_ARGC(2, 0);
125*10465441SEvalZero
126*10465441SEvalZero name = argv[1];
127*10465441SEvalZero
128*10465441SEvalZero if (uffs_mkdir(name) < 0) {
129*10465441SEvalZero MSGLN("Create %s fail, err: %d", name, uffs_get_error());
130*10465441SEvalZero return -1;
131*10465441SEvalZero }
132*10465441SEvalZero else {
133*10465441SEvalZero MSGLN("Create %s succ.", name);
134*10465441SEvalZero }
135*10465441SEvalZero
136*10465441SEvalZero return 0;
137*10465441SEvalZero }
138*10465441SEvalZero
139*10465441SEvalZero
CountObjectUnder(const char * dir)140*10465441SEvalZero static int CountObjectUnder(const char *dir)
141*10465441SEvalZero {
142*10465441SEvalZero int count = 0;
143*10465441SEvalZero uffs_DIR *dirp;
144*10465441SEvalZero
145*10465441SEvalZero dirp = uffs_opendir(dir);
146*10465441SEvalZero if (dirp) {
147*10465441SEvalZero while (uffs_readdir(dirp) != NULL)
148*10465441SEvalZero count++;
149*10465441SEvalZero uffs_closedir(dirp);
150*10465441SEvalZero }
151*10465441SEvalZero return count;
152*10465441SEvalZero }
153*10465441SEvalZero
cmd_pwd(int argc,char * argv[])154*10465441SEvalZero static int cmd_pwd(int argc, char *argv[])
155*10465441SEvalZero {
156*10465441SEvalZero MSGLN("not supported.");
157*10465441SEvalZero return 0;
158*10465441SEvalZero }
159*10465441SEvalZero
cmd_cd(int argc,char * argv[])160*10465441SEvalZero static int cmd_cd(int argc, char *argv[])
161*10465441SEvalZero {
162*10465441SEvalZero MSGLN("Not supported");
163*10465441SEvalZero return 0;
164*10465441SEvalZero }
165*10465441SEvalZero
166*10465441SEvalZero /** ls [<dir>] */
cmd_ls(int argc,char * argv[])167*10465441SEvalZero static int cmd_ls(int argc, char *argv[])
168*10465441SEvalZero {
169*10465441SEvalZero uffs_DIR *dirp;
170*10465441SEvalZero struct uffs_dirent *ent;
171*10465441SEvalZero struct uffs_stat stat_buf;
172*10465441SEvalZero int count = 0;
173*10465441SEvalZero char buf[MAX_PATH_LENGTH+2];
174*10465441SEvalZero const char *name = "/";
175*10465441SEvalZero char *sub;
176*10465441SEvalZero int ret = 0;
177*10465441SEvalZero
178*10465441SEvalZero CHK_ARGC(1, 2);
179*10465441SEvalZero
180*10465441SEvalZero if (argc > 1)
181*10465441SEvalZero name = argv[1];
182*10465441SEvalZero
183*10465441SEvalZero dirp = uffs_opendir(name);
184*10465441SEvalZero if (dirp == NULL) {
185*10465441SEvalZero MSGLN("Can't open '%s' for list", name);
186*10465441SEvalZero ret = -1;
187*10465441SEvalZero }
188*10465441SEvalZero else {
189*10465441SEvalZero MSG("------name-----------size---------serial-----" TENDSTR);
190*10465441SEvalZero ent = uffs_readdir(dirp);
191*10465441SEvalZero while (ent) {
192*10465441SEvalZero MSG("%9s", ent->d_name);
193*10465441SEvalZero strcpy(buf, name);
194*10465441SEvalZero sub = buf;
195*10465441SEvalZero if (name[strlen(name)-1] != '/')
196*10465441SEvalZero sub = strcat(buf, "/");
197*10465441SEvalZero sub = strcat(sub, ent->d_name);
198*10465441SEvalZero if (ent->d_type & FILE_ATTR_DIR) {
199*10465441SEvalZero sub = strcat(sub, "/");
200*10465441SEvalZero MSG("/ \t<%8d>", CountObjectUnder(sub));
201*10465441SEvalZero }
202*10465441SEvalZero else {
203*10465441SEvalZero uffs_stat(sub, &stat_buf);
204*10465441SEvalZero MSG(" \t %8d ", stat_buf.st_size);
205*10465441SEvalZero }
206*10465441SEvalZero MSG("\t%6d" TENDSTR, ent->d_ino);
207*10465441SEvalZero count++;
208*10465441SEvalZero ent = uffs_readdir(dirp);
209*10465441SEvalZero }
210*10465441SEvalZero
211*10465441SEvalZero uffs_closedir(dirp);
212*10465441SEvalZero
213*10465441SEvalZero MSG("Total: %d objects." TENDSTR, count);
214*10465441SEvalZero }
215*10465441SEvalZero
216*10465441SEvalZero return ret;
217*10465441SEvalZero }
218*10465441SEvalZero
219*10465441SEvalZero /** rm <obj> */
cmd_rm(int argc,char * argv[])220*10465441SEvalZero static int cmd_rm(int argc, char *argv[])
221*10465441SEvalZero {
222*10465441SEvalZero const char *name = NULL;
223*10465441SEvalZero int ret = 0;
224*10465441SEvalZero struct uffs_stat st;
225*10465441SEvalZero
226*10465441SEvalZero CHK_ARGC(2, 2);
227*10465441SEvalZero
228*10465441SEvalZero name = argv[1];
229*10465441SEvalZero
230*10465441SEvalZero ret = uffs_stat(name, &st);
231*10465441SEvalZero if (ret < 0) {
232*10465441SEvalZero MSGLN("Can't stat '%s'", name);
233*10465441SEvalZero return ret;
234*10465441SEvalZero }
235*10465441SEvalZero
236*10465441SEvalZero if (st.st_mode & US_IFDIR) {
237*10465441SEvalZero ret = uffs_rmdir(name);
238*10465441SEvalZero }
239*10465441SEvalZero else {
240*10465441SEvalZero ret = uffs_remove(name);
241*10465441SEvalZero }
242*10465441SEvalZero
243*10465441SEvalZero if (ret == 0)
244*10465441SEvalZero MSGLN("Delete '%s' succ.", name);
245*10465441SEvalZero else
246*10465441SEvalZero MSGLN("Delete '%s' fail!", name);
247*10465441SEvalZero
248*10465441SEvalZero return ret;
249*10465441SEvalZero }
250*10465441SEvalZero
251*10465441SEvalZero /** ren|mv <old> <new> */
cmd_ren(int argc,char * argv[])252*10465441SEvalZero static int cmd_ren(int argc, char *argv[])
253*10465441SEvalZero {
254*10465441SEvalZero const char *oldname;
255*10465441SEvalZero const char *newname;
256*10465441SEvalZero int ret;
257*10465441SEvalZero
258*10465441SEvalZero CHK_ARGC(3, 3);
259*10465441SEvalZero
260*10465441SEvalZero oldname = argv[1];
261*10465441SEvalZero newname = argv[2];
262*10465441SEvalZero
263*10465441SEvalZero if ((ret = uffs_rename(oldname, newname)) == 0) {
264*10465441SEvalZero MSGLN("Rename from '%s' to '%s' succ.", oldname, newname);
265*10465441SEvalZero }
266*10465441SEvalZero else {
267*10465441SEvalZero MSGLN("Rename from '%s' to '%s' fail!", oldname, newname);
268*10465441SEvalZero }
269*10465441SEvalZero
270*10465441SEvalZero return ret;
271*10465441SEvalZero }
272*10465441SEvalZero
dump_msg_to_stdout(struct uffs_DeviceSt * dev,const char * fmt,...)273*10465441SEvalZero static void dump_msg_to_stdout(struct uffs_DeviceSt *dev, const char *fmt, ...)
274*10465441SEvalZero {
275*10465441SEvalZero uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
276*10465441SEvalZero va_list args;
277*10465441SEvalZero
278*10465441SEvalZero va_start(args, fmt);
279*10465441SEvalZero //vprintf(fmt, args);
280*10465441SEvalZero if (emu && emu->dump_fp)
281*10465441SEvalZero vfprintf(emu->dump_fp, fmt, args);
282*10465441SEvalZero va_end(args);
283*10465441SEvalZero }
284*10465441SEvalZero
285*10465441SEvalZero /** dump [<mount>] */
cmd_dump(int argc,char * argv[])286*10465441SEvalZero static int cmd_dump(int argc, char *argv[])
287*10465441SEvalZero {
288*10465441SEvalZero uffs_Device *dev;
289*10465441SEvalZero uffs_FileEmu *emu;
290*10465441SEvalZero const char *mount = "/";
291*10465441SEvalZero const char *dump_file = "dump.txt";
292*10465441SEvalZero
293*10465441SEvalZero if (argc > 1) {
294*10465441SEvalZero mount = argv[1];
295*10465441SEvalZero if (argc > 2)
296*10465441SEvalZero dump_file = argv[2];
297*10465441SEvalZero }
298*10465441SEvalZero
299*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
300*10465441SEvalZero if (dev == NULL) {
301*10465441SEvalZero MSGLN("Can't get device from mount point %s", mount);
302*10465441SEvalZero return -1;
303*10465441SEvalZero }
304*10465441SEvalZero
305*10465441SEvalZero emu = (uffs_FileEmu *)(dev->attr->_private);
306*10465441SEvalZero emu->dump_fp = fopen(dump_file, "w");
307*10465441SEvalZero
308*10465441SEvalZero uffs_DumpDevice(dev, dump_msg_to_stdout);
309*10465441SEvalZero
310*10465441SEvalZero if (emu->dump_fp)
311*10465441SEvalZero fclose(emu->dump_fp);
312*10465441SEvalZero
313*10465441SEvalZero uffs_PutDevice(dev);
314*10465441SEvalZero
315*10465441SEvalZero return 0;
316*10465441SEvalZero }
317*10465441SEvalZero
318*10465441SEvalZero /** st [<mount>] */
cmd_st(int argc,char * argv[])319*10465441SEvalZero static int cmd_st(int argc, char *argv[])
320*10465441SEvalZero {
321*10465441SEvalZero uffs_Device *dev;
322*10465441SEvalZero const char *mount = "/";
323*10465441SEvalZero uffs_FlashStat *s;
324*10465441SEvalZero TreeNode *node;
325*10465441SEvalZero
326*10465441SEvalZero if (argc > 1) {
327*10465441SEvalZero mount = argv[1];
328*10465441SEvalZero }
329*10465441SEvalZero
330*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
331*10465441SEvalZero if (dev == NULL) {
332*10465441SEvalZero MSGLN("Can't get device from mount point %s", mount);
333*10465441SEvalZero return -1;
334*10465441SEvalZero }
335*10465441SEvalZero
336*10465441SEvalZero s = &(dev->st);
337*10465441SEvalZero
338*10465441SEvalZero MSG("----------- basic info -----------" TENDSTR);
339*10465441SEvalZero MSG("TreeNode size: %d" TENDSTR, sizeof(TreeNode));
340*10465441SEvalZero MSG("TagStore size: %d" TENDSTR, sizeof(struct uffs_TagStoreSt));
341*10465441SEvalZero MSG("MaxCachedBlockInfo: %d" TENDSTR, dev->cfg.bc_caches);
342*10465441SEvalZero MSG("MaxPageBuffers: %d" TENDSTR, dev->cfg.page_buffers);
343*10465441SEvalZero MSG("MaxDirtyPagesPerBlock: %d" TENDSTR, dev->cfg.dirty_pages);
344*10465441SEvalZero MSG("MaxPathLength: %d" TENDSTR, MAX_PATH_LENGTH);
345*10465441SEvalZero MSG("MaxObjectHandles: %d" TENDSTR, MAX_OBJECT_HANDLE);
346*10465441SEvalZero MSG("FreeObjectHandles: %d" TENDSTR, uffs_GetFreeObjectHandlers());
347*10465441SEvalZero MSG("MaxDirHandles: %d" TENDSTR, MAX_DIR_HANDLE);
348*10465441SEvalZero MSG("FreeDirHandles: %d" TENDSTR, uffs_PoolGetFreeCount(uffs_DirEntryBufGetPool()));
349*10465441SEvalZero
350*10465441SEvalZero MSG("----------- statistics for '%s' -----------" TENDSTR, mount);
351*10465441SEvalZero MSG("Device Ref: %d" TENDSTR, dev->ref_count);
352*10465441SEvalZero MSG("Block Erased: %d" TENDSTR, s->block_erase_count);
353*10465441SEvalZero MSG("Write Page: %d" TENDSTR, s->page_write_count);
354*10465441SEvalZero MSG("Write Spare: %d" TENDSTR, s->spare_write_count);
355*10465441SEvalZero MSG("Read Page: %d" TENDSTR, s->page_read_count - s->page_header_read_count);
356*10465441SEvalZero MSG("Read Header: %d" TENDSTR, s->page_header_read_count);
357*10465441SEvalZero MSG("Read Spare: %d" TENDSTR, s->spare_read_count);
358*10465441SEvalZero MSG("I/O Read: %lu" TENDSTR, s->io_read);
359*10465441SEvalZero MSG("I/O Write: %lu" TENDSTR, s->io_write);
360*10465441SEvalZero
361*10465441SEvalZero MSG("--------- partition info for '%s' ---------" TENDSTR, mount);
362*10465441SEvalZero MSG("Space total: %d" TENDSTR, uffs_GetDeviceTotal(dev));
363*10465441SEvalZero MSG("Space used: %d" TENDSTR, uffs_GetDeviceUsed(dev));
364*10465441SEvalZero MSG("Space free: %d" TENDSTR, uffs_GetDeviceFree(dev));
365*10465441SEvalZero MSG("Page Size: %d" TENDSTR, dev->attr->page_data_size);
366*10465441SEvalZero MSG("Spare Size: %d" TENDSTR, dev->attr->spare_size);
367*10465441SEvalZero MSG("Pages Per Block: %d" TENDSTR, dev->attr->pages_per_block);
368*10465441SEvalZero MSG("Block size: %d" TENDSTR, dev->attr->page_data_size * dev->attr->pages_per_block);
369*10465441SEvalZero MSG("Total blocks: %d of %d" TENDSTR, (dev->par.end - dev->par.start + 1), dev->attr->total_blocks);
370*10465441SEvalZero if (dev->tree.bad) {
371*10465441SEvalZero MSG("Bad blocks: ");
372*10465441SEvalZero node = dev->tree.bad;
373*10465441SEvalZero while(node) {
374*10465441SEvalZero MSG("%d, ", node->u.list.block);
375*10465441SEvalZero node = node->u.list.next;
376*10465441SEvalZero }
377*10465441SEvalZero MSG(TENDSTR);
378*10465441SEvalZero }
379*10465441SEvalZero
380*10465441SEvalZero uffs_PutDevice(dev);
381*10465441SEvalZero
382*10465441SEvalZero return 0;
383*10465441SEvalZero
384*10465441SEvalZero }
385*10465441SEvalZero
386*10465441SEvalZero /** cp <src> <des> */
cmd_cp(int argc,char * argv[])387*10465441SEvalZero static int cmd_cp(int argc, char *argv[])
388*10465441SEvalZero {
389*10465441SEvalZero const char *src;
390*10465441SEvalZero const char *des;
391*10465441SEvalZero char buf[100];
392*10465441SEvalZero int fd1 = -1, fd2 = -1;
393*10465441SEvalZero int len;
394*10465441SEvalZero BOOL src_local = FALSE, des_local = FALSE;
395*10465441SEvalZero FILE *fp1 = NULL, *fp2 = NULL;
396*10465441SEvalZero int ret = -1;
397*10465441SEvalZero
398*10465441SEvalZero CHK_ARGC(3, 3);
399*10465441SEvalZero
400*10465441SEvalZero src = argv[1];
401*10465441SEvalZero des = argv[2];
402*10465441SEvalZero
403*10465441SEvalZero if (memcmp(src, "::", 2) == 0) {
404*10465441SEvalZero src += 2;
405*10465441SEvalZero src_local = TRUE;
406*10465441SEvalZero }
407*10465441SEvalZero if (memcmp(des, "::", 2) == 0) {
408*10465441SEvalZero des += 2;
409*10465441SEvalZero des_local = TRUE;
410*10465441SEvalZero }
411*10465441SEvalZero
412*10465441SEvalZero if (src_local) {
413*10465441SEvalZero if ((fp1 = fopen(src, "rb")) == NULL) {
414*10465441SEvalZero MSGLN("Can't open %s for copy.", src);
415*10465441SEvalZero goto fail_ext;
416*10465441SEvalZero }
417*10465441SEvalZero }
418*10465441SEvalZero else {
419*10465441SEvalZero if ((fd1 = uffs_open(src, UO_RDONLY)) < 0) {
420*10465441SEvalZero MSGLN("Can't open %s for copy.", src);
421*10465441SEvalZero goto fail_ext;
422*10465441SEvalZero }
423*10465441SEvalZero }
424*10465441SEvalZero
425*10465441SEvalZero if (des_local) {
426*10465441SEvalZero if ((fp2 = fopen(des, "wb")) == NULL) {
427*10465441SEvalZero MSGLN("Can't open %s for copy.", des);
428*10465441SEvalZero goto fail_ext;
429*10465441SEvalZero }
430*10465441SEvalZero }
431*10465441SEvalZero else {
432*10465441SEvalZero if ((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0) {
433*10465441SEvalZero MSGLN("Can't open %s for copy.", des);
434*10465441SEvalZero goto fail_ext;
435*10465441SEvalZero }
436*10465441SEvalZero }
437*10465441SEvalZero
438*10465441SEvalZero ret = 0;
439*10465441SEvalZero while ( (src_local ? (feof(fp1) == 0) : (uffs_eof(fd1) == 0)) ) {
440*10465441SEvalZero ret = -1;
441*10465441SEvalZero if (src_local) {
442*10465441SEvalZero len = fread(buf, 1, sizeof(buf), fp1);
443*10465441SEvalZero }
444*10465441SEvalZero else {
445*10465441SEvalZero len = uffs_read(fd1, buf, sizeof(buf));
446*10465441SEvalZero }
447*10465441SEvalZero if (len == 0) {
448*10465441SEvalZero ret = -1;
449*10465441SEvalZero break;
450*10465441SEvalZero }
451*10465441SEvalZero if (len < 0) {
452*10465441SEvalZero MSGLN("read file %s fail ?", src);
453*10465441SEvalZero break;
454*10465441SEvalZero }
455*10465441SEvalZero if (des_local) {
456*10465441SEvalZero if ((int)fwrite(buf, 1, len, fp2) != len) {
457*10465441SEvalZero MSGLN("write file %s fail ? ", des);
458*10465441SEvalZero break;
459*10465441SEvalZero }
460*10465441SEvalZero }
461*10465441SEvalZero else {
462*10465441SEvalZero if (uffs_write(fd2, buf, len) != len) {
463*10465441SEvalZero MSGLN("write file %s fail ? ", des);
464*10465441SEvalZero break;
465*10465441SEvalZero }
466*10465441SEvalZero }
467*10465441SEvalZero ret = 0;
468*10465441SEvalZero }
469*10465441SEvalZero
470*10465441SEvalZero fail_ext:
471*10465441SEvalZero if (fd1 > 0)
472*10465441SEvalZero uffs_close(fd1);
473*10465441SEvalZero if (fd2 > 0)
474*10465441SEvalZero uffs_close(fd2);
475*10465441SEvalZero if (fp1)
476*10465441SEvalZero fclose(fp1);
477*10465441SEvalZero if (fp2)
478*10465441SEvalZero fclose(fp2);
479*10465441SEvalZero
480*10465441SEvalZero return ret;
481*10465441SEvalZero }
482*10465441SEvalZero
483*10465441SEvalZero /** cat <file> [<offset>] [<size>] */
cmd_cat(int argc,char * argv[])484*10465441SEvalZero static int cmd_cat(int argc, char *argv[])
485*10465441SEvalZero {
486*10465441SEvalZero int fd;
487*10465441SEvalZero const char *name = NULL;
488*10465441SEvalZero char buf[100];
489*10465441SEvalZero int start = 0, size = 0, printed = 0, n, len;
490*10465441SEvalZero int ret = -1;
491*10465441SEvalZero
492*10465441SEvalZero CHK_ARGC(2, 4);
493*10465441SEvalZero
494*10465441SEvalZero name = argv[1];
495*10465441SEvalZero
496*10465441SEvalZero if ((fd = uffs_open(name, UO_RDONLY)) < 0) {
497*10465441SEvalZero MSGLN("Can't open %s", name);
498*10465441SEvalZero goto fail;
499*10465441SEvalZero }
500*10465441SEvalZero
501*10465441SEvalZero if (argc > 2) {
502*10465441SEvalZero start = strtol(argv[2], NULL, 10);
503*10465441SEvalZero if (argc > 3) size = strtol(argv[3], NULL, 10);
504*10465441SEvalZero }
505*10465441SEvalZero
506*10465441SEvalZero if (start >= 0)
507*10465441SEvalZero uffs_seek(fd, start, USEEK_SET);
508*10465441SEvalZero else
509*10465441SEvalZero uffs_seek(fd, -start, USEEK_END);
510*10465441SEvalZero
511*10465441SEvalZero while (uffs_eof(fd) == 0) {
512*10465441SEvalZero len = uffs_read(fd, buf, sizeof(buf) - 1);
513*10465441SEvalZero if (len == 0)
514*10465441SEvalZero break;
515*10465441SEvalZero if (len > 0) {
516*10465441SEvalZero if (size == 0 || printed < size) {
517*10465441SEvalZero n = (size == 0 ? len : (size - printed > len ? len : size - printed));
518*10465441SEvalZero buf[n] = 0;
519*10465441SEvalZero MSG("%s", buf);
520*10465441SEvalZero printed += n;
521*10465441SEvalZero }
522*10465441SEvalZero else {
523*10465441SEvalZero break;
524*10465441SEvalZero }
525*10465441SEvalZero }
526*10465441SEvalZero }
527*10465441SEvalZero MSG(TENDSTR);
528*10465441SEvalZero uffs_close(fd);
529*10465441SEvalZero
530*10465441SEvalZero ret = 0;
531*10465441SEvalZero fail:
532*10465441SEvalZero
533*10465441SEvalZero return ret;
534*10465441SEvalZero }
535*10465441SEvalZero
536*10465441SEvalZero /** mount partition or show mounted partitions
537*10465441SEvalZero * mount [<mount>]
538*10465441SEvalZero */
cmd_mount(int argc,char * argv[])539*10465441SEvalZero static int cmd_mount(int argc, char *argv[])
540*10465441SEvalZero {
541*10465441SEvalZero uffs_MountTable *tab;
542*10465441SEvalZero const char *mount = NULL;
543*10465441SEvalZero
544*10465441SEvalZero if (argc == 1) {
545*10465441SEvalZero tab = uffs_MtbGetMounted();
546*10465441SEvalZero while (tab) {
547*10465441SEvalZero MSG(" %s : (%d) ~ (%d)\n", tab->mount, tab->start_block, tab->end_block);
548*10465441SEvalZero tab = tab->next;
549*10465441SEvalZero }
550*10465441SEvalZero }
551*10465441SEvalZero else {
552*10465441SEvalZero mount = argv[1];
553*10465441SEvalZero if (uffs_Mount(mount) < 0) {
554*10465441SEvalZero MSGLN("Can't mount %s", mount);
555*10465441SEvalZero return -1;
556*10465441SEvalZero }
557*10465441SEvalZero }
558*10465441SEvalZero return 0;
559*10465441SEvalZero }
560*10465441SEvalZero
561*10465441SEvalZero /** unmount parition or show unmounted partitions
562*10465441SEvalZero * umount [<mount>]
563*10465441SEvalZero */
cmd_unmount(int argc,char * argv[])564*10465441SEvalZero static int cmd_unmount(int argc, char *argv[])
565*10465441SEvalZero {
566*10465441SEvalZero uffs_MountTable *tab;
567*10465441SEvalZero const char *mount = NULL;
568*10465441SEvalZero
569*10465441SEvalZero if (argc == 1) {
570*10465441SEvalZero tab = uffs_MtbGetUnMounted();
571*10465441SEvalZero while (tab) {
572*10465441SEvalZero MSG(" %s : (%d) ~ (%d)\n", tab->mount, tab->start_block, tab->end_block);
573*10465441SEvalZero tab = tab->next;
574*10465441SEvalZero }
575*10465441SEvalZero }
576*10465441SEvalZero else {
577*10465441SEvalZero mount = argv[1];
578*10465441SEvalZero if (uffs_UnMount(mount) < 0) {
579*10465441SEvalZero MSGLN("Can't unmount %s", mount);
580*10465441SEvalZero return -1;
581*10465441SEvalZero }
582*10465441SEvalZero }
583*10465441SEvalZero
584*10465441SEvalZero return 0;
585*10465441SEvalZero }
586*10465441SEvalZero
587*10465441SEvalZero /** inspect buffers
588*10465441SEvalZero * inspb [<mount>]
589*10465441SEvalZero */
cmd_inspb(int argc,char * argv[])590*10465441SEvalZero static int cmd_inspb(int argc, char *argv[])
591*10465441SEvalZero {
592*10465441SEvalZero uffs_Device *dev;
593*10465441SEvalZero const char *mount = "/";
594*10465441SEvalZero
595*10465441SEvalZero CHK_ARGC(1, 2);
596*10465441SEvalZero
597*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
598*10465441SEvalZero if (dev == NULL) {
599*10465441SEvalZero MSGLN("Can't get device from mount point %s", mount);
600*10465441SEvalZero return -1;
601*10465441SEvalZero }
602*10465441SEvalZero uffs_BufInspect(dev);
603*10465441SEvalZero uffs_PutDevice(dev);
604*10465441SEvalZero
605*10465441SEvalZero return 0;
606*10465441SEvalZero
607*10465441SEvalZero }
608*10465441SEvalZero
609*10465441SEvalZero /** print block wear-leveling information
610*10465441SEvalZero * wl [<mount>]
611*10465441SEvalZero */
cmd_wl(int argc,char * argv[])612*10465441SEvalZero static int cmd_wl(int argc, char *argv[])
613*10465441SEvalZero {
614*10465441SEvalZero const char *mount = "/";
615*10465441SEvalZero uffs_Device *dev;
616*10465441SEvalZero struct uffs_PartitionSt *par;
617*10465441SEvalZero uffs_FileEmu *emu;
618*10465441SEvalZero int i, max;
619*10465441SEvalZero u32 n;
620*10465441SEvalZero
621*10465441SEvalZero #define NUM_PER_LINE 10
622*10465441SEvalZero
623*10465441SEvalZero CHK_ARGC(1, 2);
624*10465441SEvalZero
625*10465441SEvalZero if (argc > 1) {
626*10465441SEvalZero mount = argv[1];
627*10465441SEvalZero }
628*10465441SEvalZero
629*10465441SEvalZero dev = uffs_GetDeviceFromMountPoint(mount);
630*10465441SEvalZero if (dev == NULL) {
631*10465441SEvalZero MSGLN("Can't get device from mount point %s", mount);
632*10465441SEvalZero return -1;
633*10465441SEvalZero }
634*10465441SEvalZero
635*10465441SEvalZero par = &dev->par;
636*10465441SEvalZero emu = (uffs_FileEmu *)(dev->attr->_private);
637*10465441SEvalZero max = -1;
638*10465441SEvalZero
639*10465441SEvalZero for (i = 0; i < par->end - par->start; i++) {
640*10465441SEvalZero if ((i % NUM_PER_LINE) == 0) {
641*10465441SEvalZero MSG("%04d:", i + par->start);
642*10465441SEvalZero }
643*10465441SEvalZero n = i + par->start;
644*10465441SEvalZero max = (max == -1 ? n :
645*10465441SEvalZero (emu->em_monitor_block[n] > emu->em_monitor_block[max] ? n : max)
646*10465441SEvalZero );
647*10465441SEvalZero MSG(" %4d", emu->em_monitor_block[n]);
648*10465441SEvalZero if (uffs_TreeFindBadNodeByBlock(dev, n))
649*10465441SEvalZero MSG("%c", 'x');
650*10465441SEvalZero else if (uffs_TreeFindErasedNodeByBlock(dev, n))
651*10465441SEvalZero MSG("%c", ' ');
652*10465441SEvalZero else
653*10465441SEvalZero MSG("%c", '.');
654*10465441SEvalZero if (((i + 1) % NUM_PER_LINE) == 0)
655*10465441SEvalZero MSG("\n");
656*10465441SEvalZero }
657*10465441SEvalZero MSG("\n");
658*10465441SEvalZero MSG("Total blocks %d, peak erase count %d at block %d\n",
659*10465441SEvalZero par->end - par->start, max == -1 ? 0 : emu->em_monitor_block[max], max);
660*10465441SEvalZero
661*10465441SEvalZero uffs_PutDevice(dev);
662*10465441SEvalZero
663*10465441SEvalZero return 0;
664*10465441SEvalZero }
665*10465441SEvalZero
666*10465441SEvalZero static const struct cli_command helper_cmds[] =
667*10465441SEvalZero {
668*10465441SEvalZero { cmd_format, "format", "[<mount>]", "Format device" },
669*10465441SEvalZero { cmd_mkf, "mkfile", "<name>", "create a new file" },
670*10465441SEvalZero { cmd_mkdir, "mkdir", "<name>", "create a new directory" },
671*10465441SEvalZero { cmd_rm, "rm", "<name>", "delete file/directory" },
672*10465441SEvalZero { cmd_ren, "mv|ren", "<old> <new>", "rename file/directory" },
673*10465441SEvalZero { cmd_ls, "ls", "<dir>", "list dirs and files" },
674*10465441SEvalZero { cmd_st, "info|st", "<mount>", "show statistic infomation" },
675*10465441SEvalZero { cmd_cp, "cp", "<src> <des>", "copy files. the local file name start with '::'" },
676*10465441SEvalZero { cmd_cat, "cat", "<name>", "show file content" },
677*10465441SEvalZero { cmd_pwd, "pwd", NULL, "show current dir" },
678*10465441SEvalZero { cmd_cd, "cd", "<path>", "change current dir" },
679*10465441SEvalZero { cmd_mount, "mount", "[<mount>]", "mount partition or list mounted partitions" },
680*10465441SEvalZero { cmd_unmount, "umount", "[<mount>]", "unmount partition" },
681*10465441SEvalZero { cmd_dump, "dump", "[<mount>]", "dump file system", },
682*10465441SEvalZero { cmd_wl, "wl", "[<mount>]", "show block wear-leveling info", },
683*10465441SEvalZero { cmd_inspb, "inspb", "[<mount>]", "inspect buffer", },
684*10465441SEvalZero { NULL, NULL, NULL, NULL }
685*10465441SEvalZero };
686*10465441SEvalZero
687*10465441SEvalZero static struct cli_commandset helper_cmdset = {
688*10465441SEvalZero helper_cmds,
689*10465441SEvalZero };
690*10465441SEvalZero
get_helper_cmds()691*10465441SEvalZero struct cli_commandset * get_helper_cmds()
692*10465441SEvalZero {
693*10465441SEvalZero return &helper_cmdset;
694*10465441SEvalZero };
695