home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / cpio-2.3-src.lha / src / amiga / cpio-2.3 / mt.c < prev    next >
C/C++ Source or Header  |  1993-06-29  |  7KB  |  302 lines

  1. /* mt -- control magnetic tape drive operation
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* If -f is not given, the environment variable TAPE is used;
  19.    if that is not set, a default device defined in sys/mtio.h is used.
  20.    The device must be either a character special file or a remote
  21.    tape drive with the form "[user@]system:path".
  22.    The default count is 1.  Some operations ignore it.
  23.  
  24.    Exit status:
  25.    0    success
  26.    1    invalid operation or device name
  27.    2    operation failed
  28.  
  29.    Operations (unique abbreviations are accepted):
  30.    eof, weof    Write COUNT EOF marks at current position on tape.
  31.    fsf        Forward space COUNT files.
  32.         Tape is positioned on the first block of the file.
  33.    bsf        Backward space COUNT files.
  34.         Tape is positioned on the first block of the file.
  35.    fsr        Forward space COUNT records.
  36.    bsr        Backward space COUNT records.
  37.    bsfm        Backward space COUNT file marks.
  38.         Tape is positioned on the beginning-of-the-tape side of
  39.         the file mark.
  40.    asf        Absolute space to file number COUNT.
  41.         Equivalent to rewind followed by fsf COUNT.
  42.    eom        Space to the end of the recorded media on the tape
  43.         (for appending files onto tapes).
  44.    rewind    Rewind the tape.
  45.    offline, rewoffl
  46.         Rewind the tape and, if applicable, unload the tape.
  47.    status    Print status information about the tape unit.
  48.    retension    Rewind the tape, then wind it to the end of the reel,
  49.         then rewind it again.
  50.    erase    Erase the tape.
  51.  
  52.    David MacKenzie <djm@gnu.ai.mit.edu> */
  53.  
  54. #include <stdio.h>
  55. #include <sys/types.h>
  56. #include <sys/stat.h>
  57. #include <sys/ioctl.h>
  58. #ifdef HAVE_SYS_MTIO_H
  59. #ifdef HAVE_SYS_IO_TRIOCTL_H
  60. #include <sys/io/trioctl.h>
  61. #endif
  62. #include <sys/mtio.h>
  63. #endif
  64. #include <sys/file.h>
  65. #include <fcntl.h>
  66. #include <errno.h>
  67. #include <getopt.h>
  68.  
  69. #if defined(HAVE_UNISTD_H)
  70. #include <unistd.h>
  71. #endif
  72. #include "rmt.h"
  73.  
  74. #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
  75. #include <string.h>
  76. #else
  77. #include <strings.h>
  78. #endif
  79.  
  80. #if defined(STDC_HEADERS)
  81. #include <stdlib.h>
  82. #else
  83. extern int errno;
  84. char *getenv ();
  85. int atoi ();
  86. void exit ();
  87. #endif
  88.  
  89. int fstat ();
  90.  
  91. int argmatch ();
  92. void check_type ();
  93. void error ();
  94. void invalid_arg ();
  95. void perform_operation ();
  96. void print_status ();
  97. void usage ();
  98.  
  99. char *opnames[] =
  100. {
  101.   "eof", "weof", "fsf", "bsf", "fsr", "bsr",
  102.   "rewind", "offline", "rewoffl", "status",
  103. #ifdef MTBSFM
  104.   "bsfm",
  105. #endif
  106. #ifdef MTEOM
  107.   "eom",
  108. #endif
  109. #ifdef MTRETEN
  110.   "retension",
  111. #endif
  112. #ifdef MTERASE
  113.   "erase",
  114. #endif
  115.  "asf",
  116.   NULL
  117. };
  118.  
  119. #define MTASF 600        /* Random unused number.  */
  120. short operations[] =
  121. {
  122.   MTWEOF, MTWEOF, MTFSF, MTBSF, MTFSR, MTBSR,
  123.   MTREW, MTOFFL, MTOFFL, MTNOP,
  124. #ifdef MTBSFM
  125.   MTBSFM,
  126. #endif
  127. #ifdef MTEOM
  128.   MTEOM,
  129. #endif
  130. #ifdef MTRETEN
  131.   MTRETEN,
  132. #endif
  133. #ifdef MTERASE
  134.   MTERASE,
  135. #endif
  136.   MTASF
  137. };
  138.  
  139. /* If nonzero, don't consider file names that contain a `:' to be
  140.    on remote hosts; all files are local.  Always zero for mt;
  141.    since when do local device names contain colons?  */
  142. int f_force_local = 0;
  143.  
  144. struct option longopts[] =
  145. {
  146.   {"file", 1, NULL, 'f'},
  147.   {"version", 0, NULL, 'V'},
  148.   {"help", 0, NULL, 'H'},
  149.   {NULL, 0, NULL, 0}
  150. };
  151.  
  152. /* The name this program was run with.  */
  153. char *program_name;
  154.  
  155. void
  156. main (argc, argv)
  157.      int argc;
  158.      char **argv;
  159. {
  160.   extern char *version_string;
  161.   short operation;
  162.   int count;
  163.   char *tapedev;
  164.   int tapedesc;
  165.   int i;
  166.  
  167.   program_name = argv[0];
  168.   tapedev = NULL;
  169.   count = 1;
  170.  
  171.   while ((i = getopt_long (argc, argv, "f:V:H", longopts, (int *) 0)) != -1)
  172.     {
  173.       switch (i)
  174.     {
  175.     case 'f':
  176.       tapedev = optarg;
  177.       break;
  178.  
  179.     case 'V':
  180.       printf ("GNU mt %s", version_string);
  181.       exit (0);
  182.       break;
  183.  
  184.     case 'H':
  185.     default:
  186.       usage (stdout, 0);
  187.     }
  188.     }
  189.  
  190.   if (optind == argc)
  191.     usage (stderr, 1);
  192.  
  193.   i = argmatch (argv[optind], opnames);
  194.   if (i < 0)
  195.     {
  196.       invalid_arg ("tape operation", argv[optind], i);
  197.       exit (1);
  198.     }
  199.   operation = operations[i];
  200.  
  201.   if (++optind < argc)
  202.     count = atoi (argv[optind]);
  203.   if (++optind < argc)
  204.     usage (stderr, 1);
  205.  
  206.   if (tapedev == NULL)
  207.     {
  208.       tapedev = getenv ("TAPE");
  209.       if (tapedev == NULL)
  210. #ifdef DEFTAPE            /* From sys/mtio.h.  */
  211.         tapedev = DEFTAPE;
  212. #else
  213.     error (1, 0, "no tape device specified");
  214. #endif
  215.     }
  216.  
  217.   tapedesc = rmtopen (tapedev, O_RDONLY, 0);
  218.   if (tapedesc == -1)
  219.     error (1, errno, "%s", tapedev);
  220.   check_type (tapedev, tapedesc);
  221.  
  222.   if (operation == MTASF)
  223.     {
  224.       perform_operation (tapedev, tapedesc, MTREW, 1);
  225.       operation = MTFSF;
  226.     }
  227.   perform_operation (tapedev, tapedesc, operation, count);
  228.   if (operation == MTNOP)
  229.     print_status (tapedev, tapedesc);
  230.  
  231.   if (rmtclose (tapedesc) == -1)
  232.     error (2, errno, "%s", tapedev);
  233.  
  234.   exit (0);
  235. }
  236.  
  237. void
  238. check_type (dev, desc)
  239.      char *dev;
  240.      int desc;
  241. {
  242.   struct stat stats;
  243.  
  244.   if (_isrmt (desc))
  245.     return;
  246.   if (fstat (desc, &stats) == -1)
  247.     error (1, errno, "%s", dev);
  248.   if ((stats.st_mode & S_IFMT) != S_IFCHR)
  249.     error (1, 0, "%s is not a character special file", dev);
  250. }
  251.  
  252. void
  253. perform_operation (dev, desc, op, count)
  254.      char *dev;
  255.      int desc;
  256.      short op;
  257.      int count;
  258. {
  259.   struct mtop control;
  260.  
  261.   control.mt_op = op;
  262.   control.mt_count = count;
  263.   if (rmtioctl (desc, MTIOCTOP, &control))
  264.     error (2, errno, "%s", dev);
  265. }
  266.  
  267. void
  268. print_status (dev, desc)
  269.      char *dev;
  270.      int desc;
  271. {
  272.   struct mtget status;
  273.  
  274.   if (rmtioctl (desc, MTIOCGET, &status))
  275.     error (2, errno, "%s", dev);
  276.  
  277.   printf ("drive type = %d\n", (int) status.mt_type);
  278. #if defined(hpux) || defined(__hpux__)
  279.   printf ("drive status (high) = %d\n", (int) status.mt_dsreg1);
  280.   printf ("drive status (low) = %d\n", (int) status.mt_dsreg2);
  281. #else
  282.   printf ("drive status = %d\n", (int) status.mt_dsreg);
  283. #endif
  284.   printf ("sense key error = %d\n", (int) status.mt_erreg);
  285.   printf ("residue count = %d\n", (int) status.mt_resid);
  286. #if !defined(ultrix) && !defined(__ultrix__) && !defined(hpux) && !defined(__hppux__) && !defined(__osf__)
  287.   printf ("file number = %d\n", (int) status.mt_fileno);
  288.   printf ("block number = %d\n", (int) status.mt_blkno);
  289. #endif
  290. }
  291.  
  292. void
  293. usage (fp, status)
  294.   FILE *fp;
  295.   int status;
  296. {
  297.   fprintf (fp, "\
  298. Usage: %s [-V] [-f device] [--file=device] [--help] [--version] operation [count]\n",
  299.        program_name);
  300.   exit (status);
  301. }
  302.