home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
tapeutils
/
tuuros.c
< prev
next >
Wrap
C/C++ Source or Header
|
2020-01-01
|
7KB
|
251 lines
/*
* ostape.c: reads OS standard labeled tapes, using dd to do the real work.
*
* Usage: ostape
*
* Christine Gianone, CUCCA, December 1986
*
*/
/* Preprocessor Stuff */
#include <stdio.h>
#include <ctype.h>
#define MAXLEN 90 /* Max length for a label line */
#define MAXFN 17 /* Max length for filename */
#define XVOL1 0 /* Symbols for label identifiers */
#define XEOV1 1
#define XHDR1 2
#define XHDR2 3
#define XEOF1 4
#define XEOF2 5
#define XUVL1 6
#define XUHL1 7
#define XUTL1 8
/* Global Declarations */
char buff[MAXLEN]; /* Input line buffer */
FILE *fp, *fopen(); /* File pointer & open function */
struct lbl { /* Label ids and case indexes */
char *id;
int code;
};
struct lbl tbl[10] = {
"VOL1", XVOL1, /* Volume label */
"EOV1", XEOV1, /* End-of-Volume */
"HDR1", XHDR1, /* Header 1 */
"HDR2", XHDR2, /* Header 2 */
"EOF1", XEOF1, /* End of file 1 */
"EOF2", XEOF2, /* and 2 */
"UVL1", XUVL1, /* User labels */
"UHL1", XUHL1, /* are */
"UTL1", XUTL1 /* ignored... */
};
int nids = (sizeof(tbl) / sizeof(struct lbl));
extern int errno; /* System error stuff */
extern char *sys_errlist[];
char vn[6]; /* Volume name */
char fn[MAXFN]; /* File name */
int bs; /* Blocksize */
int rl; /* Record length */
int bc; /* Block count in EOF1 */
char rf; /* Record format */
char *ddhdr = "dd if=/dev/rmt12 of=hdr.tmp ibs=800 cbs=80 conv=unblock,ascii";
/* Main function */
main(argc,argv)
int argc; /* Command line arguments */
char *argv[]; /* (not used) */
{
int x; /* Declare local variables */
int files = 0; /* Files processed */
int skip = 0; /* Files skipped */
char ddcmd[200];
for (files = 0 ; ; )
{
unlink("hdr.tmp"); /* Delete temp header file */
system(ddhdr);
if ((x = phdr()) < 0) /* Process the header */
break;
else if (x == 0)
{
printf("dd cannot read %s in %c format", fn, rf);
system("mt fsf 2"); /* Skip forward 2 files */
skip++; /* to next tape header. */
continue;
}
sprintf(ddcmd,
"dd if=/dev/rmt12 of=%s ibs=%d cbs=%d conv=unblock,ascii",
fn,bs,rl);
system(ddcmd); /* Run the dd command above */
sprintf(ddcmd, "ls -l %s", fn); /* to read the tape file */
files++; /* Count the file. */
system(ddcmd); /* Run the list command above */
unlink("eof.tmp"); /* Delete old temp trailer file */
system(ddhdr);
if ((x = peof()) < 0) /* Process trailer labels */
break;
}
unlink("hdr.tmp");
unlink("eof.tmp");
printf("All done! Files Read: %d -- Files Skipped: %d\n", files, skip);
}
/* Process a header ... */
/* Returns 1 valid file header with recfm F, */
/* 0 if valid file header with some other recfm (which dd can't handle), or */
/* -1 otherwise - fatal error or end of tape */
phdr()
{
int i, j, k, l = 0;
char c;
*fn=bs=rl=rf=0; /* Initialize file variables */
fp = fopen("hdr.tmp", "r"); /* Try to open header file */
if (fp == NULL) /* Check for errors */
{
printf("%s\n",sys_errlist[errno]); /* Oops, can't... */
return(-1);
}
while (fgets(buff, MAXLEN, fp) != NULL) /* Read each line */
{
switch (k = lookup()) { /* Got line, look up label id */
case XVOL1: /* VOL1 */
buff[10] = 0;
printf("VOL: '%s'\n", buff+4); /* Print volid */
break;
case XEOV1: /* End of volume */
printf("End of volume\n");
return(-1);
case XHDR1: /* File header 1 */
for (i = 0; i < MAXFN; i++) /* Copy name */
{
c = buff[i+4]; /* and convert to lower case */
fn[i] = isupper(c) ? tolower(c) : c;
}
for (i = MAXFN - 1; i > 0; i--) /* Trim trailing blanks */
{
if (fn[i] == ' ')
fn[i] = '\0';
else break;
}
printf("Filename: '%s'\n", fn); /* Print the name */
break;
case XHDR2: /* File header 2 */
buff[15] = 0;
rl = atoi (buff + 10); /* Record length */
buff[10] = 0;
bs = atoi (buff + 5); /* Block size */
rf = buff[4]; /* Record format */
printf ("rl: %d, bs: %d, rf: %c\n", rl, bs, rf);
break;
case XUVL1: /* User headers */
case XUHL1: /* (ignored) */
break;
default:
printf("Unexpected ID header label:\n%s\n",buff);
if(++l > 3) /* Give up if too many, */
return(-1); /* probably not real headers */
break;
}
}
if (fclose(fp) == EOF) /* Close the file */
{
printf("%s\n",sys_errlist[errno]);
return(-1);
}
if (*fn != '\0' ) /* If we have a filename */
return((rf == 'F') ? 1 : 0); /* return 1 or 0 based on recfm */
else return(-1); /* otherwise probably end of tape */
}
/* Process trailer labels... */
/* Returns -1 if the trailer label is invalid, otherwise 0. */
peof()
{
int i, j, k, l = 0; /* Local variables */
char c;
bc = 0; /* Block count */
fp = fopen("eof.tmp", "r"); /* Try to open trailer label file */
if (fp == NULL) /* Check for errors */
{
printf("%s\n",sys_errlist[errno]);
return(-1);
}
while (fgets(buff, MAXLEN, fp) != NULL) /* Read each line */
{
switch (k = lookup()) /* Got line, look up label id */
{
case XEOF1: /* End of file 1 */
buff[60] = 0;
bc = atoi (buff + 54); /* Get block count & print it */
printf("EOF: %d block%c\n", bc, (bc == 1) ? ' ' : 's');
break;
case XEOV1: /* End of volume */
printf("End of volume");
return(-1);
case XEOF2: /* End of file 2 */
break;
case XUTL1: /* User trailer */
break; /* (ignored) */
default:
printf("Unexpected ID in trailer label:\n%s\n",buff);
if (++l > 3) /* If too many unknowns, */
return(-1); /* probably not a real trailer. */
break;
}
}
if (fclose(fp) == EOF) /* Close the file */
{
printf("%s\n",sys_errlist[errno]);
return(-1);
}
return(0);
}
/* Lookup */
lookup() /* Look up label ID, */
{ /* return case index, or -1. */
int i, j;
for (j = 0; j < nids; j++) /* For each ID in our list (row) */
{
for (i = 0; i < 4; i++) /* Compare each character (column) */
{
if (buff[i] != tbl[j].id[i]) /* If chars differ, */
break; /* then try next row, */
else continue; /* otherwise keep comparing. */
}
if (i == 4) return (tbl[j].code); /* i is 4 if all chars match. */
}
return (-1); /* No match, return -1. */
}