home *** CD-ROM | disk | FTP | other *** search
- /* @(#) wt.c - a Wangtek command utility.
- * A utility to issue the ioctl(2) commands to retension
- * and/or erase cartridge tapes using the Wangtek (wt) driver.
- * There was no way to accomplish this provided with the system,
- * and while trivial, one needs to be able to retension new tapes
- * and sometimes erase cartridges, to remove records that confuse
- * the less-than-great Wangtek driver provided by ISC. Some other
- * basic ops added as time passed that, while possible by proper
- * command line operations using various commands, these were awkward
- * and error prone. This kludge helps a little bit.
- * Of course, the REAL answer is a decent driver, and proper support
- * utilities.
- *
- * This thing will try /dev/rmt0, if that fails, it will look at
- * /dev/tape, then /dev/rSA/rmt0. If given a name via -f option it
- * will try only that name.
- *
- * Tossed together (literally) by pat@rwing Fri Aug 10 22:54:44 PDT 1990
- *
- * Placed in the Public Domain by pat@rwing.
- */
-
- #include <sys/wtioctl.h>
- #include <stdio.h>
- #include <errno.h>
- #include <fcntl.h>
-
- #define NOENTS 4
-
- /* HUNK
- * size of read() requests when scanning over data - I heard that ctg
- * tapes block at 63k, performance trials tend to bear this out.
- */
- #define HUNK 64512
-
- void exit(); /* to keep lint(1) smiling */
- void usage();
-
- /* usual default names for the normal rewind-on-close device */
- char *tape[NOENTS] = {
- "/dev/rmt0",
- "/dev/tape",
- "/dev/rSA/tape",
- (char *)NULL
- };
-
- /* usual default names for the NO rewind-on-close device */
- char *ntape[NOENTS] = {
- "/dev/rnmt0",
- "/dev/ntape",
- "/dev/rSA/ntape",
- (char *)NULL
- };
-
- /* foundation of a couple of commonly used error messages */
- char msgfmt[] = "Unable to open tape for %s\n";
- char errnofmt[] = "Return from errno = %d\n";
- extern int errno;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int fd, i, j, count, result;
- char scratch[HUNK]; /* buffer for reads to scan over data */
- char *cname=argv[0];
-
- /* see if user specifies a device, and if so, get its name */
- if (*argv[1] == '-') {
- if (argv[1][1] == 'f') {
- if (argv[1][2] != '\0') {
- ntape[0] = tape[0] = &argv[1][2];
- argv += 1; argc -= 1;
- } else {
- ntape[0] = tape[0] = argv[2];
- argv += 2; argc -= 2;
- }
- ntape[1] = tape[1] = (char *)NULL; /* lock out default names */
- } else {
- (void) fprintf(stderr,
- "\n%s: %2.2s -- invalid option\n\n", cname, argv[1]);
- usage(cname);
- exit(1);
- }
- }
-
- /* erase tape */
- if (!strncmp(argv[1], "erase", 3)){
- /* search for a working device */
- for (i = 0; tape[i] != NULL && (fd = open(tape[i], O_WRONLY)) < 0; i++)
- ;
- if (fd < 0) { /* open failed, complain and exit */
- (void) fprintf(stderr, msgfmt, "writing");
- (void) perror("");
- exit(errno); /* in case a script can use it */
- }
- if (ioctl(fd, WTQICMD, ERASE) <0)
- perror("erase ioctl failed");
-
- (void) close(fd); /* if close fails, nothing we can do about it */
- } /* end erase */
-
- else if (!strncmp(argv[1], "retens", 3)) { /* retension tape */
- for (i = 0; tape[i] != NULL && (fd = open(tape[i], O_RDONLY)) < 0; i++)
- ;
- if (fd < 0) {
- (void) fprintf(stderr, msgfmt, "reading");
- (void) perror("");
- exit(errno);
- }
- if (ioctl(fd, WTQICMD, RETENS) < 0)
- perror("retension ioctl failed");
-
- (void) close(fd);
- } /* end retension */
-
- else if (!strncmp(argv[1], "rewind", 3)) { /* rewind */
- for (i = 0; tape[i] != NULL && (fd = open(tape[i], O_RDONLY)) < 0; i++)
- ;
- if (fd < 0) {
- (void) fprintf(stderr, msgfmt, "reading");
- (void) perror("");
- exit(errno);
- }
- (void) close(fd); /* no rewind ioctl(), so fake it with open/close */
- } /* end rewind */
-
- /* This operation is faked, so it does not handle requests
- * to skip over more files (archives) than exist on the tape.
- * Still, its useful to position the tape if one knows the number
- * of recordings are on the ctg.
- */
-
- else if (!strncmp(argv[1], "fsf", 3)) { /* forward skip over archive */
- count = atoi(argv[2]);
- count = (count == 0 ? 1 : count);
- for (j = 0; j < count; j++) {
- for (i = 0; ntape[i] != NULL /* split to keep on screen */
- && (fd = open(ntape[i], O_RDONLY)) < 0; i++)
- ;
- if (fd < 0) {
- (void) fprintf(stderr, msgfmt, "reading");
- (void) perror("");
- exit(errno);
- }
-
- while((result = read(fd, scratch, HUNK)) > 0)
- ;
-
- if (result < 0) {
- perror("past EOD - rewind tape to use");
- exit(1);
- }
- (void) close(fd); /* closing tape opened as ntape holds position */
- }
- } /* end fwd skip file */
-
- else { /* unrecognized cmd */
- usage(cname); /* tell user how to use this thing */
- exit(1); /* give a failed exit */
- }
- exit(0);
- /*NOTREACHED*/
- }
-
- void usage(cname)
- char *cname;
- {
-
- /* void casts are to make lint shut up */
- (void) fprintf(stderr, "Command utility for Wangtek ctg drives.\n");
- (void) fprintf(stderr, "Usage: %s [-f device] command \n", cname);
- (void) fprintf(stderr, "command is one of:\n");
- (void) fprintf(stderr, " erase - erase tape\n");
- (void) fprintf(stderr, " retens - retension tape \n");
- (void) fprintf(stderr, " rewind - rewind a tape left unwound\n");
- (void) fprintf(stderr, " fsf [n] - skip over file or archive on tape\n");
- (void) fprintf(stderr, "if an open fails, wt tries other names for ");
- (void) fprintf(stderr, "the tape device,\nin case a node wasn't");
- (void) fprintf(stderr, "created, or was removed. If a name is given by\n");
- (void) fprintf(stderr, "the -f option, only that name will be tried.\n");
- }
-