int totalreadblocks
= 0 ;
int totalwritefiles
= 0 ;
int totalwriteblocks
= 0 ;
int totalwritelines
= 0 ;
int totalwritechars
= 0 ;
char *device
= "/dev/rmt12";
timetemp
= time((long *)NULL
);
tm
= localtime(&timetemp
);
/* loop through first argument (key) */
for (key
= *argv
++; *key
; key
++)
if (*argv
== NULL
|| argc
<1) {
"ansitape: 'f' option requires tape name \n");
if (*argv
== NULL
|| argc
<1) {
"ansitape: 'n' option requires file name\n");
if (*argv
== NULL
|| argc
<1) {
"ansitape: 'l' option requires label\n");
"ansitape: 'F' options requires recordsize and blocksize specifiers.\n"
tmp
= sscanf(*argv
++," %d%c ",&recordsize
,&blockchar
);
fprintf(stderr
,"illegal recordsize: recordsize set to 80\n");
if(blockchar
== 'b') recordsize
*= 512;
if(blockchar
== 'k') recordsize
*= 1024;
"ansitape: 'F' option requires blocksize specifier \n");
tmp
= sscanf(*argv
++," %d%c ",&blocksize
,&blockchar
);
fprintf(stderr
,"illegal blocksize: blocksize set to 2048\n");
if(blockchar
== 'b') blocksize
*= 512;
if(blockchar
== 'k') blocksize
*= 1024;
if(blocksize
<18) blocksize
=18;
if(blocksize
>62*1024) blocksize
=62*1024;
"ansitape: 'b' option requires blocksize specifier \n");
tmp
= sscanf(*argv
++," %d%c ",&blocksize
,&blockchar
);
fprintf(stderr
,"illegal blocksize: blocksize set to 2048\n");
if(blockchar
== 'b') blocksize
*= 512;
if(blockchar
== 'k') blocksize
*= 1024;
if(blocksize
<18) blocksize
=18;
if(blocksize
>62*1024) blocksize
=62*1024;
/*I know, this should be rflag, but I just don't like r for write*/
fprintf(stderr
, "ansitape: %c: unknown option\n", *key
);
if (!wflag
&& !xflag
&& !tflag
)
tape
= open(device
,wflag
?O_RDWR
:O_RDONLY
,NULL
);
fprintf(stderr
,"tape not accessable - check if drive online and write ring present\n");
if( readfile(tape
,argc
,argv
) ) break;
names
=fopen(namelist
,"r");
fprintf(stderr
,"unable to open namelist file - no files added to tape\n");
count
= sscanf(line
,"%s %s",unixname
,vmsname
);
if(count
<1) continue; /* blank line */
if(count
==1) strcpy(vmsname
,unixname
);
if(filecheck(&file
,unixname
)) continue;
writefile(tape
,file
,vmsname
,tapename
,filenum
,year
,day
,blocksize
,
for(argnum
=0;argnum
<argc
;argnum
++) {
if(filecheck(&file
,filename
)) continue;
writefile(tape
,file
,filename
,tapename
,filenum
,year
,day
,
if(vflag
&& (tflag
|| xflag
)) {
fprintf(stdout
," read %d files in %d blocks (%d lines, %d chars)\n",
totalreadfiles
,totalreadblocks
,totalreadlines
,totalreadchars
);
fprintf(stdout
," wrote %d files in %d blocks (%d lines, %d chars)\n",
totalwritefiles
,totalwriteblocks
,totalwritelines
,totalwritechars
);
"ansitape: usage: ansitape -{rxtc}[flnvb] [filename] [label] [filename] [blocksize] [files]\n");
writefile(tape
,file
,filename
,tapename
,filenum
,year
,day
,blocksize
,recordsize
)
writehdr1(tape
,filename
,tapename
,filenum
,year
,day
);
writehdr2(tape
,blocksize
,recordsize
);
writedata(tape
,file
,filename
,&blocks
,blocksize
,recordsize
);
writeeof1(tape
,filename
,tapename
,filenum
,year
,day
,blocks
);
writeeof2(tape
,blocksize
,recordsize
);
writedata(tape
,file
,filename
,blocks
,blocksize
,recsize
)
ibufstart
= ibuf
= malloc((unsigned)(blocksize
<4096?8200:(2*blocksize
+10)));
obufstart
= obuf
= malloc((unsigned)(blocksize
+10));
endobuf
= obuf
+ blocksize
;
if(ibuf
+i
>=endibuf
) { /* end of input buffer */
strncpy(ibufstart
,ibuf
,endibuf
-ibuf
); /* copy leftover to start */
ibuf
= ibufstart
+(endibuf
-ibuf
); /* point to end of valid data */
got
= read(file
,ibuf
,blocksize
<4096?4096:2*blocksize
); /* read in a chunk */
ibuf
= ibufstart
; /* point to beginning of data */
if(got
== 0) { /* end of input */
if(ibuf
==ibufstart
){ /* no leftovers */
ibuf
[i
]='\n'; /* fake extra newline */
if(obuf
+i
+4 > endobuf
) { /* end of output buffer */
printf("record exceeds blocksize - file truncated\n");
/* filled up output record - have to fill,output,restart*/
for(j
=obuf
;j
<endobuf
;j
++) {
success
= write(tape
,obufstart
,blocksize
);
if(success
!= blocksize
) {
fprintf(stderr
," hard write error: write aborted\n");
if(ibuf
[i
] == '\n') { /* end of line */
obuf
[0] = ((i
+4)/1000) + '0';
obuf
[1] = (((i
+4)/100)%10) + '0';
obuf
[2] = (((i
+4)/10)%10) + '0';
obuf
[3] = (((i
+4)/1)%10) + '0';
obuf
+= (4+i
); /* size + strlen */
ibuf
+= (1+i
); /* newline + strlen */
continue; /* back to the top */
/* exited - write last record and go for lunch */
for(j
=obuf
;j
<endobuf
;j
++) {
success
= write(tape
,obufstart
,blocksize
);
if(success
!= blocksize
) {
fprintf(stderr
," hard write error: write aborted\n");
/* writing an 'F' format tape */
got
= read(file
,ibuf
,recsize
+1);
/* no more data, so force the record out */
} else if(got
!= recsize
+1) {
printf("short read: filled\n");
} else if( *(ibuf
+recsize
) != '\n') {
printf("corrupted record - write aborted\b");
if(obuf
+recsize
>endobuf
) {
/*would overflow output buffer, so fill up old buffer */
for(j
=obuf
;j
<endobuf
;j
++) {
success
= write(tape
,obufstart
,blocksize
);
if(success
!= blocksize
) {
fprintf(stderr
," hard write error: write aborted\n");
bcopy(ibuf
,obuf
,recsize
);
fprintf(stdout
,"r - %s: %d lines (%d chars) in %d tape blocks\n",
filename
,numline
,numchar
,numblock
);
totalwritechars
+= numchar
;
totalwritelines
+= numline
;
totalwriteblocks
+= numblock
;
ioctl(tape
,MTIOCTOP
,&mtop
);
ioctl(tape
,MTIOCTOP
,&mtop
);
ioctl(tape
,MTIOCTOP
,&mtop
);
ioctl(tape
,MTIOCTOP
,&mtop
);
writehdr1(tape
,filename
,tapename
,filenum
,year
,day
)
"HDR1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d 000000DECFILE11A "
,filename
,tapename
,filenum
,year
,day
,year
,day
);
writeeof1(tape
,filename
,tapename
,filenum
,year
,day
,blocks
)
"EOF1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d %6.6dDECFILE11A "
,filename
,tapename
,filenum
,year
,day
,year
,day
,blocks
);
writehdr2(tape
,blocksize
,recordsize
)
sprintf(buf
,"HDR2%c%5.5d%5.5d%35.35s00%28.28s",fflag
?'F':'D',
blocksize
,recordsize
," "," ");
writeeof2(tape
,blocksize
,recordsize
)
sprintf(buf
,"EOF2%c%5.5d%5.5d%35.35s00%28.28s",fflag
?'F':'D',
blocksize
,recordsize
," "," ");
sprintf(buf
, "HDR3%76.76s"," ");
sprintf(buf
, "EOF3%76.76s"," ");
sprintf(buf
,"VOL1%-6.6s %26.26sD%cC%10.10s1%28.28s3",tapename
," ",'%'," "," ");
fprintf(stdout
," tape labeled %-6.6s\n",tapename
);
sscanf(buf
,"VOL1%6s",tapename
);
fprintf(stdout
," tape was labeled %-6.6s\n",tapename
);
*string
= toupper(*string
);
if(!(read(tape
,buf
,80))) return(1); /* no hdr record, so second eof */
sscanf(buf
,"HDR1%17s",filename
);
sscanf(buf
,"HDR2%c%5d%5d",&mode
,&blocksize
,&recordsize
);
blocksize
= blocksize
>recordsize
?blocksize
:recordsize
;
skipfile(tape
); /* throw away rest of header(s) - not interesting */
ibufstart
=ibuf
=malloc((unsigned)(blocksize
+10));
endibuf
=ibufstart
+blocksize
;
} else for(argnum
=0;argnum
<argc
;argnum
++) {
if(!strcmp(filename
,argv
[argnum
])) {
file
= fopen(filename
,"w");
while(size
=read(tape
,ibufstart
,blocksize
)) {
* somebody's brain damaged program leaves
* short blocks on the tape - fill them up to size
* (this is work THEY should have done before writing
* their undersized blocks)
for(fixpoint
=ibufstart
+size
;fixpoint
<endibuf
;fixpoint
++) {
while(strncmp("^^^^",ibuf
,4)) {
#define getsize(a) ((a[0]-'0')*1000)+((a[1]-'0')*100)+((a[2]-'0')*10)+(a[3]-'0')
#define bad(a) (!(isdigit(ibuf[a])))
if(bad(0) || bad(1) || bad(2) || bad(3)) {
fprintf(stderr
, "error: bad record length field - file may be corrupted, skipping\n");
fwrite(ibuf
+4,sizeof(char),size
-4,file
);
fprintf(stderr
,"error: bad tape records(s) - file may be corrupted\n");
if(ibuf
>endibuf
-4) break;
} else if (mode
== 'F') {
file
= fopen(filename
,"w");
while(read(tape
,ibufstart
,blocksize
)) {
while(ibuf
+recordsize
<= endibuf
) {
fwrite(ibuf
,sizeof(char),recordsize
,file
);
fprintf(stderr
,"unknown record mode (%c) - file %s skipped\n",
skipfile(tape
); /* throw away actual file */
/* not interested in contents of file, so move fast */
skipfile(tape
); /* throw away eof stuff - not interesting */
totalreadchars
+= numchar
;
totalreadlines
+= numline
;
totalreadblocks
+= numblock
;
if(xflag
&& vflag
&& ok
) {
fprintf(stdout
,"x - %s: %d lines (%d chars) in %d tape blocks\n",
filename
,numline
,numchar
,numblock
);
fprintf(stdout
,"t - %s: %d lines (%d chars) in %d tape blocks\n",
filename
,numline
,numchar
,numblock
);
if ((buf
.st_mode
& S_IFDIR
)==S_IFDIR
) {
fprintf(stderr
,"%s: directory - skipped\n",name
);
if ((buf
.st_mode
& S_IFCHR
)==S_IFCHR
) {
fprintf(stderr
,"%s: character device - skipped\n",name
);
if ((buf
.st_mode
& S_IFBLK
)==S_IFBLK
) {
fprintf(stderr
,"%s: block device - skipped\n",name
);
if ((buf
.st_mode
& S_IFLNK
)==S_IFLNK
) {
fprintf(stderr
,"%s: symbolic link - skipped\n",name
);
if ((buf
.st_mode
& S_IFSOCK
)==S_IFSOCK
) {
fprintf(stderr
,"%s: socket - skipped\n",name
);
*file
= open(name
,O_RDONLY
,NULL
);
if(read(*file
,&sample
,sizeof(struct exec
))>= sizeof(struct exec
)) {
if(!(N_BADMAG(sample
))) {
/* the format requires either fixed blocked records,
* or variable format records with each record remaining
* entirely within a tape block - this limits the
* distance between \n's to 2044 bytes, something
* which is VERY rarely true of executables, so
* we don't even try with them....
fprintf(stderr
,"%s: executable - skipped\n",name
);
/* either couldn't read sizeof(struct exec) or wasn't executable */
/* so we assume it is a reasonable file until proven otherwise */