int mkerr(unsigned char *buffer, unsigned char tag, char *errstr) { int index; int slen = strlen(errstr); int size = slen + 9; index = puthdr(buffer, 0, RError, tag, size); put2(buffer, index, slen); memcpy(&buffer[index], errstr, slen); return size; }
main(int argc, char **argv) { FILE *ifp; /* file pointer for input */ FILE *hfp; /* file pointer for popen write */ int bfd; /* file descriptor for bfile */ string tape; /* name of raw tape device */ int clean; /* clean trace header */ int verbose; /* echo every 20th trace */ int over; /* check format */ int convert; /* convert ibm fpt to ieee fpt */ string hfile; /* name of ascii header file */ string bfile; /* name of binary header file */ int trmin; /* first trace to read */ int trmax; /* last trace to read */ int nt; /* number of data samples */ char cmdbuf[BUFSIZ]; /* dd command buffer */ char ebcbuf[EBCBYTES]; /* ebcdic data buffer */ int itr = 0; /* current trace number */ bool nsflag = FALSE; /* flag for error in tr.ns */ char hdr_buf[10]; /* 1st 10 bytes of header in ascii */ char tmp_buf[3600]; /* temp. buffer to read in header */ unsigned int nsamp; /* number of samples per trace */ int i; /* loop counter to zero trace samples */ int *ibstart,*ibyte,*itype; int *obstart,*obyte,*otype; int nmap=0, imap; int ibs,iby,ity,obs,oby,oty; short itmp2; int itmp4; float tmp; int ntg=0; int rmbadtrace, ibt, nbt; /* initialize */ initargs(argc, argv); askdoc(1); /* make sure stdout is a file or pipe */ switch(filestat(STDOUT)) { case TTY: err("stdout can't be tty"); break; case DIRECTORY: err("stdout must be a file, not a directory"); break; case BADFILETYPE: err("stdout is illegal filetype"); break; } /* set filenames */ if (!getparstring("tape", &tape)) { ifp = stdin; file2g(ifp); } else { /* open files - first the tape */ ifp = efopen(tape, "r"); } file2g(stdout); /* set parameters */ if (!getparint("clean", &clean)) clean = 1; if (!getparint("verbose", &verbose)) verbose = 0; if (!getparint("over", &over)) over = 0; if (!getparint("convert", &convert)) convert = 1; if (!getparint("trmin", &trmin)) trmin = 1; if (!getparint("trmax", &trmax)) trmax = LONG_MAX; if (!getparint("rmbadtrace",&rmbadtrace)) rmbadtrace=0; nmap = countparval("ibstart"); if(nmap>0) { ibstart = (int*) malloc(nmap*sizeof(int)); ibyte = (int*) malloc(nmap*sizeof(int)); itype = (int*) malloc(nmap*sizeof(int)); obstart = (int*) malloc(nmap*sizeof(int)); obyte = (int*) malloc(nmap*sizeof(int)); otype = (int*) malloc(nmap*sizeof(int)); if(getparint("ibstart",ibstart)!=nmap) err(" check ibstart"); if(getparint("ibyte",ibyte)!=nmap) err(" check ibyte"); if(getparint("itype",itype)!=nmap) err(" check itype"); if(getparint("obstart",obstart)!=nmap) err(" check obstart"); if(getparint("obyte",obyte)!=nmap) err(" check obyte"); if(getparint("otype",otype)!=nmap) err(" check otype"); } /* read ebcdic and binary headers */ efread(ebcbuf, 1, EBCBYTES, ifp); efread((char *)&bh, 1, BNYBYTES, ifp); if (bh.format != 1) (over) ? warn("ignore bh.format ... continue") : err("format not IBM floating point"); if (!convert) warn( "assuming data is IEEE floating point, no conversion will be done"); /* set nt parameter */ if (!getparint("nt", &nt)) { nt = bh.hns; ntg = 0; } else { ntg = 1; } /* if needed, save ebcbuf into hfile */ if (getparstring("hfile", &hfile)) { /* Open pipe to use dd to convert ebcdic to ascii */ sprintf(cmdbuf, "dd ibs=3200 of=%s conv=ascii cbs=80 count=1", hfile); hfp = epopen(cmdbuf, "w"); /* Write ascii stream from buffer into pipe */ efwrite(ebcbuf, EBCBYTES, 1, hfp); epclose(hfp); } /* save the binary file, if needed */ if (getparstring("bfile", &bfile)) { /* - the binary data file */ bfd = eopen(bfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); /* Write binary header from bhed structure to binary file */ ewrite(bfd, (char *)&bh, BNYBYTES); eclose(bfd); } /* convert ebcdic to ascii for output data */ tascii_((unsigned char*)ebcbuf, (unsigned char*)&ch, EBCBYTES, 0); if (strncmp((char*)&ch, "C 1 CLIENT",10) != 0 ) { memcpy((char *)&ch, "C 1 CLIENT", 10); } /* test if number of samples set in binary header */ if (!bh.hns) { warn("samples/trace not set in binary header \n"); if (nt == 0) warn("samples/trace in 1st trace used \n"); else warn("nt in input used for samples/trace \n"); } if ((nt != bh.hns) && (nt != 0)) { warn("samples/trace reset in binary header =%d \n",nt); bh.hns = nt; } /* output ascii and binary headers to stdout */ puthdr(&ch, &bh); nbt = 0; /* convert the traces */ while (efread((char *)&tr, 1, HDRBYTES, ifp) && (itr < trmax)) { /* check first 10 bytes to look for ebcdic header, if found, this probably indicates a tape switch */ /* tascii_((unsigned char*)&tr, &hdr_buf, 10, 0); if ((strncmp(hdr_buf, "C 1 CLIENT", 10) == 0) || (strncmp(hdr_buf, "C CLIENT ", 10) == 0) || (strncmp(hdr_buf, "C 1 ", 4) == 0)) { fprintf(stderr," % efread(tmp_buf, 1, 3600 - HDRBYTES, ifp); } else { */ /* read in the trace data */ if(tr.ns==0) tr.ns = nt; if(ntg==0) { nsamp = tr.ns * 4; } else { nsamp = nt * 4; } efread((char *)&tr + HDRBYTES, 1, nsamp, ifp); ibt = 0; /* Check bh.hns with tr.ns */ if (bh.hns != tr.ns) { nsflag = true; ibt = 1; nbt = nbt + 1; /* print warning message */ if(verbose==1 || nbt<1000) warn("discrepant tr.ns = %d with bh.hns = %d\n" "\t... noted on trace %d", tr.ns, bh.hns, itr + 1); /* if user wants to leave things the way they are (nt=0) */ /* otherwise, modify number of samples per trace */ if (nt != 0) { if (nt > tr.ns) { for (i = tr.ns; i < nt; i++) tr.data[i] = 0.0; } nsamp = nt * 4; tr.ns = nt; } } /* convert and write desired traces */ if (++itr >= trmin) { /* Convert IBM floats to native floats */ if (convert) conv_float((char *)tr.data, (char *)tr.data, tr.ns, 1); /* write the trace to disk */ if(nmap==0) { /* clean up trace header beyond 180 bytes */ if (clean == 1) bzero((char *)&tr + 180, 60); if (ibt==0 || rmbadtrace==0) efwrite((char *)&tr, 1, nsamp + HDRBYTES, stdout); } else { bcopy((char*)&tr,(char*)&tro,nsamp+HDRBYTES); for(imap=0;imap<nmap;imap++) { ibs = ibstart[imap]; iby = ibyte[imap]; ity = itype[imap]; obs = obstart[imap]; oby = obyte[imap]; oty = otype[imap]; /* fprintf(stderr,"ibs=%d iby=%d ity=%d obs=%d oby=%d oty=%d \n", ibs,iby,ity,obs,oby,oty); */ if(iby==oby && ity==oty && ity!=1 ) { bcopy((char*)&tr+ibs-1,(char*)&tro+obs-1,iby); } else { if(ity==1) { conv_float((char*)&tr+ibs-1,(char*)&tmp,1,1); } else { if(iby==2) { bcopy((char*)&tr+ibs-1,(char*)&itmp2,iby); tmp = itmp2; } else if(iby==4) { bcopy((char*)&tr+ibs-1,(char*)&itmp4,iby); tmp = itmp4; } } if(oty==1) { bcopy((char*)&tmp,(char*)&tro+obs-1,oby); } else { tmp = tmp + 0.5; if(oby==2) { itmp2 = (short) tmp; bcopy((char*)&itmp2,(char*)&tro+obs-1,oby); } else { itmp4 = (int) tmp; bcopy((char*)&itmp4,(char*)&tro+obs-1,oby); } } } } /* clean up trace header beyond 180 bytes */ if (clean == 1) bzero((char *)&tro + 180, 60); if (ibt==0 || rmbadtrace==0) efwrite((char *)&tro, 1, nsamp + HDRBYTES, stdout); } /* echo under verbose option */ if (verbose && itr % 20 == 0) warn(" %d traces from tape", itr); } /* } */ } /* while loop */ /* re-iterate error in case not seen during run */ if ((nsflag) && (nt != 0)) warn("discrepancy found in header and trace ns values\n" "\theader value (%d) was used to extract traces", bh.hns); /* clean up */ efclose(ifp); if(nmap>0) { free(ibstart); free(ibyte); free(itype); free(obstart); free(obyte); free(otype); } return EXIT_SUCCESS; }
/* * Read the input files; write the output file; display information. */ static void btxld(const char *iname) { char name[FILENAME_MAX]; struct btx_hdr btx, btxle; struct hdr ihdr, ohdr; unsigned int ldr_size, cwr; int fdi[3], fdo, i; ldr_size = 0; for (i = I_LDR; i <= I_CLNT; i++) { fname = i == I_LDR ? lname : i == I_BTX ? bname : iname; if ((fdi[i] = open(fname, O_RDONLY)) == -1) err(2, "%s", fname); switch (i) { case I_LDR: gethdr(fdi[i], &ihdr); if (ihdr.fmt != F_BIN) Warn(fname, "Loader format is %s; processing as %s", fmtlist[ihdr.fmt], fmtlist[F_BIN]); ldr_size = ihdr.size; break; case I_BTX: getbtx(fdi[i], &btx); break; case I_CLNT: gethdr(fdi[i], &ihdr); if (ihdr.org && ihdr.org != BTX_PGSIZE) Warn(fname, "Client origin is 0x%x; expecting 0 or 0x%x", ihdr.org, BTX_PGSIZE); } } memset(&ohdr, 0, sizeof(ohdr)); ohdr.fmt = format; ohdr.text = ldr_size; ohdr.data = btx.btx_textsz + ihdr.size; ohdr.org = lentry; ohdr.entry = lentry; cwr = 0; if (wpage > 0 || (wpage == -1 && !(ihdr.flags & IMPURE))) { if (wpage > 0) cwr = wpage; else { cwr = howmany(ihdr.text, BTX_PGSIZE); if (cwr > BTX_MAXCWR) cwr = BTX_MAXCWR; } } if (ppage > 0 || (ppage && wpage && ihdr.org >= BTX_PGSIZE)) { btx.btx_flags |= BTX_MAPONE; if (!cwr) cwr++; } btx.btx_pgctl -= cwr; btx.btx_entry = Eflag ? centry : ihdr.entry; if ((size_t)snprintf(name, sizeof(name), "%s.tmp", oname) >= sizeof(name)) errx(2, "%s: Filename too long", oname); if ((fdo = open(name, O_CREAT | O_TRUNC | O_WRONLY, 0666)) == -1) err(2, "%s", name); if (!(tname = strdup(name))) err(2, NULL); puthdr(fdo, &ohdr); for (i = I_LDR; i <= I_CLNT; i++) { fname = i == I_LDR ? lname : i == I_BTX ? bname : iname; switch (i) { case I_LDR: copy(fdi[i], fdo, ldr_size, 0); seekx(fdo, ohdr.size += ohdr.text); break; case I_BTX: btxle = btx; btxle.btx_pgctl = htole16(btxle.btx_pgctl); btxle.btx_textsz = htole16(btxle.btx_textsz); btxle.btx_entry = htole32(btxle.btx_entry); writex(fdo, &btxle, sizeof(btxle)); copy(fdi[i], fdo, btx.btx_textsz - sizeof(btx), sizeof(btx)); break; case I_CLNT: copy(fdi[i], fdo, ihdr.size, 0); if (ftruncate(fdo, ohdr.size += ohdr.data)) err(2, "%s", tname); } if (close(fdi[i])) err(2, "%s", fname); } if (close(fdo)) err(2, "%s", tname); if (rename(tname, oname)) err(2, "%s: Can't rename to %s", tname, oname); tname = NULL; if (verbose) { printf(binfo, btx.btx_majver, btx.btx_minver, btx.btx_textsz, BTX_ORIGIN(btx), BTX_ENTRY(btx), BTX_MAPPED(btx) * BTX_PGSIZE / 0x100000, !!(btx.btx_flags & BTX_MAPONE), BTX_MAPPED(btx) - btx.btx_pgctl - BTX_PGBASE / BTX_PGSIZE - BTX_MAPPED(btx) * 4 / BTX_PGSIZE); printf(cinfo, fmtlist[ihdr.fmt], ihdr.size, ihdr.text, ihdr.data, ihdr.bss, ihdr.entry); printf(oinfo, fmtlist[ohdr.fmt], ohdr.size, ohdr.text, ohdr.data, ohdr.org, ohdr.entry); } }
unsigned long proc9p(unsigned char *msg, unsigned long size, Callbacks *cb) { Fcall ifcall; Fcall *ofcall = NULL; unsigned long slen; unsigned long index; unsigned char i; index = 4; ifcall.type = msg[index++]; get2(msg, index, ifcall.tag); if (size > MAX_MSG) { strcpy_P(pgmbuf, Etoobig); index = mkerr(msg, ifcall.tag, pgmbuf); goto END; } // if it isn't here, it isn't implemented switch(ifcall.type) { case TVersion: i = index; index = 7; get4(msg, i, ifcall.msize); get2(msg, i, slen); if (ifcall.msize > MAX_MSG) ifcall.msize = MAX_MSG; put4(msg, index, ifcall.msize); put2(msg, index, slen); index += slen; puthdr(msg, 0, RVersion, ifcall.tag, index); break; case TAttach: get4(msg, index, ifcall.fid); get4(msg, index, ifcall.afid); get2(msg, index, slen); ifcall.uname = (char*)&msg[index]; index += slen; get2(msg, index, slen); msg[index-2] = '\0'; ifcall.aname = (char*)&msg[index]; index += slen; msg[index-2] = '\0'; ofcall = cb->attach(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = 7; msg[index++] = ofcall->qid.type; put4(msg, index, ofcall->qid.version); put8(msg, index, ofcall->qid.path, 0); puthdr(msg, 0, RAttach, ifcall.tag, index); break; case TWalk: get4(msg, index, ifcall.fid); get4(msg, index, ifcall.newfid); get2(msg, index, ifcall.nwname); if (ifcall.nwname > MAX_WELEM) ifcall.nwname = MAX_WELEM; for (i = 0; i < ifcall.nwname; i++) { get2(msg, index, slen); msg[index-2] = '\0'; ifcall.wname[i] = (char*)&msg[index]; index += slen; } msg[index] = '\0'; ofcall = cb->walk(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, RWalk, ifcall.tag, 9 + ofcall->nwqid * 13); put2(msg, index, ofcall->nwqid); for (i = 0; i < ofcall->nwqid; i++) { msg[index++] = ofcall->wqid[i].type; put4(msg, index, ofcall->wqid[i].version); put8(msg, index, ofcall->wqid[i].path, 0); } break; case TStat: get4(msg, index, ifcall.fid); ofcall = cb->stat(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } slen = putstat(msg, 9, &(ofcall->stat)); index = puthdr(msg, 0, RStat, ifcall.tag, slen + 9); put2(msg, index, slen); // bleh? index += slen; break; case TClunk: get4(msg, index, ifcall.fid); ofcall = cb->clunk(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, RClunk, ifcall.tag, 7); break; case TOpen: get4(msg, index, ifcall.fid); ifcall.mode = msg[index++]; ofcall = cb->open(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, ROpen, ifcall.tag, 24); msg[index++] = ofcall->qid.type; put4(msg, index, ofcall->qid.version); put8(msg, index, ofcall->qid.path, 0); put4(msg, index, MAX_IO); break; case TRead: get4(msg, index, ifcall.fid); get4(msg, index, ifcall.offset); index += 4; // :( get4(msg, index, ifcall.count); ofcall = cb->read(&ifcall, &msg[11]); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } // No response if (ofcall == NULL) { index = 0; goto END; } index = puthdr(msg, 0, RRead, ifcall.tag, 11 + ofcall->count); put4(msg, index, ofcall->count); index += ofcall->count; break; case TCreate: get4(msg, index, ifcall.fid); get2(msg, index, slen); ifcall.name = (char*)&msg[index]; index += slen; get4(msg, index, ifcall.perm); msg[index-4] = '\0'; ifcall.mode = msg[index++]; ofcall = cb->create(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, RCreate, ifcall.tag, 24); msg[index++] = ofcall->qid.type; put4(msg, index, ofcall->qid.version); put8(msg, index, ofcall->qid.path, 0); put4(msg, index, MAX_IO); break; case TWrite: get4(msg, index, ifcall.fid); get4(msg, index, ifcall.offset); index += 4; // bleh... again get4(msg, index, ifcall.count); ofcall = cb->write(&ifcall, &msg[index]); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, RWrite, ifcall.tag, 11); put4(msg, index, ofcall->count); break; case TRemove: get4(msg, index, ifcall.fid); ofcall = cb->remove(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, RRemove, ifcall.tag, 7); break; case TFlush: get2(msg, index, ifcall.oldtag); ofcall = cb->flush(&ifcall); if (ofcall->type == RError) { index = mkerr(msg, ifcall.tag, ofcall->ename); goto END; } index = puthdr(msg, 0, RFlush, ifcall.tag, 7); break; default: strcpy_P(pgmbuf, Ebadtype); index = mkerr(msg, ifcall.tag, pgmbuf); break; } END: if (index > MAX_MSG) { strcpy_P(pgmbuf, Etoobig); index = mkerr(msg, ifcall.tag, pgmbuf); } return index; }