/*$VER: UnLoad v1.1 - (c) 1995 - JPM*/
/*
   UnLoad - A small program to Load/Unload SCSI devices using the generic
            SCSI interface.

   Author:  Juergen P. Meier -  Gauting, Germany
            (jor@muecke.rz.fh-muenchen.de)

   License: This file may be copied under the terms and conditions of
            version 2 of the GNU General Public License, as published
	    by the Free Software Foundation (Cambridge, Massachusetts).

   Initial release v1.0.

*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <unistd.h>

#define __KERNEL__
#include <linux/fs.h>
#undef __KERNEL__
#include "block/blk.h"

#include "scsi/scsi.h"
#include "scsi/sg.h"
#include <string.h>

struct sg_request {
  struct sg_header header;
  unsigned char bytes[100];
} sg_request;

struct sg_reply {
  struct sg_header header;
  unsigned char bytes[100];
};

void usage(char *name)
{
  printf(" Usage: %s [device] [0|1]\n", name);
  printf("        0 - load Medium (tested: TOSHIBA XM3601 CD-ROM)\n");
  printf("            default if _not_ invoked as 'unload' or 'eject'\n");
  printf("        1 - eject Medium (should work with any drive)\n");
  printf("            default if invoked as 'unload' or 'eject'\n");
  printf("   device - opt. SCSI-generic device (default: /dev/sgc)\n");
  printf(" UnLoad v1.0 - (c) 1995 Juergen P. Meier\n");
  return;
}

void main(int argc, char **argv)
{
  int fd_sg;
  int unload = 0;
  struct sg_reply reply;
  struct sg_request request;
  int reply_len, exp_size, act_size;
  char sg_def[] = "/dev/sgc";
  char *sg_name = sg_def;

  if (strcmp(argv[0],"unload") == 0)
    unload = 1;
  if (strcmp(argv[0],"eject") == 0)
    unload = 1;

  if (argc > 3)
  {
    printf("%s: too many arguments\n", argv[0]);
    usage(argv[0]);
    exit (10);
  }
  if (argc == 2)
  {
    if (argv[1][1] == 0)
    {
      switch (*argv[1])
      {
        case '0':
	{
	  unload = 0;
	  break;
	}
        case '1':
	{
	  unload = 1;
	  break;
	}
        default:
	{
	  printf("%s: invalid argument -- %s\n", argv[0], argv[1]);
	  usage(argv[0]);
	  exit (9);
	}
      } /* switch */
    }
    else /* devicename */
    {
      sg_name = argv[1];
    }
  } /* if (argc == 2) */
  if (argc == 3)
  {
    if (argv[2][1] == 0)
    {
      switch (*argv[2])
      {
        case '0':
	{
          unload = 0;
          break;
        }
      case '1':
        {
          unload = 1;
          break;
        }
      default:
        {
          printf("%s: invalid argument -- %s\n", argv[0], argv[2]);
          usage(argv[0]);
          exit (8);
        }
      } /* switch */
    }
    sg_name = argv[1];
  } /* if (argc == 3) */

  if ( (fd_sg = open(sg_name, O_RDWR)) < 0 )
  {
    printf("%s: error %d opening generic scsi device: %s\n",
	   argv[0], fd_sg, sg_name);
    exit (7);
  }

  reply_len = sizeof(struct sg_reply);
  bzero (&reply, sizeof(reply_len));
  bzero (&request, sizeof(request));

  request.header.pack_len = sizeof(struct sg_header) + 6;
  request.header.reply_len = reply_len + sizeof(struct sg_header);
  request.header.pack_id = 0;
  request.header.result = 0;

  request.bytes[0] = 0x1B;
  request.bytes[1] = 0;
  request.bytes[2] = 0;
  request.bytes[3] = 0;
  request.bytes[4] = unload ? 2 : 3;
  request.bytes[5] = 0;

  exp_size = sizeof(struct sg_header) + 6;
  act_size = write(fd_sg, &request, exp_size);
  if (act_size < 0)
  {
    printf("%s: write failed", argv[0]);
    exit (5);
  }
  else if (act_size != exp_size)
  {
    printf("%s: wrote %d bytes, expected to write %d.\n",
	   argv[0], act_size, exp_size);
  }

  reply_len = read(fd_sg, &reply, sizeof(struct sg_reply));

/*  printf("done\n"); */

  close(fd_sg);
  exit (0);
}
/* EOF */












