?? vt.c
字號:
/* * Virtual tape driver - copyright 1998 Warren Toomey wkt@cs.adfa.oz.au * * $Revision: 1.9 $ * $Date: 1998/02/01 00:49:15 $ */#include <sys/param.h>#include <sys/inode.h>#include "saio.h"/* Command sent to tape server */struct vtcmd { char hdr1; /* Header, 31 followed by 42 (decimal) */ char hdr2; char cmd; /* Command, one of VTC_XXX below */ /* Error comes back in top 4 bits */ char record; /* Record we're accessing */ char blklo; /* Block number, in lo/hi format */ char blkhi; char sum0; /* 16-bit checksum */ char sum1;};/* Header bytes */#define VT_HDR1 31#define VT_HDR2 42/* Commands available */#define VTC_QUICK 0 /* Quick read, no cksum sent */#define VTC_OPEN 1#define VTC_CLOSE 2#define VTC_READ 3 /* This file only uses READ and OPEN */#define VTC_WRITE 4/* Errors returned */#define VTE_NOREC 1 /* No such record available */#define VTE_OPEN 2 /* Can't open requested block */#define VTE_CLOSE 3 /* Can't close requested block */#define VTE_READ 4 /* Can't read requested block */#define VTE_WRITE 5 /* Can't write requested block */#define VTE_NOCMD 6 /* No such command */#define VTE_EOF 7 /* End of file: no blocks left to read */#define BLKSIZE 512/* Static things */struct vtcmd vtcmd; /* Command buffer */struct vtcmd vtreply; /* Reply from server */char *vtbuf; /* Pointer to input buffer */unsigned int hitim, lotim; /* Variables for delay loop */char oddeven=0; /* Toggle status printing character */char *oddstr= ".*";char vtsendcmd(); /* Forward references */char vtgetc();/*** Standalone-dependent section *//* vtopen() is used to inform the server which record we'll be using */vtopen(io)register struct iob *io;{ register i; vtcmd.record= io->i_boff; vtcmd.cmd= VTC_OPEN; vtcmd.blklo=0; vtcmd.blkhi=0; vtsendcmd(); /* Send the command to the server */}/* vtstrategy() must be called as a READ. We send a command * to the server, get a reply, and return the amount read * (even on EOF, which may be zero) or -1 on error. */vtstrategy(io, func)register struct iob *io;{ register error, i; vtbuf= io->i_ma; /* Assume record, blklo and blkhi are ok */ /* Assume i->i_cc is in multiples of BLKSIZE */ for (i=0; i<io->i_cc; i+=BLKSIZE, vtbuf+=BLKSIZE) { vtcmd.cmd= VTC_READ; error= vtsendcmd(); /* Send the command to the server */ /* Some programs rely on */ /* the buffer being cleared to */ /* indicate EOF, e.g cat */ if (error == VTE_EOF) { vtbuf[0]=0; return(i); } if (error != 0) { printf("tape error %d", error); return(-1); } /* Increment block number for next time */ vtcmd.blklo++; if (vtcmd.blklo==0) vtcmd.blkhi++; } return(io->i_cc);}/*** Protocol-specific stuff ***/char vtsendcmd(){ register i; char error, cmd, sum0, sum1; /* Build the checksum */ vtcmd.hdr1= VT_HDR1; vtcmd.hdr2= VT_HDR2; vtcmd.sum0= VT_HDR1 ^ vtcmd.cmd ^ vtcmd.blklo; vtcmd.sum1= VT_HDR2 ^ vtcmd.record ^ vtcmd.blkhi; /* Send the command to the server */ sendcmd: vtputc(vtcmd.hdr1); vtputc(vtcmd.hdr2); vtputc(vtcmd.cmd); vtputc(vtcmd.record); vtputc(vtcmd.blklo); vtputc(vtcmd.blkhi); vtputc(vtcmd.sum0); vtputc(vtcmd.sum1); /* Now get a valid reply from the server */ getreply: vtreply.hdr1= vtgetc(); if (hitim==0) goto sendcmd; if (vtreply.hdr1!=VT_HDR1) goto getreply; vtreply.hdr2= vtgetc(); if (hitim==0) goto sendcmd; if (vtreply.hdr2!=VT_HDR2) goto getreply; vtreply.cmd= vtgetc(); if (hitim==0) goto sendcmd; vtreply.record= vtgetc(); if (hitim==0) goto sendcmd; vtreply.blklo= vtgetc(); if (hitim==0) goto sendcmd; vtreply.blkhi= vtgetc(); if (hitim==0) goto sendcmd; /* Calc. the cksum to date */ sum0= VT_HDR1 ^ vtreply.cmd ^ vtreply.blklo; sum1= VT_HDR2 ^ vtreply.record ^ vtreply.blkhi; /* Retrieve the block if no errs and a READ cmd */ if (vtreply.cmd==VTC_READ) { for (i=0; i<BLKSIZE; i++) { vtbuf[i]= vtgetc(); if (hitim==0) goto sendcmd; sum0 ^= vtbuf[i]; i++; vtbuf[i]= vtgetc(); if (hitim==0) goto sendcmd; sum1 ^= vtbuf[i]; } } /* Get the checksum */ vtreply.sum0= vtgetc(); if (hitim==0) goto sendcmd; vtreply.sum1= vtgetc(); if (hitim==0) goto sendcmd; /* Try again on a bad checksum */ if ((sum0!=vtreply.sum0) || (sum1!=vtreply.sum1)) { putchar('e'); goto sendcmd; } putchar(oddstr[oddeven]); oddeven= 1-oddeven; /* Extract any error */ error= vtreply.cmd >> 4; return(error);}/*** Harware-specific stuff ***/struct device { int rcsr,rbuf; int tcsr,tbuf;};static struct device *KL1= {0176500}; /* We use KL11 unit 1 *//* vtgetc() and vtputc(): A sort-of repeat of the getchar/putchar * code in prf.c, but without any console stuff *//* Get a character, or timeout and return with hitim zero */char vtgetc(){ register c; KL1->rcsr = 1; hitim=3; lotim=65535; while ((KL1->rcsr&0200)==0) { lotim--; if (lotim==0) hitim--; if (hitim==0) { putchar('t'); return(0); } } c = KL1->rbuf; return(c);}vtputc(c)register c;{ register s; while((KL1->tcsr&0200) == 0) ; s = KL1->tcsr; KL1->tcsr = 0; KL1->tbuf = c; KL1->tcsr = s;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -