int prof_GetSymFile(void) { int tfd; if(prof_SymFile[0] == 0) { tfd = SymFileFd(1); } else { tfd = tfsopen(prof_SymFile,TFS_RDONLY,0); if(tfd < 0) { printf("%s: %s\n",prof_SymFile,(char *)tfsctrl(TFS_ERRMSG,tfd,0)); } } return(tfd); }
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); }
void tfslog(int action, char *string) { #if TFS_CHANGELOG_SIZE static char *tfslogaction[] = { "ADD", "DEL", "IPM", " ON", "OFF" }; extern void *setTmpMaxUsrLvl(); static char buf[TFS_CHANGELOG_SIZE]; TFILE *tfp; int (*fptr)(); char *eol, *eob, *logaction, tbuf[32]; int newfsize, fsize, lsize, tfd, err, len, tbuflen; switch(action) { case TFSLOG_ADD: /* Return here if logging is off, */ case TFSLOG_DEL: /* or this tfslog() call is on the */ case TFSLOG_IPM: /* TFS_CHANGELOG_FILE itself. */ if (!tfsLogging || !strcmp(string,TFS_CHANGELOG_FILE)) return; break; case TFSLOG_ON: if (tfsLogging == 1) return; tfsLogging = 1; break; case TFSLOG_OFF: if (tfsLogging == 0) return; tfsLogging = 0; break; } /* Force the getUsrLvl() function to return MAX: */ fptr = (int(*)())setTmpMaxUsrLvl(); logaction = tfslogaction[action]; tfp = tfsstat(TFS_CHANGELOG_FILE); tfsGetAtime(0,tbuf,sizeof(tbuf)); tbuflen = strlen(tbuf); if (tfp) { tfd = tfsopen(TFS_CHANGELOG_FILE,TFS_RDONLY,0); fsize = tfsread(tfd,buf,TFS_CHANGELOG_SIZE); tfsclose(tfd,0); newfsize = (fsize+strlen(logaction)+strlen(string)+3); if (tbuflen) newfsize += tbuflen + 3; eob = buf + fsize; /* If newfsize is greater than the maximum size the file is * allowed to grow, then keep removing the first line * (oldest entry) until new size is within the limit... */ if (newfsize > TFS_CHANGELOG_SIZE) { lsize = 0; eol = buf; while ((newfsize-lsize) > TFS_CHANGELOG_SIZE) { while((*eol != '\r') && (*eol != '\n')) eol++; while((*eol == '\r') || (*eol == '\n')) eol++; lsize = eol-buf; } fsize -= lsize; newfsize -= lsize; eob -= lsize; memcpy(buf,eol,fsize); } if (tbuflen) sprintf(eob,"%s: %s @ %s\n",logaction,string,tbuf); else sprintf(eob,"%s: %s\n",logaction,string); err = _tfsunlink(TFS_CHANGELOG_FILE); if (err < 0) printf("%s: %s\n",TFS_CHANGELOG_FILE, (char *)tfsctrl(TFS_ERRMSG,err,0)); err = tfsadd(TFS_CHANGELOG_FILE,0,"u3",buf,newfsize); if (err < 0) printf("%s: %s\n",TFS_CHANGELOG_FILE, (char *)tfsctrl(TFS_ERRMSG,err,0)); } else { if (tbuflen) len = sprintf(buf,"%s: %s @ %s\n",logaction,string,tbuf); else len = sprintf(buf,"%s: %s\n",logaction,string); err = tfsadd(TFS_CHANGELOG_FILE,0,"u3",buf,len); if (err < 0) printf("%s: %s\n",TFS_CHANGELOG_FILE, (char *)tfsctrl(TFS_ERRMSG,err,0)); } /* Restore the original getUsrLvl() functionality: */ clrTmpMaxUsrLvl(fptr); #endif }
/* showStruct(): * The workhorse of cast. This function parses the structfile looking for * the structure type; then it attempts to display the memory block that * begins at memAddr as if it was the structure. Note that there is no * pre-processing done to verify valid syntax of the structure definition. */ int showStruct(int tfd,long flags,char *structtype,char *structname,char *linkname) { struct mbrinfo *mptr; ulong curpos, nextlink; int i, state, snl, retval, tblsize; char line[96], addrstr[16], format[64]; char *cp, *eol, *type, *eotype, *name, *bracket, *eoname, tmp; type = (char *)0; retval = nextlink = 0; curpos = tfsctrl(TFS_TELL,tfd,0); tfsseek(tfd,0,TFS_BEGIN); castIndent(); if (structname) printf("struct %s %s:\n",structtype,structname); else printf("struct %s @0x%lx:\n",structtype,memAddr); castDepth++; state = STRUCT_SEARCH; snl = strlen(structtype); while(1) { if (tfsgetline(tfd,line,sizeof(line)-1) == 0) { printf("Structure definition '%s' not found\n",structtype); break; } if ((line[0] == '\r') || (line[0] == '\n')) /* empty line? */ continue; eol = strpbrk(line,";#\r\n"); if (eol) *eol = 0; if (state == STRUCT_SEARCH) { if (!strncmp(line,"struct",6)) { cp = line+6; while(isspace(*cp)) cp++; if (!strncmp(cp,structtype,snl)) { cp += snl; while(isspace(*cp)) cp++; if (*cp == OPEN_BRACE) state = STRUCT_DISPLAY; else { retval = -1; break; } } } } else if (state == STRUCT_DISPLAY) { type = line; while(isspace(*type)) type++; if (*type == CLOSE_BRACE) { state = STRUCT_ALLDONE; break; } eotype = type; while(!isspace(*eotype)) eotype++; *eotype = 0; name = eotype+1; while(isspace(*name)) name++; bracket = strchr(name,'['); if (bracket) tblsize = atoi(bracket+1); else tblsize = 1; if (*name == '*') { castIndent(); printf("%s%-8s %s: ",strAddr(flags,addrstr),type,name); if (!strcmp(type,"char.c")) printf("\"%s\"\n",*(char **)memAddr); else printf("0x%lx\n",*(ulong *)memAddr); memAddr += 4; continue; } mptr = mbrinfotbl; while(mptr->type) { if (!strcmp(type,mptr->type)) { castIndent(); eoname = name; while(!isspace(*eoname)) eoname++; tmp = *eoname; *eoname = 0; if (bracket) { if (!strcmp(type,"char.c")) { printf("%s%-8s %s: ", strAddr(flags,addrstr),mptr->type,name); cp = (char *)memAddr; for(i=0;i<tblsize && isprint(*cp);i++) printf("%c",*cp++); printf("\n"); } else printf("%s%-8s %s\n", strAddr(flags,addrstr),mptr->type,name); memAddr += mptr->size * tblsize; } else { sprintf(format,"%s%-8s %%s: %s\n", strAddr(flags,addrstr),mptr->type,mptr->format); switch(mptr->size) { case 1: printf(format,name,*(uchar *)memAddr); break; case 2: printf(format,name,*(ushort *)memAddr); break; case 4: printf(format,name,*(ulong *)memAddr); break; } memAddr += mptr->size; } *eoname = tmp; break; } mptr++; } if (!(mptr->type)) { int padsize; char *subtype, *subname, *eossn; if (!strcmp(type,"struct")) { subtype = eotype+1; while(isspace(*subtype)) subtype++; subname = subtype; while(!isspace(*subname)) subname++; *subname = 0; subname++; while(isspace(*subname)) subname++; eossn = subname; while(!isspace(*eossn)) eossn++; *eossn = 0; if (*subname == '*') { castIndent(); printf("%s%s %s %s: 0x%08lx\n",strAddr(flags,addrstr), type,subtype,subname,*(ulong *)memAddr); if (linkname) { if (!strcmp(linkname,subname+1)) nextlink = *(ulong *)memAddr; } memAddr += 4; } else { for (i=0;i<tblsize;i++) { if (bracket) sprintf(bracket+1,"%d]",i); if (showStruct(tfd,flags,subtype,subname,0) < 0) { state = STRUCT_ALLDONE; goto done; } } } } else if (!strncmp(type,"pad[",4)) { padsize = atoi(type+4); if (flags & STRUCT_SHOWPAD) { castIndent(); printf("%spad[%d]\n",strAddr(flags,addrstr),padsize); } memAddr += padsize; } else { retval = -1; break; } } } else { state = STRUCT_ERROR; break; } } done: switch(state) { case STRUCT_SEARCH: printf("struct %s not found\n",structtype); retval = -1; break; case STRUCT_DISPLAY: printf("invalid member type: %s\n",type); retval = -1; break; case STRUCT_ERROR: printf("unknown error\n"); retval = -1; break; } tfsseek(tfd,curpos,TFS_BEGIN); if (linkname) memAddr = nextlink; castDepth--; return(retval); }
/* envToExec(): Create a file of "set" commands that can be run to recreate the current environment. Changed Oct 2008 to eliminate use of getAppRamStart(). */ int envToExec(char *filename) { int err, vartot, size, rc; char *buf, *bp, *cp; register struct s_shell *sp; sp = shell_vars; vartot = size = rc = 0; /* First go through the list to see how much space we need * to allocate... */ while(1) { if (validEnvToExecVar(sp->name)) { size += strlen(sp->name) + 6; cp = sp->val; while(*cp) { if (*cp == '$') size++; size++; cp++; } size += 3; vartot++; } if (sp->next != (struct s_shell *)0) sp = sp->next; else break; } if (size == 0) return(0); /* Now that we know the space needed (stored in 'size' variable), * allocate it and build the new file in that space, then use tfsadd() * to create the file... */ vartot = 0; sp = shell_vars; buf = bp = (char *)env_alloc(size); while(1) { /* Note: if this code changes, then the code above that is used to * allocate the buffer size may also need to change... */ if (validEnvToExecVar(sp->name)) { bp += sprintf(bp,"set %s \"",sp->name); cp = sp->val; while(*cp) { if (*cp == '$') *bp++ = '\\'; *bp++ = *cp++; } *bp++ = '\"'; *bp++ = '\n'; *bp = 0; vartot++; } if (sp->next != (struct s_shell *)0) sp = sp->next; else break; } if (vartot > 0) { err = tfsadd(filename,"envsetup","e",(unsigned char *)buf,strlen(buf)); if (err != TFS_OKAY) { printf("%s: %s\n",filename,(char *)tfsctrl(TFS_ERRMSG,err,0)); rc = -1; } } env_free(buf); return(rc); }