⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapeinfo.c

📁 通用SCSI设备备份/读写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2000 Enhanced Software Technologies Inc. *   Released under terms of the GNU General Public License as * required by the license on 'mtxl.c'. * $Date: 2001/06/19 21:51:32 $ * $Revision: 1.2 $ *//*#define DEBUG_PARTITION *//*#define DEBUG 1 *//* What this does: This basically dumps out the contents of the following * pages: * * Inquiry -- prints full inquiry info. If it's not a tape drive, this is * the end of things. *    DeviceType: *    Manufacturer: *    ProdID:   *    ProdRevision: * * Log Sense: TapeAlert Page (if supported): *    TapeAlert:[message#]<Message>  e.g. "TapeAlert:[22]Cleaning Cartridge Worn Out" *   * Mode Sense:  *  Data Compression Page: *    DataCompEnabled:<yes|no> *    DataCompCapable:<yes|no> *    DataDeCompEnabled:<yes|no> *    CompType:<number> *    DeCompType:<number> * *  Device Configuration Page: *    ActivePartition:<#> *    DevConfigComp:<#>    -- the compression byte in device config page. *    EarlyWarningSize:<#> -- size of early warning buffer? * *  Medium Partition Page: *    NumPartitions:<#> *    MaxPartitions:<#> *    Partition[0]:<size> *    Partition[1]:<size>... * * Read Block Limits command: *    MinBlock:<#>  -- Minimum block size. *    MaxBlock:<#>  -- Maximum block size.  */#include <stdio.h>#include <string.h>#include "mtx.h"#include "mtxl.h"char  *argv0;void usage(void) {  FatalError("Usage: tapeinfo -f <generic-device>\n");}/* A table for printing out the peripheral device type as ASCII. */ static char *PeripheralDeviceType[32] = {  "Disk Drive",  "Tape Drive",  "Printer",  "Processor",  "Write-once",  "CD-ROM",  "Scanner",  "Optical",  "Medium Changer",  "Communications",  "ASC IT8",  "ASC IT8",  "RAID Array",  "Enclosure Services",  "OCR/W",  "Bridging Expander", /* 0x10 */  "Reserved",  /* 0x11 */  "Reserved", /* 0x12 */  "Reserved",  /* 0x13 */  "Reserved",  /* 0x14 */  "Reserved",  /* 0x15 */  "Reserved",  /* 0x16 */  "Reserved",  /* 0x17 */  "Reserved",  /* 0x18 */  "Reserved",  /* 0x19 */  "Reserved",  /* 0x1a */  "Reserved",  /* 0x1b */  "Reserved",  /* 0x1c */  "Reserved",  /* 0x1d */  "Reserved",  /* 0x1e */  "Unknown"    /* 0x1f */};/* we call it MediumChangerFD for history reasons, sigh. *//* now to print inquiry information: Copied from other one.... */static void ReportInquiry(DEVICE_TYPE MediumChangerFD){  RequestSense_T RequestSense;  Inquiry_T *Inquiry;  int i;  Inquiry = RequestInquiry(MediumChangerFD,&RequestSense);  if (Inquiry == NULL)     {      PrintRequestSense(&RequestSense);      FatalError("INQUIRY Command Failed\n");    }    printf("Product Type: %s\n",PeripheralDeviceType[Inquiry->PeripheralDeviceType]);  printf("Vendor ID: '");  for (i = 0; i < sizeof(Inquiry->VendorIdentification); i++)    printf("%c", Inquiry->VendorIdentification[i]);  printf("'\nProduct ID: '");  for (i = 0; i < sizeof(Inquiry->ProductIdentification); i++)    printf("%c", Inquiry->ProductIdentification[i]);  printf("'\nRevision: '");  for (i = 0; i < sizeof(Inquiry->ProductRevisionLevel); i++)    printf("%c", Inquiry->ProductRevisionLevel[i]);  printf("'\n");\  if (Inquiry->MChngr) {  /* check the attached-media-changer bit... */    printf("Attached Changer: Yes\n");  } else {    printf("Attached Changer: No\n");  }  free(Inquiry);  /* well, we're about to exit, but ... */}/* Okay, now for the Log Sense Tape Alert Page (if supported): */#define TAPEALERT_SIZE 2048  /* max size of tapealert buffer. */ #define MAX_TAPE_ALERT 0x41static char *tapealert_messages[]= {  "Undefined", /* 0 */  "         Read: Having problems reading (slowing down)", /* 1 */  "        Write: Having problems writing (losing capacity)", /* 2 */  "   Hard Error: Uncorrectable read/write error", /* 3 */  "        Media: Media Performance Degraded, Data Is At Risk", /* 4 */  " Read Failure: Tape faulty or tape drive broken", /* 5 */  "Write Failure: Tape faulty or tape drive broken", /* 6 */  "   Media Life: The tape has reached the end of its useful life", /* 7 */  "Not Data Grade:Replace cartridge with one  containing data grade tape",/*8*/  "Write Protect: Attempted to write to a write-protected cartridge",/*9 */  "   No Removal: Cannot unload, initiator is preventing media removal", /*a*/  "Cleaning Media:Cannot back up or restore to a cleaning cartridge", /* b */  "   Bad Format: The loaded tape contains data in an unsupported format", /*c */  " Snapped Tape: The data cartridge contains a broken tape", /* d */  "Undefined", /* e */  "Undefined", /* f */  "Undefined", /* 10 */  "Undefined", /* 11 */  "Undefined", /* 12 */  "Undefined", /* 13 */  "    Clean Now: The tape drive neads cleaning NOW", /* 0x14 */  "Clean Periodic:The tape drive needs to be cleaned at next opportunity", /* 0x15 */  "Cleaning Media:Cannot clean because cleaning cartridge used up, insert new cleaning cartridge to clean the drive", /* 0x16 */  "Undefined", /* 0x17 */  "Undefined", /* 0x18 */  "Undefined", /* 0x19 */  "Undefined", /* 0x1a */  "Undefined", /* 0x1b */  "Undefined", /* 0x1c */  "Undefined", /* 0x1d */  "   Hardware A: Tape drive has a problem not read/write related", /* 0x1e */  "   Hardware B: Tape drive has a problem not read/write related", /* 0x1f */  "    Interface: Problem with SCSI interface between tape drive and initiator", /* 0x20 */  "  Eject Media: The current operation has failed. Eject and reload media", /* 0x21 */  "Download Fail: Attempt to download new firmware failed", /* 0x22 */  "Undefined", /* 0x23 */  "Undefined", /* 0x24 */  "Undefined", /* 0x25 */  "Undefined", /* 0x26 */  "Undefined", /* 0x27 */  "Loader Hardware A: Changer having problems communicating with tape drive", /* 0x28   40 */  "Loader Stray Tape: Stray tape left in drive from prior error", /* 0x29 41 */  "Loader Hardware B: Autoloader mechanism has a fault", /* 0x2a 42 */  "  Loader Door: Loader door is open, please close it", /* 0x2b 43 */  "Undefined", /* 0x2c */  "Undefined", /* 0x2d */  "Undefined", /* 0x2e */  "Undefined", /* 0x2f */  "Undefined", /* 0x30 */  "Undefined", /* 0x31 */  "Undefined", /* 0x32 */  "Undefined", /* 0x33 */  "Undefined", /* 0x34 */  "Undefined", /* 0x35 */  "Undefined", /* 0x36 */  "Undefined", /* 0x37 */  "Undefined", /* 0x38 */  "Undefined", /* 0x39 */  "Undefined", /* 0x3a */  "Undefined", /* 0x3b */  "Undefined", /* 0x3c */  "Undefined", /* 0x3d */  "Undefined", /* 0x3e */  "Undefined", /* 0x3f */  "Undefined" /* 0x40 */};struct tapealert_struct {  int length;  unsigned char *data;};    static struct tapealert_struct *RequestTapeAlert(DEVICE_TYPE fd, RequestSense_T *sense) {  CDB_T CDB;    struct tapealert_struct *result;  int i,tapealert_len,result_idx;    unsigned char buffer[TAPEALERT_SIZE];  unsigned char *walkptr;  slow_bzero(buffer,TAPEALERT_SIZE); /*zero it... */  /* now to create the CDB block: */  CDB[0]=0x4d;   /* Log Sense */  CDB[1]=0;     CDB[2]=0x2e;   /* Tape Alert Page. */  CDB[3]=0;  CDB[4]=0;  CDB[5]=0;  CDB[6]=0;  CDB[7]=TAPEALERT_SIZE>>8 & 0xff;  /* hi byte, allocation size */  CDB[8]=TAPEALERT_SIZE & 0xff;     /* lo byte, allocation size */  CDB[9]=0;  /* reserved */   if (SCSI_ExecuteCommand(fd,Input,&CDB,10,buffer,TAPEALERT_SIZE,sense)!=0){    return NULL;  }  result=xmalloc(sizeof(struct tapealert_struct));  /* okay, we have stuff in the result buffer: the first 4 bytes are a header:   * byte 0 should be 0x2e, byte 1 == 0, bytes 2,3 tell how long the   * tapealert page is.    */  if ((buffer[0]&0x3f) != 0x2e) {    result->data=NULL;    result->length=0;    return result;  }  tapealert_len=(((int)buffer[2])<<8) + buffer[3];    if (!tapealert_len) {    result->length=0;    result->data=NULL;    return result;  }  /* okay, now allocate data and move the buffer over there: */  result->length=MAX_TAPE_ALERT;  result->data=xzmalloc(MAX_TAPE_ALERT); /* alloc & zero. */    walkptr=&buffer[4];  i=0;  while (i<tapealert_len) {        result_idx=(((int)walkptr[0])<<8) + walkptr[1]; /* the parameter #. */    if (result_idx > 0 && result_idx < MAX_TAPE_ALERT) {      if (walkptr[4]) {	result->data[result_idx]=1;       } else {	result->data[result_idx]=0;      }#ifdef DEBUGOLD1      fprintf(stderr,"Alert[0x%x]=%d\n",result_idx,result->data[result_idx]);      fflush(stderr);#endif    } else {      FatalError("Invalid tapealert page: %d\n",result_idx);    }    i=i+4+walkptr[3]; /* length byte! */    walkptr=walkptr+4+walkptr[3]; /* next! */  }  return result;}static void ReportTapeAlert(DEVICE_TYPE fd) {  /* we actually ignore a bad sense reading, like might happen if the    * tape drive does not support the tapealert page.    */    RequestSense_T RequestSense;    struct tapealert_struct *result;  int i;  result=RequestTapeAlert(fd,&RequestSense);  if (!result) return; /* sorry. Don't print sense here. */  if (!result->length) return; /* sorry, no alerts valid. */    for (i=0;i<result->length;i++) {    if (result->data[i]) {      printf("TapeAlert[%d]:%s.\n",i,tapealert_messages[i]);    }  }  free(result->data);  free(result);  return;}static unsigned char*mode_sense(DEVICE_TYPE fd, int pagenum, int alloc_len,  RequestSense_T *RequestSense) {  CDB_T CDB;  unsigned char *input_buffer; /*the input buffer -- has junk prepended to				* actual sense page. 				*/  unsigned char *tmp;  unsigned char *retval;  /* the return value. */  int i,pagelen;  if (alloc_len > 255) {    FatalError("mode_sense(6) can only read up to 255 characters!\n");  }  input_buffer=(unsigned char *)xzmalloc(256); /* overdo it, eh? */  /* clear the sense buffer: */  slow_bzero((char *)RequestSense,sizeof(RequestSense_T));    /* returns an array of bytes in the page, or, if not possible, NULL. */  CDB[0]=0x1a; /* Mode Sense(6) */  CDB[1]=0;   CDB[2]=pagenum; /* the page to read. */  CDB[3]=0;  CDB[4]=255; /* allocation length. This does max of 256 bytes! */  CDB[5]=0;    if (SCSI_ExecuteCommand(fd,Input,&CDB,6,			  input_buffer,255,RequestSense) != 0) {#ifdef DEBUG_MODE_SENSE    fprintf(stderr,"Could not execute mode sense...\n");    fflush(stderr);#endif    return NULL; /* sorry, couldn't do it. */  }  /* Oh hell, write protect is the only thing I have: always print   * it if our mode page was 0x0fh, before skipping past buffer:    * if the media is *NOT* write protected, just skip, sigh.    *   * Oh poops, the blocksize is reported in the block descriptor header<   * too. Again, just print if our mode page was 0x0f...   */  if (pagenum == 0x0f) {    int blocklen;    if (input_buffer[2] & 0x80) {      printf("WriteProtect: yes\n");    }    if (input_buffer[2] & 0x70) {      printf("BufferedMode: yes\n");    }    if (input_buffer[1] ) {      printf("Medium Type: 0x%x\n", input_buffer[1]);    } else {      printf("Medium Type: Not Loaded\n");    }    printf("Density Code: 0x%x\n", input_buffer[4]);    /* Put out the block size: */    blocklen=((int)input_buffer[9]<<16)+      ((int)input_buffer[10]<<8)+      input_buffer[11];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -