⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfscli.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -