/*
TAPEINFO is a Linux utility to dump the inquiry and log pages of the
Hewlett-Packard C1533A tape drive.

Copyright 1995 Eric L. Smith

TAPEINFO is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License version 2 as published by the Free
Software Foundation.  Note that I am not granting permission to redistribute
or modify TAPEINFO under the terms of any later version of the General Public
License.

This program is distributed in the hope that it will be useful (or at least
amusing), but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with
this program (in the file "COPYING"); if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

$Header: /usr/home/kolwynia/eric/tapeinfo/RCS/tapeinfo.c,v 1.8 1995/09/11 18:20:50 eric Exp eric $
*/

#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>

#include "tapeinfo.h"
#include "inquiry.h"
#include "logsense.h"
#include "modesense.h"


char const version_msg [] = "TAPEINFO version %s  %s\n";
char const copyright_msg [] = "Copyright 1995 Eric L. Smith\n";


void print_version (FILE *f)
{
  fprintf (f, version_msg, tapeinfo_version_string, tapeinfo_date_string);
  fprintf (f, "%s", copyright_msg);
}


char *progn;

void fatal (int ret, char *format, ...)
{
  va_list ap;

  if (format)
    {
      fprintf (stderr, "fatal error: ");
      va_start (ap, format);
      vfprintf (stderr, format, ap);
      va_end (ap);
    }
  if (ret == 1)
    {
      fprintf (stderr, "usage: %s device [options]\n", progn);
      fprintf (stderr,
"<device> must be a generic SCSI device (/dev/sgb), not the tape device\n"
"(/dev/st0 or /dev/nst0)\n"
"\n"
"Available options:\n"
"-i<nn>     display Inquiry page <nn>\n"
"-m<nn>     display Mode Sense page <nn>\n"
"-l<nn>     display Log Sense page <nn>\n"
"--help     display this text\n"
"--version  display version number\n"
"\n"
"With no options, a list of available pages will be displayed.  Note that\n"
"the page numbers (<nn>) are in hexadecimal.\n"
"\n");
      print_version (stderr);
    }
  exit (ret);
}


#define BYTES_PER_LINE 16

void hex_dump (FILE *f, unsigned char *buf, unsigned long len)
{
  unsigned long i, j;

  for (i = 0; i < len; i+= BYTES_PER_LINE)
    {
      fprintf (f, "%04x: ", i);
      for (j = i; j < i + BYTES_PER_LINE; j++)
	if (j < len)
	  fprintf (f, "%02x ", buf [j]);
	else
	  fprintf (f, "   ");
      for (j = i; j < i + BYTES_PER_LINE; j++)
	if (j < len)
	  {
	    if ((buf [j] >= ' ') && (buf [j] <= '~'))
	      fprintf (f, "%c", buf [j]);
	    else
	      fprintf (f, ".");
	  }
      else
	fprintf (f, " ");
      fprintf (f, "\n");
    }
}


unsigned char buf1 [BUFFER_SIZE];
unsigned char buf2 [BUFFER_SIZE];


int main (int argc, char *argv [])
{
  int fd;
  int i;
  unsigned char page;

  progn = argv [0];

  if (argc < 2)
    fatal (1, "device must be specified\n");

  fd = open (argv [1], O_RDWR);
  if (fd == -1)
    fatal (2, "unable to open device\n");

#if 0
  do_inquiry (stdout, fd);
#endif

  if (argc == 2)
    {
      print_inquiry_pages (stdout, fd, 0);
      print_mode_sense_pages (stdout, fd, 0);
      print_log_sense_pages (stdout, fd, 0);
    }

  for (i = 2; i < argc; i++)
    {
      if (strcmp (argv [i], "--help") == 0)
	fatal (1, NULL);
      else if (strcmp (argv [i], "--version") == 0)
	print_version (stderr);
      else if (strncmp (argv [i], "-i", 2) == 0)
        {
	  page = strtol (argv [i] + 2, NULL, 16);
	  print_inquiry_page (stdout, fd, page);
	}
      else if (strncmp (argv [i], "-m", 2) == 0)
        {
	  page = strtol (argv [i] + 2, NULL, 16);
	  print_mode_sense_page (stdout, fd, page);
	}
      else if (strncmp (argv [i], "-l", 2) == 0)
        {
	  page = strtol (argv [i] + 2, NULL, 16);
	  print_log_sense_page (stdout, fd, page);
	}
      else
        fatal (1, "unrecognized option '%s'\n", argv [i]);
    }

  close (fd);

  exit (0);
}

