/* ***************************************** * * * Brian D. Lockrey * * ITT North Technology Center * * 4565 Columbus Pike * * Delaware, Ohio 43015 * * 614-548-4301 Ext. 343 * * * ***************************************** Release 2.01 M T D U M P Description: Magtape Dump Utility Entry Points: MAIN - The only entry point External Routines: CCPOS - Position cursor on a channel CCTRLO - Cancel effect of ^O CLOSE - Close a channel EBCASC - Convert EBCDIC to ASCII ERRTST - Return RSTS/E Error number ERRTXT - Return RSTS/E Error text FSS - Filename String Scan GETBLK - Get a Block HEADER - Print Header Text MAGTAP - Basic-Plus MAGTAPE function OPENI - Open for Input PERROR - Print RSTS/E error message SETCC - Set ^C Trap address SYDATE - Return DATE UNSPAC - Remove spaces from a string UPCASE - Convert a string to uppser case ZFIRQB - Zeroes FIRQB ZXRB - Zeroes XRB Change Activities: Date Pgm-# Description ---- ----- ----------- 21-Dec-81 2.01 Original Release */ #include #include char ttybuf[132]; char out[132]; char cmd[3], parm[80]; char file1[30], file2[30], file10[30]; char chartype; char *buffer; int lun10, buflen, recl, log, dat; int cchit, err, devopn, den, par; extern int cctrap(); FILE *f1,*f2,*f3; /*------------------------------------------------------*/ /* Initalization and command processing routines. */ /*------------------------------------------------------*/ main() { header("MTDUMP Version 2.01"); setcc(cctrap); buffer = alloc(16384); log = FALSE; dat = FALSE; devopn = FALSE; recl = 0; chartype = 'A'; lun10 = 10; /* magtape channel */ den = 800; par = 0; strcpy(file1," "); strcpy(file2," "); strcpy(file10," "); l0: cchit = FALSE; cctrlo(flun(stdout)); fflush(stdout); if (ccpos(0) != 0) puts("\n"); puts("MTD> "); if (gets(ttybuf) == 0) { fclose(f1); close(lun10); exit(0); } upcase(ttybuf); if (cchit == TRUE) goto l0; if (ttybuf[0] != 0) parse(); if (streq(cmd,"END")) { fclose(f1); fclose(f2); close(lun10); exit(0); } if (streq(cmd,"HEL")) { help(); goto l0; } if (devopn == FALSE && streq(cmd,"DEV") == FALSE) { puts("?Device not opened, Use DEV command\n"); goto l0; } if (streq(cmd,"ANS")) { ansi(); goto l0; } if (streq(cmd,"BAC")) { backspace(); goto l0; } if (streq(cmd,"CHA")) { charset(); goto l0; } if (streq(cmd,"CLO")) { closex(); goto l0; } if (streq(cmd,"COP")) { copy(); goto l0; } if (streq(cmd,"DAT")) { datafile(); goto l0; } if (streq(cmd,"DEC")) { decimal(); goto l0; } if (streq(cmd,"DEN")) { density(); goto l0; } if (streq(cmd,"DEV")) { device(); goto l0; } if (streq(cmd,"DIS")) { display(); goto l0; } if (streq(cmd,"DOS")) { dos(); goto l0; } if (streq(cmd,"EOF")) { eofcmd(); goto l0; } if (streq(cmd,"EOT")) { eot(); goto l0; } if (streq(cmd,"HEX")) { hex(); goto l0; } if (streq(cmd,"LOG")) { logfile(); goto l0; } if (streq(cmd,"LRE")) { lrecl(); goto l0; } if (streq(cmd,"OCT")) { octal(); goto l0; } if (streq(cmd,"PAR")) { parity(); goto l0; } if (streq(cmd,"QDA")) { qdat(); goto l0; } if (streq(cmd,"QLO")) { qlog(); goto l0; } if (streq(cmd,"RAD")) { rad(); goto l0; } if (streq(cmd,"REW")) { rewind(); goto l0; } if (streq(cmd,"SCA")) { scan(); goto l0; } if (streq(cmd,"SHO")) { show(); goto l0; } if (streq(cmd,"SIZ")) { size(); goto l0; } if (streq(cmd,"SKI")) { skip(); goto l0; } if (streq(cmd,"STA")) { status(); goto l0; } if (streq(cmd,"UNL")) { unload(); goto l0; } puts("%Illegal command\n"); goto l0; } /* Parse will parse the command string into cmd and parm */ parse() { int i,j; i = 0; cmd[0] = 0; while (ttybuf[i] != ' ' && ttybuf[i] != 0) { if (i<3) cmd[i] = ttybuf[i]; ++i; } cmd[3] = 0; j = 0; while (ttybuf[i] != 0) { parm[j] = ttybuf[i]; ++i; ++j; } parm[j] = 0; unspace(parm); } /*------------------------------------------------------*/ /* Command Functions (each command calls one of these. */ /*------------------------------------------------------*/ /* Ansi will display all blocks which are ansi labels */ ansi() { int i, p; p = atoi(parm); if (p == 0) p = 1; i = 0; while (i < p) { getblock(0); if (cchit == TRUE) return; if (anslbl() == TRUE) { buffer[80] = '\0'; sprint(out,"%s\n", buffer); output(); ++i; } } } /* Backspace the number of blocks in parm */ backspace() { int i, p; p = atoi(parm); i = magtape(5,p,lun10); if ((err = errtst()) != 0) { perror(err); } i = p - i; sprint(out,"Backspaced over %d records\n", i); output(); } /* Change character set translator to ASCII or EBCDIC. */ charset() { char c; c = parm[0]; switch (c) { case 'A': chartype = 'A'; puts("Character set changed to ASCII\n"); return; case 'E': chartype = 'E'; puts("Character set changed to EBCDIC\n"); return; default: puts("%Illegal CHARset option\n"); break; } } /* Close the log file. */ closex() { if (streq(parm,"LOG") == TRUE) { fclose(f1); log = FALSE; puts("LOG file closed\n"); return; } if (streq(parm,"DAT") == TRUE) { fclose(f2); dat = FALSE; puts("DAT file closed\n"); return; } puts("%Illegal parameter on CLOse command\n"); } /* Copy the next # records to the data file */ copy() { char c; int b, i, j, k, inc, w; if (dat == FALSE) { puts("?DAT file not currently open.\n"); return; } if (streq(parm,"EOF") == TRUE) inc = 0; else inc = 1; b = atoi(parm); if (b == 0) b = 1; for (i=1; i<=b; i=i+inc) { getblock(1); if (err == 11 && inc == 0) return; if (cchit == TRUE) return; if (buflen != 0) { w = 0; for (j=0; j= recl && recl != 0) { putc(13,f2); putc(10,f2); w = 0; } } } } } /* Open the data file for output */ datafile() { fclose(f2); dat = FALSE; if ((f2 = fopen(parm,"wn")) == NULL) { puts("?Error on DAT file open\n"); return; } printf("DAT file %s now open.\n", parm); dat = TRUE; strcpy(file2,parm); } /* Decimal dump the buffer. */ decimal() { int c,inc; int i,j,b,k,kmax; kmax = 10; if (streq(parm,"EOF") == TRUE) inc = 0; else inc = 1; b = atoi(parm); if (b==0) b = 1; for (i=1; i<=b; i=i+inc) { getblock(1); if (err == 11 && inc == 0) return; k = 0; if (buflen != 0) { for (j=0; j= kmax) { ascii(kmax); k = 0; } } if (k != 0) { while ( k < kmax) { strcpy(out," "); output(); ttybuf[k] = ' '; ++k; } ascii(kmax); } } } } /* Change density to 800 or 1600 bpi. */ density() { int t; t = atoi(parm); if (t != 800 && t != 1600) { puts("%Illegal density\n"); return; } den = t; setdp(); } /* Open a magtape device on lun10. */ device() { close(lun10); fss(parm); err = openi(lun10,0,0,0,0); if (err != 0) { perror(err); return; } devopn = TRUE; strcpy(file10,parm); } /* Display the buffer, filter out all non-printable ascii. */ display() { char c; int i,j,b,w,inc; if (streq(parm,"EOF") == TRUE) inc = 0; else inc = 1; b = atoi(parm); if (b==0) b = 1; for (i=1; i<=b; i=i+inc) { getblock(1); if (err == 11 && inc == 0) return; if (cchit == TRUE) return; if (buflen != 0) { w = 0; for (j=0; j= recl && recl != 0) { strcpy(out,"\n"); output(); w = 0; } } } } } /* Dos will display all blocks which are dos labels */ dos() { char file[11], date[10]; int i, p, p1, p2; p = atoi(parm); if (p == 0) p = 1; i = 0; while (i < p) { getblock(0); if (cchit == TRUE) return; if (buflen == 14) { r50toa(&file[0],&buffer[0],2); r50toa(&file[7],&buffer[4],1); file[6] = '.'; file[10] = '\0'; p1 = swabi(swabb(&buffer[10])); sydate(p1,date); p1 = buffer[7]; p2 = buffer[6]; sprint(out,"%s [%.3d,%.3d] %s\n", file, p1, p2, date); output(); ++i; } } } /* Read forward until 'parm' EOF's have passed. */ eofcmd() { int i, p; p = atoi(parm); if (p == 0) p = 1; for (i=1; i<=p; ++i) { buflen = 1; while (buflen != 0) { getblock(1); if (cchit == TRUE) return; } } } /* Find the end-of-tape */ eot() { int flag; flag = 0; for (;;) { getblock(0); if (cchit == TRUE) return; if (buflen != 0) flag = 0; if (err == 11) ++flag; if (flag == 2) { strcpy(out,"EOT:\n"); output(); return; } } } /* Help the user, lots of commands to remember here. */ help() { type(""); type("ANSi #"); type("BACkspace #"); type("CHArset A|E"); type("CLOse DAT|LOG"); type("COPy #|EOF"); type("DATa filename"); type("DECimal #|EOF"); type("DENsity 800|1600"); type("DEVice device-name"); type("DISplay #|EOF"); type("DOS #"); type("END"); type("EOF #"); type("EOT"); type("HELp"); puts("\nType to continue? "); gets(ttybuf); type(""); type("HEX #|EOF"); type("LOGfile filename"); type("LREcl #"); type("OCTal #|EOF"); type("PARity #"); type("QDAt device"); type("QLOg device"); type("RAD #|EOF"); type("REWind"); type("SCAn #|EOF"); type("SHOw"); type("SIZE #"); type("SKIp #"); type("STAtus"); type("UNLoad"); type(""); } /* Hex dump the buffer. */ hex() { char c; int i,j,b,k,kmax; int temp, inc; kmax = 16; if (streq(parm,"EOF") == TRUE) inc = 0; else inc = 1; b = atoi(parm); if (b==0) b = 1; for (i=1; i<=b; i=i+inc) { getblock(1); if (err == 11 && inc == 0) return; k = 0; if (buflen != 0) { for (j=0; j= kmax) { ascii(kmax); k = 0; } } if (k != 0) { while ( k < kmax) { strcpy(out," "); output(); ttybuf[k] = ' '; ++k; } ascii(kmax); } } } } /* Turn on a LOG file. Open the output channel too. */ logfile() { buflen = 0; fclose(f1); log = FALSE; if ((f1 = fopen(parm,"w")) == NULL) { puts("%Error on LOG file open\n"); return; } printf("LOG file %s now active.\n", parm); log = TRUE; strcpy(file1,parm); } /* Set the lrecl for IBM type tapes */ lrecl() { recl = atoi(parm); } /* Octal dump the buffer. */ octal() { char c; int i,j,b,k,kmax; int temp, inc; kmax = 10; if (streq(parm,"EOF") == TRUE) inc = 0; else inc = 1; b = atoi(parm); if (b==0) b = 1; for (i=1; i<=b; i=i+inc) { getblock(1); if (err == 11 && inc == 0) return; if (cchit == TRUE) return; k = 0; if (buflen != 0) { for (j=0; j= kmax) { ascii(kmax); k = 0; } } if (k != 0) { while ( k < kmax) { strcpy(out," "); output(); ttybuf[k] = ' '; ++k; } ascii(kmax); } } } } /* Set parity option to Even or Odd. */ parity() { char c; c = parm[0]; switch (c) { case 'O': par = 0; break; case 'E': par = 1; break; default: puts("%Illegal PARity option\n"); return; } setdp(); } /* Que the dat file */ qdat() { if (dat == TRUE) { fclose(f2); dat = FALSE; puts("DAT file closed\n"); } if (streq(parm,"") == TRUE) strcpy(parm,"LP:"); err = que(parm, file2, 0); if (err != 0) perror(err); } /* Que the log file */ qlog() { if (log == TRUE) { fclose(f1); log = FALSE; puts("LOG file closed\n"); } if (streq(parm,"") == TRUE) strcpy(parm,"LP:"); err = que(parm, file1, 0); if (err != 0) perror(err); } /* Rad-50 dump */ rad() { int i, j, k, l, kmax, b, temp, inc; kmax = 16; if (streq(parm,"EOF") == TRUE) inc = 0; else inc = 1; b = atoi(parm); if (b == 0) b = 1; for (i=1; i<=b; i=i+inc) { getblock(1); if (err == 11 && inc == 0) return; k = 0; if (buflen != 0) { for (j=0; j= kmax) { strcpy(out,"\n"); output(); k = 0; } } } } } /* Rewind the magtape device */ rewind() { int mtsw; magtape(3,0,lun10); if ((err = errtst()) != 0) { perror(err); return; } mtsw = magtape(7,0,lun10); err = errtst(); if (mtsw & 256) { strcpy(out,"BOT:\n"); output(); } if (err != 0) { perror(err); } } /* Scan for a record of size # or EOF */ scan() { int p; if (streq(parm,"EOF") == TRUE) { strcpy(parm,"1"); eofcmd(); return; } p = atoi(parm); if (p <= 0) { puts("%Illegal SCAN parameter\n"); return; } for (;;) { getblock(1); if (buflen == p) return; if (cchit == TRUE) return; } } /* Show the current state of things */ show() { char temp[20]; strcpy(out,"\n"); output(); sprint(out,"Device: %s\n", file10); output(); switch (chartype) { case 'A': strcpy(temp,"ASCII"); break; case 'E': strcpy(temp,"EBCDIC"); break; default: strcpy(temp,"UNKNOWN"); break; } sprint(out,"Charset: %s\n", temp); output(); sprint(out,"LRECL: %d\n", recl); output(); if (log == TRUE) strcpy(temp,"open"); else strcpy(temp,"closed"); sprint(out,"LOG file: %s (%s)\n", file1, temp); output(); if (dat == TRUE) strcpy(temp,"open"); else strcpy(temp,"closed"); sprint(out,"DAT file: %s (%s)\n", file2, temp); output(); strcpy(out,"\n"); output(); } /* Display the sizes of the next 'parm' tape blocks. */ size() { int i, b; b = atoi(parm); if (b == 0) b = 1; for (i=1; i<=b; ++i) { getblock(1); if (cchit == TRUE) return; } } /* Skip the next 'parm' tape blocks. */ skip() { int i, p; p = atoi(parm); i = magtape(4,p,lun10); if ((err = errtst()) != 0) { perror(err); } i = p - i; sprint(out,"Skipped over %d records\n", i); output(); } /* Display the STATUS of the magtape device. */ status() { int t, mtsw; puts("\n"); puts("Magtape Status Report:\n"); puts("\n"); mtsw = magtape(7,0,lun10); t = (mtsw & 24576) / 8192; if (mtsw & 8) { switch (t) { case 0: puts("1600 bpi, "); break; case 1: case 2: case 3: break; } } else { switch (t) { case 0: puts("200 bpi, "); break; case 1: puts("556 bpi, "); break; case 2: puts("800 bpi, "); break; case 3: puts("800 bpi, dump mode, "); break; } } if (mtsw & 4096) puts("7 track, "); else puts("9 track, "); if (mtsw & 2048) puts("Even parity\n"); else puts("Odd parity\n"); if (mtsw & 1024) puts("Tape is physically write locked\n"); if (mtsw & 512) puts("Tape is beyond end-of-tape marker\n"); if (mtsw & 256) puts("Tape is at beginning-of-tape (Load Point)\n"); if (mtsw & 128) puts("Last command detected tape-mark\n"); if (mtsw & 64) puts("Last READ exceeded buffersize.\n"); if (mtsw & 32) puts("Unit is off line.\n"); if (mtsw & 16) puts("Unit is TU16, TE16 or TU45.\n"); puts("Last command issued: "); switch (mtsw & 7) { case 0: puts("OFF-LINE"); break; case 1: puts("READ"); break; case 2: puts("WRITE"); break; case 3: puts("WRITE TAPE MARK"); break; case 4: puts("REWIND"); break; case 5: puts("SKIP RECORD"); break; case 6: puts("BACKSPACE RECORD"); break; } puts("\n\n"); } /* Unload the tape */ unload() { magtape(1,0,lun10); if ((err = errtst()) != 0) { perror(err); } } /*------------------------------------------------------*/ /* Support Routines (not commands in themselves) */ /*------------------------------------------------------*/ /* Anslbl will determine is the buffer looks line an */ /* Ansi label, A TRUE or FALSE is returned. */ anslbl() { char temp[5]; int i; if (buflen != 80) return(FALSE); for (i=0; i<4; ++i) { temp[i] = buffer[i]; } temp[4] = '\0'; if (streq(temp,"VOL1")) return(TRUE); if (streq(temp,"HDR1")) return(TRUE); if (streq(temp,"HDR2")) return(TRUE); if (streq(temp,"EOF1")) return(TRUE); if (streq(temp,"EOF2")) return(TRUE); return(FALSE); } /* Get a block of data from the magnetic tape device. */ getblock(arg) { fflush(stdout); if (ccpos(0) != 0) type(""); buflen = getblk(lun10,buffer,8192,0); err = errtst(); if (err == 11 && arg == 1) { strcpy(out,"EOF:\n"); output(); return; } if (err != 0 && err != 11) { perror(err); buflen = 0; return; } if (chartype == 'E' && buflen != 0) { ebcasc(buffer,buflen); } if (arg == 0) return; if (cchit == TRUE) return; sprint(out,"Recordsize: %d\n", buflen); output(); } ascii(n) int n; { char c; int i; if (n==0) return; strcpy(out," #"); output(); for (i=0; i 31 && c < 126) return(c); if (c == 27) return('$'); return(' '); } valid2(c) char c; { c = c & 0377; /* trim high byte */ if (c > 31 && c < 126) return(c); if (c == 27) return('$'); if (c == 9 || c == 10 || c == 13) return(c); return(' '); } /* Display the data on tty and logfile. */ output() { if (cchit == TRUE) return; puts(out); if (log == TRUE) fprintf(f1,"%s", out); } /* cctrap is called when the user hits a ^C. It sets */ /* the cchit flag and returns */ cctrap() { cchit = TRUE; fflush(stdout); if (ccpos(0) != 0) puts("\n"); puts("\n%Command aborted.\7\n"); }