예제 #1
0
/*
 * trunctest():
 *	Test file truncation.  Verify that file truncates to expected size
 *	and that the data in the file is as expected.
 */
int
trunctest(char *fname, char *data)
{
	int	tfd, err, size;
	TFILE	*tfp;

	/* Copy incoming file name to a tempoary file... */
	cp(TMPFILE,fname);

	/* Open the temporary file and truncate it.
	 * First verify that a truncation size too big will fail, then
	 * do a real truncation.  Close the file then verify that the
	 * file has been trunated.
	 */
	tfd = mon_tfsopen(TMPFILE,TFS_APPEND,buffer1);
	if (tfd < 0)
		tfsdie(tfd);
	err = mon_tfstruncate(tfd,9999999);
	if (err != TFSERR_BADARG)
		tfsdie(err);
	err = mon_tfstruncate(tfd,TRUNCATE_SIZE);
	if (err != TFS_OKAY)
		tfsdie(err);
	err = mon_tfsclose(tfd,0);
	if (err < 0)
		tfsdie(err);

	/* Make sure that the file was truncated to the proper size. */
	tfp = mon_tfsstat(TMPFILE);
	if (!tfp)
		die();
	if (TFS_SIZE(tfp) != TRUNCATE_SIZE)
		die();
	
	/* Now reopen the file and verify that the data is correct... */
	tfd = mon_tfsopen(TMPFILE,TFS_RDONLY,0);
	if (tfd < 0)
		tfsdie(tfd);
	
	size = mon_tfsread(tfd,buffer1,TFS_SIZE(tfp));
	if (size != TFS_SIZE(tfp))
		tfsdie(size);

	if (memcmp(buffer1,data,TRUNCATE_SIZE))
		die();

	/* Close and remove the temporary file. */
	mon_tfsclose(tfd,0);
	err = mon_tfsunlink(TMPFILE);
	if (err != TFS_OKAY)
		tfsdie(err);
	return(0);
}
예제 #2
0
/*
 *	cp():
 *	File Copy...
 *	Use standard TFS facilities to copy one file to another.
 *	If successful, return the size of the copy; else die.
 */
int
cp(char *to, char *from)
{
	TFILE	finfo, *tfp;
	int		ffd, tfd, size, ret;
	char	*buffer;

	/* Open the source file: */
	ffd = mon_tfsopen(from,TFS_RDONLY,0);
	if (ffd < 0)
		tfsdie(ffd);

	/* Retrieve stats of the source file: */
	tfp = &finfo;
	if (mon_tfsfstat(from,tfp) == -1)
		die();

	/* The buffer used to open the destination file must be as large as
	 * the source file ...
	 */
	buffer = mon_malloc(TFS_SIZE(tfp));
	if (!buffer)
		die();

	/* Open the destination file for creation with the same flags
	 * as the source file:
	 */
	tfd = mon_tfsopen(to,TFS_CREATE | finfo.flags,buffer);
	if (tfd < 0)
		tfsdie(tfd);

	/* Read the entire source file into buffer, then write the entire
	 * buffer to the destination file...
	 */
	size = mon_tfsread(ffd,buffer,TFS_SIZE(tfp));
	if (size < 0)  
		tfsdie(size);
	ret = mon_tfswrite(tfd,buffer,TFS_SIZE(tfp));
	if (ret != TFS_OKAY)
		tfsdie(ret);

	mon_tfsclose(ffd,0);
	mon_tfsclose(tfd,finfo.info);
	mon_free(buffer);
	return(TFS_SIZE(tfp));
}
예제 #3
0
/*
 *	cmp():
 *	File Compare...
 *	Use the standard TFS facilities to compare two different incoming files.
 *	Return 0 if files match, else -1.
 */
int
cmp(char *f1, char *f2)
{
	TFILE	finfo1, *tfp1;
	TFILE	finfo2, *tfp2;
	int		fd1, fd2, size, ret;
	char	*buf1, *buf2;

	/* Check sizes first: */
	tfp1 = &finfo1;
	if (mon_tfsfstat(f1,tfp1) == -1)
		die();
	tfp2 = &finfo2;
	if (mon_tfsfstat(f2,tfp2) == -1)
		die();
	if (tfp1->filsize != tfp2->filsize)
		return(-1);

	/* Copy f1 to buffer: */
	buf1 = mon_malloc(TFS_SIZE(tfp1));
	if (!buf1)
		die();
	fd1 = mon_tfsopen(f1,TFS_RDONLY,0);
	if (fd1 < 0)
		tfsdie(fd1);
	size = mon_tfsread(fd1,buf1,TFS_SIZE(tfp1));
	if (size != TFS_SIZE(tfp1))
		tfsdie(size);
	ret = mon_tfsclose(fd1,0);
	if (ret != TFS_OKAY)
		tfsdie(ret);

	/* Copy f2 to buffer: */
	buf2 = mon_malloc(TFS_SIZE(tfp2));
	if (!buf2)
		die();
	fd2 = mon_tfsopen(f2,TFS_RDONLY,0);
	if (fd2 < 0)
		tfsdie(fd2);
	size = mon_tfsread(fd2,buf2,TFS_SIZE(tfp2));
	if (size != TFS_SIZE(tfp2))
		tfsdie(size);
	ret = mon_tfsclose(fd2,0);
	if (ret != TFS_OKAY)
		tfsdie(ret);

	/* Compare the buffers: */
	if (memcmp(buf1,buf2,TFS_SIZE(tfp2)))
		ret = -1;
	else
		ret = 0;

	mon_free(buf1);
	mon_free(buf2);
	return(ret);
}
예제 #4
0
/* fatfsPut():
 * Copy data or file to a FATFS file.
 *
 * Input:
 * char *fatfspath
 *	Pointer to FATFS file and path.
 * char *src
 *	Pointer to TFS filename or a addr,len string.
 *	The expected "addr,len" syntax is 0xADDR,LEN or 0xADDR,0xLEN.
 */
static int
fatfsPut(char *src, char *fatfspath)
{
	FILEINFO fi;
	char tfs, *p, *cp;
	uint32_t successcount, len, size, rc;

	if (strncmp(src,"0x",2) == 0) {
		tfs = 0;
		p = (char *)strtoul(src,&cp,0);
		cp++;
		len = strtoul(cp,0,0);
	}
	else {
#if INCLUDE_TFS
		TFILE *tfp;

		tfs = 1;
		if ((tfp = tfsstat(src)) == 0) {
			printf("Can't find file '%s' in TFS\n",src);
			return(CMD_FAILURE);
		}
		p = TFS_BASE(tfp);
		len = TFS_SIZE(tfp);
#else
		printf("TFS not built in\n");
		return(-1);
#endif
	}

	/* Copy 'len' bytes from 'p' to DOSFS file 'fatfspath'...
	 */
	if (DFS_OpenFile(&vi, (uint8_t *)fatfspath, DFS_WRITE, sector, &fi)) {
		printf("error opening '%s'\n",fatfspath);
		return(-1);
	}

	while(len > 0) {
		if (len >= SECTOR_SIZE)
			size = SECTOR_SIZE;
		else
			size = len;

		rc = DFS_WriteFile(&fi, sector2, (uint8_t *)p, &successcount, size);
		if ((rc != DFS_OK) || (successcount != size)) {
			printf("error writing '%s'\n",fatfspath);
			return(-1);
		}
		p += size;
		len -= size;
	}
	return(0);
}
예제 #5
0
파일: fs.c 프로젝트: Pedersen175/DAN-uMon
int
fs_open(char *name, struct fs_file *file)
{
  TFILE *tfp;
  char *prefix, namebuf[TFSNAMESIZE+1];
  char *origname;

  /* Look for the specified file in TFS.  If found, then
   * return it; else return the nofile string above.
   */
  origname = name;
  prefix = mon_getenv(HTTP_PREFIX_VARNAME);
  if (prefix) {
    if ((strlen(name) + strlen(prefix) + 1) < sizeof(namebuf)) {
      mon_sprintf(namebuf,"%s%s",prefix,name);
      name = namebuf;
    }
  }
  tfp = mon_tfsstat(name);
  if (!tfp) {
    file->data = (char *)nofile;
    file->len = strlen(nofile);
  }
  else {
    /* If the file ends with ".html", then parse it for ${XXX} tokens.
     * and whenver XXX is a valid shell variable in uMon, replace the
     * ${XXX} with the content of the variable (see convert_vars() above).
     */
    if (strstr(name,".html")) {
      file->len = convert_vars(TFS_BASE(tfp),TFS_SIZE(tfp));
      file->data = filebuf;
    }
    else {
      file->data = TFS_BASE(tfp);
      file->len = TFS_SIZE(tfp);
    }
  }
  return(1);
}
예제 #6
0
/* appendtest():
 *	Create a file, then append to it and verify content after
 *	closing the file.
 */
int
appendtest(char *fname, char *data1, char *data2)
{
	TFILE	finfo, *tfp;
	int	err, tfd, len;

	/* Create the first version of the file:
	 */
	err = mon_tfsadd(fname,0,0,data1,strlen(data1));
	if (err != TFS_OKAY)
		tfsdie(err);

	/* Append to that first file:
	 */
	tfd = mon_tfsopen(fname,TFS_APPEND,buffer1);
	if (tfd < 0)
		tfsdie(tfd);

	err = mon_tfswrite(tfd,data2,strlen(data2));
	if (err != TFS_OKAY)
		tfsdie(err);
	
	err = mon_tfsclose(tfd,0);
	if (err != TFS_OKAY)
		tfsdie(err);

	/* Verify that the file was properly appended to:
	 */
	tfp = &finfo;
	if (mon_tfsfstat(fname,tfp) == -1)
		die();
	len = strlen(data1) + strlen(data2);
	if (len != TFS_SIZE(tfp))
		die();

	tfd = mon_tfsopen(fname,TFS_RDONLY,0);
	if (tfd < 0)
		tfsdie(tfd);

	err = mon_tfsread(tfd,buffer1,len);
	if (err != len)
		tfsdie(err);
	
	strcpy(buffer2,data1);
	strcat(buffer2,data2);
	if (memcmp(buffer1,buffer2,len) != 0)
		die();
	
	mon_tfsclose(tfd,0);
	return(0);
}
예제 #7
0
파일: nand.c 프로젝트: bengras/umon
int
nandCmd(int argc,char *argv[])
{
    unsigned long addr;
    char *cmd, *dest, *src;
    int opt, len, rc;

    rc = 0;
    nandVerbose = 0;
    while((opt=getopt(argc,argv,"v")) != -1) {
        switch(opt) {
        case 'v':
            nandVerbose++;
            break;
        default:
            return(CMD_PARAM_ERROR);
        }
    }

    if(argc < optind+1) {
        return(CMD_PARAM_ERROR);
    }

    cmd = argv[optind];

    if(nandVerbose) {
        printf("CMD: %s\n",cmd);
    }

    if(strcmp(cmd,"init") == 0) {
        nandInit();
    } else if(strcmp(cmd,"info") == 0) {
        nandInfo();
    } else if(strcmp(cmd,"erase") == 0) {
        if(argc != optind+3) {
            return(CMD_PARAM_ERROR);
        }
        addr = strtoul(argv[optind+1],0,0);
        len = (int)strtol(argv[optind+2],0,0);
        nandEraseChunk((char *)addr,len);
    } else if(strcmp(cmd,"write") == 0) {
        if(argc != optind+4) {
            return(CMD_PARAM_ERROR);
        }
        addr = strtoul(argv[optind+1],0,0);
        src = (char *)strtoul(argv[optind+2],0,0);
        len = (int)strtol(argv[optind+3],0,0);
        nandWriteChunk((char *)addr,src,len);
    } else if(strcmp(cmd,"read") == 0) {
        if(argc != optind+4) {
            return(CMD_PARAM_ERROR);
        }
        addr = strtoul(argv[optind+1],0,0);
        dest = (char *)strtoul(argv[optind+2],0,0);
        len = (int)strtol(argv[optind+3],0,0);
        nandReadChunk((char *)addr,dest,len);
    }
#ifdef FLASHRAM_BASE
    else if(strcmp(cmd,"tfsload") == 0) {
    } else if(strcmp(cmd,"tfsstore") == 0) {
    } else if(strcmp(cmd,"tfserase") == 0) {
    } else if(strcmp(cmd, "tfsls") == 0) {
        int ftot;
        char *addr;
        TFILE tfshdr, *fp;

        ftot = 0;
        fp = &tfshdr;
        addr = (char *)BASE_OF_NAND;
        while(addr < (char *)END_OF_NAND) {
            char fbuf[32], *flags;

            if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                printf("nandReadChunk failed %d\n",rc);
                break;
            }
            if(fp->hdrsize == 0xffff) {
                break;
            }
            if(TFS_FILEEXISTS(fp)) {
                if(ftot == 0) {
                    printf(" Name                        Size    Offset    Flags  Info\n");
                }
                ftot++;
                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),(unsigned long)(addr+TFSHDRSIZ),
                       flags,TFS_INFO(fp));
            }
            addr += TFS_SIZE(fp);
            addr += TFSHDRSIZ;
            while((long)addr & 0xf) {
                addr++;
            }
        }
    } else if(strcmp(cmd, "tfsrm") == 0) {
        char *addr;
        TFILE tfshdr, *fp;
        char *arg2 = argv[optind+1];

        fp = &tfshdr;
        addr = (char *)BASE_OF_NAND;
        while(addr < (char *)END_OF_NAND) {
            if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                printf("nandReadChunk failed %d\n",rc);
                break;
            }
            if(fp->hdrsize == 0xffff) {
                printf("%s not found\n",arg2);
                break;
            }
            if(strcmp(TFS_NAME(fp),arg2) == 0) {
                if(TFS_FILEEXISTS(fp)) {
                    fp->flags &= ~TFS_ACTIVE;
                    if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                        printf(" write_hdr failed %d\n",rc);
                    }
                    break;
                }
            }
            addr += TFS_SIZE(fp);
            addr += TFSHDRSIZ;
            while((long)addr & 0xf) {
                addr++;
            }
        }
    } else if(strcmp(cmd, "tfsadd") == 0) {
        int size;
        long    bflags;
        TFILE tfshdr, *fp;
        char *addr;
        char *src, *name, *info;
        char *arg2 = argv[optind+1];
        char *arg3 = argv[optind+2];
        char *arg4 = argv[optind+3];
        char *icomma, *fcomma;

        info = "";
        bflags = 0;
        name = arg2;
        addr = (char *)BASE_OF_NAND;

        /* The incoming arguments can be either just the filename (in which
         * case we assume the source is the file in TFS with the same name),
         * or the filename, source address and size...
         */
        if(argc == optind+2) {          // Just filename?
            if((fp = tfsstat(name)) == (TFILE *)0) {
                printf("File '%s' not in TFS\n",name);
                return(CMD_FAILURE);
            }
            name = fp->name;
            info = fp->info;
            bflags = fp->flags;
            size = fp->filsize;
            src = (char *)(fp + 1);
            fp = &tfshdr;
            memset((char *)fp,0,TFSHDRSIZ);
        } else if(argc == optind+4) {   // Filename with addr and len
            // Extract flags and info fields (if any) from the name...
            fcomma = strchr(name,',');
            if(fcomma) {
                icomma = strchr(fcomma+1,',');
                if(icomma) {
                    *icomma = 0;
                    info = icomma+1;
                }
                *fcomma = 0;
                bflags = tfsctrl(TFS_FATOB,(long)(fcomma+1),0);
            }

            fp = &tfshdr;
            memset((char *)fp,0,TFSHDRSIZ);
            size = (int)strtol(arg4,0,0);
            src = (char *)strtoul(arg3,0,0);
        } else {
            return(CMD_PARAM_ERROR);
        }

        while(addr < (char *)END_OF_NAND) {
            if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                break;
            }
            if(fp->hdrsize == 0xffff) {
                unsigned long nextfileaddr;

                /* We're at the address in NAND where we can add the new
                 * file, but first we need to make sure there's enough
                 * room...
                 */
                if((TFSHDRSIZ + size + 16) >= ((char *)END_OF_NAND - addr)) {
                    printf(" not enough space\n");
                    return(CMD_FAILURE);
                }

                /* Copy name and info data to header.
                 */
                strcpy(fp->name, name);
                strcpy(fp->info, info);
                fp->hdrsize = TFSHDRSIZ;
                fp->hdrvrsn = TFSHDRVERSION;
                fp->filsize = size;
                fp->flags = bflags;
                fp->flags |= (TFS_ACTIVE | TFS_NSTALE);
                fp->filcrc = crc32((unsigned char *)src,size);
                fp->modtime = tfsGetLtime();
#if TFS_RESERVED
                {
                    int rsvd;
                    for(rsvd=0; rsvd<TFS_RESERVED; rsvd++) {
                        fp->rsvd[rsvd] = 0xffffffff;
                    }
                }
#endif
                fp->next = 0;
                fp->hdrcrc = 0;
                fp->hdrcrc = crc32((unsigned char *)fp,TFSHDRSIZ);
                nextfileaddr = NAND_TFSRAM_BASE - NAND_TFS_BASE + (long)addr + TFSHDRSIZ + size;
                if(nextfileaddr & 0xf) {
                    nextfileaddr = (nextfileaddr | 0xf) + 1;
                }

                fp->next = (TFILE *)nextfileaddr;

                printf(" writing %s...\n",arg2);
                if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                    printf(" write_hdr failed %d\n",rc);
                }

                if((rc = nandWriteChunk(addr+TFSHDRSIZ,src,size)) < 0) {
                    printf(" write_file failed %d\n",rc);
                }
                break;
            }
            if(strcmp(TFS_NAME(fp),arg2) == 0) {
                if(TFS_FILEEXISTS(fp)) {
                    printf(" removing %s...\n",arg2);
                    fp->flags &= ~TFS_ACTIVE;
                    if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                        printf(" write_hdr failed %d\n",rc);
                    }
                }
            }
            addr += TFS_SIZE(fp);
            addr += TFSHDRSIZ;
            while((long)addr & 0xf) {
                addr++;
            }
        }
    } else if(strcmp(cmd, "tfsstat") == 0) {
        char *addr, *oaddr;
        TFILE tfshdr, *fp;
        unsigned long meminuse, memdead;

        fp = &tfshdr;
        meminuse = memdead = 0;
        addr = (char *)BASE_OF_NAND;
        while(addr < (char *)END_OF_NAND) {
            if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
                printf("nandReadChunk failed %d\n",rc);
                break;
            }
            if(fp->hdrsize == 0xffff) {
                break;
            }

            oaddr = addr;
            addr += TFS_SIZE(fp);
            addr += TFSHDRSIZ;
            while((long)addr & 0xf) {
                addr++;
            }

            if(TFS_FILEEXISTS(fp)) {
                meminuse += addr - oaddr;
            } else {
                memdead += addr - oaddr;
            }
        }
        printf("Total: 0x%x, used: 0x%x, dead: 0x%x, avail: 0x%x\n",
               SIZE_OF_NAND, meminuse, memdead,
               SIZE_OF_NAND - (meminuse + memdead));
    }
#endif
    else {
        return(CMD_PARAM_ERROR);
    }

    return(CMD_SUCCESS);
}
예제 #8
0
/* _tfsclean():
 *	This is an alternative to the complicated defragmentation above.
 *	It simply scans through the file list and copies all valid files
 *	to RAM; then flash is erased and the RAM is copied back to flash.
 *  <<< WARNING >>>
 *  THIS FUNCTION SHOULD NOT BE INTERRUPTED AND IT WILL BLOW AWAY
 *  ANY APPLICATION CURRENTLY IN CLIENT RAM SPACE.
 */
int
_tfsclean(TDEV *tdp, int notused, int verbose)
{
	ulong	appramstart;
	TFILE	*tfp, *lasttfp;
	uchar	*tbuf, *cp1, *cp2;
	int		dtot, nfadd, len, err, chkstat;

	if (TfsCleanEnable < 0)
		return(TFSERR_CLEANOFF);

	appramstart = getAppRamStart();

	/* Determine how many "dead" files exist. */
	dtot = 0;
	tfp = (TFILE *)tdp->start;
	while(validtfshdr(tfp)) {
		if (!TFS_FILEEXISTS(tfp))
			dtot++;
		tfp = nextfp(tfp,tdp);
	}

	if (dtot == 0)
		return(TFS_OKAY);

	printf("TFS device '%s' non-powersafe defragmentation\n",tdp->prefix);

	tbuf = (uchar *)appramstart;
	lasttfp = tfp = (TFILE *)(tdp->start);
	nfadd = tdp->start;
	while(validtfshdr(tfp)) {
		if (TFS_FILEEXISTS(tfp)) {
			len = TFS_SIZE(tfp) + sizeof(struct tfshdr);
			if (len % TFS_FSIZEMOD)
				len += TFS_FSIZEMOD - (len % TFS_FSIZEMOD);
			nfadd += len;
			if (s_memcpy((char *)tbuf,(char *)tfp,len,0,0) != 0)
				return(TFSERR_MEMFAIL);
			
			((struct tfshdr *)tbuf)->next = (struct tfshdr *)nfadd;
			tbuf += len;
		}
		lasttfp = tfp;
		tfp = nextfp(tfp,tdp);
	}

	/* We've now copied all of the active files from flash to ram.
	 * Now we want to see how much of the flash space needs to be
	 * erased.  We only need to erase the sectors that have changed...
	 */
	cp1 = (uchar *)tdp->start;
	cp2 = (uchar *)appramstart;
	while(cp2 < tbuf) {
		if (*cp1 != *cp2)
			break;
		cp1++; cp2++;
	}
#if INCLUDE_FLASH
	if ((cp2 != tbuf) || (!TFS_FILEEXISTS(lasttfp))) {
		int first, last;
		
		if (addrtosector(cp1,&first,0,0) == -1)
			return(TFSERR_FLASHFAILURE);
		
		if (addrtosector((uchar *)tdp->end,&last,0,0) == -1)
			return(TFSERR_FLASHFAILURE);
		printf("Erasing sectors %d-%d...\n",first,last);
		while(first<last) {
			if (flasherase(first++) == 0)
				return(TFSERR_FLASHFAILURE);
		}
	}
#endif

	/* Copy data placed in RAM back to flash: */
	printf("Restoring flash...\n");
	if (TFS_DEVTYPE_ISRAM(tdp)) {
		memcpy((char *)(tdp->start),(char *)appramstart,
			(tbuf-(uchar*)appramstart));
	}
	else {
#if INCLUDE_FLASH
		err = AppFlashWrite((uchar *)(tdp->start),(uchar *)appramstart,
			(tbuf-(uchar*)appramstart));
		if (err < 0)
#endif
			return(TFSERR_FLASHFAILURE);
	}

	/* All defragmentation is done, so verify sanity of files... */
	chkstat = tfscheck(tdp,verbose);

	return(chkstat);
}
예제 #9
0
/* _tfsclean():
 *	This is an alternative to the complicated defragmentation above.
 *	It simply scans through the file list and copies all valid files
 *	to RAM; then flash is erased and the RAM is copied back to flash.
 *  <<< WARNING >>>
 *  THIS FUNCTION SHOULD NOT BE INTERRUPTED AND IT WILL BLOW AWAY
 *  ANY APPLICATION CURRENTLY IN CLIENT RAM SPACE.
 */
int
_tfsclean(TDEV *tdp, int notused, int verbose)
{
	TFILE	*tfp;
	uchar	*tbuf;
	ulong	appramstart;
	int		dtot, nfadd, len, err, chkstat;

	if (TfsCleanEnable < 0)
		return(TFSERR_CLEANOFF);

	appramstart = getAppRamStart();

	/* Determine how many "dead" files exist. */
	dtot = 0;
	tfp = (TFILE *)tdp->start;
	while(validtfshdr(tfp)) {
		if (!TFS_FILEEXISTS(tfp))
			dtot++;
		tfp = nextfp(tfp,tdp);
	}

	if (dtot == 0)
		return(TFS_OKAY);

	printf("Reconstructing device %s with %d dead file%s removed...\n",
		tdp->prefix, dtot,dtot>1 ? "s":"");

	tbuf = (char *)appramstart;
	tfp = (TFILE *)(tdp->start);
	nfadd = tdp->start;
	while(validtfshdr(tfp)) {
		if (TFS_FILEEXISTS(tfp)) {
			len = TFS_SIZE(tfp) + sizeof(struct tfshdr);
			if (len % TFS_FSIZEMOD)
				len += TFS_FSIZEMOD - (len % TFS_FSIZEMOD);
			nfadd += len;
			if (s_memcpy(tbuf,(uchar *)tfp,len,0,0) != 0)
				return(TFSERR_MEMFAIL);
			
			((struct tfshdr *)tbuf)->next = (struct tfshdr *)nfadd;
			tbuf += len;
		}
		tfp = nextfp(tfp,tdp);
	}

	/* Erase the flash device: */
	err = _tfsinit(tdp);
	if (err != TFS_OKAY)
		return(err);

	/* Copy data placed in RAM back to flash: */
	err = AppFlashWrite((ulong *)(tdp->start),(ulong *)appramstart,
		(tbuf-(uchar*)appramstart));
	if (err < 0)
		return(TFSERR_FLASHFAILURE);

	/* All defragmentation is done, so verify sanity of files... */
	chkstat = tfscheck(tdp,verbose);

	return(chkstat);
}
예제 #10
0
/* writetest():
 *  Open the specified file in APPEND (modify) mode.  Seek into the file
 *	and read 1 byte.  Increment that byte by one and then write it back
 *	to the same location from which it was read.  Then, close the file.
 *	Build a new file that is what "should" be the content of the file we
 *	just modified and compare the two files.  They better match.
 *  This function also verifies TFS_HEADROOM.
 */
int
writetest(char *fname, char *newdata)
{
	TFILE *tfp;
	char c;
	long	headroom;
	int	size, tfd, err;

	/* Open the source file: */
	tfp = mon_tfsstat(fname);
	if (!tfp)
		die();
	size = TFS_SIZE(tfp);
	tfd = mon_tfsopen(fname,TFS_APPEND,buffer1);
	if (tfd < 0)
		tfsdie(tfd);

	headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0);
	if (headroom != 0)
		die();

	err = mon_tfsseek(tfd,3,TFS_BEGIN);
	if (err != 3)
		tfsdie(err);

	headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0);
	if (headroom != (size-3))
		die();

	err = mon_tfsread(tfd,&c,1);
	if (err != 1)
		tfsdie(err);

	headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0);
	if (headroom != (size-4))
		die();

	c++;
	err = mon_tfsseek(tfd,-1,TFS_CURRENT);
	if (err != 3)
		tfsdie(err);

	headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0);
	if (headroom != (size-3))
		die();

	err = mon_tfswrite(tfd,&c,1);
	if (err != TFS_OKAY)
		tfsdie(err);

	headroom = mon_tfsctrl(TFS_HEADROOM,tfd,0);
	if (headroom != (size-4))
		die();

	mon_tfsclose(tfd,0);

	/* Add a new file that "should" be identical to the modified file;
	 * then compare them and delete the newfile...
	 */
	err = mon_tfsadd(TMPFILE,"newdata1","2",newdata,strlen(newdata));
	if (err != TFS_OKAY)
		tfsdie(err);
	if (cmp(fname,TMPFILE) != 0)
		die();
	err = mon_tfsunlink(TMPFILE);
	if (err != TFS_OKAY)
		tfsdie(err);
	
	return(0);
}
예제 #11
0
/* seektest():
 *	Run some tests on tfsseek().
 *	Verify that the character in the file specified at the incoming offset
 *	is as expected.  Seek to beyond the end of file and verify error, etc...
 */
int
seektest(char *fname, int offset, char value)
{
	char	c, buf1[16], buf2[16];
	TFILE	*tfp;
	int		tfd, end, err;

	/* Open the source file: */
	tfd = mon_tfsopen(fname,TFS_RDONLY,0);
	if (tfd < 0)
		tfsdie(tfd);

	if (mon_tfsseek(tfd,offset,TFS_BEGIN) != offset)
		tfsdie(tfd);
	
	if (mon_tfsread(tfd,&c,1) != 1)
		tfsdie(tfd);

	if (c != value)
		die();

	tfp = mon_tfsstat(fname);
	if (!tfp)
		die();
	end = TFS_SIZE(tfp);

	/* 
	 * Seek to various limits in the file and verify proper return
	 * value...
	 */
	err = mon_tfsseek(tfd,0,TFS_BEGIN);
	if (err != 0)
		tfsdie(err);
	err = mon_tfsseek(tfd,end,TFS_CURRENT);
	if (err != end)
		tfsdie(err);
	err = mon_tfsseek(tfd,1,TFS_CURRENT);
	if (err != TFSERR_EOF)
		tfsdie(err);
	err = mon_tfsseek(tfd,end,TFS_BEGIN);
	if (err != end)
		tfsdie(err);
	err = mon_tfsseek(tfd,end+1,TFS_BEGIN);
	if (err != TFSERR_EOF)
		tfsdie(err);

	err = mon_tfsseek(tfd,0,TFS_BEGIN);
	if (err != 0)
		tfsdie(err);
	err = mon_tfsseek(tfd,-1,TFS_CURRENT);
	if (err != TFSERR_EOF)
		tfsdie(err);

	err = mon_tfsseek(tfd,end,TFS_BEGIN);
	if (err != end)
		tfsdie(err);
	err = mon_tfsseek(tfd,-1,TFS_CURRENT);
	if (err != end-1)
		tfsdie(err);
	err = mon_tfsseek(tfd,2,TFS_CURRENT);
	if (err != TFSERR_EOF)
		tfsdie(err);

	/* Seek to beginning, read 10, seek to beginning again read 10 again.
	 * Verify that both reads have same data.
	 */
	err = mon_tfsseek(tfd,0,TFS_BEGIN);
	if (err != 0)
		tfsdie(err);
	err = mon_tfsread(tfd,buf1,10);
	if (err != 10)
		tfsdie(err);
	err = mon_tfsseek(tfd,0,TFS_BEGIN);
	if (err != 0)
		tfsdie(err);
	err = mon_tfsread(tfd,buf2,10);
	if (err != 10)
		tfsdie(err);
	if (memcmp(buf1,buf2,10))
		die();

	/*
	 * Seek to end, then verify that read() returns EOF and tfs_eof()
	 * returns true.
	 */
	err = mon_tfsseek(tfd,end,TFS_BEGIN);
	if (err != end)
		tfsdie(err);
	err = mon_tfsread(tfd,buf1,1);
	if (err != TFSERR_EOF)
		tfsdie(err);
	if (mon_tfseof(tfd) != 1)
		die();

	mon_tfsclose(tfd,0);
	return(0);
}