📄 tfscli.c
字号:
/* tfscli.c: * This file contains the TFS code that is only needed if the "tfs" command * is included in the command set. * * General notice: * This code is part of a boot-monitor package developed as a generic base * platform for embedded system designs. As such, it is likely to be * distributed to various projects beyond the control of the original * author. Please notify the author of any enhancements made or bugs found * so that all may benefit from the changes. In addition, notification back * to the author will allow the new user to pick up changes that may have * been made by other users after this version of the code was distributed. * * Note1: the majority of this code was edited with 4-space tabs. * Note2: as more and more contributions are accepted, the term "author" * is becoming a mis-representation of credit. * * Original author: Ed Sutter * Email: esutter@lucent.com * Phone: 908-582-2351 */#include "config.h"#include "stddefs.h"#include "genlib.h"#include "tfs.h"#include "tfsprivate.h"#include "cli.h"#if INCLUDE_TFSCLI/* tfsprflags(): * Print the specified set of flags. */static voidtfsprflags(long flags, int verbose){ struct tfsflg *tfp; if (verbose) printf(" Flags: "); tfp = tfsflgtbl; while(tfp->sdesc) { if ((flags & tfp->mask) == tfp->flag) { if (verbose) { printf("%s", tfp->ldesc); if ((tfp+1)->flag) printf(", "); } else putchar(tfp->sdesc); } tfp++; } if (!(flags & TFS_NSTALE)) printf("stale"); if (verbose) printf("\n");}static char *tfsmodebtoa(ulong mode,char *buf){ char *pipe, *bp; pipe = ""; bp = buf; *bp = 0; if (mode & TFS_RDONLY) { bp += sprintf(bp,"rdonly"); pipe = "|"; } if (mode & TFS_CREATE) { bp += sprintf(bp,"%screate",pipe); pipe = "|"; } if (mode & TFS_APPEND) sprintf(bp,"%sappend",pipe); return(buf);}/* tfsld(): * If the filename specified is AOUT, COFF or ELF, then load it. */static inttfsld(char *name,int verbose,int verifyonly){ int err; TFILE *fp; err = TFS_OKAY; fp = tfsstat(name); if (!fp) return (TFSERR_NOFILE); if (TFS_USRLVL(fp) > getUsrLvl()) return(TFSERR_USERDENIED); if (fp->flags & TFS_EBIN) { long entry; err = tfsloadebin(fp,verbose,&entry,verifyonly); if (err == TFS_OKAY) { char buf[16]; sprintf(buf,"0x%lx",entry); setenv("ENTRYPOINT",buf); } else setenv("ENTRYPOINT",0); } else { err = TFSERR_BADHDR; } return(err);}/* listfilter(): * If the incoming filename (fname) passes the incoming filter, then * return 1; else return 0. * * Examples: * if filter is "*.html" and fname is "index.html" return 1. * if filter is "dir SLASH ASTERISK" and fname is "dir/abc" return 1. * if filter is "abc" and fname is "abc" return 1. * * Notes: * * A valid filter will have the asterisk as either the first or last * character of the filter. If first, assume filter is a suffix, * if last (or none at all), assume filter is a prefix. * * If there is an asterisk in the middle of the filter, it is chopped * at the asterisk without warning. */static intlistfilter(char *filter,char *fname){ int flen; char *prefix, *suffix, *asterisk, *sp; if (!filter) /* No filter means match everything. */ return(1); flen = 0; prefix = suffix = (char *)0; asterisk = strchr(filter,'*'); /* If no asterisk, then just compare filter to fname... */ if (!asterisk) { if (!strcmp(filter,fname)) return(1); } else if (asterisk == filter) { suffix = asterisk+1; flen = strlen(suffix); sp = fname + strlen(fname) - flen; if (!strcmp(suffix,sp)) return(1); } else { *asterisk = 0; prefix = filter; flen = strlen(prefix); if (!strncmp(prefix,fname,flen)) { *asterisk = '*'; return(1); } *asterisk = '*'; } return(0);}/* tfsvlist(): verbose list... * Display all files currently stored. Do not put them in alphabetical * order; display them as they are physically listed in the file system. * Display complete structure of file header for each file. * Note1: This version of file listing is only called if "tfs -vv ls" * or "tfs -vvv ls" is called. The first level of verbosity is handled * by tfsqlist to simply display the "dot" files. */static inttfsvlist(char *filter[], int verbose, int more){ TDEV *tdp; TFILE *fp; int tot, sizetot; char tbuf[32], **fltrptr; tot = 0; sizetot = 0; for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) { fltrptr = filter; while(1) { fp = (TFILE *)tdp->start; while(validtfshdr(fp)) { int start_sector, end_sector; if ((TFS_DELETED(fp)) && (verbose < 3)) { fp = nextfp(fp,tdp); continue; } if (!listfilter(*fltrptr,TFS_NAME(fp))) { fp = nextfp(fp,tdp); continue; } if ((fp->flags & TFS_UNREAD) && (TFS_USRLVL(fp)>getUsrLvl())) { fp = nextfp(fp,tdp); continue; } printf(" Name: '%s'%s\n", fp->name,TFS_DELETED(fp) ? " (deleted)" : ""); printf(" Info: '%s'\n", fp->info); if (TFS_FILEEXISTS(fp)) tfsprflags(fp->flags, 1); printf(" Addr: 0x%lx (hdr @ 0x%lx, nxtptr = 0x%lx)\n", (ulong)(TFS_BASE(fp)),(ulong)fp,(ulong)(fp->next)); printf(" Size: %ld bytes",fp->filsize); addrtosector((char *)fp,&start_sector,0,0); addrtosector((char *)fp+fp->filsize+TFSHDRSIZ,&end_sector,0,0); if (start_sector == end_sector) { printf(" (in sector %d)\n",start_sector); } else { printf(" (spanning sectors %d-%d)\n", start_sector,end_sector); } sizetot += (fp->filsize + TFSHDRSIZ + DEFRAGHDRSIZ); if (TFS_TIME(fp) != TIME_UNDEFINED) printf(" Time: %s\n", tfsGetAtime(TFS_TIME(fp),tbuf,sizeof(tbuf))); printf("\n"); tot++; fp = nextfp(fp,tdp); if ((more) && ((tot % more) == 0)) { if (!More()) return(TFS_OKAY); } } /* If this or the next pointer is null, terminate loop now... */ if (!*fltrptr) break; fltrptr++; if (!*fltrptr) break; } } printf("Total: %d accessible file%s (%d bytes).\n", tot,tot == 1 ? "" : "s",sizetot); return (TFS_OKAY);}/* tfsqlist(): quick list... * Display list of files in alphabetical order. * Display only the name and flag summary. * * To support listing of files in a bit of an orderly manner, if this * function sees that a filename has a slash in it, it will only print the * characters upto and including the first slash. This gives the appearance * of a directory structure, even though there really isn't one. * For example, if there are three files... * CONFIG/file1 * CONFIG/file2 * CONFIG/file3 * then if no filter is specified, then that listing will be replaced with * CONFIG/ * printed only once. To display all the files prefixed with CONFIG/, the * user must type "tfs ls CONFIG/\*". * * Note: a file with a leading dot ('.') is invisible unless verbose is set. */static inttfsqlist(char *filter[], int verbose, int more){ TFILE *fp; char dirname[TFSNAMESIZE+1], tmpname[TFSNAMESIZE+1]; char *name, fbuf[16], **fltrptr, *slash, *flags; int idx, sidx, filelisted, err, sizetot; if ((err = tfsreorder()) < 0) return(err); filelisted = 0; sizetot = 0; dirname[0] = 0; fltrptr = filter; printf(" Name Size Location Flags Info\n"); while(1) { idx = 0; while((fp = tfsAlist[idx])) { name = TFS_NAME(fp); if (((name[0] == '.') && (!verbose)) || (!listfilter(*fltrptr,name)) || ((fp->flags & TFS_UNREAD) && (TFS_USRLVL(fp) > getUsrLvl()))) { idx++; continue; } /* If name contains a slash, process it differently (but ignore */ /* any leading slashes) */ strcpy(tmpname,TFS_NAME(fp)); for(sidx=0;sidx<TFSNAMESIZE;sidx++) { if (tmpname[sidx] != '/') break; } slash = strchr(&tmpname[sidx],'/'); if (slash && !*fltrptr) { char tmp; tmp = *(slash+1); *(slash+1) = 0; if (strcmp(dirname,tmpname)) { filelisted++; printf(" %-34s (dir)\n",tmpname); strcpy(dirname,tmpname); *(slash+1) = tmp; } else { idx++; *(slash+1) = tmp; continue; } } else { filelisted++; sizetot += TFS_SIZE(fp); flags = tfsflagsbtoa(TFS_FLAGS(fp),fbuf); if ((!flags) || (!fbuf[0])) flags = " "; printf(" %-23s %7ld 0x%08lx %-5s %s\n",TFS_NAME(fp), TFS_SIZE(fp),(ulong)(TFS_BASE(fp)),flags,TFS_INFO(fp)); } idx++; if ((more) && !(filelisted % more)) { if (!More()) return(TFS_OKAY); } } /* If this or the next pointer is null, terminate loop now... */ if (!*fltrptr) break; fltrptr++; if (!*fltrptr) break; } printf("\nTotal: %d item%s listed (%d bytes).\n",filelisted, filelisted == 1 ? "" : "s",sizetot); return (TFS_OKAY);}/* tfsrm(): * Remove all files that pass the incoming filter. * This replaces the older tfs rm stuff in Tfs(). */static inttfsrm(char *filter[]){ TFILE *fp; char *name, **fltrptr; int idx, err, rmtot; if ((err = tfsreorder()) < 0) return(err); fltrptr = filter; while (*fltrptr) { idx = rmtot = 0; while((fp = tfsAlist[idx])) { name = TFS_NAME(fp); if (listfilter(*fltrptr,name)) { if ((err = tfsunlink(name)) != TFS_OKAY) printf("%s: %s\n",name,(char *)tfsctrl(TFS_ERRMSG,err,0)); rmtot++; } idx++; } /* This function will potentially delete many files, but if the */ /* filter doesn't match at least one file, indicate that... */ if (!rmtot) printf("%s: file not found\n",*fltrptr); fltrptr++; } return(TFS_OKAY);}/* tfscat(): * Print each character of the file until NULL terminate. Replace * each instance of CR or LF with CRLF. */static voidtfscat(TFILE *fp, int more){ int i, lcnt; char *cp; lcnt = 0; cp = (char *) (TFS_BASE(fp)); for(i=0;i<fp->filsize;i++) { putchar(*cp); if ((*cp == '\r') || (*cp == '\n')) { lcnt++; if (lcnt == more) { if (More() == 0) break; lcnt = 0; } } cp++; }}intdumpFhdr(TFILE *fhp){ int crcok; if (tfshdrcrc(fhp) == fhp->hdrcrc) crcok = 1; else crcok = 0; printf("hdrsize: 0x%04x (%s)\n",fhp->hdrsize, fhp->hdrsize == TFSHDRSIZ ? "ok" : "bad"); printf("hdrvrsn: 0x%04x\n",fhp->hdrvrsn); printf("filsize: 0x%08lx\n",fhp->filsize); printf("flags : 0x%08lx\n",fhp->flags);#if 0 printf("filcrc : 0x%08lx (%s)\n",fhp->filcrc, crc32((uchar *)(fhp+1),fhp->filsize) == fhp->filcrc ? "ok" : "bad");#else printf("filcrc : 0x%08lx\n",fhp->filcrc);#endif printf("hdrcrc : 0x%08lx (%s)\n",fhp->hdrcrc,crcok ? "ok" : "bad"); printf("modtime: 0x%08lx\n",fhp->modtime); printf("next : 0x%08lx\n",(ulong)fhp->next); if (crcok) { printf("name : %s\n",fhp->name); printf("info : %s\n",fhp->info ? fhp->info : ""); } else { printf("name at: 0x%08lx\n",(ulong)fhp->name); printf("info at: 0x%08lx\n",(ulong)fhp->info); } printf("data at: 0x%08lx\n",(ulong)(fhp+1)); return(TFS_OKAY);}char *TfsHelp[] = { "Tiny File System Interface", "-[df:i:mv] operation [args]...", "", "Options:", " -d tfs device", " -f flags (see below)", " -i info", " -m enable more throttle", " -v enable verbosity", " -x set exit flag if error",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -