buck@siswat.UUCP (A. Lester Buck) (01/15/90)
It certainly isn't very hard to do a tape manipulating program. Here is what I wrote several years ago to follow the man page for "mt", the SVR2 tape manipulating command. This was for use with some tape drivers I was moving around from system to system, so I had to be able to move the IOCTL manipulator with me. I left out code for checking the environment variable TAPE and using that before the default device - feel free to add it. And the commands much match exactly, not just in the first unique prefix. I added a few synonyms for some commands, and most drivers do not support backspace file and backspace record, so pick and choose your commands. Mt returns 0 exit status on success, 1 if command unrecognized, and 2 if an operation failed. This program requires the sys/mtio.h (or whatever) header which defines the IOCTL's for your specific driver, but that is copyrighted and specific for your drivers and system. Of course, this program won't help much if you don't have such IOCTL information. #include <stdio.h> #include <sys/types.h> #include <fcntl.h> #include <sys/mtio.h> #define DEF_DEVICE "/dev/rmt/0" #define FAIL (-1) struct mtop mtop = {-1, 1}; struct entry { int op; char *name; } table[] = { { MTREW, "rewind"}, { MTREW, "rew"}, { MTOFFL, "offline"}, { MTOFFL, "rewoffl"}, { MTWEOF, "eof"}, { MTWEOF, "weof"}, { MTFSF, "fsf"}, { MTFSR, "fsr"}, { MTRETEN, "reten"}, { MTERASE, "erase"}, { MTBSF, "bsf"}, { MTBSR, "bsr"}, { MTNOP, "nop"} }; void usage() { fprintf(stderr, "usage: mt [-f tapename] command count\n"); exit(1); } main(argc, argv) int argc; char **argv; { int fd, entries, i; char *devpath, *cmdname; if (argc < 2) { usage(); } if (strcmp(*++argv, "-f") == 0) { switch (argc) { case 4: devpath = *++argv; cmdname = *++argv; break; case 5: devpath = *++argv; cmdname = *++argv; mtop.mt_count = atoi(*++argv); break; default: usage(); } } else { devpath = DEF_DEVICE; switch (argc) { case 2: cmdname = *argv; break; case 3: cmdname = *argv; mtop.mt_count = atoi(*++argv); break; default: usage(); } } if ((fd=open(devpath, O_RDONLY)) == FAIL) { fprintf(stderr, "mt: open failed on %s\n", devpath); exit(1); } entries = sizeof(table)/sizeof(struct entry); for ( i=0; i < entries; i++ ) { if (strcmp(table[i].name, cmdname) == 0) { mtop.mt_op = table[i].op; break; } } if (mtop.mt_op == -1) { fprintf(stderr, "mt: invalid command %s\n", cmdname); exit(1); } if (ioctl(fd, (int)MTIOCTOP, (caddr_t)&mtop) == FAIL) { perror("mt: "); exit(2); } exit(0); } -- A. Lester Buck buck@siswat.lonestar.org ...!texbell!moray!siswat!buck